aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2008-12-17 20:04:23 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-06 16:52:35 -0500
commitc55519ff75224222f4668c92ae3733059269f575 (patch)
treecf7871a28ee226e274763608f215c171d54cd33e /drivers
parent6e16aee60c815dac2d6c3b875769a79d09df6f91 (diff)
Staging: add rt2870 wireless driver
This is the Ralink RT2870 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 and cleaned up a bit already by me. Cc: Linux wireless <linux-wireless@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/rt2870/2870_main_dev.c1612
-rw-r--r--drivers/staging/rt2870/Kconfig6
-rw-r--r--drivers/staging/rt2870/Makefile47
-rw-r--r--drivers/staging/rt2870/TODO10
-rw-r--r--drivers/staging/rt2870/aironet.h210
-rw-r--r--drivers/staging/rt2870/ap.h562
-rw-r--r--drivers/staging/rt2870/chlist.h1296
-rw-r--r--drivers/staging/rt2870/common/2870_rtmp_init.c1778
-rw-r--r--drivers/staging/rt2870/common/action.c1046
-rw-r--r--drivers/staging/rt2870/common/action.h68
-rw-r--r--drivers/staging/rt2870/common/ba_action.c1798
-rw-r--r--drivers/staging/rt2870/common/cmm_data.c2734
-rw-r--r--drivers/staging/rt2870/common/cmm_data_2870.c963
-rw-r--r--drivers/staging/rt2870/common/cmm_info.c3712
-rw-r--r--drivers/staging/rt2870/common/cmm_sanity.c1663
-rw-r--r--drivers/staging/rt2870/common/cmm_sync.c711
-rw-r--r--drivers/staging/rt2870/common/cmm_wpa.c1654
-rw-r--r--drivers/staging/rt2870/common/dfs.c453
-rw-r--r--drivers/staging/rt2870/common/eeprom.c254
-rw-r--r--drivers/staging/rt2870/common/firmware.h558
-rw-r--r--drivers/staging/rt2870/common/md5.c1427
-rw-r--r--drivers/staging/rt2870/common/mlme.c8609
-rw-r--r--drivers/staging/rt2870/common/netif_block.c144
-rw-r--r--drivers/staging/rt2870/common/rtmp_init.c4132
-rw-r--r--drivers/staging/rt2870/common/rtmp_tkip.c1613
-rw-r--r--drivers/staging/rt2870/common/rtmp_wep.c508
-rw-r--r--drivers/staging/rt2870/common/rtusb_bulk.c1981
-rw-r--r--drivers/staging/rt2870/common/rtusb_data.c229
-rw-r--r--drivers/staging/rt2870/common/rtusb_io.c2006
-rw-r--r--drivers/staging/rt2870/common/spectrum.c1876
-rw-r--r--drivers/staging/rt2870/dfs.h100
-rw-r--r--drivers/staging/rt2870/leap.h215
-rw-r--r--drivers/staging/rt2870/link_list.h134
-rw-r--r--drivers/staging/rt2870/md4.h42
-rw-r--r--drivers/staging/rt2870/md5.h107
-rw-r--r--drivers/staging/rt2870/mlme.h1471
-rw-r--r--drivers/staging/rt2870/netif_block.h58
-rw-r--r--drivers/staging/rt2870/oid.h1091
-rw-r--r--drivers/staging/rt2870/rt2870.h761
-rw-r--r--drivers/staging/rt2870/rt28xx.h2689
-rw-r--r--drivers/staging/rt2870/rt_ate.c6452
-rw-r--r--drivers/staging/rt2870/rt_ate.h315
-rw-r--r--drivers/staging/rt2870/rt_config.h104
-rw-r--r--drivers/staging/rt2870/rt_linux.c1095
-rw-r--r--drivers/staging/rt2870/rt_linux.h908
-rw-r--r--drivers/staging/rt2870/rt_main_dev.c1863
-rw-r--r--drivers/staging/rt2870/rt_profile.c2016
-rw-r--r--drivers/staging/rt2870/rtmp.h7586
-rw-r--r--drivers/staging/rt2870/rtmp_ckipmic.h113
-rw-r--r--drivers/staging/rt2870/rtmp_def.h1622
-rw-r--r--drivers/staging/rt2870/rtmp_type.h94
-rw-r--r--drivers/staging/rt2870/spectrum.h322
-rw-r--r--drivers/staging/rt2870/spectrum_def.h95
-rw-r--r--drivers/staging/rt2870/sta/aironet.c1312
-rw-r--r--drivers/staging/rt2870/sta/assoc.c2039
-rw-r--r--drivers/staging/rt2870/sta/auth.c474
-rw-r--r--drivers/staging/rt2870/sta/auth_rsp.c166
-rw-r--r--drivers/staging/rt2870/sta/connect.c2822
-rw-r--r--drivers/staging/rt2870/sta/dls.c2210
-rw-r--r--drivers/staging/rt2870/sta/rtmp_data.c2619
-rw-r--r--drivers/staging/rt2870/sta/sanity.c420
-rw-r--r--drivers/staging/rt2870/sta/sync.c1753
-rw-r--r--drivers/staging/rt2870/sta/wpa.c2107
-rw-r--r--drivers/staging/rt2870/sta_ioctl.c7068
-rw-r--r--drivers/staging/rt2870/sta_ioctl.c.patch18
-rw-r--r--drivers/staging/rt2870/tmp607037
-rw-r--r--drivers/staging/rt2870/tmp617037
-rw-r--r--drivers/staging/rt2870/wpa.h357
70 files changed, 110355 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 9845eab9ebf..e2f57e9b694 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -71,6 +71,8 @@ source "drivers/staging/otus/Kconfig"
71 71
72source "drivers/staging/rt2860/Kconfig" 72source "drivers/staging/rt2860/Kconfig"
73 73
74source "drivers/staging/rt2870/Kconfig"
75
74source "drivers/staging/benet/Kconfig" 76source "drivers/staging/benet/Kconfig"
75 77
76source "drivers/staging/comedi/Kconfig" 78source "drivers/staging/comedi/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 968f333a659..94efc9df5a8 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_POCH) += poch/
18obj-$(CONFIG_AGNX) += agnx/ 18obj-$(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_BENET) += benet/ 22obj-$(CONFIG_BENET) += benet/
22obj-$(CONFIG_COMEDI) += comedi/ 23obj-$(CONFIG_COMEDI) += comedi/
23obj-$(CONFIG_ASUS_OLED) += asus_oled/ 24obj-$(CONFIG_ASUS_OLED) += asus_oled/
diff --git a/drivers/staging/rt2870/2870_main_dev.c b/drivers/staging/rt2870/2870_main_dev.c
new file mode 100644
index 00000000000..91da4e2298a
--- /dev/null
+++ b/drivers/staging/rt2870/2870_main_dev.c
@@ -0,0 +1,1612 @@
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
66extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
67 IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
68
69
70/* module table */
71struct usb_device_id rtusb_usb_id[] = RT2870_USB_DEVICES;
72INT const rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
73MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
74
75#ifndef PF_NOFREEZE
76#define PF_NOFREEZE 0
77#endif
78
79
80#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
81
82/**************************************************************************/
83/**************************************************************************/
84//tested for kernel 2.4 series
85/**************************************************************************/
86/**************************************************************************/
87static void *rtusb_probe(struct usb_device *dev, UINT interface,
88 const struct usb_device_id *id_table);
89static void rtusb_disconnect(struct usb_device *dev, void *ptr);
90
91struct usb_driver rtusb_driver = {
92 name:"rt2870",
93 probe:rtusb_probe,
94 disconnect:rtusb_disconnect,
95 id_table:rtusb_usb_id,
96 };
97
98#else
99
100#ifdef CONFIG_PM
101static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
102static int rt2870_resume(struct usb_interface *intf);
103#endif // CONFIG_PM //
104
105/**************************************************************************/
106/**************************************************************************/
107//tested for kernel 2.6series
108/**************************************************************************/
109/**************************************************************************/
110static int rtusb_probe (struct usb_interface *intf,
111 const struct usb_device_id *id);
112static void rtusb_disconnect(struct usb_interface *intf);
113
114struct usb_driver rtusb_driver = {
115#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
116 .owner = THIS_MODULE,
117#endif
118 .name="rt2870",
119 .probe=rtusb_probe,
120 .disconnect=rtusb_disconnect,
121 .id_table=rtusb_usb_id,
122
123#ifdef CONFIG_PM
124 suspend: rt2870_suspend,
125 resume: rt2870_resume,
126#endif
127 };
128
129#ifdef CONFIG_PM
130
131VOID RT2860RejectPendingPackets(
132 IN PRTMP_ADAPTER pAd)
133{
134 // clear PS packets
135 // clear TxSw packets
136}
137
138static int rt2870_suspend(
139 struct usb_interface *intf,
140 pm_message_t state)
141{
142 struct net_device *net_dev;
143 PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
144
145
146 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
147 net_dev = pAd->net_dev;
148 netif_device_detach (net_dev);
149
150 pAd->PM_FlgSuspend = 1;
151 if (netif_running(net_dev)) {
152 RTUSBCancelPendingBulkInIRP(pAd);
153 RTUSBCancelPendingBulkOutIRP(pAd);
154 }
155 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
156 return 0;
157}
158
159static int rt2870_resume(
160 struct usb_interface *intf)
161{
162 struct net_device *net_dev;
163 PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
164
165
166 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
167
168 pAd->PM_FlgSuspend = 0;
169 net_dev = pAd->net_dev;
170 netif_device_attach (net_dev);
171 netif_start_queue(net_dev);
172 netif_carrier_on(net_dev);
173 netif_wake_queue(net_dev);
174
175 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
176 return 0;
177}
178#endif // CONFIG_PM //
179#endif // LINUX_VERSION_CODE //
180
181
182// Init driver module
183INT __init rtusb_init(void)
184{
185 printk("rtusb init --->\n");
186 return usb_register(&rtusb_driver);
187}
188
189// Deinit driver module
190VOID __exit rtusb_exit(void)
191{
192 usb_deregister(&rtusb_driver);
193 printk("<--- rtusb exit\n");
194}
195
196module_init(rtusb_init);
197module_exit(rtusb_exit);
198
199
200
201
202/*--------------------------------------------------------------------- */
203/* function declarations */
204/*--------------------------------------------------------------------- */
205
206/*
207========================================================================
208Routine Description:
209 MLME kernel thread.
210
211Arguments:
212 *Context the pAd, driver control block pointer
213
214Return Value:
215 0 close the thread
216
217Note:
218========================================================================
219*/
220INT MlmeThread(
221 IN void *Context)
222{
223 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
224 POS_COOKIE pObj;
225 int status;
226
227 pObj = (POS_COOKIE)pAd->OS_Cookie;
228
229 rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete));
230
231 while (pAd->mlme_kill == 0)
232 {
233 /* lock the device pointers */
234 //down(&(pAd->mlme_semaphore));
235 status = down_interruptible(&(pAd->mlme_semaphore));
236
237 /* lock the device pointers , need to check if required*/
238 //down(&(pAd->usbdev_semaphore));
239
240 if (!pAd->PM_FlgSuspend)
241 MlmeHandler(pAd);
242
243 /* unlock the device pointers */
244 //up(&(pAd->usbdev_semaphore));
245 if (status != 0)
246 {
247 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
248 break;
249 }
250 }
251
252 /* notify the exit routine that we're actually exiting now
253 *
254 * complete()/wait_for_completion() is similar to up()/down(),
255 * except that complete() is safe in the case where the structure
256 * is getting deleted in a parallel mode of execution (i.e. just
257 * after the down() -- that's necessary for the thread-shutdown
258 * case.
259 *
260 * complete_and_exit() goes even further than this -- it is safe in
261 * the case that the thread of the caller is going away (not just
262 * the structure) -- this is necessary for the module-remove case.
263 * This is important in preemption kernels, which transfer the flow
264 * of execution immediately upon a complete().
265 */
266 DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
267
268 pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
269
270 complete_and_exit (&pAd->mlmeComplete, 0);
271 return 0;
272
273}
274
275
276/*
277========================================================================
278Routine Description:
279 USB command kernel thread.
280
281Arguments:
282 *Context the pAd, driver control block pointer
283
284Return Value:
285 0 close the thread
286
287Note:
288========================================================================
289*/
290INT RTUSBCmdThread(
291 IN void * Context)
292{
293 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
294 POS_COOKIE pObj;
295 int status;
296
297 pObj = (POS_COOKIE)pAd->OS_Cookie;
298
299 rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete));
300
301 NdisAcquireSpinLock(&pAd->CmdQLock);
302 pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING;
303 NdisReleaseSpinLock(&pAd->CmdQLock);
304
305 while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING)
306 {
307 /* lock the device pointers */
308 //down(&(pAd->RTUSBCmd_semaphore));
309 status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
310
311 if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED)
312 break;
313
314 if (status != 0)
315 {
316 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
317 break;
318 }
319 /* lock the device pointers , need to check if required*/
320 //down(&(pAd->usbdev_semaphore));
321
322 if (!pAd->PM_FlgSuspend)
323 CMDHandler(pAd);
324
325 /* unlock the device pointers */
326 //up(&(pAd->usbdev_semaphore));
327 }
328
329 if (!pAd->PM_FlgSuspend)
330 { // Clear the CmdQElements.
331 CmdQElmt *pCmdQElmt = NULL;
332
333 NdisAcquireSpinLock(&pAd->CmdQLock);
334 pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
335 while(pAd->CmdQ.size)
336 {
337 RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
338 if (pCmdQElmt)
339 {
340 if (pCmdQElmt->CmdFromNdis == TRUE)
341 {
342 if (pCmdQElmt->buffer != NULL)
343 NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
344
345 NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
346 }
347 else
348 {
349 if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
350 NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
351 {
352 NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
353 }
354 }
355 }
356 }
357
358 NdisReleaseSpinLock(&pAd->CmdQLock);
359 }
360 /* notify the exit routine that we're actually exiting now
361 *
362 * complete()/wait_for_completion() is similar to up()/down(),
363 * except that complete() is safe in the case where the structure
364 * is getting deleted in a parallel mode of execution (i.e. just
365 * after the down() -- that's necessary for the thread-shutdown
366 * case.
367 *
368 * complete_and_exit() goes even further than this -- it is safe in
369 * the case that the thread of the caller is going away (not just
370 * the structure) -- this is necessary for the module-remove case.
371 * This is important in preemption kernels, which transfer the flow
372 * of execution immediately upon a complete().
373 */
374 DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
375
376 pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
377
378 complete_and_exit (&pAd->CmdQComplete, 0);
379 return 0;
380
381}
382
383
384static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd)
385{
386 int status;
387 RALINK_TIMER_STRUCT *pTimer;
388 RT2870_TIMER_ENTRY *pEntry;
389 unsigned long irqFlag;
390
391 while(!pAd->TimerFunc_kill)
392 {
393// printk("waiting for event!\n");
394 pTimer = NULL;
395
396 status = down_interruptible(&(pAd->RTUSBTimer_semaphore));
397
398 if (pAd->TimerQ.status == RT2870_THREAD_STOPED)
399 break;
400
401 // event happened.
402 while(pAd->TimerQ.pQHead)
403 {
404 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag);
405 pEntry = pAd->TimerQ.pQHead;
406 if (pEntry)
407 {
408 pTimer = pEntry->pRaTimer;
409
410 // update pQHead
411 pAd->TimerQ.pQHead = pEntry->pNext;
412 if (pEntry == pAd->TimerQ.pQTail)
413 pAd->TimerQ.pQTail = NULL;
414
415 // return this queue entry to timerQFreeList.
416 pEntry->pNext = pAd->TimerQ.pQPollFreeList;
417 pAd->TimerQ.pQPollFreeList = pEntry;
418 }
419 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag);
420
421 if (pTimer)
422 {
423 if (pTimer->handle != NULL)
424 if (!pAd->PM_FlgSuspend)
425 pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
426 if ((pTimer->Repeat) && (pTimer->State == FALSE))
427 RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
428 }
429 }
430
431 if (status != 0)
432 {
433 pAd->TimerQ.status = RT2870_THREAD_STOPED;
434 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
435 break;
436 }
437 }
438}
439
440
441INT TimerQThread(
442 IN OUT PVOID Context)
443{
444 PRTMP_ADAPTER pAd;
445 POS_COOKIE pObj;
446
447 pAd = (PRTMP_ADAPTER)Context;
448 pObj = (POS_COOKIE) pAd->OS_Cookie;
449
450 rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete));
451
452 RT2870_TimerQ_Handle(pAd);
453
454 /* notify the exit routine that we're actually exiting now
455 *
456 * complete()/wait_for_completion() is similar to up()/down(),
457 * except that complete() is safe in the case where the structure
458 * is getting deleted in a parallel mode of execution (i.e. just
459 * after the down() -- that's necessary for the thread-shutdown
460 * case.
461 *
462 * complete_and_exit() goes even further than this -- it is safe in
463 * the case that the thread of the caller is going away (not just
464 * the structure) -- this is necessary for the module-remove case.
465 * This is important in preemption kernels, which transfer the flow
466 * of execution immediately upon a complete().
467 */
468 DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
469
470 pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE;
471
472 complete_and_exit(&pAd->TimerQComplete, 0);
473 return 0;
474
475}
476
477
478RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
479 IN RTMP_ADAPTER *pAd,
480 IN RALINK_TIMER_STRUCT *pTimer)
481{
482 RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail;
483 unsigned long irqFlags;
484
485
486 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
487 if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)
488 {
489 if(pAd->TimerQ.pQPollFreeList)
490 {
491 pQNode = pAd->TimerQ.pQPollFreeList;
492 pAd->TimerQ.pQPollFreeList = pQNode->pNext;
493
494 pQNode->pRaTimer = pTimer;
495 pQNode->pNext = NULL;
496
497 pQTail = pAd->TimerQ.pQTail;
498 if (pAd->TimerQ.pQTail != NULL)
499 pQTail->pNext = pQNode;
500 pAd->TimerQ.pQTail = pQNode;
501 if (pAd->TimerQ.pQHead == NULL)
502 pAd->TimerQ.pQHead = pQNode;
503 }
504 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
505
506 if (pQNode)
507 up(&pAd->RTUSBTimer_semaphore);
508 //wake_up(&timerWaitQ);
509 }
510 else
511 {
512 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
513 }
514 return pQNode;
515}
516
517
518BOOLEAN RT2870_TimerQ_Remove(
519 IN RTMP_ADAPTER *pAd,
520 IN RALINK_TIMER_STRUCT *pTimer)
521{
522 RT2870_TIMER_ENTRY *pNode, *pPrev = NULL;
523 unsigned long irqFlags;
524
525 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
526 if (pAd->TimerQ.status >= RT2870_THREAD_INITED)
527 {
528 pNode = pAd->TimerQ.pQHead;
529 while (pNode)
530 {
531 if (pNode->pRaTimer == pTimer)
532 break;
533 pPrev = pNode;
534 pNode = pNode->pNext;
535 }
536
537 // Now move it to freeList queue.
538 if (pNode)
539 {
540 if (pNode == pAd->TimerQ.pQHead)
541 pAd->TimerQ.pQHead = pNode->pNext;
542 if (pNode == pAd->TimerQ.pQTail)
543 pAd->TimerQ.pQTail = pPrev;
544 if (pPrev != NULL)
545 pPrev->pNext = pNode->pNext;
546
547 // return this queue entry to timerQFreeList.
548 pNode->pNext = pAd->TimerQ.pQPollFreeList;
549 pAd->TimerQ.pQPollFreeList = pNode;
550 }
551 }
552 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
553
554 return TRUE;
555}
556
557
558void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd)
559{
560 RT2870_TIMER_ENTRY *pTimerQ;
561 unsigned long irqFlags;
562
563 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
564 while (pAd->TimerQ.pQHead)
565 {
566 pTimerQ = pAd->TimerQ.pQHead;
567 pAd->TimerQ.pQHead = pTimerQ->pNext;
568 // remove the timeQ
569 }
570 pAd->TimerQ.pQPollFreeList = NULL;
571 os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
572 pAd->TimerQ.pQTail = NULL;
573 pAd->TimerQ.pQHead = NULL;
574 pAd->TimerQ.status = RT2870_THREAD_STOPED;
575 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
576
577}
578
579
580void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd)
581{
582 int i;
583 RT2870_TIMER_ENTRY *pQNode, *pEntry;
584 unsigned long irqFlags;
585
586 NdisAllocateSpinLock(&pAd->TimerQLock);
587
588 RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
589 NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
590 //InterlockedExchange(&pAd->TimerQ.count, 0);
591
592 /* Initialise the wait q head */
593 //init_waitqueue_head(&timerWaitQ);
594
595 os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX);
596 if (pAd->TimerQ.pTimerQPoll)
597 {
598 pEntry = NULL;
599 pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll;
600 for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
601 {
602 pQNode->pNext = pEntry;
603 pEntry = pQNode;
604 pQNode++;
605 }
606 pAd->TimerQ.pQPollFreeList = pEntry;
607 pAd->TimerQ.pQHead = NULL;
608 pAd->TimerQ.pQTail = NULL;
609 pAd->TimerQ.status = RT2870_THREAD_INITED;
610 }
611 RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
612}
613
614
615VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd)
616{
617 PHT_TX_CONTEXT pHTTXContext;
618 int idx;
619 ULONG irqFlags;
620 PURB pUrb;
621 BOOLEAN needDumpSeq = FALSE;
622 UINT32 MACValue;
623
624
625 idx = 0;
626 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
627 if ((MACValue & 0xff) !=0 )
628 {
629 DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
630 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
631 while((MACValue &0xff) != 0 && (idx++ < 10))
632 {
633 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
634 NdisMSleep(1);
635 }
636 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
637 }
638
639 idx = 0;
640 if ((MACValue & 0xff00) !=0 )
641 {
642 DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
643 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
644 while((MACValue &0xff00) != 0 && (idx++ < 10))
645 {
646 RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
647 NdisMSleep(1);
648 }
649 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
650 }
651
652
653 if (pAd->watchDogRxOverFlowCnt >= 2)
654 {
655 DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
656 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
657 fRTMP_ADAPTER_BULKIN_RESET |
658 fRTMP_ADAPTER_HALT_IN_PROGRESS |
659 fRTMP_ADAPTER_NIC_NOT_EXIST))))
660 {
661 DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
662 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
663 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
664 needDumpSeq = TRUE;
665 }
666 pAd->watchDogRxOverFlowCnt = 0;
667 }
668
669
670 for (idx = 0; idx < NUM_OF_TX_RING; idx++)
671 {
672 pUrb = NULL;
673
674 RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
675 if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
676 {
677 pAd->watchDogTxPendingCnt[idx]++;
678
679 if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
680 (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
681 )
682 {
683 // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
684 pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
685 if (pHTTXContext->IRPPending)
686 { // Check TxContext.
687 pUrb = pHTTXContext->pUrb;
688 }
689 else if (idx == MGMTPIPEIDX)
690 {
691 PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
692
693 //Check MgmtContext.
694 pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
695 pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
696 pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
697
698 if (pMLMEContext->IRPPending)
699 {
700 ASSERT(pMLMEContext->IRPPending);
701 pUrb = pMLMEContext->pUrb;
702 }
703 else if (pNULLContext->IRPPending)
704 {
705 ASSERT(pNULLContext->IRPPending);
706 pUrb = pNULLContext->pUrb;
707 }
708 else if (pPsPollContext->IRPPending)
709 {
710 ASSERT(pPsPollContext->IRPPending);
711 pUrb = pPsPollContext->pUrb;
712 }
713 }
714
715 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
716
717 DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
718 if (pUrb)
719 {
720 DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
721 // unlink it now
722 RTUSB_UNLINK_URB(pUrb);
723 // Sleep 200 microseconds to give cancellation time to work
724 RTMPusecDelay(200);
725 needDumpSeq = TRUE;
726 }
727 else
728 {
729 DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
730 }
731 }
732 else
733 {
734 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
735 }
736 }
737 else
738 {
739 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
740 }
741 }
742
743#ifdef DOT11_N_SUPPORT
744 // For Sigma debug, dump the ba_reordering sequence.
745 if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
746 {
747 USHORT Idx;
748 PBA_REC_ENTRY pBAEntry = NULL;
749 UCHAR count = 0;
750 struct reordering_mpdu *mpdu_blk;
751
752 Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
753
754 pBAEntry = &pAd->BATable.BARecEntry[Idx];
755 if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
756 {
757 DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
758 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
759 mpdu_blk = pBAEntry->list.next;
760 while (mpdu_blk)
761 {
762 DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
763 mpdu_blk = mpdu_blk->next;
764 count++;
765 }
766
767 DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
768 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
769 }
770 }
771#endif // DOT11_N_SUPPORT //
772}
773
774/*
775========================================================================
776Routine Description:
777 Release allocated resources.
778
779Arguments:
780 *dev Point to the PCI or USB device
781 pAd driver control block pointer
782
783Return Value:
784 None
785
786Note:
787========================================================================
788*/
789static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
790{
791 struct net_device *net_dev = NULL;
792
793
794 DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
795 dev->bus->bus_name, dev->devpath));
796 if (!pAd)
797 {
798#ifdef MULTIPLE_CARD_SUPPORT
799 if ((pAd->MC_RowID >= 0) && (pAd->MC_RowID <= MAX_NUM_OF_MULTIPLE_CARD))
800 MC_CardUsed[pAd->MC_RowID] = 0; // not clear MAC address
801#endif // MULTIPLE_CARD_SUPPORT //
802
803#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
804 while(MOD_IN_USE > 0)
805 {
806 MOD_DEC_USE_COUNT;
807 }
808#else
809 usb_put_dev(dev);
810#endif // LINUX_VERSION_CODE //
811
812 printk("rtusb_disconnect: pAd == NULL!\n");
813 return;
814 }
815 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
816
817
818
819 // for debug, wait to show some messages to /proc system
820 udelay(1);
821
822
823
824
825 net_dev = pAd->net_dev;
826 if (pAd->net_dev != NULL)
827 {
828 printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name);
829 unregister_netdev (pAd->net_dev);
830 }
831 udelay(1);
832#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
833#else
834 flush_scheduled_work();
835#endif // LINUX_VERSION_CODE //
836 udelay(1);
837
838 // free net_device memory
839#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
840 kfree(net_dev);
841#else
842 free_netdev(net_dev);
843#endif // LINUX_VERSION_CODE //
844
845 // free adapter memory
846 RTMPFreeAdapter(pAd);
847
848 // release a use of the usb device structure
849#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
850 while(MOD_IN_USE > 0)
851 {
852 MOD_DEC_USE_COUNT;
853 }
854#else
855 usb_put_dev(dev);
856#endif // LINUX_VERSION_CODE //
857 udelay(1);
858
859 DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
860}
861
862
863/*
864========================================================================
865Routine Description:
866 Probe RT28XX chipset.
867
868Arguments:
869 *dev Point to the PCI or USB device
870 interface
871 *id_table Point to the PCI or USB device ID
872
873Return Value:
874 None
875
876Note:
877========================================================================
878*/
879#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
880static void *rtusb_probe(struct usb_device *dev, UINT interface,
881 const struct usb_device_id *id)
882{
883 PRTMP_ADAPTER pAd;
884 rt28xx_probe((void *)dev, (void *)id, interface, &pAd);
885 return (void *)pAd;
886}
887
888//Disconnect function is called within exit routine
889static void rtusb_disconnect(struct usb_device *dev, void *ptr)
890{
891 _rtusb_disconnect(dev, ((PRTMP_ADAPTER)ptr));
892}
893
894#else /* kernel 2.6 series */
895static int rtusb_probe (struct usb_interface *intf,
896 const struct usb_device_id *id)
897{
898 PRTMP_ADAPTER pAd;
899 return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd);
900}
901
902
903static void rtusb_disconnect(struct usb_interface *intf)
904{
905 struct usb_device *dev = interface_to_usbdev(intf);
906 PRTMP_ADAPTER pAd;
907
908
909 pAd = usb_get_intfdata(intf);
910 usb_set_intfdata(intf, NULL);
911
912 _rtusb_disconnect(dev, pAd);
913}
914#endif // LINUX_VERSION_CODE //
915
916
917/*
918========================================================================
919Routine Description:
920 Close kernel threads.
921
922Arguments:
923 *pAd the raxx interface data pointer
924
925Return Value:
926 NONE
927
928Note:
929========================================================================
930*/
931VOID RT28xxThreadTerminate(
932 IN RTMP_ADAPTER *pAd)
933{
934 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
935 INT ret;
936
937
938 // Sleep 50 milliseconds so pending io might finish normally
939 RTMPusecDelay(50000);
940
941 // We want to wait until all pending receives and sends to the
942 // device object. We cancel any
943 // irps. Wait until sends and receives have stopped.
944 RTUSBCancelPendingIRPs(pAd);
945
946 // Terminate Threads
947 CHECK_PID_LEGALITY(pObj->TimerQThr_pid)
948 {
949 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
950
951 printk("Terminate the TimerQThr_pid=%d!\n", GET_PID_NUMBER(pObj->TimerQThr_pid));
952 mb();
953 pAd->TimerFunc_kill = 1;
954 mb();
955 ret = KILL_THREAD_PID(pObj->TimerQThr_pid, SIGTERM, 1);
956 if (ret)
957 {
958 printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
959 pAd->net_dev->name, GET_PID_NUMBER(pObj->TimerQThr_pid), ret);
960 }
961 else
962 {
963 wait_for_completion(&pAd->TimerQComplete);
964 pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE;
965 }
966 }
967
968 CHECK_PID_LEGALITY(pObj->MLMEThr_pid)
969 {
970 printk("Terminate the MLMEThr_pid=%d!\n", GET_PID_NUMBER(pObj->MLMEThr_pid));
971 mb();
972 pAd->mlme_kill = 1;
973 //RT28XX_MLME_HANDLER(pAd);
974 mb();
975 ret = KILL_THREAD_PID(pObj->MLMEThr_pid, SIGTERM, 1);
976 if (ret)
977 {
978 printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
979 pAd->net_dev->name, GET_PID_NUMBER(pObj->MLMEThr_pid), ret);
980 }
981 else
982 {
983 //wait_for_completion (&pAd->notify);
984 wait_for_completion (&pAd->mlmeComplete);
985 pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
986 }
987 }
988
989 CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
990 {
991 printk("Terminate the RTUSBCmdThr_pid=%d!\n", GET_PID_NUMBER(pObj->RTUSBCmdThr_pid));
992 mb();
993 NdisAcquireSpinLock(&pAd->CmdQLock);
994 pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
995 NdisReleaseSpinLock(&pAd->CmdQLock);
996 mb();
997 //RTUSBCMDUp(pAd);
998 ret = KILL_THREAD_PID(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
999 if (ret)
1000 {
1001 printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
1002 pAd->net_dev->name, GET_PID_NUMBER(pObj->RTUSBCmdThr_pid), ret);
1003 }
1004 else
1005 {
1006 //wait_for_completion (&pAd->notify);
1007 wait_for_completion (&pAd->CmdQComplete);
1008 pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
1009 }
1010 }
1011
1012
1013 // Kill tasklets
1014 pAd->mlme_kill = 0;
1015 pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN;
1016 pAd->TimerFunc_kill = 0;
1017}
1018
1019
1020void kill_thread_task(IN PRTMP_ADAPTER pAd)
1021{
1022 POS_COOKIE pObj;
1023
1024 pObj = (POS_COOKIE) pAd->OS_Cookie;
1025
1026 tasklet_kill(&pObj->rx_done_task);
1027 tasklet_kill(&pObj->mgmt_dma_done_task);
1028 tasklet_kill(&pObj->ac0_dma_done_task);
1029 tasklet_kill(&pObj->ac1_dma_done_task);
1030 tasklet_kill(&pObj->ac2_dma_done_task);
1031 tasklet_kill(&pObj->ac3_dma_done_task);
1032 tasklet_kill(&pObj->hcca_dma_done_task);
1033 tasklet_kill(&pObj->tbtt_task);
1034
1035}
1036
1037
1038/*
1039========================================================================
1040Routine Description:
1041 Check the chipset vendor/product ID.
1042
1043Arguments:
1044 _dev_p Point to the PCI or USB device
1045
1046Return Value:
1047 TRUE Check ok
1048 FALSE Check fail
1049
1050Note:
1051========================================================================
1052*/
1053BOOLEAN RT28XXChipsetCheck(
1054 IN void *_dev_p)
1055{
1056#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1057 struct usb_device *dev_p = (struct usb_device *)_dev_p;
1058#else
1059 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1060 struct usb_device *dev_p = interface_to_usbdev(intf);
1061#endif // LINUX_VERSION_CODE //
1062 UINT32 i;
1063
1064
1065 for(i=0; i<rtusb_usb_id_len; i++)
1066 {
1067 if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
1068 dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
1069 {
1070 printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
1071 dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
1072 break;
1073 }
1074 }
1075
1076 if (i == rtusb_usb_id_len)
1077 {
1078 printk("rt2870: Error! Device Descriptor not matching!\n");
1079 return FALSE;
1080 }
1081
1082 return TRUE;
1083}
1084
1085
1086/*
1087========================================================================
1088Routine Description:
1089 Init net device structure.
1090
1091Arguments:
1092 _dev_p Point to the PCI or USB device
1093 *net_dev Point to the net device
1094 *pAd the raxx interface data pointer
1095
1096Return Value:
1097 TRUE Init ok
1098 FALSE Init fail
1099
1100Note:
1101========================================================================
1102*/
1103BOOLEAN RT28XXNetDevInit(
1104 IN void *_dev_p,
1105 IN struct net_device *net_dev,
1106 IN RTMP_ADAPTER *pAd)
1107{
1108#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1109 struct usb_device *dev_p = (struct usb_device *)_dev_p;
1110#else
1111 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1112 struct usb_device *dev_p = interface_to_usbdev(intf);
1113#endif // LINUX_VERSION_CODE //
1114
1115
1116#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1117 pAd->config = dev_p->config;
1118#else
1119 pAd->config = &dev_p->config->desc;
1120#endif // LINUX_VERSION_CODE //
1121 return TRUE;
1122}
1123
1124
1125/*
1126========================================================================
1127Routine Description:
1128 Init net device structure.
1129
1130Arguments:
1131 _dev_p Point to the PCI or USB device
1132 *pAd the raxx interface data pointer
1133
1134Return Value:
1135 TRUE Config ok
1136 FALSE Config fail
1137
1138Note:
1139========================================================================
1140*/
1141#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1142BOOLEAN RT28XXProbePostConfig(
1143 IN void *_dev_p,
1144 IN RTMP_ADAPTER *pAd,
1145 IN INT32 interface)
1146{
1147 struct usb_device *dev_p = (struct usb_device *)_dev_p;
1148 struct usb_interface *intf;
1149 struct usb_interface_descriptor *iface_desc;
1150 struct usb_endpoint_descriptor *endpoint;
1151 ULONG BulkOutIdx;
1152 UINT32 i;
1153
1154
1155 /* get the active interface descriptor */
1156 intf = &dev_p->actconfig->interface[interface];
1157 iface_desc = &intf->altsetting[0];
1158
1159 /* get # of enpoints */
1160 pAd->NumberOfPipes = iface_desc->bNumEndpoints;
1161 DBGPRINT(RT_DEBUG_TRACE, ("NumEndpoints=%d\n", iface_desc->bNumEndpoints));
1162
1163 /* Configure Pipes */
1164 endpoint = &iface_desc->endpoint[0];
1165 BulkOutIdx = 0;
1166
1167 for(i=0; i<pAd->NumberOfPipes; i++)
1168 {
1169 if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
1170 ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
1171 {
1172 pAd->BulkInEpAddr = endpoint[i].bEndpointAddress;
1173 pAd->BulkInMaxPacketSize = endpoint[i].wMaxPacketSize;
1174
1175 DBGPRINT_RAW(RT_DEBUG_TRACE,
1176 ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
1177 DBGPRINT_RAW(RT_DEBUG_TRACE,
1178 ("EP address = 0x%2x \n", endpoint[i].bEndpointAddress));
1179 }
1180 else if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
1181 ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
1182 {
1183 // There are 6 bulk out EP. EP6 highest priority.
1184 // EP1-4 is EDCA. EP5 is HCCA.
1185 pAd->BulkOutEpAddr[BulkOutIdx++] = endpoint[i].bEndpointAddress;
1186 pAd->BulkOutMaxPacketSize = endpoint[i].wMaxPacketSize;
1187
1188 DBGPRINT_RAW(RT_DEBUG_TRACE,
1189 ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
1190 DBGPRINT_RAW(RT_DEBUG_TRACE,
1191 ("EP address = 0x%2x \n", endpoint[i].bEndpointAddress));
1192 }
1193 }
1194
1195 if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
1196 {
1197 printk("Could not find both bulk-in and bulk-out endpoints\n");
1198 return FALSE;
1199 }
1200
1201 return TRUE;
1202}
1203
1204#else
1205BOOLEAN RT28XXProbePostConfig(
1206 IN void *_dev_p,
1207 IN RTMP_ADAPTER *pAd,
1208 IN INT32 interface)
1209{
1210 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1211 struct usb_host_interface *iface_desc;
1212 ULONG BulkOutIdx;
1213 UINT32 i;
1214
1215
1216 /* get the active interface descriptor */
1217 iface_desc = intf->cur_altsetting;
1218
1219 /* get # of enpoints */
1220 pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
1221 DBGPRINT(RT_DEBUG_TRACE,
1222 ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
1223
1224 /* Configure Pipes */
1225 BulkOutIdx = 0;
1226
1227 for(i=0; i<pAd->NumberOfPipes; i++)
1228 {
1229 if ((iface_desc->endpoint[i].desc.bmAttributes ==
1230 USB_ENDPOINT_XFER_BULK) &&
1231 ((iface_desc->endpoint[i].desc.bEndpointAddress &
1232 USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
1233 {
1234 pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
1235 pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1236
1237 DBGPRINT_RAW(RT_DEBUG_TRACE,
1238 ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
1239 DBGPRINT_RAW(RT_DEBUG_TRACE,
1240 ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
1241 }
1242 else if ((iface_desc->endpoint[i].desc.bmAttributes ==
1243 USB_ENDPOINT_XFER_BULK) &&
1244 ((iface_desc->endpoint[i].desc.bEndpointAddress &
1245 USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
1246 {
1247 // there are 6 bulk out EP. EP6 highest priority.
1248 // EP1-4 is EDCA. EP5 is HCCA.
1249 pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
1250 pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
1251
1252 DBGPRINT_RAW(RT_DEBUG_TRACE,
1253 ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
1254 DBGPRINT_RAW(RT_DEBUG_TRACE,
1255 ("EP address = 0x%2x \n", iface_desc->endpoint[i].desc.bEndpointAddress));
1256 }
1257 }
1258
1259 if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
1260 {
1261 printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __FUNCTION__);
1262 return FALSE;
1263 }
1264
1265 return TRUE;
1266}
1267#endif // LINUX_VERSION_CODE //
1268
1269
1270/*
1271========================================================================
1272Routine Description:
1273 Disable DMA.
1274
1275Arguments:
1276 *pAd the raxx interface data pointer
1277
1278Return Value:
1279 None
1280
1281Note:
1282========================================================================
1283*/
1284VOID RT28XXDMADisable(
1285 IN RTMP_ADAPTER *pAd)
1286{
1287 // no use
1288}
1289
1290
1291
1292/*
1293========================================================================
1294Routine Description:
1295 Enable DMA.
1296
1297Arguments:
1298 *pAd the raxx interface data pointer
1299
1300Return Value:
1301 None
1302
1303Note:
1304========================================================================
1305*/
1306VOID RT28XXDMAEnable(
1307 IN RTMP_ADAPTER *pAd)
1308{
1309 WPDMA_GLO_CFG_STRUC GloCfg;
1310 USB_DMA_CFG_STRUC UsbCfg;
1311 int i = 0;
1312
1313
1314 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
1315 do
1316 {
1317 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1318 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1319 break;
1320
1321 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
1322 RTMPusecDelay(1000);
1323 i++;
1324 }while ( i <200);
1325
1326
1327 RTMPusecDelay(50);
1328 GloCfg.field.EnTXWriteBackDDONE = 1;
1329 GloCfg.field.EnableRxDMA = 1;
1330 GloCfg.field.EnableTxDMA = 1;
1331 DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
1332 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1333
1334 UsbCfg.word = 0;
1335 UsbCfg.field.phyclear = 0;
1336 /* usb version is 1.1,do not use bulk in aggregation */
1337 if (pAd->BulkInMaxPacketSize == 512)
1338 UsbCfg.field.RxBulkAggEn = 1;
1339 /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
1340 UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
1341 UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
1342 UsbCfg.field.RxBulkEn = 1;
1343 UsbCfg.field.TxBulkEn = 1;
1344
1345 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
1346
1347}
1348
1349/*
1350========================================================================
1351Routine Description:
1352 Write Beacon buffer to Asic.
1353
1354Arguments:
1355 *pAd the raxx interface data pointer
1356
1357Return Value:
1358 None
1359
1360Note:
1361========================================================================
1362*/
1363VOID RT28xx_UpdateBeaconToAsic(
1364 IN RTMP_ADAPTER *pAd,
1365 IN INT apidx,
1366 IN ULONG FrameLen,
1367 IN ULONG UpdatePos)
1368{
1369 PUCHAR pBeaconFrame = NULL;
1370 UCHAR *ptr;
1371 UINT i, padding;
1372 BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync;
1373 UINT32 longValue;
1374 BOOLEAN bBcnReq = FALSE;
1375 UCHAR bcn_idx = 0;
1376
1377
1378 if (pBeaconFrame == NULL)
1379 {
1380 DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
1381 return;
1382 }
1383
1384 if (pBeaconSync == NULL)
1385 {
1386 DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
1387 return;
1388 }
1389
1390 //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
1391 // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
1392 // )
1393 if (bBcnReq == FALSE)
1394 {
1395 /* when the ra interface is down, do not send its beacon frame */
1396 /* clear all zero */
1397 for(i=0; i<TXWI_SIZE; i+=4) {
1398 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
1399 }
1400 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1401 NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
1402 }
1403 else
1404 {
1405 ptr = (PUCHAR)&pAd->BeaconTxWI;
1406#ifdef RT_BIG_ENDIAN
1407 RTMPWIEndianChange(ptr, TYPE_TXWI);
1408#endif
1409 if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
1410 { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
1411 pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
1412 NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
1413 }
1414
1415 if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
1416 {
1417 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
1418 {
1419 longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1420 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
1421 ptr += 4;
1422 }
1423 }
1424
1425 ptr = pBeaconSync->BeaconBuf[bcn_idx];
1426 padding = (FrameLen & 0x01);
1427 NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
1428 FrameLen += padding;
1429 for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
1430 {
1431 if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
1432 {
1433 NdisMoveMemory(ptr, pBeaconFrame, 2);
1434 //shortValue = *ptr + (*(ptr+1)<<8);
1435 //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
1436 RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
1437 }
1438 ptr +=2;
1439 pBeaconFrame += 2;
1440 }
1441
1442 pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
1443 }
1444
1445}
1446
1447
1448VOID RT2870_BssBeaconStop(
1449 IN RTMP_ADAPTER *pAd)
1450{
1451 BEACON_SYNC_STRUCT *pBeaconSync;
1452 int i, offset;
1453 BOOLEAN Cancelled = TRUE;
1454
1455 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1456 if (pBeaconSync && pBeaconSync->EnableBeacon)
1457 {
1458 INT NumOfBcn;
1459
1460
1461#ifdef CONFIG_STA_SUPPORT
1462 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1463 {
1464 NumOfBcn = MAX_MESH_NUM;
1465 }
1466#endif // CONFIG_STA_SUPPORT //
1467
1468 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1469
1470 for(i=0; i<NumOfBcn; i++)
1471 {
1472 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1473 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1474
1475 for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
1476 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
1477
1478 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1479 pBeaconSync->TimIELocationInBeacon[i] = 0;
1480 }
1481 pBeaconSync->BeaconBitMap = 0;
1482 pBeaconSync->DtimBitOn = 0;
1483 }
1484}
1485
1486
1487VOID RT2870_BssBeaconStart(
1488 IN RTMP_ADAPTER *pAd)
1489{
1490 int apidx;
1491 BEACON_SYNC_STRUCT *pBeaconSync;
1492// LARGE_INTEGER tsfTime, deltaTime;
1493
1494 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1495 if (pBeaconSync && pBeaconSync->EnableBeacon)
1496 {
1497 INT NumOfBcn;
1498
1499
1500#ifdef CONFIG_STA_SUPPORT
1501 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1502 {
1503 NumOfBcn = MAX_MESH_NUM;
1504 }
1505#endif // CONFIG_STA_SUPPORT //
1506
1507 for(apidx=0; apidx<NumOfBcn; apidx++)
1508 {
1509 UCHAR CapabilityInfoLocationInBeacon = 0;
1510 UCHAR TimIELocationInBeacon = 0;
1511
1512 NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
1513 pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
1514 pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
1515 NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
1516 }
1517 pBeaconSync->BeaconBitMap = 0;
1518 pBeaconSync->DtimBitOn = 0;
1519 pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
1520
1521 pAd->CommonCfg.BeaconAdjust = 0;
1522 pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
1523 pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
1524 printk("RT2870_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
1525 RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
1526
1527 }
1528}
1529
1530
1531VOID RT2870_BssBeaconInit(
1532 IN RTMP_ADAPTER *pAd)
1533{
1534 BEACON_SYNC_STRUCT *pBeaconSync;
1535 int i;
1536
1537 NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
1538 if (pAd->CommonCfg.pBeaconSync)
1539 {
1540 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1541 NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
1542 for(i=0; i < HW_BEACON_MAX_COUNT; i++)
1543 {
1544 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1545 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1546 pBeaconSync->TimIELocationInBeacon[i] = 0;
1547 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1548 }
1549 pBeaconSync->BeaconBitMap = 0;
1550
1551 //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
1552 pBeaconSync->EnableBeacon = TRUE;
1553 }
1554}
1555
1556
1557VOID RT2870_BssBeaconExit(
1558 IN RTMP_ADAPTER *pAd)
1559{
1560 BEACON_SYNC_STRUCT *pBeaconSync;
1561 BOOLEAN Cancelled = TRUE;
1562 int i;
1563
1564 if (pAd->CommonCfg.pBeaconSync)
1565 {
1566 pBeaconSync = pAd->CommonCfg.pBeaconSync;
1567 pBeaconSync->EnableBeacon = FALSE;
1568 RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
1569 pBeaconSync->BeaconBitMap = 0;
1570
1571 for(i=0; i<HW_BEACON_MAX_COUNT; i++)
1572 {
1573 NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
1574 pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
1575 pBeaconSync->TimIELocationInBeacon[i] = 0;
1576 NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
1577 }
1578
1579 NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0);
1580 pAd->CommonCfg.pBeaconSync = NULL;
1581 }
1582}
1583
1584VOID BeaconUpdateExec(
1585 IN PVOID SystemSpecific1,
1586 IN PVOID FunctionContext,
1587 IN PVOID SystemSpecific2,
1588 IN PVOID SystemSpecific3)
1589{
1590 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
1591 LARGE_INTEGER tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
1592 UINT32 delta, remain, remain_low, remain_high;
1593// BOOLEAN positive;
1594
1595 ReSyncBeaconTime(pAd);
1596
1597
1598
1599 RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
1600 RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
1601
1602
1603 //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
1604 remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
1605 remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
1606 remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
1607 delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
1608
1609 pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10;
1610
1611}
1612
diff --git a/drivers/staging/rt2870/Kconfig b/drivers/staging/rt2870/Kconfig
new file mode 100644
index 00000000000..8398d9797e1
--- /dev/null
+++ b/drivers/staging/rt2870/Kconfig
@@ -0,0 +1,6 @@
1config RT2870
2 tristate "Ralink 2870 wireless support"
3 depends on USB && X86 && WLAN_80211
4 ---help---
5 This is an experimental driver for the Ralink 2870 wireless chip.
6
diff --git a/drivers/staging/rt2870/Makefile b/drivers/staging/rt2870/Makefile
new file mode 100644
index 00000000000..1a015f408e6
--- /dev/null
+++ b/drivers/staging/rt2870/Makefile
@@ -0,0 +1,47 @@
1obj-$(CONFIG_RT2870) += rt2870sta.o
2
3# TODO: all of these should be removed
4EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
5EXTRA_CFLAGS += -DRT2870
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
12rt2870sta-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/rt2870/TODO b/drivers/staging/rt2870/TODO
new file mode 100644
index 00000000000..eae1ac47d3f
--- /dev/null
+++ b/drivers/staging/rt2870/TODO
@@ -0,0 +1,10 @@
1TODO:
2 - checkpatch.pl clean
3 - sparse clean
4 - port to in-kernel 80211 stack
5 - remove reading from /etc/ config files
6 - review by the wireless developer community
7
8Please send any patches or complaints about this driver to Greg
9Kroah-Hartman <greg@kroah.com> and don't bother the upstream wireless
10kernel developers about it, they want nothing to do with it.
diff --git a/drivers/staging/rt2870/aironet.h b/drivers/staging/rt2870/aironet.h
new file mode 100644
index 00000000000..1e07b19b8cd
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/ap.h b/drivers/staging/rt2870/ap.h
new file mode 100644
index 00000000000..0dc55751679
--- /dev/null
+++ b/drivers/staging/rt2870/ap.h
@@ -0,0 +1,562 @@
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#ifdef WSC_AP_SUPPORT
494 OUT BOOLEAN *pWscCapable,
495#endif // WSC_AP_SUPPORT //
496 OUT ULONG *pRalinkIe,
497#ifdef DOT11N_DRAFT3
498 OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo,
499#endif // DOT11N_DRAFT3 //
500 OUT UCHAR *pHtCapabilityLen,
501 OUT HT_CAPABILITY_IE *pHtCapability);
502
503BOOLEAN PeerDisassocReqSanity(
504 IN PRTMP_ADAPTER pAd,
505 IN VOID *Msg,
506 IN ULONG MsgLen,
507 OUT PUCHAR pAddr2,
508 OUT USHORT *Reason);
509
510BOOLEAN PeerDeauthReqSanity(
511 IN PRTMP_ADAPTER pAd,
512 IN VOID *Msg,
513 IN ULONG MsgLen,
514 OUT PUCHAR pAddr2,
515 OUT USHORT *Reason);
516
517BOOLEAN APPeerAuthSanity(
518 IN PRTMP_ADAPTER pAd,
519 IN VOID *Msg,
520 IN ULONG MsgLen,
521 OUT PUCHAR pAddr1,
522 OUT PUCHAR pAddr2,
523 OUT USHORT *Alg,
524 OUT USHORT *Seq,
525 OUT USHORT *Status,
526 CHAR *ChlgText);
527
528BOOLEAN APPeerProbeReqSanity(
529 IN PRTMP_ADAPTER pAd,
530 IN VOID *Msg,
531 IN ULONG MsgLen,
532 OUT PUCHAR pAddr2,
533 OUT CHAR Ssid[],
534 OUT UCHAR *SsidLen);
535
536BOOLEAN APPeerBeaconAndProbeRspSanity(
537 IN PRTMP_ADAPTER pAd,
538 IN VOID *Msg,
539 IN ULONG MsgLen,
540 OUT PUCHAR pAddr2,
541 OUT PUCHAR pBssid,
542 OUT CHAR Ssid[],
543 OUT UCHAR *SsidLen,
544 OUT UCHAR *BssType,
545 OUT USHORT *BeaconPeriod,
546 OUT UCHAR *Channel,
547 OUT LARGE_INTEGER *Timestamp,
548 OUT USHORT *CapabilityInfo,
549 OUT UCHAR Rate[],
550 OUT UCHAR *RateLen,
551 OUT BOOLEAN *ExtendedRateIeExist,
552 OUT UCHAR *Erp);
553
554// ap_info.c
555
556
557
558// ================== end of AP RTMP.h ========================
559
560
561#endif // __AP_H__
562
diff --git a/drivers/staging/rt2870/chlist.h b/drivers/staging/rt2870/chlist.h
new file mode 100644
index 00000000000..9e15b9daeb8
--- /dev/null
+++ b/drivers/staging/rt2870/chlist.h
@@ -0,0 +1,1296 @@
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 { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
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#if 0
1205 switch (pAd->CommonCfg.CountryRegion & 0x7f)
1206 {
1207 case REGION_0_BG_BAND: // 1 -11
1208 case REGION_1_BG_BAND: // 1 - 13
1209 case REGION_5_BG_BAND: // 1 - 14
1210 if (Channel <= 4)
1211 {
1212 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
1213 }
1214 else if (Channel >= 8)
1215 {
1216 if ((ChannelNum - Channel) < 4)
1217 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
1218 }
1219 break;
1220
1221 case REGION_2_BG_BAND: // 10 - 11
1222 case REGION_3_BG_BAND: // 10 - 13
1223 case REGION_4_BG_BAND: // 14
1224 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
1225 break;
1226
1227 case REGION_6_BG_BAND: // 3 - 9
1228 if (Channel <= 5)
1229 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
1230 else if (Channel == 6)
1231 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
1232 else if (Channel >= 7)
1233 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
1234 break;
1235
1236 case REGION_7_BG_BAND: // 5 - 13
1237 if (Channel <= 8)
1238 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
1239 else if (Channel >= 10)
1240 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
1241 break;
1242
1243 default: // Error. should never happen
1244 break;
1245 }
1246#endif
1247 }
1248 }
1249
1250
1251}
1252
1253
1254static inline VOID N_SetCenCh(
1255 IN PRTMP_ADAPTER pAd)
1256{
1257 if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
1258 {
1259 if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
1260 {
1261 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
1262 }
1263 else
1264 {
1265 if (pAd->CommonCfg.Channel == 14)
1266 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1;
1267 else
1268 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
1269 }
1270 }
1271 else
1272 {
1273 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1274 }
1275}
1276#endif // DOT11_N_SUPPORT //
1277
1278
1279static inline UINT8 GetCuntryMaxTxPwr(
1280 IN PRTMP_ADAPTER pAd,
1281 IN UINT8 channel)
1282{
1283 int i;
1284 for (i = 0; i < pAd->ChannelListNum; i++)
1285 {
1286 if (pAd->ChannelList[i].Channel == channel)
1287 break;
1288 }
1289
1290 if (i == pAd->ChannelListNum)
1291 return 0xff;
1292 else
1293 return pAd->ChannelList[i].MaxTxPwr;
1294}
1295#endif // __CHLIST_H__
1296
diff --git a/drivers/staging/rt2870/common/2870_rtmp_init.c b/drivers/staging/rt2870/common/2870_rtmp_init.c
new file mode 100644
index 00000000000..359c1820e6d
--- /dev/null
+++ b/drivers/staging/rt2870/common/2870_rtmp_init.c
@@ -0,0 +1,1778 @@
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 for(acidx=0; acidx<4; acidx++)
238 {
239 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
240
241 NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
242 //Allocate URB
243 LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
244 ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
245 done,
246 ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
247 out1);
248
249 NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
250 pHTTXContext->pAd = pAd;
251 pHTTXContext->pIrp = NULL;
252 pHTTXContext->IRPPending = FALSE;
253 pHTTXContext->NextBulkOutPosition = 0;
254 pHTTXContext->ENextBulkOutPosition = 0;
255 pHTTXContext->CurWritePosition = 0;
256 pHTTXContext->CurWriteRealPos = 0;
257 pHTTXContext->BulkOutSize = 0;
258 pHTTXContext->BulkOutPipeId = acidx;
259 pHTTXContext->bRingEmpty = TRUE;
260 pHTTXContext->bCopySavePad = FALSE;
261
262 pAd->BulkOutPending[acidx] = FALSE;
263 }
264
265
266 //
267 // MGMT_RING_SIZE
268 //
269#if 0
270 for(i=0; i<MGMT_RING_SIZE; i++) // 8
271 {
272 PTX_CONTEXT pMLMEContext = &(pAd->MLMEContext[i]);
273
274
275 NdisZeroMemory(pMLMEContext, sizeof(TX_CONTEXT));
276
277 //Allocate URB
278 LM_USB_ALLOC(pObj, pMLMEContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
279 ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i),
280 out2,
281 ("<-- ERROR in Alloc TX MLMEContext[%d] TX_BUFFER !! \n", i),
282 out2);
283
284 pMLMEContext->pAd = pAd;
285 pMLMEContext->pIrp = NULL;
286 pMLMEContext->InUse = FALSE;
287 pMLMEContext->IRPPending = FALSE;
288 }
289#else
290 // Allocate MGMT ring descriptor's memory
291 pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
292 RTMPAllocateMemory(&pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
293 if (pAd->MgmtDescRing.AllocVa == NULL)
294 {
295 DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
296 Status = NDIS_STATUS_RESOURCES;
297 goto out1;
298 }
299 NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
300 RingBaseVa = pAd->MgmtDescRing.AllocVa;
301
302 // Initialize MGMT Ring and associated buffer memory
303 pMgmtRing = &pAd->MgmtRing;
304 for (i = 0; i < MGMT_RING_SIZE; i++)
305 {
306 // link the pre-allocated Mgmt buffer to MgmtRing.Cell
307 pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
308 pMgmtRing->Cell[i].AllocVa = RingBaseVa;
309 pMgmtRing->Cell[i].pNdisPacket = NULL;
310 pMgmtRing->Cell[i].pNextNdisPacket = NULL;
311
312 //Allocate URB for MLMEContext
313 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
314 pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
315 if (pMLMEContext->pUrb == NULL)
316 {
317 DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
318 Status = NDIS_STATUS_RESOURCES;
319 goto out2;
320 }
321 pMLMEContext->pAd = pAd;
322 pMLMEContext->pIrp = NULL;
323 pMLMEContext->TransferBuffer = NULL;
324 pMLMEContext->InUse = FALSE;
325 pMLMEContext->IRPPending = FALSE;
326 pMLMEContext->bWaitingBulkOut = FALSE;
327 pMLMEContext->BulkOutSize = 0;
328 pMLMEContext->SelfIdx = i;
329
330 // Offset to next ring descriptor address
331 RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
332 }
333 DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
334
335 //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
336 pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
337 pAd->MgmtRing.TxCpuIdx = 0;
338 pAd->MgmtRing.TxDmaIdx = 0;
339#endif
340
341 //
342 // BEACON_RING_SIZE
343 //
344 for(i=0; i<BEACON_RING_SIZE; i++) // 2
345 {
346 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
347
348
349 NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
350
351 //Allocate URB
352 LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
353 ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
354 out2,
355 ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
356 out3);
357
358 pBeaconContext->pAd = pAd;
359 pBeaconContext->pIrp = NULL;
360 pBeaconContext->InUse = FALSE;
361 pBeaconContext->IRPPending = FALSE;
362 }
363
364 //
365 // NullContext
366 //
367 NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
368
369 //Allocate URB
370 LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
371 ("<-- ERROR in Alloc TX NullContext urb!! \n"),
372 out3,
373 ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
374 out4);
375
376 pNullContext->pAd = pAd;
377 pNullContext->pIrp = NULL;
378 pNullContext->InUse = FALSE;
379 pNullContext->IRPPending = FALSE;
380
381 //
382 // RTSContext
383 //
384 NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
385
386 //Allocate URB
387 LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
388 ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
389 out4,
390 ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
391 out5);
392
393 pRTSContext->pAd = pAd;
394 pRTSContext->pIrp = NULL;
395 pRTSContext->InUse = FALSE;
396 pRTSContext->IRPPending = FALSE;
397
398 //
399 // PsPollContext
400 //
401 //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
402 //Allocate URB
403 LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
404 ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
405 out5,
406 ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
407 out6);
408
409 pPsPollContext->pAd = pAd;
410 pPsPollContext->pIrp = NULL;
411 pPsPollContext->InUse = FALSE;
412 pPsPollContext->IRPPending = FALSE;
413 pPsPollContext->bAggregatible = FALSE;
414 pPsPollContext->LastOne = TRUE;
415
416 } while (FALSE);
417
418
419done:
420 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit\n"));
421
422 return Status;
423
424 /* --------------------------- ERROR HANDLE --------------------------- */
425out6:
426 LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
427
428out5:
429 LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
430
431out4:
432 LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
433
434out3:
435 for(i=0; i<BEACON_RING_SIZE; i++)
436 {
437 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
438 if (pBeaconContext)
439 LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
440 }
441
442out2:
443 if (pAd->MgmtDescRing.AllocVa)
444 {
445 pMgmtRing = &pAd->MgmtRing;
446 for(i=0; i<MGMT_RING_SIZE; i++)
447 {
448 pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
449 if (pMLMEContext)
450 LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
451 }
452 NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
453 pAd->MgmtDescRing.AllocVa = NULL;
454 }
455
456out1:
457 for (acidx = 0; acidx < 4; acidx++)
458 {
459 PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
460 if (pTxContext)
461 LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
462 }
463
464 // Here we didn't have any pre-allocated memory need to free.
465
466 return Status;
467}
468
469
470/*
471========================================================================
472Routine Description:
473 Allocate DMA memory blocks for send, receive.
474
475Arguments:
476 pAd Pointer to our adapter
477
478Return Value:
479 NDIS_STATUS_SUCCESS
480 NDIS_STATUS_FAILURE
481 NDIS_STATUS_RESOURCES
482
483Note:
484========================================================================
485*/
486NDIS_STATUS RTMPAllocTxRxRingMemory(
487 IN PRTMP_ADAPTER pAd)
488{
489// COUNTER_802_11 pCounter = &pAd->WlanCounters;
490 NDIS_STATUS Status;
491 INT num;
492
493
494 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
495
496
497 do
498 {
499 // Init the CmdQ and CmdQLock
500 NdisAllocateSpinLock(&pAd->CmdQLock);
501 NdisAcquireSpinLock(&pAd->CmdQLock);
502 RTUSBInitializeCmdQ(&pAd->CmdQ);
503 NdisReleaseSpinLock(&pAd->CmdQLock);
504
505
506 NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
507 //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
508 NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
509 NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
510 NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
511 NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
512 NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
513 NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
514 NdisAllocateSpinLock(&pAd->BulkInLock);
515
516 for (num = 0; num < NUM_OF_TX_RING; num++)
517 {
518 NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
519 }
520
521#ifdef RALINK_ATE
522 NdisAllocateSpinLock(&pAd->GenericLock);
523#endif // RALINK_ATE //
524
525// NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX
526
527// NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
528// NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
529
530// for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
531// {
532// NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
533// }
534
535 //
536 // Init Mac Table
537 //
538// MacTableInitialize(pAd);
539
540 //
541 // Init send data structures and related parameters
542 //
543 Status = NICInitTransmit(pAd);
544 if (Status != NDIS_STATUS_SUCCESS)
545 break;
546
547 //
548 // Init receive data structures and related parameters
549 //
550 Status = NICInitRecv(pAd);
551 if (Status != NDIS_STATUS_SUCCESS)
552 break;
553
554 pAd->PendingIoCount = 1;
555
556 } while (FALSE);
557
558 NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
559 pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
560
561 if (pAd->FragFrame.pFragPacket == NULL)
562 {
563 Status = NDIS_STATUS_RESOURCES;
564 }
565
566 DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
567 return Status;
568}
569
570
571/*
572========================================================================
573Routine Description:
574 Calls USB_InterfaceStop and frees memory allocated for the URBs
575 calls NdisMDeregisterDevice and frees the memory
576 allocated in VNetInitialize for the Adapter Object
577
578Arguments:
579 *pAd the raxx interface data pointer
580
581Return Value:
582 None
583
584Note:
585========================================================================
586*/
587VOID RTMPFreeTxRxRingMemory(
588 IN PRTMP_ADAPTER pAd)
589{
590#define LM_URB_FREE(pObj, Context, BufferSize) \
591 if (NULL != Context->pUrb) { \
592 RTUSB_UNLINK_URB(Context->pUrb); \
593 RTUSB_FREE_URB(Context->pUrb); \
594 Context->pUrb = NULL; } \
595 if (NULL != Context->TransferBuffer) { \
596 RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
597 Context->TransferBuffer, \
598 Context->data_dma); \
599 Context->TransferBuffer = NULL; }
600
601
602 UINT i, acidx;
603 PTX_CONTEXT pNullContext = &pAd->NullContext;
604 PTX_CONTEXT pPsPollContext = &pAd->PsPollContext;
605 PTX_CONTEXT pRTSContext = &pAd->RTSContext;
606// PHT_TX_CONTEXT pHTTXContext;
607 //PRTMP_REORDERBUF pReorderBuf;
608 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
609// RTMP_TX_RING *pTxRing;
610
611 DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
612 pObj = pObj;
613
614 // Free all resources for the RECEIVE buffer queue.
615 for(i=0; i<(RX_RING_SIZE); i++)
616 {
617 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
618 if (pRxContext)
619 LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
620 }
621
622 // Free PsPoll frame resource
623 LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
624
625 // Free NULL frame resource
626 LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
627
628 // Free RTS frame resource
629 LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
630
631
632 // Free beacon frame resource
633 for(i=0; i<BEACON_RING_SIZE; i++)
634 {
635 PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
636 if (pBeaconContext)
637 LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
638 }
639
640
641 // Free mgmt frame resource
642 for(i = 0; i < MGMT_RING_SIZE; i++)
643 {
644 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
645 //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
646 if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
647 {
648 RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
649 pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
650 pMLMEContext->TransferBuffer = NULL;
651 }
652
653 if (pMLMEContext)
654 {
655 if (NULL != pMLMEContext->pUrb)
656 {
657 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
658 RTUSB_FREE_URB(pMLMEContext->pUrb);
659 pMLMEContext->pUrb = NULL;
660 }
661 }
662 }
663 if (pAd->MgmtDescRing.AllocVa)
664 NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
665
666
667 // Free Tx frame resource
668 for (acidx = 0; acidx < 4; acidx++)
669 {
670 PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
671 if (pHTTXContext)
672 LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
673 }
674
675 if (pAd->FragFrame.pFragPacket)
676 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
677
678 for(i=0; i<6; i++)
679 {
680 NdisFreeSpinLock(&pAd->BulkOutLock[i]);
681 }
682
683 NdisFreeSpinLock(&pAd->BulkInLock);
684 NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
685
686 NdisFreeSpinLock(&pAd->CmdQLock);
687#ifdef RALINK_ATE
688 NdisFreeSpinLock(&pAd->GenericLock);
689#endif // RALINK_ATE //
690 // Clear all pending bulk-out request flags.
691 RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
692
693// NdisFreeSpinLock(&pAd->MacTabLock);
694
695// for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
696// {
697// NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
698// }
699
700 DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n"));
701}
702
703
704/*
705========================================================================
706Routine Description:
707 Allocate memory for adapter control block.
708
709Arguments:
710 pAd Pointer to our adapter
711
712Return Value:
713 NDIS_STATUS_SUCCESS
714 NDIS_STATUS_FAILURE
715 NDIS_STATUS_RESOURCES
716
717Note:
718========================================================================
719*/
720NDIS_STATUS AdapterBlockAllocateMemory(
721 IN PVOID handle,
722 OUT PVOID *ppAd)
723{
724 PUSB_DEV usb_dev;
725 POS_COOKIE pObj = (POS_COOKIE) handle;
726
727
728 usb_dev = pObj->pUsb_Dev;
729
730 pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
731 pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
732
733 *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
734
735 if (*ppAd)
736 {
737 NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
738 ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
739 return (NDIS_STATUS_SUCCESS);
740 }
741 else
742 {
743 return (NDIS_STATUS_FAILURE);
744 }
745}
746
747
748/*
749========================================================================
750Routine Description:
751 Create kernel threads & tasklets.
752
753Arguments:
754 *net_dev Pointer to wireless net device interface
755
756Return Value:
757 NDIS_STATUS_SUCCESS
758 NDIS_STATUS_FAILURE
759
760Note:
761========================================================================
762*/
763NDIS_STATUS CreateThreads(
764 IN struct net_device *net_dev)
765{
766 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) net_dev->priv;
767 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
768 pid_t pid_number = -1;
769
770 //init_MUTEX(&(pAd->usbdev_semaphore));
771
772 init_MUTEX_LOCKED(&(pAd->mlme_semaphore));
773 init_completion (&pAd->mlmeComplete);
774
775 init_MUTEX_LOCKED(&(pAd->RTUSBCmd_semaphore));
776 init_completion (&pAd->CmdQComplete);
777
778 init_MUTEX_LOCKED(&(pAd->RTUSBTimer_semaphore));
779 init_completion (&pAd->TimerQComplete);
780
781 // Creat MLME Thread
782 pObj->MLMEThr_pid= THREAD_PID_INIT_VALUE;
783 pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
784 if (pid_number < 0)
785 {
786 printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
787 return NDIS_STATUS_FAILURE;
788 }
789 pObj->MLMEThr_pid = GET_PID(pid_number);
790 // Wait for the thread to start
791 wait_for_completion(&(pAd->mlmeComplete));
792
793 // Creat Command Thread
794 pObj->RTUSBCmdThr_pid= THREAD_PID_INIT_VALUE;
795 pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
796 if (pid_number < 0)
797 {
798 printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
799 return NDIS_STATUS_FAILURE;
800 }
801 pObj->RTUSBCmdThr_pid = GET_PID(pid_number);
802 wait_for_completion(&(pAd->CmdQComplete));
803
804 pObj->TimerQThr_pid= THREAD_PID_INIT_VALUE;
805 pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
806 if (pid_number < 0)
807 {
808 printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
809 return NDIS_STATUS_FAILURE;
810 }
811 pObj->TimerQThr_pid = GET_PID(pid_number);
812 // Wait for the thread to start
813 wait_for_completion(&(pAd->TimerQComplete));
814
815 // Create receive tasklet
816 tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd);
817 tasklet_init(&pObj->mgmt_dma_done_task, rt2870_mgmt_dma_done_tasklet, (unsigned long)pAd);
818 tasklet_init(&pObj->ac0_dma_done_task, rt2870_ac0_dma_done_tasklet, (unsigned long)pAd);
819 tasklet_init(&pObj->ac1_dma_done_task, rt2870_ac1_dma_done_tasklet, (unsigned long)pAd);
820 tasklet_init(&pObj->ac2_dma_done_task, rt2870_ac2_dma_done_tasklet, (unsigned long)pAd);
821 tasklet_init(&pObj->ac3_dma_done_task, rt2870_ac3_dma_done_tasklet, (unsigned long)pAd);
822 tasklet_init(&pObj->hcca_dma_done_task, rt2870_hcca_dma_done_tasklet, (unsigned long)pAd);
823 tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
824 tasklet_init(&pObj->null_frame_complete_task, rt2870_null_frame_complete_tasklet, (unsigned long)pAd);
825 tasklet_init(&pObj->rts_frame_complete_task, rt2870_rts_frame_complete_tasklet, (unsigned long)pAd);
826 tasklet_init(&pObj->pspoll_frame_complete_task, rt2870_pspoll_frame_complete_tasklet, (unsigned long)pAd);
827
828 return NDIS_STATUS_SUCCESS;
829}
830
831
832#ifdef CONFIG_STA_SUPPORT
833/*
834========================================================================
835Routine Description:
836 As STA's BSSID is a WC too, it uses shared key table.
837 This function write correct unicast TX key to ASIC WCID.
838 And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
839 Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
840 Caller guarantee WEP calls this function when set Txkey, default key index=0~3.
841
842Arguments:
843 pAd Pointer to our adapter
844 pKey Pointer to the where the key stored
845
846Return Value:
847 NDIS_SUCCESS Add key successfully
848
849Note:
850========================================================================
851*/
852VOID RTMPAddBSSIDCipher(
853 IN PRTMP_ADAPTER pAd,
854 IN UCHAR Aid,
855 IN PNDIS_802_11_KEY pKey,
856 IN UCHAR CipherAlg)
857{
858 PUCHAR pTxMic, pRxMic;
859 BOOLEAN bKeyRSC, bAuthenticator; // indicate the receive SC set by KeyRSC value
860// UCHAR CipherAlg;
861 UCHAR i;
862 ULONG WCIDAttri;
863 USHORT offset;
864 UCHAR KeyIdx, IVEIV[8];
865 UINT32 Value;
866
867 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddBSSIDCipher==> Aid = %d\n",Aid));
868
869 // Bit 29 of Add-key KeyRSC
870 bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
871
872 // Bit 28 of Add-key Authenticator
873 bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
874 KeyIdx = (UCHAR)pKey->KeyIndex&0xff;
875
876 if (KeyIdx > 4)
877 return;
878
879
880 if (pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg == CIPHER_TKIP)
881 { if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
882 {
883 // for WPA-None Tx, Rx MIC is the same
884 pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
885 pRxMic = pTxMic;
886 }
887 else if (bAuthenticator == TRUE)
888 {
889 pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
890 pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
891 }
892 else
893 {
894 pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
895 pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
896 }
897
898 offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x10;
899 for (i=0; i<8; )
900 {
901 Value = *(pTxMic+i);
902 Value += (*(pTxMic+i+1)<<8);
903 Value += (*(pTxMic+i+2)<<16);
904 Value += (*(pTxMic+i+3)<<24);
905 RTUSBWriteMACRegister(pAd, offset+i, Value);
906 i+=4;
907 }
908
909 offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x18;
910 for (i=0; i<8; )
911 {
912 Value = *(pRxMic+i);
913 Value += (*(pRxMic+i+1)<<8);
914 Value += (*(pRxMic+i+2)<<16);
915 Value += (*(pRxMic+i+3)<<24);
916 RTUSBWriteMACRegister(pAd, offset+i, Value);
917 i+=4;
918 }
919
920 // Only Key lenth equal to TKIP key have these
921 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxMic, pRxMic, 8);
922 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.TxMic, pTxMic, 8);
923
924 DBGPRINT(RT_DEBUG_TRACE,
925 (" TxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
926 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],
927 pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
928 DBGPRINT(RT_DEBUG_TRACE,
929 (" RxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
930 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],
931 pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
932 }
933
934 // 2. Record Security Key.
935 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen= (UCHAR)pKey->KeyLength;
936 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
937
938 // 3. Check RxTsc. And used to init to ASIC IV.
939 if (bKeyRSC == TRUE)
940 NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, &pKey->KeyRSC, 6);
941 else
942 NdisZeroMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, 6);
943
944 // 4. Init TxTsc to one based on WiFi WPA specs
945 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[0] = 1;
946 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[1] = 0;
947 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[2] = 0;
948 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[3] = 0;
949 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[4] = 0;
950 pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[5] = 0;
951
952 CipherAlg = pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg;
953
954 offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE);
955 RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial,
956 ((pKey->KeyLength == LEN_TKIP_KEY) ? 16 : (USHORT)pKey->KeyLength));
957
958 offset = SHARED_KEY_TABLE_BASE + (KeyIdx * HW_KEY_ENTRY_SIZE);
959 RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial, (USHORT)pKey->KeyLength);
960
961 offset = PAIRWISE_IVEIV_TABLE_BASE + (Aid * HW_IVEIV_ENTRY_SIZE);
962 NdisZeroMemory(IVEIV, 8);
963
964 // IV/EIV
965 if ((CipherAlg == CIPHER_TKIP) ||
966 (CipherAlg == CIPHER_TKIP_NO_MIC) ||
967 (CipherAlg == CIPHER_AES))
968 {
969 IVEIV[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key
970 }
971 // default key idx needs to set.
972 // in TKIP/AES KeyIdx = 0 , WEP KeyIdx is default tx key.
973 else
974 {
975 IVEIV[3] |= (KeyIdx<< 6);
976 }
977 RTUSBMultiWrite(pAd, (USHORT) offset, IVEIV, 8);
978
979 // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
980 if ((CipherAlg == CIPHER_TKIP) ||
981 (CipherAlg == CIPHER_TKIP_NO_MIC) ||
982 (CipherAlg == CIPHER_AES))
983 {
984 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
985 }
986 else
987 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
988
989 offset = MAC_WCID_ATTRIBUTE_BASE + (Aid* HW_WCID_ATTRI_SIZE);
990 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
991 RTUSBReadMACRegister(pAd, offset, &Value);
992
993 DBGPRINT(RT_DEBUG_TRACE, ("BSSID_WCID : offset = %x, WCIDAttri = %lx\n",
994 offset, WCIDAttri));
995
996 // pAddr
997 // Add Bssid mac address at linkup. not here. check!
998 /*offset = MAC_WCID_BASE + (BSSID_WCID * HW_WCID_ENTRY_SIZE);
999 *for (i=0; i<MAC_ADDR_LEN; i++)
1000 {
1001 RTMP_IO_WRITE8(pAd, offset+i, pKey->BSSID[i]);
1002 }
1003 */
1004
1005 DBGPRINT(RT_DEBUG_ERROR, ("AddBSSIDasWCIDEntry: Alg=%s, KeyLength = %d\n",
1006 CipherName[CipherAlg], pKey->KeyLength));
1007 DBGPRINT(RT_DEBUG_TRACE, ("Key [idx=%x] [KeyLen = %d]\n",
1008 pKey->KeyIndex, pKey->KeyLength));
1009 for(i=0; i<pKey->KeyLength; i++)
1010 DBGPRINT_RAW(RT_DEBUG_TRACE,(" %x:", pKey->KeyMaterial[i]));
1011 DBGPRINT(RT_DEBUG_TRACE,(" \n"));
1012}
1013#endif // CONFIG_STA_SUPPORT //
1014
1015/*
1016========================================================================
1017Routine Description:
1018 Get a received packet.
1019
1020Arguments:
1021 pAd device control block
1022 pSaveRxD receive descriptor information
1023 *pbReschedule need reschedule flag
1024 *pRxPending pending received packet flag
1025
1026Return Value:
1027 the recieved packet
1028
1029Note:
1030========================================================================
1031*/
1032#define RT2870_RXDMALEN_FIELD_SIZE 4
1033PNDIS_PACKET GetPacketFromRxRing(
1034 IN PRTMP_ADAPTER pAd,
1035 OUT PRT28XX_RXD_STRUC pSaveRxD,
1036 OUT BOOLEAN *pbReschedule,
1037 IN OUT UINT32 *pRxPending)
1038{
1039 PRX_CONTEXT pRxContext;
1040 PNDIS_PACKET pSkb;
1041 PUCHAR pData;
1042 ULONG ThisFrameLen;
1043 ULONG RxBufferLength;
1044 PRXWI_STRUC pRxWI;
1045
1046 pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
1047 if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
1048 return NULL;
1049
1050 RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
1051 if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC)))
1052 {
1053 goto label_null;
1054 }
1055
1056 pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
1057 // The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
1058 ThisFrameLen = *pData + (*(pData+1)<<8);
1059 if (ThisFrameLen == 0)
1060 {
1061 DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
1062 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
1063 goto label_null;
1064 }
1065 if ((ThisFrameLen&0x3) != 0)
1066 {
1067 DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
1068 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
1069 goto label_null;
1070 }
1071
1072 if ((ThisFrameLen + 8)> RxBufferLength) // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
1073 {
1074 DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
1075 pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition));
1076
1077 // error frame. finish this loop
1078 goto label_null;
1079 }
1080
1081 // skip USB frame length field
1082 pData += RT2870_RXDMALEN_FIELD_SIZE;
1083 pRxWI = (PRXWI_STRUC)pData;
1084#ifdef RT_BIG_ENDIAN
1085 RTMPWIEndianChange(pData, TYPE_RXWI);
1086#endif // RT_BIG_ENDIAN //
1087 if (pRxWI->MPDUtotalByteCount > ThisFrameLen)
1088 {
1089 DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
1090 __FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen));
1091 goto label_null;
1092 }
1093#ifdef RT_BIG_ENDIAN
1094 RTMPWIEndianChange(pData, TYPE_RXWI);
1095#endif // RT_BIG_ENDIAN //
1096
1097 // allocate a rx packet
1098 pSkb = dev_alloc_skb(ThisFrameLen);
1099 if (pSkb == NULL)
1100 {
1101 DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__));
1102 goto label_null;
1103 }
1104
1105 // copy the rx packet
1106 memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
1107 RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
1108 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
1109
1110 // copy RxD
1111 *pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen);
1112#ifdef RT_BIG_ENDIAN
1113 RTMPDescriptorEndianChange((PUCHAR)pSaveRxD, TYPE_RXINFO);
1114#endif // RT_BIG_ENDIAN //
1115
1116 // update next packet read position.
1117 pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
1118
1119 return pSkb;
1120
1121label_null:
1122
1123 return NULL;
1124}
1125
1126
1127/*
1128========================================================================
1129Routine Description:
1130 Handle received packets.
1131
1132Arguments:
1133 data - URB information pointer
1134
1135Return Value:
1136 None
1137
1138Note:
1139========================================================================
1140*/
1141static void rx_done_tasklet(unsigned long data)
1142{
1143 purbb_t pUrb;
1144 PRX_CONTEXT pRxContext;
1145 PRTMP_ADAPTER pAd;
1146 NTSTATUS Status;
1147 unsigned int IrqFlags;
1148
1149 pUrb = (purbb_t)data;
1150 pRxContext = (PRX_CONTEXT)pUrb->context;
1151 pAd = pRxContext->pAd;
1152 Status = pUrb->status;
1153
1154
1155 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1156 pRxContext->InUse = FALSE;
1157 pRxContext->IRPPending = FALSE;
1158 pRxContext->BulkInOffset += pUrb->actual_length;
1159 //NdisInterlockedDecrement(&pAd->PendingRx);
1160 pAd->PendingRx--;
1161
1162 if (Status == USB_ST_NOERROR)
1163 {
1164 pAd->BulkInComplete++;
1165 pAd->NextRxBulkInPosition = 0;
1166 if (pRxContext->BulkInOffset) // As jan's comment, it may bulk-in success but size is zero.
1167 {
1168 pRxContext->Readable = TRUE;
1169 INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
1170 }
1171 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1172 }
1173 else // STATUS_OTHER
1174 {
1175 pAd->BulkInCompleteFail++;
1176 // Still read this packet although it may comtain wrong bytes.
1177 pRxContext->Readable = FALSE;
1178 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1179
1180 // Parsing all packets. because after reset, the index will reset to all zero.
1181 if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1182 fRTMP_ADAPTER_BULKIN_RESET |
1183 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1184 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1185 {
1186
1187 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
1188 Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
1189
1190 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1191 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
1192 }
1193 }
1194
1195 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1196
1197#ifdef RALINK_ATE
1198 if (ATE_ON(pAd))
1199 {
1200 // If the driver is in ATE mode and Rx frame is set into here.
1201 if (pAd->ContinBulkIn == TRUE)
1202 {
1203 RTUSBBulkReceive(pAd);
1204 }
1205 }
1206 else
1207#endif // RALINK_ATE //
1208 RTUSBBulkReceive(pAd);
1209
1210 return;
1211
1212}
1213
1214
1215static void rt2870_mgmt_dma_done_tasklet(unsigned long data)
1216{
1217 PRTMP_ADAPTER pAd;
1218 PTX_CONTEXT pMLMEContext;
1219 int index;
1220 PNDIS_PACKET pPacket;
1221 purbb_t pUrb;
1222 NTSTATUS Status;
1223 unsigned long IrqFlags;
1224
1225
1226 pUrb = (purbb_t)data;
1227 pMLMEContext = (PTX_CONTEXT)pUrb->context;
1228 pAd = pMLMEContext->pAd;
1229 Status = pUrb->status;
1230 index = pMLMEContext->SelfIdx;
1231
1232 ASSERT((pAd->MgmtRing.TxDmaIdx == index));
1233
1234 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1235
1236
1237 if (Status != USB_ST_NOERROR)
1238 {
1239 //Bulk-Out fail status handle
1240 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1241 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1242 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1243 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1244 {
1245 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
1246 // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
1247 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1248 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1249 }
1250 }
1251
1252 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1253 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1254
1255 RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1256 // Reset MLME context flags
1257 pMLMEContext->IRPPending = FALSE;
1258 pMLMEContext->InUse = FALSE;
1259 pMLMEContext->bWaitingBulkOut = FALSE;
1260 pMLMEContext->BulkOutSize = 0;
1261
1262 pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
1263 pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
1264
1265 // Increase MgmtRing Index
1266 INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
1267 pAd->MgmtRing.TxSwFreeIdx++;
1268 RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1269
1270 // No-matter success or fail, we free the mgmt packet.
1271 if (pPacket)
1272 RTMPFreeNdisPacket(pAd, pPacket);
1273
1274 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1275 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1276 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1277 {
1278 // do nothing and return directly.
1279 }
1280 else
1281 {
1282 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) &&
1283 ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
1284 { // For Mgmt Bulk-Out failed, ignore it now.
1285 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1286 }
1287 else
1288 {
1289
1290 // Always call Bulk routine, even reset bulk.
1291 // The protectioon of rest bulk should be in BulkOut routine
1292 if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
1293 {
1294 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
1295 }
1296 RTUSBKickBulkOut(pAd);
1297 }
1298 }
1299
1300}
1301
1302
1303static void rt2870_hcca_dma_done_tasklet(unsigned long data)
1304{
1305 PRTMP_ADAPTER pAd;
1306 PHT_TX_CONTEXT pHTTXContext;
1307 UCHAR BulkOutPipeId = 4;
1308 purbb_t pUrb;
1309
1310
1311 DBGPRINT_RAW(RT_DEBUG_ERROR, ("--->hcca_dma_done_tasklet\n"));
1312
1313
1314 pUrb = (purbb_t)data;
1315 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1316 pAd = pHTTXContext->pAd;
1317
1318 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1319
1320 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1321 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1322 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1323 {
1324 // do nothing and return directly.
1325 }
1326 else
1327 {
1328 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1329 {
1330 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1331 }
1332 else
1333 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1334 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1335 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1336 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1337 (pHTTXContext->bCurWriting == FALSE))
1338 {
1339 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1340 }
1341
1342 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
1343 RTUSBKickBulkOut(pAd);
1344 }
1345 }
1346
1347 DBGPRINT_RAW(RT_DEBUG_ERROR, ("<---hcca_dma_done_tasklet\n"));
1348
1349 return;
1350}
1351
1352
1353static void rt2870_ac3_dma_done_tasklet(unsigned long data)
1354{
1355 PRTMP_ADAPTER pAd;
1356 PHT_TX_CONTEXT pHTTXContext;
1357 UCHAR BulkOutPipeId = 3;
1358 purbb_t pUrb;
1359
1360
1361 pUrb = (purbb_t)data;
1362 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1363 pAd = pHTTXContext->pAd;
1364
1365 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1366
1367 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1368 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1369 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1370 {
1371 // do nothing and return directly.
1372 }
1373 else
1374 {
1375 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1376 {
1377 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1378 }
1379 else
1380 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1381 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1382 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1383 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1384 (pHTTXContext->bCurWriting == FALSE))
1385 {
1386 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1387 }
1388
1389 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3);
1390 RTUSBKickBulkOut(pAd);
1391 }
1392 }
1393
1394
1395 return;
1396}
1397
1398
1399static void rt2870_ac2_dma_done_tasklet(unsigned long data)
1400{
1401 PRTMP_ADAPTER pAd;
1402 PHT_TX_CONTEXT pHTTXContext;
1403 UCHAR BulkOutPipeId = 2;
1404 purbb_t pUrb;
1405
1406
1407 pUrb = (purbb_t)data;
1408 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1409 pAd = pHTTXContext->pAd;
1410
1411 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1412
1413 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1414 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1415 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1416 {
1417 // do nothing and return directly.
1418 }
1419 else
1420 {
1421 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1422 {
1423 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1424 }
1425 else
1426 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1427 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1428 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1429 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1430 (pHTTXContext->bCurWriting == FALSE))
1431 {
1432 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1433 }
1434
1435 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2);
1436 RTUSBKickBulkOut(pAd);
1437 }
1438 }
1439
1440 return;
1441}
1442
1443
1444static void rt2870_ac1_dma_done_tasklet(unsigned long data)
1445{
1446 PRTMP_ADAPTER pAd;
1447 PHT_TX_CONTEXT pHTTXContext;
1448 UCHAR BulkOutPipeId = 1;
1449 purbb_t pUrb;
1450
1451
1452 pUrb = (purbb_t)data;
1453 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1454 pAd = pHTTXContext->pAd;
1455
1456 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1457
1458 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1459 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1460 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1461 {
1462 // do nothing and return directly.
1463 }
1464 else
1465 {
1466 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1467 {
1468 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1469 }
1470 else
1471 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1472 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1473 /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1474 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1475 (pHTTXContext->bCurWriting == FALSE))
1476 {
1477 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1478 }
1479
1480 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1);
1481 RTUSBKickBulkOut(pAd);
1482 }
1483 }
1484
1485
1486 return;
1487}
1488
1489
1490static void rt2870_ac0_dma_done_tasklet(unsigned long data)
1491{
1492 PRTMP_ADAPTER pAd;
1493 PHT_TX_CONTEXT pHTTXContext;
1494 UCHAR BulkOutPipeId = 0;
1495 purbb_t pUrb;
1496
1497
1498 pUrb = (purbb_t)data;
1499 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1500 pAd = pHTTXContext->pAd;
1501
1502 rt2870_dataout_complete_tasklet((unsigned long)pUrb);
1503
1504 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1505 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1506 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1507 {
1508 // do nothing and return directly.
1509 }
1510 else
1511 {
1512 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
1513 {
1514 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1515 }
1516 else
1517 { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
1518 if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
1519 /* ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
1520 (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
1521 (pHTTXContext->bCurWriting == FALSE))
1522 {
1523 RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
1524 }
1525
1526 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
1527 RTUSBKickBulkOut(pAd);
1528 }
1529 }
1530
1531
1532 return;
1533
1534}
1535
1536
1537static void rt2870_null_frame_complete_tasklet(unsigned long data)
1538{
1539 PRTMP_ADAPTER pAd;
1540 PTX_CONTEXT pNullContext;
1541 purbb_t pUrb;
1542 NTSTATUS Status;
1543 unsigned long irqFlag;
1544
1545
1546 pUrb = (purbb_t)data;
1547 pNullContext = (PTX_CONTEXT)pUrb->context;
1548 pAd = pNullContext->pAd;
1549 Status = pUrb->status;
1550
1551 // Reset Null frame context flags
1552 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
1553 pNullContext->IRPPending = FALSE;
1554 pNullContext->InUse = FALSE;
1555 pAd->BulkOutPending[0] = FALSE;
1556 pAd->watchDogTxPendingCnt[0] = 0;
1557
1558 if (Status == USB_ST_NOERROR)
1559 {
1560 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1561
1562 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1563 }
1564 else // STATUS_OTHER
1565 {
1566 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1567 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1568 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1569 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1570 {
1571 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status));
1572 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1573 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1574 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1575 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1576 }
1577 else
1578 {
1579 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1580 }
1581 }
1582
1583 // Always call Bulk routine, even reset bulk.
1584 // The protectioon of rest bulk should be in BulkOut routine
1585 RTUSBKickBulkOut(pAd);
1586
1587}
1588
1589
1590static void rt2870_rts_frame_complete_tasklet(unsigned long data)
1591{
1592 PRTMP_ADAPTER pAd;
1593 PTX_CONTEXT pRTSContext;
1594 purbb_t pUrb;
1595 NTSTATUS Status;
1596 unsigned long irqFlag;
1597
1598
1599 pUrb = (purbb_t)data;
1600 pRTSContext = (PTX_CONTEXT)pUrb->context;
1601 pAd = pRTSContext->pAd;
1602 Status = pUrb->status;
1603
1604 // Reset RTS frame context flags
1605 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
1606 pRTSContext->IRPPending = FALSE;
1607 pRTSContext->InUse = FALSE;
1608
1609 if (Status == USB_ST_NOERROR)
1610 {
1611 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1612 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1613 }
1614 else // STATUS_OTHER
1615 {
1616 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1617 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1618 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1619 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1620 {
1621 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
1622 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1623 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1624 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1625 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1626 }
1627 else
1628 {
1629 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
1630 }
1631 }
1632
1633 RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
1634 pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
1635 RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
1636
1637 // Always call Bulk routine, even reset bulk.
1638 // The protectioon of rest bulk should be in BulkOut routine
1639 RTUSBKickBulkOut(pAd);
1640
1641}
1642
1643
1644static void rt2870_pspoll_frame_complete_tasklet(unsigned long data)
1645{
1646 PRTMP_ADAPTER pAd;
1647 PTX_CONTEXT pPsPollContext;
1648 purbb_t pUrb;
1649 NTSTATUS Status;
1650
1651
1652 pUrb = (purbb_t)data;
1653 pPsPollContext = (PTX_CONTEXT)pUrb->context;
1654 pAd = pPsPollContext->pAd;
1655 Status = pUrb->status;
1656
1657 // Reset PsPoll context flags
1658 pPsPollContext->IRPPending = FALSE;
1659 pPsPollContext->InUse = FALSE;
1660 pAd->watchDogTxPendingCnt[0] = 0;
1661
1662 if (Status == USB_ST_NOERROR)
1663 {
1664 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1665 }
1666 else // STATUS_OTHER
1667 {
1668 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1669 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1670 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1671 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1672 {
1673 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
1674 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1675 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1676 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1677 }
1678 }
1679
1680 RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
1681 pAd->BulkOutPending[0] = FALSE;
1682 RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
1683
1684 // Always call Bulk routine, even reset bulk.
1685 // The protectioon of rest bulk should be in BulkOut routine
1686 RTUSBKickBulkOut(pAd);
1687
1688}
1689
1690
1691static void rt2870_dataout_complete_tasklet(unsigned long data)
1692{
1693 PRTMP_ADAPTER pAd;
1694 purbb_t pUrb;
1695 POS_COOKIE pObj;
1696 PHT_TX_CONTEXT pHTTXContext;
1697 UCHAR BulkOutPipeId;
1698 NTSTATUS Status;
1699 unsigned long IrqFlags;
1700
1701
1702 pUrb = (purbb_t)data;
1703 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
1704 pAd = pHTTXContext->pAd;
1705 pObj = (POS_COOKIE) pAd->OS_Cookie;
1706 Status = pUrb->status;
1707
1708 // Store BulkOut PipeId
1709 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
1710 pAd->BulkOutDataOneSecCount++;
1711
1712 //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
1713 // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
1714
1715 RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
1716 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
1717 pHTTXContext->IRPPending = FALSE;
1718 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
1719
1720 if (Status == USB_ST_NOERROR)
1721 {
1722 pAd->BulkOutComplete++;
1723
1724 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
1725
1726 pAd->Counters8023.GoodTransmits++;
1727 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1728 FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
1729 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1730
1731
1732 }
1733 else // STATUS_OTHER
1734 {
1735 PUCHAR pBuf;
1736
1737 pAd->BulkOutCompleteOther++;
1738
1739 pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition];
1740
1741 if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
1742 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1743 fRTMP_ADAPTER_NIC_NOT_EXIST |
1744 fRTMP_ADAPTER_BULKOUT_RESET)))
1745 {
1746 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1747 pAd->bulkResetPipeid = BulkOutPipeId;
1748 pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
1749 }
1750 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
1751
1752 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
1753 DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
1754 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]));
1755 //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
1756
1757 }
1758
1759 //
1760 // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
1761 // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
1762 //
1763 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1764 if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
1765 (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
1766 !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
1767 {
1768 // Indicate There is data avaliable
1769 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
1770 }
1771 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
1772
1773 // Always call Bulk routine, even reset bulk.
1774 // The protection of rest bulk should be in BulkOut routine
1775 RTUSBKickBulkOut(pAd);
1776}
1777
1778/* End of 2870_rtmp_init.c */
diff --git a/drivers/staging/rt2870/common/action.c b/drivers/staging/rt2870/common/action.c
new file mode 100644
index 00000000000..3a48a7f5e2b
--- /dev/null
+++ b/drivers/staging/rt2870/common/action.c
@@ -0,0 +1,1046 @@
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#ifdef QOS_DLS_SUPPORT
141 if (pAd->MacTab.Content[pInfo->Wcid].ValidAsDls)
142 ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
143 else
144#endif // QOS_DLS_SUPPORT //
145 ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr);
146
147 }
148#endif // CONFIG_STA_SUPPORT //
149
150 Frame.Category = CATEGORY_BA;
151 Frame.Action = ADDBA_REQ;
152 Frame.BaParm.AMSDUSupported = 0;
153 Frame.BaParm.BAPolicy = IMMED_BA;
154 Frame.BaParm.TID = pInfo->TID;
155 Frame.BaParm.BufSize = pInfo->BaBufSize;
156 Frame.Token = pInfo->Token;
157 Frame.TimeOutValue = pInfo->TimeOutValue;
158 Frame.BaStartSeq.field.FragNum = 0;
159 Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
160
161 *(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm));
162 Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
163 Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
164
165 MakeOutgoingFrame(pOutBuffer, &FrameLen,
166 sizeof(FRAME_ADDBA_REQ), &Frame,
167 END_OF_ARGS);
168 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
169 MlmeFreeMemory(pAd, pOutBuffer);
170
171 DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
172 }
173}
174
175/*
176 ==========================================================================
177 Description:
178 send DELBA and delete BaEntry if any
179 Parametrs:
180 Elem - MLME message MLME_DELBA_REQ_STRUCT
181
182 IRQL = DISPATCH_LEVEL
183
184 ==========================================================================
185 */
186VOID MlmeDELBAAction(
187 IN PRTMP_ADAPTER pAd,
188 IN MLME_QUEUE_ELEM *Elem)
189{
190 MLME_DELBA_REQ_STRUCT *pInfo;
191 PUCHAR pOutBuffer = NULL;
192 PUCHAR pOutBuffer2 = NULL;
193 NDIS_STATUS NStatus;
194 ULONG Idx;
195 FRAME_DELBA_REQ Frame;
196 ULONG FrameLen;
197 FRAME_BAR FrameBar;
198
199 pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg;
200 // must send back DELBA
201 NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ));
202 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
203
204 if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen))
205 {
206 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
207 if(NStatus != NDIS_STATUS_SUCCESS)
208 {
209 DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
210 return;
211 }
212
213 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
214 if(NStatus != NDIS_STATUS_SUCCESS)
215 {
216 MlmeFreeMemory(pAd, pOutBuffer);
217 DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
218 return;
219 }
220
221 // SEND BAR (Send BAR to refresh peer reordering buffer.)
222 Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
223
224#ifdef CONFIG_STA_SUPPORT
225 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
226 BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress);
227#endif // CONFIG_STA_SUPPORT //
228
229 FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL funciton.
230 FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; // make sure sequence not clear in DEL funciton.
231 FrameBar.BarControl.TID = pInfo->TID; // make sure sequence not clear in DEL funciton.
232 FrameBar.BarControl.ACKPolicy = IMMED_BA; // make sure sequence not clear in DEL funciton.
233 FrameBar.BarControl.Compressed = 1; // make sure sequence not clear in DEL funciton.
234 FrameBar.BarControl.MTID = 0; // make sure sequence not clear in DEL funciton.
235
236 MakeOutgoingFrame(pOutBuffer2, &FrameLen,
237 sizeof(FRAME_BAR), &FrameBar,
238 END_OF_ARGS);
239 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
240 MlmeFreeMemory(pAd, pOutBuffer2);
241 DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
242
243 // SEND DELBA FRAME
244 FrameLen = 0;
245#ifdef CONFIG_STA_SUPPORT
246 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
247 {
248 if (ADHOC_ON(pAd))
249 ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
250 else
251#ifdef QOS_DLS_SUPPORT
252 if (pAd->MacTab.Content[pInfo->Wcid].ValidAsDls)
253 ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
254 else
255#endif // QOS_DLS_SUPPORT //
256 ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
257 }
258#endif // CONFIG_STA_SUPPORT //
259 Frame.Category = CATEGORY_BA;
260 Frame.Action = DELBA;
261 Frame.DelbaParm.Initiator = pInfo->Initiator;
262 Frame.DelbaParm.TID = pInfo->TID;
263 Frame.ReasonCode = 39; // Time Out
264 *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm));
265 Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
266
267 MakeOutgoingFrame(pOutBuffer, &FrameLen,
268 sizeof(FRAME_DELBA_REQ), &Frame,
269 END_OF_ARGS);
270 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
271 MlmeFreeMemory(pAd, pOutBuffer);
272 DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator));
273 }
274}
275#endif // DOT11_N_SUPPORT //
276
277VOID MlmeQOSAction(
278 IN PRTMP_ADAPTER pAd,
279 IN MLME_QUEUE_ELEM *Elem)
280{
281}
282
283VOID MlmeDLSAction(
284 IN PRTMP_ADAPTER pAd,
285 IN MLME_QUEUE_ELEM *Elem)
286{
287}
288
289VOID MlmeInvalidAction(
290 IN PRTMP_ADAPTER pAd,
291 IN MLME_QUEUE_ELEM *Elem)
292{
293 //PUCHAR pOutBuffer = NULL;
294 //Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11
295}
296
297VOID PeerQOSAction(
298 IN PRTMP_ADAPTER pAd,
299 IN MLME_QUEUE_ELEM *Elem)
300{
301}
302
303#ifdef QOS_DLS_SUPPORT
304VOID PeerDLSAction(
305 IN PRTMP_ADAPTER pAd,
306 IN MLME_QUEUE_ELEM *Elem)
307{
308 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
309
310 switch(Action)
311 {
312 case ACTION_DLS_REQUEST:
313#ifdef CONFIG_STA_SUPPORT
314 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
315 PeerDlsReqAction(pAd, Elem);
316#endif // CONFIG_STA_SUPPORT //
317 break;
318
319 case ACTION_DLS_RESPONSE:
320#ifdef CONFIG_STA_SUPPORT
321 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
322 PeerDlsRspAction(pAd, Elem);
323#endif // CONFIG_STA_SUPPORT //
324 break;
325
326 case ACTION_DLS_TEARDOWN:
327#ifdef CONFIG_STA_SUPPORT
328 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
329 PeerDlsTearDownAction(pAd, Elem);
330#endif // CONFIG_STA_SUPPORT //
331 break;
332 }
333}
334#endif // QOS_DLS_SUPPORT //
335
336#ifdef DOT11_N_SUPPORT
337VOID PeerBAAction(
338 IN PRTMP_ADAPTER pAd,
339 IN MLME_QUEUE_ELEM *Elem)
340{
341 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
342
343 switch(Action)
344 {
345 case ADDBA_REQ:
346 PeerAddBAReqAction(pAd,Elem);
347 break;
348 case ADDBA_RESP:
349 PeerAddBARspAction(pAd,Elem);
350 break;
351 case DELBA:
352 PeerDelBAAction(pAd,Elem);
353 break;
354 }
355}
356
357
358#ifdef DOT11N_DRAFT3
359
360#ifdef CONFIG_STA_SUPPORT
361VOID StaPublicAction(
362 IN PRTMP_ADAPTER pAd,
363 IN UCHAR Bss2040Coexist)
364{
365 BSS_2040_COEXIST_IE BssCoexist;
366 MLME_SCAN_REQ_STRUCT ScanReq;
367
368 BssCoexist.word = Bss2040Coexist;
369 // 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
370 if ((BssCoexist.field.InfoReq == 1) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040)))
371 {
372 // Clear record first. After scan , will update those bit and send back to transmiter.
373 pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1;
374 pAd->CommonCfg.BSSCoexist2040.field.Intolerant40 = 0;
375 pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 0;
376 // Fill out stuff for scan request
377 ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST);
378 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
379 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
380 }
381}
382
383
384/*
385Description : Build Intolerant Channel Rerpot from Trigger event table.
386return : how many bytes copied.
387*/
388ULONG BuildIntolerantChannelRep(
389 IN PRTMP_ADAPTER pAd,
390 IN PUCHAR pDest)
391{
392 ULONG FrameLen = 0;
393 ULONG ReadOffset = 0;
394 UCHAR i;
395 UCHAR LastRegClass = 0xff;
396 PUCHAR pLen;
397
398 for ( i = 0;i < MAX_TRIGGER_EVENT;i++)
399 {
400 if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE)
401 {
402 if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == LastRegClass)
403 {
404 *(pDest + ReadOffset) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
405 *pLen++;
406 ReadOffset++;
407 FrameLen++;
408 }
409 else
410 {
411 *(pDest + ReadOffset) = IE_2040_BSS_INTOLERANT_REPORT; // IE
412 *(pDest + ReadOffset + 1) = 2; // Len = RegClass byte + channel byte.
413 pLen = pDest + ReadOffset + 1;
414 LastRegClass = pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass;
415 *(pDest + ReadOffset + 2) = LastRegClass; // Len = RegClass byte + channel byte.
416 *(pDest + ReadOffset + 3) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
417 FrameLen += 4;
418 ReadOffset += 4;
419 }
420
421 }
422 }
423 return FrameLen;
424}
425
426
427/*
428Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
429*/
430VOID Send2040CoexistAction(
431 IN PRTMP_ADAPTER pAd,
432 IN UCHAR Wcid,
433 IN BOOLEAN bAddIntolerantCha)
434{
435 PUCHAR pOutBuffer = NULL;
436 NDIS_STATUS NStatus;
437 FRAME_ACTION_HDR Frame;
438 ULONG FrameLen;
439 ULONG IntolerantChaRepLen;
440
441 IntolerantChaRepLen = 0;
442 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
443 if(NStatus != NDIS_STATUS_SUCCESS)
444 {
445 DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n"));
446 return;
447 }
448 ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->CommonCfg.Bssid);
449 Frame.Category = CATEGORY_PUBLIC;
450 Frame.Action = ACTION_BSS_2040_COEXIST;
451
452 MakeOutgoingFrame(pOutBuffer, &FrameLen,
453 sizeof(FRAME_ACTION_HDR), &Frame,
454 END_OF_ARGS);
455
456 *(pOutBuffer + FrameLen) = pAd->CommonCfg.BSSCoexist2040.word;
457 FrameLen++;
458
459 if (bAddIntolerantCha == TRUE)
460 IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen);
461
462 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen);
463 DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x ) \n", pAd->CommonCfg.BSSCoexist2040.word));
464
465}
466
467
468/*
469 ==========================================================================
470 Description:
471 After scan, Update 20/40 BSS Coexistence IE and send out.
472 According to 802.11n D3.03 11.14.10
473
474 Parameters:
475 ==========================================================================
476 */
477VOID Update2040CoexistFrameAndNotify(
478 IN PRTMP_ADAPTER pAd,
479 IN UCHAR Wcid,
480 IN BOOLEAN bAddIntolerantCha)
481{
482 BSS_2040_COEXIST_IE OldValue;
483
484 OldValue.word = pAd->CommonCfg.BSSCoexist2040.word;
485 if ((pAd->CommonCfg.TriggerEventTab.EventANo > 0) || (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0))
486 pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 1;
487
488 // Need to check !!!!
489 // How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first.!!!!!
490 // So Only check BSS20WidthReq change.
491 if (OldValue.field.BSS20WidthReq != pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq)
492 {
493 Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha);
494 }
495}
496#endif // CONFIG_STA_SUPPORT //
497
498
499BOOLEAN ChannelSwitchSanityCheck(
500 IN PRTMP_ADAPTER pAd,
501 IN UCHAR Wcid,
502 IN UCHAR NewChannel,
503 IN UCHAR Secondary)
504{
505 UCHAR i;
506
507 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
508 return FALSE;
509
510 if ((NewChannel > 7) && (Secondary == 1))
511 return FALSE;
512
513 if ((NewChannel < 5) && (Secondary == 3))
514 return FALSE;
515
516 // 0. Check if new channel is in the channellist.
517 for (i = 0;i < pAd->ChannelListNum;i++)
518 {
519 if (pAd->ChannelList[i].Channel == NewChannel)
520 {
521 break;
522 }
523 }
524
525 if (i == pAd->ChannelListNum)
526 return FALSE;
527
528 return TRUE;
529}
530
531
532VOID ChannelSwitchAction(
533 IN PRTMP_ADAPTER pAd,
534 IN UCHAR Wcid,
535 IN UCHAR NewChannel,
536 IN UCHAR Secondary)
537{
538 UCHAR BBPValue = 0;
539 ULONG MACValue;
540
541 DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d) \n", NewChannel, Secondary));
542
543 if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE)
544 return;
545
546 // 1. Switches to BW = 20.
547 if (Secondary == 0)
548 {
549 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
550 BBPValue&= (~0x18);
551 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
552 if (pAd->MACVersion == 0x28600100)
553 {
554 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
555 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
556 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
557 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
558 }
559 pAd->CommonCfg.BBPCurrentBW = BW_20;
560 pAd->CommonCfg.Channel = NewChannel;
561 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
562 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel,FALSE);
563 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
564 pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 0;
565 DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz !!! \n" ));
566 }
567 // 1. Switches to BW = 40 And Station supports BW = 40.
568 else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
569 {
570 pAd->CommonCfg.Channel = NewChannel;
571
572 if (Secondary == 1)
573 {
574 // Secondary above.
575 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
576 RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
577 MACValue &= 0xfe;
578 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
579 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
580 BBPValue&= (~0x18);
581 BBPValue|= (0x10);
582 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
583 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
584 BBPValue&= (~0x20);
585 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
586 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
587 }
588 else
589 {
590 // Secondary below.
591 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
592 RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
593 MACValue &= 0xfe;
594 MACValue |= 0x1;
595 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
596 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
597 BBPValue&= (~0x18);
598 BBPValue|= (0x10);
599 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
600 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
601 BBPValue&= (~0x20);
602 BBPValue|= (0x20);
603 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
604 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
605 }
606 pAd->CommonCfg.BBPCurrentBW = BW_40;
607 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
608 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
609 pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 1;
610 }
611}
612#endif // DOT11N_DRAFT3 //
613#endif // DOT11_N_SUPPORT //
614
615VOID PeerPublicAction(
616 IN PRTMP_ADAPTER pAd,
617 IN MLME_QUEUE_ELEM *Elem)
618{
619#ifdef DOT11N_DRAFT3
620 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
621#endif // DOT11N_DRAFT3 //
622
623 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
624 return;
625
626#ifdef DOT11N_DRAFT3
627 switch(Action)
628 {
629 case ACTION_BSS_2040_COEXIST: // Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
630 {
631 //UCHAR BssCoexist;
632 BSS_2040_COEXIST_ELEMENT *pCoexistInfo;
633 BSS_2040_COEXIST_IE *pBssCoexistIe;
634 BSS_2040_INTOLERANT_CH_REPORT *pIntolerantReport = NULL;
635
636 if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) )
637 {
638 DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen));
639 break;
640 }
641 DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
642 hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen);
643
644
645 pCoexistInfo = (BSS_2040_COEXIST_ELEMENT *) &Elem->Msg[LENGTH_802_11+2];
646 //hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));
647 if (Elem->MsgLen >= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT) + sizeof(BSS_2040_INTOLERANT_CH_REPORT)))
648 {
649 pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT));
650 }
651 //hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
652
653 pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe);
654
655#ifdef CONFIG_STA_SUPPORT
656 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
657 {
658 if (INFRA_ON(pAd))
659 {
660 StaPublicAction(pAd, pCoexistInfo);
661 }
662 }
663#endif // CONFIG_STA_SUPPORT //
664
665 }
666 break;
667 }
668
669#endif // DOT11N_DRAFT3 //
670
671}
672
673
674static VOID ReservedAction(
675 IN PRTMP_ADAPTER pAd,
676 IN MLME_QUEUE_ELEM *Elem)
677{
678 UCHAR Category;
679
680 if (Elem->MsgLen <= LENGTH_802_11)
681 {
682 return;
683 }
684
685 Category = Elem->Msg[LENGTH_802_11];
686 DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category));
687 hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
688}
689
690VOID PeerRMAction(
691 IN PRTMP_ADAPTER pAd,
692 IN MLME_QUEUE_ELEM *Elem)
693
694{
695 return;
696}
697
698#ifdef DOT11_N_SUPPORT
699static VOID respond_ht_information_exchange_action(
700 IN PRTMP_ADAPTER pAd,
701 IN MLME_QUEUE_ELEM *Elem)
702{
703 PUCHAR pOutBuffer = NULL;
704 NDIS_STATUS NStatus;
705 ULONG FrameLen;
706 FRAME_HT_INFO HTINFOframe, *pFrame;
707 UCHAR *pAddr;
708
709
710 // 2. Always send back ADDBA Response
711 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
712
713 if (NStatus != NDIS_STATUS_SUCCESS)
714 {
715 DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
716 return;
717 }
718
719 // get RA
720 pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
721 pAddr = pFrame->Hdr.Addr2;
722
723 NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO));
724 // 2-1. Prepare ADDBA Response frame.
725#ifdef CONFIG_STA_SUPPORT
726 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
727 {
728 if (ADHOC_ON(pAd))
729 ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
730 else
731 ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
732 }
733#endif // CONFIG_STA_SUPPORT //
734
735 HTINFOframe.Category = CATEGORY_HT;
736 HTINFOframe.Action = HT_INFO_EXCHANGE;
737 HTINFOframe.HT_Info.Request = 0;
738 HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
739 HTINFOframe.HT_Info.STA_Channel_Width = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
740
741 MakeOutgoingFrame(pOutBuffer, &FrameLen,
742 sizeof(FRAME_HT_INFO), &HTINFOframe,
743 END_OF_ARGS);
744
745 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
746 MlmeFreeMemory(pAd, pOutBuffer);
747}
748
749
750#ifdef DOT11N_DRAFT3
751VOID SendNotifyBWActionFrame(
752 IN PRTMP_ADAPTER pAd,
753 IN UCHAR Wcid,
754 IN UCHAR apidx)
755{
756 PUCHAR pOutBuffer = NULL;
757 NDIS_STATUS NStatus;
758 FRAME_ACTION_HDR Frame;
759 ULONG FrameLen;
760 PUCHAR pAddr1;
761
762
763 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
764 if(NStatus != NDIS_STATUS_SUCCESS)
765 {
766 DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n"));
767 return;
768 }
769
770 if (Wcid == MCAST_WCID)
771 pAddr1 = &BROADCAST_ADDR[0];
772 else
773 pAddr1 = pAd->MacTab.Content[Wcid].Addr;
774 ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
775
776 Frame.Category = CATEGORY_HT;
777 Frame.Action = NOTIFY_BW_ACTION;
778
779 MakeOutgoingFrame(pOutBuffer, &FrameLen,
780 sizeof(FRAME_ACTION_HDR), &Frame,
781 END_OF_ARGS);
782
783 *(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
784 FrameLen++;
785
786
787 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
788 DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth));
789
790}
791#endif // DOT11N_DRAFT3 //
792
793
794VOID PeerHTAction(
795 IN PRTMP_ADAPTER pAd,
796 IN MLME_QUEUE_ELEM *Elem)
797{
798 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
799
800 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
801 return;
802
803 switch(Action)
804 {
805 case NOTIFY_BW_ACTION:
806 DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
807#ifdef CONFIG_STA_SUPPORT
808 if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
809 {
810 // Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
811 // sending BW_Notify Action frame, and cause us to linkup and linkdown.
812 // In legacy mode, don't need to parse HT action frame.
813 DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
814 Elem->Msg[LENGTH_802_11+2] ));
815 break;
816 }
817#endif // CONFIG_STA_SUPPORT //
818
819 if (Elem->Msg[LENGTH_802_11+2] == 0) // 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
820 pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
821
822 break;
823
824 case SMPS_ACTION:
825 // 7.3.1.25
826 DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
827 if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
828 {
829 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
830 }
831 else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
832 {
833 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
834 }
835 else
836 {
837 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
838 }
839
840 DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode));
841 // rt2860c : add something for smps change.
842 break;
843
844 case SETPCO_ACTION:
845 break;
846
847 case MIMO_CHA_MEASURE_ACTION:
848 break;
849
850 case HT_INFO_EXCHANGE:
851 {
852 HT_INFORMATION_OCTET *pHT_info;
853
854 pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
855 // 7.4.8.10
856 DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
857 if (pHT_info->Request)
858 {
859 respond_ht_information_exchange_action(pAd, Elem);
860 }
861 }
862 break;
863 }
864}
865
866
867/*
868 ==========================================================================
869 Description:
870 Retry sending ADDBA Reqest.
871
872 IRQL = DISPATCH_LEVEL
873
874 Parametrs:
875 p8023Header: if this is already 802.3 format, p8023Header is NULL
876
877 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
878 FALSE , then continue indicaterx at this moment.
879 ==========================================================================
880 */
881VOID ORIBATimerTimeout(
882 IN PRTMP_ADAPTER pAd)
883{
884 MAC_TABLE_ENTRY *pEntry;
885 INT i, total;
886// FRAME_BAR FrameBar;
887// ULONG FrameLen;
888// NDIS_STATUS NStatus;
889// PUCHAR pOutBuffer = NULL;
890// USHORT Sequence;
891 UCHAR TID;
892
893#ifdef RALINK_ATE
894 if (ATE_ON(pAd))
895 return;
896#endif // RALINK_ATE //
897
898 total = pAd->MacTab.Size * NUM_OF_TID;
899
900 for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
901 {
902 if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
903 {
904 pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
905 TID = pAd->BATable.BAOriEntry[i].TID;
906
907 ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
908 }
909 total --;
910 }
911}
912
913
914VOID SendRefreshBAR(
915 IN PRTMP_ADAPTER pAd,
916 IN MAC_TABLE_ENTRY *pEntry)
917{
918 FRAME_BAR FrameBar;
919 ULONG FrameLen;
920 NDIS_STATUS NStatus;
921 PUCHAR pOutBuffer = NULL;
922 USHORT Sequence;
923 UCHAR i, TID;
924 USHORT idx;
925 BA_ORI_ENTRY *pBAEntry;
926
927 for (i = 0; i <NUM_OF_TID; i++)
928 {
929 idx = pEntry->BAOriWcidArray[i];
930 if (idx == 0)
931 {
932 continue;
933 }
934 pBAEntry = &pAd->BATable.BAOriEntry[idx];
935
936 if (pBAEntry->ORI_BA_Status == Originator_Done)
937 {
938 TID = pBAEntry->TID;
939
940 ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
941
942 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
943 if(NStatus != NDIS_STATUS_SUCCESS)
944 {
945 DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
946 return;
947 }
948
949 Sequence = pEntry->TxSeq[TID];
950
951
952#ifdef CONFIG_STA_SUPPORT
953 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
954 BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress);
955#endif // CONFIG_STA_SUPPORT //
956
957 FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
958 FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton.
959 FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton.
960
961 MakeOutgoingFrame(pOutBuffer, &FrameLen,
962 sizeof(FRAME_BAR), &FrameBar,
963 END_OF_ARGS);
964 //if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
965 if (1) // Now we always send BAR.
966 {
967 //MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
968 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
969 }
970 MlmeFreeMemory(pAd, pOutBuffer);
971 }
972 }
973}
974#endif // DOT11_N_SUPPORT //
975
976VOID ActHeaderInit(
977 IN PRTMP_ADAPTER pAd,
978 IN OUT PHEADER_802_11 pHdr80211,
979 IN PUCHAR Addr1,
980 IN PUCHAR Addr2,
981 IN PUCHAR Addr3)
982{
983 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
984 pHdr80211->FC.Type = BTYPE_MGMT;
985 pHdr80211->FC.SubType = SUBTYPE_ACTION;
986
987 COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
988 COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
989 COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
990}
991
992VOID BarHeaderInit(
993 IN PRTMP_ADAPTER pAd,
994 IN OUT PFRAME_BAR pCntlBar,
995 IN PUCHAR pDA,
996 IN PUCHAR pSA)
997{
998// USHORT Duration;
999
1000 NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
1001 pCntlBar->FC.Type = BTYPE_CNTL;
1002 pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
1003 pCntlBar->BarControl.MTID = 0;
1004 pCntlBar->BarControl.Compressed = 1;
1005 pCntlBar->BarControl.ACKPolicy = 0;
1006
1007
1008 pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
1009
1010 COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
1011 COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
1012}
1013
1014
1015/*
1016 ==========================================================================
1017 Description:
1018 Insert Category and action code into the action frame.
1019
1020 Parametrs:
1021 1. frame buffer pointer.
1022 2. frame length.
1023 3. category code of the frame.
1024 4. action code of the frame.
1025
1026 Return : None.
1027 ==========================================================================
1028 */
1029VOID InsertActField(
1030 IN PRTMP_ADAPTER pAd,
1031 OUT PUCHAR pFrameBuf,
1032 OUT PULONG pFrameLen,
1033 IN UINT8 Category,
1034 IN UINT8 ActCode)
1035{
1036 ULONG TempLen;
1037
1038 MakeOutgoingFrame( pFrameBuf, &TempLen,
1039 1, &Category,
1040 1, &ActCode,
1041 END_OF_ARGS);
1042
1043 *pFrameLen = *pFrameLen + TempLen;
1044
1045 return;
1046}
diff --git a/drivers/staging/rt2870/common/action.h b/drivers/staging/rt2870/common/action.h
new file mode 100644
index 00000000000..ce3877dce81
--- /dev/null
+++ b/drivers/staging/rt2870/common/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/rt2870/common/ba_action.c b/drivers/staging/rt2870/common/ba_action.c
new file mode 100644
index 00000000000..95addb20bce
--- /dev/null
+++ b/drivers/staging/rt2870/common/ba_action.c
@@ -0,0 +1,1798 @@
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 //
454 // force LastIndSeq to shift to LastIndSeq+1
455 //
456 Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ;
457 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
458 pBAEntry->LastIndSeqAtTimer = Now32;
459 pBAEntry->LastIndSeq = Sequence;
460 //
461 // indicate in-order mpdus
462 //
463 Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence);
464 if (Sequence != RESET_RCV_SEQ)
465 {
466 pBAEntry->LastIndSeq = Sequence;
467 }
468
469 }
470#if 0
471 else if (
472 (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT))) &&
473 (pBAEntry->list.qlen > 1))
474 )
475 {
476 DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%lx-%lx = %d > %d): %x\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
477 (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
478 pBAEntry->LastIndSeq));
479 ba_refresh_reordering_mpdus(pAd, pBAEntry);
480 pBAEntry->LastIndSeqAtTimer = Now32;
481 }
482#endif
483}
484
485
486/*
487 * generate ADDBA request to
488 * set up BA agreement
489 */
490VOID BAOriSessionSetUp(
491 IN PRTMP_ADAPTER pAd,
492 IN MAC_TABLE_ENTRY *pEntry,
493 IN UCHAR TID,
494 IN USHORT TimeOut,
495 IN ULONG DelayTime,
496 IN BOOLEAN isForced)
497
498{
499 //MLME_ADDBA_REQ_STRUCT AddbaReq;
500 BA_ORI_ENTRY *pBAEntry = NULL;
501 USHORT Idx;
502 BOOLEAN Cancelled;
503
504 if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE) && (isForced == FALSE))
505 return;
506
507 // if this entry is limited to use legacy tx mode, it doesn't generate BA.
508 if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT)
509 return;
510
511 if ((pEntry->BADeclineBitmap & (1<<TID)) && (isForced == FALSE))
512 {
513 // try again after 3 secs
514 DelayTime = 3000;
515// printk("DeCline BA from Peer\n");
516// return;
517 }
518
519
520 Idx = pEntry->BAOriWcidArray[TID];
521 if (Idx == 0)
522 {
523 // allocate a BA session
524 pBAEntry = BATableAllocOriEntry(pAd, &Idx);
525 if (pBAEntry == NULL)
526 {
527 DBGPRINT(RT_DEBUG_TRACE,("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
528 return;
529 }
530 }
531 else
532 {
533 pBAEntry =&pAd->BATable.BAOriEntry[Idx];
534 }
535
536 if (pBAEntry->ORI_BA_Status >= Originator_WaitRes)
537 {
538 return;
539 }
540
541 pEntry->BAOriWcidArray[TID] = Idx;
542
543 // Initialize BA session
544 pBAEntry->ORI_BA_Status = Originator_WaitRes;
545 pBAEntry->Wcid = pEntry->Aid;
546 pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
547 pBAEntry->Sequence = BA_ORI_INIT_SEQ;
548 pBAEntry->Token = 1; // (2008-01-21) Jan Lee recommends it - this token can't be 0
549 pBAEntry->TID = TID;
550 pBAEntry->TimeOutValue = TimeOut;
551 pBAEntry->pAdapter = pAd;
552
553 if (!(pEntry->TXBAbitmap & (1<<TID)))
554 {
555 RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
556 }
557 else
558 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
559
560 // set timer to send ADDBA request
561 RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime);
562}
563
564VOID BAOriSessionAdd(
565 IN PRTMP_ADAPTER pAd,
566 IN MAC_TABLE_ENTRY *pEntry,
567 IN PFRAME_ADDBA_RSP pFrame)
568{
569 BA_ORI_ENTRY *pBAEntry = NULL;
570 BOOLEAN Cancelled;
571 UCHAR TID;
572 USHORT Idx;
573 PUCHAR pOutBuffer2 = NULL;
574 NDIS_STATUS NStatus;
575 ULONG FrameLen;
576 FRAME_BAR FrameBar;
577
578 TID = pFrame->BaParm.TID;
579 Idx = pEntry->BAOriWcidArray[TID];
580 pBAEntry =&pAd->BATable.BAOriEntry[Idx];
581
582 // Start fill in parameters.
583 if ((Idx !=0) && (pBAEntry->TID == TID) && (pBAEntry->ORI_BA_Status == Originator_WaitRes))
584 {
585 pBAEntry->BAWinSize = min(pBAEntry->BAWinSize, ((UCHAR)pFrame->BaParm.BufSize));
586 BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize);
587
588 pBAEntry->TimeOutValue = pFrame->TimeOutValue;
589 pBAEntry->ORI_BA_Status = Originator_Done;
590 // reset sequence number
591 pBAEntry->Sequence = BA_ORI_INIT_SEQ;
592 // Set Bitmap flag.
593 pEntry->TXBAbitmap |= (1<<TID);
594 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
595
596 pBAEntry->ORIBATimer.TimerValue = 0; //pFrame->TimeOutValue;
597
598 DBGPRINT(RT_DEBUG_TRACE,("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n", __FUNCTION__, pEntry->TXBAbitmap,
599 pBAEntry->BAWinSize, pBAEntry->ORIBATimer.TimerValue));
600
601 // SEND BAR ;
602 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
603 if (NStatus != NDIS_STATUS_SUCCESS)
604 {
605 DBGPRINT(RT_DEBUG_TRACE,("BA - BAOriSessionAdd() allocate memory failed \n"));
606 return;
607 }
608
609
610#ifdef CONFIG_STA_SUPPORT
611 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
612 BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->CurrentAddress);
613#endif // CONFIG_STA_SUPPORT //
614
615 FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
616 FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; // make sure sequence not clear in DEL funciton.
617 FrameBar.BarControl.TID = pBAEntry->TID; // make sure sequence not clear in DEL funciton.
618 MakeOutgoingFrame(pOutBuffer2, &FrameLen,
619 sizeof(FRAME_BAR), &FrameBar,
620 END_OF_ARGS);
621 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
622 MlmeFreeMemory(pAd, pOutBuffer2);
623
624
625 if (pBAEntry->ORIBATimer.TimerValue)
626 RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); // in mSec
627 }
628}
629
630BOOLEAN BARecSessionAdd(
631 IN PRTMP_ADAPTER pAd,
632 IN MAC_TABLE_ENTRY *pEntry,
633 IN PFRAME_ADDBA_REQ pFrame)
634{
635 BA_REC_ENTRY *pBAEntry = NULL;
636 BOOLEAN Status = TRUE;
637 BOOLEAN Cancelled;
638 USHORT Idx;
639 UCHAR TID;
640 UCHAR BAWinSize;
641 //UINT32 Value;
642 //UINT offset;
643
644
645 ASSERT(pEntry);
646
647 // find TID
648 TID = pFrame->BaParm.TID;
649
650 BAWinSize = min(((UCHAR)pFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
651
652 // Intel patch
653 if (BAWinSize == 0)
654 {
655 BAWinSize = 64;
656 }
657
658 Idx = pEntry->BARecWcidArray[TID];
659
660
661 if (Idx == 0)
662 {
663 pBAEntry = BATableAllocRecEntry(pAd, &Idx);
664 }
665 else
666 {
667 pBAEntry = &pAd->BATable.BARecEntry[Idx];
668 // flush all pending reordering mpdus
669 ba_refresh_reordering_mpdus(pAd, pBAEntry);
670 }
671
672 DBGPRINT(RT_DEBUG_TRACE,("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __FUNCTION__, pAd->BATable.numAsRecipient, Idx,
673 pFrame->BaParm.BufSize, BAWinSize));
674
675 // Start fill in parameters.
676 if (pBAEntry != NULL)
677 {
678 ASSERT(pBAEntry->list.qlen == 0);
679
680 pBAEntry->REC_BA_Status = Recipient_HandleRes;
681 pBAEntry->BAWinSize = BAWinSize;
682 pBAEntry->Wcid = pEntry->Aid;
683 pBAEntry->TID = TID;
684 pBAEntry->TimeOutValue = pFrame->TimeOutValue;
685 pBAEntry->REC_BA_Status = Recipient_Accept;
686 // initial sequence number
687 pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq;
688
689 printk("Start Seq = %08x\n", pFrame->BaStartSeq.field.StartSeq);
690
691 if (pEntry->RXBAbitmap & (1<<TID))
692 {
693 RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
694 }
695 else
696 {
697 RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE);
698 }
699
700#if 0 // for debugging
701 RTMPSetTimer(&pBAEntry->RECBATimer, REC_BA_SESSION_IDLE_TIMEOUT);
702#endif
703
704 // Set Bitmap flag.
705 pEntry->RXBAbitmap |= (1<<TID);
706 pEntry->BARecWcidArray[TID] = Idx;
707
708 pEntry->BADeclineBitmap &= ~(1<<TID);
709
710 // Set BA session mask in WCID table.
711 RT28XX_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
712
713 DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
714 pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID]));
715 }
716 else
717 {
718 Status = FALSE;
719 DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n",
720 PRINT_MAC(pEntry->Addr), TID));
721 }
722 return(Status);
723}
724
725
726BA_REC_ENTRY *BATableAllocRecEntry(
727 IN PRTMP_ADAPTER pAd,
728 OUT USHORT *Idx)
729{
730 int i;
731 BA_REC_ENTRY *pBAEntry = NULL;
732
733
734 NdisAcquireSpinLock(&pAd->BATabLock);
735
736 if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION)
737 {
738 printk("BA Recipeint Session (%ld) > %d\n", pAd->BATable.numAsRecipient,
739 MAX_BARECI_SESSION);
740 goto done;
741 }
742
743 // reserve idx 0 to identify BAWcidArray[TID] as empty
744 for (i=1; i < MAX_LEN_OF_BA_REC_TABLE; i++)
745 {
746 pBAEntry =&pAd->BATable.BARecEntry[i];
747 if ((pBAEntry->REC_BA_Status == Recipient_NONE))
748 {
749 // get one
750 pAd->BATable.numAsRecipient++;
751 pBAEntry->REC_BA_Status = Recipient_USED;
752 *Idx = i;
753 break;
754 }
755 }
756
757done:
758 NdisReleaseSpinLock(&pAd->BATabLock);
759 return pBAEntry;
760}
761
762BA_ORI_ENTRY *BATableAllocOriEntry(
763 IN PRTMP_ADAPTER pAd,
764 OUT USHORT *Idx)
765{
766 int i;
767 BA_ORI_ENTRY *pBAEntry = NULL;
768
769 NdisAcquireSpinLock(&pAd->BATabLock);
770
771 if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE))
772 {
773 goto done;
774 }
775
776 // reserve idx 0 to identify BAWcidArray[TID] as empty
777 for (i=1; i<MAX_LEN_OF_BA_ORI_TABLE; i++)
778 {
779 pBAEntry =&pAd->BATable.BAOriEntry[i];
780 if ((pBAEntry->ORI_BA_Status == Originator_NONE))
781 {
782 // get one
783 pAd->BATable.numAsOriginator++;
784 pBAEntry->ORI_BA_Status = Originator_USED;
785 pBAEntry->pAdapter = pAd;
786 *Idx = i;
787 break;
788 }
789 }
790
791done:
792 NdisReleaseSpinLock(&pAd->BATabLock);
793 return pBAEntry;
794}
795
796
797VOID BATableFreeOriEntry(
798 IN PRTMP_ADAPTER pAd,
799 IN ULONG Idx)
800{
801 BA_ORI_ENTRY *pBAEntry = NULL;
802 MAC_TABLE_ENTRY *pEntry;
803
804
805 if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
806 return;
807
808 pBAEntry =&pAd->BATable.BAOriEntry[Idx];
809
810 if (pBAEntry->ORI_BA_Status != Originator_NONE)
811 {
812 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
813 pEntry->BAOriWcidArray[pBAEntry->TID] = 0;
814
815
816 NdisAcquireSpinLock(&pAd->BATabLock);
817 if (pBAEntry->ORI_BA_Status == Originator_Done)
818 {
819 pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) ));
820 DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
821 // Erase Bitmap flag.
822 }
823
824 ASSERT(pAd->BATable.numAsOriginator != 0);
825
826 pAd->BATable.numAsOriginator -= 1;
827
828 pBAEntry->ORI_BA_Status = Originator_NONE;
829 pBAEntry->Token = 0;
830 NdisReleaseSpinLock(&pAd->BATabLock);
831 }
832}
833
834
835VOID BATableFreeRecEntry(
836 IN PRTMP_ADAPTER pAd,
837 IN ULONG Idx)
838{
839 BA_REC_ENTRY *pBAEntry = NULL;
840 MAC_TABLE_ENTRY *pEntry;
841
842
843 if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE))
844 return;
845
846 pBAEntry =&pAd->BATable.BARecEntry[Idx];
847
848 if (pBAEntry->REC_BA_Status != Recipient_NONE)
849 {
850 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
851 pEntry->BARecWcidArray[pBAEntry->TID] = 0;
852
853 NdisAcquireSpinLock(&pAd->BATabLock);
854
855 ASSERT(pAd->BATable.numAsRecipient != 0);
856
857 pAd->BATable.numAsRecipient -= 1;
858
859 pBAEntry->REC_BA_Status = Recipient_NONE;
860 NdisReleaseSpinLock(&pAd->BATabLock);
861 }
862}
863
864
865VOID BAOriSessionTearDown(
866 IN OUT PRTMP_ADAPTER pAd,
867 IN UCHAR Wcid,
868 IN UCHAR TID,
869 IN BOOLEAN bPassive,
870 IN BOOLEAN bForceSend)
871{
872 ULONG Idx = 0;
873 BA_ORI_ENTRY *pBAEntry;
874 BOOLEAN Cancelled;
875
876 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
877 {
878 return;
879 }
880
881 //
882 // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
883 //
884 Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID];
885 if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
886 {
887 if (bForceSend == TRUE)
888 {
889 // force send specified TID DelBA
890 MLME_DELBA_REQ_STRUCT DelbaReq;
891 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
892
893 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
894 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
895
896 COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
897 DelbaReq.Wcid = Wcid;
898 DelbaReq.TID = TID;
899 DelbaReq.Initiator = ORIGINATOR;
900#if 1
901 Elem->MsgLen = sizeof(DelbaReq);
902 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
903 MlmeDELBAAction(pAd, Elem);
904 kfree(Elem);
905#else
906 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
907 RT28XX_MLME_HANDLER(pAd);
908#endif
909 }
910
911 return;
912 }
913
914 DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
915
916 pBAEntry = &pAd->BATable.BAOriEntry[Idx];
917 DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status));
918 //
919 // Prepare DelBA action frame and send to the peer.
920 //
921 if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done))
922 {
923 MLME_DELBA_REQ_STRUCT DelbaReq;
924 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
925
926 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
927 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
928
929 COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
930 DelbaReq.Wcid = Wcid;
931 DelbaReq.TID = pBAEntry->TID;
932 DelbaReq.Initiator = ORIGINATOR;
933#if 1
934 Elem->MsgLen = sizeof(DelbaReq);
935 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
936 MlmeDELBAAction(pAd, Elem);
937 kfree(Elem);
938#else
939 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
940 RT28XX_MLME_HANDLER(pAd);
941#endif
942 }
943 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
944 BATableFreeOriEntry(pAd, Idx);
945
946 if (bPassive)
947 {
948 //BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE);
949 }
950}
951
952VOID BARecSessionTearDown(
953 IN OUT PRTMP_ADAPTER pAd,
954 IN UCHAR Wcid,
955 IN UCHAR TID,
956 IN BOOLEAN bPassive)
957{
958 ULONG Idx = 0;
959 BA_REC_ENTRY *pBAEntry;
960
961 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
962 {
963 return;
964 }
965
966 //
967 // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
968 //
969 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
970 if (Idx == 0)
971 return;
972
973 DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
974
975
976 pBAEntry = &pAd->BATable.BARecEntry[Idx];
977 DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status));
978 //
979 // Prepare DelBA action frame and send to the peer.
980 //
981 if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept))
982 {
983 MLME_DELBA_REQ_STRUCT DelbaReq;
984 BOOLEAN Cancelled;
985 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
986 //ULONG offset;
987 //UINT32 VALUE;
988
989 RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
990
991 //
992 // 1. Send DELBA Action Frame
993 //
994 if (bPassive == FALSE)
995 {
996 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
997 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
998
999 COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
1000 DelbaReq.Wcid = Wcid;
1001 DelbaReq.TID = TID;
1002 DelbaReq.Initiator = RECIPIENT;
1003#if 1
1004 Elem->MsgLen = sizeof(DelbaReq);
1005 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
1006 MlmeDELBAAction(pAd, Elem);
1007 kfree(Elem);
1008#else
1009 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
1010 RT28XX_MLME_HANDLER(pAd);
1011#endif
1012 }
1013
1014
1015 //
1016 // 2. Free resource of BA session
1017 //
1018 // flush all pending reordering mpdus
1019 ba_refresh_reordering_mpdus(pAd, pBAEntry);
1020
1021 NdisAcquireSpinLock(&pAd->BATabLock);
1022
1023 // Erase Bitmap flag.
1024 pBAEntry->LastIndSeq = RESET_RCV_SEQ;
1025 pBAEntry->BAWinSize = 0;
1026 // Erase Bitmap flag at software mactable
1027 pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID)));
1028 pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
1029
1030 RT28XX_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
1031
1032 NdisReleaseSpinLock(&pAd->BATabLock);
1033
1034 }
1035
1036 BATableFreeRecEntry(pAd, Idx);
1037}
1038
1039VOID BASessionTearDownALL(
1040 IN OUT PRTMP_ADAPTER pAd,
1041 IN UCHAR Wcid)
1042{
1043 int i;
1044
1045 for (i=0; i<NUM_OF_TID; i++)
1046 {
1047 BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE);
1048 BARecSessionTearDown(pAd, Wcid, i, FALSE);
1049 }
1050}
1051
1052
1053/*
1054 ==========================================================================
1055 Description:
1056 Retry sending ADDBA Reqest.
1057
1058 IRQL = DISPATCH_LEVEL
1059
1060 Parametrs:
1061 p8023Header: if this is already 802.3 format, p8023Header is NULL
1062
1063 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
1064 FALSE , then continue indicaterx at this moment.
1065 ==========================================================================
1066 */
1067VOID BAOriSessionSetupTimeout(
1068 IN PVOID SystemSpecific1,
1069 IN PVOID FunctionContext,
1070 IN PVOID SystemSpecific2,
1071 IN PVOID SystemSpecific3)
1072{
1073 BA_ORI_ENTRY *pBAEntry = (BA_ORI_ENTRY *)FunctionContext;
1074 MAC_TABLE_ENTRY *pEntry;
1075 PRTMP_ADAPTER pAd;
1076
1077 if (pBAEntry == NULL)
1078 return;
1079
1080 pAd = pBAEntry->pAdapter;
1081
1082#ifdef CONFIG_STA_SUPPORT
1083 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1084 {
1085 // Do nothing if monitor mode is on
1086 if (MONITOR_ON(pAd))
1087 return;
1088 }
1089#endif // CONFIG_STA_SUPPORT //
1090
1091#ifdef RALINK_ATE
1092 // Nothing to do in ATE mode.
1093 if (ATE_ON(pAd))
1094 return;
1095#endif // RALINK_ATE //
1096
1097 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
1098
1099 if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) && (pBAEntry->Token < ORI_SESSION_MAX_RETRY))
1100 {
1101 MLME_ADDBA_REQ_STRUCT AddbaReq;
1102
1103 NdisZeroMemory(&AddbaReq, sizeof(AddbaReq));
1104 COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr);
1105 AddbaReq.Wcid = (UCHAR)(pEntry->Aid);
1106 AddbaReq.TID = pBAEntry->TID;
1107 AddbaReq.BaBufSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
1108 AddbaReq.TimeOutValue = 0;
1109 AddbaReq.Token = pBAEntry->Token;
1110 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq);
1111 RT28XX_MLME_HANDLER(pAd);
1112 DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
1113
1114 pBAEntry->Token++;
1115 RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
1116 }
1117 else
1118 {
1119 BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]);
1120 }
1121}
1122
1123/*
1124 ==========================================================================
1125 Description:
1126 Retry sending ADDBA Reqest.
1127
1128 IRQL = DISPATCH_LEVEL
1129
1130 Parametrs:
1131 p8023Header: if this is already 802.3 format, p8023Header is NULL
1132
1133 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
1134 FALSE , then continue indicaterx at this moment.
1135 ==========================================================================
1136 */
1137VOID BARecSessionIdleTimeout(
1138 IN PVOID SystemSpecific1,
1139 IN PVOID FunctionContext,
1140 IN PVOID SystemSpecific2,
1141 IN PVOID SystemSpecific3)
1142{
1143
1144 BA_REC_ENTRY *pBAEntry = (BA_REC_ENTRY *)FunctionContext;
1145 PRTMP_ADAPTER pAd;
1146 ULONG Now32;
1147
1148 if (pBAEntry == NULL)
1149 return;
1150
1151 if ((pBAEntry->REC_BA_Status == Recipient_Accept))
1152 {
1153 NdisGetSystemUpTime(&Now32);
1154
1155 if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT)))
1156 {
1157 pAd = pBAEntry->pAdapter;
1158 // flush all pending reordering mpdus
1159 ba_refresh_reordering_mpdus(pAd, pBAEntry);
1160 printk("%ld: REC BA session Timeout\n", Now32);
1161 }
1162 }
1163}
1164
1165
1166VOID PeerAddBAReqAction(
1167 IN PRTMP_ADAPTER pAd,
1168 IN MLME_QUEUE_ELEM *Elem)
1169
1170{
1171 // 7.4.4.1
1172 //ULONG Idx;
1173 UCHAR Status = 1;
1174 UCHAR pAddr[6];
1175 FRAME_ADDBA_RSP ADDframe;
1176 PUCHAR pOutBuffer = NULL;
1177 NDIS_STATUS NStatus;
1178 PFRAME_ADDBA_REQ pAddreqFrame = NULL;
1179 //UCHAR BufSize;
1180 ULONG FrameLen;
1181 PULONG ptemp;
1182 PMAC_TABLE_ENTRY pMacEntry;
1183
1184 DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __FUNCTION__, Elem->Wcid));
1185
1186 //hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen);
1187
1188 //ADDBA Request from unknown peer, ignore this.
1189 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
1190 return;
1191
1192 pMacEntry = &pAd->MacTab.Content[Elem->Wcid];
1193 DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n"));
1194 ptemp = (PULONG)Elem->Msg;
1195 //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)));
1196
1197 if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr))
1198 {
1199
1200 if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry))
1201 {
1202 pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
1203 printk("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid);
1204 if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))
1205 Status = 0;
1206 else
1207 Status = 38; // more parameters have invalid values
1208 }
1209 else
1210 {
1211 Status = 37; // the request has been declined.
1212 }
1213 }
1214
1215 if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)
1216 ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);
1217
1218 pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
1219 // 2. Always send back ADDBA Response
1220 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1221 if (NStatus != NDIS_STATUS_SUCCESS)
1222 {
1223 DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n"));
1224 return;
1225 }
1226
1227 NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP));
1228 // 2-1. Prepare ADDBA Response frame.
1229#ifdef CONFIG_STA_SUPPORT
1230 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1231 {
1232 if (ADHOC_ON(pAd))
1233 ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1234 else
1235#ifdef QOS_DLS_SUPPORT
1236 if (pAd->MacTab.Content[Elem->Wcid].ValidAsDls)
1237 ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1238 else
1239#endif // QOS_DLS_SUPPORT //
1240 ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
1241 }
1242#endif // CONFIG_STA_SUPPORT //
1243 ADDframe.Category = CATEGORY_BA;
1244 ADDframe.Action = ADDBA_RESP;
1245 ADDframe.Token = pAddreqFrame->Token;
1246 // What is the Status code?? need to check.
1247 ADDframe.StatusCode = Status;
1248 ADDframe.BaParm.BAPolicy = IMMED_BA;
1249 ADDframe.BaParm.AMSDUSupported = 0;
1250 ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;
1251 ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
1252 if (ADDframe.BaParm.BufSize == 0)
1253 {
1254 ADDframe.BaParm.BufSize = 64;
1255 }
1256 ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue;
1257
1258 *(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm));
1259 ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode);
1260 ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue);
1261
1262 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1263 sizeof(FRAME_ADDBA_RSP), &ADDframe,
1264 END_OF_ARGS);
1265 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1266 MlmeFreeMemory(pAd, pOutBuffer);
1267
1268 DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __FUNCTION__, Elem->Wcid, ADDframe.BaParm.TID,
1269 ADDframe.BaParm.BufSize));
1270}
1271
1272
1273VOID PeerAddBARspAction(
1274 IN PRTMP_ADAPTER pAd,
1275 IN MLME_QUEUE_ELEM *Elem)
1276
1277{
1278 //UCHAR Idx, i;
1279 //PUCHAR pOutBuffer = NULL;
1280 PFRAME_ADDBA_RSP pFrame = NULL;
1281 //PBA_ORI_ENTRY pBAEntry;
1282
1283 //ADDBA Response from unknown peer, ignore this.
1284 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
1285 return;
1286
1287 DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __FUNCTION__, Elem->Wcid));
1288
1289 //hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen);
1290
1291 if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen))
1292 {
1293 pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]);
1294
1295 DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode));
1296 switch (pFrame->StatusCode)
1297 {
1298 case 0:
1299 // I want a BAsession with this peer as an originator.
1300 BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame);
1301 break;
1302 default:
1303 // check status == USED ???
1304 BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE);
1305 break;
1306 }
1307 // Rcv Decline StatusCode
1308 if ((pFrame->StatusCode == 37)
1309#ifdef CONFIG_STA_SUPPORT
1310 || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) && (pFrame->StatusCode != 0))
1311#endif // CONFIG_STA_SUPPORT //
1312 )
1313 {
1314 pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->BaParm.TID;
1315 }
1316 }
1317}
1318
1319VOID PeerDelBAAction(
1320 IN PRTMP_ADAPTER pAd,
1321 IN MLME_QUEUE_ELEM *Elem)
1322
1323{
1324 //UCHAR Idx;
1325 //PUCHAR pOutBuffer = NULL;
1326 PFRAME_DELBA_REQ pDelFrame = NULL;
1327
1328 DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __FUNCTION__));
1329 //DELBA Request from unknown peer, ignore this.
1330 if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen))
1331 {
1332 pDelFrame = (PFRAME_DELBA_REQ)(&Elem->Msg[0]);
1333 if (pDelFrame->DelbaParm.Initiator == ORIGINATOR)
1334 {
1335 DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> ORIGINATOR\n"));
1336 BARecSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE);
1337 }
1338 else
1339 {
1340 DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n", pDelFrame->ReasonCode));
1341 //hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen);
1342 BAOriSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE, FALSE);
1343 }
1344 }
1345}
1346
1347
1348BOOLEAN CntlEnqueueForRecv(
1349 IN PRTMP_ADAPTER pAd,
1350 IN ULONG Wcid,
1351 IN ULONG MsgLen,
1352 IN PFRAME_BA_REQ pMsg)
1353{
1354 PFRAME_BA_REQ pFrame = pMsg;
1355 //PRTMP_REORDERBUF pBuffer;
1356 //PRTMP_REORDERBUF pDmaBuf;
1357 PBA_REC_ENTRY pBAEntry;
1358 //BOOLEAN Result;
1359 ULONG Idx;
1360 //UCHAR NumRxPkt;
1361 UCHAR TID;//, i;
1362
1363 TID = (UCHAR)pFrame->BARControl.TID;
1364
1365 DBGPRINT(RT_DEBUG_TRACE, ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __FUNCTION__, Wcid, TID));
1366 //hex_dump("BAR", (PCHAR) pFrame, MsgLen);
1367 // Do nothing if the driver is starting halt state.
1368 // This might happen when timer already been fired before cancel timer with mlmehalt
1369 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
1370 return FALSE;
1371
1372 // First check the size, it MUST not exceed the mlme queue size
1373 if (MsgLen > MGMT_DMA_BUFFER_SIZE)
1374 {
1375 DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
1376 return FALSE;
1377 }
1378 else if (MsgLen != sizeof(FRAME_BA_REQ))
1379 {
1380 DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
1381 return FALSE;
1382 }
1383 else if (MsgLen != sizeof(FRAME_BA_REQ))
1384 {
1385 DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
1386 return FALSE;
1387 }
1388
1389 if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8))
1390 {
1391 // if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search.
1392 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
1393 pBAEntry = &pAd->BATable.BARecEntry[Idx];
1394 }
1395 else
1396 {
1397 return FALSE;
1398 }
1399
1400 DBGPRINT(RT_DEBUG_TRACE, ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq ));
1401
1402 if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
1403 {
1404 //printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq);
1405 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);
1406 pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);
1407 }
1408 //ba_refresh_reordering_mpdus(pAd, pBAEntry);
1409 return TRUE;
1410}
1411
1412/*
1413Description : Send PSMP Action frame If PSMP mode switches.
1414*/
1415VOID SendPSMPAction(
1416 IN PRTMP_ADAPTER pAd,
1417 IN UCHAR Wcid,
1418 IN UCHAR Psmp)
1419{
1420 PUCHAR pOutBuffer = NULL;
1421 NDIS_STATUS NStatus;
1422 //ULONG Idx;
1423 FRAME_PSMP_ACTION Frame;
1424 ULONG FrameLen;
1425
1426 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1427 if (NStatus != NDIS_STATUS_SUCCESS)
1428 {
1429 DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
1430 return;
1431 }
1432#ifdef CONFIG_STA_SUPPORT
1433 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1434 ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
1435#endif // CONFIG_STA_SUPPORT //
1436
1437 Frame.Category = CATEGORY_HT;
1438 Frame.Action = SMPS_ACTION;
1439 switch (Psmp)
1440 {
1441 case MMPS_ENABLE:
1442 Frame.Psmp = 0;
1443 break;
1444 case MMPS_DYNAMIC:
1445 Frame.Psmp = 3;
1446 break;
1447 case MMPS_STATIC:
1448 Frame.Psmp = 1;
1449 break;
1450 }
1451 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1452 sizeof(FRAME_PSMP_ACTION), &Frame,
1453 END_OF_ARGS);
1454 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1455 MlmeFreeMemory(pAd, pOutBuffer);
1456 DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d ) \n", Frame.Psmp));
1457}
1458
1459
1460#define RADIO_MEASUREMENT_REQUEST_ACTION 0
1461
1462typedef struct PACKED
1463{
1464 UCHAR RegulatoryClass;
1465 UCHAR ChannelNumber;
1466 USHORT RandomInterval;
1467 USHORT MeasurementDuration;
1468 UCHAR MeasurementMode;
1469 UCHAR BSSID[MAC_ADDR_LEN];
1470 UCHAR ReportingCondition;
1471 UCHAR Threshold;
1472 UCHAR SSIDIE[2]; // 2 byte
1473} BEACON_REQUEST;
1474
1475typedef struct PACKED
1476{
1477 UCHAR ID;
1478 UCHAR Length;
1479 UCHAR Token;
1480 UCHAR RequestMode;
1481 UCHAR Type;
1482} MEASUREMENT_REQ;
1483
1484
1485
1486
1487void convert_reordering_packet_to_preAMSDU_or_802_3_packet(
1488 IN PRTMP_ADAPTER pAd,
1489 IN RX_BLK *pRxBlk,
1490 IN UCHAR FromWhichBSSID)
1491{
1492 PNDIS_PACKET pRxPkt;
1493 UCHAR Header802_3[LENGTH_802_3];
1494
1495 // 1. get 802.3 Header
1496 // 2. remove LLC
1497 // a. pointer pRxBlk->pData to payload
1498 // b. modify pRxBlk->DataSize
1499
1500#ifdef CONFIG_STA_SUPPORT
1501 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1502 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
1503#endif // CONFIG_STA_SUPPORT //
1504
1505 ASSERT(pRxBlk->pRxPacket);
1506 pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
1507
1508 RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
1509 RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData;
1510 RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize;
1511 RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len;
1512
1513 //
1514 // copy 802.3 header, if necessary
1515 //
1516 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
1517 {
1518
1519#ifdef CONFIG_STA_SUPPORT
1520 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1521 {
1522#ifdef LINUX
1523 NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
1524#endif
1525#ifdef UCOS
1526 NdisMoveMemory(net_pkt_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
1527#endif
1528 }
1529#endif // CONFIG_STA_SUPPORT //
1530 }
1531}
1532
1533
1534#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID) \
1535 do \
1536 { \
1537 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU)) \
1538 { \
1539 Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
1540 } \
1541 else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP)) \
1542 { \
1543 Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
1544 } \
1545 else \
1546 { \
1547 Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
1548 } \
1549 } while (0);
1550
1551
1552
1553static VOID ba_enqueue_reordering_packet(
1554 IN PRTMP_ADAPTER pAd,
1555 IN PBA_REC_ENTRY pBAEntry,
1556 IN RX_BLK *pRxBlk,
1557 IN UCHAR FromWhichBSSID)
1558{
1559 struct reordering_mpdu *mpdu_blk;
1560 UINT16 Sequence = (UINT16) pRxBlk->pHeader->Sequence;
1561
1562 mpdu_blk = ba_mpdu_blk_alloc(pAd);
1563 if (mpdu_blk != NULL)
1564 {
1565 // Write RxD buffer address & allocated buffer length
1566 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
1567
1568 mpdu_blk->Sequence = Sequence;
1569
1570 mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);
1571
1572 convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, pRxBlk, FromWhichBSSID);
1573
1574 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
1575
1576 //
1577 // it is necessary for reordering packet to record
1578 // which BSS it come from
1579 //
1580 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
1581
1582 mpdu_blk->pPacket = pRxBlk->pRxPacket;
1583
1584 if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) == FALSE)
1585 {
1586 // had been already within reordering list
1587 // don't indicate
1588 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_SUCCESS);
1589 ba_mpdu_blk_free(pAd, mpdu_blk);
1590 }
1591
1592 ASSERT((0<= pBAEntry->list.qlen) && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
1593 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
1594 }
1595 else
1596 {
1597#if 0
1598 DBGPRINT(RT_DEBUG_ERROR, ("!!! (%d:%d) Can't allocate reordering mpdu blk\n",
1599 blk_count, pBAEntry->list.qlen));
1600#else
1601 DBGPRINT(RT_DEBUG_ERROR, ("!!! (%d) Can't allocate reordering mpdu blk\n",
1602 pBAEntry->list.qlen));
1603#endif
1604 /*
1605 * flush all pending reordering mpdus
1606 * and receving mpdu to upper layer
1607 * make tcp/ip to take care reordering mechanism
1608 */
1609 //ba_refresh_reordering_mpdus(pAd, pBAEntry);
1610 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
1611
1612 pBAEntry->LastIndSeq = Sequence;
1613 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1614 }
1615}
1616
1617
1618/*
1619 ==========================================================================
1620 Description:
1621 Indicate this packet to upper layer or put it into reordering buffer
1622
1623 Parametrs:
1624 pRxBlk : carry necessary packet info 802.11 format
1625 FromWhichBSSID : the packet received from which BSS
1626
1627 Return :
1628 none
1629
1630 Note :
1631 the packet queued into reordering buffer need to cover to 802.3 format
1632 or pre_AMSDU format
1633 ==========================================================================
1634 */
1635
1636VOID Indicate_AMPDU_Packet(
1637 IN PRTMP_ADAPTER pAd,
1638 IN RX_BLK *pRxBlk,
1639 IN UCHAR FromWhichBSSID)
1640{
1641 USHORT Idx;
1642 PBA_REC_ENTRY pBAEntry = NULL;
1643 UINT16 Sequence = pRxBlk->pHeader->Sequence;
1644 ULONG Now32;
1645 UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
1646 UCHAR TID = pRxBlk->pRxWI->TID;
1647
1648
1649 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) && (pRxBlk->DataSize > MAX_RX_PKT_LEN))
1650 {
1651#if 0 // sample take off, no use
1652 static int err_size;
1653
1654 err_size++;
1655 if (err_size > 20) {
1656 printk("AMPDU DataSize = %d\n", pRxBlk->DataSize);
1657 hex_dump("802.11 Header", (UCHAR *)pRxBlk->pHeader, 24);
1658 hex_dump("Payload", pRxBlk->pData, 64);
1659 err_size = 0;
1660 }
1661#endif
1662 // release packet
1663 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1664 return;
1665 }
1666
1667
1668#if 0 // test
1669 /* Rec BA Session had been torn down */
1670 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1671 return;
1672#endif
1673
1674 if (Wcid < MAX_LEN_OF_MAC_TABLE)
1675 {
1676 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
1677 if (Idx == 0)
1678 {
1679 /* Rec BA Session had been torn down */
1680 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1681 return;
1682 }
1683 pBAEntry = &pAd->BATable.BARecEntry[Idx];
1684 }
1685 else
1686 {
1687 // impossible !!!
1688 ASSERT(0);
1689 // release packet
1690 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1691 return;
1692 }
1693
1694 ASSERT(pBAEntry);
1695
1696 // update last rx time
1697 NdisGetSystemUpTime(&Now32);
1698
1699 pBAEntry->rcvSeq = Sequence;
1700
1701
1702 ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
1703 pBAEntry->LastIndSeqAtTimer = Now32;
1704
1705 //
1706 // Reset Last Indicate Sequence
1707 //
1708 if (pBAEntry->LastIndSeq == RESET_RCV_SEQ)
1709 {
1710 ASSERT((pBAEntry->list.qlen == 0) && (pBAEntry->list.next == NULL));
1711
1712 // reset rcv sequence of BA session
1713 pBAEntry->LastIndSeq = Sequence;
1714 pBAEntry->LastIndSeqAtTimer = Now32;
1715 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1716 return;
1717 }
1718
1719
1720 //
1721 // I. Check if in order.
1722 //
1723 if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
1724 {
1725 USHORT LastIndSeq;
1726
1727 pBAEntry->LastIndSeq = Sequence;
1728 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1729 LastIndSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
1730 if (LastIndSeq != RESET_RCV_SEQ)
1731 {
1732 pBAEntry->LastIndSeq = LastIndSeq;
1733 }
1734 pBAEntry->LastIndSeqAtTimer = Now32;
1735 }
1736 //
1737 // II. Drop Duplicated Packet
1738 //
1739 else if (Sequence == pBAEntry->LastIndSeq)
1740 {
1741
1742 // drop and release packet
1743 pBAEntry->nDropPacket++;
1744 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1745 }
1746 //
1747 // III. Drop Old Received Packet
1748 //
1749 else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
1750 {
1751
1752 // drop and release packet
1753 pBAEntry->nDropPacket++;
1754 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1755 }
1756 //
1757 // IV. Receive Sequence within Window Size
1758 //
1759 else if (SEQ_SMALLER(Sequence, (((pBAEntry->LastIndSeq+pBAEntry->BAWinSize+1)) & MAXSEQ), MAXSEQ))
1760 {
1761 ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
1762 }
1763 //
1764 // V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer
1765 //
1766 else
1767 {
1768#if 0
1769 ba_refresh_reordering_mpdus(pAd, pBAEntry);
1770 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1771#else
1772 LONG WinStartSeq, TmpSeq;
1773
1774
1775 TmpSeq = Sequence - (pBAEntry->BAWinSize) -1;
1776 if (TmpSeq < 0)
1777 {
1778 TmpSeq = (MAXSEQ+1) + TmpSeq;
1779 }
1780 WinStartSeq = (TmpSeq+1) & MAXSEQ;
1781 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);
1782 pBAEntry->LastIndSeq = WinStartSeq; //TmpSeq;
1783
1784 pBAEntry->LastIndSeqAtTimer = Now32;
1785
1786 ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
1787
1788 TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
1789 if (TmpSeq != RESET_RCV_SEQ)
1790 {
1791 pBAEntry->LastIndSeq = TmpSeq;
1792 }
1793#endif
1794 }
1795}
1796
1797#endif // DOT11_N_SUPPORT //
1798
diff --git a/drivers/staging/rt2870/common/cmm_data.c b/drivers/staging/rt2870/common/cmm_data.c
new file mode 100644
index 00000000000..4477a8e64a2
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_data.c
@@ -0,0 +1,2734 @@
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
178
179/*
180 ========================================================================
181
182 Routine Description:
183 Copy frame from waiting queue into relative ring buffer and set
184 appropriate ASIC register to kick hardware transmit function
185
186 Arguments:
187 pAd Pointer to our adapter
188 pBuffer Pointer to memory of outgoing frame
189 Length Size of outgoing management frame
190
191 Return Value:
192 NDIS_STATUS_FAILURE
193 NDIS_STATUS_PENDING
194 NDIS_STATUS_SUCCESS
195
196 IRQL = PASSIVE_LEVEL
197 IRQL = DISPATCH_LEVEL
198
199 Note:
200
201 ========================================================================
202*/
203NDIS_STATUS MlmeHardTransmit(
204 IN PRTMP_ADAPTER pAd,
205 IN UCHAR QueIdx,
206 IN PNDIS_PACKET pPacket)
207{
208 if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
209#ifdef CARRIER_DETECTION_SUPPORT
210#endif // CARRIER_DETECTION_SUPPORT //
211 )
212 {
213 return NDIS_STATUS_FAILURE;
214 }
215
216 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
217
218}
219
220
221
222NDIS_STATUS MlmeHardTransmitMgmtRing(
223 IN PRTMP_ADAPTER pAd,
224 IN UCHAR QueIdx,
225 IN PNDIS_PACKET pPacket)
226{
227 PACKET_INFO PacketInfo;
228 PUCHAR pSrcBufVA;
229 UINT SrcBufLen;
230 PHEADER_802_11 pHeader_802_11;
231 BOOLEAN bAckRequired, bInsertTimestamp;
232 UCHAR MlmeRate;
233 PTXWI_STRUC pFirstTxWI;
234 MAC_TABLE_ENTRY *pMacEntry = NULL;
235
236 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
237
238 // Make sure MGMT ring resource won't be used by other threads
239// sample, for IRQ LOCK -> SEM LOCK
240// IrqState = pAd->irq_disabled;
241// if (!IrqState)
242 RTMP_SEM_LOCK(&pAd->MgmtRingLock);
243
244
245 if (pSrcBufVA == NULL)
246 {
247 // The buffer shouldn't be NULL
248// if (!IrqState)
249 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
250 return NDIS_STATUS_FAILURE;
251 }
252
253#ifdef CONFIG_STA_SUPPORT
254 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
255 {
256 // outgoing frame always wakeup PHY to prevent frame lost
257 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
258 AsicForceWakeup(pAd, TRUE);
259 }
260#endif // CONFIG_STA_SUPPORT //
261
262 pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE);
263 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
264
265 if (pHeader_802_11->Addr1[0] & 0x01)
266 {
267 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
268 }
269 else
270 {
271 MlmeRate = pAd->CommonCfg.MlmeRate;
272 }
273
274 // Verify Mlme rate for a / g bands.
275 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
276 MlmeRate = RATE_6;
277
278 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
279 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
280 {
281 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
282 }
283
284#ifdef CONFIG_STA_SUPPORT
285 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
286 {
287 // Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
288 if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
289#ifdef DOT11_N_SUPPORT
290 || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
291#endif // DOT11_N_SUPPORT //
292 )
293 {
294 if (pAd->LatchRfRegs.Channel > 14)
295 pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
296 else
297 pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
298 }
299 }
300#endif // CONFIG_STA_SUPPORT //
301
302 //
303 // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
304 // Snice it's been set to 0 while on MgtMacHeaderInit
305 // By the way this will cause frame to be send on PWR_SAVE failed.
306 //
307 // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
308 //
309 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
310#ifdef CONFIG_STA_SUPPORT
311 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
312 if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
313 {
314 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
315 (pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
316 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
317 else
318 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
319 }
320#endif // CONFIG_STA_SUPPORT //
321
322 bInsertTimestamp = FALSE;
323 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
324 {
325#ifdef CONFIG_STA_SUPPORT
326 //Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue.
327 if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
328 {
329 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
330 }
331#endif // CONFIG_STA_SUPPORT //
332 bAckRequired = FALSE;
333 }
334 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
335 {
336 //pAd->Sequence++;
337 //pHeader_802_11->Sequence = pAd->Sequence;
338
339 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
340 {
341 bAckRequired = FALSE;
342 pHeader_802_11->Duration = 0;
343 }
344 else
345 {
346 bAckRequired = TRUE;
347 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
348 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
349 {
350 bInsertTimestamp = TRUE;
351 }
352 }
353 }
354
355 pHeader_802_11->Sequence = pAd->Sequence++;
356 if (pAd->Sequence >0xfff)
357 pAd->Sequence = 0;
358
359 // Before radar detection done, mgmt frame can not be sent but probe req
360 // Because we need to use probe req to trigger driver to send probe req in passive scan
361 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
362 && (pAd->CommonCfg.bIEEE80211H == 1)
363 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
364 {
365 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
366// if (!IrqState)
367 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
368 return (NDIS_STATUS_FAILURE);
369 }
370
371#ifdef RT_BIG_ENDIAN
372 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
373#endif
374
375 //
376 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
377 // should always has only one ohysical buffer, and the whole frame size equals
378 // to the first scatter buffer size
379 //
380
381 // Initialize TX Descriptor
382 // For inter-frame gap, the number is for this frame and next frame
383 // For MLME rate, we will fix as 2Mb to match other vendor's implement
384// pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
385
386// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
387 if (pMacEntry == NULL)
388 {
389 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
390 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
391 }
392 else
393 {
394 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
395 bInsertTimestamp, FALSE, bAckRequired, FALSE,
396 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
397 pMacEntry->MaxHTPhyMode.field.MCS, 0,
398 (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
399 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
400 }
401
402#ifdef RT_BIG_ENDIAN
403 RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
404#endif
405
406 // Now do hardware-depened kick out.
407 HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
408
409 // Make sure to release MGMT ring resource
410// if (!IrqState)
411 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
412 return NDIS_STATUS_SUCCESS;
413}
414
415
416/********************************************************************************
417
418 New DeQueue Procedures.
419
420 ********************************************************************************/
421
422#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \
423 do{ \
424 if (bIntContext == FALSE) \
425 RTMP_IRQ_LOCK((lock), IrqFlags); \
426 }while(0)
427
428#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \
429 do{ \
430 if (bIntContext == FALSE) \
431 RTMP_IRQ_UNLOCK((lock), IrqFlags); \
432 }while(0)
433
434
435#if 0
436static VOID dumpTxBlk(TX_BLK *pTxBlk)
437{
438 NDIS_PACKET *pPacket;
439 int i, frameNum;
440 PQUEUE_ENTRY pQEntry;
441
442 printk("Dump TX_BLK Structure:\n");
443 printk("\tTxFrameType=%d!\n", pTxBlk->TxFrameType);
444 printk("\tTotalFrameLen=%d\n", pTxBlk->TotalFrameLen);
445 printk("\tTotalFrameNum=%ld!\n", pTxBlk->TxPacketList.Number);
446 printk("\tTotalFragNum=%d!\n", pTxBlk->TotalFragNum);
447 printk("\tpPacketList=\n");
448
449 frameNum = pTxBlk->TxPacketList.Number;
450
451 for(i=0; i < frameNum; i++)
452 { int j;
453 UCHAR *pBuf;
454
455 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
456 pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
457 if (pPacket)
458 {
459 pBuf = GET_OS_PKT_DATAPTR(pPacket);
460 printk("\t\t[%d]:ptr=0x%x, Len=%d!\n", i, (UINT32)(GET_OS_PKT_DATAPTR(pPacket)), GET_OS_PKT_LEN(pPacket));
461 printk("\t\t");
462 for (j =0 ; j < GET_OS_PKT_LEN(pPacket); j++)
463 {
464 printk("%02x ", (pBuf[j] & 0xff));
465 if (j == 16)
466 break;
467 }
468 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
469 }
470 }
471 printk("\tWcid=%d!\n", pTxBlk->Wcid);
472 printk("\tapidx=%d!\n", pTxBlk->apidx);
473 printk("----EndOfDump\n");
474
475}
476#endif
477
478
479/*
480 ========================================================================
481 Tx Path design algorithm:
482 Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
483 Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
484 Classification Rule=>
485 Multicast: (*addr1 & 0x01) == 0x01
486 Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
487 11N Rate : If peer support HT
488 (1).AMPDU -- If TXBA is negotiated.
489 (2).AMSDU -- If AMSDU is capable for both peer and ourself.
490 *). AMSDU can embedded in a AMPDU, but now we didn't support it.
491 (3).Normal -- Other packets which send as 11n rate.
492
493 B/G Rate : If peer is b/g only.
494 (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
495 (2).Normal -- Other packets which send as b/g rate.
496 Fragment:
497 The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
498
499 Classified Packet Handle Rule=>
500 Multicast:
501 No ACK, //pTxBlk->bAckRequired = FALSE;
502 No WMM, //pTxBlk->bWMM = FALSE;
503 No piggyback, //pTxBlk->bPiggyBack = FALSE;
504 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
505 Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use
506 the same policy to handle it.
507 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
508
509 11N Rate :
510 No piggyback, //pTxBlk->bPiggyBack = FALSE;
511
512 (1).AMSDU
513 pTxBlk->bWMM = TRUE;
514 (2).AMPDU
515 pTxBlk->bWMM = TRUE;
516 (3).Normal
517
518 B/G Rate :
519 (1).ARALINK
520
521 (2).Normal
522 ========================================================================
523*/
524static UCHAR TxPktClassification(
525 IN RTMP_ADAPTER *pAd,
526 IN PNDIS_PACKET pPacket)
527{
528 UCHAR TxFrameType = TX_UNKOWN_FRAME;
529 UCHAR Wcid;
530 MAC_TABLE_ENTRY *pMacEntry = NULL;
531#ifdef DOT11_N_SUPPORT
532 BOOLEAN bHTRate = FALSE;
533#endif // DOT11_N_SUPPORT //
534
535 Wcid = RTMP_GET_PACKET_WCID(pPacket);
536 if (Wcid == MCAST_WCID)
537 { // Handle for RA is Broadcast/Multicast Address.
538 return TX_MCAST_FRAME;
539 }
540
541 // Handle for unicast packets
542 pMacEntry = &pAd->MacTab.Content[Wcid];
543 if (RTMP_GET_PACKET_LOWRATE(pPacket))
544 { // It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
545 TxFrameType = TX_LEGACY_FRAME;
546 }
547#ifdef DOT11_N_SUPPORT
548 else if (IS_HT_RATE(pMacEntry))
549 { // it's a 11n capable packet
550
551 // Depends on HTPhyMode to check if the peer support the HTRate transmission.
552 // Currently didn't support A-MSDU embedded in A-MPDU
553 bHTRate = TRUE;
554 if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
555 TxFrameType = TX_LEGACY_FRAME;
556#ifdef UAPSD_AP_SUPPORT
557 else if (RTMP_GET_PACKET_EOSP(pPacket))
558 TxFrameType = TX_LEGACY_FRAME;
559#endif // UAPSD_AP_SUPPORT //
560 else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
561 return TX_AMPDU_FRAME;
562 else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
563 return TX_AMSDU_FRAME;
564 else
565 TxFrameType = TX_LEGACY_FRAME;
566 }
567#endif // DOT11_N_SUPPORT //
568 else
569 { // it's a legacy b/g packet.
570 if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
571 (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
572 (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
573 { // if peer support Ralink Aggregation, we use it.
574 TxFrameType = TX_RALINK_FRAME;
575 }
576 else
577 {
578 TxFrameType = TX_LEGACY_FRAME;
579 }
580 }
581
582 // Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
583 if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
584 TxFrameType = TX_FRAG_FRAME;
585
586 return TxFrameType;
587}
588
589
590BOOLEAN RTMP_FillTxBlkInfo(
591 IN RTMP_ADAPTER *pAd,
592 IN TX_BLK *pTxBlk)
593{
594 PACKET_INFO PacketInfo;
595 PNDIS_PACKET pPacket;
596 PMAC_TABLE_ENTRY pMacEntry = NULL;
597
598 pPacket = pTxBlk->pPacket;
599 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
600
601 pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
602 pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
603 pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
604 pTxBlk->FrameGap = IFS_HTTXOP; // ASIC determine Frame Gap
605
606 if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
607 TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
608 else
609 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
610
611 // Default to clear this flag
612 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
613
614
615 if (pTxBlk->Wcid == MCAST_WCID)
616 {
617 pTxBlk->pMacEntry = NULL;
618 {
619#ifdef MCAST_RATE_SPECIFIC
620 PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
621 if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
622 pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
623 else
624#endif // MCAST_RATE_SPECIFIC //
625 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
626 }
627
628 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); // AckRequired = FALSE, when broadcast packet in Adhoc mode.
629 //TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
630 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
631 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
632 if (RTMP_GET_PACKET_MOREDATA(pPacket))
633 {
634 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
635 }
636
637 }
638 else
639 {
640 pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
641 pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
642
643 pMacEntry = pTxBlk->pMacEntry;
644
645
646 // For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
647 if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
648 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
649 else
650 TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
651
652 {
653
654#ifdef CONFIG_STA_SUPPORT
655 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
656 {
657
658 // If support WMM, enable it.
659 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
660 CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
661 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
662 }
663#endif // CONFIG_STA_SUPPORT //
664 }
665
666 if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
667 {
668 if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
669 ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
670 { // Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
671 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
672#ifdef DOT11_N_SUPPORT
673 // Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
674 if (IS_HT_STA(pTxBlk->pMacEntry) &&
675 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
676 ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
677 {
678 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
679 TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
680 }
681#endif // DOT11_N_SUPPORT //
682 }
683
684#ifdef DOT11_N_SUPPORT
685 if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
686 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
687 { // Currently piggy-back only support when peer is operate in b/g mode.
688 TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
689 }
690#endif // DOT11_N_SUPPORT //
691
692 if (RTMP_GET_PACKET_MOREDATA(pPacket))
693 {
694 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
695 }
696#ifdef UAPSD_AP_SUPPORT
697 if (RTMP_GET_PACKET_EOSP(pPacket))
698 {
699 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
700 }
701#endif // UAPSD_AP_SUPPORT //
702 }
703 else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
704 {
705 TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
706 }
707
708 pMacEntry->DebugTxCount++;
709 }
710
711 return TRUE;
712
713FillTxBlkErr:
714 return FALSE;
715}
716
717
718BOOLEAN CanDoAggregateTransmit(
719 IN RTMP_ADAPTER *pAd,
720 IN NDIS_PACKET *pPacket,
721 IN TX_BLK *pTxBlk)
722{
723
724 //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
725
726 if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
727 return FALSE;
728
729 if (RTMP_GET_PACKET_DHCP(pPacket) ||
730 RTMP_GET_PACKET_EAPOL(pPacket) ||
731 RTMP_GET_PACKET_WAI(pPacket))
732 return FALSE;
733
734 if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
735 ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
736 { // For AMSDU, allow the packets with total length < max-amsdu size
737 return FALSE;
738 }
739
740 if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
741 (pTxBlk->TxPacketList.Number == 2))
742 { // For RALINK-Aggregation, allow two frames in one batch.
743 return FALSE;
744 }
745
746#ifdef CONFIG_STA_SUPPORT
747 if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
748 return TRUE;
749 else
750#endif // CONFIG_STA_SUPPORT //
751 return FALSE;
752
753}
754
755
756/*
757 ========================================================================
758
759 Routine Description:
760 To do the enqueue operation and extract the first item of waiting
761 list. If a number of available shared memory segments could meet
762 the request of extracted item, the extracted item will be fragmented
763 into shared memory segments.
764
765 Arguments:
766 pAd Pointer to our adapter
767 pQueue Pointer to Waiting Queue
768
769 Return Value:
770 None
771
772 IRQL = DISPATCH_LEVEL
773
774 Note:
775
776 ========================================================================
777*/
778VOID RTMPDeQueuePacket(
779 IN PRTMP_ADAPTER pAd,
780 IN BOOLEAN bIntContext,
781 IN UCHAR QIdx, /* BulkOutPipeId */
782 IN UCHAR Max_Tx_Packets)
783{
784 PQUEUE_ENTRY pEntry = NULL;
785 PNDIS_PACKET pPacket;
786 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
787 UCHAR Count=0;
788 PQUEUE_HEADER pQueue;
789 ULONG FreeNumber[NUM_OF_TX_RING];
790 UCHAR QueIdx, sQIdx, eQIdx;
791 unsigned long IrqFlags = 0;
792 BOOLEAN hasTxDesc = FALSE;
793 TX_BLK TxBlk;
794 TX_BLK *pTxBlk;
795
796#ifdef DBG_DIAGNOSE
797 BOOLEAN firstRound;
798 RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct;
799#endif
800
801
802 if (QIdx == NUM_OF_TX_RING)
803 {
804 sQIdx = 0;
805 eQIdx = 3; // 4 ACs, start from 0.
806 }
807 else
808 {
809 sQIdx = eQIdx = QIdx;
810 }
811
812 for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
813 {
814 Count=0;
815
816 RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
817
818#ifdef DBG_DIAGNOSE
819 firstRound = ((QueIdx == 0) ? TRUE : FALSE);
820#endif // DBG_DIAGNOSE //
821
822 while (1)
823 {
824 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
825 fRTMP_ADAPTER_RADIO_OFF |
826 fRTMP_ADAPTER_RESET_IN_PROGRESS |
827 fRTMP_ADAPTER_HALT_IN_PROGRESS |
828 fRTMP_ADAPTER_NIC_NOT_EXIST))))
829 {
830 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
831 return;
832 }
833
834 if (Count >= Max_Tx_Packets)
835 break;
836
837 DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
838 if (&pAd->TxSwQueue[QueIdx] == NULL)
839 {
840#ifdef DBG_DIAGNOSE
841 if (firstRound == TRUE)
842 pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
843#endif // DBG_DIAGNOSE //
844 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
845 break;
846 }
847
848
849 // probe the Queue Head
850 pQueue = &pAd->TxSwQueue[QueIdx];
851 if ((pEntry = pQueue->Head) == NULL)
852 {
853 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
854 break;
855 }
856
857 pTxBlk = &TxBlk;
858 NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
859 //InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it.
860 pTxBlk->QueIdx = QueIdx;
861
862 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
863
864 // Early check to make sure we have enoguh Tx Resource.
865 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
866 if (!hasTxDesc)
867 {
868 pAd->PrivateInfo.TxRingFullCnt++;
869
870 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
871
872 break;
873 }
874
875 pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
876 pEntry = RemoveHeadQueue(pQueue);
877 pTxBlk->TotalFrameNum++;
878 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
879 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
880 pTxBlk->pPacket = pPacket;
881 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
882
883 if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
884 {
885 // Enhance SW Aggregation Mechanism
886 if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
887 {
888 InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
889 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
890 break;
891 }
892
893 do{
894 if((pEntry = pQueue->Head) == NULL)
895 break;
896
897 // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
898 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
899 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
900 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
901 if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
902 break;
903
904 //Remove the packet from the TxSwQueue and insert into pTxBlk
905 pEntry = RemoveHeadQueue(pQueue);
906 ASSERT(pEntry);
907 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
908 pTxBlk->TotalFrameNum++;
909 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
910 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
911 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
912 }while(1);
913
914 if (pTxBlk->TxPacketList.Number == 1)
915 pTxBlk->TxFrameType = TX_LEGACY_FRAME;
916 }
917
918#ifdef RT2870
919 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
920#endif // RT2870 //
921
922 Count += pTxBlk->TxPacketList.Number;
923
924 // Do HardTransmit now.
925#ifdef CONFIG_STA_SUPPORT
926 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
927 Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
928#endif // CONFIG_STA_SUPPORT //
929
930
931#if 0 // We should not break if HardTransmit failed. Well, at least now we should not!
932 if (Status != NDIS_STATUS_SUCCESS)
933 {
934 DBGPRINT(RT_DEBUG_TRACE /*RT_DEBUG_INFO*/,("RTMPHardTransmit return failed!!!\n"));
935 break;
936 }
937#endif
938 }
939
940 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
941
942#ifdef RT2870
943 if (!hasTxDesc)
944 RTUSBKickBulkOut(pAd);
945#endif // RT2870 //
946
947#ifdef BLOCK_NET_IF
948 if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE)
949 && (pAd->TxSwQueue[QueIdx].Number < 1))
950 {
951 releaseNetIf(&pAd->blockQueueTab[QueIdx]);
952 }
953#endif // BLOCK_NET_IF //
954
955 }
956
957}
958
959
960/*
961 ========================================================================
962
963 Routine Description:
964 Calculates the duration which is required to transmit out frames
965 with given size and specified rate.
966
967 Arguments:
968 pAd Pointer to our adapter
969 Rate Transmit rate
970 Size Frame size in units of byte
971
972 Return Value:
973 Duration number in units of usec
974
975 IRQL = PASSIVE_LEVEL
976 IRQL = DISPATCH_LEVEL
977
978 Note:
979
980 ========================================================================
981*/
982USHORT RTMPCalcDuration(
983 IN PRTMP_ADAPTER pAd,
984 IN UCHAR Rate,
985 IN ULONG Size)
986{
987 ULONG Duration = 0;
988
989 if (Rate < RATE_FIRST_OFDM_RATE) // CCK
990 {
991 if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
992 Duration = 96; // 72+24 preamble+plcp
993 else
994 Duration = 192; // 144+48 preamble+plcp
995
996 Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
997 if ((Size << 4) % RateIdTo500Kbps[Rate])
998 Duration ++;
999 }
1000 else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
1001 {
1002 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1003 Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
1004 if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
1005 Duration += 4;
1006 }
1007 else //mimo rate
1008 {
1009 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1010 }
1011
1012 return (USHORT)Duration;
1013}
1014
1015
1016/*
1017 ========================================================================
1018
1019 Routine Description:
1020 Calculates the duration which is required to transmit out frames
1021 with given size and specified rate.
1022
1023 Arguments:
1024 pTxWI Pointer to head of each MPDU to HW.
1025 Ack Setting for Ack requirement bit
1026 Fragment Setting for Fragment bit
1027 RetryMode Setting for retry mode
1028 Ifs Setting for IFS gap
1029 Rate Setting for transmit rate
1030 Service Setting for service
1031 Length Frame length
1032 TxPreamble Short or Long preamble when using CCK rates
1033 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1034
1035 Return Value:
1036 None
1037
1038 IRQL = PASSIVE_LEVEL
1039 IRQL = DISPATCH_LEVEL
1040
1041 See also : BASmartHardTransmit() !!!
1042
1043 ========================================================================
1044*/
1045VOID RTMPWriteTxWI(
1046 IN PRTMP_ADAPTER pAd,
1047 IN PTXWI_STRUC pOutTxWI,
1048 IN BOOLEAN FRAG,
1049 IN BOOLEAN CFACK,
1050 IN BOOLEAN InsTimestamp,
1051 IN BOOLEAN AMPDU,
1052 IN BOOLEAN Ack,
1053 IN BOOLEAN NSeq, // HW new a sequence.
1054 IN UCHAR BASize,
1055 IN UCHAR WCID,
1056 IN ULONG Length,
1057 IN UCHAR PID,
1058 IN UCHAR TID,
1059 IN UCHAR TxRate,
1060 IN UCHAR Txopmode,
1061 IN BOOLEAN CfAck,
1062 IN HTTRANSMIT_SETTING *pTransmit)
1063{
1064 PMAC_TABLE_ENTRY pMac = NULL;
1065 TXWI_STRUC TxWI;
1066 PTXWI_STRUC pTxWI;
1067
1068 if (WCID < MAX_LEN_OF_MAC_TABLE)
1069 pMac = &pAd->MacTab.Content[WCID];
1070
1071 //
1072 // Always use Long preamble before verifiation short preamble functionality works well.
1073 // Todo: remove the following line if short preamble functionality works
1074 //
1075 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1076 NdisZeroMemory(&TxWI, TXWI_SIZE);
1077 pTxWI = &TxWI;
1078
1079 pTxWI->FRAG= FRAG;
1080
1081 pTxWI->CFACK = CFACK;
1082 pTxWI->TS= InsTimestamp;
1083 pTxWI->AMPDU = AMPDU;
1084 pTxWI->ACK = Ack;
1085 pTxWI->txop= Txopmode;
1086
1087 pTxWI->NSEQ = NSeq;
1088 // John tune the performace with Intel Client in 20 MHz performance
1089#ifdef DOT11_N_SUPPORT
1090 BASize = pAd->CommonCfg.TxBASize;
1091
1092 if( BASize >7 )
1093 BASize =7;
1094 pTxWI->BAWinSize = BASize;
1095 pTxWI->ShortGI = pTransmit->field.ShortGI;
1096 pTxWI->STBC = pTransmit->field.STBC;
1097#endif // DOT11_N_SUPPORT //
1098
1099 pTxWI->WirelessCliID = WCID;
1100 pTxWI->MPDUtotalByteCount = Length;
1101 pTxWI->PacketId = PID;
1102
1103 // If CCK or OFDM, BW must be 20
1104 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1105#ifdef DOT11N_DRAFT3
1106 if (pTxWI->BW)
1107 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1108#endif // DOT11N_DRAFT3 //
1109
1110 pTxWI->MCS = pTransmit->field.MCS;
1111 pTxWI->PHYMODE = pTransmit->field.MODE;
1112 pTxWI->CFACK = CfAck;
1113
1114#ifdef DOT11_N_SUPPORT
1115 if (pMac)
1116 {
1117 if (pAd->CommonCfg.bMIMOPSEnable)
1118 {
1119 if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1120 {
1121 // Dynamic MIMO Power Save Mode
1122 pTxWI->MIMOps = 1;
1123 }
1124 else if (pMac->MmpsMode == MMPS_STATIC)
1125 {
1126 // Static MIMO Power Save Mode
1127 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1128 {
1129 pTxWI->MCS = 7;
1130 pTxWI->MIMOps = 0;
1131 }
1132 }
1133 }
1134 //pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
1135 if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
1136 {
1137 pTxWI->MpduDensity = 7;
1138 }
1139 else
1140 {
1141 pTxWI->MpduDensity = pMac->MpduDensity;
1142 }
1143 }
1144#endif // DOT11_N_SUPPORT //
1145
1146 pTxWI->PacketId = pTxWI->MCS;
1147 NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
1148}
1149
1150
1151VOID RTMPWriteTxWI_Data(
1152 IN PRTMP_ADAPTER pAd,
1153 IN OUT PTXWI_STRUC pTxWI,
1154 IN TX_BLK *pTxBlk)
1155{
1156 HTTRANSMIT_SETTING *pTransmit;
1157 PMAC_TABLE_ENTRY pMacEntry;
1158#ifdef DOT11_N_SUPPORT
1159 UCHAR BASize;
1160#endif // DOT11_N_SUPPORT //
1161
1162
1163 ASSERT(pTxWI);
1164
1165 pTransmit = pTxBlk->pTransmit;
1166 pMacEntry = pTxBlk->pMacEntry;
1167
1168
1169 //
1170 // Always use Long preamble before verifiation short preamble functionality works well.
1171 // Todo: remove the following line if short preamble functionality works
1172 //
1173 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1174 NdisZeroMemory(pTxWI, TXWI_SIZE);
1175
1176 pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
1177 pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
1178 pTxWI->txop = pTxBlk->FrameGap;
1179
1180#ifdef CONFIG_STA_SUPPORT
1181#ifdef QOS_DLS_SUPPORT
1182 if (pMacEntry &&
1183 (pAd->StaCfg.BssType == BSS_INFRA) &&
1184 (pMacEntry->ValidAsDls == TRUE))
1185 pTxWI->WirelessCliID = BSSID_WCID;
1186 else
1187#endif // QOS_DLS_SUPPORT //
1188#endif // CONFIG_STA_SUPPORT //
1189 pTxWI->WirelessCliID = pTxBlk->Wcid;
1190
1191 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1192 pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
1193
1194 // If CCK or OFDM, BW must be 20
1195 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1196#ifdef DOT11_N_SUPPORT
1197#ifdef DOT11N_DRAFT3
1198 if (pTxWI->BW)
1199 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1200#endif // DOT11N_DRAFT3 //
1201 pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
1202
1203 // John tune the performace with Intel Client in 20 MHz performance
1204 BASize = pAd->CommonCfg.TxBASize;
1205 if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
1206 {
1207 UCHAR RABAOriIdx = 0; //The RA's BA Originator table index.
1208
1209 RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
1210 BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
1211 }
1212
1213#if 0 // 3*3
1214 if (BASize > 7)
1215 BASize = 7;
1216#endif
1217
1218 pTxWI->TxBF = pTransmit->field.TxBF;
1219 pTxWI->BAWinSize = BASize;
1220 pTxWI->ShortGI = pTransmit->field.ShortGI;
1221 pTxWI->STBC = pTransmit->field.STBC;
1222#endif // DOT11_N_SUPPORT //
1223
1224 pTxWI->MCS = pTransmit->field.MCS;
1225 pTxWI->PHYMODE = pTransmit->field.MODE;
1226
1227#ifdef DOT11_N_SUPPORT
1228 if (pMacEntry)
1229 {
1230 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1231 {
1232 // Dynamic MIMO Power Save Mode
1233 pTxWI->MIMOps = 1;
1234 }
1235 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1236 {
1237 // Static MIMO Power Save Mode
1238 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1239 {
1240 pTxWI->MCS = 7;
1241 pTxWI->MIMOps = 0;
1242 }
1243 }
1244
1245 if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
1246 {
1247 pTxWI->MpduDensity = 7;
1248 }
1249 else
1250 {
1251 pTxWI->MpduDensity = pMacEntry->MpduDensity;
1252 }
1253 }
1254#endif // DOT11_N_SUPPORT //
1255
1256#ifdef DBG_DIAGNOSE
1257 if (pTxBlk->QueIdx== 0)
1258 {
1259 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1260 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1261 }
1262#endif // DBG_DIAGNOSE //
1263
1264 // for rate adapation
1265 pTxWI->PacketId = pTxWI->MCS;
1266}
1267
1268
1269VOID RTMPWriteTxWI_Cache(
1270 IN PRTMP_ADAPTER pAd,
1271 IN OUT PTXWI_STRUC pTxWI,
1272 IN TX_BLK *pTxBlk)
1273{
1274 PHTTRANSMIT_SETTING /*pTxHTPhyMode,*/ pTransmit;
1275 PMAC_TABLE_ENTRY pMacEntry;
1276
1277 //
1278 // update TXWI
1279 //
1280 pMacEntry = pTxBlk->pMacEntry;
1281 pTransmit = pTxBlk->pTransmit;
1282
1283 if (pMacEntry->bAutoTxRateSwitch)
1284 {
1285 pTxWI->txop = IFS_HTTXOP;
1286
1287 // If CCK or OFDM, BW must be 20
1288 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1289 pTxWI->ShortGI = pTransmit->field.ShortGI;
1290 pTxWI->STBC = pTransmit->field.STBC;
1291
1292 pTxWI->MCS = pTransmit->field.MCS;
1293 pTxWI->PHYMODE = pTransmit->field.MODE;
1294
1295 // set PID for TxRateSwitching
1296 pTxWI->PacketId = pTransmit->field.MCS;
1297 }
1298
1299#ifdef DOT11_N_SUPPORT
1300 pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
1301 pTxWI->MIMOps = 0;
1302
1303#ifdef DOT11N_DRAFT3
1304 if (pTxWI->BW)
1305 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1306#endif // DOT11N_DRAFT3 //
1307
1308 if (pAd->CommonCfg.bMIMOPSEnable)
1309 {
1310 // MIMO Power Save Mode
1311 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1312 {
1313 // Dynamic MIMO Power Save Mode
1314 pTxWI->MIMOps = 1;
1315 }
1316 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1317 {
1318 // Static MIMO Power Save Mode
1319 if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
1320 {
1321 pTxWI->MCS = 7;
1322 pTxWI->MIMOps = 0;
1323 }
1324 }
1325 }
1326#endif // DOT11_N_SUPPORT //
1327
1328#ifdef DBG_DIAGNOSE
1329 if (pTxBlk->QueIdx== 0)
1330 {
1331 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1332 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1333 }
1334#endif // DBG_DIAGNOSE //
1335
1336 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1337
1338}
1339
1340
1341/*
1342 ========================================================================
1343
1344 Routine Description:
1345 Calculates the duration which is required to transmit out frames
1346 with given size and specified rate.
1347
1348 Arguments:
1349 pTxD Pointer to transmit descriptor
1350 Ack Setting for Ack requirement bit
1351 Fragment Setting for Fragment bit
1352 RetryMode Setting for retry mode
1353 Ifs Setting for IFS gap
1354 Rate Setting for transmit rate
1355 Service Setting for service
1356 Length Frame length
1357 TxPreamble Short or Long preamble when using CCK rates
1358 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1359
1360 Return Value:
1361 None
1362
1363 IRQL = PASSIVE_LEVEL
1364 IRQL = DISPATCH_LEVEL
1365
1366 ========================================================================
1367*/
1368VOID RTMPWriteTxDescriptor(
1369 IN PRTMP_ADAPTER pAd,
1370 IN PTXD_STRUC pTxD,
1371 IN BOOLEAN bWIV,
1372 IN UCHAR QueueSEL)
1373{
1374 //
1375 // Always use Long preamble before verifiation short preamble functionality works well.
1376 // Todo: remove the following line if short preamble functionality works
1377 //
1378 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1379
1380 pTxD->WIV = (bWIV) ? 1: 0;
1381 pTxD->QSEL= (QueueSEL);
1382 //RT2860c?? fixed using EDCA queue for test... We doubt Queue1 has problem. 2006-09-26 Jan
1383 //pTxD->QSEL= FIFO_EDCA;
1384 if (pAd->bGenOneHCCA == TRUE)
1385 pTxD->QSEL= FIFO_HCCA;
1386 pTxD->DMADONE = 0;
1387}
1388
1389
1390// should be called only when -
1391// 1. MEADIA_CONNECTED
1392// 2. AGGREGATION_IN_USED
1393// 3. Fragmentation not in used
1394// 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
1395BOOLEAN TxFrameIsAggregatible(
1396 IN PRTMP_ADAPTER pAd,
1397 IN PUCHAR pPrevAddr1,
1398 IN PUCHAR p8023hdr)
1399{
1400
1401 // can't aggregate EAPOL (802.1x) frame
1402 if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
1403 return FALSE;
1404
1405 // can't aggregate multicast/broadcast frame
1406 if (p8023hdr[0] & 0x01)
1407 return FALSE;
1408
1409 if (INFRA_ON(pAd)) // must be unicast to AP
1410 return TRUE;
1411 else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
1412 return TRUE;
1413 else
1414 return FALSE;
1415}
1416
1417
1418/*
1419 ========================================================================
1420
1421 Routine Description:
1422 Check the MSDU Aggregation policy
1423 1.HT aggregation is A-MSDU
1424 2.legaacy rate aggregation is software aggregation by Ralink.
1425
1426 Arguments:
1427
1428 Return Value:
1429
1430 Note:
1431
1432 ========================================================================
1433*/
1434BOOLEAN PeerIsAggreOn(
1435 IN PRTMP_ADAPTER pAd,
1436 IN ULONG TxRate,
1437 IN PMAC_TABLE_ENTRY pMacEntry)
1438{
1439 ULONG AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
1440
1441 if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
1442 {
1443#ifdef DOT11_N_SUPPORT
1444 if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
1445 {
1446 return TRUE;
1447 }
1448#endif // DOT11_N_SUPPORT //
1449
1450#ifdef AGGREGATION_SUPPORT
1451 if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
1452 { // legacy Ralink Aggregation support
1453 return TRUE;
1454 }
1455#endif // AGGREGATION_SUPPORT //
1456 }
1457
1458 return FALSE;
1459
1460}
1461
1462/*
1463 ========================================================================
1464
1465 Routine Description:
1466 Check and fine the packet waiting in SW queue with highest priority
1467
1468 Arguments:
1469 pAd Pointer to our adapter
1470
1471 Return Value:
1472 pQueue Pointer to Waiting Queue
1473
1474 IRQL = DISPATCH_LEVEL
1475
1476 Note:
1477
1478 ========================================================================
1479*/
1480PQUEUE_HEADER RTMPCheckTxSwQueue(
1481 IN PRTMP_ADAPTER pAd,
1482 OUT PUCHAR pQueIdx)
1483{
1484
1485 ULONG Number;
1486 // 2004-11-15 to be removed. test aggregation only
1487// if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
1488// return NULL;
1489
1490 Number = pAd->TxSwQueue[QID_AC_BK].Number
1491 + pAd->TxSwQueue[QID_AC_BE].Number
1492 + pAd->TxSwQueue[QID_AC_VI].Number
1493 + pAd->TxSwQueue[QID_AC_VO].Number
1494 + pAd->TxSwQueue[QID_HCCA].Number;
1495
1496 if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
1497 {
1498 *pQueIdx = QID_AC_VO;
1499 return (&pAd->TxSwQueue[QID_AC_VO]);
1500 }
1501 else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
1502 {
1503 *pQueIdx = QID_AC_VI;
1504 return (&pAd->TxSwQueue[QID_AC_VI]);
1505 }
1506 else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
1507 {
1508 *pQueIdx = QID_AC_BE;
1509 return (&pAd->TxSwQueue[QID_AC_BE]);
1510 }
1511 else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
1512 {
1513 *pQueIdx = QID_AC_BK;
1514 return (&pAd->TxSwQueue[QID_AC_BK]);
1515 }
1516 else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
1517 {
1518 *pQueIdx = QID_HCCA;
1519 return (&pAd->TxSwQueue[QID_HCCA]);
1520 }
1521
1522 // No packet pending in Tx Sw queue
1523 *pQueIdx = QID_AC_BK;
1524
1525 return (NULL);
1526}
1527
1528
1529
1530/*
1531 ========================================================================
1532
1533 Routine Description:
1534 Suspend MSDU transmission
1535
1536 Arguments:
1537 pAd Pointer to our adapter
1538
1539 Return Value:
1540 None
1541
1542 Note:
1543
1544 ========================================================================
1545*/
1546VOID RTMPSuspendMsduTransmission(
1547 IN PRTMP_ADAPTER pAd)
1548{
1549 DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
1550
1551
1552 //
1553 // Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
1554 // use Lowbound as R66 value on ScanNextChannel(...)
1555 //
1556 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1557
1558 // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
1559 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
1560 RTMPSetAGCInitValue(pAd, BW_20);
1561
1562 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1563 //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings
1564}
1565
1566
1567/*
1568 ========================================================================
1569
1570 Routine Description:
1571 Resume MSDU transmission
1572
1573 Arguments:
1574 pAd Pointer to our adapter
1575
1576 Return Value:
1577 None
1578
1579 IRQL = DISPATCH_LEVEL
1580
1581 Note:
1582
1583 ========================================================================
1584*/
1585VOID RTMPResumeMsduTransmission(
1586 IN PRTMP_ADAPTER pAd)
1587{
1588// UCHAR IrqState;
1589
1590 DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
1591
1592
1593 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
1594
1595 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1596// sample, for IRQ LOCK to SEM LOCK
1597// IrqState = pAd->irq_disabled;
1598// if (IrqState)
1599// RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1600// else
1601 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1602}
1603
1604
1605UINT deaggregate_AMSDU_announce(
1606 IN PRTMP_ADAPTER pAd,
1607 PNDIS_PACKET pPacket,
1608 IN PUCHAR pData,
1609 IN ULONG DataSize)
1610{
1611 USHORT PayloadSize;
1612 USHORT SubFrameSize;
1613 PHEADER_802_3 pAMSDUsubheader;
1614 UINT nMSDU;
1615 UCHAR Header802_3[14];
1616
1617 PUCHAR pPayload, pDA, pSA, pRemovedLLCSNAP;
1618 PNDIS_PACKET pClonePacket;
1619
1620
1621
1622 nMSDU = 0;
1623
1624 while (DataSize > LENGTH_802_3)
1625 {
1626
1627 nMSDU++;
1628
1629 //hex_dump("subheader", pData, 64);
1630 pAMSDUsubheader = (PHEADER_802_3)pData;
1631 //pData += LENGTH_802_3;
1632 PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
1633 SubFrameSize = PayloadSize + LENGTH_802_3;
1634
1635
1636 if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
1637 {
1638 break;
1639 }
1640
1641 //printk("%d subframe: Size = %d\n", nMSDU, PayloadSize);
1642
1643 pPayload = pData + LENGTH_802_3;
1644 pDA = pData;
1645 pSA = pData + MAC_ADDR_LEN;
1646
1647 // convert to 802.3 header
1648 CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
1649
1650#ifdef CONFIG_STA_SUPPORT
1651 if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
1652 {
1653 // avoid local heap overflow, use dyanamic allocation
1654 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
1655 memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
1656 Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
1657 WpaEAPOLKeyAction(pAd, Elem);
1658 kfree(Elem);
1659 }
1660#endif // CONFIG_STA_SUPPORT //
1661
1662#ifdef CONFIG_STA_SUPPORT
1663 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1664 {
1665 if (pRemovedLLCSNAP)
1666 {
1667 pPayload -= LENGTH_802_3;
1668 PayloadSize += LENGTH_802_3;
1669 NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
1670 }
1671 }
1672#endif // CONFIG_STA_SUPPORT //
1673
1674 pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
1675 if (pClonePacket)
1676 {
1677#ifdef CONFIG_STA_SUPPORT
1678 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1679 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
1680#endif // CONFIG_STA_SUPPORT //
1681 }
1682
1683
1684 // A-MSDU has padding to multiple of 4 including subframe header.
1685 // align SubFrameSize up to multiple of 4
1686 SubFrameSize = (SubFrameSize+3)&(~0x3);
1687
1688
1689 if (SubFrameSize > 1528 || SubFrameSize < 32)
1690 {
1691 break;
1692 }
1693
1694 if (DataSize > SubFrameSize)
1695 {
1696 pData += SubFrameSize;
1697 DataSize -= SubFrameSize;
1698 }
1699 else
1700 {
1701 // end of A-MSDU
1702 DataSize = 0;
1703 }
1704 }
1705
1706 // finally release original rx packet
1707 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1708
1709 return nMSDU;
1710}
1711
1712
1713UINT BA_Reorder_AMSDU_Annnounce(
1714 IN PRTMP_ADAPTER pAd,
1715 IN PNDIS_PACKET pPacket)
1716{
1717 PUCHAR pData;
1718 USHORT DataSize;
1719 UINT nMSDU = 0;
1720
1721 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
1722 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
1723
1724 nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
1725
1726 return nMSDU;
1727}
1728
1729
1730/*
1731 ==========================================================================
1732 Description:
1733 Look up the MAC address in the MAC table. Return NULL if not found.
1734 Return:
1735 pEntry - pointer to the MAC entry; NULL is not found
1736 ==========================================================================
1737*/
1738MAC_TABLE_ENTRY *MacTableLookup(
1739 IN PRTMP_ADAPTER pAd,
1740 PUCHAR pAddr)
1741{
1742 ULONG HashIdx;
1743 MAC_TABLE_ENTRY *pEntry = NULL;
1744
1745 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1746 pEntry = pAd->MacTab.Hash[HashIdx];
1747
1748 while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
1749 {
1750 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
1751 {
1752 break;
1753 }
1754 else
1755 pEntry = pEntry->pNext;
1756 }
1757
1758 return pEntry;
1759}
1760
1761MAC_TABLE_ENTRY *MacTableInsertEntry(
1762 IN PRTMP_ADAPTER pAd,
1763 IN PUCHAR pAddr,
1764 IN UCHAR apidx,
1765 IN BOOLEAN CleanAll)
1766{
1767 UCHAR HashIdx;
1768 int i, FirstWcid;
1769 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1770
1771 // if FULL, return
1772 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1773 return NULL;
1774
1775 FirstWcid = 1;
1776#ifdef CONFIG_STA_SUPPORT
1777 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1778 if (pAd->StaCfg.BssType == BSS_INFRA)
1779 FirstWcid = 2;
1780#endif // CONFIG_STA_SUPPORT //
1781
1782 // allocate one MAC entry
1783 NdisAcquireSpinLock(&pAd->MacTabLock);
1784 for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) // skip entry#0 so that "entry index == AID" for fast lookup
1785 {
1786 // pick up the first available vacancy
1787 if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
1788 (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
1789 (pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
1790 (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
1791#ifdef CONFIG_STA_SUPPORT
1792#ifdef QOS_DLS_SUPPORT
1793 && (pAd->MacTab.Content[i].ValidAsDls == FALSE)
1794#endif // QOS_DLS_SUPPORT //
1795#endif // CONFIG_STA_SUPPORT //
1796 )
1797 {
1798 pEntry = &pAd->MacTab.Content[i];
1799 if (CleanAll == TRUE)
1800 {
1801 pEntry->MaxSupportedRate = RATE_11;
1802 pEntry->CurrTxRate = RATE_11;
1803 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
1804 pEntry->PairwiseKey.KeyLen = 0;
1805 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1806 }
1807#ifdef CONFIG_STA_SUPPORT
1808#ifdef QOS_DLS_SUPPORT
1809 if (apidx >= MIN_NET_DEVICE_FOR_DLS)
1810 {
1811 pEntry->ValidAsCLI = FALSE;
1812 pEntry->ValidAsWDS = FALSE;
1813 pEntry->ValidAsApCli = FALSE;
1814 pEntry->ValidAsMesh = FALSE;
1815 pEntry->ValidAsDls = TRUE;
1816 pEntry->isCached = FALSE;
1817 }
1818 else
1819#endif // QOS_DLS_SUPPORT //
1820#endif // CONFIG_STA_SUPPORT //
1821 {
1822
1823#ifdef CONFIG_STA_SUPPORT
1824 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1825 {
1826 pEntry->ValidAsCLI = TRUE;
1827 pEntry->ValidAsWDS = FALSE;
1828 pEntry->ValidAsApCli = FALSE;
1829 pEntry->ValidAsMesh = FALSE;
1830 pEntry->ValidAsDls = FALSE;
1831 }
1832#endif // CONFIG_STA_SUPPORT //
1833 }
1834
1835 pEntry->bIAmBadAtheros = FALSE;
1836 pEntry->pAd = pAd;
1837 pEntry->CMTimerRunning = FALSE;
1838 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
1839 pEntry->RSNIE_Len = 0;
1840 NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
1841 pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
1842
1843 if (pEntry->ValidAsMesh)
1844 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
1845 else if (pEntry->ValidAsApCli)
1846 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
1847 else if (pEntry->ValidAsWDS)
1848 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
1849#ifdef CONFIG_STA_SUPPORT
1850#ifdef QOS_DLS_SUPPORT
1851 else if (pEntry->ValidAsDls)
1852 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS);
1853#endif // QOS_DLS_SUPPORT //
1854#endif // CONFIG_STA_SUPPORT //
1855 else
1856 pEntry->apidx = apidx;
1857
1858 {
1859
1860#ifdef CONFIG_STA_SUPPORT
1861 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1862 {
1863 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1864 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1865 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1866 }
1867#endif // CONFIG_STA_SUPPORT //
1868 }
1869
1870 pEntry->GTKState = REKEY_NEGOTIATING;
1871 pEntry->PairwiseKey.KeyLen = 0;
1872 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
1873#ifdef CONFIG_STA_SUPPORT
1874#ifdef QOS_DLS_SUPPORT
1875 if (pEntry->ValidAsDls == TRUE)
1876 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1877#endif //QOS_DLS_SUPPORT
1878#endif // CONFIG_STA_SUPPORT //
1879 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1880 pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
1881 COPY_MAC_ADDR(pEntry->Addr, pAddr);
1882 pEntry->Sst = SST_NOT_AUTH;
1883 pEntry->AuthState = AS_NOT_AUTH;
1884 pEntry->Aid = (USHORT)i; //0;
1885 pEntry->CapabilityInfo = 0;
1886 pEntry->PsMode = PWR_ACTIVE;
1887 pEntry->PsQIdleCount = 0;
1888 pEntry->NoDataIdleCount = 0;
1889 pEntry->ContinueTxFailCnt = 0;
1890 InitializeQueueHeader(&pEntry->PsQueue);
1891
1892
1893 pAd->MacTab.Size ++;
1894 // Add this entry into ASIC RX WCID search table
1895 RT28XX_STA_ENTRY_ADD(pAd, pEntry);
1896
1897 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
1898 break;
1899 }
1900 }
1901
1902 // add this MAC entry into HASH table
1903 if (pEntry)
1904 {
1905 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1906 if (pAd->MacTab.Hash[HashIdx] == NULL)
1907 {
1908 pAd->MacTab.Hash[HashIdx] = pEntry;
1909 }
1910 else
1911 {
1912 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1913 while (pCurrEntry->pNext != NULL)
1914 pCurrEntry = pCurrEntry->pNext;
1915 pCurrEntry->pNext = pEntry;
1916 }
1917 }
1918
1919 NdisReleaseSpinLock(&pAd->MacTabLock);
1920 return pEntry;
1921}
1922
1923/*
1924 ==========================================================================
1925 Description:
1926 Delete a specified client from MAC table
1927 ==========================================================================
1928 */
1929BOOLEAN MacTableDeleteEntry(
1930 IN PRTMP_ADAPTER pAd,
1931 IN USHORT wcid,
1932 IN PUCHAR pAddr)
1933{
1934 USHORT HashIdx;
1935 MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
1936 BOOLEAN Cancelled;
1937 //USHORT offset; // unused variable
1938 //UCHAR j; // unused variable
1939
1940 if (wcid >= MAX_LEN_OF_MAC_TABLE)
1941 return FALSE;
1942
1943 NdisAcquireSpinLock(&pAd->MacTabLock);
1944
1945 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
1946 //pEntry = pAd->MacTab.Hash[HashIdx];
1947 pEntry = &pAd->MacTab.Content[wcid];
1948
1949 if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
1950#ifdef CONFIG_STA_SUPPORT
1951#ifdef QOS_DLS_SUPPORT
1952 || pEntry->ValidAsDls
1953#endif // QOS_DLS_SUPPORT //
1954#endif // CONFIG_STA_SUPPORT //
1955 ))
1956 {
1957 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
1958 {
1959
1960 // Delete this entry from ASIC on-chip WCID Table
1961 RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
1962
1963#ifdef DOT11_N_SUPPORT
1964 // free resources of BA
1965 BASessionTearDownALL(pAd, pEntry->Aid);
1966#endif // DOT11_N_SUPPORT //
1967
1968
1969 pPrevEntry = NULL;
1970 pProbeEntry = pAd->MacTab.Hash[HashIdx];
1971 ASSERT(pProbeEntry);
1972
1973 // update Hash list
1974 do
1975 {
1976 if (pProbeEntry == pEntry)
1977 {
1978 if (pPrevEntry == NULL)
1979 {
1980 pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
1981 }
1982 else
1983 {
1984 pPrevEntry->pNext = pEntry->pNext;
1985 }
1986 break;
1987 }
1988
1989 pPrevEntry = pProbeEntry;
1990 pProbeEntry = pProbeEntry->pNext;
1991 } while (pProbeEntry);
1992
1993 // not found !!!
1994 ASSERT(pProbeEntry != NULL);
1995
1996 RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
1997
1998
1999 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
2000 {
2001 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
2002 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
2003 }
2004
2005
2006 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
2007 pAd->MacTab.Size --;
2008 DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
2009 }
2010 else
2011 {
2012 printk("\n%s: Impossible Wcid = %d !!!!!\n", __FUNCTION__, wcid);
2013 }
2014 }
2015
2016 NdisReleaseSpinLock(&pAd->MacTabLock);
2017
2018 //Reset operating mode when no Sta.
2019 if (pAd->MacTab.Size == 0)
2020 {
2021#ifdef DOT11_N_SUPPORT
2022 pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
2023#endif // DOT11_N_SUPPORT //
2024 AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
2025 }
2026
2027 return TRUE;
2028}
2029
2030
2031/*
2032 ==========================================================================
2033 Description:
2034 This routine reset the entire MAC table. All packets pending in
2035 the power-saving queues are freed here.
2036 ==========================================================================
2037 */
2038VOID MacTableReset(
2039 IN PRTMP_ADAPTER pAd)
2040{
2041 int i;
2042
2043 DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
2044 //NdisAcquireSpinLock(&pAd->MacTabLock);
2045
2046 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2047 {
2048 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2049 {
2050
2051#ifdef DOT11_N_SUPPORT
2052 // free resources of BA
2053 BASessionTearDownALL(pAd, i);
2054#endif // DOT11_N_SUPPORT //
2055
2056 pAd->MacTab.Content[i].ValidAsCLI = FALSE;
2057
2058
2059
2060#ifdef RT2870
2061 NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
2062 RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
2063#endif // RT2870 //
2064
2065 //AsicDelWcidTab(pAd, i);
2066 }
2067 }
2068
2069 return;
2070}
2071
2072/*
2073 ==========================================================================
2074 Description:
2075
2076 IRQL = DISPATCH_LEVEL
2077
2078 ==========================================================================
2079*/
2080VOID AssocParmFill(
2081 IN PRTMP_ADAPTER pAd,
2082 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
2083 IN PUCHAR pAddr,
2084 IN USHORT CapabilityInfo,
2085 IN ULONG Timeout,
2086 IN USHORT ListenIntv)
2087{
2088 COPY_MAC_ADDR(AssocReq->Addr, pAddr);
2089 // Add mask to support 802.11b mode only
2090 AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
2091 AssocReq->Timeout = Timeout;
2092 AssocReq->ListenIntv = ListenIntv;
2093}
2094
2095
2096/*
2097 ==========================================================================
2098 Description:
2099
2100 IRQL = DISPATCH_LEVEL
2101
2102 ==========================================================================
2103*/
2104VOID DisassocParmFill(
2105 IN PRTMP_ADAPTER pAd,
2106 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
2107 IN PUCHAR pAddr,
2108 IN USHORT Reason)
2109{
2110 COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
2111 DisassocReq->Reason = Reason;
2112}
2113
2114
2115/*
2116 ========================================================================
2117
2118 Routine Description:
2119 Check the out going frame, if this is an DHCP or ARP datagram
2120 will be duplicate another frame at low data rate transmit.
2121
2122 Arguments:
2123 pAd Pointer to our adapter
2124 pPacket Pointer to outgoing Ndis frame
2125
2126 Return Value:
2127 TRUE To be duplicate at Low data rate transmit. (1mb)
2128 FALSE Do nothing.
2129
2130 IRQL = DISPATCH_LEVEL
2131
2132 Note:
2133
2134 MAC header + IP Header + UDP Header
2135 14 Bytes 20 Bytes
2136
2137 UDP Header
2138 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
2139 Source Port
2140 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
2141 Destination Port
2142
2143 port 0x43 means Bootstrap Protocol, server.
2144 Port 0x44 means Bootstrap Protocol, client.
2145
2146 ========================================================================
2147*/
2148
2149BOOLEAN RTMPCheckDHCPFrame(
2150 IN PRTMP_ADAPTER pAd,
2151 IN PNDIS_PACKET pPacket)
2152{
2153 PACKET_INFO PacketInfo;
2154 ULONG NumberOfBytesRead = 0;
2155 ULONG CurrentOffset = 0;
2156 PVOID pVirtualAddress = NULL;
2157 UINT NdisBufferLength;
2158 PUCHAR pSrc;
2159 USHORT Protocol;
2160 UCHAR ByteOffset36 = 0;
2161 UCHAR ByteOffset38 = 0;
2162 BOOLEAN ReadFirstParm = TRUE;
2163
2164 RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
2165
2166 NumberOfBytesRead += NdisBufferLength;
2167 pSrc = (PUCHAR) pVirtualAddress;
2168 Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
2169
2170 //
2171 // Check DHCP & BOOTP protocol
2172 //
2173 while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
2174 {
2175 if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
2176 {
2177 CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
2178 ByteOffset36 = *(pSrc + CurrentOffset);
2179 ReadFirstParm = FALSE;
2180 }
2181
2182 if (NumberOfBytesRead >= 37)
2183 {
2184 CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
2185 ByteOffset38 = *(pSrc + CurrentOffset);
2186 //End of Read
2187 break;
2188 }
2189 return FALSE;
2190 }
2191
2192 // Check for DHCP & BOOTP protocol
2193 if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
2194 {
2195 //
2196 // 2054 (hex 0806) for ARP datagrams
2197 // if this packet is not ARP datagrams, then do nothing
2198 // ARP datagrams will also be duplicate at 1mb broadcast frames
2199 //
2200 if (Protocol != 0x0806 )
2201 return FALSE;
2202 }
2203
2204 return TRUE;
2205}
2206
2207
2208BOOLEAN RTMPCheckEtherType(
2209 IN PRTMP_ADAPTER pAd,
2210 IN PNDIS_PACKET pPacket)
2211{
2212 USHORT TypeLen;
2213 UCHAR Byte0, Byte1;
2214 PUCHAR pSrcBuf;
2215 UINT32 pktLen;
2216 UINT16 srcPort, dstPort;
2217 BOOLEAN status = TRUE;
2218
2219
2220 pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
2221 pktLen = GET_OS_PKT_LEN(pPacket);
2222
2223 ASSERT(pSrcBuf);
2224
2225 RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
2226
2227 // get Ethernet protocol field
2228 TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
2229
2230 pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header.
2231
2232 if (TypeLen <= 1500)
2233 { // 802.3, 802.3 LLC
2234 /*
2235 DestMAC(6) + SrcMAC(6) + Lenght(2) +
2236 DSAP(1) + SSAP(1) + Control(1) +
2237 if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
2238 => + SNAP (5, OriginationID(3) + etherType(2))
2239 */
2240 if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
2241 {
2242 Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
2243 RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
2244 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2245 pSrcBuf += 8; // Skip this LLC/SNAP header
2246 }
2247 else
2248 {
2249 //It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
2250 }
2251 }
2252
2253 // If it's a VLAN packet, get the real Type/Length field.
2254 if (TypeLen == 0x8100)
2255 {
2256 /* 0x8100 means VLAN packets */
2257
2258 /* Dest. MAC Address (6-bytes) +
2259 Source MAC Address (6-bytes) +
2260 Length/Type = 802.1Q Tag Type (2-byte) +
2261 Tag Control Information (2-bytes) +
2262 Length / Type (2-bytes) +
2263 data payload (0-n bytes) +
2264 Pad (0-p bytes) +
2265 Frame Check Sequence (4-bytes) */
2266
2267 RTMP_SET_PACKET_VLAN(pPacket, 1);
2268 Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
2269 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
2270
2271 pSrcBuf += 4; // Skip the VLAN Header.
2272 }
2273
2274 switch (TypeLen)
2275 {
2276 case 0x0800:
2277 {
2278 ASSERT((pktLen > 34));
2279 if (*(pSrcBuf + 9) == 0x11)
2280 { // udp packet
2281 ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header
2282
2283 pSrcBuf += 20; // Skip the IP header
2284 srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
2285 dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
2286
2287 if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
2288 { //It's a BOOTP/DHCP packet
2289 RTMP_SET_PACKET_DHCP(pPacket, 1);
2290 }
2291 }
2292 }
2293 break;
2294 case 0x0806:
2295 {
2296 //ARP Packet.
2297 RTMP_SET_PACKET_DHCP(pPacket, 1);
2298 }
2299 break;
2300 case 0x888e:
2301 {
2302 // EAPOL Packet.
2303 RTMP_SET_PACKET_EAPOL(pPacket, 1);
2304 }
2305 break;
2306 default:
2307 status = FALSE;
2308 break;
2309 }
2310
2311 return status;
2312
2313}
2314
2315
2316
2317VOID Update_Rssi_Sample(
2318 IN PRTMP_ADAPTER pAd,
2319 IN RSSI_SAMPLE *pRssi,
2320 IN PRXWI_STRUC pRxWI)
2321 {
2322 CHAR rssi0 = pRxWI->RSSI0;
2323 CHAR rssi1 = pRxWI->RSSI1;
2324 CHAR rssi2 = pRxWI->RSSI2;
2325
2326 if (rssi0 != 0)
2327 {
2328 pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
2329 pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
2330 pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
2331 }
2332
2333 if (rssi1 != 0)
2334 {
2335 pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
2336 pRssi->AvgRssi1X8 = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
2337 pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
2338 }
2339
2340 if (rssi2 != 0)
2341 {
2342 pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
2343 pRssi->AvgRssi2X8 = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
2344 pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
2345 }
2346}
2347
2348
2349
2350// Normal legacy Rx packet indication
2351VOID Indicate_Legacy_Packet(
2352 IN PRTMP_ADAPTER pAd,
2353 IN RX_BLK *pRxBlk,
2354 IN UCHAR FromWhichBSSID)
2355{
2356 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2357 UCHAR Header802_3[LENGTH_802_3];
2358
2359 // 1. get 802.3 Header
2360 // 2. remove LLC
2361 // a. pointer pRxBlk->pData to payload
2362 // b. modify pRxBlk->DataSize
2363#ifdef CONFIG_STA_SUPPORT
2364 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2365 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2366#endif // CONFIG_STA_SUPPORT //
2367
2368 if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
2369 {
2370#if 0 // sample take off, for multiple card design
2371 static int err_size;
2372
2373 err_size++;
2374 if (err_size > 20)
2375 {
2376 printk("Legacy DataSize = %d\n", pRxBlk->DataSize);
2377 hex_dump("802.3 Header", Header802_3, LENGTH_802_3);
2378 hex_dump("Payload", pRxBlk->pData, 64);
2379 err_size = 0;
2380 }
2381#endif
2382
2383 // release packet
2384 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2385 return;
2386 }
2387
2388
2389 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
2390
2391#ifdef RT2870
2392#ifdef DOT11_N_SUPPORT
2393 if (pAd->CommonCfg.bDisableReordering == 0)
2394 {
2395 PBA_REC_ENTRY pBAEntry;
2396 ULONG Now32;
2397 UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
2398 UCHAR TID = pRxBlk->pRxWI->TID;
2399 USHORT Idx;
2400
2401#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
2402
2403 if (Wcid < MAX_LEN_OF_MAC_TABLE)
2404 {
2405 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
2406 if (Idx != 0)
2407 {
2408 pBAEntry = &pAd->BATable.BARecEntry[Idx];
2409 // update last rx time
2410 NdisGetSystemUpTime(&Now32);
2411 if ((pBAEntry->list.qlen > 0) &&
2412 RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
2413 )
2414 {
2415 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);
2416 hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
2417 ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
2418 }
2419 }
2420 }
2421 }
2422#endif // DOT11_N_SUPPORT //
2423#endif // RT2870 //
2424
2425 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2426
2427 //
2428 // pass this 802.3 packet to upper layer or forward this packet to WM directly
2429 //
2430#ifdef CONFIG_STA_SUPPORT
2431 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2432 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
2433#endif // CONFIG_STA_SUPPORT //
2434
2435}
2436
2437
2438// Normal, AMPDU or AMSDU
2439VOID CmmRxnonRalinkFrameIndicate(
2440 IN PRTMP_ADAPTER pAd,
2441 IN RX_BLK *pRxBlk,
2442 IN UCHAR FromWhichBSSID)
2443{
2444#ifdef DOT11_N_SUPPORT
2445 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
2446 {
2447 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2448 }
2449 else
2450#endif // DOT11_N_SUPPORT //
2451 {
2452#ifdef DOT11_N_SUPPORT
2453 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
2454 {
2455 // handle A-MSDU
2456 Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
2457 }
2458 else
2459#endif // DOT11_N_SUPPORT //
2460 {
2461 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
2462 }
2463 }
2464}
2465
2466
2467VOID CmmRxRalinkFrameIndicate(
2468 IN PRTMP_ADAPTER pAd,
2469 IN MAC_TABLE_ENTRY *pEntry,
2470 IN RX_BLK *pRxBlk,
2471 IN UCHAR FromWhichBSSID)
2472{
2473 UCHAR Header802_3[LENGTH_802_3];
2474 UINT16 Msdu2Size;
2475 UINT16 Payload1Size, Payload2Size;
2476 PUCHAR pData2;
2477 PNDIS_PACKET pPacket2 = NULL;
2478
2479
2480
2481 Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
2482
2483 if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
2484 {
2485 /* skip two byte MSDU2 len */
2486 pRxBlk->pData += 2;
2487 pRxBlk->DataSize -= 2;
2488 }
2489 else
2490 {
2491 // release packet
2492 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2493 return;
2494 }
2495
2496 // get 802.3 Header and remove LLC
2497#ifdef CONFIG_STA_SUPPORT
2498 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2499 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
2500#endif // CONFIG_STA_SUPPORT //
2501
2502
2503 ASSERT(pRxBlk->pRxPacket);
2504
2505 // Ralink Aggregation frame
2506 pAd->RalinkCounters.OneSecRxAggregationCount ++;
2507 Payload1Size = pRxBlk->DataSize - Msdu2Size;
2508 Payload2Size = Msdu2Size - LENGTH_802_3;
2509
2510 pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
2511#ifdef CONFIG_STA_SUPPORT
2512 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2513 pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
2514#endif // CONFIG_STA_SUPPORT //
2515
2516 if (!pPacket2)
2517 {
2518 // release packet
2519 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2520 return;
2521 }
2522
2523 // update payload size of 1st packet
2524 pRxBlk->DataSize = Payload1Size;
2525 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
2526
2527#ifdef CONFIG_STA_SUPPORT
2528 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2529 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
2530#endif // CONFIG_STA_SUPPORT //
2531
2532 if (pPacket2)
2533 {
2534#ifdef CONFIG_STA_SUPPORT
2535 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2536 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
2537#endif // CONFIG_STA_SUPPORT //
2538 }
2539}
2540
2541
2542#define RESET_FRAGFRAME(_fragFrame) \
2543 { \
2544 _fragFrame.RxSize = 0; \
2545 _fragFrame.Sequence = 0; \
2546 _fragFrame.LastFrag = 0; \
2547 _fragFrame.Flags = 0; \
2548 }
2549
2550
2551PNDIS_PACKET RTMPDeFragmentDataFrame(
2552 IN PRTMP_ADAPTER pAd,
2553 IN RX_BLK *pRxBlk)
2554{
2555 PHEADER_802_11 pHeader = pRxBlk->pHeader;
2556 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
2557 UCHAR *pData = pRxBlk->pData;
2558 USHORT DataSize = pRxBlk->DataSize;
2559 PNDIS_PACKET pRetPacket = NULL;
2560 UCHAR *pFragBuffer = NULL;
2561 BOOLEAN bReassDone = FALSE;
2562 UCHAR HeaderRoom = 0;
2563
2564
2565 ASSERT(pHeader);
2566
2567 HeaderRoom = pData - (UCHAR *)pHeader;
2568
2569 // Re-assemble the fragmented packets
2570 if (pHeader->Frag == 0) // Frag. Number is 0 : First frag or only one pkt
2571 {
2572 // the first pkt of fragment, record it.
2573 if (pHeader->FC.MoreFrag)
2574 {
2575 ASSERT(pAd->FragFrame.pFragPacket);
2576 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2577 pAd->FragFrame.RxSize = DataSize + HeaderRoom;
2578 NdisMoveMemory(pFragBuffer, pHeader, pAd->FragFrame.RxSize);
2579 pAd->FragFrame.Sequence = pHeader->Sequence;
2580 pAd->FragFrame.LastFrag = pHeader->Frag; // Should be 0
2581 ASSERT(pAd->FragFrame.LastFrag == 0);
2582 goto done; // end of processing this frame
2583 }
2584 }
2585 else //Middle & End of fragment
2586 {
2587 if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
2588 (pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
2589 {
2590 // Fragment is not the same sequence or out of fragment number order
2591 // Reset Fragment control blk
2592 RESET_FRAGFRAME(pAd->FragFrame);
2593 DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
2594 goto done; // give up this frame
2595 }
2596 else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
2597 {
2598 // Fragment frame is too large, it exeeds the maximum frame size.
2599 // Reset Fragment control blk
2600 RESET_FRAGFRAME(pAd->FragFrame);
2601 DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
2602 goto done; // give up this frame
2603 }
2604
2605 //
2606 // Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
2607 // In this case, we will dropt it.
2608 //
2609 if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
2610 {
2611 DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
2612 goto done; // give up this frame
2613 }
2614
2615 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
2616
2617 // concatenate this fragment into the re-assembly buffer
2618 NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
2619 pAd->FragFrame.RxSize += DataSize;
2620 pAd->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
2621
2622 // Last fragment
2623 if (pHeader->FC.MoreFrag == FALSE)
2624 {
2625 bReassDone = TRUE;
2626 }
2627 }
2628
2629done:
2630 // always release rx fragmented packet
2631 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
2632
2633 // return defragmented packet if packet is reassembled completely
2634 // otherwise return NULL
2635 if (bReassDone)
2636 {
2637 PNDIS_PACKET pNewFragPacket;
2638
2639 // allocate a new packet buffer for fragment
2640 pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
2641 if (pNewFragPacket)
2642 {
2643 // update RxBlk
2644 pRetPacket = pAd->FragFrame.pFragPacket;
2645 pAd->FragFrame.pFragPacket = pNewFragPacket;
2646 pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
2647 pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
2648 pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
2649 pRxBlk->pRxPacket = pRetPacket;
2650 }
2651 else
2652 {
2653 RESET_FRAGFRAME(pAd->FragFrame);
2654 }
2655 }
2656
2657 return pRetPacket;
2658}
2659
2660
2661VOID Indicate_AMSDU_Packet(
2662 IN PRTMP_ADAPTER pAd,
2663 IN RX_BLK *pRxBlk,
2664 IN UCHAR FromWhichBSSID)
2665{
2666 UINT nMSDU;
2667
2668 update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
2669 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
2670 nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
2671}
2672
2673VOID Indicate_EAPOL_Packet(
2674 IN PRTMP_ADAPTER pAd,
2675 IN RX_BLK *pRxBlk,
2676 IN UCHAR FromWhichBSSID)
2677{
2678 MAC_TABLE_ENTRY *pEntry = NULL;
2679
2680
2681#ifdef CONFIG_STA_SUPPORT
2682 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2683 {
2684 pEntry = &pAd->MacTab.Content[BSSID_WCID];
2685 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
2686 return;
2687 }
2688#endif // CONFIG_STA_SUPPORT //
2689
2690 if (pEntry == NULL)
2691 {
2692 DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
2693 // release packet
2694 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
2695 return;
2696 }
2697}
2698
2699#define BCN_TBTT_OFFSET 64 //defer 64 us
2700VOID ReSyncBeaconTime(
2701 IN PRTMP_ADAPTER pAd)
2702{
2703
2704 UINT32 Offset;
2705
2706
2707 Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
2708
2709 pAd->TbttTickCount++;
2710
2711 //
2712 // The updated BeaconInterval Value will affect Beacon Interval after two TBTT
2713 // beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
2714 //
2715 if (Offset == (BCN_TBTT_OFFSET-2))
2716 {
2717 BCN_TIME_CFG_STRUC csr;
2718 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2719 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ; // ASIC register in units of 1/16 TU = 64us
2720 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
2721 }
2722 else
2723 {
2724 if (Offset == (BCN_TBTT_OFFSET-1))
2725 {
2726 BCN_TIME_CFG_STRUC csr;
2727
2728 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
2729 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
2730 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
2731 }
2732 }
2733}
2734
diff --git a/drivers/staging/rt2870/common/cmm_data_2870.c b/drivers/staging/rt2870/common/cmm_data_2870.c
new file mode 100644
index 00000000000..f77000f336a
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_data_2870.c
@@ -0,0 +1,963 @@
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 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
299
300 if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)
301 {
302 pTxInfo->SwUseLastRound = 1;
303 bTxQLastRound = TRUE;
304 }
305 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
306#ifdef RT_BIG_ENDIAN
307 RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
308#endif // RT_BIG_ENDIAN //
309 pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
310
311 // We unlock it here to prevent the first 8 bytes maybe over-writed issue.
312 // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext.
313 // 2. An interrupt break our routine and handle bulk-out complete.
314 // 3. In the bulk-out compllete, it need to do another bulk-out,
315 // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
316 // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
317 // 4. Interrupt complete.
318 // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
319 // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
320 // and the packet will wrong.
321 pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
322 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
323
324 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
325 pWirelessPacket += pTxBlk->SrcBufLen;
326 NdisZeroMemory(pWirelessPacket, padding + 8);
327
328 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
329
330 pHTTXContext->CurWritePosition += pTxBlk->Priv;
331 if (bTxQLastRound)
332 pHTTXContext->CurWritePosition = 8;
333 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
334
335 pHTTXContext->bCurWriting = FALSE;
336 }
337
338
339 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
340
341
342 // succeed and release the skb buffer
343 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
344
345 return(Status);
346
347}
348
349
350USHORT RtmpUSB_WriteMultiTxResource(
351 IN PRTMP_ADAPTER pAd,
352 IN TX_BLK *pTxBlk,
353 IN UCHAR frameNum,
354 OUT USHORT *FreeNumber)
355{
356 HT_TX_CONTEXT *pHTTXContext;
357 USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
358 UINT32 fillOffset;
359 TXINFO_STRUC *pTxInfo;
360 TXWI_STRUC *pTxWI;
361 PUCHAR pWirelessPacket = NULL;
362 UCHAR QueIdx;
363 NDIS_STATUS Status;
364 unsigned long IrqFlags;
365 //UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
366
367 //
368 // get Tx Ring Resource & Dma Buffer address
369 //
370 QueIdx = pTxBlk->QueIdx;
371 pHTTXContext = &pAd->TxContext[QueIdx];
372
373 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
374
375 if(frameNum == 0)
376 {
377 // Check if we have enough space for this bulk-out batch.
378 Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
379 if (Status == NDIS_STATUS_SUCCESS)
380 {
381 pHTTXContext->bCurWriting = TRUE;
382
383 pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
384 pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
385
386
387 // Reserve space for 8 bytes padding.
388 if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
389 {
390
391 pHTTXContext->CurWritePosition += 8;
392 pHTTXContext->ENextBulkOutPosition += 8;
393 }
394 fillOffset = pHTTXContext->CurWritePosition;
395 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
396
397 pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
398
399 //
400 // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
401 //
402 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
403 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
404 hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
405 else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
406 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
407 hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
408 else
409 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
410 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
411
412 // Update the pTxBlk->Priv.
413 pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
414
415 // pTxInfo->USBDMApktLen now just a temp value and will to correct latter.
416 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
417
418 // Copy it.
419 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv);
420#ifdef RT_BIG_ENDIAN
421 RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
422#endif // RT_BIG_ENDIAN //
423 pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
424 pWirelessPacket += pTxBlk->Priv;
425 }
426 }
427 else
428 { // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
429
430 Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
431 if (Status == NDIS_STATUS_SUCCESS)
432 {
433 fillOffset = (pHTTXContext->CurWritePosition + pTxBlk->Priv);
434 pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
435
436 //hwHdrLen = pTxBlk->MpduHeaderLen;
437 NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen);
438 pWirelessPacket += (pTxBlk->MpduHeaderLen);
439 pTxBlk->Priv += pTxBlk->MpduHeaderLen;
440 }
441 else
442 { // It should not happened now unless we are going to shutdown.
443 DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
444 Status = NDIS_STATUS_FAILURE;
445 }
446 }
447
448
449 // We unlock it here to prevent the first 8 bytes maybe over-write issue.
450 // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext.
451 // 2. An interrupt break our routine and handle bulk-out complete.
452 // 3. In the bulk-out compllete, it need to do another bulk-out,
453 // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
454 // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
455 // 4. Interrupt complete.
456 // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
457 // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
458 // and the packet will wrong.
459 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
460
461 if (Status != NDIS_STATUS_SUCCESS)
462 {
463 DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
464 goto done;
465 }
466
467 // Copy the frame content into DMA buffer and update the pTxBlk->Priv
468 NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
469 pWirelessPacket += pTxBlk->SrcBufLen;
470 pTxBlk->Priv += pTxBlk->SrcBufLen;
471
472done:
473 // Release the skb buffer here
474 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
475
476 return(Status);
477
478}
479
480
481VOID RtmpUSB_FinalWriteTxResource(
482 IN PRTMP_ADAPTER pAd,
483 IN TX_BLK *pTxBlk,
484 IN USHORT totalMPDUSize,
485 IN USHORT TxIdx)
486{
487 UCHAR QueIdx;
488 HT_TX_CONTEXT *pHTTXContext;
489 UINT32 fillOffset;
490 TXINFO_STRUC *pTxInfo;
491 TXWI_STRUC *pTxWI;
492 UINT32 USBDMApktLen, padding;
493 unsigned long IrqFlags;
494 PUCHAR pWirelessPacket;
495
496 QueIdx = pTxBlk->QueIdx;
497 pHTTXContext = &pAd->TxContext[QueIdx];
498
499 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
500
501 if (pHTTXContext->bCurWriting == TRUE)
502 {
503 fillOffset = pHTTXContext->CurWritePosition;
504 if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
505 && (pHTTXContext->bCopySavePad == TRUE))
506 pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]);
507 else
508 pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]);
509
510 //
511 // Update TxInfo->USBDMApktLen ,
512 // the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding
513 //
514 pTxInfo = (PTXINFO_STRUC)(pWirelessPacket);
515
516 // Calculate the bulk-out padding
517 USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
518 padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
519 USBDMApktLen += padding;
520
521 pTxInfo->USBDMATxPktLen = USBDMApktLen;
522
523 //
524 // Update TXWI->MPDUtotalByteCount ,
525 // the length = 802.11 header + payload_of_all_batch_frames
526 pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE);
527 pTxWI->MPDUtotalByteCount = totalMPDUSize;
528
529 //
530 // Update the pHTTXContext->CurWritePosition
531 //
532 pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
533 if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT)
534 { // Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame.
535 pHTTXContext->CurWritePosition = 8;
536 pTxInfo->SwUseLastRound = 1;
537 }
538 pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
539
540
541 //
542 // Zero the last padding.
543 //
544 pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]);
545 NdisZeroMemory(pWirelessPacket, padding + 8);
546
547 // Finally, set bCurWriting as FALSE
548 pHTTXContext->bCurWriting = FALSE;
549
550 }
551 else
552 { // It should not happened now unless we are going to shutdown.
553 DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
554 }
555
556 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
557
558}
559
560
561VOID RtmpUSBDataLastTxIdx(
562 IN PRTMP_ADAPTER pAd,
563 IN UCHAR QueIdx,
564 IN USHORT TxIdx)
565{
566 // DO nothing for USB.
567}
568
569
570/*
571 When can do bulk-out:
572 1. TxSwFreeIdx < TX_RING_SIZE;
573 It means has at least one Ring entity is ready for bulk-out, kick it out.
574 2. If TxSwFreeIdx == TX_RING_SIZE
575 Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
576
577*/
578VOID RtmpUSBDataKickOut(
579 IN PRTMP_ADAPTER pAd,
580 IN TX_BLK *pTxBlk,
581 IN UCHAR QueIdx)
582{
583 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
584 RTUSBKickBulkOut(pAd);
585
586}
587
588
589/*
590 Must be run in Interrupt context
591 This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
592 */
593int RtmpUSBMgmtKickOut(
594 IN RTMP_ADAPTER *pAd,
595 IN UCHAR QueIdx,
596 IN PNDIS_PACKET pPacket,
597 IN PUCHAR pSrcBufVA,
598 IN UINT SrcBufLen)
599{
600 PTXINFO_STRUC pTxInfo;
601 ULONG BulkOutSize;
602 UCHAR padLen;
603 PUCHAR pDest;
604 ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
605 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
606 unsigned long IrqFlags;
607
608
609 pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);
610
611 // Build our URB for USBD
612 BulkOutSize = SrcBufLen;
613 BulkOutSize = (BulkOutSize + 3) & (~3);
614 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
615
616 BulkOutSize += 4; // Always add 4 extra bytes at every packet.
617
618 // If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.
619 if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
620 BulkOutSize += 4;
621
622 padLen = BulkOutSize - SrcBufLen;
623 ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
624
625 // Now memzero all extra padding bytes.
626 pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
627 skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
628 NdisZeroMemory(pDest, padLen);
629
630 RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
631
632 pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
633 pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));
634
635 // Length in TxInfo should be 8 less than bulkout size.
636 pMLMEContext->BulkOutSize = BulkOutSize;
637 pMLMEContext->InUse = TRUE;
638 pMLMEContext->bWaitingBulkOut = TRUE;
639
640
641 //for debug
642 //hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));
643
644 //pAd->RalinkCounters.KickTxCount++;
645 //pAd->RalinkCounters.OneSecTxDoneCount++;
646
647 //if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
648 // needKickOut = TRUE;
649
650 // Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX
651 pAd->MgmtRing.TxSwFreeIdx--;
652 INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
653
654 RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
655
656 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
657 //if (needKickOut)
658 RTUSBKickBulkOut(pAd);
659
660 return 0;
661}
662
663
664VOID RtmpUSBNullFrameKickOut(
665 IN RTMP_ADAPTER *pAd,
666 IN UCHAR QueIdx,
667 IN UCHAR *pNullFrame,
668 IN UINT32 frameLen)
669{
670 if (pAd->NullContext.InUse == FALSE)
671 {
672 PTX_CONTEXT pNullContext;
673 PTXINFO_STRUC pTxInfo;
674 PTXWI_STRUC pTxWI;
675 PUCHAR pWirelessPkt;
676
677 pNullContext = &(pAd->NullContext);
678
679 // Set the in use bit
680 pNullContext->InUse = TRUE;
681 pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];
682
683 RTMPZeroMemory(&pWirelessPkt[0], 100);
684 pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0];
685 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
686 pTxInfo->QSEL = FIFO_EDCA;
687 pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE];
688 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
689 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
690#ifdef RT_BIG_ENDIAN
691 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
692#endif // RT_BIG_ENDIAN //
693
694 RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
695#ifdef RT_BIG_ENDIAN
696 RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWI_SIZE], DIR_WRITE, FALSE);
697#endif // RT_BIG_ENDIAN //
698 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
699
700 // Fill out frame length information for global Bulk out arbitor
701 //pNullContext->BulkOutSize = TransferBufferLength;
702 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate]));
703 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
704
705 // Kick bulk out
706 RTUSBKickBulkOut(pAd);
707 }
708
709}
710
711#ifdef CONFIG_STA_SUPPORT
712/*
713 ========================================================================
714
715 Routine Description:
716 Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
717
718 Arguments:
719 pRxD Pointer to the Rx descriptor
720
721 Return Value:
722 NDIS_STATUS_SUCCESS No err
723 NDIS_STATUS_FAILURE Error
724
725 Note:
726
727 ========================================================================
728*/
729NDIS_STATUS RTMPCheckRxError(
730 IN PRTMP_ADAPTER pAd,
731 IN PHEADER_802_11 pHeader,
732 IN PRXWI_STRUC pRxWI,
733 IN PRT28XX_RXD_STRUC pRxINFO)
734{
735 PCIPHER_KEY pWpaKey;
736 INT dBm;
737
738 if (pAd->bPromiscuous == TRUE)
739 return(NDIS_STATUS_SUCCESS);
740 if(pRxINFO == NULL)
741 return(NDIS_STATUS_FAILURE);
742
743 // Phy errors & CRC errors
744 if (pRxINFO->Crc)
745 {
746 // Check RSSI for Noise Hist statistic collection.
747 dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
748 if (dBm <= -87)
749 pAd->StaCfg.RPIDensity[0] += 1;
750 else if (dBm <= -82)
751 pAd->StaCfg.RPIDensity[1] += 1;
752 else if (dBm <= -77)
753 pAd->StaCfg.RPIDensity[2] += 1;
754 else if (dBm <= -72)
755 pAd->StaCfg.RPIDensity[3] += 1;
756 else if (dBm <= -67)
757 pAd->StaCfg.RPIDensity[4] += 1;
758 else if (dBm <= -62)
759 pAd->StaCfg.RPIDensity[5] += 1;
760 else if (dBm <= -57)
761 pAd->StaCfg.RPIDensity[6] += 1;
762 else if (dBm > -57)
763 pAd->StaCfg.RPIDensity[7] += 1;
764
765 return(NDIS_STATUS_FAILURE);
766 }
767
768 // Add Rx size to channel load counter, we should ignore error counts
769 pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14);
770
771 // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
772 if (pHeader->FC.ToDs)
773 {
774 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
775 return NDIS_STATUS_FAILURE;
776 }
777
778 // Paul 04-03 for OFDM Rx length issue
779 if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE)
780 {
781 DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
782 return NDIS_STATUS_FAILURE;
783 }
784
785 // Drop not U2M frames, cant's drop here because we will drop beacon in this case
786 // I am kind of doubting the U2M bit operation
787 // if (pRxD->U2M == 0)
788 // return(NDIS_STATUS_FAILURE);
789
790 // drop decyption fail frame
791 if (pRxINFO->Decrypted && pRxINFO->CipherErr)
792 {
793
794 //
795 // MIC Error
796 //
797 if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss)
798 {
799 pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
800 RTMPReportMicError(pAd, pWpaKey);
801 DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
802 }
803
804 if (pRxINFO->Decrypted &&
805 (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) &&
806 (pHeader->Sequence == pAd->FragFrame.Sequence))
807 {
808 //
809 // Acceptable since the First FragFrame no CipherErr problem.
810 //
811 return(NDIS_STATUS_SUCCESS);
812 }
813
814 return(NDIS_STATUS_FAILURE);
815 }
816
817 return(NDIS_STATUS_SUCCESS);
818}
819
820VOID RT28xxUsbStaAsicForceWakeup(
821 IN PRTMP_ADAPTER pAd,
822 IN BOOLEAN bFromTx)
823{
824 AUTO_WAKEUP_STRUC AutoWakeupCfg;
825
826 AutoWakeupCfg.word = 0;
827 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
828
829 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x00);
830
831 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
832}
833
834VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
835 IN PRTMP_ADAPTER pAd,
836 IN USHORT TbttNumToNextWakeUp)
837{
838 AUTO_WAKEUP_STRUC AutoWakeupCfg;
839
840 // we have decided to SLEEP, so at least do it for a BEACON period.
841 if (TbttNumToNextWakeUp == 0)
842 TbttNumToNextWakeUp = 1;
843
844 AutoWakeupCfg.word = 0;
845 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
846
847 AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
848 AutoWakeupCfg.field.EnableAutoWakeup = 1;
849 AutoWakeupCfg.field.AutoLeadTime = 5;
850 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
851
852 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); // send POWER-SAVE command to MCU. Timeout 40us.
853
854 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
855
856}
857#endif // CONFIG_STA_SUPPORT //
858
859VOID RT28xxUsbMlmeRadioOn(
860 IN PRTMP_ADAPTER pAd)
861{
862 DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
863
864 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
865 return;
866
867#ifdef CONFIG_STA_SUPPORT
868 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
869 {
870 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x00);
871 RTMPusecDelay(10000);
872 }
873#endif // CONFIG_STA_SUPPORT //
874 NICResetFromError(pAd);
875
876 // Enable Tx/Rx
877 RTMPEnableRxTx(pAd);
878
879 // Clear Radio off flag
880 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
881
882#ifdef CONFIG_STA_SUPPORT
883 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
884 RTUSBBulkReceive(pAd);
885#endif // CONFIG_STA_SUPPORT //
886
887 // Set LED
888 RTMPSetLED(pAd, LED_RADIO_ON);
889}
890
891VOID RT28xxUsbMlmeRadioOFF(
892 IN PRTMP_ADAPTER pAd)
893{
894 WPDMA_GLO_CFG_STRUC GloCfg;
895 UINT32 Value, i;
896
897 DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
898
899 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
900 return;
901
902 // Set LED
903 RTMPSetLED(pAd, LED_RADIO_OFF);
904 // Set Radio off flag
905 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
906
907#ifdef CONFIG_STA_SUPPORT
908 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
909 {
910 // Link down first if any association exists
911 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
912 LinkDown(pAd, FALSE);
913 RTMPusecDelay(10000);
914
915 //==========================================
916 // Clean up old bss table
917 BssTableInit(&pAd->ScanTab);
918 }
919#endif // CONFIG_STA_SUPPORT //
920
921
922 // Disable MAC Tx/Rx
923 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
924 Value &= (0xfffffff3);
925 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
926
927 // MAC_SYS_CTRL => value = 0x0 => 40mA
928 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0);
929
930 // PWR_PIN_CFG => value = 0x0 => 40mA
931 RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0);
932
933 // TX_PIN_CFG => value = 0x0 => 20mA
934 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, 0);
935
936 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
937 {
938 // Must using 40MHz.
939 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
940 }
941 else
942 {
943 // Must using 20MHz.
944 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
945 }
946
947 // Waiting for DMA idle
948 i = 0;
949 do
950 {
951 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
952 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
953 break;
954
955 RTMPusecDelay(1000);
956 }while (i++ < 100);
957
958#ifdef CONFIG_STA_SUPPORT
959 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
960 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
961#endif // CONFIG_STA_SUPPORT //
962}
963
diff --git a/drivers/staging/rt2870/common/cmm_info.c b/drivers/staging/rt2870/common/cmm_info.c
new file mode 100644
index 00000000000..40792e16237
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_info.c
@@ -0,0 +1,3712 @@
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 // Reset HotSpot counter
851#if 0 // ToDo.
852 for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++)
853 {
854 pEntry = &pAd->MacTab.Content[i];
855
856 if ((pEntry->Valid == FALSE) || (pEntry->Sst != SST_ASSOC))
857 continue;
858
859 pEntry->HSCounter.LastDataPacketTime = 0;
860 pEntry->HSCounter.TotalRxByteCount= 0;
861 pEntry->HSCounter.TotalTxByteCount= 0;
862 }
863#endif
864
865
866 return TRUE;
867}
868
869/*
870 ========================================================================
871
872 Routine Description:
873 Add WPA key process.
874 In Adhoc WPANONE, bPairwise = 0; KeyIdx = 0;
875
876 Arguments:
877 pAd Pointer to our adapter
878 pBuf Pointer to the where the key stored
879
880 Return Value:
881 NDIS_SUCCESS Add key successfully
882
883 IRQL = DISPATCH_LEVEL
884
885 Note:
886
887 ========================================================================
888*/
889#if 0 // remove by AlbertY
890NDIS_STATUS RTMPWPAAddKeyProc(
891 IN PRTMP_ADAPTER pAd,
892 IN PVOID pBuf)
893{
894 PNDIS_802_11_KEY pKey;
895 ULONG KeyIdx;
896// NDIS_STATUS Status;
897// ULONG offset; // unused variable, snowpin 2006.07.13
898
899 PUCHAR pTxMic, pRxMic;
900 BOOLEAN bTxKey; // Set the key as transmit key
901 BOOLEAN bPairwise; // Indicate the key is pairwise key
902 BOOLEAN bKeyRSC; // indicate the receive SC set by KeyRSC value.
903 // Otherwise, it will set by the NIC.
904 BOOLEAN bAuthenticator; // indicate key is set by authenticator.
905 UCHAR apidx = BSS0;
906
907 pKey = (PNDIS_802_11_KEY) pBuf;
908 KeyIdx = pKey->KeyIndex & 0xff;
909 // Bit 31 of Add-key, Tx Key
910 bTxKey = (pKey->KeyIndex & 0x80000000) ? TRUE : FALSE;
911 // Bit 30 of Add-key PairwiseKey
912 bPairwise = (pKey->KeyIndex & 0x40000000) ? TRUE : FALSE;
913 // Bit 29 of Add-key KeyRSC
914 bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
915 // Bit 28 of Add-key Authenticator
916 bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
917
918 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc==>pKey->KeyIndex = %x. bPairwise= %d\n", pKey->KeyIndex, bPairwise));
919 // 1. Check Group / Pairwise Key
920 if (bPairwise) // Pairwise Key
921 {
922 // 1. KeyIdx must be 0, otherwise, return NDIS_STATUS_INVALID_DATA
923 if (KeyIdx != 0)
924 return(NDIS_STATUS_INVALID_DATA);
925
926 // 2. Check bTx, it must be true, otherwise, return NDIS_STATUS_INVALID_DATA
927 if (bTxKey == FALSE)
928 return(NDIS_STATUS_INVALID_DATA);
929
930 // 3. If BSSID is all 0xff, return NDIS_STATUS_INVALID_DATA
931 if (MAC_ADDR_EQUAL(pKey->BSSID, BROADCAST_ADDR))
932 return(NDIS_STATUS_INVALID_DATA);
933
934 // 3.1 Check Pairwise key length for TKIP key. For AES, it's always 128 bits
935 //if ((pAdapter->PortCfg.WepStatus == Ndis802_11Encryption2Enabled) && (pKey->KeyLength != LEN_TKIP_KEY))
936 if ((pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) && (pKey->KeyLength != LEN_TKIP_KEY))
937 return(NDIS_STATUS_INVALID_DATA);
938
939 pAd->SharedKey[apidx][KeyIdx].Type = PAIRWISE_KEY;
940
941 if (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2)
942 {
943 // Send media specific event to start PMKID caching
944 RTMPIndicateWPA2Status(pAd);
945 }
946 }
947 else
948 {
949 // 1. Check BSSID, if not current BSSID or Bcast, return NDIS_STATUS_INVALID_DATA
950 if ((! MAC_ADDR_EQUAL(pKey->BSSID, BROADCAST_ADDR)) &&
951 (! MAC_ADDR_EQUAL(pKey->BSSID, pAd->ApCfg.MBSSID[apidx].Bssid)))
952 return(NDIS_STATUS_INVALID_DATA);
953
954 // 2. Check Key index for supported Group Key
955 if (KeyIdx >= GROUP_KEY_NUM)
956 return(NDIS_STATUS_INVALID_DATA);
957
958 // 3. Set as default Tx Key if bTxKey is TRUE
959 if (bTxKey == TRUE)
960 pAd->ApCfg.MBSSID[apidx].DefaultKeyId = (UCHAR) KeyIdx;
961
962 pAd->SharedKey[apidx][KeyIdx].Type = GROUP_KEY;
963 }
964
965 // 4. Select RxMic / TxMic based on Supp / Authenticator
966 if (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPANone)
967 {
968 // for WPA-None Tx, Rx MIC is the same
969 pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
970 pRxMic = pTxMic;
971 }
972 else if (bAuthenticator == TRUE)
973 {
974 pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
975 pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
976 }
977 else
978 {
979 pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
980 pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
981 }
982
983 // 6. Check RxTsc
984 if (bKeyRSC == TRUE)
985 {
986 NdisMoveMemory(pAd->SharedKey[apidx][KeyIdx].RxTsc, &pKey->KeyRSC, 6);
987 NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].PairwiseKey.RxTsc, &pKey->KeyRSC, 6);
988 }
989 else
990 {
991 NdisZeroMemory(pAd->SharedKey[apidx][KeyIdx].RxTsc, 6);
992 }
993
994 // 7. Copy information into Pairwise Key structure.
995 // pKey->KeyLength will include TxMic and RxMic, therefore, we use 16 bytes hardcoded.
996 pAd->SharedKey[apidx][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
997 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
998 NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, 16);
999 NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].PairwiseKey.Key, &pKey->KeyMaterial, 16);
1000 if (pKey->KeyLength == LEN_TKIP_KEY)
1001 {
1002 // Only Key lenth equal to TKIP key have these
1003 NdisMoveMemory(pAd->SharedKey[apidx][KeyIdx].RxMic, pRxMic, 8);
1004 NdisMoveMemory(pAd->SharedKey[apidx][KeyIdx].TxMic, pTxMic, 8);
1005 NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].PairwiseKey.RxMic, pRxMic, 8);
1006 NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].PairwiseKey.TxMic, pTxMic, 8);
1007 }
1008
1009 COPY_MAC_ADDR(pAd->SharedKey[BSS0][KeyIdx].BssId, pKey->BSSID);
1010
1011 // Init TxTsc to one based on WiFi WPA specs
1012 pAd->SharedKey[apidx][KeyIdx].TxTsc[0] = 1;
1013 pAd->SharedKey[apidx][KeyIdx].TxTsc[1] = 0;
1014 pAd->SharedKey[apidx][KeyIdx].TxTsc[2] = 0;
1015 pAd->SharedKey[apidx][KeyIdx].TxTsc[3] = 0;
1016 pAd->SharedKey[apidx][KeyIdx].TxTsc[4] = 0;
1017 pAd->SharedKey[apidx][KeyIdx].TxTsc[5] = 0;
1018 // 4. Init TxTsc to one based on WiFi WPA specs
1019 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.TxTsc[0] = 1;
1020 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.TxTsc[1] = 0;
1021 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.TxTsc[2] = 0;
1022 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.TxTsc[3] = 0;
1023 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.TxTsc[4] = 0;
1024 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.TxTsc[5] = 0;
1025
1026 if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption3Enabled)
1027 {
1028 pAd->SharedKey[apidx][KeyIdx].CipherAlg = CIPHER_AES;
1029 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = CIPHER_AES;
1030 }
1031 else if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption2Enabled)
1032 {
1033 pAd->SharedKey[apidx][KeyIdx].CipherAlg = CIPHER_TKIP;
1034 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = CIPHER_TKIP;
1035 }
1036 else if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption1Enabled)
1037 {
1038 if (pAd->SharedKey[apidx][KeyIdx].KeyLen == 5)
1039 {
1040 pAd->SharedKey[apidx][KeyIdx].CipherAlg = CIPHER_WEP64;
1041 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = CIPHER_WEP64;
1042 }
1043 else if (pAd->SharedKey[apidx][KeyIdx].KeyLen == 13)
1044 {
1045 pAd->SharedKey[apidx][KeyIdx].CipherAlg = CIPHER_WEP128;
1046 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = CIPHER_WEP128;
1047 }
1048 else
1049 {
1050 pAd->SharedKey[apidx][KeyIdx].CipherAlg = CIPHER_NONE;
1051 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = CIPHER_NONE;
1052 }
1053 }
1054 else
1055 {
1056 pAd->SharedKey[apidx][KeyIdx].CipherAlg = CIPHER_NONE;
1057 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = CIPHER_NONE;
1058 }
1059
1060 if ((pAd->OpMode == OPMODE_STA)) // Pairwise Key. Add BSSID to WCTable
1061 {
1062 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1063 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen;
1064 }
1065
1066 if ((pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2) ||
1067 (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA2PSK))
1068 {
1069 //
1070 // On WPA2, Update Group Key Cipher.
1071 //
1072 if (!bPairwise)
1073 {
1074 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
1075 pAd->SharedKey[apidx][KeyIdx].CipherAlg = CIPHER_AES;
1076 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
1077 pAd->SharedKey[apidx][KeyIdx].CipherAlg = CIPHER_TKIP;
1078 }
1079 }
1080
1081 DBGPRINT(RT_DEBUG_TRACE, ("pAd->SharedKey[%d][%d].CipherAlg = %d\n", apidx, KeyIdx, pAd->SharedKey[apidx][KeyIdx].CipherAlg));
1082
1083#if 0
1084 DBGPRINT_RAW(RT_DEBUG_TRACE, ("%s Key #%d", CipherName[pAd->SharedKey[apidx][KeyIdx].CipherAlg],KeyIdx));
1085 for (i = 0; i < 16; i++)
1086 {
1087 DBGPRINT_RAW(RT_DEBUG_TRACE, ("%02x:", pAd->SharedKey[apidx][KeyIdx].Key[i]));
1088 }
1089 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n Rx MIC Key = "));
1090 for (i = 0; i < 8; i++)
1091 {
1092 DBGPRINT_RAW(RT_DEBUG_TRACE, ("%02x:", pAd->SharedKey[apidx][KeyIdx].RxMic[i]));
1093 }
1094 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n Tx MIC Key = "));
1095 for (i = 0; i < 8; i++)
1096 {
1097 DBGPRINT_RAW(RT_DEBUG_TRACE, ("%02x:", pAd->SharedKey[apidx][KeyIdx].TxMic[i]));
1098 }
1099 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n RxTSC = "));
1100 for (i = 0; i < 6; i++)
1101 {
1102 DBGPRINT_RAW(RT_DEBUG_TRACE, ("%02x:", pAd->SharedKey[apidx][KeyIdx].RxTsc[i]));
1103 }
1104#endif
1105 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n pKey-> BSSID:%02x:%02x:%02x:%02x:%02x:%02x \n",
1106 pKey->BSSID[0],pKey->BSSID[1],pKey->BSSID[2],pKey->BSSID[3],pKey->BSSID[4],pKey->BSSID[5]));
1107
1108 if ((bTxKey) && (pAd->OpMode == OPMODE_STA)) // Pairwise Key. Add BSSID to WCTable
1109 RTMPAddBSSIDCipher(pAd, BSSID_WCID, pKey, pAd->SharedKey[BSS0][KeyIdx].CipherAlg);
1110
1111
1112 // No matter pairwise key or what leyidx is, always has a copy at on-chip SharedKeytable.
1113 AsicAddSharedKeyEntry(pAd,
1114 apidx,
1115 (UCHAR)KeyIdx,
1116 pAd->SharedKey[apidx][KeyIdx].CipherAlg,
1117 pAd->SharedKey[apidx][KeyIdx].Key,
1118 pAd->SharedKey[apidx][KeyIdx].TxMic,
1119 pAd->SharedKey[apidx][KeyIdx].RxMic);
1120
1121 // The WCID key specified in used at Tx. For STA, always use pairwise key.
1122
1123 // ad-hoc mode need to specify WAP Group key with WCID index=BSS0Mcast_WCID. Let's always set this key here.
1124/* if (bPairwise == FALSE)
1125 {
1126 offset = MAC_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE);
1127 NdisZeroMemory(IVEIV, 8);
1128 // 1. IV/EIV
1129 // Specify key index to find shared key.
1130 if ((pAd->SharedKey[BSS0][KeyIdx].CipherAlg==CIPHER_TKIP) ||
1131 (pAd->SharedKey[BSS0][KeyIdx].CipherAlg==CIPHER_AES))
1132 IVEIV[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key
1133 IVEIV[3] |= (KeyIdx<< 6); // groupkey index is not 0
1134 for (i=0; i<8; i++)
1135 {
1136 RTMP_IO_WRITE8(pAd, offset+i, IVEIV[i]);
1137 }
1138
1139 // 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0
1140 WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|PAIRWISEKEYTABLE;
1141 offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE);
1142 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
1143
1144 }
1145
1146*/
1147
1148 if (pAd->SharedKey[apidx][KeyIdx].Type == GROUP_KEY)
1149 {
1150 // 802.1x port control
1151 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1152 DBGPRINT(RT_DEBUG_TRACE,("!!WPA_802_1X_PORT_SECURED!!\n"));
1153
1154 }
1155
1156 return (NDIS_STATUS_SUCCESS);
1157}
1158#endif
1159
1160BOOLEAN RTMPCheckStrPrintAble(
1161 IN CHAR *pInPutStr,
1162 IN UCHAR strLen)
1163{
1164 UCHAR i=0;
1165
1166 for (i=0; i<strLen; i++)
1167 {
1168 if ((pInPutStr[i] < 0x21) ||
1169 (pInPutStr[i] > 0x7E))
1170 return FALSE;
1171 }
1172
1173 return TRUE;
1174}
1175
1176/*
1177 ========================================================================
1178
1179 Routine Description:
1180 Remove WPA Key process
1181
1182 Arguments:
1183 pAd Pointer to our adapter
1184 pBuf Pointer to the where the key stored
1185
1186 Return Value:
1187 NDIS_SUCCESS Add key successfully
1188
1189 IRQL = DISPATCH_LEVEL
1190
1191 Note:
1192
1193 ========================================================================
1194*/
1195#ifdef CONFIG_STA_SUPPORT
1196VOID RTMPSetDesiredRates(
1197 IN PRTMP_ADAPTER pAdapter,
1198 IN LONG Rates)
1199{
1200 NDIS_802_11_RATES aryRates;
1201
1202 memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
1203 switch (pAdapter->CommonCfg.PhyMode)
1204 {
1205 case PHY_11A: // A only
1206 switch (Rates)
1207 {
1208 case 6000000: //6M
1209 aryRates[0] = 0x0c; // 6M
1210 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
1211 break;
1212 case 9000000: //9M
1213 aryRates[0] = 0x12; // 9M
1214 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
1215 break;
1216 case 12000000: //12M
1217 aryRates[0] = 0x18; // 12M
1218 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
1219 break;
1220 case 18000000: //18M
1221 aryRates[0] = 0x24; // 18M
1222 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
1223 break;
1224 case 24000000: //24M
1225 aryRates[0] = 0x30; // 24M
1226 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
1227 break;
1228 case 36000000: //36M
1229 aryRates[0] = 0x48; // 36M
1230 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
1231 break;
1232 case 48000000: //48M
1233 aryRates[0] = 0x60; // 48M
1234 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
1235 break;
1236 case 54000000: //54M
1237 aryRates[0] = 0x6c; // 54M
1238 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
1239 break;
1240 case -1: //Auto
1241 default:
1242 aryRates[0] = 0x6c; // 54Mbps
1243 aryRates[1] = 0x60; // 48Mbps
1244 aryRates[2] = 0x48; // 36Mbps
1245 aryRates[3] = 0x30; // 24Mbps
1246 aryRates[4] = 0x24; // 18M
1247 aryRates[5] = 0x18; // 12M
1248 aryRates[6] = 0x12; // 9M
1249 aryRates[7] = 0x0c; // 6M
1250 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
1251 break;
1252 }
1253 break;
1254 case PHY_11BG_MIXED: // B/G Mixed
1255 case PHY_11B: // B only
1256 case PHY_11ABG_MIXED: // A/B/G Mixed
1257 default:
1258 switch (Rates)
1259 {
1260 case 1000000: //1M
1261 aryRates[0] = 0x02;
1262 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
1263 break;
1264 case 2000000: //2M
1265 aryRates[0] = 0x04;
1266 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
1267 break;
1268 case 5000000: //5.5M
1269 aryRates[0] = 0x0b; // 5.5M
1270 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
1271 break;
1272 case 11000000: //11M
1273 aryRates[0] = 0x16; // 11M
1274 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
1275 break;
1276 case 6000000: //6M
1277 aryRates[0] = 0x0c; // 6M
1278 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
1279 break;
1280 case 9000000: //9M
1281 aryRates[0] = 0x12; // 9M
1282 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
1283 break;
1284 case 12000000: //12M
1285 aryRates[0] = 0x18; // 12M
1286 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
1287 break;
1288 case 18000000: //18M
1289 aryRates[0] = 0x24; // 18M
1290 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
1291 break;
1292 case 24000000: //24M
1293 aryRates[0] = 0x30; // 24M
1294 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
1295 break;
1296 case 36000000: //36M
1297 aryRates[0] = 0x48; // 36M
1298 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
1299 break;
1300 case 48000000: //48M
1301 aryRates[0] = 0x60; // 48M
1302 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
1303 break;
1304 case 54000000: //54M
1305 aryRates[0] = 0x6c; // 54M
1306 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
1307 break;
1308 case -1: //Auto
1309 default:
1310 if (pAdapter->CommonCfg.PhyMode == PHY_11B)
1311 { //B Only
1312 aryRates[0] = 0x16; // 11Mbps
1313 aryRates[1] = 0x0b; // 5.5Mbps
1314 aryRates[2] = 0x04; // 2Mbps
1315 aryRates[3] = 0x02; // 1Mbps
1316 }
1317 else
1318 { //(B/G) Mixed or (A/B/G) Mixed
1319 aryRates[0] = 0x6c; // 54Mbps
1320 aryRates[1] = 0x60; // 48Mbps
1321 aryRates[2] = 0x48; // 36Mbps
1322 aryRates[3] = 0x30; // 24Mbps
1323 aryRates[4] = 0x16; // 11Mbps
1324 aryRates[5] = 0x0b; // 5.5Mbps
1325 aryRates[6] = 0x04; // 2Mbps
1326 aryRates[7] = 0x02; // 1Mbps
1327 }
1328 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
1329 break;
1330 }
1331 break;
1332 }
1333
1334 NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
1335 NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
1336 DBGPRINT(RT_DEBUG_TRACE, (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
1337 pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
1338 pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
1339 pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
1340 pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
1341 // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
1342 MlmeUpdateTxRates(pAdapter, FALSE, 0);
1343}
1344
1345NDIS_STATUS RTMPWPARemoveKeyProc(
1346 IN PRTMP_ADAPTER pAd,
1347 IN PVOID pBuf)
1348{
1349 PNDIS_802_11_REMOVE_KEY pKey;
1350 ULONG KeyIdx;
1351 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
1352 BOOLEAN bTxKey; // Set the key as transmit key
1353 BOOLEAN bPairwise; // Indicate the key is pairwise key
1354 BOOLEAN bKeyRSC; // indicate the receive SC set by KeyRSC value.
1355 // Otherwise, it will set by the NIC.
1356 BOOLEAN bAuthenticator; // indicate key is set by authenticator.
1357 INT i;
1358
1359 DBGPRINT(RT_DEBUG_TRACE,("---> RTMPWPARemoveKeyProc\n"));
1360
1361 pKey = (PNDIS_802_11_REMOVE_KEY) pBuf;
1362 KeyIdx = pKey->KeyIndex & 0xff;
1363 // Bit 31 of Add-key, Tx Key
1364 bTxKey = (pKey->KeyIndex & 0x80000000) ? TRUE : FALSE;
1365 // Bit 30 of Add-key PairwiseKey
1366 bPairwise = (pKey->KeyIndex & 0x40000000) ? TRUE : FALSE;
1367 // Bit 29 of Add-key KeyRSC
1368 bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
1369 // Bit 28 of Add-key Authenticator
1370 bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
1371
1372 // 1. If bTx is TRUE, return failure information
1373 if (bTxKey == TRUE)
1374 return(NDIS_STATUS_INVALID_DATA);
1375
1376 // 2. Check Pairwise Key
1377 if (bPairwise)
1378 {
1379 // a. If BSSID is broadcast, remove all pairwise keys.
1380 // b. If not broadcast, remove the pairwise specified by BSSID
1381 for (i = 0; i < SHARE_KEY_NUM; i++)
1382 {
1383 if (MAC_ADDR_EQUAL(pAd->SharedKey[BSS0][i].BssId, pKey->BSSID))
1384 {
1385 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%d)\n", i));
1386 pAd->SharedKey[BSS0][i].KeyLen = 0;
1387 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
1388 AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)i);
1389 Status = NDIS_STATUS_SUCCESS;
1390 break;
1391 }
1392 }
1393 }
1394 // 3. Group Key
1395 else
1396 {
1397 // a. If BSSID is broadcast, remove all group keys indexed
1398 // b. If BSSID matched, delete the group key indexed.
1399 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%ld)\n", KeyIdx));
1400 pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
1401 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
1402 AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx);
1403 Status = NDIS_STATUS_SUCCESS;
1404 }
1405
1406 return (Status);
1407}
1408#endif // CONFIG_STA_SUPPORT //
1409
1410
1411#ifdef CONFIG_STA_SUPPORT
1412/*
1413 ========================================================================
1414
1415 Routine Description:
1416 Remove All WPA Keys
1417
1418 Arguments:
1419 pAd Pointer to our adapter
1420
1421 Return Value:
1422 None
1423
1424 IRQL = DISPATCH_LEVEL
1425
1426 Note:
1427
1428 ========================================================================
1429*/
1430VOID RTMPWPARemoveAllKeys(
1431 IN PRTMP_ADAPTER pAd)
1432{
1433
1434 UCHAR i;
1435
1436 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
1437
1438 // For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after
1439 // Link up. And it will be replaced if user changed it.
1440 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1441 return;
1442
1443 // For WPA-None, there is no need to remove it, since WinXP won't set it again after
1444 // Link up. And it will be replaced if user changed it.
1445 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1446 return;
1447
1448 // set BSSID wcid entry of the Pair-wise Key table as no-security mode
1449 AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID);
1450
1451 // set all shared key mode as no-security.
1452 for (i = 0; i < SHARE_KEY_NUM; i++)
1453 {
1454 DBGPRINT(RT_DEBUG_TRACE,("remove %s key #%d\n", CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
1455 NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(CIPHER_KEY));
1456
1457 AsicRemoveSharedKeyEntry(pAd, BSS0, i);
1458 }
1459
1460}
1461#endif // CONFIG_STA_SUPPORT //
1462
1463/*
1464 ========================================================================
1465 Routine Description:
1466 Change NIC PHY mode. Re-association may be necessary. possible settings
1467 include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED
1468
1469 Arguments:
1470 pAd - Pointer to our adapter
1471 phymode -
1472
1473 IRQL = PASSIVE_LEVEL
1474 IRQL = DISPATCH_LEVEL
1475
1476 ========================================================================
1477*/
1478VOID RTMPSetPhyMode(
1479 IN PRTMP_ADAPTER pAd,
1480 IN ULONG phymode)
1481{
1482 INT i;
1483 // the selected phymode must be supported by the RF IC encoded in E2PROM
1484
1485 // if no change, do nothing
1486 /* bug fix
1487 if (pAd->CommonCfg.PhyMode == phymode)
1488 return;
1489 */
1490 pAd->CommonCfg.PhyMode = (UCHAR)phymode;
1491
1492 DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
1493#ifdef EXT_BUILD_CHANNEL_LIST
1494 BuildChannelListEx(pAd);
1495#else
1496 BuildChannelList(pAd);
1497#endif // EXT_BUILD_CHANNEL_LIST //
1498
1499 // sanity check user setting
1500 for (i = 0; i < pAd->ChannelListNum; i++)
1501 {
1502 if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
1503 break;
1504 }
1505
1506 if (i == pAd->ChannelListNum)
1507 {
1508#ifdef CONFIG_STA_SUPPORT
1509 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1510 pAd->CommonCfg.Channel = FirstChannel(pAd);
1511#endif // CONFIG_STA_SUPPORT //
1512 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n", pAd->CommonCfg.Channel));
1513 }
1514
1515 NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
1516 NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
1517 NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
1518 switch (phymode) {
1519 case PHY_11B:
1520 pAd->CommonCfg.SupRate[0] = 0x82; // 1 mbps, in units of 0.5 Mbps, basic rate
1521 pAd->CommonCfg.SupRate[1] = 0x84; // 2 mbps, in units of 0.5 Mbps, basic rate
1522 pAd->CommonCfg.SupRate[2] = 0x8B; // 5.5 mbps, in units of 0.5 Mbps, basic rate
1523 pAd->CommonCfg.SupRate[3] = 0x96; // 11 mbps, in units of 0.5 Mbps, basic rate
1524 pAd->CommonCfg.SupRateLen = 4;
1525 pAd->CommonCfg.ExtRateLen = 0;
1526 pAd->CommonCfg.DesireRate[0] = 2; // 1 mbps, in units of 0.5 Mbps
1527 pAd->CommonCfg.DesireRate[1] = 4; // 2 mbps, in units of 0.5 Mbps
1528 pAd->CommonCfg.DesireRate[2] = 11; // 5.5 mbps, in units of 0.5 Mbps
1529 pAd->CommonCfg.DesireRate[3] = 22; // 11 mbps, in units of 0.5 Mbps
1530 //pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use
1531 break;
1532
1533 case PHY_11G:
1534 case PHY_11BG_MIXED:
1535 case PHY_11ABG_MIXED:
1536#ifdef DOT11_N_SUPPORT
1537 case PHY_11N_2_4G:
1538 case PHY_11ABGN_MIXED:
1539 case PHY_11BGN_MIXED:
1540 case PHY_11GN_MIXED:
1541#endif // DOT11_N_SUPPORT //
1542 pAd->CommonCfg.SupRate[0] = 0x82; // 1 mbps, in units of 0.5 Mbps, basic rate
1543 pAd->CommonCfg.SupRate[1] = 0x84; // 2 mbps, in units of 0.5 Mbps, basic rate
1544 pAd->CommonCfg.SupRate[2] = 0x8B; // 5.5 mbps, in units of 0.5 Mbps, basic rate
1545 pAd->CommonCfg.SupRate[3] = 0x96; // 11 mbps, in units of 0.5 Mbps, basic rate
1546 pAd->CommonCfg.SupRate[4] = 0x12; // 9 mbps, in units of 0.5 Mbps
1547 pAd->CommonCfg.SupRate[5] = 0x24; // 18 mbps, in units of 0.5 Mbps
1548 pAd->CommonCfg.SupRate[6] = 0x48; // 36 mbps, in units of 0.5 Mbps
1549 pAd->CommonCfg.SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
1550 pAd->CommonCfg.SupRateLen = 8;
1551 pAd->CommonCfg.ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps
1552 pAd->CommonCfg.ExtRate[1] = 0x18; // 12 mbps, in units of 0.5 Mbps
1553 pAd->CommonCfg.ExtRate[2] = 0x30; // 24 mbps, in units of 0.5 Mbps
1554 pAd->CommonCfg.ExtRate[3] = 0x60; // 48 mbps, in units of 0.5 Mbps
1555 pAd->CommonCfg.ExtRateLen = 4;
1556 pAd->CommonCfg.DesireRate[0] = 2; // 1 mbps, in units of 0.5 Mbps
1557 pAd->CommonCfg.DesireRate[1] = 4; // 2 mbps, in units of 0.5 Mbps
1558 pAd->CommonCfg.DesireRate[2] = 11; // 5.5 mbps, in units of 0.5 Mbps
1559 pAd->CommonCfg.DesireRate[3] = 22; // 11 mbps, in units of 0.5 Mbps
1560 pAd->CommonCfg.DesireRate[4] = 12; // 6 mbps, in units of 0.5 Mbps
1561 pAd->CommonCfg.DesireRate[5] = 18; // 9 mbps, in units of 0.5 Mbps
1562 pAd->CommonCfg.DesireRate[6] = 24; // 12 mbps, in units of 0.5 Mbps
1563 pAd->CommonCfg.DesireRate[7] = 36; // 18 mbps, in units of 0.5 Mbps
1564 pAd->CommonCfg.DesireRate[8] = 48; // 24 mbps, in units of 0.5 Mbps
1565 pAd->CommonCfg.DesireRate[9] = 72; // 36 mbps, in units of 0.5 Mbps
1566 pAd->CommonCfg.DesireRate[10] = 96; // 48 mbps, in units of 0.5 Mbps
1567 pAd->CommonCfg.DesireRate[11] = 108; // 54 mbps, in units of 0.5 Mbps
1568 break;
1569
1570 case PHY_11A:
1571#ifdef DOT11_N_SUPPORT
1572 case PHY_11AN_MIXED:
1573 case PHY_11AGN_MIXED:
1574 case PHY_11N_5G:
1575#endif // DOT11_N_SUPPORT //
1576 pAd->CommonCfg.SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
1577 pAd->CommonCfg.SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
1578 pAd->CommonCfg.SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
1579 pAd->CommonCfg.SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
1580 pAd->CommonCfg.SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
1581 pAd->CommonCfg.SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
1582 pAd->CommonCfg.SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
1583 pAd->CommonCfg.SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
1584 pAd->CommonCfg.SupRateLen = 8;
1585 pAd->CommonCfg.ExtRateLen = 0;
1586 pAd->CommonCfg.DesireRate[0] = 12; // 6 mbps, in units of 0.5 Mbps
1587 pAd->CommonCfg.DesireRate[1] = 18; // 9 mbps, in units of 0.5 Mbps
1588 pAd->CommonCfg.DesireRate[2] = 24; // 12 mbps, in units of 0.5 Mbps
1589 pAd->CommonCfg.DesireRate[3] = 36; // 18 mbps, in units of 0.5 Mbps
1590 pAd->CommonCfg.DesireRate[4] = 48; // 24 mbps, in units of 0.5 Mbps
1591 pAd->CommonCfg.DesireRate[5] = 72; // 36 mbps, in units of 0.5 Mbps
1592 pAd->CommonCfg.DesireRate[6] = 96; // 48 mbps, in units of 0.5 Mbps
1593 pAd->CommonCfg.DesireRate[7] = 108; // 54 mbps, in units of 0.5 Mbps
1594 //pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use
1595 break;
1596
1597 default:
1598 break;
1599 }
1600
1601
1602 pAd->CommonCfg.BandState = UNKNOWN_BAND;
1603}
1604
1605
1606#ifdef DOT11_N_SUPPORT
1607/*
1608 ========================================================================
1609 Routine Description:
1610 Caller ensures we has 802.11n support.
1611 Calls at setting HT from AP/STASetinformation
1612
1613 Arguments:
1614 pAd - Pointer to our adapter
1615 phymode -
1616
1617 ========================================================================
1618*/
1619VOID RTMPSetHT(
1620 IN PRTMP_ADAPTER pAd,
1621 IN OID_SET_HT_PHYMODE *pHTPhyMode)
1622{
1623 //ULONG *pmcs;
1624 UINT32 Value = 0;
1625 UCHAR BBPValue = 0;
1626 UCHAR BBP3Value = 0;
1627 UCHAR RxStream = pAd->CommonCfg.RxStream;
1628
1629 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
1630 pHTPhyMode->HtMode, pHTPhyMode->ExtOffset,
1631 pHTPhyMode->MCS, pHTPhyMode->BW,
1632 pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
1633
1634 // Don't zero supportedHyPhy structure.
1635 RTMPZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
1636 RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
1637 RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset));
1638 RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy, sizeof(pAd->CommonCfg.DesiredHtPhy));
1639
1640 if (pAd->CommonCfg.bRdg)
1641 {
1642 pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1;
1643 pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1;
1644 }
1645 else
1646 {
1647 pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0;
1648 pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0;
1649 }
1650
1651 pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3;
1652 pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3;
1653
1654 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit));
1655
1656 // Mimo power save, A-MSDU size,
1657 pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
1658 pAd->CommonCfg.DesiredHtPhy.AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize;
1659 pAd->CommonCfg.DesiredHtPhy.MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode;
1660 pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
1661
1662 pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
1663 pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
1664 pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
1665
1666 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
1667 pAd->CommonCfg.DesiredHtPhy.AmsduSize,
1668 pAd->CommonCfg.DesiredHtPhy.MimoPs,
1669 pAd->CommonCfg.DesiredHtPhy.MpduDensity,
1670 pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
1671
1672 if(pHTPhyMode->HtMode == HTMODE_GF)
1673 {
1674 pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1;
1675 pAd->CommonCfg.DesiredHtPhy.GF = 1;
1676 }
1677 else
1678 pAd->CommonCfg.DesiredHtPhy.GF = 0;
1679
1680 // Decide Rx MCSSet
1681 switch (RxStream)
1682 {
1683 case 1:
1684 pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
1685 pAd->CommonCfg.HtCapability.MCSSet[1] = 0x00;
1686 break;
1687
1688 case 2:
1689 pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
1690 pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
1691 break;
1692
1693 case 3: // 3*3
1694 pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
1695 pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
1696 pAd->CommonCfg.HtCapability.MCSSet[2] = 0xff;
1697 break;
1698 }
1699
1700 if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40) )
1701 {
1702 pHTPhyMode->BW = BW_20;
1703 pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1;
1704 }
1705
1706 if(pHTPhyMode->BW == BW_40)
1707 {
1708 pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1; // MCS 32
1709 pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1;
1710 if (pAd->CommonCfg.Channel <= 14)
1711 pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1;
1712
1713 pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1;
1714 pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
1715 pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE;
1716 // Set Regsiter for extension channel position.
1717 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
1718 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value);
1719 if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW))
1720 {
1721 Value |= 0x1;
1722 BBP3Value |= (0x20);
1723 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
1724 }
1725 else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE))
1726 {
1727 Value &= 0xfe;
1728 BBP3Value &= (~0x20);
1729 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
1730 }
1731
1732 // Turn on BBP 40MHz mode now only as AP .
1733 // Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.
1734 if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd)
1735 )
1736 {
1737 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
1738 BBPValue &= (~0x18);
1739 BBPValue |= 0x10;
1740 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
1741
1742 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value);
1743 pAd->CommonCfg.BBPCurrentBW = BW_40;
1744 }
1745 }
1746 else
1747 {
1748 pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0;
1749 pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0;
1750 pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
1751 pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE;
1752 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1753 // Turn on BBP 20MHz mode by request here.
1754 {
1755 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
1756 BBPValue &= (~0x18);
1757 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
1758 pAd->CommonCfg.BBPCurrentBW = BW_20;
1759 }
1760 }
1761
1762 if(pHTPhyMode->STBC == STBC_USE)
1763 {
1764 pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1;
1765 pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1;
1766 pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1;
1767 pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1;
1768 }
1769 else
1770 {
1771 pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
1772 pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
1773 }
1774
1775#ifdef RT2870
1776 /* Frank recommend ,If not, Tx maybe block in high power. Rx has no problem*/
1777 if(IS_RT3070(pAd) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)))
1778 {
1779 pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 0;
1780 pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
1781 }
1782#endif // RT2870 //
1783
1784 if(pHTPhyMode->SHORTGI == GI_400)
1785 {
1786 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
1787 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1;
1788 pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1;
1789 pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1;
1790 }
1791 else
1792 {
1793 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0;
1794 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0;
1795 pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0;
1796 pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0;
1797 }
1798
1799 // We support link adaptation for unsolicit MCS feedback, set to 2.
1800 pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE; //MCSFBK_UNSOLICIT;
1801 pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel;
1802 // 1, the extension channel above the control channel.
1803
1804 // EDCA parameters used for AP's own transmission
1805 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1806 {
1807 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1808 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1809 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1810 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1811 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1812
1813 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1814 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1815 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1816 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1817
1818 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
1819 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
1820 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1821 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1822
1823 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1824 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1825 pAd->CommonCfg.APEdcaParm.Txop[2] = 94;
1826 pAd->CommonCfg.APEdcaParm.Txop[3] = 47;
1827 }
1828 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1829
1830
1831#ifdef CONFIG_STA_SUPPORT
1832 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1833 {
1834 RTMPSetIndividualHT(pAd, 0);
1835 }
1836#endif // CONFIG_STA_SUPPORT //
1837
1838}
1839
1840/*
1841 ========================================================================
1842 Routine Description:
1843 Caller ensures we has 802.11n support.
1844 Calls at setting HT from AP/STASetinformation
1845
1846 Arguments:
1847 pAd - Pointer to our adapter
1848 phymode -
1849
1850 ========================================================================
1851*/
1852VOID RTMPSetIndividualHT(
1853 IN PRTMP_ADAPTER pAd,
1854 IN UCHAR apidx)
1855{
1856 PRT_HT_PHY_INFO pDesired_ht_phy = NULL;
1857 UCHAR TxStream = pAd->CommonCfg.TxStream;
1858 UCHAR DesiredMcs = MCS_AUTO;
1859
1860 do
1861 {
1862
1863#ifdef CONFIG_STA_SUPPORT
1864 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1865 {
1866 pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo;
1867 DesiredMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
1868 //pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;
1869 break;
1870 }
1871#endif // CONFIG_STA_SUPPORT //
1872 } while (FALSE);
1873
1874 if (pDesired_ht_phy == NULL)
1875 {
1876 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
1877 return;
1878 }
1879 RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_HT_PHY_INFO));
1880
1881 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
1882 // Check the validity of MCS
1883 if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15)))
1884 {
1885 DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs));
1886 DesiredMcs = MCS_7;
1887 }
1888
1889 if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32))
1890 {
1891 DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
1892 DesiredMcs = MCS_0;
1893 }
1894
1895 pDesired_ht_phy->bHtEnable = TRUE;
1896
1897 // Decide desired Tx MCS
1898 switch (TxStream)
1899 {
1900 case 1:
1901 if (DesiredMcs == MCS_AUTO)
1902 {
1903 pDesired_ht_phy->MCSSet[0]= 0xff;
1904 pDesired_ht_phy->MCSSet[1]= 0x00;
1905 }
1906 else if (DesiredMcs <= MCS_7)
1907 {
1908 pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs;
1909 pDesired_ht_phy->MCSSet[1]= 0x00;
1910 }
1911 break;
1912
1913 case 2:
1914 if (DesiredMcs == MCS_AUTO)
1915 {
1916 pDesired_ht_phy->MCSSet[0]= 0xff;
1917 pDesired_ht_phy->MCSSet[1]= 0xff;
1918 }
1919 else if (DesiredMcs <= MCS_15)
1920 {
1921 ULONG mode;
1922
1923 mode = DesiredMcs / 8;
1924 if (mode < 2)
1925 pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
1926 }
1927 break;
1928
1929 case 3: // 3*3
1930 if (DesiredMcs == MCS_AUTO)
1931 {
1932 /* MCS0 ~ MCS23, 3 bytes */
1933 pDesired_ht_phy->MCSSet[0]= 0xff;
1934 pDesired_ht_phy->MCSSet[1]= 0xff;
1935 pDesired_ht_phy->MCSSet[2]= 0xff;
1936 }
1937 else if (DesiredMcs <= MCS_23)
1938 {
1939 ULONG mode;
1940
1941 mode = DesiredMcs / 8;
1942 if (mode < 3)
1943 pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
1944 }
1945 break;
1946 }
1947
1948 if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40)
1949 {
1950 if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32)
1951 pDesired_ht_phy->MCSSet[4] = 0x1;
1952 }
1953
1954 // update HT Rate setting
1955 if (pAd->OpMode == OPMODE_STA)
1956 MlmeUpdateHtTxRates(pAd, BSS0);
1957 else
1958 MlmeUpdateHtTxRates(pAd, apidx);
1959}
1960
1961
1962/*
1963 ========================================================================
1964 Routine Description:
1965 Update HT IE from our capability.
1966
1967 Arguments:
1968 Send all HT IE in beacon/probe rsp/assoc rsp/action frame.
1969
1970
1971 ========================================================================
1972*/
1973VOID RTMPUpdateHTIE(
1974 IN RT_HT_CAPABILITY *pRtHt,
1975 IN UCHAR *pMcsSet,
1976 OUT HT_CAPABILITY_IE *pHtCapability,
1977 OUT ADD_HT_INFO_IE *pAddHtInfo)
1978{
1979 RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE));
1980 RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE));
1981
1982 pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
1983 pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
1984 pHtCapability->HtCapInfo.GF = pRtHt->GF;
1985 pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
1986 pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
1987 pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
1988 pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
1989 pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
1990 pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
1991 pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
1992
1993 pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset ;
1994 pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
1995 pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
1996 pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
1997 RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet*/pMcsSet, 4); // rt2860 only support MCS max=32, no need to copy all 16 uchar.
1998
1999 DBGPRINT(RT_DEBUG_TRACE,("RTMPUpdateHTIE <== \n"));
2000}
2001#endif // DOT11_N_SUPPORT //
2002
2003/*
2004 ========================================================================
2005 Description:
2006 Add Client security information into ASIC WCID table and IVEIV table.
2007 Return:
2008 ========================================================================
2009*/
2010VOID RTMPAddWcidAttributeEntry(
2011 IN PRTMP_ADAPTER pAd,
2012 IN UCHAR BssIdx,
2013 IN UCHAR KeyIdx,
2014 IN UCHAR CipherAlg,
2015 IN MAC_TABLE_ENTRY *pEntry)
2016{
2017 UINT32 WCIDAttri = 0;
2018 USHORT offset;
2019 UCHAR IVEIV = 0;
2020 USHORT Wcid = 0;
2021
2022 {
2023#ifdef CONFIG_STA_SUPPORT
2024 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2025 {
2026 if (BssIdx > BSS0)
2027 {
2028 DBGPRINT(RT_DEBUG_ERROR, ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n", BssIdx));
2029 return;
2030 }
2031
2032 // 1. In ADHOC mode, the AID is wcid number. And NO mesh link exists.
2033 // 2. In Infra mode, the AID:1 MUST be wcid of infra STA.
2034 // the AID:2~ assign to mesh link entry.
2035 if (pEntry && ADHOC_ON(pAd))
2036 Wcid = pEntry->Aid;
2037 else if (pEntry && INFRA_ON(pAd))
2038 {
2039#ifdef QOS_DLS_SUPPORT
2040 if (pEntry->ValidAsDls == TRUE)
2041 Wcid = pEntry->Aid;
2042 else
2043#endif // QOS_DLS_SUPPORT //
2044 Wcid = BSSID_WCID;
2045 }
2046 else
2047 Wcid = MCAST_WCID;
2048 }
2049#endif // CONFIG_STA_SUPPORT //
2050 }
2051
2052 // Update WCID attribute table
2053 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
2054
2055#ifdef CONFIG_STA_SUPPORT
2056 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2057 {
2058 if (pEntry && pEntry->ValidAsMesh)
2059 WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
2060#ifdef QOS_DLS_SUPPORT
2061 else if ((pEntry) && (pEntry->ValidAsDls) &&
2062 ((CipherAlg == CIPHER_TKIP) ||
2063 (CipherAlg == CIPHER_TKIP_NO_MIC) ||
2064 (CipherAlg == CIPHER_AES) ||
2065 (CipherAlg == CIPHER_NONE)))
2066 WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
2067#endif // QOS_DLS_SUPPORT //
2068 else
2069 WCIDAttri = (CipherAlg<<1) | SHAREDKEYTABLE;
2070 }
2071#endif // CONFIG_STA_SUPPORT //
2072
2073 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
2074
2075
2076 // Update IV/EIV table
2077 offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
2078
2079 // WPA mode
2080 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) || (CipherAlg == CIPHER_AES))
2081 {
2082 // Eiv bit on. keyid always is 0 for pairwise key
2083 IVEIV = (KeyIdx <<6) | 0x20;
2084 }
2085 else
2086 {
2087 // WEP KeyIdx is default tx key.
2088 IVEIV = (KeyIdx << 6);
2089 }
2090
2091 // For key index and ext IV bit, so only need to update the position(offset+3).
2092#ifdef RT2870
2093 RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV);
2094#endif // RT2870 //
2095
2096 DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
2097 DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri));
2098
2099}
2100
2101/*
2102 ==========================================================================
2103 Description:
2104 Parse encryption type
2105Arguments:
2106 pAdapter Pointer to our adapter
2107 wrq Pointer to the ioctl argument
2108
2109 Return Value:
2110 None
2111
2112 Note:
2113 ==========================================================================
2114*/
2115CHAR *GetEncryptType(CHAR enc)
2116{
2117 if(enc == Ndis802_11WEPDisabled)
2118 return "NONE";
2119 if(enc == Ndis802_11WEPEnabled)
2120 return "WEP";
2121 if(enc == Ndis802_11Encryption2Enabled)
2122 return "TKIP";
2123 if(enc == Ndis802_11Encryption3Enabled)
2124 return "AES";
2125 if(enc == Ndis802_11Encryption4Enabled)
2126 return "TKIPAES";
2127 else
2128 return "UNKNOW";
2129}
2130
2131CHAR *GetAuthMode(CHAR auth)
2132{
2133 if(auth == Ndis802_11AuthModeOpen)
2134 return "OPEN";
2135 if(auth == Ndis802_11AuthModeShared)
2136 return "SHARED";
2137 if(auth == Ndis802_11AuthModeAutoSwitch)
2138 return "AUTOWEP";
2139 if(auth == Ndis802_11AuthModeWPA)
2140 return "WPA";
2141 if(auth == Ndis802_11AuthModeWPAPSK)
2142 return "WPAPSK";
2143 if(auth == Ndis802_11AuthModeWPANone)
2144 return "WPANONE";
2145 if(auth == Ndis802_11AuthModeWPA2)
2146 return "WPA2";
2147 if(auth == Ndis802_11AuthModeWPA2PSK)
2148 return "WPA2PSK";
2149 if(auth == Ndis802_11AuthModeWPA1WPA2)
2150 return "WPA1WPA2";
2151 if(auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
2152 return "WPA1PSKWPA2PSK";
2153
2154 return "UNKNOW";
2155}
2156
2157#if 1 //#ifndef UCOS
2158/*
2159 ==========================================================================
2160 Description:
2161 Get site survey results
2162 Arguments:
2163 pAdapter Pointer to our adapter
2164 wrq Pointer to the ioctl argument
2165
2166 Return Value:
2167 None
2168
2169 Note:
2170 Usage:
2171 1.) UI needs to wait 4 seconds after issue a site survey command
2172 2.) iwpriv ra0 get_site_survey
2173 3.) UI needs to prepare at least 4096bytes to get the results
2174 ==========================================================================
2175*/
2176#define LINE_LEN (4+33+20+8+10+9+7+3) // Channel+SSID+Bssid+WepStatus+AuthMode+Signal+WiressMode+NetworkType
2177VOID RTMPIoctlGetSiteSurvey(
2178 IN PRTMP_ADAPTER pAdapter,
2179 IN struct iwreq *wrq)
2180{
2181 CHAR *msg;
2182 INT i=0;
2183 INT WaitCnt;
2184 INT Status=0;
2185 CHAR Ssid[MAX_LEN_OF_SSID +1];
2186 INT Rssi = 0, max_len = LINE_LEN;
2187 UINT Rssi_Quality = 0;
2188 NDIS_802_11_NETWORK_TYPE wireless_mode;
2189
2190 os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
2191
2192 if (msg == NULL)
2193 {
2194 DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
2195 return;
2196 }
2197
2198 memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
2199 memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1));
2200 sprintf(msg,"%s","\n");
2201 sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-8s%-10s%-9s%-7s%-3s\n",
2202 "Ch", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", " NT");
2203
2204
2205 WaitCnt = 0;
2206#ifdef CONFIG_STA_SUPPORT
2207 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
2208 while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
2209 OS_WAIT(500);
2210#endif // CONFIG_STA_SUPPORT //
2211
2212 for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
2213 {
2214 if( pAdapter->ScanTab.BssEntry[i].Channel==0)
2215 break;
2216
2217 if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
2218 break;
2219
2220 //Channel
2221 sprintf(msg+strlen(msg),"%-4d", pAdapter->ScanTab.BssEntry[i].Channel);
2222 //SSID
2223 memcpy(Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
2224 Ssid[pAdapter->ScanTab.BssEntry[i].SsidLen] = '\0';
2225 sprintf(msg+strlen(msg),"%-33s", Ssid);
2226 //BSSID
2227 sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x ",
2228 pAdapter->ScanTab.BssEntry[i].Bssid[0],
2229 pAdapter->ScanTab.BssEntry[i].Bssid[1],
2230 pAdapter->ScanTab.BssEntry[i].Bssid[2],
2231 pAdapter->ScanTab.BssEntry[i].Bssid[3],
2232 pAdapter->ScanTab.BssEntry[i].Bssid[4],
2233 pAdapter->ScanTab.BssEntry[i].Bssid[5]);
2234 //Encryption Type
2235 sprintf(msg+strlen(msg),"%-8s",GetEncryptType(pAdapter->ScanTab.BssEntry[i].WepStatus));
2236 //Authentication Mode
2237 if (pAdapter->ScanTab.BssEntry[i].WepStatus == Ndis802_11WEPEnabled)
2238 sprintf(msg+strlen(msg),"%-10s", "UNKNOW");
2239 else
2240 sprintf(msg+strlen(msg),"%-10s",GetAuthMode(pAdapter->ScanTab.BssEntry[i].AuthMode));
2241 // Rssi
2242 Rssi = (INT)pAdapter->ScanTab.BssEntry[i].Rssi;
2243 if (Rssi >= -50)
2244 Rssi_Quality = 100;
2245 else if (Rssi >= -80) // between -50 ~ -80dbm
2246 Rssi_Quality = (UINT)(24 + ((Rssi + 80) * 26)/10);
2247 else if (Rssi >= -90) // between -80 ~ -90dbm
2248 Rssi_Quality = (UINT)(((Rssi + 90) * 26)/10);
2249 else // < -84 dbm
2250 Rssi_Quality = 0;
2251 sprintf(msg+strlen(msg),"%-9d", Rssi_Quality);
2252 // Wireless Mode
2253 wireless_mode = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
2254 if (wireless_mode == Ndis802_11FH ||
2255 wireless_mode == Ndis802_11DS)
2256 sprintf(msg+strlen(msg),"%-7s", "11b");
2257 else if (wireless_mode == Ndis802_11OFDM5)
2258 sprintf(msg+strlen(msg),"%-7s", "11a");
2259 else if (wireless_mode == Ndis802_11OFDM5_N)
2260 sprintf(msg+strlen(msg),"%-7s", "11a/n");
2261 else if (wireless_mode == Ndis802_11OFDM24)
2262 sprintf(msg+strlen(msg),"%-7s", "11b/g");
2263 else if (wireless_mode == Ndis802_11OFDM24_N)
2264 sprintf(msg+strlen(msg),"%-7s", "11b/g/n");
2265 else
2266 sprintf(msg+strlen(msg),"%-7s", "unknow");
2267 //Network Type
2268 if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_ADHOC)
2269 sprintf(msg+strlen(msg),"%-3s", " Ad");
2270 else
2271 sprintf(msg+strlen(msg),"%-3s", " In");
2272
2273 sprintf(msg+strlen(msg),"\n");
2274 }
2275
2276#ifdef CONFIG_STA_SUPPORT
2277 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
2278#endif // CONFIG_STA_SUPPORT //
2279 wrq->u.data.length = strlen(msg);
2280 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
2281
2282 DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - wrq->u.data.length = %d\n", wrq->u.data.length));
2283 os_free_mem(NULL, (PUCHAR)msg);
2284}
2285
2286
2287#define MAC_LINE_LEN (14+4+4+10+10+10+6+6) // Addr+aid+psm+datatime+rxbyte+txbyte+current tx rate+last tx rate
2288VOID RTMPIoctlGetMacTable(
2289 IN PRTMP_ADAPTER pAd,
2290 IN struct iwreq *wrq)
2291{
2292 INT i;
2293 RT_802_11_MAC_TABLE MacTab;
2294 char *msg;
2295
2296 MacTab.Num = 0;
2297 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
2298 {
2299 if (pAd->MacTab.Content[i].ValidAsCLI && (pAd->MacTab.Content[i].Sst == SST_ASSOC))
2300 {
2301 COPY_MAC_ADDR(MacTab.Entry[MacTab.Num].Addr, &pAd->MacTab.Content[i].Addr);
2302 MacTab.Entry[MacTab.Num].Aid = (UCHAR)pAd->MacTab.Content[i].Aid;
2303 MacTab.Entry[MacTab.Num].Psm = pAd->MacTab.Content[i].PsMode;
2304#ifdef DOT11_N_SUPPORT
2305 MacTab.Entry[MacTab.Num].MimoPs = pAd->MacTab.Content[i].MmpsMode;
2306#endif // DOT11_N_SUPPORT //
2307
2308 // Fill in RSSI per entry
2309 MacTab.Entry[MacTab.Num].AvgRssi0 = pAd->MacTab.Content[i].RssiSample.AvgRssi0;
2310 MacTab.Entry[MacTab.Num].AvgRssi1 = pAd->MacTab.Content[i].RssiSample.AvgRssi1;
2311 MacTab.Entry[MacTab.Num].AvgRssi2 = pAd->MacTab.Content[i].RssiSample.AvgRssi2;
2312
2313 // the connected time per entry
2314 MacTab.Entry[MacTab.Num].ConnectedTime = pAd->MacTab.Content[i].StaConnectTime;
2315#if 0 // ToDo
2316 MacTab.Entry[MacTab.Num].HSCounter.LastDataPacketTime = pAd->MacTab.Content[i].HSCounter.LastDataPacketTime;
2317 MacTab.Entry[MacTab.Num].HSCounter.TotalRxByteCount = pAd->MacTab.Content[i].HSCounter.TotalRxByteCount;
2318 MacTab.Entry[MacTab.Num].HSCounter.TotalTxByteCount = pAd->MacTab.Content[i].HSCounter.TotalTxByteCount;
2319#endif
2320 MacTab.Entry[MacTab.Num].TxRate.field.MCS = pAd->MacTab.Content[i].HTPhyMode.field.MCS;
2321 MacTab.Entry[MacTab.Num].TxRate.field.BW = pAd->MacTab.Content[i].HTPhyMode.field.BW;
2322 MacTab.Entry[MacTab.Num].TxRate.field.ShortGI = pAd->MacTab.Content[i].HTPhyMode.field.ShortGI;
2323 MacTab.Entry[MacTab.Num].TxRate.field.STBC = pAd->MacTab.Content[i].HTPhyMode.field.STBC;
2324 MacTab.Entry[MacTab.Num].TxRate.field.rsv = pAd->MacTab.Content[i].HTPhyMode.field.rsv;
2325 MacTab.Entry[MacTab.Num].TxRate.field.MODE = pAd->MacTab.Content[i].HTPhyMode.field.MODE;
2326 MacTab.Entry[MacTab.Num].TxRate.word = pAd->MacTab.Content[i].HTPhyMode.word;
2327
2328 MacTab.Num += 1;
2329 }
2330 }
2331 wrq->u.data.length = sizeof(RT_802_11_MAC_TABLE);
2332 if (copy_to_user(wrq->u.data.pointer, &MacTab, wrq->u.data.length))
2333 {
2334 DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
2335 }
2336
2337 msg = (CHAR *) kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
2338 memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN );
2339 sprintf(msg,"%s","\n");
2340 sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n",
2341 "MAC", "AID", "PSM", "LDT", "RxB", "TxB","CTxR", "LTxR");
2342
2343 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
2344 {
2345 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
2346 if (pEntry->ValidAsCLI && (pEntry->Sst == SST_ASSOC))
2347 {
2348 if((strlen(msg)+MAC_LINE_LEN ) >= (MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN) )
2349 break;
2350 sprintf(msg+strlen(msg),"%02x%02x%02x%02x%02x%02x ",
2351 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2352 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
2353 sprintf(msg+strlen(msg),"%-4d", (int)pEntry->Aid);
2354 sprintf(msg+strlen(msg),"%-4d", (int)pEntry->PsMode);
2355 sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.LastDataPacketTime*/); // ToDo
2356 sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalRxByteCount*/); // ToDo
2357 sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalTxByteCount*/); // ToDo
2358 sprintf(msg+strlen(msg),"%-6d",RateIdToMbps[pAd->MacTab.Content[i].CurrTxRate]);
2359 sprintf(msg+strlen(msg),"%-6d\n",0/*RateIdToMbps[pAd->MacTab.Content[i].LastTxRate]*/); // ToDo
2360 }
2361 }
2362 // for compatible with old API just do the printk to console
2363 //wrq->u.data.length = strlen(msg);
2364 //if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
2365 {
2366 DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
2367 }
2368
2369 kfree(msg);
2370}
2371#endif // UCOS //
2372
2373#ifdef DOT11_N_SUPPORT
2374INT Set_BASetup_Proc(
2375 IN PRTMP_ADAPTER pAd,
2376 IN PUCHAR arg)
2377{
2378 UCHAR mac[6], tid;
2379 char *token, sepValue[] = ":", DASH = '-';
2380 INT i;
2381 MAC_TABLE_ENTRY *pEntry;
2382
2383/*
2384 The BASetup inupt string format should be xx:xx:xx:xx:xx:xx-d,
2385 =>The six 2 digit hex-decimal number previous are the Mac address,
2386 =>The seventh decimal number is the tid value.
2387*/
2388 //printk("\n%s\n", arg);
2389
2390 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
2391 return FALSE;
2392
2393 token = strchr(arg, DASH);
2394 if ((token != NULL) && (strlen(token)>1))
2395 {
2396 tid = simple_strtol((token+1), 0, 10);
2397 if (tid > 15)
2398 return FALSE;
2399
2400 *token = '\0';
2401 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2402 {
2403 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2404 return FALSE;
2405 AtoH(token, (PUCHAR)(&mac[i]), 1);
2406 }
2407 if(i != 6)
2408 return FALSE;
2409
2410 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", mac[0], mac[1],
2411 mac[2], mac[3], mac[4], mac[5], tid);
2412
2413 pEntry = MacTableLookup(pAd, mac);
2414
2415 if (pEntry) {
2416 printk("\nSetup BA Session: Tid = %d\n", tid);
2417 BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE);
2418 }
2419
2420 return TRUE;
2421 }
2422
2423 return FALSE;
2424
2425}
2426
2427INT Set_BADecline_Proc(
2428 IN PRTMP_ADAPTER pAd,
2429 IN PUCHAR arg)
2430{
2431 ULONG bBADecline;
2432
2433 bBADecline = simple_strtol(arg, 0, 10);
2434
2435 if (bBADecline == 0)
2436 {
2437 pAd->CommonCfg.bBADecline = FALSE;
2438 }
2439 else if (bBADecline == 1)
2440 {
2441 pAd->CommonCfg.bBADecline = TRUE;
2442 }
2443 else
2444 {
2445 return FALSE; //Invalid argument
2446 }
2447
2448 DBGPRINT(RT_DEBUG_TRACE, ("Set_BADecline_Proc::(BADecline=%d)\n", pAd->CommonCfg.bBADecline));
2449
2450 return TRUE;
2451}
2452
2453INT Set_BAOriTearDown_Proc(
2454 IN PRTMP_ADAPTER pAd,
2455 IN PUCHAR arg)
2456{
2457 UCHAR mac[6], tid;
2458 char *token, sepValue[] = ":", DASH = '-';
2459 INT i;
2460 MAC_TABLE_ENTRY *pEntry;
2461
2462 //printk("\n%s\n", arg);
2463/*
2464 The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
2465 =>The six 2 digit hex-decimal number previous are the Mac address,
2466 =>The seventh decimal number is the tid value.
2467*/
2468 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
2469 return FALSE;
2470
2471 token = strchr(arg, DASH);
2472 if ((token != NULL) && (strlen(token)>1))
2473 {
2474 tid = simple_strtol((token+1), 0, 10);
2475 if (tid > NUM_OF_TID)
2476 return FALSE;
2477
2478 *token = '\0';
2479 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2480 {
2481 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2482 return FALSE;
2483 AtoH(token, (PUCHAR)(&mac[i]), 1);
2484 }
2485 if(i != 6)
2486 return FALSE;
2487
2488 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
2489 mac[2], mac[3], mac[4], mac[5], tid);
2490
2491 pEntry = MacTableLookup(pAd, mac);
2492
2493 if (pEntry) {
2494 printk("\nTear down Ori BA Session: Tid = %d\n", tid);
2495 BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE);
2496 }
2497
2498 return TRUE;
2499 }
2500
2501 return FALSE;
2502
2503}
2504
2505INT Set_BARecTearDown_Proc(
2506 IN PRTMP_ADAPTER pAd,
2507 IN PUCHAR arg)
2508{
2509 UCHAR mac[6], tid;
2510 char *token, sepValue[] = ":", DASH = '-';
2511 INT i;
2512 MAC_TABLE_ENTRY *pEntry;
2513
2514 //printk("\n%s\n", arg);
2515/*
2516 The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
2517 =>The six 2 digit hex-decimal number previous are the Mac address,
2518 =>The seventh decimal number is the tid value.
2519*/
2520 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
2521 return FALSE;
2522
2523 token = strchr(arg, DASH);
2524 if ((token != NULL) && (strlen(token)>1))
2525 {
2526 tid = simple_strtol((token+1), 0, 10);
2527 if (tid > NUM_OF_TID)
2528 return FALSE;
2529
2530 *token = '\0';
2531 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2532 {
2533 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2534 return FALSE;
2535 AtoH(token, (PUCHAR)(&mac[i]), 1);
2536 }
2537 if(i != 6)
2538 return FALSE;
2539
2540 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
2541 mac[2], mac[3], mac[4], mac[5], tid);
2542
2543 pEntry = MacTableLookup(pAd, mac);
2544
2545 if (pEntry) {
2546 printk("\nTear down Rec BA Session: Tid = %d\n", tid);
2547 BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE);
2548 }
2549
2550 return TRUE;
2551 }
2552
2553 return FALSE;
2554
2555}
2556
2557INT Set_HtBw_Proc(
2558 IN PRTMP_ADAPTER pAd,
2559 IN PUCHAR arg)
2560{
2561 ULONG HtBw;
2562
2563 HtBw = simple_strtol(arg, 0, 10);
2564 if (HtBw == BW_40)
2565 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
2566 else if (HtBw == BW_20)
2567 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
2568 else
2569 return FALSE; //Invalid argument
2570
2571 SetCommonHT(pAd);
2572
2573 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBw_Proc::(HtBw=%d)\n", pAd->CommonCfg.RegTransmitSetting.field.BW));
2574
2575 return TRUE;
2576}
2577
2578INT Set_HtMcs_Proc(
2579 IN PRTMP_ADAPTER pAd,
2580 IN PUCHAR arg)
2581{
2582 ULONG HtMcs, Mcs_tmp;
2583#ifdef CONFIG_STA_SUPPORT
2584 BOOLEAN bAutoRate = FALSE;
2585#endif // CONFIG_STA_SUPPORT //
2586
2587 Mcs_tmp = simple_strtol(arg, 0, 10);
2588
2589 if (Mcs_tmp <= 15 || Mcs_tmp == 32)
2590 HtMcs = Mcs_tmp;
2591 else
2592 HtMcs = MCS_AUTO;
2593
2594#ifdef CONFIG_STA_SUPPORT
2595 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2596 {
2597 pAd->StaCfg.DesiredTransmitSetting.field.MCS = HtMcs;
2598 pAd->StaCfg.bAutoTxRateSwitch = (HtMcs == MCS_AUTO) ? TRUE:FALSE;
2599 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(HtMcs=%d, bAutoTxRateSwitch = %d)\n",
2600 pAd->StaCfg.DesiredTransmitSetting.field.MCS, pAd->StaCfg.bAutoTxRateSwitch));
2601
2602 if ((pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED) ||
2603 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE < MODE_HTMIX))
2604 {
2605 if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
2606 (HtMcs >= 0 && HtMcs <= 3) &&
2607 (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_CCK))
2608 {
2609 RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs] * 1000000));
2610 }
2611 else if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
2612 (HtMcs >= 0 && HtMcs <= 7) &&
2613 (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_OFDM))
2614 {
2615 RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs+4] * 1000000));
2616 }
2617 else
2618 bAutoRate = TRUE;
2619
2620 if (bAutoRate)
2621 {
2622 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2623 RTMPSetDesiredRates(pAd, -1);
2624 }
2625 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(FixedTxMode=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode));
2626 }
2627 if (ADHOC_ON(pAd))
2628 return TRUE;
2629 }
2630#endif // CONFIG_STA_SUPPORT //
2631
2632 SetCommonHT(pAd);
2633
2634 return TRUE;
2635}
2636
2637INT Set_HtGi_Proc(
2638 IN PRTMP_ADAPTER pAd,
2639 IN PUCHAR arg)
2640{
2641 ULONG HtGi;
2642
2643 HtGi = simple_strtol(arg, 0, 10);
2644
2645 if ( HtGi == GI_400)
2646 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
2647 else if ( HtGi == GI_800 )
2648 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
2649 else
2650 return FALSE; //Invalid argument
2651
2652 SetCommonHT(pAd);
2653
2654 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtGi_Proc::(ShortGI=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.ShortGI));
2655
2656 return TRUE;
2657}
2658
2659
2660INT Set_HtTxBASize_Proc(
2661 IN PRTMP_ADAPTER pAd,
2662 IN PUCHAR arg)
2663{
2664 UCHAR Size;
2665
2666 Size = simple_strtol(arg, 0, 10);
2667
2668 if (Size <=0 || Size >=64)
2669 {
2670 Size = 8;
2671 }
2672 pAd->CommonCfg.TxBASize = Size-1;
2673 DBGPRINT(RT_DEBUG_ERROR, ("Set_HtTxBASize ::(TxBASize= %d)\n", Size));
2674
2675 return TRUE;
2676}
2677
2678
2679INT Set_HtOpMode_Proc(
2680 IN PRTMP_ADAPTER pAd,
2681 IN PUCHAR arg)
2682{
2683
2684 ULONG Value;
2685
2686 Value = simple_strtol(arg, 0, 10);
2687
2688 if (Value == HTMODE_GF)
2689 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
2690 else if ( Value == HTMODE_MM )
2691 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
2692 else
2693 return FALSE; //Invalid argument
2694
2695 SetCommonHT(pAd);
2696
2697 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtOpMode_Proc::(HtOpMode=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.HTMODE));
2698
2699 return TRUE;
2700
2701}
2702
2703INT Set_HtStbc_Proc(
2704 IN PRTMP_ADAPTER pAd,
2705 IN PUCHAR arg)
2706{
2707
2708 ULONG Value;
2709
2710 Value = simple_strtol(arg, 0, 10);
2711
2712 if (Value == STBC_USE)
2713 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
2714 else if ( Value == STBC_NONE )
2715 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
2716 else
2717 return FALSE; //Invalid argument
2718
2719 SetCommonHT(pAd);
2720
2721 DBGPRINT(RT_DEBUG_TRACE, ("Set_Stbc_Proc::(HtStbc=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.STBC));
2722
2723 return TRUE;
2724}
2725
2726INT Set_HtHtc_Proc(
2727 IN PRTMP_ADAPTER pAd,
2728 IN PUCHAR arg)
2729{
2730
2731 ULONG Value;
2732
2733 Value = simple_strtol(arg, 0, 10);
2734 if (Value == 0)
2735 pAd->HTCEnable = FALSE;
2736 else if ( Value ==1 )
2737 pAd->HTCEnable = TRUE;
2738 else
2739 return FALSE; //Invalid argument
2740
2741 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtHtc_Proc::(HtHtc=%d)\n",pAd->HTCEnable));
2742
2743 return TRUE;
2744}
2745
2746INT Set_HtExtcha_Proc(
2747 IN PRTMP_ADAPTER pAd,
2748 IN PUCHAR arg)
2749{
2750
2751 ULONG Value;
2752
2753 Value = simple_strtol(arg, 0, 10);
2754
2755 if (Value == 0)
2756 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
2757 else if ( Value ==1 )
2758 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
2759 else
2760 return FALSE; //Invalid argument
2761
2762 SetCommonHT(pAd);
2763
2764 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtExtcha_Proc::(HtExtcha=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.EXTCHA));
2765
2766 return TRUE;
2767}
2768
2769INT Set_HtMpduDensity_Proc(
2770 IN PRTMP_ADAPTER pAd,
2771 IN PUCHAR arg)
2772{
2773 ULONG Value;
2774
2775 Value = simple_strtol(arg, 0, 10);
2776
2777 if (Value <=7 && Value >= 0)
2778 pAd->CommonCfg.BACapability.field.MpduDensity = Value;
2779 else
2780 pAd->CommonCfg.BACapability.field.MpduDensity = 4;
2781
2782 SetCommonHT(pAd);
2783
2784 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMpduDensity_Proc::(HtMpduDensity=%d)\n",pAd->CommonCfg.BACapability.field.MpduDensity));
2785
2786 return TRUE;
2787}
2788
2789INT Set_HtBaWinSize_Proc(
2790 IN PRTMP_ADAPTER pAd,
2791 IN PUCHAR arg)
2792{
2793 ULONG Value;
2794
2795 Value = simple_strtol(arg, 0, 10);
2796
2797
2798 if (Value >=1 && Value <= 64)
2799 {
2800 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
2801 pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
2802 }
2803 else
2804 {
2805 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
2806 pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
2807 }
2808
2809 SetCommonHT(pAd);
2810
2811 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBaWinSize_Proc::(HtBaWinSize=%d)\n",pAd->CommonCfg.BACapability.field.RxBAWinLimit));
2812
2813 return TRUE;
2814}
2815
2816INT Set_HtRdg_Proc(
2817 IN PRTMP_ADAPTER pAd,
2818 IN PUCHAR arg)
2819{
2820 ULONG Value;
2821
2822 Value = simple_strtol(arg, 0, 10);
2823
2824 if (Value == 0)
2825 pAd->CommonCfg.bRdg = FALSE;
2826 else if ( Value ==1 )
2827 {
2828 pAd->HTCEnable = TRUE;
2829 pAd->CommonCfg.bRdg = TRUE;
2830 }
2831 else
2832 return FALSE; //Invalid argument
2833
2834 SetCommonHT(pAd);
2835
2836 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtRdg_Proc::(HtRdg=%d)\n",pAd->CommonCfg.bRdg));
2837
2838 return TRUE;
2839}
2840
2841INT Set_HtLinkAdapt_Proc(
2842 IN PRTMP_ADAPTER pAd,
2843 IN PUCHAR arg)
2844{
2845 ULONG Value;
2846
2847 Value = simple_strtol(arg, 0, 10);
2848 if (Value == 0)
2849 pAd->bLinkAdapt = FALSE;
2850 else if ( Value ==1 )
2851 {
2852 pAd->HTCEnable = TRUE;
2853 pAd->bLinkAdapt = TRUE;
2854 }
2855 else
2856 return FALSE; //Invalid argument
2857
2858 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtLinkAdapt_Proc::(HtLinkAdapt=%d)\n",pAd->bLinkAdapt));
2859
2860 return TRUE;
2861}
2862
2863INT Set_HtAmsdu_Proc(
2864 IN PRTMP_ADAPTER pAd,
2865 IN PUCHAR arg)
2866{
2867 ULONG Value;
2868
2869 Value = simple_strtol(arg, 0, 10);
2870 if (Value == 0)
2871 pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
2872 else if ( Value == 1 )
2873 pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
2874 else
2875 return FALSE; //Invalid argument
2876
2877 SetCommonHT(pAd);
2878
2879 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAmsdu_Proc::(HtAmsdu=%d)\n",pAd->CommonCfg.BACapability.field.AmsduEnable));
2880
2881 return TRUE;
2882}
2883
2884INT Set_HtAutoBa_Proc(
2885 IN PRTMP_ADAPTER pAd,
2886 IN PUCHAR arg)
2887{
2888 ULONG Value;
2889
2890 Value = simple_strtol(arg, 0, 10);
2891 if (Value == 0)
2892 pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
2893 else if (Value == 1)
2894 pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
2895 else
2896 return FALSE; //Invalid argument
2897
2898 pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
2899 SetCommonHT(pAd);
2900
2901 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAutoBa_Proc::(HtAutoBa=%d)\n",pAd->CommonCfg.BACapability.field.AutoBA));
2902
2903 return TRUE;
2904
2905}
2906
2907INT Set_HtProtect_Proc(
2908 IN PRTMP_ADAPTER pAd,
2909 IN PUCHAR arg)
2910{
2911 ULONG Value;
2912
2913 Value = simple_strtol(arg, 0, 10);
2914 if (Value == 0)
2915 pAd->CommonCfg.bHTProtect = FALSE;
2916 else if (Value == 1)
2917 pAd->CommonCfg.bHTProtect = TRUE;
2918 else
2919 return FALSE; //Invalid argument
2920
2921 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtProtect_Proc::(HtProtect=%d)\n",pAd->CommonCfg.bHTProtect));
2922
2923 return TRUE;
2924}
2925
2926INT Set_SendPSMPAction_Proc(
2927 IN PRTMP_ADAPTER pAd,
2928 IN PUCHAR arg)
2929{
2930 UCHAR mac[6], mode;
2931 char *token, sepValue[] = ":", DASH = '-';
2932 INT i;
2933 MAC_TABLE_ENTRY *pEntry;
2934
2935 //printk("\n%s\n", arg);
2936/*
2937 The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
2938 =>The six 2 digit hex-decimal number previous are the Mac address,
2939 =>The seventh decimal number is the mode value.
2940*/
2941 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and mode value in decimal format.
2942 return FALSE;
2943
2944 token = strchr(arg, DASH);
2945 if ((token != NULL) && (strlen(token)>1))
2946 {
2947 mode = simple_strtol((token+1), 0, 10);
2948 if (mode > MMPS_ENABLE)
2949 return FALSE;
2950
2951 *token = '\0';
2952 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2953 {
2954 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2955 return FALSE;
2956 AtoH(token, (PUCHAR)(&mac[i]), 1);
2957 }
2958 if(i != 6)
2959 return FALSE;
2960
2961 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
2962 mac[2], mac[3], mac[4], mac[5], mode);
2963
2964 pEntry = MacTableLookup(pAd, mac);
2965
2966 if (pEntry) {
2967 printk("\nSendPSMPAction MIPS mode = %d\n", mode);
2968 SendPSMPAction(pAd, pEntry->Aid, mode);
2969 }
2970
2971 return TRUE;
2972 }
2973
2974 return FALSE;
2975
2976
2977}
2978
2979INT Set_HtMIMOPSmode_Proc(
2980 IN PRTMP_ADAPTER pAd,
2981 IN PUCHAR arg)
2982{
2983 ULONG Value;
2984
2985 Value = simple_strtol(arg, 0, 10);
2986
2987 if (Value <=3 && Value >= 0)
2988 pAd->CommonCfg.BACapability.field.MMPSmode = Value;
2989 else
2990 pAd->CommonCfg.BACapability.field.MMPSmode = 3;
2991
2992 SetCommonHT(pAd);
2993
2994 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMIMOPSmode_Proc::(MIMOPS mode=%d)\n",pAd->CommonCfg.BACapability.field.MMPSmode));
2995
2996 return TRUE;
2997}
2998
2999
3000INT Set_ForceShortGI_Proc(
3001 IN PRTMP_ADAPTER pAd,
3002 IN PUCHAR arg)
3003{
3004 ULONG Value;
3005
3006 Value = simple_strtol(arg, 0, 10);
3007 if (Value == 0)
3008 pAd->WIFItestbed.bShortGI = FALSE;
3009 else if (Value == 1)
3010 pAd->WIFItestbed.bShortGI = TRUE;
3011 else
3012 return FALSE; //Invalid argument
3013
3014 SetCommonHT(pAd);
3015
3016 DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceShortGI_Proc::(ForceShortGI=%d)\n", pAd->WIFItestbed.bShortGI));
3017
3018 return TRUE;
3019}
3020
3021
3022
3023INT Set_ForceGF_Proc(
3024 IN PRTMP_ADAPTER pAd,
3025 IN PUCHAR arg)
3026{
3027 ULONG Value;
3028
3029 Value = simple_strtol(arg, 0, 10);
3030 if (Value == 0)
3031 pAd->WIFItestbed.bGreenField = FALSE;
3032 else if (Value == 1)
3033 pAd->WIFItestbed.bGreenField = TRUE;
3034 else
3035 return FALSE; //Invalid argument
3036
3037 SetCommonHT(pAd);
3038
3039 DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceGF_Proc::(ForceGF=%d)\n", pAd->WIFItestbed.bGreenField));
3040
3041 return TRUE;
3042}
3043
3044INT Set_HtMimoPs_Proc(
3045 IN PRTMP_ADAPTER pAd,
3046 IN PUCHAR arg)
3047{
3048 ULONG Value;
3049
3050 Value = simple_strtol(arg, 0, 10);
3051 if (Value == 0)
3052 pAd->CommonCfg.bMIMOPSEnable = FALSE;
3053 else if (Value == 1)
3054 pAd->CommonCfg.bMIMOPSEnable = TRUE;
3055 else
3056 return FALSE; //Invalid argument
3057
3058 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMimoPs_Proc::(HtMimoPs=%d)\n",pAd->CommonCfg.bMIMOPSEnable));
3059
3060 return TRUE;
3061}
3062#endif // DOT11_N_SUPPORT //
3063
3064
3065#ifdef DOT11_N_SUPPORT
3066INT SetCommonHT(
3067 IN PRTMP_ADAPTER pAd)
3068{
3069 OID_SET_HT_PHYMODE SetHT;
3070
3071 if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
3072 return FALSE;
3073
3074 SetHT.PhyMode = pAd->CommonCfg.PhyMode;
3075 SetHT.TransmitNo = ((UCHAR)pAd->Antenna.field.TxPath);
3076 SetHT.HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
3077 SetHT.ExtOffset = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
3078 SetHT.MCS = MCS_AUTO;
3079 SetHT.BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW;
3080 SetHT.STBC = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC;
3081 SetHT.SHORTGI = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
3082
3083 RTMPSetHT(pAd, &SetHT);
3084
3085 return TRUE;
3086}
3087#endif // DOT11_N_SUPPORT //
3088
3089INT Set_FixedTxMode_Proc(
3090 IN PRTMP_ADAPTER pAd,
3091 IN PUCHAR arg)
3092{
3093 UCHAR fix_tx_mode = FIXED_TXMODE_HT;
3094
3095 if (strcmp(arg, "OFDM") == 0 || strcmp(arg, "ofdm") == 0)
3096 {
3097 fix_tx_mode = FIXED_TXMODE_OFDM;
3098 }
3099 else if (strcmp(arg, "CCK") == 0 || strcmp(arg, "cck") == 0)
3100 {
3101 fix_tx_mode = FIXED_TXMODE_CCK;
3102 }
3103
3104#ifdef CONFIG_STA_SUPPORT
3105 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3106 pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
3107#endif // CONFIG_STA_SUPPORT //
3108
3109 DBGPRINT(RT_DEBUG_TRACE, ("Set_FixedTxMode_Proc::(FixedTxMode=%d)\n", fix_tx_mode));
3110
3111 return TRUE;
3112}
3113
3114#ifdef CONFIG_APSTA_MIXED_SUPPORT
3115INT Set_OpMode_Proc(
3116 IN PRTMP_ADAPTER pAd,
3117 IN PUCHAR arg)
3118{
3119 ULONG Value;
3120
3121 Value = simple_strtol(arg, 0, 10);
3122
3123#ifdef RT2870
3124 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
3125#endif // RT2870 //
3126 {
3127 DBGPRINT(RT_DEBUG_ERROR, ("Can not switch operate mode on interface up !! \n"));
3128 return FALSE;
3129 }
3130
3131 if (Value == 0)
3132 pAd->OpMode = OPMODE_STA;
3133 else if (Value == 1)
3134 pAd->OpMode = OPMODE_AP;
3135 else
3136 return FALSE; //Invalid argument
3137
3138 DBGPRINT(RT_DEBUG_TRACE, ("Set_OpMode_Proc::(OpMode=%s)\n", pAd->OpMode == 1 ? "AP Mode" : "STA Mode"));
3139
3140 return TRUE;
3141}
3142#endif // CONFIG_APSTA_MIXED_SUPPORT //
3143
3144
3145/////////////////////////////////////////////////////////////////////////
3146PCHAR RTMPGetRalinkAuthModeStr(
3147 IN NDIS_802_11_AUTHENTICATION_MODE authMode)
3148{
3149 switch(authMode)
3150 {
3151 case Ndis802_11AuthModeOpen:
3152 return "OPEN";
3153 case Ndis802_11AuthModeWPAPSK:
3154 return "WPAPSK";
3155 case Ndis802_11AuthModeShared:
3156 return "SHARED";
3157 case Ndis802_11AuthModeWPA:
3158 return "WPA";
3159 case Ndis802_11AuthModeWPA2:
3160 return "WPA2";
3161 case Ndis802_11AuthModeWPA2PSK:
3162 return "WPA2PSK";
3163 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
3164 return "WPAPSKWPA2PSK";
3165 case Ndis802_11AuthModeWPA1WPA2:
3166 return "WPA1WPA2";
3167 case Ndis802_11AuthModeWPANone:
3168 return "WPANONE";
3169 default:
3170 return "UNKNOW";
3171 }
3172}
3173
3174PCHAR RTMPGetRalinkEncryModeStr(
3175 IN USHORT encryMode)
3176{
3177 switch(encryMode)
3178 {
3179 case Ndis802_11WEPDisabled:
3180 return "NONE";
3181 case Ndis802_11WEPEnabled:
3182 return "WEP";
3183 case Ndis802_11Encryption2Enabled:
3184 return "TKIP";
3185 case Ndis802_11Encryption3Enabled:
3186 return "AES";
3187 case Ndis802_11Encryption4Enabled:
3188 return "TKIPAES";
3189 default:
3190 return "UNKNOW";
3191 }
3192}
3193
3194INT RTMPShowCfgValue(
3195 IN PRTMP_ADAPTER pAd,
3196 IN PUCHAR pName,
3197 IN PUCHAR pBuf)
3198{
3199 INT Status = 0;
3200
3201 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++)
3202 {
3203 if (!strcmp(pName, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name))
3204 {
3205 if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->show_proc(pAd, pBuf))
3206 Status = -EINVAL;
3207 break; //Exit for loop.
3208 }
3209 }
3210
3211 if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name == NULL)
3212 {
3213 sprintf(pBuf, "\n");
3214 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++)
3215 sprintf(pBuf, "%s%s\n", pBuf, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name);
3216 }
3217
3218 return Status;
3219}
3220
3221INT Show_SSID_Proc(
3222 IN PRTMP_ADAPTER pAd,
3223 OUT PUCHAR pBuf)
3224{
3225
3226#ifdef CONFIG_STA_SUPPORT
3227 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3228 sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid);
3229#endif // CONFIG_STA_SUPPORT //
3230 return 0;
3231}
3232
3233INT Show_WirelessMode_Proc(
3234 IN PRTMP_ADAPTER pAd,
3235 OUT PUCHAR pBuf)
3236{
3237 switch(pAd->CommonCfg.PhyMode)
3238 {
3239 case PHY_11BG_MIXED:
3240 sprintf(pBuf, "\t11B/G");
3241 break;
3242 case PHY_11B:
3243 sprintf(pBuf, "\t11B");
3244 break;
3245 case PHY_11A:
3246 sprintf(pBuf, "\t11A");
3247 break;
3248 case PHY_11ABG_MIXED:
3249 sprintf(pBuf, "\t11A/B/G");
3250 break;
3251 case PHY_11G:
3252 sprintf(pBuf, "\t11G");
3253 break;
3254#ifdef DOT11_N_SUPPORT
3255 case PHY_11ABGN_MIXED:
3256 sprintf(pBuf, "\t11A/B/G/N");
3257 break;
3258 case PHY_11N_2_4G:
3259 sprintf(pBuf, "\t11N only with 2.4G");
3260 break;
3261 case PHY_11GN_MIXED:
3262 sprintf(pBuf, "\t11G/N");
3263 break;
3264 case PHY_11AN_MIXED:
3265 sprintf(pBuf, "\t11A/N");
3266 break;
3267 case PHY_11BGN_MIXED:
3268 sprintf(pBuf, "\t11B/G/N");
3269 break;
3270 case PHY_11AGN_MIXED:
3271 sprintf(pBuf, "\t11A/G/N");
3272 break;
3273 case PHY_11N_5G:
3274 sprintf(pBuf, "\t11N only with 5G");
3275 break;
3276#endif // DOT11_N_SUPPORT //
3277 default:
3278 sprintf(pBuf, "\tUnknow Value(%d)", pAd->CommonCfg.PhyMode);
3279 break;
3280 }
3281 return 0;
3282}
3283
3284
3285INT Show_TxBurst_Proc(
3286 IN PRTMP_ADAPTER pAd,
3287 OUT PUCHAR pBuf)
3288{
3289 sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE");
3290 return 0;
3291}
3292
3293INT Show_TxPreamble_Proc(
3294 IN PRTMP_ADAPTER pAd,
3295 OUT PUCHAR pBuf)
3296{
3297 switch(pAd->CommonCfg.TxPreamble)
3298 {
3299 case Rt802_11PreambleShort:
3300 sprintf(pBuf, "\tShort");
3301 break;
3302 case Rt802_11PreambleLong:
3303 sprintf(pBuf, "\tLong");
3304 break;
3305 case Rt802_11PreambleAuto:
3306 sprintf(pBuf, "\tAuto");
3307 break;
3308 default:
3309 sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.TxPreamble);
3310 break;
3311 }
3312
3313 return 0;
3314}
3315
3316INT Show_TxPower_Proc(
3317 IN PRTMP_ADAPTER pAd,
3318 OUT PUCHAR pBuf)
3319{
3320 sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage);
3321 return 0;
3322}
3323
3324INT Show_Channel_Proc(
3325 IN PRTMP_ADAPTER pAd,
3326 OUT PUCHAR pBuf)
3327{
3328 sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel);
3329 return 0;
3330}
3331
3332INT Show_BGProtection_Proc(
3333 IN PRTMP_ADAPTER pAd,
3334 OUT PUCHAR pBuf)
3335{
3336 switch(pAd->CommonCfg.UseBGProtection)
3337 {
3338 case 1: //Always On
3339 sprintf(pBuf, "\tON");
3340 break;
3341 case 2: //Always OFF
3342 sprintf(pBuf, "\tOFF");
3343 break;
3344 case 0: //AUTO
3345 sprintf(pBuf, "\tAuto");
3346 break;
3347 default:
3348 sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.UseBGProtection);
3349 break;
3350 }
3351 return 0;
3352}
3353
3354INT Show_RTSThreshold_Proc(
3355 IN PRTMP_ADAPTER pAd,
3356 OUT PUCHAR pBuf)
3357{
3358 sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold);
3359 return 0;
3360}
3361
3362INT Show_FragThreshold_Proc(
3363 IN PRTMP_ADAPTER pAd,
3364 OUT PUCHAR pBuf)
3365{
3366 sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold);
3367 return 0;
3368}
3369
3370#ifdef DOT11_N_SUPPORT
3371INT Show_HtBw_Proc(
3372 IN PRTMP_ADAPTER pAd,
3373 OUT PUCHAR pBuf)
3374{
3375 if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
3376 {
3377 sprintf(pBuf, "\t40 MHz");
3378 }
3379 else
3380 {
3381 sprintf(pBuf, "\t20 MHz");
3382 }
3383 return 0;
3384}
3385
3386INT Show_HtMcs_Proc(
3387 IN PRTMP_ADAPTER pAd,
3388 OUT PUCHAR pBuf)
3389{
3390
3391#ifdef CONFIG_STA_SUPPORT
3392 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3393 sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS);
3394#endif // CONFIG_STA_SUPPORT //
3395 return 0;
3396}
3397
3398INT Show_HtGi_Proc(
3399 IN PRTMP_ADAPTER pAd,
3400 OUT PUCHAR pBuf)
3401{
3402 switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI)
3403 {
3404 case GI_400:
3405 sprintf(pBuf, "\tGI_400");
3406 break;
3407 case GI_800:
3408 sprintf(pBuf, "\tGI_800");
3409 break;
3410 default:
3411 sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.ShortGI);
3412 break;
3413 }
3414 return 0;
3415}
3416
3417INT Show_HtOpMode_Proc(
3418 IN PRTMP_ADAPTER pAd,
3419 OUT PUCHAR pBuf)
3420{
3421 switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE)
3422 {
3423 case HTMODE_GF:
3424 sprintf(pBuf, "\tGF");
3425 break;
3426 case HTMODE_MM:
3427 sprintf(pBuf, "\tMM");
3428 break;
3429 default:
3430 sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.HTMODE);
3431 break;
3432 }
3433 return 0;
3434}
3435
3436INT Show_HtExtcha_Proc(
3437 IN PRTMP_ADAPTER pAd,
3438 OUT PUCHAR pBuf)
3439{
3440 switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA)
3441 {
3442 case EXTCHA_BELOW:
3443 sprintf(pBuf, "\tBelow");
3444 break;
3445 case EXTCHA_ABOVE:
3446 sprintf(pBuf, "\tAbove");
3447 break;
3448 default:
3449 sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.EXTCHA);
3450 break;
3451 }
3452 return 0;
3453}
3454
3455
3456INT Show_HtMpduDensity_Proc(
3457 IN PRTMP_ADAPTER pAd,
3458 OUT PUCHAR pBuf)
3459{
3460 sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity);
3461 return 0;
3462}
3463
3464INT Show_HtBaWinSize_Proc(
3465 IN PRTMP_ADAPTER pAd,
3466 OUT PUCHAR pBuf)
3467{
3468 sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit);
3469 return 0;
3470}
3471
3472INT Show_HtRdg_Proc(
3473 IN PRTMP_ADAPTER pAd,
3474 OUT PUCHAR pBuf)
3475{
3476 sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE");
3477 return 0;
3478}
3479
3480INT Show_HtAmsdu_Proc(
3481 IN PRTMP_ADAPTER pAd,
3482 OUT PUCHAR pBuf)
3483{
3484 sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE");
3485 return 0;
3486}
3487
3488INT Show_HtAutoBa_Proc(
3489 IN PRTMP_ADAPTER pAd,
3490 OUT PUCHAR pBuf)
3491{
3492 sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE");
3493 return 0;
3494}
3495#endif // DOT11_N_SUPPORT //
3496
3497INT Show_CountryRegion_Proc(
3498 IN PRTMP_ADAPTER pAd,
3499 OUT PUCHAR pBuf)
3500{
3501 sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion);
3502 return 0;
3503}
3504
3505INT Show_CountryRegionABand_Proc(
3506 IN PRTMP_ADAPTER pAd,
3507 OUT PUCHAR pBuf)
3508{
3509 sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand);
3510 return 0;
3511}
3512
3513INT Show_CountryCode_Proc(
3514 IN PRTMP_ADAPTER pAd,
3515 OUT PUCHAR pBuf)
3516{
3517 sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode);
3518 return 0;
3519}
3520
3521#ifdef AGGREGATION_SUPPORT
3522INT Show_PktAggregate_Proc(
3523 IN PRTMP_ADAPTER pAd,
3524 OUT PUCHAR pBuf)
3525{
3526 sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE");
3527 return 0;
3528}
3529#endif // AGGREGATION_SUPPORT //
3530
3531#ifdef WMM_SUPPORT
3532INT Show_WmmCapable_Proc(
3533 IN PRTMP_ADAPTER pAd,
3534 OUT PUCHAR pBuf)
3535{
3536
3537#ifdef CONFIG_STA_SUPPORT
3538 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3539 sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE");
3540#endif // CONFIG_STA_SUPPORT //
3541
3542 return 0;
3543}
3544#endif // WMM_SUPPORT //
3545
3546INT Show_IEEE80211H_Proc(
3547 IN PRTMP_ADAPTER pAd,
3548 OUT PUCHAR pBuf)
3549{
3550 sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE");
3551 return 0;
3552}
3553
3554#ifdef CONFIG_STA_SUPPORT
3555INT Show_NetworkType_Proc(
3556 IN PRTMP_ADAPTER pAd,
3557 OUT PUCHAR pBuf)
3558{
3559 switch(pAd->StaCfg.BssType)
3560 {
3561 case BSS_ADHOC:
3562 sprintf(pBuf, "\tAdhoc");
3563 break;
3564 case BSS_INFRA:
3565 sprintf(pBuf, "\tInfra");
3566 break;
3567 case BSS_ANY:
3568 sprintf(pBuf, "\tAny");
3569 break;
3570 case BSS_MONITOR:
3571 sprintf(pBuf, "\tMonitor");
3572 break;
3573 default:
3574 sprintf(pBuf, "\tUnknow Value(%d)", pAd->StaCfg.BssType);
3575 break;
3576 }
3577 return 0;
3578}
3579#endif // CONFIG_STA_SUPPORT //
3580
3581INT Show_AuthMode_Proc(
3582 IN PRTMP_ADAPTER pAd,
3583 OUT PUCHAR pBuf)
3584{
3585 NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeOpen;
3586
3587#ifdef CONFIG_STA_SUPPORT
3588 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3589 AuthMode = pAd->StaCfg.AuthMode;
3590#endif // CONFIG_STA_SUPPORT //
3591
3592 if ((AuthMode >= Ndis802_11AuthModeOpen) &&
3593 (AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
3594 sprintf(pBuf, "\t%s", RTMPGetRalinkAuthModeStr(AuthMode));
3595 else
3596 sprintf(pBuf, "\tUnknow Value(%d)", AuthMode);
3597
3598 return 0;
3599}
3600
3601INT Show_EncrypType_Proc(
3602 IN PRTMP_ADAPTER pAd,
3603 OUT PUCHAR pBuf)
3604{
3605 NDIS_802_11_WEP_STATUS WepStatus = Ndis802_11WEPDisabled;
3606
3607#ifdef CONFIG_STA_SUPPORT
3608 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3609 WepStatus = pAd->StaCfg.WepStatus;
3610#endif // CONFIG_STA_SUPPORT //
3611
3612 if ((WepStatus >= Ndis802_11WEPEnabled) &&
3613 (WepStatus <= Ndis802_11Encryption4KeyAbsent))
3614 sprintf(pBuf, "\t%s", RTMPGetRalinkEncryModeStr(WepStatus));
3615 else
3616 sprintf(pBuf, "\tUnknow Value(%d)", WepStatus);
3617
3618 return 0;
3619}
3620
3621INT Show_DefaultKeyID_Proc(
3622 IN PRTMP_ADAPTER pAd,
3623 OUT PUCHAR pBuf)
3624{
3625 UCHAR DefaultKeyId = 0;
3626
3627#ifdef CONFIG_STA_SUPPORT
3628 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3629 DefaultKeyId = pAd->StaCfg.DefaultKeyId;
3630#endif // CONFIG_STA_SUPPORT //
3631
3632 sprintf(pBuf, "\t%d", DefaultKeyId);
3633
3634 return 0;
3635}
3636
3637INT Show_WepKey_Proc(
3638 IN PRTMP_ADAPTER pAd,
3639 IN INT KeyIdx,
3640 OUT PUCHAR pBuf)
3641{
3642 UCHAR Key[16] = {0}, KeyLength = 0;
3643 INT index = BSS0;
3644
3645 KeyLength = pAd->SharedKey[index][KeyIdx].KeyLen;
3646 NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength);
3647
3648 //check key string is ASCII or not
3649 if (RTMPCheckStrPrintAble(Key, KeyLength))
3650 sprintf(pBuf, "\t%s", Key);
3651 else
3652 {
3653 int idx;
3654 sprintf(pBuf, "\t");
3655 for (idx = 0; idx < KeyLength; idx++)
3656 sprintf(pBuf+strlen(pBuf), "%02X", Key[idx]);
3657 }
3658 return 0;
3659}
3660
3661INT Show_Key1_Proc(
3662 IN PRTMP_ADAPTER pAd,
3663 OUT PUCHAR pBuf)
3664{
3665 Show_WepKey_Proc(pAd, 0, pBuf);
3666 return 0;
3667}
3668
3669INT Show_Key2_Proc(
3670 IN PRTMP_ADAPTER pAd,
3671 OUT PUCHAR pBuf)
3672{
3673 Show_WepKey_Proc(pAd, 1, pBuf);
3674 return 0;
3675}
3676
3677INT Show_Key3_Proc(
3678 IN PRTMP_ADAPTER pAd,
3679 OUT PUCHAR pBuf)
3680{
3681 Show_WepKey_Proc(pAd, 2, pBuf);
3682 return 0;
3683}
3684
3685INT Show_Key4_Proc(
3686 IN PRTMP_ADAPTER pAd,
3687 OUT PUCHAR pBuf)
3688{
3689 Show_WepKey_Proc(pAd, 3, pBuf);
3690 return 0;
3691}
3692
3693INT Show_WPAPSK_Proc(
3694 IN PRTMP_ADAPTER pAd,
3695 OUT PUCHAR pBuf)
3696{
3697 INT idx;
3698 UCHAR PMK[32] = {0};
3699
3700
3701#ifdef CONFIG_STA_SUPPORT
3702 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3703 NdisMoveMemory(PMK, pAd->StaCfg.PMK, 32);
3704#endif // CONFIG_STA_SUPPORT //
3705
3706 sprintf(pBuf, "\tPMK = ");
3707 for (idx = 0; idx < 32; idx++)
3708 sprintf(pBuf+strlen(pBuf), "%02X", PMK[idx]);
3709
3710 return 0;
3711}
3712
diff --git a/drivers/staging/rt2870/common/cmm_sanity.c b/drivers/staging/rt2870/common/cmm_sanity.c
new file mode 100644
index 00000000000..1e24320177b
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_sanity.c
@@ -0,0 +1,1663 @@
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 break;
691
692 case IE_EXT_SUPP_RATES:
693 if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
694 {
695 NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
696 *pExtRateLen = pEid->Len;
697
698 // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
699 // from ScanTab. We should report as is. And filter out unsupported
700 // rates in MlmeAux.
701 // Check against the supported rates
702 // RTMPCheckRates(pAd, ExtRate, pExtRateLen);
703 }
704 break;
705
706 case IE_ERP:
707 if (pEid->Len == 1)
708 {
709 *pErp = (UCHAR)pEid->Octet[0];
710 }
711 break;
712
713 case IE_AIRONET_CKIP:
714 // 0. Check Aironet IE length, it must be larger or equal to 28
715 // Cisco AP350 used length as 28
716 // Cisco AP12XX used length as 30
717 if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
718 break;
719
720 // 1. Copy CKIP flag byte to buffer for process
721 *pCkipFlag = *(pEid->Octet + 8);
722 break;
723
724 case IE_AP_TX_POWER:
725 // AP Control of Client Transmit Power
726 //0. Check Aironet IE length, it must be 6
727 if (pEid->Len != 0x06)
728 break;
729
730 // Get cell power limit in dBm
731 if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
732 *pAironetCellPowerLimit = *(pEid->Octet + 4);
733 break;
734
735 // WPA2 & 802.11i RSN
736 case IE_RSN:
737 // There is no OUI for version anymore, check the group cipher OUI before copying
738 if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
739 {
740 // Copy to pVIE which will report to microsoft bssid list.
741 Ptr = (PUCHAR) pVIE;
742 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
743 *LengthVIE += (pEid->Len + 2);
744 }
745 break;
746#ifdef CONFIG_STA_SUPPORT
747#ifdef EXT_BUILD_CHANNEL_LIST
748 case IE_COUNTRY:
749 Ptr = (PUCHAR) pVIE;
750 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
751 *LengthVIE += (pEid->Len + 2);
752 break;
753#endif // EXT_BUILD_CHANNEL_LIST //
754#endif // CONFIG_STA_SUPPORT //
755 default:
756 break;
757 }
758
759 Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
760 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
761 }
762
763 // For some 11a AP. it did not have the channel EID, patch here
764#ifdef CONFIG_STA_SUPPORT
765 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
766 {
767 UCHAR LatchRfChannel = MsgChannel;
768 if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0))
769 {
770 if (CtrlChannel != 0)
771 *pChannel = CtrlChannel;
772 else
773 *pChannel = LatchRfChannel;
774 Sanity |= 0x4;
775 }
776 }
777#endif // CONFIG_STA_SUPPORT //
778
779 if (Sanity != 0x7)
780 {
781 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
782 return FALSE;
783 }
784 else
785 {
786 return TRUE;
787 }
788
789}
790
791#ifdef DOT11N_DRAFT3
792/*
793 ==========================================================================
794 Description:
795 MLME message sanity check for some IE addressed in 802.11n d3.03.
796 Return:
797 TRUE if all parameters are OK, FALSE otherwise
798
799 IRQL = DISPATCH_LEVEL
800
801 ==========================================================================
802 */
803BOOLEAN PeerBeaconAndProbeRspSanity2(
804 IN PRTMP_ADAPTER pAd,
805 IN VOID *Msg,
806 IN ULONG MsgLen,
807 OUT UCHAR *RegClass)
808{
809 CHAR *Ptr;
810 PFRAME_802_11 pFrame;
811 PEID_STRUCT pEid;
812 ULONG Length = 0;
813
814 pFrame = (PFRAME_802_11)Msg;
815
816 *RegClass = 0;
817 Ptr = pFrame->Octet;
818 Length += LENGTH_802_11;
819
820 // get timestamp from payload and advance the pointer
821 Ptr += TIMESTAMP_LEN;
822 Length += TIMESTAMP_LEN;
823
824 // get beacon interval from payload and advance the pointer
825 Ptr += 2;
826 Length += 2;
827
828 // get capability info from payload and advance the pointer
829 Ptr += 2;
830 Length += 2;
831
832 pEid = (PEID_STRUCT) Ptr;
833
834 // get variable fields from payload and advance the pointer
835 while ((Length + 2 + pEid->Len) <= MsgLen)
836 {
837 switch(pEid->Eid)
838 {
839 case IE_SUPP_REG_CLASS:
840 if(pEid->Len > 0)
841 {
842 *RegClass = *pEid->Octet;
843 }
844 else
845 {
846 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
847 return FALSE;
848 }
849 break;
850 }
851
852 Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
853 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
854 }
855
856 return TRUE;
857
858}
859#endif // DOT11N_DRAFT3 //
860
861/*
862 ==========================================================================
863 Description:
864 MLME message sanity check
865 Return:
866 TRUE if all parameters are OK, FALSE otherwise
867 ==========================================================================
868 */
869BOOLEAN MlmeScanReqSanity(
870 IN PRTMP_ADAPTER pAd,
871 IN VOID *Msg,
872 IN ULONG MsgLen,
873 OUT UCHAR *pBssType,
874 OUT CHAR Ssid[],
875 OUT UCHAR *pSsidLen,
876 OUT UCHAR *pScanType)
877{
878 MLME_SCAN_REQ_STRUCT *Info;
879
880 Info = (MLME_SCAN_REQ_STRUCT *)(Msg);
881 *pBssType = Info->BssType;
882 *pSsidLen = Info->SsidLen;
883 NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
884 *pScanType = Info->ScanType;
885
886 if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY)
887 && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE
888#ifdef CONFIG_STA_SUPPORT
889 || *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE
890 || *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE
891#endif // CONFIG_STA_SUPPORT //
892 ))
893 {
894 return TRUE;
895 }
896 else
897 {
898 DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
899 return FALSE;
900 }
901}
902
903// IRQL = DISPATCH_LEVEL
904UCHAR ChannelSanity(
905 IN PRTMP_ADAPTER pAd,
906 IN UCHAR channel)
907{
908 int i;
909
910 for (i = 0; i < pAd->ChannelListNum; i ++)
911 {
912 if (channel == pAd->ChannelList[i].Channel)
913 return 1;
914 }
915 return 0;
916}
917
918/*
919 ==========================================================================
920 Description:
921 MLME message sanity check
922 Return:
923 TRUE if all parameters are OK, FALSE otherwise
924
925 IRQL = DISPATCH_LEVEL
926
927 ==========================================================================
928 */
929BOOLEAN PeerDeauthSanity(
930 IN PRTMP_ADAPTER pAd,
931 IN VOID *Msg,
932 IN ULONG MsgLen,
933 OUT PUCHAR pAddr2,
934 OUT USHORT *pReason)
935{
936 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
937
938 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
939 NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
940
941 return TRUE;
942}
943
944/*
945 ==========================================================================
946 Description:
947 MLME message sanity check
948 Return:
949 TRUE if all parameters are OK, FALSE otherwise
950
951 IRQL = DISPATCH_LEVEL
952
953 ==========================================================================
954 */
955BOOLEAN PeerAuthSanity(
956 IN PRTMP_ADAPTER pAd,
957 IN VOID *Msg,
958 IN ULONG MsgLen,
959 OUT PUCHAR pAddr,
960 OUT USHORT *pAlg,
961 OUT USHORT *pSeq,
962 OUT USHORT *pStatus,
963 CHAR *pChlgText)
964{
965 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
966
967 COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2);
968 NdisMoveMemory(pAlg, &pFrame->Octet[0], 2);
969 NdisMoveMemory(pSeq, &pFrame->Octet[2], 2);
970 NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
971
972 if ((*pAlg == Ndis802_11AuthModeOpen)
973#ifdef LEAP_SUPPORT
974 || (*pAlg == CISCO_AuthModeLEAP)
975#endif // LEAP_SUPPORT //
976 )
977 {
978 if (*pSeq == 1 || *pSeq == 2)
979 {
980 return TRUE;
981 }
982 else
983 {
984 DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
985 return FALSE;
986 }
987 }
988 else if (*pAlg == Ndis802_11AuthModeShared)
989 {
990 if (*pSeq == 1 || *pSeq == 4)
991 {
992 return TRUE;
993 }
994 else if (*pSeq == 2 || *pSeq == 3)
995 {
996 NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN);
997 return TRUE;
998 }
999 else
1000 {
1001 DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
1002 return FALSE;
1003 }
1004 }
1005 else
1006 {
1007 DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n"));
1008 return FALSE;
1009 }
1010}
1011
1012/*
1013 ==========================================================================
1014 Description:
1015 MLME message sanity check
1016 Return:
1017 TRUE if all parameters are OK, FALSE otherwise
1018 ==========================================================================
1019 */
1020BOOLEAN MlmeAuthReqSanity(
1021 IN PRTMP_ADAPTER pAd,
1022 IN VOID *Msg,
1023 IN ULONG MsgLen,
1024 OUT PUCHAR pAddr,
1025 OUT ULONG *pTimeout,
1026 OUT USHORT *pAlg)
1027{
1028 MLME_AUTH_REQ_STRUCT *pInfo;
1029
1030 pInfo = (MLME_AUTH_REQ_STRUCT *)Msg;
1031 COPY_MAC_ADDR(pAddr, pInfo->Addr);
1032 *pTimeout = pInfo->Timeout;
1033 *pAlg = pInfo->Alg;
1034
1035 if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen)
1036#ifdef LEAP_SUPPORT
1037 || (*pAlg == CISCO_AuthModeLEAP)
1038#endif // LEAP_SUPPORT //
1039 ) &&
1040 ((*pAddr & 0x01) == 0))
1041 {
1042 return TRUE;
1043 }
1044 else
1045 {
1046 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n"));
1047 return FALSE;
1048 }
1049}
1050
1051/*
1052 ==========================================================================
1053 Description:
1054 MLME message sanity check
1055 Return:
1056 TRUE if all parameters are OK, FALSE otherwise
1057
1058 IRQL = DISPATCH_LEVEL
1059
1060 ==========================================================================
1061 */
1062BOOLEAN MlmeAssocReqSanity(
1063 IN PRTMP_ADAPTER pAd,
1064 IN VOID *Msg,
1065 IN ULONG MsgLen,
1066 OUT PUCHAR pApAddr,
1067 OUT USHORT *pCapabilityInfo,
1068 OUT ULONG *pTimeout,
1069 OUT USHORT *pListenIntv)
1070{
1071 MLME_ASSOC_REQ_STRUCT *pInfo;
1072
1073 pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg;
1074 *pTimeout = pInfo->Timeout; // timeout
1075 COPY_MAC_ADDR(pApAddr, pInfo->Addr); // AP address
1076 *pCapabilityInfo = pInfo->CapabilityInfo; // capability info
1077 *pListenIntv = pInfo->ListenIntv;
1078
1079 return TRUE;
1080}
1081
1082/*
1083 ==========================================================================
1084 Description:
1085 MLME message sanity check
1086 Return:
1087 TRUE if all parameters are OK, FALSE otherwise
1088
1089 IRQL = DISPATCH_LEVEL
1090
1091 ==========================================================================
1092 */
1093BOOLEAN PeerDisassocSanity(
1094 IN PRTMP_ADAPTER pAd,
1095 IN VOID *Msg,
1096 IN ULONG MsgLen,
1097 OUT PUCHAR pAddr2,
1098 OUT USHORT *pReason)
1099{
1100 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
1101
1102 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
1103 NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
1104
1105 return TRUE;
1106}
1107
1108/*
1109 ========================================================================
1110 Routine Description:
1111 Sanity check NetworkType (11b, 11g or 11a)
1112
1113 Arguments:
1114 pBss - Pointer to BSS table.
1115
1116 Return Value:
1117 Ndis802_11DS .......(11b)
1118 Ndis802_11OFDM24....(11g)
1119 Ndis802_11OFDM5.....(11a)
1120
1121 IRQL = DISPATCH_LEVEL
1122
1123 ========================================================================
1124*/
1125NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
1126 IN PBSS_ENTRY pBss)
1127{
1128 NDIS_802_11_NETWORK_TYPE NetWorkType;
1129 UCHAR rate, i;
1130
1131 NetWorkType = Ndis802_11DS;
1132
1133 if (pBss->Channel <= 14)
1134 {
1135 //
1136 // First check support Rate.
1137 //
1138 for (i = 0; i < pBss->SupRateLen; i++)
1139 {
1140 rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
1141 if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
1142 {
1143 continue;
1144 }
1145 else
1146 {
1147 //
1148 // Otherwise (even rate > 108) means Ndis802_11OFDM24
1149 //
1150 NetWorkType = Ndis802_11OFDM24;
1151 break;
1152 }
1153 }
1154
1155 //
1156 // Second check Extend Rate.
1157 //
1158 if (NetWorkType != Ndis802_11OFDM24)
1159 {
1160 for (i = 0; i < pBss->ExtRateLen; i++)
1161 {
1162 rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
1163 if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
1164 {
1165 continue;
1166 }
1167 else
1168 {
1169 //
1170 // Otherwise (even rate > 108) means Ndis802_11OFDM24
1171 //
1172 NetWorkType = Ndis802_11OFDM24;
1173 break;
1174 }
1175 }
1176 }
1177 }
1178 else
1179 {
1180 NetWorkType = Ndis802_11OFDM5;
1181 }
1182
1183 if (pBss->HtCapabilityLen != 0)
1184 {
1185 if (NetWorkType == Ndis802_11OFDM5)
1186 NetWorkType = Ndis802_11OFDM5_N;
1187 else
1188 NetWorkType = Ndis802_11OFDM24_N;
1189 }
1190
1191 return NetWorkType;
1192}
1193
1194/*
1195 ==========================================================================
1196 Description:
1197 WPA message sanity check
1198 Return:
1199 TRUE if all parameters are OK, FALSE otherwise
1200 ==========================================================================
1201 */
1202BOOLEAN PeerWpaMessageSanity(
1203 IN PRTMP_ADAPTER pAd,
1204 IN PEAPOL_PACKET pMsg,
1205 IN ULONG MsgLen,
1206 IN UCHAR MsgType,
1207 IN MAC_TABLE_ENTRY *pEntry)
1208{
1209 UCHAR mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
1210 BOOLEAN bReplayDiff = FALSE;
1211 BOOLEAN bWPA2 = FALSE;
1212 KEY_INFO EapolKeyInfo;
1213 UCHAR GroupKeyIndex = 0;
1214
1215
1216 NdisZeroMemory(mic, sizeof(mic));
1217 NdisZeroMemory(digest, sizeof(digest));
1218 NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
1219 NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo));
1220
1221 NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO));
1222
1223 *((USHORT *)&EapolKeyInfo) = cpu2le16(*((USHORT *)&EapolKeyInfo));
1224
1225 // Choose WPA2 or not
1226 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
1227 bWPA2 = TRUE;
1228
1229 // 0. Check MsgType
1230 if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1))
1231 {
1232 DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType));
1233 return FALSE;
1234 }
1235
1236 // 1. Replay counter check
1237 if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) // For supplicant
1238 {
1239 // First validate replay counter, only accept message with larger replay counter.
1240 // Let equal pass, some AP start with all zero replay counter
1241 UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
1242
1243 NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
1244 if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) &&
1245 (RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
1246 {
1247 bReplayDiff = TRUE;
1248 }
1249 }
1250 else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) // For authenticator
1251 {
1252 // check Replay Counter coresponds to MSG from authenticator, otherwise discard
1253 if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
1254 {
1255 bReplayDiff = TRUE;
1256 }
1257 }
1258
1259 // Replay Counter different condition
1260 if (bReplayDiff)
1261 {
1262 // send wireless event - for replay counter different
1263 if (pAd->CommonCfg.bWirelessEvent)
1264 RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1265
1266 if (MsgType < EAPOL_GROUP_MSG_1)
1267 {
1268 DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType));
1269 }
1270 else
1271 {
1272 DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
1273 }
1274
1275 hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1276 hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
1277 return FALSE;
1278 }
1279
1280 // 2. Verify MIC except Pairwise Msg1
1281 if (MsgType != EAPOL_PAIR_MSG_1)
1282 {
1283 UCHAR rcvd_mic[LEN_KEY_DESC_MIC];
1284
1285 // Record the received MIC for check later
1286 NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1287 NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1288
1289 if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) // TKIP
1290 {
1291 hmac_md5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic);
1292 }
1293 else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled) // AES
1294 {
1295 HMAC_SHA1((PUCHAR)pMsg, MsgLen, pEntry->PTK, LEN_EAP_MICK, digest);
1296 NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
1297 }
1298
1299 if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC))
1300 {
1301 // send wireless event - for MIC different
1302 if (pAd->CommonCfg.bWirelessEvent)
1303 RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1304
1305 if (MsgType < EAPOL_GROUP_MSG_1)
1306 {
1307 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType));
1308 }
1309 else
1310 {
1311 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
1312 }
1313
1314 hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
1315 hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC);
1316
1317 return FALSE;
1318 }
1319 }
1320
1321 // Extract the context of the Key Data field if it exist
1322 // The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is un-encrypted.
1323 // The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
1324 if (pMsg->KeyDesc.KeyDataLen[1] > 0)
1325 {
1326 // Decrypt this field
1327 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
1328 {
1329 if(pEntry->WepStatus == Ndis802_11Encryption3Enabled)
1330 {
1331 // AES
1332 AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA, pMsg->KeyDesc.KeyDataLen[1],pMsg->KeyDesc.KeyData);
1333 }
1334 else
1335 {
1336 INT i;
1337 UCHAR Key[32];
1338 // Decrypt TKIP GTK
1339 // Construct 32 bytes RC4 Key
1340 NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
1341 NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
1342 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
1343 //discard first 256 bytes
1344 for(i = 0; i < 256; i++)
1345 ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
1346 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
1347 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
1348 }
1349
1350 if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
1351 GroupKeyIndex = EapolKeyInfo.KeyIndex;
1352
1353 }
1354 else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2))
1355 {
1356 NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
1357 }
1358 else
1359 {
1360
1361 return TRUE;
1362 }
1363
1364 // Parse Key Data field to
1365 // 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)
1366 // 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2
1367 // 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)
1368 if (!RTMPParseEapolKeyData(pAd, KEYDATA, pMsg->KeyDesc.KeyDataLen[1], GroupKeyIndex, MsgType, bWPA2, pEntry))
1369 {
1370 return FALSE;
1371 }
1372 }
1373
1374 return TRUE;
1375
1376}
1377
1378#ifdef CONFIG_STA_SUPPORT
1379#ifdef QOS_DLS_SUPPORT
1380BOOLEAN MlmeDlsReqSanity(
1381 IN PRTMP_ADAPTER pAd,
1382 IN VOID *Msg,
1383 IN ULONG MsgLen,
1384 OUT PRT_802_11_DLS *pDLS,
1385 OUT PUSHORT pReason)
1386{
1387 MLME_DLS_REQ_STRUCT *pInfo;
1388
1389 pInfo = (MLME_DLS_REQ_STRUCT *)Msg;
1390
1391 *pDLS = pInfo->pDLS;
1392 *pReason = pInfo->Reason;
1393
1394 return TRUE;
1395}
1396#endif // QOS_DLS_SUPPORT //
1397#endif // CONFIG_STA_SUPPORT //
1398
1399#ifdef QOS_DLS_SUPPORT
1400BOOLEAN PeerDlsReqSanity(
1401 IN PRTMP_ADAPTER pAd,
1402 IN VOID *Msg,
1403 IN ULONG MsgLen,
1404 OUT PUCHAR pDA,
1405 OUT PUCHAR pSA,
1406 OUT USHORT *pCapabilityInfo,
1407 OUT USHORT *pDlsTimeout,
1408 OUT UCHAR *pRatesLen,
1409 OUT UCHAR Rates[],
1410 OUT UCHAR *pHtCapabilityLen,
1411 OUT HT_CAPABILITY_IE *pHtCapability)
1412{
1413 CHAR *Ptr;
1414 PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
1415 PEID_STRUCT eid_ptr;
1416
1417 // to prevent caller from using garbage output value
1418 *pCapabilityInfo = 0;
1419 *pDlsTimeout = 0;
1420 *pHtCapabilityLen = 0;
1421
1422 Ptr = Fr->Octet;
1423
1424 // offset to destination MAC address (Category and Action field)
1425 Ptr += 2;
1426
1427 // get DA from payload and advance the pointer
1428 NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
1429 Ptr += MAC_ADDR_LEN;
1430
1431 // get SA from payload and advance the pointer
1432 NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
1433 Ptr += MAC_ADDR_LEN;
1434
1435 // get capability info from payload and advance the pointer
1436 NdisMoveMemory(pCapabilityInfo, Ptr, 2);
1437 Ptr += 2;
1438
1439 // get capability info from payload and advance the pointer
1440 NdisMoveMemory(pDlsTimeout, Ptr, 2);
1441 Ptr += 2;
1442
1443 // Category and Action field + DA + SA + capability + Timeout
1444 eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
1445
1446 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
1447 {
1448 switch(eid_ptr->Eid)
1449 {
1450 case IE_SUPP_RATES:
1451 if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
1452 {
1453 NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
1454 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
1455 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]));
1456 *pRatesLen = eid_ptr->Len;
1457 }
1458 else
1459 {
1460 *pRatesLen = 8;
1461 Rates[0] = 0x82;
1462 Rates[1] = 0x84;
1463 Rates[2] = 0x8b;
1464 Rates[3] = 0x96;
1465 Rates[4] = 0x12;
1466 Rates[5] = 0x24;
1467 Rates[6] = 0x48;
1468 Rates[7] = 0x6c;
1469 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
1470 }
1471 break;
1472
1473 case IE_EXT_SUPP_RATES:
1474 if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
1475 {
1476 NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
1477 *pRatesLen = (*pRatesLen) + eid_ptr->Len;
1478 }
1479 else
1480 {
1481 NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
1482 *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
1483 }
1484 break;
1485
1486 case IE_HT_CAP:
1487 if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
1488 {
1489 NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
1490
1491 *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
1492 *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
1493 *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
1494
1495 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_HT_CAP\n"));
1496 }
1497 else
1498 {
1499 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
1500 }
1501 break;
1502
1503 default:
1504 break;
1505 }
1506
1507 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1508 }
1509
1510 return TRUE;
1511}
1512
1513BOOLEAN PeerDlsRspSanity(
1514 IN PRTMP_ADAPTER pAd,
1515 IN VOID *Msg,
1516 IN ULONG MsgLen,
1517 OUT PUCHAR pDA,
1518 OUT PUCHAR pSA,
1519 OUT USHORT *pCapabilityInfo,
1520 OUT USHORT *pStatus,
1521 OUT UCHAR *pRatesLen,
1522 OUT UCHAR Rates[],
1523 OUT UCHAR *pHtCapabilityLen,
1524 OUT HT_CAPABILITY_IE *pHtCapability)
1525{
1526 CHAR *Ptr;
1527 PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
1528 PEID_STRUCT eid_ptr;
1529
1530 // to prevent caller from using garbage output value
1531 *pStatus = 0;
1532 *pCapabilityInfo = 0;
1533 *pHtCapabilityLen = 0;
1534
1535 Ptr = Fr->Octet;
1536
1537 // offset to destination MAC address (Category and Action field)
1538 Ptr += 2;
1539
1540 // get status code from payload and advance the pointer
1541 NdisMoveMemory(pStatus, Ptr, 2);
1542 Ptr += 2;
1543
1544 // get DA from payload and advance the pointer
1545 NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
1546 Ptr += MAC_ADDR_LEN;
1547
1548 // get SA from payload and advance the pointer
1549 NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
1550 Ptr += MAC_ADDR_LEN;
1551
1552 if (pStatus == 0)
1553 {
1554 // get capability info from payload and advance the pointer
1555 NdisMoveMemory(pCapabilityInfo, Ptr, 2);
1556 Ptr += 2;
1557 }
1558
1559 // Category and Action field + status code + DA + SA + capability
1560 eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
1561
1562 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
1563 {
1564 switch(eid_ptr->Eid)
1565 {
1566 case IE_SUPP_RATES:
1567 if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
1568 {
1569 NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
1570 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
1571 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]));
1572 *pRatesLen = eid_ptr->Len;
1573 }
1574 else
1575 {
1576 *pRatesLen = 8;
1577 Rates[0] = 0x82;
1578 Rates[1] = 0x84;
1579 Rates[2] = 0x8b;
1580 Rates[3] = 0x96;
1581 Rates[4] = 0x12;
1582 Rates[5] = 0x24;
1583 Rates[6] = 0x48;
1584 Rates[7] = 0x6c;
1585 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
1586 }
1587 break;
1588
1589 case IE_EXT_SUPP_RATES:
1590 if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
1591 {
1592 NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
1593 *pRatesLen = (*pRatesLen) + eid_ptr->Len;
1594 }
1595 else
1596 {
1597 NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
1598 *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
1599 }
1600 break;
1601
1602 case IE_HT_CAP:
1603 if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
1604 {
1605 NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
1606
1607 *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
1608 *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
1609 *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
1610
1611 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_HT_CAP\n"));
1612 }
1613 else
1614 {
1615 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
1616 }
1617 break;
1618
1619 default:
1620 break;
1621 }
1622
1623 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1624 }
1625
1626 return TRUE;
1627}
1628
1629BOOLEAN PeerDlsTearDownSanity(
1630 IN PRTMP_ADAPTER pAd,
1631 IN VOID *Msg,
1632 IN ULONG MsgLen,
1633 OUT PUCHAR pDA,
1634 OUT PUCHAR pSA,
1635 OUT USHORT *pReason)
1636{
1637 CHAR *Ptr;
1638 PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
1639
1640 // to prevent caller from using garbage output value
1641 *pReason = 0;
1642
1643 Ptr = Fr->Octet;
1644
1645 // offset to destination MAC address (Category and Action field)
1646 Ptr += 2;
1647
1648 // get DA from payload and advance the pointer
1649 NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
1650 Ptr += MAC_ADDR_LEN;
1651
1652 // get SA from payload and advance the pointer
1653 NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
1654 Ptr += MAC_ADDR_LEN;
1655
1656 // get reason code from payload and advance the pointer
1657 NdisMoveMemory(pReason, Ptr, 2);
1658 Ptr += 2;
1659
1660 return TRUE;
1661}
1662#endif // QOS_DLS_SUPPORT //
1663
diff --git a/drivers/staging/rt2870/common/cmm_sync.c b/drivers/staging/rt2870/common/cmm_sync.c
new file mode 100644
index 00000000000..2be7c77a384
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/common/cmm_wpa.c b/drivers/staging/rt2870/common/cmm_wpa.c
new file mode 100644
index 00000000000..d2c24bd49e7
--- /dev/null
+++ b/drivers/staging/rt2870/common/cmm_wpa.c
@@ -0,0 +1,1654 @@
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_WEP40[4] = {0x00, 0x50, 0xF2, 0x01};
43UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};
44UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};
45UCHAR OUI_WPA_WEP104[4] = {0x00, 0x50, 0xF2, 0x05};
46UCHAR OUI_WPA_8021X_AKM[4] = {0x00, 0x50, 0xF2, 0x01};
47UCHAR OUI_WPA_PSK_AKM[4] = {0x00, 0x50, 0xF2, 0x02};
48// WPA2 OUI
49UCHAR OUI_WPA2_WEP40[4] = {0x00, 0x0F, 0xAC, 0x01};
50UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
51UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
52UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01};
53UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02};
54UCHAR OUI_WPA2_WEP104[4] = {0x00, 0x0F, 0xAC, 0x05};
55// MSA OUI
56UCHAR OUI_MSA_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x05}; // Not yet final - IEEE 802.11s-D1.06
57UCHAR OUI_MSA_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x06}; // Not yet final - IEEE 802.11s-D1.06
58
59/*
60 ========================================================================
61
62 Routine Description:
63 The pseudo-random function(PRF) that hashes various inputs to
64 derive a pseudo-random value. To add liveness to the pseudo-random
65 value, a nonce should be one of the inputs.
66
67 It is used to generate PTK, GTK or some specific random value.
68
69 Arguments:
70 UCHAR *key, - the key material for HMAC_SHA1 use
71 INT key_len - the length of key
72 UCHAR *prefix - a prefix label
73 INT prefix_len - the length of the label
74 UCHAR *data - a specific data with variable length
75 INT data_len - the length of a specific data
76 INT len - the output lenght
77
78 Return Value:
79 UCHAR *output - the calculated result
80
81 Note:
82 802.11i-2004 Annex H.3
83
84 ========================================================================
85*/
86VOID PRF(
87 IN UCHAR *key,
88 IN INT key_len,
89 IN UCHAR *prefix,
90 IN INT prefix_len,
91 IN UCHAR *data,
92 IN INT data_len,
93 OUT UCHAR *output,
94 IN INT len)
95{
96 INT i;
97 UCHAR *input;
98 INT currentindex = 0;
99 INT total_len;
100
101 // Allocate memory for input
102 os_alloc_mem(NULL, (PUCHAR *)&input, 1024);
103
104 if (input == NULL)
105 {
106 DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n"));
107 return;
108 }
109
110 // Generate concatenation input
111 NdisMoveMemory(input, prefix, prefix_len);
112
113 // Concatenate a single octet containing 0
114 input[prefix_len] = 0;
115
116 // Concatenate specific data
117 NdisMoveMemory(&input[prefix_len + 1], data, data_len);
118 total_len = prefix_len + 1 + data_len;
119
120 // Concatenate a single octet containing 0
121 // This octet shall be update later
122 input[total_len] = 0;
123 total_len++;
124
125 // Iterate to calculate the result by hmac-sha-1
126 // Then concatenate to last result
127 for (i = 0; i < (len + 19) / 20; i++)
128 {
129 HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
130 currentindex += 20;
131
132 // update the last octet
133 input[total_len - 1]++;
134 }
135 os_free_mem(NULL, input);
136}
137
138/*
139 ========================================================================
140
141 Routine Description:
142 It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
143 It shall be called by 4-way handshake processing.
144
145 Arguments:
146 pAd - pointer to our pAdapter context
147 PMK - pointer to PMK
148 ANonce - pointer to ANonce
149 AA - pointer to Authenticator Address
150 SNonce - pointer to SNonce
151 SA - pointer to Supplicant Address
152 len - indicate the length of PTK (octet)
153
154 Return Value:
155 Output pointer to the PTK
156
157 Note:
158 Refer to IEEE 802.11i-2004 8.5.1.2
159
160 ========================================================================
161*/
162VOID WpaCountPTK(
163 IN PRTMP_ADAPTER pAd,
164 IN UCHAR *PMK,
165 IN UCHAR *ANonce,
166 IN UCHAR *AA,
167 IN UCHAR *SNonce,
168 IN UCHAR *SA,
169 OUT UCHAR *output,
170 IN UINT len)
171{
172 UCHAR concatenation[76];
173 UINT CurrPos = 0;
174 UCHAR temp[32];
175 UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
176 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
177
178 // initiate the concatenation input
179 NdisZeroMemory(temp, sizeof(temp));
180 NdisZeroMemory(concatenation, 76);
181
182 // Get smaller address
183 if (RTMPCompareMemory(SA, AA, 6) == 1)
184 NdisMoveMemory(concatenation, AA, 6);
185 else
186 NdisMoveMemory(concatenation, SA, 6);
187 CurrPos += 6;
188
189 // Get larger address
190 if (RTMPCompareMemory(SA, AA, 6) == 1)
191 NdisMoveMemory(&concatenation[CurrPos], SA, 6);
192 else
193 NdisMoveMemory(&concatenation[CurrPos], AA, 6);
194
195 // store the larger mac address for backward compatible of
196 // ralink proprietary STA-key issue
197 NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
198 CurrPos += 6;
199
200 // Get smaller Nonce
201 if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
202 NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue
203 else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
204 NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
205 else
206 NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
207 CurrPos += 32;
208
209 // Get larger Nonce
210 if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
211 NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue
212 else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
213 NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
214 else
215 NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
216 CurrPos += 32;
217
218 hex_dump("concatenation=", concatenation, 76);
219
220 // Use PRF to generate PTK
221 PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
222
223}
224
225/*
226 ========================================================================
227
228 Routine Description:
229 Generate random number by software.
230
231 Arguments:
232 pAd - pointer to our pAdapter context
233 macAddr - pointer to local MAC address
234
235 Return Value:
236
237 Note:
238 802.1ii-2004 Annex H.5
239
240 ========================================================================
241*/
242VOID GenRandom(
243 IN PRTMP_ADAPTER pAd,
244 IN UCHAR *macAddr,
245 OUT UCHAR *random)
246{
247 INT i, curr;
248 UCHAR local[80], KeyCounter[32];
249 UCHAR result[80];
250 ULONG CurrentTime;
251 UCHAR prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
252
253 // Zero the related information
254 NdisZeroMemory(result, 80);
255 NdisZeroMemory(local, 80);
256 NdisZeroMemory(KeyCounter, 32);
257
258 for (i = 0; i < 32; i++)
259 {
260 // copy the local MAC address
261 COPY_MAC_ADDR(local, macAddr);
262 curr = MAC_ADDR_LEN;
263
264 // concatenate the current time
265 NdisGetSystemUpTime(&CurrentTime);
266 NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
267 curr += sizeof(CurrentTime);
268
269 // concatenate the last result
270 NdisMoveMemory(&local[curr], result, 32);
271 curr += 32;
272
273 // concatenate a variable
274 NdisMoveMemory(&local[curr], &i, 2);
275 curr += 2;
276
277 // calculate the result
278 PRF(KeyCounter, 32, prefix,12, local, curr, result, 32);
279 }
280
281 NdisMoveMemory(random, result, 32);
282}
283
284/*
285 ========================================================================
286
287 Routine Description:
288 Build cipher suite in RSN-IE.
289 It only shall be called by RTMPMakeRSNIE.
290
291 Arguments:
292 pAd - pointer to our pAdapter context
293 ElementID - indicate the WPA1 or WPA2
294 WepStatus - indicate the encryption type
295 bMixCipher - a boolean to indicate the pairwise cipher and group
296 cipher are the same or not
297
298 Return Value:
299
300 Note:
301
302 ========================================================================
303*/
304static VOID RTMPInsertRsnIeCipher(
305 IN PRTMP_ADAPTER pAd,
306 IN UCHAR ElementID,
307 IN UINT WepStatus,
308 IN BOOLEAN bMixCipher,
309 IN UCHAR FlexibleCipher,
310 OUT PUCHAR pRsnIe,
311 OUT UCHAR *rsn_len)
312{
313 UCHAR PairwiseCnt;
314
315 *rsn_len = 0;
316
317 // decide WPA2 or WPA1
318 if (ElementID == Wpa2Ie)
319 {
320 RSNIE2 *pRsnie_cipher = (RSNIE2*)pRsnIe;
321
322 // Assign the verson as 1
323 pRsnie_cipher->version = 1;
324
325 switch (WepStatus)
326 {
327 // TKIP mode
328 case Ndis802_11Encryption2Enabled:
329 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
330 pRsnie_cipher->ucount = 1;
331 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
332 *rsn_len = sizeof(RSNIE2);
333 break;
334
335 // AES mode
336 case Ndis802_11Encryption3Enabled:
337 if (bMixCipher)
338 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
339 else
340 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4);
341 pRsnie_cipher->ucount = 1;
342 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
343 *rsn_len = sizeof(RSNIE2);
344 break;
345
346 // TKIP-AES mix mode
347 case Ndis802_11Encryption4Enabled:
348 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
349
350 PairwiseCnt = 1;
351 // Insert WPA2 TKIP as the first pairwise cipher
352 if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher))
353 {
354 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
355 // Insert WPA2 AES as the secondary pairwise cipher
356 if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher))
357 {
358 NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4);
359 PairwiseCnt = 2;
360 }
361 }
362 else
363 {
364 // Insert WPA2 AES as the first pairwise cipher
365 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
366 }
367
368 pRsnie_cipher->ucount = PairwiseCnt;
369 *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1));
370 break;
371 }
372
373#ifdef CONFIG_STA_SUPPORT
374 if ((pAd->OpMode == OPMODE_STA) &&
375 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
376 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
377 {
378 UINT GroupCipher = pAd->StaCfg.GroupCipher;
379 switch(GroupCipher)
380 {
381 case Ndis802_11GroupWEP40Enabled:
382 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP40, 4);
383 break;
384 case Ndis802_11GroupWEP104Enabled:
385 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP104, 4);
386 break;
387 }
388 }
389#endif // CONFIG_STA_SUPPORT //
390
391 // swap for big-endian platform
392 pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
393 pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
394 }
395 else
396 {
397 RSNIE *pRsnie_cipher = (RSNIE*)pRsnIe;
398
399 // Assign OUI and version
400 NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
401 pRsnie_cipher->version = 1;
402
403 switch (WepStatus)
404 {
405 // TKIP mode
406 case Ndis802_11Encryption2Enabled:
407 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
408 pRsnie_cipher->ucount = 1;
409 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
410 *rsn_len = sizeof(RSNIE);
411 break;
412
413 // AES mode
414 case Ndis802_11Encryption3Enabled:
415 if (bMixCipher)
416 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
417 else
418 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4);
419 pRsnie_cipher->ucount = 1;
420 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
421 *rsn_len = sizeof(RSNIE);
422 break;
423
424 // TKIP-AES mix mode
425 case Ndis802_11Encryption4Enabled:
426 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
427
428 PairwiseCnt = 1;
429 // Insert WPA TKIP as the first pairwise cipher
430 if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher))
431 {
432 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
433 // Insert WPA AES as the secondary pairwise cipher
434 if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher))
435 {
436 NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4);
437 PairwiseCnt = 2;
438 }
439 }
440 else
441 {
442 // Insert WPA AES as the first pairwise cipher
443 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
444 }
445
446 pRsnie_cipher->ucount = PairwiseCnt;
447 *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1));
448 break;
449 }
450
451#ifdef CONFIG_STA_SUPPORT
452 if ((pAd->OpMode == OPMODE_STA) &&
453 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
454 (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
455 {
456 UINT GroupCipher = pAd->StaCfg.GroupCipher;
457 switch(GroupCipher)
458 {
459 case Ndis802_11GroupWEP40Enabled:
460 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP40, 4);
461 break;
462 case Ndis802_11GroupWEP104Enabled:
463 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP104, 4);
464 break;
465 }
466 }
467#endif // CONFIG_STA_SUPPORT //
468
469 // swap for big-endian platform
470 pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
471 pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
472 }
473}
474
475/*
476 ========================================================================
477
478 Routine Description:
479 Build AKM suite in RSN-IE.
480 It only shall be called by RTMPMakeRSNIE.
481
482 Arguments:
483 pAd - pointer to our pAdapter context
484 ElementID - indicate the WPA1 or WPA2
485 AuthMode - indicate the authentication mode
486 apidx - indicate the interface index
487
488 Return Value:
489
490 Note:
491
492 ========================================================================
493*/
494static VOID RTMPInsertRsnIeAKM(
495 IN PRTMP_ADAPTER pAd,
496 IN UCHAR ElementID,
497 IN UINT AuthMode,
498 IN UCHAR apidx,
499 OUT PUCHAR pRsnIe,
500 OUT UCHAR *rsn_len)
501{
502 RSNIE_AUTH *pRsnie_auth;
503
504 pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
505
506 // decide WPA2 or WPA1
507 if (ElementID == Wpa2Ie)
508 {
509 switch (AuthMode)
510 {
511 case Ndis802_11AuthModeWPA2:
512 case Ndis802_11AuthModeWPA1WPA2:
513 pRsnie_auth->acount = 1;
514 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
515 break;
516
517 case Ndis802_11AuthModeWPA2PSK:
518 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
519 pRsnie_auth->acount = 1;
520 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
521 break;
522 }
523 }
524 else
525 {
526 switch (AuthMode)
527 {
528 case Ndis802_11AuthModeWPA:
529 case Ndis802_11AuthModeWPA1WPA2:
530 pRsnie_auth->acount = 1;
531 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
532 break;
533
534 case Ndis802_11AuthModeWPAPSK:
535 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
536 pRsnie_auth->acount = 1;
537 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
538 break;
539
540 case Ndis802_11AuthModeWPANone:
541 pRsnie_auth->acount = 1;
542 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
543 break;
544 }
545 }
546
547 pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
548
549 (*rsn_len) += sizeof(RSNIE_AUTH); // update current RSNIE length
550
551}
552
553/*
554 ========================================================================
555
556 Routine Description:
557 Build capability in RSN-IE.
558 It only shall be called by RTMPMakeRSNIE.
559
560 Arguments:
561 pAd - pointer to our pAdapter context
562 ElementID - indicate the WPA1 or WPA2
563 apidx - indicate the interface index
564
565 Return Value:
566
567 Note:
568
569 ========================================================================
570*/
571static VOID RTMPInsertRsnIeCap(
572 IN PRTMP_ADAPTER pAd,
573 IN UCHAR ElementID,
574 IN UCHAR apidx,
575 OUT PUCHAR pRsnIe,
576 OUT UCHAR *rsn_len)
577{
578 RSN_CAPABILITIES *pRSN_Cap;
579
580 // it could be ignored in WPA1 mode
581 if (ElementID == WpaIe)
582 return;
583
584 pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len));
585
586
587 pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
588
589 (*rsn_len) += sizeof(RSN_CAPABILITIES); // update current RSNIE length
590
591}
592
593
594/*
595 ========================================================================
596
597 Routine Description:
598 Build RSN IE context. It is not included element-ID and length.
599
600 Arguments:
601 pAd - pointer to our pAdapter context
602 AuthMode - indicate the authentication mode
603 WepStatus - indicate the encryption type
604 apidx - indicate the interface index
605
606 Return Value:
607
608 Note:
609
610 ========================================================================
611*/
612VOID RTMPMakeRSNIE(
613 IN PRTMP_ADAPTER pAd,
614 IN UINT AuthMode,
615 IN UINT WepStatus,
616 IN UCHAR apidx)
617{
618 PUCHAR pRsnIe = NULL; // primary RSNIE
619 UCHAR *rsnielen_cur_p = 0; // the length of the primary RSNIE
620 UCHAR *rsnielen_ex_cur_p = 0; // the length of the secondary RSNIE
621 UCHAR PrimaryRsnie;
622 BOOLEAN bMixCipher = FALSE; // indicate the pairwise and group cipher are different
623 UCHAR p_offset;
624 WPA_MIX_PAIR_CIPHER FlexibleCipher = MIX_CIPHER_NOTUSE; // it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode
625
626 rsnielen_cur_p = NULL;
627 rsnielen_ex_cur_p = NULL;
628
629 {
630#ifdef CONFIG_STA_SUPPORT
631 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
632 {
633#ifdef WPA_SUPPLICANT_SUPPORT
634 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
635 {
636 if (AuthMode < Ndis802_11AuthModeWPA)
637 return;
638 }
639 else
640#endif // WPA_SUPPLICANT_SUPPORT //
641 {
642 // Support WPAPSK or WPA2PSK in STA-Infra mode
643 // Support WPANone in STA-Adhoc mode
644 if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
645 (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
646 (AuthMode != Ndis802_11AuthModeWPANone)
647 )
648 return;
649 }
650
651 DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n"));
652
653 // Zero RSNIE context
654 pAd->StaCfg.RSNIE_Len = 0;
655 NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
656
657 // Pointer to RSNIE
658 rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
659 pRsnIe = pAd->StaCfg.RSN_IE;
660
661 bMixCipher = pAd->StaCfg.bMixCipher;
662 }
663#endif // CONFIG_STA_SUPPORT //
664 }
665
666 // indicate primary RSNIE as WPA or WPA2
667 if ((AuthMode == Ndis802_11AuthModeWPA) ||
668 (AuthMode == Ndis802_11AuthModeWPAPSK) ||
669 (AuthMode == Ndis802_11AuthModeWPANone) ||
670 (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
671 (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
672 PrimaryRsnie = WpaIe;
673 else
674 PrimaryRsnie = Wpa2Ie;
675
676 {
677 // Build the primary RSNIE
678 // 1. insert cipher suite
679 RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
680
681 // 2. insert AKM
682 RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
683
684 // 3. insert capability
685 RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
686 }
687
688 // 4. update the RSNIE length
689 *rsnielen_cur_p = p_offset;
690
691 hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
692
693
694}
695
696/*
697 ==========================================================================
698 Description:
699 Check whether the received frame is EAP frame.
700
701 Arguments:
702 pAd - pointer to our pAdapter context
703 pEntry - pointer to active entry
704 pData - the received frame
705 DataByteCount - the received frame's length
706 FromWhichBSSID - indicate the interface index
707
708 Return:
709 TRUE - This frame is EAP frame
710 FALSE - otherwise
711 ==========================================================================
712*/
713BOOLEAN RTMPCheckWPAframe(
714 IN PRTMP_ADAPTER pAd,
715 IN PMAC_TABLE_ENTRY pEntry,
716 IN PUCHAR pData,
717 IN ULONG DataByteCount,
718 IN UCHAR FromWhichBSSID)
719{
720 ULONG Body_len;
721 BOOLEAN Cancelled;
722
723
724 if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
725 return FALSE;
726
727
728 // Skip LLC header
729 if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
730 // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL
731 NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6))
732 {
733 pData += 6;
734 }
735 // Skip 2-bytes EAPoL type
736 if (NdisEqualMemory(EAPOL, pData, 2))
737 {
738 pData += 2;
739 }
740 else
741 return FALSE;
742
743 switch (*(pData+1))
744 {
745 case EAPPacket:
746 Body_len = (*(pData+2)<<8) | (*(pData+3));
747 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len));
748 break;
749 case EAPOLStart:
750 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
751 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
752 {
753 DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));
754 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
755 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
756 }
757 break;
758 case EAPOLLogoff:
759 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
760 break;
761 case EAPOLKey:
762 Body_len = (*(pData+2)<<8) | (*(pData+3));
763 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len));
764 break;
765 case EAPOLASFAlert:
766 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
767 break;
768 default:
769 return FALSE;
770
771 }
772 return TRUE;
773}
774
775
776/*
777 ==========================================================================
778 Description:
779 ENCRYPT AES GTK before sending in EAPOL frame.
780 AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function.
781 This function references to RFC 3394 for aes key wrap algorithm.
782 Return:
783 ==========================================================================
784*/
785VOID AES_GTK_KEY_WRAP(
786 IN UCHAR *key,
787 IN UCHAR *plaintext,
788 IN UCHAR p_len,
789 OUT UCHAR *ciphertext)
790{
791 UCHAR A[8], BIN[16], BOUT[16];
792 UCHAR R[512];
793 INT num_blocks = p_len/8; // unit:64bits
794 INT i, j;
795 aes_context aesctx;
796 UCHAR xor;
797
798 rtmp_aes_set_key(&aesctx, key, 128);
799
800 // Init IA
801 for (i = 0; i < 8; i++)
802 A[i] = 0xa6;
803
804 //Input plaintext
805 for (i = 0; i < num_blocks; i++)
806 {
807 for (j = 0 ; j < 8; j++)
808 R[8 * (i + 1) + j] = plaintext[8 * i + j];
809 }
810
811 // Key Mix
812 for (j = 0; j < 6; j++)
813 {
814 for(i = 1; i <= num_blocks; i++)
815 {
816 //phase 1
817 NdisMoveMemory(BIN, A, 8);
818 NdisMoveMemory(&BIN[8], &R[8 * i], 8);
819 rtmp_aes_encrypt(&aesctx, BIN, BOUT);
820
821 NdisMoveMemory(A, &BOUT[0], 8);
822 xor = num_blocks * j + i;
823 A[7] = BOUT[7] ^ xor;
824 NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
825 }
826 }
827
828 // Output ciphertext
829 NdisMoveMemory(ciphertext, A, 8);
830
831 for (i = 1; i <= num_blocks; i++)
832 {
833 for (j = 0 ; j < 8; j++)
834 ciphertext[8 * i + j] = R[8 * i + j];
835 }
836}
837
838
839/*
840 ========================================================================
841
842 Routine Description:
843 Misc function to decrypt AES body
844
845 Arguments:
846
847 Return Value:
848
849 Note:
850 This function references to RFC 3394 for aes key unwrap algorithm.
851
852 ========================================================================
853*/
854VOID AES_GTK_KEY_UNWRAP(
855 IN UCHAR *key,
856 OUT UCHAR *plaintext,
857 IN UCHAR c_len,
858 IN UCHAR *ciphertext)
859
860{
861 UCHAR A[8], BIN[16], BOUT[16];
862 UCHAR xor;
863 INT i, j;
864 aes_context aesctx;
865 UCHAR *R;
866 INT num_blocks = c_len/8; // unit:64bits
867
868
869 os_alloc_mem(NULL, (PUCHAR *)&R, 512);
870
871 if (R == NULL)
872 {
873 DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
874 return;
875 } /* End of if */
876
877 // Initialize
878 NdisMoveMemory(A, ciphertext, 8);
879 //Input plaintext
880 for(i = 0; i < (c_len-8); i++)
881 {
882 R[ i] = ciphertext[i + 8];
883 }
884
885 rtmp_aes_set_key(&aesctx, key, 128);
886
887 for(j = 5; j >= 0; j--)
888 {
889 for(i = (num_blocks-1); i > 0; i--)
890 {
891 xor = (num_blocks -1 )* j + i;
892 NdisMoveMemory(BIN, A, 8);
893 BIN[7] = A[7] ^ xor;
894 NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
895 rtmp_aes_decrypt(&aesctx, BIN, BOUT);
896 NdisMoveMemory(A, &BOUT[0], 8);
897 NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
898 }
899 }
900
901 // OUTPUT
902 for(i = 0; i < c_len; i++)
903 {
904 plaintext[i] = R[i];
905 }
906
907
908 os_free_mem(NULL, R);
909}
910
911/*
912 ==========================================================================
913 Description:
914 Report the EAP message type
915
916 Arguments:
917 msg - EAPOL_PAIR_MSG_1
918 EAPOL_PAIR_MSG_2
919 EAPOL_PAIR_MSG_3
920 EAPOL_PAIR_MSG_4
921 EAPOL_GROUP_MSG_1
922 EAPOL_GROUP_MSG_2
923
924 Return:
925 message type string
926
927 ==========================================================================
928*/
929CHAR *GetEapolMsgType(CHAR msg)
930{
931 if(msg == EAPOL_PAIR_MSG_1)
932 return "Pairwise Message 1";
933 else if(msg == EAPOL_PAIR_MSG_2)
934 return "Pairwise Message 2";
935 else if(msg == EAPOL_PAIR_MSG_3)
936 return "Pairwise Message 3";
937 else if(msg == EAPOL_PAIR_MSG_4)
938 return "Pairwise Message 4";
939 else if(msg == EAPOL_GROUP_MSG_1)
940 return "Group Message 1";
941 else if(msg == EAPOL_GROUP_MSG_2)
942 return "Group Message 2";
943 else
944 return "Invalid Message";
945}
946
947
948/*
949 ========================================================================
950
951 Routine Description:
952 Check Sanity RSN IE of EAPoL message
953
954 Arguments:
955
956 Return Value:
957
958
959 ========================================================================
960*/
961BOOLEAN RTMPCheckRSNIE(
962 IN PRTMP_ADAPTER pAd,
963 IN PUCHAR pData,
964 IN UCHAR DataLen,
965 IN MAC_TABLE_ENTRY *pEntry,
966 OUT UCHAR *Offset)
967{
968 PUCHAR pVIE;
969 UCHAR len;
970 PEID_STRUCT pEid;
971 BOOLEAN result = FALSE;
972
973 pVIE = pData;
974 len = DataLen;
975 *Offset = 0;
976
977 while (len > sizeof(RSNIE2))
978 {
979 pEid = (PEID_STRUCT) pVIE;
980 // WPA RSN IE
981 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
982 {
983 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) &&
984 (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
985 (pEntry->RSNIE_Len == (pEid->Len + 2)))
986 {
987 result = TRUE;
988 }
989
990 *Offset += (pEid->Len + 2);
991 }
992 // WPA2 RSN IE
993 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
994 {
995 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) &&
996 (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
997 (pEntry->RSNIE_Len == (pEid->Len + 2))/* ToDo-AlbertY for mesh*/)
998 {
999 result = TRUE;
1000 }
1001
1002 *Offset += (pEid->Len + 2);
1003 }
1004 else
1005 {
1006 break;
1007 }
1008
1009 pVIE += (pEid->Len + 2);
1010 len -= (pEid->Len + 2);
1011 }
1012
1013
1014 return result;
1015
1016}
1017
1018
1019/*
1020 ========================================================================
1021
1022 Routine Description:
1023 Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
1024 GTK is encaptulated in KDE format at p.83 802.11i D10
1025
1026 Arguments:
1027
1028 Return Value:
1029
1030 Note:
1031 802.11i D10
1032
1033 ========================================================================
1034*/
1035BOOLEAN RTMPParseEapolKeyData(
1036 IN PRTMP_ADAPTER pAd,
1037 IN PUCHAR pKeyData,
1038 IN UCHAR KeyDataLen,
1039 IN UCHAR GroupKeyIndex,
1040 IN UCHAR MsgType,
1041 IN BOOLEAN bWPA2,
1042 IN MAC_TABLE_ENTRY *pEntry)
1043{
1044 PKDE_ENCAP pKDE = NULL;
1045 PUCHAR pMyKeyData = pKeyData;
1046 UCHAR KeyDataLength = KeyDataLen;
1047 UCHAR GTKLEN = 0;
1048 UCHAR DefaultIdx = 0;
1049 UCHAR skip_offset;
1050
1051 // Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it
1052 if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3)
1053 {
1054 // Check RSN IE whether it is WPA2/WPA2PSK
1055 if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset))
1056 {
1057 // send wireless event - for RSN IE different
1058 if (pAd->CommonCfg.bWirelessEvent)
1059 RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1060
1061 DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType));
1062 hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
1063 hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len);
1064
1065 return FALSE;
1066 }
1067 else
1068 {
1069 if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3)
1070 {
1071 // skip RSN IE
1072 pMyKeyData += skip_offset;
1073 KeyDataLength -= skip_offset;
1074 DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
1075 }
1076 else
1077 return TRUE;
1078 }
1079 }
1080
1081 DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
1082
1083 // Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2
1084 if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1))
1085 {
1086 if (KeyDataLength >= 8) // KDE format exclude GTK length
1087 {
1088 pKDE = (PKDE_ENCAP) pMyKeyData;
1089
1090
1091 DefaultIdx = pKDE->GTKEncap.Kid;
1092
1093 // Sanity check - KED length
1094 if (KeyDataLength < (pKDE->Len + 2))
1095 {
1096 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
1097 return FALSE;
1098 }
1099
1100 // Get GTK length - refer to IEEE 802.11i-2004 p.82
1101 GTKLEN = pKDE->Len -6;
1102 if (GTKLEN < LEN_AES_KEY)
1103 {
1104 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
1105 return FALSE;
1106 }
1107
1108 }
1109 else
1110 {
1111 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n"));
1112 return FALSE;
1113 }
1114
1115 DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN));
1116 // skip it
1117 pMyKeyData += 8;
1118 KeyDataLength -= 8;
1119
1120 }
1121 else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1)
1122 {
1123 DefaultIdx = GroupKeyIndex;
1124 DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx));
1125 }
1126
1127 // Sanity check - shared key index must be 1 ~ 3
1128 if (DefaultIdx < 1 || DefaultIdx > 3)
1129 {
1130 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
1131 return FALSE;
1132 }
1133
1134
1135#ifdef CONFIG_STA_SUPPORT
1136 // Todo
1137#endif // CONFIG_STA_SUPPORT //
1138
1139 return TRUE;
1140
1141}
1142
1143
1144/*
1145 ========================================================================
1146
1147 Routine Description:
1148 Construct EAPoL message for WPA handshaking
1149 Its format is below,
1150
1151 +--------------------+
1152 | Protocol Version | 1 octet
1153 +--------------------+
1154 | Protocol Type | 1 octet
1155 +--------------------+
1156 | Body Length | 2 octets
1157 +--------------------+
1158 | Descriptor Type | 1 octet
1159 +--------------------+
1160 | Key Information | 2 octets
1161 +--------------------+
1162 | Key Length | 1 octet
1163 +--------------------+
1164 | Key Repaly Counter | 8 octets
1165 +--------------------+
1166 | Key Nonce | 32 octets
1167 +--------------------+
1168 | Key IV | 16 octets
1169 +--------------------+
1170 | Key RSC | 8 octets
1171 +--------------------+
1172 | Key ID or Reserved | 8 octets
1173 +--------------------+
1174 | Key MIC | 16 octets
1175 +--------------------+
1176 | Key Data Length | 2 octets
1177 +--------------------+
1178 | Key Data | n octets
1179 +--------------------+
1180
1181
1182 Arguments:
1183 pAd Pointer to our adapter
1184
1185 Return Value:
1186 None
1187
1188 Note:
1189
1190 ========================================================================
1191*/
1192VOID ConstructEapolMsg(
1193 IN PRTMP_ADAPTER pAd,
1194 IN UCHAR AuthMode,
1195 IN UCHAR WepStatus,
1196 IN UCHAR GroupKeyWepStatus,
1197 IN UCHAR MsgType,
1198 IN UCHAR DefaultKeyIdx,
1199 IN UCHAR *ReplayCounter,
1200 IN UCHAR *KeyNonce,
1201 IN UCHAR *TxRSC,
1202 IN UCHAR *PTK,
1203 IN UCHAR *GTK,
1204 IN UCHAR *RSNIE,
1205 IN UCHAR RSNIE_Len,
1206 OUT PEAPOL_PACKET pMsg)
1207{
1208 BOOLEAN bWPA2 = FALSE;
1209
1210 // Choose WPA2 or not
1211 if ((AuthMode == Ndis802_11AuthModeWPA2) || (AuthMode == Ndis802_11AuthModeWPA2PSK))
1212 bWPA2 = TRUE;
1213
1214 // Init Packet and Fill header
1215 pMsg->ProVer = EAPOL_VER;
1216 pMsg->ProType = EAPOLKey;
1217
1218 // Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field
1219 pMsg->Body_Len[1] = LEN_EAPOL_KEY_MSG;
1220
1221 // Fill in EAPoL descriptor
1222 if (bWPA2)
1223 pMsg->KeyDesc.Type = WPA2_KEY_DESC;
1224 else
1225 pMsg->KeyDesc.Type = WPA1_KEY_DESC;
1226
1227 // Fill in Key information, refer to IEEE Std 802.11i-2004 page 78
1228 // When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used.
1229 pMsg->KeyDesc.KeyInfo.KeyDescVer =
1230 (((WepStatus == Ndis802_11Encryption3Enabled) || (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1231
1232 // Specify Key Type as Group(0) or Pairwise(1)
1233 if (MsgType >= EAPOL_GROUP_MSG_1)
1234 pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
1235 else
1236 pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
1237
1238 // Specify Key Index, only group_msg1_WPA1
1239 if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
1240 pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
1241
1242 if (MsgType == EAPOL_PAIR_MSG_3)
1243 pMsg->KeyDesc.KeyInfo.Install = 1;
1244
1245 if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))
1246 pMsg->KeyDesc.KeyInfo.KeyAck = 1;
1247
1248 if (MsgType != EAPOL_PAIR_MSG_1)
1249 pMsg->KeyDesc.KeyInfo.KeyMic = 1;
1250
1251 if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)))
1252 {
1253 pMsg->KeyDesc.KeyInfo.Secure = 1;
1254 }
1255
1256 if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
1257 {
1258 pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
1259 }
1260
1261 // key Information element has done.
1262 *(USHORT *)(&pMsg->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo));
1263
1264 // Fill in Key Length
1265#if 0
1266 if (bWPA2)
1267 {
1268 // In WPA2 mode, the field indicates the length of pairwise key cipher,
1269 // so only pairwise_msg_1 and pairwise_msg_3 need to fill.
1270 if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3))
1271 pMsg->KeyDesc.KeyLength[1] = ((WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);
1272 }
1273 else if (!bWPA2)
1274#endif
1275 {
1276 if (MsgType >= EAPOL_GROUP_MSG_1)
1277 {
1278 // the length of group key cipher
1279 pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY);
1280 }
1281 else
1282 {
1283 // the length of pairwise key cipher
1284 pMsg->KeyDesc.KeyLength[1] = ((WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);
1285 }
1286 }
1287
1288 // Fill in replay counter
1289 NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, ReplayCounter, LEN_KEY_DESC_REPLAY);
1290
1291 // Fill Key Nonce field
1292 // ANonce : pairwise_msg1 & pairwise_msg3
1293 // SNonce : pairwise_msg2
1294 // GNonce : group_msg1_wpa1
1295 if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
1296 NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE);
1297
1298 // Fill key IV - WPA2 as 0, WPA1 as random
1299 if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
1300 {
1301 // Suggest IV be random number plus some number,
1302 NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV);
1303 pMsg->KeyDesc.KeyIv[15] += 2;
1304 }
1305
1306 // Fill Key RSC field
1307 // It contains the RSC for the GTK being installed.
1308 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
1309 {
1310 NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
1311 }
1312
1313 // Clear Key MIC field for MIC calculation later
1314 NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1315
1316 ConstructEapolKeyData(pAd,
1317 AuthMode,
1318 WepStatus,
1319 GroupKeyWepStatus,
1320 MsgType,
1321 DefaultKeyIdx,
1322 bWPA2,
1323 PTK,
1324 GTK,
1325 RSNIE,
1326 RSNIE_Len,
1327 pMsg);
1328
1329 // Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.
1330 if (MsgType != EAPOL_PAIR_MSG_1)
1331 {
1332 CalculateMIC(pAd, WepStatus, PTK, pMsg);
1333 }
1334
1335 DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
1336 DBGPRINT(RT_DEBUG_TRACE, (" Body length = %d \n", pMsg->Body_Len[1]));
1337 DBGPRINT(RT_DEBUG_TRACE, (" Key length = %d \n", pMsg->KeyDesc.KeyLength[1]));
1338
1339
1340}
1341
1342/*
1343 ========================================================================
1344
1345 Routine Description:
1346 Construct the Key Data field of EAPoL message
1347
1348 Arguments:
1349 pAd Pointer to our adapter
1350 Elem Message body
1351
1352 Return Value:
1353 None
1354
1355 Note:
1356
1357 ========================================================================
1358*/
1359VOID ConstructEapolKeyData(
1360 IN PRTMP_ADAPTER pAd,
1361 IN UCHAR AuthMode,
1362 IN UCHAR WepStatus,
1363 IN UCHAR GroupKeyWepStatus,
1364 IN UCHAR MsgType,
1365 IN UCHAR DefaultKeyIdx,
1366 IN BOOLEAN bWPA2Capable,
1367 IN UCHAR *PTK,
1368 IN UCHAR *GTK,
1369 IN UCHAR *RSNIE,
1370 IN UCHAR RSNIE_LEN,
1371 OUT PEAPOL_PACKET pMsg)
1372{
1373 UCHAR *mpool, *Key_Data, *Rc4GTK;
1374 UCHAR ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)];
1375 UCHAR data_offset;
1376
1377
1378 if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
1379 return;
1380
1381 // allocate memory pool
1382 os_alloc_mem(pAd, (PUCHAR *)&mpool, 1500);
1383
1384 if (mpool == NULL)
1385 return;
1386
1387 /* Rc4GTK Len = 512 */
1388 Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4);
1389 /* Key_Data Len = 512 */
1390 Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4);
1391
1392 NdisZeroMemory(Key_Data, 512);
1393 pMsg->KeyDesc.KeyDataLen[1] = 0;
1394 data_offset = 0;
1395
1396 // Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3
1397 if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3)))
1398 {
1399 if (bWPA2Capable)
1400 Key_Data[data_offset + 0] = IE_WPA2;
1401 else
1402 Key_Data[data_offset + 0] = IE_WPA;
1403
1404 Key_Data[data_offset + 1] = RSNIE_LEN;
1405 NdisMoveMemory(&Key_Data[data_offset + 2], RSNIE, RSNIE_LEN);
1406 data_offset += (2 + RSNIE_LEN);
1407 }
1408
1409 // Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2
1410 if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
1411 {
1412 // Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h
1413 Key_Data[data_offset + 0] = 0xDD;
1414
1415 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
1416 {
1417 Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField)
1418 }
1419 else
1420 {
1421 Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField)
1422 }
1423
1424 Key_Data[data_offset + 2] = 0x00;
1425 Key_Data[data_offset + 3] = 0x0F;
1426 Key_Data[data_offset + 4] = 0xAC;
1427 Key_Data[data_offset + 5] = 0x01;
1428
1429 // GTK KDE format - 802.11i-2004 Figure-43x
1430 Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
1431 Key_Data[data_offset + 7] = 0x00; // Reserved Byte
1432
1433 data_offset += 8;
1434 }
1435
1436
1437 // Encapsulate GTK and encrypt the key-data field with KEK.
1438 // Only for pairwise_msg3_WPA2 and group_msg1
1439 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1))
1440 {
1441 // Fill in GTK
1442 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
1443 {
1444 NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY);
1445 data_offset += LEN_AES_KEY;
1446 }
1447 else
1448 {
1449 NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH);
1450 data_offset += TKIP_GTK_LENGTH;
1451 }
1452
1453 // Still dont know why, but if not append will occur "GTK not include in MSG3"
1454 // Patch for compatibility between zero config and funk
1455 if (MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
1456 {
1457 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
1458 {
1459 Key_Data[data_offset + 0] = 0xDD;
1460 Key_Data[data_offset + 1] = 0;
1461 data_offset += 2;
1462 }
1463 else
1464 {
1465 Key_Data[data_offset + 0] = 0xDD;
1466 Key_Data[data_offset + 1] = 0;
1467 Key_Data[data_offset + 2] = 0;
1468 Key_Data[data_offset + 3] = 0;
1469 Key_Data[data_offset + 4] = 0;
1470 Key_Data[data_offset + 5] = 0;
1471 data_offset += 6;
1472 }
1473 }
1474
1475 // Encrypt the data material in key data field
1476 if (WepStatus == Ndis802_11Encryption3Enabled)
1477 {
1478 AES_GTK_KEY_WRAP(&PTK[16], Key_Data, data_offset, Rc4GTK);
1479 // AES wrap function will grow 8 bytes in length
1480 data_offset += 8;
1481 }
1482 else
1483 {
1484 // PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)
1485 // put TxTsc in Key RSC field
1486 pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
1487
1488 // ekey is the contanetion of IV-field, and PTK[16]->PTK[31]
1489 NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV);
1490 NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &PTK[16], LEN_EAP_EK);
1491 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); //INIT SBOX, KEYLEN+3(IV)
1492 pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset);
1493 WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset);
1494 }
1495
1496 NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
1497 }
1498 else
1499 {
1500 NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
1501 }
1502
1503 // set key data length field and total length
1504 pMsg->KeyDesc.KeyDataLen[1] = data_offset;
1505 pMsg->Body_Len[1] += data_offset;
1506
1507 os_free_mem(pAd, mpool);
1508
1509}
1510
1511/*
1512 ========================================================================
1513
1514 Routine Description:
1515 Calcaulate MIC. It is used during 4-ways handsharking.
1516
1517 Arguments:
1518 pAd - pointer to our pAdapter context
1519 PeerWepStatus - indicate the encryption type
1520
1521 Return Value:
1522
1523 Note:
1524
1525 ========================================================================
1526*/
1527VOID CalculateMIC(
1528 IN PRTMP_ADAPTER pAd,
1529 IN UCHAR PeerWepStatus,
1530 IN UCHAR *PTK,
1531 OUT PEAPOL_PACKET pMsg)
1532{
1533 UCHAR *OutBuffer;
1534 ULONG FrameLen = 0;
1535 UCHAR mic[LEN_KEY_DESC_MIC];
1536 UCHAR digest[80];
1537
1538 // allocate memory for MIC calculation
1539 os_alloc_mem(pAd, (PUCHAR *)&OutBuffer, 512);
1540
1541 if (OutBuffer == NULL)
1542 {
1543 DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n"));
1544 return;
1545 }
1546
1547 // make a frame for calculating MIC.
1548 MakeOutgoingFrame(OutBuffer, &FrameLen,
1549 pMsg->Body_Len[1] + 4, pMsg,
1550 END_OF_ARGS);
1551
1552 NdisZeroMemory(mic, sizeof(mic));
1553
1554 // Calculate MIC
1555 if (PeerWepStatus == Ndis802_11Encryption3Enabled)
1556 {
1557 HMAC_SHA1(OutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
1558 NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
1559 }
1560 else
1561 {
1562 hmac_md5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic);
1563 }
1564
1565 // store the calculated MIC
1566 NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
1567
1568 os_free_mem(pAd, OutBuffer);
1569}
1570
1571/*
1572 ========================================================================
1573
1574 Routine Description:
1575 Some received frames can't decrypt by Asic, so decrypt them by software.
1576
1577 Arguments:
1578 pAd - pointer to our pAdapter context
1579 PeerWepStatus - indicate the encryption type
1580
1581 Return Value:
1582 NDIS_STATUS_SUCCESS - decryption successful
1583 NDIS_STATUS_FAILURE - decryption failure
1584
1585 ========================================================================
1586*/
1587NDIS_STATUS RTMPSoftDecryptBroadCastData(
1588 IN PRTMP_ADAPTER pAd,
1589 IN RX_BLK *pRxBlk,
1590 IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,
1591 IN PCIPHER_KEY pShard_key)
1592{
1593 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
1594
1595
1596
1597 // handle WEP decryption
1598 if (GroupCipher == Ndis802_11Encryption1Enabled)
1599 {
1600 if (RTMPSoftDecryptWEP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, pShard_key))
1601 {
1602
1603 //Minus IV[4] & ICV[4]
1604 pRxWI->MPDUtotalByteCount -= 8;
1605 }
1606 else
1607 {
1608 DBGPRINT(RT_DEBUG_ERROR, ("ERROR : Software decrypt WEP data fails.\n"));
1609 // give up this frame
1610 return NDIS_STATUS_FAILURE;
1611 }
1612 }
1613 // handle TKIP decryption
1614 else if (GroupCipher == Ndis802_11Encryption2Enabled)
1615 {
1616 if (RTMPSoftDecryptTKIP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, pShard_key))
1617 {
1618
1619 //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
1620 pRxWI->MPDUtotalByteCount -= 20;
1621 }
1622 else
1623 {
1624 DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
1625 // give up this frame
1626 return NDIS_STATUS_FAILURE;
1627 }
1628 }
1629 // handle AES decryption
1630 else if (GroupCipher == Ndis802_11Encryption3Enabled)
1631 {
1632 if (RTMPSoftDecryptAES(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount , pShard_key))
1633 {
1634
1635 //8 bytes MIC, 8 bytes IV/EIV (CCMP Header)
1636 pRxWI->MPDUtotalByteCount -= 16;
1637 }
1638 else
1639 {
1640 DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptAES Failed\n"));
1641 // give up this frame
1642 return NDIS_STATUS_FAILURE;
1643 }
1644 }
1645 else
1646 {
1647 // give up this frame
1648 return NDIS_STATUS_FAILURE;
1649 }
1650
1651 return NDIS_STATUS_SUCCESS;
1652
1653}
1654
diff --git a/drivers/staging/rt2870/common/dfs.c b/drivers/staging/rt2870/common/dfs.c
new file mode 100644
index 00000000000..23cf1510e2d
--- /dev/null
+++ b/drivers/staging/rt2870/common/dfs.c
@@ -0,0 +1,453 @@
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#if 0
84 // toggle Rx enable bit for radar detection.
85 // it's Andy's recommand.
86 {
87 UINT32 Value;
88 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
89 Value |= (0x1 << 3);
90 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
91 Value &= ~(0x1 << 3);
92 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
93 }
94#endif
95 RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
96 (RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
97
98 RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
99 RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
100
101 RadarDetectionStart(pAd, 0, RadarPeriod);
102 return;
103}
104
105/*
106 ========================================================================
107
108 Routine Description:
109 Bbp Radar detection routine
110
111 Arguments:
112 pAd Pointer to our adapter
113
114 Return Value:
115
116 ========================================================================
117*/
118VOID BbpRadarDetectionStop(
119 IN PRTMP_ADAPTER pAd)
120{
121 RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
122 RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
123
124 RadarDetectionStop(pAd);
125 return;
126}
127
128/*
129 ========================================================================
130
131 Routine Description:
132 Radar detection routine
133
134 Arguments:
135 pAd Pointer to our adapter
136
137 Return Value:
138
139 ========================================================================
140*/
141VOID RadarDetectionStart(
142 IN PRTMP_ADAPTER pAd,
143 IN BOOLEAN CTSProtect,
144 IN UINT8 CTSPeriod)
145{
146 UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
147 UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
148
149 if (CTSProtect != 0)
150 {
151 switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
152 {
153 case FCC:
154 case JAP_W56:
155 CtsProtect = 0x03;
156 break;
157
158 case CE:
159 case JAP_W53:
160 default:
161 CtsProtect = 0x02;
162 break;
163 }
164 }
165 else
166 CtsProtect = 0x01;
167
168
169 // send start-RD with CTS protection command to MCU
170 // highbyte [7] reserve
171 // highbyte [6:5] 0x: stop Carrier/Radar detection
172 // highbyte [10]: Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
173 // highbyte [4:0] Radar/carrier detection duration. In 1ms.
174
175 // lowbyte [7:0] Radar/carrier detection period, in 1ms.
176 AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
177 //AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
178
179 return;
180}
181
182/*
183 ========================================================================
184
185 Routine Description:
186 Radar detection routine
187
188 Arguments:
189 pAd Pointer to our adapter
190
191 Return Value:
192 TRUE Found radar signal
193 FALSE Not found radar signal
194
195 ========================================================================
196*/
197VOID RadarDetectionStop(
198 IN PRTMP_ADAPTER pAd)
199{
200 DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
201 AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00); // send start-RD with CTS protection command to MCU
202
203 return;
204}
205
206/*
207 ========================================================================
208
209 Routine Description:
210 Radar channel check routine
211
212 Arguments:
213 pAd Pointer to our adapter
214
215 Return Value:
216 TRUE need to do radar detect
217 FALSE need not to do radar detect
218
219 ========================================================================
220*/
221BOOLEAN RadarChannelCheck(
222 IN PRTMP_ADAPTER pAd,
223 IN UCHAR Ch)
224{
225#if 1
226 INT i;
227 BOOLEAN result = FALSE;
228
229 for (i=0; i<pAd->ChannelListNum; i++)
230 {
231 if (Ch == pAd->ChannelList[i].Channel)
232 {
233 result = pAd->ChannelList[i].DfsReq;
234 break;
235 }
236 }
237
238 return result;
239#else
240 INT i;
241 UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
242
243 for (i=0; i<15; i++)
244 {
245 if (Ch == Channel[i])
246 {
247 break;
248 }
249 }
250
251 if (i != 15)
252 return TRUE;
253 else
254 return FALSE;
255#endif
256}
257
258ULONG JapRadarType(
259 IN PRTMP_ADAPTER pAd)
260{
261 ULONG i;
262 const UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
263
264 if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
265 {
266 return pAd->CommonCfg.RadarDetect.RDDurRegion;
267 }
268
269 for (i=0; i<15; i++)
270 {
271 if (pAd->CommonCfg.Channel == Channel[i])
272 {
273 break;
274 }
275 }
276
277 if (i < 4)
278 return JAP_W53;
279 else if (i < 15)
280 return JAP_W56;
281 else
282 return JAP; // W52
283
284}
285
286ULONG RTMPBbpReadRadarDuration(
287 IN PRTMP_ADAPTER pAd)
288{
289 UINT8 byteValue = 0;
290 ULONG result;
291
292 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
293
294 result = 0;
295 switch (byteValue)
296 {
297 case 1: // radar signal detected by pulse mode.
298 case 2: // radar signal detected by width mode.
299 result = RTMPReadRadarDuration(pAd);
300 break;
301
302 case 0: // No radar signal.
303 default:
304
305 result = 0;
306 break;
307 }
308
309 return result;
310}
311
312ULONG RTMPReadRadarDuration(
313 IN PRTMP_ADAPTER pAd)
314{
315 ULONG result = 0;
316
317#ifdef DFS_SUPPORT
318 UINT8 duration1 = 0, duration2 = 0, duration3 = 0;
319
320 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R116, &duration1);
321 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R117, &duration2);
322 BBP_IO_READ8_BY_REG_ID(pAd, BBP_R118, &duration3);
323 result = (duration1 << 16) + (duration2 << 8) + duration3;
324#endif // DFS_SUPPORT //
325
326 return result;
327
328}
329
330VOID RTMPCleanRadarDuration(
331 IN PRTMP_ADAPTER pAd)
332{
333 return;
334}
335
336/*
337 ========================================================================
338 Routine Description:
339 Radar wave detection. The API should be invoke each second.
340
341 Arguments:
342 pAd - Adapter pointer
343
344 Return Value:
345 None
346
347 ========================================================================
348*/
349VOID ApRadarDetectPeriodic(
350 IN PRTMP_ADAPTER pAd)
351{
352 INT i;
353
354 pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
355
356 for (i=0; i<pAd->ChannelListNum; i++)
357 {
358 if (pAd->ChannelList[i].RemainingTimeForUse > 0)
359 {
360 pAd->ChannelList[i].RemainingTimeForUse --;
361 if ((pAd->Mlme.PeriodicRound%5) == 0)
362 {
363 DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
364 }
365 }
366 }
367
368 //radar detect
369 if ((pAd->CommonCfg.Channel > 14)
370 && (pAd->CommonCfg.bIEEE80211H == 1)
371 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
372 {
373 RadarDetectPeriodic(pAd);
374 }
375
376 return;
377}
378
379// Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
380// Before switch channel, driver needs doing channel switch announcement.
381VOID RadarDetectPeriodic(
382 IN PRTMP_ADAPTER pAd)
383{
384 // need to check channel availability, after switch channel
385 if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
386 return;
387
388 // channel availability check time is 60sec, use 65 for assurance
389 if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
390 {
391 DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
392 BbpRadarDetectionStop(pAd);
393 AsicEnableBssSync(pAd);
394 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
395
396
397 return;
398 }
399
400 return;
401}
402
403
404/*
405 ==========================================================================
406 Description:
407 change channel moving time for DFS testing.
408
409 Arguments:
410 pAdapter Pointer to our adapter
411 wrq Pointer to the ioctl argument
412
413 Return Value:
414 None
415
416 Note:
417 Usage:
418 1.) iwpriv ra0 set ChMovTime=[value]
419 ==========================================================================
420*/
421INT Set_ChMovingTime_Proc(
422 IN PRTMP_ADAPTER pAd,
423 IN PUCHAR arg)
424{
425 UINT8 Value;
426
427 Value = simple_strtol(arg, 0, 10);
428
429 pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
430
431 DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
432 pAd->CommonCfg.RadarDetect.ChMovingTime));
433
434 return TRUE;
435}
436
437INT Set_LongPulseRadarTh_Proc(
438 IN PRTMP_ADAPTER pAd,
439 IN PUCHAR arg)
440{
441 UINT8 Value;
442
443 Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
444
445 pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
446
447 DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
448 pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
449
450 return TRUE;
451}
452
453
diff --git a/drivers/staging/rt2870/common/eeprom.c b/drivers/staging/rt2870/common/eeprom.c
new file mode 100644
index 00000000000..33f16ed9c49
--- /dev/null
+++ b/drivers/staging/rt2870/common/eeprom.c
@@ -0,0 +1,254 @@
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#if 0
40#define EEPROM_SIZE 0x200
41#define NVRAM_OFFSET 0x30000
42#define RF_OFFSET 0x40000
43
44static UCHAR init_flag = 0;
45static PUCHAR nv_ee_start = 0;
46
47static UCHAR EeBuffer[EEPROM_SIZE];
48#endif
49// IRQL = PASSIVE_LEVEL
50VOID RaiseClock(
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); // Max frequency = 1MHz in Spec. definition
57}
58
59// IRQL = PASSIVE_LEVEL
60VOID LowerClock(
61 IN PRTMP_ADAPTER pAd,
62 IN UINT32 *x)
63{
64 *x = *x & ~EESK;
65 RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
66 RTMPusecDelay(1);
67}
68
69// IRQL = PASSIVE_LEVEL
70USHORT ShiftInBits(
71 IN PRTMP_ADAPTER pAd)
72{
73 UINT32 x,i;
74 USHORT data=0;
75
76 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
77
78 x &= ~( EEDO | EEDI);
79
80 for(i=0; i<16; i++)
81 {
82 data = data << 1;
83 RaiseClock(pAd, &x);
84
85 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
86
87 x &= ~(EEDI);
88 if(x & EEDO)
89 data |= 1;
90
91 LowerClock(pAd, &x);
92 }
93
94 return data;
95}
96
97// IRQL = PASSIVE_LEVEL
98VOID ShiftOutBits(
99 IN PRTMP_ADAPTER pAd,
100 IN USHORT data,
101 IN USHORT count)
102{
103 UINT32 x,mask;
104
105 mask = 0x01 << (count - 1);
106 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
107
108 x &= ~(EEDO | EEDI);
109
110 do
111 {
112 x &= ~EEDI;
113 if(data & mask) x |= EEDI;
114
115 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
116
117 RaiseClock(pAd, &x);
118 LowerClock(pAd, &x);
119
120 mask = mask >> 1;
121 } while(mask);
122
123 x &= ~EEDI;
124 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
125}
126
127// IRQL = PASSIVE_LEVEL
128VOID EEpromCleanup(
129 IN PRTMP_ADAPTER pAd)
130{
131 UINT32 x;
132
133 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
134
135 x &= ~(EECS | EEDI);
136 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
137
138 RaiseClock(pAd, &x);
139 LowerClock(pAd, &x);
140}
141
142VOID EWEN(
143 IN PRTMP_ADAPTER pAd)
144{
145 UINT32 x;
146
147 // reset bits and set EECS
148 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
149 x &= ~(EEDI | EEDO | EESK);
150 x |= EECS;
151 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
152
153 // kick a pulse
154 RaiseClock(pAd, &x);
155 LowerClock(pAd, &x);
156
157 // output the read_opcode and six pulse in that order
158 ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
159 ShiftOutBits(pAd, 0, 6);
160
161 EEpromCleanup(pAd);
162}
163
164VOID EWDS(
165 IN PRTMP_ADAPTER pAd)
166{
167 UINT32 x;
168
169 // reset bits and set EECS
170 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
171 x &= ~(EEDI | EEDO | EESK);
172 x |= EECS;
173 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
174
175 // kick a pulse
176 RaiseClock(pAd, &x);
177 LowerClock(pAd, &x);
178
179 // output the read_opcode and six pulse in that order
180 ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
181 ShiftOutBits(pAd, 0, 6);
182
183 EEpromCleanup(pAd);
184}
185
186// IRQL = PASSIVE_LEVEL
187USHORT RTMP_EEPROM_READ16(
188 IN PRTMP_ADAPTER pAd,
189 IN USHORT Offset)
190{
191 UINT32 x;
192 USHORT data;
193
194 Offset /= 2;
195 // reset bits and set EECS
196 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
197 x &= ~(EEDI | EEDO | EESK);
198 x |= EECS;
199 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
200
201 // kick a pulse
202 RaiseClock(pAd, &x);
203 LowerClock(pAd, &x);
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 return data;
215} //ReadEEprom
216
217VOID RTMP_EEPROM_WRITE16(
218 IN PRTMP_ADAPTER pAd,
219 IN USHORT Offset,
220 IN USHORT Data)
221{
222 UINT32 x;
223
224 Offset /= 2;
225
226 EWEN(pAd);
227
228 // reset bits and set EECS
229 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
230 x &= ~(EEDI | EEDO | EESK);
231 x |= EECS;
232 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
233
234 // kick a pulse
235 RaiseClock(pAd, &x);
236 LowerClock(pAd, &x);
237
238 // output the read_opcode ,register number and data in that order
239 ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
240 ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
241 ShiftOutBits(pAd, Data, 16); // 16-bit access
242
243 // read DO status
244 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
245
246 EEpromCleanup(pAd);
247
248 RTMPusecDelay(10000); //delay for twp(MAX)=10ms
249
250 EWDS(pAd);
251
252 EEpromCleanup(pAd);
253}
254
diff --git a/drivers/staging/rt2870/common/firmware.h b/drivers/staging/rt2870/common/firmware.h
new file mode 100644
index 00000000000..a40669895ef
--- /dev/null
+++ b/drivers/staging/rt2870/common/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, 0x79, 0x02,
480x12, 0x7a, 0x02, 0x12, 0x99, 0x02, 0x12, 0x9e, 0x12, 0x12, 0x9a, 0x22, 0x02, 0x16, 0x36, 0x02,
490x17, 0x0c, 0x02, 0x13, 0x89, 0x02, 0x12, 0x9f, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
500xae, 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, 0x6e, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
560xb7, 0x31, 0x10, 0xe2, 0x50, 0x11, 0x08, 0x51, 0x11, 0x13, 0x52, 0x11, 0x13, 0x53, 0x11, 0x13,
570x54, 0x11, 0x54, 0x55, 0x11, 0x79, 0x70, 0x11, 0xa4, 0x71, 0x11, 0xd2, 0x72, 0x12, 0x25, 0x73,
580x12, 0x46, 0x80, 0x00, 0x00, 0x12, 0x6e, 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, 0x6e, 0x02, 0x12, 0x67, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x02,
610x12, 0x6e, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x6e, 0x90,
620x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x6e, 0x75,
630x4e, 0x03, 0x75, 0x4f, 0x20, 0x02, 0x12, 0x6e, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47,
640x02, 0x12, 0x6e, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10,
650xe0, 0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74,
660x48, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04,
670x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12,
680x6e, 0x02, 0x12, 0x67, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05,
690xe5, 0x47, 0xb4, 0x09, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe4, 0xfd, 0xaf,
700x56, 0x12, 0x0b, 0x91, 0xd2, 0x04, 0x02, 0x12, 0x6e, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
710x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04,
720x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12,
730x6e, 0x02, 0x12, 0x67, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5,
740x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74,
750x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x6e, 0x02,
760x12, 0x67, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0, 0xb4, 0x30, 0x19, 0x90, 0x05,
770x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0,
780xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0xad,
790x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13,
800xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x70, 0x40,
810xe5, 0x3a, 0xf0, 0x80, 0x49, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf,
820x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
830x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05,
840xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70,
850x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x70,
860x42, 0xe5, 0x3a, 0xf0, 0xa3, 0x74, 0xab, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60,
870x09, 0xb2, 0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08,
880xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2,
890x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a, 0x9d, 0x12, 0xc1, 0x00, 0x13, 0x54, 0x04, 0x13, 0x50,
900x08, 0x13, 0x2b, 0x10, 0x12, 0xd5, 0x20, 0x12, 0xf5, 0x60, 0x13, 0x06, 0xa0, 0x00, 0x00, 0x13,
910x56, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03,
920x02, 0x13, 0x56, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54,
930x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66,
940x53, 0x43, 0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47,
950x64, 0x06, 0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4,
960x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70,
970x35, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06,
980x53, 0x5e, 0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42,
990x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06,
1000xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5,
1010x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5,
1020x4a, 0xf0, 0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5,
1030x42, 0xf0, 0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70,
1040x03, 0x12, 0x16, 0x16, 0x12, 0x13, 0x9e, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf,
1050x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f,
1060x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e,
1070xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f,
1080x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25,
1090x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5,
1100x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47,
1110x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70,
1120x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15,
1130x25, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5,
1140x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70,
1150x46, 0xe5, 0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b,
1160x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02,
1170xb2, 0x6c, 0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68,
1180x80, 0x26, 0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04,
1190x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
1200x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2,
1210x6a, 0x80, 0x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0,
1220x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e,
1230x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04,
1240xa2, 0x6c, 0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20,
1250xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04,
1260x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10,
1270x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe,
1280xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23, 0x24, 0x03, 0x60,
1290x03, 0x02, 0x16, 0x05, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07, 0x90, 0x02, 0x28,
1300xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x05, 0x44, 0x01, 0xf0, 0x02, 0x16, 0x05,
1310xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02, 0x28, 0xe0, 0x54,
1320xfe, 0x4f, 0xf0, 0x02, 0x16, 0x05, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5, 0x47, 0x64, 0x08,
1330x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x05, 0xe4, 0xf5, 0x27, 0x90, 0x02,
1340x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e, 0x14, 0x60, 0x36,
1350x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5, 0x46, 0x13, 0x13,
1360x54, 0x3f, 0x75, 0xf0, 0x01, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e,
1370x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46, 0x30, 0xe2, 0x03,
1380xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30,
1390x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47, 0x04, 0x7d,
1400x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2, 0x47, 0xb3, 0x92,
1410x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xa2, 0x47,
1420xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90, 0x02, 0x28, 0xe0,
1430x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5, 0x47, 0xf0, 0x90,
1440x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45,
1450x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59,
1460x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x46,
1470x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x16, 0xf0, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90,
1480x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04, 0x34, 0xe0, 0xb4,
1490x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f, 0x20, 0x12, 0x16,
1500x2c, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73, 0xe5, 0x50, 0x70,
1510x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x11, 0x7f, 0x20,
1520x12, 0x16, 0x2c, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x80, 0x51, 0xe5,
1530x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90, 0x04, 0x37, 0xe0,
1540x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12,
1550x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0,
1560xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75, 0x62, 0x01, 0x75,
1570x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0xf5, 0x51,
1580xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62, 0xaf, 0x40, 0x12,
1590x17, 0x7a, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01,
1600x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40,
1610x12, 0x17, 0x7a, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52, 0x01, 0x75, 0x55,
1620x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3,
1630xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x03, 0xf0, 0x90,
1640x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52,
1650xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17, 0x7a, 0x80, 0x02,
1660xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe,
1670x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14,
1680x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4,
1690x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70,
1700x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90,
1710x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90,
1720x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0,
1730x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0,
1740x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05,
1750xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x0a, 0x69, 0x77,
3030xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x25, 0x02,
3040x12, 0x26, 0x02, 0x12, 0x39, 0x02, 0x12, 0x3e, 0x12, 0x12, 0x3a, 0x22, 0x02, 0x15, 0x72, 0x02,
3050x16, 0x48, 0x02, 0x13, 0x29, 0x02, 0x12, 0x3f, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x16,
3060xea, 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, 0x1a, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
3120xb4, 0x31, 0x10, 0xdf, 0x50, 0x11, 0x05, 0x51, 0x11, 0x10, 0x52, 0x11, 0x10, 0x53, 0x11, 0x10,
3130x54, 0x11, 0x51, 0x55, 0x11, 0x70, 0x70, 0x11, 0x9a, 0x71, 0x11, 0xc4, 0x72, 0x11, 0xf2, 0x80,
3140x00, 0x00, 0x12, 0x1a, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x0b,
3150xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
3160x03, 0x02, 0x12, 0x1a, 0x02, 0x12, 0x13, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x02, 0x12, 0x1a, 0x90,
3170x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x1a, 0x90, 0x70, 0x11, 0xe0,
3180x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x1a, 0x75, 0x4e, 0x03, 0x75,
3190x4f, 0x20, 0x02, 0x12, 0x1a, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x02, 0x12, 0x1a,
3200x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74,
3210x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57,
3220xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80,
3230xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x1a, 0x02, 0x12,
3240x13, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x08, 0x08, 0x90, 0x70, 0x11, 0xe0,
3250x54, 0x07, 0xf5, 0x3a, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2, 0x04, 0x02, 0x12, 0x1a,
3260x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd,
3270xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0,
3280xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x1a, 0x80, 0x79, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90,
3290x70, 0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12,
3300x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4,
3310x60, 0x58, 0x80, 0x4f, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56,
3320x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
3330xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x70, 0x40, 0xe5, 0x3a, 0xf0,
3340x80, 0x28, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56,
3350x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
3360xf4, 0x60, 0x07, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x70, 0x42, 0xe5, 0x3a, 0xf0,
3370xa3, 0x74, 0xab, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x0e, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08,
3380xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2,
3390x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x0a, 0xb6, 0x12, 0x61, 0x00, 0x12, 0xf4, 0x04, 0x12, 0xf0,
3400x08, 0x12, 0xcb, 0x10, 0x12, 0x75, 0x20, 0x12, 0x95, 0x60, 0x12, 0xa6, 0xa0, 0x00, 0x00, 0x12,
3410xf6, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03,
3420x02, 0x12, 0xf6, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54,
3430x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66,
3440x53, 0x43, 0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47,
3450x64, 0x06, 0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4,
3460x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70,
3470x35, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06,
3480x53, 0x5e, 0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42,
3490x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06,
3500xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5,
3510x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5,
3520x4a, 0xf0, 0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5,
3530x42, 0xf0, 0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70,
3540x03, 0x12, 0x15, 0x52, 0x12, 0x13, 0x3e, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf,
3550x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f,
3560x24, 0xff, 0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e,
3570xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f,
3580x20, 0xe5, 0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25,
3590x70, 0x05, 0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5,
3600x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47,
3610x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70,
3620x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15,
3630x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5, 0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e,
3640x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20,
3650x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75,
3660x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x15, 0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe3,
3670x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x73,
3680x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x15, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe3,
3690x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x75,
3700x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x15, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3,
3710x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x71,
3720x92, 0x70, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02,
3730x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60,
3740x23, 0x24, 0x03, 0x60, 0x03, 0x02, 0x15, 0x41, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80,
3750x07, 0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x15, 0x41, 0x44, 0x01,
3760xf0, 0x02, 0x15, 0x41, 0xe5, 0x46, 0x30, 0xe3, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90,
3770x02, 0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x15, 0x41, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x09,
3780xe5, 0x47, 0x64, 0x08, 0x60, 0x03, 0x02, 0x15, 0x41, 0xe4, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0,
3790x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x26, 0x14, 0x60, 0x2e, 0x14, 0x60, 0x36, 0x24, 0x03,
3800x70, 0x5f, 0xe5, 0x46, 0x13, 0x13, 0x13, 0x54, 0x1f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20,
3810x47, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x02, 0xa2, 0x47,
3820x92, 0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x3f, 0xe5, 0x46, 0x30, 0xe3, 0x03, 0xd3, 0x80,
3830x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe3, 0x0d, 0x54, 0x70, 0xc3, 0x94, 0x60, 0x50, 0x06,
3840x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47, 0x04, 0x7d, 0x01, 0x80,
3850x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2, 0x47, 0xb3, 0x92, 0x39, 0x80,
3860x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90, 0x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27,
3870xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5, 0x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a,
3880xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45,
3890xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2,
3900x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24,
3910x02, 0x60, 0x03, 0x02, 0x16, 0x2c, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54,
3920x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0,
3930xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f, 0x20, 0x12, 0x15, 0x68, 0x90, 0x10, 0x04,
3940xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03,
3950x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70, 0x11, 0x7f, 0x20, 0x12, 0x15, 0x68, 0x90,
3960x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02, 0x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80,
3970x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33,
3980x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0,
3990x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa,
4000xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75, 0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5,
4010x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15,
4020xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62, 0xaf, 0x40, 0x12, 0x16, 0xb6, 0xe5, 0x62,
4030xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01,
4040x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x16, 0xb6, 0xe5,
4050x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01,
4060xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0,
4070xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44,
4080xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02,
4090x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x16, 0xb6, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90,
4100x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5,
4110x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4,
4120x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83,
4130xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1,
4140x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90,
4150x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5,
4160x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0,
4170x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0,
4180x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01, 0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22,
4190x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x01, 0xe9, 0x00, } ;
diff --git a/drivers/staging/rt2870/common/md5.c b/drivers/staging/rt2870/common/md5.c
new file mode 100644
index 00000000000..774776b4b8c
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/common/mlme.c b/drivers/staging/rt2870/common/mlme.c
new file mode 100644
index 00000000000..8a82cee8bf2
--- /dev/null
+++ b/drivers/staging/rt2870/common/mlme.c
@@ -0,0 +1,8609 @@
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#define NUM_OF_3020_CHNL (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM))
470
471/*
472 ==========================================================================
473 Description:
474 initialize the MLME task and its data structure (queue, spinlock,
475 timer, state machines).
476
477 IRQL = PASSIVE_LEVEL
478
479 Return:
480 always return NDIS_STATUS_SUCCESS
481
482 ==========================================================================
483*/
484NDIS_STATUS MlmeInit(
485 IN PRTMP_ADAPTER pAd)
486{
487 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
488
489 DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
490
491 do
492 {
493 Status = MlmeQueueInit(&pAd->Mlme.Queue);
494 if(Status != NDIS_STATUS_SUCCESS)
495 break;
496
497 pAd->Mlme.bRunning = FALSE;
498 NdisAllocateSpinLock(&pAd->Mlme.TaskLock);
499
500#ifdef CONFIG_STA_SUPPORT
501 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
502 {
503 BssTableInit(&pAd->ScanTab);
504
505 // init STA state machines
506 AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc);
507 AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
508 AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
509 SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
510 WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc);
511 AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc);
512
513#ifdef QOS_DLS_SUPPORT
514 DlsStateMachineInit(pAd, &pAd->Mlme.DlsMachine, pAd->Mlme.DlsFunc);
515#endif // QOS_DLS_SUPPORT //
516
517
518 // Since we are using switch/case to implement it, the init is different from the above
519 // state machine init
520 MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
521 }
522#endif // CONFIG_STA_SUPPORT //
523
524
525
526 ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
527
528 // Init mlme periodic timer
529 RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
530
531 // Set mlme periodic timer
532 RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
533
534 // software-based RX Antenna diversity
535 RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
536
537 } while (FALSE);
538
539 DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
540
541 return Status;
542}
543
544/*
545 ==========================================================================
546 Description:
547 main loop of the MLME
548 Pre:
549 Mlme has to be initialized, and there are something inside the queue
550 Note:
551 This function is invoked from MPSetInformation and MPReceive;
552 This task guarantee only one MlmeHandler will run.
553
554 IRQL = DISPATCH_LEVEL
555
556 ==========================================================================
557 */
558VOID MlmeHandler(
559 IN PRTMP_ADAPTER pAd)
560{
561 MLME_QUEUE_ELEM *Elem = NULL;
562#ifdef APCLI_SUPPORT
563 SHORT apcliIfIndex;
564#endif
565
566 // Only accept MLME and Frame from peer side, no other (control/data) frame should
567 // get into this state machine
568
569 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
570 if(pAd->Mlme.bRunning)
571 {
572 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
573 return;
574 }
575 else
576 {
577 pAd->Mlme.bRunning = TRUE;
578 }
579 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
580
581 while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
582 {
583 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
584 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
585 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
586 {
587 DBGPRINT(RT_DEBUG_TRACE, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd->Mlme.Queue.Num));
588 break;
589 }
590
591#ifdef RALINK_ATE
592 if(ATE_ON(pAd))
593 {
594 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now in MlmeHandler\n"));
595 break;
596 }
597#endif // RALINK_ATE //
598
599 //From message type, determine which state machine I should drive
600 if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
601 {
602#ifdef RT2870
603 if (Elem->MsgType == MT2_RESET_CONF)
604 {
605 DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n"));
606 MlmeRestartStateMachine(pAd);
607 Elem->Occupied = FALSE;
608 Elem->MsgLen = 0;
609 continue;
610 }
611#endif // RT2870 //
612
613 // if dequeue success
614 switch (Elem->Machine)
615 {
616 // STA state machines
617#ifdef CONFIG_STA_SUPPORT
618 case ASSOC_STATE_MACHINE:
619 StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem);
620 break;
621 case AUTH_STATE_MACHINE:
622 StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem);
623 break;
624 case AUTH_RSP_STATE_MACHINE:
625 StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem);
626 break;
627 case SYNC_STATE_MACHINE:
628 StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem);
629 break;
630 case MLME_CNTL_STATE_MACHINE:
631 MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem);
632 break;
633 case WPA_PSK_STATE_MACHINE:
634 StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
635 break;
636#ifdef LEAP_SUPPORT
637 case LEAP_STATE_MACHINE:
638 LeapMachinePerformAction(pAd, &pAd->Mlme.LeapMachine, Elem);
639 break;
640#endif
641 case AIRONET_STATE_MACHINE:
642 StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem);
643 break;
644
645#ifdef QOS_DLS_SUPPORT
646 case DLS_STATE_MACHINE:
647 StateMachinePerformAction(pAd, &pAd->Mlme.DlsMachine, Elem);
648 break;
649#endif // QOS_DLS_SUPPORT //
650#endif // CONFIG_STA_SUPPORT //
651
652 case ACTION_STATE_MACHINE:
653 StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
654 break;
655
656
657
658
659 default:
660 DBGPRINT(RT_DEBUG_TRACE, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem->Machine));
661 break;
662 } // end of switch
663
664 // free MLME element
665 Elem->Occupied = FALSE;
666 Elem->MsgLen = 0;
667
668 }
669 else {
670 DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
671 }
672 }
673
674 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
675 pAd->Mlme.bRunning = FALSE;
676 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
677}
678
679/*
680 ==========================================================================
681 Description:
682 Destructor of MLME (Destroy queue, state machine, spin lock and timer)
683 Parameters:
684 Adapter - NIC Adapter pointer
685 Post:
686 The MLME task will no longer work properly
687
688 IRQL = PASSIVE_LEVEL
689
690 ==========================================================================
691 */
692VOID MlmeHalt(
693 IN PRTMP_ADAPTER pAd)
694{
695 BOOLEAN Cancelled;
696
697 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
698
699 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
700 {
701 // disable BEACON generation and other BEACON related hardware timers
702 AsicDisableSync(pAd);
703 }
704
705#ifdef CONFIG_STA_SUPPORT
706 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
707 {
708#ifdef QOS_DLS_SUPPORT
709 UCHAR i;
710#endif // QOS_DLS_SUPPORT //
711 // Cancel pending timers
712 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
713 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
714 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
715 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
716 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
717 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
718
719#ifdef QOS_DLS_SUPPORT
720 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
721 {
722 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
723 }
724#endif // QOS_DLS_SUPPORT //
725 }
726#endif // CONFIG_STA_SUPPORT //
727
728 RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
729 RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled);
730
731
732
733 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
734 {
735 // Set LED
736 RTMPSetLED(pAd, LED_HALT);
737 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
738#ifdef RT2870
739 {
740 LED_CFG_STRUC LedCfg;
741 RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
742 LedCfg.field.LedPolar = 0;
743 LedCfg.field.RLedMode = 0;
744 LedCfg.field.GLedMode = 0;
745 LedCfg.field.YLedMode = 0;
746 RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
747 }
748#endif // RT2870 //
749 }
750
751 RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled
752
753 MlmeQueueDestroy(&pAd->Mlme.Queue);
754 NdisFreeSpinLock(&pAd->Mlme.TaskLock);
755
756 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
757}
758
759VOID MlmeResetRalinkCounters(
760 IN PRTMP_ADAPTER pAd)
761{
762 pAd->RalinkCounters.LastOneSecRxOkDataCnt = pAd->RalinkCounters.OneSecRxOkDataCnt;
763 // clear all OneSecxxx counters.
764 pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
765 pAd->RalinkCounters.OneSecFalseCCACnt = 0;
766 pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
767 pAd->RalinkCounters.OneSecRxOkCnt = 0;
768 pAd->RalinkCounters.OneSecTxFailCount = 0;
769 pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
770 pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
771 pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
772
773 // TODO: for debug only. to be removed
774 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
775 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
776 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
777 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0;
778 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0;
779 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0;
780 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0;
781 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0;
782 pAd->RalinkCounters.OneSecTxDoneCount = 0;
783 pAd->RalinkCounters.OneSecRxCount = 0;
784 pAd->RalinkCounters.OneSecTxAggregationCount = 0;
785 pAd->RalinkCounters.OneSecRxAggregationCount = 0;
786
787 return;
788}
789
790unsigned long rx_AMSDU;
791unsigned long rx_Total;
792
793/*
794 ==========================================================================
795 Description:
796 This routine is executed periodically to -
797 1. Decide if it's a right time to turn on PwrMgmt bit of all
798 outgoiing frames
799 2. Calculate ChannelQuality based on statistics of the last
800 period, so that TX rate won't toggling very frequently between a
801 successful TX and a failed TX.
802 3. If the calculated ChannelQuality indicated current connection not
803 healthy, then a ROAMing attempt is tried here.
804
805 IRQL = DISPATCH_LEVEL
806
807 ==========================================================================
808 */
809#define ADHOC_BEACON_LOST_TIME (8*OS_HZ) // 8 sec
810VOID MlmePeriodicExec(
811 IN PVOID SystemSpecific1,
812 IN PVOID FunctionContext,
813 IN PVOID SystemSpecific2,
814 IN PVOID SystemSpecific3)
815{
816 ULONG TxTotalCnt;
817 PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
818
819 // Do nothing if the driver is starting halt state.
820 // This might happen when timer already been fired before cancel timer with mlmehalt
821 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS |
822 fRTMP_ADAPTER_RADIO_OFF |
823 fRTMP_ADAPTER_RADIO_MEASUREMENT |
824 fRTMP_ADAPTER_RESET_IN_PROGRESS))))
825 return;
826
827 RT28XX_MLME_PRE_SANITY_CHECK(pAd);
828
829#ifdef RALINK_ATE
830 /* Do not show RSSI until "Normal 1 second Mlme PeriodicExec". */
831 if (ATE_ON(pAd))
832 {
833 if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE != (MLME_TASK_EXEC_MULTIPLE - 1))
834 {
835 pAd->Mlme.PeriodicRound ++;
836 return;
837 }
838 }
839#endif // RALINK_ATE //
840
841#ifdef CONFIG_STA_SUPPORT
842 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
843 {
844 // Do nothing if monitor mode is on
845 if (MONITOR_ON(pAd))
846 return;
847
848 if (pAd->Mlme.PeriodicRound & 0x1)
849 {
850 // This is the fix for wifi 11n extension channel overlapping test case. for 2860D
851 if (((pAd->MACVersion & 0xffff) == 0x0101) &&
852 (STA_TGN_WIFI_ON(pAd)) &&
853 (pAd->CommonCfg.IOTestParm.bToggle == FALSE))
854
855 {
856 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
857 pAd->CommonCfg.IOTestParm.bToggle = TRUE;
858 }
859 else if ((STA_TGN_WIFI_ON(pAd)) &&
860 ((pAd->MACVersion & 0xffff) == 0x0101))
861 {
862 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
863 pAd->CommonCfg.IOTestParm.bToggle = FALSE;
864 }
865 }
866 }
867#endif // CONFIG_STA_SUPPORT //
868
869 pAd->bUpdateBcnCntDone = FALSE;
870
871// RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
872 pAd->Mlme.PeriodicRound ++;
873
874 // execute every 500ms
875 if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
876 {
877#ifdef CONFIG_STA_SUPPORT
878 // perform dynamic tx rate switching based on past TX history
879 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
880 {
881 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
882 )
883 && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
884 MlmeDynamicTxRateSwitching(pAd);
885 }
886#endif // CONFIG_STA_SUPPORT //
887 }
888
889 // Normal 1 second Mlme PeriodicExec.
890 if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0)
891 {
892 pAd->Mlme.OneSecPeriodicRound ++;
893
894#ifdef RALINK_ATE
895 if (ATE_ON(pAd))
896 {
897 /* request from Baron : move this routine from later to here */
898 /* for showing Rx error count in ATE RXFRAME */
899 NICUpdateRawCounters(pAd);
900 if (pAd->ate.bRxFer == 1)
901 {
902 pAd->ate.RxTotalCnt += pAd->ate.RxCntPerSec;
903 ate_print(KERN_EMERG "MlmePeriodicExec: Rx packet cnt = %d/%d\n", pAd->ate.RxCntPerSec, pAd->ate.RxTotalCnt);
904 pAd->ate.RxCntPerSec = 0;
905
906 if (pAd->ate.RxAntennaSel == 0)
907 ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi0=%d, AvgRssi1=%d, AvgRssi2=%d\n\n",
908 pAd->ate.AvgRssi0, pAd->ate.AvgRssi1, pAd->ate.AvgRssi2);
909 else
910 ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi=%d\n\n", pAd->ate.AvgRssi0);
911 }
912 MlmeResetRalinkCounters(pAd);
913 return;
914 }
915#endif // RALINK_ATE //
916
917
918 if (rx_Total)
919 {
920
921 // reset counters
922 rx_AMSDU = 0;
923 rx_Total = 0;
924 }
925
926 //ORIBATimerTimeout(pAd);
927
928 // Media status changed, report to NDIS
929 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
930 {
931 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
932 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
933 {
934 pAd->IndicateMediaState = NdisMediaStateConnected;
935 RTMP_IndicateMediaState(pAd);
936
937 }
938 else
939 {
940 pAd->IndicateMediaState = NdisMediaStateDisconnected;
941 RTMP_IndicateMediaState(pAd);
942 }
943 }
944
945 NdisGetSystemUpTime(&pAd->Mlme.Now32);
946
947 // add the most up-to-date h/w raw counters into software variable, so that
948 // the dynamic tuning mechanism below are based on most up-to-date information
949 NICUpdateRawCounters(pAd);
950
951#ifdef RT2870
952 RT2870_WatchDog(pAd);
953#endif // RT2870 //
954
955#ifdef DOT11_N_SUPPORT
956 // Need statistics after read counter. So put after NICUpdateRawCounters
957 ORIBATimerTimeout(pAd);
958#endif // DOT11_N_SUPPORT //
959
960 // if MGMT RING is full more than twice within 1 second, we consider there's
961 // a hardware problem stucking the TX path. In this case, try a hardware reset
962 // to recover the system
963 // if (pAd->RalinkCounters.MgmtRingFullCount >= 2)
964 // RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR);
965 // else
966 // pAd->RalinkCounters.MgmtRingFullCount = 0;
967
968 // The time period for checking antenna is according to traffic
969 if (pAd->Mlme.bEnableAutoAntennaCheck)
970 {
971 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
972 pAd->RalinkCounters.OneSecTxRetryOkCount +
973 pAd->RalinkCounters.OneSecTxFailCount;
974
975 if (TxTotalCnt > 50)
976 {
977 if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
978 {
979 AsicEvaluateRxAnt(pAd);
980 }
981 }
982 else
983 {
984 if (pAd->Mlme.OneSecPeriodicRound % 3 == 0)
985 {
986 AsicEvaluateRxAnt(pAd);
987 }
988 }
989 }
990
991#ifdef CONFIG_STA_SUPPORT
992 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
993 STAMlmePeriodicExec(pAd);
994#endif // CONFIG_STA_SUPPORT //
995
996 MlmeResetRalinkCounters(pAd);
997
998#ifdef CONFIG_STA_SUPPORT
999 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1000 {
1001 {
1002 // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
1003 // and sending CTS-to-self over and over.
1004 // Software Patch Solution:
1005 // 1. Polling debug state register 0x10F4 every one second.
1006 // 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
1007 // 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
1008
1009 UINT32 MacReg = 0;
1010
1011 RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
1012 if (((MacReg & 0x20000000) && (MacReg & 0x80)) || ((MacReg & 0x20000000) && (MacReg & 0x20)))
1013 {
1014 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
1015 RTMPusecDelay(1);
1016 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
1017
1018 DBGPRINT(RT_DEBUG_WARN,("Warning, MAC specific condition occurs \n"));
1019 }
1020 }
1021 }
1022#endif // CONFIG_STA_SUPPORT //
1023
1024 RT28XX_MLME_HANDLER(pAd);
1025 }
1026
1027
1028 pAd->bUpdateBcnCntDone = FALSE;
1029}
1030
1031#ifdef CONFIG_STA_SUPPORT
1032VOID STAMlmePeriodicExec(
1033 PRTMP_ADAPTER pAd)
1034{
1035 ULONG TxTotalCnt;
1036 int i;
1037
1038//
1039// We return here in ATE mode, because the statistics
1040// that ATE needs are not collected via this routine.
1041//
1042#ifdef RALINK_ATE
1043 // It is supposed that we will never reach here in ATE mode.
1044 ASSERT(!(ATE_ON(pAd)));
1045 if (ATE_ON(pAd))
1046 return;
1047#endif // RALINK_ATE //
1048
1049#ifdef WPA_SUPPLICANT_SUPPORT
1050 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
1051#endif // WPA_SUPPLICANT_SUPPORT //
1052 {
1053 // WPA MIC error should block association attempt for 60 seconds
1054 if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32))
1055 pAd->StaCfg.bBlockAssoc = FALSE;
1056 }
1057
1058 if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
1059 {
1060 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1061 {
1062 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1063 }
1064 pAd->PreMediaState = pAd->IndicateMediaState;
1065 }
1066
1067
1068
1069
1070 AsicStaBbpTuning(pAd);
1071
1072 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
1073 pAd->RalinkCounters.OneSecTxRetryOkCount +
1074 pAd->RalinkCounters.OneSecTxFailCount;
1075
1076 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1077 {
1078 // update channel quality for Roaming and UI LinkQuality display
1079 MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32);
1080 }
1081
1082 // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
1083 // Radio is currently in noisy environment
1084 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1085 AsicAdjustTxPower(pAd);
1086
1087 if (INFRA_ON(pAd))
1088 {
1089#ifdef QOS_DLS_SUPPORT
1090 // Check DLS time out, then tear down those session
1091 RTMPCheckDLSTimeOut(pAd);
1092#endif // QOS_DLS_SUPPORT //
1093
1094 // Is PSM bit consistent with user power management policy?
1095 // This is the only place that will set PSM bit ON.
1096 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1097 MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
1098
1099 pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
1100
1101 if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) &&
1102 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
1103 ((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600)))
1104 {
1105 RTMPSetAGCInitValue(pAd, BW_20);
1106 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
1107 }
1108
1109 //if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
1110 // (pAd->RalinkCounters.OneSecTxRetryOkCount == 0))
1111 {
1112 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
1113 {
1114 // When APSD is enabled, the period changes as 20 sec
1115 if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
1116 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1117 }
1118 else
1119 {
1120 // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
1121 if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
1122 {
1123 if (pAd->CommonCfg.bWmmCapable)
1124 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1125 else
1126 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
1127 }
1128 }
1129 }
1130
1131 if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
1132 {
1133 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1134 pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
1135 pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime;
1136
1137 // Lost AP, send disconnect & link down event
1138 LinkDown(pAd, FALSE);
1139
1140#ifdef WPA_SUPPLICANT_SUPPORT
1141#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1142 if (pAd->StaCfg.WpaSupplicantUP)
1143 {
1144 union iwreq_data wrqu;
1145 //send disassociate event to wpa_supplicant
1146 memset(&wrqu, 0, sizeof(wrqu));
1147 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
1148 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1149 }
1150#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1151#endif // WPA_SUPPLICANT_SUPPORT //
1152
1153#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1154 {
1155 union iwreq_data wrqu;
1156 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1157 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1158 }
1159#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1160
1161 // RTMPPatchMacBbpBug(pAd);
1162 MlmeAutoReconnectLastSSID(pAd);
1163 }
1164 else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
1165 {
1166 pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
1167 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1168 MlmeAutoReconnectLastSSID(pAd);
1169 }
1170
1171 // Add auto seamless roaming
1172 if (pAd->StaCfg.bFastRoaming)
1173 {
1174 SHORT dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam;
1175
1176 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));
1177
1178 if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam)
1179 {
1180 MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32);
1181 }
1182 }
1183 }
1184 else if (ADHOC_ON(pAd))
1185 {
1186 //radar detect
1187 if ((pAd->CommonCfg.Channel > 14)
1188 && (pAd->CommonCfg.bIEEE80211H == 1)
1189 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1190 {
1191 RadarDetectPeriodic(pAd);
1192 }
1193
1194 // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
1195 // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
1196 // join later.
1197 if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) &&
1198 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1199 {
1200 MLME_START_REQ_STRUCT StartReq;
1201
1202 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
1203 LinkDown(pAd, FALSE);
1204
1205 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
1206 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
1207 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
1208 }
1209
1210 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
1211 {
1212 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
1213
1214 if (pEntry->ValidAsCLI == FALSE)
1215 continue;
1216
1217 if (pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32)
1218 MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
1219 }
1220 }
1221 else // no INFRA nor ADHOC connection
1222 {
1223
1224 if (pAd->StaCfg.bScanReqIsFromWebUI &&
1225 ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32))
1226 goto SKIP_AUTO_SCAN_CONN;
1227 else
1228 pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
1229
1230 if ((pAd->StaCfg.bAutoReconnect == TRUE)
1231 && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
1232 && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1233 {
1234 if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
1235 {
1236 MLME_SCAN_REQ_STRUCT ScanReq;
1237
1238 if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
1239 {
1240 DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
1241 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
1242 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
1243 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
1244 // Reset Missed scan number
1245 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1246 }
1247 else if (pAd->StaCfg.BssType == BSS_ADHOC) // Quit the forever scan when in a very clean room
1248 MlmeAutoReconnectLastSSID(pAd);
1249 }
1250 else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1251 {
1252 if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
1253 {
1254 MlmeAutoScan(pAd);
1255 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1256 }
1257 else
1258 {
1259#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1260 if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
1261 {
1262 if ((pAd->Mlme.OneSecPeriodicRound % 5) == 1)
1263 MlmeAutoReconnectLastSSID(pAd);
1264 }
1265 else
1266#endif // CARRIER_DETECTION_SUPPORT //
1267 MlmeAutoReconnectLastSSID(pAd);
1268 }
1269 }
1270 }
1271 }
1272
1273SKIP_AUTO_SCAN_CONN:
1274
1275#ifdef DOT11_N_SUPPORT
1276 if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
1277 {
1278 pAd->MacTab.fAnyBASession = TRUE;
1279 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE, FALSE);
1280 }
1281 else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
1282 {
1283 pAd->MacTab.fAnyBASession = FALSE;
1284 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1285 }
1286#endif // DOT11_N_SUPPORT //
1287
1288
1289#ifdef DOT11_N_SUPPORT
1290#ifdef DOT11N_DRAFT3
1291 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040))
1292 TriEventCounterMaintenance(pAd);
1293#endif // DOT11N_DRAFT3 //
1294#endif // DOT11_N_SUPPORT //
1295
1296 return;
1297}
1298
1299// Link down report
1300VOID LinkDownExec(
1301 IN PVOID SystemSpecific1,
1302 IN PVOID FunctionContext,
1303 IN PVOID SystemSpecific2,
1304 IN PVOID SystemSpecific3)
1305{
1306
1307 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
1308
1309 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1310 RTMP_IndicateMediaState(pAd);
1311 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1312}
1313
1314// IRQL = DISPATCH_LEVEL
1315VOID MlmeAutoScan(
1316 IN PRTMP_ADAPTER pAd)
1317{
1318 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1319 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1320 {
1321 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
1322 MlmeEnqueue(pAd,
1323 MLME_CNTL_STATE_MACHINE,
1324 OID_802_11_BSSID_LIST_SCAN,
1325 0,
1326 NULL);
1327 RT28XX_MLME_HANDLER(pAd);
1328 }
1329}
1330
1331// IRQL = DISPATCH_LEVEL
1332VOID MlmeAutoReconnectLastSSID(
1333 IN PRTMP_ADAPTER pAd)
1334{
1335
1336
1337 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1338 if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
1339 (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1340 {
1341 NDIS_802_11_SSID OidSsid;
1342 OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
1343 NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
1344
1345 DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
1346 MlmeEnqueue(pAd,
1347 MLME_CNTL_STATE_MACHINE,
1348 OID_802_11_SSID,
1349 sizeof(NDIS_802_11_SSID),
1350 &OidSsid);
1351 RT28XX_MLME_HANDLER(pAd);
1352 }
1353}
1354#endif // CONFIG_STA_SUPPORT //
1355
1356/*
1357 ==========================================================================
1358 Validate SSID for connection try and rescan purpose
1359 Valid SSID will have visible chars only.
1360 The valid length is from 0 to 32.
1361 IRQL = DISPATCH_LEVEL
1362 ==========================================================================
1363 */
1364BOOLEAN MlmeValidateSSID(
1365 IN PUCHAR pSsid,
1366 IN UCHAR SsidLen)
1367{
1368 int index;
1369
1370 if (SsidLen > MAX_LEN_OF_SSID)
1371 return (FALSE);
1372
1373 // Check each character value
1374 for (index = 0; index < SsidLen; index++)
1375 {
1376 if (pSsid[index] < 0x20)
1377 return (FALSE);
1378 }
1379
1380 // All checked
1381 return (TRUE);
1382}
1383
1384VOID MlmeSelectTxRateTable(
1385 IN PRTMP_ADAPTER pAd,
1386 IN PMAC_TABLE_ENTRY pEntry,
1387 IN PUCHAR *ppTable,
1388 IN PUCHAR pTableSize,
1389 IN PUCHAR pInitTxRateIdx)
1390{
1391 do
1392 {
1393 // decide the rate table for tuning
1394 if (pAd->CommonCfg.TxRateTableSize > 0)
1395 {
1396 *ppTable = RateSwitchTable;
1397 *pTableSize = RateSwitchTable[0];
1398 *pInitTxRateIdx = RateSwitchTable[1];
1399
1400 break;
1401 }
1402
1403#ifdef CONFIG_STA_SUPPORT
1404 if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
1405 {
1406#ifdef DOT11_N_SUPPORT
1407 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
1408 (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1409 ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1410 {// 11N 1S Adhoc
1411 *ppTable = RateSwitchTable11N1S;
1412 *pTableSize = RateSwitchTable11N1S[0];
1413 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1414
1415 }
1416 else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
1417 (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1418 (pEntry->HTCapability.MCSSet[1] == 0xff) &&
1419 (pAd->Antenna.field.TxPath == 2))
1420 {// 11N 2S Adhoc
1421 if (pAd->LatchRfRegs.Channel <= 14)
1422 {
1423 *ppTable = RateSwitchTable11N2S;
1424 *pTableSize = RateSwitchTable11N2S[0];
1425 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1426 }
1427 else
1428 {
1429 *ppTable = RateSwitchTable11N2SForABand;
1430 *pTableSize = RateSwitchTable11N2SForABand[0];
1431 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1432 }
1433
1434 }
1435 else
1436#endif // DOT11_N_SUPPORT //
1437 if ((pEntry->RateLen == 4)
1438#ifdef DOT11_N_SUPPORT
1439 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1440#endif // DOT11_N_SUPPORT //
1441 )
1442 {
1443 *ppTable = RateSwitchTable11B;
1444 *pTableSize = RateSwitchTable11B[0];
1445 *pInitTxRateIdx = RateSwitchTable11B[1];
1446
1447 }
1448 else if (pAd->LatchRfRegs.Channel <= 14)
1449 {
1450 *ppTable = RateSwitchTable11BG;
1451 *pTableSize = RateSwitchTable11BG[0];
1452 *pInitTxRateIdx = RateSwitchTable11BG[1];
1453
1454 }
1455 else
1456 {
1457 *ppTable = RateSwitchTable11G;
1458 *pTableSize = RateSwitchTable11G[0];
1459 *pInitTxRateIdx = RateSwitchTable11G[1];
1460
1461 }
1462 break;
1463 }
1464#endif // CONFIG_STA_SUPPORT //
1465
1466#ifdef DOT11_N_SUPPORT
1467 //if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1468 // ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1469 if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1470 ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
1471 {// 11BGN 1S AP
1472 *ppTable = RateSwitchTable11BGN1S;
1473 *pTableSize = RateSwitchTable11BGN1S[0];
1474 *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
1475
1476 break;
1477 }
1478
1479 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1480 // (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
1481 if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1482 (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
1483 {// 11BGN 2S AP
1484 if (pAd->LatchRfRegs.Channel <= 14)
1485 {
1486 *ppTable = RateSwitchTable11BGN2S;
1487 *pTableSize = RateSwitchTable11BGN2S[0];
1488 *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
1489
1490 }
1491 else
1492 {
1493 *ppTable = RateSwitchTable11BGN2SForABand;
1494 *pTableSize = RateSwitchTable11BGN2SForABand[0];
1495 *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
1496
1497 }
1498 break;
1499 }
1500
1501 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1502 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
1503 {// 11N 1S AP
1504 *ppTable = RateSwitchTable11N1S;
1505 *pTableSize = RateSwitchTable11N1S[0];
1506 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1507
1508 break;
1509 }
1510
1511 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
1512 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
1513 {// 11N 2S AP
1514 if (pAd->LatchRfRegs.Channel <= 14)
1515 {
1516 *ppTable = RateSwitchTable11N2S;
1517 *pTableSize = RateSwitchTable11N2S[0];
1518 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1519 }
1520 else
1521 {
1522 *ppTable = RateSwitchTable11N2SForABand;
1523 *pTableSize = RateSwitchTable11N2SForABand[0];
1524 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1525 }
1526
1527 break;
1528 }
1529#endif // DOT11_N_SUPPORT //
1530 //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1531 if ((pEntry->RateLen == 4)
1532#ifdef DOT11_N_SUPPORT
1533 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1534#endif // DOT11_N_SUPPORT //
1535 )
1536 {// B only AP
1537 *ppTable = RateSwitchTable11B;
1538 *pTableSize = RateSwitchTable11B[0];
1539 *pInitTxRateIdx = RateSwitchTable11B[1];
1540
1541 break;
1542 }
1543
1544 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1545 if ((pEntry->RateLen > 8)
1546#ifdef DOT11_N_SUPPORT
1547 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1548#endif // DOT11_N_SUPPORT //
1549 )
1550 {// B/G mixed AP
1551 *ppTable = RateSwitchTable11BG;
1552 *pTableSize = RateSwitchTable11BG[0];
1553 *pInitTxRateIdx = RateSwitchTable11BG[1];
1554
1555 break;
1556 }
1557
1558 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1559 if ((pEntry->RateLen == 8)
1560#ifdef DOT11_N_SUPPORT
1561 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1562#endif // DOT11_N_SUPPORT //
1563 )
1564 {// G only AP
1565 *ppTable = RateSwitchTable11G;
1566 *pTableSize = RateSwitchTable11G[0];
1567 *pInitTxRateIdx = RateSwitchTable11G[1];
1568
1569 break;
1570 }
1571#ifdef DOT11_N_SUPPORT
1572#endif // DOT11_N_SUPPORT //
1573
1574#ifdef CONFIG_STA_SUPPORT
1575 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1576 {
1577#ifdef DOT11_N_SUPPORT
1578 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1579 if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
1580#endif // DOT11_N_SUPPORT //
1581 { // Legacy mode
1582 if (pAd->CommonCfg.MaxTxRate <= RATE_11)
1583 {
1584 *ppTable = RateSwitchTable11B;
1585 *pTableSize = RateSwitchTable11B[0];
1586 *pInitTxRateIdx = RateSwitchTable11B[1];
1587 }
1588 else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
1589 {
1590 *ppTable = RateSwitchTable11G;
1591 *pTableSize = RateSwitchTable11G[0];
1592 *pInitTxRateIdx = RateSwitchTable11G[1];
1593
1594 }
1595 else
1596 {
1597 *ppTable = RateSwitchTable11BG;
1598 *pTableSize = RateSwitchTable11BG[0];
1599 *pInitTxRateIdx = RateSwitchTable11BG[1];
1600 }
1601 break;
1602 }
1603#ifdef DOT11_N_SUPPORT
1604 if (pAd->LatchRfRegs.Channel <= 14)
1605 {
1606 if (pAd->CommonCfg.TxStream == 1)
1607 {
1608 *ppTable = RateSwitchTable11N1S;
1609 *pTableSize = RateSwitchTable11N1S[0];
1610 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1611 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
1612 }
1613 else
1614 {
1615 *ppTable = RateSwitchTable11N2S;
1616 *pTableSize = RateSwitchTable11N2S[0];
1617 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1618 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
1619 }
1620 }
1621 else
1622 {
1623 if (pAd->CommonCfg.TxStream == 1)
1624 {
1625 *ppTable = RateSwitchTable11N1S;
1626 *pTableSize = RateSwitchTable11N1S[0];
1627 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1628 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
1629 }
1630 else
1631 {
1632 *ppTable = RateSwitchTable11N2SForABand;
1633 *pTableSize = RateSwitchTable11N2SForABand[0];
1634 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1635 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
1636 }
1637 }
1638#endif // DOT11_N_SUPPORT //
1639 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
1640 pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
1641 }
1642#endif // CONFIG_STA_SUPPORT //
1643 } while(FALSE);
1644}
1645
1646#ifdef CONFIG_STA_SUPPORT
1647/*
1648 ==========================================================================
1649 Description:
1650 This routine checks if there're other APs out there capable for
1651 roaming. Caller should call this routine only when Link up in INFRA mode
1652 and channel quality is below CQI_GOOD_THRESHOLD.
1653
1654 IRQL = DISPATCH_LEVEL
1655
1656 Output:
1657 ==========================================================================
1658 */
1659VOID MlmeCheckForRoaming(
1660 IN PRTMP_ADAPTER pAd,
1661 IN ULONG Now32)
1662{
1663 USHORT i;
1664 BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
1665 BSS_ENTRY *pBss;
1666
1667 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
1668 // put all roaming candidates into RoamTab, and sort in RSSI order
1669 BssTableInit(pRoamTab);
1670 for (i = 0; i < pAd->ScanTab.BssNr; i++)
1671 {
1672 pBss = &pAd->ScanTab.BssEntry[i];
1673
1674 if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32)
1675 continue; // AP disappear
1676 if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
1677 continue; // RSSI too weak. forget it.
1678 if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
1679 continue; // skip current AP
1680 if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
1681 continue; // only AP with stronger RSSI is eligible for roaming
1682
1683 // AP passing all above rules is put into roaming candidate table
1684 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
1685 pRoamTab->BssNr += 1;
1686 }
1687
1688 if (pRoamTab->BssNr > 0)
1689 {
1690 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1691 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1692 {
1693 pAd->RalinkCounters.PoorCQIRoamingCount ++;
1694 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
1695 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
1696 RT28XX_MLME_HANDLER(pAd);
1697 }
1698 }
1699 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
1700}
1701
1702/*
1703 ==========================================================================
1704 Description:
1705 This routine checks if there're other APs out there capable for
1706 roaming. Caller should call this routine only when link up in INFRA mode
1707 and channel quality is below CQI_GOOD_THRESHOLD.
1708
1709 IRQL = DISPATCH_LEVEL
1710
1711 Output:
1712 ==========================================================================
1713 */
1714VOID MlmeCheckForFastRoaming(
1715 IN PRTMP_ADAPTER pAd,
1716 IN ULONG Now)
1717{
1718 USHORT i;
1719 BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
1720 BSS_ENTRY *pBss;
1721
1722 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
1723 // put all roaming candidates into RoamTab, and sort in RSSI order
1724 BssTableInit(pRoamTab);
1725 for (i = 0; i < pAd->ScanTab.BssNr; i++)
1726 {
1727 pBss = &pAd->ScanTab.BssEntry[i];
1728
1729 if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
1730 continue; // RSSI too weak. forget it.
1731 if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
1732 continue; // skip current AP
1733 if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
1734 continue; // skip different SSID
1735 if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
1736 continue; // skip AP without better RSSI
1737
1738 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));
1739 // AP passing all above rules is put into roaming candidate table
1740 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
1741 pRoamTab->BssNr += 1;
1742 }
1743
1744 if (pRoamTab->BssNr > 0)
1745 {
1746 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1747 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1748 {
1749 pAd->RalinkCounters.PoorCQIRoamingCount ++;
1750 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
1751 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
1752 RT28XX_MLME_HANDLER(pAd);
1753 }
1754 }
1755 // Maybe site survey required
1756 else
1757 {
1758 if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)
1759 {
1760 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1761 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
1762 pAd->StaCfg.ScanCnt = 2;
1763 pAd->StaCfg.LastScanTime = Now;
1764 MlmeAutoScan(pAd);
1765 }
1766 }
1767
1768 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
1769}
1770
1771/*
1772 ==========================================================================
1773 Description:
1774 This routine calculates TxPER, RxPER of the past N-sec period. And
1775 according to the calculation result, ChannelQuality is calculated here
1776 to decide if current AP is still doing the job.
1777
1778 If ChannelQuality is not good, a ROAMing attempt may be tried later.
1779 Output:
1780 StaCfg.ChannelQuality - 0..100
1781
1782 IRQL = DISPATCH_LEVEL
1783
1784 NOTE: This routine decide channle quality based on RX CRC error ratio.
1785 Caller should make sure a function call to NICUpdateRawCounters(pAd)
1786 is performed right before this routine, so that this routine can decide
1787 channel quality based on the most up-to-date information
1788 ==========================================================================
1789 */
1790VOID MlmeCalculateChannelQuality(
1791 IN PRTMP_ADAPTER pAd,
1792 IN ULONG Now32)
1793{
1794 ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
1795 ULONG RxCnt, RxPER;
1796 UCHAR NorRssi;
1797 CHAR MaxRssi;
1798 ULONG BeaconLostTime = BEACON_LOST_TIME;
1799
1800#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1801 // longer beacon lost time when carrier detection enabled
1802 if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
1803 {
1804 BeaconLostTime = BEACON_LOST_TIME + BEACON_LOST_TIME/2;
1805 }
1806#endif // CARRIER_DETECTION_SUPPORT //
1807
1808 MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
1809
1810 //
1811 // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
1812 //
1813 TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;
1814 TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;
1815 if (TxCnt < 5)
1816 {
1817 TxPER = 0;
1818 TxPRR = 0;
1819 }
1820 else
1821 {
1822 TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt;
1823 TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;
1824 }
1825
1826 //
1827 // calculate RX PER - don't take RxPER into consideration if too few sample
1828 //
1829 RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;
1830 if (RxCnt < 5)
1831 RxPER = 0;
1832 else
1833 RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;
1834
1835 //
1836 // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
1837 //
1838 if (INFRA_ON(pAd) &&
1839 (pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic
1840 (pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32))
1841 {
1842 DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
1843 pAd->Mlme.ChannelQuality = 0;
1844 }
1845 else
1846 {
1847 // Normalize Rssi
1848 if (MaxRssi > -40)
1849 NorRssi = 100;
1850 else if (MaxRssi < -90)
1851 NorRssi = 0;
1852 else
1853 NorRssi = (MaxRssi + 90) * 2;
1854
1855 // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
1856 pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi +
1857 TX_WEIGHTING * (100 - TxPRR) +
1858 RX_WEIGHTING* (100 - RxPER)) / 100;
1859 if (pAd->Mlme.ChannelQuality >= 100)
1860 pAd->Mlme.ChannelQuality = 100;
1861 }
1862
1863}
1864
1865VOID MlmeSetTxRate(
1866 IN PRTMP_ADAPTER pAd,
1867 IN PMAC_TABLE_ENTRY pEntry,
1868 IN PRTMP_TX_RATE_SWITCH pTxRate)
1869{
1870 UCHAR MaxMode = MODE_OFDM;
1871
1872#ifdef DOT11_N_SUPPORT
1873 MaxMode = MODE_HTGREENFIELD;
1874
1875 if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
1876 pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
1877 else
1878#endif // DOT11_N_SUPPORT //
1879 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
1880
1881 if (pTxRate->CurrMCS < MCS_AUTO)
1882 pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
1883
1884 if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
1885 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
1886
1887 if (ADHOC_ON(pAd))
1888 {
1889 // If peer adhoc is b-only mode, we can't send 11g rate.
1890 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1891 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1892
1893 //
1894 // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
1895 //
1896 pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
1897 pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
1898 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1899
1900 // Patch speed error in status page
1901 pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
1902 }
1903 else
1904 {
1905 if (pTxRate->Mode <= MaxMode)
1906 pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
1907
1908#ifdef DOT11_N_SUPPORT
1909 if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
1910 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
1911 else
1912#endif // DOT11_N_SUPPORT //
1913 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1914
1915#ifdef DOT11_N_SUPPORT
1916 // Reexam each bandwidth's SGI support.
1917 if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
1918 {
1919 if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
1920 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1921 if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
1922 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1923 }
1924
1925 // Turn RTS/CTS rate to 6Mbps.
1926 if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
1927 {
1928 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1929 if (pAd->MacTab.fAnyBASession)
1930 {
1931 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1932 }
1933 else
1934 {
1935 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1936 }
1937 }
1938 else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
1939 {
1940 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1941 if (pAd->MacTab.fAnyBASession)
1942 {
1943 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1944 }
1945 else
1946 {
1947 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1948 }
1949 }
1950 else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
1951 {
1952 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1953
1954 }
1955 else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
1956 {
1957 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1958 }
1959#endif // DOT11_N_SUPPORT //
1960
1961 pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
1962 pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
1963 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1964 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
1965#ifdef DOT11_N_SUPPORT
1966 if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
1967 pAd->WIFItestbed.bGreenField)
1968 pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
1969#endif // DOT11_N_SUPPORT //
1970 }
1971
1972 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1973}
1974
1975/*
1976 ==========================================================================
1977 Description:
1978 This routine calculates the acumulated TxPER of eaxh TxRate. And
1979 according to the calculation result, change CommonCfg.TxRate which
1980 is the stable TX Rate we expect the Radio situation could sustained.
1981
1982 CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
1983 Output:
1984 CommonCfg.TxRate -
1985
1986 IRQL = DISPATCH_LEVEL
1987
1988 NOTE:
1989 call this routine every second
1990 ==========================================================================
1991 */
1992VOID MlmeDynamicTxRateSwitching(
1993 IN PRTMP_ADAPTER pAd)
1994{
1995 UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
1996 ULONG i, AccuTxTotalCnt = 0, TxTotalCnt;
1997 ULONG TxErrorRatio = 0;
1998 BOOLEAN bTxRateChanged, bUpgradeQuality = FALSE;
1999 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
2000 PUCHAR pTable;
2001 UCHAR TableSize = 0;
2002 UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
2003 CHAR Rssi, RssiOffset = 0;
2004 TX_STA_CNT1_STRUC StaTx1;
2005 TX_STA_CNT0_STRUC TxStaCnt0;
2006 ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
2007 MAC_TABLE_ENTRY *pEntry;
2008
2009#ifdef RALINK_ATE
2010 if (ATE_ON(pAd))
2011 {
2012 return;
2013 }
2014#endif // RALINK_ATE //
2015
2016 //
2017 // walk through MAC table, see if need to change AP's TX rate toward each entry
2018 //
2019 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
2020 {
2021 pEntry = &pAd->MacTab.Content[i];
2022
2023 // check if this entry need to switch rate automatically
2024 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2025 continue;
2026
2027 if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
2028 {
2029 Rssi = RTMPMaxRssi(pAd,
2030 pAd->StaCfg.RssiSample.AvgRssi0,
2031 pAd->StaCfg.RssiSample.AvgRssi1,
2032 pAd->StaCfg.RssiSample.AvgRssi2);
2033
2034 // Update statistic counter
2035 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2036 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2037 pAd->bUpdateBcnCntDone = TRUE;
2038 TxRetransmit = StaTx1.field.TxRetransmit;
2039 TxSuccess = StaTx1.field.TxSuccess;
2040 TxFailCount = TxStaCnt0.field.TxFailCount;
2041 TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
2042
2043 pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2044 pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2045 pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2046 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2047 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2048 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2049
2050 // if no traffic in the past 1-sec period, don't change TX rate,
2051 // but clear all bad history. because the bad history may affect the next
2052 // Chariot throughput test
2053 AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
2054 pAd->RalinkCounters.OneSecTxRetryOkCount +
2055 pAd->RalinkCounters.OneSecTxFailCount;
2056
2057 if (TxTotalCnt)
2058 TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
2059 }
2060 else
2061 {
2062 if (INFRA_ON(pAd) && (i == 1))
2063 Rssi = RTMPMaxRssi(pAd,
2064 pAd->StaCfg.RssiSample.AvgRssi0,
2065 pAd->StaCfg.RssiSample.AvgRssi1,
2066 pAd->StaCfg.RssiSample.AvgRssi2);
2067 else
2068 Rssi = RTMPMaxRssi(pAd,
2069 pEntry->RssiSample.AvgRssi0,
2070 pEntry->RssiSample.AvgRssi1,
2071 pEntry->RssiSample.AvgRssi2);
2072
2073 TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
2074 pEntry->OneSecTxRetryOkCount +
2075 pEntry->OneSecTxFailCount;
2076
2077 if (TxTotalCnt)
2078 TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
2079 }
2080
2081 CurrRateIdx = pEntry->CurrTxRateIndex;
2082
2083 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
2084
2085 if (CurrRateIdx >= TableSize)
2086 {
2087 CurrRateIdx = TableSize - 1;
2088 }
2089
2090 // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
2091 // So need to sync here.
2092 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2093 if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
2094 //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
2095 )
2096 {
2097
2098 // Need to sync Real Tx rate and our record.
2099 // Then return for next DRS.
2100 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
2101 pEntry->CurrTxRateIndex = InitTxRateIdx;
2102 MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
2103
2104 // reset all OneSecTx counters
2105 RESET_ONE_SEC_TX_CNT(pEntry);
2106 continue;
2107 }
2108
2109 // decide the next upgrade rate and downgrade rate, if any
2110 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
2111 {
2112 UpRateIdx = CurrRateIdx + 1;
2113 DownRateIdx = CurrRateIdx -1;
2114 }
2115 else if (CurrRateIdx == 0)
2116 {
2117 UpRateIdx = CurrRateIdx + 1;
2118 DownRateIdx = CurrRateIdx;
2119 }
2120 else if (CurrRateIdx == (TableSize - 1))
2121 {
2122 UpRateIdx = CurrRateIdx;
2123 DownRateIdx = CurrRateIdx - 1;
2124 }
2125
2126 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2127
2128#ifdef DOT11_N_SUPPORT
2129 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
2130 {
2131 TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
2132 TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
2133 }
2134 else
2135#endif // DOT11_N_SUPPORT //
2136 {
2137 TrainUp = pCurrTxRate->TrainUp;
2138 TrainDown = pCurrTxRate->TrainDown;
2139 }
2140
2141 //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
2142
2143 //
2144 // Keep the last time TxRateChangeAction status.
2145 //
2146 pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
2147
2148
2149
2150 //
2151 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2152 // (criteria copied from RT2500 for Netopia case)
2153 //
2154 if (TxTotalCnt <= 15)
2155 {
2156 CHAR idx = 0;
2157 UCHAR TxRateIdx;
2158 //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2159 UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0;
2160 UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2161 UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
2162
2163 // check the existence and index of each needed MCS
2164 while (idx < pTable[0])
2165 {
2166 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
2167
2168 if (pCurrTxRate->CurrMCS == MCS_0)
2169 {
2170 MCS0 = idx;
2171 }
2172 else if (pCurrTxRate->CurrMCS == MCS_1)
2173 {
2174 MCS1 = idx;
2175 }
2176 else if (pCurrTxRate->CurrMCS == MCS_2)
2177 {
2178 MCS2 = idx;
2179 }
2180 else if (pCurrTxRate->CurrMCS == MCS_3)
2181 {
2182 MCS3 = idx;
2183 }
2184 else if (pCurrTxRate->CurrMCS == MCS_4)
2185 {
2186 MCS4 = idx;
2187 }
2188 else if (pCurrTxRate->CurrMCS == MCS_5)
2189 {
2190 MCS5 = idx;
2191 }
2192 else if (pCurrTxRate->CurrMCS == MCS_6)
2193 {
2194 MCS6 = idx;
2195 }
2196 //else if (pCurrTxRate->CurrMCS == MCS_7)
2197 else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) // prevent the highest MCS using short GI when 1T and low throughput
2198 {
2199 MCS7 = idx;
2200 }
2201 else if (pCurrTxRate->CurrMCS == MCS_12)
2202 {
2203 MCS12 = idx;
2204 }
2205 else if (pCurrTxRate->CurrMCS == MCS_13)
2206 {
2207 MCS13 = idx;
2208 }
2209 else if (pCurrTxRate->CurrMCS == MCS_14)
2210 {
2211 MCS14 = idx;
2212 }
2213 //else if ((pCurrTxRate->CurrMCS == MCS_15)/* && (pCurrTxRate->ShortGI == GI_800)*/) //we hope to use ShortGI as initial rate
2214 else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800)) //we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI
2215 {
2216 MCS15 = idx;
2217 }
2218 else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
2219 {
2220 MCS20 = idx;
2221 }
2222 else if (pCurrTxRate->CurrMCS == MCS_21)
2223 {
2224 MCS21 = idx;
2225 }
2226 else if (pCurrTxRate->CurrMCS == MCS_22)
2227 {
2228 MCS22 = idx;
2229 }
2230 else if (pCurrTxRate->CurrMCS == MCS_23)
2231 {
2232 MCS23 = idx;
2233 }
2234 idx ++;
2235 }
2236
2237 if (pAd->LatchRfRegs.Channel <= 14)
2238 {
2239 if (pAd->NicConfig2.field.ExternalLNAForG)
2240 {
2241 RssiOffset = 2;
2242 }
2243 else
2244 {
2245 RssiOffset = 5;
2246 }
2247 }
2248 else
2249 {
2250 if (pAd->NicConfig2.field.ExternalLNAForA)
2251 {
2252 RssiOffset = 5;
2253 }
2254 else
2255 {
2256 RssiOffset = 8;
2257 }
2258 }
2259#ifdef DOT11_N_SUPPORT
2260 /*if (MCS15)*/
2261 if ((pTable == RateSwitchTable11BGN3S) ||
2262 (pTable == RateSwitchTable11N3S) ||
2263 (pTable == RateSwitchTable))
2264 {// N mode with 3 stream // 3*3
2265 if (MCS23 && (Rssi >= -70))
2266 TxRateIdx = MCS15;
2267 else if (MCS22 && (Rssi >= -72))
2268 TxRateIdx = MCS14;
2269 else if (MCS21 && (Rssi >= -76))
2270 TxRateIdx = MCS13;
2271 else if (MCS20 && (Rssi >= -78))
2272 TxRateIdx = MCS12;
2273 else if (MCS4 && (Rssi >= -82))
2274 TxRateIdx = MCS4;
2275 else if (MCS3 && (Rssi >= -84))
2276 TxRateIdx = MCS3;
2277 else if (MCS2 && (Rssi >= -86))
2278 TxRateIdx = MCS2;
2279 else if (MCS1 && (Rssi >= -88))
2280 TxRateIdx = MCS1;
2281 else
2282 TxRateIdx = MCS0;
2283 }
2284// else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable))
2285 else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
2286 {// N mode with 2 stream
2287 if (MCS15 && (Rssi >= (-70+RssiOffset)))
2288 TxRateIdx = MCS15;
2289 else if (MCS14 && (Rssi >= (-72+RssiOffset)))
2290 TxRateIdx = MCS14;
2291 else if (MCS13 && (Rssi >= (-76+RssiOffset)))
2292 TxRateIdx = MCS13;
2293 else if (MCS12 && (Rssi >= (-78+RssiOffset)))
2294 TxRateIdx = MCS12;
2295 else if (MCS4 && (Rssi >= (-82+RssiOffset)))
2296 TxRateIdx = MCS4;
2297 else if (MCS3 && (Rssi >= (-84+RssiOffset)))
2298 TxRateIdx = MCS3;
2299 else if (MCS2 && (Rssi >= (-86+RssiOffset)))
2300 TxRateIdx = MCS2;
2301 else if (MCS1 && (Rssi >= (-88+RssiOffset)))
2302 TxRateIdx = MCS1;
2303 else
2304 TxRateIdx = MCS0;
2305 }
2306 else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
2307 {// N mode with 1 stream
2308 if (MCS7 && (Rssi > (-72+RssiOffset)))
2309 TxRateIdx = MCS7;
2310 else if (MCS6 && (Rssi > (-74+RssiOffset)))
2311 TxRateIdx = MCS6;
2312 else if (MCS5 && (Rssi > (-77+RssiOffset)))
2313 TxRateIdx = MCS5;
2314 else if (MCS4 && (Rssi > (-79+RssiOffset)))
2315 TxRateIdx = MCS4;
2316 else if (MCS3 && (Rssi > (-81+RssiOffset)))
2317 TxRateIdx = MCS3;
2318 else if (MCS2 && (Rssi > (-83+RssiOffset)))
2319 TxRateIdx = MCS2;
2320 else if (MCS1 && (Rssi > (-86+RssiOffset)))
2321 TxRateIdx = MCS1;
2322 else
2323 TxRateIdx = MCS0;
2324 }
2325 else
2326#endif // DOT11_N_SUPPORT //
2327 {// Legacy mode
2328 if (MCS7 && (Rssi > -70))
2329 TxRateIdx = MCS7;
2330 else if (MCS6 && (Rssi > -74))
2331 TxRateIdx = MCS6;
2332 else if (MCS5 && (Rssi > -78))
2333 TxRateIdx = MCS5;
2334 else if (MCS4 && (Rssi > -82))
2335 TxRateIdx = MCS4;
2336 else if (MCS4 == 0) // for B-only mode
2337 TxRateIdx = MCS3;
2338 else if (MCS3 && (Rssi > -85))
2339 TxRateIdx = MCS3;
2340 else if (MCS2 && (Rssi > -87))
2341 TxRateIdx = MCS2;
2342 else if (MCS1 && (Rssi > -90))
2343 TxRateIdx = MCS1;
2344 else
2345 TxRateIdx = MCS0;
2346 }
2347
2348 // if (TxRateIdx != pAd->CommonCfg.TxRateIndex)
2349 {
2350 pEntry->CurrTxRateIndex = TxRateIdx;
2351 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
2352 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2353 }
2354
2355 NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2356 NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2357 pEntry->fLastSecAccordingRSSI = TRUE;
2358 // reset all OneSecTx counters
2359 RESET_ONE_SEC_TX_CNT(pEntry);
2360
2361 continue;
2362 }
2363
2364 if (pEntry->fLastSecAccordingRSSI == TRUE)
2365 {
2366 pEntry->fLastSecAccordingRSSI = FALSE;
2367 pEntry->LastSecTxRateChangeAction = 0;
2368 // reset all OneSecTx counters
2369 RESET_ONE_SEC_TX_CNT(pEntry);
2370
2371 continue;
2372 }
2373
2374 do
2375 {
2376 BOOLEAN bTrainUpDown = FALSE;
2377
2378 pEntry->CurrTxRateStableTime ++;
2379
2380 // downgrade TX quality if PER >= Rate-Down threshold
2381 if (TxErrorRatio >= TrainDown)
2382 {
2383 bTrainUpDown = TRUE;
2384 pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2385 }
2386 // upgrade TX quality if PER <= Rate-Up threshold
2387 else if (TxErrorRatio <= TrainUp)
2388 {
2389 bTrainUpDown = TRUE;
2390 bUpgradeQuality = TRUE;
2391 if (pEntry->TxQuality[CurrRateIdx])
2392 pEntry->TxQuality[CurrRateIdx] --; // quality very good in CurrRate
2393
2394 if (pEntry->TxRateUpPenalty)
2395 pEntry->TxRateUpPenalty --;
2396 else if (pEntry->TxQuality[UpRateIdx])
2397 pEntry->TxQuality[UpRateIdx] --; // may improve next UP rate's quality
2398 }
2399
2400 pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
2401
2402 if (bTrainUpDown)
2403 {
2404 // perform DRS - consider TxRate Down first, then rate up.
2405 if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
2406 {
2407 pEntry->CurrTxRateIndex = DownRateIdx;
2408 }
2409 else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
2410 {
2411 pEntry->CurrTxRateIndex = UpRateIdx;
2412 }
2413 }
2414 } while (FALSE);
2415
2416 // if rate-up happen, clear all bad history of all TX rates
2417 if (pEntry->CurrTxRateIndex > CurrRateIdx)
2418 {
2419 pEntry->CurrTxRateStableTime = 0;
2420 pEntry->TxRateUpPenalty = 0;
2421 pEntry->LastSecTxRateChangeAction = 1; // rate UP
2422 NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2423 NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2424
2425 //
2426 // For TxRate fast train up
2427 //
2428 if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
2429 {
2430 RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
2431
2432 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
2433 }
2434 bTxRateChanged = TRUE;
2435 }
2436 // if rate-down happen, only clear DownRate's bad history
2437 else if (pEntry->CurrTxRateIndex < CurrRateIdx)
2438 {
2439 pEntry->CurrTxRateStableTime = 0;
2440 pEntry->TxRateUpPenalty = 0; // no penalty
2441 pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
2442 pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
2443 pEntry->PER[pEntry->CurrTxRateIndex] = 0;
2444
2445 //
2446 // For TxRate fast train down
2447 //
2448 if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
2449 {
2450 RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
2451
2452 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
2453 }
2454 bTxRateChanged = TRUE;
2455 }
2456 else
2457 {
2458 pEntry->LastSecTxRateChangeAction = 0; // rate no change
2459 bTxRateChanged = FALSE;
2460 }
2461
2462 pEntry->LastTxOkCount = TxSuccess;
2463
2464 // reset all OneSecTx counters
2465 RESET_ONE_SEC_TX_CNT(pEntry);
2466
2467 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
2468 if (bTxRateChanged && pNextTxRate)
2469 {
2470 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2471 }
2472 }
2473}
2474
2475/*
2476 ========================================================================
2477 Routine Description:
2478 Station side, Auto TxRate faster train up timer call back function.
2479
2480 Arguments:
2481 SystemSpecific1 - Not used.
2482 FunctionContext - Pointer to our Adapter context.
2483 SystemSpecific2 - Not used.
2484 SystemSpecific3 - Not used.
2485
2486 Return Value:
2487 None
2488
2489 ========================================================================
2490*/
2491VOID StaQuickResponeForRateUpExec(
2492 IN PVOID SystemSpecific1,
2493 IN PVOID FunctionContext,
2494 IN PVOID SystemSpecific2,
2495 IN PVOID SystemSpecific3)
2496{
2497 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
2498 UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
2499 ULONG TxTotalCnt;
2500 ULONG TxErrorRatio = 0;
2501 BOOLEAN bTxRateChanged; //, bUpgradeQuality = FALSE;
2502 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
2503 PUCHAR pTable;
2504 UCHAR TableSize = 0;
2505 UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
2506 TX_STA_CNT1_STRUC StaTx1;
2507 TX_STA_CNT0_STRUC TxStaCnt0;
2508 CHAR Rssi, ratio;
2509 ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
2510 MAC_TABLE_ENTRY *pEntry;
2511 ULONG i;
2512
2513 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
2514
2515 //
2516 // walk through MAC table, see if need to change AP's TX rate toward each entry
2517 //
2518 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
2519 {
2520 pEntry = &pAd->MacTab.Content[i];
2521
2522 // check if this entry need to switch rate automatically
2523 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2524 continue;
2525
2526 if (INFRA_ON(pAd) && (i == 1))
2527 Rssi = RTMPMaxRssi(pAd,
2528 pAd->StaCfg.RssiSample.AvgRssi0,
2529 pAd->StaCfg.RssiSample.AvgRssi1,
2530 pAd->StaCfg.RssiSample.AvgRssi2);
2531 else
2532 Rssi = RTMPMaxRssi(pAd,
2533 pEntry->RssiSample.AvgRssi0,
2534 pEntry->RssiSample.AvgRssi1,
2535 pEntry->RssiSample.AvgRssi2);
2536
2537 CurrRateIdx = pAd->CommonCfg.TxRateIndex;
2538
2539 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
2540
2541 // decide the next upgrade rate and downgrade rate, if any
2542 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
2543 {
2544 UpRateIdx = CurrRateIdx + 1;
2545 DownRateIdx = CurrRateIdx -1;
2546 }
2547 else if (CurrRateIdx == 0)
2548 {
2549 UpRateIdx = CurrRateIdx + 1;
2550 DownRateIdx = CurrRateIdx;
2551 }
2552 else if (CurrRateIdx == (TableSize - 1))
2553 {
2554 UpRateIdx = CurrRateIdx;
2555 DownRateIdx = CurrRateIdx - 1;
2556 }
2557
2558 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2559
2560#ifdef DOT11_N_SUPPORT
2561 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
2562 {
2563 TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
2564 TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
2565 }
2566 else
2567#endif // DOT11_N_SUPPORT //
2568 {
2569 TrainUp = pCurrTxRate->TrainUp;
2570 TrainDown = pCurrTxRate->TrainDown;
2571 }
2572
2573 if (pAd->MacTab.Size == 1)
2574 {
2575 // Update statistic counter
2576 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2577 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2578
2579 TxRetransmit = StaTx1.field.TxRetransmit;
2580 TxSuccess = StaTx1.field.TxSuccess;
2581 TxFailCount = TxStaCnt0.field.TxFailCount;
2582 TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
2583
2584 pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2585 pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2586 pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2587 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2588 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2589 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2590
2591#if 0 // test by Gary.
2592 // if no traffic in the past 1-sec period, don't change TX rate,
2593 // but clear all bad history. because the bad history may affect the next
2594 // Chariot throughput test
2595 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
2596 pAd->RalinkCounters.OneSecTxRetryOkCount +
2597 pAd->RalinkCounters.OneSecTxFailCount;
2598#endif
2599 if (TxTotalCnt)
2600 TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
2601 }
2602 else
2603 {
2604 TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
2605 pEntry->OneSecTxRetryOkCount +
2606 pEntry->OneSecTxFailCount;
2607
2608 if (TxTotalCnt)
2609 TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
2610 }
2611
2612
2613 //
2614 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2615 // (criteria copied from RT2500 for Netopia case)
2616 //
2617 if (TxTotalCnt <= 12)
2618 {
2619 NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2620 NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2621
2622 if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
2623 {
2624 pAd->CommonCfg.TxRateIndex = DownRateIdx;
2625 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2626 }
2627 else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
2628 {
2629 pAd->CommonCfg.TxRateIndex = UpRateIdx;
2630 }
2631
2632 DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
2633 return;
2634 }
2635
2636 do
2637 {
2638 ULONG OneSecTxNoRetryOKRationCount;
2639
2640 if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
2641 ratio = 5;
2642 else
2643 ratio = 4;
2644
2645 // downgrade TX quality if PER >= Rate-Down threshold
2646 if (TxErrorRatio >= TrainDown)
2647 {
2648 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2649 }
2650
2651 pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
2652
2653 OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
2654
2655 // perform DRS - consider TxRate Down first, then rate up.
2656 if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
2657 {
2658 if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
2659 {
2660 pAd->CommonCfg.TxRateIndex = DownRateIdx;
2661 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2662
2663 }
2664
2665 }
2666 else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
2667 {
2668 if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
2669 {
2670
2671 }
2672 else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
2673 {
2674 pAd->CommonCfg.TxRateIndex = UpRateIdx;
2675 }
2676 }
2677 }while (FALSE);
2678
2679 // if rate-up happen, clear all bad history of all TX rates
2680 if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
2681 {
2682 pAd->DrsCounters.TxRateUpPenalty = 0;
2683 NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2684 NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2685 bTxRateChanged = TRUE;
2686 }
2687 // if rate-down happen, only clear DownRate's bad history
2688 else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
2689 {
2690 DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
2691
2692 pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty
2693 pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
2694 pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
2695 bTxRateChanged = TRUE;
2696 }
2697 else
2698 {
2699 bTxRateChanged = FALSE;
2700 }
2701
2702 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
2703 if (bTxRateChanged && pNextTxRate)
2704 {
2705 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2706 }
2707 }
2708}
2709
2710/*
2711 ==========================================================================
2712 Description:
2713 This routine is executed periodically inside MlmePeriodicExec() after
2714 association with an AP.
2715 It checks if StaCfg.Psm is consistent with user policy (recorded in
2716 StaCfg.WindowsPowerMode). If not, enforce user policy. However,
2717 there're some conditions to consider:
2718 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
2719 the time when Mibss==TRUE
2720 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
2721 if outgoing traffic available in TxRing or MgmtRing.
2722 Output:
2723 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
2724
2725 IRQL = DISPATCH_LEVEL
2726
2727 ==========================================================================
2728 */
2729VOID MlmeCheckPsmChange(
2730 IN PRTMP_ADAPTER pAd,
2731 IN ULONG Now32)
2732{
2733 ULONG PowerMode;
2734
2735 // condition -
2736 // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
2737 // 2. user wants either MAX_PSP or FAST_PSP
2738 // 3. but current psm is not in PWR_SAVE
2739 // 4. CNTL state machine is not doing SCANning
2740 // 5. no TX SUCCESS event for the past 1-sec period
2741#ifdef NDIS51_MINIPORT
2742 if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery)
2743 PowerMode = pAd->StaCfg.WindowsBatteryPowerMode;
2744 else
2745#endif
2746 PowerMode = pAd->StaCfg.WindowsPowerMode;
2747
2748 if (INFRA_ON(pAd) &&
2749 (PowerMode != Ndis802_11PowerModeCAM) &&
2750 (pAd->StaCfg.Psm == PWR_ACTIVE) &&
2751// (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2752 (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) /*&&
2753 (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
2754 (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/)
2755 {
2756 NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
2757 pAd->RalinkCounters.RxCountSinceLastNULL = 0;
2758 MlmeSetPsmBit(pAd, PWR_SAVE);
2759 if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
2760 {
2761 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
2762 }
2763 else
2764 {
2765 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
2766 }
2767 }
2768}
2769
2770// IRQL = PASSIVE_LEVEL
2771// IRQL = DISPATCH_LEVEL
2772VOID MlmeSetPsmBit(
2773 IN PRTMP_ADAPTER pAd,
2774 IN USHORT psm)
2775{
2776 AUTO_RSP_CFG_STRUC csr4;
2777
2778 pAd->StaCfg.Psm = psm;
2779 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
2780 csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
2781 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
2782 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
2783}
2784#endif // CONFIG_STA_SUPPORT //
2785
2786
2787// IRQL = DISPATCH_LEVEL
2788VOID MlmeSetTxPreamble(
2789 IN PRTMP_ADAPTER pAd,
2790 IN USHORT TxPreamble)
2791{
2792 AUTO_RSP_CFG_STRUC csr4;
2793
2794 //
2795 // Always use Long preamble before verifiation short preamble functionality works well.
2796 // Todo: remove the following line if short preamble functionality works
2797 //
2798 //TxPreamble = Rt802_11PreambleLong;
2799
2800 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
2801 if (TxPreamble == Rt802_11PreambleLong)
2802 {
2803 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
2804 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2805 csr4.field.AutoResponderPreamble = 0;
2806 }
2807 else
2808 {
2809 // NOTE: 1Mbps should always use long preamble
2810 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
2811 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2812 csr4.field.AutoResponderPreamble = 1;
2813 }
2814
2815 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
2816}
2817
2818/*
2819 ==========================================================================
2820 Description:
2821 Update basic rate bitmap
2822 ==========================================================================
2823 */
2824
2825VOID UpdateBasicRateBitmap(
2826 IN PRTMP_ADAPTER pAdapter)
2827{
2828 INT i, j;
2829 /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
2830 UCHAR rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
2831 UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
2832 UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
2833 ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
2834
2835
2836 /* if A mode, always use fix BasicRateBitMap */
2837 //if (pAdapter->CommonCfg.Channel == PHY_11A)
2838 if (pAdapter->CommonCfg.Channel > 14)
2839 pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
2840 /* End of if */
2841
2842 if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
2843 {
2844 /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
2845 return;
2846 } /* End of if */
2847
2848 for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2849 {
2850 sup_p[i] &= 0x7f;
2851 ext_p[i] &= 0x7f;
2852 } /* End of for */
2853
2854 for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2855 {
2856 if (bitmap & (1 << i))
2857 {
2858 for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
2859 {
2860 if (sup_p[j] == rate[i])
2861 sup_p[j] |= 0x80;
2862 /* End of if */
2863 } /* End of for */
2864
2865 for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
2866 {
2867 if (ext_p[j] == rate[i])
2868 ext_p[j] |= 0x80;
2869 /* End of if */
2870 } /* End of for */
2871 } /* End of if */
2872 } /* End of for */
2873} /* End of UpdateBasicRateBitmap */
2874
2875// IRQL = PASSIVE_LEVEL
2876// IRQL = DISPATCH_LEVEL
2877// bLinkUp is to identify the inital link speed.
2878// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
2879VOID MlmeUpdateTxRates(
2880 IN PRTMP_ADAPTER pAd,
2881 IN BOOLEAN bLinkUp,
2882 IN UCHAR apidx)
2883{
2884 int i, num;
2885 UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
2886 UCHAR MinSupport = RATE_54;
2887 ULONG BasicRateBitmap = 0;
2888 UCHAR CurrBasicRate = RATE_1;
2889 UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
2890 PHTTRANSMIT_SETTING pHtPhy = NULL;
2891 PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
2892 PHTTRANSMIT_SETTING pMinHtPhy = NULL;
2893 BOOLEAN *auto_rate_cur_p;
2894 UCHAR HtMcs = MCS_AUTO;
2895
2896 // find max desired rate
2897 UpdateBasicRateBitmap(pAd);
2898
2899 num = 0;
2900 auto_rate_cur_p = NULL;
2901 for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2902 {
2903 switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
2904 {
2905 case 2: Rate = RATE_1; num++; break;
2906 case 4: Rate = RATE_2; num++; break;
2907 case 11: Rate = RATE_5_5; num++; break;
2908 case 22: Rate = RATE_11; num++; break;
2909 case 12: Rate = RATE_6; num++; break;
2910 case 18: Rate = RATE_9; num++; break;
2911 case 24: Rate = RATE_12; num++; break;
2912 case 36: Rate = RATE_18; num++; break;
2913 case 48: Rate = RATE_24; num++; break;
2914 case 72: Rate = RATE_36; num++; break;
2915 case 96: Rate = RATE_48; num++; break;
2916 case 108: Rate = RATE_54; num++; break;
2917 //default: Rate = RATE_1; break;
2918 }
2919 if (MaxDesire < Rate) MaxDesire = Rate;
2920 }
2921
2922//===========================================================================
2923//===========================================================================
2924
2925#ifdef CONFIG_STA_SUPPORT
2926 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2927 {
2928 pHtPhy = &pAd->StaCfg.HTPhyMode;
2929 pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
2930 pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
2931
2932 auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
2933 HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
2934
2935 if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
2936 (pAd->CommonCfg.PhyMode == PHY_11B) &&
2937 (MaxDesire > RATE_11))
2938 {
2939 MaxDesire = RATE_11;
2940 }
2941 }
2942#endif // CONFIG_STA_SUPPORT //
2943
2944 pAd->CommonCfg.MaxDesiredRate = MaxDesire;
2945 pMinHtPhy->word = 0;
2946 pMaxHtPhy->word = 0;
2947 pHtPhy->word = 0;
2948
2949 // Auto rate switching is enabled only if more than one DESIRED RATES are
2950 // specified; otherwise disabled
2951 if (num <= 1)
2952 {
2953 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2954 //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
2955 *auto_rate_cur_p = FALSE;
2956 }
2957 else
2958 {
2959 //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2960 //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
2961 *auto_rate_cur_p = TRUE;
2962 }
2963
2964#if 1
2965 if (HtMcs != MCS_AUTO)
2966 {
2967 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2968 //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
2969 *auto_rate_cur_p = FALSE;
2970 }
2971 else
2972 {
2973 //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
2974 //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
2975 *auto_rate_cur_p = TRUE;
2976 }
2977#endif
2978
2979#ifdef CONFIG_STA_SUPPORT
2980 if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
2981 {
2982 pSupRate = &pAd->StaActive.SupRate[0];
2983 pExtRate = &pAd->StaActive.ExtRate[0];
2984 SupRateLen = pAd->StaActive.SupRateLen;
2985 ExtRateLen = pAd->StaActive.ExtRateLen;
2986 }
2987 else
2988#endif // CONFIG_STA_SUPPORT //
2989 {
2990 pSupRate = &pAd->CommonCfg.SupRate[0];
2991 pExtRate = &pAd->CommonCfg.ExtRate[0];
2992 SupRateLen = pAd->CommonCfg.SupRateLen;
2993 ExtRateLen = pAd->CommonCfg.ExtRateLen;
2994 }
2995
2996 // find max supported rate
2997 for (i=0; i<SupRateLen; i++)
2998 {
2999 switch (pSupRate[i] & 0x7f)
3000 {
3001 case 2: Rate = RATE_1; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
3002 case 4: Rate = RATE_2; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
3003 case 11: Rate = RATE_5_5; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
3004 case 22: Rate = RATE_11; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
3005 case 12: Rate = RATE_6; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
3006 case 18: Rate = RATE_9; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
3007 case 24: Rate = RATE_12; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
3008 case 36: Rate = RATE_18; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
3009 case 48: Rate = RATE_24; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
3010 case 72: Rate = RATE_36; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
3011 case 96: Rate = RATE_48; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
3012 case 108: Rate = RATE_54; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
3013 default: Rate = RATE_1; break;
3014 }
3015 if (MaxSupport < Rate) MaxSupport = Rate;
3016
3017 if (MinSupport > Rate) MinSupport = Rate;
3018 }
3019
3020 for (i=0; i<ExtRateLen; i++)
3021 {
3022 switch (pExtRate[i] & 0x7f)
3023 {
3024 case 2: Rate = RATE_1; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
3025 case 4: Rate = RATE_2; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
3026 case 11: Rate = RATE_5_5; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
3027 case 22: Rate = RATE_11; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
3028 case 12: Rate = RATE_6; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
3029 case 18: Rate = RATE_9; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
3030 case 24: Rate = RATE_12; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
3031 case 36: Rate = RATE_18; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
3032 case 48: Rate = RATE_24; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
3033 case 72: Rate = RATE_36; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
3034 case 96: Rate = RATE_48; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
3035 case 108: Rate = RATE_54; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
3036 default: Rate = RATE_1; break;
3037 }
3038 if (MaxSupport < Rate) MaxSupport = Rate;
3039
3040 if (MinSupport > Rate) MinSupport = Rate;
3041 }
3042
3043 RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
3044
3045 // bug fix
3046 // pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap;
3047
3048 // calculate the exptected ACK rate for each TX rate. This info is used to caculate
3049 // the DURATION field of outgoing uniicast DATA/MGMT frame
3050 for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
3051 {
3052 if (BasicRateBitmap & (0x01 << i))
3053 CurrBasicRate = (UCHAR)i;
3054 pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
3055 }
3056
3057 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
3058 // max tx rate = min {max desire rate, max supported rate}
3059 if (MaxSupport < MaxDesire)
3060 pAd->CommonCfg.MaxTxRate = MaxSupport;
3061 else
3062 pAd->CommonCfg.MaxTxRate = MaxDesire;
3063
3064 pAd->CommonCfg.MinTxRate = MinSupport;
3065 // 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success
3066 // ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending
3067 // on average RSSI
3068 // 1. RSSI >= -70db, start at 54 Mbps (short distance)
3069 // 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance)
3070 // 3. -75 > RSSI, start at 11 Mbps (long distance)
3071 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)/* &&
3072 // OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)*/)
3073 if (*auto_rate_cur_p)
3074 {
3075 short dbm = 0;
3076#ifdef CONFIG_STA_SUPPORT
3077 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3078 dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
3079#endif // CONFIG_STA_SUPPORT //
3080 if (bLinkUp == TRUE)
3081 pAd->CommonCfg.TxRate = RATE_24;
3082 else
3083 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3084
3085 if (dbm < -75)
3086 pAd->CommonCfg.TxRate = RATE_11;
3087 else if (dbm < -70)
3088 pAd->CommonCfg.TxRate = RATE_24;
3089
3090 // should never exceed MaxTxRate (consider 11B-only mode)
3091 if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
3092 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3093
3094 pAd->CommonCfg.TxRateIndex = 0;
3095 }
3096 else
3097 {
3098 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3099 pHtPhy->field.MCS = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
3100 pHtPhy->field.MODE = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
3101
3102 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC = pHtPhy->field.STBC;
3103 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI;
3104 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS = pHtPhy->field.MCS;
3105 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE = pHtPhy->field.MODE;
3106 }
3107
3108 if (pAd->CommonCfg.TxRate <= RATE_11)
3109 {
3110 pMaxHtPhy->field.MODE = MODE_CCK;
3111 pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
3112 pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
3113 }
3114 else
3115 {
3116 pMaxHtPhy->field.MODE = MODE_OFDM;
3117 pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
3118 if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
3119 {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
3120 else
3121 {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
3122 }
3123
3124 pHtPhy->word = (pMaxHtPhy->word);
3125 if (bLinkUp && (pAd->OpMode == OPMODE_STA))
3126 {
3127 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
3128 pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
3129 pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
3130 }
3131 else
3132 {
3133 switch (pAd->CommonCfg.PhyMode)
3134 {
3135 case PHY_11BG_MIXED:
3136 case PHY_11B:
3137#ifdef DOT11_N_SUPPORT
3138 case PHY_11BGN_MIXED:
3139#endif // DOT11_N_SUPPORT //
3140 pAd->CommonCfg.MlmeRate = RATE_1;
3141 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3142 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3143
3144//#ifdef WIFI_TEST
3145 pAd->CommonCfg.RtsRate = RATE_11;
3146//#else
3147// pAd->CommonCfg.RtsRate = RATE_1;
3148//#endif
3149 break;
3150 case PHY_11G:
3151 case PHY_11A:
3152#ifdef DOT11_N_SUPPORT
3153 case PHY_11AGN_MIXED:
3154 case PHY_11GN_MIXED:
3155 case PHY_11N_2_4G:
3156 case PHY_11AN_MIXED:
3157 case PHY_11N_5G:
3158#endif // DOT11_N_SUPPORT //
3159 pAd->CommonCfg.MlmeRate = RATE_6;
3160 pAd->CommonCfg.RtsRate = RATE_6;
3161 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3162 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3163 break;
3164 case PHY_11ABG_MIXED:
3165#ifdef DOT11_N_SUPPORT
3166 case PHY_11ABGN_MIXED:
3167#endif // DOT11_N_SUPPORT //
3168 if (pAd->CommonCfg.Channel <= 14)
3169 {
3170 pAd->CommonCfg.MlmeRate = RATE_1;
3171 pAd->CommonCfg.RtsRate = RATE_1;
3172 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3173 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3174 }
3175 else
3176 {
3177 pAd->CommonCfg.MlmeRate = RATE_6;
3178 pAd->CommonCfg.RtsRate = RATE_6;
3179 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3180 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3181 }
3182 break;
3183 default: // error
3184 pAd->CommonCfg.MlmeRate = RATE_6;
3185 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3186 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3187 pAd->CommonCfg.RtsRate = RATE_1;
3188 break;
3189 }
3190 //
3191 // Keep Basic Mlme Rate.
3192 //
3193 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
3194 if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
3195 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
3196 else
3197 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
3198 pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
3199 }
3200
3201 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
3202 RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
3203 /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
3204 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
3205 RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
3206 DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
3207 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 ));
3208}
3209
3210#ifdef DOT11_N_SUPPORT
3211/*
3212 ==========================================================================
3213 Description:
3214 This function update HT Rate setting.
3215 Input Wcid value is valid for 2 case :
3216 1. it's used for Station in infra mode that copy AP rate to Mactable.
3217 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
3218
3219 IRQL = DISPATCH_LEVEL
3220
3221 ==========================================================================
3222 */
3223VOID MlmeUpdateHtTxRates(
3224 IN PRTMP_ADAPTER pAd,
3225 IN UCHAR apidx)
3226{
3227 UCHAR StbcMcs; //j, StbcMcs, bitmask;
3228 CHAR i; // 3*3
3229 RT_HT_CAPABILITY *pRtHtCap = NULL;
3230 RT_HT_PHY_INFO *pActiveHtPhy = NULL;
3231 ULONG BasicMCS;
3232 UCHAR j, bitmask;
3233 PRT_HT_PHY_INFO pDesireHtPhy = NULL;
3234 PHTTRANSMIT_SETTING pHtPhy = NULL;
3235 PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
3236 PHTTRANSMIT_SETTING pMinHtPhy = NULL;
3237 BOOLEAN *auto_rate_cur_p;
3238
3239 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
3240
3241 auto_rate_cur_p = NULL;
3242
3243#ifdef CONFIG_STA_SUPPORT
3244 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3245 {
3246 pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
3247 pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
3248 pHtPhy = &pAd->StaCfg.HTPhyMode;
3249 pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
3250 pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
3251
3252 auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
3253 }
3254#endif // CONFIG_STA_SUPPORT //
3255
3256#ifdef CONFIG_STA_SUPPORT
3257 if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
3258 {
3259 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
3260 return;
3261
3262 pRtHtCap = &pAd->StaActive.SupportedHtPhy;
3263 pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
3264 StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
3265 BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
3266 if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
3267 pMaxHtPhy->field.STBC = STBC_USE;
3268 else
3269 pMaxHtPhy->field.STBC = STBC_NONE;
3270 }
3271 else
3272#endif // CONFIG_STA_SUPPORT //
3273 {
3274 if (pDesireHtPhy->bHtEnable == FALSE)
3275 return;
3276
3277 pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
3278 StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
3279 BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
3280 if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
3281 pMaxHtPhy->field.STBC = STBC_USE;
3282 else
3283 pMaxHtPhy->field.STBC = STBC_NONE;
3284 }
3285
3286 // Decide MAX ht rate.
3287 if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
3288 pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
3289 else
3290 pMaxHtPhy->field.MODE = MODE_HTMIX;
3291
3292 if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
3293 pMaxHtPhy->field.BW = BW_40;
3294 else
3295 pMaxHtPhy->field.BW = BW_20;
3296
3297 if (pMaxHtPhy->field.BW == BW_20)
3298 pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
3299 else
3300 pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
3301
3302 for (i=23; i>=0; i--) // 3*3
3303 {
3304 j = i/8;
3305 bitmask = (1<<(i-(j*8)));
3306
3307 if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
3308 {
3309 pMaxHtPhy->field.MCS = i;
3310 break;
3311 }
3312
3313 if (i==0)
3314 break;
3315 }
3316
3317 // Copy MIN ht rate. rt2860???
3318 pMinHtPhy->field.BW = BW_20;
3319 pMinHtPhy->field.MCS = 0;
3320 pMinHtPhy->field.STBC = 0;
3321 pMinHtPhy->field.ShortGI = 0;
3322 //If STA assigns fixed rate. update to fixed here.
3323#ifdef CONFIG_STA_SUPPORT
3324 if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
3325 {
3326 if (pDesireHtPhy->MCSSet[4] != 0)
3327 {
3328 pMaxHtPhy->field.MCS = 32;
3329 pMinHtPhy->field.MCS = 32;
3330 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
3331 }
3332
3333 for (i=23; (CHAR)i >= 0; i--) // 3*3
3334 {
3335 j = i/8;
3336 bitmask = (1<<(i-(j*8)));
3337 if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
3338 {
3339 pMaxHtPhy->field.MCS = i;
3340 pMinHtPhy->field.MCS = i;
3341 break;
3342 }
3343 if (i==0)
3344 break;
3345 }
3346 }
3347#endif // CONFIG_STA_SUPPORT //
3348
3349
3350 // Decide ht rate
3351 pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
3352 pHtPhy->field.BW = pMaxHtPhy->field.BW;
3353 pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
3354 pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
3355 pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
3356
3357 // use default now. rt2860
3358 if (pDesireHtPhy->MCSSet[0] != 0xff)
3359 *auto_rate_cur_p = FALSE;
3360 else
3361 *auto_rate_cur_p = TRUE;
3362
3363 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
3364 DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
3365 pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
3366 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
3367}
3368#endif // DOT11_N_SUPPORT //
3369
3370// IRQL = DISPATCH_LEVEL
3371VOID MlmeRadioOff(
3372 IN PRTMP_ADAPTER pAd)
3373{
3374 RT28XX_MLME_RADIO_OFF(pAd);
3375}
3376
3377// IRQL = DISPATCH_LEVEL
3378VOID MlmeRadioOn(
3379 IN PRTMP_ADAPTER pAd)
3380{
3381 RT28XX_MLME_RADIO_ON(pAd);
3382}
3383
3384// ===========================================================================================
3385// bss_table.c
3386// ===========================================================================================
3387
3388
3389/*! \brief initialize BSS table
3390 * \param p_tab pointer to the table
3391 * \return none
3392 * \pre
3393 * \post
3394
3395 IRQL = PASSIVE_LEVEL
3396 IRQL = DISPATCH_LEVEL
3397
3398 */
3399VOID BssTableInit(
3400 IN BSS_TABLE *Tab)
3401{
3402 int i;
3403
3404 Tab->BssNr = 0;
3405 Tab->BssOverlapNr = 0;
3406 for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
3407 {
3408 NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
3409 Tab->BssEntry[i].Rssi = -127; // initial the rssi as a minimum value
3410 }
3411}
3412
3413#ifdef DOT11_N_SUPPORT
3414VOID BATableInit(
3415 IN PRTMP_ADAPTER pAd,
3416 IN BA_TABLE *Tab)
3417{
3418 int i;
3419
3420 Tab->numAsOriginator = 0;
3421 Tab->numAsRecipient = 0;
3422 NdisAllocateSpinLock(&pAd->BATabLock);
3423 for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
3424 {
3425 Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
3426 NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
3427 }
3428 for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
3429 {
3430 Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
3431 }
3432}
3433#endif // DOT11_N_SUPPORT //
3434
3435/*! \brief search the BSS table by SSID
3436 * \param p_tab pointer to the bss table
3437 * \param ssid SSID string
3438 * \return index of the table, BSS_NOT_FOUND if not in the table
3439 * \pre
3440 * \post
3441 * \note search by sequential search
3442
3443 IRQL = DISPATCH_LEVEL
3444
3445 */
3446ULONG BssTableSearch(
3447 IN BSS_TABLE *Tab,
3448 IN PUCHAR pBssid,
3449 IN UCHAR Channel)
3450{
3451 UCHAR i;
3452
3453 for (i = 0; i < Tab->BssNr; i++)
3454 {
3455 //
3456 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3457 // We should distinguish this case.
3458 //
3459 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3460 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3461 MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
3462 {
3463 return i;
3464 }
3465 }
3466 return (ULONG)BSS_NOT_FOUND;
3467}
3468
3469ULONG BssSsidTableSearch(
3470 IN BSS_TABLE *Tab,
3471 IN PUCHAR pBssid,
3472 IN PUCHAR pSsid,
3473 IN UCHAR SsidLen,
3474 IN UCHAR Channel)
3475{
3476 UCHAR i;
3477
3478 for (i = 0; i < Tab->BssNr; i++)
3479 {
3480 //
3481 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3482 // We should distinguish this case.
3483 //
3484 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3485 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3486 MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
3487 SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
3488 {
3489 return i;
3490 }
3491 }
3492 return (ULONG)BSS_NOT_FOUND;
3493}
3494
3495ULONG BssTableSearchWithSSID(
3496 IN BSS_TABLE *Tab,
3497 IN PUCHAR Bssid,
3498 IN PUCHAR pSsid,
3499 IN UCHAR SsidLen,
3500 IN UCHAR Channel)
3501{
3502 UCHAR i;
3503
3504 for (i = 0; i < Tab->BssNr; i++)
3505 {
3506 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3507 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3508 MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
3509 (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
3510 (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
3511 (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
3512 {
3513 return i;
3514 }
3515 }
3516 return (ULONG)BSS_NOT_FOUND;
3517}
3518
3519// IRQL = DISPATCH_LEVEL
3520VOID BssTableDeleteEntry(
3521 IN OUT BSS_TABLE *Tab,
3522 IN PUCHAR pBssid,
3523 IN UCHAR Channel)
3524{
3525 UCHAR i, j;
3526
3527 for (i = 0; i < Tab->BssNr; i++)
3528 {
3529 if ((Tab->BssEntry[i].Channel == Channel) &&
3530 (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
3531 {
3532 for (j = i; j < Tab->BssNr - 1; j++)
3533 {
3534 NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
3535 }
3536 NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
3537 Tab->BssNr -= 1;
3538 return;
3539 }
3540 }
3541}
3542
3543#ifdef DOT11_N_SUPPORT
3544/*
3545 ========================================================================
3546 Routine Description:
3547 Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
3548
3549 Arguments:
3550 // IRQL = DISPATCH_LEVEL
3551 ========================================================================
3552*/
3553VOID BATableDeleteORIEntry(
3554 IN OUT PRTMP_ADAPTER pAd,
3555 IN BA_ORI_ENTRY *pBAORIEntry)
3556{
3557
3558 if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
3559 {
3560 NdisAcquireSpinLock(&pAd->BATabLock);
3561 if (pBAORIEntry->ORI_BA_Status == Originator_Done)
3562 {
3563 pAd->BATable.numAsOriginator -= 1;
3564 DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
3565 // Erase Bitmap flag.
3566 }
3567 pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) )); // If STA mode, erase flag here
3568 pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0; // If STA mode, erase flag here
3569 pBAORIEntry->ORI_BA_Status = Originator_NONE;
3570 pBAORIEntry->Token = 1;
3571 // Not clear Sequence here.
3572 NdisReleaseSpinLock(&pAd->BATabLock);
3573 }
3574}
3575#endif // DOT11_N_SUPPORT //
3576
3577/*! \brief
3578 * \param
3579 * \return
3580 * \pre
3581 * \post
3582
3583 IRQL = DISPATCH_LEVEL
3584
3585 */
3586VOID BssEntrySet(
3587 IN PRTMP_ADAPTER pAd,
3588 OUT BSS_ENTRY *pBss,
3589 IN PUCHAR pBssid,
3590 IN CHAR Ssid[],
3591 IN UCHAR SsidLen,
3592 IN UCHAR BssType,
3593 IN USHORT BeaconPeriod,
3594 IN PCF_PARM pCfParm,
3595 IN USHORT AtimWin,
3596 IN USHORT CapabilityInfo,
3597 IN UCHAR SupRate[],
3598 IN UCHAR SupRateLen,
3599 IN UCHAR ExtRate[],
3600 IN UCHAR ExtRateLen,
3601 IN HT_CAPABILITY_IE *pHtCapability,
3602 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
3603 IN UCHAR HtCapabilityLen,
3604 IN UCHAR AddHtInfoLen,
3605 IN UCHAR NewExtChanOffset,
3606 IN UCHAR Channel,
3607 IN CHAR Rssi,
3608 IN LARGE_INTEGER TimeStamp,
3609 IN UCHAR CkipFlag,
3610 IN PEDCA_PARM pEdcaParm,
3611 IN PQOS_CAPABILITY_PARM pQosCapability,
3612 IN PQBSS_LOAD_PARM pQbssLoad,
3613 IN USHORT LengthVIE,
3614 IN PNDIS_802_11_VARIABLE_IEs pVIE)
3615{
3616 COPY_MAC_ADDR(pBss->Bssid, pBssid);
3617 // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
3618 pBss->Hidden = 1;
3619 if (SsidLen > 0)
3620 {
3621 // For hidden SSID AP, it might send beacon with SSID len equal to 0
3622 // Or send beacon /probe response with SSID len matching real SSID length,
3623 // but SSID is all zero. such as "00-00-00-00" with length 4.
3624 // We have to prevent this case overwrite correct table
3625 if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
3626 {
3627 NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
3628 NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
3629 pBss->SsidLen = SsidLen;
3630 pBss->Hidden = 0;
3631 }
3632 }
3633 else
3634 pBss->SsidLen = 0;
3635 pBss->BssType = BssType;
3636 pBss->BeaconPeriod = BeaconPeriod;
3637 if (BssType == BSS_INFRA)
3638 {
3639 if (pCfParm->bValid)
3640 {
3641 pBss->CfpCount = pCfParm->CfpCount;
3642 pBss->CfpPeriod = pCfParm->CfpPeriod;
3643 pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
3644 pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
3645 }
3646 }
3647 else
3648 {
3649 pBss->AtimWin = AtimWin;
3650 }
3651
3652 pBss->CapabilityInfo = CapabilityInfo;
3653 // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
3654 // Combine with AuthMode, they will decide the connection methods.
3655 pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
3656 ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3657 if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
3658 NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
3659 else
3660 NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
3661 pBss->SupRateLen = SupRateLen;
3662 ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3663 NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
3664 NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
3665 NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
3666 pBss->NewExtChanOffset = NewExtChanOffset;
3667 pBss->ExtRateLen = ExtRateLen;
3668 pBss->Channel = Channel;
3669 pBss->CentralChannel = Channel;
3670 pBss->Rssi = Rssi;
3671 // Update CkipFlag. if not exists, the value is 0x0
3672 pBss->CkipFlag = CkipFlag;
3673
3674 // New for microsoft Fixed IEs
3675 NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
3676 pBss->FixIEs.BeaconInterval = BeaconPeriod;
3677 pBss->FixIEs.Capabilities = CapabilityInfo;
3678
3679 // New for microsoft Variable IEs
3680 if (LengthVIE != 0)
3681 {
3682 pBss->VarIELen = LengthVIE;
3683 NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
3684 }
3685 else
3686 {
3687 pBss->VarIELen = 0;
3688 }
3689
3690 pBss->AddHtInfoLen = 0;
3691 pBss->HtCapabilityLen = 0;
3692#ifdef DOT11_N_SUPPORT
3693 if (HtCapabilityLen> 0)
3694 {
3695 pBss->HtCapabilityLen = HtCapabilityLen;
3696 NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
3697 if (AddHtInfoLen > 0)
3698 {
3699 pBss->AddHtInfoLen = AddHtInfoLen;
3700 NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
3701
3702 if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3703 {
3704 pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
3705 }
3706 else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3707 {
3708 pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
3709 }
3710 }
3711 }
3712#endif // DOT11_N_SUPPORT //
3713
3714 BssCipherParse(pBss);
3715
3716 // new for QOS
3717 if (pEdcaParm)
3718 NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
3719 else
3720 pBss->EdcaParm.bValid = FALSE;
3721 if (pQosCapability)
3722 NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
3723 else
3724 pBss->QosCapability.bValid = FALSE;
3725 if (pQbssLoad)
3726 NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
3727 else
3728 pBss->QbssLoad.bValid = FALSE;
3729
3730#ifdef CONFIG_STA_SUPPORT
3731 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3732 {
3733 PEID_STRUCT pEid;
3734 USHORT Length = 0;
3735
3736
3737 NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
3738 NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
3739#ifdef EXT_BUILD_CHANNEL_LIST
3740 NdisZeroMemory(&pBss->CountryString[0], 3);
3741 pBss->bHasCountryIE = FALSE;
3742#endif // EXT_BUILD_CHANNEL_LIST //
3743 pEid = (PEID_STRUCT) pVIE;
3744 while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
3745 {
3746 switch(pEid->Eid)
3747 {
3748 case IE_WPA:
3749 if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
3750 {
3751 if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
3752 {
3753 pBss->WpaIE.IELen = 0;
3754 break;
3755 }
3756 pBss->WpaIE.IELen = pEid->Len + 2;
3757 NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
3758 }
3759 break;
3760 case IE_RSN:
3761 if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
3762 {
3763 if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
3764 {
3765 pBss->RsnIE.IELen = 0;
3766 break;
3767 }
3768 pBss->RsnIE.IELen = pEid->Len + 2;
3769 NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
3770 }
3771 break;
3772#ifdef EXT_BUILD_CHANNEL_LIST
3773 case IE_COUNTRY:
3774 NdisMoveMemory(&pBss->CountryString[0], pEid->Octet, 3);
3775 pBss->bHasCountryIE = TRUE;
3776 break;
3777#endif // EXT_BUILD_CHANNEL_LIST //
3778 }
3779 Length = Length + 2 + (USHORT)pEid->Len; // Eid[1] + Len[1]+ content[Len]
3780 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
3781 }
3782 }
3783#endif // CONFIG_STA_SUPPORT //
3784}
3785
3786/*!
3787 * \brief insert an entry into the bss table
3788 * \param p_tab The BSS table
3789 * \param Bssid BSSID
3790 * \param ssid SSID
3791 * \param ssid_len Length of SSID
3792 * \param bss_type
3793 * \param beacon_period
3794 * \param timestamp
3795 * \param p_cf
3796 * \param atim_win
3797 * \param cap
3798 * \param rates
3799 * \param rates_len
3800 * \param channel_idx
3801 * \return none
3802 * \pre
3803 * \post
3804 * \note If SSID is identical, the old entry will be replaced by the new one
3805
3806 IRQL = DISPATCH_LEVEL
3807
3808 */
3809ULONG BssTableSetEntry(
3810 IN PRTMP_ADAPTER pAd,
3811 OUT BSS_TABLE *Tab,
3812 IN PUCHAR pBssid,
3813 IN CHAR Ssid[],
3814 IN UCHAR SsidLen,
3815 IN UCHAR BssType,
3816 IN USHORT BeaconPeriod,
3817 IN CF_PARM *CfParm,
3818 IN USHORT AtimWin,
3819 IN USHORT CapabilityInfo,
3820 IN UCHAR SupRate[],
3821 IN UCHAR SupRateLen,
3822 IN UCHAR ExtRate[],
3823 IN UCHAR ExtRateLen,
3824 IN HT_CAPABILITY_IE *pHtCapability,
3825 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
3826 IN UCHAR HtCapabilityLen,
3827 IN UCHAR AddHtInfoLen,
3828 IN UCHAR NewExtChanOffset,
3829 IN UCHAR ChannelNo,
3830 IN CHAR Rssi,
3831 IN LARGE_INTEGER TimeStamp,
3832 IN UCHAR CkipFlag,
3833 IN PEDCA_PARM pEdcaParm,
3834 IN PQOS_CAPABILITY_PARM pQosCapability,
3835 IN PQBSS_LOAD_PARM pQbssLoad,
3836 IN USHORT LengthVIE,
3837 IN PNDIS_802_11_VARIABLE_IEs pVIE)
3838{
3839 ULONG Idx;
3840
3841 Idx = BssTableSearchWithSSID(Tab, pBssid, Ssid, SsidLen, ChannelNo);
3842 if (Idx == BSS_NOT_FOUND)
3843 {
3844 if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
3845 {
3846 //
3847 // It may happen when BSS Table was full.
3848 // The desired AP will not be added into BSS Table
3849 // In this case, if we found the desired AP then overwrite BSS Table.
3850 //
3851 if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
3852 {
3853 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
3854 SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
3855 {
3856 Idx = Tab->BssOverlapNr;
3857 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
3858 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3859 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3860 Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
3861 }
3862 return Idx;
3863 }
3864 else
3865 {
3866 return BSS_NOT_FOUND;
3867 }
3868 }
3869 Idx = Tab->BssNr;
3870 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
3871 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3872 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3873 Tab->BssNr++;
3874 }
3875 else
3876 {
3877 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
3878 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3879 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3880 }
3881
3882 return Idx;
3883}
3884
3885#ifdef CONFIG_STA_SUPPORT
3886#ifdef DOT11_N_SUPPORT
3887#ifdef DOT11N_DRAFT3
3888VOID TriEventInit(
3889 IN PRTMP_ADAPTER pAd)
3890{
3891 UCHAR i;
3892
3893 for (i = 0;i < MAX_TRIGGER_EVENT;i++)
3894 pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
3895
3896 pAd->CommonCfg.TriggerEventTab.EventANo = 0;
3897 pAd->CommonCfg.TriggerEventTab.EventBCountDown = 0;
3898}
3899
3900ULONG TriEventTableSetEntry(
3901 IN PRTMP_ADAPTER pAd,
3902 OUT TRIGGER_EVENT_TAB *Tab,
3903 IN PUCHAR pBssid,
3904 IN HT_CAPABILITY_IE *pHtCapability,
3905 IN UCHAR HtCapabilityLen,
3906 IN UCHAR RegClass,
3907 IN UCHAR ChannelNo)
3908{
3909 // Event A
3910 if (HtCapabilityLen == 0)
3911 {
3912 if (Tab->EventANo < MAX_TRIGGER_EVENT)
3913 {
3914 RTMPMoveMemory(Tab->EventA[Tab->EventANo].BSSID, pBssid, 6);
3915 Tab->EventA[Tab->EventANo].bValid = TRUE;
3916 Tab->EventA[Tab->EventANo].Channel = ChannelNo;
3917 Tab->EventA[Tab->EventANo].CDCounter = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
3918 if (RegClass != 0)
3919 {
3920 // Beacon has Regulatory class IE. So use beacon's
3921 Tab->EventA[Tab->EventANo].RegClass = RegClass;
3922 }
3923 else
3924 {
3925 // Use Station's Regulatory class instead.
3926 if (pAd->StaActive.SupportedHtPhy.bHtEnable == TRUE)
3927 {
3928 if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
3929 {
3930 Tab->EventA[Tab->EventANo].RegClass = 32;
3931 }
3932 else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
3933 Tab->EventA[Tab->EventANo].RegClass = 33;
3934 }
3935 else
3936 Tab->EventA[Tab->EventANo].RegClass = ??;
3937
3938 }
3939
3940 Tab->EventANo ++;
3941 }
3942 }
3943 else if (pHtCapability->HtCapInfo.Intolerant40)
3944 {
3945 Tab->EventBCountDown = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
3946 }
3947
3948}
3949
3950/*
3951 ========================================================================
3952 Routine Description:
3953 Trigger Event table Maintainence called once every second.
3954
3955 Arguments:
3956 // IRQL = DISPATCH_LEVEL
3957 ========================================================================
3958*/
3959VOID TriEventCounterMaintenance(
3960 IN PRTMP_ADAPTER pAd)
3961{
3962 UCHAR i;
3963 BOOLEAN bNotify = FALSE;
3964 for (i = 0;i < MAX_TRIGGER_EVENT;i++)
3965 {
3966 if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid && (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter > 0))
3967 {
3968 pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter--;
3969 if (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter == 0)
3970 {
3971 pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
3972 pAd->CommonCfg.TriggerEventTab.EventANo --;
3973 // Need to send 20/40 Coexistence Notify frame if has status change.
3974 bNotify = TRUE;
3975 }
3976 }
3977 }
3978 if (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0)
3979 {
3980 pAd->CommonCfg.TriggerEventTab.EventBCountDown--;
3981 if (pAd->CommonCfg.TriggerEventTab.EventBCountDown == 0)
3982 bNotify = TRUE;
3983 }
3984
3985 if (bNotify == TRUE)
3986 Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
3987}
3988#endif // DOT11N_DRAFT3 //
3989#endif // DOT11_N_SUPPORT //
3990
3991// IRQL = DISPATCH_LEVEL
3992VOID BssTableSsidSort(
3993 IN PRTMP_ADAPTER pAd,
3994 OUT BSS_TABLE *OutTab,
3995 IN CHAR Ssid[],
3996 IN UCHAR SsidLen)
3997{
3998 INT i;
3999 BssTableInit(OutTab);
4000
4001 for (i = 0; i < pAd->ScanTab.BssNr; i++)
4002 {
4003 BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
4004 BOOLEAN bIsHiddenApIncluded = FALSE;
4005
4006 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
4007 (pAd->MlmeAux.Channel > 14) &&
4008 RadarChannelCheck(pAd, pInBss->Channel))
4009#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
4010 || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
4011#endif // CARRIER_DETECTION_SUPPORT //
4012 )
4013 {
4014 if (pInBss->Hidden)
4015 bIsHiddenApIncluded = TRUE;
4016 }
4017
4018 if ((pInBss->BssType == pAd->StaCfg.BssType) &&
4019 (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
4020 {
4021 BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
4022
4023
4024#ifdef EXT_BUILD_CHANNEL_LIST
4025 // If no Country IE exists no Connection will be established when IEEE80211dClientMode is strict.
4026 if ((pAd->StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict) &&
4027 (pInBss->bHasCountryIE == FALSE))
4028 {
4029 DBGPRINT(RT_DEBUG_TRACE,("StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict, but this AP doesn't have country IE.\n"));
4030 continue;
4031 }
4032#endif // EXT_BUILD_CHANNEL_LIST //
4033
4034#ifdef DOT11_N_SUPPORT
4035 // 2.4G/5G N only mode
4036 if ((pInBss->HtCapabilityLen == 0) &&
4037 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
4038 {
4039 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
4040 continue;
4041 }
4042#endif // DOT11_N_SUPPORT //
4043
4044 // New for WPA2
4045 // Check the Authmode first
4046 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
4047 {
4048 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
4049 if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
4050 // None matched
4051 continue;
4052
4053 // Check cipher suite, AP must have more secured cipher than station setting
4054 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
4055 {
4056 // If it's not mixed mode, we should only let BSS pass with the same encryption
4057 if (pInBss->WPA.bMixMode == FALSE)
4058 if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
4059 continue;
4060
4061 // check group cipher
4062 if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
4063 (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
4064 (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled))
4065 continue;
4066
4067 // check pairwise cipher, skip if none matched
4068 // If profile set to AES, let it pass without question.
4069 // If profile set to TKIP, we must find one mateched
4070 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4071 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
4072 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
4073 continue;
4074 }
4075 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
4076 {
4077 // If it's not mixed mode, we should only let BSS pass with the same encryption
4078 if (pInBss->WPA2.bMixMode == FALSE)
4079 if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
4080 continue;
4081
4082 // check group cipher
4083 if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
4084 (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
4085 (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled))
4086 continue;
4087
4088 // check pairwise cipher, skip if none matched
4089 // If profile set to AES, let it pass without question.
4090 // If profile set to TKIP, we must find one mateched
4091 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4092 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
4093 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
4094 continue;
4095 }
4096 }
4097 // Bss Type matched, SSID matched.
4098 // We will check wepstatus for qualification Bss
4099 else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
4100 {
4101 DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
4102 //
4103 // For the SESv2 case, we will not qualify WepStatus.
4104 //
4105 if (!pInBss->bSES)
4106 continue;
4107 }
4108
4109 // Since the AP is using hidden SSID, and we are trying to connect to ANY
4110 // It definitely will fail. So, skip it.
4111 // CCX also require not even try to connect it!!
4112 if (SsidLen == 0)
4113 continue;
4114
4115#ifdef DOT11_N_SUPPORT
4116 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
4117 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
4118 if ((pInBss->CentralChannel != pInBss->Channel) &&
4119 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
4120 {
4121 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
4122 {
4123 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
4124 SetCommonHT(pAd);
4125 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
4126 }
4127 else
4128 {
4129 if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
4130 {
4131 SetCommonHT(pAd);
4132 }
4133 }
4134 }
4135#endif // DOT11_N_SUPPORT //
4136
4137 // copy matching BSS from InTab to OutTab
4138 NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
4139
4140 OutTab->BssNr++;
4141 }
4142 else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
4143 {
4144 BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
4145
4146
4147#ifdef DOT11_N_SUPPORT
4148 // 2.4G/5G N only mode
4149 if ((pInBss->HtCapabilityLen == 0) &&
4150 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
4151 {
4152 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
4153 continue;
4154 }
4155#endif // DOT11_N_SUPPORT //
4156
4157 // New for WPA2
4158 // Check the Authmode first
4159 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
4160 {
4161 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
4162 if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
4163 // None matched
4164 continue;
4165
4166 // Check cipher suite, AP must have more secured cipher than station setting
4167 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
4168 {
4169 // If it's not mixed mode, we should only let BSS pass with the same encryption
4170 if (pInBss->WPA.bMixMode == FALSE)
4171 if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
4172 continue;
4173
4174 // check group cipher
4175 if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
4176 continue;
4177
4178 // check pairwise cipher, skip if none matched
4179 // If profile set to AES, let it pass without question.
4180 // If profile set to TKIP, we must find one mateched
4181 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4182 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
4183 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
4184 continue;
4185 }
4186 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
4187 {
4188 // If it's not mixed mode, we should only let BSS pass with the same encryption
4189 if (pInBss->WPA2.bMixMode == FALSE)
4190 if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
4191 continue;
4192
4193 // check group cipher
4194 if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
4195 continue;
4196
4197 // check pairwise cipher, skip if none matched
4198 // If profile set to AES, let it pass without question.
4199 // If profile set to TKIP, we must find one mateched
4200 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4201 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
4202 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
4203 continue;
4204 }
4205 }
4206 // Bss Type matched, SSID matched.
4207 // We will check wepstatus for qualification Bss
4208 else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
4209 continue;
4210
4211#ifdef DOT11_N_SUPPORT
4212 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
4213 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
4214 if ((pInBss->CentralChannel != pInBss->Channel) &&
4215 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
4216 {
4217 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
4218 {
4219 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
4220 SetCommonHT(pAd);
4221 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
4222 }
4223 }
4224#endif // DOT11_N_SUPPORT //
4225
4226 // copy matching BSS from InTab to OutTab
4227 NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
4228
4229 OutTab->BssNr++;
4230 }
4231
4232 if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
4233 break;
4234 }
4235
4236 BssTableSortByRssi(OutTab);
4237}
4238
4239
4240// IRQL = DISPATCH_LEVEL
4241VOID BssTableSortByRssi(
4242 IN OUT BSS_TABLE *OutTab)
4243{
4244 INT i, j;
4245 BSS_ENTRY TmpBss;
4246
4247 for (i = 0; i < OutTab->BssNr - 1; i++)
4248 {
4249 for (j = i+1; j < OutTab->BssNr; j++)
4250 {
4251 if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
4252 {
4253 NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
4254 NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
4255 NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
4256 }
4257 }
4258 }
4259}
4260#endif // CONFIG_STA_SUPPORT //
4261
4262
4263VOID BssCipherParse(
4264 IN OUT PBSS_ENTRY pBss)
4265{
4266 PEID_STRUCT pEid;
4267 PUCHAR pTmp;
4268 PRSN_IE_HEADER_STRUCT pRsnHeader;
4269 PCIPHER_SUITE_STRUCT pCipher;
4270 PAKM_SUITE_STRUCT pAKM;
4271 USHORT Count;
4272 INT Length;
4273 NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
4274
4275 //
4276 // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
4277 //
4278 if (pBss->Privacy)
4279 {
4280 pBss->WepStatus = Ndis802_11WEPEnabled;
4281 }
4282 else
4283 {
4284 pBss->WepStatus = Ndis802_11WEPDisabled;
4285 }
4286 // Set default to disable & open authentication before parsing variable IE
4287 pBss->AuthMode = Ndis802_11AuthModeOpen;
4288 pBss->AuthModeAux = Ndis802_11AuthModeOpen;
4289
4290 // Init WPA setting
4291 pBss->WPA.PairCipher = Ndis802_11WEPDisabled;
4292 pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
4293 pBss->WPA.GroupCipher = Ndis802_11WEPDisabled;
4294 pBss->WPA.RsnCapability = 0;
4295 pBss->WPA.bMixMode = FALSE;
4296
4297 // Init WPA2 setting
4298 pBss->WPA2.PairCipher = Ndis802_11WEPDisabled;
4299 pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
4300 pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
4301 pBss->WPA2.RsnCapability = 0;
4302 pBss->WPA2.bMixMode = FALSE;
4303
4304
4305 Length = (INT) pBss->VarIELen;
4306
4307 while (Length > 0)
4308 {
4309 // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
4310 pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
4311 pEid = (PEID_STRUCT) pTmp;
4312 switch (pEid->Eid)
4313 {
4314 case IE_WPA:
4315 //Parse Cisco IE_WPA (LEAP, CCKM, etc.)
4316 if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3))
4317 {
4318 pTmp += 11;
4319 switch (*pTmp)
4320 {
4321 case 1:
4322 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4323 pBss->WepStatus = Ndis802_11Encryption1Enabled;
4324 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4325 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4326 break;
4327 case 2:
4328 pBss->WepStatus = Ndis802_11Encryption2Enabled;
4329 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4330 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4331 break;
4332 case 4:
4333 pBss->WepStatus = Ndis802_11Encryption3Enabled;
4334 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4335 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4336 break;
4337 default:
4338 break;
4339 }
4340
4341 // if Cisco IE_WPA, break
4342 break;
4343 }
4344 else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
4345 {
4346 pBss->bSES = TRUE;
4347 break;
4348 }
4349 else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
4350 {
4351 // if unsupported vendor specific IE
4352 break;
4353 }
4354 // Skip OUI, version, and multicast suite
4355 // This part should be improved in the future when AP supported multiple cipher suite.
4356 // For now, it's OK since almost all APs have fixed cipher suite supported.
4357 // pTmp = (PUCHAR) pEid->Octet;
4358 pTmp += 11;
4359
4360 // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
4361 // Value Meaning
4362 // 0 None
4363 // 1 WEP-40
4364 // 2 Tkip
4365 // 3 WRAP
4366 // 4 AES
4367 // 5 WEP-104
4368 // Parse group cipher
4369 switch (*pTmp)
4370 {
4371 case 1:
4372 pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
4373 break;
4374 case 5:
4375 pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
4376 break;
4377 case 2:
4378 pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
4379 break;
4380 case 4:
4381 pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled;
4382 break;
4383 default:
4384 break;
4385 }
4386 // number of unicast suite
4387 pTmp += 1;
4388
4389 // skip all unicast cipher suites
4390 //Count = *(PUSHORT) pTmp;
4391 Count = (pTmp[1]<<8) + pTmp[0];
4392 pTmp += sizeof(USHORT);
4393
4394 // Parsing all unicast cipher suite
4395 while (Count > 0)
4396 {
4397 // Skip OUI
4398 pTmp += 3;
4399 TmpCipher = Ndis802_11WEPDisabled;
4400 switch (*pTmp)
4401 {
4402 case 1:
4403 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4404 TmpCipher = Ndis802_11Encryption1Enabled;
4405 break;
4406 case 2:
4407 TmpCipher = Ndis802_11Encryption2Enabled;
4408 break;
4409 case 4:
4410 TmpCipher = Ndis802_11Encryption3Enabled;
4411 break;
4412 default:
4413 break;
4414 }
4415 if (TmpCipher > pBss->WPA.PairCipher)
4416 {
4417 // Move the lower cipher suite to PairCipherAux
4418 pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
4419 pBss->WPA.PairCipher = TmpCipher;
4420 }
4421 else
4422 {
4423 pBss->WPA.PairCipherAux = TmpCipher;
4424 }
4425 pTmp++;
4426 Count--;
4427 }
4428
4429 // 4. get AKM suite counts
4430 //Count = *(PUSHORT) pTmp;
4431 Count = (pTmp[1]<<8) + pTmp[0];
4432 pTmp += sizeof(USHORT);
4433 pTmp += 3;
4434
4435 switch (*pTmp)
4436 {
4437 case 1:
4438 // Set AP support WPA mode
4439 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4440 pBss->AuthMode = Ndis802_11AuthModeWPA;
4441 else
4442 pBss->AuthModeAux = Ndis802_11AuthModeWPA;
4443 break;
4444 case 2:
4445 // Set AP support WPA mode
4446 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4447 pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
4448 else
4449 pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
4450 break;
4451 default:
4452 break;
4453 }
4454 pTmp += 1;
4455
4456 // Fixed for WPA-None
4457 if (pBss->BssType == BSS_ADHOC)
4458 {
4459 pBss->AuthMode = Ndis802_11AuthModeWPANone;
4460 pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4461 pBss->WepStatus = pBss->WPA.GroupCipher;
4462 // Patched bugs for old driver
4463 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
4464 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
4465 }
4466 else
4467 pBss->WepStatus = pBss->WPA.PairCipher;
4468
4469 // Check the Pair & Group, if different, turn on mixed mode flag
4470 if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
4471 pBss->WPA.bMixMode = TRUE;
4472
4473 break;
4474
4475 case IE_RSN:
4476 pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
4477
4478 // 0. Version must be 1
4479 if (le2cpu16(pRsnHeader->Version) != 1)
4480 break;
4481 pTmp += sizeof(RSN_IE_HEADER_STRUCT);
4482
4483 // 1. Check group cipher
4484 pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
4485 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4486 break;
4487
4488 // Parse group cipher
4489 switch (pCipher->Type)
4490 {
4491 case 1:
4492 pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
4493 break;
4494 case 5:
4495 pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
4496 break;
4497 case 2:
4498 pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
4499 break;
4500 case 4:
4501 pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
4502 break;
4503 default:
4504 break;
4505 }
4506 // set to correct offset for next parsing
4507 pTmp += sizeof(CIPHER_SUITE_STRUCT);
4508
4509 // 2. Get pairwise cipher counts
4510 //Count = *(PUSHORT) pTmp;
4511 Count = (pTmp[1]<<8) + pTmp[0];
4512 pTmp += sizeof(USHORT);
4513
4514 // 3. Get pairwise cipher
4515 // Parsing all unicast cipher suite
4516 while (Count > 0)
4517 {
4518 // Skip OUI
4519 pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
4520 TmpCipher = Ndis802_11WEPDisabled;
4521 switch (pCipher->Type)
4522 {
4523 case 1:
4524 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4525 TmpCipher = Ndis802_11Encryption1Enabled;
4526 break;
4527 case 2:
4528 TmpCipher = Ndis802_11Encryption2Enabled;
4529 break;
4530 case 4:
4531 TmpCipher = Ndis802_11Encryption3Enabled;
4532 break;
4533 default:
4534 break;
4535 }
4536 if (TmpCipher > pBss->WPA2.PairCipher)
4537 {
4538 // Move the lower cipher suite to PairCipherAux
4539 pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
4540 pBss->WPA2.PairCipher = TmpCipher;
4541 }
4542 else
4543 {
4544 pBss->WPA2.PairCipherAux = TmpCipher;
4545 }
4546 pTmp += sizeof(CIPHER_SUITE_STRUCT);
4547 Count--;
4548 }
4549
4550 // 4. get AKM suite counts
4551 //Count = *(PUSHORT) pTmp;
4552 Count = (pTmp[1]<<8) + pTmp[0];
4553 pTmp += sizeof(USHORT);
4554
4555 // 5. Get AKM ciphers
4556 pAKM = (PAKM_SUITE_STRUCT) pTmp;
4557 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4558 break;
4559
4560 switch (pAKM->Type)
4561 {
4562 case 1:
4563 // Set AP support WPA mode
4564 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4565 pBss->AuthMode = Ndis802_11AuthModeWPA2;
4566 else
4567 pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
4568 break;
4569 case 2:
4570 // Set AP support WPA mode
4571 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4572 pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
4573 else
4574 pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
4575 break;
4576 default:
4577 break;
4578 }
4579 pTmp += (Count * sizeof(AKM_SUITE_STRUCT));
4580
4581 // Fixed for WPA-None
4582 if (pBss->BssType == BSS_ADHOC)
4583 {
4584 pBss->AuthMode = Ndis802_11AuthModeWPANone;
4585 pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4586 pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
4587 pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
4588 pBss->WepStatus = pBss->WPA.GroupCipher;
4589 // Patched bugs for old driver
4590 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
4591 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
4592 }
4593 pBss->WepStatus = pBss->WPA2.PairCipher;
4594
4595 // 6. Get RSN capability
4596 //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
4597 pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
4598 pTmp += sizeof(USHORT);
4599
4600 // Check the Pair & Group, if different, turn on mixed mode flag
4601 if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
4602 pBss->WPA2.bMixMode = TRUE;
4603
4604 break;
4605 default:
4606 break;
4607 }
4608 Length -= (pEid->Len + 2);
4609 }
4610}
4611
4612// ===========================================================================================
4613// mac_table.c
4614// ===========================================================================================
4615
4616/*! \brief generates a random mac address value for IBSS BSSID
4617 * \param Addr the bssid location
4618 * \return none
4619 * \pre
4620 * \post
4621 */
4622VOID MacAddrRandomBssid(
4623 IN PRTMP_ADAPTER pAd,
4624 OUT PUCHAR pAddr)
4625{
4626 INT i;
4627
4628 for (i = 0; i < MAC_ADDR_LEN; i++)
4629 {
4630 pAddr[i] = RandomByte(pAd);
4631 }
4632
4633 pAddr[0] = (pAddr[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx
4634}
4635
4636/*! \brief init the management mac frame header
4637 * \param p_hdr mac header
4638 * \param subtype subtype of the frame
4639 * \param p_ds destination address, don't care if it is a broadcast address
4640 * \return none
4641 * \pre the station has the following information in the pAd->StaCfg
4642 * - bssid
4643 * - station address
4644 * \post
4645 * \note this function initializes the following field
4646
4647 IRQL = PASSIVE_LEVEL
4648 IRQL = DISPATCH_LEVEL
4649
4650 */
4651VOID MgtMacHeaderInit(
4652 IN PRTMP_ADAPTER pAd,
4653 IN OUT PHEADER_802_11 pHdr80211,
4654 IN UCHAR SubType,
4655 IN UCHAR ToDs,
4656 IN PUCHAR pDA,
4657 IN PUCHAR pBssid)
4658{
4659 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
4660
4661 pHdr80211->FC.Type = BTYPE_MGMT;
4662 pHdr80211->FC.SubType = SubType;
4663// if (SubType == SUBTYPE_ACK) // sample, no use, it will conflict with ACTION frame sub type
4664// pHdr80211->FC.Type = BTYPE_CNTL;
4665 pHdr80211->FC.ToDs = ToDs;
4666 COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
4667#ifdef CONFIG_STA_SUPPORT
4668 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4669 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
4670#endif // CONFIG_STA_SUPPORT //
4671 COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
4672}
4673
4674// ===========================================================================================
4675// mem_mgmt.c
4676// ===========================================================================================
4677
4678/*!***************************************************************************
4679 * This routine build an outgoing frame, and fill all information specified
4680 * in argument list to the frame body. The actual frame size is the summation
4681 * of all arguments.
4682 * input params:
4683 * Buffer - pointer to a pre-allocated memory segment
4684 * args - a list of <int arg_size, arg> pairs.
4685 * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
4686 * function will FAIL!!!
4687 * return:
4688 * Size of the buffer
4689 * usage:
4690 * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
4691
4692 IRQL = PASSIVE_LEVEL
4693 IRQL = DISPATCH_LEVEL
4694
4695 ****************************************************************************/
4696ULONG MakeOutgoingFrame(
4697 OUT CHAR *Buffer,
4698 OUT ULONG *FrameLen, ...)
4699{
4700 CHAR *p;
4701 int leng;
4702 ULONG TotLeng;
4703 va_list Args;
4704
4705 // calculates the total length
4706 TotLeng = 0;
4707 va_start(Args, FrameLen);
4708 do
4709 {
4710 leng = va_arg(Args, int);
4711 if (leng == END_OF_ARGS)
4712 {
4713 break;
4714 }
4715 p = va_arg(Args, PVOID);
4716 NdisMoveMemory(&Buffer[TotLeng], p, leng);
4717 TotLeng = TotLeng + leng;
4718 } while(TRUE);
4719
4720 va_end(Args); /* clean up */
4721 *FrameLen = TotLeng;
4722 return TotLeng;
4723}
4724
4725// ===========================================================================================
4726// mlme_queue.c
4727// ===========================================================================================
4728
4729/*! \brief Initialize The MLME Queue, used by MLME Functions
4730 * \param *Queue The MLME Queue
4731 * \return Always Return NDIS_STATE_SUCCESS in this implementation
4732 * \pre
4733 * \post
4734 * \note Because this is done only once (at the init stage), no need to be locked
4735
4736 IRQL = PASSIVE_LEVEL
4737
4738 */
4739NDIS_STATUS MlmeQueueInit(
4740 IN MLME_QUEUE *Queue)
4741{
4742 INT i;
4743
4744 NdisAllocateSpinLock(&Queue->Lock);
4745
4746 Queue->Num = 0;
4747 Queue->Head = 0;
4748 Queue->Tail = 0;
4749
4750 for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
4751 {
4752 Queue->Entry[i].Occupied = FALSE;
4753 Queue->Entry[i].MsgLen = 0;
4754 NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
4755 }
4756
4757 return NDIS_STATUS_SUCCESS;
4758}
4759
4760/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
4761 * \param *Queue The MLME Queue
4762 * \param Machine The State Machine Id
4763 * \param MsgType The Message Type
4764 * \param MsgLen The Message length
4765 * \param *Msg The message pointer
4766 * \return TRUE if enqueue is successful, FALSE if the queue is full
4767 * \pre
4768 * \post
4769 * \note The message has to be initialized
4770
4771 IRQL = PASSIVE_LEVEL
4772 IRQL = DISPATCH_LEVEL
4773
4774 */
4775BOOLEAN MlmeEnqueue(
4776 IN PRTMP_ADAPTER pAd,
4777 IN ULONG Machine,
4778 IN ULONG MsgType,
4779 IN ULONG MsgLen,
4780 IN VOID *Msg)
4781{
4782 INT Tail;
4783 MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
4784
4785 // Do nothing if the driver is starting halt state.
4786 // This might happen when timer already been fired before cancel timer with mlmehalt
4787 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
4788 return FALSE;
4789
4790 // First check the size, it MUST not exceed the mlme queue size
4791 if (MsgLen > MGMT_DMA_BUFFER_SIZE)
4792 {
4793 DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
4794 return FALSE;
4795 }
4796
4797 if (MlmeQueueFull(Queue))
4798 {
4799 return FALSE;
4800 }
4801
4802 NdisAcquireSpinLock(&(Queue->Lock));
4803 Tail = Queue->Tail;
4804 Queue->Tail++;
4805 Queue->Num++;
4806 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
4807 {
4808 Queue->Tail = 0;
4809 }
4810
4811 Queue->Entry[Tail].Wcid = RESERVED_WCID;
4812 Queue->Entry[Tail].Occupied = TRUE;
4813 Queue->Entry[Tail].Machine = Machine;
4814 Queue->Entry[Tail].MsgType = MsgType;
4815 Queue->Entry[Tail].MsgLen = MsgLen;
4816
4817 if (Msg != NULL)
4818 {
4819 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4820 }
4821
4822 NdisReleaseSpinLock(&(Queue->Lock));
4823 return TRUE;
4824}
4825
4826/*! \brief This function is used when Recv gets a MLME message
4827 * \param *Queue The MLME Queue
4828 * \param TimeStampHigh The upper 32 bit of timestamp
4829 * \param TimeStampLow The lower 32 bit of timestamp
4830 * \param Rssi The receiving RSSI strength
4831 * \param MsgLen The length of the message
4832 * \param *Msg The message pointer
4833 * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
4834 * \pre
4835 * \post
4836
4837 IRQL = DISPATCH_LEVEL
4838
4839 */
4840BOOLEAN MlmeEnqueueForRecv(
4841 IN PRTMP_ADAPTER pAd,
4842 IN ULONG Wcid,
4843 IN ULONG TimeStampHigh,
4844 IN ULONG TimeStampLow,
4845 IN UCHAR Rssi0,
4846 IN UCHAR Rssi1,
4847 IN UCHAR Rssi2,
4848 IN ULONG MsgLen,
4849 IN VOID *Msg,
4850 IN UCHAR Signal)
4851{
4852 INT Tail, Machine;
4853 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
4854 INT MsgType;
4855 MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
4856
4857#ifdef RALINK_ATE
4858 /* Nothing to do in ATE mode */
4859 if(ATE_ON(pAd))
4860 return FALSE;
4861#endif // RALINK_ATE //
4862
4863 // Do nothing if the driver is starting halt state.
4864 // This might happen when timer already been fired before cancel timer with mlmehalt
4865 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
4866 {
4867 DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
4868 return FALSE;
4869 }
4870
4871 // First check the size, it MUST not exceed the mlme queue size
4872 if (MsgLen > MGMT_DMA_BUFFER_SIZE)
4873 {
4874 DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
4875 return FALSE;
4876 }
4877
4878 if (MlmeQueueFull(Queue))
4879 {
4880 return FALSE;
4881 }
4882
4883#ifdef CONFIG_STA_SUPPORT
4884 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4885 {
4886 if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
4887 {
4888 DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
4889 return FALSE;
4890 }
4891 }
4892#endif // CONFIG_STA_SUPPORT //
4893
4894 // OK, we got all the informations, it is time to put things into queue
4895 NdisAcquireSpinLock(&(Queue->Lock));
4896 Tail = Queue->Tail;
4897 Queue->Tail++;
4898 Queue->Num++;
4899 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
4900 {
4901 Queue->Tail = 0;
4902 }
4903 Queue->Entry[Tail].Occupied = TRUE;
4904 Queue->Entry[Tail].Machine = Machine;
4905 Queue->Entry[Tail].MsgType = MsgType;
4906 Queue->Entry[Tail].MsgLen = MsgLen;
4907 Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
4908 Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
4909 Queue->Entry[Tail].Rssi0 = Rssi0;
4910 Queue->Entry[Tail].Rssi1 = Rssi1;
4911 Queue->Entry[Tail].Rssi2 = Rssi2;
4912 Queue->Entry[Tail].Signal = Signal;
4913 Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
4914
4915 Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
4916
4917 if (Msg != NULL)
4918 {
4919 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4920 }
4921
4922 NdisReleaseSpinLock(&(Queue->Lock));
4923
4924 RT28XX_MLME_HANDLER(pAd);
4925
4926 return TRUE;
4927}
4928
4929
4930/*! \brief Dequeue a message from the MLME Queue
4931 * \param *Queue The MLME Queue
4932 * \param *Elem The message dequeued from MLME Queue
4933 * \return TRUE if the Elem contains something, FALSE otherwise
4934 * \pre
4935 * \post
4936
4937 IRQL = DISPATCH_LEVEL
4938
4939 */
4940BOOLEAN MlmeDequeue(
4941 IN MLME_QUEUE *Queue,
4942 OUT MLME_QUEUE_ELEM **Elem)
4943{
4944 NdisAcquireSpinLock(&(Queue->Lock));
4945 *Elem = &(Queue->Entry[Queue->Head]);
4946 Queue->Num--;
4947 Queue->Head++;
4948 if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
4949 {
4950 Queue->Head = 0;
4951 }
4952 NdisReleaseSpinLock(&(Queue->Lock));
4953 return TRUE;
4954}
4955
4956// IRQL = DISPATCH_LEVEL
4957VOID MlmeRestartStateMachine(
4958 IN PRTMP_ADAPTER pAd)
4959{
4960#ifdef CONFIG_STA_SUPPORT
4961 BOOLEAN Cancelled;
4962#endif // CONFIG_STA_SUPPORT //
4963
4964 DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
4965
4966
4967#ifdef CONFIG_STA_SUPPORT
4968 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4969 {
4970#ifdef QOS_DLS_SUPPORT
4971 UCHAR i;
4972#endif // QOS_DLS_SUPPORT //
4973 // Cancel all timer events
4974 // Be careful to cancel new added timer
4975 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
4976 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
4977 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
4978 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
4979 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
4980 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
4981
4982#ifdef QOS_DLS_SUPPORT
4983 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
4984 {
4985 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
4986 }
4987#endif // QOS_DLS_SUPPORT //
4988 }
4989#endif // CONFIG_STA_SUPPORT //
4990
4991 // Change back to original channel in case of doing scan
4992 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
4993 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
4994
4995 // Resume MSDU which is turned off durning scan
4996 RTMPResumeMsduTransmission(pAd);
4997
4998#ifdef CONFIG_STA_SUPPORT
4999 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
5000 {
5001 // Set all state machines back IDLE
5002 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
5003 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
5004 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
5005 pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
5006 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
5007 pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
5008#ifdef QOS_DLS_SUPPORT
5009 pAd->Mlme.DlsMachine.CurrState = DLS_IDLE;
5010#endif // QOS_DLS_SUPPORT //
5011 }
5012#endif // CONFIG_STA_SUPPORT //
5013
5014}
5015
5016/*! \brief test if the MLME Queue is empty
5017 * \param *Queue The MLME Queue
5018 * \return TRUE if the Queue is empty, FALSE otherwise
5019 * \pre
5020 * \post
5021
5022 IRQL = DISPATCH_LEVEL
5023
5024 */
5025BOOLEAN MlmeQueueEmpty(
5026 IN MLME_QUEUE *Queue)
5027{
5028 BOOLEAN Ans;
5029
5030 NdisAcquireSpinLock(&(Queue->Lock));
5031 Ans = (Queue->Num == 0);
5032 NdisReleaseSpinLock(&(Queue->Lock));
5033
5034 return Ans;
5035}
5036
5037/*! \brief test if the MLME Queue is full
5038 * \param *Queue The MLME Queue
5039 * \return TRUE if the Queue is empty, FALSE otherwise
5040 * \pre
5041 * \post
5042
5043 IRQL = PASSIVE_LEVEL
5044 IRQL = DISPATCH_LEVEL
5045
5046 */
5047BOOLEAN MlmeQueueFull(
5048 IN MLME_QUEUE *Queue)
5049{
5050 BOOLEAN Ans;
5051
5052 NdisAcquireSpinLock(&(Queue->Lock));
5053 Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
5054 NdisReleaseSpinLock(&(Queue->Lock));
5055
5056 return Ans;
5057}
5058
5059/*! \brief The destructor of MLME Queue
5060 * \param
5061 * \return
5062 * \pre
5063 * \post
5064 * \note Clear Mlme Queue, Set Queue->Num to Zero.
5065
5066 IRQL = PASSIVE_LEVEL
5067
5068 */
5069VOID MlmeQueueDestroy(
5070 IN MLME_QUEUE *pQueue)
5071{
5072 NdisAcquireSpinLock(&(pQueue->Lock));
5073 pQueue->Num = 0;
5074 pQueue->Head = 0;
5075 pQueue->Tail = 0;
5076 NdisReleaseSpinLock(&(pQueue->Lock));
5077 NdisFreeSpinLock(&(pQueue->Lock));
5078}
5079
5080/*! \brief To substitute the message type if the message is coming from external
5081 * \param pFrame The frame received
5082 * \param *Machine The state machine
5083 * \param *MsgType the message type for the state machine
5084 * \return TRUE if the substitution is successful, FALSE otherwise
5085 * \pre
5086 * \post
5087
5088 IRQL = DISPATCH_LEVEL
5089
5090 */
5091#ifdef CONFIG_STA_SUPPORT
5092BOOLEAN MsgTypeSubst(
5093 IN PRTMP_ADAPTER pAd,
5094 IN PFRAME_802_11 pFrame,
5095 OUT INT *Machine,
5096 OUT INT *MsgType)
5097{
5098 USHORT Seq;
5099 UCHAR EAPType;
5100 PUCHAR pData;
5101
5102 // Pointer to start of data frames including SNAP header
5103 pData = (PUCHAR) pFrame + LENGTH_802_11;
5104
5105 // The only data type will pass to this function is EAPOL frame
5106 if (pFrame->Hdr.FC.Type == BTYPE_DATA)
5107 {
5108 if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H))
5109 {
5110 // Cisco Aironet SNAP header
5111 *Machine = AIRONET_STATE_MACHINE;
5112 *MsgType = MT2_AIRONET_MSG;
5113 return (TRUE);
5114 }
5115#ifdef LEAP_SUPPORT
5116 if ( pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP ) //LEAP
5117 {
5118 // LEAP frames
5119 *Machine = LEAP_STATE_MACHINE;
5120 EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
5121 return (LeapMsgTypeSubst(EAPType, MsgType));
5122 }
5123 else
5124#endif // LEAP_SUPPORT //
5125 {
5126 *Machine = WPA_PSK_STATE_MACHINE;
5127 EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
5128 return(WpaMsgTypeSubst(EAPType, MsgType));
5129 }
5130 }
5131
5132 switch (pFrame->Hdr.FC.SubType)
5133 {
5134 case SUBTYPE_ASSOC_REQ:
5135 *Machine = ASSOC_STATE_MACHINE;
5136 *MsgType = MT2_PEER_ASSOC_REQ;
5137 break;
5138 case SUBTYPE_ASSOC_RSP:
5139 *Machine = ASSOC_STATE_MACHINE;
5140 *MsgType = MT2_PEER_ASSOC_RSP;
5141 break;
5142 case SUBTYPE_REASSOC_REQ:
5143 *Machine = ASSOC_STATE_MACHINE;
5144 *MsgType = MT2_PEER_REASSOC_REQ;
5145 break;
5146 case SUBTYPE_REASSOC_RSP:
5147 *Machine = ASSOC_STATE_MACHINE;
5148 *MsgType = MT2_PEER_REASSOC_RSP;
5149 break;
5150 case SUBTYPE_PROBE_REQ:
5151 *Machine = SYNC_STATE_MACHINE;
5152 *MsgType = MT2_PEER_PROBE_REQ;
5153 break;
5154 case SUBTYPE_PROBE_RSP:
5155 *Machine = SYNC_STATE_MACHINE;
5156 *MsgType = MT2_PEER_PROBE_RSP;
5157 break;
5158 case SUBTYPE_BEACON:
5159 *Machine = SYNC_STATE_MACHINE;
5160 *MsgType = MT2_PEER_BEACON;
5161 break;
5162 case SUBTYPE_ATIM:
5163 *Machine = SYNC_STATE_MACHINE;
5164 *MsgType = MT2_PEER_ATIM;
5165 break;
5166 case SUBTYPE_DISASSOC:
5167 *Machine = ASSOC_STATE_MACHINE;
5168 *MsgType = MT2_PEER_DISASSOC_REQ;
5169 break;
5170 case SUBTYPE_AUTH:
5171 // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
5172 NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
5173 if (Seq == 1 || Seq == 3)
5174 {
5175 *Machine = AUTH_RSP_STATE_MACHINE;
5176 *MsgType = MT2_PEER_AUTH_ODD;
5177 }
5178 else if (Seq == 2 || Seq == 4)
5179 {
5180 *Machine = AUTH_STATE_MACHINE;
5181 *MsgType = MT2_PEER_AUTH_EVEN;
5182 }
5183 else
5184 {
5185 return FALSE;
5186 }
5187 break;
5188 case SUBTYPE_DEAUTH:
5189 *Machine = AUTH_RSP_STATE_MACHINE;
5190 *MsgType = MT2_PEER_DEAUTH;
5191 break;
5192 case SUBTYPE_ACTION:
5193 *Machine = ACTION_STATE_MACHINE;
5194 // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
5195 if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
5196 {
5197 *MsgType = MT2_ACT_INVALID;
5198 }
5199 else
5200 {
5201 *MsgType = (pFrame->Octet[0]&0x7F);
5202 }
5203 break;
5204 default:
5205 return FALSE;
5206 break;
5207 }
5208
5209 return TRUE;
5210}
5211#endif // CONFIG_STA_SUPPORT //
5212
5213// ===========================================================================================
5214// state_machine.c
5215// ===========================================================================================
5216
5217/*! \brief Initialize the state machine.
5218 * \param *S pointer to the state machine
5219 * \param Trans State machine transition function
5220 * \param StNr number of states
5221 * \param MsgNr number of messages
5222 * \param DefFunc default function, when there is invalid state/message combination
5223 * \param InitState initial state of the state machine
5224 * \param Base StateMachine base, internal use only
5225 * \pre p_sm should be a legal pointer
5226 * \post
5227
5228 IRQL = PASSIVE_LEVEL
5229
5230 */
5231VOID StateMachineInit(
5232 IN STATE_MACHINE *S,
5233 IN STATE_MACHINE_FUNC Trans[],
5234 IN ULONG StNr,
5235 IN ULONG MsgNr,
5236 IN STATE_MACHINE_FUNC DefFunc,
5237 IN ULONG InitState,
5238 IN ULONG Base)
5239{
5240 ULONG i, j;
5241
5242 // set number of states and messages
5243 S->NrState = StNr;
5244 S->NrMsg = MsgNr;
5245 S->Base = Base;
5246
5247 S->TransFunc = Trans;
5248
5249 // init all state transition to default function
5250 for (i = 0; i < StNr; i++)
5251 {
5252 for (j = 0; j < MsgNr; j++)
5253 {
5254 S->TransFunc[i * MsgNr + j] = DefFunc;
5255 }
5256 }
5257
5258 // set the starting state
5259 S->CurrState = InitState;
5260}
5261
5262/*! \brief This function fills in the function pointer into the cell in the state machine
5263 * \param *S pointer to the state machine
5264 * \param St state
5265 * \param Msg incoming message
5266 * \param f the function to be executed when (state, message) combination occurs at the state machine
5267 * \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
5268 * \post
5269
5270 IRQL = PASSIVE_LEVEL
5271
5272 */
5273VOID StateMachineSetAction(
5274 IN STATE_MACHINE *S,
5275 IN ULONG St,
5276 IN ULONG Msg,
5277 IN STATE_MACHINE_FUNC Func)
5278{
5279 ULONG MsgIdx;
5280
5281 MsgIdx = Msg - S->Base;
5282
5283 if (St < S->NrState && MsgIdx < S->NrMsg)
5284 {
5285 // boundary checking before setting the action
5286 S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
5287 }
5288}
5289
5290/*! \brief This function does the state transition
5291 * \param *Adapter the NIC adapter pointer
5292 * \param *S the state machine
5293 * \param *Elem the message to be executed
5294 * \return None
5295
5296 IRQL = DISPATCH_LEVEL
5297
5298 */
5299VOID StateMachinePerformAction(
5300 IN PRTMP_ADAPTER pAd,
5301 IN STATE_MACHINE *S,
5302 IN MLME_QUEUE_ELEM *Elem)
5303{
5304 (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
5305}
5306
5307/*
5308 ==========================================================================
5309 Description:
5310 The drop function, when machine executes this, the message is simply
5311 ignored. This function does nothing, the message is freed in
5312 StateMachinePerformAction()
5313 ==========================================================================
5314 */
5315VOID Drop(
5316 IN PRTMP_ADAPTER pAd,
5317 IN MLME_QUEUE_ELEM *Elem)
5318{
5319}
5320
5321// ===========================================================================================
5322// lfsr.c
5323// ===========================================================================================
5324
5325/*
5326 ==========================================================================
5327 Description:
5328
5329 IRQL = PASSIVE_LEVEL
5330
5331 ==========================================================================
5332 */
5333VOID LfsrInit(
5334 IN PRTMP_ADAPTER pAd,
5335 IN ULONG Seed)
5336{
5337 if (Seed == 0)
5338 pAd->Mlme.ShiftReg = 1;
5339 else
5340 pAd->Mlme.ShiftReg = Seed;
5341}
5342
5343/*
5344 ==========================================================================
5345 Description:
5346 ==========================================================================
5347 */
5348UCHAR RandomByte(
5349 IN PRTMP_ADAPTER pAd)
5350{
5351 ULONG i;
5352 UCHAR R, Result;
5353
5354 R = 0;
5355
5356 if (pAd->Mlme.ShiftReg == 0)
5357 NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
5358
5359 for (i = 0; i < 8; i++)
5360 {
5361 if (pAd->Mlme.ShiftReg & 0x00000001)
5362 {
5363 pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
5364 Result = 1;
5365 }
5366 else
5367 {
5368 pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
5369 Result = 0;
5370 }
5371 R = (R << 1) | Result;
5372 }
5373
5374 return R;
5375}
5376
5377VOID AsicUpdateAutoFallBackTable(
5378 IN PRTMP_ADAPTER pAd,
5379 IN PUCHAR pRateTable)
5380{
5381 UCHAR i;
5382 HT_FBK_CFG0_STRUC HtCfg0;
5383 HT_FBK_CFG1_STRUC HtCfg1;
5384 LG_FBK_CFG0_STRUC LgCfg0;
5385 LG_FBK_CFG1_STRUC LgCfg1;
5386 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate;
5387
5388 // set to initial value
5389 HtCfg0.word = 0x65432100;
5390 HtCfg1.word = 0xedcba988;
5391 LgCfg0.word = 0xedcba988;
5392 LgCfg1.word = 0x00002100;
5393
5394 pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
5395 for (i = 1; i < *((PUCHAR) pRateTable); i++)
5396 {
5397 pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
5398 switch (pCurrTxRate->Mode)
5399 {
5400 case 0: //CCK
5401 break;
5402 case 1: //OFDM
5403 {
5404 switch(pCurrTxRate->CurrMCS)
5405 {
5406 case 0:
5407 LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5408 break;
5409 case 1:
5410 LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5411 break;
5412 case 2:
5413 LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5414 break;
5415 case 3:
5416 LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5417 break;
5418 case 4:
5419 LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5420 break;
5421 case 5:
5422 LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5423 break;
5424 case 6:
5425 LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5426 break;
5427 case 7:
5428 LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5429 break;
5430 }
5431 }
5432 break;
5433#ifdef DOT11_N_SUPPORT
5434 case 2: //HT-MIX
5435 case 3: //HT-GF
5436 {
5437 if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
5438 {
5439 switch(pCurrTxRate->CurrMCS)
5440 {
5441 case 0:
5442 HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
5443 break;
5444 case 1:
5445 HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
5446 break;
5447 case 2:
5448 HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
5449 break;
5450 case 3:
5451 HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
5452 break;
5453 case 4:
5454 HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
5455 break;
5456 case 5:
5457 HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
5458 break;
5459 case 6:
5460 HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
5461 break;
5462 case 7:
5463 HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
5464 break;
5465 case 8:
5466 HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
5467 break;
5468 case 9:
5469 HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
5470 break;
5471 case 10:
5472 HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
5473 break;
5474 case 11:
5475 HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
5476 break;
5477 case 12:
5478 HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
5479 break;
5480 case 13:
5481 HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
5482 break;
5483 case 14:
5484 HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
5485 break;
5486 case 15:
5487 HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
5488 break;
5489 default:
5490 DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
5491 }
5492 }
5493 }
5494 break;
5495#endif // DOT11_N_SUPPORT //
5496 }
5497
5498 pNextTxRate = pCurrTxRate;
5499 }
5500
5501 RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
5502 RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
5503 RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
5504 RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
5505}
5506
5507/*
5508 ========================================================================
5509
5510 Routine Description:
5511 Set MAC register value according operation mode.
5512 OperationMode AND bNonGFExist are for MM and GF Proteciton.
5513 If MM or GF mask is not set, those passing argument doesn't not take effect.
5514
5515 Operation mode meaning:
5516 = 0 : Pure HT, no preotection.
5517 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
5518 = 0x10: No Transmission in 40M is protected.
5519 = 0x11: Transmission in both 40M and 20M shall be protected
5520 if (bNonGFExist)
5521 we should choose not to use GF. But still set correct ASIC registers.
5522 ========================================================================
5523*/
5524VOID AsicUpdateProtect(
5525 IN PRTMP_ADAPTER pAd,
5526 IN USHORT OperationMode,
5527 IN UCHAR SetMask,
5528 IN BOOLEAN bDisableBGProtect,
5529 IN BOOLEAN bNonGFExist)
5530{
5531 PROT_CFG_STRUC ProtCfg, ProtCfg4;
5532 UINT32 Protect[6];
5533 USHORT offset;
5534 UCHAR i;
5535 UINT32 MacReg = 0;
5536
5537#ifdef RALINK_ATE
5538 if (ATE_ON(pAd))
5539 return;
5540#endif // RALINK_ATE //
5541
5542#ifdef DOT11_N_SUPPORT
5543 if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
5544 {
5545 return;
5546 }
5547
5548 if (pAd->BATable.numAsOriginator)
5549 {
5550 //
5551 // enable the RTS/CTS to avoid channel collision
5552 //
5553 SetMask = ALLN_SETPROTECT;
5554 OperationMode = 8;
5555 }
5556#endif // DOT11_N_SUPPORT //
5557
5558 // Config ASIC RTS threshold register
5559 RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
5560 MacReg &= 0xFF0000FF;
5561#if 0
5562 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
5563#else
5564 // If the user want disable RtsThreshold and enbale Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
5565 if ((
5566#ifdef DOT11_N_SUPPORT
5567 (pAd->CommonCfg.BACapability.field.AmsduEnable) ||
5568#endif // DOT11_N_SUPPORT //
5569 (pAd->CommonCfg.bAggregationCapable == TRUE))
5570 && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
5571 {
5572 MacReg |= (0x1000 << 8);
5573 }
5574 else
5575 {
5576 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
5577 }
5578#endif
5579
5580 RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
5581
5582 // Initial common protection settings
5583 RTMPZeroMemory(Protect, sizeof(Protect));
5584 ProtCfg4.word = 0;
5585 ProtCfg.word = 0;
5586 ProtCfg.field.TxopAllowGF40 = 1;
5587 ProtCfg.field.TxopAllowGF20 = 1;
5588 ProtCfg.field.TxopAllowMM40 = 1;
5589 ProtCfg.field.TxopAllowMM20 = 1;
5590 ProtCfg.field.TxopAllowOfdm = 1;
5591 ProtCfg.field.TxopAllowCck = 1;
5592 ProtCfg.field.RTSThEn = 1;
5593 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5594
5595 // update PHY mode and rate
5596 if (pAd->CommonCfg.Channel > 14)
5597 ProtCfg.field.ProtectRate = 0x4000;
5598 ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
5599
5600 // Handle legacy(B/G) protection
5601 if (bDisableBGProtect)
5602 {
5603 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5604 ProtCfg.field.ProtectCtrl = 0;
5605 Protect[0] = ProtCfg.word;
5606 Protect[1] = ProtCfg.word;
5607 }
5608 else
5609 {
5610 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5611 ProtCfg.field.ProtectCtrl = 0; // CCK do not need to be protected
5612 Protect[0] = ProtCfg.word;
5613 ProtCfg.field.ProtectCtrl = ASIC_CTS; // OFDM needs using CCK to protect
5614 Protect[1] = ProtCfg.word;
5615 }
5616
5617#ifdef DOT11_N_SUPPORT
5618 // Decide HT frame protection.
5619 if ((SetMask & ALLN_SETPROTECT) != 0)
5620 {
5621 switch(OperationMode)
5622 {
5623 case 0x0:
5624 // NO PROTECT
5625 // 1.All STAs in the BSS are 20/40 MHz HT
5626 // 2. in ai 20/40MHz BSS
5627 // 3. all STAs are 20MHz in a 20MHz BSS
5628 // Pure HT. no protection.
5629
5630 // MM20_PROT_CFG
5631 // Reserved (31:27)
5632 // PROT_TXOP(25:20) -- 010111
5633 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5634 // PROT_CTRL(17:16) -- 00 (None)
5635 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5636 Protect[2] = 0x01744004;
5637
5638 // MM40_PROT_CFG
5639 // Reserved (31:27)
5640 // PROT_TXOP(25:20) -- 111111
5641 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5642 // PROT_CTRL(17:16) -- 00 (None)
5643 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5644 Protect[3] = 0x03f44084;
5645
5646 // CF20_PROT_CFG
5647 // Reserved (31:27)
5648 // PROT_TXOP(25:20) -- 010111
5649 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5650 // PROT_CTRL(17:16) -- 00 (None)
5651 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5652 Protect[4] = 0x01744004;
5653
5654 // CF40_PROT_CFG
5655 // Reserved (31:27)
5656 // PROT_TXOP(25:20) -- 111111
5657 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5658 // PROT_CTRL(17:16) -- 00 (None)
5659 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5660 Protect[5] = 0x03f44084;
5661
5662 if (bNonGFExist)
5663 {
5664 // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
5665 // PROT_CTRL(17:16) -- 01 (RTS/CTS)
5666 Protect[4] = 0x01754004;
5667 Protect[5] = 0x03f54084;
5668 }
5669 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
5670 break;
5671
5672 case 1:
5673 // This is "HT non-member protection mode."
5674 // If there may be non-HT STAs my BSS
5675 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5676 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
5677 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
5678 {
5679 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5680 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
5681 }
5682 //Assign Protection method for 20&40 MHz packets
5683 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5684 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5685 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5686 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5687 Protect[2] = ProtCfg.word;
5688 Protect[3] = ProtCfg4.word;
5689 Protect[4] = ProtCfg.word;
5690 Protect[5] = ProtCfg4.word;
5691 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5692 break;
5693
5694 case 2:
5695 // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
5696 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5697 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
5698
5699 //Assign Protection method for 40MHz packets
5700 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5701 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5702 Protect[2] = ProtCfg.word;
5703 Protect[3] = ProtCfg4.word;
5704 if (bNonGFExist)
5705 {
5706 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5707 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5708 }
5709 Protect[4] = ProtCfg.word;
5710 Protect[5] = ProtCfg4.word;
5711
5712 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
5713 break;
5714
5715 case 3:
5716 // HT mixed mode. PROTECT ALL!
5717 // Assign Rate
5718 ProtCfg.word = 0x01744004; //duplicaet legacy 24M. BW set 1.
5719 ProtCfg4.word = 0x03f44084;
5720 // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
5721 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
5722 {
5723 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5724 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
5725 }
5726 //Assign Protection method for 20&40 MHz packets
5727 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5728 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5729 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5730 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5731 Protect[2] = ProtCfg.word;
5732 Protect[3] = ProtCfg4.word;
5733 Protect[4] = ProtCfg.word;
5734 Protect[5] = ProtCfg4.word;
5735 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5736 break;
5737
5738 case 8:
5739 // Special on for Atheros problem n chip.
5740 Protect[2] = 0x01754004;
5741 Protect[3] = 0x03f54084;
5742 Protect[4] = 0x01754004;
5743 Protect[5] = 0x03f54084;
5744 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5745 break;
5746 }
5747 }
5748#endif // DOT11_N_SUPPORT //
5749
5750 offset = CCK_PROT_CFG;
5751 for (i = 0;i < 6;i++)
5752 {
5753 if ((SetMask & (1<< i)))
5754 {
5755 RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
5756 }
5757 }
5758}
5759
5760/*
5761 ==========================================================================
5762 Description:
5763
5764 IRQL = PASSIVE_LEVEL
5765 IRQL = DISPATCH_LEVEL
5766
5767 ==========================================================================
5768 */
5769VOID AsicSwitchChannel(
5770 IN PRTMP_ADAPTER pAd,
5771 IN UCHAR Channel,
5772 IN BOOLEAN bScan)
5773{
5774 ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
5775 CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
5776 UCHAR index;
5777 UINT32 Value = 0; //BbpReg, Value;
5778 RTMP_RF_REGS *RFRegTable;
5779
5780 // Search Tx power value
5781 for (index = 0; index < pAd->ChannelListNum; index++)
5782 {
5783 if (Channel == pAd->ChannelList[index].Channel)
5784 {
5785 TxPwer = pAd->ChannelList[index].Power;
5786 TxPwer2 = pAd->ChannelList[index].Power2;
5787 break;
5788 }
5789 }
5790
5791 if (index == MAX_NUM_OF_CHANNELS)
5792 {
5793 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Cant find the Channel#%d \n", Channel));
5794 }
5795
5796#ifdef RT2870
5797 // The RF programming sequence is difference between 3xxx and 2xxx
5798 if (IS_RT3070(pAd) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)))
5799 {
5800 /* modify by WY for Read RF Reg. error */
5801 UCHAR RFValue;
5802
5803 for (index = 0; index < NUM_OF_3020_CHNL; index++)
5804 {
5805 if (Channel == FreqItems3020[index].Channel)
5806 {
5807 // Programming channel parameters
5808 RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
5809 RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
5810
5811 RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RFValue);
5812 RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
5813 RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RFValue);
5814
5815 // Set Tx Power
5816 RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
5817 RFValue = (RFValue & 0xE0) | TxPwer;
5818 RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
5819
5820 // Set RF offset
5821 RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
5822 RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
5823 RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
5824
5825 // Set BW
5826 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
5827 {
5828 RFValue = pAd->Mlme.CaliBW40RfR24;
5829 //DISABLE_11N_CHECK(pAd);
5830 }
5831 else
5832 {
5833 RFValue = pAd->Mlme.CaliBW20RfR24;
5834 }
5835 RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR)RFValue);
5836
5837 // Enable RF tuning
5838 RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)&RFValue);
5839 RFValue = RFValue | 0x1;
5840 RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue);
5841
5842 // latch channel for future usage.
5843 pAd->LatchRfRegs.Channel = Channel;
5844
5845 break;
5846 }
5847 }
5848
5849 DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
5850 Channel,
5851 pAd->RfIcType,
5852 TxPwer,
5853 TxPwer2,
5854 pAd->Antenna.field.TxPath,
5855 FreqItems3020[index].N,
5856 FreqItems3020[index].K,
5857 FreqItems3020[index].R));
5858 }
5859 else
5860#endif // RT2870 //
5861 {
5862 RFRegTable = RF2850RegTable;
5863
5864 switch (pAd->RfIcType)
5865 {
5866 case RFIC_2820:
5867 case RFIC_2850:
5868 case RFIC_2720:
5869 case RFIC_2750:
5870
5871 for (index = 0; index < NUM_OF_2850_CHNL; index++)
5872 {
5873 if (Channel == RFRegTable[index].Channel)
5874 {
5875 R2 = RFRegTable[index].R2;
5876 if (pAd->Antenna.field.TxPath == 1)
5877 {
5878 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
5879 }
5880
5881 if (pAd->Antenna.field.RxPath == 2)
5882 {
5883 R2 |= 0x40; // write 1 to off Rxpath.
5884 }
5885 else if (pAd->Antenna.field.RxPath == 1)
5886 {
5887 R2 |= 0x20040; // write 1 to off RxPath
5888 }
5889
5890 if (Channel > 14)
5891 {
5892 // initialize R3, R4
5893 R3 = (RFRegTable[index].R3 & 0xffffc1ff);
5894 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
5895
5896 // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
5897 // R3
5898 if ((TxPwer >= -7) && (TxPwer < 0))
5899 {
5900 TxPwer = (7+TxPwer);
5901 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
5902 R3 |= (TxPwer << 10);
5903 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
5904 }
5905 else
5906 {
5907 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
5908 R3 |= (TxPwer << 10) | (1 << 9);
5909 }
5910
5911 // R4
5912 if ((TxPwer2 >= -7) && (TxPwer2 < 0))
5913 {
5914 TxPwer2 = (7+TxPwer2);
5915 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
5916 R4 |= (TxPwer2 << 7);
5917 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
5918 }
5919 else
5920 {
5921 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
5922 R4 |= (TxPwer2 << 7) | (1 << 6);
5923 }
5924 }
5925 else
5926 {
5927 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
5928 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
5929 }
5930
5931 // Based on BBP current mode before changing RF channel.
5932 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
5933 {
5934 R4 |=0x200000;
5935 }
5936
5937 // Update variables
5938 pAd->LatchRfRegs.Channel = Channel;
5939 pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
5940 pAd->LatchRfRegs.R2 = R2;
5941 pAd->LatchRfRegs.R3 = R3;
5942 pAd->LatchRfRegs.R4 = R4;
5943
5944 // Set RF value 1's set R3[bit2] = [0]
5945 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
5946 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
5947 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
5948 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
5949
5950 RTMPusecDelay(200);
5951
5952 // Set RF value 2's set R3[bit2] = [1]
5953 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
5954 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
5955 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
5956 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
5957
5958 RTMPusecDelay(200);
5959
5960 // Set RF value 3's set R3[bit2] = [0]
5961 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
5962 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
5963 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
5964 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
5965
5966 break;
5967 }
5968 }
5969 break;
5970
5971 default:
5972 break;
5973 }
5974 }
5975
5976 // Change BBP setting during siwtch from a->g, g->a
5977 if (Channel <= 14)
5978 {
5979 ULONG TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
5980
5981 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
5982 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
5983 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
5984 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.
5985 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
5986
5987 // Rx High power VGA offset for LNA select
5988 if (pAd->NicConfig2.field.ExternalLNAForG)
5989 {
5990 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
5991 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
5992 }
5993 else
5994 {
5995 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
5996 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
5997 }
5998
5999 // 5G band selection PIN, bit1 and bit2 are complement
6000 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
6001 Value &= (~0x6);
6002 Value |= (0x04);
6003 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
6004
6005 // Turn off unused PA or LNA when only 1T or 1R
6006 if (pAd->Antenna.field.TxPath == 1)
6007 {
6008 TxPinCfg &= 0xFFFFFFF3;
6009 }
6010 if (pAd->Antenna.field.RxPath == 1)
6011 {
6012 TxPinCfg &= 0xFFFFF3FF;
6013 }
6014
6015 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
6016 }
6017 else
6018 {
6019 ULONG TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
6020
6021 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
6022 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
6023 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
6024 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.
6025 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
6026
6027 // Rx High power VGA offset for LNA select
6028 if (pAd->NicConfig2.field.ExternalLNAForA)
6029 {
6030 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
6031 }
6032 else
6033 {
6034 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
6035 }
6036
6037 // 5G band selection PIN, bit1 and bit2 are complement
6038 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
6039 Value &= (~0x6);
6040 Value |= (0x02);
6041 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
6042
6043 // Turn off unused PA or LNA when only 1T or 1R
6044 if (pAd->Antenna.field.TxPath == 1)
6045 {
6046 TxPinCfg &= 0xFFFFFFF3;
6047 }
6048 if (pAd->Antenna.field.RxPath == 1)
6049 {
6050 TxPinCfg &= 0xFFFFF3FF;
6051 }
6052
6053 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
6054 }
6055
6056 // R66 should be set according to Channel and use 20MHz when scanning
6057 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
6058 if (bScan)
6059 RTMPSetAGCInitValue(pAd, BW_20);
6060 else
6061 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
6062
6063 //
6064 // On 11A, We should delay and wait RF/BBP to be stable
6065 // and the appropriate time should be 1000 micro seconds
6066 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
6067 //
6068 RTMPusecDelay(1000);
6069
6070 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",
6071 Channel,
6072 pAd->RfIcType,
6073 (R3 & 0x00003e00) >> 9,
6074 (R4 & 0x000007c0) >> 6,
6075 pAd->Antenna.field.TxPath,
6076 pAd->LatchRfRegs.R1,
6077 pAd->LatchRfRegs.R2,
6078 pAd->LatchRfRegs.R3,
6079 pAd->LatchRfRegs.R4));
6080}
6081
6082/*
6083 ==========================================================================
6084 Description:
6085 This function is required for 2421 only, and should not be used during
6086 site survey. It's only required after NIC decided to stay at a channel
6087 for a longer period.
6088 When this function is called, it's always after AsicSwitchChannel().
6089
6090 IRQL = PASSIVE_LEVEL
6091 IRQL = DISPATCH_LEVEL
6092
6093 ==========================================================================
6094 */
6095VOID AsicLockChannel(
6096 IN PRTMP_ADAPTER pAd,
6097 IN UCHAR Channel)
6098{
6099}
6100
6101/*
6102 ==========================================================================
6103 Description:
6104
6105 IRQL = PASSIVE_LEVEL
6106 IRQL = DISPATCH_LEVEL
6107
6108 ==========================================================================
6109 */
6110VOID AsicAntennaSelect(
6111 IN PRTMP_ADAPTER pAd,
6112 IN UCHAR Channel)
6113{
6114}
6115
6116/*
6117 ========================================================================
6118
6119 Routine Description:
6120 Antenna miscellaneous setting.
6121
6122 Arguments:
6123 pAd Pointer to our adapter
6124 BandState Indicate current Band State.
6125
6126 Return Value:
6127 None
6128
6129 IRQL <= DISPATCH_LEVEL
6130
6131 Note:
6132 1.) Frame End type control
6133 only valid for G only (RF_2527 & RF_2529)
6134 0: means DPDT, set BBP R4 bit 5 to 1
6135 1: means SPDT, set BBP R4 bit 5 to 0
6136
6137
6138 ========================================================================
6139*/
6140VOID AsicAntennaSetting(
6141 IN PRTMP_ADAPTER pAd,
6142 IN ABGBAND_STATE BandState)
6143{
6144}
6145
6146VOID AsicRfTuningExec(
6147 IN PVOID SystemSpecific1,
6148 IN PVOID FunctionContext,
6149 IN PVOID SystemSpecific2,
6150 IN PVOID SystemSpecific3)
6151{
6152}
6153
6154/*
6155 ==========================================================================
6156 Description:
6157 Gives CCK TX rate 2 more dB TX power.
6158 This routine works only in LINK UP in INFRASTRUCTURE mode.
6159
6160 calculate desired Tx power in RF R3.Tx0~5, should consider -
6161 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
6162 1. TxPowerPercentage
6163 2. auto calibration based on TSSI feedback
6164 3. extra 2 db for CCK
6165 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
6166
6167 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
6168 it should be called AFTER MlmeDynamicTxRatSwitching()
6169 ==========================================================================
6170 */
6171VOID AsicAdjustTxPower(
6172 IN PRTMP_ADAPTER pAd)
6173{
6174 INT i, j;
6175 CHAR DeltaPwr = 0;
6176 BOOLEAN bAutoTxAgc = FALSE;
6177 UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
6178 UCHAR BbpR1 = 0, BbpR49 = 0, idx;
6179 PCHAR pTxAgcCompensate;
6180 ULONG TxPwr[5];
6181 CHAR Value;
6182
6183 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
6184 {
6185 if (pAd->CommonCfg.CentralChannel > 14)
6186 {
6187 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
6188 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
6189 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
6190 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
6191 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
6192 }
6193 else
6194 {
6195 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
6196 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
6197 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
6198 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
6199 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
6200 }
6201 }
6202 else
6203 {
6204 if (pAd->CommonCfg.Channel > 14)
6205 {
6206 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
6207 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
6208 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
6209 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
6210 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
6211 }
6212 else
6213 {
6214 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
6215 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
6216 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
6217 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
6218 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
6219 }
6220 }
6221
6222 // TX power compensation for temperature variation based on TSSI. try every 4 second
6223 if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
6224 {
6225 if (pAd->CommonCfg.Channel <= 14)
6226 {
6227 /* bg channel */
6228 bAutoTxAgc = pAd->bAutoTxAgcG;
6229 TssiRef = pAd->TssiRefG;
6230 pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
6231 pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
6232 TxAgcStep = pAd->TxAgcStepG;
6233 pTxAgcCompensate = &pAd->TxAgcCompensateG;
6234 }
6235 else
6236 {
6237 /* a channel */
6238 bAutoTxAgc = pAd->bAutoTxAgcA;
6239 TssiRef = pAd->TssiRefA;
6240 pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
6241 pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
6242 TxAgcStep = pAd->TxAgcStepA;
6243 pTxAgcCompensate = &pAd->TxAgcCompensateA;
6244 }
6245
6246 if (bAutoTxAgc)
6247 {
6248 /* BbpR1 is unsigned char */
6249 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
6250
6251 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
6252 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
6253 /* step value is defined in pAd->TxAgcStepG for tx power value */
6254
6255 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
6256 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
6257 above value are examined in mass factory production */
6258 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
6259
6260 /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
6261 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
6262 /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
6263
6264 if (BbpR49 > pTssiMinusBoundary[1])
6265 {
6266 // Reading is larger than the reference value
6267 // check for how large we need to decrease the Tx power
6268 for (idx = 1; idx < 5; idx++)
6269 {
6270 if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
6271 break;
6272 }
6273 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
6274// if (R3 > (ULONG) (TxAgcStep * (idx-1)))
6275 *pTxAgcCompensate = -(TxAgcStep * (idx-1));
6276// else
6277// *pTxAgcCompensate = -((UCHAR)R3);
6278
6279 DeltaPwr += (*pTxAgcCompensate);
6280 DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
6281 BbpR49, TssiRef, TxAgcStep, idx-1));
6282 }
6283 else if (BbpR49 < pTssiPlusBoundary[1])
6284 {
6285 // Reading is smaller than the reference value
6286 // check for how large we need to increase the Tx power
6287 for (idx = 1; idx < 5; idx++)
6288 {
6289 if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
6290 break;
6291 }
6292 // The index is the step we should increase, idx = 0 means there is nothing to compensate
6293 *pTxAgcCompensate = TxAgcStep * (idx-1);
6294 DeltaPwr += (*pTxAgcCompensate);
6295 DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6296 BbpR49, TssiRef, TxAgcStep, idx-1));
6297 }
6298 else
6299 {
6300 *pTxAgcCompensate = 0;
6301 DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6302 BbpR49, TssiRef, TxAgcStep, 0));
6303 }
6304 }
6305 }
6306 else
6307 {
6308 if (pAd->CommonCfg.Channel <= 14)
6309 {
6310 bAutoTxAgc = pAd->bAutoTxAgcG;
6311 pTxAgcCompensate = &pAd->TxAgcCompensateG;
6312 }
6313 else
6314 {
6315 bAutoTxAgc = pAd->bAutoTxAgcA;
6316 pTxAgcCompensate = &pAd->TxAgcCompensateA;
6317 }
6318
6319 if (bAutoTxAgc)
6320 DeltaPwr += (*pTxAgcCompensate);
6321 }
6322
6323 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
6324 BbpR1 &= 0xFC;
6325
6326#ifdef SINGLE_SKU
6327 // Handle regulatory max tx power constrain
6328 do
6329 {
6330 UCHAR TxPwrInEEPROM = 0xFF, CountryTxPwr = 0xFF, criterion;
6331 UCHAR AdjustMaxTxPwr[40];
6332
6333 if (pAd->CommonCfg.Channel > 14) // 5G band
6334 TxPwrInEEPROM = ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF00) >> 8);
6335 else // 2.4G band
6336 TxPwrInEEPROM = (pAd->CommonCfg.DefineMaxTxPwr & 0x00FF);
6337 CountryTxPwr = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
6338
6339 // error handling, range check
6340 if ((TxPwrInEEPROM > 0x50) || (CountryTxPwr > 0x50))
6341 {
6342 DBGPRINT(RT_DEBUG_ERROR,("AsicAdjustTxPower - Invalid max tx power (=0x%02x), CountryTxPwr=%d\n", TxPwrInEEPROM, CountryTxPwr));
6343 break;
6344 }
6345
6346 criterion = *((PUCHAR)TxPwr + 2) & 0xF; // FAE use OFDM 6M as criterion
6347
6348 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (criterion=%d, TxPwrInEEPROM=%d, CountryTxPwr=%d)\n", criterion, TxPwrInEEPROM, CountryTxPwr));
6349
6350 // Adjust max tx power according to the relationship of tx power in E2PROM
6351 for (i=0; i<5; i++)
6352 {
6353 // CCK will have 4dBm larger than OFDM
6354 // Therefore, we should separate to parse the tx power field
6355 if (i == 0)
6356 {
6357 for (j=0; j<8; j++)
6358 {
6359 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
6360
6361 if (j < 4)
6362 {
6363 // CCK will have 4dBm larger than OFDM
6364 AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion) + 4;
6365 }
6366 else
6367 {
6368 AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
6369 }
6370 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6371 }
6372 }
6373 else
6374 {
6375 for (j=0; j<8; j++)
6376 {
6377 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
6378
6379 AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
6380 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6381 }
6382 }
6383 }
6384
6385 // Adjust tx power according to the relationship
6386 for (i=0; i<5; i++)
6387 {
6388 if (TxPwr[i] != 0xffffffff)
6389 {
6390 for (j=0; j<8; j++)
6391 {
6392 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
6393
6394 // The system tx power is larger than the regulatory, the power should be restrain
6395 if (AdjustMaxTxPwr[i*8+j] > CountryTxPwr)
6396 {
6397 // decrease to zero and don't need to take care BBPR1
6398 if ((Value - (AdjustMaxTxPwr[i*8+j] - CountryTxPwr)) > 0)
6399 Value -= (AdjustMaxTxPwr[i*8+j] - CountryTxPwr);
6400 else
6401 Value = 0;
6402
6403 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6404 }
6405 else
6406 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d, no change)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6407
6408 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
6409 }
6410 }
6411 }
6412 } while (FALSE);
6413#endif // SINGLE_SKU //
6414
6415 /* calculate delta power based on the percentage specified from UI */
6416 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
6417 // We lower TX power here according to the percentage specified from UI
6418 if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
6419 ;
6420 else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
6421 ;
6422 else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
6423 {
6424 DeltaPwr -= 1;
6425 }
6426 else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
6427 {
6428 DeltaPwr -= 3;
6429 }
6430 else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
6431 {
6432 BbpR1 |= 0x01;
6433 }
6434 else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
6435 {
6436 BbpR1 |= 0x01;
6437 DeltaPwr -= 3;
6438 }
6439 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
6440 {
6441 BbpR1 |= 0x02;
6442 }
6443
6444 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
6445
6446 /* reset different new tx power for different TX rate */
6447 for(i=0; i<5; i++)
6448 {
6449 if (TxPwr[i] != 0xffffffff)
6450 {
6451 for (j=0; j<8; j++)
6452 {
6453 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
6454
6455 if ((Value + DeltaPwr) < 0)
6456 {
6457 Value = 0; /* min */
6458 }
6459 else if ((Value + DeltaPwr) > 0xF)
6460 {
6461 Value = 0xF; /* max */
6462 }
6463 else
6464 {
6465 Value += DeltaPwr; /* temperature compensation */
6466 }
6467
6468 /* fill new value to CSR offset */
6469 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
6470 }
6471
6472 /* write tx power value to CSR */
6473 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
6474 TX power for OFDM 6M/9M
6475 TX power for CCK5.5M/11M
6476 TX power for CCK1M/2M */
6477 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
6478 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
6479 }
6480 }
6481
6482}
6483
6484#ifdef CONFIG_STA_SUPPORT
6485/*
6486 ==========================================================================
6487 Description:
6488 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
6489 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
6490 the wakeup timer timeout. Driver has to issue a separate command to wake
6491 PHY up.
6492
6493 IRQL = DISPATCH_LEVEL
6494
6495 ==========================================================================
6496 */
6497VOID AsicSleepThenAutoWakeup(
6498 IN PRTMP_ADAPTER pAd,
6499 IN USHORT TbttNumToNextWakeUp)
6500{
6501 RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
6502}
6503
6504/*
6505 ==========================================================================
6506 Description:
6507 AsicForceWakeup() is used whenever manual wakeup is required
6508 AsicForceSleep() should only be used when not in INFRA BSS. When
6509 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
6510 ==========================================================================
6511 */
6512VOID AsicForceSleep(
6513 IN PRTMP_ADAPTER pAd)
6514{
6515
6516}
6517
6518/*
6519 ==========================================================================
6520 Description:
6521 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
6522 expired.
6523
6524 IRQL = PASSIVE_LEVEL
6525 IRQL = DISPATCH_LEVEL
6526 ==========================================================================
6527 */
6528VOID AsicForceWakeup(
6529 IN PRTMP_ADAPTER pAd,
6530 IN BOOLEAN bFromTx)
6531{
6532 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
6533 RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
6534}
6535#endif // CONFIG_STA_SUPPORT //
6536/*
6537 ==========================================================================
6538 Description:
6539 Set My BSSID
6540
6541 IRQL = DISPATCH_LEVEL
6542
6543 ==========================================================================
6544 */
6545VOID AsicSetBssid(
6546 IN PRTMP_ADAPTER pAd,
6547 IN PUCHAR pBssid)
6548{
6549 ULONG Addr4;
6550 DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
6551 pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
6552
6553 Addr4 = (ULONG)(pBssid[0]) |
6554 (ULONG)(pBssid[1] << 8) |
6555 (ULONG)(pBssid[2] << 16) |
6556 (ULONG)(pBssid[3] << 24);
6557 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
6558
6559 Addr4 = 0;
6560 // always one BSSID in STA mode
6561 Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
6562
6563 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
6564}
6565
6566VOID AsicSetMcastWC(
6567 IN PRTMP_ADAPTER pAd)
6568{
6569 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
6570 USHORT offset;
6571
6572 pEntry->Sst = SST_ASSOC;
6573 pEntry->Aid = MCAST_WCID; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
6574 pEntry->PsMode = PWR_ACTIVE;
6575 pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
6576 offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
6577}
6578
6579/*
6580 ==========================================================================
6581 Description:
6582
6583 IRQL = DISPATCH_LEVEL
6584
6585 ==========================================================================
6586 */
6587VOID AsicDelWcidTab(
6588 IN PRTMP_ADAPTER pAd,
6589 IN UCHAR Wcid)
6590{
6591 ULONG Addr0 = 0x0, Addr1 = 0x0;
6592 ULONG offset;
6593
6594 DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
6595 offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
6596 RTMP_IO_WRITE32(pAd, offset, Addr0);
6597 offset += 4;
6598 RTMP_IO_WRITE32(pAd, offset, Addr1);
6599}
6600
6601/*
6602 ==========================================================================
6603 Description:
6604
6605 IRQL = DISPATCH_LEVEL
6606
6607 ==========================================================================
6608 */
6609VOID AsicEnableRDG(
6610 IN PRTMP_ADAPTER pAd)
6611{
6612 TX_LINK_CFG_STRUC TxLinkCfg;
6613 UINT32 Data = 0;
6614
6615 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
6616 TxLinkCfg.field.TxRDGEn = 1;
6617 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
6618
6619 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
6620 Data &= 0xFFFFFF00;
6621 Data |= 0x80;
6622 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
6623
6624 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
6625}
6626
6627/*
6628 ==========================================================================
6629 Description:
6630
6631 IRQL = DISPATCH_LEVEL
6632
6633 ==========================================================================
6634 */
6635VOID AsicDisableRDG(
6636 IN PRTMP_ADAPTER pAd)
6637{
6638 TX_LINK_CFG_STRUC TxLinkCfg;
6639 UINT32 Data = 0;
6640
6641
6642 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
6643 TxLinkCfg.field.TxRDGEn = 0;
6644 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
6645
6646 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
6647
6648 Data &= 0xFFFFFF00;
6649 //Data |= 0x20;
6650#ifndef WIFI_TEST
6651 //if ( pAd->CommonCfg.bEnableTxBurst )
6652 // Data |= 0x60; // for performance issue not set the TXOP to 0
6653#endif
6654 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
6655#ifdef DOT11_N_SUPPORT
6656 && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
6657#endif // DOT11_N_SUPPORT //
6658 )
6659 {
6660 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6661 if (pAd->CommonCfg.bEnableTxBurst)
6662 Data |= 0x20;
6663 }
6664 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
6665}
6666
6667/*
6668 ==========================================================================
6669 Description:
6670
6671 IRQL = PASSIVE_LEVEL
6672 IRQL = DISPATCH_LEVEL
6673
6674 ==========================================================================
6675 */
6676VOID AsicDisableSync(
6677 IN PRTMP_ADAPTER pAd)
6678{
6679 BCN_TIME_CFG_STRUC csr;
6680
6681 DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
6682
6683 // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
6684 // that NIC will never wakes up because TSF stops and no more
6685 // TBTT interrupts
6686 pAd->TbttTickCount = 0;
6687 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
6688 csr.field.bBeaconGen = 0;
6689 csr.field.bTBTTEnable = 0;
6690 csr.field.TsfSyncMode = 0;
6691 csr.field.bTsfTicking = 0;
6692 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
6693
6694}
6695
6696/*
6697 ==========================================================================
6698 Description:
6699
6700 IRQL = DISPATCH_LEVEL
6701
6702 ==========================================================================
6703 */
6704VOID AsicEnableBssSync(
6705 IN PRTMP_ADAPTER pAd)
6706{
6707 BCN_TIME_CFG_STRUC csr;
6708
6709 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
6710
6711 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
6712// RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000);
6713#ifdef CONFIG_STA_SUPPORT
6714 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6715 {
6716 csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
6717 csr.field.bTsfTicking = 1;
6718 csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
6719 csr.field.bBeaconGen = 0; // do NOT generate BEACON
6720 csr.field.bTBTTEnable = 1;
6721 }
6722#endif // CONFIG_STA_SUPPORT //
6723 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
6724}
6725
6726/*
6727 ==========================================================================
6728 Description:
6729 Note:
6730 BEACON frame in shared memory should be built ok before this routine
6731 can be called. Otherwise, a garbage frame maybe transmitted out every
6732 Beacon period.
6733
6734 IRQL = DISPATCH_LEVEL
6735
6736 ==========================================================================
6737 */
6738VOID AsicEnableIbssSync(
6739 IN PRTMP_ADAPTER pAd)
6740{
6741 BCN_TIME_CFG_STRUC csr9;
6742 PUCHAR ptr;
6743 UINT i;
6744
6745 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
6746
6747 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
6748 csr9.field.bBeaconGen = 0;
6749 csr9.field.bTBTTEnable = 0;
6750 csr9.field.bTsfTicking = 0;
6751 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
6752
6753
6754#ifdef RT2870
6755 // move BEACON TXD and frame content to on-chip memory
6756 ptr = (PUCHAR)&pAd->BeaconTxWI;
6757 for (i=0; i<TXWI_SIZE; i+=2) // 16-byte TXWI field
6758 {
6759 //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
6760 //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
6761 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
6762 ptr += 2;
6763 }
6764
6765 // start right after the 16-byte TXWI field
6766 ptr = pAd->BeaconBuf;
6767 for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
6768 {
6769 //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
6770 //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
6771 RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
6772 ptr +=2;
6773 }
6774#endif // RT2870 //
6775
6776 //
6777 // For Wi-Fi faily generated beacons between participating stations.
6778 // Set TBTT phase adaptive adjustment step to 8us (default 16us)
6779 // don't change settings 2006-5- by Jerry
6780 //RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010);
6781
6782 // start sending BEACON
6783 csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
6784 csr9.field.bTsfTicking = 1;
6785 csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
6786 csr9.field.bTBTTEnable = 1;
6787 csr9.field.bBeaconGen = 1;
6788 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
6789}
6790
6791/*
6792 ==========================================================================
6793 Description:
6794
6795 IRQL = PASSIVE_LEVEL
6796 IRQL = DISPATCH_LEVEL
6797
6798 ==========================================================================
6799 */
6800VOID AsicSetEdcaParm(
6801 IN PRTMP_ADAPTER pAd,
6802 IN PEDCA_PARM pEdcaParm)
6803{
6804 EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
6805 AC_TXOP_CSR0_STRUC csr0;
6806 AC_TXOP_CSR1_STRUC csr1;
6807 AIFSN_CSR_STRUC AifsnCsr;
6808 CWMIN_CSR_STRUC CwminCsr;
6809 CWMAX_CSR_STRUC CwmaxCsr;
6810 int i;
6811
6812 Ac0Cfg.word = 0;
6813 Ac1Cfg.word = 0;
6814 Ac2Cfg.word = 0;
6815 Ac3Cfg.word = 0;
6816 if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
6817 {
6818 DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
6819 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
6820 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
6821 {
6822 if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
6823 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
6824 }
6825
6826 //========================================================
6827 // MAC Register has a copy .
6828 //========================================================
6829//#ifndef WIFI_TEST
6830 if( pAd->CommonCfg.bEnableTxBurst )
6831 {
6832 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6833 Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
6834 }
6835 else
6836 Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
6837//#else
6838// Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
6839//#endif
6840 Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
6841 Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
6842 Ac0Cfg.field.Aifsn = 2;
6843 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
6844
6845 Ac1Cfg.field.AcTxop = 0; // QID_AC_BK
6846 Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
6847 Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
6848 Ac1Cfg.field.Aifsn = 2;
6849 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
6850
6851 if (pAd->CommonCfg.PhyMode == PHY_11B)
6852 {
6853 Ac2Cfg.field.AcTxop = 192; // AC_VI: 192*32us ~= 6ms
6854 Ac3Cfg.field.AcTxop = 96; // AC_VO: 96*32us ~= 3ms
6855 }
6856 else
6857 {
6858 Ac2Cfg.field.AcTxop = 96; // AC_VI: 96*32us ~= 3ms
6859 Ac3Cfg.field.AcTxop = 48; // AC_VO: 48*32us ~= 1.5ms
6860 }
6861 Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
6862 Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
6863 Ac2Cfg.field.Aifsn = 2;
6864 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
6865 Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
6866 Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
6867 Ac3Cfg.field.Aifsn = 2;
6868 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
6869
6870 //========================================================
6871 // DMA Register has a copy too.
6872 //========================================================
6873 csr0.field.Ac0Txop = 0; // QID_AC_BE
6874 csr0.field.Ac1Txop = 0; // QID_AC_BK
6875 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
6876 if (pAd->CommonCfg.PhyMode == PHY_11B)
6877 {
6878 csr1.field.Ac2Txop = 192; // AC_VI: 192*32us ~= 6ms
6879 csr1.field.Ac3Txop = 96; // AC_VO: 96*32us ~= 3ms
6880 }
6881 else
6882 {
6883 csr1.field.Ac2Txop = 96; // AC_VI: 96*32us ~= 3ms
6884 csr1.field.Ac3Txop = 48; // AC_VO: 48*32us ~= 1.5ms
6885 }
6886 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
6887
6888 CwminCsr.word = 0;
6889 CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
6890 CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
6891 CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
6892 CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
6893 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
6894
6895 CwmaxCsr.word = 0;
6896 CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
6897 CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
6898 CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
6899 CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
6900 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
6901
6902 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
6903
6904 NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
6905 }
6906 else
6907 {
6908 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
6909 //========================================================
6910 // MAC Register has a copy.
6911 //========================================================
6912 //
6913 // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
6914 // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
6915 //
6916 //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
6917
6918 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
6919 Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
6920 Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
6921 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
6922
6923 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
6924 Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
6925 Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
6926 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
6927
6928 Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
6929 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
6930 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
6931 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI];
6932#ifdef CONFIG_STA_SUPPORT
6933 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6934 {
6935 // Tuning for Wi-Fi WMM S06
6936 if (pAd->CommonCfg.bWiFiTest &&
6937 pEdcaParm->Aifsn[QID_AC_VI] == 10)
6938 Ac2Cfg.field.Aifsn -= 1;
6939
6940 // Tuning for TGn Wi-Fi 5.2.32
6941 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
6942 if (STA_TGN_WIFI_ON(pAd) &&
6943 pEdcaParm->Aifsn[QID_AC_VI] == 10)
6944 {
6945 Ac0Cfg.field.Aifsn = 3;
6946 Ac2Cfg.field.AcTxop = 5;
6947 }
6948 }
6949#endif // CONFIG_STA_SUPPORT //
6950
6951 Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
6952 Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
6953 Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
6954 Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
6955
6956//#ifdef WIFI_TEST
6957 if (pAd->CommonCfg.bWiFiTest)
6958 {
6959 if (Ac3Cfg.field.AcTxop == 102)
6960 {
6961 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
6962 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
6963 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
6964 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];
6965 Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
6966 } /* End of if */
6967 }
6968//#endif // WIFI_TEST //
6969
6970 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
6971 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
6972 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
6973 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
6974
6975
6976 //========================================================
6977 // DMA Register has a copy too.
6978 //========================================================
6979 csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
6980 csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
6981 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
6982
6983 csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
6984 csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
6985 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
6986
6987 CwminCsr.word = 0;
6988 CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
6989 CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
6990 CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
6991#ifdef CONFIG_STA_SUPPORT
6992 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6993 CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
6994#endif // CONFIG_STA_SUPPORT //
6995 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
6996
6997 CwmaxCsr.word = 0;
6998 CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
6999 CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
7000 CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
7001 CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
7002 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
7003
7004 AifsnCsr.word = 0;
7005 AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
7006 AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
7007 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
7008#ifdef CONFIG_STA_SUPPORT
7009 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7010 {
7011 // Tuning for Wi-Fi WMM S06
7012 if (pAd->CommonCfg.bWiFiTest &&
7013 pEdcaParm->Aifsn[QID_AC_VI] == 10)
7014 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
7015
7016 // Tuning for TGn Wi-Fi 5.2.32
7017 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
7018 if (STA_TGN_WIFI_ON(pAd) &&
7019 pEdcaParm->Aifsn[QID_AC_VI] == 10)
7020 {
7021 AifsnCsr.field.Aifsn0 = 3;
7022 AifsnCsr.field.Aifsn2 = 7;
7023 }
7024
7025 if (INFRA_ON(pAd))
7026 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
7027 }
7028#endif // CONFIG_STA_SUPPORT //
7029
7030#ifdef CONFIG_STA_SUPPORT
7031 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7032 AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
7033#endif // CONFIG_STA_SUPPORT //
7034 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
7035
7036 NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
7037 if (!ADHOC_ON(pAd))
7038 {
7039 DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount));
7040 DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n",
7041 pEdcaParm->Aifsn[0],
7042 pEdcaParm->Cwmin[0],
7043 pEdcaParm->Cwmax[0],
7044 pEdcaParm->Txop[0]<<5,
7045 pEdcaParm->bACM[0]));
7046 DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n",
7047 pEdcaParm->Aifsn[1],
7048 pEdcaParm->Cwmin[1],
7049 pEdcaParm->Cwmax[1],
7050 pEdcaParm->Txop[1]<<5,
7051 pEdcaParm->bACM[1]));
7052 DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n",
7053 pEdcaParm->Aifsn[2],
7054 pEdcaParm->Cwmin[2],
7055 pEdcaParm->Cwmax[2],
7056 pEdcaParm->Txop[2]<<5,
7057 pEdcaParm->bACM[2]));
7058 DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n",
7059 pEdcaParm->Aifsn[3],
7060 pEdcaParm->Cwmin[3],
7061 pEdcaParm->Cwmax[3],
7062 pEdcaParm->Txop[3]<<5,
7063 pEdcaParm->bACM[3]));
7064 }
7065 }
7066}
7067
7068/*
7069 ==========================================================================
7070 Description:
7071
7072 IRQL = PASSIVE_LEVEL
7073 IRQL = DISPATCH_LEVEL
7074
7075 ==========================================================================
7076 */
7077VOID AsicSetSlotTime(
7078 IN PRTMP_ADAPTER pAd,
7079 IN BOOLEAN bUseShortSlotTime)
7080{
7081 ULONG SlotTime;
7082 UINT32 RegValue = 0;
7083
7084#ifdef CONFIG_STA_SUPPORT
7085 if (pAd->CommonCfg.Channel > 14)
7086 bUseShortSlotTime = TRUE;
7087#endif // CONFIG_STA_SUPPORT //
7088
7089 if (bUseShortSlotTime)
7090 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
7091 else
7092 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
7093
7094 SlotTime = (bUseShortSlotTime)? 9 : 20;
7095
7096#ifdef CONFIG_STA_SUPPORT
7097 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7098 {
7099 // force using short SLOT time for FAE to demo performance when TxBurst is ON
7100 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
7101#ifdef DOT11_N_SUPPORT
7102 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
7103#endif // DOT11_N_SUPPORT //
7104 )
7105 {
7106 // In this case, we will think it is doing Wi-Fi test
7107 // And we will not set to short slot when bEnableTxBurst is TRUE.
7108 }
7109 else if (pAd->CommonCfg.bEnableTxBurst)
7110 SlotTime = 9;
7111 }
7112#endif // CONFIG_STA_SUPPORT //
7113
7114 //
7115 // For some reasons, always set it to short slot time.
7116 //
7117 // ToDo: Should consider capability with 11B
7118 //
7119#ifdef CONFIG_STA_SUPPORT
7120 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7121 {
7122 if (pAd->StaCfg.BssType == BSS_ADHOC)
7123 SlotTime = 20;
7124 }
7125#endif // CONFIG_STA_SUPPORT //
7126
7127 RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
7128 RegValue = RegValue & 0xFFFFFF00;
7129
7130 RegValue |= SlotTime;
7131
7132 RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
7133}
7134
7135/*
7136 ========================================================================
7137 Description:
7138 Add Shared key information into ASIC.
7139 Update shared key, TxMic and RxMic to Asic Shared key table
7140 Update its cipherAlg to Asic Shared key Mode.
7141
7142 Return:
7143 ========================================================================
7144*/
7145VOID AsicAddSharedKeyEntry(
7146 IN PRTMP_ADAPTER pAd,
7147 IN UCHAR BssIndex,
7148 IN UCHAR KeyIdx,
7149 IN UCHAR CipherAlg,
7150 IN PUCHAR pKey,
7151 IN PUCHAR pTxMic,
7152 IN PUCHAR pRxMic)
7153{
7154 ULONG offset; //, csr0;
7155 SHAREDKEY_MODE_STRUC csr1;
7156
7157 DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
7158//============================================================================================
7159
7160 DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
7161 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7162 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]));
7163 if (pRxMic)
7164 {
7165 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7166 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
7167 }
7168 if (pTxMic)
7169 {
7170 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7171 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
7172 }
7173//============================================================================================
7174 //
7175 // fill key material - key + TX MIC + RX MIC
7176 //
7177
7178#ifdef RT2870
7179{
7180 offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
7181 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
7182
7183 offset += MAX_LEN_OF_SHARE_KEY;
7184 if (pTxMic)
7185 {
7186 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
7187 }
7188
7189 offset += 8;
7190 if (pRxMic)
7191 {
7192 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
7193 }
7194}
7195#endif // RT2870 //
7196
7197 //
7198 // Update cipher algorithm. WSTA always use BSS0
7199 //
7200 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
7201 DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
7202 if ((BssIndex%2) == 0)
7203 {
7204 if (KeyIdx == 0)
7205 csr1.field.Bss0Key0CipherAlg = CipherAlg;
7206 else if (KeyIdx == 1)
7207 csr1.field.Bss0Key1CipherAlg = CipherAlg;
7208 else if (KeyIdx == 2)
7209 csr1.field.Bss0Key2CipherAlg = CipherAlg;
7210 else
7211 csr1.field.Bss0Key3CipherAlg = CipherAlg;
7212 }
7213 else
7214 {
7215 if (KeyIdx == 0)
7216 csr1.field.Bss1Key0CipherAlg = CipherAlg;
7217 else if (KeyIdx == 1)
7218 csr1.field.Bss1Key1CipherAlg = CipherAlg;
7219 else if (KeyIdx == 2)
7220 csr1.field.Bss1Key2CipherAlg = CipherAlg;
7221 else
7222 csr1.field.Bss1Key3CipherAlg = CipherAlg;
7223 }
7224 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
7225 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
7226
7227}
7228
7229// IRQL = DISPATCH_LEVEL
7230VOID AsicRemoveSharedKeyEntry(
7231 IN PRTMP_ADAPTER pAd,
7232 IN UCHAR BssIndex,
7233 IN UCHAR KeyIdx)
7234{
7235 //ULONG SecCsr0;
7236 SHAREDKEY_MODE_STRUC csr1;
7237
7238 DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
7239
7240 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
7241 if ((BssIndex%2) == 0)
7242 {
7243 if (KeyIdx == 0)
7244 csr1.field.Bss0Key0CipherAlg = 0;
7245 else if (KeyIdx == 1)
7246 csr1.field.Bss0Key1CipherAlg = 0;
7247 else if (KeyIdx == 2)
7248 csr1.field.Bss0Key2CipherAlg = 0;
7249 else
7250 csr1.field.Bss0Key3CipherAlg = 0;
7251 }
7252 else
7253 {
7254 if (KeyIdx == 0)
7255 csr1.field.Bss1Key0CipherAlg = 0;
7256 else if (KeyIdx == 1)
7257 csr1.field.Bss1Key1CipherAlg = 0;
7258 else if (KeyIdx == 2)
7259 csr1.field.Bss1Key2CipherAlg = 0;
7260 else
7261 csr1.field.Bss1Key3CipherAlg = 0;
7262 }
7263 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
7264 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
7265 ASSERT(BssIndex < 4);
7266 ASSERT(KeyIdx < 4);
7267
7268}
7269
7270
7271VOID AsicUpdateWCIDAttribute(
7272 IN PRTMP_ADAPTER pAd,
7273 IN USHORT WCID,
7274 IN UCHAR BssIndex,
7275 IN UCHAR CipherAlg,
7276 IN BOOLEAN bUsePairewiseKeyTable)
7277{
7278 ULONG WCIDAttri = 0, offset;
7279
7280 //
7281 // Update WCID attribute.
7282 // Only TxKey could update WCID attribute.
7283 //
7284 offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
7285 WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
7286 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
7287}
7288
7289VOID AsicUpdateWCIDIVEIV(
7290 IN PRTMP_ADAPTER pAd,
7291 IN USHORT WCID,
7292 IN ULONG uIV,
7293 IN ULONG uEIV)
7294{
7295 ULONG offset;
7296
7297 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
7298
7299 RTMP_IO_WRITE32(pAd, offset, uIV);
7300 RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
7301}
7302
7303VOID AsicUpdateRxWCIDTable(
7304 IN PRTMP_ADAPTER pAd,
7305 IN USHORT WCID,
7306 IN PUCHAR pAddr)
7307{
7308 ULONG offset;
7309 ULONG Addr;
7310
7311 offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
7312 Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
7313 RTMP_IO_WRITE32(pAd, offset, Addr);
7314 Addr = pAddr[4] + (pAddr[5] << 8);
7315 RTMP_IO_WRITE32(pAd, offset + 4, Addr);
7316}
7317
7318
7319/*
7320 ========================================================================
7321
7322 Routine Description:
7323 Set Cipher Key, Cipher algorithm, IV/EIV to Asic
7324
7325 Arguments:
7326 pAd Pointer to our adapter
7327 WCID WCID Entry number.
7328 BssIndex BSSID index, station or none multiple BSSID support
7329 this value should be 0.
7330 KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
7331 pCipherKey Pointer to Cipher Key.
7332 bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
7333 otherwise PairewiseKey table
7334 bTxKey This is the transmit key if enabled.
7335
7336 Return Value:
7337 None
7338
7339 Note:
7340 This routine will set the relative key stuff to Asic including WCID attribute,
7341 Cipher Key, Cipher algorithm and IV/EIV.
7342
7343 IV/EIV will be update if this CipherKey is the transmission key because
7344 ASIC will base on IV's KeyID value to select Cipher Key.
7345
7346 If bTxKey sets to FALSE, this is not the TX key, but it could be
7347 RX key
7348
7349 For AP mode bTxKey must be always set to TRUE.
7350 ========================================================================
7351*/
7352VOID AsicAddKeyEntry(
7353 IN PRTMP_ADAPTER pAd,
7354 IN USHORT WCID,
7355 IN UCHAR BssIndex,
7356 IN UCHAR KeyIdx,
7357 IN PCIPHER_KEY pCipherKey,
7358 IN BOOLEAN bUsePairewiseKeyTable,
7359 IN BOOLEAN bTxKey)
7360{
7361 ULONG offset;
7362// ULONG WCIDAttri = 0;
7363 UCHAR IV4 = 0;
7364 PUCHAR pKey = pCipherKey->Key;
7365// ULONG KeyLen = pCipherKey->KeyLen;
7366 PUCHAR pTxMic = pCipherKey->TxMic;
7367 PUCHAR pRxMic = pCipherKey->RxMic;
7368 PUCHAR pTxtsc = pCipherKey->TxTsc;
7369 UCHAR CipherAlg = pCipherKey->CipherAlg;
7370 SHAREDKEY_MODE_STRUC csr1;
7371
7372// ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY);
7373
7374 DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
7375 //
7376 // 1.) decide key table offset
7377 //
7378 if (bUsePairewiseKeyTable)
7379 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
7380 else
7381 offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
7382
7383 //
7384 // 2.) Set Key to Asic
7385 //
7386 //for (i = 0; i < KeyLen; i++)
7387
7388#ifdef RT2870
7389 RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
7390 offset += MAX_LEN_OF_PEER_KEY;
7391
7392 //
7393 // 3.) Set MIC key if available
7394 //
7395 if (pTxMic)
7396 {
7397 RTUSBMultiWrite(pAd, offset, pTxMic, 8);
7398 }
7399 offset += LEN_TKIP_TXMICK;
7400
7401 if (pRxMic)
7402 {
7403 RTUSBMultiWrite(pAd, offset, pRxMic, 8);
7404 }
7405#endif // RT2870 //
7406
7407 //
7408 // 4.) Modify IV/EIV if needs
7409 // This will force Asic to use this key ID by setting IV.
7410 //
7411 if (bTxKey)
7412 {
7413
7414#ifdef RT2870
7415 UINT32 tmpVal;
7416
7417 //
7418 // Write IV
7419 //
7420 IV4 = (KeyIdx << 6);
7421 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
7422 IV4 |= 0x20; // turn on extension bit means EIV existence
7423
7424 tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
7425 RTMP_IO_WRITE32(pAd, offset, tmpVal);
7426
7427 //
7428 // Write EIV
7429 //
7430 offset += 4;
7431 RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
7432#endif // RT2870 //
7433 AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
7434 }
7435
7436 if (!bUsePairewiseKeyTable)
7437 {
7438 //
7439 // Only update the shared key security mode
7440 //
7441 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
7442 if ((BssIndex % 2) == 0)
7443 {
7444 if (KeyIdx == 0)
7445 csr1.field.Bss0Key0CipherAlg = CipherAlg;
7446 else if (KeyIdx == 1)
7447 csr1.field.Bss0Key1CipherAlg = CipherAlg;
7448 else if (KeyIdx == 2)
7449 csr1.field.Bss0Key2CipherAlg = CipherAlg;
7450 else
7451 csr1.field.Bss0Key3CipherAlg = CipherAlg;
7452 }
7453 else
7454 {
7455 if (KeyIdx == 0)
7456 csr1.field.Bss1Key0CipherAlg = CipherAlg;
7457 else if (KeyIdx == 1)
7458 csr1.field.Bss1Key1CipherAlg = CipherAlg;
7459 else if (KeyIdx == 2)
7460 csr1.field.Bss1Key2CipherAlg = CipherAlg;
7461 else
7462 csr1.field.Bss1Key3CipherAlg = CipherAlg;
7463 }
7464 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
7465 }
7466
7467 DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
7468}
7469
7470
7471/*
7472 ========================================================================
7473 Description:
7474 Add Pair-wise key material into ASIC.
7475 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
7476
7477 Return:
7478 ========================================================================
7479*/
7480VOID AsicAddPairwiseKeyEntry(
7481 IN PRTMP_ADAPTER pAd,
7482 IN PUCHAR pAddr,
7483 IN UCHAR WCID,
7484 IN CIPHER_KEY *pCipherKey)
7485{
7486 INT i;
7487 ULONG offset;
7488 PUCHAR pKey = pCipherKey->Key;
7489 PUCHAR pTxMic = pCipherKey->TxMic;
7490 PUCHAR pRxMic = pCipherKey->RxMic;
7491#ifdef DBG
7492 UCHAR CipherAlg = pCipherKey->CipherAlg;
7493#endif // DBG //
7494
7495 // EKEY
7496 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
7497#ifdef RT2870
7498 RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
7499#endif // RT2870 //
7500 for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
7501 {
7502 UINT32 Value;
7503 RTMP_IO_READ32(pAd, offset + i, &Value);
7504 }
7505
7506 offset += MAX_LEN_OF_PEER_KEY;
7507
7508 // MIC KEY
7509 if (pTxMic)
7510 {
7511#ifdef RT2870
7512 RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
7513#endif // RT2870 //
7514 }
7515 offset += 8;
7516 if (pRxMic)
7517 {
7518#ifdef RT2870
7519 RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
7520#endif // RT2870 //
7521 }
7522
7523 DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
7524 DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7525 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]));
7526 if (pRxMic)
7527 {
7528 DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7529 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
7530 }
7531 if (pTxMic)
7532 {
7533 DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7534 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
7535 }
7536}
7537/*
7538 ========================================================================
7539 Description:
7540 Remove Pair-wise key material from ASIC.
7541
7542 Return:
7543 ========================================================================
7544*/
7545VOID AsicRemovePairwiseKeyEntry(
7546 IN PRTMP_ADAPTER pAd,
7547 IN UCHAR BssIdx,
7548 IN UCHAR Wcid)
7549{
7550 ULONG WCIDAttri;
7551 USHORT offset;
7552
7553 // re-set the entry's WCID attribute as OPEN-NONE.
7554 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
7555 WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
7556 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
7557}
7558
7559BOOLEAN AsicSendCommandToMcu(
7560 IN PRTMP_ADAPTER pAd,
7561 IN UCHAR Command,
7562 IN UCHAR Token,
7563 IN UCHAR Arg0,
7564 IN UCHAR Arg1)
7565{
7566 HOST_CMD_CSR_STRUC H2MCmd;
7567 H2M_MAILBOX_STRUC H2MMailbox;
7568 ULONG i = 0;
7569 do
7570 {
7571 RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
7572 if (H2MMailbox.field.Owner == 0)
7573 break;
7574
7575 RTMPusecDelay(2);
7576 } while(i++ < 100);
7577
7578 if (i >= 100)
7579 {
7580 {
7581 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
7582 }
7583 return FALSE;
7584 }
7585
7586
7587 H2MMailbox.field.Owner = 1; // pass ownership to MCU
7588 H2MMailbox.field.CmdToken = Token;
7589 H2MMailbox.field.HighByte = Arg1;
7590 H2MMailbox.field.LowByte = Arg0;
7591 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
7592
7593 H2MCmd.word = 0;
7594 H2MCmd.field.HostCommand = Command;
7595 RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
7596
7597 if (Command != 0x80)
7598 {
7599 }
7600
7601 return TRUE;
7602}
7603
7604
7605/*
7606 ========================================================================
7607
7608 Routine Description:
7609 Verify the support rate for different PHY type
7610
7611 Arguments:
7612 pAd Pointer to our adapter
7613
7614 Return Value:
7615 None
7616
7617 IRQL = PASSIVE_LEVEL
7618
7619 ========================================================================
7620*/
7621VOID RTMPCheckRates(
7622 IN PRTMP_ADAPTER pAd,
7623 IN OUT UCHAR SupRate[],
7624 IN OUT UCHAR *SupRateLen)
7625{
7626 UCHAR RateIdx, i, j;
7627 UCHAR NewRate[12], NewRateLen;
7628
7629 NewRateLen = 0;
7630
7631 if (pAd->CommonCfg.PhyMode == PHY_11B)
7632 RateIdx = 4;
7633 else
7634 RateIdx = 12;
7635
7636 // Check for support rates exclude basic rate bit
7637 for (i = 0; i < *SupRateLen; i++)
7638 for (j = 0; j < RateIdx; j++)
7639 if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
7640 NewRate[NewRateLen++] = SupRate[i];
7641
7642 *SupRateLen = NewRateLen;
7643 NdisMoveMemory(SupRate, NewRate, NewRateLen);
7644}
7645
7646#ifdef CONFIG_STA_SUPPORT
7647#ifdef DOT11_N_SUPPORT
7648BOOLEAN RTMPCheckChannel(
7649 IN PRTMP_ADAPTER pAd,
7650 IN UCHAR CentralChannel,
7651 IN UCHAR Channel)
7652{
7653 UCHAR k;
7654 UCHAR UpperChannel = 0, LowerChannel = 0;
7655 UCHAR NoEffectChannelinList = 0;
7656
7657 // Find upper and lower channel according to 40MHz current operation.
7658 if (CentralChannel < Channel)
7659 {
7660 UpperChannel = Channel;
7661 if (CentralChannel > 2)
7662 LowerChannel = CentralChannel - 2;
7663 else
7664 return FALSE;
7665 }
7666 else if (CentralChannel > Channel)
7667 {
7668 UpperChannel = CentralChannel + 2;
7669 LowerChannel = Channel;
7670 }
7671
7672 for (k = 0;k < pAd->ChannelListNum;k++)
7673 {
7674 if (pAd->ChannelList[k].Channel == UpperChannel)
7675 {
7676 NoEffectChannelinList ++;
7677 }
7678 if (pAd->ChannelList[k].Channel == LowerChannel)
7679 {
7680 NoEffectChannelinList ++;
7681 }
7682 }
7683
7684 DBGPRINT(RT_DEBUG_TRACE,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList));
7685 if (NoEffectChannelinList == 2)
7686 return TRUE;
7687 else
7688 return FALSE;
7689}
7690
7691/*
7692 ========================================================================
7693
7694 Routine Description:
7695 Verify the support rate for HT phy type
7696
7697 Arguments:
7698 pAd Pointer to our adapter
7699
7700 Return Value:
7701 FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability. (AP Mode)
7702
7703 IRQL = PASSIVE_LEVEL
7704
7705 ========================================================================
7706*/
7707BOOLEAN RTMPCheckHt(
7708 IN PRTMP_ADAPTER pAd,
7709 IN UCHAR Wcid,
7710 IN HT_CAPABILITY_IE *pHtCapability,
7711 IN ADD_HT_INFO_IE *pAddHtInfo)
7712{
7713 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
7714 return FALSE;
7715
7716 // If use AMSDU, set flag.
7717 if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
7718 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_AMSDU_INUSED);
7719 // Save Peer Capability
7720 if (pHtCapability->HtCapInfo.ShortGIfor20)
7721 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI20_CAPABLE);
7722 if (pHtCapability->HtCapInfo.ShortGIfor40)
7723 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI40_CAPABLE);
7724 if (pHtCapability->HtCapInfo.TxSTBC)
7725 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_TxSTBC_CAPABLE);
7726 if (pHtCapability->HtCapInfo.RxSTBC)
7727 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RxSTBC_CAPABLE);
7728 if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
7729 {
7730 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RDG_CAPABLE);
7731 }
7732
7733 if (Wcid < MAX_LEN_OF_MAC_TABLE)
7734 {
7735 pAd->MacTab.Content[Wcid].MpduDensity = pHtCapability->HtCapParm.MpduDensity;
7736 }
7737
7738 // Will check ChannelWidth for MCSSet[4] below
7739 pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
7740 switch (pAd->CommonCfg.RxStream)
7741 {
7742 case 1:
7743 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
7744 pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
7745 pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
7746 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
7747 break;
7748 case 2:
7749 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
7750 pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
7751 pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
7752 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
7753 break;
7754 case 3:
7755 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
7756 pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
7757 pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
7758 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
7759 break;
7760 }
7761
7762 pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.ChannelWidth;
7763
7764 DBGPRINT(RT_DEBUG_TRACE, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
7765 pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, pAddHtInfo->AddHtInfo.RecomWidth, pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
7766 pAd->NicConfig2.field.BW40MAvailForA, pAd->NicConfig2.field.BW40MAvailForG, pAd->CommonCfg.PhyMode));
7767
7768 pAd->MlmeAux.HtCapability.HtCapInfo.GF = pHtCapability->HtCapInfo.GF &pAd->CommonCfg.DesiredHtPhy.GF;
7769
7770 // Send Assoc Req with my HT capability.
7771 pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize = pAd->CommonCfg.DesiredHtPhy.AmsduSize;
7772 pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs = pAd->CommonCfg.DesiredHtPhy.MimoPs;
7773 pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20);
7774 pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40);
7775 pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC = (pAd->CommonCfg.DesiredHtPhy.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC);
7776 pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC = (pAd->CommonCfg.DesiredHtPhy.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC);
7777 pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
7778 pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
7779 pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
7780 pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
7781 if (pAd->CommonCfg.bRdg)
7782 {
7783 pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport;
7784 pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
7785 }
7786
7787 if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
7788 pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0; // BW20 can't transmit MCS32
7789
7790 COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
7791 return TRUE;
7792}
7793#endif // DOT11_N_SUPPORT //
7794#endif // CONFIG_STA_SUPPORT //
7795
7796/*
7797 ========================================================================
7798
7799 Routine Description:
7800 Verify the support rate for different PHY type
7801
7802 Arguments:
7803 pAd Pointer to our adapter
7804
7805 Return Value:
7806 None
7807
7808 IRQL = PASSIVE_LEVEL
7809
7810 ========================================================================
7811*/
7812VOID RTMPUpdateMlmeRate(
7813 IN PRTMP_ADAPTER pAd)
7814{
7815 UCHAR MinimumRate;
7816 UCHAR ProperMlmeRate; //= RATE_54;
7817 UCHAR i, j, RateIdx = 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
7818 BOOLEAN bMatch = FALSE;
7819
7820 switch (pAd->CommonCfg.PhyMode)
7821 {
7822 case PHY_11B:
7823 ProperMlmeRate = RATE_11;
7824 MinimumRate = RATE_1;
7825 break;
7826 case PHY_11BG_MIXED:
7827#ifdef DOT11_N_SUPPORT
7828 case PHY_11ABGN_MIXED:
7829 case PHY_11BGN_MIXED:
7830#endif // DOT11_N_SUPPORT //
7831 if ((pAd->MlmeAux.SupRateLen == 4) &&
7832 (pAd->MlmeAux.ExtRateLen == 0))
7833 // B only AP
7834 ProperMlmeRate = RATE_11;
7835 else
7836 ProperMlmeRate = RATE_24;
7837
7838 if (pAd->MlmeAux.Channel <= 14)
7839 MinimumRate = RATE_1;
7840 else
7841 MinimumRate = RATE_6;
7842 break;
7843 case PHY_11A:
7844#ifdef DOT11_N_SUPPORT
7845 case PHY_11N_2_4G: // rt2860 need to check mlmerate for 802.11n
7846 case PHY_11GN_MIXED:
7847 case PHY_11AGN_MIXED:
7848 case PHY_11AN_MIXED:
7849 case PHY_11N_5G:
7850#endif // DOT11_N_SUPPORT //
7851 ProperMlmeRate = RATE_24;
7852 MinimumRate = RATE_6;
7853 break;
7854 case PHY_11ABG_MIXED:
7855 ProperMlmeRate = RATE_24;
7856 if (pAd->MlmeAux.Channel <= 14)
7857 MinimumRate = RATE_1;
7858 else
7859 MinimumRate = RATE_6;
7860 break;
7861 default: // error
7862 ProperMlmeRate = RATE_1;
7863 MinimumRate = RATE_1;
7864 break;
7865 }
7866
7867 for (i = 0; i < pAd->MlmeAux.SupRateLen; i++)
7868 {
7869 for (j = 0; j < RateIdx; j++)
7870 {
7871 if ((pAd->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
7872 {
7873 if (j == ProperMlmeRate)
7874 {
7875 bMatch = TRUE;
7876 break;
7877 }
7878 }
7879 }
7880
7881 if (bMatch)
7882 break;
7883 }
7884
7885 if (bMatch == FALSE)
7886 {
7887 for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++)
7888 {
7889 for (j = 0; j < RateIdx; j++)
7890 {
7891 if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
7892 {
7893 if (j == ProperMlmeRate)
7894 {
7895 bMatch = TRUE;
7896 break;
7897 }
7898 }
7899 }
7900
7901 if (bMatch)
7902 break;
7903 }
7904 }
7905
7906 if (bMatch == FALSE)
7907 {
7908 ProperMlmeRate = MinimumRate;
7909 }
7910
7911 pAd->CommonCfg.MlmeRate = MinimumRate;
7912 pAd->CommonCfg.RtsRate = ProperMlmeRate;
7913 if (pAd->CommonCfg.MlmeRate >= RATE_6)
7914 {
7915 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
7916 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
7917 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
7918 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
7919 }
7920 else
7921 {
7922 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
7923 pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
7924 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK;
7925 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate;
7926 }
7927
7928 DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n" , pAd->CommonCfg.MlmeTransmit.word));
7929}
7930
7931CHAR RTMPMaxRssi(
7932 IN PRTMP_ADAPTER pAd,
7933 IN CHAR Rssi0,
7934 IN CHAR Rssi1,
7935 IN CHAR Rssi2)
7936{
7937 CHAR larger = -127;
7938
7939 if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0))
7940 {
7941 larger = Rssi0;
7942 }
7943
7944 if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0))
7945 {
7946 larger = max(Rssi0, Rssi1);
7947 }
7948
7949 if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0))
7950 {
7951 larger = max(larger, Rssi2);
7952 }
7953
7954 if (larger == -127)
7955 larger = 0;
7956
7957 return larger;
7958}
7959
7960/*
7961 ========================================================================
7962 Routine Description:
7963 Periodic evaluate antenna link status
7964
7965 Arguments:
7966 pAd - Adapter pointer
7967
7968 Return Value:
7969 None
7970
7971 ========================================================================
7972*/
7973VOID AsicEvaluateRxAnt(
7974 IN PRTMP_ADAPTER pAd)
7975{
7976 UCHAR BBPR3 = 0;
7977
7978#ifdef RALINK_ATE
7979 if (ATE_ON(pAd))
7980 return;
7981#endif // RALINK_ATE //
7982
7983
7984#ifdef CONFIG_STA_SUPPORT
7985 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7986 {
7987 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
7988 fRTMP_ADAPTER_HALT_IN_PROGRESS |
7989 fRTMP_ADAPTER_RADIO_OFF |
7990 fRTMP_ADAPTER_NIC_NOT_EXIST |
7991 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
7992 return;
7993
7994 if (pAd->StaCfg.Psm == PWR_SAVE)
7995 return;
7996 }
7997#endif // CONFIG_STA_SUPPORT //
7998
7999 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
8000 BBPR3 &= (~0x18);
8001 if(pAd->Antenna.field.RxPath == 3)
8002 {
8003 BBPR3 |= (0x10);
8004 }
8005 else if(pAd->Antenna.field.RxPath == 2)
8006 {
8007 BBPR3 |= (0x8);
8008 }
8009 else if(pAd->Antenna.field.RxPath == 1)
8010 {
8011 BBPR3 |= (0x0);
8012 }
8013 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8014#ifdef CONFIG_STA_SUPPORT
8015#endif // CONFIG_STA_SUPPORT //
8016 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
8017 )
8018 {
8019 ULONG TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
8020 pAd->RalinkCounters.OneSecTxRetryOkCount +
8021 pAd->RalinkCounters.OneSecTxFailCount;
8022
8023 if (TxTotalCnt > 50)
8024 {
8025 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
8026 pAd->Mlme.bLowThroughput = FALSE;
8027 }
8028 else
8029 {
8030 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
8031 pAd->Mlme.bLowThroughput = TRUE;
8032 }
8033 }
8034}
8035
8036/*
8037 ========================================================================
8038 Routine Description:
8039 After evaluation, check antenna link status
8040
8041 Arguments:
8042 pAd - Adapter pointer
8043
8044 Return Value:
8045 None
8046
8047 ========================================================================
8048*/
8049VOID AsicRxAntEvalTimeout(
8050 IN PVOID SystemSpecific1,
8051 IN PVOID FunctionContext,
8052 IN PVOID SystemSpecific2,
8053 IN PVOID SystemSpecific3)
8054{
8055 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
8056#ifdef CONFIG_STA_SUPPORT
8057 UCHAR BBPR3 = 0;
8058 CHAR larger = -127, rssi0, rssi1, rssi2;
8059#endif // CONFIG_STA_SUPPORT //
8060
8061#ifdef RALINK_ATE
8062 if (ATE_ON(pAd))
8063 return;
8064#endif // RALINK_ATE //
8065
8066
8067#ifdef CONFIG_STA_SUPPORT
8068 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8069 {
8070 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
8071 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
8072 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF) ||
8073 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
8074 return;
8075
8076 if (pAd->StaCfg.Psm == PWR_SAVE)
8077 return;
8078
8079
8080 // if the traffic is low, use average rssi as the criteria
8081 if (pAd->Mlme.bLowThroughput == TRUE)
8082 {
8083 rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
8084 rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
8085 rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
8086 }
8087 else
8088 {
8089 rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
8090 rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
8091 rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
8092 }
8093
8094 if(pAd->Antenna.field.RxPath == 3)
8095 {
8096 larger = max(rssi0, rssi1);
8097
8098 if (larger > (rssi2 + 20))
8099 pAd->Mlme.RealRxPath = 2;
8100 else
8101 pAd->Mlme.RealRxPath = 3;
8102 }
8103 else if(pAd->Antenna.field.RxPath == 2)
8104 {
8105 if (rssi0 > (rssi1 + 20))
8106 pAd->Mlme.RealRxPath = 1;
8107 else
8108 pAd->Mlme.RealRxPath = 2;
8109 }
8110
8111 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
8112 BBPR3 &= (~0x18);
8113 if(pAd->Mlme.RealRxPath == 3)
8114 {
8115 BBPR3 |= (0x10);
8116 }
8117 else if(pAd->Mlme.RealRxPath == 2)
8118 {
8119 BBPR3 |= (0x8);
8120 }
8121 else if(pAd->Mlme.RealRxPath == 1)
8122 {
8123 BBPR3 |= (0x0);
8124 }
8125 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8126 }
8127
8128#endif // CONFIG_STA_SUPPORT //
8129
8130}
8131
8132
8133
8134VOID APSDPeriodicExec(
8135 IN PVOID SystemSpecific1,
8136 IN PVOID FunctionContext,
8137 IN PVOID SystemSpecific2,
8138 IN PVOID SystemSpecific3)
8139{
8140 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
8141
8142 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
8143 return;
8144
8145 pAd->CommonCfg.TriggerTimerCount++;
8146
8147// Driver should not send trigger frame, it should be send by application layer
8148/*
8149 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
8150 && (pAd->CommonCfg.bNeedSendTriggerFrame ||
8151 (((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
8152 {
8153 DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
8154 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
8155 pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
8156 pAd->CommonCfg.TriggerTimerCount = 0;
8157 pAd->CommonCfg.bInServicePeriod = TRUE;
8158 }*/
8159}
8160
8161/*
8162 ========================================================================
8163 Routine Description:
8164 Set/reset MAC registers according to bPiggyBack parameter
8165
8166 Arguments:
8167 pAd - Adapter pointer
8168 bPiggyBack - Enable / Disable Piggy-Back
8169
8170 Return Value:
8171 None
8172
8173 ========================================================================
8174*/
8175VOID RTMPSetPiggyBack(
8176 IN PRTMP_ADAPTER pAd,
8177 IN BOOLEAN bPiggyBack)
8178{
8179 TX_LINK_CFG_STRUC TxLinkCfg;
8180
8181 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
8182
8183 TxLinkCfg.field.TxCFAckEn = bPiggyBack;
8184 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
8185}
8186
8187/*
8188 ========================================================================
8189 Routine Description:
8190 check if this entry need to switch rate automatically
8191
8192 Arguments:
8193 pAd
8194 pEntry
8195
8196 Return Value:
8197 TURE
8198 FALSE
8199
8200 ========================================================================
8201*/
8202BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
8203 IN PRTMP_ADAPTER pAd,
8204 IN PMAC_TABLE_ENTRY pEntry)
8205{
8206 BOOLEAN result = TRUE;
8207
8208
8209#ifdef CONFIG_STA_SUPPORT
8210 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8211 {
8212 // only associated STA counts
8213 if (pEntry && (pEntry->ValidAsCLI) && (pEntry->Sst == SST_ASSOC))
8214 {
8215 result = pAd->StaCfg.bAutoTxRateSwitch;
8216 }
8217 else
8218 result = FALSE;
8219
8220#ifdef QOS_DLS_SUPPORT
8221 if (pEntry && (pEntry->ValidAsDls))
8222 result = pAd->StaCfg.bAutoTxRateSwitch;
8223#endif // QOS_DLS_SUPPORT //
8224 }
8225#endif // CONFIG_STA_SUPPORT //
8226
8227
8228
8229 return result;
8230}
8231
8232
8233BOOLEAN RTMPAutoRateSwitchCheck(
8234 IN PRTMP_ADAPTER pAd)
8235{
8236
8237#ifdef CONFIG_STA_SUPPORT
8238 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8239 {
8240 if (pAd->StaCfg.bAutoTxRateSwitch)
8241 return TRUE;
8242 }
8243#endif // CONFIG_STA_SUPPORT //
8244 return FALSE;
8245}
8246
8247
8248/*
8249 ========================================================================
8250 Routine Description:
8251 check if this entry need to fix tx legacy rate
8252
8253 Arguments:
8254 pAd
8255 pEntry
8256
8257 Return Value:
8258 TURE
8259 FALSE
8260
8261 ========================================================================
8262*/
8263UCHAR RTMPStaFixedTxMode(
8264 IN PRTMP_ADAPTER pAd,
8265 IN PMAC_TABLE_ENTRY pEntry)
8266{
8267 UCHAR tx_mode = FIXED_TXMODE_HT;
8268
8269
8270#ifdef CONFIG_STA_SUPPORT
8271 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8272 {
8273 tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
8274 }
8275#endif // CONFIG_STA_SUPPORT //
8276
8277 return tx_mode;
8278}
8279
8280/*
8281 ========================================================================
8282 Routine Description:
8283 Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
8284
8285 Arguments:
8286 pAd
8287 pEntry
8288
8289 Return Value:
8290 TURE
8291 FALSE
8292
8293 ========================================================================
8294*/
8295VOID RTMPUpdateLegacyTxSetting(
8296 UCHAR fixed_tx_mode,
8297 PMAC_TABLE_ENTRY pEntry)
8298{
8299 HTTRANSMIT_SETTING TransmitSetting;
8300
8301 if (fixed_tx_mode == FIXED_TXMODE_HT)
8302 return;
8303
8304 TransmitSetting.word = 0;
8305
8306 TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
8307 TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
8308
8309 if (fixed_tx_mode == FIXED_TXMODE_CCK)
8310 {
8311 TransmitSetting.field.MODE = MODE_CCK;
8312 // CCK mode allow MCS 0~3
8313 if (TransmitSetting.field.MCS > MCS_3)
8314 TransmitSetting.field.MCS = MCS_3;
8315 }
8316 else
8317 {
8318 TransmitSetting.field.MODE = MODE_OFDM;
8319 // OFDM mode allow MCS 0~7
8320 if (TransmitSetting.field.MCS > MCS_7)
8321 TransmitSetting.field.MCS = MCS_7;
8322 }
8323
8324 if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE)
8325 {
8326 pEntry->HTPhyMode.word = TransmitSetting.word;
8327 DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
8328 pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS));
8329 }
8330}
8331
8332#ifdef CONFIG_STA_SUPPORT
8333/*
8334 ==========================================================================
8335 Description:
8336 dynamic tune BBP R66 to find a balance between sensibility and
8337 noise isolation
8338
8339 IRQL = DISPATCH_LEVEL
8340
8341 ==========================================================================
8342 */
8343VOID AsicStaBbpTuning(
8344 IN PRTMP_ADAPTER pAd)
8345{
8346 UCHAR OrigR66Value = 0, R66;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
8347 CHAR Rssi;
8348
8349 // 2860C did not support Fase CCA, therefore can't tune
8350 if (pAd->MACVersion == 0x28600100)
8351 return;
8352
8353 //
8354 // work as a STA
8355 //
8356 if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) // no R66 tuning when SCANNING
8357 return;
8358
8359 if ((pAd->OpMode == OPMODE_STA)
8360 && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
8361 )
8362 && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
8363 )
8364 {
8365 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
8366 R66 = OrigR66Value;
8367
8368 if (pAd->Antenna.field.RxPath > 1)
8369 Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
8370 else
8371 Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
8372
8373 if (pAd->LatchRfRegs.Channel <= 14)
8374 { //BG band
8375#ifdef RT2870
8376 // RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
8377 // Otherwise, it will have some throughput side effect when low RSSI
8378 if (IS_RT3070(pAd))
8379 {
8380 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8381 {
8382 R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
8383 if (OrigR66Value != R66)
8384 {
8385 RTUSBWriteBBPRegister(pAd, BBP_R66, R66);
8386 }
8387 }
8388 else
8389 {
8390 R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
8391 if (OrigR66Value != R66)
8392 {
8393 RTUSBWriteBBPRegister(pAd, BBP_R66, R66);
8394 }
8395 }
8396 }
8397 else
8398#endif // RT2870 //
8399 {
8400 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8401 {
8402 R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
8403 if (OrigR66Value != R66)
8404 {
8405 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8406 }
8407 }
8408 else
8409 {
8410 R66 = 0x2E + GET_LNA_GAIN(pAd);
8411 if (OrigR66Value != R66)
8412 {
8413 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8414 }
8415 }
8416 }
8417 }
8418 else
8419 { //A band
8420 if (pAd->CommonCfg.BBPCurrentBW == BW_20)
8421 {
8422 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8423 {
8424 R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
8425 if (OrigR66Value != R66)
8426 {
8427 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8428 }
8429 }
8430 else
8431 {
8432 R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3;
8433 if (OrigR66Value != R66)
8434 {
8435 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8436 }
8437 }
8438 }
8439 else
8440 {
8441 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8442 {
8443 R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
8444 if (OrigR66Value != R66)
8445 {
8446 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8447 }
8448 }
8449 else
8450 {
8451 R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3;
8452 if (OrigR66Value != R66)
8453 {
8454 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8455 }
8456 }
8457 }
8458 }
8459
8460
8461 }
8462}
8463#endif // CONFIG_STA_SUPPORT //
8464
8465VOID RTMPSetAGCInitValue(
8466 IN PRTMP_ADAPTER pAd,
8467 IN UCHAR BandWidth)
8468{
8469 UCHAR R66 = 0x30;
8470
8471 if (pAd->LatchRfRegs.Channel <= 14)
8472 { // BG band
8473 R66 = 0x2E + GET_LNA_GAIN(pAd);
8474 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8475 }
8476 else
8477 { //A band
8478 if (BandWidth == BW_20)
8479 {
8480 R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
8481 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8482 }
8483#ifdef DOT11_N_SUPPORT
8484 else
8485 {
8486 R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
8487 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8488 }
8489#endif // DOT11_N_SUPPORT //
8490 }
8491
8492}
8493
8494VOID AsicTurnOffRFClk(
8495 IN PRTMP_ADAPTER pAd,
8496 IN UCHAR Channel)
8497{
8498
8499 // RF R2 bit 18 = 0
8500 UINT32 R1 = 0, R2 = 0, R3 = 0;
8501 UCHAR index;
8502 RTMP_RF_REGS *RFRegTable;
8503
8504 RFRegTable = RF2850RegTable;
8505
8506 switch (pAd->RfIcType)
8507 {
8508 case RFIC_2820:
8509 case RFIC_2850:
8510 case RFIC_2720:
8511 case RFIC_2750:
8512
8513 for (index = 0; index < NUM_OF_2850_CHNL; index++)
8514 {
8515 if (Channel == RFRegTable[index].Channel)
8516 {
8517 R1 = RFRegTable[index].R1 & 0xffffdfff;
8518 R2 = RFRegTable[index].R2 & 0xfffbffff;
8519 R3 = RFRegTable[index].R3 & 0xfff3ffff;
8520
8521 RTMP_RF_IO_WRITE32(pAd, R1);
8522 RTMP_RF_IO_WRITE32(pAd, R2);
8523
8524 // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
8525 // Set RF R2 bit18=0, R3 bit[18:19]=0
8526 //if (pAd->StaCfg.bRadio == FALSE)
8527 if (1)
8528 {
8529 RTMP_RF_IO_WRITE32(pAd, R3);
8530
8531 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
8532 Channel, pAd->RfIcType, R2, R3));
8533 }
8534 else
8535 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
8536 Channel, pAd->RfIcType, R2));
8537 break;
8538 }
8539 }
8540 break;
8541
8542 default:
8543 break;
8544 }
8545}
8546
8547
8548VOID AsicTurnOnRFClk(
8549 IN PRTMP_ADAPTER pAd,
8550 IN UCHAR Channel)
8551{
8552
8553 // RF R2 bit 18 = 0
8554 UINT32 R1 = 0, R2 = 0, R3 = 0;
8555 UCHAR index;
8556 RTMP_RF_REGS *RFRegTable;
8557
8558 RFRegTable = RF2850RegTable;
8559
8560 switch (pAd->RfIcType)
8561 {
8562 case RFIC_2820:
8563 case RFIC_2850:
8564 case RFIC_2720:
8565 case RFIC_2750:
8566
8567 for (index = 0; index < NUM_OF_2850_CHNL; index++)
8568 {
8569 if (Channel == RFRegTable[index].Channel)
8570 {
8571 R3 = pAd->LatchRfRegs.R3;
8572 R3 &= 0xfff3ffff;
8573 R3 |= 0x00080000;
8574 RTMP_RF_IO_WRITE32(pAd, R3);
8575
8576 R1 = RFRegTable[index].R1;
8577 RTMP_RF_IO_WRITE32(pAd, R1);
8578
8579 R2 = RFRegTable[index].R2;
8580 if (pAd->Antenna.field.TxPath == 1)
8581 {
8582 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
8583 }
8584
8585 if (pAd->Antenna.field.RxPath == 2)
8586 {
8587 R2 |= 0x40; // write 1 to off Rxpath.
8588 }
8589 else if (pAd->Antenna.field.RxPath == 1)
8590 {
8591 R2 |= 0x20040; // write 1 to off RxPath
8592 }
8593 RTMP_RF_IO_WRITE32(pAd, R2);
8594
8595 break;
8596 }
8597 }
8598 break;
8599
8600 default:
8601 break;
8602 }
8603
8604 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
8605 Channel,
8606 pAd->RfIcType,
8607 R2));
8608}
8609
diff --git a/drivers/staging/rt2870/common/netif_block.c b/drivers/staging/rt2870/common/netif_block.c
new file mode 100644
index 00000000000..d3f7d087e7f
--- /dev/null
+++ b/drivers/staging/rt2870/common/netif_block.c
@@ -0,0 +1,144 @@
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 APCLI_SUPPORT
99 if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_APCLI)
100 {
101 IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_APCLI) % MAX_APCLI_NUM;
102 NetDev = pAd->ApCfg.ApCliTab[IfIdx].dev;
103 }
104 else
105#endif // APCLI_SUPPORT //
106#ifdef WDS_SUPPORT
107 if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_WDS)
108 {
109 IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_WDS) % MAX_WDS_ENTRY;
110 NetDev = pAd->WdsTab.WdsEntry[IfIdx].dev;
111 }
112 else
113#endif // WDS_SUPPORT //
114 {
115#ifdef MBSS_SUPPORT
116 if (pAd->OpMode == OPMODE_AP)
117 {
118 IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_MBSSID) % MAX_MBSSID_NUM;
119 NetDev = pAd->ApCfg.MBSSID[IfIdx].MSSIDDev;
120 }
121 else
122 {
123 IfIdx = MAIN_MBSSID;
124 NetDev = pAd->net_dev;
125 }
126#else
127 IfIdx = MAIN_MBSSID;
128 NetDev = pAd->net_dev;
129#endif
130 }
131
132 // WMM support 4 software queues.
133 // One software queue full doesn't mean device have no capbility to transmit packet.
134 // So disable block Net-If queue function while WMM enable.
135#ifdef CONFIG_STA_SUPPORT
136 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
137 valid = (pAd->CommonCfg.bWmmCapable == TRUE) ? FALSE : TRUE;
138#endif // CONFIG_STA_SUPPORT //
139
140 if (valid)
141 blockNetIf(&pAd->blockQueueTab[QueIdx], NetDev);
142 return;
143}
144
diff --git a/drivers/staging/rt2870/common/rtmp_init.c b/drivers/staging/rt2870/common/rtmp_init.c
new file mode 100644
index 00000000000..87028fd60bc
--- /dev/null
+++ b/drivers/staging/rt2870/common/rtmp_init.c
@@ -0,0 +1,4132 @@
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 RT2870
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, 0x71},
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_R27, 0x03},
153 {RF_R29, 0x1F},
154};
155#define NUM_RF_REG_PARMS (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR))
156#endif // RT2870 //
157
158//
159// ASIC register initialization sets
160//
161
162RTMP_REG_PAIR MACRegTable[] = {
163#if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200)
164 {BCN_OFFSET0, 0xf8f0e8e0}, /* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */
165 {BCN_OFFSET1, 0x6f77d0c8}, /* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */
166#elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100)
167 {BCN_OFFSET0, 0xece8e4e0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
168 {BCN_OFFSET1, 0xfcf8f4f0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
169#else
170 #error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]!!!
171#endif // HW_BEACON_OFFSET //
172
173 {LEGACY_BASIC_RATE, 0x0000013f}, // Basic rate set bitmap
174 {HT_BASIC_RATE, 0x00008003}, // Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI.
175 {MAC_SYS_CTRL, 0x00}, // 0x1004, , default Disable RX
176 {RX_FILTR_CFG, 0x17f97}, //0x1400 , RX filter control,
177 {BKOFF_SLOT_CFG, 0x209}, // default set short slot time, CC_DELAY_TIME should be 2
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, 0x00182090}, // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT
182 {TX_TIMEOUT_CFG, 0x000a2090}, // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01
183 {MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000}, // 0x3018, MAX frame length. Max PSDU = 16kbytes.
184 {LED_CFG, 0x7f031e46}, // Gary, 2006-08-23
185 {PBF_MAX_PCNT, 0x1F3FBF9F}, //0x1F3f7f9f}, //Jan, 2006/04/20
186 //{TX_RTY_CFG, 0x6bb80408}, // Jan, 2006/11/16
187 {TX_RTY_CFG, 0x47d01f0f}, // Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03
188 {AUTO_RSP_CFG, 0x00000013}, // Initial Auto_Responder, because QA will turn off Auto-Responder
189 {CCK_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
190 {OFDM_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
191#ifdef RT2870
192 {PBF_CFG, 0xf40006}, // Only enable Queue 2
193 {MM40_PROT_CFG, 0x3F44084}, // Initial Auto_Responder, because QA will turn off Auto-Responder
194 {WPDMA_GLO_CFG, 0x00000030},
195#endif // RT2870 //
196 {GF20_PROT_CFG, 0x01744004}, // set 19:18 --> Short NAV for MIMO PS
197 {GF40_PROT_CFG, 0x03F44084},
198 {MM20_PROT_CFG, 0x01744004},
199 {TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f*/ /*0x000024bf*/}, //Extension channel backoff.
200 {TX_RTS_CFG, 0x00092b20},
201//#ifdef WIFI_TEST
202 {EXP_ACK_TIME, 0x002400ca}, // default value
203//#else
204// {EXP_ACK_TIME, 0x005400ca}, // suggested by Gray @ 20070323 for 11n intel-sta throughput
205//#endif // end - WIFI_TEST //
206 {TXOP_HLDR_ET, 0x00000002},
207
208 /* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us
209 is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0
210 and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping
211 will always lost. So we change the SIFS of CCK from 10us to 16us. */
212 {XIFS_TIME_CFG, 0x33a41010},
213 {PWR_PIN_CFG, 0x00000003}, // patch for 2880-E
214};
215
216
217#ifdef CONFIG_STA_SUPPORT
218RTMP_REG_PAIR STAMACRegTable[] = {
219 {WMM_AIFSN_CFG, 0x00002273},
220 {WMM_CWMIN_CFG, 0x00002344},
221 {WMM_CWMAX_CFG, 0x000034aa},
222};
223#endif // CONFIG_STA_SUPPORT //
224
225#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR))
226#ifdef CONFIG_STA_SUPPORT
227#define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR))
228#endif // CONFIG_STA_SUPPORT //
229
230#ifdef RT2870
231//
232// RT2870 Firmware Spec only used 1 oct for version expression
233//
234#define FIRMWARE_MINOR_VERSION 7
235
236#endif // RT2870 //
237
238// New 8k byte firmware size for RT3071/RT3072
239#define FIRMWAREIMAGE_MAX_LENGTH 0x2000
240#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR))
241#define FIRMWARE_MAJOR_VERSION 0
242
243#define FIRMWAREIMAGEV1_LENGTH 0x1000
244#define FIRMWAREIMAGEV2_LENGTH 0x1000
245
246
247
248/*
249 ========================================================================
250
251 Routine Description:
252 Allocate RTMP_ADAPTER data block and do some initialization
253
254 Arguments:
255 Adapter Pointer to our adapter
256
257 Return Value:
258 NDIS_STATUS_SUCCESS
259 NDIS_STATUS_FAILURE
260
261 IRQL = PASSIVE_LEVEL
262
263 Note:
264
265 ========================================================================
266*/
267NDIS_STATUS RTMPAllocAdapterBlock(
268 IN PVOID handle,
269 OUT PRTMP_ADAPTER *ppAdapter)
270{
271 PRTMP_ADAPTER pAd;
272 NDIS_STATUS Status;
273 INT index;
274 UCHAR *pBeaconBuf = NULL;
275
276 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n"));
277
278 *ppAdapter = NULL;
279
280 do
281 {
282 // Allocate RTMP_ADAPTER memory block
283 pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG);
284 if (pBeaconBuf == NULL)
285 {
286 Status = NDIS_STATUS_FAILURE;
287 DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n"));
288 break;
289 }
290
291 Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd);
292 if (Status != NDIS_STATUS_SUCCESS)
293 {
294 DBGPRINT_ERR(("Failed to allocate memory - ADAPTER\n"));
295 break;
296 }
297 pAd->BeaconBuf = pBeaconBuf;
298 printk("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER));
299
300
301 // Init spin locks
302 NdisAllocateSpinLock(&pAd->MgmtRingLock);
303
304 for (index =0 ; index < NUM_OF_TX_RING; index++)
305 {
306 NdisAllocateSpinLock(&pAd->TxSwQueueLock[index]);
307 NdisAllocateSpinLock(&pAd->DeQueueLock[index]);
308 pAd->DeQueueRunning[index] = FALSE;
309 }
310
311 NdisAllocateSpinLock(&pAd->irq_lock);
312
313 } while (FALSE);
314
315 if ((Status != NDIS_STATUS_SUCCESS) && (pBeaconBuf))
316 kfree(pBeaconBuf);
317
318 *ppAdapter = pAd;
319
320 DBGPRINT_S(Status, ("<-- RTMPAllocAdapterBlock, Status=%x\n", Status));
321 return Status;
322}
323
324/*
325 ========================================================================
326
327 Routine Description:
328 Read initial Tx power per MCS and BW from EEPROM
329
330 Arguments:
331 Adapter Pointer to our adapter
332
333 Return Value:
334 None
335
336 IRQL = PASSIVE_LEVEL
337
338 Note:
339
340 ========================================================================
341*/
342VOID RTMPReadTxPwrPerRate(
343 IN PRTMP_ADAPTER pAd)
344{
345 ULONG data, Adata, Gdata;
346 USHORT i, value, value2;
347 INT Apwrdelta, Gpwrdelta;
348 UCHAR t1,t2,t3,t4;
349 BOOLEAN bValid, bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
350
351 //
352 // Get power delta for 20MHz and 40MHz.
353 //
354 DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n"));
355 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2);
356 Apwrdelta = 0;
357 Gpwrdelta = 0;
358
359 if ((value2 & 0xff) != 0xff)
360 {
361 if ((value2 & 0x80))
362 Gpwrdelta = (value2&0xf);
363
364 if ((value2 & 0x40))
365 bGpwrdeltaMinus = FALSE;
366 else
367 bGpwrdeltaMinus = TRUE;
368 }
369 if ((value2 & 0xff00) != 0xff00)
370 {
371 if ((value2 & 0x8000))
372 Apwrdelta = ((value2&0xf00)>>8);
373
374 if ((value2 & 0x4000))
375 bApwrdeltaMinus = FALSE;
376 else
377 bApwrdeltaMinus = TRUE;
378 }
379 DBGPRINT(RT_DEBUG_TRACE, ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta));
380
381 //
382 // Get Txpower per MCS for 20MHz in 2.4G.
383 //
384 for (i=0; i<5; i++)
385 {
386 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4, value);
387 data = value;
388 if (bApwrdeltaMinus == FALSE)
389 {
390 t1 = (value&0xf)+(Apwrdelta);
391 if (t1 > 0xf)
392 t1 = 0xf;
393 t2 = ((value&0xf0)>>4)+(Apwrdelta);
394 if (t2 > 0xf)
395 t2 = 0xf;
396 t3 = ((value&0xf00)>>8)+(Apwrdelta);
397 if (t3 > 0xf)
398 t3 = 0xf;
399 t4 = ((value&0xf000)>>12)+(Apwrdelta);
400 if (t4 > 0xf)
401 t4 = 0xf;
402 }
403 else
404 {
405 if ((value&0xf) > Apwrdelta)
406 t1 = (value&0xf)-(Apwrdelta);
407 else
408 t1 = 0;
409 if (((value&0xf0)>>4) > Apwrdelta)
410 t2 = ((value&0xf0)>>4)-(Apwrdelta);
411 else
412 t2 = 0;
413 if (((value&0xf00)>>8) > Apwrdelta)
414 t3 = ((value&0xf00)>>8)-(Apwrdelta);
415 else
416 t3 = 0;
417 if (((value&0xf000)>>12) > Apwrdelta)
418 t4 = ((value&0xf000)>>12)-(Apwrdelta);
419 else
420 t4 = 0;
421 }
422 Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
423 if (bGpwrdeltaMinus == FALSE)
424 {
425 t1 = (value&0xf)+(Gpwrdelta);
426 if (t1 > 0xf)
427 t1 = 0xf;
428 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
429 if (t2 > 0xf)
430 t2 = 0xf;
431 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
432 if (t3 > 0xf)
433 t3 = 0xf;
434 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
435 if (t4 > 0xf)
436 t4 = 0xf;
437 }
438 else
439 {
440 if ((value&0xf) > Gpwrdelta)
441 t1 = (value&0xf)-(Gpwrdelta);
442 else
443 t1 = 0;
444 if (((value&0xf0)>>4) > Gpwrdelta)
445 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
446 else
447 t2 = 0;
448 if (((value&0xf00)>>8) > Gpwrdelta)
449 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
450 else
451 t3 = 0;
452 if (((value&0xf000)>>12) > Gpwrdelta)
453 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
454 else
455 t4 = 0;
456 }
457 Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
458
459 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4 + 2, value);
460 if (bApwrdeltaMinus == FALSE)
461 {
462 t1 = (value&0xf)+(Apwrdelta);
463 if (t1 > 0xf)
464 t1 = 0xf;
465 t2 = ((value&0xf0)>>4)+(Apwrdelta);
466 if (t2 > 0xf)
467 t2 = 0xf;
468 t3 = ((value&0xf00)>>8)+(Apwrdelta);
469 if (t3 > 0xf)
470 t3 = 0xf;
471 t4 = ((value&0xf000)>>12)+(Apwrdelta);
472 if (t4 > 0xf)
473 t4 = 0xf;
474 }
475 else
476 {
477 if ((value&0xf) > Apwrdelta)
478 t1 = (value&0xf)-(Apwrdelta);
479 else
480 t1 = 0;
481 if (((value&0xf0)>>4) > Apwrdelta)
482 t2 = ((value&0xf0)>>4)-(Apwrdelta);
483 else
484 t2 = 0;
485 if (((value&0xf00)>>8) > Apwrdelta)
486 t3 = ((value&0xf00)>>8)-(Apwrdelta);
487 else
488 t3 = 0;
489 if (((value&0xf000)>>12) > Apwrdelta)
490 t4 = ((value&0xf000)>>12)-(Apwrdelta);
491 else
492 t4 = 0;
493 }
494 Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
495 if (bGpwrdeltaMinus == FALSE)
496 {
497 t1 = (value&0xf)+(Gpwrdelta);
498 if (t1 > 0xf)
499 t1 = 0xf;
500 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
501 if (t2 > 0xf)
502 t2 = 0xf;
503 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
504 if (t3 > 0xf)
505 t3 = 0xf;
506 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
507 if (t4 > 0xf)
508 t4 = 0xf;
509 }
510 else
511 {
512 if ((value&0xf) > Gpwrdelta)
513 t1 = (value&0xf)-(Gpwrdelta);
514 else
515 t1 = 0;
516 if (((value&0xf0)>>4) > Gpwrdelta)
517 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
518 else
519 t2 = 0;
520 if (((value&0xf00)>>8) > Gpwrdelta)
521 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
522 else
523 t3 = 0;
524 if (((value&0xf000)>>12) > Gpwrdelta)
525 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
526 else
527 t4 = 0;
528 }
529 Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
530 data |= (value<<16);
531
532 pAd->Tx20MPwrCfgABand[i] = pAd->Tx40MPwrCfgABand[i] = Adata;
533 pAd->Tx20MPwrCfgGBand[i] = pAd->Tx40MPwrCfgGBand[i] = Gdata;
534
535 if (data != 0xffffffff)
536 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data);
537 DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%lx, Adata = %lx, Gdata = %lx \n", data, Adata, Gdata));
538 }
539
540 //
541 // Check this block is valid for 40MHz in 2.4G. If invalid, use parameter for 20MHz in 2.4G
542 //
543 bValid = TRUE;
544 for (i=0; i<6; i++)
545 {
546 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + 2 + i*2, value);
547 if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
548 {
549 bValid = FALSE;
550 break;
551 }
552 }
553
554 //
555 // Get Txpower per MCS for 40MHz in 2.4G.
556 //
557 if (bValid)
558 {
559 for (i=0; i<4; i++)
560 {
561 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4, value);
562 if (bGpwrdeltaMinus == FALSE)
563 {
564 t1 = (value&0xf)+(Gpwrdelta);
565 if (t1 > 0xf)
566 t1 = 0xf;
567 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
568 if (t2 > 0xf)
569 t2 = 0xf;
570 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
571 if (t3 > 0xf)
572 t3 = 0xf;
573 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
574 if (t4 > 0xf)
575 t4 = 0xf;
576 }
577 else
578 {
579 if ((value&0xf) > Gpwrdelta)
580 t1 = (value&0xf)-(Gpwrdelta);
581 else
582 t1 = 0;
583 if (((value&0xf0)>>4) > Gpwrdelta)
584 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
585 else
586 t2 = 0;
587 if (((value&0xf00)>>8) > Gpwrdelta)
588 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
589 else
590 t3 = 0;
591 if (((value&0xf000)>>12) > Gpwrdelta)
592 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
593 else
594 t4 = 0;
595 }
596 Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
597
598 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4 + 2, value);
599 if (bGpwrdeltaMinus == FALSE)
600 {
601 t1 = (value&0xf)+(Gpwrdelta);
602 if (t1 > 0xf)
603 t1 = 0xf;
604 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
605 if (t2 > 0xf)
606 t2 = 0xf;
607 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
608 if (t3 > 0xf)
609 t3 = 0xf;
610 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
611 if (t4 > 0xf)
612 t4 = 0xf;
613 }
614 else
615 {
616 if ((value&0xf) > Gpwrdelta)
617 t1 = (value&0xf)-(Gpwrdelta);
618 else
619 t1 = 0;
620 if (((value&0xf0)>>4) > Gpwrdelta)
621 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
622 else
623 t2 = 0;
624 if (((value&0xf00)>>8) > Gpwrdelta)
625 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
626 else
627 t3 = 0;
628 if (((value&0xf000)>>12) > Gpwrdelta)
629 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
630 else
631 t4 = 0;
632 }
633 Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
634
635 if (i == 0)
636 pAd->Tx40MPwrCfgGBand[i+1] = (pAd->Tx40MPwrCfgGBand[i+1] & 0x0000FFFF) | (Gdata & 0xFFFF0000);
637 else
638 pAd->Tx40MPwrCfgGBand[i+1] = Gdata;
639
640 DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 2.4G band, Gdata = %lx \n", Gdata));
641 }
642 }
643
644 //
645 // Check this block is valid for 20MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
646 //
647 bValid = TRUE;
648 for (i=0; i<8; i++)
649 {
650 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + 2 + i*2, value);
651 if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
652 {
653 bValid = FALSE;
654 break;
655 }
656 }
657
658 //
659 // Get Txpower per MCS for 20MHz in 5G.
660 //
661 if (bValid)
662 {
663 for (i=0; i<5; i++)
664 {
665 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4, value);
666 if (bApwrdeltaMinus == FALSE)
667 {
668 t1 = (value&0xf)+(Apwrdelta);
669 if (t1 > 0xf)
670 t1 = 0xf;
671 t2 = ((value&0xf0)>>4)+(Apwrdelta);
672 if (t2 > 0xf)
673 t2 = 0xf;
674 t3 = ((value&0xf00)>>8)+(Apwrdelta);
675 if (t3 > 0xf)
676 t3 = 0xf;
677 t4 = ((value&0xf000)>>12)+(Apwrdelta);
678 if (t4 > 0xf)
679 t4 = 0xf;
680 }
681 else
682 {
683 if ((value&0xf) > Apwrdelta)
684 t1 = (value&0xf)-(Apwrdelta);
685 else
686 t1 = 0;
687 if (((value&0xf0)>>4) > Apwrdelta)
688 t2 = ((value&0xf0)>>4)-(Apwrdelta);
689 else
690 t2 = 0;
691 if (((value&0xf00)>>8) > Apwrdelta)
692 t3 = ((value&0xf00)>>8)-(Apwrdelta);
693 else
694 t3 = 0;
695 if (((value&0xf000)>>12) > Apwrdelta)
696 t4 = ((value&0xf000)>>12)-(Apwrdelta);
697 else
698 t4 = 0;
699 }
700 Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
701
702 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4 + 2, value);
703 if (bApwrdeltaMinus == FALSE)
704 {
705 t1 = (value&0xf)+(Apwrdelta);
706 if (t1 > 0xf)
707 t1 = 0xf;
708 t2 = ((value&0xf0)>>4)+(Apwrdelta);
709 if (t2 > 0xf)
710 t2 = 0xf;
711 t3 = ((value&0xf00)>>8)+(Apwrdelta);
712 if (t3 > 0xf)
713 t3 = 0xf;
714 t4 = ((value&0xf000)>>12)+(Apwrdelta);
715 if (t4 > 0xf)
716 t4 = 0xf;
717 }
718 else
719 {
720 if ((value&0xf) > Apwrdelta)
721 t1 = (value&0xf)-(Apwrdelta);
722 else
723 t1 = 0;
724 if (((value&0xf0)>>4) > Apwrdelta)
725 t2 = ((value&0xf0)>>4)-(Apwrdelta);
726 else
727 t2 = 0;
728 if (((value&0xf00)>>8) > Apwrdelta)
729 t3 = ((value&0xf00)>>8)-(Apwrdelta);
730 else
731 t3 = 0;
732 if (((value&0xf000)>>12) > Apwrdelta)
733 t4 = ((value&0xf000)>>12)-(Apwrdelta);
734 else
735 t4 = 0;
736 }
737 Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
738
739 if (i == 0)
740 pAd->Tx20MPwrCfgABand[i] = (pAd->Tx20MPwrCfgABand[i] & 0x0000FFFF) | (Adata & 0xFFFF0000);
741 else
742 pAd->Tx20MPwrCfgABand[i] = Adata;
743
744 DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 5GHz band, Adata = %lx \n", Adata));
745 }
746 }
747
748 //
749 // Check this block is valid for 40MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
750 //
751 bValid = TRUE;
752 for (i=0; i<6; i++)
753 {
754 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + 2 + i*2, value);
755 if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
756 {
757 bValid = FALSE;
758 break;
759 }
760 }
761
762 //
763 // Get Txpower per MCS for 40MHz in 5G.
764 //
765 if (bValid)
766 {
767 for (i=0; i<4; i++)
768 {
769 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4, value);
770 if (bApwrdeltaMinus == FALSE)
771 {
772 t1 = (value&0xf)+(Apwrdelta);
773 if (t1 > 0xf)
774 t1 = 0xf;
775 t2 = ((value&0xf0)>>4)+(Apwrdelta);
776 if (t2 > 0xf)
777 t2 = 0xf;
778 t3 = ((value&0xf00)>>8)+(Apwrdelta);
779 if (t3 > 0xf)
780 t3 = 0xf;
781 t4 = ((value&0xf000)>>12)+(Apwrdelta);
782 if (t4 > 0xf)
783 t4 = 0xf;
784 }
785 else
786 {
787 if ((value&0xf) > Apwrdelta)
788 t1 = (value&0xf)-(Apwrdelta);
789 else
790 t1 = 0;
791 if (((value&0xf0)>>4) > Apwrdelta)
792 t2 = ((value&0xf0)>>4)-(Apwrdelta);
793 else
794 t2 = 0;
795 if (((value&0xf00)>>8) > Apwrdelta)
796 t3 = ((value&0xf00)>>8)-(Apwrdelta);
797 else
798 t3 = 0;
799 if (((value&0xf000)>>12) > Apwrdelta)
800 t4 = ((value&0xf000)>>12)-(Apwrdelta);
801 else
802 t4 = 0;
803 }
804 Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
805
806 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4 + 2, value);
807 if (bApwrdeltaMinus == FALSE)
808 {
809 t1 = (value&0xf)+(Apwrdelta);
810 if (t1 > 0xf)
811 t1 = 0xf;
812 t2 = ((value&0xf0)>>4)+(Apwrdelta);
813 if (t2 > 0xf)
814 t2 = 0xf;
815 t3 = ((value&0xf00)>>8)+(Apwrdelta);
816 if (t3 > 0xf)
817 t3 = 0xf;
818 t4 = ((value&0xf000)>>12)+(Apwrdelta);
819 if (t4 > 0xf)
820 t4 = 0xf;
821 }
822 else
823 {
824 if ((value&0xf) > Apwrdelta)
825 t1 = (value&0xf)-(Apwrdelta);
826 else
827 t1 = 0;
828 if (((value&0xf0)>>4) > Apwrdelta)
829 t2 = ((value&0xf0)>>4)-(Apwrdelta);
830 else
831 t2 = 0;
832 if (((value&0xf00)>>8) > Apwrdelta)
833 t3 = ((value&0xf00)>>8)-(Apwrdelta);
834 else
835 t3 = 0;
836 if (((value&0xf000)>>12) > Apwrdelta)
837 t4 = ((value&0xf000)>>12)-(Apwrdelta);
838 else
839 t4 = 0;
840 }
841 Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
842
843 if (i == 0)
844 pAd->Tx40MPwrCfgABand[i+1] = (pAd->Tx40MPwrCfgABand[i+1] & 0x0000FFFF) | (Adata & 0xFFFF0000);
845 else
846 pAd->Tx40MPwrCfgABand[i+1] = Adata;
847
848 DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 5GHz band, Adata = %lx \n", Adata));
849 }
850 }
851}
852
853
854/*
855 ========================================================================
856
857 Routine Description:
858 Read initial channel power parameters from EEPROM
859
860 Arguments:
861 Adapter Pointer to our adapter
862
863 Return Value:
864 None
865
866 IRQL = PASSIVE_LEVEL
867
868 Note:
869
870 ========================================================================
871*/
872VOID RTMPReadChannelPwr(
873 IN PRTMP_ADAPTER pAd)
874{
875 UCHAR i, choffset;
876 EEPROM_TX_PWR_STRUC Power;
877 EEPROM_TX_PWR_STRUC Power2;
878
879 // Read Tx power value for all channels
880 // Value from 1 - 0x7f. Default value is 24.
881 // Power value : 2.4G 0x00 (0) ~ 0x1F (31)
882 // : 5.5G 0xF9 (-7) ~ 0x0F (15)
883
884 // 0. 11b/g, ch1 - ch 14
885 for (i = 0; i < 7; i++)
886 {
887// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2);
888// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2);
889 RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2, Power.word);
890 RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2, Power2.word);
891 pAd->TxPower[i * 2].Channel = i * 2 + 1;
892 pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2;
893
894 if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0))
895 pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER;
896 else
897 pAd->TxPower[i * 2].Power = Power.field.Byte0;
898
899 if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0))
900 pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER;
901 else
902 pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1;
903
904 if ((Power2.field.Byte0 > 31) || (Power2.field.Byte0 < 0))
905 pAd->TxPower[i * 2].Power2 = DEFAULT_RF_TX_POWER;
906 else
907 pAd->TxPower[i * 2].Power2 = Power2.field.Byte0;
908
909 if ((Power2.field.Byte1 > 31) || (Power2.field.Byte1 < 0))
910 pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER;
911 else
912 pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1;
913 }
914
915 // 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz)
916 // 1.1 Fill up channel
917 choffset = 14;
918 for (i = 0; i < 4; i++)
919 {
920 pAd->TxPower[3 * i + choffset + 0].Channel = 36 + i * 8 + 0;
921 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
922 pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
923
924 pAd->TxPower[3 * i + choffset + 1].Channel = 36 + i * 8 + 2;
925 pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
926 pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
927
928 pAd->TxPower[3 * i + choffset + 2].Channel = 36 + i * 8 + 4;
929 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
930 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
931 }
932
933 // 1.2 Fill up power
934 for (i = 0; i < 6; i++)
935 {
936// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2);
937// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2);
938 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2, Power.word);
939 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2, Power2.word);
940
941 if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
942 pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
943
944 if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
945 pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
946
947 if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
948 pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
949
950 if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
951 pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
952 }
953
954 // 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)
955 // 2.1 Fill up channel
956 choffset = 14 + 12;
957 for (i = 0; i < 5; i++)
958 {
959 pAd->TxPower[3 * i + choffset + 0].Channel = 100 + i * 8 + 0;
960 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
961 pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
962
963 pAd->TxPower[3 * i + choffset + 1].Channel = 100 + i * 8 + 2;
964 pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
965 pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
966
967 pAd->TxPower[3 * i + choffset + 2].Channel = 100 + i * 8 + 4;
968 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
969 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
970 }
971 pAd->TxPower[3 * 5 + choffset + 0].Channel = 140;
972 pAd->TxPower[3 * 5 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
973 pAd->TxPower[3 * 5 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
974
975 // 2.2 Fill up power
976 for (i = 0; i < 8; i++)
977 {
978// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2);
979// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2);
980 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
981 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
982
983 if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
984 pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
985
986 if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
987 pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
988
989 if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
990 pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
991
992 if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
993 pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
994 }
995
996 // 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165 (including central frequency in BW 40MHz)
997 // 3.1 Fill up channel
998 choffset = 14 + 12 + 16;
999 for (i = 0; i < 2; i++)
1000 {
1001 pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0;
1002 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
1003 pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
1004
1005 pAd->TxPower[3 * i + choffset + 1].Channel = 149 + i * 8 + 2;
1006 pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
1007 pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
1008
1009 pAd->TxPower[3 * i + choffset + 2].Channel = 149 + i * 8 + 4;
1010 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
1011 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
1012 }
1013 pAd->TxPower[3 * 2 + choffset + 0].Channel = 165;
1014 pAd->TxPower[3 * 2 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
1015 pAd->TxPower[3 * 2 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
1016
1017 // 3.2 Fill up power
1018 for (i = 0; i < 4; i++)
1019 {
1020// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2);
1021// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2);
1022 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
1023 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
1024
1025 if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
1026 pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
1027
1028 if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
1029 pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
1030
1031 if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
1032 pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
1033
1034 if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
1035 pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
1036 }
1037
1038 // 4. Print and Debug
1039 choffset = 14 + 12 + 16 + 7;
1040
1041}
1042
1043/*
1044 ========================================================================
1045
1046 Routine Description:
1047 Read the following from the registry
1048 1. All the parameters
1049 2. NetworkAddres
1050
1051 Arguments:
1052 Adapter Pointer to our adapter
1053 WrapperConfigurationContext For use by NdisOpenConfiguration
1054
1055 Return Value:
1056 NDIS_STATUS_SUCCESS
1057 NDIS_STATUS_FAILURE
1058 NDIS_STATUS_RESOURCES
1059
1060 IRQL = PASSIVE_LEVEL
1061
1062 Note:
1063
1064 ========================================================================
1065*/
1066NDIS_STATUS NICReadRegParameters(
1067 IN PRTMP_ADAPTER pAd,
1068 IN NDIS_HANDLE WrapperConfigurationContext
1069 )
1070{
1071 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1072 DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
1073 return Status;
1074}
1075
1076
1077#ifdef RT2870
1078/*
1079 ========================================================================
1080
1081 Routine Description:
1082 For RF filter calibration purpose
1083
1084 Arguments:
1085 pAd Pointer to our adapter
1086
1087 Return Value:
1088 None
1089
1090 IRQL = PASSIVE_LEVEL
1091
1092 ========================================================================
1093*/
1094VOID RTUSBFilterCalibration(
1095 IN PRTMP_ADAPTER pAd)
1096{
1097 UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue;
1098 UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0;
1099 UCHAR RF_R24_Value = 0;
1100
1101 // Give bbp filter initial value
1102 pAd->Mlme.CaliBW20RfR24 = 0x16;
1103 pAd->Mlme.CaliBW40RfR24 = 0x36; //Bit[5] must be 1 for BW 40
1104
1105 do
1106 {
1107 if (loop == 1) //BandWidth = 40 MHz
1108 {
1109 // Write 0x27 to RF_R24 to program filter
1110 RF_R24_Value = 0x27;
1111 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
1112 FilterTarget = 0x19;
1113
1114 // when calibrate BW40, BBP mask must set to BW40.
1115 RTUSBReadBBPRegister(pAd, BBP_R4, &BBPValue);
1116 BBPValue&= (~0x18);
1117 BBPValue|= (0x10);
1118 RTUSBWriteBBPRegister(pAd, BBP_R4, BBPValue);
1119 }
1120 else //BandWidth = 20 MHz
1121 {
1122 // Write 0x07 to RF_R24 to program filter
1123 RF_R24_Value = 0x07;
1124 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
1125 FilterTarget = 0x16;
1126 }
1127
1128 // Write 0x01 to RF_R22 to enable baseband loopback mode
1129 RT30xxReadRFRegister(pAd, RF_R22, &value);
1130 value |= 0x01;
1131 RT30xxWriteRFRegister(pAd, RF_R22, value);
1132
1133 // Write 0x00 to BBP_R24 to set power & frequency of passband test tone
1134 RTUSBWriteBBPRegister(pAd, BBP_R24, 0);
1135
1136 do
1137 {
1138 // Write 0x90 to BBP_R25 to transmit test tone
1139 RTUSBWriteBBPRegister(pAd, BBP_R25, 0x90);
1140
1141 RTMPusecDelay(1000);
1142 // Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
1143 RTUSBReadBBPRegister(pAd, BBP_R55, &value);
1144 R55x = value & 0xFF;
1145
1146 } while ((ReTry++ < 100) && (R55x == 0));
1147
1148 // Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
1149 RTUSBWriteBBPRegister(pAd, BBP_R24, 0x06);
1150
1151 while(TRUE)
1152 {
1153 // Write 0x90 to BBP_R25 to transmit test tone
1154 RTUSBWriteBBPRegister(pAd, BBP_R25, 0x90);
1155
1156 //We need to wait for calibration
1157 RTMPusecDelay(1000);
1158 RTUSBReadBBPRegister(pAd, BBP_R55, &value);
1159 value &= 0xFF;
1160 if ((R55x - value) < FilterTarget)
1161 {
1162 RF_R24_Value ++;
1163 }
1164 else if ((R55x - value) == FilterTarget)
1165 {
1166 RF_R24_Value ++;
1167 count ++;
1168 }
1169 else
1170 {
1171 break;
1172 }
1173
1174 // prevent infinite loop cause driver hang.
1175 if (loopcnt++ > 100)
1176 {
1177 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
1178 break;
1179 }
1180
1181 // Write RF_R24 to program filter
1182 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
1183 }
1184
1185 if (count > 0)
1186 {
1187 RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
1188 }
1189
1190 // Store for future usage
1191 if (loopcnt < 100)
1192 {
1193 if (loop++ == 0)
1194 {
1195 //BandWidth = 20 MHz
1196 pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
1197 }
1198 else
1199 {
1200 //BandWidth = 40 MHz
1201 pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
1202 break;
1203 }
1204 }
1205 else
1206 break;
1207
1208 RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
1209
1210 // reset count
1211 count = 0;
1212 } while(TRUE);
1213
1214 //
1215 // Set back to initial state
1216 //
1217 RTUSBWriteBBPRegister(pAd, BBP_R24, 0);
1218
1219 RT30xxReadRFRegister(pAd, RF_R22, &value);
1220 value &= ~(0x01);
1221 RT30xxWriteRFRegister(pAd, RF_R22, value);
1222
1223 // set BBP back to BW20
1224 RTUSBReadBBPRegister(pAd, BBP_R4, &BBPValue);
1225 BBPValue&= (~0x18);
1226 RTUSBWriteBBPRegister(pAd, BBP_R4, BBPValue);
1227
1228 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
1229}
1230
1231
1232VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd)
1233{
1234 INT i;
1235 // Driver must read EEPROM to get RfIcType before initial RF registers
1236 // Initialize RF register to default value
1237 if (IS_RT3070(pAd) && ((pAd->RfIcType == RFIC_3020) ||(pAd->RfIcType == RFIC_2020)))
1238 {
1239 // Init RF calibration
1240 // Driver should toggle RF R30 bit7 before init RF registers
1241 ULONG RfReg = 0;
1242 RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
1243 RfReg |= 0x80;
1244 RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
1245 RTMPusecDelay(1000);
1246 RfReg &= 0x7F;
1247 RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
1248
1249 // Initialize RF register to default value
1250 for (i = 0; i < NUM_RF_REG_PARMS; i++)
1251 {
1252 RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
1253 }
1254
1255 //For RF filter Calibration
1256 RTUSBFilterCalibration(pAd);
1257 }
1258
1259}
1260#endif // RT2870 //
1261
1262
1263/*
1264 ========================================================================
1265
1266 Routine Description:
1267 Read initial parameters from EEPROM
1268
1269 Arguments:
1270 Adapter Pointer to our adapter
1271
1272 Return Value:
1273 None
1274
1275 IRQL = PASSIVE_LEVEL
1276
1277 Note:
1278
1279 ========================================================================
1280*/
1281VOID NICReadEEPROMParameters(
1282 IN PRTMP_ADAPTER pAd,
1283 IN PUCHAR mac_addr)
1284{
1285 UINT32 data = 0;
1286 USHORT i, value, value2;
1287 UCHAR TmpPhy;
1288 EEPROM_TX_PWR_STRUC Power;
1289 EEPROM_VERSION_STRUC Version;
1290 EEPROM_ANTENNA_STRUC Antenna;
1291 EEPROM_NIC_CONFIG2_STRUC NicConfig2;
1292
1293 DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n"));
1294
1295 // Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8
1296 RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
1297 DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data));
1298
1299 if((data & 0x30) == 0)
1300 pAd->EEPROMAddressNum = 6; // 93C46
1301 else if((data & 0x30) == 0x10)
1302 pAd->EEPROMAddressNum = 8; // 93C66
1303 else
1304 pAd->EEPROMAddressNum = 8; // 93C86
1305 DBGPRINT(RT_DEBUG_TRACE, ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum ));
1306
1307 // RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize
1308 // MAC address registers according to E2PROM setting
1309 if (mac_addr == NULL ||
1310 strlen(mac_addr) != 17 ||
1311 mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' ||
1312 mac_addr[11] != ':' || mac_addr[14] != ':')
1313 {
1314 USHORT Addr01,Addr23,Addr45 ;
1315
1316 RT28xx_EEPROM_READ16(pAd, 0x04, Addr01);
1317 RT28xx_EEPROM_READ16(pAd, 0x06, Addr23);
1318 RT28xx_EEPROM_READ16(pAd, 0x08, Addr45);
1319
1320 pAd->PermanentAddress[0] = (UCHAR)(Addr01 & 0xff);
1321 pAd->PermanentAddress[1] = (UCHAR)(Addr01 >> 8);
1322 pAd->PermanentAddress[2] = (UCHAR)(Addr23 & 0xff);
1323 pAd->PermanentAddress[3] = (UCHAR)(Addr23 >> 8);
1324 pAd->PermanentAddress[4] = (UCHAR)(Addr45 & 0xff);
1325 pAd->PermanentAddress[5] = (UCHAR)(Addr45 >> 8);
1326
1327 DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from E2PROM \n"));
1328 }
1329 else
1330 {
1331 INT j;
1332 PUCHAR macptr;
1333
1334 macptr = mac_addr;
1335
1336 for (j=0; j<MAC_ADDR_LEN; j++)
1337 {
1338 AtoH(macptr, &pAd->PermanentAddress[j], 1);
1339 macptr=macptr+3;
1340 }
1341
1342 DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from module parameter \n"));
1343 }
1344
1345
1346 {
1347#if 0
1348 USHORT Addr01,Addr23,Addr45 ;
1349
1350 Addr01=RTMP_EEPROM_READ16(pAd, 0x04);
1351 Addr23=RTMP_EEPROM_READ16(pAd, 0x06);
1352 Addr45=RTMP_EEPROM_READ16(pAd, 0x08);
1353
1354 pAd->PermanentAddress[0] = (UCHAR)(Addr01 & 0xff);
1355 pAd->PermanentAddress[1] = (UCHAR)(Addr01 >> 8);
1356 pAd->PermanentAddress[2] = (UCHAR)(Addr23 & 0xff);
1357 pAd->PermanentAddress[3] = (UCHAR)(Addr23 >> 8);
1358 pAd->PermanentAddress[4] = (UCHAR)(Addr45 & 0xff);
1359 pAd->PermanentAddress[5] = (UCHAR)(Addr45 >> 8);
1360#endif
1361 //more conveninet to test mbssid, so ap's bssid &0xf1
1362 if (pAd->PermanentAddress[0] == 0xff)
1363 pAd->PermanentAddress[0] = RandomByte(pAd)&0xf8;
1364
1365 //if (pAd->PermanentAddress[5] == 0xff)
1366 // pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8;
1367
1368 DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
1369 pAd->PermanentAddress[0], pAd->PermanentAddress[1],
1370 pAd->PermanentAddress[2], pAd->PermanentAddress[3],
1371 pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
1372 if (pAd->bLocalAdminMAC == FALSE)
1373 {
1374 MAC_DW0_STRUC csr2;
1375 MAC_DW1_STRUC csr3;
1376 COPY_MAC_ADDR(pAd->CurrentAddress, pAd->PermanentAddress);
1377 csr2.field.Byte0 = pAd->CurrentAddress[0];
1378 csr2.field.Byte1 = pAd->CurrentAddress[1];
1379 csr2.field.Byte2 = pAd->CurrentAddress[2];
1380 csr2.field.Byte3 = pAd->CurrentAddress[3];
1381 RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word);
1382 csr3.word = 0;
1383 csr3.field.Byte4 = pAd->CurrentAddress[4];
1384 csr3.field.Byte5 = pAd->CurrentAddress[5];
1385 csr3.field.U2MeMask = 0xff;
1386 RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word);
1387 DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
1388 pAd->PermanentAddress[0], pAd->PermanentAddress[1],
1389 pAd->PermanentAddress[2], pAd->PermanentAddress[3],
1390 pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
1391 }
1392 }
1393
1394 // if not return early. cause fail at emulation.
1395 // Init the channel number for TX channel power
1396 RTMPReadChannelPwr(pAd);
1397
1398 // if E2PROM version mismatch with driver's expectation, then skip
1399 // all subsequent E2RPOM retieval and set a system error bit to notify GUI
1400 RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word);
1401 pAd->EepromVersion = Version.field.Version + Version.field.FaeReleaseNumber * 256;
1402 DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: Version = %d, FAE release #%d\n", Version.field.Version, Version.field.FaeReleaseNumber));
1403
1404 if (Version.field.Version > VALID_EEPROM_VERSION)
1405 {
1406 DBGPRINT_ERR(("E2PROM: WRONG VERSION 0x%x, should be %d\n",Version.field.Version, VALID_EEPROM_VERSION));
1407 /*pAd->SystemErrorBitmap |= 0x00000001;
1408
1409 // hard-code default value when no proper E2PROM installed
1410 pAd->bAutoTxAgcA = FALSE;
1411 pAd->bAutoTxAgcG = FALSE;
1412
1413 // Default the channel power
1414 for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
1415 pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
1416
1417 // Default the channel power
1418 for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++)
1419 pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER;
1420
1421 for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
1422 pAd->EEPROMDefaultValue[i] = 0xffff;
1423 return; */
1424 }
1425
1426 // Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd
1427 RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value);
1428 pAd->EEPROMDefaultValue[0] = value;
1429
1430 RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value);
1431 pAd->EEPROMDefaultValue[1] = value;
1432
1433 RT28xx_EEPROM_READ16(pAd, 0x38, value); // Country Region
1434 pAd->EEPROMDefaultValue[2] = value;
1435
1436 for(i = 0; i < 8; i++)
1437 {
1438 RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i*2, value);
1439 pAd->EEPROMDefaultValue[i+3] = value;
1440 }
1441
1442 // We have to parse NIC configuration 0 at here.
1443 // If TSSI did not have preloaded value, it should reset the TxAutoAgc to false
1444 // Therefore, we have to read TxAutoAgc control beforehand.
1445 // Read Tx AGC control bit
1446 Antenna.word = pAd->EEPROMDefaultValue[0];
1447 if (Antenna.word == 0xFFFF)
1448 {
1449 Antenna.word = 0;
1450 Antenna.field.RfIcType = RFIC_2820;
1451 Antenna.field.TxPath = 1;
1452 Antenna.field.RxPath = 2;
1453 DBGPRINT(RT_DEBUG_WARN, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
1454 }
1455
1456 // Choose the desired Tx&Rx stream.
1457 if ((pAd->CommonCfg.TxStream == 0) || (pAd->CommonCfg.TxStream > Antenna.field.TxPath))
1458 pAd->CommonCfg.TxStream = Antenna.field.TxPath;
1459
1460 if ((pAd->CommonCfg.RxStream == 0) || (pAd->CommonCfg.RxStream > Antenna.field.RxPath))
1461 {
1462 pAd->CommonCfg.RxStream = Antenna.field.RxPath;
1463
1464 if ((pAd->MACVersion < RALINK_2883_VERSION) &&
1465 (pAd->CommonCfg.RxStream > 2))
1466 {
1467 // only 2 Rx streams for RT2860 series
1468 pAd->CommonCfg.RxStream = 2;
1469 }
1470 }
1471
1472 // 3*3
1473 // read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2
1474 // yet implement
1475 for(i=0; i<3; i++)
1476 {
1477 }
1478
1479 NicConfig2.word = pAd->EEPROMDefaultValue[1];
1480
1481
1482
1483#ifdef CONFIG_STA_SUPPORT
1484 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1485 {
1486 NicConfig2.word = 0;
1487 if ((NicConfig2.word & 0x00ff) == 0xff)
1488 {
1489 NicConfig2.word &= 0xff00;
1490 }
1491
1492 if ((NicConfig2.word >> 8) == 0xff)
1493 {
1494 NicConfig2.word &= 0x00ff;
1495 }
1496 }
1497#endif // CONFIG_STA_SUPPORT //
1498
1499 if (NicConfig2.field.DynamicTxAgcControl == 1)
1500 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
1501 else
1502 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
1503
1504 DBGPRINT_RAW(RT_DEBUG_TRACE, ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n", Antenna.field.RxPath, Antenna.field.TxPath));
1505
1506 // Save the antenna for future use
1507 pAd->Antenna.word = Antenna.word;
1508
1509 //
1510 // Reset PhyMode if we don't support 802.11a
1511 // Only RFIC_2850 & RFIC_2750 support 802.11a
1512 //
1513 if ((Antenna.field.RfIcType != RFIC_2850) && (Antenna.field.RfIcType != RFIC_2750))
1514 {
1515 if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) ||
1516 (pAd->CommonCfg.PhyMode == PHY_11A))
1517 pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;
1518#ifdef DOT11_N_SUPPORT
1519 else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) ||
1520 (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) ||
1521 (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) ||
1522 (pAd->CommonCfg.PhyMode == PHY_11N_5G))
1523 pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED;
1524#endif // DOT11_N_SUPPORT //
1525 }
1526
1527 // Read TSSI reference and TSSI boundary for temperature compensation. This is ugly
1528 // 0. 11b/g
1529 {
1530 /* these are tempature reference value (0x00 ~ 0xFE)
1531 ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
1532 TssiPlusBoundaryG [4] [3] [2] [1] [0] (smaller) +
1533 TssiMinusBoundaryG[0] [1] [2] [3] [4] (larger) */
1534 RT28xx_EEPROM_READ16(pAd, 0x6E, Power.word);
1535 pAd->TssiMinusBoundaryG[4] = Power.field.Byte0;
1536 pAd->TssiMinusBoundaryG[3] = Power.field.Byte1;
1537 RT28xx_EEPROM_READ16(pAd, 0x70, Power.word);
1538 pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
1539 pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
1540 RT28xx_EEPROM_READ16(pAd, 0x72, Power.word);
1541 pAd->TssiRefG = Power.field.Byte0; /* reference value [0] */
1542 pAd->TssiPlusBoundaryG[1] = Power.field.Byte1;
1543 RT28xx_EEPROM_READ16(pAd, 0x74, Power.word);
1544 pAd->TssiPlusBoundaryG[2] = Power.field.Byte0;
1545 pAd->TssiPlusBoundaryG[3] = Power.field.Byte1;
1546 RT28xx_EEPROM_READ16(pAd, 0x76, Power.word);
1547 pAd->TssiPlusBoundaryG[4] = Power.field.Byte0;
1548 pAd->TxAgcStepG = Power.field.Byte1;
1549 pAd->TxAgcCompensateG = 0;
1550 pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG;
1551 pAd->TssiPlusBoundaryG[0] = pAd->TssiRefG;
1552
1553 // Disable TxAgc if the based value is not right
1554 if (pAd->TssiRefG == 0xff)
1555 pAd->bAutoTxAgcG = FALSE;
1556
1557 DBGPRINT(RT_DEBUG_TRACE,("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
1558 pAd->TssiMinusBoundaryG[4], pAd->TssiMinusBoundaryG[3], pAd->TssiMinusBoundaryG[2], pAd->TssiMinusBoundaryG[1],
1559 pAd->TssiRefG,
1560 pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2], pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4],
1561 pAd->TxAgcStepG, pAd->bAutoTxAgcG));
1562 }
1563 // 1. 11a
1564 {
1565 RT28xx_EEPROM_READ16(pAd, 0xD4, Power.word);
1566 pAd->TssiMinusBoundaryA[4] = Power.field.Byte0;
1567 pAd->TssiMinusBoundaryA[3] = Power.field.Byte1;
1568 RT28xx_EEPROM_READ16(pAd, 0xD6, Power.word);
1569 pAd->TssiMinusBoundaryA[2] = Power.field.Byte0;
1570 pAd->TssiMinusBoundaryA[1] = Power.field.Byte1;
1571 RT28xx_EEPROM_READ16(pAd, 0xD8, Power.word);
1572 pAd->TssiRefA = Power.field.Byte0;
1573 pAd->TssiPlusBoundaryA[1] = Power.field.Byte1;
1574 RT28xx_EEPROM_READ16(pAd, 0xDA, Power.word);
1575 pAd->TssiPlusBoundaryA[2] = Power.field.Byte0;
1576 pAd->TssiPlusBoundaryA[3] = Power.field.Byte1;
1577 RT28xx_EEPROM_READ16(pAd, 0xDC, Power.word);
1578 pAd->TssiPlusBoundaryA[4] = Power.field.Byte0;
1579 pAd->TxAgcStepA = Power.field.Byte1;
1580 pAd->TxAgcCompensateA = 0;
1581 pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA;
1582 pAd->TssiPlusBoundaryA[0] = pAd->TssiRefA;
1583
1584 // Disable TxAgc if the based value is not right
1585 if (pAd->TssiRefA == 0xff)
1586 pAd->bAutoTxAgcA = FALSE;
1587
1588 DBGPRINT(RT_DEBUG_TRACE,("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
1589 pAd->TssiMinusBoundaryA[4], pAd->TssiMinusBoundaryA[3], pAd->TssiMinusBoundaryA[2], pAd->TssiMinusBoundaryA[1],
1590 pAd->TssiRefA,
1591 pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2], pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4],
1592 pAd->TxAgcStepA, pAd->bAutoTxAgcA));
1593 }
1594 pAd->BbpRssiToDbmDelta = 0x0;
1595
1596 // Read frequency offset setting for RF
1597 RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value);
1598 if ((value & 0x00FF) != 0x00FF)
1599 pAd->RfFreqOffset = (ULONG) (value & 0x00FF);
1600 else
1601 pAd->RfFreqOffset = 0;
1602 DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
1603
1604 //CountryRegion byte offset (38h)
1605 value = pAd->EEPROMDefaultValue[2] >> 8; // 2.4G band
1606 value2 = pAd->EEPROMDefaultValue[2] & 0x00FF; // 5G band
1607
1608 if ((value <= REGION_MAXIMUM_BG_BAND) && (value2 <= REGION_MAXIMUM_A_BAND))
1609 {
1610 pAd->CommonCfg.CountryRegion = ((UCHAR) value) | 0x80;
1611 pAd->CommonCfg.CountryRegionForABand = ((UCHAR) value2) | 0x80;
1612 TmpPhy = pAd->CommonCfg.PhyMode;
1613 pAd->CommonCfg.PhyMode = 0xff;
1614 RTMPSetPhyMode(pAd, TmpPhy);
1615#ifdef DOT11_N_SUPPORT
1616 SetCommonHT(pAd);
1617#endif // DOT11_N_SUPPORT //
1618 }
1619
1620 //
1621 // Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch.
1622 // The valid value are (-10 ~ 10)
1623 //
1624 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value);
1625 pAd->BGRssiOffset0 = value & 0x00ff;
1626 pAd->BGRssiOffset1 = (value >> 8);
1627 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET+2, value);
1628 pAd->BGRssiOffset2 = value & 0x00ff;
1629 pAd->ALNAGain1 = (value >> 8);
1630 RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value);
1631 pAd->BLNAGain = value & 0x00ff;
1632 pAd->ALNAGain0 = (value >> 8);
1633
1634 // Validate 11b/g RSSI_0 offset.
1635 if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10))
1636 pAd->BGRssiOffset0 = 0;
1637
1638 // Validate 11b/g RSSI_1 offset.
1639 if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10))
1640 pAd->BGRssiOffset1 = 0;
1641
1642 // Validate 11b/g RSSI_2 offset.
1643 if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10))
1644 pAd->BGRssiOffset2 = 0;
1645
1646 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value);
1647 pAd->ARssiOffset0 = value & 0x00ff;
1648 pAd->ARssiOffset1 = (value >> 8);
1649 RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET+2), value);
1650 pAd->ARssiOffset2 = value & 0x00ff;
1651 pAd->ALNAGain2 = (value >> 8);
1652
1653 if (((UCHAR)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00))
1654 pAd->ALNAGain1 = pAd->ALNAGain0;
1655 if (((UCHAR)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00))
1656 pAd->ALNAGain2 = pAd->ALNAGain0;
1657
1658 // Validate 11a RSSI_0 offset.
1659 if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10))
1660 pAd->ARssiOffset0 = 0;
1661
1662 // Validate 11a RSSI_1 offset.
1663 if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10))
1664 pAd->ARssiOffset1 = 0;
1665
1666 //Validate 11a RSSI_2 offset.
1667 if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10))
1668 pAd->ARssiOffset2 = 0;
1669
1670 //
1671 // Get LED Setting.
1672 //
1673 RT28xx_EEPROM_READ16(pAd, 0x3a, value);
1674 pAd->LedCntl.word = (value&0xff00) >> 8;
1675 RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value);
1676 pAd->Led1 = value;
1677 RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value);
1678 pAd->Led2 = value;
1679 RT28xx_EEPROM_READ16(pAd, EEPROM_LED3_OFFSET, value);
1680 pAd->Led3 = value;
1681
1682 RTMPReadTxPwrPerRate(pAd);
1683
1684#ifdef SINGLE_SKU
1685 //pAd->CommonCfg.DefineMaxTxPwr = RTMP_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR);
1686 RT28xx_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR, pAd->CommonCfg.DefineMaxTxPwr);
1687#endif // SINGLE_SKU //
1688
1689 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
1690}
1691
1692/*
1693 ========================================================================
1694
1695 Routine Description:
1696 Set default value from EEPROM
1697
1698 Arguments:
1699 Adapter Pointer to our adapter
1700
1701 Return Value:
1702 None
1703
1704 IRQL = PASSIVE_LEVEL
1705
1706 Note:
1707
1708 ========================================================================
1709*/
1710VOID NICInitAsicFromEEPROM(
1711 IN PRTMP_ADAPTER pAd)
1712{
1713#ifdef CONFIG_STA_SUPPORT
1714 UINT32 data = 0;
1715 UCHAR BBPR1 = 0;
1716#endif // CONFIG_STA_SUPPORT //
1717 USHORT i;
1718 EEPROM_ANTENNA_STRUC Antenna;
1719 EEPROM_NIC_CONFIG2_STRUC NicConfig2;
1720 UCHAR BBPR3 = 0;
1721
1722 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n"));
1723 for(i = 3; i < NUM_EEPROM_BBP_PARMS; i++)
1724 {
1725 UCHAR BbpRegIdx, BbpValue;
1726
1727 if ((pAd->EEPROMDefaultValue[i] != 0xFFFF) && (pAd->EEPROMDefaultValue[i] != 0))
1728 {
1729 BbpRegIdx = (UCHAR)(pAd->EEPROMDefaultValue[i] >> 8);
1730 BbpValue = (UCHAR)(pAd->EEPROMDefaultValue[i] & 0xff);
1731 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue);
1732 }
1733 }
1734
1735 Antenna.word = pAd->Antenna.word;
1736 pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
1737 pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
1738
1739 NicConfig2.word = pAd->EEPROMDefaultValue[1];
1740
1741
1742 // Save the antenna for future use
1743 pAd->NicConfig2.word = NicConfig2.word;
1744
1745 //
1746 // Send LED Setting to MCU.
1747 //
1748 if (pAd->LedCntl.word == 0xFF)
1749 {
1750 pAd->LedCntl.word = 0x01;
1751 pAd->Led1 = 0x5555;
1752 pAd->Led2 = 0x2221;
1753
1754#ifdef RT2870
1755 pAd->Led3 = 0x5627;
1756#endif // RT2870 //
1757 }
1758
1759 AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
1760 AsicSendCommandToMcu(pAd, 0x53, 0xff, (UCHAR)pAd->Led2, (UCHAR)(pAd->Led2 >> 8));
1761 AsicSendCommandToMcu(pAd, 0x54, 0xff, (UCHAR)pAd->Led3, (UCHAR)(pAd->Led3 >> 8));
1762 pAd->LedIndicatorStregth = 0xFF;
1763 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, before link up
1764
1765#ifdef CONFIG_STA_SUPPORT
1766 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1767 {
1768 // Read Hardware controlled Radio state enable bit
1769 if (NicConfig2.field.HardwareRadioControl == 1)
1770 {
1771 pAd->StaCfg.bHardwareRadio = TRUE;
1772
1773 // Read GPIO pin2 as Hardware controlled radio state
1774 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
1775 if ((data & 0x04) == 0)
1776 {
1777 pAd->StaCfg.bHwRadio = FALSE;
1778 pAd->StaCfg.bRadio = FALSE;
1779// RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
1780 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1781 }
1782 }
1783 else
1784 pAd->StaCfg.bHardwareRadio = FALSE;
1785
1786 if (pAd->StaCfg.bRadio == FALSE)
1787 {
1788 RTMPSetLED(pAd, LED_RADIO_OFF);
1789 }
1790 else
1791 {
1792 RTMPSetLED(pAd, LED_RADIO_ON);
1793 }
1794 }
1795#endif // CONFIG_STA_SUPPORT //
1796
1797 // Turn off patching for cardbus controller
1798 if (NicConfig2.field.CardbusAcceleration == 1)
1799 {
1800// pAd->bTest1 = TRUE;
1801 }
1802
1803 if (NicConfig2.field.DynamicTxAgcControl == 1)
1804 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
1805 else
1806 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
1807 //
1808 // Since BBP has been progamed, to make sure BBP setting will be
1809 // upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND!!
1810 //
1811 pAd->CommonCfg.BandState = UNKNOWN_BAND;
1812
1813 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
1814 BBPR3 &= (~0x18);
1815 if(pAd->Antenna.field.RxPath == 3)
1816 {
1817 BBPR3 |= (0x10);
1818 }
1819 else if(pAd->Antenna.field.RxPath == 2)
1820 {
1821 BBPR3 |= (0x8);
1822 }
1823 else if(pAd->Antenna.field.RxPath == 1)
1824 {
1825 BBPR3 |= (0x0);
1826 }
1827 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
1828
1829#ifdef CONFIG_STA_SUPPORT
1830 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1831 {
1832 // Handle the difference when 1T
1833 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
1834 if(pAd->Antenna.field.TxPath == 1)
1835 {
1836 BBPR1 &= (~0x18);
1837 }
1838 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
1839
1840 DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n", pAd->CommonCfg.bHardwareRadio, pAd->CommonCfg.bHardwareRadio));
1841 }
1842#endif // CONFIG_STA_SUPPORT //
1843 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));
1844 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n"));
1845}
1846
1847/*
1848 ========================================================================
1849
1850 Routine Description:
1851 Initialize NIC hardware
1852
1853 Arguments:
1854 Adapter Pointer to our adapter
1855
1856 Return Value:
1857 None
1858
1859 IRQL = PASSIVE_LEVEL
1860
1861 Note:
1862
1863 ========================================================================
1864*/
1865NDIS_STATUS NICInitializeAdapter(
1866 IN PRTMP_ADAPTER pAd,
1867 IN BOOLEAN bHardReset)
1868{
1869 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1870 WPDMA_GLO_CFG_STRUC GloCfg;
1871// INT_MASK_CSR_STRUC IntMask;
1872 ULONG i =0, j=0;
1873 AC_TXOP_CSR0_STRUC csr0;
1874
1875 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n"));
1876
1877 // 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
1878retry:
1879 i = 0;
1880 do
1881 {
1882 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1883 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1884 break;
1885
1886 RTMPusecDelay(1000);
1887 i++;
1888 }while ( i<100);
1889 DBGPRINT(RT_DEBUG_TRACE, ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word));
1890 GloCfg.word &= 0xff0;
1891 GloCfg.field.EnTXWriteBackDDONE =1;
1892 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1893
1894 // Record HW Beacon offset
1895 pAd->BeaconOffset[0] = HW_BEACON_BASE0;
1896 pAd->BeaconOffset[1] = HW_BEACON_BASE1;
1897 pAd->BeaconOffset[2] = HW_BEACON_BASE2;
1898 pAd->BeaconOffset[3] = HW_BEACON_BASE3;
1899 pAd->BeaconOffset[4] = HW_BEACON_BASE4;
1900 pAd->BeaconOffset[5] = HW_BEACON_BASE5;
1901 pAd->BeaconOffset[6] = HW_BEACON_BASE6;
1902 pAd->BeaconOffset[7] = HW_BEACON_BASE7;
1903
1904 //
1905 // write all shared Ring's base address into ASIC
1906 //
1907
1908 // asic simulation sequence put this ahead before loading firmware.
1909 // pbf hardware reset
1910
1911 // Initialze ASIC for TX & Rx operation
1912 if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
1913 {
1914 if (j++ == 0)
1915 {
1916 NICLoadFirmware(pAd);
1917 goto retry;
1918 }
1919 return NDIS_STATUS_FAILURE;
1920 }
1921
1922
1923
1924
1925 // WMM parameter
1926 csr0.word = 0;
1927 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1928 if (pAd->CommonCfg.PhyMode == PHY_11B)
1929 {
1930 csr0.field.Ac0Txop = 192; // AC_VI: 192*32us ~= 6ms
1931 csr0.field.Ac1Txop = 96; // AC_VO: 96*32us ~= 3ms
1932 }
1933 else
1934 {
1935 csr0.field.Ac0Txop = 96; // AC_VI: 96*32us ~= 3ms
1936 csr0.field.Ac1Txop = 48; // AC_VO: 48*32us ~= 1.5ms
1937 }
1938 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
1939
1940
1941
1942
1943 // reset action
1944 // Load firmware
1945 // Status = NICLoadFirmware(pAd);
1946
1947 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n"));
1948 return Status;
1949}
1950
1951/*
1952 ========================================================================
1953
1954 Routine Description:
1955 Initialize ASIC
1956
1957 Arguments:
1958 Adapter Pointer to our adapter
1959
1960 Return Value:
1961 None
1962
1963 IRQL = PASSIVE_LEVEL
1964
1965 Note:
1966
1967 ========================================================================
1968*/
1969NDIS_STATUS NICInitializeAsic(
1970 IN PRTMP_ADAPTER pAd,
1971 IN BOOLEAN bHardReset)
1972{
1973 ULONG Index = 0;
1974 UCHAR R0 = 0xff;
1975 UINT32 MacCsr12 = 0, Counter = 0;
1976#ifdef RT2870
1977 UINT32 MacCsr0 = 0;
1978 NTSTATUS Status;
1979 UCHAR Value = 0xff;
1980#endif // RT2870 //
1981 USHORT KeyIdx;
1982 INT i,apidx;
1983
1984 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
1985
1986
1987#ifdef RT2870
1988 //
1989 // Make sure MAC gets ready after NICLoadFirmware().
1990 //
1991 Index = 0;
1992
1993 //To avoid hang-on issue when interface up in kernel 2.4,
1994 //we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly.
1995 do
1996 {
1997 RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
1998
1999 if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
2000 break;
2001
2002 RTMPusecDelay(10);
2003 } while (Index++ < 100);
2004
2005 pAd->MACVersion = MacCsr0;
2006 DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
2007 // turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue.
2008 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacCsr12);
2009 MacCsr12 &= (~0x2000);
2010 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacCsr12);
2011
2012 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
2013 RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0);
2014 Status = RTUSBVenderReset(pAd);
2015
2016 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
2017
2018 // Initialize MAC register to default value
2019 for(Index=0; Index<NUM_MAC_REG_PARMS; Index++)
2020 {
2021 RTMP_IO_WRITE32(pAd, (USHORT)MACRegTable[Index].Register, MACRegTable[Index].Value);
2022 }
2023
2024 if(IS_RT3070(pAd))
2025 {
2026 // According to Frank Hsu (from Gary Tsao)
2027 RTMP_IO_WRITE32(pAd, (USHORT)TX_SW_CFG0, 0x00000400);
2028
2029 // Initialize RT3070 serial MAC registers which is different from RT2870 serial
2030 RTUSBWriteMACRegister(pAd, TX_SW_CFG1, 0);
2031 RTUSBWriteMACRegister(pAd, TX_SW_CFG2, 0);
2032 }
2033
2034
2035#ifdef CONFIG_STA_SUPPORT
2036 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2037 {
2038 for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++)
2039 {
2040 RTMP_IO_WRITE32(pAd, (USHORT)STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
2041 }
2042 }
2043#endif // CONFIG_STA_SUPPORT //
2044#endif // RT2870 //
2045
2046 //
2047 // Before program BBP, we need to wait BBP/RF get wake up.
2048 //
2049 Index = 0;
2050 do
2051 {
2052 RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12);
2053
2054 if ((MacCsr12 & 0x03) == 0) // if BB.RF is stable
2055 break;
2056
2057 DBGPRINT(RT_DEBUG_TRACE, ("Check MAC_STATUS_CFG = Busy = %x\n", MacCsr12));
2058 RTMPusecDelay(1000);
2059 } while (Index++ < 100);
2060
2061 // The commands to firmware should be after these commands, these commands will init firmware
2062 // PCI and USB are not the same because PCI driver needs to wait for PCI bus ready
2063 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0); // initialize BBP R/W access agent
2064 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
2065 RTMPusecDelay(1000);
2066
2067 // Read BBP register, make sure BBP is up and running before write new data
2068 Index = 0;
2069 do
2070 {
2071 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0);
2072 DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0));
2073 } while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00)));
2074 //ASSERT(Index < 20); //this will cause BSOD on Check-build driver
2075
2076 if ((R0 == 0xff) || (R0 == 0x00))
2077 return NDIS_STATUS_FAILURE;
2078
2079 // Initialize BBP register to default value
2080 for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
2081 {
2082 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value);
2083 }
2084
2085 // for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
2086 if ((pAd->MACVersion&0xffff) != 0x0101)
2087 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
2088
2089#ifdef RT2870
2090 //write RT3070 BBP wchich different with 2870 after write RT2870 BBP
2091 if (IS_RT3070(pAd))
2092 {
2093 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0a);
2094 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x99);
2095 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, 0x05);
2096 }
2097#endif // RT2870 //
2098
2099 if (pAd->MACVersion == 0x28600100)
2100 {
2101 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
2102 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
2103 }
2104
2105 if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION) // 3*3
2106 {
2107 // enlarge MAX_LEN_CFG
2108 UINT32 csr;
2109 RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr);
2110 csr &= 0xFFF;
2111 csr |= 0x2000;
2112 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
2113 }
2114
2115#ifdef RT2870
2116{
2117 UCHAR MAC_Value[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0,0};
2118
2119 //Initialize WCID table
2120 Value = 0xff;
2121 for(Index =0 ;Index < 254;Index++)
2122 {
2123 RTUSBMultiWrite(pAd, (USHORT)(MAC_WCID_BASE + Index * 8), MAC_Value, 8);
2124 }
2125}
2126#endif // RT2870 //
2127
2128 // Add radio off control
2129#ifdef CONFIG_STA_SUPPORT
2130 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2131 {
2132 if (pAd->StaCfg.bRadio == FALSE)
2133 {
2134// RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
2135 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
2136 DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n"));
2137 }
2138 }
2139#endif // CONFIG_STA_SUPPORT //
2140
2141 // Clear raw counters
2142 RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
2143 RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
2144 RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
2145 RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
2146 RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
2147 RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
2148
2149 // ASIC will keep garbage value after boot
2150 // Clear all seared key table when initial
2151 // This routine can be ignored in radio-ON/OFF operation.
2152 if (bHardReset)
2153 {
2154 for (KeyIdx = 0; KeyIdx < 4; KeyIdx++)
2155 {
2156 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4*KeyIdx, 0);
2157 }
2158
2159 // Clear all pairwise key table when initial
2160 for (KeyIdx = 0; KeyIdx < 256; KeyIdx++)
2161 {
2162 RTMP_IO_WRITE32(pAd, MAC_WCID_ATTRIBUTE_BASE + (KeyIdx * HW_WCID_ATTRI_SIZE), 1);
2163 }
2164 }
2165
2166 // assert HOST ready bit
2167// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark
2168// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4);
2169
2170 // It isn't necessary to clear this space when not hard reset.
2171 if (bHardReset == TRUE)
2172 {
2173 // clear all on-chip BEACON frame space
2174 for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++)
2175 {
2176 for (i = 0; i < HW_BEACON_OFFSET>>2; i+=4)
2177 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00);
2178 }
2179 }
2180#ifdef RT2870
2181 AsicDisableSync(pAd);
2182 // Clear raw counters
2183 RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
2184 RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
2185 RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
2186 RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
2187 RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
2188 RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
2189 // Default PCI clock cycle per ms is different as default setting, which is based on PCI.
2190 RTMP_IO_READ32(pAd, USB_CYC_CFG, &Counter);
2191 Counter&=0xffffff00;
2192 Counter|=0x000001e;
2193 RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter);
2194#endif // RT2870 //
2195
2196#ifdef CONFIG_STA_SUPPORT
2197 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2198 {
2199 // for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT.
2200 if ((pAd->MACVersion&0xffff) != 0x0101)
2201 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f);
2202 }
2203#endif // CONFIG_STA_SUPPORT //
2204
2205 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n"));
2206 return NDIS_STATUS_SUCCESS;
2207}
2208
2209/*
2210 ========================================================================
2211
2212 Routine Description:
2213 Reset NIC Asics
2214
2215 Arguments:
2216 Adapter Pointer to our adapter
2217
2218 Return Value:
2219 None
2220
2221 IRQL = PASSIVE_LEVEL
2222
2223 Note:
2224 Reset NIC to initial state AS IS system boot up time.
2225
2226 ========================================================================
2227*/
2228VOID NICIssueReset(
2229 IN PRTMP_ADAPTER pAd)
2230{
2231 UINT32 Value = 0;
2232 DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n"));
2233
2234 // Abort Tx, prevent ASIC from writing to Host memory
2235 //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000);
2236
2237 // Disable Rx, register value supposed will remain after reset
2238 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
2239 Value &= (0xfffffff3);
2240 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
2241
2242 // Issue reset and clear from reset state
2243 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03); // 2004-09-17 change from 0x01
2244 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
2245
2246 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICIssueReset\n"));
2247}
2248
2249/*
2250 ========================================================================
2251
2252 Routine Description:
2253 Check ASIC registers and find any reason the system might hang
2254
2255 Arguments:
2256 Adapter Pointer to our adapter
2257
2258 Return Value:
2259 None
2260
2261 IRQL = DISPATCH_LEVEL
2262
2263 ========================================================================
2264*/
2265BOOLEAN NICCheckForHang(
2266 IN PRTMP_ADAPTER pAd)
2267{
2268 return (FALSE);
2269}
2270
2271VOID NICUpdateFifoStaCounters(
2272 IN PRTMP_ADAPTER pAd)
2273{
2274 TX_STA_FIFO_STRUC StaFifo;
2275 MAC_TABLE_ENTRY *pEntry;
2276 UCHAR i = 0;
2277 UCHAR pid = 0, wcid = 0;
2278 CHAR reTry;
2279 UCHAR succMCS;
2280
2281#ifdef RALINK_ATE
2282 /* Nothing to do in ATE mode */
2283 if (ATE_ON(pAd))
2284 return;
2285#endif // RALINK_ATE //
2286
2287 do
2288 {
2289 RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
2290
2291 if (StaFifo.field.bValid == 0)
2292 break;
2293
2294 wcid = (UCHAR)StaFifo.field.wcid;
2295
2296
2297 /* ignore NoACK and MGMT frame use 0xFF as WCID */
2298 if ((StaFifo.field.TxAckRequired == 0) || (wcid >= MAX_LEN_OF_MAC_TABLE))
2299 {
2300 i++;
2301 continue;
2302 }
2303
2304 /* PID store Tx MCS Rate */
2305 pid = (UCHAR)StaFifo.field.PidType;
2306
2307 pEntry = &pAd->MacTab.Content[wcid];
2308
2309 pEntry->DebugFIFOCount++;
2310
2311#ifdef DOT11_N_SUPPORT
2312 if (StaFifo.field.TxBF) // 3*3
2313 pEntry->TxBFCount++;
2314#endif // DOT11_N_SUPPORT //
2315
2316#ifdef UAPSD_AP_SUPPORT
2317 UAPSD_SP_AUE_Handle(pAd, pEntry, StaFifo.field.TxSuccess);
2318#endif // UAPSD_AP_SUPPORT //
2319
2320 if (!StaFifo.field.TxSuccess)
2321 {
2322 pEntry->FIFOCount++;
2323 pEntry->OneSecTxFailCount++;
2324
2325 if (pEntry->FIFOCount >= 1)
2326 {
2327 DBGPRINT(RT_DEBUG_TRACE, ("#"));
2328#if 0
2329 SendRefreshBAR(pAd, pEntry);
2330 pEntry->NoBADataCountDown = 64;
2331#else
2332#ifdef DOT11_N_SUPPORT
2333 pEntry->NoBADataCountDown = 64;
2334#endif // DOT11_N_SUPPORT //
2335
2336 if(pEntry->PsMode == PWR_ACTIVE)
2337 {
2338#ifdef DOT11_N_SUPPORT
2339 int tid;
2340 for (tid=0; tid<NUM_OF_TID; tid++)
2341 {
2342 BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, FALSE);
2343 }
2344#endif // DOT11_N_SUPPORT //
2345
2346 // Update the continuous transmission counter except PS mode
2347 pEntry->ContinueTxFailCnt++;
2348 }
2349 else
2350 {
2351 // Clear the FIFOCount when sta in Power Save mode. Basically we assume
2352 // this tx error happened due to sta just go to sleep.
2353 pEntry->FIFOCount = 0;
2354 pEntry->ContinueTxFailCnt = 0;
2355 }
2356#endif
2357 //pEntry->FIFOCount = 0;
2358 }
2359 //pEntry->bSendBAR = TRUE;
2360 }
2361 else
2362 {
2363#ifdef DOT11_N_SUPPORT
2364 if ((pEntry->PsMode != PWR_SAVE) && (pEntry->NoBADataCountDown > 0))
2365 {
2366 pEntry->NoBADataCountDown--;
2367 if (pEntry->NoBADataCountDown==0)
2368 {
2369 DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
2370 }
2371 }
2372#endif // DOT11_N_SUPPORT //
2373 pEntry->FIFOCount = 0;
2374 pEntry->OneSecTxNoRetryOkCount++;
2375 // update NoDataIdleCount when sucessful send packet to STA.
2376 pEntry->NoDataIdleCount = 0;
2377 pEntry->ContinueTxFailCnt = 0;
2378 }
2379
2380 succMCS = StaFifo.field.SuccessRate & 0x7F;
2381
2382 reTry = pid - succMCS;
2383
2384 if (StaFifo.field.TxSuccess)
2385 {
2386 pEntry->TXMCSExpected[pid]++;
2387 if (pid == succMCS)
2388 {
2389 pEntry->TXMCSSuccessful[pid]++;
2390 }
2391 else
2392 {
2393 pEntry->TXMCSAutoFallBack[pid][succMCS]++;
2394 }
2395 }
2396 else
2397 {
2398 pEntry->TXMCSFailed[pid]++;
2399 }
2400
2401 if (reTry > 0)
2402 {
2403 if ((pid >= 12) && succMCS <=7)
2404 {
2405 reTry -= 4;
2406 }
2407 pEntry->OneSecTxRetryOkCount += reTry;
2408 }
2409
2410 i++;
2411 // ASIC store 16 stack
2412 } while ( i < (2*TX_RING_SIZE) );
2413
2414}
2415
2416/*
2417 ========================================================================
2418
2419 Routine Description:
2420 Read statistical counters from hardware registers and record them
2421 in software variables for later on query
2422
2423 Arguments:
2424 pAd Pointer to our adapter
2425
2426 Return Value:
2427 None
2428
2429 IRQL = DISPATCH_LEVEL
2430
2431 ========================================================================
2432*/
2433VOID NICUpdateRawCounters(
2434 IN PRTMP_ADAPTER pAd)
2435{
2436 UINT32 OldValue;
2437 RX_STA_CNT0_STRUC RxStaCnt0;
2438 RX_STA_CNT1_STRUC RxStaCnt1;
2439 RX_STA_CNT2_STRUC RxStaCnt2;
2440 TX_STA_CNT0_STRUC TxStaCnt0;
2441 TX_STA_CNT1_STRUC StaTx1;
2442 TX_STA_CNT2_STRUC StaTx2;
2443 TX_AGG_CNT_STRUC TxAggCnt;
2444 TX_AGG_CNT0_STRUC TxAggCnt0;
2445 TX_AGG_CNT1_STRUC TxAggCnt1;
2446 TX_AGG_CNT2_STRUC TxAggCnt2;
2447 TX_AGG_CNT3_STRUC TxAggCnt3;
2448 TX_AGG_CNT4_STRUC TxAggCnt4;
2449 TX_AGG_CNT5_STRUC TxAggCnt5;
2450 TX_AGG_CNT6_STRUC TxAggCnt6;
2451 TX_AGG_CNT7_STRUC TxAggCnt7;
2452
2453
2454 RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word);
2455 RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word);
2456
2457 {
2458 RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
2459 // Update RX PLCP error counter
2460 pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr;
2461 // Update False CCA counter
2462 pAd->RalinkCounters.OneSecFalseCCACnt += RxStaCnt1.field.FalseCca;
2463 }
2464
2465 // Update FCS counters
2466 OldValue= pAd->WlanCounters.FCSErrorCount.u.LowPart;
2467 pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); // >> 7);
2468 if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue)
2469 pAd->WlanCounters.FCSErrorCount.u.HighPart++;
2470
2471 // Add FCS error count to private counters
2472 pAd->RalinkCounters.OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
2473 OldValue = pAd->RalinkCounters.RealFcsErrCount.u.LowPart;
2474 pAd->RalinkCounters.RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
2475 if (pAd->RalinkCounters.RealFcsErrCount.u.LowPart < OldValue)
2476 pAd->RalinkCounters.RealFcsErrCount.u.HighPart++;
2477
2478 // Update Duplicate Rcv check
2479 pAd->RalinkCounters.DuplicateRcv += RxStaCnt2.field.RxDupliCount;
2480 pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount;
2481 // Update RX Overflow counter
2482 pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
2483
2484 //pAd->RalinkCounters.RxCount = 0;
2485#ifdef RT2870
2486 if (pAd->RalinkCounters.RxCount != pAd->watchDogRxCnt)
2487 {
2488 pAd->watchDogRxCnt = pAd->RalinkCounters.RxCount;
2489 pAd->watchDogRxOverFlowCnt = 0;
2490 }
2491 else
2492 {
2493 if (RxStaCnt2.field.RxFifoOverflowCount)
2494 pAd->watchDogRxOverFlowCnt++;
2495 else
2496 pAd->watchDogRxOverFlowCnt = 0;
2497 }
2498#endif // RT2870 //
2499
2500
2501 //if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) ||
2502 // (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1)))
2503 if (!pAd->bUpdateBcnCntDone)
2504 {
2505 // Update BEACON sent count
2506 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2507 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2508 RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
2509 pAd->RalinkCounters.OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount;
2510 pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2511 pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2512 pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2513 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2514 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2515 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2516 }
2517
2518#if 0
2519 Retry = StaTx1.field.TxRetransmit;
2520 Fail = TxStaCnt0.field.TxFailCount;
2521 TxErrorRatio = 0;
2522 OneSecTransmitCount = pAd->WlanCounters.TransmittedFragmentCount.u.LowPart- pAd->WlanCounters.LastTransmittedFragmentCount.u.LowPart;
2523 if ((OneSecTransmitCount+Retry + Fail) > 0)
2524 TxErrorRatio = (( Retry + Fail) *100) / (OneSecTransmitCount+Retry + Fail);
2525
2526 if ((OneSecTransmitCount+Retry + Fail) > 0)
2527 TxErrorRatio = (( Retry + Fail) *100) / (OneSecTransmitCount+Retry + Fail);
2528 DBGPRINT(RT_DEBUG_INFO, ("TX ERROR Rate = %ld %%, Retry = %ld, Fail = %ld, Total = %ld \n",TxErrorRatio, Retry, Fail, (OneSecTransmitCount+Retry + Fail)));
2529 pAd->WlanCounters.LastTransmittedFragmentCount.u.LowPart = pAd->WlanCounters.TransmittedFragmentCount.u.LowPart;
2530#endif
2531
2532 //if (pAd->bStaFifoTest == TRUE)
2533 {
2534 RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word);
2535 RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word);
2536 RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word);
2537 RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word);
2538 RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word);
2539 RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word);
2540 RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word);
2541 RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word);
2542 RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word);
2543 pAd->RalinkCounters.TxAggCount += TxAggCnt.field.AggTxCount;
2544 pAd->RalinkCounters.TxNonAggCount += TxAggCnt.field.NonAggTxCount;
2545 pAd->RalinkCounters.TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count;
2546 pAd->RalinkCounters.TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count;
2547
2548 pAd->RalinkCounters.TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count;
2549 pAd->RalinkCounters.TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count;
2550 pAd->RalinkCounters.TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count;
2551 pAd->RalinkCounters.TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count;
2552
2553 pAd->RalinkCounters.TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count;
2554 pAd->RalinkCounters.TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count;
2555 pAd->RalinkCounters.TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count;
2556 pAd->RalinkCounters.TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count;
2557
2558 pAd->RalinkCounters.TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count;
2559 pAd->RalinkCounters.TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count;
2560 pAd->RalinkCounters.TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count;
2561 pAd->RalinkCounters.TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count;
2562
2563 pAd->RalinkCounters.TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count;
2564 pAd->RalinkCounters.TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count;
2565
2566 // Calculate the transmitted A-MPDU count
2567 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count;
2568 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2);
2569
2570 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3);
2571 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4);
2572
2573 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5);
2574 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6);
2575
2576 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7);
2577 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8);
2578
2579 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9);
2580 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10);
2581
2582 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11);
2583 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12);
2584
2585 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13);
2586 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14);
2587
2588 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15);
2589 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16);
2590 }
2591
2592#ifdef DBG_DIAGNOSE
2593 {
2594 RtmpDiagStruct *pDiag;
2595 COUNTER_RALINK *pRalinkCounters;
2596 UCHAR ArrayCurIdx, i;
2597
2598 pDiag = &pAd->DiagStruct;
2599 pRalinkCounters = &pAd->RalinkCounters;
2600 ArrayCurIdx = pDiag->ArrayCurIdx;
2601
2602 if (pDiag->inited == 0)
2603 {
2604 NdisZeroMemory(pDiag, sizeof(struct _RtmpDiagStrcut_));
2605 pDiag->ArrayStartIdx = pDiag->ArrayCurIdx = 0;
2606 pDiag->inited = 1;
2607 }
2608 else
2609 {
2610 // Tx
2611 pDiag->TxFailCnt[ArrayCurIdx] = TxStaCnt0.field.TxFailCount;
2612 pDiag->TxAggCnt[ArrayCurIdx] = TxAggCnt.field.AggTxCount;
2613 pDiag->TxNonAggCnt[ArrayCurIdx] = TxAggCnt.field.NonAggTxCount;
2614 pDiag->TxAMPDUCnt[ArrayCurIdx][0] = TxAggCnt0.field.AggSize1Count;
2615 pDiag->TxAMPDUCnt[ArrayCurIdx][1] = TxAggCnt0.field.AggSize2Count;
2616 pDiag->TxAMPDUCnt[ArrayCurIdx][2] = TxAggCnt1.field.AggSize3Count;
2617 pDiag->TxAMPDUCnt[ArrayCurIdx][3] = TxAggCnt1.field.AggSize4Count;
2618 pDiag->TxAMPDUCnt[ArrayCurIdx][4] = TxAggCnt2.field.AggSize5Count;
2619 pDiag->TxAMPDUCnt[ArrayCurIdx][5] = TxAggCnt2.field.AggSize6Count;
2620 pDiag->TxAMPDUCnt[ArrayCurIdx][6] = TxAggCnt3.field.AggSize7Count;
2621 pDiag->TxAMPDUCnt[ArrayCurIdx][7] = TxAggCnt3.field.AggSize8Count;
2622 pDiag->TxAMPDUCnt[ArrayCurIdx][8] = TxAggCnt4.field.AggSize9Count;
2623 pDiag->TxAMPDUCnt[ArrayCurIdx][9] = TxAggCnt4.field.AggSize10Count;
2624 pDiag->TxAMPDUCnt[ArrayCurIdx][10] = TxAggCnt5.field.AggSize11Count;
2625 pDiag->TxAMPDUCnt[ArrayCurIdx][11] = TxAggCnt5.field.AggSize12Count;
2626 pDiag->TxAMPDUCnt[ArrayCurIdx][12] = TxAggCnt6.field.AggSize13Count;
2627 pDiag->TxAMPDUCnt[ArrayCurIdx][13] = TxAggCnt6.field.AggSize14Count;
2628 pDiag->TxAMPDUCnt[ArrayCurIdx][14] = TxAggCnt7.field.AggSize15Count;
2629 pDiag->TxAMPDUCnt[ArrayCurIdx][15] = TxAggCnt7.field.AggSize16Count;
2630
2631 pDiag->RxCrcErrCnt[ArrayCurIdx] = RxStaCnt0.field.CrcErr;
2632
2633 INC_RING_INDEX(pDiag->ArrayCurIdx, DIAGNOSE_TIME);
2634 ArrayCurIdx = pDiag->ArrayCurIdx;
2635 for (i =0; i < 9; i++)
2636 {
2637 pDiag->TxDescCnt[ArrayCurIdx][i]= 0;
2638 pDiag->TxSWQueCnt[ArrayCurIdx][i] =0;
2639 pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
2640 pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
2641 }
2642 pDiag->TxDataCnt[ArrayCurIdx] = 0;
2643 pDiag->TxFailCnt[ArrayCurIdx] = 0;
2644 pDiag->RxDataCnt[ArrayCurIdx] = 0;
2645 pDiag->RxCrcErrCnt[ArrayCurIdx] = 0;
2646// for (i = 9; i < 16; i++)
2647 for (i = 9; i < 24; i++) // 3*3
2648 {
2649 pDiag->TxDescCnt[ArrayCurIdx][i] = 0;
2650 pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
2651 pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
2652}
2653
2654 if (pDiag->ArrayCurIdx == pDiag->ArrayStartIdx)
2655 INC_RING_INDEX(pDiag->ArrayStartIdx, DIAGNOSE_TIME);
2656 }
2657
2658 }
2659#endif // DBG_DIAGNOSE //
2660
2661
2662}
2663
2664
2665/*
2666 ========================================================================
2667
2668 Routine Description:
2669 Reset NIC from error
2670
2671 Arguments:
2672 Adapter Pointer to our adapter
2673
2674 Return Value:
2675 None
2676
2677 IRQL = PASSIVE_LEVEL
2678
2679 Note:
2680 Reset NIC from error state
2681
2682 ========================================================================
2683*/
2684VOID NICResetFromError(
2685 IN PRTMP_ADAPTER pAd)
2686{
2687 // Reset BBP (according to alex, reset ASIC will force reset BBP
2688 // Therefore, skip the reset BBP
2689 // RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2);
2690
2691 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
2692 // Remove ASIC from reset state
2693 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
2694
2695 NICInitializeAdapter(pAd, FALSE);
2696 NICInitAsicFromEEPROM(pAd);
2697
2698 // Switch to current channel, since during reset process, the connection should remains on.
2699 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
2700 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
2701}
2702
2703/*
2704 ========================================================================
2705
2706 Routine Description:
2707 erase 8051 firmware image in MAC ASIC
2708
2709 Arguments:
2710 Adapter Pointer to our adapter
2711
2712 IRQL = PASSIVE_LEVEL
2713
2714 ========================================================================
2715*/
2716VOID NICEraseFirmware(
2717 IN PRTMP_ADAPTER pAd)
2718{
2719 ULONG i;
2720
2721 for(i=0; i<MAX_FIRMWARE_IMAGE_SIZE; i+=4)
2722 RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
2723
2724}/* End of NICEraseFirmware */
2725
2726/*
2727 ========================================================================
2728
2729 Routine Description:
2730 Load 8051 firmware RT2561.BIN file into MAC ASIC
2731
2732 Arguments:
2733 Adapter Pointer to our adapter
2734
2735 Return Value:
2736 NDIS_STATUS_SUCCESS firmware image load ok
2737 NDIS_STATUS_FAILURE image not found
2738
2739 IRQL = PASSIVE_LEVEL
2740
2741 ========================================================================
2742*/
2743NDIS_STATUS NICLoadFirmware(
2744 IN PRTMP_ADAPTER pAd)
2745{
2746#ifdef BIN_IN_FILE
2747#define NICLF_DEFAULT_USE() \
2748 flg_default_firm_use = TRUE; \
2749 printk("%s - Use default firmware!\n", __FUNCTION__);
2750
2751 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
2752 PUCHAR src;
2753 struct file *srcf;
2754 INT retval, orgfsuid, orgfsgid, i;
2755 mm_segment_t orgfs;
2756 PUCHAR pFirmwareImage;
2757 UINT FileLength = 0;
2758 UINT32 MacReg;
2759 ULONG Index;
2760 ULONG firm;
2761 BOOLEAN flg_default_firm_use = FALSE;
2762
2763
2764 DBGPRINT(RT_DEBUG_TRACE, ("===> %s\n", __FUNCTION__));
2765
2766 /* init */
2767 pFirmwareImage = NULL;
2768 src = RTMP_FIRMWARE_FILE_NAME;
2769
2770 /* save uid and gid used for filesystem access.
2771 set user and group to 0 (root) */
2772 orgfsuid = current->fsuid;
2773 orgfsgid = current->fsgid;
2774 current->fsuid = current->fsgid = 0;
2775 orgfs = get_fs();
2776 set_fs(KERNEL_DS);
2777
2778 pAd->FirmwareVersion = (FIRMWARE_MAJOR_VERSION << 8) + \
2779 FIRMWARE_MINOR_VERSION;
2780
2781
2782 /* allocate firmware buffer */
2783 pFirmwareImage = kmalloc(MAX_FIRMWARE_IMAGE_SIZE, MEM_ALLOC_FLAG);
2784 if (pFirmwareImage == NULL)
2785 {
2786 /* allocate fail, use default firmware array in firmware.h */
2787 printk("%s - Allocate memory fail!\n", __FUNCTION__);
2788 NICLF_DEFAULT_USE();
2789 }
2790 else
2791 {
2792 /* allocate ok! zero the firmware buffer */
2793 memset(pFirmwareImage, 0x00, MAX_FIRMWARE_IMAGE_SIZE);
2794 } /* End of if */
2795
2796
2797 /* if ok, read firmware file from *.bin file */
2798 if (flg_default_firm_use == FALSE)
2799 {
2800 do
2801 {
2802 /* open the bin file */
2803 srcf = filp_open(src, O_RDONLY, 0);
2804
2805 if (IS_ERR(srcf))
2806 {
2807 printk("%s - Error %ld opening %s\n",
2808 __FUNCTION__, -PTR_ERR(srcf), src);
2809 NICLF_DEFAULT_USE();
2810 break;
2811 } /* End of if */
2812
2813 /* the object must have a read method */
2814 if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
2815 {
2816 printk("%s - %s does not have a write method\n", __FUNCTION__, src);
2817 NICLF_DEFAULT_USE();
2818 break;
2819 } /* End of if */
2820
2821 /* read the firmware from the file *.bin */
2822 FileLength = srcf->f_op->read(srcf,
2823 pFirmwareImage,
2824 MAX_FIRMWARE_IMAGE_SIZE,
2825 &srcf->f_pos);
2826
2827 if (FileLength != MAX_FIRMWARE_IMAGE_SIZE)
2828 {
2829 printk("%s: error file length (=%d) in RT2860AP.BIN\n",
2830 __FUNCTION__, FileLength);
2831 NICLF_DEFAULT_USE();
2832 break;
2833 }
2834 else
2835 {
2836 PUCHAR ptr = pFirmwareImage;
2837 USHORT crc = 0xffff;
2838
2839
2840 /* calculate firmware CRC */
2841 for(i=0; i<(MAX_FIRMWARE_IMAGE_SIZE-2); i++, ptr++)
2842 crc = ByteCRC16(BitReverse(*ptr), crc);
2843 /* End of for */
2844
2845 if ((pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2] != \
2846 (UCHAR)BitReverse((UCHAR)(crc>>8))) ||
2847 (pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1] != \
2848 (UCHAR)BitReverse((UCHAR)crc)))
2849 {
2850 /* CRC fail */
2851 printk("%s: CRC = 0x%02x 0x%02x "
2852 "error, should be 0x%02x 0x%02x\n",
2853 __FUNCTION__,
2854 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2],
2855 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1],
2856 (UCHAR)(crc>>8), (UCHAR)(crc));
2857 NICLF_DEFAULT_USE();
2858 break;
2859 }
2860 else
2861 {
2862 /* firmware is ok */
2863 pAd->FirmwareVersion = \
2864 (pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4] << 8) +
2865 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3];
2866
2867 /* check if firmware version of the file is too old */
2868 if ((pAd->FirmwareVersion) < \
2869 ((FIRMWARE_MAJOR_VERSION << 8) +
2870 FIRMWARE_MINOR_VERSION))
2871 {
2872 printk("%s: firmware version too old!\n", __FUNCTION__);
2873 NICLF_DEFAULT_USE();
2874 break;
2875 } /* End of if */
2876 } /* End of if */
2877
2878 DBGPRINT(RT_DEBUG_TRACE,
2879 ("NICLoadFirmware: CRC ok, ver=%d.%d\n",
2880 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4],
2881 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3]));
2882 } /* End of if (FileLength == MAX_FIRMWARE_IMAGE_SIZE) */
2883 break;
2884 } while(TRUE);
2885
2886 /* close firmware file */
2887 if (IS_ERR(srcf))
2888 ;
2889 else
2890 {
2891 retval = filp_close(srcf, NULL);
2892 if (retval)
2893 {
2894 DBGPRINT(RT_DEBUG_ERROR,
2895 ("--> Error %d closing %s\n", -retval, src));
2896 } /* End of if */
2897 } /* End of if */
2898 } /* End of if */
2899
2900
2901 /* write firmware to ASIC */
2902 if (flg_default_firm_use == TRUE)
2903 {
2904 /* use default fimeware, free allocated buffer */
2905 if (pFirmwareImage != NULL)
2906 kfree(pFirmwareImage);
2907 /* End of if */
2908
2909 /* use default *.bin array */
2910 pFirmwareImage = FirmwareImage;
2911 FileLength = sizeof(FirmwareImage);
2912 } /* End of if */
2913
2914 /* enable Host program ram write selection */
2915 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x10000);
2916
2917 for(i=0; i<FileLength; i+=4)
2918 {
2919 firm = pFirmwareImage[i] +
2920 (pFirmwareImage[i+3] << 24) +
2921 (pFirmwareImage[i+2] << 16) +
2922 (pFirmwareImage[i+1] << 8);
2923
2924 RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, firm);
2925 } /* End of for */
2926
2927 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00000);
2928 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00001);
2929
2930 /* initialize BBP R/W access agent */
2931 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);
2932 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
2933
2934 if (flg_default_firm_use == FALSE)
2935 {
2936 /* use file firmware, free allocated buffer */
2937 if (pFirmwareImage != NULL)
2938 kfree(pFirmwareImage);
2939 /* End of if */
2940 } /* End of if */
2941
2942 set_fs(orgfs);
2943 current->fsuid = orgfsuid;
2944 current->fsgid = orgfsgid;
2945#else
2946
2947 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
2948 PUCHAR pFirmwareImage;
2949 ULONG FileLength, Index;
2950 //ULONG firm;
2951 UINT32 MacReg = 0;
2952#ifdef RT2870
2953 UINT32 Version = (pAd->MACVersion >> 16);
2954#endif // RT2870 //
2955
2956 pFirmwareImage = FirmwareImage;
2957 FileLength = sizeof(FirmwareImage);
2958#ifdef RT2870
2959 // New 8k byte firmware size for RT3071/RT3072
2960 //printk("Usb Chip\n");
2961 if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH)
2962 //The firmware image consists of two parts. One is the origianl and the other is the new.
2963 //Use Second Part
2964 {
2965 if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070))
2966 { // Use Firmware V2.
2967 //printk("KH:Use New Version,part2\n");
2968 pFirmwareImage = (PUCHAR)&FirmwareImage[FIRMWAREIMAGEV1_LENGTH];
2969 FileLength = FIRMWAREIMAGEV2_LENGTH;
2970 }
2971 else
2972 {
2973 //printk("KH:Use New Version,part1\n");
2974 pFirmwareImage = FirmwareImage;
2975 FileLength = FIRMWAREIMAGEV1_LENGTH;
2976 }
2977 }
2978 else
2979 {
2980 DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n"));
2981 Status = NDIS_STATUS_FAILURE;
2982 }
2983
2984#endif // RT2870 //
2985
2986#if 0
2987 /* enable Host program ram write selection */
2988 RT28XX_FIRMUD_INIT(pAd);
2989
2990 for(i=0; i<FileLength; i+=4)
2991 {
2992 firm = pFirmwareImage[i] +
2993 (pFirmwareImage[i+3] << 24) +
2994 (pFirmwareImage[i+2] << 16) +
2995 (pFirmwareImage[i+1] << 8);
2996
2997 RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, firm);
2998 } /* End of for */
2999
3000 RT28XX_FIRMUD_END(pAd);
3001#else
3002 RT28XX_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
3003#endif
3004
3005#endif
3006
3007 /* check if MCU is ready */
3008 Index = 0;
3009 do
3010 {
3011 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
3012
3013 if (MacReg & 0x80)
3014 break;
3015
3016 RTMPusecDelay(1000);
3017 } while (Index++ < 1000);
3018
3019 if (Index >= 1000)
3020 {
3021 Status = NDIS_STATUS_FAILURE;
3022 DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
3023 } /* End of if */
3024
3025#if 0
3026 DBGPRINT(RT_DEBUG_TRACE,
3027 ("<=== %s (src=%s, status=%d)\n", __FUNCTION__, src, Status));
3028#else
3029 DBGPRINT(RT_DEBUG_TRACE,
3030 ("<=== %s (status=%d)\n", __FUNCTION__, Status));
3031#endif
3032 return Status;
3033} /* End of NICLoadFirmware */
3034
3035
3036/*
3037 ========================================================================
3038
3039 Routine Description:
3040 Load Tx rate switching parameters
3041
3042 Arguments:
3043 Adapter Pointer to our adapter
3044
3045 Return Value:
3046 NDIS_STATUS_SUCCESS firmware image load ok
3047 NDIS_STATUS_FAILURE image not found
3048
3049 IRQL = PASSIVE_LEVEL
3050
3051 Rate Table Format:
3052 1. (B0: Valid Item number) (B1:Initial item from zero)
3053 2. Item Number(Dec) Mode(Hex) Current MCS(Dec) TrainUp(Dec) TrainDown(Dec)
3054
3055 ========================================================================
3056*/
3057NDIS_STATUS NICLoadRateSwitchingParams(
3058 IN PRTMP_ADAPTER pAd)
3059{
3060#if 0
3061 NDIS_STATUS Status;
3062
3063 NDIS_HANDLE FileHandle;
3064 UINT FileLength = 0, i, j;
3065 PUCHAR pFirmwareImage;
3066 NDIS_STRING FileName;
3067 NDIS_PHYSICAL_ADDRESS HighestAcceptableMax = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
3068
3069 DBGPRINT(RT_DEBUG_TRACE,("===> NICLoadRateSwitchingParams \n"));
3070 pAd->CommonCfg.TxRateTableSize = 0;
3071
3072 if ((pAd->DeviceID == NIC2860_PCI_DEVICE_ID) || (pAd->DeviceID == NIC2860_PCIe_DEVICE_ID))
3073 {
3074 NdisInitializeString(&FileName,"rate.bin");
3075 DBGPRINT(RT_DEBUG_TRACE, ("NICLoadRateSwitchingParams: load file - rate.bin for tx rate switch \n"));
3076 }
3077 else
3078 {
3079 DBGPRINT_ERR(("NICLoadRateSwitchingParams: wrong DeviceID = 0x%04x, can't find Tx rate switch parameters file\n", pAd->DeviceID));
3080 return NDIS_STATUS_SUCCESS;
3081 }
3082 NdisOpenFile(&Status, &FileHandle, &FileLength, &FileName, HighestAcceptableMax);
3083 NdisFreeString(FileName);
3084
3085 if (Status != NDIS_STATUS_SUCCESS)
3086 {
3087 DBGPRINT(RT_DEBUG_ERROR, ("NICLoadRateSwitchingParams: NdisOpenFile() failed, used RateSwitchTable instead\n"));
3088 return NDIS_STATUS_SUCCESS;
3089 }
3090
3091 if ((FileLength == 0) || (FileLength > (MAX_STEP_OF_TX_RATE_SWITCH+1)*16))
3092 {
3093 DBGPRINT(RT_DEBUG_ERROR, ("NICLoadRateSwitchingParams: file size is not reasonable, used RateSwitchTable instead\n"));
3094
3095 NdisCloseFile(FileHandle);
3096 return NDIS_STATUS_SUCCESS;
3097 }
3098 else
3099 {
3100 //
3101 // NDIS_STATUS_SUCCESS means
3102 // The handle at FileHandle is valid for a subsequent call to NdisMapFile.
3103 //
3104 NdisMapFile(&Status, &pFirmwareImage, FileHandle);
3105 DBGPRINT(RT_DEBUG_TRACE, ("NdisMapFile FileLength=%d\n", FileLength));
3106 }
3107
3108 for (i=0, j=0; i<FileLength; i++)
3109 {
3110 if ((i%16) <= 4) // trim reserved field
3111 {
3112 if (i%16 == 1) // deal with DEC and HEX, only row0 is Hex, others are Dec
3113 {
3114 RateSwitchTable[j] = *(pFirmwareImage + i);
3115 }
3116 else
3117 {
3118 RateSwitchTable[j] = (*(pFirmwareImage + i)>>4) * 10 + (*(pFirmwareImage + i) & 0x0F);
3119 }
3120
3121 j++;
3122 }
3123 }
3124
3125 pAd->CommonCfg.TxRateTableSize = RateSwitchTable[0]; // backup table size
3126
3127 if (Status == NDIS_STATUS_SUCCESS)
3128 {
3129 NdisUnmapFile(FileHandle);
3130 NdisCloseFile(FileHandle);
3131 }
3132
3133 DBGPRINT(RT_DEBUG_TRACE,("<=== NICLoadRateSwitchingParams(Valid TxRateTable item number=%d)\n", pAd->CommonCfg.TxRateTableSize));
3134#endif
3135 return NDIS_STATUS_SUCCESS;
3136}
3137
3138/*
3139 ========================================================================
3140
3141 Routine Description:
3142 if pSrc1 all zero with length Length, return 0.
3143 If not all zero, return 1
3144
3145 Arguments:
3146 pSrc1
3147
3148 Return Value:
3149 1: not all zero
3150 0: all zero
3151
3152 IRQL = DISPATCH_LEVEL
3153
3154 Note:
3155
3156 ========================================================================
3157*/
3158ULONG RTMPNotAllZero(
3159 IN PVOID pSrc1,
3160 IN ULONG Length)
3161{
3162 PUCHAR pMem1;
3163 ULONG Index = 0;
3164
3165 pMem1 = (PUCHAR) pSrc1;
3166
3167 for (Index = 0; Index < Length; Index++)
3168 {
3169 if (pMem1[Index] != 0x0)
3170 {
3171 break;
3172 }
3173 }
3174
3175 if (Index == Length)
3176 {
3177 return (0);
3178 }
3179 else
3180 {
3181 return (1);
3182 }
3183}
3184
3185/*
3186 ========================================================================
3187
3188 Routine Description:
3189 Compare two memory block
3190
3191 Arguments:
3192 pSrc1 Pointer to first memory address
3193 pSrc2 Pointer to second memory address
3194
3195 Return Value:
3196 0: memory is equal
3197 1: pSrc1 memory is larger
3198 2: pSrc2 memory is larger
3199
3200 IRQL = DISPATCH_LEVEL
3201
3202 Note:
3203
3204 ========================================================================
3205*/
3206ULONG RTMPCompareMemory(
3207 IN PVOID pSrc1,
3208 IN PVOID pSrc2,
3209 IN ULONG Length)
3210{
3211 PUCHAR pMem1;
3212 PUCHAR pMem2;
3213 ULONG Index = 0;
3214
3215 pMem1 = (PUCHAR) pSrc1;
3216 pMem2 = (PUCHAR) pSrc2;
3217
3218 for (Index = 0; Index < Length; Index++)
3219 {
3220 if (pMem1[Index] > pMem2[Index])
3221 return (1);
3222 else if (pMem1[Index] < pMem2[Index])
3223 return (2);
3224 }
3225
3226 // Equal
3227 return (0);
3228}
3229
3230/*
3231 ========================================================================
3232
3233 Routine Description:
3234 Zero out memory block
3235
3236 Arguments:
3237 pSrc1 Pointer to memory address
3238 Length Size
3239
3240 Return Value:
3241 None
3242
3243 IRQL = PASSIVE_LEVEL
3244 IRQL = DISPATCH_LEVEL
3245
3246 Note:
3247
3248 ========================================================================
3249*/
3250VOID RTMPZeroMemory(
3251 IN PVOID pSrc,
3252 IN ULONG Length)
3253{
3254 PUCHAR pMem;
3255 ULONG Index = 0;
3256
3257 pMem = (PUCHAR) pSrc;
3258
3259 for (Index = 0; Index < Length; Index++)
3260 {
3261 pMem[Index] = 0x00;
3262 }
3263}
3264
3265VOID RTMPFillMemory(
3266 IN PVOID pSrc,
3267 IN ULONG Length,
3268 IN UCHAR Fill)
3269{
3270 PUCHAR pMem;
3271 ULONG Index = 0;
3272
3273 pMem = (PUCHAR) pSrc;
3274
3275 for (Index = 0; Index < Length; Index++)
3276 {
3277 pMem[Index] = Fill;
3278 }
3279}
3280
3281/*
3282 ========================================================================
3283
3284 Routine Description:
3285 Copy data from memory block 1 to memory block 2
3286
3287 Arguments:
3288 pDest Pointer to destination memory address
3289 pSrc Pointer to source memory address
3290 Length Copy size
3291
3292 Return Value:
3293 None
3294
3295 IRQL = PASSIVE_LEVEL
3296 IRQL = DISPATCH_LEVEL
3297
3298 Note:
3299
3300 ========================================================================
3301*/
3302VOID RTMPMoveMemory(
3303 OUT PVOID pDest,
3304 IN PVOID pSrc,
3305 IN ULONG Length)
3306{
3307 PUCHAR pMem1;
3308 PUCHAR pMem2;
3309 UINT Index;
3310
3311 ASSERT((Length==0) || (pDest && pSrc));
3312
3313 pMem1 = (PUCHAR) pDest;
3314 pMem2 = (PUCHAR) pSrc;
3315
3316 for (Index = 0; Index < Length; Index++)
3317 {
3318 pMem1[Index] = pMem2[Index];
3319 }
3320}
3321
3322/*
3323 ========================================================================
3324
3325 Routine Description:
3326 Initialize port configuration structure
3327
3328 Arguments:
3329 Adapter Pointer to our adapter
3330
3331 Return Value:
3332 None
3333
3334 IRQL = PASSIVE_LEVEL
3335
3336 Note:
3337
3338 ========================================================================
3339*/
3340VOID UserCfgInit(
3341 IN PRTMP_ADAPTER pAd)
3342{
3343// EDCA_PARM DefaultEdcaParm;
3344 UINT key_index, bss_index;
3345
3346 DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
3347
3348 //
3349 // part I. intialize common configuration
3350 //
3351#ifdef RT2870
3352 pAd->BulkOutReq = 0;
3353
3354 pAd->BulkOutComplete = 0;
3355 pAd->BulkOutCompleteOther = 0;
3356 pAd->BulkOutCompleteCancel = 0;
3357 pAd->BulkInReq = 0;
3358 pAd->BulkInComplete = 0;
3359 pAd->BulkInCompleteFail = 0;
3360
3361 //pAd->QuickTimerP = 100;
3362 //pAd->TurnAggrBulkInCount = 0;
3363 pAd->bUsbTxBulkAggre = 0;
3364
3365 // init as unsed value to ensure driver will set to MCU once.
3366 pAd->LedIndicatorStregth = 0xFF;
3367
3368 pAd->CommonCfg.MaxPktOneTxBulk = 2;
3369 pAd->CommonCfg.TxBulkFactor = 1;
3370 pAd->CommonCfg.RxBulkFactor =1;
3371
3372 pAd->CommonCfg.TxPower = 100; //mW
3373
3374 NdisZeroMemory(&pAd->CommonCfg.IOTestParm, sizeof(pAd->CommonCfg.IOTestParm));
3375#endif // RT2870 //
3376
3377 for(key_index=0; key_index<SHARE_KEY_NUM; key_index++)
3378 {
3379 for(bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++)
3380 {
3381 pAd->SharedKey[bss_index][key_index].KeyLen = 0;
3382 pAd->SharedKey[bss_index][key_index].CipherAlg = CIPHER_NONE;
3383 }
3384 }
3385
3386 pAd->Antenna.word = 0;
3387 pAd->CommonCfg.BBPCurrentBW = BW_20;
3388
3389 pAd->LedCntl.word = 0;
3390
3391 pAd->bAutoTxAgcA = FALSE; // Default is OFF
3392 pAd->bAutoTxAgcG = FALSE; // Default is OFF
3393 pAd->RfIcType = RFIC_2820;
3394
3395 // Init timer for reset complete event
3396 pAd->CommonCfg.CentralChannel = 1;
3397 pAd->bForcePrintTX = FALSE;
3398 pAd->bForcePrintRX = FALSE;
3399 pAd->bStaFifoTest = FALSE;
3400 pAd->bProtectionTest = FALSE;
3401 pAd->bHCCATest = FALSE;
3402 pAd->bGenOneHCCA = FALSE;
3403 pAd->CommonCfg.Dsifs = 10; // in units of usec
3404 pAd->CommonCfg.TxPower = 100; //mW
3405 pAd->CommonCfg.TxPowerPercentage = 0xffffffff; // AUTO
3406 pAd->CommonCfg.TxPowerDefault = 0xffffffff; // AUTO
3407 pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto; // use Long preamble on TX by defaut
3408 pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
3409 pAd->CommonCfg.RtsThreshold = 2347;
3410 pAd->CommonCfg.FragmentThreshold = 2346;
3411 pAd->CommonCfg.UseBGProtection = 0; // 0: AUTO
3412 pAd->CommonCfg.bEnableTxBurst = TRUE; //0;
3413 pAd->CommonCfg.PhyMode = 0xff; // unknown
3414 pAd->CommonCfg.BandState = UNKNOWN_BAND;
3415 pAd->CommonCfg.RadarDetect.CSPeriod = 10;
3416 pAd->CommonCfg.RadarDetect.CSCount = 0;
3417 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
3418 pAd->CommonCfg.RadarDetect.ChMovingTime = 65;
3419 pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3;
3420 pAd->CommonCfg.bAPSDCapable = FALSE;
3421 pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
3422 pAd->CommonCfg.TriggerTimerCount = 0;
3423 pAd->CommonCfg.bAPSDForcePowerSave = FALSE;
3424 pAd->CommonCfg.bCountryFlag = FALSE;
3425 pAd->CommonCfg.TxStream = 0;
3426 pAd->CommonCfg.RxStream = 0;
3427
3428 NdisZeroMemory(&pAd->BeaconTxWI, sizeof(pAd->BeaconTxWI));
3429
3430#ifdef DOT11_N_SUPPORT
3431 NdisZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
3432 pAd->HTCEnable = FALSE;
3433 pAd->bBroadComHT = FALSE;
3434 pAd->CommonCfg.bRdg = FALSE;
3435
3436#ifdef DOT11N_DRAFT3
3437 pAd->CommonCfg.Dot11OBssScanPassiveDwell = dot11OBSSScanPassiveDwell; // Unit : TU. 5~1000
3438 pAd->CommonCfg.Dot11OBssScanActiveDwell = dot11OBSSScanActiveDwell; // Unit : TU. 10~1000
3439 pAd->CommonCfg.Dot11BssWidthTriggerScanInt = dot11BSSWidthTriggerScanInterval; // Unit : Second
3440 pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = dot11OBSSScanPassiveTotalPerChannel; // Unit : TU. 200~10000
3441 pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = dot11OBSSScanActiveTotalPerChannel; // Unit : TU. 20~10000
3442 pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = dot11BSSWidthChannelTransactionDelayFactor;
3443 pAd->CommonCfg.Dot11OBssScanActivityThre = dot11BSSScanActivityThreshold; // Unit : percentage
3444 pAd->CommonCfg.Dot11BssWidthChanTranDelay = (pAd->CommonCfg.Dot11BssWidthTriggerScanInt * pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor);
3445#endif // DOT11N_DRAFT3 //
3446
3447 NdisZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
3448 pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
3449 pAd->CommonCfg.BACapability.field.MpduDensity = 0;
3450 pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
3451 pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; //32;
3452 pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64; //32;
3453 DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit. BACapability = 0x%x\n", pAd->CommonCfg.BACapability.word));
3454
3455 pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
3456 BATableInit(pAd, &pAd->BATable);
3457
3458 pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1;
3459 pAd->CommonCfg.bHTProtect = 1;
3460 pAd->CommonCfg.bMIMOPSEnable = TRUE;
3461 pAd->CommonCfg.bBADecline = FALSE;
3462 pAd->CommonCfg.bDisableReordering = FALSE;
3463
3464 pAd->CommonCfg.TxBASize = 7;
3465
3466 pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
3467#endif // DOT11_N_SUPPORT //
3468
3469 //pAd->CommonCfg.HTPhyMode.field.BW = BW_20;
3470 //pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO;
3471 //pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800;
3472 //pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE;
3473 pAd->CommonCfg.TxRate = RATE_6;
3474
3475 pAd->CommonCfg.MlmeTransmit.field.MCS = MCS_RATE_6;
3476 pAd->CommonCfg.MlmeTransmit.field.BW = BW_20;
3477 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3478
3479 pAd->CommonCfg.BeaconPeriod = 100; // in mSec
3480
3481 //
3482 // part II. intialize STA specific configuration
3483 //
3484#ifdef CONFIG_STA_SUPPORT
3485 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3486 {
3487 RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT);
3488 RX_FILTER_CLEAR_FLAG(pAd, fRX_FILTER_ACCEPT_MULTICAST);
3489 RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_BROADCAST);
3490 RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_ALL_MULTICAST);
3491
3492 pAd->StaCfg.Psm = PWR_ACTIVE;
3493
3494 pAd->StaCfg.OrigWepStatus = Ndis802_11EncryptionDisabled;
3495 pAd->StaCfg.PairCipher = Ndis802_11EncryptionDisabled;
3496 pAd->StaCfg.GroupCipher = Ndis802_11EncryptionDisabled;
3497 pAd->StaCfg.bMixCipher = FALSE;
3498 pAd->StaCfg.DefaultKeyId = 0;
3499
3500 // 802.1x port control
3501 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
3502 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3503 pAd->StaCfg.LastMicErrorTime = 0;
3504 pAd->StaCfg.MicErrCnt = 0;
3505 pAd->StaCfg.bBlockAssoc = FALSE;
3506 pAd->StaCfg.WpaState = SS_NOTUSE;
3507
3508 pAd->CommonCfg.NdisRadioStateOff = FALSE; // New to support microsoft disable radio with OID command
3509
3510 pAd->StaCfg.RssiTrigger = 0;
3511 NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(RSSI_SAMPLE));
3512 pAd->StaCfg.RssiTriggerMode = RSSI_TRIGGERED_UPON_BELOW_THRESHOLD;
3513 pAd->StaCfg.AtimWin = 0;
3514 pAd->StaCfg.DefaultListenCount = 3;//default listen count;
3515 pAd->StaCfg.BssType = BSS_INFRA; // BSS_INFRA or BSS_ADHOC or BSS_MONITOR
3516 pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
3517 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
3518 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
3519
3520 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
3521 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3522 }
3523
3524#ifdef EXT_BUILD_CHANNEL_LIST
3525 pAd->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
3526#endif // EXT_BUILD_CHANNEL_LIST //
3527#endif // CONFIG_STA_SUPPORT //
3528
3529 // global variables mXXXX used in MAC protocol state machines
3530 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
3531 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
3532 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
3533
3534 // PHY specification
3535 pAd->CommonCfg.PhyMode = PHY_11BG_MIXED; // default PHY mode
3536 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); // CCK use LONG preamble
3537
3538#ifdef CONFIG_STA_SUPPORT
3539 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3540 {
3541 // user desired power mode
3542 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
3543 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
3544 pAd->StaCfg.bWindowsACCAMEnable = FALSE;
3545
3546#ifdef LEAP_SUPPORT
3547 // CCX v1.0 releated init value
3548 RTMPInitTimer(pAd, &pAd->StaCfg.LeapAuthTimer, GET_TIMER_FUNCTION(LeapAuthTimeout), pAd, FALSE);
3549 pAd->StaCfg.LeapAuthMode = CISCO_AuthModeLEAPNone;
3550 pAd->StaCfg.bCkipOn = FALSE;
3551#endif // LEAP_SUPPORT //
3552
3553 RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer, GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec), pAd, FALSE);
3554 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
3555
3556 // Patch for Ndtest
3557 pAd->StaCfg.ScanCnt = 0;
3558
3559 // CCX 2.0 control flag init
3560 pAd->StaCfg.CCXEnable = FALSE;
3561 pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
3562 pAd->StaCfg.CCXQosECWMin = 4;
3563 pAd->StaCfg.CCXQosECWMax = 10;
3564
3565 pAd->StaCfg.bHwRadio = TRUE; // Default Hardware Radio status is On
3566 pAd->StaCfg.bSwRadio = TRUE; // Default Software Radio status is On
3567 pAd->StaCfg.bRadio = TRUE; // bHwRadio && bSwRadio
3568 pAd->StaCfg.bHardwareRadio = FALSE; // Default is OFF
3569 pAd->StaCfg.bShowHiddenSSID = FALSE; // Default no show
3570
3571 // Nitro mode control
3572 pAd->StaCfg.bAutoReconnect = TRUE;
3573
3574 // Save the init time as last scan time, the system should do scan after 2 seconds.
3575 // This patch is for driver wake up from standby mode, system will do scan right away.
3576 pAd->StaCfg.LastScanTime = 0;
3577 NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1);
3578 sprintf(pAd->nickname, "%s", STA_NIC_DEVICE_NAME);
3579 RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), pAd, FALSE);
3580#ifdef WPA_SUPPLICANT_SUPPORT
3581 pAd->StaCfg.IEEE8021X = FALSE;
3582 pAd->StaCfg.IEEE8021x_required_keys = FALSE;
3583 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
3584#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
3585 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
3586#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
3587#endif // WPA_SUPPLICANT_SUPPORT //
3588
3589 }
3590#endif // CONFIG_STA_SUPPORT //
3591
3592 // Default for extra information is not valid
3593 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
3594
3595 // Default Config change flag
3596 pAd->bConfigChanged = FALSE;
3597
3598 //
3599 // part III. AP configurations
3600 //
3601
3602
3603 //
3604 // part IV. others
3605 //
3606 // dynamic BBP R66:sensibity tuning to overcome background noise
3607 pAd->BbpTuning.bEnable = TRUE;
3608 pAd->BbpTuning.FalseCcaLowerThreshold = 100;
3609 pAd->BbpTuning.FalseCcaUpperThreshold = 512;
3610 pAd->BbpTuning.R66Delta = 4;
3611 pAd->Mlme.bEnableAutoAntennaCheck = TRUE;
3612
3613 //
3614 // Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value.
3615 // if not initial this value, the default value will be 0.
3616 //
3617 pAd->BbpTuning.R66CurrentValue = 0x38;
3618
3619 pAd->Bbp94 = BBPR94_DEFAULT;
3620 pAd->BbpForCCK = FALSE;
3621
3622 // Default is FALSE for test bit 1
3623 //pAd->bTest1 = FALSE;
3624
3625 // initialize MAC table and allocate spin lock
3626 NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
3627 InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
3628 NdisAllocateSpinLock(&pAd->MacTabLock);
3629
3630 //RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE);
3631 //RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV);
3632
3633#ifdef RALINK_ATE
3634 NdisZeroMemory(&pAd->ate, sizeof(ATE_INFO));
3635 pAd->ate.Mode = ATE_STOP;
3636 pAd->ate.TxCount = 200;/* to exceed TX_RING_SIZE ... */
3637 pAd->ate.TxLength = 1024;
3638 pAd->ate.TxWI.ShortGI = 0;// LONG GI : 800 ns
3639 pAd->ate.TxWI.PHYMODE = MODE_CCK;
3640 pAd->ate.TxWI.MCS = 3;
3641 pAd->ate.TxWI.BW = BW_20;
3642 pAd->ate.Channel = 1;
3643 pAd->ate.QID = QID_AC_BE;
3644 pAd->ate.Addr1[0] = 0x00;
3645 pAd->ate.Addr1[1] = 0x11;
3646 pAd->ate.Addr1[2] = 0x22;
3647 pAd->ate.Addr1[3] = 0xAA;
3648 pAd->ate.Addr1[4] = 0xBB;
3649 pAd->ate.Addr1[5] = 0xCC;
3650 NdisMoveMemory(pAd->ate.Addr2, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
3651 NdisMoveMemory(pAd->ate.Addr3, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
3652 pAd->ate.bRxFer = 0;
3653 pAd->ate.bQATxStart = FALSE;
3654 pAd->ate.bQARxStart = FALSE;
3655#ifdef RALINK_28xx_QA
3656 //pAd->ate.Repeat = 0;
3657 pAd->ate.TxStatus = 0;
3658 pAd->ate.AtePid = THREAD_PID_INIT_VALUE;
3659#endif // RALINK_28xx_QA //
3660#endif // RALINK_ATE //
3661
3662
3663 pAd->CommonCfg.bWiFiTest = FALSE;
3664
3665
3666 DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
3667}
3668
3669// IRQL = PASSIVE_LEVEL
3670UCHAR BtoH(char ch)
3671{
3672 if (ch >= '0' && ch <= '9') return (ch - '0'); // Handle numerals
3673 if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA); // Handle capitol hex digits
3674 if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA); // Handle small hex digits
3675 return(255);
3676}
3677
3678//
3679// FUNCTION: AtoH(char *, UCHAR *, int)
3680//
3681// PURPOSE: Converts ascii string to network order hex
3682//
3683// PARAMETERS:
3684// src - pointer to input ascii string
3685// dest - pointer to output hex
3686// destlen - size of dest
3687//
3688// COMMENTS:
3689//
3690// 2 ascii bytes make a hex byte so must put 1st ascii byte of pair
3691// into upper nibble and 2nd ascii byte of pair into lower nibble.
3692//
3693// IRQL = PASSIVE_LEVEL
3694
3695void AtoH(char * src, UCHAR * dest, int destlen)
3696{
3697 char * srcptr;
3698 PUCHAR destTemp;
3699
3700 srcptr = src;
3701 destTemp = (PUCHAR) dest;
3702
3703 while(destlen--)
3704 {
3705 *destTemp = BtoH(*srcptr++) << 4; // Put 1st ascii byte in upper nibble.
3706 *destTemp += BtoH(*srcptr++); // Add 2nd ascii byte to above.
3707 destTemp++;
3708 }
3709}
3710
3711VOID RTMPPatchMacBbpBug(
3712 IN PRTMP_ADAPTER pAd)
3713{
3714 ULONG Index;
3715
3716 // Initialize BBP register to default value
3717 for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
3718 {
3719 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, (UCHAR)BBPRegTable[Index].Value);
3720 }
3721
3722 // Initialize RF register to default value
3723 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
3724 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
3725
3726 // Re-init BBP register from EEPROM value
3727 NICInitAsicFromEEPROM(pAd);
3728}
3729
3730/*
3731 ========================================================================
3732
3733 Routine Description:
3734 Init timer objects
3735
3736 Arguments:
3737 pAd Pointer to our adapter
3738 pTimer Timer structure
3739 pTimerFunc Function to execute when timer expired
3740 Repeat Ture for period timer
3741
3742 Return Value:
3743 None
3744
3745 Note:
3746
3747 ========================================================================
3748*/
3749VOID RTMPInitTimer(
3750 IN PRTMP_ADAPTER pAd,
3751 IN PRALINK_TIMER_STRUCT pTimer,
3752 IN PVOID pTimerFunc,
3753 IN PVOID pData,
3754 IN BOOLEAN Repeat)
3755{
3756 //
3757 // Set Valid to TRUE for later used.
3758 // It will crash if we cancel a timer or set a timer
3759 // that we haven't initialize before.
3760 //
3761 pTimer->Valid = TRUE;
3762
3763 pTimer->PeriodicType = Repeat;
3764 pTimer->State = FALSE;
3765 pTimer->cookie = (ULONG) pData;
3766
3767#ifdef RT2870
3768 pTimer->pAd = pAd;
3769#endif // RT2870 //
3770
3771 RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (PVOID) pTimer);
3772}
3773
3774/*
3775 ========================================================================
3776
3777 Routine Description:
3778 Init timer objects
3779
3780 Arguments:
3781 pTimer Timer structure
3782 Value Timer value in milliseconds
3783
3784 Return Value:
3785 None
3786
3787 Note:
3788 To use this routine, must call RTMPInitTimer before.
3789
3790 ========================================================================
3791*/
3792VOID RTMPSetTimer(
3793 IN PRALINK_TIMER_STRUCT pTimer,
3794 IN ULONG Value)
3795{
3796 if (pTimer->Valid)
3797 {
3798 pTimer->TimerValue = Value;
3799 pTimer->State = FALSE;
3800 if (pTimer->PeriodicType == TRUE)
3801 {
3802 pTimer->Repeat = TRUE;
3803 RTMP_SetPeriodicTimer(&pTimer->TimerObj, Value);
3804 }
3805 else
3806 {
3807 pTimer->Repeat = FALSE;
3808 RTMP_OS_Add_Timer(&pTimer->TimerObj, Value);
3809 }
3810 }
3811 else
3812 {
3813 DBGPRINT_ERR(("RTMPSetTimer failed, Timer hasn't been initialize!\n"));
3814 }
3815}
3816
3817
3818/*
3819 ========================================================================
3820
3821 Routine Description:
3822 Init timer objects
3823
3824 Arguments:
3825 pTimer Timer structure
3826 Value Timer value in milliseconds
3827
3828 Return Value:
3829 None
3830
3831 Note:
3832 To use this routine, must call RTMPInitTimer before.
3833
3834 ========================================================================
3835*/
3836VOID RTMPModTimer(
3837 IN PRALINK_TIMER_STRUCT pTimer,
3838 IN ULONG Value)
3839{
3840 BOOLEAN Cancel;
3841
3842 if (pTimer->Valid)
3843 {
3844 pTimer->TimerValue = Value;
3845 pTimer->State = FALSE;
3846 if (pTimer->PeriodicType == TRUE)
3847 {
3848 RTMPCancelTimer(pTimer, &Cancel);
3849 RTMPSetTimer(pTimer, Value);
3850 }
3851 else
3852 {
3853 RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value);
3854 }
3855 }
3856 else
3857 {
3858 DBGPRINT_ERR(("RTMPModTimer failed, Timer hasn't been initialize!\n"));
3859 }
3860}
3861
3862/*
3863 ========================================================================
3864
3865 Routine Description:
3866 Cancel timer objects
3867
3868 Arguments:
3869 Adapter Pointer to our adapter
3870
3871 Return Value:
3872 None
3873
3874 IRQL = PASSIVE_LEVEL
3875 IRQL = DISPATCH_LEVEL
3876
3877 Note:
3878 1.) To use this routine, must call RTMPInitTimer before.
3879 2.) Reset NIC to initial state AS IS system boot up time.
3880
3881 ========================================================================
3882*/
3883VOID RTMPCancelTimer(
3884 IN PRALINK_TIMER_STRUCT pTimer,
3885 OUT BOOLEAN *pCancelled)
3886{
3887 if (pTimer->Valid)
3888 {
3889 if (pTimer->State == FALSE)
3890 pTimer->Repeat = FALSE;
3891 RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled);
3892
3893 if (*pCancelled == TRUE)
3894 pTimer->State = TRUE;
3895
3896#ifdef RT2870
3897 // We need to go-through the TimerQ to findout this timer handler and remove it if
3898 // it's still waiting for execution.
3899
3900 RT2870_TimerQ_Remove(pTimer->pAd, pTimer);
3901#endif // RT2870 //
3902 }
3903 else
3904 {
3905 //
3906 // NdisMCancelTimer just canced the timer and not mean release the timer.
3907 // And don't set the "Valid" to False. So that we can use this timer again.
3908 //
3909 DBGPRINT_ERR(("RTMPCancelTimer failed, Timer hasn't been initialize!\n"));
3910 }
3911}
3912
3913/*
3914 ========================================================================
3915
3916 Routine Description:
3917 Set LED Status
3918
3919 Arguments:
3920 pAd Pointer to our adapter
3921 Status LED Status
3922
3923 Return Value:
3924 None
3925
3926 IRQL = PASSIVE_LEVEL
3927 IRQL = DISPATCH_LEVEL
3928
3929 Note:
3930
3931 ========================================================================
3932*/
3933VOID RTMPSetLED(
3934 IN PRTMP_ADAPTER pAd,
3935 IN UCHAR Status)
3936{
3937 //ULONG data;
3938 UCHAR HighByte = 0;
3939 UCHAR LowByte;
3940
3941// In ATE mode of RT2860 AP/STA, we have erased 8051 firmware.
3942// So LED mode is not supported when ATE is running.
3943#ifdef RALINK_ATE
3944 if (ATE_ON(pAd))
3945 return;
3946#endif // RALINK_ATE //
3947
3948 LowByte = pAd->LedCntl.field.LedMode&0x7f;
3949 switch (Status)
3950 {
3951 case LED_LINK_DOWN:
3952 HighByte = 0x20;
3953 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3954 pAd->LedIndicatorStregth = 0;
3955 break;
3956 case LED_LINK_UP:
3957 if (pAd->CommonCfg.Channel > 14)
3958 HighByte = 0xa0;
3959 else
3960 HighByte = 0x60;
3961 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3962 break;
3963 case LED_RADIO_ON:
3964 HighByte = 0x20;
3965 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3966 break;
3967 case LED_HALT:
3968 LowByte = 0; // Driver sets MAC register and MAC controls LED
3969 case LED_RADIO_OFF:
3970 HighByte = 0;
3971 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3972 break;
3973 case LED_WPS:
3974 HighByte = 0x10;
3975 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3976 break;
3977 case LED_ON_SITE_SURVEY:
3978 HighByte = 0x08;
3979 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3980 break;
3981 case LED_POWER_UP:
3982 HighByte = 0x04;
3983 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3984 break;
3985 default:
3986 DBGPRINT(RT_DEBUG_WARN, ("RTMPSetLED::Unknown Status %d\n", Status));
3987 break;
3988 }
3989
3990 //
3991 // Keep LED status for LED SiteSurvey mode.
3992 // After SiteSurvey, we will set the LED mode to previous status.
3993 //
3994 if ((Status != LED_ON_SITE_SURVEY) && (Status != LED_POWER_UP))
3995 pAd->LedStatus = Status;
3996
3997 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetLED::Mode=%d,HighByte=0x%02x,LowByte=0x%02x\n", pAd->LedCntl.field.LedMode, HighByte, LowByte));
3998}
3999
4000/*
4001 ========================================================================
4002
4003 Routine Description:
4004 Set LED Signal Stregth
4005
4006 Arguments:
4007 pAd Pointer to our adapter
4008 Dbm Signal Stregth
4009
4010 Return Value:
4011 None
4012
4013 IRQL = PASSIVE_LEVEL
4014
4015 Note:
4016 Can be run on any IRQL level.
4017
4018 According to Microsoft Zero Config Wireless Signal Stregth definition as belows.
4019 <= -90 No Signal
4020 <= -81 Very Low
4021 <= -71 Low
4022 <= -67 Good
4023 <= -57 Very Good
4024 > -57 Excellent
4025 ========================================================================
4026*/
4027VOID RTMPSetSignalLED(
4028 IN PRTMP_ADAPTER pAd,
4029 IN NDIS_802_11_RSSI Dbm)
4030{
4031 UCHAR nLed = 0;
4032
4033 //
4034 // if not Signal Stregth, then do nothing.
4035 //
4036 if (pAd->LedCntl.field.LedMode != LED_MODE_SIGNAL_STREGTH)
4037 {
4038 return;
4039 }
4040
4041 if (Dbm <= -90)
4042 nLed = 0;
4043 else if (Dbm <= -81)
4044 nLed = 1;
4045 else if (Dbm <= -71)
4046 nLed = 3;
4047 else if (Dbm <= -67)
4048 nLed = 7;
4049 else if (Dbm <= -57)
4050 nLed = 15;
4051 else
4052 nLed = 31;
4053
4054 //
4055 // Update Signal Stregth to firmware if changed.
4056 //
4057 if (pAd->LedIndicatorStregth != nLed)
4058 {
4059 AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, pAd->LedCntl.field.Polarity);
4060 pAd->LedIndicatorStregth = nLed;
4061 }
4062}
4063
4064/*
4065 ========================================================================
4066
4067 Routine Description:
4068 Enable RX
4069
4070 Arguments:
4071 pAd Pointer to our adapter
4072
4073 Return Value:
4074 None
4075
4076 IRQL <= DISPATCH_LEVEL
4077
4078 Note:
4079 Before Enable RX, make sure you have enabled Interrupt.
4080 ========================================================================
4081*/
4082VOID RTMPEnableRxTx(
4083 IN PRTMP_ADAPTER pAd)
4084{
4085// WPDMA_GLO_CFG_STRUC GloCfg;
4086// ULONG i = 0;
4087
4088 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
4089
4090#if 0
4091 // Enable Rx DMA.
4092 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
4093 do
4094 {
4095 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
4096 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
4097 break;
4098
4099 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
4100 RTMPusecDelay(1000);
4101 i++;
4102 }while ( i <200);
4103
4104 RTMPusecDelay(50);
4105 RT28XX_DMA_WRITE_INIT(GloCfg);
4106 DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
4107 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
4108
4109 RT28XX_DMA_POST_WRITE(pAd);
4110#else
4111 // Enable Rx DMA.
4112 RT28XXDMAEnable(pAd);
4113#endif
4114
4115 // enable RX of MAC block
4116 if (pAd->OpMode == OPMODE_AP)
4117 {
4118 UINT32 rx_filter_flag = APNORMAL;
4119
4120
4121 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); // enable RX of DMA block
4122 }
4123 else
4124 {
4125 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
4126 }
4127
4128 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
4129 DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n"));
4130}
4131
4132
diff --git a/drivers/staging/rt2870/common/rtmp_tkip.c b/drivers/staging/rt2870/common/rtmp_tkip.c
new file mode 100644
index 00000000000..2847409ff08
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/common/rtmp_wep.c b/drivers/staging/rt2870/common/rtmp_wep.c
new file mode 100644
index 00000000000..62f9e58729d
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/common/rtusb_bulk.c b/drivers/staging/rt2870/common/rtusb_bulk.c
new file mode 100644
index 00000000000..3c6ba1b9deb
--- /dev/null
+++ b/drivers/staging/rt2870/common/rtusb_bulk.c
@@ -0,0 +1,1981 @@
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 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
295 {
296 // Limit BulkOut size to about 4k bytes.
297 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
298 break;
299 }
300 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
301 {
302 // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
303 // 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.
304 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
305 break;
306 }
307 }
308 // end Iverson
309 else
310 {
311 if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
312 { // Limit BulkOut size to about 24k bytes.
313 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
314 break;
315 }
316 else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
317 { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
318 // 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.
319 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
320 break;
321 }
322 }
323
324 if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
325 {
326 pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
327 break;
328 }
329
330 if (pTxInfo->QSEL != FIFO_EDCA)
331 {
332 printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __FUNCTION__, pTxInfo->QSEL);
333 printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
334 hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
335 }
336
337 if (pTxInfo->USBDMATxPktLen <= 8)
338 {
339 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
340 DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
341 pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
342 {
343 DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n",
344 pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
345 ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
346 }
347 pAd->bForcePrintTX = TRUE;
348 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
349 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
350 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
351 //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
352 return;
353 }
354
355 // Increase Total transmit byte counter
356 pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount;
357 pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount;
358
359 pLastTxInfo = pTxInfo;
360
361 // Make sure we use EDCA QUEUE.
362 pTxInfo->QSEL = FIFO_EDCA;
363 ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
364 TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
365
366 if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
367 pTxInfo->USBDMANextVLD = 1;
368
369 if (pTxInfo->SwUseLastRound == 1)
370 {
371 if (pHTTXContext->CurWritePosition == 8)
372 pTxInfo->USBDMANextVLD = 0;
373 pTxInfo->SwUseLastRound = 0;
374
375 bTxQLastRound = TRUE;
376 pHTTXContext->ENextBulkOutPosition = 8;
377
378 #ifdef RT_BIG_ENDIAN
379 RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
380 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
381 #endif // RT_BIG_ENDIAN //
382
383 break;
384 }
385
386#ifdef RT_BIG_ENDIAN
387 RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
388 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
389#endif // RT_BIG_ENDIAN //
390
391 }while (TRUE);
392
393 // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
394 if (pLastTxInfo)
395 {
396#ifdef RT_BIG_ENDIAN
397 RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
398#endif // RT_BIG_ENDIAN //
399 pLastTxInfo->USBDMANextVLD = 0;
400#ifdef RT_BIG_ENDIAN
401 RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
402#endif // RT_BIG_ENDIAN //
403 }
404
405 /*
406 We need to copy SavedPad when following condition matched!
407 1. Not the last round of the TxQueue and
408 2. any match of following cases:
409 (1). The End Position of this bulk out is reach to the Currenct Write position and
410 the TxInfo and related header already write to the CurWritePosition.
411 =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
412
413 (2). The EndPosition of the bulk out is not reach to the Current Write Position.
414 =>(ENextBulkOutPosition != CurWritePosition)
415 */
416 if ((bTxQLastRound == FALSE) &&
417 (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
418 (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
419 )
420 {
421 NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
422 pHTTXContext->bCopySavePad = TRUE;
423 if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
424 {
425 PUCHAR pBuf = &pHTTXContext->SavedPad[0];
426 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",
427 pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
428 pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
429
430 pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
431 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]));
432 }
433 //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
434 }
435
436 if (pAd->bForcePrintTX == TRUE)
437 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));
438 //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));
439
440 // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
441 pAppendant = &pWirelessPkt[TmpBulkEndPos];
442 NdisZeroMemory(pAppendant, 8);
443 ThisBulkSize += 4;
444 pHTTXContext->LastOne = TRUE;
445 if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
446 ThisBulkSize += 4;
447 pHTTXContext->BulkOutSize = ThisBulkSize;
448
449 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
450 BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
451
452 // Init Tx context descriptor
453 RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
454
455 pUrb = pHTTXContext->pUrb;
456 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
457 {
458 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
459
460 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
461 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
462 pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
463 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
464
465 return;
466 }
467
468 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
469 pHTTXContext->IRPPending = TRUE;
470 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
471 pAd->BulkOutReq++;
472
473}
474
475
476VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
477{
478#if 0 // sample, IRQ LOCK
479 PRTMP_ADAPTER pAd;
480 POS_COOKIE pObj;
481 PHT_TX_CONTEXT pHTTXContext;
482 UCHAR BulkOutPipeId;
483 NTSTATUS Status;
484 unsigned long IrqFlags;
485
486 DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutDataPacketComplete\n"));
487
488 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
489 pAd = pHTTXContext->pAd;
490 pObj = (POS_COOKIE) pAd->OS_Cookie;
491 Status = pUrb->status;
492
493 // Store BulkOut PipeId
494 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
495 pAd->BulkOutDataOneSecCount++;
496
497 //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
498 // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
499
500 RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
501 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
502 pHTTXContext->IRPPending = FALSE;
503 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
504
505 if (Status == USB_ST_NOERROR)
506 {
507 pAd->BulkOutComplete++;
508
509 pAd->Counters8023.GoodTransmits++;
510 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
511 FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
512 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
513
514
515 }
516 else // STATUS_OTHER
517 {
518 PUCHAR pBuf;
519
520 pAd->BulkOutCompleteOther++;
521
522 pBuf = &pHTTXContext->TransferBuffer->WirelessPacket[pHTTXContext->NextBulkOutPosition];
523
524 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
525 DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
526 DBGPRINT_RAW(RT_DEBUG_ERROR, (">>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]));
527 //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
528
529 if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
530 fRTMP_ADAPTER_HALT_IN_PROGRESS |
531 fRTMP_ADAPTER_NIC_NOT_EXIST |
532 fRTMP_ADAPTER_BULKOUT_RESET)))
533 {
534 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
535 pAd->bulkResetPipeid = BulkOutPipeId;
536 }
537 }
538
539 //
540 // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
541 // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
542 //
543 //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
544 if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
545 (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
546 !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
547 {
548 // Indicate There is data avaliable
549 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
550 }
551 //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
552
553 // Always call Bulk routine, even reset bulk.
554 // The protection of rest bulk should be in BulkOut routine
555 RTUSBKickBulkOut(pAd);
556
557
558 //DBGPRINT(RT_DEBUG_LOUD,("Done-A(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d\n", BulkOutPipeId, in_interrupt(),
559 // pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
560
561 switch (BulkOutPipeId)
562 {
563 case 0:
564 pObj->ac0_dma_done_task.data = (unsigned long)pAd;
565 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
566 break;
567 case 1:
568 pObj->ac1_dma_done_task.data = (unsigned long)pAd;
569 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
570 break;
571 case 2:
572 pObj->ac2_dma_done_task.data = (unsigned long)pAd;
573 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
574 break;
575 case 3:
576 pObj->ac3_dma_done_task.data = (unsigned long)pAd;
577 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
578 break;
579 case 4:
580 pObj->hcca_dma_done_task.data = (unsigned long)pAd;
581 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
582 break;
583 }
584#else
585
586{
587 PHT_TX_CONTEXT pHTTXContext;
588 PRTMP_ADAPTER pAd;
589 POS_COOKIE pObj;
590 UCHAR BulkOutPipeId;
591
592
593 pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
594 pAd = pHTTXContext->pAd;
595 pObj = (POS_COOKIE) pAd->OS_Cookie;
596
597 // Store BulkOut PipeId
598 BulkOutPipeId = pHTTXContext->BulkOutPipeId;
599 pAd->BulkOutDataOneSecCount++;
600
601 switch (BulkOutPipeId)
602 {
603 case 0:
604 pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
605 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
606 break;
607 case 1:
608 pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
609 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
610 break;
611 case 2:
612 pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
613 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
614 break;
615 case 3:
616 pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
617 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
618 break;
619 case 4:
620 pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
621 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
622 break;
623 }
624}
625#endif
626
627
628}
629
630
631/*
632 ========================================================================
633
634 Routine Description:
635
636 Arguments:
637
638 Return Value:
639
640 Note: NULL frame use BulkOutPipeId = 0
641
642 ========================================================================
643*/
644VOID RTUSBBulkOutNullFrame(
645 IN PRTMP_ADAPTER pAd)
646{
647 PTX_CONTEXT pNullContext = &(pAd->NullContext);
648 PURB pUrb;
649 int ret = 0;
650 unsigned long IrqFlags;
651
652 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
653 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
654 {
655 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
656 return;
657 }
658 pAd->BulkOutPending[0] = TRUE;
659 pAd->watchDogTxPendingCnt[0] = 1;
660 pNullContext->IRPPending = TRUE;
661 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
662
663 // Increase Total transmit byte counter
664 pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
665
666
667 // Clear Null frame bulk flag
668 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
669
670#ifdef RT_BIG_ENDIAN
671 RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO);
672#endif // RT_BIG_ENDIAN //
673
674 // Init Tx context descriptor
675 RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
676
677 pUrb = pNullContext->pUrb;
678 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
679 {
680 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
681 pAd->BulkOutPending[0] = FALSE;
682 pAd->watchDogTxPendingCnt[0] = 0;
683 pNullContext->IRPPending = FALSE;
684 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
685
686 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
687 return;
688 }
689
690}
691
692// NULL frame use BulkOutPipeId = 0
693VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
694{
695 PRTMP_ADAPTER pAd;
696 PTX_CONTEXT pNullContext;
697 NTSTATUS Status;
698#if 0 // sample, IRQ LOCK
699 unsigned long IrqFlags;
700#endif
701 POS_COOKIE pObj;
702
703
704 pNullContext = (PTX_CONTEXT)pUrb->context;
705 pAd = pNullContext->pAd;
706 Status = pUrb->status;
707
708#if 0 // sample, IRQ LOCK
709 // Reset Null frame context flags
710 pNullContext->IRPPending = FALSE;
711 pNullContext->InUse = FALSE;
712
713 if (Status == USB_ST_NOERROR)
714 {
715 // Don't worry about the queue is empty or not, this function will check itself
716 //RTMPUSBDeQueuePacket(pAd, 0);
717 RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
718 }
719 else // STATUS_OTHER
720 {
721 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
722 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
723 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
724 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
725 {
726 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed\n"));
727 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
728 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
729 }
730 }
731
732 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
733 pAd->BulkOutPending[0] = FALSE;
734 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
735
736 // Always call Bulk routine, even reset bulk.
737 // The protectioon of rest bulk should be in BulkOut routine
738 RTUSBKickBulkOut(pAd);
739#else
740
741 pObj = (POS_COOKIE) pAd->OS_Cookie;
742 pObj->null_frame_complete_task.data = (unsigned long)pUrb;
743 tasklet_hi_schedule(&pObj->null_frame_complete_task);
744#endif
745
746}
747
748#if 0 // For RT2870, RTS frame not used now, but maybe will use it latter.
749/*
750 ========================================================================
751
752 Routine Description:
753
754 Arguments:
755
756 Return Value:
757
758 Note: RTS frame use BulkOutPipeId = 0
759
760 ========================================================================
761*/
762VOID RTUSBBulkOutRTSFrame(
763 IN PRTMP_ADAPTER pAd)
764{
765 PTX_CONTEXT pRTSContext = &(pAd->RTSContext);
766 PURB pUrb;
767 int ret = 0;
768 unsigned long IrqFlags;
769 UCHAR PipeID=0;
770
771 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
772 PipeID= 3;
773 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
774 PipeID= 2;
775 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
776 PipeID= 1;
777 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
778 PipeID= 0;
779
780 RTMP_IRQ_LOCK(&pAd->BulkOutLock[PipeID], IrqFlags);
781 if ((pAd->BulkOutPending[PipeID] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
782 {
783 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[PipeID], IrqFlags);
784 return;
785 }
786 pAd->BulkOutPending[PipeID] = TRUE;
787 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[PipeID], IrqFlags);
788
789 // Increase Total transmit byte counter
790 pAd->RalinkCounters.TransmittedByteCount += pRTSContext->BulkOutSize;
791
792 DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutRTSFrame \n"));
793
794 // Clear RTS frame bulk flag
795 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_RTS);
796
797#ifdef RT_BIG_ENDIAN
798 RTMPDescriptorEndianChange((PUCHAR)pRTSContext->TransferBuffer, TYPE_TXINFO);
799#endif // RT_BIG_ENDIAN //
800
801 // Init Tx context descriptor
802 RTUSBInitTxDesc(pAd, pRTSContext, PipeID, (usb_complete_t)RTUSBBulkOutRTSFrameComplete);
803 pRTSContext->IRPPending = TRUE;
804
805 pUrb = pRTSContext->pUrb;
806 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
807 {
808 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutRTSFrame: Submit Tx URB failed %d\n", ret));
809 return;
810 }
811
812 DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutRTSFrame \n"));
813
814}
815
816// RTS frame use BulkOutPipeId = 0
817VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
818{
819 PRTMP_ADAPTER pAd;
820 PTX_CONTEXT pRTSContext;
821 NTSTATUS Status;
822#if 0 // sample, IRQ LOCK
823 unsigned long IrqFlags;
824#endif
825 POS_COOKIE pObj;
826
827 DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutRTSFrameComplete\n"));
828
829 pRTSContext = (PTX_CONTEXT)pUrb->context;
830 pAd = pRTSContext->pAd;
831 Status = pUrb->status;
832
833#if 0 // sample, IRQ LOCK
834 // Reset RTS frame context flags
835 pRTSContext->IRPPending = FALSE;
836 pRTSContext->InUse = FALSE;
837
838 if (Status == USB_ST_NOERROR)
839 {
840 // Don't worry about the queue is empty or not, this function will check itself
841 //RTMPUSBDeQueuePacket(pAd, pRTSContext->BulkOutPipeId);
842 RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
843 }
844 else // STATUS_OTHER
845 {
846 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
847 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
848 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
849 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
850 {
851 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
852 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
853 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
854 }
855 }
856
857 RTMP_IRQ_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId], IrqFlags);
858 pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
859 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId], IrqFlags);
860
861 // Always call Bulk routine, even reset bulk.
862 // The protectioon of rest bulk should be in BulkOut routine
863 RTUSBKickBulkOut(pAd);
864#else
865
866 pObj = (POS_COOKIE) pAd->OS_Cookie;
867 pObj->rts_frame_complete_task.data = (unsigned long)pUrb;
868 tasklet_hi_schedule(&pObj->rts_frame_complete_task);
869#endif
870
871 DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutRTSFrameComplete\n"));
872
873}
874#endif
875
876/*
877 ========================================================================
878
879 Routine Description:
880
881 Arguments:
882
883 Return Value:
884
885 Note: MLME use BulkOutPipeId = 0
886
887 ========================================================================
888*/
889VOID RTUSBBulkOutMLMEPacket(
890 IN PRTMP_ADAPTER pAd,
891 IN UCHAR Index)
892{
893 PTX_CONTEXT pMLMEContext;
894 PURB pUrb;
895 int ret = 0;
896 unsigned long IrqFlags;
897
898 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
899 pUrb = pMLMEContext->pUrb;
900
901 if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
902 (pMLMEContext->InUse == FALSE) ||
903 (pMLMEContext->bWaitingBulkOut == FALSE))
904 {
905
906
907 // Clear MLME bulk flag
908 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
909
910 return;
911 }
912
913
914 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
915 if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
916 {
917 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
918 return;
919 }
920
921 pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
922 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
923 pMLMEContext->IRPPending = TRUE;
924 pMLMEContext->bWaitingBulkOut = FALSE;
925 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
926
927 // Increase Total transmit byte counter
928 pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
929
930 // Clear MLME bulk flag
931 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
932
933
934 //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacket\n"));
935#if 0 // for debug
936{
937 printk("MLME-Out, C=%d!, D=%d, F=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
938
939 //TODO: Need to remove it when formal release
940 PTXINFO_STRUC pTxInfo;
941
942 pTxInfo = (PTXINFO_STRUC)pMLMEContext->TransferBuffer;
943 if (pTxInfo->QSEL != FIFO_EDCA)
944 {
945 printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __FUNCTION__, pTxInfo->QSEL);
946 printk("\tMLME_Index=%d!\n", Index);
947 hex_dump("Wrong QSel Pkt:", (PUCHAR)pMLMEContext->TransferBuffer, pTxInfo->USBDMATxPktLen);
948 }
949}
950#endif
951
952#ifdef RT_BIG_ENDIAN
953 RTMPDescriptorEndianChange((PUCHAR)pMLMEContext->TransferBuffer, TYPE_TXINFO);
954#endif // RT_BIG_ENDIAN //
955
956 // Init Tx context descriptor
957 RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
958
959#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
960 //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
961 pUrb->transfer_dma = 0;
962 pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
963#endif
964
965 pUrb = pMLMEContext->pUrb;
966 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
967 {
968 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
969 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
970 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
971 pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
972 pMLMEContext->IRPPending = FALSE;
973 pMLMEContext->bWaitingBulkOut = TRUE;
974 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
975
976 return;
977 }
978
979 //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
980// printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
981}
982
983
984VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
985{
986 PTX_CONTEXT pMLMEContext;
987 PRTMP_ADAPTER pAd;
988 NTSTATUS Status;
989 POS_COOKIE pObj;
990 int index;
991#if 0 // sample, IRQ LOCK
992 unsigned long IrqFlags;
993 PNDIS_PACKET pPacket;
994#endif
995
996
997 //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
998 pMLMEContext = (PTX_CONTEXT)pUrb->context;
999 pAd = pMLMEContext->pAd;
1000 pObj = (POS_COOKIE)pAd->OS_Cookie;
1001 Status = pUrb->status;
1002 index = pMLMEContext->SelfIdx;
1003
1004
1005#if 0 // sample, IRQ LOCK
1006 ASSERT((pAd->MgmtRing.TxDmaIdx == index));
1007 //printk("MLME-Done-B: C=%d, D=%d, F=%d, Self=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx, pMLMEContext->SelfIdx);
1008
1009 RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1010
1011
1012 if (Status != USB_ST_NOERROR)
1013 {
1014 //Bulk-Out fail status handle
1015 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1016 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1017 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1018 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1019 {
1020 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
1021 // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
1022 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1023 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1024 }
1025 }
1026 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1027 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
1028
1029 RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1030 // Reset MLME context flags
1031 pMLMEContext->IRPPending = FALSE;
1032 pMLMEContext->InUse = FALSE;
1033 pMLMEContext->bWaitingBulkOut = FALSE;
1034 pMLMEContext->BulkOutSize = 0;
1035
1036 pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
1037 pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
1038
1039 // Increase MgmtRing Index
1040 INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
1041 pAd->MgmtRing.TxSwFreeIdx++;
1042
1043 RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
1044
1045 // No-matter success or fail, we free the mgmt packet.
1046 if (pPacket)
1047 RTMPFreeNdisPacket(pAd, pPacket);
1048
1049#if 0
1050 //Bulk-Out fail status handle
1051 if (Status != USB_ST_NOERROR)
1052 {
1053 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1054 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1055 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1056 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1057 {
1058 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
1059 // TODO: How to handle about the MLMEBulkOut failed issue. Need to reset the endpoint?
1060 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1061 pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
1062 }
1063 }
1064#endif
1065
1066 //printk("MLME-Done-A: C=%d, D=%d, F=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
1067
1068 pObj->mgmt_dma_done_task.data = (unsigned long)pAd;
1069 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
1070
1071 //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacketComplete\n"));
1072// printk("<---RTUSBBulkOutMLMEPacketComplete, Cpu=%d, Dma=%d, SwIdx=%d!\n",
1073// pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
1074
1075#else
1076
1077 pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
1078 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
1079#endif
1080}
1081
1082
1083/*
1084 ========================================================================
1085
1086 Routine Description:
1087
1088 Arguments:
1089
1090 Return Value:
1091
1092 Note: PsPoll use BulkOutPipeId = 0
1093
1094 ========================================================================
1095*/
1096VOID RTUSBBulkOutPsPoll(
1097 IN PRTMP_ADAPTER pAd)
1098{
1099 PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
1100 PURB pUrb;
1101 int ret = 0;
1102 unsigned long IrqFlags;
1103
1104 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1105 if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
1106 {
1107 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1108 return;
1109 }
1110 pAd->BulkOutPending[0] = TRUE;
1111 pAd->watchDogTxPendingCnt[0] = 1;
1112 pPsPollContext->IRPPending = TRUE;
1113 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1114
1115
1116 // Clear PS-Poll bulk flag
1117 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
1118
1119#ifdef RT_BIG_ENDIAN
1120 RTMPDescriptorEndianChange((PUCHAR)pPsPollContext->TransferBuffer, TYPE_TXINFO);
1121#endif // RT_BIG_ENDIAN //
1122
1123 // Init Tx context descriptor
1124 RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
1125
1126 pUrb = pPsPollContext->pUrb;
1127 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1128 {
1129 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1130 pAd->BulkOutPending[0] = FALSE;
1131 pAd->watchDogTxPendingCnt[0] = 0;
1132 pPsPollContext->IRPPending = FALSE;
1133 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1134
1135 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
1136 return;
1137 }
1138
1139}
1140
1141// PS-Poll frame use BulkOutPipeId = 0
1142VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
1143{
1144 PRTMP_ADAPTER pAd;
1145 PTX_CONTEXT pPsPollContext;
1146 NTSTATUS Status;
1147#if 0 // sample, IRQ LOCK
1148 unsigned long IrqFlags;
1149#endif
1150 POS_COOKIE pObj;
1151
1152
1153 pPsPollContext= (PTX_CONTEXT)pUrb->context;
1154 pAd = pPsPollContext->pAd;
1155 Status = pUrb->status;
1156
1157#if 0 // sample, IRQ LOCK
1158 // Reset PsPoll context flags
1159 pPsPollContext->IRPPending = FALSE;
1160 pPsPollContext->InUse = FALSE;
1161
1162 if (Status == USB_ST_NOERROR)
1163 {
1164 // Don't worry about the queue is empty or not, this function will check itself
1165 RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1166 }
1167 else // STATUS_OTHER
1168 {
1169 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1170 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1171 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
1172 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
1173 {
1174 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
1175 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1176 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
1177 }
1178 }
1179
1180 RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1181 pAd->BulkOutPending[0] = FALSE;
1182 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1183
1184 // Always call Bulk routine, even reset bulk.
1185 // The protectioon of rest bulk should be in BulkOut routine
1186 RTUSBKickBulkOut(pAd);
1187#else
1188
1189 pObj = (POS_COOKIE) pAd->OS_Cookie;
1190 pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
1191 tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
1192#endif
1193}
1194
1195
1196#if 0
1197/*
1198 ========================================================================
1199
1200 Routine Description:
1201 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
1202 to USB. It checks if an Rx Descriptor is available and passes the
1203 the coresponding buffer to be filled. If no descriptor is available
1204 fails the request. When setting the completion routine we pass our
1205 Adapter Object as Context.
1206
1207 Arguments:
1208
1209 Return Value:
1210 TRUE found matched tuple cache
1211 FALSE no matched found
1212
1213 Note:
1214
1215 ========================================================================
1216*/
1217VOID RTUSBBulkReceive(
1218 IN PRTMP_ADAPTER pAd)
1219{
1220 PRX_CONTEXT pRxContext;
1221 PURB pUrb;
1222 int ret = 0;
1223 unsigned long IrqFlags;
1224
1225
1226 /* device had been closed */
1227 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS))
1228 return;
1229
1230 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1231
1232 // Last is time point between 2 separate URB.
1233 if (pAd->NextRxBulkInPosition == 0)
1234 {
1235 //pAd->NextRxBulkInIndex = (pAd->NextRxBulkInIndex + 1) % (RX_RING_SIZE);
1236 INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
1237 }
1238 else if ((pAd->NextRxBulkInPosition&0x1ff) != 0)
1239 {
1240 //pAd->NextRxBulkInIndex = (pAd->NextRxBulkInIndex + 1) % (RX_RING_SIZE);
1241 INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
1242 DBGPRINT_RAW(RT_DEBUG_TRACE, ("pAd->NextRxBulkInPosition = 0x%lx. End of URB.\n", pAd->NextRxBulkInPosition ));
1243 pAd->NextRxBulkInPosition = 0;
1244 }
1245
1246 if (pAd->NextRxBulkInPosition == MAX_RXBULK_SIZE)
1247 pAd->NextRxBulkInPosition = 0;
1248
1249 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1250
1251 // TODO: Why need to check if pRxContext->InUsed == TRUE?
1252 //if ((pRxContext->InUse == TRUE) || (pRxContext->Readable == TRUE))
1253 if ((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE))
1254 {
1255 DBGPRINT_RAW(RT_DEBUG_TRACE, ("pRxContext[%d] InUse = %d.pRxContext->Readable = %d. Return.\n", pAd->NextRxBulkInIndex,pRxContext->InUse, pRxContext->Readable ));
1256 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1257
1258 // read RxContext, Since not
1259#ifdef CONFIG_STA_SUPPORT
1260 STARxDoneInterruptHandle(pAd, TRUE);
1261#endif // CONFIG_STA_SUPPORT //
1262
1263 //return;
1264 }
1265 pRxContext->InUse = TRUE;
1266 pRxContext->IRPPending= TRUE;
1267
1268 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1269
1270 // Init Rx context descriptor
1271 NdisZeroMemory(pRxContext->TransferBuffer, BUFFER_SIZE);
1272 RTUSBInitRxDesc(pAd, pRxContext);
1273
1274 pUrb = pRxContext->pUrb;
1275 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1276 {
1277 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
1278 return;
1279 }
1280 else // success
1281 {
1282 NdisInterlockedIncrement(&pAd->PendingRx);
1283 pAd->BulkInReq++;
1284 }
1285
1286 // read RxContext, Since not
1287#ifdef CONFIG_STA_SUPPORT
1288 STARxDoneInterruptHandle(pAd, FALSE);
1289#endif // CONFIG_STA_SUPPORT //
1290}
1291
1292/*
1293 ========================================================================
1294
1295 Routine Description:
1296 This routine process Rx Irp and call rx complete function.
1297
1298 Arguments:
1299 DeviceObject Pointer to the device object for next lower
1300 device. DeviceObject passed in here belongs to
1301 the next lower driver in the stack because we
1302 were invoked via IoCallDriver in USB_RxPacket
1303 AND it is not OUR device object
1304 Irp Ptr to completed IRP
1305 Context Ptr to our Adapter object (context specified
1306 in IoSetCompletionRoutine
1307
1308 Return Value:
1309 Always returns STATUS_MORE_PROCESSING_REQUIRED
1310
1311 Note:
1312 Always returns STATUS_MORE_PROCESSING_REQUIRED
1313 ========================================================================
1314*/
1315VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
1316{
1317#if 0
1318 PRX_CONTEXT pRxContext;
1319 PRTMP_ADAPTER pAd;
1320 NTSTATUS Status;
1321// POS_COOKIE pObj;
1322
1323 pRxContext = (PRX_CONTEXT)pUrb->context;
1324 pAd = pRxContext->pAd;
1325// pObj = (POS_COOKIE) pAd->OS_Cookie;
1326
1327
1328 Status = pUrb->status;
1329 //pRxContext->pIrp = NULL;
1330
1331 pRxContext->InUse = FALSE;
1332 pRxContext->IRPPending = FALSE;
1333
1334 if (Status == USB_ST_NOERROR)
1335 {
1336 pAd->BulkInComplete++;
1337 pRxContext->Readable = TRUE;
1338 pAd->NextRxBulkInPosition = 0;
1339
1340 }
1341 else // STATUS_OTHER
1342 {
1343 pAd->BulkInCompleteFail++;
1344 // Still read this packet although it may comtain wrong bytes.
1345 pRxContext->Readable = FALSE;
1346 // Parsing all packets. because after reset, the index will reset to all zero.
1347
1348 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1349 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET)) &&
1350 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1351 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1352 {
1353
1354 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status = %d\n", Status));
1355 DBGPRINT_RAW(RT_DEBUG_ERROR, ("==>NextRxBulkInIndex=0x%x, NextRxBulkInReadIndex=0x%x, TransferBufferLength= 0x%x\n",
1356 pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
1357
1358 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1359 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
1360 }
1361 //pUrb = NULL;
1362 }
1363
1364 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
1365 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET)) &&
1366// (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) &&
1367 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) &&
1368 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
1369 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1370 {
1371 RTUSBBulkReceive(pAd);
1372#if 0
1373#if 1
1374 STARxDoneInterruptHandle(pAd, FALSE);
1375#else
1376 pObj->rx_bh.data = (unsigned long)pUrb;
1377 tasklet_schedule(&pObj->rx_bh);
1378#endif
1379#endif
1380 }
1381
1382 // Call RxPacket to process packet and return the status
1383 NdisInterlockedDecrement(&pAd->PendingRx);
1384#else
1385
1386
1387 // use a receive tasklet to handle received packets;
1388 // or sometimes hardware IRQ will be disabled here, so we can not
1389 // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
1390 PRX_CONTEXT pRxContext;
1391 PRTMP_ADAPTER pAd;
1392 POS_COOKIE pObj;
1393
1394
1395 pRxContext = (PRX_CONTEXT)pUrb->context;
1396 pAd = pRxContext->pAd;
1397 pObj = (POS_COOKIE) pAd->OS_Cookie;
1398
1399 pObj->rx_done_task.data = (unsigned long)pUrb;
1400 tasklet_hi_schedule(&pObj->rx_done_task);
1401#endif
1402}
1403
1404#else
1405
1406VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
1407{
1408 PRX_CONTEXT pRxContext;
1409 PURB pUrb;
1410 int ret = 0;
1411 unsigned long IrqFlags;
1412
1413 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1414 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1415 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
1416 {
1417 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1418 return;
1419 }
1420 pRxContext->InUse = TRUE;
1421 pRxContext->IRPPending = TRUE;
1422 pAd->PendingRx++;
1423 pAd->BulkInReq++;
1424 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1425
1426 // Init Rx context descriptor
1427 NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
1428 RTUSBInitRxDesc(pAd, pRxContext);
1429
1430 pUrb = pRxContext->pUrb;
1431 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1432 { // fail
1433
1434 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1435 pRxContext->InUse = FALSE;
1436 pRxContext->IRPPending = FALSE;
1437 pAd->PendingRx--;
1438 pAd->BulkInReq--;
1439 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1440 DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
1441 }
1442 else
1443 { // success
1444#if 0
1445 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1446 pRxContext->IRPPending = TRUE;
1447 //NdisInterlockedIncrement(&pAd->PendingRx);
1448 pAd->PendingRx++;
1449 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1450 pAd->BulkInReq++;
1451#endif
1452 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1453 //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
1454 }
1455}
1456
1457
1458/*
1459 ========================================================================
1460
1461 Routine Description:
1462 USB_RxPacket initializes a URB and uses the Rx IRP to submit it
1463 to USB. It checks if an Rx Descriptor is available and passes the
1464 the coresponding buffer to be filled. If no descriptor is available
1465 fails the request. When setting the completion routine we pass our
1466 Adapter Object as Context.
1467
1468 Arguments:
1469
1470 Return Value:
1471 TRUE found matched tuple cache
1472 FALSE no matched found
1473
1474 Note:
1475
1476 ========================================================================
1477*/
1478#define fRTMP_ADAPTER_NEED_STOP_RX \
1479 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
1480 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
1481 fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
1482
1483#define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
1484 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
1485 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
1486 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
1487
1488VOID RTUSBBulkReceive(
1489 IN PRTMP_ADAPTER pAd)
1490{
1491 PRX_CONTEXT pRxContext;
1492 unsigned long IrqFlags;
1493
1494
1495 /* sanity check */
1496 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
1497 return;
1498
1499 while(1)
1500 {
1501
1502 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1503 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
1504 if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
1505 (pRxContext->bRxHandling == FALSE))
1506 {
1507 pRxContext->bRxHandling = TRUE;
1508 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1509
1510 // read RxContext, Since not
1511#ifdef CONFIG_STA_SUPPORT
1512 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1513 STARxDoneInterruptHandle(pAd, TRUE);
1514#endif // CONFIG_STA_SUPPORT //
1515
1516 // Finish to handle this bulkIn buffer.
1517 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1518 pRxContext->BulkInOffset = 0;
1519 pRxContext->Readable = FALSE;
1520 pRxContext->bRxHandling = FALSE;
1521 pAd->ReadPosition = 0;
1522 pAd->TransferBufferLength = 0;
1523 INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
1524 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1525
1526 }
1527 else
1528 {
1529 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1530 break;
1531 }
1532 }
1533
1534 if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
1535 DoBulkIn(pAd);
1536
1537}
1538
1539
1540/*
1541 ========================================================================
1542
1543 Routine Description:
1544 This routine process Rx Irp and call rx complete function.
1545
1546 Arguments:
1547 DeviceObject Pointer to the device object for next lower
1548 device. DeviceObject passed in here belongs to
1549 the next lower driver in the stack because we
1550 were invoked via IoCallDriver in USB_RxPacket
1551 AND it is not OUR device object
1552 Irp Ptr to completed IRP
1553 Context Ptr to our Adapter object (context specified
1554 in IoSetCompletionRoutine
1555
1556 Return Value:
1557 Always returns STATUS_MORE_PROCESSING_REQUIRED
1558
1559 Note:
1560 Always returns STATUS_MORE_PROCESSING_REQUIRED
1561 ========================================================================
1562*/
1563VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
1564{
1565 // use a receive tasklet to handle received packets;
1566 // or sometimes hardware IRQ will be disabled here, so we can not
1567 // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
1568 PRX_CONTEXT pRxContext;
1569 PRTMP_ADAPTER pAd;
1570 POS_COOKIE pObj;
1571
1572
1573 pRxContext = (PRX_CONTEXT)pUrb->context;
1574 pAd = pRxContext->pAd;
1575 pObj = (POS_COOKIE) pAd->OS_Cookie;
1576
1577 pObj->rx_done_task.data = (unsigned long)pUrb;
1578 tasklet_hi_schedule(&pObj->rx_done_task);
1579
1580}
1581
1582#endif
1583
1584
1585
1586/*
1587 ========================================================================
1588
1589 Routine Description:
1590
1591 Arguments:
1592
1593 Return Value:
1594
1595 Note:
1596
1597 ========================================================================
1598*/
1599VOID RTUSBKickBulkOut(
1600 IN PRTMP_ADAPTER pAd)
1601{
1602 // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
1603 if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
1604#ifdef RALINK_ATE
1605 && !(ATE_ON(pAd))
1606#endif // RALINK_ATE //
1607 )
1608 {
1609#if 0 // not used now in RT28xx, but may used latter.
1610 // 1. Data Fragment has highest priority
1611 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG))
1612 {
1613 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1614 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1615 ))
1616 {
1617 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
1618 }
1619 }
1620 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_2))
1621 {
1622 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1623 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1624 ))
1625 {
1626 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
1627 }
1628 }
1629 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_3))
1630 {
1631 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1632 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1633 ))
1634 {
1635 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
1636 }
1637 }
1638 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_FRAG_4))
1639 {
1640 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1641 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1642 ))
1643 {
1644 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
1645 }
1646 }
1647#endif
1648
1649 // 2. PS-Poll frame is next
1650 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
1651 {
1652 RTUSBBulkOutPsPoll(pAd);
1653 }
1654
1655 // 5. Mlme frame is next
1656 else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
1657 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
1658 {
1659 RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
1660 }
1661
1662 // 6. Data frame normal is next
1663 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
1664 {
1665 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1666 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1667 ))
1668 {
1669 RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
1670 }
1671 }
1672 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
1673 {
1674 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1675 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1676 ))
1677 {
1678 RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
1679 }
1680 }
1681 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
1682 {
1683 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1684 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1685 ))
1686 {
1687 RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
1688 }
1689 }
1690 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
1691 {
1692 if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
1693 (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1694 ))
1695 {
1696 RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
1697 }
1698 }
1699
1700 // 7. Null frame is the last
1701 else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
1702 {
1703 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1704 {
1705 RTUSBBulkOutNullFrame(pAd);
1706 }
1707 }
1708
1709 // 8. No data avaliable
1710 else
1711 {
1712
1713 }
1714 }
1715#ifdef RALINK_ATE
1716 /* If the mode is in ATE mode. */
1717 else if((ATE_ON(pAd)) &&
1718 !RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX))// PETER : watch out !
1719 {
1720 if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE))
1721 {
1722 ATE_RTUSBBulkOutDataPacket(pAd, 0);
1723 }
1724 }
1725#endif // RALINK_ATE //
1726
1727}
1728
1729/*
1730 ========================================================================
1731
1732 Routine Description:
1733 Call from Reset action after BulkOut failed.
1734 Arguments:
1735
1736 Return Value:
1737
1738 Note:
1739
1740 ========================================================================
1741*/
1742VOID RTUSBCleanUpDataBulkOutQueue(
1743 IN PRTMP_ADAPTER pAd)
1744{
1745 UCHAR Idx;
1746 PHT_TX_CONTEXT pTxContext;
1747
1748 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
1749
1750 for (Idx = 0; Idx < 4; Idx++)
1751 {
1752 pTxContext = &pAd->TxContext[Idx];
1753
1754 pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
1755 pTxContext->LastOne = FALSE;
1756 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1757 pAd->BulkOutPending[Idx] = FALSE;
1758 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1759 }
1760
1761 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
1762}
1763
1764/*
1765 ========================================================================
1766
1767 Routine Description:
1768
1769 Arguments:
1770
1771 Return Value:
1772
1773 Note:
1774
1775 ========================================================================
1776*/
1777VOID RTUSBCleanUpMLMEBulkOutQueue(
1778 IN PRTMP_ADAPTER pAd)
1779{
1780 DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
1781
1782#if 0 // Do nothing!
1783 NdisAcquireSpinLock(&pAd->MLMEBulkOutLock);
1784 while (pAd->PrioRingTxCnt > 0)
1785 {
1786 pAd->MLMEContext[pAd->PrioRingFirstIndex].InUse = FALSE;
1787
1788 pAd->PrioRingFirstIndex++;
1789 if (pAd->PrioRingFirstIndex >= MGMT_RING_SIZE)
1790 {
1791 pAd->PrioRingFirstIndex = 0;
1792 }
1793
1794 pAd->PrioRingTxCnt--;
1795 }
1796 NdisReleaseSpinLock(&pAd->MLMEBulkOutLock);
1797#endif
1798
1799 DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
1800}
1801
1802
1803/*
1804 ========================================================================
1805
1806 Routine Description:
1807
1808 Arguments:
1809
1810 Return Value:
1811
1812
1813 Note:
1814
1815 ========================================================================
1816*/
1817VOID RTUSBCancelPendingIRPs(
1818 IN PRTMP_ADAPTER pAd)
1819{
1820 RTUSBCancelPendingBulkInIRP(pAd);
1821 RTUSBCancelPendingBulkOutIRP(pAd);
1822}
1823
1824/*
1825 ========================================================================
1826
1827 Routine Description:
1828
1829 Arguments:
1830
1831 Return Value:
1832
1833 Note:
1834
1835 ========================================================================
1836*/
1837VOID RTUSBCancelPendingBulkInIRP(
1838 IN PRTMP_ADAPTER pAd)
1839{
1840 PRX_CONTEXT pRxContext;
1841 UINT i;
1842
1843 DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
1844 for ( i = 0; i < (RX_RING_SIZE); i++)
1845 {
1846 pRxContext = &(pAd->RxContext[i]);
1847 if(pRxContext->IRPPending == TRUE)
1848 {
1849 RTUSB_UNLINK_URB(pRxContext->pUrb);
1850 pRxContext->IRPPending = FALSE;
1851 pRxContext->InUse = FALSE;
1852 //NdisInterlockedDecrement(&pAd->PendingRx);
1853 //pAd->PendingRx--;
1854 }
1855 }
1856 DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
1857}
1858
1859
1860/*
1861 ========================================================================
1862
1863 Routine Description:
1864
1865 Arguments:
1866
1867 Return Value:
1868
1869 Note:
1870
1871 ========================================================================
1872*/
1873VOID RTUSBCancelPendingBulkOutIRP(
1874 IN PRTMP_ADAPTER pAd)
1875{
1876 PHT_TX_CONTEXT pHTTXContext;
1877 PTX_CONTEXT pMLMEContext;
1878 PTX_CONTEXT pBeaconContext;
1879 PTX_CONTEXT pNullContext;
1880 PTX_CONTEXT pPsPollContext;
1881 PTX_CONTEXT pRTSContext;
1882 UINT i, Idx;
1883// unsigned int IrqFlags;
1884// NDIS_SPIN_LOCK *pLock;
1885// BOOLEAN *pPending;
1886
1887
1888// pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
1889// pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
1890
1891 for (Idx = 0; Idx < 4; Idx++)
1892 {
1893 pHTTXContext = &(pAd->TxContext[Idx]);
1894
1895 if (pHTTXContext->IRPPending == TRUE)
1896 {
1897
1898 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1899 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1900 // when the last IRP on the list has been cancelled; that's how we exit this loop
1901 //
1902
1903 RTUSB_UNLINK_URB(pHTTXContext->pUrb);
1904
1905 // Sleep 200 microseconds to give cancellation time to work
1906 RTMPusecDelay(200);
1907 }
1908
1909#ifdef RALINK_ATE
1910 pHTTXContext->bCopySavePad = 0;
1911 pHTTXContext->CurWritePosition = 0;
1912 pHTTXContext->CurWriteRealPos = 0;
1913 pHTTXContext->bCurWriting = FALSE;
1914 pHTTXContext->NextBulkOutPosition = 0;
1915 pHTTXContext->ENextBulkOutPosition = 0;
1916#endif // RALINK_ATE //
1917 pAd->BulkOutPending[Idx] = FALSE;
1918 }
1919
1920 //RTMP_IRQ_LOCK(pLock, IrqFlags);
1921 for (i = 0; i < MGMT_RING_SIZE; i++)
1922 {
1923 pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
1924 if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
1925 {
1926
1927 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1928 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1929 // when the last IRP on the list has been cancelled; that's how we exit this loop
1930 //
1931
1932 RTUSB_UNLINK_URB(pMLMEContext->pUrb);
1933 pMLMEContext->IRPPending = FALSE;
1934
1935 // Sleep 200 microsecs to give cancellation time to work
1936 RTMPusecDelay(200);
1937 }
1938 }
1939 pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
1940 //RTMP_IRQ_UNLOCK(pLock, IrqFlags);
1941
1942
1943 for (i = 0; i < BEACON_RING_SIZE; i++)
1944 {
1945 pBeaconContext = &(pAd->BeaconContext[i]);
1946
1947 if(pBeaconContext->IRPPending == TRUE)
1948 {
1949
1950 // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
1951 // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
1952 // when the last IRP on the list has been cancelled; that's how we exit this loop
1953 //
1954
1955 RTUSB_UNLINK_URB(pBeaconContext->pUrb);
1956
1957 // Sleep 200 microsecs to give cancellation time to work
1958 RTMPusecDelay(200);
1959 }
1960 }
1961
1962 pNullContext = &(pAd->NullContext);
1963 if (pNullContext->IRPPending == TRUE)
1964 RTUSB_UNLINK_URB(pNullContext->pUrb);
1965
1966 pRTSContext = &(pAd->RTSContext);
1967 if (pRTSContext->IRPPending == TRUE)
1968 RTUSB_UNLINK_URB(pRTSContext->pUrb);
1969
1970 pPsPollContext = &(pAd->PsPollContext);
1971 if (pPsPollContext->IRPPending == TRUE)
1972 RTUSB_UNLINK_URB(pPsPollContext->pUrb);
1973
1974 for (Idx = 0; Idx < 4; Idx++)
1975 {
1976 NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
1977 pAd->BulkOutPending[Idx] = FALSE;
1978 NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
1979 }
1980}
1981
diff --git a/drivers/staging/rt2870/common/rtusb_data.c b/drivers/staging/rt2870/common/rtusb_data.c
new file mode 100644
index 00000000000..5a0d78389f4
--- /dev/null
+++ b/drivers/staging/rt2870/common/rtusb_data.c
@@ -0,0 +1,229 @@
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
44VOID REPORT_AMSDU_FRAMES_TO_LLC(
45 IN PRTMP_ADAPTER pAd,
46 IN PUCHAR pData,
47 IN ULONG DataSize)
48{
49 PNDIS_PACKET pPacket;
50 UINT nMSDU;
51 struct sk_buff *pSkb;
52
53 nMSDU = 0;
54 /* allocate a rx packet */
55 pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE);
56 pPacket = (PNDIS_PACKET)OSPKT_TO_RTPKT(pSkb);
57 if (pSkb)
58 {
59
60 /* convert 802.11 to 802.3 packet */
61 pSkb->dev = get_netdev_from_bssid(pAd, BSS0);
62 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
63 deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
64 }
65 else
66 {
67 DBGPRINT(RT_DEBUG_ERROR,("Can't allocate skb\n"));
68 }
69}
70
71NDIS_STATUS RTUSBFreeDescriptorRequest(
72 IN PRTMP_ADAPTER pAd,
73 IN UCHAR BulkOutPipeId,
74 IN UINT32 NumberRequired)
75{
76// UCHAR FreeNumber = 0;
77// UINT Index;
78 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
79 unsigned long IrqFlags;
80 HT_TX_CONTEXT *pHTTXContext;
81
82
83 pHTTXContext = &pAd->TxContext[BulkOutPipeId];
84 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
85 if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) && ((pHTTXContext->CurWritePosition + NumberRequired + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition))
86 {
87
88 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
89 }
90 else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < (NumberRequired + LOCAL_TXBUF_SIZE)))
91 {
92 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
93 }
94 else if (pHTTXContext->bCurWriting == TRUE)
95 {
96 DBGPRINT(RT_DEBUG_TRACE,("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", BulkOutPipeId, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
97 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
98 }
99 else
100 {
101 Status = NDIS_STATUS_SUCCESS;
102 }
103 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
104
105
106 return (Status);
107}
108
109NDIS_STATUS RTUSBFreeDescriptorRelease(
110 IN RTMP_ADAPTER *pAd,
111 IN UCHAR BulkOutPipeId)
112{
113 unsigned long IrqFlags;
114 HT_TX_CONTEXT *pHTTXContext;
115
116 pHTTXContext = &pAd->TxContext[BulkOutPipeId];
117 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
118 pHTTXContext->bCurWriting = FALSE;
119 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
120
121 return (NDIS_STATUS_SUCCESS);
122}
123
124
125BOOLEAN RTUSBNeedQueueBackForAgg(
126 IN RTMP_ADAPTER *pAd,
127 IN UCHAR BulkOutPipeId)
128{
129 unsigned long IrqFlags;
130 HT_TX_CONTEXT *pHTTXContext;
131 BOOLEAN needQueBack = FALSE;
132
133 pHTTXContext = &pAd->TxContext[BulkOutPipeId];
134
135 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
136 if ((pHTTXContext->IRPPending == TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */)
137 {
138#if 0
139 if ((pHTTXContext->CurWritePosition <= 8) &&
140 (pHTTXContext->NextBulkOutPosition > 8 && (pHTTXContext->NextBulkOutPosition+MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT))
141 {
142 needQueBack = TRUE;
143 }
144 else if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) &&
145 ((pHTTXContext->NextBulkOutPosition + MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT))
146 {
147 needQueBack = TRUE;
148 }
149#else
150 if ((pHTTXContext->CurWritePosition < pHTTXContext->ENextBulkOutPosition) &&
151 (((pHTTXContext->ENextBulkOutPosition+MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT) || (pHTTXContext->CurWritePosition > MAX_AGGREGATION_SIZE)))
152 {
153 needQueBack = TRUE;
154 }
155#endif
156 else if ((pHTTXContext->CurWritePosition > pHTTXContext->ENextBulkOutPosition) &&
157 ((pHTTXContext->ENextBulkOutPosition + MAX_AGGREGATION_SIZE) < pHTTXContext->CurWritePosition))
158 {
159 needQueBack = TRUE;
160 }
161 }
162 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
163
164 return needQueBack;
165
166}
167
168
169/*
170 ========================================================================
171
172 Routine Description:
173
174 Arguments:
175
176 Return Value:
177
178 IRQL =
179
180 Note:
181
182 ========================================================================
183*/
184VOID RTUSBRejectPendingPackets(
185 IN PRTMP_ADAPTER pAd)
186{
187 UCHAR Index;
188 PQUEUE_ENTRY pEntry;
189 PNDIS_PACKET pPacket;
190 PQUEUE_HEADER pQueue;
191
192
193 for (Index = 0; Index < 4; Index++)
194 {
195 NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]);
196 while (pAd->TxSwQueue[Index].Head != NULL)
197 {
198 pQueue = (PQUEUE_HEADER) &(pAd->TxSwQueue[Index]);
199 pEntry = RemoveHeadQueue(pQueue);
200 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
201 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
202 }
203 NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]);
204
205 }
206
207}
208
209VOID RTMPWriteTxInfo(
210 IN PRTMP_ADAPTER pAd,
211 IN PTXINFO_STRUC pTxInfo,
212 IN USHORT USBDMApktLen,
213 IN BOOLEAN bWiv,
214 IN UCHAR QueueSel,
215 IN UCHAR NextValid,
216 IN UCHAR TxBurst)
217{
218 pTxInfo->USBDMATxPktLen = USBDMApktLen;
219 pTxInfo->QSEL = QueueSel;
220 if (QueueSel != FIFO_EDCA)
221 DBGPRINT(RT_DEBUG_TRACE, ("====> QueueSel != FIFO_EDCA<============\n"));
222 pTxInfo->USBDMANextVLD = FALSE; //NextValid; // Need to check with Jan about this.
223 pTxInfo->USBDMATxburst = TxBurst;
224 pTxInfo->WIV = bWiv;
225 pTxInfo->SwUseLastRound = 0;
226 pTxInfo->rsv = 0;
227 pTxInfo->rsv2 = 0;
228}
229
diff --git a/drivers/staging/rt2870/common/rtusb_io.c b/drivers/staging/rt2870/common/rtusb_io.c
new file mode 100644
index 00000000000..6db443e9268
--- /dev/null
+++ b/drivers/staging/rt2870/common/rtusb_io.c
@@ -0,0 +1,2006 @@
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 return Status;
114}
115
116
117/*
118 ========================================================================
119
120 Routine Description: Get current firmware operation mode (Return Value)
121
122 Arguments:
123
124 Return Value:
125 0 or 1 = Downloaded by host driver
126 others = Driver doesn't download firmware
127
128 IRQL =
129
130 Note:
131
132 ========================================================================
133*/
134NTSTATUS RTUSBFirmwareOpmode(
135 IN PRTMP_ADAPTER pAd,
136 OUT PUINT32 pValue)
137{
138 NTSTATUS Status;
139
140 Status = RTUSB_VendorRequest(
141 pAd,
142 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
143 DEVICE_VENDOR_REQUEST_IN,
144 0x1,
145 0x11,
146 0,
147 pValue,
148 4);
149 return Status;
150}
151NTSTATUS RTUSBVenderReset(
152 IN PRTMP_ADAPTER pAd)
153{
154 NTSTATUS Status;
155 DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n"));
156 Status = RTUSB_VendorRequest(
157 pAd,
158 USBD_TRANSFER_DIRECTION_OUT,
159 DEVICE_VENDOR_REQUEST_OUT,
160 0x01,
161 0x1,
162 0,
163 NULL,
164 0);
165
166 DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n"));
167 return Status;
168}
169/*
170 ========================================================================
171
172 Routine Description: Read various length data from RT2573
173
174 Arguments:
175
176 Return Value:
177
178 IRQL =
179
180 Note:
181
182 ========================================================================
183*/
184NTSTATUS RTUSBMultiRead(
185 IN PRTMP_ADAPTER pAd,
186 IN USHORT Offset,
187 OUT PUCHAR pData,
188 IN USHORT length)
189{
190 NTSTATUS Status;
191
192 Status = RTUSB_VendorRequest(
193 pAd,
194 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
195 DEVICE_VENDOR_REQUEST_IN,
196 0x7,
197 0,
198 Offset,
199 pData,
200 length);
201
202 return Status;
203}
204
205/*
206 ========================================================================
207
208 Routine Description: Write various length data to RT2573
209
210 Arguments:
211
212 Return Value:
213
214 IRQL =
215
216 Note:
217
218 ========================================================================
219*/
220NTSTATUS RTUSBMultiWrite_OneByte(
221 IN PRTMP_ADAPTER pAd,
222 IN USHORT Offset,
223 IN PUCHAR pData)
224{
225 NTSTATUS Status;
226
227 // TODO: In 2870, use this funciton carefully cause it's not stable.
228 Status = RTUSB_VendorRequest(
229 pAd,
230 USBD_TRANSFER_DIRECTION_OUT,
231 DEVICE_VENDOR_REQUEST_OUT,
232 0x6,
233 0,
234 Offset,
235 pData,
236 1);
237
238 return Status;
239}
240
241NTSTATUS RTUSBMultiWrite(
242 IN PRTMP_ADAPTER pAd,
243 IN USHORT Offset,
244 IN PUCHAR pData,
245 IN USHORT length)
246{
247 NTSTATUS Status;
248
249
250 USHORT index = 0,Value;
251 PUCHAR pSrc = pData;
252 USHORT resude = 0;
253
254 resude = length % 2;
255 length += resude;
256 do
257 {
258 Value =(USHORT)( *pSrc | (*(pSrc + 1) << 8));
259 Status = RTUSBSingleWrite(pAd,Offset + index,Value);
260 index +=2;
261 length -= 2;
262 pSrc = pSrc + 2;
263 }while(length > 0);
264
265 return Status;
266}
267
268
269NTSTATUS RTUSBSingleWrite(
270 IN RTMP_ADAPTER *pAd,
271 IN USHORT Offset,
272 IN USHORT Value)
273{
274 NTSTATUS Status;
275
276 Status = RTUSB_VendorRequest(
277 pAd,
278 USBD_TRANSFER_DIRECTION_OUT,
279 DEVICE_VENDOR_REQUEST_OUT,
280 0x2,
281 Value,
282 Offset,
283 NULL,
284 0);
285
286 return Status;
287
288}
289
290
291/*
292 ========================================================================
293
294 Routine Description: Read 32-bit MAC register
295
296 Arguments:
297
298 Return Value:
299
300 IRQL =
301
302 Note:
303
304 ========================================================================
305*/
306NTSTATUS RTUSBReadMACRegister(
307 IN PRTMP_ADAPTER pAd,
308 IN USHORT Offset,
309 OUT PUINT32 pValue)
310{
311 NTSTATUS Status;
312 UINT32 localVal;
313
314 Status = RTUSB_VendorRequest(
315 pAd,
316 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
317 DEVICE_VENDOR_REQUEST_IN,
318 0x7,
319 0,
320 Offset,
321 &localVal,
322 4);
323
324 *pValue = le2cpu32(localVal);
325
326
327 if (Status < 0)
328 *pValue = 0xffffffff;
329
330 return Status;
331}
332
333
334/*
335 ========================================================================
336
337 Routine Description: Write 32-bit MAC register
338
339 Arguments:
340
341 Return Value:
342
343 IRQL =
344
345 Note:
346
347 ========================================================================
348*/
349NTSTATUS RTUSBWriteMACRegister(
350 IN PRTMP_ADAPTER pAd,
351 IN USHORT Offset,
352 IN UINT32 Value)
353{
354 NTSTATUS Status;
355 UINT32 localVal;
356
357 localVal = Value;
358
359 Status = RTUSBSingleWrite(pAd, Offset, (USHORT)(localVal & 0xffff));
360 Status = RTUSBSingleWrite(pAd, Offset + 2, (USHORT)((localVal & 0xffff0000) >> 16));
361
362 return Status;
363}
364
365
366
367#if 1
368/*
369 ========================================================================
370
371 Routine Description: Read 8-bit BBP register
372
373 Arguments:
374
375 Return Value:
376
377 IRQL =
378
379 Note:
380
381 ========================================================================
382*/
383NTSTATUS RTUSBReadBBPRegister(
384 IN PRTMP_ADAPTER pAd,
385 IN UCHAR Id,
386 IN PUCHAR pValue)
387{
388 BBP_CSR_CFG_STRUC BbpCsr;
389 UINT i = 0;
390 NTSTATUS status;
391
392 // Verify the busy condition
393 do
394 {
395 status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
396 if(status >= 0)
397 {
398 if (!(BbpCsr.field.Busy == BUSY))
399 break;
400 }
401 printk("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", i);
402 i++;
403 }
404 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
405
406 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
407 {
408 //
409 // Read failed then Return Default value.
410 //
411 *pValue = pAd->BbpWriteLatch[Id];
412
413 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
414 return STATUS_UNSUCCESSFUL;
415 }
416
417 // Prepare for write material
418 BbpCsr.word = 0;
419 BbpCsr.field.fRead = 1;
420 BbpCsr.field.Busy = 1;
421 BbpCsr.field.RegNum = Id;
422 RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
423
424 i = 0;
425 // Verify the busy condition
426 do
427 {
428 status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
429 if (status >= 0)
430 {
431 if (!(BbpCsr.field.Busy == BUSY))
432 {
433 *pValue = (UCHAR)BbpCsr.field.Value;
434 break;
435 }
436 }
437 printk("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", i);
438 i++;
439 }
440 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
441
442 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
443 {
444 //
445 // Read failed then Return Default value.
446 //
447 *pValue = pAd->BbpWriteLatch[Id];
448
449 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
450 return STATUS_UNSUCCESSFUL;
451 }
452
453 return STATUS_SUCCESS;
454}
455#else
456/*
457 ========================================================================
458
459 Routine Description: Read 8-bit BBP register via firmware
460
461 Arguments:
462
463 Return Value:
464
465 IRQL =
466
467 Note:
468
469 ========================================================================
470*/
471NTSTATUS RTUSBReadBBPRegister(
472 IN PRTMP_ADAPTER pAd,
473 IN UCHAR Id,
474 IN PUCHAR pValue)
475{
476 BBP_CSR_CFG_STRUC BbpCsr;
477 int i, k;
478 for (i=0; i<MAX_BUSY_COUNT; i++)
479 {
480 RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
481 if (BbpCsr.field.Busy == BUSY)
482 {
483 continue;
484 }
485 BbpCsr.word = 0;
486 BbpCsr.field.fRead = 1;
487 BbpCsr.field.BBP_RW_MODE = 1;
488 BbpCsr.field.Busy = 1;
489 BbpCsr.field.RegNum = Id;
490 RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, BbpCsr.word);
491 AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
492 for (k=0; k<MAX_BUSY_COUNT; k++)
493 {
494 RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
495 if (BbpCsr.field.Busy == IDLE)
496 break;
497 }
498 if ((BbpCsr.field.Busy == IDLE) &&
499 (BbpCsr.field.RegNum == Id))
500 {
501 *pValue = (UCHAR)BbpCsr.field.Value;
502 break;
503 }
504 }
505 if (BbpCsr.field.Busy == BUSY)
506 {
507 DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", Id, BbpCsr.word));
508 *pValue = pAd->BbpWriteLatch[Id];
509 return STATUS_UNSUCCESSFUL;
510 }
511 return STATUS_SUCCESS;
512}
513#endif
514
515#if 1
516/*
517 ========================================================================
518
519 Routine Description: Write 8-bit BBP register
520
521 Arguments:
522
523 Return Value:
524
525 IRQL =
526
527 Note:
528
529 ========================================================================
530*/
531NTSTATUS RTUSBWriteBBPRegister(
532 IN PRTMP_ADAPTER pAd,
533 IN UCHAR Id,
534 IN UCHAR Value)
535{
536 BBP_CSR_CFG_STRUC BbpCsr;
537 UINT i = 0;
538 NTSTATUS status;
539 // Verify the busy condition
540 do
541 {
542 status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
543 if (status >= 0)
544 {
545 if (!(BbpCsr.field.Busy == BUSY))
546 break;
547 }
548 printk("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i);
549 i++;
550 }
551 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
552
553 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
554 {
555 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
556 return STATUS_UNSUCCESSFUL;
557 }
558
559 // Prepare for write material
560 BbpCsr.word = 0;
561 BbpCsr.field.fRead = 0;
562 BbpCsr.field.Value = Value;
563 BbpCsr.field.Busy = 1;
564 BbpCsr.field.RegNum = Id;
565 RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
566
567 pAd->BbpWriteLatch[Id] = Value;
568
569 return STATUS_SUCCESS;
570}
571#else
572/*
573 ========================================================================
574
575 Routine Description: Write 8-bit BBP register via firmware
576
577 Arguments:
578
579 Return Value:
580
581 IRQL =
582
583 Note:
584
585 ========================================================================
586*/
587
588NTSTATUS RTUSBWriteBBPRegister(
589 IN PRTMP_ADAPTER pAd,
590 IN UCHAR Id,
591 IN UCHAR Value)
592
593{
594 BBP_CSR_CFG_STRUC BbpCsr;
595 int BusyCnt;
596 for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)
597 {
598 RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
599 if (BbpCsr.field.Busy == BUSY)
600 continue;
601 BbpCsr.word = 0;
602 BbpCsr.field.fRead = 0;
603 BbpCsr.field.BBP_RW_MODE = 1;
604 BbpCsr.field.Busy = 1;
605 BbpCsr.field.Value = Value;
606 BbpCsr.field.RegNum = Id;
607 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
608 AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
609 pAd->BbpWriteLatch[Id] = Value;
610 break;
611 }
612 if (BusyCnt == MAX_BUSY_COUNT)
613 {
614 DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", Id, BbpCsr.word));
615 return STATUS_UNSUCCESSFUL;
616 }
617 return STATUS_SUCCESS;
618}
619#endif
620/*
621 ========================================================================
622
623 Routine Description: Write RF register through MAC
624
625 Arguments:
626
627 Return Value:
628
629 IRQL =
630
631 Note:
632
633 ========================================================================
634*/
635NTSTATUS RTUSBWriteRFRegister(
636 IN PRTMP_ADAPTER pAd,
637 IN UINT32 Value)
638{
639 PHY_CSR4_STRUC PhyCsr4;
640 UINT i = 0;
641 NTSTATUS status;
642
643 NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC));
644 do
645 {
646 status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word);
647 if (status >= 0)
648 {
649 if (!(PhyCsr4.field.Busy))
650 break;
651 }
652 printk("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i);
653 i++;
654 }
655 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
656
657 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
658 {
659 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
660 return STATUS_UNSUCCESSFUL;
661 }
662
663 RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value);
664
665 return STATUS_SUCCESS;
666}
667
668/*
669 ========================================================================
670
671 Routine Description: Write RT3070 RF register through MAC
672
673 Arguments:
674
675 Return Value:
676
677 IRQL =
678
679 Note:
680
681 ========================================================================
682*/
683NTSTATUS RT30xxWriteRFRegister(
684 IN PRTMP_ADAPTER pAd,
685 IN UCHAR RegID,
686 IN UCHAR Value)
687{
688 RF_CSR_CFG_STRUC rfcsr;
689 UINT i = 0;
690
691 do
692 {
693 RTUSBReadMACRegister(pAd, RF_CSR_CFG, &rfcsr.word);
694
695 if (!rfcsr.field.RF_CSR_KICK)
696 break;
697 i++;
698 }
699 while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
700
701 if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
702 {
703 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
704 return STATUS_UNSUCCESSFUL;
705 }
706
707 rfcsr.field.RF_CSR_WR = 1;
708 rfcsr.field.RF_CSR_KICK = 1;
709 rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
710 rfcsr.field.RF_CSR_DATA = Value;
711
712 RTUSBWriteMACRegister(pAd, RF_CSR_CFG, rfcsr.word);
713
714 return STATUS_SUCCESS;
715}
716
717/*
718 ========================================================================
719
720 Routine Description: Read RT3070 RF register through MAC
721
722 Arguments:
723
724 Return Value:
725
726 IRQL =
727
728 Note:
729
730 ========================================================================
731*/
732NTSTATUS RT30xxReadRFRegister(
733 IN PRTMP_ADAPTER pAd,
734 IN UCHAR RegID,
735 IN PUCHAR pValue)
736{
737 RF_CSR_CFG_STRUC rfcsr;
738 UINT i=0, k;
739
740 for (i=0; i<MAX_BUSY_COUNT; i++)
741 {
742 RTUSBReadMACRegister(pAd, RF_CSR_CFG, &rfcsr.word);
743
744 if (rfcsr.field.RF_CSR_KICK == BUSY)
745 {
746 continue;
747 }
748 rfcsr.word = 0;
749 rfcsr.field.RF_CSR_WR = 0;
750 rfcsr.field.RF_CSR_KICK = 1;
751 rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
752 RTUSBWriteMACRegister(pAd, RF_CSR_CFG, rfcsr.word);
753 for (k=0; k<MAX_BUSY_COUNT; k++)
754 {
755 RTUSBReadMACRegister(pAd, RF_CSR_CFG, &rfcsr.word);
756
757 if (rfcsr.field.RF_CSR_KICK == IDLE)
758 break;
759 }
760 if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
761 (rfcsr.field.TESTCSR_RFACC_REGNUM == RegID))
762 {
763 *pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
764 break;
765 }
766 }
767 if (rfcsr.field.RF_CSR_KICK == BUSY)
768 {
769 DBGPRINT_ERR(("RF read R%d=0x%x fail\n", RegID, rfcsr.word));
770 return STATUS_UNSUCCESSFUL;
771 }
772
773 return STATUS_SUCCESS;
774}
775
776/*
777 ========================================================================
778
779 Routine Description:
780
781 Arguments:
782
783 Return Value:
784
785 IRQL =
786
787 Note:
788
789 ========================================================================
790*/
791NTSTATUS RTUSBReadEEPROM(
792 IN PRTMP_ADAPTER pAd,
793 IN USHORT Offset,
794 OUT PUCHAR pData,
795 IN USHORT length)
796{
797 NTSTATUS Status = STATUS_SUCCESS;
798
799 Status = RTUSB_VendorRequest(
800 pAd,
801 (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
802 DEVICE_VENDOR_REQUEST_IN,
803 0x9,
804 0,
805 Offset,
806 pData,
807 length);
808
809 return Status;
810}
811
812/*
813 ========================================================================
814
815 Routine Description:
816
817 Arguments:
818
819 Return Value:
820
821 IRQL =
822
823 Note:
824
825 ========================================================================
826*/
827NTSTATUS RTUSBWriteEEPROM(
828 IN PRTMP_ADAPTER pAd,
829 IN USHORT Offset,
830 IN PUCHAR pData,
831 IN USHORT length)
832{
833 NTSTATUS Status = STATUS_SUCCESS;
834
835 Status = RTUSB_VendorRequest(
836 pAd,
837 USBD_TRANSFER_DIRECTION_OUT,
838 DEVICE_VENDOR_REQUEST_OUT,
839 0x8,
840 0,
841 Offset,
842 pData,
843 length);
844
845 return Status;
846}
847
848/*
849 ========================================================================
850
851 Routine Description:
852
853 Arguments:
854
855 Return Value:
856
857 IRQL =
858
859 Note:
860
861 ========================================================================
862*/
863VOID RTUSBPutToSleep(
864 IN PRTMP_ADAPTER pAd)
865{
866 UINT32 value;
867
868 // Timeout 0x40 x 50us
869 value = (SLEEPCID<<16)+(OWNERMCU<<24)+ (0x40<<8)+1;
870 RTUSBWriteMACRegister(pAd, 0x7010, value);
871 RTUSBWriteMACRegister(pAd, 0x404, 0x30);
872 //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
873 DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value));
874
875}
876
877/*
878 ========================================================================
879
880 Routine Description:
881
882 Arguments:
883
884 Return Value:
885
886 IRQL =
887
888 Note:
889
890 ========================================================================
891*/
892NTSTATUS RTUSBWakeUp(
893 IN PRTMP_ADAPTER pAd)
894{
895 NTSTATUS Status;
896
897 Status = RTUSB_VendorRequest(
898 pAd,
899 USBD_TRANSFER_DIRECTION_OUT,
900 DEVICE_VENDOR_REQUEST_OUT,
901 0x01,
902 0x09,
903 0,
904 NULL,
905 0);
906
907 return Status;
908}
909
910/*
911 ========================================================================
912
913 Routine Description:
914
915 Arguments:
916
917 Return Value:
918
919 IRQL =
920
921 Note:
922
923 ========================================================================
924*/
925VOID RTUSBInitializeCmdQ(
926 IN PCmdQ cmdq)
927{
928 cmdq->head = NULL;
929 cmdq->tail = NULL;
930 cmdq->size = 0;
931 cmdq->CmdQState = RT2870_THREAD_INITED;
932}
933
934/*
935 ========================================================================
936
937 Routine Description:
938
939 Arguments:
940
941 Return Value:
942
943 IRQL =
944
945 Note:
946
947 ========================================================================
948*/
949NDIS_STATUS RTUSBEnqueueCmdFromNdis(
950 IN PRTMP_ADAPTER pAd,
951 IN NDIS_OID Oid,
952 IN BOOLEAN SetInformation,
953 IN PVOID pInformationBuffer,
954 IN UINT32 InformationBufferLength)
955{
956 NDIS_STATUS status;
957 PCmdQElmt cmdqelmt = NULL;
958 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
959
960
961 CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
962 return (NDIS_STATUS_RESOURCES);
963
964 status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
965 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
966 return (NDIS_STATUS_RESOURCES);
967
968 cmdqelmt->buffer = NULL;
969 if (pInformationBuffer != NULL)
970 {
971 status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
972 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
973 {
974 kfree(cmdqelmt);
975 return (NDIS_STATUS_RESOURCES);
976 }
977 else
978 {
979 NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
980 cmdqelmt->bufferlength = InformationBufferLength;
981 }
982 }
983 else
984 cmdqelmt->bufferlength = 0;
985
986 cmdqelmt->command = Oid;
987 cmdqelmt->CmdFromNdis = TRUE;
988 if (SetInformation == TRUE)
989 cmdqelmt->SetOperation = TRUE;
990 else
991 cmdqelmt->SetOperation = FALSE;
992
993 NdisAcquireSpinLock(&pAd->CmdQLock);
994 if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
995 {
996 EnqueueCmd((&pAd->CmdQ), cmdqelmt);
997 status = NDIS_STATUS_SUCCESS;
998 }
999 else
1000 {
1001 status = NDIS_STATUS_FAILURE;
1002 }
1003 NdisReleaseSpinLock(&pAd->CmdQLock);
1004
1005 if (status == NDIS_STATUS_FAILURE)
1006 {
1007 if (cmdqelmt->buffer)
1008 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1009 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1010 }
1011 else
1012 RTUSBCMDUp(pAd);
1013
1014
1015 return(NDIS_STATUS_SUCCESS);
1016}
1017
1018/*
1019 ========================================================================
1020
1021 Routine Description:
1022
1023 Arguments:
1024
1025 Return Value:
1026
1027 IRQL =
1028
1029 Note:
1030
1031 ========================================================================
1032*/
1033NDIS_STATUS RTUSBEnqueueInternalCmd(
1034 IN PRTMP_ADAPTER pAd,
1035 IN NDIS_OID Oid,
1036 IN PVOID pInformationBuffer,
1037 IN UINT32 InformationBufferLength)
1038{
1039 NDIS_STATUS status;
1040 PCmdQElmt cmdqelmt = NULL;
1041
1042
1043 status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
1044 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
1045 return (NDIS_STATUS_RESOURCES);
1046 NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt));
1047
1048 if(InformationBufferLength > 0)
1049 {
1050 status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
1051 if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
1052 {
1053 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1054 return (NDIS_STATUS_RESOURCES);
1055 }
1056 else
1057 {
1058 NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
1059 cmdqelmt->bufferlength = InformationBufferLength;
1060 }
1061 }
1062 else
1063 {
1064 cmdqelmt->buffer = NULL;
1065 cmdqelmt->bufferlength = 0;
1066 }
1067
1068 cmdqelmt->command = Oid;
1069 cmdqelmt->CmdFromNdis = FALSE;
1070
1071 if (cmdqelmt != NULL)
1072 {
1073 NdisAcquireSpinLock(&pAd->CmdQLock);
1074 if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
1075 {
1076 EnqueueCmd((&pAd->CmdQ), cmdqelmt);
1077 status = NDIS_STATUS_SUCCESS;
1078 }
1079 else
1080 {
1081 status = NDIS_STATUS_FAILURE;
1082 }
1083 NdisReleaseSpinLock(&pAd->CmdQLock);
1084
1085 if (status == NDIS_STATUS_FAILURE)
1086 {
1087 if (cmdqelmt->buffer)
1088 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1089 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1090 }
1091 else
1092 RTUSBCMDUp(pAd);
1093 }
1094 return(NDIS_STATUS_SUCCESS);
1095}
1096
1097/*
1098 ========================================================================
1099
1100 Routine Description:
1101
1102 Arguments:
1103
1104 Return Value:
1105
1106 IRQL =
1107
1108 Note:
1109
1110 ========================================================================
1111*/
1112VOID RTUSBDequeueCmd(
1113 IN PCmdQ cmdq,
1114 OUT PCmdQElmt *pcmdqelmt)
1115{
1116 *pcmdqelmt = cmdq->head;
1117
1118 if (*pcmdqelmt != NULL)
1119 {
1120 cmdq->head = cmdq->head->next;
1121 cmdq->size--;
1122 if (cmdq->size == 0)
1123 cmdq->tail = NULL;
1124 }
1125}
1126
1127/*
1128 ========================================================================
1129 usb_control_msg - Builds a control urb, sends it off and waits for completion
1130 @dev: pointer to the usb device to send the message to
1131 @pipe: endpoint "pipe" to send the message to
1132 @request: USB message request value
1133 @requesttype: USB message request type value
1134 @value: USB message value
1135 @index: USB message index value
1136 @data: pointer to the data to send
1137 @size: length in bytes of the data to send
1138 @timeout: time in jiffies to wait for the message to complete before
1139 timing out (if 0 the wait is forever)
1140 Context: !in_interrupt ()
1141
1142 This function sends a simple control message to a specified endpoint
1143 and waits for the message to complete, or timeout.
1144 If successful, it returns the number of bytes transferred, otherwise a negative error number.
1145
1146 Don't use this function from within an interrupt context, like a
1147 bottom half handler. If you need an asynchronous message, or need to send
1148 a message from within interrupt context, use usb_submit_urb()
1149 If a thread in your driver uses this call, make sure your disconnect()
1150 method can wait for it to complete. Since you don't have a handle on
1151 the URB used, you can't cancel the request.
1152
1153
1154 Routine Description:
1155
1156 Arguments:
1157
1158 Return Value:
1159
1160 Note:
1161
1162 ========================================================================
1163*/
1164NTSTATUS RTUSB_VendorRequest(
1165 IN PRTMP_ADAPTER pAd,
1166 IN UINT32 TransferFlags,
1167 IN UCHAR RequestType,
1168 IN UCHAR Request,
1169 IN USHORT Value,
1170 IN USHORT Index,
1171 IN PVOID TransferBuffer,
1172 IN UINT32 TransferBufferLength)
1173{
1174 int ret;
1175 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
1176
1177 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
1178 {
1179 DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));
1180 return -1;
1181 }
1182 else if (in_interrupt())
1183 {
1184 DBGPRINT(RT_DEBUG_ERROR, ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",Request,Value,Index));
1185
1186 return -1;
1187 }
1188 else
1189 {
1190#define MAX_RETRY_COUNT 10
1191
1192 int retryCount = 0;
1193 void *tmpBuf = TransferBuffer;
1194
1195 // Acquire Control token
1196#ifdef INF_AMAZON_SE
1197 //Semaphore fix INF_AMAZON_SE hang
1198 //pAd->UsbVendorReqBuf is the swap for DEVICE_VENDOR_REQUEST_IN to fix dma bug.
1199 ret = down_interruptible(&(pAd->UsbVendorReq_semaphore));
1200 if (pAd->UsbVendorReqBuf)
1201 {
1202 ASSERT(TransferBufferLength <MAX_PARAM_BUFFER_SIZE);
1203
1204 tmpBuf = (void *)pAd->UsbVendorReqBuf;
1205 NdisZeroMemory(pAd->UsbVendorReqBuf, TransferBufferLength);
1206
1207 if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
1208 NdisMoveMemory(tmpBuf, TransferBuffer, TransferBufferLength);
1209 }
1210#endif // INF_AMAZON_SE //
1211 do {
1212 if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
1213 ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1214 else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
1215 ret=usb_control_msg(pObj->pUsb_Dev, usb_rcvctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1216 else
1217 {
1218 DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n"));
1219 ret = -1;
1220 }
1221
1222 retryCount++;
1223 if (ret < 0) {
1224 printk("#\n");
1225 RTMPusecDelay(5000);
1226 }
1227 } while((ret < 0) && (retryCount < MAX_RETRY_COUNT));
1228
1229#ifdef INF_AMAZON_SE
1230 if ((pAd->UsbVendorReqBuf) && (RequestType == DEVICE_VENDOR_REQUEST_IN))
1231 NdisMoveMemory(TransferBuffer, tmpBuf, TransferBufferLength);
1232 up(&(pAd->UsbVendorReq_semaphore));
1233#endif // INF_AMAZON_SE //
1234
1235 if (ret < 0) {
1236// DBGPRINT(RT_DEBUG_ERROR, ("USBVendorRequest failed ret=%d \n",ret));
1237 DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
1238 ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index));
1239 if (Request == 0x2)
1240 DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value));
1241
1242 if ((TransferBuffer!= NULL) && (TransferBufferLength > 0))
1243 hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength);
1244 }
1245
1246#if 0
1247 // retry
1248 if (ret < 0) {
1249 int temp_i=0;
1250 DBGPRINT(RT_DEBUG_ERROR, ("USBVendorRequest failed ret=%d, \n",ret));
1251 ret = 0;
1252 do
1253 {
1254 if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
1255 ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, TransferBuffer, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1256 else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
1257 ret=usb_control_msg(pObj->pUsb_Dev, usb_rcvctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, TransferBuffer, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
1258 temp_i++;
1259 } while( (ret < 0) && (temp_i <= 1) );
1260
1261 if( ret >= 0)
1262 return ret;
1263
1264 }
1265#endif
1266
1267 }
1268 return ret;
1269}
1270
1271/*
1272 ========================================================================
1273
1274 Routine Description:
1275 Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT
1276 synchronously. Callers of this function must be running at
1277 PASSIVE LEVEL.
1278
1279 Arguments:
1280
1281 Return Value:
1282
1283 Note:
1284
1285 ========================================================================
1286*/
1287NTSTATUS RTUSB_ResetDevice(
1288 IN PRTMP_ADAPTER pAd)
1289{
1290 NTSTATUS Status = TRUE;
1291
1292 DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n"));
1293 //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
1294 return Status;
1295}
1296
1297VOID CMDHandler(
1298 IN PRTMP_ADAPTER pAd)
1299{
1300 PCmdQElmt cmdqelmt;
1301 PUCHAR pData;
1302 NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
1303// ULONG Now = 0;
1304 NTSTATUS ntStatus;
1305// unsigned long IrqFlags;
1306
1307 while (pAd->CmdQ.size > 0)
1308 {
1309 NdisStatus = NDIS_STATUS_SUCCESS;
1310
1311 NdisAcquireSpinLock(&pAd->CmdQLock);
1312 RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);
1313 NdisReleaseSpinLock(&pAd->CmdQLock);
1314
1315 if (cmdqelmt == NULL)
1316 break;
1317
1318 pData = cmdqelmt->buffer;
1319
1320 if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
1321 {
1322 switch (cmdqelmt->command)
1323 {
1324 case CMDTHREAD_CHECK_GPIO:
1325 {
1326#ifdef CONFIG_STA_SUPPORT
1327 UINT32 data;
1328#endif // CONFIG_STA_SUPPORT //
1329#ifdef RALINK_ATE
1330 if(ATE_ON(pAd))
1331 {
1332 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
1333 break;
1334 }
1335#endif // RALINK_ATE //
1336
1337#ifdef CONFIG_STA_SUPPORT
1338
1339
1340 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1341 {
1342 // Read GPIO pin2 as Hardware controlled radio state
1343
1344 RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);
1345
1346 if (data & 0x04)
1347 {
1348 pAd->StaCfg.bHwRadio = TRUE;
1349 }
1350 else
1351 {
1352 pAd->StaCfg.bHwRadio = FALSE;
1353 }
1354
1355 if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
1356 {
1357 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
1358 if(pAd->StaCfg.bRadio == TRUE)
1359 {
1360 DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));
1361
1362 MlmeRadioOn(pAd);
1363 // Update extra information
1364 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
1365 }
1366 else
1367 {
1368 DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));
1369
1370 MlmeRadioOff(pAd);
1371 // Update extra information
1372 pAd->ExtraInfo = HW_RADIO_OFF;
1373 }
1374 }
1375 }
1376#endif // CONFIG_STA_SUPPORT //
1377 }
1378 break;
1379
1380#ifdef CONFIG_STA_SUPPORT
1381 case CMDTHREAD_QKERIODIC_EXECUT:
1382 {
1383 StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
1384 }
1385 break;
1386#endif // CONFIG_STA_SUPPORT //
1387
1388 case CMDTHREAD_RESET_BULK_OUT:
1389 {
1390 UINT32 MACValue;
1391 UCHAR Index;
1392 int ret=0;
1393 PHT_TX_CONTEXT pHTTXContext;
1394// RTMP_TX_RING *pTxRing;
1395 unsigned long IrqFlags;
1396#ifdef RALINK_ATE
1397 PTX_CONTEXT pNullContext = &(pAd->NullContext);
1398#endif // RALINK_ATE //
1399 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid));
1400 // All transfers must be aborted or cancelled before attempting to reset the pipe.
1401 //RTUSBCancelPendingBulkOutIRP(pAd);
1402 // Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
1403 Index = 0;
1404 do
1405 {
1406 RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
1407 if ((MACValue & 0xf00000/*0x800000*/) == 0)
1408 break;
1409 Index++;
1410 RTMPusecDelay(10000);
1411 }while(Index < 100);
1412 MACValue = 0;
1413 RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1414 // To prevent Read Register error, we 2nd check the validity.
1415 if ((MACValue & 0xc00000) == 0)
1416 RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1417 // To prevent Read Register error, we 3rd check the validity.
1418 if ((MACValue & 0xc00000) == 0)
1419 RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
1420 MACValue |= 0x80000;
1421 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
1422
1423 // Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
1424 RTMPusecDelay(1000);
1425
1426 MACValue &= (~0x80000);
1427 RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
1428 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
1429
1430 // Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
1431 //RTMPusecDelay(5000);
1432
1433 if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
1434 {
1435 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1436 if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
1437 {
1438 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
1439 }
1440 RTUSBKickBulkOut(pAd);
1441
1442 DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
1443 }
1444 else
1445 {
1446 pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
1447 //NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1448 RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1449 if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
1450 {
1451 pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
1452 pHTTXContext->IRPPending = TRUE;
1453 pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;
1454
1455 // no matter what, clean the flag
1456 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1457
1458 //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1459 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1460/*-----------------------------------------------------------------------------------------------*/
1461#ifdef RALINK_ATE
1462 if(ATE_ON(pAd))
1463 {
1464 pNullContext->IRPPending = TRUE;
1465 //
1466 // If driver is still in ATE TXFRAME mode,
1467 // keep on transmitting ATE frames.
1468 //
1469 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)));
1470 if((pAd->ate.Mode == ATE_TXFRAME) && ((pAd->ContinBulkOut == TRUE) || (atomic_read(&pAd->BulkOutRemained) > 0)))
1471 {
1472 DBGPRINT_RAW(RT_DEBUG_TRACE, ("After CMDTHREAD_RESET_BULK_OUT, continue to bulk out frames !\n"));
1473
1474 // Init Tx context descriptor
1475 RTUSBInitTxDesc(pAd, pNullContext, 0/* pAd->bulkResetPipeid */, (usb_complete_t)ATE_RTUSBBulkOutDataPacketComplete);
1476
1477 if((ret = RTUSB_SUBMIT_URB(pNullContext->pUrb))!=0)
1478 {
1479 DBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
1480 }
1481
1482 pAd->BulkOutReq++;
1483 }
1484 }
1485 else
1486#endif // RALINK_ATE //
1487/*-----------------------------------------------------------------------------------------------*/
1488 {
1489 RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
1490
1491 if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
1492 {
1493 RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1494 pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
1495 pHTTXContext->IRPPending = FALSE;
1496 pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
1497 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1498
1499 DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", ret));
1500 }
1501 else
1502 {
1503 RTMP_IRQ_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1504 DBGPRINT_RAW(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
1505 pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition,
1506 pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid]));
1507 DBGPRINT_RAW(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
1508 pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
1509 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1510 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));
1511
1512 }
1513 }
1514 }
1515 else
1516 {
1517 //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
1518 //RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1519
1520 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));
1521 if (pAd->bulkResetPipeid == 0)
1522 {
1523 UCHAR pendingContext = 0;
1524 PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
1525 PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
1526 PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
1527 PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);
1528
1529 if (pHTTXContext->IRPPending)
1530 pendingContext |= 1;
1531 else if (pMLMEContext->IRPPending)
1532 pendingContext |= 2;
1533 else if (pNULLContext->IRPPending)
1534 pendingContext |= 4;
1535 else if (pPsPollContext->IRPPending)
1536 pendingContext |= 8;
1537 else
1538 pendingContext = 0;
1539
1540 DBGPRINT_RAW(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
1541 }
1542
1543 // no matter what, clean the flag
1544 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
1545
1546 RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
1547
1548 RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
1549 }
1550
1551 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1552 //RTUSBKickBulkOut(pAd);
1553 }
1554
1555 }
1556 /*
1557 // Don't cancel BULKIN.
1558 while ((atomic_read(&pAd->PendingRx) > 0) &&
1559 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1560 {
1561 if (atomic_read(&pAd->PendingRx) > 0)
1562 {
1563 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
1564 RTUSBCancelPendingBulkInIRP(pAd);
1565 }
1566 RTMPusecDelay(100000);
1567 }
1568
1569 if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
1570 {
1571 UCHAR i;
1572 RTUSBRxPacket(pAd);
1573 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1574 pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer
1575 for (i = 0; i < (RX_RING_SIZE); i++)
1576 {
1577 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
1578
1579 pRxContext->pAd = pAd;
1580 pRxContext->InUse = FALSE;
1581 pRxContext->IRPPending = FALSE;
1582 pRxContext->Readable = FALSE;
1583 pRxContext->ReorderInUse = FALSE;
1584
1585 }
1586 RTUSBBulkReceive(pAd);
1587 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
1588 }*/
1589 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
1590 break;
1591
1592 case CMDTHREAD_RESET_BULK_IN:
1593 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));
1594
1595 // All transfers must be aborted or cancelled before attempting to reset the pipe.
1596 {
1597 UINT32 MACValue;
1598/*-----------------------------------------------------------------------------------------------*/
1599#ifdef RALINK_ATE
1600 if (ATE_ON(pAd))
1601 {
1602 if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1603 {
1604 DBGPRINT_RAW(RT_DEBUG_ERROR, ("ATE : BulkIn IRP Pending!!!\n"));
1605 ATE_RTUSBCancelPendingBulkInIRP(pAd);
1606 RTMPusecDelay(100000);
1607 pAd->PendingRx = 0;
1608 }
1609 }
1610 else
1611#endif // RALINK_ATE //
1612/*-----------------------------------------------------------------------------------------------*/
1613 {
1614 //while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1615 if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
1616 {
1617 DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
1618 RTUSBCancelPendingBulkInIRP(pAd);
1619 RTMPusecDelay(100000);
1620 pAd->PendingRx = 0;
1621 }
1622 }
1623
1624 // Wait 10ms before reading register.
1625 RTMPusecDelay(10000);
1626 ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);
1627
1628 if ((NT_SUCCESS(ntStatus) == TRUE) &&
1629 (!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
1630 fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
1631 {
1632 UCHAR i;
1633
1634 if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
1635 fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
1636 break;
1637 pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
1638 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",
1639 pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
1640 for (i = 0; i < RX_RING_SIZE; i++)
1641 {
1642 DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
1643 , i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
1644 }
1645 /*
1646
1647 DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));
1648
1649 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1650 pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer
1651 for (i = 0; i < (RX_RING_SIZE); i++)
1652 {
1653 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
1654
1655 pRxContext->pAd = pAd;
1656 pRxContext->InUse = FALSE;
1657 pRxContext->IRPPending = FALSE;
1658 pRxContext->Readable = FALSE;
1659 pRxContext->ReorderInUse = FALSE;
1660
1661 }*/
1662 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
1663 for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
1664 {
1665 //RTUSBBulkReceive(pAd);
1666 PRX_CONTEXT pRxContext;
1667 PURB pUrb;
1668 int ret = 0;
1669 unsigned long IrqFlags;
1670
1671
1672 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1673 pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
1674 if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
1675 {
1676 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1677 break;
1678 }
1679 pRxContext->InUse = TRUE;
1680 pRxContext->IRPPending = TRUE;
1681 pAd->PendingRx++;
1682 pAd->BulkInReq++;
1683 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1684
1685 // Init Rx context descriptor
1686 RTUSBInitRxDesc(pAd, pRxContext);
1687 pUrb = pRxContext->pUrb;
1688 if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
1689 { // fail
1690
1691 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1692 pRxContext->InUse = FALSE;
1693 pRxContext->IRPPending = FALSE;
1694 pAd->PendingRx--;
1695 pAd->BulkInReq--;
1696 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1697 DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->status));
1698 }
1699 else
1700 { // success
1701#if 0
1702 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
1703 pRxContext->IRPPending = TRUE;
1704 //NdisInterlockedIncrement(&pAd->PendingRx);
1705 pAd->PendingRx++;
1706 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
1707 pAd->BulkInReq++;
1708#endif
1709 //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
1710 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status));
1711 ASSERT((pRxContext->InUse == pRxContext->IRPPending));
1712 }
1713 }
1714
1715 }
1716 else
1717 {
1718 // Card must be removed
1719 if (NT_SUCCESS(ntStatus) != TRUE)
1720 {
1721 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
1722 DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
1723 }
1724 else
1725 {
1726 DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
1727 }
1728 }
1729 }
1730 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
1731 break;
1732
1733 case CMDTHREAD_SET_ASIC_WCID:
1734 {
1735 RT_SET_ASIC_WCID SetAsicWcid;
1736 USHORT offset;
1737 UINT32 MACValue, MACRValue = 0;
1738 SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));
1739
1740 if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
1741 return;
1742
1743 offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;
1744
1745 DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
1746 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]);
1747 DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
1748 RTUSBWriteMACRegister(pAd, offset, MACValue);
1749 // Read bitmask
1750 RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
1751 if ( SetAsicWcid.DeleteTid != 0xffffffff)
1752 MACRValue &= (~SetAsicWcid.DeleteTid);
1753 if (SetAsicWcid.SetTid != 0xffffffff)
1754 MACRValue |= (SetAsicWcid.SetTid);
1755 MACRValue &= 0xffff0000;
1756
1757 MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
1758 MACValue |= MACRValue;
1759 RTUSBWriteMACRegister(pAd, offset+4, MACValue);
1760
1761 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
1762 }
1763 break;
1764
1765 case CMDTHREAD_SET_ASIC_WCID_CIPHER:
1766 {
1767#ifdef CONFIG_STA_SUPPORT
1768 RT_SET_ASIC_WCID_ATTRI SetAsicWcidAttri;
1769 USHORT offset;
1770 UINT32 MACRValue = 0;
1771 SHAREDKEY_MODE_STRUC csr1;
1772 SetAsicWcidAttri = *((PRT_SET_ASIC_WCID_ATTRI)(pData));
1773
1774 if (SetAsicWcidAttri.WCID >= MAX_LEN_OF_MAC_TABLE)
1775 return;
1776
1777 offset = MAC_WCID_ATTRIBUTE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_WCID_ATTRI_SIZE;
1778
1779 DBGPRINT_RAW(RT_DEBUG_TRACE, ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", SetAsicWcidAttri.WCID, SetAsicWcidAttri.Cipher));
1780 // Read bitmask
1781 RTUSBReadMACRegister(pAd, offset, &MACRValue);
1782 MACRValue = 0;
1783 MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
1784
1785 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1786 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
1787
1788 offset = PAIRWISE_IVEIV_TABLE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_IVEIV_ENTRY_SIZE;
1789 MACRValue = 0;
1790 if ( (SetAsicWcidAttri.Cipher <= CIPHER_WEP128))
1791 MACRValue |= ( pAd->StaCfg.DefaultKeyId << 30);
1792 else
1793 MACRValue |= (0x20000000);
1794 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1795 DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
1796
1797 //
1798 // Update cipher algorithm. WSTA always use BSS0
1799 //
1800 // for adhoc mode only ,because wep status slow than add key, when use zero config
1801 if (pAd->StaCfg.BssType == BSS_ADHOC )
1802 {
1803 offset = MAC_WCID_ATTRIBUTE_BASE;
1804
1805 RTUSBReadMACRegister(pAd, offset, &MACRValue);
1806 MACRValue &= (~0xe);
1807 MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
1808
1809 RTUSBWriteMACRegister(pAd, offset, MACRValue);
1810
1811 //Update group key cipher,,because wep status slow than add key, when use zero config
1812 RTUSBReadMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), &csr1.word);
1813
1814 csr1.field.Bss0Key0CipherAlg = SetAsicWcidAttri.Cipher;
1815 csr1.field.Bss0Key1CipherAlg = SetAsicWcidAttri.Cipher;
1816
1817 RTUSBWriteMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), csr1.word);
1818 }
1819#endif // CONFIG_STA_SUPPORT //
1820 }
1821 break;
1822
1823#ifdef CONFIG_STA_SUPPORT
1824#ifdef QOS_DLS_SUPPORT
1825 // avoid in interrupt when write key
1826 case RT_CMD_SET_KEY_TABLE: //General call for AsicAddPairwiseKeyEntry()
1827 {
1828 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1829 KeyInfo = *((PRT_ADD_PAIRWISE_KEY_ENTRY)(pData));
1830 AsicAddPairwiseKeyEntry(pAd,
1831 KeyInfo.MacAddr,
1832 (UCHAR)KeyInfo.MacTabMatchWCID,
1833 &KeyInfo.CipherKey);
1834 }
1835 break;
1836
1837 case RT_CMD_SET_RX_WCID_TABLE: //General call for RTMPAddWcidAttributeEntry()
1838 {
1839 PMAC_TABLE_ENTRY pEntry ;
1840 pEntry = (PMAC_TABLE_ENTRY)(pData);
1841 RTMPAddWcidAttributeEntry(pAd,
1842 BSS0,
1843 0,
1844 pEntry->PairwiseKey.CipherAlg,
1845 pEntry);
1846 }
1847 break;
1848#endif // QOS_DLS_SUPPORT //
1849#endif // CONFIG_STA_SUPPORT //
1850
1851 case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
1852 {
1853 MAC_TABLE_ENTRY *pEntry;
1854 pEntry = (MAC_TABLE_ENTRY *)pData;
1855
1856
1857#ifdef CONFIG_STA_SUPPORT
1858 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1859 {
1860 AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid);
1861 if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled))
1862 {
1863 UINT32 uIV = 0;
1864 PUCHAR ptr;
1865
1866 ptr = (PUCHAR) &uIV;
1867 *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
1868 AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
1869 AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
1870 }
1871 else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)
1872 {
1873 UINT32 uIV = 0;
1874 PUCHAR ptr;
1875
1876 ptr = (PUCHAR) &uIV;
1877 *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
1878 AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
1879 AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
1880 }
1881 else
1882 {
1883 //
1884 // Other case, disable engine.
1885 // Don't worry WPA key, we will add WPA Key after 4-Way handshaking.
1886 //
1887 USHORT offset;
1888 offset = MAC_WCID_ATTRIBUTE_BASE + (pEntry->Aid * HW_WCID_ATTRI_SIZE);
1889 // RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0
1890 RTUSBWriteMACRegister(pAd, offset, 0);
1891 }
1892 }
1893#endif // CONFIG_STA_SUPPORT //
1894
1895 AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
1896 printk("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid,
1897 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
1898 }
1899 break;
1900
1901 case OID_802_11_ADD_WEP:
1902 {
1903#ifdef CONFIG_STA_SUPPORT
1904 UINT i;
1905 UINT32 KeyIdx;
1906 PNDIS_802_11_WEP pWepKey;
1907
1908 DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP \n"));
1909
1910 pWepKey = (PNDIS_802_11_WEP)pData;
1911 KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
1912
1913 // it is a shared key
1914 if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13)))
1915 {
1916 NdisStatus = NDIS_STATUS_INVALID_DATA;
1917 DBGPRINT(RT_DEBUG_ERROR, ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
1918 }
1919 else
1920 {
1921 UCHAR CipherAlg;
1922 pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
1923 NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
1924 CipherAlg = (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128;
1925
1926 //
1927 // Change the WEP cipher to CKIP cipher if CKIP KP on.
1928 // Funk UI or Meetinghouse UI will add ckip key from this path.
1929 //
1930
1931 if (pAd->OpMode == OPMODE_STA)
1932 {
1933 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1934 pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen;
1935 }
1936 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
1937 if (pWepKey->KeyIndex & 0x80000000)
1938 {
1939 // Default key for tx (shared key)
1940 UCHAR IVEIV[8];
1941 UINT32 WCIDAttri, Value;
1942 USHORT offset, offset2;
1943 NdisZeroMemory(IVEIV, 8);
1944 pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
1945 // Add BSSID to WCTable. because this is Tx wep key.
1946 // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
1947 WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
1948
1949 offset = MAC_WCID_ATTRIBUTE_BASE + (BSSID_WCID* HW_WCID_ATTRI_SIZE);
1950 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
1951 // 1. IV/EIV
1952 // Specify key index to find shared key.
1953 IVEIV[3] = (UCHAR)(KeyIdx<< 6); //WEP Eiv bit off. groupkey index is not 0
1954 offset = PAIRWISE_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE);
1955 offset2 = PAIRWISE_IVEIV_TABLE_BASE + (BSSID_WCID* HW_IVEIV_ENTRY_SIZE);
1956 for (i=0; i<8;)
1957 {
1958 Value = IVEIV[i];
1959 Value += (IVEIV[i+1]<<8);
1960 Value += (IVEIV[i+2]<<16);
1961 Value += (IVEIV[i+3]<<24);
1962 RTUSBWriteMACRegister(pAd, offset+i, Value);
1963 RTUSBWriteMACRegister(pAd, offset2+i, Value);
1964 i+=4;
1965 }
1966
1967 // 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0
1968 WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|SHAREDKEYTABLE;
1969 offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE);
1970 DBGPRINT(RT_DEBUG_TRACE, ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", offset, WCIDAttri));
1971 RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
1972
1973 }
1974 AsicAddSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL);
1975 DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength));
1976 }
1977#endif // CONFIG_STA_SUPPORT //
1978 }
1979 break;
1980
1981 case CMDTHREAD_802_11_COUNTER_MEASURE:
1982 break;
1983 default:
1984 DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
1985 break;
1986 }
1987 }
1988
1989 if (cmdqelmt->CmdFromNdis == TRUE)
1990 {
1991 if (cmdqelmt->buffer != NULL)
1992 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
1993
1994 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
1995 }
1996 else
1997 {
1998 if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
1999 NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
2000 {
2001 NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
2002 }
2003 }
2004 } /* end of while */
2005}
2006
diff --git a/drivers/staging/rt2870/common/spectrum.c b/drivers/staging/rt2870/common/spectrum.c
new file mode 100644
index 00000000000..abba8405184
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/dfs.h b/drivers/staging/rt2870/dfs.h
new file mode 100644
index 00000000000..752a6352d9d
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/leap.h b/drivers/staging/rt2870/leap.h
new file mode 100644
index 00000000000..6818c1ff4d7
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/link_list.h b/drivers/staging/rt2870/link_list.h
new file mode 100644
index 00000000000..f6521133fd5
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/md4.h b/drivers/staging/rt2870/md4.h
new file mode 100644
index 00000000000..f1e5b526350
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/md5.h b/drivers/staging/rt2870/md5.h
new file mode 100644
index 00000000000..d85db12170d
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/mlme.h b/drivers/staging/rt2870/mlme.h
new file mode 100644
index 00000000000..52fb8e1c290
--- /dev/null
+++ b/drivers/staging/rt2870/mlme.h
@@ -0,0 +1,1471 @@
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#if 0 // move to
511 BOOLEAN bHtEnable; // If we should use ht rate.
512 BOOLEAN bPreNHt; // If we should use ht rate.
513 //Substract from HT Capability IE
514 UCHAR MCSSet[16]; //only supoort MCS=0-15,32 ,
515#endif
516#ifdef RT_BIG_ENDIAN
517 USHORT rsv:5;
518 USHORT AmsduSize:1; // Max receiving A-MSDU size
519 USHORT AmsduEnable:1; // Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
520 USHORT RxSTBC:2; // 2 bits
521 USHORT TxSTBC:1;
522 USHORT ShortGIfor40:1; //for40MHz
523 USHORT ShortGIfor20:1;
524 USHORT GF:1; //green field
525 USHORT MimoPs:2;//mimo power safe MMPS_
526 USHORT ChannelWidth:1;
527#else
528 USHORT ChannelWidth:1;
529 USHORT MimoPs:2;//mimo power safe MMPS_
530 USHORT GF:1; //green field
531 USHORT ShortGIfor20:1;
532 USHORT ShortGIfor40:1; //for40MHz
533 USHORT TxSTBC:1;
534 USHORT RxSTBC:2; // 2 bits
535 USHORT AmsduEnable:1; // Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
536 USHORT AmsduSize:1; // Max receiving A-MSDU size
537 USHORT rsv:5;
538#endif
539
540 //Substract from Addiont HT INFO IE
541#ifdef RT_BIG_ENDIAN
542 UCHAR RecomWidth:1;
543 UCHAR ExtChanOffset:2; // Please not the difference with following UCHAR NewExtChannelOffset; from 802.11n
544 UCHAR MpduDensity:3;
545 UCHAR MaxRAmpduFactor:2;
546#else
547 UCHAR MaxRAmpduFactor:2;
548 UCHAR MpduDensity:3;
549 UCHAR ExtChanOffset:2; // Please not the difference with following UCHAR NewExtChannelOffset; from 802.11n
550 UCHAR RecomWidth:1;
551#endif
552
553#ifdef RT_BIG_ENDIAN
554 USHORT rsv2:11;
555 USHORT OBSS_NonHTExist:1;
556 USHORT rsv3:1;
557 USHORT NonGfPresent:1;
558 USHORT OperaionMode:2;
559#else
560 USHORT OperaionMode:2;
561 USHORT NonGfPresent:1;
562 USHORT rsv3:1;
563 USHORT OBSS_NonHTExist:1;
564 USHORT rsv2:11;
565#endif
566
567 // New Extension Channel Offset IE
568 UCHAR NewExtChannelOffset;
569 // Extension Capability IE = 127
570 UCHAR BSSCoexist2040;
571} RT_HT_CAPABILITY, *PRT_HT_CAPABILITY;
572
573// field in Addtional HT Information IE .
574typedef struct PACKED {
575#ifdef RT_BIG_ENDIAN
576 UCHAR SerInterGranu:3;
577 UCHAR S_PSMPSup:1;
578 UCHAR RifsMode:1;
579 UCHAR RecomWidth:1;
580 UCHAR ExtChanOffset:2;
581#else
582 UCHAR ExtChanOffset:2;
583 UCHAR RecomWidth:1;
584 UCHAR RifsMode:1;
585 UCHAR S_PSMPSup:1; //Indicate support for scheduled PSMP
586 UCHAR SerInterGranu:3; //service interval granularity
587#endif
588} ADD_HTINFO, *PADD_HTINFO;
589
590typedef struct PACKED{
591#ifdef RT_BIG_ENDIAN
592 USHORT rsv2:11;
593 USHORT OBSS_NonHTExist:1;
594 USHORT rsv:1;
595 USHORT NonGfPresent:1;
596 USHORT OperaionMode:2;
597#else
598 USHORT OperaionMode:2;
599 USHORT NonGfPresent:1;
600 USHORT rsv:1;
601 USHORT OBSS_NonHTExist:1;
602 USHORT rsv2:11;
603#endif
604} ADD_HTINFO2, *PADD_HTINFO2;
605
606
607// TODO: Need sync with spec about the definition of StbcMcs. In Draft 3.03, it's reserved.
608typedef struct PACKED{
609#ifdef RT_BIG_ENDIAN
610 USHORT rsv:4;
611 USHORT PcoPhase:1;
612 USHORT PcoActive:1;
613 USHORT LsigTxopProt:1;
614 USHORT STBCBeacon:1;
615 USHORT DualCTSProtect:1;
616 USHORT DualBeacon:1;
617 USHORT StbcMcs:6;
618#else
619 USHORT StbcMcs:6;
620 USHORT DualBeacon:1;
621 USHORT DualCTSProtect:1;
622 USHORT STBCBeacon:1;
623 USHORT LsigTxopProt:1; // L-SIG TXOP protection full support
624 USHORT PcoActive:1;
625 USHORT PcoPhase:1;
626 USHORT rsv:4;
627#endif // RT_BIG_ENDIAN //
628} ADD_HTINFO3, *PADD_HTINFO3;
629
630#define SIZE_ADD_HT_INFO_IE 22
631typedef struct PACKED{
632 UCHAR ControlChan;
633 ADD_HTINFO AddHtInfo;
634 ADD_HTINFO2 AddHtInfo2;
635 ADD_HTINFO3 AddHtInfo3;
636 UCHAR MCSSet[16]; // Basic MCS set
637} ADD_HT_INFO_IE, *PADD_HT_INFO_IE;
638
639typedef struct PACKED{
640 UCHAR NewExtChanOffset;
641} NEW_EXT_CHAN_IE, *PNEW_EXT_CHAN_IE;
642
643
644// 4-byte HTC field. maybe included in any frame except non-QOS data frame. The Order bit must set 1.
645typedef struct PACKED {
646#ifdef RT_BIG_ENDIAN
647 UINT32 RDG:1; //RDG / More PPDU
648 UINT32 ACConstraint:1; //feedback request
649 UINT32 rsv:5; //calibration sequence
650 UINT32 ZLFAnnouce:1; // ZLF announcement
651 UINT32 CSISTEERING:2; //CSI/ STEERING
652 UINT32 FBKReq:2; //feedback request
653 UINT32 CalSeq:2; //calibration sequence
654 UINT32 CalPos:2; // calibration position
655 UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
656 UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB.
657 UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
658 UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback
659 UINT32 TRQ:1; //sounding request
660 UINT32 MA:1; //management action payload exist in (QoS Null+HTC)
661#else
662 UINT32 MA:1; //management action payload exist in (QoS Null+HTC)
663 UINT32 TRQ:1; //sounding request
664 UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback
665 UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
666 UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB.
667 UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
668 UINT32 CalPos:2; // calibration position
669 UINT32 CalSeq:2; //calibration sequence
670 UINT32 FBKReq:2; //feedback request
671 UINT32 CSISTEERING:2; //CSI/ STEERING
672 UINT32 ZLFAnnouce:1; // ZLF announcement
673 UINT32 rsv:5; //calibration sequence
674 UINT32 ACConstraint:1; //feedback request
675 UINT32 RDG:1; //RDG / More PPDU
676#endif /* !RT_BIG_ENDIAN */
677} HT_CONTROL, *PHT_CONTROL;
678
679// 2-byte QOS CONTROL field
680typedef struct PACKED {
681#ifdef RT_BIG_ENDIAN
682 USHORT Txop_QueueSize:8;
683 USHORT AMsduPresent:1;
684 USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA
685 USHORT EOSP:1;
686 USHORT TID:4;
687#else
688 USHORT TID:4;
689 USHORT EOSP:1;
690 USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA
691 USHORT AMsduPresent:1;
692 USHORT Txop_QueueSize:8;
693#endif /* !RT_BIG_ENDIAN */
694} QOS_CONTROL, *PQOS_CONTROL;
695
696// 2-byte Frame control field
697typedef struct PACKED {
698#ifdef RT_BIG_ENDIAN
699 USHORT Order:1; // Strict order expected
700 USHORT Wep:1; // Wep data
701 USHORT MoreData:1; // More data bit
702 USHORT PwrMgmt:1; // Power management bit
703 USHORT Retry:1; // Retry status bit
704 USHORT MoreFrag:1; // More fragment bit
705 USHORT FrDs:1; // From DS indication
706 USHORT ToDs:1; // To DS indication
707 USHORT SubType:4; // MSDU subtype
708 USHORT Type:2; // MSDU type
709 USHORT Ver:2; // Protocol version
710#else
711 USHORT Ver:2; // Protocol version
712 USHORT Type:2; // MSDU type
713 USHORT SubType:4; // MSDU subtype
714 USHORT ToDs:1; // To DS indication
715 USHORT FrDs:1; // From DS indication
716 USHORT MoreFrag:1; // More fragment bit
717 USHORT Retry:1; // Retry status bit
718 USHORT PwrMgmt:1; // Power management bit
719 USHORT MoreData:1; // More data bit
720 USHORT Wep:1; // Wep data
721 USHORT Order:1; // Strict order expected
722#endif /* !RT_BIG_ENDIAN */
723} FRAME_CONTROL, *PFRAME_CONTROL;
724
725typedef struct PACKED _HEADER_802_11 {
726 FRAME_CONTROL FC;
727 USHORT Duration;
728 UCHAR Addr1[MAC_ADDR_LEN];
729 UCHAR Addr2[MAC_ADDR_LEN];
730 UCHAR Addr3[MAC_ADDR_LEN];
731#ifdef RT_BIG_ENDIAN
732 USHORT Sequence:12;
733 USHORT Frag:4;
734#else
735 USHORT Frag:4;
736 USHORT Sequence:12;
737#endif /* !RT_BIG_ENDIAN */
738 UCHAR Octet[0];
739} HEADER_802_11, *PHEADER_802_11;
740
741typedef struct PACKED _FRAME_802_11 {
742 HEADER_802_11 Hdr;
743 UCHAR Octet[1];
744} FRAME_802_11, *PFRAME_802_11;
745
746// QoSNull embedding of management action. When HT Control MA field set to 1.
747typedef struct PACKED _MA_BODY {
748 UCHAR Category;
749 UCHAR Action;
750 UCHAR Octet[1];
751} MA_BODY, *PMA_BODY;
752
753typedef struct PACKED _HEADER_802_3 {
754 UCHAR DAAddr1[MAC_ADDR_LEN];
755 UCHAR SAAddr2[MAC_ADDR_LEN];
756 UCHAR Octet[2];
757} HEADER_802_3, *PHEADER_802_3;
758////Block ACK related format
759// 2-byte BA Parameter field in DELBA frames to terminate an already set up bA
760typedef struct PACKED{
761#ifdef RT_BIG_ENDIAN
762 USHORT TID:4; // value of TC os TS
763 USHORT Initiator:1; // 1: originator 0:recipient
764 USHORT Rsv:11; // always set to 0
765#else
766 USHORT Rsv:11; // always set to 0
767 USHORT Initiator:1; // 1: originator 0:recipient
768 USHORT TID:4; // value of TC os TS
769#endif /* !RT_BIG_ENDIAN */
770} DELBA_PARM, *PDELBA_PARM;
771
772// 2-byte BA Parameter Set field in ADDBA frames to signal parm for setting up a BA
773typedef struct PACKED {
774#ifdef RT_BIG_ENDIAN
775 USHORT BufSize:10; // number of buffe of size 2304 octetsr
776 USHORT TID:4; // value of TC os TS
777 USHORT BAPolicy:1; // 1: immediately BA 0:delayed BA
778 USHORT AMSDUSupported:1; // 0: not permitted 1: permitted
779#else
780 USHORT AMSDUSupported:1; // 0: not permitted 1: permitted
781 USHORT BAPolicy:1; // 1: immediately BA 0:delayed BA
782 USHORT TID:4; // value of TC os TS
783 USHORT BufSize:10; // number of buffe of size 2304 octetsr
784#endif /* !RT_BIG_ENDIAN */
785} BA_PARM, *PBA_PARM;
786
787// 2-byte BA Starting Seq CONTROL field
788typedef union PACKED {
789 struct PACKED {
790#ifdef RT_BIG_ENDIAN
791 USHORT StartSeq:12; // sequence number of the 1st MSDU for which this BAR is sent
792 USHORT FragNum:4; // always set to 0
793#else
794 USHORT FragNum:4; // always set to 0
795 USHORT StartSeq:12; // sequence number of the 1st MSDU for which this BAR is sent
796#endif /* RT_BIG_ENDIAN */
797 } field;
798 USHORT word;
799} BASEQ_CONTROL, *PBASEQ_CONTROL;
800
801//BAControl and BARControl are the same
802// 2-byte BA CONTROL field in BA frame
803typedef struct PACKED {
804#ifdef RT_BIG_ENDIAN
805 USHORT TID:4;
806 USHORT Rsv:9;
807 USHORT Compressed:1;
808 USHORT MTID:1; //EWC V1.24
809 USHORT ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK
810#else
811 USHORT ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK
812 USHORT MTID:1; //EWC V1.24
813 USHORT Compressed:1;
814 USHORT Rsv:9;
815 USHORT TID:4;
816#endif /* !RT_BIG_ENDIAN */
817} BA_CONTROL, *PBA_CONTROL;
818
819// 2-byte BAR CONTROL field in BAR frame
820typedef struct PACKED {
821#ifdef RT_BIG_ENDIAN
822 USHORT TID:4;
823 USHORT Rsv1:9;
824 USHORT Compressed:1;
825 USHORT MTID:1; //if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ
826 USHORT ACKPolicy:1;
827#else
828 USHORT ACKPolicy:1; // 0:normal ack, 1:no ack.
829 USHORT MTID:1; //if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ
830 USHORT Compressed:1;
831 USHORT Rsv1:9;
832 USHORT TID:4;
833#endif /* !RT_BIG_ENDIAN */
834} BAR_CONTROL, *PBAR_CONTROL;
835
836// BARControl in MTBAR frame
837typedef struct PACKED {
838#ifdef RT_BIG_ENDIAN
839 USHORT NumTID:4;
840 USHORT Rsv1:9;
841 USHORT Compressed:1;
842 USHORT MTID:1;
843 USHORT ACKPolicy:1;
844#else
845 USHORT ACKPolicy:1;
846 USHORT MTID:1;
847 USHORT Compressed:1;
848 USHORT Rsv1:9;
849 USHORT NumTID:4;
850#endif /* !RT_BIG_ENDIAN */
851} MTBAR_CONTROL, *PMTBAR_CONTROL;
852
853typedef struct PACKED {
854#ifdef RT_BIG_ENDIAN
855 USHORT TID:4;
856 USHORT Rsv1:12;
857#else
858 USHORT Rsv1:12;
859 USHORT TID:4;
860#endif /* !RT_BIG_ENDIAN */
861} PER_TID_INFO, *PPER_TID_INFO;
862
863typedef struct {
864 PER_TID_INFO PerTID;
865 BASEQ_CONTROL BAStartingSeq;
866} EACH_TID, *PEACH_TID;
867
868
869typedef struct PACKED _PSPOLL_FRAME {
870 FRAME_CONTROL FC;
871 USHORT Aid;
872 UCHAR Bssid[MAC_ADDR_LEN];
873 UCHAR Ta[MAC_ADDR_LEN];
874} PSPOLL_FRAME, *PPSPOLL_FRAME;
875
876typedef struct PACKED _RTS_FRAME {
877 FRAME_CONTROL FC;
878 USHORT Duration;
879 UCHAR Addr1[MAC_ADDR_LEN];
880 UCHAR Addr2[MAC_ADDR_LEN];
881}RTS_FRAME, *PRTS_FRAME;
882
883// BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap.
884typedef struct PACKED _FRAME_BA_REQ {
885 FRAME_CONTROL FC;
886 USHORT Duration;
887 UCHAR Addr1[MAC_ADDR_LEN];
888 UCHAR Addr2[MAC_ADDR_LEN];
889 BAR_CONTROL BARControl;
890 BASEQ_CONTROL BAStartingSeq;
891} FRAME_BA_REQ, *PFRAME_BA_REQ;
892
893typedef struct PACKED _FRAME_MTBA_REQ {
894 FRAME_CONTROL FC;
895 USHORT Duration;
896 UCHAR Addr1[MAC_ADDR_LEN];
897 UCHAR Addr2[MAC_ADDR_LEN];
898 MTBAR_CONTROL MTBARControl;
899 PER_TID_INFO PerTIDInfo;
900 BASEQ_CONTROL BAStartingSeq;
901} FRAME_MTBA_REQ, *PFRAME_MTBA_REQ;
902
903// Compressed format is mandantory in HT STA
904typedef struct PACKED _FRAME_MTBA {
905 FRAME_CONTROL FC;
906 USHORT Duration;
907 UCHAR Addr1[MAC_ADDR_LEN];
908 UCHAR Addr2[MAC_ADDR_LEN];
909 BA_CONTROL BAControl;
910 BASEQ_CONTROL BAStartingSeq;
911 UCHAR BitMap[8];
912} FRAME_MTBA, *PFRAME_MTBA;
913
914typedef struct PACKED _FRAME_PSMP_ACTION {
915 HEADER_802_11 Hdr;
916 UCHAR Category;
917 UCHAR Action;
918 UCHAR Psmp; // 7.3.1.25
919} FRAME_PSMP_ACTION, *PFRAME_PSMP_ACTION;
920
921typedef struct PACKED _FRAME_ACTION_HDR {
922 HEADER_802_11 Hdr;
923 UCHAR Category;
924 UCHAR Action;
925} FRAME_ACTION_HDR, *PFRAME_ACTION_HDR;
926
927//Action Frame
928//Action Frame Category:Spectrum, Action:Channel Switch. 7.3.2.20
929typedef struct PACKED _CHAN_SWITCH_ANNOUNCE {
930 UCHAR ElementID; // ID = IE_CHANNEL_SWITCH_ANNOUNCEMENT = 37
931 UCHAR Len;
932 CHA_SWITCH_ANNOUNCE_IE CSAnnounceIe;
933} CHAN_SWITCH_ANNOUNCE, *PCHAN_SWITCH_ANNOUNCE;
934
935
936//802.11n : 7.3.2.20a
937typedef struct PACKED _SECOND_CHAN_OFFSET {
938 UCHAR ElementID; // ID = IE_SECONDARY_CH_OFFSET = 62
939 UCHAR Len;
940 SEC_CHA_OFFSET_IE SecChOffsetIe;
941} SECOND_CHAN_OFFSET, *PSECOND_CHAN_OFFSET;
942
943
944typedef struct PACKED _FRAME_SPETRUM_CS {
945 HEADER_802_11 Hdr;
946 UCHAR Category;
947 UCHAR Action;
948 CHAN_SWITCH_ANNOUNCE CSAnnounce;
949 SECOND_CHAN_OFFSET SecondChannel;
950} FRAME_SPETRUM_CS, *PFRAME_SPETRUM_CS;
951
952
953typedef struct PACKED _FRAME_ADDBA_REQ {
954 HEADER_802_11 Hdr;
955 UCHAR Category;
956 UCHAR Action;
957 UCHAR Token; // 1
958 BA_PARM BaParm; // 2 - 10
959 USHORT TimeOutValue; // 0 - 0
960 BASEQ_CONTROL BaStartSeq; // 0-0
961} FRAME_ADDBA_REQ, *PFRAME_ADDBA_REQ;
962
963typedef struct PACKED _FRAME_ADDBA_RSP {
964 HEADER_802_11 Hdr;
965 UCHAR Category;
966 UCHAR Action;
967 UCHAR Token;
968 USHORT StatusCode;
969 BA_PARM BaParm; //0 - 2
970 USHORT TimeOutValue;
971} FRAME_ADDBA_RSP, *PFRAME_ADDBA_RSP;
972
973typedef struct PACKED _FRAME_DELBA_REQ {
974 HEADER_802_11 Hdr;
975 UCHAR Category;
976 UCHAR Action;
977 DELBA_PARM DelbaParm;
978 USHORT ReasonCode;
979} FRAME_DELBA_REQ, *PFRAME_DELBA_REQ;
980
981
982//7.2.1.7
983typedef struct PACKED _FRAME_BAR {
984 FRAME_CONTROL FC;
985 USHORT Duration;
986 UCHAR Addr1[MAC_ADDR_LEN];
987 UCHAR Addr2[MAC_ADDR_LEN];
988 BAR_CONTROL BarControl;
989 BASEQ_CONTROL StartingSeq;
990} FRAME_BAR, *PFRAME_BAR;
991
992//7.2.1.7
993typedef struct PACKED _FRAME_BA {
994 FRAME_CONTROL FC;
995 USHORT Duration;
996 UCHAR Addr1[MAC_ADDR_LEN];
997 UCHAR Addr2[MAC_ADDR_LEN];
998 BAR_CONTROL BarControl;
999 BASEQ_CONTROL StartingSeq;
1000 UCHAR bitmask[8];
1001} FRAME_BA, *PFRAME_BA;
1002
1003
1004// Radio Measuement Request Frame Format
1005typedef struct PACKED _FRAME_RM_REQ_ACTION {
1006 HEADER_802_11 Hdr;
1007 UCHAR Category;
1008 UCHAR Action;
1009 UCHAR Token;
1010 USHORT Repetition;
1011 UCHAR data[0];
1012} FRAME_RM_REQ_ACTION, *PFRAME_RM_REQ_ACTION;
1013
1014typedef struct PACKED {
1015 UCHAR ID;
1016 UCHAR Length;
1017 UCHAR ChannelSwitchMode;
1018 UCHAR NewRegClass;
1019 UCHAR NewChannelNum;
1020 UCHAR ChannelSwitchCount;
1021} HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE, *PHT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE;
1022
1023
1024//
1025// _Limit must be the 2**n - 1
1026// _SEQ1 , _SEQ2 must be within 0 ~ _Limit
1027//
1028#define SEQ_STEPONE(_SEQ1, _SEQ2, _Limit) ((_SEQ1 == ((_SEQ2+1) & _Limit)))
1029#define SEQ_SMALLER(_SEQ1, _SEQ2, _Limit) (((_SEQ1-_SEQ2) & ((_Limit+1)>>1)))
1030#define SEQ_LARGER(_SEQ1, _SEQ2, _Limit) ((_SEQ1 != _SEQ2) && !(((_SEQ1-_SEQ2) & ((_Limit+1)>>1))))
1031#define SEQ_WITHIN_WIN(_SEQ1, _SEQ2, _WIN, _Limit) (SEQ_LARGER(_SEQ1, _SEQ2, _Limit) && \
1032 SEQ_SMALLER(_SEQ1, ((_SEQ2+_WIN+1)&_Limit), _Limit))
1033
1034//
1035// Contention-free parameter (without ID and Length)
1036//
1037typedef struct PACKED {
1038 BOOLEAN bValid; // 1: variable contains valid value
1039 UCHAR CfpCount;
1040 UCHAR CfpPeriod;
1041 USHORT CfpMaxDuration;
1042 USHORT CfpDurRemaining;
1043} CF_PARM, *PCF_PARM;
1044
1045typedef struct _CIPHER_SUITE {
1046 NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher 1, this one has more secured cipher suite
1047 NDIS_802_11_ENCRYPTION_STATUS PairCipherAux; // Unicast cipher 2 if AP announce two unicast cipher suite
1048 NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Group cipher
1049 USHORT RsnCapability; // RSN capability from beacon
1050 BOOLEAN bMixMode; // Indicate Pair & Group cipher might be different
1051} CIPHER_SUITE, *PCIPHER_SUITE;
1052
1053// EDCA configuration from AP's BEACON/ProbeRsp
1054typedef struct {
1055 BOOLEAN bValid; // 1: variable contains valid value
1056 BOOLEAN bAdd; // 1: variable contains valid value
1057 BOOLEAN bQAck;
1058 BOOLEAN bQueueRequest;
1059 BOOLEAN bTxopRequest;
1060 BOOLEAN bAPSDCapable;
1061// BOOLEAN bMoreDataAck;
1062 UCHAR EdcaUpdateCount;
1063 UCHAR Aifsn[4]; // 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO
1064 UCHAR Cwmin[4];
1065 UCHAR Cwmax[4];
1066 USHORT Txop[4]; // in unit of 32-us
1067 BOOLEAN bACM[4]; // 1: Admission Control of AC_BK is mandattory
1068} EDCA_PARM, *PEDCA_PARM;
1069
1070// QBSS LOAD information from QAP's BEACON/ProbeRsp
1071typedef struct {
1072 BOOLEAN bValid; // 1: variable contains valid value
1073 USHORT StaNum;
1074 UCHAR ChannelUtilization;
1075 USHORT RemainingAdmissionControl; // in unit of 32-us
1076} QBSS_LOAD_PARM, *PQBSS_LOAD_PARM;
1077
1078// QBSS Info field in QSTA's assoc req
1079typedef struct PACKED {
1080#ifdef RT_BIG_ENDIAN
1081 UCHAR Rsv2:1;
1082 UCHAR MaxSPLength:2;
1083 UCHAR Rsv1:1;
1084 UCHAR UAPSD_AC_BE:1;
1085 UCHAR UAPSD_AC_BK:1;
1086 UCHAR UAPSD_AC_VI:1;
1087 UCHAR UAPSD_AC_VO:1;
1088#else
1089 UCHAR UAPSD_AC_VO:1;
1090 UCHAR UAPSD_AC_VI:1;
1091 UCHAR UAPSD_AC_BK:1;
1092 UCHAR UAPSD_AC_BE:1;
1093 UCHAR Rsv1:1;
1094 UCHAR MaxSPLength:2;
1095 UCHAR Rsv2:1;
1096#endif /* !RT_BIG_ENDIAN */
1097} QBSS_STA_INFO_PARM, *PQBSS_STA_INFO_PARM;
1098
1099// QBSS Info field in QAP's Beacon/ProbeRsp
1100typedef struct PACKED {
1101#ifdef RT_BIG_ENDIAN
1102 UCHAR UAPSD:1;
1103 UCHAR Rsv:3;
1104 UCHAR ParamSetCount:4;
1105#else
1106 UCHAR ParamSetCount:4;
1107 UCHAR Rsv:3;
1108 UCHAR UAPSD:1;
1109#endif /* !RT_BIG_ENDIAN */
1110} QBSS_AP_INFO_PARM, *PQBSS_AP_INFO_PARM;
1111
1112// QOS Capability reported in QAP's BEACON/ProbeRsp
1113// QOS Capability sent out in QSTA's AssociateReq/ReAssociateReq
1114typedef struct {
1115 BOOLEAN bValid; // 1: variable contains valid value
1116 BOOLEAN bQAck;
1117 BOOLEAN bQueueRequest;
1118 BOOLEAN bTxopRequest;
1119// BOOLEAN bMoreDataAck;
1120 UCHAR EdcaUpdateCount;
1121} QOS_CAPABILITY_PARM, *PQOS_CAPABILITY_PARM;
1122
1123#ifdef CONFIG_STA_SUPPORT
1124typedef struct {
1125 UCHAR IELen;
1126 UCHAR IE[MAX_CUSTOM_LEN];
1127} WPA_IE_;
1128#endif // CONFIG_STA_SUPPORT //
1129
1130
1131typedef struct {
1132 UCHAR Bssid[MAC_ADDR_LEN];
1133 UCHAR Channel;
1134 UCHAR CentralChannel; //Store the wide-band central channel for 40MHz. .used in 40MHz AP. Or this is the same as Channel.
1135 UCHAR BssType;
1136 USHORT AtimWin;
1137 USHORT BeaconPeriod;
1138
1139 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
1140 UCHAR SupRateLen;
1141 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1142 UCHAR ExtRateLen;
1143 HT_CAPABILITY_IE HtCapability;
1144 UCHAR HtCapabilityLen;
1145 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1146 UCHAR AddHtInfoLen;
1147 UCHAR NewExtChanOffset;
1148 CHAR Rssi;
1149 UCHAR Privacy; // Indicate security function ON/OFF. Don't mess up with auth mode.
1150 UCHAR Hidden;
1151
1152 USHORT DtimPeriod;
1153 USHORT CapabilityInfo;
1154
1155 USHORT CfpCount;
1156 USHORT CfpPeriod;
1157 USHORT CfpMaxDuration;
1158 USHORT CfpDurRemaining;
1159 UCHAR SsidLen;
1160 CHAR Ssid[MAX_LEN_OF_SSID];
1161
1162 ULONG LastBeaconRxTime; // OS's timestamp
1163
1164 BOOLEAN bSES;
1165
1166 // New for WPA2
1167 CIPHER_SUITE WPA; // AP announced WPA cipher suite
1168 CIPHER_SUITE WPA2; // AP announced WPA2 cipher suite
1169
1170 // New for microsoft WPA support
1171 NDIS_802_11_FIXED_IEs FixIEs;
1172 NDIS_802_11_AUTHENTICATION_MODE AuthModeAux; // Addition mode for WPA2 / WPA capable AP
1173 NDIS_802_11_AUTHENTICATION_MODE AuthMode;
1174 NDIS_802_11_WEP_STATUS WepStatus; // Unicast Encryption Algorithm extract from VAR_IE
1175 USHORT VarIELen; // Length of next VIE include EID & Length
1176 UCHAR VarIEs[MAX_VIE_LEN];
1177
1178 // CCX Ckip information
1179 UCHAR CkipFlag;
1180
1181 // CCX 2 TSF
1182 UCHAR PTSF[4]; // Parent TSF
1183 UCHAR TTSF[8]; // Target TSF
1184
1185 // 802.11e d9, and WMM
1186 EDCA_PARM EdcaParm;
1187 QOS_CAPABILITY_PARM QosCapability;
1188 QBSS_LOAD_PARM QbssLoad;
1189#ifdef CONFIG_STA_SUPPORT
1190 WPA_IE_ WpaIE;
1191 WPA_IE_ RsnIE;
1192#ifdef EXT_BUILD_CHANNEL_LIST
1193 UCHAR CountryString[3];
1194 BOOLEAN bHasCountryIE;
1195#endif // EXT_BUILD_CHANNEL_LIST //
1196#endif // CONFIG_STA_SUPPORT //
1197} BSS_ENTRY, *PBSS_ENTRY;
1198
1199typedef struct {
1200 UCHAR BssNr;
1201 UCHAR BssOverlapNr;
1202 BSS_ENTRY BssEntry[MAX_LEN_OF_BSS_TABLE];
1203} BSS_TABLE, *PBSS_TABLE;
1204
1205
1206typedef struct _MLME_QUEUE_ELEM {
1207 ULONG Machine;
1208 ULONG MsgType;
1209 ULONG MsgLen;
1210 UCHAR Msg[MGMT_DMA_BUFFER_SIZE];
1211 LARGE_INTEGER TimeStamp;
1212 UCHAR Rssi0;
1213 UCHAR Rssi1;
1214 UCHAR Rssi2;
1215 UCHAR Signal;
1216 UCHAR Channel;
1217 UCHAR Wcid;
1218 BOOLEAN Occupied;
1219} MLME_QUEUE_ELEM, *PMLME_QUEUE_ELEM;
1220
1221typedef struct _MLME_QUEUE {
1222 ULONG Num;
1223 ULONG Head;
1224 ULONG Tail;
1225 NDIS_SPIN_LOCK Lock;
1226 MLME_QUEUE_ELEM Entry[MAX_LEN_OF_MLME_QUEUE];
1227} MLME_QUEUE, *PMLME_QUEUE;
1228
1229typedef VOID (*STATE_MACHINE_FUNC)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem);
1230
1231typedef struct _STATE_MACHINE {
1232 ULONG Base;
1233 ULONG NrState;
1234 ULONG NrMsg;
1235 ULONG CurrState;
1236 STATE_MACHINE_FUNC *TransFunc;
1237} STATE_MACHINE, *PSTATE_MACHINE;
1238
1239
1240// MLME AUX data structure that hold temporarliy settings during a connection attempt.
1241// Once this attemp succeeds, all settings will be copy to pAd->StaActive.
1242// A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of
1243// several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely
1244// separate this under-trial settings away from pAd->StaActive so that once
1245// this new attempt failed, driver can auto-recover back to the active settings.
1246typedef struct _MLME_AUX {
1247 UCHAR BssType;
1248 UCHAR Ssid[MAX_LEN_OF_SSID];
1249 UCHAR SsidLen;
1250 UCHAR Bssid[MAC_ADDR_LEN];
1251 UCHAR AutoReconnectSsid[MAX_LEN_OF_SSID];
1252 UCHAR AutoReconnectSsidLen;
1253 USHORT Alg;
1254 UCHAR ScanType;
1255 UCHAR Channel;
1256 UCHAR CentralChannel;
1257 USHORT Aid;
1258 USHORT CapabilityInfo;
1259 USHORT BeaconPeriod;
1260 USHORT CfpMaxDuration;
1261 USHORT CfpPeriod;
1262 USHORT AtimWin;
1263
1264 // Copy supported rate from desired AP's beacon. We are trying to match
1265 // AP's supported and extended rate settings.
1266 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
1267 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1268 UCHAR SupRateLen;
1269 UCHAR ExtRateLen;
1270 HT_CAPABILITY_IE HtCapability;
1271 UCHAR HtCapabilityLen;
1272 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1273 UCHAR NewExtChannelOffset;
1274 //RT_HT_CAPABILITY SupportedHtPhy;
1275
1276 // new for QOS
1277 QOS_CAPABILITY_PARM APQosCapability; // QOS capability of the current associated AP
1278 EDCA_PARM APEdcaParm; // EDCA parameters of the current associated AP
1279 QBSS_LOAD_PARM APQbssLoad; // QBSS load of the current associated AP
1280
1281 // new to keep Ralink specific feature
1282 ULONG APRalinkIe;
1283
1284 BSS_TABLE SsidBssTab; // AP list for the same SSID
1285 BSS_TABLE RoamTab; // AP list eligible for roaming
1286 ULONG BssIdx;
1287 ULONG RoamIdx;
1288
1289 BOOLEAN CurrReqIsFromNdis;
1290
1291 RALINK_TIMER_STRUCT BeaconTimer, ScanTimer;
1292 RALINK_TIMER_STRUCT AuthTimer;
1293 RALINK_TIMER_STRUCT AssocTimer, ReassocTimer, DisassocTimer;
1294} MLME_AUX, *PMLME_AUX;
1295
1296typedef struct _MLME_ADDBA_REQ_STRUCT{
1297 UCHAR Wcid; //
1298 UCHAR pAddr[MAC_ADDR_LEN];
1299 UCHAR BaBufSize;
1300 USHORT TimeOutValue;
1301 UCHAR TID;
1302 UCHAR Token;
1303 USHORT BaStartSeq;
1304} MLME_ADDBA_REQ_STRUCT, *PMLME_ADDBA_REQ_STRUCT;
1305
1306
1307typedef struct _MLME_DELBA_REQ_STRUCT{
1308 UCHAR Wcid; //
1309 UCHAR Addr[MAC_ADDR_LEN];
1310 UCHAR TID;
1311 UCHAR Initiator;
1312} MLME_DELBA_REQ_STRUCT, *PMLME_DELBA_REQ_STRUCT;
1313
1314// assoc struct is equal to reassoc
1315typedef struct _MLME_ASSOC_REQ_STRUCT{
1316 UCHAR Addr[MAC_ADDR_LEN];
1317 USHORT CapabilityInfo;
1318 USHORT ListenIntv;
1319 ULONG Timeout;
1320} MLME_ASSOC_REQ_STRUCT, *PMLME_ASSOC_REQ_STRUCT, MLME_REASSOC_REQ_STRUCT, *PMLME_REASSOC_REQ_STRUCT;
1321
1322typedef struct _MLME_DISASSOC_REQ_STRUCT{
1323 UCHAR Addr[MAC_ADDR_LEN];
1324 USHORT Reason;
1325} MLME_DISASSOC_REQ_STRUCT, *PMLME_DISASSOC_REQ_STRUCT;
1326
1327typedef struct _MLME_AUTH_REQ_STRUCT {
1328 UCHAR Addr[MAC_ADDR_LEN];
1329 USHORT Alg;
1330 ULONG Timeout;
1331} MLME_AUTH_REQ_STRUCT, *PMLME_AUTH_REQ_STRUCT;
1332
1333typedef struct _MLME_DEAUTH_REQ_STRUCT {
1334 UCHAR Addr[MAC_ADDR_LEN];
1335 USHORT Reason;
1336} MLME_DEAUTH_REQ_STRUCT, *PMLME_DEAUTH_REQ_STRUCT;
1337
1338typedef struct {
1339 ULONG BssIdx;
1340} MLME_JOIN_REQ_STRUCT;
1341
1342typedef struct _MLME_SCAN_REQ_STRUCT {
1343 UCHAR Bssid[MAC_ADDR_LEN];
1344 UCHAR BssType;
1345 UCHAR ScanType;
1346 UCHAR SsidLen;
1347 CHAR Ssid[MAX_LEN_OF_SSID];
1348} MLME_SCAN_REQ_STRUCT, *PMLME_SCAN_REQ_STRUCT;
1349
1350typedef struct _MLME_START_REQ_STRUCT {
1351 CHAR Ssid[MAX_LEN_OF_SSID];
1352 UCHAR SsidLen;
1353} MLME_START_REQ_STRUCT, *PMLME_START_REQ_STRUCT;
1354
1355#ifdef CONFIG_STA_SUPPORT
1356#ifdef QOS_DLS_SUPPORT
1357// structure for DLS
1358typedef struct _RT_802_11_DLS {
1359 USHORT TimeOut; // Use to time out while slience, unit: second , set by UI
1360 USHORT CountDownTimer; // Use to time out while slience,unit: second , used by driver only
1361 NDIS_802_11_MAC_ADDRESS MacAddr; // set by UI
1362 UCHAR Status; // 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
1363 BOOLEAN Valid; // 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
1364 RALINK_TIMER_STRUCT Timer; // Use to time out while handshake
1365 USHORT Sequence;
1366 USHORT MacTabMatchWCID; // ASIC
1367 BOOLEAN bHTCap;
1368 PVOID pAd;
1369} RT_802_11_DLS, *PRT_802_11_DLS;
1370
1371typedef struct _MLME_DLS_REQ_STRUCT {
1372 PRT_802_11_DLS pDLS;
1373 USHORT Reason;
1374} MLME_DLS_REQ_STRUCT, *PMLME_DLS_REQ_STRUCT;
1375#endif // QOS_DLS_SUPPORT //
1376#endif // CONFIG_STA_SUPPORT //
1377
1378typedef struct PACKED {
1379 UCHAR Eid;
1380 UCHAR Len;
1381 CHAR Octet[1];
1382} EID_STRUCT,*PEID_STRUCT, BEACON_EID_STRUCT, *PBEACON_EID_STRUCT;
1383
1384typedef struct PACKED _RTMP_TX_RATE_SWITCH
1385{
1386 UCHAR ItemNo;
1387#ifdef RT_BIG_ENDIAN
1388 UCHAR Rsv2:2;
1389 UCHAR Mode:2;
1390 UCHAR Rsv1:1;
1391 UCHAR BW:1;
1392 UCHAR ShortGI:1;
1393 UCHAR STBC:1;
1394#else
1395 UCHAR STBC:1;
1396 UCHAR ShortGI:1;
1397 UCHAR BW:1;
1398 UCHAR Rsv1:1;
1399 UCHAR Mode:2;
1400 UCHAR Rsv2:2;
1401#endif
1402 UCHAR CurrMCS;
1403 UCHAR TrainUp;
1404 UCHAR TrainDown;
1405} RRTMP_TX_RATE_SWITCH, *PRTMP_TX_RATE_SWITCH;
1406
1407// ========================== AP mlme.h ===============================
1408#define TBTT_PRELOAD_TIME 384 // usec. LomgPreamble + 24-byte at 1Mbps
1409#define DEFAULT_DTIM_PERIOD 1
1410
1411// weighting factor to calculate Channel quality, total should be 100%
1412//#define RSSI_WEIGHTING 0
1413//#define TX_WEIGHTING 40
1414//#define RX_WEIGHTING 60
1415
1416#define MAC_TABLE_AGEOUT_TIME 300 // unit: sec
1417#define MAC_TABLE_ASSOC_TIMEOUT 5 // unit: sec
1418#define MAC_TABLE_FULL(Tab) ((Tab).size == MAX_LEN_OF_MAC_TABLE)
1419
1420// AP shall drop the sta if contine Tx fail count reach it.
1421#define MAC_ENTRY_LIFE_CHECK_CNT 20 // packet cnt.
1422
1423// Value domain of pMacEntry->Sst
1424typedef enum _Sst {
1425 SST_NOT_AUTH, // 0: equivalent to IEEE 802.11/1999 state 1
1426 SST_AUTH, // 1: equivalent to IEEE 802.11/1999 state 2
1427 SST_ASSOC // 2: equivalent to IEEE 802.11/1999 state 3
1428} SST;
1429
1430// value domain of pMacEntry->AuthState
1431typedef enum _AuthState {
1432 AS_NOT_AUTH,
1433 AS_AUTH_OPEN, // STA has been authenticated using OPEN SYSTEM
1434 AS_AUTH_KEY, // STA has been authenticated using SHARED KEY
1435 AS_AUTHENTICATING // STA is waiting for AUTH seq#3 using SHARED KEY
1436} AUTH_STATE;
1437
1438//for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
1439typedef enum _ApWpaState {
1440 AS_NOTUSE, // 0
1441 AS_DISCONNECT, // 1
1442 AS_DISCONNECTED, // 2
1443 AS_INITIALIZE, // 3
1444 AS_AUTHENTICATION, // 4
1445 AS_AUTHENTICATION2, // 5
1446 AS_INITPMK, // 6
1447 AS_INITPSK, // 7
1448 AS_PTKSTART, // 8
1449 AS_PTKINIT_NEGOTIATING, // 9
1450 AS_PTKINITDONE, // 10
1451 AS_UPDATEKEYS, // 11
1452 AS_INTEGRITY_FAILURE, // 12
1453 AS_KEYUPDATE, // 13
1454} AP_WPA_STATE;
1455
1456// for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
1457typedef enum _GTKState {
1458 REKEY_NEGOTIATING,
1459 REKEY_ESTABLISHED,
1460 KEYERROR,
1461} GTK_STATE;
1462
1463// for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
1464typedef enum _WpaGTKState {
1465 SETKEYS,
1466 SETKEYS_DONE,
1467} WPA_GTK_STATE;
1468// ====================== end of AP mlme.h ============================
1469
1470
1471#endif // MLME_H__
diff --git a/drivers/staging/rt2870/netif_block.h b/drivers/staging/rt2870/netif_block.h
new file mode 100644
index 00000000000..6e5151c4109
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/oid.h b/drivers/staging/rt2870/oid.h
new file mode 100644
index 00000000000..d788db6b626
--- /dev/null
+++ b/drivers/staging/rt2870/oid.h
@@ -0,0 +1,1091 @@
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#define TRUE 1
41#define FALSE 0
42//
43// IEEE 802.11 Structures and definitions
44//
45#define MAX_TX_POWER_LEVEL 100 /* mW */
46#define MAX_RSSI_TRIGGER -10 /* dBm */
47#define MIN_RSSI_TRIGGER -200 /* dBm */
48#define MAX_FRAG_THRESHOLD 2346 /* byte count */
49#define MIN_FRAG_THRESHOLD 256 /* byte count */
50#define MAX_RTS_THRESHOLD 2347 /* byte count */
51
52// new types for Media Specific Indications
53// Extension channel offset
54#define EXTCHA_NONE 0
55#define EXTCHA_ABOVE 0x1
56#define EXTCHA_BELOW 0x3
57
58// BW
59#define BAND_WIDTH_20 0
60#define BAND_WIDTH_40 1
61#define BAND_WIDTH_BOTH 2
62#define BAND_WIDTH_10 3 // 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
63// SHORTGI
64#define GAP_INTERVAL_400 1 // only support in HT mode
65#define GAP_INTERVAL_800 0
66#define GAP_INTERVAL_BOTH 2
67
68#define NdisMediaStateConnected 1
69#define NdisMediaStateDisconnected 0
70
71#define NDIS_802_11_LENGTH_SSID 32
72#define NDIS_802_11_LENGTH_RATES 8
73#define NDIS_802_11_LENGTH_RATES_EX 16
74#define MAC_ADDR_LENGTH 6
75#define MAX_NUM_OF_CHS 49 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc
76#define MAX_NUMBER_OF_EVENT 10 // entry # in EVENT table
77#define MAX_NUMBER_OF_MAC 32 // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
78#define MAX_NUMBER_OF_ACL 64
79#define MAX_LENGTH_OF_SUPPORT_RATES 12 // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
80#define MAX_NUMBER_OF_DLS_ENTRY 4
81
82#ifndef UNDER_CE
83// OID definition, since NDIS 5.0 didn't define these, we need to define for our own
84//#if _WIN32_WINNT<=0x0500
85
86#define OID_GEN_MACHINE_NAME 0x0001021A
87
88#ifdef RALINK_ATE
89#define RT_QUERY_ATE_TXDONE_COUNT 0x0401
90#endif // RALINK_ATE //
91#define RT_QUERY_SIGNAL_CONTEXT 0x0402
92#define RT_SET_IAPP_PID 0x0404
93#define RT_SET_APD_PID 0x0405
94#define RT_SET_DEL_MAC_ENTRY 0x0406
95
96//
97// IEEE 802.11 OIDs
98//
99#define OID_GET_SET_TOGGLE 0x8000
100
101#define OID_802_11_NETWORK_TYPES_SUPPORTED 0x0103
102#define OID_802_11_NETWORK_TYPE_IN_USE 0x0104
103#define OID_802_11_RSSI_TRIGGER 0x0107
104#define RT_OID_802_11_RSSI 0x0108 //rt2860 only , kathy
105#define RT_OID_802_11_RSSI_1 0x0109 //rt2860 only , kathy
106#define RT_OID_802_11_RSSI_2 0x010A //rt2860 only , kathy
107#define OID_802_11_NUMBER_OF_ANTENNAS 0x010B
108#define OID_802_11_RX_ANTENNA_SELECTED 0x010C
109#define OID_802_11_TX_ANTENNA_SELECTED 0x010D
110#define OID_802_11_SUPPORTED_RATES 0x010E
111#define OID_802_11_ADD_WEP 0x0112
112#define OID_802_11_REMOVE_WEP 0x0113
113#define OID_802_11_DISASSOCIATE 0x0114
114#define OID_802_11_PRIVACY_FILTER 0x0118
115#define OID_802_11_ASSOCIATION_INFORMATION 0x011E
116#define OID_802_11_TEST 0x011F
117#define RT_OID_802_11_COUNTRY_REGION 0x0507
118#define OID_802_11_BSSID_LIST_SCAN 0x0508
119#define OID_802_11_SSID 0x0509
120#define OID_802_11_BSSID 0x050A
121#define RT_OID_802_11_RADIO 0x050B
122#define RT_OID_802_11_PHY_MODE 0x050C
123#define RT_OID_802_11_STA_CONFIG 0x050D
124#define OID_802_11_DESIRED_RATES 0x050E
125#define RT_OID_802_11_PREAMBLE 0x050F
126#define OID_802_11_WEP_STATUS 0x0510
127#define OID_802_11_AUTHENTICATION_MODE 0x0511
128#define OID_802_11_INFRASTRUCTURE_MODE 0x0512
129#define RT_OID_802_11_RESET_COUNTERS 0x0513
130#define OID_802_11_RTS_THRESHOLD 0x0514
131#define OID_802_11_FRAGMENTATION_THRESHOLD 0x0515
132#define OID_802_11_POWER_MODE 0x0516
133#define OID_802_11_TX_POWER_LEVEL 0x0517
134#define RT_OID_802_11_ADD_WPA 0x0518
135#define OID_802_11_REMOVE_KEY 0x0519
136#define OID_802_11_ADD_KEY 0x0520
137#define OID_802_11_CONFIGURATION 0x0521
138#define OID_802_11_TX_PACKET_BURST 0x0522
139#define RT_OID_802_11_QUERY_NOISE_LEVEL 0x0523
140#define RT_OID_802_11_EXTRA_INFO 0x0524
141#ifdef DBG
142#define RT_OID_802_11_HARDWARE_REGISTER 0x0525
143#endif
144#define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS
145#define OID_802_11_DEAUTHENTICATION 0x0526
146#define OID_802_11_DROP_UNENCRYPTED 0x0527
147#define OID_802_11_MIC_FAILURE_REPORT_FRAME 0x0528
148
149// For 802.1x daemin using to require current driver configuration
150#define OID_802_11_RADIUS_QUERY_SETTING 0x0540
151
152#define RT_OID_DEVICE_NAME 0x0607
153#define RT_OID_VERSION_INFO 0x0608
154#define OID_802_11_BSSID_LIST 0x0609
155#define OID_802_3_CURRENT_ADDRESS 0x060A
156#define OID_GEN_MEDIA_CONNECT_STATUS 0x060B
157#define RT_OID_802_11_QUERY_LINK_STATUS 0x060C
158#define OID_802_11_RSSI 0x060D
159#define OID_802_11_STATISTICS 0x060E
160#define OID_GEN_RCV_OK 0x060F
161#define OID_GEN_RCV_NO_BUFFER 0x0610
162#define RT_OID_802_11_QUERY_EEPROM_VERSION 0x0611
163#define RT_OID_802_11_QUERY_FIRMWARE_VERSION 0x0612
164#define RT_OID_802_11_QUERY_LAST_RX_RATE 0x0613
165#define RT_OID_802_11_TX_POWER_LEVEL_1 0x0614
166#define RT_OID_802_11_QUERY_PIDVID 0x0615
167//for WPA_SUPPLICANT_SUPPORT
168#define OID_SET_COUNTERMEASURES 0x0616
169#define OID_802_11_SET_IEEE8021X 0x0617
170#define OID_802_11_SET_IEEE8021X_REQUIRE_KEY 0x0618
171#define OID_802_11_PMKID 0x0620
172#define RT_OID_WPA_SUPPLICANT_SUPPORT 0x0621
173#define RT_OID_WE_VERSION_COMPILED 0x0622
174#define RT_OID_NEW_DRIVER 0x0623
175
176
177//rt2860 , kathy
178#define RT_OID_802_11_SNR_0 0x0630
179#define RT_OID_802_11_SNR_1 0x0631
180#define RT_OID_802_11_QUERY_LAST_TX_RATE 0x0632
181#define RT_OID_802_11_QUERY_HT_PHYMODE 0x0633
182#define RT_OID_802_11_SET_HT_PHYMODE 0x0634
183#define OID_802_11_RELOAD_DEFAULTS 0x0635
184#define RT_OID_802_11_QUERY_APSD_SETTING 0x0636
185#define RT_OID_802_11_SET_APSD_SETTING 0x0637
186#define RT_OID_802_11_QUERY_APSD_PSM 0x0638
187#define RT_OID_802_11_SET_APSD_PSM 0x0639
188#define RT_OID_802_11_QUERY_DLS 0x063A
189#define RT_OID_802_11_SET_DLS 0x063B
190#define RT_OID_802_11_QUERY_DLS_PARAM 0x063C
191#define RT_OID_802_11_SET_DLS_PARAM 0x063D
192#define RT_OID_802_11_QUERY_WMM 0x063E
193#define RT_OID_802_11_SET_WMM 0x063F
194#define RT_OID_802_11_QUERY_IMME_BA_CAP 0x0640
195#define RT_OID_802_11_SET_IMME_BA_CAP 0x0641
196#define RT_OID_802_11_QUERY_BATABLE 0x0642
197#define RT_OID_802_11_ADD_IMME_BA 0x0643
198#define RT_OID_802_11_TEAR_IMME_BA 0x0644
199#define RT_OID_DRIVER_DEVICE_NAME 0x0645
200#define RT_OID_802_11_QUERY_DAT_HT_PHYMODE 0x0646
201#define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT 0x0647
202
203// Ralink defined OIDs
204// Dennis Lee move to platform specific
205
206#define RT_OID_802_11_BSSID (OID_GET_SET_TOGGLE | OID_802_11_BSSID)
207#define RT_OID_802_11_SSID (OID_GET_SET_TOGGLE | OID_802_11_SSID)
208#define RT_OID_802_11_INFRASTRUCTURE_MODE (OID_GET_SET_TOGGLE | OID_802_11_INFRASTRUCTURE_MODE)
209#define RT_OID_802_11_ADD_WEP (OID_GET_SET_TOGGLE | OID_802_11_ADD_WEP)
210#define RT_OID_802_11_ADD_KEY (OID_GET_SET_TOGGLE | OID_802_11_ADD_KEY)
211#define RT_OID_802_11_REMOVE_WEP (OID_GET_SET_TOGGLE | OID_802_11_REMOVE_WEP)
212#define RT_OID_802_11_REMOVE_KEY (OID_GET_SET_TOGGLE | OID_802_11_REMOVE_KEY)
213#define RT_OID_802_11_DISASSOCIATE (OID_GET_SET_TOGGLE | OID_802_11_DISASSOCIATE)
214#define RT_OID_802_11_AUTHENTICATION_MODE (OID_GET_SET_TOGGLE | OID_802_11_AUTHENTICATION_MODE)
215#define RT_OID_802_11_PRIVACY_FILTER (OID_GET_SET_TOGGLE | OID_802_11_PRIVACY_FILTER)
216#define RT_OID_802_11_BSSID_LIST_SCAN (OID_GET_SET_TOGGLE | OID_802_11_BSSID_LIST_SCAN)
217#define RT_OID_802_11_WEP_STATUS (OID_GET_SET_TOGGLE | OID_802_11_WEP_STATUS)
218#define RT_OID_802_11_RELOAD_DEFAULTS (OID_GET_SET_TOGGLE | OID_802_11_RELOAD_DEFAULTS)
219#define RT_OID_802_11_NETWORK_TYPE_IN_USE (OID_GET_SET_TOGGLE | OID_802_11_NETWORK_TYPE_IN_USE)
220#define RT_OID_802_11_TX_POWER_LEVEL (OID_GET_SET_TOGGLE | OID_802_11_TX_POWER_LEVEL)
221#define RT_OID_802_11_RSSI_TRIGGER (OID_GET_SET_TOGGLE | OID_802_11_RSSI_TRIGGER)
222#define RT_OID_802_11_FRAGMENTATION_THRESHOLD (OID_GET_SET_TOGGLE | OID_802_11_FRAGMENTATION_THRESHOLD)
223#define RT_OID_802_11_RTS_THRESHOLD (OID_GET_SET_TOGGLE | OID_802_11_RTS_THRESHOLD)
224#define RT_OID_802_11_RX_ANTENNA_SELECTED (OID_GET_SET_TOGGLE | OID_802_11_RX_ANTENNA_SELECTED)
225#define RT_OID_802_11_TX_ANTENNA_SELECTED (OID_GET_SET_TOGGLE | OID_802_11_TX_ANTENNA_SELECTED)
226#define RT_OID_802_11_SUPPORTED_RATES (OID_GET_SET_TOGGLE | OID_802_11_SUPPORTED_RATES)
227#define RT_OID_802_11_DESIRED_RATES (OID_GET_SET_TOGGLE | OID_802_11_DESIRED_RATES)
228#define RT_OID_802_11_CONFIGURATION (OID_GET_SET_TOGGLE | OID_802_11_CONFIGURATION)
229#define RT_OID_802_11_POWER_MODE (OID_GET_SET_TOGGLE | OID_802_11_POWER_MODE)
230
231typedef enum _NDIS_802_11_STATUS_TYPE
232{
233 Ndis802_11StatusType_Authentication,
234 Ndis802_11StatusType_MediaStreamMode,
235 Ndis802_11StatusType_PMKID_CandidateList,
236 Ndis802_11StatusTypeMax // not a real type, defined as an upper bound
237} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE;
238
239typedef UCHAR NDIS_802_11_MAC_ADDRESS[6];
240
241typedef struct _NDIS_802_11_STATUS_INDICATION
242{
243 NDIS_802_11_STATUS_TYPE StatusType;
244} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION;
245
246// mask for authentication/integrity fields
247#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f
248
249#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01
250#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02
251#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06
252#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E
253
254typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST
255{
256 ULONG Length; // Length of structure
257 NDIS_802_11_MAC_ADDRESS Bssid;
258 ULONG Flags;
259} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST;
260
261//Added new types for PMKID Candidate lists.
262typedef struct _PMKID_CANDIDATE {
263 NDIS_802_11_MAC_ADDRESS BSSID;
264 ULONG Flags;
265} PMKID_CANDIDATE, *PPMKID_CANDIDATE;
266
267typedef struct _NDIS_802_11_PMKID_CANDIDATE_LIST
268{
269 ULONG Version; // Version of the structure
270 ULONG NumCandidates; // No. of pmkid candidates
271 PMKID_CANDIDATE CandidateList[1];
272} NDIS_802_11_PMKID_CANDIDATE_LIST, *PNDIS_802_11_PMKID_CANDIDATE_LIST;
273
274//Flags for PMKID Candidate list structure
275#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
276
277// Added new types for OFDM 5G and 2.4G
278typedef enum _NDIS_802_11_NETWORK_TYPE
279{
280 Ndis802_11FH,
281 Ndis802_11DS,
282 Ndis802_11OFDM5,
283 Ndis802_11OFDM5_N,
284 Ndis802_11OFDM24,
285 Ndis802_11OFDM24_N,
286 Ndis802_11Automode,
287 Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound
288} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE;
289
290typedef struct _NDIS_802_11_NETWORK_TYPE_LIST
291{
292 UINT NumberOfItems; // in list below, at least 1
293 NDIS_802_11_NETWORK_TYPE NetworkType [1];
294} NDIS_802_11_NETWORK_TYPE_LIST, *PNDIS_802_11_NETWORK_TYPE_LIST;
295
296typedef enum _NDIS_802_11_POWER_MODE
297{
298 Ndis802_11PowerModeCAM,
299 Ndis802_11PowerModeMAX_PSP,
300 Ndis802_11PowerModeFast_PSP,
301 Ndis802_11PowerModeLegacy_PSP,
302 Ndis802_11PowerModeMax // not a real mode, defined as an upper bound
303} NDIS_802_11_POWER_MODE, *PNDIS_802_11_POWER_MODE;
304
305typedef ULONG NDIS_802_11_TX_POWER_LEVEL; // in milliwatts
306
307//
308// Received Signal Strength Indication
309//
310typedef LONG NDIS_802_11_RSSI; // in dBm
311
312typedef struct _NDIS_802_11_CONFIGURATION_FH
313{
314 ULONG Length; // Length of structure
315 ULONG HopPattern; // As defined by 802.11, MSB set
316 ULONG HopSet; // to one if non-802.11
317 ULONG DwellTime; // units are Kusec
318} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH;
319
320typedef struct _NDIS_802_11_CONFIGURATION
321{
322 ULONG Length; // Length of structure
323 ULONG BeaconPeriod; // units are Kusec
324 ULONG ATIMWindow; // units are Kusec
325 ULONG DSConfig; // Frequency, units are kHz
326 NDIS_802_11_CONFIGURATION_FH FHConfig;
327} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION;
328
329typedef struct _NDIS_802_11_STATISTICS
330{
331 ULONG Length; // Length of structure
332 LARGE_INTEGER TransmittedFragmentCount;
333 LARGE_INTEGER MulticastTransmittedFrameCount;
334 LARGE_INTEGER FailedCount;
335 LARGE_INTEGER RetryCount;
336 LARGE_INTEGER MultipleRetryCount;
337 LARGE_INTEGER RTSSuccessCount;
338 LARGE_INTEGER RTSFailureCount;
339 LARGE_INTEGER ACKFailureCount;
340 LARGE_INTEGER FrameDuplicateCount;
341 LARGE_INTEGER ReceivedFragmentCount;
342 LARGE_INTEGER MulticastReceivedFrameCount;
343 LARGE_INTEGER FCSErrorCount;
344 LARGE_INTEGER TKIPLocalMICFailures;
345 LARGE_INTEGER TKIPRemoteMICErrors;
346 LARGE_INTEGER TKIPICVErrors;
347 LARGE_INTEGER TKIPCounterMeasuresInvoked;
348 LARGE_INTEGER TKIPReplays;
349 LARGE_INTEGER CCMPFormatErrors;
350 LARGE_INTEGER CCMPReplays;
351 LARGE_INTEGER CCMPDecryptErrors;
352 LARGE_INTEGER FourWayHandshakeFailures;
353} NDIS_802_11_STATISTICS, *PNDIS_802_11_STATISTICS;
354
355typedef ULONG NDIS_802_11_KEY_INDEX;
356typedef ULONGLONG NDIS_802_11_KEY_RSC;
357
358#define MAX_RADIUS_SRV_NUM 2 // 802.1x failover number
359
360typedef struct PACKED _RADIUS_SRV_INFO {
361 UINT32 radius_ip;
362 UINT32 radius_port;
363 UCHAR radius_key[64];
364 UCHAR radius_key_len;
365} RADIUS_SRV_INFO, *PRADIUS_SRV_INFO;
366
367typedef struct PACKED _RADIUS_KEY_INFO
368{
369 UCHAR radius_srv_num;
370 RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM];
371 UCHAR ieee8021xWEP; // dynamic WEP
372 UCHAR key_index;
373 UCHAR key_length; // length of key in bytes
374 UCHAR key_material[13];
375} RADIUS_KEY_INFO, *PRADIUS_KEY_INFO;
376
377// It's used by 802.1x daemon to require relative configuration
378typedef struct PACKED _RADIUS_CONF
379{
380 UINT32 Length; // Length of this structure
381 UCHAR mbss_num; // indicate multiple BSS number
382 UINT32 own_ip_addr;
383 UINT32 retry_interval;
384 UINT32 session_timeout_interval;
385 UCHAR EAPifname[IFNAMSIZ];
386 UCHAR EAPifname_len;
387 UCHAR PreAuthifname[IFNAMSIZ];
388 UCHAR PreAuthifname_len;
389 RADIUS_KEY_INFO RadiusInfo[8/*MAX_MBSSID_NUM*/];
390} RADIUS_CONF, *PRADIUS_CONF;
391
392
393
394#ifdef CONFIG_STA_SUPPORT
395// Key mapping keys require a BSSID
396typedef struct _NDIS_802_11_KEY
397{
398 UINT Length; // Length of this structure
399 UINT KeyIndex;
400 UINT KeyLength; // length of key in bytes
401 NDIS_802_11_MAC_ADDRESS BSSID;
402 NDIS_802_11_KEY_RSC KeyRSC;
403 UCHAR KeyMaterial[1]; // variable length depending on above field
404} NDIS_802_11_KEY, *PNDIS_802_11_KEY;
405#endif // CONFIG_STA_SUPPORT //
406
407typedef struct _NDIS_802_11_REMOVE_KEY
408{
409 UINT Length; // Length of this structure
410 UINT KeyIndex;
411 NDIS_802_11_MAC_ADDRESS BSSID;
412} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY;
413
414typedef struct _NDIS_802_11_WEP
415{
416 UINT Length; // Length of this structure
417 UINT KeyIndex; // 0 is the per-client key, 1-N are the
418 // global keys
419 UINT KeyLength; // length of key in bytes
420 UCHAR KeyMaterial[1];// variable length depending on above field
421} NDIS_802_11_WEP, *PNDIS_802_11_WEP;
422
423
424typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE
425{
426 Ndis802_11IBSS,
427 Ndis802_11Infrastructure,
428 Ndis802_11AutoUnknown,
429 Ndis802_11Monitor,
430 Ndis802_11InfrastructureMax // Not a real value, defined as upper bound
431} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE;
432
433// Add new authentication modes
434typedef enum _NDIS_802_11_AUTHENTICATION_MODE
435{
436 Ndis802_11AuthModeOpen,
437 Ndis802_11AuthModeShared,
438 Ndis802_11AuthModeAutoSwitch,
439 Ndis802_11AuthModeWPA,
440 Ndis802_11AuthModeWPAPSK,
441 Ndis802_11AuthModeWPANone,
442 Ndis802_11AuthModeWPA2,
443 Ndis802_11AuthModeWPA2PSK,
444 Ndis802_11AuthModeWPA1WPA2,
445 Ndis802_11AuthModeWPA1PSKWPA2PSK,
446 Ndis802_11AuthModeMax // Not a real mode, defined as upper bound
447} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE;
448
449typedef UCHAR NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; // Set of 8 data rates
450typedef UCHAR NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; // Set of 16 data rates
451
452typedef struct PACKED _NDIS_802_11_SSID
453{
454 UINT SsidLength; // length of SSID field below, in bytes;
455 // this can be zero.
456 UCHAR Ssid[NDIS_802_11_LENGTH_SSID]; // SSID information field
457} NDIS_802_11_SSID, *PNDIS_802_11_SSID;
458
459
460typedef struct PACKED _NDIS_WLAN_BSSID
461{
462 ULONG Length; // Length of this structure
463 NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID
464 UCHAR Reserved[2];
465 NDIS_802_11_SSID Ssid; // SSID
466 ULONG Privacy; // WEP encryption requirement
467 NDIS_802_11_RSSI Rssi; // receive signal strength in dBm
468 NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
469 NDIS_802_11_CONFIGURATION Configuration;
470 NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
471 NDIS_802_11_RATES SupportedRates;
472} NDIS_WLAN_BSSID, *PNDIS_WLAN_BSSID;
473
474typedef struct PACKED _NDIS_802_11_BSSID_LIST
475{
476 UINT NumberOfItems; // in list below, at least 1
477 NDIS_WLAN_BSSID Bssid[1];
478} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST;
479
480// Added Capabilities, IELength and IEs for each BSSID
481typedef struct PACKED _NDIS_WLAN_BSSID_EX
482{
483 ULONG Length; // Length of this structure
484 NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID
485 UCHAR Reserved[2];
486 NDIS_802_11_SSID Ssid; // SSID
487 UINT Privacy; // WEP encryption requirement
488 NDIS_802_11_RSSI Rssi; // receive signal
489 // strength in dBm
490 NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
491 NDIS_802_11_CONFIGURATION Configuration;
492 NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
493 NDIS_802_11_RATES_EX SupportedRates;
494 ULONG IELength;
495 UCHAR IEs[1];
496} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX;
497
498typedef struct PACKED _NDIS_802_11_BSSID_LIST_EX
499{
500 UINT NumberOfItems; // in list below, at least 1
501 NDIS_WLAN_BSSID_EX Bssid[1];
502} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX;
503
504typedef struct PACKED _NDIS_802_11_FIXED_IEs
505{
506 UCHAR Timestamp[8];
507 USHORT BeaconInterval;
508 USHORT Capabilities;
509} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs;
510
511typedef struct _NDIS_802_11_VARIABLE_IEs
512{
513 UCHAR ElementID;
514 UCHAR Length; // Number of bytes in data field
515 UCHAR data[1];
516} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs;
517
518typedef ULONG NDIS_802_11_FRAGMENTATION_THRESHOLD;
519
520typedef ULONG NDIS_802_11_RTS_THRESHOLD;
521
522typedef ULONG NDIS_802_11_ANTENNA;
523
524typedef enum _NDIS_802_11_PRIVACY_FILTER
525{
526 Ndis802_11PrivFilterAcceptAll,
527 Ndis802_11PrivFilter8021xWEP
528} NDIS_802_11_PRIVACY_FILTER, *PNDIS_802_11_PRIVACY_FILTER;
529
530// Added new encryption types
531// Also aliased typedef to new name
532typedef enum _NDIS_802_11_WEP_STATUS
533{
534 Ndis802_11WEPEnabled,
535 Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
536 Ndis802_11WEPDisabled,
537 Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
538 Ndis802_11WEPKeyAbsent,
539 Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
540 Ndis802_11WEPNotSupported,
541 Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
542 Ndis802_11Encryption2Enabled,
543 Ndis802_11Encryption2KeyAbsent,
544 Ndis802_11Encryption3Enabled,
545 Ndis802_11Encryption3KeyAbsent,
546 Ndis802_11Encryption4Enabled, // TKIP or AES mix
547 Ndis802_11Encryption4KeyAbsent,
548 Ndis802_11GroupWEP40Enabled,
549 Ndis802_11GroupWEP104Enabled,
550} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
551 NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
552
553typedef enum _NDIS_802_11_RELOAD_DEFAULTS
554{
555 Ndis802_11ReloadWEPKeys
556} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS;
557
558#define NDIS_802_11_AI_REQFI_CAPABILITIES 1
559#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2
560#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4
561
562#define NDIS_802_11_AI_RESFI_CAPABILITIES 1
563#define NDIS_802_11_AI_RESFI_STATUSCODE 2
564#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4
565
566typedef struct _NDIS_802_11_AI_REQFI
567{
568 USHORT Capabilities;
569 USHORT ListenInterval;
570 NDIS_802_11_MAC_ADDRESS CurrentAPAddress;
571} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
572
573typedef struct _NDIS_802_11_AI_RESFI
574{
575 USHORT Capabilities;
576 USHORT StatusCode;
577 USHORT AssociationId;
578} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
579
580typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
581{
582 ULONG Length;
583 USHORT AvailableRequestFixedIEs;
584 NDIS_802_11_AI_REQFI RequestFixedIEs;
585 ULONG RequestIELength;
586 ULONG OffsetRequestIEs;
587 USHORT AvailableResponseFixedIEs;
588 NDIS_802_11_AI_RESFI ResponseFixedIEs;
589 ULONG ResponseIELength;
590 ULONG OffsetResponseIEs;
591} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
592
593typedef struct _NDIS_802_11_AUTHENTICATION_EVENT
594{
595 NDIS_802_11_STATUS_INDICATION Status;
596 NDIS_802_11_AUTHENTICATION_REQUEST Request[1];
597} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT;
598
599/*
600typedef struct _NDIS_802_11_TEST
601{
602 ULONG Length;
603 ULONG Type;
604 union
605 {
606 NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent;
607 NDIS_802_11_RSSI RssiTrigger;
608 };
609} NDIS_802_11_TEST, *PNDIS_802_11_TEST;
610 */
611
612// 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE
613typedef enum _NDIS_802_11_MEDIA_STREAM_MODE
614{
615 Ndis802_11MediaStreamOff,
616 Ndis802_11MediaStreamOn,
617} NDIS_802_11_MEDIA_STREAM_MODE, *PNDIS_802_11_MEDIA_STREAM_MODE;
618
619// PMKID Structures
620typedef UCHAR NDIS_802_11_PMKID_VALUE[16];
621
622#ifdef CONFIG_STA_SUPPORT
623typedef struct _BSSID_INFO
624{
625 NDIS_802_11_MAC_ADDRESS BSSID;
626 NDIS_802_11_PMKID_VALUE PMKID;
627} BSSID_INFO, *PBSSID_INFO;
628
629typedef struct _NDIS_802_11_PMKID
630{
631 UINT Length;
632 UINT BSSIDInfoCount;
633 BSSID_INFO BSSIDInfo[1];
634} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID;
635#endif // CONFIG_STA_SUPPORT //
636
637
638typedef struct _NDIS_802_11_AUTHENTICATION_ENCRYPTION
639{
640 NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported;
641 NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported;
642} NDIS_802_11_AUTHENTICATION_ENCRYPTION, *PNDIS_802_11_AUTHENTICATION_ENCRYPTION;
643
644typedef struct _NDIS_802_11_CAPABILITY
645{
646 ULONG Length;
647 ULONG Version;
648 ULONG NoOfPMKIDs;
649 ULONG NoOfAuthEncryptPairsSupported;
650 NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1];
651} NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY;
652
653//#endif //of WIN 2k
654#endif //UNDER_CE
655
656#if WIRELESS_EXT <= 11
657#ifndef SIOCDEVPRIVATE
658#define SIOCDEVPRIVATE 0x8BE0
659#endif
660#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
661#endif
662
663#ifdef CONFIG_STA_SUPPORT
664#define RTPRIV_IOCTL_SET (SIOCIWFIRSTPRIV + 0x02)
665
666#ifdef DBG
667#define RTPRIV_IOCTL_BBP (SIOCIWFIRSTPRIV + 0x03)
668#define RTPRIV_IOCTL_MAC (SIOCIWFIRSTPRIV + 0x05)
669#define RTPRIV_IOCTL_E2P (SIOCIWFIRSTPRIV + 0x07)
670#endif
671
672#ifdef RALINK_ATE
673#ifdef RALINK_28xx_QA
674#define RTPRIV_IOCTL_ATE (SIOCIWFIRSTPRIV + 0x08)
675#endif // RALINK_28xx_QA //
676#endif // RALINK_ATE //
677
678#define RTPRIV_IOCTL_STATISTICS (SIOCIWFIRSTPRIV + 0x09)
679#define RTPRIV_IOCTL_ADD_PMKID_CACHE (SIOCIWFIRSTPRIV + 0x0A)
680#define RTPRIV_IOCTL_RADIUS_DATA (SIOCIWFIRSTPRIV + 0x0C)
681#define RTPRIV_IOCTL_GSITESURVEY (SIOCIWFIRSTPRIV + 0x0D)
682#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x0E) // Sync. with RT61 (for wpa_supplicant)
683#define RTPRIV_IOCTL_GET_MAC_TABLE (SIOCIWFIRSTPRIV + 0x0F)
684
685#define RTPRIV_IOCTL_SHOW (SIOCIWFIRSTPRIV + 0x11)
686enum {
687 SHOW_CONN_STATUS = 4,
688 SHOW_DRVIER_VERION = 5,
689 SHOW_BA_INFO = 6,
690 SHOW_DESC_INFO = 7,
691#ifdef RT2870
692 SHOW_RXBULK_INFO = 8,
693 SHOW_TXBULK_INFO = 9,
694#endif // RT2870 //
695 RAIO_OFF = 10,
696 RAIO_ON = 11,
697#ifdef QOS_DLS_SUPPORT
698 SHOW_DLS_ENTRY_INFO = 19,
699#endif // QOS_DLS_SUPPORT //
700 SHOW_CFG_VALUE = 20,
701 SHOW_ADHOC_ENTRY_INFO = 21,
702};
703
704
705#endif // CONFIG_STA_SUPPORT //
706
707#ifdef SNMP_SUPPORT
708//SNMP ieee 802dot11, kathy , 2008_0220
709// dot11res(3)
710#define RT_OID_802_11_MANUFACTUREROUI 0x0700
711#define RT_OID_802_11_MANUFACTURERNAME 0x0701
712#define RT_OID_802_11_RESOURCETYPEIDNAME 0x0702
713
714// dot11smt(1)
715#define RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED 0x0703
716#define RT_OID_802_11_POWERMANAGEMENTMODE 0x0704
717#define OID_802_11_WEPDEFAULTKEYVALUE 0x0705 // read , write
718#define OID_802_11_WEPDEFAULTKEYID 0x0706
719#define RT_OID_802_11_WEPKEYMAPPINGLENGTH 0x0707
720#define OID_802_11_SHORTRETRYLIMIT 0x0708
721#define OID_802_11_LONGRETRYLIMIT 0x0709
722#define RT_OID_802_11_PRODUCTID 0x0710
723#define RT_OID_802_11_MANUFACTUREID 0x0711
724
725// //dot11Phy(4)
726#define OID_802_11_CURRENTCHANNEL 0x0712
727
728//dot11mac
729#define RT_OID_802_11_MAC_ADDRESS 0x0713
730#endif // SNMP_SUPPORT //
731
732#define OID_802_11_BUILD_CHANNEL_EX 0x0714
733#define OID_802_11_GET_CH_LIST 0x0715
734#define OID_802_11_GET_COUNTRY_CODE 0x0716
735#define OID_802_11_GET_CHANNEL_GEOGRAPHY 0x0717
736
737#ifdef LLTD_SUPPORT
738// for consistency with RT61
739#define RT_OID_GET_PHY_MODE 0x761
740#endif // LLTD_SUPPORT //
741
742// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!!
743typedef union _HTTRANSMIT_SETTING {
744#ifdef RT_BIG_ENDIAN
745 struct {
746 USHORT MODE:2; // Use definition MODE_xxx.
747// USHORT rsv:3;
748 USHORT TxBF:1;
749 USHORT rsv:2;
750 USHORT STBC:2; //SPACE
751 USHORT ShortGI:1;
752 USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
753 USHORT MCS:7; // MCS
754 } field;
755#else
756 struct {
757 USHORT MCS:7; // MCS
758 USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
759 USHORT ShortGI:1;
760 USHORT STBC:2; //SPACE
761// USHORT rsv:3;
762 USHORT rsv:2;
763 USHORT TxBF:1;
764 USHORT MODE:2; // Use definition MODE_xxx.
765 } field;
766#endif
767 USHORT word;
768 } HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING;
769
770typedef enum _RT_802_11_PREAMBLE {
771 Rt802_11PreambleLong,
772 Rt802_11PreambleShort,
773 Rt802_11PreambleAuto
774} RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE;
775
776// Only for STA, need to sync with AP
777typedef enum _RT_802_11_PHY_MODE {
778 PHY_11BG_MIXED = 0,
779 PHY_11B,
780 PHY_11A,
781 PHY_11ABG_MIXED,
782 PHY_11G,
783#ifdef DOT11_N_SUPPORT
784 PHY_11ABGN_MIXED, // both band 5
785 PHY_11N_2_4G, // 11n-only with 2.4G band 6
786 PHY_11GN_MIXED, // 2.4G band 7
787 PHY_11AN_MIXED, // 5G band 8
788 PHY_11BGN_MIXED, // if check 802.11b. 9
789 PHY_11AGN_MIXED, // if check 802.11b. 10
790 PHY_11N_5G, // 11n-only with 5G band 11
791#endif // DOT11_N_SUPPORT //
792} RT_802_11_PHY_MODE;
793
794// put all proprietery for-query objects here to reduce # of Query_OID
795typedef struct _RT_802_11_LINK_STATUS {
796 ULONG CurrTxRate; // in units of 0.5Mbps
797 ULONG ChannelQuality; // 0..100 %
798 ULONG TxByteCount; // both ok and fail
799 ULONG RxByteCount; // both ok and fail
800 ULONG CentralChannel; // 40MHz central channel number
801} RT_802_11_LINK_STATUS, *PRT_802_11_LINK_STATUS;
802
803typedef struct _RT_802_11_EVENT_LOG {
804 LARGE_INTEGER SystemTime; // timestammp via NdisGetCurrentSystemTime()
805 UCHAR Addr[MAC_ADDR_LENGTH];
806 USHORT Event; // EVENT_xxx
807} RT_802_11_EVENT_LOG, *PRT_802_11_EVENT_LOG;
808
809typedef struct _RT_802_11_EVENT_TABLE {
810 ULONG Num;
811 ULONG Rsv; // to align Log[] at LARGE_INEGER boundary
812 RT_802_11_EVENT_LOG Log[MAX_NUMBER_OF_EVENT];
813} RT_802_11_EVENT_TABLE, PRT_802_11_EVENT_TABLE;
814
815// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!!
816typedef union _MACHTTRANSMIT_SETTING {
817 struct {
818 USHORT MCS:7; // MCS
819 USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
820 USHORT ShortGI:1;
821 USHORT STBC:2; //SPACE
822 USHORT rsv:3;
823 USHORT MODE:2; // Use definition MODE_xxx.
824 } field;
825 USHORT word;
826 } MACHTTRANSMIT_SETTING, *PMACHTTRANSMIT_SETTING;
827
828typedef struct _RT_802_11_MAC_ENTRY {
829 UCHAR Addr[MAC_ADDR_LENGTH];
830 UCHAR Aid;
831 UCHAR Psm; // 0:PWR_ACTIVE, 1:PWR_SAVE
832 UCHAR MimoPs; // 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled
833 CHAR AvgRssi0;
834 CHAR AvgRssi1;
835 CHAR AvgRssi2;
836 UINT32 ConnectedTime;
837 MACHTTRANSMIT_SETTING TxRate;
838} RT_802_11_MAC_ENTRY, *PRT_802_11_MAC_ENTRY;
839
840typedef struct _RT_802_11_MAC_TABLE {
841 ULONG Num;
842 RT_802_11_MAC_ENTRY Entry[MAX_NUMBER_OF_MAC];
843} RT_802_11_MAC_TABLE, *PRT_802_11_MAC_TABLE;
844
845// structure for query/set hardware register - MAC, BBP, RF register
846typedef struct _RT_802_11_HARDWARE_REGISTER {
847 ULONG HardwareType; // 0:MAC, 1:BBP, 2:RF register, 3:EEPROM
848 ULONG Offset; // Q/S register offset addr
849 ULONG Data; // R/W data buffer
850} RT_802_11_HARDWARE_REGISTER, *PRT_802_11_HARDWARE_REGISTER;
851
852// structure to tune BBP R17 "RX AGC VGC init"
853//typedef struct _RT_802_11_RX_AGC_VGC_TUNING {
854// UCHAR FalseCcaLowerThreshold; // 0-255, def 10
855// UCHAR FalseCcaUpperThreshold; // 0-255, def 100
856// UCHAR VgcDelta; // R17 +-= VgcDelta whenever flase CCA over UpprThreshold
857// // or lower than LowerThresholdupper threshold
858// UCHAR VgcUpperBound; // max value of R17
859//} RT_802_11_RX_AGC_VGC_TUNING, *PRT_802_11_RX_AGC_VGC_TUNING;
860
861typedef struct _RT_802_11_AP_CONFIG {
862 ULONG EnableTxBurst; // 0-disable, 1-enable
863 ULONG EnableTurboRate; // 0-disable, 1-enable 72/100mbps turbo rate
864 ULONG IsolateInterStaTraffic; // 0-disable, 1-enable isolation
865 ULONG HideSsid; // 0-disable, 1-enable hiding
866 ULONG UseBGProtection; // 0-AUTO, 1-always ON, 2-always OFF
867 ULONG UseShortSlotTime; // 0-no use, 1-use 9-us short slot time
868 ULONG Rsv1; // must be 0
869 ULONG SystemErrorBitmap; // ignore upon SET, return system error upon QUERY
870} RT_802_11_AP_CONFIG, *PRT_802_11_AP_CONFIG;
871
872// structure to query/set STA_CONFIG
873typedef struct _RT_802_11_STA_CONFIG {
874 ULONG EnableTxBurst; // 0-disable, 1-enable
875 ULONG EnableTurboRate; // 0-disable, 1-enable 72/100mbps turbo rate
876 ULONG UseBGProtection; // 0-AUTO, 1-always ON, 2-always OFF
877 ULONG UseShortSlotTime; // 0-no use, 1-use 9-us short slot time when applicable
878 ULONG AdhocMode; // 0-11b rates only (WIFI spec), 1 - b/g mixed, 2 - g only
879 ULONG HwRadioStatus; // 0-OFF, 1-ON, default is 1, Read-Only
880 ULONG Rsv1; // must be 0
881 ULONG SystemErrorBitmap; // ignore upon SET, return system error upon QUERY
882} RT_802_11_STA_CONFIG, *PRT_802_11_STA_CONFIG;
883
884//
885// For OID Query or Set about BA structure
886//
887typedef struct _OID_BACAP_STRUC {
888 UCHAR RxBAWinLimit;
889 UCHAR TxBAWinLimit;
890 UCHAR Policy; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid
891 UCHAR MpduDensity; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid
892 UCHAR AmsduEnable; //Enable AMSDU transmisstion
893 UCHAR AmsduSize; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
894 UCHAR MMPSmode; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
895 BOOLEAN AutoBA; // Auto BA will automatically
896} OID_BACAP_STRUC, *POID_BACAP_STRUC;
897
898typedef struct _RT_802_11_ACL_ENTRY {
899 UCHAR Addr[MAC_ADDR_LENGTH];
900 USHORT Rsv;
901} RT_802_11_ACL_ENTRY, *PRT_802_11_ACL_ENTRY;
902
903typedef struct PACKED _RT_802_11_ACL {
904 ULONG Policy; // 0-disable, 1-positive list, 2-negative list
905 ULONG Num;
906 RT_802_11_ACL_ENTRY Entry[MAX_NUMBER_OF_ACL];
907} RT_802_11_ACL, *PRT_802_11_ACL;
908
909typedef struct _RT_802_11_WDS {
910 ULONG Num;
911 NDIS_802_11_MAC_ADDRESS Entry[24/*MAX_NUM_OF_WDS_LINK*/];
912 ULONG KeyLength;
913 UCHAR KeyMaterial[32];
914} RT_802_11_WDS, *PRT_802_11_WDS;
915
916typedef struct _RT_802_11_TX_RATES_ {
917 UCHAR SupRateLen;
918 UCHAR SupRate[MAX_LENGTH_OF_SUPPORT_RATES];
919 UCHAR ExtRateLen;
920 UCHAR ExtRate[MAX_LENGTH_OF_SUPPORT_RATES];
921} RT_802_11_TX_RATES, *PRT_802_11_TX_RATES;
922
923
924// Definition of extra information code
925#define GENERAL_LINK_UP 0x0 // Link is Up
926#define GENERAL_LINK_DOWN 0x1 // Link is Down
927#define HW_RADIO_OFF 0x2 // Hardware radio off
928#define SW_RADIO_OFF 0x3 // Software radio off
929#define AUTH_FAIL 0x4 // Open authentication fail
930#define AUTH_FAIL_KEYS 0x5 // Shared authentication fail
931#define ASSOC_FAIL 0x6 // Association failed
932#define EAP_MIC_FAILURE 0x7 // Deauthencation because MIC failure
933#define EAP_4WAY_TIMEOUT 0x8 // Deauthencation on 4-way handshake timeout
934#define EAP_GROUP_KEY_TIMEOUT 0x9 // Deauthencation on group key handshake timeout
935#define EAP_SUCCESS 0xa // EAP succeed
936#define DETECT_RADAR_SIGNAL 0xb // Radar signal occur in current channel
937#define EXTRA_INFO_MAX 0xb // Indicate Last OID
938
939#define EXTRA_INFO_CLEAR 0xffffffff
940
941// This is OID setting structure. So only GF or MM as Mode. This is valid when our wirelss mode has 802.11n in use.
942typedef struct {
943 RT_802_11_PHY_MODE PhyMode; //
944 UCHAR TransmitNo;
945 UCHAR HtMode; //HTMODE_GF or HTMODE_MM
946 UCHAR ExtOffset; //extension channel above or below
947 UCHAR MCS;
948 UCHAR BW;
949 UCHAR STBC;
950 UCHAR SHORTGI;
951 UCHAR rsv;
952} OID_SET_HT_PHYMODE, *POID_SET_HT_PHYMODE;
953
954#ifdef NINTENDO_AP
955#define NINTENDO_MAX_ENTRY 16
956#define NINTENDO_SSID_NAME_LN 8
957#define NINTENDO_SSID_NAME "NWCUSBAP"
958#define NINTENDO_PROBE_REQ_FLAG_MASK 0x03
959#define NINTENDO_PROBE_REQ_ON 0x01
960#define NINTENDO_PROBE_REQ_SIGNAL 0x02
961#define NINTENDO_PROBE_RSP_ON 0x01
962#define NINTENDO_SSID_NICKNAME_LN 20
963
964#define NINTENDO_WEPKEY_LN 13
965
966typedef struct _NINTENDO_SSID
967{
968 UCHAR NINTENDOFixChar[NINTENDO_SSID_NAME_LN];
969 UCHAR zero1;
970 UCHAR registe;
971 UCHAR ID;
972 UCHAR zero2;
973 UCHAR NICKname[NINTENDO_SSID_NICKNAME_LN];
974} RT_NINTENDO_SSID, *PRT_NINTENDO_SSID;
975
976typedef struct _NINTENDO_ENTRY
977{
978 UCHAR NICKname[NINTENDO_SSID_NICKNAME_LN];
979 UCHAR DS_Addr[ETH_LENGTH_OF_ADDRESS];
980 UCHAR registe;
981 UCHAR UserSpaceAck;
982} RT_NINTENDO_ENTRY, *PRT_NINTENDO_ENTRY;
983
984//RTPRIV_IOCTL_NINTENDO_GET_TABLE
985//RTPRIV_IOCTL_NINTENDO_SET_TABLE
986typedef struct _NINTENDO_TABLE
987{
988 UINT number;
989 RT_NINTENDO_ENTRY entry[NINTENDO_MAX_ENTRY];
990} RT_NINTENDO_TABLE, *PRT_NINTENDO_TABLE;
991
992//RTPRIV_IOCTL_NINTENDO_SEED_WEPKEY
993typedef struct _NINTENDO_SEED_WEPKEY
994{
995 UCHAR seed[NINTENDO_SSID_NICKNAME_LN];
996 UCHAR wepkey[16];//use 13 for 104 bits wep key
997} RT_NINTENDO_SEED_WEPKEY, *PRT_NINTENDO_SEED_WEPKEY;
998#endif // NINTENDO_AP //
999
1000#ifdef LLTD_SUPPORT
1001typedef struct _RT_LLTD_ASSOICATION_ENTRY {
1002 UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
1003 unsigned short MOR; // maximum operational rate
1004 UCHAR phyMode;
1005} RT_LLTD_ASSOICATION_ENTRY, *PRT_LLTD_ASSOICATION_ENTRY;
1006
1007typedef struct _RT_LLTD_ASSOICATION_TABLE {
1008 unsigned int Num;
1009 RT_LLTD_ASSOICATION_ENTRY Entry[MAX_NUMBER_OF_MAC];
1010} RT_LLTD_ASSOICATION_TABLE, *PRT_LLTD_ASSOICATION_TABLE;
1011#endif // LLTD_SUPPORT //
1012
1013#ifdef CONFIG_STA_SUPPORT
1014#ifdef QOS_DLS_SUPPORT
1015//rt2860, kathy 2007-0118
1016// structure for DLS
1017typedef struct _RT_802_11_DLS_UI {
1018 USHORT TimeOut; // unit: second , set by UI
1019 USHORT CountDownTimer; // unit: second , used by driver only
1020 NDIS_802_11_MAC_ADDRESS MacAddr; // set by UI
1021 UCHAR Status; // 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
1022 BOOLEAN Valid; // 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
1023} RT_802_11_DLS_UI, *PRT_802_11_DLS_UI;
1024
1025typedef struct _RT_802_11_DLS_INFO {
1026 RT_802_11_DLS_UI Entry[MAX_NUMBER_OF_DLS_ENTRY];
1027 UCHAR num;
1028} RT_802_11_DLS_INFO, *PRT_802_11_DLS_INFO;
1029
1030typedef enum _RT_802_11_DLS_MODE {
1031 DLS_NONE,
1032 DLS_WAIT_KEY,
1033 DLS_FINISH
1034} RT_802_11_DLS_MODE;
1035#endif // QOS_DLS_SUPPORT //
1036
1037#ifdef WPA_SUPPLICANT_SUPPORT
1038#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1039#define RT_ASSOC_EVENT_FLAG 0x0101
1040#define RT_DISASSOC_EVENT_FLAG 0x0102
1041#define RT_REQIE_EVENT_FLAG 0x0103
1042#define RT_RESPIE_EVENT_FLAG 0x0104
1043#define RT_ASSOCINFO_EVENT_FLAG 0x0105
1044#define RT_PMKIDCAND_FLAG 0x0106
1045#define RT_INTERFACE_DOWN 0x0107
1046#define RT_INTERFACE_UP 0x0108
1047#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1048#endif // WPA_SUPPLICANT_SUPPORT //
1049#endif // CONFIG_STA_SUPPORT //
1050
1051
1052#define MAX_CUSTOM_LEN 128
1053
1054#ifdef CONFIG_STA_SUPPORT
1055typedef enum _RT_802_11_D_CLIENT_MODE
1056{
1057 Rt802_11_D_None,
1058 Rt802_11_D_Flexible,
1059 Rt802_11_D_Strict,
1060} RT_802_11_D_CLIENT_MODE, *PRT_802_11_D_CLIENT_MODE;
1061#endif // CONFIG_STA_SUPPORT //
1062
1063typedef struct _RT_CHANNEL_LIST_INFO
1064{
1065 UCHAR ChannelList[MAX_NUM_OF_CHS]; // list all supported channels for site survey
1066 UCHAR ChannelListNum; // number of channel in ChannelList[]
1067} RT_CHANNEL_LIST_INFO, *PRT_CHANNEL_LIST_INFO;
1068
1069// WSC configured credential
1070typedef struct _WSC_CREDENTIAL
1071{
1072 NDIS_802_11_SSID SSID; // mandatory
1073 USHORT AuthType; // mandatory, 1: open, 2: wpa-psk, 4: shared, 8:wpa, 0x10: wpa2, 0x20: wpa2-psk
1074 USHORT EncrType; // mandatory, 1: none, 2: wep, 4: tkip, 8: aes
1075 UCHAR Key[64]; // mandatory, Maximum 64 byte
1076 USHORT KeyLength;
1077 UCHAR MacAddr[6]; // mandatory, AP MAC address
1078 UCHAR KeyIndex; // optional, default is 1
1079 UCHAR Rsvd[3]; // Make alignment
1080} WSC_CREDENTIAL, *PWSC_CREDENTIAL;
1081
1082// WSC configured profiles
1083typedef struct _WSC_PROFILE
1084{
1085 UINT ProfileCnt;
1086 WSC_CREDENTIAL Profile[8]; // Support up to 8 profiles
1087} WSC_PROFILE, *PWSC_PROFILE;
1088
1089
1090#endif // _OID_H_
1091
diff --git a/drivers/staging/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h
new file mode 100644
index 00000000000..30af4b57c3d
--- /dev/null
+++ b/drivers/staging/rt2870/rt2870.h
@@ -0,0 +1,761 @@
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 RETRY_LIMIT 10
60#define BUFFER_SIZE 2400 //2048
61#define TX_RING 0xa
62#define PRIO_RING 0xc
63
64
65// Flags for Bulkflags control for bulk out data
66//
67#define fRTUSB_BULK_OUT_DATA_NULL 0x00000001
68#define fRTUSB_BULK_OUT_RTS 0x00000002
69#define fRTUSB_BULK_OUT_MLME 0x00000004
70
71#define fRTUSB_BULK_OUT_DATA_NORMAL 0x00010000
72#define fRTUSB_BULK_OUT_DATA_NORMAL_2 0x00020000
73#define fRTUSB_BULK_OUT_DATA_NORMAL_3 0x00040000
74#define fRTUSB_BULK_OUT_DATA_NORMAL_4 0x00080000
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 */ \
91 {USB_DEVICE(0x0B05,0x1731)}, /* Asus */ \
92 {USB_DEVICE(0x0B05,0x1732)}, /* Asus */ \
93 {USB_DEVICE(0x0B05,0x1742)}, /* Asus */ \
94 {USB_DEVICE(0x0DF6,0x0017)}, /* Sitecom */ \
95 {USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */ \
96 {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ \
97 {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ \
98 {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ \
99 {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ \
100 {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ \
101 {USB_DEVICE(0x2019,0xAB25)}, /* Planex Communications, Inc. RT3070 */ \
102 {USB_DEVICE(0x07D1,0x3C09)}, /* D-Link */ \
103 {USB_DEVICE(0x07D1,0x3C11)}, /* D-Link */ \
104 {USB_DEVICE(0x14B2,0x3C07)}, /* AL */ \
105 {USB_DEVICE(0x14B2,0x3C12)}, /* AL */ \
106 {USB_DEVICE(0x050D,0x8053)}, /* Belkin */ \
107 {USB_DEVICE(0x14B2,0x3C23)}, /* Airlink */ \
108 {USB_DEVICE(0x14B2,0x3C27)}, /* Airlink */ \
109 {USB_DEVICE(0x07AA,0x002F)}, /* Corega */ \
110 {USB_DEVICE(0x07AA,0x003C)}, /* Corega */ \
111 {USB_DEVICE(0x07AA,0x003F)}, /* Corega */ \
112 {USB_DEVICE(0x18C5,0x0012)}, /* Corega */ \
113 {USB_DEVICE(0x1044,0x800B)}, /* Gigabyte */ \
114 {USB_DEVICE(0x15A9,0x0006)}, /* Sparklan */ \
115 {USB_DEVICE(0x083A,0xB522)}, /* SMC */ \
116 {USB_DEVICE(0x083A,0xA618)}, /* SMC */ \
117 {USB_DEVICE(0x083A,0x7522)}, /* Arcadyan */ \
118 {USB_DEVICE(0x0CDE,0x0022)}, /* ZCOM */ \
119 {USB_DEVICE(0x0586,0x3416)}, /* Zyxel */ \
120 {USB_DEVICE(0x0CDE,0x0025)}, /* Zyxel */ \
121 {USB_DEVICE(0x1740,0x9701)}, /* EnGenius */ \
122 {USB_DEVICE(0x1740,0x9702)}, /* EnGenius */ \
123 {USB_DEVICE(0x0471,0x200f)}, /* Philips */ \
124 {USB_DEVICE(0x14B2,0x3C25)}, /* Draytek */ \
125 {USB_DEVICE(0x13D3,0x3247)}, /* AzureWave */ \
126 {USB_DEVICE(0x083A,0x6618)}, /* Accton */ \
127 {USB_DEVICE(0x15c5,0x0008)}, /* Amit */ \
128 {USB_DEVICE(0x0E66,0x0001)}, /* Hawking */ \
129 {USB_DEVICE(0x0E66,0x0003)}, /* Hawking */ \
130 {USB_DEVICE(0x129B,0x1828)}, /* Siemens */ \
131 {USB_DEVICE(0x157E,0x300E)}, /* U-Media */ \
132 {USB_DEVICE(0x050d,0x805c)}, \
133 {USB_DEVICE(0x1482,0x3C09)}, /* Abocom*/ \
134 {USB_DEVICE(0x14B2,0x3C09)}, /* Alpha */ \
135 {USB_DEVICE(0x04E8,0x2018)}, /* samsung */ \
136 {USB_DEVICE(0x07B8,0x3070)}, /* AboCom */ \
137 {USB_DEVICE(0x07B8,0x3071)}, /* AboCom */ \
138 {USB_DEVICE(0x07B8,0x2870)}, /* AboCom */ \
139 {USB_DEVICE(0x07B8,0x2770)}, /* AboCom */ \
140 {USB_DEVICE(0x7392,0x7711)}, /* Edimax */ \
141 {USB_DEVICE(0x5A57,0x0280)}, /* Zinwell */ \
142 {USB_DEVICE(0x5A57,0x0282)}, /* Zinwell */ \
143 {USB_DEVICE(0x0789,0x0162)}, /* Logitec */ \
144 {USB_DEVICE(0x0789,0x0163)}, /* Logitec */ \
145 {USB_DEVICE(0x0789,0x0164)}, /* Logitec */ \
146 { }/* Terminating entry */ \
147}
148
149#define FREE_HTTX_RING(_p, _b, _t) \
150{ \
151 if ((_t)->ENextBulkOutPosition == (_t)->CurWritePosition) \
152 { \
153 (_t)->bRingEmpty = TRUE; \
154 } \
155 /*NdisInterlockedDecrement(&(_p)->TxCount); */\
156}
157
158//
159// RXINFO appends at the end of each rx packet.
160//
161#ifdef RT_BIG_ENDIAN
162typedef struct PACKED _RXINFO_STRUC {
163 UINT32 PlcpSignal:12;
164 UINT32 LastAMSDU:1;
165 UINT32 CipherAlg:1;
166 UINT32 PlcpRssil:1;
167 UINT32 Decrypted:1;
168 UINT32 AMPDU:1; // To be moved
169 UINT32 L2PAD:1;
170 UINT32 RSSI:1;
171 UINT32 HTC:1;
172 UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header.
173 UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
174 UINT32 Crc:1; // 1: CRC error
175 UINT32 MyBss:1; // 1: this frame belongs to the same BSSID
176 UINT32 Bcast:1; // 1: this is a broadcast frame
177 UINT32 Mcast:1; // 1: this is a multicast frame
178 UINT32 U2M:1; // 1: this RX frame is unicast to me
179 UINT32 FRAG:1;
180 UINT32 NULLDATA:1;
181 UINT32 DATA:1;
182 UINT32 BA:1;
183} RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
184#else
185typedef struct PACKED _RXINFO_STRUC {
186 UINT32 BA:1;
187 UINT32 DATA:1;
188 UINT32 NULLDATA:1;
189 UINT32 FRAG:1;
190 UINT32 U2M:1; // 1: this RX frame is unicast to me
191 UINT32 Mcast:1; // 1: this is a multicast frame
192 UINT32 Bcast:1; // 1: this is a broadcast frame
193 UINT32 MyBss:1; // 1: this frame belongs to the same BSSID
194 UINT32 Crc:1; // 1: CRC error
195 UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
196 UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header.
197 UINT32 HTC:1;
198 UINT32 RSSI:1;
199 UINT32 L2PAD:1;
200 UINT32 AMPDU:1; // To be moved
201 UINT32 Decrypted:1;
202 UINT32 PlcpRssil:1;
203 UINT32 CipherAlg:1;
204 UINT32 LastAMSDU:1;
205 UINT32 PlcpSignal:12;
206} RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
207#endif
208
209
210//
211// TXINFO
212//
213#ifdef RT_BIG_ENDIAN
214typedef struct _TXINFO_STRUC {
215 // Word 0
216 UINT32 USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint
217 UINT32 USBDMANextVLD:1; //used ONLY in USB bulk Aggregation, NextValid
218 UINT32 rsv2:2; // Software use.
219 UINT32 SwUseLastRound:1; // Software use.
220 UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
221 UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
222 UINT32 rsv:8;
223 UINT32 USBDMATxPktLen:16; //used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame.
224} TXINFO_STRUC, *PTXINFO_STRUC;
225#else
226typedef struct _TXINFO_STRUC {
227 // Word 0
228 UINT32 USBDMATxPktLen:16; //used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame.
229 UINT32 rsv:8;
230 UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
231 UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
232 UINT32 SwUseLastRound:1; // Software use.
233 UINT32 rsv2:2; // Software use.
234 UINT32 USBDMANextVLD:1; //used ONLY in USB bulk Aggregation, NextValid
235 UINT32 USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint
236} TXINFO_STRUC, *PTXINFO_STRUC;
237#endif
238
239#define TXINFO_SIZE 4
240#define RXINFO_SIZE 4
241#define TXPADDING_SIZE 11
242
243//
244// Management ring buffer format
245//
246typedef struct _MGMT_STRUC {
247 BOOLEAN Valid;
248 PUCHAR pBuffer;
249 ULONG Length;
250} MGMT_STRUC, *PMGMT_STRUC;
251
252
253/* ----------------- EEPROM Related MACRO ----------------- */
254#define RT28xx_EEPROM_READ16(pAd, offset, var) \
255 do { \
256 RTUSBReadEEPROM(pAd, offset, (PUCHAR)&(var), 2); \
257 var = le2cpu16(var); \
258 }while(0)
259
260#define RT28xx_EEPROM_WRITE16(pAd, offset, var) \
261 do{ \
262 USHORT _tmpVar; \
263 _tmpVar = cpu2le16(var); \
264 RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(_tmpVar), 2); \
265 }while(0)
266
267/* ----------------- TASK/THREAD Related MACRO ----------------- */
268#define RT28XX_TASK_THREAD_INIT(pAd, Status) \
269 Status = CreateThreads(net_dev);
270
271
272/* ----------------- Frimware Related MACRO ----------------- */
273#if 0
274#define RT28XX_FIRMUD_INIT(pAd) \
275 { UINT32 MacReg; \
276 RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg); }
277
278#define RT28XX_FIRMUD_END(pAd) \
279 RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff); \
280 RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff); \
281 RTUSBFirmwareRun(pAd);
282#else
283#define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \
284 RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen)
285#endif
286
287/* ----------------- TX Related MACRO ----------------- */
288#define RT28XX_START_DEQUEUE(pAd, QueIdx, irqFlags) \
289 { \
290 RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
291 if (pAd->DeQueueRunning[QueIdx]) \
292 { \
293 RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
294 printk("DeQueueRunning[%d]= TRUE!\n", QueIdx); \
295 continue; \
296 } \
297 else \
298 { \
299 pAd->DeQueueRunning[QueIdx] = TRUE; \
300 RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
301 } \
302 }
303#define RT28XX_STOP_DEQUEUE(pAd, QueIdx, irqFlags) \
304 do{ \
305 RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
306 pAd->DeQueueRunning[QueIdx] = FALSE; \
307 RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
308 }while(0)
309
310
311#define RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
312 (RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS)
313
314#define RT28XX_RELEASE_DESC_RESOURCE(pAd, QueIdx) \
315 do{}while(0)
316
317#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType) \
318 ((_TxFrameType == TX_RALINK_FRAME) && (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx)))
319
320
321
322#define fRTMP_ADAPTER_NEED_STOP_TX \
323 (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
324 fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \
325 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
326
327
328#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \
329 RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
330
331#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \
332 RtmpUSB_WriteSingleTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)
333
334#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
335 RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
336
337#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \
338 RtmpUSB_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)
339
340#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) \
341 RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)
342
343#define HAL_LastTxIdx(pAd, QueIdx,TxIdx) \
344 /*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx)*/
345
346#define HAL_KickOutTx(pAd, pTxBlk, QueIdx) \
347 RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx)
348
349
350#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) \
351 RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)
352
353#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \
354 RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen)
355
356#define RTMP_PKT_TAIL_PADDING 11 // 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding)
357
358extern UCHAR EpToQueue[6];
359
360
361#ifdef RT2870
362#define GET_TXRING_FREENO(_pAd, _QueIdx) (_QueIdx) //(_pAd->TxRing[_QueIdx].TxSwFreeIdx)
363#define GET_MGMTRING_FREENO(_pAd) (_pAd->MgmtRing.TxSwFreeIdx)
364#endif // RT2870 //
365
366
367/* ----------------- RX Related MACRO ----------------- */
368//#define RT28XX_RX_ERROR_CHECK RTMPCheckRxWI
369
370#if 0
371#define RT28XX_RCV_INIT(pAd) \
372 pAd->TransferBufferLength = 0; \
373 pAd->ReadPosition = 0; \
374 pAd->pCurrRxContext = NULL;
375#endif
376
377#define RT28XX_RV_ALL_BUF_END(bBulkReceive) \
378 /* We return STATUS_MORE_PROCESSING_REQUIRED so that the completion */ \
379 /* routine (IofCompleteRequest) will stop working on the irp. */ \
380 if (bBulkReceive == TRUE) RTUSBBulkReceive(pAd);
381
382
383/* ----------------- ASIC Related MACRO ----------------- */
384#if 0
385#define RT28XX_DMA_WRITE_INIT(GloCfg) \
386 { GloCfg.field.EnTXWriteBackDDONE = 1; \
387 GloCfg.field.EnableRxDMA = 1; \
388 GloCfg.field.EnableTxDMA = 1; }
389
390#define RT28XX_DMA_POST_WRITE(_pAd) \
391 do{ USB_DMA_CFG_STRUC UsbCfg; \
392 UsbCfg.word = 0; \
393 /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */ \
394 UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3; \
395 UsbCfg.field.phyclear = 0; \
396 /* usb version is 1.1,do not use bulk in aggregation */ \
397 if (_pAd->BulkInMaxPacketSize == 512) \
398 UsbCfg.field.RxBulkAggEn = 1; \
399 UsbCfg.field.RxBulkEn = 1; \
400 UsbCfg.field.TxBulkEn = 1; \
401 UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */ \
402 RTUSBWriteMACRegister(_pAd, USB_DMA_CFG, UsbCfg.word); \
403 }while(0)
404#endif
405
406// reset MAC of a station entry to 0xFFFFFFFFFFFF
407#define RT28XX_STA_ENTRY_MAC_RESET(pAd, Wcid) \
408 { RT_SET_ASIC_WCID SetAsicWcid; \
409 SetAsicWcid.WCID = Wcid; \
410 SetAsicWcid.SetTid = 0xffffffff; \
411 SetAsicWcid.DeleteTid = 0xffffffff; \
412 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID, \
413 &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); }
414
415// add this entry into ASIC RX WCID search table
416#define RT28XX_STA_ENTRY_ADD(pAd, pEntry) \
417 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY, \
418 pEntry, sizeof(MAC_TABLE_ENTRY));
419
420// remove Pair-wise key material from ASIC
421// yet implement
422#define RT28XX_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)
423
424// add Client security information into ASIC WCID table and IVEIV table
425#define RT28XX_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry) \
426 { RT28XX_STA_ENTRY_MAC_RESET(pAd, pEntry->Aid); \
427 if (pEntry->Aid >= 1) { \
428 RT_SET_ASIC_WCID_ATTRI SetAsicWcidAttri; \
429 SetAsicWcidAttri.WCID = pEntry->Aid; \
430 if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && \
431 (pEntry->WepStatus == Ndis802_11Encryption1Enabled)) \
432 { \
433 SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \
434 } \
435 else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone) \
436 { \
437 SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \
438 } \
439 else SetAsicWcidAttri.Cipher = 0; \
440 DBGPRINT(RT_DEBUG_TRACE, ("aid cipher = %ld\n",SetAsicWcidAttri.Cipher)); \
441 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID_CIPHER, \
442 &SetAsicWcidAttri, sizeof(RT_SET_ASIC_WCID_ATTRI)); } }
443
444// Insert the BA bitmap to ASIC for the Wcid entry
445#define RT28XX_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \
446 do{ \
447 RT_SET_ASIC_WCID SetAsicWcid; \
448 SetAsicWcid.WCID = (_Aid); \
449 SetAsicWcid.SetTid = (0x10000<<(_TID)); \
450 SetAsicWcid.DeleteTid = 0xffffffff; \
451 RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \
452 }while(0)
453
454// Remove the BA bitmap from ASIC for the Wcid entry
455#define RT28XX_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \
456 do{ \
457 RT_SET_ASIC_WCID SetAsicWcid; \
458 SetAsicWcid.WCID = (_Wcid); \
459 SetAsicWcid.SetTid = (0xffffffff); \
460 SetAsicWcid.DeleteTid = (0x10000<<(_TID) ); \
461 RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \
462 }while(0)
463
464
465/* ----------------- PCI/USB Related MACRO ----------------- */
466#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p) \
467 ((POS_COOKIE)handle)->pUsb_Dev = dev_p;
468
469// no use
470#define RT28XX_UNMAP()
471#define RT28XX_IRQ_REQUEST(net_dev)
472#define RT28XX_IRQ_RELEASE(net_dev)
473#define RT28XX_IRQ_INIT(pAd)
474#define RT28XX_IRQ_ENABLE(pAd)
475
476
477/* ----------------- MLME Related MACRO ----------------- */
478#define RT28XX_MLME_HANDLER(pAd) RTUSBMlmeUp(pAd)
479
480#define RT28XX_MLME_PRE_SANITY_CHECK(pAd) \
481 { if ((pAd->CommonCfg.bHardwareRadio == TRUE) && \
482 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && \
483 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { \
484 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } }
485
486#define RT28XX_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \
487 { RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0); \
488 RTUSBMlmeUp(pAd); }
489
490#define RT28XX_MLME_RESET_STATE_MACHINE(pAd) \
491 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL); \
492 RTUSBMlmeUp(pAd);
493
494#define RT28XX_HANDLE_COUNTER_MEASURE(_pAd, _pEntry) \
495 { RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(MAC_TABLE_ENTRY)); \
496 RTUSBMlmeUp(_pAd); \
497 }
498
499
500/* ----------------- Power Save Related MACRO ----------------- */
501#define RT28XX_PS_POLL_ENQUEUE(pAd) \
502 { RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); \
503 RTUSBKickBulkOut(pAd); }
504
505#define RT28xx_CHIP_NAME "RT2870"
506#define USB_CYC_CFG 0x02a4
507#define STATUS_SUCCESS 0x00
508#define STATUS_UNSUCCESSFUL 0x01
509#define NT_SUCCESS(status) (((status) > 0) ? (1):(0))
510#define InterlockedIncrement atomic_inc
511#define NdisInterlockedIncrement atomic_inc
512#define InterlockedDecrement atomic_dec
513#define NdisInterlockedDecrement atomic_dec
514#define InterlockedExchange atomic_set
515//#define NdisMSendComplete RTMP_SendComplete
516#define NdisMCancelTimer RTMPCancelTimer
517#define NdisAllocMemory(_ptr, _size, _flag) \
518 do{_ptr = kmalloc((_size),(_flag));}while(0)
519#define NdisFreeMemory(a, b, c) kfree((a))
520#define NdisMSleep RTMPusecDelay /* unit: microsecond */
521
522
523#define USBD_TRANSFER_DIRECTION_OUT 0
524#define USBD_TRANSFER_DIRECTION_IN 0
525#define USBD_SHORT_TRANSFER_OK 0
526#define PURB purbb_t
527
528#define RTUSB_FREE_URB(pUrb) usb_free_urb(pUrb)
529
530//#undef MlmeAllocateMemory
531//#undef MlmeFreeMemory
532
533typedef int NTSTATUS;
534typedef struct usb_device * PUSB_DEV;
535
536/* MACRO for linux usb */
537typedef struct urb *purbb_t;
538typedef struct usb_ctrlrequest devctrlrequest;
539#define PIRP PVOID
540#define PMDL PVOID
541#define NDIS_OID UINT
542#ifndef USB_ST_NOERROR
543#define USB_ST_NOERROR 0
544#endif
545
546// vendor-specific control operations
547#define CONTROL_TIMEOUT_JIFFIES ( (100 * HZ) / 1000)
548#define UNLINK_TIMEOUT_MS 3
549
550/* unlink urb */
551#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7)
552#define RTUSB_UNLINK_URB(pUrb) usb_kill_urb(pUrb)
553#else
554#define RTUSB_UNLINK_URB(pUrb) usb_unlink_urb(pUrb)
555#endif
556
557// Prototypes of completion funuc.
558#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
559#define RTUSBBulkOutDataPacketComplete(purb, pt_regs) RTUSBBulkOutDataPacketComplete(purb)
560#define RTUSBBulkOutMLMEPacketComplete(pUrb, pt_regs) RTUSBBulkOutMLMEPacketComplete(pUrb)
561#define RTUSBBulkOutNullFrameComplete(pUrb, pt_regs) RTUSBBulkOutNullFrameComplete(pUrb)
562#define RTUSBBulkOutRTSFrameComplete(pUrb, pt_regs) RTUSBBulkOutRTSFrameComplete(pUrb)
563#define RTUSBBulkOutPsPollComplete(pUrb, pt_regs) RTUSBBulkOutPsPollComplete(pUrb)
564#define RTUSBBulkRxComplete(pUrb, pt_regs) RTUSBBulkRxComplete(pUrb)
565#endif
566
567
568VOID RTUSBBulkOutDataPacketComplete(purbb_t purb, struct pt_regs *pt_regs);
569VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs);
570VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
571VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
572VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb, struct pt_regs *pt_regs);
573VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs);
574
575
576#define RTUSBMlmeUp(pAd) \
577{ \
578 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \
579 CHECK_PID_LEGALITY(pObj->MLMEThr_pid) \
580 up(&(pAd->mlme_semaphore)); \
581}
582
583#define RTUSBCMDUp(pAd) \
584{ \
585 POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \
586 CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid) \
587 up(&(pAd->RTUSBCmd_semaphore)); \
588}
589
590
591static inline NDIS_STATUS RTMPAllocateMemory(
592 OUT PVOID *ptr,
593 IN size_t size)
594{
595 *ptr = kmalloc(size, GFP_ATOMIC);
596 if(*ptr)
597 return NDIS_STATUS_SUCCESS;
598 else
599 return NDIS_STATUS_RESOURCES;
600}
601
602/* rtmp.h */
603#define BEACON_RING_SIZE 2
604#define DEVICE_VENDOR_REQUEST_OUT 0x40
605#define DEVICE_VENDOR_REQUEST_IN 0xc0
606#define INTERFACE_VENDOR_REQUEST_OUT 0x41
607#define INTERFACE_VENDOR_REQUEST_IN 0xc1
608#define MGMTPIPEIDX 0 // EP6 is highest priority
609
610#define BULKOUT_MGMT_RESET_FLAG 0x80
611
612#define RTUSB_SET_BULK_FLAG(_M, _F) ((_M)->BulkFlags |= (_F))
613#define RTUSB_CLEAR_BULK_FLAG(_M, _F) ((_M)->BulkFlags &= ~(_F))
614#define RTUSB_TEST_BULK_FLAG(_M, _F) (((_M)->BulkFlags & (_F)) != 0)
615
616#define EnqueueCmd(cmdq, cmdqelmt) \
617{ \
618 if (cmdq->size == 0) \
619 cmdq->head = cmdqelmt; \
620 else \
621 cmdq->tail->next = cmdqelmt; \
622 cmdq->tail = cmdqelmt; \
623 cmdqelmt->next = NULL; \
624 cmdq->size++; \
625}
626
627typedef struct _RT_SET_ASIC_WCID {
628 ULONG WCID; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
629 ULONG SetTid; // time-based: seconds, packet-based: kilo-packets
630 ULONG DeleteTid; // time-based: seconds, packet-based: kilo-packets
631 UCHAR Addr[MAC_ADDR_LEN]; // avoid in interrupt when write key
632} RT_SET_ASIC_WCID,*PRT_SET_ASIC_WCID;
633
634typedef struct _RT_SET_ASIC_WCID_ATTRI {
635 ULONG WCID; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
636 ULONG Cipher; // ASIC Cipher definition
637 UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
638} RT_SET_ASIC_WCID_ATTRI,*PRT_SET_ASIC_WCID_ATTRI;
639
640typedef struct _MLME_MEMORY_STRUCT {
641 PVOID AllocVa; //Pointer to the base virtual address of the allocated memory
642 struct _MLME_MEMORY_STRUCT *Next; //Pointer to the next virtual address of the allocated memory
643} MLME_MEMORY_STRUCT, *PMLME_MEMORY_STRUCT;
644
645typedef struct _MLME_MEMORY_HANDLER {
646 BOOLEAN MemRunning; //The flag of the Mlme memory handler's status
647 UINT MemoryCount; //Total nonpaged system-space memory not size
648 UINT InUseCount; //Nonpaged system-space memory in used counts
649 UINT UnUseCount; //Nonpaged system-space memory available counts
650 INT PendingCount; //Nonpaged system-space memory for free counts
651 PMLME_MEMORY_STRUCT pInUseHead; //Pointer to the first nonpaed memory not used
652 PMLME_MEMORY_STRUCT pInUseTail; //Pointer to the last nonpaged memory not used
653 PMLME_MEMORY_STRUCT pUnUseHead; //Pointer to the first nonpaged memory in used
654 PMLME_MEMORY_STRUCT pUnUseTail; //Pointer to the last nonpaged memory in used
655 PULONG MemFreePending[MAX_MLME_HANDLER_MEMORY]; //an array to keep pending free-memory's pointer (32bits)
656} MLME_MEMORY_HANDLER, *PMLME_MEMORY_HANDLER;
657
658typedef struct _CmdQElmt {
659 UINT command;
660 PVOID buffer;
661 ULONG bufferlength;
662 BOOLEAN CmdFromNdis;
663 BOOLEAN SetOperation;
664 struct _CmdQElmt *next;
665} CmdQElmt, *PCmdQElmt;
666
667typedef struct _CmdQ {
668 UINT size;
669 CmdQElmt *head;
670 CmdQElmt *tail;
671 UINT32 CmdQState;
672}CmdQ, *PCmdQ;
673
674//
675// For WPA SUPPLICANT: WIRELESS EXT support wireless events: v14 or newer
676//
677#if WIRELESS_EXT >= 14
678//#define WPA_SUPPLICANT_SUPPORT 1
679#endif
680
681/* oid.h */
682// Cipher suite type for mixed mode group cipher, P802.11i-2004
683typedef enum _RT_802_11_CIPHER_SUITE_TYPE {
684 Cipher_Type_NONE,
685 Cipher_Type_WEP40,
686 Cipher_Type_TKIP,
687 Cipher_Type_RSVD,
688 Cipher_Type_CCMP,
689 Cipher_Type_WEP104
690} RT_802_11_CIPHER_SUITE_TYPE, *PRT_802_11_CIPHER_SUITE_TYPE;
691
692//CMDTHREAD_MULTI_READ_MAC
693//CMDTHREAD_MULTI_WRITE_MAC
694//CMDTHREAD_VENDOR_EEPROM_READ
695//CMDTHREAD_VENDOR_EEPROM_WRITE
696typedef struct _CMDHandler_TLV {
697 USHORT Offset;
698 USHORT Length;
699 UCHAR DataFirst;
700} CMDHandler_TLV, *PCMDHandler_TLV;
701
702// New for MeetingHouse Api support
703#define CMDTHREAD_VENDOR_RESET 0x0D730101 // cmd
704#define CMDTHREAD_VENDOR_UNPLUG 0x0D730102 // cmd
705#define CMDTHREAD_VENDOR_SWITCH_FUNCTION 0x0D730103 // cmd
706#define CMDTHREAD_MULTI_WRITE_MAC 0x0D730107 // cmd
707#define CMDTHREAD_MULTI_READ_MAC 0x0D730108 // cmd
708#define CMDTHREAD_VENDOR_EEPROM_WRITE 0x0D73010A // cmd
709#define CMDTHREAD_VENDOR_EEPROM_READ 0x0D73010B // cmd
710#define CMDTHREAD_VENDOR_ENTER_TESTMODE 0x0D73010C // cmd
711#define CMDTHREAD_VENDOR_EXIT_TESTMODE 0x0D73010D // cmd
712#define CMDTHREAD_VENDOR_WRITE_BBP 0x0D730119 // cmd
713#define CMDTHREAD_VENDOR_READ_BBP 0x0D730118 // cmd
714#define CMDTHREAD_VENDOR_WRITE_RF 0x0D73011A // cmd
715#define CMDTHREAD_VENDOR_FLIP_IQ 0x0D73011D // cmd
716#define CMDTHREAD_RESET_BULK_OUT 0x0D730210 // cmd
717#define CMDTHREAD_RESET_BULK_IN 0x0D730211 // cmd
718#define CMDTHREAD_SET_PSM_BIT_SAVE 0x0D730212 // cmd
719#define CMDTHREAD_SET_RADIO 0x0D730214 // cmd
720#define CMDTHREAD_UPDATE_TX_RATE 0x0D730216 // cmd
721#define CMDTHREAD_802_11_ADD_KEY_WEP 0x0D730218 // cmd
722#define CMDTHREAD_RESET_FROM_ERROR 0x0D73021A // cmd
723#define CMDTHREAD_LINK_DOWN 0x0D73021B // cmd
724#define CMDTHREAD_RESET_FROM_NDIS 0x0D73021C // cmd
725#define CMDTHREAD_CHECK_GPIO 0x0D730215 // cmd
726#define CMDTHREAD_FORCE_WAKE_UP 0x0D730222 // cmd
727#define CMDTHREAD_SET_BW 0x0D730225 // cmd
728#define CMDTHREAD_SET_ASIC_WCID 0x0D730226 // cmd
729#define CMDTHREAD_SET_ASIC_WCID_CIPHER 0x0D730227 // cmd
730#define CMDTHREAD_QKERIODIC_EXECUT 0x0D73023D // cmd
731#define RT_CMD_SET_KEY_TABLE 0x0D730228 // cmd
732#define RT_CMD_SET_RX_WCID_TABLE 0x0D730229 // cmd
733#define CMDTHREAD_SET_CLIENT_MAC_ENTRY 0x0D73023E // cmd
734#define CMDTHREAD_802_11_QUERY_HARDWARE_REGISTER 0x0D710105 // cmd
735#define CMDTHREAD_802_11_SET_PHY_MODE 0x0D79010C // cmd
736#define CMDTHREAD_802_11_SET_STA_CONFIG 0x0D790111 // cmd
737#define CMDTHREAD_802_11_SET_PREAMBLE 0x0D790101 // cmd
738#define CMDTHREAD_802_11_COUNTER_MEASURE 0x0D790102 // cmd
739
740
741#define WPA1AKMBIT 0x01
742#define WPA2AKMBIT 0x02
743#define WPA1PSKAKMBIT 0x04
744#define WPA2PSKAKMBIT 0x08
745#define TKIPBIT 0x01
746#define CCMPBIT 0x02
747
748
749#define RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx) \
750 RT28xxUsbStaAsicForceWakeup(pAd, bFromTx);
751
752#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
753 RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
754
755#define RT28XX_MLME_RADIO_ON(pAd) \
756 RT28xxUsbMlmeRadioOn(pAd);
757
758#define RT28XX_MLME_RADIO_OFF(pAd) \
759 RT28xxUsbMlmeRadioOFF(pAd);
760
761#endif //__RT2870_H__
diff --git a/drivers/staging/rt2870/rt28xx.h b/drivers/staging/rt2870/rt28xx.h
new file mode 100644
index 00000000000..3927d22f78f
--- /dev/null
+++ b/drivers/staging/rt2870/rt28xx.h
@@ -0,0 +1,2689 @@
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//
51// SCH/DMA registers - base address 0x0200
52//
53// INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit
54//
55#define DMA_CSR0 0x200
56#define INT_SOURCE_CSR 0x200
57#ifdef RT_BIG_ENDIAN
58typedef union _INT_SOURCE_CSR_STRUC {
59 struct {
60 UINT32 :14;
61 UINT32 TxCoherent:1;
62 UINT32 RxCoherent:1;
63 UINT32 GPTimer:1;
64 UINT32 AutoWakeup:1;//bit14
65 UINT32 TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
66 UINT32 PreTBTT:1;
67 UINT32 TBTTInt:1;
68 UINT32 RxTxCoherent:1;
69 UINT32 MCUCommandINT:1;
70 UINT32 MgmtDmaDone:1;
71 UINT32 HccaDmaDone:1;
72 UINT32 Ac3DmaDone:1;
73 UINT32 Ac2DmaDone:1;
74 UINT32 Ac1DmaDone:1;
75 UINT32 Ac0DmaDone:1;
76 UINT32 RxDone:1;
77 UINT32 TxDelayINT:1; //delayed interrupt, not interrupt until several int or time limit hit
78 UINT32 RxDelayINT:1; //dealyed interrupt
79 } field;
80 UINT32 word;
81} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
82#else
83typedef union _INT_SOURCE_CSR_STRUC {
84 struct {
85 UINT32 RxDelayINT:1;
86 UINT32 TxDelayINT:1;
87 UINT32 RxDone:1;
88 UINT32 Ac0DmaDone:1;//4
89 UINT32 Ac1DmaDone:1;
90 UINT32 Ac2DmaDone:1;
91 UINT32 Ac3DmaDone:1;
92 UINT32 HccaDmaDone:1; // bit7
93 UINT32 MgmtDmaDone:1;
94 UINT32 MCUCommandINT:1;//bit 9
95 UINT32 RxTxCoherent:1;
96 UINT32 TBTTInt:1;
97 UINT32 PreTBTT:1;
98 UINT32 TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
99 UINT32 AutoWakeup:1;//bit14
100 UINT32 GPTimer:1;
101 UINT32 RxCoherent:1;//bit16
102 UINT32 TxCoherent:1;
103 UINT32 :14;
104 } field;
105 UINT32 word;
106} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
107#endif
108
109//
110// INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF
111//
112#define INT_MASK_CSR 0x204
113#ifdef RT_BIG_ENDIAN
114typedef union _INT_MASK_CSR_STRUC {
115 struct {
116 UINT32 TxCoherent:1;
117 UINT32 RxCoherent:1;
118 UINT32 :20;
119 UINT32 MCUCommandINT:1;
120 UINT32 MgmtDmaDone:1;
121 UINT32 HccaDmaDone:1;
122 UINT32 Ac3DmaDone:1;
123 UINT32 Ac2DmaDone:1;
124 UINT32 Ac1DmaDone:1;
125 UINT32 Ac0DmaDone:1;
126 UINT32 RxDone:1;
127 UINT32 TxDelay:1;
128 UINT32 RXDelay_INT_MSK:1;
129 } field;
130 UINT32 word;
131}INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
132#else
133typedef union _INT_MASK_CSR_STRUC {
134 struct {
135 UINT32 RXDelay_INT_MSK:1;
136 UINT32 TxDelay:1;
137 UINT32 RxDone:1;
138 UINT32 Ac0DmaDone:1;
139 UINT32 Ac1DmaDone:1;
140 UINT32 Ac2DmaDone:1;
141 UINT32 Ac3DmaDone:1;
142 UINT32 HccaDmaDone:1;
143 UINT32 MgmtDmaDone:1;
144 UINT32 MCUCommandINT:1;
145 UINT32 :20;
146 UINT32 RxCoherent:1;
147 UINT32 TxCoherent:1;
148 } field;
149 UINT32 word;
150} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
151#endif
152#define WPDMA_GLO_CFG 0x208
153#ifdef RT_BIG_ENDIAN
154typedef union _WPDMA_GLO_CFG_STRUC {
155 struct {
156 UINT32 HDR_SEG_LEN:16;
157 UINT32 RXHdrScater:8;
158 UINT32 BigEndian:1;
159 UINT32 EnTXWriteBackDDONE:1;
160 UINT32 WPDMABurstSIZE:2;
161 UINT32 RxDMABusy:1;
162 UINT32 EnableRxDMA:1;
163 UINT32 TxDMABusy:1;
164 UINT32 EnableTxDMA:1;
165 } field;
166 UINT32 word;
167}WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
168#else
169typedef union _WPDMA_GLO_CFG_STRUC {
170 struct {
171 UINT32 EnableTxDMA:1;
172 UINT32 TxDMABusy:1;
173 UINT32 EnableRxDMA:1;
174 UINT32 RxDMABusy:1;
175 UINT32 WPDMABurstSIZE:2;
176 UINT32 EnTXWriteBackDDONE:1;
177 UINT32 BigEndian:1;
178 UINT32 RXHdrScater:8;
179 UINT32 HDR_SEG_LEN:16;
180 } field;
181 UINT32 word;
182} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
183#endif
184#define WPDMA_RST_IDX 0x20c
185#ifdef RT_BIG_ENDIAN
186typedef union _WPDMA_RST_IDX_STRUC {
187 struct {
188 UINT32 :15;
189 UINT32 RST_DRX_IDX0:1;
190 UINT32 rsv:10;
191 UINT32 RST_DTX_IDX5:1;
192 UINT32 RST_DTX_IDX4:1;
193 UINT32 RST_DTX_IDX3:1;
194 UINT32 RST_DTX_IDX2:1;
195 UINT32 RST_DTX_IDX1:1;
196 UINT32 RST_DTX_IDX0:1;
197 } field;
198 UINT32 word;
199}WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
200#else
201typedef union _WPDMA_RST_IDX_STRUC {
202 struct {
203 UINT32 RST_DTX_IDX0:1;
204 UINT32 RST_DTX_IDX1:1;
205 UINT32 RST_DTX_IDX2:1;
206 UINT32 RST_DTX_IDX3:1;
207 UINT32 RST_DTX_IDX4:1;
208 UINT32 RST_DTX_IDX5:1;
209 UINT32 rsv:10;
210 UINT32 RST_DRX_IDX0:1;
211 UINT32 :15;
212 } field;
213 UINT32 word;
214} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
215#endif
216#define DELAY_INT_CFG 0x0210
217#ifdef RT_BIG_ENDIAN
218typedef union _DELAY_INT_CFG_STRUC {
219 struct {
220 UINT32 TXDLY_INT_EN:1;
221 UINT32 TXMAX_PINT:7;
222 UINT32 TXMAX_PTIME:8;
223 UINT32 RXDLY_INT_EN:1;
224 UINT32 RXMAX_PINT:7;
225 UINT32 RXMAX_PTIME:8;
226 } field;
227 UINT32 word;
228}DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
229#else
230typedef union _DELAY_INT_CFG_STRUC {
231 struct {
232 UINT32 RXMAX_PTIME:8;
233 UINT32 RXMAX_PINT:7;
234 UINT32 RXDLY_INT_EN:1;
235 UINT32 TXMAX_PTIME:8;
236 UINT32 TXMAX_PINT:7;
237 UINT32 TXDLY_INT_EN:1;
238 } field;
239 UINT32 word;
240} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
241#endif
242#define WMM_AIFSN_CFG 0x0214
243#ifdef RT_BIG_ENDIAN
244typedef union _AIFSN_CSR_STRUC {
245 struct {
246 UINT32 Rsv:16;
247 UINT32 Aifsn3:4; // for AC_VO
248 UINT32 Aifsn2:4; // for AC_VI
249 UINT32 Aifsn1:4; // for AC_BK
250 UINT32 Aifsn0:4; // for AC_BE
251 } field;
252 UINT32 word;
253} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
254#else
255typedef union _AIFSN_CSR_STRUC {
256 struct {
257 UINT32 Aifsn0:4; // for AC_BE
258 UINT32 Aifsn1:4; // for AC_BK
259 UINT32 Aifsn2:4; // for AC_VI
260 UINT32 Aifsn3:4; // for AC_VO
261 UINT32 Rsv:16;
262 } field;
263 UINT32 word;
264} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
265#endif
266//
267// CWMIN_CSR: CWmin for each EDCA AC
268//
269#define WMM_CWMIN_CFG 0x0218
270#ifdef RT_BIG_ENDIAN
271typedef union _CWMIN_CSR_STRUC {
272 struct {
273 UINT32 Rsv:16;
274 UINT32 Cwmin3:4; // for AC_VO
275 UINT32 Cwmin2:4; // for AC_VI
276 UINT32 Cwmin1:4; // for AC_BK
277 UINT32 Cwmin0:4; // for AC_BE
278 } field;
279 UINT32 word;
280} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
281#else
282typedef union _CWMIN_CSR_STRUC {
283 struct {
284 UINT32 Cwmin0:4; // for AC_BE
285 UINT32 Cwmin1:4; // for AC_BK
286 UINT32 Cwmin2:4; // for AC_VI
287 UINT32 Cwmin3:4; // for AC_VO
288 UINT32 Rsv:16;
289 } field;
290 UINT32 word;
291} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
292#endif
293
294//
295// CWMAX_CSR: CWmin for each EDCA AC
296//
297#define WMM_CWMAX_CFG 0x021c
298#ifdef RT_BIG_ENDIAN
299typedef union _CWMAX_CSR_STRUC {
300 struct {
301 UINT32 Rsv:16;
302 UINT32 Cwmax3:4; // for AC_VO
303 UINT32 Cwmax2:4; // for AC_VI
304 UINT32 Cwmax1:4; // for AC_BK
305 UINT32 Cwmax0:4; // for AC_BE
306 } field;
307 UINT32 word;
308} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
309#else
310typedef union _CWMAX_CSR_STRUC {
311 struct {
312 UINT32 Cwmax0:4; // for AC_BE
313 UINT32 Cwmax1:4; // for AC_BK
314 UINT32 Cwmax2:4; // for AC_VI
315 UINT32 Cwmax3:4; // for AC_VO
316 UINT32 Rsv:16;
317 } field;
318 UINT32 word;
319} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
320#endif
321
322
323//
324// AC_TXOP_CSR0: AC_BK/AC_BE TXOP register
325//
326#define WMM_TXOP0_CFG 0x0220
327#ifdef RT_BIG_ENDIAN
328typedef union _AC_TXOP_CSR0_STRUC {
329 struct {
330 USHORT Ac1Txop; // for AC_BE, in unit of 32us
331 USHORT Ac0Txop; // for AC_BK, in unit of 32us
332 } field;
333 UINT32 word;
334} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
335#else
336typedef union _AC_TXOP_CSR0_STRUC {
337 struct {
338 USHORT Ac0Txop; // for AC_BK, in unit of 32us
339 USHORT Ac1Txop; // for AC_BE, in unit of 32us
340 } field;
341 UINT32 word;
342} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
343#endif
344
345//
346// AC_TXOP_CSR1: AC_VO/AC_VI TXOP register
347//
348#define WMM_TXOP1_CFG 0x0224
349#ifdef RT_BIG_ENDIAN
350typedef union _AC_TXOP_CSR1_STRUC {
351 struct {
352 USHORT Ac3Txop; // for AC_VO, in unit of 32us
353 USHORT Ac2Txop; // for AC_VI, in unit of 32us
354 } field;
355 UINT32 word;
356} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
357#else
358typedef union _AC_TXOP_CSR1_STRUC {
359 struct {
360 USHORT Ac2Txop; // for AC_VI, in unit of 32us
361 USHORT Ac3Txop; // for AC_VO, in unit of 32us
362 } field;
363 UINT32 word;
364} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
365#endif
366#define RINGREG_DIFF 0x10
367#define GPIO_CTRL_CFG 0x0228 //MAC_CSR13
368#define MCU_CMD_CFG 0x022c
369#define TX_BASE_PTR0 0x0230 //AC_BK base address
370#define TX_MAX_CNT0 0x0234
371#define TX_CTX_IDX0 0x0238
372#define TX_DTX_IDX0 0x023c
373#define TX_BASE_PTR1 0x0240 //AC_BE base address
374#define TX_MAX_CNT1 0x0244
375#define TX_CTX_IDX1 0x0248
376#define TX_DTX_IDX1 0x024c
377#define TX_BASE_PTR2 0x0250 //AC_VI base address
378#define TX_MAX_CNT2 0x0254
379#define TX_CTX_IDX2 0x0258
380#define TX_DTX_IDX2 0x025c
381#define TX_BASE_PTR3 0x0260 //AC_VO base address
382#define TX_MAX_CNT3 0x0264
383#define TX_CTX_IDX3 0x0268
384#define TX_DTX_IDX3 0x026c
385#define TX_BASE_PTR4 0x0270 //HCCA base address
386#define TX_MAX_CNT4 0x0274
387#define TX_CTX_IDX4 0x0278
388#define TX_DTX_IDX4 0x027c
389#define TX_BASE_PTR5 0x0280 //MGMT base address
390#define TX_MAX_CNT5 0x0284
391#define TX_CTX_IDX5 0x0288
392#define TX_DTX_IDX5 0x028c
393#define TX_MGMTMAX_CNT TX_MAX_CNT5
394#define TX_MGMTCTX_IDX TX_CTX_IDX5
395#define TX_MGMTDTX_IDX TX_DTX_IDX5
396#define RX_BASE_PTR 0x0290 //RX base address
397#define RX_MAX_CNT 0x0294
398#define RX_CRX_IDX 0x0298
399#define RX_DRX_IDX 0x029c
400#define USB_DMA_CFG 0x02a0
401#ifdef RT_BIG_ENDIAN
402typedef union _USB_DMA_CFG_STRUC {
403 struct {
404 UINT32 TxBusy:1; //USB DMA TX FSM busy . debug only
405 UINT32 RxBusy:1; //USB DMA RX FSM busy . debug only
406 UINT32 EpoutValid:6; //OUT endpoint data valid. debug only
407 UINT32 TxBulkEn:1; //Enable USB DMA Tx
408 UINT32 RxBulkEn:1; //Enable USB DMA Rx
409 UINT32 RxBulkAggEn:1; //Enable Rx Bulk Aggregation
410 UINT32 TxopHalt:1; //Halt TXOP count down when TX buffer is full.
411 UINT32 TxClear:1; //Clear USB DMA TX path
412 UINT32 rsv:2;
413 UINT32 phyclear:1; //phy watch dog enable. write 1
414 UINT32 RxBulkAggLmt:8; //Rx Bulk Aggregation Limit in unit of 1024 bytes
415 UINT32 RxBulkAggTOut:8; //Rx Bulk Aggregation TimeOut in unit of 33ns
416 } field;
417 UINT32 word;
418} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
419#else
420typedef union _USB_DMA_CFG_STRUC {
421 struct {
422 UINT32 RxBulkAggTOut:8; //Rx Bulk Aggregation TimeOut in unit of 33ns
423 UINT32 RxBulkAggLmt:8; //Rx Bulk Aggregation Limit in unit of 256 bytes
424 UINT32 phyclear:1; //phy watch dog enable. write 1
425 UINT32 rsv:2;
426 UINT32 TxClear:1; //Clear USB DMA TX path
427 UINT32 TxopHalt:1; //Halt TXOP count down when TX buffer is full.
428 UINT32 RxBulkAggEn:1; //Enable Rx Bulk Aggregation
429 UINT32 RxBulkEn:1; //Enable USB DMA Rx
430 UINT32 TxBulkEn:1; //Enable USB DMA Tx
431 UINT32 EpoutValid:6; //OUT endpoint data valid
432 UINT32 RxBusy:1; //USB DMA RX FSM busy
433 UINT32 TxBusy:1; //USB DMA TX FSM busy
434 } field;
435 UINT32 word;
436} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
437#endif
438
439//
440// 3 PBF registers
441//
442//
443// Most are for debug. Driver doesn't touch PBF register.
444#define PBF_SYS_CTRL 0x0400
445#define PBF_CFG 0x0408
446#define PBF_MAX_PCNT 0x040C
447#define PBF_CTRL 0x0410
448#define PBF_INT_STA 0x0414
449#define PBF_INT_ENA 0x0418
450#define TXRXQ_PCNT 0x0438
451#define PBF_DBG 0x043c
452#define PBF_CAP_CTRL 0x0440
453
454//
455// 4 MAC registers
456//
457//
458// 4.1 MAC SYSTEM configuration registers (offset:0x1000)
459//
460#define MAC_CSR0 0x1000
461#ifdef RT_BIG_ENDIAN
462typedef union _ASIC_VER_ID_STRUC {
463 struct {
464 USHORT ASICVer; // version : 2860
465 USHORT ASICRev; // reversion : 0
466 } field;
467 UINT32 word;
468} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
469#else
470typedef union _ASIC_VER_ID_STRUC {
471 struct {
472 USHORT ASICRev; // reversion : 0
473 USHORT ASICVer; // version : 2860
474 } field;
475 UINT32 word;
476} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
477#endif
478#define MAC_SYS_CTRL 0x1004 //MAC_CSR1
479#define MAC_ADDR_DW0 0x1008 // MAC ADDR DW0
480#define MAC_ADDR_DW1 0x100c // MAC ADDR DW1
481//
482// MAC_CSR2: STA MAC register 0
483//
484#ifdef RT_BIG_ENDIAN
485typedef union _MAC_DW0_STRUC {
486 struct {
487 UCHAR Byte3; // MAC address byte 3
488 UCHAR Byte2; // MAC address byte 2
489 UCHAR Byte1; // MAC address byte 1
490 UCHAR Byte0; // MAC address byte 0
491 } field;
492 UINT32 word;
493} MAC_DW0_STRUC, *PMAC_DW0_STRUC;
494#else
495typedef union _MAC_DW0_STRUC {
496 struct {
497 UCHAR Byte0; // MAC address byte 0
498 UCHAR Byte1; // MAC address byte 1
499 UCHAR Byte2; // MAC address byte 2
500 UCHAR Byte3; // MAC address byte 3
501 } field;
502 UINT32 word;
503} MAC_DW0_STRUC, *PMAC_DW0_STRUC;
504#endif
505
506//
507// MAC_CSR3: STA MAC register 1
508//
509#ifdef RT_BIG_ENDIAN
510typedef union _MAC_DW1_STRUC {
511 struct {
512 UCHAR Rsvd1;
513 UCHAR U2MeMask;
514 UCHAR Byte5; // MAC address byte 5
515 UCHAR Byte4; // MAC address byte 4
516 } field;
517 UINT32 word;
518} MAC_DW1_STRUC, *PMAC_DW1_STRUC;
519#else
520typedef union _MAC_DW1_STRUC {
521 struct {
522 UCHAR Byte4; // MAC address byte 4
523 UCHAR Byte5; // MAC address byte 5
524 UCHAR U2MeMask;
525 UCHAR Rsvd1;
526 } field;
527 UINT32 word;
528} MAC_DW1_STRUC, *PMAC_DW1_STRUC;
529#endif
530
531#define MAC_BSSID_DW0 0x1010 // MAC BSSID DW0
532#define MAC_BSSID_DW1 0x1014 // MAC BSSID DW1
533
534//
535// MAC_CSR5: BSSID register 1
536//
537#ifdef RT_BIG_ENDIAN
538typedef union _MAC_CSR5_STRUC {
539 struct {
540 USHORT Rsvd:11;
541 USHORT MBssBcnNum:3;
542 USHORT BssIdMode:2; // 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID
543 UCHAR Byte5; // BSSID byte 5
544 UCHAR Byte4; // BSSID byte 4
545 } field;
546 UINT32 word;
547} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
548#else
549typedef union _MAC_CSR5_STRUC {
550 struct {
551 UCHAR Byte4; // BSSID byte 4
552 UCHAR Byte5; // BSSID byte 5
553 USHORT BssIdMask:2; // 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID
554 USHORT MBssBcnNum:3;
555 USHORT Rsvd:11;
556 } field;
557 UINT32 word;
558} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
559#endif
560
561#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
562#define BBP_CSR_CFG 0x101c //
563//
564// BBP_CSR_CFG: BBP serial control register
565//
566#ifdef RT_BIG_ENDIAN
567typedef union _BBP_CSR_CFG_STRUC {
568 struct {
569 UINT32 :12;
570 UINT32 BBP_RW_MODE:1; // 0: use serial mode 1:parallel
571 UINT32 BBP_PAR_DUR:1; // 0: 4 MAC clock cycles 1: 8 MAC clock cycles
572 UINT32 Busy:1; // 1: ASIC is busy execute BBP programming.
573 UINT32 fRead:1; // 0: Write BBP, 1: Read BBP
574 UINT32 RegNum:8; // Selected BBP register
575 UINT32 Value:8; // Register value to program into BBP
576 } field;
577 UINT32 word;
578} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
579#else
580typedef union _BBP_CSR_CFG_STRUC {
581 struct {
582 UINT32 Value:8; // Register value to program into BBP
583 UINT32 RegNum:8; // Selected BBP register
584 UINT32 fRead:1; // 0: Write BBP, 1: Read BBP
585 UINT32 Busy:1; // 1: ASIC is busy execute BBP programming.
586 UINT32 BBP_PAR_DUR:1; // 0: 4 MAC clock cycles 1: 8 MAC clock cycles
587 UINT32 BBP_RW_MODE:1; // 0: use serial mode 1:parallel
588 UINT32 :12;
589 } field;
590 UINT32 word;
591} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
592#endif
593#define RF_CSR_CFG0 0x1020
594//
595// RF_CSR_CFG: RF control register
596//
597#ifdef RT_BIG_ENDIAN
598typedef union _RF_CSR_CFG0_STRUC {
599 struct {
600 UINT32 Busy:1; // 0: idle 1: 8busy
601 UINT32 Sel:1; // 0:RF_LE0 activate 1:RF_LE1 activate
602 UINT32 StandbyMode:1; // 0: high when stand by 1: low when standby
603 UINT32 bitwidth:5; // Selected BBP register
604 UINT32 RegIdAndContent:24; // Register value to program into BBP
605 } field;
606 UINT32 word;
607} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
608#else
609typedef union _RF_CSR_CFG0_STRUC {
610 struct {
611 UINT32 RegIdAndContent:24; // Register value to program into BBP
612 UINT32 bitwidth:5; // Selected BBP register
613 UINT32 StandbyMode:1; // 0: high when stand by 1: low when standby
614 UINT32 Sel:1; // 0:RF_LE0 activate 1:RF_LE1 activate
615 UINT32 Busy:1; // 0: idle 1: 8busy
616 } field;
617 UINT32 word;
618} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
619#endif
620#define RF_CSR_CFG1 0x1024
621#ifdef RT_BIG_ENDIAN
622typedef union _RF_CSR_CFG1_STRUC {
623 struct {
624 UINT32 rsv:7; // 0: idle 1: 8busy
625 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)
626 UINT32 RegIdAndContent:24; // Register value to program into BBP
627 } field;
628 UINT32 word;
629} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
630#else
631typedef union _RF_CSR_CFG1_STRUC {
632 struct {
633 UINT32 RegIdAndContent:24; // Register value to program into BBP
634 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)
635 UINT32 rsv:7; // 0: idle 1: 8busy
636 } field;
637 UINT32 word;
638} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
639#endif
640#define RF_CSR_CFG2 0x1028 //
641#ifdef RT_BIG_ENDIAN
642typedef union _RF_CSR_CFG2_STRUC {
643 struct {
644 UINT32 rsv:8; // 0: idle 1: 8busy
645 UINT32 RegIdAndContent:24; // Register value to program into BBP
646 } field;
647 UINT32 word;
648} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
649#else
650typedef union _RF_CSR_CFG2_STRUC {
651 struct {
652 UINT32 RegIdAndContent:24; // Register value to program into BBP
653 UINT32 rsv:8; // 0: idle 1: 8busy
654 } field;
655 UINT32 word;
656} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
657#endif
658#define LED_CFG 0x102c // MAC_CSR14
659#ifdef RT_BIG_ENDIAN
660typedef union _LED_CFG_STRUC {
661 struct {
662 UINT32 :1;
663 UINT32 LedPolar:1; // Led Polarity. 0: active low1: active high
664 UINT32 YLedMode:2; // yellow Led Mode
665 UINT32 GLedMode:2; // green Led Mode
666 UINT32 RLedMode:2; // red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on
667 UINT32 rsv:2;
668 UINT32 SlowBlinkPeriod:6; // slow blinking period. unit:1ms
669 UINT32 OffPeriod:8; // blinking off period unit 1ms
670 UINT32 OnPeriod:8; // blinking on period unit 1ms
671 } field;
672 UINT32 word;
673} LED_CFG_STRUC, *PLED_CFG_STRUC;
674#else
675typedef union _LED_CFG_STRUC {
676 struct {
677 UINT32 OnPeriod:8; // blinking on period unit 1ms
678 UINT32 OffPeriod:8; // blinking off period unit 1ms
679 UINT32 SlowBlinkPeriod:6; // slow blinking period. unit:1ms
680 UINT32 rsv:2;
681 UINT32 RLedMode:2; // red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on
682 UINT32 GLedMode:2; // green Led Mode
683 UINT32 YLedMode:2; // yellow Led Mode
684 UINT32 LedPolar:1; // Led Polarity. 0: active low1: active high
685 UINT32 :1;
686 } field;
687 UINT32 word;
688} LED_CFG_STRUC, *PLED_CFG_STRUC;
689#endif
690//
691// 4.2 MAC TIMING configuration registers (offset:0x1100)
692//
693#define XIFS_TIME_CFG 0x1100 // MAC_CSR8 MAC_CSR9
694#ifdef RT_BIG_ENDIAN
695typedef union _IFS_SLOT_CFG_STRUC {
696 struct {
697 UINT32 rsv:2;
698 UINT32 BBRxendEnable:1; // reference RXEND signal to begin XIFS defer
699 UINT32 EIFS:9; // unit 1us
700 UINT32 OfdmXifsTime:4; //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
701 UINT32 OfdmSifsTime:8; // unit 1us. Applied after OFDM RX/TX
702 UINT32 CckmSifsTime:8; // unit 1us. Applied after CCK RX/TX
703 } field;
704 UINT32 word;
705} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
706#else
707typedef union _IFS_SLOT_CFG_STRUC {
708 struct {
709 UINT32 CckmSifsTime:8; // unit 1us. Applied after CCK RX/TX
710 UINT32 OfdmSifsTime:8; // unit 1us. Applied after OFDM RX/TX
711 UINT32 OfdmXifsTime:4; //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
712 UINT32 EIFS:9; // unit 1us
713 UINT32 BBRxendEnable:1; // reference RXEND signal to begin XIFS defer
714 UINT32 rsv:2;
715 } field;
716 UINT32 word;
717} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
718#endif
719
720#define BKOFF_SLOT_CFG 0x1104 // mac_csr9 last 8 bits
721#define NAV_TIME_CFG 0x1108 // NAV (MAC_CSR15)
722#define CH_TIME_CFG 0x110C // Count as channel busy
723#define PBF_LIFE_TIMER 0x1110 //TX/RX MPDU timestamp timer (free run)Unit: 1us
724#define BCN_TIME_CFG 0x1114 // TXRX_CSR9
725
726#define BCN_OFFSET0 0x042C
727#define BCN_OFFSET1 0x0430
728
729//
730// BCN_TIME_CFG : Synchronization control register
731//
732#ifdef RT_BIG_ENDIAN
733typedef union _BCN_TIME_CFG_STRUC {
734 struct {
735 UINT32 TxTimestampCompensate:8;
736 UINT32 :3;
737 UINT32 bBeaconGen:1; // Enable beacon generator
738 UINT32 bTBTTEnable:1;
739 UINT32 TsfSyncMode:2; // Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
740 UINT32 bTsfTicking:1; // Enable TSF auto counting
741 UINT32 BeaconInterval:16; // in unit of 1/16 TU
742 } field;
743 UINT32 word;
744} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
745#else
746typedef union _BCN_TIME_CFG_STRUC {
747 struct {
748 UINT32 BeaconInterval:16; // in unit of 1/16 TU
749 UINT32 bTsfTicking:1; // Enable TSF auto counting
750 UINT32 TsfSyncMode:2; // Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
751 UINT32 bTBTTEnable:1;
752 UINT32 bBeaconGen:1; // Enable beacon generator
753 UINT32 :3;
754 UINT32 TxTimestampCompensate:8;
755 } field;
756 UINT32 word;
757} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
758#endif
759#define TBTT_SYNC_CFG 0x1118 // txrx_csr10
760#define TSF_TIMER_DW0 0x111C // Local TSF timer lsb 32 bits. Read-only
761#define TSF_TIMER_DW1 0x1120 // msb 32 bits. Read-only.
762#define TBTT_TIMER 0x1124 // TImer remains till next TBTT. Read-only. TXRX_CSR14
763#define INT_TIMER_CFG 0x1128 //
764#define INT_TIMER_EN 0x112c // GP-timer and pre-tbtt Int enable
765#define CH_IDLE_STA 0x1130 // channel idle time
766#define CH_BUSY_STA 0x1134 // channle busy time
767//
768// 4.2 MAC POWER configuration registers (offset:0x1200)
769//
770#define MAC_STATUS_CFG 0x1200 // old MAC_CSR12
771#define PWR_PIN_CFG 0x1204 // old MAC_CSR12
772#define AUTO_WAKEUP_CFG 0x1208 // old MAC_CSR10
773//
774// AUTO_WAKEUP_CFG: Manual power control / status register
775//
776#ifdef RT_BIG_ENDIAN
777typedef union _AUTO_WAKEUP_STRUC {
778 struct {
779 UINT32 :16;
780 UINT32 EnableAutoWakeup:1; // 0:sleep, 1:awake
781 UINT32 NumofSleepingTbtt:7; // ForceWake has high privilege than PutToSleep when both set
782 UINT32 AutoLeadTime:8;
783 } field;
784 UINT32 word;
785} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
786#else
787typedef union _AUTO_WAKEUP_STRUC {
788 struct {
789 UINT32 AutoLeadTime:8;
790 UINT32 NumofSleepingTbtt:7; // ForceWake has high privilege than PutToSleep when both set
791 UINT32 EnableAutoWakeup:1; // 0:sleep, 1:awake
792 UINT32 :16;
793 } field;
794 UINT32 word;
795} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
796#endif
797//
798// 4.3 MAC TX configuration registers (offset:0x1300)
799//
800
801#define EDCA_AC0_CFG 0x1300 //AC_TXOP_CSR0 0x3474
802#define EDCA_AC1_CFG 0x1304
803#define EDCA_AC2_CFG 0x1308
804#define EDCA_AC3_CFG 0x130c
805#ifdef RT_BIG_ENDIAN
806typedef union _EDCA_AC_CFG_STRUC {
807 struct {
808 UINT32 :12; //
809 UINT32 Cwmax:4; //unit power of 2
810 UINT32 Cwmin:4; //
811 UINT32 Aifsn:4; // # of slot time
812 UINT32 AcTxop:8; // in unit of 32us
813 } field;
814 UINT32 word;
815} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
816#else
817typedef union _EDCA_AC_CFG_STRUC {
818 struct {
819 UINT32 AcTxop:8; // in unit of 32us
820 UINT32 Aifsn:4; // # of slot time
821 UINT32 Cwmin:4; //
822 UINT32 Cwmax:4; //unit power of 2
823 UINT32 :12; //
824 } field;
825 UINT32 word;
826} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
827#endif
828
829#define EDCA_TID_AC_MAP 0x1310
830#define TX_PWR_CFG_0 0x1314
831#define TX_PWR_CFG_1 0x1318
832#define TX_PWR_CFG_2 0x131C
833#define TX_PWR_CFG_3 0x1320
834#define TX_PWR_CFG_4 0x1324
835#define TX_PIN_CFG 0x1328
836#define TX_BAND_CFG 0x132c // 0x1 use upper 20MHz. 0 juse lower 20MHz
837#define TX_SW_CFG0 0x1330
838#define TX_SW_CFG1 0x1334
839#define TX_SW_CFG2 0x1338
840#define TXOP_THRES_CFG 0x133c
841#define TXOP_CTRL_CFG 0x1340
842#define TX_RTS_CFG 0x1344
843
844#ifdef RT_BIG_ENDIAN
845typedef union _TX_RTS_CFG_STRUC {
846 struct {
847 UINT32 rsv:7;
848 UINT32 RtsFbkEn:1; // enable rts rate fallback
849 UINT32 RtsThres:16; // unit:byte
850 UINT32 AutoRtsRetryLimit:8;
851 } field;
852 UINT32 word;
853} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
854#else
855typedef union _TX_RTS_CFG_STRUC {
856 struct {
857 UINT32 AutoRtsRetryLimit:8;
858 UINT32 RtsThres:16; // unit:byte
859 UINT32 RtsFbkEn:1; // enable rts rate fallback
860 UINT32 rsv:7; // 1: HT non-STBC control frame enable
861 } field;
862 UINT32 word;
863} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
864#endif
865#define TX_TIMEOUT_CFG 0x1348
866#ifdef RT_BIG_ENDIAN
867typedef union _TX_TIMEOUT_CFG_STRUC {
868 struct {
869 UINT32 rsv2:8;
870 UINT32 TxopTimeout:8; //TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
871 UINT32 RxAckTimeout:8; // unit:slot. Used for TX precedure
872 UINT32 MpduLifeTime:4; // expiration time = 2^(9+MPDU LIFE TIME) us
873 UINT32 rsv:4;
874 } field;
875 UINT32 word;
876} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
877#else
878typedef union _TX_TIMEOUT_CFG_STRUC {
879 struct {
880 UINT32 rsv:4;
881 UINT32 MpduLifeTime:4; // expiration time = 2^(9+MPDU LIFE TIME) us
882 UINT32 RxAckTimeout:8; // unit:slot. Used for TX precedure
883 UINT32 TxopTimeout:8; //TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
884 UINT32 rsv2:8; // 1: HT non-STBC control frame enable
885 } field;
886 UINT32 word;
887} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
888#endif
889#define TX_RTY_CFG 0x134c
890#ifdef RT_BIG_ENDIAN
891typedef union PACKED _TX_RTY_CFG_STRUC {
892 struct {
893 UINT32 rsv:1;
894 UINT32 TxautoFBEnable:1; // Tx retry PHY rate auto fallback enable
895 UINT32 AggRtyMode:1; // Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
896 UINT32 NonAggRtyMode:1; // Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
897 UINT32 LongRtyThre:12; // Long retry threshoold
898 UINT32 LongRtyLimit:8; //long retry limit
899 UINT32 ShortRtyLimit:8; // short retry limit
900
901 } field;
902 UINT32 word;
903} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
904#else
905typedef union PACKED _TX_RTY_CFG_STRUC {
906 struct {
907 UINT32 ShortRtyLimit:8; // short retry limit
908 UINT32 LongRtyLimit:8; //long retry limit
909 UINT32 LongRtyThre:12; // Long retry threshoold
910 UINT32 NonAggRtyMode:1; // Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
911 UINT32 AggRtyMode:1; // Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
912 UINT32 TxautoFBEnable:1; // Tx retry PHY rate auto fallback enable
913 UINT32 rsv:1; // 1: HT non-STBC control frame enable
914 } field;
915 UINT32 word;
916} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
917#endif
918#define TX_LINK_CFG 0x1350
919#ifdef RT_BIG_ENDIAN
920typedef union PACKED _TX_LINK_CFG_STRUC {
921 struct PACKED {
922 UINT32 RemotMFS:8; //remote MCS feedback sequence number
923 UINT32 RemotMFB:8; // remote MCS feedback
924 UINT32 rsv:3; //
925 UINT32 TxCFAckEn:1; // Piggyback CF-ACK enable
926 UINT32 TxRDGEn:1; // RDG TX enable
927 UINT32 TxMRQEn:1; // MCS request TX enable
928 UINT32 RemoteUMFSEnable:1; // remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7)
929 UINT32 MFBEnable:1; // TX apply remote MFB 1:enable
930 UINT32 RemoteMFBLifeTime:8; //remote MFB life time. unit : 32us
931 } field;
932 UINT32 word;
933} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
934#else
935typedef union PACKED _TX_LINK_CFG_STRUC {
936 struct PACKED {
937 UINT32 RemoteMFBLifeTime:8; //remote MFB life time. unit : 32us
938 UINT32 MFBEnable:1; // TX apply remote MFB 1:enable
939 UINT32 RemoteUMFSEnable:1; // remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7)
940 UINT32 TxMRQEn:1; // MCS request TX enable
941 UINT32 TxRDGEn:1; // RDG TX enable
942 UINT32 TxCFAckEn:1; // Piggyback CF-ACK enable
943 UINT32 rsv:3; //
944 UINT32 RemotMFB:8; // remote MCS feedback
945 UINT32 RemotMFS:8; //remote MCS feedback sequence number
946 } field;
947 UINT32 word;
948} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
949#endif
950#define HT_FBK_CFG0 0x1354
951#ifdef RT_BIG_ENDIAN
952typedef union PACKED _HT_FBK_CFG0_STRUC {
953 struct {
954 UINT32 HTMCS7FBK:4;
955 UINT32 HTMCS6FBK:4;
956 UINT32 HTMCS5FBK:4;
957 UINT32 HTMCS4FBK:4;
958 UINT32 HTMCS3FBK:4;
959 UINT32 HTMCS2FBK:4;
960 UINT32 HTMCS1FBK:4;
961 UINT32 HTMCS0FBK:4;
962 } field;
963 UINT32 word;
964} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
965#else
966typedef union PACKED _HT_FBK_CFG0_STRUC {
967 struct {
968 UINT32 HTMCS0FBK:4;
969 UINT32 HTMCS1FBK:4;
970 UINT32 HTMCS2FBK:4;
971 UINT32 HTMCS3FBK:4;
972 UINT32 HTMCS4FBK:4;
973 UINT32 HTMCS5FBK:4;
974 UINT32 HTMCS6FBK:4;
975 UINT32 HTMCS7FBK:4;
976 } field;
977 UINT32 word;
978} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
979#endif
980#define HT_FBK_CFG1 0x1358
981#ifdef RT_BIG_ENDIAN
982typedef union _HT_FBK_CFG1_STRUC {
983 struct {
984 UINT32 HTMCS15FBK:4;
985 UINT32 HTMCS14FBK:4;
986 UINT32 HTMCS13FBK:4;
987 UINT32 HTMCS12FBK:4;
988 UINT32 HTMCS11FBK:4;
989 UINT32 HTMCS10FBK:4;
990 UINT32 HTMCS9FBK:4;
991 UINT32 HTMCS8FBK:4;
992 } field;
993 UINT32 word;
994} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
995#else
996typedef union _HT_FBK_CFG1_STRUC {
997 struct {
998 UINT32 HTMCS8FBK:4;
999 UINT32 HTMCS9FBK:4;
1000 UINT32 HTMCS10FBK:4;
1001 UINT32 HTMCS11FBK:4;
1002 UINT32 HTMCS12FBK:4;
1003 UINT32 HTMCS13FBK:4;
1004 UINT32 HTMCS14FBK:4;
1005 UINT32 HTMCS15FBK:4;
1006 } field;
1007 UINT32 word;
1008} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
1009#endif
1010#define LG_FBK_CFG0 0x135c
1011#ifdef RT_BIG_ENDIAN
1012typedef union _LG_FBK_CFG0_STRUC {
1013 struct {
1014 UINT32 OFDMMCS7FBK:4; //initial value is 6
1015 UINT32 OFDMMCS6FBK:4; //initial value is 5
1016 UINT32 OFDMMCS5FBK:4; //initial value is 4
1017 UINT32 OFDMMCS4FBK:4; //initial value is 3
1018 UINT32 OFDMMCS3FBK:4; //initial value is 2
1019 UINT32 OFDMMCS2FBK:4; //initial value is 1
1020 UINT32 OFDMMCS1FBK:4; //initial value is 0
1021 UINT32 OFDMMCS0FBK:4; //initial value is 0
1022 } field;
1023 UINT32 word;
1024} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
1025#else
1026typedef union _LG_FBK_CFG0_STRUC {
1027 struct {
1028 UINT32 OFDMMCS0FBK:4; //initial value is 0
1029 UINT32 OFDMMCS1FBK:4; //initial value is 0
1030 UINT32 OFDMMCS2FBK:4; //initial value is 1
1031 UINT32 OFDMMCS3FBK:4; //initial value is 2
1032 UINT32 OFDMMCS4FBK:4; //initial value is 3
1033 UINT32 OFDMMCS5FBK:4; //initial value is 4
1034 UINT32 OFDMMCS6FBK:4; //initial value is 5
1035 UINT32 OFDMMCS7FBK:4; //initial value is 6
1036 } field;
1037 UINT32 word;
1038} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
1039#endif
1040#define LG_FBK_CFG1 0x1360
1041#ifdef RT_BIG_ENDIAN
1042typedef union _LG_FBK_CFG1_STRUC {
1043 struct {
1044 UINT32 rsv:16;
1045 UINT32 CCKMCS3FBK:4; //initial value is 2
1046 UINT32 CCKMCS2FBK:4; //initial value is 1
1047 UINT32 CCKMCS1FBK:4; //initial value is 0
1048 UINT32 CCKMCS0FBK:4; //initial value is 0
1049 } field;
1050 UINT32 word;
1051} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
1052#else
1053typedef union _LG_FBK_CFG1_STRUC {
1054 struct {
1055 UINT32 CCKMCS0FBK:4; //initial value is 0
1056 UINT32 CCKMCS1FBK:4; //initial value is 0
1057 UINT32 CCKMCS2FBK:4; //initial value is 1
1058 UINT32 CCKMCS3FBK:4; //initial value is 2
1059 UINT32 rsv:16;
1060 } field;
1061 UINT32 word;
1062} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
1063#endif
1064
1065//=======================================================
1066//================ Protection Paramater================================
1067//=======================================================
1068#define CCK_PROT_CFG 0x1364 //CCK Protection
1069#define ASIC_SHORTNAV 1
1070#define ASIC_LONGNAV 2
1071#define ASIC_RTS 1
1072#define ASIC_CTS 2
1073#ifdef RT_BIG_ENDIAN
1074typedef union _PROT_CFG_STRUC {
1075 struct {
1076 UINT32 rsv:5;
1077 UINT32 RTSThEn:1; //RTS threshold enable on CCK TX
1078 UINT32 TxopAllowGF40:1; //CCK TXOP allowance.0:disallow.
1079 UINT32 TxopAllowGF20:1; //CCK TXOP allowance.0:disallow.
1080 UINT32 TxopAllowMM40:1; //CCK TXOP allowance.0:disallow.
1081 UINT32 TxopAllowMM20:1; //CCK TXOP allowance. 0:disallow.
1082 UINT32 TxopAllowOfdm:1; //CCK TXOP allowance.0:disallow.
1083 UINT32 TxopAllowCck:1; //CCK TXOP allowance.0:disallow.
1084 UINT32 ProtectNav:2; //TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv
1085 UINT32 ProtectCtrl:2; //Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
1086 UINT32 ProtectRate:16; //Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
1087 } field;
1088 UINT32 word;
1089} PROT_CFG_STRUC, *PPROT_CFG_STRUC;
1090#else
1091typedef union _PROT_CFG_STRUC {
1092 struct {
1093 UINT32 ProtectRate:16; //Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
1094 UINT32 ProtectCtrl:2; //Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
1095 UINT32 ProtectNav:2; //TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv
1096 UINT32 TxopAllowCck:1; //CCK TXOP allowance.0:disallow.
1097 UINT32 TxopAllowOfdm:1; //CCK TXOP allowance.0:disallow.
1098 UINT32 TxopAllowMM20:1; //CCK TXOP allowance. 0:disallow.
1099 UINT32 TxopAllowMM40:1; //CCK TXOP allowance.0:disallow.
1100 UINT32 TxopAllowGF20:1; //CCK TXOP allowance.0:disallow.
1101 UINT32 TxopAllowGF40:1; //CCK TXOP allowance.0:disallow.
1102 UINT32 RTSThEn:1; //RTS threshold enable on CCK TX
1103 UINT32 rsv:5;
1104 } field;
1105 UINT32 word;
1106} PROT_CFG_STRUC, *PPROT_CFG_STRUC;
1107#endif
1108
1109#define OFDM_PROT_CFG 0x1368 //OFDM Protection
1110#define MM20_PROT_CFG 0x136C //MM20 Protection
1111#define MM40_PROT_CFG 0x1370 //MM40 Protection
1112#define GF20_PROT_CFG 0x1374 //GF20 Protection
1113#define GF40_PROT_CFG 0x1378 //GR40 Protection
1114#define EXP_CTS_TIME 0x137C //
1115#define EXP_ACK_TIME 0x1380 //
1116
1117//
1118// 4.4 MAC RX configuration registers (offset:0x1400)
1119//
1120#define RX_FILTR_CFG 0x1400 //TXRX_CSR0
1121#define AUTO_RSP_CFG 0x1404 //TXRX_CSR4
1122//
1123// TXRX_CSR4: Auto-Responder/
1124//
1125#ifdef RT_BIG_ENDIAN
1126typedef union _AUTO_RSP_CFG_STRUC {
1127 struct {
1128 UINT32 :24;
1129 UINT32 AckCtsPsmBit:1; // Power bit value in conrtrol frame
1130 UINT32 DualCTSEn:1; // Power bit value in conrtrol frame
1131 UINT32 rsv:1; // Power bit value in conrtrol frame
1132 UINT32 AutoResponderPreamble:1; // 0:long, 1:short preamble
1133 UINT32 CTS40MRef:1; // Response CTS 40MHz duplicate mode
1134 UINT32 CTS40MMode:1; // Response CTS 40MHz duplicate mode
1135 UINT32 BACAckPolicyEnable:1; // 0:long, 1:short preamble
1136 UINT32 AutoResponderEnable:1;
1137 } field;
1138 UINT32 word;
1139} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
1140#else
1141typedef union _AUTO_RSP_CFG_STRUC {
1142 struct {
1143 UINT32 AutoResponderEnable:1;
1144 UINT32 BACAckPolicyEnable:1; // 0:long, 1:short preamble
1145 UINT32 CTS40MMode:1; // Response CTS 40MHz duplicate mode
1146 UINT32 CTS40MRef:1; // Response CTS 40MHz duplicate mode
1147 UINT32 AutoResponderPreamble:1; // 0:long, 1:short preamble
1148 UINT32 rsv:1; // Power bit value in conrtrol frame
1149 UINT32 DualCTSEn:1; // Power bit value in conrtrol frame
1150 UINT32 AckCtsPsmBit:1; // Power bit value in conrtrol frame
1151 UINT32 :24;
1152 } field;
1153 UINT32 word;
1154} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
1155#endif
1156
1157#define LEGACY_BASIC_RATE 0x1408 // TXRX_CSR5 0x3054
1158#define HT_BASIC_RATE 0x140c
1159#define HT_CTRL_CFG 0x1410
1160#define SIFS_COST_CFG 0x1414
1161#define RX_PARSER_CFG 0x1418 //Set NAV for all received frames
1162
1163//
1164// 4.5 MAC Security configuration (offset:0x1500)
1165//
1166#define TX_SEC_CNT0 0x1500 //
1167#define RX_SEC_CNT0 0x1504 //
1168#define CCMP_FC_MUTE 0x1508 //
1169//
1170// 4.6 HCCA/PSMP (offset:0x1600)
1171//
1172#define TXOP_HLDR_ADDR0 0x1600
1173#define TXOP_HLDR_ADDR1 0x1604
1174#define TXOP_HLDR_ET 0x1608
1175#define QOS_CFPOLL_RA_DW0 0x160c
1176#define QOS_CFPOLL_A1_DW1 0x1610
1177#define QOS_CFPOLL_QC 0x1614
1178//
1179// 4.7 MAC Statistis registers (offset:0x1700)
1180//
1181#define RX_STA_CNT0 0x1700 //
1182#define RX_STA_CNT1 0x1704 //
1183#define RX_STA_CNT2 0x1708 //
1184
1185//
1186// RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count
1187//
1188#ifdef RT_BIG_ENDIAN
1189typedef union _RX_STA_CNT0_STRUC {
1190 struct {
1191 USHORT PhyErr;
1192 USHORT CrcErr;
1193 } field;
1194 UINT32 word;
1195} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
1196#else
1197typedef union _RX_STA_CNT0_STRUC {
1198 struct {
1199 USHORT CrcErr;
1200 USHORT PhyErr;
1201 } field;
1202 UINT32 word;
1203} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
1204#endif
1205
1206//
1207// RX_STA_CNT1_STRUC: RX False CCA count & RX LONG frame count
1208//
1209#ifdef RT_BIG_ENDIAN
1210typedef union _RX_STA_CNT1_STRUC {
1211 struct {
1212 USHORT PlcpErr;
1213 USHORT FalseCca;
1214 } field;
1215 UINT32 word;
1216} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
1217#else
1218typedef union _RX_STA_CNT1_STRUC {
1219 struct {
1220 USHORT FalseCca;
1221 USHORT PlcpErr;
1222 } field;
1223 UINT32 word;
1224} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
1225#endif
1226
1227//
1228// RX_STA_CNT2_STRUC:
1229//
1230#ifdef RT_BIG_ENDIAN
1231typedef union _RX_STA_CNT2_STRUC {
1232 struct {
1233 USHORT RxFifoOverflowCount;
1234 USHORT RxDupliCount;
1235 } field;
1236 UINT32 word;
1237} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
1238#else
1239typedef union _RX_STA_CNT2_STRUC {
1240 struct {
1241 USHORT RxDupliCount;
1242 USHORT RxFifoOverflowCount;
1243 } field;
1244 UINT32 word;
1245} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
1246#endif
1247#define TX_STA_CNT0 0x170C //
1248//
1249// STA_CSR3: TX Beacon count
1250//
1251#ifdef RT_BIG_ENDIAN
1252typedef union _TX_STA_CNT0_STRUC {
1253 struct {
1254 USHORT TxBeaconCount;
1255 USHORT TxFailCount;
1256 } field;
1257 UINT32 word;
1258} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
1259#else
1260typedef union _TX_STA_CNT0_STRUC {
1261 struct {
1262 USHORT TxFailCount;
1263 USHORT TxBeaconCount;
1264 } field;
1265 UINT32 word;
1266} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
1267#endif
1268#define TX_STA_CNT1 0x1710 //
1269//
1270// TX_STA_CNT1: TX tx count
1271//
1272#ifdef RT_BIG_ENDIAN
1273typedef union _TX_STA_CNT1_STRUC {
1274 struct {
1275 USHORT TxRetransmit;
1276 USHORT TxSuccess;
1277 } field;
1278 UINT32 word;
1279} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
1280#else
1281typedef union _TX_STA_CNT1_STRUC {
1282 struct {
1283 USHORT TxSuccess;
1284 USHORT TxRetransmit;
1285 } field;
1286 UINT32 word;
1287} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
1288#endif
1289#define TX_STA_CNT2 0x1714 //
1290//
1291// TX_STA_CNT2: TX tx count
1292//
1293#ifdef RT_BIG_ENDIAN
1294typedef union _TX_STA_CNT2_STRUC {
1295 struct {
1296 USHORT TxUnderFlowCount;
1297 USHORT TxZeroLenCount;
1298 } field;
1299 UINT32 word;
1300} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
1301#else
1302typedef union _TX_STA_CNT2_STRUC {
1303 struct {
1304 USHORT TxZeroLenCount;
1305 USHORT TxUnderFlowCount;
1306 } field;
1307 UINT32 word;
1308} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
1309#endif
1310#define TX_STA_FIFO 0x1718 //
1311//
1312// TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register
1313//
1314#ifdef RT_BIG_ENDIAN
1315typedef union PACKED _TX_STA_FIFO_STRUC {
1316 struct {
1317 UINT32 Reserve:2;
1318 UINT32 TxBF:1; // 3*3
1319 UINT32 SuccessRate:13; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
1320// UINT32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
1321 UINT32 wcid:8; //wireless client index
1322 UINT32 TxAckRequired:1; // ack required
1323 UINT32 TxAggre:1; // Tx is aggregated
1324 UINT32 TxSuccess:1; // Tx success. whether success or not
1325 UINT32 PidType:4;
1326 UINT32 bValid:1; // 1:This register contains a valid TX result
1327 } field;
1328 UINT32 word;
1329} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
1330#else
1331typedef union PACKED _TX_STA_FIFO_STRUC {
1332 struct {
1333 UINT32 bValid:1; // 1:This register contains a valid TX result
1334 UINT32 PidType:4;
1335 UINT32 TxSuccess:1; // Tx No retry success
1336 UINT32 TxAggre:1; // Tx Retry Success
1337 UINT32 TxAckRequired:1; // Tx fail
1338 UINT32 wcid:8; //wireless client index
1339// UINT32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
1340 UINT32 SuccessRate:13; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
1341 UINT32 TxBF:1;
1342 UINT32 Reserve:2;
1343 } field;
1344 UINT32 word;
1345} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
1346#endif
1347// Debug counter
1348#define TX_AGG_CNT 0x171c
1349#ifdef RT_BIG_ENDIAN
1350typedef union _TX_AGG_CNT_STRUC {
1351 struct {
1352 USHORT AggTxCount;
1353 USHORT NonAggTxCount;
1354 } field;
1355 UINT32 word;
1356} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
1357#else
1358typedef union _TX_AGG_CNT_STRUC {
1359 struct {
1360 USHORT NonAggTxCount;
1361 USHORT AggTxCount;
1362 } field;
1363 UINT32 word;
1364} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
1365#endif
1366// Debug counter
1367#define TX_AGG_CNT0 0x1720
1368#ifdef RT_BIG_ENDIAN
1369typedef union _TX_AGG_CNT0_STRUC {
1370 struct {
1371 USHORT AggSize2Count;
1372 USHORT AggSize1Count;
1373 } field;
1374 UINT32 word;
1375} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
1376#else
1377typedef union _TX_AGG_CNT0_STRUC {
1378 struct {
1379 USHORT AggSize1Count;
1380 USHORT AggSize2Count;
1381 } field;
1382 UINT32 word;
1383} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
1384#endif
1385// Debug counter
1386#define TX_AGG_CNT1 0x1724
1387#ifdef RT_BIG_ENDIAN
1388typedef union _TX_AGG_CNT1_STRUC {
1389 struct {
1390 USHORT AggSize4Count;
1391 USHORT AggSize3Count;
1392 } field;
1393 UINT32 word;
1394} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
1395#else
1396typedef union _TX_AGG_CNT1_STRUC {
1397 struct {
1398 USHORT AggSize3Count;
1399 USHORT AggSize4Count;
1400 } field;
1401 UINT32 word;
1402} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
1403#endif
1404#define TX_AGG_CNT2 0x1728
1405#ifdef RT_BIG_ENDIAN
1406typedef union _TX_AGG_CNT2_STRUC {
1407 struct {
1408 USHORT AggSize6Count;
1409 USHORT AggSize5Count;
1410 } field;
1411 UINT32 word;
1412} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
1413#else
1414typedef union _TX_AGG_CNT2_STRUC {
1415 struct {
1416 USHORT AggSize5Count;
1417 USHORT AggSize6Count;
1418 } field;
1419 UINT32 word;
1420} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
1421#endif
1422// Debug counter
1423#define TX_AGG_CNT3 0x172c
1424#ifdef RT_BIG_ENDIAN
1425typedef union _TX_AGG_CNT3_STRUC {
1426 struct {
1427 USHORT AggSize8Count;
1428 USHORT AggSize7Count;
1429 } field;
1430 UINT32 word;
1431} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
1432#else
1433typedef union _TX_AGG_CNT3_STRUC {
1434 struct {
1435 USHORT AggSize7Count;
1436 USHORT AggSize8Count;
1437 } field;
1438 UINT32 word;
1439} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
1440#endif
1441// Debug counter
1442#define TX_AGG_CNT4 0x1730
1443#ifdef RT_BIG_ENDIAN
1444typedef union _TX_AGG_CNT4_STRUC {
1445 struct {
1446 USHORT AggSize10Count;
1447 USHORT AggSize9Count;
1448 } field;
1449 UINT32 word;
1450} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
1451#else
1452typedef union _TX_AGG_CNT4_STRUC {
1453 struct {
1454 USHORT AggSize9Count;
1455 USHORT AggSize10Count;
1456 } field;
1457 UINT32 word;
1458} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
1459#endif
1460#define TX_AGG_CNT5 0x1734
1461#ifdef RT_BIG_ENDIAN
1462typedef union _TX_AGG_CNT5_STRUC {
1463 struct {
1464 USHORT AggSize12Count;
1465 USHORT AggSize11Count;
1466 } field;
1467 UINT32 word;
1468} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
1469#else
1470typedef union _TX_AGG_CNT5_STRUC {
1471 struct {
1472 USHORT AggSize11Count;
1473 USHORT AggSize12Count;
1474 } field;
1475 UINT32 word;
1476} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
1477#endif
1478#define TX_AGG_CNT6 0x1738
1479#ifdef RT_BIG_ENDIAN
1480typedef union _TX_AGG_CNT6_STRUC {
1481 struct {
1482 USHORT AggSize14Count;
1483 USHORT AggSize13Count;
1484 } field;
1485 UINT32 word;
1486} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
1487#else
1488typedef union _TX_AGG_CNT6_STRUC {
1489 struct {
1490 USHORT AggSize13Count;
1491 USHORT AggSize14Count;
1492 } field;
1493 UINT32 word;
1494} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
1495#endif
1496#define TX_AGG_CNT7 0x173c
1497#ifdef RT_BIG_ENDIAN
1498typedef union _TX_AGG_CNT7_STRUC {
1499 struct {
1500 USHORT AggSize16Count;
1501 USHORT AggSize15Count;
1502 } field;
1503 UINT32 word;
1504} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
1505#else
1506typedef union _TX_AGG_CNT7_STRUC {
1507 struct {
1508 USHORT AggSize15Count;
1509 USHORT AggSize16Count;
1510 } field;
1511 UINT32 word;
1512} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
1513#endif
1514#define MPDU_DENSITY_CNT 0x1740
1515#ifdef RT_BIG_ENDIAN
1516typedef union _MPDU_DEN_CNT_STRUC {
1517 struct {
1518 USHORT RXZeroDelCount; //RX zero length delimiter count
1519 USHORT TXZeroDelCount; //TX zero length delimiter count
1520 } field;
1521 UINT32 word;
1522} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
1523#else
1524typedef union _MPDU_DEN_CNT_STRUC {
1525 struct {
1526 USHORT TXZeroDelCount; //TX zero length delimiter count
1527 USHORT RXZeroDelCount; //RX zero length delimiter count
1528 } field;
1529 UINT32 word;
1530} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
1531#endif
1532//
1533// TXRX control registers - base address 0x3000
1534//
1535// rt2860b UNKNOWN reg use R/O Reg Addr 0x77d0 first..
1536#define TXRX_CSR1 0x77d0
1537
1538//
1539// Security key table memory, base address = 0x1000
1540//
1541#define MAC_WCID_BASE 0x1800 //8-bytes(use only 6-bytes) * 256 entry =
1542#define HW_WCID_ENTRY_SIZE 8
1543#define PAIRWISE_KEY_TABLE_BASE 0x4000 // 32-byte * 256-entry = -byte
1544#define HW_KEY_ENTRY_SIZE 0x20
1545#define PAIRWISE_IVEIV_TABLE_BASE 0x6000 // 8-byte * 256-entry = -byte
1546#define MAC_IVEIV_TABLE_BASE 0x6000 // 8-byte * 256-entry = -byte
1547#define HW_IVEIV_ENTRY_SIZE 8
1548#define MAC_WCID_ATTRIBUTE_BASE 0x6800 // 4-byte * 256-entry = -byte
1549#define HW_WCID_ATTRI_SIZE 4
1550#define WCID_RESERVED 0x6bfc
1551#define SHARED_KEY_TABLE_BASE 0x6c00 // 32-byte * 16-entry = 512-byte
1552#define SHARED_KEY_MODE_BASE 0x7000 // 32-byte * 16-entry = 512-byte
1553#define HW_SHARED_KEY_MODE_SIZE 4
1554#define SHAREDKEYTABLE 0
1555#define PAIRWISEKEYTABLE 1
1556
1557
1558#ifdef RT_BIG_ENDIAN
1559typedef union _SHAREDKEY_MODE_STRUC {
1560 struct {
1561 UINT32 :1;
1562 UINT32 Bss1Key3CipherAlg:3;
1563 UINT32 :1;
1564 UINT32 Bss1Key2CipherAlg:3;
1565 UINT32 :1;
1566 UINT32 Bss1Key1CipherAlg:3;
1567 UINT32 :1;
1568 UINT32 Bss1Key0CipherAlg:3;
1569 UINT32 :1;
1570 UINT32 Bss0Key3CipherAlg:3;
1571 UINT32 :1;
1572 UINT32 Bss0Key2CipherAlg:3;
1573 UINT32 :1;
1574 UINT32 Bss0Key1CipherAlg:3;
1575 UINT32 :1;
1576 UINT32 Bss0Key0CipherAlg:3;
1577 } field;
1578 UINT32 word;
1579} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
1580#else
1581typedef union _SHAREDKEY_MODE_STRUC {
1582 struct {
1583 UINT32 Bss0Key0CipherAlg:3;
1584 UINT32 :1;
1585 UINT32 Bss0Key1CipherAlg:3;
1586 UINT32 :1;
1587 UINT32 Bss0Key2CipherAlg:3;
1588 UINT32 :1;
1589 UINT32 Bss0Key3CipherAlg:3;
1590 UINT32 :1;
1591 UINT32 Bss1Key0CipherAlg:3;
1592 UINT32 :1;
1593 UINT32 Bss1Key1CipherAlg:3;
1594 UINT32 :1;
1595 UINT32 Bss1Key2CipherAlg:3;
1596 UINT32 :1;
1597 UINT32 Bss1Key3CipherAlg:3;
1598 UINT32 :1;
1599 } field;
1600 UINT32 word;
1601} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
1602#endif
1603// 64-entry for pairwise key table
1604typedef struct _HW_WCID_ENTRY { // 8-byte per entry
1605 UCHAR Address[6];
1606 UCHAR Rsv[2];
1607} HW_WCID_ENTRY, PHW_WCID_ENTRY;
1608
1609
1610
1611//
1612// Other on-chip shared memory space, base = 0x2000
1613//
1614
1615// CIS space - base address = 0x2000
1616#define HW_CIS_BASE 0x2000
1617
1618// Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function.
1619#define HW_CS_CTS_BASE 0x7700
1620// DFS CTS frame base address. It's where mac stores CTS frame for DFS.
1621#define HW_DFS_CTS_BASE 0x7780
1622#define HW_CTS_FRAME_SIZE 0x80
1623
1624// 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes
1625// to save debugging settings
1626#define HW_DEBUG_SETTING_BASE 0x77f0 // 0x77f0~0x77ff total 16 bytes
1627#define HW_DEBUG_SETTING_BASE2 0x7770 // 0x77f0~0x77ff total 16 bytes
1628
1629#if 0
1630// on-chip BEACON frame space - base address = 0x7800
1631#define HW_BEACON_MAX_SIZE 0x0800 /* unit: byte */
1632#define HW_BEACON_BASE0 0x7800
1633#define HW_BEACON_BASE1 0x7900
1634#define HW_BEACON_BASE2 0x7a00
1635#define HW_BEACON_BASE3 0x7b00
1636#define HW_BEACON_BASE4 0x7c00
1637#define HW_BEACON_BASE5 0x7d00
1638#define HW_BEACON_BASE6 0x7e00
1639#define HW_BEACON_BASE7 0x7f00
1640/* 1. HW_BEACON_OFFSET/64B must be 0;
1641 2. BCN_OFFSET0 must also be changed in NICInitializeAsic();
1642 3. max 0x0800 for 8 beacon frames; */
1643#else
1644// In order to support maximum 8 MBSS and its maximum length is 512 for each beacon
1645// Three section discontinue memory segments will be used.
1646// 1. The original region for BCN 0~3
1647// 2. Extract memory from FCE table for BCN 4~5
1648// 3. Extract memory from Pair-wise key table for BCN 6~7
1649// It occupied those memory of wcid 238~253 for BCN 6
1650// and wcid 222~237 for BCN 7
1651#define HW_BEACON_MAX_SIZE 0x1000 /* unit: byte */
1652#define HW_BEACON_BASE0 0x7800
1653#define HW_BEACON_BASE1 0x7A00
1654#define HW_BEACON_BASE2 0x7C00
1655#define HW_BEACON_BASE3 0x7E00
1656#define HW_BEACON_BASE4 0x7200
1657#define HW_BEACON_BASE5 0x7400
1658#define HW_BEACON_BASE6 0x5DC0
1659#define HW_BEACON_BASE7 0x5BC0
1660#endif
1661
1662#define HW_BEACON_MAX_COUNT 8
1663#define HW_BEACON_OFFSET 0x0200
1664#define HW_BEACON_CONTENT_LEN (HW_BEACON_OFFSET - TXWI_SIZE)
1665
1666// HOST-MCU shared memory - base address = 0x2100
1667#define HOST_CMD_CSR 0x404
1668#define H2M_MAILBOX_CSR 0x7010
1669#define H2M_MAILBOX_CID 0x7014
1670#define H2M_MAILBOX_STATUS 0x701c
1671#define H2M_INT_SRC 0x7024
1672#define H2M_BBP_AGENT 0x7028
1673#define M2H_CMD_DONE_CSR 0x000c
1674#define MCU_TXOP_ARRAY_BASE 0x000c // TODO: to be provided by Albert
1675#define MCU_TXOP_ENTRY_SIZE 32 // TODO: to be provided by Albert
1676#define MAX_NUM_OF_TXOP_ENTRY 16 // TODO: must be same with 8051 firmware
1677#define MCU_MBOX_VERSION 0x01 // TODO: to be confirmed by Albert
1678#define MCU_MBOX_VERSION_OFFSET 5 // TODO: to be provided by Albert
1679
1680//
1681// Host DMA registers - base address 0x200 . TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT,
1682//
1683//
1684// DMA RING DESCRIPTOR
1685//
1686#define E2PROM_CSR 0x0004
1687#define IO_CNTL_CSR 0x77d0
1688
1689#ifdef RT2870
1690// 8051 firmware image for usb - use last-half base address = 0x3000
1691#define FIRMWARE_IMAGE_BASE 0x3000
1692#define MAX_FIRMWARE_IMAGE_SIZE 0x1000 // 4kbyte
1693#endif // RT2870 //
1694
1695// TODO: ????? old RT2560 registers. to keep them or remove them?
1696//#define MCAST0 0x0178 // multicast filter register 0
1697//#define MCAST1 0x017c // multicast filter register 1
1698
1699
1700// ================================================================
1701// Tx / Rx / Mgmt ring descriptor definition
1702// ================================================================
1703
1704// the following PID values are used to mark outgoing frame type in TXD->PID so that
1705// proper TX statistics can be collected based on these categories
1706// b3-2 of PID field -
1707#define PID_MGMT 0x05
1708#define PID_BEACON 0x0c
1709#define PID_DATA_NORMALUCAST 0x02
1710#define PID_DATA_AMPDU 0x04
1711#define PID_DATA_NO_ACK 0x08
1712#define PID_DATA_NOT_NORM_ACK 0x03
1713#if 0
1714#define PTYPE_DATA_REQUIRE_ACK 0x00 // b7-6:00, b5-0: 0~59 is MAC table index (AID?), 60~63 is WDS index
1715#define PTYPE_NULL_AT_HIGH_RATE 0x04 // b7-6:01, b5-0: 0~59 is MAC table index (AID?), 60~63 is WDS index
1716#define PTYPE_RESERVED 0x08 // b7-6:10
1717#define PTYPE_SPECIAL 0x0c // b7-6:11
1718
1719// when b3-2=11 (PTYPE_SPECIAL), b1-0 coube be ...
1720#define PSUBTYPE_DATA_NO_ACK 0x00
1721#define PSUBTYPE_MGMT 0x01
1722#define PSUBTYPE_OTHER_CNTL 0x02
1723#define PSUBTYPE_RTS 0x03
1724#endif
1725// value domain of pTxD->HostQId (4-bit: 0~15)
1726#define QID_AC_BK 1 // meet ACI definition in 802.11e
1727#define QID_AC_BE 0 // meet ACI definition in 802.11e
1728#define QID_AC_VI 2
1729#define QID_AC_VO 3
1730#define QID_HCCA 4
1731#define NUM_OF_TX_RING 5
1732#define QID_MGMT 13
1733#define QID_RX 14
1734#define QID_OTHER 15
1735
1736
1737// ------------------------------------------------------
1738// BBP & RF definition
1739// ------------------------------------------------------
1740#define BUSY 1
1741#define IDLE 0
1742
1743#define RF_R00 0
1744#define RF_R01 1
1745#define RF_R02 2
1746#define RF_R03 3
1747#define RF_R04 4
1748#define RF_R05 5
1749#define RF_R06 6
1750#define RF_R07 7
1751#define RF_R08 8
1752#define RF_R09 9
1753#define RF_R10 10
1754#define RF_R11 11
1755#define RF_R12 12
1756#define RF_R13 13
1757#define RF_R14 14
1758#define RF_R15 15
1759#define RF_R16 16
1760#define RF_R17 17
1761#define RF_R18 18
1762#define RF_R19 19
1763#define RF_R20 20
1764#define RF_R21 21
1765#define RF_R22 22
1766#define RF_R23 23
1767#define RF_R24 24
1768#define RF_R25 25
1769#define RF_R26 26
1770#define RF_R27 27
1771#define RF_R28 28
1772#define RF_R29 29
1773#define RF_R30 30
1774#define RF_R31 31
1775
1776#define BBP_R0 0 // version
1777#define BBP_R1 1 // TSSI
1778#define BBP_R2 2 // TX configure
1779#define BBP_R3 3
1780#define BBP_R4 4
1781#define BBP_R5 5
1782#define BBP_R6 6
1783#define BBP_R14 14 // RX configure
1784#define BBP_R16 16
1785#define BBP_R17 17 // RX sensibility
1786#define BBP_R18 18
1787#define BBP_R21 21
1788#define BBP_R22 22
1789#define BBP_R24 24
1790#define BBP_R25 25
1791#define BBP_R49 49 //TSSI
1792#define BBP_R50 50
1793#define BBP_R51 51
1794#define BBP_R52 52
1795#define BBP_R55 55
1796#define BBP_R62 62 // Rx SQ0 Threshold HIGH
1797#define BBP_R63 63
1798#define BBP_R64 64
1799#define BBP_R65 65
1800#define BBP_R66 66
1801#define BBP_R67 67
1802#define BBP_R68 68
1803#define BBP_R69 69
1804#define BBP_R70 70 // Rx AGC SQ CCK Xcorr threshold
1805#define BBP_R73 73
1806#define BBP_R75 75
1807#define BBP_R77 77
1808#define BBP_R81 81
1809#define BBP_R82 82
1810#define BBP_R83 83
1811#define BBP_R84 84
1812#define BBP_R86 86
1813#define BBP_R91 91
1814#define BBP_R92 92
1815#define BBP_R94 94 // Tx Gain Control
1816#define BBP_R103 103
1817#define BBP_R105 105
1818#define BBP_R113 113
1819#define BBP_R114 114
1820#define BBP_R115 115
1821#define BBP_R116 116
1822#define BBP_R117 117
1823#define BBP_R118 118
1824#define BBP_R119 119
1825#define BBP_R120 120
1826#define BBP_R121 121
1827#define BBP_R122 122
1828#define BBP_R123 123
1829
1830
1831#define BBPR94_DEFAULT 0x06 // Add 1 value will gain 1db
1832
1833//#define PHY_TR_SWITCH_TIME 5 // usec
1834
1835//#define BBP_R17_LOW_SENSIBILITY 0x50
1836//#define BBP_R17_MID_SENSIBILITY 0x41
1837//#define BBP_R17_DYNAMIC_UP_BOUND 0x40
1838#define RSSI_FOR_VERY_LOW_SENSIBILITY -35
1839#define RSSI_FOR_LOW_SENSIBILITY -58
1840#define RSSI_FOR_MID_LOW_SENSIBILITY -80
1841#define RSSI_FOR_MID_SENSIBILITY -90
1842
1843//-------------------------------------------------------------------------
1844// EEPROM definition
1845//-------------------------------------------------------------------------
1846#define EEDO 0x08
1847#define EEDI 0x04
1848#define EECS 0x02
1849#define EESK 0x01
1850#define EERL 0x80
1851
1852#define EEPROM_WRITE_OPCODE 0x05
1853#define EEPROM_READ_OPCODE 0x06
1854#define EEPROM_EWDS_OPCODE 0x10
1855#define EEPROM_EWEN_OPCODE 0x13
1856
1857#define NUM_EEPROM_BBP_PARMS 19 // Include NIC Config 0, 1, CR, TX ALC step, BBPs
1858#define NUM_EEPROM_TX_G_PARMS 7
1859#define EEPROM_NIC1_OFFSET 0x34 // The address is from NIC config 0, not BBP register ID
1860#define EEPROM_NIC2_OFFSET 0x36 // The address is from NIC config 0, not BBP register ID
1861#define EEPROM_BBP_BASE_OFFSET 0xf0 // The address is from NIC config 0, not BBP register ID
1862#define EEPROM_G_TX_PWR_OFFSET 0x52
1863#define EEPROM_G_TX2_PWR_OFFSET 0x60
1864#define EEPROM_LED1_OFFSET 0x3c
1865#define EEPROM_LED2_OFFSET 0x3e
1866#define EEPROM_LED3_OFFSET 0x40
1867#define EEPROM_LNA_OFFSET 0x44
1868#define EEPROM_RSSI_BG_OFFSET 0x46
1869#define EEPROM_RSSI_A_OFFSET 0x4a
1870#define EEPROM_DEFINE_MAX_TXPWR 0x4e
1871#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G 0xde // 20MHZ 2.4G tx power.
1872#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G 0xee // 40MHZ 2.4G tx power.
1873#define EEPROM_TXPOWER_BYRATE_20MHZ_5G 0xfa // 20MHZ 5G tx power.
1874#define EEPROM_TXPOWER_BYRATE_40MHZ_5G 0x10a // 40MHZ 5G tx power.
1875#define EEPROM_A_TX_PWR_OFFSET 0x78
1876#define EEPROM_A_TX2_PWR_OFFSET 0xa6
1877//#define EEPROM_Japan_TX_PWR_OFFSET 0x90 // 802.11j
1878//#define EEPROM_Japan_TX2_PWR_OFFSET 0xbe
1879//#define EEPROM_TSSI_REF_OFFSET 0x54
1880//#define EEPROM_TSSI_DELTA_OFFSET 0x24
1881//#define EEPROM_CCK_TX_PWR_OFFSET 0x62
1882//#define EEPROM_CALIBRATE_OFFSET 0x7c
1883#define EEPROM_VERSION_OFFSET 0x02
1884#define EEPROM_FREQ_OFFSET 0x3a
1885#define EEPROM_TXPOWER_BYRATE 0xde // 20MHZ power.
1886#define EEPROM_TXPOWER_DELTA 0x50 // 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ.
1887#define VALID_EEPROM_VERSION 1
1888
1889// PairKeyMode definition
1890#define PKMODE_NONE 0
1891#define PKMODE_WEP64 1
1892#define PKMODE_WEP128 2
1893#define PKMODE_TKIP 3
1894#define PKMODE_AES 4
1895#define PKMODE_CKIP64 5
1896#define PKMODE_CKIP128 6
1897#define PKMODE_TKIP_NO_MIC 7 // MIC appended by driver: not a valid value in hardware key table
1898
1899// =================================================================================
1900// WCID format
1901// =================================================================================
1902//7.1 WCID ENTRY format : 8bytes
1903typedef struct _WCID_ENTRY_STRUC {
1904 UCHAR RXBABitmap7; // bit0 for TID8, bit7 for TID 15
1905 UCHAR RXBABitmap0; // bit0 for TID0, bit7 for TID 7
1906 UCHAR MAC[6]; // 0 for shared key table. 1 for pairwise key table
1907} WCID_ENTRY_STRUC, *PWCID_ENTRY_STRUC;
1908
1909//8.1.1 SECURITY KEY format : 8DW
1910// 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table
1911typedef struct _HW_KEY_ENTRY { // 32-byte per entry
1912 UCHAR Key[16];
1913 UCHAR TxMic[8];
1914 UCHAR RxMic[8];
1915} HW_KEY_ENTRY, *PHW_KEY_ENTRY;
1916
1917//8.1.2 IV/EIV format : 2DW
1918
1919//8.1.3 RX attribute entry format : 1DW
1920#ifdef RT_BIG_ENDIAN
1921typedef struct _MAC_ATTRIBUTE_STRUC {
1922 UINT32 rsv:22;
1923 UINT32 RXWIUDF:3;
1924 UINT32 BSSIDIdx:3; //multipleBSS index for the WCID
1925 UINT32 PairKeyMode:3;
1926 UINT32 KeyTab:1; // 0 for shared key table. 1 for pairwise key table
1927} MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
1928#else
1929typedef struct _MAC_ATTRIBUTE_STRUC {
1930 UINT32 KeyTab:1; // 0 for shared key table. 1 for pairwise key table
1931 UINT32 PairKeyMode:3;
1932 UINT32 BSSIDIdx:3; //multipleBSS index for the WCID
1933 UINT32 RXWIUDF:3;
1934 UINT32 rsv:22;
1935} MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
1936#endif
1937
1938
1939// =================================================================================
1940// TX / RX ring descriptor format
1941// =================================================================================
1942
1943// the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO.
1944// MAC block use this TXINFO to control the transmission behavior of this frame.
1945#define FIFO_MGMT 0
1946#define FIFO_HCCA 1
1947#define FIFO_EDCA 2
1948
1949//
1950// TX descriptor format, Tx ring, Mgmt Ring
1951//
1952#ifdef RT_BIG_ENDIAN
1953typedef struct PACKED _TXD_STRUC {
1954 // Word 0
1955 UINT32 SDPtr0;
1956 // Word 1
1957 UINT32 DMADONE:1;
1958 UINT32 LastSec0:1;
1959 UINT32 SDLen0:14;
1960 UINT32 Burst:1;
1961 UINT32 LastSec1:1;
1962 UINT32 SDLen1:14;
1963 // Word 2
1964 UINT32 SDPtr1;
1965 // Word 3
1966 UINT32 ICO:1;
1967 UINT32 UCO:1;
1968 UINT32 TCO:1;
1969 UINT32 rsv:2;
1970 UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
1971 UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
1972 UINT32 rsv2:24;
1973} TXD_STRUC, *PTXD_STRUC;
1974#else
1975typedef struct PACKED _TXD_STRUC {
1976 // Word 0
1977 UINT32 SDPtr0;
1978 // Word 1
1979 UINT32 SDLen1:14;
1980 UINT32 LastSec1:1;
1981 UINT32 Burst:1;
1982 UINT32 SDLen0:14;
1983 UINT32 LastSec0:1;
1984 UINT32 DMADONE:1;
1985 //Word2
1986 UINT32 SDPtr1;
1987 //Word3
1988 UINT32 rsv2:24;
1989 UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
1990 UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
1991 UINT32 rsv:2;
1992 UINT32 TCO:1; //
1993 UINT32 UCO:1; //
1994 UINT32 ICO:1; //
1995} TXD_STRUC, *PTXD_STRUC;
1996#endif
1997
1998
1999//
2000// TXD Wireless Information format for Tx ring and Mgmt Ring
2001//
2002//txop : for txop mode
2003// 0:txop for the MPDU frame will be handles by ASIC by register
2004// 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS
2005#ifdef RT_BIG_ENDIAN
2006typedef struct PACKED _TXWI_STRUC {
2007 // Word 0
2008 UINT32 PHYMODE:2;
2009 UINT32 TxBF:1; // 3*3
2010 UINT32 rsv2:1;
2011// UINT32 rsv2:2;
2012 UINT32 Ifs:1; //
2013 UINT32 STBC:2; //channel bandwidth 20MHz or 40 MHz
2014 UINT32 ShortGI:1;
2015 UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
2016 UINT32 MCS:7;
2017
2018 UINT32 rsv:6;
2019 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.
2020 UINT32 MpduDensity:3;
2021 UINT32 AMPDU:1;
2022
2023 UINT32 TS:1;
2024 UINT32 CFACK:1;
2025 UINT32 MIMOps:1; // the remote peer is in dynamic MIMO-PS mode
2026 UINT32 FRAG:1; // 1 to inform TKIP engine this is a fragment.
2027 // Word 1
2028 UINT32 PacketId:4;
2029 UINT32 MPDUtotalByteCount:12;
2030 UINT32 WirelessCliID:8;
2031 UINT32 BAWinSize:6;
2032 UINT32 NSEQ:1;
2033 UINT32 ACK:1;
2034 // Word 2
2035 UINT32 IV;
2036 // Word 3
2037 UINT32 EIV;
2038} TXWI_STRUC, *PTXWI_STRUC;
2039#else
2040typedef struct PACKED _TXWI_STRUC {
2041 // Word 0
2042 UINT32 FRAG:1; // 1 to inform TKIP engine this is a fragment.
2043 UINT32 MIMOps:1; // the remote peer is in dynamic MIMO-PS mode
2044 UINT32 CFACK:1;
2045 UINT32 TS:1;
2046
2047 UINT32 AMPDU:1;
2048 UINT32 MpduDensity:3;
2049 UINT32 txop:2; //FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
2050 UINT32 rsv:6;
2051
2052 UINT32 MCS:7;
2053 UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
2054 UINT32 ShortGI:1;
2055 UINT32 STBC:2; // 1: STBC support MCS =0-7, 2,3 : RESERVE
2056 UINT32 Ifs:1; //
2057// UINT32 rsv2:2; //channel bandwidth 20MHz or 40 MHz
2058 UINT32 rsv2:1;
2059 UINT32 TxBF:1; // 3*3
2060 UINT32 PHYMODE:2;
2061 // Word 1
2062 UINT32 ACK:1;
2063 UINT32 NSEQ:1;
2064 UINT32 BAWinSize:6;
2065 UINT32 WirelessCliID:8;
2066 UINT32 MPDUtotalByteCount:12;
2067 UINT32 PacketId:4;
2068 //Word2
2069 UINT32 IV;
2070 //Word3
2071 UINT32 EIV;
2072} TXWI_STRUC, *PTXWI_STRUC;
2073#endif
2074//
2075// Rx descriptor format, Rx Ring
2076//
2077//
2078// RXWI wireless information format, in PBF. invisible in driver.
2079//
2080#ifdef RT_BIG_ENDIAN
2081typedef struct PACKED _RXWI_STRUC {
2082 // Word 0
2083 UINT32 TID:4;
2084 UINT32 MPDUtotalByteCount:12;
2085 UINT32 UDF:3;
2086 UINT32 BSSID:3;
2087 UINT32 KeyIndex:2;
2088 UINT32 WirelessCliID:8;
2089 // Word 1
2090 UINT32 PHYMODE:2; // 1: this RX frame is unicast to me
2091 UINT32 rsv:3;
2092 UINT32 STBC:2;
2093 UINT32 ShortGI:1;
2094 UINT32 BW:1;
2095 UINT32 MCS:7;
2096 UINT32 SEQUENCE:12;
2097 UINT32 FRAG:4;
2098 // Word 2
2099 UINT32 rsv1:8;
2100 UINT32 RSSI2:8;
2101 UINT32 RSSI1:8;
2102 UINT32 RSSI0:8;
2103 // Word 3
2104 UINT32 rsv2:16;
2105 UINT32 SNR1:8;
2106 UINT32 SNR0:8;
2107} RXWI_STRUC, *PRXWI_STRUC;
2108#else
2109typedef struct PACKED _RXWI_STRUC {
2110 // Word 0
2111 UINT32 WirelessCliID:8;
2112 UINT32 KeyIndex:2;
2113 UINT32 BSSID:3;
2114 UINT32 UDF:3;
2115 UINT32 MPDUtotalByteCount:12;
2116 UINT32 TID:4;
2117 // Word 1
2118 UINT32 FRAG:4;
2119 UINT32 SEQUENCE:12;
2120 UINT32 MCS:7;
2121 UINT32 BW:1;
2122 UINT32 ShortGI:1;
2123 UINT32 STBC:2;
2124 UINT32 rsv:3;
2125 UINT32 PHYMODE:2; // 1: this RX frame is unicast to me
2126 //Word2
2127 UINT32 RSSI0:8;
2128 UINT32 RSSI1:8;
2129 UINT32 RSSI2:8;
2130 UINT32 rsv1:8;
2131 //Word3
2132 UINT32 SNR0:8;
2133 UINT32 SNR1:8;
2134 UINT32 rsv2:16;
2135} RXWI_STRUC, *PRXWI_STRUC;
2136#endif
2137
2138
2139// =================================================================================
2140// HOST-MCU communication data structure
2141// =================================================================================
2142
2143//
2144// H2M_MAILBOX_CSR: Host-to-MCU Mailbox
2145//
2146#ifdef RT_BIG_ENDIAN
2147typedef union _H2M_MAILBOX_STRUC {
2148 struct {
2149 UINT32 Owner:8;
2150 UINT32 CmdToken:8; // 0xff tells MCU not to report CmdDoneInt after excuting the command
2151 UINT32 HighByte:8;
2152 UINT32 LowByte:8;
2153 } field;
2154 UINT32 word;
2155} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
2156#else
2157typedef union _H2M_MAILBOX_STRUC {
2158 struct {
2159 UINT32 LowByte:8;
2160 UINT32 HighByte:8;
2161 UINT32 CmdToken:8;
2162 UINT32 Owner:8;
2163 } field;
2164 UINT32 word;
2165} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
2166#endif
2167
2168//
2169// M2H_CMD_DONE_CSR: MCU-to-Host command complete indication
2170//
2171#ifdef RT_BIG_ENDIAN
2172typedef union _M2H_CMD_DONE_STRUC {
2173 struct {
2174 UINT32 CmdToken3;
2175 UINT32 CmdToken2;
2176 UINT32 CmdToken1;
2177 UINT32 CmdToken0;
2178 } field;
2179 UINT32 word;
2180} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
2181#else
2182typedef union _M2H_CMD_DONE_STRUC {
2183 struct {
2184 UINT32 CmdToken0;
2185 UINT32 CmdToken1;
2186 UINT32 CmdToken2;
2187 UINT32 CmdToken3;
2188 } field;
2189 UINT32 word;
2190} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
2191#endif
2192
2193
2194
2195//
2196// MCU_LEDCS: MCU LED Control Setting.
2197//
2198#ifdef RT_BIG_ENDIAN
2199typedef union _MCU_LEDCS_STRUC {
2200 struct {
2201 UCHAR Polarity:1;
2202 UCHAR LedMode:7;
2203 } field;
2204 UCHAR word;
2205} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
2206#else
2207typedef union _MCU_LEDCS_STRUC {
2208 struct {
2209 UCHAR LedMode:7;
2210 UCHAR Polarity:1;
2211 } field;
2212 UCHAR word;
2213} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
2214#endif
2215// =================================================================================
2216// Register format
2217// =================================================================================
2218
2219
2220
2221//NAV_TIME_CFG :NAV
2222#ifdef RT_BIG_ENDIAN
2223typedef union _NAV_TIME_CFG_STRUC {
2224 struct {
2225 USHORT rsv:6;
2226 USHORT ZeroSifs:1; // Applied zero SIFS timer after OFDM RX 0: disable
2227 USHORT Eifs:9; // in unit of 1-us
2228 UCHAR SlotTime; // in unit of 1-us
2229 UCHAR Sifs; // in unit of 1-us
2230 } field;
2231 UINT32 word;
2232} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
2233#else
2234typedef union _NAV_TIME_CFG_STRUC {
2235 struct {
2236 UCHAR Sifs; // in unit of 1-us
2237 UCHAR SlotTime; // in unit of 1-us
2238 USHORT Eifs:9; // in unit of 1-us
2239 USHORT ZeroSifs:1; // Applied zero SIFS timer after OFDM RX 0: disable
2240 USHORT rsv:6;
2241 } field;
2242 UINT32 word;
2243} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
2244#endif
2245
2246
2247
2248
2249
2250//
2251// RX_FILTR_CFG: /RX configuration register
2252//
2253#ifdef RT_BIG_ENDIAN
2254typedef union RX_FILTR_CFG_STRUC {
2255 struct {
2256 UINT32 :15;
2257 UINT32 DropRsvCntlType:1;
2258
2259 UINT32 DropBAR:1; //
2260 UINT32 DropBA:1; //
2261 UINT32 DropPsPoll:1; // Drop Ps-Poll
2262 UINT32 DropRts:1; // Drop Ps-Poll
2263
2264 UINT32 DropCts:1; // Drop Ps-Poll
2265 UINT32 DropAck:1; // Drop Ps-Poll
2266 UINT32 DropCFEnd:1; // Drop Ps-Poll
2267 UINT32 DropCFEndAck:1; // Drop Ps-Poll
2268
2269 UINT32 DropDuplicate:1; // Drop duplicate frame
2270 UINT32 DropBcast:1; // Drop broadcast frames
2271 UINT32 DropMcast:1; // Drop multicast frames
2272 UINT32 DropVerErr:1; // Drop version error frame
2273
2274 UINT32 DropNotMyBSSID:1; // Drop fram ToDs bit is true
2275 UINT32 DropNotToMe:1; // Drop not to me unicast frame
2276 UINT32 DropPhyErr:1; // Drop physical error
2277 UINT32 DropCRCErr:1; // Drop CRC error
2278 } field;
2279 UINT32 word;
2280} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
2281#else
2282typedef union _RX_FILTR_CFG_STRUC {
2283 struct {
2284 UINT32 DropCRCErr:1; // Drop CRC error
2285 UINT32 DropPhyErr:1; // Drop physical error
2286 UINT32 DropNotToMe:1; // Drop not to me unicast frame
2287 UINT32 DropNotMyBSSID:1; // Drop fram ToDs bit is true
2288
2289 UINT32 DropVerErr:1; // Drop version error frame
2290 UINT32 DropMcast:1; // Drop multicast frames
2291 UINT32 DropBcast:1; // Drop broadcast frames
2292 UINT32 DropDuplicate:1; // Drop duplicate frame
2293
2294 UINT32 DropCFEndAck:1; // Drop Ps-Poll
2295 UINT32 DropCFEnd:1; // Drop Ps-Poll
2296 UINT32 DropAck:1; // Drop Ps-Poll
2297 UINT32 DropCts:1; // Drop Ps-Poll
2298
2299 UINT32 DropRts:1; // Drop Ps-Poll
2300 UINT32 DropPsPoll:1; // Drop Ps-Poll
2301 UINT32 DropBA:1; //
2302 UINT32 DropBAR:1; //
2303
2304 UINT32 DropRsvCntlType:1;
2305 UINT32 :15;
2306 } field;
2307 UINT32 word;
2308} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
2309#endif
2310
2311
2312
2313
2314//
2315// PHY_CSR4: RF serial control register
2316//
2317#ifdef RT_BIG_ENDIAN
2318typedef union _PHY_CSR4_STRUC {
2319 struct {
2320 UINT32 Busy:1; // 1: ASIC is busy execute RF programming.
2321 UINT32 PLL_LD:1; // RF PLL_LD status
2322 UINT32 IFSelect:1; // 1: select IF to program, 0: select RF to program
2323 UINT32 NumberOfBits:5; // Number of bits used in RFRegValue (I:20, RFMD:22)
2324 UINT32 RFRegValue:24; // Register value (include register id) serial out to RF/IF chip.
2325 } field;
2326 UINT32 word;
2327} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
2328#else
2329typedef union _PHY_CSR4_STRUC {
2330 struct {
2331 UINT32 RFRegValue:24; // Register value (include register id) serial out to RF/IF chip.
2332 UINT32 NumberOfBits:5; // Number of bits used in RFRegValue (I:20, RFMD:22)
2333 UINT32 IFSelect:1; // 1: select IF to program, 0: select RF to program
2334 UINT32 PLL_LD:1; // RF PLL_LD status
2335 UINT32 Busy:1; // 1: ASIC is busy execute RF programming.
2336 } field;
2337 UINT32 word;
2338} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
2339#endif
2340
2341
2342//
2343// SEC_CSR5: shared key table security mode register
2344//
2345#ifdef RT_BIG_ENDIAN
2346typedef union _SEC_CSR5_STRUC {
2347 struct {
2348 UINT32 :1;
2349 UINT32 Bss3Key3CipherAlg:3;
2350 UINT32 :1;
2351 UINT32 Bss3Key2CipherAlg:3;
2352 UINT32 :1;
2353 UINT32 Bss3Key1CipherAlg:3;
2354 UINT32 :1;
2355 UINT32 Bss3Key0CipherAlg:3;
2356 UINT32 :1;
2357 UINT32 Bss2Key3CipherAlg:3;
2358 UINT32 :1;
2359 UINT32 Bss2Key2CipherAlg:3;
2360 UINT32 :1;
2361 UINT32 Bss2Key1CipherAlg:3;
2362 UINT32 :1;
2363 UINT32 Bss2Key0CipherAlg:3;
2364 } field;
2365 UINT32 word;
2366} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
2367#else
2368typedef union _SEC_CSR5_STRUC {
2369 struct {
2370 UINT32 Bss2Key0CipherAlg:3;
2371 UINT32 :1;
2372 UINT32 Bss2Key1CipherAlg:3;
2373 UINT32 :1;
2374 UINT32 Bss2Key2CipherAlg:3;
2375 UINT32 :1;
2376 UINT32 Bss2Key3CipherAlg:3;
2377 UINT32 :1;
2378 UINT32 Bss3Key0CipherAlg:3;
2379 UINT32 :1;
2380 UINT32 Bss3Key1CipherAlg:3;
2381 UINT32 :1;
2382 UINT32 Bss3Key2CipherAlg:3;
2383 UINT32 :1;
2384 UINT32 Bss3Key3CipherAlg:3;
2385 UINT32 :1;
2386 } field;
2387 UINT32 word;
2388} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
2389#endif
2390
2391
2392//
2393// HOST_CMD_CSR: For HOST to interrupt embedded processor
2394//
2395#ifdef RT_BIG_ENDIAN
2396typedef union _HOST_CMD_CSR_STRUC {
2397 struct {
2398 UINT32 Rsv:24;
2399 UINT32 HostCommand:8;
2400 } field;
2401 UINT32 word;
2402} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
2403#else
2404typedef union _HOST_CMD_CSR_STRUC {
2405 struct {
2406 UINT32 HostCommand:8;
2407 UINT32 Rsv:24;
2408 } field;
2409 UINT32 word;
2410} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
2411#endif
2412
2413
2414//
2415// AIFSN_CSR: AIFSN for each EDCA AC
2416//
2417
2418
2419
2420//
2421// E2PROM_CSR: EEPROM control register
2422//
2423#ifdef RT_BIG_ENDIAN
2424typedef union _E2PROM_CSR_STRUC {
2425 struct {
2426 UINT32 Rsvd:25;
2427 UINT32 LoadStatus:1; // 1:loading, 0:done
2428 UINT32 Type:1; // 1: 93C46, 0:93C66
2429 UINT32 EepromDO:1;
2430 UINT32 EepromDI:1;
2431 UINT32 EepromCS:1;
2432 UINT32 EepromSK:1;
2433 UINT32 Reload:1; // Reload EEPROM content, write one to reload, self-cleared.
2434 } field;
2435 UINT32 word;
2436} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
2437#else
2438typedef union _E2PROM_CSR_STRUC {
2439 struct {
2440 UINT32 Reload:1; // Reload EEPROM content, write one to reload, self-cleared.
2441 UINT32 EepromSK:1;
2442 UINT32 EepromCS:1;
2443 UINT32 EepromDI:1;
2444 UINT32 EepromDO:1;
2445 UINT32 Type:1; // 1: 93C46, 0:93C66
2446 UINT32 LoadStatus:1; // 1:loading, 0:done
2447 UINT32 Rsvd:25;
2448 } field;
2449 UINT32 word;
2450} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
2451#endif
2452
2453
2454// -------------------------------------------------------------------
2455// E2PROM data layout
2456// -------------------------------------------------------------------
2457
2458//
2459// EEPROM antenna select format
2460//
2461#ifdef RT_BIG_ENDIAN
2462typedef union _EEPROM_ANTENNA_STRUC {
2463 struct {
2464 USHORT Rsv:4;
2465 USHORT RfIcType:4; // see E2PROM document
2466 USHORT TxPath:4; // 1: 1T, 2: 2T
2467 USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R
2468 } field;
2469 USHORT word;
2470} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
2471#else
2472typedef union _EEPROM_ANTENNA_STRUC {
2473 struct {
2474 USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R
2475 USHORT TxPath:4; // 1: 1T, 2: 2T
2476 USHORT RfIcType:4; // see E2PROM document
2477 USHORT Rsv:4;
2478 } field;
2479 USHORT word;
2480} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
2481#endif
2482
2483#ifdef RT_BIG_ENDIAN
2484typedef union _EEPROM_NIC_CINFIG2_STRUC {
2485 struct {
2486 USHORT Rsv2:6; // must be 0
2487 USHORT BW40MAvailForA:1; // 0:enable, 1:disable
2488 USHORT BW40MAvailForG:1; // 0:enable, 1:disable
2489 USHORT EnableWPSPBC:1; // WPS PBC Control bit
2490 USHORT BW40MSidebandForA:1;
2491 USHORT BW40MSidebandForG:1;
2492 USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable
2493 USHORT ExternalLNAForA:1; // external LNA enable for 5G
2494 USHORT ExternalLNAForG:1; // external LNA enable for 2.4G
2495 USHORT DynamicTxAgcControl:1; //
2496 USHORT HardwareRadioControl:1; // Whether RF is controlled by driver or HW. 1:enable hw control, 0:disable
2497 } field;
2498 USHORT word;
2499} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
2500#else
2501typedef union _EEPROM_NIC_CINFIG2_STRUC {
2502 struct {
2503 USHORT HardwareRadioControl:1; // 1:enable, 0:disable
2504 USHORT DynamicTxAgcControl:1; //
2505 USHORT ExternalLNAForG:1; //
2506 USHORT ExternalLNAForA:1; // external LNA enable for 2.4G
2507 USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable
2508 USHORT BW40MSidebandForG:1;
2509 USHORT BW40MSidebandForA:1;
2510 USHORT EnableWPSPBC:1; // WPS PBC Control bit
2511 USHORT BW40MAvailForG:1; // 0:enable, 1:disable
2512 USHORT BW40MAvailForA:1; // 0:enable, 1:disable
2513 USHORT Rsv2:6; // must be 0
2514 } field;
2515 USHORT word;
2516} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
2517#endif
2518
2519//
2520// TX_PWR Value valid range 0xFA(-6) ~ 0x24(36)
2521//
2522#ifdef RT_BIG_ENDIAN
2523typedef union _EEPROM_TX_PWR_STRUC {
2524 struct {
2525 CHAR Byte1; // High Byte
2526 CHAR Byte0; // Low Byte
2527 } field;
2528 USHORT word;
2529} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
2530#else
2531typedef union _EEPROM_TX_PWR_STRUC {
2532 struct {
2533 CHAR Byte0; // Low Byte
2534 CHAR Byte1; // High Byte
2535 } field;
2536 USHORT word;
2537} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
2538#endif
2539
2540#ifdef RT_BIG_ENDIAN
2541typedef union _EEPROM_VERSION_STRUC {
2542 struct {
2543 UCHAR Version; // High Byte
2544 UCHAR FaeReleaseNumber; // Low Byte
2545 } field;
2546 USHORT word;
2547} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
2548#else
2549typedef union _EEPROM_VERSION_STRUC {
2550 struct {
2551 UCHAR FaeReleaseNumber; // Low Byte
2552 UCHAR Version; // High Byte
2553 } field;
2554 USHORT word;
2555} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
2556#endif
2557
2558#ifdef RT_BIG_ENDIAN
2559typedef union _EEPROM_LED_STRUC {
2560 struct {
2561 USHORT Rsvd:3; // Reserved
2562 USHORT LedMode:5; // Led mode.
2563 USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting.
2564 USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting.
2565 USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting.
2566 USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting.
2567 USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting.
2568 USHORT PolarityACT:1; // Polarity ACT setting.
2569 USHORT PolarityRDY_A:1; // Polarity RDY_A setting.
2570 USHORT PolarityRDY_G:1; // Polarity RDY_G setting.
2571 } field;
2572 USHORT word;
2573} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
2574#else
2575typedef union _EEPROM_LED_STRUC {
2576 struct {
2577 USHORT PolarityRDY_G:1; // Polarity RDY_G setting.
2578 USHORT PolarityRDY_A:1; // Polarity RDY_A setting.
2579 USHORT PolarityACT:1; // Polarity ACT setting.
2580 USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting.
2581 USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting.
2582 USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting.
2583 USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting.
2584 USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting.
2585 USHORT LedMode:5; // Led mode.
2586 USHORT Rsvd:3; // Reserved
2587 } field;
2588 USHORT word;
2589} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
2590#endif
2591
2592#ifdef RT_BIG_ENDIAN
2593typedef union _EEPROM_TXPOWER_DELTA_STRUC {
2594 struct {
2595 UCHAR TxPowerEnable:1;// Enable
2596 UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value
2597 UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4)
2598 } field;
2599 UCHAR value;
2600} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
2601#else
2602typedef union _EEPROM_TXPOWER_DELTA_STRUC {
2603 struct {
2604 UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4)
2605 UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value
2606 UCHAR TxPowerEnable:1;// Enable
2607 } field;
2608 UCHAR value;
2609} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
2610#endif
2611
2612//
2613// QOS_CSR0: TXOP holder address0 register
2614//
2615#ifdef RT_BIG_ENDIAN
2616typedef union _QOS_CSR0_STRUC {
2617 struct {
2618 UCHAR Byte3; // MAC address byte 3
2619 UCHAR Byte2; // MAC address byte 2
2620 UCHAR Byte1; // MAC address byte 1
2621 UCHAR Byte0; // MAC address byte 0
2622 } field;
2623 UINT32 word;
2624} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
2625#else
2626typedef union _QOS_CSR0_STRUC {
2627 struct {
2628 UCHAR Byte0; // MAC address byte 0
2629 UCHAR Byte1; // MAC address byte 1
2630 UCHAR Byte2; // MAC address byte 2
2631 UCHAR Byte3; // MAC address byte 3
2632 } field;
2633 UINT32 word;
2634} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
2635#endif
2636
2637//
2638// QOS_CSR1: TXOP holder address1 register
2639//
2640#ifdef RT_BIG_ENDIAN
2641typedef union _QOS_CSR1_STRUC {
2642 struct {
2643 UCHAR Rsvd1;
2644 UCHAR Rsvd0;
2645 UCHAR Byte5; // MAC address byte 5
2646 UCHAR Byte4; // MAC address byte 4
2647 } field;
2648 UINT32 word;
2649} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
2650#else
2651typedef union _QOS_CSR1_STRUC {
2652 struct {
2653 UCHAR Byte4; // MAC address byte 4
2654 UCHAR Byte5; // MAC address byte 5
2655 UCHAR Rsvd0;
2656 UCHAR Rsvd1;
2657 } field;
2658 UINT32 word;
2659} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
2660#endif
2661
2662#define RF_CSR_CFG 0x500
2663#ifdef RT_BIG_ENDIAN
2664typedef union _RF_CSR_CFG_STRUC {
2665 struct {
2666 UINT Rsvd1:14; // Reserved
2667 UINT RF_CSR_KICK:1; // kick RF register read/write
2668 UINT RF_CSR_WR:1; // 0: read 1: write
2669 UINT Rsvd2:3; // Reserved
2670 UINT TESTCSR_RFACC_REGNUM:5; // RF register ID
2671 UINT RF_CSR_DATA:8; // DATA
2672 } field;
2673 UINT word;
2674} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
2675#else
2676typedef union _RF_CSR_CFG_STRUC {
2677 struct {
2678 UINT RF_CSR_DATA:8; // DATA
2679 UINT TESTCSR_RFACC_REGNUM:5; // RF register ID
2680 UINT Rsvd2:3; // Reserved
2681 UINT RF_CSR_WR:1; // 0: read 1: write
2682 UINT RF_CSR_KICK:1; // kick RF register read/write
2683 UINT Rsvd1:14; // Reserved
2684 } field;
2685 UINT word;
2686} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
2687#endif
2688
2689#endif // __RT28XX_H__
diff --git a/drivers/staging/rt2870/rt_ate.c b/drivers/staging/rt2870/rt_ate.c
new file mode 100644
index 00000000000..e99b3da0b62
--- /dev/null
+++ b/drivers/staging/rt2870/rt_ate.c
@@ -0,0 +1,6452 @@
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#ifdef RALINK_ATE
35UCHAR 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
36extern RTMP_RF_REGS RF2850RegTable[];
37extern UCHAR NUM_OF_2850_CHNL;
38
39#ifdef RT2870
40extern UCHAR EpToQueue[];
41extern VOID RTUSBRejectPendingPackets( IN PRTMP_ADAPTER pAd);
42#endif // RT2870 //
43
44#ifdef UCOS
45extern INT ConsoleResponse(IN PUCHAR buff);
46extern int (*remote_display)(char *);
47#endif // UCOS //
48
49static CHAR CCKRateTable[] = {0, 1, 2, 3, 8, 9, 10, 11, -1}; /* CCK Mode. */
50static CHAR OFDMRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, -1}; /* OFDM Mode. */
51static CHAR HTMIXRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}; /* HT Mix Mode. */
52
53static INT TxDmaBusy(
54 IN PRTMP_ADAPTER pAd);
55
56static INT RxDmaBusy(
57 IN PRTMP_ADAPTER pAd);
58
59static VOID RtmpDmaEnable(
60 IN PRTMP_ADAPTER pAd,
61 IN INT Enable);
62
63static VOID BbpSoftReset(
64 IN PRTMP_ADAPTER pAd);
65
66static VOID RtmpRfIoWrite(
67 IN PRTMP_ADAPTER pAd);
68
69static INT ATESetUpFrame(
70 IN PRTMP_ADAPTER pAd,
71 IN UINT32 TxIdx);
72
73static INT ATETxPwrHandler(
74 IN PRTMP_ADAPTER pAd,
75 IN char index);
76
77static INT ATECmdHandler(
78 IN PRTMP_ADAPTER pAd,
79 IN PUCHAR arg);
80
81static int CheckMCSValid(
82 IN UCHAR Mode,
83 IN UCHAR Mcs);
84
85
86#ifdef RT2870
87static VOID ATEWriteTxInfo(
88 IN PRTMP_ADAPTER pAd,
89 IN PTXINFO_STRUC pTxInfo,
90 IN USHORT USBDMApktLen,
91 IN BOOLEAN bWiv,
92 IN UCHAR QueueSel,
93 IN UCHAR NextValid,
94 IN UCHAR TxBurst);
95
96static VOID ATEWriteTxWI(
97 IN PRTMP_ADAPTER pAd,
98 IN PTXWI_STRUC pTxWI,
99 IN BOOLEAN FRAG,
100 IN BOOLEAN InsTimestamp,
101 IN BOOLEAN AMPDU,
102 IN BOOLEAN Ack,
103 IN BOOLEAN NSeq, // HW new a sequence.
104 IN UCHAR BASize,
105 IN UCHAR WCID,
106 IN ULONG Length,
107 IN UCHAR PID,
108 IN UCHAR MIMOps,
109 IN UCHAR Txopmode,
110 IN BOOLEAN CfAck,
111 IN HTTRANSMIT_SETTING Transmit);
112
113#endif // RT2870 //
114
115static VOID SetJapanFilter(
116 IN PRTMP_ADAPTER pAd);
117
118/*=========================end of prototype=========================*/
119
120
121#ifdef RT2870
122static INT TxDmaBusy(
123 IN PRTMP_ADAPTER pAd)
124{
125 INT result;
126 USB_DMA_CFG_STRUC UsbCfg;
127
128 RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
129 if (UsbCfg.field.TxBusy)
130 result = 1;
131 else
132 result = 0;
133
134 return result;
135}
136
137static INT RxDmaBusy(
138 IN PRTMP_ADAPTER pAd)
139{
140 INT result;
141 USB_DMA_CFG_STRUC UsbCfg;
142
143 RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
144 if (UsbCfg.field.RxBusy)
145 result = 1;
146 else
147 result = 0;
148
149 return result;
150}
151
152static VOID RtmpDmaEnable(
153 IN PRTMP_ADAPTER pAd,
154 IN INT Enable)
155{
156 BOOLEAN value;
157 ULONG WaitCnt;
158 USB_DMA_CFG_STRUC UsbCfg;
159
160 value = Enable > 0 ? 1 : 0;
161
162 // check DMA is in busy mode.
163 WaitCnt = 0;
164 while (TxDmaBusy(pAd) || RxDmaBusy(pAd))
165 {
166 RTMPusecDelay(10);
167 if (WaitCnt++ > 100)
168 break;
169 }
170
171 //Why not to clear USB DMA TX path first ???
172 RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
173 UsbCfg.field.TxBulkEn = value;
174 UsbCfg.field.RxBulkEn = value;
175 RTMP_IO_WRITE32(pAd, USB_DMA_CFG, UsbCfg.word); // abort all TX rings
176 RTMPusecDelay(5000);
177
178 return;
179}
180#endif // RT2870 //
181
182static VOID BbpSoftReset(
183 IN PRTMP_ADAPTER pAd)
184{
185 UCHAR BbpData = 0;
186
187 // Soft reset, set BBP R21 bit0=1->0
188 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
189 BbpData |= 0x00000001; //set bit0=1
190 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
191
192 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
193 BbpData &= ~(0x00000001); //set bit0=0
194 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
195
196 return;
197}
198
199static VOID RtmpRfIoWrite(
200 IN PRTMP_ADAPTER pAd)
201{
202 // Set RF value 1's set R3[bit2] = [0]
203 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
204 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
205 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
206 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
207
208 RTMPusecDelay(200);
209
210 // Set RF value 2's set R3[bit2] = [1]
211 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
212 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
213 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
214 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
215
216 RTMPusecDelay(200);
217
218 // Set RF value 3's set R3[bit2] = [0]
219 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
220 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
221 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
222 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
223
224 return;
225}
226
227static int CheckMCSValid(
228 UCHAR Mode,
229 UCHAR Mcs)
230{
231 int i;
232 PCHAR pRateTab;
233
234 switch(Mode)
235 {
236 case 0:
237 pRateTab = CCKRateTable;
238 break;
239 case 1:
240 pRateTab = OFDMRateTable;
241 break;
242 case 2:
243 case 3:
244 pRateTab = HTMIXRateTable;
245 break;
246 default:
247 ATEDBGPRINT(RT_DEBUG_ERROR, ("unrecognizable Tx Mode %d\n", Mode));
248 return -1;
249 break;
250 }
251
252 i = 0;
253 while(pRateTab[i] != -1)
254 {
255 if (pRateTab[i] == Mcs)
256 return 0;
257 i++;
258 }
259
260 return -1;
261}
262
263#if 1
264static INT ATETxPwrHandler(
265 IN PRTMP_ADAPTER pAd,
266 IN char index)
267{
268 ULONG R;
269 CHAR TxPower;
270 UCHAR Bbp94 = 0;
271 BOOLEAN bPowerReduce = FALSE;
272
273#ifdef RALINK_28xx_QA
274 if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
275 {
276 /* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
277 ** are not synchronized.
278 */
279/*
280 pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
281 pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
282*/
283 return 0;
284 }
285 else
286#endif // RALINK_28xx_QA //
287 {
288 TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
289
290 if (pAd->ate.Channel <= 14)
291 {
292 if (TxPower > 31)
293 {
294 //
295 // R3, R4 can't large than 31 (0x24), 31 ~ 36 used by BBP 94
296 //
297 R = 31;
298 if (TxPower <= 36)
299 Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
300 }
301 else if (TxPower < 0)
302 {
303 //
304 // R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
305 //
306 R = 0;
307 if (TxPower >= -6)
308 Bbp94 = BBPR94_DEFAULT + TxPower;
309 }
310 else
311 {
312 // 0 ~ 31
313 R = (ULONG) TxPower;
314 Bbp94 = BBPR94_DEFAULT;
315 }
316
317 ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
318 }
319 else// 5.5 GHz
320 {
321 if (TxPower > 15)
322 {
323 //
324 // R3, R4 can't large than 15 (0x0F)
325 //
326 R = 15;
327 }
328 else if (TxPower < 0)
329 {
330 //
331 // R3, R4 can't less than 0
332 //
333 // -1 ~ -7
334 ASSERT((TxPower >= -7));
335 R = (ULONG)(TxPower + 7);
336 bPowerReduce = TRUE;
337 }
338 else
339 {
340 // 0 ~ 15
341 R = (ULONG) TxPower;
342 }
343
344 ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%lu)\n", __FUNCTION__, TxPower, R));
345 }
346
347 if (pAd->ate.Channel <= 14)
348 {
349 if (index == 0)
350 {
351 R = R << 9; // shift TX power control to correct RF(R3) register bit position
352 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
353 pAd->LatchRfRegs.R3 = R;
354 }
355 else
356 {
357 R = R << 6; // shift TX power control to correct RF(R4) register bit position
358 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
359 pAd->LatchRfRegs.R4 = R;
360 }
361 }
362 else// 5.5GHz
363 {
364 if (bPowerReduce == FALSE)
365 {
366 if (index == 0)
367 {
368 R = (R << 10) | (1 << 9); // shift TX power control to correct RF(R3) register bit position
369 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
370 pAd->LatchRfRegs.R3 = R;
371 }
372 else
373 {
374 R = (R << 7) | (1 << 6); // shift TX power control to correct RF(R4) register bit position
375 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
376 pAd->LatchRfRegs.R4 = R;
377 }
378 }
379 else
380 {
381 if (index == 0)
382 {
383 R = (R << 10); // shift TX power control to correct RF(R3) register bit position
384 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
385
386 /* Clear bit 9 of R3 to reduce 7dB. */
387 pAd->LatchRfRegs.R3 = (R & (~(1 << 9)));
388 }
389 else
390 {
391 R = (R << 7); // shift TX power control to correct RF(R4) register bit position
392 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
393
394 /* Clear bit 6 of R4 to reduce 7dB. */
395 pAd->LatchRfRegs.R4 = (R & (~(1 << 6)));
396 }
397 }
398 }
399
400 RtmpRfIoWrite(pAd);
401
402 return 0;
403 }
404}
405#else// 1 //
406static INT ATETxPwrHandler(
407 IN PRTMP_ADAPTER pAd,
408 IN char index)
409{
410 ULONG R;
411 CHAR TxPower;
412 UCHAR Bbp94 = 0;
413
414#ifdef RALINK_28xx_QA
415 if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
416 {
417 // TODO: how to get current TxPower0/1 from pAd->LatchRfRegs ?
418 /* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
419 ** are not synchronized.
420 */
421/*
422 pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
423 pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
424*/
425 return 0;
426 }
427 else
428#endif // RALINK_28xx_QA //
429 {
430 TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
431
432 if (TxPower > 31)
433 {
434 //
435 // R3, R4 can't large than 36 (0x24), 31 ~ 36 used by BBP 94
436 //
437 R = 31;
438 if (TxPower <= 36)
439 Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
440 }
441 else if (TxPower < 0)
442 {
443 //
444 // R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
445 //
446 R = 0;
447 if (TxPower >= -6)
448 Bbp94 = BBPR94_DEFAULT + TxPower;
449 }
450 else
451 {
452 // 0 ~ 31
453 R = (ULONG) TxPower;
454 Bbp94 = BBPR94_DEFAULT;
455 }
456
457 ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R3=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
458
459 if (pAd->ate.Channel <= 14)
460 {
461 if (index == 0)
462 {
463 R = R << 9; // shift TX power control to correct RF(R3) register bit position
464 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
465 pAd->LatchRfRegs.R3 = R;
466 }
467 else
468 {
469 R = R << 6; // shift TX power control to correct RF(R4) register bit position
470 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
471 pAd->LatchRfRegs.R4 = R;
472 }
473 }
474 else
475 {
476 if (index == 0)
477 {
478 R = (R << 10) | (1 << 9); // shift TX power control to correct RF(R3) register bit position
479 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
480 pAd->LatchRfRegs.R3 = R;
481 }
482 else
483 {
484 R = (R << 7) | (1 << 6); // shift TX power control to correct RF(R4) register bit position
485 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
486 pAd->LatchRfRegs.R4 = R;
487 }
488 }
489
490 RtmpRfIoWrite(pAd);
491
492 return 0;
493 }
494}
495#endif // 1 //
496/*
497 ==========================================================================
498 Description:
499 Set ATE operation mode to
500 0. ATESTART = Start ATE Mode
501 1. ATESTOP = Stop ATE Mode
502 2. TXCONT = Continuous Transmit
503 3. TXCARR = Transmit Carrier
504 4. TXFRAME = Transmit Frames
505 5. RXFRAME = Receive Frames
506#ifdef RALINK_28xx_QA
507 6. TXSTOP = Stop Any Type of Transmition
508 7. RXSTOP = Stop Receiving Frames
509#endif // RALINK_28xx_QA //
510 Return:
511 TRUE if all parameters are OK, FALSE otherwise
512 ==========================================================================
513*/
514/* */
515/* */
516/*=======================End of RT2860=======================*/
517
518
519/*======================Start of RT2870======================*/
520/* */
521/* */
522
523#ifdef RT2870
524static INT ATECmdHandler(
525 IN PRTMP_ADAPTER pAd,
526 IN PUCHAR arg)
527{
528 UINT32 Value;
529 UCHAR BbpData;
530 UINT32 MacData;
531 UINT i=0, atemode;
532 //NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
533 //PUCHAR pDest;
534 UINT32 temp;
535 ULONG IrqFlags;
536
537 ATEDBGPRINT(RT_DEBUG_TRACE, ("===> ATECmdHandler()\n"));
538 ATEAsicSwitchChannel(pAd);
539 /* AsicLockChannel() is empty function so far in fact */
540 AsicLockChannel(pAd, pAd->ate.Channel);
541
542 RTMPusecDelay(5000);
543
544 // Default value in BBP R22 is 0x0.
545 BbpData = 0;
546
547 /* Enter ATE mode and set Tx/Rx Idle */
548 if (!strcmp(arg, "ATESTART"))
549 {
550#ifdef CONFIG_STA_SUPPORT
551 BOOLEAN Cancelled;
552#endif // CONFIG_STA_SUPPORT //
553 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: ATESTART\n"));
554
555 netif_stop_queue(pAd->net_dev);
556
557 atemode = pAd->ate.Mode;
558 pAd->ate.Mode = ATE_START;
559// pAd->ate.TxDoneCount = pAd->ate.TxCount;
560 // Disable Rx
561 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
562 Value &= ~(1 << 3);
563 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
564
565 // Disable auto responder
566 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp);
567 temp = temp & 0xFFFFFFFE;
568 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp);
569
570 // read MAC_SYS_CTRL and backup MAC_SYS_CTRL value.
571 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
572 // clean bit4 to stop continuous Tx production test.
573 MacData &= 0xFFFFFFEF;
574 // Stop continuous TX production test.
575 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);//disable or cancel pending irp first ???
576
577 if (atemode & ATE_TXCARR)
578 {
579 // No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
580 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
581 BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
582 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
583 }
584 else if (atemode & ATE_TXCARRSUPP)
585 {
586 // No Cont. TX set BBP R22 bit7=0
587 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
588 BbpData &= ~(1 << 7); //set bit7=0
589 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
590
591 // No Carrier Suppression set BBP R24 bit0=0
592 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
593 BbpData &= 0xFFFFFFFE; //clear bit0
594 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
595 }
596 // We should free some resource which allocate when ATE_TXFRAME , ATE_STOP, and ATE_TXCONT.
597 // TODO:Should we free some resource which was allocated when LoopBack and ATE_STOP ?
598 else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
599 {
600 if (atemode & ATE_TXCONT)
601 {
602 // Not Cont. TX anymore, so set BBP R22 bit7=0
603 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
604 BbpData &= ~(1 << 7); //set bit7=0
605 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
606 }
607 // Abort Tx, Rx DMA.
608 RtmpDmaEnable(pAd, 0);
609
610 {
611 // It seems nothing to free,
612 // because we didn't allocate any resource when we entered ATE_TXFRAME mode latestly.
613 }
614
615 // Start Tx, RX DMA
616 RtmpDmaEnable(pAd, 1);
617 }
618
619 RTUSBRejectPendingPackets(pAd);
620 RTUSBCleanUpDataBulkOutQueue(pAd);
621
622#ifdef CONFIG_STA_SUPPORT
623 //
624 // It will be called in MlmeSuspend().
625 //
626 // Cancel pending timers
627 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
628 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
629 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
630 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
631 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
632 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
633#endif // CONFIG_STA_SUPPORT //
634
635 //RTUSBCleanUpMLMEWaitQueue(pAd); /* not used in RT28xx */
636 RTUSBCleanUpMLMEBulkOutQueue(pAd);
637
638 // Sometimes kernel will hang on, so we avoid calling MlmeSuspend().
639// MlmeSuspend(pAd, TRUE);
640 //RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
641
642 // Disable Rx
643 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
644 Value &= ~(1 << 3);
645 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
646
647 // Abort Tx, RX DMA.
648 RtmpDmaEnable(pAd, 0);
649
650 // Disable Tx
651 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
652 Value &= ~(1 << 2);
653 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
654
655 // Make sure there are no pending bulk in/out IRPs before we go on.
656/*=========================================================================*/
657 /* pAd->PendingRx is not of type atomic_t anymore in 28xx */
658// while ((atomic_read(&pAd->PendingRx) > 0)) //pAd->BulkFlags != 0 wait bulk out finish
659 while ((pAd->PendingRx > 0)) //pAd->BulkFlags != 0 wait bulk out finish
660 {
661#if 1
662 ATE_RTUSBCancelPendingBulkInIRP(pAd);
663#else
664 NdisInterlockedDecrement(&pAd->PendingRx);
665#endif
666 /* delay 0.5 seconds */
667 RTMPusecDelay(500000);
668 pAd->PendingRx = 0;
669 }
670 /* peter : why don't we have to get BulkOutLock first ? */
671 while (((pAd->BulkOutPending[0] == TRUE) ||
672 (pAd->BulkOutPending[1] == TRUE) ||
673 (pAd->BulkOutPending[2] == TRUE) ||
674 (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
675 {
676 do
677 {
678 /* pAd->BulkOutPending[y] will be set to FALSE in RTUSBCancelPendingBulkOutIRP(pAd) */
679 RTUSBCancelPendingBulkOutIRP(pAd);
680 } while (FALSE);
681
682 /* we have enough time delay in RTUSBCancelPendingBulkOutIRP(pAd)
683 ** so this is not necessary
684 */
685// RTMPusecDelay(500000);
686 }
687
688 /* pAd->PendingRx is not of type atomic_t anymore in 28xx */
689// ASSERT(atomic_read(&pAd->PendingRx) == 0);
690 ASSERT(pAd->PendingRx == 0);
691/*=========================================================================*/
692
693 // reset Rx statistics.
694 pAd->ate.LastSNR0 = 0;
695 pAd->ate.LastSNR1 = 0;
696 pAd->ate.LastRssi0 = 0;
697 pAd->ate.LastRssi1 = 0;
698 pAd->ate.LastRssi2 = 0;
699 pAd->ate.AvgRssi0 = 0;
700 pAd->ate.AvgRssi1 = 0;
701 pAd->ate.AvgRssi2 = 0;
702 pAd->ate.AvgRssi0X8 = 0;
703 pAd->ate.AvgRssi1X8 = 0;
704 pAd->ate.AvgRssi2X8 = 0;
705 pAd->ate.NumOfAvgRssiSample = 0;
706
707#ifdef RALINK_28xx_QA
708 // Tx frame
709 pAd->ate.bQATxStart = FALSE;
710 pAd->ate.bQARxStart = FALSE;
711 pAd->ate.seq = 0;
712
713 // counters
714 pAd->ate.U2M = 0;
715 pAd->ate.OtherData = 0;
716 pAd->ate.Beacon = 0;
717 pAd->ate.OtherCount = 0;
718 pAd->ate.TxAc0 = 0;
719 pAd->ate.TxAc1 = 0;
720 pAd->ate.TxAc2 = 0;
721 pAd->ate.TxAc3 = 0;
722 pAd->ate.TxHCCA = 0;
723 pAd->ate.TxMgmt = 0;
724 pAd->ate.RSSI0 = 0;
725 pAd->ate.RSSI1 = 0;
726 pAd->ate.RSSI2 = 0;
727 pAd->ate.SNR0 = 0;
728 pAd->ate.SNR1 = 0;
729
730 // control
731 pAd->ate.TxDoneCount = 0;
732 pAd->ate.TxStatus = 0; // task Tx status // 0 --> task is idle, 1 --> task is running
733#endif // RALINK_28xx_QA //
734
735 // Soft reset BBP.
736 BbpSoftReset(pAd);
737
738
739#ifdef CONFIG_STA_SUPPORT
740 AsicDisableSync(pAd);
741
742 /*
743 ** If we skip "LinkDown()", we should disable protection
744 ** to prevent from sending out RTS or CTS-to-self.
745 */
746 ATEDisableAsicProtect(pAd);
747 RTMPStationStop(pAd);
748#endif // CONFIG_STA_SUPPORT //
749
750 // Default value in BBP R22 is 0x0.
751 BbpData = 0;
752 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
753
754 // Clean bit4 to stop continuous Tx production test.
755 MacData &= 0xFFFFFFEF;
756 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
757 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
758 //Clean ATE Bulk in/out counter and continue setup
759 InterlockedExchange(&pAd->BulkOutRemained, 0);
760
761 /* NdisAcquireSpinLock()/NdisReleaseSpinLock() need only one argument in RT28xx */
762 NdisAcquireSpinLock(&pAd->GenericLock);
763 pAd->ContinBulkOut = FALSE;
764 pAd->ContinBulkIn = FALSE;
765 NdisReleaseSpinLock(&pAd->GenericLock);
766
767 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
768 }
769 else if (!strcmp(arg, "ATESTOP"))
770 {
771 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE : ATESTOP ===>\n"));
772
773 // Default value in BBP R22 is 0x0.
774 BbpData = 0;
775 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);//0820
776 // Clean bit4 to stop continuous Tx production test.
777 MacData &= 0xFFFFFFEF;
778 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
779 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); // recover the MAC_SYS_CTRL register back.
780
781 // Disable Rx
782 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
783 Value &= ~(1 << 3);
784 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
785
786 /*
787 ** Abort Tx, RX DMA.
788 ** Q : How to do the following I/O if Tx, Rx DMA is aborted ?
789 ** Ans : Bulk endpoints are aborted, while the control endpoint is not.
790 */
791 RtmpDmaEnable(pAd, 0);
792
793 // Disable Tx
794 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
795 Value &= ~(1 << 2);
796 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
797
798 /* Make sure there are no pending bulk in/out IRPs before we go on. */
799/*=========================================================================*/
800// while ((atomic_read(&pAd->PendingRx) > 0)) //pAd->BulkFlags != 0 wait bulk out finish
801 while (pAd->PendingRx > 0)
802 {
803#if 1
804 ATE_RTUSBCancelPendingBulkInIRP(pAd);
805#else
806// NdisInterlockedDecrement(&pAd->PendingRx);
807 pAd->PendingRx--;
808#endif
809 RTMPusecDelay(500000);
810 }
811
812 while (((pAd->BulkOutPending[0] == TRUE) ||
813 (pAd->BulkOutPending[1] == TRUE) ||
814 (pAd->BulkOutPending[2] == TRUE) ||
815 (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
816 {
817 do
818 {
819 RTUSBCancelPendingBulkOutIRP(pAd);
820 } while (FALSE);
821
822 RTMPusecDelay(500000);
823 }
824
825// ASSERT(atomic_read(&pAd->PendingRx) == 0);
826 ASSERT(pAd->PendingRx == 0);
827/*=========================================================================*/
828/* Reset Rx RING */
829/*=========================================================================*/
830// InterlockedExchange(&pAd->PendingRx, 0);
831 pAd->PendingRx = 0;
832 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
833 pAd->NextRxBulkInIndex = RX_RING_SIZE - 1; // Rx Bulk pointer
834 pAd->NextRxBulkInPosition = 0;
835 for (i = 0; i < (RX_RING_SIZE); i++)
836 {
837 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
838 NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
839 /* peter : why don't we have to get BulkInLock first ? */
840 pRxContext->pAd = pAd;
841 pRxContext->pIrp = NULL;
842 /* peter debug ++ */
843 pRxContext->BulkInOffset = 0;
844 pRxContext->bRxHandling = FALSE;
845 /* peter debug -- */
846 pRxContext->InUse = FALSE;
847 pRxContext->IRPPending = FALSE;
848 pRxContext->Readable = FALSE;
849// pRxContext->ReorderInUse = FALSE;
850// pRxContext->ReadPosOffset = 0;
851 }
852
853/*=========================================================================*/
854/* Reset Tx RING */
855/*=========================================================================*/
856 do
857 {
858 RTUSBCancelPendingBulkOutIRP(pAd);
859 } while (FALSE);
860
861/*=========================================================================*/
862 // Enable auto responder.
863 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp);
864 temp = temp | (0x01);
865 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp);
866
867/*================================================*/
868 AsicEnableBssSync(pAd);
869
870 /* Soft reset BBP.*/
871 /* In 2870 chipset, ATE_BBP_IO_READ8_BY_REG_ID() == RTMP_BBP_IO_READ8_BY_REG_ID() */
872 /* Both rt2870ap and rt2870sta use BbpSoftReset(pAd) to do BBP soft reset */
873 BbpSoftReset(pAd);
874/*================================================*/
875 {
876#ifdef CONFIG_STA_SUPPORT
877 // Set all state machines back IDLE
878 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
879 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
880 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
881 pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
882 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
883 pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
884#endif // CONFIG_STA_SUPPORT //
885
886 //
887 // ===> refer to MlmeRestartStateMachine().
888 // When we entered ATE_START mode, PeriodicTimer was not cancelled.
889 // So we don't have to set it here.
890 //
891 //RTMPSetTimer(pAd, &pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
892
893 ASSERT(pAd->CommonCfg.Channel != 0);
894
895 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
896 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
897
898
899#ifdef CONFIG_STA_SUPPORT
900 RTMPStationStart(pAd);
901#endif // CONFIG_STA_SUPPORT //
902 }
903//
904// These two steps have been done when entering ATE_STOP mode.
905//
906#if 0
907 RTUSBWriteBBPRegister(pAd, BBP_R22, BbpData);
908 RTUSBWriteMACRegister(pAd, MAC_SYS_CTRL, MacData);
909#endif
910 // Clean ATE Bulk in/out counter and continue setup.
911 InterlockedExchange(&pAd->BulkOutRemained, 0);
912 NdisAcquireSpinLock(&pAd->GenericLock);
913 pAd->ContinBulkOut = FALSE;
914 pAd->ContinBulkIn = FALSE;
915 NdisReleaseSpinLock(&pAd->GenericLock);
916
917 /* Wait 50ms to prevent next URB to bulkout during HW reset. */
918 /* todo : remove this if not necessary */
919 NdisMSleep(50000);
920
921 pAd->ate.Mode = ATE_STOP;
922
923 // Enable Tx
924 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
925 Value |= (1 << 2);
926 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
927
928/*=========================================================================*/
929 /* restore RX_FILTR_CFG */
930#ifdef CONFIG_STA_SUPPORT
931 /* restore RX_FILTR_CFG in order that QA maybe set it to 0x3 */
932 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL);
933#endif // CONFIG_STA_SUPPORT //
934/*=========================================================================*/
935
936 // Enable Tx, RX DMA.
937 RtmpDmaEnable(pAd, 1);
938
939 // Enable Rx
940 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
941 Value |= (1 << 3);
942 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
943
944 // Wait 10ms to wait all of the bulk-in URBs to complete.
945 /* todo : remove this if not necessary */
946 NdisMSleep(10000);
947
948 // Everything is ready to start normal Tx/Rx.
949 RTUSBBulkReceive(pAd);
950 netif_start_queue(pAd->net_dev);
951
952 ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATE : ATESTOP \n"));
953 }
954 else if (!strcmp(arg, "TXCARR")) // Tx Carrier
955 {
956 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCARR\n"));
957 pAd->ate.Mode |= ATE_TXCARR;
958
959 // Disable Rx
960 // May be we need not to do this, because these have been done in ATE_START mode ???
961 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
962 Value &= ~(1 << 3);
963 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
964
965 // QA has done the following steps if it is used.
966 if (pAd->ate.bQATxStart == FALSE)
967 {
968 // Soft reset BBP.
969 BbpSoftReset(pAd);
970
971 // Carrier Test set BBP R22 bit7=1, bit6=1, bit[5~0]=0x01
972 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
973 BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
974 BbpData |= 0x000000C1; //set bit7=1, bit6=1, bit[5~0]=0x01
975 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
976
977 // set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1
978 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
979 Value = Value | 0x00000010;
980 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
981 }
982 }
983 else if (!strcmp(arg, "TXCONT")) // Tx Continue
984 {
985 if (pAd->ate.bQATxStart == TRUE)
986 {
987 /* set MAC_SYS_CTRL(0x1004) bit4(Continuous Tx Production Test)
988 and bit2(MAC TX enable) back to zero. */
989 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
990 MacData &= 0xFFFFFFEB;
991 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
992
993 // set BBP R22 bit7=0
994 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
995 BbpData &= 0xFFFFFF7F; //set bit7=0
996 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
997 }
998
999 /* for TxCont mode.
1000 ** Step 1: Send 50 packets first then wait for a moment.
1001 ** Step 2: Send more 50 packet then start continue mode.
1002 */
1003 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCONT\n"));
1004 // Step 1: send 50 packets first.
1005 pAd->ate.Mode |= ATE_TXCONT;
1006 pAd->ate.TxCount = 50;
1007 pAd->ate.TxDoneCount = 0;
1008
1009 // Soft reset BBP.
1010 BbpSoftReset(pAd);
1011
1012 // Abort Tx, RX DMA.
1013 RtmpDmaEnable(pAd, 0);
1014
1015
1016 /* Only needed if we have to send some normal frames. */
1017 SetJapanFilter(pAd);
1018
1019 // Setup frame format.
1020 ATESetUpFrame(pAd, 0);
1021
1022 // Enable Tx
1023 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1024 Value |= (1 << 2);
1025 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1026
1027 // Disable Rx
1028 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1029 Value &= ~(1 << 3);
1030 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1031
1032 // Start Tx, RX DMA.
1033 RtmpDmaEnable(pAd, 1);
1034
1035 InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
1036
1037#ifdef RALINK_28xx_QA
1038 if (pAd->ate.bQATxStart == TRUE)
1039 {
1040 pAd->ate.TxStatus = 1;
1041 //pAd->ate.Repeat = 0;
1042 }
1043#endif // RALINK_28xx_QA //
1044
1045 NdisAcquireSpinLock(&pAd->GenericLock);//0820
1046 pAd->ContinBulkOut = FALSE;
1047 NdisReleaseSpinLock(&pAd->GenericLock);
1048
1049 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
1050
1051 // Kick bulk out
1052 RTUSBKickBulkOut(pAd);
1053
1054 /* To make sure all the 50 frames have been bulk out before executing step 2 */
1055 while (atomic_read(&pAd->BulkOutRemained) > 0)
1056 {
1057 RTMPusecDelay(5000);
1058 }
1059
1060 // Step 2: send more 50 packets then start continue mode.
1061 // Abort Tx, RX DMA.
1062 RtmpDmaEnable(pAd, 0);
1063
1064 // Cont. TX set BBP R22 bit7=1
1065 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1066 BbpData |= 0x00000080; //set bit7=1
1067 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1068
1069 pAd->ate.TxCount = 50;
1070 pAd->ate.TxDoneCount = 0;
1071
1072 SetJapanFilter(pAd);
1073
1074 // Setup frame format.
1075 ATESetUpFrame(pAd, 0);
1076
1077 // Enable Tx
1078 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1079 Value |= (1 << 2);
1080 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1081
1082 // Disable Rx
1083 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1084 Value &= ~(1 << 3);
1085
1086 // Start Tx, RX DMA.
1087 RtmpDmaEnable(pAd, 1);
1088
1089 InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
1090
1091#ifdef RALINK_28xx_QA
1092 if (pAd->ate.bQATxStart == TRUE)
1093 {
1094 pAd->ate.TxStatus = 1;
1095 //pAd->ate.Repeat = 0;
1096 }
1097#endif // RALINK_28xx_QA //
1098
1099 NdisAcquireSpinLock(&pAd->GenericLock);//0820
1100 pAd->ContinBulkOut = FALSE;
1101 NdisReleaseSpinLock(&pAd->GenericLock);
1102
1103 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
1104 // Kick bulk out
1105 RTUSBKickBulkOut(pAd);
1106
1107#if 1
1108 RTMPusecDelay(500);
1109#else
1110 while (atomic_read(&pAd->BulkOutRemained) > 0)
1111 {
1112 RTMPusecDelay(5000);
1113 }
1114#endif // 1 //
1115
1116 // Set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1.
1117 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
1118 MacData |= 0x00000010;
1119 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
1120 }
1121 else if (!strcmp(arg, "TXFRAME")) // Tx Frames
1122 {
1123 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXFRAME(Count=0x%08x)\n", pAd->ate.TxCount));
1124 pAd->ate.Mode |= ATE_TXFRAME;
1125
1126 // Soft reset BBP.
1127 BbpSoftReset(pAd);
1128
1129 // Default value in BBP R22 is 0x0.
1130 BbpData = 0;
1131
1132 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
1133
1134 // Clean bit4 to stop continuous Tx production test.
1135 MacData &= 0xFFFFFFEF;
1136
1137 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1138 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
1139
1140#ifdef RALINK_28xx_QA
1141 // add this for LoopBack mode
1142 if (pAd->ate.bQARxStart == FALSE)
1143 {
1144 // Disable Rx
1145 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1146 Value &= ~(1 << 3);
1147 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1148 }
1149
1150 if (pAd->ate.bQATxStart == TRUE)
1151 {
1152 pAd->ate.TxStatus = 1;
1153 //pAd->ate.Repeat = 0;
1154 }
1155#else
1156 // Disable Rx
1157 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1158 Value &= ~(1 << 3);
1159 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1160#endif // RALINK_28xx_QA //
1161
1162 // Enable Tx
1163 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1164 Value |= (1 << 2);
1165 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1166
1167 SetJapanFilter(pAd);
1168
1169 // Abort Tx, RX DMA.
1170 RtmpDmaEnable(pAd, 0);
1171
1172 pAd->ate.TxDoneCount = 0;
1173
1174 // Setup frame format
1175 ATESetUpFrame(pAd, 0);
1176
1177 // Start Tx, RX DMA.
1178 RtmpDmaEnable(pAd, 1);
1179
1180 // Check count is continuous or not yet.
1181 //
1182 // Due to the type mismatch between "pAd->BulkOutRemained"(atomic_t) and "pAd->ate.TxCount"(UINT32)
1183 //
1184 if (pAd->ate.TxCount == 0)
1185 {
1186 InterlockedExchange(&pAd->BulkOutRemained, 0);
1187 }
1188 else
1189 {
1190 InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
1191 }
1192 ATEDBGPRINT(RT_DEBUG_TRACE, ("bulk out count = %d\n", atomic_read(&pAd->BulkOutRemained)));
1193 ASSERT((atomic_read(&pAd->BulkOutRemained) >= 0));
1194
1195 if (atomic_read(&pAd->BulkOutRemained) == 0)
1196 {
1197 ATEDBGPRINT(RT_DEBUG_TRACE, ("Send packet countinuously\n"));
1198
1199 /* In 28xx, NdisAcquireSpinLock() == spin_lock_bh() */
1200 /* NdisAcquireSpinLock only need one argument in 28xx. */
1201 NdisAcquireSpinLock(&pAd->GenericLock);
1202 pAd->ContinBulkOut = TRUE;
1203 NdisReleaseSpinLock(&pAd->GenericLock);
1204
1205 /* In 28xx, BULK_OUT_LOCK() == spin_lock_irqsave() */
1206 BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags);// peter : NdisAcquireSpinLock ==> BULK_OUT_LOCK
1207 pAd->BulkOutPending[0] = FALSE;
1208 BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);// peter : NdisAcquireSpinLock ==> BULK_OUT_LOCK
1209 }
1210 else
1211 {
1212 ATEDBGPRINT(RT_DEBUG_TRACE, ("Send packets depend on counter\n"));
1213
1214 NdisAcquireSpinLock(&pAd->GenericLock);
1215 pAd->ContinBulkOut = FALSE;
1216 NdisReleaseSpinLock(&pAd->GenericLock);
1217
1218 BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags);
1219 pAd->BulkOutPending[0] = FALSE;
1220 BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
1221 }
1222
1223 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
1224
1225 // Kick bulk out
1226 RTUSBKickBulkOut(pAd);
1227 }
1228#ifdef RALINK_28xx_QA
1229 else if (!strcmp(arg, "TXSTOP")) //Enter ATE mode and set Tx/Rx Idle
1230 {
1231 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXSTOP\n"));
1232
1233 atemode = pAd->ate.Mode;
1234 pAd->ate.Mode &= ATE_TXSTOP;
1235 pAd->ate.bQATxStart = FALSE;
1236// pAd->ate.TxDoneCount = pAd->ate.TxCount;
1237
1238/*=========================================================================*/
1239 if (atemode & ATE_TXCARR)
1240 {
1241 // No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
1242 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1243 BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
1244 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1245 }
1246 else if (atemode & ATE_TXCARRSUPP)
1247 {
1248 // No Cont. TX set BBP R22 bit7=0
1249 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1250 BbpData &= ~(1 << 7); //set bit7=0
1251 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1252
1253 // No Carrier Suppression set BBP R24 bit0=0
1254 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
1255 BbpData &= 0xFFFFFFFE; //clear bit0
1256 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
1257 }
1258 else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
1259 {
1260 if (atemode & ATE_TXCONT)
1261 {
1262 // No Cont. TX set BBP R22 bit7=0
1263 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1264 BbpData &= ~(1 << 7); //set bit7=0
1265 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1266 }
1267 }
1268
1269/*=========================================================================*/
1270 RTUSBRejectPendingPackets(pAd);
1271 RTUSBCleanUpDataBulkOutQueue(pAd);
1272
1273 /* not used in RT28xx */
1274 //RTUSBCleanUpMLMEWaitQueue(pAd);
1275 /* empty function so far */
1276 RTUSBCleanUpMLMEBulkOutQueue(pAd);
1277/*=========================================================================*/
1278 // Abort Tx, RX DMA.
1279 RtmpDmaEnable(pAd, 0);
1280/*=========================================================================*/
1281
1282 /* In 28xx, pAd->PendingRx is not of type atomic_t anymore */
1283// while ((atomic_read(&pAd->PendingRx) > 0)) //pAd->BulkFlags != 0 wait bulk out finish
1284 /* peter todo : BulkInLock */
1285 while (pAd->PendingRx > 0)
1286 {
1287#if 1
1288 ATE_RTUSBCancelPendingBulkInIRP(pAd);
1289#else
1290// NdisInterlockedDecrement(&pAd->PendingRx);
1291 pAd->PendingRx--;
1292#endif
1293 RTMPusecDelay(500000);
1294 }
1295
1296 while (((pAd->BulkOutPending[0] == TRUE) ||
1297 (pAd->BulkOutPending[1] == TRUE) ||
1298 (pAd->BulkOutPending[2] == TRUE) ||
1299 (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
1300 {
1301 do
1302 {
1303 RTUSBCancelPendingBulkOutIRP(pAd);
1304 } while (FALSE);
1305
1306 RTMPusecDelay(500000);
1307 }
1308
1309 ASSERT(pAd->PendingRx == 0);
1310/*=========================================================================*/
1311 // Enable Tx, Rx DMA.
1312 RtmpDmaEnable(pAd, 1);
1313
1314 /* task Tx status : 0 --> task is idle, 1 --> task is running */
1315 pAd->ate.TxStatus = 0;
1316
1317 // Soft reset BBP.
1318 BbpSoftReset(pAd);
1319
1320 // Disable Tx
1321 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
1322 MacData &= (0xfffffffb);
1323 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
1324
1325 //Clean ATE Bulk in/out counter and continue setup
1326 InterlockedExchange(&pAd->BulkOutRemained, 0);
1327
1328 pAd->ContinBulkOut = FALSE;
1329 }
1330 else if (!strcmp(arg, "RXSTOP"))
1331 {
1332 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXSTOP\n"));
1333 atemode = pAd->ate.Mode;
1334
1335 // Disable Rx
1336 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1337 Value &= ~(1 << 3);
1338 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1339
1340 pAd->ate.Mode &= ATE_RXSTOP;
1341 pAd->ate.bQARxStart = FALSE;
1342// pAd->ate.TxDoneCount = pAd->ate.TxCount;
1343
1344/*=========================================================================*/
1345 RTUSBRejectPendingPackets(pAd);
1346 RTUSBCleanUpDataBulkOutQueue(pAd);
1347
1348 /* not used in RT28xx */
1349 //RTUSBCleanUpMLMEWaitQueue(pAd);
1350 RTUSBCleanUpMLMEBulkOutQueue(pAd);
1351/*=========================================================================*/
1352
1353 // Abort Tx, RX DMA.
1354 RtmpDmaEnable(pAd, 0);
1355/*=========================================================================*/
1356// while ((atomic_read(&pAd->PendingRx) > 0))
1357 while (pAd->PendingRx > 0)
1358 {
1359#if 1
1360 ATE_RTUSBCancelPendingBulkInIRP(pAd);
1361#else
1362// NdisInterlockedDecrement(&pAd->PendingRx);
1363 pAd->PendingRx--;
1364#endif
1365 RTMPusecDelay(500000);
1366 }
1367
1368 while (((pAd->BulkOutPending[0] == TRUE) ||
1369 (pAd->BulkOutPending[1] == TRUE) ||
1370 (pAd->BulkOutPending[2] == TRUE) ||
1371 (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
1372 {
1373 do
1374 {
1375 RTUSBCancelPendingBulkOutIRP(pAd);
1376 } while (FALSE);
1377
1378 RTMPusecDelay(500000);
1379 }
1380
1381 ASSERT(pAd->PendingRx == 0);
1382/*=========================================================================*/
1383
1384 // Soft reset BBP.
1385 BbpSoftReset(pAd);
1386 pAd->ContinBulkIn = FALSE;
1387 }
1388#endif // RALINK_28xx_QA //
1389 else if (!strcmp(arg, "RXFRAME")) // Rx Frames
1390 {
1391 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXFRAME\n"));
1392
1393 // Disable Rx of MAC block
1394 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1395 Value &= ~(1 << 3);
1396 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1397
1398 // Default value in BBP R22 is 0x0.
1399 BbpData = 0;
1400
1401 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
1402 // Clean bit4 to stop continuous Tx production test.
1403 MacData &= 0xFFFFFFEF;
1404
1405 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1406 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
1407
1408 pAd->ate.Mode |= ATE_RXFRAME;
1409
1410 // Abort Tx, RX DMA.
1411 RtmpDmaEnable(pAd, 0);
1412
1413 // Disable TX of MAC block
1414 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1415 Value &= ~(1 << 2);
1416 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1417
1418 // Reset Rx RING.
1419 for ( i = 0; i < (RX_RING_SIZE); i++)
1420 {
1421 PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
1422
1423 pRxContext->InUse = FALSE;
1424 pRxContext->IRPPending = FALSE;
1425 pRxContext->Readable = FALSE;
1426
1427 //
1428 // Get the urb from kernel back to driver.
1429 //
1430 RTUSB_UNLINK_URB(pRxContext->pUrb);
1431
1432 /* Sleep 200 microsecs to give cancellation time to work. */
1433 NdisMSleep(200);
1434 pAd->BulkInReq = 0;
1435
1436// InterlockedExchange(&pAd->PendingRx, 0);
1437 pAd->PendingRx = 0;
1438 pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
1439 pAd->NextRxBulkInIndex = RX_RING_SIZE - 1; // Rx Bulk pointer
1440 pAd->NextRxBulkInPosition = 0;
1441 }
1442
1443 // read to clear counters
1444 RTUSBReadMACRegister(pAd, RX_STA_CNT0, &temp); //RX PHY & RX CRC count
1445 RTUSBReadMACRegister(pAd, RX_STA_CNT1, &temp); //RX PLCP error count & CCA false alarm count
1446 RTUSBReadMACRegister(pAd, RX_STA_CNT2, &temp); //RX FIFO overflow frame count & RX duplicated filtered frame count
1447
1448 pAd->ContinBulkIn = TRUE;
1449
1450 // Enable Tx, RX DMA.
1451 RtmpDmaEnable(pAd, 1);
1452
1453 // Enable RX of MAC block
1454 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1455 Value |= (1 << 3);
1456 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1457
1458 // Kick bulk in
1459 RTUSBBulkReceive(pAd);
1460 }
1461 else
1462 {
1463 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: Invalid arg!\n"));
1464 return FALSE;
1465 }
1466 RTMPusecDelay(5000);
1467
1468 ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATECmdHandler()\n"));
1469
1470 return TRUE;
1471}
1472#endif // RT2870 //
1473
1474INT Set_ATE_Proc(
1475 IN PRTMP_ADAPTER pAd,
1476 IN PUCHAR arg)
1477{
1478 if (ATECmdHandler(pAd, arg))
1479 {
1480 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Success\n"));
1481
1482
1483 return TRUE;
1484 }
1485 else
1486 {
1487 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Failed\n"));
1488 return FALSE;
1489 }
1490}
1491
1492/*
1493 ==========================================================================
1494 Description:
1495 Set ATE ADDR1=DA for TxFrame(AP : To DS = 0 ; From DS = 1)
1496 or
1497 Set ATE ADDR3=DA for TxFrame(STA : To DS = 1 ; From DS = 0)
1498
1499 Return:
1500 TRUE if all parameters are OK, FALSE otherwise
1501 ==========================================================================
1502*/
1503INT Set_ATE_DA_Proc(
1504 IN PRTMP_ADAPTER pAd,
1505 IN PUCHAR arg)
1506{
1507 CHAR *value;
1508 INT i;
1509
1510 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
1511 return FALSE;
1512
1513 for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
1514 {
1515 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
1516 return FALSE; //Invalid
1517
1518
1519#ifdef CONFIG_STA_SUPPORT
1520 AtoH(value, &pAd->ate.Addr3[i++], 1);
1521#endif // CONFIG_STA_SUPPORT //
1522 }
1523
1524 if(i != 6)
1525 return FALSE; //Invalid
1526
1527
1528#ifdef CONFIG_STA_SUPPORT
1529 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DA_Proc (DA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr3[0],
1530 pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]));
1531#endif // CONFIG_STA_SUPPORT //
1532
1533 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_DA_Proc Success\n"));
1534
1535 return TRUE;
1536}
1537
1538/*
1539 ==========================================================================
1540 Description:
1541 Set ATE ADDR3=SA for TxFrame(AP : To DS = 0 ; From DS = 1)
1542 or
1543 Set ATE ADDR2=SA for TxFrame(STA : To DS = 1 ; From DS = 0)
1544
1545 Return:
1546 TRUE if all parameters are OK, FALSE otherwise
1547 ==========================================================================
1548*/
1549INT Set_ATE_SA_Proc(
1550 IN PRTMP_ADAPTER pAd,
1551 IN PUCHAR arg)
1552{
1553 CHAR *value;
1554 INT i;
1555
1556 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
1557 return FALSE;
1558
1559 for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
1560 {
1561 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
1562 return FALSE; //Invalid
1563
1564
1565#ifdef CONFIG_STA_SUPPORT
1566 AtoH(value, &pAd->ate.Addr2[i++], 1);
1567#endif // CONFIG_STA_SUPPORT //
1568 }
1569
1570 if(i != 6)
1571 return FALSE; //Invalid
1572
1573
1574#ifdef CONFIG_STA_SUPPORT
1575 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_SA_Proc (SA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr2[0],
1576 pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]));
1577#endif // CONFIG_STA_SUPPORT //
1578
1579 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_SA_Proc Success\n"));
1580
1581 return TRUE;
1582}
1583
1584/*
1585 ==========================================================================
1586 Description:
1587 Set ATE ADDR2=BSSID for TxFrame(AP : To DS = 0 ; From DS = 1)
1588 or
1589 Set ATE ADDR1=BSSID for TxFrame(STA : To DS = 1 ; From DS = 0)
1590
1591 Return:
1592 TRUE if all parameters are OK, FALSE otherwise
1593 ==========================================================================
1594*/
1595INT Set_ATE_BSSID_Proc(
1596 IN PRTMP_ADAPTER pAd,
1597 IN PUCHAR arg)
1598{
1599 CHAR *value;
1600 INT i;
1601
1602 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
1603 return FALSE;
1604
1605 for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
1606 {
1607 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
1608 return FALSE; //Invalid
1609
1610
1611#ifdef CONFIG_STA_SUPPORT
1612 AtoH(value, &pAd->ate.Addr1[i++], 1);
1613#endif // CONFIG_STA_SUPPORT //
1614 }
1615
1616 if(i != 6)
1617 return FALSE; //Invalid
1618
1619
1620#ifdef CONFIG_STA_SUPPORT
1621 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_BSSID_Proc (BSSID = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr1[0],
1622 pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]));
1623#endif // CONFIG_STA_SUPPORT //
1624
1625 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_BSSID_Proc Success\n"));
1626
1627 return TRUE;
1628}
1629
1630/*
1631 ==========================================================================
1632 Description:
1633 Set ATE Tx Channel
1634
1635 Return:
1636 TRUE if all parameters are OK, FALSE otherwise
1637 ==========================================================================
1638*/
1639INT Set_ATE_CHANNEL_Proc(
1640 IN PRTMP_ADAPTER pAd,
1641 IN PUCHAR arg)
1642{
1643 UCHAR channel;
1644
1645 channel = simple_strtol(arg, 0, 10);
1646
1647 if ((channel < 1) || (channel > 216))// to allow A band channel : ((channel < 1) || (channel > 14))
1648 {
1649 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_CHANNEL_Proc::Out of range, it should be in range of 1~14.\n"));
1650 return FALSE;
1651 }
1652 pAd->ate.Channel = channel;
1653
1654 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_CHANNEL_Proc (ATE Channel = %d)\n", pAd->ate.Channel));
1655 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_CHANNEL_Proc Success\n"));
1656
1657
1658 return TRUE;
1659}
1660
1661/*
1662 ==========================================================================
1663 Description:
1664 Set ATE Tx Power0
1665
1666 Return:
1667 TRUE if all parameters are OK, FALSE otherwise
1668 ==========================================================================
1669*/
1670INT Set_ATE_TX_POWER0_Proc(
1671 IN PRTMP_ADAPTER pAd,
1672 IN PUCHAR arg)
1673{
1674 CHAR TxPower;
1675
1676 TxPower = simple_strtol(arg, 0, 10);
1677
1678 if (pAd->ate.Channel <= 14)
1679 {
1680 if ((TxPower > 31) || (TxPower < 0))
1681 {
1682 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
1683 return FALSE;
1684 }
1685 }
1686 else// 5.5GHz
1687 {
1688 if ((TxPower > 15) || (TxPower < -7))
1689 {
1690 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
1691 return FALSE;
1692 }
1693 }
1694
1695 pAd->ate.TxPower0 = TxPower;
1696 ATETxPwrHandler(pAd, 0);
1697 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER0_Proc Success\n"));
1698
1699
1700 return TRUE;
1701}
1702
1703/*
1704 ==========================================================================
1705 Description:
1706 Set ATE Tx Power1
1707
1708 Return:
1709 TRUE if all parameters are OK, FALSE otherwise
1710 ==========================================================================
1711*/
1712INT Set_ATE_TX_POWER1_Proc(
1713 IN PRTMP_ADAPTER pAd,
1714 IN PUCHAR arg)
1715{
1716 CHAR TxPower;
1717
1718 TxPower = simple_strtol(arg, 0, 10);
1719
1720 if (pAd->ate.Channel <= 14)
1721 {
1722 if ((TxPower > 31) || (TxPower < 0))
1723 {
1724 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
1725 return FALSE;
1726 }
1727 }
1728 else
1729 {
1730 if ((TxPower > 15) || (TxPower < -7))
1731 {
1732 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
1733 return FALSE;
1734 }
1735 }
1736
1737 pAd->ate.TxPower1 = TxPower;
1738 ATETxPwrHandler(pAd, 1);
1739 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER1_Proc Success\n"));
1740
1741
1742 return TRUE;
1743}
1744
1745/*
1746 ==========================================================================
1747 Description:
1748 Set ATE Tx Antenna
1749
1750 Return:
1751 TRUE if all parameters are OK, FALSE otherwise
1752 ==========================================================================
1753*/
1754INT Set_ATE_TX_Antenna_Proc(
1755 IN PRTMP_ADAPTER pAd,
1756 IN PUCHAR arg)
1757{
1758 CHAR value;
1759
1760 value = simple_strtol(arg, 0, 10);
1761
1762 if ((value > 2) || (value < 0))
1763 {
1764 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_Antenna_Proc::Out of range (Value=%d)\n", value));
1765 return FALSE;
1766 }
1767
1768 pAd->ate.TxAntennaSel = value;
1769
1770 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_Antenna_Proc (Antenna = %d)\n", pAd->ate.TxAntennaSel));
1771 ATEDBGPRINT(RT_DEBUG_TRACE,("Ralink: Set_ATE_TX_Antenna_Proc Success\n"));
1772
1773
1774 return TRUE;
1775}
1776
1777/*
1778 ==========================================================================
1779 Description:
1780 Set ATE Rx Antenna
1781
1782 Return:
1783 TRUE if all parameters are OK, FALSE otherwise
1784 ==========================================================================
1785*/
1786INT Set_ATE_RX_Antenna_Proc(
1787 IN PRTMP_ADAPTER pAd,
1788 IN PUCHAR arg)
1789{
1790 CHAR value;
1791
1792 value = simple_strtol(arg, 0, 10);
1793
1794 if ((value > 3) || (value < 0))
1795 {
1796 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_RX_Antenna_Proc::Out of range (Value=%d)\n", value));
1797 return FALSE;
1798 }
1799
1800 pAd->ate.RxAntennaSel = value;
1801
1802 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_Antenna_Proc (Antenna = %d)\n", pAd->ate.RxAntennaSel));
1803 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_Antenna_Proc Success\n"));
1804
1805
1806 return TRUE;
1807}
1808
1809/*
1810 ==========================================================================
1811 Description:
1812 Set ATE RF frequence offset
1813
1814 Return:
1815 TRUE if all parameters are OK, FALSE otherwise
1816 ==========================================================================
1817*/
1818INT Set_ATE_TX_FREQOFFSET_Proc(
1819 IN PRTMP_ADAPTER pAd,
1820 IN PUCHAR arg)
1821{
1822 UCHAR RFFreqOffset;
1823 ULONG R4;
1824
1825 RFFreqOffset = simple_strtol(arg, 0, 10);
1826
1827 if(RFFreqOffset >= 64)
1828 {
1829 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_FREQOFFSET_Proc::Out of range, it should be in range of 0~63.\n"));
1830 return FALSE;
1831 }
1832
1833 pAd->ate.RFFreqOffset = RFFreqOffset;
1834 R4 = pAd->ate.RFFreqOffset << 15; // shift TX power control to correct RF register bit position
1835 R4 |= (pAd->LatchRfRegs.R4 & ((~0x001f8000)));
1836 pAd->LatchRfRegs.R4 = R4;
1837
1838 RtmpRfIoWrite(pAd);
1839
1840 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_FREQOFFSET_Proc (RFFreqOffset = %d)\n", pAd->ate.RFFreqOffset));
1841 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_FREQOFFSET_Proc Success\n"));
1842
1843
1844 return TRUE;
1845}
1846
1847/*
1848 ==========================================================================
1849 Description:
1850 Set ATE RF BW
1851
1852 Return:
1853 TRUE if all parameters are OK, FALSE otherwise
1854 ==========================================================================
1855*/
1856INT Set_ATE_TX_BW_Proc(
1857 IN PRTMP_ADAPTER pAd,
1858 IN PUCHAR arg)
1859{
1860 int i;
1861 UCHAR value = 0;
1862 UCHAR BBPCurrentBW;
1863
1864 BBPCurrentBW = simple_strtol(arg, 0, 10);
1865
1866 if(BBPCurrentBW == 0)
1867 pAd->ate.TxWI.BW = BW_20;
1868 else
1869 pAd->ate.TxWI.BW = BW_40;
1870
1871 if(pAd->ate.TxWI.BW == BW_20)
1872 {
1873 if(pAd->ate.Channel <= 14)
1874 {
1875 for (i=0; i<5; i++)
1876 {
1877 if (pAd->Tx20MPwrCfgGBand[i] != 0xffffffff)
1878 {
1879 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgGBand[i]);
1880 RTMPusecDelay(5000);
1881 }
1882 }
1883 }
1884 else
1885 {
1886 for (i=0; i<5; i++)
1887 {
1888 if (pAd->Tx20MPwrCfgABand[i] != 0xffffffff)
1889 {
1890 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgABand[i]);
1891 RTMPusecDelay(5000);
1892 }
1893 }
1894 }
1895
1896 //Set BBP R4 bit[4:3]=0:0
1897 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
1898 value &= (~0x18);
1899 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
1900
1901 //Set BBP R66=0x3C
1902 value = 0x3C;
1903 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
1904 //Set BBP R68=0x0B
1905 //to improve Rx sensitivity.
1906 value = 0x0B;
1907 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
1908 //Set BBP R69=0x16
1909 value = 0x16;
1910 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
1911 //Set BBP R70=0x08
1912 value = 0x08;
1913 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
1914 //Set BBP R73=0x11
1915 value = 0x11;
1916 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
1917
1918 // If Channel=14, Bandwidth=20M and Mode=CCK, Set BBP R4 bit5=1
1919 // (Japan filter coefficients)
1920 // This segment of code will only works when ATETXMODE and ATECHANNEL
1921 // were set to MODE_CCK and 14 respectively before ATETXBW is set to 0.
1922 //=====================================================================
1923 if (pAd->ate.Channel == 14)
1924 {
1925 int TxMode = pAd->ate.TxWI.PHYMODE;
1926 if (TxMode == MODE_CCK)
1927 {
1928 // when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1
1929 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
1930 value |= 0x20; //set bit5=1
1931 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
1932 }
1933 }
1934
1935 //=====================================================================
1936 // If bandwidth != 40M, RF Reg4 bit 21 = 0.
1937 pAd->LatchRfRegs.R4 &= ~0x00200000;
1938 RtmpRfIoWrite(pAd);
1939 }
1940 else if(pAd->ate.TxWI.BW == BW_40)
1941 {
1942 if(pAd->ate.Channel <= 14)
1943 {
1944 for (i=0; i<5; i++)
1945 {
1946 if (pAd->Tx40MPwrCfgGBand[i] != 0xffffffff)
1947 {
1948 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgGBand[i]);
1949 RTMPusecDelay(5000);
1950 }
1951 }
1952 }
1953 else
1954 {
1955 for (i=0; i<5; i++)
1956 {
1957 if (pAd->Tx40MPwrCfgABand[i] != 0xffffffff)
1958 {
1959 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgABand[i]);
1960 RTMPusecDelay(5000);
1961 }
1962 }
1963#ifdef DOT11_N_SUPPORT
1964 if ((pAd->ate.TxWI.PHYMODE >= MODE_HTMIX) && (pAd->ate.TxWI.MCS == 7))
1965 {
1966 value = 0x28;
1967 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R67, value);
1968 }
1969#endif // DOT11_N_SUPPORT //
1970 }
1971
1972 //Set BBP R4 bit[4:3]=1:0
1973 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
1974 value &= (~0x18);
1975 value |= 0x10;
1976 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
1977
1978 //Set BBP R66=0x3C
1979 value = 0x3C;
1980 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
1981 //Set BBP R68=0x0C
1982 //to improve Rx sensitivity.
1983 value = 0x0C;
1984 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
1985 //Set BBP R69=0x1A
1986 value = 0x1A;
1987 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
1988 //Set BBP R70=0x0A
1989 value = 0x0A;
1990 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
1991 //Set BBP R73=0x16
1992 value = 0x16;
1993 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
1994
1995 // If bandwidth = 40M, set RF Reg4 bit 21 = 1.
1996 pAd->LatchRfRegs.R4 |= 0x00200000;
1997 RtmpRfIoWrite(pAd);
1998 }
1999
2000 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_BW_Proc (BBPCurrentBW = %d)\n", pAd->ate.TxWI.BW));
2001 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_BW_Proc Success\n"));
2002
2003
2004 return TRUE;
2005}
2006
2007/*
2008 ==========================================================================
2009 Description:
2010 Set ATE Tx frame length
2011
2012 Return:
2013 TRUE if all parameters are OK, FALSE otherwise
2014 ==========================================================================
2015*/
2016INT Set_ATE_TX_LENGTH_Proc(
2017 IN PRTMP_ADAPTER pAd,
2018 IN PUCHAR arg)
2019{
2020 pAd->ate.TxLength = simple_strtol(arg, 0, 10);
2021
2022 if((pAd->ate.TxLength < 24) || (pAd->ate.TxLength > (MAX_FRAME_SIZE - 34/* == 2312 */)))
2023 {
2024 pAd->ate.TxLength = (MAX_FRAME_SIZE - 34/* == 2312 */);
2025 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 */)));
2026 return FALSE;
2027 }
2028
2029 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_LENGTH_Proc (TxLength = %d)\n", pAd->ate.TxLength));
2030 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_LENGTH_Proc Success\n"));
2031
2032
2033 return TRUE;
2034}
2035
2036/*
2037 ==========================================================================
2038 Description:
2039 Set ATE Tx frame count
2040
2041 Return:
2042 TRUE if all parameters are OK, FALSE otherwise
2043 ==========================================================================
2044*/
2045INT Set_ATE_TX_COUNT_Proc(
2046 IN PRTMP_ADAPTER pAd,
2047 IN PUCHAR arg)
2048{
2049 pAd->ate.TxCount = simple_strtol(arg, 0, 10);
2050
2051 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pAd->ate.TxCount));
2052 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n"));
2053
2054
2055 return TRUE;
2056}
2057
2058/*
2059 ==========================================================================
2060 Description:
2061 Set ATE Tx frame MCS
2062
2063 Return:
2064 TRUE if all parameters are OK, FALSE otherwise
2065 ==========================================================================
2066*/
2067INT Set_ATE_TX_MCS_Proc(
2068 IN PRTMP_ADAPTER pAd,
2069 IN PUCHAR arg)
2070{
2071 UCHAR MCS;
2072 int result;
2073
2074 MCS = simple_strtol(arg, 0, 10);
2075 result = CheckMCSValid(pAd->ate.TxWI.PHYMODE, MCS);
2076
2077 if (result != -1)
2078 {
2079 pAd->ate.TxWI.MCS = (UCHAR)MCS;
2080 }
2081 else
2082 {
2083 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MCS_Proc::Out of range, refer to rate table.\n"));
2084 return FALSE;
2085 }
2086
2087 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MCS_Proc (MCS = %d)\n", pAd->ate.TxWI.MCS));
2088 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MCS_Proc Success\n"));
2089
2090
2091 return TRUE;
2092}
2093
2094/*
2095 ==========================================================================
2096 Description:
2097 Set ATE Tx frame Mode
2098 0: MODE_CCK
2099 1: MODE_OFDM
2100 2: MODE_HTMIX
2101 3: MODE_HTGREENFIELD
2102
2103 Return:
2104 TRUE if all parameters are OK, FALSE otherwise
2105 ==========================================================================
2106*/
2107INT Set_ATE_TX_MODE_Proc(
2108 IN PRTMP_ADAPTER pAd,
2109 IN PUCHAR arg)
2110{
2111 pAd->ate.TxWI.PHYMODE = simple_strtol(arg, 0, 10);
2112
2113 if(pAd->ate.TxWI.PHYMODE > 3)
2114 {
2115 pAd->ate.TxWI.PHYMODE = 0;
2116 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MODE_Proc::Out of range. it should be in range of 0~3\n"));
2117 ATEDBGPRINT(RT_DEBUG_ERROR, ("0: CCK, 1: OFDM, 2: HT_MIX, 3: HT_GREEN_FIELD.\n"));
2118 return FALSE;
2119 }
2120
2121 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MODE_Proc (TxMode = %d)\n", pAd->ate.TxWI.PHYMODE));
2122 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MODE_Proc Success\n"));
2123
2124
2125 return TRUE;
2126}
2127
2128/*
2129 ==========================================================================
2130 Description:
2131 Set ATE Tx frame GI
2132
2133 Return:
2134 TRUE if all parameters are OK, FALSE otherwise
2135 ==========================================================================
2136*/
2137INT Set_ATE_TX_GI_Proc(
2138 IN PRTMP_ADAPTER pAd,
2139 IN PUCHAR arg)
2140{
2141 pAd->ate.TxWI.ShortGI = simple_strtol(arg, 0, 10);
2142
2143 if(pAd->ate.TxWI.ShortGI > 1)
2144 {
2145 pAd->ate.TxWI.ShortGI = 0;
2146 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_GI_Proc::Out of range\n"));
2147 return FALSE;
2148 }
2149
2150 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_GI_Proc (GI = %d)\n", pAd->ate.TxWI.ShortGI));
2151 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_GI_Proc Success\n"));
2152
2153
2154 return TRUE;
2155}
2156
2157/*
2158 ==========================================================================
2159 Description:
2160 ==========================================================================
2161 */
2162INT Set_ATE_RX_FER_Proc(
2163 IN PRTMP_ADAPTER pAd,
2164 IN PUCHAR arg)
2165{
2166 pAd->ate.bRxFer = simple_strtol(arg, 0, 10);
2167
2168 if (pAd->ate.bRxFer == 1)
2169 {
2170 pAd->ate.RxCntPerSec = 0;
2171 pAd->ate.RxTotalCnt = 0;
2172 }
2173
2174 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_FER_Proc (bRxFer = %d)\n", pAd->ate.bRxFer));
2175 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_FER_Proc Success\n"));
2176
2177
2178 return TRUE;
2179}
2180
2181INT Set_ATE_Read_RF_Proc(
2182 IN PRTMP_ADAPTER pAd,
2183 IN PUCHAR arg)
2184{
2185 ate_print(KERN_EMERG "R1 = %lx\n", pAd->LatchRfRegs.R1);
2186 ate_print(KERN_EMERG "R2 = %lx\n", pAd->LatchRfRegs.R2);
2187 ate_print(KERN_EMERG "R3 = %lx\n", pAd->LatchRfRegs.R3);
2188 ate_print(KERN_EMERG "R4 = %lx\n", pAd->LatchRfRegs.R4);
2189
2190 return TRUE;
2191}
2192
2193INT Set_ATE_Write_RF1_Proc(
2194 IN PRTMP_ADAPTER pAd,
2195 IN PUCHAR arg)
2196{
2197 UINT32 value = simple_strtol(arg, 0, 16);
2198
2199 pAd->LatchRfRegs.R1 = value;
2200 RtmpRfIoWrite(pAd);
2201
2202 return TRUE;
2203}
2204
2205INT Set_ATE_Write_RF2_Proc(
2206 IN PRTMP_ADAPTER pAd,
2207 IN PUCHAR arg)
2208{
2209 UINT32 value = simple_strtol(arg, 0, 16);
2210
2211 pAd->LatchRfRegs.R2 = value;
2212 RtmpRfIoWrite(pAd);
2213
2214 return TRUE;
2215}
2216
2217INT Set_ATE_Write_RF3_Proc(
2218 IN PRTMP_ADAPTER pAd,
2219 IN PUCHAR arg)
2220{
2221 UINT32 value = simple_strtol(arg, 0, 16);
2222
2223 pAd->LatchRfRegs.R3 = value;
2224 RtmpRfIoWrite(pAd);
2225
2226 return TRUE;
2227}
2228
2229INT Set_ATE_Write_RF4_Proc(
2230 IN PRTMP_ADAPTER pAd,
2231 IN PUCHAR arg)
2232{
2233 UINT32 value = simple_strtol(arg, 0, 16);
2234
2235 pAd->LatchRfRegs.R4 = value;
2236 RtmpRfIoWrite(pAd);
2237
2238 return TRUE;
2239}
2240
2241/*
2242 ==========================================================================
2243 Description:
2244 Load and Write EEPROM from a binary file prepared in advance.
2245
2246 Return:
2247 TRUE if all parameters are OK, FALSE otherwise
2248 ==========================================================================
2249*/
2250#ifndef UCOS
2251INT Set_ATE_Load_E2P_Proc(
2252 IN PRTMP_ADAPTER pAd,
2253 IN PUCHAR arg)
2254{
2255 BOOLEAN ret = FALSE;
2256 PUCHAR src = EEPROM_BIN_FILE_NAME;
2257 struct file *srcf;
2258 INT32 retval, orgfsuid, orgfsgid;
2259 mm_segment_t orgfs;
2260 USHORT WriteEEPROM[(EEPROM_SIZE/2)];
2261 UINT32 FileLength = 0;
2262 UINT32 value = simple_strtol(arg, 0, 10);
2263
2264 ATEDBGPRINT(RT_DEBUG_ERROR, ("===> %s (value=%d)\n\n", __FUNCTION__, value));
2265
2266 if (value > 0)
2267 {
2268 /* zero the e2p buffer */
2269 NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
2270
2271 /* save uid and gid used for filesystem access.
2272 ** set user and group to 0 (root)
2273 */
2274 orgfsuid = current->fsuid;
2275 orgfsgid = current->fsgid;
2276 /* as root */
2277 current->fsuid = current->fsgid = 0;
2278 orgfs = get_fs();
2279 set_fs(KERNEL_DS);
2280
2281 do
2282 {
2283 /* open the bin file */
2284 srcf = filp_open(src, O_RDONLY, 0);
2285
2286 if (IS_ERR(srcf))
2287 {
2288 ate_print("%s - Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(srcf), src);
2289 break;
2290 }
2291
2292 /* the object must have a read method */
2293 if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
2294 {
2295 ate_print("%s - %s does not have a read method\n", __FUNCTION__, src);
2296 break;
2297 }
2298
2299 /* read the firmware from the file *.bin */
2300 FileLength = srcf->f_op->read(srcf,
2301 (PUCHAR)WriteEEPROM,
2302 EEPROM_SIZE,
2303 &srcf->f_pos);
2304
2305 if (FileLength != EEPROM_SIZE)
2306 {
2307 ate_print("%s: error file length (=%d) in e2p.bin\n",
2308 __FUNCTION__, FileLength);
2309 break;
2310 }
2311 else
2312 {
2313 /* write the content of .bin file to EEPROM */
2314 rt_ee_write_all(pAd, WriteEEPROM);
2315 ret = TRUE;
2316 }
2317 break;
2318 } while(TRUE);
2319
2320 /* close firmware file */
2321 if (IS_ERR(srcf))
2322 {
2323 ;
2324 }
2325 else
2326 {
2327 retval = filp_close(srcf, NULL);
2328 if (retval)
2329 {
2330 ATEDBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src));
2331
2332 }
2333 }
2334
2335 /* restore */
2336 set_fs(orgfs);
2337 current->fsuid = orgfsuid;
2338 current->fsgid = orgfsgid;
2339 }
2340 ATEDBGPRINT(RT_DEBUG_ERROR, ("<=== %s (ret=%d)\n", __FUNCTION__, ret));
2341
2342 return ret;
2343
2344}
2345#else
2346INT Set_ATE_Load_E2P_Proc(
2347 IN PRTMP_ADAPTER pAd,
2348 IN PUCHAR arg)
2349{
2350 USHORT WriteEEPROM[(EEPROM_SIZE/2)];
2351 struct iwreq *wrq = (struct iwreq *)arg;
2352
2353 ATEDBGPRINT(RT_DEBUG_TRACE, ("===> %s (wrq->u.data.length = %d)\n\n", __FUNCTION__, wrq->u.data.length));
2354
2355 if (wrq->u.data.length != EEPROM_SIZE)
2356 {
2357 ate_print("%s: error length (=%d) from host\n",
2358 __FUNCTION__, wrq->u.data.length);
2359 return FALSE;
2360 }
2361 else/* (wrq->u.data.length == EEPROM_SIZE) */
2362 {
2363 /* zero the e2p buffer */
2364 NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
2365
2366 /* fill the local buffer */
2367 NdisMoveMemory((PUCHAR)WriteEEPROM, wrq->u.data.pointer, wrq->u.data.length);
2368
2369 do
2370 {
2371 /* write the content of .bin file to EEPROM */
2372 rt_ee_write_all(pAd, WriteEEPROM);
2373
2374 } while(FALSE);
2375 }
2376
2377 ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== %s\n", __FUNCTION__));
2378
2379 return TRUE;
2380
2381}
2382#endif // !UCOS //
2383
2384INT Set_ATE_Read_E2P_Proc(
2385 IN PRTMP_ADAPTER pAd,
2386 IN PUCHAR arg)
2387{
2388 USHORT buffer[EEPROM_SIZE/2];
2389 USHORT *p;
2390 int i;
2391
2392 rt_ee_read_all(pAd, (USHORT *)buffer);
2393 p = buffer;
2394 for (i = 0; i < (EEPROM_SIZE/2); i++)
2395 {
2396 ate_print("%4.4x ", *p);
2397 if (((i+1) % 16) == 0)
2398 ate_print("\n");
2399 p++;
2400 }
2401 return TRUE;
2402}
2403
2404INT Set_ATE_Show_Proc(
2405 IN PRTMP_ADAPTER pAd,
2406 IN PUCHAR arg)
2407{
2408 ate_print("Mode=%d\n", pAd->ate.Mode);
2409 ate_print("TxPower0=%d\n", pAd->ate.TxPower0);
2410 ate_print("TxPower1=%d\n", pAd->ate.TxPower1);
2411 ate_print("TxAntennaSel=%d\n", pAd->ate.TxAntennaSel);
2412 ate_print("RxAntennaSel=%d\n", pAd->ate.RxAntennaSel);
2413 ate_print("BBPCurrentBW=%d\n", pAd->ate.TxWI.BW);
2414 ate_print("GI=%d\n", pAd->ate.TxWI.ShortGI);
2415 ate_print("MCS=%d\n", pAd->ate.TxWI.MCS);
2416 ate_print("TxMode=%d\n", pAd->ate.TxWI.PHYMODE);
2417 ate_print("Addr1=%02x:%02x:%02x:%02x:%02x:%02x\n",
2418 pAd->ate.Addr1[0], pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]);
2419 ate_print("Addr2=%02x:%02x:%02x:%02x:%02x:%02x\n",
2420 pAd->ate.Addr2[0], pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]);
2421 ate_print("Addr3=%02x:%02x:%02x:%02x:%02x:%02x\n",
2422 pAd->ate.Addr3[0], pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]);
2423 ate_print("Channel=%d\n", pAd->ate.Channel);
2424 ate_print("TxLength=%d\n", pAd->ate.TxLength);
2425 ate_print("TxCount=%u\n", pAd->ate.TxCount);
2426 ate_print("RFFreqOffset=%d\n", pAd->ate.RFFreqOffset);
2427 ate_print(KERN_EMERG "Set_ATE_Show_Proc Success\n");
2428 return TRUE;
2429}
2430
2431INT Set_ATE_Help_Proc(
2432 IN PRTMP_ADAPTER pAd,
2433 IN PUCHAR arg)
2434{
2435 ate_print("ATE=ATESTART, ATESTOP, TXCONT, TXCARR, TXFRAME, RXFRAME\n");
2436 ate_print("ATEDA\n");
2437 ate_print("ATESA\n");
2438 ate_print("ATEBSSID\n");
2439 ate_print("ATECHANNEL, range:0~14(unless A band !)\n");
2440 ate_print("ATETXPOW0, set power level of antenna 1.\n");
2441 ate_print("ATETXPOW1, set power level of antenna 2.\n");
2442 ate_print("ATETXANT, set TX antenna. 0:all, 1:antenna one, 2:antenna two.\n");
2443 ate_print("ATERXANT, set RX antenna.0:all, 1:antenna one, 2:antenna two, 3:antenna three.\n");
2444 ate_print("ATETXFREQOFFSET, set frequency offset, range 0~63\n");
2445 ate_print("ATETXBW, set BandWidth, 0:20MHz, 1:40MHz.\n");
2446 ate_print("ATETXLEN, set Frame length, range 24~%d\n", (MAX_FRAME_SIZE - 34/* == 2312 */));
2447 ate_print("ATETXCNT, set how many frame going to transmit.\n");
2448 ate_print("ATETXMCS, set MCS, reference to rate table.\n");
2449 ate_print("ATETXMODE, set Mode 0:CCK, 1:OFDM, 2:HT-Mix, 3:GreenField, reference to rate table.\n");
2450 ate_print("ATETXGI, set GI interval, 0:Long, 1:Short\n");
2451 ate_print("ATERXFER, 0:disable Rx Frame error rate. 1:enable Rx Frame error rate.\n");
2452 ate_print("ATERRF, show all RF registers.\n");
2453 ate_print("ATEWRF1, set RF1 register.\n");
2454 ate_print("ATEWRF2, set RF2 register.\n");
2455 ate_print("ATEWRF3, set RF3 register.\n");
2456 ate_print("ATEWRF4, set RF4 register.\n");
2457 ate_print("ATELDE2P, load EEPROM from .bin file.\n");
2458 ate_print("ATERE2P, display all EEPROM content.\n");
2459 ate_print("ATESHOW, display all parameters of ATE.\n");
2460 ate_print("ATEHELP, online help.\n");
2461
2462 return TRUE;
2463}
2464
2465/*
2466 ==========================================================================
2467 Description:
2468
2469 AsicSwitchChannel() dedicated for ATE.
2470
2471 ==========================================================================
2472*/
2473VOID ATEAsicSwitchChannel(
2474 IN PRTMP_ADAPTER pAd)
2475{
2476 UINT32 R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0, Value = 0;
2477 CHAR TxPwer = 0, TxPwer2 = 0;
2478 UCHAR index, BbpValue = 0, R66 = 0x30;
2479 RTMP_RF_REGS *RFRegTable;
2480 UCHAR Channel;
2481
2482#ifdef RALINK_28xx_QA
2483 if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
2484 {
2485 if (pAd->ate.Channel != pAd->LatchRfRegs.Channel)
2486 {
2487 pAd->ate.Channel = pAd->LatchRfRegs.Channel;
2488 }
2489 return;
2490 }
2491 else
2492#endif // RALINK_28xx_QA //
2493 Channel = pAd->ate.Channel;
2494
2495 // Select antenna
2496 AsicAntennaSelect(pAd, Channel);
2497
2498 // fill Tx power value
2499 TxPwer = pAd->ate.TxPower0;
2500 TxPwer2 = pAd->ate.TxPower1;
2501
2502 RFRegTable = RF2850RegTable;
2503
2504 switch (pAd->RfIcType)
2505 {
2506 /* But only 2850 and 2750 support 5.5GHz band... */
2507 case RFIC_2820:
2508 case RFIC_2850:
2509 case RFIC_2720:
2510 case RFIC_2750:
2511
2512 for (index = 0; index < NUM_OF_2850_CHNL; index++)
2513 {
2514 if (Channel == RFRegTable[index].Channel)
2515 {
2516 R2 = RFRegTable[index].R2;
2517 if (pAd->Antenna.field.TxPath == 1)
2518 {
2519 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
2520 }
2521
2522 if (pAd->Antenna.field.RxPath == 2)
2523 {
2524 switch (pAd->ate.RxAntennaSel)
2525 {
2526 case 1:
2527 R2 |= 0x20040;
2528 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2529 BbpValue &= 0xE4;
2530 BbpValue |= 0x00;
2531 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2532 break;
2533 case 2:
2534 R2 |= 0x10040;
2535 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2536 BbpValue &= 0xE4;
2537 BbpValue |= 0x01;
2538 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2539 break;
2540 default:
2541 R2 |= 0x40;
2542 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2543 BbpValue &= 0xE4;
2544 /* Only enable two Antenna to receive. */
2545 BbpValue |= 0x08;
2546 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2547 break;
2548 }
2549 }
2550 else if (pAd->Antenna.field.RxPath == 1)
2551 {
2552 R2 |= 0x20040; // write 1 to off RxPath
2553 }
2554
2555 if (pAd->Antenna.field.TxPath == 2)
2556 {
2557 if (pAd->ate.TxAntennaSel == 1)
2558 {
2559 R2 |= 0x4000; // If TX Antenna select is 1 , bit 14 = 1; Disable Ant 2
2560 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
2561 BbpValue &= 0xE7; //11100111B
2562 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
2563 }
2564 else if (pAd->ate.TxAntennaSel == 2)
2565 {
2566 R2 |= 0x8000; // If TX Antenna select is 2 , bit 15 = 1; Disable Ant 1
2567 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
2568 BbpValue &= 0xE7;
2569 BbpValue |= 0x08;
2570 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
2571 }
2572 else
2573 {
2574 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
2575 BbpValue &= 0xE7;
2576 BbpValue |= 0x10;
2577 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
2578 }
2579 }
2580 if (pAd->Antenna.field.RxPath == 3)
2581 {
2582 switch (pAd->ate.RxAntennaSel)
2583 {
2584 case 1:
2585 R2 |= 0x20040;
2586 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2587 BbpValue &= 0xE4;
2588 BbpValue |= 0x00;
2589 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2590 break;
2591 case 2:
2592 R2 |= 0x10040;
2593 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2594 BbpValue &= 0xE4;
2595 BbpValue |= 0x01;
2596 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2597 break;
2598 case 3:
2599 R2 |= 0x30000;
2600 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2601 BbpValue &= 0xE4;
2602 BbpValue |= 0x02;
2603 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2604 break;
2605 default:
2606 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2607 BbpValue &= 0xE4;
2608 BbpValue |= 0x10;
2609 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2610 break;
2611 }
2612 }
2613
2614 if (Channel > 14)
2615 {
2616 // initialize R3, R4
2617 R3 = (RFRegTable[index].R3 & 0xffffc1ff);
2618 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15);
2619
2620 // According the Rory's suggestion to solve the middle range issue.
2621 // 5.5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
2622 // R3
2623 if ((TxPwer >= -7) && (TxPwer < 0))
2624 {
2625 TxPwer = (7+TxPwer);
2626 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
2627 R3 |= (TxPwer << 10);
2628 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer=%d \n", TxPwer));
2629 }
2630 else
2631 {
2632 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
2633 R3 |= (TxPwer << 10) | (1 << 9);
2634 }
2635
2636 // R4
2637 if ((TxPwer2 >= -7) && (TxPwer2 < 0))
2638 {
2639 TxPwer2 = (7+TxPwer2);
2640 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
2641 R4 |= (TxPwer2 << 7);
2642 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
2643 }
2644 else
2645 {
2646 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
2647 R4 |= (TxPwer2 << 7) | (1 << 6);
2648 }
2649 }
2650 else
2651 {
2652 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
2653 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15) | (TxPwer2 <<6);// Set freq offset & TxPwr1
2654 }
2655
2656 // Based on BBP current mode before changing RF channel.
2657 if (pAd->ate.TxWI.BW == BW_40)
2658 {
2659 R4 |=0x200000;
2660 }
2661
2662 // Update variables
2663 pAd->LatchRfRegs.Channel = Channel;
2664 pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
2665 pAd->LatchRfRegs.R2 = R2;
2666 pAd->LatchRfRegs.R3 = R3;
2667 pAd->LatchRfRegs.R4 = R4;
2668
2669 RtmpRfIoWrite(pAd);
2670
2671 break;
2672 }
2673 }
2674 break;
2675
2676 default:
2677 break;
2678 }
2679
2680 // Change BBP setting during switch from a->g, g->a
2681 if (Channel <= 14)
2682 {
2683 ULONG TxPinCfg = 0x00050F0A;// 2007.10.09 by Brian : 0x0005050A ==> 0x00050F0A
2684
2685 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
2686 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
2687 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
2688
2689 /* For 1T/2R chip only... */
2690 if (pAd->NicConfig2.field.ExternalLNAForG)
2691 {
2692 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
2693 }
2694 else
2695 {
2696 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
2697 }
2698
2699 // According the Rory's suggestion to solve the middle range issue.
2700 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
2701 ASSERT((BbpValue == 0x00));
2702 if ((BbpValue != 0x00))
2703 {
2704 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
2705 }
2706
2707 // 5.5GHz band selection PIN, bit1 and bit2 are complement
2708 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
2709 Value &= (~0x6);
2710 Value |= (0x04);
2711 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
2712
2713 // Turn off unused PA or LNA when only 1T or 1R.
2714 if (pAd->Antenna.field.TxPath == 1)
2715 {
2716 TxPinCfg &= 0xFFFFFFF3;
2717 }
2718 if (pAd->Antenna.field.RxPath == 1)
2719 {
2720 TxPinCfg &= 0xFFFFF3FF;
2721 }
2722
2723 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
2724 }
2725 else
2726 {
2727 ULONG TxPinCfg = 0x00050F05;//2007.10.09 by Brian : 0x00050505 ==> 0x00050F05
2728
2729 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
2730 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
2731 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
2732 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
2733
2734 // According the Rory's suggestion to solve the middle range issue.
2735 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
2736 ASSERT((BbpValue == 0x00));
2737 if ((BbpValue != 0x00))
2738 {
2739 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
2740 }
2741 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R91, &BbpValue);
2742 ASSERT((BbpValue == 0x04));
2743
2744 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R92, &BbpValue);
2745 ASSERT((BbpValue == 0x00));
2746
2747 // 5.5GHz band selection PIN, bit1 and bit2 are complement
2748 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
2749 Value &= (~0x6);
2750 Value |= (0x02);
2751 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
2752
2753 // Turn off unused PA or LNA when only 1T or 1R.
2754 if (pAd->Antenna.field.TxPath == 1)
2755 {
2756 TxPinCfg &= 0xFFFFFFF3;
2757 }
2758 if (pAd->Antenna.field.RxPath == 1)
2759 {
2760 TxPinCfg &= 0xFFFFF3FF;
2761 }
2762
2763 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
2764 }
2765
2766 // R66 should be set according to Channel and use 20MHz when scanning
2767 if (Channel <= 14)
2768 {
2769 // BG band
2770 R66 = 0x2E + GET_LNA_GAIN(pAd);
2771 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
2772 }
2773 else
2774 {
2775 // 5.5 GHz band
2776 if (pAd->ate.TxWI.BW == BW_20)
2777 {
2778 R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
2779 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
2780 }
2781 else
2782 {
2783 R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
2784 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
2785 }
2786 }
2787
2788 //
2789 // On 11A, We should delay and wait RF/BBP to be stable
2790 // and the appropriate time should be 1000 micro seconds
2791 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
2792 //
2793 RTMPusecDelay(1000);
2794
2795 if (Channel > 14)
2796 {
2797 // When 5.5GHz band the LSB of TxPwr will be used to reduced 7dB or not.
2798 ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
2799 Channel,
2800 pAd->RfIcType,
2801 pAd->Antenna.field.TxPath,
2802 pAd->LatchRfRegs.R1,
2803 pAd->LatchRfRegs.R2,
2804 pAd->LatchRfRegs.R3,
2805 pAd->LatchRfRegs.R4));
2806 }
2807 else
2808 {
2809 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",
2810 Channel,
2811 pAd->RfIcType,
2812 (R3 & 0x00003e00) >> 9,
2813 (R4 & 0x000007c0) >> 6,
2814 pAd->Antenna.field.TxPath,
2815 pAd->LatchRfRegs.R1,
2816 pAd->LatchRfRegs.R2,
2817 pAd->LatchRfRegs.R3,
2818 pAd->LatchRfRegs.R4));
2819 }
2820}
2821
2822//
2823// In fact, no one will call this routine so far !
2824//
2825/*
2826 ==========================================================================
2827 Description:
2828 Gives CCK TX rate 2 more dB TX power.
2829 This routine works only in ATE mode.
2830
2831 calculate desired Tx power in RF R3.Tx0~5, should consider -
2832 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
2833 1. TxPowerPercentage
2834 2. auto calibration based on TSSI feedback
2835 3. extra 2 db for CCK
2836 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
2837
2838 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
2839 it should be called AFTER MlmeDynamicTxRateSwitching()
2840 ==========================================================================
2841 */
2842VOID ATEAsicAdjustTxPower(
2843 IN PRTMP_ADAPTER pAd)
2844{
2845 INT i, j;
2846 CHAR DeltaPwr = 0;
2847 BOOLEAN bAutoTxAgc = FALSE;
2848 UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
2849 UCHAR BbpR49 = 0, idx;
2850 PCHAR pTxAgcCompensate;
2851 ULONG TxPwr[5];
2852 CHAR Value;
2853
2854 /* no one calls this procedure so far */
2855 if (pAd->ate.TxWI.BW == BW_40)
2856 {
2857 if (pAd->ate.Channel > 14)
2858 {
2859 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
2860 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
2861 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
2862 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
2863 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
2864 }
2865 else
2866 {
2867 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
2868 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
2869 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
2870 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
2871 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
2872 }
2873 }
2874 else
2875 {
2876 if (pAd->ate.Channel > 14)
2877 {
2878 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
2879 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
2880 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
2881 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
2882 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
2883 }
2884 else
2885 {
2886 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
2887 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
2888 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
2889 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
2890 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
2891 }
2892 }
2893
2894 // TX power compensation for temperature variation based on TSSI.
2895 // Do it per 4 seconds.
2896 if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
2897 {
2898 if (pAd->ate.Channel <= 14)
2899 {
2900 /* bg channel */
2901 bAutoTxAgc = pAd->bAutoTxAgcG;
2902 TssiRef = pAd->TssiRefG;
2903 pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
2904 pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
2905 TxAgcStep = pAd->TxAgcStepG;
2906 pTxAgcCompensate = &pAd->TxAgcCompensateG;
2907 }
2908 else
2909 {
2910 /* a channel */
2911 bAutoTxAgc = pAd->bAutoTxAgcA;
2912 TssiRef = pAd->TssiRefA;
2913 pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
2914 pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
2915 TxAgcStep = pAd->TxAgcStepA;
2916 pTxAgcCompensate = &pAd->TxAgcCompensateA;
2917 }
2918
2919 if (bAutoTxAgc)
2920 {
2921 /* BbpR49 is unsigned char */
2922 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
2923
2924 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
2925 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
2926 /* step value is defined in pAd->TxAgcStepG for tx power value */
2927
2928 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
2929 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
2930 above value are examined in mass factory production */
2931 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
2932
2933 /* plus is 0x10 ~ 0x40, minus is 0x60 ~ 0x90 */
2934 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
2935 /* if value is 0x65, tx power will be -= TxAgcStep*(2-1) */
2936
2937 if (BbpR49 > pTssiMinusBoundary[1])
2938 {
2939 // Reading is larger than the reference value.
2940 // Check for how large we need to decrease the Tx power.
2941 for (idx = 1; idx < 5; idx++)
2942 {
2943 if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
2944 break;
2945 }
2946 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
2947// if (R3 > (ULONG) (TxAgcStep * (idx-1)))
2948 *pTxAgcCompensate = -(TxAgcStep * (idx-1));
2949// else
2950// *pTxAgcCompensate = -((UCHAR)R3);
2951
2952 DeltaPwr += (*pTxAgcCompensate);
2953 ATEDBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
2954 BbpR49, TssiRef, TxAgcStep, idx-1));
2955 }
2956 else if (BbpR49 < pTssiPlusBoundary[1])
2957 {
2958 // Reading is smaller than the reference value
2959 // check for how large we need to increase the Tx power
2960 for (idx = 1; idx < 5; idx++)
2961 {
2962 if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
2963 break;
2964 }
2965 // The index is the step we should increase, idx = 0 means there is nothing to compensate
2966 *pTxAgcCompensate = TxAgcStep * (idx-1);
2967 DeltaPwr += (*pTxAgcCompensate);
2968 ATEDBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
2969 BbpR49, TssiRef, TxAgcStep, idx-1));
2970 }
2971 else
2972 {
2973 *pTxAgcCompensate = 0;
2974 ATEDBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
2975 BbpR49, TssiRef, TxAgcStep, 0));
2976 }
2977 }
2978 }
2979 else
2980 {
2981 if (pAd->ate.Channel <= 14)
2982 {
2983 bAutoTxAgc = pAd->bAutoTxAgcG;
2984 pTxAgcCompensate = &pAd->TxAgcCompensateG;
2985 }
2986 else
2987 {
2988 bAutoTxAgc = pAd->bAutoTxAgcA;
2989 pTxAgcCompensate = &pAd->TxAgcCompensateA;
2990 }
2991
2992 if (bAutoTxAgc)
2993 DeltaPwr += (*pTxAgcCompensate);
2994 }
2995
2996 /* calculate delta power based on the percentage specified from UI */
2997 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
2998 // We lower TX power here according to the percentage specified from UI
2999 if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
3000 ;
3001 else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
3002 ;
3003 else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW
3004 {
3005 DeltaPwr -= 1;
3006 }
3007 else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW
3008 {
3009 DeltaPwr -= 3;
3010 }
3011 else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW
3012 {
3013 DeltaPwr -= 6;
3014 }
3015 else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW
3016 {
3017 DeltaPwr -= 9;
3018 }
3019 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW
3020 {
3021 DeltaPwr -= 12;
3022 }
3023
3024 /* reset different new tx power for different TX rate */
3025 for(i=0; i<5; i++)
3026 {
3027 if (TxPwr[i] != 0xffffffff)
3028 {
3029 for (j=0; j<8; j++)
3030 {
3031 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
3032
3033 if ((Value + DeltaPwr) < 0)
3034 {
3035 Value = 0; /* min */
3036 }
3037 else if ((Value + DeltaPwr) > 0xF)
3038 {
3039 Value = 0xF; /* max */
3040 }
3041 else
3042 {
3043 Value += DeltaPwr; /* temperature compensation */
3044 }
3045
3046 /* fill new value to CSR offset */
3047 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
3048 }
3049
3050 /* write tx power value to CSR */
3051 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
3052 TX power for OFDM 6M/9M
3053 TX power for CCK5.5M/11M
3054 TX power for CCK1M/2M */
3055 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
3056 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
3057
3058
3059 }
3060 }
3061
3062}
3063
3064/*
3065 ========================================================================
3066 Routine Description:
3067 Write TxWI for ATE mode.
3068
3069 Return Value:
3070 None
3071 ========================================================================
3072*/
3073
3074#ifdef RT2870
3075static VOID ATEWriteTxWI(
3076 IN PRTMP_ADAPTER pAd,
3077 IN PTXWI_STRUC pTxWI,
3078 IN BOOLEAN FRAG,
3079 IN BOOLEAN InsTimestamp,
3080 IN BOOLEAN AMPDU,
3081 IN BOOLEAN Ack,
3082 IN BOOLEAN NSeq, // HW new a sequence.
3083 IN UCHAR BASize,
3084 IN UCHAR WCID,
3085 IN ULONG Length,
3086 IN UCHAR PID,
3087 IN UCHAR MIMOps,
3088 IN UCHAR Txopmode,
3089 IN BOOLEAN CfAck,
3090 IN HTTRANSMIT_SETTING Transmit)
3091{
3092 //
3093 // Always use Long preamble before verifiation short preamble functionality works well.
3094 // Todo: remove the following line if short preamble functionality works
3095 //
3096 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
3097 pTxWI->FRAG= FRAG;
3098 pTxWI->TS= InsTimestamp;
3099 pTxWI->AMPDU = AMPDU;
3100
3101 pTxWI->MIMOps = PWR_ACTIVE;
3102 pTxWI->MpduDensity = 4;
3103 pTxWI->ACK = Ack;
3104 pTxWI->txop = Txopmode;
3105 pTxWI->NSEQ = NSeq;
3106 pTxWI->BAWinSize = BASize;
3107
3108 pTxWI->WirelessCliID = WCID;
3109 pTxWI->MPDUtotalByteCount = Length;
3110 pTxWI->PacketId = PID;
3111
3112 pTxWI->BW = Transmit.field.BW;
3113 pTxWI->ShortGI = Transmit.field.ShortGI;
3114 pTxWI->STBC= Transmit.field.STBC;
3115
3116 pTxWI->MCS = Transmit.field.MCS;
3117 pTxWI->PHYMODE= Transmit.field.MODE;
3118
3119#ifdef DOT11_N_SUPPORT
3120 //
3121 // MMPS is 802.11n features. Because TxWI->MCS > 7 must be HT mode,
3122 // so need not check if it's HT rate.
3123 //
3124 if ((MIMOps == MMPS_STATIC) && (pTxWI->MCS > 7))
3125 pTxWI->MCS = 7;
3126
3127 if ((MIMOps == MMPS_DYNAMIC) && (pTxWI->MCS > 7)) // SMPS protect 2 spatial.
3128 pTxWI->MIMOps = 1;
3129#endif // DOT11_N_SUPPORT //
3130
3131 pTxWI->CFACK = CfAck;
3132
3133 return;
3134}
3135#endif // RT2870 //
3136/*
3137 ========================================================================
3138
3139 Routine Description:
3140 Disable protection for ATE.
3141 ========================================================================
3142*/
3143VOID ATEDisableAsicProtect(
3144 IN PRTMP_ADAPTER pAd)
3145{
3146 PROT_CFG_STRUC ProtCfg, ProtCfg4;
3147 UINT32 Protect[6];
3148 USHORT offset;
3149 UCHAR i;
3150 UINT32 MacReg = 0;
3151
3152 // Config ASIC RTS threshold register
3153 RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
3154 MacReg &= 0xFF0000FF;
3155 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
3156 RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
3157
3158 // Initial common protection settings
3159 RTMPZeroMemory(Protect, sizeof(Protect));
3160 ProtCfg4.word = 0;
3161 ProtCfg.word = 0;
3162 ProtCfg.field.TxopAllowGF40 = 1;
3163 ProtCfg.field.TxopAllowGF20 = 1;
3164 ProtCfg.field.TxopAllowMM40 = 1;
3165 ProtCfg.field.TxopAllowMM20 = 1;
3166 ProtCfg.field.TxopAllowOfdm = 1;
3167 ProtCfg.field.TxopAllowCck = 1;
3168 ProtCfg.field.RTSThEn = 1;
3169 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
3170
3171 // Handle legacy(B/G) protection
3172 ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
3173 ProtCfg.field.ProtectCtrl = 0;
3174 Protect[0] = ProtCfg.word;
3175 Protect[1] = ProtCfg.word;
3176
3177 // NO PROTECT
3178 // 1.All STAs in the BSS are 20/40 MHz HT
3179 // 2. in ai 20/40MHz BSS
3180 // 3. all STAs are 20MHz in a 20MHz BSS
3181 // Pure HT. no protection.
3182
3183 // MM20_PROT_CFG
3184 // Reserved (31:27)
3185 // PROT_TXOP(25:20) -- 010111
3186 // PROT_NAV(19:18) -- 01 (Short NAV protection)
3187 // PROT_CTRL(17:16) -- 00 (None)
3188 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
3189 Protect[2] = 0x01744004;
3190
3191 // MM40_PROT_CFG
3192 // Reserved (31:27)
3193 // PROT_TXOP(25:20) -- 111111
3194 // PROT_NAV(19:18) -- 01 (Short NAV protection)
3195 // PROT_CTRL(17:16) -- 00 (None)
3196 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
3197 Protect[3] = 0x03f44084;
3198
3199 // CF20_PROT_CFG
3200 // Reserved (31:27)
3201 // PROT_TXOP(25:20) -- 010111
3202 // PROT_NAV(19:18) -- 01 (Short NAV protection)
3203 // PROT_CTRL(17:16) -- 00 (None)
3204 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
3205 Protect[4] = 0x01744004;
3206
3207 // CF40_PROT_CFG
3208 // Reserved (31:27)
3209 // PROT_TXOP(25:20) -- 111111
3210 // PROT_NAV(19:18) -- 01 (Short NAV protection)
3211 // PROT_CTRL(17:16) -- 00 (None)
3212 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
3213 Protect[5] = 0x03f44084;
3214
3215 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
3216
3217 offset = CCK_PROT_CFG;
3218 for (i = 0;i < 6;i++)
3219 RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
3220
3221}
3222
3223#ifdef RT2870
3224/*
3225 ========================================================================
3226 Routine Description:
3227 Write TxInfo for ATE mode.
3228
3229 Return Value:
3230 None
3231 ========================================================================
3232*/
3233static VOID ATEWriteTxInfo(
3234 IN PRTMP_ADAPTER pAd,
3235 IN PTXINFO_STRUC pTxInfo,
3236 IN USHORT USBDMApktLen,
3237 IN BOOLEAN bWiv,
3238 IN UCHAR QueueSel,
3239 IN UCHAR NextValid,
3240 IN UCHAR TxBurst)
3241{
3242 pTxInfo->USBDMATxPktLen = USBDMApktLen;
3243 pTxInfo->QSEL = QueueSel;
3244
3245 if (QueueSel != FIFO_EDCA)
3246 ATEDBGPRINT(RT_DEBUG_TRACE, ("=======> QueueSel != FIFO_EDCA<=======\n"));
3247
3248 pTxInfo->USBDMANextVLD = NextValid;
3249 pTxInfo->USBDMATxburst = TxBurst;
3250 pTxInfo->WIV = bWiv;
3251 pTxInfo->SwUseLastRound = 0;
3252 pTxInfo->rsv = 0;
3253 pTxInfo->rsv2 = 0;
3254
3255 return;
3256}
3257#endif // RT2870 //
3258
3259/* There are two ways to convert Rssi */
3260#if 1
3261//
3262// The way used with GET_LNA_GAIN().
3263//
3264CHAR ATEConvertToRssi(
3265 IN PRTMP_ADAPTER pAd,
3266 IN CHAR Rssi,
3267 IN UCHAR RssiNumber)
3268{
3269 UCHAR RssiOffset, LNAGain;
3270
3271 // Rssi equals to zero should be an invalid value
3272 if (Rssi == 0)
3273 return -99;
3274
3275 LNAGain = GET_LNA_GAIN(pAd);
3276 if (pAd->LatchRfRegs.Channel > 14)
3277 {
3278 if (RssiNumber == 0)
3279 RssiOffset = pAd->ARssiOffset0;
3280 else if (RssiNumber == 1)
3281 RssiOffset = pAd->ARssiOffset1;
3282 else
3283 RssiOffset = pAd->ARssiOffset2;
3284 }
3285 else
3286 {
3287 if (RssiNumber == 0)
3288 RssiOffset = pAd->BGRssiOffset0;
3289 else if (RssiNumber == 1)
3290 RssiOffset = pAd->BGRssiOffset1;
3291 else
3292 RssiOffset = pAd->BGRssiOffset2;
3293 }
3294
3295 return (-12 - RssiOffset - LNAGain - Rssi);
3296}
3297#else
3298//
3299// The way originally used in ATE of rt2860ap.
3300//
3301CHAR ATEConvertToRssi(
3302 IN PRTMP_ADAPTER pAd,
3303 IN CHAR Rssi,
3304 IN UCHAR RssiNumber)
3305{
3306 UCHAR RssiOffset, LNAGain;
3307
3308 // Rssi equals to zero should be an invalid value
3309 if (Rssi == 0)
3310 return -99;
3311
3312 if (pAd->LatchRfRegs.Channel > 14)
3313 {
3314 LNAGain = pAd->ALNAGain;
3315 if (RssiNumber == 0)
3316 RssiOffset = pAd->ARssiOffset0;
3317 else if (RssiNumber == 1)
3318 RssiOffset = pAd->ARssiOffset1;
3319 else
3320 RssiOffset = pAd->ARssiOffset2;
3321 }
3322 else
3323 {
3324 LNAGain = pAd->BLNAGain;
3325 if (RssiNumber == 0)
3326 RssiOffset = pAd->BGRssiOffset0;
3327 else if (RssiNumber == 1)
3328 RssiOffset = pAd->BGRssiOffset1;
3329 else
3330 RssiOffset = pAd->BGRssiOffset2;
3331 }
3332
3333 return (-32 - RssiOffset + LNAGain - Rssi);
3334}
3335#endif /* end of #if 1 */
3336
3337/*
3338 ========================================================================
3339
3340 Routine Description:
3341 Set Japan filter coefficients if needed.
3342 Note:
3343 This routine should only be called when
3344 entering TXFRAME mode or TXCONT mode.
3345
3346 ========================================================================
3347*/
3348static VOID SetJapanFilter(
3349 IN PRTMP_ADAPTER pAd)
3350{
3351 UCHAR BbpData = 0;
3352
3353 //
3354 // If Channel=14 and Bandwidth=20M and Mode=CCK, set BBP R4 bit5=1
3355 // (Japan Tx filter coefficients)when (TXFRAME or TXCONT).
3356 //
3357 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpData);
3358
3359 if ((pAd->ate.TxWI.PHYMODE == MODE_CCK) && (pAd->ate.Channel == 14) && (pAd->ate.TxWI.BW == BW_20))
3360 {
3361 BbpData |= 0x20; // turn on
3362 ATEDBGPRINT(RT_DEBUG_TRACE, ("SetJapanFilter!!!\n"));
3363 }
3364 else
3365 {
3366 BbpData &= 0xdf; // turn off
3367 ATEDBGPRINT(RT_DEBUG_TRACE, ("ClearJapanFilter!!!\n"));
3368 }
3369
3370 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData);
3371}
3372
3373VOID ATESampleRssi(
3374 IN PRTMP_ADAPTER pAd,
3375 IN PRXWI_STRUC pRxWI)
3376{
3377 /* There are two ways to collect RSSI. */
3378#if 1
3379 //pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
3380 if (pRxWI->RSSI0 != 0)
3381 {
3382 pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
3383 pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
3384 pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3;
3385 }
3386 if (pRxWI->RSSI1 != 0)
3387 {
3388 pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
3389 pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
3390 pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3;
3391 }
3392 if (pRxWI->RSSI2 != 0)
3393 {
3394 pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
3395 pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
3396 pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3;
3397 }
3398
3399 pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);// CHAR ==> UCHAR ?
3400 pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);// CHAR ==> UCHAR ?
3401
3402 pAd->ate.NumOfAvgRssiSample ++;
3403#else
3404 pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);
3405 pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);
3406 pAd->ate.RxCntPerSec++;
3407 pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
3408 pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
3409 pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
3410 pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
3411 pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3;
3412 pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
3413 pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3;
3414 pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
3415 pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3;
3416 pAd->ate.NumOfAvgRssiSample ++;
3417#endif
3418}
3419
3420#ifdef CONFIG_STA_SUPPORT
3421VOID RTMPStationStop(
3422 IN PRTMP_ADAPTER pAd)
3423{
3424// BOOLEAN Cancelled;
3425
3426 ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStop\n"));
3427
3428#if 0
3429 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
3430 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
3431 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
3432 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
3433 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
3434 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
3435#endif
3436 // For rx statistics, we need to keep this timer running.
3437// RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
3438
3439 ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStop\n"));
3440}
3441
3442VOID RTMPStationStart(
3443 IN PRTMP_ADAPTER pAd)
3444{
3445 ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStart\n"));
3446 ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStart\n"));
3447}
3448#endif // CONFIG_STA_SUPPORT //
3449
3450/*
3451 ==========================================================================
3452 Description:
3453 Setup Frame format.
3454 NOTE:
3455 This routine should only be used in ATE mode.
3456 ==========================================================================
3457 */
3458
3459#ifdef RT2870
3460/*======================Start of RT2870======================*/
3461/* */
3462/* */
3463static INT ATESetUpFrame(
3464 IN PRTMP_ADAPTER pAd,
3465 IN UINT32 TxIdx)
3466{
3467 UINT j;
3468 PTX_CONTEXT pNullContext;
3469 PUCHAR pDest;
3470 HTTRANSMIT_SETTING TxHTPhyMode;
3471 PTXWI_STRUC pTxWI;
3472 PTXINFO_STRUC pTxInfo;
3473 UINT32 TransferBufferLength, OrgBufferLength = 0;
3474 UCHAR padLen = 0;
3475#ifdef RALINK_28xx_QA
3476 PHEADER_802_11 pHeader80211 = NULL;
3477#endif // RALINK_28xx_QA //
3478
3479 if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
3480 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) ||
3481 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
3482 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
3483 {
3484 return -1;
3485 }
3486
3487 /* We always use QID_AC_BE and FIFO_EDCA in ATE mode. */
3488
3489 pNullContext = &(pAd->NullContext);
3490 ASSERT(pNullContext != NULL);
3491
3492 if (pNullContext->InUse == FALSE)
3493 {
3494 // Set the in use bit
3495 pNullContext->InUse = TRUE;
3496 NdisZeroMemory(&(pAd->NullFrame), sizeof(HEADER_802_11));
3497
3498 // Fill 802.11 header.
3499#ifdef RALINK_28xx_QA
3500 if (pAd->ate.bQATxStart == TRUE)
3501 {
3502 pHeader80211 = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);
3503// pDest = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);
3504// pHeader80211 = (PHEADER_802_11)pDest;
3505 }
3506 else
3507#endif // RALINK_28xx_QA //
3508 {
3509 // Fill 802.11 header.
3510 NdisMoveMemory(&(pAd->NullFrame), TemplateFrame, sizeof(HEADER_802_11));
3511 }
3512#ifdef RT_BIG_ENDIAN
3513 RTMPFrameEndianChange(pAd, (PUCHAR)&(pAd->NullFrame), DIR_READ, FALSE);
3514#endif // RT_BIG_ENDIAN //
3515
3516#ifdef RALINK_28xx_QA
3517 if (pAd->ate.bQATxStart == TRUE)
3518 {
3519 /* modify sequence number.... */
3520 if (pAd->ate.TxDoneCount == 0)
3521 {
3522 pAd->ate.seq = pHeader80211->Sequence;
3523 }
3524 else
3525 {
3526 pHeader80211->Sequence = ++pAd->ate.seq;
3527 }
3528 /* We already got all the addr. fields from QA GUI. */
3529 }
3530 else
3531#endif // RALINK_28xx_QA //
3532 {
3533 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->ate.Addr1);
3534 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->ate.Addr2);
3535 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->ate.Addr3);
3536 }
3537
3538 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], TX_BUFFER_NORMSIZE);//???
3539 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
3540
3541#ifdef RALINK_28xx_QA
3542 if (pAd->ate.bQATxStart == TRUE)
3543 {
3544 // Avoid to exceed the range of WirelessPacket[].
3545 ASSERT(pAd->ate.TxInfo.USBDMATxPktLen <= (MAX_FRAME_SIZE - 34/* == 2312 */));
3546 NdisMoveMemory(pTxInfo, &(pAd->ate.TxInfo), sizeof(pAd->ate.TxInfo));
3547 }
3548 else
3549#endif // RALINK_28xx_QA //
3550 {
3551 // Avoid to exceed the range of WirelessPacket[].
3552 ASSERT(pAd->ate.TxLength <= (MAX_FRAME_SIZE - 34/* == 2312 */));
3553
3554 // pTxInfo->USBDMATxPktLen will be updated to include padding later.
3555 ATEWriteTxInfo(pAd, pTxInfo, (USHORT)(TXWI_SIZE + pAd->ate.TxLength), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
3556 pTxInfo->QSEL = FIFO_EDCA;
3557 }
3558
3559 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
3560
3561 // Fill TxWI.
3562 if (pAd->ate.bQATxStart == TRUE)
3563 {
3564 TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
3565 TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
3566 TxHTPhyMode.field.STBC = pAd->ate.TxWI.STBC;
3567 TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
3568 TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
3569 ATEWriteTxWI(pAd, pTxWI, pAd->ate.TxWI.FRAG, pAd->ate.TxWI.TS, pAd->ate.TxWI.AMPDU, pAd->ate.TxWI.ACK, pAd->ate.TxWI.NSEQ,
3570 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);
3571 }
3572 else
3573 {
3574 TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
3575 TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
3576 TxHTPhyMode.field.STBC = 0;
3577 TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
3578 TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
3579
3580 ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE/* No ack required. */, FALSE, 0, BSSID_WCID, pAd->ate.TxLength,
3581 0, 0, IFS_HTTXOP, FALSE, TxHTPhyMode);// "MMPS_STATIC" instead of "MMPS_DYNAMIC" ???
3582 }
3583
3584 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
3585
3586 pDest = &(pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE+sizeof(HEADER_802_11)]);
3587
3588 // Prepare frame payload
3589#ifdef RALINK_28xx_QA
3590 if (pAd->ate.bQATxStart == TRUE)
3591 {
3592 // copy pattern
3593 if ((pAd->ate.PLen != 0))
3594 {
3595 for (j = 0; j < pAd->ate.DLen; j+=pAd->ate.PLen)
3596 {
3597 RTMPMoveMemory(pDest, pAd->ate.Pattern, pAd->ate.PLen);
3598 pDest += pAd->ate.PLen;
3599 }
3600 }
3601 TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxWI.MPDUtotalByteCount;
3602 }
3603 else
3604#endif // RALINK_28xx_QA //
3605 {
3606 for (j = 0; j < (pAd->ate.TxLength - sizeof(HEADER_802_11)); j++)
3607 {
3608 *pDest = 0xA5;
3609 pDest += 1;
3610 }
3611 TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxLength;
3612 }
3613
3614#if 1
3615 OrgBufferLength = TransferBufferLength;
3616 TransferBufferLength = (TransferBufferLength + 3) & (~3);
3617
3618 // Always add 4 extra bytes at every packet.
3619 padLen = TransferBufferLength - OrgBufferLength + 4;/* 4 == last packet padding */
3620 ASSERT((padLen <= (RTMP_PKT_TAIL_PADDING - 4/* 4 == MaxBulkOutsize alignment padding */)));
3621
3622 /* Now memzero all extra padding bytes. */
3623 NdisZeroMemory(pDest, padLen);
3624 pDest += padLen;
3625#else
3626 if ((TransferBufferLength % 4) == 1)
3627 {
3628 NdisZeroMemory(pDest, 7);
3629 pDest += 7;
3630 TransferBufferLength += 3;
3631 }
3632 else if ((TransferBufferLength % 4) == 2)
3633 {
3634 NdisZeroMemory(pDest, 6);
3635 pDest += 6;
3636 TransferBufferLength += 2;
3637 }
3638 else if ((TransferBufferLength % 4) == 3)
3639 {
3640 NdisZeroMemory(pDest, 5);
3641 pDest += 5;
3642 TransferBufferLength += 1;
3643 }
3644#endif // 1 //
3645
3646 // Update pTxInfo->USBDMATxPktLen to include padding.
3647 pTxInfo->USBDMATxPktLen = TransferBufferLength - TXINFO_SIZE;
3648
3649 TransferBufferLength += 4;
3650
3651 // If TransferBufferLength is multiple of 64, add extra 4 bytes again.
3652 if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0)
3653 {
3654 NdisZeroMemory(pDest, 4);
3655 TransferBufferLength += 4;
3656 }
3657
3658 // Fill out frame length information for global Bulk out arbitor
3659 pAd->NullContext.BulkOutSize = TransferBufferLength;
3660 }
3661#ifdef RT_BIG_ENDIAN
3662 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
3663 RTMPFrameEndianChange(pAd, (((PUCHAR)pTxInfo)+TXWI_SIZE+TXINFO_SIZE), DIR_WRITE, FALSE);
3664 RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
3665#endif // RT_BIG_ENDIAN //
3666 return 0;
3667}
3668
3669VOID ATE_RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
3670{
3671 PRTMP_ADAPTER pAd;
3672 PTX_CONTEXT pNullContext;
3673 UCHAR BulkOutPipeId;
3674 NTSTATUS Status;
3675 unsigned long IrqFlags;
3676 ULONG OldValue;
3677
3678 pNullContext = (PTX_CONTEXT)pUrb->context;
3679 pAd = pNullContext->pAd;
3680
3681
3682 // Reset Null frame context flags
3683 pNullContext->IRPPending = FALSE;
3684 pNullContext->InUse = FALSE;
3685 Status = pUrb->status;
3686
3687 // Store BulkOut PipeId
3688 BulkOutPipeId = pNullContext->BulkOutPipeId;
3689 pAd->BulkOutDataOneSecCount++;
3690
3691 if (Status == USB_ST_NOERROR)
3692 {
3693#ifdef RALINK_28xx_QA
3694 if ((ATE_ON(pAd)) && (pAd->ate.bQATxStart == TRUE))
3695 {
3696 if (pAd->ate.QID == BulkOutPipeId)
3697 {
3698 // Let Rx can have a chance to break in during Tx process,
3699 // especially for loopback mode in QA ATE.
3700 // To trade off between tx performance and loopback mode integrity.
3701 /* Q : Now Rx is handled by tasklet, do we still need this delay ? */
3702 /* Ans : Even tasklet is used, Rx/Tx < 1 if we do not delay for a while right here. */
3703 RTMPusecDelay(500);
3704 pAd->ate.TxDoneCount++;
3705 pAd->RalinkCounters.KickTxCount++;
3706 ASSERT(pAd->ate.QID == 0);
3707 pAd->ate.TxAc0++;
3708 }
3709 }
3710#endif // RALINK_28xx_QA //
3711 pAd->BulkOutComplete++;
3712
3713 pAd->Counters8023.GoodTransmits++;
3714
3715 /* Don't worry about the queue is empty or not. This function will check itself. */
3716 RTMPDeQueuePacket(pAd, TRUE, BulkOutPipeId, MAX_TX_PROCESS);
3717
3718 /* In 28xx, SendTxWaitQueue ==> TxSwQueue */
3719/*
3720 if (pAd->SendTxWaitQueue[BulkOutPipeId].Number > 0)
3721 {
3722 RTMPDeQueuePacket(pAd, BulkOutPipeId);
3723 }
3724*/
3725 }
3726 else // STATUS_OTHER
3727 {
3728 pAd->BulkOutCompleteOther++;
3729
3730 ATEDBGPRINT(RT_DEBUG_ERROR, ("BulkOutDataPacket Failed STATUS_OTHER = 0x%x . \n", Status));
3731 ATEDBGPRINT(RT_DEBUG_ERROR, (">>BulkOutReq=0x%lx, BulkOutComplete=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete));
3732
3733 if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
3734 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
3735 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
3736 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
3737 {
3738 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
3739 /* In 28xx, RT_OID_USB_RESET_BULK_OUT ==> CMDTHREAD_RESET_BULK_OUT */
3740 RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
3741 // Check
3742 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
3743 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
3744 pAd->bulkResetPipeid = BulkOutPipeId;
3745 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
3746 return;
3747 }
3748 }
3749
3750
3751
3752 if (atomic_read(&pAd->BulkOutRemained) > 0)
3753 {
3754 atomic_dec(&pAd->BulkOutRemained);
3755 }
3756
3757 // 1st - Transmit Success
3758 OldValue = pAd->WlanCounters.TransmittedFragmentCount.u.LowPart;
3759 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart++;
3760
3761 if (pAd->WlanCounters.TransmittedFragmentCount.u.LowPart < OldValue)
3762 {
3763 pAd->WlanCounters.TransmittedFragmentCount.u.HighPart++;
3764 }
3765
3766 if(((pAd->ContinBulkOut == TRUE ) ||(atomic_read(&pAd->BulkOutRemained) > 0)) && (pAd->ate.Mode & ATE_TXFRAME))
3767 {
3768 RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
3769 }
3770 else
3771 {
3772 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
3773#ifdef RALINK_28xx_QA
3774 pAd->ate.TxStatus = 0;
3775#endif // RALINK_28xx_QA //
3776 }
3777
3778 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
3779 pAd->BulkOutPending[BulkOutPipeId] = FALSE;
3780 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
3781
3782 // Always call Bulk routine, even reset bulk.
3783 // The protection of rest bulk should be in BulkOut routine.
3784 RTUSBKickBulkOut(pAd);
3785}
3786
3787/*
3788 ========================================================================
3789
3790 Routine Description:
3791
3792 Arguments:
3793
3794 Return Value:
3795
3796 Note:
3797
3798 ========================================================================
3799*/
3800VOID ATE_RTUSBBulkOutDataPacket(
3801 IN PRTMP_ADAPTER pAd,
3802 IN UCHAR BulkOutPipeId)
3803{
3804 PTX_CONTEXT pNullContext = &(pAd->NullContext);
3805 PURB pUrb;
3806 int ret = 0;
3807 unsigned long IrqFlags;
3808
3809
3810 ASSERT(BulkOutPipeId == 0);
3811
3812 /* Build up the frame first. */
3813// ATESetUpFrame(pAd, 0);
3814
3815 BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
3816
3817 if (pAd->BulkOutPending[BulkOutPipeId] == TRUE)
3818 {
3819 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
3820 return;
3821 }
3822
3823 pAd->BulkOutPending[BulkOutPipeId] = TRUE;
3824 BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
3825
3826 // Increase Total transmit byte counter
3827 pAd->RalinkCounters.OneSecTransmittedByteCount += pNullContext->BulkOutSize;
3828 pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
3829
3830 // Clear ATE frame bulk out flag
3831 RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
3832
3833 // Init Tx context descriptor
3834 pNullContext->IRPPending = TRUE;
3835 RTUSBInitTxDesc(pAd, pNullContext, BulkOutPipeId, (usb_complete_t)ATE_RTUSBBulkOutDataPacketComplete);
3836 pUrb = pNullContext->pUrb;
3837
3838 if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
3839 {
3840 ATEDBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
3841 return;
3842 }
3843
3844 pAd->BulkOutReq++;
3845 return;
3846
3847}
3848
3849/*
3850 ========================================================================
3851
3852 Routine Description:
3853
3854 Arguments:
3855
3856 Return Value:
3857
3858 Note:
3859
3860 ========================================================================
3861*/
3862VOID ATE_RTUSBCancelPendingBulkInIRP(
3863 IN PRTMP_ADAPTER pAd)
3864{
3865 PRX_CONTEXT pRxContext;
3866 UINT i;
3867
3868 ATEDBGPRINT(RT_DEBUG_TRACE, ("--->ATE_RTUSBCancelPendingBulkInIRP\n"));
3869#if 1
3870 for ( i = 0; i < (RX_RING_SIZE); i++)
3871 {
3872 pRxContext = &(pAd->RxContext[i]);
3873 if(pRxContext->IRPPending == TRUE)
3874 {
3875 RTUSB_UNLINK_URB(pRxContext->pUrb);
3876 pRxContext->IRPPending = FALSE;
3877 pRxContext->InUse = FALSE;
3878 //NdisInterlockedDecrement(&pAd->PendingRx);
3879 //pAd->PendingRx--;
3880 }
3881 }
3882#else
3883 for ( i = 0; i < (RX_RING_SIZE); i++)
3884 {
3885 pRxContext = &(pAd->RxContext[i]);
3886 if(atomic_read(&pRxContext->IrpLock) == IRPLOCK_CANCELABLE)
3887 {
3888 RTUSB_UNLINK_URB(pRxContext->pUrb);
3889 }
3890 InterlockedExchange(&pRxContext->IrpLock, IRPLOCK_CANCE_START);
3891 }
3892#endif // 1 //
3893 ATEDBGPRINT(RT_DEBUG_TRACE, ("<---ATE_RTUSBCancelPendingBulkInIRP\n"));
3894 return;
3895}
3896#endif // RT2870 //
3897
3898VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
3899{
3900 USHORT i;
3901 USHORT value;
3902
3903 for (i = 0 ; i < EEPROM_SIZE/2 ; )
3904 {
3905 /* "value" is expecially for some compilers... */
3906 RT28xx_EEPROM_READ16(pAd, i*2, value);
3907 Data[i] = value;
3908 i++;
3909 }
3910}
3911
3912VOID rt_ee_write_all(PRTMP_ADAPTER pAd, USHORT *Data)
3913{
3914 USHORT i;
3915 USHORT value;
3916
3917 for (i = 0 ; i < EEPROM_SIZE/2 ; )
3918 {
3919 /* "value" is expecially for some compilers... */
3920 value = Data[i];
3921 RT28xx_EEPROM_WRITE16(pAd, i*2, value);
3922 i ++;
3923 }
3924}
3925#ifdef RALINK_28xx_QA
3926VOID ATE_QA_Statistics(
3927 IN PRTMP_ADAPTER pAd,
3928 IN PRXWI_STRUC pRxWI,
3929 IN PRT28XX_RXD_STRUC pRxD,
3930 IN PHEADER_802_11 pHeader)
3931{
3932 // update counter first
3933 if (pHeader != NULL)
3934 {
3935 if (pHeader->FC.Type == BTYPE_DATA)
3936 {
3937 if (pRxD->U2M)
3938 pAd->ate.U2M++;
3939 else
3940 pAd->ate.OtherData++;
3941 }
3942 else if (pHeader->FC.Type == BTYPE_MGMT)
3943 {
3944 if (pHeader->FC.SubType == SUBTYPE_BEACON)
3945 pAd->ate.Beacon++;
3946 else
3947 pAd->ate.OtherCount++;
3948 }
3949 else if (pHeader->FC.Type == BTYPE_CNTL)
3950 {
3951 pAd->ate.OtherCount++;
3952 }
3953 }
3954 pAd->ate.RSSI0 = pRxWI->RSSI0;
3955 pAd->ate.RSSI1 = pRxWI->RSSI1;
3956 pAd->ate.RSSI2 = pRxWI->RSSI2;
3957 pAd->ate.SNR0 = pRxWI->SNR0;
3958 pAd->ate.SNR1 = pRxWI->SNR1;
3959}
3960
3961/* command id with Cmd Type == 0x0008(for 28xx)/0x0005(for iNIC) */
3962#define RACFG_CMD_RF_WRITE_ALL 0x0000
3963#define RACFG_CMD_E2PROM_READ16 0x0001
3964#define RACFG_CMD_E2PROM_WRITE16 0x0002
3965#define RACFG_CMD_E2PROM_READ_ALL 0x0003
3966#define RACFG_CMD_E2PROM_WRITE_ALL 0x0004
3967#define RACFG_CMD_IO_READ 0x0005
3968#define RACFG_CMD_IO_WRITE 0x0006
3969#define RACFG_CMD_IO_READ_BULK 0x0007
3970#define RACFG_CMD_BBP_READ8 0x0008
3971#define RACFG_CMD_BBP_WRITE8 0x0009
3972#define RACFG_CMD_BBP_READ_ALL 0x000a
3973#define RACFG_CMD_GET_COUNTER 0x000b
3974#define RACFG_CMD_CLEAR_COUNTER 0x000c
3975
3976#define RACFG_CMD_RSV1 0x000d
3977#define RACFG_CMD_RSV2 0x000e
3978#define RACFG_CMD_RSV3 0x000f
3979
3980#define RACFG_CMD_TX_START 0x0010
3981#define RACFG_CMD_GET_TX_STATUS 0x0011
3982#define RACFG_CMD_TX_STOP 0x0012
3983#define RACFG_CMD_RX_START 0x0013
3984#define RACFG_CMD_RX_STOP 0x0014
3985#define RACFG_CMD_GET_NOISE_LEVEL 0x0015
3986
3987#define RACFG_CMD_ATE_START 0x0080
3988#define RACFG_CMD_ATE_STOP 0x0081
3989
3990#define RACFG_CMD_ATE_START_TX_CARRIER 0x0100
3991#define RACFG_CMD_ATE_START_TX_CONT 0x0101
3992#define RACFG_CMD_ATE_START_TX_FRAME 0x0102
3993#define RACFG_CMD_ATE_SET_BW 0x0103
3994#define RACFG_CMD_ATE_SET_TX_POWER0 0x0104
3995#define RACFG_CMD_ATE_SET_TX_POWER1 0x0105
3996#define RACFG_CMD_ATE_SET_FREQ_OFFSET 0x0106
3997#define RACFG_CMD_ATE_GET_STATISTICS 0x0107
3998#define RACFG_CMD_ATE_RESET_COUNTER 0x0108
3999#define RACFG_CMD_ATE_SEL_TX_ANTENNA 0x0109
4000#define RACFG_CMD_ATE_SEL_RX_ANTENNA 0x010a
4001#define RACFG_CMD_ATE_SET_PREAMBLE 0x010b
4002#define RACFG_CMD_ATE_SET_CHANNEL 0x010c
4003#define RACFG_CMD_ATE_SET_ADDR1 0x010d
4004#define RACFG_CMD_ATE_SET_ADDR2 0x010e
4005#define RACFG_CMD_ATE_SET_ADDR3 0x010f
4006#define RACFG_CMD_ATE_SET_RATE 0x0110
4007#define RACFG_CMD_ATE_SET_TX_FRAME_LEN 0x0111
4008#define RACFG_CMD_ATE_SET_TX_FRAME_COUNT 0x0112
4009#define RACFG_CMD_ATE_START_RX_FRAME 0x0113
4010#define RACFG_CMD_ATE_E2PROM_READ_BULK 0x0114
4011#define RACFG_CMD_ATE_E2PROM_WRITE_BULK 0x0115
4012#define RACFG_CMD_ATE_IO_WRITE_BULK 0x0116
4013#define RACFG_CMD_ATE_BBP_READ_BULK 0x0117
4014#define RACFG_CMD_ATE_BBP_WRITE_BULK 0x0118
4015#define RACFG_CMD_ATE_RF_READ_BULK 0x0119
4016#define RACFG_CMD_ATE_RF_WRITE_BULK 0x011a
4017
4018
4019
4020#define A2Hex(_X, _p) \
4021{ \
4022 UCHAR *p; \
4023 _X = 0; \
4024 p = _p; \
4025 while (((*p >= 'a') && (*p <= 'f')) || ((*p >= 'A') && (*p <= 'F')) || ((*p >= '0') && (*p <= '9'))) \
4026 { \
4027 if ((*p >= 'a') && (*p <= 'f')) \
4028 _X = _X * 16 + *p - 87; \
4029 else if ((*p >= 'A') && (*p <= 'F')) \
4030 _X = _X * 16 + *p - 55; \
4031 else if ((*p >= '0') && (*p <= '9')) \
4032 _X = _X * 16 + *p - 48; \
4033 p++; \
4034 } \
4035}
4036
4037
4038static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
4039static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
4040static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len);
4041
4042#ifdef UCOS
4043int ate_copy_to_user(
4044 IN PUCHAR payload,
4045 IN PUCHAR msg,
4046 IN INT len)
4047{
4048 memmove(payload, msg, len);
4049 return 0;
4050}
4051
4052#undef copy_to_user
4053#define copy_to_user(x,y,z) ate_copy_to_user((PUCHAR)x, (PUCHAR)y, z)
4054#endif // UCOS //
4055
4056#define LEN_OF_ARG 16
4057
4058VOID RtmpDoAte(
4059 IN PRTMP_ADAPTER pAdapter,
4060 IN struct iwreq *wrq)
4061{
4062 unsigned short Command_Id;
4063 struct ate_racfghdr *pRaCfg;
4064 INT Status = NDIS_STATUS_SUCCESS;
4065
4066
4067
4068 if((pRaCfg = kmalloc(sizeof(struct ate_racfghdr), GFP_KERNEL)) == NULL)
4069 {
4070 Status = -EINVAL;
4071 return;
4072 }
4073
4074 NdisZeroMemory(pRaCfg, sizeof(struct ate_racfghdr));
4075
4076 if (copy_from_user((PUCHAR)pRaCfg, wrq->u.data.pointer, wrq->u.data.length))
4077 {
4078 Status = -EFAULT;
4079 kfree(pRaCfg);
4080 return;
4081 }
4082
4083
4084 Command_Id = ntohs(pRaCfg->command_id);
4085
4086 ATEDBGPRINT(RT_DEBUG_TRACE,("\n%s: Command_Id = 0x%04x !\n", __FUNCTION__, Command_Id));
4087
4088 switch (Command_Id)
4089 {
4090 // We will get this command when QA starts.
4091 case RACFG_CMD_ATE_START:
4092 {
4093 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START\n"));
4094
4095 // prepare feedback as soon as we can to avoid QA timeout.
4096 pRaCfg->length = htons(2);
4097 pRaCfg->status = htons(0);
4098
4099 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4100 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4101 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4102
4103 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
4104
4105 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4106 {
4107 ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_ATE_START\n"));
4108 Status = -EFAULT;
4109 }
4110 else
4111 {
4112 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START is done !\n"));
4113 }
4114 Set_ATE_Proc(pAdapter, "ATESTART");
4115 }
4116 break;
4117
4118 // We will get this command either QA is closed or ated is killed by user.
4119 case RACFG_CMD_ATE_STOP:
4120 {
4121#ifndef UCOS
4122 INT32 ret;
4123#endif // !UCOS //
4124
4125 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_STOP\n"));
4126
4127 // Distinguish this command came from QA(via ated)
4128 // or ate daemon according to the existence of pid in payload.
4129 // No need to prepare feedback if this cmd came directly from ate daemon.
4130 pRaCfg->length = ntohs(pRaCfg->length);
4131
4132 if (pRaCfg->length == sizeof(pAdapter->ate.AtePid))
4133 {
4134 // This command came from QA.
4135 // Get the pid of ATE daemon.
4136 memcpy((UCHAR *)&pAdapter->ate.AtePid,
4137 (&pRaCfg->data[0]) - 2/* == &(pRaCfg->status) */,
4138 sizeof(pAdapter->ate.AtePid));
4139
4140 // prepare feedback as soon as we can to avoid QA timeout.
4141 pRaCfg->length = htons(2);
4142 pRaCfg->status = htons(0);
4143
4144 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4145 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4146 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4147
4148 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
4149
4150 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4151 {
4152 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_STOP\n"));
4153 Status = -EFAULT;
4154 }
4155
4156 //
4157 // kill ATE daemon when leaving ATE mode.
4158 // We must kill ATE daemon first before setting ATESTOP,
4159 // or Microsoft will report sth. wrong.
4160#ifndef UCOS
4161 ret = KILL_THREAD_PID(pAdapter->ate.AtePid, SIGTERM, 1);
4162 if (ret)
4163 {
4164 ATEDBGPRINT(RT_DEBUG_ERROR, ("%s: unable to signal thread\n", pAdapter->net_dev->name));
4165 }
4166#endif // !UCOS //
4167 }
4168
4169 // AP might have in ATE_STOP mode due to cmd from QA.
4170 if (ATE_ON(pAdapter))
4171 {
4172 // Someone has killed ate daemon while QA GUI is still open.
4173 Set_ATE_Proc(pAdapter, "ATESTOP");
4174 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_AP_START is done !\n"));
4175 }
4176 }
4177 break;
4178
4179 case RACFG_CMD_RF_WRITE_ALL:
4180 {
4181 UINT32 R1, R2, R3, R4;
4182 USHORT channel;
4183
4184 memcpy(&R1, pRaCfg->data-2, 4);
4185 memcpy(&R2, pRaCfg->data+2, 4);
4186 memcpy(&R3, pRaCfg->data+6, 4);
4187 memcpy(&R4, pRaCfg->data+10, 4);
4188 memcpy(&channel, pRaCfg->data+14, 2);
4189
4190 pAdapter->LatchRfRegs.R1 = ntohl(R1);
4191 pAdapter->LatchRfRegs.R2 = ntohl(R2);
4192 pAdapter->LatchRfRegs.R3 = ntohl(R3);
4193 pAdapter->LatchRfRegs.R4 = ntohl(R4);
4194 pAdapter->LatchRfRegs.Channel = ntohs(channel);
4195
4196 RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R1);
4197 RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R2);
4198 RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R3);
4199 RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R4);
4200
4201 // prepare feedback
4202 pRaCfg->length = htons(2);
4203 pRaCfg->status = htons(0);
4204
4205 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4206 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4207 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4208
4209 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
4210 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4211 {
4212 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RF_WRITE_ALL\n"));
4213 Status = -EFAULT;
4214 }
4215 else
4216 {
4217 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RF_WRITE_ALL is done !\n"));
4218 }
4219 }
4220 break;
4221
4222 case RACFG_CMD_E2PROM_READ16:
4223 {
4224 USHORT offset, value, tmp;
4225
4226 offset = ntohs(pRaCfg->status);
4227 /* "tmp" is expecially for some compilers... */
4228 RT28xx_EEPROM_READ16(pAdapter, offset, tmp);
4229 value = tmp;
4230 value = htons(value);
4231
4232 ATEDBGPRINT(RT_DEBUG_TRACE,("EEPROM Read offset = 0x%04x, value = 0x%04x\n", offset, value));
4233
4234 // prepare feedback
4235 pRaCfg->length = htons(4);
4236 pRaCfg->status = htons(0);
4237 memcpy(pRaCfg->data, &value, 2);
4238
4239 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4240 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4241 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4242
4243 ATEDBGPRINT(RT_DEBUG_TRACE, ("sizeof(struct ate_racfghdr) = %d\n", sizeof(struct ate_racfghdr)));
4244 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
4245
4246 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4247 {
4248 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ16\n"));
4249 Status = -EFAULT;
4250 }
4251 else
4252 {
4253 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ16 is done !\n"));
4254 }
4255 }
4256 break;
4257
4258 case RACFG_CMD_E2PROM_WRITE16:
4259 {
4260 USHORT offset, value;
4261
4262 offset = ntohs(pRaCfg->status);
4263 memcpy(&value, pRaCfg->data, 2);
4264 value = ntohs(value);
4265 RT28xx_EEPROM_WRITE16(pAdapter, offset, value);
4266
4267 // prepare feedback
4268 pRaCfg->length = htons(2);
4269 pRaCfg->status = htons(0);
4270 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4271 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4272 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4273
4274 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4275 {
4276 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE16\n"));
4277 Status = -EFAULT;
4278 }
4279 else
4280 {
4281 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_WRITE16 is done !\n"));
4282 }
4283 }
4284 break;
4285
4286 case RACFG_CMD_E2PROM_READ_ALL:
4287 {
4288 USHORT buffer[EEPROM_SIZE/2];
4289
4290 rt_ee_read_all(pAdapter,(USHORT *)buffer);
4291 memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer, EEPROM_SIZE);
4292
4293 // prepare feedback
4294 pRaCfg->length = htons(2+EEPROM_SIZE);
4295 pRaCfg->status = htons(0);
4296 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4297 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4298 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4299
4300 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4301 {
4302 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ_ALL\n"));
4303 Status = -EFAULT;
4304 }
4305 else
4306 {
4307 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ_ALL is done !\n"));
4308 }
4309 }
4310 break;
4311
4312 case RACFG_CMD_E2PROM_WRITE_ALL:
4313 {
4314 USHORT buffer[EEPROM_SIZE/2];
4315
4316 NdisZeroMemory((UCHAR *)buffer, EEPROM_SIZE);
4317 memcpy_exs(pAdapter, (UCHAR *)buffer, (UCHAR *)&pRaCfg->status, EEPROM_SIZE);
4318 rt_ee_write_all(pAdapter,(USHORT *)buffer);
4319
4320 // prepare feedback
4321 pRaCfg->length = htons(2);
4322 pRaCfg->status = htons(0);
4323 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4324 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4325 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4326
4327 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4328 {
4329 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE_ALL\n"));
4330 Status = -EFAULT;
4331 }
4332 else
4333 {
4334 ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_E2PROM_WRITE_ALL is done !\n"));
4335 }
4336
4337 }
4338 break;
4339
4340 case RACFG_CMD_IO_READ:
4341 {
4342 UINT32 offset;
4343 UINT32 value;
4344
4345 memcpy(&offset, &pRaCfg->status, 4);
4346 offset = ntohl(offset);
4347
4348 // We do not need the base address.
4349 // So just extract the offset out.
4350 offset &= 0x0000FFFF;
4351 RTMP_IO_READ32(pAdapter, offset, &value);
4352 value = htonl(value);
4353
4354 // prepare feedback
4355 pRaCfg->length = htons(6);
4356 pRaCfg->status = htons(0);
4357 memcpy(pRaCfg->data, &value, 4);
4358
4359 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4360 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4361 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4362
4363 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4364 {
4365 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ\n"));
4366 Status = -EFAULT;
4367 }
4368 else
4369 {
4370 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ is done !\n"));
4371 }
4372 }
4373 break;
4374
4375 case RACFG_CMD_IO_WRITE:
4376 {
4377 UINT32 offset, value;
4378
4379 memcpy(&offset, pRaCfg->data-2, 4);
4380 memcpy(&value, pRaCfg->data+2, 4);
4381
4382 offset = ntohl(offset);
4383
4384 // We do not need the base address.
4385 // So just extract out the offset.
4386 offset &= 0x0000FFFF;
4387 value = ntohl(value);
4388 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_IO_WRITE: offset = %x, value = %x\n", offset, value));
4389 RTMP_IO_WRITE32(pAdapter, offset, value);
4390
4391 // prepare feedback
4392 pRaCfg->length = htons(2);
4393 pRaCfg->status = htons(0);
4394 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4395 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4396 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4397
4398 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4399 {
4400 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_WRITE\n"));
4401 Status = -EFAULT;
4402 }
4403 else
4404 {
4405 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_WRITE is done !\n"));
4406 }
4407 }
4408 break;
4409
4410 case RACFG_CMD_IO_READ_BULK:
4411 {
4412 UINT32 offset;
4413 USHORT len;
4414
4415 memcpy(&offset, &pRaCfg->status, 4);
4416 offset = ntohl(offset);
4417
4418 // We do not need the base address.
4419 // So just extract the offset.
4420 offset &= 0x0000FFFF;
4421 memcpy(&len, pRaCfg->data+2, 2);
4422 len = ntohs(len);
4423
4424 if (len > 371)
4425 {
4426 ATEDBGPRINT(RT_DEBUG_TRACE,("len is too large, make it smaller\n"));
4427 pRaCfg->length = htons(2);
4428 pRaCfg->status = htons(1);
4429 break;
4430 }
4431
4432 RTMP_IO_READ_BULK(pAdapter, pRaCfg->data, (UCHAR *)offset, len*4);// unit in four bytes
4433
4434 // prepare feedback
4435 pRaCfg->length = htons(2+len*4);// unit in four bytes
4436 pRaCfg->status = htons(0);
4437 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4438 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4439 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4440
4441 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4442 {
4443 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ_BULK\n"));
4444 Status = -EFAULT;
4445 }
4446 else
4447 {
4448 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ_BULK is done !\n"));
4449 }
4450 }
4451 break;
4452
4453 case RACFG_CMD_BBP_READ8:
4454 {
4455 USHORT offset;
4456 UCHAR value;
4457
4458 value = 0;
4459 offset = ntohs(pRaCfg->status);
4460
4461 if (ATE_ON(pAdapter))
4462 {
4463 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value);
4464 }
4465 else
4466 {
4467 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value);
4468 }
4469 // prepare feedback
4470 pRaCfg->length = htons(3);
4471 pRaCfg->status = htons(0);
4472 pRaCfg->data[0] = value;
4473
4474 ATEDBGPRINT(RT_DEBUG_TRACE,("BBP value = %x\n", value));
4475
4476 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4477 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4478 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4479
4480 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4481 {
4482 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ8\n"));
4483 Status = -EFAULT;
4484 }
4485 else
4486 {
4487 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ8 is done !\n"));
4488 }
4489 }
4490 break;
4491 case RACFG_CMD_BBP_WRITE8:
4492 {
4493 USHORT offset;
4494 UCHAR value;
4495
4496 offset = ntohs(pRaCfg->status);
4497 memcpy(&value, pRaCfg->data, 1);
4498
4499 if (ATE_ON(pAdapter))
4500 {
4501 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value);
4502 }
4503 else
4504 {
4505 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value);
4506 }
4507
4508 if ((offset == BBP_R1) || (offset == BBP_R3))
4509 {
4510 SyncTxRxConfig(pAdapter, offset, value);
4511 }
4512
4513 // prepare feedback
4514 pRaCfg->length = htons(2);
4515 pRaCfg->status = htons(0);
4516 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4517 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4518 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4519
4520 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4521 {
4522 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_WRITE8\n"));
4523 Status = -EFAULT;
4524 }
4525 else
4526 {
4527 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_WRITE8 is done !\n"));
4528 }
4529 }
4530 break;
4531
4532 case RACFG_CMD_BBP_READ_ALL:
4533 {
4534 USHORT j;
4535
4536 for (j = 0; j < 137; j++)
4537 {
4538 pRaCfg->data[j] = 0;
4539
4540 if (ATE_ON(pAdapter))
4541 {
4542 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j]);
4543 }
4544 else
4545 {
4546 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j]);
4547 }
4548 }
4549
4550 // prepare feedback
4551 pRaCfg->length = htons(2+137);
4552 pRaCfg->status = htons(0);
4553
4554 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4555 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4556 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4557
4558 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4559 {
4560 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ_ALL\n"));
4561 Status = -EFAULT;
4562 }
4563 else
4564 {
4565 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ_ALL is done !\n"));
4566 }
4567 }
4568
4569 break;
4570
4571 case RACFG_CMD_ATE_E2PROM_READ_BULK:
4572 {
4573 USHORT offset;
4574 USHORT len;
4575 USHORT buffer[EEPROM_SIZE/2];
4576
4577 offset = ntohs(pRaCfg->status);
4578 memcpy(&len, pRaCfg->data, 2);
4579 len = ntohs(len);
4580
4581 rt_ee_read_all(pAdapter,(USHORT *)buffer);
4582 if (offset + len <= EEPROM_SIZE)
4583 memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer+offset, len);
4584 else
4585 ATEDBGPRINT(RT_DEBUG_ERROR, ("exceed EEPROM size\n"));
4586
4587 // prepare feedback
4588 pRaCfg->length = htons(2+len);
4589 pRaCfg->status = htons(0);
4590 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4591 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4592 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4593
4594 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4595 {
4596 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_READ_BULK\n"));
4597 Status = -EFAULT;
4598 }
4599 else
4600 {
4601 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_E2PROM_READ_BULK is done !\n"));
4602 }
4603
4604 }
4605 break;
4606
4607 case RACFG_CMD_ATE_E2PROM_WRITE_BULK:
4608 {
4609 USHORT offset;
4610 USHORT len;
4611 USHORT buffer[EEPROM_SIZE/2];
4612
4613 offset = ntohs(pRaCfg->status);
4614 memcpy(&len, pRaCfg->data, 2);
4615 len = ntohs(len);
4616
4617 rt_ee_read_all(pAdapter,(USHORT *)buffer);
4618 memcpy_exs(pAdapter, (UCHAR *)buffer + offset, (UCHAR *)pRaCfg->data + 2, len);
4619 rt_ee_write_all(pAdapter,(USHORT *)buffer);
4620
4621 // prepare feedback
4622 pRaCfg->length = htons(2);
4623 pRaCfg->status = htons(0);
4624 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4625 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4626 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4627 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4628 {
4629 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_WRITE_BULK\n"));
4630 Status = -EFAULT;
4631 }
4632 else
4633 {
4634 ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_E2PROM_WRITE_BULK is done !\n"));
4635 }
4636
4637 }
4638 break;
4639
4640 case RACFG_CMD_ATE_IO_WRITE_BULK:
4641 {
4642 UINT32 offset, i, value;
4643 USHORT len;
4644
4645 memcpy(&offset, &pRaCfg->status, 4);
4646 offset = ntohl(offset);
4647 memcpy(&len, pRaCfg->data+2, 2);
4648 len = ntohs(len);
4649
4650 for (i = 0; i < len; i += 4)
4651 {
4652 memcpy_exl(pAdapter, (UCHAR *)&value, pRaCfg->data+4+i, 4);
4653 printk("Write %x %x\n", offset + i, value);
4654 RTMP_IO_WRITE32(pAdapter, (offset +i) & 0xffff, value);
4655 }
4656
4657 // prepare feedback
4658 pRaCfg->length = htons(2);
4659 pRaCfg->status = htons(0);
4660 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4661 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4662 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4663 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4664 {
4665 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_IO_WRITE_BULK\n"));
4666 Status = -EFAULT;
4667 }
4668 else
4669 {
4670 ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_IO_WRITE_BULK is done !\n"));
4671 }
4672
4673 }
4674 break;
4675
4676 case RACFG_CMD_ATE_BBP_READ_BULK:
4677 {
4678 USHORT offset;
4679 USHORT len;
4680 USHORT j;
4681
4682 offset = ntohs(pRaCfg->status);
4683 memcpy(&len, pRaCfg->data, 2);
4684 len = ntohs(len);
4685
4686
4687 for (j = offset; j < (offset+len); j++)
4688 {
4689 pRaCfg->data[j - offset] = 0;
4690
4691 if (pAdapter->ate.Mode == ATE_STOP)
4692 {
4693 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]);
4694 }
4695 else
4696 {
4697 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]);
4698 }
4699 }
4700
4701 // prepare feedback
4702 pRaCfg->length = htons(2+len);
4703 pRaCfg->status = htons(0);
4704 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4705 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4706 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4707
4708 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4709 {
4710 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_READ_BULK\n"));
4711 Status = -EFAULT;
4712 }
4713 else
4714 {
4715 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_READ_BULK is done !\n"));
4716 }
4717
4718 }
4719 break;
4720
4721 case RACFG_CMD_ATE_BBP_WRITE_BULK:
4722 {
4723 USHORT offset;
4724 USHORT len;
4725 USHORT j;
4726 UCHAR *value;
4727
4728 offset = ntohs(pRaCfg->status);
4729 memcpy(&len, pRaCfg->data, 2);
4730 len = ntohs(len);
4731
4732 for (j = offset; j < (offset+len); j++)
4733 {
4734 value = pRaCfg->data + 2 + (j - offset);
4735 if (pAdapter->ate.Mode == ATE_STOP)
4736 {
4737 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j, *value);
4738 }
4739 else
4740 {
4741 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j, *value);
4742 }
4743 }
4744
4745 // prepare feedback
4746 pRaCfg->length = htons(2);
4747 pRaCfg->status = htons(0);
4748 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4749 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4750 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4751
4752 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4753 {
4754 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_WRITE_BULK\n"));
4755 Status = -EFAULT;
4756 }
4757 else
4758 {
4759 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_WRITE_BULK is done !\n"));
4760 }
4761 }
4762 break;
4763
4764#ifdef CONFIG_RALINK_RT3052
4765 case RACFG_CMD_ATE_RF_READ_BULK:
4766 {
4767 USHORT offset;
4768 USHORT len;
4769 USHORT j;
4770
4771 offset = ntohs(pRaCfg->status);
4772 memcpy(&len, pRaCfg->data, 2);
4773 len = ntohs(len);
4774
4775 for (j = offset; j < (offset+len); j++)
4776 {
4777 pRaCfg->data[j - offset] = 0;
4778 RT30xxReadRFRegister(pAdapter, j, &pRaCfg->data[j - offset]);
4779 }
4780
4781 // prepare feedback
4782 pRaCfg->length = htons(2+len);
4783 pRaCfg->status = htons(0);
4784 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4785 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4786 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4787
4788 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4789 {
4790 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_READ_BULK\n"));
4791 Status = -EFAULT;
4792 }
4793 else
4794 {
4795 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_READ_BULK is done !\n"));
4796 }
4797
4798 }
4799 break;
4800
4801 case RACFG_CMD_ATE_RF_WRITE_BULK:
4802 {
4803 USHORT offset;
4804 USHORT len;
4805 USHORT j;
4806 UCHAR *value;
4807
4808 offset = ntohs(pRaCfg->status);
4809 memcpy(&len, pRaCfg->data, 2);
4810 len = ntohs(len);
4811
4812 for (j = offset; j < (offset+len); j++)
4813 {
4814 value = pRaCfg->data + 2 + (j - offset);
4815 RT30xxWriteRFRegister(pAdapter, j, *value);
4816 }
4817
4818 // prepare feedback
4819 pRaCfg->length = htons(2);
4820 pRaCfg->status = htons(0);
4821 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4822 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4823 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4824
4825 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4826 {
4827 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_WRITE_BULK\n"));
4828 Status = -EFAULT;
4829 }
4830 else
4831 {
4832 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_WRITE_BULK is done !\n"));
4833 }
4834
4835 }
4836 break;
4837#endif
4838
4839
4840 case RACFG_CMD_GET_NOISE_LEVEL:
4841 {
4842 UCHAR channel;
4843 INT32 buffer[3][10];/* 3 : RxPath ; 10 : no. of per rssi samples */
4844
4845 channel = (ntohs(pRaCfg->status) & 0x00FF);
4846 CalNoiseLevel(pAdapter, channel, buffer);
4847 memcpy_exl(pAdapter, (UCHAR *)pRaCfg->data, (UCHAR *)&(buffer[0][0]), (sizeof(INT32)*3*10));
4848
4849 // prepare feedback
4850 pRaCfg->length = htons(2 + (sizeof(INT32)*3*10));
4851 pRaCfg->status = htons(0);
4852 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4853 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4854 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4855
4856 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4857 {
4858 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_NOISE_LEVEL\n"));
4859 Status = -EFAULT;
4860 }
4861 else
4862 {
4863 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_NOISE_LEVEL is done !\n"));
4864 }
4865 }
4866 break;
4867
4868 case RACFG_CMD_GET_COUNTER:
4869 {
4870 memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.U2M, 4);
4871 memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->ate.OtherData, 4);
4872 memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->ate.Beacon, 4);
4873 memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->ate.OtherCount, 4);
4874 memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->ate.TxAc0, 4);
4875 memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->ate.TxAc1, 4);
4876 memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->ate.TxAc2, 4);
4877 memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->ate.TxAc3, 4);
4878 memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->ate.TxHCCA, 4);
4879 memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->ate.TxMgmt, 4);
4880 memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&pAdapter->ate.RSSI0, 4);
4881 memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&pAdapter->ate.RSSI1, 4);
4882 memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&pAdapter->ate.RSSI2, 4);
4883 memcpy_exl(pAdapter, &pRaCfg->data[52], (UCHAR *)&pAdapter->ate.SNR0, 4);
4884 memcpy_exl(pAdapter, &pRaCfg->data[56], (UCHAR *)&pAdapter->ate.SNR1, 4);
4885
4886 pRaCfg->length = htons(2+60);
4887 pRaCfg->status = htons(0);
4888 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4889 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4890 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4891
4892 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4893 {
4894 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_COUNTER\n"));
4895 Status = -EFAULT;
4896 }
4897 else
4898 {
4899 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_COUNTER is done !\n"));
4900 }
4901 }
4902 break;
4903
4904 case RACFG_CMD_CLEAR_COUNTER:
4905 {
4906 pAdapter->ate.U2M = 0;
4907 pAdapter->ate.OtherData = 0;
4908 pAdapter->ate.Beacon = 0;
4909 pAdapter->ate.OtherCount = 0;
4910 pAdapter->ate.TxAc0 = 0;
4911 pAdapter->ate.TxAc1 = 0;
4912 pAdapter->ate.TxAc2 = 0;
4913 pAdapter->ate.TxAc3 = 0;
4914 pAdapter->ate.TxHCCA = 0;
4915 pAdapter->ate.TxMgmt = 0;
4916 pAdapter->ate.TxDoneCount = 0;
4917
4918 pRaCfg->length = htons(2);
4919 pRaCfg->status = htons(0);
4920
4921 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4922 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4923 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4924
4925 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4926 {
4927 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_CLEAR_COUNTER\n"));
4928 Status = -EFAULT;
4929 }
4930 else
4931 {
4932 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_CLEAR_COUNTER is done !\n"));
4933 }
4934 }
4935
4936 break;
4937
4938 case RACFG_CMD_TX_START:
4939 {
4940 USHORT *p;
4941 USHORT err = 1;
4942 UCHAR Bbp22Value = 0, Bbp24Value = 0;
4943
4944 if ((pAdapter->ate.TxStatus != 0) && (pAdapter->ate.Mode & ATE_TXFRAME))
4945 {
4946 ATEDBGPRINT(RT_DEBUG_TRACE,("Ate Tx is already running, to run next Tx, you must stop it first\n"));
4947 err = 2;
4948 goto TX_START_ERROR;
4949 }
4950 else if ((pAdapter->ate.TxStatus != 0) && !(pAdapter->ate.Mode & ATE_TXFRAME))
4951 {
4952 int i = 0;
4953
4954 while ((i++ < 10) && (pAdapter->ate.TxStatus != 0))
4955 {
4956 RTMPusecDelay(5000);
4957 }
4958
4959 // force it to stop
4960 pAdapter->ate.TxStatus = 0;
4961 pAdapter->ate.TxDoneCount = 0;
4962 //pAdapter->ate.Repeat = 0;
4963 pAdapter->ate.bQATxStart = FALSE;
4964 }
4965
4966 // If pRaCfg->length == 0, this "RACFG_CMD_TX_START" is for Carrier test or Carrier Suppression.
4967 if (ntohs(pRaCfg->length) != 0)
4968 {
4969 // Get frame info
4970#ifdef RT2870
4971 NdisMoveMemory(&pAdapter->ate.TxInfo, pRaCfg->data - 2, 4);
4972#ifdef RT_BIG_ENDIAN
4973 RTMPDescriptorEndianChange((PUCHAR) &pAdapter->ate.TxInfo, TYPE_TXINFO);
4974#endif // RT_BIG_ENDIAN //
4975#endif // RT2870 //
4976
4977 NdisMoveMemory(&pAdapter->ate.TxWI, pRaCfg->data + 2, 16);
4978#ifdef RT_BIG_ENDIAN
4979 RTMPWIEndianChange((PUCHAR)&pAdapter->ate.TxWI, TYPE_TXWI);
4980#endif // RT_BIG_ENDIAN //
4981
4982 NdisMoveMemory(&pAdapter->ate.TxCount, pRaCfg->data + 18, 4);
4983 pAdapter->ate.TxCount = ntohl(pAdapter->ate.TxCount);
4984
4985 p = (USHORT *)(&pRaCfg->data[22]);
4986 //p = pRaCfg->data + 22;
4987 // always use QID_AC_BE
4988 pAdapter->ate.QID = 0;
4989 p = (USHORT *)(&pRaCfg->data[24]);
4990 //p = pRaCfg->data + 24;
4991 pAdapter->ate.HLen = ntohs(*p);
4992
4993 if (pAdapter->ate.HLen > 32)
4994 {
4995 ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.HLen > 32\n"));
4996 err = 3;
4997 goto TX_START_ERROR;
4998 }
4999
5000 NdisMoveMemory(&pAdapter->ate.Header, pRaCfg->data + 26, pAdapter->ate.HLen);
5001
5002
5003 pAdapter->ate.PLen = ntohs(pRaCfg->length) - (pAdapter->ate.HLen + 28);
5004
5005 if (pAdapter->ate.PLen > 32)
5006 {
5007 ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.PLen > 32\n"));
5008 err = 4;
5009 goto TX_START_ERROR;
5010 }
5011
5012 NdisMoveMemory(&pAdapter->ate.Pattern, pRaCfg->data + 26 + pAdapter->ate.HLen, pAdapter->ate.PLen);
5013 pAdapter->ate.DLen = pAdapter->ate.TxWI.MPDUtotalByteCount - pAdapter->ate.HLen;
5014 }
5015
5016 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R22, &Bbp22Value);
5017
5018 switch (Bbp22Value)
5019 {
5020 case BBP22_TXFRAME:
5021 {
5022 if (pAdapter->ate.TxCount == 0)
5023 {
5024 }
5025 ATEDBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n"));
5026 pAdapter->ate.bQATxStart = TRUE;
5027 Set_ATE_Proc(pAdapter, "TXFRAME");
5028 }
5029 break;
5030
5031 case BBP22_TXCONT_OR_CARRSUPP:
5032 {
5033 ATEDBGPRINT(RT_DEBUG_TRACE,("BBP22_TXCONT_OR_CARRSUPP\n"));
5034 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, 24, &Bbp24Value);
5035
5036 switch (Bbp24Value)
5037 {
5038 case BBP24_TXCONT:
5039 {
5040 ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCONT\n"));
5041 pAdapter->ate.bQATxStart = TRUE;
5042 Set_ATE_Proc(pAdapter, "TXCONT");
5043 }
5044 break;
5045
5046 case BBP24_CARRSUPP:
5047 {
5048 ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARRSUPP\n"));
5049 pAdapter->ate.bQATxStart = TRUE;
5050 pAdapter->ate.Mode |= ATE_TXCARRSUPP;
5051 }
5052 break;
5053
5054 default:
5055 {
5056 ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
5057 }
5058 break;
5059 }
5060 }
5061 break;
5062
5063 case BBP22_TXCARR:
5064 {
5065 ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARR\n"));
5066 pAdapter->ate.bQATxStart = TRUE;
5067 Set_ATE_Proc(pAdapter, "TXCARR");
5068 }
5069 break;
5070
5071 default:
5072 {
5073 ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
5074 }
5075 break;
5076 }
5077
5078 if (pAdapter->ate.bQATxStart == TRUE)
5079 {
5080 // prepare feedback
5081 pRaCfg->length = htons(2);
5082 pRaCfg->status = htons(0);
5083
5084 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5085 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5086 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5087
5088 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5089 {
5090 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() was failed in case RACFG_CMD_TX_START\n"));
5091 Status = -EFAULT;
5092 }
5093 else
5094 {
5095 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_START is done !\n"));
5096 }
5097 break;
5098 }
5099
5100TX_START_ERROR:
5101 // prepare feedback
5102 pRaCfg->length = htons(2);
5103 pRaCfg->status = htons(err);
5104
5105 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5106 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5107 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
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_TX_START\n"));
5111 Status = -EFAULT;
5112 }
5113 else
5114 {
5115 ATEDBGPRINT(RT_DEBUG_TRACE, ("feedback of TX_START_ERROR is done !\n"));
5116 }
5117 }
5118 break;
5119
5120 case RACFG_CMD_GET_TX_STATUS:
5121 {
5122 UINT32 count;
5123
5124 // prepare feedback
5125 pRaCfg->length = htons(6);
5126 pRaCfg->status = htons(0);
5127 count = htonl(pAdapter->ate.TxDoneCount);
5128 NdisMoveMemory(pRaCfg->data, &count, 4);
5129 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5130 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5131 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5132
5133 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5134 {
5135 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_TX_STATUS\n"));
5136 Status = -EFAULT;
5137 }
5138 else
5139 {
5140 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_TX_STATUS is done !\n"));
5141 }
5142 }
5143 break;
5144
5145 case RACFG_CMD_TX_STOP:
5146 {
5147 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_TX_STOP\n"));
5148
5149 Set_ATE_Proc(pAdapter, "TXSTOP");
5150
5151 // prepare feedback
5152 pRaCfg->length = htons(2);
5153 pRaCfg->status = htons(0);
5154 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5155 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5156 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5157
5158 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5159 {
5160 ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_TX_STOP\n"));
5161 Status = -EFAULT;
5162 }
5163 else
5164 {
5165 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_STOP is done !\n"));
5166 }
5167 }
5168 break;
5169
5170 case RACFG_CMD_RX_START:
5171 {
5172 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
5173
5174 pAdapter->ate.bQARxStart = TRUE;
5175 Set_ATE_Proc(pAdapter, "RXFRAME");
5176
5177 // prepare feedback
5178 pRaCfg->length = htons(2);
5179 pRaCfg->status = htons(0);
5180 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5181 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5182 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5183
5184 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5185 {
5186 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
5187 Status = -EFAULT;
5188 }
5189 else
5190 {
5191 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
5192 }
5193 }
5194 break;
5195
5196 case RACFG_CMD_RX_STOP:
5197 {
5198 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_STOP\n"));
5199
5200 Set_ATE_Proc(pAdapter, "RXSTOP");
5201
5202 // prepare feedback
5203 pRaCfg->length = htons(2);
5204 pRaCfg->status = htons(0);
5205 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5206 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5207 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5208
5209 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5210 {
5211 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_STOP\n"));
5212 Status = -EFAULT;
5213 }
5214 else
5215 {
5216 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_STOP is done !\n"));
5217 }
5218 }
5219 break;
5220
5221 /* The following cases are for new ATE GUI(not QA). */
5222 /*==================================================*/
5223 case RACFG_CMD_ATE_START_TX_CARRIER:
5224 {
5225 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CARRIER\n"));
5226
5227 Set_ATE_Proc(pAdapter, "TXCARR");
5228
5229 pRaCfg->length = htons(2);
5230 pRaCfg->status = htons(0);
5231
5232 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5233 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5234 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5235
5236 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
5237
5238 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5239 {
5240 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CARRIER\n"));
5241 Status = -EFAULT;
5242 }
5243 else
5244 {
5245 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CARRIER is done !\n"));
5246 }
5247 }
5248 break;
5249
5250 case RACFG_CMD_ATE_START_TX_CONT:
5251 {
5252 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CONT\n"));
5253
5254 Set_ATE_Proc(pAdapter, "TXCONT");
5255
5256 pRaCfg->length = htons(2);
5257 pRaCfg->status = htons(0);
5258
5259 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5260 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5261 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5262
5263 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
5264
5265 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5266 {
5267 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CONT\n"));
5268 Status = -EFAULT;
5269 }
5270 else
5271 {
5272 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CONT is done !\n"));
5273 }
5274 }
5275 break;
5276
5277 case RACFG_CMD_ATE_START_TX_FRAME:
5278 {
5279 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_FRAME\n"));
5280
5281 Set_ATE_Proc(pAdapter, "TXFRAME");
5282
5283 pRaCfg->length = htons(2);
5284 pRaCfg->status = htons(0);
5285
5286 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5287 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5288 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5289
5290 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
5291
5292 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5293 {
5294 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_FRAME\n"));
5295 Status = -EFAULT;
5296 }
5297 else
5298 {
5299 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_FRAME is done !\n"));
5300 }
5301 }
5302 break;
5303
5304 case RACFG_CMD_ATE_SET_BW:
5305 {
5306 SHORT value = 0;
5307 UCHAR str[LEN_OF_ARG];
5308
5309 NdisZeroMemory(str, LEN_OF_ARG);
5310
5311 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_BW\n"));
5312
5313 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5314 value = ntohs(value);
5315 sprintf((PCHAR)str, "%d", value);
5316
5317 Set_ATE_TX_BW_Proc(pAdapter, str);
5318
5319 // prepare feedback
5320 pRaCfg->length = htons(2);
5321 pRaCfg->status = htons(0);
5322 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5323 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5324 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5325
5326 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5327 {
5328 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_BW\n"));
5329 Status = -EFAULT;
5330 }
5331 else
5332 {
5333 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_BW is done !\n"));
5334 }
5335 }
5336 break;
5337
5338 case RACFG_CMD_ATE_SET_TX_POWER0:
5339 {
5340 SHORT value = 0;
5341 UCHAR str[LEN_OF_ARG];
5342
5343 NdisZeroMemory(str, LEN_OF_ARG);
5344
5345 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER0\n"));
5346
5347 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5348 value = ntohs(value);
5349 sprintf((PCHAR)str, "%d", value);
5350 Set_ATE_TX_POWER0_Proc(pAdapter, str);
5351
5352 // prepare feedback
5353 pRaCfg->length = htons(2);
5354 pRaCfg->status = htons(0);
5355 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5356 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5357 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5358
5359 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5360 {
5361 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER0\n"));
5362 Status = -EFAULT;
5363 }
5364 else
5365 {
5366 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER0 is done !\n"));
5367 }
5368 }
5369 break;
5370
5371 case RACFG_CMD_ATE_SET_TX_POWER1:
5372 {
5373 SHORT value = 0;
5374 UCHAR str[LEN_OF_ARG];
5375
5376 NdisZeroMemory(str, LEN_OF_ARG);
5377
5378 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER1\n"));
5379
5380 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5381 value = ntohs(value);
5382 sprintf((PCHAR)str, "%d", value);
5383 Set_ATE_TX_POWER1_Proc(pAdapter, str);
5384
5385 // prepare feedback
5386 pRaCfg->length = htons(2);
5387 pRaCfg->status = htons(0);
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
5392 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5393 {
5394 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER1\n"));
5395 Status = -EFAULT;
5396 }
5397 else
5398 {
5399 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER1 is done !\n"));
5400 }
5401 }
5402 break;
5403
5404 case RACFG_CMD_ATE_SET_FREQ_OFFSET:
5405 {
5406 SHORT value = 0;
5407 UCHAR str[LEN_OF_ARG];
5408
5409 NdisZeroMemory(str, LEN_OF_ARG);
5410
5411 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
5412
5413 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5414 value = ntohs(value);
5415 sprintf((PCHAR)str, "%d", value);
5416 Set_ATE_TX_FREQOFFSET_Proc(pAdapter, str);
5417
5418 // prepare feedback
5419 pRaCfg->length = htons(2);
5420 pRaCfg->status = htons(0);
5421 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5422 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5423 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5424
5425 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5426 {
5427 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
5428 Status = -EFAULT;
5429 }
5430 else
5431 {
5432 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_FREQ_OFFSET is done !\n"));
5433 }
5434 }
5435 break;
5436
5437 case RACFG_CMD_ATE_GET_STATISTICS:
5438 {
5439 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_GET_STATISTICS\n"));
5440
5441 memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.TxDoneCount, 4);
5442 memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->WlanCounters.RetryCount.u.LowPart, 4);
5443 memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->WlanCounters.FailedCount.u.LowPart, 4);
5444 memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->WlanCounters.RTSSuccessCount.u.LowPart, 4);
5445 memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->WlanCounters.RTSFailureCount.u.LowPart, 4);
5446 memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart, 4);
5447 memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->WlanCounters.FCSErrorCount.u.LowPart, 4);
5448 memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->Counters8023.RxNoBuffer, 4);
5449 memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart, 4);
5450 memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->RalinkCounters.OneSecFalseCCACnt, 4);
5451
5452 if (pAdapter->ate.RxAntennaSel == 0)
5453 {
5454 INT32 RSSI0 = 0;
5455 INT32 RSSI1 = 0;
5456 INT32 RSSI2 = 0;
5457
5458 RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
5459 RSSI1 = (INT32)(pAdapter->ate.LastRssi1 - pAdapter->BbpRssiToDbmDelta);
5460 RSSI2 = (INT32)(pAdapter->ate.LastRssi2 - pAdapter->BbpRssiToDbmDelta);
5461 memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
5462 memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&RSSI1, 4);
5463 memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&RSSI2, 4);
5464 pRaCfg->length = htons(2+52);
5465 }
5466 else
5467 {
5468 INT32 RSSI0 = 0;
5469
5470 RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
5471 memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
5472 pRaCfg->length = htons(2+44);
5473 }
5474 pRaCfg->status = htons(0);
5475 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5476 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5477 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5478
5479 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5480 {
5481 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_GET_STATISTICS\n"));
5482 Status = -EFAULT;
5483 }
5484 else
5485 {
5486 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_GET_STATISTICS is done !\n"));
5487 }
5488 }
5489 break;
5490
5491 case RACFG_CMD_ATE_RESET_COUNTER:
5492 {
5493 SHORT value = 1;
5494 UCHAR str[LEN_OF_ARG];
5495
5496 NdisZeroMemory(str, LEN_OF_ARG);
5497
5498 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_RESET_COUNTER\n"));
5499
5500 sprintf((PCHAR)str, "%d", value);
5501 Set_ResetStatCounter_Proc(pAdapter, str);
5502
5503 pAdapter->ate.TxDoneCount = 0;
5504
5505 pRaCfg->length = htons(2);
5506 pRaCfg->status = htons(0);
5507
5508 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5509 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5510 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5511
5512 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5513 {
5514 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RESET_COUNTER\n"));
5515 Status = -EFAULT;
5516 }
5517 else
5518 {
5519 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RESET_COUNTER is done !\n"));
5520 }
5521 }
5522
5523 break;
5524
5525 case RACFG_CMD_ATE_SEL_TX_ANTENNA:
5526 {
5527 SHORT value = 0;
5528 UCHAR str[LEN_OF_ARG];
5529
5530 NdisZeroMemory(str, LEN_OF_ARG);
5531
5532 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
5533
5534 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5535 value = ntohs(value);
5536 sprintf((PCHAR)str, "%d", value);
5537 Set_ATE_TX_Antenna_Proc(pAdapter, str);
5538
5539 // prepare feedback
5540 pRaCfg->length = htons(2);
5541 pRaCfg->status = htons(0);
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 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5547 {
5548 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
5549 Status = -EFAULT;
5550 }
5551 else
5552 {
5553 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_TX_ANTENNA is done !\n"));
5554 }
5555 }
5556 break;
5557
5558 case RACFG_CMD_ATE_SEL_RX_ANTENNA:
5559 {
5560 SHORT value = 0;
5561 UCHAR str[LEN_OF_ARG];
5562
5563 NdisZeroMemory(str, LEN_OF_ARG);
5564
5565 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
5566
5567 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5568 value = ntohs(value);
5569 sprintf((PCHAR)str, "%d", value);
5570 Set_ATE_RX_Antenna_Proc(pAdapter, str);
5571
5572 // prepare feedback
5573 pRaCfg->length = htons(2);
5574 pRaCfg->status = htons(0);
5575 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5576 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5577 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5578
5579 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5580 {
5581 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
5582 Status = -EFAULT;
5583 }
5584 else
5585 {
5586 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_RX_ANTENNA is done !\n"));
5587 }
5588 }
5589 break;
5590
5591 case RACFG_CMD_ATE_SET_PREAMBLE:
5592 {
5593 SHORT value = 0;
5594 UCHAR str[LEN_OF_ARG];
5595
5596 NdisZeroMemory(str, LEN_OF_ARG);
5597
5598 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_PREAMBLE\n"));
5599
5600 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5601 value = ntohs(value);
5602 sprintf((PCHAR)str, "%d", value);
5603 Set_ATE_TX_MODE_Proc(pAdapter, str);
5604
5605 // prepare feedback
5606 pRaCfg->length = htons(2);
5607 pRaCfg->status = htons(0);
5608 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5609 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5610 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5611
5612 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5613 {
5614 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_PREAMBLE\n"));
5615 Status = -EFAULT;
5616 }
5617 else
5618 {
5619 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_PREAMBLE is done !\n"));
5620 }
5621 }
5622 break;
5623
5624 case RACFG_CMD_ATE_SET_CHANNEL:
5625 {
5626 SHORT value = 0;
5627 UCHAR str[LEN_OF_ARG];
5628
5629 NdisZeroMemory(str, LEN_OF_ARG);
5630
5631 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_CHANNEL\n"));
5632
5633 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5634 value = ntohs(value);
5635 sprintf((PCHAR)str, "%d", value);
5636 Set_ATE_CHANNEL_Proc(pAdapter, str);
5637
5638 // prepare feedback
5639 pRaCfg->length = htons(2);
5640 pRaCfg->status = htons(0);
5641 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5642 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5643 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5644
5645 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5646 {
5647 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_CHANNEL\n"));
5648 Status = -EFAULT;
5649 }
5650 else
5651 {
5652 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_CHANNEL is done !\n"));
5653 }
5654 }
5655 break;
5656
5657 case RACFG_CMD_ATE_SET_ADDR1:
5658 {
5659 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR1\n"));
5660
5661 // Addr is an array of UCHAR,
5662 // so no need to perform endian swap.
5663 memcpy(pAdapter->ate.Addr1, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
5664
5665 // prepare feedback
5666 pRaCfg->length = htons(2);
5667 pRaCfg->status = htons(0);
5668 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5669 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5670 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5671
5672 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5673 {
5674 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR1\n"));
5675 Status = -EFAULT;
5676 }
5677 else
5678 {
5679 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR1 is done !\n (ADDR1 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr1[0],
5680 pAdapter->ate.Addr1[1], pAdapter->ate.Addr1[2], pAdapter->ate.Addr1[3], pAdapter->ate.Addr1[4], pAdapter->ate.Addr1[5]));
5681 }
5682 }
5683 break;
5684
5685 case RACFG_CMD_ATE_SET_ADDR2:
5686 {
5687 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR2\n"));
5688
5689 // Addr is an array of UCHAR,
5690 // so no need to perform endian swap.
5691 memcpy(pAdapter->ate.Addr2, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
5692
5693 // prepare feedback
5694 pRaCfg->length = htons(2);
5695 pRaCfg->status = htons(0);
5696 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5697 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5698 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5699
5700 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5701 {
5702 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR2\n"));
5703 Status = -EFAULT;
5704 }
5705 else
5706 {
5707 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR2 is done !\n (ADDR2 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr2[0],
5708 pAdapter->ate.Addr2[1], pAdapter->ate.Addr2[2], pAdapter->ate.Addr2[3], pAdapter->ate.Addr2[4], pAdapter->ate.Addr2[5]));
5709 }
5710 }
5711 break;
5712
5713 case RACFG_CMD_ATE_SET_ADDR3:
5714 {
5715 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR3\n"));
5716
5717 // Addr is an array of UCHAR,
5718 // so no need to perform endian swap.
5719 memcpy(pAdapter->ate.Addr3, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
5720
5721 // prepare feedback
5722 pRaCfg->length = htons(2);
5723 pRaCfg->status = htons(0);
5724 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5725 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5726 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5727
5728 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5729 {
5730 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR3\n"));
5731 Status = -EFAULT;
5732 }
5733 else
5734 {
5735 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR3 is done !\n (ADDR3 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr3[0],
5736 pAdapter->ate.Addr3[1], pAdapter->ate.Addr3[2], pAdapter->ate.Addr3[3], pAdapter->ate.Addr3[4], pAdapter->ate.Addr3[5]));
5737 }
5738 }
5739 break;
5740
5741 case RACFG_CMD_ATE_SET_RATE:
5742 {
5743 SHORT value = 0;
5744 UCHAR str[LEN_OF_ARG];
5745
5746 NdisZeroMemory(str, LEN_OF_ARG);
5747
5748 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_RATE\n"));
5749
5750 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5751 value = ntohs(value);
5752 sprintf((PCHAR)str, "%d", value);
5753 Set_ATE_TX_MCS_Proc(pAdapter, str);
5754
5755 // prepare feedback
5756 pRaCfg->length = htons(2);
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_SET_RATE\n"));
5765 Status = -EFAULT;
5766 }
5767 else
5768 {
5769 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_RATE is done !\n"));
5770 }
5771 }
5772 break;
5773
5774 case RACFG_CMD_ATE_SET_TX_FRAME_LEN:
5775 {
5776 SHORT value = 0;
5777 UCHAR str[LEN_OF_ARG];
5778
5779 NdisZeroMemory(str, LEN_OF_ARG);
5780
5781 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
5782
5783 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5784 value = ntohs(value);
5785 sprintf((PCHAR)str, "%d", value);
5786 Set_ATE_TX_LENGTH_Proc(pAdapter, str);
5787
5788 // prepare feedback
5789 pRaCfg->length = htons(2);
5790 pRaCfg->status = htons(0);
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_SET_TX_FRAME_LEN\n"));
5798 Status = -EFAULT;
5799 }
5800 else
5801 {
5802 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_LEN is done !\n"));
5803 }
5804 }
5805 break;
5806
5807 case RACFG_CMD_ATE_SET_TX_FRAME_COUNT:
5808 {
5809 USHORT value = 0;
5810 UCHAR str[LEN_OF_ARG];
5811
5812 NdisZeroMemory(str, LEN_OF_ARG);
5813
5814 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
5815
5816 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5817 value = ntohs(value);
5818 {
5819 sprintf((PCHAR)str, "%d", value);
5820 Set_ATE_TX_COUNT_Proc(pAdapter, str);
5821 }
5822
5823 // prepare feedback
5824 pRaCfg->length = htons(2);
5825 pRaCfg->status = htons(0);
5826 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5827 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5828 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5829
5830 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5831 {
5832 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
5833 Status = -EFAULT;
5834 }
5835 else
5836 {
5837 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_COUNT is done !\n"));
5838 }
5839 }
5840 break;
5841
5842 case RACFG_CMD_ATE_START_RX_FRAME:
5843 {
5844 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
5845
5846 Set_ATE_Proc(pAdapter, "RXFRAME");
5847
5848 // prepare feedback
5849 pRaCfg->length = htons(2);
5850 pRaCfg->status = htons(0);
5851 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5852 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5853 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5854
5855 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5856 {
5857 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
5858 Status = -EFAULT;
5859 }
5860 else
5861 {
5862 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
5863 }
5864 }
5865 break;
5866 default:
5867 break;
5868 }
5869 ASSERT(pRaCfg != NULL);
5870 if (pRaCfg != NULL)
5871 {
5872 kfree(pRaCfg);
5873 }
5874 return;
5875}
5876
5877VOID BubbleSort(INT32 n, INT32 a[])
5878{
5879 INT32 k, j, temp;
5880
5881 for (k = n-1; k>0; k--)
5882 {
5883 for (j = 0; j<k; j++)
5884 {
5885 if(a[j] > a[j+1])
5886 {
5887 temp = a[j];
5888 a[j]=a[j+1];
5889 a[j+1]=temp;
5890 }
5891 }
5892 }
5893}
5894
5895VOID CalNoiseLevel(PRTMP_ADAPTER pAd, UCHAR channel, INT32 RSSI[3][10])
5896{
5897 INT32 RSSI0, RSSI1, RSSI2;
5898 CHAR Rssi0Offset, Rssi1Offset, Rssi2Offset;
5899 UCHAR BbpR50Rssi0 = 0, BbpR51Rssi1 = 0, BbpR52Rssi2 = 0;
5900 UCHAR Org_BBP66value = 0, Org_BBP69value = 0, Org_BBP70value = 0, data = 0;
5901 USHORT LNA_Gain = 0;
5902 INT32 j = 0;
5903 UCHAR Org_Channel = pAd->ate.Channel;
5904 USHORT GainValue = 0, OffsetValue = 0;
5905
5906 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &Org_BBP66value);
5907 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R69, &Org_BBP69value);
5908 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R70, &Org_BBP70value);
5909
5910 //**********************************************************************
5911 // Read the value of LNA gain and Rssi offset
5912 //**********************************************************************
5913 RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, GainValue);
5914
5915 // for Noise Level
5916 if (channel <= 14)
5917 {
5918 LNA_Gain = GainValue & 0x00FF;
5919
5920 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, OffsetValue);
5921 Rssi0Offset = OffsetValue & 0x00FF;
5922 Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
5923 RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_BG_OFFSET + 2)/* 0x48 */, OffsetValue);
5924 Rssi2Offset = OffsetValue & 0x00FF;
5925 }
5926 else
5927 {
5928 LNA_Gain = (GainValue & 0xFF00) >> 8;
5929
5930 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, OffsetValue);
5931 Rssi0Offset = OffsetValue & 0x00FF;
5932 Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
5933 RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2)/* 0x4C */, OffsetValue);
5934 Rssi2Offset = OffsetValue & 0x00FF;
5935 }
5936 //**********************************************************************
5937 {
5938 pAd->ate.Channel = channel;
5939 ATEAsicSwitchChannel(pAd);
5940 mdelay(5);
5941
5942 data = 0x10;
5943 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, data);
5944 data = 0x40;
5945 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, data);
5946 data = 0x40;
5947 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, data);
5948 mdelay(5);
5949
5950 // Start Rx
5951 pAd->ate.bQARxStart = TRUE;
5952 Set_ATE_Proc(pAd, "RXFRAME");
5953
5954 mdelay(5);
5955
5956 for (j = 0; j < 10; j++)
5957 {
5958 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R50, &BbpR50Rssi0);
5959 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R51, &BbpR51Rssi1);
5960 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R52, &BbpR52Rssi2);
5961
5962 mdelay(10);
5963
5964 // Calculate RSSI 0
5965 if (BbpR50Rssi0 == 0)
5966 {
5967 RSSI0 = -100;
5968 }
5969 else
5970 {
5971 RSSI0 = (INT32)(-12 - BbpR50Rssi0 - LNA_Gain - Rssi0Offset);
5972 }
5973 RSSI[0][j] = RSSI0;
5974
5975 if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
5976 {
5977 // Calculate RSSI 1
5978 if (BbpR51Rssi1 == 0)
5979 {
5980 RSSI1 = -100;
5981 }
5982 else
5983 {
5984 RSSI1 = (INT32)(-12 - BbpR51Rssi1 - LNA_Gain - Rssi1Offset);
5985 }
5986 RSSI[1][j] = RSSI1;
5987 }
5988
5989 if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
5990 {
5991 // Calculate RSSI 2
5992 if (BbpR52Rssi2 == 0)
5993 RSSI2 = -100;
5994 else
5995 RSSI2 = (INT32)(-12 - BbpR52Rssi2 - LNA_Gain - Rssi2Offset);
5996
5997 RSSI[2][j] = RSSI2;
5998 }
5999 }
6000
6001 // Stop Rx
6002 Set_ATE_Proc(pAd, "RXSTOP");
6003
6004 mdelay(5);
6005
6006#if 0// Debug Message................
6007 ate_print("\n**********************************************************\n");
6008 ate_print("Noise Level: Channel %d\n", channel);
6009 ate_print("RSSI0 = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
6010 RSSI[0][0], RSSI[0][1], RSSI[0][2],
6011 RSSI[0][3], RSSI[0][4], RSSI[0][5],
6012 RSSI[0][6], RSSI[0][7], RSSI[0][8],
6013 RSSI[0][9]);
6014 if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
6015 {
6016 ate_print("RSSI1 = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
6017 RSSI[1][0], RSSI[1][1], RSSI[1][2],
6018 RSSI[1][3], RSSI[1][4], RSSI[1][5],
6019 RSSI[1][6], RSSI[1][7], RSSI[1][8],
6020 RSSI[1][9]);
6021 }
6022 if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
6023 {
6024 ate_print("RSSI2 = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
6025 RSSI[2][0], RSSI[2][1], RSSI[2][2],
6026 RSSI[2][3], RSSI[2][4], RSSI[2][5],
6027 RSSI[2][6], RSSI[2][7], RSSI[2][8],
6028 RSSI[2][9]);
6029 }
6030#endif // 0 //
6031 BubbleSort(10, RSSI[0]); // 1R
6032
6033 if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
6034 {
6035 BubbleSort(10, RSSI[1]);
6036 }
6037
6038 if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
6039 {
6040 BubbleSort(10, RSSI[2]);
6041 }
6042
6043#if 0// Debug Message................
6044 ate_print("\nAfter Sorting....Channel %d\n", channel);
6045 ate_print("RSSI0 = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
6046 RSSI[0][0], RSSI[0][1], RSSI[0][2],
6047 RSSI[0][3], RSSI[0][4], RSSI[0][5],
6048 RSSI[0][6], RSSI[0][7], RSSI[0][8],
6049 RSSI[0][9]);
6050 if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
6051 {
6052 ate_print("RSSI1 = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
6053 RSSI[1][0], RSSI[1][1], RSSI[1][2],
6054 RSSI[1][3], RSSI[1][4], RSSI[1][5],
6055 RSSI[1][6], RSSI[1][7], RSSI[1][8],
6056 RSSI[1][9]);
6057 }
6058 if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
6059 {
6060 ate_print("RSSI2 = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
6061 RSSI[2][0], RSSI[2][1], RSSI[2][2],
6062 RSSI[2][3], RSSI[2][4], RSSI[2][5],
6063 RSSI[2][6], RSSI[2][7], RSSI[2][8],
6064 RSSI[2][9]);
6065 }
6066 ate_print("**********************************************************\n");
6067#endif // 0 //
6068 }
6069
6070 pAd->ate.Channel = Org_Channel;
6071 ATEAsicSwitchChannel(pAd);
6072
6073 // Restore original value
6074 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, Org_BBP66value);
6075 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, Org_BBP69value);
6076 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, Org_BBP70value);
6077
6078 return;
6079}
6080
6081BOOLEAN SyncTxRxConfig(PRTMP_ADAPTER pAd, USHORT offset, UCHAR value)
6082{
6083 UCHAR tmp = 0, bbp_data = 0;
6084
6085 if (ATE_ON(pAd))
6086 {
6087 ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
6088 }
6089 else
6090 {
6091 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
6092 }
6093
6094 /* confirm again */
6095 ASSERT(bbp_data == value);
6096
6097 switch(offset)
6098 {
6099 case BBP_R1:
6100 /* Need to sync. tx configuration with legacy ATE. */
6101 tmp = (bbp_data & ((1 << 4) | (1 << 3))/* 0x18 */) >> 3;
6102 switch(tmp)
6103 {
6104 /* The BBP R1 bit[4:3] = 2 :: Both DACs will be used by QA. */
6105 case 2:
6106 /* All */
6107 pAd->ate.TxAntennaSel = 0;
6108 break;
6109 /* The BBP R1 bit[4:3] = 0 :: DAC 0 will be used by QA. */
6110 case 0:
6111 /* Antenna one */
6112 pAd->ate.TxAntennaSel = 1;
6113 break;
6114 /* The BBP R1 bit[4:3] = 1 :: DAC 1 will be used by QA. */
6115 case 1:
6116 /* Antenna two */
6117 pAd->ate.TxAntennaSel = 2;
6118 break;
6119 default:
6120 DBGPRINT(RT_DEBUG_TRACE, ("%s -- Sth. wrong! : return FALSE; \n", __FUNCTION__));
6121 return FALSE;
6122 }
6123 break;/* case BBP_R1 */
6124
6125 case BBP_R3:
6126 /* Need to sync. rx configuration with legacy ATE. */
6127 tmp = (bbp_data & ((1 << 1) | (1 << 0))/* 0x03 */);
6128 switch(tmp)
6129 {
6130 /* The BBP R3 bit[1:0] = 3 :: All ADCs will be used by QA. */
6131 case 3:
6132 /* All */
6133 pAd->ate.RxAntennaSel = 0;
6134 break;
6135 /* The BBP R3 bit[1:0] = 0 :: ADC 0 will be used by QA, */
6136 /* unless the BBP R3 bit[4:3] = 2 */
6137 case 0:
6138 /* Antenna one */
6139 pAd->ate.RxAntennaSel = 1;
6140 tmp = ((bbp_data & ((1 << 4) | (1 << 3))/* 0x03 */) >> 3);
6141 if (tmp == 2)// 3R
6142 {
6143 /* Default : All ADCs will be used by QA */
6144 pAd->ate.RxAntennaSel = 0;
6145 }
6146 break;
6147 /* The BBP R3 bit[1:0] = 1 :: ADC 1 will be used by QA. */
6148 case 1:
6149 /* Antenna two */
6150 pAd->ate.RxAntennaSel = 2;
6151 break;
6152 /* The BBP R3 bit[1:0] = 2 :: ADC 2 will be used by QA. */
6153 case 2:
6154 /* Antenna three */
6155 pAd->ate.RxAntennaSel = 3;
6156 break;
6157 default:
6158 DBGPRINT(RT_DEBUG_ERROR, ("%s -- Impossible! : return FALSE; \n", __FUNCTION__));
6159 return FALSE;
6160 }
6161 break;/* case BBP_R3 */
6162
6163 default:
6164 DBGPRINT(RT_DEBUG_ERROR, ("%s -- Sth. wrong! : return FALSE; \n", __FUNCTION__));
6165 return FALSE;
6166
6167 }
6168 return TRUE;
6169}
6170
6171static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
6172{
6173 ULONG i, Value = 0;
6174 ULONG *pDst, *pSrc;
6175 UCHAR *p8;
6176
6177 p8 = src;
6178 pDst = (ULONG *) dst;
6179 pSrc = (ULONG *) src;
6180
6181 for (i = 0 ; i < (len/4); i++)
6182 {
6183 /* For alignment issue, we need a variable "Value". */
6184 memmove(&Value, pSrc, 4);
6185 Value = htonl(Value);
6186 memmove(pDst, &Value, 4);
6187 pDst++;
6188 pSrc++;
6189 }
6190 if ((len % 4) != 0)
6191 {
6192 /* wish that it will never reach here */
6193 memmove(&Value, pSrc, (len % 4));
6194 Value = htonl(Value);
6195 memmove(pDst, &Value, (len % 4));
6196 }
6197}
6198
6199static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
6200{
6201 ULONG i;
6202 UCHAR *pDst, *pSrc;
6203
6204 pDst = dst;
6205 pSrc = src;
6206
6207 for (i = 0; i < (len/2); i++)
6208 {
6209 memmove(pDst, pSrc, 2);
6210 *((USHORT *)pDst) = htons(*((USHORT *)pDst));
6211 pDst+=2;
6212 pSrc+=2;
6213 }
6214
6215 if ((len % 2) != 0)
6216 {
6217 memmove(pDst, pSrc, 1);
6218 }
6219}
6220
6221static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len)
6222{
6223 UINT32 i, Value;
6224 UINT32 *pDst, *pSrc;
6225
6226 pDst = (UINT32 *) dst;
6227 pSrc = (UINT32 *) src;
6228
6229 for (i = 0 ; i < (len/4); i++)
6230 {
6231 RTMP_IO_READ32(pAd, (ULONG)pSrc, &Value);
6232 Value = htonl(Value);
6233 memmove(pDst, &Value, 4);
6234 pDst++;
6235 pSrc++;
6236 }
6237 return;
6238}
6239
6240// TODO:
6241#if 0
6242/* These work only when RALINK_ATE is defined */
6243INT Set_TxStart_Proc(
6244 IN PRTMP_ADAPTER pAd,
6245 IN PUCHAR arg)
6246{
6247 ULONG value = simple_strtol(arg, 0, 10);
6248 UCHAR buffer[26] = {0x88, 0x02, 0x2c, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x00, 0x55, 0x44, 0x33, 0x22, 0x11, 0xc0, 0x22, 0x00, 0x00};
6249 POS_COOKIE pObj;
6250
6251 if (pAd->ate.TxStatus != 0)
6252 return FALSE;
6253
6254 pAd->ate.TxInfo = 0x04000000;
6255 bzero(&pAd->ate.TxWI, sizeof(TXWI_STRUC));
6256 pAd->ate.TxWI.PHYMODE = 0;// MODE_CCK
6257 pAd->ate.TxWI.MPDUtotalByteCount = 1226;
6258 pAd->ate.TxWI.MCS = 3;
6259 //pAd->ate.Mode = ATE_START;
6260 pAd->ate.Mode |= ATE_TXFRAME;
6261 pAd->ate.TxCount = value;
6262 pAd->ate.QID = 0;
6263 pAd->ate.HLen = 26;
6264 pAd->ate.PLen = 0;
6265 pAd->ate.DLen = 1200;
6266 memcpy(pAd->ate.Header, buffer, 26);
6267 pAd->ate.bQATxStart = TRUE;
6268 //pObj = (POS_COOKIE) pAd->OS_Cookie;
6269 //tasklet_hi_schedule(&pObj->AteTxTask);
6270 return TRUE;
6271}
6272#endif /* end of #if 0 */
6273
6274INT Set_TxStop_Proc(
6275 IN PRTMP_ADAPTER pAd,
6276 IN PUCHAR arg)
6277{
6278 ATEDBGPRINT(RT_DEBUG_TRACE,("Set_TxStop_Proc\n"));
6279
6280 if (Set_ATE_Proc(pAd, "TXSTOP"))
6281 {
6282 return TRUE;
6283}
6284 else
6285 {
6286 return FALSE;
6287 }
6288}
6289
6290INT Set_RxStop_Proc(
6291 IN PRTMP_ADAPTER pAd,
6292 IN PUCHAR arg)
6293{
6294 ATEDBGPRINT(RT_DEBUG_TRACE,("Set_RxStop_Proc\n"));
6295
6296 if (Set_ATE_Proc(pAd, "RXSTOP"))
6297 {
6298 return TRUE;
6299}
6300 else
6301 {
6302 return FALSE;
6303 }
6304}
6305
6306#if 0
6307INT Set_EEWrite_Proc(
6308 IN PRTMP_ADAPTER pAd,
6309 IN PUCHAR arg)
6310{
6311 USHORT offset = 0, value;
6312 PUCHAR p2 = arg;
6313
6314 while((*p2 != ':') && (*p2 != '\0'))
6315 {
6316 p2++;
6317 }
6318
6319 if (*p2 == ':')
6320 {
6321 A2Hex(offset, arg);
6322 A2Hex(value, p2+ 1);
6323 }
6324 else
6325 {
6326 A2Hex(value, arg);
6327 }
6328
6329 if (offset >= EEPROM_SIZE)
6330 {
6331 ate_print("Offset can not exceed EEPROM_SIZE( == 0x%04x)\n", EEPROM_SIZE);
6332 return FALSE;
6333 }
6334
6335 RTMP_EEPROM_WRITE16(pAd, offset, value);
6336
6337 return TRUE;
6338}
6339
6340INT Set_BBPRead_Proc(
6341 IN PRTMP_ADAPTER pAd,
6342 IN PUCHAR arg)
6343{
6344 UCHAR value = 0, offset;
6345
6346 A2Hex(offset, arg);
6347
6348 if (ATE_ON(pAd))
6349 {
6350 ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &value);
6351 }
6352 else
6353 {
6354 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, &value);
6355 }
6356
6357 ate_print("%x\n", value);
6358
6359 return TRUE;
6360}
6361
6362
6363INT Set_BBPWrite_Proc(
6364 IN PRTMP_ADAPTER pAd,
6365 IN PUCHAR arg)
6366{
6367 USHORT offset = 0;
6368 PUCHAR p2 = arg;
6369 UCHAR value;
6370
6371 while((*p2 != ':') && (*p2 != '\0'))
6372 {
6373 p2++;
6374 }
6375
6376 if (*p2 == ':')
6377 {
6378 A2Hex(offset, arg);
6379 A2Hex(value, p2+ 1);
6380 }
6381 else
6382 {
6383 A2Hex(value, arg);
6384 }
6385
6386 if (ATE_ON(pAd))
6387 {
6388 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, offset, value);
6389 }
6390 else
6391 {
6392 RTNP_BBP_IO_WRITE8_BY_REG_ID(pAd, offset, value);
6393 }
6394
6395 return TRUE;
6396}
6397
6398INT Set_RFWrite_Proc(
6399 IN PRTMP_ADAPTER pAd,
6400 IN PUCHAR arg)
6401{
6402 PUCHAR p2, p3, p4;
6403 ULONG R1, R2, R3, R4;
6404
6405 p2 = arg;
6406
6407 while((*p2 != ':') && (*p2 != '\0'))
6408 {
6409 p2++;
6410 }
6411
6412 if (*p2 != ':')
6413 return FALSE;
6414
6415 p3 = p2 + 1;
6416
6417 while((*p3 != ':') && (*p3 != '\0'))
6418 {
6419 p3++;
6420 }
6421
6422 if (*p3 != ':')
6423 return FALSE;
6424
6425 p4 = p3 + 1;
6426
6427 while((*p4 != ':') && (*p4 != '\0'))
6428 {
6429 p4++;
6430 }
6431
6432 if (*p4 != ':')
6433 return FALSE;
6434
6435
6436 A2Hex(R1, arg);
6437 A2Hex(R2, p2 + 1);
6438 A2Hex(R3, p3 + 1);
6439 A2Hex(R4, p4 + 1);
6440
6441 RTMP_RF_IO_WRITE32(pAd, R1);
6442 RTMP_RF_IO_WRITE32(pAd, R2);
6443 RTMP_RF_IO_WRITE32(pAd, R3);
6444 RTMP_RF_IO_WRITE32(pAd, R4);
6445
6446 return TRUE;
6447}
6448#endif // end of #if 0 //
6449#endif // RALINK_28xx_QA //
6450
6451#endif // RALINK_ATE //
6452
diff --git a/drivers/staging/rt2870/rt_ate.h b/drivers/staging/rt2870/rt_ate.h
new file mode 100644
index 00000000000..b618ce3599a
--- /dev/null
+++ b/drivers/staging/rt2870/rt_ate.h
@@ -0,0 +1,315 @@
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
111VOID rt_ee_read_all(
112 IN PRTMP_ADAPTER pAd,
113 OUT USHORT *Data);
114
115
116VOID rt_ee_write_all(
117 IN PRTMP_ADAPTER pAd,
118 IN USHORT *Data);
119
120INT Set_ATE_Proc(
121 IN PRTMP_ADAPTER pAd,
122 IN PUCHAR arg);
123
124INT Set_ATE_DA_Proc(
125 IN PRTMP_ADAPTER pAd,
126 IN PUCHAR arg);
127
128INT Set_ATE_SA_Proc(
129 IN PRTMP_ADAPTER pAd,
130 IN PUCHAR arg);
131
132INT Set_ATE_BSSID_Proc(
133 IN PRTMP_ADAPTER pAd,
134 IN PUCHAR arg);
135
136INT Set_ATE_CHANNEL_Proc(
137 IN PRTMP_ADAPTER pAd,
138 IN PUCHAR arg);
139
140INT Set_ATE_TX_POWER0_Proc(
141 IN PRTMP_ADAPTER pAd,
142 IN PUCHAR arg);
143
144INT Set_ATE_TX_POWER1_Proc(
145 IN PRTMP_ADAPTER pAd,
146 IN PUCHAR arg);
147
148INT Set_ATE_TX_Antenna_Proc(
149 IN PRTMP_ADAPTER pAd,
150 IN PUCHAR arg);
151
152INT Set_ATE_RX_Antenna_Proc(
153 IN PRTMP_ADAPTER pAd,
154 IN PUCHAR arg);
155
156INT Set_ATE_TX_FREQOFFSET_Proc(
157 IN PRTMP_ADAPTER pAd,
158 IN PUCHAR arg);
159
160INT Set_ATE_TX_BW_Proc(
161 IN PRTMP_ADAPTER pAd,
162 IN PUCHAR arg);
163
164INT Set_ATE_TX_LENGTH_Proc(
165 IN PRTMP_ADAPTER pAd,
166 IN PUCHAR arg);
167
168INT Set_ATE_TX_COUNT_Proc(
169 IN PRTMP_ADAPTER pAd,
170 IN PUCHAR arg);
171
172INT Set_ATE_TX_MCS_Proc(
173 IN PRTMP_ADAPTER pAd,
174 IN PUCHAR arg);
175
176INT Set_ATE_TX_MODE_Proc(
177 IN PRTMP_ADAPTER pAd,
178 IN PUCHAR arg);
179
180INT Set_ATE_TX_GI_Proc(
181 IN PRTMP_ADAPTER pAd,
182 IN PUCHAR arg);
183
184
185INT Set_ATE_RX_FER_Proc(
186 IN PRTMP_ADAPTER pAd,
187 IN PUCHAR arg);
188
189INT Set_ATE_Read_RF_Proc(
190 IN PRTMP_ADAPTER pAd,
191 IN PUCHAR arg);
192
193INT Set_ATE_Write_RF1_Proc(
194 IN PRTMP_ADAPTER pAd,
195 IN PUCHAR arg);
196
197INT Set_ATE_Write_RF2_Proc(
198 IN PRTMP_ADAPTER pAd,
199 IN PUCHAR arg);
200
201INT Set_ATE_Write_RF3_Proc(
202 IN PRTMP_ADAPTER pAd,
203 IN PUCHAR arg);
204
205INT Set_ATE_Write_RF4_Proc(
206 IN PRTMP_ADAPTER pAd,
207 IN PUCHAR arg);
208
209INT Set_ATE_Load_E2P_Proc(
210 IN PRTMP_ADAPTER pAd,
211 IN PUCHAR arg);
212
213INT Set_ATE_Read_E2P_Proc(
214 IN PRTMP_ADAPTER pAd,
215 IN PUCHAR arg);
216
217INT Set_ATE_Show_Proc(
218 IN PRTMP_ADAPTER pAd,
219 IN PUCHAR arg);
220
221INT Set_ATE_Help_Proc(
222 IN PRTMP_ADAPTER pAd,
223 IN PUCHAR arg);
224
225#ifdef RALINK_ATE
226#ifdef RALINK_28xx_QA
227VOID ATE_QA_Statistics(
228 IN PRTMP_ADAPTER pAd,
229 IN PRXWI_STRUC pRxWI,
230 IN PRT28XX_RXD_STRUC p28xxRxD,
231 IN PHEADER_802_11 pHeader);
232
233VOID RtmpDoAte(
234 IN PRTMP_ADAPTER pAdapter,
235 IN struct iwreq *wrq);
236
237VOID BubbleSort(
238 IN INT32 n,
239 IN INT32 a[]);
240
241VOID CalNoiseLevel(
242 IN PRTMP_ADAPTER pAdapter,
243 IN UCHAR channel,
244 OUT INT32 buffer[3][10]);
245
246BOOLEAN SyncTxRxConfig(
247 IN PRTMP_ADAPTER pAdapter,
248 IN USHORT offset,
249 IN UCHAR value);
250
251#if 0
252INT Set_TxStart_Proc(
253 IN PRTMP_ADAPTER pAd,
254 IN PUCHAR arg);
255#endif // 0 //
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#if 0
266INT Set_EERead_Proc(
267 IN PRTMP_ADAPTER pAd,
268 IN PUCHAR arg);
269
270INT Set_EEWrite_Proc(
271 IN PRTMP_ADAPTER pAd,
272 IN PUCHAR arg);
273
274INT Set_BBPRead_Proc(
275 IN PRTMP_ADAPTER pAd,
276 IN PUCHAR arg);
277
278INT Set_BBPWrite_Proc(
279 IN PRTMP_ADAPTER pAd,
280 IN PUCHAR arg);
281
282INT Set_RFWrite_Proc(
283 IN PRTMP_ADAPTER pAd,
284 IN PUCHAR arg);
285#endif // end of #if 0 //
286#endif // RALINK_28xx_QA //
287#endif // RALINK_ATE //
288
289VOID ATEAsicSwitchChannel(
290 IN PRTMP_ADAPTER pAd);
291
292VOID ATEAsicAdjustTxPower(
293 IN PRTMP_ADAPTER pAd);
294
295VOID ATEDisableAsicProtect(
296 IN PRTMP_ADAPTER pAd);
297
298CHAR ATEConvertToRssi(
299 IN PRTMP_ADAPTER pAd,
300 IN CHAR Rssi,
301 IN UCHAR RssiNumber);
302
303VOID ATESampleRssi(
304 IN PRTMP_ADAPTER pAd,
305 IN PRXWI_STRUC pRxWI);
306
307
308#ifdef CONFIG_STA_SUPPORT
309VOID RTMPStationStop(
310 IN PRTMP_ADAPTER pAd);
311
312VOID RTMPStationStart(
313 IN PRTMP_ADAPTER pAd);
314#endif // CONFIG_STA_SUPPORT //
315#endif // __ATE_H__ //
diff --git a/drivers/staging/rt2870/rt_config.h b/drivers/staging/rt2870/rt_config.h
new file mode 100644
index 00000000000..e3fe2642633
--- /dev/null
+++ b/drivers/staging/rt2870/rt_config.h
@@ -0,0 +1,104 @@
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
71
72#ifdef LEAP_SUPPORT
73#include "leap.h"
74#endif // LEAP_SUPPORT //
75
76#ifdef BLOCK_NET_IF
77#include "netif_block.h"
78#endif // BLOCK_NET_IF //
79
80#ifdef IGMP_SNOOP_SUPPORT
81#include "igmp_snoop.h"
82#endif // IGMP_SNOOP_SUPPORT //
83
84#ifdef RALINK_ATE
85#include "rt_ate.h"
86#endif // RALINK_ATE //
87
88
89
90#ifdef CONFIG_STA_SUPPORT
91#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
92#ifndef WPA_SUPPLICANT_SUPPORT
93#error "Build for being controlled by NetworkManager or wext, please set HAS_WPA_SUPPLICANT=y and HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y"
94#endif // WPA_SUPPLICANT_SUPPORT //
95#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
96
97#endif // CONFIG_STA_SUPPORT //
98
99#ifdef IKANOS_VX_1X0
100#include "vr_ikans.h"
101#endif // IKANOS_VX_1X0 //
102
103#endif // __RT_CONFIG_H__
104
diff --git a/drivers/staging/rt2870/rt_linux.c b/drivers/staging/rt2870/rt_linux.c
new file mode 100644
index 00000000000..f2ea8ebcd04
--- /dev/null
+++ b/drivers/staging/rt2870/rt_linux.c
@@ -0,0 +1,1095 @@
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// for wireless system event message
61char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
62 // system status event
63 "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
64 "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
65 "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
66 "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
67 "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
68 "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
69 "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
70 "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
71 "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
72 "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
73 "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
74 "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
75 "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
76 "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
77 "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
78 "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
79 "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
80 "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
81 "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
82 };
83
84// for wireless IDS_spoof_attack event message
85char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
86 "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
87 "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
88 "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
89 "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
90 "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
91 "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
92 "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
93 "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
94 "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
95 "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
96 };
97
98// for wireless IDS_flooding_attack event message
99char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
100 "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
101 "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
102 "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
103 "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
104 "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
105 "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
106 "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
107 };
108
109/* timeout -- ms */
110VOID RTMP_SetPeriodicTimer(
111 IN NDIS_MINIPORT_TIMER *pTimer,
112 IN unsigned long timeout)
113{
114 timeout = ((timeout*HZ) / 1000);
115 pTimer->expires = jiffies + timeout;
116 add_timer(pTimer);
117}
118
119/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
120VOID RTMP_OS_Init_Timer(
121 IN PRTMP_ADAPTER pAd,
122 IN NDIS_MINIPORT_TIMER *pTimer,
123 IN TIMER_FUNCTION function,
124 IN PVOID data)
125{
126 init_timer(pTimer);
127 pTimer->data = (unsigned long)data;
128 pTimer->function = function;
129}
130
131
132VOID RTMP_OS_Add_Timer(
133 IN NDIS_MINIPORT_TIMER *pTimer,
134 IN unsigned long timeout)
135{
136 if (timer_pending(pTimer))
137 return;
138
139 timeout = ((timeout*HZ) / 1000);
140 pTimer->expires = jiffies + timeout;
141 add_timer(pTimer);
142}
143
144VOID RTMP_OS_Mod_Timer(
145 IN NDIS_MINIPORT_TIMER *pTimer,
146 IN unsigned long timeout)
147{
148 timeout = ((timeout*HZ) / 1000);
149 mod_timer(pTimer, jiffies + timeout);
150}
151
152VOID RTMP_OS_Del_Timer(
153 IN NDIS_MINIPORT_TIMER *pTimer,
154 OUT BOOLEAN *pCancelled)
155{
156 if (timer_pending(pTimer))
157 {
158 *pCancelled = del_timer_sync(pTimer);
159 }
160 else
161 {
162 *pCancelled = TRUE;
163 }
164
165}
166
167VOID RTMP_OS_Release_Packet(
168 IN PRTMP_ADAPTER pAd,
169 IN PQUEUE_ENTRY pEntry)
170{
171 //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
172}
173
174// Unify all delay routine by using udelay
175VOID RTMPusecDelay(
176 IN ULONG usec)
177{
178 ULONG i;
179
180 for (i = 0; i < (usec / 50); i++)
181 udelay(50);
182
183 if (usec % 50)
184 udelay(usec % 50);
185}
186
187void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
188{
189 time->u.LowPart = jiffies;
190}
191
192// pAd MUST allow to be NULL
193NDIS_STATUS os_alloc_mem(
194 IN PRTMP_ADAPTER pAd,
195 OUT PUCHAR *mem,
196 IN ULONG size)
197{
198 *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
199 if (*mem)
200 return (NDIS_STATUS_SUCCESS);
201 else
202 return (NDIS_STATUS_FAILURE);
203}
204
205// pAd MUST allow to be NULL
206NDIS_STATUS os_free_mem(
207 IN PRTMP_ADAPTER pAd,
208 IN PUCHAR mem)
209{
210
211 ASSERT(mem);
212 kfree(mem);
213 return (NDIS_STATUS_SUCCESS);
214}
215
216
217PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
218 IN PRTMP_ADAPTER pAd,
219 IN ULONG Length)
220{
221 struct sk_buff *pkt;
222
223 pkt = dev_alloc_skb(Length);
224
225 if (pkt == NULL)
226 {
227 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
228 }
229
230 if (pkt)
231 {
232 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
233 }
234
235 return (PNDIS_PACKET) pkt;
236}
237
238
239PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
240 IN PRTMP_ADAPTER pAd,
241 IN ULONG Length,
242 IN BOOLEAN Cached,
243 OUT PVOID *VirtualAddress)
244{
245 struct sk_buff *pkt;
246
247 pkt = dev_alloc_skb(Length);
248
249 if (pkt == NULL)
250 {
251 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
252 }
253
254 if (pkt)
255 {
256 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
257 *VirtualAddress = (PVOID) pkt->data;
258 }
259 else
260 {
261 *VirtualAddress = (PVOID) NULL;
262 }
263
264 return (PNDIS_PACKET) pkt;
265}
266
267
268VOID build_tx_packet(
269 IN PRTMP_ADAPTER pAd,
270 IN PNDIS_PACKET pPacket,
271 IN PUCHAR pFrame,
272 IN ULONG FrameLen)
273{
274
275 struct sk_buff *pTxPkt;
276
277 ASSERT(pPacket);
278 pTxPkt = RTPKT_TO_OSPKT(pPacket);
279
280 NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
281}
282
283VOID RTMPFreeAdapter(
284 IN PRTMP_ADAPTER pAd)
285{
286 POS_COOKIE os_cookie;
287 int index;
288
289 os_cookie=(POS_COOKIE)pAd->OS_Cookie;
290
291 kfree(pAd->BeaconBuf);
292
293
294 NdisFreeSpinLock(&pAd->MgmtRingLock);
295
296
297 for (index =0 ; index < NUM_OF_TX_RING; index++)
298 {
299 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
300 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
301 pAd->DeQueueRunning[index] = FALSE;
302 }
303
304 NdisFreeSpinLock(&pAd->irq_lock);
305
306
307 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
308 kfree(os_cookie);
309}
310
311BOOLEAN OS_Need_Clone_Packet(void)
312{
313 return (FALSE);
314}
315
316
317
318/*
319 ========================================================================
320
321 Routine Description:
322 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
323 must have only one NDIS BUFFER
324 return - byte copied. 0 means can't create NDIS PACKET
325 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
326
327 Arguments:
328 pAd Pointer to our adapter
329 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
330 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
331
332 Return Value:
333 NDIS_STATUS_SUCCESS
334 NDIS_STATUS_FAILURE
335
336 Note:
337
338 ========================================================================
339*/
340NDIS_STATUS RTMPCloneNdisPacket(
341 IN PRTMP_ADAPTER pAd,
342 IN BOOLEAN pInsAMSDUHdr,
343 IN PNDIS_PACKET pInPacket,
344 OUT PNDIS_PACKET *ppOutPacket)
345{
346
347 struct sk_buff *pkt;
348
349 ASSERT(pInPacket);
350 ASSERT(ppOutPacket);
351
352 // 1. Allocate a packet
353 pkt = dev_alloc_skb(2048);
354
355 if (pkt == NULL)
356 {
357 return NDIS_STATUS_FAILURE;
358 }
359
360 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
361 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
362 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
363
364
365 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
366
367 printk("###Clone###\n");
368
369 return NDIS_STATUS_SUCCESS;
370}
371
372
373// the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
374NDIS_STATUS RTMPAllocateNdisPacket(
375 IN PRTMP_ADAPTER pAd,
376 OUT PNDIS_PACKET *ppPacket,
377 IN PUCHAR pHeader,
378 IN UINT HeaderLen,
379 IN PUCHAR pData,
380 IN UINT DataLen)
381{
382 PNDIS_PACKET pPacket;
383 ASSERT(pData);
384 ASSERT(DataLen);
385
386 // 1. Allocate a packet
387 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
388 if (pPacket == NULL)
389 {
390 *ppPacket = NULL;
391#ifdef DEBUG
392 printk("RTMPAllocateNdisPacket Fail\n\n");
393#endif
394 return NDIS_STATUS_FAILURE;
395 }
396
397 // 2. clone the frame content
398 if (HeaderLen > 0)
399 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
400 if (DataLen > 0)
401 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
402
403 // 3. update length of packet
404 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
405
406 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
407// printk("%s : pPacket = %p, len = %d\n", __FUNCTION__, pPacket, GET_OS_PKT_LEN(pPacket));
408 *ppPacket = pPacket;
409 return NDIS_STATUS_SUCCESS;
410}
411
412/*
413 ========================================================================
414 Description:
415 This routine frees a miniport internally allocated NDIS_PACKET and its
416 corresponding NDIS_BUFFER and allocated memory.
417 ========================================================================
418*/
419VOID RTMPFreeNdisPacket(
420 IN PRTMP_ADAPTER pAd,
421 IN PNDIS_PACKET pPacket)
422{
423 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
424}
425
426
427// IRQL = DISPATCH_LEVEL
428// NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
429// scatter gather buffer
430NDIS_STATUS Sniff2BytesFromNdisBuffer(
431 IN PNDIS_BUFFER pFirstBuffer,
432 IN UCHAR DesiredOffset,
433 OUT PUCHAR pByte0,
434 OUT PUCHAR pByte1)
435{
436 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
437 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
438
439 return NDIS_STATUS_SUCCESS;
440}
441
442
443void RTMP_QueryPacketInfo(
444 IN PNDIS_PACKET pPacket,
445 OUT PACKET_INFO *pPacketInfo,
446 OUT PUCHAR *pSrcBufVA,
447 OUT UINT *pSrcBufLen)
448{
449 pPacketInfo->BufferCount = 1;
450 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
451 pPacketInfo->PhysicalBufferCount = 1;
452 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
453
454 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
455 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
456}
457
458void RTMP_QueryNextPacketInfo(
459 IN PNDIS_PACKET *ppPacket,
460 OUT PACKET_INFO *pPacketInfo,
461 OUT PUCHAR *pSrcBufVA,
462 OUT UINT *pSrcBufLen)
463{
464 PNDIS_PACKET pPacket = NULL;
465
466 if (*ppPacket)
467 pPacket = GET_OS_PKT_NEXT(*ppPacket);
468
469 if (pPacket)
470 {
471 pPacketInfo->BufferCount = 1;
472 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
473 pPacketInfo->PhysicalBufferCount = 1;
474 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
475
476 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
477 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
478 *ppPacket = GET_OS_PKT_NEXT(pPacket);
479 }
480 else
481 {
482 pPacketInfo->BufferCount = 0;
483 pPacketInfo->pFirstBuffer = NULL;
484 pPacketInfo->PhysicalBufferCount = 0;
485 pPacketInfo->TotalPacketLength = 0;
486
487 *pSrcBufVA = NULL;
488 *pSrcBufLen = 0;
489 *ppPacket = NULL;
490 }
491}
492
493// not yet support MBSS
494PNET_DEV get_netdev_from_bssid(
495 IN PRTMP_ADAPTER pAd,
496 IN UCHAR FromWhichBSSID)
497{
498 PNET_DEV dev_p = NULL;
499
500
501#ifdef CONFIG_STA_SUPPORT
502 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
503 {
504 dev_p = pAd->net_dev;
505 }
506#endif // CONFIG_STA_SUPPORT //
507
508 ASSERT(dev_p);
509 return dev_p; /* return one of MBSS */
510}
511
512PNDIS_PACKET DuplicatePacket(
513 IN PRTMP_ADAPTER pAd,
514 IN PNDIS_PACKET pPacket,
515 IN UCHAR FromWhichBSSID)
516{
517 struct sk_buff *skb;
518 PNDIS_PACKET pRetPacket = NULL;
519 USHORT DataSize;
520 UCHAR *pData;
521
522 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
523 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
524
525
526 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
527 if (skb)
528 {
529 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
530 pRetPacket = OSPKT_TO_RTPKT(skb);
531 }
532
533#if 0
534 if ((skb = __dev_alloc_skb(DataSize + 2+32, MEM_ALLOC_FLAG)) != NULL)
535 {
536 skb_reserve(skb, 2+32);
537 NdisMoveMemory(skb->tail, pData, DataSize);
538 skb_put(skb, DataSize);
539 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
540 pRetPacket = OSPKT_TO_RTPKT(skb);
541 }
542#endif
543
544 return pRetPacket;
545
546}
547
548PNDIS_PACKET duplicate_pkt(
549 IN PRTMP_ADAPTER pAd,
550 IN PUCHAR pHeader802_3,
551 IN UINT HdrLen,
552 IN PUCHAR pData,
553 IN ULONG DataSize,
554 IN UCHAR FromWhichBSSID)
555{
556 struct sk_buff *skb;
557 PNDIS_PACKET pPacket = NULL;
558
559
560 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
561 {
562 skb_reserve(skb, 2);
563 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
564 skb_put(skb, HdrLen);
565 NdisMoveMemory(skb->tail, pData, DataSize);
566 skb_put(skb, DataSize);
567 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
568 pPacket = OSPKT_TO_RTPKT(skb);
569 }
570
571 return pPacket;
572}
573
574
575#define TKIP_TX_MIC_SIZE 8
576PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
577 IN PRTMP_ADAPTER pAd,
578 IN PNDIS_PACKET pPacket)
579{
580 struct sk_buff *skb, *newskb;
581
582
583 skb = RTPKT_TO_OSPKT(pPacket);
584 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
585 {
586 // alloc a new skb and copy the packet
587 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
588 dev_kfree_skb_any(skb);
589 if (newskb == NULL)
590 {
591 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
592 return NULL;
593 }
594 skb = newskb;
595 }
596
597 return OSPKT_TO_RTPKT(skb);
598
599#if 0
600 if ((data = skb_put(skb, TKIP_TX_MIC_SIZE)) != NULL)
601 { // If we can extend it, well, copy it first.
602 NdisMoveMemory(data, pAd->PrivateInfo.Tx.MIC, TKIP_TX_MIC_SIZE);
603 }
604 else
605 {
606 // Otherwise, copy the packet.
607 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
608 dev_kfree_skb_any(skb);
609 if (newskb == NULL)
610 {
611 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC to packet failed!, dropping packet\n"));
612 return NULL;
613 }
614 skb = newskb;
615
616 NdisMoveMemory(skb->tail, pAd->PrivateInfo.Tx.MIC, TKIP_TX_MIC_SIZE);
617 skb_put(skb, TKIP_TX_MIC_SIZE);
618 }
619
620 return OSPKT_TO_RTPKT(skb);
621#endif
622
623}
624
625
626
627
628PNDIS_PACKET ClonePacket(
629 IN PRTMP_ADAPTER pAd,
630 IN PNDIS_PACKET pPacket,
631 IN PUCHAR pData,
632 IN ULONG DataSize)
633{
634 struct sk_buff *pRxPkt;
635 struct sk_buff *pClonedPkt;
636
637 ASSERT(pPacket);
638 pRxPkt = RTPKT_TO_OSPKT(pPacket);
639
640 // clone the packet
641 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
642
643 if (pClonedPkt)
644 {
645 // set the correct dataptr and data len
646 pClonedPkt->dev = pRxPkt->dev;
647 pClonedPkt->data = pData;
648 pClonedPkt->len = DataSize;
649 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
650 ASSERT(DataSize < 1530);
651 }
652 return pClonedPkt;
653}
654
655//
656// change OS packet DataPtr and DataLen
657//
658void update_os_packet_info(
659 IN PRTMP_ADAPTER pAd,
660 IN RX_BLK *pRxBlk,
661 IN UCHAR FromWhichBSSID)
662{
663 struct sk_buff *pOSPkt;
664
665 ASSERT(pRxBlk->pRxPacket);
666 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
667
668 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
669 pOSPkt->data = pRxBlk->pData;
670 pOSPkt->len = pRxBlk->DataSize;
671 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
672}
673
674
675void wlan_802_11_to_802_3_packet(
676 IN PRTMP_ADAPTER pAd,
677 IN RX_BLK *pRxBlk,
678 IN PUCHAR pHeader802_3,
679 IN UCHAR FromWhichBSSID)
680{
681 struct sk_buff *pOSPkt;
682
683 ASSERT(pRxBlk->pRxPacket);
684 ASSERT(pHeader802_3);
685
686 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
687
688 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
689 pOSPkt->data = pRxBlk->pData;
690 pOSPkt->len = pRxBlk->DataSize;
691 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
692
693 //
694 // copy 802.3 header
695 //
696 //
697
698#ifdef CONFIG_STA_SUPPORT
699 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
700 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
701#endif // CONFIG_STA_SUPPORT //
702 }
703
704
705
706void announce_802_3_packet(
707 IN PRTMP_ADAPTER pAd,
708 IN PNDIS_PACKET pPacket)
709{
710
711 struct sk_buff *pRxPkt;
712
713 ASSERT(pPacket);
714
715 pRxPkt = RTPKT_TO_OSPKT(pPacket);
716
717#ifdef CONFIG_STA_SUPPORT
718#endif // CONFIG_STA_SUPPORT //
719
720 /* Push up the protocol stack */
721#ifdef IKANOS_VX_1X0
722 IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
723#else
724 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
725
726//#ifdef CONFIG_5VT_ENHANCE
727// *(int*)(pRxPkt->cb) = BRIDGE_TAG;
728//#endif
729 netif_rx(pRxPkt);
730#endif // IKANOS_VX_1X0 //
731}
732
733
734PRTMP_SCATTER_GATHER_LIST
735rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
736{
737 sg->NumberOfElements = 1;
738 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
739 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
740 return (sg);
741}
742
743void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
744{
745 unsigned char *pt;
746 int x;
747
748 if (RTDebugLevel < RT_DEBUG_TRACE)
749 return;
750
751 pt = pSrcBufVA;
752 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
753 for (x=0; x<SrcBufLen; x++)
754 {
755 if (x % 16 == 0)
756 printk("0x%04x : ", x);
757 printk("%02x ", ((unsigned char)pt[x]));
758 if (x%16 == 15) printk("\n");
759 }
760 printk("\n");
761}
762
763/*
764 ========================================================================
765
766 Routine Description:
767 Send log message through wireless event
768
769 Support standard iw_event with IWEVCUSTOM. It is used below.
770
771 iwreq_data.data.flags is used to store event_flag that is defined by user.
772 iwreq_data.data.length is the length of the event log.
773
774 The format of the event log is composed of the entry's MAC address and
775 the desired log message (refer to pWirelessEventText).
776
777 ex: 11:22:33:44:55:66 has associated successfully
778
779 p.s. The requirement of Wireless Extension is v15 or newer.
780
781 ========================================================================
782*/
783VOID RTMPSendWirelessEvent(
784 IN PRTMP_ADAPTER pAd,
785 IN USHORT Event_flag,
786 IN PUCHAR pAddr,
787 IN UCHAR BssIdx,
788 IN CHAR Rssi)
789{
790#if WIRELESS_EXT >= 15
791
792 union iwreq_data wrqu;
793 PUCHAR pBuf = NULL, pBufPtr = NULL;
794 USHORT event, type, BufLen;
795 UCHAR event_table_len = 0;
796
797 type = Event_flag & 0xFF00;
798 event = Event_flag & 0x00FF;
799
800 switch (type)
801 {
802 case IW_SYS_EVENT_FLAG_START:
803 event_table_len = IW_SYS_EVENT_TYPE_NUM;
804 break;
805
806 case IW_SPOOF_EVENT_FLAG_START:
807 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
808 break;
809
810 case IW_FLOOD_EVENT_FLAG_START:
811 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
812 break;
813 }
814
815 if (event_table_len == 0)
816 {
817 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __FUNCTION__, type));
818 return;
819 }
820
821 if (event >= event_table_len)
822 {
823 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __FUNCTION__, event));
824 return;
825 }
826
827 //Allocate memory and copy the msg.
828 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
829 {
830 //Prepare the payload
831 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
832
833 pBufPtr = pBuf;
834
835 if (pAddr)
836 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
837 else if (BssIdx < MAX_MBSSID_NUM)
838 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
839 else
840 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
841
842 if (type == IW_SYS_EVENT_FLAG_START)
843 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
844 else if (type == IW_SPOOF_EVENT_FLAG_START)
845 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
846 else if (type == IW_FLOOD_EVENT_FLAG_START)
847 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
848 else
849 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
850
851 pBufPtr[pBufPtr - pBuf] = '\0';
852 BufLen = pBufPtr - pBuf;
853
854 memset(&wrqu, 0, sizeof(wrqu));
855 wrqu.data.flags = Event_flag;
856 wrqu.data.length = BufLen;
857
858 //send wireless event
859 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
860
861 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __FUNCTION__, pBuf));
862
863 kfree(pBuf);
864 }
865 else
866 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __FUNCTION__));
867#else
868 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __FUNCTION__));
869#endif /* WIRELESS_EXT >= 15 */
870}
871
872
873#ifdef CONFIG_STA_SUPPORT
874void send_monitor_packets(
875 IN PRTMP_ADAPTER pAd,
876 IN RX_BLK *pRxBlk)
877{
878 struct sk_buff *pOSPkt;
879 wlan_ng_prism2_header *ph;
880 int rate_index = 0;
881 USHORT header_len = 0;
882 UCHAR temp_header[40] = {0};
883
884 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
885 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,
886 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};
887
888
889 ASSERT(pRxBlk->pRxPacket);
890 if (pRxBlk->DataSize < 10)
891 {
892 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __FUNCTION__, pRxBlk->DataSize));
893 goto err_free_sk_buff;
894 }
895
896 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
897 {
898 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __FUNCTION__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
899 goto err_free_sk_buff;
900 }
901
902 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
903 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
904 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
905 {
906 pRxBlk->DataSize -= LENGTH_802_11;
907 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
908 (pRxBlk->pHeader->FC.FrDs == 1))
909 header_len = LENGTH_802_11_WITH_ADDR4;
910 else
911 header_len = LENGTH_802_11;
912
913 // QOS
914 if (pRxBlk->pHeader->FC.SubType & 0x08)
915 {
916 header_len += 2;
917 // Data skip QOS contorl field
918 pRxBlk->DataSize -=2;
919 }
920
921 // Order bit: A-Ralink or HTC+
922 if (pRxBlk->pHeader->FC.Order)
923 {
924 header_len += 4;
925 // Data skip HTC contorl field
926 pRxBlk->DataSize -= 4;
927 }
928
929 // Copy Header
930 if (header_len <= 40)
931 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
932
933 // skip HW padding
934 if (pRxBlk->RxD.L2PAD)
935 pRxBlk->pData += (header_len + 2);
936 else
937 pRxBlk->pData += header_len;
938 } //end if
939
940
941 if (pRxBlk->DataSize < pOSPkt->len) {
942 skb_trim(pOSPkt,pRxBlk->DataSize);
943 } else {
944 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
945 } //end if
946
947 if ((pRxBlk->pData - pOSPkt->data) > 0) {
948 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
949 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
950 } //end if
951
952 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
953 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
954 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __FUNCTION__));
955 goto err_free_sk_buff;
956 } //end if
957 } //end if
958
959 if (header_len > 0)
960 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
961
962 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
963 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
964
965 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
966 ph->msglen = sizeof(wlan_ng_prism2_header);
967 strcpy(ph->devname, pAd->net_dev->name);
968
969 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
970 ph->hosttime.status = 0;
971 ph->hosttime.len = 4;
972 ph->hosttime.data = jiffies;
973
974 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
975 ph->mactime.status = 0;
976 ph->mactime.len = 0;
977 ph->mactime.data = 0;
978
979 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
980 ph->istx.status = 0;
981 ph->istx.len = 0;
982 ph->istx.data = 0;
983
984 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
985 ph->channel.status = 0;
986 ph->channel.len = 4;
987
988 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
989
990 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
991 ph->rssi.status = 0;
992 ph->rssi.len = 4;
993 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));;
994
995 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
996 ph->signal.status = 0;
997 ph->signal.len = 4;
998 ph->signal.data = 0; //rssi + noise;
999
1000 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
1001 ph->noise.status = 0;
1002 ph->noise.len = 4;
1003 ph->noise.data = 0;
1004
1005#ifdef DOT11_N_SUPPORT
1006 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
1007 {
1008 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
1009 }
1010 else
1011#endif // DOT11_N_SUPPORT //
1012 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
1013 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
1014 else
1015 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
1016 if (rate_index < 0)
1017 rate_index = 0;
1018 if (rate_index > 255)
1019 rate_index = 255;
1020
1021 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
1022 ph->rate.status = 0;
1023 ph->rate.len = 4;
1024 ph->rate.data = ralinkrate[rate_index];
1025
1026 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
1027 ph->frmlen.status = 0;
1028 ph->frmlen.len = 4;
1029 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
1030
1031
1032 pOSPkt->pkt_type = PACKET_OTHERHOST;
1033 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
1034 pOSPkt->ip_summed = CHECKSUM_NONE;
1035 netif_rx(pOSPkt);
1036
1037 return;
1038
1039err_free_sk_buff:
1040 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1041 return;
1042
1043}
1044#endif // CONFIG_STA_SUPPORT //
1045
1046
1047void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
1048{
1049
1050#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1051 daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
1052
1053 allow_signal(SIGTERM);
1054 allow_signal(SIGKILL);
1055 current->flags |= PF_NOFREEZE;
1056#else
1057 unsigned long flags;
1058
1059 daemonize();
1060 reparent_to_init();
1061 strcpy(current->comm, pThreadName);
1062
1063 siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
1064
1065 /* Allow interception of SIGKILL only
1066 * Don't allow other signals to interrupt the transmission */
1067#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
1068 spin_lock_irqsave(&current->sigmask_lock, flags);
1069 flush_signals(current);
1070 recalc_sigpending(current);
1071 spin_unlock_irqrestore(&current->sigmask_lock, flags);
1072#endif
1073#endif
1074
1075 /* signal that we've started the thread */
1076 complete(pNotify);
1077
1078}
1079
1080void RTMP_IndicateMediaState(
1081 IN PRTMP_ADAPTER pAd)
1082{
1083 if (pAd->CommonCfg.bWirelessEvent)
1084 {
1085 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1086 {
1087 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1088 }
1089 else
1090 {
1091 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1092 }
1093 }
1094}
1095
diff --git a/drivers/staging/rt2870/rt_linux.h b/drivers/staging/rt2870/rt_linux.h
new file mode 100644
index 00000000000..81429757726
--- /dev/null
+++ b/drivers/staging/rt2870/rt_linux.h
@@ -0,0 +1,908 @@
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 "1.4.0.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
167#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
168typedef struct pid * THREAD_PID;
169#define THREAD_PID_INIT_VALUE NULL
170#define GET_PID(_v) find_get_pid(_v)
171#define GET_PID_NUMBER(_v) pid_nr(_v)
172#define CHECK_PID_LEGALITY(_pid) if (pid_nr(_pid) >= 0)
173#define KILL_THREAD_PID(_A, _B, _C) kill_pid(_A, _B, _C)
174#else
175typedef pid_t THREAD_PID;
176#define THREAD_PID_INIT_VALUE -1
177#define GET_PID(_v) _v
178#define GET_PID_NUMBER(_v) _v
179#define CHECK_PID_LEGALITY(_pid) if (_pid >= 0)
180#define KILL_THREAD_PID(_A, _B, _C) kill_proc(_A, _B, _C)
181#endif
182
183struct os_lock {
184 spinlock_t lock;
185 unsigned long flags;
186};
187
188
189struct os_cookie {
190
191#ifdef RT2870
192 struct usb_device *pUsb_Dev;
193
194 THREAD_PID MLMEThr_pid;
195 THREAD_PID RTUSBCmdThr_pid;
196 THREAD_PID TimerQThr_pid;
197#endif // RT2870 //
198
199 struct tasklet_struct rx_done_task;
200 struct tasklet_struct mgmt_dma_done_task;
201 struct tasklet_struct ac0_dma_done_task;
202 struct tasklet_struct ac1_dma_done_task;
203 struct tasklet_struct ac2_dma_done_task;
204 struct tasklet_struct ac3_dma_done_task;
205 struct tasklet_struct hcca_dma_done_task;
206 struct tasklet_struct tbtt_task;
207#ifdef RT2870
208 struct tasklet_struct null_frame_complete_task;
209 struct tasklet_struct rts_frame_complete_task;
210 struct tasklet_struct pspoll_frame_complete_task;
211#endif // RT2870 //
212
213
214 unsigned long apd_pid; //802.1x daemon pid
215 INT ioctl_if_type;
216 INT ioctl_if;
217};
218
219typedef struct _VIRTUAL_ADAPTER
220{
221 struct net_device *RtmpDev;
222 struct net_device *VirtualDev;
223} VIRTUAL_ADAPTER, PVIRTUAL_ADAPTER;
224
225#undef ASSERT
226#define ASSERT(x) \
227{ \
228 if (!(x)) \
229 { \
230 printk(KERN_WARNING __FILE__ ":%d assert " #x "failed\n", __LINE__); \
231 } \
232}
233
234typedef struct os_cookie * POS_COOKIE;
235typedef struct pci_dev * PPCI_DEV;
236typedef struct net_device * PNET_DEV;
237typedef void * PNDIS_PACKET;
238typedef char NDIS_PACKET;
239typedef PNDIS_PACKET * PPNDIS_PACKET;
240typedef dma_addr_t NDIS_PHYSICAL_ADDRESS;
241typedef dma_addr_t * PNDIS_PHYSICAL_ADDRESS;
242//typedef struct timer_list RALINK_TIMER_STRUCT;
243//typedef struct timer_list * PRALINK_TIMER_STRUCT;
244//typedef struct os_lock NDIS_SPIN_LOCK;
245typedef spinlock_t NDIS_SPIN_LOCK;
246typedef struct timer_list NDIS_MINIPORT_TIMER;
247typedef void * NDIS_HANDLE;
248typedef char * PNDIS_BUFFER;
249
250
251
252void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen);
253
254dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction);
255void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction);
256
257
258////////////////////////////////////////
259// MOVE TO rtmp.h ?
260/////////////////////////////////////////
261#define PKTSRC_NDIS 0x7f
262#define PKTSRC_DRIVER 0x0f
263#define PRINT_MAC(addr) \
264 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
265
266
267#define RT2860_PCI_DEVICE_ID 0x0601
268
269
270#ifdef RT2870
271#define PCI_MAP_SINGLE(_handle, _ptr, _size, _dir) (ULONG)0
272
273#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir)
274#endif // RT2870 //
275
276
277#define BEACON_FRAME_DMA_CACHE_WBACK(_ptr, _size) \
278 dma_cache_wback(_ptr, _size)
279
280
281//////////////////////////////////////////
282//
283//////////////////////////////////////////
284
285
286#define NdisMIndicateStatus(_w, _x, _y, _z)
287
288typedef struct timer_list RTMP_OS_TIMER;
289
290#ifdef RT2870
291/* ----------------- Timer Related MARCO ---------------*/
292// In RT2870, we have a lot of timer functions and will read/write register, it's
293// not allowed in Linux USB sub-system to do it ( because of sleep issue when submit
294// to ctrl pipe). So we need a wrapper function to take care it.
295
296typedef VOID (*RT2870_TIMER_HANDLE)(
297 IN PVOID SystemSpecific1,
298 IN PVOID FunctionContext,
299 IN PVOID SystemSpecific2,
300 IN PVOID SystemSpecific3);
301#endif // RT2870 //
302
303
304typedef struct _RALINK_TIMER_STRUCT {
305 RTMP_OS_TIMER TimerObj; // Ndis Timer object
306 BOOLEAN Valid; // Set to True when call RTMPInitTimer
307 BOOLEAN State; // True if timer cancelled
308 BOOLEAN PeriodicType; // True if timer is periodic timer
309 BOOLEAN Repeat; // True if periodic timer
310 ULONG TimerValue; // Timer value in milliseconds
311 ULONG cookie; // os specific object
312#ifdef RT2870
313 RT2870_TIMER_HANDLE handle;
314 void *pAd;
315#endif // RT2870 //
316} RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT;
317
318
319#ifdef RT2870
320
321typedef enum _RT2870_KERNEL_THREAD_STATUS_
322{
323 RT2870_THREAD_UNKNOWN = 0,
324 RT2870_THREAD_INITED = 1,
325 RT2870_THREAD_RUNNING = 2,
326 RT2870_THREAD_STOPED = 4,
327}RT2870_KERNEL_THREAD_STATUS;
328
329#define RT2870_THREAD_CAN_DO_INSERT (RT2870_THREAD_INITED |RT2870_THREAD_RUNNING)
330
331typedef struct _RT2870_TIMER_ENTRY_
332{
333 RALINK_TIMER_STRUCT *pRaTimer;
334 struct _RT2870_TIMER_ENTRY_ *pNext;
335}RT2870_TIMER_ENTRY;
336
337
338#define TIMER_QUEUE_SIZE_MAX 128
339typedef struct _RT2870_TIMER_QUEUE_
340{
341 unsigned int status;
342 //wait_queue_head_t timerWaitQ;
343 //atomic_t count;
344 UCHAR *pTimerQPoll;
345 RT2870_TIMER_ENTRY *pQPollFreeList;
346 RT2870_TIMER_ENTRY *pQHead;
347 RT2870_TIMER_ENTRY *pQTail;
348}RT2870_TIMER_QUEUE;
349#endif // RT2870 //
350
351
352//#define DBG 1
353
354//
355// MACRO for debugging information
356//
357
358#ifdef DBG
359extern ULONG RTDebugLevel;
360
361#define DBGPRINT_RAW(Level, Fmt) \
362{ \
363 if (Level <= RTDebugLevel) \
364 { \
365 printk Fmt; \
366 } \
367}
368
369#define DBGPRINT(Level, Fmt) DBGPRINT_RAW(Level, Fmt)
370
371
372#define DBGPRINT_ERR(Fmt) \
373{ \
374 printk("ERROR!!! "); \
375 printk Fmt; \
376}
377
378#define DBGPRINT_S(Status, Fmt) \
379{ \
380 printk Fmt; \
381}
382
383
384#else
385#define DBGPRINT(Level, Fmt)
386#define DBGPRINT_RAW(Level, Fmt)
387#define DBGPRINT_S(Status, Fmt)
388#define DBGPRINT_ERR(Fmt)
389#endif
390
391
392//
393// spin_lock enhanced for Nested spin lock
394//
395#define NdisAllocateSpinLock(__lock) \
396{ \
397 spin_lock_init((spinlock_t *)(__lock)); \
398}
399
400#define NdisFreeSpinLock(lock) \
401{ \
402}
403
404
405#define RTMP_SEM_LOCK(__lock) \
406{ \
407 spin_lock_bh((spinlock_t *)(__lock)); \
408}
409
410#define RTMP_SEM_UNLOCK(__lock) \
411{ \
412 spin_unlock_bh((spinlock_t *)(__lock)); \
413}
414
415#if 0 // sample, IRQ LOCK
416#define RTMP_IRQ_LOCK(__lock, __irqflags) \
417{ \
418 spin_lock_irqsave((spinlock_t *)__lock, __irqflags); \
419 pAd->irq_disabled |= 1; \
420}
421
422#define RTMP_IRQ_UNLOCK(__lock, __irqflag) \
423{ \
424 pAd->irq_disabled &= 0; \
425 spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag)); \
426}
427#else
428
429// sample, use semaphore lock to replace IRQ lock, 2007/11/15
430#define RTMP_IRQ_LOCK(__lock, __irqflags) \
431{ \
432 __irqflags = 0; \
433 spin_lock_bh((spinlock_t *)(__lock)); \
434 pAd->irq_disabled |= 1; \
435}
436
437#define RTMP_IRQ_UNLOCK(__lock, __irqflag) \
438{ \
439 pAd->irq_disabled &= 0; \
440 spin_unlock_bh((spinlock_t *)(__lock)); \
441}
442
443#define RTMP_INT_LOCK(__lock, __irqflags) \
444{ \
445 spin_lock_irqsave((spinlock_t *)__lock, __irqflags); \
446}
447
448#define RTMP_INT_UNLOCK(__lock, __irqflag) \
449{ \
450 spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag)); \
451}
452#endif
453
454
455
456#ifdef RT2870
457//Patch for ASIC turst read/write bug, needs to remove after metel fix
458#define RTMP_IO_READ32(_A, _R, _pV) \
459 RTUSBReadMACRegister(_A, _R, _pV)
460
461#define RTMP_IO_READ8(_A, _R, _pV) \
462{ \
463}
464
465#define RTMP_IO_WRITE32(_A, _R, _V) \
466 RTUSBWriteMACRegister(_A, _R, _V)
467
468
469#define RTMP_IO_WRITE8(_A, _R, _V) \
470{ \
471 USHORT _Val = _V; \
472 RTUSBSingleWrite(_A, _R, _Val); \
473}
474
475
476#define RTMP_IO_WRITE16(_A, _R, _V) \
477{ \
478 RTUSBSingleWrite(_A, _R, _V); \
479}
480#endif // RT2870 //
481
482#ifndef wait_event_interruptible_timeout
483#define __wait_event_interruptible_timeout(wq, condition, ret) \
484do { \
485 wait_queue_t __wait; \
486 init_waitqueue_entry(&__wait, current); \
487 add_wait_queue(&wq, &__wait); \
488 for (;;) { \
489 set_current_state(TASK_INTERRUPTIBLE); \
490 if (condition) \
491 break; \
492 if (!signal_pending(current)) { \
493 ret = schedule_timeout(ret); \
494 if (!ret) \
495 break; \
496 continue; \
497 } \
498 ret = -ERESTARTSYS; \
499 break; \
500 } \
501 current->state = TASK_RUNNING; \
502 remove_wait_queue(&wq, &__wait); \
503} while (0)
504
505#define wait_event_interruptible_timeout(wq, condition, timeout) \
506({ \
507 long __ret = timeout; \
508 if (!(condition)) \
509 __wait_event_interruptible_timeout(wq, condition, __ret); \
510 __ret; \
511})
512#endif
513#define ONE_TICK 1
514#define OS_WAIT(_time) \
515{ int _i; \
516 long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\
517 wait_queue_head_t _wait; \
518 init_waitqueue_head(&_wait); \
519 for (_i=0; _i<(_loop); _i++) \
520 wait_event_interruptible_timeout(_wait, 0, ONE_TICK); }
521
522
523typedef void (*TIMER_FUNCTION)(unsigned long);
524
525#define COPY_MAC_ADDR(Addr1, Addr2) memcpy((Addr1), (Addr2), MAC_ADDR_LEN)
526
527#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
528#define MlmeFreeMemory(_pAd, _pVA) os_free_mem(_pAd, _pVA)
529
530
531#ifdef RT2870
532#define BUILD_TIMER_FUNCTION(_func) \
533void linux_##_func(unsigned long data) \
534{ \
535 PRALINK_TIMER_STRUCT _pTimer = (PRALINK_TIMER_STRUCT)data; \
536 RT2870_TIMER_ENTRY *_pQNode; \
537 RTMP_ADAPTER *_pAd; \
538 \
539 _pTimer->handle = _func; \
540 _pAd = (RTMP_ADAPTER *)_pTimer->pAd; \
541 _pQNode = RT2870_TimerQ_Insert(_pAd, _pTimer); \
542 if ((_pQNode == NULL) && (_pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)) \
543 RTMP_OS_Add_Timer(&_pTimer->TimerObj, HZ); \
544}
545#endif // RT2870 //
546
547
548#define DECLARE_TIMER_FUNCTION(_func) \
549void linux_##_func(unsigned long data)
550
551#define GET_TIMER_FUNCTION(_func) \
552 linux_##_func
553
554DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
555DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
556DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
557DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
558DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
559#ifdef RT2870
560DECLARE_TIMER_FUNCTION(BeaconUpdateExec);
561#endif // RT2870 //
562
563
564#ifdef CONFIG_STA_SUPPORT
565DECLARE_TIMER_FUNCTION(BeaconTimeout);
566DECLARE_TIMER_FUNCTION(ScanTimeout);
567DECLARE_TIMER_FUNCTION(AuthTimeout);
568DECLARE_TIMER_FUNCTION(AssocTimeout);
569DECLARE_TIMER_FUNCTION(ReassocTimeout);
570DECLARE_TIMER_FUNCTION(DisassocTimeout);
571DECLARE_TIMER_FUNCTION(LinkDownExec);
572#ifdef LEAP_SUPPORT
573DECLARE_TIMER_FUNCTION(LeapAuthTimeout);
574#endif
575DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
576DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
577DECLARE_TIMER_FUNCTION(PsPollWakeExec);
578DECLARE_TIMER_FUNCTION(RadioOnExec);
579
580#ifdef QOS_DLS_SUPPORT
581DECLARE_TIMER_FUNCTION(DlsTimeoutAction);
582#endif // QOS_DLS_SUPPORT //
583#endif // CONFIG_STA_SUPPORT //
584
585void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time);
586
587
588/*
589 * packet helper
590 * - convert internal rt packet to os packet or
591 * os packet to rt packet
592 */
593#define RTPKT_TO_OSPKT(_p) ((struct sk_buff *)(_p))
594#define OSPKT_TO_RTPKT(_p) ((PNDIS_PACKET)(_p))
595
596#define GET_OS_PKT_DATAPTR(_pkt) \
597 (RTPKT_TO_OSPKT(_pkt)->data)
598
599#define GET_OS_PKT_LEN(_pkt) \
600 (RTPKT_TO_OSPKT(_pkt)->len)
601
602#define GET_OS_PKT_DATATAIL(_pkt) \
603 (RTPKT_TO_OSPKT(_pkt)->tail)
604
605#define GET_OS_PKT_HEAD(_pkt) \
606 (RTPKT_TO_OSPKT(_pkt)->head)
607
608#define GET_OS_PKT_END(_pkt) \
609 (RTPKT_TO_OSPKT(_pkt)->end)
610
611#define GET_OS_PKT_NETDEV(_pkt) \
612 (RTPKT_TO_OSPKT(_pkt)->dev)
613
614#define GET_OS_PKT_TYPE(_pkt) \
615 (RTPKT_TO_OSPKT(_pkt))
616
617#define GET_OS_PKT_NEXT(_pkt) \
618 (RTPKT_TO_OSPKT(_pkt)->next)
619
620
621#define OS_NTOHS(_Val) \
622 (ntohs(_Val))
623#define OS_HTONS(_Val) \
624 (htons(_Val))
625#define OS_NTOHL(_Val) \
626 (ntohl(_Val))
627#define OS_HTONL(_Val) \
628 (htonl(_Val))
629
630/* statistics counter */
631#define STATS_INC_RX_PACKETS(_pAd, _dev)
632#define STATS_INC_TX_PACKETS(_pAd, _dev)
633
634#define STATS_INC_RX_BYTESS(_pAd, _dev, len)
635#define STATS_INC_TX_BYTESS(_pAd, _dev, len)
636
637#define STATS_INC_RX_ERRORS(_pAd, _dev)
638#define STATS_INC_TX_ERRORS(_pAd, _dev)
639
640#define STATS_INC_RX_DROPPED(_pAd, _dev)
641#define STATS_INC_TX_DROPPED(_pAd, _dev)
642
643
644#define CB_OFF 10
645
646
647// check DDK NDIS_PACKET data structure and find out only MiniportReservedEx[0..7] can be used by our driver without
648// ambiguity. Fields after pPacket->MiniportReservedEx[8] may be used by other wrapper layer thus crashes the driver
649//
650//#define RTMP_GET_PACKET_MR(_p) (RTPKT_TO_OSPKT(_p))
651
652// User Priority
653#define RTMP_SET_PACKET_UP(_p, _prio) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio)
654#define RTMP_GET_PACKET_UP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0])
655
656// Fragment #
657#define RTMP_SET_PACKET_FRAGMENTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1] = _num)
658#define RTMP_GET_PACKET_FRAGMENTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1])
659
660// 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.
661//(this value also as MAC(on-chip WCID) table index)
662// 0x80~0xff: TX to a WDS link. b0~6: WDS index
663#define RTMP_SET_PACKET_WCID(_p, _wdsidx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2] = _wdsidx)
664#define RTMP_GET_PACKET_WCID(_p) ((UCHAR)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2]))
665
666// 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet
667#define RTMP_SET_PACKET_SOURCE(_p, _pktsrc) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3] = _pktsrc)
668#define RTMP_GET_PACKET_SOURCE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3])
669
670// RTS/CTS-to-self protection method
671#define RTMP_SET_PACKET_RTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4] = _num)
672#define RTMP_GET_PACKET_RTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4])
673// see RTMP_S(G)ET_PACKET_EMACTAB
674
675// TX rate index
676#define RTMP_SET_PACKET_TXRATE(_p, _rate) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5] = _rate)
677#define RTMP_GET_PACKET_TXRATE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5])
678
679// From which Interface
680#define RTMP_SET_PACKET_IF(_p, _ifdx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6] = _ifdx)
681#define RTMP_GET_PACKET_IF(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6])
682#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss) RTMP_SET_PACKET_IF((_p), (_bss))
683#define RTMP_SET_PACKET_NET_DEVICE_WDS(_p, _bss) RTMP_SET_PACKET_IF((_p), ((_bss) + MIN_NET_DEVICE_FOR_WDS))
684#define RTMP_SET_PACKET_NET_DEVICE_APCLI(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_APCLI))
685#define RTMP_SET_PACKET_NET_DEVICE_MESH(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_MESH))
686#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p) RTMP_GET_PACKET_IF((_p))
687#define RTMP_GET_PACKET_NET_DEVICE(_p) RTMP_GET_PACKET_IF((_p))
688
689#define RTMP_SET_PACKET_MOREDATA(_p, _morebit) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7] = _morebit)
690#define RTMP_GET_PACKET_MOREDATA(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7])
691
692//#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss) (RTPKT_TO_OSPKT(_p)->cb[8] = _bss)
693//#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p) (RTPKT_TO_OSPKT(_p)->cb[8])
694
695
696
697
698#if 0
699//#define RTMP_SET_PACKET_DHCP(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg)
700//#define RTMP_GET_PACKET_DHCP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11])
701#else
702//
703// Sepcific Pakcet Type definition
704//
705#define RTMP_PACKET_SPECIFIC_CB_OFFSET 11
706
707#define RTMP_PACKET_SPECIFIC_DHCP 0x01
708#define RTMP_PACKET_SPECIFIC_EAPOL 0x02
709#define RTMP_PACKET_SPECIFIC_IPV4 0x04
710#define RTMP_PACKET_SPECIFIC_WAI 0x08
711#define RTMP_PACKET_SPECIFIC_VLAN 0x10
712#define RTMP_PACKET_SPECIFIC_LLCSNAP 0x20
713
714//Specific
715#define RTMP_SET_PACKET_SPECIFIC(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg)
716
717//DHCP
718#define RTMP_SET_PACKET_DHCP(_p, _flg) \
719 do{ \
720 if (_flg) \
721 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_DHCP); \
722 else \
723 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_DHCP); \
724 }while(0)
725#define RTMP_GET_PACKET_DHCP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_DHCP)
726
727//EAPOL
728#define RTMP_SET_PACKET_EAPOL(_p, _flg) \
729 do{ \
730 if (_flg) \
731 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_EAPOL); \
732 else \
733 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_EAPOL); \
734 }while(0)
735#define RTMP_GET_PACKET_EAPOL(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_EAPOL)
736
737//WAI
738#define RTMP_SET_PACKET_WAI(_p, _flg) \
739 do{ \
740 if (_flg) \
741 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_WAI); \
742 else \
743 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_WAI); \
744 }while(0)
745#define RTMP_GET_PACKET_WAI(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_WAI)
746
747#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))
748
749//VLAN
750#define RTMP_SET_PACKET_VLAN(_p, _flg) \
751 do{ \
752 if (_flg) \
753 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_VLAN); \
754 else \
755 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_VLAN); \
756 }while(0)
757#define RTMP_GET_PACKET_VLAN(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_VLAN)
758
759//LLC/SNAP
760#define RTMP_SET_PACKET_LLCSNAP(_p, _flg) \
761 do{ \
762 if (_flg) \
763 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_LLCSNAP); \
764 else \
765 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_LLCSNAP); \
766 }while(0)
767
768#define RTMP_GET_PACKET_LLCSNAP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_LLCSNAP)
769
770// IP
771#define RTMP_SET_PACKET_IPV4(_p, _flg) \
772 do{ \
773 if (_flg) \
774 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_IPV4); \
775 else \
776 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_IPV4); \
777 }while(0)
778
779#define RTMP_GET_PACKET_IPV4(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_IPV4)
780
781#endif
782
783
784// If this flag is set, it indicates that this EAPoL frame MUST be clear.
785#define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg)
786#define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12])
787
788#define RTMP_SET_PACKET_5VT(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg)
789#define RTMP_GET_PACKET_5VT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22])
790
791
792#ifdef CONFIG_5VT_ENHANCE
793#define BRIDGE_TAG 0x35564252 // depends on 5VT define in br_input.c
794#endif
795
796
797#define NDIS_SET_PACKET_STATUS(_p, _status)
798
799
800#define GET_SG_LIST_FROM_PACKET(_p, _sc) \
801 rt_get_sg_list_from_packet(_p, _sc)
802
803
804#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
805#define NdisZeroMemory(Destination, Length) memset(Destination, 0, Length)
806#define NdisFillMemory(Destination, Length, Fill) memset(Destination, Fill, Length)
807#define NdisEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length))
808#define RTMPEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length))
809
810
811#define RTMP_INC_REF(_A) 0
812#define RTMP_DEC_REF(_A) 0
813#define RTMP_GET_REF(_A) 0
814
815
816
817/*
818 * ULONG
819 * RTMP_GetPhysicalAddressLow(
820 * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);
821 */
822#define RTMP_GetPhysicalAddressLow(PhysicalAddress) (PhysicalAddress)
823
824/*
825 * ULONG
826 * RTMP_GetPhysicalAddressHigh(
827 * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);
828 */
829#define RTMP_GetPhysicalAddressHigh(PhysicalAddress) (0)
830
831/*
832 * VOID
833 * RTMP_SetPhysicalAddressLow(
834 * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
835 * IN ULONG Value);
836 */
837#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value) \
838 PhysicalAddress = Value;
839
840/*
841 * VOID
842 * RTMP_SetPhysicalAddressHigh(
843 * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
844 * IN ULONG Value);
845 */
846#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value)
847
848
849//CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
850#define QUEUE_ENTRY_TO_PACKET(pEntry) \
851 (PNDIS_PACKET)(pEntry)
852
853#define PACKET_TO_QUEUE_ENTRY(pPacket) \
854 (PQUEUE_ENTRY)(pPacket)
855
856
857#ifndef CONTAINING_RECORD
858#define CONTAINING_RECORD(address, type, field) \
859((type *)((PCHAR)(address) - offsetof(type, field)))
860#endif
861
862
863#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status) \
864{ \
865 RTMPFreeNdisPacket(_pAd, _pPacket); \
866}
867
868
869#define SWITCH_PhyAB(_pAA, _pBB) \
870{ \
871 ULONG AABasePaHigh; \
872 ULONG AABasePaLow; \
873 ULONG BBBasePaHigh; \
874 ULONG BBBasePaLow; \
875 BBBasePaHigh = RTMP_GetPhysicalAddressHigh(_pBB); \
876 BBBasePaLow = RTMP_GetPhysicalAddressLow(_pBB); \
877 AABasePaHigh = RTMP_GetPhysicalAddressHigh(_pAA); \
878 AABasePaLow = RTMP_GetPhysicalAddressLow(_pAA); \
879 RTMP_SetPhysicalAddressHigh(_pAA, BBBasePaHigh); \
880 RTMP_SetPhysicalAddressLow(_pAA, BBBasePaLow); \
881 RTMP_SetPhysicalAddressHigh(_pBB, AABasePaHigh); \
882 RTMP_SetPhysicalAddressLow(_pBB, AABasePaLow); \
883}
884
885
886#define NdisWriteErrorLogEntry(_a, _b, _c, _d)
887#define NdisMAllocateMapRegisters(_a, _b, _c, _d, _e) NDIS_STATUS_SUCCESS
888
889
890#define NdisAcquireSpinLock RTMP_SEM_LOCK
891#define NdisReleaseSpinLock RTMP_SEM_UNLOCK
892
893static inline void NdisGetSystemUpTime(ULONG *time)
894{
895 *time = jiffies;
896}
897
898//pPacket = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
899#define QUEUE_ENTRY_TO_PKT(pEntry) \
900 ((PNDIS_PACKET) (pEntry))
901
902int rt28xx_packet_xmit(struct sk_buff *skb);
903
904
905
906void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify);
907
908
diff --git a/drivers/staging/rt2870/rt_main_dev.c b/drivers/staging/rt2870/rt_main_dev.c
new file mode 100644
index 00000000000..16cace7b4c1
--- /dev/null
+++ b/drivers/staging/rt2870/rt_main_dev.c
@@ -0,0 +1,1863 @@
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/*---------------------------------------------------------------------*/
51/* Private Variables Used */
52/*---------------------------------------------------------------------*/
53//static RALINK_TIMER_STRUCT PeriodicTimer;
54
55char *mac = ""; // default 00:00:00:00:00:00
56char *hostname = "";
57#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
58MODULE_PARM (mac, "s");
59#else
60module_param (mac, charp, 0);
61#endif
62MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
63
64
65/*---------------------------------------------------------------------*/
66/* Prototypes of Functions Used */
67/*---------------------------------------------------------------------*/
68#ifdef DOT11_N_SUPPORT
69extern BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
70extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
71#endif // DOT11_N_SUPPORT //
72extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd);
73
74
75// public function prototype
76INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
77 IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
78
79// private function prototype
80static int rt28xx_init(IN struct net_device *net_dev);
81INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
82
83#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
84struct net_device *alloc_netdev(
85 int sizeof_priv,
86 const char *mask,
87 void (*setup)(struct net_device *));
88#endif // LINUX_VERSION_CODE //
89
90static void CfgInitHook(PRTMP_ADAPTER pAd);
91//static BOOLEAN RT28XXAvailRANameAssign(IN CHAR *name_p);
92
93#ifdef CONFIG_STA_SUPPORT
94extern const struct iw_handler_def rt28xx_iw_handler_def;
95#endif // CONFIG_STA_SUPPORT //
96
97#if WIRELESS_EXT >= 12
98// This function will be called when query /proc
99struct iw_statistics *rt28xx_get_wireless_stats(
100 IN struct net_device *net_dev);
101#endif
102
103struct net_device_stats *RT28xx_get_ether_stats(
104 IN struct net_device *net_dev);
105
106/*
107========================================================================
108Routine Description:
109 Close raxx interface.
110
111Arguments:
112 *net_dev the raxx interface pointer
113
114Return Value:
115 0 Open OK
116 otherwise Open Fail
117
118Note:
119 1. if open fail, kernel will not call the close function.
120 2. Free memory for
121 (1) Mlme Memory Handler: MlmeHalt()
122 (2) TX & RX: RTMPFreeTxRxRingMemory()
123 (3) BA Reordering: ba_reordering_resource_release()
124========================================================================
125*/
126int MainVirtualIF_close(IN struct net_device *net_dev)
127{
128 RTMP_ADAPTER *pAd = net_dev->priv;
129
130 // Sanity check for pAd
131 if (pAd == NULL)
132 return 0; // close ok
133
134 netif_carrier_off(pAd->net_dev);
135 netif_stop_queue(pAd->net_dev);
136
137
138
139 VIRTUAL_IF_DOWN(pAd);
140
141 RT_MOD_DEC_USE_COUNT();
142
143 return 0; // close ok
144}
145
146/*
147========================================================================
148Routine Description:
149 Open raxx interface.
150
151Arguments:
152 *net_dev the raxx interface pointer
153
154Return Value:
155 0 Open OK
156 otherwise Open Fail
157
158Note:
159 1. if open fail, kernel will not call the close function.
160 2. Free memory for
161 (1) Mlme Memory Handler: MlmeHalt()
162 (2) TX & RX: RTMPFreeTxRxRingMemory()
163 (3) BA Reordering: ba_reordering_resource_release()
164========================================================================
165*/
166int MainVirtualIF_open(IN struct net_device *net_dev)
167{
168 RTMP_ADAPTER *pAd = net_dev->priv;
169
170 // Sanity check for pAd
171 if (pAd == NULL)
172 return 0; // close ok
173
174 if (VIRTUAL_IF_UP(pAd) != 0)
175 return -1;
176
177 // increase MODULE use count
178 RT_MOD_INC_USE_COUNT();
179
180 netif_start_queue(net_dev);
181 netif_carrier_on(net_dev);
182 netif_wake_queue(net_dev);
183
184 return 0;
185}
186
187/*
188========================================================================
189Routine Description:
190 Close raxx interface.
191
192Arguments:
193 *net_dev the raxx interface pointer
194
195Return Value:
196 0 Open OK
197 otherwise Open Fail
198
199Note:
200 1. if open fail, kernel will not call the close function.
201 2. Free memory for
202 (1) Mlme Memory Handler: MlmeHalt()
203 (2) TX & RX: RTMPFreeTxRxRingMemory()
204 (3) BA Reordering: ba_reordering_resource_release()
205========================================================================
206*/
207int rt28xx_close(IN PNET_DEV dev)
208{
209 struct net_device * net_dev = (struct net_device *)dev;
210 RTMP_ADAPTER *pAd = net_dev->priv;
211 BOOLEAN Cancelled = FALSE;
212 UINT32 i = 0;
213#ifdef RT2870
214 DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
215 DECLARE_WAITQUEUE(wait, current);
216
217 //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
218#endif // RT2870 //
219
220
221 DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
222
223 // Sanity check for pAd
224 if (pAd == NULL)
225 return 0; // close ok
226
227
228#ifdef CONFIG_STA_SUPPORT
229 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
230 {
231
232 // If dirver doesn't wake up firmware here,
233 // NICLoadFirmware will hang forever when interface is up again.
234 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
235 {
236 AsicForceWakeup(pAd, TRUE);
237 }
238
239#ifdef QOS_DLS_SUPPORT
240 // send DLS-TEAR_DOWN message,
241 if (pAd->CommonCfg.bDLSCapable)
242 {
243 UCHAR i;
244
245 // tear down local dls table entry
246 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
247 {
248 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
249 {
250 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
251 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
252 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
253 }
254 }
255
256 // tear down peer dls table entry
257 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
258 {
259 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
260 {
261 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
262 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
263 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
264 }
265 }
266 RT28XX_MLME_HANDLER(pAd);
267 }
268#endif // QOS_DLS_SUPPORT //
269
270 if (INFRA_ON(pAd) &&
271 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
272 {
273 MLME_DISASSOC_REQ_STRUCT DisReq;
274 MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
275
276 COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
277 DisReq.Reason = REASON_DEAUTH_STA_LEAVING;
278
279 MsgElem->Machine = ASSOC_STATE_MACHINE;
280 MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
281 MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
282 NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
283
284 // Prevent to connect AP again in STAMlmePeriodicExec
285 pAd->MlmeAux.AutoReconnectSsidLen= 32;
286 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
287
288 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
289 MlmeDisassocReqAction(pAd, MsgElem);
290 kfree(MsgElem);
291
292 RTMPusecDelay(1000);
293 }
294
295#ifdef RT2870
296 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
297#endif // RT2870 //
298
299#ifdef CCX_SUPPORT
300 RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &Cancelled);
301#endif
302
303 RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
304 RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
305
306#ifdef WPA_SUPPLICANT_SUPPORT
307#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
308 {
309 union iwreq_data wrqu;
310 // send wireless event to wpa_supplicant for infroming interface down.
311 memset(&wrqu, 0, sizeof(wrqu));
312 wrqu.data.flags = RT_INTERFACE_DOWN;
313 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
314 }
315#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
316#endif // WPA_SUPPLICANT_SUPPORT //
317
318 MlmeRadioOff(pAd);
319 }
320#endif // CONFIG_STA_SUPPORT //
321
322 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
323
324 for (i = 0 ; i < NUM_OF_TX_RING; i++)
325 {
326 while (pAd->DeQueueRunning[i] == TRUE)
327 {
328 printk("Waiting for TxQueue[%d] done..........\n", i);
329 RTMPusecDelay(1000);
330 }
331 }
332
333#ifdef RT2870
334 // ensure there are no more active urbs.
335 add_wait_queue (&unlink_wakeup, &wait);
336 pAd->wait = &unlink_wakeup;
337
338 // maybe wait for deletions to finish.
339 i = 0;
340 //while((i < 25) && atomic_read(&pAd->PendingRx) > 0)
341 while(i < 25)
342 {
343 unsigned long IrqFlags;
344
345 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
346 if (pAd->PendingRx == 0)
347 {
348 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
349 break;
350 }
351 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
352
353#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
354 msleep(UNLINK_TIMEOUT_MS); //Time in millisecond
355#else
356 RTMPusecDelay(UNLINK_TIMEOUT_MS*1000); //Time in microsecond
357#endif
358 i++;
359 }
360 pAd->wait = NULL;
361 remove_wait_queue (&unlink_wakeup, &wait);
362#endif // RT2870 //
363
364 //RTUSBCleanUpMLMEWaitQueue(pAd); /*not used in RT28xx*/
365
366
367#ifdef RT2870
368 // We need clear timerQ related structure before exits of the timer thread.
369 RT2870_TimerQ_Exit(pAd);
370 // Close kernel threads or tasklets
371 RT28xxThreadTerminate(pAd);
372#endif // RT2870 //
373
374 // Stop Mlme state machine
375 MlmeHalt(pAd);
376
377 // Close kernel threads or tasklets
378 kill_thread_task(pAd);
379
380
381#ifdef CONFIG_STA_SUPPORT
382 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
383 {
384 MacTableReset(pAd);
385 }
386#endif // CONFIG_STA_SUPPORT //
387
388
389 MeasureReqTabExit(pAd);
390 TpcReqTabExit(pAd);
391
392
393
394
395 // Free Ring or USB buffers
396 RTMPFreeTxRxRingMemory(pAd);
397
398 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
399
400#ifdef DOT11_N_SUPPORT
401 // Free BA reorder resource
402 ba_reordering_resource_release(pAd);
403#endif // DOT11_N_SUPPORT //
404
405#ifdef RT2870
406#ifdef INF_AMAZON_SE
407 if (pAd->UsbVendorReqBuf)
408 os_free_mem(pAd, pAd->UsbVendorReqBuf);
409#endif // INF_AMAZON_SE //
410#endif // RT2870 //
411
412 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
413
414 return 0; // close ok
415} /* End of rt28xx_close */
416
417static int rt28xx_init(IN struct net_device *net_dev)
418{
419 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)net_dev->priv;
420 UINT index;
421 UCHAR TmpPhy;
422 NDIS_STATUS Status;
423 UINT32 MacCsr0 = 0;
424
425#ifdef RT2870
426#ifdef INF_AMAZON_SE
427 init_MUTEX(&(pAd->UsbVendorReq_semaphore));
428 os_alloc_mem(pAd, (PUCHAR)&pAd->UsbVendorReqBuf, MAX_PARAM_BUFFER_SIZE - 1);
429 if (pAd->UsbVendorReqBuf == NULL)
430 {
431 DBGPRINT(RT_DEBUG_ERROR, ("Allocate vendor request temp buffer failed!\n"));
432 goto err0;
433 }
434#endif // INF_AMAZON_SE //
435#endif // RT2870 //
436
437#ifdef DOT11_N_SUPPORT
438 // Allocate BA Reordering memory
439 ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
440#endif // DOT11_N_SUPPORT //
441
442 // Make sure MAC gets ready.
443 index = 0;
444 do
445 {
446 RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
447 pAd->MACVersion = MacCsr0;
448
449 if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
450 break;
451
452 RTMPusecDelay(10);
453 } while (index++ < 100);
454
455 DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
456
457 // Disable DMA
458 RT28XXDMADisable(pAd);
459
460
461 // Load 8051 firmware
462 Status = NICLoadFirmware(pAd);
463 if (Status != NDIS_STATUS_SUCCESS)
464 {
465 DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
466 goto err1;
467 }
468
469 NICLoadRateSwitchingParams(pAd);
470
471 // Disable interrupts here which is as soon as possible
472 // This statement should never be true. We might consider to remove it later
473
474 Status = RTMPAllocTxRxRingMemory(pAd);
475 if (Status != NDIS_STATUS_SUCCESS)
476 {
477 DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status));
478 goto err1;
479 }
480
481 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
482
483 // initialize MLME
484 //
485
486 Status = MlmeInit(pAd);
487 if (Status != NDIS_STATUS_SUCCESS)
488 {
489 DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
490 goto err2;
491 }
492
493 // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default
494 //
495 UserCfgInit(pAd);
496
497#ifdef RT2870
498 // We need init timerQ related structure before create the timer thread.
499 RT2870_TimerQ_Init(pAd);
500#endif // RT2870 //
501
502 RT28XX_TASK_THREAD_INIT(pAd, Status);
503 if (Status != NDIS_STATUS_SUCCESS)
504 goto err1;
505
506// COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr);
507// pAd->bForcePrintTX = TRUE;
508
509 CfgInitHook(pAd);
510
511
512#ifdef BLOCK_NET_IF
513 initblockQueueTab(pAd);
514#endif // BLOCK_NET_IF //
515
516#ifdef CONFIG_STA_SUPPORT
517 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
518 NdisAllocateSpinLock(&pAd->MacTabLock);
519#endif // CONFIG_STA_SUPPORT //
520
521 MeasureReqTabInit(pAd);
522 TpcReqTabInit(pAd);
523
524 //
525 // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset
526 //
527 Status = NICInitializeAdapter(pAd, TRUE);
528 if (Status != NDIS_STATUS_SUCCESS)
529 {
530 DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status));
531 if (Status != NDIS_STATUS_SUCCESS)
532 goto err3;
533 }
534
535 // Read parameters from Config File
536 Status = RTMPReadParametersHook(pAd);
537
538 printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
539 if (Status != NDIS_STATUS_SUCCESS)
540 {
541 DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status));
542 goto err4;
543 }
544
545#ifdef RT2870
546 pAd->CommonCfg.bMultipleIRP = FALSE;
547
548 if (pAd->CommonCfg.bMultipleIRP)
549 pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
550 else
551 pAd->CommonCfg.NumOfBulkInIRP = 1;
552#endif // RT2870 //
553
554
555 //Init Ba Capability parameters.
556// RT28XX_BA_INIT(pAd);
557#ifdef DOT11_N_SUPPORT
558 pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
559 pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
560 pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
561 pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
562 // UPdata to HT IE
563 pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
564 pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
565 pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
566#endif // DOT11_N_SUPPORT //
567
568 // after reading Registry, we now know if in AP mode or STA mode
569
570 // Load 8051 firmware; crash when FW image not existent
571 // Status = NICLoadFirmware(pAd);
572 // if (Status != NDIS_STATUS_SUCCESS)
573 // break;
574
575 printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
576
577 // We should read EEPROM for all cases. rt2860b
578 NICReadEEPROMParameters(pAd, mac);
579#ifdef CONFIG_STA_SUPPORT
580#endif // CONFIG_STA_SUPPORT //
581
582 printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
583
584 NICInitAsicFromEEPROM(pAd); //rt2860b
585
586 // Set PHY to appropriate mode
587 TmpPhy = pAd->CommonCfg.PhyMode;
588 pAd->CommonCfg.PhyMode = 0xff;
589 RTMPSetPhyMode(pAd, TmpPhy);
590#ifdef DOT11_N_SUPPORT
591 SetCommonHT(pAd);
592#endif // DOT11_N_SUPPORT //
593
594 // No valid channels.
595 if (pAd->ChannelListNum == 0)
596 {
597 printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n");
598 goto err4;
599 }
600
601#ifdef DOT11_N_SUPPORT
602 printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0],
603 pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2],
604 pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]);
605#endif // DOT11_N_SUPPORT //
606
607#ifdef RT2870
608 //Init RT30xx RFRegisters after read RFIC type from EEPROM
609 NICInitRT30xxRFRegisters(pAd);
610#endif // RT2870 //
611
612#if 0
613 // Patch cardbus controller if EEPROM said so.
614 if (pAd->bTest1 == FALSE)
615 RTMPPatchCardBus(pAd);
616#endif
617
618
619// APInitialize(pAd);
620
621#ifdef IKANOS_VX_1X0
622 VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress);
623#endif // IKANOS_VX_1X0 //
624
625 //
626 // Initialize RF register to default value
627 //
628 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
629 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
630
631 // 8051 firmware require the signal during booting time.
632 AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00);
633
634 if (pAd && (Status != NDIS_STATUS_SUCCESS))
635 {
636 //
637 // Undo everything if it failed
638 //
639 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
640 {
641// NdisMDeregisterInterrupt(&pAd->Interrupt);
642 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
643 }
644// RTMPFreeAdapter(pAd); // we will free it in disconnect()
645 }
646 else if (pAd)
647 {
648 // Microsoft HCT require driver send a disconnect event after driver initialization.
649 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
650// pAd->IndicateMediaState = NdisMediaStateDisconnected;
651 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
652
653 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
654
655
656#ifdef RT2870
657 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
658 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
659
660 //
661 // Support multiple BulkIn IRP,
662 // the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
663 //
664 for(index=0; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
665 {
666 RTUSBBulkReceive(pAd);
667 DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
668 }
669#endif // RT2870 //
670 }// end of else
671
672
673 DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status));
674
675 return TRUE;
676
677
678err4:
679err3:
680 MlmeHalt(pAd);
681err2:
682 RTMPFreeTxRxRingMemory(pAd);
683// RTMPFreeAdapter(pAd);
684err1:
685
686#ifdef DOT11_N_SUPPORT
687 os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool
688#endif // DOT11_N_SUPPORT //
689 RT28XX_IRQ_RELEASE(net_dev);
690
691 // shall not set priv to NULL here because the priv didn't been free yet.
692 //net_dev->priv = 0;
693#ifdef INF_AMAZON_SE
694err0:
695#endif // INF_AMAZON_SE //
696 printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME);
697 return FALSE;
698} /* End of rt28xx_init */
699
700
701/*
702========================================================================
703Routine Description:
704 Open raxx interface.
705
706Arguments:
707 *net_dev the raxx interface pointer
708
709Return Value:
710 0 Open OK
711 otherwise Open Fail
712
713Note:
714========================================================================
715*/
716int rt28xx_open(IN PNET_DEV dev)
717{
718 struct net_device * net_dev = (struct net_device *)dev;
719 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)net_dev->priv;
720 int retval = 0;
721 POS_COOKIE pObj;
722
723
724 // Sanity check for pAd
725 if (pAd == NULL)
726 {
727 /* if 1st open fail, pAd will be free;
728 So the net_dev->priv will be NULL in 2rd open */
729 return -1;
730 }
731
732#ifdef CONFIG_APSTA_MIXED_SUPPORT
733 if (pAd->OpMode == OPMODE_AP)
734 {
735 CW_MAX_IN_BITS = 6;
736 }
737 else if (pAd->OpMode == OPMODE_STA)
738 {
739 CW_MAX_IN_BITS = 10;
740 }
741
742#if WIRELESS_EXT >= 12
743 if (net_dev->priv_flags == INT_MAIN)
744 {
745 if (pAd->OpMode == OPMODE_AP)
746 net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def;
747 else if (pAd->OpMode == OPMODE_STA)
748 net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def;
749 }
750#endif // WIRELESS_EXT >= 12 //
751#endif // CONFIG_APSTA_MIXED_SUPPORT //
752
753#ifdef CONFIG_STA_SUPPORT
754#endif // CONFIG_STA_SUPPORT //
755
756 // Init
757 pObj = (POS_COOKIE)pAd->OS_Cookie;
758
759 // reset Adapter flags
760 RTMP_CLEAR_FLAGS(pAd);
761
762 // Request interrupt service routine for PCI device
763 // register the interrupt routine with the os
764 RT28XX_IRQ_REQUEST(net_dev);
765
766
767 // Init BssTab & ChannelInfo tabbles for auto channel select.
768
769
770 // Chip & other init
771 if (rt28xx_init(net_dev) == FALSE)
772 goto err;
773
774#ifdef CONFIG_STA_SUPPORT
775 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
776 {
777 NdisZeroMemory(pAd->StaCfg.dev_name, 16);
778 NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
779 }
780#endif // CONFIG_STA_SUPPORT //
781
782 // Set up the Mac address
783 NdisMoveMemory(net_dev->dev_addr, (void *) pAd->CurrentAddress, 6);
784
785 // Init IRQ parameters
786 RT28XX_IRQ_INIT(pAd);
787
788 // Various AP function init
789
790#ifdef CONFIG_STA_SUPPORT
791 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
792 {
793#ifdef WPA_SUPPLICANT_SUPPORT
794#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
795 {
796 union iwreq_data wrqu;
797 // send wireless event to wpa_supplicant for infroming interface down.
798 memset(&wrqu, 0, sizeof(wrqu));
799 wrqu.data.flags = RT_INTERFACE_UP;
800 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
801 }
802#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
803#endif // WPA_SUPPLICANT_SUPPORT //
804
805 }
806#endif // CONFIG_STA_SUPPORT //
807
808 // Enable Interrupt
809 RT28XX_IRQ_ENABLE(pAd);
810
811 // Now Enable RxTx
812 RTMPEnableRxTx(pAd);
813 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
814
815 {
816 UINT32 reg = 0;
817 RTMP_IO_READ32(pAd, 0x1300, &reg); // clear garbage interrupts
818 printk("0x1300 = %08x\n", reg);
819 }
820
821 {
822// u32 reg;
823// u8 byte;
824// u16 tmp;
825
826// RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg);
827
828// tmp = 0x0805;
829// reg = (reg & 0xffff0000) | tmp;
830// RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);
831
832 }
833
834#if 0
835 /*
836 * debugging helper
837 * show the size of main table in Adapter structure
838 * MacTab -- 185K
839 * BATable -- 137K
840 * Total -- 385K !!!!! (5/26/2006)
841 */
842 printk("sizeof(pAd->MacTab) = %ld\n", sizeof(pAd->MacTab));
843 printk("sizeof(pAd->AccessControlList) = %ld\n", sizeof(pAd->AccessControlList));
844 printk("sizeof(pAd->ApCfg) = %ld\n", sizeof(pAd->ApCfg));
845 printk("sizeof(pAd->BATable) = %ld\n", sizeof(pAd->BATable));
846 BUG();
847#endif
848
849#ifdef CONFIG_STA_SUPPORT
850#endif // CONFIG_STA_SUPPORT //
851
852 return (retval);
853
854err:
855 return (-1);
856} /* End of rt28xx_open */
857
858
859/* Must not be called for mdev and apdev */
860static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd)
861{
862 NDIS_STATUS Status;
863 INT i=0;
864 CHAR slot_name[IFNAMSIZ];
865 struct net_device *device;
866
867
868 //ether_setup(dev);
869 dev->hard_start_xmit = rt28xx_send_packets;
870
871#ifdef IKANOS_VX_1X0
872 dev->hard_start_xmit = IKANOS_DataFramesTx;
873#endif // IKANOS_VX_1X0 //
874
875// dev->set_multicast_list = ieee80211_set_multicast_list;
876// dev->change_mtu = ieee80211_change_mtu;
877#ifdef CONFIG_STA_SUPPORT
878#if WIRELESS_EXT >= 12
879 if (pAd->OpMode == OPMODE_STA)
880 {
881 dev->wireless_handlers = &rt28xx_iw_handler_def;
882 }
883#endif //WIRELESS_EXT >= 12
884#endif // CONFIG_STA_SUPPORT //
885
886#ifdef CONFIG_APSTA_MIXED_SUPPORT
887#if WIRELESS_EXT >= 12
888 if (pAd->OpMode == OPMODE_AP)
889 {
890 dev->wireless_handlers = &rt28xx_ap_iw_handler_def;
891 }
892#endif //WIRELESS_EXT >= 12
893#endif // CONFIG_APSTA_MIXED_SUPPORT //
894
895#if WIRELESS_EXT < 21
896 dev->get_wireless_stats = rt28xx_get_wireless_stats;
897#endif
898 dev->get_stats = RT28xx_get_ether_stats;
899 dev->open = MainVirtualIF_open; //rt28xx_open;
900 dev->stop = MainVirtualIF_close; //rt28xx_close;
901// dev->uninit = ieee80211_if_reinit;
902// dev->destructor = ieee80211_if_free;
903 dev->priv_flags = INT_MAIN;
904 dev->do_ioctl = rt28xx_ioctl;
905#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
906 dev->validate_addr = NULL;
907#endif
908 // find available device name
909 for (i = 0; i < 8; i++)
910 {
911#ifdef MULTIPLE_CARD_SUPPORT
912 if (pAd->MC_RowID >= 0)
913 sprintf(slot_name, "ra%02d_%d", pAd->MC_RowID, i);
914 else
915#endif // MULTIPLE_CARD_SUPPORT //
916 sprintf(slot_name, "ra%d", i);
917
918#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
919#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
920#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
921 device = dev_get_by_name(dev_net(dev), slot_name);
922#else
923 device = dev_get_by_name(dev->nd_net, slot_name);
924#endif
925#else
926 device = dev_get_by_name(slot_name);
927#endif
928 if (device != NULL) dev_put(device);
929#else
930 for (device = dev_base; device != NULL; device = device->next)
931 {
932 if (strncmp(device->name, slot_name, 4) == 0)
933 break;
934 }
935#endif
936 if(device == NULL)
937 break;
938 }
939
940 if(i == 8)
941 {
942 DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n"));
943 Status = NDIS_STATUS_FAILURE;
944 }
945 else
946 {
947#ifdef MULTIPLE_CARD_SUPPORT
948 if (pAd->MC_RowID >= 0)
949 sprintf(dev->name, "ra%02d_%d", pAd->MC_RowID, i);
950 else
951#endif // MULTIPLE_CARD_SUPPORT //
952 sprintf(dev->name, "ra%d", i);
953 Status = NDIS_STATUS_SUCCESS;
954 }
955
956 return Status;
957
958}
959
960
961#ifdef MULTIPLE_CARD_SUPPORT
962/*
963========================================================================
964Routine Description:
965 Get card profile path.
966
967Arguments:
968 pAd
969
970Return Value:
971 TRUE - Find a card profile
972 FALSE - use default profile
973
974Note:
975========================================================================
976*/
977extern INT RTMPGetKeyParameter(
978 IN PCHAR key,
979 OUT PCHAR dest,
980 IN INT destsize,
981 IN PCHAR buffer);
982
983BOOLEAN RTMP_CardInfoRead(
984 IN PRTMP_ADAPTER pAd)
985{
986#define MC_SELECT_CARDID 0 /* use CARD ID (0 ~ 31) to identify different cards */
987#define MC_SELECT_MAC 1 /* use CARD MAC to identify different cards */
988#define MC_SELECT_CARDTYPE 2 /* use CARD type (abgn or bgn) to identify different cards */
989
990#define LETTER_CASE_TRANSLATE(txt_p, card_id) \
991 { UINT32 _len; char _char; \
992 for(_len=0; _len<strlen(card_id); _len++) { \
993 _char = *(txt_p + _len); \
994 if (('A' <= _char) && (_char <= 'Z')) \
995 *(txt_p+_len) = 'a'+(_char-'A'); \
996 } }
997
998 struct file *srcf;
999 INT retval, orgfsuid, orgfsgid;
1000 mm_segment_t orgfs;
1001 CHAR *buffer, *tmpbuf, card_id_buf[30], RFIC_word[30];
1002 BOOLEAN flg_match_ok = FALSE;
1003 INT32 card_select_method;
1004 INT32 card_free_id, card_nouse_id, card_same_mac_id, card_match_id;
1005 EEPROM_ANTENNA_STRUC antenna;
1006 USHORT addr01, addr23, addr45;
1007 UINT8 mac[6];
1008 UINT32 data, card_index;
1009 UCHAR *start_ptr;
1010
1011
1012 // init
1013 buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
1014 if (buffer == NULL)
1015 return FALSE;
1016
1017 tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
1018 if(tmpbuf == NULL)
1019 {
1020 kfree(buffer);
1021 return NDIS_STATUS_FAILURE;
1022 }
1023
1024 orgfsuid = current->fsuid;
1025 orgfsgid = current->fsgid;
1026 current->fsuid = current->fsgid = 0;
1027 orgfs = get_fs();
1028 set_fs(KERNEL_DS);
1029
1030 // get RF IC type
1031 RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
1032
1033 if ((data & 0x30) == 0)
1034 pAd->EEPROMAddressNum = 6; // 93C46
1035 else if ((data & 0x30) == 0x10)
1036 pAd->EEPROMAddressNum = 8; // 93C66
1037 else
1038 pAd->EEPROMAddressNum = 8; // 93C86
1039
1040 //antenna.word = RTMP_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET);
1041 RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, antenna.word);
1042
1043 if ((antenna.field.RfIcType == RFIC_2850) ||
1044 (antenna.field.RfIcType == RFIC_2750))
1045 {
1046 /* ABGN card */
1047 strcpy(RFIC_word, "abgn");
1048 }
1049 else
1050 {
1051 /* BGN card */
1052 strcpy(RFIC_word, "bgn");
1053 }
1054
1055 // get MAC address
1056 //addr01 = RTMP_EEPROM_READ16(pAd, 0x04);
1057 //addr23 = RTMP_EEPROM_READ16(pAd, 0x06);
1058 //addr45 = RTMP_EEPROM_READ16(pAd, 0x08);
1059 RT28xx_EEPROM_READ16(pAd, 0x04, addr01);
1060 RT28xx_EEPROM_READ16(pAd, 0x06, addr23);
1061 RT28xx_EEPROM_READ16(pAd, 0x08, addr45);
1062
1063 mac[0] = (UCHAR)(addr01 & 0xff);
1064 mac[1] = (UCHAR)(addr01 >> 8);
1065 mac[2] = (UCHAR)(addr23 & 0xff);
1066 mac[3] = (UCHAR)(addr23 >> 8);
1067 mac[4] = (UCHAR)(addr45 & 0xff);
1068 mac[5] = (UCHAR)(addr45 >> 8);
1069
1070 // open card information file
1071 srcf = filp_open(CARD_INFO_PATH, O_RDONLY, 0);
1072 if (IS_ERR(srcf))
1073 {
1074 /* card information file does not exist */
1075 DBGPRINT(RT_DEBUG_TRACE,
1076 ("--> Error %ld opening %s\n", -PTR_ERR(srcf), CARD_INFO_PATH));
1077 return FALSE;
1078 }
1079
1080 if (srcf->f_op && srcf->f_op->read)
1081 {
1082 /* card information file exists so reading the card information */
1083 memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
1084 retval = srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
1085 if (retval < 0)
1086 {
1087 /* read fail */
1088 DBGPRINT(RT_DEBUG_TRACE,
1089 ("--> Read %s error %d\n", CARD_INFO_PATH, -retval));
1090 }
1091 else
1092 {
1093 /* get card selection method */
1094 memset(tmpbuf, 0x00, MAX_PARAM_BUFFER_SIZE);
1095 card_select_method = MC_SELECT_CARDTYPE; // default
1096
1097 if (RTMPGetKeyParameter("SELECT", tmpbuf, 256, buffer))
1098 {
1099 if (strcmp(tmpbuf, "CARDID") == 0)
1100 card_select_method = MC_SELECT_CARDID;
1101 else if (strcmp(tmpbuf, "MAC") == 0)
1102 card_select_method = MC_SELECT_MAC;
1103 else if (strcmp(tmpbuf, "CARDTYPE") == 0)
1104 card_select_method = MC_SELECT_CARDTYPE;
1105 }
1106
1107 DBGPRINT(RT_DEBUG_TRACE,
1108 ("MC> Card Selection = %d\n", card_select_method));
1109
1110 // init
1111 card_free_id = -1;
1112 card_nouse_id = -1;
1113 card_same_mac_id = -1;
1114 card_match_id = -1;
1115
1116 // search current card information records
1117 for(card_index=0;
1118 card_index<MAX_NUM_OF_MULTIPLE_CARD;
1119 card_index++)
1120 {
1121 if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
1122 (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
1123 {
1124 // MAC is all-0 so the entry is available
1125 MC_CardUsed[card_index] = 0;
1126
1127 if (card_free_id < 0)
1128 card_free_id = card_index; // 1st free entry
1129 }
1130 else
1131 {
1132 if (memcmp(MC_CardMac[card_index], mac, 6) == 0)
1133 {
1134 // we find the entry with same MAC
1135 if (card_same_mac_id < 0)
1136 card_same_mac_id = card_index; // 1st same entry
1137 }
1138 else
1139 {
1140 // MAC is not all-0 but used flag == 0
1141 if ((MC_CardUsed[card_index] == 0) &&
1142 (card_nouse_id < 0))
1143 {
1144 card_nouse_id = card_index; // 1st available entry
1145 }
1146 }
1147 }
1148 }
1149
1150 DBGPRINT(RT_DEBUG_TRACE,
1151 ("MC> Free = %d, Same = %d, NOUSE = %d\n",
1152 card_free_id, card_same_mac_id, card_nouse_id));
1153
1154 if ((card_same_mac_id >= 0) &&
1155 ((card_select_method == MC_SELECT_CARDID) ||
1156 (card_select_method == MC_SELECT_CARDTYPE)))
1157 {
1158 // same MAC entry is found
1159 card_match_id = card_same_mac_id;
1160
1161 if (card_select_method == MC_SELECT_CARDTYPE)
1162 {
1163 // for CARDTYPE
1164 sprintf(card_id_buf, "%02dCARDTYPE%s",
1165 card_match_id, RFIC_word);
1166
1167 if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
1168 {
1169 // we found the card ID
1170 LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
1171 }
1172 }
1173 }
1174 else
1175 {
1176 // the card is 1st plug-in, try to find the match card profile
1177 switch(card_select_method)
1178 {
1179 case MC_SELECT_CARDID: // CARDID
1180 default:
1181 if (card_free_id >= 0)
1182 card_match_id = card_free_id;
1183 else
1184 card_match_id = card_nouse_id;
1185 break;
1186
1187 case MC_SELECT_MAC: // MAC
1188 sprintf(card_id_buf, "MAC%02x:%02x:%02x:%02x:%02x:%02x",
1189 mac[0], mac[1], mac[2],
1190 mac[3], mac[4], mac[5]);
1191
1192 /* try to find the key word in the card file */
1193 if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
1194 {
1195 LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
1196
1197 /* get the row ID (2 ASCII characters) */
1198 start_ptr -= 2;
1199 card_id_buf[0] = *(start_ptr);
1200 card_id_buf[1] = *(start_ptr+1);
1201 card_id_buf[2] = 0x00;
1202
1203 card_match_id = simple_strtol(card_id_buf, 0, 10);
1204 }
1205 break;
1206
1207 case MC_SELECT_CARDTYPE: // CARDTYPE
1208 card_nouse_id = -1;
1209
1210 for(card_index=0;
1211 card_index<MAX_NUM_OF_MULTIPLE_CARD;
1212 card_index++)
1213 {
1214 sprintf(card_id_buf, "%02dCARDTYPE%s",
1215 card_index, RFIC_word);
1216
1217 if ((start_ptr=rtstrstruncasecmp(buffer,
1218 card_id_buf)) != NULL)
1219 {
1220 LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
1221
1222 if (MC_CardUsed[card_index] == 0)
1223 {
1224 /* current the card profile is not used */
1225 if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
1226 (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
1227 {
1228 // find it and no previous card use it
1229 card_match_id = card_index;
1230 break;
1231 }
1232 else
1233 {
1234 // ever a card use it
1235 if (card_nouse_id < 0)
1236 card_nouse_id = card_index;
1237 }
1238 }
1239 }
1240 }
1241
1242 // if not find a free one, use the available one
1243 if (card_match_id < 0)
1244 card_match_id = card_nouse_id;
1245 break;
1246 }
1247 }
1248
1249 if (card_match_id >= 0)
1250 {
1251 // make up search keyword
1252 switch(card_select_method)
1253 {
1254 case MC_SELECT_CARDID: // CARDID
1255 sprintf(card_id_buf, "%02dCARDID", card_match_id);
1256 break;
1257
1258 case MC_SELECT_MAC: // MAC
1259 sprintf(card_id_buf,
1260 "%02dmac%02x:%02x:%02x:%02x:%02x:%02x",
1261 card_match_id,
1262 mac[0], mac[1], mac[2],
1263 mac[3], mac[4], mac[5]);
1264 break;
1265
1266 case MC_SELECT_CARDTYPE: // CARDTYPE
1267 default:
1268 sprintf(card_id_buf, "%02dcardtype%s",
1269 card_match_id, RFIC_word);
1270 break;
1271 }
1272
1273 DBGPRINT(RT_DEBUG_TRACE, ("Search Keyword = %s\n", card_id_buf));
1274
1275 // read card file path
1276 if (RTMPGetKeyParameter(card_id_buf, tmpbuf, 256, buffer))
1277 {
1278 if (strlen(tmpbuf) < sizeof(pAd->MC_FileName))
1279 {
1280 // backup card information
1281 pAd->MC_RowID = card_match_id; /* base 0 */
1282 MC_CardUsed[card_match_id] = 1;
1283 memcpy(MC_CardMac[card_match_id], mac, sizeof(mac));
1284
1285 // backup card file path
1286 NdisMoveMemory(pAd->MC_FileName, tmpbuf , strlen(tmpbuf));
1287 pAd->MC_FileName[strlen(tmpbuf)] = '\0';
1288 flg_match_ok = TRUE;
1289
1290 DBGPRINT(RT_DEBUG_TRACE,
1291 ("Card Profile Name = %s\n", pAd->MC_FileName));
1292 }
1293 else
1294 {
1295 DBGPRINT(RT_DEBUG_ERROR,
1296 ("Card Profile Name length too large!\n"));
1297 }
1298 }
1299 else
1300 {
1301 DBGPRINT(RT_DEBUG_ERROR,
1302 ("Can not find search key word in card.dat!\n"));
1303 }
1304
1305 if ((flg_match_ok != TRUE) &&
1306 (card_match_id < MAX_NUM_OF_MULTIPLE_CARD))
1307 {
1308 MC_CardUsed[card_match_id] = 0;
1309 memset(MC_CardMac[card_match_id], 0, sizeof(mac));
1310 }
1311 } // if (card_match_id >= 0)
1312 }
1313 }
1314
1315 // close file
1316 retval = filp_close(srcf, NULL);
1317 set_fs(orgfs);
1318 current->fsuid = orgfsuid;
1319 current->fsgid = orgfsgid;
1320 kfree(buffer);
1321 kfree(tmpbuf);
1322 return flg_match_ok;
1323}
1324#endif // MULTIPLE_CARD_SUPPORT //
1325
1326
1327/*
1328========================================================================
1329Routine Description:
1330 Probe RT28XX chipset.
1331
1332Arguments:
1333 _dev_p Point to the PCI or USB device
1334 _dev_id_p Point to the PCI or USB device ID
1335
1336Return Value:
1337 0 Probe OK
1338 -ENODEV Probe Fail
1339
1340Note:
1341========================================================================
1342*/
1343INT __devinit rt28xx_probe(
1344 IN void *_dev_p,
1345 IN void *_dev_id_p,
1346 IN UINT argc,
1347 OUT PRTMP_ADAPTER *ppAd)
1348{
1349 struct net_device *net_dev;
1350 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) NULL;
1351 INT status;
1352 PVOID handle;
1353#ifdef RT2870
1354#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
1355 struct usb_device *dev_p = (struct usb_device *)_dev_p;
1356#else
1357 struct usb_interface *intf = (struct usb_interface *)_dev_p;
1358 struct usb_device *dev_p = interface_to_usbdev(intf);
1359
1360 dev_p = usb_get_dev(dev_p);
1361#endif // LINUX_VERSION_CODE //
1362#endif // RT2870 //
1363
1364
1365#ifdef CONFIG_STA_SUPPORT
1366 DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
1367#endif // CONFIG_STA_SUPPORT //
1368
1369 // Check chipset vendor/product ID
1370// if (RT28XXChipsetCheck(_dev_p) == FALSE)
1371// goto err_out;
1372
1373#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
1374 net_dev = alloc_netdev(sizeof(PRTMP_ADAPTER), "eth%d", ether_setup);
1375#else
1376 net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));
1377#endif
1378 if (net_dev == NULL)
1379 {
1380 printk("alloc_netdev failed\n");
1381
1382#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1383#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
1384 module_put(THIS_MODULE);
1385#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
1386#else
1387 MOD_DEC_USE_COUNT;
1388#endif
1389 goto err_out;
1390 }
1391
1392// sample
1393// if (rt_ieee80211_if_setup(net_dev) != NDIS_STATUS_SUCCESS)
1394// goto err_out;
1395
1396#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1397 SET_MODULE_OWNER(net_dev);
1398#endif
1399
1400 netif_stop_queue(net_dev);
1401#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1402/* for supporting Network Manager */
1403/* Set the sysfs physical device reference for the network logical device
1404 * if set prior to registration will cause a symlink during initialization.
1405 */
1406#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
1407 SET_NETDEV_DEV(net_dev, &(dev_p->dev));
1408#endif
1409#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1410
1411 // Allocate RTMP_ADAPTER miniport adapter structure
1412 handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
1413 RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p);
1414
1415 status = RTMPAllocAdapterBlock(handle, &pAd);
1416 if (status != NDIS_STATUS_SUCCESS)
1417 goto err_out_free_netdev;
1418
1419 net_dev->priv = (PVOID)pAd;
1420 pAd->net_dev = net_dev; // must be before RT28XXNetDevInit()
1421
1422 RT28XXNetDevInit(_dev_p, net_dev, pAd);
1423
1424#ifdef CONFIG_STA_SUPPORT
1425 pAd->StaCfg.OriDevType = net_dev->type;
1426#endif // CONFIG_STA_SUPPORT //
1427
1428 // Find and assign a free interface name, raxx
1429// RT28XXAvailRANameAssign(net_dev->name);
1430
1431 // Post config
1432#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1433 if (RT28XXProbePostConfig(_dev_p, pAd, argc) == FALSE)
1434 goto err_out_unmap;
1435#else
1436 if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE)
1437 goto err_out_unmap;
1438#endif // LINUX_VERSION_CODE //
1439
1440#ifdef CONFIG_STA_SUPPORT
1441 pAd->OpMode = OPMODE_STA;
1442#endif // CONFIG_STA_SUPPORT //
1443
1444
1445#ifdef MULTIPLE_CARD_SUPPORT
1446 // find its profile path
1447 pAd->MC_RowID = -1; // use default profile path
1448 RTMP_CardInfoRead(pAd);
1449
1450 if (pAd->MC_RowID == -1)
1451#ifdef CONFIG_STA_SUPPORT
1452 strcpy(pAd->MC_FileName, STA_PROFILE_PATH);
1453#endif // CONFIG_STA_SUPPORT //
1454
1455 DBGPRINT(RT_DEBUG_TRACE,
1456 ("MC> ROW = %d, PATH = %s\n", pAd->MC_RowID, pAd->MC_FileName));
1457#endif // MULTIPLE_CARD_SUPPORT //
1458
1459 // sample move
1460 if (rt_ieee80211_if_setup(net_dev, pAd) != NDIS_STATUS_SUCCESS)
1461 goto err_out_unmap;
1462
1463 // Register this device
1464 status = register_netdev(net_dev);
1465 if (status)
1466 goto err_out_unmap;
1467
1468 // Set driver data
1469 RT28XX_DRVDATA_SET(_dev_p);
1470
1471
1472
1473 *ppAd = pAd;
1474 return 0; // probe ok
1475
1476
1477 /* --------------------------- ERROR HANDLE --------------------------- */
1478err_out_unmap:
1479 RTMPFreeAdapter(pAd);
1480 RT28XX_UNMAP();
1481
1482err_out_free_netdev:
1483#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1484 free_netdev(net_dev);
1485#else
1486 kfree(net_dev);
1487#endif
1488
1489err_out:
1490 RT28XX_PUT_DEVICE(dev_p);
1491
1492#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1493 return (LONG)NULL;
1494#else
1495 return -ENODEV; /* probe fail */
1496#endif // LINUX_VERSION_CODE //
1497} /* End of rt28xx_probe */
1498
1499
1500/*
1501========================================================================
1502Routine Description:
1503 The entry point for Linux kernel sent packet to our driver.
1504
1505Arguments:
1506 sk_buff *skb the pointer refer to a sk_buffer.
1507
1508Return Value:
1509 0
1510
1511Note:
1512 This function is the entry point of Tx Path for Os delivery packet to
1513 our driver. You only can put OS-depened & STA/AP common handle procedures
1514 in here.
1515========================================================================
1516*/
1517int rt28xx_packet_xmit(struct sk_buff *skb)
1518{
1519 struct net_device *net_dev = skb->dev;
1520 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) net_dev->priv;
1521 int status = 0;
1522 PNDIS_PACKET pPacket = (PNDIS_PACKET) skb;
1523
1524 /* RT2870STA does this in RTMPSendPackets() */
1525#ifdef RALINK_ATE
1526 if (ATE_ON(pAd))
1527 {
1528 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
1529 return 0;
1530 }
1531#endif // RALINK_ATE //
1532
1533#ifdef CONFIG_STA_SUPPORT
1534 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1535 {
1536 // Drop send request since we are in monitor mode
1537 if (MONITOR_ON(pAd))
1538 {
1539 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1540 goto done;
1541 }
1542 }
1543#endif // CONFIG_STA_SUPPORT //
1544
1545 // EapolStart size is 18
1546 if (skb->len < 14)
1547 {
1548 //printk("bad packet size: %d\n", pkt->len);
1549 hex_dump("bad packet", skb->data, skb->len);
1550 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1551 goto done;
1552 }
1553
1554#if 0
1555// if ((pkt->data[0] & 0x1) == 0)
1556 {
1557 //hex_dump(__FUNCTION__, pkt->data, pkt->len);
1558 printk("pPacket = %x\n", pPacket);
1559 }
1560#endif
1561
1562 RTMP_SET_PACKET_5VT(pPacket, 0);
1563// MiniportMMRequest(pAd, pkt->data, pkt->len);
1564#ifdef CONFIG_5VT_ENHANCE
1565 if (*(int*)(skb->cb) == BRIDGE_TAG) {
1566 RTMP_SET_PACKET_5VT(pPacket, 1);
1567 }
1568#endif
1569
1570
1571
1572#ifdef CONFIG_STA_SUPPORT
1573 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1574 {
1575
1576 STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
1577 }
1578
1579#endif // CONFIG_STA_SUPPORT //
1580
1581 status = 0;
1582done:
1583
1584 return status;
1585}
1586
1587
1588/*
1589========================================================================
1590Routine Description:
1591 Send a packet to WLAN.
1592
1593Arguments:
1594 skb_p points to our adapter
1595 dev_p which WLAN network interface
1596
1597Return Value:
1598 0: transmit successfully
1599 otherwise: transmit fail
1600
1601Note:
1602========================================================================
1603*/
1604INT rt28xx_send_packets(
1605 IN struct sk_buff *skb_p,
1606 IN struct net_device *net_dev)
1607{
1608 RTMP_ADAPTER *pAd = net_dev->priv;
1609
1610 if (!(net_dev->flags & IFF_UP))
1611 {
1612 RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE);
1613 return 0;
1614 }
1615
1616 NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15);
1617 RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
1618
1619 return rt28xx_packet_xmit(skb_p);
1620} /* End of MBSS_VirtualIF_PacketSend */
1621
1622
1623
1624
1625#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
1626//static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)) //sample
1627struct net_device *alloc_netdev(
1628 int sizeof_priv,
1629 const char *mask,
1630 void (*setup)(struct net_device *))
1631{
1632 struct net_device *dev;
1633 INT alloc_size;
1634
1635
1636 /* ensure 32-byte alignment of the private area */
1637 alloc_size = sizeof (*dev) + sizeof_priv + 31;
1638
1639 dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
1640 if (dev == NULL)
1641 {
1642 DBGPRINT(RT_DEBUG_ERROR,
1643 ("alloc_netdev: Unable to allocate device memory.\n"));
1644 return NULL;
1645 }
1646
1647 memset(dev, 0, alloc_size);
1648
1649 if (sizeof_priv)
1650 dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
1651
1652 setup(dev);
1653 strcpy(dev->name, mask);
1654
1655 return dev;
1656}
1657#endif // LINUX_VERSION_CODE //
1658
1659
1660void CfgInitHook(PRTMP_ADAPTER pAd)
1661{
1662 pAd->bBroadComHT = TRUE;
1663} /* End of CfgInitHook */
1664
1665
1666#if 0 // Not used now, should keep it in our source tree??
1667/*
1668========================================================================
1669Routine Description:
1670 Find and assign a free interface name (raxx).
1671
1672Arguments:
1673 *name_p the interface name pointer
1674
1675Return Value:
1676 TRUE OK
1677 FALSE FAIL
1678
1679Note:
1680========================================================================
1681*/
1682static BOOLEAN RT28XXAvailRANameAssign(
1683 IN CHAR *name_p)
1684{
1685 CHAR slot_name[IFNAMSIZ];
1686 struct net_device *device;
1687 UINT32 if_id;
1688
1689
1690 for(if_id=0; if_id<8; if_id++)
1691 {
1692 sprintf(slot_name, "ra%d", if_id);
1693
1694 for(device=dev_base; device!=NULL; device=device->next)
1695 {
1696 if (strncmp(device->name, slot_name, 4) == 0)
1697 break;
1698 }
1699
1700 if (device == NULL)
1701 break;
1702 }
1703
1704 if (if_id == 8)
1705 {
1706 DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n"));
1707 return FALSE;
1708 }
1709
1710 sprintf(name_p, "ra%d", if_id);
1711 return TRUE;
1712} /* End of RT28XXAvailRANameAssign */
1713#endif
1714
1715#if WIRELESS_EXT >= 12
1716// This function will be called when query /proc
1717struct iw_statistics *rt28xx_get_wireless_stats(
1718 IN struct net_device *net_dev)
1719{
1720 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) net_dev->priv;
1721
1722
1723 DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
1724
1725 pAd->iw_stats.status = 0; // Status - device dependent for now
1726
1727 // link quality
1728 pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
1729 if(pAd->iw_stats.qual.qual > 100)
1730 pAd->iw_stats.qual.qual = 100;
1731
1732#ifdef CONFIG_STA_SUPPORT
1733 if (pAd->OpMode == OPMODE_STA)
1734 pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
1735#endif // CONFIG_STA_SUPPORT //
1736
1737 pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm)
1738
1739 pAd->iw_stats.qual.noise += 256 - 143;
1740 pAd->iw_stats.qual.updated = 1; // Flags to know if updated
1741#ifdef IW_QUAL_DBM
1742 pAd->iw_stats.qual.updated |= IW_QUAL_DBM; // Level + Noise are dBm
1743#endif // IW_QUAL_DBM //
1744
1745 pAd->iw_stats.discard.nwid = 0; // Rx : Wrong nwid/essid
1746 pAd->iw_stats.miss.beacon = 0; // Missed beacons/superframe
1747
1748 DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
1749 return &pAd->iw_stats;
1750} /* End of rt28xx_get_wireless_stats */
1751#endif // WIRELESS_EXT //
1752
1753
1754
1755void tbtt_tasklet(unsigned long data)
1756{
1757#define MAX_TX_IN_TBTT (16)
1758
1759}
1760
1761INT rt28xx_ioctl(
1762 IN struct net_device *net_dev,
1763 IN OUT struct ifreq *rq,
1764 IN INT cmd)
1765{
1766 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1767 RTMP_ADAPTER *pAd = NULL;
1768 INT ret = 0;
1769
1770 if (net_dev->priv_flags == INT_MAIN)
1771 {
1772 pAd = net_dev->priv;
1773 }
1774 else
1775 {
1776 pVirtualAd = net_dev->priv;
1777 pAd = pVirtualAd->RtmpDev->priv;
1778 }
1779
1780 if (pAd == NULL)
1781 {
1782 /* if 1st open fail, pAd will be free;
1783 So the net_dev->priv will be NULL in 2rd open */
1784 return -ENETDOWN;
1785 }
1786
1787
1788#ifdef CONFIG_STA_SUPPORT
1789 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1790 {
1791 ret = rt28xx_sta_ioctl(net_dev, rq, cmd);
1792 }
1793#endif // CONFIG_STA_SUPPORT //
1794
1795 return ret;
1796}
1797
1798/*
1799 ========================================================================
1800
1801 Routine Description:
1802 return ethernet statistics counter
1803
1804 Arguments:
1805 net_dev Pointer to net_device
1806
1807 Return Value:
1808 net_device_stats*
1809
1810 Note:
1811
1812 ========================================================================
1813*/
1814struct net_device_stats *RT28xx_get_ether_stats(
1815 IN struct net_device *net_dev)
1816{
1817 RTMP_ADAPTER *pAd = NULL;
1818
1819 if (net_dev)
1820 pAd = net_dev->priv;
1821
1822 if (pAd)
1823 {
1824
1825 pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
1826 pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
1827
1828 pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
1829 pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
1830
1831 pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
1832 pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
1833
1834 pAd->stats.rx_dropped = 0;
1835 pAd->stats.tx_dropped = 0;
1836
1837 pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart; // multicast packets received
1838 pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions; // Collision packets
1839
1840 pAd->stats.rx_length_errors = 0;
1841 pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer; // receiver ring buff overflow
1842 pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error
1843 pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors; // recv'd frame alignment error
1844 pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer; // recv'r fifo overrun
1845 pAd->stats.rx_missed_errors = 0; // receiver missed packet
1846
1847 // detailed tx_errors
1848 pAd->stats.tx_aborted_errors = 0;
1849 pAd->stats.tx_carrier_errors = 0;
1850 pAd->stats.tx_fifo_errors = 0;
1851 pAd->stats.tx_heartbeat_errors = 0;
1852 pAd->stats.tx_window_errors = 0;
1853
1854 // for cslip etc
1855 pAd->stats.rx_compressed = 0;
1856 pAd->stats.tx_compressed = 0;
1857
1858 return &pAd->stats;
1859 }
1860 else
1861 return NULL;
1862}
1863
diff --git a/drivers/staging/rt2870/rt_profile.c b/drivers/staging/rt2870/rt_profile.c
new file mode 100644
index 00000000000..3e360c66158
--- /dev/null
+++ b/drivers/staging/rt2870/rt_profile.c
@@ -0,0 +1,2016 @@
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 orgfsuid = current->fsuid;
929 orgfsgid = current->fsgid;
930 current->fsuid=current->fsgid = 0;
931 orgfs = get_fs();
932 set_fs(KERNEL_DS);
933
934 if (src && *src)
935 {
936 srcf = filp_open(src, O_RDONLY, 0);
937 if (IS_ERR(srcf))
938 {
939 DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
940 }
941 else
942 {
943 // The object must have a read method
944 if (srcf->f_op && srcf->f_op->read)
945 {
946 memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
947 retval=srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
948 if (retval < 0)
949 {
950 DBGPRINT(RT_DEBUG_TRACE, ("--> Read %s error %d\n", src, -retval));
951 }
952 else
953 {
954 // set file parameter to portcfg
955 //CountryRegion
956 if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, buffer))
957 {
958 pAd->CommonCfg.CountryRegion = (UCHAR) simple_strtol(tmpbuf, 0, 10);
959 DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
960 }
961 //CountryRegionABand
962 if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, buffer))
963 {
964 pAd->CommonCfg.CountryRegionForABand= (UCHAR) simple_strtol(tmpbuf, 0, 10);
965 DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
966 }
967 //CountryCode
968 if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, buffer))
969 {
970 NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2);
971#ifdef CONFIG_STA_SUPPORT
972#ifdef EXT_BUILD_CHANNEL_LIST
973 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
974 NdisMoveMemory(pAd->StaCfg.StaOriCountryCode, tmpbuf , 2);
975#endif // EXT_BUILD_CHANNEL_LIST //
976#endif // CONFIG_STA_SUPPORT //
977 if (strlen(pAd->CommonCfg.CountryCode) != 0)
978 {
979 pAd->CommonCfg.bCountryFlag = TRUE;
980 }
981 DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
982 }
983 //ChannelGeography
984 if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, buffer))
985 {
986 UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10);
987 if (Geography <= BOTH)
988 {
989 pAd->CommonCfg.Geography = Geography;
990 pAd->CommonCfg.CountryCode[2] =
991 (pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
992#ifdef CONFIG_STA_SUPPORT
993#ifdef EXT_BUILD_CHANNEL_LIST
994 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
995 pAd->StaCfg.StaOriGeography = pAd->CommonCfg.Geography;
996#endif // EXT_BUILD_CHANNEL_LIST //
997#endif // CONFIG_STA_SUPPORT //
998 DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
999 }
1000 }
1001 else
1002 {
1003 pAd->CommonCfg.Geography = BOTH;
1004 pAd->CommonCfg.CountryCode[2] = ' ';
1005 }
1006
1007
1008#ifdef CONFIG_STA_SUPPORT
1009 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1010 {
1011 //SSID
1012 if (RTMPGetCriticalParameter("SSID", tmpbuf, 256, buffer))
1013 {
1014 if (strlen(tmpbuf) <= 32)
1015 {
1016 pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf);
1017 NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID);
1018 NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen);
1019 pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
1020 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID);
1021 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen);
1022 pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
1023 NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID);
1024 NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen);
1025 DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __FUNCTION__, tmpbuf));
1026 }
1027 }
1028 }
1029#endif // CONFIG_STA_SUPPORT //
1030
1031#ifdef CONFIG_STA_SUPPORT
1032 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1033 {
1034 //NetworkType
1035 if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, buffer))
1036 {
1037 pAd->bConfigChanged = TRUE;
1038 if (strcmp(tmpbuf, "Adhoc") == 0)
1039 pAd->StaCfg.BssType = BSS_ADHOC;
1040 else //Default Infrastructure mode
1041 pAd->StaCfg.BssType = BSS_INFRA;
1042 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
1043 pAd->StaCfg.WpaState = SS_NOTUSE;
1044 DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __FUNCTION__, pAd->StaCfg.BssType));
1045 }
1046 }
1047#endif // CONFIG_STA_SUPPORT //
1048 //Channel
1049 if(RTMPGetKeyParameter("Channel", tmpbuf, 10, buffer))
1050 {
1051 pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10);
1052 DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel));
1053 }
1054 //WirelessMode
1055 if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, buffer))
1056 {
1057 int value = 0, maxPhyMode = PHY_11G;
1058
1059#ifdef DOT11_N_SUPPORT
1060 maxPhyMode = PHY_11N_5G;
1061#endif // DOT11_N_SUPPORT //
1062
1063 value = simple_strtol(tmpbuf, 0, 10);
1064
1065 if (value <= maxPhyMode)
1066 {
1067 pAd->CommonCfg.PhyMode = value;
1068 }
1069 DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
1070 }
1071 //BasicRate
1072 if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, buffer))
1073 {
1074 pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10);
1075 DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap));
1076 }
1077 //BeaconPeriod
1078 if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, buffer))
1079 {
1080 pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10);
1081 DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod));
1082 }
1083 //TxPower
1084 if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, buffer))
1085 {
1086 pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
1087#ifdef CONFIG_STA_SUPPORT
1088 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1089 pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage;
1090#endif // CONFIG_STA_SUPPORT //
1091 DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage));
1092 }
1093 //BGProtection
1094 if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, buffer))
1095 {
1096 switch (simple_strtol(tmpbuf, 0, 10))
1097 {
1098 case 1: //Always On
1099 pAd->CommonCfg.UseBGProtection = 1;
1100 break;
1101 case 2: //Always OFF
1102 pAd->CommonCfg.UseBGProtection = 2;
1103 break;
1104 case 0: //AUTO
1105 default:
1106 pAd->CommonCfg.UseBGProtection = 0;
1107 break;
1108 }
1109 DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
1110 }
1111 //OLBCDetection
1112 if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, buffer))
1113 {
1114 switch (simple_strtol(tmpbuf, 0, 10))
1115 {
1116 case 1: //disable OLBC Detection
1117 pAd->CommonCfg.DisableOLBCDetect = 1;
1118 break;
1119 case 0: //enable OLBC Detection
1120 pAd->CommonCfg.DisableOLBCDetect = 0;
1121 break;
1122 default:
1123 pAd->CommonCfg.DisableOLBCDetect= 0;
1124 break;
1125 }
1126 DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
1127 }
1128 //TxPreamble
1129 if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, buffer))
1130 {
1131 switch (simple_strtol(tmpbuf, 0, 10))
1132 {
1133 case Rt802_11PreambleShort:
1134 pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort;
1135 break;
1136 case Rt802_11PreambleLong:
1137 default:
1138 pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong;
1139 break;
1140 }
1141 DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble));
1142 }
1143 //RTSThreshold
1144 if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, buffer))
1145 {
1146 RtsThresh = simple_strtol(tmpbuf, 0, 10);
1147 if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) )
1148 pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
1149 else
1150 pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
1151
1152 DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold));
1153 }
1154 //FragThreshold
1155 if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, buffer))
1156 {
1157 FragThresh = simple_strtol(tmpbuf, 0, 10);
1158 pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
1159
1160 if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
1161 { //illegal FragThresh so we set it to default
1162 pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
1163 pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
1164 }
1165 else if (FragThresh % 2 == 1)
1166 {
1167 // The length of each fragment shall always be an even number of octets, except for the last fragment
1168 // of an MSDU or MMPDU, which may be either an even or an odd number of octets.
1169 pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
1170 }
1171 else
1172 {
1173 pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
1174 }
1175 //pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
1176 DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold));
1177 }
1178 //TxBurst
1179 if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, buffer))
1180 {
1181//#ifdef WIFI_TEST
1182// pAd->CommonCfg.bEnableTxBurst = FALSE;
1183//#else
1184 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
1185 pAd->CommonCfg.bEnableTxBurst = TRUE;
1186 else //Disable
1187 pAd->CommonCfg.bEnableTxBurst = FALSE;
1188//#endif
1189 DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
1190 }
1191
1192#ifdef AGGREGATION_SUPPORT
1193 //PktAggregate
1194 if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, buffer))
1195 {
1196 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
1197 pAd->CommonCfg.bAggregationCapable = TRUE;
1198 else //Disable
1199 pAd->CommonCfg.bAggregationCapable = FALSE;
1200#ifdef PIGGYBACK_SUPPORT
1201 pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
1202#endif // PIGGYBACK_SUPPORT //
1203 DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
1204 }
1205#else
1206 pAd->CommonCfg.bAggregationCapable = FALSE;
1207 pAd->CommonCfg.bPiggyBackCapable = FALSE;
1208#endif // AGGREGATION_SUPPORT //
1209
1210 // WmmCapable
1211
1212#ifdef CONFIG_STA_SUPPORT
1213 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1214 rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, buffer);
1215#endif // CONFIG_STA_SUPPORT //
1216
1217 //ShortSlot
1218 if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, buffer))
1219 {
1220 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
1221 pAd->CommonCfg.bUseShortSlotTime = TRUE;
1222 else //Disable
1223 pAd->CommonCfg.bUseShortSlotTime = FALSE;
1224
1225 DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
1226 }
1227 //IEEE80211H
1228 if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, buffer))
1229 {
1230 for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
1231 {
1232 if(simple_strtol(macptr, 0, 10) != 0) //Enable
1233 pAd->CommonCfg.bIEEE80211H = TRUE;
1234 else //Disable
1235 pAd->CommonCfg.bIEEE80211H = FALSE;
1236
1237 DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
1238 }
1239 }
1240 //CSPeriod
1241 if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, buffer))
1242 {
1243 if(simple_strtol(tmpbuf, 0, 10) != 0)
1244 pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
1245 else
1246 pAd->CommonCfg.RadarDetect.CSPeriod = 0;
1247
1248 DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
1249 }
1250
1251 //RDRegion
1252 if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, buffer))
1253 {
1254 if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
1255 {
1256 pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W53;
1257 pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
1258 }
1259 else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
1260 {
1261 pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W56;
1262 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1263 }
1264 else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
1265 {
1266 pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
1267 pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
1268 }
1269 else if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
1270 {
1271 pAd->CommonCfg.RadarDetect.RDDurRegion = FCC;
1272 pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
1273 }
1274 else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
1275 {
1276 pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1277 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1278 }
1279 else
1280 {
1281 pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1282 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1283 }
1284
1285 DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RadarDetect.RDDurRegion));
1286 }
1287 else
1288 {
1289 pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1290 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1291 }
1292
1293 //WirelessEvent
1294 if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, buffer))
1295 {
1296#if WIRELESS_EXT >= 15
1297 if(simple_strtol(tmpbuf, 0, 10) != 0)
1298 pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
1299 else
1300 pAd->CommonCfg.bWirelessEvent = 0; // disable
1301#else
1302 pAd->CommonCfg.bWirelessEvent = 0; // disable
1303#endif
1304 DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
1305 }
1306 if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, buffer))
1307 {
1308 if(simple_strtol(tmpbuf, 0, 10) != 0)
1309 pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
1310 else
1311 pAd->CommonCfg.bWiFiTest = 0; // disable
1312
1313 DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
1314 }
1315 //AuthMode
1316 if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, buffer))
1317 {
1318#ifdef CONFIG_STA_SUPPORT
1319 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1320 {
1321 if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
1322 pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
1323 else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
1324 pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1325 else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
1326 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
1327 else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
1328 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
1329 else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
1330 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
1331#ifdef WPA_SUPPLICANT_SUPPORT
1332 else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
1333 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
1334 else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
1335 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
1336#endif // WPA_SUPPLICANT_SUPPORT //
1337 else
1338 pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1339
1340 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1341
1342 DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
1343 }
1344#endif // CONFIG_STA_SUPPORT //
1345 }
1346 //EncrypType
1347 if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, buffer))
1348 {
1349
1350#ifdef CONFIG_STA_SUPPORT
1351 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1352 {
1353 if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
1354 pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1355 else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
1356 pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
1357 else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
1358 pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
1359 else
1360 pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1361
1362 // Update all wepstatus related
1363 pAd->StaCfg.PairCipher = pAd->StaCfg.WepStatus;
1364 pAd->StaCfg.GroupCipher = pAd->StaCfg.WepStatus;
1365 pAd->StaCfg.OrigWepStatus = pAd->StaCfg.WepStatus;
1366 pAd->StaCfg.bMixCipher = FALSE;
1367
1368 //RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
1369 DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
1370 }
1371#endif // CONFIG_STA_SUPPORT //
1372 }
1373
1374
1375
1376#ifdef CONFIG_STA_SUPPORT
1377 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1378 {
1379 if(RTMPGetCriticalParameter("WPAPSK", tmpbuf, 512, buffer))
1380 {
1381 int err=0;
1382
1383 tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
1384
1385 if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
1386 (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
1387 (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
1388 )
1389 {
1390 err = 1;
1391 }
1392 else if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) < 64))
1393 {
1394 PasswordHash((char *)tmpbuf, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, keyMaterial);
1395 NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
1396
1397 }
1398 else if (strlen(tmpbuf) == 64)
1399 {
1400 AtoH(tmpbuf, keyMaterial, 32);
1401 NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
1402 }
1403 else
1404 {
1405 err = 1;
1406 DBGPRINT(RT_DEBUG_ERROR, ("%s::(WPAPSK key-string required 8 ~ 64 characters!)\n", __FUNCTION__));
1407 }
1408
1409 if (err == 0)
1410 {
1411 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1412 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1413 {
1414 // Start STA supplicant state machine
1415 pAd->StaCfg.WpaState = SS_START;
1416 }
1417 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1418 {
1419 /*
1420 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1421 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1422 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1423 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1424 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1425
1426 // Decide its ChiperAlg
1427 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1428 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1429 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1430 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1431 else
1432 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
1433 */
1434 pAd->StaCfg.WpaState = SS_NOTUSE;
1435 }
1436
1437 DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __FUNCTION__, tmpbuf));
1438 }
1439 }
1440 }
1441#endif // CONFIG_STA_SUPPORT //
1442
1443 //DefaultKeyID, KeyType, KeyStr
1444 rtmp_read_key_parms_from_file(pAd, tmpbuf, buffer);
1445
1446
1447 //HSCounter
1448 /*if(RTMPGetKeyParameter("HSCounter", tmpbuf, 10, buffer))
1449 {
1450 switch (simple_strtol(tmpbuf, 0, 10))
1451 {
1452 case 1: //Enable
1453 pAd->CommonCfg.bEnableHSCounter = TRUE;
1454 break;
1455 case 0: //Disable
1456 default:
1457 pAd->CommonCfg.bEnableHSCounter = FALSE;
1458 break;
1459 }
1460 DBGPRINT(RT_DEBUG_TRACE, "HSCounter=%d\n", pAd->CommonCfg.bEnableHSCounter);
1461 }*/
1462
1463#ifdef DOT11_N_SUPPORT
1464 HTParametersHook(pAd, tmpbuf, buffer);
1465#endif // DOT11_N_SUPPORT //
1466
1467
1468#ifdef CARRIER_DETECTION_SUPPORT
1469 //CarrierDetect
1470 if(RTMPGetKeyParameter("CarrierDetect", tmpbuf, 128, buffer))
1471 {
1472 if ((strncmp(tmpbuf, "0", 1) == 0))
1473 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
1474 else if ((strncmp(tmpbuf, "1", 1) == 0))
1475 pAd->CommonCfg.CarrierDetect.Enable = TRUE;
1476 else
1477 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
1478
1479 DBGPRINT(RT_DEBUG_TRACE, ("CarrierDetect.Enable=%d\n", pAd->CommonCfg.CarrierDetect.Enable));
1480 }
1481 else
1482 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
1483#endif // CARRIER_DETECTION_SUPPORT //
1484
1485#ifdef CONFIG_STA_SUPPORT
1486 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1487 {
1488 //PSMode
1489 if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer))
1490 {
1491 if (pAd->StaCfg.BssType == BSS_INFRA)
1492 {
1493 if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
1494 {
1495 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1496 // to exclude certain situations.
1497 // MlmeSetPsm(pAd, PWR_SAVE);
1498 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1499 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1500 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
1501 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
1502 pAd->StaCfg.DefaultListenCount = 5;
1503 }
1504 else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
1505 || (strcmp(tmpbuf, "FAST_PSP") == 0))
1506 {
1507 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1508 // to exclude certain situations.
1509 // MlmeSetPsmBit(pAd, PWR_SAVE);
1510 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1511 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1512 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
1513 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
1514 pAd->StaCfg.DefaultListenCount = 3;
1515 }
1516 else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
1517 || (strcmp(tmpbuf, "LEGACY_PSP") == 0))
1518 {
1519 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1520 // to exclude certain situations.
1521 // MlmeSetPsmBit(pAd, PWR_SAVE);
1522 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1523 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1524 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
1525 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
1526 pAd->StaCfg.DefaultListenCount = 3;
1527 }
1528 else
1529 { //Default Ndis802_11PowerModeCAM
1530 // clear PSM bit immediately
1531 MlmeSetPsmBit(pAd, PWR_ACTIVE);
1532 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1533 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1534 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
1535 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
1536 }
1537 DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
1538 }
1539 }
1540 // FastRoaming
1541 if (RTMPGetKeyParameter("FastRoaming", tmpbuf, 32, buffer))
1542 {
1543 if (simple_strtol(tmpbuf, 0, 10) == 0)
1544 pAd->StaCfg.bFastRoaming = FALSE;
1545 else
1546 pAd->StaCfg.bFastRoaming = TRUE;
1547
1548 DBGPRINT(RT_DEBUG_TRACE, ("FastRoaming=%d\n", pAd->StaCfg.bFastRoaming));
1549 }
1550 // RoamThreshold
1551 if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, buffer))
1552 {
1553 long lInfo = simple_strtol(tmpbuf, 0, 10);
1554
1555 if (lInfo > 90 || lInfo < 60)
1556 pAd->StaCfg.dBmToRoam = -70;
1557 else
1558 pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
1559
1560 DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d dBm\n", pAd->StaCfg.dBmToRoam));
1561 }
1562
1563 if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, buffer))
1564 {
1565 if(simple_strtol(tmpbuf, 0, 10) == 0)
1566 pAd->StaCfg.bTGnWifiTest = FALSE;
1567 else
1568 pAd->StaCfg.bTGnWifiTest = TRUE;
1569 DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
1570 }
1571 }
1572#endif // CONFIG_STA_SUPPORT //
1573
1574
1575
1576 }
1577 }
1578 else
1579 {
1580 DBGPRINT(RT_DEBUG_TRACE, ("--> %s does not have a write method\n", src));
1581 }
1582
1583 retval=filp_close(srcf,NULL);
1584
1585 if (retval)
1586 {
1587 DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
1588 }
1589 }
1590 }
1591
1592 set_fs(orgfs);
1593 current->fsuid = orgfsuid;
1594 current->fsgid = orgfsgid;
1595
1596 kfree(buffer);
1597 kfree(tmpbuf);
1598
1599 return (NDIS_STATUS_SUCCESS);
1600}
1601
1602#ifdef DOT11_N_SUPPORT
1603static void HTParametersHook(
1604 IN PRTMP_ADAPTER pAd,
1605 IN CHAR *pValueStr,
1606 IN CHAR *pInput)
1607{
1608
1609 INT Value;
1610
1611 if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput))
1612 {
1613 Value = simple_strtol(pValueStr, 0, 10);
1614 if (Value == 0)
1615 {
1616 pAd->CommonCfg.bHTProtect = FALSE;
1617 }
1618 else
1619 {
1620 pAd->CommonCfg.bHTProtect = TRUE;
1621 }
1622 DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection = %s\n", (Value==0) ? "Disable" : "Enable"));
1623 }
1624
1625 if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput))
1626 {
1627 Value = simple_strtol(pValueStr, 0, 10);
1628 if (Value == 0)
1629 {
1630 pAd->CommonCfg.bMIMOPSEnable = FALSE;
1631 }
1632 else
1633 {
1634 pAd->CommonCfg.bMIMOPSEnable = TRUE;
1635 }
1636 DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable = %s\n", (Value==0) ? "Disable" : "Enable"));
1637 }
1638
1639
1640 if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput))
1641 {
1642 Value = simple_strtol(pValueStr, 0, 10);
1643 if (Value > MMPS_ENABLE)
1644 {
1645 pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
1646 }
1647 else
1648 {
1649 //TODO: add mimo power saving mechanism
1650 pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
1651 //pAd->CommonCfg.BACapability.field.MMPSmode = Value;
1652 }
1653 DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode = %d\n", Value));
1654 }
1655
1656 if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput))
1657 {
1658 Value = simple_strtol(pValueStr, 0, 10);
1659 if (Value == 0)
1660 {
1661 pAd->CommonCfg.bBADecline = FALSE;
1662 }
1663 else
1664 {
1665 pAd->CommonCfg.bBADecline = TRUE;
1666 }
1667 DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline = %s\n", (Value==0) ? "Disable" : "Enable"));
1668 }
1669
1670
1671 if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput))
1672 {
1673 Value = simple_strtol(pValueStr, 0, 10);
1674 if (Value == 0)
1675 {
1676 pAd->CommonCfg.bDisableReordering = FALSE;
1677 }
1678 else
1679 {
1680 pAd->CommonCfg.bDisableReordering = TRUE;
1681 }
1682 DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering = %s\n", (Value==0) ? "Disable" : "Enable"));
1683 }
1684
1685 if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput))
1686 {
1687 Value = simple_strtol(pValueStr, 0, 10);
1688 if (Value == 0)
1689 {
1690 pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
1691 }
1692 else
1693 {
1694 pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
1695 }
1696 pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
1697 DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA = %s\n", (Value==0) ? "Disable" : "Enable"));
1698 }
1699
1700 // Tx_+HTC frame
1701 if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput))
1702 {
1703 Value = simple_strtol(pValueStr, 0, 10);
1704 if (Value == 0)
1705 {
1706 pAd->HTCEnable = FALSE;
1707 }
1708 else
1709 {
1710 pAd->HTCEnable = TRUE;
1711 }
1712 DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
1713 }
1714
1715 // Enable HT Link Adaptation Control
1716 if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput))
1717 {
1718 Value = simple_strtol(pValueStr, 0, 10);
1719 if (Value == 0)
1720 {
1721 pAd->bLinkAdapt = FALSE;
1722 }
1723 else
1724 {
1725 pAd->HTCEnable = TRUE;
1726 pAd->bLinkAdapt = TRUE;
1727 }
1728 DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
1729 }
1730
1731 // Reverse Direction Mechanism
1732 if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput))
1733 {
1734 Value = simple_strtol(pValueStr, 0, 10);
1735 if (Value == 0)
1736 {
1737 pAd->CommonCfg.bRdg = FALSE;
1738 }
1739 else
1740 {
1741 pAd->HTCEnable = TRUE;
1742 pAd->CommonCfg.bRdg = TRUE;
1743 }
1744 DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
1745 }
1746
1747
1748
1749
1750 // Tx A-MSUD ?
1751 if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput))
1752 {
1753 Value = simple_strtol(pValueStr, 0, 10);
1754 if (Value == 0)
1755 {
1756 pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
1757 }
1758 else
1759 {
1760 pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
1761 }
1762 DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
1763 }
1764
1765 // MPDU Density
1766 if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput))
1767 {
1768 Value = simple_strtol(pValueStr, 0, 10);
1769 if (Value <=7 && Value >= 0)
1770 {
1771 pAd->CommonCfg.BACapability.field.MpduDensity = Value;
1772 DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", Value));
1773 }
1774 else
1775 {
1776 pAd->CommonCfg.BACapability.field.MpduDensity = 4;
1777 DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
1778 }
1779 }
1780
1781 // Max Rx BA Window Size
1782 if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput))
1783 {
1784 Value = simple_strtol(pValueStr, 0, 10);
1785
1786 if (Value >=1 && Value <= 64)
1787 {
1788 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
1789 pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
1790 DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", Value));
1791 }
1792 else
1793 {
1794 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
1795 pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
1796 DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
1797 }
1798
1799 }
1800
1801 // Guard Interval
1802 if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput))
1803 {
1804 Value = simple_strtol(pValueStr, 0, 10);
1805
1806 if (Value == GI_400)
1807 {
1808 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
1809 }
1810 else
1811 {
1812 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
1813 }
1814
1815 DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
1816 }
1817
1818 // HT Operation Mode : Mixed Mode , Green Field
1819 if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput))
1820 {
1821 Value = simple_strtol(pValueStr, 0, 10);
1822
1823 if (Value == HTMODE_GF)
1824 {
1825
1826 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
1827 }
1828 else
1829 {
1830 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
1831 }
1832
1833 DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
1834 }
1835
1836 // Fixed Tx mode : CCK, OFDM
1837 if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput))
1838 {
1839 UCHAR fix_tx_mode;
1840
1841#ifdef CONFIG_STA_SUPPORT
1842 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1843 {
1844 fix_tx_mode = FIXED_TXMODE_HT;
1845
1846 if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
1847 {
1848 fix_tx_mode = FIXED_TXMODE_OFDM;
1849 }
1850 else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
1851 {
1852 fix_tx_mode = FIXED_TXMODE_CCK;
1853 }
1854 else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
1855 {
1856 fix_tx_mode = FIXED_TXMODE_HT;
1857 }
1858 else
1859 {
1860 Value = simple_strtol(pValueStr, 0, 10);
1861 // 1 : CCK
1862 // 2 : OFDM
1863 // otherwise : HT
1864 if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
1865 fix_tx_mode = Value;
1866 else
1867 fix_tx_mode = FIXED_TXMODE_HT;
1868 }
1869
1870 pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
1871 DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
1872
1873 }
1874#endif // CONFIG_STA_SUPPORT //
1875 }
1876
1877
1878 // Channel Width
1879 if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput))
1880 {
1881 Value = simple_strtol(pValueStr, 0, 10);
1882
1883 if (Value == BW_40)
1884 {
1885 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
1886 }
1887 else
1888 {
1889 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
1890 }
1891
1892#ifdef MCAST_RATE_SPECIFIC
1893 pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
1894#endif // MCAST_RATE_SPECIFIC //
1895
1896 DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
1897 }
1898
1899 if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput))
1900 {
1901 Value = simple_strtol(pValueStr, 0, 10);
1902
1903 if (Value == 0)
1904 {
1905
1906 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
1907 }
1908 else
1909 {
1910 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
1911 }
1912
1913 DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
1914 }
1915
1916 // MSC
1917 if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput))
1918 {
1919
1920#ifdef CONFIG_STA_SUPPORT
1921 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1922 {
1923 Value = simple_strtol(pValueStr, 0, 10);
1924
1925// if ((Value >= 0 && Value <= 15) || (Value == 32))
1926 if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
1927 {
1928 pAd->StaCfg.DesiredTransmitSetting.field.MCS = Value;
1929 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
1930 DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
1931 }
1932 else
1933 {
1934 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
1935 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
1936 DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
1937 }
1938 }
1939#endif // CONFIG_STA_SUPPORT //
1940 }
1941
1942 // STBC
1943 if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput))
1944 {
1945 Value = simple_strtol(pValueStr, 0, 10);
1946 if (Value == STBC_USE)
1947 {
1948 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
1949 }
1950 else
1951 {
1952 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
1953 }
1954 DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
1955 }
1956
1957 // 40_Mhz_Intolerant
1958 if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput))
1959 {
1960 Value = simple_strtol(pValueStr, 0, 10);
1961 if (Value == 0)
1962 {
1963 pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
1964 }
1965 else
1966 {
1967 pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
1968 }
1969 DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
1970 }
1971 //HT_TxStream
1972 if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput))
1973 {
1974 switch (simple_strtol(pValueStr, 0, 10))
1975 {
1976 case 1:
1977 pAd->CommonCfg.TxStream = 1;
1978 break;
1979 case 2:
1980 pAd->CommonCfg.TxStream = 2;
1981 break;
1982 case 3: // 3*3
1983 default:
1984 pAd->CommonCfg.TxStream = 3;
1985
1986 if (pAd->MACVersion < RALINK_2883_VERSION)
1987 pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
1988 break;
1989 }
1990 DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
1991 }
1992 //HT_RxStream
1993 if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput))
1994 {
1995 switch (simple_strtol(pValueStr, 0, 10))
1996 {
1997 case 1:
1998 pAd->CommonCfg.RxStream = 1;
1999 break;
2000 case 2:
2001 pAd->CommonCfg.RxStream = 2;
2002 break;
2003 case 3:
2004 default:
2005 pAd->CommonCfg.RxStream = 3;
2006
2007 if (pAd->MACVersion < RALINK_2883_VERSION)
2008 pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
2009 break;
2010 }
2011 DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
2012 }
2013
2014}
2015#endif // DOT11_N_SUPPORT //
2016
diff --git a/drivers/staging/rt2870/rtmp.h b/drivers/staging/rt2870/rtmp.h
new file mode 100644
index 00000000000..c2a4784ec33
--- /dev/null
+++ b/drivers/staging/rt2870/rtmp.h
@@ -0,0 +1,7586 @@
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
47#ifdef CONFIG_STA_SUPPORT
48#include "aironet.h"
49#endif // CONFIG_STA_SUPPORT //
50
51//#define DBG 1
52
53//#define DBG_DIAGNOSE 1
54
55#if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_STA_SUPPORT)
56#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd) if(_pAd->OpMode == OPMODE_AP)
57#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd) if(_pAd->OpMode == OPMODE_STA)
58#else
59#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd)
60#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd)
61#endif
62
63#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++)
64#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--)
65#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt)
66
67#ifdef RT2870
68////////////////////////////////////////////////////////////////////////////
69// The TX_BUFFER structure forms the transmitted USB packet to the device
70////////////////////////////////////////////////////////////////////////////
71typedef struct __TX_BUFFER{
72 union {
73 UCHAR WirelessPacket[TX_BUFFER_NORMSIZE];
74 HEADER_802_11 NullFrame;
75 PSPOLL_FRAME PsPollPacket;
76 RTS_FRAME RTSFrame;
77 }field;
78 UCHAR Aggregation[4]; //Buffer for save Aggregation size.
79} TX_BUFFER, *PTX_BUFFER;
80
81typedef struct __HTTX_BUFFER{
82 union {
83 UCHAR WirelessPacket[MAX_TXBULK_SIZE];
84 HEADER_802_11 NullFrame;
85 PSPOLL_FRAME PsPollPacket;
86 RTS_FRAME RTSFrame;
87 }field;
88 UCHAR Aggregation[4]; //Buffer for save Aggregation size.
89} HTTX_BUFFER, *PHTTX_BUFFER;
90
91
92// used to track driver-generated write irps
93typedef struct _TX_CONTEXT
94{
95 PVOID pAd; //Initialized in MiniportInitialize
96 PURB pUrb; //Initialized in MiniportInitialize
97 PIRP pIrp; //used to cancel pending bulk out.
98 //Initialized in MiniportInitialize
99 PTX_BUFFER TransferBuffer; //Initialized in MiniportInitialize
100 ULONG BulkOutSize;
101 UCHAR BulkOutPipeId;
102 UCHAR SelfIdx;
103 BOOLEAN InUse;
104 BOOLEAN bWaitingBulkOut; // at least one packet is in this TxContext, ready for making IRP anytime.
105 BOOLEAN bFullForBulkOut; // all tx buffer are full , so waiting for tx bulkout.
106 BOOLEAN IRPPending;
107 BOOLEAN LastOne;
108 BOOLEAN bAggregatible;
109 UCHAR Header_802_3[LENGTH_802_3];
110 UCHAR Rsv[2];
111 ULONG DataOffset;
112 UINT TxRate;
113 dma_addr_t data_dma; // urb dma on linux
114
115} TX_CONTEXT, *PTX_CONTEXT, **PPTX_CONTEXT;
116
117
118// used to track driver-generated write irps
119typedef struct _HT_TX_CONTEXT
120{
121 PVOID pAd; //Initialized in MiniportInitialize
122 PURB pUrb; //Initialized in MiniportInitialize
123 PIRP pIrp; //used to cancel pending bulk out.
124 //Initialized in MiniportInitialize
125 PHTTX_BUFFER TransferBuffer; //Initialized in MiniportInitialize
126 ULONG BulkOutSize; // Indicate the total bulk-out size in bytes in one bulk-transmission
127 UCHAR BulkOutPipeId;
128 BOOLEAN IRPPending;
129 BOOLEAN LastOne;
130 BOOLEAN bCurWriting;
131 BOOLEAN bRingEmpty;
132 BOOLEAN bCopySavePad;
133 UCHAR SavedPad[8];
134 UCHAR Header_802_3[LENGTH_802_3];
135 ULONG CurWritePosition; // Indicate the buffer offset which packet will be inserted start from.
136 ULONG CurWriteRealPos; // Indicate the buffer offset which packet now are writing to.
137 ULONG NextBulkOutPosition; // Indicate the buffer start offset of a bulk-transmission
138 ULONG ENextBulkOutPosition; // Indicate the buffer end offset of a bulk-transmission
139 UINT TxRate;
140 dma_addr_t data_dma; // urb dma on linux
141} HT_TX_CONTEXT, *PHT_TX_CONTEXT, **PPHT_TX_CONTEXT;
142
143
144//
145// Structure to keep track of receive packets and buffers to indicate
146// receive data to the protocol.
147//
148typedef struct _RX_CONTEXT
149{
150 PUCHAR TransferBuffer;
151 PVOID pAd;
152 PIRP pIrp;//used to cancel pending bulk in.
153 PURB pUrb;
154 //These 2 Boolean shouldn't both be 1 at the same time.
155 ULONG BulkInOffset; // number of packets waiting for reordering .
156// BOOLEAN ReorderInUse; // At least one packet in this buffer are in reordering buffer and wait for receive indication
157 BOOLEAN bRxHandling; // Notify this packet is being process now.
158 BOOLEAN InUse; // USB Hardware Occupied. Wait for USB HW to put packet.
159 BOOLEAN Readable; // Receive Complete back. OK for driver to indicate receiving packet.
160 BOOLEAN IRPPending; // TODO: To be removed
161 atomic_t IrpLock;
162 NDIS_SPIN_LOCK RxContextLock;
163 dma_addr_t data_dma; // urb dma on linux
164} RX_CONTEXT, *PRX_CONTEXT;
165#endif // RT2870 //
166
167
168//
169// NDIS Version definitions
170//
171#ifdef NDIS50_MINIPORT
172#define RTMP_NDIS_MAJOR_VERSION 5
173#define RTMP_NDIS_MINOR_VERSION 0
174#endif
175
176#ifdef NDIS51_MINIPORT
177#define RTMP_NDIS_MAJOR_VERSION 5
178#define RTMP_NDIS_MINOR_VERSION 1
179#endif
180
181extern char NIC_VENDOR_DESC[];
182extern int NIC_VENDOR_DESC_LEN;
183
184extern unsigned char SNAP_AIRONET[];
185extern unsigned char CipherSuiteCiscoCCKM[];
186extern unsigned char CipherSuiteCiscoCCKMLen;
187extern unsigned char CipherSuiteCiscoCCKM24[];
188extern unsigned char CipherSuiteCiscoCCKM24Len;
189extern unsigned char CipherSuiteCCXTkip[];
190extern unsigned char CipherSuiteCCXTkipLen;
191extern unsigned char CISCO_OUI[];
192extern UCHAR BaSizeArray[4];
193
194extern UCHAR BROADCAST_ADDR[MAC_ADDR_LEN];
195extern UCHAR MULTICAST_ADDR[MAC_ADDR_LEN];
196extern UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN];
197extern ULONG BIT32[32];
198extern UCHAR BIT8[8];
199extern char* CipherName[];
200extern char* MCSToMbps[];
201extern UCHAR RxwiMCSToOfdmRate[12];
202extern UCHAR SNAP_802_1H[6];
203extern UCHAR SNAP_BRIDGE_TUNNEL[6];
204extern UCHAR SNAP_AIRONET[8];
205extern UCHAR CKIP_LLC_SNAP[8];
206extern UCHAR EAPOL_LLC_SNAP[8];
207extern UCHAR EAPOL[2];
208extern UCHAR IPX[2];
209extern UCHAR APPLE_TALK[2];
210extern UCHAR RateIdToPlcpSignal[12]; // see IEEE802.11a-1999 p.14
211extern UCHAR OfdmRateToRxwiMCS[];
212extern UCHAR OfdmSignalToRateId[16] ;
213extern UCHAR default_cwmin[4];
214extern UCHAR default_cwmax[4];
215extern UCHAR default_sta_aifsn[4];
216extern UCHAR MapUserPriorityToAccessCategory[8];
217
218extern USHORT RateUpPER[];
219extern USHORT RateDownPER[];
220extern UCHAR Phy11BNextRateDownward[];
221extern UCHAR Phy11BNextRateUpward[];
222extern UCHAR Phy11BGNextRateDownward[];
223extern UCHAR Phy11BGNextRateUpward[];
224extern UCHAR Phy11ANextRateDownward[];
225extern UCHAR Phy11ANextRateUpward[];
226extern CHAR RssiSafeLevelForTxRate[];
227extern UCHAR RateIdToMbps[];
228extern USHORT RateIdTo500Kbps[];
229
230extern UCHAR CipherSuiteWpaNoneTkip[];
231extern UCHAR CipherSuiteWpaNoneTkipLen;
232
233extern UCHAR CipherSuiteWpaNoneAes[];
234extern UCHAR CipherSuiteWpaNoneAesLen;
235
236extern UCHAR SsidIe;
237extern UCHAR SupRateIe;
238extern UCHAR ExtRateIe;
239
240#ifdef DOT11_N_SUPPORT
241extern UCHAR HtCapIe;
242extern UCHAR AddHtInfoIe;
243extern UCHAR NewExtChanIe;
244#ifdef DOT11N_DRAFT3
245extern UCHAR ExtHtCapIe;
246#endif // DOT11N_DRAFT3 //
247#endif // DOT11_N_SUPPORT //
248
249extern UCHAR ErpIe;
250extern UCHAR DsIe;
251extern UCHAR TimIe;
252extern UCHAR WpaIe;
253extern UCHAR Wpa2Ie;
254extern UCHAR IbssIe;
255extern UCHAR Ccx2Ie;
256
257extern UCHAR WPA_OUI[];
258extern UCHAR RSN_OUI[];
259extern UCHAR WME_INFO_ELEM[];
260extern UCHAR WME_PARM_ELEM[];
261extern UCHAR Ccx2QosInfo[];
262extern UCHAR Ccx2IeInfo[];
263extern UCHAR RALINK_OUI[];
264extern UCHAR PowerConstraintIE[];
265
266
267extern UCHAR RateSwitchTable[];
268extern UCHAR RateSwitchTable11B[];
269extern UCHAR RateSwitchTable11G[];
270extern UCHAR RateSwitchTable11BG[];
271
272#ifdef DOT11_N_SUPPORT
273extern UCHAR RateSwitchTable11BGN1S[];
274extern UCHAR RateSwitchTable11BGN2S[];
275extern UCHAR RateSwitchTable11BGN2SForABand[];
276extern UCHAR RateSwitchTable11N1S[];
277extern UCHAR RateSwitchTable11N2S[];
278extern UCHAR RateSwitchTable11N2SForABand[];
279
280#ifdef CONFIG_STA_SUPPORT
281extern UCHAR PRE_N_HT_OUI[];
282#endif // CONFIG_STA_SUPPORT //
283#endif // DOT11_N_SUPPORT //
284
285#define MAXSEQ (0xFFF)
286
287#ifdef RALINK_ATE
288typedef struct _ATE_INFO {
289 UCHAR Mode;
290 CHAR TxPower0;
291 CHAR TxPower1;
292 CHAR TxAntennaSel;
293 CHAR RxAntennaSel;
294 TXWI_STRUC TxWI; // TXWI
295 USHORT QID;
296 UCHAR Addr1[MAC_ADDR_LEN];
297 UCHAR Addr2[MAC_ADDR_LEN];
298 UCHAR Addr3[MAC_ADDR_LEN];
299 UCHAR Channel;
300 UINT32 TxLength;
301 UINT32 TxCount;
302 UINT32 TxDoneCount; // Tx DMA Done
303 UINT32 RFFreqOffset;
304 BOOLEAN bRxFer;
305 BOOLEAN bQATxStart; // Have compiled QA in and use it to ATE tx.
306 BOOLEAN bQARxStart; // Have compiled QA in and use it to ATE rx.
307 UINT32 RxTotalCnt;
308 UINT32 RxCntPerSec;
309
310 CHAR LastSNR0; // last received SNR
311 CHAR LastSNR1; // last received SNR for 2nd antenna
312 CHAR LastRssi0; // last received RSSI
313 CHAR LastRssi1; // last received RSSI for 2nd antenna
314 CHAR LastRssi2; // last received RSSI for 3rd antenna
315 CHAR AvgRssi0; // last 8 frames' average RSSI
316 CHAR AvgRssi1; // last 8 frames' average RSSI
317 CHAR AvgRssi2; // last 8 frames' average RSSI
318 SHORT AvgRssi0X8; // sum of last 8 frames' RSSI
319 SHORT AvgRssi1X8; // sum of last 8 frames' RSSI
320 SHORT AvgRssi2X8; // sum of last 8 frames' RSSI
321
322 UINT32 NumOfAvgRssiSample;
323
324#ifdef RALINK_28xx_QA
325 // Tx frame
326#ifdef RT2870
327 /* not used in RT2860 */
328 TXINFO_STRUC TxInfo; // TxInfo
329#endif // RT2870 //
330 USHORT HLen; // Header Length
331 USHORT PLen; // Pattern Length
332 UCHAR Header[32]; // Header buffer
333 UCHAR Pattern[32]; // Pattern buffer
334 USHORT DLen; // Data Length
335 USHORT seq;
336 UINT32 CID;
337 THREAD_PID AtePid;
338 // counters
339 UINT32 U2M;
340 UINT32 OtherData;
341 UINT32 Beacon;
342 UINT32 OtherCount;
343 UINT32 TxAc0;
344 UINT32 TxAc1;
345 UINT32 TxAc2;
346 UINT32 TxAc3;
347 UINT32 TxHCCA;
348 UINT32 TxMgmt;
349 UINT32 RSSI0;
350 UINT32 RSSI1;
351 UINT32 RSSI2;
352 UINT32 SNR0;
353 UINT32 SNR1;
354 // control
355 //UINT32 Repeat; // Tx Cpu count
356 UCHAR TxStatus; // task Tx status // 0 --> task is idle, 1 --> task is running
357#endif // RALINK_28xx_QA //
358} ATE_INFO, *PATE_INFO;
359
360#ifdef RALINK_28xx_QA
361struct ate_racfghdr {
362 UINT32 magic_no;
363 USHORT command_type;
364 USHORT command_id;
365 USHORT length;
366 USHORT sequence;
367 USHORT status;
368 UCHAR data[2046];
369} __attribute__((packed));
370#endif // RALINK_28xx_QA //
371#endif // RALINK_ATE //
372
373#ifdef DOT11_N_SUPPORT
374struct reordering_mpdu
375{
376 struct reordering_mpdu *next;
377 PNDIS_PACKET pPacket; /* coverted to 802.3 frame */
378 int Sequence; /* sequence number of MPDU */
379 BOOLEAN bAMSDU;
380};
381
382struct reordering_list
383{
384 struct reordering_mpdu *next;
385 int qlen;
386};
387
388struct reordering_mpdu_pool
389{
390 PVOID mem;
391 NDIS_SPIN_LOCK lock;
392 struct reordering_list freelist;
393};
394#endif // DOT11_N_SUPPORT //
395
396typedef struct _RSSI_SAMPLE {
397 CHAR LastRssi0; // last received RSSI
398 CHAR LastRssi1; // last received RSSI
399 CHAR LastRssi2; // last received RSSI
400 CHAR AvgRssi0;
401 CHAR AvgRssi1;
402 CHAR AvgRssi2;
403 SHORT AvgRssi0X8;
404 SHORT AvgRssi1X8;
405 SHORT AvgRssi2X8;
406} RSSI_SAMPLE;
407
408//
409// Queue structure and macros
410//
411typedef struct _QUEUE_ENTRY {
412 struct _QUEUE_ENTRY *Next;
413} QUEUE_ENTRY, *PQUEUE_ENTRY;
414
415// Queue structure
416typedef struct _QUEUE_HEADER {
417 PQUEUE_ENTRY Head;
418 PQUEUE_ENTRY Tail;
419 ULONG Number;
420} QUEUE_HEADER, *PQUEUE_HEADER;
421
422#define InitializeQueueHeader(QueueHeader) \
423{ \
424 (QueueHeader)->Head = (QueueHeader)->Tail = NULL; \
425 (QueueHeader)->Number = 0; \
426}
427
428#define RemoveHeadQueue(QueueHeader) \
429(QueueHeader)->Head; \
430{ \
431 PQUEUE_ENTRY pNext; \
432 if ((QueueHeader)->Head != NULL) \
433 { \
434 pNext = (QueueHeader)->Head->Next; \
435 (QueueHeader)->Head = pNext; \
436 if (pNext == NULL) \
437 (QueueHeader)->Tail = NULL; \
438 (QueueHeader)->Number--; \
439 } \
440}
441
442#define InsertHeadQueue(QueueHeader, QueueEntry) \
443{ \
444 ((PQUEUE_ENTRY)QueueEntry)->Next = (QueueHeader)->Head; \
445 (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \
446 if ((QueueHeader)->Tail == NULL) \
447 (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \
448 (QueueHeader)->Number++; \
449}
450
451#define InsertTailQueue(QueueHeader, QueueEntry) \
452{ \
453 ((PQUEUE_ENTRY)QueueEntry)->Next = NULL; \
454 if ((QueueHeader)->Tail) \
455 (QueueHeader)->Tail->Next = (PQUEUE_ENTRY)(QueueEntry); \
456 else \
457 (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \
458 (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \
459 (QueueHeader)->Number++; \
460}
461
462//
463// Macros for flag and ref count operations
464//
465#define RTMP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F))
466#define RTMP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F))
467#define RTMP_CLEAR_FLAGS(_M) ((_M)->Flags = 0)
468#define RTMP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0)
469#define RTMP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F))
470
471#define OPSTATUS_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags |= (_F))
472#define OPSTATUS_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F))
473#define OPSTATUS_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0)
474
475#define CLIENT_STATUS_SET_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags |= (_F))
476#define CLIENT_STATUS_CLEAR_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags &= ~(_F))
477#define CLIENT_STATUS_TEST_FLAG(_pEntry,_F) (((_pEntry)->ClientStatusFlags & (_F)) != 0)
478
479#define RX_FILTER_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter |= (_F))
480#define RX_FILTER_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter &= ~(_F))
481#define RX_FILTER_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.PacketFilter & (_F)) != 0)
482
483#ifdef CONFIG_STA_SUPPORT
484#define STA_NO_SECURITY_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
485#define STA_WEP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
486#define STA_TKIP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
487#define STA_AES_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
488
489#define STA_TGN_WIFI_ON(_p) (_p->StaCfg.bTGnWifiTest == TRUE)
490#endif // CONFIG_STA_SUPPORT //
491
492#define CKIP_KP_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x10) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
493#define CKIP_CMIC_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x08) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
494
495
496#define INC_RING_INDEX(_idx, _RingSize) \
497{ \
498 (_idx) = (_idx+1) % (_RingSize); \
499}
500
501#define IS_RT3070(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
502
503#define RING_PACKET_INIT(_TxRing, _idx) \
504{ \
505 _TxRing->Cell[_idx].pNdisPacket = NULL; \
506 _TxRing->Cell[_idx].pNextNdisPacket = NULL; \
507}
508
509#define TXDT_INIT(_TxD) \
510{ \
511 NdisZeroMemory(_TxD, TXD_SIZE); \
512 _TxD->DMADONE = 1; \
513}
514
515//Set last data segment
516#define RING_SET_LASTDS(_TxD, _IsSD0) \
517{ \
518 if (_IsSD0) {_TxD->LastSec0 = 1;} \
519 else {_TxD->LastSec1 = 1;} \
520}
521
522// Increase TxTsc value for next transmission
523// TODO:
524// When i==6, means TSC has done one full cycle, do re-keying stuff follow specs
525// Should send a special event microsoft defined to request re-key
526#define INC_TX_TSC(_tsc) \
527{ \
528 int i=0; \
529 while (++_tsc[i] == 0x0) \
530 { \
531 i++; \
532 if (i == 6) \
533 break; \
534 } \
535}
536
537#ifdef DOT11_N_SUPPORT
538// StaActive.SupportedHtPhy.MCSSet is copied from AP beacon. Don't need to update here.
539#define COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
540{ \
541 _pAd->StaActive.SupportedHtPhy.ChannelWidth = _pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth; \
542 _pAd->StaActive.SupportedHtPhy.MimoPs = _pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs; \
543 _pAd->StaActive.SupportedHtPhy.GF = _pAd->MlmeAux.HtCapability.HtCapInfo.GF; \
544 _pAd->StaActive.SupportedHtPhy.ShortGIfor20 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20; \
545 _pAd->StaActive.SupportedHtPhy.ShortGIfor40 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40; \
546 _pAd->StaActive.SupportedHtPhy.TxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC; \
547 _pAd->StaActive.SupportedHtPhy.RxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC; \
548 _pAd->StaActive.SupportedHtPhy.ExtChanOffset = _pAd->MlmeAux.AddHtInfo.AddHtInfo.ExtChanOffset; \
549 _pAd->StaActive.SupportedHtPhy.RecomWidth = _pAd->MlmeAux.AddHtInfo.AddHtInfo.RecomWidth; \
550 _pAd->StaActive.SupportedHtPhy.OperaionMode = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode; \
551 _pAd->StaActive.SupportedHtPhy.NonGfPresent = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent; \
552 NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(UCHAR) * 16);\
553}
554
555#define COPY_AP_HTSETTINGS_FROM_BEACON(_pAd, _pHtCapability) \
556{ \
557 _pAd->MacTab.Content[BSSID_WCID].AMsduSize = (UCHAR)(_pHtCapability->HtCapInfo.AMsduSize); \
558 _pAd->MacTab.Content[BSSID_WCID].MmpsMode= (UCHAR)(_pHtCapability->HtCapInfo.MimoPs); \
559 _pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (UCHAR)(_pHtCapability->HtCapParm.MaxRAmpduFactor); \
560}
561#endif // DOT11_N_SUPPORT //
562
563//
564// BBP & RF are using indirect access. Before write any value into it.
565// We have to make sure there is no outstanding command pending via checking busy bit.
566//
567#define MAX_BUSY_COUNT 100 // Number of retry before failing access BBP & RF indirect register
568//
569
570#ifdef RT2870
571#define RTMP_RF_IO_WRITE32(_A, _V) RTUSBWriteRFRegister(_A, _V)
572#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV)
573#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V)
574
575#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V)
576#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV)
577#endif // RT2870 //
578
579#define MAP_CHANNEL_ID_TO_KHZ(ch, khz) { \
580 switch (ch) \
581 { \
582 case 1: khz = 2412000; break; \
583 case 2: khz = 2417000; break; \
584 case 3: khz = 2422000; break; \
585 case 4: khz = 2427000; break; \
586 case 5: khz = 2432000; break; \
587 case 6: khz = 2437000; break; \
588 case 7: khz = 2442000; break; \
589 case 8: khz = 2447000; break; \
590 case 9: khz = 2452000; break; \
591 case 10: khz = 2457000; break; \
592 case 11: khz = 2462000; break; \
593 case 12: khz = 2467000; break; \
594 case 13: khz = 2472000; break; \
595 case 14: khz = 2484000; break; \
596 case 36: /* UNII */ khz = 5180000; break; \
597 case 40: /* UNII */ khz = 5200000; break; \
598 case 44: /* UNII */ khz = 5220000; break; \
599 case 48: /* UNII */ khz = 5240000; break; \
600 case 52: /* UNII */ khz = 5260000; break; \
601 case 56: /* UNII */ khz = 5280000; break; \
602 case 60: /* UNII */ khz = 5300000; break; \
603 case 64: /* UNII */ khz = 5320000; break; \
604 case 149: /* UNII */ khz = 5745000; break; \
605 case 153: /* UNII */ khz = 5765000; break; \
606 case 157: /* UNII */ khz = 5785000; break; \
607 case 161: /* UNII */ khz = 5805000; break; \
608 case 165: /* UNII */ khz = 5825000; break; \
609 case 100: /* HiperLAN2 */ khz = 5500000; break; \
610 case 104: /* HiperLAN2 */ khz = 5520000; break; \
611 case 108: /* HiperLAN2 */ khz = 5540000; break; \
612 case 112: /* HiperLAN2 */ khz = 5560000; break; \
613 case 116: /* HiperLAN2 */ khz = 5580000; break; \
614 case 120: /* HiperLAN2 */ khz = 5600000; break; \
615 case 124: /* HiperLAN2 */ khz = 5620000; break; \
616 case 128: /* HiperLAN2 */ khz = 5640000; break; \
617 case 132: /* HiperLAN2 */ khz = 5660000; break; \
618 case 136: /* HiperLAN2 */ khz = 5680000; break; \
619 case 140: /* HiperLAN2 */ khz = 5700000; break; \
620 case 34: /* Japan MMAC */ khz = 5170000; break; \
621 case 38: /* Japan MMAC */ khz = 5190000; break; \
622 case 42: /* Japan MMAC */ khz = 5210000; break; \
623 case 46: /* Japan MMAC */ khz = 5230000; break; \
624 case 184: /* Japan */ khz = 4920000; break; \
625 case 188: /* Japan */ khz = 4940000; break; \
626 case 192: /* Japan */ khz = 4960000; break; \
627 case 196: /* Japan */ khz = 4980000; break; \
628 case 208: /* Japan, means J08 */ khz = 5040000; break; \
629 case 212: /* Japan, means J12 */ khz = 5060000; break; \
630 case 216: /* Japan, means J16 */ khz = 5080000; break; \
631 default: khz = 2412000; break; \
632 } \
633 }
634
635#define MAP_KHZ_TO_CHANNEL_ID(khz, ch) { \
636 switch (khz) \
637 { \
638 case 2412000: ch = 1; break; \
639 case 2417000: ch = 2; break; \
640 case 2422000: ch = 3; break; \
641 case 2427000: ch = 4; break; \
642 case 2432000: ch = 5; break; \
643 case 2437000: ch = 6; break; \
644 case 2442000: ch = 7; break; \
645 case 2447000: ch = 8; break; \
646 case 2452000: ch = 9; break; \
647 case 2457000: ch = 10; break; \
648 case 2462000: ch = 11; break; \
649 case 2467000: ch = 12; break; \
650 case 2472000: ch = 13; break; \
651 case 2484000: ch = 14; break; \
652 case 5180000: ch = 36; /* UNII */ break; \
653 case 5200000: ch = 40; /* UNII */ break; \
654 case 5220000: ch = 44; /* UNII */ break; \
655 case 5240000: ch = 48; /* UNII */ break; \
656 case 5260000: ch = 52; /* UNII */ break; \
657 case 5280000: ch = 56; /* UNII */ break; \
658 case 5300000: ch = 60; /* UNII */ break; \
659 case 5320000: ch = 64; /* UNII */ break; \
660 case 5745000: ch = 149; /* UNII */ break; \
661 case 5765000: ch = 153; /* UNII */ break; \
662 case 5785000: ch = 157; /* UNII */ break; \
663 case 5805000: ch = 161; /* UNII */ break; \
664 case 5825000: ch = 165; /* UNII */ break; \
665 case 5500000: ch = 100; /* HiperLAN2 */ break; \
666 case 5520000: ch = 104; /* HiperLAN2 */ break; \
667 case 5540000: ch = 108; /* HiperLAN2 */ break; \
668 case 5560000: ch = 112; /* HiperLAN2 */ break; \
669 case 5580000: ch = 116; /* HiperLAN2 */ break; \
670 case 5600000: ch = 120; /* HiperLAN2 */ break; \
671 case 5620000: ch = 124; /* HiperLAN2 */ break; \
672 case 5640000: ch = 128; /* HiperLAN2 */ break; \
673 case 5660000: ch = 132; /* HiperLAN2 */ break; \
674 case 5680000: ch = 136; /* HiperLAN2 */ break; \
675 case 5700000: ch = 140; /* HiperLAN2 */ break; \
676 case 5170000: ch = 34; /* Japan MMAC */ break; \
677 case 5190000: ch = 38; /* Japan MMAC */ break; \
678 case 5210000: ch = 42; /* Japan MMAC */ break; \
679 case 5230000: ch = 46; /* Japan MMAC */ break; \
680 case 4920000: ch = 184; /* Japan */ break; \
681 case 4940000: ch = 188; /* Japan */ break; \
682 case 4960000: ch = 192; /* Japan */ break; \
683 case 4980000: ch = 196; /* Japan */ break; \
684 case 5040000: ch = 208; /* Japan, means J08 */ break; \
685 case 5060000: ch = 212; /* Japan, means J12 */ break; \
686 case 5080000: ch = 216; /* Japan, means J16 */ break; \
687 default: ch = 1; break; \
688 } \
689 }
690
691//
692// Common fragment list structure - Identical to the scatter gather frag list structure
693//
694//#define RTMP_SCATTER_GATHER_ELEMENT SCATTER_GATHER_ELEMENT
695//#define PRTMP_SCATTER_GATHER_ELEMENT PSCATTER_GATHER_ELEMENT
696#define NIC_MAX_PHYS_BUF_COUNT 8
697
698typedef struct _RTMP_SCATTER_GATHER_ELEMENT {
699 PVOID Address;
700 ULONG Length;
701 PULONG Reserved;
702} RTMP_SCATTER_GATHER_ELEMENT, *PRTMP_SCATTER_GATHER_ELEMENT;
703
704
705typedef struct _RTMP_SCATTER_GATHER_LIST {
706 ULONG NumberOfElements;
707 PULONG Reserved;
708 RTMP_SCATTER_GATHER_ELEMENT Elements[NIC_MAX_PHYS_BUF_COUNT];
709} RTMP_SCATTER_GATHER_LIST, *PRTMP_SCATTER_GATHER_LIST;
710
711//
712// Some utility macros
713//
714#ifndef min
715#define min(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
716#endif
717
718#ifndef max
719#define max(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
720#endif
721
722#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))))
723
724#define INC_COUNTER64(Val) (Val.QuadPart++)
725
726#define INFRA_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_INFRA_ON))
727#define ADHOC_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_ADHOC_ON))
728#define MONITOR_ON(_p) (((_p)->StaCfg.BssType) == BSS_MONITOR)
729#define IDLE_ON(_p) (!INFRA_ON(_p) && !ADHOC_ON(_p))
730
731// Check LEAP & CCKM flags
732#define LEAP_ON(_p) (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP)
733#define LEAP_CCKM_ON(_p) ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE))
734
735// if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required
736#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap) \
737{ \
738 if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500) \
739 { \
740 _pExtraLlcSnapEncap = SNAP_802_1H; \
741 if (NdisEqualMemory(IPX, _pBufVA + 12, 2) || \
742 NdisEqualMemory(APPLE_TALK, _pBufVA + 12, 2)) \
743 { \
744 _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \
745 } \
746 } \
747 else \
748 { \
749 _pExtraLlcSnapEncap = NULL; \
750 } \
751}
752
753// New Define for new Tx Path.
754#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(_pBufVA, _pExtraLlcSnapEncap) \
755{ \
756 if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500) \
757 { \
758 _pExtraLlcSnapEncap = SNAP_802_1H; \
759 if (NdisEqualMemory(IPX, _pBufVA, 2) || \
760 NdisEqualMemory(APPLE_TALK, _pBufVA, 2)) \
761 { \
762 _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \
763 } \
764 } \
765 else \
766 { \
767 _pExtraLlcSnapEncap = NULL; \
768 } \
769}
770
771
772#define MAKE_802_3_HEADER(_p, _pMac1, _pMac2, _pType) \
773{ \
774 NdisMoveMemory(_p, _pMac1, MAC_ADDR_LEN); \
775 NdisMoveMemory((_p + MAC_ADDR_LEN), _pMac2, MAC_ADDR_LEN); \
776 NdisMoveMemory((_p + MAC_ADDR_LEN * 2), _pType, LENGTH_802_3_TYPE); \
777}
778
779// if pData has no LLC/SNAP (neither RFC1042 nor Bridge tunnel), keep it that way.
780// else if the received frame is LLC/SNAP-encaped IPX or APPLETALK, preserve the LLC/SNAP field
781// else remove the LLC/SNAP field from the result Ethernet frame
782// Patch for WHQL only, which did not turn on Netbios but use IPX within its payload
783// Note:
784// _pData & _DataSize may be altered (remove 8-byte LLC/SNAP) by this MACRO
785// _pRemovedLLCSNAP: pointer to removed LLC/SNAP; NULL is not removed
786#define CONVERT_TO_802_3(_p8023hdr, _pDA, _pSA, _pData, _DataSize, _pRemovedLLCSNAP) \
787{ \
788 char LLC_Len[2]; \
789 \
790 _pRemovedLLCSNAP = NULL; \
791 if (NdisEqualMemory(SNAP_802_1H, _pData, 6) || \
792 NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6)) \
793 { \
794 PUCHAR pProto = _pData + 6; \
795 \
796 if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) && \
797 NdisEqualMemory(SNAP_802_1H, _pData, 6)) \
798 { \
799 LLC_Len[0] = (UCHAR)(_DataSize / 256); \
800 LLC_Len[1] = (UCHAR)(_DataSize % 256); \
801 MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \
802 } \
803 else \
804 { \
805 MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, pProto); \
806 _pRemovedLLCSNAP = _pData; \
807 _DataSize -= LENGTH_802_1_H; \
808 _pData += LENGTH_802_1_H; \
809 } \
810 } \
811 else \
812 { \
813 LLC_Len[0] = (UCHAR)(_DataSize / 256); \
814 LLC_Len[1] = (UCHAR)(_DataSize % 256); \
815 MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \
816 } \
817}
818
819#define SWITCH_AB( _pAA, _pBB) \
820{ \
821 PVOID pCC; \
822 pCC = _pBB; \
823 _pBB = _pAA; \
824 _pAA = pCC; \
825}
826
827// Enqueue this frame to MLME engine
828// We need to enqueue the whole frame because MLME need to pass data type
829// information from 802.11 header
830#ifdef RT2870
831#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal) \
832{ \
833 UINT32 High32TSF=0, Low32TSF=0; \
834 MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal); \
835}
836#endif // RT2870 //
837
838#define NDIS_QUERY_BUFFER(_NdisBuf, _ppVA, _pBufLen) \
839 NdisQueryBuffer(_NdisBuf, _ppVA, _pBufLen)
840
841#define MAC_ADDR_EQUAL(pAddr1,pAddr2) RTMPEqualMemory((PVOID)(pAddr1), (PVOID)(pAddr2), MAC_ADDR_LEN)
842#define SSID_EQUAL(ssid1, len1, ssid2, len2) ((len1==len2) && (RTMPEqualMemory(ssid1, ssid2, len1)))
843
844//
845// Check if it is Japan W53(ch52,56,60,64) channel.
846//
847#define JapanChannelCheck(channel) ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64))
848
849#ifdef CONFIG_STA_SUPPORT
850#define STA_PORT_SECURED(_pAd) \
851{ \
852 _pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
853 NdisAcquireSpinLock(&_pAd->MacTabLock); \
854 _pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \
855 NdisReleaseSpinLock(&_pAd->MacTabLock); \
856}
857#endif // CONFIG_STA_SUPPORT //
858
859
860//
861// Register set pair for initialzation register set definition
862//
863typedef struct _RTMP_REG_PAIR
864{
865 ULONG Register;
866 ULONG Value;
867} RTMP_REG_PAIR, *PRTMP_REG_PAIR;
868
869typedef struct _REG_PAIR
870{
871 UCHAR Register;
872 UCHAR Value;
873} REG_PAIR, *PREG_PAIR;
874
875//
876// Register set pair for initialzation register set definition
877//
878typedef struct _RTMP_RF_REGS
879{
880 UCHAR Channel;
881 ULONG R1;
882 ULONG R2;
883 ULONG R3;
884 ULONG R4;
885} RTMP_RF_REGS, *PRTMP_RF_REGS;
886
887typedef struct _FREQUENCY_ITEM {
888 UCHAR Channel;
889 UCHAR N;
890 UCHAR R;
891 UCHAR K;
892} FREQUENCY_ITEM, *PFREQUENCY_ITEM;
893
894//
895// Data buffer for DMA operation, the buffer must be contiguous physical memory
896// Both DMA to / from CPU use the same structure.
897//
898typedef struct _RTMP_DMABUF
899{
900 ULONG AllocSize;
901 PVOID AllocVa; // TxBuf virtual address
902 NDIS_PHYSICAL_ADDRESS AllocPa; // TxBuf physical address
903} RTMP_DMABUF, *PRTMP_DMABUF;
904
905
906typedef union _HEADER_802_11_SEQ{
907#ifdef RT_BIG_ENDIAN
908 struct {
909 USHORT Sequence:12;
910 USHORT Frag:4;
911 } field;
912#else
913 struct {
914 USHORT Frag:4;
915 USHORT Sequence:12;
916 } field;
917#endif
918 USHORT value;
919} HEADER_802_11_SEQ, *PHEADER_802_11_SEQ;
920
921//
922// Data buffer for DMA operation, the buffer must be contiguous physical memory
923// Both DMA to / from CPU use the same structure.
924//
925typedef struct _RTMP_REORDERBUF
926{
927 BOOLEAN IsFull;
928 PVOID AllocVa; // TxBuf virtual address
929 UCHAR Header802_3[14];
930 HEADER_802_11_SEQ Sequence; //support compressed bitmap BA, so no consider fragment in BA
931 UCHAR DataOffset;
932 USHORT Datasize;
933 ULONG AllocSize;
934#ifdef RT2870
935 PUCHAR AllocPa;
936#endif // RT2870 //
937} RTMP_REORDERBUF, *PRTMP_REORDERBUF;
938
939//
940// Control block (Descriptor) for all ring descriptor DMA operation, buffer must be
941// contiguous physical memory. NDIS_PACKET stored the binding Rx packet descriptor
942// which won't be released, driver has to wait until upper layer return the packet
943// before giveing up this rx ring descriptor to ASIC. NDIS_BUFFER is assocaited pair
944// to describe the packet buffer. For Tx, NDIS_PACKET stored the tx packet descriptor
945// which driver should ACK upper layer when the tx is physically done or failed.
946//
947typedef struct _RTMP_DMACB
948{
949 ULONG AllocSize; // Control block size
950 PVOID AllocVa; // Control block virtual address
951 NDIS_PHYSICAL_ADDRESS AllocPa; // Control block physical address
952 PNDIS_PACKET pNdisPacket;
953 PNDIS_PACKET pNextNdisPacket;
954
955 RTMP_DMABUF DmaBuf; // Associated DMA buffer structure
956} RTMP_DMACB, *PRTMP_DMACB;
957
958typedef struct _RTMP_TX_BUF
959{
960 PQUEUE_ENTRY Next;
961 UCHAR Index;
962 ULONG AllocSize; // Control block size
963 PVOID AllocVa; // Control block virtual address
964 NDIS_PHYSICAL_ADDRESS AllocPa; // Control block physical address
965} RTMP_TXBUF, *PRTMP_TXBUF;
966
967typedef struct _RTMP_RX_BUF
968{
969 BOOLEAN InUse;
970 ULONG ByBaRecIndex;
971 RTMP_REORDERBUF MAP_RXBuf[MAX_RX_REORDERBUF];
972} RTMP_RXBUF, *PRTMP_RXBUF;
973typedef struct _RTMP_TX_RING
974{
975 RTMP_DMACB Cell[TX_RING_SIZE];
976 UINT32 TxCpuIdx;
977 UINT32 TxDmaIdx;
978 UINT32 TxSwFreeIdx; // software next free tx index
979} RTMP_TX_RING, *PRTMP_TX_RING;
980
981typedef struct _RTMP_RX_RING
982{
983 RTMP_DMACB Cell[RX_RING_SIZE];
984 UINT32 RxCpuIdx;
985 UINT32 RxDmaIdx;
986 INT32 RxSwReadIdx; // software next read index
987} RTMP_RX_RING, *PRTMP_RX_RING;
988
989typedef struct _RTMP_MGMT_RING
990{
991 RTMP_DMACB Cell[MGMT_RING_SIZE];
992 UINT32 TxCpuIdx;
993 UINT32 TxDmaIdx;
994 UINT32 TxSwFreeIdx; // software next free tx index
995} RTMP_MGMT_RING, *PRTMP_MGMT_RING;
996
997//
998// Statistic counter structure
999//
1000typedef struct _COUNTER_802_3
1001{
1002 // General Stats
1003 ULONG GoodTransmits;
1004 ULONG GoodReceives;
1005 ULONG TxErrors;
1006 ULONG RxErrors;
1007 ULONG RxNoBuffer;
1008
1009 // Ethernet Stats
1010 ULONG RcvAlignmentErrors;
1011 ULONG OneCollision;
1012 ULONG MoreCollisions;
1013
1014} COUNTER_802_3, *PCOUNTER_802_3;
1015
1016typedef struct _COUNTER_802_11 {
1017 ULONG Length;
1018 LARGE_INTEGER LastTransmittedFragmentCount;
1019 LARGE_INTEGER TransmittedFragmentCount;
1020 LARGE_INTEGER MulticastTransmittedFrameCount;
1021 LARGE_INTEGER FailedCount;
1022 LARGE_INTEGER RetryCount;
1023 LARGE_INTEGER MultipleRetryCount;
1024 LARGE_INTEGER RTSSuccessCount;
1025 LARGE_INTEGER RTSFailureCount;
1026 LARGE_INTEGER ACKFailureCount;
1027 LARGE_INTEGER FrameDuplicateCount;
1028 LARGE_INTEGER ReceivedFragmentCount;
1029 LARGE_INTEGER MulticastReceivedFrameCount;
1030 LARGE_INTEGER FCSErrorCount;
1031} COUNTER_802_11, *PCOUNTER_802_11;
1032
1033typedef struct _COUNTER_RALINK {
1034 ULONG TransmittedByteCount; // both successful and failure, used to calculate TX throughput
1035 ULONG ReceivedByteCount; // both CRC okay and CRC error, used to calculate RX throughput
1036 ULONG BeenDisassociatedCount;
1037 ULONG BadCQIAutoRecoveryCount;
1038 ULONG PoorCQIRoamingCount;
1039 ULONG MgmtRingFullCount;
1040 ULONG RxCountSinceLastNULL;
1041 ULONG RxCount;
1042 ULONG RxRingErrCount;
1043 ULONG KickTxCount;
1044 ULONG TxRingErrCount;
1045 LARGE_INTEGER RealFcsErrCount;
1046 ULONG PendingNdisPacketCount;
1047
1048 ULONG OneSecOsTxCount[NUM_OF_TX_RING];
1049 ULONG OneSecDmaDoneCount[NUM_OF_TX_RING];
1050 UINT32 OneSecTxDoneCount;
1051 ULONG OneSecRxCount;
1052 UINT32 OneSecTxAggregationCount;
1053 UINT32 OneSecRxAggregationCount;
1054
1055 UINT32 OneSecFrameDuplicateCount;
1056
1057#ifdef RT2870
1058 ULONG OneSecTransmittedByteCount; // both successful and failure, used to calculate TX throughput
1059#endif // RT2870 //
1060
1061 UINT32 OneSecTxNoRetryOkCount;
1062 UINT32 OneSecTxRetryOkCount;
1063 UINT32 OneSecTxFailCount;
1064 UINT32 OneSecFalseCCACnt; // CCA error count, for debug purpose, might move to global counter
1065 UINT32 OneSecRxOkCnt; // RX without error
1066 UINT32 OneSecRxOkDataCnt; // unicast-to-me DATA frame count
1067 UINT32 OneSecRxFcsErrCnt; // CRC error
1068 UINT32 OneSecBeaconSentCnt;
1069 UINT32 LastOneSecTotalTxCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
1070 UINT32 LastOneSecRxOkDataCnt; // OneSecRxOkDataCnt
1071 ULONG DuplicateRcv;
1072 ULONG TxAggCount;
1073 ULONG TxNonAggCount;
1074 ULONG TxAgg1MPDUCount;
1075 ULONG TxAgg2MPDUCount;
1076 ULONG TxAgg3MPDUCount;
1077 ULONG TxAgg4MPDUCount;
1078 ULONG TxAgg5MPDUCount;
1079 ULONG TxAgg6MPDUCount;
1080 ULONG TxAgg7MPDUCount;
1081 ULONG TxAgg8MPDUCount;
1082 ULONG TxAgg9MPDUCount;
1083 ULONG TxAgg10MPDUCount;
1084 ULONG TxAgg11MPDUCount;
1085 ULONG TxAgg12MPDUCount;
1086 ULONG TxAgg13MPDUCount;
1087 ULONG TxAgg14MPDUCount;
1088 ULONG TxAgg15MPDUCount;
1089 ULONG TxAgg16MPDUCount;
1090
1091 LARGE_INTEGER TransmittedOctetsInAMSDU;
1092 LARGE_INTEGER TransmittedAMSDUCount;
1093 LARGE_INTEGER ReceivedOctesInAMSDUCount;
1094 LARGE_INTEGER ReceivedAMSDUCount;
1095 LARGE_INTEGER TransmittedAMPDUCount;
1096 LARGE_INTEGER TransmittedMPDUsInAMPDUCount;
1097 LARGE_INTEGER TransmittedOctetsInAMPDUCount;
1098 LARGE_INTEGER MPDUInReceivedAMPDUCount;
1099} COUNTER_RALINK, *PCOUNTER_RALINK;
1100
1101typedef struct _PID_COUNTER {
1102 ULONG TxAckRequiredCount; // CRC error
1103 ULONG TxAggreCount;
1104 ULONG TxSuccessCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
1105 ULONG LastSuccessRate;
1106} PID_COUNTER, *PPID_COUNTER;
1107
1108typedef struct _COUNTER_DRS {
1109 // to record the each TX rate's quality. 0 is best, the bigger the worse.
1110 USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
1111 UCHAR PER[MAX_STEP_OF_TX_RATE_SWITCH];
1112 UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
1113 ULONG CurrTxRateStableTime; // # of second in current TX rate
1114 BOOLEAN fNoisyEnvironment;
1115 BOOLEAN fLastSecAccordingRSSI;
1116 UCHAR LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
1117 UCHAR LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
1118 ULONG LastTxOkCount;
1119} COUNTER_DRS, *PCOUNTER_DRS;
1120
1121//
1122// Arcfour Structure Added by PaulWu
1123//
1124typedef struct _ARCFOUR
1125{
1126 UINT X;
1127 UINT Y;
1128 UCHAR STATE[256];
1129} ARCFOURCONTEXT, *PARCFOURCONTEXT;
1130
1131// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI too. just copy to TXWI.
1132typedef struct _RECEIVE_SETTING {
1133#ifdef RT_BIG_ENDIAN
1134 USHORT MIMO:1;
1135 USHORT OFDM:1;
1136 USHORT rsv:3;
1137 USHORT STBC:2; //SPACE
1138 USHORT ShortGI:1;
1139 USHORT Mode:2; //channel bandwidth 20MHz or 40 MHz
1140 USHORT NumOfRX:2; // MIMO. WE HAVE 3R
1141#else
1142 USHORT NumOfRX:2; // MIMO. WE HAVE 3R
1143 USHORT Mode:2; //channel bandwidth 20MHz or 40 MHz
1144 USHORT ShortGI:1;
1145 USHORT STBC:2; //SPACE
1146 USHORT rsv:3;
1147 USHORT OFDM:1;
1148 USHORT MIMO:1;
1149#endif
1150 } RECEIVE_SETTING, *PRECEIVE_SETTING;
1151
1152// Shared key data structure
1153typedef struct _WEP_KEY {
1154 UCHAR KeyLen; // Key length for each key, 0: entry is invalid
1155 UCHAR Key[MAX_LEN_OF_KEY]; // right now we implement 4 keys, 128 bits max
1156} WEP_KEY, *PWEP_KEY;
1157
1158typedef struct _CIPHER_KEY {
1159 UCHAR Key[16]; // right now we implement 4 keys, 128 bits max
1160 UCHAR RxMic[8]; // make alignment
1161 UCHAR TxMic[8];
1162 UCHAR TxTsc[6]; // 48bit TSC value
1163 UCHAR RxTsc[6]; // 48bit TSC value
1164 UCHAR CipherAlg; // 0-none, 1:WEP64, 2:WEP128, 3:TKIP, 4:AES, 5:CKIP64, 6:CKIP128
1165 UCHAR KeyLen;
1166#ifdef CONFIG_STA_SUPPORT
1167 UCHAR BssId[6];
1168#endif // CONFIG_STA_SUPPORT //
1169 // Key length for each key, 0: entry is invalid
1170 UCHAR Type; // Indicate Pairwise/Group when reporting MIC error
1171} CIPHER_KEY, *PCIPHER_KEY;
1172
1173typedef struct _BBP_TUNING_STRUCT {
1174 BOOLEAN Enable;
1175 UCHAR FalseCcaCountUpperBound; // 100 per sec
1176 UCHAR FalseCcaCountLowerBound; // 10 per sec
1177 UCHAR R17LowerBound; // specified in E2PROM
1178 UCHAR R17UpperBound; // 0x68 according to David Tung
1179 UCHAR CurrentR17Value;
1180} BBP_TUNING, *PBBP_TUNING;
1181
1182typedef struct _SOFT_RX_ANT_DIVERSITY_STRUCT {
1183 UCHAR EvaluatePeriod; // 0:not evalute status, 1: evaluate status, 2: switching status
1184 UCHAR Pair1PrimaryRxAnt; // 0:Ant-E1, 1:Ant-E2
1185 UCHAR Pair1SecondaryRxAnt; // 0:Ant-E1, 1:Ant-E2
1186 UCHAR Pair2PrimaryRxAnt; // 0:Ant-E3, 1:Ant-E4
1187 UCHAR Pair2SecondaryRxAnt; // 0:Ant-E3, 1:Ant-E4
1188 SHORT Pair1AvgRssi[2]; // AvgRssi[0]:E1, AvgRssi[1]:E2
1189 SHORT Pair2AvgRssi[2]; // AvgRssi[0]:E3, AvgRssi[1]:E4
1190 SHORT Pair1LastAvgRssi; //
1191 SHORT Pair2LastAvgRssi; //
1192 ULONG RcvPktNumWhenEvaluate;
1193 BOOLEAN FirstPktArrivedWhenEvaluate;
1194 RALINK_TIMER_STRUCT RxAntDiversityTimer;
1195} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY;
1196
1197typedef struct _LEAP_AUTH_INFO {
1198 BOOLEAN Enabled; //Ture: Enable LEAP Authentication
1199 BOOLEAN CCKM; //Ture: Use Fast Reauthentication with CCKM
1200 UCHAR Reserve[2];
1201 UCHAR UserName[256]; //LEAP, User name
1202 ULONG UserNameLen;
1203 UCHAR Password[256]; //LEAP, User Password
1204 ULONG PasswordLen;
1205} LEAP_AUTH_INFO, *PLEAP_AUTH_INFO;
1206
1207typedef struct {
1208 UCHAR Addr[MAC_ADDR_LEN];
1209 UCHAR ErrorCode[2]; //00 01-Invalid authentication type
1210 //00 02-Authentication timeout
1211 //00 03-Challenge from AP failed
1212 //00 04-Challenge to AP failed
1213 BOOLEAN Reported;
1214} ROGUEAP_ENTRY, *PROGUEAP_ENTRY;
1215
1216typedef struct {
1217 UCHAR RogueApNr;
1218 ROGUEAP_ENTRY RogueApEntry[MAX_LEN_OF_BSS_TABLE];
1219} ROGUEAP_TABLE, *PROGUEAP_TABLE;
1220
1221typedef struct {
1222 BOOLEAN Enable;
1223 UCHAR Delta;
1224 BOOLEAN PlusSign;
1225} CCK_TX_POWER_CALIBRATE, *PCCK_TX_POWER_CALIBRATE;
1226
1227//
1228// Receive Tuple Cache Format
1229//
1230typedef struct _TUPLE_CACHE {
1231 BOOLEAN Valid;
1232 UCHAR MacAddress[MAC_ADDR_LEN];
1233 USHORT Sequence;
1234 USHORT Frag;
1235} TUPLE_CACHE, *PTUPLE_CACHE;
1236
1237//
1238// Fragment Frame structure
1239//
1240typedef struct _FRAGMENT_FRAME {
1241 PNDIS_PACKET pFragPacket;
1242 ULONG RxSize;
1243 USHORT Sequence;
1244 USHORT LastFrag;
1245 ULONG Flags; // Some extra frame information. bit 0: LLC presented
1246} FRAGMENT_FRAME, *PFRAGMENT_FRAME;
1247
1248
1249//
1250// Packet information for NdisQueryPacket
1251//
1252typedef struct _PACKET_INFO {
1253 UINT PhysicalBufferCount; // Physical breaks of buffer descripor chained
1254 UINT BufferCount ; // Number of Buffer descriptor chained
1255 UINT TotalPacketLength ; // Self explained
1256 PNDIS_BUFFER pFirstBuffer; // Pointer to first buffer descriptor
1257} PACKET_INFO, *PPACKET_INFO;
1258
1259//
1260// Tkip Key structure which RC4 key & MIC calculation
1261//
1262typedef struct _TKIP_KEY_INFO {
1263 UINT nBytesInM; // # bytes in M for MICKEY
1264 ULONG IV16;
1265 ULONG IV32;
1266 ULONG K0; // for MICKEY Low
1267 ULONG K1; // for MICKEY Hig
1268 ULONG L; // Current state for MICKEY
1269 ULONG R; // Current state for MICKEY
1270 ULONG M; // Message accumulator for MICKEY
1271 UCHAR RC4KEY[16];
1272 UCHAR MIC[8];
1273} TKIP_KEY_INFO, *PTKIP_KEY_INFO;
1274
1275//
1276// Private / Misc data, counters for driver internal use
1277//
1278typedef struct __PRIVATE_STRUC {
1279 UINT SystemResetCnt; // System reset counter
1280 UINT TxRingFullCnt; // Tx ring full occurrance number
1281 UINT PhyRxErrCnt; // PHY Rx error count, for debug purpose, might move to global counter
1282 // Variables for WEP encryption / decryption in rtmp_wep.c
1283 UINT FCSCRC32;
1284 ARCFOURCONTEXT WEPCONTEXT;
1285 // Tkip stuff
1286 TKIP_KEY_INFO Tx;
1287 TKIP_KEY_INFO Rx;
1288} PRIVATE_STRUC, *PPRIVATE_STRUC;
1289
1290// structure to tune BBP R66 (BBP TUNING)
1291typedef struct _BBP_R66_TUNING {
1292 BOOLEAN bEnable;
1293 USHORT FalseCcaLowerThreshold; // default 100
1294 USHORT FalseCcaUpperThreshold; // default 512
1295 UCHAR R66Delta;
1296 UCHAR R66CurrentValue;
1297 BOOLEAN R66LowerUpperSelect; //Before LinkUp, Used LowerBound or UpperBound as R66 value.
1298} BBP_R66_TUNING, *PBBP_R66_TUNING;
1299
1300// structure to store channel TX power
1301typedef struct _CHANNEL_TX_POWER {
1302 USHORT RemainingTimeForUse; //unit: sec
1303 UCHAR Channel;
1304#ifdef DOT11N_DRAFT3
1305 BOOLEAN bEffectedChannel; // For BW 40 operating in 2.4GHz , the "effected channel" is the channel that is covered in 40Mhz.
1306#endif // DOT11N_DRAFT3 //
1307 CHAR Power;
1308 CHAR Power2;
1309 UCHAR MaxTxPwr;
1310 UCHAR DfsReq;
1311} CHANNEL_TX_POWER, *PCHANNEL_TX_POWER;
1312
1313// structure to store 802.11j channel TX power
1314typedef struct _CHANNEL_11J_TX_POWER {
1315 UCHAR Channel;
1316 UCHAR BW; // BW_10 or BW_20
1317 CHAR Power;
1318 CHAR Power2;
1319 USHORT RemainingTimeForUse; //unit: sec
1320} CHANNEL_11J_TX_POWER, *PCHANNEL_11J_TX_POWER;
1321
1322typedef enum _ABGBAND_STATE_ {
1323 UNKNOWN_BAND,
1324 BG_BAND,
1325 A_BAND,
1326} ABGBAND_STATE;
1327
1328typedef struct _MLME_STRUCT {
1329#ifdef CONFIG_STA_SUPPORT
1330 // STA state machines
1331 STATE_MACHINE CntlMachine;
1332 STATE_MACHINE AssocMachine;
1333 STATE_MACHINE AuthMachine;
1334 STATE_MACHINE AuthRspMachine;
1335 STATE_MACHINE SyncMachine;
1336 STATE_MACHINE WpaPskMachine;
1337 STATE_MACHINE LeapMachine;
1338 STATE_MACHINE AironetMachine;
1339 STATE_MACHINE_FUNC AssocFunc[ASSOC_FUNC_SIZE];
1340 STATE_MACHINE_FUNC AuthFunc[AUTH_FUNC_SIZE];
1341 STATE_MACHINE_FUNC AuthRspFunc[AUTH_RSP_FUNC_SIZE];
1342 STATE_MACHINE_FUNC SyncFunc[SYNC_FUNC_SIZE];
1343 STATE_MACHINE_FUNC WpaPskFunc[WPA_PSK_FUNC_SIZE];
1344 STATE_MACHINE_FUNC AironetFunc[AIRONET_FUNC_SIZE];
1345#endif // CONFIG_STA_SUPPORT //
1346 STATE_MACHINE_FUNC ActFunc[ACT_FUNC_SIZE];
1347 // Action
1348 STATE_MACHINE ActMachine;
1349
1350
1351#ifdef QOS_DLS_SUPPORT
1352 STATE_MACHINE DlsMachine;
1353 STATE_MACHINE_FUNC DlsFunc[DLS_FUNC_SIZE];
1354#endif // QOS_DLS_SUPPORT //
1355
1356
1357
1358
1359 ULONG ChannelQuality; // 0..100, Channel Quality Indication for Roaming
1360 ULONG Now32; // latch the value of NdisGetSystemUpTime()
1361 ULONG LastSendNULLpsmTime;
1362
1363 BOOLEAN bRunning;
1364 NDIS_SPIN_LOCK TaskLock;
1365 MLME_QUEUE Queue;
1366
1367 UINT ShiftReg;
1368
1369 RALINK_TIMER_STRUCT PeriodicTimer;
1370 RALINK_TIMER_STRUCT APSDPeriodicTimer;
1371 RALINK_TIMER_STRUCT LinkDownTimer;
1372 RALINK_TIMER_STRUCT LinkUpTimer;
1373 ULONG PeriodicRound;
1374 ULONG OneSecPeriodicRound;
1375
1376 UCHAR RealRxPath;
1377 BOOLEAN bLowThroughput;
1378 BOOLEAN bEnableAutoAntennaCheck;
1379 RALINK_TIMER_STRUCT RxAntEvalTimer;
1380
1381#ifdef RT2870
1382 UCHAR CaliBW40RfR24;
1383 UCHAR CaliBW20RfR24;
1384#endif // RT2870 //
1385
1386} MLME_STRUCT, *PMLME_STRUCT;
1387
1388// structure for radar detection and channel switch
1389typedef struct _RADAR_DETECT_STRUCT {
1390 //BOOLEAN IEEE80211H; // 0: disable, 1: enable IEEE802.11h
1391 UCHAR CSCount; //Channel switch counter
1392 UCHAR CSPeriod; //Channel switch period (beacon count)
1393 UCHAR RDCount; //Radar detection counter
1394 UCHAR RDMode; //Radar Detection mode
1395 UCHAR RDDurRegion; //Radar detection duration region
1396 UCHAR BBPR16;
1397 UCHAR BBPR17;
1398 UCHAR BBPR18;
1399 UCHAR BBPR21;
1400 UCHAR BBPR22;
1401 UCHAR BBPR64;
1402 ULONG InServiceMonitorCount; // unit: sec
1403 UINT8 DfsSessionTime;
1404 BOOLEAN bFastDfs;
1405 UINT8 ChMovingTime;
1406 UINT8 LongPulseRadarTh;
1407} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT;
1408
1409#ifdef CARRIER_DETECTION_SUPPORT
1410typedef enum CD_STATE_n
1411{
1412 CD_NORMAL,
1413 CD_SILENCE,
1414 CD_MAX_STATE
1415} CD_STATE;
1416
1417typedef struct CARRIER_DETECTION_s
1418{
1419 BOOLEAN Enable;
1420 UINT8 CDSessionTime;
1421 UINT8 CDPeriod;
1422 CD_STATE CD_State;
1423} CARRIER_DETECTION, *PCARRIER_DETECTION;
1424#endif // CARRIER_DETECTION_SUPPORT //
1425
1426typedef enum _REC_BLOCKACK_STATUS
1427{
1428 Recipient_NONE=0,
1429 Recipient_USED,
1430 Recipient_HandleRes,
1431 Recipient_Accept
1432} REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS;
1433
1434typedef enum _ORI_BLOCKACK_STATUS
1435{
1436 Originator_NONE=0,
1437 Originator_USED,
1438 Originator_WaitRes,
1439 Originator_Done
1440} ORI_BLOCKACK_STATUS, *PORI_BLOCKACK_STATUS;
1441
1442#ifdef DOT11_N_SUPPORT
1443typedef struct _BA_ORI_ENTRY{
1444 UCHAR Wcid;
1445 UCHAR TID;
1446 UCHAR BAWinSize;
1447 UCHAR Token;
1448// Sequence is to fill every outgoing QoS DATA frame's sequence field in 802.11 header.
1449 USHORT Sequence;
1450 USHORT TimeOutValue;
1451 ORI_BLOCKACK_STATUS ORI_BA_Status;
1452 RALINK_TIMER_STRUCT ORIBATimer;
1453 PVOID pAdapter;
1454} BA_ORI_ENTRY, *PBA_ORI_ENTRY;
1455
1456typedef struct _BA_REC_ENTRY {
1457 UCHAR Wcid;
1458 UCHAR TID;
1459 UCHAR BAWinSize; // 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU.
1460 //UCHAR NumOfRxPkt;
1461 //UCHAR Curindidx; // the head in the RX reordering buffer
1462 USHORT LastIndSeq;
1463// USHORT LastIndSeqAtTimer;
1464 USHORT TimeOutValue;
1465 RALINK_TIMER_STRUCT RECBATimer;
1466 ULONG LastIndSeqAtTimer;
1467 ULONG nDropPacket;
1468 ULONG rcvSeq;
1469 REC_BLOCKACK_STATUS REC_BA_Status;
1470// UCHAR RxBufIdxUsed;
1471 // corresponding virtual address for RX reordering packet storage.
1472 //RTMP_REORDERDMABUF MAP_RXBuf[MAX_RX_REORDERBUF];
1473 NDIS_SPIN_LOCK RxReRingLock; // Rx Ring spinlock
1474// struct _BA_REC_ENTRY *pNext;
1475 PVOID pAdapter;
1476 struct reordering_list list;
1477} BA_REC_ENTRY, *PBA_REC_ENTRY;
1478
1479
1480typedef struct {
1481 ULONG numAsRecipient; // I am recipient of numAsRecipient clients. These client are in the BARecEntry[]
1482 ULONG numAsOriginator; // I am originator of numAsOriginator clients. These clients are in the BAOriEntry[]
1483 BA_ORI_ENTRY BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE];
1484 BA_REC_ENTRY BARecEntry[MAX_LEN_OF_BA_REC_TABLE];
1485} BA_TABLE, *PBA_TABLE;
1486
1487//For QureyBATableOID use;
1488typedef struct PACKED _OID_BA_REC_ENTRY{
1489 UCHAR MACAddr[MAC_ADDR_LEN];
1490 UCHAR BaBitmap; // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize
1491 UCHAR rsv;
1492 UCHAR BufSize[8];
1493 REC_BLOCKACK_STATUS REC_BA_Status[8];
1494} OID_BA_REC_ENTRY, *POID_BA_REC_ENTRY;
1495
1496//For QureyBATableOID use;
1497typedef struct PACKED _OID_BA_ORI_ENTRY{
1498 UCHAR MACAddr[MAC_ADDR_LEN];
1499 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
1500 UCHAR rsv;
1501 UCHAR BufSize[8];
1502 ORI_BLOCKACK_STATUS ORI_BA_Status[8];
1503} OID_BA_ORI_ENTRY, *POID_BA_ORI_ENTRY;
1504
1505typedef struct _QUERYBA_TABLE{
1506 OID_BA_ORI_ENTRY BAOriEntry[32];
1507 OID_BA_REC_ENTRY BARecEntry[32];
1508 UCHAR OriNum;// Number of below BAOriEntry
1509 UCHAR RecNum;// Number of below BARecEntry
1510} QUERYBA_TABLE, *PQUERYBA_TABLE;
1511
1512typedef union _BACAP_STRUC {
1513#ifdef RT_BIG_ENDIAN
1514 struct {
1515 UINT32 :4;
1516 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.
1517 UINT32 bHtAdhoc:1; // adhoc can use ht rate.
1518 UINT32 MMPSmode:2; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
1519 UINT32 AmsduSize:1; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
1520 UINT32 AmsduEnable:1; //Enable AMSDU transmisstion
1521 UINT32 MpduDensity:3;
1522 UINT32 Policy:2; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use
1523 UINT32 AutoBA:1; // automatically BA
1524 UINT32 TxBAWinLimit:8;
1525 UINT32 RxBAWinLimit:8;
1526 } field;
1527#else
1528 struct {
1529 UINT32 RxBAWinLimit:8;
1530 UINT32 TxBAWinLimit:8;
1531 UINT32 AutoBA:1; // automatically BA
1532 UINT32 Policy:2; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use
1533 UINT32 MpduDensity:3;
1534 UINT32 AmsduEnable:1; //Enable AMSDU transmisstion
1535 UINT32 AmsduSize:1; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
1536 UINT32 MMPSmode:2; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
1537 UINT32 bHtAdhoc:1; // adhoc can use ht rate.
1538 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.
1539 UINT32 :4;
1540 } field;
1541#endif
1542 UINT32 word;
1543} BACAP_STRUC, *PBACAP_STRUC;
1544#endif // DOT11_N_SUPPORT //
1545
1546//This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second. (Details see MLMEPeriodic)
1547typedef struct _IOT_STRUC {
1548 UCHAR Threshold[2];
1549 UCHAR ReorderTimeOutNum[MAX_LEN_OF_BA_REC_TABLE]; // compare with threshold[0]
1550 UCHAR RefreshNum[MAX_LEN_OF_BA_REC_TABLE]; // compare with threshold[1]
1551 ULONG OneSecInWindowCount;
1552 ULONG OneSecFrameDuplicateCount;
1553 ULONG OneSecOutWindowCount;
1554 UCHAR DelOriAct;
1555 UCHAR DelRecAct;
1556 UCHAR RTSShortProt;
1557 UCHAR RTSLongProt;
1558 BOOLEAN bRTSLongProtOn;
1559#ifdef CONFIG_STA_SUPPORT
1560 BOOLEAN bLastAtheros;
1561 BOOLEAN bCurrentAtheros;
1562 BOOLEAN bNowAtherosBurstOn;
1563 BOOLEAN bNextDisableRxBA;
1564 BOOLEAN bToggle;
1565#endif // CONFIG_STA_SUPPORT //
1566} IOT_STRUC, *PIOT_STRUC;
1567
1568// This is the registry setting for 802.11n transmit setting. Used in advanced page.
1569typedef union _REG_TRANSMIT_SETTING {
1570#ifdef RT_BIG_ENDIAN
1571 struct {
1572 UINT32 rsv:13;
1573 UINT32 EXTCHA:2;
1574 UINT32 HTMODE:1;
1575 UINT32 TRANSNO:2;
1576 UINT32 STBC:1; //SPACE
1577 UINT32 ShortGI:1;
1578 UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
1579 UINT32 TxBF:1; // 3*3
1580 UINT32 rsv0:10;
1581 //UINT32 MCS:7; // MCS
1582 //UINT32 PhyMode:4;
1583 } field;
1584#else
1585 struct {
1586 //UINT32 PhyMode:4;
1587 //UINT32 MCS:7; // MCS
1588 UINT32 rsv0:10;
1589 UINT32 TxBF:1;
1590 UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
1591 UINT32 ShortGI:1;
1592 UINT32 STBC:1; //SPACE
1593 UINT32 TRANSNO:2;
1594 UINT32 HTMODE:1;
1595 UINT32 EXTCHA:2;
1596 UINT32 rsv:13;
1597 } field;
1598#endif
1599 UINT32 word;
1600} REG_TRANSMIT_SETTING, *PREG_TRANSMIT_SETTING;
1601
1602typedef union _DESIRED_TRANSMIT_SETTING {
1603#ifdef RT_BIG_ENDIAN
1604 struct {
1605 USHORT rsv:3;
1606 USHORT FixedTxMode:2; // If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
1607 USHORT PhyMode:4;
1608 USHORT MCS:7; // MCS
1609 } field;
1610#else
1611 struct {
1612 USHORT MCS:7; // MCS
1613 USHORT PhyMode:4;
1614 USHORT FixedTxMode:2; // If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
1615 USHORT rsv:3;
1616 } field;
1617#endif
1618 USHORT word;
1619 } DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING;
1620
1621typedef struct {
1622 BOOLEAN IsRecipient;
1623 UCHAR MACAddr[MAC_ADDR_LEN];
1624 UCHAR TID;
1625 UCHAR nMSDU;
1626 USHORT TimeOut;
1627 BOOLEAN bAllTid; // If True, delete all TID for BA sessions with this MACaddr.
1628} OID_ADD_BA_ENTRY, *POID_ADD_BA_ENTRY;
1629
1630//
1631// Multiple SSID structure
1632//
1633#define WLAN_MAX_NUM_OF_TIM ((MAX_LEN_OF_MAC_TABLE >> 3) + 1) /* /8 + 1 */
1634#define WLAN_CT_TIM_BCMC_OFFSET 0 /* unit: 32B */
1635
1636/* clear bcmc TIM bit */
1637#define WLAN_MR_TIM_BCMC_CLEAR(apidx) \
1638 pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] &= ~BIT8[0];
1639
1640/* set bcmc TIM bit */
1641#define WLAN_MR_TIM_BCMC_SET(apidx) \
1642 pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] |= BIT8[0];
1643
1644/* clear a station PS TIM bit */
1645#define WLAN_MR_TIM_BIT_CLEAR(ad_p, apidx, wcid) \
1646 { UCHAR tim_offset = wcid >> 3; \
1647 UCHAR bit_offset = wcid & 0x7; \
1648 ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] &= (~BIT8[bit_offset]); }
1649
1650/* set a station PS TIM bit */
1651#define WLAN_MR_TIM_BIT_SET(ad_p, apidx, wcid) \
1652 { UCHAR tim_offset = wcid >> 3; \
1653 UCHAR bit_offset = wcid & 0x7; \
1654 ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] |= BIT8[bit_offset]; }
1655
1656#ifdef RT2870
1657#define BEACON_BITMAP_MASK 0xff
1658typedef struct _BEACON_SYNC_STRUCT_
1659{
1660 UCHAR BeaconBuf[HW_BEACON_MAX_COUNT][HW_BEACON_OFFSET];
1661 UCHAR BeaconTxWI[HW_BEACON_MAX_COUNT][TXWI_SIZE];
1662 ULONG TimIELocationInBeacon[HW_BEACON_MAX_COUNT];
1663 ULONG CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT];
1664 BOOLEAN EnableBeacon; // trigger to enable beacon transmission.
1665 UCHAR BeaconBitMap; // NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change.
1666 UCHAR DtimBitOn; // NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change.
1667}BEACON_SYNC_STRUCT;
1668#endif // RT2870 //
1669
1670typedef struct _MULTISSID_STRUCT {
1671 UCHAR Bssid[MAC_ADDR_LEN];
1672 UCHAR SsidLen;
1673 CHAR Ssid[MAX_LEN_OF_SSID];
1674 USHORT CapabilityInfo;
1675
1676 PNET_DEV MSSIDDev;
1677
1678 NDIS_802_11_AUTHENTICATION_MODE AuthMode;
1679 NDIS_802_11_WEP_STATUS WepStatus;
1680 NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
1681 WPA_MIX_PAIR_CIPHER WpaMixPairCipher;
1682
1683 ULONG TxCount;
1684 ULONG RxCount;
1685 ULONG ReceivedByteCount;
1686 ULONG TransmittedByteCount;
1687 ULONG RxErrorCount;
1688 ULONG RxDropCount;
1689
1690 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
1691 RT_HT_PHY_INFO DesiredHtPhyInfo;
1692 DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting. this is for reading registry setting only. not useful.
1693 BOOLEAN bAutoTxRateSwitch;
1694
1695 //CIPHER_KEY SharedKey[SHARE_KEY_NUM]; // ref pAd->SharedKey[BSS][4]
1696 UCHAR DefaultKeyId;
1697
1698 UCHAR TxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11, ...
1699 UCHAR DesiredRates[MAX_LEN_OF_SUPPORTED_RATES];// OID_802_11_DESIRED_RATES
1700 UCHAR DesiredRatesIndex;
1701 UCHAR MaxTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
1702
1703// ULONG TimBitmap; // bit0 for broadcast, 1 for AID1, 2 for AID2, ...so on
1704// ULONG TimBitmap2; // b0 for AID32, b1 for AID33, ... and so on
1705 UCHAR TimBitmaps[WLAN_MAX_NUM_OF_TIM];
1706
1707 // WPA
1708 UCHAR GMK[32];
1709 UCHAR PMK[32];
1710 UCHAR GTK[32];
1711 BOOLEAN IEEE8021X;
1712 BOOLEAN PreAuth;
1713 UCHAR GNonce[32];
1714 UCHAR PortSecured;
1715 NDIS_802_11_PRIVACY_FILTER PrivacyFilter;
1716 UCHAR BANClass3Data;
1717 ULONG IsolateInterStaTraffic;
1718
1719 UCHAR RSNIE_Len[2];
1720 UCHAR RSN_IE[2][MAX_LEN_OF_RSNIE];
1721
1722
1723 UCHAR TimIELocationInBeacon;
1724 UCHAR CapabilityInfoLocationInBeacon;
1725 // outgoing BEACON frame buffer and corresponding TXWI
1726 // PTXWI_STRUC BeaconTxWI; //
1727 CHAR BeaconBuf[MAX_BEACON_SIZE]; // NOTE: BeaconBuf should be 4-byte aligned
1728
1729 BOOLEAN bHideSsid;
1730 UINT16 StationKeepAliveTime; // unit: second
1731
1732 USHORT VLAN_VID;
1733 USHORT VLAN_Priority;
1734
1735 RT_802_11_ACL AccessControlList;
1736
1737 // EDCA Qos
1738 BOOLEAN bWmmCapable; // 0:disable WMM, 1:enable WMM
1739 BOOLEAN bDLSCapable; // 0:disable DLS, 1:enable DLS
1740
1741 UCHAR DlsPTK[64]; // Due to windows dirver count on meetinghouse to handle 4-way shake
1742
1743 // For 802.1x daemon setting per BSS
1744 UCHAR radius_srv_num;
1745 RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM];
1746
1747#ifdef RTL865X_SOC
1748 unsigned int mylinkid;
1749#endif
1750
1751
1752 UINT32 RcvdConflictSsidCount;
1753 UINT32 RcvdSpoofedAssocRespCount;
1754 UINT32 RcvdSpoofedReassocRespCount;
1755 UINT32 RcvdSpoofedProbeRespCount;
1756 UINT32 RcvdSpoofedBeaconCount;
1757 UINT32 RcvdSpoofedDisassocCount;
1758 UINT32 RcvdSpoofedAuthCount;
1759 UINT32 RcvdSpoofedDeauthCount;
1760 UINT32 RcvdSpoofedUnknownMgmtCount;
1761 UINT32 RcvdReplayAttackCount;
1762
1763 CHAR RssiOfRcvdConflictSsid;
1764 CHAR RssiOfRcvdSpoofedAssocResp;
1765 CHAR RssiOfRcvdSpoofedReassocResp;
1766 CHAR RssiOfRcvdSpoofedProbeResp;
1767 CHAR RssiOfRcvdSpoofedBeacon;
1768 CHAR RssiOfRcvdSpoofedDisassoc;
1769 CHAR RssiOfRcvdSpoofedAuth;
1770 CHAR RssiOfRcvdSpoofedDeauth;
1771 CHAR RssiOfRcvdSpoofedUnknownMgmt;
1772 CHAR RssiOfRcvdReplayAttack;
1773
1774 BOOLEAN bBcnSntReq;
1775 UCHAR BcnBufIdx;
1776} MULTISSID_STRUCT, *PMULTISSID_STRUCT;
1777
1778
1779
1780#ifdef DOT11N_DRAFT3
1781typedef enum _BSS2040COEXIST_FLAG{
1782 BSS_2040_COEXIST_DISABLE = 0,
1783 BSS_2040_COEXIST_TIMER_FIRED = 1,
1784 BSS_2040_COEXIST_INFO_SYNC = 2,
1785 BSS_2040_COEXIST_INFO_NOTIFY = 4,
1786}BSS2040COEXIST_FLAG;
1787#endif // DOT11N_DRAFT3 //
1788
1789// configuration common to OPMODE_AP as well as OPMODE_STA
1790typedef struct _COMMON_CONFIG {
1791
1792 BOOLEAN bCountryFlag;
1793 UCHAR CountryCode[3];
1794 UCHAR Geography;
1795 UCHAR CountryRegion; // Enum of country region, 0:FCC, 1:IC, 2:ETSI, 3:SPAIN, 4:France, 5:MKK, 6:MKK1, 7:Israel
1796 UCHAR CountryRegionForABand; // Enum of country region for A band
1797 UCHAR PhyMode; // PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED
1798 USHORT Dsifs; // in units of usec
1799 ULONG PacketFilter; // Packet filter for receiving
1800
1801 CHAR Ssid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
1802 UCHAR SsidLen; // the actual ssid length in used
1803 UCHAR LastSsidLen; // the actual ssid length in used
1804 CHAR LastSsid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
1805 UCHAR LastBssid[MAC_ADDR_LEN];
1806
1807 UCHAR Bssid[MAC_ADDR_LEN];
1808 USHORT BeaconPeriod;
1809 UCHAR Channel;
1810 UCHAR CentralChannel; // Central Channel when using 40MHz is indicating. not real channel.
1811
1812#if 0 // move to STA_ADMIN_CONFIG
1813 UCHAR DefaultKeyId;
1814
1815 NDIS_802_11_PRIVACY_FILTER PrivacyFilter; // PrivacyFilter enum for 802.1X
1816 NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
1817 NDIS_802_11_WEP_STATUS WepStatus;
1818 NDIS_802_11_WEP_STATUS OrigWepStatus; // Original wep status set from OID
1819
1820 // Add to support different cipher suite for WPA2/WPA mode
1821 NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Multicast cipher suite
1822 NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher suite
1823 BOOLEAN bMixCipher; // Indicate current Pair & Group use different cipher suites
1824 USHORT RsnCapability;
1825
1826 NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
1827#endif
1828
1829 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
1830 UCHAR SupRateLen;
1831 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1832 UCHAR ExtRateLen;
1833 UCHAR DesireRate[MAX_LEN_OF_SUPPORTED_RATES]; // OID_802_11_DESIRED_RATES
1834 UCHAR MaxDesiredRate;
1835 UCHAR ExpectedACKRate[MAX_LEN_OF_SUPPORTED_RATES];
1836
1837 ULONG BasicRateBitmap; // backup basic ratebitmap
1838
1839 BOOLEAN bAPSDCapable;
1840 BOOLEAN bInServicePeriod;
1841 BOOLEAN bAPSDAC_BE;
1842 BOOLEAN bAPSDAC_BK;
1843 BOOLEAN bAPSDAC_VI;
1844 BOOLEAN bAPSDAC_VO;
1845 BOOLEAN bNeedSendTriggerFrame;
1846 BOOLEAN bAPSDForcePowerSave; // Force power save mode, should only use in APSD-STAUT
1847 ULONG TriggerTimerCount;
1848 UCHAR MaxSPLength;
1849 UCHAR BBPCurrentBW; // BW_10, BW_20, BW_40
1850 // move to MULTISSID_STRUCT for MBSS
1851 //HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
1852 REG_TRANSMIT_SETTING RegTransmitSetting; //registry transmit setting. this is for reading registry setting only. not useful.
1853 //UCHAR FixedTxMode; // Fixed Tx Mode (CCK, OFDM), for HT fixed tx mode (GF, MIX) , refer to RegTransmitSetting.field.HTMode
1854 UCHAR TxRate; // Same value to fill in TXD. TxRate is 6-bit
1855 UCHAR MaxTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
1856 UCHAR TxRateIndex; // Tx rate index in RateSwitchTable
1857 UCHAR TxRateTableSize; // Valid Tx rate table size in RateSwitchTable
1858 //BOOLEAN bAutoTxRateSwitch;
1859 UCHAR MinTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
1860 UCHAR RtsRate; // RATE_xxx
1861 HTTRANSMIT_SETTING MlmeTransmit; // MGMT frame PHY rate setting when operatin at Ht rate.
1862 UCHAR MlmeRate; // RATE_xxx, used to send MLME frames
1863 UCHAR BasicMlmeRate; // Default Rate for sending MLME frames
1864
1865 USHORT RtsThreshold; // in unit of BYTE
1866 USHORT FragmentThreshold; // in unit of BYTE
1867
1868 UCHAR TxPower; // in unit of mW
1869 ULONG TxPowerPercentage; // 0~100 %
1870 ULONG TxPowerDefault; // keep for TxPowerPercentage
1871
1872#ifdef DOT11_N_SUPPORT
1873 BACAP_STRUC BACapability; // NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0
1874 BACAP_STRUC REGBACapability; // NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0
1875#endif // DOT11_N_SUPPORT //
1876 IOT_STRUC IOTestParm; // 802.11n InterOpbility Test Parameter;
1877 ULONG TxPreamble; // Rt802_11PreambleLong, Rt802_11PreambleShort, Rt802_11PreambleAuto
1878 BOOLEAN bUseZeroToDisableFragment; // Microsoft use 0 as disable
1879 ULONG UseBGProtection; // 0: auto, 1: always use, 2: always not use
1880 BOOLEAN bUseShortSlotTime; // 0: disable, 1 - use short slot (9us)
1881 BOOLEAN bEnableTxBurst; // 1: enble TX PACKET BURST, 0: disable TX PACKET BURST
1882 BOOLEAN bAggregationCapable; // 1: enable TX aggregation when the peer supports it
1883 BOOLEAN bPiggyBackCapable; // 1: enable TX piggy-back according MAC's version
1884 BOOLEAN bIEEE80211H; // 1: enable IEEE802.11h spec.
1885 ULONG DisableOLBCDetect; // 0: enable OLBC detect; 1 disable OLBC detect
1886
1887#ifdef DOT11_N_SUPPORT
1888 BOOLEAN bRdg;
1889#endif // DOT11_N_SUPPORT //
1890 BOOLEAN bWmmCapable; // 0:disable WMM, 1:enable WMM
1891 QOS_CAPABILITY_PARM APQosCapability; // QOS capability of the current associated AP
1892 EDCA_PARM APEdcaParm; // EDCA parameters of the current associated AP
1893 QBSS_LOAD_PARM APQbssLoad; // QBSS load of the current associated AP
1894 UCHAR AckPolicy[4]; // ACK policy of the specified AC. see ACK_xxx
1895#ifdef CONFIG_STA_SUPPORT
1896 BOOLEAN bDLSCapable; // 0:disable DLS, 1:enable DLS
1897#endif // CONFIG_STA_SUPPORT //
1898 // a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
1899 // BOOLEAN control, either ON or OFF. These flags should always be accessed via
1900 // OPSTATUS_TEST_FLAG(), OPSTATUS_SET_FLAG(), OP_STATUS_CLEAR_FLAG() macros.
1901 // see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition
1902 ULONG OpStatusFlags;
1903
1904 BOOLEAN NdisRadioStateOff; //For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff.
1905 ABGBAND_STATE BandState; // For setting BBP used on B/G or A mode.
1906
1907 // IEEE802.11H--DFS.
1908 RADAR_DETECT_STRUCT RadarDetect;
1909
1910#ifdef CARRIER_DETECTION_SUPPORT
1911 CARRIER_DETECTION CarrierDetect;
1912#endif // CARRIER_DETECTION_SUPPORT //
1913
1914#ifdef DOT11_N_SUPPORT
1915 // HT
1916 UCHAR BASize; // USer desired BAWindowSize. Should not exceed our max capability
1917 //RT_HT_CAPABILITY SupportedHtPhy;
1918 RT_HT_CAPABILITY DesiredHtPhy;
1919 HT_CAPABILITY_IE HtCapability;
1920 ADD_HT_INFO_IE AddHTInfo; // Useful as AP.
1921 //This IE is used with channel switch announcement element when changing to a new 40MHz.
1922 //This IE is included in channel switch ammouncement frames 7.4.1.5, beacons, probe Rsp.
1923 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
1924
1925#ifdef DOT11N_DRAFT3
1926 UCHAR Bss2040CoexistFlag; // bit 0: bBssCoexistTimerRunning, bit 1: NeedSyncAddHtInfo.
1927 RALINK_TIMER_STRUCT Bss2040CoexistTimer;
1928
1929 //This IE is used for 20/40 BSS Coexistence.
1930 BSS_2040_COEXIST_IE BSS2040CoexistInfo;
1931 // ====== 11n D3.0 =======================>
1932 USHORT Dot11OBssScanPassiveDwell; // Unit : TU. 5~1000
1933 USHORT Dot11OBssScanActiveDwell; // Unit : TU. 10~1000
1934 USHORT Dot11BssWidthTriggerScanInt; // Unit : Second
1935 USHORT Dot11OBssScanPassiveTotalPerChannel; // Unit : TU. 200~10000
1936 USHORT Dot11OBssScanActiveTotalPerChannel; // Unit : TU. 20~10000
1937 USHORT Dot11BssWidthChanTranDelayFactor;
1938 USHORT Dot11OBssScanActivityThre; // Unit : percentage
1939
1940 ULONG Dot11BssWidthChanTranDelay; // multiple of (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
1941 ULONG CountDownCtr; // CountDown Counter from (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
1942
1943 NDIS_SPIN_LOCK TriggerEventTabLock;
1944 BSS_2040_COEXIST_IE LastBSSCoexist2040;
1945 BSS_2040_COEXIST_IE BSSCoexist2040;
1946 TRIGGER_EVENT_TAB TriggerEventTab;
1947 UCHAR ChannelListIdx;
1948 // <====== 11n D3.0 =======================
1949 BOOLEAN bOverlapScanning;
1950#endif // DOT11N_DRAFT3 //
1951
1952 BOOLEAN bHTProtect;
1953 BOOLEAN bMIMOPSEnable;
1954 BOOLEAN bBADecline;
1955 BOOLEAN bDisableReordering;
1956 BOOLEAN bForty_Mhz_Intolerant;
1957 BOOLEAN bExtChannelSwitchAnnouncement;
1958 BOOLEAN bRcvBSSWidthTriggerEvents;
1959 ULONG LastRcvBSSWidthTriggerEventsTime;
1960
1961 UCHAR TxBASize;
1962#endif // DOT11_N_SUPPORT //
1963
1964 // Enable wireless event
1965 BOOLEAN bWirelessEvent;
1966 BOOLEAN bWiFiTest; // Enable this parameter for WiFi test
1967
1968 // Tx & Rx Stream number selection
1969 UCHAR TxStream;
1970 UCHAR RxStream;
1971
1972 // transmit phy mode, trasmit rate for Multicast.
1973#ifdef MCAST_RATE_SPECIFIC
1974 UCHAR McastTransmitMcs;
1975 UCHAR McastTransmitPhyMode;
1976#endif // MCAST_RATE_SPECIFIC //
1977
1978 BOOLEAN bHardwareRadio; // Hardware controlled Radio enabled
1979
1980#ifdef RT2870
1981 BOOLEAN bMultipleIRP; // Multiple Bulk IN flag
1982 UCHAR NumOfBulkInIRP; // if bMultipleIRP == TRUE, NumOfBulkInIRP will be 4 otherwise be 1
1983 RT_HT_CAPABILITY SupportedHtPhy;
1984 ULONG MaxPktOneTxBulk;
1985 UCHAR TxBulkFactor;
1986 UCHAR RxBulkFactor;
1987
1988 BEACON_SYNC_STRUCT *pBeaconSync;
1989 RALINK_TIMER_STRUCT BeaconUpdateTimer;
1990 UINT32 BeaconAdjust;
1991 UINT32 BeaconFactor;
1992 UINT32 BeaconRemain;
1993#endif // RT2870 //
1994
1995
1996 NDIS_SPIN_LOCK MeasureReqTabLock;
1997 PMEASURE_REQ_TAB pMeasureReqTab;
1998
1999 NDIS_SPIN_LOCK TpcReqTabLock;
2000 PTPC_REQ_TAB pTpcReqTab;
2001
2002 // transmit phy mode, trasmit rate for Multicast.
2003#ifdef MCAST_RATE_SPECIFIC
2004 HTTRANSMIT_SETTING MCastPhyMode;
2005#endif // MCAST_RATE_SPECIFIC //
2006
2007#ifdef SINGLE_SKU
2008 UINT16 DefineMaxTxPwr;
2009#endif // SINGLE_SKU //
2010
2011
2012} COMMON_CONFIG, *PCOMMON_CONFIG;
2013
2014
2015#ifdef CONFIG_STA_SUPPORT
2016/* Modified by Wu Xi-Kun 4/21/2006 */
2017// STA configuration and status
2018typedef struct _STA_ADMIN_CONFIG {
2019 // GROUP 1 -
2020 // User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
2021 // the user intended configuration, but not necessary fully equal to the final
2022 // settings in ACTIVE BSS after negotiation/compromize with the BSS holder (either
2023 // AP or IBSS holder).
2024 // Once initialized, user configuration can only be changed via OID_xxx
2025 UCHAR BssType; // BSS_INFRA or BSS_ADHOC
2026 USHORT AtimWin; // used when starting a new IBSS
2027
2028 // GROUP 2 -
2029 // User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
2030 // the user intended configuration, and should be always applied to the final
2031 // settings in ACTIVE BSS without compromising with the BSS holder.
2032 // Once initialized, user configuration can only be changed via OID_xxx
2033 UCHAR RssiTrigger;
2034 UCHAR RssiTriggerMode; // RSSI_TRIGGERED_UPON_BELOW_THRESHOLD or RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD
2035 USHORT DefaultListenCount; // default listen count;
2036 ULONG WindowsPowerMode; // Power mode for AC power
2037 ULONG WindowsBatteryPowerMode; // Power mode for battery if exists
2038 BOOLEAN bWindowsACCAMEnable; // Enable CAM power mode when AC on
2039 BOOLEAN bAutoReconnect; // Set to TRUE when setting OID_802_11_SSID with no matching BSSID
2040 ULONG WindowsPowerProfile; // Windows power profile, for NDIS5.1 PnP
2041
2042 // MIB:ieee802dot11.dot11smt(1).dot11StationConfigTable(1)
2043 USHORT Psm; // power management mode (PWR_ACTIVE|PWR_SAVE)
2044 USHORT DisassocReason;
2045 UCHAR DisassocSta[MAC_ADDR_LEN];
2046 USHORT DeauthReason;
2047 UCHAR DeauthSta[MAC_ADDR_LEN];
2048 USHORT AuthFailReason;
2049 UCHAR AuthFailSta[MAC_ADDR_LEN];
2050
2051 NDIS_802_11_PRIVACY_FILTER PrivacyFilter; // PrivacyFilter enum for 802.1X
2052 NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
2053 NDIS_802_11_WEP_STATUS WepStatus;
2054 NDIS_802_11_WEP_STATUS OrigWepStatus; // Original wep status set from OID
2055
2056 // Add to support different cipher suite for WPA2/WPA mode
2057 NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Multicast cipher suite
2058 NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher suite
2059 BOOLEAN bMixCipher; // Indicate current Pair & Group use different cipher suites
2060 USHORT RsnCapability;
2061
2062 NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
2063
2064 UCHAR PMK[32]; // WPA PSK mode PMK
2065 UCHAR PTK[64]; // WPA PSK mode PTK
2066 UCHAR GTK[32]; // GTK from authenticator
2067 BSSID_INFO SavedPMK[PMKID_NO];
2068 UINT SavedPMKNum; // Saved PMKID number
2069
2070 UCHAR DefaultKeyId;
2071
2072
2073 // WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
2074 UCHAR PortSecured;
2075
2076 // For WPA countermeasures
2077 ULONG LastMicErrorTime; // record last MIC error time
2078 ULONG MicErrCnt; // Should be 0, 1, 2, then reset to zero (after disassoiciation).
2079 BOOLEAN bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred.
2080 // For WPA-PSK supplicant state
2081 WPA_STATE WpaState; // Default is SS_NOTUSE and handled by microsoft 802.1x
2082 UCHAR ReplayCounter[8];
2083 UCHAR ANonce[32]; // ANonce for WPA-PSK from aurhenticator
2084 UCHAR SNonce[32]; // SNonce for WPA-PSK
2085
2086 UCHAR LastSNR0; // last received BEACON's SNR
2087 UCHAR LastSNR1; // last received BEACON's SNR for 2nd antenna
2088 RSSI_SAMPLE RssiSample;
2089 ULONG NumOfAvgRssiSample;
2090
2091 ULONG LastBeaconRxTime; // OS's timestamp of the last BEACON RX time
2092 ULONG Last11bBeaconRxTime; // OS's timestamp of the last 11B BEACON RX time
2093 ULONG Last11gBeaconRxTime; // OS's timestamp of the last 11G BEACON RX time
2094 ULONG Last20NBeaconRxTime; // OS's timestamp of the last 20MHz N BEACON RX time
2095
2096 ULONG LastScanTime; // Record last scan time for issue BSSID_SCAN_LIST
2097 ULONG ScanCnt; // Scan counts since most recent SSID, BSSID, SCAN OID request
2098 BOOLEAN bSwRadio; // Software controlled Radio On/Off, TRUE: On
2099 BOOLEAN bHwRadio; // Hardware controlled Radio On/Off, TRUE: On
2100 BOOLEAN bRadio; // Radio state, And of Sw & Hw radio state
2101 BOOLEAN bHardwareRadio; // Hardware controlled Radio enabled
2102 BOOLEAN bShowHiddenSSID; // Show all known SSID in SSID list get operation
2103
2104
2105 // New for WPA, windows want us to to keep association information and
2106 // Fixed IEs from last association response
2107 NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo;
2108 USHORT ReqVarIELen; // Length of next VIE include EID & Length
2109 UCHAR ReqVarIEs[MAX_VIE_LEN]; // The content saved here should be little-endian format.
2110 USHORT ResVarIELen; // Length of next VIE include EID & Length
2111 UCHAR ResVarIEs[MAX_VIE_LEN];
2112
2113 UCHAR RSNIE_Len;
2114 UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; // The content saved here should be little-endian format.
2115
2116 // New variables used for CCX 1.0
2117 BOOLEAN bCkipOn;
2118 BOOLEAN bCkipCmicOn;
2119 UCHAR CkipFlag;
2120 UCHAR GIV[3]; //for CCX iv
2121 UCHAR RxSEQ[4];
2122 UCHAR TxSEQ[4];
2123 UCHAR CKIPMIC[4];
2124 UCHAR LeapAuthMode;
2125 LEAP_AUTH_INFO LeapAuthInfo;
2126 UCHAR HashPwd[16];
2127 UCHAR NetworkChallenge[8];
2128 UCHAR NetworkChallengeResponse[24];
2129 UCHAR PeerChallenge[8];
2130
2131 UCHAR PeerChallengeResponse[24];
2132 UCHAR SessionKey[16]; //Network session keys (NSK)
2133 RALINK_TIMER_STRUCT LeapAuthTimer;
2134 ROGUEAP_TABLE RogueApTab; //Cisco CCX1 Rogue AP Detection
2135
2136 // New control flags for CCX
2137 CCX_CONTROL CCXControl; // Master administration state
2138 BOOLEAN CCXEnable; // Actual CCX state
2139 UCHAR CCXScanChannel; // Selected channel for CCX beacon request
2140 USHORT CCXScanTime; // Time out to wait for beacon and probe response
2141 UCHAR CCXReqType; // Current processing CCX request type
2142 BSS_TABLE CCXBssTab; // BSS Table
2143 UCHAR FrameReportBuf[2048]; // Buffer for creating frame report
2144 USHORT FrameReportLen; // Current Frame report length
2145 ULONG CLBusyBytes; // Save the total bytes received durning channel load scan time
2146 USHORT RPIDensity[8]; // Array for RPI density collection
2147 // Start address of each BSS table within FrameReportBuf
2148 // It's important to update the RxPower of the corresponding Bss
2149 USHORT BssReportOffset[MAX_LEN_OF_BSS_TABLE];
2150 USHORT BeaconToken; // Token for beacon report
2151 ULONG LastBssIndex; // Most current reported Bss index
2152 RM_REQUEST_ACTION MeasurementRequest[16]; // Saved measurement request
2153 UCHAR RMReqCnt; // Number of measurement request saved.
2154 UCHAR CurrentRMReqIdx; // Number of measurement request saved.
2155 BOOLEAN ParallelReq; // Parallel measurement, only one request performed,
2156 // It must be the same channel with maximum duration
2157 USHORT ParallelDuration; // Maximum duration for parallel measurement
2158 UCHAR ParallelChannel; // Only one channel with parallel measurement
2159 USHORT IAPPToken; // IAPP dialog token
2160 UCHAR CCXQosECWMin; // Cisco QOS ECWMin for AC 0
2161 UCHAR CCXQosECWMax; // Cisco QOS ECWMax for AC 0
2162 // Hack for channel load and noise histogram parameters
2163 UCHAR NHFactor; // Parameter for Noise histogram
2164 UCHAR CLFactor; // Parameter for channel load
2165
2166 UCHAR KRK[16]; //Key Refresh Key.
2167 UCHAR BTK[32]; //Base Transient Key
2168 BOOLEAN CCKMLinkUpFlag;
2169 ULONG CCKMRN; //(Re)Association request number.
2170 LARGE_INTEGER CCKMBeaconAtJoinTimeStamp; //TSF timer for Re-assocaite to the new AP
2171 UCHAR AironetCellPowerLimit; //in dBm
2172 UCHAR AironetIPAddress[4]; //eg. 192.168.1.1
2173 BOOLEAN CCXAdjacentAPReportFlag; //flag for determining report Assoc Lost time
2174 CHAR CCXAdjacentAPSsid[MAX_LEN_OF_SSID]; //Adjacent AP's SSID report
2175 UCHAR CCXAdjacentAPSsidLen; // the actual ssid length in used
2176 UCHAR CCXAdjacentAPBssid[MAC_ADDR_LEN]; //Adjacent AP's BSSID report
2177 USHORT CCXAdjacentAPChannel;
2178 ULONG CCXAdjacentAPLinkDownTime; //for Spec S32.
2179
2180 RALINK_TIMER_STRUCT StaQuickResponeForRateUpTimer;
2181 BOOLEAN StaQuickResponeForRateUpTimerRunning;
2182
2183 UCHAR DtimCount; // 0.. DtimPeriod-1
2184 UCHAR DtimPeriod; // default = 3
2185
2186#ifdef QOS_DLS_SUPPORT
2187 RT_802_11_DLS DLSEntry[MAX_NUM_OF_DLS_ENTRY];
2188 UCHAR DlsReplayCounter[8];
2189#endif // QOS_DLS_SUPPORT //
2190 ////////////////////////////////////////////////////////////////////////////////////////
2191 // This is only for WHQL test.
2192 BOOLEAN WhqlTest;
2193 ////////////////////////////////////////////////////////////////////////////////////////
2194
2195 RALINK_TIMER_STRUCT WpaDisassocAndBlockAssocTimer;
2196 // Fast Roaming
2197 BOOLEAN bFastRoaming; // 0:disable fast roaming, 1:enable fast roaming
2198 CHAR dBmToRoam; // the condition to roam when receiving Rssi less than this value. It's negative value.
2199
2200#ifdef WPA_SUPPLICANT_SUPPORT
2201 BOOLEAN IEEE8021X;
2202 BOOLEAN IEEE8021x_required_keys;
2203 CIPHER_KEY DesireSharedKey[4]; // Record user desired WEP keys
2204 UCHAR DesireSharedKeyId;
2205
2206 // 0: driver ignores wpa_supplicant
2207 // 1: wpa_supplicant initiates scanning and AP selection
2208 // 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters
2209 UCHAR WpaSupplicantUP;
2210 UCHAR WpaSupplicantScanCount;
2211#endif // WPA_SUPPLICANT_SUPPORT //
2212
2213 CHAR dev_name[16];
2214 USHORT OriDevType;
2215
2216 BOOLEAN bTGnWifiTest;
2217 BOOLEAN bScanReqIsFromWebUI;
2218
2219 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
2220 DESIRED_TRANSMIT_SETTING DesiredTransmitSetting;
2221 RT_HT_PHY_INFO DesiredHtPhyInfo;
2222 BOOLEAN bAutoTxRateSwitch;
2223
2224
2225#ifdef EXT_BUILD_CHANNEL_LIST
2226 UCHAR IEEE80211dClientMode;
2227 UCHAR StaOriCountryCode[3];
2228 UCHAR StaOriGeography;
2229#endif // EXT_BUILD_CHANNEL_LIST //
2230} STA_ADMIN_CONFIG, *PSTA_ADMIN_CONFIG;
2231
2232// This data structure keep the current active BSS/IBSS's configuration that this STA
2233// had agreed upon joining the network. Which means these parameters are usually decided
2234// by the BSS/IBSS creator instead of user configuration. Data in this data structurre
2235// is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE.
2236// Normally, after SCAN or failed roaming attempts, we need to recover back to
2237// the current active settings.
2238typedef struct _STA_ACTIVE_CONFIG {
2239 USHORT Aid;
2240 USHORT AtimWin; // in kusec; IBSS parameter set element
2241 USHORT CapabilityInfo;
2242 USHORT CfpMaxDuration;
2243 USHORT CfpPeriod;
2244
2245 // Copy supported rate from desired AP's beacon. We are trying to match
2246 // AP's supported and extended rate settings.
2247 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2248 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2249 UCHAR SupRateLen;
2250 UCHAR ExtRateLen;
2251 // Copy supported ht from desired AP's beacon. We are trying to match
2252 RT_HT_PHY_INFO SupportedPhyInfo;
2253 RT_HT_CAPABILITY SupportedHtPhy;
2254} STA_ACTIVE_CONFIG, *PSTA_ACTIVE_CONFIG;
2255
2256#ifdef RT2870
2257// for USB interface, avoid in interrupt when write key
2258typedef struct RT_ADD_PAIRWISE_KEY_ENTRY {
2259 NDIS_802_11_MAC_ADDRESS MacAddr;
2260 USHORT MacTabMatchWCID; // ASIC
2261 CIPHER_KEY CipherKey;
2262} RT_ADD_PAIRWISE_KEY_ENTRY,*PRT_ADD_PAIRWISE_KEY_ENTRY;
2263#endif // RT2870 //
2264#endif // CONFIG_STA_SUPPORT //
2265
2266// ----------- start of AP --------------------------
2267// AUTH-RSP State Machine Aux data structure
2268typedef struct _AP_MLME_AUX {
2269 UCHAR Addr[MAC_ADDR_LEN];
2270 USHORT Alg;
2271 CHAR Challenge[CIPHER_TEXT_LEN];
2272} AP_MLME_AUX, *PAP_MLME_AUX;
2273
2274// structure to define WPA Group Key Rekey Interval
2275typedef struct PACKED _RT_802_11_WPA_REKEY {
2276 ULONG ReKeyMethod; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
2277 ULONG ReKeyInterval; // time-based: seconds, packet-based: kilo-packets
2278} RT_WPA_REKEY,*PRT_WPA_REKEY, RT_802_11_WPA_REKEY, *PRT_802_11_WPA_REKEY;
2279
2280typedef struct _MAC_TABLE_ENTRY {
2281 //Choose 1 from ValidAsWDS and ValidAsCLI to validize.
2282 BOOLEAN ValidAsCLI; // Sta mode, set this TRUE after Linkup,too.
2283 BOOLEAN ValidAsWDS; // This is WDS Entry. only for AP mode.
2284 BOOLEAN ValidAsApCli; //This is a AP-Client entry, only for AP mode which enable AP-Client functions.
2285 BOOLEAN ValidAsMesh;
2286 BOOLEAN ValidAsDls; // This is DLS Entry. only for STA mode.
2287 BOOLEAN isCached;
2288 BOOLEAN bIAmBadAtheros; // Flag if this is Atheros chip that has IOT problem. We need to turn on RTS/CTS protection.
2289
2290 UCHAR EnqueueEapolStartTimerRunning; // Enqueue EAPoL-Start for triggering EAP SM
2291 //jan for wpa
2292 // record which entry revoke MIC Failure , if it leaves the BSS itself, AP won't update aMICFailTime MIB
2293 UCHAR CMTimerRunning;
2294 UCHAR apidx; // MBSS number
2295 UCHAR RSNIE_Len;
2296 UCHAR RSN_IE[MAX_LEN_OF_RSNIE];
2297 UCHAR ANonce[LEN_KEY_DESC_NONCE];
2298 UCHAR R_Counter[LEN_KEY_DESC_REPLAY];
2299 UCHAR PTK[64];
2300 UCHAR ReTryCounter;
2301 RALINK_TIMER_STRUCT RetryTimer;
2302 RALINK_TIMER_STRUCT EnqueueStartForPSKTimer; // A timer which enqueue EAPoL-Start for triggering PSK SM
2303 NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
2304 NDIS_802_11_WEP_STATUS WepStatus;
2305 AP_WPA_STATE WpaState;
2306 GTK_STATE GTKState;
2307 USHORT PortSecured;
2308 NDIS_802_11_PRIVACY_FILTER PrivacyFilter; // PrivacyFilter enum for 802.1X
2309 CIPHER_KEY PairwiseKey;
2310 PVOID pAd;
2311 INT PMKID_CacheIdx;
2312 UCHAR PMKID[LEN_PMKID];
2313
2314
2315 UCHAR Addr[MAC_ADDR_LEN];
2316 UCHAR PsMode;
2317 SST Sst;
2318 AUTH_STATE AuthState; // for SHARED KEY authentication state machine used only
2319 BOOLEAN IsReassocSta; // Indicate whether this is a reassociation procedure
2320 USHORT Aid;
2321 USHORT CapabilityInfo;
2322 UCHAR LastRssi;
2323 ULONG NoDataIdleCount;
2324 UINT16 StationKeepAliveCount; // unit: second
2325 ULONG PsQIdleCount;
2326 QUEUE_HEADER PsQueue;
2327
2328 UINT32 StaConnectTime; // the live time of this station since associated with AP
2329
2330
2331#ifdef DOT11_N_SUPPORT
2332 BOOLEAN bSendBAR;
2333 USHORT NoBADataCountDown;
2334
2335 UINT32 CachedBuf[16]; // UINT (4 bytes) for alignment
2336 UINT TxBFCount; // 3*3
2337#endif // DOT11_N_SUPPORT //
2338 UINT FIFOCount;
2339 UINT DebugFIFOCount;
2340 UINT DebugTxCount;
2341 BOOLEAN bDlsInit;
2342
2343
2344//====================================================
2345//WDS entry needs these
2346// rt2860 add this. if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab
2347 UINT MatchWDSTabIdx;
2348 UCHAR MaxSupportedRate;
2349 UCHAR CurrTxRate;
2350 UCHAR CurrTxRateIndex;
2351 // to record the each TX rate's quality. 0 is best, the bigger the worse.
2352 USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
2353// USHORT OneSecTxOkCount;
2354 UINT32 OneSecTxNoRetryOkCount;
2355 UINT32 OneSecTxRetryOkCount;
2356 UINT32 OneSecTxFailCount;
2357 UINT32 ContinueTxFailCnt;
2358 UINT32 CurrTxRateStableTime; // # of second in current TX rate
2359 UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
2360//====================================================
2361
2362
2363
2364#ifdef CONFIG_STA_SUPPORT
2365#ifdef QOS_DLS_SUPPORT
2366 UINT MatchDlsEntryIdx; // indicate the index in pAd->StaCfg.DLSEntry
2367#endif // QOS_DLS_SUPPORT //
2368#endif // CONFIG_STA_SUPPORT //
2369
2370 BOOLEAN fNoisyEnvironment;
2371 BOOLEAN fLastSecAccordingRSSI;
2372 UCHAR LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
2373 CHAR LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
2374 ULONG LastTxOkCount;
2375 UCHAR PER[MAX_STEP_OF_TX_RATE_SWITCH];
2376
2377 // a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
2378 // BOOLEAN control, either ON or OFF. These flags should always be accessed via
2379 // CLIENT_STATUS_TEST_FLAG(), CLIENT_STATUS_SET_FLAG(), CLIENT_STATUS_CLEAR_FLAG() macros.
2380 // see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition. fCLIENT_STATUS_AMSDU_INUSED
2381 ULONG ClientStatusFlags;
2382
2383 // TODO: Shall we move that to DOT11_N_SUPPORT???
2384 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
2385
2386#ifdef DOT11_N_SUPPORT
2387 // HT EWC MIMO-N used parameters
2388 USHORT RXBAbitmap; // fill to on-chip RXWI_BA_BITMASK in 8.1.3RX attribute entry format
2389 USHORT TXBAbitmap; // This bitmap as originator, only keep in software used to mark AMPDU bit in TXWI
2390 USHORT TXAutoBAbitmap;
2391 USHORT BADeclineBitmap;
2392 USHORT BARecWcidArray[NUM_OF_TID]; // The mapping wcid of recipient session. if RXBAbitmap bit is masked
2393 USHORT BAOriWcidArray[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
2394 USHORT BAOriSequence[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
2395
2396 // 802.11n features.
2397 UCHAR MpduDensity;
2398 UCHAR MaxRAmpduFactor;
2399 UCHAR AMsduSize;
2400 UCHAR MmpsMode; // MIMO power save more.
2401
2402 HT_CAPABILITY_IE HTCapability;
2403
2404#ifdef DOT11N_DRAFT3
2405 UCHAR BSS2040CoexistenceMgmtSupport;
2406#endif // DOT11N_DRAFT3 //
2407#endif // DOT11_N_SUPPORT //
2408
2409 BOOLEAN bAutoTxRateSwitch;
2410
2411 UCHAR RateLen;
2412 struct _MAC_TABLE_ENTRY *pNext;
2413 USHORT TxSeq[NUM_OF_TID];
2414 USHORT NonQosDataSeq;
2415
2416 RSSI_SAMPLE RssiSample;
2417
2418 UINT32 TXMCSExpected[16];
2419 UINT32 TXMCSSuccessful[16];
2420 UINT32 TXMCSFailed[16];
2421 UINT32 TXMCSAutoFallBack[16][16];
2422
2423#ifdef CONFIG_STA_SUPPORT
2424 ULONG LastBeaconRxTime;
2425#endif // CONFIG_STA_SUPPORT //
2426} MAC_TABLE_ENTRY, *PMAC_TABLE_ENTRY;
2427
2428typedef struct _MAC_TABLE {
2429 USHORT Size;
2430 MAC_TABLE_ENTRY *Hash[HASH_TABLE_SIZE];
2431 MAC_TABLE_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
2432 QUEUE_HEADER McastPsQueue;
2433 ULONG PsQIdleCount;
2434 BOOLEAN fAnyStationInPsm;
2435 BOOLEAN fAnyStationBadAtheros; // Check if any Station is atheros 802.11n Chip. We need to use RTS/CTS with Atheros 802,.11n chip.
2436 BOOLEAN fAnyTxOPForceDisable; // Check if it is necessary to disable BE TxOP
2437 BOOLEAN fAllStationAsRalink; // Check if all stations are ralink-chipset
2438#ifdef DOT11_N_SUPPORT
2439 BOOLEAN fAnyStationIsLegacy; // Check if I use legacy rate to transmit to my BSS Station/
2440 BOOLEAN fAnyStationNonGF; // Check if any Station can't support GF.
2441 BOOLEAN fAnyStation20Only; // Check if any Station can't support GF.
2442 BOOLEAN fAnyStationMIMOPSDynamic; // Check if any Station is MIMO Dynamic
2443 BOOLEAN fAnyBASession; // Check if there is BA session. Force turn on RTS/CTS
2444#endif // DOT11_N_SUPPORT //
2445} MAC_TABLE, *PMAC_TABLE;
2446
2447#ifdef DOT11_N_SUPPORT
2448#define IS_HT_STA(_pMacEntry) \
2449 (_pMacEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX)
2450
2451#define IS_HT_RATE(_pMacEntry) \
2452 (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
2453
2454#define PEER_IS_HT_RATE(_pMacEntry) \
2455 (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
2456#endif // DOT11_N_SUPPORT //
2457
2458typedef struct _WDS_ENTRY {
2459 BOOLEAN Valid;
2460 UCHAR Addr[MAC_ADDR_LEN];
2461 ULONG NoDataIdleCount;
2462 struct _WDS_ENTRY *pNext;
2463} WDS_ENTRY, *PWDS_ENTRY;
2464
2465typedef struct _WDS_TABLE_ENTRY {
2466 USHORT Size;
2467 UCHAR WdsAddr[MAC_ADDR_LEN];
2468 WDS_ENTRY *Hash[HASH_TABLE_SIZE];
2469 WDS_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
2470 UCHAR MaxSupportedRate;
2471 UCHAR CurrTxRate;
2472 USHORT TxQuality[MAX_LEN_OF_SUPPORTED_RATES];
2473 USHORT OneSecTxOkCount;
2474 USHORT OneSecTxRetryOkCount;
2475 USHORT OneSecTxFailCount;
2476 ULONG CurrTxRateStableTime; // # of second in current TX rate
2477 UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
2478} WDS_TABLE_ENTRY, *PWDS_TABLE_ENTRY;
2479
2480typedef struct _RT_802_11_WDS_ENTRY {
2481 PNET_DEV dev;
2482 UCHAR Valid;
2483 UCHAR PhyMode;
2484 UCHAR PeerWdsAddr[MAC_ADDR_LEN];
2485 UCHAR MacTabMatchWCID; // ASIC
2486 NDIS_802_11_WEP_STATUS WepStatus;
2487 UCHAR KeyIdx;
2488 CIPHER_KEY WdsKey;
2489 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
2490 RT_HT_PHY_INFO DesiredHtPhyInfo;
2491 BOOLEAN bAutoTxRateSwitch;
2492 DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting.
2493} RT_802_11_WDS_ENTRY, *PRT_802_11_WDS_ENTRY;
2494
2495typedef struct _WDS_TABLE {
2496 UCHAR Mode;
2497 ULONG Size;
2498 RT_802_11_WDS_ENTRY WdsEntry[MAX_WDS_ENTRY];
2499} WDS_TABLE, *PWDS_TABLE;
2500
2501typedef struct _APCLI_STRUCT {
2502 PNET_DEV dev;
2503#ifdef RTL865X_SOC
2504 unsigned int mylinkid;
2505#endif
2506 BOOLEAN Enable; // Set it as 1 if the apcli interface was configured to "1" or by iwpriv cmd "ApCliEnable"
2507 BOOLEAN Valid; // Set it as 1 if the apcli interface associated success to remote AP.
2508 UCHAR MacTabWCID; //WCID value, which point to the entry of ASIC Mac table.
2509 UCHAR SsidLen;
2510 CHAR Ssid[MAX_LEN_OF_SSID];
2511
2512 UCHAR CfgSsidLen;
2513 CHAR CfgSsid[MAX_LEN_OF_SSID];
2514 UCHAR CfgApCliBssid[ETH_LENGTH_OF_ADDRESS];
2515 UCHAR CurrentAddress[ETH_LENGTH_OF_ADDRESS];
2516
2517 ULONG ApCliRcvBeaconTime;
2518
2519 ULONG CtrlCurrState;
2520 ULONG SyncCurrState;
2521 ULONG AuthCurrState;
2522 ULONG AssocCurrState;
2523 ULONG WpaPskCurrState;
2524
2525 USHORT AuthReqCnt;
2526 USHORT AssocReqCnt;
2527
2528 ULONG ClientStatusFlags;
2529 UCHAR MpduDensity;
2530
2531 NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
2532 NDIS_802_11_WEP_STATUS WepStatus;
2533
2534 // Add to support different cipher suite for WPA2/WPA mode
2535 NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Multicast cipher suite
2536 NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher suite
2537 BOOLEAN bMixCipher; // Indicate current Pair & Group use different cipher suites
2538 USHORT RsnCapability;
2539
2540 UCHAR PSK[100]; // reserve PSK key material
2541 UCHAR PSKLen;
2542 UCHAR PMK[32]; // WPA PSK mode PMK
2543 //UCHAR PTK[64]; // WPA PSK mode PTK
2544 UCHAR GTK[32]; // GTK from authenticator
2545
2546 //CIPHER_KEY PairwiseKey;
2547 CIPHER_KEY SharedKey[SHARE_KEY_NUM];
2548 UCHAR DefaultKeyId;
2549
2550 // WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
2551 //UCHAR PortSecured;
2552
2553 // store RSN_IE built by driver
2554 UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; // The content saved here should be convert to little-endian format.
2555 UCHAR RSNIE_Len;
2556
2557 // For WPA countermeasures
2558 ULONG LastMicErrorTime; // record last MIC error time
2559 //ULONG MicErrCnt; // Should be 0, 1, 2, then reset to zero (after disassoiciation).
2560 BOOLEAN bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred.
2561
2562 // For WPA-PSK supplicant state
2563 //WPA_STATE WpaState; // Default is SS_NOTUSE
2564 //UCHAR ReplayCounter[8];
2565 //UCHAR ANonce[32]; // ANonce for WPA-PSK from authenticator
2566 UCHAR SNonce[32]; // SNonce for WPA-PSK
2567 UCHAR GNonce[32]; // GNonce for WPA-PSK from authenticator
2568
2569 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
2570 RT_HT_PHY_INFO DesiredHtPhyInfo;
2571 BOOLEAN bAutoTxRateSwitch;
2572 DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting.
2573} APCLI_STRUCT, *PAPCLI_STRUCT;
2574
2575// ----------- end of AP ----------------------------
2576
2577#ifdef BLOCK_NET_IF
2578typedef struct _BLOCK_QUEUE_ENTRY
2579{
2580 BOOLEAN SwTxQueueBlockFlag;
2581 LIST_HEADER NetIfList;
2582} BLOCK_QUEUE_ENTRY, *PBLOCK_QUEUE_ENTRY;
2583#endif // BLOCK_NET_IF //
2584
2585struct wificonf
2586{
2587 BOOLEAN bShortGI;
2588 BOOLEAN bGreenField;
2589};
2590
2591
2592
2593typedef struct _INF_PCI_CONFIG
2594{
2595 PUCHAR CSRBaseAddress; // PCI MMIO Base Address, all access will use
2596}INF_PCI_CONFIG;
2597
2598typedef struct _INF_USB_CONFIG
2599{
2600 UINT BulkInEpAddr; // bulk-in endpoint address
2601 UINT BulkOutEpAddr[6]; // bulk-out endpoint address
2602
2603}INF_USB_CONFIG;
2604
2605#ifdef IKANOS_VX_1X0
2606 typedef void (*IkanosWlanTxCbFuncP)(void *, void *);
2607
2608 struct IKANOS_TX_INFO
2609 {
2610 struct net_device *netdev;
2611 IkanosWlanTxCbFuncP *fp;
2612 };
2613#endif // IKANOS_VX_1X0 //
2614
2615#ifdef NINTENDO_AP
2616typedef struct _NINDO_CTRL_BLOCK {
2617
2618 RT_NINTENDO_TABLE DS_TABLE;
2619
2620#ifdef CHIP25XX
2621 spinlock_t NINTENDO_TABLE_Lock;
2622#else
2623 NDIS_SPIN_LOCK NINTENDO_TABLE_Lock;
2624#endif // CHIP25XX //
2625
2626 UCHAR NINTENDO_UP_BUFFER[512];
2627 UCHAR Local_KeyIdx;
2628 CIPHER_KEY Local_SharedKey;
2629 UCHAR Local_bHideSsid;
2630 UCHAR Local_AuthMode;
2631 UCHAR Local_WepStatus;
2632 USHORT Local_CapabilityInfo;
2633} NINDO_CTRL_BLOCK;
2634#endif // NINTENDO_AP //
2635
2636
2637#ifdef DBG_DIAGNOSE
2638#define DIAGNOSE_TIME 10 // 10 sec
2639typedef struct _RtmpDiagStrcut_
2640{ // Diagnosis Related element
2641 unsigned char inited;
2642 unsigned char qIdx;
2643 unsigned char ArrayStartIdx;
2644 unsigned char ArrayCurIdx;
2645 // Tx Related Count
2646 USHORT TxDataCnt[DIAGNOSE_TIME];
2647 USHORT TxFailCnt[DIAGNOSE_TIME];
2648// USHORT TxDescCnt[DIAGNOSE_TIME][16]; // TxDesc queue length in scale of 0~14, >=15
2649 USHORT TxDescCnt[DIAGNOSE_TIME][24]; // 3*3 // TxDesc queue length in scale of 0~14, >=15
2650// USHORT TxMcsCnt[DIAGNOSE_TIME][16]; // TxDate MCS Count in range from 0 to 15, step in 1.
2651 USHORT TxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
2652 USHORT TxSWQueCnt[DIAGNOSE_TIME][9]; // TxSwQueue length in scale of 0, 1, 2, 3, 4, 5, 6, 7, >=8
2653
2654 USHORT TxAggCnt[DIAGNOSE_TIME];
2655 USHORT TxNonAggCnt[DIAGNOSE_TIME];
2656// USHORT TxAMPDUCnt[DIAGNOSE_TIME][16]; // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
2657 USHORT TxAMPDUCnt[DIAGNOSE_TIME][24]; // 3*3 // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
2658 USHORT TxRalinkCnt[DIAGNOSE_TIME]; // TxRalink Aggregation Count in 1 sec scale.
2659 USHORT TxAMSDUCnt[DIAGNOSE_TIME]; // TxAMSUD Aggregation Count in 1 sec scale.
2660
2661 // Rx Related Count
2662 USHORT RxDataCnt[DIAGNOSE_TIME]; // Rx Total Data count.
2663 USHORT RxCrcErrCnt[DIAGNOSE_TIME];
2664// USHORT RxMcsCnt[DIAGNOSE_TIME][16]; // Rx MCS Count in range from 0 to 15, step in 1.
2665 USHORT RxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
2666}RtmpDiagStruct;
2667#endif // DBG_DIAGNOSE //
2668
2669
2670//
2671// The miniport adapter structure
2672//
2673typedef struct _RTMP_ADAPTER
2674{
2675 PVOID OS_Cookie; // save specific structure relative to OS
2676 PNET_DEV net_dev;
2677 ULONG VirtualIfCnt;
2678
2679
2680
2681 NDIS_SPIN_LOCK irq_lock;
2682 UCHAR irq_disabled;
2683
2684#ifdef RT2870
2685/*****************************************************************************************/
2686/* USB related parameters */
2687/*****************************************************************************************/
2688 struct usb_config_descriptor *config;
2689 UINT BulkInEpAddr; // bulk-in endpoint address
2690 UINT BulkOutEpAddr[6]; // bulk-out endpoint address
2691
2692 UINT NumberOfPipes;
2693 USHORT BulkOutMaxPacketSize;
2694 USHORT BulkInMaxPacketSize;
2695
2696 //======Control Flags
2697 LONG PendingIoCount;
2698 ULONG BulkFlags;
2699 BOOLEAN bUsbTxBulkAggre; // Flags for bulk out data priority
2700
2701
2702 //======Timer Thread
2703 RT2870_TIMER_QUEUE TimerQ;
2704 NDIS_SPIN_LOCK TimerQLock;
2705
2706
2707 //======Cmd Thread
2708 CmdQ CmdQ;
2709 NDIS_SPIN_LOCK CmdQLock; // CmdQLock spinlock
2710
2711 BOOLEAN TimerFunc_kill;
2712 BOOLEAN mlme_kill;
2713
2714
2715 //======Semaphores (event)
2716 struct semaphore mlme_semaphore; /* to sleep thread on */
2717 struct semaphore RTUSBCmd_semaphore; /* to sleep thread on */
2718 struct semaphore RTUSBTimer_semaphore;
2719#ifdef INF_AMAZON_SE
2720 struct semaphore UsbVendorReq_semaphore;
2721 PVOID UsbVendorReqBuf;
2722#endif // INF_AMAZON_SE //
2723 struct completion TimerQComplete;
2724 struct completion mlmeComplete;
2725 struct completion CmdQComplete;
2726 wait_queue_head_t *wait;
2727
2728 //======Lock for 2870 ATE
2729#ifdef RALINK_ATE
2730 NDIS_SPIN_LOCK GenericLock; // ATE Tx/Rx generic spinlock
2731#endif // RALINK_ATE //
2732
2733#endif // RT2870 //
2734
2735
2736/*****************************************************************************************/
2737 /* Both PCI/USB related parameters */
2738/*****************************************************************************************/
2739
2740
2741/*****************************************************************************************/
2742/* Tx related parameters */
2743/*****************************************************************************************/
2744 BOOLEAN DeQueueRunning[NUM_OF_TX_RING]; // for ensuring RTUSBDeQueuePacket get call once
2745 NDIS_SPIN_LOCK DeQueueLock[NUM_OF_TX_RING];
2746
2747#ifdef RT2870
2748 // Data related context and AC specified, 4 AC supported
2749 NDIS_SPIN_LOCK BulkOutLock[6]; // BulkOut spinlock for 4 ACs
2750 NDIS_SPIN_LOCK MLMEBulkOutLock; // MLME BulkOut lock
2751
2752 HT_TX_CONTEXT TxContext[NUM_OF_TX_RING];
2753 NDIS_SPIN_LOCK TxContextQueueLock[NUM_OF_TX_RING]; // TxContextQueue spinlock
2754
2755 // 4 sets of Bulk Out index and pending flag
2756 UCHAR NextBulkOutIndex[4]; // only used for 4 EDCA bulkout pipe
2757
2758 BOOLEAN BulkOutPending[6]; // used for total 6 bulkout pipe
2759 UCHAR bulkResetPipeid;
2760 BOOLEAN MgmtBulkPending;
2761 ULONG bulkResetReq[6];
2762#endif // RT2870 //
2763
2764 // resource for software backlog queues
2765 QUEUE_HEADER TxSwQueue[NUM_OF_TX_RING]; // 4 AC + 1 HCCA
2766 NDIS_SPIN_LOCK TxSwQueueLock[NUM_OF_TX_RING]; // TxSwQueue spinlock
2767
2768 RTMP_DMABUF MgmtDescRing; // Shared memory for MGMT descriptors
2769 RTMP_MGMT_RING MgmtRing;
2770 NDIS_SPIN_LOCK MgmtRingLock; // Prio Ring spinlock
2771
2772
2773/*****************************************************************************************/
2774/* Rx related parameters */
2775/*****************************************************************************************/
2776
2777
2778#ifdef RT2870
2779 RX_CONTEXT RxContext[RX_RING_SIZE]; // 1 for redundant multiple IRP bulk in.
2780 NDIS_SPIN_LOCK BulkInLock; // BulkIn spinlock for 4 ACs
2781 UCHAR PendingRx; // The Maxima pending Rx value should be RX_RING_SIZE.
2782 UCHAR NextRxBulkInIndex; // Indicate the current RxContext Index which hold by Host controller.
2783 UCHAR NextRxBulkInReadIndex; // Indicate the current RxContext Index which driver can read & process it.
2784 ULONG NextRxBulkInPosition; // Want to contatenate 2 URB buffer while 1st is bulkin failed URB. This Position is 1st URB TransferLength.
2785 ULONG TransferBufferLength; // current length of the packet buffer
2786 ULONG ReadPosition; // current read position in a packet buffer
2787#endif // RT2870 //
2788
2789
2790/*****************************************************************************************/
2791/* ASIC related parameters */
2792/*****************************************************************************************/
2793 UINT32 MACVersion; // MAC version. Record rt2860C(0x28600100) or rt2860D (0x28600101)..
2794
2795 // ---------------------------
2796 // E2PROM
2797 // ---------------------------
2798 ULONG EepromVersion; // byte 0: version, byte 1: revision, byte 2~3: unused
2799 UCHAR EEPROMAddressNum; // 93c46=6 93c66=8
2800 USHORT EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS];
2801 ULONG FirmwareVersion; // byte 0: Minor version, byte 1: Major version, otherwise unused.
2802
2803 // ---------------------------
2804 // BBP Control
2805 // ---------------------------
2806 UCHAR BbpWriteLatch[140]; // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID
2807 UCHAR BbpRssiToDbmDelta;
2808 BBP_R66_TUNING BbpTuning;
2809
2810 // ----------------------------
2811 // RFIC control
2812 // ----------------------------
2813 UCHAR RfIcType; // RFIC_xxx
2814 ULONG RfFreqOffset; // Frequency offset for channel switching
2815 RTMP_RF_REGS LatchRfRegs; // latch th latest RF programming value since RF IC doesn't support READ
2816
2817 EEPROM_ANTENNA_STRUC Antenna; // Since ANtenna definition is different for a & g. We need to save it for future reference.
2818 EEPROM_NIC_CONFIG2_STRUC NicConfig2;
2819
2820 // This soft Rx Antenna Diversity mechanism is used only when user set
2821 // RX Antenna = DIVERSITY ON
2822 SOFT_RX_ANT_DIVERSITY RxAnt;
2823
2824 UCHAR RFProgSeq;
2825 CHANNEL_TX_POWER TxPower[MAX_NUM_OF_CHANNELS]; // Store Tx power value for all channels.
2826 CHANNEL_TX_POWER ChannelList[MAX_NUM_OF_CHANNELS]; // list all supported channels for site survey
2827 CHANNEL_11J_TX_POWER TxPower11J[MAX_NUM_OF_11JCHANNELS]; // 802.11j channel and bw
2828 CHANNEL_11J_TX_POWER ChannelList11J[MAX_NUM_OF_11JCHANNELS]; // list all supported channels for site survey
2829
2830 UCHAR ChannelListNum; // number of channel in ChannelList[]
2831 UCHAR Bbp94;
2832 BOOLEAN BbpForCCK;
2833 ULONG Tx20MPwrCfgABand[5];
2834 ULONG Tx20MPwrCfgGBand[5];
2835 ULONG Tx40MPwrCfgABand[5];
2836 ULONG Tx40MPwrCfgGBand[5];
2837
2838 BOOLEAN bAutoTxAgcA; // Enable driver auto Tx Agc control
2839 UCHAR TssiRefA; // Store Tssi reference value as 25 temperature.
2840 UCHAR TssiPlusBoundaryA[5]; // Tssi boundary for increase Tx power to compensate.
2841 UCHAR TssiMinusBoundaryA[5]; // Tssi boundary for decrease Tx power to compensate.
2842 UCHAR TxAgcStepA; // Store Tx TSSI delta increment / decrement value
2843 CHAR TxAgcCompensateA; // Store the compensation (TxAgcStep * (idx-1))
2844
2845 BOOLEAN bAutoTxAgcG; // Enable driver auto Tx Agc control
2846 UCHAR TssiRefG; // Store Tssi reference value as 25 temperature.
2847 UCHAR TssiPlusBoundaryG[5]; // Tssi boundary for increase Tx power to compensate.
2848 UCHAR TssiMinusBoundaryG[5]; // Tssi boundary for decrease Tx power to compensate.
2849 UCHAR TxAgcStepG; // Store Tx TSSI delta increment / decrement value
2850 CHAR TxAgcCompensateG; // Store the compensation (TxAgcStep * (idx-1))
2851
2852 //+++For RT2870, the parameteres is start from BGRssiOffset1 ~ BGRssiOffset3
2853 CHAR BGRssiOffset0; // Store B/G RSSI#0 Offset value on EEPROM 0x46h
2854 CHAR BGRssiOffset1; // Store B/G RSSI#1 Offset value
2855 CHAR BGRssiOffset2; // Store B/G RSSI#2 Offset value
2856 //---
2857
2858 //+++For RT2870, the parameteres is start from ARssiOffset1 ~ ARssiOffset3
2859 CHAR ARssiOffset0; // Store A RSSI#0 Offset value on EEPROM 0x4Ah
2860 CHAR ARssiOffset1; // Store A RSSI#1 Offset value
2861 CHAR ARssiOffset2; // Store A RSSI#2 Offset value
2862 //---
2863
2864 CHAR BLNAGain; // Store B/G external LNA#0 value on EEPROM 0x44h
2865 CHAR ALNAGain0; // Store A external LNA#0 value for ch36~64
2866 CHAR ALNAGain1; // Store A external LNA#1 value for ch100~128
2867 CHAR ALNAGain2; // Store A external LNA#2 value for ch132~165
2868
2869 // ----------------------------
2870 // LED control
2871 // ----------------------------
2872 MCU_LEDCS_STRUC LedCntl;
2873 USHORT Led1; // read from EEPROM 0x3c
2874 USHORT Led2; // EEPROM 0x3e
2875 USHORT Led3; // EEPROM 0x40
2876 UCHAR LedIndicatorStregth;
2877 UCHAR RssiSingalstrengthOffet;
2878 BOOLEAN bLedOnScanning;
2879 UCHAR LedStatus;
2880
2881/*****************************************************************************************/
2882/* 802.11 related parameters */
2883/*****************************************************************************************/
2884 // outgoing BEACON frame buffer and corresponding TXD
2885 TXWI_STRUC BeaconTxWI;
2886 PUCHAR BeaconBuf;
2887 USHORT BeaconOffset[HW_BEACON_MAX_COUNT];
2888
2889 // pre-build PS-POLL and NULL frame upon link up. for efficiency purpose.
2890 PSPOLL_FRAME PsPollFrame;
2891 HEADER_802_11 NullFrame;
2892
2893#ifdef RT2870
2894 TX_CONTEXT BeaconContext[BEACON_RING_SIZE];
2895 TX_CONTEXT NullContext;
2896 TX_CONTEXT PsPollContext;
2897 TX_CONTEXT RTSContext;
2898#endif // RT2870 //
2899
2900
2901
2902//=========AP===========
2903
2904
2905//=======STA===========
2906#ifdef CONFIG_STA_SUPPORT
2907/* Modified by Wu Xi-Kun 4/21/2006 */
2908 // -----------------------------------------------
2909 // STA specific configuration & operation status
2910 // used only when pAd->OpMode == OPMODE_STA
2911 // -----------------------------------------------
2912 STA_ADMIN_CONFIG StaCfg; // user desired settings
2913 STA_ACTIVE_CONFIG StaActive; // valid only when ADHOC_ON(pAd) || INFRA_ON(pAd)
2914 CHAR nickname[IW_ESSID_MAX_SIZE+1]; // nickname, only used in the iwconfig i/f
2915 NDIS_MEDIA_STATE PreMediaState;
2916#endif // CONFIG_STA_SUPPORT //
2917
2918//=======Common===========
2919 // OP mode: either AP or STA
2920 UCHAR OpMode; // OPMODE_STA, OPMODE_AP
2921
2922 NDIS_MEDIA_STATE IndicateMediaState; // Base on Indication state, default is NdisMediaStateDisConnected
2923
2924
2925 // configuration: read from Registry & E2PROM
2926 BOOLEAN bLocalAdminMAC; // Use user changed MAC
2927 UCHAR PermanentAddress[MAC_ADDR_LEN]; // Factory default MAC address
2928 UCHAR CurrentAddress[MAC_ADDR_LEN]; // User changed MAC address
2929
2930 // ------------------------------------------------------
2931 // common configuration to both OPMODE_STA and OPMODE_AP
2932 // ------------------------------------------------------
2933 COMMON_CONFIG CommonCfg;
2934 MLME_STRUCT Mlme;
2935
2936 // AP needs those vaiables for site survey feature.
2937 MLME_AUX MlmeAux; // temporary settings used during MLME state machine
2938 BSS_TABLE ScanTab; // store the latest SCAN result
2939
2940 //About MacTab, the sta driver will use #0 and #1 for multicast and AP.
2941 MAC_TABLE MacTab; // ASIC on-chip WCID entry table. At TX, ASIC always use key according to this on-chip table.
2942 NDIS_SPIN_LOCK MacTabLock;
2943
2944#ifdef DOT11_N_SUPPORT
2945 BA_TABLE BATable;
2946#endif // DOT11_N_SUPPORT //
2947 NDIS_SPIN_LOCK BATabLock;
2948 RALINK_TIMER_STRUCT RECBATimer;
2949
2950 // encryption/decryption KEY tables
2951 CIPHER_KEY SharedKey[MAX_MBSSID_NUM][4]; // STA always use SharedKey[BSS0][0..3]
2952
2953 // RX re-assembly buffer for fragmentation
2954 FRAGMENT_FRAME FragFrame; // Frame storage for fragment frame
2955
2956 // various Counters
2957 COUNTER_802_3 Counters8023; // 802.3 counters
2958 COUNTER_802_11 WlanCounters; // 802.11 MIB counters
2959 COUNTER_RALINK RalinkCounters; // Ralink propriety counters
2960 COUNTER_DRS DrsCounters; // counters for Dynamic TX Rate Switching
2961 PRIVATE_STRUC PrivateInfo; // Private information & counters
2962
2963 // flags, see fRTMP_ADAPTER_xxx flags
2964 ULONG Flags; // Represent current device status
2965
2966 // current TX sequence #
2967 USHORT Sequence;
2968
2969 // Control disconnect / connect event generation
2970 //+++Didn't used anymore
2971 ULONG LinkDownTime;
2972 //---
2973 ULONG LastRxRate;
2974 ULONG LastTxRate;
2975 //+++Used only for Station
2976 BOOLEAN bConfigChanged; // Config Change flag for the same SSID setting
2977 //---
2978
2979 ULONG ExtraInfo; // Extra information for displaying status
2980 ULONG SystemErrorBitmap; // b0: E2PROM version error
2981
2982 //+++Didn't used anymore
2983 ULONG MacIcVersion; // MAC/BBP serial interface issue solved after ver.D
2984 //---
2985
2986 // ---------------------------
2987 // System event log
2988 // ---------------------------
2989 RT_802_11_EVENT_TABLE EventTab;
2990
2991
2992 BOOLEAN HTCEnable;
2993
2994 /*****************************************************************************************/
2995 /* Statistic related parameters */
2996 /*****************************************************************************************/
2997#ifdef RT2870
2998 ULONG BulkOutDataOneSecCount;
2999 ULONG BulkInDataOneSecCount;
3000 ULONG BulkLastOneSecCount; // BulkOutDataOneSecCount + BulkInDataOneSecCount
3001 ULONG watchDogRxCnt;
3002 ULONG watchDogRxOverFlowCnt;
3003 ULONG watchDogTxPendingCnt[NUM_OF_TX_RING];
3004#endif // RT2870 //
3005
3006 BOOLEAN bUpdateBcnCntDone;
3007 ULONG watchDogMacDeadlock; // prevent MAC/BBP into deadlock condition
3008 // ----------------------------
3009 // DEBUG paramerts
3010 // ----------------------------
3011 //ULONG DebugSetting[4];
3012 BOOLEAN bBanAllBaSetup;
3013 BOOLEAN bPromiscuous;
3014
3015 // ----------------------------
3016 // rt2860c emulation-use Parameters
3017 // ----------------------------
3018 ULONG rtsaccu[30];
3019 ULONG ctsaccu[30];
3020 ULONG cfendaccu[30];
3021 ULONG bacontent[16];
3022 ULONG rxint[RX_RING_SIZE+1];
3023 UCHAR rcvba[60];
3024 BOOLEAN bLinkAdapt;
3025 BOOLEAN bForcePrintTX;
3026 BOOLEAN bForcePrintRX;
3027 BOOLEAN bDisablescanning; //defined in RT2870 USB
3028 BOOLEAN bStaFifoTest;
3029 BOOLEAN bProtectionTest;
3030 BOOLEAN bHCCATest;
3031 BOOLEAN bGenOneHCCA;
3032 BOOLEAN bBroadComHT;
3033 //+++Following add from RT2870 USB.
3034 ULONG BulkOutReq;
3035 ULONG BulkOutComplete;
3036 ULONG BulkOutCompleteOther;
3037 ULONG BulkOutCompleteCancel; // seems not use now?
3038 ULONG BulkInReq;
3039 ULONG BulkInComplete;
3040 ULONG BulkInCompleteFail;
3041 //---
3042
3043 struct wificonf WIFItestbed;
3044
3045#ifdef RALINK_ATE
3046 ATE_INFO ate;
3047#ifdef RT2870
3048 BOOLEAN ContinBulkOut; //ATE bulk out control
3049 BOOLEAN ContinBulkIn; //ATE bulk in control
3050 atomic_t BulkOutRemained;
3051 atomic_t BulkInRemained;
3052#endif // RT2870 //
3053#endif // RALINK_ATE //
3054
3055#ifdef DOT11_N_SUPPORT
3056 struct reordering_mpdu_pool mpdu_blk_pool;
3057#endif // DOT11_N_SUPPORT //
3058
3059 ULONG OneSecondnonBEpackets; // record non BE packets per second
3060
3061#if WIRELESS_EXT >= 12
3062 struct iw_statistics iw_stats;
3063#endif
3064
3065 struct net_device_stats stats;
3066
3067#ifdef BLOCK_NET_IF
3068 BLOCK_QUEUE_ENTRY blockQueueTab[NUM_OF_TX_RING];
3069#endif // BLOCK_NET_IF //
3070
3071
3072
3073#ifdef MULTIPLE_CARD_SUPPORT
3074 INT32 MC_RowID;
3075 UCHAR MC_FileName[256];
3076#endif // MULTIPLE_CARD_SUPPORT //
3077
3078 ULONG TbttTickCount;
3079#ifdef PCI_MSI_SUPPORT
3080 BOOLEAN HaveMsi;
3081#endif // PCI_MSI_SUPPORT //
3082
3083
3084 UCHAR is_on;
3085
3086#define TIME_BASE (1000000/OS_HZ)
3087#define TIME_ONE_SECOND (1000000/TIME_BASE)
3088 UCHAR flg_be_adjust;
3089 ULONG be_adjust_last_time;
3090
3091
3092#ifdef IKANOS_VX_1X0
3093 struct IKANOS_TX_INFO IkanosTxInfo;
3094 struct IKANOS_TX_INFO IkanosRxInfo[MAX_MBSSID_NUM + MAX_WDS_ENTRY + MAX_APCLI_NUM + MAX_MESH_NUM];
3095#endif // IKANOS_VX_1X0 //
3096
3097
3098#ifdef DBG_DIAGNOSE
3099 RtmpDiagStruct DiagStruct;
3100#endif // DBG_DIAGNOSE //
3101
3102
3103 UINT8 PM_FlgSuspend;
3104} RTMP_ADAPTER, *PRTMP_ADAPTER;
3105
3106//
3107// Cisco IAPP format
3108//
3109typedef struct _CISCO_IAPP_CONTENT_
3110{
3111 USHORT Length; //IAPP Length
3112 UCHAR MessageType; //IAPP type
3113 UCHAR FunctionCode; //IAPP function type
3114 UCHAR DestinaionMAC[MAC_ADDR_LEN];
3115 UCHAR SourceMAC[MAC_ADDR_LEN];
3116 USHORT Tag; //Tag(element IE) - Adjacent AP report
3117 USHORT TagLength; //Length of element not including 4 byte header
3118 UCHAR OUI[4]; //0x00, 0x40, 0x96, 0x00
3119 UCHAR PreviousAP[MAC_ADDR_LEN]; //MAC Address of access point
3120 USHORT Channel;
3121 USHORT SsidLen;
3122 UCHAR Ssid[MAX_LEN_OF_SSID];
3123 USHORT Seconds; //Seconds that the client has been disassociated.
3124} CISCO_IAPP_CONTENT, *PCISCO_IAPP_CONTENT;
3125
3126#define DELAYINTMASK 0x0003fffb
3127#define INTMASK 0x0003fffb
3128#define IndMask 0x0003fffc
3129#define RxINT 0x00000005 // Delayed Rx or indivi rx
3130#define TxDataInt 0x000000fa // Delayed Tx or indivi tx
3131#define TxMgmtInt 0x00000102 // Delayed Tx or indivi tx
3132#define TxCoherent 0x00020000 // tx coherent
3133#define RxCoherent 0x00010000 // rx coherent
3134#define McuCommand 0x00000200 // mcu
3135#define PreTBTTInt 0x00001000 // Pre-TBTT interrupt
3136#define TBTTInt 0x00000800 // TBTT interrupt
3137#define GPTimeOutInt 0x00008000 // GPtimeout interrupt
3138#define AutoWakeupInt 0x00004000 // AutoWakeupInt interrupt
3139#define FifoStaFullInt 0x00002000 // fifo statistics full interrupt
3140
3141
3142typedef struct _RX_BLK_
3143{
3144// RXD_STRUC RxD; // sample
3145 RT28XX_RXD_STRUC RxD;
3146 PRXWI_STRUC pRxWI;
3147 PHEADER_802_11 pHeader;
3148 PNDIS_PACKET pRxPacket;
3149 UCHAR *pData;
3150 USHORT DataSize;
3151 USHORT Flags;
3152 UCHAR UserPriority; // for calculate TKIP MIC using
3153} RX_BLK;
3154
3155
3156#define RX_BLK_SET_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags |= _flag)
3157#define RX_BLK_TEST_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags & _flag)
3158#define RX_BLK_CLEAR_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags &= ~(_flag))
3159
3160
3161#define fRX_WDS 0x0001
3162#define fRX_AMSDU 0x0002
3163#define fRX_ARALINK 0x0004
3164#define fRX_HTC 0x0008
3165#define fRX_PAD 0x0010
3166#define fRX_AMPDU 0x0020
3167#define fRX_QOS 0x0040
3168#define fRX_INFRA 0x0080
3169#define fRX_EAP 0x0100
3170#define fRX_MESH 0x0200
3171#define fRX_APCLI 0x0400
3172#define fRX_DLS 0x0800
3173#define fRX_WPI 0x1000
3174
3175#define LENGTH_AMSDU_SUBFRAMEHEAD 14
3176#define LENGTH_ARALINK_SUBFRAMEHEAD 14
3177#define LENGTH_ARALINK_HEADER_FIELD 2
3178
3179#define TX_UNKOWN_FRAME 0x00
3180#define TX_MCAST_FRAME 0x01
3181#define TX_LEGACY_FRAME 0x02
3182#define TX_AMPDU_FRAME 0x04
3183#define TX_AMSDU_FRAME 0x08
3184#define TX_RALINK_FRAME 0x10
3185#define TX_FRAG_FRAME 0x20
3186
3187
3188// Currently the sizeof(TX_BLK) is 148 bytes.
3189typedef struct _TX_BLK_
3190{
3191 UCHAR QueIdx;
3192 UCHAR TxFrameType; // Indicate the Transmission type of the all frames in one batch
3193 UCHAR TotalFrameNum; // Total frame number want to send-out in one batch
3194 USHORT TotalFragNum; // Total frame fragments required in one batch
3195 USHORT TotalFrameLen; // Total length of all frames want to send-out in one batch
3196
3197 QUEUE_HEADER TxPacketList;
3198 MAC_TABLE_ENTRY *pMacEntry; // NULL: packet with 802.11 RA field is multicast/broadcast address
3199 HTTRANSMIT_SETTING *pTransmit;
3200
3201 // Following structure used for the characteristics of a specific packet.
3202 PNDIS_PACKET pPacket;
3203 PUCHAR pSrcBufHeader; // Reference to the head of sk_buff->data
3204 PUCHAR pSrcBufData; // Reference to the sk_buff->data, will changed depends on hanlding progresss
3205 UINT SrcBufLen; // Length of packet payload which not including Layer 2 header
3206 PUCHAR pExtraLlcSnapEncap; // NULL means no extra LLC/SNAP is required
3207 UCHAR HeaderBuf[80]; // TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP
3208 UCHAR MpduHeaderLen; // 802.11 header length NOT including the padding
3209 UCHAR HdrPadLen; // recording Header Padding Length;
3210 UCHAR apidx; // The interface associated to this packet
3211 UCHAR Wcid; // The MAC entry associated to this packet
3212 UCHAR UserPriority; // priority class of packet
3213 UCHAR FrameGap; // what kind of IFS this packet use
3214 UCHAR MpduReqNum; // number of fragments of this frame
3215 UCHAR TxRate; // TODO: Obsoleted? Should change to MCS?
3216 UCHAR CipherAlg; // cipher alogrithm
3217 PCIPHER_KEY pKey;
3218
3219
3220
3221 USHORT Flags; //See following definitions for detail.
3222
3223 //YOU SHOULD NOT TOUCH IT! Following parameters are used for hardware-depended layer.
3224 ULONG Priv; // Hardware specific value saved in here.
3225} TX_BLK, *PTX_BLK;
3226
3227
3228#define fTX_bRtsRequired 0x0001 // Indicate if need send RTS frame for protection. Not used in RT2860/RT2870.
3229#define fTX_bAckRequired 0x0002 // the packet need ack response
3230#define fTX_bPiggyBack 0x0004 // Legacy device use Piggback or not
3231#define fTX_bHTRate 0x0008 // allow to use HT rate
3232//#define fTX_bForceLowRate 0x0010 // force to use Low Rate
3233#define fTX_bForceNonQoS 0x0010 // force to transmit frame without WMM-QoS in HT mode
3234#define fTX_bAllowFrag 0x0020 // allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment
3235#define fTX_bMoreData 0x0040 // there are more data packets in PowerSave Queue
3236#define fTX_bWMM 0x0080 // QOS Data
3237
3238#define fTX_bClearEAPFrame 0x0100
3239
3240
3241#ifdef CONFIG_STA_SUPPORT
3242#endif // CONFIG_STA_SUPPORT //
3243
3244
3245
3246#define TX_BLK_ASSIGN_FLAG(_pTxBlk, _flag, value) \
3247 do { \
3248 if (value) \
3249 (_pTxBlk->Flags |= _flag) \
3250 else \
3251 (_pTxBlk->Flags &= ~(_flag)) \
3252 }while(0)
3253
3254#define TX_BLK_SET_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags |= _flag)
3255#define TX_BLK_TEST_FLAG(_pTxBlk, _flag) (((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0)
3256#define TX_BLK_CLEAR_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags &= ~(_flag))
3257
3258
3259
3260
3261
3262//------------------------------------------------------------------------------------------
3263
3264
3265
3266#ifdef RT_BIG_ENDIAN
3267static inline VOID WriteBackToDescriptor(
3268 IN PUCHAR Dest,
3269 IN PUCHAR Src,
3270 IN BOOLEAN DoEncrypt,
3271 IN ULONG DescriptorType)
3272{
3273 UINT32 *p1, *p2;
3274
3275 p1 = ((UINT32 *)Dest);
3276 p2 = ((UINT32 *)Src);
3277
3278 *p1 = *p2;
3279 *(p1+2) = *(p2+2);
3280 *(p1+3) = *(p2+3);
3281 *(p1+1) = *(p2+1); // Word 1; this must be written back last
3282}
3283
3284/*
3285 ========================================================================
3286
3287 Routine Description:
3288 Endian conversion of Tx/Rx descriptor .
3289
3290 Arguments:
3291 pAd Pointer to our adapter
3292 pData Pointer to Tx/Rx descriptor
3293 DescriptorType Direction of the frame
3294
3295 Return Value:
3296 None
3297
3298 Note:
3299 Call this function when read or update descriptor
3300 ========================================================================
3301*/
3302static inline VOID RTMPWIEndianChange(
3303 IN PUCHAR pData,
3304 IN ULONG DescriptorType)
3305{
3306 int size;
3307 int i;
3308
3309 size = ((DescriptorType == TYPE_TXWI) ? TXWI_SIZE : RXWI_SIZE);
3310
3311 if(DescriptorType == TYPE_TXWI)
3312 {
3313 *((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData))); // Byte 0~3
3314 *((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData+4))); // Byte 4~7
3315 }
3316 else
3317 {
3318 for(i=0; i < size/4 ; i++)
3319 *(((UINT32 *)pData) +i) = SWAP32(*(((UINT32 *)pData)+i));
3320 }
3321}
3322
3323/*
3324 ========================================================================
3325
3326 Routine Description:
3327 Endian conversion of Tx/Rx descriptor .
3328
3329 Arguments:
3330 pAd Pointer to our adapter
3331 pData Pointer to Tx/Rx descriptor
3332 DescriptorType Direction of the frame
3333
3334 Return Value:
3335 None
3336
3337 Note:
3338 Call this function when read or update descriptor
3339 ========================================================================
3340*/
3341
3342#ifdef RT2870
3343static inline VOID RTMPDescriptorEndianChange(
3344 IN PUCHAR pData,
3345 IN ULONG DescriptorType)
3346{
3347 *((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData)));
3348}
3349#endif // RT2870 //
3350/*
3351 ========================================================================
3352
3353 Routine Description:
3354 Endian conversion of all kinds of 802.11 frames .
3355
3356 Arguments:
3357 pAd Pointer to our adapter
3358 pData Pointer to the 802.11 frame structure
3359 Dir Direction of the frame
3360 FromRxDoneInt Caller is from RxDone interrupt
3361
3362 Return Value:
3363 None
3364
3365 Note:
3366 Call this function when read or update buffer data
3367 ========================================================================
3368*/
3369static inline VOID RTMPFrameEndianChange(
3370 IN PRTMP_ADAPTER pAd,
3371 IN PUCHAR pData,
3372 IN ULONG Dir,
3373 IN BOOLEAN FromRxDoneInt)
3374{
3375 PHEADER_802_11 pFrame;
3376 PUCHAR pMacHdr;
3377
3378 // swab 16 bit fields - Frame Control field
3379 if(Dir == DIR_READ)
3380 {
3381 *(USHORT *)pData = SWAP16(*(USHORT *)pData);
3382 }
3383
3384 pFrame = (PHEADER_802_11) pData;
3385 pMacHdr = (PUCHAR) pFrame;
3386
3387 // swab 16 bit fields - Duration/ID field
3388 *(USHORT *)(pMacHdr + 2) = SWAP16(*(USHORT *)(pMacHdr + 2));
3389
3390 // swab 16 bit fields - Sequence Control field
3391 *(USHORT *)(pMacHdr + 22) = SWAP16(*(USHORT *)(pMacHdr + 22));
3392
3393 if(pFrame->FC.Type == BTYPE_MGMT)
3394 {
3395 switch(pFrame->FC.SubType)
3396 {
3397 case SUBTYPE_ASSOC_REQ:
3398 case SUBTYPE_REASSOC_REQ:
3399 // swab 16 bit fields - CapabilityInfo field
3400 pMacHdr += sizeof(HEADER_802_11);
3401 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3402
3403 // swab 16 bit fields - Listen Interval field
3404 pMacHdr += 2;
3405 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3406 break;
3407
3408 case SUBTYPE_ASSOC_RSP:
3409 case SUBTYPE_REASSOC_RSP:
3410 // swab 16 bit fields - CapabilityInfo field
3411 pMacHdr += sizeof(HEADER_802_11);
3412 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3413
3414 // swab 16 bit fields - Status Code field
3415 pMacHdr += 2;
3416 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3417
3418 // swab 16 bit fields - AID field
3419 pMacHdr += 2;
3420 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3421 break;
3422
3423 case SUBTYPE_AUTH:
3424 // If from APHandleRxDoneInterrupt routine, it is still a encrypt format.
3425 // The convertion is delayed to RTMPHandleDecryptionDoneInterrupt.
3426 if(!FromRxDoneInt && pFrame->FC.Wep == 1)
3427 break;
3428 else
3429 {
3430 // swab 16 bit fields - Auth Alg No. field
3431 pMacHdr += sizeof(HEADER_802_11);
3432 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3433
3434 // swab 16 bit fields - Auth Seq No. field
3435 pMacHdr += 2;
3436 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3437
3438 // swab 16 bit fields - Status Code field
3439 pMacHdr += 2;
3440 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3441 }
3442 break;
3443
3444 case SUBTYPE_BEACON:
3445 case SUBTYPE_PROBE_RSP:
3446 // swab 16 bit fields - BeaconInterval field
3447 pMacHdr += (sizeof(HEADER_802_11) + TIMESTAMP_LEN);
3448 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3449
3450 // swab 16 bit fields - CapabilityInfo field
3451 pMacHdr += sizeof(USHORT);
3452 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3453 break;
3454
3455 case SUBTYPE_DEAUTH:
3456 case SUBTYPE_DISASSOC:
3457 // swab 16 bit fields - Reason code field
3458 pMacHdr += sizeof(HEADER_802_11);
3459 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3460 break;
3461 }
3462 }
3463 else if( pFrame->FC.Type == BTYPE_DATA )
3464 {
3465 }
3466 else if(pFrame->FC.Type == BTYPE_CNTL)
3467 {
3468 switch(pFrame->FC.SubType)
3469 {
3470 case SUBTYPE_BLOCK_ACK_REQ:
3471 {
3472 PFRAME_BA_REQ pBAReq = (PFRAME_BA_REQ)pFrame;
3473 *(USHORT *)(&pBAReq->BARControl) = SWAP16(*(USHORT *)(&pBAReq->BARControl));
3474 pBAReq->BAStartingSeq.word = SWAP16(pBAReq->BAStartingSeq.word);
3475 }
3476 break;
3477 case SUBTYPE_BLOCK_ACK:
3478 // For Block Ack packet, the HT_CONTROL field is in the same offset with Addr3
3479 *(UINT32 *)(&pFrame->Addr3[0]) = SWAP32(*(UINT32 *)(&pFrame->Addr3[0]));
3480 break;
3481
3482 case SUBTYPE_ACK:
3483 //For ACK packet, the HT_CONTROL field is in the same offset with Addr2
3484 *(UINT32 *)(&pFrame->Addr2[0])= SWAP32(*(UINT32 *)(&pFrame->Addr2[0]));
3485 break;
3486 }
3487 }
3488 else
3489 {
3490 DBGPRINT(RT_DEBUG_ERROR,("Invalid Frame Type!!!\n"));
3491 }
3492
3493 // swab 16 bit fields - Frame Control
3494 if(Dir == DIR_WRITE)
3495 {
3496 *(USHORT *)pData = SWAP16(*(USHORT *)pData);
3497 }
3498}
3499#endif // RT_BIG_ENDIAN //
3500
3501
3502static inline VOID ConvertMulticastIP2MAC(
3503 IN PUCHAR pIpAddr,
3504 IN PUCHAR *ppMacAddr,
3505 IN UINT16 ProtoType)
3506{
3507 if (pIpAddr == NULL)
3508 return;
3509
3510 if (ppMacAddr == NULL || *ppMacAddr == NULL)
3511 return;
3512
3513 switch (ProtoType)
3514 {
3515 case ETH_P_IPV6:
3516// memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
3517 *(*ppMacAddr) = 0x33;
3518 *(*ppMacAddr + 1) = 0x33;
3519 *(*ppMacAddr + 2) = pIpAddr[12];
3520 *(*ppMacAddr + 3) = pIpAddr[13];
3521 *(*ppMacAddr + 4) = pIpAddr[14];
3522 *(*ppMacAddr + 5) = pIpAddr[15];
3523 break;
3524
3525 case ETH_P_IP:
3526 default:
3527// memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
3528 *(*ppMacAddr) = 0x01;
3529 *(*ppMacAddr + 1) = 0x00;
3530 *(*ppMacAddr + 2) = 0x5e;
3531 *(*ppMacAddr + 3) = pIpAddr[1] & 0x7f;
3532 *(*ppMacAddr + 4) = pIpAddr[2];
3533 *(*ppMacAddr + 5) = pIpAddr[3];
3534 break;
3535 }
3536
3537 return;
3538}
3539
3540BOOLEAN RTMPCheckForHang(
3541 IN NDIS_HANDLE MiniportAdapterContext
3542 );
3543
3544VOID RTMPHalt(
3545 IN NDIS_HANDLE MiniportAdapterContext
3546 );
3547
3548//
3549// Private routines in rtmp_init.c
3550//
3551NDIS_STATUS RTMPAllocAdapterBlock(
3552 IN PVOID handle,
3553 OUT PRTMP_ADAPTER *ppAdapter
3554 );
3555
3556NDIS_STATUS RTMPAllocTxRxRingMemory(
3557 IN PRTMP_ADAPTER pAd
3558 );
3559
3560NDIS_STATUS RTMPFindAdapter(
3561 IN PRTMP_ADAPTER pAd,
3562 IN NDIS_HANDLE WrapperConfigurationContext
3563 );
3564
3565NDIS_STATUS RTMPReadParametersHook(
3566 IN PRTMP_ADAPTER pAd
3567 );
3568
3569VOID RTMPFreeAdapter(
3570 IN PRTMP_ADAPTER pAd
3571 );
3572
3573NDIS_STATUS NICReadRegParameters(
3574 IN PRTMP_ADAPTER pAd,
3575 IN NDIS_HANDLE WrapperConfigurationContext
3576 );
3577
3578#ifdef RT2870
3579VOID NICInitRT30xxRFRegisters(
3580 IN PRTMP_ADAPTER pAd);
3581#endif // RT2870 //
3582
3583VOID NICReadEEPROMParameters(
3584 IN PRTMP_ADAPTER pAd,
3585 IN PUCHAR mac_addr);
3586
3587VOID NICInitAsicFromEEPROM(
3588 IN PRTMP_ADAPTER pAd);
3589
3590VOID NICInitTxRxRingAndBacklogQueue(
3591 IN PRTMP_ADAPTER pAd);
3592
3593NDIS_STATUS NICInitializeAdapter(
3594 IN PRTMP_ADAPTER pAd,
3595 IN BOOLEAN bHardReset);
3596
3597NDIS_STATUS NICInitializeAsic(
3598 IN PRTMP_ADAPTER pAd,
3599 IN BOOLEAN bHardReset);
3600
3601VOID NICIssueReset(
3602 IN PRTMP_ADAPTER pAd);
3603
3604VOID RTMPRingCleanUp(
3605 IN PRTMP_ADAPTER pAd,
3606 IN UCHAR RingType);
3607
3608VOID RxTest(
3609 IN PRTMP_ADAPTER pAd);
3610
3611NDIS_STATUS DbgSendPacket(
3612 IN PRTMP_ADAPTER pAd,
3613 IN PNDIS_PACKET pPacket);
3614
3615VOID UserCfgInit(
3616 IN PRTMP_ADAPTER pAd);
3617
3618VOID NICResetFromError(
3619 IN PRTMP_ADAPTER pAd);
3620
3621VOID NICEraseFirmware(
3622 IN PRTMP_ADAPTER pAd);
3623
3624NDIS_STATUS NICLoadFirmware(
3625 IN PRTMP_ADAPTER pAd);
3626
3627NDIS_STATUS NICLoadRateSwitchingParams(
3628 IN PRTMP_ADAPTER pAd);
3629
3630BOOLEAN NICCheckForHang(
3631 IN PRTMP_ADAPTER pAd);
3632
3633VOID NICUpdateFifoStaCounters(
3634 IN PRTMP_ADAPTER pAd);
3635
3636VOID NICUpdateRawCounters(
3637 IN PRTMP_ADAPTER pAd);
3638
3639#if 0
3640ULONG RTMPEqualMemory(
3641 IN PVOID pSrc1,
3642 IN PVOID pSrc2,
3643 IN ULONG Length);
3644#endif
3645
3646ULONG RTMPNotAllZero(
3647 IN PVOID pSrc1,
3648 IN ULONG Length);
3649
3650VOID RTMPZeroMemory(
3651 IN PVOID pSrc,
3652 IN ULONG Length);
3653
3654ULONG RTMPCompareMemory(
3655 IN PVOID pSrc1,
3656 IN PVOID pSrc2,
3657 IN ULONG Length);
3658
3659VOID RTMPMoveMemory(
3660 OUT PVOID pDest,
3661 IN PVOID pSrc,
3662 IN ULONG Length);
3663
3664VOID AtoH(
3665 char *src,
3666 UCHAR *dest,
3667 int destlen);
3668
3669UCHAR BtoH(
3670 char ch);
3671
3672VOID RTMPPatchMacBbpBug(
3673 IN PRTMP_ADAPTER pAd);
3674
3675VOID RTMPPatchCardBus(
3676 IN PRTMP_ADAPTER pAdapter);
3677
3678VOID RTMPPatchRalinkCardBus(
3679 IN PRTMP_ADAPTER pAdapter,
3680 IN ULONG Bus);
3681
3682ULONG RTMPReadCBConfig(
3683 IN ULONG Bus,
3684 IN ULONG Slot,
3685 IN ULONG Func,
3686 IN ULONG Offset);
3687
3688VOID RTMPWriteCBConfig(
3689 IN ULONG Bus,
3690 IN ULONG Slot,
3691 IN ULONG Func,
3692 IN ULONG Offset,
3693 IN ULONG Value);
3694
3695VOID RTMPInitTimer(
3696 IN PRTMP_ADAPTER pAd,
3697 IN PRALINK_TIMER_STRUCT pTimer,
3698 IN PVOID pTimerFunc,
3699 IN PVOID pData,
3700 IN BOOLEAN Repeat);
3701
3702VOID RTMPSetTimer(
3703 IN PRALINK_TIMER_STRUCT pTimer,
3704 IN ULONG Value);
3705
3706
3707VOID RTMPModTimer(
3708 IN PRALINK_TIMER_STRUCT pTimer,
3709 IN ULONG Value);
3710
3711VOID RTMPCancelTimer(
3712 IN PRALINK_TIMER_STRUCT pTimer,
3713 OUT BOOLEAN *pCancelled);
3714
3715VOID RTMPSetLED(
3716 IN PRTMP_ADAPTER pAd,
3717 IN UCHAR Status);
3718
3719VOID RTMPSetSignalLED(
3720 IN PRTMP_ADAPTER pAd,
3721 IN NDIS_802_11_RSSI Dbm);
3722
3723VOID RTMPEnableRxTx(
3724 IN PRTMP_ADAPTER pAd);
3725
3726//
3727// prototype in action.c
3728//
3729VOID ActionStateMachineInit(
3730 IN PRTMP_ADAPTER pAd,
3731 IN STATE_MACHINE *S,
3732 OUT STATE_MACHINE_FUNC Trans[]);
3733
3734VOID MlmeADDBAAction(
3735 IN PRTMP_ADAPTER pAd,
3736 IN MLME_QUEUE_ELEM *Elem);
3737
3738VOID MlmeDELBAAction(
3739 IN PRTMP_ADAPTER pAd,
3740 IN MLME_QUEUE_ELEM *Elem);
3741
3742VOID MlmeDLSAction(
3743 IN PRTMP_ADAPTER pAd,
3744 IN MLME_QUEUE_ELEM *Elem);
3745
3746VOID MlmeInvalidAction(
3747 IN PRTMP_ADAPTER pAd,
3748 IN MLME_QUEUE_ELEM *Elem);
3749
3750VOID MlmeQOSAction(
3751 IN PRTMP_ADAPTER pAd,
3752 IN MLME_QUEUE_ELEM *Elem);
3753
3754#ifdef DOT11_N_SUPPORT
3755VOID PeerAddBAReqAction(
3756 IN PRTMP_ADAPTER pAd,
3757 IN MLME_QUEUE_ELEM *Elem);
3758
3759VOID PeerAddBARspAction(
3760 IN PRTMP_ADAPTER pAd,
3761 IN MLME_QUEUE_ELEM *Elem);
3762
3763VOID PeerDelBAAction(
3764 IN PRTMP_ADAPTER pAd,
3765 IN MLME_QUEUE_ELEM *Elem);
3766
3767VOID PeerBAAction(
3768 IN PRTMP_ADAPTER pAd,
3769 IN MLME_QUEUE_ELEM *Elem);
3770#endif // DOT11_N_SUPPORT //
3771
3772VOID SendPSMPAction(
3773 IN PRTMP_ADAPTER pAd,
3774 IN UCHAR Wcid,
3775 IN UCHAR Psmp);
3776
3777
3778#ifdef DOT11N_DRAFT3
3779VOID SendBSS2040CoexistMgmtAction(
3780 IN PRTMP_ADAPTER pAd,
3781 IN UCHAR Wcid,
3782 IN UCHAR apidx,
3783 IN UCHAR InfoReq);
3784
3785VOID SendNotifyBWActionFrame(
3786 IN PRTMP_ADAPTER pAd,
3787 IN UCHAR Wcid,
3788 IN UCHAR apidx);
3789
3790BOOLEAN ChannelSwitchSanityCheck(
3791 IN PRTMP_ADAPTER pAd,
3792 IN UCHAR Wcid,
3793 IN UCHAR NewChannel,
3794 IN UCHAR Secondary);
3795
3796VOID ChannelSwitchAction(
3797 IN PRTMP_ADAPTER pAd,
3798 IN UCHAR Wcid,
3799 IN UCHAR Channel,
3800 IN UCHAR Secondary);
3801
3802ULONG BuildIntolerantChannelRep(
3803 IN PRTMP_ADAPTER pAd,
3804 IN PUCHAR pDest);
3805
3806VOID Update2040CoexistFrameAndNotify(
3807 IN PRTMP_ADAPTER pAd,
3808 IN UCHAR Wcid,
3809 IN BOOLEAN bAddIntolerantCha);
3810
3811VOID Send2040CoexistAction(
3812 IN PRTMP_ADAPTER pAd,
3813 IN UCHAR Wcid,
3814 IN BOOLEAN bAddIntolerantCha);
3815#endif // DOT11N_DRAFT3 //
3816
3817VOID PeerRMAction(
3818 IN PRTMP_ADAPTER pAd,
3819 IN MLME_QUEUE_ELEM *Elem);
3820
3821VOID PeerPublicAction(
3822 IN PRTMP_ADAPTER pAd,
3823 IN MLME_QUEUE_ELEM *Elem);
3824
3825#ifdef CONFIG_STA_SUPPORT
3826VOID StaPublicAction(
3827 IN PRTMP_ADAPTER pAd,
3828 IN UCHAR Bss2040Coexist);
3829#endif // CONFIG_STA_SUPPORT //
3830
3831
3832VOID PeerBSSTranAction(
3833 IN PRTMP_ADAPTER pAd,
3834 IN MLME_QUEUE_ELEM *Elem);
3835
3836#ifdef DOT11_N_SUPPORT
3837VOID PeerHTAction(
3838 IN PRTMP_ADAPTER pAd,
3839 IN MLME_QUEUE_ELEM *Elem);
3840#endif // DOT11_N_SUPPORT //
3841
3842VOID PeerQOSAction(
3843 IN PRTMP_ADAPTER pAd,
3844 IN MLME_QUEUE_ELEM *Elem);
3845
3846#ifdef QOS_DLS_SUPPORT
3847VOID PeerDLSAction(
3848 IN PRTMP_ADAPTER pAd,
3849 IN MLME_QUEUE_ELEM *Elem);
3850#endif // QOS_DLS_SUPPORT //
3851
3852#ifdef CONFIG_STA_SUPPORT
3853#ifdef QOS_DLS_SUPPORT
3854VOID DlsParmFill(
3855 IN PRTMP_ADAPTER pAd,
3856 IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
3857 IN PRT_802_11_DLS pDls,
3858 IN USHORT reason);
3859#endif // QOS_DLS_SUPPORT //
3860#endif // CONFIG_STA_SUPPORT //
3861
3862#ifdef DOT11_N_SUPPORT
3863VOID RECBATimerTimeout(
3864 IN PVOID SystemSpecific1,
3865 IN PVOID FunctionContext,
3866 IN PVOID SystemSpecific2,
3867 IN PVOID SystemSpecific3);
3868
3869VOID ORIBATimerTimeout(
3870 IN PRTMP_ADAPTER pAd);
3871
3872VOID SendRefreshBAR(
3873 IN PRTMP_ADAPTER pAd,
3874 IN MAC_TABLE_ENTRY *pEntry);
3875#endif // DOT11_N_SUPPORT //
3876
3877VOID ActHeaderInit(
3878 IN PRTMP_ADAPTER pAd,
3879 IN OUT PHEADER_802_11 pHdr80211,
3880 IN PUCHAR Addr1,
3881 IN PUCHAR Addr2,
3882 IN PUCHAR Addr3);
3883
3884VOID BarHeaderInit(
3885 IN PRTMP_ADAPTER pAd,
3886 IN OUT PFRAME_BAR pCntlBar,
3887 IN PUCHAR pDA,
3888 IN PUCHAR pSA);
3889
3890VOID InsertActField(
3891 IN PRTMP_ADAPTER pAd,
3892 OUT PUCHAR pFrameBuf,
3893 OUT PULONG pFrameLen,
3894 IN UINT8 Category,
3895 IN UINT8 ActCode);
3896
3897BOOLEAN QosBADataParse(
3898 IN PRTMP_ADAPTER pAd,
3899 IN BOOLEAN bAMSDU,
3900 IN PUCHAR p8023Header,
3901 IN UCHAR WCID,
3902 IN UCHAR TID,
3903 IN USHORT Sequence,
3904 IN UCHAR DataOffset,
3905 IN USHORT Datasize,
3906 IN UINT CurRxIndex);
3907
3908#ifdef DOT11_N_SUPPORT
3909BOOLEAN CntlEnqueueForRecv(
3910 IN PRTMP_ADAPTER pAd,
3911 IN ULONG Wcid,
3912 IN ULONG MsgLen,
3913 IN PFRAME_BA_REQ pMsg);
3914
3915VOID BaAutoManSwitch(
3916 IN PRTMP_ADAPTER pAd);
3917#endif // DOT11_N_SUPPORT //
3918
3919VOID HTIOTCheck(
3920 IN PRTMP_ADAPTER pAd,
3921 IN UCHAR BatRecIdx);
3922
3923//
3924// Private routines in rtmp_data.c
3925//
3926BOOLEAN RTMPHandleRxDoneInterrupt(
3927 IN PRTMP_ADAPTER pAd);
3928
3929VOID RTMPHandleTxDoneInterrupt(
3930 IN PRTMP_ADAPTER pAd);
3931
3932BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
3933 IN PRTMP_ADAPTER pAd,
3934 IN INT_SOURCE_CSR_STRUC TxRingBitmap);
3935
3936VOID RTMPHandleMgmtRingDmaDoneInterrupt(
3937 IN PRTMP_ADAPTER pAd);
3938
3939VOID RTMPHandleTBTTInterrupt(
3940 IN PRTMP_ADAPTER pAd);
3941
3942VOID RTMPHandlePreTBTTInterrupt(
3943 IN PRTMP_ADAPTER pAd);
3944
3945void RTMPHandleTwakeupInterrupt(
3946 IN PRTMP_ADAPTER pAd);
3947
3948VOID RTMPHandleRxCoherentInterrupt(
3949 IN PRTMP_ADAPTER pAd);
3950
3951BOOLEAN TxFrameIsAggregatible(
3952 IN PRTMP_ADAPTER pAd,
3953 IN PUCHAR pPrevAddr1,
3954 IN PUCHAR p8023hdr);
3955
3956BOOLEAN PeerIsAggreOn(
3957 IN PRTMP_ADAPTER pAd,
3958 IN ULONG TxRate,
3959 IN PMAC_TABLE_ENTRY pMacEntry);
3960
3961#if 0 // It's not be used
3962HTTRANSMIT_SETTING *GetTxMode(
3963 IN PRTMP_ADAPTER pAd,
3964 IN TX_BLK *pTxBlk);
3965#endif
3966
3967NDIS_STATUS Sniff2BytesFromNdisBuffer(
3968 IN PNDIS_BUFFER pFirstBuffer,
3969 IN UCHAR DesiredOffset,
3970 OUT PUCHAR pByte0,
3971 OUT PUCHAR pByte1);
3972
3973NDIS_STATUS STASendPacket(
3974 IN PRTMP_ADAPTER pAd,
3975 IN PNDIS_PACKET pPacket);
3976
3977VOID STASendPackets(
3978 IN NDIS_HANDLE MiniportAdapterContext,
3979 IN PPNDIS_PACKET ppPacketArray,
3980 IN UINT NumberOfPackets);
3981
3982VOID RTMPDeQueuePacket(
3983 IN PRTMP_ADAPTER pAd,
3984 IN BOOLEAN bIntContext,
3985 IN UCHAR QueIdx,
3986 IN UCHAR Max_Tx_Packets);
3987
3988NDIS_STATUS RTMPHardTransmit(
3989 IN PRTMP_ADAPTER pAd,
3990 IN PNDIS_PACKET pPacket,
3991 IN UCHAR QueIdx,
3992 OUT PULONG pFreeTXDLeft);
3993
3994NDIS_STATUS STAHardTransmit(
3995 IN PRTMP_ADAPTER pAd,
3996 IN TX_BLK *pTxBlk,
3997 IN UCHAR QueIdx);
3998
3999VOID STARxEAPOLFrameIndicate(
4000 IN PRTMP_ADAPTER pAd,
4001 IN MAC_TABLE_ENTRY *pEntry,
4002 IN RX_BLK *pRxBlk,
4003 IN UCHAR FromWhichBSSID);
4004
4005NDIS_STATUS RTMPFreeTXDRequest(
4006 IN PRTMP_ADAPTER pAd,
4007 IN UCHAR RingType,
4008 IN UCHAR NumberRequired,
4009 IN PUCHAR FreeNumberIs);
4010
4011NDIS_STATUS MlmeHardTransmit(
4012 IN PRTMP_ADAPTER pAd,
4013 IN UCHAR QueIdx,
4014 IN PNDIS_PACKET pPacket);
4015
4016NDIS_STATUS MlmeHardTransmitMgmtRing(
4017 IN PRTMP_ADAPTER pAd,
4018 IN UCHAR QueIdx,
4019 IN PNDIS_PACKET pPacket);
4020
4021NDIS_STATUS MlmeHardTransmitTxRing(
4022 IN PRTMP_ADAPTER pAd,
4023 IN UCHAR QueIdx,
4024 IN PNDIS_PACKET pPacket);
4025
4026USHORT RTMPCalcDuration(
4027 IN PRTMP_ADAPTER pAd,
4028 IN UCHAR Rate,
4029 IN ULONG Size);
4030
4031VOID RTMPWriteTxWI(
4032 IN PRTMP_ADAPTER pAd,
4033 IN PTXWI_STRUC pTxWI,
4034 IN BOOLEAN FRAG,
4035 IN BOOLEAN CFACK,
4036 IN BOOLEAN InsTimestamp,
4037 IN BOOLEAN AMPDU,
4038 IN BOOLEAN Ack,
4039 IN BOOLEAN NSeq, // HW new a sequence.
4040 IN UCHAR BASize,
4041 IN UCHAR WCID,
4042 IN ULONG Length,
4043 IN UCHAR PID,
4044 IN UCHAR TID,
4045 IN UCHAR TxRate,
4046 IN UCHAR Txopmode,
4047 IN BOOLEAN CfAck,
4048 IN HTTRANSMIT_SETTING *pTransmit);
4049
4050
4051VOID RTMPWriteTxWI_Data(
4052 IN PRTMP_ADAPTER pAd,
4053 IN OUT PTXWI_STRUC pTxWI,
4054 IN TX_BLK *pTxBlk);
4055
4056
4057VOID RTMPWriteTxWI_Cache(
4058 IN PRTMP_ADAPTER pAd,
4059 IN OUT PTXWI_STRUC pTxWI,
4060 IN TX_BLK *pTxBlk);
4061
4062VOID RTMPWriteTxDescriptor(
4063 IN PRTMP_ADAPTER pAd,
4064 IN PTXD_STRUC pTxD,
4065 IN BOOLEAN bWIV,
4066 IN UCHAR QSEL);
4067
4068VOID RTMPSuspendMsduTransmission(
4069 IN PRTMP_ADAPTER pAd);
4070
4071VOID RTMPResumeMsduTransmission(
4072 IN PRTMP_ADAPTER pAd);
4073
4074NDIS_STATUS MiniportMMRequest(
4075 IN PRTMP_ADAPTER pAd,
4076 IN UCHAR QueIdx,
4077 IN PUCHAR pData,
4078 IN UINT Length);
4079
4080NDIS_STATUS MiniportDataMMRequest(
4081 IN PRTMP_ADAPTER pAd,
4082 IN UCHAR QueIdx,
4083 IN PUCHAR pData,
4084 IN UINT Length);
4085
4086VOID RTMPSendNullFrame(
4087 IN PRTMP_ADAPTER pAd,
4088 IN UCHAR TxRate,
4089 IN BOOLEAN bQosNull);
4090
4091VOID RTMPSendDisassociationFrame(
4092 IN PRTMP_ADAPTER pAd);
4093
4094VOID RTMPSendRTSFrame(
4095 IN PRTMP_ADAPTER pAd,
4096 IN PUCHAR pDA,
4097 IN unsigned int NextMpduSize,
4098 IN UCHAR TxRate,
4099 IN UCHAR RTSRate,
4100 IN USHORT AckDuration,
4101 IN UCHAR QueIdx,
4102 IN UCHAR FrameGap);
4103
4104
4105NDIS_STATUS RTMPApplyPacketFilter(
4106 IN PRTMP_ADAPTER pAd,
4107 IN PRT28XX_RXD_STRUC pRxD,
4108 IN PHEADER_802_11 pHeader);
4109
4110PQUEUE_HEADER RTMPCheckTxSwQueue(
4111 IN PRTMP_ADAPTER pAd,
4112 OUT UCHAR *QueIdx);
4113
4114#ifdef CONFIG_STA_SUPPORT
4115VOID RTMPReportMicError(
4116 IN PRTMP_ADAPTER pAd,
4117 IN PCIPHER_KEY pWpaKey);
4118
4119VOID WpaMicFailureReportFrame(
4120 IN PRTMP_ADAPTER pAd,
4121 IN MLME_QUEUE_ELEM *Elem);
4122
4123VOID WpaDisassocApAndBlockAssoc(
4124 IN PVOID SystemSpecific1,
4125 IN PVOID FunctionContext,
4126 IN PVOID SystemSpecific2,
4127 IN PVOID SystemSpecific3);
4128#endif // CONFIG_STA_SUPPORT //
4129
4130NDIS_STATUS RTMPCloneNdisPacket(
4131 IN PRTMP_ADAPTER pAd,
4132 IN BOOLEAN pInsAMSDUHdr,
4133 IN PNDIS_PACKET pInPacket,
4134 OUT PNDIS_PACKET *ppOutPacket);
4135
4136NDIS_STATUS RTMPAllocateNdisPacket(
4137 IN PRTMP_ADAPTER pAd,
4138 IN PNDIS_PACKET *pPacket,
4139 IN PUCHAR pHeader,
4140 IN UINT HeaderLen,
4141 IN PUCHAR pData,
4142 IN UINT DataLen);
4143
4144VOID RTMPFreeNdisPacket(
4145 IN PRTMP_ADAPTER pAd,
4146 IN PNDIS_PACKET pPacket);
4147
4148BOOLEAN RTMPFreeTXDUponTxDmaDone(
4149 IN PRTMP_ADAPTER pAd,
4150 IN UCHAR QueIdx);
4151
4152BOOLEAN RTMPCheckDHCPFrame(
4153 IN PRTMP_ADAPTER pAd,
4154 IN PNDIS_PACKET pPacket);
4155
4156
4157BOOLEAN RTMPCheckEtherType(
4158 IN PRTMP_ADAPTER pAd,
4159 IN PNDIS_PACKET pPacket);
4160
4161
4162VOID RTMPCckBbpTuning(
4163 IN PRTMP_ADAPTER pAd,
4164 IN UINT TxRate);
4165
4166//
4167// Private routines in rtmp_wep.c
4168//
4169VOID RTMPInitWepEngine(
4170 IN PRTMP_ADAPTER pAd,
4171 IN PUCHAR pKey,
4172 IN UCHAR KeyId,
4173 IN UCHAR KeyLen,
4174 IN PUCHAR pDest);
4175
4176VOID RTMPEncryptData(
4177 IN PRTMP_ADAPTER pAd,
4178 IN PUCHAR pSrc,
4179 IN PUCHAR pDest,
4180 IN UINT Len);
4181
4182BOOLEAN RTMPDecryptData(
4183 IN PRTMP_ADAPTER pAdapter,
4184 IN PUCHAR pSrc,
4185 IN UINT Len,
4186 IN UINT idx);
4187
4188BOOLEAN RTMPSoftDecryptWEP(
4189 IN PRTMP_ADAPTER pAd,
4190 IN PUCHAR pData,
4191 IN ULONG DataByteCnt,
4192 IN PCIPHER_KEY pGroupKey);
4193
4194VOID RTMPSetICV(
4195 IN PRTMP_ADAPTER pAd,
4196 IN PUCHAR pDest);
4197
4198VOID ARCFOUR_INIT(
4199 IN PARCFOURCONTEXT Ctx,
4200 IN PUCHAR pKey,
4201 IN UINT KeyLen);
4202
4203UCHAR ARCFOUR_BYTE(
4204 IN PARCFOURCONTEXT Ctx);
4205
4206VOID ARCFOUR_DECRYPT(
4207 IN PARCFOURCONTEXT Ctx,
4208 IN PUCHAR pDest,
4209 IN PUCHAR pSrc,
4210 IN UINT Len);
4211
4212VOID ARCFOUR_ENCRYPT(
4213 IN PARCFOURCONTEXT Ctx,
4214 IN PUCHAR pDest,
4215 IN PUCHAR pSrc,
4216 IN UINT Len);
4217
4218VOID WPAARCFOUR_ENCRYPT(
4219 IN PARCFOURCONTEXT Ctx,
4220 IN PUCHAR pDest,
4221 IN PUCHAR pSrc,
4222 IN UINT Len);
4223
4224UINT RTMP_CALC_FCS32(
4225 IN UINT Fcs,
4226 IN PUCHAR Cp,
4227 IN INT Len);
4228
4229//
4230// MLME routines
4231//
4232
4233// Asic/RF/BBP related functions
4234
4235VOID AsicAdjustTxPower(
4236 IN PRTMP_ADAPTER pAd);
4237
4238VOID AsicUpdateProtect(
4239 IN PRTMP_ADAPTER pAd,
4240 IN USHORT OperaionMode,
4241 IN UCHAR SetMask,
4242 IN BOOLEAN bDisableBGProtect,
4243 IN BOOLEAN bNonGFExist);
4244
4245VOID AsicSwitchChannel(
4246 IN PRTMP_ADAPTER pAd,
4247 IN UCHAR Channel,
4248 IN BOOLEAN bScan);
4249
4250VOID AsicLockChannel(
4251 IN PRTMP_ADAPTER pAd,
4252 IN UCHAR Channel) ;
4253
4254VOID AsicAntennaSelect(
4255 IN PRTMP_ADAPTER pAd,
4256 IN UCHAR Channel);
4257
4258VOID AsicAntennaSetting(
4259 IN PRTMP_ADAPTER pAd,
4260 IN ABGBAND_STATE BandState);
4261
4262VOID AsicRfTuningExec(
4263 IN PVOID SystemSpecific1,
4264 IN PVOID FunctionContext,
4265 IN PVOID SystemSpecific2,
4266 IN PVOID SystemSpecific3);
4267
4268#ifdef CONFIG_STA_SUPPORT
4269VOID AsicSleepThenAutoWakeup(
4270 IN PRTMP_ADAPTER pAd,
4271 IN USHORT TbttNumToNextWakeUp);
4272
4273VOID AsicForceSleep(
4274 IN PRTMP_ADAPTER pAd);
4275
4276VOID AsicForceWakeup(
4277 IN PRTMP_ADAPTER pAd,
4278 IN BOOLEAN bFromTx);
4279#endif // CONFIG_STA_SUPPORT //
4280
4281VOID AsicSetBssid(
4282 IN PRTMP_ADAPTER pAd,
4283 IN PUCHAR pBssid);
4284
4285VOID AsicSetMcastWC(
4286 IN PRTMP_ADAPTER pAd);
4287
4288#if 0 // removed by AlbertY
4289VOID AsicSetBssidWC(
4290 IN PRTMP_ADAPTER pAd,
4291 IN PUCHAR pBssid);
4292#endif
4293
4294VOID AsicDelWcidTab(
4295 IN PRTMP_ADAPTER pAd,
4296 IN UCHAR Wcid);
4297
4298VOID AsicEnableRDG(
4299 IN PRTMP_ADAPTER pAd);
4300
4301VOID AsicDisableRDG(
4302 IN PRTMP_ADAPTER pAd);
4303
4304VOID AsicDisableSync(
4305 IN PRTMP_ADAPTER pAd);
4306
4307VOID AsicEnableBssSync(
4308 IN PRTMP_ADAPTER pAd);
4309
4310VOID AsicEnableIbssSync(
4311 IN PRTMP_ADAPTER pAd);
4312
4313VOID AsicSetEdcaParm(
4314 IN PRTMP_ADAPTER pAd,
4315 IN PEDCA_PARM pEdcaParm);
4316
4317VOID AsicSetSlotTime(
4318 IN PRTMP_ADAPTER pAd,
4319 IN BOOLEAN bUseShortSlotTime);
4320
4321#if 0
4322VOID AsicAddWcidCipherEntry(
4323 IN PRTMP_ADAPTER pAd,
4324 IN UCHAR WCID,
4325 IN UCHAR BssIndex,
4326 IN UCHAR KeyTable,
4327 IN UCHAR CipherAlg,
4328 IN PUCHAR pAddr,
4329 IN CIPHER_KEY *pCipherKey);
4330#endif
4331
4332VOID AsicAddSharedKeyEntry(
4333 IN PRTMP_ADAPTER pAd,
4334 IN UCHAR BssIndex,
4335 IN UCHAR KeyIdx,
4336 IN UCHAR CipherAlg,
4337 IN PUCHAR pKey,
4338 IN PUCHAR pTxMic,
4339 IN PUCHAR pRxMic);
4340
4341VOID AsicRemoveSharedKeyEntry(
4342 IN PRTMP_ADAPTER pAd,
4343 IN UCHAR BssIndex,
4344 IN UCHAR KeyIdx);
4345
4346VOID AsicUpdateWCIDAttribute(
4347 IN PRTMP_ADAPTER pAd,
4348 IN USHORT WCID,
4349 IN UCHAR BssIndex,
4350 IN UCHAR CipherAlg,
4351 IN BOOLEAN bUsePairewiseKeyTable);
4352
4353VOID AsicUpdateWCIDIVEIV(
4354 IN PRTMP_ADAPTER pAd,
4355 IN USHORT WCID,
4356 IN ULONG uIV,
4357 IN ULONG uEIV);
4358
4359VOID AsicUpdateRxWCIDTable(
4360 IN PRTMP_ADAPTER pAd,
4361 IN USHORT WCID,
4362 IN PUCHAR pAddr);
4363
4364VOID AsicAddKeyEntry(
4365 IN PRTMP_ADAPTER pAd,
4366 IN USHORT WCID,
4367 IN UCHAR BssIndex,
4368 IN UCHAR KeyIdx,
4369 IN PCIPHER_KEY pCipherKey,
4370 IN BOOLEAN bUsePairewiseKeyTable,
4371 IN BOOLEAN bTxKey);
4372
4373VOID AsicAddPairwiseKeyEntry(
4374 IN PRTMP_ADAPTER pAd,
4375 IN PUCHAR pAddr,
4376 IN UCHAR WCID,
4377 IN CIPHER_KEY *pCipherKey);
4378
4379VOID AsicRemovePairwiseKeyEntry(
4380 IN PRTMP_ADAPTER pAd,
4381 IN UCHAR BssIdx,
4382 IN UCHAR Wcid);
4383
4384BOOLEAN AsicSendCommandToMcu(
4385 IN PRTMP_ADAPTER pAd,
4386 IN UCHAR Command,
4387 IN UCHAR Token,
4388 IN UCHAR Arg0,
4389 IN UCHAR Arg1);
4390
4391
4392VOID MacAddrRandomBssid(
4393 IN PRTMP_ADAPTER pAd,
4394 OUT PUCHAR pAddr);
4395
4396VOID MgtMacHeaderInit(
4397 IN PRTMP_ADAPTER pAd,
4398 IN OUT PHEADER_802_11 pHdr80211,
4399 IN UCHAR SubType,
4400 IN UCHAR ToDs,
4401 IN PUCHAR pDA,
4402 IN PUCHAR pBssid);
4403
4404VOID MlmeRadioOff(
4405 IN PRTMP_ADAPTER pAd);
4406
4407VOID MlmeRadioOn(
4408 IN PRTMP_ADAPTER pAd);
4409
4410
4411VOID BssTableInit(
4412 IN BSS_TABLE *Tab);
4413
4414#ifdef DOT11_N_SUPPORT
4415VOID BATableInit(
4416 IN PRTMP_ADAPTER pAd,
4417 IN BA_TABLE *Tab);
4418#endif // DOT11_N_SUPPORT //
4419
4420ULONG BssTableSearch(
4421 IN BSS_TABLE *Tab,
4422 IN PUCHAR pBssid,
4423 IN UCHAR Channel);
4424
4425ULONG BssSsidTableSearch(
4426 IN BSS_TABLE *Tab,
4427 IN PUCHAR pBssid,
4428 IN PUCHAR pSsid,
4429 IN UCHAR SsidLen,
4430 IN UCHAR Channel);
4431
4432ULONG BssTableSearchWithSSID(
4433 IN BSS_TABLE *Tab,
4434 IN PUCHAR Bssid,
4435 IN PUCHAR pSsid,
4436 IN UCHAR SsidLen,
4437 IN UCHAR Channel);
4438
4439VOID BssTableDeleteEntry(
4440 IN OUT PBSS_TABLE pTab,
4441 IN PUCHAR pBssid,
4442 IN UCHAR Channel);
4443
4444#ifdef DOT11_N_SUPPORT
4445VOID BATableDeleteORIEntry(
4446 IN OUT PRTMP_ADAPTER pAd,
4447 IN BA_ORI_ENTRY *pBAORIEntry);
4448
4449VOID BATableDeleteRECEntry(
4450 IN OUT PRTMP_ADAPTER pAd,
4451 IN BA_REC_ENTRY *pBARECEntry);
4452
4453VOID BATableTearORIEntry(
4454 IN OUT PRTMP_ADAPTER pAd,
4455 IN UCHAR TID,
4456 IN UCHAR Wcid,
4457 IN BOOLEAN bForceDelete,
4458 IN BOOLEAN ALL);
4459
4460VOID BATableTearRECEntry(
4461 IN OUT PRTMP_ADAPTER pAd,
4462 IN UCHAR TID,
4463 IN UCHAR WCID,
4464 IN BOOLEAN ALL);
4465#endif // DOT11_N_SUPPORT //
4466
4467VOID BssEntrySet(
4468 IN PRTMP_ADAPTER pAd,
4469 OUT PBSS_ENTRY pBss,
4470 IN PUCHAR pBssid,
4471 IN CHAR Ssid[],
4472 IN UCHAR SsidLen,
4473 IN UCHAR BssType,
4474 IN USHORT BeaconPeriod,
4475 IN PCF_PARM CfParm,
4476 IN USHORT AtimWin,
4477 IN USHORT CapabilityInfo,
4478 IN UCHAR SupRate[],
4479 IN UCHAR SupRateLen,
4480 IN UCHAR ExtRate[],
4481 IN UCHAR ExtRateLen,
4482 IN HT_CAPABILITY_IE *pHtCapability,
4483 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
4484 IN UCHAR HtCapabilityLen,
4485 IN UCHAR AddHtInfoLen,
4486 IN UCHAR NewExtChanOffset,
4487 IN UCHAR Channel,
4488 IN CHAR Rssi,
4489 IN LARGE_INTEGER TimeStamp,
4490 IN UCHAR CkipFlag,
4491 IN PEDCA_PARM pEdcaParm,
4492 IN PQOS_CAPABILITY_PARM pQosCapability,
4493 IN PQBSS_LOAD_PARM pQbssLoad,
4494 IN USHORT LengthVIE,
4495 IN PNDIS_802_11_VARIABLE_IEs pVIE);
4496
4497ULONG BssTableSetEntry(
4498 IN PRTMP_ADAPTER pAd,
4499 OUT PBSS_TABLE pTab,
4500 IN PUCHAR pBssid,
4501 IN CHAR Ssid[],
4502 IN UCHAR SsidLen,
4503 IN UCHAR BssType,
4504 IN USHORT BeaconPeriod,
4505 IN CF_PARM *CfParm,
4506 IN USHORT AtimWin,
4507 IN USHORT CapabilityInfo,
4508 IN UCHAR SupRate[],
4509 IN UCHAR SupRateLen,
4510 IN UCHAR ExtRate[],
4511 IN UCHAR ExtRateLen,
4512 IN HT_CAPABILITY_IE *pHtCapability,
4513 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
4514 IN UCHAR HtCapabilityLen,
4515 IN UCHAR AddHtInfoLen,
4516 IN UCHAR NewExtChanOffset,
4517 IN UCHAR Channel,
4518 IN CHAR Rssi,
4519 IN LARGE_INTEGER TimeStamp,
4520 IN UCHAR CkipFlag,
4521 IN PEDCA_PARM pEdcaParm,
4522 IN PQOS_CAPABILITY_PARM pQosCapability,
4523 IN PQBSS_LOAD_PARM pQbssLoad,
4524 IN USHORT LengthVIE,
4525 IN PNDIS_802_11_VARIABLE_IEs pVIE);
4526
4527#ifdef DOT11_N_SUPPORT
4528VOID BATableInsertEntry(
4529 IN PRTMP_ADAPTER pAd,
4530 IN USHORT Aid,
4531 IN USHORT TimeOutValue,
4532 IN USHORT StartingSeq,
4533 IN UCHAR TID,
4534 IN UCHAR BAWinSize,
4535 IN UCHAR OriginatorStatus,
4536 IN BOOLEAN IsRecipient);
4537
4538#ifdef DOT11N_DRAFT3
4539VOID Bss2040CoexistTimeOut(
4540 IN PVOID SystemSpecific1,
4541 IN PVOID FunctionContext,
4542 IN PVOID SystemSpecific2,
4543 IN PVOID SystemSpecific3);
4544
4545
4546VOID TriEventInit(
4547 IN PRTMP_ADAPTER pAd);
4548
4549ULONG TriEventTableSetEntry(
4550 IN PRTMP_ADAPTER pAd,
4551 OUT TRIGGER_EVENT_TAB *Tab,
4552 IN PUCHAR pBssid,
4553 IN HT_CAPABILITY_IE *pHtCapability,
4554 IN UCHAR HtCapabilityLen,
4555 IN UCHAR RegClass,
4556 IN UCHAR ChannelNo);
4557
4558VOID TriEventCounterMaintenance(
4559 IN PRTMP_ADAPTER pAd);
4560#endif // DOT11N_DRAFT3 //
4561#endif // DOT11_N_SUPPORT //
4562
4563VOID BssTableSsidSort(
4564 IN PRTMP_ADAPTER pAd,
4565 OUT BSS_TABLE *OutTab,
4566 IN CHAR Ssid[],
4567 IN UCHAR SsidLen);
4568
4569VOID BssTableSortByRssi(
4570 IN OUT BSS_TABLE *OutTab);
4571
4572VOID BssCipherParse(
4573 IN OUT PBSS_ENTRY pBss);
4574
4575NDIS_STATUS MlmeQueueInit(
4576 IN MLME_QUEUE *Queue);
4577
4578VOID MlmeQueueDestroy(
4579 IN MLME_QUEUE *Queue);
4580
4581BOOLEAN MlmeEnqueue(
4582 IN PRTMP_ADAPTER pAd,
4583 IN ULONG Machine,
4584 IN ULONG MsgType,
4585 IN ULONG MsgLen,
4586 IN VOID *Msg);
4587
4588BOOLEAN MlmeEnqueueForRecv(
4589 IN PRTMP_ADAPTER pAd,
4590 IN ULONG Wcid,
4591 IN ULONG TimeStampHigh,
4592 IN ULONG TimeStampLow,
4593 IN UCHAR Rssi0,
4594 IN UCHAR Rssi1,
4595 IN UCHAR Rssi2,
4596 IN ULONG MsgLen,
4597 IN PVOID Msg,
4598 IN UCHAR Signal);
4599
4600
4601BOOLEAN MlmeDequeue(
4602 IN MLME_QUEUE *Queue,
4603 OUT MLME_QUEUE_ELEM **Elem);
4604
4605VOID MlmeRestartStateMachine(
4606 IN PRTMP_ADAPTER pAd);
4607
4608BOOLEAN MlmeQueueEmpty(
4609 IN MLME_QUEUE *Queue);
4610
4611BOOLEAN MlmeQueueFull(
4612 IN MLME_QUEUE *Queue);
4613
4614BOOLEAN MsgTypeSubst(
4615 IN PRTMP_ADAPTER pAd,
4616 IN PFRAME_802_11 pFrame,
4617 OUT INT *Machine,
4618 OUT INT *MsgType);
4619
4620VOID StateMachineInit(
4621 IN STATE_MACHINE *Sm,
4622 IN STATE_MACHINE_FUNC Trans[],
4623 IN ULONG StNr,
4624 IN ULONG MsgNr,
4625 IN STATE_MACHINE_FUNC DefFunc,
4626 IN ULONG InitState,
4627 IN ULONG Base);
4628
4629VOID StateMachineSetAction(
4630 IN STATE_MACHINE *S,
4631 IN ULONG St,
4632 ULONG Msg,
4633 IN STATE_MACHINE_FUNC F);
4634
4635VOID StateMachinePerformAction(
4636 IN PRTMP_ADAPTER pAd,
4637 IN STATE_MACHINE *S,
4638 IN MLME_QUEUE_ELEM *Elem);
4639
4640VOID Drop(
4641 IN PRTMP_ADAPTER pAd,
4642 IN MLME_QUEUE_ELEM *Elem);
4643
4644VOID AssocStateMachineInit(
4645 IN PRTMP_ADAPTER pAd,
4646 IN STATE_MACHINE *Sm,
4647 OUT STATE_MACHINE_FUNC Trans[]);
4648
4649VOID ReassocTimeout(
4650 IN PVOID SystemSpecific1,
4651 IN PVOID FunctionContext,
4652 IN PVOID SystemSpecific2,
4653 IN PVOID SystemSpecific3);
4654
4655VOID AssocTimeout(
4656 IN PVOID SystemSpecific1,
4657 IN PVOID FunctionContext,
4658 IN PVOID SystemSpecific2,
4659 IN PVOID SystemSpecific3);
4660
4661VOID DisassocTimeout(
4662 IN PVOID SystemSpecific1,
4663 IN PVOID FunctionContext,
4664 IN PVOID SystemSpecific2,
4665 IN PVOID SystemSpecific3);
4666
4667//----------------------------------------------
4668VOID MlmeDisassocReqAction(
4669 IN PRTMP_ADAPTER pAd,
4670 IN MLME_QUEUE_ELEM *Elem);
4671
4672VOID MlmeAssocReqAction(
4673 IN PRTMP_ADAPTER pAd,
4674 IN MLME_QUEUE_ELEM *Elem);
4675
4676VOID MlmeReassocReqAction(
4677 IN PRTMP_ADAPTER pAd,
4678 IN MLME_QUEUE_ELEM *Elem);
4679
4680VOID MlmeDisassocReqAction(
4681 IN PRTMP_ADAPTER pAd,
4682 IN MLME_QUEUE_ELEM *Elem);
4683
4684VOID PeerAssocRspAction(
4685 IN PRTMP_ADAPTER pAd,
4686 IN MLME_QUEUE_ELEM *Elem);
4687
4688VOID PeerReassocRspAction(
4689 IN PRTMP_ADAPTER pAd,
4690 IN MLME_QUEUE_ELEM *Elem);
4691
4692VOID PeerDisassocAction(
4693 IN PRTMP_ADAPTER pAd,
4694 IN MLME_QUEUE_ELEM *Elem);
4695
4696VOID DisassocTimeoutAction(
4697 IN PRTMP_ADAPTER pAd,
4698 IN MLME_QUEUE_ELEM *Elem);
4699
4700VOID AssocTimeoutAction(
4701 IN PRTMP_ADAPTER pAd,
4702 IN MLME_QUEUE_ELEM *Elem);
4703
4704VOID ReassocTimeoutAction(
4705 IN PRTMP_ADAPTER pAd,
4706 IN MLME_QUEUE_ELEM *Elem);
4707
4708VOID Cls3errAction(
4709 IN PRTMP_ADAPTER pAd,
4710 IN PUCHAR pAddr);
4711
4712VOID SwitchBetweenWepAndCkip(
4713 IN PRTMP_ADAPTER pAd);
4714
4715VOID InvalidStateWhenAssoc(
4716 IN PRTMP_ADAPTER pAd,
4717 IN MLME_QUEUE_ELEM *Elem);
4718
4719VOID InvalidStateWhenReassoc(
4720 IN PRTMP_ADAPTER pAd,
4721 IN MLME_QUEUE_ELEM *Elem);
4722
4723VOID InvalidStateWhenDisassociate(
4724 IN PRTMP_ADAPTER pAd,
4725 IN MLME_QUEUE_ELEM *Elem);
4726
4727#ifdef RT2870
4728VOID MlmeCntlConfirm(
4729 IN PRTMP_ADAPTER pAd,
4730 IN ULONG MsgType,
4731 IN USHORT Msg);
4732#endif // RT2870 //
4733
4734VOID ComposePsPoll(
4735 IN PRTMP_ADAPTER pAd);
4736
4737VOID ComposeNullFrame(
4738 IN PRTMP_ADAPTER pAd);
4739
4740VOID AssocPostProc(
4741 IN PRTMP_ADAPTER pAd,
4742 IN PUCHAR pAddr2,
4743 IN USHORT CapabilityInfo,
4744 IN USHORT Aid,
4745 IN UCHAR SupRate[],
4746 IN UCHAR SupRateLen,
4747 IN UCHAR ExtRate[],
4748 IN UCHAR ExtRateLen,
4749 IN PEDCA_PARM pEdcaParm,
4750 IN HT_CAPABILITY_IE *pHtCapability,
4751 IN UCHAR HtCapabilityLen,
4752 IN ADD_HT_INFO_IE *pAddHtInfo);
4753
4754VOID AuthStateMachineInit(
4755 IN PRTMP_ADAPTER pAd,
4756 IN PSTATE_MACHINE sm,
4757 OUT STATE_MACHINE_FUNC Trans[]);
4758
4759VOID AuthTimeout(
4760 IN PVOID SystemSpecific1,
4761 IN PVOID FunctionContext,
4762 IN PVOID SystemSpecific2,
4763 IN PVOID SystemSpecific3);
4764
4765VOID MlmeAuthReqAction(
4766 IN PRTMP_ADAPTER pAd,
4767 IN MLME_QUEUE_ELEM *Elem);
4768
4769VOID PeerAuthRspAtSeq2Action(
4770 IN PRTMP_ADAPTER pAd,
4771 IN MLME_QUEUE_ELEM *Elem);
4772
4773VOID PeerAuthRspAtSeq4Action(
4774 IN PRTMP_ADAPTER pAd,
4775 IN MLME_QUEUE_ELEM *Elem);
4776
4777VOID AuthTimeoutAction(
4778 IN PRTMP_ADAPTER pAd,
4779 IN MLME_QUEUE_ELEM *Elem);
4780
4781VOID Cls2errAction(
4782 IN PRTMP_ADAPTER pAd,
4783 IN PUCHAR pAddr);
4784
4785VOID MlmeDeauthReqAction(
4786 IN PRTMP_ADAPTER pAd,
4787 IN MLME_QUEUE_ELEM *Elem);
4788
4789VOID InvalidStateWhenAuth(
4790 IN PRTMP_ADAPTER pAd,
4791 IN MLME_QUEUE_ELEM *Elem);
4792
4793//=============================================
4794
4795VOID AuthRspStateMachineInit(
4796 IN PRTMP_ADAPTER pAd,
4797 IN PSTATE_MACHINE Sm,
4798 IN STATE_MACHINE_FUNC Trans[]);
4799
4800VOID PeerDeauthAction(
4801 IN PRTMP_ADAPTER pAd,
4802 IN MLME_QUEUE_ELEM *Elem);
4803
4804VOID PeerAuthSimpleRspGenAndSend(
4805 IN PRTMP_ADAPTER pAd,
4806 IN PHEADER_802_11 pHdr80211,
4807 IN USHORT Alg,
4808 IN USHORT Seq,
4809 IN USHORT Reason,
4810 IN USHORT Status);
4811
4812//
4813// Private routines in dls.c
4814//
4815
4816#ifdef CONFIG_STA_SUPPORT
4817#ifdef QOS_DLS_SUPPORT
4818void DlsStateMachineInit(
4819 IN PRTMP_ADAPTER pAd,
4820 IN STATE_MACHINE *Sm,
4821 OUT STATE_MACHINE_FUNC Trans[]);
4822
4823VOID MlmeDlsReqAction(
4824 IN PRTMP_ADAPTER pAd,
4825 IN MLME_QUEUE_ELEM *Elem);
4826
4827VOID PeerDlsReqAction(
4828 IN PRTMP_ADAPTER pAd,
4829 IN MLME_QUEUE_ELEM *Elem);
4830
4831VOID PeerDlsRspAction(
4832 IN PRTMP_ADAPTER pAd,
4833 IN MLME_QUEUE_ELEM *Elem);
4834
4835VOID MlmeDlsTearDownAction(
4836 IN PRTMP_ADAPTER pAd,
4837 IN MLME_QUEUE_ELEM *Elem);
4838
4839VOID PeerDlsTearDownAction(
4840 IN PRTMP_ADAPTER pAd,
4841 IN MLME_QUEUE_ELEM *Elem);
4842
4843VOID RTMPCheckDLSTimeOut(
4844 IN PRTMP_ADAPTER pAd);
4845
4846BOOLEAN RTMPRcvFrameDLSCheck(
4847 IN PRTMP_ADAPTER pAd,
4848 IN PHEADER_802_11 pHeader,
4849 IN ULONG Len,
4850 IN PRT28XX_RXD_STRUC pRxD);
4851
4852INT RTMPCheckDLSFrame(
4853 IN PRTMP_ADAPTER pAd,
4854 IN PUCHAR pDA);
4855
4856VOID RTMPSendDLSTearDownFrame(
4857 IN PRTMP_ADAPTER pAd,
4858 IN PUCHAR pDA);
4859
4860NDIS_STATUS RTMPSendSTAKeyRequest(
4861 IN PRTMP_ADAPTER pAd,
4862 IN PUCHAR pDA);
4863
4864NDIS_STATUS RTMPSendSTAKeyHandShake(
4865 IN PRTMP_ADAPTER pAd,
4866 IN PUCHAR pDA);
4867
4868VOID DlsTimeoutAction(
4869 IN PVOID SystemSpecific1,
4870 IN PVOID FunctionContext,
4871 IN PVOID SystemSpecific2,
4872 IN PVOID SystemSpecific3);
4873
4874BOOLEAN MlmeDlsReqSanity(
4875 IN PRTMP_ADAPTER pAd,
4876 IN VOID *Msg,
4877 IN ULONG MsgLen,
4878 OUT PRT_802_11_DLS *pDLS,
4879 OUT PUSHORT pReason);
4880
4881INT Set_DlsEntryInfo_Display_Proc(
4882 IN PRTMP_ADAPTER pAd,
4883 IN PUCHAR arg);
4884
4885MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
4886 IN PRTMP_ADAPTER pAd,
4887 IN PUCHAR pAddr,
4888 IN UINT DlsEntryIdx);
4889
4890BOOLEAN MacTableDeleteDlsEntry(
4891 IN PRTMP_ADAPTER pAd,
4892 IN USHORT wcid,
4893 IN PUCHAR pAddr);
4894
4895MAC_TABLE_ENTRY *DlsEntryTableLookup(
4896 IN PRTMP_ADAPTER pAd,
4897 IN PUCHAR pAddr,
4898 IN BOOLEAN bResetIdelCount);
4899
4900MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
4901 IN PRTMP_ADAPTER pAd,
4902 IN UCHAR wcid,
4903 IN PUCHAR pAddr,
4904 IN BOOLEAN bResetIdelCount);
4905
4906INT Set_DlsAddEntry_Proc(
4907 IN PRTMP_ADAPTER pAd,
4908 IN PUCHAR arg);
4909
4910INT Set_DlsTearDownEntry_Proc(
4911 IN PRTMP_ADAPTER pAd,
4912 IN PUCHAR arg);
4913#endif // QOS_DLS_SUPPORT //
4914#endif // CONFIG_STA_SUPPORT //
4915
4916#ifdef QOS_DLS_SUPPORT
4917BOOLEAN PeerDlsReqSanity(
4918 IN PRTMP_ADAPTER pAd,
4919 IN VOID *Msg,
4920 IN ULONG MsgLen,
4921 OUT PUCHAR pDA,
4922 OUT PUCHAR pSA,
4923 OUT USHORT *pCapabilityInfo,
4924 OUT USHORT *pDlsTimeout,
4925 OUT UCHAR *pRatesLen,
4926 OUT UCHAR Rates[],
4927 OUT UCHAR *pHtCapabilityLen,
4928 OUT HT_CAPABILITY_IE *pHtCapability);
4929
4930BOOLEAN PeerDlsRspSanity(
4931 IN PRTMP_ADAPTER pAd,
4932 IN VOID *Msg,
4933 IN ULONG MsgLen,
4934 OUT PUCHAR pDA,
4935 OUT PUCHAR pSA,
4936 OUT USHORT *pCapabilityInfo,
4937 OUT USHORT *pStatus,
4938 OUT UCHAR *pRatesLen,
4939 OUT UCHAR Rates[],
4940 OUT UCHAR *pHtCapabilityLen,
4941 OUT HT_CAPABILITY_IE *pHtCapability);
4942
4943BOOLEAN PeerDlsTearDownSanity(
4944 IN PRTMP_ADAPTER pAd,
4945 IN VOID *Msg,
4946 IN ULONG MsgLen,
4947 OUT PUCHAR pDA,
4948 OUT PUCHAR pSA,
4949 OUT USHORT *pReason);
4950#endif // QOS_DLS_SUPPORT //
4951
4952//========================================
4953
4954VOID SyncStateMachineInit(
4955 IN PRTMP_ADAPTER pAd,
4956 IN STATE_MACHINE *Sm,
4957 OUT STATE_MACHINE_FUNC Trans[]);
4958
4959VOID BeaconTimeout(
4960 IN PVOID SystemSpecific1,
4961 IN PVOID FunctionContext,
4962 IN PVOID SystemSpecific2,
4963 IN PVOID SystemSpecific3);
4964
4965VOID ScanTimeout(
4966 IN PVOID SystemSpecific1,
4967 IN PVOID FunctionContext,
4968 IN PVOID SystemSpecific2,
4969 IN PVOID SystemSpecific3);
4970
4971VOID MlmeScanReqAction(
4972 IN PRTMP_ADAPTER pAd,
4973 IN MLME_QUEUE_ELEM *Elem);
4974
4975VOID InvalidStateWhenScan(
4976 IN PRTMP_ADAPTER pAd,
4977 IN MLME_QUEUE_ELEM *Elem);
4978
4979VOID InvalidStateWhenJoin(
4980 IN PRTMP_ADAPTER pAd,
4981 IN MLME_QUEUE_ELEM *Elem);
4982
4983VOID InvalidStateWhenStart(
4984 IN PRTMP_ADAPTER pAd,
4985 IN MLME_QUEUE_ELEM *Elem);
4986
4987VOID PeerBeacon(
4988 IN PRTMP_ADAPTER pAd,
4989 IN MLME_QUEUE_ELEM *Elem);
4990
4991VOID EnqueueProbeRequest(
4992 IN PRTMP_ADAPTER pAd);
4993
4994BOOLEAN ScanRunning(
4995 IN PRTMP_ADAPTER pAd);
4996//=========================================
4997
4998VOID MlmeCntlInit(
4999 IN PRTMP_ADAPTER pAd,
5000 IN STATE_MACHINE *S,
5001 OUT STATE_MACHINE_FUNC Trans[]);
5002
5003VOID MlmeCntlMachinePerformAction(
5004 IN PRTMP_ADAPTER pAd,
5005 IN STATE_MACHINE *S,
5006 IN MLME_QUEUE_ELEM *Elem);
5007
5008VOID CntlIdleProc(
5009 IN PRTMP_ADAPTER pAd,
5010 IN MLME_QUEUE_ELEM *Elem);
5011
5012VOID CntlOidScanProc(
5013 IN PRTMP_ADAPTER pAd,
5014 IN MLME_QUEUE_ELEM *Elem);
5015
5016VOID CntlOidSsidProc(
5017 IN PRTMP_ADAPTER pAd,
5018 IN MLME_QUEUE_ELEM * Elem);
5019
5020VOID CntlOidRTBssidProc(
5021 IN PRTMP_ADAPTER pAd,
5022 IN MLME_QUEUE_ELEM * Elem);
5023
5024VOID CntlMlmeRoamingProc(
5025 IN PRTMP_ADAPTER pAd,
5026 IN MLME_QUEUE_ELEM * Elem);
5027
5028VOID CntlWaitDisassocProc(
5029 IN PRTMP_ADAPTER pAd,
5030 IN MLME_QUEUE_ELEM *Elem);
5031
5032VOID CntlWaitJoinProc(
5033 IN PRTMP_ADAPTER pAd,
5034 IN MLME_QUEUE_ELEM *Elem);
5035
5036VOID CntlWaitReassocProc(
5037 IN PRTMP_ADAPTER pAd,
5038 IN MLME_QUEUE_ELEM *Elem);
5039
5040VOID CntlWaitStartProc(
5041 IN PRTMP_ADAPTER pAd,
5042 IN MLME_QUEUE_ELEM *Elem);
5043
5044VOID CntlWaitAuthProc(
5045 IN PRTMP_ADAPTER pAd,
5046 IN MLME_QUEUE_ELEM *Elem);
5047
5048VOID CntlWaitAuthProc2(
5049 IN PRTMP_ADAPTER pAd,
5050 IN MLME_QUEUE_ELEM *Elem);
5051
5052VOID CntlWaitAssocProc(
5053 IN PRTMP_ADAPTER pAd,
5054 IN MLME_QUEUE_ELEM *Elem);
5055
5056#ifdef QOS_DLS_SUPPORT
5057VOID CntlOidDLSSetupProc(
5058 IN PRTMP_ADAPTER pAd,
5059 IN MLME_QUEUE_ELEM *Elem);
5060#endif // QOS_DLS_SUPPORT //
5061
5062VOID LinkUp(
5063 IN PRTMP_ADAPTER pAd,
5064 IN UCHAR BssType);
5065
5066VOID LinkDown(
5067 IN PRTMP_ADAPTER pAd,
5068 IN BOOLEAN IsReqFromAP);
5069
5070VOID IterateOnBssTab(
5071 IN PRTMP_ADAPTER pAd);
5072
5073VOID IterateOnBssTab2(
5074 IN PRTMP_ADAPTER pAd);;
5075
5076VOID JoinParmFill(
5077 IN PRTMP_ADAPTER pAd,
5078 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
5079 IN ULONG BssIdx);
5080
5081VOID AssocParmFill(
5082 IN PRTMP_ADAPTER pAd,
5083 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
5084 IN PUCHAR pAddr,
5085 IN USHORT CapabilityInfo,
5086 IN ULONG Timeout,
5087 IN USHORT ListenIntv);
5088
5089VOID ScanParmFill(
5090 IN PRTMP_ADAPTER pAd,
5091 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
5092 IN CHAR Ssid[],
5093 IN UCHAR SsidLen,
5094 IN UCHAR BssType,
5095 IN UCHAR ScanType);
5096
5097VOID DisassocParmFill(
5098 IN PRTMP_ADAPTER pAd,
5099 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
5100 IN PUCHAR pAddr,
5101 IN USHORT Reason);
5102
5103VOID StartParmFill(
5104 IN PRTMP_ADAPTER pAd,
5105 IN OUT MLME_START_REQ_STRUCT *StartReq,
5106 IN CHAR Ssid[],
5107 IN UCHAR SsidLen);
5108
5109VOID AuthParmFill(
5110 IN PRTMP_ADAPTER pAd,
5111 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
5112 IN PUCHAR pAddr,
5113 IN USHORT Alg);
5114
5115VOID EnqueuePsPoll(
5116 IN PRTMP_ADAPTER pAd);
5117
5118VOID EnqueueBeaconFrame(
5119 IN PRTMP_ADAPTER pAd);
5120
5121VOID MlmeJoinReqAction(
5122 IN PRTMP_ADAPTER pAd,
5123 IN MLME_QUEUE_ELEM *Elem);
5124
5125VOID MlmeScanReqAction(
5126 IN PRTMP_ADAPTER pAd,
5127 IN MLME_QUEUE_ELEM *Elem);
5128
5129VOID MlmeStartReqAction(
5130 IN PRTMP_ADAPTER pAd,
5131 IN MLME_QUEUE_ELEM *Elem);
5132
5133VOID ScanTimeoutAction(
5134 IN PRTMP_ADAPTER pAd,
5135 IN MLME_QUEUE_ELEM *Elem);
5136
5137VOID BeaconTimeoutAtJoinAction(
5138 IN PRTMP_ADAPTER pAd,
5139 IN MLME_QUEUE_ELEM *Elem);
5140
5141VOID PeerBeaconAtScanAction(
5142 IN PRTMP_ADAPTER pAd,
5143 IN MLME_QUEUE_ELEM *Elem);
5144
5145VOID PeerBeaconAtJoinAction(
5146 IN PRTMP_ADAPTER pAd,
5147 IN MLME_QUEUE_ELEM *Elem);
5148
5149VOID PeerBeacon(
5150 IN PRTMP_ADAPTER pAd,
5151 IN MLME_QUEUE_ELEM *Elem);
5152
5153VOID PeerProbeReqAction(
5154 IN PRTMP_ADAPTER pAd,
5155 IN MLME_QUEUE_ELEM *Elem);
5156
5157VOID ScanNextChannel(
5158 IN PRTMP_ADAPTER pAd);
5159
5160ULONG MakeIbssBeacon(
5161 IN PRTMP_ADAPTER pAd);
5162
5163VOID CCXAdjacentAPReport(
5164 IN PRTMP_ADAPTER pAd);
5165
5166BOOLEAN MlmeScanReqSanity(
5167 IN PRTMP_ADAPTER pAd,
5168 IN VOID *Msg,
5169 IN ULONG MsgLen,
5170 OUT UCHAR *BssType,
5171 OUT CHAR ssid[],
5172 OUT UCHAR *SsidLen,
5173 OUT UCHAR *ScanType);
5174
5175BOOLEAN PeerBeaconAndProbeRspSanity(
5176 IN PRTMP_ADAPTER pAd,
5177 IN VOID *Msg,
5178 IN ULONG MsgLen,
5179 IN UCHAR MsgChannel,
5180 OUT PUCHAR pAddr2,
5181 OUT PUCHAR pBssid,
5182 OUT CHAR Ssid[],
5183 OUT UCHAR *pSsidLen,
5184 OUT UCHAR *pBssType,
5185 OUT USHORT *pBeaconPeriod,
5186 OUT UCHAR *pChannel,
5187 OUT UCHAR *pNewChannel,
5188 OUT LARGE_INTEGER *pTimestamp,
5189 OUT CF_PARM *pCfParm,
5190 OUT USHORT *pAtimWin,
5191 OUT USHORT *pCapabilityInfo,
5192 OUT UCHAR *pErp,
5193 OUT UCHAR *pDtimCount,
5194 OUT UCHAR *pDtimPeriod,
5195 OUT UCHAR *pBcastFlag,
5196 OUT UCHAR *pMessageToMe,
5197 OUT UCHAR SupRate[],
5198 OUT UCHAR *pSupRateLen,
5199 OUT UCHAR ExtRate[],
5200 OUT UCHAR *pExtRateLen,
5201 OUT UCHAR *pCkipFlag,
5202 OUT UCHAR *pAironetCellPowerLimit,
5203 OUT PEDCA_PARM pEdcaParm,
5204 OUT PQBSS_LOAD_PARM pQbssLoad,
5205 OUT PQOS_CAPABILITY_PARM pQosCapability,
5206 OUT ULONG *pRalinkIe,
5207 OUT UCHAR *pHtCapabilityLen,
5208#ifdef CONFIG_STA_SUPPORT
5209 OUT UCHAR *pPreNHtCapabilityLen,
5210#endif // CONFIG_STA_SUPPORT //
5211 OUT HT_CAPABILITY_IE *pHtCapability,
5212 OUT UCHAR *AddHtInfoLen,
5213 OUT ADD_HT_INFO_IE *AddHtInfo,
5214 OUT UCHAR *NewExtChannel,
5215 OUT USHORT *LengthVIE,
5216 OUT PNDIS_802_11_VARIABLE_IEs pVIE);
5217
5218BOOLEAN PeerAddBAReqActionSanity(
5219 IN PRTMP_ADAPTER pAd,
5220 IN VOID *pMsg,
5221 IN ULONG MsgLen,
5222 OUT PUCHAR pAddr2);
5223
5224BOOLEAN PeerAddBARspActionSanity(
5225 IN PRTMP_ADAPTER pAd,
5226 IN VOID *pMsg,
5227 IN ULONG MsgLen);
5228
5229BOOLEAN PeerDelBAActionSanity(
5230 IN PRTMP_ADAPTER pAd,
5231 IN UCHAR Wcid,
5232 IN VOID *pMsg,
5233 IN ULONG MsgLen);
5234
5235BOOLEAN MlmeAssocReqSanity(
5236 IN PRTMP_ADAPTER pAd,
5237 IN VOID *Msg,
5238 IN ULONG MsgLen,
5239 OUT PUCHAR pApAddr,
5240 OUT USHORT *CapabilityInfo,
5241 OUT ULONG *Timeout,
5242 OUT USHORT *ListenIntv);
5243
5244BOOLEAN MlmeAuthReqSanity(
5245 IN PRTMP_ADAPTER pAd,
5246 IN VOID *Msg,
5247 IN ULONG MsgLen,
5248 OUT PUCHAR pAddr,
5249 OUT ULONG *Timeout,
5250 OUT USHORT *Alg);
5251
5252BOOLEAN MlmeStartReqSanity(
5253 IN PRTMP_ADAPTER pAd,
5254 IN VOID *Msg,
5255 IN ULONG MsgLen,
5256 OUT CHAR Ssid[],
5257 OUT UCHAR *Ssidlen);
5258
5259BOOLEAN PeerAuthSanity(
5260 IN PRTMP_ADAPTER pAd,
5261 IN VOID *Msg,
5262 IN ULONG MsgLen,
5263 OUT PUCHAR pAddr,
5264 OUT USHORT *Alg,
5265 OUT USHORT *Seq,
5266 OUT USHORT *Status,
5267 OUT CHAR ChlgText[]);
5268
5269BOOLEAN PeerAssocRspSanity(
5270 IN PRTMP_ADAPTER pAd,
5271 IN VOID *pMsg,
5272 IN ULONG MsgLen,
5273 OUT PUCHAR pAddr2,
5274 OUT USHORT *pCapabilityInfo,
5275 OUT USHORT *pStatus,
5276 OUT USHORT *pAid,
5277 OUT UCHAR SupRate[],
5278 OUT UCHAR *pSupRateLen,
5279 OUT UCHAR ExtRate[],
5280 OUT UCHAR *pExtRateLen,
5281 OUT HT_CAPABILITY_IE *pHtCapability,
5282 OUT ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
5283 OUT UCHAR *pHtCapabilityLen,
5284 OUT UCHAR *pAddHtInfoLen,
5285 OUT UCHAR *pNewExtChannelOffset,
5286 OUT PEDCA_PARM pEdcaParm,
5287 OUT UCHAR *pCkipFlag);
5288
5289BOOLEAN PeerDisassocSanity(
5290 IN PRTMP_ADAPTER pAd,
5291 IN VOID *Msg,
5292 IN ULONG MsgLen,
5293 OUT PUCHAR pAddr2,
5294 OUT USHORT *Reason);
5295
5296BOOLEAN PeerWpaMessageSanity(
5297 IN PRTMP_ADAPTER pAd,
5298 IN PEAPOL_PACKET pMsg,
5299 IN ULONG MsgLen,
5300 IN UCHAR MsgType,
5301 IN MAC_TABLE_ENTRY *pEntry);
5302
5303BOOLEAN PeerDeauthSanity(
5304 IN PRTMP_ADAPTER pAd,
5305 IN VOID *Msg,
5306 IN ULONG MsgLen,
5307 OUT PUCHAR pAddr2,
5308 OUT USHORT *Reason);
5309
5310BOOLEAN PeerProbeReqSanity(
5311 IN PRTMP_ADAPTER pAd,
5312 IN VOID *Msg,
5313 IN ULONG MsgLen,
5314 OUT PUCHAR pAddr2,
5315 OUT CHAR Ssid[],
5316 OUT UCHAR *pSsidLen);
5317
5318BOOLEAN GetTimBit(
5319 IN CHAR *Ptr,
5320 IN USHORT Aid,
5321 OUT UCHAR *TimLen,
5322 OUT UCHAR *BcastFlag,
5323 OUT UCHAR *DtimCount,
5324 OUT UCHAR *DtimPeriod,
5325 OUT UCHAR *MessageToMe);
5326
5327UCHAR ChannelSanity(
5328 IN PRTMP_ADAPTER pAd,
5329 IN UCHAR channel);
5330
5331NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
5332 IN PBSS_ENTRY pBss);
5333
5334#if 0 // It's omitted
5335NDIS_STATUS RTMPWepKeySanity(
5336 IN PRTMP_ADAPTER pAdapter,
5337 IN PVOID pBuf);
5338#endif
5339
5340BOOLEAN MlmeDelBAReqSanity(
5341 IN PRTMP_ADAPTER pAd,
5342 IN VOID *Msg,
5343 IN ULONG MsgLen);
5344
5345BOOLEAN MlmeAddBAReqSanity(
5346 IN PRTMP_ADAPTER pAd,
5347 IN VOID *Msg,
5348 IN ULONG MsgLen,
5349 OUT PUCHAR pAddr2);
5350
5351ULONG MakeOutgoingFrame(
5352 OUT CHAR *Buffer,
5353 OUT ULONG *Length, ...);
5354
5355VOID LfsrInit(
5356 IN PRTMP_ADAPTER pAd,
5357 IN ULONG Seed);
5358
5359UCHAR RandomByte(
5360 IN PRTMP_ADAPTER pAd);
5361
5362VOID AsicUpdateAutoFallBackTable(
5363 IN PRTMP_ADAPTER pAd,
5364 IN PUCHAR pTxRate);
5365
5366VOID MlmePeriodicExec(
5367 IN PVOID SystemSpecific1,
5368 IN PVOID FunctionContext,
5369 IN PVOID SystemSpecific2,
5370 IN PVOID SystemSpecific3);
5371
5372VOID LinkDownExec(
5373 IN PVOID SystemSpecific1,
5374 IN PVOID FunctionContext,
5375 IN PVOID SystemSpecific2,
5376 IN PVOID SystemSpecific3);
5377
5378VOID LinkUpExec(
5379 IN PVOID SystemSpecific1,
5380 IN PVOID FunctionContext,
5381 IN PVOID SystemSpecific2,
5382 IN PVOID SystemSpecific3);
5383
5384VOID STAMlmePeriodicExec(
5385 PRTMP_ADAPTER pAd);
5386
5387VOID MlmeAutoScan(
5388 IN PRTMP_ADAPTER pAd);
5389
5390VOID MlmeAutoReconnectLastSSID(
5391 IN PRTMP_ADAPTER pAd);
5392
5393BOOLEAN MlmeValidateSSID(
5394 IN PUCHAR pSsid,
5395 IN UCHAR SsidLen);
5396
5397VOID MlmeCheckForRoaming(
5398 IN PRTMP_ADAPTER pAd,
5399 IN ULONG Now32);
5400
5401VOID MlmeCheckForFastRoaming(
5402 IN PRTMP_ADAPTER pAd,
5403 IN ULONG Now);
5404
5405VOID MlmeDynamicTxRateSwitching(
5406 IN PRTMP_ADAPTER pAd);
5407
5408VOID MlmeSetTxRate(
5409 IN PRTMP_ADAPTER pAd,
5410 IN PMAC_TABLE_ENTRY pEntry,
5411 IN PRTMP_TX_RATE_SWITCH pTxRate);
5412
5413VOID MlmeSelectTxRateTable(
5414 IN PRTMP_ADAPTER pAd,
5415 IN PMAC_TABLE_ENTRY pEntry,
5416 IN PUCHAR *ppTable,
5417 IN PUCHAR pTableSize,
5418 IN PUCHAR pInitTxRateIdx);
5419
5420VOID MlmeCalculateChannelQuality(
5421 IN PRTMP_ADAPTER pAd,
5422 IN ULONG Now);
5423
5424VOID MlmeCheckPsmChange(
5425 IN PRTMP_ADAPTER pAd,
5426 IN ULONG Now32);
5427
5428VOID MlmeSetPsmBit(
5429 IN PRTMP_ADAPTER pAd,
5430 IN USHORT psm);
5431
5432VOID MlmeSetTxPreamble(
5433 IN PRTMP_ADAPTER pAd,
5434 IN USHORT TxPreamble);
5435
5436VOID UpdateBasicRateBitmap(
5437 IN PRTMP_ADAPTER pAd);
5438
5439VOID MlmeUpdateTxRates(
5440 IN PRTMP_ADAPTER pAd,
5441 IN BOOLEAN bLinkUp,
5442 IN UCHAR apidx);
5443
5444#ifdef DOT11_N_SUPPORT
5445VOID MlmeUpdateHtTxRates(
5446 IN PRTMP_ADAPTER pAd,
5447 IN UCHAR apidx);
5448#endif // DOT11_N_SUPPORT //
5449
5450VOID RTMPCheckRates(
5451 IN PRTMP_ADAPTER pAd,
5452 IN OUT UCHAR SupRate[],
5453 IN OUT UCHAR *SupRateLen);
5454
5455#ifdef CONFIG_STA_SUPPORT
5456BOOLEAN RTMPCheckChannel(
5457 IN PRTMP_ADAPTER pAd,
5458 IN UCHAR CentralChannel,
5459 IN UCHAR Channel);
5460#endif // CONFIG_STA_SUPPORT //
5461
5462BOOLEAN RTMPCheckHt(
5463 IN PRTMP_ADAPTER pAd,
5464 IN UCHAR Wcid,
5465 IN OUT HT_CAPABILITY_IE *pHtCapability,
5466 IN OUT ADD_HT_INFO_IE *pAddHtInfo);
5467
5468VOID StaQuickResponeForRateUpExec(
5469 IN PVOID SystemSpecific1,
5470 IN PVOID FunctionContext,
5471 IN PVOID SystemSpecific2,
5472 IN PVOID SystemSpecific3);
5473
5474VOID AsicBbpTuning1(
5475 IN PRTMP_ADAPTER pAd);
5476
5477VOID AsicBbpTuning2(
5478 IN PRTMP_ADAPTER pAd);
5479
5480VOID RTMPUpdateMlmeRate(
5481 IN PRTMP_ADAPTER pAd);
5482
5483CHAR RTMPMaxRssi(
5484 IN PRTMP_ADAPTER pAd,
5485 IN CHAR Rssi0,
5486 IN CHAR Rssi1,
5487 IN CHAR Rssi2);
5488
5489VOID AsicEvaluateRxAnt(
5490 IN PRTMP_ADAPTER pAd);
5491
5492VOID AsicRxAntEvalTimeout(
5493 IN PVOID SystemSpecific1,
5494 IN PVOID FunctionContext,
5495 IN PVOID SystemSpecific2,
5496 IN PVOID SystemSpecific3);
5497
5498VOID APSDPeriodicExec(
5499 IN PVOID SystemSpecific1,
5500 IN PVOID FunctionContext,
5501 IN PVOID SystemSpecific2,
5502 IN PVOID SystemSpecific3);
5503
5504BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
5505 IN PRTMP_ADAPTER pAd,
5506 IN PMAC_TABLE_ENTRY pEntry);
5507
5508UCHAR RTMPStaFixedTxMode(
5509 IN PRTMP_ADAPTER pAd,
5510 IN PMAC_TABLE_ENTRY pEntry);
5511
5512VOID RTMPUpdateLegacyTxSetting(
5513 UCHAR fixed_tx_mode,
5514 PMAC_TABLE_ENTRY pEntry);
5515
5516BOOLEAN RTMPAutoRateSwitchCheck(
5517 IN PRTMP_ADAPTER pAd);
5518
5519NDIS_STATUS MlmeInit(
5520 IN PRTMP_ADAPTER pAd);
5521
5522VOID MlmeHandler(
5523 IN PRTMP_ADAPTER pAd);
5524
5525VOID MlmeHalt(
5526 IN PRTMP_ADAPTER pAd);
5527
5528VOID MlmeResetRalinkCounters(
5529 IN PRTMP_ADAPTER pAd);
5530
5531VOID BuildChannelList(
5532 IN PRTMP_ADAPTER pAd);
5533
5534UCHAR FirstChannel(
5535 IN PRTMP_ADAPTER pAd);
5536
5537UCHAR NextChannel(
5538 IN PRTMP_ADAPTER pAd,
5539 IN UCHAR channel);
5540
5541VOID ChangeToCellPowerLimit(
5542 IN PRTMP_ADAPTER pAd,
5543 IN UCHAR AironetCellPowerLimit);
5544
5545VOID RaiseClock(
5546 IN PRTMP_ADAPTER pAd,
5547 IN UINT32 *x);
5548
5549VOID LowerClock(
5550 IN PRTMP_ADAPTER pAd,
5551 IN UINT32 *x);
5552
5553USHORT ShiftInBits(
5554 IN PRTMP_ADAPTER pAd);
5555
5556VOID ShiftOutBits(
5557 IN PRTMP_ADAPTER pAd,
5558 IN USHORT data,
5559 IN USHORT count);
5560
5561VOID EEpromCleanup(
5562 IN PRTMP_ADAPTER pAd);
5563
5564VOID EWDS(
5565 IN PRTMP_ADAPTER pAd);
5566
5567VOID EWEN(
5568 IN PRTMP_ADAPTER pAd);
5569
5570USHORT RTMP_EEPROM_READ16(
5571 IN PRTMP_ADAPTER pAd,
5572 IN USHORT Offset);
5573
5574VOID RTMP_EEPROM_WRITE16(
5575 IN PRTMP_ADAPTER pAd,
5576 IN USHORT Offset,
5577 IN USHORT Data);
5578
5579//
5580// Prototypes of function definition in rtmp_tkip.c
5581//
5582VOID RTMPInitTkipEngine(
5583 IN PRTMP_ADAPTER pAd,
5584 IN PUCHAR pTKey,
5585 IN UCHAR KeyId,
5586 IN PUCHAR pTA,
5587 IN PUCHAR pMICKey,
5588 IN PUCHAR pTSC,
5589 OUT PULONG pIV16,
5590 OUT PULONG pIV32);
5591
5592VOID RTMPInitMICEngine(
5593 IN PRTMP_ADAPTER pAd,
5594 IN PUCHAR pKey,
5595 IN PUCHAR pDA,
5596 IN PUCHAR pSA,
5597 IN UCHAR UserPriority,
5598 IN PUCHAR pMICKey);
5599
5600BOOLEAN RTMPTkipCompareMICValue(
5601 IN PRTMP_ADAPTER pAd,
5602 IN PUCHAR pSrc,
5603 IN PUCHAR pDA,
5604 IN PUCHAR pSA,
5605 IN PUCHAR pMICKey,
5606 IN UCHAR UserPriority,
5607 IN UINT Len);
5608
5609VOID RTMPCalculateMICValue(
5610 IN PRTMP_ADAPTER pAd,
5611 IN PNDIS_PACKET pPacket,
5612 IN PUCHAR pEncap,
5613 IN PCIPHER_KEY pKey,
5614 IN UCHAR apidx);
5615
5616BOOLEAN RTMPTkipCompareMICValueWithLLC(
5617 IN PRTMP_ADAPTER pAd,
5618 IN PUCHAR pLLC,
5619 IN PUCHAR pSrc,
5620 IN PUCHAR pDA,
5621 IN PUCHAR pSA,
5622 IN PUCHAR pMICKey,
5623 IN UINT Len);
5624
5625VOID RTMPTkipAppendByte(
5626 IN PTKIP_KEY_INFO pTkip,
5627 IN UCHAR uChar);
5628
5629VOID RTMPTkipAppend(
5630 IN PTKIP_KEY_INFO pTkip,
5631 IN PUCHAR pSrc,
5632 IN UINT nBytes);
5633
5634VOID RTMPTkipGetMIC(
5635 IN PTKIP_KEY_INFO pTkip);
5636
5637BOOLEAN RTMPSoftDecryptTKIP(
5638 IN PRTMP_ADAPTER pAd,
5639 IN PUCHAR pData,
5640 IN ULONG DataByteCnt,
5641 IN UCHAR UserPriority,
5642 IN PCIPHER_KEY pWpaKey);
5643
5644BOOLEAN RTMPSoftDecryptAES(
5645 IN PRTMP_ADAPTER pAd,
5646 IN PUCHAR pData,
5647 IN ULONG DataByteCnt,
5648 IN PCIPHER_KEY pWpaKey);
5649
5650#if 0 // removed by AlbertY
5651NDIS_STATUS RTMPWPAAddKeyProc(
5652 IN PRTMP_ADAPTER pAd,
5653 IN PVOID pBuf);
5654#endif
5655
5656//
5657// Prototypes of function definition in cmm_info.c
5658//
5659NDIS_STATUS RTMPWPARemoveKeyProc(
5660 IN PRTMP_ADAPTER pAd,
5661 IN PVOID pBuf);
5662
5663VOID RTMPWPARemoveAllKeys(
5664 IN PRTMP_ADAPTER pAd);
5665
5666BOOLEAN RTMPCheckStrPrintAble(
5667 IN CHAR *pInPutStr,
5668 IN UCHAR strLen);
5669
5670VOID RTMPSetPhyMode(
5671 IN PRTMP_ADAPTER pAd,
5672 IN ULONG phymode);
5673
5674VOID RTMPUpdateHTIE(
5675 IN RT_HT_CAPABILITY *pRtHt,
5676 IN UCHAR *pMcsSet,
5677 OUT HT_CAPABILITY_IE *pHtCapability,
5678 OUT ADD_HT_INFO_IE *pAddHtInfo);
5679
5680VOID RTMPAddWcidAttributeEntry(
5681 IN PRTMP_ADAPTER pAd,
5682 IN UCHAR BssIdx,
5683 IN UCHAR KeyIdx,
5684 IN UCHAR CipherAlg,
5685 IN MAC_TABLE_ENTRY *pEntry);
5686
5687CHAR *GetEncryptType(
5688 CHAR enc);
5689
5690CHAR *GetAuthMode(
5691 CHAR auth);
5692
5693VOID RTMPIoctlGetSiteSurvey(
5694 IN PRTMP_ADAPTER pAdapter,
5695 IN struct iwreq *wrq);
5696
5697VOID RTMPIoctlGetMacTable(
5698 IN PRTMP_ADAPTER pAd,
5699 IN struct iwreq *wrq);
5700
5701VOID RTMPIndicateWPA2Status(
5702 IN PRTMP_ADAPTER pAdapter);
5703
5704VOID RTMPOPModeSwitching(
5705 IN PRTMP_ADAPTER pAd);
5706
5707#ifdef CONFIG_STA_SUPPORT
5708VOID RTMPAddBSSIDCipher(
5709 IN PRTMP_ADAPTER pAd,
5710 IN UCHAR Aid,
5711 IN PNDIS_802_11_KEY pKey,
5712 IN UCHAR CipherAlg);
5713#endif // CONFIG_STA_SUPPORT //
5714
5715#ifdef DOT11_N_SUPPORT
5716VOID RTMPSetHT(
5717 IN PRTMP_ADAPTER pAd,
5718 IN OID_SET_HT_PHYMODE *pHTPhyMode);
5719
5720VOID RTMPSetIndividualHT(
5721 IN PRTMP_ADAPTER pAd,
5722 IN UCHAR apidx);
5723#endif // DOT11_N_SUPPORT //
5724
5725VOID RTMPSendWirelessEvent(
5726 IN PRTMP_ADAPTER pAd,
5727 IN USHORT Event_flag,
5728 IN PUCHAR pAddr,
5729 IN UCHAR BssIdx,
5730 IN CHAR Rssi);
5731
5732VOID NICUpdateCntlCounters(
5733 IN PRTMP_ADAPTER pAd,
5734 IN PHEADER_802_11 pHeader,
5735 IN UCHAR SubType,
5736 IN PRXWI_STRUC pRxWI);
5737//
5738// prototype in wpa.c
5739//
5740BOOLEAN WpaMsgTypeSubst(
5741 IN UCHAR EAPType,
5742 OUT INT *MsgType);
5743
5744VOID WpaPskStateMachineInit(
5745 IN PRTMP_ADAPTER pAd,
5746 IN STATE_MACHINE *S,
5747 OUT STATE_MACHINE_FUNC Trans[]);
5748
5749VOID WpaEAPOLKeyAction(
5750 IN PRTMP_ADAPTER pAd,
5751 IN MLME_QUEUE_ELEM *Elem);
5752
5753VOID WpaPairMsg1Action(
5754 IN PRTMP_ADAPTER pAd,
5755 IN MLME_QUEUE_ELEM *Elem);
5756
5757VOID WpaPairMsg3Action(
5758 IN PRTMP_ADAPTER pAd,
5759 IN MLME_QUEUE_ELEM *Elem);
5760
5761VOID WpaGroupMsg1Action(
5762 IN PRTMP_ADAPTER pAd,
5763 IN MLME_QUEUE_ELEM *Elem);
5764
5765VOID WpaMacHeaderInit(
5766 IN PRTMP_ADAPTER pAd,
5767 IN OUT PHEADER_802_11 pHdr80211,
5768 IN UCHAR wep,
5769 IN PUCHAR pAddr1);
5770
5771VOID Wpa2PairMsg1Action(
5772 IN PRTMP_ADAPTER pAd,
5773 IN MLME_QUEUE_ELEM *Elem);
5774
5775VOID Wpa2PairMsg3Action(
5776 IN PRTMP_ADAPTER pAd,
5777 IN MLME_QUEUE_ELEM *Elem);
5778
5779BOOLEAN ParseKeyData(
5780 IN PRTMP_ADAPTER pAd,
5781 IN PUCHAR pKeyData,
5782 IN UCHAR KeyDataLen,
5783 IN UCHAR bPairewise);
5784
5785VOID RTMPToWirelessSta(
5786 IN PRTMP_ADAPTER pAd,
5787 IN PUCHAR pHeader802_3,
5788 IN UINT HdrLen,
5789 IN PUCHAR pData,
5790 IN UINT DataLen,
5791 IN BOOLEAN is4wayFrame);
5792
5793VOID HMAC_SHA1(
5794 IN UCHAR *text,
5795 IN UINT text_len,
5796 IN UCHAR *key,
5797 IN UINT key_len,
5798 IN UCHAR *digest);
5799
5800VOID PRF(
5801 IN UCHAR *key,
5802 IN INT key_len,
5803 IN UCHAR *prefix,
5804 IN INT prefix_len,
5805 IN UCHAR *data,
5806 IN INT data_len,
5807 OUT UCHAR *output,
5808 IN INT len);
5809
5810VOID CCKMPRF(
5811 IN UCHAR *key,
5812 IN INT key_len,
5813 IN UCHAR *data,
5814 IN INT data_len,
5815 OUT UCHAR *output,
5816 IN INT len);
5817
5818VOID WpaCountPTK(
5819 IN PRTMP_ADAPTER pAd,
5820 IN UCHAR *PMK,
5821 IN UCHAR *ANonce,
5822 IN UCHAR *AA,
5823 IN UCHAR *SNonce,
5824 IN UCHAR *SA,
5825 OUT UCHAR *output,
5826 IN UINT len);
5827
5828VOID GenRandom(
5829 IN PRTMP_ADAPTER pAd,
5830 IN UCHAR *macAddr,
5831 OUT UCHAR *random);
5832
5833//
5834// prototype in aironet.c
5835//
5836VOID AironetStateMachineInit(
5837 IN PRTMP_ADAPTER pAd,
5838 IN STATE_MACHINE *S,
5839 OUT STATE_MACHINE_FUNC Trans[]);
5840
5841VOID AironetMsgAction(
5842 IN PRTMP_ADAPTER pAd,
5843 IN MLME_QUEUE_ELEM *Elem);
5844
5845VOID AironetRequestAction(
5846 IN PRTMP_ADAPTER pAd,
5847 IN MLME_QUEUE_ELEM *Elem);
5848
5849VOID ChannelLoadRequestAction(
5850 IN PRTMP_ADAPTER pAd,
5851 IN UCHAR Index);
5852
5853VOID NoiseHistRequestAction(
5854 IN PRTMP_ADAPTER pAd,
5855 IN UCHAR Index);
5856
5857VOID BeaconRequestAction(
5858 IN PRTMP_ADAPTER pAd,
5859 IN UCHAR Index);
5860
5861VOID AironetReportAction(
5862 IN PRTMP_ADAPTER pAd,
5863 IN MLME_QUEUE_ELEM *Elem);
5864
5865VOID ChannelLoadReportAction(
5866 IN PRTMP_ADAPTER pAd,
5867 IN UCHAR Index);
5868
5869VOID NoiseHistReportAction(
5870 IN PRTMP_ADAPTER pAd,
5871 IN UCHAR Index);
5872
5873VOID AironetFinalReportAction(
5874 IN PRTMP_ADAPTER pAd);
5875
5876VOID BeaconReportAction(
5877 IN PRTMP_ADAPTER pAd,
5878 IN UCHAR Index);
5879
5880VOID AironetAddBeaconReport(
5881 IN PRTMP_ADAPTER pAd,
5882 IN ULONG Index,
5883 IN PMLME_QUEUE_ELEM pElem);
5884
5885VOID AironetCreateBeaconReportFromBssTable(
5886 IN PRTMP_ADAPTER pAd);
5887
5888VOID DBGPRINT_TX_RING(
5889 IN PRTMP_ADAPTER pAd,
5890 IN UCHAR QueIdx);
5891
5892VOID DBGPRINT_RX_RING(
5893 IN PRTMP_ADAPTER pAd);
5894
5895CHAR ConvertToRssi(
5896 IN PRTMP_ADAPTER pAd,
5897 IN CHAR Rssi,
5898 IN UCHAR RssiNumber);
5899
5900
5901#ifdef DOT11N_DRAFT3
5902VOID BuildEffectedChannelList(
5903 IN PRTMP_ADAPTER pAd);
5904#endif // DOT11N_DRAFT3 //
5905
5906
5907VOID APAsicEvaluateRxAnt(
5908 IN PRTMP_ADAPTER pAd);
5909
5910
5911VOID APAsicRxAntEvalTimeout(
5912 IN PRTMP_ADAPTER pAd);
5913
5914//
5915// function prototype in cmm_wpa.c
5916//
5917BOOLEAN RTMPCheckWPAframe(
5918 IN PRTMP_ADAPTER pAd,
5919 IN PMAC_TABLE_ENTRY pEntry,
5920 IN PUCHAR pData,
5921 IN ULONG DataByteCount,
5922 IN UCHAR FromWhichBSSID);
5923
5924VOID AES_GTK_KEY_UNWRAP(
5925 IN UCHAR *key,
5926 OUT UCHAR *plaintext,
5927 IN UCHAR c_len,
5928 IN UCHAR *ciphertext);
5929
5930BOOLEAN RTMPCheckRSNIE(
5931 IN PRTMP_ADAPTER pAd,
5932 IN PUCHAR pData,
5933 IN UCHAR DataLen,
5934 IN MAC_TABLE_ENTRY *pEntry,
5935 OUT UCHAR *Offset);
5936
5937BOOLEAN RTMPParseEapolKeyData(
5938 IN PRTMP_ADAPTER pAd,
5939 IN PUCHAR pKeyData,
5940 IN UCHAR KeyDataLen,
5941 IN UCHAR GroupKeyIndex,
5942 IN UCHAR MsgType,
5943 IN BOOLEAN bWPA2,
5944 IN MAC_TABLE_ENTRY *pEntry);
5945
5946VOID ConstructEapolMsg(
5947 IN PRTMP_ADAPTER pAd,
5948 IN UCHAR PeerAuthMode,
5949 IN UCHAR PeerWepStatus,
5950 IN UCHAR MyGroupKeyWepStatus,
5951 IN UCHAR MsgType,
5952 IN UCHAR DefaultKeyIdx,
5953 IN UCHAR *ReplayCounter,
5954 IN UCHAR *KeyNonce,
5955 IN UCHAR *TxRSC,
5956 IN UCHAR *PTK,
5957 IN UCHAR *GTK,
5958 IN UCHAR *RSNIE,
5959 IN UCHAR RSNIE_Len,
5960 OUT PEAPOL_PACKET pMsg);
5961
5962VOID CalculateMIC(
5963 IN PRTMP_ADAPTER pAd,
5964 IN UCHAR PeerWepStatus,
5965 IN UCHAR *PTK,
5966 OUT PEAPOL_PACKET pMsg);
5967
5968NDIS_STATUS RTMPSoftDecryptBroadCastData(
5969 IN PRTMP_ADAPTER pAd,
5970 IN RX_BLK *pRxBlk,
5971 IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,
5972 IN PCIPHER_KEY pShard_key);
5973
5974VOID ConstructEapolKeyData(
5975 IN PRTMP_ADAPTER pAd,
5976 IN UCHAR PeerAuthMode,
5977 IN UCHAR PeerWepStatus,
5978 IN UCHAR GroupKeyWepStatus,
5979 IN UCHAR MsgType,
5980 IN UCHAR DefaultKeyIdx,
5981 IN BOOLEAN bWPA2Capable,
5982 IN UCHAR *PTK,
5983 IN UCHAR *GTK,
5984 IN UCHAR *RSNIE,
5985 IN UCHAR RSNIE_LEN,
5986 OUT PEAPOL_PACKET pMsg);
5987
5988VOID RTMPMakeRSNIE(
5989 IN PRTMP_ADAPTER pAd,
5990 IN UINT AuthMode,
5991 IN UINT WepStatus,
5992 IN UCHAR apidx);
5993
5994//
5995// function prototype in ap_wpa.c
5996//
5997
5998BOOLEAN APWpaMsgTypeSubst(
5999 IN UCHAR EAPType,
6000 OUT INT *MsgType) ;
6001
6002MAC_TABLE_ENTRY *PACInquiry(
6003 IN PRTMP_ADAPTER pAd,
6004 IN ULONG Wcid);
6005
6006BOOLEAN RTMPCheckMcast(
6007 IN PRTMP_ADAPTER pAd,
6008 IN PEID_STRUCT eid_ptr,
6009 IN MAC_TABLE_ENTRY *pEntry);
6010
6011BOOLEAN RTMPCheckUcast(
6012 IN PRTMP_ADAPTER pAd,
6013 IN PEID_STRUCT eid_ptr,
6014 IN MAC_TABLE_ENTRY *pEntry);
6015
6016BOOLEAN RTMPCheckAUTH(
6017 IN PRTMP_ADAPTER pAd,
6018 IN PEID_STRUCT eid_ptr,
6019 IN MAC_TABLE_ENTRY *pEntry);
6020
6021VOID WPAStart4WayHS(
6022 IN PRTMP_ADAPTER pAd,
6023 IN MAC_TABLE_ENTRY *pEntry,
6024 IN ULONG TimeInterval);
6025
6026VOID WPAStart2WayGroupHS(
6027 IN PRTMP_ADAPTER pAd,
6028 IN MAC_TABLE_ENTRY *pEntry);
6029
6030VOID APWpaEAPPacketAction(
6031 IN PRTMP_ADAPTER pAd,
6032 IN MLME_QUEUE_ELEM *Elem);
6033
6034VOID APWpaEAPOLStartAction(
6035 IN PRTMP_ADAPTER pAd,
6036 IN MLME_QUEUE_ELEM *Elem);
6037
6038VOID APWpaEAPOLLogoffAction(
6039 IN PRTMP_ADAPTER pAd,
6040 IN MLME_QUEUE_ELEM *Elem);
6041
6042VOID APWpaEAPOLKeyAction(
6043 IN PRTMP_ADAPTER pAd,
6044 IN MLME_QUEUE_ELEM *Elem);
6045
6046VOID APWpaEAPOLASFAlertAction(
6047 IN PRTMP_ADAPTER pAd,
6048 IN MLME_QUEUE_ELEM *Elem);
6049
6050VOID HandleCounterMeasure(
6051 IN PRTMP_ADAPTER pAd,
6052 IN MAC_TABLE_ENTRY *pEntry);
6053
6054VOID PeerPairMsg2Action(
6055 IN PRTMP_ADAPTER pAd,
6056 IN MAC_TABLE_ENTRY *pEntry,
6057 IN MLME_QUEUE_ELEM *Elem);
6058
6059VOID PeerPairMsg4Action(
6060 IN PRTMP_ADAPTER pAd,
6061 IN MAC_TABLE_ENTRY *pEntry,
6062 IN MLME_QUEUE_ELEM *Elem);
6063
6064VOID CMTimerExec(
6065 IN PVOID SystemSpecific1,
6066 IN PVOID FunctionContext,
6067 IN PVOID SystemSpecific2,
6068 IN PVOID SystemSpecific3);
6069
6070VOID WPARetryExec(
6071 IN PVOID SystemSpecific1,
6072 IN PVOID FunctionContext,
6073 IN PVOID SystemSpecific2,
6074 IN PVOID SystemSpecific3);
6075
6076VOID EnqueueStartForPSKExec(
6077 IN PVOID SystemSpecific1,
6078 IN PVOID FunctionContext,
6079 IN PVOID SystemSpecific2,
6080 IN PVOID SystemSpecific3);
6081
6082VOID RTMPHandleSTAKey(
6083 IN PRTMP_ADAPTER pAdapter,
6084 IN MAC_TABLE_ENTRY *pEntry,
6085 IN MLME_QUEUE_ELEM *Elem);
6086
6087#if 0 // merge into PeerPairMsg4Action
6088VOID Wpa1PeerPairMsg4Action(
6089 IN PRTMP_ADAPTER pAd,
6090 IN MAC_TABLE_ENTRY *pEntry,
6091 IN MLME_QUEUE_ELEM *Elem);
6092
6093VOID Wpa2PeerPairMsg4Action(
6094 IN PRTMP_ADAPTER pAd,
6095 IN PMAC_TABLE_ENTRY pEntry,
6096 IN MLME_QUEUE_ELEM *Elem);
6097#endif // 0 //
6098
6099VOID PeerGroupMsg2Action(
6100 IN PRTMP_ADAPTER pAd,
6101 IN PMAC_TABLE_ENTRY pEntry,
6102 IN VOID *Msg,
6103 IN UINT MsgLen);
6104
6105#if 0 // replaced by WPAStart2WayGroupHS
6106NDIS_STATUS APWpaHardTransmit(
6107 IN PRTMP_ADAPTER pAd,
6108 IN PMAC_TABLE_ENTRY pEntry);
6109#endif // 0 //
6110
6111VOID PairDisAssocAction(
6112 IN PRTMP_ADAPTER pAd,
6113 IN PMAC_TABLE_ENTRY pEntry,
6114 IN USHORT Reason);
6115
6116VOID MlmeDeAuthAction(
6117 IN PRTMP_ADAPTER pAd,
6118 IN PMAC_TABLE_ENTRY pEntry,
6119 IN USHORT Reason);
6120
6121VOID GREKEYPeriodicExec(
6122 IN PVOID SystemSpecific1,
6123 IN PVOID FunctionContext,
6124 IN PVOID SystemSpecific2,
6125 IN PVOID SystemSpecific3);
6126
6127VOID CountGTK(
6128 IN UCHAR *PMK,
6129 IN UCHAR *GNonce,
6130 IN UCHAR *AA,
6131 OUT UCHAR *output,
6132 IN UINT len);
6133
6134VOID GetSmall(
6135 IN PVOID pSrc1,
6136 IN PVOID pSrc2,
6137 OUT PUCHAR out,
6138 IN ULONG Length);
6139
6140VOID GetLarge(
6141 IN PVOID pSrc1,
6142 IN PVOID pSrc2,
6143 OUT PUCHAR out,
6144 IN ULONG Length);
6145
6146VOID APGenRandom(
6147 IN PRTMP_ADAPTER pAd,
6148 OUT UCHAR *random);
6149
6150VOID AES_GTK_KEY_WRAP(
6151 IN UCHAR *key,
6152 IN UCHAR *plaintext,
6153 IN UCHAR p_len,
6154 OUT UCHAR *ciphertext);
6155
6156VOID WpaSend(
6157 IN PRTMP_ADAPTER pAdapter,
6158 IN PUCHAR pPacket,
6159 IN ULONG Len);
6160
6161VOID APToWirelessSta(
6162 IN PRTMP_ADAPTER pAd,
6163 IN MAC_TABLE_ENTRY *pEntry,
6164 IN PUCHAR pHeader802_3,
6165 IN UINT HdrLen,
6166 IN PUCHAR pData,
6167 IN UINT DataLen,
6168 IN BOOLEAN bClearFrame);
6169
6170VOID RTMPAddPMKIDCache(
6171 IN PRTMP_ADAPTER pAd,
6172 IN INT apidx,
6173 IN PUCHAR pAddr,
6174 IN UCHAR *PMKID,
6175 IN UCHAR *PMK);
6176
6177INT RTMPSearchPMKIDCache(
6178 IN PRTMP_ADAPTER pAd,
6179 IN INT apidx,
6180 IN PUCHAR pAddr);
6181
6182VOID RTMPDeletePMKIDCache(
6183 IN PRTMP_ADAPTER pAd,
6184 IN INT apidx,
6185 IN INT idx);
6186
6187VOID RTMPMaintainPMKIDCache(
6188 IN PRTMP_ADAPTER pAd);
6189
6190VOID RTMPSendTriggerFrame(
6191 IN PRTMP_ADAPTER pAd,
6192 IN PVOID pBuffer,
6193 IN ULONG Length,
6194 IN UCHAR TxRate,
6195 IN BOOLEAN bQosNull);
6196
6197
6198//typedef void (*TIMER_FUNCTION)(unsigned long);
6199
6200
6201/* timeout -- ms */
6202VOID RTMP_SetPeriodicTimer(
6203 IN NDIS_MINIPORT_TIMER *pTimer,
6204 IN unsigned long timeout);
6205
6206VOID RTMP_OS_Init_Timer(
6207 IN PRTMP_ADAPTER pAd,
6208 IN NDIS_MINIPORT_TIMER *pTimer,
6209 IN TIMER_FUNCTION function,
6210 IN PVOID data);
6211
6212VOID RTMP_OS_Add_Timer(
6213 IN NDIS_MINIPORT_TIMER *pTimer,
6214 IN unsigned long timeout);
6215
6216VOID RTMP_OS_Mod_Timer(
6217 IN NDIS_MINIPORT_TIMER *pTimer,
6218 IN unsigned long timeout);
6219
6220
6221VOID RTMP_OS_Del_Timer(
6222 IN NDIS_MINIPORT_TIMER *pTimer,
6223 OUT BOOLEAN *pCancelled);
6224
6225
6226VOID RTMP_OS_Release_Packet(
6227 IN PRTMP_ADAPTER pAd,
6228 IN PQUEUE_ENTRY pEntry);
6229
6230VOID RTMPusecDelay(
6231 IN ULONG usec);
6232
6233NDIS_STATUS os_alloc_mem(
6234 IN PRTMP_ADAPTER pAd,
6235 OUT PUCHAR *mem,
6236 IN ULONG size);
6237
6238NDIS_STATUS os_free_mem(
6239 IN PRTMP_ADAPTER pAd,
6240 IN PUCHAR mem);
6241
6242
6243void RTMP_AllocateSharedMemory(
6244 IN PRTMP_ADAPTER pAd,
6245 IN ULONG Length,
6246 IN BOOLEAN Cached,
6247 OUT PVOID *VirtualAddress,
6248 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6249
6250VOID RTMPFreeTxRxRingMemory(
6251 IN PRTMP_ADAPTER pAd);
6252
6253NDIS_STATUS AdapterBlockAllocateMemory(
6254 IN PVOID handle,
6255 OUT PVOID *ppAd);
6256
6257void RTMP_AllocateTxDescMemory(
6258 IN PRTMP_ADAPTER pAd,
6259 IN UINT Index,
6260 IN ULONG Length,
6261 IN BOOLEAN Cached,
6262 OUT PVOID *VirtualAddress,
6263 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6264
6265void RTMP_AllocateFirstTxBuffer(
6266 IN PRTMP_ADAPTER pAd,
6267 IN UINT Index,
6268 IN ULONG Length,
6269 IN BOOLEAN Cached,
6270 OUT PVOID *VirtualAddress,
6271 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6272
6273void RTMP_AllocateMgmtDescMemory(
6274 IN PRTMP_ADAPTER pAd,
6275 IN ULONG Length,
6276 IN BOOLEAN Cached,
6277 OUT PVOID *VirtualAddress,
6278 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6279
6280void RTMP_AllocateRxDescMemory(
6281 IN PRTMP_ADAPTER pAd,
6282 IN ULONG Length,
6283 IN BOOLEAN Cached,
6284 OUT PVOID *VirtualAddress,
6285 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6286
6287PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
6288 IN PRTMP_ADAPTER pAd,
6289 IN ULONG Length,
6290 IN BOOLEAN Cached,
6291 OUT PVOID *VirtualAddress,
6292 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6293
6294PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
6295 IN PRTMP_ADAPTER pAd,
6296 IN ULONG Length,
6297 IN BOOLEAN Cached,
6298 OUT PVOID *VirtualAddress);
6299
6300PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
6301 IN PRTMP_ADAPTER pAd,
6302 IN ULONG Length);
6303
6304void RTMP_QueryPacketInfo(
6305 IN PNDIS_PACKET pPacket,
6306 OUT PACKET_INFO *pPacketInfo,
6307 OUT PUCHAR *pSrcBufVA,
6308 OUT UINT *pSrcBufLen);
6309
6310void RTMP_QueryNextPacketInfo(
6311 IN PNDIS_PACKET *ppPacket,
6312 OUT PACKET_INFO *pPacketInfo,
6313 OUT PUCHAR *pSrcBufVA,
6314 OUT UINT *pSrcBufLen);
6315
6316
6317BOOLEAN RTMP_FillTxBlkInfo(
6318 IN RTMP_ADAPTER *pAd,
6319 IN TX_BLK *pTxBlk);
6320
6321
6322PRTMP_SCATTER_GATHER_LIST
6323rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg);
6324
6325
6326 void announce_802_3_packet(
6327 IN PRTMP_ADAPTER pAd,
6328 IN PNDIS_PACKET pPacket);
6329
6330
6331UINT BA_Reorder_AMSDU_Annnounce(
6332 IN PRTMP_ADAPTER pAd,
6333 IN PNDIS_PACKET pPacket);
6334
6335
6336UINT Handle_AMSDU_Packet(
6337 IN PRTMP_ADAPTER pAd,
6338 IN PUCHAR pData,
6339 IN ULONG DataSize,
6340 IN UCHAR FromWhichBSSID);
6341
6342
6343void convert_802_11_to_802_3_packet(
6344 IN PRTMP_ADAPTER pAd,
6345 IN PNDIS_PACKET pPacket,
6346 IN PUCHAR p8023hdr,
6347 IN PUCHAR pData,
6348 IN ULONG DataSize,
6349 IN UCHAR FromWhichBSSID);
6350
6351
6352PNET_DEV get_netdev_from_bssid(
6353 IN PRTMP_ADAPTER pAd,
6354 IN UCHAR FromWhichBSSID);
6355
6356
6357PNDIS_PACKET duplicate_pkt(
6358 IN PRTMP_ADAPTER pAd,
6359 IN PUCHAR pHeader802_3,
6360 IN UINT HdrLen,
6361 IN PUCHAR pData,
6362 IN ULONG DataSize,
6363 IN UCHAR FromWhichBSSID);
6364
6365
6366PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
6367 IN PRTMP_ADAPTER pAd,
6368 IN PNDIS_PACKET pOldPkt);
6369
6370PNDIS_PACKET duplicate_pkt_with_VLAN(
6371 IN PRTMP_ADAPTER pAd,
6372 IN PUCHAR pHeader802_3,
6373 IN UINT HdrLen,
6374 IN PUCHAR pData,
6375 IN ULONG DataSize,
6376 IN UCHAR FromWhichBSSID);
6377
6378PNDIS_PACKET duplicate_pkt_with_WPI(
6379 IN PRTMP_ADAPTER pAd,
6380 IN PNDIS_PACKET pPacket,
6381 IN UINT32 ext_head_len,
6382 IN UINT32 ext_tail_len);
6383
6384UCHAR VLAN_8023_Header_Copy(
6385 IN PRTMP_ADAPTER pAd,
6386 IN PUCHAR pHeader802_3,
6387 IN UINT HdrLen,
6388 OUT PUCHAR pData,
6389 IN UCHAR FromWhichBSSID);
6390
6391#ifdef DOT11_N_SUPPORT
6392void ba_flush_reordering_timeout_mpdus(
6393 IN PRTMP_ADAPTER pAd,
6394 IN PBA_REC_ENTRY pBAEntry,
6395 IN ULONG Now32);
6396
6397
6398VOID BAOriSessionSetUp(
6399 IN PRTMP_ADAPTER pAd,
6400 IN MAC_TABLE_ENTRY *pEntry,
6401 IN UCHAR TID,
6402 IN USHORT TimeOut,
6403 IN ULONG DelayTime,
6404 IN BOOLEAN isForced);
6405
6406VOID BASessionTearDownALL(
6407 IN OUT PRTMP_ADAPTER pAd,
6408 IN UCHAR Wcid);
6409#endif // DOT11_N_SUPPORT //
6410
6411BOOLEAN OS_Need_Clone_Packet(void);
6412
6413
6414VOID build_tx_packet(
6415 IN PRTMP_ADAPTER pAd,
6416 IN PNDIS_PACKET pPacket,
6417 IN PUCHAR pFrame,
6418 IN ULONG FrameLen);
6419
6420
6421VOID BAOriSessionTearDown(
6422 IN OUT PRTMP_ADAPTER pAd,
6423 IN UCHAR Wcid,
6424 IN UCHAR TID,
6425 IN BOOLEAN bPassive,
6426 IN BOOLEAN bForceSend);
6427
6428VOID BARecSessionTearDown(
6429 IN OUT PRTMP_ADAPTER pAd,
6430 IN UCHAR Wcid,
6431 IN UCHAR TID,
6432 IN BOOLEAN bPassive);
6433
6434BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
6435void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
6436
6437ULONG AutoChBssInsertEntry(
6438 IN PRTMP_ADAPTER pAd,
6439 IN PUCHAR pBssid,
6440 IN CHAR Ssid[],
6441 IN UCHAR SsidLen,
6442 IN UCHAR ChannelNo,
6443 IN CHAR Rssi);
6444
6445void AutoChBssTableInit(
6446 IN PRTMP_ADAPTER pAd);
6447
6448void ChannelInfoInit(
6449 IN PRTMP_ADAPTER pAd);
6450
6451void AutoChBssTableDestroy(
6452 IN PRTMP_ADAPTER pAd);
6453
6454void ChannelInfoDestroy(
6455 IN PRTMP_ADAPTER pAd);
6456
6457UCHAR New_ApAutoSelectChannel(
6458 IN PRTMP_ADAPTER pAd);
6459
6460BOOLEAN rtstrmactohex(
6461 IN char *s1,
6462 IN char *s2);
6463
6464BOOLEAN rtstrcasecmp(
6465 IN char *s1,
6466 IN char *s2);
6467
6468char *rtstrstruncasecmp(
6469 IN char *s1,
6470 IN char *s2);
6471
6472char *rtstrstr(
6473 IN const char * s1,
6474 IN const char * s2);
6475
6476char *rstrtok(
6477 IN char * s,
6478 IN const char * ct);
6479
6480int rtinet_aton(
6481 const char *cp,
6482 unsigned int *addr);
6483
6484////////// common ioctl functions //////////
6485INT Set_DriverVersion_Proc(
6486 IN PRTMP_ADAPTER pAd,
6487 IN PUCHAR arg);
6488
6489INT Set_CountryRegion_Proc(
6490 IN PRTMP_ADAPTER pAd,
6491 IN PUCHAR arg);
6492
6493INT Set_CountryRegionABand_Proc(
6494 IN PRTMP_ADAPTER pAd,
6495 IN PUCHAR arg);
6496
6497INT Set_WirelessMode_Proc(
6498 IN PRTMP_ADAPTER pAd,
6499 IN PUCHAR arg);
6500
6501INT Set_Channel_Proc(
6502 IN PRTMP_ADAPTER pAd,
6503 IN PUCHAR arg);
6504
6505INT Set_ShortSlot_Proc(
6506 IN PRTMP_ADAPTER pAd,
6507 IN PUCHAR arg);
6508
6509INT Set_TxPower_Proc(
6510 IN PRTMP_ADAPTER pAd,
6511 IN PUCHAR arg);
6512
6513INT Set_BGProtection_Proc(
6514 IN PRTMP_ADAPTER pAd,
6515 IN PUCHAR arg);
6516
6517INT Set_TxPreamble_Proc(
6518 IN PRTMP_ADAPTER pAd,
6519 IN PUCHAR arg);
6520
6521INT Set_RTSThreshold_Proc(
6522 IN PRTMP_ADAPTER pAd,
6523 IN PUCHAR arg);
6524
6525INT Set_FragThreshold_Proc(
6526 IN PRTMP_ADAPTER pAd,
6527 IN PUCHAR arg);
6528
6529INT Set_TxBurst_Proc(
6530 IN PRTMP_ADAPTER pAd,
6531 IN PUCHAR arg);
6532
6533#ifdef AGGREGATION_SUPPORT
6534INT Set_PktAggregate_Proc(
6535 IN PRTMP_ADAPTER pAd,
6536 IN PUCHAR arg);
6537#endif
6538
6539INT Set_IEEE80211H_Proc(
6540 IN PRTMP_ADAPTER pAd,
6541 IN PUCHAR arg);
6542
6543#ifdef DBG
6544INT Set_Debug_Proc(
6545 IN PRTMP_ADAPTER pAd,
6546 IN PUCHAR arg);
6547#endif
6548
6549INT Show_DescInfo_Proc(
6550 IN PRTMP_ADAPTER pAd,
6551 IN PUCHAR arg);
6552
6553INT Set_ResetStatCounter_Proc(
6554 IN PRTMP_ADAPTER pAd,
6555 IN PUCHAR arg);
6556
6557#ifdef DOT11_N_SUPPORT
6558INT Set_BASetup_Proc(
6559 IN PRTMP_ADAPTER pAd,
6560 IN PUCHAR arg);
6561
6562INT Set_BADecline_Proc(
6563 IN PRTMP_ADAPTER pAd,
6564 IN PUCHAR arg);
6565
6566INT Set_BAOriTearDown_Proc(
6567 IN PRTMP_ADAPTER pAd,
6568 IN PUCHAR arg);
6569
6570INT Set_BARecTearDown_Proc(
6571 IN PRTMP_ADAPTER pAd,
6572 IN PUCHAR arg);
6573
6574INT Set_HtBw_Proc(
6575 IN PRTMP_ADAPTER pAd,
6576 IN PUCHAR arg);
6577
6578INT Set_HtMcs_Proc(
6579 IN PRTMP_ADAPTER pAd,
6580 IN PUCHAR arg);
6581
6582INT Set_HtGi_Proc(
6583 IN PRTMP_ADAPTER pAd,
6584 IN PUCHAR arg);
6585
6586INT Set_HtOpMode_Proc(
6587 IN PRTMP_ADAPTER pAd,
6588 IN PUCHAR arg);
6589
6590INT Set_HtStbc_Proc(
6591 IN PRTMP_ADAPTER pAd,
6592 IN PUCHAR arg);
6593
6594INT Set_HtHtc_Proc(
6595 IN PRTMP_ADAPTER pAd,
6596 IN PUCHAR arg);
6597
6598INT Set_HtExtcha_Proc(
6599 IN PRTMP_ADAPTER pAd,
6600 IN PUCHAR arg);
6601
6602INT Set_HtMpduDensity_Proc(
6603 IN PRTMP_ADAPTER pAd,
6604 IN PUCHAR arg);
6605
6606INT Set_HtBaWinSize_Proc(
6607 IN PRTMP_ADAPTER pAd,
6608 IN PUCHAR arg);
6609
6610INT Set_HtRdg_Proc(
6611 IN PRTMP_ADAPTER pAd,
6612 IN PUCHAR arg);
6613
6614INT Set_HtLinkAdapt_Proc(
6615 IN PRTMP_ADAPTER pAd,
6616 IN PUCHAR arg);
6617
6618INT Set_HtAmsdu_Proc(
6619 IN PRTMP_ADAPTER pAd,
6620 IN PUCHAR arg);
6621
6622INT Set_HtAutoBa_Proc(
6623 IN PRTMP_ADAPTER pAd,
6624 IN PUCHAR arg);
6625
6626INT Set_HtProtect_Proc(
6627 IN PRTMP_ADAPTER pAd,
6628 IN PUCHAR arg);
6629
6630INT Set_HtMimoPs_Proc(
6631 IN PRTMP_ADAPTER pAd,
6632 IN PUCHAR arg);
6633
6634
6635INT Set_ForceShortGI_Proc(
6636 IN PRTMP_ADAPTER pAd,
6637 IN PUCHAR arg);
6638
6639INT Set_ForceGF_Proc(
6640 IN PRTMP_ADAPTER pAd,
6641 IN PUCHAR arg);
6642
6643INT SetCommonHT(
6644 IN PRTMP_ADAPTER pAd);
6645
6646INT Set_SendPSMPAction_Proc(
6647 IN PRTMP_ADAPTER pAd,
6648 IN PUCHAR arg);
6649
6650INT Set_HtMIMOPSmode_Proc(
6651 IN PRTMP_ADAPTER pAd,
6652 IN PUCHAR arg);
6653
6654
6655INT Set_HtTxBASize_Proc(
6656 IN PRTMP_ADAPTER pAd,
6657 IN PUCHAR arg);
6658#endif // DOT11_N_SUPPORT //
6659
6660
6661
6662#ifdef CONFIG_STA_SUPPORT
6663//Dls , kathy
6664VOID RTMPSendDLSTearDownFrame(
6665 IN PRTMP_ADAPTER pAd,
6666 IN PUCHAR pDA);
6667
6668#ifdef DOT11_N_SUPPORT
6669//Block ACK
6670VOID QueryBATABLE(
6671 IN PRTMP_ADAPTER pAd,
6672 OUT PQUERYBA_TABLE pBAT);
6673#endif // DOT11_N_SUPPORT //
6674
6675#ifdef WPA_SUPPLICANT_SUPPORT
6676INT WpaCheckEapCode(
6677 IN PRTMP_ADAPTER pAd,
6678 IN PUCHAR pFrame,
6679 IN USHORT FrameLen,
6680 IN USHORT OffSet);
6681
6682VOID WpaSendMicFailureToWpaSupplicant(
6683 IN PRTMP_ADAPTER pAd,
6684 IN BOOLEAN bUnicast);
6685
6686VOID SendAssocIEsToWpaSupplicant(
6687 IN PRTMP_ADAPTER pAd);
6688#endif // WPA_SUPPLICANT_SUPPORT //
6689
6690#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
6691int wext_notify_event_assoc(
6692 IN RTMP_ADAPTER *pAd);
6693#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
6694
6695#endif // CONFIG_STA_SUPPORT //
6696
6697
6698
6699#ifdef DOT11_N_SUPPORT
6700VOID Handle_BSS_Width_Trigger_Events(
6701 IN PRTMP_ADAPTER pAd);
6702
6703void build_ext_channel_switch_ie(
6704 IN PRTMP_ADAPTER pAd,
6705 IN HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE *pIE);
6706#endif // DOT11_N_SUPPORT //
6707
6708
6709BOOLEAN APRxDoneInterruptHandle(
6710 IN PRTMP_ADAPTER pAd);
6711
6712BOOLEAN STARxDoneInterruptHandle(
6713 IN PRTMP_ADAPTER pAd,
6714 IN BOOLEAN argc);
6715
6716#ifdef DOT11_N_SUPPORT
6717// AMPDU packet indication
6718VOID Indicate_AMPDU_Packet(
6719 IN PRTMP_ADAPTER pAd,
6720 IN RX_BLK *pRxBlk,
6721 IN UCHAR FromWhichBSSID);
6722
6723// AMSDU packet indication
6724VOID Indicate_AMSDU_Packet(
6725 IN PRTMP_ADAPTER pAd,
6726 IN RX_BLK *pRxBlk,
6727 IN UCHAR FromWhichBSSID);
6728#endif // DOT11_N_SUPPORT //
6729
6730// Normal legacy Rx packet indication
6731VOID Indicate_Legacy_Packet(
6732 IN PRTMP_ADAPTER pAd,
6733 IN RX_BLK *pRxBlk,
6734 IN UCHAR FromWhichBSSID);
6735
6736VOID Indicate_EAPOL_Packet(
6737 IN PRTMP_ADAPTER pAd,
6738 IN RX_BLK *pRxBlk,
6739 IN UCHAR FromWhichBSSID);
6740
6741void update_os_packet_info(
6742 IN PRTMP_ADAPTER pAd,
6743 IN RX_BLK *pRxBlk,
6744 IN UCHAR FromWhichBSSID);
6745
6746void wlan_802_11_to_802_3_packet(
6747 IN PRTMP_ADAPTER pAd,
6748 IN RX_BLK *pRxBlk,
6749 IN PUCHAR pHeader802_3,
6750 IN UCHAR FromWhichBSSID);
6751
6752UINT deaggregate_AMSDU_announce(
6753 IN PRTMP_ADAPTER pAd,
6754 PNDIS_PACKET pPacket,
6755 IN PUCHAR pData,
6756 IN ULONG DataSize);
6757
6758
6759#ifdef CONFIG_STA_SUPPORT
6760// remove LLC and get 802_3 Header
6761#define RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(_pRxBlk, _pHeader802_3) \
6762{ \
6763 PUCHAR _pRemovedLLCSNAP = NULL, _pDA, _pSA; \
6764 \
6765 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH)) \
6766 { \
6767 _pDA = _pRxBlk->pHeader->Addr3; \
6768 _pSA = (PUCHAR)_pRxBlk->pHeader + sizeof(HEADER_802_11); \
6769 } \
6770 else \
6771 { \
6772 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_INFRA)) \
6773 { \
6774 _pDA = _pRxBlk->pHeader->Addr1; \
6775 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_DLS)) \
6776 _pSA = _pRxBlk->pHeader->Addr2; \
6777 else \
6778 _pSA = _pRxBlk->pHeader->Addr3; \
6779 } \
6780 else \
6781 { \
6782 _pDA = _pRxBlk->pHeader->Addr1; \
6783 _pSA = _pRxBlk->pHeader->Addr2; \
6784 } \
6785 } \
6786 \
6787 CONVERT_TO_802_3(_pHeader802_3, _pDA, _pSA, _pRxBlk->pData, \
6788 _pRxBlk->DataSize, _pRemovedLLCSNAP); \
6789}
6790#endif // CONFIG_STA_SUPPORT //
6791
6792
6793BOOLEAN APFowardWirelessStaToWirelessSta(
6794 IN PRTMP_ADAPTER pAd,
6795 IN PNDIS_PACKET pPacket,
6796 IN ULONG FromWhichBSSID);
6797
6798VOID Announce_or_Forward_802_3_Packet(
6799 IN PRTMP_ADAPTER pAd,
6800 IN PNDIS_PACKET pPacket,
6801 IN UCHAR FromWhichBSSID);
6802
6803VOID Sta_Announce_or_Forward_802_3_Packet(
6804 IN PRTMP_ADAPTER pAd,
6805 IN PNDIS_PACKET pPacket,
6806 IN UCHAR FromWhichBSSID);
6807
6808
6809#ifdef CONFIG_STA_SUPPORT
6810#define ANNOUNCE_OR_FORWARD_802_3_PACKET(_pAd, _pPacket, _FromWhichBSS)\
6811 Sta_Announce_or_Forward_802_3_Packet(_pAd, _pPacket, _FromWhichBSS);
6812 //announce_802_3_packet(_pAd, _pPacket);
6813#endif // CONFIG_STA_SUPPORT //
6814
6815
6816PNDIS_PACKET DuplicatePacket(
6817 IN PRTMP_ADAPTER pAd,
6818 IN PNDIS_PACKET pPacket,
6819 IN UCHAR FromWhichBSSID);
6820
6821
6822PNDIS_PACKET ClonePacket(
6823 IN PRTMP_ADAPTER pAd,
6824 IN PNDIS_PACKET pPacket,
6825 IN PUCHAR pData,
6826 IN ULONG DataSize);
6827
6828
6829// Normal, AMPDU or AMSDU
6830VOID CmmRxnonRalinkFrameIndicate(
6831 IN PRTMP_ADAPTER pAd,
6832 IN RX_BLK *pRxBlk,
6833 IN UCHAR FromWhichBSSID);
6834
6835VOID CmmRxRalinkFrameIndicate(
6836 IN PRTMP_ADAPTER pAd,
6837 IN MAC_TABLE_ENTRY *pEntry,
6838 IN RX_BLK *pRxBlk,
6839 IN UCHAR FromWhichBSSID);
6840
6841VOID Update_Rssi_Sample(
6842 IN PRTMP_ADAPTER pAd,
6843 IN RSSI_SAMPLE *pRssi,
6844 IN PRXWI_STRUC pRxWI);
6845
6846PNDIS_PACKET GetPacketFromRxRing(
6847 IN PRTMP_ADAPTER pAd,
6848 OUT PRT28XX_RXD_STRUC pSaveRxD,
6849 OUT BOOLEAN *pbReschedule,
6850 IN OUT UINT32 *pRxPending);
6851
6852PNDIS_PACKET RTMPDeFragmentDataFrame(
6853 IN PRTMP_ADAPTER pAd,
6854 IN RX_BLK *pRxBlk);
6855
6856////////////////////////////////////////
6857
6858
6859
6860
6861
6862#ifdef SNMP_SUPPORT
6863//for snmp , kathy
6864typedef struct _DefaultKeyIdxValue
6865{
6866 UCHAR KeyIdx;
6867 UCHAR Value[16];
6868} DefaultKeyIdxValue, *PDefaultKeyIdxValue;
6869#endif
6870
6871
6872#ifdef CONFIG_STA_SUPPORT
6873enum {
6874 DIDmsg_lnxind_wlansniffrm = 0x00000044,
6875 DIDmsg_lnxind_wlansniffrm_hosttime = 0x00010044,
6876 DIDmsg_lnxind_wlansniffrm_mactime = 0x00020044,
6877 DIDmsg_lnxind_wlansniffrm_channel = 0x00030044,
6878 DIDmsg_lnxind_wlansniffrm_rssi = 0x00040044,
6879 DIDmsg_lnxind_wlansniffrm_sq = 0x00050044,
6880 DIDmsg_lnxind_wlansniffrm_signal = 0x00060044,
6881 DIDmsg_lnxind_wlansniffrm_noise = 0x00070044,
6882 DIDmsg_lnxind_wlansniffrm_rate = 0x00080044,
6883 DIDmsg_lnxind_wlansniffrm_istx = 0x00090044,
6884 DIDmsg_lnxind_wlansniffrm_frmlen = 0x000A0044
6885};
6886enum {
6887 P80211ENUM_msgitem_status_no_value = 0x00
6888};
6889enum {
6890 P80211ENUM_truth_false = 0x00,
6891 P80211ENUM_truth_true = 0x01
6892};
6893
6894/* Definition from madwifi */
6895typedef struct {
6896 UINT32 did;
6897 UINT16 status;
6898 UINT16 len;
6899 UINT32 data;
6900} p80211item_uint32_t;
6901
6902typedef struct {
6903 UINT32 msgcode;
6904 UINT32 msglen;
6905#define WLAN_DEVNAMELEN_MAX 16
6906 UINT8 devname[WLAN_DEVNAMELEN_MAX];
6907 p80211item_uint32_t hosttime;
6908 p80211item_uint32_t mactime;
6909 p80211item_uint32_t channel;
6910 p80211item_uint32_t rssi;
6911 p80211item_uint32_t sq;
6912 p80211item_uint32_t signal;
6913 p80211item_uint32_t noise;
6914 p80211item_uint32_t rate;
6915 p80211item_uint32_t istx;
6916 p80211item_uint32_t frmlen;
6917} wlan_ng_prism2_header;
6918
6919/* The radio capture header precedes the 802.11 header. */
6920typedef struct PACKED _ieee80211_radiotap_header {
6921 UINT8 it_version; /* Version 0. Only increases
6922 * for drastic changes,
6923 * introduction of compatible
6924 * new fields does not count.
6925 */
6926 UINT8 it_pad;
6927 UINT16 it_len; /* length of the whole
6928 * header in bytes, including
6929 * it_version, it_pad,
6930 * it_len, and data fields.
6931 */
6932 UINT32 it_present; /* A bitmap telling which
6933 * fields are present. Set bit 31
6934 * (0x80000000) to extend the
6935 * bitmap by another 32 bits.
6936 * Additional extensions are made
6937 * by setting bit 31.
6938 */
6939}ieee80211_radiotap_header ;
6940
6941enum ieee80211_radiotap_type {
6942 IEEE80211_RADIOTAP_TSFT = 0,
6943 IEEE80211_RADIOTAP_FLAGS = 1,
6944 IEEE80211_RADIOTAP_RATE = 2,
6945 IEEE80211_RADIOTAP_CHANNEL = 3,
6946 IEEE80211_RADIOTAP_FHSS = 4,
6947 IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
6948 IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
6949 IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
6950 IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
6951 IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
6952 IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
6953 IEEE80211_RADIOTAP_ANTENNA = 11,
6954 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
6955 IEEE80211_RADIOTAP_DB_ANTNOISE = 13
6956};
6957
6958#define WLAN_RADIOTAP_PRESENT ( \
6959 (1 << IEEE80211_RADIOTAP_TSFT) | \
6960 (1 << IEEE80211_RADIOTAP_FLAGS) | \
6961 (1 << IEEE80211_RADIOTAP_RATE) | \
6962 0)
6963
6964typedef struct _wlan_radiotap_header {
6965 ieee80211_radiotap_header wt_ihdr;
6966 INT64 wt_tsft;
6967 UINT8 wt_flags;
6968 UINT8 wt_rate;
6969} wlan_radiotap_header;
6970/* Definition from madwifi */
6971
6972void send_monitor_packets(
6973 IN PRTMP_ADAPTER pAd,
6974 IN RX_BLK *pRxBlk);
6975
6976#if WIRELESS_EXT >= 12
6977// This function will be called when query /proc
6978struct iw_statistics *rt28xx_get_wireless_stats(
6979 IN struct net_device *net_dev);
6980#endif
6981
6982VOID RTMPSetDesiredRates(
6983 IN PRTMP_ADAPTER pAdapter,
6984 IN LONG Rates);
6985#endif // CONFIG_STA_SUPPORT //
6986
6987INT Set_FixedTxMode_Proc(
6988 IN PRTMP_ADAPTER pAd,
6989 IN PUCHAR arg);
6990
6991#ifdef CONFIG_APSTA_MIXED_SUPPORT
6992INT Set_OpMode_Proc(
6993 IN PRTMP_ADAPTER pAd,
6994 IN PUCHAR arg);
6995#endif // CONFIG_APSTA_MIXED_SUPPORT //
6996
6997static inline char* GetPhyMode(
6998 int Mode)
6999{
7000 switch(Mode)
7001 {
7002 case MODE_CCK:
7003 return "CCK";
7004
7005 case MODE_OFDM:
7006 return "OFDM";
7007#ifdef DOT11_N_SUPPORT
7008 case MODE_HTMIX:
7009 return "HTMIX";
7010
7011 case MODE_HTGREENFIELD:
7012 return "GREEN";
7013#endif // DOT11_N_SUPPORT //
7014 default:
7015 return "N/A";
7016 }
7017}
7018
7019
7020static inline char* GetBW(
7021 int BW)
7022{
7023 switch(BW)
7024 {
7025 case BW_10:
7026 return "10M";
7027
7028 case BW_20:
7029 return "20M";
7030#ifdef DOT11_N_SUPPORT
7031 case BW_40:
7032 return "40M";
7033#endif // DOT11_N_SUPPORT //
7034 default:
7035 return "N/A";
7036 }
7037}
7038
7039
7040VOID RT28xxThreadTerminate(
7041 IN RTMP_ADAPTER *pAd);
7042
7043BOOLEAN RT28XXChipsetCheck(
7044 IN void *_dev_p);
7045
7046BOOLEAN RT28XXNetDevInit(
7047 IN void *_dev_p,
7048 IN struct net_device *net_dev,
7049 IN RTMP_ADAPTER *pAd);
7050
7051BOOLEAN RT28XXProbePostConfig(
7052 IN void *_dev_p,
7053 IN RTMP_ADAPTER *pAd,
7054 IN INT32 argc);
7055
7056VOID RT28XXDMADisable(
7057 IN RTMP_ADAPTER *pAd);
7058
7059VOID RT28XXDMAEnable(
7060 IN RTMP_ADAPTER *pAd);
7061
7062VOID RT28xx_UpdateBeaconToAsic(
7063 IN RTMP_ADAPTER * pAd,
7064 IN INT apidx,
7065 IN ULONG BeaconLen,
7066 IN ULONG UpdatePos);
7067
7068INT rt28xx_ioctl(
7069 IN struct net_device *net_dev,
7070 IN OUT struct ifreq *rq,
7071 IN INT cmd);
7072
7073
7074#ifdef CONFIG_STA_SUPPORT
7075INT rt28xx_sta_ioctl(
7076 IN struct net_device *net_dev,
7077 IN OUT struct ifreq *rq,
7078 IN INT cmd);
7079#endif // CONFIG_STA_SUPPORT //
7080
7081BOOLEAN RT28XXSecurityKeyAdd(
7082 IN PRTMP_ADAPTER pAd,
7083 IN ULONG apidx,
7084 IN ULONG KeyIdx,
7085 IN MAC_TABLE_ENTRY *pEntry);
7086
7087////////////////////////////////////////
7088PNDIS_PACKET GetPacketFromRxRing(
7089 IN PRTMP_ADAPTER pAd,
7090 OUT PRT28XX_RXD_STRUC pSaveRxD,
7091 OUT BOOLEAN *pbReschedule,
7092 IN OUT UINT32 *pRxPending);
7093
7094
7095void kill_thread_task(PRTMP_ADAPTER pAd);
7096
7097void tbtt_tasklet(unsigned long data);
7098
7099
7100VOID AsicTurnOffRFClk(
7101 IN PRTMP_ADAPTER pAd,
7102 IN UCHAR Channel);
7103
7104VOID AsicTurnOnRFClk(
7105 IN PRTMP_ADAPTER pAd,
7106 IN UCHAR Channel);
7107
7108#ifdef RT2870
7109//
7110// Function Prototype in rtusb_bulk.c
7111//
7112VOID RTUSBInitTxDesc(
7113 IN PRTMP_ADAPTER pAd,
7114 IN PTX_CONTEXT pTxContext,
7115 IN UCHAR BulkOutPipeId,
7116 IN usb_complete_t Func);
7117
7118VOID RTUSBInitHTTxDesc(
7119 IN PRTMP_ADAPTER pAd,
7120 IN PHT_TX_CONTEXT pTxContext,
7121 IN UCHAR BulkOutPipeId,
7122 IN ULONG BulkOutSize,
7123 IN usb_complete_t Func);
7124
7125VOID RTUSBInitRxDesc(
7126 IN PRTMP_ADAPTER pAd,
7127 IN PRX_CONTEXT pRxContext);
7128
7129VOID RTUSBCleanUpDataBulkOutQueue(
7130 IN PRTMP_ADAPTER pAd);
7131
7132VOID RTUSBCancelPendingBulkOutIRP(
7133 IN PRTMP_ADAPTER pAd);
7134
7135VOID RTUSBBulkOutDataPacket(
7136 IN PRTMP_ADAPTER pAd,
7137 IN UCHAR BulkOutPipeId,
7138 IN UCHAR Index);
7139
7140VOID RTUSBBulkOutNullFrame(
7141 IN PRTMP_ADAPTER pAd);
7142
7143VOID RTUSBBulkOutRTSFrame(
7144 IN PRTMP_ADAPTER pAd);
7145
7146VOID RTUSBCancelPendingBulkInIRP(
7147 IN PRTMP_ADAPTER pAd);
7148
7149VOID RTUSBCancelPendingIRPs(
7150 IN PRTMP_ADAPTER pAd);
7151
7152VOID RTUSBBulkOutMLMEPacket(
7153 IN PRTMP_ADAPTER pAd,
7154 IN UCHAR Index);
7155
7156VOID RTUSBBulkOutPsPoll(
7157 IN PRTMP_ADAPTER pAd);
7158
7159VOID RTUSBCleanUpMLMEBulkOutQueue(
7160 IN PRTMP_ADAPTER pAd);
7161
7162VOID RTUSBKickBulkOut(
7163 IN PRTMP_ADAPTER pAd);
7164
7165VOID RTUSBBulkReceive(
7166 IN PRTMP_ADAPTER pAd);
7167
7168VOID DoBulkIn(
7169 IN RTMP_ADAPTER *pAd);
7170
7171VOID RTUSBInitRxDesc(
7172 IN PRTMP_ADAPTER pAd,
7173 IN PRX_CONTEXT pRxContext);
7174
7175VOID RTUSBBulkRxHandle(
7176 IN unsigned long data);
7177
7178//
7179// Function Prototype in rtusb_io.c
7180//
7181NTSTATUS RTUSBMultiRead(
7182 IN PRTMP_ADAPTER pAd,
7183 IN USHORT Offset,
7184 OUT PUCHAR pData,
7185 IN USHORT length);
7186
7187NTSTATUS RTUSBMultiWrite(
7188 IN PRTMP_ADAPTER pAd,
7189 IN USHORT Offset,
7190 IN PUCHAR pData,
7191 IN USHORT length);
7192
7193NTSTATUS RTUSBMultiWrite_OneByte(
7194 IN PRTMP_ADAPTER pAd,
7195 IN USHORT Offset,
7196 IN PUCHAR pData);
7197
7198NTSTATUS RTUSBReadBBPRegister(
7199 IN PRTMP_ADAPTER pAd,
7200 IN UCHAR Id,
7201 IN PUCHAR pValue);
7202
7203NTSTATUS RTUSBWriteBBPRegister(
7204 IN PRTMP_ADAPTER pAd,
7205 IN UCHAR Id,
7206 IN UCHAR Value);
7207
7208NTSTATUS RTUSBWriteRFRegister(
7209 IN PRTMP_ADAPTER pAd,
7210 IN UINT32 Value);
7211
7212NTSTATUS RT30xxWriteRFRegister(
7213 IN PRTMP_ADAPTER pAd,
7214 IN UCHAR RegID,
7215 IN UCHAR Value);
7216
7217NTSTATUS RT30xxReadRFRegister(
7218 IN PRTMP_ADAPTER pAd,
7219 IN UCHAR RegID,
7220 IN PUCHAR pValue);
7221
7222NTSTATUS RTUSB_VendorRequest(
7223 IN PRTMP_ADAPTER pAd,
7224 IN UINT32 TransferFlags,
7225 IN UCHAR ReservedBits,
7226 IN UCHAR Request,
7227 IN USHORT Value,
7228 IN USHORT Index,
7229 IN PVOID TransferBuffer,
7230 IN UINT32 TransferBufferLength);
7231
7232NTSTATUS RTUSBReadEEPROM(
7233 IN PRTMP_ADAPTER pAd,
7234 IN USHORT Offset,
7235 OUT PUCHAR pData,
7236 IN USHORT length);
7237
7238NTSTATUS RTUSBWriteEEPROM(
7239 IN PRTMP_ADAPTER pAd,
7240 IN USHORT Offset,
7241 IN PUCHAR pData,
7242 IN USHORT length);
7243
7244VOID RTUSBPutToSleep(
7245 IN PRTMP_ADAPTER pAd);
7246
7247NTSTATUS RTUSBWakeUp(
7248 IN PRTMP_ADAPTER pAd);
7249
7250VOID RTUSBInitializeCmdQ(
7251 IN PCmdQ cmdq);
7252
7253NDIS_STATUS RTUSBEnqueueCmdFromNdis(
7254 IN PRTMP_ADAPTER pAd,
7255 IN NDIS_OID Oid,
7256 IN BOOLEAN SetInformation,
7257 IN PVOID pInformationBuffer,
7258 IN UINT32 InformationBufferLength);
7259
7260NDIS_STATUS RTUSBEnqueueInternalCmd(
7261 IN PRTMP_ADAPTER pAd,
7262 IN NDIS_OID Oid,
7263 IN PVOID pInformationBuffer,
7264 IN UINT32 InformationBufferLength);
7265
7266VOID RTUSBDequeueCmd(
7267 IN PCmdQ cmdq,
7268 OUT PCmdQElmt *pcmdqelmt);
7269
7270INT RTUSBCmdThread(
7271 IN OUT PVOID Context);
7272
7273INT TimerQThread(
7274 IN OUT PVOID Context);
7275
7276RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
7277 IN RTMP_ADAPTER *pAd,
7278 IN RALINK_TIMER_STRUCT *pTimer);
7279
7280BOOLEAN RT2870_TimerQ_Remove(
7281 IN RTMP_ADAPTER *pAd,
7282 IN RALINK_TIMER_STRUCT *pTimer);
7283
7284void RT2870_TimerQ_Exit(
7285 IN RTMP_ADAPTER *pAd);
7286
7287void RT2870_TimerQ_Init(
7288 IN RTMP_ADAPTER *pAd);
7289
7290VOID RT2870_BssBeaconExit(
7291 IN RTMP_ADAPTER *pAd);
7292
7293VOID RT2870_BssBeaconStop(
7294 IN RTMP_ADAPTER *pAd);
7295
7296VOID RT2870_BssBeaconStart(
7297 IN RTMP_ADAPTER * pAd);
7298
7299VOID RT2870_BssBeaconInit(
7300 IN RTMP_ADAPTER *pAd);
7301
7302VOID RT2870_WatchDog(
7303 IN RTMP_ADAPTER *pAd);
7304
7305NTSTATUS RTUSBWriteMACRegister(
7306 IN PRTMP_ADAPTER pAd,
7307 IN USHORT Offset,
7308 IN UINT32 Value);
7309
7310NTSTATUS RTUSBReadMACRegister(
7311 IN PRTMP_ADAPTER pAd,
7312 IN USHORT Offset,
7313 OUT PUINT32 pValue);
7314
7315NTSTATUS RTUSBSingleWrite(
7316 IN RTMP_ADAPTER *pAd,
7317 IN USHORT Offset,
7318 IN USHORT Value);
7319
7320NTSTATUS RTUSBFirmwareRun(
7321 IN PRTMP_ADAPTER pAd);
7322
7323NTSTATUS RTUSBFirmwareWrite(
7324 IN PRTMP_ADAPTER pAd,
7325 IN PUCHAR pFwImage,
7326 IN ULONG FwLen);
7327
7328NTSTATUS RTUSBFirmwareOpmode(
7329 IN PRTMP_ADAPTER pAd,
7330 OUT PUINT32 pValue);
7331
7332NTSTATUS RTUSBVenderReset(
7333 IN PRTMP_ADAPTER pAd);
7334
7335NDIS_STATUS RTUSBSetHardWareRegister(
7336 IN PRTMP_ADAPTER pAdapter,
7337 IN PVOID pBuf);
7338
7339NDIS_STATUS RTUSBQueryHardWareRegister(
7340 IN PRTMP_ADAPTER pAdapter,
7341 IN PVOID pBuf);
7342
7343VOID CMDHandler(
7344 IN PRTMP_ADAPTER pAd);
7345
7346
7347NDIS_STATUS CreateThreads(
7348 IN struct net_device *net_dev );
7349
7350
7351VOID MacTableInitialize(
7352 IN PRTMP_ADAPTER pAd);
7353
7354VOID MlmeSetPsm(
7355 IN PRTMP_ADAPTER pAd,
7356 IN USHORT psm);
7357
7358NDIS_STATUS RTMPWPAAddKeyProc(
7359 IN PRTMP_ADAPTER pAd,
7360 IN PVOID pBuf);
7361
7362VOID AsicRxAntEvalAction(
7363 IN PRTMP_ADAPTER pAd);
7364
7365#if 0 // Mark because not used in RT28xx.
7366NTSTATUS RTUSBRxPacket(
7367 IN PRTMP_ADAPTER pAd,
7368 IN BOOLEAN bBulkReceive);
7369
7370VOID RTUSBDequeueMLMEPacket(
7371 IN PRTMP_ADAPTER pAd);
7372
7373VOID RTUSBCleanUpMLMEWaitQueue(
7374 IN PRTMP_ADAPTER pAd);
7375#endif
7376
7377void append_pkt(
7378 IN PRTMP_ADAPTER pAd,
7379 IN PUCHAR pHeader802_3,
7380 IN UINT HdrLen,
7381 IN PUCHAR pData,
7382 IN ULONG DataSize,
7383 OUT PNDIS_PACKET *ppPacket);
7384
7385UINT deaggregate_AMSDU_announce(
7386 IN PRTMP_ADAPTER pAd,
7387 PNDIS_PACKET pPacket,
7388 IN PUCHAR pData,
7389 IN ULONG DataSize);
7390
7391NDIS_STATUS RTMPCheckRxError(
7392 IN PRTMP_ADAPTER pAd,
7393 IN PHEADER_802_11 pHeader,
7394 IN PRXWI_STRUC pRxWI,
7395 IN PRT28XX_RXD_STRUC pRxINFO);
7396
7397
7398VOID RTUSBMlmeHardTransmit(
7399 IN PRTMP_ADAPTER pAd,
7400 IN PMGMT_STRUC pMgmt);
7401
7402INT MlmeThread(
7403 IN PVOID Context);
7404
7405#if 0
7406VOID RTUSBResumeMsduTransmission(
7407 IN PRTMP_ADAPTER pAd);
7408
7409VOID RTUSBSuspendMsduTransmission(
7410 IN PRTMP_ADAPTER pAd);
7411#endif
7412
7413//
7414// Function Prototype in rtusb_data.c
7415//
7416NDIS_STATUS RTUSBFreeDescriptorRequest(
7417 IN PRTMP_ADAPTER pAd,
7418 IN UCHAR BulkOutPipeId,
7419 IN UINT32 NumberRequired);
7420
7421
7422BOOLEAN RTUSBNeedQueueBackForAgg(
7423 IN RTMP_ADAPTER *pAd,
7424 IN UCHAR BulkOutPipeId);
7425
7426
7427VOID RTMPWriteTxInfo(
7428 IN PRTMP_ADAPTER pAd,
7429 IN PTXINFO_STRUC pTxInfo,
7430 IN USHORT USBDMApktLen,
7431 IN BOOLEAN bWiv,
7432 IN UCHAR QueueSel,
7433 IN UCHAR NextValid,
7434 IN UCHAR TxBurst);
7435
7436//
7437// Function Prototype in cmm_data_2870.c
7438//
7439USHORT RtmpUSB_WriteSubTxResource(
7440 IN PRTMP_ADAPTER pAd,
7441 IN TX_BLK *pTxBlk,
7442 IN BOOLEAN bIsLast,
7443 OUT USHORT *FreeNumber);
7444
7445USHORT RtmpUSB_WriteSingleTxResource(
7446 IN PRTMP_ADAPTER pAd,
7447 IN TX_BLK *pTxBlk,
7448 IN BOOLEAN bIsLast,
7449 OUT USHORT *FreeNumber);
7450
7451USHORT RtmpUSB_WriteFragTxResource(
7452 IN PRTMP_ADAPTER pAd,
7453 IN TX_BLK *pTxBlk,
7454 IN UCHAR fragNum,
7455 OUT USHORT *FreeNumber);
7456
7457USHORT RtmpUSB_WriteMultiTxResource(
7458 IN PRTMP_ADAPTER pAd,
7459 IN TX_BLK *pTxBlk,
7460 IN UCHAR frameNum,
7461 OUT USHORT *FreeNumber);
7462
7463VOID RtmpUSB_FinalWriteTxResource(
7464 IN PRTMP_ADAPTER pAd,
7465 IN TX_BLK *pTxBlk,
7466 IN USHORT totalMPDUSize,
7467 IN USHORT TxIdx);
7468
7469VOID RtmpUSBDataLastTxIdx(
7470 IN PRTMP_ADAPTER pAd,
7471 IN UCHAR QueIdx,
7472 IN USHORT TxIdx);
7473
7474VOID RtmpUSBDataKickOut(
7475 IN PRTMP_ADAPTER pAd,
7476 IN TX_BLK *pTxBlk,
7477 IN UCHAR QueIdx);
7478
7479
7480int RtmpUSBMgmtKickOut(
7481 IN RTMP_ADAPTER *pAd,
7482 IN UCHAR QueIdx,
7483 IN PNDIS_PACKET pPacket,
7484 IN PUCHAR pSrcBufVA,
7485 IN UINT SrcBufLen);
7486
7487VOID RtmpUSBNullFrameKickOut(
7488 IN RTMP_ADAPTER *pAd,
7489 IN UCHAR QueIdx,
7490 IN UCHAR *pNullFrame,
7491 IN UINT32 frameLen);
7492
7493VOID RT28xxUsbStaAsicForceWakeup(
7494 IN PRTMP_ADAPTER pAd,
7495 IN BOOLEAN bFromTx);
7496
7497VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
7498 IN PRTMP_ADAPTER pAd,
7499 IN USHORT TbttNumToNextWakeUp);
7500
7501VOID RT28xxUsbMlmeRadioOn(
7502 IN PRTMP_ADAPTER pAd);
7503
7504VOID RT28xxUsbMlmeRadioOFF(
7505 IN PRTMP_ADAPTER pAd);
7506#endif // RT2870 //
7507
7508////////////////////////////////////////
7509
7510VOID QBSS_LoadInit(
7511 IN RTMP_ADAPTER *pAd);
7512
7513UINT32 QBSS_LoadElementAppend(
7514 IN RTMP_ADAPTER *pAd,
7515 OUT UINT8 *buf_p);
7516
7517VOID QBSS_LoadUpdate(
7518 IN RTMP_ADAPTER *pAd);
7519
7520///////////////////////////////////////
7521INT RTMPShowCfgValue(
7522 IN PRTMP_ADAPTER pAd,
7523 IN PUCHAR pName,
7524 IN PUCHAR pBuf);
7525
7526PCHAR RTMPGetRalinkAuthModeStr(
7527 IN NDIS_802_11_AUTHENTICATION_MODE authMode);
7528
7529PCHAR RTMPGetRalinkEncryModeStr(
7530 IN USHORT encryMode);
7531//////////////////////////////////////
7532
7533#ifdef CONFIG_STA_SUPPORT
7534VOID AsicStaBbpTuning(
7535 IN PRTMP_ADAPTER pAd);
7536
7537BOOLEAN StaAddMacTableEntry(
7538 IN PRTMP_ADAPTER pAd,
7539 IN PMAC_TABLE_ENTRY pEntry,
7540 IN UCHAR MaxSupportedRateIn500Kbps,
7541 IN HT_CAPABILITY_IE *pHtCapability,
7542 IN UCHAR HtCapabilityLen,
7543 IN USHORT CapabilityInfo);
7544#endif // CONFIG_STA_SUPPORT //
7545
7546void RTMP_IndicateMediaState(
7547 IN PRTMP_ADAPTER pAd);
7548
7549VOID ReSyncBeaconTime(
7550 IN PRTMP_ADAPTER pAd);
7551
7552VOID RTMPSetAGCInitValue(
7553 IN PRTMP_ADAPTER pAd,
7554 IN UCHAR BandWidth);
7555
7556int rt28xx_close(IN PNET_DEV dev);
7557int rt28xx_open(IN PNET_DEV dev);
7558
7559__inline INT VIRTUAL_IF_UP(PRTMP_ADAPTER pAd)
7560{
7561extern VOID MeshMakeBeacon(IN PRTMP_ADAPTER pAd, IN UCHAR idx);
7562extern VOID MeshUpdateBeaconFrame(IN PRTMP_ADAPTER pAd, IN UCHAR idx);
7563
7564 if (VIRTUAL_IF_NUM(pAd) == 0)
7565 {
7566 if (rt28xx_open(pAd->net_dev) != 0)
7567 return -1;
7568 }
7569 else
7570 {
7571 }
7572 VIRTUAL_IF_INC(pAd);
7573 return 0;
7574}
7575
7576__inline VOID VIRTUAL_IF_DOWN(PRTMP_ADAPTER pAd)
7577{
7578 VIRTUAL_IF_DEC(pAd);
7579 if (VIRTUAL_IF_NUM(pAd) == 0)
7580 rt28xx_close(pAd->net_dev);
7581 return;
7582}
7583
7584
7585#endif // __RTMP_H__
7586
diff --git a/drivers/staging/rt2870/rtmp_ckipmic.h b/drivers/staging/rt2870/rtmp_ckipmic.h
new file mode 100644
index 00000000000..a3d949a39d3
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/rtmp_def.h b/drivers/staging/rt2870/rtmp_def.h
new file mode 100644
index 00000000000..9b86325b4c5
--- /dev/null
+++ b/drivers/staging/rt2870/rtmp_def.h
@@ -0,0 +1,1622 @@
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//
45// Debug information verbosity: lower values indicate higher urgency
46//
47#define RT_DEBUG_OFF 0
48#define RT_DEBUG_ERROR 1
49#define RT_DEBUG_WARN 2
50#define RT_DEBUG_TRACE 3
51#define RT_DEBUG_INFO 4
52#define RT_DEBUG_LOUD 5
53
54#define NIC_TAG ((ULONG)'0682')
55#define NIC_DBG_STRING ("**RT28xx**")
56
57#ifdef SNMP_SUPPORT
58// for snmp
59// to get manufacturer OUI, kathy, 2008_0220
60#define ManufacturerOUI_LEN 3
61#define ManufacturerNAME ("Ralink Technology Company.")
62#define ResourceTypeIdName ("Ralink_ID")
63#endif
64
65
66//#define PACKED
67
68#define RALINK_2883_VERSION ((UINT32)0x28830300)
69#define RALINK_2880E_VERSION ((UINT32)0x28720200)
70#define RALINK_3070_VERSION ((UINT32)0x30700200)
71
72//
73// NDIS version in use by the NIC driver.
74// The high byte is the major version. The low byte is the minor version.
75//
76#ifdef NDIS51_MINIPORT
77#define NIC_DRIVER_VERSION 0x0501
78#else
79#define NIC_DRIVER_VERSION 0x0500
80#endif
81
82//
83// NDIS media type, current is ethernet, change if native wireless supported
84//
85#define NIC_MEDIA_TYPE NdisMedium802_3
86#define NIC_PCI_HDR_LENGTH 0xe2
87#define NIC_MAX_PACKET_SIZE 2304
88#define NIC_HEADER_SIZE 14
89#define MAX_MAP_REGISTERS_NEEDED 32
90#define MIN_MAP_REGISTERS_NEEDED 2 //Todo: should consider fragment issue.
91
92//
93// interface type, we use PCI
94//
95#define NIC_INTERFACE_TYPE NdisInterfacePci
96#define NIC_INTERRUPT_MODE NdisInterruptLevelSensitive
97
98//
99// buffer size passed in NdisMQueryAdapterResources
100// We should only need three adapter resources (IO, interrupt and memory),
101// Some devices get extra resources, so have room for 10 resources
102// UF_SIZE (sizeof(NDIS_RESOURCE_LIST) + (10*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)))
103
104
105#define NIC_RESOURCE_B//
106// IO space length
107//
108#define NIC_MAP_IOSPACE_LENGTH sizeof(CSR_STRUC)
109
110#define MAX_RX_PKT_LEN 1520
111
112//
113// Entry number for each DMA descriptor ring
114//
115
116
117#ifdef RT2870
118#define TX_RING_SIZE 8 // 1
119#define PRIO_RING_SIZE 8
120#define MGMT_RING_SIZE 32 // PRIO_RING_SIZE
121#define RX_RING_SIZE 8
122#define MAX_TX_PROCESS 4
123#define LOCAL_TXBUF_SIZE 2048
124#endif // RT2870 //
125
126#ifdef MULTIPLE_CARD_SUPPORT
127// MC: Multple Cards
128#define MAX_NUM_OF_MULTIPLE_CARD 32
129#endif // MULTIPLE_CARD_SUPPORT //
130
131#define MAX_RX_PROCESS 128 //64 //32
132#define NUM_OF_LOCAL_TXBUF 2
133#define TXD_SIZE 16
134#define TXWI_SIZE 16
135#define RXD_SIZE 16
136#define RXWI_SIZE 16
137// TXINFO_SIZE + TXWI_SIZE + 802.11 Header Size + AMSDU sub frame header
138#define TX_DMA_1ST_BUFFER_SIZE 96 // only the 1st physical buffer is pre-allocated
139#define MGMT_DMA_BUFFER_SIZE 1536 //2048
140#define RX_BUFFER_AGGRESIZE 3840 //3904 //3968 //4096 //2048 //4096
141#define RX_BUFFER_NORMSIZE 3840 //3904 //3968 //4096 //2048 //4096
142#define TX_BUFFER_NORMSIZE RX_BUFFER_NORMSIZE
143#define MAX_FRAME_SIZE 2346 // Maximum 802.11 frame size
144#define MAX_AGGREGATION_SIZE 3840 //3904 //3968 //4096
145#define MAX_NUM_OF_TUPLE_CACHE 2
146#define MAX_MCAST_LIST_SIZE 32
147#define MAX_LEN_OF_VENDOR_DESC 64
148//#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
149#define MAX_SIZE_OF_MCAST_PSQ 32
150
151#define MAX_RX_PROCESS_CNT (RX_RING_SIZE)
152
153
154#define MAX_PACKETS_IN_QUEUE (512) //(512) // to pass WMM A5-WPAPSK
155#define MAX_PACKETS_IN_MCAST_PS_QUEUE 32
156#define MAX_PACKETS_IN_PS_QUEUE 128 //32
157#define WMM_NUM_OF_AC 4 /* AC0, AC1, AC2, and AC3 */
158
159
160
161// RxFilter
162#define STANORMAL 0x17f97
163#define APNORMAL 0x15f97
164//
165// RTMP_ADAPTER flags
166//
167#define fRTMP_ADAPTER_MAP_REGISTER 0x00000001
168#define fRTMP_ADAPTER_INTERRUPT_IN_USE 0x00000002
169#define fRTMP_ADAPTER_HARDWARE_ERROR 0x00000004
170#define fRTMP_ADAPTER_SCATTER_GATHER 0x00000008
171#define fRTMP_ADAPTER_SEND_PACKET_ERROR 0x00000010
172#define fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS 0x00000020
173#define fRTMP_ADAPTER_HALT_IN_PROGRESS 0x00000040
174#define fRTMP_ADAPTER_RESET_IN_PROGRESS 0x00000080
175#define fRTMP_ADAPTER_NIC_NOT_EXIST 0x00000100
176#define fRTMP_ADAPTER_TX_RING_ALLOCATED 0x00000200
177#define fRTMP_ADAPTER_REMOVE_IN_PROGRESS 0x00000400
178#define fRTMP_ADAPTER_MIMORATE_INUSED 0x00000800
179#define fRTMP_ADAPTER_RX_RING_ALLOCATED 0x00001000
180#define fRTMP_ADAPTER_INTERRUPT_ACTIVE 0x00002000
181#define fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS 0x00004000
182#define fRTMP_ADAPTER_REASSOC_IN_PROGRESS 0x00008000
183#define fRTMP_ADAPTER_MEDIA_STATE_PENDING 0x00010000
184#define fRTMP_ADAPTER_RADIO_OFF 0x00020000
185#define fRTMP_ADAPTER_BULKOUT_RESET 0x00040000
186#define fRTMP_ADAPTER_BULKIN_RESET 0x00080000
187#define fRTMP_ADAPTER_RDG_ACTIVE 0x00100000
188#define fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE 0x00200000
189#define fRTMP_ADAPTER_SCAN_2040 0x04000000
190#define fRTMP_ADAPTER_RADIO_MEASUREMENT 0x08000000
191
192#define fRTMP_ADAPTER_START_UP 0x10000000 //Devive already initialized and enabled Tx/Rx.
193#define fRTMP_ADAPTER_MEDIA_STATE_CHANGE 0x20000000
194#define fRTMP_ADAPTER_IDLE_RADIO_OFF 0x40000000
195
196// Lock bit for accessing different ring buffers
197//#define fRTMP_ADAPTER_TX_RING_BUSY 0x80000000
198//#define fRTMP_ADAPTER_MGMT_RING_BUSY 0x40000000
199//#define fRTMP_ADAPTER_ATIM_RING_BUSY 0x20000000
200//#define fRTMP_ADAPTER_RX_RING_BUSY 0x10000000
201
202// Lock bit for accessing different queue
203//#define fRTMP_ADAPTER_TX_QUEUE_BUSY 0x08000000
204//#define fRTMP_ADAPTER_MGMT_QUEUE_BUSY 0x04000000
205
206//
207// STA operation status flags
208//
209#define fOP_STATUS_INFRA_ON 0x00000001
210#define fOP_STATUS_ADHOC_ON 0x00000002
211#define fOP_STATUS_BG_PROTECTION_INUSED 0x00000004
212#define fOP_STATUS_SHORT_SLOT_INUSED 0x00000008
213#define fOP_STATUS_SHORT_PREAMBLE_INUSED 0x00000010
214#define fOP_STATUS_RECEIVE_DTIM 0x00000020
215//#define fOP_STATUS_TX_RATE_SWITCH_ENABLED 0x00000040
216#define fOP_STATUS_MEDIA_STATE_CONNECTED 0x00000080
217#define fOP_STATUS_WMM_INUSED 0x00000100
218#define fOP_STATUS_AGGREGATION_INUSED 0x00000200
219#define fOP_STATUS_DOZE 0x00000400 // debug purpose
220#define fOP_STATUS_PIGGYBACK_INUSED 0x00000800 // piggy-back, and aggregation
221#define fOP_STATUS_APSD_INUSED 0x00001000
222#define fOP_STATUS_TX_AMSDU_INUSED 0x00002000
223#define fOP_STATUS_MAX_RETRY_ENABLED 0x00004000
224#define fOP_STATUS_WAKEUP_NOW 0x00008000
225#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE 0x00020000
226
227#ifdef DOT11N_DRAFT3
228#define fOP_STATUS_SCAN_2040 0x00040000
229#endif // DOT11N_DRAFT3 //
230
231#define CCKSETPROTECT 0x1
232#define OFDMSETPROTECT 0x2
233#define MM20SETPROTECT 0x4
234#define MM40SETPROTECT 0x8
235#define GF20SETPROTECT 0x10
236#define GR40SETPROTECT 0x20
237#define ALLN_SETPROTECT (GR40SETPROTECT | GF20SETPROTECT | MM40SETPROTECT | MM20SETPROTECT)
238
239//
240// AP's client table operation status flags
241//
242#define fCLIENT_STATUS_WMM_CAPABLE 0x00000001 // CLIENT can parse QOS DATA frame
243#define fCLIENT_STATUS_AGGREGATION_CAPABLE 0x00000002 // CLIENT can receive Ralink's proprietary TX aggregation frame
244#define fCLIENT_STATUS_PIGGYBACK_CAPABLE 0x00000004 // CLIENT support piggy-back
245#define fCLIENT_STATUS_AMSDU_INUSED 0x00000008
246#define fCLIENT_STATUS_SGI20_CAPABLE 0x00000010
247#define fCLIENT_STATUS_SGI40_CAPABLE 0x00000020
248#define fCLIENT_STATUS_TxSTBC_CAPABLE 0x00000040
249#define fCLIENT_STATUS_RxSTBC_CAPABLE 0x00000080
250#define fCLIENT_STATUS_HTC_CAPABLE 0x00000100
251#define fCLIENT_STATUS_RDG_CAPABLE 0x00000200
252#define fCLIENT_STATUS_MCSFEEDBACK_CAPABLE 0x00000400
253#define fCLIENT_STATUS_APSD_CAPABLE 0x00000800 /* UAPSD STATION */
254
255#ifdef DOT11N_DRAFT3
256#define fCLIENT_STATUS_BSSCOEXIST_CAPABLE 0x00001000
257#endif // DOT11N_DRAFT3 //
258
259#define fCLIENT_STATUS_RALINK_CHIPSET 0x00100000
260//
261// STA configuration flags
262//
263//#define fSTA_CFG_ENABLE_TX_BURST 0x00000001
264
265// 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case
266#define HT_NO_PROTECT 0
267#define HT_LEGACY_PROTECT 1
268#define HT_40_PROTECT 2
269#define HT_2040_PROTECT 3
270#define HT_RTSCTS_6M 7
271//following is our own definition in order to turn on our ASIC protection register in INFRASTRUCTURE.
272#define HT_ATHEROS 8 // rt2860c has problem with atheros chip. we need to turn on RTS/CTS .
273#define HT_FORCERTSCTS 9 // Force turn on RTS/CTS first. then go to evaluate if this force RTS is necessary.
274
275//
276// RX Packet Filter control flags. Apply on pAd->PacketFilter
277//
278#define fRX_FILTER_ACCEPT_DIRECT NDIS_PACKET_TYPE_DIRECTED
279#define fRX_FILTER_ACCEPT_MULTICAST NDIS_PACKET_TYPE_MULTICAST
280#define fRX_FILTER_ACCEPT_BROADCAST NDIS_PACKET_TYPE_BROADCAST
281#define fRX_FILTER_ACCEPT_ALL_MULTICAST NDIS_PACKET_TYPE_ALL_MULTICAST
282
283//
284// Error code section
285//
286// NDIS_ERROR_CODE_ADAPTER_NOT_FOUND
287#define ERRLOG_READ_PCI_SLOT_FAILED 0x00000101L
288#define ERRLOG_WRITE_PCI_SLOT_FAILED 0x00000102L
289#define ERRLOG_VENDOR_DEVICE_NOMATCH 0x00000103L
290
291// NDIS_ERROR_CODE_ADAPTER_DISABLED
292#define ERRLOG_BUS_MASTER_DISABLED 0x00000201L
293
294// NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION
295#define ERRLOG_INVALID_SPEED_DUPLEX 0x00000301L
296#define ERRLOG_SET_SECONDARY_FAILED 0x00000302L
297
298// NDIS_ERROR_CODE_OUT_OF_RESOURCES
299#define ERRLOG_OUT_OF_MEMORY 0x00000401L
300#define ERRLOG_OUT_OF_SHARED_MEMORY 0x00000402L
301#define ERRLOG_OUT_OF_MAP_REGISTERS 0x00000403L
302#define ERRLOG_OUT_OF_BUFFER_POOL 0x00000404L
303#define ERRLOG_OUT_OF_NDIS_BUFFER 0x00000405L
304#define ERRLOG_OUT_OF_PACKET_POOL 0x00000406L
305#define ERRLOG_OUT_OF_NDIS_PACKET 0x00000407L
306#define ERRLOG_OUT_OF_LOOKASIDE_MEMORY 0x00000408L
307
308// NDIS_ERROR_CODE_HARDWARE_FAILURE
309#define ERRLOG_SELFTEST_FAILED 0x00000501L
310#define ERRLOG_INITIALIZE_ADAPTER 0x00000502L
311#define ERRLOG_REMOVE_MINIPORT 0x00000503L
312
313// NDIS_ERROR_CODE_RESOURCE_CONFLICT
314#define ERRLOG_MAP_IO_SPACE 0x00000601L
315#define ERRLOG_QUERY_ADAPTER_RESOURCES 0x00000602L
316#define ERRLOG_NO_IO_RESOURCE 0x00000603L
317#define ERRLOG_NO_INTERRUPT_RESOURCE 0x00000604L
318#define ERRLOG_NO_MEMORY_RESOURCE 0x00000605L
319
320
321// WDS definition
322#define MAX_WDS_ENTRY 4
323#define WDS_PAIRWISE_KEY_OFFSET 60 // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
324
325#define WDS_DISABLE_MODE 0
326#define WDS_RESTRICT_MODE 1
327#define WDS_BRIDGE_MODE 2
328#define WDS_REPEATER_MODE 3
329#define WDS_LAZY_MODE 4
330
331
332#define MAX_MESH_NUM 0
333
334#define MAX_APCLI_NUM 0
335#ifdef APCLI_SUPPORT
336#undef MAX_APCLI_NUM
337#define MAX_APCLI_NUM 1
338#endif // APCLI_SUPPORT //
339
340#define MAX_MBSSID_NUM 1
341
342/* sanity check for apidx */
343#define MBSS_MR_APIDX_SANITY_CHECK(apidx) \
344 { if (apidx > MAX_MBSSID_NUM) { \
345 printk("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __FUNCTION__, apidx); \
346 apidx = MAIN_MBSSID; } }
347
348#define VALID_WCID(_wcid) ((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE )
349
350#define MAIN_MBSSID 0
351#define FIRST_MBSSID 1
352
353
354#define MAX_BEACON_SIZE 512
355// If the MAX_MBSSID_NUM is larger than 6,
356// it shall reserve some WCID space(wcid 222~253) for beacon frames.
357// - these wcid 238~253 are reserved for beacon#6(ra6).
358// - these wcid 222~237 are reserved for beacon#7(ra7).
359#if defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 8)
360#define HW_RESERVED_WCID 222
361#elif defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 7)
362#define HW_RESERVED_WCID 238
363#else
364#define HW_RESERVED_WCID 255
365#endif
366
367// Then dedicate wcid of DFS and Carrier-Sense.
368#define DFS_CTS_WCID (HW_RESERVED_WCID - 1)
369#define CS_CTS_WCID (HW_RESERVED_WCID - 2)
370#define LAST_SPECIFIC_WCID (HW_RESERVED_WCID - 2)
371
372// If MAX_MBSSID_NUM is 8, the maximum available wcid for the associated STA is 211.
373// If MAX_MBSSID_NUM is 7, the maximum available wcid for the associated STA is 228.
374#define MAX_AVAILABLE_CLIENT_WCID (LAST_SPECIFIC_WCID - MAX_MBSSID_NUM - 1)
375
376// TX need WCID to find Cipher Key
377// these wcid 212 ~ 219 are reserved for bc/mc packets if MAX_MBSSID_NUM is 8.
378#define GET_GroupKey_WCID(__wcid, __bssidx) \
379 { \
380 __wcid = LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM) + __bssidx; \
381 }
382
383#define IsGroupKeyWCID(__wcid) (((__wcid) < LAST_SPECIFIC_WCID) && ((__wcid) >= (LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM))))
384
385
386// definition to support multiple BSSID
387#define BSS0 0
388#define BSS1 1
389#define BSS2 2
390#define BSS3 3
391#define BSS4 4
392#define BSS5 5
393#define BSS6 6
394#define BSS7 7
395
396
397//============================================================
398// Length definitions
399#define PEER_KEY_NO 2
400#define MAC_ADDR_LEN 6
401#define TIMESTAMP_LEN 8
402#define MAX_LEN_OF_SUPPORTED_RATES MAX_LENGTH_OF_SUPPORT_RATES // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
403#define MAX_LEN_OF_KEY 32 // 32 octets == 256 bits, Redefine for WPA
404#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
405#define MAX_NUM_OF_11JCHANNELS 20 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
406#define MAX_LEN_OF_SSID 32
407#define CIPHER_TEXT_LEN 128
408#define HASH_TABLE_SIZE 256
409#define MAX_VIE_LEN 1024 // New for WPA cipher suite variable IE sizes.
410#define MAX_SUPPORT_MCS 32
411
412//============================================================
413// ASIC WCID Table definition.
414//============================================================
415#define BSSID_WCID 1 // in infra mode, always put bssid with this WCID
416#define MCAST_WCID 0x0
417#define BSS0Mcast_WCID 0x0
418#define BSS1Mcast_WCID 0xf8
419#define BSS2Mcast_WCID 0xf9
420#define BSS3Mcast_WCID 0xfa
421#define BSS4Mcast_WCID 0xfb
422#define BSS5Mcast_WCID 0xfc
423#define BSS6Mcast_WCID 0xfd
424#define BSS7Mcast_WCID 0xfe
425#define RESERVED_WCID 0xff
426
427#define MAX_NUM_OF_ACL_LIST MAX_NUMBER_OF_ACL
428
429#define MAX_LEN_OF_MAC_TABLE MAX_NUMBER_OF_MAC // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
430
431#if MAX_LEN_OF_MAC_TABLE>MAX_AVAILABLE_CLIENT_WCID
432#error MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID!!!!
433#endif
434
435#define MAX_NUM_OF_WDS_LINK_PERBSSID 3
436#define MAX_NUM_OF_WDS_LINK (MAX_NUM_OF_WDS_LINK_PERBSSID*MAX_MBSSID_NUM)
437#define MAX_NUM_OF_EVENT MAX_NUMBER_OF_EVENT
438#define WDS_LINK_START_WCID (MAX_LEN_OF_MAC_TABLE-1)
439
440#define NUM_OF_TID 8
441#define MAX_AID_BA 4
442#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
443#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
444#define MAX_LEN_OF_BSS_TABLE 64
445#define MAX_REORDERING_MPDU_NUM 512
446
447// key related definitions
448#define SHARE_KEY_NUM 4
449#define MAX_LEN_OF_SHARE_KEY 16 // byte count
450#define MAX_LEN_OF_PEER_KEY 16 // byte count
451#define PAIRWISE_KEY_NUM 64 // in MAC ASIC pairwise key table
452#define GROUP_KEY_NUM 4
453#define PMK_LEN 32
454#define WDS_PAIRWISE_KEY_OFFSET 60 // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
455#define PMKID_NO 4 // Number of PMKID saved supported
456#define MAX_LEN_OF_MLME_BUFFER 2048
457
458// power status related definitions
459#define PWR_ACTIVE 0
460#define PWR_SAVE 1
461#define PWR_MMPS 2 //MIMO power save
462//#define PWR_UNKNOWN 2
463
464// Auth and Assoc mode related definitions
465#define AUTH_MODE_OPEN 0x00
466#define AUTH_MODE_KEY 0x01
467//#define AUTH_MODE_AUTO_SWITCH 0x03
468//#define AUTH_MODE_DEAUTH 0x04
469//#define AUTH_MODE_UPLAYER 0x05 // reserved for 802.11i use
470
471// BSS Type definitions
472#define BSS_ADHOC 0 // = Ndis802_11IBSS
473#define BSS_INFRA 1 // = Ndis802_11Infrastructure
474#define BSS_ANY 2 // = Ndis802_11AutoUnknown
475#define BSS_MONITOR 3 // = Ndis802_11Monitor
476
477
478// Reason code definitions
479#define REASON_RESERVED 0
480#define REASON_UNSPECIFY 1
481#define REASON_NO_LONGER_VALID 2
482#define REASON_DEAUTH_STA_LEAVING 3
483#define REASON_DISASSOC_INACTIVE 4
484#define REASON_DISASSPC_AP_UNABLE 5
485#define REASON_CLS2ERR 6
486#define REASON_CLS3ERR 7
487#define REASON_DISASSOC_STA_LEAVING 8
488#define REASON_STA_REQ_ASSOC_NOT_AUTH 9
489#define REASON_INVALID_IE 13
490#define REASON_MIC_FAILURE 14
491#define REASON_4_WAY_TIMEOUT 15
492#define REASON_GROUP_KEY_HS_TIMEOUT 16
493#define REASON_IE_DIFFERENT 17
494#define REASON_MCIPHER_NOT_VALID 18
495#define REASON_UCIPHER_NOT_VALID 19
496#define REASON_AKMP_NOT_VALID 20
497#define REASON_UNSUPPORT_RSNE_VER 21
498#define REASON_INVALID_RSNE_CAP 22
499#define REASON_8021X_AUTH_FAIL 23
500#define REASON_CIPHER_SUITE_REJECTED 24
501#define REASON_DECLINED 37
502
503#define REASON_QOS_UNSPECIFY 32
504#define REASON_QOS_LACK_BANDWIDTH 33
505#define REASON_POOR_CHANNEL_CONDITION 34
506#define REASON_QOS_OUTSIDE_TXOP_LIMITION 35
507#define REASON_QOS_QSTA_LEAVING_QBSS 36
508#define REASON_QOS_UNWANTED_MECHANISM 37
509#define REASON_QOS_MECH_SETUP_REQUIRED 38
510#define REASON_QOS_REQUEST_TIMEOUT 39
511#define REASON_QOS_CIPHER_NOT_SUPPORT 45
512
513// Status code definitions
514#define MLME_SUCCESS 0
515#define MLME_UNSPECIFY_FAIL 1
516#define MLME_CANNOT_SUPPORT_CAP 10
517#define MLME_REASSOC_DENY_ASSOC_EXIST 11
518#define MLME_ASSOC_DENY_OUT_SCOPE 12
519#define MLME_ALG_NOT_SUPPORT 13
520#define MLME_SEQ_NR_OUT_OF_SEQUENCE 14
521#define MLME_REJ_CHALLENGE_FAILURE 15
522#define MLME_REJ_TIMEOUT 16
523#define MLME_ASSOC_REJ_UNABLE_HANDLE_STA 17
524#define MLME_ASSOC_REJ_DATA_RATE 18
525
526#define MLME_ASSOC_REJ_NO_EXT_RATE 22
527#define MLME_ASSOC_REJ_NO_EXT_RATE_PBCC 23
528#define MLME_ASSOC_REJ_NO_CCK_OFDM 24
529
530#define MLME_QOS_UNSPECIFY 32
531#define MLME_REQUEST_DECLINED 37
532#define MLME_REQUEST_WITH_INVALID_PARAM 38
533#define MLME_DLS_NOT_ALLOW_IN_QBSS 48
534#define MLME_DEST_STA_NOT_IN_QBSS 49
535#define MLME_DEST_STA_IS_NOT_A_QSTA 50
536
537#define MLME_INVALID_FORMAT 0x51
538#define MLME_FAIL_NO_RESOURCE 0x52
539#define MLME_STATE_MACHINE_REJECT 0x53
540#define MLME_MAC_TABLE_FAIL 0x54
541
542// IE code
543#define IE_SSID 0
544#define IE_SUPP_RATES 1
545#define IE_FH_PARM 2
546#define IE_DS_PARM 3
547#define IE_CF_PARM 4
548#define IE_TIM 5
549#define IE_IBSS_PARM 6
550#define IE_COUNTRY 7 // 802.11d
551#define IE_802_11D_REQUEST 10 // 802.11d
552#define IE_QBSS_LOAD 11 // 802.11e d9
553#define IE_EDCA_PARAMETER 12 // 802.11e d9
554#define IE_TSPEC 13 // 802.11e d9
555#define IE_TCLAS 14 // 802.11e d9
556#define IE_SCHEDULE 15 // 802.11e d9
557#define IE_CHALLENGE_TEXT 16
558#define IE_POWER_CONSTRAINT 32 // 802.11h d3.3
559#define IE_POWER_CAPABILITY 33 // 802.11h d3.3
560#define IE_TPC_REQUEST 34 // 802.11h d3.3
561#define IE_TPC_REPORT 35 // 802.11h d3.3
562#define IE_SUPP_CHANNELS 36 // 802.11h d3.3
563#define IE_CHANNEL_SWITCH_ANNOUNCEMENT 37 // 802.11h d3.3
564#define IE_MEASUREMENT_REQUEST 38 // 802.11h d3.3
565#define IE_MEASUREMENT_REPORT 39 // 802.11h d3.3
566#define IE_QUIET 40 // 802.11h d3.3
567#define IE_IBSS_DFS 41 // 802.11h d3.3
568#define IE_ERP 42 // 802.11g
569#define IE_TS_DELAY 43 // 802.11e d9
570#define IE_TCLAS_PROCESSING 44 // 802.11e d9
571#define IE_QOS_CAPABILITY 46 // 802.11e d6
572#define IE_HT_CAP 45 // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
573#define IE_AP_CHANNEL_REPORT 51 // 802.11k d6
574#define IE_HT_CAP2 52 // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
575#define IE_RSN 48 // 802.11i d3.0
576#define IE_WPA2 48 // WPA2
577#define IE_EXT_SUPP_RATES 50 // 802.11g
578#define IE_SUPP_REG_CLASS 59 // 802.11y. Supported regulatory classes.
579#define IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT 60 // 802.11n
580#define IE_ADD_HT 61 // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
581#define IE_ADD_HT2 53 // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
582
583
584// For 802.11n D3.03
585//#define IE_NEW_EXT_CHA_OFFSET 62 // 802.11n d1. New extension channel offset elemet
586#define IE_SECONDARY_CH_OFFSET 62 // 802.11n D3.03 Secondary Channel Offset element
587#define IE_WAPI 68 // WAPI information element
588#define IE_2040_BSS_COEXIST 72 // 802.11n D3.0.3
589#define IE_2040_BSS_INTOLERANT_REPORT 73 // 802.11n D3.03
590#define IE_OVERLAPBSS_SCAN_PARM 74 // 802.11n D3.03
591#define IE_EXT_CAPABILITY 127 // 802.11n D3.03
592
593
594#define IE_WPA 221 // WPA
595#define IE_VENDOR_SPECIFIC 221 // Wifi WMM (WME)
596
597#define OUI_BROADCOM_HT 51 //
598#define OUI_BROADCOM_HTADD 52 //
599#define OUI_PREN_HT_CAP 51 //
600#define OUI_PREN_ADD_HT 52 //
601
602// CCX information
603#define IE_AIRONET_CKIP 133 // CCX1.0 ID 85H for CKIP
604#define IE_AP_TX_POWER 150 // CCX 2.0 for AP transmit power
605#define IE_MEASUREMENT_CAPABILITY 221 // CCX 2.0
606#define IE_CCX_V2 221
607#define IE_AIRONET_IPADDRESS 149 // CCX ID 95H for IP Address
608#define IE_AIRONET_CCKMREASSOC 156 // CCX ID 9CH for CCKM Reassociation Request element
609#define CKIP_NEGOTIATION_LENGTH 30
610#define AIRONET_IPADDRESS_LENGTH 10
611#define AIRONET_CCKMREASSOC_LENGTH 24
612
613// ========================================================
614// MLME state machine definition
615// ========================================================
616
617// STA MLME state mahcines
618#define ASSOC_STATE_MACHINE 1
619#define AUTH_STATE_MACHINE 2
620#define AUTH_RSP_STATE_MACHINE 3
621#define SYNC_STATE_MACHINE 4
622#define MLME_CNTL_STATE_MACHINE 5
623#define WPA_PSK_STATE_MACHINE 6
624#define LEAP_STATE_MACHINE 7
625#define AIRONET_STATE_MACHINE 8
626#define ACTION_STATE_MACHINE 9
627
628// AP MLME state machines
629#define AP_ASSOC_STATE_MACHINE 11
630#define AP_AUTH_STATE_MACHINE 12
631#define AP_AUTH_RSP_STATE_MACHINE 13
632#define AP_SYNC_STATE_MACHINE 14
633#define AP_CNTL_STATE_MACHINE 15
634#define AP_WPA_STATE_MACHINE 16
635
636#ifdef QOS_DLS_SUPPORT
637#define DLS_STATE_MACHINE 26
638#endif // QOS_DLS_SUPPORT //
639
640//
641// STA's CONTROL/CONNECT state machine: states, events, total function #
642//
643#define CNTL_IDLE 0
644#define CNTL_WAIT_DISASSOC 1
645#define CNTL_WAIT_JOIN 2
646#define CNTL_WAIT_REASSOC 3
647#define CNTL_WAIT_START 4
648#define CNTL_WAIT_AUTH 5
649#define CNTL_WAIT_ASSOC 6
650#define CNTL_WAIT_AUTH2 7
651#define CNTL_WAIT_OID_LIST_SCAN 8
652#define CNTL_WAIT_OID_DISASSOC 9
653#ifdef RT2870
654#define CNTL_WAIT_SCAN_FOR_CONNECT 10
655#endif // RT2870 //
656
657#define MT2_ASSOC_CONF 34
658#define MT2_AUTH_CONF 35
659#define MT2_DEAUTH_CONF 36
660#define MT2_DISASSOC_CONF 37
661#define MT2_REASSOC_CONF 38
662#define MT2_PWR_MGMT_CONF 39
663#define MT2_JOIN_CONF 40
664#define MT2_SCAN_CONF 41
665#define MT2_START_CONF 42
666#define MT2_GET_CONF 43
667#define MT2_SET_CONF 44
668#define MT2_RESET_CONF 45
669#define MT2_MLME_ROAMING_REQ 52
670
671#define CNTL_FUNC_SIZE 1
672
673//
674// STA's ASSOC state machine: states, events, total function #
675//
676#define ASSOC_IDLE 0
677#define ASSOC_WAIT_RSP 1
678#define REASSOC_WAIT_RSP 2
679#define DISASSOC_WAIT_RSP 3
680#define MAX_ASSOC_STATE 4
681
682#define ASSOC_MACHINE_BASE 0
683#define MT2_MLME_ASSOC_REQ 0
684#define MT2_MLME_REASSOC_REQ 1
685#define MT2_MLME_DISASSOC_REQ 2
686#define MT2_PEER_DISASSOC_REQ 3
687#define MT2_PEER_ASSOC_REQ 4
688#define MT2_PEER_ASSOC_RSP 5
689#define MT2_PEER_REASSOC_REQ 6
690#define MT2_PEER_REASSOC_RSP 7
691#define MT2_DISASSOC_TIMEOUT 8
692#define MT2_ASSOC_TIMEOUT 9
693#define MT2_REASSOC_TIMEOUT 10
694#define MAX_ASSOC_MSG 11
695
696#define ASSOC_FUNC_SIZE (MAX_ASSOC_STATE * MAX_ASSOC_MSG)
697
698//
699// ACT state machine: states, events, total function #
700//
701#define ACT_IDLE 0
702#define MAX_ACT_STATE 1
703
704#define ACT_MACHINE_BASE 0
705
706//Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please don'es modify it by your self.
707//Category
708#define MT2_PEER_SPECTRUM_CATE 0
709#define MT2_PEER_QOS_CATE 1
710#define MT2_PEER_DLS_CATE 2
711#define MT2_PEER_BA_CATE 3
712#define MT2_PEER_PUBLIC_CATE 4
713#define MT2_PEER_RM_CATE 5
714#define MT2_PEER_HT_CATE 7 // 7.4.7
715#define MAX_PEER_CATE_MSG 7
716#define MT2_MLME_ADD_BA_CATE 8
717#define MT2_MLME_ORI_DELBA_CATE 9
718#define MT2_MLME_REC_DELBA_CATE 10
719#define MT2_MLME_QOS_CATE 11
720#define MT2_MLME_DLS_CATE 12
721#define MT2_ACT_INVALID 13
722#define MAX_ACT_MSG 14
723
724//Category field
725#define CATEGORY_SPECTRUM 0
726#define CATEGORY_QOS 1
727#define CATEGORY_DLS 2
728#define CATEGORY_BA 3
729#define CATEGORY_PUBLIC 4
730#define CATEGORY_RM 5
731#define CATEGORY_HT 7
732
733
734// DLS Action frame definition
735#define ACTION_DLS_REQUEST 0
736#define ACTION_DLS_RESPONSE 1
737#define ACTION_DLS_TEARDOWN 2
738
739//Spectrum Action field value 802.11h 7.4.1
740#define SPEC_MRQ 0 // Request
741#define SPEC_MRP 1 //Report
742#define SPEC_TPCRQ 2
743#define SPEC_TPCRP 3
744#define SPEC_CHANNEL_SWITCH 4
745
746
747//BA Action field value
748#define ADDBA_REQ 0
749#define ADDBA_RESP 1
750#define DELBA 2
751
752//Public's Action field value in Public Category. Some in 802.11y and some in 11n
753#define ACTION_BSS_2040_COEXIST 0 // 11n
754#define ACTION_DSE_ENABLEMENT 1 // 11y D9.0
755#define ACTION_DSE_DEENABLEMENT 2 // 11y D9.0
756#define ACTION_DSE_REG_LOCATION_ANNOUNCE 3 // 11y D9.0
757#define ACTION_EXT_CH_SWITCH_ANNOUNCE 4 // 11y D9.0
758#define ACTION_DSE_MEASUREMENT_REQ 5 // 11y D9.0
759#define ACTION_DSE_MEASUREMENT_REPORT 6 // 11y D9.0
760#define ACTION_MEASUREMENT_PILOT_ACTION 7 // 11y D9.0
761#define ACTION_DSE_POWER_CONSTRAINT 8 // 11y D9.0
762
763
764//HT Action field value
765#define NOTIFY_BW_ACTION 0
766#define SMPS_ACTION 1
767#define PSMP_ACTION 2
768#define SETPCO_ACTION 3
769#define MIMO_CHA_MEASURE_ACTION 4
770#define MIMO_N_BEACONFORM 5
771#define MIMO_BEACONFORM 6
772#define ANTENNA_SELECT 7
773#define HT_INFO_EXCHANGE 8
774
775#define ACT_FUNC_SIZE (MAX_ACT_STATE * MAX_ACT_MSG)
776//
777// STA's AUTHENTICATION state machine: states, evvents, total function #
778//
779#define AUTH_REQ_IDLE 0
780#define AUTH_WAIT_SEQ2 1
781#define AUTH_WAIT_SEQ4 2
782#define MAX_AUTH_STATE 3
783
784#define AUTH_MACHINE_BASE 0
785#define MT2_MLME_AUTH_REQ 0
786#define MT2_PEER_AUTH_EVEN 1
787#define MT2_AUTH_TIMEOUT 2
788#define MAX_AUTH_MSG 3
789
790#define AUTH_FUNC_SIZE (MAX_AUTH_STATE * MAX_AUTH_MSG)
791
792//
793// STA's AUTH_RSP state machine: states, events, total function #
794//
795#define AUTH_RSP_IDLE 0
796#define AUTH_RSP_WAIT_CHAL 1
797#define MAX_AUTH_RSP_STATE 2
798
799#define AUTH_RSP_MACHINE_BASE 0
800#define MT2_AUTH_CHALLENGE_TIMEOUT 0
801#define MT2_PEER_AUTH_ODD 1
802#define MT2_PEER_DEAUTH 2
803#define MAX_AUTH_RSP_MSG 3
804
805#define AUTH_RSP_FUNC_SIZE (MAX_AUTH_RSP_STATE * MAX_AUTH_RSP_MSG)
806
807//
808// STA's SYNC state machine: states, events, total function #
809//
810#define SYNC_IDLE 0 // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
811#define JOIN_WAIT_BEACON 1
812#define SCAN_LISTEN 2
813#define MAX_SYNC_STATE 3
814
815#define SYNC_MACHINE_BASE 0
816#define MT2_MLME_SCAN_REQ 0
817#define MT2_MLME_JOIN_REQ 1
818#define MT2_MLME_START_REQ 2
819#define MT2_PEER_BEACON 3
820#define MT2_PEER_PROBE_RSP 4
821#define MT2_PEER_ATIM 5
822#define MT2_SCAN_TIMEOUT 6
823#define MT2_BEACON_TIMEOUT 7
824#define MT2_ATIM_TIMEOUT 8
825#define MT2_PEER_PROBE_REQ 9
826#define MAX_SYNC_MSG 10
827
828#define SYNC_FUNC_SIZE (MAX_SYNC_STATE * MAX_SYNC_MSG)
829
830//Messages for the DLS state machine
831#define DLS_IDLE 0
832#define MAX_DLS_STATE 1
833
834#define DLS_MACHINE_BASE 0
835#define MT2_MLME_DLS_REQ 0
836#define MT2_PEER_DLS_REQ 1
837#define MT2_PEER_DLS_RSP 2
838#define MT2_MLME_DLS_TEAR_DOWN 3
839#define MT2_PEER_DLS_TEAR_DOWN 4
840#define MAX_DLS_MSG 5
841
842#define DLS_FUNC_SIZE (MAX_DLS_STATE * MAX_DLS_MSG)
843
844//
845// STA's WPA-PSK State machine: states, events, total function #
846//
847#define WPA_PSK_IDLE 0
848#define MAX_WPA_PSK_STATE 1
849
850#define WPA_MACHINE_BASE 0
851#define MT2_EAPPacket 0
852#define MT2_EAPOLStart 1
853#define MT2_EAPOLLogoff 2
854#define MT2_EAPOLKey 3
855#define MT2_EAPOLASFAlert 4
856#define MAX_WPA_PSK_MSG 5
857
858#define WPA_PSK_FUNC_SIZE (MAX_WPA_PSK_STATE * MAX_WPA_PSK_MSG)
859
860//
861// STA's CISCO-AIRONET State machine: states, events, total function #
862//
863#define AIRONET_IDLE 0
864#define AIRONET_SCANNING 1
865#define MAX_AIRONET_STATE 2
866
867#define AIRONET_MACHINE_BASE 0
868#define MT2_AIRONET_MSG 0
869#define MT2_AIRONET_SCAN_REQ 1
870#define MT2_AIRONET_SCAN_DONE 2
871#define MAX_AIRONET_MSG 3
872
873#define AIRONET_FUNC_SIZE (MAX_AIRONET_STATE * MAX_AIRONET_MSG)
874
875//
876// AP's CONTROL/CONNECT state machine: states, events, total function #
877//
878#define AP_CNTL_FUNC_SIZE 1
879
880//
881// AP's ASSOC state machine: states, events, total function #
882//
883#define AP_ASSOC_IDLE 0
884#define AP_MAX_ASSOC_STATE 1
885
886#define AP_ASSOC_MACHINE_BASE 0
887#define APMT2_MLME_DISASSOC_REQ 0
888#define APMT2_PEER_DISASSOC_REQ 1
889#define APMT2_PEER_ASSOC_REQ 2
890#define APMT2_PEER_REASSOC_REQ 3
891#define APMT2_CLS3ERR 4
892#define AP_MAX_ASSOC_MSG 5
893
894#define AP_ASSOC_FUNC_SIZE (AP_MAX_ASSOC_STATE * AP_MAX_ASSOC_MSG)
895
896//
897// AP's AUTHENTICATION state machine: states, events, total function #
898//
899#define AP_AUTH_REQ_IDLE 0
900#define AP_MAX_AUTH_STATE 1
901
902#define AP_AUTH_MACHINE_BASE 0
903#define APMT2_MLME_DEAUTH_REQ 0
904#define APMT2_CLS2ERR 1
905#define AP_MAX_AUTH_MSG 2
906
907#define AP_AUTH_FUNC_SIZE (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG)
908
909//
910// AP's AUTH-RSP state machine: states, events, total function #
911//
912#define AP_AUTH_RSP_IDLE 0
913#define AP_MAX_AUTH_RSP_STATE 1
914
915#define AP_AUTH_RSP_MACHINE_BASE 0
916#define APMT2_AUTH_CHALLENGE_TIMEOUT 0
917#define APMT2_PEER_AUTH_ODD 1
918#define APMT2_PEER_DEAUTH 2
919#define AP_MAX_AUTH_RSP_MSG 3
920
921#define AP_AUTH_RSP_FUNC_SIZE (AP_MAX_AUTH_RSP_STATE * AP_MAX_AUTH_RSP_MSG)
922
923//
924// AP's SYNC state machine: states, events, total function #
925//
926#define AP_SYNC_IDLE 0
927#define AP_SCAN_LISTEN 1
928#define AP_MAX_SYNC_STATE 2
929
930#define AP_SYNC_MACHINE_BASE 0
931#define APMT2_PEER_PROBE_REQ 0
932#define APMT2_PEER_BEACON 1
933#define APMT2_MLME_SCAN_REQ 2
934#define APMT2_PEER_PROBE_RSP 3
935#define APMT2_SCAN_TIMEOUT 4
936#define APMT2_MLME_SCAN_CNCL 5
937#define AP_MAX_SYNC_MSG 6
938
939#define AP_SYNC_FUNC_SIZE (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG)
940
941//
942// AP's WPA state machine: states, events, total function #
943//
944#define AP_WPA_PTK 0
945#define AP_MAX_WPA_PTK_STATE 1
946
947#define AP_WPA_MACHINE_BASE 0
948#define APMT2_EAPPacket 0
949#define APMT2_EAPOLStart 1
950#define APMT2_EAPOLLogoff 2
951#define APMT2_EAPOLKey 3
952#define APMT2_EAPOLASFAlert 4
953#define AP_MAX_WPA_MSG 5
954
955#define AP_WPA_FUNC_SIZE (AP_MAX_WPA_PTK_STATE * AP_MAX_WPA_MSG)
956
957#ifdef APCLI_SUPPORT
958//ApCli authentication state machine
959#define APCLI_AUTH_REQ_IDLE 0
960#define APCLI_AUTH_WAIT_SEQ2 1
961#define APCLI_AUTH_WAIT_SEQ4 2
962#define APCLI_MAX_AUTH_STATE 3
963
964#define APCLI_AUTH_MACHINE_BASE 0
965#define APCLI_MT2_MLME_AUTH_REQ 0
966#define APCLI_MT2_MLME_DEAUTH_REQ 1
967#define APCLI_MT2_PEER_AUTH_EVEN 2
968#define APCLI_MT2_PEER_DEAUTH 3
969#define APCLI_MT2_AUTH_TIMEOUT 4
970#define APCLI_MAX_AUTH_MSG 5
971
972#define APCLI_AUTH_FUNC_SIZE (APCLI_MAX_AUTH_STATE * APCLI_MAX_AUTH_MSG)
973
974//ApCli association state machine
975#define APCLI_ASSOC_IDLE 0
976#define APCLI_ASSOC_WAIT_RSP 1
977#define APCLI_MAX_ASSOC_STATE 2
978
979#define APCLI_ASSOC_MACHINE_BASE 0
980#define APCLI_MT2_MLME_ASSOC_REQ 0
981#define APCLI_MT2_MLME_DISASSOC_REQ 1
982#define APCLI_MT2_PEER_DISASSOC_REQ 2
983#define APCLI_MT2_PEER_ASSOC_RSP 3
984#define APCLI_MT2_ASSOC_TIMEOUT 4
985#define APCLI_MAX_ASSOC_MSG 5
986
987#define APCLI_ASSOC_FUNC_SIZE (APCLI_MAX_ASSOC_STATE * APCLI_MAX_ASSOC_MSG)
988
989//ApCli sync state machine
990#define APCLI_SYNC_IDLE 0 // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
991#define APCLI_JOIN_WAIT_PROBE_RSP 1
992#define APCLI_MAX_SYNC_STATE 2
993
994#define APCLI_SYNC_MACHINE_BASE 0
995#define APCLI_MT2_MLME_PROBE_REQ 0
996#define APCLI_MT2_PEER_PROBE_RSP 1
997#define APCLI_MT2_PROBE_TIMEOUT 2
998#define APCLI_MAX_SYNC_MSG 3
999
1000#define APCLI_SYNC_FUNC_SIZE (APCLI_MAX_SYNC_STATE * APCLI_MAX_SYNC_MSG)
1001
1002//ApCli ctrl state machine
1003#define APCLI_CTRL_DISCONNECTED 0 // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
1004#define APCLI_CTRL_PROBE 1
1005#define APCLI_CTRL_AUTH 2
1006#define APCLI_CTRL_AUTH_2 3
1007#define APCLI_CTRL_ASSOC 4
1008#define APCLI_CTRL_DEASSOC 5
1009#define APCLI_CTRL_CONNECTED 6
1010#define APCLI_MAX_CTRL_STATE 7
1011
1012#define APCLI_CTRL_MACHINE_BASE 0
1013#define APCLI_CTRL_JOIN_REQ 0
1014#define APCLI_CTRL_PROBE_RSP 1
1015#define APCLI_CTRL_AUTH_RSP 2
1016#define APCLI_CTRL_DISCONNECT_REQ 3
1017#define APCLI_CTRL_PEER_DISCONNECT_REQ 4
1018#define APCLI_CTRL_ASSOC_RSP 5
1019#define APCLI_CTRL_DEASSOC_RSP 6
1020#define APCLI_CTRL_JOIN_REQ_TIMEOUT 7
1021#define APCLI_CTRL_AUTH_REQ_TIMEOUT 8
1022#define APCLI_CTRL_ASSOC_REQ_TIMEOUT 9
1023#define APCLI_MAX_CTRL_MSG 10
1024
1025#define APCLI_CTRL_FUNC_SIZE (APCLI_MAX_CTRL_STATE * APCLI_MAX_CTRL_MSG)
1026
1027#if 0 // remove those variables by AlbertY
1028// ApCli WPA state machine
1029#define APCLI_WPA_PSK_IDLE 0
1030#define APCLI_MAX_WPA_PSK_STATE 1
1031
1032// ApCli WPA MSG Type
1033#define APCLI_WPA_MACHINE_BASE 0
1034#define APCLI_MT2_EAPPacket 0
1035#define APCLI_MT2_EAPOLStart 1
1036#define APCLI_MT2_EAPOLLogoff 2
1037#define APCLI_MT2_EAPOLKey 3
1038#define APCLI_MT2_EAPOLASFAlert 4
1039#define APCLI_MAX_WPA_PSK_MSG 5
1040
1041#define APCLI_WPA_PSK_FUNC_SIZE (APCLI_MAX_WPA_PSK_STATE * APCLI_MAX_WPA_PSK_MSG)
1042#endif // end - 0 //
1043
1044#endif // APCLI_SUPPORT //
1045
1046
1047// =============================================================================
1048
1049// value domain of 802.11 header FC.Tyte, which is b3..b2 of the 1st-byte of MAC header
1050#define BTYPE_MGMT 0
1051#define BTYPE_CNTL 1
1052#define BTYPE_DATA 2
1053
1054// value domain of 802.11 MGMT frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
1055#define SUBTYPE_ASSOC_REQ 0
1056#define SUBTYPE_ASSOC_RSP 1
1057#define SUBTYPE_REASSOC_REQ 2
1058#define SUBTYPE_REASSOC_RSP 3
1059#define SUBTYPE_PROBE_REQ 4
1060#define SUBTYPE_PROBE_RSP 5
1061#define SUBTYPE_BEACON 8
1062#define SUBTYPE_ATIM 9
1063#define SUBTYPE_DISASSOC 10
1064#define SUBTYPE_AUTH 11
1065#define SUBTYPE_DEAUTH 12
1066#define SUBTYPE_ACTION 13
1067#define SUBTYPE_ACTION_NO_ACK 14
1068
1069// value domain of 802.11 CNTL frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
1070#define SUBTYPE_WRAPPER 7
1071#define SUBTYPE_BLOCK_ACK_REQ 8
1072#define SUBTYPE_BLOCK_ACK 9
1073#define SUBTYPE_PS_POLL 10
1074#define SUBTYPE_RTS 11
1075#define SUBTYPE_CTS 12
1076#define SUBTYPE_ACK 13
1077#define SUBTYPE_CFEND 14
1078#define SUBTYPE_CFEND_CFACK 15
1079
1080// value domain of 802.11 DATA frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
1081#define SUBTYPE_DATA 0
1082#define SUBTYPE_DATA_CFACK 1
1083#define SUBTYPE_DATA_CFPOLL 2
1084#define SUBTYPE_DATA_CFACK_CFPOLL 3
1085#define SUBTYPE_NULL_FUNC 4
1086#define SUBTYPE_CFACK 5
1087#define SUBTYPE_CFPOLL 6
1088#define SUBTYPE_CFACK_CFPOLL 7
1089#define SUBTYPE_QDATA 8
1090#define SUBTYPE_QDATA_CFACK 9
1091#define SUBTYPE_QDATA_CFPOLL 10
1092#define SUBTYPE_QDATA_CFACK_CFPOLL 11
1093#define SUBTYPE_QOS_NULL 12
1094#define SUBTYPE_QOS_CFACK 13
1095#define SUBTYPE_QOS_CFPOLL 14
1096#define SUBTYPE_QOS_CFACK_CFPOLL 15
1097
1098// ACK policy of QOS Control field bit 6:5
1099#define NORMAL_ACK 0x00 // b6:5 = 00
1100#define NO_ACK 0x20 // b6:5 = 01
1101#define NO_EXPLICIT_ACK 0x40 // b6:5 = 10
1102#define BLOCK_ACK 0x60 // b6:5 = 11
1103
1104//
1105// rtmp_data.c use these definition
1106//
1107#define LENGTH_802_11 24
1108#define LENGTH_802_11_AND_H 30
1109#define LENGTH_802_11_CRC_H 34
1110#define LENGTH_802_11_CRC 28
1111#define LENGTH_802_11_WITH_ADDR4 30
1112#define LENGTH_802_3 14
1113#define LENGTH_802_3_TYPE 2
1114#define LENGTH_802_1_H 8
1115#define LENGTH_EAPOL_H 4
1116#define LENGTH_WMMQOS_H 2
1117#define LENGTH_CRC 4
1118#define MAX_SEQ_NUMBER 0x0fff
1119#define LENGTH_802_3_NO_TYPE 12
1120#define LENGTH_802_1Q 4 /* VLAN related */
1121
1122// STA_CSR4.field.TxResult
1123#define TX_RESULT_SUCCESS 0
1124#define TX_RESULT_ZERO_LENGTH 1
1125#define TX_RESULT_UNDER_RUN 2
1126#define TX_RESULT_OHY_ERROR 4
1127#define TX_RESULT_RETRY_FAIL 6
1128
1129// All PHY rate summary in TXD
1130// Preamble MODE in TxD
1131#define MODE_CCK 0
1132#define MODE_OFDM 1
1133#ifdef DOT11_N_SUPPORT
1134#define MODE_HTMIX 2
1135#define MODE_HTGREENFIELD 3
1136#endif // DOT11_N_SUPPORT //
1137// MCS for CCK. BW.SGI.STBC are reserved
1138#define MCS_LONGP_RATE_1 0 // long preamble CCK 1Mbps
1139#define MCS_LONGP_RATE_2 1 // long preamble CCK 1Mbps
1140#define MCS_LONGP_RATE_5_5 2
1141#define MCS_LONGP_RATE_11 3
1142#define MCS_SHORTP_RATE_1 4 // long preamble CCK 1Mbps. short is forbidden in 1Mbps
1143#define MCS_SHORTP_RATE_2 5 // short preamble CCK 2Mbps
1144#define MCS_SHORTP_RATE_5_5 6
1145#define MCS_SHORTP_RATE_11 7
1146// To send duplicate legacy OFDM. set BW=BW_40. SGI.STBC are reserved
1147#define MCS_RATE_6 0 // legacy OFDM
1148#define MCS_RATE_9 1 // OFDM
1149#define MCS_RATE_12 2 // OFDM
1150#define MCS_RATE_18 3 // OFDM
1151#define MCS_RATE_24 4 // OFDM
1152#define MCS_RATE_36 5 // OFDM
1153#define MCS_RATE_48 6 // OFDM
1154#define MCS_RATE_54 7 // OFDM
1155// HT
1156#define MCS_0 0 // 1S
1157#define MCS_1 1
1158#define MCS_2 2
1159#define MCS_3 3
1160#define MCS_4 4
1161#define MCS_5 5
1162#define MCS_6 6
1163#define MCS_7 7
1164#define MCS_8 8 // 2S
1165#define MCS_9 9
1166#define MCS_10 10
1167#define MCS_11 11
1168#define MCS_12 12
1169#define MCS_13 13
1170#define MCS_14 14
1171#define MCS_15 15
1172#define MCS_16 16 // 3*3
1173#define MCS_17 17
1174#define MCS_18 18
1175#define MCS_19 19
1176#define MCS_20 20
1177#define MCS_21 21
1178#define MCS_22 22
1179#define MCS_23 23
1180#define MCS_32 32
1181#define MCS_AUTO 33
1182
1183#ifdef DOT11_N_SUPPORT
1184// OID_HTPHYMODE
1185// MODE
1186#define HTMODE_MM 0
1187#define HTMODE_GF 1
1188#endif // DOT11_N_SUPPORT //
1189
1190// Fixed Tx MODE - HT, CCK or OFDM
1191#define FIXED_TXMODE_HT 0
1192#define FIXED_TXMODE_CCK 1
1193#define FIXED_TXMODE_OFDM 2
1194// BW
1195#define BW_20 BAND_WIDTH_20
1196#define BW_40 BAND_WIDTH_40
1197#define BW_BOTH BAND_WIDTH_BOTH
1198#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.
1199
1200#ifdef DOT11_N_SUPPORT
1201// SHORTGI
1202#define GI_400 GAP_INTERVAL_400 // only support in HT mode
1203#define GI_BOTH GAP_INTERVAL_BOTH
1204#endif // DOT11_N_SUPPORT //
1205#define GI_800 GAP_INTERVAL_800
1206// STBC
1207#define STBC_NONE 0
1208#ifdef DOT11_N_SUPPORT
1209#define STBC_USE 1 // limited use in rt2860b phy
1210#define RXSTBC_ONE 1 // rx support of one spatial stream
1211#define RXSTBC_TWO 2 // rx support of 1 and 2 spatial stream
1212#define RXSTBC_THR 3 // rx support of 1~3 spatial stream
1213// MCS FEEDBACK
1214#define MCSFBK_NONE 0 // not support mcs feedback /
1215#define MCSFBK_RSV 1 // reserved
1216#define MCSFBK_UNSOLICIT 2 // only support unsolict mcs feedback
1217#define MCSFBK_MRQ 3 // response to both MRQ and unsolict mcs feedback
1218
1219// MIMO power safe
1220#define MMPS_STATIC 0
1221#define MMPS_DYNAMIC 1
1222#define MMPS_RSV 2
1223#define MMPS_ENABLE 3
1224
1225
1226// A-MSDU size
1227#define AMSDU_0 0
1228#define AMSDU_1 1
1229
1230#endif // DOT11_N_SUPPORT //
1231
1232// MCS use 7 bits
1233#define TXRATEMIMO 0x80
1234#define TXRATEMCS 0x7F
1235#define TXRATEOFDM 0x7F
1236#define RATE_1 0
1237#define RATE_2 1
1238#define RATE_5_5 2
1239#define RATE_11 3
1240#define RATE_6 4 // OFDM
1241#define RATE_9 5 // OFDM
1242#define RATE_12 6 // OFDM
1243#define RATE_18 7 // OFDM
1244#define RATE_24 8 // OFDM
1245#define RATE_36 9 // OFDM
1246#define RATE_48 10 // OFDM
1247#define RATE_54 11 // OFDM
1248#define RATE_FIRST_OFDM_RATE RATE_6
1249#define RATE_LAST_OFDM_RATE RATE_54
1250#define RATE_6_5 12 // HT mix
1251#define RATE_13 13 // HT mix
1252#define RATE_19_5 14 // HT mix
1253#define RATE_26 15 // HT mix
1254#define RATE_39 16 // HT mix
1255#define RATE_52 17 // HT mix
1256#define RATE_58_5 18 // HT mix
1257#define RATE_65 19 // HT mix
1258#define RATE_78 20 // HT mix
1259#define RATE_104 21 // HT mix
1260#define RATE_117 22 // HT mix
1261#define RATE_130 23 // HT mix
1262//#define RATE_AUTO_SWITCH 255 // for StaCfg.FixedTxRate only
1263#define HTRATE_0 12
1264#define RATE_FIRST_MM_RATE HTRATE_0
1265#define RATE_FIRST_HT_RATE HTRATE_0
1266#define RATE_LAST_HT_RATE HTRATE_0
1267
1268// pTxWI->txop
1269#define IFS_HTTXOP 0 // The txop will be handles by ASIC.
1270#define IFS_PIFS 1
1271#define IFS_SIFS 2
1272#define IFS_BACKOFF 3
1273
1274// pTxD->RetryMode
1275#define LONG_RETRY 1
1276#define SHORT_RETRY 0
1277
1278// Country Region definition
1279#define REGION_MINIMUM_BG_BAND 0
1280#define REGION_0_BG_BAND 0 // 1-11
1281#define REGION_1_BG_BAND 1 // 1-13
1282#define REGION_2_BG_BAND 2 // 10-11
1283#define REGION_3_BG_BAND 3 // 10-13
1284#define REGION_4_BG_BAND 4 // 14
1285#define REGION_5_BG_BAND 5 // 1-14
1286#define REGION_6_BG_BAND 6 // 3-9
1287#define REGION_7_BG_BAND 7 // 5-13
1288#define REGION_31_BG_BAND 31 // 5-13
1289#define REGION_MAXIMUM_BG_BAND 7
1290
1291#define REGION_MINIMUM_A_BAND 0
1292#define REGION_0_A_BAND 0 // 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165
1293#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
1294#define REGION_2_A_BAND 2 // 36, 40, 44, 48, 52, 56, 60, 64
1295#define REGION_3_A_BAND 3 // 52, 56, 60, 64, 149, 153, 157, 161
1296#define REGION_4_A_BAND 4 // 149, 153, 157, 161, 165
1297#define REGION_5_A_BAND 5 // 149, 153, 157, 161
1298#define REGION_6_A_BAND 6 // 36, 40, 44, 48
1299#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
1300#define REGION_8_A_BAND 8 // 52, 56, 60, 64
1301#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
1302#define REGION_10_A_BAND 10 // 36, 40, 44, 48, 149, 153, 157, 161, 165
1303#define REGION_11_A_BAND 11 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161
1304#define REGION_MAXIMUM_A_BAND 11
1305
1306// pTxD->CipherAlg
1307#define CIPHER_NONE 0
1308#define CIPHER_WEP64 1
1309#define CIPHER_WEP128 2
1310#define CIPHER_TKIP 3
1311#define CIPHER_AES 4
1312#define CIPHER_CKIP64 5
1313#define CIPHER_CKIP128 6
1314#define CIPHER_TKIP_NO_MIC 7 // MIC appended by driver: not a valid value in hardware key table
1315#define CIPHER_SMS4 8
1316
1317// value domain of pAd->RfIcType
1318#define RFIC_2820 1 // 2.4G 2T3R
1319#define RFIC_2850 2 // 2.4G/5G 2T3R
1320#define RFIC_2720 3 // 2.4G 1T2R
1321#define RFIC_2750 4 // 2.4G/5G 1T2R
1322#define RFIC_3020 5 // 2.4G 1T1R
1323#define RFIC_2020 6 // 2.4G B/G
1324
1325// LED Status.
1326#define LED_LINK_DOWN 0
1327#define LED_LINK_UP 1
1328#define LED_RADIO_OFF 2
1329#define LED_RADIO_ON 3
1330#define LED_HALT 4
1331#define LED_WPS 5
1332#define LED_ON_SITE_SURVEY 6
1333#define LED_POWER_UP 7
1334
1335// value domain of pAd->LedCntl.LedMode and E2PROM
1336#define LED_MODE_DEFAULT 0
1337#define LED_MODE_TWO_LED 1
1338#define LED_MODE_SIGNAL_STREGTH 8 // EEPROM define =8
1339
1340// RC4 init value, used fro WEP & TKIP
1341#define PPPINITFCS32 0xffffffff /* Initial FCS value */
1342
1343// value domain of pAd->StaCfg.PortSecured. 802.1X controlled port definition
1344#define WPA_802_1X_PORT_SECURED 1
1345#define WPA_802_1X_PORT_NOT_SECURED 2
1346
1347#define PAIRWISE_KEY 1
1348#define GROUP_KEY 2
1349
1350//definition of DRS
1351#define MAX_STEP_OF_TX_RATE_SWITCH 32
1352
1353
1354// pre-allocated free NDIS PACKET/BUFFER poll for internal usage
1355#define MAX_NUM_OF_FREE_NDIS_PACKET 128
1356
1357//Block ACK
1358#define MAX_TX_REORDERBUF 64
1359#define MAX_RX_REORDERBUF 64
1360#define DEFAULT_TX_TIMEOUT 30
1361#define DEFAULT_RX_TIMEOUT 30
1362
1363// definition of Recipient or Originator
1364#define I_RECIPIENT TRUE
1365#define I_ORIGINATOR FALSE
1366
1367#define DEFAULT_BBP_TX_POWER 0
1368#define DEFAULT_RF_TX_POWER 5
1369
1370#define MAX_INI_BUFFER_SIZE 4096
1371#define MAX_PARAM_BUFFER_SIZE (2048) // enough for ACL (18*64)
1372 //18 : the length of Mac address acceptable format "01:02:03:04:05:06;")
1373 //64 : MAX_NUM_OF_ACL_LIST
1374// definition of pAd->OpMode
1375#define OPMODE_STA 0
1376#define OPMODE_AP 1
1377//#define OPMODE_L3_BRG 2 // as AP and STA at the same time
1378
1379#ifdef RT_BIG_ENDIAN
1380#define DIR_READ 0
1381#define DIR_WRITE 1
1382#define TYPE_TXD 0
1383#define TYPE_RXD 1
1384#define TYPE_TXINFO 0
1385#define TYPE_RXINFO 1
1386#define TYPE_TXWI 0
1387#define TYPE_RXWI 1
1388#endif
1389
1390// ========================= AP rtmp_def.h ===========================
1391// value domain for pAd->EventTab.Log[].Event
1392#define EVENT_RESET_ACCESS_POINT 0 // Log = "hh:mm:ss Restart Access Point"
1393#define EVENT_ASSOCIATED 1 // Log = "hh:mm:ss STA 00:01:02:03:04:05 associated"
1394#define EVENT_DISASSOCIATED 2 // Log = "hh:mm:ss STA 00:01:02:03:04:05 left this BSS"
1395#define EVENT_AGED_OUT 3 // Log = "hh:mm:ss STA 00:01:02:03:04:05 was aged-out and removed from this BSS"
1396#define EVENT_COUNTER_M 4
1397#define EVENT_INVALID_PSK 5
1398#define EVENT_MAX_EVENT_TYPE 6
1399// ==== end of AP rtmp_def.h ============
1400
1401// definition RSSI Number
1402#define RSSI_0 0
1403#define RSSI_1 1
1404#define RSSI_2 2
1405
1406// definition of radar detection
1407#define RD_NORMAL_MODE 0 // Not found radar signal
1408#define RD_SWITCHING_MODE 1 // Found radar signal, and doing channel switch
1409#define RD_SILENCE_MODE 2 // After channel switch, need to be silence a while to ensure radar not found
1410
1411//Driver defined cid for mapping status and command.
1412#define SLEEPCID 0x11
1413#define WAKECID 0x22
1414#define QUERYPOWERCID 0x33
1415#define OWNERMCU 0x1
1416#define OWNERCPU 0x0
1417
1418// MBSSID definition
1419#define ENTRY_NOT_FOUND 0xFF
1420
1421
1422/* After Linux 2.6.9,
1423 * VLAN module use Private (from user) interface flags (netdevice->priv_flags).
1424 * #define IFF_802_1Q_VLAN 0x1 -- 802.1Q VLAN device. in if.h
1425 * ref to ip_sabotage_out() [ out->priv_flags & IFF_802_1Q_VLAN ] in br_netfilter.c
1426 *
1427 * For this reason, we MUST use EVEN value in priv_flags
1428 */
1429#define INT_MAIN 0x0100
1430#define INT_MBSSID 0x0200
1431#define INT_WDS 0x0300
1432#define INT_APCLI 0x0400
1433#define INT_MESH 0x0500
1434
1435// Use bitmap to allow coexist of ATE_TXFRAME and ATE_RXFRAME(i.e.,to support LoopBack mode)
1436#ifdef RALINK_ATE
1437#define ATE_START 0x00 // Start ATE
1438#define ATE_STOP 0x80 // Stop ATE
1439#define ATE_TXCONT 0x05 // Continuous Transmit
1440#define ATE_TXCARR 0x09 // Transmit Carrier
1441#define ATE_TXCARRSUPP 0x11 // Transmit Carrier Suppression
1442#define ATE_TXFRAME 0x01 // Transmit Frames
1443#define ATE_RXFRAME 0x02 // Receive Frames
1444#ifdef RALINK_28xx_QA
1445#define ATE_TXSTOP 0xe2 // Stop Transmition(i.e., TXCONT, TXCARR, TXCARRSUPP, and TXFRAME)
1446#define ATE_RXSTOP 0xfd // Stop receiving Frames
1447#define BBP22_TXFRAME 0x00 // Transmit Frames
1448#define BBP22_TXCONT_OR_CARRSUPP 0x80 // Continuous Transmit or Carrier Suppression
1449#define BBP22_TXCARR 0xc1 // Transmit Carrier
1450#define BBP24_TXCONT 0x00 // Continuous Transmit
1451#define BBP24_CARRSUPP 0x01 // Carrier Suppression
1452#endif // RALINK_28xx_QA //
1453#endif // RALINK_ATE //
1454
1455// WEP Key TYPE
1456#define WEP_HEXADECIMAL_TYPE 0
1457#define WEP_ASCII_TYPE 1
1458
1459
1460
1461// WIRELESS EVENTS definition
1462/* Max number of char in custom event, refer to wireless_tools.28/wireless.20.h */
1463#define IW_CUSTOM_MAX_LEN 255 /* In bytes */
1464
1465// For system event - start
1466#define IW_SYS_EVENT_FLAG_START 0x0200
1467#define IW_ASSOC_EVENT_FLAG 0x0200
1468#define IW_DISASSOC_EVENT_FLAG 0x0201
1469#define IW_DEAUTH_EVENT_FLAG 0x0202
1470#define IW_AGEOUT_EVENT_FLAG 0x0203
1471#define IW_COUNTER_MEASURES_EVENT_FLAG 0x0204
1472#define IW_REPLAY_COUNTER_DIFF_EVENT_FLAG 0x0205
1473#define IW_RSNIE_DIFF_EVENT_FLAG 0x0206
1474#define IW_MIC_DIFF_EVENT_FLAG 0x0207
1475#define IW_ICV_ERROR_EVENT_FLAG 0x0208
1476#define IW_MIC_ERROR_EVENT_FLAG 0x0209
1477#define IW_GROUP_HS_TIMEOUT_EVENT_FLAG 0x020A
1478#define IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG 0x020B
1479#define IW_RSNIE_SANITY_FAIL_EVENT_FLAG 0x020C
1480#define IW_SET_KEY_DONE_WPA1_EVENT_FLAG 0x020D
1481#define IW_SET_KEY_DONE_WPA2_EVENT_FLAG 0x020E
1482#define IW_STA_LINKUP_EVENT_FLAG 0x020F
1483#define IW_STA_LINKDOWN_EVENT_FLAG 0x0210
1484#define IW_SCAN_COMPLETED_EVENT_FLAG 0x0211
1485#define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG 0x0212
1486// if add new system event flag, please upadte the IW_SYS_EVENT_FLAG_END
1487#define IW_SYS_EVENT_FLAG_END 0x0212
1488#define IW_SYS_EVENT_TYPE_NUM (IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1)
1489// For system event - end
1490
1491// For spoof attack event - start
1492#define IW_SPOOF_EVENT_FLAG_START 0x0300
1493#define IW_CONFLICT_SSID_EVENT_FLAG 0x0300
1494#define IW_SPOOF_ASSOC_RESP_EVENT_FLAG 0x0301
1495#define IW_SPOOF_REASSOC_RESP_EVENT_FLAG 0x0302
1496#define IW_SPOOF_PROBE_RESP_EVENT_FLAG 0x0303
1497#define IW_SPOOF_BEACON_EVENT_FLAG 0x0304
1498#define IW_SPOOF_DISASSOC_EVENT_FLAG 0x0305
1499#define IW_SPOOF_AUTH_EVENT_FLAG 0x0306
1500#define IW_SPOOF_DEAUTH_EVENT_FLAG 0x0307
1501#define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG 0x0308
1502#define IW_REPLAY_ATTACK_EVENT_FLAG 0x0309
1503// if add new spoof attack event flag, please upadte the IW_SPOOF_EVENT_FLAG_END
1504#define IW_SPOOF_EVENT_FLAG_END 0x0309
1505#define IW_SPOOF_EVENT_TYPE_NUM (IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1)
1506// For spoof attack event - end
1507
1508// For flooding attack event - start
1509#define IW_FLOOD_EVENT_FLAG_START 0x0400
1510#define IW_FLOOD_AUTH_EVENT_FLAG 0x0400
1511#define IW_FLOOD_ASSOC_REQ_EVENT_FLAG 0x0401
1512#define IW_FLOOD_REASSOC_REQ_EVENT_FLAG 0x0402
1513#define IW_FLOOD_PROBE_REQ_EVENT_FLAG 0x0403
1514#define IW_FLOOD_DISASSOC_EVENT_FLAG 0x0404
1515#define IW_FLOOD_DEAUTH_EVENT_FLAG 0x0405
1516#define IW_FLOOD_EAP_REQ_EVENT_FLAG 0x0406
1517// if add new flooding attack event flag, please upadte the IW_FLOOD_EVENT_FLAG_END
1518#define IW_FLOOD_EVENT_FLAG_END 0x0406
1519#define IW_FLOOD_EVENT_TYPE_NUM (IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1)
1520// For flooding attack - end
1521
1522// End - WIRELESS EVENTS definition
1523
1524#ifdef CONFIG_STA_SUPPORT
1525// definition for DLS, kathy
1526#define MAX_NUM_OF_INIT_DLS_ENTRY 1
1527#define MAX_NUM_OF_DLS_ENTRY MAX_NUMBER_OF_DLS_ENTRY
1528
1529//Block ACK , rt2860, kathy
1530#define MAX_TX_REORDERBUF 64
1531#define MAX_RX_REORDERBUF 64
1532#define DEFAULT_TX_TIMEOUT 30
1533#define DEFAULT_RX_TIMEOUT 30
1534#ifndef CONFIG_AP_SUPPORT
1535#define MAX_BARECI_SESSION 8
1536#endif
1537
1538#ifndef IW_ESSID_MAX_SIZE
1539/* Maximum size of the ESSID and pAd->nickname strings */
1540#define IW_ESSID_MAX_SIZE 32
1541#endif
1542#endif // CONFIG_STA_SUPPORT //
1543
1544#ifdef MCAST_RATE_SPECIFIC
1545#define MCAST_DISABLE 0
1546#define MCAST_CCK 1
1547#define MCAST_OFDM 2
1548#define MCAST_HTMIX 3
1549#endif // MCAST_RATE_SPECIFIC //
1550
1551// For AsicRadioOff/AsicRadioOn function
1552#define DOT11POWERSAVE 0
1553#define GUIRADIO_OFF 1
1554#define RTMP_HALT 2
1555#define GUI_IDLE_POWER_SAVE 3
1556// --
1557
1558
1559// definition for WpaSupport flag
1560#define WPA_SUPPLICANT_DISABLE 0
1561#define WPA_SUPPLICANT_ENABLE 1
1562#define WPA_SUPPLICANT_ENABLE_WITH_WEB_UI 2
1563
1564// Endian byte swapping codes
1565#define SWAP16(x) \
1566 ((UINT16)( \
1567 (((UINT16)(x) & (UINT16) 0x00ffU) << 8) | \
1568 (((UINT16)(x) & (UINT16) 0xff00U) >> 8) ))
1569
1570#define SWAP32(x) \
1571 ((UINT32)( \
1572 (((UINT32)(x) & (UINT32) 0x000000ffUL) << 24) | \
1573 (((UINT32)(x) & (UINT32) 0x0000ff00UL) << 8) | \
1574 (((UINT32)(x) & (UINT32) 0x00ff0000UL) >> 8) | \
1575 (((UINT32)(x) & (UINT32) 0xff000000UL) >> 24) ))
1576
1577#define SWAP64(x) \
1578 ((UINT64)( \
1579 (UINT64)(((UINT64)(x) & (UINT64) 0x00000000000000ffULL) << 56) | \
1580 (UINT64)(((UINT64)(x) & (UINT64) 0x000000000000ff00ULL) << 40) | \
1581 (UINT64)(((UINT64)(x) & (UINT64) 0x0000000000ff0000ULL) << 24) | \
1582 (UINT64)(((UINT64)(x) & (UINT64) 0x00000000ff000000ULL) << 8) | \
1583 (UINT64)(((UINT64)(x) & (UINT64) 0x000000ff00000000ULL) >> 8) | \
1584 (UINT64)(((UINT64)(x) & (UINT64) 0x0000ff0000000000ULL) >> 24) | \
1585 (UINT64)(((UINT64)(x) & (UINT64) 0x00ff000000000000ULL) >> 40) | \
1586 (UINT64)(((UINT64)(x) & (UINT64) 0xff00000000000000ULL) >> 56) ))
1587
1588#ifdef RT_BIG_ENDIAN
1589
1590#define cpu2le64(x) SWAP64((x))
1591#define le2cpu64(x) SWAP64((x))
1592#define cpu2le32(x) SWAP32((x))
1593#define le2cpu32(x) SWAP32((x))
1594#define cpu2le16(x) SWAP16((x))
1595#define le2cpu16(x) SWAP16((x))
1596#define cpu2be64(x) ((UINT64)(x))
1597#define be2cpu64(x) ((UINT64)(x))
1598#define cpu2be32(x) ((UINT32)(x))
1599#define be2cpu32(x) ((UINT32)(x))
1600#define cpu2be16(x) ((UINT16)(x))
1601#define be2cpu16(x) ((UINT16)(x))
1602
1603#else // Little_Endian
1604
1605#define cpu2le64(x) ((UINT64)(x))
1606#define le2cpu64(x) ((UINT64)(x))
1607#define cpu2le32(x) ((UINT32)(x))
1608#define le2cpu32(x) ((UINT32)(x))
1609#define cpu2le16(x) ((UINT16)(x))
1610#define le2cpu16(x) ((UINT16)(x))
1611#define cpu2be64(x) SWAP64((x))
1612#define be2cpu64(x) SWAP64((x))
1613#define cpu2be32(x) SWAP32((x))
1614#define be2cpu32(x) SWAP32((x))
1615#define cpu2be16(x) SWAP16((x))
1616#define be2cpu16(x) SWAP16((x))
1617
1618#endif // RT_BIG_ENDIAN
1619
1620#endif // __RTMP_DEF_H__
1621
1622
diff --git a/drivers/staging/rt2870/rtmp_type.h b/drivers/staging/rt2870/rtmp_type.h
new file mode 100644
index 00000000000..1fd7df1e179
--- /dev/null
+++ b/drivers/staging/rt2870/rtmp_type.h
@@ -0,0 +1,94 @@
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#define PACKED __attribute__ ((packed))
42
43// Put platform dependent declaration here
44// For example, linux type definition
45typedef unsigned char UINT8;
46typedef unsigned short UINT16;
47typedef unsigned int UINT32;
48typedef unsigned long long UINT64;
49typedef int INT32;
50typedef long long INT64;
51
52typedef unsigned char * PUINT8;
53typedef unsigned short * PUINT16;
54typedef unsigned int * PUINT32;
55typedef unsigned long long * PUINT64;
56typedef int * PINT32;
57typedef long long * PINT64;
58
59typedef signed char CHAR;
60typedef signed short SHORT;
61typedef signed int INT;
62typedef signed long LONG;
63typedef signed long long LONGLONG;
64
65
66typedef unsigned char UCHAR;
67typedef unsigned short USHORT;
68typedef unsigned int UINT;
69typedef unsigned long ULONG;
70typedef unsigned long long ULONGLONG;
71
72typedef unsigned char BOOLEAN;
73typedef void VOID;
74
75typedef VOID * PVOID;
76typedef CHAR * PCHAR;
77typedef UCHAR * PUCHAR;
78typedef USHORT * PUSHORT;
79typedef LONG * PLONG;
80typedef ULONG * PULONG;
81typedef UINT * PUINT;
82
83typedef unsigned int NDIS_MEDIA_STATE;
84
85typedef union _LARGE_INTEGER {
86 struct {
87 UINT LowPart;
88 INT32 HighPart;
89 } u;
90 INT64 QuadPart;
91} LARGE_INTEGER;
92
93#endif // __RTMP_TYPE_H__
94
diff --git a/drivers/staging/rt2870/spectrum.h b/drivers/staging/rt2870/spectrum.h
new file mode 100644
index 00000000000..94cfa5b174f
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/spectrum_def.h b/drivers/staging/rt2870/spectrum_def.h
new file mode 100644
index 00000000000..4ca4817bba0
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/sta/aironet.c b/drivers/staging/rt2870/sta/aironet.c
new file mode 100644
index 00000000000..4af4a190618
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/sta/assoc.c b/drivers/staging/rt2870/sta/assoc.c
new file mode 100644
index 00000000000..a76dab500bc
--- /dev/null
+++ b/drivers/staging/rt2870/sta/assoc.c
@@ -0,0 +1,2039 @@
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 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
477
478 // Check for WPA PMK cache list
479 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
480 {
481 INT idx;
482 BOOLEAN FoundPMK = FALSE;
483 // Search chched PMKID, append it if existed
484 for (idx = 0; idx < PMKID_NO; idx++)
485 {
486 if (NdisEqualMemory(ApAddr, &pAd->StaCfg.SavedPMK[idx].BSSID, 6))
487 {
488 FoundPMK = TRUE;
489 break;
490 }
491 }
492
493 if (FoundPMK)
494 {
495 // Set PMK number
496 *(PUSHORT) &pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len] = 1;
497 NdisMoveMemory(&pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len + 2], &pAd->StaCfg.SavedPMK[idx].PMKID, 16);
498 pAd->StaCfg.RSNIE_Len += 18;
499 }
500 }
501
502 {
503 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
504 1, &RSNIe,
505 1, &pAd->StaCfg.RSNIE_Len,
506 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
507 END_OF_ARGS);
508 }
509
510 FrameLen += tmp;
511
512 {
513 // Append Variable IE
514 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
515 VarIesOffset += 1;
516 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->StaCfg.RSNIE_Len, 1);
517 VarIesOffset += 1;
518 }
519 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
520 VarIesOffset += pAd->StaCfg.RSNIE_Len;
521
522 // Set Variable IEs Length
523 pAd->StaCfg.ReqVarIELen = VarIesOffset;
524 }
525
526 // We have update that at PeerBeaconAtJoinRequest()
527 CkipFlag = pAd->StaCfg.CkipFlag;
528 if (CkipFlag != 0)
529 {
530 NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
531 CkipNegotiationBuffer[2] = 0x66;
532 // Make it try KP & MIC, since we have to follow the result from AssocRsp
533 CkipNegotiationBuffer[8] = 0x18;
534 CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
535 CkipFlag = 0x18;
536
537 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
538 1, &AironetCkipIe,
539 1, &AironetCkipLen,
540 AironetCkipLen, CkipNegotiationBuffer,
541 END_OF_ARGS);
542 FrameLen += tmp;
543 }
544
545 // Add CCX v2 request if CCX2 admin state is on
546 if (pAd->StaCfg.CCXControl.field.Enable == 1)
547 {
548
549 //
550 // Add AironetIPAddressIE for Cisco CCX 2.X
551 // Add CCX Version
552 //
553 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
554 1, &AironetIPAddressIE,
555 1, &AironetIPAddressLen,
556 AironetIPAddressLen, AironetIPAddressBuffer,
557 1, &Ccx2Ie,
558 1, &Ccx2Len,
559 Ccx2Len, Ccx2IeInfo,
560 END_OF_ARGS);
561 FrameLen += tmp;
562
563 //
564 // Add CipherSuite CCKM or LeapTkip if setting.
565 //
566#ifdef LEAP_SUPPORT
567 if (LEAP_CCKM_ON(pAd))
568 {
569 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
570 CipherSuiteCiscoCCKMLen, CipherSuiteCiscoCCKM,
571 END_OF_ARGS);
572 FrameLen += tmp;
573
574 // Third add RSN
575 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, CipherSuiteCiscoCCKM, CipherSuiteCiscoCCKMLen); //Save CipherSuite
576 VarIesOffset += CipherSuiteCiscoCCKMLen;
577 }
578 else if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled))
579 {
580 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
581 CipherSuiteCCXTkipLen, CipherSuiteCCXTkip,
582 END_OF_ARGS);
583 FrameLen += tmp;
584
585 // Third add RSN
586 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, CipherSuiteCCXTkip, CipherSuiteCCXTkipLen);
587 VarIesOffset += CipherSuiteCCXTkipLen;
588 }
589#endif // LEAP_SUPPORT //
590
591 // Add by James 03/06/27
592 // Set Variable IEs Length
593 pAd->StaCfg.ReqVarIELen = VarIesOffset;
594 pAd->StaCfg.AssocInfo.RequestIELength = VarIesOffset;
595
596 // OffsetResponseIEs follow ReqVarIE
597 pAd->StaCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->StaCfg.ReqVarIELen;
598 // End Add by James
599 }
600
601
602 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
603 MlmeFreeMemory(pAd, pOutBuffer);
604
605 RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout);
606 pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP;
607 }
608 else
609 {
610 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n"));
611 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
612 Status = MLME_INVALID_FORMAT;
613 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
614 }
615
616}
617
618/*
619 ==========================================================================
620 Description:
621 mlme reassoc req handling procedure
622 Parameters:
623 Elem -
624 Pre:
625 -# SSID (Adapter->StaCfg.ssid[])
626 -# BSSID (AP address, Adapter->StaCfg.bssid)
627 -# Supported rates (Adapter->StaCfg.supported_rates[])
628 -# Supported rates length (Adapter->StaCfg.supported_rates_len)
629 -# Tx power (Adapter->StaCfg.tx_power)
630
631 IRQL = DISPATCH_LEVEL
632
633 ==========================================================================
634 */
635VOID MlmeReassocReqAction(
636 IN PRTMP_ADAPTER pAd,
637 IN MLME_QUEUE_ELEM *Elem)
638{
639 UCHAR ApAddr[6];
640 HEADER_802_11 ReassocHdr;
641 UCHAR Ccx2Len = 5;
642 UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
643 USHORT CapabilityInfo, ListenIntv;
644 ULONG Timeout;
645 ULONG FrameLen = 0;
646 BOOLEAN TimerCancelled;
647 NDIS_STATUS NStatus;
648 ULONG tmp;
649 PUCHAR pOutBuffer = NULL;
650//CCX 2.X
651#ifdef LEAP_SUPPORT
652 UCHAR CkipFlag;
653 UCHAR CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
654 UCHAR AironetCkipIe = IE_AIRONET_CKIP;
655 UCHAR AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
656 UCHAR AironetIPAddressIE = IE_AIRONET_IPADDRESS;
657 UCHAR AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
658 UCHAR AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
659 UCHAR AironetCCKMReassocIE = IE_AIRONET_CCKMREASSOC;
660 UCHAR AironetCCKMReassocLen = AIRONET_CCKMREASSOC_LENGTH;
661 UCHAR AironetCCKMReassocBuffer[AIRONET_CCKMREASSOC_LENGTH];
662 UCHAR AironetOUI[] = {0x00, 0x40, 0x96, 0x00};
663 UCHAR MICMN[16];
664 UCHAR CalcMicBuffer[80];
665 ULONG CalcMicBufferLen = 0;
666#endif // LEAP_SUPPORT //
667 USHORT Status;
668
669 // Block all authentication request durning WPA block period
670 if (pAd->StaCfg.bBlockAssoc == TRUE)
671 {
672 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block ReAssoc request durning WPA block period!\n"));
673 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
674 Status = MLME_STATE_MACHINE_REJECT;
675 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
676 }
677 // the parameters are the same as the association
678 else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
679 {
680 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
681
682 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
683 if(NStatus != NDIS_STATUS_SUCCESS)
684 {
685 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() allocate memory failed \n"));
686 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
687 Status = MLME_FAIL_NO_RESOURCE;
688 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
689 return;
690 }
691
692 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
693
694 // make frame, use bssid as the AP address??
695 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send RE-ASSOC request...\n"));
696 MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, ApAddr, ApAddr);
697 MakeOutgoingFrame(pOutBuffer, &FrameLen,
698 sizeof(HEADER_802_11), &ReassocHdr,
699 2, &CapabilityInfo,
700 2, &ListenIntv,
701 MAC_ADDR_LEN, ApAddr,
702 1, &SsidIe,
703 1, &pAd->MlmeAux.SsidLen,
704 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
705 1, &SupRateIe,
706 1, &pAd->MlmeAux.SupRateLen,
707 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
708 END_OF_ARGS);
709
710 if (pAd->MlmeAux.ExtRateLen != 0)
711 {
712 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
713 1, &ExtRateIe,
714 1, &pAd->MlmeAux.ExtRateLen,
715 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
716 END_OF_ARGS);
717 FrameLen += tmp;
718 }
719
720 if (pAd->MlmeAux.APEdcaParm.bValid)
721 {
722 if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
723 {
724 QBSS_STA_INFO_PARM QosInfo;
725
726 NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
727 QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
728 QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
729 QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
730 QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
731 QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
732 WmeIe[8] |= *(PUCHAR)&QosInfo;
733 }
734
735 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
736 9, &WmeIe[0],
737 END_OF_ARGS);
738 FrameLen += tmp;
739 }
740
741#ifdef DOT11_N_SUPPORT
742 // HT
743 if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
744 {
745 ULONG TmpLen;
746 UCHAR HtLen;
747 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
748 if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
749 {
750 HtLen = SIZE_HT_CAP_IE + 4;
751 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
752 1, &WpaIe,
753 1, &HtLen,
754 4, &BROADCOM[0],
755 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
756 END_OF_ARGS);
757 }
758 else
759 {
760 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
761 1, &HtCapIe,
762 1, &pAd->MlmeAux.HtCapabilityLen,
763 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
764 END_OF_ARGS);
765 }
766 FrameLen += TmpLen;
767 }
768#endif // DOT11_N_SUPPORT //
769
770 // add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
771 // Case I: (Aggregation + Piggy-Back)
772 // 1. user enable aggregation, AND
773 // 2. Mac support piggy-back
774 // 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
775 // Case II: (Aggregation)
776 // 1. user enable aggregation, AND
777 // 2. AP annouces it's AGGREGATION-capable in BEACON
778 if (pAd->CommonCfg.bAggregationCapable)
779 {
780 if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
781 {
782 ULONG TmpLen;
783 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
784 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
785 9, RalinkIe,
786 END_OF_ARGS);
787 FrameLen += TmpLen;
788 }
789 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
790 {
791 ULONG TmpLen;
792 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
793 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
794 9, RalinkIe,
795 END_OF_ARGS);
796 FrameLen += TmpLen;
797 }
798 }
799 else
800 {
801 ULONG TmpLen;
802 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04, 0x00, 0x00, 0x00};
803 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
804 9, RalinkIe,
805 END_OF_ARGS);
806 FrameLen += TmpLen;
807 }
808#ifdef LEAP_SUPPORT
809 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
810 {
811 CkipFlag = pAd->StaCfg.CkipFlag; // We have update that at PeerBeaconAtJoinRequest()
812 if (CkipFlag != 0)
813 {
814 NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
815 CkipNegotiationBuffer[2] = 0x66;
816 // Make it try KP & MIC, since we have to follow the result from AssocRsp
817 CkipNegotiationBuffer[8] = 0x18;
818 CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
819
820 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
821 1, &AironetCkipIe,
822 1, &AironetCkipLen,
823 AironetCkipLen, CkipNegotiationBuffer,
824 END_OF_ARGS);
825 FrameLen += tmp;
826 }
827
828 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
829 1, &AironetIPAddressIE,
830 1, &AironetIPAddressLen,
831 AironetIPAddressLen, AironetIPAddressBuffer,
832 END_OF_ARGS);
833 FrameLen += tmp;
834
835 //
836 // The RN is incremented before each reassociation request.
837 //
838 pAd->StaCfg.CCKMRN++;
839 //
840 // Calculate MIC = hmac-md5(krk, STA-ID|BSSID|RSNIE|TSF|RN);
841 //
842 COPY_MAC_ADDR(CalcMicBuffer, pAd->CurrentAddress);
843 CalcMicBufferLen = MAC_ADDR_LEN;
844 COPY_MAC_ADDR(CalcMicBuffer + CalcMicBufferLen, pAd->MlmeAux.Bssid);
845 CalcMicBufferLen += MAC_ADDR_LEN;
846 NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, CipherSuiteCiscoCCKM, CipherSuiteCiscoCCKMLen);
847 CalcMicBufferLen += CipherSuiteCiscoCCKMLen;
848 NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, (PUCHAR) &pAd->StaCfg.CCKMBeaconAtJoinTimeStamp, sizeof(pAd->StaCfg.CCKMBeaconAtJoinTimeStamp));
849 CalcMicBufferLen += sizeof(pAd->StaCfg.CCKMBeaconAtJoinTimeStamp);
850 NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, (PUCHAR)&pAd->StaCfg.CCKMRN, sizeof(pAd->StaCfg.CCKMRN));
851 CalcMicBufferLen += sizeof(pAd->StaCfg.CCKMRN);
852 hmac_md5(pAd->StaCfg.KRK, LEN_EAP_MICK, CalcMicBuffer, CalcMicBufferLen, MICMN);
853
854 //
855 // fill up CCKM reassociation request element
856 //
857 NdisMoveMemory(AironetCCKMReassocBuffer, AironetOUI, 4);
858 NdisMoveMemory(AironetCCKMReassocBuffer + 4, (PUCHAR)&pAd->StaCfg.CCKMBeaconAtJoinTimeStamp, 8);
859 NdisMoveMemory(AironetCCKMReassocBuffer + 12, (PUCHAR) &pAd->StaCfg.CCKMRN, 4);
860 NdisMoveMemory(AironetCCKMReassocBuffer +16, MICMN, 8);
861
862 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
863 1, &AironetCCKMReassocIE,
864 1, &AironetCCKMReassocLen,
865 AironetCCKMReassocLen, AironetCCKMReassocBuffer,
866 END_OF_ARGS);
867 FrameLen += tmp;
868
869 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
870 CipherSuiteCiscoCCKMLen,CipherSuiteCiscoCCKM,
871 END_OF_ARGS);
872 FrameLen += tmp;
873 }
874#endif // LEAP_SUPPORT //
875
876 // Add CCX v2 request if CCX2 admin state is on
877 if (pAd->StaCfg.CCXControl.field.Enable == 1)
878 {
879 //
880 // Add CCX Version
881 //
882 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
883 1, &Ccx2Ie,
884 1, &Ccx2Len,
885 Ccx2Len, Ccx2IeInfo,
886 END_OF_ARGS);
887 FrameLen += tmp;
888 }
889
890 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
891 MlmeFreeMemory(pAd, pOutBuffer);
892
893 RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout); /* in mSec */
894 pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP;
895 }
896 else
897 {
898 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!!!! \n"));
899 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
900 Status = MLME_INVALID_FORMAT;
901 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
902 }
903}
904
905/*
906 ==========================================================================
907 Description:
908 Upper layer issues disassoc request
909 Parameters:
910 Elem -
911
912 IRQL = PASSIVE_LEVEL
913
914 ==========================================================================
915 */
916VOID MlmeDisassocReqAction(
917 IN PRTMP_ADAPTER pAd,
918 IN MLME_QUEUE_ELEM *Elem)
919{
920 PMLME_DISASSOC_REQ_STRUCT pDisassocReq;
921 HEADER_802_11 DisassocHdr;
922 PHEADER_802_11 pDisassocHdr;
923 PUCHAR pOutBuffer = NULL;
924 ULONG FrameLen = 0;
925 NDIS_STATUS NStatus;
926 BOOLEAN TimerCancelled;
927 ULONG Timeout = 0;
928 USHORT Status;
929
930#ifdef QOS_DLS_SUPPORT
931 // send DLS-TEAR_DOWN message,
932 if (pAd->CommonCfg.bDLSCapable)
933 {
934 UCHAR i;
935
936 // tear down local dls table entry
937 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
938 {
939 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
940 {
941 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
942 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
943 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
944 }
945 }
946
947 // tear down peer dls table entry
948 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
949 {
950 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
951 {
952 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
953 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
954 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
955 }
956 }
957 }
958#endif // QOS_DLS_SUPPORT //
959
960 // skip sanity check
961 pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg);
962
963 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
964 if (NStatus != NDIS_STATUS_SUCCESS)
965 {
966 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n"));
967 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
968 Status = MLME_FAIL_NO_RESOURCE;
969 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
970 return;
971 }
972
973
974
975 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &TimerCancelled);
976
977 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send DISASSOC request[BSSID::%02x:%02x:%02x:%02x:%02x:%02x (Reason=%d)\n",
978 pDisassocReq->Addr[0], pDisassocReq->Addr[1], pDisassocReq->Addr[2],
979 pDisassocReq->Addr[3], pDisassocReq->Addr[4], pDisassocReq->Addr[5], pDisassocReq->Reason));
980 MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr); // patch peap ttls switching issue
981 MakeOutgoingFrame(pOutBuffer, &FrameLen,
982 sizeof(HEADER_802_11),&DisassocHdr,
983 2, &pDisassocReq->Reason,
984 END_OF_ARGS);
985 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
986
987 // To patch Instance and Buffalo(N) AP
988 // Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
989 // Therefore, we send both of them.
990 pDisassocHdr = (PHEADER_802_11)pOutBuffer;
991 pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
992 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
993
994 MlmeFreeMemory(pAd, pOutBuffer);
995
996 pAd->StaCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING;
997 COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pDisassocReq->Addr);
998
999 RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */
1000 pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
1001
1002#ifdef WPA_SUPPLICANT_SUPPORT
1003#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1004 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1005 {
1006 union iwreq_data wrqu;
1007 //send disassociate event to wpa_supplicant
1008 memset(&wrqu, 0, sizeof(wrqu));
1009 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
1010 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1011 }
1012#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1013#endif // WPA_SUPPLICANT_SUPPORT //
1014
1015#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1016 {
1017 union iwreq_data wrqu;
1018 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1019 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1020 }
1021#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1022
1023}
1024
1025/*
1026 ==========================================================================
1027 Description:
1028 peer sends assoc rsp back
1029 Parameters:
1030 Elme - MLME message containing the received frame
1031
1032 IRQL = DISPATCH_LEVEL
1033
1034 ==========================================================================
1035 */
1036VOID PeerAssocRspAction(
1037 IN PRTMP_ADAPTER pAd,
1038 IN MLME_QUEUE_ELEM *Elem)
1039{
1040 USHORT CapabilityInfo, Status, Aid;
1041 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
1042 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
1043 UCHAR Addr2[MAC_ADDR_LEN];
1044 BOOLEAN TimerCancelled;
1045 UCHAR CkipFlag;
1046 EDCA_PARM EdcaParm;
1047 HT_CAPABILITY_IE HtCapability;
1048 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1049 UCHAR HtCapabilityLen;
1050 UCHAR AddHtInfoLen;
1051 UCHAR NewExtChannelOffset = 0xff;
1052
1053 if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
1054 &HtCapability,&AddHtInfo, &HtCapabilityLen,&AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
1055 {
1056 // The frame is for me ?
1057 if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid))
1058 {
1059 DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status));
1060#ifdef DOT11_N_SUPPORT
1061 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));
1062#endif // DOT11_N_SUPPORT //
1063 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
1064 if(Status == MLME_SUCCESS)
1065 {
1066 UCHAR MaxSupportedRateIn500Kbps = 0;
1067 UCHAR idx;
1068
1069 // supported rates array may not be sorted. sort it and find the maximum rate
1070 for (idx=0; idx<SupRateLen; idx++)
1071 {
1072 if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
1073 MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
1074 }
1075
1076 for (idx=0; idx<ExtRateLen; idx++)
1077 {
1078 if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
1079 MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
1080 }
1081 // go to procedure listed on page 376
1082 AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
1083 &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
1084
1085 StaAddMacTableEntry(pAd, &pAd->MacTab.Content[BSSID_WCID], MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo);
1086
1087 pAd->StaCfg.CkipFlag = CkipFlag;
1088 if (CkipFlag & 0x18)
1089 {
1090 NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
1091 NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
1092 NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
1093 pAd->StaCfg.GIV[0] = RandomByte(pAd);
1094 pAd->StaCfg.GIV[1] = RandomByte(pAd);
1095 pAd->StaCfg.GIV[2] = RandomByte(pAd);
1096 pAd->StaCfg.bCkipOn = TRUE;
1097 DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
1098 }
1099 }
1100 else
1101 {
1102 // Faile on Association, we need to check the status code
1103 // Is that a Rogue AP?
1104#ifdef LEAP_SUPPORT
1105 if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (Status == MLME_ALG_NOT_SUPPORT))
1106 { //Possibly Rogue AP
1107 RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, pAd->MlmeAux.Bssid, LEAP_REASON_INVALID_AUTH);
1108 }
1109#endif // LEAP_SUPPORT //
1110 }
1111 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1112 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
1113 }
1114 }
1115 else
1116 {
1117 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerAssocRspAction() sanity check fail\n"));
1118 }
1119}
1120
1121/*
1122 ==========================================================================
1123 Description:
1124 peer sends reassoc rsp
1125 Parametrs:
1126 Elem - MLME message cntaining the received frame
1127
1128 IRQL = DISPATCH_LEVEL
1129
1130 ==========================================================================
1131 */
1132VOID PeerReassocRspAction(
1133 IN PRTMP_ADAPTER pAd,
1134 IN MLME_QUEUE_ELEM *Elem)
1135{
1136 USHORT CapabilityInfo;
1137 USHORT Status;
1138 USHORT Aid;
1139 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
1140 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
1141 UCHAR Addr2[MAC_ADDR_LEN];
1142 UCHAR CkipFlag;
1143 BOOLEAN TimerCancelled;
1144 EDCA_PARM EdcaParm;
1145 HT_CAPABILITY_IE HtCapability;
1146 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1147 UCHAR HtCapabilityLen;
1148 UCHAR AddHtInfoLen;
1149 UCHAR NewExtChannelOffset = 0xff;
1150
1151 if(PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
1152 &HtCapability, &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
1153 {
1154 if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) // The frame is for me ?
1155 {
1156 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status));
1157 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
1158
1159 if(Status == MLME_SUCCESS)
1160 {
1161 // go to procedure listed on page 376
1162 AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
1163 &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
1164
1165#ifdef WPA_SUPPLICANT_SUPPORT
1166#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1167 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1168 {
1169 union iwreq_data wrqu;
1170
1171 SendAssocIEsToWpaSupplicant(pAd);
1172 memset(&wrqu, 0, sizeof(wrqu));
1173 wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
1174 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1175 }
1176#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1177#endif // WPA_SUPPLICANT_SUPPORT //
1178
1179#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1180 {
1181 union iwreq_data wrqu;
1182 wext_notify_event_assoc(pAd);
1183
1184 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1185 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
1186 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1187
1188 }
1189#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1190
1191 }
1192
1193 //
1194 // Cisco Leap CCKM supported Re-association.
1195 //
1196#ifdef LEAP_SUPPORT
1197 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
1198 {
1199 if (CCKMAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen) == TRUE)
1200 {
1201 pAd->StaCfg.CkipFlag = CkipFlag;
1202 if (CkipFlag & 0x18)
1203 {
1204 NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
1205 NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
1206 NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
1207 pAd->StaCfg.GIV[0] = RandomByte(pAd);
1208 pAd->StaCfg.GIV[1] = RandomByte(pAd);
1209 pAd->StaCfg.GIV[2] = RandomByte(pAd);
1210 pAd->StaCfg.bCkipOn = TRUE;
1211 DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
1212 }
1213
1214 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1215 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1216 }
1217 else
1218 {
1219 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - CCKMAssocRspSanity() sanity check fail\n"));
1220 }
1221 }
1222 else
1223#endif // LEAP_SUPPORT //
1224 {
1225 // CkipFlag is no use for reassociate
1226 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1227 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1228 }
1229 }
1230 }
1231 else
1232 {
1233 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerReassocRspAction() sanity check fail\n"));
1234 }
1235
1236}
1237
1238/*
1239 ==========================================================================
1240 Description:
1241 procedures on IEEE 802.11/1999 p.376
1242 Parametrs:
1243
1244 IRQL = DISPATCH_LEVEL
1245
1246 ==========================================================================
1247 */
1248VOID AssocPostProc(
1249 IN PRTMP_ADAPTER pAd,
1250 IN PUCHAR pAddr2,
1251 IN USHORT CapabilityInfo,
1252 IN USHORT Aid,
1253 IN UCHAR SupRate[],
1254 IN UCHAR SupRateLen,
1255 IN UCHAR ExtRate[],
1256 IN UCHAR ExtRateLen,
1257 IN PEDCA_PARM pEdcaParm,
1258 IN HT_CAPABILITY_IE *pHtCapability,
1259 IN UCHAR HtCapabilityLen,
1260 IN ADD_HT_INFO_IE *pAddHtInfo) // AP might use this additional ht info IE
1261{
1262 ULONG Idx;
1263
1264 pAd->MlmeAux.BssType = BSS_INFRA;
1265 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2);
1266 pAd->MlmeAux.Aid = Aid;
1267 pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
1268#ifdef DOT11_N_SUPPORT
1269 // Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on.
1270 if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE))
1271 {
1272 pEdcaParm->bValid = TRUE;
1273 pEdcaParm->Aifsn[0] = 3;
1274 pEdcaParm->Aifsn[1] = 7;
1275 pEdcaParm->Aifsn[2] = 2;
1276 pEdcaParm->Aifsn[3] = 2;
1277
1278 pEdcaParm->Cwmin[0] = 4;
1279 pEdcaParm->Cwmin[1] = 4;
1280 pEdcaParm->Cwmin[2] = 3;
1281 pEdcaParm->Cwmin[3] = 2;
1282
1283 pEdcaParm->Cwmax[0] = 10;
1284 pEdcaParm->Cwmax[1] = 10;
1285 pEdcaParm->Cwmax[2] = 4;
1286 pEdcaParm->Cwmax[3] = 3;
1287
1288 pEdcaParm->Txop[0] = 0;
1289 pEdcaParm->Txop[1] = 0;
1290 pEdcaParm->Txop[2] = 96;
1291 pEdcaParm->Txop[3] = 48;
1292
1293 }
1294#endif // DOT11_N_SUPPORT //
1295
1296 NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
1297
1298 // filter out un-supported rates
1299 pAd->MlmeAux.SupRateLen = SupRateLen;
1300 NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
1301 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
1302
1303 // filter out un-supported rates
1304 pAd->MlmeAux.ExtRateLen = ExtRateLen;
1305 NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
1306 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
1307
1308#ifdef DOT11_N_SUPPORT
1309 if (HtCapabilityLen > 0)
1310 {
1311 RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo);
1312 }
1313 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n", pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1314
1315 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> (Mmps=%d, AmsduSize=%d, )\n",
1316 pAd->MacTab.Content[BSSID_WCID].MmpsMode, pAd->MacTab.Content[BSSID_WCID].AMsduSize));
1317#endif // DOT11_N_SUPPORT //
1318
1319 // Set New WPA information
1320 Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel);
1321 if (Idx == BSS_NOT_FOUND)
1322 {
1323 DBGPRINT_ERR(("ASSOC - Can't find BSS after receiving Assoc response\n"));
1324 }
1325 else
1326 {
1327 // Init variable
1328 pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0;
1329 NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, MAX_LEN_OF_RSNIE);
1330
1331 // Store appropriate RSN_IE for WPA SM negotiation later
1332 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0))
1333 {
1334 PUCHAR pVIE;
1335 USHORT len;
1336 PEID_STRUCT pEid;
1337
1338 pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs;
1339 len = pAd->ScanTab.BssEntry[Idx].VarIELen;
1340
1341 while (len > 0)
1342 {
1343 pEid = (PEID_STRUCT) pVIE;
1344 // For WPA/WPAPSK
1345 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
1346 && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1347 {
1348 NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
1349 pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
1350 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n"));
1351 }
1352 // For WPA2/WPA2PSK
1353 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
1354 && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1355 {
1356 NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
1357 pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
1358 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n"));
1359 }
1360
1361 pVIE += (pEid->Len + 2);
1362 len -= (pEid->Len + 2);
1363 }
1364 }
1365
1366 if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0)
1367 {
1368 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> no RSN_IE \n"));
1369 }
1370 else
1371 {
1372 hex_dump("RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
1373 }
1374 }
1375}
1376
1377/*
1378 ==========================================================================
1379 Description:
1380 left part of IEEE 802.11/1999 p.374
1381 Parameters:
1382 Elem - MLME message containing the received frame
1383
1384 IRQL = DISPATCH_LEVEL
1385
1386 ==========================================================================
1387 */
1388VOID PeerDisassocAction(
1389 IN PRTMP_ADAPTER pAd,
1390 IN MLME_QUEUE_ELEM *Elem)
1391{
1392 UCHAR Addr2[MAC_ADDR_LEN];
1393 USHORT Reason;
1394
1395 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction()\n"));
1396 if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
1397 {
1398 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() Reason = %d\n", Reason));
1399 if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2))
1400 {
1401
1402 if (pAd->CommonCfg.bWirelessEvent)
1403 {
1404 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1405 }
1406
1407
1408#ifdef LEAP_SUPPORT
1409 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1410 {
1411 // Cisco_LEAP has start a timer
1412 // We should cancel it if using LEAP
1413 RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &TimerCancelled);
1414 //Check is it mach the LEAP Authentication failed as possible a Rogue AP
1415 //on it's PortSecured not equal to WPA_802_1X_PORT_SECURED while process the Association.
1416 if ((pAd->Mlme.LeapMachine.CurrState != LEAP_IDLE) && (pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
1417 {
1418 RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_AUTH_TIMEOUT);
1419 }
1420 }
1421#endif // LEAP_SUPPORT //
1422 //
1423 // Get Current System time and Turn on AdjacentAPReport
1424 //
1425 NdisGetSystemUpTime(&pAd->StaCfg.CCXAdjacentAPLinkDownTime);
1426 pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
1427 LinkDown(pAd, TRUE);
1428 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1429
1430#ifdef WPA_SUPPLICANT_SUPPORT
1431#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1432 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1433 {
1434 union iwreq_data wrqu;
1435 //send disassociate event to wpa_supplicant
1436 memset(&wrqu, 0, sizeof(wrqu));
1437 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
1438 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1439 }
1440#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1441#endif // WPA_SUPPLICANT_SUPPORT //
1442
1443#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1444 {
1445 union iwreq_data wrqu;
1446 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1447 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1448 }
1449#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1450 }
1451 }
1452 else
1453 {
1454 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() sanity check fail\n"));
1455 }
1456
1457}
1458
1459/*
1460 ==========================================================================
1461 Description:
1462 what the state machine will do after assoc timeout
1463 Parameters:
1464 Elme -
1465
1466 IRQL = DISPATCH_LEVEL
1467
1468 ==========================================================================
1469 */
1470VOID AssocTimeoutAction(
1471 IN PRTMP_ADAPTER pAd,
1472 IN MLME_QUEUE_ELEM *Elem)
1473{
1474 USHORT Status;
1475 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - AssocTimeoutAction\n"));
1476 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1477 Status = MLME_REJ_TIMEOUT;
1478 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
1479}
1480
1481/*
1482 ==========================================================================
1483 Description:
1484 what the state machine will do after reassoc timeout
1485
1486 IRQL = DISPATCH_LEVEL
1487
1488 ==========================================================================
1489 */
1490VOID ReassocTimeoutAction(
1491 IN PRTMP_ADAPTER pAd,
1492 IN MLME_QUEUE_ELEM *Elem)
1493{
1494 USHORT Status;
1495 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - ReassocTimeoutAction\n"));
1496 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1497 Status = MLME_REJ_TIMEOUT;
1498 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1499}
1500
1501/*
1502 ==========================================================================
1503 Description:
1504 what the state machine will do after disassoc timeout
1505
1506 IRQL = DISPATCH_LEVEL
1507
1508 ==========================================================================
1509 */
1510VOID DisassocTimeoutAction(
1511 IN PRTMP_ADAPTER pAd,
1512 IN MLME_QUEUE_ELEM *Elem)
1513{
1514 USHORT Status;
1515 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - DisassocTimeoutAction\n"));
1516 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1517 Status = MLME_SUCCESS;
1518 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
1519}
1520
1521VOID InvalidStateWhenAssoc(
1522 IN PRTMP_ADAPTER pAd,
1523 IN MLME_QUEUE_ELEM *Elem)
1524{
1525 USHORT Status;
1526 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n",
1527 pAd->Mlme.AssocMachine.CurrState));
1528 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1529 Status = MLME_STATE_MACHINE_REJECT;
1530 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
1531}
1532
1533VOID InvalidStateWhenReassoc(
1534 IN PRTMP_ADAPTER pAd,
1535 IN MLME_QUEUE_ELEM *Elem)
1536{
1537 USHORT Status;
1538 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n",
1539 pAd->Mlme.AssocMachine.CurrState));
1540 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1541 Status = MLME_STATE_MACHINE_REJECT;
1542 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1543}
1544
1545VOID InvalidStateWhenDisassociate(
1546 IN PRTMP_ADAPTER pAd,
1547 IN MLME_QUEUE_ELEM *Elem)
1548{
1549 USHORT Status;
1550 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n",
1551 pAd->Mlme.AssocMachine.CurrState));
1552 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1553 Status = MLME_STATE_MACHINE_REJECT;
1554 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
1555}
1556
1557/*
1558 ==========================================================================
1559 Description:
1560 right part of IEEE 802.11/1999 page 374
1561 Note:
1562 This event should never cause ASSOC state machine perform state
1563 transition, and has no relationship with CNTL machine. So we separate
1564 this routine as a service outside of ASSOC state transition table.
1565
1566 IRQL = DISPATCH_LEVEL
1567
1568 ==========================================================================
1569 */
1570VOID Cls3errAction(
1571 IN PRTMP_ADAPTER pAd,
1572 IN PUCHAR pAddr)
1573{
1574 HEADER_802_11 DisassocHdr;
1575 PHEADER_802_11 pDisassocHdr;
1576 PUCHAR pOutBuffer = NULL;
1577 ULONG FrameLen = 0;
1578 NDIS_STATUS NStatus;
1579 USHORT Reason = REASON_CLS3ERR;
1580
1581 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1582 if (NStatus != NDIS_STATUS_SUCCESS)
1583 return;
1584
1585 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Class 3 Error, Send DISASSOC frame\n"));
1586 MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->CommonCfg.Bssid); // patch peap ttls switching issue
1587 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1588 sizeof(HEADER_802_11),&DisassocHdr,
1589 2, &Reason,
1590 END_OF_ARGS);
1591 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1592
1593 // To patch Instance and Buffalo(N) AP
1594 // Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
1595 // Therefore, we send both of them.
1596 pDisassocHdr = (PHEADER_802_11)pOutBuffer;
1597 pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
1598 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1599
1600 MlmeFreeMemory(pAd, pOutBuffer);
1601
1602 pAd->StaCfg.DisassocReason = REASON_CLS3ERR;
1603 COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr);
1604}
1605
1606 /*
1607 ==========================================================================
1608 Description:
1609 Switch between WEP and CKIP upon new association up.
1610 Parameters:
1611
1612 IRQL = DISPATCH_LEVEL
1613
1614 ==========================================================================
1615 */
1616VOID SwitchBetweenWepAndCkip(
1617 IN PRTMP_ADAPTER pAd)
1618{
1619 int i;
1620 SHAREDKEY_MODE_STRUC csr1;
1621
1622 // if KP is required. change the CipherAlg in hardware shard key table from WEP
1623 // to CKIP. else remain as WEP
1624 if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10))
1625 {
1626 // modify hardware key table so that MAC use correct algorithm to decrypt RX
1627 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
1628 if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP64)
1629 csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP64;
1630 else if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP128)
1631 csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP128;
1632
1633 if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP64)
1634 csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP64;
1635 else if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP128)
1636 csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP128;
1637
1638 if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP64)
1639 csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP64;
1640 else if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP128)
1641 csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP128;
1642
1643 if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP64)
1644 csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP64;
1645 else if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP128)
1646 csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP128;
1647 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
1648 DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
1649
1650 // modify software key table so that driver can specify correct algorithm in TXD upon TX
1651 for (i=0; i<SHARE_KEY_NUM; i++)
1652 {
1653 if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP64)
1654 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP64;
1655 else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP128)
1656 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP128;
1657 }
1658 }
1659
1660 // else if KP NOT inused. change the CipherAlg in hardware shard key table from CKIP
1661 // to WEP.
1662 else
1663 {
1664 // modify hardware key table so that MAC use correct algorithm to decrypt RX
1665 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
1666 if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP64)
1667 csr1.field.Bss0Key0CipherAlg = CIPHER_WEP64;
1668 else if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP128)
1669 csr1.field.Bss0Key0CipherAlg = CIPHER_WEP128;
1670
1671 if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP64)
1672 csr1.field.Bss0Key1CipherAlg = CIPHER_WEP64;
1673 else if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP128)
1674 csr1.field.Bss0Key1CipherAlg = CIPHER_WEP128;
1675
1676 if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP64)
1677 csr1.field.Bss0Key2CipherAlg = CIPHER_WEP64;
1678 else if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP128)
1679 csr1.field.Bss0Key2CipherAlg = CIPHER_WEP128;
1680
1681 if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP64)
1682 csr1.field.Bss0Key3CipherAlg = CIPHER_WEP64;
1683 else if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP128)
1684 csr1.field.Bss0Key3CipherAlg = CIPHER_WEP128;
1685
1686 // modify software key table so that driver can specify correct algorithm in TXD upon TX
1687 for (i=0; i<SHARE_KEY_NUM; i++)
1688 {
1689 if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP64)
1690 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP64;
1691 else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP128)
1692 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP128;
1693 }
1694
1695 //
1696 // On WPA-NONE, must update CipherAlg.
1697 // Because the OID_802_11_WEP_STATUS was been set after OID_802_11_ADD_KEY
1698 // and CipherAlg will be CIPHER_NONE by Windows ZeroConfig.
1699 // So we need to update CipherAlg after connect.
1700 //
1701 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1702 {
1703 for (i = 0; i < SHARE_KEY_NUM; i++)
1704 {
1705 if (pAd->SharedKey[BSS0][i].KeyLen != 0)
1706 {
1707 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
1708 {
1709 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_TKIP;
1710 }
1711 else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1712 {
1713 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_AES;
1714 }
1715 }
1716 else
1717 {
1718 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
1719 }
1720 }
1721
1722 csr1.field.Bss0Key0CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
1723 csr1.field.Bss0Key1CipherAlg = pAd->SharedKey[BSS0][1].CipherAlg;
1724 csr1.field.Bss0Key2CipherAlg = pAd->SharedKey[BSS0][2].CipherAlg;
1725 csr1.field.Bss0Key3CipherAlg = pAd->SharedKey[BSS0][3].CipherAlg;
1726 }
1727 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
1728 DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
1729 }
1730}
1731
1732#ifdef WPA_SUPPLICANT_SUPPORT
1733#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1734VOID SendAssocIEsToWpaSupplicant(
1735 IN PRTMP_ADAPTER pAd)
1736{
1737 union iwreq_data wrqu;
1738 unsigned char custom[IW_CUSTOM_MAX] = {0};
1739
1740 if ((pAd->StaCfg.ReqVarIELen + 17) <= IW_CUSTOM_MAX)
1741 {
1742 sprintf(custom, "ASSOCINFO_ReqIEs=");
1743 NdisMoveMemory(custom+17, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
1744 memset(&wrqu, 0, sizeof(wrqu));
1745 wrqu.data.length = pAd->StaCfg.ReqVarIELen + 17;
1746 wrqu.data.flags = RT_REQIE_EVENT_FLAG;
1747 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
1748
1749 memset(&wrqu, 0, sizeof(wrqu));
1750 wrqu.data.flags = RT_ASSOCINFO_EVENT_FLAG;
1751 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1752 }
1753 else
1754 DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen + 17 > MAX_CUSTOM_LEN\n"));
1755
1756 return;
1757}
1758#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1759#endif // WPA_SUPPLICANT_SUPPORT //
1760
1761#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1762int wext_notify_event_assoc(
1763 IN RTMP_ADAPTER *pAd)
1764{
1765 union iwreq_data wrqu;
1766 char custom[IW_CUSTOM_MAX] = {0};
1767
1768#if WIRELESS_EXT > 17
1769 if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX)
1770 {
1771 wrqu.data.length = pAd->StaCfg.ReqVarIELen;
1772 memcpy(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
1773 wireless_send_event(pAd->net_dev, IWEVASSOCREQIE, &wrqu, custom);
1774 }
1775 else
1776 DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
1777#else
1778 if (((pAd->StaCfg.ReqVarIELen*2) + 17) <= IW_CUSTOM_MAX)
1779 {
1780 UCHAR idx;
1781 wrqu.data.length = (pAd->StaCfg.ReqVarIELen*2) + 17;
1782 sprintf(custom, "ASSOCINFO(ReqIEs=");
1783 for (idx=0; idx<pAd->StaCfg.ReqVarIELen; idx++)
1784 sprintf(custom, "%s%02x", custom, pAd->StaCfg.ReqVarIEs[idx]);
1785 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
1786 }
1787 else
1788 DBGPRINT(RT_DEBUG_TRACE, ("(pAd->StaCfg.ReqVarIELen*2) + 17 > MAX_CUSTOM_LEN\n"));
1789#endif
1790
1791 return 0;
1792
1793}
1794#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1795
1796
1797BOOLEAN StaAddMacTableEntry(
1798 IN PRTMP_ADAPTER pAd,
1799 IN PMAC_TABLE_ENTRY pEntry,
1800 IN UCHAR MaxSupportedRateIn500Kbps,
1801 IN HT_CAPABILITY_IE *pHtCapability,
1802 IN UCHAR HtCapabilityLen,
1803 IN USHORT CapabilityInfo)
1804{
1805 UCHAR MaxSupportedRate = RATE_11;
1806
1807 if (ADHOC_ON(pAd))
1808 CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
1809
1810 switch (MaxSupportedRateIn500Kbps)
1811 {
1812 case 108: MaxSupportedRate = RATE_54; break;
1813 case 96: MaxSupportedRate = RATE_48; break;
1814 case 72: MaxSupportedRate = RATE_36; break;
1815 case 48: MaxSupportedRate = RATE_24; break;
1816 case 36: MaxSupportedRate = RATE_18; break;
1817 case 24: MaxSupportedRate = RATE_12; break;
1818 case 18: MaxSupportedRate = RATE_9; break;
1819 case 12: MaxSupportedRate = RATE_6; break;
1820 case 22: MaxSupportedRate = RATE_11; break;
1821 case 11: MaxSupportedRate = RATE_5_5; break;
1822 case 4: MaxSupportedRate = RATE_2; break;
1823 case 2: MaxSupportedRate = RATE_1; break;
1824 default: MaxSupportedRate = RATE_11; break;
1825 }
1826
1827 if ((pAd->CommonCfg.PhyMode == PHY_11G) && (MaxSupportedRate < RATE_FIRST_OFDM_RATE))
1828 return FALSE;
1829
1830#ifdef DOT11_N_SUPPORT
1831 // 11n only
1832 if (((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))&& (HtCapabilityLen == 0))
1833 return FALSE;
1834#endif // DOT11_N_SUPPORT //
1835
1836 if (!pEntry)
1837 return FALSE;
1838
1839 NdisAcquireSpinLock(&pAd->MacTabLock);
1840 if (pEntry)
1841 {
1842 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1843 if ((MaxSupportedRate < RATE_FIRST_OFDM_RATE) ||
1844 (pAd->CommonCfg.PhyMode == PHY_11B))
1845 {
1846 pEntry->RateLen = 4;
1847 if (MaxSupportedRate >= RATE_FIRST_OFDM_RATE)
1848 MaxSupportedRate = RATE_11;
1849 }
1850 else
1851 pEntry->RateLen = 12;
1852
1853 pEntry->MaxHTPhyMode.word = 0;
1854 pEntry->MinHTPhyMode.word = 0;
1855 pEntry->HTPhyMode.word = 0;
1856 pEntry->MaxSupportedRate = MaxSupportedRate;
1857 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
1858 {
1859 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
1860 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
1861 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
1862 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
1863 pEntry->HTPhyMode.field.MODE = MODE_CCK;
1864 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
1865 }
1866 else
1867 {
1868 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
1869 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
1870 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
1871 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
1872 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
1873 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
1874 }
1875 pEntry->CapabilityInfo = CapabilityInfo;
1876 CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
1877 CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
1878 }
1879
1880#ifdef DOT11_N_SUPPORT
1881 // If this Entry supports 802.11n, upgrade to HT rate.
1882 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
1883 {
1884 UCHAR j, bitmask; //k,bitmask;
1885 CHAR i;
1886
1887 if (ADHOC_ON(pAd))
1888 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
1889 if ((pHtCapability->HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
1890 {
1891 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
1892 }
1893 else
1894 {
1895 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
1896 pAd->MacTab.fAnyStationNonGF = TRUE;
1897 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
1898 }
1899
1900 if ((pHtCapability->HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
1901 {
1902 pEntry->MaxHTPhyMode.field.BW= BW_40;
1903 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pHtCapability->HtCapInfo.ShortGIfor40));
1904 }
1905 else
1906 {
1907 pEntry->MaxHTPhyMode.field.BW = BW_20;
1908 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(pHtCapability->HtCapInfo.ShortGIfor20));
1909 pAd->MacTab.fAnyStation20Only = TRUE;
1910 }
1911
1912 // 3*3
1913 if (pAd->MACVersion >= RALINK_2883_VERSION && pAd->MACVersion < RALINK_3070_VERSION)
1914 pEntry->MaxHTPhyMode.field.TxBF = pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1915
1916 // find max fixed rate
1917 for (i=23; i>=0; i--) // 3*3
1918 {
1919 j = i/8;
1920 bitmask = (1<<(i-(j*8)));
1921 if ((pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j] & bitmask) && (pHtCapability->MCSSet[j] & bitmask))
1922 {
1923 pEntry->MaxHTPhyMode.field.MCS = i;
1924 break;
1925 }
1926 if (i==0)
1927 break;
1928 }
1929
1930
1931 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
1932 {
1933 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
1934 {
1935 // Fix MCS as HT Duplicated Mode
1936 pEntry->MaxHTPhyMode.field.BW = 1;
1937 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
1938 pEntry->MaxHTPhyMode.field.STBC = 0;
1939 pEntry->MaxHTPhyMode.field.ShortGI = 0;
1940 pEntry->MaxHTPhyMode.field.MCS = 32;
1941 }
1942 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
1943 {
1944 // STA supports fixed MCS
1945 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1946 }
1947 }
1948
1949 pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
1950 pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity;
1951 pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor;
1952 pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs;
1953 pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize;
1954 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
1955
1956 if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
1957 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED);
1958 if (pHtCapability->HtCapInfo.ShortGIfor20)
1959 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
1960 if (pHtCapability->HtCapInfo.ShortGIfor40)
1961 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
1962 if (pHtCapability->HtCapInfo.TxSTBC)
1963 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
1964 if (pHtCapability->HtCapInfo.RxSTBC)
1965 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
1966 if (pHtCapability->ExtHtCapInfo.PlusHTC)
1967 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
1968 if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
1969 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
1970 if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03)
1971 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
1972 }
1973 else
1974 {
1975 pAd->MacTab.fAnyStationIsLegacy = TRUE;
1976 }
1977
1978 NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE));
1979#endif // DOT11_N_SUPPORT //
1980
1981 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
1982 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
1983
1984 // Set asic auto fall back
1985 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
1986 {
1987 PUCHAR pTable;
1988 UCHAR TableSize = 0;
1989
1990 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
1991 pEntry->bAutoTxRateSwitch = TRUE;
1992 }
1993 else
1994 {
1995 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
1996 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1997 pEntry->bAutoTxRateSwitch = FALSE;
1998
1999 // If the legacy mode is set, overwrite the transmit setting of this entry.
2000 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
2001 }
2002
2003 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
2004 pEntry->Sst = SST_ASSOC;
2005 pEntry->AuthState = AS_AUTH_OPEN;
2006 pEntry->AuthMode = pAd->StaCfg.AuthMode;
2007 pEntry->WepStatus = pAd->StaCfg.WepStatus;
2008
2009 NdisReleaseSpinLock(&pAd->MacTabLock);
2010
2011#ifdef WPA_SUPPLICANT_SUPPORT
2012#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2013 if (pAd->StaCfg.WpaSupplicantUP)
2014 {
2015 union iwreq_data wrqu;
2016
2017 SendAssocIEsToWpaSupplicant(pAd);
2018 memset(&wrqu, 0, sizeof(wrqu));
2019 wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
2020 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2021 }
2022#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2023#endif // WPA_SUPPLICANT_SUPPORT //
2024
2025#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2026 {
2027 union iwreq_data wrqu;
2028 wext_notify_event_assoc(pAd);
2029
2030 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2031 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
2032 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2033
2034 }
2035#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2036 return TRUE;
2037}
2038
2039
diff --git a/drivers/staging/rt2870/sta/auth.c b/drivers/staging/rt2870/sta/auth.c
new file mode 100644
index 00000000000..73fb8d6ea76
--- /dev/null
+++ b/drivers/staging/rt2870/sta/auth.c
@@ -0,0 +1,474 @@
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 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send DE-AUTH request (Reason=%d)...\n", pInfo->Reason));
378 MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, pAd->MlmeAux.Bssid);
379 MakeOutgoingFrame(pOutBuffer, &FrameLen,
380 sizeof(HEADER_802_11),&DeauthHdr,
381 2, &pInfo->Reason,
382 END_OF_ARGS);
383 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
384 MlmeFreeMemory(pAd, pOutBuffer);
385
386 pAd->StaCfg.DeauthReason = pInfo->Reason;
387 COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr);
388 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
389 Status = MLME_SUCCESS;
390 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
391
392 // send wireless event - for deauthentication
393 if (pAd->CommonCfg.bWirelessEvent)
394 RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
395}
396
397/*
398 ==========================================================================
399 Description:
400
401 IRQL = DISPATCH_LEVEL
402
403 ==========================================================================
404 */
405VOID AuthTimeoutAction(
406 IN PRTMP_ADAPTER pAd,
407 IN MLME_QUEUE_ELEM *Elem)
408{
409 USHORT Status;
410 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeoutAction\n"));
411 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
412 Status = MLME_REJ_TIMEOUT;
413 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
414}
415
416/*
417 ==========================================================================
418 Description:
419
420 IRQL = DISPATCH_LEVEL
421
422 ==========================================================================
423 */
424VOID InvalidStateWhenAuth(
425 IN PRTMP_ADAPTER pAd,
426 IN MLME_QUEUE_ELEM *Elem)
427{
428 USHORT Status;
429 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n", pAd->Mlme.AuthMachine.CurrState));
430 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
431 Status = MLME_STATE_MACHINE_REJECT;
432 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
433}
434
435/*
436 ==========================================================================
437 Description:
438 Some STA/AP
439 Note:
440 This action should never trigger AUTH state transition, therefore we
441 separate it from AUTH state machine, and make it as a standalone service
442
443 IRQL = DISPATCH_LEVEL
444
445 ==========================================================================
446 */
447VOID Cls2errAction(
448 IN PRTMP_ADAPTER pAd,
449 IN PUCHAR pAddr)
450{
451 HEADER_802_11 DeauthHdr;
452 PUCHAR pOutBuffer = NULL;
453 NDIS_STATUS NStatus;
454 ULONG FrameLen = 0;
455 USHORT Reason = REASON_CLS2ERR;
456
457 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
458 if (NStatus != NDIS_STATUS_SUCCESS)
459 return;
460
461 DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Class 2 error, Send DEAUTH frame...\n"));
462 MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr, pAd->MlmeAux.Bssid);
463 MakeOutgoingFrame(pOutBuffer, &FrameLen,
464 sizeof(HEADER_802_11),&DeauthHdr,
465 2, &Reason,
466 END_OF_ARGS);
467 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
468 MlmeFreeMemory(pAd, pOutBuffer);
469
470 pAd->StaCfg.DeauthReason = Reason;
471 COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr);
472}
473
474
diff --git a/drivers/staging/rt2870/sta/auth_rsp.c b/drivers/staging/rt2870/sta/auth_rsp.c
new file mode 100644
index 00000000000..6e3c2d24cda
--- /dev/null
+++ b/drivers/staging/rt2870/sta/auth_rsp.c
@@ -0,0 +1,166 @@
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#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
131 {
132 union iwreq_data wrqu;
133 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
134 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
135 }
136#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
137
138
139 // send wireless event - for deauthentication
140 if (pAd->CommonCfg.bWirelessEvent)
141 RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
142
143 LinkDown(pAd, TRUE);
144
145 // Authentication Mode Cisco_LEAP has start a timer
146 // We should cancel it if using LEAP
147#ifdef LEAP_SUPPORT
148 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
149 {
150 RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &TimerCancelled);
151 //Check is it mach the LEAP Authentication failed as possible a Rogue AP
152 //on it's PortSecured not equal to WPA_802_1X_PORT_SECURED while process the Authenticaton.
153 if ((pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED) && (pAd->Mlme.LeapMachine.CurrState != LEAP_IDLE))
154 {
155 RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_AUTH_TIMEOUT);
156 }
157 }
158#endif // LEAP_SUPPORT //
159 }
160 }
161 else
162 {
163 DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - PeerDeauthAction() sanity check fail\n"));
164 }
165}
166
diff --git a/drivers/staging/rt2870/sta/connect.c b/drivers/staging/rt2870/sta/connect.c
new file mode 100644
index 00000000000..c93140a8caa
--- /dev/null
+++ b/drivers/staging/rt2870/sta/connect.c
@@ -0,0 +1,2822 @@
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 CntlIdleProc(pAd, Elem);
127 break;
128 case CNTL_WAIT_DISASSOC:
129 CntlWaitDisassocProc(pAd, Elem);
130 break;
131 case CNTL_WAIT_JOIN:
132 CntlWaitJoinProc(pAd, Elem);
133 break;
134
135 // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
136 // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
137 // Therefore not protected by NDIS's "only one outstanding OID request"
138 // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
139 // Current approach is to block new SET request at RTMPSetInformation()
140 // when CntlMachine.CurrState is not CNTL_IDLE
141 case CNTL_WAIT_REASSOC:
142 CntlWaitReassocProc(pAd, Elem);
143 break;
144
145 case CNTL_WAIT_START:
146 CntlWaitStartProc(pAd, Elem);
147 break;
148 case CNTL_WAIT_AUTH:
149 CntlWaitAuthProc(pAd, Elem);
150 break;
151 case CNTL_WAIT_AUTH2:
152 CntlWaitAuthProc2(pAd, Elem);
153 break;
154 case CNTL_WAIT_ASSOC:
155 CntlWaitAssocProc(pAd, Elem);
156 break;
157
158 case CNTL_WAIT_OID_LIST_SCAN:
159 if(Elem->MsgType == MT2_SCAN_CONF)
160 {
161 // Resume TxRing after SCANING complete. We hope the out-of-service time
162 // won't be too long to let upper layer time-out the waiting frames
163 RTMPResumeMsduTransmission(pAd);
164 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
165 {
166 // Cisco scan request is finished, prepare beacon report
167 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
168 }
169 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
170
171 //
172 // Set LED status to previous status.
173 //
174 if (pAd->bLedOnScanning)
175 {
176 pAd->bLedOnScanning = FALSE;
177 RTMPSetLED(pAd, pAd->LedStatus);
178 }
179#ifdef DOT11N_DRAFT3
180 // AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone.
181 if (pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1)
182 {
183 Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
184 }
185#endif // DOT11N_DRAFT3 //
186 }
187 break;
188
189 case CNTL_WAIT_OID_DISASSOC:
190 if (Elem->MsgType == MT2_DISASSOC_CONF)
191 {
192 LinkDown(pAd, FALSE);
193 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
194 }
195 break;
196#ifdef RT2870
197 //
198 // This state is for that we want to connect to an AP but
199 // it didn't find on BSS List table. So we need to scan the air first,
200 // after that we can try to connect to the desired AP if available.
201 //
202 case CNTL_WAIT_SCAN_FOR_CONNECT:
203 if(Elem->MsgType == MT2_SCAN_CONF)
204 {
205 // Resume TxRing after SCANING complete. We hope the out-of-service time
206 // won't be too long to let upper layer time-out the waiting frames
207 RTMPResumeMsduTransmission(pAd);
208#ifdef CCX_SUPPORT
209 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
210 {
211 // Cisco scan request is finished, prepare beacon report
212 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
213 }
214#endif // CCX_SUPPORT //
215 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
216
217 //
218 // Check if we can connect to.
219 //
220 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
221 if (pAd->MlmeAux.SsidBssTab.BssNr > 0)
222 {
223 MlmeAutoReconnectLastSSID(pAd);
224 }
225 }
226 break;
227#endif // RT2870 //
228 default:
229 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
230 break;
231 }
232}
233
234
235/*
236 ==========================================================================
237 Description:
238
239 IRQL = DISPATCH_LEVEL
240
241 ==========================================================================
242*/
243VOID CntlIdleProc(
244 IN PRTMP_ADAPTER pAd,
245 IN MLME_QUEUE_ELEM *Elem)
246{
247 MLME_DISASSOC_REQ_STRUCT DisassocReq;
248
249 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
250 return;
251
252 switch(Elem->MsgType)
253 {
254 case OID_802_11_SSID:
255 CntlOidSsidProc(pAd, Elem);
256 break;
257
258 case OID_802_11_BSSID:
259 CntlOidRTBssidProc(pAd,Elem);
260 break;
261
262 case OID_802_11_BSSID_LIST_SCAN:
263 CntlOidScanProc(pAd,Elem);
264 break;
265
266 case OID_802_11_DISASSOCIATE:
267#ifdef RALINK_ATE
268 if(ATE_ON(pAd))
269 {
270 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
271 break;
272 }
273#endif // RALINK_ATE //
274 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
275 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
276 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
277#ifdef WPA_SUPPLICANT_SUPPORT
278 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
279#endif // WPA_SUPPLICANT_SUPPORT //
280 {
281 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
282 // Since calling this indicate user don't want to connect to that SSID anymore.
283 pAd->MlmeAux.AutoReconnectSsidLen= 32;
284 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
285 }
286 break;
287
288 case MT2_MLME_ROAMING_REQ:
289 CntlMlmeRoamingProc(pAd, Elem);
290 break;
291
292 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
293 WpaMicFailureReportFrame(pAd, Elem);
294 break;
295
296#ifdef QOS_DLS_SUPPORT
297 case RT_OID_802_11_SET_DLS_PARAM:
298 CntlOidDLSSetupProc(pAd, Elem);
299 break;
300#endif // QOS_DLS_SUPPORT //
301
302 default:
303 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
304 break;
305 }
306}
307
308VOID CntlOidScanProc(
309 IN PRTMP_ADAPTER pAd,
310 IN MLME_QUEUE_ELEM *Elem)
311{
312 MLME_SCAN_REQ_STRUCT ScanReq;
313 ULONG BssIdx = BSS_NOT_FOUND;
314 BSS_ENTRY CurrBss;
315
316#ifdef RALINK_ATE
317/* Disable scanning when ATE is running. */
318 if (ATE_ON(pAd))
319 return;
320#endif // RALINK_ATE //
321
322
323 // record current BSS if network is connected.
324 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
325 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
326 {
327 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
328 if (BssIdx != BSS_NOT_FOUND)
329 {
330 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
331 }
332 }
333
334 // clean up previous SCAN result, add current BSS back to table if any
335 BssTableInit(&pAd->ScanTab);
336 if (BssIdx != BSS_NOT_FOUND)
337 {
338 // DDK Note: If the NIC is associated with a particular BSSID and SSID
339 // that are not contained in the list of BSSIDs generated by this scan, the
340 // BSSID description of the currently associated BSSID and SSID should be
341 // appended to the list of BSSIDs in the NIC's database.
342 // To ensure this, we append this BSS as the first entry in SCAN result
343 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
344 pAd->ScanTab.BssNr = 1;
345 }
346
347 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
348 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
349 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
350 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
351}
352
353/*
354 ==========================================================================
355 Description:
356 Before calling this routine, user desired SSID should already been
357 recorded in CommonCfg.Ssid[]
358 IRQL = DISPATCH_LEVEL
359
360 ==========================================================================
361*/
362VOID CntlOidSsidProc(
363 IN PRTMP_ADAPTER pAd,
364 IN MLME_QUEUE_ELEM * Elem)
365{
366 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
367 MLME_DISASSOC_REQ_STRUCT DisassocReq;
368 ULONG Now;
369
370 // Step 1. record the desired user settings to MlmeAux
371 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
372 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
373 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
374 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
375 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
376
377
378 //
379 // Update Reconnect Ssid, that user desired to connect.
380 //
381 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
382 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
383 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
384
385 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
386 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
387 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
388
389 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
390 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
391 NdisGetSystemUpTime(&Now);
392
393 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
394 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
395 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
396 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
397 {
398 // Case 1. already connected with an AP who has the desired SSID
399 // with highest RSSI
400
401 // Add checking Mode "LEAP" for CCX 1.0
402 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
403 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
404 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
405 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
406#ifdef LEAP_SUPPORT
407 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
408#endif // LEAP_SUPPORT //
409 ) &&
410 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
411 {
412 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
413 // connection process
414 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
415 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
416 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
417 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
418 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
419 }
420 else if (pAd->bConfigChanged == TRUE)
421 {
422 // case 1.2 Important Config has changed, we have to reconnect to the same AP
423 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
424 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
425 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
426 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
427 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
428 }
429 else
430 {
431 // case 1.3. already connected to the SSID with highest RSSI.
432 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
433 //
434 // (HCT 12.1) 1c_wlan_mediaevents required
435 // media connect events are indicated when associating with the same AP
436 //
437 if (INFRA_ON(pAd))
438 {
439 //
440 // Since MediaState already is NdisMediaStateConnected
441 // We just indicate the connect event again to meet the WHQL required.
442 //
443 pAd->IndicateMediaState = NdisMediaStateConnected;
444 RTMP_IndicateMediaState(pAd);
445 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
446 }
447
448 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
449#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
450 {
451 union iwreq_data wrqu;
452
453 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
454 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
455 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
456
457 }
458#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
459 }
460 }
461 else if (INFRA_ON(pAd))
462 {
463 //
464 // For RT61
465 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
466 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
467 // But media status is connected, so the SSID not report correctly.
468 //
469 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
470 {
471 //
472 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
473 //
474 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
475 }
476 // case 2. active INFRA association existent
477 // roaming is done within miniport driver, nothing to do with configuration
478 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
479 // disassociate with the current associated AP,
480 // then perform a new association with this new SSID, no matter the
481 // new/old SSID are the same or not.
482 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
483 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
484 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
485 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
486 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
487 }
488 else
489 {
490 if (ADHOC_ON(pAd))
491 {
492 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
493 LinkDown(pAd, FALSE);
494 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
495 pAd->IndicateMediaState = NdisMediaStateDisconnected;
496 RTMP_IndicateMediaState(pAd);
497 pAd->ExtraInfo = GENERAL_LINK_DOWN;
498 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
499 }
500
501 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
502 (pAd->StaCfg.bAutoReconnect == TRUE) &&
503 (pAd->MlmeAux.BssType == BSS_INFRA) &&
504 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
505 )
506 {
507 MLME_SCAN_REQ_STRUCT ScanReq;
508
509 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
510 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
511 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
512 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
513 // Reset Missed scan number
514 pAd->StaCfg.LastScanTime = Now;
515 }
516 else
517 {
518 pAd->MlmeAux.BssIdx = 0;
519 IterateOnBssTab(pAd);
520 }
521 }
522}
523
524
525/*
526 ==========================================================================
527 Description:
528
529 IRQL = DISPATCH_LEVEL
530
531 ==========================================================================
532*/
533VOID CntlOidRTBssidProc(
534 IN PRTMP_ADAPTER pAd,
535 IN MLME_QUEUE_ELEM * Elem)
536{
537 ULONG BssIdx;
538 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
539 MLME_DISASSOC_REQ_STRUCT DisassocReq;
540 MLME_JOIN_REQ_STRUCT JoinReq;
541
542#ifdef RALINK_ATE
543/* No need to perform this routine when ATE is running. */
544 if (ATE_ON(pAd))
545 return;
546#endif // RALINK_ATE //
547
548 // record user desired settings
549 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
550 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
551
552 //
553 // Update Reconnect Ssid, that user desired to connect.
554 //
555 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
556 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
557 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
558
559 // find the desired BSS in the latest SCAN result table
560 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
561 if (BssIdx == BSS_NOT_FOUND)
562 {
563 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
564 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
565 return;
566 }
567
568 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
569 // Because we need this entry to become the JOIN target in later on SYNC state machine
570 pAd->MlmeAux.BssIdx = 0;
571 pAd->MlmeAux.SsidBssTab.BssNr = 1;
572 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
573
574 //pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
575 //NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
576
577 // Add SSID into MlmeAux for site surey joining hidden SSID
578 //pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
579 //NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
580
581 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
582 // we just follow normal procedure. The reason of user doing this may because he/she changed
583 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
584 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
585 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
586 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
587 // connection when setting the same BSSID.
588 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
589 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
590 {
591 // already connected to the same BSSID, go back to idle state directly
592 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
593 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
594#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
595 {
596 union iwreq_data wrqu;
597
598 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
599 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
600 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
601
602 }
603#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
604 }
605 else
606 {
607 if (INFRA_ON(pAd))
608 {
609 // disassoc from current AP first
610 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
611 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
612 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
613 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
614
615 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
616 }
617 else
618 {
619 if (ADHOC_ON(pAd))
620 {
621 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
622 LinkDown(pAd, FALSE);
623 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
624 pAd->IndicateMediaState = NdisMediaStateDisconnected;
625 RTMP_IndicateMediaState(pAd);
626 pAd->ExtraInfo = GENERAL_LINK_DOWN;
627 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
628 }
629
630 // Change the wepstatus to original wepstatus
631 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
632 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
633 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
634
635 // Check cipher suite, AP must have more secured cipher than station setting
636 // Set the Pairwise and Group cipher to match the intended AP setting
637 // We can only connect to AP with less secured cipher setting
638 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
639 {
640 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
641
642 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
643 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
644 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
645 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
646 else // There is no PairCipher Aux, downgrade our capability to TKIP
647 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
648 }
649 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
650 {
651 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
652
653 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
654 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
655 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
656 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
657 else // There is no PairCipher Aux, downgrade our capability to TKIP
658 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
659
660 // RSN capability
661 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
662 }
663
664 // Set Mix cipher flag
665 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
666 if (pAd->StaCfg.bMixCipher == TRUE)
667 {
668 // If mix cipher, re-build RSNIE
669 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
670 }
671 // No active association, join the BSS immediately
672 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
673 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
674
675 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
676 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
677
678 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
679 }
680 }
681}
682
683// Roaming is the only external request triggering CNTL state machine
684// despite of other "SET OID" operation. All "SET OID" related oerations
685// happen in sequence, because no other SET OID will be sent to this device
686// until the the previous SET operation is complete (successful o failed).
687// So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
688// or been corrupted by other "SET OID"?
689//
690// IRQL = DISPATCH_LEVEL
691VOID CntlMlmeRoamingProc(
692 IN PRTMP_ADAPTER pAd,
693 IN MLME_QUEUE_ELEM *Elem)
694{
695 // TODO:
696 // AP in different channel may show lower RSSI than actual value??
697 // should we add a weighting factor to compensate it?
698 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
699
700 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
701 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
702
703 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
704 pAd->MlmeAux.BssIdx = 0;
705 IterateOnBssTab(pAd);
706}
707
708#ifdef QOS_DLS_SUPPORT
709/*
710 ==========================================================================
711 Description:
712
713 IRQL = DISPATCH_LEVEL
714
715 ==========================================================================
716*/
717VOID CntlOidDLSSetupProc(
718 IN PRTMP_ADAPTER pAd,
719 IN MLME_QUEUE_ELEM *Elem)
720{
721 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)Elem->Msg;
722 MLME_DLS_REQ_STRUCT MlmeDlsReq;
723 INT i;
724 USHORT reason = REASON_UNSPECIFY;
725
726 DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n",
727 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5],
728 pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer));
729
730 if (!pAd->CommonCfg.bDLSCapable)
731 return;
732
733 // DLS will not be supported when Adhoc mode
734 if (INFRA_ON(pAd))
735 {
736 for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++)
737 {
738 if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
739 (pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
740 {
741 // 1. Same setting, just drop it
742 DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n"));
743 break;
744 }
745 else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
746 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
747 {
748 // 2. Disable DLS link case, just tear down DLS link
749 reason = REASON_QOS_UNWANTED_MECHANISM;
750 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
751 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
752 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
753 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
754 DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n"));
755 break;
756 }
757 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid)
758 {
759 // 3. Enable case, start DLS setup procedure
760 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
761
762 //Update countdown timer
763 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
764 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
765 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
766 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n"));
767 break;
768 }
769 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
770 (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
771 {
772 // 4. update mac case, tear down old DLS and setup new DLS
773 reason = REASON_QOS_UNWANTED_MECHANISM;
774 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
775 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
776 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
777 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
778 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
779 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
780 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
781 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS tear down and restart case\n"));
782 break;
783 }
784 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
785 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr) && (pAd->StaCfg.DLSEntry[i].TimeOut != pDLS->TimeOut))
786 {
787 // 5. update timeout case, start DLS setup procedure (no tear down)
788 pAd->StaCfg.DLSEntry[i].TimeOut = pDLS->TimeOut;
789 //Update countdown timer
790 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
791 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
792 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
793 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS update timeout case\n"));
794 break;
795 }
796 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
797 (pAd->StaCfg.DLSEntry[i].Status != DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
798 {
799 // 6. re-setup case, start DLS setup procedure (no tear down)
800 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
801 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
802 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS retry setup procedure\n"));
803 break;
804 }
805 else
806 {
807 DBGPRINT(RT_DEBUG_WARN,("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n",
808 i, pAd->StaCfg.DLSEntry[i].Valid, pAd->StaCfg.DLSEntry[i].Status, pAd->StaCfg.DLSEntry[i].TimeOut));
809 }
810 }
811 }
812}
813#endif // QOS_DLS_SUPPORT //
814
815/*
816 ==========================================================================
817 Description:
818
819 IRQL = DISPATCH_LEVEL
820
821 ==========================================================================
822*/
823VOID CntlWaitDisassocProc(
824 IN PRTMP_ADAPTER pAd,
825 IN MLME_QUEUE_ELEM *Elem)
826{
827 MLME_START_REQ_STRUCT StartReq;
828
829 if (Elem->MsgType == MT2_DISASSOC_CONF)
830 {
831 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
832
833 if (pAd->CommonCfg.bWirelessEvent)
834 {
835 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
836 }
837
838 LinkDown(pAd, FALSE);
839
840 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
841 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
842 {
843 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
844 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
845 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
846 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
847 }
848 // case 2. try each matched BSS
849 else
850 {
851 pAd->MlmeAux.BssIdx = 0;
852
853 IterateOnBssTab(pAd);
854 }
855 }
856}
857
858/*
859 ==========================================================================
860 Description:
861
862 IRQL = DISPATCH_LEVEL
863
864 ==========================================================================
865*/
866VOID CntlWaitJoinProc(
867 IN PRTMP_ADAPTER pAd,
868 IN MLME_QUEUE_ELEM *Elem)
869{
870 USHORT Reason;
871 MLME_AUTH_REQ_STRUCT AuthReq;
872
873 if (Elem->MsgType == MT2_JOIN_CONF)
874 {
875 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
876 if (Reason == MLME_SUCCESS)
877 {
878 // 1. joined an IBSS, we are pretty much done here
879 if (pAd->MlmeAux.BssType == BSS_ADHOC)
880 {
881 //
882 // 5G bands rules of Japan:
883 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
884 //
885 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
886 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
887 )
888 {
889 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
890 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
891 return;
892 }
893
894 LinkUp(pAd, BSS_ADHOC);
895 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
896 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
897 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
898 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
899
900 pAd->IndicateMediaState = NdisMediaStateConnected;
901 pAd->ExtraInfo = GENERAL_LINK_UP;
902 }
903 // 2. joined a new INFRA network, start from authentication
904 else
905 {
906#ifdef LEAP_SUPPORT
907 // Add AuthMode "LEAP" for CCX 1.X
908 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
909 {
910 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
911 }
912 else
913#endif // LEAP_SUPPORT //
914 {
915 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
916 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
917 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
918 {
919 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
920 }
921 else
922 {
923 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
924 }
925 }
926 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
927 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
928
929 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
930 }
931 }
932 else
933 {
934 // 3. failed, try next BSS
935 pAd->MlmeAux.BssIdx++;
936 IterateOnBssTab(pAd);
937 }
938 }
939}
940
941
942/*
943 ==========================================================================
944 Description:
945
946 IRQL = DISPATCH_LEVEL
947
948 ==========================================================================
949*/
950VOID CntlWaitStartProc(
951 IN PRTMP_ADAPTER pAd,
952 IN MLME_QUEUE_ELEM *Elem)
953{
954 USHORT Result;
955
956 if (Elem->MsgType == MT2_START_CONF)
957 {
958 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
959 if (Result == MLME_SUCCESS)
960 {
961 //
962 // 5G bands rules of Japan:
963 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
964 //
965 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
966 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
967 )
968 {
969 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
970 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
971 return;
972 }
973#ifdef DOT11_N_SUPPORT
974 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
975 {
976 N_ChannelCheck(pAd);
977 SetCommonHT(pAd);
978 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
979 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
980 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
981 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
982 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
983 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
984
985 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
986 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
987 {
988 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
989 }
990 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
991 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
992 {
993 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
994 }
995 }
996 else
997#endif // DOT11_N_SUPPORT //
998 {
999 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1000 }
1001 LinkUp(pAd, BSS_ADHOC);
1002 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1003 // Before send beacon, driver need do radar detection
1004 if ((pAd->CommonCfg.Channel > 14 )
1005 && (pAd->CommonCfg.bIEEE80211H == 1)
1006 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1007 {
1008 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
1009 pAd->CommonCfg.RadarDetect.RDCount = 0;
1010#ifdef DFS_SUPPORT
1011 BbpRadarDetectionStart(pAd);
1012#endif // DFS_SUPPORT //
1013 }
1014
1015 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
1016 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
1017 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
1018 }
1019 else
1020 {
1021 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
1022 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1023 }
1024 }
1025}
1026
1027/*
1028 ==========================================================================
1029 Description:
1030
1031 IRQL = DISPATCH_LEVEL
1032
1033 ==========================================================================
1034*/
1035VOID CntlWaitAuthProc(
1036 IN PRTMP_ADAPTER pAd,
1037 IN MLME_QUEUE_ELEM *Elem)
1038{
1039 USHORT Reason;
1040 MLME_ASSOC_REQ_STRUCT AssocReq;
1041 MLME_AUTH_REQ_STRUCT AuthReq;
1042
1043 if (Elem->MsgType == MT2_AUTH_CONF)
1044 {
1045 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1046 if (Reason == MLME_SUCCESS)
1047 {
1048 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1049 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1050 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1051
1052#ifdef LEAP_SUPPORT
1053 //
1054 // Cisco Leap CCKM supported Re-association.
1055 //
1056 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
1057 {
1058 //if CCKM is turn on , that's mean Fast Reauthentication
1059 //Use CCKM Reassociation instead of normal association for Fast Roaming.
1060 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
1061 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1062
1063 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
1064 }
1065 else
1066#endif // LEAP_SUPPORT //
1067 {
1068 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1069 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1070
1071 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1072 }
1073 }
1074 else
1075 {
1076 // This fail may because of the AP already keep us in its MAC table without
1077 // ageing-out. The previous authentication attempt must have let it remove us.
1078 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
1079 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
1080#ifdef LEAP_SUPPORT
1081 //Add AuthMode "LEAP" for CCX 1.X
1082 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1083 {
1084 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
1085 }
1086 else
1087#endif // LEAP_SUPPORT //
1088 {
1089 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
1090 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
1091 {
1092 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
1093 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
1094 }
1095 else
1096 {
1097 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1098 }
1099 }
1100 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1101 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1102
1103 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1104 }
1105 }
1106}
1107
1108/*
1109 ==========================================================================
1110 Description:
1111
1112 IRQL = DISPATCH_LEVEL
1113
1114 ==========================================================================
1115*/
1116VOID CntlWaitAuthProc2(
1117 IN PRTMP_ADAPTER pAd,
1118 IN MLME_QUEUE_ELEM *Elem)
1119{
1120 USHORT Reason;
1121 MLME_ASSOC_REQ_STRUCT AssocReq;
1122 MLME_AUTH_REQ_STRUCT AuthReq;
1123
1124 if (Elem->MsgType == MT2_AUTH_CONF)
1125 {
1126 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1127 if (Reason == MLME_SUCCESS)
1128 {
1129 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1130 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1131 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1132 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1133 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1134
1135 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1136 }
1137 else
1138 {
1139#ifdef LEAP_SUPPORT
1140 // Process LEAP first, since it use different control variable
1141 // We don't want to affect other poven operation
1142 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1143 {
1144 // LEAP Auth not success, try next BSS
1145 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
1146 DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
1147 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1148 pAd->MlmeAux.BssIdx++;
1149 IterateOnBssTab(pAd);
1150 }
1151 else
1152#endif // LEAP_SUPPORT //
1153 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
1154 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
1155 {
1156 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
1157 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1158 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1159 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1160
1161 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1162 }
1163 else
1164 {
1165 // not success, try next BSS
1166 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
1167 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
1168 pAd->MlmeAux.BssIdx++;
1169 IterateOnBssTab(pAd);
1170 }
1171 }
1172 }
1173}
1174
1175/*
1176 ==========================================================================
1177 Description:
1178
1179 IRQL = DISPATCH_LEVEL
1180
1181 ==========================================================================
1182*/
1183VOID CntlWaitAssocProc(
1184 IN PRTMP_ADAPTER pAd,
1185 IN MLME_QUEUE_ELEM *Elem)
1186{
1187 USHORT Reason;
1188
1189 if (Elem->MsgType == MT2_ASSOC_CONF)
1190 {
1191 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1192 if (Reason == MLME_SUCCESS)
1193 {
1194 LinkUp(pAd, BSS_INFRA);
1195 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1196 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1197
1198 if (pAd->CommonCfg.bWirelessEvent)
1199 {
1200 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1201 }
1202 }
1203 else
1204 {
1205 // not success, try next BSS
1206 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1207 pAd->MlmeAux.BssIdx++;
1208 IterateOnBssTab(pAd);
1209 }
1210 }
1211}
1212
1213/*
1214 ==========================================================================
1215 Description:
1216
1217 IRQL = DISPATCH_LEVEL
1218
1219 ==========================================================================
1220*/
1221VOID CntlWaitReassocProc(
1222 IN PRTMP_ADAPTER pAd,
1223 IN MLME_QUEUE_ELEM *Elem)
1224{
1225 USHORT Result;
1226
1227 if (Elem->MsgType == MT2_REASSOC_CONF)
1228 {
1229 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1230 if (Result == MLME_SUCCESS)
1231 {
1232 //
1233 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1234 //
1235 LinkUp(pAd, BSS_INFRA);
1236
1237 // send wireless event - for association
1238 if (pAd->CommonCfg.bWirelessEvent)
1239 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1240
1241
1242#ifdef LEAP_SUPPORT
1243 if (LEAP_CCKM_ON(pAd))
1244 {
1245 STA_PORT_SECURED(pAd);
1246 pAd->StaCfg.WpaState = SS_FINISH;
1247 }
1248#endif // LEAP_SUPPORT //
1249 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1250 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1251 }
1252 else
1253 {
1254 // reassoc failed, try to pick next BSS in the BSS Table
1255 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1256 pAd->MlmeAux.RoamIdx++;
1257 IterateOnBssTab2(pAd);
1258 }
1259 }
1260}
1261
1262
1263VOID AdhocTurnOnQos(
1264 IN PRTMP_ADAPTER pAd)
1265{
1266#define AC0_DEF_TXOP 0
1267#define AC1_DEF_TXOP 0
1268#define AC2_DEF_TXOP 94
1269#define AC3_DEF_TXOP 47
1270
1271 // Turn on QOs if use HT rate.
1272 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1273 {
1274 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1275 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1276 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1277 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1278 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1279
1280 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1281 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1282 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1283 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1284
1285 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
1286 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
1287 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1288 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1289
1290 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1291 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1292 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
1293 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
1294 }
1295 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1296}
1297
1298/*
1299 ==========================================================================
1300 Description:
1301
1302 IRQL = DISPATCH_LEVEL
1303
1304 ==========================================================================
1305*/
1306VOID LinkUp(
1307 IN PRTMP_ADAPTER pAd,
1308 IN UCHAR BssType)
1309{
1310 ULONG Now;
1311 UINT32 Data;
1312 BOOLEAN Cancelled;
1313 UCHAR Value = 0, idx;
1314 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1315
1316 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1317
1318 //
1319 // ASSOC - DisassocTimeoutAction
1320 // CNTL - Dis-associate successful
1321 // !!! LINK DOWN !!!
1322 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1323 //
1324 // To prevent DisassocTimeoutAction to call Link down after we link up,
1325 // cancel the DisassocTimer no matter what it start or not.
1326 //
1327 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1328
1329 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1330
1331#ifdef DOT11_N_SUPPORT
1332 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1333#endif // DOT11_N_SUPPORT //
1334 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1335 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1336 // to examine if cipher algorithm switching is required.
1337 //rt2860b. Don't know why need this
1338 SwitchBetweenWepAndCkip(pAd);
1339
1340
1341 if (BssType == BSS_ADHOC)
1342 {
1343 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1344 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1345
1346#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1347 // No carrier detection when adhoc
1348 // CarrierDetectionStop(pAd);
1349 pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
1350#endif // CARRIER_DETECTION_SUPPORT //
1351
1352#ifdef DOT11_N_SUPPORT
1353 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1354 AdhocTurnOnQos(pAd);
1355#endif // DOT11_N_SUPPORT //
1356
1357 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1358 }
1359 else
1360 {
1361 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1362 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1363
1364 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1365 }
1366
1367 // 3*3
1368 // reset Tx beamforming bit
1369 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1370 Value &= (~0x01);
1371 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1372 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1373
1374#ifdef DOT11_N_SUPPORT
1375 // Change to AP channel
1376 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1377 {
1378 // Must using 40MHz.
1379 pAd->CommonCfg.BBPCurrentBW = BW_40;
1380 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1381 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1382
1383 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1384 Value &= (~0x18);
1385 Value |= 0x10;
1386 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1387
1388 // RX : control channel at lower
1389 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1390 Value &= (~0x20);
1391 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1392
1393 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1394 Data &= 0xfffffffe;
1395 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1396
1397 if (pAd->MACVersion == 0x28600100)
1398 {
1399 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1400 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1401 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1402 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1403 }
1404
1405 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1406 }
1407 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1408 {
1409 // Must using 40MHz.
1410 pAd->CommonCfg.BBPCurrentBW = BW_40;
1411 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1412 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1413
1414 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1415 Value &= (~0x18);
1416 Value |= 0x10;
1417 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1418
1419 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1420 Data |= 0x1;
1421 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1422
1423 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1424 Value |= (0x20);
1425 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1426
1427 if (pAd->MACVersion == 0x28600100)
1428 {
1429 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1430 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1431 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1432 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1433 }
1434
1435 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1436 }
1437 else
1438#endif // DOT11_N_SUPPORT //
1439 {
1440 pAd->CommonCfg.BBPCurrentBW = BW_20;
1441 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1442 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1443 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1444
1445 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1446 Value &= (~0x18);
1447 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1448
1449 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1450 Data &= 0xfffffffe;
1451 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1452
1453 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1454 Value &= (~0x20);
1455 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1456
1457 if (pAd->MACVersion == 0x28600100)
1458 {
1459 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1460 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1461 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1462 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1463 }
1464
1465 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1466 }
1467
1468 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1469 //
1470 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1471 //
1472 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1473
1474 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1475 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1476
1477#ifdef DOT11_N_SUPPORT
1478 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1479#endif // DOT11_N_SUPPORT //
1480
1481 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1482
1483 AsicSetSlotTime(pAd, TRUE);
1484 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1485
1486 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1487 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1488
1489#ifdef DOT11_N_SUPPORT
1490 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1491 {
1492 // Update HT protectionfor based on AP's operating mode.
1493 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1494 {
1495 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1496 }
1497 else
1498 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1499 }
1500#endif // DOT11_N_SUPPORT //
1501
1502 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1503
1504 NdisGetSystemUpTime(&Now);
1505 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1506
1507 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1508 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1509 {
1510 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1511 }
1512
1513 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1514
1515 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1516 {
1517#ifdef DFS_SUPPORT
1518 RadarDetectionStop(pAd);
1519#endif // DFS_SUPPORT //
1520 }
1521 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1522
1523 if (BssType == BSS_ADHOC)
1524 {
1525 MakeIbssBeacon(pAd);
1526 if ((pAd->CommonCfg.Channel > 14)
1527 && (pAd->CommonCfg.bIEEE80211H == 1)
1528 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1529 {
1530 ; //Do nothing
1531 }
1532 else
1533 {
1534 AsicEnableIbssSync(pAd);
1535 }
1536
1537 // In ad hoc mode, use MAC table from index 1.
1538 // 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.
1539 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1540 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1541
1542 // If WEP is enabled, add key material and cipherAlg into Asic
1543 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1544
1545 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1546 {
1547 PUCHAR Key;
1548 UCHAR CipherAlg;
1549
1550 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1551 {
1552 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1553 Key = pAd->SharedKey[BSS0][idx].Key;
1554
1555 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1556 {
1557 // Set key material and cipherAlg to Asic
1558 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1559
1560 if (idx == pAd->StaCfg.DefaultKeyId)
1561 {
1562 // Update WCID attribute table and IVEIV table for this group key table
1563 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1564 }
1565 }
1566
1567
1568 }
1569 }
1570 // If WPANone is enabled, add key material and cipherAlg into Asic
1571 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1572 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1573 {
1574 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1575
1576 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1577 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1578 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1579
1580 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1581 {
1582 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1583 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1584 }
1585
1586 // Decide its ChiperAlg
1587 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1588 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1589 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1590 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1591 else
1592 {
1593 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1594 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1595 }
1596
1597 // Set key material and cipherAlg to Asic
1598 AsicAddSharedKeyEntry(pAd,
1599 BSS0,
1600 0,
1601 pAd->SharedKey[BSS0][0].CipherAlg,
1602 pAd->SharedKey[BSS0][0].Key,
1603 pAd->SharedKey[BSS0][0].TxMic,
1604 pAd->SharedKey[BSS0][0].RxMic);
1605
1606 // Update WCID attribute table and IVEIV table for this group key table
1607 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1608
1609 }
1610
1611 }
1612 else // BSS_INFRA
1613 {
1614 // Check the new SSID with last SSID
1615 while (Cancelled == TRUE)
1616 {
1617 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1618 {
1619 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1620 {
1621 // Link to the old one no linkdown is required.
1622 break;
1623 }
1624 }
1625 // Send link down event before set to link up
1626 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1627 RTMP_IndicateMediaState(pAd);
1628 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1629 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1630 break;
1631 }
1632
1633 //
1634 // On WPA mode, Remove All Keys if not connect to the last BSSID
1635 // Key will be set after 4-way handshake.
1636 //
1637 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1638 {
1639 ULONG IV;
1640
1641 // Remove all WPA keys
1642 RTMPWPARemoveAllKeys(pAd);
1643 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1644 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1645
1646 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1647 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1648 IV = 0;
1649 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1650 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1651 }
1652 // NOTE:
1653 // the decision of using "short slot time" or not may change dynamically due to
1654 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1655
1656 // NOTE:
1657 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1658 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1659
1660 ComposePsPoll(pAd);
1661 ComposeNullFrame(pAd);
1662
1663 AsicEnableBssSync(pAd);
1664
1665 // Add BSSID to WCID search table
1666 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1667
1668 NdisAcquireSpinLock(&pAd->MacTabLock);
1669 // add this BSSID entry into HASH table
1670 {
1671 UCHAR HashIdx;
1672
1673 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1674 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1675 if (pAd->MacTab.Hash[HashIdx] == NULL)
1676 {
1677 pAd->MacTab.Hash[HashIdx] = pEntry;
1678 }
1679 else
1680 {
1681 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1682 while (pCurrEntry->pNext != NULL)
1683 pCurrEntry = pCurrEntry->pNext;
1684 pCurrEntry->pNext = pEntry;
1685 }
1686 }
1687 NdisReleaseSpinLock(&pAd->MacTabLock);
1688
1689
1690 // If WEP is enabled, add paiewise and shared key
1691#ifdef WPA_SUPPLICANT_SUPPORT
1692 if (((pAd->StaCfg.WpaSupplicantUP)&&
1693 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1694 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1695 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1696 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1697#else
1698 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1699#endif // WPA_SUPPLICANT_SUPPORT //
1700 {
1701 PUCHAR Key;
1702 UCHAR CipherAlg;
1703
1704 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1705 {
1706 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1707 Key = pAd->SharedKey[BSS0][idx].Key;
1708
1709 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1710 {
1711 // Set key material and cipherAlg to Asic
1712 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1713
1714 if (idx == pAd->StaCfg.DefaultKeyId)
1715 {
1716 // Assign group key info
1717 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1718
1719 // Assign pairwise key info
1720 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1721 }
1722 }
1723 }
1724 }
1725
1726 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1727 // should wait until at least 2 active nodes in this BSSID.
1728 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1729
1730 // For GUI ++
1731 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1732 {
1733 pAd->IndicateMediaState = NdisMediaStateConnected;
1734 pAd->ExtraInfo = GENERAL_LINK_UP;
1735 RTMP_IndicateMediaState(pAd);
1736 }
1737 // --
1738
1739 // Add BSSID in my MAC Table.
1740 NdisAcquireSpinLock(&pAd->MacTabLock);
1741 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1742 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1743 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1744 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1745 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1746 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1747 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1748 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1749 NdisReleaseSpinLock(&pAd->MacTabLock);
1750
1751 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1752 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1753
1754 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1755#ifdef DOT11_N_SUPPORT
1756 MlmeUpdateHtTxRates(pAd, BSS0);
1757 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1758#endif // DOT11_N_SUPPORT //
1759
1760 //
1761 // Report Adjacent AP report.
1762 //
1763#ifdef LEAP_SUPPORT
1764 CCXAdjacentAPReport(pAd);
1765#endif // LEAP_SUPPORT //
1766
1767 if (pAd->CommonCfg.bAggregationCapable)
1768 {
1769 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1770 {
1771
1772 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1773 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1774 RTMPSetPiggyBack(pAd, TRUE);
1775 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1776 }
1777 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1778 {
1779 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1780 }
1781 }
1782
1783 if (pAd->MlmeAux.APRalinkIe != 0x0)
1784 {
1785#ifdef DOT11_N_SUPPORT
1786 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1787 {
1788 AsicEnableRDG(pAd);
1789 }
1790#endif // DOT11_N_SUPPORT //
1791 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1792 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1793 }
1794 else
1795 {
1796 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1797 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1798 }
1799 }
1800
1801#ifdef DOT11_N_SUPPORT
1802 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));
1803#endif // DOT11_N_SUPPORT //
1804
1805 // Set LED
1806 RTMPSetLED(pAd, LED_LINK_UP);
1807
1808 pAd->Mlme.PeriodicRound = 0;
1809 pAd->Mlme.OneSecPeriodicRound = 0;
1810 pAd->bConfigChanged = FALSE; // Reset config flag
1811 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1812
1813 // Set asic auto fall back
1814 {
1815 PUCHAR pTable;
1816 UCHAR TableSize = 0;
1817
1818 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1819 AsicUpdateAutoFallBackTable(pAd, pTable);
1820 }
1821
1822 NdisAcquireSpinLock(&pAd->MacTabLock);
1823 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1824 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1825 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1826 {
1827 pEntry->bAutoTxRateSwitch = FALSE;
1828#ifdef DOT11_N_SUPPORT
1829 if (pEntry->HTPhyMode.field.MCS == 32)
1830 pEntry->HTPhyMode.field.ShortGI = GI_800;
1831
1832 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1833 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1834#endif // DOT11_N_SUPPORT //
1835 // If the legacy mode is set, overwrite the transmit setting of this entry.
1836 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1837 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1838 }
1839 else
1840 pEntry->bAutoTxRateSwitch = TRUE;
1841 NdisReleaseSpinLock(&pAd->MacTabLock);
1842
1843 // Let Link Status Page display first initial rate.
1844 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1845 // Select DAC according to HT or Legacy
1846 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1847 {
1848 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1849 Value &= (~0x18);
1850 if (pAd->Antenna.field.TxPath == 2)
1851 {
1852 Value |= 0x10;
1853 }
1854 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1855 }
1856 else
1857 {
1858 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1859 Value &= (~0x18);
1860 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1861 }
1862
1863#ifdef DOT11_N_SUPPORT
1864 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1865 {
1866 }
1867 else if (pEntry->MaxRAmpduFactor == 0)
1868 {
1869 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1870 // Because our Init value is 1 at MACRegTable.
1871 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1872 }
1873#endif // DOT11_N_SUPPORT //
1874
1875 // Patch for Marvel AP to gain high throughput
1876 // Need to set as following,
1877 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1878 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1879 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1880 // 4. kick per two packets when dequeue
1881 //
1882 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1883 //
1884 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1885#ifdef DOT11_N_SUPPORT
1886 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1887 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1888 {
1889 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1890 Data &= 0xFFFFFF00;
1891 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1892
1893 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1894 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1895 }
1896 else
1897#endif // DOT11_N_SUPPORT //
1898 if (pAd->CommonCfg.bEnableTxBurst)
1899 {
1900 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1901 Data &= 0xFFFFFF00;
1902 Data |= 0x60;
1903 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1904 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1905
1906 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1907 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1908 }
1909 else
1910 {
1911 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1912 Data &= 0xFFFFFF00;
1913 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1914
1915 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1916 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1917 }
1918
1919#ifdef DOT11_N_SUPPORT
1920 // Re-check to turn on TX burst or not.
1921 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1922 {
1923 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1924 if (pAd->CommonCfg.bEnableTxBurst)
1925 {
1926 UINT32 MACValue = 0;
1927 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1928 // I didn't change PBF_MAX_PCNT setting.
1929 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1930 MACValue &= 0xFFFFFF00;
1931 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1932 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1933 }
1934 }
1935 else
1936 {
1937 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1938 }
1939#endif // DOT11_N_SUPPORT //
1940
1941 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1942 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1943 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1944 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1945 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1946 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1947
1948 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1949 {
1950 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1951 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1952 }
1953
1954 NdisAcquireSpinLock(&pAd->MacTabLock);
1955 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1956 NdisReleaseSpinLock(&pAd->MacTabLock);
1957
1958 //
1959 // Patch Atheros AP TX will breakdown issue.
1960 // AP Model: DLink DWL-8200AP
1961 //
1962 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1963 {
1964 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1965 }
1966 else
1967 {
1968 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1969 }
1970
1971 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1972
1973
1974#ifdef DOT11_N_SUPPORT
1975#ifdef DOT11N_DRAFT3
1976 if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
1977 {
1978 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
1979 BuildEffectedChannelList(pAd);
1980 }
1981#endif // DOT11N_DRAFT3 //
1982#endif // DOT11_N_SUPPORT //
1983}
1984
1985/*
1986 ==========================================================================
1987
1988 Routine Description:
1989 Disconnect current BSSID
1990
1991 Arguments:
1992 pAd - Pointer to our adapter
1993 IsReqFromAP - Request from AP
1994
1995 Return Value:
1996 None
1997
1998 IRQL = DISPATCH_LEVEL
1999
2000 Note:
2001 We need more information to know it's this requst from AP.
2002 If yes! we need to do extra handling, for example, remove the WPA key.
2003 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
2004 remove while auto reconnect.
2005 Disconnect request from AP, it means we will start afresh 4-way handshaking
2006 on WPA mode.
2007
2008 ==========================================================================
2009*/
2010VOID LinkDown(
2011 IN PRTMP_ADAPTER pAd,
2012 IN BOOLEAN IsReqFromAP)
2013{
2014 UCHAR i, ByteValue = 0;
2015
2016 // Do nothing if monitor mode is on
2017 if (MONITOR_ON(pAd))
2018 return;
2019
2020#ifdef RALINK_ATE
2021 // Nothing to do in ATE mode.
2022 if (ATE_ON(pAd))
2023 return;
2024#endif // RALINK_ATE //
2025
2026 if (pAd->CommonCfg.bWirelessEvent)
2027 {
2028 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
2029 }
2030
2031 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
2032 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
2033
2034 if (ADHOC_ON(pAd)) // Adhoc mode link down
2035 {
2036 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
2037
2038 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
2039 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2040 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2041 RTMP_IndicateMediaState(pAd);
2042 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2043 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2044 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
2045 }
2046 else // Infra structure mode
2047 {
2048 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
2049
2050#ifdef QOS_DLS_SUPPORT
2051 // DLS tear down frame must be sent before link down
2052 // send DLS-TEAR_DOWN message
2053 if (pAd->CommonCfg.bDLSCapable)
2054 {
2055 // tear down local dls table entry
2056 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
2057 {
2058 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2059 {
2060 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2061 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2062 }
2063 }
2064
2065 // tear down peer dls table entry
2066 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
2067 {
2068 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2069 {
2070 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2071 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2072 }
2073 }
2074 }
2075#endif // QOS_DLS_SUPPORT //
2076
2077 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
2078 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2079
2080 // Saved last SSID for linkup comparison
2081 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
2082 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
2083 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
2084 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
2085 {
2086 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2087 RTMP_IndicateMediaState(pAd);
2088 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2089 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
2090 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
2091 }
2092 else
2093 {
2094 //
2095 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
2096 // Otherwise lost beacon or receive De-Authentication from AP,
2097 // then we should delete BSSID from BssTable.
2098 // If we don't delete from entry, roaming will fail.
2099 //
2100 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2101 }
2102
2103 // restore back to -
2104 // 1. long slot (20 us) or short slot (9 us) time
2105 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
2106 // 3. short preamble
2107 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
2108
2109 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
2110 {
2111 //
2112 // Record current AP's information.
2113 // for later used reporting Adjacent AP report.
2114 //
2115 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
2116 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
2117 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
2118 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
2119 }
2120
2121#ifdef EXT_BUILD_CHANNEL_LIST
2122 // Country IE of the AP will be evaluated and will be used.
2123 if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
2124 {
2125 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
2126 pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
2127 BuildChannelListEx(pAd);
2128 }
2129#endif // EXT_BUILD_CHANNEL_LIST //
2130
2131 }
2132
2133 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2134 {
2135 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2136 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
2137 }
2138
2139 pAd->StaCfg.CCXQosECWMin = 4;
2140 pAd->StaCfg.CCXQosECWMax = 10;
2141
2142 AsicSetSlotTime(pAd, TRUE); //FALSE);
2143 AsicSetEdcaParm(pAd, NULL);
2144
2145 // Set LED
2146 RTMPSetLED(pAd, LED_LINK_DOWN);
2147 pAd->LedIndicatorStregth = 0xF0;
2148 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
2149
2150 AsicDisableSync(pAd);
2151
2152 pAd->Mlme.PeriodicRound = 0;
2153 pAd->Mlme.OneSecPeriodicRound = 0;
2154
2155 if (pAd->StaCfg.BssType == BSS_INFRA)
2156 {
2157 // Remove StaCfg Information after link down
2158 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
2159 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
2160 pAd->CommonCfg.SsidLen = 0;
2161 }
2162#ifdef DOT11_N_SUPPORT
2163 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
2164 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
2165 pAd->MlmeAux.HtCapabilityLen = 0;
2166 pAd->MlmeAux.NewExtChannelOffset = 0xff;
2167#endif // DOT11_N_SUPPORT //
2168
2169 // Reset WPA-PSK state. Only reset when supplicant enabled
2170 if (pAd->StaCfg.WpaState != SS_NOTUSE)
2171 {
2172 pAd->StaCfg.WpaState = SS_START;
2173 // Clear Replay counter
2174 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2175
2176#ifdef QOS_DLS_SUPPORT
2177 if (pAd->CommonCfg.bDLSCapable)
2178 NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
2179#endif // QOS_DLS_SUPPORT //
2180 }
2181
2182
2183 //
2184 // if link down come from AP, we need to remove all WPA keys on WPA mode.
2185 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
2186 //
2187 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
2188 {
2189 // Remove all WPA keys
2190 RTMPWPARemoveAllKeys(pAd);
2191 }
2192
2193 // 802.1x port control
2194#ifdef WPA_SUPPLICANT_SUPPORT
2195 // Prevent clear PortSecured here with static WEP
2196 // NetworkManger set security policy first then set SSID to connect AP.
2197 if (pAd->StaCfg.WpaSupplicantUP &&
2198 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
2199 (pAd->StaCfg.IEEE8021X == FALSE))
2200 {
2201 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2202 }
2203 else
2204#endif // WPA_SUPPLICANT_SUPPORT //
2205 {
2206 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2207 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2208 }
2209
2210 NdisAcquireSpinLock(&pAd->MacTabLock);
2211 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2212 NdisReleaseSpinLock(&pAd->MacTabLock);
2213
2214 pAd->StaCfg.MicErrCnt = 0;
2215
2216 // Turn off Ckip control flag
2217 pAd->StaCfg.bCkipOn = FALSE;
2218 pAd->StaCfg.CCXEnable = FALSE;
2219
2220 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2221 // Update extra information to link is up
2222 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2223
2224 //pAd->StaCfg.AdhocBOnlyJoined = FALSE;
2225 //pAd->StaCfg.AdhocBGJoined = FALSE;
2226 //pAd->StaCfg.Adhoc20NJoined = FALSE;
2227 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2228
2229 // Reset the Current AP's IP address
2230 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
2231#ifdef RT2870
2232 pAd->bUsbTxBulkAggre = FALSE;
2233#endif // RT2870 //
2234
2235 // Clean association information
2236 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
2237 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
2238 pAd->StaCfg.ReqVarIELen = 0;
2239 pAd->StaCfg.ResVarIELen = 0;
2240
2241 //
2242 // Reset RSSI value after link down
2243 //
2244 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2245 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2246 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2247 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2248 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2249 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2250
2251 // Restore MlmeRate
2252 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2253 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2254
2255#ifdef DOT11_N_SUPPORT
2256 //
2257 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
2258 //
2259 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
2260 {
2261 pAd->CommonCfg.BBPCurrentBW = BW_20;
2262 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2263 ByteValue &= (~0x18);
2264 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2265 }
2266#endif // DOT11_N_SUPPORT //
2267 // Reset DAC
2268 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2269 ByteValue &= (~0x18);
2270 if (pAd->Antenna.field.TxPath == 2)
2271 {
2272 ByteValue |= 0x10;
2273 }
2274 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2275
2276 RTMPSetPiggyBack(pAd,FALSE);
2277 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2278
2279#ifdef DOT11_N_SUPPORT
2280 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2281#endif // DOT11_N_SUPPORT //
2282
2283 // Restore all settings in the following.
2284 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2285 AsicDisableRDG(pAd);
2286 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2287 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2288
2289#ifdef DOT11_N_SUPPORT
2290#ifdef DOT11N_DRAFT3
2291 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
2292 pAd->CommonCfg.BSSCoexist2040.word = 0;
2293 TriEventInit(pAd);
2294 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
2295 {
2296 pAd->ChannelList[i].bEffectedChannel = FALSE;
2297 }
2298#endif // DOT11N_DRAFT3 //
2299#endif // DOT11_N_SUPPORT //
2300
2301 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2302 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2303
2304#ifdef WPA_SUPPLICANT_SUPPORT
2305#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2306 if (pAd->StaCfg.WpaSupplicantUP) {
2307 union iwreq_data wrqu;
2308 //send disassociate event to wpa_supplicant
2309 memset(&wrqu, 0, sizeof(wrqu));
2310 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2311 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2312 }
2313#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2314#endif // WPA_SUPPLICANT_SUPPORT //
2315
2316#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2317 {
2318 union iwreq_data wrqu;
2319 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2320 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2321 }
2322#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2323}
2324
2325/*
2326 ==========================================================================
2327 Description:
2328
2329 IRQL = DISPATCH_LEVEL
2330
2331 ==========================================================================
2332*/
2333VOID IterateOnBssTab(
2334 IN PRTMP_ADAPTER pAd)
2335{
2336 MLME_START_REQ_STRUCT StartReq;
2337 MLME_JOIN_REQ_STRUCT JoinReq;
2338 ULONG BssIdx;
2339
2340 // Change the wepstatus to original wepstatus
2341 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2342 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2343 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2344
2345 BssIdx = pAd->MlmeAux.BssIdx;
2346 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2347 {
2348 // Check cipher suite, AP must have more secured cipher than station setting
2349 // Set the Pairwise and Group cipher to match the intended AP setting
2350 // We can only connect to AP with less secured cipher setting
2351 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2352 {
2353 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2354
2355 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2356 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2357 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2358 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2359 else // There is no PairCipher Aux, downgrade our capability to TKIP
2360 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2361 }
2362 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2363 {
2364 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2365
2366 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2367 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2368 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2369 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2370 else // There is no PairCipher Aux, downgrade our capability to TKIP
2371 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2372
2373 // RSN capability
2374 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2375 }
2376
2377 // Set Mix cipher flag
2378 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2379 if (pAd->StaCfg.bMixCipher == TRUE)
2380 {
2381 // If mix cipher, re-build RSNIE
2382 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2383 }
2384
2385 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2386 JoinParmFill(pAd, &JoinReq, BssIdx);
2387 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2388 &JoinReq);
2389 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2390 }
2391 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2392 {
2393 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2394 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2395 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2396 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2397 }
2398 else // no more BSS
2399 {
2400 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2401 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2402 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2403 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2404 }
2405}
2406
2407// for re-association only
2408// IRQL = DISPATCH_LEVEL
2409VOID IterateOnBssTab2(
2410 IN PRTMP_ADAPTER pAd)
2411{
2412 MLME_REASSOC_REQ_STRUCT ReassocReq;
2413 ULONG BssIdx;
2414 BSS_ENTRY *pBss;
2415
2416 BssIdx = pAd->MlmeAux.RoamIdx;
2417 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2418
2419 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2420 {
2421 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2422
2423 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2424 AsicLockChannel(pAd, pBss->Channel);
2425
2426 // reassociate message has the same structure as associate message
2427 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2428 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2429 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2430 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2431
2432 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2433 }
2434 else // no more BSS
2435 {
2436 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2437 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2438 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2439 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2440 }
2441}
2442
2443/*
2444 ==========================================================================
2445 Description:
2446
2447 IRQL = DISPATCH_LEVEL
2448
2449 ==========================================================================
2450*/
2451VOID JoinParmFill(
2452 IN PRTMP_ADAPTER pAd,
2453 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2454 IN ULONG BssIdx)
2455{
2456 JoinReq->BssIdx = BssIdx;
2457}
2458
2459/*
2460 ==========================================================================
2461 Description:
2462
2463 IRQL = DISPATCH_LEVEL
2464
2465 ==========================================================================
2466*/
2467VOID ScanParmFill(
2468 IN PRTMP_ADAPTER pAd,
2469 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2470 IN CHAR Ssid[],
2471 IN UCHAR SsidLen,
2472 IN UCHAR BssType,
2473 IN UCHAR ScanType)
2474{
2475 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2476 ScanReq->SsidLen = SsidLen;
2477 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2478 ScanReq->BssType = BssType;
2479 ScanReq->ScanType = ScanType;
2480}
2481
2482#ifdef QOS_DLS_SUPPORT
2483/*
2484 ==========================================================================
2485 Description:
2486
2487 IRQL = DISPATCH_LEVEL
2488
2489 ==========================================================================
2490*/
2491VOID DlsParmFill(
2492 IN PRTMP_ADAPTER pAd,
2493 IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
2494 IN PRT_802_11_DLS pDls,
2495 IN USHORT reason)
2496{
2497 pDlsReq->pDLS = pDls;
2498 pDlsReq->Reason = reason;
2499}
2500#endif // QOS_DLS_SUPPORT //
2501
2502/*
2503 ==========================================================================
2504 Description:
2505
2506 IRQL = DISPATCH_LEVEL
2507
2508 ==========================================================================
2509*/
2510VOID StartParmFill(
2511 IN PRTMP_ADAPTER pAd,
2512 IN OUT MLME_START_REQ_STRUCT *StartReq,
2513 IN CHAR Ssid[],
2514 IN UCHAR SsidLen)
2515{
2516 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2517 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2518 StartReq->SsidLen = SsidLen;
2519}
2520
2521/*
2522 ==========================================================================
2523 Description:
2524
2525 IRQL = DISPATCH_LEVEL
2526
2527 ==========================================================================
2528*/
2529VOID AuthParmFill(
2530 IN PRTMP_ADAPTER pAd,
2531 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2532 IN PUCHAR pAddr,
2533 IN USHORT Alg)
2534{
2535 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2536 AuthReq->Alg = Alg;
2537 AuthReq->Timeout = AUTH_TIMEOUT;
2538}
2539
2540/*
2541 ==========================================================================
2542 Description:
2543
2544 IRQL = DISPATCH_LEVEL
2545
2546 ==========================================================================
2547 */
2548
2549
2550#ifdef RT2870
2551
2552VOID MlmeCntlConfirm(
2553 IN PRTMP_ADAPTER pAd,
2554 IN ULONG MsgType,
2555 IN USHORT Msg)
2556{
2557 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
2558}
2559
2560VOID ComposePsPoll(
2561 IN PRTMP_ADAPTER pAd)
2562{
2563 PTXINFO_STRUC pTxInfo;
2564 PTXWI_STRUC pTxWI;
2565
2566 DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
2567 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2568
2569 pAd->PsPollFrame.FC.PwrMgmt = 0;
2570 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2571 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2572 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2573 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2574 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2575
2576 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
2577 pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
2578 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2579 pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2580 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
2581 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2582 RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2583 // Append 4 extra zero bytes.
2584 pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
2585}
2586
2587// IRQL = DISPATCH_LEVEL
2588VOID ComposeNullFrame(
2589 IN PRTMP_ADAPTER pAd)
2590{
2591 PTXINFO_STRUC pTxInfo;
2592 PTXWI_STRUC pTxWI;
2593
2594 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2595 pAd->NullFrame.FC.Type = BTYPE_DATA;
2596 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2597 pAd->NullFrame.FC.ToDs = 1;
2598 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2599 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2600 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2601 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
2602 pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
2603 RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
2604 pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
2605 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
2606 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
2607 RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
2608 pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
2609}
2610#endif // RT2870 //
2611
2612
2613/*
2614 ==========================================================================
2615 Description:
2616 Pre-build a BEACON frame in the shared memory
2617
2618 IRQL = PASSIVE_LEVEL
2619 IRQL = DISPATCH_LEVEL
2620
2621 ==========================================================================
2622*/
2623ULONG MakeIbssBeacon(
2624 IN PRTMP_ADAPTER pAd)
2625{
2626 UCHAR DsLen = 1, IbssLen = 2;
2627 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2628 HEADER_802_11 BcnHdr;
2629 USHORT CapabilityInfo;
2630 LARGE_INTEGER FakeTimestamp;
2631 ULONG FrameLen = 0;
2632 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2633 CHAR *pBeaconFrame = pAd->BeaconBuf;
2634 BOOLEAN Privacy;
2635 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2636 UCHAR SupRateLen = 0;
2637 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2638 UCHAR ExtRateLen = 0;
2639 UCHAR RSNIe = IE_WPA;
2640
2641 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2642 {
2643 SupRate[0] = 0x82; // 1 mbps
2644 SupRate[1] = 0x84; // 2 mbps
2645 SupRate[2] = 0x8b; // 5.5 mbps
2646 SupRate[3] = 0x96; // 11 mbps
2647 SupRateLen = 4;
2648 ExtRateLen = 0;
2649 }
2650 else if (pAd->CommonCfg.Channel > 14)
2651 {
2652 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2653 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2654 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2655 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2656 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2657 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2658 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2659 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2660 SupRateLen = 8;
2661 ExtRateLen = 0;
2662
2663 //
2664 // Also Update MlmeRate & RtsRate for G only & A only
2665 //
2666 pAd->CommonCfg.MlmeRate = RATE_6;
2667 pAd->CommonCfg.RtsRate = RATE_6;
2668 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2669 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2670 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2671 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2672 }
2673 else
2674 {
2675 SupRate[0] = 0x82; // 1 mbps
2676 SupRate[1] = 0x84; // 2 mbps
2677 SupRate[2] = 0x8b; // 5.5 mbps
2678 SupRate[3] = 0x96; // 11 mbps
2679 SupRateLen = 4;
2680
2681 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2682 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2683 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2684 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2685 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2686 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2687 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2688 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2689 ExtRateLen = 8;
2690 }
2691
2692 pAd->StaActive.SupRateLen = SupRateLen;
2693 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2694 pAd->StaActive.ExtRateLen = ExtRateLen;
2695 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2696
2697 // compose IBSS beacon frame
2698 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2699 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2700 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2701 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2702 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2703
2704 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2705 sizeof(HEADER_802_11), &BcnHdr,
2706 TIMESTAMP_LEN, &FakeTimestamp,
2707 2, &pAd->CommonCfg.BeaconPeriod,
2708 2, &CapabilityInfo,
2709 1, &SsidIe,
2710 1, &pAd->CommonCfg.SsidLen,
2711 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2712 1, &SupRateIe,
2713 1, &SupRateLen,
2714 SupRateLen, SupRate,
2715 1, &DsIe,
2716 1, &DsLen,
2717 1, &pAd->CommonCfg.Channel,
2718 1, &IbssIe,
2719 1, &IbssLen,
2720 2, &pAd->StaActive.AtimWin,
2721 END_OF_ARGS);
2722
2723 // add ERP_IE and EXT_RAE IE of in 802.11g
2724 if (ExtRateLen)
2725 {
2726 ULONG tmp;
2727
2728 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2729 3, LocalErpIe,
2730 1, &ExtRateIe,
2731 1, &ExtRateLen,
2732 ExtRateLen, ExtRate,
2733 END_OF_ARGS);
2734 FrameLen += tmp;
2735 }
2736
2737 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2738 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2739 {
2740 ULONG tmp;
2741 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2742
2743 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2744 1, &RSNIe,
2745 1, &pAd->StaCfg.RSNIE_Len,
2746 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2747 END_OF_ARGS);
2748 FrameLen += tmp;
2749 }
2750
2751#ifdef DOT11_N_SUPPORT
2752 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2753 {
2754 ULONG TmpLen;
2755 UCHAR HtLen, HtLen1;
2756
2757#ifdef RT_BIG_ENDIAN
2758 HT_CAPABILITY_IE HtCapabilityTmp;
2759 ADD_HT_INFO_IE addHTInfoTmp;
2760 USHORT b2lTmp, b2lTmp2;
2761#endif
2762
2763 // add HT Capability IE
2764 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2765 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2766#ifndef RT_BIG_ENDIAN
2767 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2768 1, &HtCapIe,
2769 1, &HtLen,
2770 HtLen, &pAd->CommonCfg.HtCapability,
2771 1, &AddHtInfoIe,
2772 1, &HtLen1,
2773 HtLen1, &pAd->CommonCfg.AddHTInfo,
2774 END_OF_ARGS);
2775#else
2776 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2777 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2778 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2779
2780 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2781 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2782 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2783
2784 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2785 1, &HtCapIe,
2786 1, &HtLen,
2787 HtLen, &HtCapabilityTmp,
2788 1, &AddHtInfoIe,
2789 1, &HtLen1,
2790 HtLen1, &addHTInfoTmp,
2791 END_OF_ARGS);
2792#endif
2793 FrameLen += TmpLen;
2794 }
2795#endif // DOT11_N_SUPPORT //
2796
2797 //beacon use reserved WCID 0xff
2798 if (pAd->CommonCfg.Channel > 14)
2799 {
2800 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2801 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2802 }
2803 else
2804 {
2805 // Set to use 1Mbps for Adhoc beacon.
2806 HTTRANSMIT_SETTING Transmit;
2807 Transmit.word = 0;
2808 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2809 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2810 }
2811
2812#ifdef RT_BIG_ENDIAN
2813 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2814 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2815#endif
2816
2817 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2818 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));
2819 return FrameLen;
2820}
2821
2822
diff --git a/drivers/staging/rt2870/sta/dls.c b/drivers/staging/rt2870/sta/dls.c
new file mode 100644
index 00000000000..56bfbc33d6f
--- /dev/null
+++ b/drivers/staging/rt2870/sta/dls.c
@@ -0,0 +1,2210 @@
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 DBGPRINT(RT_DEBUG_OFF, ("DLS - PeerDlsReqAction() Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
364 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
365
366 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
367 {
368 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
369 }
370 else
371 {
372 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
373 pAd->MacTab.fAnyStationNonGF = TRUE;
374 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
375 }
376
377 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
378 {
379 pEntry->MaxHTPhyMode.field.BW= BW_40;
380 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
381 }
382 else
383 {
384 pEntry->MaxHTPhyMode.field.BW = BW_20;
385 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
386 pAd->MacTab.fAnyStation20Only = TRUE;
387 }
388
389 // find max fixed rate
390 for (ii=15; ii>=0; ii--)
391 {
392 j = ii/8;
393 bitmask = (1<<(ii-(j*8)));
394 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
395 {
396 pEntry->MaxHTPhyMode.field.MCS = ii;
397 break;
398 }
399 if (ii==0)
400 break;
401 }
402
403
404 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
405 {
406
407 printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
408 pAd->StaCfg.DesiredTransmitSetting.field.MCS);
409 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
410 {
411 // Fix MCS as HT Duplicated Mode
412 pEntry->MaxHTPhyMode.field.BW = 1;
413 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
414 pEntry->MaxHTPhyMode.field.STBC = 0;
415 pEntry->MaxHTPhyMode.field.ShortGI = 0;
416 pEntry->MaxHTPhyMode.field.MCS = 32;
417 }
418 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
419 {
420 // STA supports fixed MCS
421 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
422 }
423 }
424
425 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
426 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
427 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
428 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
429 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
430 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
431
432 if (HtCapability.HtCapInfo.ShortGIfor20)
433 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
434 if (HtCapability.HtCapInfo.ShortGIfor40)
435 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
436 if (HtCapability.HtCapInfo.TxSTBC)
437 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
438 if (HtCapability.HtCapInfo.RxSTBC)
439 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
440 if (HtCapability.ExtHtCapInfo.PlusHTC)
441 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
442 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
443 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
444 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
445 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
446
447 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
448 }
449#endif // DOT11_N_SUPPORT //
450
451 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
452 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
453 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
454
455 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
456 {
457 PUCHAR pTable;
458 UCHAR TableSize = 0;
459
460 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
461 pEntry->bAutoTxRateSwitch = TRUE;
462 }
463 else
464 {
465 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
466 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
467 pEntry->bAutoTxRateSwitch = FALSE;
468
469 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
470 }
471 pEntry->RateLen = SupportedRatesLen;
472
473 break;
474 }
475 }
476 }
477 StatusCode = MLME_SUCCESS;
478
479 // can not find in table, create a new one
480 if (i < 0)
481 {
482 StatusCode = MLME_QOS_UNSPECIFY;
483 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));
484 }
485 else
486 {
487 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n",
488 i, SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
489 }
490 }
491
492 ActHeaderInit(pAd, &DlsRspHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
493
494 // Build basic frame first
495 if (StatusCode == MLME_SUCCESS)
496 {
497 MakeOutgoingFrame(pOutBuffer, &FrameLen,
498 sizeof(HEADER_802_11), &DlsRspHdr,
499 1, &Category,
500 1, &Action,
501 2, &StatusCode,
502 6, SA,
503 6, pAd->CurrentAddress,
504 2, &pAd->StaActive.CapabilityInfo,
505 1, &SupRateIe,
506 1, &pAd->MlmeAux.SupRateLen,
507 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
508 END_OF_ARGS);
509
510 if (pAd->MlmeAux.ExtRateLen != 0)
511 {
512 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
513 1, &ExtRateIe,
514 1, &pAd->MlmeAux.ExtRateLen,
515 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
516 END_OF_ARGS);
517 FrameLen += tmp;
518 }
519
520#ifdef DOT11_N_SUPPORT
521 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
522 {
523 UCHAR HtLen;
524
525#ifdef RT_BIG_ENDIAN
526 HT_CAPABILITY_IE HtCapabilityTmp;
527#endif
528
529 // add HT Capability IE
530 HtLen = sizeof(HT_CAPABILITY_IE);
531#ifndef RT_BIG_ENDIAN
532 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
533 1, &HtCapIe,
534 1, &HtLen,
535 HtLen, &pAd->CommonCfg.HtCapability,
536 END_OF_ARGS);
537#else
538 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
539 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
540 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
541
542 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
543 1, &HtCapIe,
544 1, &HtLen,
545 HtLen, &HtCapabilityTmp,
546 END_OF_ARGS);
547#endif
548 FrameLen = FrameLen + tmp;
549 }
550#endif // DOT11_N_SUPPORT //
551
552 if (pDLS && (pDLS->Status != DLS_FINISH))
553 {
554 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
555 Timeout = DLS_TIMEOUT;
556 RTMPSetTimer(&pDLS->Timer, Timeout);
557 }
558 }
559 else
560 {
561 MakeOutgoingFrame(pOutBuffer, &FrameLen,
562 sizeof(HEADER_802_11), &DlsRspHdr,
563 1, &Category,
564 1, &Action,
565 2, &StatusCode,
566 6, SA,
567 6, pAd->CurrentAddress,
568 END_OF_ARGS);
569 }
570
571 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
572 MlmeFreeMemory(pAd, pOutBuffer);
573}
574
575/*
576 ==========================================================================
577 Description:
578
579 IRQL = DISPATCH_LEVEL
580
581 ==========================================================================
582 */
583VOID PeerDlsRspAction(
584 IN PRTMP_ADAPTER pAd,
585 IN MLME_QUEUE_ELEM *Elem)
586{
587 USHORT CapabilityInfo;
588 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
589 USHORT StatusCode;
590 SHORT i;
591 BOOLEAN TimerCancelled;
592 UCHAR MaxSupportedRateIn500Kbps = 0;
593 UCHAR SupportedRatesLen;
594 UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
595 UCHAR HtCapabilityLen;
596 HT_CAPABILITY_IE HtCapability;
597
598 if (!pAd->CommonCfg.bDLSCapable)
599 return;
600
601 if (!INFRA_ON(pAd))
602 return;
603
604 if (!PeerDlsRspSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode,
605 &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
606 return;
607
608 // supported rates array may not be sorted. sort it and find the maximum rate
609 for (i=0; i<SupportedRatesLen; i++)
610 {
611 if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
612 MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
613 }
614
615 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x with StatusCode=%d, CapabilityInfo=0x%x\n",
616 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode, CapabilityInfo));
617
618 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
619 {
620 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
621 {
622 if (StatusCode == MLME_SUCCESS)
623 {
624 MAC_TABLE_ENTRY *pEntry;
625 UCHAR MaxSupportedRate = RATE_11;
626
627 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
628
629 switch (MaxSupportedRateIn500Kbps)
630 {
631 case 108: MaxSupportedRate = RATE_54; break;
632 case 96: MaxSupportedRate = RATE_48; break;
633 case 72: MaxSupportedRate = RATE_36; break;
634 case 48: MaxSupportedRate = RATE_24; break;
635 case 36: MaxSupportedRate = RATE_18; break;
636 case 24: MaxSupportedRate = RATE_12; break;
637 case 18: MaxSupportedRate = RATE_9; break;
638 case 12: MaxSupportedRate = RATE_6; break;
639 case 22: MaxSupportedRate = RATE_11; break;
640 case 11: MaxSupportedRate = RATE_5_5; break;
641 case 4: MaxSupportedRate = RATE_2; break;
642 case 2: MaxSupportedRate = RATE_1; break;
643 default: MaxSupportedRate = RATE_11; break;
644 }
645
646 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
647
648 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
649 {
650 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
651 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
652 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
653 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
654 pEntry->HTPhyMode.field.MODE = MODE_CCK;
655 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
656 }
657 else
658 {
659 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
660 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
661 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
662 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
663 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
664 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
665 }
666
667 pEntry->MaxHTPhyMode.field.BW = BW_20;
668 pEntry->MinHTPhyMode.field.BW = BW_20;
669
670#ifdef DOT11_N_SUPPORT
671 pEntry->HTCapability.MCSSet[0] = 0;
672 pEntry->HTCapability.MCSSet[1] = 0;
673
674 // If this Entry supports 802.11n, upgrade to HT rate.
675 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
676 {
677 UCHAR j, bitmask; //k,bitmask;
678 CHAR ii;
679
680 DBGPRINT(RT_DEBUG_OFF, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
681 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
682
683 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
684 {
685 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
686 }
687 else
688 {
689 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
690 pAd->MacTab.fAnyStationNonGF = TRUE;
691 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
692 }
693
694 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
695 {
696 pEntry->MaxHTPhyMode.field.BW= BW_40;
697 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
698 }
699 else
700 {
701 pEntry->MaxHTPhyMode.field.BW = BW_20;
702 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
703 pAd->MacTab.fAnyStation20Only = TRUE;
704 }
705
706 // find max fixed rate
707 for (ii=15; ii>=0; ii--)
708 {
709 j = ii/8;
710 bitmask = (1<<(ii-(j*8)));
711 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
712 {
713 pEntry->MaxHTPhyMode.field.MCS = ii;
714 break;
715 }
716 if (ii==0)
717 break;
718 }
719
720 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
721 {
722 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
723 {
724 // Fix MCS as HT Duplicated Mode
725 pEntry->MaxHTPhyMode.field.BW = 1;
726 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
727 pEntry->MaxHTPhyMode.field.STBC = 0;
728 pEntry->MaxHTPhyMode.field.ShortGI = 0;
729 pEntry->MaxHTPhyMode.field.MCS = 32;
730 }
731 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
732 {
733 // STA supports fixed MCS
734 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
735 }
736 }
737
738 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
739 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
740 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
741 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
742 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
743 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
744
745 if (HtCapability.HtCapInfo.ShortGIfor20)
746 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
747 if (HtCapability.HtCapInfo.ShortGIfor40)
748 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
749 if (HtCapability.HtCapInfo.TxSTBC)
750 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
751 if (HtCapability.HtCapInfo.RxSTBC)
752 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
753 if (HtCapability.ExtHtCapInfo.PlusHTC)
754 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
755 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
756 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
757 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
758 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
759
760 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
761 }
762#endif // DOT11_N_SUPPORT //
763 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
764 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
765 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
766
767 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
768 {
769 PUCHAR pTable;
770 UCHAR TableSize = 0;
771
772 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
773 pEntry->bAutoTxRateSwitch = TRUE;
774 }
775 else
776 {
777 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
778 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
779 pEntry->bAutoTxRateSwitch = FALSE;
780
781 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
782 }
783 pEntry->RateLen = SupportedRatesLen;
784
785 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
786 {
787 // If support WPA or WPA2, start STAKey hand shake,
788 // If failed hand shake, just tear down peer DLS
789 if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
790 {
791 MLME_DLS_REQ_STRUCT MlmeDlsReq;
792 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
793
794 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
795 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
796 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
797 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
798 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
799 }
800 else
801 {
802 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
803 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
804 }
805 }
806 else
807 {
808 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
809 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
810 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]));
811 }
812
813 //initialize seq no for DLS frames.
814 pAd->StaCfg.DLSEntry[i].Sequence = 0;
815 if (HtCapabilityLen != 0)
816 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
817 else
818 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
819 }
820 else
821 {
822 // DLS setup procedure failed.
823 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
824 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
825 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
826 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
827 }
828 }
829 }
830
831 if (i >= MAX_NUM_OF_INIT_DLS_ENTRY)
832 {
833 DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() update timeout value \n"));
834 for (i=(MAX_NUM_OF_DLS_ENTRY-1); i>=MAX_NUM_OF_INIT_DLS_ENTRY; i--)
835 {
836 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
837 {
838 if (StatusCode == MLME_SUCCESS)
839 {
840 MAC_TABLE_ENTRY *pEntry;
841 UCHAR MaxSupportedRate = RATE_11;
842
843 pEntry = MacTableInsertDlsEntry(pAd, SA, i);
844
845 switch (MaxSupportedRateIn500Kbps)
846 {
847 case 108: MaxSupportedRate = RATE_54; break;
848 case 96: MaxSupportedRate = RATE_48; break;
849 case 72: MaxSupportedRate = RATE_36; break;
850 case 48: MaxSupportedRate = RATE_24; break;
851 case 36: MaxSupportedRate = RATE_18; break;
852 case 24: MaxSupportedRate = RATE_12; break;
853 case 18: MaxSupportedRate = RATE_9; break;
854 case 12: MaxSupportedRate = RATE_6; break;
855 case 22: MaxSupportedRate = RATE_11; break;
856 case 11: MaxSupportedRate = RATE_5_5; break;
857 case 4: MaxSupportedRate = RATE_2; break;
858 case 2: MaxSupportedRate = RATE_1; break;
859 default: MaxSupportedRate = RATE_11; break;
860 }
861
862 pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
863
864 if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
865 {
866 pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
867 pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
868 pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
869 pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
870 pEntry->HTPhyMode.field.MODE = MODE_CCK;
871 pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
872 }
873 else
874 {
875 pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
876 pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
877 pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
878 pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
879 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
880 pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
881 }
882
883 pEntry->MaxHTPhyMode.field.BW = BW_20;
884 pEntry->MinHTPhyMode.field.BW = BW_20;
885
886#ifdef DOT11_N_SUPPORT
887 pEntry->HTCapability.MCSSet[0] = 0;
888 pEntry->HTCapability.MCSSet[1] = 0;
889
890 // If this Entry supports 802.11n, upgrade to HT rate.
891 if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
892 {
893 UCHAR j, bitmask; //k,bitmask;
894 CHAR ii;
895
896 DBGPRINT(RT_DEBUG_OFF, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n",
897 SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
898
899 if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
900 {
901 pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
902 }
903 else
904 {
905 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
906 pAd->MacTab.fAnyStationNonGF = TRUE;
907 pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
908 }
909
910 if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
911 {
912 pEntry->MaxHTPhyMode.field.BW= BW_40;
913 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
914 }
915 else
916 {
917 pEntry->MaxHTPhyMode.field.BW = BW_20;
918 pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
919 pAd->MacTab.fAnyStation20Only = TRUE;
920 }
921
922 // find max fixed rate
923 for (ii=15; ii>=0; ii--)
924 {
925 j = ii/8;
926 bitmask = (1<<(ii-(j*8)));
927 if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
928 {
929 pEntry->MaxHTPhyMode.field.MCS = ii;
930 break;
931 }
932 if (ii==0)
933 break;
934 }
935
936 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
937 {
938 printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
939 pAd->StaCfg.DesiredTransmitSetting.field.MCS);
940 if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
941 {
942 // Fix MCS as HT Duplicated Mode
943 pEntry->MaxHTPhyMode.field.BW = 1;
944 pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
945 pEntry->MaxHTPhyMode.field.STBC = 0;
946 pEntry->MaxHTPhyMode.field.ShortGI = 0;
947 pEntry->MaxHTPhyMode.field.MCS = 32;
948 }
949 else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
950 {
951 // STA supports fixed MCS
952 pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
953 }
954 }
955
956 pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
957 pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
958 pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
959 pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
960 pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
961 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
962
963 if (HtCapability.HtCapInfo.ShortGIfor20)
964 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
965 if (HtCapability.HtCapInfo.ShortGIfor40)
966 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
967 if (HtCapability.HtCapInfo.TxSTBC)
968 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
969 if (HtCapability.HtCapInfo.RxSTBC)
970 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
971 if (HtCapability.ExtHtCapInfo.PlusHTC)
972 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
973 if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
974 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
975 if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
976 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
977
978 NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
979 }
980#endif // DOT11_N_SUPPORT //
981
982 pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
983 pEntry->CurrTxRate = pEntry->MaxSupportedRate;
984 CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
985
986 if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
987 {
988 PUCHAR pTable;
989 UCHAR TableSize = 0;
990
991 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
992 pEntry->bAutoTxRateSwitch = TRUE;
993 }
994 else
995 {
996 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
997 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
998 pEntry->bAutoTxRateSwitch = FALSE;
999
1000 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1001 }
1002 pEntry->RateLen = SupportedRatesLen;
1003
1004 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
1005 {
1006 // If support WPA or WPA2, start STAKey hand shake,
1007 // If failed hand shake, just tear down peer DLS
1008 if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
1009 {
1010 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1011 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1012
1013 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1014 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1015 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1016 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1017 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
1018 }
1019 else
1020 {
1021 pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
1022 DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
1023 }
1024 }
1025 else
1026 {
1027 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1028 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1029 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]));
1030 }
1031 pAd->StaCfg.DLSEntry[i].Sequence = 0;
1032 if (HtCapabilityLen != 0)
1033 pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
1034 else
1035 pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
1036 }
1037 else
1038 {
1039 // DLS setup procedure failed.
1040 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1041 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1042 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1043 DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
1044 }
1045 }
1046 }
1047 }
1048}
1049
1050/*
1051 ==========================================================================
1052 Description:
1053
1054 IRQL = DISPATCH_LEVEL
1055
1056 ==========================================================================
1057 */
1058VOID MlmeDlsTearDownAction(
1059 IN PRTMP_ADAPTER pAd,
1060 IN MLME_QUEUE_ELEM *Elem)
1061{
1062 PUCHAR pOutBuffer = NULL;
1063 NDIS_STATUS NStatus;
1064 ULONG FrameLen = 0;
1065 UCHAR Category = CATEGORY_DLS;
1066 UCHAR Action = ACTION_DLS_TEARDOWN;
1067 USHORT ReasonCode = REASON_QOS_UNSPECIFY;
1068 HEADER_802_11 DlsTearDownHdr;
1069 PRT_802_11_DLS pDLS;
1070 BOOLEAN TimerCancelled;
1071 UCHAR i;
1072
1073 if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode))
1074 return;
1075
1076 DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode));
1077
1078 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1079 if (NStatus != NDIS_STATUS_SUCCESS)
1080 {
1081 DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsTearDownAction() allocate memory failed \n"));
1082 return;
1083 }
1084
1085 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1086
1087 // Build basic frame first
1088 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1089 sizeof(HEADER_802_11), &DlsTearDownHdr,
1090 1, &Category,
1091 1, &Action,
1092 6, &pDLS->MacAddr,
1093 6, pAd->CurrentAddress,
1094 2, &ReasonCode,
1095 END_OF_ARGS);
1096
1097 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1098 MlmeFreeMemory(pAd, pOutBuffer);
1099 RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
1100
1101 // Remove key in local dls table entry
1102 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1103 {
1104 if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1105 {
1106 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1107 }
1108 }
1109
1110 // clear peer dls table entry
1111 for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++)
1112 {
1113 if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1114 {
1115 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1116 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1117 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1118 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1119 }
1120 }
1121}
1122
1123/*
1124 ==========================================================================
1125 Description:
1126
1127 IRQL = DISPATCH_LEVEL
1128
1129 ==========================================================================
1130 */
1131VOID PeerDlsTearDownAction(
1132 IN PRTMP_ADAPTER pAd,
1133 IN MLME_QUEUE_ELEM *Elem)
1134{
1135 UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
1136 USHORT ReasonCode;
1137 UINT i;
1138 BOOLEAN TimerCancelled;
1139
1140 if (!pAd->CommonCfg.bDLSCapable)
1141 return;
1142
1143 if (!INFRA_ON(pAd))
1144 return;
1145
1146 if (!PeerDlsTearDownSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode))
1147 return;
1148
1149 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));
1150
1151 // clear local dls table entry
1152 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1153 {
1154 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
1155 {
1156 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1157 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1158 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1159 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1160 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1161 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1162 }
1163 }
1164
1165 // clear peer dls table entry
1166 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1167 {
1168 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
1169 {
1170 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1171 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1172 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1173 //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1174 //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
1175 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1176 }
1177 }
1178}
1179
1180/*
1181 ==========================================================================
1182 Description:
1183
1184 IRQL = DISPATCH_LEVEL
1185
1186 ==========================================================================
1187 */
1188VOID RTMPCheckDLSTimeOut(
1189 IN PRTMP_ADAPTER pAd)
1190{
1191 ULONG i;
1192 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1193 USHORT reason = REASON_QOS_UNSPECIFY;
1194
1195 if (! pAd->CommonCfg.bDLSCapable)
1196 return;
1197
1198 if (! INFRA_ON(pAd))
1199 return;
1200
1201 // If timeout value is equaled to zero, it means always not be timeout.
1202
1203 // update local dls table entry
1204 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1205 {
1206 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1207 && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
1208 {
1209 pAd->StaCfg.DLSEntry[i].CountDownTimer --;
1210
1211 if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
1212 {
1213 reason = REASON_QOS_REQUEST_TIMEOUT;
1214 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1215 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1216 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1217 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1218 }
1219 }
1220 }
1221
1222 // update peer dls table entry
1223 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1224 {
1225 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1226 && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
1227 {
1228 pAd->StaCfg.DLSEntry[i].CountDownTimer --;
1229
1230 if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
1231 {
1232 reason = REASON_QOS_REQUEST_TIMEOUT;
1233 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1234 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1235 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1236 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1237 }
1238 }
1239 }
1240}
1241
1242/*
1243 ==========================================================================
1244 Description:
1245
1246 IRQL = DISPATCH_LEVEL
1247
1248 ==========================================================================
1249 */
1250BOOLEAN RTMPRcvFrameDLSCheck(
1251 IN PRTMP_ADAPTER pAd,
1252 IN PHEADER_802_11 pHeader,
1253 IN ULONG Len,
1254 IN PRT28XX_RXD_STRUC pRxD)
1255{
1256 ULONG i;
1257 BOOLEAN bFindEntry = FALSE;
1258 BOOLEAN bSTAKeyFrame = FALSE;
1259 PEAPOL_PACKET pEap;
1260 PUCHAR pProto, pAddr = NULL;
1261 PUCHAR pSTAKey = NULL;
1262 UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
1263 UCHAR Mic[16], OldMic[16];
1264 UCHAR digest[80];
1265 UCHAR DlsPTK[80];
1266 UCHAR temp[64];
1267 BOOLEAN TimerCancelled;
1268 CIPHER_KEY PairwiseKey;
1269
1270
1271 if (! pAd->CommonCfg.bDLSCapable)
1272 return bSTAKeyFrame;
1273
1274 if (! INFRA_ON(pAd))
1275 return bSTAKeyFrame;
1276
1277 if (! (pHeader->FC.SubType & 0x08))
1278 return bSTAKeyFrame;
1279
1280 if (Len < LENGTH_802_11 + 6 + 2 + 2)
1281 return bSTAKeyFrame;
1282
1283 pProto = (PUCHAR)pHeader + LENGTH_802_11 + 2 + 6; // QOS Control field , 0xAA 0xAA 0xAA 0x00 0x00 0x00
1284 pAddr = pHeader->Addr2;
1285
1286 // L2PAD bit on will pad 2 bytes at LLC
1287 if (pRxD->L2PAD)
1288 {
1289 pProto += 2;
1290 }
1291
1292 if (RTMPEqualMemory(EAPOL, pProto, 2) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1293 {
1294 pEap = (PEAPOL_PACKET) (pProto + 2);
1295
1296 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,
1297 (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16),
1298 pEap->KeyDesc.KeyInfo.KeyMic,
1299 pEap->KeyDesc.KeyInfo.Install,
1300 pEap->KeyDesc.KeyInfo.KeyAck,
1301 pEap->KeyDesc.KeyInfo.Secure,
1302 pEap->KeyDesc.KeyInfo.EKD_DL,
1303 pEap->KeyDesc.KeyInfo.Error,
1304 pEap->KeyDesc.KeyInfo.Request));
1305
1306 if ((Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16)) && pEap->KeyDesc.KeyInfo.KeyMic
1307 && pEap->KeyDesc.KeyInfo.Install && pEap->KeyDesc.KeyInfo.KeyAck && pEap->KeyDesc.KeyInfo.Secure
1308 && pEap->KeyDesc.KeyInfo.EKD_DL && !pEap->KeyDesc.KeyInfo.Error && !pEap->KeyDesc.KeyInfo.Request)
1309 {
1310 // First validate replay counter, only accept message with larger replay counter
1311 // Let equal pass, some AP start with all zero replay counter
1312 NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
1313 if ((RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
1314 (RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
1315 return bSTAKeyFrame;
1316
1317 //RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1318 RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1319 DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1320 pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
1321 pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
1322 pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
1323
1324 // put these code segment to get the replay counter
1325 if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
1326 return bSTAKeyFrame;
1327
1328 // Check MIC value
1329 // Save the MIC and replace with zero
1330 // use proprietary PTK
1331 NdisZeroMemory(temp, 64);
1332 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1333 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1334
1335 NdisMoveMemory(OldMic, pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1336 NdisZeroMemory(pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1337 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1338 {
1339 // AES
1340 HMAC_SHA1((PUCHAR) pEap, pEap->Body_Len[1] + 4, DlsPTK, LEN_EAP_MICK, digest);
1341 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1342 }
1343 else
1344 {
1345 hmac_md5(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, Mic);
1346 }
1347
1348 if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
1349 {
1350 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in Msg1 of STAKey handshake! \n"));
1351 return bSTAKeyFrame;
1352 }
1353 else
1354 DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in Msg1 of STAKey handshake! \n"));
1355#if 1
1356 if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0C)
1357 && (pEap->KeyDesc.KeyData[4] == 0x43) && (pEap->KeyDesc.KeyData[5] == 0x02))
1358 {
1359 pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
1360 pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
1361
1362 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%ld, KeyDataLen=%d\n",
1363 pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
1364
1365 bSTAKeyFrame = TRUE;
1366 }
1367#else
1368 if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0F)
1369 && (pEap->KeyDesc.KeyData[4] == 0xAC) && (pEap->KeyDesc.KeyData[5] == 0x02))
1370 {
1371 pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
1372 pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
1373
1374 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%d, KeyDataLen=%d\n",
1375 pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
1376
1377 bSTAKeyFrame = TRUE;
1378 }
1379#endif
1380
1381 }
1382 else if (Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE))
1383 {
1384#if 0
1385 RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1386
1387#endif
1388 RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1389 DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
1390 pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
1391 pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
1392 pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
1393
1394 }
1395 }
1396
1397 // If timeout value is equaled to zero, it means always not be timeout.
1398 // update local dls table entry
1399 for (i= 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1400 {
1401 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1402 {
1403 if (bSTAKeyFrame)
1404 {
1405 PMAC_TABLE_ENTRY pEntry;
1406
1407 // STAKey frame, add pairwise key table
1408 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1409 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1410
1411 PairwiseKey.KeyLen = LEN_TKIP_EK;
1412 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1413 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1414 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1415
1416 PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1417
1418 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1419 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1420 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1421 // Add Pair-wise key to Asic
1422#ifdef RT2870
1423 {
1424 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1425 COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
1426 KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
1427 NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY));
1428 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
1429 }
1430 {
1431 PMAC_TABLE_ENTRY pDLSEntry;
1432 pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1433 pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
1434 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
1435 }
1436#endif // RT2870 //
1437 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1438 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
1439
1440 RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
1441
1442 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
1443 }
1444 else
1445 {
1446 // Data frame, update timeout value
1447 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1448 {
1449 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1450 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1451 }
1452 }
1453
1454 bFindEntry = TRUE;
1455 }
1456 }
1457
1458 // update peer dls table entry
1459 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1460 {
1461 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1462 {
1463 if (bSTAKeyFrame)
1464 {
1465 PMAC_TABLE_ENTRY pEntry = NULL;
1466
1467 // STAKey frame, add pairwise key table, and send STAkey Msg-2
1468 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1469 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1470
1471 PairwiseKey.KeyLen = LEN_TKIP_EK;
1472 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1473 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1474 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1475
1476 PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1477
1478 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1479 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1480 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1481 // Add Pair-wise key to Asic
1482#ifdef RT2870
1483 {
1484 RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
1485 COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
1486 KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
1487 NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY));
1488 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
1489 }
1490 {
1491 PMAC_TABLE_ENTRY pDLSEntry;
1492 pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1493 pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
1494 RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
1495 }
1496#endif // RT2870 //
1497 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1498 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
1499
1500 // If support WPA or WPA2, start STAKey hand shake,
1501 // If failed hand shake, just tear down peer DLS
1502 if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS)
1503 {
1504 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1505 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1506
1507 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1508 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1509 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1510 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1511 }
1512 else
1513 {
1514 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
1515 }
1516 }
1517 else
1518 {
1519 // Data frame, update timeout value
1520 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1521 {
1522 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1523 }
1524 }
1525
1526 bFindEntry = TRUE;
1527 }
1528 }
1529
1530
1531 return bSTAKeyFrame;
1532}
1533
1534/*
1535 ========================================================================
1536
1537 Routine Description:
1538 Check if the frame can be sent through DLS direct link interface
1539
1540 Arguments:
1541 pAd Pointer to adapter
1542
1543 Return Value:
1544 DLS entry index
1545
1546 Note:
1547
1548 ========================================================================
1549*/
1550INT RTMPCheckDLSFrame(
1551 IN PRTMP_ADAPTER pAd,
1552 IN PUCHAR pDA)
1553{
1554 INT rval = -1;
1555 INT i;
1556
1557 if (!pAd->CommonCfg.bDLSCapable)
1558 return rval;
1559
1560 if (!INFRA_ON(pAd))
1561 return rval;
1562
1563 do{
1564 // check local dls table entry
1565 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1566 {
1567 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1568 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1569 {
1570 rval = i;
1571 break;
1572 }
1573 }
1574
1575 // check peer dls table entry
1576 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1577 {
1578 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1579 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1580 {
1581 rval = i;
1582 break;
1583 }
1584 }
1585 } while (FALSE);
1586
1587 return rval;
1588}
1589
1590/*
1591 ==========================================================================
1592 Description:
1593
1594 IRQL = DISPATCH_LEVEL
1595
1596 ==========================================================================
1597 */
1598VOID RTMPSendDLSTearDownFrame(
1599 IN PRTMP_ADAPTER pAd,
1600 IN PUCHAR pDA)
1601{
1602 PUCHAR pOutBuffer = NULL;
1603 NDIS_STATUS NStatus;
1604 HEADER_802_11 DlsTearDownHdr;
1605 ULONG FrameLen = 0;
1606 USHORT Reason = REASON_QOS_QSTA_LEAVING_QBSS;
1607 UCHAR Category = CATEGORY_DLS;
1608 UCHAR Action = ACTION_DLS_TEARDOWN;
1609 UCHAR i = 0;
1610
1611 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
1612 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
1613 return;
1614
1615 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
1616
1617 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1618 if (NStatus != NDIS_STATUS_SUCCESS)
1619 {
1620 DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
1621 return;
1622 }
1623
1624 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1625 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1626 sizeof(HEADER_802_11), &DlsTearDownHdr,
1627 1, &Category,
1628 1, &Action,
1629 6, pDA,
1630 6, pAd->CurrentAddress,
1631 2, &Reason,
1632 END_OF_ARGS);
1633
1634 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1635 MlmeFreeMemory(pAd, pOutBuffer);
1636
1637 // Remove key in local dls table entry
1638 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1639 {
1640 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1641 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1642 {
1643 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1644 }
1645 }
1646
1647 // Remove key in peer dls table entry
1648 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1649 {
1650 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1651 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1652 {
1653 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1654 }
1655 }
1656
1657 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
1658}
1659
1660/*
1661 ==========================================================================
1662 Description:
1663
1664 IRQL = DISPATCH_LEVEL
1665
1666 ==========================================================================
1667 */
1668NDIS_STATUS RTMPSendSTAKeyRequest(
1669 IN PRTMP_ADAPTER pAd,
1670 IN PUCHAR pDA)
1671{
1672 UCHAR Header802_3[14];
1673 NDIS_STATUS NStatus;
1674 ULONG FrameLen = 0;
1675 EAPOL_PACKET Packet;
1676 UCHAR Mic[16];
1677 UCHAR digest[80];
1678 PUCHAR pOutBuffer = NULL;
1679 PNDIS_PACKET pNdisPacket;
1680 UCHAR temp[64];
1681 UCHAR DlsPTK[80];
1682
1683 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]));
1684
1685 pAd->Sequence ++;
1686 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1687
1688 // Zero message body
1689 NdisZeroMemory(&Packet, sizeof(Packet));
1690 Packet.ProVer = EAPOL_VER;
1691 Packet.ProType = EAPOLKey;
1692 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE andPeer MAC address
1693
1694 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1695 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1696 {
1697 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1698 }
1699 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1700 {
1701 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1702 }
1703
1704 // Key descriptor version
1705 Packet.KeyDesc.KeyInfo.KeyDescVer =
1706 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1707
1708 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1709 Packet.KeyDesc.KeyInfo.Secure = 1;
1710 Packet.KeyDesc.KeyInfo.Request = 1;
1711
1712 Packet.KeyDesc.KeyDataLen[1] = 12;
1713
1714 // use our own OUI to distinguish proprietary with standard.
1715 Packet.KeyDesc.KeyData[0] = 0xDD;
1716 Packet.KeyDesc.KeyData[1] = 0x0A;
1717 Packet.KeyDesc.KeyData[2] = 0x00;
1718 Packet.KeyDesc.KeyData[3] = 0x0C;
1719 Packet.KeyDesc.KeyData[4] = 0x43;
1720 Packet.KeyDesc.KeyData[5] = 0x03;
1721 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1722
1723 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1724
1725 // Allocate buffer for transmitting message
1726 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1727 if (NStatus != NDIS_STATUS_SUCCESS)
1728 return NStatus;
1729
1730 // Prepare EAPOL frame for MIC calculation
1731 // Be careful, only EAPOL frame is counted for MIC calculation
1732 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1733 Packet.Body_Len[1] + 4, &Packet,
1734 END_OF_ARGS);
1735
1736 // use proprietary PTK
1737 NdisZeroMemory(temp, 64);
1738 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1739 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1740
1741 // calculate MIC
1742 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1743 {
1744 // AES
1745 NdisZeroMemory(digest, sizeof(digest));
1746 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1747 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1748 }
1749 else
1750 {
1751 NdisZeroMemory(Mic, sizeof(Mic));
1752 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1753 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1754 }
1755
1756 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1757 sizeof(Header802_3), Header802_3,
1758 Packet.Body_Len[1] + 4, &Packet,
1759 END_OF_ARGS);
1760
1761 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1762 if (NStatus == NDIS_STATUS_SUCCESS)
1763 {
1764 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1765 STASendPacket(pAd, pNdisPacket);
1766 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1767 }
1768
1769 MlmeFreeMemory(pAd, pOutBuffer);
1770
1771 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1772
1773 return NStatus;
1774}
1775
1776/*
1777 ==========================================================================
1778 Description:
1779
1780 IRQL = DISPATCH_LEVEL
1781
1782 ==========================================================================
1783 */
1784NDIS_STATUS RTMPSendSTAKeyHandShake(
1785 IN PRTMP_ADAPTER pAd,
1786 IN PUCHAR pDA)
1787{
1788 UCHAR Header802_3[14];
1789 NDIS_STATUS NStatus;
1790 ULONG FrameLen = 0;
1791 EAPOL_PACKET Packet;
1792 UCHAR Mic[16];
1793 UCHAR digest[80];
1794 PUCHAR pOutBuffer = NULL;
1795 PNDIS_PACKET pNdisPacket;
1796 UCHAR temp[64];
1797 UCHAR DlsPTK[80]; // Due to dirver can not get PTK, use proprietary PTK
1798
1799 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]));
1800
1801 pAd->Sequence ++;
1802 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1803
1804 // Zero message body
1805 NdisZeroMemory(&Packet, sizeof(Packet));
1806 Packet.ProVer = EAPOL_VER;
1807 Packet.ProType = EAPOLKey;
1808 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE and Peer MAC address
1809
1810 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1811 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1812 {
1813 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1814 }
1815 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1816 {
1817 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1818 }
1819
1820 // Key descriptor version
1821 Packet.KeyDesc.KeyInfo.KeyDescVer =
1822 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1823
1824 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1825 Packet.KeyDesc.KeyInfo.Secure = 1;
1826
1827 Packet.KeyDesc.KeyDataLen[1] = 12;
1828
1829 // use our own OUI to distinguish proprietary with standard.
1830 Packet.KeyDesc.KeyData[0] = 0xDD;
1831 Packet.KeyDesc.KeyData[1] = 0x0A;
1832 Packet.KeyDesc.KeyData[2] = 0x00;
1833 Packet.KeyDesc.KeyData[3] = 0x0C;
1834 Packet.KeyDesc.KeyData[4] = 0x43;
1835 Packet.KeyDesc.KeyData[5] = 0x03;
1836 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1837
1838 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1839
1840 // Allocate buffer for transmitting message
1841 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1842 if (NStatus != NDIS_STATUS_SUCCESS)
1843 return NStatus;
1844
1845 // Prepare EAPOL frame for MIC calculation
1846 // Be careful, only EAPOL frame is counted for MIC calculation
1847 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1848 Packet.Body_Len[1] + 4, &Packet,
1849 END_OF_ARGS);
1850
1851 // use proprietary PTK
1852 NdisZeroMemory(temp, 64);
1853 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1854 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1855
1856 // calculate MIC
1857 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1858 {
1859 // AES
1860 NdisZeroMemory(digest, sizeof(digest));
1861 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1862 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1863 }
1864 else
1865 {
1866 NdisZeroMemory(Mic, sizeof(Mic));
1867 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1868 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1869 }
1870
1871 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1872 sizeof(Header802_3), Header802_3,
1873 Packet.Body_Len[1] + 4, &Packet,
1874 END_OF_ARGS);
1875
1876 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1877 if (NStatus == NDIS_STATUS_SUCCESS)
1878 {
1879 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1880 STASendPacket(pAd, pNdisPacket);
1881 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1882 }
1883
1884 MlmeFreeMemory(pAd, pOutBuffer);
1885
1886 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1887
1888 return NStatus;
1889}
1890
1891VOID DlsTimeoutAction(
1892 IN PVOID SystemSpecific1,
1893 IN PVOID FunctionContext,
1894 IN PVOID SystemSpecific2,
1895 IN PVOID SystemSpecific3)
1896{
1897 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1898 USHORT reason;
1899 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)FunctionContext;
1900 PRTMP_ADAPTER pAd = pDLS->pAd;
1901
1902 DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
1903 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5]));
1904
1905 if ((pDLS) && (pDLS->Valid))
1906 {
1907 reason = REASON_QOS_REQUEST_TIMEOUT;
1908 pDLS->Valid = FALSE;
1909 pDLS->Status = DLS_NONE;
1910 DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason);
1911 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1912 RT28XX_MLME_HANDLER(pAd);
1913 }
1914}
1915
1916/*
1917================================================================
1918Description : because DLS and CLI share the same WCID table in ASIC.
1919Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE.
1920Also fills the pairwise key.
1921Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
1922from index MAX_AID_BA.
1923================================================================
1924*/
1925MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
1926 IN PRTMP_ADAPTER pAd,
1927 IN PUCHAR pAddr,
1928 IN UINT DlsEntryIdx)
1929{
1930 PMAC_TABLE_ENTRY pEntry = NULL;
1931
1932 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
1933 // if FULL, return
1934 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1935 return NULL;
1936
1937 do
1938 {
1939 if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
1940 break;
1941
1942 // allocate one MAC entry
1943 pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
1944 if (pEntry)
1945 {
1946 pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid;
1947 pEntry->MatchDlsEntryIdx = DlsEntryIdx;
1948 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1949 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1950 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1951
1952 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
1953
1954 // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
1955 if ((pEntry->ValidAsDls) && (pEntry->WepStatus == Ndis802_11WEPEnabled))
1956 {
1957 UCHAR KeyIdx = 0;
1958 UCHAR CipherAlg = 0;
1959
1960 KeyIdx = pAd->StaCfg.DefaultKeyId;
1961
1962 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1963
1964 RTMPAddWcidAttributeEntry(pAd,
1965 BSS0,
1966 pAd->StaCfg.DefaultKeyId,
1967 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1968 pEntry);
1969 }
1970
1971 break;
1972 }
1973 } while(FALSE);
1974
1975 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
1976
1977 return pEntry;
1978}
1979
1980
1981/*
1982 ==========================================================================
1983 Description:
1984 Delete all Mesh Entry in pAd->MacTab
1985 ==========================================================================
1986 */
1987BOOLEAN MacTableDeleteDlsEntry(
1988 IN PRTMP_ADAPTER pAd,
1989 IN USHORT wcid,
1990 IN PUCHAR pAddr)
1991{
1992 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
1993
1994 if (!VALID_WCID(wcid))
1995 return FALSE;
1996
1997 MacTableDeleteEntry(pAd, wcid, pAddr);
1998
1999 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
2000
2001 return TRUE;
2002}
2003
2004MAC_TABLE_ENTRY *DlsEntryTableLookup(
2005 IN PRTMP_ADAPTER pAd,
2006 IN PUCHAR pAddr,
2007 IN BOOLEAN bResetIdelCount)
2008{
2009 ULONG HashIdx;
2010 MAC_TABLE_ENTRY *pEntry = NULL;
2011
2012 RTMP_SEM_LOCK(&pAd->MacTabLock);
2013 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2014 pEntry = pAd->MacTab.Hash[HashIdx];
2015
2016 while (pEntry)
2017 {
2018 if ((pEntry->ValidAsDls == TRUE)
2019 && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2020 {
2021 if(bResetIdelCount)
2022 pEntry->NoDataIdleCount = 0;
2023 break;
2024 }
2025 else
2026 pEntry = pEntry->pNext;
2027 }
2028
2029 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2030 return pEntry;
2031}
2032
2033MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
2034 IN PRTMP_ADAPTER pAd,
2035 IN UCHAR wcid,
2036 IN PUCHAR pAddr,
2037 IN BOOLEAN bResetIdelCount)
2038{
2039 ULONG DLsIndex;
2040 PMAC_TABLE_ENTRY pCurEntry = NULL;
2041 PMAC_TABLE_ENTRY pEntry = NULL;
2042
2043 if (!VALID_WCID(wcid))
2044 return NULL;
2045
2046 RTMP_SEM_LOCK(&pAd->MacTabLock);
2047
2048 do
2049 {
2050 pCurEntry = &pAd->MacTab.Content[wcid];
2051
2052 DLsIndex = 0xff;
2053 if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
2054 {
2055 DLsIndex = pCurEntry->MatchDlsEntryIdx;
2056 }
2057
2058 if (DLsIndex == 0xff)
2059 break;
2060
2061 if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
2062 {
2063 if(bResetIdelCount)
2064 pCurEntry->NoDataIdleCount = 0;
2065 pEntry = pCurEntry;
2066 break;
2067 }
2068 } while(FALSE);
2069
2070 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2071
2072 return pEntry;
2073}
2074
2075INT Set_DlsEntryInfo_Display_Proc(
2076 IN PRTMP_ADAPTER pAd,
2077 IN PUCHAR arg)
2078{
2079 INT i;
2080
2081 printk("\n%-19s%-8s\n", "MAC", "TIMEOUT\n");
2082 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
2083 {
2084 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2085 {
2086 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[pAd->StaCfg.DLSEntry[i].MacTabMatchWCID];
2087
2088 printk("%02x:%02x:%02x:%02x:%02x:%02x ",
2089 pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2],
2090 pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5]);
2091 printk("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut);
2092
2093 printk("\n");
2094 printk("\n%-19s%-4s%-4s%-4s%-4s%-7s%-7s%-7s","MAC", "AID", "BSS", "PSM", "WMM", "RSSI0", "RSSI1", "RSSI2");
2095#ifdef DOT11_N_SUPPORT
2096 printk("%-8s%-10s%-6s%-6s%-6s%-6s", "MIMOPS", "PhMd", "BW", "MCS", "SGI", "STBC");
2097#endif // DOT11_N_SUPPORT //
2098 printk("\n%02X:%02X:%02X:%02X:%02X:%02X ",
2099 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2100 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
2101 printk("%-4d", (int)pEntry->Aid);
2102 printk("%-4d", (int)pEntry->apidx);
2103 printk("%-4d", (int)pEntry->PsMode);
2104 printk("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE));
2105 printk("%-7d", pEntry->RssiSample.AvgRssi0);
2106 printk("%-7d", pEntry->RssiSample.AvgRssi1);
2107 printk("%-7d", pEntry->RssiSample.AvgRssi2);
2108#ifdef DOT11_N_SUPPORT
2109 printk("%-8d", (int)pEntry->MmpsMode);
2110 printk("%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE));
2111 printk("%-6s", GetBW(pEntry->HTPhyMode.field.BW));
2112 printk("%-6d", pEntry->HTPhyMode.field.MCS);
2113 printk("%-6d", pEntry->HTPhyMode.field.ShortGI);
2114 printk("%-6d", pEntry->HTPhyMode.field.STBC);
2115#endif // DOT11_N_SUPPORT //
2116 printk("%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
2117 (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
2118 printk("\n");
2119
2120 }
2121 }
2122
2123 return TRUE;
2124}
2125
2126INT Set_DlsAddEntry_Proc(
2127 IN PRTMP_ADAPTER pAd,
2128 IN PUCHAR arg)
2129{
2130 UCHAR mac[MAC_ADDR_LEN];
2131 USHORT Timeout;
2132 char *token, sepValue[] = ":", DASH = '-';
2133 INT i;
2134 RT_802_11_DLS Dls;
2135
2136 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
2137 return FALSE;
2138
2139 token = strchr(arg, DASH);
2140 if ((token != NULL) && (strlen(token)>1))
2141 {
2142 Timeout = simple_strtol((token+1), 0, 10);
2143
2144 *token = '\0';
2145 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2146 {
2147 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2148 return FALSE;
2149 AtoH(token, (PUCHAR)(&mac[i]), 1);
2150 }
2151 if(i != 6)
2152 return FALSE;
2153
2154 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1],
2155 mac[2], mac[3], mac[4], mac[5], (int)Timeout);
2156
2157 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2158 Dls.TimeOut = Timeout;
2159 COPY_MAC_ADDR(Dls.MacAddr, mac);
2160 Dls.Valid = 1;
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
2171 return FALSE;
2172
2173}
2174
2175INT Set_DlsTearDownEntry_Proc(
2176 IN PRTMP_ADAPTER pAd,
2177 IN PUCHAR arg)
2178{
2179 UCHAR macAddr[MAC_ADDR_LEN];
2180 CHAR *value;
2181 INT i;
2182 RT_802_11_DLS Dls;
2183
2184 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
2185 return FALSE;
2186
2187 for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
2188 {
2189 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
2190 return FALSE; //Invalid
2191
2192 AtoH(value, &macAddr[i++], 2);
2193 }
2194
2195 printk("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1],
2196 macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
2197
2198 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2199 COPY_MAC_ADDR(Dls.MacAddr, macAddr);
2200 Dls.Valid = 0;
2201
2202 MlmeEnqueue(pAd,
2203 MLME_CNTL_STATE_MACHINE,
2204 RT_OID_802_11_SET_DLS_PARAM,
2205 sizeof(RT_802_11_DLS),
2206 &Dls);
2207
2208 return TRUE;
2209}
2210
diff --git a/drivers/staging/rt2870/sta/rtmp_data.c b/drivers/staging/rt2870/sta/rtmp_data.c
new file mode 100644
index 00000000000..9942ecaf5e2
--- /dev/null
+++ b/drivers/staging/rt2870/sta/rtmp_data.c
@@ -0,0 +1,2619 @@
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
42VOID STARxEAPOLFrameIndicate(
43 IN PRTMP_ADAPTER pAd,
44 IN MAC_TABLE_ENTRY *pEntry,
45 IN RX_BLK *pRxBlk,
46 IN UCHAR FromWhichBSSID)
47{
48 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
49 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
50 UCHAR *pTmpBuf;
51
52#ifdef WPA_SUPPLICANT_SUPPORT
53 if (pAd->StaCfg.WpaSupplicantUP)
54 {
55 // All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon)
56 // TBD : process fragmented EAPol frames
57 {
58 // In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable
59 if ( pAd->StaCfg.IEEE8021X == TRUE &&
60 (EAP_CODE_SUCCESS == WpaCheckEapCode(pAd, pRxBlk->pData, pRxBlk->DataSize, LENGTH_802_1_H)))
61 {
62 PUCHAR Key;
63 UCHAR CipherAlg;
64 int idx = 0;
65
66 DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n"));
67 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
68 STA_PORT_SECURED(pAd);
69
70 if (pAd->StaCfg.IEEE8021x_required_keys == FALSE)
71 {
72 idx = pAd->StaCfg.DesireSharedKeyId;
73 CipherAlg = pAd->StaCfg.DesireSharedKey[idx].CipherAlg;
74 Key = pAd->StaCfg.DesireSharedKey[idx].Key;
75
76 if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)
77 {
78#ifdef RT2870
79 union
80 {
81 char buf[sizeof(NDIS_802_11_WEP)+MAX_LEN_OF_KEY- 1];
82 NDIS_802_11_WEP keyinfo;
83 } WepKey;
84 int len;
85
86
87 NdisZeroMemory(&WepKey, sizeof(WepKey));
88 len =pAd->StaCfg.DesireSharedKey[idx].KeyLen;
89
90 NdisMoveMemory(WepKey.keyinfo.KeyMaterial,
91 pAd->StaCfg.DesireSharedKey[idx].Key,
92 pAd->StaCfg.DesireSharedKey[idx].KeyLen);
93
94 WepKey.keyinfo.KeyIndex = 0x80000000 + idx;
95 WepKey.keyinfo.KeyLength = len;
96 pAd->SharedKey[BSS0][idx].KeyLen =(UCHAR) (len <= 5 ? 5 : 13);
97
98 pAd->IndicateMediaState = NdisMediaStateConnected;
99 pAd->ExtraInfo = GENERAL_LINK_UP;
100 // need to enqueue cmd to thread
101 RTUSBEnqueueCmdFromNdis(pAd, OID_802_11_ADD_WEP, TRUE, &WepKey, sizeof(WepKey.keyinfo) + len - 1);
102#endif // RT2870 //
103 // For Preventing ShardKey Table is cleared by remove key procedure.
104 pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
105 pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
106 NdisMoveMemory(pAd->SharedKey[BSS0][idx].Key,
107 pAd->StaCfg.DesireSharedKey[idx].Key,
108 pAd->StaCfg.DesireSharedKey[idx].KeyLen);
109 }
110 }
111 }
112
113 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
114 return;
115 }
116 }
117 else
118#endif // WPA_SUPPLICANT_SUPPORT //
119 {
120 // Special DATA frame that has to pass to MLME
121 // 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process
122 // 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process
123 {
124 pTmpBuf = pRxBlk->pData - LENGTH_802_11;
125 NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
126 REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
127 DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! report EAPOL/AIRONET DATA to MLME (len=%d) !!!\n", pRxBlk->DataSize));
128 }
129 }
130
131 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
132 return;
133
134}
135
136VOID STARxDataFrameAnnounce(
137 IN PRTMP_ADAPTER pAd,
138 IN MAC_TABLE_ENTRY *pEntry,
139 IN RX_BLK *pRxBlk,
140 IN UCHAR FromWhichBSSID)
141{
142
143 // non-EAP frame
144 if (!RTMPCheckWPAframe(pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID))
145 {
146 {
147 // drop all non-EAP DATA frame before
148 // this client's Port-Access-Control is secured
149 if (pRxBlk->pHeader->FC.Wep)
150 {
151 // unsupported cipher suite
152 if (pAd->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
153 {
154 // release packet
155 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
156 return;
157 }
158 }
159 else
160 {
161 // encryption in-use but receive a non-EAPOL clear text frame, drop it
162 if ((pAd->StaCfg.WepStatus != Ndis802_11EncryptionDisabled) &&
163 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
164 {
165 // release packet
166 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
167 return;
168 }
169 }
170 }
171 RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
172 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK))
173 {
174 // Normal legacy, AMPDU or AMSDU
175 CmmRxnonRalinkFrameIndicate(pAd, pRxBlk, FromWhichBSSID);
176
177 }
178 else
179 {
180 // ARALINK
181 CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
182 }
183#ifdef QOS_DLS_SUPPORT
184 RX_BLK_CLEAR_FLAG(pRxBlk, fRX_DLS);
185#endif // QOS_DLS_SUPPORT //
186 }
187 else
188 {
189 RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
190#ifdef DOT11_N_SUPPORT
191 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
192 {
193 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
194 }
195 else
196#endif // DOT11_N_SUPPORT //
197 {
198 // Determin the destination of the EAP frame
199 // to WPA state machine or upper layer
200 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
201 }
202 }
203}
204
205
206// For TKIP frame, calculate the MIC value
207BOOLEAN STACheckTkipMICValue(
208 IN PRTMP_ADAPTER pAd,
209 IN MAC_TABLE_ENTRY *pEntry,
210 IN RX_BLK *pRxBlk)
211{
212 PHEADER_802_11 pHeader = pRxBlk->pHeader;
213 UCHAR *pData = pRxBlk->pData;
214 USHORT DataSize = pRxBlk->DataSize;
215 UCHAR UserPriority = pRxBlk->UserPriority;
216 PCIPHER_KEY pWpaKey;
217 UCHAR *pDA, *pSA;
218
219 pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];
220
221 pDA = pHeader->Addr1;
222 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA))
223 {
224 pSA = pHeader->Addr3;
225 }
226 else
227 {
228 pSA = pHeader->Addr2;
229 }
230
231 if (RTMPTkipCompareMICValue(pAd,
232 pData,
233 pDA,
234 pSA,
235 pWpaKey->RxMic,
236 UserPriority,
237 DataSize) == FALSE)
238 {
239 DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error 2\n"));
240
241#ifdef WPA_SUPPLICANT_SUPPORT
242 if (pAd->StaCfg.WpaSupplicantUP)
243 {
244 WpaSendMicFailureToWpaSupplicant(pAd, (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE);
245 }
246 else
247#endif // WPA_SUPPLICANT_SUPPORT //
248 {
249 RTMPReportMicError(pAd, pWpaKey);
250 }
251
252 // release packet
253 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
254 return FALSE;
255 }
256
257 return TRUE;
258}
259
260
261//
262// All Rx routines use RX_BLK structure to hande rx events
263// It is very important to build pRxBlk attributes
264// 1. pHeader pointer to 802.11 Header
265// 2. pData pointer to payload including LLC (just skip Header)
266// 3. set payload size including LLC to DataSize
267// 4. set some flags with RX_BLK_SET_FLAG()
268//
269VOID STAHandleRxDataFrame(
270 IN PRTMP_ADAPTER pAd,
271 IN RX_BLK *pRxBlk)
272{
273 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
274 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
275 PHEADER_802_11 pHeader = pRxBlk->pHeader;
276 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
277 BOOLEAN bFragment = FALSE;
278 MAC_TABLE_ENTRY *pEntry = NULL;
279 UCHAR FromWhichBSSID = BSS0;
280 UCHAR UserPriority = 0;
281
282 {
283 // before LINK UP, all DATA frames are rejected
284 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
285 {
286 // release packet
287 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
288 return;
289 }
290
291#ifdef QOS_DLS_SUPPORT
292 //if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
293 if (RTMPRcvFrameDLSCheck(pAd, pHeader, pRxWI->MPDUtotalByteCount, pRxD))
294 {
295 return;
296 }
297#endif // QOS_DLS_SUPPORT //
298
299 // Drop not my BSS frames
300 if (pRxD->MyBss == 0)
301 {
302 {
303 // release packet
304 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
305 return;
306 }
307 }
308
309 pAd->RalinkCounters.RxCountSinceLastNULL++;
310 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && (pHeader->FC.SubType & 0x08))
311 {
312 UCHAR *pData;
313 DBGPRINT(RT_DEBUG_TRACE,("bAPSDCapable\n"));
314
315 // Qos bit 4
316 pData = (PUCHAR)pHeader + LENGTH_802_11;
317 if ((*pData >> 4) & 0x01)
318 {
319 DBGPRINT(RT_DEBUG_TRACE,("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
320 pAd->CommonCfg.bInServicePeriod = FALSE;
321
322 // Force driver to fall into sleep mode when rcv EOSP frame
323 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
324 {
325 USHORT TbttNumToNextWakeUp;
326 USHORT NextDtim = pAd->StaCfg.DtimPeriod;
327 ULONG Now;
328
329 NdisGetSystemUpTime(&Now);
330 NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;
331
332 TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
333 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
334 TbttNumToNextWakeUp = NextDtim;
335
336 MlmeSetPsmBit(pAd, PWR_SAVE);
337 // if WMM-APSD is failed, try to disable following line
338 AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
339 }
340 }
341
342 if ((pHeader->FC.MoreData) && (pAd->CommonCfg.bInServicePeriod))
343 {
344 DBGPRINT(RT_DEBUG_TRACE,("Sending another trigger frame when More Data bit is set to 1\n"));
345 }
346 }
347
348 // Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame
349 if ((pHeader->FC.SubType & 0x04)) // bit 2 : no DATA
350 {
351 // release packet
352 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
353 return;
354 }
355
356 // Drop not my BSS frame (we can not only check the MyBss bit in RxD)
357#ifdef QOS_DLS_SUPPORT
358 if (!pAd->CommonCfg.bDLSCapable)
359 {
360#endif // QOS_DLS_SUPPORT //
361 if (INFRA_ON(pAd))
362 {
363 // Infrastructure mode, check address 2 for BSSID
364 if (!RTMPEqualMemory(&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6))
365 {
366 // Receive frame not my BSSID
367 // release packet
368 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
369 return;
370 }
371 }
372 else // Ad-Hoc mode or Not associated
373 {
374 // Ad-Hoc mode, check address 3 for BSSID
375 if (!RTMPEqualMemory(&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6))
376 {
377 // Receive frame not my BSSID
378 // release packet
379 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
380 return;
381 }
382 }
383#ifdef QOS_DLS_SUPPORT
384 }
385#endif // QOS_DLS_SUPPORT //
386
387 //
388 // find pEntry
389 //
390 if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE)
391 {
392 pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
393 }
394 else
395 {
396 // 1. release packet if infra mode
397 // 2. new a pEntry if ad-hoc mode
398 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
399 return;
400 }
401
402 // infra or ad-hoc
403 if (INFRA_ON(pAd))
404 {
405 RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
406#ifdef QOS_DLS_SUPPORT
407 if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
408 RX_BLK_SET_FLAG(pRxBlk, fRX_DLS);
409 else
410#endif // QOS_DLS_SUPPORT //
411 ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
412 }
413
414 // check Atheros Client
415 if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1) && (pHeader->FC.Retry ))
416 {
417 pEntry->bIAmBadAtheros = TRUE;
418 pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
419 pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
420 if (!STA_AES_ON(pAd))
421 {
422 AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE, FALSE);
423 }
424 }
425 }
426
427 pRxBlk->pData = (UCHAR *)pHeader;
428
429 //
430 // update RxBlk->pData, DataSize
431 // 802.11 Header, QOS, HTC, Hw Padding
432 //
433
434 // 1. skip 802.11 HEADER
435 {
436 pRxBlk->pData += LENGTH_802_11;
437 pRxBlk->DataSize -= LENGTH_802_11;
438 }
439
440 // 2. QOS
441 if (pHeader->FC.SubType & 0x08)
442 {
443 RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
444 UserPriority = *(pRxBlk->pData) & 0x0f;
445 // bit 7 in QoS Control field signals the HT A-MSDU format
446 if ((*pRxBlk->pData) & 0x80)
447 {
448 RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
449 }
450
451 // skip QOS contorl field
452 pRxBlk->pData += 2;
453 pRxBlk->DataSize -=2;
454 }
455 pRxBlk->UserPriority = UserPriority;
456
457 // 3. Order bit: A-Ralink or HTC+
458 if (pHeader->FC.Order)
459 {
460#ifdef AGGREGATION_SUPPORT
461 if ((pRxWI->PHYMODE <= MODE_OFDM) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
462 {
463 RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
464 }
465 else
466#endif
467 {
468#ifdef DOT11_N_SUPPORT
469 RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
470 // skip HTC contorl field
471 pRxBlk->pData += 4;
472 pRxBlk->DataSize -= 4;
473#endif // DOT11_N_SUPPORT //
474 }
475 }
476
477 // 4. skip HW padding
478 if (pRxD->L2PAD)
479 {
480 // just move pData pointer
481 // because DataSize excluding HW padding
482 RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
483 pRxBlk->pData += 2;
484 }
485
486#ifdef DOT11_N_SUPPORT
487 if (pRxD->BA)
488 {
489 RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
490 }
491#endif // DOT11_N_SUPPORT //
492
493
494 //
495 // Case I Process Broadcast & Multicast data frame
496 //
497 if (pRxD->Bcast || pRxD->Mcast)
498 {
499 INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
500
501 // Drop Mcast/Bcast frame with fragment bit on
502 if (pHeader->FC.MoreFrag)
503 {
504 // release packet
505 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
506 return;
507 }
508
509 // Filter out Bcast frame which AP relayed for us
510 if (pHeader->FC.FrDs && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress))
511 {
512 // release packet
513 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
514 return;
515 }
516
517 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
518 return;
519 }
520 else if (pRxD->U2M)
521 {
522 pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
523
524
525#ifdef QOS_DLS_SUPPORT
526 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_DLS))
527 {
528 MAC_TABLE_ENTRY *pDlsEntry = NULL;
529
530 pDlsEntry = DlsEntryTableLookupByWcid(pAd, pRxWI->WirelessCliID, pHeader->Addr2, TRUE);
531 if(pDlsEntry)
532 Update_Rssi_Sample(pAd, &pDlsEntry->RssiSample, pRxWI);
533 }
534 else
535#endif // QOS_DLS_SUPPORT //
536 if (ADHOC_ON(pAd))
537 {
538 pEntry = MacTableLookup(pAd, pHeader->Addr2);
539 if (pEntry)
540 Update_Rssi_Sample(pAd, &pEntry->RssiSample, pRxWI);
541 }
542
543
544 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
545
546 pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
547 pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
548
549 pAd->RalinkCounters.OneSecRxOkDataCnt++;
550
551
552 if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0)))
553 {
554 // re-assemble the fragmented packets
555 // return complete frame (pRxPacket) or NULL
556 bFragment = TRUE;
557 pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
558 }
559
560 if (pRxPacket)
561 {
562 pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
563
564 // process complete frame
565 if (bFragment && (pRxD->Decrypted) && (pEntry->WepStatus == Ndis802_11Encryption2Enabled))
566 {
567 // Minus MIC length
568 pRxBlk->DataSize -= 8;
569
570 // For TKIP frame, calculate the MIC value
571 if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) == FALSE)
572 {
573 return;
574 }
575 }
576
577 STARxDataFrameAnnounce(pAd, pEntry, pRxBlk, FromWhichBSSID);
578 return;
579 }
580 else
581 {
582 // just return
583 // because RTMPDeFragmentDataFrame() will release rx packet,
584 // if packet is fragmented
585 return;
586 }
587 }
588
589 ASSERT(0);
590 // release packet
591 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
592}
593
594VOID STAHandleRxMgmtFrame(
595 IN PRTMP_ADAPTER pAd,
596 IN RX_BLK *pRxBlk)
597{
598 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
599 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
600 PHEADER_802_11 pHeader = pRxBlk->pHeader;
601 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
602
603 do
604 {
605
606 // We should collect RSSI not only U2M data but also my beacon
607 if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2)))
608 {
609 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
610
611 pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
612 pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
613 }
614
615 // First check the size, it MUST not exceed the mlme queue size
616 if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE)
617 {
618 DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount));
619 break;
620 }
621
622 REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader, pRxWI->MPDUtotalByteCount,
623 pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
624 } while (FALSE);
625
626 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
627}
628
629VOID STAHandleRxControlFrame(
630 IN PRTMP_ADAPTER pAd,
631 IN RX_BLK *pRxBlk)
632{
633#ifdef DOT11_N_SUPPORT
634 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
635#endif // DOT11_N_SUPPORT //
636 PHEADER_802_11 pHeader = pRxBlk->pHeader;
637 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
638
639 switch (pHeader->FC.SubType)
640 {
641 case SUBTYPE_BLOCK_ACK_REQ:
642#ifdef DOT11_N_SUPPORT
643 {
644 CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, (pRxWI->MPDUtotalByteCount), (PFRAME_BA_REQ)pHeader);
645 }
646 break;
647#endif // DOT11_N_SUPPORT //
648 case SUBTYPE_BLOCK_ACK:
649 case SUBTYPE_ACK:
650 default:
651 break;
652 }
653
654 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
655}
656
657
658/*
659 ========================================================================
660
661 Routine Description:
662 Process RxDone interrupt, running in DPC level
663
664 Arguments:
665 pAd Pointer to our adapter
666
667 Return Value:
668 None
669
670 IRQL = DISPATCH_LEVEL
671
672 Note:
673 This routine has to maintain Rx ring read pointer.
674 Need to consider QOS DATA format when converting to 802.3
675 ========================================================================
676*/
677BOOLEAN STARxDoneInterruptHandle(
678 IN PRTMP_ADAPTER pAd,
679 IN BOOLEAN argc)
680{
681 NDIS_STATUS Status;
682 UINT32 RxProcessed, RxPending;
683 BOOLEAN bReschedule = FALSE;
684 RT28XX_RXD_STRUC *pRxD;
685 UCHAR *pData;
686 PRXWI_STRUC pRxWI;
687 PNDIS_PACKET pRxPacket;
688 PHEADER_802_11 pHeader;
689 RX_BLK RxCell;
690
691 RxProcessed = RxPending = 0;
692
693 // process whole rx ring
694 while (1)
695 {
696
697 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
698 fRTMP_ADAPTER_RESET_IN_PROGRESS |
699 fRTMP_ADAPTER_HALT_IN_PROGRESS |
700 fRTMP_ADAPTER_NIC_NOT_EXIST) ||
701 !RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_START_UP))
702 {
703 break;
704 }
705
706
707 RxProcessed ++; // test
708
709 // 1. allocate a new data packet into rx ring to replace received packet
710 // then processing the received packet
711 // 2. the callee must take charge of release of packet
712 // 3. As far as driver is concerned ,
713 // the rx packet must
714 // a. be indicated to upper layer or
715 // b. be released if it is discarded
716 pRxPacket = GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule, &RxPending);
717 if (pRxPacket == NULL)
718 {
719 // no more packet to process
720 break;
721 }
722
723 // get rx ring descriptor
724 pRxD = &(RxCell.RxD);
725 // get rx data buffer
726 pData = GET_OS_PKT_DATAPTR(pRxPacket);
727 pRxWI = (PRXWI_STRUC) pData;
728 pHeader = (PHEADER_802_11) (pData+RXWI_SIZE) ;
729
730#ifdef RT_BIG_ENDIAN
731 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, TRUE);
732 RTMPWIEndianChange((PUCHAR)pRxWI, TYPE_RXWI);
733#endif
734
735 // build RxCell
736 RxCell.pRxWI = pRxWI;
737 RxCell.pHeader = pHeader;
738 RxCell.pRxPacket = pRxPacket;
739 RxCell.pData = (UCHAR *) pHeader;
740 RxCell.DataSize = pRxWI->MPDUtotalByteCount;
741 RxCell.Flags = 0;
742
743 // Increase Total receive byte counter after real data received no mater any error or not
744 pAd->RalinkCounters.ReceivedByteCount += pRxWI->MPDUtotalByteCount;
745 pAd->RalinkCounters.RxCount ++;
746
747 INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
748
749 if (pRxWI->MPDUtotalByteCount < 14)
750 Status = NDIS_STATUS_FAILURE;
751
752 if (MONITOR_ON(pAd))
753 {
754 send_monitor_packets(pAd, &RxCell);
755 break;
756 }
757 /* RT2870 invokes STARxDoneInterruptHandle() in rtusb_bulk.c */
758#ifdef RALINK_ATE
759 if (ATE_ON(pAd))
760 {
761 pAd->ate.RxCntPerSec++;
762 ATESampleRssi(pAd, pRxWI);
763#ifdef RALINK_28xx_QA
764 if (pAd->ate.bQARxStart == TRUE)
765 {
766 /* (*pRxD) has been swapped in GetPacketFromRxRing() */
767 ATE_QA_Statistics(pAd, pRxWI, pRxD, pHeader);
768 }
769#endif // RALINK_28xx_QA //
770 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
771 continue;
772 }
773#endif // RALINK_ATE //
774
775 // Check for all RxD errors
776 Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
777
778 // Handle the received frame
779 if (Status == NDIS_STATUS_SUCCESS)
780 {
781 switch (pHeader->FC.Type)
782 {
783 // CASE I, receive a DATA frame
784 case BTYPE_DATA:
785 {
786 // process DATA frame
787 STAHandleRxDataFrame(pAd, &RxCell);
788 }
789 break;
790 // CASE II, receive a MGMT frame
791 case BTYPE_MGMT:
792 {
793 STAHandleRxMgmtFrame(pAd, &RxCell);
794 }
795 break;
796 // CASE III. receive a CNTL frame
797 case BTYPE_CNTL:
798 {
799 STAHandleRxControlFrame(pAd, &RxCell);
800 }
801 break;
802 // discard other type
803 default:
804 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
805 break;
806 }
807 }
808 else
809 {
810 pAd->Counters8023.RxErrors++;
811 // discard this frame
812 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
813 }
814 }
815
816 return bReschedule;
817}
818
819/*
820 ========================================================================
821
822 Routine Description:
823 Arguments:
824 pAd Pointer to our adapter
825
826 IRQL = DISPATCH_LEVEL
827
828 ========================================================================
829*/
830VOID RTMPHandleTwakeupInterrupt(
831 IN PRTMP_ADAPTER pAd)
832{
833 AsicForceWakeup(pAd, FALSE);
834}
835
836/*
837========================================================================
838Routine Description:
839 Early checking and OS-depened parsing for Tx packet send to our STA driver.
840
841Arguments:
842 NDIS_HANDLE MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd.
843 PPNDIS_PACKET ppPacketArray The packet array need to do transmission.
844 UINT NumberOfPackets Number of packet in packet array.
845
846Return Value:
847 NONE
848
849Note:
850 This function do early checking and classification for send-out packet.
851 You only can put OS-depened & STA related code in here.
852========================================================================
853*/
854VOID STASendPackets(
855 IN NDIS_HANDLE MiniportAdapterContext,
856 IN PPNDIS_PACKET ppPacketArray,
857 IN UINT NumberOfPackets)
858{
859 UINT Index;
860 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) MiniportAdapterContext;
861 PNDIS_PACKET pPacket;
862 BOOLEAN allowToSend = FALSE;
863
864
865 for (Index = 0; Index < NumberOfPackets; Index++)
866 {
867 pPacket = ppPacketArray[Index];
868
869 do
870 {
871 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
872 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
873 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
874 {
875 // Drop send request since hardware is in reset state
876 break;
877 }
878 else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd))
879 {
880 // Drop send request since there are no physical connection yet
881 break;
882 }
883 else
884 {
885 // Record that orignal packet source is from NDIS layer,so that
886 // later on driver knows how to release this NDIS PACKET
887#ifdef QOS_DLS_SUPPORT
888 MAC_TABLE_ENTRY *pEntry;
889 PUCHAR pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
890
891 pEntry = MacTableLookup(pAd, pSrcBufVA);
892 if (pEntry && (pEntry->ValidAsDls == TRUE))
893 {
894 RTMP_SET_PACKET_WCID(pPacket, pEntry->Aid);
895 }
896 else
897#endif // QOS_DLS_SUPPORT //
898 RTMP_SET_PACKET_WCID(pPacket, 0); // this field is useless when in STA mode
899 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
900 NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING);
901 pAd->RalinkCounters.PendingNdisPacketCount++;
902
903 allowToSend = TRUE;
904 }
905 } while(FALSE);
906
907 if (allowToSend == TRUE)
908 STASendPacket(pAd, pPacket);
909 else
910 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
911 }
912
913 // Dequeue outgoing frames from TxSwQueue[] and process it
914 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
915
916}
917
918
919/*
920========================================================================
921Routine Description:
922 This routine is used to do packet parsing and classification for Tx packet
923 to STA device, and it will en-queue packets to our TxSwQueue depends on AC
924 class.
925
926Arguments:
927 pAd Pointer to our adapter
928 pPacket Pointer to send packet
929
930Return Value:
931 NDIS_STATUS_SUCCESS If succes to queue the packet into TxSwQueue.
932 NDIS_STATUS_FAILURE If failed to do en-queue.
933
934Note:
935 You only can put OS-indepened & STA related code in here.
936========================================================================
937*/
938NDIS_STATUS STASendPacket(
939 IN PRTMP_ADAPTER pAd,
940 IN PNDIS_PACKET pPacket)
941{
942 PACKET_INFO PacketInfo;
943 PUCHAR pSrcBufVA;
944 UINT SrcBufLen;
945 UINT AllowFragSize;
946 UCHAR NumberOfFrag;
947// UCHAR RTSRequired;
948 UCHAR QueIdx, UserPriority;
949 MAC_TABLE_ENTRY *pEntry = NULL;
950 unsigned int IrqFlags;
951 UCHAR FlgIsIP = 0;
952 UCHAR Rate;
953
954 // Prepare packet information structure for buffer descriptor
955 // chained within a single NDIS packet.
956 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
957
958 if (pSrcBufVA == NULL)
959 {
960 DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> pSrcBufVA == NULL !!!SrcBufLen=%x\n",SrcBufLen));
961 // Resourece is low, system did not allocate virtual address
962 // return NDIS_STATUS_FAILURE directly to upper layer
963 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
964 return NDIS_STATUS_FAILURE;
965 }
966
967
968 if (SrcBufLen < 14)
969 {
970 DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> Ndis Packet buffer error !!!\n"));
971 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
972 return (NDIS_STATUS_FAILURE);
973 }
974
975 // In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry.
976 // Note multicast packets in adhoc also use BSSID_WCID index.
977 {
978 if(INFRA_ON(pAd))
979 {
980#ifdef QOS_DLS_SUPPORT
981 USHORT tmpWcid;
982
983 tmpWcid = RTMP_GET_PACKET_WCID(pPacket);
984 if (VALID_WCID(tmpWcid) &&
985 (pAd->MacTab.Content[tmpWcid].ValidAsDls== TRUE))
986 {
987 pEntry = &pAd->MacTab.Content[tmpWcid];
988 Rate = pAd->MacTab.Content[tmpWcid].CurrTxRate;
989 }
990 else
991#endif // QOS_DLS_SUPPORT //
992 {
993 pEntry = &pAd->MacTab.Content[BSSID_WCID];
994 RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
995 Rate = pAd->CommonCfg.TxRate;
996 }
997 }
998 else if (ADHOC_ON(pAd))
999 {
1000 if (*pSrcBufVA & 0x01)
1001 {
1002 RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
1003 pEntry = &pAd->MacTab.Content[MCAST_WCID];
1004 }
1005 else
1006 {
1007 pEntry = MacTableLookup(pAd, pSrcBufVA);
1008 }
1009 Rate = pAd->CommonCfg.TxRate;
1010 }
1011 }
1012
1013 if (!pEntry)
1014 {
1015 DBGPRINT(RT_DEBUG_ERROR,("STASendPacket->Cannot find pEntry(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n", PRINT_MAC(pSrcBufVA)));
1016 // Resourece is low, system did not allocate virtual address
1017 // return NDIS_STATUS_FAILURE directly to upper layer
1018 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1019 return NDIS_STATUS_FAILURE;
1020 }
1021
1022 if (ADHOC_ON(pAd)
1023 )
1024 {
1025 RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid);
1026 }
1027
1028 //
1029 // Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags.
1030 // Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL).
1031 RTMPCheckEtherType(pAd, pPacket);
1032
1033
1034
1035 //
1036 // WPA 802.1x secured port control - drop all non-802.1x frame before port secured
1037 //
1038 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1039 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1040 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
1041 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1042#ifdef WPA_SUPPLICANT_SUPPORT
1043 || (pAd->StaCfg.IEEE8021X == TRUE)
1044#endif // WPA_SUPPLICANT_SUPPORT //
1045#ifdef LEAP_SUPPORT
1046 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1047#endif // LEAP_SUPPORT //
1048 )
1049 && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAd->StaCfg.MicErrCnt >= 2))
1050 && (RTMP_GET_PACKET_EAPOL(pPacket)== FALSE)
1051 )
1052 {
1053 DBGPRINT(RT_DEBUG_TRACE,("STASendPacket --> Drop packet before port secured !!!\n"));
1054 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1055
1056 return (NDIS_STATUS_FAILURE);
1057 }
1058
1059
1060 // STEP 1. Decide number of fragments required to deliver this MSDU.
1061 // The estimation here is not very accurate because difficult to
1062 // take encryption overhead into consideration here. The result
1063 // "NumberOfFrag" is then just used to pre-check if enough free
1064 // TXD are available to hold this MSDU.
1065
1066
1067 if (*pSrcBufVA & 0x01) // fragmentation not allowed on multicast & broadcast
1068 NumberOfFrag = 1;
1069 else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
1070 NumberOfFrag = 1; // Aggregation overwhelms fragmentation
1071 else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
1072 NumberOfFrag = 1; // Aggregation overwhelms fragmentation
1073#ifdef DOT11_N_SUPPORT
1074 else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX) || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
1075 NumberOfFrag = 1; // MIMO RATE overwhelms fragmentation
1076#endif // DOT11_N_SUPPORT //
1077 else
1078 {
1079 // The calculated "NumberOfFrag" is a rough estimation because of various
1080 // encryption/encapsulation overhead not taken into consideration. This number is just
1081 // used to make sure enough free TXD are available before fragmentation takes place.
1082 // In case the actual required number of fragments of an NDIS packet
1083 // excceeds "NumberOfFrag"caculated here and not enough free TXD available, the
1084 // last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of
1085 // resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should
1086 // rarely happen and the penalty is just like a TX RETRY fail. Affordable.
1087
1088 AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
1089 NumberOfFrag = ((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;
1090 // To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size
1091 if (((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)
1092 {
1093 NumberOfFrag--;
1094 }
1095 }
1096
1097 // Save fragment number to Ndis packet reserved field
1098 RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
1099
1100
1101 // STEP 2. Check the requirement of RTS:
1102 // If multiple fragment required, RTS is required only for the first fragment
1103 // if the fragment size large than RTS threshold
1104 // For RT28xx, Let ASIC send RTS/CTS
1105 RTMP_SET_PACKET_RTS(pPacket, 0);
1106 RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
1107
1108 //
1109 // STEP 3. Traffic classification. outcome = <UserPriority, QueIdx>
1110 //
1111 UserPriority = 0;
1112 QueIdx = QID_AC_BE;
1113 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
1114 CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
1115 {
1116 USHORT Protocol;
1117 UCHAR LlcSnapLen = 0, Byte0, Byte1;
1118 do
1119 {
1120 // get Ethernet protocol field
1121 Protocol = (USHORT)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
1122 if (Protocol <= 1500)
1123 {
1124 // get Ethernet protocol field from LLC/SNAP
1125 if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + 6, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
1126 break;
1127
1128 Protocol = (USHORT)((Byte0 << 8) + Byte1);
1129 LlcSnapLen = 8;
1130 }
1131
1132 // always AC_BE for non-IP packet
1133 if (Protocol != 0x0800)
1134 break;
1135
1136 // get IP header
1137 if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
1138 break;
1139
1140 // return AC_BE if packet is not IPv4
1141 if ((Byte0 & 0xf0) != 0x40)
1142 break;
1143
1144 FlgIsIP = 1;
1145 UserPriority = (Byte1 & 0xe0) >> 5;
1146 QueIdx = MapUserPriorityToAccessCategory[UserPriority];
1147
1148 // TODO: have to check ACM bit. apply TSPEC if ACM is ON
1149 // TODO: downgrade UP & QueIdx before passing ACM
1150 if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx])
1151 {
1152 UserPriority = 0;
1153 QueIdx = QID_AC_BE;
1154 }
1155 } while (FALSE);
1156 }
1157
1158 RTMP_SET_PACKET_UP(pPacket, UserPriority);
1159
1160
1161
1162 // Make sure SendTxWait queue resource won't be used by other threads
1163 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
1164 if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE)
1165 {
1166 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1167#ifdef BLOCK_NET_IF
1168 StopNetIfQueue(pAd, QueIdx, pPacket);
1169#endif // BLOCK_NET_IF //
1170 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1171
1172 return NDIS_STATUS_FAILURE;
1173 }
1174 else
1175 {
1176 InsertTailQueue(&pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
1177 }
1178 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1179
1180#ifdef DOT11_N_SUPPORT
1181 if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE)&&
1182 IS_HT_STA(pEntry))
1183 {
1184 //PMAC_TABLE_ENTRY pMacEntry = &pAd->MacTab.Content[BSSID_WCID];
1185 if (((pEntry->TXBAbitmap & (1<<UserPriority)) == 0) &&
1186 ((pEntry->BADeclineBitmap & (1<<UserPriority)) == 0) &&
1187 (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
1188 // For IOT compatibility, if
1189 // 1. It is Ralink chip or
1190 // 2. It is OPEN or AES mode,
1191 // then BA session can be bulit.
1192 && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0) ||
1193 (pEntry->WepStatus == Ndis802_11WEPDisabled || pEntry->WepStatus == Ndis802_11Encryption3Enabled))
1194 )
1195 {
1196 BAOriSessionSetUp(pAd, pEntry, 0, 0, 10, FALSE);
1197 }
1198 }
1199#endif // DOT11_N_SUPPORT //
1200
1201 pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; // TODO: for debug only. to be removed
1202 return NDIS_STATUS_SUCCESS;
1203}
1204
1205
1206/*
1207 ========================================================================
1208
1209 Routine Description:
1210 This subroutine will scan through releative ring descriptor to find
1211 out avaliable free ring descriptor and compare with request size.
1212
1213 Arguments:
1214 pAd Pointer to our adapter
1215 QueIdx Selected TX Ring
1216
1217 Return Value:
1218 NDIS_STATUS_FAILURE Not enough free descriptor
1219 NDIS_STATUS_SUCCESS Enough free descriptor
1220
1221 IRQL = PASSIVE_LEVEL
1222 IRQL = DISPATCH_LEVEL
1223
1224 Note:
1225
1226 ========================================================================
1227*/
1228
1229#ifdef RT2870
1230/*
1231 Actually, this function used to check if the TxHardware Queue still has frame need to send.
1232 If no frame need to send, go to sleep, else, still wake up.
1233*/
1234NDIS_STATUS RTMPFreeTXDRequest(
1235 IN PRTMP_ADAPTER pAd,
1236 IN UCHAR QueIdx,
1237 IN UCHAR NumberRequired,
1238 IN PUCHAR FreeNumberIs)
1239{
1240 //ULONG FreeNumber = 0;
1241 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
1242 unsigned long IrqFlags;
1243 HT_TX_CONTEXT *pHTTXContext;
1244
1245 switch (QueIdx)
1246 {
1247 case QID_AC_BK:
1248 case QID_AC_BE:
1249 case QID_AC_VI:
1250 case QID_AC_VO:
1251 case QID_HCCA:
1252 {
1253 pHTTXContext = &pAd->TxContext[QueIdx];
1254 RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
1255 if ((pHTTXContext->CurWritePosition != pHTTXContext->ENextBulkOutPosition) ||
1256 (pHTTXContext->IRPPending == TRUE))
1257 {
1258 Status = NDIS_STATUS_FAILURE;
1259 }
1260 else
1261 {
1262 Status = NDIS_STATUS_SUCCESS;
1263 }
1264 RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
1265 }
1266 break;
1267
1268 case QID_MGMT:
1269 if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE)
1270 Status = NDIS_STATUS_FAILURE;
1271 else
1272 Status = NDIS_STATUS_SUCCESS;
1273 break;
1274
1275 default:
1276 DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
1277 break;
1278 }
1279
1280 return (Status);
1281
1282}
1283#endif // RT2870 //
1284
1285
1286VOID RTMPSendDisassociationFrame(
1287 IN PRTMP_ADAPTER pAd)
1288{
1289}
1290
1291VOID RTMPSendNullFrame(
1292 IN PRTMP_ADAPTER pAd,
1293 IN UCHAR TxRate,
1294 IN BOOLEAN bQosNull)
1295{
1296 UCHAR NullFrame[48];
1297 ULONG Length;
1298 PHEADER_802_11 pHeader_802_11;
1299
1300
1301#ifdef RALINK_ATE
1302 if(ATE_ON(pAd))
1303 {
1304 return;
1305 }
1306#endif // RALINK_ATE //
1307
1308 // WPA 802.1x secured port control
1309 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1310 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1311 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
1312 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1313#ifdef WPA_SUPPLICANT_SUPPORT
1314 || (pAd->StaCfg.IEEE8021X == TRUE)
1315#endif
1316 ) &&
1317 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1318 {
1319 return;
1320 }
1321
1322 NdisZeroMemory(NullFrame, 48);
1323 Length = sizeof(HEADER_802_11);
1324
1325 pHeader_802_11 = (PHEADER_802_11) NullFrame;
1326
1327 pHeader_802_11->FC.Type = BTYPE_DATA;
1328 pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
1329 pHeader_802_11->FC.ToDs = 1;
1330 COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
1331 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1332 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1333
1334 if (pAd->CommonCfg.bAPSDForcePowerSave)
1335 {
1336 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
1337 }
1338 else
1339 {
1340 pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE) ? 1: 0;
1341 }
1342 pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
1343
1344 pAd->Sequence++;
1345 pHeader_802_11->Sequence = pAd->Sequence;
1346
1347 // Prepare QosNull function frame
1348 if (bQosNull)
1349 {
1350 pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;
1351
1352 // copy QOS control bytes
1353 NullFrame[Length] = 0;
1354 NullFrame[Length+1] = 0;
1355 Length += 2;// if pad with 2 bytes for alignment, APSD will fail
1356 }
1357
1358 HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);
1359
1360}
1361
1362// IRQL = DISPATCH_LEVEL
1363VOID RTMPSendRTSFrame(
1364 IN PRTMP_ADAPTER pAd,
1365 IN PUCHAR pDA,
1366 IN unsigned int NextMpduSize,
1367 IN UCHAR TxRate,
1368 IN UCHAR RTSRate,
1369 IN USHORT AckDuration,
1370 IN UCHAR QueIdx,
1371 IN UCHAR FrameGap)
1372{
1373}
1374
1375
1376
1377// --------------------------------------------------------
1378// FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM
1379// Find the WPA key, either Group or Pairwise Key
1380// LEAP + TKIP also use WPA key.
1381// --------------------------------------------------------
1382// Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst
1383// In Cisco CCX 2.0 Leap Authentication
1384// WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey
1385// Instead of the SharedKey, SharedKey Length may be Zero.
1386VOID STAFindCipherAlgorithm(
1387 IN PRTMP_ADAPTER pAd,
1388 IN TX_BLK *pTxBlk)
1389{
1390 NDIS_802_11_ENCRYPTION_STATUS Cipher; // To indicate cipher used for this packet
1391 UCHAR CipherAlg = CIPHER_NONE; // cipher alogrithm
1392 UCHAR KeyIdx = 0xff;
1393 PUCHAR pSrcBufVA;
1394 PCIPHER_KEY pKey = NULL;
1395
1396 pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);
1397
1398 {
1399 // Select Cipher
1400 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
1401 Cipher = pAd->StaCfg.GroupCipher; // Cipher for Multicast or Broadcast
1402 else
1403 Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast
1404
1405 if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
1406 {
1407 ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <= CIPHER_CKIP128);
1408
1409 // 4-way handshaking frame must be clear
1410 if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) && (pAd->SharedKey[BSS0][0].CipherAlg) &&
1411 (pAd->SharedKey[BSS0][0].KeyLen))
1412 {
1413 CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
1414 KeyIdx = 0;
1415 }
1416 }
1417 else if (Cipher == Ndis802_11Encryption1Enabled)
1418 {
1419#ifdef LEAP_SUPPORT
1420 if (pAd->StaCfg.CkipFlag & 0x10) // Cisco CKIP KP is on
1421 {
1422 if (LEAP_CCKM_ON(pAd))
1423 {
1424 if (((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))))
1425 KeyIdx = 1;
1426 else
1427 KeyIdx = 0;
1428 }
1429 else
1430 KeyIdx = pAd->StaCfg.DefaultKeyId;
1431 }
1432 else if (pAd->StaCfg.CkipFlag & 0x08) // only CKIP CMIC
1433 KeyIdx = pAd->StaCfg.DefaultKeyId;
1434 else if (LEAP_CCKM_ON(pAd))
1435 {
1436 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
1437 KeyIdx = 1;
1438 else
1439 KeyIdx = 0;
1440 }
1441 else // standard WEP64 or WEP128
1442#endif // LEAP_SUPPORT //
1443 KeyIdx = pAd->StaCfg.DefaultKeyId;
1444 }
1445 else if ((Cipher == Ndis802_11Encryption2Enabled) ||
1446 (Cipher == Ndis802_11Encryption3Enabled))
1447 {
1448 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) // multicast
1449 KeyIdx = pAd->StaCfg.DefaultKeyId;
1450 else if (pAd->SharedKey[BSS0][0].KeyLen)
1451 KeyIdx = 0;
1452 else
1453 KeyIdx = pAd->StaCfg.DefaultKeyId;
1454 }
1455
1456 if (KeyIdx == 0xff)
1457 CipherAlg = CIPHER_NONE;
1458 else if ((Cipher == Ndis802_11EncryptionDisabled) || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
1459 CipherAlg = CIPHER_NONE;
1460#ifdef WPA_SUPPLICANT_SUPPORT
1461 else if ( pAd->StaCfg.WpaSupplicantUP &&
1462 (Cipher == Ndis802_11Encryption1Enabled) &&
1463 (pAd->StaCfg.IEEE8021X == TRUE) &&
1464 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1465 CipherAlg = CIPHER_NONE;
1466#endif // WPA_SUPPLICANT_SUPPORT //
1467 else
1468 {
1469 //Header_802_11.FC.Wep = 1;
1470 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1471 pKey = &pAd->SharedKey[BSS0][KeyIdx];
1472 }
1473 }
1474
1475 pTxBlk->CipherAlg = CipherAlg;
1476 pTxBlk->pKey = pKey;
1477}
1478
1479
1480VOID STABuildCommon802_11Header(
1481 IN PRTMP_ADAPTER pAd,
1482 IN TX_BLK *pTxBlk)
1483{
1484
1485 HEADER_802_11 *pHeader_802_11;
1486#ifdef QOS_DLS_SUPPORT
1487 BOOLEAN bDLSFrame = FALSE;
1488 INT DlsEntryIndex = 0;
1489#endif // QOS_DLS_SUPPORT //
1490
1491 //
1492 // MAKE A COMMON 802.11 HEADER
1493 //
1494
1495 // normal wlan header size : 24 octets
1496 pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
1497
1498 pHeader_802_11 = (HEADER_802_11 *) &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1499
1500 NdisZeroMemory(pHeader_802_11, sizeof(HEADER_802_11));
1501
1502 pHeader_802_11->FC.FrDs = 0;
1503 pHeader_802_11->FC.Type = BTYPE_DATA;
1504 pHeader_802_11->FC.SubType = ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : SUBTYPE_DATA);
1505
1506#ifdef QOS_DLS_SUPPORT
1507 if (INFRA_ON(pAd))
1508 {
1509 // Check if the frame can be sent through DLS direct link interface
1510 // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
1511 DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
1512 if (DlsEntryIndex >= 0)
1513 bDLSFrame = TRUE;
1514 else
1515 bDLSFrame = FALSE;
1516 }
1517#endif // QOS_DLS_SUPPORT //
1518
1519 if (pTxBlk->pMacEntry)
1520 {
1521 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS))
1522 {
1523 pHeader_802_11->Sequence = pTxBlk->pMacEntry->NonQosDataSeq;
1524 pTxBlk->pMacEntry->NonQosDataSeq = (pTxBlk->pMacEntry->NonQosDataSeq+1) & MAXSEQ;
1525 }
1526 else
1527 {
1528 pHeader_802_11->Sequence = pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority];
1529 pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
1530 }
1531 }
1532 else
1533 {
1534 pHeader_802_11->Sequence = pAd->Sequence;
1535 pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; // next sequence
1536 }
1537
1538 pHeader_802_11->Frag = 0;
1539
1540 pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
1541
1542 {
1543 if (INFRA_ON(pAd))
1544 {
1545#ifdef QOS_DLS_SUPPORT
1546 if (bDLSFrame)
1547 {
1548 COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
1549 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1550 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1551 pHeader_802_11->FC.ToDs = 0;
1552 }
1553 else
1554#endif // QOS_DLS_SUPPORT //
1555 {
1556 COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
1557 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1558 COPY_MAC_ADDR(pHeader_802_11->Addr3, pTxBlk->pSrcBufHeader);
1559 pHeader_802_11->FC.ToDs = 1;
1560 }
1561 }
1562 else if (ADHOC_ON(pAd))
1563 {
1564 COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
1565 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1566 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1567 pHeader_802_11->FC.ToDs = 0;
1568 }
1569 }
1570
1571 if (pTxBlk->CipherAlg != CIPHER_NONE)
1572 pHeader_802_11->FC.Wep = 1;
1573
1574 // -----------------------------------------------------------------
1575 // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
1576 // -----------------------------------------------------------------
1577 if (pAd->CommonCfg.bAPSDForcePowerSave)
1578 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
1579 else
1580 pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
1581}
1582
1583#ifdef DOT11_N_SUPPORT
1584VOID STABuildCache802_11Header(
1585 IN RTMP_ADAPTER *pAd,
1586 IN TX_BLK *pTxBlk,
1587 IN UCHAR *pHeader)
1588{
1589 MAC_TABLE_ENTRY *pMacEntry;
1590 PHEADER_802_11 pHeader80211;
1591
1592 pHeader80211 = (PHEADER_802_11)pHeader;
1593 pMacEntry = pTxBlk->pMacEntry;
1594
1595 //
1596 // Update the cached 802.11 HEADER
1597 //
1598
1599 // normal wlan header size : 24 octets
1600 pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
1601
1602 // More Bit
1603 pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
1604
1605 // Sequence
1606 pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
1607 pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
1608
1609 {
1610 // Check if the frame can be sent through DLS direct link interface
1611 // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
1612#ifdef QOS_DLS_SUPPORT
1613 BOOLEAN bDLSFrame = FALSE;
1614 INT DlsEntryIndex = 0;
1615
1616 DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
1617 if (DlsEntryIndex >= 0)
1618 bDLSFrame = TRUE;
1619 else
1620 bDLSFrame = FALSE;
1621#endif // QOS_DLS_SUPPORT //
1622
1623 // The addr3 of normal packet send from DS is Dest Mac address.
1624#ifdef QOS_DLS_SUPPORT
1625 if (bDLSFrame)
1626 {
1627 COPY_MAC_ADDR(pHeader80211->Addr1, pTxBlk->pSrcBufHeader);
1628 COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
1629 pHeader80211->FC.ToDs = 0;
1630 }
1631 else
1632#endif // QOS_DLS_SUPPORT //
1633 if (ADHOC_ON(pAd))
1634 COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
1635 else
1636 COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader);
1637 }
1638
1639 // -----------------------------------------------------------------
1640 // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
1641 // -----------------------------------------------------------------
1642 if (pAd->CommonCfg.bAPSDForcePowerSave)
1643 pHeader80211->FC.PwrMgmt = PWR_SAVE;
1644 else
1645 pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
1646}
1647#endif // DOT11_N_SUPPORT //
1648
1649static inline PUCHAR STA_Build_ARalink_Frame_Header(
1650 IN RTMP_ADAPTER *pAd,
1651 IN TX_BLK *pTxBlk)
1652{
1653 PUCHAR pHeaderBufPtr;
1654 HEADER_802_11 *pHeader_802_11;
1655 PNDIS_PACKET pNextPacket;
1656 UINT32 nextBufLen;
1657 PQUEUE_ENTRY pQEntry;
1658
1659 STAFindCipherAlgorithm(pAd, pTxBlk);
1660 STABuildCommon802_11Header(pAd, pTxBlk);
1661
1662
1663 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1664 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
1665
1666 // steal "order" bit to mark "aggregation"
1667 pHeader_802_11->FC.Order = 1;
1668
1669 // skip common header
1670 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1671
1672 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
1673 {
1674 //
1675 // build QOS Control bytes
1676 //
1677 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1678
1679 *(pHeaderBufPtr+1) = 0;
1680 pHeaderBufPtr +=2;
1681 pTxBlk->MpduHeaderLen += 2;
1682 }
1683
1684 // padding at front of LLC header. LLC header should at 4-bytes aligment.
1685 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
1686 pHeaderBufPtr = (PCHAR)ROUND_UP(pHeaderBufPtr, 4);
1687 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1688
1689 // For RA Aggregation,
1690 // put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format
1691 pQEntry = pTxBlk->TxPacketList.Head;
1692 pNextPacket = QUEUE_ENTRY_TO_PKT(pQEntry);
1693 nextBufLen = GET_OS_PKT_LEN(pNextPacket);
1694 if (RTMP_GET_PACKET_VLAN(pNextPacket))
1695 nextBufLen -= LENGTH_802_1Q;
1696
1697 *pHeaderBufPtr = (UCHAR)nextBufLen & 0xff;
1698 *(pHeaderBufPtr+1) = (UCHAR)(nextBufLen >> 8);
1699
1700 pHeaderBufPtr += 2;
1701 pTxBlk->MpduHeaderLen += 2;
1702
1703 return pHeaderBufPtr;
1704
1705}
1706
1707#ifdef DOT11_N_SUPPORT
1708static inline PUCHAR STA_Build_AMSDU_Frame_Header(
1709 IN RTMP_ADAPTER *pAd,
1710 IN TX_BLK *pTxBlk)
1711{
1712 PUCHAR pHeaderBufPtr;//, pSaveBufPtr;
1713 HEADER_802_11 *pHeader_802_11;
1714
1715
1716 STAFindCipherAlgorithm(pAd, pTxBlk);
1717 STABuildCommon802_11Header(pAd, pTxBlk);
1718
1719 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1720 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
1721
1722 // skip common header
1723 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1724
1725 //
1726 // build QOS Control bytes
1727 //
1728 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1729
1730 //
1731 // A-MSDU packet
1732 //
1733 *pHeaderBufPtr |= 0x80;
1734
1735 *(pHeaderBufPtr+1) = 0;
1736 pHeaderBufPtr +=2;
1737 pTxBlk->MpduHeaderLen += 2;
1738
1739 //pSaveBufPtr = pHeaderBufPtr;
1740
1741 //
1742 // padding at front of LLC header
1743 // LLC header should locate at 4-octets aligment
1744 //
1745 // @@@ MpduHeaderLen excluding padding @@@
1746 //
1747 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
1748 pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
1749 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1750
1751 return pHeaderBufPtr;
1752
1753}
1754
1755
1756VOID STA_AMPDU_Frame_Tx(
1757 IN PRTMP_ADAPTER pAd,
1758 IN TX_BLK *pTxBlk)
1759{
1760 HEADER_802_11 *pHeader_802_11;
1761 PUCHAR pHeaderBufPtr;
1762 USHORT FreeNumber;
1763 MAC_TABLE_ENTRY *pMacEntry;
1764 BOOLEAN bVLANPkt;
1765 PQUEUE_ENTRY pQEntry;
1766
1767 ASSERT(pTxBlk);
1768
1769 while(pTxBlk->TxPacketList.Head)
1770 {
1771 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1772 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1773 if ( RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
1774 {
1775 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
1776 continue;
1777 }
1778
1779 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
1780
1781 pMacEntry = pTxBlk->pMacEntry;
1782 if (pMacEntry->isCached)
1783 {
1784 // NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]!!!!
1785 NdisMoveMemory((PUCHAR)&pTxBlk->HeaderBuf[TXINFO_SIZE], (PUCHAR)&pMacEntry->CachedBuf[0], TXWI_SIZE + sizeof(HEADER_802_11));
1786 pHeaderBufPtr = (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
1787 STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
1788 }
1789 else
1790 {
1791 STAFindCipherAlgorithm(pAd, pTxBlk);
1792 STABuildCommon802_11Header(pAd, pTxBlk);
1793
1794 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1795 }
1796
1797
1798 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
1799
1800 // skip common header
1801 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1802
1803 //
1804 // build QOS Control bytes
1805 //
1806 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1807 *(pHeaderBufPtr+1) = 0;
1808 pHeaderBufPtr +=2;
1809 pTxBlk->MpduHeaderLen += 2;
1810
1811 //
1812 // build HTC+
1813 // HTC control filed following QoS field
1814 //
1815 if ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_RDG_CAPABLE))
1816 {
1817 if (pMacEntry->isCached == FALSE)
1818 {
1819 // mark HTC bit
1820 pHeader_802_11->FC.Order = 1;
1821
1822 NdisZeroMemory(pHeaderBufPtr, 4);
1823 *(pHeaderBufPtr+3) |= 0x80;
1824 }
1825 pHeaderBufPtr += 4;
1826 pTxBlk->MpduHeaderLen += 4;
1827 }
1828
1829 //pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE;
1830 ASSERT(pTxBlk->MpduHeaderLen >= 24);
1831
1832 // skip 802.3 header
1833 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
1834 pTxBlk->SrcBufLen -= LENGTH_802_3;
1835
1836 // skip vlan tag
1837 if (bVLANPkt)
1838 {
1839 pTxBlk->pSrcBufData += LENGTH_802_1Q;
1840 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
1841 }
1842
1843 //
1844 // padding at front of LLC header
1845 // LLC header should locate at 4-octets aligment
1846 //
1847 // @@@ MpduHeaderLen excluding padding @@@
1848 //
1849 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
1850 pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
1851 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1852
1853 {
1854
1855 //
1856 // Insert LLC-SNAP encapsulation - 8 octets
1857 //
1858 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
1859 if (pTxBlk->pExtraLlcSnapEncap)
1860 {
1861 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
1862 pHeaderBufPtr += 6;
1863 // get 2 octets (TypeofLen)
1864 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
1865 pHeaderBufPtr += 2;
1866 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
1867 }
1868
1869 }
1870
1871 if (pMacEntry->isCached)
1872 {
1873 RTMPWriteTxWI_Cache(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
1874 }
1875 else
1876 {
1877 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
1878
1879 NdisZeroMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), sizeof(pMacEntry->CachedBuf));
1880 NdisMoveMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (pHeaderBufPtr - (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE])));
1881 pMacEntry->isCached = TRUE;
1882 }
1883
1884 // calculate Transmitted AMPDU count and ByteCount
1885 {
1886 pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart ++;
1887 pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.QuadPart += pTxBlk->SrcBufLen;
1888 }
1889
1890 //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
1891
1892 HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
1893
1894 //
1895 // Kick out Tx
1896 //
1897 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
1898
1899 pAd->RalinkCounters.KickTxCount++;
1900 pAd->RalinkCounters.OneSecTxDoneCount++;
1901 }
1902
1903}
1904
1905
1906VOID STA_AMSDU_Frame_Tx(
1907 IN PRTMP_ADAPTER pAd,
1908 IN TX_BLK *pTxBlk)
1909{
1910 PUCHAR pHeaderBufPtr;
1911 USHORT FreeNumber;
1912 USHORT subFramePayloadLen = 0; // AMSDU Subframe length without AMSDU-Header / Padding.
1913 USHORT totalMPDUSize=0;
1914 UCHAR *subFrameHeader;
1915 UCHAR padding = 0;
1916 USHORT FirstTx = 0, LastTxIdx = 0;
1917 BOOLEAN bVLANPkt;
1918 int frameNum = 0;
1919 PQUEUE_ENTRY pQEntry;
1920
1921
1922 ASSERT(pTxBlk);
1923
1924 ASSERT((pTxBlk->TxPacketList.Number > 1));
1925
1926 while(pTxBlk->TxPacketList.Head)
1927 {
1928 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1929 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1930 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
1931 {
1932 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
1933 continue;
1934 }
1935
1936 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
1937
1938 // skip 802.3 header
1939 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
1940 pTxBlk->SrcBufLen -= LENGTH_802_3;
1941
1942 // skip vlan tag
1943 if (bVLANPkt)
1944 {
1945 pTxBlk->pSrcBufData += LENGTH_802_1Q;
1946 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
1947 }
1948
1949 if (frameNum == 0)
1950 {
1951 pHeaderBufPtr = STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
1952
1953 // NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled.
1954 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
1955 }
1956 else
1957 {
1958 pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
1959 padding = ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen, 4) - (LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen);
1960 NdisZeroMemory(pHeaderBufPtr, padding + LENGTH_AMSDU_SUBFRAMEHEAD);
1961 pHeaderBufPtr += padding;
1962 pTxBlk->MpduHeaderLen = padding;
1963 }
1964
1965 //
1966 // A-MSDU subframe
1967 // DA(6)+SA(6)+Length(2) + LLC/SNAP Encap
1968 //
1969 subFrameHeader = pHeaderBufPtr;
1970 subFramePayloadLen = pTxBlk->SrcBufLen;
1971
1972 NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
1973
1974
1975 pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
1976 pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;
1977
1978
1979 //
1980 // Insert LLC-SNAP encapsulation - 8 octets
1981 //
1982 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
1983
1984 subFramePayloadLen = pTxBlk->SrcBufLen;
1985
1986 if (pTxBlk->pExtraLlcSnapEncap)
1987 {
1988 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
1989 pHeaderBufPtr += 6;
1990 // get 2 octets (TypeofLen)
1991 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
1992 pHeaderBufPtr += 2;
1993 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
1994 subFramePayloadLen += LENGTH_802_1_H;
1995 }
1996
1997 // update subFrame Length field
1998 subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
1999 subFrameHeader[13] = subFramePayloadLen & 0xFF;
2000
2001 totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
2002
2003 if (frameNum ==0)
2004 FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2005 else
2006 LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2007
2008 frameNum++;
2009
2010 pAd->RalinkCounters.KickTxCount++;
2011 pAd->RalinkCounters.OneSecTxDoneCount++;
2012
2013 // calculate Transmitted AMSDU Count and ByteCount
2014 {
2015 pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart ++;
2016 pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart += totalMPDUSize;
2017 }
2018
2019 }
2020
2021 HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
2022 HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
2023
2024 //
2025 // Kick out Tx
2026 //
2027 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2028}
2029#endif // DOT11_N_SUPPORT //
2030
2031VOID STA_Legacy_Frame_Tx(
2032 IN PRTMP_ADAPTER pAd,
2033 IN TX_BLK *pTxBlk)
2034{
2035 HEADER_802_11 *pHeader_802_11;
2036 PUCHAR pHeaderBufPtr;
2037 USHORT FreeNumber;
2038 BOOLEAN bVLANPkt;
2039 PQUEUE_ENTRY pQEntry;
2040
2041 ASSERT(pTxBlk);
2042
2043
2044 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2045 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2046 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
2047 {
2048 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2049 return;
2050 }
2051
2052 if (pTxBlk->TxFrameType == TX_MCAST_FRAME)
2053 {
2054 INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
2055 }
2056
2057 if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket))
2058 TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired);
2059 else
2060 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired);
2061
2062 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2063
2064 if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate)
2065 pTxBlk->TxRate = pAd->CommonCfg.MinTxRate;
2066
2067 STAFindCipherAlgorithm(pAd, pTxBlk);
2068 STABuildCommon802_11Header(pAd, pTxBlk);
2069
2070
2071 // skip 802.3 header
2072 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2073 pTxBlk->SrcBufLen -= LENGTH_802_3;
2074
2075 // skip vlan tag
2076 if (bVLANPkt)
2077 {
2078 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2079 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2080 }
2081
2082 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
2083 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
2084
2085 // skip common header
2086 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
2087
2088 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
2089 {
2090 //
2091 // build QOS Control bytes
2092 //
2093 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
2094 *(pHeaderBufPtr+1) = 0;
2095 pHeaderBufPtr +=2;
2096 pTxBlk->MpduHeaderLen += 2;
2097 }
2098
2099 // The remaining content of MPDU header should locate at 4-octets aligment
2100 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
2101 pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
2102 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
2103
2104 {
2105
2106 //
2107 // Insert LLC-SNAP encapsulation - 8 octets
2108 //
2109 //
2110 // if original Ethernet frame contains no LLC/SNAP,
2111 // then an extra LLC/SNAP encap is required
2112 //
2113 EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
2114 if (pTxBlk->pExtraLlcSnapEncap)
2115 {
2116 UCHAR vlan_size;
2117
2118 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2119 pHeaderBufPtr += 6;
2120 // skip vlan tag
2121 vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
2122 // get 2 octets (TypeofLen)
2123 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
2124 pHeaderBufPtr += 2;
2125 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2126 }
2127
2128 }
2129
2130 //
2131 // prepare for TXWI
2132 // use Wcid as Key Index
2133 //
2134
2135 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
2136
2137 //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
2138
2139 HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
2140
2141 pAd->RalinkCounters.KickTxCount++;
2142 pAd->RalinkCounters.OneSecTxDoneCount++;
2143
2144 //
2145 // Kick out Tx
2146 //
2147 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2148}
2149
2150
2151VOID STA_ARalink_Frame_Tx(
2152 IN PRTMP_ADAPTER pAd,
2153 IN TX_BLK *pTxBlk)
2154{
2155 PUCHAR pHeaderBufPtr;
2156 USHORT FreeNumber;
2157 USHORT totalMPDUSize=0;
2158 USHORT FirstTx, LastTxIdx;
2159 int frameNum = 0;
2160 BOOLEAN bVLANPkt;
2161 PQUEUE_ENTRY pQEntry;
2162
2163
2164 ASSERT(pTxBlk);
2165
2166 ASSERT((pTxBlk->TxPacketList.Number== 2));
2167
2168
2169 FirstTx = LastTxIdx = 0; // Is it ok init they as 0?
2170 while(pTxBlk->TxPacketList.Head)
2171 {
2172 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2173 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2174
2175 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
2176 {
2177 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2178 continue;
2179 }
2180
2181 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2182
2183 // skip 802.3 header
2184 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2185 pTxBlk->SrcBufLen -= LENGTH_802_3;
2186
2187 // skip vlan tag
2188 if (bVLANPkt)
2189 {
2190 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2191 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2192 }
2193
2194 if (frameNum == 0)
2195 { // For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header
2196
2197 pHeaderBufPtr = STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
2198
2199 // It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount
2200 // will be updated after final frame was handled.
2201 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
2202
2203
2204 //
2205 // Insert LLC-SNAP encapsulation - 8 octets
2206 //
2207 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
2208
2209 if (pTxBlk->pExtraLlcSnapEncap)
2210 {
2211 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2212 pHeaderBufPtr += 6;
2213 // get 2 octets (TypeofLen)
2214 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
2215 pHeaderBufPtr += 2;
2216 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2217 }
2218 }
2219 else
2220 { // For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0.
2221
2222 pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
2223 pTxBlk->MpduHeaderLen = 0;
2224
2225 // A-Ralink sub-sequent frame header is the same as 802.3 header.
2226 // DA(6)+SA(6)+FrameType(2)
2227 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader, 12);
2228 pHeaderBufPtr += 12;
2229 // get 2 octets (TypeofLen)
2230 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
2231 pHeaderBufPtr += 2;
2232 pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
2233 }
2234
2235 totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
2236
2237 //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
2238 if (frameNum ==0)
2239 FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2240 else
2241 LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2242
2243 frameNum++;
2244
2245 pAd->RalinkCounters.OneSecTxAggregationCount++;
2246 pAd->RalinkCounters.KickTxCount++;
2247 pAd->RalinkCounters.OneSecTxDoneCount++;
2248
2249 }
2250
2251 HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
2252 HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
2253
2254 //
2255 // Kick out Tx
2256 //
2257 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2258
2259}
2260
2261
2262VOID STA_Fragment_Frame_Tx(
2263 IN RTMP_ADAPTER *pAd,
2264 IN TX_BLK *pTxBlk)
2265{
2266 HEADER_802_11 *pHeader_802_11;
2267 PUCHAR pHeaderBufPtr;
2268 USHORT FreeNumber;
2269 UCHAR fragNum = 0;
2270 PACKET_INFO PacketInfo;
2271 USHORT EncryptionOverhead = 0;
2272 UINT32 FreeMpduSize, SrcRemainingBytes;
2273 USHORT AckDuration;
2274 UINT NextMpduSize;
2275 BOOLEAN bVLANPkt;
2276 PQUEUE_ENTRY pQEntry;
2277
2278
2279 ASSERT(pTxBlk);
2280
2281 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2282 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2283 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
2284 {
2285 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2286 return;
2287 }
2288
2289 ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag));
2290 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2291
2292 STAFindCipherAlgorithm(pAd, pTxBlk);
2293 STABuildCommon802_11Header(pAd, pTxBlk);
2294
2295 if (pTxBlk->CipherAlg == CIPHER_TKIP)
2296 {
2297 pTxBlk->pPacket = duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
2298 if (pTxBlk->pPacket == NULL)
2299 return;
2300 RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
2301 }
2302
2303 // skip 802.3 header
2304 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2305 pTxBlk->SrcBufLen -= LENGTH_802_3;
2306
2307
2308 // skip vlan tag
2309 if (bVLANPkt)
2310 {
2311 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2312 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2313 }
2314
2315 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
2316 pHeader_802_11 = (HEADER_802_11 *)pHeaderBufPtr;
2317
2318
2319 // skip common header
2320 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
2321
2322 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
2323 {
2324 //
2325 // build QOS Control bytes
2326 //
2327 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
2328
2329 *(pHeaderBufPtr+1) = 0;
2330 pHeaderBufPtr +=2;
2331 pTxBlk->MpduHeaderLen += 2;
2332 }
2333
2334 //
2335 // padding at front of LLC header
2336 // LLC header should locate at 4-octets aligment
2337 //
2338 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
2339 pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
2340 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
2341
2342
2343
2344 //
2345 // Insert LLC-SNAP encapsulation - 8 octets
2346 //
2347 //
2348 // if original Ethernet frame contains no LLC/SNAP,
2349 // then an extra LLC/SNAP encap is required
2350 //
2351 EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
2352 if (pTxBlk->pExtraLlcSnapEncap)
2353 {
2354 UCHAR vlan_size;
2355
2356 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2357 pHeaderBufPtr += 6;
2358 // skip vlan tag
2359 vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
2360 // get 2 octets (TypeofLen)
2361 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
2362 pHeaderBufPtr += 2;
2363 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2364 }
2365
2366
2367 // If TKIP is used and fragmentation is required. Driver has to
2368 // append TKIP MIC at tail of the scatter buffer
2369 // MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC
2370 if (pTxBlk->CipherAlg == CIPHER_TKIP)
2371 {
2372
2373 // NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust
2374 // to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress.
2375 NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen, &pAd->PrivateInfo.Tx.MIC[0], 8);
2376 //skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8);
2377 pTxBlk->SrcBufLen += 8;
2378 pTxBlk->TotalFrameLen += 8;
2379 pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
2380 }
2381
2382 //
2383 // calcuate the overhead bytes that encryption algorithm may add. This
2384 // affects the calculate of "duration" field
2385 //
2386 if ((pTxBlk->CipherAlg == CIPHER_WEP64) || (pTxBlk->CipherAlg == CIPHER_WEP128))
2387 EncryptionOverhead = 8; //WEP: IV[4] + ICV[4];
2388 else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
2389 EncryptionOverhead = 12;//TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength
2390 else if (pTxBlk->CipherAlg == CIPHER_TKIP)
2391 EncryptionOverhead = 20;//TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8]
2392 else if (pTxBlk->CipherAlg == CIPHER_AES)
2393 EncryptionOverhead = 16; // AES: IV[4] + EIV[4] + MIC[8]
2394 else
2395 EncryptionOverhead = 0;
2396
2397 // decide how much time an ACK/CTS frame will consume in the air
2398 AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14);
2399
2400 // Init the total payload length of this frame.
2401 SrcRemainingBytes = pTxBlk->SrcBufLen;
2402
2403 pTxBlk->TotalFragNum = 0xff;
2404
2405 do {
2406
2407 FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC;
2408
2409 FreeMpduSize -= pTxBlk->MpduHeaderLen;
2410
2411 if (SrcRemainingBytes <= FreeMpduSize)
2412 { // this is the last or only fragment
2413
2414 pTxBlk->SrcBufLen = SrcRemainingBytes;
2415
2416 pHeader_802_11->FC.MoreFrag = 0;
2417 pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + AckDuration;
2418
2419 // Indicate the lower layer that this's the last fragment.
2420 pTxBlk->TotalFragNum = fragNum;
2421 }
2422 else
2423 { // more fragment is required
2424
2425 pTxBlk->SrcBufLen = FreeMpduSize;
2426
2427 NextMpduSize = min(((UINT)SrcRemainingBytes - pTxBlk->SrcBufLen), ((UINT)pAd->CommonCfg.FragmentThreshold));
2428 pHeader_802_11->FC.MoreFrag = 1;
2429 pHeader_802_11->Duration = (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) + RTMPCalcDuration(pAd, pTxBlk->TxRate, NextMpduSize + EncryptionOverhead);
2430 }
2431
2432 if (fragNum == 0)
2433 pTxBlk->FrameGap = IFS_HTTXOP;
2434 else
2435 pTxBlk->FrameGap = IFS_SIFS;
2436
2437 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
2438
2439 HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);
2440
2441 pAd->RalinkCounters.KickTxCount++;
2442 pAd->RalinkCounters.OneSecTxDoneCount++;
2443
2444 // Update the frame number, remaining size of the NDIS packet payload.
2445
2446 // space for 802.11 header.
2447 if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
2448 pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;
2449
2450 fragNum++;
2451 SrcRemainingBytes -= pTxBlk->SrcBufLen;
2452 pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;
2453
2454 pHeader_802_11->Frag++; // increase Frag #
2455
2456 }while(SrcRemainingBytes > 0);
2457
2458 //
2459 // Kick out Tx
2460 //
2461 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2462}
2463
2464
2465#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) \
2466 while(_pTxBlk->TxPacketList.Head) \
2467 { \
2468 _pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList); \
2469 RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status); \
2470 }
2471
2472
2473/*
2474 ========================================================================
2475
2476 Routine Description:
2477 Copy frame from waiting queue into relative ring buffer and set
2478 appropriate ASIC register to kick hardware encryption before really
2479 sent out to air.
2480
2481 Arguments:
2482 pAd Pointer to our adapter
2483 PNDIS_PACKET Pointer to outgoing Ndis frame
2484 NumberOfFrag Number of fragment required
2485
2486 Return Value:
2487 None
2488
2489 IRQL = DISPATCH_LEVEL
2490
2491 Note:
2492
2493 ========================================================================
2494*/
2495NDIS_STATUS STAHardTransmit(
2496 IN PRTMP_ADAPTER pAd,
2497 IN TX_BLK *pTxBlk,
2498 IN UCHAR QueIdx)
2499{
2500 NDIS_PACKET *pPacket;
2501 PQUEUE_ENTRY pQEntry;
2502
2503 // ---------------------------------------------
2504 // STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION.
2505 // ---------------------------------------------
2506 //
2507 ASSERT(pTxBlk->TxPacketList.Number);
2508 if (pTxBlk->TxPacketList.Head == NULL)
2509 {
2510 DBGPRINT(RT_DEBUG_ERROR, ("pTxBlk->TotalFrameNum == %ld!\n", pTxBlk->TxPacketList.Number));
2511 return NDIS_STATUS_FAILURE;
2512 }
2513
2514 pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);
2515
2516#if 0 //def CARRIER_DETECTION_SUPPORT // Roger sync Carrier
2517 if ((pAd->CommonCfg.CarrierDetect.Enable == TRUE) && (isCarrierDetectExist(pAd) == TRUE))
2518 {
2519 DBGPRINT(RT_DEBUG_INFO,("STAHardTransmit --> radar detect not in normal mode !!!\n"));
2520 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
2521 return (NDIS_STATUS_FAILURE);
2522 }
2523#endif // CARRIER_DETECTION_SUPPORT //
2524
2525 // ------------------------------------------------------------------
2526 // STEP 1. WAKE UP PHY
2527 // outgoing frame always wakeup PHY to prevent frame lost and
2528 // turn off PSM bit to improve performance
2529 // ------------------------------------------------------------------
2530 // not to change PSM bit, just send this frame out?
2531 if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
2532 {
2533 DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicForceWakeup At HardTx\n"));
2534 AsicForceWakeup(pAd, TRUE);
2535 }
2536
2537 // It should not change PSM bit, when APSD turn on.
2538 if ((!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
2539 || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
2540 || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket)))
2541 {
2542 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
2543 (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP))
2544 MlmeSetPsmBit(pAd, PWR_ACTIVE);
2545 }
2546
2547 switch (pTxBlk->TxFrameType)
2548 {
2549#ifdef DOT11_N_SUPPORT
2550 case TX_AMPDU_FRAME:
2551 STA_AMPDU_Frame_Tx(pAd, pTxBlk);
2552 break;
2553 case TX_AMSDU_FRAME:
2554 STA_AMSDU_Frame_Tx(pAd, pTxBlk);
2555 break;
2556#endif // DOT11_N_SUPPORT //
2557 case TX_LEGACY_FRAME:
2558 STA_Legacy_Frame_Tx(pAd, pTxBlk);
2559 break;
2560 case TX_MCAST_FRAME:
2561 STA_Legacy_Frame_Tx(pAd, pTxBlk);
2562 break;
2563 case TX_RALINK_FRAME:
2564 STA_ARalink_Frame_Tx(pAd, pTxBlk);
2565 break;
2566 case TX_FRAG_FRAME:
2567 STA_Fragment_Frame_Tx(pAd, pTxBlk);
2568 break;
2569 default:
2570 {
2571 // It should not happened!
2572 DBGPRINT(RT_DEBUG_ERROR, ("Send a pacekt was not classified!! It should not happen!\n"));
2573 while(pTxBlk->TxPacketList.Number)
2574 {
2575 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2576 pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2577 if (pPacket)
2578 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
2579 }
2580 }
2581 break;
2582 }
2583
2584 return (NDIS_STATUS_SUCCESS);
2585
2586}
2587
2588ULONG HashBytesPolynomial(UCHAR *value, unsigned int len)
2589{
2590 unsigned char *word = value;
2591 unsigned int ret = 0;
2592 unsigned int i;
2593
2594 for(i=0; i < len; i++)
2595 {
2596 int mod = i % 32;
2597 ret ^=(unsigned int) (word[i]) << mod;
2598 ret ^=(unsigned int) (word[i]) >> (32 - mod);
2599 }
2600 return ret;
2601}
2602
2603VOID Sta_Announce_or_Forward_802_3_Packet(
2604 IN PRTMP_ADAPTER pAd,
2605 IN PNDIS_PACKET pPacket,
2606 IN UCHAR FromWhichBSSID)
2607{
2608 if (TRUE
2609 )
2610 {
2611 announce_802_3_packet(pAd, pPacket);
2612 }
2613 else
2614 {
2615 // release packet
2616 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
2617 }
2618}
2619
diff --git a/drivers/staging/rt2870/sta/sanity.c b/drivers/staging/rt2870/sta/sanity.c
new file mode 100644
index 00000000000..239872464be
--- /dev/null
+++ b/drivers/staging/rt2870/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/rt2870/sta/sync.c b/drivers/staging/rt2870/sta/sync.c
new file mode 100644
index 00000000000..a48975566e0
--- /dev/null
+++ b/drivers/staging/rt2870/sta/sync.c
@@ -0,0 +1,1753 @@
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 return;
1124 }
1125
1126 // collapse into the ADHOC network which has bigger BSSID value.
1127 for (i = 0; i < 6; i++)
1128 {
1129 if (Bssid[i] > pAd->CommonCfg.Bssid[i])
1130 {
1131 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
1132 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
1133 AsicDisableSync(pAd);
1134 COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid);
1135 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1136 MakeIbssBeacon(pAd); // re-build BEACON frame
1137 AsicEnableIbssSync(pAd); // copy BEACON frame to on-chip memory
1138 is_my_bssid = TRUE;
1139 break;
1140 }
1141 else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
1142 break;
1143 }
1144 }
1145
1146
1147 NdisGetSystemUpTime(&Now);
1148 pBss = &pAd->ScanTab.BssEntry[Bssidx];
1149 pBss->Rssi = RealRssi; // lastest RSSI
1150 pBss->LastBeaconRxTime = Now; // last RX timestamp
1151
1152 //
1153 // BEACON from my BSSID - either IBSS or INFRA network
1154 //
1155 if (is_my_bssid)
1156 {
1157 RXWI_STRUC RxWI;
1158
1159 pAd->StaCfg.DtimCount = DtimCount;
1160 pAd->StaCfg.DtimPeriod = DtimPeriod;
1161 pAd->StaCfg.LastBeaconRxTime = Now;
1162
1163
1164 RxWI.RSSI0 = Elem->Rssi0;
1165 RxWI.RSSI1 = Elem->Rssi1;
1166 RxWI.RSSI2 = Elem->Rssi2;
1167
1168 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
1169 if (AironetCellPowerLimit != 0xFF)
1170 {
1171 //
1172 // We get the Cisco (ccx) "TxPower Limit" required
1173 // Changed to appropriate TxPower Limit for Ciso Compatible Extensions
1174 //
1175 ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
1176 }
1177 else
1178 {
1179 //
1180 // AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
1181 // Used the default TX Power Percentage, that set from UI.
1182 //
1183 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
1184 }
1185
1186 if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
1187 {
1188 UCHAR MaxSupportedRateIn500Kbps = 0;
1189 UCHAR idx;
1190 MAC_TABLE_ENTRY *pEntry;
1191
1192 // supported rates array may not be sorted. sort it and find the maximum rate
1193 for (idx=0; idx<SupRateLen; idx++)
1194 {
1195 if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
1196 MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
1197 }
1198
1199 for (idx=0; idx<ExtRateLen; idx++)
1200 {
1201 if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
1202 MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
1203 }
1204
1205 // look up the existing table
1206 pEntry = MacTableLookup(pAd, Addr2);
1207
1208 // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
1209 // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
1210 if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) ||
1211 (pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now)))
1212 {
1213 if (pEntry == NULL)
1214 // Another adhoc joining, add to our MAC table.
1215 pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
1216
1217 if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo) == FALSE)
1218 {
1219 DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n"));
1220 return;
1221 }
1222
1223 if (pEntry &&
1224 (Elem->Wcid == RESERVED_WCID))
1225 {
1226 idx = pAd->StaCfg.DefaultKeyId;
1227 RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
1228 }
1229 }
1230
1231 if (pEntry && pEntry->ValidAsCLI)
1232 pEntry->LastBeaconRxTime = Now;
1233
1234 // At least another peer in this IBSS, declare MediaState as CONNECTED
1235 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1236 {
1237 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1238
1239 pAd->IndicateMediaState = NdisMediaStateConnected;
1240 RTMP_IndicateMediaState(pAd);
1241 pAd->ExtraInfo = GENERAL_LINK_UP;
1242 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1243
1244 // 2003/03/12 - john
1245 // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
1246 // "site survey" result should always include the current connected network.
1247 //
1248 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1249 if (Bssidx == BSS_NOT_FOUND)
1250 {
1251 Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
1252 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
1253 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
1254 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
1255 }
1256 DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1257 }
1258 }
1259
1260 if (INFRA_ON(pAd))
1261 {
1262 BOOLEAN bUseShortSlot, bUseBGProtection;
1263
1264 // decide to use/change to -
1265 // 1. long slot (20 us) or short slot (9 us) time
1266 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1267 // 3. short preamble
1268
1269 //bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
1270 bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo);
1271 if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
1272 AsicSetSlotTime(pAd, bUseShortSlot);
1273
1274 bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || // always use
1275 ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp));
1276
1277 if (pAd->CommonCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
1278 bUseBGProtection = FALSE;
1279
1280 if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
1281 {
1282 if (bUseBGProtection)
1283 {
1284 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1285 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
1286 }
1287 else
1288 {
1289 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1290 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
1291 }
1292
1293 DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection));
1294 }
1295
1296#ifdef DOT11_N_SUPPORT
1297 // check Ht protection mode. and adhere to the Non-GF device indication by AP.
1298 if ((AddHtInfoLen != 0) &&
1299 ((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) ||
1300 (AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent)))
1301 {
1302 pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent;
1303 pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode;
1304 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1305 {
1306 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1307 }
1308 else
1309 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1310
1311 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode));
1312 }
1313#endif // DOT11_N_SUPPORT //
1314
1315 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) &&
1316 ERP_IS_USE_BARKER_PREAMBLE(Erp))
1317 {
1318 MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
1319 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n"));
1320 }
1321
1322 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
1323 (EdcaParm.bValid == TRUE) &&
1324 (EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount))
1325 {
1326 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1327 pAd->CommonCfg.APEdcaParm.EdcaUpdateCount,
1328 EdcaParm.EdcaUpdateCount));
1329 AsicSetEdcaParm(pAd, &EdcaParm);
1330 }
1331
1332 // copy QOS related information
1333 NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
1334 NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
1335 }
1336
1337 // only INFRASTRUCTURE mode support power-saving feature
1338 if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave))
1339 {
1340 UCHAR FreeNumber;
1341 // 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
1342 // 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
1343 // 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
1344 // 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
1345 // 5. otherwise, put PHY back to sleep to save battery.
1346 if (MessageToMe)
1347 {
1348 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
1349 pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
1350 {
1351 pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
1352 }
1353 else
1354 RT28XX_PS_POLL_ENQUEUE(pAd);
1355 }
1356 else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
1357 {
1358 }
1359 else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) ||
1360 (pAd->TxSwQueue[QID_AC_BE].Number != 0) ||
1361 (pAd->TxSwQueue[QID_AC_VI].Number != 0) ||
1362 (pAd->TxSwQueue[QID_AC_VO].Number != 0) ||
1363 (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1364 (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1365 (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1366 (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1367 (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS))
1368 {
1369 // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
1370 // can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
1371 }
1372 else
1373 {
1374 USHORT NextDtim = DtimCount;
1375
1376 if (NextDtim == 0)
1377 NextDtim = DtimPeriod;
1378
1379 TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
1380 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
1381 TbttNumToNextWakeUp = NextDtim;
1382
1383 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1384 {
1385 AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
1386 }
1387 }
1388 }
1389 }
1390 // not my BSSID, ignore it
1391 }
1392 // sanity check fail, ignore this frame
1393}
1394
1395/*
1396 ==========================================================================
1397 Description:
1398 Receive PROBE REQ from remote peer when operating in IBSS mode
1399 ==========================================================================
1400 */
1401VOID PeerProbeReqAction(
1402 IN PRTMP_ADAPTER pAd,
1403 IN MLME_QUEUE_ELEM *Elem)
1404{
1405 UCHAR Addr2[MAC_ADDR_LEN];
1406 CHAR Ssid[MAX_LEN_OF_SSID];
1407 UCHAR SsidLen;
1408#ifdef DOT11_N_SUPPORT
1409 UCHAR HtLen, AddHtLen, NewExtLen;
1410#endif // DOT11_N_SUPPORT //
1411 HEADER_802_11 ProbeRspHdr;
1412 NDIS_STATUS NStatus;
1413 PUCHAR pOutBuffer = NULL;
1414 ULONG FrameLen = 0;
1415 LARGE_INTEGER FakeTimestamp;
1416 UCHAR DsLen = 1, IbssLen = 2;
1417 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0};
1418 BOOLEAN Privacy;
1419 USHORT CapabilityInfo;
1420 UCHAR RSNIe = IE_WPA;
1421
1422 if (! ADHOC_ON(pAd))
1423 return;
1424
1425 if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
1426 {
1427 if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
1428 {
1429 // allocate and send out ProbeRsp frame
1430 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1431 if (NStatus != NDIS_STATUS_SUCCESS)
1432 return;
1433
1434 //pAd->StaCfg.AtimWin = 0; // ??????
1435
1436 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
1437 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
1438 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
1439 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
1440
1441 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1442 sizeof(HEADER_802_11), &ProbeRspHdr,
1443 TIMESTAMP_LEN, &FakeTimestamp,
1444 2, &pAd->CommonCfg.BeaconPeriod,
1445 2, &CapabilityInfo,
1446 1, &SsidIe,
1447 1, &pAd->CommonCfg.SsidLen,
1448 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1449 1, &SupRateIe,
1450 1, &pAd->StaActive.SupRateLen,
1451 pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
1452 1, &DsIe,
1453 1, &DsLen,
1454 1, &pAd->CommonCfg.Channel,
1455 1, &IbssIe,
1456 1, &IbssLen,
1457 2, &pAd->StaActive.AtimWin,
1458 END_OF_ARGS);
1459
1460 if (pAd->StaActive.ExtRateLen)
1461 {
1462 ULONG tmp;
1463 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1464 3, LocalErpIe,
1465 1, &ExtRateIe,
1466 1, &pAd->StaActive.ExtRateLen,
1467 pAd->StaActive.ExtRateLen, &pAd->StaActive.ExtRate,
1468 END_OF_ARGS);
1469 FrameLen += tmp;
1470 }
1471
1472 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1473 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1474 {
1475 ULONG tmp;
1476 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1477 1, &RSNIe,
1478 1, &pAd->StaCfg.RSNIE_Len,
1479 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
1480 END_OF_ARGS);
1481 FrameLen += tmp;
1482 }
1483#ifdef DOT11_N_SUPPORT
1484 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1485 {
1486 ULONG TmpLen;
1487 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
1488 HtLen = sizeof(pAd->CommonCfg.HtCapability);
1489 AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
1490 NewExtLen = 1;
1491 //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
1492 if (pAd->bBroadComHT == TRUE)
1493 {
1494 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
1495 1, &WpaIe,
1496 4, &BROADCOM[0],
1497 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
1498 END_OF_ARGS);
1499 }
1500 else
1501 {
1502 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
1503 1, &HtCapIe,
1504 1, &HtLen,
1505 sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability,
1506 1, &AddHtInfoIe,
1507 1, &AddHtLen,
1508 sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo,
1509 1, &NewExtChanIe,
1510 1, &NewExtLen,
1511 sizeof(NEW_EXT_CHAN_IE), &pAd->CommonCfg.NewExtChanOffset,
1512 END_OF_ARGS);
1513 }
1514 FrameLen += TmpLen;
1515 }
1516#endif // DOT11_N_SUPPORT //
1517 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1518 MlmeFreeMemory(pAd, pOutBuffer);
1519 }
1520 }
1521}
1522
1523VOID BeaconTimeoutAtJoinAction(
1524 IN PRTMP_ADAPTER pAd,
1525 IN MLME_QUEUE_ELEM *Elem)
1526{
1527 USHORT Status;
1528 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1529 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1530 Status = MLME_REJ_TIMEOUT;
1531 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1532}
1533
1534/*
1535 ==========================================================================
1536 Description:
1537 Scan timeout procedure. basically add channel index by 1 and rescan
1538 ==========================================================================
1539 */
1540VOID ScanTimeoutAction(
1541 IN PRTMP_ADAPTER pAd,
1542 IN MLME_QUEUE_ELEM *Elem)
1543{
1544 pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
1545
1546 // Only one channel scanned for CISCO beacon request
1547 if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
1548 (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
1549 (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
1550 (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
1551 pAd->MlmeAux.Channel = 0;
1552
1553 // this routine will stop if pAd->MlmeAux.Channel == 0
1554 ScanNextChannel(pAd);
1555}
1556
1557/*
1558 ==========================================================================
1559 Description:
1560 ==========================================================================
1561 */
1562VOID InvalidStateWhenScan(
1563 IN PRTMP_ADAPTER pAd,
1564 IN MLME_QUEUE_ELEM *Elem)
1565{
1566 USHORT Status;
1567 DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1568 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1569 Status = MLME_STATE_MACHINE_REJECT;
1570 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
1571}
1572
1573/*
1574 ==========================================================================
1575 Description:
1576 ==========================================================================
1577 */
1578VOID InvalidStateWhenJoin(
1579 IN PRTMP_ADAPTER pAd,
1580 IN MLME_QUEUE_ELEM *Elem)
1581{
1582 USHORT Status;
1583 DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1584 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1585 Status = MLME_STATE_MACHINE_REJECT;
1586 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1587}
1588
1589/*
1590 ==========================================================================
1591 Description:
1592 ==========================================================================
1593 */
1594VOID InvalidStateWhenStart(
1595 IN PRTMP_ADAPTER pAd,
1596 IN MLME_QUEUE_ELEM *Elem)
1597{
1598 USHORT Status;
1599 DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1600 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1601 Status = MLME_STATE_MACHINE_REJECT;
1602 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
1603}
1604
1605/*
1606 ==========================================================================
1607 Description:
1608
1609 IRQL = DISPATCH_LEVEL
1610
1611 ==========================================================================
1612 */
1613VOID EnqueuePsPoll(
1614 IN PRTMP_ADAPTER pAd)
1615{
1616#ifdef RALINK_ATE
1617 if (ATE_ON(pAd))
1618 {
1619 return;
1620 }
1621#endif // RALINK_ATE //
1622
1623
1624 if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
1625 pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
1626 MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
1627}
1628
1629
1630/*
1631 ==========================================================================
1632 Description:
1633 ==========================================================================
1634 */
1635VOID EnqueueProbeRequest(
1636 IN PRTMP_ADAPTER pAd)
1637{
1638 NDIS_STATUS NState;
1639 PUCHAR pOutBuffer;
1640 ULONG FrameLen = 0;
1641 HEADER_802_11 Hdr80211;
1642
1643 DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
1644
1645 NState = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1646 if (NState == NDIS_STATUS_SUCCESS)
1647 {
1648 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
1649
1650 // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
1651 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1652 sizeof(HEADER_802_11), &Hdr80211,
1653 1, &SsidIe,
1654 1, &pAd->CommonCfg.SsidLen,
1655 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1656 1, &SupRateIe,
1657 1, &pAd->StaActive.SupRateLen,
1658 pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
1659 END_OF_ARGS);
1660 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1661 MlmeFreeMemory(pAd, pOutBuffer);
1662 }
1663
1664}
1665
1666#ifdef DOT11_N_SUPPORT
1667#ifdef DOT11N_DRAFT3
1668VOID BuildEffectedChannelList(
1669 IN PRTMP_ADAPTER pAd)
1670{
1671 UCHAR EChannel[11];
1672 UCHAR i, j, k;
1673 UCHAR UpperChannel = 0, LowerChannel = 0;
1674
1675 RTMPZeroMemory(EChannel, 11);
1676 i = 0;
1677 // Find upper channel and lower channel.
1678 if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
1679 {
1680 UpperChannel = pAd->CommonCfg.Channel;
1681 LowerChannel = pAd->CommonCfg.CentralChannel;
1682 }
1683 else if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
1684 {
1685 UpperChannel = pAd->CommonCfg.CentralChannel;
1686 LowerChannel = pAd->CommonCfg.Channel;
1687 }
1688 else
1689 {
1690 return;
1691 }
1692
1693 // Record channels that is below lower channel..
1694 if (LowerChannel > 1)
1695 {
1696 EChannel[0] = LowerChannel - 1;
1697 i = 1;
1698 if (LowerChannel > 2)
1699 {
1700 EChannel[1] = LowerChannel - 2;
1701 i = 2;
1702 if (LowerChannel > 3)
1703 {
1704 EChannel[2] = LowerChannel - 3;
1705 i = 3;
1706 }
1707 }
1708 }
1709 // Record channels that is between lower channel and upper channel.
1710 for (k = LowerChannel;k < UpperChannel;k++)
1711 {
1712 EChannel[i] = k;
1713 i++;
1714 }
1715 // Record channels that is above upper channel..
1716 if (LowerChannel < 11)
1717 {
1718 EChannel[i] = UpperChannel + 1;
1719 i++;
1720 if (LowerChannel < 10)
1721 {
1722 EChannel[i] = LowerChannel + 2;
1723 i++;
1724 if (LowerChannel < 9)
1725 {
1726 EChannel[i] = LowerChannel + 3;
1727 i++;
1728 }
1729 }
1730 }
1731 //
1732 for (j = 0;j < i;j++)
1733 {
1734 for (k = 0;k < pAd->ChannelListNum;k++)
1735 {
1736 if (pAd->ChannelList[k].Channel == EChannel[j])
1737 {
1738 pAd->ChannelList[k].bEffectedChannel = TRUE;
1739 DBGPRINT(RT_DEBUG_TRACE,(" EffectedChannel( =%d)\n", EChannel[j]));
1740 break;
1741 }
1742 }
1743 }
1744}
1745#endif // DOT11N_DRAFT3 //
1746#endif // DOT11_N_SUPPORT //
1747
1748BOOLEAN ScanRunning(
1749 IN PRTMP_ADAPTER pAd)
1750{
1751 return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;
1752}
1753
diff --git a/drivers/staging/rt2870/sta/wpa.c b/drivers/staging/rt2870/sta/wpa.c
new file mode 100644
index 00000000000..8626dcde605
--- /dev/null
+++ b/drivers/staging/rt2870/sta/wpa.c
@@ -0,0 +1,2107 @@
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 else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
1389 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64;
1390 else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
1391 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128;
1392
1393 //hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
1394 }
1395
1396 // Update group key information to ASIC Shared Key Table
1397 AsicAddSharedKeyEntry(pAd,
1398 BSS0,
1399 pAd->StaCfg.DefaultKeyId,
1400 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1401 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
1402 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
1403 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
1404
1405 // Update ASIC WCID attribute table and IVEIV table
1406 RTMPAddWcidAttributeEntry(pAd,
1407 BSS0,
1408 pAd->StaCfg.DefaultKeyId,
1409 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1410 NULL);
1411
1412 // set 802.1x port control
1413 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1414 STA_PORT_SECURED(pAd);
1415
1416 // Indicate Connected for GUI
1417 pAd->IndicateMediaState = NdisMediaStateConnected;
1418
1419 // init header and Fill Packet
1420 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1421
1422 // Zero Group message 1 body
1423 NdisZeroMemory(&Packet, sizeof(Packet));
1424 Packet.ProVer = EAPOL_VER;
1425 Packet.ProType = EAPOLKey;
1426 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
1427
1428 //
1429 // Group Message 2 as EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
1430 //
1431 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1432 {
1433 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1434 }
1435 else
1436 {
1437 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1438 }
1439
1440 // Key descriptor version and appropriate RSN IE
1441 Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
1442
1443 // Update Key Length
1444 Packet.KeyDesc.KeyLength[0] = pGroup->KeyDesc.KeyLength[0];
1445 Packet.KeyDesc.KeyLength[1] = pGroup->KeyDesc.KeyLength[1];
1446
1447 // Key Index as G-Msg 1
1448 if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
1449 Packet.KeyDesc.KeyInfo.KeyIndex = peerKeyInfo.KeyIndex;
1450
1451 // Key Type Group key
1452 Packet.KeyDesc.KeyInfo.KeyType = GROUPKEY;
1453
1454 // KeyMic field presented
1455 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1456
1457 // Secure bit
1458 Packet.KeyDesc.KeyInfo.Secure = 1;
1459
1460 // Convert to little-endian format.
1461 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
1462
1463 // Key Replay count
1464 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1465
1466 // Out buffer for transmitting group message 2
1467 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
1468 if(pOutBuffer == NULL)
1469 {
1470 MlmeFreeMemory(pAd, (PUCHAR)mpool);
1471 return;
1472 }
1473
1474 // Prepare EAPOL frame for MIC calculation
1475 // Be careful, only EAPOL frame is counted for MIC calculation
1476 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1477 Packet.Body_Len[1] + 4, &Packet,
1478 END_OF_ARGS);
1479
1480 // Prepare and Fill MIC value
1481 NdisZeroMemory(Mic, sizeof(Mic));
1482 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1483 {
1484 // AES
1485 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
1486 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1487 }
1488 else
1489 {
1490 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1491 }
1492 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1493
1494
1495 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1496 LENGTH_802_3, &Header802_3,
1497 Packet.Body_Len[1] + 4, &Packet,
1498 END_OF_ARGS);
1499
1500
1501 // 5. Copy frame to Tx ring and prepare for encryption
1502 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
1503
1504 // 6 Free allocated memory
1505 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
1506 os_free_mem(pAd, (PUCHAR)mpool);
1507
1508 // send wireless event - for set key done WPA2
1509 if (pAd->CommonCfg.bWirelessEvent)
1510 RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1511
1512 DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action <-----\n"));
1513}
1514
1515/*
1516 ========================================================================
1517
1518 Routine Description:
1519 Init WPA MAC header
1520
1521 Arguments:
1522 pAd Pointer to our adapter
1523
1524 Return Value:
1525 None
1526
1527 Note:
1528
1529 ========================================================================
1530*/
1531VOID WpaMacHeaderInit(
1532 IN PRTMP_ADAPTER pAd,
1533 IN OUT PHEADER_802_11 pHdr80211,
1534 IN UCHAR wep,
1535 IN PUCHAR pAddr1)
1536{
1537 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
1538 pHdr80211->FC.Type = BTYPE_DATA;
1539 pHdr80211->FC.ToDs = 1;
1540 if (wep == 1)
1541 pHdr80211->FC.Wep = 1;
1542
1543 // Addr1: BSSID, Addr2: SA, Addr3: DA
1544 COPY_MAC_ADDR(pHdr80211->Addr1, pAddr1);
1545 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
1546 COPY_MAC_ADDR(pHdr80211->Addr3, pAd->CommonCfg.Bssid);
1547 pHdr80211->Sequence = pAd->Sequence;
1548}
1549
1550/*
1551 ========================================================================
1552
1553 Routine Description:
1554 Copy frame from waiting queue into relative ring buffer and set
1555 appropriate ASIC register to kick hardware encryption before really
1556 sent out to air.
1557
1558 Arguments:
1559 pAd Pointer to our adapter
1560 PNDIS_PACKET Pointer to outgoing Ndis frame
1561 NumberOfFrag Number of fragment required
1562
1563 Return Value:
1564 None
1565
1566 Note:
1567
1568 ========================================================================
1569*/
1570VOID RTMPToWirelessSta(
1571 IN PRTMP_ADAPTER pAd,
1572 IN PUCHAR pHeader802_3,
1573 IN UINT HdrLen,
1574 IN PUCHAR pData,
1575 IN UINT DataLen,
1576 IN BOOLEAN is4wayFrame)
1577
1578{
1579 NDIS_STATUS Status;
1580 PNDIS_PACKET pPacket;
1581 UCHAR Index;
1582
1583 do
1584 {
1585 // 1. build a NDIS packet and call RTMPSendPacket();
1586 // be careful about how/when to release this internal allocated NDIS PACKET buffer
1587 Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
1588 if (Status != NDIS_STATUS_SUCCESS)
1589 break;
1590
1591 if (is4wayFrame)
1592 RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
1593 else
1594 RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
1595
1596 // 2. send out the packet
1597 Status = STASendPacket(pAd, pPacket);
1598 if(Status == NDIS_STATUS_SUCCESS)
1599 {
1600 // Dequeue one frame from TxSwQueue0..3 queue and process it
1601 // There are three place calling dequeue for TX ring.
1602 // 1. Here, right after queueing the frame.
1603 // 2. At the end of TxRingTxDone service routine.
1604 // 3. Upon NDIS call RTMPSendPackets
1605 if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
1606 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
1607 {
1608 for(Index = 0; Index < 5; Index ++)
1609 if(pAd->TxSwQueue[Index].Number > 0)
1610 RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS);
1611 }
1612 }
1613 } while(FALSE);
1614
1615}
1616
1617/*
1618 ========================================================================
1619
1620 Routine Description:
1621 Check Sanity RSN IE form AP
1622
1623 Arguments:
1624
1625 Return Value:
1626
1627
1628 ========================================================================
1629*/
1630BOOLEAN CheckRSNIE(
1631 IN PRTMP_ADAPTER pAd,
1632 IN PUCHAR pData,
1633 IN UCHAR DataLen,
1634 OUT UCHAR *Offset)
1635{
1636 PUCHAR pVIE;
1637 UCHAR len;
1638 PEID_STRUCT pEid;
1639 BOOLEAN result = FALSE;
1640
1641 pVIE = pData;
1642 len = DataLen;
1643 *Offset = 0;
1644
1645 while (len > sizeof(RSNIE2))
1646 {
1647 pEid = (PEID_STRUCT) pVIE;
1648 // WPA RSN IE
1649 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
1650 {
1651 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) &&
1652 (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
1653 (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
1654 {
1655 DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA/WPAPSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
1656 result = TRUE;
1657 }
1658
1659 *Offset += (pEid->Len + 2);
1660 }
1661 // WPA2 RSN IE
1662 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
1663 {
1664 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) &&
1665 (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
1666 (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
1667 {
1668 DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
1669 result = TRUE;
1670 }
1671
1672 *Offset += (pEid->Len + 2);
1673 }
1674 else
1675 {
1676 break;
1677 }
1678
1679 pVIE += (pEid->Len + 2);
1680 len -= (pEid->Len + 2);
1681 }
1682
1683 DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> skip_offset(%d) \n", *Offset));
1684
1685 return result;
1686
1687}
1688
1689
1690/*
1691 ========================================================================
1692
1693 Routine Description:
1694 Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
1695 GTK is encaptulated in KDE format at p.83 802.11i D10
1696
1697 Arguments:
1698
1699 Return Value:
1700
1701 Note:
1702 802.11i D10
1703
1704 ========================================================================
1705*/
1706BOOLEAN ParseKeyData(
1707 IN PRTMP_ADAPTER pAd,
1708 IN PUCHAR pKeyData,
1709 IN UCHAR KeyDataLen,
1710 IN UCHAR bPairewise)
1711{
1712 PKDE_ENCAP pKDE = NULL;
1713 PUCHAR pMyKeyData = pKeyData;
1714 UCHAR KeyDataLength = KeyDataLen;
1715 UCHAR GTKLEN;
1716 UCHAR skip_offset;
1717
1718 // Verify The RSN IE contained in Pairewise-Msg 3 and skip it
1719 if (bPairewise)
1720 {
1721 // Check RSN IE whether it is WPA2/WPA2PSK
1722 if (!CheckRSNIE(pAd, pKeyData, KeyDataLen, &skip_offset))
1723 {
1724 DBGPRINT(RT_DEBUG_ERROR, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE mismatched \n"));
1725 hex_dump("Get KEYDATA :", pKeyData, KeyDataLen);
1726 return FALSE;
1727 }
1728 else
1729 {
1730 // skip RSN IE
1731 pMyKeyData += skip_offset;
1732 KeyDataLength -= skip_offset;
1733
1734 //DBGPRINT(RT_DEBUG_TRACE, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
1735 }
1736 }
1737
1738 DBGPRINT(RT_DEBUG_TRACE,("ParseKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
1739
1740 // Parse EKD format
1741 if (KeyDataLength >= 8)
1742 {
1743 pKDE = (PKDE_ENCAP) pMyKeyData;
1744 }
1745 else
1746 {
1747 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KeyDataLength is too short \n"));
1748 return FALSE;
1749 }
1750
1751
1752 // Sanity check - shared key index should not be 0
1753 if (pKDE->GTKEncap.Kid == 0)
1754 {
1755 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index zero \n"));
1756 return FALSE;
1757 }
1758
1759 // Sanity check - KED length
1760 if (KeyDataLength < (pKDE->Len + 2))
1761 {
1762 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
1763 return FALSE;
1764 }
1765
1766 // Get GTK length - refer to IEEE 802.11i-2004 p.82
1767 GTKLEN = pKDE->Len -6;
1768
1769 if (GTKLEN < MIN_LEN_OF_GTK)
1770 {
1771 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
1772 return FALSE;
1773 }
1774 else
1775 DBGPRINT(RT_DEBUG_TRACE, ("GTK Key with KDE formet got index=%d, len=%d \n", pKDE->GTKEncap.Kid, GTKLEN));
1776
1777 // Update GTK
1778 // set key material, TxMic and RxMic for WPAPSK
1779 NdisMoveMemory(pAd->StaCfg.GTK, pKDE->GTKEncap.GTK, 32);
1780 pAd->StaCfg.DefaultKeyId = pKDE->GTKEncap.Kid;
1781
1782 // Update shared key table
1783 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
1784 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
1785 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKDE->GTKEncap.GTK, LEN_TKIP_EK);
1786 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &pKDE->GTKEncap.GTK[16], LEN_TKIP_RXMICK);
1787 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &pKDE->GTKEncap.GTK[24], LEN_TKIP_TXMICK);
1788
1789 // Update Shared Key CipherAlg
1790 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
1791 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
1792 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
1793 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
1794 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
1795 else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
1796 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64;
1797 else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
1798 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128;
1799
1800 return TRUE;
1801
1802}
1803
1804/*
1805 ========================================================================
1806
1807 Routine Description:
1808 Cisco CCKM PRF function
1809
1810 Arguments:
1811 key Cisco Base Transient Key (BTK)
1812 key_len The key length of the BTK
1813 data Ruquest Number(RN) + BSSID
1814 data_len The length of the data
1815 output Store for PTK(Pairwise transient keys)
1816 len The length of the output
1817 Return Value:
1818 None
1819
1820 Note:
1821 802.1i Annex F.9
1822
1823 ========================================================================
1824*/
1825VOID CCKMPRF(
1826 IN UCHAR *key,
1827 IN INT key_len,
1828 IN UCHAR *data,
1829 IN INT data_len,
1830 OUT UCHAR *output,
1831 IN INT len)
1832{
1833 INT i;
1834 UCHAR input[1024];
1835 INT currentindex = 0;
1836 INT total_len;
1837
1838 NdisMoveMemory(input, data, data_len);
1839 total_len = data_len;
1840 input[total_len] = 0;
1841 total_len++;
1842 for (i = 0; i < (len + 19) / 20; i++)
1843 {
1844 HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
1845 currentindex += 20;
1846 input[total_len - 1]++;
1847 }
1848}
1849
1850/*
1851 ========================================================================
1852
1853 Routine Description:
1854 Process MIC error indication and record MIC error timer.
1855
1856 Arguments:
1857 pAd Pointer to our adapter
1858 pWpaKey Pointer to the WPA key structure
1859
1860 Return Value:
1861 None
1862
1863 IRQL = DISPATCH_LEVEL
1864
1865 Note:
1866
1867 ========================================================================
1868*/
1869VOID RTMPReportMicError(
1870 IN PRTMP_ADAPTER pAd,
1871 IN PCIPHER_KEY pWpaKey)
1872{
1873 ULONG Now;
1874 UCHAR unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0);
1875
1876 // Record Last MIC error time and count
1877 Now = jiffies;
1878 if (pAd->StaCfg.MicErrCnt == 0)
1879 {
1880 pAd->StaCfg.MicErrCnt++;
1881 pAd->StaCfg.LastMicErrorTime = Now;
1882 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1883 }
1884 else if (pAd->StaCfg.MicErrCnt == 1)
1885 {
1886 if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now)
1887 {
1888 // Update Last MIC error time, this did not violate two MIC errors within 60 seconds
1889 pAd->StaCfg.LastMicErrorTime = Now;
1890 }
1891 else
1892 {
1893
1894 if (pAd->CommonCfg.bWirelessEvent)
1895 RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1896
1897 pAd->StaCfg.LastMicErrorTime = Now;
1898 // Violate MIC error counts, MIC countermeasures kicks in
1899 pAd->StaCfg.MicErrCnt++;
1900 // We shall block all reception
1901 // We shall clean all Tx ring and disassoicate from AP after next EAPOL frame
1902 //
1903 // No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets
1904 // if pAd->StaCfg.MicErrCnt greater than 2.
1905 //
1906 // RTMPRingCleanUp(pAd, QID_AC_BK);
1907 // RTMPRingCleanUp(pAd, QID_AC_BE);
1908 // RTMPRingCleanUp(pAd, QID_AC_VI);
1909 // RTMPRingCleanUp(pAd, QID_AC_VO);
1910 // RTMPRingCleanUp(pAd, QID_HCCA);
1911 }
1912 }
1913 else
1914 {
1915 // MIC error count >= 2
1916 // This should not happen
1917 ;
1918 }
1919 MlmeEnqueue(pAd,
1920 MLME_CNTL_STATE_MACHINE,
1921 OID_802_11_MIC_FAILURE_REPORT_FRAME,
1922 1,
1923 &unicastKey);
1924
1925 if (pAd->StaCfg.MicErrCnt == 2)
1926 {
1927 RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
1928 }
1929}
1930
1931
1932#ifdef WPA_SUPPLICANT_SUPPORT
1933#define LENGTH_EAP_H 4
1934// If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)).
1935INT WpaCheckEapCode(
1936 IN PRTMP_ADAPTER pAd,
1937 IN PUCHAR pFrame,
1938 IN USHORT FrameLen,
1939 IN USHORT OffSet)
1940{
1941
1942 PUCHAR pData;
1943 INT result = 0;
1944
1945 if( FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H )
1946 return result;
1947
1948 pData = pFrame + OffSet; // skip offset bytes
1949
1950 if(*(pData+1) == EAPPacket) // 802.1x header - Packet Type
1951 {
1952 result = *(pData+4); // EAP header - Code
1953 }
1954
1955 return result;
1956}
1957
1958VOID WpaSendMicFailureToWpaSupplicant(
1959 IN PRTMP_ADAPTER pAd,
1960 IN BOOLEAN bUnicast)
1961{
1962 union iwreq_data wrqu;
1963 char custom[IW_CUSTOM_MAX] = {0};
1964
1965 sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
1966 if (bUnicast)
1967 sprintf(custom, "%s unicast", custom);
1968 wrqu.data.length = strlen(custom);
1969 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
1970
1971 return;
1972}
1973#endif // WPA_SUPPLICANT_SUPPORT //
1974
1975VOID WpaMicFailureReportFrame(
1976 IN PRTMP_ADAPTER pAd,
1977 IN MLME_QUEUE_ELEM *Elem)
1978{
1979 PUCHAR pOutBuffer = NULL;
1980 UCHAR Header802_3[14];
1981 ULONG FrameLen = 0;
1982 EAPOL_PACKET Packet;
1983 UCHAR Mic[16];
1984 BOOLEAN bUnicast;
1985
1986 DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));
1987
1988 bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
1989 pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
1990
1991 // init 802.3 header and Fill Packet
1992 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1993
1994 NdisZeroMemory(&Packet, sizeof(Packet));
1995 Packet.ProVer = EAPOL_VER;
1996 Packet.ProType = EAPOLKey;
1997
1998 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1999
2000 // Request field presented
2001 Packet.KeyDesc.KeyInfo.Request = 1;
2002
2003 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
2004 {
2005 Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
2006 }
2007 else // TKIP
2008 {
2009 Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
2010 }
2011
2012 Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
2013
2014 // KeyMic field presented
2015 Packet.KeyDesc.KeyInfo.KeyMic = 1;
2016
2017 // Error field presented
2018 Packet.KeyDesc.KeyInfo.Error = 1;
2019
2020 // Update packet length after decide Key data payload
2021 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;
2022
2023 // Key Replay Count
2024 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
2025 inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
2026
2027 // Convert to little-endian format.
2028 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
2029
2030
2031 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
2032 if(pOutBuffer == NULL)
2033 {
2034 return;
2035 }
2036
2037 // Prepare EAPOL frame for MIC calculation
2038 // Be careful, only EAPOL frame is counted for MIC calculation
2039 MakeOutgoingFrame(pOutBuffer, &FrameLen,
2040 Packet.Body_Len[1] + 4, &Packet,
2041 END_OF_ARGS);
2042
2043 // Prepare and Fill MIC value
2044 NdisZeroMemory(Mic, sizeof(Mic));
2045 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
2046 { // AES
2047 UCHAR digest[20] = {0};
2048 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
2049 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
2050 }
2051 else
2052 { // TKIP
2053 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
2054 }
2055 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
2056
2057 MakeOutgoingFrame(pOutBuffer, &FrameLen,
2058 LENGTH_802_3, &Header802_3,
2059 Packet.Body_Len[1] + 4, &Packet,
2060 END_OF_ARGS);
2061
2062 // opy frame to Tx ring and send MIC failure report frame to authenticator
2063 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
2064
2065 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
2066
2067 DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
2068}
2069
2070/** from wpa_supplicant
2071 * inc_byte_array - Increment arbitrary length byte array by one
2072 * @counter: Pointer to byte array
2073 * @len: Length of the counter in bytes
2074 *
2075 * This function increments the last byte of the counter by one and continues
2076 * rolling over to more significant bytes if the byte was incremented from
2077 * 0xff to 0x00.
2078 */
2079void inc_byte_array(UCHAR *counter, int len)
2080{
2081 int pos = len - 1;
2082 while (pos >= 0) {
2083 counter[pos]++;
2084 if (counter[pos] != 0)
2085 break;
2086 pos--;
2087 }
2088}
2089
2090VOID WpaDisassocApAndBlockAssoc(
2091 IN PVOID SystemSpecific1,
2092 IN PVOID FunctionContext,
2093 IN PVOID SystemSpecific2,
2094 IN PVOID SystemSpecific3)
2095{
2096 RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext;
2097 MLME_DISASSOC_REQ_STRUCT DisassocReq;
2098
2099 // disassoc from current AP first
2100 DBGPRINT(RT_DEBUG_TRACE, ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
2101 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_MIC_FAILURE);
2102 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
2103
2104 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
2105 pAd->StaCfg.bBlockAssoc = TRUE;
2106}
2107
diff --git a/drivers/staging/rt2870/sta_ioctl.c b/drivers/staging/rt2870/sta_ioctl.c
new file mode 100644
index 00000000000..bb386ab64c1
--- /dev/null
+++ b/drivers/staging/rt2870/sta_ioctl.c
@@ -0,0 +1,7068 @@
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
52#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
53#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_A, _B, _C, _D, _E)
54#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_A, _B, _C, _D, _E)
55#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_A, _B, _C, _D, _E, _F)
56#else
57#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_B, _C, _D, _E)
58#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_B, _C, _D, _E)
59#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_B, _C, _D, _E, _F)
60#endif
61
62extern UCHAR CipherWpa2Template[];
63extern UCHAR CipherWpaPskTkip[];
64extern UCHAR CipherWpaPskTkipLen;
65
66typedef struct PACKED _RT_VERSION_INFO{
67 UCHAR DriverVersionW;
68 UCHAR DriverVersionX;
69 UCHAR DriverVersionY;
70 UCHAR DriverVersionZ;
71 UINT DriverBuildYear;
72 UINT DriverBuildMonth;
73 UINT DriverBuildDay;
74} RT_VERSION_INFO, *PRT_VERSION_INFO;
75
76struct iw_priv_args privtab[] = {
77{ RTPRIV_IOCTL_SET,
78 IW_PRIV_TYPE_CHAR | 1024, 0,
79 "set"},
80
81{ RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
82 ""},
83{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
84 ""},
85/* --- sub-ioctls definitions --- */
86 { SHOW_CONN_STATUS,
87 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
88 { SHOW_DRVIER_VERION,
89 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
90 { SHOW_BA_INFO,
91 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
92 { SHOW_DESC_INFO,
93 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
94 { RAIO_OFF,
95 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
96 { RAIO_ON,
97 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
98#ifdef QOS_DLS_SUPPORT
99 { SHOW_DLS_ENTRY_INFO,
100 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "dlsentryinfo" },
101#endif // QOS_DLS_SUPPORT //
102 { SHOW_CFG_VALUE,
103 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
104 { SHOW_ADHOC_ENTRY_INFO,
105 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "adhocEntry" },
106
107/* --- sub-ioctls relations --- */
108
109#ifdef DBG
110{ RTPRIV_IOCTL_BBP,
111 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
112 "bbp"},
113{ RTPRIV_IOCTL_MAC,
114 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
115 "mac"},
116{ RTPRIV_IOCTL_E2P,
117 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
118 "e2p"},
119#endif /* DBG */
120
121{ RTPRIV_IOCTL_STATISTICS,
122 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
123 "stat"},
124{ RTPRIV_IOCTL_GSITESURVEY,
125 0, IW_PRIV_TYPE_CHAR | 1024,
126 "get_site_survey"},
127};
128
129INT Set_SSID_Proc(
130 IN PRTMP_ADAPTER pAdapter,
131 IN PUCHAR arg);
132
133#ifdef WMM_SUPPORT
134INT Set_WmmCapable_Proc(
135 IN PRTMP_ADAPTER pAd,
136 IN PUCHAR arg);
137#endif
138
139INT Set_NetworkType_Proc(
140 IN PRTMP_ADAPTER pAdapter,
141 IN PUCHAR arg);
142
143INT Set_AuthMode_Proc(
144 IN PRTMP_ADAPTER pAdapter,
145 IN PUCHAR arg);
146
147INT Set_EncrypType_Proc(
148 IN PRTMP_ADAPTER pAdapter,
149 IN PUCHAR arg);
150
151INT Set_DefaultKeyID_Proc(
152 IN PRTMP_ADAPTER pAdapter,
153 IN PUCHAR arg);
154
155INT Set_Key1_Proc(
156 IN PRTMP_ADAPTER pAdapter,
157 IN PUCHAR arg);
158
159INT Set_Key2_Proc(
160 IN PRTMP_ADAPTER pAdapter,
161 IN PUCHAR arg);
162
163INT Set_Key3_Proc(
164 IN PRTMP_ADAPTER pAdapter,
165 IN PUCHAR arg);
166
167INT Set_Key4_Proc(
168 IN PRTMP_ADAPTER pAdapter,
169 IN PUCHAR arg);
170
171INT Set_WPAPSK_Proc(
172 IN PRTMP_ADAPTER pAdapter,
173 IN PUCHAR arg);
174
175
176INT Set_PSMode_Proc(
177 IN PRTMP_ADAPTER pAdapter,
178 IN PUCHAR arg);
179
180#ifdef WPA_SUPPLICANT_SUPPORT
181INT Set_Wpa_Support(
182 IN PRTMP_ADAPTER pAd,
183 IN PUCHAR arg);
184#endif // WPA_SUPPLICANT_SUPPORT //
185
186#ifdef DBG
187VOID RTMPIoctlBBP(
188 IN PRTMP_ADAPTER pAdapter,
189 IN struct iwreq *wrq);
190
191VOID RTMPIoctlMAC(
192 IN PRTMP_ADAPTER pAdapter,
193 IN struct iwreq *wrq);
194
195VOID RTMPIoctlE2PROM(
196 IN PRTMP_ADAPTER pAdapter,
197 IN struct iwreq *wrq);
198#endif // DBG //
199
200
201NDIS_STATUS RTMPWPANoneAddKeyProc(
202 IN PRTMP_ADAPTER pAd,
203 IN PVOID pBuf);
204
205INT Set_FragTest_Proc(
206 IN PRTMP_ADAPTER pAdapter,
207 IN PUCHAR arg);
208
209#ifdef DOT11_N_SUPPORT
210INT Set_TGnWifiTest_Proc(
211 IN PRTMP_ADAPTER pAd,
212 IN PUCHAR arg);
213#endif // DOT11_N_SUPPORT //
214
215INT Set_LongRetryLimit_Proc(
216 IN PRTMP_ADAPTER pAdapter,
217 IN PUCHAR arg);
218
219INT Set_ShortRetryLimit_Proc(
220 IN PRTMP_ADAPTER pAdapter,
221 IN PUCHAR arg);
222
223#ifdef EXT_BUILD_CHANNEL_LIST
224INT Set_Ieee80211dClientMode_Proc(
225 IN PRTMP_ADAPTER pAdapter,
226 IN PUCHAR arg);
227#endif // EXT_BUILD_CHANNEL_LIST //
228
229#ifdef CARRIER_DETECTION_SUPPORT
230INT Set_CarrierDetect_Proc(
231 IN PRTMP_ADAPTER pAd,
232 IN PUCHAR arg);
233#endif // CARRIER_DETECTION_SUPPORT //
234
235INT Show_Adhoc_MacTable_Proc(
236 IN PRTMP_ADAPTER pAd,
237 IN PCHAR extra);
238
239static struct {
240 CHAR *name;
241 INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
242} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
243 {"DriverVersion", Set_DriverVersion_Proc},
244 {"CountryRegion", Set_CountryRegion_Proc},
245 {"CountryRegionABand", Set_CountryRegionABand_Proc},
246 {"SSID", Set_SSID_Proc},
247 {"WirelessMode", Set_WirelessMode_Proc},
248 {"TxBurst", Set_TxBurst_Proc},
249 {"TxPreamble", Set_TxPreamble_Proc},
250 {"TxPower", Set_TxPower_Proc},
251 {"Channel", Set_Channel_Proc},
252 {"BGProtection", Set_BGProtection_Proc},
253 {"RTSThreshold", Set_RTSThreshold_Proc},
254 {"FragThreshold", Set_FragThreshold_Proc},
255#ifdef DOT11_N_SUPPORT
256 {"HtBw", Set_HtBw_Proc},
257 {"HtMcs", Set_HtMcs_Proc},
258 {"HtGi", Set_HtGi_Proc},
259 {"HtOpMode", Set_HtOpMode_Proc},
260 {"HtExtcha", Set_HtExtcha_Proc},
261 {"HtMpduDensity", Set_HtMpduDensity_Proc},
262 {"HtBaWinSize", Set_HtBaWinSize_Proc},
263 {"HtRdg", Set_HtRdg_Proc},
264 {"HtAmsdu", Set_HtAmsdu_Proc},
265 {"HtAutoBa", Set_HtAutoBa_Proc},
266 {"HtBaDecline", Set_BADecline_Proc},
267 {"HtProtect", Set_HtProtect_Proc},
268 {"HtMimoPs", Set_HtMimoPs_Proc},
269#endif // DOT11_N_SUPPORT //
270
271#ifdef AGGREGATION_SUPPORT
272 {"PktAggregate", Set_PktAggregate_Proc},
273#endif
274
275#ifdef WMM_SUPPORT
276 {"WmmCapable", Set_WmmCapable_Proc},
277#endif
278 {"IEEE80211H", Set_IEEE80211H_Proc},
279 {"NetworkType", Set_NetworkType_Proc},
280 {"AuthMode", Set_AuthMode_Proc},
281 {"EncrypType", Set_EncrypType_Proc},
282 {"DefaultKeyID", Set_DefaultKeyID_Proc},
283 {"Key1", Set_Key1_Proc},
284 {"Key2", Set_Key2_Proc},
285 {"Key3", Set_Key3_Proc},
286 {"Key4", Set_Key4_Proc},
287 {"WPAPSK", Set_WPAPSK_Proc},
288 {"ResetCounter", Set_ResetStatCounter_Proc},
289 {"PSMode", Set_PSMode_Proc},
290#ifdef DBG
291 {"Debug", Set_Debug_Proc},
292#endif
293
294#ifdef RALINK_ATE
295 {"ATE", Set_ATE_Proc},
296 {"ATEDA", Set_ATE_DA_Proc},
297 {"ATESA", Set_ATE_SA_Proc},
298 {"ATEBSSID", Set_ATE_BSSID_Proc},
299 {"ATECHANNEL", Set_ATE_CHANNEL_Proc},
300 {"ATETXPOW0", Set_ATE_TX_POWER0_Proc},
301 {"ATETXPOW1", Set_ATE_TX_POWER1_Proc},
302 {"ATETXANT", Set_ATE_TX_Antenna_Proc},
303 {"ATERXANT", Set_ATE_RX_Antenna_Proc},
304 {"ATETXFREQOFFSET", Set_ATE_TX_FREQOFFSET_Proc},
305 {"ATETXBW", Set_ATE_TX_BW_Proc},
306 {"ATETXLEN", Set_ATE_TX_LENGTH_Proc},
307 {"ATETXCNT", Set_ATE_TX_COUNT_Proc},
308 {"ATETXMCS", Set_ATE_TX_MCS_Proc},
309 {"ATETXMODE", Set_ATE_TX_MODE_Proc},
310 {"ATETXGI", Set_ATE_TX_GI_Proc},
311 {"ATERXFER", Set_ATE_RX_FER_Proc},
312 {"ATERRF", Set_ATE_Read_RF_Proc},
313 {"ATEWRF1", Set_ATE_Write_RF1_Proc},
314 {"ATEWRF2", Set_ATE_Write_RF2_Proc},
315 {"ATEWRF3", Set_ATE_Write_RF3_Proc},
316 {"ATEWRF4", Set_ATE_Write_RF4_Proc},
317 {"ATELDE2P", Set_ATE_Load_E2P_Proc},
318 {"ATERE2P", Set_ATE_Read_E2P_Proc},
319 {"ATESHOW", Set_ATE_Show_Proc},
320 {"ATEHELP", Set_ATE_Help_Proc},
321
322#ifdef RALINK_28xx_QA
323 {"TxStop", Set_TxStop_Proc},
324 {"RxStop", Set_RxStop_Proc},
325#endif // RALINK_28xx_QA //
326#endif // RALINK_ATE //
327
328#ifdef WPA_SUPPLICANT_SUPPORT
329 {"WpaSupport", Set_Wpa_Support},
330#endif // WPA_SUPPLICANT_SUPPORT //
331
332
333
334 {"FixedTxMode", Set_FixedTxMode_Proc},
335#ifdef CONFIG_APSTA_MIXED_SUPPORT
336 {"OpMode", Set_OpMode_Proc},
337#endif // CONFIG_APSTA_MIXED_SUPPORT //
338#ifdef DOT11_N_SUPPORT
339 {"TGnWifiTest", Set_TGnWifiTest_Proc},
340 {"ForceGF", Set_ForceGF_Proc},
341#endif // DOT11_N_SUPPORT //
342#ifdef QOS_DLS_SUPPORT
343 {"DlsAddEntry", Set_DlsAddEntry_Proc},
344 {"DlsTearDownEntry", Set_DlsTearDownEntry_Proc},
345#endif // QOS_DLS_SUPPORT //
346 {"LongRetry", Set_LongRetryLimit_Proc},
347 {"ShortRetry", Set_ShortRetryLimit_Proc},
348#ifdef EXT_BUILD_CHANNEL_LIST
349 {"11dClientMode", Set_Ieee80211dClientMode_Proc},
350#endif // EXT_BUILD_CHANNEL_LIST //
351#ifdef CARRIER_DETECTION_SUPPORT
352 {"CarrierDetect", Set_CarrierDetect_Proc},
353#endif // CARRIER_DETECTION_SUPPORT //
354
355 {NULL,}
356};
357
358
359VOID RTMPAddKey(
360 IN PRTMP_ADAPTER pAd,
361 IN PNDIS_802_11_KEY pKey)
362{
363 ULONG KeyIdx;
364 MAC_TABLE_ENTRY *pEntry;
365
366 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
367
368 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
369 {
370 if (pKey->KeyIndex & 0x80000000)
371 {
372 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
373 {
374 NdisZeroMemory(pAd->StaCfg.PMK, 32);
375 NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
376 goto end;
377 }
378 // Update PTK
379 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
380 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
381 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
382#ifdef WPA_SUPPLICANT_SUPPORT
383 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
384 {
385 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
386 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
387 }
388 else
389#endif // WPA_SUPPLICANT_SUPPORT //
390 {
391 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
392 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
393 }
394
395 // Decide its ChiperAlg
396 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
397 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
398 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
399 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
400 else
401 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
402
403 // Update these related information to MAC_TABLE_ENTRY
404 pEntry = &pAd->MacTab.Content[BSSID_WCID];
405 NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
406 NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
407 NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
408 pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
409
410 // Update pairwise key information to ASIC Shared Key Table
411 AsicAddSharedKeyEntry(pAd,
412 BSS0,
413 0,
414 pAd->SharedKey[BSS0][0].CipherAlg,
415 pAd->SharedKey[BSS0][0].Key,
416 pAd->SharedKey[BSS0][0].TxMic,
417 pAd->SharedKey[BSS0][0].RxMic);
418
419 // Update ASIC WCID attribute table and IVEIV table
420 RTMPAddWcidAttributeEntry(pAd,
421 BSS0,
422 0,
423 pAd->SharedKey[BSS0][0].CipherAlg,
424 pEntry);
425
426 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
427 {
428 // set 802.1x port control
429 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
430 STA_PORT_SECURED(pAd);
431
432 // Indicate Connected for GUI
433 pAd->IndicateMediaState = NdisMediaStateConnected;
434 }
435 }
436 else
437 {
438 // Update GTK
439 pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
440 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
441 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
442 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
443#ifdef WPA_SUPPLICANT_SUPPORT
444 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
445 {
446 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
447 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
448 }
449 else
450#endif // WPA_SUPPLICANT_SUPPORT //
451 {
452 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
453 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
454 }
455
456 // Update Shared Key CipherAlg
457 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
458 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
459 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
460 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
461 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
462
463 // Update group key information to ASIC Shared Key Table
464 AsicAddSharedKeyEntry(pAd,
465 BSS0,
466 pAd->StaCfg.DefaultKeyId,
467 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
468 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
469 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
470 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
471
472 // Update ASIC WCID attribute table and IVEIV table
473 RTMPAddWcidAttributeEntry(pAd,
474 BSS0,
475 pAd->StaCfg.DefaultKeyId,
476 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
477 NULL);
478
479 // set 802.1x port control
480 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
481 STA_PORT_SECURED(pAd);
482
483 // Indicate Connected for GUI
484 pAd->IndicateMediaState = NdisMediaStateConnected;
485 }
486 }
487 else // dynamic WEP from wpa_supplicant
488 {
489 UCHAR CipherAlg;
490 PUCHAR Key;
491
492 if(pKey->KeyLength == 32)
493 goto end;
494
495 KeyIdx = pKey->KeyIndex & 0x0fffffff;
496
497 if (KeyIdx < 4)
498 {
499 // it is a default shared key, for Pairwise key setting
500 if (pKey->KeyIndex & 0x80000000)
501 {
502 pEntry = MacTableLookup(pAd, pKey->BSSID);
503
504 if (pEntry)
505 {
506 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
507
508 // set key material and key length
509 pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
510 NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
511
512 // set Cipher type
513 if (pKey->KeyLength == 5)
514 pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
515 else
516 pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
517
518 // Add Pair-wise key to Asic
519 AsicAddPairwiseKeyEntry(
520 pAd,
521 pEntry->Addr,
522 (UCHAR)pEntry->Aid,
523 &pEntry->PairwiseKey);
524
525 // update WCID attribute table and IVEIV table for this entry
526 RTMPAddWcidAttributeEntry(
527 pAd,
528 BSS0,
529 KeyIdx, // The value may be not zero
530 pEntry->PairwiseKey.CipherAlg,
531 pEntry);
532
533 }
534 }
535 else
536 {
537 // Default key for tx (shared key)
538 pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
539
540 // set key material and key length
541 pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
542 NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
543
544 // Set Ciper type
545 if (pKey->KeyLength == 5)
546 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
547 else
548 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
549
550 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
551 Key = pAd->SharedKey[BSS0][KeyIdx].Key;
552
553 // Set Group key material to Asic
554 AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
555
556 // Update WCID attribute table and IVEIV table for this group key table
557 RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
558
559 }
560 }
561 }
562end:
563 return;
564}
565
566char * rtstrchr(const char * s, int c)
567{
568 for(; *s != (char) c; ++s)
569 if (*s == '\0')
570 return NULL;
571 return (char *) s;
572}
573
574/*
575This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
576*/
577
578int
579rt_ioctl_giwname(struct net_device *dev,
580 struct iw_request_info *info,
581 char *name, char *extra)
582{
583// PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
584
585#ifdef RT2870
586 strncpy(name, "RT2870 Wireless", IFNAMSIZ);
587#endif // RT2870 //
588 return 0;
589}
590
591int rt_ioctl_siwfreq(struct net_device *dev,
592 struct iw_request_info *info,
593 struct iw_freq *freq, char *extra)
594{
595 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
596 int chan = -1;
597
598 //check if the interface is down
599 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
600 {
601 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
602 return -ENETDOWN;
603 }
604
605
606 if (freq->e > 1)
607 return -EINVAL;
608
609 if((freq->e == 0) && (freq->m <= 1000))
610 chan = freq->m; // Setting by channel number
611 else
612 MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
613
614 if (ChannelSanity(pAdapter, chan) == TRUE)
615 {
616 pAdapter->CommonCfg.Channel = chan;
617 DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
618 }
619 else
620 return -EINVAL;
621
622 return 0;
623}
624int rt_ioctl_giwfreq(struct net_device *dev,
625 struct iw_request_info *info,
626 struct iw_freq *freq, char *extra)
627{
628 VIRTUAL_ADAPTER *pVirtualAd = NULL;
629 PRTMP_ADAPTER pAdapter = NULL;
630 UCHAR ch;
631 ULONG m;
632
633 if (dev->priv_flags == INT_MAIN)
634 {
635 pAdapter = dev->priv;
636 }
637 else
638 {
639 pVirtualAd = dev->priv;
640 if (pVirtualAd && pVirtualAd->RtmpDev)
641 pAdapter = pVirtualAd->RtmpDev->priv;
642 }
643
644 if (pAdapter == NULL)
645 {
646 /* if 1st open fail, pAd will be free;
647 So the net_dev->priv will be NULL in 2rd open */
648 return -ENETDOWN;
649 }
650
651 ch = pAdapter->CommonCfg.Channel;
652
653 DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq %d\n", ch));
654
655 MAP_CHANNEL_ID_TO_KHZ(ch, m);
656 freq->m = m * 100;
657 freq->e = 1;
658 return 0;
659}
660
661int rt_ioctl_siwmode(struct net_device *dev,
662 struct iw_request_info *info,
663 __u32 *mode, char *extra)
664{
665 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
666
667 //check if the interface is down
668 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
669 {
670 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
671 return -ENETDOWN;
672 }
673
674 switch (*mode)
675 {
676 case IW_MODE_ADHOC:
677 Set_NetworkType_Proc(pAdapter, "Adhoc");
678 break;
679 case IW_MODE_INFRA:
680 Set_NetworkType_Proc(pAdapter, "Infra");
681 break;
682#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
683 case IW_MODE_MONITOR:
684 Set_NetworkType_Proc(pAdapter, "Monitor");
685 break;
686#endif
687 default:
688 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
689 return -EINVAL;
690 }
691
692 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
693 pAdapter->StaCfg.WpaState = SS_NOTUSE;
694
695 return 0;
696}
697
698int rt_ioctl_giwmode(struct net_device *dev,
699 struct iw_request_info *info,
700 __u32 *mode, char *extra)
701{
702 PRTMP_ADAPTER pAdapter = NULL;
703 VIRTUAL_ADAPTER *pVirtualAd = NULL;
704
705 if (dev->priv_flags == INT_MAIN)
706 {
707 pAdapter = dev->priv;
708 }
709 else
710 {
711 pVirtualAd = dev->priv;
712 if (pVirtualAd && pVirtualAd->RtmpDev)
713 pAdapter = pVirtualAd->RtmpDev->priv;
714 }
715
716 if (pAdapter == NULL)
717 {
718 /* if 1st open fail, pAd will be free;
719 So the net_dev->priv will be NULL in 2rd open */
720 return -ENETDOWN;
721 }
722
723 if (ADHOC_ON(pAdapter))
724 *mode = IW_MODE_ADHOC;
725 else if (INFRA_ON(pAdapter))
726 *mode = IW_MODE_INFRA;
727#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
728 else if (MONITOR_ON(pAdapter))
729 {
730 *mode = IW_MODE_MONITOR;
731 }
732#endif
733 else
734 *mode = IW_MODE_AUTO;
735
736 DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
737 return 0;
738}
739
740int rt_ioctl_siwsens(struct net_device *dev,
741 struct iw_request_info *info,
742 char *name, char *extra)
743{
744 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
745
746 //check if the interface is down
747 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
748 {
749 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
750 return -ENETDOWN;
751 }
752
753 return 0;
754}
755
756int rt_ioctl_giwsens(struct net_device *dev,
757 struct iw_request_info *info,
758 char *name, char *extra)
759{
760 return 0;
761}
762
763int rt_ioctl_giwrange(struct net_device *dev,
764 struct iw_request_info *info,
765 struct iw_point *data, char *extra)
766{
767 PRTMP_ADAPTER pAdapter = NULL;
768 VIRTUAL_ADAPTER *pVirtualAd = NULL;
769 struct iw_range *range = (struct iw_range *) extra;
770 u16 val;
771 int i;
772
773 if (dev->priv_flags == INT_MAIN)
774 {
775 pAdapter = dev->priv;
776 }
777 else
778 {
779 pVirtualAd = dev->priv;
780 if (pVirtualAd && pVirtualAd->RtmpDev)
781 pAdapter = pVirtualAd->RtmpDev->priv;
782 }
783
784 if (pAdapter == NULL)
785 {
786 /* if 1st open fail, pAd will be free;
787 So the net_dev->priv will be NULL in 2rd open */
788 return -ENETDOWN;
789 }
790
791 DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
792 data->length = sizeof(struct iw_range);
793 memset(range, 0, sizeof(struct iw_range));
794
795 range->txpower_capa = IW_TXPOW_DBM;
796
797 if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
798 {
799 range->min_pmp = 1 * 1024;
800 range->max_pmp = 65535 * 1024;
801 range->min_pmt = 1 * 1024;
802 range->max_pmt = 1000 * 1024;
803 range->pmp_flags = IW_POWER_PERIOD;
804 range->pmt_flags = IW_POWER_TIMEOUT;
805 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
806 IW_POWER_UNICAST_R | IW_POWER_ALL_R;
807 }
808
809 range->we_version_compiled = WIRELESS_EXT;
810 range->we_version_source = 14;
811
812 range->retry_capa = IW_RETRY_LIMIT;
813 range->retry_flags = IW_RETRY_LIMIT;
814 range->min_retry = 0;
815 range->max_retry = 255;
816
817 range->num_channels = pAdapter->ChannelListNum;
818
819 val = 0;
820 for (i = 1; i <= range->num_channels; i++)
821 {
822 u32 m;
823 range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
824 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
825 range->freq[val].m = m * 100; /* HZ */
826
827 range->freq[val].e = 1;
828 val++;
829 if (val == IW_MAX_FREQUENCIES)
830 break;
831 }
832 range->num_frequency = val;
833
834 range->max_qual.qual = 100; /* what is correct max? This was not
835 * documented exactly. At least
836 * 69 has been observed. */
837 range->max_qual.level = 0; /* dB */
838 range->max_qual.noise = 0; /* dB */
839
840 /* What would be suitable values for "average/typical" qual? */
841 range->avg_qual.qual = 20;
842 range->avg_qual.level = -60;
843 range->avg_qual.noise = -95;
844 range->sensitivity = 3;
845
846 range->max_encoding_tokens = NR_WEP_KEYS;
847 range->num_encoding_sizes = 2;
848 range->encoding_size[0] = 5;
849 range->encoding_size[1] = 13;
850
851 range->min_rts = 0;
852 range->max_rts = 2347;
853 range->min_frag = 256;
854 range->max_frag = 2346;
855
856#if WIRELESS_EXT > 17
857 /* IW_ENC_CAPA_* bit field */
858 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
859 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
860#endif
861
862 return 0;
863}
864
865int rt_ioctl_siwap(struct net_device *dev,
866 struct iw_request_info *info,
867 struct sockaddr *ap_addr, char *extra)
868{
869 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
870 NDIS_802_11_MAC_ADDRESS Bssid;
871
872 //check if the interface is down
873 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
874 {
875 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
876 return -ENETDOWN;
877 }
878
879 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
880 {
881 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
882 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
883 }
884
885 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
886 // this request, because this request is initiated by NDIS.
887 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
888 // Prevent to connect AP again in STAMlmePeriodicExec
889 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
890
891 memset(Bssid, 0, MAC_ADDR_LEN);
892 memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
893 MlmeEnqueue(pAdapter,
894 MLME_CNTL_STATE_MACHINE,
895 OID_802_11_BSSID,
896 sizeof(NDIS_802_11_MAC_ADDRESS),
897 (VOID *)&Bssid);
898
899 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
900 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
901
902 return 0;
903}
904
905int rt_ioctl_giwap(struct net_device *dev,
906 struct iw_request_info *info,
907 struct sockaddr *ap_addr, char *extra)
908{
909 PRTMP_ADAPTER pAdapter = NULL;
910 VIRTUAL_ADAPTER *pVirtualAd = NULL;
911
912 if (dev->priv_flags == INT_MAIN)
913 {
914 pAdapter = dev->priv;
915 }
916 else
917 {
918 pVirtualAd = dev->priv;
919 if (pVirtualAd && pVirtualAd->RtmpDev)
920 pAdapter = pVirtualAd->RtmpDev->priv;
921 }
922
923 if (pAdapter == NULL)
924 {
925 /* if 1st open fail, pAd will be free;
926 So the net_dev->priv will be NULL in 2rd open */
927 return -ENETDOWN;
928 }
929
930 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
931 {
932 ap_addr->sa_family = ARPHRD_ETHER;
933 memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
934 }
935#ifdef WPA_SUPPLICANT_SUPPORT
936 // Add for RT2870
937 else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
938 {
939 ap_addr->sa_family = ARPHRD_ETHER;
940 memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
941 }
942#endif // WPA_SUPPLICANT_SUPPORT //
943 else
944 {
945 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
946 return -ENOTCONN;
947 }
948
949 return 0;
950}
951
952/*
953 * Units are in db above the noise floor. That means the
954 * rssi values reported in the tx/rx descriptors in the
955 * driver are the SNR expressed in db.
956 *
957 * If you assume that the noise floor is -95, which is an
958 * excellent assumption 99.5 % of the time, then you can
959 * derive the absolute signal level (i.e. -95 + rssi).
960 * There are some other slight factors to take into account
961 * depending on whether the rssi measurement is from 11b,
962 * 11g, or 11a. These differences are at most 2db and
963 * can be documented.
964 *
965 * NB: various calculations are based on the orinoco/wavelan
966 * drivers for compatibility
967 */
968static void set_quality(PRTMP_ADAPTER pAdapter,
969 struct iw_quality *iq,
970 signed char rssi)
971{
972 __u8 ChannelQuality;
973
974 // Normalize Rssi
975 if (rssi >= -50)
976 ChannelQuality = 100;
977 else if (rssi >= -80) // between -50 ~ -80dbm
978 ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
979 else if (rssi >= -90) // between -80 ~ -90dbm
980 ChannelQuality = (__u8)((rssi + 90) * 26)/10;
981 else
982 ChannelQuality = 0;
983
984 iq->qual = (__u8)ChannelQuality;
985
986 iq->level = (__u8)(rssi);
987 iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); // noise level (dBm)
988 iq->noise += 256 - 143;
989 iq->updated = pAdapter->iw_stats.qual.updated;
990}
991
992int rt_ioctl_iwaplist(struct net_device *dev,
993 struct iw_request_info *info,
994 struct iw_point *data, char *extra)
995{
996 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
997
998 struct sockaddr addr[IW_MAX_AP];
999 struct iw_quality qual[IW_MAX_AP];
1000 int i;
1001
1002 //check if the interface is down
1003 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1004 {
1005 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1006 data->length = 0;
1007 return 0;
1008 //return -ENETDOWN;
1009 }
1010
1011 for (i = 0; i <IW_MAX_AP ; i++)
1012 {
1013 if (i >= pAdapter->ScanTab.BssNr)
1014 break;
1015 addr[i].sa_family = ARPHRD_ETHER;
1016 memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
1017 set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
1018 }
1019 data->length = i;
1020 memcpy(extra, &addr, i*sizeof(addr[0]));
1021 data->flags = 1; /* signal quality present (sort of) */
1022 memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
1023
1024 return 0;
1025}
1026
1027#ifdef SIOCGIWSCAN
1028int rt_ioctl_siwscan(struct net_device *dev,
1029 struct iw_request_info *info,
1030 struct iw_point *data, char *extra)
1031{
1032 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1033
1034 ULONG Now;
1035 int Status = NDIS_STATUS_SUCCESS;
1036
1037 //check if the interface is down
1038 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1039 {
1040 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1041 return -ENETDOWN;
1042 }
1043
1044 if (MONITOR_ON(pAdapter))
1045 {
1046 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
1047 return -EINVAL;
1048 }
1049
1050
1051#ifdef WPA_SUPPLICANT_SUPPORT
1052 if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
1053 {
1054 pAdapter->StaCfg.WpaSupplicantScanCount++;
1055 }
1056#endif // WPA_SUPPLICANT_SUPPORT //
1057
1058 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
1059 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1060 return 0;
1061 do{
1062 Now = jiffies;
1063
1064#ifdef WPA_SUPPLICANT_SUPPORT
1065 if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
1066 (pAdapter->StaCfg.WpaSupplicantScanCount > 3))
1067 {
1068 DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
1069 Status = NDIS_STATUS_SUCCESS;
1070 break;
1071 }
1072#endif // WPA_SUPPLICANT_SUPPORT //
1073
1074 if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
1075 ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1076 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
1077 (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1078 {
1079 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
1080 Status = NDIS_STATUS_SUCCESS;
1081 break;
1082 }
1083
1084 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
1085 {
1086 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
1087 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
1088 }
1089
1090 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
1091 // this request, because this request is initiated by NDIS.
1092 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
1093 // Reset allowed scan retries
1094 pAdapter->StaCfg.ScanCnt = 0;
1095 pAdapter->StaCfg.LastScanTime = Now;
1096
1097 MlmeEnqueue(pAdapter,
1098 MLME_CNTL_STATE_MACHINE,
1099 OID_802_11_BSSID_LIST_SCAN,
1100 0,
1101 NULL);
1102
1103 Status = NDIS_STATUS_SUCCESS;
1104 RT28XX_MLME_HANDLER(pAdapter);
1105 }while(0);
1106 return 0;
1107}
1108
1109int rt_ioctl_giwscan(struct net_device *dev,
1110 struct iw_request_info *info,
1111 struct iw_point *data, char *extra)
1112{
1113
1114 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1115 int i=0;
1116 char *current_ev = extra, *previous_ev = extra;
1117 char *end_buf;
1118 char *current_val, custom[MAX_CUSTOM_LEN] = {0};
1119#ifndef IWEVGENIE
1120 char idx;
1121#endif // IWEVGENIE //
1122 struct iw_event iwe;
1123
1124 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1125 {
1126 /*
1127 * Still scanning, indicate the caller should try again.
1128 */
1129 return -EAGAIN;
1130 }
1131
1132
1133#ifdef WPA_SUPPLICANT_SUPPORT
1134 if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
1135 {
1136 pAdapter->StaCfg.WpaSupplicantScanCount = 0;
1137 }
1138#endif // WPA_SUPPLICANT_SUPPORT //
1139
1140 if (pAdapter->ScanTab.BssNr == 0)
1141 {
1142 data->length = 0;
1143 return 0;
1144 }
1145
1146#if WIRELESS_EXT >= 17
1147 if (data->length > 0)
1148 end_buf = extra + data->length;
1149 else
1150 end_buf = extra + IW_SCAN_MAX_DATA;
1151#else
1152 end_buf = extra + IW_SCAN_MAX_DATA;
1153#endif
1154
1155 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
1156 {
1157 if (current_ev >= end_buf)
1158 {
1159#if WIRELESS_EXT >= 17
1160 return -E2BIG;
1161#else
1162 break;
1163#endif
1164 }
1165
1166 //MAC address
1167 //================================
1168 memset(&iwe, 0, sizeof(iwe));
1169 iwe.cmd = SIOCGIWAP;
1170 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1171 memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
1172
1173 previous_ev = current_ev;
1174 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
1175 if (current_ev == previous_ev)
1176#if WIRELESS_EXT >= 17
1177 return -E2BIG;
1178#else
1179 break;
1180#endif
1181
1182 //ESSID
1183 //================================
1184 memset(&iwe, 0, sizeof(iwe));
1185 iwe.cmd = SIOCGIWESSID;
1186 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
1187 iwe.u.data.flags = 1;
1188
1189 previous_ev = current_ev;
1190 current_ev = IWE_STREAM_ADD_POINT(info, current_ev,end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
1191 if (current_ev == previous_ev)
1192#if WIRELESS_EXT >= 17
1193 return -E2BIG;
1194#else
1195 break;
1196#endif
1197
1198 //Network Type
1199 //================================
1200 memset(&iwe, 0, sizeof(iwe));
1201 iwe.cmd = SIOCGIWMODE;
1202 if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
1203 {
1204 iwe.u.mode = IW_MODE_ADHOC;
1205 }
1206 else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
1207 {
1208 iwe.u.mode = IW_MODE_INFRA;
1209 }
1210 else
1211 {
1212 iwe.u.mode = IW_MODE_AUTO;
1213 }
1214 iwe.len = IW_EV_UINT_LEN;
1215
1216 previous_ev = current_ev;
1217 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
1218 if (current_ev == previous_ev)
1219#if WIRELESS_EXT >= 17
1220 return -E2BIG;
1221#else
1222 break;
1223#endif
1224
1225 //Channel and Frequency
1226 //================================
1227 memset(&iwe, 0, sizeof(iwe));
1228 iwe.cmd = SIOCGIWFREQ;
1229 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
1230 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1231 else
1232 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1233 iwe.u.freq.e = 0;
1234 iwe.u.freq.i = 0;
1235
1236 previous_ev = current_ev;
1237 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
1238 if (current_ev == previous_ev)
1239#if WIRELESS_EXT >= 17
1240 return -E2BIG;
1241#else
1242 break;
1243#endif
1244
1245 //Add quality statistics
1246 //================================
1247 memset(&iwe, 0, sizeof(iwe));
1248 iwe.cmd = IWEVQUAL;
1249 iwe.u.qual.level = 0;
1250 iwe.u.qual.noise = 0;
1251 set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
1252 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
1253 if (current_ev == previous_ev)
1254#if WIRELESS_EXT >= 17
1255 return -E2BIG;
1256#else
1257 break;
1258#endif
1259
1260 //Encyption key
1261 //================================
1262 memset(&iwe, 0, sizeof(iwe));
1263 iwe.cmd = SIOCGIWENCODE;
1264 if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
1265 iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1266 else
1267 iwe.u.data.flags = IW_ENCODE_DISABLED;
1268
1269 previous_ev = current_ev;
1270 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);
1271 if (current_ev == previous_ev)
1272#if WIRELESS_EXT >= 17
1273 return -E2BIG;
1274#else
1275 break;
1276#endif
1277
1278 //Bit Rate
1279 //================================
1280 if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
1281 {
1282 UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
1283 memset(&iwe, 0, sizeof(iwe));
1284 iwe.cmd = SIOCGIWRATE;
1285 current_val = current_ev + IW_EV_LCP_LEN;
1286 if (tmpRate == 0x82)
1287 iwe.u.bitrate.value = 1 * 1000000;
1288 else if (tmpRate == 0x84)
1289 iwe.u.bitrate.value = 2 * 1000000;
1290 else if (tmpRate == 0x8B)
1291 iwe.u.bitrate.value = 5.5 * 1000000;
1292 else if (tmpRate == 0x96)
1293 iwe.u.bitrate.value = 11 * 1000000;
1294 else
1295 iwe.u.bitrate.value = (tmpRate/2) * 1000000;
1296
1297 iwe.u.bitrate.disabled = 0;
1298 current_val = IWE_STREAM_ADD_VALUE(info, current_ev,
1299 current_val, end_buf, &iwe,
1300 IW_EV_PARAM_LEN);
1301
1302 if((current_val-current_ev)>IW_EV_LCP_LEN)
1303 current_ev = current_val;
1304 else
1305#if WIRELESS_EXT >= 17
1306 return -E2BIG;
1307#else
1308 break;
1309#endif
1310 }
1311
1312#ifdef IWEVGENIE
1313 //WPA IE
1314 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1315 {
1316 memset(&iwe, 0, sizeof(iwe));
1317 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1318 memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
1319 pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
1320 iwe.cmd = IWEVGENIE;
1321 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
1322 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1323 if (current_ev == previous_ev)
1324#if WIRELESS_EXT >= 17
1325 return -E2BIG;
1326#else
1327 break;
1328#endif
1329 }
1330
1331 //WPA2 IE
1332 if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1333 {
1334 memset(&iwe, 0, sizeof(iwe));
1335 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1336 memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
1337 pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
1338 iwe.cmd = IWEVGENIE;
1339 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
1340 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1341 if (current_ev == previous_ev)
1342#if WIRELESS_EXT >= 17
1343 return -E2BIG;
1344#else
1345 break;
1346#endif
1347 }
1348#else
1349 //WPA IE
1350 //================================
1351 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1352 {
1353 NdisZeroMemory(&iwe, sizeof(iwe));
1354 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1355 iwe.cmd = IWEVCUSTOM;
1356 iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen * 2) + 7;
1357 NdisMoveMemory(custom, "wpa_ie=", 7);
1358 for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].WpaIE.IELen; idx++)
1359 sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].WpaIE.IE[idx]);
1360 previous_ev = current_ev;
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
1370 //WPA2 IE
1371 if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1372 {
1373 NdisZeroMemory(&iwe, sizeof(iwe));
1374 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1375 iwe.cmd = IWEVCUSTOM;
1376 iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen * 2) + 7;
1377 NdisMoveMemory(custom, "rsn_ie=", 7);
1378 for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].RsnIE.IELen; idx++)
1379 sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].RsnIE.IE[idx]);
1380 previous_ev = current_ev;
1381 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1382 if (current_ev == previous_ev)
1383#if WIRELESS_EXT >= 17
1384 return -E2BIG;
1385#else
1386 break;
1387#endif
1388 }
1389#endif // IWEVGENIE //
1390 }
1391
1392 data->length = current_ev - extra;
1393 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
1394 DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
1395 return 0;
1396}
1397#endif
1398
1399int rt_ioctl_siwessid(struct net_device *dev,
1400 struct iw_request_info *info,
1401 struct iw_point *data, char *essid)
1402{
1403 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1404
1405 //check if the interface is down
1406 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1407 {
1408 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1409 return -ENETDOWN;
1410 }
1411
1412 if (data->flags)
1413 {
1414 PCHAR pSsidString = NULL;
1415
1416 // Includes null character.
1417 if (data->length > (IW_ESSID_MAX_SIZE + 1))
1418 return -E2BIG;
1419
1420 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
1421 if (pSsidString)
1422 {
1423 NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
1424 NdisMoveMemory(pSsidString, essid, data->length);
1425 if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
1426 return -EINVAL;
1427 }
1428 else
1429 return -ENOMEM;
1430 }
1431 else
1432 {
1433 // ANY ssid
1434 if (Set_SSID_Proc(pAdapter, "") == FALSE)
1435 return -EINVAL;
1436 }
1437 return 0;
1438}
1439
1440int rt_ioctl_giwessid(struct net_device *dev,
1441 struct iw_request_info *info,
1442 struct iw_point *data, char *essid)
1443{
1444 PRTMP_ADAPTER pAdapter = NULL;
1445 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1446
1447 if (dev->priv_flags == INT_MAIN)
1448 {
1449 pAdapter = dev->priv;
1450 }
1451 else
1452 {
1453 pVirtualAd = dev->priv;
1454 if (pVirtualAd && pVirtualAd->RtmpDev)
1455 pAdapter = pVirtualAd->RtmpDev->priv;
1456 }
1457
1458 if (pAdapter == NULL)
1459 {
1460 /* if 1st open fail, pAd will be free;
1461 So the net_dev->priv will be NULL in 2rd open */
1462 return -ENETDOWN;
1463 }
1464
1465 data->flags = 1;
1466 if (MONITOR_ON(pAdapter))
1467 {
1468 data->length = 0;
1469 return 0;
1470 }
1471
1472 if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
1473 {
1474 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
1475 data->length = pAdapter->CommonCfg.SsidLen;
1476 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1477 }
1478#ifdef RT2870
1479#ifdef WPA_SUPPLICANT_SUPPORT
1480 // Add for RT2870
1481 else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1482 {
1483 data->length = pAdapter->CommonCfg.SsidLen;
1484 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1485 }
1486#endif // WPA_SUPPLICANT_SUPPORT //
1487#endif // RT2870 //
1488 else
1489 {//the ANY ssid was specified
1490 data->length = 0;
1491 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
1492 }
1493
1494 return 0;
1495
1496}
1497
1498int rt_ioctl_siwnickn(struct net_device *dev,
1499 struct iw_request_info *info,
1500 struct iw_point *data, char *nickname)
1501{
1502 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1503
1504 //check if the interface is down
1505 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1506 {
1507 DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
1508 return -ENETDOWN;
1509 }
1510
1511 if (data->length > IW_ESSID_MAX_SIZE)
1512 return -EINVAL;
1513
1514 memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
1515 memcpy(pAdapter->nickname, nickname, data->length);
1516
1517
1518 return 0;
1519}
1520
1521int rt_ioctl_giwnickn(struct net_device *dev,
1522 struct iw_request_info *info,
1523 struct iw_point *data, char *nickname)
1524{
1525 PRTMP_ADAPTER pAdapter = NULL;
1526 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1527
1528 if (dev->priv_flags == INT_MAIN)
1529 {
1530 pAdapter = dev->priv;
1531 }
1532 else
1533 {
1534 pVirtualAd = dev->priv;
1535 if (pVirtualAd && pVirtualAd->RtmpDev)
1536 pAdapter = pVirtualAd->RtmpDev->priv;
1537 }
1538
1539 if (pAdapter == NULL)
1540 {
1541 /* if 1st open fail, pAd will be free;
1542 So the net_dev->priv will be NULL in 2rd open */
1543 return -ENETDOWN;
1544 }
1545
1546 if (data->length > strlen(pAdapter->nickname) + 1)
1547 data->length = strlen(pAdapter->nickname) + 1;
1548 if (data->length > 0) {
1549 memcpy(nickname, pAdapter->nickname, data->length-1);
1550 nickname[data->length-1] = '\0';
1551 }
1552 return 0;
1553}
1554
1555int rt_ioctl_siwrts(struct net_device *dev,
1556 struct iw_request_info *info,
1557 struct iw_param *rts, char *extra)
1558{
1559 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1560 u16 val;
1561
1562 //check if the interface is down
1563 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1564 {
1565 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1566 return -ENETDOWN;
1567 }
1568
1569 if (rts->disabled)
1570 val = MAX_RTS_THRESHOLD;
1571 else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
1572 return -EINVAL;
1573 else if (rts->value == 0)
1574 val = MAX_RTS_THRESHOLD;
1575 else
1576 val = rts->value;
1577
1578 if (val != pAdapter->CommonCfg.RtsThreshold)
1579 pAdapter->CommonCfg.RtsThreshold = val;
1580
1581 return 0;
1582}
1583
1584int rt_ioctl_giwrts(struct net_device *dev,
1585 struct iw_request_info *info,
1586 struct iw_param *rts, char *extra)
1587{
1588 PRTMP_ADAPTER pAdapter = NULL;
1589 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1590
1591 if (dev->priv_flags == INT_MAIN)
1592 {
1593 pAdapter = dev->priv;
1594 }
1595 else
1596 {
1597 pVirtualAd = dev->priv;
1598 if (pVirtualAd && pVirtualAd->RtmpDev)
1599 pAdapter = pVirtualAd->RtmpDev->priv;
1600 }
1601
1602 if (pAdapter == NULL)
1603 {
1604 /* if 1st open fail, pAd will be free;
1605 So the net_dev->priv will be NULL in 2rd open */
1606 return -ENETDOWN;
1607 }
1608
1609 //check if the interface is down
1610 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1611 {
1612 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1613 return -ENETDOWN;
1614 }
1615
1616 rts->value = pAdapter->CommonCfg.RtsThreshold;
1617 rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
1618 rts->fixed = 1;
1619
1620 return 0;
1621}
1622
1623int rt_ioctl_siwfrag(struct net_device *dev,
1624 struct iw_request_info *info,
1625 struct iw_param *frag, char *extra)
1626{
1627 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1628 u16 val;
1629
1630 //check if the interface is down
1631 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1632 {
1633 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1634 return -ENETDOWN;
1635 }
1636
1637 if (frag->disabled)
1638 val = MAX_FRAG_THRESHOLD;
1639 else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
1640 val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
1641 else if (frag->value == 0)
1642 val = MAX_FRAG_THRESHOLD;
1643 else
1644 return -EINVAL;
1645
1646 pAdapter->CommonCfg.FragmentThreshold = val;
1647 return 0;
1648}
1649
1650int rt_ioctl_giwfrag(struct net_device *dev,
1651 struct iw_request_info *info,
1652 struct iw_param *frag, char *extra)
1653{
1654 PRTMP_ADAPTER pAdapter = NULL;
1655 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1656
1657 if (dev->priv_flags == INT_MAIN)
1658 {
1659 pAdapter = dev->priv;
1660 }
1661 else
1662 {
1663 pVirtualAd = dev->priv;
1664 if (pVirtualAd && pVirtualAd->RtmpDev)
1665 pAdapter = pVirtualAd->RtmpDev->priv;
1666 }
1667
1668 if (pAdapter == NULL)
1669 {
1670 /* if 1st open fail, pAd will be free;
1671 So the net_dev->priv will be NULL in 2rd open */
1672 return -ENETDOWN;
1673 }
1674
1675 //check if the interface is down
1676 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1677 {
1678 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1679 return -ENETDOWN;
1680 }
1681
1682 frag->value = pAdapter->CommonCfg.FragmentThreshold;
1683 frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
1684 frag->fixed = 1;
1685
1686 return 0;
1687}
1688
1689#define MAX_WEP_KEY_SIZE 13
1690#define MIN_WEP_KEY_SIZE 5
1691int rt_ioctl_siwencode(struct net_device *dev,
1692 struct iw_request_info *info,
1693 struct iw_point *erq, char *extra)
1694{
1695 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1696
1697 //check if the interface is down
1698 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1699 {
1700 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1701 return -ENETDOWN;
1702 }
1703
1704 if ((erq->length == 0) &&
1705 (erq->flags & IW_ENCODE_DISABLED))
1706 {
1707 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1708 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1709 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1710 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1711 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1712 goto done;
1713 }
1714 else if ((erq->length == 0) &&
1715 (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN))
1716 {
1717 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1718 STA_PORT_SECURED(pAdapter);
1719 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1720 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1721 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1722 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1723 if (erq->flags & IW_ENCODE_RESTRICTED)
1724 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1725 else
1726 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1727 goto done;
1728 }
1729
1730 if (erq->length > 0)
1731 {
1732 int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
1733 /* Check the size of the key */
1734 if (erq->length > MAX_WEP_KEY_SIZE) {
1735 return -EINVAL;
1736 }
1737 /* Check key index */
1738 if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
1739 {
1740 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
1741 keyIdx, pAdapter->StaCfg.DefaultKeyId));
1742
1743 //Using default key
1744 keyIdx = pAdapter->StaCfg.DefaultKeyId;
1745 }
1746
1747 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
1748
1749 if (erq->length == MAX_WEP_KEY_SIZE)
1750 {
1751 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
1752 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
1753 }
1754 else if (erq->length == MIN_WEP_KEY_SIZE)
1755 {
1756 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
1757 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
1758 }
1759 else
1760 /* Disable the key */
1761 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
1762
1763 /* Check if the key is not marked as invalid */
1764 if(!(erq->flags & IW_ENCODE_NOKEY)) {
1765 /* Copy the key in the driver */
1766 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
1767 }
1768 }
1769 else
1770 {
1771 /* Do we want to just set the transmit key index ? */
1772 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
1773 if ((index >= 0) && (index < 4))
1774 {
1775 pAdapter->StaCfg.DefaultKeyId = index;
1776 }
1777 else
1778 /* Don't complain if only change the mode */
1779 if(!erq->flags & IW_ENCODE_MODE) {
1780 return -EINVAL;
1781 }
1782 }
1783
1784done:
1785 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
1786 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
1787 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
1788 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
1789 return 0;
1790}
1791
1792int
1793rt_ioctl_giwencode(struct net_device *dev,
1794 struct iw_request_info *info,
1795 struct iw_point *erq, char *key)
1796{
1797 int kid;
1798 PRTMP_ADAPTER pAdapter = NULL;
1799 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1800
1801 if (dev->priv_flags == INT_MAIN)
1802 {
1803 pAdapter = dev->priv;
1804 }
1805 else
1806 {
1807 pVirtualAd = dev->priv;
1808 if (pVirtualAd && pVirtualAd->RtmpDev)
1809 pAdapter = pVirtualAd->RtmpDev->priv;
1810 }
1811
1812 if (pAdapter == NULL)
1813 {
1814 /* if 1st open fail, pAd will be free;
1815 So the net_dev->priv will be NULL in 2rd open */
1816 return -ENETDOWN;
1817 }
1818
1819 //check if the interface is down
1820 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1821 {
1822 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1823 return -ENETDOWN;
1824 }
1825
1826 kid = erq->flags & IW_ENCODE_INDEX;
1827 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
1828
1829 if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
1830 {
1831 erq->length = 0;
1832 erq->flags = IW_ENCODE_DISABLED;
1833 }
1834 else if ((kid > 0) && (kid <=4))
1835 {
1836 // copy wep key
1837 erq->flags = kid ; /* NB: base 1 */
1838 if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
1839 erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
1840 memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
1841 //if ((kid == pAdapter->PortCfg.DefaultKeyId))
1842 //erq->flags |= IW_ENCODE_ENABLED; /* XXX */
1843 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1844 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1845 else
1846 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1847
1848 }
1849 else if (kid == 0)
1850 {
1851 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1852 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1853 else
1854 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1855 erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
1856 memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
1857 // copy default key ID
1858 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1859 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1860 else
1861 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1862 erq->flags = pAdapter->StaCfg.DefaultKeyId + 1; /* NB: base 1 */
1863 erq->flags |= IW_ENCODE_ENABLED; /* XXX */
1864 }
1865
1866 return 0;
1867
1868}
1869
1870static int
1871rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
1872 void *w, char *extra)
1873{
1874 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1875 PRTMP_ADAPTER pAdapter;
1876 POS_COOKIE pObj;
1877 char *this_char = extra;
1878 char *value;
1879 int Status=0;
1880
1881 if (dev->priv_flags == INT_MAIN)
1882 {
1883 pAdapter = dev->priv;
1884 }
1885 else
1886 {
1887 pVirtualAd = dev->priv;
1888 pAdapter = pVirtualAd->RtmpDev->priv;
1889 }
1890 pObj = (POS_COOKIE) pAdapter->OS_Cookie;
1891
1892 if (pAdapter == NULL)
1893 {
1894 /* if 1st open fail, pAd will be free;
1895 So the net_dev->priv will be NULL in 2rd open */
1896 return -ENETDOWN;
1897 }
1898
1899 {
1900 pObj->ioctl_if_type = INT_MAIN;
1901 pObj->ioctl_if = MAIN_MBSSID;
1902 }
1903
1904 //check if the interface is down
1905 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1906 {
1907 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1908 return -ENETDOWN;
1909 }
1910
1911 if (!*this_char)
1912 return -EINVAL;
1913
1914 if ((value = rtstrchr(this_char, '=')) != NULL)
1915 *value++ = 0;
1916
1917 if (!value)
1918 return -EINVAL;
1919
1920 // reject setting nothing besides ANY ssid(ssidLen=0)
1921 if (!*value && (strcmp(this_char, "SSID") != 0))
1922 return -EINVAL;
1923
1924 for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
1925 {
1926 if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
1927 {
1928 if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
1929 { //FALSE:Set private failed then return Invalid argument
1930 Status = -EINVAL;
1931 }
1932 break; //Exit for loop.
1933 }
1934 }
1935
1936 if(PRTMP_PRIVATE_SET_PROC->name == NULL)
1937 { //Not found argument
1938 Status = -EINVAL;
1939 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
1940 }
1941
1942 return Status;
1943}
1944
1945
1946static int
1947rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
1948 struct iw_point *wrq, char *extra)
1949{
1950 INT Status = 0;
1951 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
1952
1953 if (extra == NULL)
1954 {
1955 wrq->length = 0;
1956 return -EIO;
1957 }
1958
1959 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
1960 sprintf(extra, "\n\n");
1961
1962#ifdef RALINK_ATE
1963 if (ATE_ON(pAd))
1964 {
1965 sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->ate.TxDoneCount);
1966 //sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->ate.TxDoneCount);
1967 }
1968 else
1969#endif // RALINK_ATE //
1970 {
1971 sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
1972 sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1973 }
1974 sprintf(extra+strlen(extra), "Tx success after retry = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1975 sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
1976 sprintf(extra+strlen(extra), "RTS Success Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
1977 sprintf(extra+strlen(extra), "RTS Fail Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
1978
1979 sprintf(extra+strlen(extra), "Rx success = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
1980 sprintf(extra+strlen(extra), "Rx with CRC = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
1981 sprintf(extra+strlen(extra), "Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
1982 sprintf(extra+strlen(extra), "Rx duplicate frame = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
1983
1984 sprintf(extra+strlen(extra), "False CCA (one second) = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
1985#ifdef RALINK_ATE
1986 if (ATE_ON(pAd))
1987 {
1988 if (pAd->ate.RxAntennaSel == 0)
1989 {
1990 sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
1991 sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta));
1992 sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta));
1993 }
1994 else
1995 {
1996 sprintf(extra+strlen(extra), "RSSI = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
1997 }
1998 }
1999 else
2000#endif // RALINK_ATE //
2001 {
2002 sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
2003 sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
2004 sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
2005 }
2006#ifdef WPA_SUPPLICANT_SUPPORT
2007 sprintf(extra+strlen(extra), "WpaSupplicantUP = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
2008#endif // WPA_SUPPLICANT_SUPPORT //
2009
2010
2011 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2012 DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
2013
2014 return Status;
2015}
2016
2017#ifdef DOT11_N_SUPPORT
2018void getBaInfo(
2019 IN PRTMP_ADAPTER pAd,
2020 IN PUCHAR pOutBuf)
2021{
2022 INT i, j;
2023 BA_ORI_ENTRY *pOriBAEntry;
2024 BA_REC_ENTRY *pRecBAEntry;
2025
2026 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
2027 {
2028 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
2029 if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
2030 || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
2031 {
2032 sprintf(pOutBuf, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
2033 pOutBuf,
2034 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2035 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
2036
2037 sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
2038 for (j=0; j < NUM_OF_TID; j++)
2039 {
2040 if (pEntry->BARecWcidArray[j] != 0)
2041 {
2042 pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
2043 sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
2044 }
2045 }
2046 sprintf(pOutBuf, "%s\n", pOutBuf);
2047
2048 sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
2049 for (j=0; j < NUM_OF_TID; j++)
2050 {
2051 if (pEntry->BAOriWcidArray[j] != 0)
2052 {
2053 pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
2054 sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
2055 }
2056 }
2057 sprintf(pOutBuf, "%s\n\n", pOutBuf);
2058 }
2059 if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
2060 break;
2061 }
2062
2063 return;
2064}
2065#endif // DOT11_N_SUPPORT //
2066
2067static int
2068rt_private_show(struct net_device *dev, struct iw_request_info *info,
2069 struct iw_point *wrq, char *extra)
2070{
2071 INT Status = 0;
2072 VIRTUAL_ADAPTER *pVirtualAd = NULL;
2073 PRTMP_ADAPTER pAd;
2074 POS_COOKIE pObj;
2075 u32 subcmd = wrq->flags;
2076
2077 if (dev->priv_flags == INT_MAIN)
2078 pAd = dev->priv;
2079 else
2080 {
2081 pVirtualAd = dev->priv;
2082 pAd = pVirtualAd->RtmpDev->priv;
2083 }
2084 pObj = (POS_COOKIE) pAd->OS_Cookie;
2085
2086 if (pAd == NULL)
2087 {
2088 /* if 1st open fail, pAd will be free;
2089 So the net_dev->priv will be NULL in 2rd open */
2090 return -ENETDOWN;
2091 }
2092
2093 if (extra == NULL)
2094 {
2095 wrq->length = 0;
2096 return -EIO;
2097 }
2098 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2099
2100 {
2101 pObj->ioctl_if_type = INT_MAIN;
2102 pObj->ioctl_if = MAIN_MBSSID;
2103 }
2104
2105 switch(subcmd)
2106 {
2107
2108 case SHOW_CONN_STATUS:
2109 if (MONITOR_ON(pAd))
2110 {
2111#ifdef DOT11_N_SUPPORT
2112 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
2113 pAd->CommonCfg.RegTransmitSetting.field.BW)
2114 sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
2115 else
2116#endif // DOT11_N_SUPPORT //
2117 sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
2118 }
2119 else
2120 {
2121 if (pAd->IndicateMediaState == NdisMediaStateConnected)
2122 {
2123 if (INFRA_ON(pAd))
2124 {
2125 sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
2126 pAd->CommonCfg.Ssid,
2127 pAd->CommonCfg.Bssid[0],
2128 pAd->CommonCfg.Bssid[1],
2129 pAd->CommonCfg.Bssid[2],
2130 pAd->CommonCfg.Bssid[3],
2131 pAd->CommonCfg.Bssid[4],
2132 pAd->CommonCfg.Bssid[5]);
2133 DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
2134 }
2135 else if (ADHOC_ON(pAd))
2136 sprintf(extra, "Connected\n");
2137 }
2138 else
2139 {
2140 sprintf(extra, "Disconnected\n");
2141 DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
2142 }
2143 }
2144 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2145 break;
2146 case SHOW_DRVIER_VERION:
2147 sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
2148 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2149 break;
2150#ifdef DOT11_N_SUPPORT
2151 case SHOW_BA_INFO:
2152 getBaInfo(pAd, extra);
2153 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2154 break;
2155#endif // DOT11_N_SUPPORT //
2156 case SHOW_DESC_INFO:
2157 {
2158 Show_DescInfo_Proc(pAd, NULL);
2159 wrq->length = 0; // 1: size of '\0'
2160 }
2161 break;
2162 case RAIO_OFF:
2163 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2164 {
2165 sprintf(extra, "Scanning\n");
2166 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2167 break;
2168 }
2169 pAd->StaCfg.bSwRadio = FALSE;
2170 if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2171 {
2172 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2173 if (pAd->StaCfg.bRadio == FALSE)
2174 {
2175 MlmeRadioOff(pAd);
2176 // Update extra information
2177 pAd->ExtraInfo = SW_RADIO_OFF;
2178 }
2179 }
2180 sprintf(extra, "Radio Off\n");
2181 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2182 break;
2183 case RAIO_ON:
2184 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2185 {
2186 sprintf(extra, "Scanning\n");
2187 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2188 break;
2189 }
2190 pAd->StaCfg.bSwRadio = TRUE;
2191 //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2192 {
2193 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2194 if (pAd->StaCfg.bRadio == TRUE)
2195 {
2196 MlmeRadioOn(pAd);
2197 // Update extra information
2198 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
2199 }
2200 }
2201 sprintf(extra, "Radio On\n");
2202 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2203 break;
2204
2205
2206#ifdef QOS_DLS_SUPPORT
2207 case SHOW_DLS_ENTRY_INFO:
2208 {
2209 Set_DlsEntryInfo_Display_Proc(pAd, NULL);
2210 wrq->length = 0; // 1: size of '\0'
2211 }
2212 break;
2213#endif // QOS_DLS_SUPPORT //
2214
2215 case SHOW_CFG_VALUE:
2216 {
2217 Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
2218 if (Status == 0)
2219 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2220 }
2221 break;
2222 case SHOW_ADHOC_ENTRY_INFO:
2223 Show_Adhoc_MacTable_Proc(pAd, extra);
2224 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2225 break;
2226 default:
2227 DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __FUNCTION__, subcmd));
2228 break;
2229 }
2230
2231 return Status;
2232}
2233
2234#ifdef SIOCSIWMLME
2235int rt_ioctl_siwmlme(struct net_device *dev,
2236 struct iw_request_info *info,
2237 union iwreq_data *wrqu,
2238 char *extra)
2239{
2240 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2241 struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
2242 MLME_QUEUE_ELEM MsgElem;
2243 MLME_DISASSOC_REQ_STRUCT DisAssocReq;
2244 MLME_DEAUTH_REQ_STRUCT DeAuthReq;
2245
2246 DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
2247
2248 if (pMlme == NULL)
2249 return -EINVAL;
2250
2251 switch(pMlme->cmd)
2252 {
2253#ifdef IW_MLME_DEAUTH
2254 case IW_MLME_DEAUTH:
2255 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __FUNCTION__));
2256 COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
2257 DeAuthReq.Reason = pMlme->reason_code;
2258 MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
2259 NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
2260 MlmeDeauthReqAction(pAd, &MsgElem);
2261 if (INFRA_ON(pAd))
2262 {
2263 LinkDown(pAd, FALSE);
2264 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
2265 }
2266 break;
2267#endif // IW_MLME_DEAUTH //
2268#ifdef IW_MLME_DISASSOC
2269 case IW_MLME_DISASSOC:
2270 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __FUNCTION__));
2271 COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
2272 DisAssocReq.Reason = pMlme->reason_code;
2273
2274 MsgElem.Machine = ASSOC_STATE_MACHINE;
2275 MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
2276 MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
2277 NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
2278
2279 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
2280 MlmeDisassocReqAction(pAd, &MsgElem);
2281 break;
2282#endif // IW_MLME_DISASSOC //
2283 default:
2284 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __FUNCTION__));
2285 break;
2286 }
2287
2288 return 0;
2289}
2290#endif // SIOCSIWMLME //
2291
2292#if WIRELESS_EXT > 17
2293int rt_ioctl_siwauth(struct net_device *dev,
2294 struct iw_request_info *info,
2295 union iwreq_data *wrqu, char *extra)
2296{
2297 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2298 struct iw_param *param = &wrqu->param;
2299
2300 //check if the interface is down
2301 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2302 {
2303 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2304 return -ENETDOWN;
2305 }
2306 switch (param->flags & IW_AUTH_INDEX) {
2307 case IW_AUTH_WPA_VERSION:
2308 if (param->value == IW_AUTH_WPA_VERSION_WPA)
2309 {
2310 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
2311 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
2312 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
2313 }
2314 else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
2315 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
2316
2317 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
2318 break;
2319 case IW_AUTH_CIPHER_PAIRWISE:
2320 if (param->value == IW_AUTH_CIPHER_NONE)
2321 {
2322 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
2323 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2324 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
2325 }
2326 else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2327 param->value == IW_AUTH_CIPHER_WEP104)
2328 {
2329 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
2330 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2331 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
2332#ifdef WPA_SUPPLICANT_SUPPORT
2333 pAdapter->StaCfg.IEEE8021X = FALSE;
2334#endif // WPA_SUPPLICANT_SUPPORT //
2335 }
2336 else if (param->value == IW_AUTH_CIPHER_TKIP)
2337 {
2338 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
2339 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2340 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2341 }
2342 else if (param->value == IW_AUTH_CIPHER_CCMP)
2343 {
2344 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
2345 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2346 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
2347 }
2348 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __FUNCTION__, param->value));
2349 break;
2350 case IW_AUTH_CIPHER_GROUP:
2351 if (param->value == IW_AUTH_CIPHER_NONE)
2352 {
2353 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
2354 }
2355 else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2356 param->value == IW_AUTH_CIPHER_WEP104)
2357 {
2358 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
2359 }
2360 else if (param->value == IW_AUTH_CIPHER_TKIP)
2361 {
2362 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
2363 }
2364 else if (param->value == IW_AUTH_CIPHER_CCMP)
2365 {
2366 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
2367 }
2368 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __FUNCTION__, param->value));
2369 break;
2370 case IW_AUTH_KEY_MGMT:
2371 if (param->value == IW_AUTH_KEY_MGMT_802_1X)
2372 {
2373 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
2374 {
2375 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
2376#ifdef WPA_SUPPLICANT_SUPPORT
2377 pAdapter->StaCfg.IEEE8021X = FALSE;
2378#endif // WPA_SUPPLICANT_SUPPORT //
2379 }
2380 else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
2381 {
2382 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
2383#ifdef WPA_SUPPLICANT_SUPPORT
2384 pAdapter->StaCfg.IEEE8021X = FALSE;
2385#endif // WPA_SUPPLICANT_SUPPORT //
2386 }
2387#ifdef WPA_SUPPLICANT_SUPPORT
2388 else
2389 // WEP 1x
2390 pAdapter->StaCfg.IEEE8021X = TRUE;
2391#endif // WPA_SUPPLICANT_SUPPORT //
2392 }
2393 else if (param->value == 0)
2394 {
2395 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2396 STA_PORT_SECURED(pAdapter);
2397 }
2398 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __FUNCTION__, param->value));
2399 break;
2400 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2401 break;
2402 case IW_AUTH_PRIVACY_INVOKED:
2403 /*if (param->value == 0)
2404 {
2405 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2406 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
2407 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2408 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
2409 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
2410 }*/
2411 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __FUNCTION__, param->value));
2412 break;
2413 case IW_AUTH_DROP_UNENCRYPTED:
2414 if (param->value != 0)
2415 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2416 else
2417 {
2418 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2419 STA_PORT_SECURED(pAdapter);
2420 }
2421 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
2422 break;
2423 case IW_AUTH_80211_AUTH_ALG:
2424 if (param->value & IW_AUTH_ALG_SHARED_KEY)
2425 {
2426 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
2427 }
2428 else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
2429 {
2430 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2431 }
2432 else
2433 return -EINVAL;
2434 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __FUNCTION__, param->value));
2435 break;
2436 case IW_AUTH_WPA_ENABLED:
2437 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __FUNCTION__, param->value));
2438 break;
2439 default:
2440 return -EOPNOTSUPP;
2441}
2442
2443 return 0;
2444}
2445
2446int rt_ioctl_giwauth(struct net_device *dev,
2447 struct iw_request_info *info,
2448 union iwreq_data *wrqu, char *extra)
2449{
2450 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2451 struct iw_param *param = &wrqu->param;
2452
2453 //check if the interface is down
2454 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2455 {
2456 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2457 return -ENETDOWN;
2458 }
2459
2460 switch (param->flags & IW_AUTH_INDEX) {
2461 case IW_AUTH_DROP_UNENCRYPTED:
2462 param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
2463 break;
2464
2465 case IW_AUTH_80211_AUTH_ALG:
2466 param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
2467 break;
2468
2469 case IW_AUTH_WPA_ENABLED:
2470 param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
2471 break;
2472
2473 default:
2474 return -EOPNOTSUPP;
2475 }
2476 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
2477 return 0;
2478}
2479
2480void fnSetCipherKey(
2481 IN PRTMP_ADAPTER pAdapter,
2482 IN INT keyIdx,
2483 IN UCHAR CipherAlg,
2484 IN BOOLEAN bGTK,
2485 IN struct iw_encode_ext *ext)
2486{
2487 NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2488 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
2489 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
2490 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
2491 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
2492 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
2493
2494 // Update group key information to ASIC Shared Key Table
2495 AsicAddSharedKeyEntry(pAdapter,
2496 BSS0,
2497 keyIdx,
2498 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2499 pAdapter->SharedKey[BSS0][keyIdx].Key,
2500 pAdapter->SharedKey[BSS0][keyIdx].TxMic,
2501 pAdapter->SharedKey[BSS0][keyIdx].RxMic);
2502
2503 if (bGTK)
2504 // Update ASIC WCID attribute table and IVEIV table
2505 RTMPAddWcidAttributeEntry(pAdapter,
2506 BSS0,
2507 keyIdx,
2508 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2509 NULL);
2510 else
2511 // Update ASIC WCID attribute table and IVEIV table
2512 RTMPAddWcidAttributeEntry(pAdapter,
2513 BSS0,
2514 keyIdx,
2515 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2516 &pAdapter->MacTab.Content[BSSID_WCID]);
2517}
2518
2519int rt_ioctl_siwencodeext(struct net_device *dev,
2520 struct iw_request_info *info,
2521 union iwreq_data *wrqu,
2522 char *extra)
2523 {
2524 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2525 struct iw_point *encoding = &wrqu->encoding;
2526 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2527 int keyIdx, alg = ext->alg;
2528
2529 //check if the interface is down
2530 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2531 {
2532 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2533 return -ENETDOWN;
2534 }
2535
2536 if (encoding->flags & IW_ENCODE_DISABLED)
2537 {
2538 keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2539 // set BSSID wcid entry of the Pair-wise Key table as no-security mode
2540 AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
2541 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
2542 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
2543 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
2544 NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2545 DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __FUNCTION__, encoding->flags));
2546 }
2547 else
2548 {
2549 // Get Key Index and convet to our own defined key index
2550 keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2551 if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
2552 return -EINVAL;
2553
2554 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2555 {
2556 pAdapter->StaCfg.DefaultKeyId = keyIdx;
2557 DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __FUNCTION__, pAdapter->StaCfg.DefaultKeyId));
2558 }
2559
2560 switch (alg) {
2561 case IW_ENCODE_ALG_NONE:
2562 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __FUNCTION__));
2563 break;
2564 case IW_ENCODE_ALG_WEP:
2565 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __FUNCTION__, ext->key_len, keyIdx));
2566 if (ext->key_len == MAX_WEP_KEY_SIZE)
2567 {
2568 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
2569 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
2570 }
2571 else if (ext->key_len == MIN_WEP_KEY_SIZE)
2572 {
2573 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
2574 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
2575 }
2576 else
2577 return -EINVAL;
2578
2579 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
2580 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
2581
2582 if (pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled ||
2583 pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
2584 {
2585 // Set Group key material to Asic
2586 AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, pAdapter->SharedKey[BSS0][keyIdx].Key, NULL, NULL);
2587
2588 // Update WCID attribute table and IVEIV table for this group key table
2589 RTMPAddWcidAttributeEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, NULL);
2590
2591 STA_PORT_SECURED(pAdapter);
2592
2593 // Indicate Connected for GUI
2594 pAdapter->IndicateMediaState = NdisMediaStateConnected;
2595 }
2596 break;
2597 case IW_ENCODE_ALG_TKIP:
2598 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __FUNCTION__, keyIdx, ext->key_len));
2599 if (ext->key_len == 32)
2600 {
2601 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2602 {
2603 fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
2604 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2605 {
2606 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2607 STA_PORT_SECURED(pAdapter);
2608 }
2609 }
2610 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2611 {
2612 fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
2613
2614 // set 802.1x port control
2615 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2616 STA_PORT_SECURED(pAdapter);
2617 }
2618 }
2619 else
2620 return -EINVAL;
2621 break;
2622 case IW_ENCODE_ALG_CCMP:
2623 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2624 {
2625 fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
2626 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2627 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2628 STA_PORT_SECURED(pAdapter);
2629 }
2630 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2631 {
2632 fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
2633
2634 // set 802.1x port control
2635 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2636 STA_PORT_SECURED(pAdapter);
2637 }
2638 break;
2639 default:
2640 return -EINVAL;
2641 }
2642 }
2643
2644 return 0;
2645}
2646
2647int
2648rt_ioctl_giwencodeext(struct net_device *dev,
2649 struct iw_request_info *info,
2650 union iwreq_data *wrqu, char *extra)
2651{
2652 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2653 PCHAR pKey = NULL;
2654 struct iw_point *encoding = &wrqu->encoding;
2655 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2656 int idx, max_key_len;
2657
2658 DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
2659
2660 max_key_len = encoding->length - sizeof(*ext);
2661 if (max_key_len < 0)
2662 return -EINVAL;
2663
2664 idx = encoding->flags & IW_ENCODE_INDEX;
2665 if (idx)
2666 {
2667 if (idx < 1 || idx > 4)
2668 return -EINVAL;
2669 idx--;
2670
2671 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2672 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
2673 {
2674 if (idx != pAd->StaCfg.DefaultKeyId)
2675 {
2676 ext->key_len = 0;
2677 return 0;
2678 }
2679 }
2680 }
2681 else
2682 idx = pAd->StaCfg.DefaultKeyId;
2683
2684 encoding->flags = idx + 1;
2685 memset(ext, 0, sizeof(*ext));
2686
2687 ext->key_len = 0;
2688 switch(pAd->StaCfg.WepStatus) {
2689 case Ndis802_11WEPDisabled:
2690 ext->alg = IW_ENCODE_ALG_NONE;
2691 encoding->flags |= IW_ENCODE_DISABLED;
2692 break;
2693 case Ndis802_11WEPEnabled:
2694 ext->alg = IW_ENCODE_ALG_WEP;
2695 if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
2696 return -E2BIG;
2697 else
2698 {
2699 ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
2700 pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
2701 }
2702 break;
2703 case Ndis802_11Encryption2Enabled:
2704 case Ndis802_11Encryption3Enabled:
2705 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2706 ext->alg = IW_ENCODE_ALG_TKIP;
2707 else
2708 ext->alg = IW_ENCODE_ALG_CCMP;
2709
2710 if (max_key_len < 32)
2711 return -E2BIG;
2712 else
2713 {
2714 ext->key_len = 32;
2715 pKey = &pAd->StaCfg.PMK[0];
2716 }
2717 break;
2718 default:
2719 return -EINVAL;
2720 }
2721
2722 if (ext->key_len && pKey)
2723 {
2724 encoding->flags |= IW_ENCODE_ENABLED;
2725 memcpy(ext->key, pKey, ext->key_len);
2726 }
2727
2728 return 0;
2729}
2730
2731#ifdef SIOCSIWGENIE
2732int rt_ioctl_siwgenie(struct net_device *dev,
2733 struct iw_request_info *info,
2734 union iwreq_data *wrqu, char *extra)
2735{
2736 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2737
2738 if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
2739 (wrqu->data.length && extra == NULL))
2740 return -EINVAL;
2741
2742 if (wrqu->data.length)
2743 {
2744 pAd->StaCfg.RSNIE_Len = wrqu->data.length;
2745 NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
2746 }
2747 else
2748 {
2749 pAd->StaCfg.RSNIE_Len = 0;
2750 NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
2751 }
2752
2753 return 0;
2754}
2755#endif // SIOCSIWGENIE //
2756
2757int rt_ioctl_giwgenie(struct net_device *dev,
2758 struct iw_request_info *info,
2759 union iwreq_data *wrqu, char *extra)
2760{
2761 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2762
2763 if ((pAd->StaCfg.RSNIE_Len == 0) ||
2764 (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
2765 {
2766 wrqu->data.length = 0;
2767 return 0;
2768 }
2769
2770#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2771#ifdef SIOCSIWGENIE
2772 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
2773 {
2774 if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
2775 return -E2BIG;
2776
2777 wrqu->data.length = pAd->StaCfg.RSNIE_Len;
2778 memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2779 }
2780 else
2781#endif // SIOCSIWGENIE //
2782#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2783 {
2784 UCHAR RSNIe = IE_WPA;
2785
2786 if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
2787 return -E2BIG;
2788 wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
2789
2790 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
2791 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
2792 RSNIe = IE_RSN;
2793
2794 extra[0] = (char)RSNIe;
2795 extra[1] = pAd->StaCfg.RSNIE_Len;
2796 memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2797 }
2798
2799 return 0;
2800}
2801
2802int rt_ioctl_siwpmksa(struct net_device *dev,
2803 struct iw_request_info *info,
2804 union iwreq_data *wrqu,
2805 char *extra)
2806{
2807 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2808 struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
2809 INT CachedIdx = 0, idx = 0;
2810
2811 if (pPmksa == NULL)
2812 return -EINVAL;
2813
2814 DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
2815 switch(pPmksa->cmd)
2816 {
2817 case IW_PMKSA_FLUSH:
2818 NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
2819 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
2820 break;
2821 case IW_PMKSA_REMOVE:
2822 for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2823 {
2824 // compare the BSSID
2825 if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2826 {
2827 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
2828 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
2829 for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
2830 {
2831 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
2832 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
2833 }
2834 pAd->StaCfg.SavedPMKNum--;
2835 break;
2836 }
2837 }
2838
2839 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
2840 break;
2841 case IW_PMKSA_ADD:
2842 for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2843 {
2844 // compare the BSSID
2845 if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2846 break;
2847 }
2848
2849 // Found, replace it
2850 if (CachedIdx < PMKID_NO)
2851 {
2852 DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2853 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2854 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2855 pAd->StaCfg.SavedPMKNum++;
2856 }
2857 // Not found, replace the last one
2858 else
2859 {
2860 // Randomly replace one
2861 CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
2862 DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2863 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2864 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2865 }
2866
2867 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
2868 break;
2869 default:
2870 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
2871 break;
2872 }
2873
2874 return 0;
2875}
2876#endif // #if WIRELESS_EXT > 17
2877
2878#ifdef DBG
2879static int
2880rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info,
2881 struct iw_point *wrq, char *extra)
2882 {
2883 CHAR *this_char;
2884 CHAR *value = NULL;
2885 UCHAR regBBP = 0;
2886// CHAR arg[255]={0};
2887 UINT32 bbpId;
2888 UINT32 bbpValue;
2889 BOOLEAN bIsPrintAllBBP = FALSE;
2890 INT Status = 0;
2891 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2892
2893
2894 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2895
2896 if (wrq->length > 1) //No parameters.
2897 {
2898 sprintf(extra, "\n");
2899
2900 //Parsing Read or Write
2901 this_char = wrq->pointer;
2902 DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char));
2903 if (!*this_char)
2904 goto next;
2905
2906 if ((value = rtstrchr(this_char, '=')) != NULL)
2907 *value++ = 0;
2908
2909 if (!value || !*value)
2910 { //Read
2911 DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value));
2912 if (sscanf(this_char, "%d", &(bbpId)) == 1)
2913 {
2914 if (bbpId <= 136)
2915 {
2916#ifdef RALINK_ATE
2917 if (ATE_ON(pAdapter))
2918 {
2919 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2920 }
2921 else
2922#endif // RALINK_ATE //
2923 {
2924 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2925 }
2926 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2927 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2928 DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2929 }
2930 else
2931 {//Invalid parametes, so default printk all bbp
2932 bIsPrintAllBBP = TRUE;
2933 goto next;
2934 }
2935 }
2936 else
2937 { //Invalid parametes, so default printk all bbp
2938 bIsPrintAllBBP = TRUE;
2939 goto next;
2940 }
2941 }
2942 else
2943 { //Write
2944 if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1))
2945 {
2946 if (bbpId <= 136)
2947 {
2948#ifdef RALINK_ATE
2949 if (ATE_ON(pAdapter))
2950 {
2951 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2952 //Read it back for showing
2953 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2954 }
2955 else
2956#endif // RALINK_ATE //
2957 {
2958 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2959 //Read it back for showing
2960 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2961 }
2962 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2963 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2964 DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2965 }
2966 else
2967 {//Invalid parametes, so default printk all bbp
2968 bIsPrintAllBBP = TRUE;
2969 goto next;
2970 }
2971 }
2972 else
2973 { //Invalid parametes, so default printk all bbp
2974 bIsPrintAllBBP = TRUE;
2975 goto next;
2976 }
2977 }
2978 }
2979 else
2980 bIsPrintAllBBP = TRUE;
2981
2982next:
2983 if (bIsPrintAllBBP)
2984 {
2985 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2986 sprintf(extra, "\n");
2987 for (bbpId = 0; bbpId <= 136; bbpId++)
2988 {
2989 if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 10))
2990 break;
2991#ifdef RALINK_ATE
2992 if (ATE_ON(pAdapter))
2993 {
2994 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2995 }
2996 else
2997#endif // RALINK_ATE //
2998 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2999 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X ", bbpId, bbpId*2, regBBP);
3000 if (bbpId%5 == 4)
3001 sprintf(extra+strlen(extra), "\n");
3002 }
3003
3004 wrq->length = strlen(extra) + 1; // 1: size of '\0'
3005 DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->length));
3006 }
3007
3008 DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n"));
3009
3010 return Status;
3011}
3012#endif // DBG //
3013
3014int rt_ioctl_siwrate(struct net_device *dev,
3015 struct iw_request_info *info,
3016 union iwreq_data *wrqu, char *extra)
3017{
3018 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
3019 UINT32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
3020
3021 //check if the interface is down
3022 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3023 {
3024 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
3025 return -ENETDOWN;
3026 }
3027
3028 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
3029 /* rate = -1 => auto rate
3030 rate = X, fixed = 1 => (fixed rate X)
3031 */
3032 if (rate == -1)
3033 {
3034 //Auto Rate
3035 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3036 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
3037 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
3038 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
3039 RTMPSetDesiredRates(pAd, -1);
3040
3041#ifdef DOT11_N_SUPPORT
3042 SetCommonHT(pAd);
3043#endif // DOT11_N_SUPPORT //
3044 }
3045 else
3046 {
3047 if (fixed)
3048 {
3049 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
3050 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
3051 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
3052 RTMPSetDesiredRates(pAd, rate);
3053 else
3054 {
3055 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3056#ifdef DOT11_N_SUPPORT
3057 SetCommonHT(pAd);
3058#endif // DOT11_N_SUPPORT //
3059 }
3060 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
3061 }
3062 else
3063 {
3064 // TODO: rate = X, fixed = 0 => (rates <= X)
3065 return -EOPNOTSUPP;
3066 }
3067 }
3068
3069 return 0;
3070}
3071
3072int rt_ioctl_giwrate(struct net_device *dev,
3073 struct iw_request_info *info,
3074 union iwreq_data *wrqu, char *extra)
3075{
3076 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
3077 int rate_index = 0, rate_count = 0;
3078 HTTRANSMIT_SETTING ht_setting;
3079 __s32 ralinkrate[] =
3080 {2, 4, 11, 22, // CCK
3081 12, 18, 24, 36, 48, 72, 96, 108, // OFDM
3082 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
3083 39, 78, 117, 156, 234, 312, 351, 390, // 20MHz, 800ns GI, MCS: 16 ~ 23
3084 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
3085 81, 162, 243, 324, 486, 648, 729, 810, // 40MHz, 800ns GI, MCS: 16 ~ 23
3086 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
3087 43, 87, 130, 173, 260, 317, 390, 433, // 20MHz, 400ns GI, MCS: 16 ~ 23
3088 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
3089 90, 180, 270, 360, 540, 720, 810, 900}; // 40MHz, 400ns GI, MCS: 16 ~ 23
3090
3091 rate_count = sizeof(ralinkrate)/sizeof(__s32);
3092 //check if the interface is down
3093 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3094 {
3095 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
3096 return -ENETDOWN;
3097 }
3098
3099 if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
3100 (INFRA_ON(pAd)) &&
3101 ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
3102 ht_setting.word = pAd->StaCfg.HTPhyMode.word;
3103 else
3104 ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
3105
3106#ifdef DOT11_N_SUPPORT
3107 if (ht_setting.field.MODE >= MODE_HTMIX)
3108 {
3109// rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS);
3110 rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
3111 }
3112 else
3113#endif // DOT11_N_SUPPORT //
3114 if (ht_setting.field.MODE == MODE_OFDM)
3115 rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
3116 else if (ht_setting.field.MODE == MODE_CCK)
3117 rate_index = (UCHAR)(ht_setting.field.MCS);
3118
3119 if (rate_index < 0)
3120 rate_index = 0;
3121
3122 if (rate_index > rate_count)
3123 rate_index = rate_count;
3124
3125 wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
3126 wrqu->bitrate.disabled = 0;
3127
3128 return 0;
3129}
3130
3131static const iw_handler rt_handler[] =
3132{
3133 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3134 (iw_handler) rt_ioctl_giwname, /* SIOCGIWNAME */
3135 (iw_handler) NULL, /* SIOCSIWNWID */
3136 (iw_handler) NULL, /* SIOCGIWNWID */
3137 (iw_handler) rt_ioctl_siwfreq, /* SIOCSIWFREQ */
3138 (iw_handler) rt_ioctl_giwfreq, /* SIOCGIWFREQ */
3139 (iw_handler) rt_ioctl_siwmode, /* SIOCSIWMODE */
3140 (iw_handler) rt_ioctl_giwmode, /* SIOCGIWMODE */
3141 (iw_handler) NULL, /* SIOCSIWSENS */
3142 (iw_handler) NULL, /* SIOCGIWSENS */
3143 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
3144 (iw_handler) rt_ioctl_giwrange, /* SIOCGIWRANGE */
3145 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
3146 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
3147 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
3148 (iw_handler) rt28xx_get_wireless_stats /* kernel code */, /* SIOCGIWSTATS */
3149 (iw_handler) NULL, /* SIOCSIWSPY */
3150 (iw_handler) NULL, /* SIOCGIWSPY */
3151 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3152 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3153 (iw_handler) rt_ioctl_siwap, /* SIOCSIWAP */
3154 (iw_handler) rt_ioctl_giwap, /* SIOCGIWAP */
3155#ifdef SIOCSIWMLME
3156 (iw_handler) rt_ioctl_siwmlme, /* SIOCSIWMLME */
3157#else
3158 (iw_handler) NULL, /* SIOCSIWMLME */
3159#endif // SIOCSIWMLME //
3160 (iw_handler) rt_ioctl_iwaplist, /* SIOCGIWAPLIST */
3161#ifdef SIOCGIWSCAN
3162 (iw_handler) rt_ioctl_siwscan, /* SIOCSIWSCAN */
3163 (iw_handler) rt_ioctl_giwscan, /* SIOCGIWSCAN */
3164#else
3165 (iw_handler) NULL, /* SIOCSIWSCAN */
3166 (iw_handler) NULL, /* SIOCGIWSCAN */
3167#endif /* SIOCGIWSCAN */
3168 (iw_handler) rt_ioctl_siwessid, /* SIOCSIWESSID */
3169 (iw_handler) rt_ioctl_giwessid, /* SIOCGIWESSID */
3170 (iw_handler) rt_ioctl_siwnickn, /* SIOCSIWNICKN */
3171 (iw_handler) rt_ioctl_giwnickn, /* SIOCGIWNICKN */
3172 (iw_handler) NULL, /* -- hole -- */
3173 (iw_handler) NULL, /* -- hole -- */
3174 (iw_handler) rt_ioctl_siwrate, /* SIOCSIWRATE */
3175 (iw_handler) rt_ioctl_giwrate, /* SIOCGIWRATE */
3176 (iw_handler) rt_ioctl_siwrts, /* SIOCSIWRTS */
3177 (iw_handler) rt_ioctl_giwrts, /* SIOCGIWRTS */
3178 (iw_handler) rt_ioctl_siwfrag, /* SIOCSIWFRAG */
3179 (iw_handler) rt_ioctl_giwfrag, /* SIOCGIWFRAG */
3180 (iw_handler) NULL, /* SIOCSIWTXPOW */
3181 (iw_handler) NULL, /* SIOCGIWTXPOW */
3182 (iw_handler) NULL, /* SIOCSIWRETRY */
3183 (iw_handler) NULL, /* SIOCGIWRETRY */
3184 (iw_handler) rt_ioctl_siwencode, /* SIOCSIWENCODE */
3185 (iw_handler) rt_ioctl_giwencode, /* SIOCGIWENCODE */
3186 (iw_handler) NULL, /* SIOCSIWPOWER */
3187 (iw_handler) NULL, /* SIOCGIWPOWER */
3188 (iw_handler) NULL, /* -- hole -- */
3189 (iw_handler) NULL, /* -- hole -- */
3190#if WIRELESS_EXT > 17
3191 (iw_handler) rt_ioctl_siwgenie, /* SIOCSIWGENIE */
3192 (iw_handler) rt_ioctl_giwgenie, /* SIOCGIWGENIE */
3193 (iw_handler) rt_ioctl_siwauth, /* SIOCSIWAUTH */
3194 (iw_handler) rt_ioctl_giwauth, /* SIOCGIWAUTH */
3195 (iw_handler) rt_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
3196 (iw_handler) rt_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
3197 (iw_handler) rt_ioctl_siwpmksa, /* SIOCSIWPMKSA */
3198#endif
3199};
3200
3201static const iw_handler rt_priv_handlers[] = {
3202 (iw_handler) NULL, /* + 0x00 */
3203 (iw_handler) NULL, /* + 0x01 */
3204#ifndef CONFIG_AP_SUPPORT
3205 (iw_handler) rt_ioctl_setparam, /* + 0x02 */
3206#else
3207 (iw_handler) NULL, /* + 0x02 */
3208#endif // CONFIG_AP_SUPPORT //
3209#ifdef DBG
3210 (iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
3211#else
3212 (iw_handler) NULL, /* + 0x03 */
3213#endif
3214 (iw_handler) NULL, /* + 0x04 */
3215 (iw_handler) NULL, /* + 0x05 */
3216 (iw_handler) NULL, /* + 0x06 */
3217 (iw_handler) NULL, /* + 0x07 */
3218 (iw_handler) NULL, /* + 0x08 */
3219 (iw_handler) rt_private_get_statistics, /* + 0x09 */
3220 (iw_handler) NULL, /* + 0x0A */
3221 (iw_handler) NULL, /* + 0x0B */
3222 (iw_handler) NULL, /* + 0x0C */
3223 (iw_handler) NULL, /* + 0x0D */
3224 (iw_handler) NULL, /* + 0x0E */
3225 (iw_handler) NULL, /* + 0x0F */
3226 (iw_handler) NULL, /* + 0x10 */
3227 (iw_handler) rt_private_show, /* + 0x11 */
3228 (iw_handler) NULL, /* + 0x12 */
3229 (iw_handler) NULL, /* + 0x13 */
3230 (iw_handler) NULL, /* + 0x15 */
3231 (iw_handler) NULL, /* + 0x17 */
3232 (iw_handler) NULL, /* + 0x18 */
3233};
3234
3235const struct iw_handler_def rt28xx_iw_handler_def =
3236{
3237#define N(a) (sizeof (a) / sizeof (a[0]))
3238 .standard = (iw_handler *) rt_handler,
3239 .num_standard = sizeof(rt_handler) / sizeof(iw_handler),
3240 .private = (iw_handler *) rt_priv_handlers,
3241 .num_private = N(rt_priv_handlers),
3242 .private_args = (struct iw_priv_args *) privtab,
3243 .num_private_args = N(privtab),
3244#if IW_HANDLER_VERSION >= 7
3245 .get_wireless_stats = rt28xx_get_wireless_stats,
3246#endif
3247};
3248
3249INT RTMPSetInformation(
3250 IN PRTMP_ADAPTER pAdapter,
3251 IN OUT struct ifreq *rq,
3252 IN INT cmd)
3253{
3254 struct iwreq *wrq = (struct iwreq *) rq;
3255 NDIS_802_11_SSID Ssid;
3256 NDIS_802_11_MAC_ADDRESS Bssid;
3257 RT_802_11_PHY_MODE PhyMode;
3258 RT_802_11_STA_CONFIG StaConfig;
3259 NDIS_802_11_RATES aryRates;
3260 RT_802_11_PREAMBLE Preamble;
3261 NDIS_802_11_WEP_STATUS WepStatus;
3262 NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeMax;
3263 NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
3264 NDIS_802_11_RTS_THRESHOLD RtsThresh;
3265 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
3266 NDIS_802_11_POWER_MODE PowerMode;
3267 PNDIS_802_11_KEY pKey = NULL;
3268 PNDIS_802_11_WEP pWepKey =NULL;
3269 PNDIS_802_11_REMOVE_KEY pRemoveKey = NULL;
3270 NDIS_802_11_CONFIGURATION Config, *pConfig = NULL;
3271 NDIS_802_11_NETWORK_TYPE NetType;
3272 ULONG Now;
3273 UINT KeyIdx = 0;
3274 INT Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
3275 ULONG PowerTemp;
3276 BOOLEAN RadioState;
3277 BOOLEAN StateMachineTouched = FALSE;
3278#ifdef DOT11_N_SUPPORT
3279 OID_SET_HT_PHYMODE HT_PhyMode; //11n ,kathy
3280#endif // DOT11_N_SUPPORT //
3281#ifdef WPA_SUPPLICANT_SUPPORT
3282 PNDIS_802_11_PMKID pPmkId = NULL;
3283 BOOLEAN IEEE8021xState = FALSE;
3284 BOOLEAN IEEE8021x_required_keys = FALSE;
3285 UCHAR wpa_supplicant_enable = 0;
3286#endif // WPA_SUPPLICANT_SUPPORT //
3287
3288#ifdef SNMP_SUPPORT
3289 TX_RTY_CFG_STRUC tx_rty_cfg;
3290 ULONG ShortRetryLimit, LongRetryLimit;
3291 UCHAR ctmp;
3292#endif // SNMP_SUPPORT //
3293
3294
3295
3296#ifdef DOT11_N_SUPPORT
3297 MaxPhyMode = PHY_11N_5G;
3298#endif // DOT11_N_SUPPORT //
3299
3300
3301 DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(), 0x%08x\n", cmd&0x7FFF));
3302 switch(cmd & 0x7FFF) {
3303 case RT_OID_802_11_COUNTRY_REGION:
3304 if (wrq->u.data.length < sizeof(UCHAR))
3305 Status = -EINVAL;
3306 // Only avaliable when EEPROM not programming
3307 else if (!(pAdapter->CommonCfg.CountryRegion & 0x80) && !(pAdapter->CommonCfg.CountryRegionForABand & 0x80))
3308 {
3309 ULONG Country;
3310 UCHAR TmpPhy;
3311
3312 Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
3313 pAdapter->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
3314 pAdapter->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
3315 TmpPhy = pAdapter->CommonCfg.PhyMode;
3316 pAdapter->CommonCfg.PhyMode = 0xff;
3317 // Build all corresponding channel information
3318 RTMPSetPhyMode(pAdapter, TmpPhy);
3319#ifdef DOT11_N_SUPPORT
3320 SetCommonHT(pAdapter);
3321#endif // DOT11_N_SUPPORT //
3322 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d B/G:%d)\n", pAdapter->CommonCfg.CountryRegionForABand,
3323 pAdapter->CommonCfg.CountryRegion));
3324 }
3325 break;
3326 case OID_802_11_BSSID_LIST_SCAN:
3327 #ifdef RALINK_ATE
3328 if (ATE_ON(pAdapter))
3329 {
3330 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3331 break;
3332 }
3333#endif // RALINK_ATE //
3334 Now = jiffies;
3335 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAdapter->RalinkCounters.LastOneSecTotalTxCount));
3336
3337 if (MONITOR_ON(pAdapter))
3338 {
3339 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
3340 break;
3341 }
3342
3343 //Benson add 20080527, when radio off, sta don't need to scan
3344 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
3345 break;
3346
3347 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
3348 {
3349 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
3350 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3351 Status = NDIS_STATUS_SUCCESS;
3352 break;
3353 }
3354
3355 if (pAdapter->RalinkCounters.LastOneSecTotalTxCount > 100)
3356 {
3357 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3358 Status = NDIS_STATUS_SUCCESS;
3359 pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
3360 break;
3361 }
3362
3363 if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
3364 ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
3365 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3366 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
3367 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
3368 (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
3369 {
3370 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3371 Status = NDIS_STATUS_SUCCESS;
3372 pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
3373 break;
3374 }
3375
3376
3377 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3378 {
3379 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3380 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3381 }
3382
3383 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3384 // this request, because this request is initiated by NDIS.
3385 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3386 // Reset allowed scan retries
3387 pAdapter->StaCfg.ScanCnt = 0;
3388 pAdapter->StaCfg.LastScanTime = Now;
3389
3390 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3391 RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3392 MlmeEnqueue(pAdapter,
3393 MLME_CNTL_STATE_MACHINE,
3394 OID_802_11_BSSID_LIST_SCAN,
3395 0,
3396 NULL);
3397
3398 Status = NDIS_STATUS_SUCCESS;
3399 StateMachineTouched = TRUE;
3400 break;
3401 case OID_802_11_SSID:
3402 if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
3403 Status = -EINVAL;
3404 else
3405 {
3406 PCHAR pSsidString = NULL;
3407 Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
3408
3409 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
3410 if (Ssid.SsidLength > MAX_LEN_OF_SSID)
3411 Status = -EINVAL;
3412 else
3413 {
3414 if (Ssid.SsidLength == 0)
3415 {
3416 Set_SSID_Proc(pAdapter, "");
3417 }
3418 else
3419 {
3420 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
3421 if (pSsidString)
3422 {
3423 NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
3424 NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
3425 Set_SSID_Proc(pAdapter, pSsidString);
3426 kfree(pSsidString);
3427 }
3428 else
3429 Status = -ENOMEM;
3430 }
3431 }
3432 }
3433 break;
3434 case OID_802_11_BSSID:
3435#ifdef RALINK_ATE
3436 if (ATE_ON(pAdapter))
3437 {
3438 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3439 break;
3440 }
3441#endif // RALINK_ATE //
3442 if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
3443 Status = -EINVAL;
3444 else
3445 {
3446 Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
3447
3448 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3449 // this request, because this request is initiated by NDIS.
3450 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3451
3452 // Prevent to connect AP again in STAMlmePeriodicExec
3453 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3454
3455 // Reset allowed scan retries
3456 pAdapter->StaCfg.ScanCnt = 0;
3457
3458 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3459 {
3460 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3461 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3462 }
3463 MlmeEnqueue(pAdapter,
3464 MLME_CNTL_STATE_MACHINE,
3465 OID_802_11_BSSID,
3466 sizeof(NDIS_802_11_MAC_ADDRESS),
3467 (VOID *)&Bssid);
3468 Status = NDIS_STATUS_SUCCESS;
3469 StateMachineTouched = TRUE;
3470
3471 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
3472 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
3473 }
3474 break;
3475 case RT_OID_802_11_RADIO:
3476 if (wrq->u.data.length != sizeof(BOOLEAN))
3477 Status = -EINVAL;
3478 else
3479 {
3480 Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
3481 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
3482 if (pAdapter->StaCfg.bSwRadio != RadioState)
3483 {
3484 pAdapter->StaCfg.bSwRadio = RadioState;
3485 if (pAdapter->StaCfg.bRadio != (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio))
3486 {
3487 pAdapter->StaCfg.bRadio = (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio);
3488 if (pAdapter->StaCfg.bRadio == TRUE)
3489 {
3490 MlmeRadioOn(pAdapter);
3491 // Update extra information
3492 pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;
3493 }
3494 else
3495 {
3496 MlmeRadioOff(pAdapter);
3497 // Update extra information
3498 pAdapter->ExtraInfo = SW_RADIO_OFF;
3499 }
3500 }
3501 }
3502 }
3503 break;
3504 case RT_OID_802_11_PHY_MODE:
3505 if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
3506 Status = -EINVAL;
3507 else
3508 {
3509 Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3510 if (PhyMode <= MaxPhyMode)
3511 {
3512 RTMPSetPhyMode(pAdapter, PhyMode);
3513#ifdef DOT11_N_SUPPORT
3514 SetCommonHT(pAdapter);
3515#endif // DOT11_N_SUPPORT //
3516 }
3517 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
3518 }
3519 break;
3520 case RT_OID_802_11_STA_CONFIG:
3521 if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
3522 Status = -EINVAL;
3523 else
3524 {
3525 Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
3526 pAdapter->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
3527 pAdapter->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
3528 pAdapter->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
3529 if ((pAdapter->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
3530 (StaConfig.AdhocMode <= MaxPhyMode))
3531 {
3532 // allow dynamic change of "USE OFDM rate or not" in ADHOC mode
3533 // if setting changed, need to reset current TX rate as well as BEACON frame format
3534 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
3535 {
3536 pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
3537 RTMPSetPhyMode(pAdapter, PhyMode);
3538 MlmeUpdateTxRates(pAdapter, FALSE, 0);
3539 MakeIbssBeacon(pAdapter); // re-build BEACON frame
3540 AsicEnableIbssSync(pAdapter); // copy to on-chip memory
3541 }
3542 }
3543 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
3544 pAdapter->CommonCfg.bEnableTxBurst,
3545 pAdapter->CommonCfg.UseBGProtection,
3546 pAdapter->CommonCfg.bUseShortSlotTime));
3547 }
3548 break;
3549 case OID_802_11_DESIRED_RATES:
3550 if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
3551 Status = -EINVAL;
3552 else
3553 {
3554 Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
3555 NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
3556 NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
3557 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
3558 pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
3559 pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
3560 pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
3561 pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
3562 // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
3563 MlmeUpdateTxRates(pAdapter, FALSE, 0);
3564 }
3565 break;
3566 case RT_OID_802_11_PREAMBLE:
3567 if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
3568 Status = -EINVAL;
3569 else
3570 {
3571 Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
3572 if (Preamble == Rt802_11PreambleShort)
3573 {
3574 pAdapter->CommonCfg.TxPreamble = Preamble;
3575 MlmeSetTxPreamble(pAdapter, Rt802_11PreambleShort);
3576 }
3577 else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
3578 {
3579 // if user wants AUTO, initialize to LONG here, then change according to AP's
3580 // capability upon association.
3581 pAdapter->CommonCfg.TxPreamble = Preamble;
3582 MlmeSetTxPreamble(pAdapter, Rt802_11PreambleLong);
3583 }
3584 else
3585 {
3586 Status = -EINVAL;
3587 break;
3588 }
3589 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
3590 }
3591 break;
3592 case OID_802_11_WEP_STATUS:
3593 if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
3594 Status = -EINVAL;
3595 else
3596 {
3597 Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
3598 // Since TKIP, AES, WEP are all supported. It should not have any invalid setting
3599 if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
3600 {
3601 if (pAdapter->StaCfg.WepStatus != WepStatus)
3602 {
3603 // Config has changed
3604 pAdapter->bConfigChanged = TRUE;
3605 }
3606 pAdapter->StaCfg.WepStatus = WepStatus;
3607 pAdapter->StaCfg.OrigWepStatus = WepStatus;
3608 pAdapter->StaCfg.PairCipher = WepStatus;
3609 pAdapter->StaCfg.GroupCipher = WepStatus;
3610 }
3611 else
3612 {
3613 Status = -EINVAL;
3614 break;
3615 }
3616 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
3617 }
3618 break;
3619 case OID_802_11_AUTHENTICATION_MODE:
3620 if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
3621 Status = -EINVAL;
3622 else
3623 {
3624 Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
3625 if (AuthMode > Ndis802_11AuthModeMax)
3626 {
3627 Status = -EINVAL;
3628 break;
3629 }
3630 else
3631 {
3632 if (pAdapter->StaCfg.AuthMode != AuthMode)
3633 {
3634 // Config has changed
3635 pAdapter->bConfigChanged = TRUE;
3636 }
3637 pAdapter->StaCfg.AuthMode = AuthMode;
3638 }
3639 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3640 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAdapter->StaCfg.AuthMode));
3641 }
3642 break;
3643 case OID_802_11_INFRASTRUCTURE_MODE:
3644 if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
3645 Status = -EINVAL;
3646 else
3647 {
3648 Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
3649
3650 if (BssType == Ndis802_11IBSS)
3651 Set_NetworkType_Proc(pAdapter, "Adhoc");
3652 else if (BssType == Ndis802_11Infrastructure)
3653 Set_NetworkType_Proc(pAdapter, "Infra");
3654 else if (BssType == Ndis802_11Monitor)
3655 Set_NetworkType_Proc(pAdapter, "Monitor");
3656 else
3657 {
3658 Status = -EINVAL;
3659 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
3660 }
3661 }
3662 break;
3663 case OID_802_11_REMOVE_WEP:
3664 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
3665 if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
3666 {
3667 Status = -EINVAL;
3668 }
3669 else
3670 {
3671 KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
3672
3673 if (KeyIdx & 0x80000000)
3674 {
3675 // Should never set default bit when remove key
3676 Status = -EINVAL;
3677 }
3678 else
3679 {
3680 KeyIdx = KeyIdx & 0x0fffffff;
3681 if (KeyIdx >= 4){
3682 Status = -EINVAL;
3683 }
3684 else
3685 {
3686 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3687 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3688 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3689 }
3690 }
3691 }
3692 break;
3693 case RT_OID_802_11_RESET_COUNTERS:
3694 NdisZeroMemory(&pAdapter->WlanCounters, sizeof(COUNTER_802_11));
3695 NdisZeroMemory(&pAdapter->Counters8023, sizeof(COUNTER_802_3));
3696 NdisZeroMemory(&pAdapter->RalinkCounters, sizeof(COUNTER_RALINK));
3697 pAdapter->Counters8023.RxNoBuffer = 0;
3698 pAdapter->Counters8023.GoodReceives = 0;
3699 pAdapter->Counters8023.RxNoBuffer = 0;
3700#ifdef RT2870
3701 pAdapter->BulkOutComplete = 0;
3702 pAdapter->BulkOutCompleteOther= 0;
3703 pAdapter->BulkOutCompleteCancel = 0;
3704 pAdapter->BulkOutReq = 0;
3705 pAdapter->BulkInReq= 0;
3706 pAdapter->BulkInComplete = 0;
3707 pAdapter->BulkInCompleteFail = 0;
3708#endif // RT2870 //
3709 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
3710 break;
3711 case OID_802_11_RTS_THRESHOLD:
3712 if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
3713 Status = -EINVAL;
3714 else
3715 {
3716 Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
3717 if (RtsThresh > MAX_RTS_THRESHOLD)
3718 Status = -EINVAL;
3719 else
3720 pAdapter->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
3721 }
3722 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
3723 break;
3724 case OID_802_11_FRAGMENTATION_THRESHOLD:
3725 if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
3726 Status = -EINVAL;
3727 else
3728 {
3729 Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
3730 pAdapter->CommonCfg.bUseZeroToDisableFragment = FALSE;
3731 if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
3732 {
3733 if (FragThresh == 0)
3734 {
3735 pAdapter->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
3736 pAdapter->CommonCfg.bUseZeroToDisableFragment = TRUE;
3737 }
3738 else
3739 Status = -EINVAL;
3740 }
3741 else
3742 pAdapter->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
3743 }
3744 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
3745 break;
3746 case OID_802_11_POWER_MODE:
3747 if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
3748 Status = -EINVAL;
3749 else
3750 {
3751 Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
3752 if (PowerMode == Ndis802_11PowerModeCAM)
3753 Set_PSMode_Proc(pAdapter, "CAM");
3754 else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
3755 Set_PSMode_Proc(pAdapter, "Max_PSP");
3756 else if (PowerMode == Ndis802_11PowerModeFast_PSP)
3757 Set_PSMode_Proc(pAdapter, "Fast_PSP");
3758 else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
3759 Set_PSMode_Proc(pAdapter, "Legacy_PSP");
3760 else
3761 Status = -EINVAL;
3762 }
3763 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
3764 break;
3765 case RT_OID_802_11_TX_POWER_LEVEL_1:
3766 if (wrq->u.data.length < sizeof(ULONG))
3767 Status = -EINVAL;
3768 else
3769 {
3770 Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
3771 if (PowerTemp > 100)
3772 PowerTemp = 0xffffffff; // AUTO
3773 pAdapter->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
3774 pAdapter->CommonCfg.TxPowerPercentage = pAdapter->CommonCfg.TxPowerDefault;
3775 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
3776 }
3777 break;
3778 case OID_802_11_NETWORK_TYPE_IN_USE:
3779 if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
3780 Status = -EINVAL;
3781 else
3782 {
3783 Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
3784
3785 if (NetType == Ndis802_11DS)
3786 RTMPSetPhyMode(pAdapter, PHY_11B);
3787 else if (NetType == Ndis802_11OFDM24)
3788 RTMPSetPhyMode(pAdapter, PHY_11BG_MIXED);
3789 else if (NetType == Ndis802_11OFDM5)
3790 RTMPSetPhyMode(pAdapter, PHY_11A);
3791 else
3792 Status = -EINVAL;
3793#ifdef DOT11_N_SUPPORT
3794 if (Status == NDIS_STATUS_SUCCESS)
3795 SetCommonHT(pAdapter);
3796#endif // DOT11_N_SUPPORT //
3797 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
3798 }
3799 break;
3800 // For WPA PSK PMK key
3801 case RT_OID_802_11_ADD_WPA:
3802 pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3803 if(pKey == NULL)
3804 {
3805 Status = -ENOMEM;
3806 break;
3807 }
3808
3809 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3810 if (pKey->Length != wrq->u.data.length)
3811 {
3812 Status = -EINVAL;
3813 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
3814 }
3815 else
3816 {
3817 if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
3818 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
3819 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
3820 {
3821 Status = -EOPNOTSUPP;
3822 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
3823 }
3824 else if ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3825 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
3826 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) ) // Only for WPA PSK mode
3827 {
3828 NdisMoveMemory(pAdapter->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
3829 // Use RaConfig as PSK agent.
3830 // Start STA supplicant state machine
3831 if (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
3832 pAdapter->StaCfg.WpaState = SS_START;
3833
3834 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3835 }
3836 else
3837 {
3838 pAdapter->StaCfg.WpaState = SS_NOTUSE;
3839 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3840 }
3841 }
3842 kfree(pKey);
3843 break;
3844 case OID_802_11_REMOVE_KEY:
3845 pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3846 if(pRemoveKey == NULL)
3847 {
3848 Status = -ENOMEM;
3849 break;
3850 }
3851
3852 Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
3853 if (pRemoveKey->Length != wrq->u.data.length)
3854 {
3855 Status = -EINVAL;
3856 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
3857 }
3858 else
3859 {
3860 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3861 {
3862 RTMPWPARemoveKeyProc(pAdapter, pRemoveKey);
3863 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
3864 }
3865 else
3866 {
3867 KeyIdx = pRemoveKey->KeyIndex;
3868
3869 if (KeyIdx & 0x80000000)
3870 {
3871 // Should never set default bit when remove key
3872 Status = -EINVAL;
3873 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
3874 }
3875 else
3876 {
3877 KeyIdx = KeyIdx & 0x0fffffff;
3878 if (KeyIdx > 3)
3879 {
3880 Status = -EINVAL;
3881 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
3882 }
3883 else
3884 {
3885 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3886 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3887 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3888 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
3889 }
3890 }
3891 }
3892 }
3893 kfree(pRemoveKey);
3894 break;
3895 // New for WPA
3896 case OID_802_11_ADD_KEY:
3897 pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3898 if(pKey == NULL)
3899 {
3900 Status = -ENOMEM;
3901 break;
3902 }
3903 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3904 if (pKey->Length != wrq->u.data.length)
3905 {
3906 Status = -EINVAL;
3907 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
3908 }
3909 else
3910 {
3911 RTMPAddKey(pAdapter, pKey);
3912 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3913 }
3914 kfree(pKey);
3915 break;
3916 case OID_802_11_CONFIGURATION:
3917 if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
3918 Status = -EINVAL;
3919 else
3920 {
3921 Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
3922 pConfig = &Config;
3923
3924 if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
3925 pAdapter->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
3926
3927 pAdapter->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
3928 MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAdapter->CommonCfg.Channel);
3929 //
3930 // Save the channel on MlmeAux for CntlOidRTBssidProc used.
3931 //
3932 pAdapter->MlmeAux.Channel = pAdapter->CommonCfg.Channel;
3933
3934 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
3935 pConfig->BeaconPeriod, pConfig->ATIMWindow, pAdapter->CommonCfg.Channel));
3936 // Config has changed
3937 pAdapter->bConfigChanged = TRUE;
3938 }
3939 break;
3940#ifdef DOT11_N_SUPPORT
3941 case RT_OID_802_11_SET_HT_PHYMODE:
3942 if (wrq->u.data.length != sizeof(OID_SET_HT_PHYMODE))
3943 Status = -EINVAL;
3944 else
3945 {
3946 POID_SET_HT_PHYMODE pHTPhyMode = &HT_PhyMode;
3947
3948 Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3949 DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode (PhyMode = %d,TransmitNo = %d, HtMode = %d, ExtOffset = %d , MCS = %d, BW = %d, STBC = %d, SHORTGI = %d) \n",
3950 pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
3951 pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
3952 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
3953 RTMPSetHT(pAdapter, pHTPhyMode);
3954 }
3955 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
3956 pAdapter->StaCfg.HTPhyMode.field.MCS, pAdapter->StaCfg.HTPhyMode.field.BW, pAdapter->StaCfg.HTPhyMode.field.ShortGI,
3957 pAdapter->StaCfg.HTPhyMode.field.STBC));
3958 break;
3959#endif // DOT11_N_SUPPORT //
3960 case RT_OID_802_11_SET_APSD_SETTING:
3961 if (wrq->u.data.length != sizeof(ULONG))
3962 Status = -EINVAL;
3963 else
3964 {
3965 ULONG apsd ;
3966 Status = copy_from_user(&apsd, wrq->u.data.pointer, wrq->u.data.length);
3967
3968 /*-------------------------------------------------------------------
3969 |B31~B7 | B6~B5 | B4 | B3 | B2 | B1 | B0 |
3970 ---------------------------------------------------------------------
3971 | Rsvd | Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD Capable |
3972 ---------------------------------------------------------------------*/
3973 pAdapter->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE : FALSE;
3974 pAdapter->CommonCfg.bAPSDAC_BE = ((apsd & 0x00000002) >> 1) ? TRUE : FALSE;
3975 pAdapter->CommonCfg.bAPSDAC_BK = ((apsd & 0x00000004) >> 2) ? TRUE : FALSE;
3976 pAdapter->CommonCfg.bAPSDAC_VI = ((apsd & 0x00000008) >> 3) ? TRUE : FALSE;
3977 pAdapter->CommonCfg.bAPSDAC_VO = ((apsd & 0x00000010) >> 4) ? TRUE : FALSE;
3978 pAdapter->CommonCfg.MaxSPLength = (UCHAR)((apsd & 0x00000060) >> 5);
3979
3980 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,
3981 pAdapter->CommonCfg.bAPSDAC_BE, pAdapter->CommonCfg.bAPSDAC_BK, pAdapter->CommonCfg.bAPSDAC_VI, pAdapter->CommonCfg.bAPSDAC_VO, pAdapter->CommonCfg.MaxSPLength));
3982 }
3983 break;
3984
3985 case RT_OID_802_11_SET_APSD_PSM:
3986 if (wrq->u.data.length != sizeof(ULONG))
3987 Status = -EINVAL;
3988 else
3989 {
3990 // Driver needs to notify AP when PSM changes
3991 Status = copy_from_user(&pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
3992 if (pAdapter->CommonCfg.bAPSDForcePowerSave != pAdapter->StaCfg.Psm)
3993 {
3994 MlmeSetPsmBit(pAdapter, pAdapter->CommonCfg.bAPSDForcePowerSave);
3995 RTMPSendNullFrame(pAdapter, pAdapter->CommonCfg.TxRate, TRUE);
3996 }
3997 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
3998 }
3999 break;
4000#ifdef QOS_DLS_SUPPORT
4001 case RT_OID_802_11_SET_DLS:
4002 if (wrq->u.data.length != sizeof(ULONG))
4003 Status = -EINVAL;
4004 else
4005 {
4006 BOOLEAN oldvalue = pAdapter->CommonCfg.bDLSCapable;
4007 Status = copy_from_user(&pAdapter->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
4008 if (oldvalue && !pAdapter->CommonCfg.bDLSCapable)
4009 {
4010 int i;
4011 // tear down local dls table entry
4012 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
4013 {
4014 if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
4015 {
4016 pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
4017 pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
4018 RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
4019 }
4020 }
4021
4022 // tear down peer dls table entry
4023 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
4024 {
4025 if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
4026 {
4027 pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
4028 pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
4029 RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
4030 }
4031 }
4032 }
4033
4034 DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAdapter->CommonCfg.bDLSCapable));
4035 }
4036 break;
4037
4038 case RT_OID_802_11_SET_DLS_PARAM:
4039 if (wrq->u.data.length != sizeof(RT_802_11_DLS_UI))
4040 Status = -EINVAL;
4041 else
4042 {
4043 RT_802_11_DLS Dls;
4044
4045 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
4046 RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI));
4047 MlmeEnqueue(pAdapter,
4048 MLME_CNTL_STATE_MACHINE,
4049 RT_OID_802_11_SET_DLS_PARAM,
4050 sizeof(RT_802_11_DLS),
4051 &Dls);
4052 DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n"));
4053 }
4054 break;
4055#endif // QOS_DLS_SUPPORT //
4056 case RT_OID_802_11_SET_WMM:
4057 if (wrq->u.data.length != sizeof(BOOLEAN))
4058 Status = -EINVAL;
4059 else
4060 {
4061 Status = copy_from_user(&pAdapter->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
4062 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d) \n", pAdapter->CommonCfg.bWmmCapable));
4063 }
4064 break;
4065
4066 case OID_802_11_DISASSOCIATE:
4067#ifdef RALINK_ATE
4068 if (ATE_ON(pAdapter))
4069 {
4070 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4071 break;
4072 }
4073#endif // RALINK_ATE //
4074 //
4075 // Set NdisRadioStateOff to TRUE, instead of called MlmeRadioOff.
4076 // Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be 0
4077 // when query OID_802_11_BSSID_LIST.
4078 //
4079 // TRUE: NumberOfItems will set to 0.
4080 // FALSE: NumberOfItems no change.
4081 //
4082 pAdapter->CommonCfg.NdisRadioStateOff = TRUE;
4083 // Set to immediately send the media disconnect event
4084 pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
4085 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE \n"));
4086
4087 if (INFRA_ON(pAdapter))
4088 {
4089 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
4090 {
4091 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
4092 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
4093 }
4094
4095 MlmeEnqueue(pAdapter,
4096 MLME_CNTL_STATE_MACHINE,
4097 OID_802_11_DISASSOCIATE,
4098 0,
4099 NULL);
4100
4101 StateMachineTouched = TRUE;
4102 }
4103 break;
4104
4105#ifdef DOT11_N_SUPPORT
4106 case RT_OID_802_11_SET_IMME_BA_CAP:
4107 if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
4108 Status = -EINVAL;
4109 else
4110 {
4111 OID_BACAP_STRUC Orde ;
4112 Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
4113 if (Orde.Policy > BA_NOTUSE)
4114 {
4115 Status = NDIS_STATUS_INVALID_DATA;
4116 }
4117 else if (Orde.Policy == BA_NOTUSE)
4118 {
4119 pAdapter->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
4120 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4121 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4122 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4123 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4124 pAdapter->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
4125 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4126 // UPdata to HT IE
4127 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4128 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4129 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4130 }
4131 else
4132 {
4133 pAdapter->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
4134 pAdapter->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
4135 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4136 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4137 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4138 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4139 pAdapter->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
4140 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4141
4142 // UPdata to HT IE
4143 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4144 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4145 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4146
4147 if (pAdapter->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
4148 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
4149
4150 }
4151
4152 pAdapter->CommonCfg.REGBACapability.word = pAdapter->CommonCfg.BACapability.word;
4153 DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAdapter->CommonCfg.BACapability.field.Policy,
4154 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit,pAdapter->CommonCfg.BACapability.field.TxBAWinLimit, pAdapter->CommonCfg.BACapability.field.AutoBA));
4155 DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAdapter->CommonCfg.DesiredHtPhy.MimoPs, pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable,
4156 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize, pAdapter->CommonCfg.DesiredHtPhy.MpduDensity));
4157 }
4158
4159 break;
4160 case RT_OID_802_11_ADD_IMME_BA:
4161 DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
4162 if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4163 Status = -EINVAL;
4164 else
4165 {
4166 UCHAR index;
4167 OID_ADD_BA_ENTRY BA;
4168 MAC_TABLE_ENTRY *pEntry;
4169
4170 Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
4171 if (BA.TID > 15)
4172 {
4173 Status = NDIS_STATUS_INVALID_DATA;
4174 break;
4175 }
4176 else
4177 {
4178 //BATableInsertEntry
4179 //As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
4180 index = BA.TID;
4181 // in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
4182 pEntry = MacTableLookup(pAdapter, BA.MACAddr);
4183 if (!pEntry)
4184 {
4185 DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
4186 break;
4187 }
4188 if (BA.IsRecipient == FALSE)
4189 {
4190 if (pEntry->bIAmBadAtheros == TRUE)
4191 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
4192
4193 BAOriSessionSetUp(pAdapter, pEntry, index, 0, 100, TRUE);
4194 }
4195 else
4196 {
4197 //BATableInsertEntry(pAdapter, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
4198 }
4199
4200 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
4201 BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
4202 , BA.MACAddr[4], BA.MACAddr[5]));
4203 }
4204 }
4205 break;
4206
4207 case RT_OID_802_11_TEAR_IMME_BA:
4208 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
4209 if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4210 Status = -EINVAL;
4211 else
4212 {
4213 POID_ADD_BA_ENTRY pBA;
4214 MAC_TABLE_ENTRY *pEntry;
4215
4216 pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4217
4218 if (pBA == NULL)
4219 {
4220 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
4221 Status = NDIS_STATUS_FAILURE;
4222 }
4223 else
4224 {
4225 Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
4226 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
4227
4228 if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
4229 {
4230 Status = NDIS_STATUS_INVALID_DATA;
4231 break;
4232 }
4233
4234 if (pBA->IsRecipient == FALSE)
4235 {
4236 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4237 DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
4238 if (pEntry)
4239 {
4240 DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
4241 BAOriSessionTearDown(pAdapter, pEntry->Aid, pBA->TID, FALSE, TRUE);
4242 }
4243 else
4244 DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4245 }
4246 else
4247 {
4248 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4249 if (pEntry)
4250 {
4251 BARecSessionTearDown( pAdapter, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
4252 }
4253 else
4254 DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4255 }
4256 kfree(pBA);
4257 }
4258 }
4259 break;
4260#endif // DOT11_N_SUPPORT //
4261
4262 // For WPA_SUPPLICANT to set static wep key
4263 case OID_802_11_ADD_WEP:
4264 pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4265
4266 if(pWepKey == NULL)
4267 {
4268 Status = -ENOMEM;
4269 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
4270 break;
4271 }
4272 Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
4273 if (Status)
4274 {
4275 Status = -EINVAL;
4276 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
4277 }
4278 else
4279 {
4280 KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
4281 // KeyIdx must be 0 ~ 3
4282 if (KeyIdx > 4)
4283 {
4284 Status = -EINVAL;
4285 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
4286 }
4287 else
4288 {
4289 UCHAR CipherAlg = 0;
4290 PUCHAR Key;
4291
4292 // set key material and key length
4293 NdisZeroMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, 16);
4294 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4295 NdisMoveMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4296
4297 switch(pWepKey->KeyLength)
4298 {
4299 case 5:
4300 CipherAlg = CIPHER_WEP64;
4301 break;
4302 case 13:
4303 CipherAlg = CIPHER_WEP128;
4304 break;
4305 default:
4306 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
4307 Status = -EINVAL;
4308 break;
4309 }
4310 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
4311
4312 // Default key for tx (shared key)
4313 if (pWepKey->KeyIndex & 0x80000000)
4314 {
4315#ifdef WPA_SUPPLICANT_SUPPORT
4316 // set key material and key length
4317 NdisZeroMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
4318 pAdapter->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4319 NdisMoveMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4320 pAdapter->StaCfg.DesireSharedKeyId = KeyIdx;
4321 pAdapter->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
4322#endif // WPA_SUPPLICANT_SUPPORT //
4323 pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4324 }
4325
4326#ifdef WPA_SUPPLICANT_SUPPORT
4327 if ((pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) &&
4328 (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
4329 {
4330 Key = pWepKey->KeyMaterial;
4331
4332 // Set Group key material to Asic
4333 AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
4334
4335 // Update WCID attribute table and IVEIV table for this group key table
4336 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
4337
4338 STA_PORT_SECURED(pAdapter);
4339
4340 // Indicate Connected for GUI
4341 pAdapter->IndicateMediaState = NdisMediaStateConnected;
4342 }
4343 else if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
4344#endif // WPA_SUPPLICANT_SUPPORT
4345 {
4346 Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
4347
4348 // Set key material and cipherAlg to Asic
4349 AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
4350
4351 if (pWepKey->KeyIndex & 0x80000000)
4352 {
4353 PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[BSSID_WCID];
4354 // Assign group key info
4355 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
4356 // Assign pairwise key info
4357 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, pEntry);
4358 }
4359 }
4360 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"));
4361 }
4362 }
4363 kfree(pWepKey);
4364 break;
4365#ifdef WPA_SUPPLICANT_SUPPORT
4366 case OID_SET_COUNTERMEASURES:
4367 if (wrq->u.data.length != sizeof(int))
4368 Status = -EINVAL;
4369 else
4370 {
4371 int enabled = 0;
4372 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4373 if (enabled == 1)
4374 pAdapter->StaCfg.bBlockAssoc = TRUE;
4375 else
4376 // WPA MIC error should block association attempt for 60 seconds
4377 pAdapter->StaCfg.bBlockAssoc = FALSE;
4378 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAdapter->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
4379 }
4380 break;
4381 case RT_OID_WPA_SUPPLICANT_SUPPORT:
4382 if (wrq->u.data.length != sizeof(UCHAR))
4383 Status = -EINVAL;
4384 else
4385 {
4386 Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
4387 pAdapter->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
4388 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
4389 }
4390 break;
4391 case OID_802_11_DEAUTHENTICATION:
4392 if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
4393 Status = -EINVAL;
4394 else
4395 {
4396 MLME_DEAUTH_REQ_STRUCT *pInfo;
4397 MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
4398
4399 pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
4400 Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
4401 MlmeDeauthReqAction(pAdapter, MsgElem);
4402 kfree(MsgElem);
4403
4404 if (INFRA_ON(pAdapter))
4405 {
4406 LinkDown(pAdapter, FALSE);
4407 pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
4408 }
4409 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
4410 }
4411 break;
4412 case OID_802_11_DROP_UNENCRYPTED:
4413 if (wrq->u.data.length != sizeof(int))
4414 Status = -EINVAL;
4415 else
4416 {
4417 int enabled = 0;
4418 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4419 if (enabled == 1)
4420 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
4421 else
4422 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
4423 NdisAcquireSpinLock(&pAdapter->MacTabLock);
4424 pAdapter->MacTab.Content[BSSID_WCID].PortSecured = pAdapter->StaCfg.PortSecured;
4425 NdisReleaseSpinLock(&pAdapter->MacTabLock);
4426 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
4427 }
4428 break;
4429 case OID_802_11_SET_IEEE8021X:
4430 if (wrq->u.data.length != sizeof(BOOLEAN))
4431 Status = -EINVAL;
4432 else
4433 {
4434 Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
4435 pAdapter->StaCfg.IEEE8021X = IEEE8021xState;
4436 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
4437 }
4438 break;
4439 case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
4440 if (wrq->u.data.length != sizeof(BOOLEAN))
4441 Status = -EINVAL;
4442 else
4443 {
4444 Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
4445 pAdapter->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
4446 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
4447 }
4448 break;
4449 case OID_802_11_PMKID:
4450 pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4451
4452 if(pPmkId == NULL) {
4453 Status = -ENOMEM;
4454 break;
4455 }
4456 Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
4457
4458 // check the PMKID information
4459 if (pPmkId->BSSIDInfoCount == 0)
4460 NdisZeroMemory(pAdapter->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
4461 else
4462 {
4463 PBSSID_INFO pBssIdInfo;
4464 UINT BssIdx;
4465 UINT CachedIdx;
4466
4467 for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
4468 {
4469 // point to the indexed BSSID_INFO structure
4470 pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
4471 // Find the entry in the saved data base.
4472 for (CachedIdx = 0; CachedIdx < pAdapter->StaCfg.SavedPMKNum; CachedIdx++)
4473 {
4474 // compare the BSSID
4475 if (NdisEqualMemory(pBssIdInfo->BSSID, pAdapter->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
4476 break;
4477 }
4478
4479 // Found, replace it
4480 if (CachedIdx < PMKID_NO)
4481 {
4482 DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4483 NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4484 pAdapter->StaCfg.SavedPMKNum++;
4485 }
4486 // Not found, replace the last one
4487 else
4488 {
4489 // Randomly replace one
4490 CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
4491 DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4492 NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4493 }
4494 }
4495 }
4496 if(pPmkId)
4497 kfree(pPmkId);
4498 break;
4499#endif // WPA_SUPPLICANT_SUPPORT //
4500
4501
4502
4503#ifdef SNMP_SUPPORT
4504 case OID_802_11_SHORTRETRYLIMIT:
4505 if (wrq->u.data.length != sizeof(ULONG))
4506 Status = -EINVAL;
4507 else
4508 {
4509 Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4510 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4511 tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
4512 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4513 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit));
4514 }
4515 break;
4516
4517 case OID_802_11_LONGRETRYLIMIT:
4518 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n"));
4519 if (wrq->u.data.length != sizeof(ULONG))
4520 Status = -EINVAL;
4521 else
4522 {
4523 Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4524 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4525 tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
4526 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4527 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit));
4528 }
4529 break;
4530
4531 case OID_802_11_WEPDEFAULTKEYVALUE:
4532 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n"));
4533 pKey = kmalloc(wrq->u.data.length, GFP_KERNEL);
4534 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
4535 //pKey = &WepKey;
4536
4537 if ( pKey->Length != wrq->u.data.length)
4538 {
4539 Status = -EINVAL;
4540 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n"));
4541 }
4542 KeyIdx = pKey->KeyIndex & 0x0fffffff;
4543 DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength));
4544
4545 // it is a shared key
4546 if (KeyIdx > 4)
4547 Status = -EINVAL;
4548 else
4549 {
4550 pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
4551 NdisMoveMemory(&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
4552 if (pKey->KeyIndex & 0x80000000)
4553 {
4554 // Default key for tx (shared key)
4555 pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4556 }
4557 //RestartAPIsRequired = TRUE;
4558 }
4559 break;
4560
4561
4562 case OID_802_11_WEPDEFAULTKEYID:
4563 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n"));
4564
4565 if (wrq->u.data.length != sizeof(UCHAR))
4566 Status = -EINVAL;
4567 else
4568 Status = copy_from_user(&pAdapter->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length);
4569
4570 break;
4571
4572
4573 case OID_802_11_CURRENTCHANNEL:
4574 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n"));
4575 if (wrq->u.data.length != sizeof(UCHAR))
4576 Status = -EINVAL;
4577 else
4578 {
4579 Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length);
4580 sprintf(&ctmp,"%d", ctmp);
4581 Set_Channel_Proc(pAdapter, &ctmp);
4582 }
4583 break;
4584#endif
4585
4586
4587
4588 default:
4589 DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
4590 Status = -EOPNOTSUPP;
4591 break;
4592 }
4593
4594
4595 return Status;
4596}
4597
4598INT RTMPQueryInformation(
4599 IN PRTMP_ADAPTER pAdapter,
4600 IN OUT struct ifreq *rq,
4601 IN INT cmd)
4602{
4603 struct iwreq *wrq = (struct iwreq *) rq;
4604 NDIS_802_11_BSSID_LIST_EX *pBssidList = NULL;
4605 PNDIS_WLAN_BSSID_EX pBss;
4606 NDIS_802_11_SSID Ssid;
4607 NDIS_802_11_CONFIGURATION *pConfiguration = NULL;
4608 RT_802_11_LINK_STATUS *pLinkStatus = NULL;
4609 RT_802_11_STA_CONFIG *pStaConfig = NULL;
4610 NDIS_802_11_STATISTICS *pStatistics = NULL;
4611 NDIS_802_11_RTS_THRESHOLD RtsThresh;
4612 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
4613 NDIS_802_11_POWER_MODE PowerMode;
4614 NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
4615 RT_802_11_PREAMBLE PreamType;
4616 NDIS_802_11_AUTHENTICATION_MODE AuthMode;
4617 NDIS_802_11_WEP_STATUS WepStatus;
4618 NDIS_MEDIA_STATE MediaState;
4619 ULONG BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
4620 USHORT BssLen = 0;
4621 PUCHAR pBuf = NULL, pPtr;
4622 INT Status = NDIS_STATUS_SUCCESS;
4623 UINT we_version_compiled;
4624 UCHAR i, Padding = 0;
4625 BOOLEAN RadioState;
4626 UCHAR driverVersion[8];
4627 OID_SET_HT_PHYMODE *pHTPhyMode = NULL;
4628
4629
4630#ifdef SNMP_SUPPORT
4631 //for snmp, kathy
4632 DefaultKeyIdxValue *pKeyIdxValue;
4633 INT valueLen;
4634 TX_RTY_CFG_STRUC tx_rty_cfg;
4635 ULONG ShortRetryLimit, LongRetryLimit;
4636 UCHAR tmp[64];
4637#endif //SNMP
4638
4639 switch(cmd)
4640 {
4641 case RT_OID_DEVICE_NAME:
4642 wrq->u.data.length = sizeof(STA_NIC_DEVICE_NAME);
4643 Status = copy_to_user(wrq->u.data.pointer, STA_NIC_DEVICE_NAME, wrq->u.data.length);
4644 break;
4645 case RT_OID_VERSION_INFO:
4646 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
4647 wrq->u.data.length = 8*sizeof(UCHAR);
4648 sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
4649 driverVersion[7] = '\0';
4650 if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
4651 {
4652 Status = -EFAULT;
4653 }
4654 break;
4655#ifdef RALINK_ATE
4656 case RT_QUERY_ATE_TXDONE_COUNT:
4657 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_QUERY_ATE_TXDONE_COUNT \n"));
4658 wrq->u.data.length = sizeof(UINT32);
4659 if (copy_to_user(wrq->u.data.pointer, &pAdapter->ate.TxDoneCount, wrq->u.data.length))
4660 {
4661 Status = -EFAULT;
4662 }
4663 break;
4664#endif // RALINK_ATE //
4665 case OID_802_11_BSSID_LIST:
4666 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
4667 {
4668 /*
4669 * Still scanning, indicate the caller should try again.
4670 */
4671 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
4672 return -EAGAIN;
4673 }
4674 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAdapter->ScanTab.BssNr));
4675 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
4676 // Claculate total buffer size required
4677 BssBufSize = sizeof(ULONG);
4678
4679 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4680 {
4681 // Align pointer to 4 bytes boundary.
4682 //Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
4683 //if (Padding == 4)
4684 // Padding = 0;
4685 BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4686 }
4687
4688 // For safety issue, we add 256 bytes just in case
4689 BssBufSize += 256;
4690 // Allocate the same size as passed from higher layer
4691 pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
4692 if(pBuf == NULL)
4693 {
4694 Status = -ENOMEM;
4695 break;
4696 }
4697 // Init 802_11_BSSID_LIST_EX structure
4698 NdisZeroMemory(pBuf, BssBufSize);
4699 pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
4700 pBssidList->NumberOfItems = pAdapter->ScanTab.BssNr;
4701
4702 // Calculate total buffer length
4703 BssLen = 4; // Consist of NumberOfItems
4704 // Point to start of NDIS_WLAN_BSSID_EX
4705 // pPtr = pBuf + sizeof(ULONG);
4706 pPtr = (PUCHAR) &pBssidList->Bssid[0];
4707 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4708 {
4709 pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
4710 NdisMoveMemory(&pBss->MacAddress, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
4711 if ((pAdapter->ScanTab.BssEntry[i].Hidden == 1) && (pAdapter->StaCfg.bShowHiddenSSID == FALSE))
4712 {
4713 //
4714 // We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
4715 // and then failed to send EAPOl farame.
4716 //
4717 if ((pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAdapter->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
4718 {
4719 pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4720 NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4721 }
4722 else
4723 pBss->Ssid.SsidLength = 0;
4724 }
4725 else
4726 {
4727 pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4728 NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4729 }
4730 pBss->Privacy = pAdapter->ScanTab.BssEntry[i].Privacy;
4731 pBss->Rssi = pAdapter->ScanTab.BssEntry[i].Rssi - pAdapter->BbpRssiToDbmDelta;
4732 pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
4733 pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
4734 pBss->Configuration.BeaconPeriod = pAdapter->ScanTab.BssEntry[i].BeaconPeriod;
4735 pBss->Configuration.ATIMWindow = pAdapter->ScanTab.BssEntry[i].AtimWin;
4736
4737 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
4738
4739 if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_INFRA)
4740 pBss->InfrastructureMode = Ndis802_11Infrastructure;
4741 else
4742 pBss->InfrastructureMode = Ndis802_11IBSS;
4743
4744 NdisMoveMemory(pBss->SupportedRates, pAdapter->ScanTab.BssEntry[i].SupRate, pAdapter->ScanTab.BssEntry[i].SupRateLen);
4745 NdisMoveMemory(pBss->SupportedRates + pAdapter->ScanTab.BssEntry[i].SupRateLen,
4746 pAdapter->ScanTab.BssEntry[i].ExtRate,
4747 pAdapter->ScanTab.BssEntry[i].ExtRateLen);
4748
4749 if (pAdapter->ScanTab.BssEntry[i].VarIELen == 0)
4750 {
4751 pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
4752 NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4753 pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4754 }
4755 else
4756 {
4757 pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen);
4758 pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4759 NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4760 NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAdapter->ScanTab.BssEntry[i].VarIEs, pAdapter->ScanTab.BssEntry[i].VarIELen);
4761 pPtr += pAdapter->ScanTab.BssEntry[i].VarIELen;
4762 }
4763 pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4764
4765#if WIRELESS_EXT < 17
4766 if ((BssLen + pBss->Length) < wrq->u.data.length)
4767 BssLen += pBss->Length;
4768 else
4769 {
4770 pBssidList->NumberOfItems = i;
4771 break;
4772 }
4773#else
4774 BssLen += pBss->Length;
4775#endif
4776 }
4777
4778#if WIRELESS_EXT < 17
4779 wrq->u.data.length = BssLen;
4780#else
4781 if (BssLen > wrq->u.data.length)
4782 {
4783 kfree(pBssidList);
4784 return -E2BIG;
4785 }
4786 else
4787 wrq->u.data.length = BssLen;
4788#endif
4789 Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
4790 kfree(pBssidList);
4791 break;
4792 case OID_802_3_CURRENT_ADDRESS:
4793 wrq->u.data.length = MAC_ADDR_LEN;
4794 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
4795 break;
4796 case OID_GEN_MEDIA_CONNECT_STATUS:
4797 if (pAdapter->IndicateMediaState == NdisMediaStateConnected)
4798 MediaState = NdisMediaStateConnected;
4799 else
4800 MediaState = NdisMediaStateDisconnected;
4801
4802 wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
4803 Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
4804 break;
4805 case OID_802_11_BSSID:
4806#ifdef RALINK_ATE
4807 if (ATE_ON(pAdapter))
4808 {
4809 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4810 Status = NDIS_STATUS_RESOURCES;
4811 break;
4812 }
4813#endif // RALINK_ATE //
4814 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
4815 {
4816 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
4817
4818 }
4819 else
4820 {
4821 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
4822 Status = -ENOTCONN;
4823 }
4824 break;
4825 case OID_802_11_SSID:
4826 NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
4827 NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
4828 Ssid.SsidLength = pAdapter->CommonCfg.SsidLen;
4829 memcpy(Ssid.Ssid, pAdapter->CommonCfg.Ssid, Ssid.SsidLength);
4830 wrq->u.data.length = sizeof(NDIS_802_11_SSID);
4831 Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
4832 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
4833 break;
4834 case RT_OID_802_11_QUERY_LINK_STATUS:
4835 pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
4836 if (pLinkStatus)
4837 {
4838 pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAdapter->CommonCfg.TxRate]; // unit : 500 kbps
4839 pLinkStatus->ChannelQuality = pAdapter->Mlme.ChannelQuality;
4840 pLinkStatus->RxByteCount = pAdapter->RalinkCounters.ReceivedByteCount;
4841 pLinkStatus->TxByteCount = pAdapter->RalinkCounters.TransmittedByteCount;
4842 pLinkStatus->CentralChannel = pAdapter->CommonCfg.CentralChannel;
4843 wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
4844 Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
4845 kfree(pLinkStatus);
4846 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
4847 }
4848 else
4849 {
4850 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
4851 Status = -EFAULT;
4852 }
4853 break;
4854 case OID_802_11_CONFIGURATION:
4855 pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
4856 if (pConfiguration)
4857 {
4858 pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
4859 pConfiguration->BeaconPeriod = pAdapter->CommonCfg.BeaconPeriod;
4860 pConfiguration->ATIMWindow = pAdapter->StaActive.AtimWin;
4861 MAP_CHANNEL_ID_TO_KHZ(pAdapter->CommonCfg.Channel, pConfiguration->DSConfig);
4862 wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
4863 Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
4864 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
4865 pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAdapter->CommonCfg.Channel));
4866 kfree(pConfiguration);
4867 }
4868 else
4869 {
4870 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
4871 Status = -EFAULT;
4872 }
4873 break;
4874 case RT_OID_802_11_SNR_0:
4875 if ((pAdapter->StaCfg.LastSNR0 > 0))
4876 {
4877 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR0) * 3) / 16 ;
4878 wrq->u.data.length = sizeof(ulInfo);
4879 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4880 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
4881 }
4882 else
4883 Status = -EFAULT;
4884 break;
4885 case RT_OID_802_11_SNR_1:
4886 if ((pAdapter->Antenna.field.RxPath > 1) &&
4887 (pAdapter->StaCfg.LastSNR1 > 0))
4888 {
4889 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR1) * 3) / 16 ;
4890 wrq->u.data.length = sizeof(ulInfo);
4891 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4892 DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
4893 }
4894 else
4895 Status = -EFAULT;
4896 DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAdapter->StaCfg.LastSNR1=%d)\n",pAdapter->StaCfg.LastSNR1));
4897 break;
4898 case OID_802_11_RSSI_TRIGGER:
4899 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0 - pAdapter->BbpRssiToDbmDelta;
4900 wrq->u.data.length = sizeof(ulInfo);
4901 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4902 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
4903 break;
4904 case OID_802_11_RSSI:
4905 case RT_OID_802_11_RSSI:
4906 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0;
4907 wrq->u.data.length = sizeof(ulInfo);
4908 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4909 break;
4910 case RT_OID_802_11_RSSI_1:
4911 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi1;
4912 wrq->u.data.length = sizeof(ulInfo);
4913 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4914 break;
4915 case RT_OID_802_11_RSSI_2:
4916 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi2;
4917 wrq->u.data.length = sizeof(ulInfo);
4918 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4919 break;
4920 case OID_802_11_STATISTICS:
4921 pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
4922 if (pStatistics)
4923 {
4924 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
4925 // add the most up-to-date h/w raw counters into software counters
4926 NICUpdateRawCounters(pAdapter);
4927
4928 // Sanity check for calculation of sucessful count
4929 if (pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart < pAdapter->WlanCounters.RetryCount.QuadPart)
4930 pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4931
4932 pStatistics->TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart;
4933 pStatistics->MulticastTransmittedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
4934 pStatistics->FailedCount.QuadPart = pAdapter->WlanCounters.FailedCount.QuadPart;
4935 pStatistics->RetryCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4936 pStatistics->MultipleRetryCount.QuadPart = pAdapter->WlanCounters.MultipleRetryCount.QuadPart;
4937 pStatistics->RTSSuccessCount.QuadPart = pAdapter->WlanCounters.RTSSuccessCount.QuadPart;
4938 pStatistics->RTSFailureCount.QuadPart = pAdapter->WlanCounters.RTSFailureCount.QuadPart;
4939 pStatistics->ACKFailureCount.QuadPart = pAdapter->WlanCounters.ACKFailureCount.QuadPart;
4940 pStatistics->FrameDuplicateCount.QuadPart = pAdapter->WlanCounters.FrameDuplicateCount.QuadPart;
4941 pStatistics->ReceivedFragmentCount.QuadPart = pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart;
4942 pStatistics->MulticastReceivedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastReceivedFrameCount.QuadPart;
4943#ifdef DBG
4944 pStatistics->FCSErrorCount = pAdapter->RalinkCounters.RealFcsErrCount;
4945#else
4946 pStatistics->FCSErrorCount.QuadPart = pAdapter->WlanCounters.FCSErrorCount.QuadPart;
4947 pStatistics->FrameDuplicateCount.u.LowPart = pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
4948#endif
4949 wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
4950 Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
4951 kfree(pStatistics);
4952 }
4953 else
4954 {
4955 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
4956 Status = -EFAULT;
4957 }
4958 break;
4959 case OID_GEN_RCV_OK:
4960 ulInfo = pAdapter->Counters8023.GoodReceives;
4961 wrq->u.data.length = sizeof(ulInfo);
4962 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4963 break;
4964 case OID_GEN_RCV_NO_BUFFER:
4965 ulInfo = pAdapter->Counters8023.RxNoBuffer;
4966 wrq->u.data.length = sizeof(ulInfo);
4967 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4968 break;
4969 case RT_OID_802_11_PHY_MODE:
4970 ulInfo = (ULONG)pAdapter->CommonCfg.PhyMode;
4971 wrq->u.data.length = sizeof(ulInfo);
4972 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4973 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo));
4974 break;
4975 case RT_OID_802_11_STA_CONFIG:
4976 pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
4977 if (pStaConfig)
4978 {
4979 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
4980 pStaConfig->EnableTxBurst = pAdapter->CommonCfg.bEnableTxBurst;
4981 pStaConfig->EnableTurboRate = 0;
4982 pStaConfig->UseBGProtection = pAdapter->CommonCfg.UseBGProtection;
4983 pStaConfig->UseShortSlotTime = pAdapter->CommonCfg.bUseShortSlotTime;
4984 //pStaConfig->AdhocMode = pAdapter->StaCfg.AdhocMode;
4985 pStaConfig->HwRadioStatus = (pAdapter->StaCfg.bHwRadio == TRUE) ? 1 : 0;
4986 pStaConfig->Rsv1 = 0;
4987 pStaConfig->SystemErrorBitmap = pAdapter->SystemErrorBitmap;
4988 wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
4989 Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
4990 kfree(pStaConfig);
4991 }
4992 else
4993 {
4994 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
4995 Status = -EFAULT;
4996 }
4997 break;
4998 case OID_802_11_RTS_THRESHOLD:
4999 RtsThresh = pAdapter->CommonCfg.RtsThreshold;
5000 wrq->u.data.length = sizeof(RtsThresh);
5001 Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
5002 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
5003 break;
5004 case OID_802_11_FRAGMENTATION_THRESHOLD:
5005 FragThresh = pAdapter->CommonCfg.FragmentThreshold;
5006 if (pAdapter->CommonCfg.bUseZeroToDisableFragment == TRUE)
5007 FragThresh = 0;
5008 wrq->u.data.length = sizeof(FragThresh);
5009 Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
5010 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
5011 break;
5012 case OID_802_11_POWER_MODE:
5013 PowerMode = pAdapter->StaCfg.WindowsPowerMode;
5014 wrq->u.data.length = sizeof(PowerMode);
5015 Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
5016 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
5017 break;
5018 case RT_OID_802_11_RADIO:
5019 RadioState = (BOOLEAN) pAdapter->StaCfg.bSwRadio;
5020 wrq->u.data.length = sizeof(RadioState);
5021 Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
5022 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
5023 break;
5024 case OID_802_11_INFRASTRUCTURE_MODE:
5025 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
5026 BssType = Ndis802_11IBSS;
5027 else if (pAdapter->StaCfg.BssType == BSS_INFRA)
5028 BssType = Ndis802_11Infrastructure;
5029 else if (pAdapter->StaCfg.BssType == BSS_MONITOR)
5030 BssType = Ndis802_11Monitor;
5031 else
5032 BssType = Ndis802_11AutoUnknown;
5033
5034 wrq->u.data.length = sizeof(BssType);
5035 Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
5036 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
5037 break;
5038 case RT_OID_802_11_PREAMBLE:
5039 PreamType = pAdapter->CommonCfg.TxPreamble;
5040 wrq->u.data.length = sizeof(PreamType);
5041 Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
5042 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
5043 break;
5044 case OID_802_11_AUTHENTICATION_MODE:
5045 AuthMode = pAdapter->StaCfg.AuthMode;
5046 wrq->u.data.length = sizeof(AuthMode);
5047 Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
5048 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
5049 break;
5050 case OID_802_11_WEP_STATUS:
5051 WepStatus = pAdapter->StaCfg.WepStatus;
5052 wrq->u.data.length = sizeof(WepStatus);
5053 Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
5054 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
5055 break;
5056 case OID_802_11_TX_POWER_LEVEL:
5057 wrq->u.data.length = sizeof(ULONG);
5058 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPower, wrq->u.data.length);
5059 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAdapter->CommonCfg.TxPower));
5060 break;
5061 case RT_OID_802_11_TX_POWER_LEVEL_1:
5062 wrq->u.data.length = sizeof(ULONG);
5063 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPowerPercentage, wrq->u.data.length);
5064 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
5065 break;
5066 case OID_802_11_NETWORK_TYPES_SUPPORTED:
5067 if ((pAdapter->RfIcType == RFIC_2850) || (pAdapter->RfIcType == RFIC_2750))
5068 {
5069 NetworkTypeList[0] = 3; // NumberOfItems = 3
5070 NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
5071 NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
5072 NetworkTypeList[3] = Ndis802_11OFDM5; // NetworkType[3] = 11a
5073 wrq->u.data.length = 16;
5074 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
5075 }
5076 else
5077 {
5078 NetworkTypeList[0] = 2; // NumberOfItems = 2
5079 NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
5080 NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
5081 wrq->u.data.length = 12;
5082 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
5083 }
5084 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
5085 break;
5086 case OID_802_11_NETWORK_TYPE_IN_USE:
5087 wrq->u.data.length = sizeof(ULONG);
5088 if (pAdapter->CommonCfg.PhyMode == PHY_11A)
5089 ulInfo = Ndis802_11OFDM5;
5090 else if ((pAdapter->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAdapter->CommonCfg.PhyMode == PHY_11G))
5091 ulInfo = Ndis802_11OFDM24;
5092 else
5093 ulInfo = Ndis802_11DS;
5094 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5095 break;
5096 case RT_OID_802_11_QUERY_LAST_RX_RATE:
5097 ulInfo = (ULONG)pAdapter->LastRxRate;
5098 wrq->u.data.length = sizeof(ulInfo);
5099 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5100 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
5101 break;
5102 case RT_OID_802_11_QUERY_LAST_TX_RATE:
5103 //ulInfo = (ULONG)pAdapter->LastTxRate;
5104 ulInfo = (ULONG)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word;
5105 wrq->u.data.length = sizeof(ulInfo);
5106 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5107 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
5108 break;
5109 case RT_OID_802_11_QUERY_EEPROM_VERSION:
5110 wrq->u.data.length = sizeof(ULONG);
5111 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->EepromVersion, wrq->u.data.length);
5112 break;
5113 case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
5114 wrq->u.data.length = sizeof(ULONG);
5115 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->FirmwareVersion, wrq->u.data.length);
5116 break;
5117 case RT_OID_802_11_QUERY_NOISE_LEVEL:
5118 wrq->u.data.length = sizeof(UCHAR);
5119 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->BbpWriteLatch[66], wrq->u.data.length);
5120 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAdapter->BbpWriteLatch[66]));
5121 break;
5122 case RT_OID_802_11_EXTRA_INFO:
5123 wrq->u.data.length = sizeof(ULONG);
5124 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->ExtraInfo, wrq->u.data.length);
5125 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAdapter->ExtraInfo));
5126 break;
5127 case RT_OID_WE_VERSION_COMPILED:
5128 wrq->u.data.length = sizeof(UINT);
5129 we_version_compiled = WIRELESS_EXT;
5130 Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
5131 break;
5132 case RT_OID_802_11_QUERY_APSD_SETTING:
5133 apsd = (pAdapter->CommonCfg.bAPSDCapable | (pAdapter->CommonCfg.bAPSDAC_BE << 1) | (pAdapter->CommonCfg.bAPSDAC_BK << 2)
5134 | (pAdapter->CommonCfg.bAPSDAC_VI << 3) | (pAdapter->CommonCfg.bAPSDAC_VO << 4) | (pAdapter->CommonCfg.MaxSPLength << 5));
5135
5136 wrq->u.data.length = sizeof(ULONG);
5137 Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
5138 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",
5139 apsd,pAdapter->CommonCfg.bAPSDCapable,pAdapter->CommonCfg.bAPSDAC_BE,pAdapter->CommonCfg.bAPSDAC_BK,pAdapter->CommonCfg.bAPSDAC_VI,pAdapter->CommonCfg.bAPSDAC_VO,pAdapter->CommonCfg.MaxSPLength));
5140 break;
5141 case RT_OID_802_11_QUERY_APSD_PSM:
5142 wrq->u.data.length = sizeof(ULONG);
5143 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
5144 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
5145 break;
5146 case RT_OID_802_11_QUERY_WMM:
5147 wrq->u.data.length = sizeof(BOOLEAN);
5148 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bWmmCapable, wrq->u.data.length);
5149 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n", pAdapter->CommonCfg.bWmmCapable));
5150 break;
5151#ifdef WPA_SUPPLICANT_SUPPORT
5152 case RT_OID_NEW_DRIVER:
5153 {
5154 UCHAR enabled = 1;
5155 wrq->u.data.length = sizeof(UCHAR);
5156 Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
5157 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
5158 }
5159 break;
5160 case RT_OID_WPA_SUPPLICANT_SUPPORT:
5161 wrq->u.data.length = sizeof(UCHAR);
5162 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.WpaSupplicantUP, wrq->u.data.length);
5163 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
5164 break;
5165#endif // WPA_SUPPLICANT_SUPPORT //
5166
5167 case RT_OID_DRIVER_DEVICE_NAME:
5168 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
5169 wrq->u.data.length = 16;
5170 if (copy_to_user(wrq->u.data.pointer, pAdapter->StaCfg.dev_name, wrq->u.data.length))
5171 {
5172 Status = -EFAULT;
5173 }
5174 break;
5175 case RT_OID_802_11_QUERY_HT_PHYMODE:
5176 pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5177 if (pHTPhyMode)
5178 {
5179 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5180 pHTPhyMode->HtMode = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
5181 pHTPhyMode->BW = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
5182 pHTPhyMode->MCS= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
5183 pHTPhyMode->SHORTGI= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
5184 pHTPhyMode->STBC= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
5185
5186 pHTPhyMode->ExtOffset = ((pAdapter->CommonCfg.CentralChannel < pAdapter->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
5187 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5188 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5189 {
5190 Status = -EFAULT;
5191 }
5192 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5193 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5194 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5195 }
5196 else
5197 {
5198 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5199 Status = -EFAULT;
5200 }
5201 break;
5202 case RT_OID_802_11_COUNTRY_REGION:
5203 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
5204 wrq->u.data.length = sizeof(ulInfo);
5205 ulInfo = pAdapter->CommonCfg.CountryRegionForABand;
5206 ulInfo = (ulInfo << 8)|(pAdapter->CommonCfg.CountryRegion);
5207 if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
5208 {
5209 Status = -EFAULT;
5210 }
5211 break;
5212 case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
5213 pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5214 if (pHTPhyMode)
5215 {
5216 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5217 pHTPhyMode->HtMode = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.HTMODE;
5218 pHTPhyMode->BW = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.BW;
5219 pHTPhyMode->MCS= (UCHAR)pAdapter->StaCfg.DesiredTransmitSetting.field.MCS;
5220 pHTPhyMode->SHORTGI= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.ShortGI;
5221 pHTPhyMode->STBC= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.STBC;
5222
5223 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5224 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5225 {
5226 Status = -EFAULT;
5227 }
5228 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5229 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5230 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5231 }
5232 else
5233 {
5234 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5235 Status = -EFAULT;
5236 }
5237 break;
5238 case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
5239 wrq->u.data.length = sizeof(UCHAR);
5240 i = 0;
5241#ifdef MULTIPLE_CARD_SUPPORT
5242 i = 1;
5243#endif // MULTIPLE_CARD_SUPPORT //
5244 if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
5245 {
5246 Status = -EFAULT;
5247 }
5248 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
5249 break;
5250#ifdef SNMP_SUPPORT
5251 case RT_OID_802_11_MAC_ADDRESS:
5252 wrq->u.data.length = MAC_ADDR_LEN;
5253 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5254 break;
5255
5256 case RT_OID_802_11_MANUFACTUREROUI:
5257 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n"));
5258 wrq->u.data.length = ManufacturerOUI_LEN;
5259 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5260 break;
5261
5262 case RT_OID_802_11_MANUFACTURERNAME:
5263 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n"));
5264 wrq->u.data.length = strlen(ManufacturerNAME);
5265 Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5266 break;
5267
5268 case RT_OID_802_11_RESOURCETYPEIDNAME:
5269 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n"));
5270 wrq->u.data.length = strlen(ResourceTypeIdName);
5271 Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length);
5272 break;
5273
5274 case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED:
5275 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n"));
5276 ulInfo = 1; // 1 is support wep else 2 is not support.
5277 wrq->u.data.length = sizeof(ulInfo);
5278 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5279 break;
5280
5281 case RT_OID_802_11_POWERMANAGEMENTMODE:
5282 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
5283 if (pAdapter->StaCfg.Psm == PSMP_ACTION)
5284 ulInfo = 1; // 1 is power active else 2 is power save.
5285 else
5286 ulInfo = 2;
5287
5288 wrq->u.data.length = sizeof(ulInfo);
5289 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5290 break;
5291
5292 case OID_802_11_WEPDEFAULTKEYVALUE:
5293 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n"));
5294 //KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId;
5295 pKeyIdxValue = wrq->u.data.pointer;
5296 DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
5297 valueLen = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
5298 NdisMoveMemory(pKeyIdxValue->Value,
5299 &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key,
5300 valueLen);
5301 pKeyIdxValue->Value[valueLen]='\0';
5302
5303 wrq->u.data.length = sizeof(DefaultKeyIdxValue);
5304
5305 Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length);
5306 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,
5307 pAdapter->SharedKey[BSS0][0].Key[0],
5308 pAdapter->SharedKey[BSS0][1].Key[0],
5309 pAdapter->SharedKey[BSS0][2].Key[0],
5310 pAdapter->SharedKey[BSS0][3].Key[0]));
5311 break;
5312
5313 case OID_802_11_WEPDEFAULTKEYID:
5314 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n"));
5315 wrq->u.data.length = sizeof(UCHAR);
5316 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length);
5317 DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAdapter->StaCfg.DefaultKeyId));
5318 break;
5319
5320 case RT_OID_802_11_WEPKEYMAPPINGLENGTH:
5321 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n"));
5322 wrq->u.data.length = sizeof(UCHAR);
5323 Status = copy_to_user(wrq->u.data.pointer,
5324 &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
5325 wrq->u.data.length);
5326 break;
5327
5328 case OID_802_11_SHORTRETRYLIMIT:
5329 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n"));
5330 wrq->u.data.length = sizeof(ULONG);
5331 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5332 ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit;
5333 DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld, tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit));
5334 Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length);
5335 break;
5336
5337 case OID_802_11_LONGRETRYLIMIT:
5338 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n"));
5339 wrq->u.data.length = sizeof(ULONG);
5340 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5341 LongRetryLimit = tx_rty_cfg.field.LongRtyLimit;
5342 DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld, tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit));
5343 Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length);
5344 break;
5345
5346 case RT_OID_802_11_PRODUCTID:
5347 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
5348
5349#ifdef RT2870
5350 sprintf(tmp, "%04x %04x\n", ((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idVendor ,((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idProduct);
5351
5352#endif // RT2870 //
5353 wrq->u.data.length = strlen(tmp);
5354 Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
5355 break;
5356
5357 case RT_OID_802_11_MANUFACTUREID:
5358 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n"));
5359 wrq->u.data.length = strlen(ManufacturerNAME);
5360 Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5361 break;
5362
5363 case OID_802_11_CURRENTCHANNEL:
5364 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n"));
5365 wrq->u.data.length = sizeof(UCHAR);
5366 DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAdapter->CommonCfg.Channel));
5367 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Channel, wrq->u.data.length);
5368 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5369 break;
5370#endif //SNMP_SUPPORT
5371
5372 case OID_802_11_BUILD_CHANNEL_EX:
5373 {
5374 UCHAR value;
5375 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
5376 wrq->u.data.length = sizeof(UCHAR);
5377#ifdef EXT_BUILD_CHANNEL_LIST
5378 DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n"));
5379 value = 1;
5380#else
5381 DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
5382 value = 0;
5383#endif // EXT_BUILD_CHANNEL_LIST //
5384 Status = copy_to_user(wrq->u.data.pointer, &value, 1);
5385 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5386 }
5387 break;
5388
5389 case OID_802_11_GET_CH_LIST:
5390 {
5391 PRT_CHANNEL_LIST_INFO pChListBuf;
5392
5393 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
5394 if (pAdapter->ChannelListNum == 0)
5395 {
5396 wrq->u.data.length = 0;
5397 break;
5398 }
5399
5400 pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
5401 if (pChListBuf == NULL)
5402 {
5403 wrq->u.data.length = 0;
5404 break;
5405 }
5406
5407 pChListBuf->ChannelListNum = pAdapter->ChannelListNum;
5408 for (i = 0; i < pChListBuf->ChannelListNum; i++)
5409 pChListBuf->ChannelList[i] = pAdapter->ChannelList[i].Channel;
5410
5411 wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
5412 Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
5413 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5414
5415 if (pChListBuf)
5416 kfree(pChListBuf);
5417 }
5418 break;
5419
5420 case OID_802_11_GET_COUNTRY_CODE:
5421 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
5422 wrq->u.data.length = 2;
5423 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.CountryCode, 2);
5424 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5425 break;
5426
5427 case OID_802_11_GET_CHANNEL_GEOGRAPHY:
5428 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
5429 wrq->u.data.length = 1;
5430 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Geography, 1);
5431 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5432 break;
5433
5434
5435#ifdef QOS_DLS_SUPPORT
5436 case RT_OID_802_11_QUERY_DLS:
5437 wrq->u.data.length = sizeof(BOOLEAN);
5438 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bDLSCapable, wrq->u.data.length);
5439 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAdapter->CommonCfg.bDLSCapable));
5440 break;
5441
5442 case RT_OID_802_11_QUERY_DLS_PARAM:
5443 {
5444 PRT_802_11_DLS_INFO pDlsInfo = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC);
5445 if (pDlsInfo == NULL)
5446 break;
5447
5448 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
5449 {
5450 RTMPMoveMemory(&pDlsInfo->Entry[i], &pAdapter->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI));
5451 }
5452
5453 pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY;
5454 wrq->u.data.length = sizeof(RT_802_11_DLS_INFO);
5455 Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length);
5456 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n"));
5457
5458 if (pDlsInfo)
5459 kfree(pDlsInfo);
5460 }
5461 break;
5462#endif // QOS_DLS_SUPPORT //
5463 default:
5464 DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
5465 Status = -EOPNOTSUPP;
5466 break;
5467 }
5468 return Status;
5469}
5470
5471INT rt28xx_sta_ioctl(
5472 IN struct net_device *net_dev,
5473 IN OUT struct ifreq *rq,
5474 IN INT cmd)
5475{
5476 POS_COOKIE pObj;
5477 VIRTUAL_ADAPTER *pVirtualAd = NULL;
5478 RTMP_ADAPTER *pAd = NULL;
5479 struct iwreq *wrq = (struct iwreq *) rq;
5480 BOOLEAN StateMachineTouched = FALSE;
5481 INT Status = NDIS_STATUS_SUCCESS;
5482 USHORT subcmd;
5483
5484 if (net_dev->priv_flags == INT_MAIN)
5485 {
5486 pAd = net_dev->priv;
5487 }
5488 else
5489 {
5490 pVirtualAd = net_dev->priv;
5491 pAd = pVirtualAd->RtmpDev->priv;
5492 }
5493 pObj = (POS_COOKIE) pAd->OS_Cookie;
5494
5495 if (pAd == NULL)
5496 {
5497 /* if 1st open fail, pAd will be free;
5498 So the net_dev->priv will be NULL in 2rd open */
5499 return -ENETDOWN;
5500 }
5501
5502 //check if the interface is down
5503 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
5504 {
5505#ifdef CONFIG_APSTA_MIXED_SUPPORT
5506 if (wrq->u.data.pointer == NULL)
5507 {
5508 return Status;
5509 }
5510
5511 if (strstr(wrq->u.data.pointer, "OpMode") == NULL)
5512#endif // CONFIG_APSTA_MIXED_SUPPORT //
5513 {
5514 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
5515 return -ENETDOWN;
5516 }
5517 }
5518
5519 { // determine this ioctl command is comming from which interface.
5520 pObj->ioctl_if_type = INT_MAIN;
5521 pObj->ioctl_if = MAIN_MBSSID;
5522 }
5523
5524 switch(cmd)
5525 {
5526#ifdef RALINK_ATE
5527#ifdef RALINK_28xx_QA
5528 case RTPRIV_IOCTL_ATE:
5529 {
5530 RtmpDoAte(pAd, wrq);
5531 }
5532 break;
5533#endif // RALINK_28xx_QA //
5534#endif // RALINK_ATE //
5535 case SIOCGIFHWADDR:
5536 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
5537 memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
5538 break;
5539 case SIOCGIWNAME:
5540 {
5541 char *name=&wrq->u.name[0];
5542 rt_ioctl_giwname(net_dev, NULL, name, NULL);
5543 break;
5544 }
5545 case SIOCGIWESSID: //Get ESSID
5546 {
5547 struct iw_point *essid=&wrq->u.essid;
5548 rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
5549 break;
5550 }
5551 case SIOCSIWESSID: //Set ESSID
5552 {
5553 struct iw_point *essid=&wrq->u.essid;
5554 rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
5555 break;
5556 }
5557 case SIOCSIWNWID: // set network id (the cell)
5558 case SIOCGIWNWID: // get network id
5559 Status = -EOPNOTSUPP;
5560 break;
5561 case SIOCSIWFREQ: //set channel/frequency (Hz)
5562 {
5563 struct iw_freq *freq=&wrq->u.freq;
5564 rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
5565 break;
5566 }
5567 case SIOCGIWFREQ: // get channel/frequency (Hz)
5568 {
5569 struct iw_freq *freq=&wrq->u.freq;
5570 rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
5571 break;
5572 }
5573 case SIOCSIWNICKN: //set node name/nickname
5574 {
5575 struct iw_point *data=&wrq->u.data;
5576 rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
5577 break;
5578 }
5579 case SIOCGIWNICKN: //get node name/nickname
5580 {
5581 struct iw_point *data=&wrq->u.data;
5582 rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
5583 break;
5584 }
5585 case SIOCGIWRATE: //get default bit rate (bps)
5586 rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
5587 break;
5588 case SIOCSIWRATE: //set default bit rate (bps)
5589 rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
5590 break;
5591 case SIOCGIWRTS: // get RTS/CTS threshold (bytes)
5592 {
5593 struct iw_param *rts=&wrq->u.rts;
5594 rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
5595 break;
5596 }
5597 case SIOCSIWRTS: //set RTS/CTS threshold (bytes)
5598 {
5599 struct iw_param *rts=&wrq->u.rts;
5600 rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
5601 break;
5602 }
5603 case SIOCGIWFRAG: //get fragmentation thr (bytes)
5604 {
5605 struct iw_param *frag=&wrq->u.frag;
5606 rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
5607 break;
5608 }
5609 case SIOCSIWFRAG: //set fragmentation thr (bytes)
5610 {
5611 struct iw_param *frag=&wrq->u.frag;
5612 rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
5613 break;
5614 }
5615 case SIOCGIWENCODE: //get encoding token & mode
5616 {
5617 struct iw_point *erq=&wrq->u.encoding;
5618 if(erq->pointer)
5619 rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
5620 break;
5621 }
5622 case SIOCSIWENCODE: //set encoding token & mode
5623 {
5624 struct iw_point *erq=&wrq->u.encoding;
5625 if(erq->pointer)
5626 rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
5627 break;
5628 }
5629 case SIOCGIWAP: //get access point MAC addresses
5630 {
5631 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5632 rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5633 break;
5634 }
5635 case SIOCSIWAP: //set access point MAC addresses
5636 {
5637 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5638 rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5639 break;
5640 }
5641 case SIOCGIWMODE: //get operation mode
5642 {
5643 __u32 *mode=&wrq->u.mode;
5644 rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
5645 break;
5646 }
5647 case SIOCSIWMODE: //set operation mode
5648 {
5649 __u32 *mode=&wrq->u.mode;
5650 rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
5651 break;
5652 }
5653 case SIOCGIWSENS: //get sensitivity (dBm)
5654 case SIOCSIWSENS: //set sensitivity (dBm)
5655 case SIOCGIWPOWER: //get Power Management settings
5656 case SIOCSIWPOWER: //set Power Management settings
5657 case SIOCGIWTXPOW: //get transmit power (dBm)
5658 case SIOCSIWTXPOW: //set transmit power (dBm)
5659 case SIOCGIWRANGE: //Get range of parameters
5660 case SIOCGIWRETRY: //get retry limits and lifetime
5661 case SIOCSIWRETRY: //set retry limits and lifetime
5662 Status = -EOPNOTSUPP;
5663 break;
5664 case RT_PRIV_IOCTL:
5665 subcmd = wrq->u.data.flags;
5666 if( subcmd & OID_GET_SET_TOGGLE)
5667 Status = RTMPSetInformation(pAd, rq, subcmd);
5668 else
5669 Status = RTMPQueryInformation(pAd, rq, subcmd);
5670 break;
5671 case SIOCGIWPRIV:
5672 if (wrq->u.data.pointer)
5673 {
5674 if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
5675 break;
5676 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
5677 if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
5678 Status = -EFAULT;
5679 }
5680 break;
5681 case RTPRIV_IOCTL_SET:
5682 if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
5683 break;
5684 rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
5685 break;
5686 case RTPRIV_IOCTL_GSITESURVEY:
5687 RTMPIoctlGetSiteSurvey(pAd, wrq);
5688 break;
5689#ifdef DBG
5690 case RTPRIV_IOCTL_MAC:
5691 RTMPIoctlMAC(pAd, wrq);
5692 break;
5693 case RTPRIV_IOCTL_E2P:
5694 RTMPIoctlE2PROM(pAd, wrq);
5695 break;
5696#endif // DBG //
5697 case SIOCETHTOOL:
5698 break;
5699 default:
5700 DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
5701 Status = -EOPNOTSUPP;
5702 break;
5703 }
5704
5705 if(StateMachineTouched) // Upper layer sent a MLME-related operations
5706 RT28XX_MLME_HANDLER(pAd);
5707
5708 return Status;
5709}
5710
5711/*
5712 ==========================================================================
5713 Description:
5714 Set SSID
5715 Return:
5716 TRUE if all parameters are OK, FALSE otherwise
5717 ==========================================================================
5718*/
5719INT Set_SSID_Proc(
5720 IN PRTMP_ADAPTER pAdapter,
5721 IN PUCHAR arg)
5722{
5723 NDIS_802_11_SSID Ssid, *pSsid=NULL;
5724 BOOLEAN StateMachineTouched = FALSE;
5725 int success = TRUE;
5726
5727 if( strlen(arg) <= MAX_LEN_OF_SSID)
5728 {
5729 NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
5730 if (strlen(arg) != 0)
5731 {
5732 NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
5733 Ssid.SsidLength = strlen(arg);
5734 }
5735 else //ANY ssid
5736 {
5737 Ssid.SsidLength = 0;
5738 memcpy(Ssid.Ssid, "", 0);
5739 pAdapter->StaCfg.BssType = BSS_INFRA;
5740 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5741 pAdapter->StaCfg.WepStatus = Ndis802_11EncryptionDisabled;
5742 }
5743 pSsid = &Ssid;
5744
5745 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
5746 {
5747 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5748 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
5749 }
5750
5751 pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
5752 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
5753 pAdapter->bConfigChanged = TRUE;
5754
5755 MlmeEnqueue(pAdapter,
5756 MLME_CNTL_STATE_MACHINE,
5757 OID_802_11_SSID,
5758 sizeof(NDIS_802_11_SSID),
5759 (VOID *)pSsid);
5760
5761 StateMachineTouched = TRUE;
5762 DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
5763 }
5764 else
5765 success = FALSE;
5766
5767 if (StateMachineTouched) // Upper layer sent a MLME-related operations
5768 RT28XX_MLME_HANDLER(pAdapter);
5769
5770 return success;
5771}
5772
5773#ifdef WMM_SUPPORT
5774/*
5775 ==========================================================================
5776 Description:
5777 Set WmmCapable Enable or Disable
5778 Return:
5779 TRUE if all parameters are OK, FALSE otherwise
5780 ==========================================================================
5781*/
5782INT Set_WmmCapable_Proc(
5783 IN PRTMP_ADAPTER pAd,
5784 IN PUCHAR arg)
5785{
5786 BOOLEAN bWmmCapable;
5787
5788 bWmmCapable = simple_strtol(arg, 0, 10);
5789
5790 if ((bWmmCapable == 1)
5791#ifdef RT2870
5792 && (pAd->NumberOfPipes >= 5)
5793#endif // RT2870 //
5794 )
5795 pAd->CommonCfg.bWmmCapable = TRUE;
5796 else if (bWmmCapable == 0)
5797 pAd->CommonCfg.bWmmCapable = FALSE;
5798 else
5799 return FALSE; //Invalid argument
5800
5801 DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
5802 pAd->CommonCfg.bWmmCapable));
5803
5804 return TRUE;
5805}
5806#endif // WMM_SUPPORT //
5807
5808/*
5809 ==========================================================================
5810 Description:
5811 Set Network Type(Infrastructure/Adhoc mode)
5812 Return:
5813 TRUE if all parameters are OK, FALSE otherwise
5814 ==========================================================================
5815*/
5816INT Set_NetworkType_Proc(
5817 IN PRTMP_ADAPTER pAdapter,
5818 IN PUCHAR arg)
5819{
5820 UINT32 Value = 0;
5821
5822 if (strcmp(arg, "Adhoc") == 0)
5823 {
5824 if (pAdapter->StaCfg.BssType != BSS_ADHOC)
5825 {
5826 // Config has changed
5827 pAdapter->bConfigChanged = TRUE;
5828 if (MONITOR_ON(pAdapter))
5829 {
5830 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5831 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5832 Value &= (~0x80);
5833 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5834 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5835 pAdapter->StaCfg.bAutoReconnect = TRUE;
5836 LinkDown(pAdapter, FALSE);
5837 }
5838 if (INFRA_ON(pAdapter))
5839 {
5840 //BOOLEAN Cancelled;
5841 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5842 // Since calling this indicate user don't want to connect to that SSID anymore.
5843 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5844 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5845
5846 LinkDown(pAdapter, FALSE);
5847
5848 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
5849 }
5850 }
5851 pAdapter->StaCfg.BssType = BSS_ADHOC;
5852 pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5853 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
5854 }
5855 else if (strcmp(arg, "Infra") == 0)
5856 {
5857 if (pAdapter->StaCfg.BssType != BSS_INFRA)
5858 {
5859 // Config has changed
5860 pAdapter->bConfigChanged = TRUE;
5861 if (MONITOR_ON(pAdapter))
5862 {
5863 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5864 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5865 Value &= (~0x80);
5866 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5867 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5868 pAdapter->StaCfg.bAutoReconnect = TRUE;
5869 LinkDown(pAdapter, FALSE);
5870 }
5871 if (ADHOC_ON(pAdapter))
5872 {
5873 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5874 // Since calling this indicate user don't want to connect to that SSID anymore.
5875 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5876 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5877
5878 LinkDown(pAdapter, FALSE);
5879 }
5880 }
5881 pAdapter->StaCfg.BssType = BSS_INFRA;
5882 pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5883 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
5884
5885 pAdapter->StaCfg.BssType = BSS_INFRA;
5886 }
5887 else if (strcmp(arg, "Monitor") == 0)
5888 {
5889 UCHAR bbpValue = 0;
5890 BCN_TIME_CFG_STRUC csr;
5891 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
5892 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
5893 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5894 // disable all periodic state machine
5895 pAdapter->StaCfg.bAutoReconnect = FALSE;
5896 // reset all mlme state machine
5897 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5898 DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
5899 if (pAdapter->CommonCfg.CentralChannel == 0)
5900 {
5901#ifdef DOT11_N_SUPPORT
5902 if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
5903 pAdapter->CommonCfg.CentralChannel = 36;
5904 else
5905#endif // DOT11_N_SUPPORT //
5906 pAdapter->CommonCfg.CentralChannel = 6;
5907 }
5908#ifdef DOT11_N_SUPPORT
5909 else
5910 N_ChannelCheck(pAdapter);
5911#endif // DOT11_N_SUPPORT //
5912
5913#ifdef DOT11_N_SUPPORT
5914 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5915 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5916 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
5917 {
5918 // 40MHz ,control channel at lower
5919 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5920 bbpValue &= (~0x18);
5921 bbpValue |= 0x10;
5922 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5923 pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5924 // RX : control channel at lower
5925 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5926 bbpValue &= (~0x20);
5927 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5928
5929 RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5930 Value &= 0xfffffffe;
5931 RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5932 pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
5933 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5934 AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5935 DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5936 pAdapter->CommonCfg.Channel,
5937 pAdapter->CommonCfg.CentralChannel));
5938 }
5939 else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5940 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5941 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
5942 {
5943 // 40MHz ,control channel at upper
5944 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5945 bbpValue &= (~0x18);
5946 bbpValue |= 0x10;
5947 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5948 pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5949 RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5950 Value |= 0x1;
5951 RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5952
5953 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5954 bbpValue |= (0x20);
5955 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5956 pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
5957 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5958 AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5959 DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5960 pAdapter->CommonCfg.Channel,
5961 pAdapter->CommonCfg.CentralChannel));
5962 }
5963 else
5964#endif // DOT11_N_SUPPORT //
5965 {
5966 // 20MHz
5967 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5968 bbpValue &= (~0x18);
5969 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5970 pAdapter->CommonCfg.BBPCurrentBW = BW_20;
5971 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
5972 AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
5973 DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
5974 }
5975 // Enable Rx with promiscuous reception
5976 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
5977 // ASIC supporsts sniffer function with replacing RSSI with timestamp.
5978 //RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5979 //Value |= (0x80);
5980 //RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5981 // disable sync
5982 RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
5983 csr.field.bBeaconGen = 0;
5984 csr.field.bTBTTEnable = 0;
5985 csr.field.TsfSyncMode = 0;
5986 RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
5987
5988 pAdapter->StaCfg.BssType = BSS_MONITOR;
5989 pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
5990 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
5991 }
5992
5993 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
5994 pAdapter->StaCfg.WpaState = SS_NOTUSE;
5995
5996 DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
5997
5998 return TRUE;
5999}
6000
6001/*
6002 ==========================================================================
6003 Description:
6004 Set Authentication mode
6005 Return:
6006 TRUE if all parameters are OK, FALSE otherwise
6007 ==========================================================================
6008*/
6009INT Set_AuthMode_Proc(
6010 IN PRTMP_ADAPTER pAdapter,
6011 IN PUCHAR arg)
6012{
6013 if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
6014 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
6015 else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
6016 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
6017 else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
6018 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
6019 else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
6020 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
6021 else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
6022 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
6023 else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
6024 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
6025#ifdef WPA_SUPPLICANT_SUPPORT
6026 else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
6027 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
6028 else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
6029 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
6030#endif // WPA_SUPPLICANT_SUPPORT //
6031 else
6032 return FALSE;
6033
6034 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
6035
6036 DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
6037
6038 return TRUE;
6039}
6040
6041/*
6042 ==========================================================================
6043 Description:
6044 Set Encryption Type
6045 Return:
6046 TRUE if all parameters are OK, FALSE otherwise
6047 ==========================================================================
6048*/
6049INT Set_EncrypType_Proc(
6050 IN PRTMP_ADAPTER pAdapter,
6051 IN PUCHAR arg)
6052{
6053 if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
6054 {
6055 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6056 return TRUE; // do nothing
6057
6058 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
6059 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
6060 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
6061 }
6062 else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
6063 {
6064 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6065 return TRUE; // do nothing
6066
6067 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
6068 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
6069 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
6070 }
6071 else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
6072 {
6073 if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
6074 return TRUE; // do nothing
6075
6076 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
6077 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
6078 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
6079 }
6080 else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
6081 {
6082 if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
6083 return TRUE; // do nothing
6084
6085 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
6086 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
6087 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
6088 }
6089 else
6090 return FALSE;
6091
6092 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
6093
6094 DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
6095
6096 return TRUE;
6097}
6098
6099/*
6100 ==========================================================================
6101 Description:
6102 Set Default Key ID
6103 Return:
6104 TRUE if all parameters are OK, FALSE otherwise
6105 ==========================================================================
6106*/
6107INT Set_DefaultKeyID_Proc(
6108 IN PRTMP_ADAPTER pAdapter,
6109 IN PUCHAR arg)
6110{
6111 ULONG KeyIdx;
6112
6113 KeyIdx = simple_strtol(arg, 0, 10);
6114 if((KeyIdx >= 1 ) && (KeyIdx <= 4))
6115 pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
6116 else
6117 return FALSE; //Invalid argument
6118
6119 DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
6120
6121 return TRUE;
6122}
6123
6124/*
6125 ==========================================================================
6126 Description:
6127 Set WEP KEY1
6128 Return:
6129 TRUE if all parameters are OK, FALSE otherwise
6130 ==========================================================================
6131*/
6132INT Set_Key1_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][0].KeyLen = KeyLen;
6149 memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6150 CipherAlg = CIPHER_WEP64;
6151 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%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][0].KeyLen = KeyLen / 2 ;
6160 AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6161 CipherAlg = CIPHER_WEP64;
6162 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6163 break;
6164 case 13: //wep 104 Ascii type
6165 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6166 memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6167 CipherAlg = CIPHER_WEP128;
6168 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%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][0].KeyLen = KeyLen / 2 ;
6177 AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6178 CipherAlg = CIPHER_WEP128;
6179 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6180 break;
6181 default: //Invalid argument
6182 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
6183 return FALSE;
6184 }
6185
6186 pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
6187
6188 // Set keys (into ASIC)
6189 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6190 ; // not support
6191 else // Old WEP stuff
6192 {
6193 AsicAddSharedKeyEntry(pAdapter,
6194 0,
6195 0,
6196 pAdapter->SharedKey[BSS0][0].CipherAlg,
6197 pAdapter->SharedKey[BSS0][0].Key,
6198 NULL,
6199 NULL);
6200 }
6201
6202 return TRUE;
6203}
6204/*
6205 ==========================================================================
6206
6207 Description:
6208 Set WEP KEY2
6209 Return:
6210 TRUE if all parameters are OK, FALSE otherwise
6211 ==========================================================================
6212*/
6213INT Set_Key2_Proc(
6214 IN PRTMP_ADAPTER pAdapter,
6215 IN PUCHAR arg)
6216{
6217 int KeyLen;
6218 int i;
6219 UCHAR CipherAlg=CIPHER_WEP64;
6220
6221 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6222 return TRUE; // do nothing
6223
6224 KeyLen = strlen(arg);
6225
6226 switch (KeyLen)
6227 {
6228 case 5: //wep 40 Ascii type
6229 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6230 memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6231 CipherAlg = CIPHER_WEP64;
6232 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6233 break;
6234 case 10: //wep 40 Hex type
6235 for(i=0; i < KeyLen; i++)
6236 {
6237 if( !isxdigit(*(arg+i)) )
6238 return FALSE; //Not Hex value;
6239 }
6240 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6241 AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6242 CipherAlg = CIPHER_WEP64;
6243 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6244 break;
6245 case 13: //wep 104 Ascii type
6246 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6247 memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6248 CipherAlg = CIPHER_WEP128;
6249 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6250 break;
6251 case 26: //wep 104 Hex type
6252 for(i=0; i < KeyLen; i++)
6253 {
6254 if( !isxdigit(*(arg+i)) )
6255 return FALSE; //Not Hex value;
6256 }
6257 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6258 AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6259 CipherAlg = CIPHER_WEP128;
6260 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6261 break;
6262 default: //Invalid argument
6263 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
6264 return FALSE;
6265 }
6266 pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
6267
6268 // Set keys (into ASIC)
6269 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6270 ; // not support
6271 else // Old WEP stuff
6272 {
6273 AsicAddSharedKeyEntry(pAdapter,
6274 0,
6275 1,
6276 pAdapter->SharedKey[BSS0][1].CipherAlg,
6277 pAdapter->SharedKey[BSS0][1].Key,
6278 NULL,
6279 NULL);
6280 }
6281
6282 return TRUE;
6283}
6284/*
6285 ==========================================================================
6286 Description:
6287 Set WEP KEY3
6288 Return:
6289 TRUE if all parameters are OK, FALSE otherwise
6290 ==========================================================================
6291*/
6292INT Set_Key3_Proc(
6293 IN PRTMP_ADAPTER pAdapter,
6294 IN PUCHAR arg)
6295{
6296 int KeyLen;
6297 int i;
6298 UCHAR CipherAlg=CIPHER_WEP64;
6299
6300 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6301 return TRUE; // do nothing
6302
6303 KeyLen = strlen(arg);
6304
6305 switch (KeyLen)
6306 {
6307 case 5: //wep 40 Ascii type
6308 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6309 memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6310 CipherAlg = CIPHER_WEP64;
6311 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6312 break;
6313 case 10: //wep 40 Hex type
6314 for(i=0; i < KeyLen; i++)
6315 {
6316 if( !isxdigit(*(arg+i)) )
6317 return FALSE; //Not Hex value;
6318 }
6319 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6320 AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6321 CipherAlg = CIPHER_WEP64;
6322 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6323 break;
6324 case 13: //wep 104 Ascii type
6325 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6326 memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6327 CipherAlg = CIPHER_WEP128;
6328 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6329 break;
6330 case 26: //wep 104 Hex type
6331 for(i=0; i < KeyLen; i++)
6332 {
6333 if( !isxdigit(*(arg+i)) )
6334 return FALSE; //Not Hex value;
6335 }
6336 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6337 AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6338 CipherAlg = CIPHER_WEP128;
6339 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6340 break;
6341 default: //Invalid argument
6342 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
6343 return FALSE;
6344 }
6345 pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
6346
6347 // Set keys (into ASIC)
6348 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6349 ; // not support
6350 else // Old WEP stuff
6351 {
6352 AsicAddSharedKeyEntry(pAdapter,
6353 0,
6354 2,
6355 pAdapter->SharedKey[BSS0][2].CipherAlg,
6356 pAdapter->SharedKey[BSS0][2].Key,
6357 NULL,
6358 NULL);
6359 }
6360
6361 return TRUE;
6362}
6363/*
6364 ==========================================================================
6365 Description:
6366 Set WEP KEY4
6367 Return:
6368 TRUE if all parameters are OK, FALSE otherwise
6369 ==========================================================================
6370*/
6371INT Set_Key4_Proc(
6372 IN PRTMP_ADAPTER pAdapter,
6373 IN PUCHAR arg)
6374{
6375 int KeyLen;
6376 int i;
6377 UCHAR CipherAlg=CIPHER_WEP64;
6378
6379 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6380 return TRUE; // do nothing
6381
6382 KeyLen = strlen(arg);
6383
6384 switch (KeyLen)
6385 {
6386 case 5: //wep 40 Ascii type
6387 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6388 memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6389 CipherAlg = CIPHER_WEP64;
6390 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6391 break;
6392 case 10: //wep 40 Hex type
6393 for(i=0; i < KeyLen; i++)
6394 {
6395 if( !isxdigit(*(arg+i)) )
6396 return FALSE; //Not Hex value;
6397 }
6398 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6399 AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6400 CipherAlg = CIPHER_WEP64;
6401 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6402 break;
6403 case 13: //wep 104 Ascii type
6404 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6405 memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6406 CipherAlg = CIPHER_WEP128;
6407 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6408 break;
6409 case 26: //wep 104 Hex type
6410 for(i=0; i < KeyLen; i++)
6411 {
6412 if( !isxdigit(*(arg+i)) )
6413 return FALSE; //Not Hex value;
6414 }
6415 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6416 AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6417 CipherAlg = CIPHER_WEP128;
6418 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6419 break;
6420 default: //Invalid argument
6421 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
6422 return FALSE;
6423 }
6424 pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
6425
6426 // Set keys (into ASIC)
6427 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6428 ; // not support
6429 else // Old WEP stuff
6430 {
6431 AsicAddSharedKeyEntry(pAdapter,
6432 0,
6433 3,
6434 pAdapter->SharedKey[BSS0][3].CipherAlg,
6435 pAdapter->SharedKey[BSS0][3].Key,
6436 NULL,
6437 NULL);
6438 }
6439
6440 return TRUE;
6441}
6442
6443/*
6444 ==========================================================================
6445 Description:
6446 Set WPA PSK key
6447 Return:
6448 TRUE if all parameters are OK, FALSE otherwise
6449 ==========================================================================
6450*/
6451INT Set_WPAPSK_Proc(
6452 IN PRTMP_ADAPTER pAdapter,
6453 IN PUCHAR arg)
6454{
6455 UCHAR keyMaterial[40];
6456
6457 if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
6458 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
6459 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
6460 )
6461 return TRUE; // do nothing
6462
6463 DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
6464
6465 NdisZeroMemory(keyMaterial, 40);
6466
6467 if ((strlen(arg) < 8) || (strlen(arg) > 64))
6468 {
6469 DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
6470 return FALSE;
6471 }
6472
6473 if (strlen(arg) == 64)
6474 {
6475 AtoH(arg, keyMaterial, 32);
6476 NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6477
6478 }
6479 else
6480 {
6481 PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
6482 NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6483 }
6484
6485
6486
6487 if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
6488 pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
6489 {
6490 pAdapter->StaCfg.WpaState = SS_NOTUSE;
6491 }
6492 else
6493 {
6494 // Start STA supplicant state machine
6495 pAdapter->StaCfg.WpaState = SS_START;
6496 }
6497
6498 return TRUE;
6499}
6500
6501/*
6502 ==========================================================================
6503 Description:
6504 Set Power Saving mode
6505 Return:
6506 TRUE if all parameters are OK, FALSE otherwise
6507 ==========================================================================
6508*/
6509INT Set_PSMode_Proc(
6510 IN PRTMP_ADAPTER pAdapter,
6511 IN PUCHAR arg)
6512{
6513 if (pAdapter->StaCfg.BssType == BSS_INFRA)
6514 {
6515 if ((strcmp(arg, "Max_PSP") == 0) ||
6516 (strcmp(arg, "max_psp") == 0) ||
6517 (strcmp(arg, "MAX_PSP") == 0))
6518 {
6519 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6520 // to exclude certain situations.
6521 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6522 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
6523 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
6524 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6525 pAdapter->StaCfg.DefaultListenCount = 5;
6526
6527 }
6528 else if ((strcmp(arg, "Fast_PSP") == 0) ||
6529 (strcmp(arg, "fast_psp") == 0) ||
6530 (strcmp(arg, "FAST_PSP") == 0))
6531 {
6532 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6533 // to exclude certain situations.
6534 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6535 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6536 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
6537 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
6538 pAdapter->StaCfg.DefaultListenCount = 3;
6539 }
6540 else if ((strcmp(arg, "Legacy_PSP") == 0) ||
6541 (strcmp(arg, "legacy_psp") == 0) ||
6542 (strcmp(arg, "LEGACY_PSP") == 0))
6543 {
6544 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6545 // to exclude certain situations.
6546 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6547 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6548 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
6549 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
6550 pAdapter->StaCfg.DefaultListenCount = 3;
6551 }
6552 else
6553 {
6554 //Default Ndis802_11PowerModeCAM
6555 // clear PSM bit immediately
6556 MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
6557 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6558 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6559 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
6560 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
6561 }
6562
6563 DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
6564 }
6565 else
6566 return FALSE;
6567
6568
6569 return TRUE;
6570}
6571
6572#ifdef WPA_SUPPLICANT_SUPPORT
6573/*
6574 ==========================================================================
6575 Description:
6576 Set WpaSupport flag.
6577 Value:
6578 0: Driver ignore wpa_supplicant.
6579 1: wpa_supplicant initiates scanning and AP selection.
6580 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
6581 Return:
6582 TRUE if all parameters are OK, FALSE otherwise
6583 ==========================================================================
6584*/
6585INT Set_Wpa_Support(
6586 IN PRTMP_ADAPTER pAd,
6587 IN PUCHAR arg)
6588{
6589
6590 if ( simple_strtol(arg, 0, 10) == 0)
6591 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6592 else if ( simple_strtol(arg, 0, 10) == 1)
6593 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
6594 else if ( simple_strtol(arg, 0, 10) == 2)
6595 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
6596 else
6597 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6598
6599 DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
6600
6601 return TRUE;
6602}
6603#endif // WPA_SUPPLICANT_SUPPORT //
6604
6605#ifdef DBG
6606/*
6607 ==========================================================================
6608 Description:
6609 Read / Write MAC
6610 Arguments:
6611 pAdapter Pointer to our adapter
6612 wrq Pointer to the ioctl argument
6613
6614 Return Value:
6615 None
6616
6617 Note:
6618 Usage:
6619 1.) iwpriv ra0 mac 0 ==> read MAC where Addr=0x0
6620 2.) iwpriv ra0 mac 0=12 ==> write MAC where Addr=0x0, value=12
6621 ==========================================================================
6622*/
6623VOID RTMPIoctlMAC(
6624 IN PRTMP_ADAPTER pAdapter,
6625 IN struct iwreq *wrq)
6626{
6627 CHAR *this_char;
6628 CHAR *value;
6629 INT j = 0, k = 0;
6630 CHAR msg[1024];
6631 CHAR arg[255];
6632 ULONG macAddr = 0;
6633 UCHAR temp[16], temp2[16];
6634 UINT32 macValue = 0;
6635 INT Status;
6636
6637
6638 memset(msg, 0x00, 1024);
6639 if (wrq->u.data.length > 1) //No parameters.
6640 {
6641 Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6642 sprintf(msg, "\n");
6643
6644 //Parsing Read or Write
6645 this_char = arg;
6646 if (!*this_char)
6647 goto next;
6648
6649 if ((value = rtstrchr(this_char, '=')) != NULL)
6650 *value++ = 0;
6651
6652 if (!value || !*value)
6653 { //Read
6654 // Sanity check
6655 if(strlen(this_char) > 4)
6656 goto next;
6657
6658 j = strlen(this_char);
6659 while(j-- > 0)
6660 {
6661 if(this_char[j] > 'f' || this_char[j] < '0')
6662 return;
6663 }
6664
6665 // Mac Addr
6666 k = j = strlen(this_char);
6667 while(j-- > 0)
6668 {
6669 this_char[4-k+j] = this_char[j];
6670 }
6671
6672 while(k < 4)
6673 this_char[3-k++]='0';
6674 this_char[4]='\0';
6675
6676 if(strlen(this_char) == 4)
6677 {
6678 AtoH(this_char, temp, 2);
6679 macAddr = *temp*256 + temp[1];
6680 if (macAddr < 0xFFFF)
6681 {
6682 RTMP_IO_READ32(pAdapter, macAddr, &macValue);
6683 DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
6684 sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr , macValue);
6685 }
6686 else
6687 {//Invalid parametes, so default printk all bbp
6688 goto next;
6689 }
6690 }
6691 }
6692 else
6693 { //Write
6694 memcpy(&temp2, value, strlen(value));
6695 temp2[strlen(value)] = '\0';
6696
6697 // Sanity check
6698 if((strlen(this_char) > 4) || strlen(temp2) > 8)
6699 goto next;
6700
6701 j = strlen(this_char);
6702 while(j-- > 0)
6703 {
6704 if(this_char[j] > 'f' || this_char[j] < '0')
6705 return;
6706 }
6707
6708 j = strlen(temp2);
6709 while(j-- > 0)
6710 {
6711 if(temp2[j] > 'f' || temp2[j] < '0')
6712 return;
6713 }
6714
6715 //MAC Addr
6716 k = j = strlen(this_char);
6717 while(j-- > 0)
6718 {
6719 this_char[4-k+j] = this_char[j];
6720 }
6721
6722 while(k < 4)
6723 this_char[3-k++]='0';
6724 this_char[4]='\0';
6725
6726 //MAC value
6727 k = j = strlen(temp2);
6728 while(j-- > 0)
6729 {
6730 temp2[8-k+j] = temp2[j];
6731 }
6732
6733 while(k < 8)
6734 temp2[7-k++]='0';
6735 temp2[8]='\0';
6736
6737 {
6738 AtoH(this_char, temp, 2);
6739 macAddr = *temp*256 + temp[1];
6740
6741 AtoH(temp2, temp, 4);
6742 macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
6743
6744 // debug mode
6745 if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
6746 {
6747 // 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
6748 if (macValue & 0x000000ff)
6749 {
6750 pAdapter->BbpTuning.bEnable = TRUE;
6751 DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
6752 }
6753 else
6754 {
6755 UCHAR R66;
6756 pAdapter->BbpTuning.bEnable = FALSE;
6757 R66 = 0x26 + GET_LNA_GAIN(pAdapter);
6758#ifdef RALINK_ATE
6759 if (ATE_ON(pAdapter))
6760 {
6761 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6762 }
6763 else
6764#endif // RALINK_ATE //
6765 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6766 DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
6767 }
6768 return;
6769 }
6770
6771 DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
6772
6773 RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
6774 sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr, macValue);
6775 }
6776 }
6777 }
6778next:
6779 if(strlen(msg) == 1)
6780 sprintf(msg+strlen(msg), "===>Error command format!");
6781
6782 // Copy the information into the user buffer
6783 wrq->u.data.length = strlen(msg);
6784 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6785
6786 DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
6787}
6788
6789/*
6790 ==========================================================================
6791 Description:
6792 Read / Write E2PROM
6793 Arguments:
6794 pAdapter Pointer to our adapter
6795 wrq Pointer to the ioctl argument
6796
6797 Return Value:
6798 None
6799
6800 Note:
6801 Usage:
6802 1.) iwpriv ra0 e2p 0 ==> read E2PROM where Addr=0x0
6803 2.) iwpriv ra0 e2p 0=1234 ==> write E2PROM where Addr=0x0, value=1234
6804 ==========================================================================
6805*/
6806VOID RTMPIoctlE2PROM(
6807 IN PRTMP_ADAPTER pAdapter,
6808 IN struct iwreq *wrq)
6809{
6810 CHAR *this_char;
6811 CHAR *value;
6812 INT j = 0, k = 0;
6813 CHAR msg[1024];
6814 CHAR arg[255];
6815 USHORT eepAddr = 0;
6816 UCHAR temp[16], temp2[16];
6817 USHORT eepValue;
6818 int Status;
6819
6820
6821 memset(msg, 0x00, 1024);
6822 if (wrq->u.data.length > 1) //No parameters.
6823 {
6824 Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6825 sprintf(msg, "\n");
6826
6827 //Parsing Read or Write
6828 this_char = arg;
6829
6830
6831 if (!*this_char)
6832 goto next;
6833
6834 if ((value = rtstrchr(this_char, '=')) != NULL)
6835 *value++ = 0;
6836
6837 if (!value || !*value)
6838 { //Read
6839
6840 // Sanity check
6841 if(strlen(this_char) > 4)
6842 goto next;
6843
6844 j = strlen(this_char);
6845 while(j-- > 0)
6846 {
6847 if(this_char[j] > 'f' || this_char[j] < '0')
6848 return;
6849 }
6850
6851 // E2PROM addr
6852 k = j = strlen(this_char);
6853 while(j-- > 0)
6854 {
6855 this_char[4-k+j] = this_char[j];
6856 }
6857
6858 while(k < 4)
6859 this_char[3-k++]='0';
6860 this_char[4]='\0';
6861
6862 if(strlen(this_char) == 4)
6863 {
6864 AtoH(this_char, temp, 2);
6865 eepAddr = *temp*256 + temp[1];
6866 if (eepAddr < 0xFFFF)
6867 {
6868 RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
6869 sprintf(msg+strlen(msg), "[0x%04X]:0x%04X ", eepAddr , eepValue);
6870 }
6871 else
6872 {//Invalid parametes, so default printk all bbp
6873 goto next;
6874 }
6875 }
6876 }
6877 else
6878 { //Write
6879 memcpy(&temp2, value, strlen(value));
6880 temp2[strlen(value)] = '\0';
6881
6882 // Sanity check
6883 if((strlen(this_char) > 4) || strlen(temp2) > 8)
6884 goto next;
6885
6886 j = strlen(this_char);
6887 while(j-- > 0)
6888 {
6889 if(this_char[j] > 'f' || this_char[j] < '0')
6890 return;
6891 }
6892 j = strlen(temp2);
6893 while(j-- > 0)
6894 {
6895 if(temp2[j] > 'f' || temp2[j] < '0')
6896 return;
6897 }
6898
6899 //MAC Addr
6900 k = j = strlen(this_char);
6901 while(j-- > 0)
6902 {
6903 this_char[4-k+j] = this_char[j];
6904 }
6905
6906 while(k < 4)
6907 this_char[3-k++]='0';
6908 this_char[4]='\0';
6909
6910 //MAC value
6911 k = j = strlen(temp2);
6912 while(j-- > 0)
6913 {
6914 temp2[4-k+j] = temp2[j];
6915 }
6916
6917 while(k < 4)
6918 temp2[3-k++]='0';
6919 temp2[4]='\0';
6920
6921 AtoH(this_char, temp, 2);
6922 eepAddr = *temp*256 + temp[1];
6923
6924 AtoH(temp2, temp, 2);
6925 eepValue = *temp*256 + temp[1];
6926
6927 RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
6928 sprintf(msg+strlen(msg), "[0x%02X]:%02X ", eepAddr, eepValue);
6929 }
6930 }
6931next:
6932 if(strlen(msg) == 1)
6933 sprintf(msg+strlen(msg), "===>Error command format!");
6934
6935
6936 // Copy the information into the user buffer
6937 wrq->u.data.length = strlen(msg);
6938 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6939
6940 DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
6941}
6942#endif // DBG //
6943
6944
6945
6946
6947INT Set_TGnWifiTest_Proc(
6948 IN PRTMP_ADAPTER pAd,
6949 IN PUCHAR arg)
6950{
6951 if (simple_strtol(arg, 0, 10) == 0)
6952 pAd->StaCfg.bTGnWifiTest = FALSE;
6953 else
6954 pAd->StaCfg.bTGnWifiTest = TRUE;
6955
6956 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
6957 return TRUE;
6958}
6959
6960INT Set_LongRetryLimit_Proc(
6961 IN PRTMP_ADAPTER pAdapter,
6962 IN PUCHAR arg)
6963{
6964 TX_RTY_CFG_STRUC tx_rty_cfg;
6965 UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6966
6967 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6968 tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
6969 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6970 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6971 return TRUE;
6972}
6973
6974INT Set_ShortRetryLimit_Proc(
6975 IN PRTMP_ADAPTER pAdapter,
6976 IN PUCHAR arg)
6977{
6978 TX_RTY_CFG_STRUC tx_rty_cfg;
6979 UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6980
6981 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6982 tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
6983 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6984 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6985 return TRUE;
6986}
6987
6988#ifdef EXT_BUILD_CHANNEL_LIST
6989INT Set_Ieee80211dClientMode_Proc(
6990 IN PRTMP_ADAPTER pAdapter,
6991 IN PUCHAR arg)
6992{
6993 if (simple_strtol(arg, 0, 10) == 0)
6994 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
6995 else if (simple_strtol(arg, 0, 10) == 1)
6996 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible;
6997 else if (simple_strtol(arg, 0, 10) == 2)
6998 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict;
6999 else
7000 return FALSE;
7001
7002 DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode));
7003 return TRUE;
7004}
7005#endif // EXT_BUILD_CHANNEL_LIST //
7006
7007#ifdef CARRIER_DETECTION_SUPPORT
7008INT Set_CarrierDetect_Proc(
7009 IN PRTMP_ADAPTER pAd,
7010 IN PUCHAR arg)
7011{
7012 if (simple_strtol(arg, 0, 10) == 0)
7013 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
7014 else
7015 pAd->CommonCfg.CarrierDetect.Enable = TRUE;
7016
7017 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable));
7018 return TRUE;
7019}
7020#endif // CARRIER_DETECTION_SUPPORT //
7021
7022
7023INT Show_Adhoc_MacTable_Proc(
7024 IN PRTMP_ADAPTER pAd,
7025 IN PCHAR extra)
7026{
7027 INT i;
7028
7029 sprintf(extra, "\n");
7030
7031#ifdef DOT11_N_SUPPORT
7032 sprintf(extra, "%sHT Operating Mode : %d\n", extra, pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode);
7033#endif // DOT11_N_SUPPORT //
7034
7035 sprintf(extra, "%s\n%-19s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n", extra,
7036 "MAC", "AID", "BSS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
7037
7038 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
7039 {
7040 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
7041
7042 if (strlen(extra) > (IW_PRIV_SIZE_MASK - 30))
7043 break;
7044 if ((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
7045 {
7046 sprintf(extra, "%s%02X:%02X:%02X:%02X:%02X:%02X ", extra,
7047 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
7048 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
7049 sprintf(extra, "%s%-4d", extra, (int)pEntry->Aid);
7050 sprintf(extra, "%s%-4d", extra, (int)pEntry->apidx);
7051 sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi0);
7052 sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi1);
7053 sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi2);
7054 sprintf(extra, "%s%-10s", extra, GetPhyMode(pEntry->HTPhyMode.field.MODE));
7055 sprintf(extra, "%s%-6s", extra, GetBW(pEntry->HTPhyMode.field.BW));
7056 sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.MCS);
7057 sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.ShortGI);
7058 sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.STBC);
7059 sprintf(extra, "%s%-10d, %d, %d%%\n", extra, pEntry->DebugFIFOCount, pEntry->DebugTxCount,
7060 (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
7061 sprintf(extra, "%s\n", extra);
7062 }
7063 }
7064
7065 return TRUE;
7066}
7067
7068
diff --git a/drivers/staging/rt2870/sta_ioctl.c.patch b/drivers/staging/rt2870/sta_ioctl.c.patch
new file mode 100644
index 00000000000..8672b147a76
--- /dev/null
+++ b/drivers/staging/rt2870/sta_ioctl.c.patch
@@ -0,0 +1,18 @@
1--- sta_ioctl.c 2008-09-19 14:37:52.000000000 +0800
2+++ sta_ioctl.c.fc9 2008-09-19 14:38:20.000000000 +0800
3@@ -49,15 +49,9 @@
4
5 #define GROUP_KEY_NO 4
6
7-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
8 #define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_A, _B, _C, _D, _E)
9 #define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_A, _B, _C, _D, _E)
10 #define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_A, _B, _C, _D, _E, _F)
11-#else
12-#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_B, _C, _D, _E)
13-#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_B, _C, _D, _E)
14-#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_B, _C, _D, _E, _F)
15-#endif
16
17 extern UCHAR CipherWpa2Template[];
18 extern UCHAR CipherWpaPskTkip[];
diff --git a/drivers/staging/rt2870/tmp60 b/drivers/staging/rt2870/tmp60
new file mode 100644
index 00000000000..992096a248c
--- /dev/null
+++ b/drivers/staging/rt2870/tmp60
@@ -0,0 +1,7037 @@
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
52#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
53#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_A, _B, _C, _D, _E)
54#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_A, _B, _C, _D, _E)
55#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_A, _B, _C, _D, _E, _F)
56#else
57#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_B, _C, _D, _E)
58#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_B, _C, _D, _E)
59#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_B, _C, _D, _E, _F)
60#endif
61
62extern UCHAR CipherWpa2Template[];
63extern UCHAR CipherWpaPskTkip[];
64extern UCHAR CipherWpaPskTkipLen;
65
66typedef struct PACKED _RT_VERSION_INFO{
67 UCHAR DriverVersionW;
68 UCHAR DriverVersionX;
69 UCHAR DriverVersionY;
70 UCHAR DriverVersionZ;
71 UINT DriverBuildYear;
72 UINT DriverBuildMonth;
73 UINT DriverBuildDay;
74} RT_VERSION_INFO, *PRT_VERSION_INFO;
75
76struct iw_priv_args privtab[] = {
77{ RTPRIV_IOCTL_SET,
78 IW_PRIV_TYPE_CHAR | 1024, 0,
79 "set"},
80
81{ RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
82 ""},
83{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
84 ""},
85/* --- sub-ioctls definitions --- */
86 { SHOW_CONN_STATUS,
87 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
88 { SHOW_DRVIER_VERION,
89 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
90 { SHOW_BA_INFO,
91 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
92 { SHOW_DESC_INFO,
93 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
94 { RAIO_OFF,
95 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
96 { RAIO_ON,
97 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
98#ifdef QOS_DLS_SUPPORT
99 { SHOW_DLS_ENTRY_INFO,
100 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "dlsentryinfo" },
101#endif // QOS_DLS_SUPPORT //
102 { SHOW_CFG_VALUE,
103 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
104 { SHOW_ADHOC_ENTRY_INFO,
105 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "adhocEntry" },
106
107/* --- sub-ioctls relations --- */
108
109#ifdef DBG
110{ RTPRIV_IOCTL_BBP,
111 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
112 "bbp"},
113{ RTPRIV_IOCTL_MAC,
114 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
115 "mac"},
116{ RTPRIV_IOCTL_E2P,
117 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
118 "e2p"},
119#endif /* DBG */
120
121{ RTPRIV_IOCTL_STATISTICS,
122 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
123 "stat"},
124{ RTPRIV_IOCTL_GSITESURVEY,
125 0, IW_PRIV_TYPE_CHAR | 1024,
126 "get_site_survey"},
127};
128
129INT Set_SSID_Proc(
130 IN PRTMP_ADAPTER pAdapter,
131 IN PUCHAR arg);
132
133#ifdef WMM_SUPPORT
134INT Set_WmmCapable_Proc(
135 IN PRTMP_ADAPTER pAd,
136 IN PUCHAR arg);
137#endif
138
139INT Set_NetworkType_Proc(
140 IN PRTMP_ADAPTER pAdapter,
141 IN PUCHAR arg);
142
143INT Set_AuthMode_Proc(
144 IN PRTMP_ADAPTER pAdapter,
145 IN PUCHAR arg);
146
147INT Set_EncrypType_Proc(
148 IN PRTMP_ADAPTER pAdapter,
149 IN PUCHAR arg);
150
151INT Set_DefaultKeyID_Proc(
152 IN PRTMP_ADAPTER pAdapter,
153 IN PUCHAR arg);
154
155INT Set_Key1_Proc(
156 IN PRTMP_ADAPTER pAdapter,
157 IN PUCHAR arg);
158
159INT Set_Key2_Proc(
160 IN PRTMP_ADAPTER pAdapter,
161 IN PUCHAR arg);
162
163INT Set_Key3_Proc(
164 IN PRTMP_ADAPTER pAdapter,
165 IN PUCHAR arg);
166
167INT Set_Key4_Proc(
168 IN PRTMP_ADAPTER pAdapter,
169 IN PUCHAR arg);
170
171INT Set_WPAPSK_Proc(
172 IN PRTMP_ADAPTER pAdapter,
173 IN PUCHAR arg);
174
175
176INT Set_PSMode_Proc(
177 IN PRTMP_ADAPTER pAdapter,
178 IN PUCHAR arg);
179
180#ifdef WPA_SUPPLICANT_SUPPORT
181INT Set_Wpa_Support(
182 IN PRTMP_ADAPTER pAd,
183 IN PUCHAR arg);
184#endif // WPA_SUPPLICANT_SUPPORT //
185
186#ifdef DBG
187VOID RTMPIoctlBBP(
188 IN PRTMP_ADAPTER pAdapter,
189 IN struct iwreq *wrq);
190
191VOID RTMPIoctlMAC(
192 IN PRTMP_ADAPTER pAdapter,
193 IN struct iwreq *wrq);
194
195VOID RTMPIoctlE2PROM(
196 IN PRTMP_ADAPTER pAdapter,
197 IN struct iwreq *wrq);
198#endif // DBG //
199
200
201NDIS_STATUS RTMPWPANoneAddKeyProc(
202 IN PRTMP_ADAPTER pAd,
203 IN PVOID pBuf);
204
205INT Set_FragTest_Proc(
206 IN PRTMP_ADAPTER pAdapter,
207 IN PUCHAR arg);
208
209#ifdef DOT11_N_SUPPORT
210INT Set_TGnWifiTest_Proc(
211 IN PRTMP_ADAPTER pAd,
212 IN PUCHAR arg);
213#endif // DOT11_N_SUPPORT //
214
215INT Set_LongRetryLimit_Proc(
216 IN PRTMP_ADAPTER pAdapter,
217 IN PUCHAR arg);
218
219INT Set_ShortRetryLimit_Proc(
220 IN PRTMP_ADAPTER pAdapter,
221 IN PUCHAR arg);
222
223#ifdef EXT_BUILD_CHANNEL_LIST
224INT Set_Ieee80211dClientMode_Proc(
225 IN PRTMP_ADAPTER pAdapter,
226 IN PUCHAR arg);
227#endif // EXT_BUILD_CHANNEL_LIST //
228
229#ifdef CARRIER_DETECTION_SUPPORT
230INT Set_CarrierDetect_Proc(
231 IN PRTMP_ADAPTER pAd,
232 IN PUCHAR arg);
233#endif // CARRIER_DETECTION_SUPPORT //
234
235INT Show_Adhoc_MacTable_Proc(
236 IN PRTMP_ADAPTER pAd,
237 IN PCHAR extra);
238
239static struct {
240 CHAR *name;
241 INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
242} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
243 {"DriverVersion", Set_DriverVersion_Proc},
244 {"CountryRegion", Set_CountryRegion_Proc},
245 {"CountryRegionABand", Set_CountryRegionABand_Proc},
246 {"SSID", Set_SSID_Proc},
247 {"WirelessMode", Set_WirelessMode_Proc},
248 {"TxBurst", Set_TxBurst_Proc},
249 {"TxPreamble", Set_TxPreamble_Proc},
250 {"TxPower", Set_TxPower_Proc},
251 {"Channel", Set_Channel_Proc},
252 {"BGProtection", Set_BGProtection_Proc},
253 {"RTSThreshold", Set_RTSThreshold_Proc},
254 {"FragThreshold", Set_FragThreshold_Proc},
255#ifdef DOT11_N_SUPPORT
256 {"HtBw", Set_HtBw_Proc},
257 {"HtMcs", Set_HtMcs_Proc},
258 {"HtGi", Set_HtGi_Proc},
259 {"HtOpMode", Set_HtOpMode_Proc},
260 {"HtExtcha", Set_HtExtcha_Proc},
261 {"HtMpduDensity", Set_HtMpduDensity_Proc},
262 {"HtBaWinSize", Set_HtBaWinSize_Proc},
263 {"HtRdg", Set_HtRdg_Proc},
264 {"HtAmsdu", Set_HtAmsdu_Proc},
265 {"HtAutoBa", Set_HtAutoBa_Proc},
266 {"HtBaDecline", Set_BADecline_Proc},
267 {"HtProtect", Set_HtProtect_Proc},
268 {"HtMimoPs", Set_HtMimoPs_Proc},
269#endif // DOT11_N_SUPPORT //
270
271#ifdef AGGREGATION_SUPPORT
272 {"PktAggregate", Set_PktAggregate_Proc},
273#endif
274
275#ifdef WMM_SUPPORT
276 {"WmmCapable", Set_WmmCapable_Proc},
277#endif
278 {"IEEE80211H", Set_IEEE80211H_Proc},
279 {"NetworkType", Set_NetworkType_Proc},
280 {"AuthMode", Set_AuthMode_Proc},
281 {"EncrypType", Set_EncrypType_Proc},
282 {"DefaultKeyID", Set_DefaultKeyID_Proc},
283 {"Key1", Set_Key1_Proc},
284 {"Key2", Set_Key2_Proc},
285 {"Key3", Set_Key3_Proc},
286 {"Key4", Set_Key4_Proc},
287 {"WPAPSK", Set_WPAPSK_Proc},
288 {"ResetCounter", Set_ResetStatCounter_Proc},
289 {"PSMode", Set_PSMode_Proc},
290#ifdef DBG
291 {"Debug", Set_Debug_Proc},
292#endif
293
294#ifdef RALINK_ATE
295 {"ATE", Set_ATE_Proc},
296 {"ATEDA", Set_ATE_DA_Proc},
297 {"ATESA", Set_ATE_SA_Proc},
298 {"ATEBSSID", Set_ATE_BSSID_Proc},
299 {"ATECHANNEL", Set_ATE_CHANNEL_Proc},
300 {"ATETXPOW0", Set_ATE_TX_POWER0_Proc},
301 {"ATETXPOW1", Set_ATE_TX_POWER1_Proc},
302 {"ATETXANT", Set_ATE_TX_Antenna_Proc},
303 {"ATERXANT", Set_ATE_RX_Antenna_Proc},
304 {"ATETXFREQOFFSET", Set_ATE_TX_FREQOFFSET_Proc},
305 {"ATETXBW", Set_ATE_TX_BW_Proc},
306 {"ATETXLEN", Set_ATE_TX_LENGTH_Proc},
307 {"ATETXCNT", Set_ATE_TX_COUNT_Proc},
308 {"ATETXMCS", Set_ATE_TX_MCS_Proc},
309 {"ATETXMODE", Set_ATE_TX_MODE_Proc},
310 {"ATETXGI", Set_ATE_TX_GI_Proc},
311 {"ATERXFER", Set_ATE_RX_FER_Proc},
312 {"ATERRF", Set_ATE_Read_RF_Proc},
313 {"ATEWRF1", Set_ATE_Write_RF1_Proc},
314 {"ATEWRF2", Set_ATE_Write_RF2_Proc},
315 {"ATEWRF3", Set_ATE_Write_RF3_Proc},
316 {"ATEWRF4", Set_ATE_Write_RF4_Proc},
317 {"ATELDE2P", Set_ATE_Load_E2P_Proc},
318 {"ATERE2P", Set_ATE_Read_E2P_Proc},
319 {"ATESHOW", Set_ATE_Show_Proc},
320 {"ATEHELP", Set_ATE_Help_Proc},
321
322#ifdef RALINK_28xx_QA
323 {"TxStop", Set_TxStop_Proc},
324 {"RxStop", Set_RxStop_Proc},
325#endif // RALINK_28xx_QA //
326#endif // RALINK_ATE //
327
328#ifdef WPA_SUPPLICANT_SUPPORT
329 {"WpaSupport", Set_Wpa_Support},
330#endif // WPA_SUPPLICANT_SUPPORT //
331
332
333
334 {"FixedTxMode", Set_FixedTxMode_Proc},
335#ifdef CONFIG_APSTA_MIXED_SUPPORT
336 {"OpMode", Set_OpMode_Proc},
337#endif // CONFIG_APSTA_MIXED_SUPPORT //
338#ifdef DOT11_N_SUPPORT
339 {"TGnWifiTest", Set_TGnWifiTest_Proc},
340 {"ForceGF", Set_ForceGF_Proc},
341#endif // DOT11_N_SUPPORT //
342#ifdef QOS_DLS_SUPPORT
343 {"DlsAddEntry", Set_DlsAddEntry_Proc},
344 {"DlsTearDownEntry", Set_DlsTearDownEntry_Proc},
345#endif // QOS_DLS_SUPPORT //
346 {"LongRetry", Set_LongRetryLimit_Proc},
347 {"ShortRetry", Set_ShortRetryLimit_Proc},
348#ifdef EXT_BUILD_CHANNEL_LIST
349 {"11dClientMode", Set_Ieee80211dClientMode_Proc},
350#endif // EXT_BUILD_CHANNEL_LIST //
351#ifdef CARRIER_DETECTION_SUPPORT
352 {"CarrierDetect", Set_CarrierDetect_Proc},
353#endif // CARRIER_DETECTION_SUPPORT //
354
355 {NULL,}
356};
357
358
359VOID RTMPAddKey(
360 IN PRTMP_ADAPTER pAd,
361 IN PNDIS_802_11_KEY pKey)
362{
363 ULONG KeyIdx;
364 MAC_TABLE_ENTRY *pEntry;
365
366 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
367
368 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
369 {
370 if (pKey->KeyIndex & 0x80000000)
371 {
372 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
373 {
374 NdisZeroMemory(pAd->StaCfg.PMK, 32);
375 NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
376 goto end;
377 }
378 // Update PTK
379 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
380 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
381 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
382#ifdef WPA_SUPPLICANT_SUPPORT
383 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
384 {
385 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
386 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
387 }
388 else
389#endif // WPA_SUPPLICANT_SUPPORT //
390 {
391 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
392 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
393 }
394
395 // Decide its ChiperAlg
396 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
397 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
398 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
399 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
400 else
401 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
402
403 // Update these related information to MAC_TABLE_ENTRY
404 pEntry = &pAd->MacTab.Content[BSSID_WCID];
405 NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
406 NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
407 NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
408 pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
409
410 // Update pairwise key information to ASIC Shared Key Table
411 AsicAddSharedKeyEntry(pAd,
412 BSS0,
413 0,
414 pAd->SharedKey[BSS0][0].CipherAlg,
415 pAd->SharedKey[BSS0][0].Key,
416 pAd->SharedKey[BSS0][0].TxMic,
417 pAd->SharedKey[BSS0][0].RxMic);
418
419 // Update ASIC WCID attribute table and IVEIV table
420 RTMPAddWcidAttributeEntry(pAd,
421 BSS0,
422 0,
423 pAd->SharedKey[BSS0][0].CipherAlg,
424 pEntry);
425
426 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
427 {
428 // set 802.1x port control
429 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
430 STA_PORT_SECURED(pAd);
431
432 // Indicate Connected for GUI
433 pAd->IndicateMediaState = NdisMediaStateConnected;
434 }
435 }
436 else
437 {
438 // Update GTK
439 pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
440 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
441 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
442 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
443#ifdef WPA_SUPPLICANT_SUPPORT
444 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
445 {
446 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
447 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
448 }
449 else
450#endif // WPA_SUPPLICANT_SUPPORT //
451 {
452 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
453 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
454 }
455
456 // Update Shared Key CipherAlg
457 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
458 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
459 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
460 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
461 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
462
463 // Update group key information to ASIC Shared Key Table
464 AsicAddSharedKeyEntry(pAd,
465 BSS0,
466 pAd->StaCfg.DefaultKeyId,
467 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
468 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
469 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
470 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
471
472 // Update ASIC WCID attribute table and IVEIV table
473 RTMPAddWcidAttributeEntry(pAd,
474 BSS0,
475 pAd->StaCfg.DefaultKeyId,
476 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
477 NULL);
478
479 // set 802.1x port control
480 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
481 STA_PORT_SECURED(pAd);
482
483 // Indicate Connected for GUI
484 pAd->IndicateMediaState = NdisMediaStateConnected;
485 }
486 }
487 else // dynamic WEP from wpa_supplicant
488 {
489 UCHAR CipherAlg;
490 PUCHAR Key;
491
492 if(pKey->KeyLength == 32)
493 goto end;
494
495 KeyIdx = pKey->KeyIndex & 0x0fffffff;
496
497 if (KeyIdx < 4)
498 {
499 // it is a default shared key, for Pairwise key setting
500 if (pKey->KeyIndex & 0x80000000)
501 {
502 pEntry = MacTableLookup(pAd, pKey->BSSID);
503
504 if (pEntry)
505 {
506 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
507
508 // set key material and key length
509 pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
510 NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
511
512 // set Cipher type
513 if (pKey->KeyLength == 5)
514 pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
515 else
516 pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
517
518 // Add Pair-wise key to Asic
519 AsicAddPairwiseKeyEntry(
520 pAd,
521 pEntry->Addr,
522 (UCHAR)pEntry->Aid,
523 &pEntry->PairwiseKey);
524
525 // update WCID attribute table and IVEIV table for this entry
526 RTMPAddWcidAttributeEntry(
527 pAd,
528 BSS0,
529 KeyIdx, // The value may be not zero
530 pEntry->PairwiseKey.CipherAlg,
531 pEntry);
532
533 }
534 }
535 else
536 {
537 // Default key for tx (shared key)
538 pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
539
540 // set key material and key length
541 pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
542 NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
543
544 // Set Ciper type
545 if (pKey->KeyLength == 5)
546 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
547 else
548 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
549
550 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
551 Key = pAd->SharedKey[BSS0][KeyIdx].Key;
552
553 // Set Group key material to Asic
554 AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
555
556 // Update WCID attribute table and IVEIV table for this group key table
557 RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
558
559 }
560 }
561 }
562end:
563 return;
564}
565
566char * rtstrchr(const char * s, int c)
567{
568 for(; *s != (char) c; ++s)
569 if (*s == '\0')
570 return NULL;
571 return (char *) s;
572}
573
574/*
575This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
576*/
577
578int
579rt_ioctl_giwname(struct net_device *dev,
580 struct iw_request_info *info,
581 char *name, char *extra)
582{
583// PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
584
585#ifdef RT2870
586 strncpy(name, "RT2870 Wireless", IFNAMSIZ);
587#endif // RT2870 //
588 return 0;
589}
590
591int rt_ioctl_siwfreq(struct net_device *dev,
592 struct iw_request_info *info,
593 struct iw_freq *freq, char *extra)
594{
595 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
596 int chan = -1;
597
598 //check if the interface is down
599 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
600 {
601 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
602 return -ENETDOWN;
603 }
604
605
606 if (freq->e > 1)
607 return -EINVAL;
608
609 if((freq->e == 0) && (freq->m <= 1000))
610 chan = freq->m; // Setting by channel number
611 else
612 MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
613
614 if (ChannelSanity(pAdapter, chan) == TRUE)
615 {
616 pAdapter->CommonCfg.Channel = chan;
617 DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
618 }
619 else
620 return -EINVAL;
621
622 return 0;
623}
624int rt_ioctl_giwfreq(struct net_device *dev,
625 struct iw_request_info *info,
626 struct iw_freq *freq, char *extra)
627{
628 VIRTUAL_ADAPTER *pVirtualAd = NULL;
629 PRTMP_ADAPTER pAdapter = NULL;
630 UCHAR ch;
631 ULONG m;
632
633 if (dev->priv_flags == INT_MAIN)
634 {
635 pAdapter = dev->priv;
636 }
637 else
638 {
639 pVirtualAd = dev->priv;
640 if (pVirtualAd && pVirtualAd->RtmpDev)
641 pAdapter = pVirtualAd->RtmpDev->priv;
642 }
643
644 if (pAdapter == NULL)
645 {
646 /* if 1st open fail, pAd will be free;
647 So the net_dev->priv will be NULL in 2rd open */
648 return -ENETDOWN;
649 }
650
651 ch = pAdapter->CommonCfg.Channel;
652
653 DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq %d\n", ch));
654
655 MAP_CHANNEL_ID_TO_KHZ(ch, m);
656 freq->m = m * 100;
657 freq->e = 1;
658 return 0;
659}
660
661int rt_ioctl_siwmode(struct net_device *dev,
662 struct iw_request_info *info,
663 __u32 *mode, char *extra)
664{
665 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
666
667 //check if the interface is down
668 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
669 {
670 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
671 return -ENETDOWN;
672 }
673
674 switch (*mode)
675 {
676 case IW_MODE_ADHOC:
677 Set_NetworkType_Proc(pAdapter, "Adhoc");
678 break;
679 case IW_MODE_INFRA:
680 Set_NetworkType_Proc(pAdapter, "Infra");
681 break;
682#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
683 case IW_MODE_MONITOR:
684 Set_NetworkType_Proc(pAdapter, "Monitor");
685 break;
686#endif
687 default:
688 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
689 return -EINVAL;
690 }
691
692 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
693 pAdapter->StaCfg.WpaState = SS_NOTUSE;
694
695 return 0;
696}
697
698int rt_ioctl_giwmode(struct net_device *dev,
699 struct iw_request_info *info,
700 __u32 *mode, char *extra)
701{
702 PRTMP_ADAPTER pAdapter = NULL;
703 VIRTUAL_ADAPTER *pVirtualAd = NULL;
704
705 if (dev->priv_flags == INT_MAIN)
706 {
707 pAdapter = dev->priv;
708 }
709 else
710 {
711 pVirtualAd = dev->priv;
712 if (pVirtualAd && pVirtualAd->RtmpDev)
713 pAdapter = pVirtualAd->RtmpDev->priv;
714 }
715
716 if (pAdapter == NULL)
717 {
718 /* if 1st open fail, pAd will be free;
719 So the net_dev->priv will be NULL in 2rd open */
720 return -ENETDOWN;
721 }
722
723 if (ADHOC_ON(pAdapter))
724 *mode = IW_MODE_ADHOC;
725 else if (INFRA_ON(pAdapter))
726 *mode = IW_MODE_INFRA;
727#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
728 else if (MONITOR_ON(pAdapter))
729 {
730 *mode = IW_MODE_MONITOR;
731 }
732#endif
733 else
734 *mode = IW_MODE_AUTO;
735
736 DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
737 return 0;
738}
739
740int rt_ioctl_siwsens(struct net_device *dev,
741 struct iw_request_info *info,
742 char *name, char *extra)
743{
744 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
745
746 //check if the interface is down
747 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
748 {
749 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
750 return -ENETDOWN;
751 }
752
753 return 0;
754}
755
756int rt_ioctl_giwsens(struct net_device *dev,
757 struct iw_request_info *info,
758 char *name, char *extra)
759{
760 return 0;
761}
762
763int rt_ioctl_giwrange(struct net_device *dev,
764 struct iw_request_info *info,
765 struct iw_point *data, char *extra)
766{
767 PRTMP_ADAPTER pAdapter = NULL;
768 VIRTUAL_ADAPTER *pVirtualAd = NULL;
769 struct iw_range *range = (struct iw_range *) extra;
770 u16 val;
771 int i;
772
773 if (dev->priv_flags == INT_MAIN)
774 {
775 pAdapter = dev->priv;
776 }
777 else
778 {
779 pVirtualAd = dev->priv;
780 if (pVirtualAd && pVirtualAd->RtmpDev)
781 pAdapter = pVirtualAd->RtmpDev->priv;
782 }
783
784 if (pAdapter == NULL)
785 {
786 /* if 1st open fail, pAd will be free;
787 So the net_dev->priv will be NULL in 2rd open */
788 return -ENETDOWN;
789 }
790
791 DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
792 data->length = sizeof(struct iw_range);
793 memset(range, 0, sizeof(struct iw_range));
794
795 range->txpower_capa = IW_TXPOW_DBM;
796
797 if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
798 {
799 range->min_pmp = 1 * 1024;
800 range->max_pmp = 65535 * 1024;
801 range->min_pmt = 1 * 1024;
802 range->max_pmt = 1000 * 1024;
803 range->pmp_flags = IW_POWER_PERIOD;
804 range->pmt_flags = IW_POWER_TIMEOUT;
805 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
806 IW_POWER_UNICAST_R | IW_POWER_ALL_R;
807 }
808
809 range->we_version_compiled = WIRELESS_EXT;
810 range->we_version_source = 14;
811
812 range->retry_capa = IW_RETRY_LIMIT;
813 range->retry_flags = IW_RETRY_LIMIT;
814 range->min_retry = 0;
815 range->max_retry = 255;
816
817 range->num_channels = pAdapter->ChannelListNum;
818
819 val = 0;
820 for (i = 1; i <= range->num_channels; i++)
821 {
822 u32 m;
823 range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
824 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
825 range->freq[val].m = m * 100; /* HZ */
826
827 range->freq[val].e = 1;
828 val++;
829 if (val == IW_MAX_FREQUENCIES)
830 break;
831 }
832 range->num_frequency = val;
833
834 range->max_qual.qual = 100; /* what is correct max? This was not
835 * documented exactly. At least
836 * 69 has been observed. */
837 range->max_qual.level = 0; /* dB */
838 range->max_qual.noise = 0; /* dB */
839
840 /* What would be suitable values for "average/typical" qual? */
841 range->avg_qual.qual = 20;
842 range->avg_qual.level = -60;
843 range->avg_qual.noise = -95;
844 range->sensitivity = 3;
845
846 range->max_encoding_tokens = NR_WEP_KEYS;
847 range->num_encoding_sizes = 2;
848 range->encoding_size[0] = 5;
849 range->encoding_size[1] = 13;
850
851 range->min_rts = 0;
852 range->max_rts = 2347;
853 range->min_frag = 256;
854 range->max_frag = 2346;
855
856#if WIRELESS_EXT > 17
857 /* IW_ENC_CAPA_* bit field */
858 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
859 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
860#endif
861
862 return 0;
863}
864
865int rt_ioctl_siwap(struct net_device *dev,
866 struct iw_request_info *info,
867 struct sockaddr *ap_addr, char *extra)
868{
869 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
870 NDIS_802_11_MAC_ADDRESS Bssid;
871
872 //check if the interface is down
873 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
874 {
875 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
876 return -ENETDOWN;
877 }
878
879 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
880 {
881 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
882 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
883 }
884
885 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
886 // this request, because this request is initiated by NDIS.
887 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
888 // Prevent to connect AP again in STAMlmePeriodicExec
889 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
890
891 memset(Bssid, 0, MAC_ADDR_LEN);
892 memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
893 MlmeEnqueue(pAdapter,
894 MLME_CNTL_STATE_MACHINE,
895 OID_802_11_BSSID,
896 sizeof(NDIS_802_11_MAC_ADDRESS),
897 (VOID *)&Bssid);
898
899 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
900 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
901
902 return 0;
903}
904
905int rt_ioctl_giwap(struct net_device *dev,
906 struct iw_request_info *info,
907 struct sockaddr *ap_addr, char *extra)
908{
909 PRTMP_ADAPTER pAdapter = NULL;
910 VIRTUAL_ADAPTER *pVirtualAd = NULL;
911
912 if (dev->priv_flags == INT_MAIN)
913 {
914 pAdapter = dev->priv;
915 }
916 else
917 {
918 pVirtualAd = dev->priv;
919 if (pVirtualAd && pVirtualAd->RtmpDev)
920 pAdapter = pVirtualAd->RtmpDev->priv;
921 }
922
923 if (pAdapter == NULL)
924 {
925 /* if 1st open fail, pAd will be free;
926 So the net_dev->priv will be NULL in 2rd open */
927 return -ENETDOWN;
928 }
929
930 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
931 {
932 ap_addr->sa_family = ARPHRD_ETHER;
933 memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
934 }
935#ifdef WPA_SUPPLICANT_SUPPORT
936 // Add for RT2870
937 else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
938 {
939 ap_addr->sa_family = ARPHRD_ETHER;
940 memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
941 }
942#endif // WPA_SUPPLICANT_SUPPORT //
943 else
944 {
945 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
946 return -ENOTCONN;
947 }
948
949 return 0;
950}
951
952/*
953 * Units are in db above the noise floor. That means the
954 * rssi values reported in the tx/rx descriptors in the
955 * driver are the SNR expressed in db.
956 *
957 * If you assume that the noise floor is -95, which is an
958 * excellent assumption 99.5 % of the time, then you can
959 * derive the absolute signal level (i.e. -95 + rssi).
960 * There are some other slight factors to take into account
961 * depending on whether the rssi measurement is from 11b,
962 * 11g, or 11a. These differences are at most 2db and
963 * can be documented.
964 *
965 * NB: various calculations are based on the orinoco/wavelan
966 * drivers for compatibility
967 */
968static void set_quality(PRTMP_ADAPTER pAdapter,
969 struct iw_quality *iq,
970 signed char rssi)
971{
972 __u8 ChannelQuality;
973
974 // Normalize Rssi
975 if (rssi >= -50)
976 ChannelQuality = 100;
977 else if (rssi >= -80) // between -50 ~ -80dbm
978 ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
979 else if (rssi >= -90) // between -80 ~ -90dbm
980 ChannelQuality = (__u8)((rssi + 90) * 26)/10;
981 else
982 ChannelQuality = 0;
983
984 iq->qual = (__u8)ChannelQuality;
985
986 iq->level = (__u8)(rssi);
987 iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); // noise level (dBm)
988 iq->noise += 256 - 143;
989 iq->updated = pAdapter->iw_stats.qual.updated;
990}
991
992int rt_ioctl_iwaplist(struct net_device *dev,
993 struct iw_request_info *info,
994 struct iw_point *data, char *extra)
995{
996 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
997
998 struct sockaddr addr[IW_MAX_AP];
999 struct iw_quality qual[IW_MAX_AP];
1000 int i;
1001
1002 //check if the interface is down
1003 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1004 {
1005 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1006 data->length = 0;
1007 return 0;
1008 //return -ENETDOWN;
1009 }
1010
1011 for (i = 0; i <IW_MAX_AP ; i++)
1012 {
1013 if (i >= pAdapter->ScanTab.BssNr)
1014 break;
1015 addr[i].sa_family = ARPHRD_ETHER;
1016 memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
1017 set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
1018 }
1019 data->length = i;
1020 memcpy(extra, &addr, i*sizeof(addr[0]));
1021 data->flags = 1; /* signal quality present (sort of) */
1022 memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
1023
1024 return 0;
1025}
1026
1027#ifdef SIOCGIWSCAN
1028int rt_ioctl_siwscan(struct net_device *dev,
1029 struct iw_request_info *info,
1030 struct iw_point *data, char *extra)
1031{
1032 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1033
1034 ULONG Now;
1035 int Status = NDIS_STATUS_SUCCESS;
1036
1037 //check if the interface is down
1038 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1039 {
1040 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1041 return -ENETDOWN;
1042 }
1043
1044 if (MONITOR_ON(pAdapter))
1045 {
1046 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
1047 return -EINVAL;
1048 }
1049
1050
1051#ifdef WPA_SUPPLICANT_SUPPORT
1052 if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
1053 {
1054 pAdapter->StaCfg.WpaSupplicantScanCount++;
1055 }
1056#endif // WPA_SUPPLICANT_SUPPORT //
1057
1058 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
1059 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1060 return 0;
1061 do{
1062 Now = jiffies;
1063
1064#ifdef WPA_SUPPLICANT_SUPPORT
1065 if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
1066 (pAdapter->StaCfg.WpaSupplicantScanCount > 3))
1067 {
1068 DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
1069 Status = NDIS_STATUS_SUCCESS;
1070 break;
1071 }
1072#endif // WPA_SUPPLICANT_SUPPORT //
1073
1074 if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
1075 ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1076 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
1077 (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1078 {
1079 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
1080 Status = NDIS_STATUS_SUCCESS;
1081 break;
1082 }
1083
1084 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
1085 {
1086 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
1087 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
1088 }
1089
1090 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
1091 // this request, because this request is initiated by NDIS.
1092 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
1093 // Reset allowed scan retries
1094 pAdapter->StaCfg.ScanCnt = 0;
1095 pAdapter->StaCfg.LastScanTime = Now;
1096
1097 MlmeEnqueue(pAdapter,
1098 MLME_CNTL_STATE_MACHINE,
1099 OID_802_11_BSSID_LIST_SCAN,
1100 0,
1101 NULL);
1102
1103 Status = NDIS_STATUS_SUCCESS;
1104 RT28XX_MLME_HANDLER(pAdapter);
1105 }while(0);
1106 return 0;
1107}
1108
1109int rt_ioctl_giwscan(struct net_device *dev,
1110 struct iw_request_info *info,
1111 struct iw_point *data, char *extra)
1112{
1113
1114 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1115 int i=0;
1116 char *current_ev = extra, *previous_ev = extra;
1117 char *end_buf;
1118 char *current_val, custom[MAX_CUSTOM_LEN] = {0};
1119#ifndef IWEVGENIE
1120 char idx;
1121#endif // IWEVGENIE //
1122 struct iw_event iwe;
1123
1124 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1125 {
1126 /*
1127 * Still scanning, indicate the caller should try again.
1128 */
1129 return -EAGAIN;
1130 }
1131
1132
1133#ifdef WPA_SUPPLICANT_SUPPORT
1134 if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
1135 {
1136 pAdapter->StaCfg.WpaSupplicantScanCount = 0;
1137 }
1138#endif // WPA_SUPPLICANT_SUPPORT //
1139
1140 if (pAdapter->ScanTab.BssNr == 0)
1141 {
1142 data->length = 0;
1143 return 0;
1144 }
1145
1146#if WIRELESS_EXT >= 17
1147 if (data->length > 0)
1148 end_buf = extra + data->length;
1149 else
1150 end_buf = extra + IW_SCAN_MAX_DATA;
1151#else
1152 end_buf = extra + IW_SCAN_MAX_DATA;
1153#endif
1154
1155 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
1156 {
1157 if (current_ev >= end_buf)
1158 {
1159#if WIRELESS_EXT >= 17
1160 return -E2BIG;
1161#else
1162 break;
1163#endif
1164 }
1165
1166 //MAC address
1167 //================================
1168 memset(&iwe, 0, sizeof(iwe));
1169 iwe.cmd = SIOCGIWAP;
1170 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1171 memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
1172
1173 previous_ev = current_ev;
1174 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
1175 if (current_ev == previous_ev)
1176#if WIRELESS_EXT >= 17
1177 return -E2BIG;
1178#else
1179 break;
1180#endif
1181
1182 //ESSID
1183 //================================
1184 memset(&iwe, 0, sizeof(iwe));
1185 iwe.cmd = SIOCGIWESSID;
1186 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
1187 iwe.u.data.flags = 1;
1188
1189 previous_ev = current_ev;
1190 current_ev = IWE_STREAM_ADD_POINT(info, current_ev,end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
1191 if (current_ev == previous_ev)
1192#if WIRELESS_EXT >= 17
1193 return -E2BIG;
1194#else
1195 break;
1196#endif
1197
1198 //Network Type
1199 //================================
1200 memset(&iwe, 0, sizeof(iwe));
1201 iwe.cmd = SIOCGIWMODE;
1202 if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
1203 {
1204 iwe.u.mode = IW_MODE_ADHOC;
1205 }
1206 else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
1207 {
1208 iwe.u.mode = IW_MODE_INFRA;
1209 }
1210 else
1211 {
1212 iwe.u.mode = IW_MODE_AUTO;
1213 }
1214 iwe.len = IW_EV_UINT_LEN;
1215
1216 previous_ev = current_ev;
1217 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
1218 if (current_ev == previous_ev)
1219#if WIRELESS_EXT >= 17
1220 return -E2BIG;
1221#else
1222 break;
1223#endif
1224
1225 //Channel and Frequency
1226 //================================
1227 memset(&iwe, 0, sizeof(iwe));
1228 iwe.cmd = SIOCGIWFREQ;
1229 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
1230 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1231 else
1232 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1233 iwe.u.freq.e = 0;
1234 iwe.u.freq.i = 0;
1235
1236 previous_ev = current_ev;
1237 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
1238 if (current_ev == previous_ev)
1239#if WIRELESS_EXT >= 17
1240 return -E2BIG;
1241#else
1242 break;
1243#endif
1244
1245 //Add quality statistics
1246 //================================
1247 memset(&iwe, 0, sizeof(iwe));
1248 iwe.cmd = IWEVQUAL;
1249 iwe.u.qual.level = 0;
1250 iwe.u.qual.noise = 0;
1251 set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
1252 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
1253 if (current_ev == previous_ev)
1254#if WIRELESS_EXT >= 17
1255 return -E2BIG;
1256#else
1257 break;
1258#endif
1259
1260 //Encyption key
1261 //================================
1262 memset(&iwe, 0, sizeof(iwe));
1263 iwe.cmd = SIOCGIWENCODE;
1264 if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
1265 iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1266 else
1267 iwe.u.data.flags = IW_ENCODE_DISABLED;
1268
1269 previous_ev = current_ev;
1270 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);
1271 if (current_ev == previous_ev)
1272#if WIRELESS_EXT >= 17
1273 return -E2BIG;
1274#else
1275 break;
1276#endif
1277
1278 //Bit Rate
1279 //================================
1280 if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
1281 {
1282 UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
1283 memset(&iwe, 0, sizeof(iwe));
1284 iwe.cmd = SIOCGIWRATE;
1285 current_val = current_ev + IW_EV_LCP_LEN;
1286 if (tmpRate == 0x82)
1287 iwe.u.bitrate.value = 1 * 1000000;
1288 else if (tmpRate == 0x84)
1289 iwe.u.bitrate.value = 2 * 1000000;
1290 else if (tmpRate == 0x8B)
1291 iwe.u.bitrate.value = 5.5 * 1000000;
1292 else if (tmpRate == 0x96)
1293 iwe.u.bitrate.value = 11 * 1000000;
1294 else
1295 iwe.u.bitrate.value = (tmpRate/2) * 1000000;
1296
1297 iwe.u.bitrate.disabled = 0;
1298 current_val = IWE_STREAM_ADD_VALUE(info, current_ev,
1299 current_val, end_buf, &iwe,
1300 IW_EV_PARAM_LEN);
1301
1302 if((current_val-current_ev)>IW_EV_LCP_LEN)
1303 current_ev = current_val;
1304 else
1305#if WIRELESS_EXT >= 17
1306 return -E2BIG;
1307#else
1308 break;
1309#endif
1310 }
1311
1312#ifdef IWEVGENIE
1313 //WPA IE
1314 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1315 {
1316 memset(&iwe, 0, sizeof(iwe));
1317 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1318 memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
1319 pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
1320 iwe.cmd = IWEVGENIE;
1321 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
1322 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1323 if (current_ev == previous_ev)
1324#if WIRELESS_EXT >= 17
1325 return -E2BIG;
1326#else
1327 break;
1328#endif
1329 }
1330
1331 //WPA2 IE
1332 if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1333 {
1334 memset(&iwe, 0, sizeof(iwe));
1335 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1336 memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
1337 pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
1338 iwe.cmd = IWEVGENIE;
1339 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
1340 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1341 if (current_ev == previous_ev)
1342#if WIRELESS_EXT >= 17
1343 return -E2BIG;
1344#else
1345 break;
1346#endif
1347 }
1348#else
1349 //WPA IE
1350 //================================
1351 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1352 {
1353 NdisZeroMemory(&iwe, sizeof(iwe));
1354 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1355 iwe.cmd = IWEVCUSTOM;
1356 iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen * 2) + 7;
1357 NdisMoveMemory(custom, "wpa_ie=", 7);
1358 for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].WpaIE.IELen; idx++)
1359 sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].WpaIE.IE[idx]);
1360 previous_ev = current_ev;
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
1370 //WPA2 IE
1371 if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1372 {
1373 NdisZeroMemory(&iwe, sizeof(iwe));
1374 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1375 iwe.cmd = IWEVCUSTOM;
1376 iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen * 2) + 7;
1377 NdisMoveMemory(custom, "rsn_ie=", 7);
1378 for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].RsnIE.IELen; idx++)
1379 sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].RsnIE.IE[idx]);
1380 previous_ev = current_ev;
1381 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1382 if (current_ev == previous_ev)
1383#if WIRELESS_EXT >= 17
1384 return -E2BIG;
1385#else
1386 break;
1387#endif
1388 }
1389#endif // IWEVGENIE //
1390 }
1391
1392 data->length = current_ev - extra;
1393 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
1394 DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
1395 return 0;
1396}
1397#endif
1398
1399int rt_ioctl_siwessid(struct net_device *dev,
1400 struct iw_request_info *info,
1401 struct iw_point *data, char *essid)
1402{
1403 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1404
1405 //check if the interface is down
1406 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1407 {
1408 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1409 return -ENETDOWN;
1410 }
1411
1412 if (data->flags)
1413 {
1414 PCHAR pSsidString = NULL;
1415
1416 // Includes null character.
1417 if (data->length > (IW_ESSID_MAX_SIZE + 1))
1418 return -E2BIG;
1419
1420 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
1421 if (pSsidString)
1422 {
1423 NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
1424 NdisMoveMemory(pSsidString, essid, data->length);
1425 if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
1426 return -EINVAL;
1427 }
1428 else
1429 return -ENOMEM;
1430 }
1431 else
1432 {
1433 // ANY ssid
1434 if (Set_SSID_Proc(pAdapter, "") == FALSE)
1435 return -EINVAL;
1436 }
1437 return 0;
1438}
1439
1440int rt_ioctl_giwessid(struct net_device *dev,
1441 struct iw_request_info *info,
1442 struct iw_point *data, char *essid)
1443{
1444 PRTMP_ADAPTER pAdapter = NULL;
1445 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1446
1447 if (dev->priv_flags == INT_MAIN)
1448 {
1449 pAdapter = dev->priv;
1450 }
1451 else
1452 {
1453 pVirtualAd = dev->priv;
1454 if (pVirtualAd && pVirtualAd->RtmpDev)
1455 pAdapter = pVirtualAd->RtmpDev->priv;
1456 }
1457
1458 if (pAdapter == NULL)
1459 {
1460 /* if 1st open fail, pAd will be free;
1461 So the net_dev->priv will be NULL in 2rd open */
1462 return -ENETDOWN;
1463 }
1464
1465 data->flags = 1;
1466 if (MONITOR_ON(pAdapter))
1467 {
1468 data->length = 0;
1469 return 0;
1470 }
1471
1472 if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
1473 {
1474 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
1475 data->length = pAdapter->CommonCfg.SsidLen;
1476 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1477 }
1478#ifdef RT2870
1479#ifdef WPA_SUPPLICANT_SUPPORT
1480 // Add for RT2870
1481 else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1482 {
1483 data->length = pAdapter->CommonCfg.SsidLen;
1484 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1485 }
1486#endif // WPA_SUPPLICANT_SUPPORT //
1487#endif // RT2870 //
1488 else
1489 {//the ANY ssid was specified
1490 data->length = 0;
1491 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
1492 }
1493
1494 return 0;
1495
1496}
1497
1498int rt_ioctl_siwnickn(struct net_device *dev,
1499 struct iw_request_info *info,
1500 struct iw_point *data, char *nickname)
1501{
1502 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1503
1504 //check if the interface is down
1505 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1506 {
1507 DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
1508 return -ENETDOWN;
1509 }
1510
1511 if (data->length > IW_ESSID_MAX_SIZE)
1512 return -EINVAL;
1513
1514 memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
1515 memcpy(pAdapter->nickname, nickname, data->length);
1516
1517
1518 return 0;
1519}
1520
1521int rt_ioctl_giwnickn(struct net_device *dev,
1522 struct iw_request_info *info,
1523 struct iw_point *data, char *nickname)
1524{
1525 PRTMP_ADAPTER pAdapter = NULL;
1526 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1527
1528 if (dev->priv_flags == INT_MAIN)
1529 {
1530 pAdapter = dev->priv;
1531 }
1532 else
1533 {
1534 pVirtualAd = dev->priv;
1535 if (pVirtualAd && pVirtualAd->RtmpDev)
1536 pAdapter = pVirtualAd->RtmpDev->priv;
1537 }
1538
1539 if (pAdapter == NULL)
1540 {
1541 /* if 1st open fail, pAd will be free;
1542 So the net_dev->priv will be NULL in 2rd open */
1543 return -ENETDOWN;
1544 }
1545
1546 if (data->length > strlen(pAdapter->nickname) + 1)
1547 data->length = strlen(pAdapter->nickname) + 1;
1548 if (data->length > 0) {
1549 memcpy(nickname, pAdapter->nickname, data->length-1);
1550 nickname[data->length-1] = '\0';
1551 }
1552 return 0;
1553}
1554
1555int rt_ioctl_siwrts(struct net_device *dev,
1556 struct iw_request_info *info,
1557 struct iw_param *rts, char *extra)
1558{
1559 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1560 u16 val;
1561
1562 //check if the interface is down
1563 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1564 {
1565 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1566 return -ENETDOWN;
1567 }
1568
1569 if (rts->disabled)
1570 val = MAX_RTS_THRESHOLD;
1571 else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
1572 return -EINVAL;
1573 else if (rts->value == 0)
1574 val = MAX_RTS_THRESHOLD;
1575 else
1576 val = rts->value;
1577
1578 if (val != pAdapter->CommonCfg.RtsThreshold)
1579 pAdapter->CommonCfg.RtsThreshold = val;
1580
1581 return 0;
1582}
1583
1584int rt_ioctl_giwrts(struct net_device *dev,
1585 struct iw_request_info *info,
1586 struct iw_param *rts, char *extra)
1587{
1588 PRTMP_ADAPTER pAdapter = NULL;
1589 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1590
1591 if (dev->priv_flags == INT_MAIN)
1592 {
1593 pAdapter = dev->priv;
1594 }
1595 else
1596 {
1597 pVirtualAd = dev->priv;
1598 if (pVirtualAd && pVirtualAd->RtmpDev)
1599 pAdapter = pVirtualAd->RtmpDev->priv;
1600 }
1601
1602 if (pAdapter == NULL)
1603 {
1604 /* if 1st open fail, pAd will be free;
1605 So the net_dev->priv will be NULL in 2rd open */
1606 return -ENETDOWN;
1607 }
1608
1609 //check if the interface is down
1610 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1611 {
1612 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1613 return -ENETDOWN;
1614 }
1615
1616 rts->value = pAdapter->CommonCfg.RtsThreshold;
1617 rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
1618 rts->fixed = 1;
1619
1620 return 0;
1621}
1622
1623int rt_ioctl_siwfrag(struct net_device *dev,
1624 struct iw_request_info *info,
1625 struct iw_param *frag, char *extra)
1626{
1627 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1628 u16 val;
1629
1630 //check if the interface is down
1631 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1632 {
1633 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1634 return -ENETDOWN;
1635 }
1636
1637 if (frag->disabled)
1638 val = MAX_FRAG_THRESHOLD;
1639 else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
1640 val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
1641 else if (frag->value == 0)
1642 val = MAX_FRAG_THRESHOLD;
1643 else
1644 return -EINVAL;
1645
1646 pAdapter->CommonCfg.FragmentThreshold = val;
1647 return 0;
1648}
1649
1650int rt_ioctl_giwfrag(struct net_device *dev,
1651 struct iw_request_info *info,
1652 struct iw_param *frag, char *extra)
1653{
1654 PRTMP_ADAPTER pAdapter = NULL;
1655 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1656
1657 if (dev->priv_flags == INT_MAIN)
1658 {
1659 pAdapter = dev->priv;
1660 }
1661 else
1662 {
1663 pVirtualAd = dev->priv;
1664 if (pVirtualAd && pVirtualAd->RtmpDev)
1665 pAdapter = pVirtualAd->RtmpDev->priv;
1666 }
1667
1668 if (pAdapter == NULL)
1669 {
1670 /* if 1st open fail, pAd will be free;
1671 So the net_dev->priv will be NULL in 2rd open */
1672 return -ENETDOWN;
1673 }
1674
1675 //check if the interface is down
1676 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1677 {
1678 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1679 return -ENETDOWN;
1680 }
1681
1682 frag->value = pAdapter->CommonCfg.FragmentThreshold;
1683 frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
1684 frag->fixed = 1;
1685
1686 return 0;
1687}
1688
1689#define MAX_WEP_KEY_SIZE 13
1690#define MIN_WEP_KEY_SIZE 5
1691int rt_ioctl_siwencode(struct net_device *dev,
1692 struct iw_request_info *info,
1693 struct iw_point *erq, char *extra)
1694{
1695 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1696
1697 //check if the interface is down
1698 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1699 {
1700 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1701 return -ENETDOWN;
1702 }
1703
1704 if ((erq->length == 0) &&
1705 (erq->flags & IW_ENCODE_DISABLED))
1706 {
1707 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1708 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1709 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1710 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1711 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1712 goto done;
1713 }
1714 else if ((erq->length == 0) &&
1715 (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN))
1716 {
1717 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1718 STA_PORT_SECURED(pAdapter);
1719 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1720 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1721 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1722 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1723 if (erq->flags & IW_ENCODE_RESTRICTED)
1724 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1725 else
1726 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1727 goto done;
1728 }
1729
1730 if (erq->length > 0)
1731 {
1732 int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
1733 /* Check the size of the key */
1734 if (erq->length > MAX_WEP_KEY_SIZE) {
1735 return -EINVAL;
1736 }
1737 /* Check key index */
1738 if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
1739 {
1740 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
1741 keyIdx, pAdapter->StaCfg.DefaultKeyId));
1742
1743 //Using default key
1744 keyIdx = pAdapter->StaCfg.DefaultKeyId;
1745 }
1746
1747 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
1748
1749 if (erq->length == MAX_WEP_KEY_SIZE)
1750 {
1751 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
1752 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
1753 }
1754 else if (erq->length == MIN_WEP_KEY_SIZE)
1755 {
1756 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
1757 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
1758 }
1759 else
1760 /* Disable the key */
1761 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
1762
1763 /* Check if the key is not marked as invalid */
1764 if(!(erq->flags & IW_ENCODE_NOKEY)) {
1765 /* Copy the key in the driver */
1766 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
1767 }
1768 }
1769 else
1770 {
1771 /* Do we want to just set the transmit key index ? */
1772 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
1773 if ((index >= 0) && (index < 4))
1774 {
1775 pAdapter->StaCfg.DefaultKeyId = index;
1776 }
1777 else
1778 /* Don't complain if only change the mode */
1779 if(!erq->flags & IW_ENCODE_MODE) {
1780 return -EINVAL;
1781 }
1782 }
1783
1784done:
1785 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
1786 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
1787 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
1788 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
1789 return 0;
1790}
1791
1792int
1793rt_ioctl_giwencode(struct net_device *dev,
1794 struct iw_request_info *info,
1795 struct iw_point *erq, char *key)
1796{
1797 int kid;
1798 PRTMP_ADAPTER pAdapter = NULL;
1799 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1800
1801 if (dev->priv_flags == INT_MAIN)
1802 {
1803 pAdapter = dev->priv;
1804 }
1805 else
1806 {
1807 pVirtualAd = dev->priv;
1808 if (pVirtualAd && pVirtualAd->RtmpDev)
1809 pAdapter = pVirtualAd->RtmpDev->priv;
1810 }
1811
1812 if (pAdapter == NULL)
1813 {
1814 /* if 1st open fail, pAd will be free;
1815 So the net_dev->priv will be NULL in 2rd open */
1816 return -ENETDOWN;
1817 }
1818
1819 //check if the interface is down
1820 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1821 {
1822 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1823 return -ENETDOWN;
1824 }
1825
1826 kid = erq->flags & IW_ENCODE_INDEX;
1827 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
1828
1829 if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
1830 {
1831 erq->length = 0;
1832 erq->flags = IW_ENCODE_DISABLED;
1833 }
1834 else if ((kid > 0) && (kid <=4))
1835 {
1836 // copy wep key
1837 erq->flags = kid ; /* NB: base 1 */
1838 if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
1839 erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
1840 memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
1841 //if ((kid == pAdapter->PortCfg.DefaultKeyId))
1842 //erq->flags |= IW_ENCODE_ENABLED; /* XXX */
1843 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1844 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1845 else
1846 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1847
1848 }
1849 else if (kid == 0)
1850 {
1851 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1852 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1853 else
1854 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1855 erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
1856 memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
1857 // copy default key ID
1858 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1859 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1860 else
1861 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1862 erq->flags = pAdapter->StaCfg.DefaultKeyId + 1; /* NB: base 1 */
1863 erq->flags |= IW_ENCODE_ENABLED; /* XXX */
1864 }
1865
1866 return 0;
1867
1868}
1869
1870static int
1871rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
1872 void *w, char *extra)
1873{
1874 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1875 PRTMP_ADAPTER pAdapter;
1876 POS_COOKIE pObj;
1877 char *this_char = extra;
1878 char *value;
1879 int Status=0;
1880
1881 if (dev->priv_flags == INT_MAIN)
1882 {
1883 pAdapter = dev->priv;
1884 }
1885 else
1886 {
1887 pVirtualAd = dev->priv;
1888 pAdapter = pVirtualAd->RtmpDev->priv;
1889 }
1890 pObj = (POS_COOKIE) pAdapter->OS_Cookie;
1891
1892 if (pAdapter == NULL)
1893 {
1894 /* if 1st open fail, pAd will be free;
1895 So the net_dev->priv will be NULL in 2rd open */
1896 return -ENETDOWN;
1897 }
1898
1899 {
1900 pObj->ioctl_if_type = INT_MAIN;
1901 pObj->ioctl_if = MAIN_MBSSID;
1902 }
1903
1904 //check if the interface is down
1905 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1906 {
1907 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1908 return -ENETDOWN;
1909 }
1910
1911 if (!*this_char)
1912 return -EINVAL;
1913
1914 if ((value = rtstrchr(this_char, '=')) != NULL)
1915 *value++ = 0;
1916
1917 if (!value)
1918 return -EINVAL;
1919
1920 // reject setting nothing besides ANY ssid(ssidLen=0)
1921 if (!*value && (strcmp(this_char, "SSID") != 0))
1922 return -EINVAL;
1923
1924 for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
1925 {
1926 if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
1927 {
1928 if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
1929 { //FALSE:Set private failed then return Invalid argument
1930 Status = -EINVAL;
1931 }
1932 break; //Exit for loop.
1933 }
1934 }
1935
1936 if(PRTMP_PRIVATE_SET_PROC->name == NULL)
1937 { //Not found argument
1938 Status = -EINVAL;
1939 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
1940 }
1941
1942 return Status;
1943}
1944
1945
1946static int
1947rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
1948 struct iw_point *wrq, char *extra)
1949{
1950 INT Status = 0;
1951 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
1952
1953 if (extra == NULL)
1954 {
1955 wrq->length = 0;
1956 return -EIO;
1957 }
1958
1959 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
1960 sprintf(extra, "\n\n");
1961
1962#ifdef RALINK_ATE
1963 if (ATE_ON(pAd))
1964 {
1965 sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->ate.TxDoneCount);
1966 //sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->ate.TxDoneCount);
1967 }
1968 else
1969#endif // RALINK_ATE //
1970 {
1971 sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
1972 sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1973 }
1974 sprintf(extra+strlen(extra), "Tx success after retry = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1975 sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
1976 sprintf(extra+strlen(extra), "RTS Success Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
1977 sprintf(extra+strlen(extra), "RTS Fail Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
1978
1979 sprintf(extra+strlen(extra), "Rx success = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
1980 sprintf(extra+strlen(extra), "Rx with CRC = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
1981 sprintf(extra+strlen(extra), "Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
1982 sprintf(extra+strlen(extra), "Rx duplicate frame = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
1983
1984 sprintf(extra+strlen(extra), "False CCA (one second) = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
1985#ifdef RALINK_ATE
1986 if (ATE_ON(pAd))
1987 {
1988 if (pAd->ate.RxAntennaSel == 0)
1989 {
1990 sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
1991 sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta));
1992 sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta));
1993 }
1994 else
1995 {
1996 sprintf(extra+strlen(extra), "RSSI = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
1997 }
1998 }
1999 else
2000#endif // RALINK_ATE //
2001 {
2002 sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
2003 sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
2004 sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
2005 }
2006#ifdef WPA_SUPPLICANT_SUPPORT
2007 sprintf(extra+strlen(extra), "WpaSupplicantUP = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
2008#endif // WPA_SUPPLICANT_SUPPORT //
2009
2010
2011 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2012 DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
2013
2014 return Status;
2015}
2016
2017#ifdef DOT11_N_SUPPORT
2018void getBaInfo(
2019 IN PRTMP_ADAPTER pAd,
2020 IN PUCHAR pOutBuf)
2021{
2022 INT i, j;
2023 BA_ORI_ENTRY *pOriBAEntry;
2024 BA_REC_ENTRY *pRecBAEntry;
2025
2026 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
2027 {
2028 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
2029 if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
2030 || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
2031 {
2032 sprintf(pOutBuf, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
2033 pOutBuf,
2034 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2035 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
2036
2037 sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
2038 for (j=0; j < NUM_OF_TID; j++)
2039 {
2040 if (pEntry->BARecWcidArray[j] != 0)
2041 {
2042 pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
2043 sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
2044 }
2045 }
2046 sprintf(pOutBuf, "%s\n", pOutBuf);
2047
2048 sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
2049 for (j=0; j < NUM_OF_TID; j++)
2050 {
2051 if (pEntry->BAOriWcidArray[j] != 0)
2052 {
2053 pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
2054 sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
2055 }
2056 }
2057 sprintf(pOutBuf, "%s\n\n", pOutBuf);
2058 }
2059 if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
2060 break;
2061 }
2062
2063 return;
2064}
2065#endif // DOT11_N_SUPPORT //
2066
2067static int
2068rt_private_show(struct net_device *dev, struct iw_request_info *info,
2069 struct iw_point *wrq, char *extra)
2070{
2071 INT Status = 0;
2072 VIRTUAL_ADAPTER *pVirtualAd = NULL;
2073 PRTMP_ADAPTER pAd;
2074 POS_COOKIE pObj;
2075 u32 subcmd = wrq->flags;
2076
2077 if (dev->priv_flags == INT_MAIN)
2078 pAd = dev->priv;
2079 else
2080 {
2081 pVirtualAd = dev->priv;
2082 pAd = pVirtualAd->RtmpDev->priv;
2083 }
2084 pObj = (POS_COOKIE) pAd->OS_Cookie;
2085
2086 if (pAd == NULL)
2087 {
2088 /* if 1st open fail, pAd will be free;
2089 So the net_dev->priv will be NULL in 2rd open */
2090 return -ENETDOWN;
2091 }
2092
2093 if (extra == NULL)
2094 {
2095 wrq->length = 0;
2096 return -EIO;
2097 }
2098 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2099
2100 {
2101 pObj->ioctl_if_type = INT_MAIN;
2102 pObj->ioctl_if = MAIN_MBSSID;
2103 }
2104
2105 switch(subcmd)
2106 {
2107
2108 case SHOW_CONN_STATUS:
2109 if (MONITOR_ON(pAd))
2110 {
2111#ifdef DOT11_N_SUPPORT
2112 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
2113 pAd->CommonCfg.RegTransmitSetting.field.BW)
2114 sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
2115 else
2116#endif // DOT11_N_SUPPORT //
2117 sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
2118 }
2119 else
2120 {
2121 if (pAd->IndicateMediaState == NdisMediaStateConnected)
2122 {
2123 if (INFRA_ON(pAd))
2124 {
2125 sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
2126 pAd->CommonCfg.Ssid,
2127 pAd->CommonCfg.Bssid[0],
2128 pAd->CommonCfg.Bssid[1],
2129 pAd->CommonCfg.Bssid[2],
2130 pAd->CommonCfg.Bssid[3],
2131 pAd->CommonCfg.Bssid[4],
2132 pAd->CommonCfg.Bssid[5]);
2133 DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
2134 }
2135 else if (ADHOC_ON(pAd))
2136 sprintf(extra, "Connected\n");
2137 }
2138 else
2139 {
2140 sprintf(extra, "Disconnected\n");
2141 DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
2142 }
2143 }
2144 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2145 break;
2146 case SHOW_DRVIER_VERION:
2147 sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
2148 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2149 break;
2150#ifdef DOT11_N_SUPPORT
2151 case SHOW_BA_INFO:
2152 getBaInfo(pAd, extra);
2153 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2154 break;
2155#endif // DOT11_N_SUPPORT //
2156 case SHOW_DESC_INFO:
2157 {
2158 Show_DescInfo_Proc(pAd, NULL);
2159 wrq->length = 0; // 1: size of '\0'
2160 }
2161 break;
2162 case RAIO_OFF:
2163 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2164 {
2165 sprintf(extra, "Scanning\n");
2166 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2167 break;
2168 }
2169 pAd->StaCfg.bSwRadio = FALSE;
2170 if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2171 {
2172 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2173 if (pAd->StaCfg.bRadio == FALSE)
2174 {
2175 MlmeRadioOff(pAd);
2176 // Update extra information
2177 pAd->ExtraInfo = SW_RADIO_OFF;
2178 }
2179 }
2180 sprintf(extra, "Radio Off\n");
2181 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2182 break;
2183 case RAIO_ON:
2184 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2185 {
2186 sprintf(extra, "Scanning\n");
2187 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2188 break;
2189 }
2190 pAd->StaCfg.bSwRadio = TRUE;
2191 //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2192 {
2193 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2194 if (pAd->StaCfg.bRadio == TRUE)
2195 {
2196 MlmeRadioOn(pAd);
2197 // Update extra information
2198 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
2199 }
2200 }
2201 sprintf(extra, "Radio On\n");
2202 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2203 break;
2204
2205
2206#ifdef QOS_DLS_SUPPORT
2207 case SHOW_DLS_ENTRY_INFO:
2208 {
2209 Set_DlsEntryInfo_Display_Proc(pAd, NULL);
2210 wrq->length = 0; // 1: size of '\0'
2211 }
2212 break;
2213#endif // QOS_DLS_SUPPORT //
2214
2215 case SHOW_CFG_VALUE:
2216 {
2217 Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
2218 if (Status == 0)
2219 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2220 }
2221 break;
2222 case SHOW_ADHOC_ENTRY_INFO:
2223 Show_Adhoc_MacTable_Proc(pAd, extra);
2224 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2225 break;
2226 default:
2227 DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __FUNCTION__, subcmd));
2228 break;
2229 }
2230
2231 return Status;
2232}
2233
2234#ifdef SIOCSIWMLME
2235int rt_ioctl_siwmlme(struct net_device *dev,
2236 struct iw_request_info *info,
2237 union iwreq_data *wrqu,
2238 char *extra)
2239{
2240 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2241 struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
2242 MLME_QUEUE_ELEM MsgElem;
2243 MLME_DISASSOC_REQ_STRUCT DisAssocReq;
2244 MLME_DEAUTH_REQ_STRUCT DeAuthReq;
2245
2246 DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
2247
2248 if (pMlme == NULL)
2249 return -EINVAL;
2250
2251 switch(pMlme->cmd)
2252 {
2253#ifdef IW_MLME_DEAUTH
2254 case IW_MLME_DEAUTH:
2255 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __FUNCTION__));
2256 COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
2257 DeAuthReq.Reason = pMlme->reason_code;
2258 MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
2259 NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
2260 MlmeDeauthReqAction(pAd, &MsgElem);
2261 if (INFRA_ON(pAd))
2262 {
2263 LinkDown(pAd, FALSE);
2264 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
2265 }
2266 break;
2267#endif // IW_MLME_DEAUTH //
2268#ifdef IW_MLME_DISASSOC
2269 case IW_MLME_DISASSOC:
2270 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __FUNCTION__));
2271 COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
2272 DisAssocReq.Reason = pMlme->reason_code;
2273
2274 MsgElem.Machine = ASSOC_STATE_MACHINE;
2275 MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
2276 MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
2277 NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
2278
2279 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
2280 MlmeDisassocReqAction(pAd, &MsgElem);
2281 break;
2282#endif // IW_MLME_DISASSOC //
2283 default:
2284 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __FUNCTION__));
2285 break;
2286 }
2287
2288 return 0;
2289}
2290#endif // SIOCSIWMLME //
2291
2292#if WIRELESS_EXT > 17
2293int rt_ioctl_siwauth(struct net_device *dev,
2294 struct iw_request_info *info,
2295 union iwreq_data *wrqu, char *extra)
2296{
2297 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2298 struct iw_param *param = &wrqu->param;
2299
2300 //check if the interface is down
2301 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2302 {
2303 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2304 return -ENETDOWN;
2305 }
2306 switch (param->flags & IW_AUTH_INDEX) {
2307 case IW_AUTH_WPA_VERSION:
2308 if (param->value == IW_AUTH_WPA_VERSION_WPA)
2309 {
2310 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
2311 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
2312 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
2313 }
2314 else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
2315 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
2316
2317 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
2318 break;
2319 case IW_AUTH_CIPHER_PAIRWISE:
2320 if (param->value == IW_AUTH_CIPHER_NONE)
2321 {
2322 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
2323 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2324 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
2325 }
2326 else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2327 param->value == IW_AUTH_CIPHER_WEP104)
2328 {
2329 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
2330 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2331 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
2332#ifdef WPA_SUPPLICANT_SUPPORT
2333 pAdapter->StaCfg.IEEE8021X = FALSE;
2334#endif // WPA_SUPPLICANT_SUPPORT //
2335 }
2336 else if (param->value == IW_AUTH_CIPHER_TKIP)
2337 {
2338 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
2339 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2340 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2341 }
2342 else if (param->value == IW_AUTH_CIPHER_CCMP)
2343 {
2344 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
2345 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2346 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
2347 }
2348 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __FUNCTION__, param->value));
2349 break;
2350 case IW_AUTH_CIPHER_GROUP:
2351 if (param->value == IW_AUTH_CIPHER_NONE)
2352 {
2353 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
2354 }
2355 else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2356 param->value == IW_AUTH_CIPHER_WEP104)
2357 {
2358 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
2359 }
2360 else if (param->value == IW_AUTH_CIPHER_TKIP)
2361 {
2362 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
2363 }
2364 else if (param->value == IW_AUTH_CIPHER_CCMP)
2365 {
2366 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
2367 }
2368 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __FUNCTION__, param->value));
2369 break;
2370 case IW_AUTH_KEY_MGMT:
2371 if (param->value == IW_AUTH_KEY_MGMT_802_1X)
2372 {
2373 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
2374 {
2375 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
2376#ifdef WPA_SUPPLICANT_SUPPORT
2377 pAdapter->StaCfg.IEEE8021X = FALSE;
2378#endif // WPA_SUPPLICANT_SUPPORT //
2379 }
2380 else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
2381 {
2382 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
2383#ifdef WPA_SUPPLICANT_SUPPORT
2384 pAdapter->StaCfg.IEEE8021X = FALSE;
2385#endif // WPA_SUPPLICANT_SUPPORT //
2386 }
2387#ifdef WPA_SUPPLICANT_SUPPORT
2388 else
2389 // WEP 1x
2390 pAdapter->StaCfg.IEEE8021X = TRUE;
2391#endif // WPA_SUPPLICANT_SUPPORT //
2392 }
2393 else if (param->value == 0)
2394 {
2395 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2396 STA_PORT_SECURED(pAdapter);
2397 }
2398 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __FUNCTION__, param->value));
2399 break;
2400 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2401 break;
2402 case IW_AUTH_PRIVACY_INVOKED:
2403 /*if (param->value == 0)
2404 {
2405 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2406 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
2407 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2408 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
2409 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
2410 }*/
2411 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __FUNCTION__, param->value));
2412 break;
2413 case IW_AUTH_DROP_UNENCRYPTED:
2414 if (param->value != 0)
2415 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2416 else
2417 {
2418 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2419 STA_PORT_SECURED(pAdapter);
2420 }
2421 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
2422 break;
2423 case IW_AUTH_80211_AUTH_ALG:
2424 if (param->value & IW_AUTH_ALG_SHARED_KEY)
2425 {
2426 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
2427 }
2428 else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
2429 {
2430 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2431 }
2432 else
2433 return -EINVAL;
2434 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __FUNCTION__, param->value));
2435 break;
2436 case IW_AUTH_WPA_ENABLED:
2437 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __FUNCTION__, param->value));
2438 break;
2439 default:
2440 return -EOPNOTSUPP;
2441}
2442
2443 return 0;
2444}
2445
2446int rt_ioctl_giwauth(struct net_device *dev,
2447 struct iw_request_info *info,
2448 union iwreq_data *wrqu, char *extra)
2449{
2450 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2451 struct iw_param *param = &wrqu->param;
2452
2453 //check if the interface is down
2454 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2455 {
2456 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2457 return -ENETDOWN;
2458 }
2459
2460 switch (param->flags & IW_AUTH_INDEX) {
2461 case IW_AUTH_DROP_UNENCRYPTED:
2462 param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
2463 break;
2464
2465 case IW_AUTH_80211_AUTH_ALG:
2466 param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
2467 break;
2468
2469 case IW_AUTH_WPA_ENABLED:
2470 param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
2471 break;
2472
2473 default:
2474 return -EOPNOTSUPP;
2475 }
2476 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
2477 return 0;
2478}
2479
2480void fnSetCipherKey(
2481 IN PRTMP_ADAPTER pAdapter,
2482 IN INT keyIdx,
2483 IN UCHAR CipherAlg,
2484 IN BOOLEAN bGTK,
2485 IN struct iw_encode_ext *ext)
2486{
2487 NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2488 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
2489 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
2490 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
2491 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
2492 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
2493
2494 // Update group key information to ASIC Shared Key Table
2495 AsicAddSharedKeyEntry(pAdapter,
2496 BSS0,
2497 keyIdx,
2498 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2499 pAdapter->SharedKey[BSS0][keyIdx].Key,
2500 pAdapter->SharedKey[BSS0][keyIdx].TxMic,
2501 pAdapter->SharedKey[BSS0][keyIdx].RxMic);
2502
2503 if (bGTK)
2504 // Update ASIC WCID attribute table and IVEIV table
2505 RTMPAddWcidAttributeEntry(pAdapter,
2506 BSS0,
2507 keyIdx,
2508 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2509 NULL);
2510 else
2511 // Update ASIC WCID attribute table and IVEIV table
2512 RTMPAddWcidAttributeEntry(pAdapter,
2513 BSS0,
2514 keyIdx,
2515 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2516 &pAdapter->MacTab.Content[BSSID_WCID]);
2517}
2518
2519int rt_ioctl_siwencodeext(struct net_device *dev,
2520 struct iw_request_info *info,
2521 union iwreq_data *wrqu,
2522 char *extra)
2523 {
2524 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2525 struct iw_point *encoding = &wrqu->encoding;
2526 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2527 int keyIdx, alg = ext->alg;
2528
2529 //check if the interface is down
2530 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2531 {
2532 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2533 return -ENETDOWN;
2534 }
2535
2536 if (encoding->flags & IW_ENCODE_DISABLED)
2537 {
2538 keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2539 // set BSSID wcid entry of the Pair-wise Key table as no-security mode
2540 AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
2541 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
2542 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
2543 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
2544 NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2545 DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __FUNCTION__, encoding->flags));
2546 }
2547 else
2548 {
2549 // Get Key Index and convet to our own defined key index
2550 keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2551 if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
2552 return -EINVAL;
2553
2554 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2555 {
2556 pAdapter->StaCfg.DefaultKeyId = keyIdx;
2557 DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __FUNCTION__, pAdapter->StaCfg.DefaultKeyId));
2558 }
2559
2560 switch (alg) {
2561 case IW_ENCODE_ALG_NONE:
2562 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __FUNCTION__));
2563 break;
2564 case IW_ENCODE_ALG_WEP:
2565 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __FUNCTION__, ext->key_len, keyIdx));
2566 if (ext->key_len == MAX_WEP_KEY_SIZE)
2567 {
2568 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
2569 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
2570 }
2571 else if (ext->key_len == MIN_WEP_KEY_SIZE)
2572 {
2573 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
2574 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
2575 }
2576 else
2577 return -EINVAL;
2578
2579 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
2580 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
2581 break;
2582 case IW_ENCODE_ALG_TKIP:
2583 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __FUNCTION__, keyIdx, ext->key_len));
2584 if (ext->key_len == 32)
2585 {
2586 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2587 {
2588 fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
2589 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2590 {
2591 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2592 STA_PORT_SECURED(pAdapter);
2593 }
2594 }
2595 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2596 {
2597 fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
2598
2599 // set 802.1x port control
2600 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2601 STA_PORT_SECURED(pAdapter);
2602 }
2603 }
2604 else
2605 return -EINVAL;
2606 break;
2607 case IW_ENCODE_ALG_CCMP:
2608 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2609 {
2610 fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
2611 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2612 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2613 STA_PORT_SECURED(pAdapter);
2614 }
2615 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2616 {
2617 fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
2618
2619 // set 802.1x port control
2620 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2621 STA_PORT_SECURED(pAdapter);
2622 }
2623 break;
2624 default:
2625 return -EINVAL;
2626 }
2627 }
2628
2629 return 0;
2630}
2631
2632int
2633rt_ioctl_giwencodeext(struct net_device *dev,
2634 struct iw_request_info *info,
2635 union iwreq_data *wrqu, char *extra)
2636{
2637 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2638 PCHAR pKey = NULL;
2639 struct iw_point *encoding = &wrqu->encoding;
2640 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2641 int idx, max_key_len;
2642
2643 DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
2644
2645 max_key_len = encoding->length - sizeof(*ext);
2646 if (max_key_len < 0)
2647 return -EINVAL;
2648
2649 idx = encoding->flags & IW_ENCODE_INDEX;
2650 if (idx)
2651 {
2652 if (idx < 1 || idx > 4)
2653 return -EINVAL;
2654 idx--;
2655
2656 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2657 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
2658 {
2659 if (idx != pAd->StaCfg.DefaultKeyId)
2660 {
2661 ext->key_len = 0;
2662 return 0;
2663 }
2664 }
2665 }
2666 else
2667 idx = pAd->StaCfg.DefaultKeyId;
2668
2669 encoding->flags = idx + 1;
2670 memset(ext, 0, sizeof(*ext));
2671
2672 ext->key_len = 0;
2673 switch(pAd->StaCfg.WepStatus) {
2674 case Ndis802_11WEPDisabled:
2675 ext->alg = IW_ENCODE_ALG_NONE;
2676 encoding->flags |= IW_ENCODE_DISABLED;
2677 break;
2678 case Ndis802_11WEPEnabled:
2679 ext->alg = IW_ENCODE_ALG_WEP;
2680 if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
2681 return -E2BIG;
2682 else
2683 {
2684 ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
2685 pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
2686 }
2687 break;
2688 case Ndis802_11Encryption2Enabled:
2689 case Ndis802_11Encryption3Enabled:
2690 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2691 ext->alg = IW_ENCODE_ALG_TKIP;
2692 else
2693 ext->alg = IW_ENCODE_ALG_CCMP;
2694
2695 if (max_key_len < 32)
2696 return -E2BIG;
2697 else
2698 {
2699 ext->key_len = 32;
2700 pKey = &pAd->StaCfg.PMK[0];
2701 }
2702 break;
2703 default:
2704 return -EINVAL;
2705 }
2706
2707 if (ext->key_len && pKey)
2708 {
2709 encoding->flags |= IW_ENCODE_ENABLED;
2710 memcpy(ext->key, pKey, ext->key_len);
2711 }
2712
2713 return 0;
2714}
2715
2716#ifdef SIOCSIWGENIE
2717int rt_ioctl_siwgenie(struct net_device *dev,
2718 struct iw_request_info *info,
2719 union iwreq_data *wrqu, char *extra)
2720{
2721 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2722
2723 if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
2724 (wrqu->data.length && extra == NULL))
2725 return -EINVAL;
2726
2727 if (wrqu->data.length)
2728 {
2729 pAd->StaCfg.RSNIE_Len = wrqu->data.length;
2730 NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
2731 }
2732 else
2733 {
2734 pAd->StaCfg.RSNIE_Len = 0;
2735 NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
2736 }
2737
2738 return 0;
2739}
2740#endif // SIOCSIWGENIE //
2741
2742int rt_ioctl_giwgenie(struct net_device *dev,
2743 struct iw_request_info *info,
2744 union iwreq_data *wrqu, char *extra)
2745{
2746 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2747
2748 if ((pAd->StaCfg.RSNIE_Len == 0) ||
2749 (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
2750 {
2751 wrqu->data.length = 0;
2752 return 0;
2753 }
2754
2755#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2756#ifdef SIOCSIWGENIE
2757 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
2758 {
2759 if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
2760 return -E2BIG;
2761
2762 wrqu->data.length = pAd->StaCfg.RSNIE_Len;
2763 memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2764 }
2765 else
2766#endif // SIOCSIWGENIE //
2767#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2768 {
2769 UCHAR RSNIe = IE_WPA;
2770
2771 if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
2772 return -E2BIG;
2773 wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
2774
2775 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
2776 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
2777 RSNIe = IE_RSN;
2778
2779 extra[0] = (char)RSNIe;
2780 extra[1] = pAd->StaCfg.RSNIE_Len;
2781 memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2782 }
2783
2784 return 0;
2785}
2786
2787int rt_ioctl_siwpmksa(struct net_device *dev,
2788 struct iw_request_info *info,
2789 union iwreq_data *wrqu,
2790 char *extra)
2791{
2792 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2793 struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
2794 INT CachedIdx = 0, idx = 0;
2795
2796 if (pPmksa == NULL)
2797 return -EINVAL;
2798
2799 DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
2800 switch(pPmksa->cmd)
2801 {
2802 case IW_PMKSA_FLUSH:
2803 NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
2804 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
2805 break;
2806 case IW_PMKSA_REMOVE:
2807 for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2808 {
2809 // compare the BSSID
2810 if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2811 {
2812 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
2813 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
2814 for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
2815 {
2816 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
2817 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
2818 }
2819 pAd->StaCfg.SavedPMKNum--;
2820 break;
2821 }
2822 }
2823
2824 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
2825 break;
2826 case IW_PMKSA_ADD:
2827 for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2828 {
2829 // compare the BSSID
2830 if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2831 break;
2832 }
2833
2834 // Found, replace it
2835 if (CachedIdx < PMKID_NO)
2836 {
2837 DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2838 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2839 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2840 pAd->StaCfg.SavedPMKNum++;
2841 }
2842 // Not found, replace the last one
2843 else
2844 {
2845 // Randomly replace one
2846 CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
2847 DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2848 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2849 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2850 }
2851
2852 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
2853 break;
2854 default:
2855 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
2856 break;
2857 }
2858
2859 return 0;
2860}
2861#endif // #if WIRELESS_EXT > 17
2862
2863#ifdef DBG
2864static int
2865rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info,
2866 struct iw_point *wrq, char *extra)
2867 {
2868 CHAR *this_char;
2869 CHAR *value = NULL;
2870 UCHAR regBBP = 0;
2871// CHAR arg[255]={0};
2872 UINT32 bbpId;
2873 UINT32 bbpValue;
2874 BOOLEAN bIsPrintAllBBP = FALSE;
2875 INT Status = 0;
2876 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2877
2878
2879 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2880
2881 if (wrq->length > 1) //No parameters.
2882 {
2883 sprintf(extra, "\n");
2884
2885 //Parsing Read or Write
2886 this_char = wrq->pointer;
2887 DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char));
2888 if (!*this_char)
2889 goto next;
2890
2891 if ((value = rtstrchr(this_char, '=')) != NULL)
2892 *value++ = 0;
2893
2894 if (!value || !*value)
2895 { //Read
2896 DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value));
2897 if (sscanf(this_char, "%d", &(bbpId)) == 1)
2898 {
2899 if (bbpId <= 136)
2900 {
2901#ifdef RALINK_ATE
2902 if (ATE_ON(pAdapter))
2903 {
2904 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2905 }
2906 else
2907#endif // RALINK_ATE //
2908 {
2909 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2910 }
2911 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2912 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2913 DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2914 }
2915 else
2916 {//Invalid parametes, so default printk all bbp
2917 bIsPrintAllBBP = TRUE;
2918 goto next;
2919 }
2920 }
2921 else
2922 { //Invalid parametes, so default printk all bbp
2923 bIsPrintAllBBP = TRUE;
2924 goto next;
2925 }
2926 }
2927 else
2928 { //Write
2929 if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1))
2930 {
2931 if (bbpId <= 136)
2932 {
2933#ifdef RALINK_ATE
2934 if (ATE_ON(pAdapter))
2935 {
2936 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2937 //Read it back for showing
2938 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2939 }
2940 else
2941#endif // RALINK_ATE //
2942 {
2943 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2944 //Read it back for showing
2945 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2946 }
2947 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2948 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2949 DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2950 }
2951 else
2952 {//Invalid parametes, so default printk all bbp
2953 bIsPrintAllBBP = TRUE;
2954 goto next;
2955 }
2956 }
2957 else
2958 { //Invalid parametes, so default printk all bbp
2959 bIsPrintAllBBP = TRUE;
2960 goto next;
2961 }
2962 }
2963 }
2964 else
2965 bIsPrintAllBBP = TRUE;
2966
2967next:
2968 if (bIsPrintAllBBP)
2969 {
2970 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2971 sprintf(extra, "\n");
2972 for (bbpId = 0; bbpId <= 136; bbpId++)
2973 {
2974 if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 10))
2975 break;
2976#ifdef RALINK_ATE
2977 if (ATE_ON(pAdapter))
2978 {
2979 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2980 }
2981 else
2982#endif // RALINK_ATE //
2983 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2984 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X ", bbpId, bbpId*2, regBBP);
2985 if (bbpId%5 == 4)
2986 sprintf(extra+strlen(extra), "\n");
2987 }
2988
2989 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2990 DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->length));
2991 }
2992
2993 DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n"));
2994
2995 return Status;
2996}
2997#endif // DBG //
2998
2999int rt_ioctl_siwrate(struct net_device *dev,
3000 struct iw_request_info *info,
3001 union iwreq_data *wrqu, char *extra)
3002{
3003 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
3004 UINT32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
3005
3006 //check if the interface is down
3007 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3008 {
3009 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
3010 return -ENETDOWN;
3011 }
3012
3013 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
3014 /* rate = -1 => auto rate
3015 rate = X, fixed = 1 => (fixed rate X)
3016 */
3017 if (rate == -1)
3018 {
3019 //Auto Rate
3020 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3021 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
3022 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
3023 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
3024 RTMPSetDesiredRates(pAd, -1);
3025
3026#ifdef DOT11_N_SUPPORT
3027 SetCommonHT(pAd);
3028#endif // DOT11_N_SUPPORT //
3029 }
3030 else
3031 {
3032 if (fixed)
3033 {
3034 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
3035 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
3036 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
3037 RTMPSetDesiredRates(pAd, rate);
3038 else
3039 {
3040 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3041#ifdef DOT11_N_SUPPORT
3042 SetCommonHT(pAd);
3043#endif // DOT11_N_SUPPORT //
3044 }
3045 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
3046 }
3047 else
3048 {
3049 // TODO: rate = X, fixed = 0 => (rates <= X)
3050 return -EOPNOTSUPP;
3051 }
3052 }
3053
3054 return 0;
3055}
3056
3057int rt_ioctl_giwrate(struct net_device *dev,
3058 struct iw_request_info *info,
3059 union iwreq_data *wrqu, char *extra)
3060{
3061 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
3062 int rate_index = 0, rate_count = 0;
3063 HTTRANSMIT_SETTING ht_setting;
3064 __s32 ralinkrate[] =
3065 {2, 4, 11, 22, // CCK
3066 12, 18, 24, 36, 48, 72, 96, 108, // OFDM
3067 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
3068 39, 78, 117, 156, 234, 312, 351, 390, // 20MHz, 800ns GI, MCS: 16 ~ 23
3069 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
3070 81, 162, 243, 324, 486, 648, 729, 810, // 40MHz, 800ns GI, MCS: 16 ~ 23
3071 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
3072 43, 87, 130, 173, 260, 317, 390, 433, // 20MHz, 400ns GI, MCS: 16 ~ 23
3073 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
3074 90, 180, 270, 360, 540, 720, 810, 900}; // 40MHz, 400ns GI, MCS: 16 ~ 23
3075
3076 rate_count = sizeof(ralinkrate)/sizeof(__s32);
3077 //check if the interface is down
3078 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3079 {
3080 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
3081 return -ENETDOWN;
3082 }
3083
3084 if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
3085 (INFRA_ON(pAd)) &&
3086 ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
3087 ht_setting.word = pAd->StaCfg.HTPhyMode.word;
3088 else
3089 ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
3090
3091#ifdef DOT11_N_SUPPORT
3092 if (ht_setting.field.MODE >= MODE_HTMIX)
3093 {
3094// rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS);
3095 rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
3096 }
3097 else
3098#endif // DOT11_N_SUPPORT //
3099 if (ht_setting.field.MODE == MODE_OFDM)
3100 rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
3101 else if (ht_setting.field.MODE == MODE_CCK)
3102 rate_index = (UCHAR)(ht_setting.field.MCS);
3103
3104 if (rate_index < 0)
3105 rate_index = 0;
3106
3107 if (rate_index > rate_count)
3108 rate_index = rate_count;
3109
3110 wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
3111 wrqu->bitrate.disabled = 0;
3112
3113 return 0;
3114}
3115
3116static const iw_handler rt_handler[] =
3117{
3118 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3119 (iw_handler) rt_ioctl_giwname, /* SIOCGIWNAME */
3120 (iw_handler) NULL, /* SIOCSIWNWID */
3121 (iw_handler) NULL, /* SIOCGIWNWID */
3122 (iw_handler) rt_ioctl_siwfreq, /* SIOCSIWFREQ */
3123 (iw_handler) rt_ioctl_giwfreq, /* SIOCGIWFREQ */
3124 (iw_handler) rt_ioctl_siwmode, /* SIOCSIWMODE */
3125 (iw_handler) rt_ioctl_giwmode, /* SIOCGIWMODE */
3126 (iw_handler) NULL, /* SIOCSIWSENS */
3127 (iw_handler) NULL, /* SIOCGIWSENS */
3128 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
3129 (iw_handler) rt_ioctl_giwrange, /* SIOCGIWRANGE */
3130 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
3131 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
3132 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
3133 (iw_handler) rt28xx_get_wireless_stats /* kernel code */, /* SIOCGIWSTATS */
3134 (iw_handler) NULL, /* SIOCSIWSPY */
3135 (iw_handler) NULL, /* SIOCGIWSPY */
3136 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3137 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3138 (iw_handler) rt_ioctl_siwap, /* SIOCSIWAP */
3139 (iw_handler) rt_ioctl_giwap, /* SIOCGIWAP */
3140#ifdef SIOCSIWMLME
3141 (iw_handler) rt_ioctl_siwmlme, /* SIOCSIWMLME */
3142#else
3143 (iw_handler) NULL, /* SIOCSIWMLME */
3144#endif // SIOCSIWMLME //
3145 (iw_handler) rt_ioctl_iwaplist, /* SIOCGIWAPLIST */
3146#ifdef SIOCGIWSCAN
3147 (iw_handler) rt_ioctl_siwscan, /* SIOCSIWSCAN */
3148 (iw_handler) rt_ioctl_giwscan, /* SIOCGIWSCAN */
3149#else
3150 (iw_handler) NULL, /* SIOCSIWSCAN */
3151 (iw_handler) NULL, /* SIOCGIWSCAN */
3152#endif /* SIOCGIWSCAN */
3153 (iw_handler) rt_ioctl_siwessid, /* SIOCSIWESSID */
3154 (iw_handler) rt_ioctl_giwessid, /* SIOCGIWESSID */
3155 (iw_handler) rt_ioctl_siwnickn, /* SIOCSIWNICKN */
3156 (iw_handler) rt_ioctl_giwnickn, /* SIOCGIWNICKN */
3157 (iw_handler) NULL, /* -- hole -- */
3158 (iw_handler) NULL, /* -- hole -- */
3159 (iw_handler) rt_ioctl_siwrate, /* SIOCSIWRATE */
3160 (iw_handler) rt_ioctl_giwrate, /* SIOCGIWRATE */
3161 (iw_handler) rt_ioctl_siwrts, /* SIOCSIWRTS */
3162 (iw_handler) rt_ioctl_giwrts, /* SIOCGIWRTS */
3163 (iw_handler) rt_ioctl_siwfrag, /* SIOCSIWFRAG */
3164 (iw_handler) rt_ioctl_giwfrag, /* SIOCGIWFRAG */
3165 (iw_handler) NULL, /* SIOCSIWTXPOW */
3166 (iw_handler) NULL, /* SIOCGIWTXPOW */
3167 (iw_handler) NULL, /* SIOCSIWRETRY */
3168 (iw_handler) NULL, /* SIOCGIWRETRY */
3169 (iw_handler) rt_ioctl_siwencode, /* SIOCSIWENCODE */
3170 (iw_handler) rt_ioctl_giwencode, /* SIOCGIWENCODE */
3171 (iw_handler) NULL, /* SIOCSIWPOWER */
3172 (iw_handler) NULL, /* SIOCGIWPOWER */
3173 (iw_handler) NULL, /* -- hole -- */
3174 (iw_handler) NULL, /* -- hole -- */
3175#if WIRELESS_EXT > 17
3176 (iw_handler) rt_ioctl_siwgenie, /* SIOCSIWGENIE */
3177 (iw_handler) rt_ioctl_giwgenie, /* SIOCGIWGENIE */
3178 (iw_handler) rt_ioctl_siwauth, /* SIOCSIWAUTH */
3179 (iw_handler) rt_ioctl_giwauth, /* SIOCGIWAUTH */
3180 (iw_handler) rt_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
3181 (iw_handler) rt_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
3182 (iw_handler) rt_ioctl_siwpmksa, /* SIOCSIWPMKSA */
3183#endif
3184};
3185
3186static const iw_handler rt_priv_handlers[] = {
3187 (iw_handler) NULL, /* + 0x00 */
3188 (iw_handler) NULL, /* + 0x01 */
3189#ifndef CONFIG_AP_SUPPORT
3190 (iw_handler) rt_ioctl_setparam, /* + 0x02 */
3191#else
3192 (iw_handler) NULL, /* + 0x02 */
3193#endif // CONFIG_AP_SUPPORT //
3194#ifdef DBG
3195 (iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
3196#else
3197 (iw_handler) NULL, /* + 0x03 */
3198#endif
3199 (iw_handler) NULL, /* + 0x04 */
3200 (iw_handler) NULL, /* + 0x05 */
3201 (iw_handler) NULL, /* + 0x06 */
3202 (iw_handler) NULL, /* + 0x07 */
3203 (iw_handler) NULL, /* + 0x08 */
3204 (iw_handler) rt_private_get_statistics, /* + 0x09 */
3205 (iw_handler) NULL, /* + 0x0A */
3206 (iw_handler) NULL, /* + 0x0B */
3207 (iw_handler) NULL, /* + 0x0C */
3208 (iw_handler) NULL, /* + 0x0D */
3209 (iw_handler) NULL, /* + 0x0E */
3210 (iw_handler) NULL, /* + 0x0F */
3211 (iw_handler) NULL, /* + 0x10 */
3212 (iw_handler) rt_private_show, /* + 0x11 */
3213 (iw_handler) NULL, /* + 0x12 */
3214 (iw_handler) NULL, /* + 0x13 */
3215 (iw_handler) NULL, /* + 0x15 */
3216 (iw_handler) NULL, /* + 0x17 */
3217 (iw_handler) NULL, /* + 0x18 */
3218};
3219
3220const struct iw_handler_def rt28xx_iw_handler_def =
3221{
3222#define N(a) (sizeof (a) / sizeof (a[0]))
3223 .standard = (iw_handler *) rt_handler,
3224 .num_standard = sizeof(rt_handler) / sizeof(iw_handler),
3225 .private = (iw_handler *) rt_priv_handlers,
3226 .num_private = N(rt_priv_handlers),
3227 .private_args = (struct iw_priv_args *) privtab,
3228 .num_private_args = N(privtab),
3229#if IW_HANDLER_VERSION >= 7
3230 .get_wireless_stats = rt28xx_get_wireless_stats,
3231#endif
3232};
3233
3234INT RTMPSetInformation(
3235 IN PRTMP_ADAPTER pAdapter,
3236 IN OUT struct ifreq *rq,
3237 IN INT cmd)
3238{
3239 struct iwreq *wrq = (struct iwreq *) rq;
3240 NDIS_802_11_SSID Ssid;
3241 NDIS_802_11_MAC_ADDRESS Bssid;
3242 RT_802_11_PHY_MODE PhyMode;
3243 RT_802_11_STA_CONFIG StaConfig;
3244 NDIS_802_11_RATES aryRates;
3245 RT_802_11_PREAMBLE Preamble;
3246 NDIS_802_11_WEP_STATUS WepStatus;
3247 NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeMax;
3248 NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
3249 NDIS_802_11_RTS_THRESHOLD RtsThresh;
3250 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
3251 NDIS_802_11_POWER_MODE PowerMode;
3252 PNDIS_802_11_KEY pKey = NULL;
3253 PNDIS_802_11_WEP pWepKey =NULL;
3254 PNDIS_802_11_REMOVE_KEY pRemoveKey = NULL;
3255 NDIS_802_11_CONFIGURATION Config, *pConfig = NULL;
3256 NDIS_802_11_NETWORK_TYPE NetType;
3257 ULONG Now;
3258 UINT KeyIdx = 0;
3259 INT Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
3260 ULONG PowerTemp;
3261 BOOLEAN RadioState;
3262 BOOLEAN StateMachineTouched = FALSE;
3263#ifdef DOT11_N_SUPPORT
3264 OID_SET_HT_PHYMODE HT_PhyMode; //11n ,kathy
3265#endif // DOT11_N_SUPPORT //
3266#ifdef WPA_SUPPLICANT_SUPPORT
3267 PNDIS_802_11_PMKID pPmkId = NULL;
3268 BOOLEAN IEEE8021xState = FALSE;
3269 BOOLEAN IEEE8021x_required_keys = FALSE;
3270 UCHAR wpa_supplicant_enable = 0;
3271#endif // WPA_SUPPLICANT_SUPPORT //
3272
3273#ifdef SNMP_SUPPORT
3274 TX_RTY_CFG_STRUC tx_rty_cfg;
3275 ULONG ShortRetryLimit, LongRetryLimit;
3276 UCHAR ctmp;
3277#endif // SNMP_SUPPORT //
3278
3279
3280
3281#ifdef DOT11_N_SUPPORT
3282 MaxPhyMode = PHY_11N_5G;
3283#endif // DOT11_N_SUPPORT //
3284
3285
3286 DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(), 0x%08x\n", cmd&0x7FFF));
3287 switch(cmd & 0x7FFF) {
3288 case RT_OID_802_11_COUNTRY_REGION:
3289 if (wrq->u.data.length < sizeof(UCHAR))
3290 Status = -EINVAL;
3291 // Only avaliable when EEPROM not programming
3292 else if (!(pAdapter->CommonCfg.CountryRegion & 0x80) && !(pAdapter->CommonCfg.CountryRegionForABand & 0x80))
3293 {
3294 ULONG Country;
3295 UCHAR TmpPhy;
3296
3297 Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
3298 pAdapter->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
3299 pAdapter->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
3300 TmpPhy = pAdapter->CommonCfg.PhyMode;
3301 pAdapter->CommonCfg.PhyMode = 0xff;
3302 // Build all corresponding channel information
3303 RTMPSetPhyMode(pAdapter, TmpPhy);
3304#ifdef DOT11_N_SUPPORT
3305 SetCommonHT(pAdapter);
3306#endif // DOT11_N_SUPPORT //
3307 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d B/G:%d)\n", pAdapter->CommonCfg.CountryRegionForABand,
3308 pAdapter->CommonCfg.CountryRegion));
3309 }
3310 break;
3311 case OID_802_11_BSSID_LIST_SCAN:
3312 #ifdef RALINK_ATE
3313 if (ATE_ON(pAdapter))
3314 {
3315 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3316 break;
3317 }
3318#endif // RALINK_ATE //
3319 Now = jiffies;
3320 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAdapter->RalinkCounters.LastOneSecTotalTxCount));
3321
3322 if (MONITOR_ON(pAdapter))
3323 {
3324 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
3325 break;
3326 }
3327
3328 //Benson add 20080527, when radio off, sta don't need to scan
3329 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
3330 break;
3331
3332 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
3333 {
3334 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
3335 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3336 Status = NDIS_STATUS_SUCCESS;
3337 break;
3338 }
3339
3340 if (pAdapter->RalinkCounters.LastOneSecTotalTxCount > 100)
3341 {
3342 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3343 Status = NDIS_STATUS_SUCCESS;
3344 pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
3345 break;
3346 }
3347
3348 if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
3349 ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
3350 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3351 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
3352 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
3353 (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
3354 {
3355 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3356 Status = NDIS_STATUS_SUCCESS;
3357 pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
3358 break;
3359 }
3360
3361
3362 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3363 {
3364 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3365 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3366 }
3367
3368 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3369 // this request, because this request is initiated by NDIS.
3370 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3371 // Reset allowed scan retries
3372 pAdapter->StaCfg.ScanCnt = 0;
3373 pAdapter->StaCfg.LastScanTime = Now;
3374
3375 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3376 RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3377 MlmeEnqueue(pAdapter,
3378 MLME_CNTL_STATE_MACHINE,
3379 OID_802_11_BSSID_LIST_SCAN,
3380 0,
3381 NULL);
3382
3383 Status = NDIS_STATUS_SUCCESS;
3384 StateMachineTouched = TRUE;
3385 break;
3386 case OID_802_11_SSID:
3387 if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
3388 Status = -EINVAL;
3389 else
3390 {
3391 PCHAR pSsidString = NULL;
3392 Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
3393
3394 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
3395 if (Ssid.SsidLength > MAX_LEN_OF_SSID)
3396 Status = -EINVAL;
3397 else
3398 {
3399 if (Ssid.SsidLength == 0)
3400 {
3401 Set_SSID_Proc(pAdapter, "");
3402 }
3403 else
3404 {
3405 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
3406 if (pSsidString)
3407 {
3408 NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
3409 NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
3410 Set_SSID_Proc(pAdapter, pSsidString);
3411 kfree(pSsidString);
3412 }
3413 else
3414 Status = -ENOMEM;
3415 }
3416 }
3417 }
3418 break;
3419 case OID_802_11_BSSID:
3420#ifdef RALINK_ATE
3421 if (ATE_ON(pAdapter))
3422 {
3423 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3424 break;
3425 }
3426#endif // RALINK_ATE //
3427 if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
3428 Status = -EINVAL;
3429 else
3430 {
3431 Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
3432
3433 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3434 // this request, because this request is initiated by NDIS.
3435 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3436
3437 // Prevent to connect AP again in STAMlmePeriodicExec
3438 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3439
3440 // Reset allowed scan retries
3441 pAdapter->StaCfg.ScanCnt = 0;
3442
3443 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3444 {
3445 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3446 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3447 }
3448 MlmeEnqueue(pAdapter,
3449 MLME_CNTL_STATE_MACHINE,
3450 OID_802_11_BSSID,
3451 sizeof(NDIS_802_11_MAC_ADDRESS),
3452 (VOID *)&Bssid);
3453 Status = NDIS_STATUS_SUCCESS;
3454 StateMachineTouched = TRUE;
3455
3456 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
3457 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
3458 }
3459 break;
3460 case RT_OID_802_11_RADIO:
3461 if (wrq->u.data.length != sizeof(BOOLEAN))
3462 Status = -EINVAL;
3463 else
3464 {
3465 Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
3466 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
3467 if (pAdapter->StaCfg.bSwRadio != RadioState)
3468 {
3469 pAdapter->StaCfg.bSwRadio = RadioState;
3470 if (pAdapter->StaCfg.bRadio != (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio))
3471 {
3472 pAdapter->StaCfg.bRadio = (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio);
3473 if (pAdapter->StaCfg.bRadio == TRUE)
3474 {
3475 MlmeRadioOn(pAdapter);
3476 // Update extra information
3477 pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;
3478 }
3479 else
3480 {
3481 MlmeRadioOff(pAdapter);
3482 // Update extra information
3483 pAdapter->ExtraInfo = SW_RADIO_OFF;
3484 }
3485 }
3486 }
3487 }
3488 break;
3489 case RT_OID_802_11_PHY_MODE:
3490 if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
3491 Status = -EINVAL;
3492 else
3493 {
3494 Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3495 if (PhyMode <= MaxPhyMode)
3496 {
3497 RTMPSetPhyMode(pAdapter, PhyMode);
3498#ifdef DOT11_N_SUPPORT
3499 SetCommonHT(pAdapter);
3500#endif // DOT11_N_SUPPORT //
3501 }
3502 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
3503 }
3504 break;
3505 case RT_OID_802_11_STA_CONFIG:
3506 if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
3507 Status = -EINVAL;
3508 else
3509 {
3510 Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
3511 pAdapter->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
3512 pAdapter->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
3513 pAdapter->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
3514 if ((pAdapter->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
3515 (StaConfig.AdhocMode <= MaxPhyMode))
3516 {
3517 // allow dynamic change of "USE OFDM rate or not" in ADHOC mode
3518 // if setting changed, need to reset current TX rate as well as BEACON frame format
3519 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
3520 {
3521 pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
3522 RTMPSetPhyMode(pAdapter, PhyMode);
3523 MlmeUpdateTxRates(pAdapter, FALSE, 0);
3524 MakeIbssBeacon(pAdapter); // re-build BEACON frame
3525 AsicEnableIbssSync(pAdapter); // copy to on-chip memory
3526 }
3527 }
3528 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
3529 pAdapter->CommonCfg.bEnableTxBurst,
3530 pAdapter->CommonCfg.UseBGProtection,
3531 pAdapter->CommonCfg.bUseShortSlotTime));
3532 }
3533 break;
3534 case OID_802_11_DESIRED_RATES:
3535 if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
3536 Status = -EINVAL;
3537 else
3538 {
3539 Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
3540 NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
3541 NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
3542 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
3543 pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
3544 pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
3545 pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
3546 pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
3547 // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
3548 MlmeUpdateTxRates(pAdapter, FALSE, 0);
3549 }
3550 break;
3551 case RT_OID_802_11_PREAMBLE:
3552 if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
3553 Status = -EINVAL;
3554 else
3555 {
3556 Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
3557 if (Preamble == Rt802_11PreambleShort)
3558 {
3559 pAdapter->CommonCfg.TxPreamble = Preamble;
3560 MlmeSetTxPreamble(pAdapter, Rt802_11PreambleShort);
3561 }
3562 else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
3563 {
3564 // if user wants AUTO, initialize to LONG here, then change according to AP's
3565 // capability upon association.
3566 pAdapter->CommonCfg.TxPreamble = Preamble;
3567 MlmeSetTxPreamble(pAdapter, Rt802_11PreambleLong);
3568 }
3569 else
3570 {
3571 Status = -EINVAL;
3572 break;
3573 }
3574 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
3575 }
3576 break;
3577 case OID_802_11_WEP_STATUS:
3578 if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
3579 Status = -EINVAL;
3580 else
3581 {
3582 Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
3583 // Since TKIP, AES, WEP are all supported. It should not have any invalid setting
3584 if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
3585 {
3586 if (pAdapter->StaCfg.WepStatus != WepStatus)
3587 {
3588 // Config has changed
3589 pAdapter->bConfigChanged = TRUE;
3590 }
3591 pAdapter->StaCfg.WepStatus = WepStatus;
3592 pAdapter->StaCfg.OrigWepStatus = WepStatus;
3593 pAdapter->StaCfg.PairCipher = WepStatus;
3594 pAdapter->StaCfg.GroupCipher = WepStatus;
3595 }
3596 else
3597 {
3598 Status = -EINVAL;
3599 break;
3600 }
3601 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
3602 }
3603 break;
3604 case OID_802_11_AUTHENTICATION_MODE:
3605 if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
3606 Status = -EINVAL;
3607 else
3608 {
3609 Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
3610 if (AuthMode > Ndis802_11AuthModeMax)
3611 {
3612 Status = -EINVAL;
3613 break;
3614 }
3615 else
3616 {
3617 if (pAdapter->StaCfg.AuthMode != AuthMode)
3618 {
3619 // Config has changed
3620 pAdapter->bConfigChanged = TRUE;
3621 }
3622 pAdapter->StaCfg.AuthMode = AuthMode;
3623 }
3624 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3625 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAdapter->StaCfg.AuthMode));
3626 }
3627 break;
3628 case OID_802_11_INFRASTRUCTURE_MODE:
3629 if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
3630 Status = -EINVAL;
3631 else
3632 {
3633 Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
3634
3635 if (BssType == Ndis802_11IBSS)
3636 Set_NetworkType_Proc(pAdapter, "Adhoc");
3637 else if (BssType == Ndis802_11Infrastructure)
3638 Set_NetworkType_Proc(pAdapter, "Infra");
3639 else if (BssType == Ndis802_11Monitor)
3640 Set_NetworkType_Proc(pAdapter, "Monitor");
3641 else
3642 {
3643 Status = -EINVAL;
3644 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
3645 }
3646 }
3647 break;
3648 case OID_802_11_REMOVE_WEP:
3649 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
3650 if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
3651 {
3652 Status = -EINVAL;
3653 }
3654 else
3655 {
3656 KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
3657
3658 if (KeyIdx & 0x80000000)
3659 {
3660 // Should never set default bit when remove key
3661 Status = -EINVAL;
3662 }
3663 else
3664 {
3665 KeyIdx = KeyIdx & 0x0fffffff;
3666 if (KeyIdx >= 4){
3667 Status = -EINVAL;
3668 }
3669 else
3670 {
3671 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3672 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3673 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3674 }
3675 }
3676 }
3677 break;
3678 case RT_OID_802_11_RESET_COUNTERS:
3679 NdisZeroMemory(&pAdapter->WlanCounters, sizeof(COUNTER_802_11));
3680 NdisZeroMemory(&pAdapter->Counters8023, sizeof(COUNTER_802_3));
3681 NdisZeroMemory(&pAdapter->RalinkCounters, sizeof(COUNTER_RALINK));
3682 pAdapter->Counters8023.RxNoBuffer = 0;
3683 pAdapter->Counters8023.GoodReceives = 0;
3684 pAdapter->Counters8023.RxNoBuffer = 0;
3685#ifdef RT2870
3686 pAdapter->BulkOutComplete = 0;
3687 pAdapter->BulkOutCompleteOther= 0;
3688 pAdapter->BulkOutCompleteCancel = 0;
3689 pAdapter->BulkOutReq = 0;
3690 pAdapter->BulkInReq= 0;
3691 pAdapter->BulkInComplete = 0;
3692 pAdapter->BulkInCompleteFail = 0;
3693#endif // RT2870 //
3694 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
3695 break;
3696 case OID_802_11_RTS_THRESHOLD:
3697 if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
3698 Status = -EINVAL;
3699 else
3700 {
3701 Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
3702 if (RtsThresh > MAX_RTS_THRESHOLD)
3703 Status = -EINVAL;
3704 else
3705 pAdapter->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
3706 }
3707 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
3708 break;
3709 case OID_802_11_FRAGMENTATION_THRESHOLD:
3710 if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
3711 Status = -EINVAL;
3712 else
3713 {
3714 Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
3715 pAdapter->CommonCfg.bUseZeroToDisableFragment = FALSE;
3716 if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
3717 {
3718 if (FragThresh == 0)
3719 {
3720 pAdapter->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
3721 pAdapter->CommonCfg.bUseZeroToDisableFragment = TRUE;
3722 }
3723 else
3724 Status = -EINVAL;
3725 }
3726 else
3727 pAdapter->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
3728 }
3729 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
3730 break;
3731 case OID_802_11_POWER_MODE:
3732 if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
3733 Status = -EINVAL;
3734 else
3735 {
3736 Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
3737 if (PowerMode == Ndis802_11PowerModeCAM)
3738 Set_PSMode_Proc(pAdapter, "CAM");
3739 else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
3740 Set_PSMode_Proc(pAdapter, "Max_PSP");
3741 else if (PowerMode == Ndis802_11PowerModeFast_PSP)
3742 Set_PSMode_Proc(pAdapter, "Fast_PSP");
3743 else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
3744 Set_PSMode_Proc(pAdapter, "Legacy_PSP");
3745 else
3746 Status = -EINVAL;
3747 }
3748 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
3749 break;
3750 case RT_OID_802_11_TX_POWER_LEVEL_1:
3751 if (wrq->u.data.length < sizeof(ULONG))
3752 Status = -EINVAL;
3753 else
3754 {
3755 Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
3756 if (PowerTemp > 100)
3757 PowerTemp = 0xffffffff; // AUTO
3758 pAdapter->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
3759 pAdapter->CommonCfg.TxPowerPercentage = pAdapter->CommonCfg.TxPowerDefault;
3760 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
3761 }
3762 break;
3763 case OID_802_11_NETWORK_TYPE_IN_USE:
3764 if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
3765 Status = -EINVAL;
3766 else
3767 {
3768 Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
3769
3770 if (NetType == Ndis802_11DS)
3771 RTMPSetPhyMode(pAdapter, PHY_11B);
3772 else if (NetType == Ndis802_11OFDM24)
3773 RTMPSetPhyMode(pAdapter, PHY_11BG_MIXED);
3774 else if (NetType == Ndis802_11OFDM5)
3775 RTMPSetPhyMode(pAdapter, PHY_11A);
3776 else
3777 Status = -EINVAL;
3778#ifdef DOT11_N_SUPPORT
3779 if (Status == NDIS_STATUS_SUCCESS)
3780 SetCommonHT(pAdapter);
3781#endif // DOT11_N_SUPPORT //
3782 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
3783 }
3784 break;
3785 // For WPA PSK PMK key
3786 case RT_OID_802_11_ADD_WPA:
3787 pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3788 if(pKey == NULL)
3789 {
3790 Status = -ENOMEM;
3791 break;
3792 }
3793
3794 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3795 if (pKey->Length != wrq->u.data.length)
3796 {
3797 Status = -EINVAL;
3798 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
3799 }
3800 else
3801 {
3802 if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
3803 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
3804 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
3805 {
3806 Status = -EOPNOTSUPP;
3807 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
3808 }
3809 else if ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3810 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
3811 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) ) // Only for WPA PSK mode
3812 {
3813 NdisMoveMemory(pAdapter->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
3814 // Use RaConfig as PSK agent.
3815 // Start STA supplicant state machine
3816 if (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
3817 pAdapter->StaCfg.WpaState = SS_START;
3818
3819 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3820 }
3821 else
3822 {
3823 pAdapter->StaCfg.WpaState = SS_NOTUSE;
3824 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3825 }
3826 }
3827 kfree(pKey);
3828 break;
3829 case OID_802_11_REMOVE_KEY:
3830 pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3831 if(pRemoveKey == NULL)
3832 {
3833 Status = -ENOMEM;
3834 break;
3835 }
3836
3837 Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
3838 if (pRemoveKey->Length != wrq->u.data.length)
3839 {
3840 Status = -EINVAL;
3841 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
3842 }
3843 else
3844 {
3845 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3846 {
3847 RTMPWPARemoveKeyProc(pAdapter, pRemoveKey);
3848 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
3849 }
3850 else
3851 {
3852 KeyIdx = pRemoveKey->KeyIndex;
3853
3854 if (KeyIdx & 0x80000000)
3855 {
3856 // Should never set default bit when remove key
3857 Status = -EINVAL;
3858 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
3859 }
3860 else
3861 {
3862 KeyIdx = KeyIdx & 0x0fffffff;
3863 if (KeyIdx > 3)
3864 {
3865 Status = -EINVAL;
3866 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
3867 }
3868 else
3869 {
3870 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3871 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3872 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3873 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
3874 }
3875 }
3876 }
3877 }
3878 kfree(pRemoveKey);
3879 break;
3880 // New for WPA
3881 case OID_802_11_ADD_KEY:
3882 pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3883 if(pKey == NULL)
3884 {
3885 Status = -ENOMEM;
3886 break;
3887 }
3888 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3889 if (pKey->Length != wrq->u.data.length)
3890 {
3891 Status = -EINVAL;
3892 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
3893 }
3894 else
3895 {
3896 RTMPAddKey(pAdapter, pKey);
3897 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3898 }
3899 kfree(pKey);
3900 break;
3901 case OID_802_11_CONFIGURATION:
3902 if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
3903 Status = -EINVAL;
3904 else
3905 {
3906 Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
3907 pConfig = &Config;
3908
3909 if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
3910 pAdapter->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
3911
3912 pAdapter->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
3913 MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAdapter->CommonCfg.Channel);
3914 //
3915 // Save the channel on MlmeAux for CntlOidRTBssidProc used.
3916 //
3917 pAdapter->MlmeAux.Channel = pAdapter->CommonCfg.Channel;
3918
3919 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
3920 pConfig->BeaconPeriod, pConfig->ATIMWindow, pAdapter->CommonCfg.Channel));
3921 // Config has changed
3922 pAdapter->bConfigChanged = TRUE;
3923 }
3924 break;
3925#ifdef DOT11_N_SUPPORT
3926 case RT_OID_802_11_SET_HT_PHYMODE:
3927 if (wrq->u.data.length != sizeof(OID_SET_HT_PHYMODE))
3928 Status = -EINVAL;
3929 else
3930 {
3931 POID_SET_HT_PHYMODE pHTPhyMode = &HT_PhyMode;
3932
3933 Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3934 DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode (PhyMode = %d,TransmitNo = %d, HtMode = %d, ExtOffset = %d , MCS = %d, BW = %d, STBC = %d, SHORTGI = %d) \n",
3935 pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
3936 pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
3937 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
3938 RTMPSetHT(pAdapter, pHTPhyMode);
3939 }
3940 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
3941 pAdapter->StaCfg.HTPhyMode.field.MCS, pAdapter->StaCfg.HTPhyMode.field.BW, pAdapter->StaCfg.HTPhyMode.field.ShortGI,
3942 pAdapter->StaCfg.HTPhyMode.field.STBC));
3943 break;
3944#endif // DOT11_N_SUPPORT //
3945 case RT_OID_802_11_SET_APSD_SETTING:
3946 if (wrq->u.data.length != sizeof(ULONG))
3947 Status = -EINVAL;
3948 else
3949 {
3950 ULONG apsd ;
3951 Status = copy_from_user(&apsd, wrq->u.data.pointer, wrq->u.data.length);
3952
3953 /*-------------------------------------------------------------------
3954 |B31~B7 | B6~B5 | B4 | B3 | B2 | B1 | B0 |
3955 ---------------------------------------------------------------------
3956 | Rsvd | Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD Capable |
3957 ---------------------------------------------------------------------*/
3958 pAdapter->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE : FALSE;
3959 pAdapter->CommonCfg.bAPSDAC_BE = ((apsd & 0x00000002) >> 1) ? TRUE : FALSE;
3960 pAdapter->CommonCfg.bAPSDAC_BK = ((apsd & 0x00000004) >> 2) ? TRUE : FALSE;
3961 pAdapter->CommonCfg.bAPSDAC_VI = ((apsd & 0x00000008) >> 3) ? TRUE : FALSE;
3962 pAdapter->CommonCfg.bAPSDAC_VO = ((apsd & 0x00000010) >> 4) ? TRUE : FALSE;
3963 pAdapter->CommonCfg.MaxSPLength = (UCHAR)((apsd & 0x00000060) >> 5);
3964
3965 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,
3966 pAdapter->CommonCfg.bAPSDAC_BE, pAdapter->CommonCfg.bAPSDAC_BK, pAdapter->CommonCfg.bAPSDAC_VI, pAdapter->CommonCfg.bAPSDAC_VO, pAdapter->CommonCfg.MaxSPLength));
3967 }
3968 break;
3969
3970 case RT_OID_802_11_SET_APSD_PSM:
3971 if (wrq->u.data.length != sizeof(ULONG))
3972 Status = -EINVAL;
3973 else
3974 {
3975 // Driver needs to notify AP when PSM changes
3976 Status = copy_from_user(&pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
3977 if (pAdapter->CommonCfg.bAPSDForcePowerSave != pAdapter->StaCfg.Psm)
3978 {
3979 MlmeSetPsmBit(pAdapter, pAdapter->CommonCfg.bAPSDForcePowerSave);
3980 RTMPSendNullFrame(pAdapter, pAdapter->CommonCfg.TxRate, TRUE);
3981 }
3982 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
3983 }
3984 break;
3985#ifdef QOS_DLS_SUPPORT
3986 case RT_OID_802_11_SET_DLS:
3987 if (wrq->u.data.length != sizeof(ULONG))
3988 Status = -EINVAL;
3989 else
3990 {
3991 BOOLEAN oldvalue = pAdapter->CommonCfg.bDLSCapable;
3992 Status = copy_from_user(&pAdapter->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
3993 if (oldvalue && !pAdapter->CommonCfg.bDLSCapable)
3994 {
3995 int i;
3996 // tear down local dls table entry
3997 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
3998 {
3999 if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
4000 {
4001 pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
4002 pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
4003 RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
4004 }
4005 }
4006
4007 // tear down peer dls table entry
4008 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
4009 {
4010 if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
4011 {
4012 pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
4013 pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
4014 RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
4015 }
4016 }
4017 }
4018
4019 DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAdapter->CommonCfg.bDLSCapable));
4020 }
4021 break;
4022
4023 case RT_OID_802_11_SET_DLS_PARAM:
4024 if (wrq->u.data.length != sizeof(RT_802_11_DLS_UI))
4025 Status = -EINVAL;
4026 else
4027 {
4028 RT_802_11_DLS Dls;
4029
4030 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
4031 RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI));
4032 MlmeEnqueue(pAdapter,
4033 MLME_CNTL_STATE_MACHINE,
4034 RT_OID_802_11_SET_DLS_PARAM,
4035 sizeof(RT_802_11_DLS),
4036 &Dls);
4037 DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n"));
4038 }
4039 break;
4040#endif // QOS_DLS_SUPPORT //
4041 case RT_OID_802_11_SET_WMM:
4042 if (wrq->u.data.length != sizeof(BOOLEAN))
4043 Status = -EINVAL;
4044 else
4045 {
4046 Status = copy_from_user(&pAdapter->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
4047 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d) \n", pAdapter->CommonCfg.bWmmCapable));
4048 }
4049 break;
4050
4051 case OID_802_11_DISASSOCIATE:
4052#ifdef RALINK_ATE
4053 if (ATE_ON(pAdapter))
4054 {
4055 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4056 break;
4057 }
4058#endif // RALINK_ATE //
4059 //
4060 // Set NdisRadioStateOff to TRUE, instead of called MlmeRadioOff.
4061 // Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be 0
4062 // when query OID_802_11_BSSID_LIST.
4063 //
4064 // TRUE: NumberOfItems will set to 0.
4065 // FALSE: NumberOfItems no change.
4066 //
4067 pAdapter->CommonCfg.NdisRadioStateOff = TRUE;
4068 // Set to immediately send the media disconnect event
4069 pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
4070 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE \n"));
4071
4072 if (INFRA_ON(pAdapter))
4073 {
4074 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
4075 {
4076 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
4077 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
4078 }
4079
4080 MlmeEnqueue(pAdapter,
4081 MLME_CNTL_STATE_MACHINE,
4082 OID_802_11_DISASSOCIATE,
4083 0,
4084 NULL);
4085
4086 StateMachineTouched = TRUE;
4087 }
4088 break;
4089
4090#ifdef DOT11_N_SUPPORT
4091 case RT_OID_802_11_SET_IMME_BA_CAP:
4092 if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
4093 Status = -EINVAL;
4094 else
4095 {
4096 OID_BACAP_STRUC Orde ;
4097 Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
4098 if (Orde.Policy > BA_NOTUSE)
4099 {
4100 Status = NDIS_STATUS_INVALID_DATA;
4101 }
4102 else if (Orde.Policy == BA_NOTUSE)
4103 {
4104 pAdapter->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
4105 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4106 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4107 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4108 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4109 pAdapter->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
4110 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4111 // UPdata to HT IE
4112 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4113 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4114 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4115 }
4116 else
4117 {
4118 pAdapter->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
4119 pAdapter->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
4120 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4121 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4122 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4123 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4124 pAdapter->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
4125 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4126
4127 // UPdata to HT IE
4128 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4129 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4130 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4131
4132 if (pAdapter->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
4133 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
4134
4135 }
4136
4137 pAdapter->CommonCfg.REGBACapability.word = pAdapter->CommonCfg.BACapability.word;
4138 DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAdapter->CommonCfg.BACapability.field.Policy,
4139 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit,pAdapter->CommonCfg.BACapability.field.TxBAWinLimit, pAdapter->CommonCfg.BACapability.field.AutoBA));
4140 DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAdapter->CommonCfg.DesiredHtPhy.MimoPs, pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable,
4141 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize, pAdapter->CommonCfg.DesiredHtPhy.MpduDensity));
4142 }
4143
4144 break;
4145 case RT_OID_802_11_ADD_IMME_BA:
4146 DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
4147 if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4148 Status = -EINVAL;
4149 else
4150 {
4151 UCHAR index;
4152 OID_ADD_BA_ENTRY BA;
4153 MAC_TABLE_ENTRY *pEntry;
4154
4155 Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
4156 if (BA.TID > 15)
4157 {
4158 Status = NDIS_STATUS_INVALID_DATA;
4159 break;
4160 }
4161 else
4162 {
4163 //BATableInsertEntry
4164 //As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
4165 index = BA.TID;
4166 // in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
4167 pEntry = MacTableLookup(pAdapter, BA.MACAddr);
4168 if (!pEntry)
4169 {
4170 DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
4171 break;
4172 }
4173 if (BA.IsRecipient == FALSE)
4174 {
4175 if (pEntry->bIAmBadAtheros == TRUE)
4176 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
4177
4178 BAOriSessionSetUp(pAdapter, pEntry, index, 0, 100, TRUE);
4179 }
4180 else
4181 {
4182 //BATableInsertEntry(pAdapter, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
4183 }
4184
4185 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
4186 BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
4187 , BA.MACAddr[4], BA.MACAddr[5]));
4188 }
4189 }
4190 break;
4191
4192 case RT_OID_802_11_TEAR_IMME_BA:
4193 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
4194 if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4195 Status = -EINVAL;
4196 else
4197 {
4198 POID_ADD_BA_ENTRY pBA;
4199 MAC_TABLE_ENTRY *pEntry;
4200
4201 pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4202
4203 if (pBA == NULL)
4204 {
4205 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
4206 Status = NDIS_STATUS_FAILURE;
4207 }
4208 else
4209 {
4210 Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
4211 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
4212
4213 if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
4214 {
4215 Status = NDIS_STATUS_INVALID_DATA;
4216 break;
4217 }
4218
4219 if (pBA->IsRecipient == FALSE)
4220 {
4221 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4222 DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
4223 if (pEntry)
4224 {
4225 DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
4226 BAOriSessionTearDown(pAdapter, pEntry->Aid, pBA->TID, FALSE, TRUE);
4227 }
4228 else
4229 DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4230 }
4231 else
4232 {
4233 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4234 if (pEntry)
4235 {
4236 BARecSessionTearDown( pAdapter, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
4237 }
4238 else
4239 DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4240 }
4241 kfree(pBA);
4242 }
4243 }
4244 break;
4245#endif // DOT11_N_SUPPORT //
4246
4247 // For WPA_SUPPLICANT to set static wep key
4248 case OID_802_11_ADD_WEP:
4249 pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4250
4251 if(pWepKey == NULL)
4252 {
4253 Status = -ENOMEM;
4254 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
4255 break;
4256 }
4257 Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
4258 if (Status)
4259 {
4260 Status = -EINVAL;
4261 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
4262 }
4263 else
4264 {
4265 KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
4266 // KeyIdx must be 0 ~ 3
4267 if (KeyIdx > 4)
4268 {
4269 Status = -EINVAL;
4270 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
4271 }
4272 else
4273 {
4274 UCHAR CipherAlg = 0;
4275 PUCHAR Key;
4276
4277 // set key material and key length
4278 NdisZeroMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, 16);
4279 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4280 NdisMoveMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4281
4282 switch(pWepKey->KeyLength)
4283 {
4284 case 5:
4285 CipherAlg = CIPHER_WEP64;
4286 break;
4287 case 13:
4288 CipherAlg = CIPHER_WEP128;
4289 break;
4290 default:
4291 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
4292 Status = -EINVAL;
4293 break;
4294 }
4295 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
4296
4297 // Default key for tx (shared key)
4298 if (pWepKey->KeyIndex & 0x80000000)
4299 {
4300#ifdef WPA_SUPPLICANT_SUPPORT
4301 // set key material and key length
4302 NdisZeroMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
4303 pAdapter->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4304 NdisMoveMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4305 pAdapter->StaCfg.DesireSharedKeyId = KeyIdx;
4306 pAdapter->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
4307#endif // WPA_SUPPLICANT_SUPPORT //
4308 pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4309 }
4310
4311#ifdef WPA_SUPPLICANT_SUPPORT
4312 if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
4313#endif // WPA_SUPPLICANT_SUPPORT
4314 {
4315 Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
4316
4317 // Set key material and cipherAlg to Asic
4318 AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
4319
4320 if (pWepKey->KeyIndex & 0x80000000)
4321 {
4322 PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[BSSID_WCID];
4323 // Assign group key info
4324 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
4325 // Assign pairwise key info
4326 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, pEntry);
4327 }
4328 }
4329 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"));
4330 }
4331 }
4332 kfree(pWepKey);
4333 break;
4334#ifdef WPA_SUPPLICANT_SUPPORT
4335 case OID_SET_COUNTERMEASURES:
4336 if (wrq->u.data.length != sizeof(int))
4337 Status = -EINVAL;
4338 else
4339 {
4340 int enabled = 0;
4341 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4342 if (enabled == 1)
4343 pAdapter->StaCfg.bBlockAssoc = TRUE;
4344 else
4345 // WPA MIC error should block association attempt for 60 seconds
4346 pAdapter->StaCfg.bBlockAssoc = FALSE;
4347 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAdapter->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
4348 }
4349 break;
4350 case RT_OID_WPA_SUPPLICANT_SUPPORT:
4351 if (wrq->u.data.length != sizeof(UCHAR))
4352 Status = -EINVAL;
4353 else
4354 {
4355 Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
4356 pAdapter->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
4357 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
4358 }
4359 break;
4360 case OID_802_11_DEAUTHENTICATION:
4361 if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
4362 Status = -EINVAL;
4363 else
4364 {
4365 MLME_DEAUTH_REQ_STRUCT *pInfo;
4366 MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
4367
4368 pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
4369 Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
4370 MlmeDeauthReqAction(pAdapter, MsgElem);
4371 kfree(MsgElem);
4372
4373 if (INFRA_ON(pAdapter))
4374 {
4375 LinkDown(pAdapter, FALSE);
4376 pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
4377 }
4378 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
4379 }
4380 break;
4381 case OID_802_11_DROP_UNENCRYPTED:
4382 if (wrq->u.data.length != sizeof(int))
4383 Status = -EINVAL;
4384 else
4385 {
4386 int enabled = 0;
4387 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4388 if (enabled == 1)
4389 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
4390 else
4391 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
4392 NdisAcquireSpinLock(&pAdapter->MacTabLock);
4393 pAdapter->MacTab.Content[BSSID_WCID].PortSecured = pAdapter->StaCfg.PortSecured;
4394 NdisReleaseSpinLock(&pAdapter->MacTabLock);
4395 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
4396 }
4397 break;
4398 case OID_802_11_SET_IEEE8021X:
4399 if (wrq->u.data.length != sizeof(BOOLEAN))
4400 Status = -EINVAL;
4401 else
4402 {
4403 Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
4404 pAdapter->StaCfg.IEEE8021X = IEEE8021xState;
4405 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
4406 }
4407 break;
4408 case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
4409 if (wrq->u.data.length != sizeof(BOOLEAN))
4410 Status = -EINVAL;
4411 else
4412 {
4413 Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
4414 pAdapter->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
4415 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
4416 }
4417 break;
4418 case OID_802_11_PMKID:
4419 pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4420
4421 if(pPmkId == NULL) {
4422 Status = -ENOMEM;
4423 break;
4424 }
4425 Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
4426
4427 // check the PMKID information
4428 if (pPmkId->BSSIDInfoCount == 0)
4429 NdisZeroMemory(pAdapter->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
4430 else
4431 {
4432 PBSSID_INFO pBssIdInfo;
4433 UINT BssIdx;
4434 UINT CachedIdx;
4435
4436 for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
4437 {
4438 // point to the indexed BSSID_INFO structure
4439 pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
4440 // Find the entry in the saved data base.
4441 for (CachedIdx = 0; CachedIdx < pAdapter->StaCfg.SavedPMKNum; CachedIdx++)
4442 {
4443 // compare the BSSID
4444 if (NdisEqualMemory(pBssIdInfo->BSSID, pAdapter->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
4445 break;
4446 }
4447
4448 // Found, replace it
4449 if (CachedIdx < PMKID_NO)
4450 {
4451 DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4452 NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4453 pAdapter->StaCfg.SavedPMKNum++;
4454 }
4455 // Not found, replace the last one
4456 else
4457 {
4458 // Randomly replace one
4459 CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
4460 DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4461 NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4462 }
4463 }
4464 }
4465 if(pPmkId)
4466 kfree(pPmkId);
4467 break;
4468#endif // WPA_SUPPLICANT_SUPPORT //
4469
4470
4471
4472#ifdef SNMP_SUPPORT
4473 case OID_802_11_SHORTRETRYLIMIT:
4474 if (wrq->u.data.length != sizeof(ULONG))
4475 Status = -EINVAL;
4476 else
4477 {
4478 Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4479 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4480 tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
4481 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4482 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit));
4483 }
4484 break;
4485
4486 case OID_802_11_LONGRETRYLIMIT:
4487 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n"));
4488 if (wrq->u.data.length != sizeof(ULONG))
4489 Status = -EINVAL;
4490 else
4491 {
4492 Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4493 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4494 tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
4495 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4496 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit));
4497 }
4498 break;
4499
4500 case OID_802_11_WEPDEFAULTKEYVALUE:
4501 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n"));
4502 pKey = kmalloc(wrq->u.data.length, GFP_KERNEL);
4503 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
4504 //pKey = &WepKey;
4505
4506 if ( pKey->Length != wrq->u.data.length)
4507 {
4508 Status = -EINVAL;
4509 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n"));
4510 }
4511 KeyIdx = pKey->KeyIndex & 0x0fffffff;
4512 DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength));
4513
4514 // it is a shared key
4515 if (KeyIdx > 4)
4516 Status = -EINVAL;
4517 else
4518 {
4519 pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
4520 NdisMoveMemory(&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
4521 if (pKey->KeyIndex & 0x80000000)
4522 {
4523 // Default key for tx (shared key)
4524 pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4525 }
4526 //RestartAPIsRequired = TRUE;
4527 }
4528 break;
4529
4530
4531 case OID_802_11_WEPDEFAULTKEYID:
4532 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n"));
4533
4534 if (wrq->u.data.length != sizeof(UCHAR))
4535 Status = -EINVAL;
4536 else
4537 Status = copy_from_user(&pAdapter->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length);
4538
4539 break;
4540
4541
4542 case OID_802_11_CURRENTCHANNEL:
4543 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n"));
4544 if (wrq->u.data.length != sizeof(UCHAR))
4545 Status = -EINVAL;
4546 else
4547 {
4548 Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length);
4549 sprintf(&ctmp,"%d", ctmp);
4550 Set_Channel_Proc(pAdapter, &ctmp);
4551 }
4552 break;
4553#endif
4554
4555
4556
4557 default:
4558 DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
4559 Status = -EOPNOTSUPP;
4560 break;
4561 }
4562
4563
4564 return Status;
4565}
4566
4567INT RTMPQueryInformation(
4568 IN PRTMP_ADAPTER pAdapter,
4569 IN OUT struct ifreq *rq,
4570 IN INT cmd)
4571{
4572 struct iwreq *wrq = (struct iwreq *) rq;
4573 NDIS_802_11_BSSID_LIST_EX *pBssidList = NULL;
4574 PNDIS_WLAN_BSSID_EX pBss;
4575 NDIS_802_11_SSID Ssid;
4576 NDIS_802_11_CONFIGURATION *pConfiguration = NULL;
4577 RT_802_11_LINK_STATUS *pLinkStatus = NULL;
4578 RT_802_11_STA_CONFIG *pStaConfig = NULL;
4579 NDIS_802_11_STATISTICS *pStatistics = NULL;
4580 NDIS_802_11_RTS_THRESHOLD RtsThresh;
4581 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
4582 NDIS_802_11_POWER_MODE PowerMode;
4583 NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
4584 RT_802_11_PREAMBLE PreamType;
4585 NDIS_802_11_AUTHENTICATION_MODE AuthMode;
4586 NDIS_802_11_WEP_STATUS WepStatus;
4587 NDIS_MEDIA_STATE MediaState;
4588 ULONG BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
4589 USHORT BssLen = 0;
4590 PUCHAR pBuf = NULL, pPtr;
4591 INT Status = NDIS_STATUS_SUCCESS;
4592 UINT we_version_compiled;
4593 UCHAR i, Padding = 0;
4594 BOOLEAN RadioState;
4595 UCHAR driverVersion[8];
4596 OID_SET_HT_PHYMODE *pHTPhyMode = NULL;
4597
4598
4599#ifdef SNMP_SUPPORT
4600 //for snmp, kathy
4601 DefaultKeyIdxValue *pKeyIdxValue;
4602 INT valueLen;
4603 TX_RTY_CFG_STRUC tx_rty_cfg;
4604 ULONG ShortRetryLimit, LongRetryLimit;
4605 UCHAR tmp[64];
4606#endif //SNMP
4607
4608 switch(cmd)
4609 {
4610 case RT_OID_DEVICE_NAME:
4611 wrq->u.data.length = sizeof(STA_NIC_DEVICE_NAME);
4612 Status = copy_to_user(wrq->u.data.pointer, STA_NIC_DEVICE_NAME, wrq->u.data.length);
4613 break;
4614 case RT_OID_VERSION_INFO:
4615 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
4616 wrq->u.data.length = 8*sizeof(UCHAR);
4617 sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
4618 driverVersion[7] = '\0';
4619 if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
4620 {
4621 Status = -EFAULT;
4622 }
4623 break;
4624#ifdef RALINK_ATE
4625 case RT_QUERY_ATE_TXDONE_COUNT:
4626 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_QUERY_ATE_TXDONE_COUNT \n"));
4627 wrq->u.data.length = sizeof(UINT32);
4628 if (copy_to_user(wrq->u.data.pointer, &pAdapter->ate.TxDoneCount, wrq->u.data.length))
4629 {
4630 Status = -EFAULT;
4631 }
4632 break;
4633#endif // RALINK_ATE //
4634 case OID_802_11_BSSID_LIST:
4635 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
4636 {
4637 /*
4638 * Still scanning, indicate the caller should try again.
4639 */
4640 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
4641 return -EAGAIN;
4642 }
4643 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAdapter->ScanTab.BssNr));
4644 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
4645 // Claculate total buffer size required
4646 BssBufSize = sizeof(ULONG);
4647
4648 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4649 {
4650 // Align pointer to 4 bytes boundary.
4651 //Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
4652 //if (Padding == 4)
4653 // Padding = 0;
4654 BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4655 }
4656
4657 // For safety issue, we add 256 bytes just in case
4658 BssBufSize += 256;
4659 // Allocate the same size as passed from higher layer
4660 pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
4661 if(pBuf == NULL)
4662 {
4663 Status = -ENOMEM;
4664 break;
4665 }
4666 // Init 802_11_BSSID_LIST_EX structure
4667 NdisZeroMemory(pBuf, BssBufSize);
4668 pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
4669 pBssidList->NumberOfItems = pAdapter->ScanTab.BssNr;
4670
4671 // Calculate total buffer length
4672 BssLen = 4; // Consist of NumberOfItems
4673 // Point to start of NDIS_WLAN_BSSID_EX
4674 // pPtr = pBuf + sizeof(ULONG);
4675 pPtr = (PUCHAR) &pBssidList->Bssid[0];
4676 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4677 {
4678 pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
4679 NdisMoveMemory(&pBss->MacAddress, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
4680 if ((pAdapter->ScanTab.BssEntry[i].Hidden == 1) && (pAdapter->StaCfg.bShowHiddenSSID == FALSE))
4681 {
4682 //
4683 // We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
4684 // and then failed to send EAPOl farame.
4685 //
4686 if ((pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAdapter->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
4687 {
4688 pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4689 NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4690 }
4691 else
4692 pBss->Ssid.SsidLength = 0;
4693 }
4694 else
4695 {
4696 pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4697 NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4698 }
4699 pBss->Privacy = pAdapter->ScanTab.BssEntry[i].Privacy;
4700 pBss->Rssi = pAdapter->ScanTab.BssEntry[i].Rssi - pAdapter->BbpRssiToDbmDelta;
4701 pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
4702 pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
4703 pBss->Configuration.BeaconPeriod = pAdapter->ScanTab.BssEntry[i].BeaconPeriod;
4704 pBss->Configuration.ATIMWindow = pAdapter->ScanTab.BssEntry[i].AtimWin;
4705
4706 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
4707
4708 if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_INFRA)
4709 pBss->InfrastructureMode = Ndis802_11Infrastructure;
4710 else
4711 pBss->InfrastructureMode = Ndis802_11IBSS;
4712
4713 NdisMoveMemory(pBss->SupportedRates, pAdapter->ScanTab.BssEntry[i].SupRate, pAdapter->ScanTab.BssEntry[i].SupRateLen);
4714 NdisMoveMemory(pBss->SupportedRates + pAdapter->ScanTab.BssEntry[i].SupRateLen,
4715 pAdapter->ScanTab.BssEntry[i].ExtRate,
4716 pAdapter->ScanTab.BssEntry[i].ExtRateLen);
4717
4718 if (pAdapter->ScanTab.BssEntry[i].VarIELen == 0)
4719 {
4720 pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
4721 NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4722 pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4723 }
4724 else
4725 {
4726 pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen);
4727 pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4728 NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4729 NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAdapter->ScanTab.BssEntry[i].VarIEs, pAdapter->ScanTab.BssEntry[i].VarIELen);
4730 pPtr += pAdapter->ScanTab.BssEntry[i].VarIELen;
4731 }
4732 pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4733
4734#if WIRELESS_EXT < 17
4735 if ((BssLen + pBss->Length) < wrq->u.data.length)
4736 BssLen += pBss->Length;
4737 else
4738 {
4739 pBssidList->NumberOfItems = i;
4740 break;
4741 }
4742#else
4743 BssLen += pBss->Length;
4744#endif
4745 }
4746
4747#if WIRELESS_EXT < 17
4748 wrq->u.data.length = BssLen;
4749#else
4750 if (BssLen > wrq->u.data.length)
4751 {
4752 kfree(pBssidList);
4753 return -E2BIG;
4754 }
4755 else
4756 wrq->u.data.length = BssLen;
4757#endif
4758 Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
4759 kfree(pBssidList);
4760 break;
4761 case OID_802_3_CURRENT_ADDRESS:
4762 wrq->u.data.length = MAC_ADDR_LEN;
4763 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
4764 break;
4765 case OID_GEN_MEDIA_CONNECT_STATUS:
4766 if (pAdapter->IndicateMediaState == NdisMediaStateConnected)
4767 MediaState = NdisMediaStateConnected;
4768 else
4769 MediaState = NdisMediaStateDisconnected;
4770
4771 wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
4772 Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
4773 break;
4774 case OID_802_11_BSSID:
4775#ifdef RALINK_ATE
4776 if (ATE_ON(pAdapter))
4777 {
4778 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4779 Status = NDIS_STATUS_RESOURCES;
4780 break;
4781 }
4782#endif // RALINK_ATE //
4783 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
4784 {
4785 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
4786
4787 }
4788 else
4789 {
4790 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
4791 Status = -ENOTCONN;
4792 }
4793 break;
4794 case OID_802_11_SSID:
4795 NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
4796 NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
4797 Ssid.SsidLength = pAdapter->CommonCfg.SsidLen;
4798 memcpy(Ssid.Ssid, pAdapter->CommonCfg.Ssid, Ssid.SsidLength);
4799 wrq->u.data.length = sizeof(NDIS_802_11_SSID);
4800 Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
4801 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
4802 break;
4803 case RT_OID_802_11_QUERY_LINK_STATUS:
4804 pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
4805 if (pLinkStatus)
4806 {
4807 pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAdapter->CommonCfg.TxRate]; // unit : 500 kbps
4808 pLinkStatus->ChannelQuality = pAdapter->Mlme.ChannelQuality;
4809 pLinkStatus->RxByteCount = pAdapter->RalinkCounters.ReceivedByteCount;
4810 pLinkStatus->TxByteCount = pAdapter->RalinkCounters.TransmittedByteCount;
4811 pLinkStatus->CentralChannel = pAdapter->CommonCfg.CentralChannel;
4812 wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
4813 Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
4814 kfree(pLinkStatus);
4815 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
4816 }
4817 else
4818 {
4819 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
4820 Status = -EFAULT;
4821 }
4822 break;
4823 case OID_802_11_CONFIGURATION:
4824 pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
4825 if (pConfiguration)
4826 {
4827 pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
4828 pConfiguration->BeaconPeriod = pAdapter->CommonCfg.BeaconPeriod;
4829 pConfiguration->ATIMWindow = pAdapter->StaActive.AtimWin;
4830 MAP_CHANNEL_ID_TO_KHZ(pAdapter->CommonCfg.Channel, pConfiguration->DSConfig);
4831 wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
4832 Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
4833 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
4834 pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAdapter->CommonCfg.Channel));
4835 kfree(pConfiguration);
4836 }
4837 else
4838 {
4839 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
4840 Status = -EFAULT;
4841 }
4842 break;
4843 case RT_OID_802_11_SNR_0:
4844 if ((pAdapter->StaCfg.LastSNR0 > 0))
4845 {
4846 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR0) * 3) / 16 ;
4847 wrq->u.data.length = sizeof(ulInfo);
4848 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4849 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
4850 }
4851 else
4852 Status = -EFAULT;
4853 break;
4854 case RT_OID_802_11_SNR_1:
4855 if ((pAdapter->Antenna.field.RxPath > 1) &&
4856 (pAdapter->StaCfg.LastSNR1 > 0))
4857 {
4858 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR1) * 3) / 16 ;
4859 wrq->u.data.length = sizeof(ulInfo);
4860 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4861 DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
4862 }
4863 else
4864 Status = -EFAULT;
4865 DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAdapter->StaCfg.LastSNR1=%d)\n",pAdapter->StaCfg.LastSNR1));
4866 break;
4867 case OID_802_11_RSSI_TRIGGER:
4868 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0 - pAdapter->BbpRssiToDbmDelta;
4869 wrq->u.data.length = sizeof(ulInfo);
4870 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4871 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
4872 break;
4873 case OID_802_11_RSSI:
4874 case RT_OID_802_11_RSSI:
4875 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0;
4876 wrq->u.data.length = sizeof(ulInfo);
4877 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4878 break;
4879 case RT_OID_802_11_RSSI_1:
4880 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi1;
4881 wrq->u.data.length = sizeof(ulInfo);
4882 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4883 break;
4884 case RT_OID_802_11_RSSI_2:
4885 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi2;
4886 wrq->u.data.length = sizeof(ulInfo);
4887 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4888 break;
4889 case OID_802_11_STATISTICS:
4890 pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
4891 if (pStatistics)
4892 {
4893 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
4894 // add the most up-to-date h/w raw counters into software counters
4895 NICUpdateRawCounters(pAdapter);
4896
4897 // Sanity check for calculation of sucessful count
4898 if (pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart < pAdapter->WlanCounters.RetryCount.QuadPart)
4899 pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4900
4901 pStatistics->TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart;
4902 pStatistics->MulticastTransmittedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
4903 pStatistics->FailedCount.QuadPart = pAdapter->WlanCounters.FailedCount.QuadPart;
4904 pStatistics->RetryCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4905 pStatistics->MultipleRetryCount.QuadPart = pAdapter->WlanCounters.MultipleRetryCount.QuadPart;
4906 pStatistics->RTSSuccessCount.QuadPart = pAdapter->WlanCounters.RTSSuccessCount.QuadPart;
4907 pStatistics->RTSFailureCount.QuadPart = pAdapter->WlanCounters.RTSFailureCount.QuadPart;
4908 pStatistics->ACKFailureCount.QuadPart = pAdapter->WlanCounters.ACKFailureCount.QuadPart;
4909 pStatistics->FrameDuplicateCount.QuadPart = pAdapter->WlanCounters.FrameDuplicateCount.QuadPart;
4910 pStatistics->ReceivedFragmentCount.QuadPart = pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart;
4911 pStatistics->MulticastReceivedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastReceivedFrameCount.QuadPart;
4912#ifdef DBG
4913 pStatistics->FCSErrorCount = pAdapter->RalinkCounters.RealFcsErrCount;
4914#else
4915 pStatistics->FCSErrorCount.QuadPart = pAdapter->WlanCounters.FCSErrorCount.QuadPart;
4916 pStatistics->FrameDuplicateCount.u.LowPart = pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
4917#endif
4918 wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
4919 Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
4920 kfree(pStatistics);
4921 }
4922 else
4923 {
4924 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
4925 Status = -EFAULT;
4926 }
4927 break;
4928 case OID_GEN_RCV_OK:
4929 ulInfo = pAdapter->Counters8023.GoodReceives;
4930 wrq->u.data.length = sizeof(ulInfo);
4931 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4932 break;
4933 case OID_GEN_RCV_NO_BUFFER:
4934 ulInfo = pAdapter->Counters8023.RxNoBuffer;
4935 wrq->u.data.length = sizeof(ulInfo);
4936 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4937 break;
4938 case RT_OID_802_11_PHY_MODE:
4939 ulInfo = (ULONG)pAdapter->CommonCfg.PhyMode;
4940 wrq->u.data.length = sizeof(ulInfo);
4941 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4942 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo));
4943 break;
4944 case RT_OID_802_11_STA_CONFIG:
4945 pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
4946 if (pStaConfig)
4947 {
4948 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
4949 pStaConfig->EnableTxBurst = pAdapter->CommonCfg.bEnableTxBurst;
4950 pStaConfig->EnableTurboRate = 0;
4951 pStaConfig->UseBGProtection = pAdapter->CommonCfg.UseBGProtection;
4952 pStaConfig->UseShortSlotTime = pAdapter->CommonCfg.bUseShortSlotTime;
4953 //pStaConfig->AdhocMode = pAdapter->StaCfg.AdhocMode;
4954 pStaConfig->HwRadioStatus = (pAdapter->StaCfg.bHwRadio == TRUE) ? 1 : 0;
4955 pStaConfig->Rsv1 = 0;
4956 pStaConfig->SystemErrorBitmap = pAdapter->SystemErrorBitmap;
4957 wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
4958 Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
4959 kfree(pStaConfig);
4960 }
4961 else
4962 {
4963 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
4964 Status = -EFAULT;
4965 }
4966 break;
4967 case OID_802_11_RTS_THRESHOLD:
4968 RtsThresh = pAdapter->CommonCfg.RtsThreshold;
4969 wrq->u.data.length = sizeof(RtsThresh);
4970 Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
4971 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
4972 break;
4973 case OID_802_11_FRAGMENTATION_THRESHOLD:
4974 FragThresh = pAdapter->CommonCfg.FragmentThreshold;
4975 if (pAdapter->CommonCfg.bUseZeroToDisableFragment == TRUE)
4976 FragThresh = 0;
4977 wrq->u.data.length = sizeof(FragThresh);
4978 Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
4979 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
4980 break;
4981 case OID_802_11_POWER_MODE:
4982 PowerMode = pAdapter->StaCfg.WindowsPowerMode;
4983 wrq->u.data.length = sizeof(PowerMode);
4984 Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
4985 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
4986 break;
4987 case RT_OID_802_11_RADIO:
4988 RadioState = (BOOLEAN) pAdapter->StaCfg.bSwRadio;
4989 wrq->u.data.length = sizeof(RadioState);
4990 Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
4991 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
4992 break;
4993 case OID_802_11_INFRASTRUCTURE_MODE:
4994 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
4995 BssType = Ndis802_11IBSS;
4996 else if (pAdapter->StaCfg.BssType == BSS_INFRA)
4997 BssType = Ndis802_11Infrastructure;
4998 else if (pAdapter->StaCfg.BssType == BSS_MONITOR)
4999 BssType = Ndis802_11Monitor;
5000 else
5001 BssType = Ndis802_11AutoUnknown;
5002
5003 wrq->u.data.length = sizeof(BssType);
5004 Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
5005 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
5006 break;
5007 case RT_OID_802_11_PREAMBLE:
5008 PreamType = pAdapter->CommonCfg.TxPreamble;
5009 wrq->u.data.length = sizeof(PreamType);
5010 Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
5011 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
5012 break;
5013 case OID_802_11_AUTHENTICATION_MODE:
5014 AuthMode = pAdapter->StaCfg.AuthMode;
5015 wrq->u.data.length = sizeof(AuthMode);
5016 Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
5017 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
5018 break;
5019 case OID_802_11_WEP_STATUS:
5020 WepStatus = pAdapter->StaCfg.WepStatus;
5021 wrq->u.data.length = sizeof(WepStatus);
5022 Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
5023 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
5024 break;
5025 case OID_802_11_TX_POWER_LEVEL:
5026 wrq->u.data.length = sizeof(ULONG);
5027 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPower, wrq->u.data.length);
5028 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAdapter->CommonCfg.TxPower));
5029 break;
5030 case RT_OID_802_11_TX_POWER_LEVEL_1:
5031 wrq->u.data.length = sizeof(ULONG);
5032 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPowerPercentage, wrq->u.data.length);
5033 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
5034 break;
5035 case OID_802_11_NETWORK_TYPES_SUPPORTED:
5036 if ((pAdapter->RfIcType == RFIC_2850) || (pAdapter->RfIcType == RFIC_2750))
5037 {
5038 NetworkTypeList[0] = 3; // NumberOfItems = 3
5039 NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
5040 NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
5041 NetworkTypeList[3] = Ndis802_11OFDM5; // NetworkType[3] = 11a
5042 wrq->u.data.length = 16;
5043 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
5044 }
5045 else
5046 {
5047 NetworkTypeList[0] = 2; // NumberOfItems = 2
5048 NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
5049 NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
5050 wrq->u.data.length = 12;
5051 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
5052 }
5053 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
5054 break;
5055 case OID_802_11_NETWORK_TYPE_IN_USE:
5056 wrq->u.data.length = sizeof(ULONG);
5057 if (pAdapter->CommonCfg.PhyMode == PHY_11A)
5058 ulInfo = Ndis802_11OFDM5;
5059 else if ((pAdapter->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAdapter->CommonCfg.PhyMode == PHY_11G))
5060 ulInfo = Ndis802_11OFDM24;
5061 else
5062 ulInfo = Ndis802_11DS;
5063 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5064 break;
5065 case RT_OID_802_11_QUERY_LAST_RX_RATE:
5066 ulInfo = (ULONG)pAdapter->LastRxRate;
5067 wrq->u.data.length = sizeof(ulInfo);
5068 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5069 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
5070 break;
5071 case RT_OID_802_11_QUERY_LAST_TX_RATE:
5072 //ulInfo = (ULONG)pAdapter->LastTxRate;
5073 ulInfo = (ULONG)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word;
5074 wrq->u.data.length = sizeof(ulInfo);
5075 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5076 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
5077 break;
5078 case RT_OID_802_11_QUERY_EEPROM_VERSION:
5079 wrq->u.data.length = sizeof(ULONG);
5080 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->EepromVersion, wrq->u.data.length);
5081 break;
5082 case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
5083 wrq->u.data.length = sizeof(ULONG);
5084 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->FirmwareVersion, wrq->u.data.length);
5085 break;
5086 case RT_OID_802_11_QUERY_NOISE_LEVEL:
5087 wrq->u.data.length = sizeof(UCHAR);
5088 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->BbpWriteLatch[66], wrq->u.data.length);
5089 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAdapter->BbpWriteLatch[66]));
5090 break;
5091 case RT_OID_802_11_EXTRA_INFO:
5092 wrq->u.data.length = sizeof(ULONG);
5093 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->ExtraInfo, wrq->u.data.length);
5094 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAdapter->ExtraInfo));
5095 break;
5096 case RT_OID_WE_VERSION_COMPILED:
5097 wrq->u.data.length = sizeof(UINT);
5098 we_version_compiled = WIRELESS_EXT;
5099 Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
5100 break;
5101 case RT_OID_802_11_QUERY_APSD_SETTING:
5102 apsd = (pAdapter->CommonCfg.bAPSDCapable | (pAdapter->CommonCfg.bAPSDAC_BE << 1) | (pAdapter->CommonCfg.bAPSDAC_BK << 2)
5103 | (pAdapter->CommonCfg.bAPSDAC_VI << 3) | (pAdapter->CommonCfg.bAPSDAC_VO << 4) | (pAdapter->CommonCfg.MaxSPLength << 5));
5104
5105 wrq->u.data.length = sizeof(ULONG);
5106 Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
5107 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",
5108 apsd,pAdapter->CommonCfg.bAPSDCapable,pAdapter->CommonCfg.bAPSDAC_BE,pAdapter->CommonCfg.bAPSDAC_BK,pAdapter->CommonCfg.bAPSDAC_VI,pAdapter->CommonCfg.bAPSDAC_VO,pAdapter->CommonCfg.MaxSPLength));
5109 break;
5110 case RT_OID_802_11_QUERY_APSD_PSM:
5111 wrq->u.data.length = sizeof(ULONG);
5112 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
5113 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
5114 break;
5115 case RT_OID_802_11_QUERY_WMM:
5116 wrq->u.data.length = sizeof(BOOLEAN);
5117 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bWmmCapable, wrq->u.data.length);
5118 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n", pAdapter->CommonCfg.bWmmCapable));
5119 break;
5120#ifdef WPA_SUPPLICANT_SUPPORT
5121 case RT_OID_NEW_DRIVER:
5122 {
5123 UCHAR enabled = 1;
5124 wrq->u.data.length = sizeof(UCHAR);
5125 Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
5126 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
5127 }
5128 break;
5129 case RT_OID_WPA_SUPPLICANT_SUPPORT:
5130 wrq->u.data.length = sizeof(UCHAR);
5131 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.WpaSupplicantUP, wrq->u.data.length);
5132 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
5133 break;
5134#endif // WPA_SUPPLICANT_SUPPORT //
5135
5136 case RT_OID_DRIVER_DEVICE_NAME:
5137 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
5138 wrq->u.data.length = 16;
5139 if (copy_to_user(wrq->u.data.pointer, pAdapter->StaCfg.dev_name, wrq->u.data.length))
5140 {
5141 Status = -EFAULT;
5142 }
5143 break;
5144 case RT_OID_802_11_QUERY_HT_PHYMODE:
5145 pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5146 if (pHTPhyMode)
5147 {
5148 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5149 pHTPhyMode->HtMode = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
5150 pHTPhyMode->BW = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
5151 pHTPhyMode->MCS= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
5152 pHTPhyMode->SHORTGI= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
5153 pHTPhyMode->STBC= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
5154
5155 pHTPhyMode->ExtOffset = ((pAdapter->CommonCfg.CentralChannel < pAdapter->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
5156 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5157 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5158 {
5159 Status = -EFAULT;
5160 }
5161 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5162 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5163 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5164 }
5165 else
5166 {
5167 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5168 Status = -EFAULT;
5169 }
5170 break;
5171 case RT_OID_802_11_COUNTRY_REGION:
5172 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
5173 wrq->u.data.length = sizeof(ulInfo);
5174 ulInfo = pAdapter->CommonCfg.CountryRegionForABand;
5175 ulInfo = (ulInfo << 8)|(pAdapter->CommonCfg.CountryRegion);
5176 if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
5177 {
5178 Status = -EFAULT;
5179 }
5180 break;
5181 case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
5182 pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5183 if (pHTPhyMode)
5184 {
5185 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5186 pHTPhyMode->HtMode = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.HTMODE;
5187 pHTPhyMode->BW = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.BW;
5188 pHTPhyMode->MCS= (UCHAR)pAdapter->StaCfg.DesiredTransmitSetting.field.MCS;
5189 pHTPhyMode->SHORTGI= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.ShortGI;
5190 pHTPhyMode->STBC= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.STBC;
5191
5192 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5193 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5194 {
5195 Status = -EFAULT;
5196 }
5197 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5198 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5199 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5200 }
5201 else
5202 {
5203 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5204 Status = -EFAULT;
5205 }
5206 break;
5207 case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
5208 wrq->u.data.length = sizeof(UCHAR);
5209 i = 0;
5210#ifdef MULTIPLE_CARD_SUPPORT
5211 i = 1;
5212#endif // MULTIPLE_CARD_SUPPORT //
5213 if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
5214 {
5215 Status = -EFAULT;
5216 }
5217 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
5218 break;
5219#ifdef SNMP_SUPPORT
5220 case RT_OID_802_11_MAC_ADDRESS:
5221 wrq->u.data.length = MAC_ADDR_LEN;
5222 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5223 break;
5224
5225 case RT_OID_802_11_MANUFACTUREROUI:
5226 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n"));
5227 wrq->u.data.length = ManufacturerOUI_LEN;
5228 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5229 break;
5230
5231 case RT_OID_802_11_MANUFACTURERNAME:
5232 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n"));
5233 wrq->u.data.length = strlen(ManufacturerNAME);
5234 Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5235 break;
5236
5237 case RT_OID_802_11_RESOURCETYPEIDNAME:
5238 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n"));
5239 wrq->u.data.length = strlen(ResourceTypeIdName);
5240 Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length);
5241 break;
5242
5243 case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED:
5244 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n"));
5245 ulInfo = 1; // 1 is support wep else 2 is not support.
5246 wrq->u.data.length = sizeof(ulInfo);
5247 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5248 break;
5249
5250 case RT_OID_802_11_POWERMANAGEMENTMODE:
5251 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
5252 if (pAdapter->StaCfg.Psm == PSMP_ACTION)
5253 ulInfo = 1; // 1 is power active else 2 is power save.
5254 else
5255 ulInfo = 2;
5256
5257 wrq->u.data.length = sizeof(ulInfo);
5258 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5259 break;
5260
5261 case OID_802_11_WEPDEFAULTKEYVALUE:
5262 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n"));
5263 //KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId;
5264 pKeyIdxValue = wrq->u.data.pointer;
5265 DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
5266 valueLen = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
5267 NdisMoveMemory(pKeyIdxValue->Value,
5268 &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key,
5269 valueLen);
5270 pKeyIdxValue->Value[valueLen]='\0';
5271
5272 wrq->u.data.length = sizeof(DefaultKeyIdxValue);
5273
5274 Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length);
5275 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,
5276 pAdapter->SharedKey[BSS0][0].Key[0],
5277 pAdapter->SharedKey[BSS0][1].Key[0],
5278 pAdapter->SharedKey[BSS0][2].Key[0],
5279 pAdapter->SharedKey[BSS0][3].Key[0]));
5280 break;
5281
5282 case OID_802_11_WEPDEFAULTKEYID:
5283 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n"));
5284 wrq->u.data.length = sizeof(UCHAR);
5285 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length);
5286 DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAdapter->StaCfg.DefaultKeyId));
5287 break;
5288
5289 case RT_OID_802_11_WEPKEYMAPPINGLENGTH:
5290 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n"));
5291 wrq->u.data.length = sizeof(UCHAR);
5292 Status = copy_to_user(wrq->u.data.pointer,
5293 &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
5294 wrq->u.data.length);
5295 break;
5296
5297 case OID_802_11_SHORTRETRYLIMIT:
5298 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n"));
5299 wrq->u.data.length = sizeof(ULONG);
5300 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5301 ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit;
5302 DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld, tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit));
5303 Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length);
5304 break;
5305
5306 case OID_802_11_LONGRETRYLIMIT:
5307 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n"));
5308 wrq->u.data.length = sizeof(ULONG);
5309 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5310 LongRetryLimit = tx_rty_cfg.field.LongRtyLimit;
5311 DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld, tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit));
5312 Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length);
5313 break;
5314
5315 case RT_OID_802_11_PRODUCTID:
5316 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
5317
5318#ifdef RT2870
5319 sprintf(tmp, "%04x %04x\n", ((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idVendor ,((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idProduct);
5320
5321#endif // RT2870 //
5322 wrq->u.data.length = strlen(tmp);
5323 Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
5324 break;
5325
5326 case RT_OID_802_11_MANUFACTUREID:
5327 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n"));
5328 wrq->u.data.length = strlen(ManufacturerNAME);
5329 Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5330 break;
5331
5332 case OID_802_11_CURRENTCHANNEL:
5333 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n"));
5334 wrq->u.data.length = sizeof(UCHAR);
5335 DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAdapter->CommonCfg.Channel));
5336 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Channel, wrq->u.data.length);
5337 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5338 break;
5339#endif //SNMP_SUPPORT
5340
5341 case OID_802_11_BUILD_CHANNEL_EX:
5342 {
5343 UCHAR value;
5344 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
5345 wrq->u.data.length = sizeof(UCHAR);
5346#ifdef EXT_BUILD_CHANNEL_LIST
5347 DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n"));
5348 value = 1;
5349#else
5350 DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
5351 value = 0;
5352#endif // EXT_BUILD_CHANNEL_LIST //
5353 Status = copy_to_user(wrq->u.data.pointer, &value, 1);
5354 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5355 }
5356 break;
5357
5358 case OID_802_11_GET_CH_LIST:
5359 {
5360 PRT_CHANNEL_LIST_INFO pChListBuf;
5361
5362 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
5363 if (pAdapter->ChannelListNum == 0)
5364 {
5365 wrq->u.data.length = 0;
5366 break;
5367 }
5368
5369 pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
5370 if (pChListBuf == NULL)
5371 {
5372 wrq->u.data.length = 0;
5373 break;
5374 }
5375
5376 pChListBuf->ChannelListNum = pAdapter->ChannelListNum;
5377 for (i = 0; i < pChListBuf->ChannelListNum; i++)
5378 pChListBuf->ChannelList[i] = pAdapter->ChannelList[i].Channel;
5379
5380 wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
5381 Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
5382 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5383
5384 if (pChListBuf)
5385 kfree(pChListBuf);
5386 }
5387 break;
5388
5389 case OID_802_11_GET_COUNTRY_CODE:
5390 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
5391 wrq->u.data.length = 2;
5392 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.CountryCode, 2);
5393 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5394 break;
5395
5396 case OID_802_11_GET_CHANNEL_GEOGRAPHY:
5397 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
5398 wrq->u.data.length = 1;
5399 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Geography, 1);
5400 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5401 break;
5402
5403
5404#ifdef QOS_DLS_SUPPORT
5405 case RT_OID_802_11_QUERY_DLS:
5406 wrq->u.data.length = sizeof(BOOLEAN);
5407 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bDLSCapable, wrq->u.data.length);
5408 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAdapter->CommonCfg.bDLSCapable));
5409 break;
5410
5411 case RT_OID_802_11_QUERY_DLS_PARAM:
5412 {
5413 PRT_802_11_DLS_INFO pDlsInfo = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC);
5414 if (pDlsInfo == NULL)
5415 break;
5416
5417 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
5418 {
5419 RTMPMoveMemory(&pDlsInfo->Entry[i], &pAdapter->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI));
5420 }
5421
5422 pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY;
5423 wrq->u.data.length = sizeof(RT_802_11_DLS_INFO);
5424 Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length);
5425 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n"));
5426
5427 if (pDlsInfo)
5428 kfree(pDlsInfo);
5429 }
5430 break;
5431#endif // QOS_DLS_SUPPORT //
5432 default:
5433 DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
5434 Status = -EOPNOTSUPP;
5435 break;
5436 }
5437 return Status;
5438}
5439
5440INT rt28xx_sta_ioctl(
5441 IN struct net_device *net_dev,
5442 IN OUT struct ifreq *rq,
5443 IN INT cmd)
5444{
5445 POS_COOKIE pObj;
5446 VIRTUAL_ADAPTER *pVirtualAd = NULL;
5447 RTMP_ADAPTER *pAd = NULL;
5448 struct iwreq *wrq = (struct iwreq *) rq;
5449 BOOLEAN StateMachineTouched = FALSE;
5450 INT Status = NDIS_STATUS_SUCCESS;
5451 USHORT subcmd;
5452
5453 if (net_dev->priv_flags == INT_MAIN)
5454 {
5455 pAd = net_dev->priv;
5456 }
5457 else
5458 {
5459 pVirtualAd = net_dev->priv;
5460 pAd = pVirtualAd->RtmpDev->priv;
5461 }
5462 pObj = (POS_COOKIE) pAd->OS_Cookie;
5463
5464 if (pAd == NULL)
5465 {
5466 /* if 1st open fail, pAd will be free;
5467 So the net_dev->priv will be NULL in 2rd open */
5468 return -ENETDOWN;
5469 }
5470
5471 //check if the interface is down
5472 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
5473 {
5474#ifdef CONFIG_APSTA_MIXED_SUPPORT
5475 if (wrq->u.data.pointer == NULL)
5476 {
5477 return Status;
5478 }
5479
5480 if (strstr(wrq->u.data.pointer, "OpMode") == NULL)
5481#endif // CONFIG_APSTA_MIXED_SUPPORT //
5482 {
5483 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
5484 return -ENETDOWN;
5485 }
5486 }
5487
5488 { // determine this ioctl command is comming from which interface.
5489 pObj->ioctl_if_type = INT_MAIN;
5490 pObj->ioctl_if = MAIN_MBSSID;
5491 }
5492
5493 switch(cmd)
5494 {
5495#ifdef RALINK_ATE
5496#ifdef RALINK_28xx_QA
5497 case RTPRIV_IOCTL_ATE:
5498 {
5499 RtmpDoAte(pAd, wrq);
5500 }
5501 break;
5502#endif // RALINK_28xx_QA //
5503#endif // RALINK_ATE //
5504 case SIOCGIFHWADDR:
5505 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
5506 memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
5507 break;
5508 case SIOCGIWNAME:
5509 {
5510 char *name=&wrq->u.name[0];
5511 rt_ioctl_giwname(net_dev, NULL, name, NULL);
5512 break;
5513 }
5514 case SIOCGIWESSID: //Get ESSID
5515 {
5516 struct iw_point *essid=&wrq->u.essid;
5517 rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
5518 break;
5519 }
5520 case SIOCSIWESSID: //Set ESSID
5521 {
5522 struct iw_point *essid=&wrq->u.essid;
5523 rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
5524 break;
5525 }
5526 case SIOCSIWNWID: // set network id (the cell)
5527 case SIOCGIWNWID: // get network id
5528 Status = -EOPNOTSUPP;
5529 break;
5530 case SIOCSIWFREQ: //set channel/frequency (Hz)
5531 {
5532 struct iw_freq *freq=&wrq->u.freq;
5533 rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
5534 break;
5535 }
5536 case SIOCGIWFREQ: // get channel/frequency (Hz)
5537 {
5538 struct iw_freq *freq=&wrq->u.freq;
5539 rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
5540 break;
5541 }
5542 case SIOCSIWNICKN: //set node name/nickname
5543 {
5544 struct iw_point *data=&wrq->u.data;
5545 rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
5546 break;
5547 }
5548 case SIOCGIWNICKN: //get node name/nickname
5549 {
5550 struct iw_point *data=&wrq->u.data;
5551 rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
5552 break;
5553 }
5554 case SIOCGIWRATE: //get default bit rate (bps)
5555 rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
5556 break;
5557 case SIOCSIWRATE: //set default bit rate (bps)
5558 rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
5559 break;
5560 case SIOCGIWRTS: // get RTS/CTS threshold (bytes)
5561 {
5562 struct iw_param *rts=&wrq->u.rts;
5563 rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
5564 break;
5565 }
5566 case SIOCSIWRTS: //set RTS/CTS threshold (bytes)
5567 {
5568 struct iw_param *rts=&wrq->u.rts;
5569 rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
5570 break;
5571 }
5572 case SIOCGIWFRAG: //get fragmentation thr (bytes)
5573 {
5574 struct iw_param *frag=&wrq->u.frag;
5575 rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
5576 break;
5577 }
5578 case SIOCSIWFRAG: //set fragmentation thr (bytes)
5579 {
5580 struct iw_param *frag=&wrq->u.frag;
5581 rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
5582 break;
5583 }
5584 case SIOCGIWENCODE: //get encoding token & mode
5585 {
5586 struct iw_point *erq=&wrq->u.encoding;
5587 if(erq->pointer)
5588 rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
5589 break;
5590 }
5591 case SIOCSIWENCODE: //set encoding token & mode
5592 {
5593 struct iw_point *erq=&wrq->u.encoding;
5594 if(erq->pointer)
5595 rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
5596 break;
5597 }
5598 case SIOCGIWAP: //get access point MAC addresses
5599 {
5600 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5601 rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5602 break;
5603 }
5604 case SIOCSIWAP: //set access point MAC addresses
5605 {
5606 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5607 rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5608 break;
5609 }
5610 case SIOCGIWMODE: //get operation mode
5611 {
5612 __u32 *mode=&wrq->u.mode;
5613 rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
5614 break;
5615 }
5616 case SIOCSIWMODE: //set operation mode
5617 {
5618 __u32 *mode=&wrq->u.mode;
5619 rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
5620 break;
5621 }
5622 case SIOCGIWSENS: //get sensitivity (dBm)
5623 case SIOCSIWSENS: //set sensitivity (dBm)
5624 case SIOCGIWPOWER: //get Power Management settings
5625 case SIOCSIWPOWER: //set Power Management settings
5626 case SIOCGIWTXPOW: //get transmit power (dBm)
5627 case SIOCSIWTXPOW: //set transmit power (dBm)
5628 case SIOCGIWRANGE: //Get range of parameters
5629 case SIOCGIWRETRY: //get retry limits and lifetime
5630 case SIOCSIWRETRY: //set retry limits and lifetime
5631 Status = -EOPNOTSUPP;
5632 break;
5633 case RT_PRIV_IOCTL:
5634 subcmd = wrq->u.data.flags;
5635 if( subcmd & OID_GET_SET_TOGGLE)
5636 Status = RTMPSetInformation(pAd, rq, subcmd);
5637 else
5638 Status = RTMPQueryInformation(pAd, rq, subcmd);
5639 break;
5640 case SIOCGIWPRIV:
5641 if (wrq->u.data.pointer)
5642 {
5643 if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
5644 break;
5645 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
5646 if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
5647 Status = -EFAULT;
5648 }
5649 break;
5650 case RTPRIV_IOCTL_SET:
5651 if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
5652 break;
5653 rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
5654 break;
5655 case RTPRIV_IOCTL_GSITESURVEY:
5656 RTMPIoctlGetSiteSurvey(pAd, wrq);
5657 break;
5658#ifdef DBG
5659 case RTPRIV_IOCTL_MAC:
5660 RTMPIoctlMAC(pAd, wrq);
5661 break;
5662 case RTPRIV_IOCTL_E2P:
5663 RTMPIoctlE2PROM(pAd, wrq);
5664 break;
5665#endif // DBG //
5666 case SIOCETHTOOL:
5667 break;
5668 default:
5669 DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
5670 Status = -EOPNOTSUPP;
5671 break;
5672 }
5673
5674 if(StateMachineTouched) // Upper layer sent a MLME-related operations
5675 RT28XX_MLME_HANDLER(pAd);
5676
5677 return Status;
5678}
5679
5680/*
5681 ==========================================================================
5682 Description:
5683 Set SSID
5684 Return:
5685 TRUE if all parameters are OK, FALSE otherwise
5686 ==========================================================================
5687*/
5688INT Set_SSID_Proc(
5689 IN PRTMP_ADAPTER pAdapter,
5690 IN PUCHAR arg)
5691{
5692 NDIS_802_11_SSID Ssid, *pSsid=NULL;
5693 BOOLEAN StateMachineTouched = FALSE;
5694 int success = TRUE;
5695
5696 if( strlen(arg) <= MAX_LEN_OF_SSID)
5697 {
5698 NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
5699 if (strlen(arg) != 0)
5700 {
5701 NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
5702 Ssid.SsidLength = strlen(arg);
5703 }
5704 else //ANY ssid
5705 {
5706 Ssid.SsidLength = 0;
5707 memcpy(Ssid.Ssid, "", 0);
5708 pAdapter->StaCfg.BssType = BSS_INFRA;
5709 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5710 pAdapter->StaCfg.WepStatus = Ndis802_11EncryptionDisabled;
5711 }
5712 pSsid = &Ssid;
5713
5714 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
5715 {
5716 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5717 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
5718 }
5719
5720 pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
5721 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
5722 pAdapter->bConfigChanged = TRUE;
5723
5724 MlmeEnqueue(pAdapter,
5725 MLME_CNTL_STATE_MACHINE,
5726 OID_802_11_SSID,
5727 sizeof(NDIS_802_11_SSID),
5728 (VOID *)pSsid);
5729
5730 StateMachineTouched = TRUE;
5731 DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
5732 }
5733 else
5734 success = FALSE;
5735
5736 if (StateMachineTouched) // Upper layer sent a MLME-related operations
5737 RT28XX_MLME_HANDLER(pAdapter);
5738
5739 return success;
5740}
5741
5742#ifdef WMM_SUPPORT
5743/*
5744 ==========================================================================
5745 Description:
5746 Set WmmCapable Enable or Disable
5747 Return:
5748 TRUE if all parameters are OK, FALSE otherwise
5749 ==========================================================================
5750*/
5751INT Set_WmmCapable_Proc(
5752 IN PRTMP_ADAPTER pAd,
5753 IN PUCHAR arg)
5754{
5755 BOOLEAN bWmmCapable;
5756
5757 bWmmCapable = simple_strtol(arg, 0, 10);
5758
5759 if ((bWmmCapable == 1)
5760#ifdef RT2870
5761 && (pAd->NumberOfPipes >= 5)
5762#endif // RT2870 //
5763 )
5764 pAd->CommonCfg.bWmmCapable = TRUE;
5765 else if (bWmmCapable == 0)
5766 pAd->CommonCfg.bWmmCapable = FALSE;
5767 else
5768 return FALSE; //Invalid argument
5769
5770 DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
5771 pAd->CommonCfg.bWmmCapable));
5772
5773 return TRUE;
5774}
5775#endif // WMM_SUPPORT //
5776
5777/*
5778 ==========================================================================
5779 Description:
5780 Set Network Type(Infrastructure/Adhoc mode)
5781 Return:
5782 TRUE if all parameters are OK, FALSE otherwise
5783 ==========================================================================
5784*/
5785INT Set_NetworkType_Proc(
5786 IN PRTMP_ADAPTER pAdapter,
5787 IN PUCHAR arg)
5788{
5789 UINT32 Value = 0;
5790
5791 if (strcmp(arg, "Adhoc") == 0)
5792 {
5793 if (pAdapter->StaCfg.BssType != BSS_ADHOC)
5794 {
5795 // Config has changed
5796 pAdapter->bConfigChanged = TRUE;
5797 if (MONITOR_ON(pAdapter))
5798 {
5799 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5800 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5801 Value &= (~0x80);
5802 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5803 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5804 pAdapter->StaCfg.bAutoReconnect = TRUE;
5805 LinkDown(pAdapter, FALSE);
5806 }
5807 if (INFRA_ON(pAdapter))
5808 {
5809 //BOOLEAN Cancelled;
5810 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5811 // Since calling this indicate user don't want to connect to that SSID anymore.
5812 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5813 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5814
5815 LinkDown(pAdapter, FALSE);
5816
5817 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
5818 }
5819 }
5820 pAdapter->StaCfg.BssType = BSS_ADHOC;
5821 pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5822 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
5823 }
5824 else if (strcmp(arg, "Infra") == 0)
5825 {
5826 if (pAdapter->StaCfg.BssType != BSS_INFRA)
5827 {
5828 // Config has changed
5829 pAdapter->bConfigChanged = TRUE;
5830 if (MONITOR_ON(pAdapter))
5831 {
5832 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5833 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5834 Value &= (~0x80);
5835 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5836 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5837 pAdapter->StaCfg.bAutoReconnect = TRUE;
5838 LinkDown(pAdapter, FALSE);
5839 }
5840 if (ADHOC_ON(pAdapter))
5841 {
5842 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5843 // Since calling this indicate user don't want to connect to that SSID anymore.
5844 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5845 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5846
5847 LinkDown(pAdapter, FALSE);
5848 }
5849 }
5850 pAdapter->StaCfg.BssType = BSS_INFRA;
5851 pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5852 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
5853
5854 pAdapter->StaCfg.BssType = BSS_INFRA;
5855 }
5856 else if (strcmp(arg, "Monitor") == 0)
5857 {
5858 UCHAR bbpValue = 0;
5859 BCN_TIME_CFG_STRUC csr;
5860 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
5861 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
5862 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5863 // disable all periodic state machine
5864 pAdapter->StaCfg.bAutoReconnect = FALSE;
5865 // reset all mlme state machine
5866 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5867 DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
5868 if (pAdapter->CommonCfg.CentralChannel == 0)
5869 {
5870#ifdef DOT11_N_SUPPORT
5871 if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
5872 pAdapter->CommonCfg.CentralChannel = 36;
5873 else
5874#endif // DOT11_N_SUPPORT //
5875 pAdapter->CommonCfg.CentralChannel = 6;
5876 }
5877#ifdef DOT11_N_SUPPORT
5878 else
5879 N_ChannelCheck(pAdapter);
5880#endif // DOT11_N_SUPPORT //
5881
5882#ifdef DOT11_N_SUPPORT
5883 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5884 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5885 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
5886 {
5887 // 40MHz ,control channel at lower
5888 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5889 bbpValue &= (~0x18);
5890 bbpValue |= 0x10;
5891 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5892 pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5893 // RX : control channel at lower
5894 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5895 bbpValue &= (~0x20);
5896 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5897
5898 RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5899 Value &= 0xfffffffe;
5900 RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5901 pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
5902 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5903 AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5904 DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5905 pAdapter->CommonCfg.Channel,
5906 pAdapter->CommonCfg.CentralChannel));
5907 }
5908 else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5909 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5910 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
5911 {
5912 // 40MHz ,control channel at upper
5913 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5914 bbpValue &= (~0x18);
5915 bbpValue |= 0x10;
5916 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5917 pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5918 RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5919 Value |= 0x1;
5920 RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5921
5922 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5923 bbpValue |= (0x20);
5924 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5925 pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
5926 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5927 AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5928 DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5929 pAdapter->CommonCfg.Channel,
5930 pAdapter->CommonCfg.CentralChannel));
5931 }
5932 else
5933#endif // DOT11_N_SUPPORT //
5934 {
5935 // 20MHz
5936 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5937 bbpValue &= (~0x18);
5938 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5939 pAdapter->CommonCfg.BBPCurrentBW = BW_20;
5940 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
5941 AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
5942 DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
5943 }
5944 // Enable Rx with promiscuous reception
5945 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
5946 // ASIC supporsts sniffer function with replacing RSSI with timestamp.
5947 //RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5948 //Value |= (0x80);
5949 //RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5950 // disable sync
5951 RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
5952 csr.field.bBeaconGen = 0;
5953 csr.field.bTBTTEnable = 0;
5954 csr.field.TsfSyncMode = 0;
5955 RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
5956
5957 pAdapter->StaCfg.BssType = BSS_MONITOR;
5958 pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
5959 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
5960 }
5961
5962 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
5963 pAdapter->StaCfg.WpaState = SS_NOTUSE;
5964
5965 DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
5966
5967 return TRUE;
5968}
5969
5970/*
5971 ==========================================================================
5972 Description:
5973 Set Authentication mode
5974 Return:
5975 TRUE if all parameters are OK, FALSE otherwise
5976 ==========================================================================
5977*/
5978INT Set_AuthMode_Proc(
5979 IN PRTMP_ADAPTER pAdapter,
5980 IN PUCHAR arg)
5981{
5982 if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
5983 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
5984 else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
5985 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5986 else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
5987 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
5988 else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
5989 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
5990 else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
5991 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
5992 else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
5993 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
5994#ifdef WPA_SUPPLICANT_SUPPORT
5995 else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
5996 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
5997 else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
5998 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
5999#endif // WPA_SUPPLICANT_SUPPORT //
6000 else
6001 return FALSE;
6002
6003 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
6004
6005 DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
6006
6007 return TRUE;
6008}
6009
6010/*
6011 ==========================================================================
6012 Description:
6013 Set Encryption Type
6014 Return:
6015 TRUE if all parameters are OK, FALSE otherwise
6016 ==========================================================================
6017*/
6018INT Set_EncrypType_Proc(
6019 IN PRTMP_ADAPTER pAdapter,
6020 IN PUCHAR arg)
6021{
6022 if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
6023 {
6024 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6025 return TRUE; // do nothing
6026
6027 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
6028 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
6029 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
6030 }
6031 else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
6032 {
6033 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6034 return TRUE; // do nothing
6035
6036 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
6037 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
6038 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
6039 }
6040 else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
6041 {
6042 if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
6043 return TRUE; // do nothing
6044
6045 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
6046 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
6047 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
6048 }
6049 else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
6050 {
6051 if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
6052 return TRUE; // do nothing
6053
6054 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
6055 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
6056 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
6057 }
6058 else
6059 return FALSE;
6060
6061 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
6062
6063 DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
6064
6065 return TRUE;
6066}
6067
6068/*
6069 ==========================================================================
6070 Description:
6071 Set Default Key ID
6072 Return:
6073 TRUE if all parameters are OK, FALSE otherwise
6074 ==========================================================================
6075*/
6076INT Set_DefaultKeyID_Proc(
6077 IN PRTMP_ADAPTER pAdapter,
6078 IN PUCHAR arg)
6079{
6080 ULONG KeyIdx;
6081
6082 KeyIdx = simple_strtol(arg, 0, 10);
6083 if((KeyIdx >= 1 ) && (KeyIdx <= 4))
6084 pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
6085 else
6086 return FALSE; //Invalid argument
6087
6088 DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
6089
6090 return TRUE;
6091}
6092
6093/*
6094 ==========================================================================
6095 Description:
6096 Set WEP KEY1
6097 Return:
6098 TRUE if all parameters are OK, FALSE otherwise
6099 ==========================================================================
6100*/
6101INT Set_Key1_Proc(
6102 IN PRTMP_ADAPTER pAdapter,
6103 IN PUCHAR arg)
6104{
6105 int KeyLen;
6106 int i;
6107 UCHAR CipherAlg=CIPHER_WEP64;
6108
6109 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6110 return TRUE; // do nothing
6111
6112 KeyLen = strlen(arg);
6113
6114 switch (KeyLen)
6115 {
6116 case 5: //wep 40 Ascii type
6117 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6118 memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6119 CipherAlg = CIPHER_WEP64;
6120 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
6121 break;
6122 case 10: //wep 40 Hex type
6123 for(i=0; i < KeyLen; i++)
6124 {
6125 if( !isxdigit(*(arg+i)) )
6126 return FALSE; //Not Hex value;
6127 }
6128 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
6129 AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6130 CipherAlg = CIPHER_WEP64;
6131 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6132 break;
6133 case 13: //wep 104 Ascii type
6134 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6135 memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6136 CipherAlg = CIPHER_WEP128;
6137 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
6138 break;
6139 case 26: //wep 104 Hex type
6140 for(i=0; i < KeyLen; i++)
6141 {
6142 if( !isxdigit(*(arg+i)) )
6143 return FALSE; //Not Hex value;
6144 }
6145 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
6146 AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6147 CipherAlg = CIPHER_WEP128;
6148 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6149 break;
6150 default: //Invalid argument
6151 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
6152 return FALSE;
6153 }
6154
6155 pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
6156
6157 // Set keys (into ASIC)
6158 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6159 ; // not support
6160 else // Old WEP stuff
6161 {
6162 AsicAddSharedKeyEntry(pAdapter,
6163 0,
6164 0,
6165 pAdapter->SharedKey[BSS0][0].CipherAlg,
6166 pAdapter->SharedKey[BSS0][0].Key,
6167 NULL,
6168 NULL);
6169 }
6170
6171 return TRUE;
6172}
6173/*
6174 ==========================================================================
6175
6176 Description:
6177 Set WEP KEY2
6178 Return:
6179 TRUE if all parameters are OK, FALSE otherwise
6180 ==========================================================================
6181*/
6182INT Set_Key2_Proc(
6183 IN PRTMP_ADAPTER pAdapter,
6184 IN PUCHAR arg)
6185{
6186 int KeyLen;
6187 int i;
6188 UCHAR CipherAlg=CIPHER_WEP64;
6189
6190 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6191 return TRUE; // do nothing
6192
6193 KeyLen = strlen(arg);
6194
6195 switch (KeyLen)
6196 {
6197 case 5: //wep 40 Ascii type
6198 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6199 memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6200 CipherAlg = CIPHER_WEP64;
6201 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6202 break;
6203 case 10: //wep 40 Hex type
6204 for(i=0; i < KeyLen; i++)
6205 {
6206 if( !isxdigit(*(arg+i)) )
6207 return FALSE; //Not Hex value;
6208 }
6209 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6210 AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6211 CipherAlg = CIPHER_WEP64;
6212 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6213 break;
6214 case 13: //wep 104 Ascii type
6215 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6216 memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6217 CipherAlg = CIPHER_WEP128;
6218 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6219 break;
6220 case 26: //wep 104 Hex type
6221 for(i=0; i < KeyLen; i++)
6222 {
6223 if( !isxdigit(*(arg+i)) )
6224 return FALSE; //Not Hex value;
6225 }
6226 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6227 AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6228 CipherAlg = CIPHER_WEP128;
6229 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6230 break;
6231 default: //Invalid argument
6232 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
6233 return FALSE;
6234 }
6235 pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
6236
6237 // Set keys (into ASIC)
6238 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6239 ; // not support
6240 else // Old WEP stuff
6241 {
6242 AsicAddSharedKeyEntry(pAdapter,
6243 0,
6244 1,
6245 pAdapter->SharedKey[BSS0][1].CipherAlg,
6246 pAdapter->SharedKey[BSS0][1].Key,
6247 NULL,
6248 NULL);
6249 }
6250
6251 return TRUE;
6252}
6253/*
6254 ==========================================================================
6255 Description:
6256 Set WEP KEY3
6257 Return:
6258 TRUE if all parameters are OK, FALSE otherwise
6259 ==========================================================================
6260*/
6261INT Set_Key3_Proc(
6262 IN PRTMP_ADAPTER pAdapter,
6263 IN PUCHAR arg)
6264{
6265 int KeyLen;
6266 int i;
6267 UCHAR CipherAlg=CIPHER_WEP64;
6268
6269 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6270 return TRUE; // do nothing
6271
6272 KeyLen = strlen(arg);
6273
6274 switch (KeyLen)
6275 {
6276 case 5: //wep 40 Ascii type
6277 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6278 memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6279 CipherAlg = CIPHER_WEP64;
6280 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6281 break;
6282 case 10: //wep 40 Hex type
6283 for(i=0; i < KeyLen; i++)
6284 {
6285 if( !isxdigit(*(arg+i)) )
6286 return FALSE; //Not Hex value;
6287 }
6288 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6289 AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6290 CipherAlg = CIPHER_WEP64;
6291 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6292 break;
6293 case 13: //wep 104 Ascii type
6294 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6295 memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6296 CipherAlg = CIPHER_WEP128;
6297 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6298 break;
6299 case 26: //wep 104 Hex type
6300 for(i=0; i < KeyLen; i++)
6301 {
6302 if( !isxdigit(*(arg+i)) )
6303 return FALSE; //Not Hex value;
6304 }
6305 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6306 AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6307 CipherAlg = CIPHER_WEP128;
6308 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6309 break;
6310 default: //Invalid argument
6311 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
6312 return FALSE;
6313 }
6314 pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
6315
6316 // Set keys (into ASIC)
6317 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6318 ; // not support
6319 else // Old WEP stuff
6320 {
6321 AsicAddSharedKeyEntry(pAdapter,
6322 0,
6323 2,
6324 pAdapter->SharedKey[BSS0][2].CipherAlg,
6325 pAdapter->SharedKey[BSS0][2].Key,
6326 NULL,
6327 NULL);
6328 }
6329
6330 return TRUE;
6331}
6332/*
6333 ==========================================================================
6334 Description:
6335 Set WEP KEY4
6336 Return:
6337 TRUE if all parameters are OK, FALSE otherwise
6338 ==========================================================================
6339*/
6340INT Set_Key4_Proc(
6341 IN PRTMP_ADAPTER pAdapter,
6342 IN PUCHAR arg)
6343{
6344 int KeyLen;
6345 int i;
6346 UCHAR CipherAlg=CIPHER_WEP64;
6347
6348 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6349 return TRUE; // do nothing
6350
6351 KeyLen = strlen(arg);
6352
6353 switch (KeyLen)
6354 {
6355 case 5: //wep 40 Ascii type
6356 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6357 memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6358 CipherAlg = CIPHER_WEP64;
6359 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6360 break;
6361 case 10: //wep 40 Hex type
6362 for(i=0; i < KeyLen; i++)
6363 {
6364 if( !isxdigit(*(arg+i)) )
6365 return FALSE; //Not Hex value;
6366 }
6367 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6368 AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6369 CipherAlg = CIPHER_WEP64;
6370 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6371 break;
6372 case 13: //wep 104 Ascii type
6373 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6374 memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6375 CipherAlg = CIPHER_WEP128;
6376 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6377 break;
6378 case 26: //wep 104 Hex type
6379 for(i=0; i < KeyLen; i++)
6380 {
6381 if( !isxdigit(*(arg+i)) )
6382 return FALSE; //Not Hex value;
6383 }
6384 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6385 AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6386 CipherAlg = CIPHER_WEP128;
6387 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6388 break;
6389 default: //Invalid argument
6390 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
6391 return FALSE;
6392 }
6393 pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
6394
6395 // Set keys (into ASIC)
6396 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6397 ; // not support
6398 else // Old WEP stuff
6399 {
6400 AsicAddSharedKeyEntry(pAdapter,
6401 0,
6402 3,
6403 pAdapter->SharedKey[BSS0][3].CipherAlg,
6404 pAdapter->SharedKey[BSS0][3].Key,
6405 NULL,
6406 NULL);
6407 }
6408
6409 return TRUE;
6410}
6411
6412/*
6413 ==========================================================================
6414 Description:
6415 Set WPA PSK key
6416 Return:
6417 TRUE if all parameters are OK, FALSE otherwise
6418 ==========================================================================
6419*/
6420INT Set_WPAPSK_Proc(
6421 IN PRTMP_ADAPTER pAdapter,
6422 IN PUCHAR arg)
6423{
6424 UCHAR keyMaterial[40];
6425
6426 if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
6427 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
6428 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
6429 )
6430 return TRUE; // do nothing
6431
6432 DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
6433
6434 NdisZeroMemory(keyMaterial, 40);
6435
6436 if ((strlen(arg) < 8) || (strlen(arg) > 64))
6437 {
6438 DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
6439 return FALSE;
6440 }
6441
6442 if (strlen(arg) == 64)
6443 {
6444 AtoH(arg, keyMaterial, 32);
6445 NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6446
6447 }
6448 else
6449 {
6450 PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
6451 NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6452 }
6453
6454
6455
6456 if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
6457 pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
6458 {
6459 pAdapter->StaCfg.WpaState = SS_NOTUSE;
6460 }
6461 else
6462 {
6463 // Start STA supplicant state machine
6464 pAdapter->StaCfg.WpaState = SS_START;
6465 }
6466
6467 return TRUE;
6468}
6469
6470/*
6471 ==========================================================================
6472 Description:
6473 Set Power Saving mode
6474 Return:
6475 TRUE if all parameters are OK, FALSE otherwise
6476 ==========================================================================
6477*/
6478INT Set_PSMode_Proc(
6479 IN PRTMP_ADAPTER pAdapter,
6480 IN PUCHAR arg)
6481{
6482 if (pAdapter->StaCfg.BssType == BSS_INFRA)
6483 {
6484 if ((strcmp(arg, "Max_PSP") == 0) ||
6485 (strcmp(arg, "max_psp") == 0) ||
6486 (strcmp(arg, "MAX_PSP") == 0))
6487 {
6488 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6489 // to exclude certain situations.
6490 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6491 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
6492 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
6493 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6494 pAdapter->StaCfg.DefaultListenCount = 5;
6495
6496 }
6497 else if ((strcmp(arg, "Fast_PSP") == 0) ||
6498 (strcmp(arg, "fast_psp") == 0) ||
6499 (strcmp(arg, "FAST_PSP") == 0))
6500 {
6501 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6502 // to exclude certain situations.
6503 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6504 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6505 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
6506 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
6507 pAdapter->StaCfg.DefaultListenCount = 3;
6508 }
6509 else if ((strcmp(arg, "Legacy_PSP") == 0) ||
6510 (strcmp(arg, "legacy_psp") == 0) ||
6511 (strcmp(arg, "LEGACY_PSP") == 0))
6512 {
6513 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6514 // to exclude certain situations.
6515 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6516 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6517 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
6518 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
6519 pAdapter->StaCfg.DefaultListenCount = 3;
6520 }
6521 else
6522 {
6523 //Default Ndis802_11PowerModeCAM
6524 // clear PSM bit immediately
6525 MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
6526 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6527 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6528 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
6529 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
6530 }
6531
6532 DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
6533 }
6534 else
6535 return FALSE;
6536
6537
6538 return TRUE;
6539}
6540
6541#ifdef WPA_SUPPLICANT_SUPPORT
6542/*
6543 ==========================================================================
6544 Description:
6545 Set WpaSupport flag.
6546 Value:
6547 0: Driver ignore wpa_supplicant.
6548 1: wpa_supplicant initiates scanning and AP selection.
6549 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
6550 Return:
6551 TRUE if all parameters are OK, FALSE otherwise
6552 ==========================================================================
6553*/
6554INT Set_Wpa_Support(
6555 IN PRTMP_ADAPTER pAd,
6556 IN PUCHAR arg)
6557{
6558
6559 if ( simple_strtol(arg, 0, 10) == 0)
6560 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6561 else if ( simple_strtol(arg, 0, 10) == 1)
6562 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
6563 else if ( simple_strtol(arg, 0, 10) == 2)
6564 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
6565 else
6566 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6567
6568 DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
6569
6570 return TRUE;
6571}
6572#endif // WPA_SUPPLICANT_SUPPORT //
6573
6574#ifdef DBG
6575/*
6576 ==========================================================================
6577 Description:
6578 Read / Write MAC
6579 Arguments:
6580 pAdapter Pointer to our adapter
6581 wrq Pointer to the ioctl argument
6582
6583 Return Value:
6584 None
6585
6586 Note:
6587 Usage:
6588 1.) iwpriv ra0 mac 0 ==> read MAC where Addr=0x0
6589 2.) iwpriv ra0 mac 0=12 ==> write MAC where Addr=0x0, value=12
6590 ==========================================================================
6591*/
6592VOID RTMPIoctlMAC(
6593 IN PRTMP_ADAPTER pAdapter,
6594 IN struct iwreq *wrq)
6595{
6596 CHAR *this_char;
6597 CHAR *value;
6598 INT j = 0, k = 0;
6599 CHAR msg[1024];
6600 CHAR arg[255];
6601 ULONG macAddr = 0;
6602 UCHAR temp[16], temp2[16];
6603 UINT32 macValue = 0;
6604 INT Status;
6605
6606
6607 memset(msg, 0x00, 1024);
6608 if (wrq->u.data.length > 1) //No parameters.
6609 {
6610 Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6611 sprintf(msg, "\n");
6612
6613 //Parsing Read or Write
6614 this_char = arg;
6615 if (!*this_char)
6616 goto next;
6617
6618 if ((value = rtstrchr(this_char, '=')) != NULL)
6619 *value++ = 0;
6620
6621 if (!value || !*value)
6622 { //Read
6623 // Sanity check
6624 if(strlen(this_char) > 4)
6625 goto next;
6626
6627 j = strlen(this_char);
6628 while(j-- > 0)
6629 {
6630 if(this_char[j] > 'f' || this_char[j] < '0')
6631 return;
6632 }
6633
6634 // Mac Addr
6635 k = j = strlen(this_char);
6636 while(j-- > 0)
6637 {
6638 this_char[4-k+j] = this_char[j];
6639 }
6640
6641 while(k < 4)
6642 this_char[3-k++]='0';
6643 this_char[4]='\0';
6644
6645 if(strlen(this_char) == 4)
6646 {
6647 AtoH(this_char, temp, 2);
6648 macAddr = *temp*256 + temp[1];
6649 if (macAddr < 0xFFFF)
6650 {
6651 RTMP_IO_READ32(pAdapter, macAddr, &macValue);
6652 DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
6653 sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr , macValue);
6654 }
6655 else
6656 {//Invalid parametes, so default printk all bbp
6657 goto next;
6658 }
6659 }
6660 }
6661 else
6662 { //Write
6663 memcpy(&temp2, value, strlen(value));
6664 temp2[strlen(value)] = '\0';
6665
6666 // Sanity check
6667 if((strlen(this_char) > 4) || strlen(temp2) > 8)
6668 goto next;
6669
6670 j = strlen(this_char);
6671 while(j-- > 0)
6672 {
6673 if(this_char[j] > 'f' || this_char[j] < '0')
6674 return;
6675 }
6676
6677 j = strlen(temp2);
6678 while(j-- > 0)
6679 {
6680 if(temp2[j] > 'f' || temp2[j] < '0')
6681 return;
6682 }
6683
6684 //MAC Addr
6685 k = j = strlen(this_char);
6686 while(j-- > 0)
6687 {
6688 this_char[4-k+j] = this_char[j];
6689 }
6690
6691 while(k < 4)
6692 this_char[3-k++]='0';
6693 this_char[4]='\0';
6694
6695 //MAC value
6696 k = j = strlen(temp2);
6697 while(j-- > 0)
6698 {
6699 temp2[8-k+j] = temp2[j];
6700 }
6701
6702 while(k < 8)
6703 temp2[7-k++]='0';
6704 temp2[8]='\0';
6705
6706 {
6707 AtoH(this_char, temp, 2);
6708 macAddr = *temp*256 + temp[1];
6709
6710 AtoH(temp2, temp, 4);
6711 macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
6712
6713 // debug mode
6714 if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
6715 {
6716 // 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
6717 if (macValue & 0x000000ff)
6718 {
6719 pAdapter->BbpTuning.bEnable = TRUE;
6720 DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
6721 }
6722 else
6723 {
6724 UCHAR R66;
6725 pAdapter->BbpTuning.bEnable = FALSE;
6726 R66 = 0x26 + GET_LNA_GAIN(pAdapter);
6727#ifdef RALINK_ATE
6728 if (ATE_ON(pAdapter))
6729 {
6730 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6731 }
6732 else
6733#endif // RALINK_ATE //
6734 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6735 DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
6736 }
6737 return;
6738 }
6739
6740 DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
6741
6742 RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
6743 sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr, macValue);
6744 }
6745 }
6746 }
6747next:
6748 if(strlen(msg) == 1)
6749 sprintf(msg+strlen(msg), "===>Error command format!");
6750
6751 // Copy the information into the user buffer
6752 wrq->u.data.length = strlen(msg);
6753 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6754
6755 DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
6756}
6757
6758/*
6759 ==========================================================================
6760 Description:
6761 Read / Write E2PROM
6762 Arguments:
6763 pAdapter Pointer to our adapter
6764 wrq Pointer to the ioctl argument
6765
6766 Return Value:
6767 None
6768
6769 Note:
6770 Usage:
6771 1.) iwpriv ra0 e2p 0 ==> read E2PROM where Addr=0x0
6772 2.) iwpriv ra0 e2p 0=1234 ==> write E2PROM where Addr=0x0, value=1234
6773 ==========================================================================
6774*/
6775VOID RTMPIoctlE2PROM(
6776 IN PRTMP_ADAPTER pAdapter,
6777 IN struct iwreq *wrq)
6778{
6779 CHAR *this_char;
6780 CHAR *value;
6781 INT j = 0, k = 0;
6782 CHAR msg[1024];
6783 CHAR arg[255];
6784 USHORT eepAddr = 0;
6785 UCHAR temp[16], temp2[16];
6786 USHORT eepValue;
6787 int Status;
6788
6789
6790 memset(msg, 0x00, 1024);
6791 if (wrq->u.data.length > 1) //No parameters.
6792 {
6793 Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6794 sprintf(msg, "\n");
6795
6796 //Parsing Read or Write
6797 this_char = arg;
6798
6799
6800 if (!*this_char)
6801 goto next;
6802
6803 if ((value = rtstrchr(this_char, '=')) != NULL)
6804 *value++ = 0;
6805
6806 if (!value || !*value)
6807 { //Read
6808
6809 // Sanity check
6810 if(strlen(this_char) > 4)
6811 goto next;
6812
6813 j = strlen(this_char);
6814 while(j-- > 0)
6815 {
6816 if(this_char[j] > 'f' || this_char[j] < '0')
6817 return;
6818 }
6819
6820 // E2PROM addr
6821 k = j = strlen(this_char);
6822 while(j-- > 0)
6823 {
6824 this_char[4-k+j] = this_char[j];
6825 }
6826
6827 while(k < 4)
6828 this_char[3-k++]='0';
6829 this_char[4]='\0';
6830
6831 if(strlen(this_char) == 4)
6832 {
6833 AtoH(this_char, temp, 2);
6834 eepAddr = *temp*256 + temp[1];
6835 if (eepAddr < 0xFFFF)
6836 {
6837 RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
6838 sprintf(msg+strlen(msg), "[0x%04X]:0x%04X ", eepAddr , eepValue);
6839 }
6840 else
6841 {//Invalid parametes, so default printk all bbp
6842 goto next;
6843 }
6844 }
6845 }
6846 else
6847 { //Write
6848 memcpy(&temp2, value, strlen(value));
6849 temp2[strlen(value)] = '\0';
6850
6851 // Sanity check
6852 if((strlen(this_char) > 4) || strlen(temp2) > 8)
6853 goto next;
6854
6855 j = strlen(this_char);
6856 while(j-- > 0)
6857 {
6858 if(this_char[j] > 'f' || this_char[j] < '0')
6859 return;
6860 }
6861 j = strlen(temp2);
6862 while(j-- > 0)
6863 {
6864 if(temp2[j] > 'f' || temp2[j] < '0')
6865 return;
6866 }
6867
6868 //MAC Addr
6869 k = j = strlen(this_char);
6870 while(j-- > 0)
6871 {
6872 this_char[4-k+j] = this_char[j];
6873 }
6874
6875 while(k < 4)
6876 this_char[3-k++]='0';
6877 this_char[4]='\0';
6878
6879 //MAC value
6880 k = j = strlen(temp2);
6881 while(j-- > 0)
6882 {
6883 temp2[4-k+j] = temp2[j];
6884 }
6885
6886 while(k < 4)
6887 temp2[3-k++]='0';
6888 temp2[4]='\0';
6889
6890 AtoH(this_char, temp, 2);
6891 eepAddr = *temp*256 + temp[1];
6892
6893 AtoH(temp2, temp, 2);
6894 eepValue = *temp*256 + temp[1];
6895
6896 RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
6897 sprintf(msg+strlen(msg), "[0x%02X]:%02X ", eepAddr, eepValue);
6898 }
6899 }
6900next:
6901 if(strlen(msg) == 1)
6902 sprintf(msg+strlen(msg), "===>Error command format!");
6903
6904
6905 // Copy the information into the user buffer
6906 wrq->u.data.length = strlen(msg);
6907 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6908
6909 DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
6910}
6911#endif // DBG //
6912
6913
6914
6915
6916INT Set_TGnWifiTest_Proc(
6917 IN PRTMP_ADAPTER pAd,
6918 IN PUCHAR arg)
6919{
6920 if (simple_strtol(arg, 0, 10) == 0)
6921 pAd->StaCfg.bTGnWifiTest = FALSE;
6922 else
6923 pAd->StaCfg.bTGnWifiTest = TRUE;
6924
6925 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
6926 return TRUE;
6927}
6928
6929INT Set_LongRetryLimit_Proc(
6930 IN PRTMP_ADAPTER pAdapter,
6931 IN PUCHAR arg)
6932{
6933 TX_RTY_CFG_STRUC tx_rty_cfg;
6934 UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6935
6936 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6937 tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
6938 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6939 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6940 return TRUE;
6941}
6942
6943INT Set_ShortRetryLimit_Proc(
6944 IN PRTMP_ADAPTER pAdapter,
6945 IN PUCHAR arg)
6946{
6947 TX_RTY_CFG_STRUC tx_rty_cfg;
6948 UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6949
6950 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6951 tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
6952 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6953 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6954 return TRUE;
6955}
6956
6957#ifdef EXT_BUILD_CHANNEL_LIST
6958INT Set_Ieee80211dClientMode_Proc(
6959 IN PRTMP_ADAPTER pAdapter,
6960 IN PUCHAR arg)
6961{
6962 if (simple_strtol(arg, 0, 10) == 0)
6963 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
6964 else if (simple_strtol(arg, 0, 10) == 1)
6965 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible;
6966 else if (simple_strtol(arg, 0, 10) == 2)
6967 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict;
6968 else
6969 return FALSE;
6970
6971 DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode));
6972 return TRUE;
6973}
6974#endif // EXT_BUILD_CHANNEL_LIST //
6975
6976#ifdef CARRIER_DETECTION_SUPPORT
6977INT Set_CarrierDetect_Proc(
6978 IN PRTMP_ADAPTER pAd,
6979 IN PUCHAR arg)
6980{
6981 if (simple_strtol(arg, 0, 10) == 0)
6982 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
6983 else
6984 pAd->CommonCfg.CarrierDetect.Enable = TRUE;
6985
6986 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable));
6987 return TRUE;
6988}
6989#endif // CARRIER_DETECTION_SUPPORT //
6990
6991
6992INT Show_Adhoc_MacTable_Proc(
6993 IN PRTMP_ADAPTER pAd,
6994 IN PCHAR extra)
6995{
6996 INT i;
6997
6998 sprintf(extra, "\n");
6999
7000#ifdef DOT11_N_SUPPORT
7001 sprintf(extra, "%sHT Operating Mode : %d\n", extra, pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode);
7002#endif // DOT11_N_SUPPORT //
7003
7004 sprintf(extra, "%s\n%-19s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n", extra,
7005 "MAC", "AID", "BSS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
7006
7007 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
7008 {
7009 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
7010
7011 if (strlen(extra) > (IW_PRIV_SIZE_MASK - 30))
7012 break;
7013 if ((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
7014 {
7015 sprintf(extra, "%s%02X:%02X:%02X:%02X:%02X:%02X ", extra,
7016 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
7017 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
7018 sprintf(extra, "%s%-4d", extra, (int)pEntry->Aid);
7019 sprintf(extra, "%s%-4d", extra, (int)pEntry->apidx);
7020 sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi0);
7021 sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi1);
7022 sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi2);
7023 sprintf(extra, "%s%-10s", extra, GetPhyMode(pEntry->HTPhyMode.field.MODE));
7024 sprintf(extra, "%s%-6s", extra, GetBW(pEntry->HTPhyMode.field.BW));
7025 sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.MCS);
7026 sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.ShortGI);
7027 sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.STBC);
7028 sprintf(extra, "%s%-10d, %d, %d%%\n", extra, pEntry->DebugFIFOCount, pEntry->DebugTxCount,
7029 (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
7030 sprintf(extra, "%s\n", extra);
7031 }
7032 }
7033
7034 return TRUE;
7035}
7036
7037
diff --git a/drivers/staging/rt2870/tmp61 b/drivers/staging/rt2870/tmp61
new file mode 100644
index 00000000000..992096a248c
--- /dev/null
+++ b/drivers/staging/rt2870/tmp61
@@ -0,0 +1,7037 @@
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
52#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
53#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_A, _B, _C, _D, _E)
54#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_A, _B, _C, _D, _E)
55#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_A, _B, _C, _D, _E, _F)
56#else
57#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_B, _C, _D, _E)
58#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_B, _C, _D, _E)
59#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_B, _C, _D, _E, _F)
60#endif
61
62extern UCHAR CipherWpa2Template[];
63extern UCHAR CipherWpaPskTkip[];
64extern UCHAR CipherWpaPskTkipLen;
65
66typedef struct PACKED _RT_VERSION_INFO{
67 UCHAR DriverVersionW;
68 UCHAR DriverVersionX;
69 UCHAR DriverVersionY;
70 UCHAR DriverVersionZ;
71 UINT DriverBuildYear;
72 UINT DriverBuildMonth;
73 UINT DriverBuildDay;
74} RT_VERSION_INFO, *PRT_VERSION_INFO;
75
76struct iw_priv_args privtab[] = {
77{ RTPRIV_IOCTL_SET,
78 IW_PRIV_TYPE_CHAR | 1024, 0,
79 "set"},
80
81{ RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
82 ""},
83{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
84 ""},
85/* --- sub-ioctls definitions --- */
86 { SHOW_CONN_STATUS,
87 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
88 { SHOW_DRVIER_VERION,
89 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
90 { SHOW_BA_INFO,
91 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
92 { SHOW_DESC_INFO,
93 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
94 { RAIO_OFF,
95 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
96 { RAIO_ON,
97 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
98#ifdef QOS_DLS_SUPPORT
99 { SHOW_DLS_ENTRY_INFO,
100 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "dlsentryinfo" },
101#endif // QOS_DLS_SUPPORT //
102 { SHOW_CFG_VALUE,
103 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
104 { SHOW_ADHOC_ENTRY_INFO,
105 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "adhocEntry" },
106
107/* --- sub-ioctls relations --- */
108
109#ifdef DBG
110{ RTPRIV_IOCTL_BBP,
111 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
112 "bbp"},
113{ RTPRIV_IOCTL_MAC,
114 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
115 "mac"},
116{ RTPRIV_IOCTL_E2P,
117 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
118 "e2p"},
119#endif /* DBG */
120
121{ RTPRIV_IOCTL_STATISTICS,
122 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
123 "stat"},
124{ RTPRIV_IOCTL_GSITESURVEY,
125 0, IW_PRIV_TYPE_CHAR | 1024,
126 "get_site_survey"},
127};
128
129INT Set_SSID_Proc(
130 IN PRTMP_ADAPTER pAdapter,
131 IN PUCHAR arg);
132
133#ifdef WMM_SUPPORT
134INT Set_WmmCapable_Proc(
135 IN PRTMP_ADAPTER pAd,
136 IN PUCHAR arg);
137#endif
138
139INT Set_NetworkType_Proc(
140 IN PRTMP_ADAPTER pAdapter,
141 IN PUCHAR arg);
142
143INT Set_AuthMode_Proc(
144 IN PRTMP_ADAPTER pAdapter,
145 IN PUCHAR arg);
146
147INT Set_EncrypType_Proc(
148 IN PRTMP_ADAPTER pAdapter,
149 IN PUCHAR arg);
150
151INT Set_DefaultKeyID_Proc(
152 IN PRTMP_ADAPTER pAdapter,
153 IN PUCHAR arg);
154
155INT Set_Key1_Proc(
156 IN PRTMP_ADAPTER pAdapter,
157 IN PUCHAR arg);
158
159INT Set_Key2_Proc(
160 IN PRTMP_ADAPTER pAdapter,
161 IN PUCHAR arg);
162
163INT Set_Key3_Proc(
164 IN PRTMP_ADAPTER pAdapter,
165 IN PUCHAR arg);
166
167INT Set_Key4_Proc(
168 IN PRTMP_ADAPTER pAdapter,
169 IN PUCHAR arg);
170
171INT Set_WPAPSK_Proc(
172 IN PRTMP_ADAPTER pAdapter,
173 IN PUCHAR arg);
174
175
176INT Set_PSMode_Proc(
177 IN PRTMP_ADAPTER pAdapter,
178 IN PUCHAR arg);
179
180#ifdef WPA_SUPPLICANT_SUPPORT
181INT Set_Wpa_Support(
182 IN PRTMP_ADAPTER pAd,
183 IN PUCHAR arg);
184#endif // WPA_SUPPLICANT_SUPPORT //
185
186#ifdef DBG
187VOID RTMPIoctlBBP(
188 IN PRTMP_ADAPTER pAdapter,
189 IN struct iwreq *wrq);
190
191VOID RTMPIoctlMAC(
192 IN PRTMP_ADAPTER pAdapter,
193 IN struct iwreq *wrq);
194
195VOID RTMPIoctlE2PROM(
196 IN PRTMP_ADAPTER pAdapter,
197 IN struct iwreq *wrq);
198#endif // DBG //
199
200
201NDIS_STATUS RTMPWPANoneAddKeyProc(
202 IN PRTMP_ADAPTER pAd,
203 IN PVOID pBuf);
204
205INT Set_FragTest_Proc(
206 IN PRTMP_ADAPTER pAdapter,
207 IN PUCHAR arg);
208
209#ifdef DOT11_N_SUPPORT
210INT Set_TGnWifiTest_Proc(
211 IN PRTMP_ADAPTER pAd,
212 IN PUCHAR arg);
213#endif // DOT11_N_SUPPORT //
214
215INT Set_LongRetryLimit_Proc(
216 IN PRTMP_ADAPTER pAdapter,
217 IN PUCHAR arg);
218
219INT Set_ShortRetryLimit_Proc(
220 IN PRTMP_ADAPTER pAdapter,
221 IN PUCHAR arg);
222
223#ifdef EXT_BUILD_CHANNEL_LIST
224INT Set_Ieee80211dClientMode_Proc(
225 IN PRTMP_ADAPTER pAdapter,
226 IN PUCHAR arg);
227#endif // EXT_BUILD_CHANNEL_LIST //
228
229#ifdef CARRIER_DETECTION_SUPPORT
230INT Set_CarrierDetect_Proc(
231 IN PRTMP_ADAPTER pAd,
232 IN PUCHAR arg);
233#endif // CARRIER_DETECTION_SUPPORT //
234
235INT Show_Adhoc_MacTable_Proc(
236 IN PRTMP_ADAPTER pAd,
237 IN PCHAR extra);
238
239static struct {
240 CHAR *name;
241 INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
242} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
243 {"DriverVersion", Set_DriverVersion_Proc},
244 {"CountryRegion", Set_CountryRegion_Proc},
245 {"CountryRegionABand", Set_CountryRegionABand_Proc},
246 {"SSID", Set_SSID_Proc},
247 {"WirelessMode", Set_WirelessMode_Proc},
248 {"TxBurst", Set_TxBurst_Proc},
249 {"TxPreamble", Set_TxPreamble_Proc},
250 {"TxPower", Set_TxPower_Proc},
251 {"Channel", Set_Channel_Proc},
252 {"BGProtection", Set_BGProtection_Proc},
253 {"RTSThreshold", Set_RTSThreshold_Proc},
254 {"FragThreshold", Set_FragThreshold_Proc},
255#ifdef DOT11_N_SUPPORT
256 {"HtBw", Set_HtBw_Proc},
257 {"HtMcs", Set_HtMcs_Proc},
258 {"HtGi", Set_HtGi_Proc},
259 {"HtOpMode", Set_HtOpMode_Proc},
260 {"HtExtcha", Set_HtExtcha_Proc},
261 {"HtMpduDensity", Set_HtMpduDensity_Proc},
262 {"HtBaWinSize", Set_HtBaWinSize_Proc},
263 {"HtRdg", Set_HtRdg_Proc},
264 {"HtAmsdu", Set_HtAmsdu_Proc},
265 {"HtAutoBa", Set_HtAutoBa_Proc},
266 {"HtBaDecline", Set_BADecline_Proc},
267 {"HtProtect", Set_HtProtect_Proc},
268 {"HtMimoPs", Set_HtMimoPs_Proc},
269#endif // DOT11_N_SUPPORT //
270
271#ifdef AGGREGATION_SUPPORT
272 {"PktAggregate", Set_PktAggregate_Proc},
273#endif
274
275#ifdef WMM_SUPPORT
276 {"WmmCapable", Set_WmmCapable_Proc},
277#endif
278 {"IEEE80211H", Set_IEEE80211H_Proc},
279 {"NetworkType", Set_NetworkType_Proc},
280 {"AuthMode", Set_AuthMode_Proc},
281 {"EncrypType", Set_EncrypType_Proc},
282 {"DefaultKeyID", Set_DefaultKeyID_Proc},
283 {"Key1", Set_Key1_Proc},
284 {"Key2", Set_Key2_Proc},
285 {"Key3", Set_Key3_Proc},
286 {"Key4", Set_Key4_Proc},
287 {"WPAPSK", Set_WPAPSK_Proc},
288 {"ResetCounter", Set_ResetStatCounter_Proc},
289 {"PSMode", Set_PSMode_Proc},
290#ifdef DBG
291 {"Debug", Set_Debug_Proc},
292#endif
293
294#ifdef RALINK_ATE
295 {"ATE", Set_ATE_Proc},
296 {"ATEDA", Set_ATE_DA_Proc},
297 {"ATESA", Set_ATE_SA_Proc},
298 {"ATEBSSID", Set_ATE_BSSID_Proc},
299 {"ATECHANNEL", Set_ATE_CHANNEL_Proc},
300 {"ATETXPOW0", Set_ATE_TX_POWER0_Proc},
301 {"ATETXPOW1", Set_ATE_TX_POWER1_Proc},
302 {"ATETXANT", Set_ATE_TX_Antenna_Proc},
303 {"ATERXANT", Set_ATE_RX_Antenna_Proc},
304 {"ATETXFREQOFFSET", Set_ATE_TX_FREQOFFSET_Proc},
305 {"ATETXBW", Set_ATE_TX_BW_Proc},
306 {"ATETXLEN", Set_ATE_TX_LENGTH_Proc},
307 {"ATETXCNT", Set_ATE_TX_COUNT_Proc},
308 {"ATETXMCS", Set_ATE_TX_MCS_Proc},
309 {"ATETXMODE", Set_ATE_TX_MODE_Proc},
310 {"ATETXGI", Set_ATE_TX_GI_Proc},
311 {"ATERXFER", Set_ATE_RX_FER_Proc},
312 {"ATERRF", Set_ATE_Read_RF_Proc},
313 {"ATEWRF1", Set_ATE_Write_RF1_Proc},
314 {"ATEWRF2", Set_ATE_Write_RF2_Proc},
315 {"ATEWRF3", Set_ATE_Write_RF3_Proc},
316 {"ATEWRF4", Set_ATE_Write_RF4_Proc},
317 {"ATELDE2P", Set_ATE_Load_E2P_Proc},
318 {"ATERE2P", Set_ATE_Read_E2P_Proc},
319 {"ATESHOW", Set_ATE_Show_Proc},
320 {"ATEHELP", Set_ATE_Help_Proc},
321
322#ifdef RALINK_28xx_QA
323 {"TxStop", Set_TxStop_Proc},
324 {"RxStop", Set_RxStop_Proc},
325#endif // RALINK_28xx_QA //
326#endif // RALINK_ATE //
327
328#ifdef WPA_SUPPLICANT_SUPPORT
329 {"WpaSupport", Set_Wpa_Support},
330#endif // WPA_SUPPLICANT_SUPPORT //
331
332
333
334 {"FixedTxMode", Set_FixedTxMode_Proc},
335#ifdef CONFIG_APSTA_MIXED_SUPPORT
336 {"OpMode", Set_OpMode_Proc},
337#endif // CONFIG_APSTA_MIXED_SUPPORT //
338#ifdef DOT11_N_SUPPORT
339 {"TGnWifiTest", Set_TGnWifiTest_Proc},
340 {"ForceGF", Set_ForceGF_Proc},
341#endif // DOT11_N_SUPPORT //
342#ifdef QOS_DLS_SUPPORT
343 {"DlsAddEntry", Set_DlsAddEntry_Proc},
344 {"DlsTearDownEntry", Set_DlsTearDownEntry_Proc},
345#endif // QOS_DLS_SUPPORT //
346 {"LongRetry", Set_LongRetryLimit_Proc},
347 {"ShortRetry", Set_ShortRetryLimit_Proc},
348#ifdef EXT_BUILD_CHANNEL_LIST
349 {"11dClientMode", Set_Ieee80211dClientMode_Proc},
350#endif // EXT_BUILD_CHANNEL_LIST //
351#ifdef CARRIER_DETECTION_SUPPORT
352 {"CarrierDetect", Set_CarrierDetect_Proc},
353#endif // CARRIER_DETECTION_SUPPORT //
354
355 {NULL,}
356};
357
358
359VOID RTMPAddKey(
360 IN PRTMP_ADAPTER pAd,
361 IN PNDIS_802_11_KEY pKey)
362{
363 ULONG KeyIdx;
364 MAC_TABLE_ENTRY *pEntry;
365
366 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
367
368 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
369 {
370 if (pKey->KeyIndex & 0x80000000)
371 {
372 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
373 {
374 NdisZeroMemory(pAd->StaCfg.PMK, 32);
375 NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
376 goto end;
377 }
378 // Update PTK
379 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
380 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
381 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
382#ifdef WPA_SUPPLICANT_SUPPORT
383 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
384 {
385 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
386 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
387 }
388 else
389#endif // WPA_SUPPLICANT_SUPPORT //
390 {
391 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
392 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
393 }
394
395 // Decide its ChiperAlg
396 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
397 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
398 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
399 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
400 else
401 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
402
403 // Update these related information to MAC_TABLE_ENTRY
404 pEntry = &pAd->MacTab.Content[BSSID_WCID];
405 NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
406 NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
407 NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
408 pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
409
410 // Update pairwise key information to ASIC Shared Key Table
411 AsicAddSharedKeyEntry(pAd,
412 BSS0,
413 0,
414 pAd->SharedKey[BSS0][0].CipherAlg,
415 pAd->SharedKey[BSS0][0].Key,
416 pAd->SharedKey[BSS0][0].TxMic,
417 pAd->SharedKey[BSS0][0].RxMic);
418
419 // Update ASIC WCID attribute table and IVEIV table
420 RTMPAddWcidAttributeEntry(pAd,
421 BSS0,
422 0,
423 pAd->SharedKey[BSS0][0].CipherAlg,
424 pEntry);
425
426 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
427 {
428 // set 802.1x port control
429 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
430 STA_PORT_SECURED(pAd);
431
432 // Indicate Connected for GUI
433 pAd->IndicateMediaState = NdisMediaStateConnected;
434 }
435 }
436 else
437 {
438 // Update GTK
439 pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
440 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
441 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
442 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
443#ifdef WPA_SUPPLICANT_SUPPORT
444 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
445 {
446 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
447 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
448 }
449 else
450#endif // WPA_SUPPLICANT_SUPPORT //
451 {
452 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
453 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
454 }
455
456 // Update Shared Key CipherAlg
457 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
458 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
459 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
460 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
461 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
462
463 // Update group key information to ASIC Shared Key Table
464 AsicAddSharedKeyEntry(pAd,
465 BSS0,
466 pAd->StaCfg.DefaultKeyId,
467 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
468 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
469 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
470 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
471
472 // Update ASIC WCID attribute table and IVEIV table
473 RTMPAddWcidAttributeEntry(pAd,
474 BSS0,
475 pAd->StaCfg.DefaultKeyId,
476 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
477 NULL);
478
479 // set 802.1x port control
480 //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
481 STA_PORT_SECURED(pAd);
482
483 // Indicate Connected for GUI
484 pAd->IndicateMediaState = NdisMediaStateConnected;
485 }
486 }
487 else // dynamic WEP from wpa_supplicant
488 {
489 UCHAR CipherAlg;
490 PUCHAR Key;
491
492 if(pKey->KeyLength == 32)
493 goto end;
494
495 KeyIdx = pKey->KeyIndex & 0x0fffffff;
496
497 if (KeyIdx < 4)
498 {
499 // it is a default shared key, for Pairwise key setting
500 if (pKey->KeyIndex & 0x80000000)
501 {
502 pEntry = MacTableLookup(pAd, pKey->BSSID);
503
504 if (pEntry)
505 {
506 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
507
508 // set key material and key length
509 pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
510 NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
511
512 // set Cipher type
513 if (pKey->KeyLength == 5)
514 pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
515 else
516 pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
517
518 // Add Pair-wise key to Asic
519 AsicAddPairwiseKeyEntry(
520 pAd,
521 pEntry->Addr,
522 (UCHAR)pEntry->Aid,
523 &pEntry->PairwiseKey);
524
525 // update WCID attribute table and IVEIV table for this entry
526 RTMPAddWcidAttributeEntry(
527 pAd,
528 BSS0,
529 KeyIdx, // The value may be not zero
530 pEntry->PairwiseKey.CipherAlg,
531 pEntry);
532
533 }
534 }
535 else
536 {
537 // Default key for tx (shared key)
538 pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
539
540 // set key material and key length
541 pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
542 NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
543
544 // Set Ciper type
545 if (pKey->KeyLength == 5)
546 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
547 else
548 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
549
550 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
551 Key = pAd->SharedKey[BSS0][KeyIdx].Key;
552
553 // Set Group key material to Asic
554 AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
555
556 // Update WCID attribute table and IVEIV table for this group key table
557 RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
558
559 }
560 }
561 }
562end:
563 return;
564}
565
566char * rtstrchr(const char * s, int c)
567{
568 for(; *s != (char) c; ++s)
569 if (*s == '\0')
570 return NULL;
571 return (char *) s;
572}
573
574/*
575This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
576*/
577
578int
579rt_ioctl_giwname(struct net_device *dev,
580 struct iw_request_info *info,
581 char *name, char *extra)
582{
583// PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
584
585#ifdef RT2870
586 strncpy(name, "RT2870 Wireless", IFNAMSIZ);
587#endif // RT2870 //
588 return 0;
589}
590
591int rt_ioctl_siwfreq(struct net_device *dev,
592 struct iw_request_info *info,
593 struct iw_freq *freq, char *extra)
594{
595 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
596 int chan = -1;
597
598 //check if the interface is down
599 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
600 {
601 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
602 return -ENETDOWN;
603 }
604
605
606 if (freq->e > 1)
607 return -EINVAL;
608
609 if((freq->e == 0) && (freq->m <= 1000))
610 chan = freq->m; // Setting by channel number
611 else
612 MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
613
614 if (ChannelSanity(pAdapter, chan) == TRUE)
615 {
616 pAdapter->CommonCfg.Channel = chan;
617 DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
618 }
619 else
620 return -EINVAL;
621
622 return 0;
623}
624int rt_ioctl_giwfreq(struct net_device *dev,
625 struct iw_request_info *info,
626 struct iw_freq *freq, char *extra)
627{
628 VIRTUAL_ADAPTER *pVirtualAd = NULL;
629 PRTMP_ADAPTER pAdapter = NULL;
630 UCHAR ch;
631 ULONG m;
632
633 if (dev->priv_flags == INT_MAIN)
634 {
635 pAdapter = dev->priv;
636 }
637 else
638 {
639 pVirtualAd = dev->priv;
640 if (pVirtualAd && pVirtualAd->RtmpDev)
641 pAdapter = pVirtualAd->RtmpDev->priv;
642 }
643
644 if (pAdapter == NULL)
645 {
646 /* if 1st open fail, pAd will be free;
647 So the net_dev->priv will be NULL in 2rd open */
648 return -ENETDOWN;
649 }
650
651 ch = pAdapter->CommonCfg.Channel;
652
653 DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq %d\n", ch));
654
655 MAP_CHANNEL_ID_TO_KHZ(ch, m);
656 freq->m = m * 100;
657 freq->e = 1;
658 return 0;
659}
660
661int rt_ioctl_siwmode(struct net_device *dev,
662 struct iw_request_info *info,
663 __u32 *mode, char *extra)
664{
665 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
666
667 //check if the interface is down
668 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
669 {
670 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
671 return -ENETDOWN;
672 }
673
674 switch (*mode)
675 {
676 case IW_MODE_ADHOC:
677 Set_NetworkType_Proc(pAdapter, "Adhoc");
678 break;
679 case IW_MODE_INFRA:
680 Set_NetworkType_Proc(pAdapter, "Infra");
681 break;
682#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
683 case IW_MODE_MONITOR:
684 Set_NetworkType_Proc(pAdapter, "Monitor");
685 break;
686#endif
687 default:
688 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
689 return -EINVAL;
690 }
691
692 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
693 pAdapter->StaCfg.WpaState = SS_NOTUSE;
694
695 return 0;
696}
697
698int rt_ioctl_giwmode(struct net_device *dev,
699 struct iw_request_info *info,
700 __u32 *mode, char *extra)
701{
702 PRTMP_ADAPTER pAdapter = NULL;
703 VIRTUAL_ADAPTER *pVirtualAd = NULL;
704
705 if (dev->priv_flags == INT_MAIN)
706 {
707 pAdapter = dev->priv;
708 }
709 else
710 {
711 pVirtualAd = dev->priv;
712 if (pVirtualAd && pVirtualAd->RtmpDev)
713 pAdapter = pVirtualAd->RtmpDev->priv;
714 }
715
716 if (pAdapter == NULL)
717 {
718 /* if 1st open fail, pAd will be free;
719 So the net_dev->priv will be NULL in 2rd open */
720 return -ENETDOWN;
721 }
722
723 if (ADHOC_ON(pAdapter))
724 *mode = IW_MODE_ADHOC;
725 else if (INFRA_ON(pAdapter))
726 *mode = IW_MODE_INFRA;
727#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
728 else if (MONITOR_ON(pAdapter))
729 {
730 *mode = IW_MODE_MONITOR;
731 }
732#endif
733 else
734 *mode = IW_MODE_AUTO;
735
736 DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
737 return 0;
738}
739
740int rt_ioctl_siwsens(struct net_device *dev,
741 struct iw_request_info *info,
742 char *name, char *extra)
743{
744 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
745
746 //check if the interface is down
747 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
748 {
749 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
750 return -ENETDOWN;
751 }
752
753 return 0;
754}
755
756int rt_ioctl_giwsens(struct net_device *dev,
757 struct iw_request_info *info,
758 char *name, char *extra)
759{
760 return 0;
761}
762
763int rt_ioctl_giwrange(struct net_device *dev,
764 struct iw_request_info *info,
765 struct iw_point *data, char *extra)
766{
767 PRTMP_ADAPTER pAdapter = NULL;
768 VIRTUAL_ADAPTER *pVirtualAd = NULL;
769 struct iw_range *range = (struct iw_range *) extra;
770 u16 val;
771 int i;
772
773 if (dev->priv_flags == INT_MAIN)
774 {
775 pAdapter = dev->priv;
776 }
777 else
778 {
779 pVirtualAd = dev->priv;
780 if (pVirtualAd && pVirtualAd->RtmpDev)
781 pAdapter = pVirtualAd->RtmpDev->priv;
782 }
783
784 if (pAdapter == NULL)
785 {
786 /* if 1st open fail, pAd will be free;
787 So the net_dev->priv will be NULL in 2rd open */
788 return -ENETDOWN;
789 }
790
791 DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
792 data->length = sizeof(struct iw_range);
793 memset(range, 0, sizeof(struct iw_range));
794
795 range->txpower_capa = IW_TXPOW_DBM;
796
797 if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
798 {
799 range->min_pmp = 1 * 1024;
800 range->max_pmp = 65535 * 1024;
801 range->min_pmt = 1 * 1024;
802 range->max_pmt = 1000 * 1024;
803 range->pmp_flags = IW_POWER_PERIOD;
804 range->pmt_flags = IW_POWER_TIMEOUT;
805 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
806 IW_POWER_UNICAST_R | IW_POWER_ALL_R;
807 }
808
809 range->we_version_compiled = WIRELESS_EXT;
810 range->we_version_source = 14;
811
812 range->retry_capa = IW_RETRY_LIMIT;
813 range->retry_flags = IW_RETRY_LIMIT;
814 range->min_retry = 0;
815 range->max_retry = 255;
816
817 range->num_channels = pAdapter->ChannelListNum;
818
819 val = 0;
820 for (i = 1; i <= range->num_channels; i++)
821 {
822 u32 m;
823 range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
824 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
825 range->freq[val].m = m * 100; /* HZ */
826
827 range->freq[val].e = 1;
828 val++;
829 if (val == IW_MAX_FREQUENCIES)
830 break;
831 }
832 range->num_frequency = val;
833
834 range->max_qual.qual = 100; /* what is correct max? This was not
835 * documented exactly. At least
836 * 69 has been observed. */
837 range->max_qual.level = 0; /* dB */
838 range->max_qual.noise = 0; /* dB */
839
840 /* What would be suitable values for "average/typical" qual? */
841 range->avg_qual.qual = 20;
842 range->avg_qual.level = -60;
843 range->avg_qual.noise = -95;
844 range->sensitivity = 3;
845
846 range->max_encoding_tokens = NR_WEP_KEYS;
847 range->num_encoding_sizes = 2;
848 range->encoding_size[0] = 5;
849 range->encoding_size[1] = 13;
850
851 range->min_rts = 0;
852 range->max_rts = 2347;
853 range->min_frag = 256;
854 range->max_frag = 2346;
855
856#if WIRELESS_EXT > 17
857 /* IW_ENC_CAPA_* bit field */
858 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
859 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
860#endif
861
862 return 0;
863}
864
865int rt_ioctl_siwap(struct net_device *dev,
866 struct iw_request_info *info,
867 struct sockaddr *ap_addr, char *extra)
868{
869 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
870 NDIS_802_11_MAC_ADDRESS Bssid;
871
872 //check if the interface is down
873 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
874 {
875 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
876 return -ENETDOWN;
877 }
878
879 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
880 {
881 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
882 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
883 }
884
885 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
886 // this request, because this request is initiated by NDIS.
887 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
888 // Prevent to connect AP again in STAMlmePeriodicExec
889 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
890
891 memset(Bssid, 0, MAC_ADDR_LEN);
892 memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
893 MlmeEnqueue(pAdapter,
894 MLME_CNTL_STATE_MACHINE,
895 OID_802_11_BSSID,
896 sizeof(NDIS_802_11_MAC_ADDRESS),
897 (VOID *)&Bssid);
898
899 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
900 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
901
902 return 0;
903}
904
905int rt_ioctl_giwap(struct net_device *dev,
906 struct iw_request_info *info,
907 struct sockaddr *ap_addr, char *extra)
908{
909 PRTMP_ADAPTER pAdapter = NULL;
910 VIRTUAL_ADAPTER *pVirtualAd = NULL;
911
912 if (dev->priv_flags == INT_MAIN)
913 {
914 pAdapter = dev->priv;
915 }
916 else
917 {
918 pVirtualAd = dev->priv;
919 if (pVirtualAd && pVirtualAd->RtmpDev)
920 pAdapter = pVirtualAd->RtmpDev->priv;
921 }
922
923 if (pAdapter == NULL)
924 {
925 /* if 1st open fail, pAd will be free;
926 So the net_dev->priv will be NULL in 2rd open */
927 return -ENETDOWN;
928 }
929
930 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
931 {
932 ap_addr->sa_family = ARPHRD_ETHER;
933 memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
934 }
935#ifdef WPA_SUPPLICANT_SUPPORT
936 // Add for RT2870
937 else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
938 {
939 ap_addr->sa_family = ARPHRD_ETHER;
940 memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
941 }
942#endif // WPA_SUPPLICANT_SUPPORT //
943 else
944 {
945 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
946 return -ENOTCONN;
947 }
948
949 return 0;
950}
951
952/*
953 * Units are in db above the noise floor. That means the
954 * rssi values reported in the tx/rx descriptors in the
955 * driver are the SNR expressed in db.
956 *
957 * If you assume that the noise floor is -95, which is an
958 * excellent assumption 99.5 % of the time, then you can
959 * derive the absolute signal level (i.e. -95 + rssi).
960 * There are some other slight factors to take into account
961 * depending on whether the rssi measurement is from 11b,
962 * 11g, or 11a. These differences are at most 2db and
963 * can be documented.
964 *
965 * NB: various calculations are based on the orinoco/wavelan
966 * drivers for compatibility
967 */
968static void set_quality(PRTMP_ADAPTER pAdapter,
969 struct iw_quality *iq,
970 signed char rssi)
971{
972 __u8 ChannelQuality;
973
974 // Normalize Rssi
975 if (rssi >= -50)
976 ChannelQuality = 100;
977 else if (rssi >= -80) // between -50 ~ -80dbm
978 ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
979 else if (rssi >= -90) // between -80 ~ -90dbm
980 ChannelQuality = (__u8)((rssi + 90) * 26)/10;
981 else
982 ChannelQuality = 0;
983
984 iq->qual = (__u8)ChannelQuality;
985
986 iq->level = (__u8)(rssi);
987 iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); // noise level (dBm)
988 iq->noise += 256 - 143;
989 iq->updated = pAdapter->iw_stats.qual.updated;
990}
991
992int rt_ioctl_iwaplist(struct net_device *dev,
993 struct iw_request_info *info,
994 struct iw_point *data, char *extra)
995{
996 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
997
998 struct sockaddr addr[IW_MAX_AP];
999 struct iw_quality qual[IW_MAX_AP];
1000 int i;
1001
1002 //check if the interface is down
1003 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1004 {
1005 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1006 data->length = 0;
1007 return 0;
1008 //return -ENETDOWN;
1009 }
1010
1011 for (i = 0; i <IW_MAX_AP ; i++)
1012 {
1013 if (i >= pAdapter->ScanTab.BssNr)
1014 break;
1015 addr[i].sa_family = ARPHRD_ETHER;
1016 memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
1017 set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
1018 }
1019 data->length = i;
1020 memcpy(extra, &addr, i*sizeof(addr[0]));
1021 data->flags = 1; /* signal quality present (sort of) */
1022 memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
1023
1024 return 0;
1025}
1026
1027#ifdef SIOCGIWSCAN
1028int rt_ioctl_siwscan(struct net_device *dev,
1029 struct iw_request_info *info,
1030 struct iw_point *data, char *extra)
1031{
1032 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1033
1034 ULONG Now;
1035 int Status = NDIS_STATUS_SUCCESS;
1036
1037 //check if the interface is down
1038 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1039 {
1040 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1041 return -ENETDOWN;
1042 }
1043
1044 if (MONITOR_ON(pAdapter))
1045 {
1046 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
1047 return -EINVAL;
1048 }
1049
1050
1051#ifdef WPA_SUPPLICANT_SUPPORT
1052 if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
1053 {
1054 pAdapter->StaCfg.WpaSupplicantScanCount++;
1055 }
1056#endif // WPA_SUPPLICANT_SUPPORT //
1057
1058 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
1059 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1060 return 0;
1061 do{
1062 Now = jiffies;
1063
1064#ifdef WPA_SUPPLICANT_SUPPORT
1065 if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
1066 (pAdapter->StaCfg.WpaSupplicantScanCount > 3))
1067 {
1068 DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
1069 Status = NDIS_STATUS_SUCCESS;
1070 break;
1071 }
1072#endif // WPA_SUPPLICANT_SUPPORT //
1073
1074 if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
1075 ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1076 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
1077 (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1078 {
1079 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
1080 Status = NDIS_STATUS_SUCCESS;
1081 break;
1082 }
1083
1084 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
1085 {
1086 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
1087 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
1088 }
1089
1090 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
1091 // this request, because this request is initiated by NDIS.
1092 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
1093 // Reset allowed scan retries
1094 pAdapter->StaCfg.ScanCnt = 0;
1095 pAdapter->StaCfg.LastScanTime = Now;
1096
1097 MlmeEnqueue(pAdapter,
1098 MLME_CNTL_STATE_MACHINE,
1099 OID_802_11_BSSID_LIST_SCAN,
1100 0,
1101 NULL);
1102
1103 Status = NDIS_STATUS_SUCCESS;
1104 RT28XX_MLME_HANDLER(pAdapter);
1105 }while(0);
1106 return 0;
1107}
1108
1109int rt_ioctl_giwscan(struct net_device *dev,
1110 struct iw_request_info *info,
1111 struct iw_point *data, char *extra)
1112{
1113
1114 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1115 int i=0;
1116 char *current_ev = extra, *previous_ev = extra;
1117 char *end_buf;
1118 char *current_val, custom[MAX_CUSTOM_LEN] = {0};
1119#ifndef IWEVGENIE
1120 char idx;
1121#endif // IWEVGENIE //
1122 struct iw_event iwe;
1123
1124 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1125 {
1126 /*
1127 * Still scanning, indicate the caller should try again.
1128 */
1129 return -EAGAIN;
1130 }
1131
1132
1133#ifdef WPA_SUPPLICANT_SUPPORT
1134 if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
1135 {
1136 pAdapter->StaCfg.WpaSupplicantScanCount = 0;
1137 }
1138#endif // WPA_SUPPLICANT_SUPPORT //
1139
1140 if (pAdapter->ScanTab.BssNr == 0)
1141 {
1142 data->length = 0;
1143 return 0;
1144 }
1145
1146#if WIRELESS_EXT >= 17
1147 if (data->length > 0)
1148 end_buf = extra + data->length;
1149 else
1150 end_buf = extra + IW_SCAN_MAX_DATA;
1151#else
1152 end_buf = extra + IW_SCAN_MAX_DATA;
1153#endif
1154
1155 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
1156 {
1157 if (current_ev >= end_buf)
1158 {
1159#if WIRELESS_EXT >= 17
1160 return -E2BIG;
1161#else
1162 break;
1163#endif
1164 }
1165
1166 //MAC address
1167 //================================
1168 memset(&iwe, 0, sizeof(iwe));
1169 iwe.cmd = SIOCGIWAP;
1170 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1171 memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
1172
1173 previous_ev = current_ev;
1174 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
1175 if (current_ev == previous_ev)
1176#if WIRELESS_EXT >= 17
1177 return -E2BIG;
1178#else
1179 break;
1180#endif
1181
1182 //ESSID
1183 //================================
1184 memset(&iwe, 0, sizeof(iwe));
1185 iwe.cmd = SIOCGIWESSID;
1186 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
1187 iwe.u.data.flags = 1;
1188
1189 previous_ev = current_ev;
1190 current_ev = IWE_STREAM_ADD_POINT(info, current_ev,end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
1191 if (current_ev == previous_ev)
1192#if WIRELESS_EXT >= 17
1193 return -E2BIG;
1194#else
1195 break;
1196#endif
1197
1198 //Network Type
1199 //================================
1200 memset(&iwe, 0, sizeof(iwe));
1201 iwe.cmd = SIOCGIWMODE;
1202 if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
1203 {
1204 iwe.u.mode = IW_MODE_ADHOC;
1205 }
1206 else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
1207 {
1208 iwe.u.mode = IW_MODE_INFRA;
1209 }
1210 else
1211 {
1212 iwe.u.mode = IW_MODE_AUTO;
1213 }
1214 iwe.len = IW_EV_UINT_LEN;
1215
1216 previous_ev = current_ev;
1217 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
1218 if (current_ev == previous_ev)
1219#if WIRELESS_EXT >= 17
1220 return -E2BIG;
1221#else
1222 break;
1223#endif
1224
1225 //Channel and Frequency
1226 //================================
1227 memset(&iwe, 0, sizeof(iwe));
1228 iwe.cmd = SIOCGIWFREQ;
1229 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
1230 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1231 else
1232 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1233 iwe.u.freq.e = 0;
1234 iwe.u.freq.i = 0;
1235
1236 previous_ev = current_ev;
1237 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
1238 if (current_ev == previous_ev)
1239#if WIRELESS_EXT >= 17
1240 return -E2BIG;
1241#else
1242 break;
1243#endif
1244
1245 //Add quality statistics
1246 //================================
1247 memset(&iwe, 0, sizeof(iwe));
1248 iwe.cmd = IWEVQUAL;
1249 iwe.u.qual.level = 0;
1250 iwe.u.qual.noise = 0;
1251 set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
1252 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
1253 if (current_ev == previous_ev)
1254#if WIRELESS_EXT >= 17
1255 return -E2BIG;
1256#else
1257 break;
1258#endif
1259
1260 //Encyption key
1261 //================================
1262 memset(&iwe, 0, sizeof(iwe));
1263 iwe.cmd = SIOCGIWENCODE;
1264 if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
1265 iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1266 else
1267 iwe.u.data.flags = IW_ENCODE_DISABLED;
1268
1269 previous_ev = current_ev;
1270 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);
1271 if (current_ev == previous_ev)
1272#if WIRELESS_EXT >= 17
1273 return -E2BIG;
1274#else
1275 break;
1276#endif
1277
1278 //Bit Rate
1279 //================================
1280 if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
1281 {
1282 UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
1283 memset(&iwe, 0, sizeof(iwe));
1284 iwe.cmd = SIOCGIWRATE;
1285 current_val = current_ev + IW_EV_LCP_LEN;
1286 if (tmpRate == 0x82)
1287 iwe.u.bitrate.value = 1 * 1000000;
1288 else if (tmpRate == 0x84)
1289 iwe.u.bitrate.value = 2 * 1000000;
1290 else if (tmpRate == 0x8B)
1291 iwe.u.bitrate.value = 5.5 * 1000000;
1292 else if (tmpRate == 0x96)
1293 iwe.u.bitrate.value = 11 * 1000000;
1294 else
1295 iwe.u.bitrate.value = (tmpRate/2) * 1000000;
1296
1297 iwe.u.bitrate.disabled = 0;
1298 current_val = IWE_STREAM_ADD_VALUE(info, current_ev,
1299 current_val, end_buf, &iwe,
1300 IW_EV_PARAM_LEN);
1301
1302 if((current_val-current_ev)>IW_EV_LCP_LEN)
1303 current_ev = current_val;
1304 else
1305#if WIRELESS_EXT >= 17
1306 return -E2BIG;
1307#else
1308 break;
1309#endif
1310 }
1311
1312#ifdef IWEVGENIE
1313 //WPA IE
1314 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1315 {
1316 memset(&iwe, 0, sizeof(iwe));
1317 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1318 memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
1319 pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
1320 iwe.cmd = IWEVGENIE;
1321 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
1322 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1323 if (current_ev == previous_ev)
1324#if WIRELESS_EXT >= 17
1325 return -E2BIG;
1326#else
1327 break;
1328#endif
1329 }
1330
1331 //WPA2 IE
1332 if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1333 {
1334 memset(&iwe, 0, sizeof(iwe));
1335 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1336 memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
1337 pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
1338 iwe.cmd = IWEVGENIE;
1339 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
1340 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1341 if (current_ev == previous_ev)
1342#if WIRELESS_EXT >= 17
1343 return -E2BIG;
1344#else
1345 break;
1346#endif
1347 }
1348#else
1349 //WPA IE
1350 //================================
1351 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1352 {
1353 NdisZeroMemory(&iwe, sizeof(iwe));
1354 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1355 iwe.cmd = IWEVCUSTOM;
1356 iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen * 2) + 7;
1357 NdisMoveMemory(custom, "wpa_ie=", 7);
1358 for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].WpaIE.IELen; idx++)
1359 sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].WpaIE.IE[idx]);
1360 previous_ev = current_ev;
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
1370 //WPA2 IE
1371 if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1372 {
1373 NdisZeroMemory(&iwe, sizeof(iwe));
1374 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1375 iwe.cmd = IWEVCUSTOM;
1376 iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen * 2) + 7;
1377 NdisMoveMemory(custom, "rsn_ie=", 7);
1378 for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].RsnIE.IELen; idx++)
1379 sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].RsnIE.IE[idx]);
1380 previous_ev = current_ev;
1381 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1382 if (current_ev == previous_ev)
1383#if WIRELESS_EXT >= 17
1384 return -E2BIG;
1385#else
1386 break;
1387#endif
1388 }
1389#endif // IWEVGENIE //
1390 }
1391
1392 data->length = current_ev - extra;
1393 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
1394 DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
1395 return 0;
1396}
1397#endif
1398
1399int rt_ioctl_siwessid(struct net_device *dev,
1400 struct iw_request_info *info,
1401 struct iw_point *data, char *essid)
1402{
1403 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1404
1405 //check if the interface is down
1406 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1407 {
1408 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1409 return -ENETDOWN;
1410 }
1411
1412 if (data->flags)
1413 {
1414 PCHAR pSsidString = NULL;
1415
1416 // Includes null character.
1417 if (data->length > (IW_ESSID_MAX_SIZE + 1))
1418 return -E2BIG;
1419
1420 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
1421 if (pSsidString)
1422 {
1423 NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
1424 NdisMoveMemory(pSsidString, essid, data->length);
1425 if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
1426 return -EINVAL;
1427 }
1428 else
1429 return -ENOMEM;
1430 }
1431 else
1432 {
1433 // ANY ssid
1434 if (Set_SSID_Proc(pAdapter, "") == FALSE)
1435 return -EINVAL;
1436 }
1437 return 0;
1438}
1439
1440int rt_ioctl_giwessid(struct net_device *dev,
1441 struct iw_request_info *info,
1442 struct iw_point *data, char *essid)
1443{
1444 PRTMP_ADAPTER pAdapter = NULL;
1445 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1446
1447 if (dev->priv_flags == INT_MAIN)
1448 {
1449 pAdapter = dev->priv;
1450 }
1451 else
1452 {
1453 pVirtualAd = dev->priv;
1454 if (pVirtualAd && pVirtualAd->RtmpDev)
1455 pAdapter = pVirtualAd->RtmpDev->priv;
1456 }
1457
1458 if (pAdapter == NULL)
1459 {
1460 /* if 1st open fail, pAd will be free;
1461 So the net_dev->priv will be NULL in 2rd open */
1462 return -ENETDOWN;
1463 }
1464
1465 data->flags = 1;
1466 if (MONITOR_ON(pAdapter))
1467 {
1468 data->length = 0;
1469 return 0;
1470 }
1471
1472 if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
1473 {
1474 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
1475 data->length = pAdapter->CommonCfg.SsidLen;
1476 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1477 }
1478#ifdef RT2870
1479#ifdef WPA_SUPPLICANT_SUPPORT
1480 // Add for RT2870
1481 else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1482 {
1483 data->length = pAdapter->CommonCfg.SsidLen;
1484 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1485 }
1486#endif // WPA_SUPPLICANT_SUPPORT //
1487#endif // RT2870 //
1488 else
1489 {//the ANY ssid was specified
1490 data->length = 0;
1491 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
1492 }
1493
1494 return 0;
1495
1496}
1497
1498int rt_ioctl_siwnickn(struct net_device *dev,
1499 struct iw_request_info *info,
1500 struct iw_point *data, char *nickname)
1501{
1502 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1503
1504 //check if the interface is down
1505 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1506 {
1507 DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
1508 return -ENETDOWN;
1509 }
1510
1511 if (data->length > IW_ESSID_MAX_SIZE)
1512 return -EINVAL;
1513
1514 memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
1515 memcpy(pAdapter->nickname, nickname, data->length);
1516
1517
1518 return 0;
1519}
1520
1521int rt_ioctl_giwnickn(struct net_device *dev,
1522 struct iw_request_info *info,
1523 struct iw_point *data, char *nickname)
1524{
1525 PRTMP_ADAPTER pAdapter = NULL;
1526 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1527
1528 if (dev->priv_flags == INT_MAIN)
1529 {
1530 pAdapter = dev->priv;
1531 }
1532 else
1533 {
1534 pVirtualAd = dev->priv;
1535 if (pVirtualAd && pVirtualAd->RtmpDev)
1536 pAdapter = pVirtualAd->RtmpDev->priv;
1537 }
1538
1539 if (pAdapter == NULL)
1540 {
1541 /* if 1st open fail, pAd will be free;
1542 So the net_dev->priv will be NULL in 2rd open */
1543 return -ENETDOWN;
1544 }
1545
1546 if (data->length > strlen(pAdapter->nickname) + 1)
1547 data->length = strlen(pAdapter->nickname) + 1;
1548 if (data->length > 0) {
1549 memcpy(nickname, pAdapter->nickname, data->length-1);
1550 nickname[data->length-1] = '\0';
1551 }
1552 return 0;
1553}
1554
1555int rt_ioctl_siwrts(struct net_device *dev,
1556 struct iw_request_info *info,
1557 struct iw_param *rts, char *extra)
1558{
1559 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1560 u16 val;
1561
1562 //check if the interface is down
1563 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1564 {
1565 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1566 return -ENETDOWN;
1567 }
1568
1569 if (rts->disabled)
1570 val = MAX_RTS_THRESHOLD;
1571 else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
1572 return -EINVAL;
1573 else if (rts->value == 0)
1574 val = MAX_RTS_THRESHOLD;
1575 else
1576 val = rts->value;
1577
1578 if (val != pAdapter->CommonCfg.RtsThreshold)
1579 pAdapter->CommonCfg.RtsThreshold = val;
1580
1581 return 0;
1582}
1583
1584int rt_ioctl_giwrts(struct net_device *dev,
1585 struct iw_request_info *info,
1586 struct iw_param *rts, char *extra)
1587{
1588 PRTMP_ADAPTER pAdapter = NULL;
1589 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1590
1591 if (dev->priv_flags == INT_MAIN)
1592 {
1593 pAdapter = dev->priv;
1594 }
1595 else
1596 {
1597 pVirtualAd = dev->priv;
1598 if (pVirtualAd && pVirtualAd->RtmpDev)
1599 pAdapter = pVirtualAd->RtmpDev->priv;
1600 }
1601
1602 if (pAdapter == NULL)
1603 {
1604 /* if 1st open fail, pAd will be free;
1605 So the net_dev->priv will be NULL in 2rd open */
1606 return -ENETDOWN;
1607 }
1608
1609 //check if the interface is down
1610 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1611 {
1612 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1613 return -ENETDOWN;
1614 }
1615
1616 rts->value = pAdapter->CommonCfg.RtsThreshold;
1617 rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
1618 rts->fixed = 1;
1619
1620 return 0;
1621}
1622
1623int rt_ioctl_siwfrag(struct net_device *dev,
1624 struct iw_request_info *info,
1625 struct iw_param *frag, char *extra)
1626{
1627 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1628 u16 val;
1629
1630 //check if the interface is down
1631 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1632 {
1633 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1634 return -ENETDOWN;
1635 }
1636
1637 if (frag->disabled)
1638 val = MAX_FRAG_THRESHOLD;
1639 else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
1640 val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
1641 else if (frag->value == 0)
1642 val = MAX_FRAG_THRESHOLD;
1643 else
1644 return -EINVAL;
1645
1646 pAdapter->CommonCfg.FragmentThreshold = val;
1647 return 0;
1648}
1649
1650int rt_ioctl_giwfrag(struct net_device *dev,
1651 struct iw_request_info *info,
1652 struct iw_param *frag, char *extra)
1653{
1654 PRTMP_ADAPTER pAdapter = NULL;
1655 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1656
1657 if (dev->priv_flags == INT_MAIN)
1658 {
1659 pAdapter = dev->priv;
1660 }
1661 else
1662 {
1663 pVirtualAd = dev->priv;
1664 if (pVirtualAd && pVirtualAd->RtmpDev)
1665 pAdapter = pVirtualAd->RtmpDev->priv;
1666 }
1667
1668 if (pAdapter == NULL)
1669 {
1670 /* if 1st open fail, pAd will be free;
1671 So the net_dev->priv will be NULL in 2rd open */
1672 return -ENETDOWN;
1673 }
1674
1675 //check if the interface is down
1676 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1677 {
1678 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1679 return -ENETDOWN;
1680 }
1681
1682 frag->value = pAdapter->CommonCfg.FragmentThreshold;
1683 frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
1684 frag->fixed = 1;
1685
1686 return 0;
1687}
1688
1689#define MAX_WEP_KEY_SIZE 13
1690#define MIN_WEP_KEY_SIZE 5
1691int rt_ioctl_siwencode(struct net_device *dev,
1692 struct iw_request_info *info,
1693 struct iw_point *erq, char *extra)
1694{
1695 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1696
1697 //check if the interface is down
1698 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1699 {
1700 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1701 return -ENETDOWN;
1702 }
1703
1704 if ((erq->length == 0) &&
1705 (erq->flags & IW_ENCODE_DISABLED))
1706 {
1707 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1708 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1709 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1710 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1711 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1712 goto done;
1713 }
1714 else if ((erq->length == 0) &&
1715 (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN))
1716 {
1717 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1718 STA_PORT_SECURED(pAdapter);
1719 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1720 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1721 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1722 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1723 if (erq->flags & IW_ENCODE_RESTRICTED)
1724 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1725 else
1726 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1727 goto done;
1728 }
1729
1730 if (erq->length > 0)
1731 {
1732 int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
1733 /* Check the size of the key */
1734 if (erq->length > MAX_WEP_KEY_SIZE) {
1735 return -EINVAL;
1736 }
1737 /* Check key index */
1738 if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
1739 {
1740 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
1741 keyIdx, pAdapter->StaCfg.DefaultKeyId));
1742
1743 //Using default key
1744 keyIdx = pAdapter->StaCfg.DefaultKeyId;
1745 }
1746
1747 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
1748
1749 if (erq->length == MAX_WEP_KEY_SIZE)
1750 {
1751 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
1752 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
1753 }
1754 else if (erq->length == MIN_WEP_KEY_SIZE)
1755 {
1756 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
1757 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
1758 }
1759 else
1760 /* Disable the key */
1761 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
1762
1763 /* Check if the key is not marked as invalid */
1764 if(!(erq->flags & IW_ENCODE_NOKEY)) {
1765 /* Copy the key in the driver */
1766 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
1767 }
1768 }
1769 else
1770 {
1771 /* Do we want to just set the transmit key index ? */
1772 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
1773 if ((index >= 0) && (index < 4))
1774 {
1775 pAdapter->StaCfg.DefaultKeyId = index;
1776 }
1777 else
1778 /* Don't complain if only change the mode */
1779 if(!erq->flags & IW_ENCODE_MODE) {
1780 return -EINVAL;
1781 }
1782 }
1783
1784done:
1785 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
1786 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
1787 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
1788 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
1789 return 0;
1790}
1791
1792int
1793rt_ioctl_giwencode(struct net_device *dev,
1794 struct iw_request_info *info,
1795 struct iw_point *erq, char *key)
1796{
1797 int kid;
1798 PRTMP_ADAPTER pAdapter = NULL;
1799 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1800
1801 if (dev->priv_flags == INT_MAIN)
1802 {
1803 pAdapter = dev->priv;
1804 }
1805 else
1806 {
1807 pVirtualAd = dev->priv;
1808 if (pVirtualAd && pVirtualAd->RtmpDev)
1809 pAdapter = pVirtualAd->RtmpDev->priv;
1810 }
1811
1812 if (pAdapter == NULL)
1813 {
1814 /* if 1st open fail, pAd will be free;
1815 So the net_dev->priv will be NULL in 2rd open */
1816 return -ENETDOWN;
1817 }
1818
1819 //check if the interface is down
1820 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1821 {
1822 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1823 return -ENETDOWN;
1824 }
1825
1826 kid = erq->flags & IW_ENCODE_INDEX;
1827 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
1828
1829 if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
1830 {
1831 erq->length = 0;
1832 erq->flags = IW_ENCODE_DISABLED;
1833 }
1834 else if ((kid > 0) && (kid <=4))
1835 {
1836 // copy wep key
1837 erq->flags = kid ; /* NB: base 1 */
1838 if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
1839 erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
1840 memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
1841 //if ((kid == pAdapter->PortCfg.DefaultKeyId))
1842 //erq->flags |= IW_ENCODE_ENABLED; /* XXX */
1843 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1844 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1845 else
1846 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1847
1848 }
1849 else if (kid == 0)
1850 {
1851 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1852 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1853 else
1854 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1855 erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
1856 memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
1857 // copy default key ID
1858 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1859 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1860 else
1861 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1862 erq->flags = pAdapter->StaCfg.DefaultKeyId + 1; /* NB: base 1 */
1863 erq->flags |= IW_ENCODE_ENABLED; /* XXX */
1864 }
1865
1866 return 0;
1867
1868}
1869
1870static int
1871rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
1872 void *w, char *extra)
1873{
1874 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1875 PRTMP_ADAPTER pAdapter;
1876 POS_COOKIE pObj;
1877 char *this_char = extra;
1878 char *value;
1879 int Status=0;
1880
1881 if (dev->priv_flags == INT_MAIN)
1882 {
1883 pAdapter = dev->priv;
1884 }
1885 else
1886 {
1887 pVirtualAd = dev->priv;
1888 pAdapter = pVirtualAd->RtmpDev->priv;
1889 }
1890 pObj = (POS_COOKIE) pAdapter->OS_Cookie;
1891
1892 if (pAdapter == NULL)
1893 {
1894 /* if 1st open fail, pAd will be free;
1895 So the net_dev->priv will be NULL in 2rd open */
1896 return -ENETDOWN;
1897 }
1898
1899 {
1900 pObj->ioctl_if_type = INT_MAIN;
1901 pObj->ioctl_if = MAIN_MBSSID;
1902 }
1903
1904 //check if the interface is down
1905 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1906 {
1907 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1908 return -ENETDOWN;
1909 }
1910
1911 if (!*this_char)
1912 return -EINVAL;
1913
1914 if ((value = rtstrchr(this_char, '=')) != NULL)
1915 *value++ = 0;
1916
1917 if (!value)
1918 return -EINVAL;
1919
1920 // reject setting nothing besides ANY ssid(ssidLen=0)
1921 if (!*value && (strcmp(this_char, "SSID") != 0))
1922 return -EINVAL;
1923
1924 for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
1925 {
1926 if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
1927 {
1928 if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
1929 { //FALSE:Set private failed then return Invalid argument
1930 Status = -EINVAL;
1931 }
1932 break; //Exit for loop.
1933 }
1934 }
1935
1936 if(PRTMP_PRIVATE_SET_PROC->name == NULL)
1937 { //Not found argument
1938 Status = -EINVAL;
1939 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
1940 }
1941
1942 return Status;
1943}
1944
1945
1946static int
1947rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
1948 struct iw_point *wrq, char *extra)
1949{
1950 INT Status = 0;
1951 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
1952
1953 if (extra == NULL)
1954 {
1955 wrq->length = 0;
1956 return -EIO;
1957 }
1958
1959 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
1960 sprintf(extra, "\n\n");
1961
1962#ifdef RALINK_ATE
1963 if (ATE_ON(pAd))
1964 {
1965 sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->ate.TxDoneCount);
1966 //sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->ate.TxDoneCount);
1967 }
1968 else
1969#endif // RALINK_ATE //
1970 {
1971 sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
1972 sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1973 }
1974 sprintf(extra+strlen(extra), "Tx success after retry = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1975 sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
1976 sprintf(extra+strlen(extra), "RTS Success Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
1977 sprintf(extra+strlen(extra), "RTS Fail Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
1978
1979 sprintf(extra+strlen(extra), "Rx success = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
1980 sprintf(extra+strlen(extra), "Rx with CRC = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
1981 sprintf(extra+strlen(extra), "Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
1982 sprintf(extra+strlen(extra), "Rx duplicate frame = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
1983
1984 sprintf(extra+strlen(extra), "False CCA (one second) = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
1985#ifdef RALINK_ATE
1986 if (ATE_ON(pAd))
1987 {
1988 if (pAd->ate.RxAntennaSel == 0)
1989 {
1990 sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
1991 sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta));
1992 sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta));
1993 }
1994 else
1995 {
1996 sprintf(extra+strlen(extra), "RSSI = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
1997 }
1998 }
1999 else
2000#endif // RALINK_ATE //
2001 {
2002 sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
2003 sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
2004 sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
2005 }
2006#ifdef WPA_SUPPLICANT_SUPPORT
2007 sprintf(extra+strlen(extra), "WpaSupplicantUP = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
2008#endif // WPA_SUPPLICANT_SUPPORT //
2009
2010
2011 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2012 DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
2013
2014 return Status;
2015}
2016
2017#ifdef DOT11_N_SUPPORT
2018void getBaInfo(
2019 IN PRTMP_ADAPTER pAd,
2020 IN PUCHAR pOutBuf)
2021{
2022 INT i, j;
2023 BA_ORI_ENTRY *pOriBAEntry;
2024 BA_REC_ENTRY *pRecBAEntry;
2025
2026 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
2027 {
2028 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
2029 if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
2030 || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
2031 {
2032 sprintf(pOutBuf, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
2033 pOutBuf,
2034 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2035 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
2036
2037 sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
2038 for (j=0; j < NUM_OF_TID; j++)
2039 {
2040 if (pEntry->BARecWcidArray[j] != 0)
2041 {
2042 pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
2043 sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
2044 }
2045 }
2046 sprintf(pOutBuf, "%s\n", pOutBuf);
2047
2048 sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
2049 for (j=0; j < NUM_OF_TID; j++)
2050 {
2051 if (pEntry->BAOriWcidArray[j] != 0)
2052 {
2053 pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
2054 sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
2055 }
2056 }
2057 sprintf(pOutBuf, "%s\n\n", pOutBuf);
2058 }
2059 if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
2060 break;
2061 }
2062
2063 return;
2064}
2065#endif // DOT11_N_SUPPORT //
2066
2067static int
2068rt_private_show(struct net_device *dev, struct iw_request_info *info,
2069 struct iw_point *wrq, char *extra)
2070{
2071 INT Status = 0;
2072 VIRTUAL_ADAPTER *pVirtualAd = NULL;
2073 PRTMP_ADAPTER pAd;
2074 POS_COOKIE pObj;
2075 u32 subcmd = wrq->flags;
2076
2077 if (dev->priv_flags == INT_MAIN)
2078 pAd = dev->priv;
2079 else
2080 {
2081 pVirtualAd = dev->priv;
2082 pAd = pVirtualAd->RtmpDev->priv;
2083 }
2084 pObj = (POS_COOKIE) pAd->OS_Cookie;
2085
2086 if (pAd == NULL)
2087 {
2088 /* if 1st open fail, pAd will be free;
2089 So the net_dev->priv will be NULL in 2rd open */
2090 return -ENETDOWN;
2091 }
2092
2093 if (extra == NULL)
2094 {
2095 wrq->length = 0;
2096 return -EIO;
2097 }
2098 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2099
2100 {
2101 pObj->ioctl_if_type = INT_MAIN;
2102 pObj->ioctl_if = MAIN_MBSSID;
2103 }
2104
2105 switch(subcmd)
2106 {
2107
2108 case SHOW_CONN_STATUS:
2109 if (MONITOR_ON(pAd))
2110 {
2111#ifdef DOT11_N_SUPPORT
2112 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
2113 pAd->CommonCfg.RegTransmitSetting.field.BW)
2114 sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
2115 else
2116#endif // DOT11_N_SUPPORT //
2117 sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
2118 }
2119 else
2120 {
2121 if (pAd->IndicateMediaState == NdisMediaStateConnected)
2122 {
2123 if (INFRA_ON(pAd))
2124 {
2125 sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
2126 pAd->CommonCfg.Ssid,
2127 pAd->CommonCfg.Bssid[0],
2128 pAd->CommonCfg.Bssid[1],
2129 pAd->CommonCfg.Bssid[2],
2130 pAd->CommonCfg.Bssid[3],
2131 pAd->CommonCfg.Bssid[4],
2132 pAd->CommonCfg.Bssid[5]);
2133 DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
2134 }
2135 else if (ADHOC_ON(pAd))
2136 sprintf(extra, "Connected\n");
2137 }
2138 else
2139 {
2140 sprintf(extra, "Disconnected\n");
2141 DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
2142 }
2143 }
2144 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2145 break;
2146 case SHOW_DRVIER_VERION:
2147 sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
2148 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2149 break;
2150#ifdef DOT11_N_SUPPORT
2151 case SHOW_BA_INFO:
2152 getBaInfo(pAd, extra);
2153 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2154 break;
2155#endif // DOT11_N_SUPPORT //
2156 case SHOW_DESC_INFO:
2157 {
2158 Show_DescInfo_Proc(pAd, NULL);
2159 wrq->length = 0; // 1: size of '\0'
2160 }
2161 break;
2162 case RAIO_OFF:
2163 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2164 {
2165 sprintf(extra, "Scanning\n");
2166 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2167 break;
2168 }
2169 pAd->StaCfg.bSwRadio = FALSE;
2170 if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2171 {
2172 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2173 if (pAd->StaCfg.bRadio == FALSE)
2174 {
2175 MlmeRadioOff(pAd);
2176 // Update extra information
2177 pAd->ExtraInfo = SW_RADIO_OFF;
2178 }
2179 }
2180 sprintf(extra, "Radio Off\n");
2181 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2182 break;
2183 case RAIO_ON:
2184 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2185 {
2186 sprintf(extra, "Scanning\n");
2187 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2188 break;
2189 }
2190 pAd->StaCfg.bSwRadio = TRUE;
2191 //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2192 {
2193 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2194 if (pAd->StaCfg.bRadio == TRUE)
2195 {
2196 MlmeRadioOn(pAd);
2197 // Update extra information
2198 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
2199 }
2200 }
2201 sprintf(extra, "Radio On\n");
2202 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2203 break;
2204
2205
2206#ifdef QOS_DLS_SUPPORT
2207 case SHOW_DLS_ENTRY_INFO:
2208 {
2209 Set_DlsEntryInfo_Display_Proc(pAd, NULL);
2210 wrq->length = 0; // 1: size of '\0'
2211 }
2212 break;
2213#endif // QOS_DLS_SUPPORT //
2214
2215 case SHOW_CFG_VALUE:
2216 {
2217 Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
2218 if (Status == 0)
2219 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2220 }
2221 break;
2222 case SHOW_ADHOC_ENTRY_INFO:
2223 Show_Adhoc_MacTable_Proc(pAd, extra);
2224 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2225 break;
2226 default:
2227 DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __FUNCTION__, subcmd));
2228 break;
2229 }
2230
2231 return Status;
2232}
2233
2234#ifdef SIOCSIWMLME
2235int rt_ioctl_siwmlme(struct net_device *dev,
2236 struct iw_request_info *info,
2237 union iwreq_data *wrqu,
2238 char *extra)
2239{
2240 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2241 struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
2242 MLME_QUEUE_ELEM MsgElem;
2243 MLME_DISASSOC_REQ_STRUCT DisAssocReq;
2244 MLME_DEAUTH_REQ_STRUCT DeAuthReq;
2245
2246 DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
2247
2248 if (pMlme == NULL)
2249 return -EINVAL;
2250
2251 switch(pMlme->cmd)
2252 {
2253#ifdef IW_MLME_DEAUTH
2254 case IW_MLME_DEAUTH:
2255 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __FUNCTION__));
2256 COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
2257 DeAuthReq.Reason = pMlme->reason_code;
2258 MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
2259 NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
2260 MlmeDeauthReqAction(pAd, &MsgElem);
2261 if (INFRA_ON(pAd))
2262 {
2263 LinkDown(pAd, FALSE);
2264 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
2265 }
2266 break;
2267#endif // IW_MLME_DEAUTH //
2268#ifdef IW_MLME_DISASSOC
2269 case IW_MLME_DISASSOC:
2270 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __FUNCTION__));
2271 COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
2272 DisAssocReq.Reason = pMlme->reason_code;
2273
2274 MsgElem.Machine = ASSOC_STATE_MACHINE;
2275 MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
2276 MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
2277 NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
2278
2279 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
2280 MlmeDisassocReqAction(pAd, &MsgElem);
2281 break;
2282#endif // IW_MLME_DISASSOC //
2283 default:
2284 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __FUNCTION__));
2285 break;
2286 }
2287
2288 return 0;
2289}
2290#endif // SIOCSIWMLME //
2291
2292#if WIRELESS_EXT > 17
2293int rt_ioctl_siwauth(struct net_device *dev,
2294 struct iw_request_info *info,
2295 union iwreq_data *wrqu, char *extra)
2296{
2297 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2298 struct iw_param *param = &wrqu->param;
2299
2300 //check if the interface is down
2301 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2302 {
2303 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2304 return -ENETDOWN;
2305 }
2306 switch (param->flags & IW_AUTH_INDEX) {
2307 case IW_AUTH_WPA_VERSION:
2308 if (param->value == IW_AUTH_WPA_VERSION_WPA)
2309 {
2310 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
2311 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
2312 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
2313 }
2314 else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
2315 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
2316
2317 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
2318 break;
2319 case IW_AUTH_CIPHER_PAIRWISE:
2320 if (param->value == IW_AUTH_CIPHER_NONE)
2321 {
2322 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
2323 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2324 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
2325 }
2326 else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2327 param->value == IW_AUTH_CIPHER_WEP104)
2328 {
2329 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
2330 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2331 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
2332#ifdef WPA_SUPPLICANT_SUPPORT
2333 pAdapter->StaCfg.IEEE8021X = FALSE;
2334#endif // WPA_SUPPLICANT_SUPPORT //
2335 }
2336 else if (param->value == IW_AUTH_CIPHER_TKIP)
2337 {
2338 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
2339 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2340 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2341 }
2342 else if (param->value == IW_AUTH_CIPHER_CCMP)
2343 {
2344 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
2345 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2346 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
2347 }
2348 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __FUNCTION__, param->value));
2349 break;
2350 case IW_AUTH_CIPHER_GROUP:
2351 if (param->value == IW_AUTH_CIPHER_NONE)
2352 {
2353 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
2354 }
2355 else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2356 param->value == IW_AUTH_CIPHER_WEP104)
2357 {
2358 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
2359 }
2360 else if (param->value == IW_AUTH_CIPHER_TKIP)
2361 {
2362 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
2363 }
2364 else if (param->value == IW_AUTH_CIPHER_CCMP)
2365 {
2366 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
2367 }
2368 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __FUNCTION__, param->value));
2369 break;
2370 case IW_AUTH_KEY_MGMT:
2371 if (param->value == IW_AUTH_KEY_MGMT_802_1X)
2372 {
2373 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
2374 {
2375 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
2376#ifdef WPA_SUPPLICANT_SUPPORT
2377 pAdapter->StaCfg.IEEE8021X = FALSE;
2378#endif // WPA_SUPPLICANT_SUPPORT //
2379 }
2380 else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
2381 {
2382 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
2383#ifdef WPA_SUPPLICANT_SUPPORT
2384 pAdapter->StaCfg.IEEE8021X = FALSE;
2385#endif // WPA_SUPPLICANT_SUPPORT //
2386 }
2387#ifdef WPA_SUPPLICANT_SUPPORT
2388 else
2389 // WEP 1x
2390 pAdapter->StaCfg.IEEE8021X = TRUE;
2391#endif // WPA_SUPPLICANT_SUPPORT //
2392 }
2393 else if (param->value == 0)
2394 {
2395 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2396 STA_PORT_SECURED(pAdapter);
2397 }
2398 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __FUNCTION__, param->value));
2399 break;
2400 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2401 break;
2402 case IW_AUTH_PRIVACY_INVOKED:
2403 /*if (param->value == 0)
2404 {
2405 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2406 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
2407 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2408 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
2409 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
2410 }*/
2411 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __FUNCTION__, param->value));
2412 break;
2413 case IW_AUTH_DROP_UNENCRYPTED:
2414 if (param->value != 0)
2415 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2416 else
2417 {
2418 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2419 STA_PORT_SECURED(pAdapter);
2420 }
2421 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
2422 break;
2423 case IW_AUTH_80211_AUTH_ALG:
2424 if (param->value & IW_AUTH_ALG_SHARED_KEY)
2425 {
2426 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
2427 }
2428 else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
2429 {
2430 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2431 }
2432 else
2433 return -EINVAL;
2434 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __FUNCTION__, param->value));
2435 break;
2436 case IW_AUTH_WPA_ENABLED:
2437 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __FUNCTION__, param->value));
2438 break;
2439 default:
2440 return -EOPNOTSUPP;
2441}
2442
2443 return 0;
2444}
2445
2446int rt_ioctl_giwauth(struct net_device *dev,
2447 struct iw_request_info *info,
2448 union iwreq_data *wrqu, char *extra)
2449{
2450 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2451 struct iw_param *param = &wrqu->param;
2452
2453 //check if the interface is down
2454 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2455 {
2456 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2457 return -ENETDOWN;
2458 }
2459
2460 switch (param->flags & IW_AUTH_INDEX) {
2461 case IW_AUTH_DROP_UNENCRYPTED:
2462 param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
2463 break;
2464
2465 case IW_AUTH_80211_AUTH_ALG:
2466 param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
2467 break;
2468
2469 case IW_AUTH_WPA_ENABLED:
2470 param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
2471 break;
2472
2473 default:
2474 return -EOPNOTSUPP;
2475 }
2476 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
2477 return 0;
2478}
2479
2480void fnSetCipherKey(
2481 IN PRTMP_ADAPTER pAdapter,
2482 IN INT keyIdx,
2483 IN UCHAR CipherAlg,
2484 IN BOOLEAN bGTK,
2485 IN struct iw_encode_ext *ext)
2486{
2487 NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2488 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
2489 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
2490 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
2491 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
2492 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
2493
2494 // Update group key information to ASIC Shared Key Table
2495 AsicAddSharedKeyEntry(pAdapter,
2496 BSS0,
2497 keyIdx,
2498 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2499 pAdapter->SharedKey[BSS0][keyIdx].Key,
2500 pAdapter->SharedKey[BSS0][keyIdx].TxMic,
2501 pAdapter->SharedKey[BSS0][keyIdx].RxMic);
2502
2503 if (bGTK)
2504 // Update ASIC WCID attribute table and IVEIV table
2505 RTMPAddWcidAttributeEntry(pAdapter,
2506 BSS0,
2507 keyIdx,
2508 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2509 NULL);
2510 else
2511 // Update ASIC WCID attribute table and IVEIV table
2512 RTMPAddWcidAttributeEntry(pAdapter,
2513 BSS0,
2514 keyIdx,
2515 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2516 &pAdapter->MacTab.Content[BSSID_WCID]);
2517}
2518
2519int rt_ioctl_siwencodeext(struct net_device *dev,
2520 struct iw_request_info *info,
2521 union iwreq_data *wrqu,
2522 char *extra)
2523 {
2524 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2525 struct iw_point *encoding = &wrqu->encoding;
2526 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2527 int keyIdx, alg = ext->alg;
2528
2529 //check if the interface is down
2530 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2531 {
2532 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2533 return -ENETDOWN;
2534 }
2535
2536 if (encoding->flags & IW_ENCODE_DISABLED)
2537 {
2538 keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2539 // set BSSID wcid entry of the Pair-wise Key table as no-security mode
2540 AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
2541 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
2542 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
2543 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
2544 NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2545 DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __FUNCTION__, encoding->flags));
2546 }
2547 else
2548 {
2549 // Get Key Index and convet to our own defined key index
2550 keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2551 if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
2552 return -EINVAL;
2553
2554 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2555 {
2556 pAdapter->StaCfg.DefaultKeyId = keyIdx;
2557 DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __FUNCTION__, pAdapter->StaCfg.DefaultKeyId));
2558 }
2559
2560 switch (alg) {
2561 case IW_ENCODE_ALG_NONE:
2562 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __FUNCTION__));
2563 break;
2564 case IW_ENCODE_ALG_WEP:
2565 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __FUNCTION__, ext->key_len, keyIdx));
2566 if (ext->key_len == MAX_WEP_KEY_SIZE)
2567 {
2568 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
2569 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
2570 }
2571 else if (ext->key_len == MIN_WEP_KEY_SIZE)
2572 {
2573 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
2574 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
2575 }
2576 else
2577 return -EINVAL;
2578
2579 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
2580 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
2581 break;
2582 case IW_ENCODE_ALG_TKIP:
2583 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __FUNCTION__, keyIdx, ext->key_len));
2584 if (ext->key_len == 32)
2585 {
2586 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2587 {
2588 fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
2589 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2590 {
2591 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2592 STA_PORT_SECURED(pAdapter);
2593 }
2594 }
2595 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2596 {
2597 fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
2598
2599 // set 802.1x port control
2600 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2601 STA_PORT_SECURED(pAdapter);
2602 }
2603 }
2604 else
2605 return -EINVAL;
2606 break;
2607 case IW_ENCODE_ALG_CCMP:
2608 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2609 {
2610 fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
2611 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2612 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2613 STA_PORT_SECURED(pAdapter);
2614 }
2615 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2616 {
2617 fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
2618
2619 // set 802.1x port control
2620 //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2621 STA_PORT_SECURED(pAdapter);
2622 }
2623 break;
2624 default:
2625 return -EINVAL;
2626 }
2627 }
2628
2629 return 0;
2630}
2631
2632int
2633rt_ioctl_giwencodeext(struct net_device *dev,
2634 struct iw_request_info *info,
2635 union iwreq_data *wrqu, char *extra)
2636{
2637 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2638 PCHAR pKey = NULL;
2639 struct iw_point *encoding = &wrqu->encoding;
2640 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2641 int idx, max_key_len;
2642
2643 DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
2644
2645 max_key_len = encoding->length - sizeof(*ext);
2646 if (max_key_len < 0)
2647 return -EINVAL;
2648
2649 idx = encoding->flags & IW_ENCODE_INDEX;
2650 if (idx)
2651 {
2652 if (idx < 1 || idx > 4)
2653 return -EINVAL;
2654 idx--;
2655
2656 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2657 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
2658 {
2659 if (idx != pAd->StaCfg.DefaultKeyId)
2660 {
2661 ext->key_len = 0;
2662 return 0;
2663 }
2664 }
2665 }
2666 else
2667 idx = pAd->StaCfg.DefaultKeyId;
2668
2669 encoding->flags = idx + 1;
2670 memset(ext, 0, sizeof(*ext));
2671
2672 ext->key_len = 0;
2673 switch(pAd->StaCfg.WepStatus) {
2674 case Ndis802_11WEPDisabled:
2675 ext->alg = IW_ENCODE_ALG_NONE;
2676 encoding->flags |= IW_ENCODE_DISABLED;
2677 break;
2678 case Ndis802_11WEPEnabled:
2679 ext->alg = IW_ENCODE_ALG_WEP;
2680 if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
2681 return -E2BIG;
2682 else
2683 {
2684 ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
2685 pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
2686 }
2687 break;
2688 case Ndis802_11Encryption2Enabled:
2689 case Ndis802_11Encryption3Enabled:
2690 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2691 ext->alg = IW_ENCODE_ALG_TKIP;
2692 else
2693 ext->alg = IW_ENCODE_ALG_CCMP;
2694
2695 if (max_key_len < 32)
2696 return -E2BIG;
2697 else
2698 {
2699 ext->key_len = 32;
2700 pKey = &pAd->StaCfg.PMK[0];
2701 }
2702 break;
2703 default:
2704 return -EINVAL;
2705 }
2706
2707 if (ext->key_len && pKey)
2708 {
2709 encoding->flags |= IW_ENCODE_ENABLED;
2710 memcpy(ext->key, pKey, ext->key_len);
2711 }
2712
2713 return 0;
2714}
2715
2716#ifdef SIOCSIWGENIE
2717int rt_ioctl_siwgenie(struct net_device *dev,
2718 struct iw_request_info *info,
2719 union iwreq_data *wrqu, char *extra)
2720{
2721 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2722
2723 if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
2724 (wrqu->data.length && extra == NULL))
2725 return -EINVAL;
2726
2727 if (wrqu->data.length)
2728 {
2729 pAd->StaCfg.RSNIE_Len = wrqu->data.length;
2730 NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
2731 }
2732 else
2733 {
2734 pAd->StaCfg.RSNIE_Len = 0;
2735 NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
2736 }
2737
2738 return 0;
2739}
2740#endif // SIOCSIWGENIE //
2741
2742int rt_ioctl_giwgenie(struct net_device *dev,
2743 struct iw_request_info *info,
2744 union iwreq_data *wrqu, char *extra)
2745{
2746 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2747
2748 if ((pAd->StaCfg.RSNIE_Len == 0) ||
2749 (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
2750 {
2751 wrqu->data.length = 0;
2752 return 0;
2753 }
2754
2755#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2756#ifdef SIOCSIWGENIE
2757 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
2758 {
2759 if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
2760 return -E2BIG;
2761
2762 wrqu->data.length = pAd->StaCfg.RSNIE_Len;
2763 memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2764 }
2765 else
2766#endif // SIOCSIWGENIE //
2767#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2768 {
2769 UCHAR RSNIe = IE_WPA;
2770
2771 if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
2772 return -E2BIG;
2773 wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
2774
2775 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
2776 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
2777 RSNIe = IE_RSN;
2778
2779 extra[0] = (char)RSNIe;
2780 extra[1] = pAd->StaCfg.RSNIE_Len;
2781 memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2782 }
2783
2784 return 0;
2785}
2786
2787int rt_ioctl_siwpmksa(struct net_device *dev,
2788 struct iw_request_info *info,
2789 union iwreq_data *wrqu,
2790 char *extra)
2791{
2792 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2793 struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
2794 INT CachedIdx = 0, idx = 0;
2795
2796 if (pPmksa == NULL)
2797 return -EINVAL;
2798
2799 DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
2800 switch(pPmksa->cmd)
2801 {
2802 case IW_PMKSA_FLUSH:
2803 NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
2804 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
2805 break;
2806 case IW_PMKSA_REMOVE:
2807 for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2808 {
2809 // compare the BSSID
2810 if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2811 {
2812 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
2813 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
2814 for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
2815 {
2816 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
2817 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
2818 }
2819 pAd->StaCfg.SavedPMKNum--;
2820 break;
2821 }
2822 }
2823
2824 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
2825 break;
2826 case IW_PMKSA_ADD:
2827 for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2828 {
2829 // compare the BSSID
2830 if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2831 break;
2832 }
2833
2834 // Found, replace it
2835 if (CachedIdx < PMKID_NO)
2836 {
2837 DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2838 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2839 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2840 pAd->StaCfg.SavedPMKNum++;
2841 }
2842 // Not found, replace the last one
2843 else
2844 {
2845 // Randomly replace one
2846 CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
2847 DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2848 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2849 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2850 }
2851
2852 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
2853 break;
2854 default:
2855 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
2856 break;
2857 }
2858
2859 return 0;
2860}
2861#endif // #if WIRELESS_EXT > 17
2862
2863#ifdef DBG
2864static int
2865rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info,
2866 struct iw_point *wrq, char *extra)
2867 {
2868 CHAR *this_char;
2869 CHAR *value = NULL;
2870 UCHAR regBBP = 0;
2871// CHAR arg[255]={0};
2872 UINT32 bbpId;
2873 UINT32 bbpValue;
2874 BOOLEAN bIsPrintAllBBP = FALSE;
2875 INT Status = 0;
2876 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2877
2878
2879 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2880
2881 if (wrq->length > 1) //No parameters.
2882 {
2883 sprintf(extra, "\n");
2884
2885 //Parsing Read or Write
2886 this_char = wrq->pointer;
2887 DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char));
2888 if (!*this_char)
2889 goto next;
2890
2891 if ((value = rtstrchr(this_char, '=')) != NULL)
2892 *value++ = 0;
2893
2894 if (!value || !*value)
2895 { //Read
2896 DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value));
2897 if (sscanf(this_char, "%d", &(bbpId)) == 1)
2898 {
2899 if (bbpId <= 136)
2900 {
2901#ifdef RALINK_ATE
2902 if (ATE_ON(pAdapter))
2903 {
2904 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2905 }
2906 else
2907#endif // RALINK_ATE //
2908 {
2909 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2910 }
2911 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2912 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2913 DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2914 }
2915 else
2916 {//Invalid parametes, so default printk all bbp
2917 bIsPrintAllBBP = TRUE;
2918 goto next;
2919 }
2920 }
2921 else
2922 { //Invalid parametes, so default printk all bbp
2923 bIsPrintAllBBP = TRUE;
2924 goto next;
2925 }
2926 }
2927 else
2928 { //Write
2929 if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1))
2930 {
2931 if (bbpId <= 136)
2932 {
2933#ifdef RALINK_ATE
2934 if (ATE_ON(pAdapter))
2935 {
2936 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2937 //Read it back for showing
2938 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2939 }
2940 else
2941#endif // RALINK_ATE //
2942 {
2943 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2944 //Read it back for showing
2945 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2946 }
2947 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2948 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2949 DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2950 }
2951 else
2952 {//Invalid parametes, so default printk all bbp
2953 bIsPrintAllBBP = TRUE;
2954 goto next;
2955 }
2956 }
2957 else
2958 { //Invalid parametes, so default printk all bbp
2959 bIsPrintAllBBP = TRUE;
2960 goto next;
2961 }
2962 }
2963 }
2964 else
2965 bIsPrintAllBBP = TRUE;
2966
2967next:
2968 if (bIsPrintAllBBP)
2969 {
2970 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2971 sprintf(extra, "\n");
2972 for (bbpId = 0; bbpId <= 136; bbpId++)
2973 {
2974 if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 10))
2975 break;
2976#ifdef RALINK_ATE
2977 if (ATE_ON(pAdapter))
2978 {
2979 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2980 }
2981 else
2982#endif // RALINK_ATE //
2983 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2984 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X ", bbpId, bbpId*2, regBBP);
2985 if (bbpId%5 == 4)
2986 sprintf(extra+strlen(extra), "\n");
2987 }
2988
2989 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2990 DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->length));
2991 }
2992
2993 DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n"));
2994
2995 return Status;
2996}
2997#endif // DBG //
2998
2999int rt_ioctl_siwrate(struct net_device *dev,
3000 struct iw_request_info *info,
3001 union iwreq_data *wrqu, char *extra)
3002{
3003 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
3004 UINT32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
3005
3006 //check if the interface is down
3007 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3008 {
3009 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
3010 return -ENETDOWN;
3011 }
3012
3013 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
3014 /* rate = -1 => auto rate
3015 rate = X, fixed = 1 => (fixed rate X)
3016 */
3017 if (rate == -1)
3018 {
3019 //Auto Rate
3020 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3021 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
3022 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
3023 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
3024 RTMPSetDesiredRates(pAd, -1);
3025
3026#ifdef DOT11_N_SUPPORT
3027 SetCommonHT(pAd);
3028#endif // DOT11_N_SUPPORT //
3029 }
3030 else
3031 {
3032 if (fixed)
3033 {
3034 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
3035 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
3036 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
3037 RTMPSetDesiredRates(pAd, rate);
3038 else
3039 {
3040 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3041#ifdef DOT11_N_SUPPORT
3042 SetCommonHT(pAd);
3043#endif // DOT11_N_SUPPORT //
3044 }
3045 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
3046 }
3047 else
3048 {
3049 // TODO: rate = X, fixed = 0 => (rates <= X)
3050 return -EOPNOTSUPP;
3051 }
3052 }
3053
3054 return 0;
3055}
3056
3057int rt_ioctl_giwrate(struct net_device *dev,
3058 struct iw_request_info *info,
3059 union iwreq_data *wrqu, char *extra)
3060{
3061 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
3062 int rate_index = 0, rate_count = 0;
3063 HTTRANSMIT_SETTING ht_setting;
3064 __s32 ralinkrate[] =
3065 {2, 4, 11, 22, // CCK
3066 12, 18, 24, 36, 48, 72, 96, 108, // OFDM
3067 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
3068 39, 78, 117, 156, 234, 312, 351, 390, // 20MHz, 800ns GI, MCS: 16 ~ 23
3069 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
3070 81, 162, 243, 324, 486, 648, 729, 810, // 40MHz, 800ns GI, MCS: 16 ~ 23
3071 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
3072 43, 87, 130, 173, 260, 317, 390, 433, // 20MHz, 400ns GI, MCS: 16 ~ 23
3073 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
3074 90, 180, 270, 360, 540, 720, 810, 900}; // 40MHz, 400ns GI, MCS: 16 ~ 23
3075
3076 rate_count = sizeof(ralinkrate)/sizeof(__s32);
3077 //check if the interface is down
3078 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3079 {
3080 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
3081 return -ENETDOWN;
3082 }
3083
3084 if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
3085 (INFRA_ON(pAd)) &&
3086 ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
3087 ht_setting.word = pAd->StaCfg.HTPhyMode.word;
3088 else
3089 ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
3090
3091#ifdef DOT11_N_SUPPORT
3092 if (ht_setting.field.MODE >= MODE_HTMIX)
3093 {
3094// rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS);
3095 rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
3096 }
3097 else
3098#endif // DOT11_N_SUPPORT //
3099 if (ht_setting.field.MODE == MODE_OFDM)
3100 rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
3101 else if (ht_setting.field.MODE == MODE_CCK)
3102 rate_index = (UCHAR)(ht_setting.field.MCS);
3103
3104 if (rate_index < 0)
3105 rate_index = 0;
3106
3107 if (rate_index > rate_count)
3108 rate_index = rate_count;
3109
3110 wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
3111 wrqu->bitrate.disabled = 0;
3112
3113 return 0;
3114}
3115
3116static const iw_handler rt_handler[] =
3117{
3118 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3119 (iw_handler) rt_ioctl_giwname, /* SIOCGIWNAME */
3120 (iw_handler) NULL, /* SIOCSIWNWID */
3121 (iw_handler) NULL, /* SIOCGIWNWID */
3122 (iw_handler) rt_ioctl_siwfreq, /* SIOCSIWFREQ */
3123 (iw_handler) rt_ioctl_giwfreq, /* SIOCGIWFREQ */
3124 (iw_handler) rt_ioctl_siwmode, /* SIOCSIWMODE */
3125 (iw_handler) rt_ioctl_giwmode, /* SIOCGIWMODE */
3126 (iw_handler) NULL, /* SIOCSIWSENS */
3127 (iw_handler) NULL, /* SIOCGIWSENS */
3128 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
3129 (iw_handler) rt_ioctl_giwrange, /* SIOCGIWRANGE */
3130 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
3131 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
3132 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
3133 (iw_handler) rt28xx_get_wireless_stats /* kernel code */, /* SIOCGIWSTATS */
3134 (iw_handler) NULL, /* SIOCSIWSPY */
3135 (iw_handler) NULL, /* SIOCGIWSPY */
3136 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3137 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3138 (iw_handler) rt_ioctl_siwap, /* SIOCSIWAP */
3139 (iw_handler) rt_ioctl_giwap, /* SIOCGIWAP */
3140#ifdef SIOCSIWMLME
3141 (iw_handler) rt_ioctl_siwmlme, /* SIOCSIWMLME */
3142#else
3143 (iw_handler) NULL, /* SIOCSIWMLME */
3144#endif // SIOCSIWMLME //
3145 (iw_handler) rt_ioctl_iwaplist, /* SIOCGIWAPLIST */
3146#ifdef SIOCGIWSCAN
3147 (iw_handler) rt_ioctl_siwscan, /* SIOCSIWSCAN */
3148 (iw_handler) rt_ioctl_giwscan, /* SIOCGIWSCAN */
3149#else
3150 (iw_handler) NULL, /* SIOCSIWSCAN */
3151 (iw_handler) NULL, /* SIOCGIWSCAN */
3152#endif /* SIOCGIWSCAN */
3153 (iw_handler) rt_ioctl_siwessid, /* SIOCSIWESSID */
3154 (iw_handler) rt_ioctl_giwessid, /* SIOCGIWESSID */
3155 (iw_handler) rt_ioctl_siwnickn, /* SIOCSIWNICKN */
3156 (iw_handler) rt_ioctl_giwnickn, /* SIOCGIWNICKN */
3157 (iw_handler) NULL, /* -- hole -- */
3158 (iw_handler) NULL, /* -- hole -- */
3159 (iw_handler) rt_ioctl_siwrate, /* SIOCSIWRATE */
3160 (iw_handler) rt_ioctl_giwrate, /* SIOCGIWRATE */
3161 (iw_handler) rt_ioctl_siwrts, /* SIOCSIWRTS */
3162 (iw_handler) rt_ioctl_giwrts, /* SIOCGIWRTS */
3163 (iw_handler) rt_ioctl_siwfrag, /* SIOCSIWFRAG */
3164 (iw_handler) rt_ioctl_giwfrag, /* SIOCGIWFRAG */
3165 (iw_handler) NULL, /* SIOCSIWTXPOW */
3166 (iw_handler) NULL, /* SIOCGIWTXPOW */
3167 (iw_handler) NULL, /* SIOCSIWRETRY */
3168 (iw_handler) NULL, /* SIOCGIWRETRY */
3169 (iw_handler) rt_ioctl_siwencode, /* SIOCSIWENCODE */
3170 (iw_handler) rt_ioctl_giwencode, /* SIOCGIWENCODE */
3171 (iw_handler) NULL, /* SIOCSIWPOWER */
3172 (iw_handler) NULL, /* SIOCGIWPOWER */
3173 (iw_handler) NULL, /* -- hole -- */
3174 (iw_handler) NULL, /* -- hole -- */
3175#if WIRELESS_EXT > 17
3176 (iw_handler) rt_ioctl_siwgenie, /* SIOCSIWGENIE */
3177 (iw_handler) rt_ioctl_giwgenie, /* SIOCGIWGENIE */
3178 (iw_handler) rt_ioctl_siwauth, /* SIOCSIWAUTH */
3179 (iw_handler) rt_ioctl_giwauth, /* SIOCGIWAUTH */
3180 (iw_handler) rt_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
3181 (iw_handler) rt_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
3182 (iw_handler) rt_ioctl_siwpmksa, /* SIOCSIWPMKSA */
3183#endif
3184};
3185
3186static const iw_handler rt_priv_handlers[] = {
3187 (iw_handler) NULL, /* + 0x00 */
3188 (iw_handler) NULL, /* + 0x01 */
3189#ifndef CONFIG_AP_SUPPORT
3190 (iw_handler) rt_ioctl_setparam, /* + 0x02 */
3191#else
3192 (iw_handler) NULL, /* + 0x02 */
3193#endif // CONFIG_AP_SUPPORT //
3194#ifdef DBG
3195 (iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
3196#else
3197 (iw_handler) NULL, /* + 0x03 */
3198#endif
3199 (iw_handler) NULL, /* + 0x04 */
3200 (iw_handler) NULL, /* + 0x05 */
3201 (iw_handler) NULL, /* + 0x06 */
3202 (iw_handler) NULL, /* + 0x07 */
3203 (iw_handler) NULL, /* + 0x08 */
3204 (iw_handler) rt_private_get_statistics, /* + 0x09 */
3205 (iw_handler) NULL, /* + 0x0A */
3206 (iw_handler) NULL, /* + 0x0B */
3207 (iw_handler) NULL, /* + 0x0C */
3208 (iw_handler) NULL, /* + 0x0D */
3209 (iw_handler) NULL, /* + 0x0E */
3210 (iw_handler) NULL, /* + 0x0F */
3211 (iw_handler) NULL, /* + 0x10 */
3212 (iw_handler) rt_private_show, /* + 0x11 */
3213 (iw_handler) NULL, /* + 0x12 */
3214 (iw_handler) NULL, /* + 0x13 */
3215 (iw_handler) NULL, /* + 0x15 */
3216 (iw_handler) NULL, /* + 0x17 */
3217 (iw_handler) NULL, /* + 0x18 */
3218};
3219
3220const struct iw_handler_def rt28xx_iw_handler_def =
3221{
3222#define N(a) (sizeof (a) / sizeof (a[0]))
3223 .standard = (iw_handler *) rt_handler,
3224 .num_standard = sizeof(rt_handler) / sizeof(iw_handler),
3225 .private = (iw_handler *) rt_priv_handlers,
3226 .num_private = N(rt_priv_handlers),
3227 .private_args = (struct iw_priv_args *) privtab,
3228 .num_private_args = N(privtab),
3229#if IW_HANDLER_VERSION >= 7
3230 .get_wireless_stats = rt28xx_get_wireless_stats,
3231#endif
3232};
3233
3234INT RTMPSetInformation(
3235 IN PRTMP_ADAPTER pAdapter,
3236 IN OUT struct ifreq *rq,
3237 IN INT cmd)
3238{
3239 struct iwreq *wrq = (struct iwreq *) rq;
3240 NDIS_802_11_SSID Ssid;
3241 NDIS_802_11_MAC_ADDRESS Bssid;
3242 RT_802_11_PHY_MODE PhyMode;
3243 RT_802_11_STA_CONFIG StaConfig;
3244 NDIS_802_11_RATES aryRates;
3245 RT_802_11_PREAMBLE Preamble;
3246 NDIS_802_11_WEP_STATUS WepStatus;
3247 NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeMax;
3248 NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
3249 NDIS_802_11_RTS_THRESHOLD RtsThresh;
3250 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
3251 NDIS_802_11_POWER_MODE PowerMode;
3252 PNDIS_802_11_KEY pKey = NULL;
3253 PNDIS_802_11_WEP pWepKey =NULL;
3254 PNDIS_802_11_REMOVE_KEY pRemoveKey = NULL;
3255 NDIS_802_11_CONFIGURATION Config, *pConfig = NULL;
3256 NDIS_802_11_NETWORK_TYPE NetType;
3257 ULONG Now;
3258 UINT KeyIdx = 0;
3259 INT Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
3260 ULONG PowerTemp;
3261 BOOLEAN RadioState;
3262 BOOLEAN StateMachineTouched = FALSE;
3263#ifdef DOT11_N_SUPPORT
3264 OID_SET_HT_PHYMODE HT_PhyMode; //11n ,kathy
3265#endif // DOT11_N_SUPPORT //
3266#ifdef WPA_SUPPLICANT_SUPPORT
3267 PNDIS_802_11_PMKID pPmkId = NULL;
3268 BOOLEAN IEEE8021xState = FALSE;
3269 BOOLEAN IEEE8021x_required_keys = FALSE;
3270 UCHAR wpa_supplicant_enable = 0;
3271#endif // WPA_SUPPLICANT_SUPPORT //
3272
3273#ifdef SNMP_SUPPORT
3274 TX_RTY_CFG_STRUC tx_rty_cfg;
3275 ULONG ShortRetryLimit, LongRetryLimit;
3276 UCHAR ctmp;
3277#endif // SNMP_SUPPORT //
3278
3279
3280
3281#ifdef DOT11_N_SUPPORT
3282 MaxPhyMode = PHY_11N_5G;
3283#endif // DOT11_N_SUPPORT //
3284
3285
3286 DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(), 0x%08x\n", cmd&0x7FFF));
3287 switch(cmd & 0x7FFF) {
3288 case RT_OID_802_11_COUNTRY_REGION:
3289 if (wrq->u.data.length < sizeof(UCHAR))
3290 Status = -EINVAL;
3291 // Only avaliable when EEPROM not programming
3292 else if (!(pAdapter->CommonCfg.CountryRegion & 0x80) && !(pAdapter->CommonCfg.CountryRegionForABand & 0x80))
3293 {
3294 ULONG Country;
3295 UCHAR TmpPhy;
3296
3297 Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
3298 pAdapter->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
3299 pAdapter->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
3300 TmpPhy = pAdapter->CommonCfg.PhyMode;
3301 pAdapter->CommonCfg.PhyMode = 0xff;
3302 // Build all corresponding channel information
3303 RTMPSetPhyMode(pAdapter, TmpPhy);
3304#ifdef DOT11_N_SUPPORT
3305 SetCommonHT(pAdapter);
3306#endif // DOT11_N_SUPPORT //
3307 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d B/G:%d)\n", pAdapter->CommonCfg.CountryRegionForABand,
3308 pAdapter->CommonCfg.CountryRegion));
3309 }
3310 break;
3311 case OID_802_11_BSSID_LIST_SCAN:
3312 #ifdef RALINK_ATE
3313 if (ATE_ON(pAdapter))
3314 {
3315 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3316 break;
3317 }
3318#endif // RALINK_ATE //
3319 Now = jiffies;
3320 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAdapter->RalinkCounters.LastOneSecTotalTxCount));
3321
3322 if (MONITOR_ON(pAdapter))
3323 {
3324 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
3325 break;
3326 }
3327
3328 //Benson add 20080527, when radio off, sta don't need to scan
3329 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
3330 break;
3331
3332 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
3333 {
3334 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
3335 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3336 Status = NDIS_STATUS_SUCCESS;
3337 break;
3338 }
3339
3340 if (pAdapter->RalinkCounters.LastOneSecTotalTxCount > 100)
3341 {
3342 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3343 Status = NDIS_STATUS_SUCCESS;
3344 pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
3345 break;
3346 }
3347
3348 if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
3349 ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
3350 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3351 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
3352 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
3353 (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
3354 {
3355 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3356 Status = NDIS_STATUS_SUCCESS;
3357 pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
3358 break;
3359 }
3360
3361
3362 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3363 {
3364 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3365 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3366 }
3367
3368 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3369 // this request, because this request is initiated by NDIS.
3370 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3371 // Reset allowed scan retries
3372 pAdapter->StaCfg.ScanCnt = 0;
3373 pAdapter->StaCfg.LastScanTime = Now;
3374
3375 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3376 RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3377 MlmeEnqueue(pAdapter,
3378 MLME_CNTL_STATE_MACHINE,
3379 OID_802_11_BSSID_LIST_SCAN,
3380 0,
3381 NULL);
3382
3383 Status = NDIS_STATUS_SUCCESS;
3384 StateMachineTouched = TRUE;
3385 break;
3386 case OID_802_11_SSID:
3387 if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
3388 Status = -EINVAL;
3389 else
3390 {
3391 PCHAR pSsidString = NULL;
3392 Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
3393
3394 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
3395 if (Ssid.SsidLength > MAX_LEN_OF_SSID)
3396 Status = -EINVAL;
3397 else
3398 {
3399 if (Ssid.SsidLength == 0)
3400 {
3401 Set_SSID_Proc(pAdapter, "");
3402 }
3403 else
3404 {
3405 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
3406 if (pSsidString)
3407 {
3408 NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
3409 NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
3410 Set_SSID_Proc(pAdapter, pSsidString);
3411 kfree(pSsidString);
3412 }
3413 else
3414 Status = -ENOMEM;
3415 }
3416 }
3417 }
3418 break;
3419 case OID_802_11_BSSID:
3420#ifdef RALINK_ATE
3421 if (ATE_ON(pAdapter))
3422 {
3423 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3424 break;
3425 }
3426#endif // RALINK_ATE //
3427 if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
3428 Status = -EINVAL;
3429 else
3430 {
3431 Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
3432
3433 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3434 // this request, because this request is initiated by NDIS.
3435 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3436
3437 // Prevent to connect AP again in STAMlmePeriodicExec
3438 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3439
3440 // Reset allowed scan retries
3441 pAdapter->StaCfg.ScanCnt = 0;
3442
3443 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3444 {
3445 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3446 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3447 }
3448 MlmeEnqueue(pAdapter,
3449 MLME_CNTL_STATE_MACHINE,
3450 OID_802_11_BSSID,
3451 sizeof(NDIS_802_11_MAC_ADDRESS),
3452 (VOID *)&Bssid);
3453 Status = NDIS_STATUS_SUCCESS;
3454 StateMachineTouched = TRUE;
3455
3456 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
3457 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
3458 }
3459 break;
3460 case RT_OID_802_11_RADIO:
3461 if (wrq->u.data.length != sizeof(BOOLEAN))
3462 Status = -EINVAL;
3463 else
3464 {
3465 Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
3466 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
3467 if (pAdapter->StaCfg.bSwRadio != RadioState)
3468 {
3469 pAdapter->StaCfg.bSwRadio = RadioState;
3470 if (pAdapter->StaCfg.bRadio != (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio))
3471 {
3472 pAdapter->StaCfg.bRadio = (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio);
3473 if (pAdapter->StaCfg.bRadio == TRUE)
3474 {
3475 MlmeRadioOn(pAdapter);
3476 // Update extra information
3477 pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;
3478 }
3479 else
3480 {
3481 MlmeRadioOff(pAdapter);
3482 // Update extra information
3483 pAdapter->ExtraInfo = SW_RADIO_OFF;
3484 }
3485 }
3486 }
3487 }
3488 break;
3489 case RT_OID_802_11_PHY_MODE:
3490 if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
3491 Status = -EINVAL;
3492 else
3493 {
3494 Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3495 if (PhyMode <= MaxPhyMode)
3496 {
3497 RTMPSetPhyMode(pAdapter, PhyMode);
3498#ifdef DOT11_N_SUPPORT
3499 SetCommonHT(pAdapter);
3500#endif // DOT11_N_SUPPORT //
3501 }
3502 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
3503 }
3504 break;
3505 case RT_OID_802_11_STA_CONFIG:
3506 if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
3507 Status = -EINVAL;
3508 else
3509 {
3510 Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
3511 pAdapter->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
3512 pAdapter->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
3513 pAdapter->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
3514 if ((pAdapter->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
3515 (StaConfig.AdhocMode <= MaxPhyMode))
3516 {
3517 // allow dynamic change of "USE OFDM rate or not" in ADHOC mode
3518 // if setting changed, need to reset current TX rate as well as BEACON frame format
3519 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
3520 {
3521 pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
3522 RTMPSetPhyMode(pAdapter, PhyMode);
3523 MlmeUpdateTxRates(pAdapter, FALSE, 0);
3524 MakeIbssBeacon(pAdapter); // re-build BEACON frame
3525 AsicEnableIbssSync(pAdapter); // copy to on-chip memory
3526 }
3527 }
3528 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
3529 pAdapter->CommonCfg.bEnableTxBurst,
3530 pAdapter->CommonCfg.UseBGProtection,
3531 pAdapter->CommonCfg.bUseShortSlotTime));
3532 }
3533 break;
3534 case OID_802_11_DESIRED_RATES:
3535 if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
3536 Status = -EINVAL;
3537 else
3538 {
3539 Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
3540 NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
3541 NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
3542 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
3543 pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
3544 pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
3545 pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
3546 pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
3547 // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
3548 MlmeUpdateTxRates(pAdapter, FALSE, 0);
3549 }
3550 break;
3551 case RT_OID_802_11_PREAMBLE:
3552 if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
3553 Status = -EINVAL;
3554 else
3555 {
3556 Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
3557 if (Preamble == Rt802_11PreambleShort)
3558 {
3559 pAdapter->CommonCfg.TxPreamble = Preamble;
3560 MlmeSetTxPreamble(pAdapter, Rt802_11PreambleShort);
3561 }
3562 else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
3563 {
3564 // if user wants AUTO, initialize to LONG here, then change according to AP's
3565 // capability upon association.
3566 pAdapter->CommonCfg.TxPreamble = Preamble;
3567 MlmeSetTxPreamble(pAdapter, Rt802_11PreambleLong);
3568 }
3569 else
3570 {
3571 Status = -EINVAL;
3572 break;
3573 }
3574 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
3575 }
3576 break;
3577 case OID_802_11_WEP_STATUS:
3578 if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
3579 Status = -EINVAL;
3580 else
3581 {
3582 Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
3583 // Since TKIP, AES, WEP are all supported. It should not have any invalid setting
3584 if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
3585 {
3586 if (pAdapter->StaCfg.WepStatus != WepStatus)
3587 {
3588 // Config has changed
3589 pAdapter->bConfigChanged = TRUE;
3590 }
3591 pAdapter->StaCfg.WepStatus = WepStatus;
3592 pAdapter->StaCfg.OrigWepStatus = WepStatus;
3593 pAdapter->StaCfg.PairCipher = WepStatus;
3594 pAdapter->StaCfg.GroupCipher = WepStatus;
3595 }
3596 else
3597 {
3598 Status = -EINVAL;
3599 break;
3600 }
3601 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
3602 }
3603 break;
3604 case OID_802_11_AUTHENTICATION_MODE:
3605 if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
3606 Status = -EINVAL;
3607 else
3608 {
3609 Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
3610 if (AuthMode > Ndis802_11AuthModeMax)
3611 {
3612 Status = -EINVAL;
3613 break;
3614 }
3615 else
3616 {
3617 if (pAdapter->StaCfg.AuthMode != AuthMode)
3618 {
3619 // Config has changed
3620 pAdapter->bConfigChanged = TRUE;
3621 }
3622 pAdapter->StaCfg.AuthMode = AuthMode;
3623 }
3624 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3625 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAdapter->StaCfg.AuthMode));
3626 }
3627 break;
3628 case OID_802_11_INFRASTRUCTURE_MODE:
3629 if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
3630 Status = -EINVAL;
3631 else
3632 {
3633 Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
3634
3635 if (BssType == Ndis802_11IBSS)
3636 Set_NetworkType_Proc(pAdapter, "Adhoc");
3637 else if (BssType == Ndis802_11Infrastructure)
3638 Set_NetworkType_Proc(pAdapter, "Infra");
3639 else if (BssType == Ndis802_11Monitor)
3640 Set_NetworkType_Proc(pAdapter, "Monitor");
3641 else
3642 {
3643 Status = -EINVAL;
3644 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
3645 }
3646 }
3647 break;
3648 case OID_802_11_REMOVE_WEP:
3649 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
3650 if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
3651 {
3652 Status = -EINVAL;
3653 }
3654 else
3655 {
3656 KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
3657
3658 if (KeyIdx & 0x80000000)
3659 {
3660 // Should never set default bit when remove key
3661 Status = -EINVAL;
3662 }
3663 else
3664 {
3665 KeyIdx = KeyIdx & 0x0fffffff;
3666 if (KeyIdx >= 4){
3667 Status = -EINVAL;
3668 }
3669 else
3670 {
3671 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3672 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3673 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3674 }
3675 }
3676 }
3677 break;
3678 case RT_OID_802_11_RESET_COUNTERS:
3679 NdisZeroMemory(&pAdapter->WlanCounters, sizeof(COUNTER_802_11));
3680 NdisZeroMemory(&pAdapter->Counters8023, sizeof(COUNTER_802_3));
3681 NdisZeroMemory(&pAdapter->RalinkCounters, sizeof(COUNTER_RALINK));
3682 pAdapter->Counters8023.RxNoBuffer = 0;
3683 pAdapter->Counters8023.GoodReceives = 0;
3684 pAdapter->Counters8023.RxNoBuffer = 0;
3685#ifdef RT2870
3686 pAdapter->BulkOutComplete = 0;
3687 pAdapter->BulkOutCompleteOther= 0;
3688 pAdapter->BulkOutCompleteCancel = 0;
3689 pAdapter->BulkOutReq = 0;
3690 pAdapter->BulkInReq= 0;
3691 pAdapter->BulkInComplete = 0;
3692 pAdapter->BulkInCompleteFail = 0;
3693#endif // RT2870 //
3694 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
3695 break;
3696 case OID_802_11_RTS_THRESHOLD:
3697 if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
3698 Status = -EINVAL;
3699 else
3700 {
3701 Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
3702 if (RtsThresh > MAX_RTS_THRESHOLD)
3703 Status = -EINVAL;
3704 else
3705 pAdapter->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
3706 }
3707 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
3708 break;
3709 case OID_802_11_FRAGMENTATION_THRESHOLD:
3710 if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
3711 Status = -EINVAL;
3712 else
3713 {
3714 Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
3715 pAdapter->CommonCfg.bUseZeroToDisableFragment = FALSE;
3716 if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
3717 {
3718 if (FragThresh == 0)
3719 {
3720 pAdapter->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
3721 pAdapter->CommonCfg.bUseZeroToDisableFragment = TRUE;
3722 }
3723 else
3724 Status = -EINVAL;
3725 }
3726 else
3727 pAdapter->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
3728 }
3729 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
3730 break;
3731 case OID_802_11_POWER_MODE:
3732 if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
3733 Status = -EINVAL;
3734 else
3735 {
3736 Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
3737 if (PowerMode == Ndis802_11PowerModeCAM)
3738 Set_PSMode_Proc(pAdapter, "CAM");
3739 else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
3740 Set_PSMode_Proc(pAdapter, "Max_PSP");
3741 else if (PowerMode == Ndis802_11PowerModeFast_PSP)
3742 Set_PSMode_Proc(pAdapter, "Fast_PSP");
3743 else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
3744 Set_PSMode_Proc(pAdapter, "Legacy_PSP");
3745 else
3746 Status = -EINVAL;
3747 }
3748 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
3749 break;
3750 case RT_OID_802_11_TX_POWER_LEVEL_1:
3751 if (wrq->u.data.length < sizeof(ULONG))
3752 Status = -EINVAL;
3753 else
3754 {
3755 Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
3756 if (PowerTemp > 100)
3757 PowerTemp = 0xffffffff; // AUTO
3758 pAdapter->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
3759 pAdapter->CommonCfg.TxPowerPercentage = pAdapter->CommonCfg.TxPowerDefault;
3760 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
3761 }
3762 break;
3763 case OID_802_11_NETWORK_TYPE_IN_USE:
3764 if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
3765 Status = -EINVAL;
3766 else
3767 {
3768 Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
3769
3770 if (NetType == Ndis802_11DS)
3771 RTMPSetPhyMode(pAdapter, PHY_11B);
3772 else if (NetType == Ndis802_11OFDM24)
3773 RTMPSetPhyMode(pAdapter, PHY_11BG_MIXED);
3774 else if (NetType == Ndis802_11OFDM5)
3775 RTMPSetPhyMode(pAdapter, PHY_11A);
3776 else
3777 Status = -EINVAL;
3778#ifdef DOT11_N_SUPPORT
3779 if (Status == NDIS_STATUS_SUCCESS)
3780 SetCommonHT(pAdapter);
3781#endif // DOT11_N_SUPPORT //
3782 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
3783 }
3784 break;
3785 // For WPA PSK PMK key
3786 case RT_OID_802_11_ADD_WPA:
3787 pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3788 if(pKey == NULL)
3789 {
3790 Status = -ENOMEM;
3791 break;
3792 }
3793
3794 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3795 if (pKey->Length != wrq->u.data.length)
3796 {
3797 Status = -EINVAL;
3798 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
3799 }
3800 else
3801 {
3802 if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
3803 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
3804 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
3805 {
3806 Status = -EOPNOTSUPP;
3807 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
3808 }
3809 else if ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3810 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
3811 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) ) // Only for WPA PSK mode
3812 {
3813 NdisMoveMemory(pAdapter->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
3814 // Use RaConfig as PSK agent.
3815 // Start STA supplicant state machine
3816 if (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
3817 pAdapter->StaCfg.WpaState = SS_START;
3818
3819 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3820 }
3821 else
3822 {
3823 pAdapter->StaCfg.WpaState = SS_NOTUSE;
3824 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3825 }
3826 }
3827 kfree(pKey);
3828 break;
3829 case OID_802_11_REMOVE_KEY:
3830 pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3831 if(pRemoveKey == NULL)
3832 {
3833 Status = -ENOMEM;
3834 break;
3835 }
3836
3837 Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
3838 if (pRemoveKey->Length != wrq->u.data.length)
3839 {
3840 Status = -EINVAL;
3841 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
3842 }
3843 else
3844 {
3845 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3846 {
3847 RTMPWPARemoveKeyProc(pAdapter, pRemoveKey);
3848 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
3849 }
3850 else
3851 {
3852 KeyIdx = pRemoveKey->KeyIndex;
3853
3854 if (KeyIdx & 0x80000000)
3855 {
3856 // Should never set default bit when remove key
3857 Status = -EINVAL;
3858 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
3859 }
3860 else
3861 {
3862 KeyIdx = KeyIdx & 0x0fffffff;
3863 if (KeyIdx > 3)
3864 {
3865 Status = -EINVAL;
3866 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
3867 }
3868 else
3869 {
3870 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3871 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3872 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3873 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
3874 }
3875 }
3876 }
3877 }
3878 kfree(pRemoveKey);
3879 break;
3880 // New for WPA
3881 case OID_802_11_ADD_KEY:
3882 pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3883 if(pKey == NULL)
3884 {
3885 Status = -ENOMEM;
3886 break;
3887 }
3888 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3889 if (pKey->Length != wrq->u.data.length)
3890 {
3891 Status = -EINVAL;
3892 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
3893 }
3894 else
3895 {
3896 RTMPAddKey(pAdapter, pKey);
3897 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3898 }
3899 kfree(pKey);
3900 break;
3901 case OID_802_11_CONFIGURATION:
3902 if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
3903 Status = -EINVAL;
3904 else
3905 {
3906 Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
3907 pConfig = &Config;
3908
3909 if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
3910 pAdapter->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
3911
3912 pAdapter->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
3913 MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAdapter->CommonCfg.Channel);
3914 //
3915 // Save the channel on MlmeAux for CntlOidRTBssidProc used.
3916 //
3917 pAdapter->MlmeAux.Channel = pAdapter->CommonCfg.Channel;
3918
3919 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
3920 pConfig->BeaconPeriod, pConfig->ATIMWindow, pAdapter->CommonCfg.Channel));
3921 // Config has changed
3922 pAdapter->bConfigChanged = TRUE;
3923 }
3924 break;
3925#ifdef DOT11_N_SUPPORT
3926 case RT_OID_802_11_SET_HT_PHYMODE:
3927 if (wrq->u.data.length != sizeof(OID_SET_HT_PHYMODE))
3928 Status = -EINVAL;
3929 else
3930 {
3931 POID_SET_HT_PHYMODE pHTPhyMode = &HT_PhyMode;
3932
3933 Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3934 DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode (PhyMode = %d,TransmitNo = %d, HtMode = %d, ExtOffset = %d , MCS = %d, BW = %d, STBC = %d, SHORTGI = %d) \n",
3935 pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
3936 pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
3937 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
3938 RTMPSetHT(pAdapter, pHTPhyMode);
3939 }
3940 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
3941 pAdapter->StaCfg.HTPhyMode.field.MCS, pAdapter->StaCfg.HTPhyMode.field.BW, pAdapter->StaCfg.HTPhyMode.field.ShortGI,
3942 pAdapter->StaCfg.HTPhyMode.field.STBC));
3943 break;
3944#endif // DOT11_N_SUPPORT //
3945 case RT_OID_802_11_SET_APSD_SETTING:
3946 if (wrq->u.data.length != sizeof(ULONG))
3947 Status = -EINVAL;
3948 else
3949 {
3950 ULONG apsd ;
3951 Status = copy_from_user(&apsd, wrq->u.data.pointer, wrq->u.data.length);
3952
3953 /*-------------------------------------------------------------------
3954 |B31~B7 | B6~B5 | B4 | B3 | B2 | B1 | B0 |
3955 ---------------------------------------------------------------------
3956 | Rsvd | Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD Capable |
3957 ---------------------------------------------------------------------*/
3958 pAdapter->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE : FALSE;
3959 pAdapter->CommonCfg.bAPSDAC_BE = ((apsd & 0x00000002) >> 1) ? TRUE : FALSE;
3960 pAdapter->CommonCfg.bAPSDAC_BK = ((apsd & 0x00000004) >> 2) ? TRUE : FALSE;
3961 pAdapter->CommonCfg.bAPSDAC_VI = ((apsd & 0x00000008) >> 3) ? TRUE : FALSE;
3962 pAdapter->CommonCfg.bAPSDAC_VO = ((apsd & 0x00000010) >> 4) ? TRUE : FALSE;
3963 pAdapter->CommonCfg.MaxSPLength = (UCHAR)((apsd & 0x00000060) >> 5);
3964
3965 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,
3966 pAdapter->CommonCfg.bAPSDAC_BE, pAdapter->CommonCfg.bAPSDAC_BK, pAdapter->CommonCfg.bAPSDAC_VI, pAdapter->CommonCfg.bAPSDAC_VO, pAdapter->CommonCfg.MaxSPLength));
3967 }
3968 break;
3969
3970 case RT_OID_802_11_SET_APSD_PSM:
3971 if (wrq->u.data.length != sizeof(ULONG))
3972 Status = -EINVAL;
3973 else
3974 {
3975 // Driver needs to notify AP when PSM changes
3976 Status = copy_from_user(&pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
3977 if (pAdapter->CommonCfg.bAPSDForcePowerSave != pAdapter->StaCfg.Psm)
3978 {
3979 MlmeSetPsmBit(pAdapter, pAdapter->CommonCfg.bAPSDForcePowerSave);
3980 RTMPSendNullFrame(pAdapter, pAdapter->CommonCfg.TxRate, TRUE);
3981 }
3982 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
3983 }
3984 break;
3985#ifdef QOS_DLS_SUPPORT
3986 case RT_OID_802_11_SET_DLS:
3987 if (wrq->u.data.length != sizeof(ULONG))
3988 Status = -EINVAL;
3989 else
3990 {
3991 BOOLEAN oldvalue = pAdapter->CommonCfg.bDLSCapable;
3992 Status = copy_from_user(&pAdapter->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
3993 if (oldvalue && !pAdapter->CommonCfg.bDLSCapable)
3994 {
3995 int i;
3996 // tear down local dls table entry
3997 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
3998 {
3999 if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
4000 {
4001 pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
4002 pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
4003 RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
4004 }
4005 }
4006
4007 // tear down peer dls table entry
4008 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
4009 {
4010 if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
4011 {
4012 pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
4013 pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
4014 RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
4015 }
4016 }
4017 }
4018
4019 DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAdapter->CommonCfg.bDLSCapable));
4020 }
4021 break;
4022
4023 case RT_OID_802_11_SET_DLS_PARAM:
4024 if (wrq->u.data.length != sizeof(RT_802_11_DLS_UI))
4025 Status = -EINVAL;
4026 else
4027 {
4028 RT_802_11_DLS Dls;
4029
4030 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
4031 RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI));
4032 MlmeEnqueue(pAdapter,
4033 MLME_CNTL_STATE_MACHINE,
4034 RT_OID_802_11_SET_DLS_PARAM,
4035 sizeof(RT_802_11_DLS),
4036 &Dls);
4037 DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n"));
4038 }
4039 break;
4040#endif // QOS_DLS_SUPPORT //
4041 case RT_OID_802_11_SET_WMM:
4042 if (wrq->u.data.length != sizeof(BOOLEAN))
4043 Status = -EINVAL;
4044 else
4045 {
4046 Status = copy_from_user(&pAdapter->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
4047 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d) \n", pAdapter->CommonCfg.bWmmCapable));
4048 }
4049 break;
4050
4051 case OID_802_11_DISASSOCIATE:
4052#ifdef RALINK_ATE
4053 if (ATE_ON(pAdapter))
4054 {
4055 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4056 break;
4057 }
4058#endif // RALINK_ATE //
4059 //
4060 // Set NdisRadioStateOff to TRUE, instead of called MlmeRadioOff.
4061 // Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be 0
4062 // when query OID_802_11_BSSID_LIST.
4063 //
4064 // TRUE: NumberOfItems will set to 0.
4065 // FALSE: NumberOfItems no change.
4066 //
4067 pAdapter->CommonCfg.NdisRadioStateOff = TRUE;
4068 // Set to immediately send the media disconnect event
4069 pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
4070 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE \n"));
4071
4072 if (INFRA_ON(pAdapter))
4073 {
4074 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
4075 {
4076 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
4077 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
4078 }
4079
4080 MlmeEnqueue(pAdapter,
4081 MLME_CNTL_STATE_MACHINE,
4082 OID_802_11_DISASSOCIATE,
4083 0,
4084 NULL);
4085
4086 StateMachineTouched = TRUE;
4087 }
4088 break;
4089
4090#ifdef DOT11_N_SUPPORT
4091 case RT_OID_802_11_SET_IMME_BA_CAP:
4092 if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
4093 Status = -EINVAL;
4094 else
4095 {
4096 OID_BACAP_STRUC Orde ;
4097 Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
4098 if (Orde.Policy > BA_NOTUSE)
4099 {
4100 Status = NDIS_STATUS_INVALID_DATA;
4101 }
4102 else if (Orde.Policy == BA_NOTUSE)
4103 {
4104 pAdapter->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
4105 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4106 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4107 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4108 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4109 pAdapter->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
4110 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4111 // UPdata to HT IE
4112 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4113 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4114 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4115 }
4116 else
4117 {
4118 pAdapter->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
4119 pAdapter->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
4120 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4121 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4122 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4123 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4124 pAdapter->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
4125 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4126
4127 // UPdata to HT IE
4128 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4129 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4130 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4131
4132 if (pAdapter->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
4133 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
4134
4135 }
4136
4137 pAdapter->CommonCfg.REGBACapability.word = pAdapter->CommonCfg.BACapability.word;
4138 DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAdapter->CommonCfg.BACapability.field.Policy,
4139 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit,pAdapter->CommonCfg.BACapability.field.TxBAWinLimit, pAdapter->CommonCfg.BACapability.field.AutoBA));
4140 DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAdapter->CommonCfg.DesiredHtPhy.MimoPs, pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable,
4141 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize, pAdapter->CommonCfg.DesiredHtPhy.MpduDensity));
4142 }
4143
4144 break;
4145 case RT_OID_802_11_ADD_IMME_BA:
4146 DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
4147 if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4148 Status = -EINVAL;
4149 else
4150 {
4151 UCHAR index;
4152 OID_ADD_BA_ENTRY BA;
4153 MAC_TABLE_ENTRY *pEntry;
4154
4155 Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
4156 if (BA.TID > 15)
4157 {
4158 Status = NDIS_STATUS_INVALID_DATA;
4159 break;
4160 }
4161 else
4162 {
4163 //BATableInsertEntry
4164 //As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
4165 index = BA.TID;
4166 // in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
4167 pEntry = MacTableLookup(pAdapter, BA.MACAddr);
4168 if (!pEntry)
4169 {
4170 DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
4171 break;
4172 }
4173 if (BA.IsRecipient == FALSE)
4174 {
4175 if (pEntry->bIAmBadAtheros == TRUE)
4176 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
4177
4178 BAOriSessionSetUp(pAdapter, pEntry, index, 0, 100, TRUE);
4179 }
4180 else
4181 {
4182 //BATableInsertEntry(pAdapter, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
4183 }
4184
4185 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
4186 BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
4187 , BA.MACAddr[4], BA.MACAddr[5]));
4188 }
4189 }
4190 break;
4191
4192 case RT_OID_802_11_TEAR_IMME_BA:
4193 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
4194 if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4195 Status = -EINVAL;
4196 else
4197 {
4198 POID_ADD_BA_ENTRY pBA;
4199 MAC_TABLE_ENTRY *pEntry;
4200
4201 pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4202
4203 if (pBA == NULL)
4204 {
4205 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
4206 Status = NDIS_STATUS_FAILURE;
4207 }
4208 else
4209 {
4210 Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
4211 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
4212
4213 if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
4214 {
4215 Status = NDIS_STATUS_INVALID_DATA;
4216 break;
4217 }
4218
4219 if (pBA->IsRecipient == FALSE)
4220 {
4221 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4222 DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
4223 if (pEntry)
4224 {
4225 DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
4226 BAOriSessionTearDown(pAdapter, pEntry->Aid, pBA->TID, FALSE, TRUE);
4227 }
4228 else
4229 DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4230 }
4231 else
4232 {
4233 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4234 if (pEntry)
4235 {
4236 BARecSessionTearDown( pAdapter, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
4237 }
4238 else
4239 DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4240 }
4241 kfree(pBA);
4242 }
4243 }
4244 break;
4245#endif // DOT11_N_SUPPORT //
4246
4247 // For WPA_SUPPLICANT to set static wep key
4248 case OID_802_11_ADD_WEP:
4249 pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4250
4251 if(pWepKey == NULL)
4252 {
4253 Status = -ENOMEM;
4254 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
4255 break;
4256 }
4257 Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
4258 if (Status)
4259 {
4260 Status = -EINVAL;
4261 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
4262 }
4263 else
4264 {
4265 KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
4266 // KeyIdx must be 0 ~ 3
4267 if (KeyIdx > 4)
4268 {
4269 Status = -EINVAL;
4270 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
4271 }
4272 else
4273 {
4274 UCHAR CipherAlg = 0;
4275 PUCHAR Key;
4276
4277 // set key material and key length
4278 NdisZeroMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, 16);
4279 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4280 NdisMoveMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4281
4282 switch(pWepKey->KeyLength)
4283 {
4284 case 5:
4285 CipherAlg = CIPHER_WEP64;
4286 break;
4287 case 13:
4288 CipherAlg = CIPHER_WEP128;
4289 break;
4290 default:
4291 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
4292 Status = -EINVAL;
4293 break;
4294 }
4295 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
4296
4297 // Default key for tx (shared key)
4298 if (pWepKey->KeyIndex & 0x80000000)
4299 {
4300#ifdef WPA_SUPPLICANT_SUPPORT
4301 // set key material and key length
4302 NdisZeroMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
4303 pAdapter->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4304 NdisMoveMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4305 pAdapter->StaCfg.DesireSharedKeyId = KeyIdx;
4306 pAdapter->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
4307#endif // WPA_SUPPLICANT_SUPPORT //
4308 pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4309 }
4310
4311#ifdef WPA_SUPPLICANT_SUPPORT
4312 if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
4313#endif // WPA_SUPPLICANT_SUPPORT
4314 {
4315 Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
4316
4317 // Set key material and cipherAlg to Asic
4318 AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
4319
4320 if (pWepKey->KeyIndex & 0x80000000)
4321 {
4322 PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[BSSID_WCID];
4323 // Assign group key info
4324 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
4325 // Assign pairwise key info
4326 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, pEntry);
4327 }
4328 }
4329 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"));
4330 }
4331 }
4332 kfree(pWepKey);
4333 break;
4334#ifdef WPA_SUPPLICANT_SUPPORT
4335 case OID_SET_COUNTERMEASURES:
4336 if (wrq->u.data.length != sizeof(int))
4337 Status = -EINVAL;
4338 else
4339 {
4340 int enabled = 0;
4341 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4342 if (enabled == 1)
4343 pAdapter->StaCfg.bBlockAssoc = TRUE;
4344 else
4345 // WPA MIC error should block association attempt for 60 seconds
4346 pAdapter->StaCfg.bBlockAssoc = FALSE;
4347 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAdapter->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
4348 }
4349 break;
4350 case RT_OID_WPA_SUPPLICANT_SUPPORT:
4351 if (wrq->u.data.length != sizeof(UCHAR))
4352 Status = -EINVAL;
4353 else
4354 {
4355 Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
4356 pAdapter->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
4357 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
4358 }
4359 break;
4360 case OID_802_11_DEAUTHENTICATION:
4361 if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
4362 Status = -EINVAL;
4363 else
4364 {
4365 MLME_DEAUTH_REQ_STRUCT *pInfo;
4366 MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
4367
4368 pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
4369 Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
4370 MlmeDeauthReqAction(pAdapter, MsgElem);
4371 kfree(MsgElem);
4372
4373 if (INFRA_ON(pAdapter))
4374 {
4375 LinkDown(pAdapter, FALSE);
4376 pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
4377 }
4378 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
4379 }
4380 break;
4381 case OID_802_11_DROP_UNENCRYPTED:
4382 if (wrq->u.data.length != sizeof(int))
4383 Status = -EINVAL;
4384 else
4385 {
4386 int enabled = 0;
4387 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4388 if (enabled == 1)
4389 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
4390 else
4391 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
4392 NdisAcquireSpinLock(&pAdapter->MacTabLock);
4393 pAdapter->MacTab.Content[BSSID_WCID].PortSecured = pAdapter->StaCfg.PortSecured;
4394 NdisReleaseSpinLock(&pAdapter->MacTabLock);
4395 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
4396 }
4397 break;
4398 case OID_802_11_SET_IEEE8021X:
4399 if (wrq->u.data.length != sizeof(BOOLEAN))
4400 Status = -EINVAL;
4401 else
4402 {
4403 Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
4404 pAdapter->StaCfg.IEEE8021X = IEEE8021xState;
4405 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
4406 }
4407 break;
4408 case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
4409 if (wrq->u.data.length != sizeof(BOOLEAN))
4410 Status = -EINVAL;
4411 else
4412 {
4413 Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
4414 pAdapter->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
4415 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
4416 }
4417 break;
4418 case OID_802_11_PMKID:
4419 pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4420
4421 if(pPmkId == NULL) {
4422 Status = -ENOMEM;
4423 break;
4424 }
4425 Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
4426
4427 // check the PMKID information
4428 if (pPmkId->BSSIDInfoCount == 0)
4429 NdisZeroMemory(pAdapter->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
4430 else
4431 {
4432 PBSSID_INFO pBssIdInfo;
4433 UINT BssIdx;
4434 UINT CachedIdx;
4435
4436 for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
4437 {
4438 // point to the indexed BSSID_INFO structure
4439 pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
4440 // Find the entry in the saved data base.
4441 for (CachedIdx = 0; CachedIdx < pAdapter->StaCfg.SavedPMKNum; CachedIdx++)
4442 {
4443 // compare the BSSID
4444 if (NdisEqualMemory(pBssIdInfo->BSSID, pAdapter->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
4445 break;
4446 }
4447
4448 // Found, replace it
4449 if (CachedIdx < PMKID_NO)
4450 {
4451 DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4452 NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4453 pAdapter->StaCfg.SavedPMKNum++;
4454 }
4455 // Not found, replace the last one
4456 else
4457 {
4458 // Randomly replace one
4459 CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
4460 DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4461 NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4462 }
4463 }
4464 }
4465 if(pPmkId)
4466 kfree(pPmkId);
4467 break;
4468#endif // WPA_SUPPLICANT_SUPPORT //
4469
4470
4471
4472#ifdef SNMP_SUPPORT
4473 case OID_802_11_SHORTRETRYLIMIT:
4474 if (wrq->u.data.length != sizeof(ULONG))
4475 Status = -EINVAL;
4476 else
4477 {
4478 Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4479 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4480 tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
4481 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4482 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit));
4483 }
4484 break;
4485
4486 case OID_802_11_LONGRETRYLIMIT:
4487 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n"));
4488 if (wrq->u.data.length != sizeof(ULONG))
4489 Status = -EINVAL;
4490 else
4491 {
4492 Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4493 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4494 tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
4495 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4496 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit));
4497 }
4498 break;
4499
4500 case OID_802_11_WEPDEFAULTKEYVALUE:
4501 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n"));
4502 pKey = kmalloc(wrq->u.data.length, GFP_KERNEL);
4503 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
4504 //pKey = &WepKey;
4505
4506 if ( pKey->Length != wrq->u.data.length)
4507 {
4508 Status = -EINVAL;
4509 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n"));
4510 }
4511 KeyIdx = pKey->KeyIndex & 0x0fffffff;
4512 DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength));
4513
4514 // it is a shared key
4515 if (KeyIdx > 4)
4516 Status = -EINVAL;
4517 else
4518 {
4519 pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
4520 NdisMoveMemory(&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
4521 if (pKey->KeyIndex & 0x80000000)
4522 {
4523 // Default key for tx (shared key)
4524 pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4525 }
4526 //RestartAPIsRequired = TRUE;
4527 }
4528 break;
4529
4530
4531 case OID_802_11_WEPDEFAULTKEYID:
4532 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n"));
4533
4534 if (wrq->u.data.length != sizeof(UCHAR))
4535 Status = -EINVAL;
4536 else
4537 Status = copy_from_user(&pAdapter->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length);
4538
4539 break;
4540
4541
4542 case OID_802_11_CURRENTCHANNEL:
4543 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n"));
4544 if (wrq->u.data.length != sizeof(UCHAR))
4545 Status = -EINVAL;
4546 else
4547 {
4548 Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length);
4549 sprintf(&ctmp,"%d", ctmp);
4550 Set_Channel_Proc(pAdapter, &ctmp);
4551 }
4552 break;
4553#endif
4554
4555
4556
4557 default:
4558 DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
4559 Status = -EOPNOTSUPP;
4560 break;
4561 }
4562
4563
4564 return Status;
4565}
4566
4567INT RTMPQueryInformation(
4568 IN PRTMP_ADAPTER pAdapter,
4569 IN OUT struct ifreq *rq,
4570 IN INT cmd)
4571{
4572 struct iwreq *wrq = (struct iwreq *) rq;
4573 NDIS_802_11_BSSID_LIST_EX *pBssidList = NULL;
4574 PNDIS_WLAN_BSSID_EX pBss;
4575 NDIS_802_11_SSID Ssid;
4576 NDIS_802_11_CONFIGURATION *pConfiguration = NULL;
4577 RT_802_11_LINK_STATUS *pLinkStatus = NULL;
4578 RT_802_11_STA_CONFIG *pStaConfig = NULL;
4579 NDIS_802_11_STATISTICS *pStatistics = NULL;
4580 NDIS_802_11_RTS_THRESHOLD RtsThresh;
4581 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
4582 NDIS_802_11_POWER_MODE PowerMode;
4583 NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
4584 RT_802_11_PREAMBLE PreamType;
4585 NDIS_802_11_AUTHENTICATION_MODE AuthMode;
4586 NDIS_802_11_WEP_STATUS WepStatus;
4587 NDIS_MEDIA_STATE MediaState;
4588 ULONG BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
4589 USHORT BssLen = 0;
4590 PUCHAR pBuf = NULL, pPtr;
4591 INT Status = NDIS_STATUS_SUCCESS;
4592 UINT we_version_compiled;
4593 UCHAR i, Padding = 0;
4594 BOOLEAN RadioState;
4595 UCHAR driverVersion[8];
4596 OID_SET_HT_PHYMODE *pHTPhyMode = NULL;
4597
4598
4599#ifdef SNMP_SUPPORT
4600 //for snmp, kathy
4601 DefaultKeyIdxValue *pKeyIdxValue;
4602 INT valueLen;
4603 TX_RTY_CFG_STRUC tx_rty_cfg;
4604 ULONG ShortRetryLimit, LongRetryLimit;
4605 UCHAR tmp[64];
4606#endif //SNMP
4607
4608 switch(cmd)
4609 {
4610 case RT_OID_DEVICE_NAME:
4611 wrq->u.data.length = sizeof(STA_NIC_DEVICE_NAME);
4612 Status = copy_to_user(wrq->u.data.pointer, STA_NIC_DEVICE_NAME, wrq->u.data.length);
4613 break;
4614 case RT_OID_VERSION_INFO:
4615 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
4616 wrq->u.data.length = 8*sizeof(UCHAR);
4617 sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
4618 driverVersion[7] = '\0';
4619 if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
4620 {
4621 Status = -EFAULT;
4622 }
4623 break;
4624#ifdef RALINK_ATE
4625 case RT_QUERY_ATE_TXDONE_COUNT:
4626 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_QUERY_ATE_TXDONE_COUNT \n"));
4627 wrq->u.data.length = sizeof(UINT32);
4628 if (copy_to_user(wrq->u.data.pointer, &pAdapter->ate.TxDoneCount, wrq->u.data.length))
4629 {
4630 Status = -EFAULT;
4631 }
4632 break;
4633#endif // RALINK_ATE //
4634 case OID_802_11_BSSID_LIST:
4635 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
4636 {
4637 /*
4638 * Still scanning, indicate the caller should try again.
4639 */
4640 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
4641 return -EAGAIN;
4642 }
4643 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAdapter->ScanTab.BssNr));
4644 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
4645 // Claculate total buffer size required
4646 BssBufSize = sizeof(ULONG);
4647
4648 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4649 {
4650 // Align pointer to 4 bytes boundary.
4651 //Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
4652 //if (Padding == 4)
4653 // Padding = 0;
4654 BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4655 }
4656
4657 // For safety issue, we add 256 bytes just in case
4658 BssBufSize += 256;
4659 // Allocate the same size as passed from higher layer
4660 pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
4661 if(pBuf == NULL)
4662 {
4663 Status = -ENOMEM;
4664 break;
4665 }
4666 // Init 802_11_BSSID_LIST_EX structure
4667 NdisZeroMemory(pBuf, BssBufSize);
4668 pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
4669 pBssidList->NumberOfItems = pAdapter->ScanTab.BssNr;
4670
4671 // Calculate total buffer length
4672 BssLen = 4; // Consist of NumberOfItems
4673 // Point to start of NDIS_WLAN_BSSID_EX
4674 // pPtr = pBuf + sizeof(ULONG);
4675 pPtr = (PUCHAR) &pBssidList->Bssid[0];
4676 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4677 {
4678 pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
4679 NdisMoveMemory(&pBss->MacAddress, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
4680 if ((pAdapter->ScanTab.BssEntry[i].Hidden == 1) && (pAdapter->StaCfg.bShowHiddenSSID == FALSE))
4681 {
4682 //
4683 // We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
4684 // and then failed to send EAPOl farame.
4685 //
4686 if ((pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAdapter->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
4687 {
4688 pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4689 NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4690 }
4691 else
4692 pBss->Ssid.SsidLength = 0;
4693 }
4694 else
4695 {
4696 pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4697 NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4698 }
4699 pBss->Privacy = pAdapter->ScanTab.BssEntry[i].Privacy;
4700 pBss->Rssi = pAdapter->ScanTab.BssEntry[i].Rssi - pAdapter->BbpRssiToDbmDelta;
4701 pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
4702 pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
4703 pBss->Configuration.BeaconPeriod = pAdapter->ScanTab.BssEntry[i].BeaconPeriod;
4704 pBss->Configuration.ATIMWindow = pAdapter->ScanTab.BssEntry[i].AtimWin;
4705
4706 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
4707
4708 if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_INFRA)
4709 pBss->InfrastructureMode = Ndis802_11Infrastructure;
4710 else
4711 pBss->InfrastructureMode = Ndis802_11IBSS;
4712
4713 NdisMoveMemory(pBss->SupportedRates, pAdapter->ScanTab.BssEntry[i].SupRate, pAdapter->ScanTab.BssEntry[i].SupRateLen);
4714 NdisMoveMemory(pBss->SupportedRates + pAdapter->ScanTab.BssEntry[i].SupRateLen,
4715 pAdapter->ScanTab.BssEntry[i].ExtRate,
4716 pAdapter->ScanTab.BssEntry[i].ExtRateLen);
4717
4718 if (pAdapter->ScanTab.BssEntry[i].VarIELen == 0)
4719 {
4720 pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
4721 NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4722 pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4723 }
4724 else
4725 {
4726 pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen);
4727 pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4728 NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4729 NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAdapter->ScanTab.BssEntry[i].VarIEs, pAdapter->ScanTab.BssEntry[i].VarIELen);
4730 pPtr += pAdapter->ScanTab.BssEntry[i].VarIELen;
4731 }
4732 pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4733
4734#if WIRELESS_EXT < 17
4735 if ((BssLen + pBss->Length) < wrq->u.data.length)
4736 BssLen += pBss->Length;
4737 else
4738 {
4739 pBssidList->NumberOfItems = i;
4740 break;
4741 }
4742#else
4743 BssLen += pBss->Length;
4744#endif
4745 }
4746
4747#if WIRELESS_EXT < 17
4748 wrq->u.data.length = BssLen;
4749#else
4750 if (BssLen > wrq->u.data.length)
4751 {
4752 kfree(pBssidList);
4753 return -E2BIG;
4754 }
4755 else
4756 wrq->u.data.length = BssLen;
4757#endif
4758 Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
4759 kfree(pBssidList);
4760 break;
4761 case OID_802_3_CURRENT_ADDRESS:
4762 wrq->u.data.length = MAC_ADDR_LEN;
4763 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
4764 break;
4765 case OID_GEN_MEDIA_CONNECT_STATUS:
4766 if (pAdapter->IndicateMediaState == NdisMediaStateConnected)
4767 MediaState = NdisMediaStateConnected;
4768 else
4769 MediaState = NdisMediaStateDisconnected;
4770
4771 wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
4772 Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
4773 break;
4774 case OID_802_11_BSSID:
4775#ifdef RALINK_ATE
4776 if (ATE_ON(pAdapter))
4777 {
4778 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4779 Status = NDIS_STATUS_RESOURCES;
4780 break;
4781 }
4782#endif // RALINK_ATE //
4783 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
4784 {
4785 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
4786
4787 }
4788 else
4789 {
4790 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
4791 Status = -ENOTCONN;
4792 }
4793 break;
4794 case OID_802_11_SSID:
4795 NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
4796 NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
4797 Ssid.SsidLength = pAdapter->CommonCfg.SsidLen;
4798 memcpy(Ssid.Ssid, pAdapter->CommonCfg.Ssid, Ssid.SsidLength);
4799 wrq->u.data.length = sizeof(NDIS_802_11_SSID);
4800 Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
4801 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
4802 break;
4803 case RT_OID_802_11_QUERY_LINK_STATUS:
4804 pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
4805 if (pLinkStatus)
4806 {
4807 pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAdapter->CommonCfg.TxRate]; // unit : 500 kbps
4808 pLinkStatus->ChannelQuality = pAdapter->Mlme.ChannelQuality;
4809 pLinkStatus->RxByteCount = pAdapter->RalinkCounters.ReceivedByteCount;
4810 pLinkStatus->TxByteCount = pAdapter->RalinkCounters.TransmittedByteCount;
4811 pLinkStatus->CentralChannel = pAdapter->CommonCfg.CentralChannel;
4812 wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
4813 Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
4814 kfree(pLinkStatus);
4815 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
4816 }
4817 else
4818 {
4819 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
4820 Status = -EFAULT;
4821 }
4822 break;
4823 case OID_802_11_CONFIGURATION:
4824 pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
4825 if (pConfiguration)
4826 {
4827 pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
4828 pConfiguration->BeaconPeriod = pAdapter->CommonCfg.BeaconPeriod;
4829 pConfiguration->ATIMWindow = pAdapter->StaActive.AtimWin;
4830 MAP_CHANNEL_ID_TO_KHZ(pAdapter->CommonCfg.Channel, pConfiguration->DSConfig);
4831 wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
4832 Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
4833 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
4834 pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAdapter->CommonCfg.Channel));
4835 kfree(pConfiguration);
4836 }
4837 else
4838 {
4839 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
4840 Status = -EFAULT;
4841 }
4842 break;
4843 case RT_OID_802_11_SNR_0:
4844 if ((pAdapter->StaCfg.LastSNR0 > 0))
4845 {
4846 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR0) * 3) / 16 ;
4847 wrq->u.data.length = sizeof(ulInfo);
4848 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4849 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
4850 }
4851 else
4852 Status = -EFAULT;
4853 break;
4854 case RT_OID_802_11_SNR_1:
4855 if ((pAdapter->Antenna.field.RxPath > 1) &&
4856 (pAdapter->StaCfg.LastSNR1 > 0))
4857 {
4858 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR1) * 3) / 16 ;
4859 wrq->u.data.length = sizeof(ulInfo);
4860 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4861 DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
4862 }
4863 else
4864 Status = -EFAULT;
4865 DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAdapter->StaCfg.LastSNR1=%d)\n",pAdapter->StaCfg.LastSNR1));
4866 break;
4867 case OID_802_11_RSSI_TRIGGER:
4868 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0 - pAdapter->BbpRssiToDbmDelta;
4869 wrq->u.data.length = sizeof(ulInfo);
4870 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4871 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
4872 break;
4873 case OID_802_11_RSSI:
4874 case RT_OID_802_11_RSSI:
4875 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0;
4876 wrq->u.data.length = sizeof(ulInfo);
4877 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4878 break;
4879 case RT_OID_802_11_RSSI_1:
4880 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi1;
4881 wrq->u.data.length = sizeof(ulInfo);
4882 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4883 break;
4884 case RT_OID_802_11_RSSI_2:
4885 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi2;
4886 wrq->u.data.length = sizeof(ulInfo);
4887 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4888 break;
4889 case OID_802_11_STATISTICS:
4890 pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
4891 if (pStatistics)
4892 {
4893 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
4894 // add the most up-to-date h/w raw counters into software counters
4895 NICUpdateRawCounters(pAdapter);
4896
4897 // Sanity check for calculation of sucessful count
4898 if (pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart < pAdapter->WlanCounters.RetryCount.QuadPart)
4899 pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4900
4901 pStatistics->TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart;
4902 pStatistics->MulticastTransmittedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
4903 pStatistics->FailedCount.QuadPart = pAdapter->WlanCounters.FailedCount.QuadPart;
4904 pStatistics->RetryCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4905 pStatistics->MultipleRetryCount.QuadPart = pAdapter->WlanCounters.MultipleRetryCount.QuadPart;
4906 pStatistics->RTSSuccessCount.QuadPart = pAdapter->WlanCounters.RTSSuccessCount.QuadPart;
4907 pStatistics->RTSFailureCount.QuadPart = pAdapter->WlanCounters.RTSFailureCount.QuadPart;
4908 pStatistics->ACKFailureCount.QuadPart = pAdapter->WlanCounters.ACKFailureCount.QuadPart;
4909 pStatistics->FrameDuplicateCount.QuadPart = pAdapter->WlanCounters.FrameDuplicateCount.QuadPart;
4910 pStatistics->ReceivedFragmentCount.QuadPart = pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart;
4911 pStatistics->MulticastReceivedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastReceivedFrameCount.QuadPart;
4912#ifdef DBG
4913 pStatistics->FCSErrorCount = pAdapter->RalinkCounters.RealFcsErrCount;
4914#else
4915 pStatistics->FCSErrorCount.QuadPart = pAdapter->WlanCounters.FCSErrorCount.QuadPart;
4916 pStatistics->FrameDuplicateCount.u.LowPart = pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
4917#endif
4918 wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
4919 Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
4920 kfree(pStatistics);
4921 }
4922 else
4923 {
4924 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
4925 Status = -EFAULT;
4926 }
4927 break;
4928 case OID_GEN_RCV_OK:
4929 ulInfo = pAdapter->Counters8023.GoodReceives;
4930 wrq->u.data.length = sizeof(ulInfo);
4931 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4932 break;
4933 case OID_GEN_RCV_NO_BUFFER:
4934 ulInfo = pAdapter->Counters8023.RxNoBuffer;
4935 wrq->u.data.length = sizeof(ulInfo);
4936 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4937 break;
4938 case RT_OID_802_11_PHY_MODE:
4939 ulInfo = (ULONG)pAdapter->CommonCfg.PhyMode;
4940 wrq->u.data.length = sizeof(ulInfo);
4941 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4942 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo));
4943 break;
4944 case RT_OID_802_11_STA_CONFIG:
4945 pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
4946 if (pStaConfig)
4947 {
4948 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
4949 pStaConfig->EnableTxBurst = pAdapter->CommonCfg.bEnableTxBurst;
4950 pStaConfig->EnableTurboRate = 0;
4951 pStaConfig->UseBGProtection = pAdapter->CommonCfg.UseBGProtection;
4952 pStaConfig->UseShortSlotTime = pAdapter->CommonCfg.bUseShortSlotTime;
4953 //pStaConfig->AdhocMode = pAdapter->StaCfg.AdhocMode;
4954 pStaConfig->HwRadioStatus = (pAdapter->StaCfg.bHwRadio == TRUE) ? 1 : 0;
4955 pStaConfig->Rsv1 = 0;
4956 pStaConfig->SystemErrorBitmap = pAdapter->SystemErrorBitmap;
4957 wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
4958 Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
4959 kfree(pStaConfig);
4960 }
4961 else
4962 {
4963 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
4964 Status = -EFAULT;
4965 }
4966 break;
4967 case OID_802_11_RTS_THRESHOLD:
4968 RtsThresh = pAdapter->CommonCfg.RtsThreshold;
4969 wrq->u.data.length = sizeof(RtsThresh);
4970 Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
4971 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
4972 break;
4973 case OID_802_11_FRAGMENTATION_THRESHOLD:
4974 FragThresh = pAdapter->CommonCfg.FragmentThreshold;
4975 if (pAdapter->CommonCfg.bUseZeroToDisableFragment == TRUE)
4976 FragThresh = 0;
4977 wrq->u.data.length = sizeof(FragThresh);
4978 Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
4979 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
4980 break;
4981 case OID_802_11_POWER_MODE:
4982 PowerMode = pAdapter->StaCfg.WindowsPowerMode;
4983 wrq->u.data.length = sizeof(PowerMode);
4984 Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
4985 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
4986 break;
4987 case RT_OID_802_11_RADIO:
4988 RadioState = (BOOLEAN) pAdapter->StaCfg.bSwRadio;
4989 wrq->u.data.length = sizeof(RadioState);
4990 Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
4991 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
4992 break;
4993 case OID_802_11_INFRASTRUCTURE_MODE:
4994 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
4995 BssType = Ndis802_11IBSS;
4996 else if (pAdapter->StaCfg.BssType == BSS_INFRA)
4997 BssType = Ndis802_11Infrastructure;
4998 else if (pAdapter->StaCfg.BssType == BSS_MONITOR)
4999 BssType = Ndis802_11Monitor;
5000 else
5001 BssType = Ndis802_11AutoUnknown;
5002
5003 wrq->u.data.length = sizeof(BssType);
5004 Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
5005 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
5006 break;
5007 case RT_OID_802_11_PREAMBLE:
5008 PreamType = pAdapter->CommonCfg.TxPreamble;
5009 wrq->u.data.length = sizeof(PreamType);
5010 Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
5011 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
5012 break;
5013 case OID_802_11_AUTHENTICATION_MODE:
5014 AuthMode = pAdapter->StaCfg.AuthMode;
5015 wrq->u.data.length = sizeof(AuthMode);
5016 Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
5017 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
5018 break;
5019 case OID_802_11_WEP_STATUS:
5020 WepStatus = pAdapter->StaCfg.WepStatus;
5021 wrq->u.data.length = sizeof(WepStatus);
5022 Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
5023 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
5024 break;
5025 case OID_802_11_TX_POWER_LEVEL:
5026 wrq->u.data.length = sizeof(ULONG);
5027 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPower, wrq->u.data.length);
5028 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAdapter->CommonCfg.TxPower));
5029 break;
5030 case RT_OID_802_11_TX_POWER_LEVEL_1:
5031 wrq->u.data.length = sizeof(ULONG);
5032 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPowerPercentage, wrq->u.data.length);
5033 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
5034 break;
5035 case OID_802_11_NETWORK_TYPES_SUPPORTED:
5036 if ((pAdapter->RfIcType == RFIC_2850) || (pAdapter->RfIcType == RFIC_2750))
5037 {
5038 NetworkTypeList[0] = 3; // NumberOfItems = 3
5039 NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
5040 NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
5041 NetworkTypeList[3] = Ndis802_11OFDM5; // NetworkType[3] = 11a
5042 wrq->u.data.length = 16;
5043 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
5044 }
5045 else
5046 {
5047 NetworkTypeList[0] = 2; // NumberOfItems = 2
5048 NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
5049 NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
5050 wrq->u.data.length = 12;
5051 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
5052 }
5053 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
5054 break;
5055 case OID_802_11_NETWORK_TYPE_IN_USE:
5056 wrq->u.data.length = sizeof(ULONG);
5057 if (pAdapter->CommonCfg.PhyMode == PHY_11A)
5058 ulInfo = Ndis802_11OFDM5;
5059 else if ((pAdapter->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAdapter->CommonCfg.PhyMode == PHY_11G))
5060 ulInfo = Ndis802_11OFDM24;
5061 else
5062 ulInfo = Ndis802_11DS;
5063 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5064 break;
5065 case RT_OID_802_11_QUERY_LAST_RX_RATE:
5066 ulInfo = (ULONG)pAdapter->LastRxRate;
5067 wrq->u.data.length = sizeof(ulInfo);
5068 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5069 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
5070 break;
5071 case RT_OID_802_11_QUERY_LAST_TX_RATE:
5072 //ulInfo = (ULONG)pAdapter->LastTxRate;
5073 ulInfo = (ULONG)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word;
5074 wrq->u.data.length = sizeof(ulInfo);
5075 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5076 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
5077 break;
5078 case RT_OID_802_11_QUERY_EEPROM_VERSION:
5079 wrq->u.data.length = sizeof(ULONG);
5080 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->EepromVersion, wrq->u.data.length);
5081 break;
5082 case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
5083 wrq->u.data.length = sizeof(ULONG);
5084 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->FirmwareVersion, wrq->u.data.length);
5085 break;
5086 case RT_OID_802_11_QUERY_NOISE_LEVEL:
5087 wrq->u.data.length = sizeof(UCHAR);
5088 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->BbpWriteLatch[66], wrq->u.data.length);
5089 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAdapter->BbpWriteLatch[66]));
5090 break;
5091 case RT_OID_802_11_EXTRA_INFO:
5092 wrq->u.data.length = sizeof(ULONG);
5093 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->ExtraInfo, wrq->u.data.length);
5094 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAdapter->ExtraInfo));
5095 break;
5096 case RT_OID_WE_VERSION_COMPILED:
5097 wrq->u.data.length = sizeof(UINT);
5098 we_version_compiled = WIRELESS_EXT;
5099 Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
5100 break;
5101 case RT_OID_802_11_QUERY_APSD_SETTING:
5102 apsd = (pAdapter->CommonCfg.bAPSDCapable | (pAdapter->CommonCfg.bAPSDAC_BE << 1) | (pAdapter->CommonCfg.bAPSDAC_BK << 2)
5103 | (pAdapter->CommonCfg.bAPSDAC_VI << 3) | (pAdapter->CommonCfg.bAPSDAC_VO << 4) | (pAdapter->CommonCfg.MaxSPLength << 5));
5104
5105 wrq->u.data.length = sizeof(ULONG);
5106 Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
5107 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",
5108 apsd,pAdapter->CommonCfg.bAPSDCapable,pAdapter->CommonCfg.bAPSDAC_BE,pAdapter->CommonCfg.bAPSDAC_BK,pAdapter->CommonCfg.bAPSDAC_VI,pAdapter->CommonCfg.bAPSDAC_VO,pAdapter->CommonCfg.MaxSPLength));
5109 break;
5110 case RT_OID_802_11_QUERY_APSD_PSM:
5111 wrq->u.data.length = sizeof(ULONG);
5112 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
5113 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
5114 break;
5115 case RT_OID_802_11_QUERY_WMM:
5116 wrq->u.data.length = sizeof(BOOLEAN);
5117 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bWmmCapable, wrq->u.data.length);
5118 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n", pAdapter->CommonCfg.bWmmCapable));
5119 break;
5120#ifdef WPA_SUPPLICANT_SUPPORT
5121 case RT_OID_NEW_DRIVER:
5122 {
5123 UCHAR enabled = 1;
5124 wrq->u.data.length = sizeof(UCHAR);
5125 Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
5126 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
5127 }
5128 break;
5129 case RT_OID_WPA_SUPPLICANT_SUPPORT:
5130 wrq->u.data.length = sizeof(UCHAR);
5131 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.WpaSupplicantUP, wrq->u.data.length);
5132 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
5133 break;
5134#endif // WPA_SUPPLICANT_SUPPORT //
5135
5136 case RT_OID_DRIVER_DEVICE_NAME:
5137 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
5138 wrq->u.data.length = 16;
5139 if (copy_to_user(wrq->u.data.pointer, pAdapter->StaCfg.dev_name, wrq->u.data.length))
5140 {
5141 Status = -EFAULT;
5142 }
5143 break;
5144 case RT_OID_802_11_QUERY_HT_PHYMODE:
5145 pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5146 if (pHTPhyMode)
5147 {
5148 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5149 pHTPhyMode->HtMode = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
5150 pHTPhyMode->BW = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
5151 pHTPhyMode->MCS= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
5152 pHTPhyMode->SHORTGI= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
5153 pHTPhyMode->STBC= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
5154
5155 pHTPhyMode->ExtOffset = ((pAdapter->CommonCfg.CentralChannel < pAdapter->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
5156 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5157 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5158 {
5159 Status = -EFAULT;
5160 }
5161 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5162 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5163 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5164 }
5165 else
5166 {
5167 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5168 Status = -EFAULT;
5169 }
5170 break;
5171 case RT_OID_802_11_COUNTRY_REGION:
5172 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
5173 wrq->u.data.length = sizeof(ulInfo);
5174 ulInfo = pAdapter->CommonCfg.CountryRegionForABand;
5175 ulInfo = (ulInfo << 8)|(pAdapter->CommonCfg.CountryRegion);
5176 if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
5177 {
5178 Status = -EFAULT;
5179 }
5180 break;
5181 case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
5182 pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5183 if (pHTPhyMode)
5184 {
5185 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5186 pHTPhyMode->HtMode = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.HTMODE;
5187 pHTPhyMode->BW = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.BW;
5188 pHTPhyMode->MCS= (UCHAR)pAdapter->StaCfg.DesiredTransmitSetting.field.MCS;
5189 pHTPhyMode->SHORTGI= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.ShortGI;
5190 pHTPhyMode->STBC= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.STBC;
5191
5192 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5193 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5194 {
5195 Status = -EFAULT;
5196 }
5197 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5198 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5199 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5200 }
5201 else
5202 {
5203 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5204 Status = -EFAULT;
5205 }
5206 break;
5207 case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
5208 wrq->u.data.length = sizeof(UCHAR);
5209 i = 0;
5210#ifdef MULTIPLE_CARD_SUPPORT
5211 i = 1;
5212#endif // MULTIPLE_CARD_SUPPORT //
5213 if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
5214 {
5215 Status = -EFAULT;
5216 }
5217 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
5218 break;
5219#ifdef SNMP_SUPPORT
5220 case RT_OID_802_11_MAC_ADDRESS:
5221 wrq->u.data.length = MAC_ADDR_LEN;
5222 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5223 break;
5224
5225 case RT_OID_802_11_MANUFACTUREROUI:
5226 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n"));
5227 wrq->u.data.length = ManufacturerOUI_LEN;
5228 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5229 break;
5230
5231 case RT_OID_802_11_MANUFACTURERNAME:
5232 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n"));
5233 wrq->u.data.length = strlen(ManufacturerNAME);
5234 Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5235 break;
5236
5237 case RT_OID_802_11_RESOURCETYPEIDNAME:
5238 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n"));
5239 wrq->u.data.length = strlen(ResourceTypeIdName);
5240 Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length);
5241 break;
5242
5243 case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED:
5244 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n"));
5245 ulInfo = 1; // 1 is support wep else 2 is not support.
5246 wrq->u.data.length = sizeof(ulInfo);
5247 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5248 break;
5249
5250 case RT_OID_802_11_POWERMANAGEMENTMODE:
5251 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
5252 if (pAdapter->StaCfg.Psm == PSMP_ACTION)
5253 ulInfo = 1; // 1 is power active else 2 is power save.
5254 else
5255 ulInfo = 2;
5256
5257 wrq->u.data.length = sizeof(ulInfo);
5258 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5259 break;
5260
5261 case OID_802_11_WEPDEFAULTKEYVALUE:
5262 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n"));
5263 //KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId;
5264 pKeyIdxValue = wrq->u.data.pointer;
5265 DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
5266 valueLen = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
5267 NdisMoveMemory(pKeyIdxValue->Value,
5268 &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key,
5269 valueLen);
5270 pKeyIdxValue->Value[valueLen]='\0';
5271
5272 wrq->u.data.length = sizeof(DefaultKeyIdxValue);
5273
5274 Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length);
5275 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,
5276 pAdapter->SharedKey[BSS0][0].Key[0],
5277 pAdapter->SharedKey[BSS0][1].Key[0],
5278 pAdapter->SharedKey[BSS0][2].Key[0],
5279 pAdapter->SharedKey[BSS0][3].Key[0]));
5280 break;
5281
5282 case OID_802_11_WEPDEFAULTKEYID:
5283 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n"));
5284 wrq->u.data.length = sizeof(UCHAR);
5285 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length);
5286 DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAdapter->StaCfg.DefaultKeyId));
5287 break;
5288
5289 case RT_OID_802_11_WEPKEYMAPPINGLENGTH:
5290 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n"));
5291 wrq->u.data.length = sizeof(UCHAR);
5292 Status = copy_to_user(wrq->u.data.pointer,
5293 &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
5294 wrq->u.data.length);
5295 break;
5296
5297 case OID_802_11_SHORTRETRYLIMIT:
5298 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n"));
5299 wrq->u.data.length = sizeof(ULONG);
5300 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5301 ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit;
5302 DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld, tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit));
5303 Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length);
5304 break;
5305
5306 case OID_802_11_LONGRETRYLIMIT:
5307 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n"));
5308 wrq->u.data.length = sizeof(ULONG);
5309 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5310 LongRetryLimit = tx_rty_cfg.field.LongRtyLimit;
5311 DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld, tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit));
5312 Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length);
5313 break;
5314
5315 case RT_OID_802_11_PRODUCTID:
5316 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
5317
5318#ifdef RT2870
5319 sprintf(tmp, "%04x %04x\n", ((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idVendor ,((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idProduct);
5320
5321#endif // RT2870 //
5322 wrq->u.data.length = strlen(tmp);
5323 Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
5324 break;
5325
5326 case RT_OID_802_11_MANUFACTUREID:
5327 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n"));
5328 wrq->u.data.length = strlen(ManufacturerNAME);
5329 Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5330 break;
5331
5332 case OID_802_11_CURRENTCHANNEL:
5333 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n"));
5334 wrq->u.data.length = sizeof(UCHAR);
5335 DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAdapter->CommonCfg.Channel));
5336 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Channel, wrq->u.data.length);
5337 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5338 break;
5339#endif //SNMP_SUPPORT
5340
5341 case OID_802_11_BUILD_CHANNEL_EX:
5342 {
5343 UCHAR value;
5344 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
5345 wrq->u.data.length = sizeof(UCHAR);
5346#ifdef EXT_BUILD_CHANNEL_LIST
5347 DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n"));
5348 value = 1;
5349#else
5350 DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
5351 value = 0;
5352#endif // EXT_BUILD_CHANNEL_LIST //
5353 Status = copy_to_user(wrq->u.data.pointer, &value, 1);
5354 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5355 }
5356 break;
5357
5358 case OID_802_11_GET_CH_LIST:
5359 {
5360 PRT_CHANNEL_LIST_INFO pChListBuf;
5361
5362 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
5363 if (pAdapter->ChannelListNum == 0)
5364 {
5365 wrq->u.data.length = 0;
5366 break;
5367 }
5368
5369 pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
5370 if (pChListBuf == NULL)
5371 {
5372 wrq->u.data.length = 0;
5373 break;
5374 }
5375
5376 pChListBuf->ChannelListNum = pAdapter->ChannelListNum;
5377 for (i = 0; i < pChListBuf->ChannelListNum; i++)
5378 pChListBuf->ChannelList[i] = pAdapter->ChannelList[i].Channel;
5379
5380 wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
5381 Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
5382 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5383
5384 if (pChListBuf)
5385 kfree(pChListBuf);
5386 }
5387 break;
5388
5389 case OID_802_11_GET_COUNTRY_CODE:
5390 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
5391 wrq->u.data.length = 2;
5392 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.CountryCode, 2);
5393 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5394 break;
5395
5396 case OID_802_11_GET_CHANNEL_GEOGRAPHY:
5397 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
5398 wrq->u.data.length = 1;
5399 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Geography, 1);
5400 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5401 break;
5402
5403
5404#ifdef QOS_DLS_SUPPORT
5405 case RT_OID_802_11_QUERY_DLS:
5406 wrq->u.data.length = sizeof(BOOLEAN);
5407 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bDLSCapable, wrq->u.data.length);
5408 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAdapter->CommonCfg.bDLSCapable));
5409 break;
5410
5411 case RT_OID_802_11_QUERY_DLS_PARAM:
5412 {
5413 PRT_802_11_DLS_INFO pDlsInfo = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC);
5414 if (pDlsInfo == NULL)
5415 break;
5416
5417 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
5418 {
5419 RTMPMoveMemory(&pDlsInfo->Entry[i], &pAdapter->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI));
5420 }
5421
5422 pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY;
5423 wrq->u.data.length = sizeof(RT_802_11_DLS_INFO);
5424 Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length);
5425 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n"));
5426
5427 if (pDlsInfo)
5428 kfree(pDlsInfo);
5429 }
5430 break;
5431#endif // QOS_DLS_SUPPORT //
5432 default:
5433 DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
5434 Status = -EOPNOTSUPP;
5435 break;
5436 }
5437 return Status;
5438}
5439
5440INT rt28xx_sta_ioctl(
5441 IN struct net_device *net_dev,
5442 IN OUT struct ifreq *rq,
5443 IN INT cmd)
5444{
5445 POS_COOKIE pObj;
5446 VIRTUAL_ADAPTER *pVirtualAd = NULL;
5447 RTMP_ADAPTER *pAd = NULL;
5448 struct iwreq *wrq = (struct iwreq *) rq;
5449 BOOLEAN StateMachineTouched = FALSE;
5450 INT Status = NDIS_STATUS_SUCCESS;
5451 USHORT subcmd;
5452
5453 if (net_dev->priv_flags == INT_MAIN)
5454 {
5455 pAd = net_dev->priv;
5456 }
5457 else
5458 {
5459 pVirtualAd = net_dev->priv;
5460 pAd = pVirtualAd->RtmpDev->priv;
5461 }
5462 pObj = (POS_COOKIE) pAd->OS_Cookie;
5463
5464 if (pAd == NULL)
5465 {
5466 /* if 1st open fail, pAd will be free;
5467 So the net_dev->priv will be NULL in 2rd open */
5468 return -ENETDOWN;
5469 }
5470
5471 //check if the interface is down
5472 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
5473 {
5474#ifdef CONFIG_APSTA_MIXED_SUPPORT
5475 if (wrq->u.data.pointer == NULL)
5476 {
5477 return Status;
5478 }
5479
5480 if (strstr(wrq->u.data.pointer, "OpMode") == NULL)
5481#endif // CONFIG_APSTA_MIXED_SUPPORT //
5482 {
5483 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
5484 return -ENETDOWN;
5485 }
5486 }
5487
5488 { // determine this ioctl command is comming from which interface.
5489 pObj->ioctl_if_type = INT_MAIN;
5490 pObj->ioctl_if = MAIN_MBSSID;
5491 }
5492
5493 switch(cmd)
5494 {
5495#ifdef RALINK_ATE
5496#ifdef RALINK_28xx_QA
5497 case RTPRIV_IOCTL_ATE:
5498 {
5499 RtmpDoAte(pAd, wrq);
5500 }
5501 break;
5502#endif // RALINK_28xx_QA //
5503#endif // RALINK_ATE //
5504 case SIOCGIFHWADDR:
5505 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
5506 memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
5507 break;
5508 case SIOCGIWNAME:
5509 {
5510 char *name=&wrq->u.name[0];
5511 rt_ioctl_giwname(net_dev, NULL, name, NULL);
5512 break;
5513 }
5514 case SIOCGIWESSID: //Get ESSID
5515 {
5516 struct iw_point *essid=&wrq->u.essid;
5517 rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
5518 break;
5519 }
5520 case SIOCSIWESSID: //Set ESSID
5521 {
5522 struct iw_point *essid=&wrq->u.essid;
5523 rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
5524 break;
5525 }
5526 case SIOCSIWNWID: // set network id (the cell)
5527 case SIOCGIWNWID: // get network id
5528 Status = -EOPNOTSUPP;
5529 break;
5530 case SIOCSIWFREQ: //set channel/frequency (Hz)
5531 {
5532 struct iw_freq *freq=&wrq->u.freq;
5533 rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
5534 break;
5535 }
5536 case SIOCGIWFREQ: // get channel/frequency (Hz)
5537 {
5538 struct iw_freq *freq=&wrq->u.freq;
5539 rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
5540 break;
5541 }
5542 case SIOCSIWNICKN: //set node name/nickname
5543 {
5544 struct iw_point *data=&wrq->u.data;
5545 rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
5546 break;
5547 }
5548 case SIOCGIWNICKN: //get node name/nickname
5549 {
5550 struct iw_point *data=&wrq->u.data;
5551 rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
5552 break;
5553 }
5554 case SIOCGIWRATE: //get default bit rate (bps)
5555 rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
5556 break;
5557 case SIOCSIWRATE: //set default bit rate (bps)
5558 rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
5559 break;
5560 case SIOCGIWRTS: // get RTS/CTS threshold (bytes)
5561 {
5562 struct iw_param *rts=&wrq->u.rts;
5563 rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
5564 break;
5565 }
5566 case SIOCSIWRTS: //set RTS/CTS threshold (bytes)
5567 {
5568 struct iw_param *rts=&wrq->u.rts;
5569 rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
5570 break;
5571 }
5572 case SIOCGIWFRAG: //get fragmentation thr (bytes)
5573 {
5574 struct iw_param *frag=&wrq->u.frag;
5575 rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
5576 break;
5577 }
5578 case SIOCSIWFRAG: //set fragmentation thr (bytes)
5579 {
5580 struct iw_param *frag=&wrq->u.frag;
5581 rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
5582 break;
5583 }
5584 case SIOCGIWENCODE: //get encoding token & mode
5585 {
5586 struct iw_point *erq=&wrq->u.encoding;
5587 if(erq->pointer)
5588 rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
5589 break;
5590 }
5591 case SIOCSIWENCODE: //set encoding token & mode
5592 {
5593 struct iw_point *erq=&wrq->u.encoding;
5594 if(erq->pointer)
5595 rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
5596 break;
5597 }
5598 case SIOCGIWAP: //get access point MAC addresses
5599 {
5600 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5601 rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5602 break;
5603 }
5604 case SIOCSIWAP: //set access point MAC addresses
5605 {
5606 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5607 rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5608 break;
5609 }
5610 case SIOCGIWMODE: //get operation mode
5611 {
5612 __u32 *mode=&wrq->u.mode;
5613 rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
5614 break;
5615 }
5616 case SIOCSIWMODE: //set operation mode
5617 {
5618 __u32 *mode=&wrq->u.mode;
5619 rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
5620 break;
5621 }
5622 case SIOCGIWSENS: //get sensitivity (dBm)
5623 case SIOCSIWSENS: //set sensitivity (dBm)
5624 case SIOCGIWPOWER: //get Power Management settings
5625 case SIOCSIWPOWER: //set Power Management settings
5626 case SIOCGIWTXPOW: //get transmit power (dBm)
5627 case SIOCSIWTXPOW: //set transmit power (dBm)
5628 case SIOCGIWRANGE: //Get range of parameters
5629 case SIOCGIWRETRY: //get retry limits and lifetime
5630 case SIOCSIWRETRY: //set retry limits and lifetime
5631 Status = -EOPNOTSUPP;
5632 break;
5633 case RT_PRIV_IOCTL:
5634 subcmd = wrq->u.data.flags;
5635 if( subcmd & OID_GET_SET_TOGGLE)
5636 Status = RTMPSetInformation(pAd, rq, subcmd);
5637 else
5638 Status = RTMPQueryInformation(pAd, rq, subcmd);
5639 break;
5640 case SIOCGIWPRIV:
5641 if (wrq->u.data.pointer)
5642 {
5643 if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
5644 break;
5645 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
5646 if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
5647 Status = -EFAULT;
5648 }
5649 break;
5650 case RTPRIV_IOCTL_SET:
5651 if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
5652 break;
5653 rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
5654 break;
5655 case RTPRIV_IOCTL_GSITESURVEY:
5656 RTMPIoctlGetSiteSurvey(pAd, wrq);
5657 break;
5658#ifdef DBG
5659 case RTPRIV_IOCTL_MAC:
5660 RTMPIoctlMAC(pAd, wrq);
5661 break;
5662 case RTPRIV_IOCTL_E2P:
5663 RTMPIoctlE2PROM(pAd, wrq);
5664 break;
5665#endif // DBG //
5666 case SIOCETHTOOL:
5667 break;
5668 default:
5669 DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
5670 Status = -EOPNOTSUPP;
5671 break;
5672 }
5673
5674 if(StateMachineTouched) // Upper layer sent a MLME-related operations
5675 RT28XX_MLME_HANDLER(pAd);
5676
5677 return Status;
5678}
5679
5680/*
5681 ==========================================================================
5682 Description:
5683 Set SSID
5684 Return:
5685 TRUE if all parameters are OK, FALSE otherwise
5686 ==========================================================================
5687*/
5688INT Set_SSID_Proc(
5689 IN PRTMP_ADAPTER pAdapter,
5690 IN PUCHAR arg)
5691{
5692 NDIS_802_11_SSID Ssid, *pSsid=NULL;
5693 BOOLEAN StateMachineTouched = FALSE;
5694 int success = TRUE;
5695
5696 if( strlen(arg) <= MAX_LEN_OF_SSID)
5697 {
5698 NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
5699 if (strlen(arg) != 0)
5700 {
5701 NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
5702 Ssid.SsidLength = strlen(arg);
5703 }
5704 else //ANY ssid
5705 {
5706 Ssid.SsidLength = 0;
5707 memcpy(Ssid.Ssid, "", 0);
5708 pAdapter->StaCfg.BssType = BSS_INFRA;
5709 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5710 pAdapter->StaCfg.WepStatus = Ndis802_11EncryptionDisabled;
5711 }
5712 pSsid = &Ssid;
5713
5714 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
5715 {
5716 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5717 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
5718 }
5719
5720 pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
5721 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
5722 pAdapter->bConfigChanged = TRUE;
5723
5724 MlmeEnqueue(pAdapter,
5725 MLME_CNTL_STATE_MACHINE,
5726 OID_802_11_SSID,
5727 sizeof(NDIS_802_11_SSID),
5728 (VOID *)pSsid);
5729
5730 StateMachineTouched = TRUE;
5731 DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
5732 }
5733 else
5734 success = FALSE;
5735
5736 if (StateMachineTouched) // Upper layer sent a MLME-related operations
5737 RT28XX_MLME_HANDLER(pAdapter);
5738
5739 return success;
5740}
5741
5742#ifdef WMM_SUPPORT
5743/*
5744 ==========================================================================
5745 Description:
5746 Set WmmCapable Enable or Disable
5747 Return:
5748 TRUE if all parameters are OK, FALSE otherwise
5749 ==========================================================================
5750*/
5751INT Set_WmmCapable_Proc(
5752 IN PRTMP_ADAPTER pAd,
5753 IN PUCHAR arg)
5754{
5755 BOOLEAN bWmmCapable;
5756
5757 bWmmCapable = simple_strtol(arg, 0, 10);
5758
5759 if ((bWmmCapable == 1)
5760#ifdef RT2870
5761 && (pAd->NumberOfPipes >= 5)
5762#endif // RT2870 //
5763 )
5764 pAd->CommonCfg.bWmmCapable = TRUE;
5765 else if (bWmmCapable == 0)
5766 pAd->CommonCfg.bWmmCapable = FALSE;
5767 else
5768 return FALSE; //Invalid argument
5769
5770 DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
5771 pAd->CommonCfg.bWmmCapable));
5772
5773 return TRUE;
5774}
5775#endif // WMM_SUPPORT //
5776
5777/*
5778 ==========================================================================
5779 Description:
5780 Set Network Type(Infrastructure/Adhoc mode)
5781 Return:
5782 TRUE if all parameters are OK, FALSE otherwise
5783 ==========================================================================
5784*/
5785INT Set_NetworkType_Proc(
5786 IN PRTMP_ADAPTER pAdapter,
5787 IN PUCHAR arg)
5788{
5789 UINT32 Value = 0;
5790
5791 if (strcmp(arg, "Adhoc") == 0)
5792 {
5793 if (pAdapter->StaCfg.BssType != BSS_ADHOC)
5794 {
5795 // Config has changed
5796 pAdapter->bConfigChanged = TRUE;
5797 if (MONITOR_ON(pAdapter))
5798 {
5799 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5800 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5801 Value &= (~0x80);
5802 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5803 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5804 pAdapter->StaCfg.bAutoReconnect = TRUE;
5805 LinkDown(pAdapter, FALSE);
5806 }
5807 if (INFRA_ON(pAdapter))
5808 {
5809 //BOOLEAN Cancelled;
5810 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5811 // Since calling this indicate user don't want to connect to that SSID anymore.
5812 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5813 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5814
5815 LinkDown(pAdapter, FALSE);
5816
5817 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
5818 }
5819 }
5820 pAdapter->StaCfg.BssType = BSS_ADHOC;
5821 pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5822 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
5823 }
5824 else if (strcmp(arg, "Infra") == 0)
5825 {
5826 if (pAdapter->StaCfg.BssType != BSS_INFRA)
5827 {
5828 // Config has changed
5829 pAdapter->bConfigChanged = TRUE;
5830 if (MONITOR_ON(pAdapter))
5831 {
5832 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5833 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5834 Value &= (~0x80);
5835 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5836 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5837 pAdapter->StaCfg.bAutoReconnect = TRUE;
5838 LinkDown(pAdapter, FALSE);
5839 }
5840 if (ADHOC_ON(pAdapter))
5841 {
5842 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5843 // Since calling this indicate user don't want to connect to that SSID anymore.
5844 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5845 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5846
5847 LinkDown(pAdapter, FALSE);
5848 }
5849 }
5850 pAdapter->StaCfg.BssType = BSS_INFRA;
5851 pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5852 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
5853
5854 pAdapter->StaCfg.BssType = BSS_INFRA;
5855 }
5856 else if (strcmp(arg, "Monitor") == 0)
5857 {
5858 UCHAR bbpValue = 0;
5859 BCN_TIME_CFG_STRUC csr;
5860 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
5861 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
5862 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5863 // disable all periodic state machine
5864 pAdapter->StaCfg.bAutoReconnect = FALSE;
5865 // reset all mlme state machine
5866 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5867 DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
5868 if (pAdapter->CommonCfg.CentralChannel == 0)
5869 {
5870#ifdef DOT11_N_SUPPORT
5871 if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
5872 pAdapter->CommonCfg.CentralChannel = 36;
5873 else
5874#endif // DOT11_N_SUPPORT //
5875 pAdapter->CommonCfg.CentralChannel = 6;
5876 }
5877#ifdef DOT11_N_SUPPORT
5878 else
5879 N_ChannelCheck(pAdapter);
5880#endif // DOT11_N_SUPPORT //
5881
5882#ifdef DOT11_N_SUPPORT
5883 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5884 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5885 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
5886 {
5887 // 40MHz ,control channel at lower
5888 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5889 bbpValue &= (~0x18);
5890 bbpValue |= 0x10;
5891 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5892 pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5893 // RX : control channel at lower
5894 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5895 bbpValue &= (~0x20);
5896 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5897
5898 RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5899 Value &= 0xfffffffe;
5900 RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5901 pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
5902 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5903 AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5904 DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5905 pAdapter->CommonCfg.Channel,
5906 pAdapter->CommonCfg.CentralChannel));
5907 }
5908 else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5909 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5910 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
5911 {
5912 // 40MHz ,control channel at upper
5913 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5914 bbpValue &= (~0x18);
5915 bbpValue |= 0x10;
5916 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5917 pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5918 RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5919 Value |= 0x1;
5920 RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5921
5922 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5923 bbpValue |= (0x20);
5924 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5925 pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
5926 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5927 AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5928 DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5929 pAdapter->CommonCfg.Channel,
5930 pAdapter->CommonCfg.CentralChannel));
5931 }
5932 else
5933#endif // DOT11_N_SUPPORT //
5934 {
5935 // 20MHz
5936 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5937 bbpValue &= (~0x18);
5938 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5939 pAdapter->CommonCfg.BBPCurrentBW = BW_20;
5940 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
5941 AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
5942 DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
5943 }
5944 // Enable Rx with promiscuous reception
5945 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
5946 // ASIC supporsts sniffer function with replacing RSSI with timestamp.
5947 //RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5948 //Value |= (0x80);
5949 //RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5950 // disable sync
5951 RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
5952 csr.field.bBeaconGen = 0;
5953 csr.field.bTBTTEnable = 0;
5954 csr.field.TsfSyncMode = 0;
5955 RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
5956
5957 pAdapter->StaCfg.BssType = BSS_MONITOR;
5958 pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
5959 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
5960 }
5961
5962 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
5963 pAdapter->StaCfg.WpaState = SS_NOTUSE;
5964
5965 DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
5966
5967 return TRUE;
5968}
5969
5970/*
5971 ==========================================================================
5972 Description:
5973 Set Authentication mode
5974 Return:
5975 TRUE if all parameters are OK, FALSE otherwise
5976 ==========================================================================
5977*/
5978INT Set_AuthMode_Proc(
5979 IN PRTMP_ADAPTER pAdapter,
5980 IN PUCHAR arg)
5981{
5982 if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
5983 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
5984 else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
5985 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5986 else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
5987 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
5988 else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
5989 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
5990 else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
5991 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
5992 else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
5993 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
5994#ifdef WPA_SUPPLICANT_SUPPORT
5995 else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
5996 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
5997 else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
5998 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
5999#endif // WPA_SUPPLICANT_SUPPORT //
6000 else
6001 return FALSE;
6002
6003 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
6004
6005 DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
6006
6007 return TRUE;
6008}
6009
6010/*
6011 ==========================================================================
6012 Description:
6013 Set Encryption Type
6014 Return:
6015 TRUE if all parameters are OK, FALSE otherwise
6016 ==========================================================================
6017*/
6018INT Set_EncrypType_Proc(
6019 IN PRTMP_ADAPTER pAdapter,
6020 IN PUCHAR arg)
6021{
6022 if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
6023 {
6024 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6025 return TRUE; // do nothing
6026
6027 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
6028 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
6029 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
6030 }
6031 else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
6032 {
6033 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6034 return TRUE; // do nothing
6035
6036 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
6037 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
6038 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
6039 }
6040 else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
6041 {
6042 if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
6043 return TRUE; // do nothing
6044
6045 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
6046 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
6047 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
6048 }
6049 else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
6050 {
6051 if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
6052 return TRUE; // do nothing
6053
6054 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
6055 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
6056 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
6057 }
6058 else
6059 return FALSE;
6060
6061 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
6062
6063 DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
6064
6065 return TRUE;
6066}
6067
6068/*
6069 ==========================================================================
6070 Description:
6071 Set Default Key ID
6072 Return:
6073 TRUE if all parameters are OK, FALSE otherwise
6074 ==========================================================================
6075*/
6076INT Set_DefaultKeyID_Proc(
6077 IN PRTMP_ADAPTER pAdapter,
6078 IN PUCHAR arg)
6079{
6080 ULONG KeyIdx;
6081
6082 KeyIdx = simple_strtol(arg, 0, 10);
6083 if((KeyIdx >= 1 ) && (KeyIdx <= 4))
6084 pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
6085 else
6086 return FALSE; //Invalid argument
6087
6088 DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
6089
6090 return TRUE;
6091}
6092
6093/*
6094 ==========================================================================
6095 Description:
6096 Set WEP KEY1
6097 Return:
6098 TRUE if all parameters are OK, FALSE otherwise
6099 ==========================================================================
6100*/
6101INT Set_Key1_Proc(
6102 IN PRTMP_ADAPTER pAdapter,
6103 IN PUCHAR arg)
6104{
6105 int KeyLen;
6106 int i;
6107 UCHAR CipherAlg=CIPHER_WEP64;
6108
6109 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6110 return TRUE; // do nothing
6111
6112 KeyLen = strlen(arg);
6113
6114 switch (KeyLen)
6115 {
6116 case 5: //wep 40 Ascii type
6117 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6118 memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6119 CipherAlg = CIPHER_WEP64;
6120 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
6121 break;
6122 case 10: //wep 40 Hex type
6123 for(i=0; i < KeyLen; i++)
6124 {
6125 if( !isxdigit(*(arg+i)) )
6126 return FALSE; //Not Hex value;
6127 }
6128 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
6129 AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6130 CipherAlg = CIPHER_WEP64;
6131 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6132 break;
6133 case 13: //wep 104 Ascii type
6134 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6135 memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6136 CipherAlg = CIPHER_WEP128;
6137 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
6138 break;
6139 case 26: //wep 104 Hex type
6140 for(i=0; i < KeyLen; i++)
6141 {
6142 if( !isxdigit(*(arg+i)) )
6143 return FALSE; //Not Hex value;
6144 }
6145 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
6146 AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6147 CipherAlg = CIPHER_WEP128;
6148 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6149 break;
6150 default: //Invalid argument
6151 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
6152 return FALSE;
6153 }
6154
6155 pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
6156
6157 // Set keys (into ASIC)
6158 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6159 ; // not support
6160 else // Old WEP stuff
6161 {
6162 AsicAddSharedKeyEntry(pAdapter,
6163 0,
6164 0,
6165 pAdapter->SharedKey[BSS0][0].CipherAlg,
6166 pAdapter->SharedKey[BSS0][0].Key,
6167 NULL,
6168 NULL);
6169 }
6170
6171 return TRUE;
6172}
6173/*
6174 ==========================================================================
6175
6176 Description:
6177 Set WEP KEY2
6178 Return:
6179 TRUE if all parameters are OK, FALSE otherwise
6180 ==========================================================================
6181*/
6182INT Set_Key2_Proc(
6183 IN PRTMP_ADAPTER pAdapter,
6184 IN PUCHAR arg)
6185{
6186 int KeyLen;
6187 int i;
6188 UCHAR CipherAlg=CIPHER_WEP64;
6189
6190 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6191 return TRUE; // do nothing
6192
6193 KeyLen = strlen(arg);
6194
6195 switch (KeyLen)
6196 {
6197 case 5: //wep 40 Ascii type
6198 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6199 memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6200 CipherAlg = CIPHER_WEP64;
6201 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6202 break;
6203 case 10: //wep 40 Hex type
6204 for(i=0; i < KeyLen; i++)
6205 {
6206 if( !isxdigit(*(arg+i)) )
6207 return FALSE; //Not Hex value;
6208 }
6209 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6210 AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6211 CipherAlg = CIPHER_WEP64;
6212 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6213 break;
6214 case 13: //wep 104 Ascii type
6215 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6216 memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6217 CipherAlg = CIPHER_WEP128;
6218 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6219 break;
6220 case 26: //wep 104 Hex type
6221 for(i=0; i < KeyLen; i++)
6222 {
6223 if( !isxdigit(*(arg+i)) )
6224 return FALSE; //Not Hex value;
6225 }
6226 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6227 AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6228 CipherAlg = CIPHER_WEP128;
6229 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6230 break;
6231 default: //Invalid argument
6232 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
6233 return FALSE;
6234 }
6235 pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
6236
6237 // Set keys (into ASIC)
6238 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6239 ; // not support
6240 else // Old WEP stuff
6241 {
6242 AsicAddSharedKeyEntry(pAdapter,
6243 0,
6244 1,
6245 pAdapter->SharedKey[BSS0][1].CipherAlg,
6246 pAdapter->SharedKey[BSS0][1].Key,
6247 NULL,
6248 NULL);
6249 }
6250
6251 return TRUE;
6252}
6253/*
6254 ==========================================================================
6255 Description:
6256 Set WEP KEY3
6257 Return:
6258 TRUE if all parameters are OK, FALSE otherwise
6259 ==========================================================================
6260*/
6261INT Set_Key3_Proc(
6262 IN PRTMP_ADAPTER pAdapter,
6263 IN PUCHAR arg)
6264{
6265 int KeyLen;
6266 int i;
6267 UCHAR CipherAlg=CIPHER_WEP64;
6268
6269 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6270 return TRUE; // do nothing
6271
6272 KeyLen = strlen(arg);
6273
6274 switch (KeyLen)
6275 {
6276 case 5: //wep 40 Ascii type
6277 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6278 memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6279 CipherAlg = CIPHER_WEP64;
6280 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6281 break;
6282 case 10: //wep 40 Hex type
6283 for(i=0; i < KeyLen; i++)
6284 {
6285 if( !isxdigit(*(arg+i)) )
6286 return FALSE; //Not Hex value;
6287 }
6288 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6289 AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6290 CipherAlg = CIPHER_WEP64;
6291 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6292 break;
6293 case 13: //wep 104 Ascii type
6294 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6295 memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6296 CipherAlg = CIPHER_WEP128;
6297 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6298 break;
6299 case 26: //wep 104 Hex type
6300 for(i=0; i < KeyLen; i++)
6301 {
6302 if( !isxdigit(*(arg+i)) )
6303 return FALSE; //Not Hex value;
6304 }
6305 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6306 AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6307 CipherAlg = CIPHER_WEP128;
6308 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6309 break;
6310 default: //Invalid argument
6311 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
6312 return FALSE;
6313 }
6314 pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
6315
6316 // Set keys (into ASIC)
6317 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6318 ; // not support
6319 else // Old WEP stuff
6320 {
6321 AsicAddSharedKeyEntry(pAdapter,
6322 0,
6323 2,
6324 pAdapter->SharedKey[BSS0][2].CipherAlg,
6325 pAdapter->SharedKey[BSS0][2].Key,
6326 NULL,
6327 NULL);
6328 }
6329
6330 return TRUE;
6331}
6332/*
6333 ==========================================================================
6334 Description:
6335 Set WEP KEY4
6336 Return:
6337 TRUE if all parameters are OK, FALSE otherwise
6338 ==========================================================================
6339*/
6340INT Set_Key4_Proc(
6341 IN PRTMP_ADAPTER pAdapter,
6342 IN PUCHAR arg)
6343{
6344 int KeyLen;
6345 int i;
6346 UCHAR CipherAlg=CIPHER_WEP64;
6347
6348 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6349 return TRUE; // do nothing
6350
6351 KeyLen = strlen(arg);
6352
6353 switch (KeyLen)
6354 {
6355 case 5: //wep 40 Ascii type
6356 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6357 memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6358 CipherAlg = CIPHER_WEP64;
6359 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6360 break;
6361 case 10: //wep 40 Hex type
6362 for(i=0; i < KeyLen; i++)
6363 {
6364 if( !isxdigit(*(arg+i)) )
6365 return FALSE; //Not Hex value;
6366 }
6367 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6368 AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6369 CipherAlg = CIPHER_WEP64;
6370 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6371 break;
6372 case 13: //wep 104 Ascii type
6373 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6374 memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6375 CipherAlg = CIPHER_WEP128;
6376 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6377 break;
6378 case 26: //wep 104 Hex type
6379 for(i=0; i < KeyLen; i++)
6380 {
6381 if( !isxdigit(*(arg+i)) )
6382 return FALSE; //Not Hex value;
6383 }
6384 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6385 AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6386 CipherAlg = CIPHER_WEP128;
6387 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6388 break;
6389 default: //Invalid argument
6390 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
6391 return FALSE;
6392 }
6393 pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
6394
6395 // Set keys (into ASIC)
6396 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6397 ; // not support
6398 else // Old WEP stuff
6399 {
6400 AsicAddSharedKeyEntry(pAdapter,
6401 0,
6402 3,
6403 pAdapter->SharedKey[BSS0][3].CipherAlg,
6404 pAdapter->SharedKey[BSS0][3].Key,
6405 NULL,
6406 NULL);
6407 }
6408
6409 return TRUE;
6410}
6411
6412/*
6413 ==========================================================================
6414 Description:
6415 Set WPA PSK key
6416 Return:
6417 TRUE if all parameters are OK, FALSE otherwise
6418 ==========================================================================
6419*/
6420INT Set_WPAPSK_Proc(
6421 IN PRTMP_ADAPTER pAdapter,
6422 IN PUCHAR arg)
6423{
6424 UCHAR keyMaterial[40];
6425
6426 if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
6427 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
6428 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
6429 )
6430 return TRUE; // do nothing
6431
6432 DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
6433
6434 NdisZeroMemory(keyMaterial, 40);
6435
6436 if ((strlen(arg) < 8) || (strlen(arg) > 64))
6437 {
6438 DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
6439 return FALSE;
6440 }
6441
6442 if (strlen(arg) == 64)
6443 {
6444 AtoH(arg, keyMaterial, 32);
6445 NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6446
6447 }
6448 else
6449 {
6450 PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
6451 NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6452 }
6453
6454
6455
6456 if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
6457 pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
6458 {
6459 pAdapter->StaCfg.WpaState = SS_NOTUSE;
6460 }
6461 else
6462 {
6463 // Start STA supplicant state machine
6464 pAdapter->StaCfg.WpaState = SS_START;
6465 }
6466
6467 return TRUE;
6468}
6469
6470/*
6471 ==========================================================================
6472 Description:
6473 Set Power Saving mode
6474 Return:
6475 TRUE if all parameters are OK, FALSE otherwise
6476 ==========================================================================
6477*/
6478INT Set_PSMode_Proc(
6479 IN PRTMP_ADAPTER pAdapter,
6480 IN PUCHAR arg)
6481{
6482 if (pAdapter->StaCfg.BssType == BSS_INFRA)
6483 {
6484 if ((strcmp(arg, "Max_PSP") == 0) ||
6485 (strcmp(arg, "max_psp") == 0) ||
6486 (strcmp(arg, "MAX_PSP") == 0))
6487 {
6488 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6489 // to exclude certain situations.
6490 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6491 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
6492 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
6493 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6494 pAdapter->StaCfg.DefaultListenCount = 5;
6495
6496 }
6497 else if ((strcmp(arg, "Fast_PSP") == 0) ||
6498 (strcmp(arg, "fast_psp") == 0) ||
6499 (strcmp(arg, "FAST_PSP") == 0))
6500 {
6501 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6502 // to exclude certain situations.
6503 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6504 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6505 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
6506 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
6507 pAdapter->StaCfg.DefaultListenCount = 3;
6508 }
6509 else if ((strcmp(arg, "Legacy_PSP") == 0) ||
6510 (strcmp(arg, "legacy_psp") == 0) ||
6511 (strcmp(arg, "LEGACY_PSP") == 0))
6512 {
6513 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6514 // to exclude certain situations.
6515 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6516 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6517 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
6518 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
6519 pAdapter->StaCfg.DefaultListenCount = 3;
6520 }
6521 else
6522 {
6523 //Default Ndis802_11PowerModeCAM
6524 // clear PSM bit immediately
6525 MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
6526 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6527 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6528 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
6529 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
6530 }
6531
6532 DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
6533 }
6534 else
6535 return FALSE;
6536
6537
6538 return TRUE;
6539}
6540
6541#ifdef WPA_SUPPLICANT_SUPPORT
6542/*
6543 ==========================================================================
6544 Description:
6545 Set WpaSupport flag.
6546 Value:
6547 0: Driver ignore wpa_supplicant.
6548 1: wpa_supplicant initiates scanning and AP selection.
6549 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
6550 Return:
6551 TRUE if all parameters are OK, FALSE otherwise
6552 ==========================================================================
6553*/
6554INT Set_Wpa_Support(
6555 IN PRTMP_ADAPTER pAd,
6556 IN PUCHAR arg)
6557{
6558
6559 if ( simple_strtol(arg, 0, 10) == 0)
6560 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6561 else if ( simple_strtol(arg, 0, 10) == 1)
6562 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
6563 else if ( simple_strtol(arg, 0, 10) == 2)
6564 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
6565 else
6566 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6567
6568 DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
6569
6570 return TRUE;
6571}
6572#endif // WPA_SUPPLICANT_SUPPORT //
6573
6574#ifdef DBG
6575/*
6576 ==========================================================================
6577 Description:
6578 Read / Write MAC
6579 Arguments:
6580 pAdapter Pointer to our adapter
6581 wrq Pointer to the ioctl argument
6582
6583 Return Value:
6584 None
6585
6586 Note:
6587 Usage:
6588 1.) iwpriv ra0 mac 0 ==> read MAC where Addr=0x0
6589 2.) iwpriv ra0 mac 0=12 ==> write MAC where Addr=0x0, value=12
6590 ==========================================================================
6591*/
6592VOID RTMPIoctlMAC(
6593 IN PRTMP_ADAPTER pAdapter,
6594 IN struct iwreq *wrq)
6595{
6596 CHAR *this_char;
6597 CHAR *value;
6598 INT j = 0, k = 0;
6599 CHAR msg[1024];
6600 CHAR arg[255];
6601 ULONG macAddr = 0;
6602 UCHAR temp[16], temp2[16];
6603 UINT32 macValue = 0;
6604 INT Status;
6605
6606
6607 memset(msg, 0x00, 1024);
6608 if (wrq->u.data.length > 1) //No parameters.
6609 {
6610 Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6611 sprintf(msg, "\n");
6612
6613 //Parsing Read or Write
6614 this_char = arg;
6615 if (!*this_char)
6616 goto next;
6617
6618 if ((value = rtstrchr(this_char, '=')) != NULL)
6619 *value++ = 0;
6620
6621 if (!value || !*value)
6622 { //Read
6623 // Sanity check
6624 if(strlen(this_char) > 4)
6625 goto next;
6626
6627 j = strlen(this_char);
6628 while(j-- > 0)
6629 {
6630 if(this_char[j] > 'f' || this_char[j] < '0')
6631 return;
6632 }
6633
6634 // Mac Addr
6635 k = j = strlen(this_char);
6636 while(j-- > 0)
6637 {
6638 this_char[4-k+j] = this_char[j];
6639 }
6640
6641 while(k < 4)
6642 this_char[3-k++]='0';
6643 this_char[4]='\0';
6644
6645 if(strlen(this_char) == 4)
6646 {
6647 AtoH(this_char, temp, 2);
6648 macAddr = *temp*256 + temp[1];
6649 if (macAddr < 0xFFFF)
6650 {
6651 RTMP_IO_READ32(pAdapter, macAddr, &macValue);
6652 DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
6653 sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr , macValue);
6654 }
6655 else
6656 {//Invalid parametes, so default printk all bbp
6657 goto next;
6658 }
6659 }
6660 }
6661 else
6662 { //Write
6663 memcpy(&temp2, value, strlen(value));
6664 temp2[strlen(value)] = '\0';
6665
6666 // Sanity check
6667 if((strlen(this_char) > 4) || strlen(temp2) > 8)
6668 goto next;
6669
6670 j = strlen(this_char);
6671 while(j-- > 0)
6672 {
6673 if(this_char[j] > 'f' || this_char[j] < '0')
6674 return;
6675 }
6676
6677 j = strlen(temp2);
6678 while(j-- > 0)
6679 {
6680 if(temp2[j] > 'f' || temp2[j] < '0')
6681 return;
6682 }
6683
6684 //MAC Addr
6685 k = j = strlen(this_char);
6686 while(j-- > 0)
6687 {
6688 this_char[4-k+j] = this_char[j];
6689 }
6690
6691 while(k < 4)
6692 this_char[3-k++]='0';
6693 this_char[4]='\0';
6694
6695 //MAC value
6696 k = j = strlen(temp2);
6697 while(j-- > 0)
6698 {
6699 temp2[8-k+j] = temp2[j];
6700 }
6701
6702 while(k < 8)
6703 temp2[7-k++]='0';
6704 temp2[8]='\0';
6705
6706 {
6707 AtoH(this_char, temp, 2);
6708 macAddr = *temp*256 + temp[1];
6709
6710 AtoH(temp2, temp, 4);
6711 macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
6712
6713 // debug mode
6714 if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
6715 {
6716 // 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
6717 if (macValue & 0x000000ff)
6718 {
6719 pAdapter->BbpTuning.bEnable = TRUE;
6720 DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
6721 }
6722 else
6723 {
6724 UCHAR R66;
6725 pAdapter->BbpTuning.bEnable = FALSE;
6726 R66 = 0x26 + GET_LNA_GAIN(pAdapter);
6727#ifdef RALINK_ATE
6728 if (ATE_ON(pAdapter))
6729 {
6730 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6731 }
6732 else
6733#endif // RALINK_ATE //
6734 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6735 DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
6736 }
6737 return;
6738 }
6739
6740 DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
6741
6742 RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
6743 sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr, macValue);
6744 }
6745 }
6746 }
6747next:
6748 if(strlen(msg) == 1)
6749 sprintf(msg+strlen(msg), "===>Error command format!");
6750
6751 // Copy the information into the user buffer
6752 wrq->u.data.length = strlen(msg);
6753 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6754
6755 DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
6756}
6757
6758/*
6759 ==========================================================================
6760 Description:
6761 Read / Write E2PROM
6762 Arguments:
6763 pAdapter Pointer to our adapter
6764 wrq Pointer to the ioctl argument
6765
6766 Return Value:
6767 None
6768
6769 Note:
6770 Usage:
6771 1.) iwpriv ra0 e2p 0 ==> read E2PROM where Addr=0x0
6772 2.) iwpriv ra0 e2p 0=1234 ==> write E2PROM where Addr=0x0, value=1234
6773 ==========================================================================
6774*/
6775VOID RTMPIoctlE2PROM(
6776 IN PRTMP_ADAPTER pAdapter,
6777 IN struct iwreq *wrq)
6778{
6779 CHAR *this_char;
6780 CHAR *value;
6781 INT j = 0, k = 0;
6782 CHAR msg[1024];
6783 CHAR arg[255];
6784 USHORT eepAddr = 0;
6785 UCHAR temp[16], temp2[16];
6786 USHORT eepValue;
6787 int Status;
6788
6789
6790 memset(msg, 0x00, 1024);
6791 if (wrq->u.data.length > 1) //No parameters.
6792 {
6793 Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6794 sprintf(msg, "\n");
6795
6796 //Parsing Read or Write
6797 this_char = arg;
6798
6799
6800 if (!*this_char)
6801 goto next;
6802
6803 if ((value = rtstrchr(this_char, '=')) != NULL)
6804 *value++ = 0;
6805
6806 if (!value || !*value)
6807 { //Read
6808
6809 // Sanity check
6810 if(strlen(this_char) > 4)
6811 goto next;
6812
6813 j = strlen(this_char);
6814 while(j-- > 0)
6815 {
6816 if(this_char[j] > 'f' || this_char[j] < '0')
6817 return;
6818 }
6819
6820 // E2PROM addr
6821 k = j = strlen(this_char);
6822 while(j-- > 0)
6823 {
6824 this_char[4-k+j] = this_char[j];
6825 }
6826
6827 while(k < 4)
6828 this_char[3-k++]='0';
6829 this_char[4]='\0';
6830
6831 if(strlen(this_char) == 4)
6832 {
6833 AtoH(this_char, temp, 2);
6834 eepAddr = *temp*256 + temp[1];
6835 if (eepAddr < 0xFFFF)
6836 {
6837 RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
6838 sprintf(msg+strlen(msg), "[0x%04X]:0x%04X ", eepAddr , eepValue);
6839 }
6840 else
6841 {//Invalid parametes, so default printk all bbp
6842 goto next;
6843 }
6844 }
6845 }
6846 else
6847 { //Write
6848 memcpy(&temp2, value, strlen(value));
6849 temp2[strlen(value)] = '\0';
6850
6851 // Sanity check
6852 if((strlen(this_char) > 4) || strlen(temp2) > 8)
6853 goto next;
6854
6855 j = strlen(this_char);
6856 while(j-- > 0)
6857 {
6858 if(this_char[j] > 'f' || this_char[j] < '0')
6859 return;
6860 }
6861 j = strlen(temp2);
6862 while(j-- > 0)
6863 {
6864 if(temp2[j] > 'f' || temp2[j] < '0')
6865 return;
6866 }
6867
6868 //MAC Addr
6869 k = j = strlen(this_char);
6870 while(j-- > 0)
6871 {
6872 this_char[4-k+j] = this_char[j];
6873 }
6874
6875 while(k < 4)
6876 this_char[3-k++]='0';
6877 this_char[4]='\0';
6878
6879 //MAC value
6880 k = j = strlen(temp2);
6881 while(j-- > 0)
6882 {
6883 temp2[4-k+j] = temp2[j];
6884 }
6885
6886 while(k < 4)
6887 temp2[3-k++]='0';
6888 temp2[4]='\0';
6889
6890 AtoH(this_char, temp, 2);
6891 eepAddr = *temp*256 + temp[1];
6892
6893 AtoH(temp2, temp, 2);
6894 eepValue = *temp*256 + temp[1];
6895
6896 RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
6897 sprintf(msg+strlen(msg), "[0x%02X]:%02X ", eepAddr, eepValue);
6898 }
6899 }
6900next:
6901 if(strlen(msg) == 1)
6902 sprintf(msg+strlen(msg), "===>Error command format!");
6903
6904
6905 // Copy the information into the user buffer
6906 wrq->u.data.length = strlen(msg);
6907 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6908
6909 DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
6910}
6911#endif // DBG //
6912
6913
6914
6915
6916INT Set_TGnWifiTest_Proc(
6917 IN PRTMP_ADAPTER pAd,
6918 IN PUCHAR arg)
6919{
6920 if (simple_strtol(arg, 0, 10) == 0)
6921 pAd->StaCfg.bTGnWifiTest = FALSE;
6922 else
6923 pAd->StaCfg.bTGnWifiTest = TRUE;
6924
6925 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
6926 return TRUE;
6927}
6928
6929INT Set_LongRetryLimit_Proc(
6930 IN PRTMP_ADAPTER pAdapter,
6931 IN PUCHAR arg)
6932{
6933 TX_RTY_CFG_STRUC tx_rty_cfg;
6934 UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6935
6936 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6937 tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
6938 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6939 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6940 return TRUE;
6941}
6942
6943INT Set_ShortRetryLimit_Proc(
6944 IN PRTMP_ADAPTER pAdapter,
6945 IN PUCHAR arg)
6946{
6947 TX_RTY_CFG_STRUC tx_rty_cfg;
6948 UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6949
6950 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6951 tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
6952 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6953 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6954 return TRUE;
6955}
6956
6957#ifdef EXT_BUILD_CHANNEL_LIST
6958INT Set_Ieee80211dClientMode_Proc(
6959 IN PRTMP_ADAPTER pAdapter,
6960 IN PUCHAR arg)
6961{
6962 if (simple_strtol(arg, 0, 10) == 0)
6963 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
6964 else if (simple_strtol(arg, 0, 10) == 1)
6965 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible;
6966 else if (simple_strtol(arg, 0, 10) == 2)
6967 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict;
6968 else
6969 return FALSE;
6970
6971 DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode));
6972 return TRUE;
6973}
6974#endif // EXT_BUILD_CHANNEL_LIST //
6975
6976#ifdef CARRIER_DETECTION_SUPPORT
6977INT Set_CarrierDetect_Proc(
6978 IN PRTMP_ADAPTER pAd,
6979 IN PUCHAR arg)
6980{
6981 if (simple_strtol(arg, 0, 10) == 0)
6982 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
6983 else
6984 pAd->CommonCfg.CarrierDetect.Enable = TRUE;
6985
6986 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable));
6987 return TRUE;
6988}
6989#endif // CARRIER_DETECTION_SUPPORT //
6990
6991
6992INT Show_Adhoc_MacTable_Proc(
6993 IN PRTMP_ADAPTER pAd,
6994 IN PCHAR extra)
6995{
6996 INT i;
6997
6998 sprintf(extra, "\n");
6999
7000#ifdef DOT11_N_SUPPORT
7001 sprintf(extra, "%sHT Operating Mode : %d\n", extra, pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode);
7002#endif // DOT11_N_SUPPORT //
7003
7004 sprintf(extra, "%s\n%-19s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n", extra,
7005 "MAC", "AID", "BSS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
7006
7007 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
7008 {
7009 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
7010
7011 if (strlen(extra) > (IW_PRIV_SIZE_MASK - 30))
7012 break;
7013 if ((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
7014 {
7015 sprintf(extra, "%s%02X:%02X:%02X:%02X:%02X:%02X ", extra,
7016 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
7017 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
7018 sprintf(extra, "%s%-4d", extra, (int)pEntry->Aid);
7019 sprintf(extra, "%s%-4d", extra, (int)pEntry->apidx);
7020 sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi0);
7021 sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi1);
7022 sprintf(extra, "%s%-7d", extra, pEntry->RssiSample.AvgRssi2);
7023 sprintf(extra, "%s%-10s", extra, GetPhyMode(pEntry->HTPhyMode.field.MODE));
7024 sprintf(extra, "%s%-6s", extra, GetBW(pEntry->HTPhyMode.field.BW));
7025 sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.MCS);
7026 sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.ShortGI);
7027 sprintf(extra, "%s%-6d", extra, pEntry->HTPhyMode.field.STBC);
7028 sprintf(extra, "%s%-10d, %d, %d%%\n", extra, pEntry->DebugFIFOCount, pEntry->DebugTxCount,
7029 (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
7030 sprintf(extra, "%s\n", extra);
7031 }
7032 }
7033
7034 return TRUE;
7035}
7036
7037
diff --git a/drivers/staging/rt2870/wpa.h b/drivers/staging/rt2870/wpa.h
new file mode 100644
index 00000000000..0134ae6097c
--- /dev/null
+++ b/drivers/staging/rt2870/wpa.h
@@ -0,0 +1,357 @@
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#define MIN_LEN_OF_GTK 5
94
95// RSN IE Length definition
96#define MAX_LEN_OF_RSNIE 90
97#define MIN_LEN_OF_RSNIE 8
98
99//EAP Packet Type
100#define EAPPacket 0
101#define EAPOLStart 1
102#define EAPOLLogoff 2
103#define EAPOLKey 3
104#define EAPOLASFAlert 4
105#define EAPTtypeMax 5
106
107#define EAPOL_MSG_INVALID 0
108#define EAPOL_PAIR_MSG_1 1
109#define EAPOL_PAIR_MSG_2 2
110#define EAPOL_PAIR_MSG_3 3
111#define EAPOL_PAIR_MSG_4 4
112#define EAPOL_GROUP_MSG_1 5
113#define EAPOL_GROUP_MSG_2 6
114
115#define PAIRWISEKEY 1
116#define GROUPKEY 0
117
118// Retry timer counter initial value
119#define PEER_MSG1_RETRY_TIMER_CTR 0
120#define PEER_MSG3_RETRY_TIMER_CTR 10
121#define GROUP_MSG1_RETRY_TIMER_CTR 20
122
123
124#define EAPOL_START_DISABLE 0
125#define EAPOL_START_PSK 1
126#define EAPOL_START_1X 2
127
128#define MIX_CIPHER_WPA_TKIP_ON(x) (((x) & 0x08) != 0)
129#define MIX_CIPHER_WPA_AES_ON(x) (((x) & 0x04) != 0)
130#define MIX_CIPHER_WPA2_TKIP_ON(x) (((x) & 0x02) != 0)
131#define MIX_CIPHER_WPA2_AES_ON(x) (((x) & 0x01) != 0)
132
133#define ROUND_UP(__x, __y) \
134 (((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1)))
135
136#define ADD_ONE_To_64BIT_VAR(_V) \
137{ \
138 UCHAR cnt = LEN_KEY_DESC_REPLAY; \
139 do \
140 { \
141 cnt--; \
142 _V[cnt]++; \
143 if (cnt == 0) \
144 break; \
145 }while (_V[cnt] == 0); \
146}
147
148#define IS_WPA_CAPABILITY(a) (((a) >= Ndis802_11AuthModeWPA) && ((a) <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
149
150// EAPOL Key Information definition within Key descriptor format
151typedef struct PACKED _KEY_INFO
152{
153#ifdef RT_BIG_ENDIAN
154 UCHAR KeyAck:1;
155 UCHAR Install:1;
156 UCHAR KeyIndex:2;
157 UCHAR KeyType:1;
158 UCHAR KeyDescVer:3;
159 UCHAR Rsvd:3;
160 UCHAR EKD_DL:1; // EKD for AP; DL for STA
161 UCHAR Request:1;
162 UCHAR Error:1;
163 UCHAR Secure:1;
164 UCHAR KeyMic:1;
165#else
166 UCHAR KeyMic:1;
167 UCHAR Secure:1;
168 UCHAR Error:1;
169 UCHAR Request:1;
170 UCHAR EKD_DL:1; // EKD for AP; DL for STA
171 UCHAR Rsvd:3;
172 UCHAR KeyDescVer:3;
173 UCHAR KeyType:1;
174 UCHAR KeyIndex:2;
175 UCHAR Install:1;
176 UCHAR KeyAck:1;
177#endif
178} KEY_INFO, *PKEY_INFO;
179
180// EAPOL Key descriptor format
181typedef struct PACKED _KEY_DESCRIPTER
182{
183 UCHAR Type;
184 KEY_INFO KeyInfo;
185 UCHAR KeyLength[2];
186 UCHAR ReplayCounter[LEN_KEY_DESC_REPLAY];
187 UCHAR KeyNonce[LEN_KEY_DESC_NONCE];
188 UCHAR KeyIv[LEN_KEY_DESC_IV];
189 UCHAR KeyRsc[LEN_KEY_DESC_RSC];
190 UCHAR KeyId[LEN_KEY_DESC_ID];
191 UCHAR KeyMic[LEN_KEY_DESC_MIC];
192 UCHAR KeyDataLen[2];
193 UCHAR KeyData[MAX_LEN_OF_RSNIE];
194} KEY_DESCRIPTER, *PKEY_DESCRIPTER;
195
196typedef struct PACKED _EAPOL_PACKET
197{
198 UCHAR ProVer;
199 UCHAR ProType;
200 UCHAR Body_Len[2];
201 KEY_DESCRIPTER KeyDesc;
202} EAPOL_PACKET, *PEAPOL_PACKET;
203
204//802.11i D10 page 83
205typedef struct PACKED _GTK_ENCAP
206{
207#ifndef RT_BIG_ENDIAN
208 UCHAR Kid:2;
209 UCHAR tx:1;
210 UCHAR rsv:5;
211 UCHAR rsv1;
212#else
213 UCHAR rsv:5;
214 UCHAR tx:1;
215 UCHAR Kid:2;
216 UCHAR rsv1;
217#endif
218 UCHAR GTK[TKIP_GTK_LENGTH];
219} GTK_ENCAP, *PGTK_ENCAP;
220
221typedef struct PACKED _KDE_ENCAP
222{
223 UCHAR Type;
224 UCHAR Len;
225 UCHAR OUI[3];
226 UCHAR DataType;
227 GTK_ENCAP GTKEncap;
228} KDE_ENCAP, *PKDE_ENCAP;
229
230// For WPA1
231typedef struct PACKED _RSNIE {
232 UCHAR oui[4];
233 USHORT version;
234 UCHAR mcast[4];
235 USHORT ucount;
236 struct PACKED {
237 UCHAR oui[4];
238 }ucast[1];
239} RSNIE, *PRSNIE;
240
241// For WPA2
242typedef struct PACKED _RSNIE2 {
243 USHORT version;
244 UCHAR mcast[4];
245 USHORT ucount;
246 struct PACKED {
247 UCHAR oui[4];
248 }ucast[1];
249} RSNIE2, *PRSNIE2;
250
251// AKM Suite
252typedef struct PACKED _RSNIE_AUTH {
253 USHORT acount;
254 struct PACKED {
255 UCHAR oui[4];
256 }auth[1];
257} RSNIE_AUTH,*PRSNIE_AUTH;
258
259typedef union PACKED _RSN_CAPABILITIES {
260 struct PACKED {
261#ifdef RT_BIG_ENDIAN
262 USHORT Rsvd:10;
263 USHORT GTKSA_R_Counter:2;
264 USHORT PTKSA_R_Counter:2;
265 USHORT No_Pairwise:1;
266 USHORT PreAuth:1;
267#else
268 USHORT PreAuth:1;
269 USHORT No_Pairwise:1;
270 USHORT PTKSA_R_Counter:2;
271 USHORT GTKSA_R_Counter:2;
272 USHORT Rsvd:10;
273#endif
274 } field;
275 USHORT word;
276} RSN_CAPABILITIES, *PRSN_CAPABILITIES;
277
278typedef struct PACKED _EAP_HDR {
279 UCHAR ProVer;
280 UCHAR ProType;
281 UCHAR Body_Len[2];
282 UCHAR code;
283 UCHAR identifier;
284 UCHAR length[2]; // including code and identifier, followed by length-2 octets of data
285} EAP_HDR, *PEAP_HDR;
286
287// For supplicant state machine states. 802.11i Draft 4.1, p. 97
288// We simplified it
289typedef enum _WpaState
290{
291 SS_NOTUSE, // 0
292 SS_START, // 1
293 SS_WAIT_MSG_3, // 2
294 SS_WAIT_GROUP, // 3
295 SS_FINISH, // 4
296 SS_KEYUPDATE, // 5
297} WPA_STATE;
298
299//
300// The definition of the cipher combination
301//
302// bit3 bit2 bit1 bit0
303// +------------+------------+
304// | WPA | WPA2 |
305// +------+-----+------+-----+
306// | TKIP | AES | TKIP | AES |
307// | 0 | 1 | 1 | 0 | -> 0x06
308// | 0 | 1 | 1 | 1 | -> 0x07
309// | 1 | 0 | 0 | 1 | -> 0x09
310// | 1 | 0 | 1 | 1 | -> 0x0B
311// | 1 | 1 | 0 | 1 | -> 0x0D
312// | 1 | 1 | 1 | 0 | -> 0x0E
313// | 1 | 1 | 1 | 1 | -> 0x0F
314// +------+-----+------+-----+
315//
316typedef enum _WpaMixPairCipher
317{
318 MIX_CIPHER_NOTUSE = 0x00,
319 WPA_NONE_WPA2_TKIPAES = 0x03, // WPA2-TKIPAES
320 WPA_AES_WPA2_TKIP = 0x06,
321 WPA_AES_WPA2_TKIPAES = 0x07,
322 WPA_TKIP_WPA2_AES = 0x09,
323 WPA_TKIP_WPA2_TKIPAES = 0x0B,
324 WPA_TKIPAES_WPA2_NONE = 0x0C, // WPA-TKIPAES
325 WPA_TKIPAES_WPA2_AES = 0x0D,
326 WPA_TKIPAES_WPA2_TKIP = 0x0E,
327 WPA_TKIPAES_WPA2_TKIPAES = 0x0F,
328} WPA_MIX_PAIR_CIPHER;
329
330typedef struct PACKED _RSN_IE_HEADER_STRUCT {
331 UCHAR Eid;
332 UCHAR Length;
333 USHORT Version; // Little endian format
334} RSN_IE_HEADER_STRUCT, *PRSN_IE_HEADER_STRUCT;
335
336// Cipher suite selector types
337typedef struct PACKED _CIPHER_SUITE_STRUCT {
338 UCHAR Oui[3];
339 UCHAR Type;
340} CIPHER_SUITE_STRUCT, *PCIPHER_SUITE_STRUCT;
341
342// Authentication and Key Management suite selector
343typedef struct PACKED _AKM_SUITE_STRUCT {
344 UCHAR Oui[3];
345 UCHAR Type;
346} AKM_SUITE_STRUCT, *PAKM_SUITE_STRUCT;
347
348// RSN capability
349typedef struct PACKED _RSN_CAPABILITY {
350 USHORT Rsv:10;
351 USHORT GTKSAReplayCnt:2;
352 USHORT PTKSAReplayCnt:2;
353 USHORT NoPairwise:1;
354 USHORT PreAuth:1;
355} RSN_CAPABILITY, *PRSN_CAPABILITY;
356
357#endif