aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2008-10-28 17:48:09 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-01-06 16:52:11 -0500
commit91980990527258a075361490cecadbb7356fc0d2 (patch)
treea50d4f8765c85210062cbfe011b4367f87f81ec0
parentf4f85ff7255836122fc03f69957cdb02e2530faa (diff)
Staging: add rt2860 wireless driver
This is the Ralink RT2860 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>
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/rt2860/2860_main_dev.c1377
-rw-r--r--drivers/staging/rt2860/Kconfig5
-rw-r--r--drivers/staging/rt2860/Makefile41
-rw-r--r--drivers/staging/rt2860/TODO17
-rw-r--r--drivers/staging/rt2860/aironet.h210
-rw-r--r--drivers/staging/rt2860/ap.h557
-rw-r--r--drivers/staging/rt2860/chlist.h1296
-rw-r--r--drivers/staging/rt2860/common/2860_rtmp_init.c922
-rw-r--r--drivers/staging/rt2860/common/action.c1031
-rw-r--r--drivers/staging/rt2860/common/action.h68
-rw-r--r--drivers/staging/rt2860/common/ba_action.c1802
-rw-r--r--drivers/staging/rt2860/common/cmm_data.c3469
-rw-r--r--drivers/staging/rt2860/common/cmm_data_2860.c1240
-rw-r--r--drivers/staging/rt2860/common/cmm_info.c3417
-rw-r--r--drivers/staging/rt2860/common/cmm_sanity.c1633
-rw-r--r--drivers/staging/rt2860/common/cmm_sync.c702
-rw-r--r--drivers/staging/rt2860/common/cmm_wpa.c1606
-rw-r--r--drivers/staging/rt2860/common/dfs.c453
-rw-r--r--drivers/staging/rt2860/common/eeprom.c244
-rw-r--r--drivers/staging/rt2860/common/firmware.h558
-rw-r--r--drivers/staging/rt2860/common/md5.c1427
-rw-r--r--drivers/staging/rt2860/common/mlme.c8667
-rw-r--r--drivers/staging/rt2860/common/netif_block.c144
-rw-r--r--drivers/staging/rt2860/common/netif_block.h58
-rw-r--r--drivers/staging/rt2860/common/rtmp_init.c3757
-rw-r--r--drivers/staging/rt2860/common/rtmp_tkip.c1607
-rw-r--r--drivers/staging/rt2860/common/rtmp_wep.c499
-rw-r--r--drivers/staging/rt2860/common/spectrum.c1877
-rw-r--r--drivers/staging/rt2860/config.mk245
-rw-r--r--drivers/staging/rt2860/dfs.h100
-rw-r--r--drivers/staging/rt2860/leap.h215
-rw-r--r--drivers/staging/rt2860/link_list.h134
-rw-r--r--drivers/staging/rt2860/md4.h42
-rw-r--r--drivers/staging/rt2860/md5.h107
-rw-r--r--drivers/staging/rt2860/mlme.h1447
-rw-r--r--drivers/staging/rt2860/oid.h995
-rw-r--r--drivers/staging/rt2860/rt2860.h349
-rw-r--r--drivers/staging/rt2860/rt28xx.h2714
-rw-r--r--drivers/staging/rt2860/rt_ate.c6025
-rw-r--r--drivers/staging/rt2860/rt_ate.h353
-rw-r--r--drivers/staging/rt2860/rt_config.h101
-rw-r--r--drivers/staging/rt2860/rt_linux.c1054
-rw-r--r--drivers/staging/rt2860/rt_linux.h926
-rw-r--r--drivers/staging/rt2860/rt_main_dev.c1686
-rw-r--r--drivers/staging/rt2860/rt_profile.c1976
-rw-r--r--drivers/staging/rt2860/rtmp.h7177
-rw-r--r--drivers/staging/rt2860/rtmp_ckipmic.h113
-rw-r--r--drivers/staging/rt2860/rtmp_def.h1588
-rw-r--r--drivers/staging/rt2860/rtmp_type.h94
-rw-r--r--drivers/staging/rt2860/spectrum.h322
-rw-r--r--drivers/staging/rt2860/spectrum_def.h95
-rw-r--r--drivers/staging/rt2860/sta/aironet.c1312
-rw-r--r--drivers/staging/rt2860/sta/assoc.c1826
-rw-r--r--drivers/staging/rt2860/sta/auth.c474
-rw-r--r--drivers/staging/rt2860/sta/auth_rsp.c167
-rw-r--r--drivers/staging/rt2860/sta/connect.c2751
-rw-r--r--drivers/staging/rt2860/sta/dls.c2201
-rw-r--r--drivers/staging/rt2860/sta/rtmp_data.c2614
-rw-r--r--drivers/staging/rt2860/sta/sanity.c420
-rw-r--r--drivers/staging/rt2860/sta/sync.c1961
-rw-r--r--drivers/staging/rt2860/sta/wpa.c2086
-rw-r--r--drivers/staging/rt2860/sta_ioctl.c6944
-rw-r--r--drivers/staging/rt2860/wpa.h356
65 files changed, 89657 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index dea55e178c3..f9b785a0390 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -67,5 +67,7 @@ source "drivers/staging/agnx/Kconfig"
67 67
68source "drivers/staging/otus/Kconfig" 68source "drivers/staging/otus/Kconfig"
69 69
70source "drivers/staging/rt2860/Kconfig"
71
70endif # !STAGING_EXCLUDE_BUILD 72endif # !STAGING_EXCLUDE_BUILD
71endif # STAGING 73endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 43f6385592f..147a467358a 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_USB_ATMEL) += at76_usb/
16obj-$(CONFIG_POCH) += poch/ 16obj-$(CONFIG_POCH) += poch/
17obj-$(CONFIG_AGNX) += agnx/ 17obj-$(CONFIG_AGNX) += agnx/
18obj-$(CONFIG_OTUS) += otus/ 18obj-$(CONFIG_OTUS) += otus/
19obj-$(CONFIG_RT2860) += rt2860/
diff --git a/drivers/staging/rt2860/2860_main_dev.c b/drivers/staging/rt2860/2860_main_dev.c
new file mode 100644
index 00000000000..c2945364185
--- /dev/null
+++ b/drivers/staging/rt2860/2860_main_dev.c
@@ -0,0 +1,1377 @@
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_main_dev.c
29
30 Abstract:
31 Create and register network interface.
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36*/
37
38#include "rt_config.h"
39
40
41#ifdef MULTIPLE_CARD_SUPPORT
42// record whether the card in the card list is used in the card file
43extern UINT8 MC_CardUsed[];
44#endif // MULTIPLE_CARD_SUPPORT //
45
46
47extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
48 IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
49
50static void rx_done_tasklet(unsigned long data);
51static void mgmt_dma_done_tasklet(unsigned long data);
52static void ac0_dma_done_tasklet(unsigned long data);
53static void ac1_dma_done_tasklet(unsigned long data);
54static void ac2_dma_done_tasklet(unsigned long data);
55static void ac3_dma_done_tasklet(unsigned long data);
56static void hcca_dma_done_tasklet(unsigned long data);
57static void fifo_statistic_full_tasklet(unsigned long data);
58
59
60/*---------------------------------------------------------------------*/
61/* Symbol & Macro Definitions */
62/*---------------------------------------------------------------------*/
63#define RT2860_INT_RX_DLY (1<<0) // bit 0
64#define RT2860_INT_TX_DLY (1<<1) // bit 1
65#define RT2860_INT_RX_DONE (1<<2) // bit 2
66#define RT2860_INT_AC0_DMA_DONE (1<<3) // bit 3
67#define RT2860_INT_AC1_DMA_DONE (1<<4) // bit 4
68#define RT2860_INT_AC2_DMA_DONE (1<<5) // bit 5
69#define RT2860_INT_AC3_DMA_DONE (1<<6) // bit 6
70#define RT2860_INT_HCCA_DMA_DONE (1<<7) // bit 7
71#define RT2860_INT_MGMT_DONE (1<<8) // bit 8
72
73#define INT_RX RT2860_INT_RX_DONE
74
75#define INT_AC0_DLY (RT2860_INT_AC0_DMA_DONE) //| RT2860_INT_TX_DLY)
76#define INT_AC1_DLY (RT2860_INT_AC1_DMA_DONE) //| RT2860_INT_TX_DLY)
77#define INT_AC2_DLY (RT2860_INT_AC2_DMA_DONE) //| RT2860_INT_TX_DLY)
78#define INT_AC3_DLY (RT2860_INT_AC3_DMA_DONE) //| RT2860_INT_TX_DLY)
79#define INT_HCCA_DLY (RT2860_INT_HCCA_DMA_DONE) //| RT2860_INT_TX_DLY)
80#define INT_MGMT_DLY RT2860_INT_MGMT_DONE
81
82/*---------------------------------------------------------------------*/
83/* Prototypes of Functions Used */
84/*---------------------------------------------------------------------*/
85/* function declarations */
86static INT __devinit rt2860_init_one (struct pci_dev *pci_dev, const struct pci_device_id *ent);
87static VOID __devexit rt2860_remove_one(struct pci_dev *pci_dev);
88static INT __devinit rt2860_probe(struct pci_dev *pci_dev, const struct pci_device_id *ent);
89void init_thread_task(PRTMP_ADAPTER pAd);
90static void __exit rt2860_cleanup_module(void);
91static int __init rt2860_init_module(void);
92
93#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
94#ifdef CONFIG_PM
95static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
96static int rt2860_resume(struct pci_dev *pci_dev);
97#endif // CONFIG_PM //
98#endif
99
100
101//
102// Ralink PCI device table, include all supported chipsets
103//
104static struct pci_device_id rt2860_pci_tbl[] __devinitdata =
105{
106 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCI_DEVICE_ID)}, //RT28602.4G
107 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCIe_DEVICE_ID)},
108 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2760_PCI_DEVICE_ID)},
109 {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2790_PCIe_DEVICE_ID)},
110 {PCI_DEVICE(VEN_AWT_PCI_VENDOR_ID, VEN_AWT_PCIe_DEVICE_ID)},
111 {0,} // terminate list
112};
113
114MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl);
115#ifdef CONFIG_STA_SUPPORT
116MODULE_LICENSE("GPL");
117#ifdef MODULE_VERSION
118MODULE_VERSION(STA_DRIVER_VERSION);
119#endif
120#endif // CONFIG_STA_SUPPORT //
121
122
123//
124// Our PCI driver structure
125//
126static struct pci_driver rt2860_driver =
127{
128 name: "rt2860",
129 id_table: rt2860_pci_tbl,
130 probe: rt2860_init_one,
131#if LINUX_VERSION_CODE >= 0x20412
132 remove: __devexit_p(rt2860_remove_one),
133#else
134 remove: __devexit(rt2860_remove_one),
135#endif
136
137#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
138#ifdef CONFIG_PM
139 suspend: rt2860_suspend,
140 resume: rt2860_resume,
141#endif
142#endif
143};
144
145
146#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
147#ifdef CONFIG_PM
148
149VOID RT2860RejectPendingPackets(
150 IN PRTMP_ADAPTER pAd)
151{
152 // clear PS packets
153 // clear TxSw packets
154}
155
156static int rt2860_suspend(
157 struct pci_dev *pci_dev,
158 pm_message_t state)
159{
160 struct net_device *net_dev = pci_get_drvdata(pci_dev);
161 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
162 INT32 retval;
163
164
165 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n"));
166
167 if (net_dev == NULL)
168 {
169 DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
170 }
171 else
172 {
173 pAd = (PRTMP_ADAPTER)net_dev->priv;
174
175 /* we can not use IFF_UP because ra0 down but ra1 up */
176 /* and 1 suspend/resume function for 1 module, not for each interface */
177 /* so Linux will call suspend/resume function once */
178 if (VIRTUAL_IF_NUM(pAd) > 0)
179 {
180 // avoid users do suspend after interface is down
181
182 // stop interface
183 netif_carrier_off(net_dev);
184 netif_stop_queue(net_dev);
185
186 // mark device as removed from system and therefore no longer available
187 netif_device_detach(net_dev);
188
189 // mark halt flag
190 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
191 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
192
193 // take down the device
194 rt28xx_close((PNET_DEV)net_dev);
195
196 RT_MOD_DEC_USE_COUNT();
197 }
198 }
199
200 // reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html
201 // enable device to generate PME# when suspended
202 // pci_choose_state(): Choose the power state of a PCI device to be suspended
203 retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1);
204 // save the PCI configuration space of a device before suspending
205 pci_save_state(pci_dev);
206 // disable PCI device after use
207 pci_disable_device(pci_dev);
208
209 retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
210
211 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n"));
212 return retval;
213}
214
215static int rt2860_resume(
216 struct pci_dev *pci_dev)
217{
218 struct net_device *net_dev = pci_get_drvdata(pci_dev);
219 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
220 INT32 retval;
221
222
223 // set the power state of a PCI device
224 // PCI has 4 power states, DO (normal) ~ D3(less power)
225 // in include/linux/pci.h, you can find that
226 // #define PCI_D0 ((pci_power_t __force) 0)
227 // #define PCI_D1 ((pci_power_t __force) 1)
228 // #define PCI_D2 ((pci_power_t __force) 2)
229 // #define PCI_D3hot ((pci_power_t __force) 3)
230 // #define PCI_D3cold ((pci_power_t __force) 4)
231 // #define PCI_UNKNOWN ((pci_power_t __force) 5)
232 // #define PCI_POWER_ERROR ((pci_power_t __force) -1)
233 retval = pci_set_power_state(pci_dev, PCI_D0);
234
235 // restore the saved state of a PCI device
236 pci_restore_state(pci_dev);
237
238 // initialize device before it's used by a driver
239 if (pci_enable_device(pci_dev))
240 {
241 printk("pci enable fail!\n");
242 return 0;
243 }
244
245 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n"));
246
247 if (net_dev == NULL)
248 {
249 DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
250 }
251 else
252 pAd = (PRTMP_ADAPTER)net_dev->priv;
253
254 if (pAd != NULL)
255 {
256 /* we can not use IFF_UP because ra0 down but ra1 up */
257 /* and 1 suspend/resume function for 1 module, not for each interface */
258 /* so Linux will call suspend/resume function once */
259 if (VIRTUAL_IF_NUM(pAd) > 0)
260 {
261 // mark device as attached from system and restart if needed
262 netif_device_attach(net_dev);
263
264 if (rt28xx_open((PNET_DEV)net_dev) != 0)
265 {
266 // open fail
267 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
268 return 0;
269 }
270
271 // increase MODULE use count
272 RT_MOD_INC_USE_COUNT();
273
274 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
275 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
276
277 netif_start_queue(net_dev);
278 netif_carrier_on(net_dev);
279 netif_wake_queue(net_dev);
280 }
281 }
282
283 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
284 return 0;
285}
286#endif // CONFIG_PM //
287#endif
288
289
290static INT __init rt2860_init_module(VOID)
291{
292#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
293 return pci_register_driver(&rt2860_driver);
294#else
295 return pci_module_init(&rt2860_driver);
296#endif
297}
298
299
300//
301// Driver module unload function
302//
303static VOID __exit rt2860_cleanup_module(VOID)
304{
305 pci_unregister_driver(&rt2860_driver);
306}
307
308module_init(rt2860_init_module);
309module_exit(rt2860_cleanup_module);
310
311
312static INT __devinit rt2860_init_one (
313 IN struct pci_dev *pci_dev,
314 IN const struct pci_device_id *ent)
315{
316 INT rc;
317
318 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_init_one\n"));
319
320 // wake up and enable device
321 if (pci_enable_device (pci_dev))
322 {
323 rc = -EIO;
324 }
325 else
326 {
327 rc = rt2860_probe(pci_dev, ent);
328 }
329
330 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_init_one\n"));
331 return rc;
332}
333
334
335static VOID __devexit rt2860_remove_one(
336 IN struct pci_dev *pci_dev)
337{
338 struct net_device *net_dev = pci_get_drvdata(pci_dev);
339 RTMP_ADAPTER *pAd = net_dev->priv;
340
341 DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n"));
342
343 if (pAd != NULL)
344 {
345#ifdef MULTIPLE_CARD_SUPPORT
346 if ((pAd->MC_RowID >= 0) && (pAd->MC_RowID <= MAX_NUM_OF_MULTIPLE_CARD))
347 MC_CardUsed[pAd->MC_RowID] = 0; // not clear MAC address
348#endif // MULTIPLE_CARD_SUPPORT //
349
350
351
352
353 // Unregister network device
354 unregister_netdev(net_dev);
355
356 // Unmap CSR base address
357 iounmap((char *)(net_dev->base_addr));
358
359 RTMPFreeAdapter(pAd);
360
361 // release memory region
362 release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
363 }
364 else
365 {
366 // Unregister network device
367 unregister_netdev(net_dev);
368
369 // Unmap CSR base address
370 iounmap((char *)(net_dev->base_addr));
371
372 // release memory region
373 release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0));
374 }
375
376 // Free pre-allocated net_device memory
377#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
378 free_netdev(net_dev);
379#else
380 kfree(net_dev);
381#endif
382}
383
384//
385// PCI device probe & initialization function
386//
387static INT __devinit rt2860_probe(
388 IN struct pci_dev *pci_dev,
389 IN const struct pci_device_id *ent)
390{
391 PRTMP_ADAPTER pAd;
392 INT rv = 0;
393
394 rv = (INT)rt28xx_probe((void *)pci_dev, (void *)ent, 0, &pAd);
395 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE);
396 return rv;
397}
398
399
400void init_thread_task(IN PRTMP_ADAPTER pAd)
401{
402 POS_COOKIE pObj;
403
404 pObj = (POS_COOKIE) pAd->OS_Cookie;
405
406 tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
407 tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet, (unsigned long)pAd);
408 tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet, (unsigned long)pAd);
409 tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet, (unsigned long)pAd);
410 tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet, (unsigned long)pAd);
411 tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet, (unsigned long)pAd);
412 tasklet_init(&pObj->hcca_dma_done_task, hcca_dma_done_tasklet, (unsigned long)pAd);
413 tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
414 tasklet_init(&pObj->fifo_statistic_full_task, fifo_statistic_full_tasklet, (unsigned long)pAd);
415}
416
417void kill_thread_task(IN PRTMP_ADAPTER pAd)
418{
419 POS_COOKIE pObj;
420
421 pObj = (POS_COOKIE) pAd->OS_Cookie;
422
423 tasklet_kill(&pObj->rx_done_task);
424 tasklet_kill(&pObj->mgmt_dma_done_task);
425 tasklet_kill(&pObj->ac0_dma_done_task);
426 tasklet_kill(&pObj->ac1_dma_done_task);
427 tasklet_kill(&pObj->ac2_dma_done_task);
428 tasklet_kill(&pObj->ac3_dma_done_task);
429 tasklet_kill(&pObj->hcca_dma_done_task);
430 tasklet_kill(&pObj->tbtt_task);
431 tasklet_kill(&pObj->fifo_statistic_full_task);
432}
433
434
435static void rt2860_int_enable(PRTMP_ADAPTER pAd, unsigned int mode)
436{
437 u32 regValue;
438
439 pAd->int_disable_mask &= ~(mode);
440 regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
441 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); // 1:enable
442
443 if (regValue != 0)
444 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
445}
446
447
448static void rt2860_int_disable(PRTMP_ADAPTER pAd, unsigned int mode)
449{
450 u32 regValue;
451
452 pAd->int_disable_mask |= mode;
453 regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
454 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); // 0: disable
455
456 if (regValue == 0)
457 {
458 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
459 }
460}
461
462static void mgmt_dma_done_tasklet(unsigned long data)
463{
464 unsigned long flags;
465 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
466 INT_SOURCE_CSR_STRUC IntSource;
467 POS_COOKIE pObj;
468
469 // Do nothing if the driver is starting halt state.
470 // This might happen when timer already been fired before cancel timer with mlmehalt
471 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
472 return;
473
474 pObj = (POS_COOKIE) pAd->OS_Cookie;
475
476 IntSource.word = 0;
477 IntSource.field.MgmtDmaDone = 1;
478 pAd->int_pending &= ~INT_MGMT_DLY;
479
480 RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
481
482 // if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any
483 // bug report output
484 RTMP_INT_LOCK(&pAd->irq_lock, flags);
485 /*
486 * double check to avoid lose of interrupts
487 */
488 if (pAd->int_pending & INT_MGMT_DLY)
489 {
490 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
491 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
492 return;
493 }
494
495 /* enable TxDataInt again */
496 rt2860_int_enable(pAd, INT_MGMT_DLY);
497 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
498}
499
500static void rx_done_tasklet(unsigned long data)
501{
502 unsigned long flags;
503 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
504 BOOLEAN bReschedule = 0;
505 POS_COOKIE pObj;
506
507 // Do nothing if the driver is starting halt state.
508 // This might happen when timer already been fired before cancel timer with mlmehalt
509 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
510 return;
511
512 pObj = (POS_COOKIE) pAd->OS_Cookie;
513
514 pAd->int_pending &= ~(INT_RX);
515#ifdef CONFIG_STA_SUPPORT
516 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
517 bReschedule = STARxDoneInterruptHandle(pAd, 0);
518#endif // CONFIG_STA_SUPPORT //
519
520 RTMP_INT_LOCK(&pAd->irq_lock, flags);
521 /*
522 * double check to avoid rotting packet
523 */
524 if (pAd->int_pending & INT_RX || bReschedule)
525 {
526 tasklet_hi_schedule(&pObj->rx_done_task);
527 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
528 return;
529 }
530
531 /* enable RxINT again */
532 rt2860_int_enable(pAd, INT_RX);
533 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
534
535}
536
537void fifo_statistic_full_tasklet(unsigned long data)
538{
539 unsigned long flags;
540 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
541 POS_COOKIE pObj;
542
543 // Do nothing if the driver is starting halt state.
544 // This might happen when timer already been fired before cancel timer with mlmehalt
545 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
546 return;
547
548 pObj = (POS_COOKIE) pAd->OS_Cookie;
549
550 pAd->int_pending &= ~(FifoStaFullInt);
551 NICUpdateFifoStaCounters(pAd);
552
553 RTMP_INT_LOCK(&pAd->irq_lock, flags);
554 /*
555 * double check to avoid rotting packet
556 */
557 if (pAd->int_pending & FifoStaFullInt)
558 {
559 tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
560 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
561 return;
562 }
563
564 /* enable RxINT again */
565
566 rt2860_int_enable(pAd, FifoStaFullInt);
567 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
568
569}
570
571static void hcca_dma_done_tasklet(unsigned long data)
572{
573 unsigned long flags;
574 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
575 INT_SOURCE_CSR_STRUC IntSource;
576 POS_COOKIE pObj;
577
578 // Do nothing if the driver is starting halt state.
579 // This might happen when timer already been fired before cancel timer with mlmehalt
580 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
581 return;
582
583 pObj = (POS_COOKIE) pAd->OS_Cookie;
584
585
586 IntSource.word = 0;
587 IntSource.field.HccaDmaDone = 1;
588 pAd->int_pending &= ~INT_HCCA_DLY;
589
590 RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
591
592 RTMP_INT_LOCK(&pAd->irq_lock, flags);
593 /*
594 * double check to avoid lose of interrupts
595 */
596 if (pAd->int_pending & INT_HCCA_DLY)
597 {
598 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
599 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
600 return;
601 }
602
603 /* enable TxDataInt again */
604 rt2860_int_enable(pAd, INT_HCCA_DLY);
605 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
606}
607
608static void ac3_dma_done_tasklet(unsigned long data)
609{
610 unsigned long flags;
611 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
612 INT_SOURCE_CSR_STRUC IntSource;
613 POS_COOKIE pObj;
614 BOOLEAN bReschedule = 0;
615
616 // Do nothing if the driver is starting halt state.
617 // This might happen when timer already been fired before cancel timer with mlmehalt
618 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
619 return;
620
621 pObj = (POS_COOKIE) pAd->OS_Cookie;
622
623 IntSource.word = 0;
624 IntSource.field.Ac3DmaDone = 1;
625 pAd->int_pending &= ~INT_AC3_DLY;
626
627 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
628
629 RTMP_INT_LOCK(&pAd->irq_lock, flags);
630 /*
631 * double check to avoid lose of interrupts
632 */
633 if ((pAd->int_pending & INT_AC3_DLY) || bReschedule)
634 {
635 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
636 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
637 return;
638 }
639
640 /* enable TxDataInt again */
641 rt2860_int_enable(pAd, INT_AC3_DLY);
642 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
643}
644
645static void ac2_dma_done_tasklet(unsigned long data)
646{
647 unsigned long flags;
648 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
649 INT_SOURCE_CSR_STRUC IntSource;
650 POS_COOKIE pObj;
651 BOOLEAN bReschedule = 0;
652
653 // Do nothing if the driver is starting halt state.
654 // This might happen when timer already been fired before cancel timer with mlmehalt
655 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
656 return;
657
658 pObj = (POS_COOKIE) pAd->OS_Cookie;
659
660 IntSource.word = 0;
661 IntSource.field.Ac2DmaDone = 1;
662 pAd->int_pending &= ~INT_AC2_DLY;
663
664 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
665
666 RTMP_INT_LOCK(&pAd->irq_lock, flags);
667
668 /*
669 * double check to avoid lose of interrupts
670 */
671 if ((pAd->int_pending & INT_AC2_DLY) || bReschedule)
672 {
673 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
674 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
675 return;
676 }
677
678 /* enable TxDataInt again */
679 rt2860_int_enable(pAd, INT_AC2_DLY);
680 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
681}
682
683static void ac1_dma_done_tasklet(unsigned long data)
684{
685 unsigned long flags;
686 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
687 INT_SOURCE_CSR_STRUC IntSource;
688 POS_COOKIE pObj;
689 BOOLEAN bReschedule = 0;
690
691 // Do nothing if the driver is starting halt state.
692 // This might happen when timer already been fired before cancel timer with mlmehalt
693 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
694 return;
695
696 pObj = (POS_COOKIE) pAd->OS_Cookie;
697
698 IntSource.word = 0;
699 IntSource.field.Ac1DmaDone = 1;
700 pAd->int_pending &= ~INT_AC1_DLY;
701
702 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
703
704 RTMP_INT_LOCK(&pAd->irq_lock, flags);
705 /*
706 * double check to avoid lose of interrupts
707 */
708 if ((pAd->int_pending & INT_AC1_DLY) || bReschedule)
709 {
710 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
711 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
712 return;
713 }
714
715 /* enable TxDataInt again */
716 rt2860_int_enable(pAd, INT_AC1_DLY);
717 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
718}
719
720static void ac0_dma_done_tasklet(unsigned long data)
721{
722 unsigned long flags;
723 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data;
724 INT_SOURCE_CSR_STRUC IntSource;
725 POS_COOKIE pObj;
726 BOOLEAN bReschedule = 0;
727
728 // Do nothing if the driver is starting halt state.
729 // This might happen when timer already been fired before cancel timer with mlmehalt
730 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
731 return;
732
733 pObj = (POS_COOKIE) pAd->OS_Cookie;
734
735 IntSource.word = 0;
736 IntSource.field.Ac0DmaDone = 1;
737 pAd->int_pending &= ~INT_AC0_DLY;
738
739 bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
740
741 RTMP_INT_LOCK(&pAd->irq_lock, flags);
742 /*
743 * double check to avoid lose of interrupts
744 */
745 if ((pAd->int_pending & INT_AC0_DLY) || bReschedule)
746 {
747 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
748 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
749 return;
750 }
751
752 /* enable TxDataInt again */
753 rt2860_int_enable(pAd, INT_AC0_DLY);
754 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
755}
756
757
758int print_int_count;
759
760IRQ_HANDLE_TYPE
761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
762rt2860_interrupt(int irq, void *dev_instance)
763#else
764rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
765#endif
766{
767 struct net_device *net_dev = (struct net_device *) dev_instance;
768 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) net_dev->priv;
769 INT_SOURCE_CSR_STRUC IntSource;
770 POS_COOKIE pObj;
771
772 pObj = (POS_COOKIE) pAd->OS_Cookie;
773
774
775 /* Note 03312008: we can not return here before
776 RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
777 RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);
778 Or kernel will panic after ifconfig ra0 down sometimes */
779
780
781 //
782 // Inital the Interrupt source.
783 //
784 IntSource.word = 0x00000000L;
785// McuIntSource.word = 0x00000000L;
786
787 //
788 // Get the interrupt sources & saved to local variable
789 //
790 //RTMP_IO_READ32(pAd, where, &McuIntSource.word);
791 //RTMP_IO_WRITE32(pAd, , McuIntSource.word);
792
793 //
794 // Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp
795 // And at the same time, clock maybe turned off that say there is no DMA service.
796 // when ASIC get to sleep.
797 // To prevent system hang on power saving.
798 // We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up.
799 //
800 // RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
801 // RT2860 => when ASIC is sleeping, MAC register can be read and written.
802
803 {
804 RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
805 RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
806 }
807
808 // Do nothing if Reset in progress
809 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
810 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
811 {
812#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
813 return IRQ_HANDLED;
814#else
815 return;
816#endif
817 }
818
819 //
820 // Handle interrupt, walk through all bits
821 // Should start from highest priority interrupt
822 // The priority can be adjust by altering processing if statement
823 //
824
825 pAd->bPCIclkOff = FALSE;
826
827 // If required spinlock, each interrupt service routine has to acquire
828 // and release itself.
829 //
830
831 // Do nothing if NIC doesn't exist
832 if (IntSource.word == 0xffffffff)
833 {
834 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
835#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
836 return IRQ_HANDLED;
837#else
838 return;
839#endif
840 }
841
842 if (IntSource.word & TxCoherent)
843 {
844 DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
845 RTMPHandleRxCoherentInterrupt(pAd);
846 }
847
848 if (IntSource.word & RxCoherent)
849 {
850 DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
851 RTMPHandleRxCoherentInterrupt(pAd);
852 }
853
854 if (IntSource.word & FifoStaFullInt)
855 {
856#if 1
857 if ((pAd->int_disable_mask & FifoStaFullInt) == 0)
858 {
859 /* mask FifoStaFullInt */
860 rt2860_int_disable(pAd, FifoStaFullInt);
861 tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
862 }
863 pAd->int_pending |= FifoStaFullInt;
864#else
865 NICUpdateFifoStaCounters(pAd);
866#endif
867 }
868
869 if (IntSource.word & INT_MGMT_DLY)
870 {
871 if ((pAd->int_disable_mask & INT_MGMT_DLY) ==0 )
872 {
873 rt2860_int_disable(pAd, INT_MGMT_DLY);
874 tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
875 }
876 pAd->int_pending |= INT_MGMT_DLY ;
877 }
878
879 if (IntSource.word & INT_RX)
880 {
881 if ((pAd->int_disable_mask & INT_RX) == 0)
882 {
883 /* mask RxINT */
884 rt2860_int_disable(pAd, INT_RX);
885 tasklet_hi_schedule(&pObj->rx_done_task);
886 }
887 pAd->int_pending |= INT_RX;
888 }
889
890 if (IntSource.word & INT_HCCA_DLY)
891 {
892
893 if ((pAd->int_disable_mask & INT_HCCA_DLY) == 0)
894 {
895 /* mask TxDataInt */
896 rt2860_int_disable(pAd, INT_HCCA_DLY);
897 tasklet_hi_schedule(&pObj->hcca_dma_done_task);
898 }
899 pAd->int_pending |= INT_HCCA_DLY;
900 }
901
902 if (IntSource.word & INT_AC3_DLY)
903 {
904
905 if ((pAd->int_disable_mask & INT_AC3_DLY) == 0)
906 {
907 /* mask TxDataInt */
908 rt2860_int_disable(pAd, INT_AC3_DLY);
909 tasklet_hi_schedule(&pObj->ac3_dma_done_task);
910 }
911 pAd->int_pending |= INT_AC3_DLY;
912 }
913
914 if (IntSource.word & INT_AC2_DLY)
915 {
916
917 if ((pAd->int_disable_mask & INT_AC2_DLY) == 0)
918 {
919 /* mask TxDataInt */
920 rt2860_int_disable(pAd, INT_AC2_DLY);
921 tasklet_hi_schedule(&pObj->ac2_dma_done_task);
922 }
923 pAd->int_pending |= INT_AC2_DLY;
924 }
925
926 if (IntSource.word & INT_AC1_DLY)
927 {
928
929 pAd->int_pending |= INT_AC1_DLY;
930
931 if ((pAd->int_disable_mask & INT_AC1_DLY) == 0)
932 {
933 /* mask TxDataInt */
934 rt2860_int_disable(pAd, INT_AC1_DLY);
935 tasklet_hi_schedule(&pObj->ac1_dma_done_task);
936 }
937
938 }
939
940 if (IntSource.word & INT_AC0_DLY)
941 {
942 pAd->int_pending |= INT_AC0_DLY;
943
944 if ((pAd->int_disable_mask & INT_AC0_DLY) == 0)
945 {
946 /* mask TxDataInt */
947 rt2860_int_disable(pAd, INT_AC0_DLY);
948 tasklet_hi_schedule(&pObj->ac0_dma_done_task);
949 }
950
951 }
952
953 if (IntSource.word & PreTBTTInt)
954 {
955 RTMPHandlePreTBTTInterrupt(pAd);
956 }
957
958 if (IntSource.word & TBTTInt)
959 {
960 RTMPHandleTBTTInterrupt(pAd);
961 }
962
963
964
965#ifdef CONFIG_STA_SUPPORT
966 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
967 {
968 if (IntSource.word & AutoWakeupInt)
969 RTMPHandleTwakeupInterrupt(pAd);
970 }
971#endif // CONFIG_STA_SUPPORT //
972
973#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
974 return IRQ_HANDLED;
975#endif
976
977}
978
979/*
980========================================================================
981Routine Description:
982 Check the chipset vendor/product ID.
983
984Arguments:
985 _dev_p Point to the PCI or USB device
986
987Return Value:
988 TRUE Check ok
989 FALSE Check fail
990
991Note:
992========================================================================
993*/
994BOOLEAN RT28XXChipsetCheck(
995 IN void *_dev_p)
996{
997 /* always TRUE */
998 return TRUE;
999}
1000
1001
1002/*
1003========================================================================
1004Routine Description:
1005 Init net device structure.
1006
1007Arguments:
1008 _dev_p Point to the PCI or USB device
1009 *net_dev Point to the net device
1010 *pAd the raxx interface data pointer
1011
1012Return Value:
1013 TRUE Init ok
1014 FALSE Init fail
1015
1016Note:
1017========================================================================
1018*/
1019BOOLEAN RT28XXNetDevInit(
1020 IN void *_dev_p,
1021 IN struct net_device *net_dev,
1022 IN RTMP_ADAPTER *pAd)
1023{
1024 struct pci_dev *pci_dev = (struct pci_dev *)_dev_p;
1025 CHAR *print_name;
1026 ULONG csr_addr;
1027
1028
1029#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1030 print_name = pci_dev ? pci_name(pci_dev) : "rt2860";
1031#else
1032 print_name = pci_dev ? pci_dev->slot_name : "rt2860";
1033#endif // LINUX_VERSION_CODE //
1034
1035 net_dev->base_addr = 0;
1036 net_dev->irq = 0;
1037
1038 if (pci_request_regions(pci_dev, print_name))
1039 goto err_out_free_netdev;
1040
1041 // interrupt IRQ number
1042 net_dev->irq = pci_dev->irq;
1043
1044 // map physical address to virtual address for accessing register
1045 csr_addr = (unsigned long) ioremap(pci_resource_start(pci_dev, 0),
1046 pci_resource_len(pci_dev, 0));
1047
1048 if (!csr_addr)
1049 {
1050 DBGPRINT(RT_DEBUG_ERROR,
1051 ("ioremap failed for device %s, region 0x%lX @ 0x%lX\n",
1052 print_name, (ULONG)pci_resource_len(pci_dev, 0),
1053 (ULONG)pci_resource_start(pci_dev, 0)));
1054 goto err_out_free_res;
1055 }
1056
1057 // Save CSR virtual address and irq to device structure
1058 net_dev->base_addr = csr_addr;
1059 pAd->CSRBaseAddress = (PUCHAR)net_dev->base_addr;
1060
1061 // Set DMA master
1062 pci_set_master(pci_dev);
1063
1064 net_dev->priv_flags = INT_MAIN;
1065
1066 DBGPRINT(RT_DEBUG_TRACE, ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n",
1067 net_dev->name, (ULONG)pci_resource_start(pci_dev, 0),
1068 (ULONG)csr_addr, pci_dev->irq));
1069 return TRUE;
1070
1071
1072 /* --------------------------- ERROR HANDLE --------------------------- */
1073err_out_free_res:
1074 pci_release_regions(pci_dev);
1075err_out_free_netdev:
1076 /* free netdev in caller, not here */
1077 return FALSE;
1078}
1079
1080
1081/*
1082========================================================================
1083Routine Description:
1084 Init net device structure.
1085
1086Arguments:
1087 _dev_p Point to the PCI or USB device
1088 *pAd the raxx interface data pointer
1089
1090Return Value:
1091 TRUE Config ok
1092 FALSE Config fail
1093
1094Note:
1095========================================================================
1096*/
1097BOOLEAN RT28XXProbePostConfig(
1098 IN void *_dev_p,
1099 IN RTMP_ADAPTER *pAd,
1100 IN INT32 argc)
1101{
1102 /* no use */
1103 return TRUE;
1104}
1105
1106
1107/*
1108========================================================================
1109Routine Description:
1110 Disable DMA.
1111
1112Arguments:
1113 *pAd the raxx interface data pointer
1114
1115Return Value:
1116 None
1117
1118Note:
1119========================================================================
1120*/
1121VOID RT28XXDMADisable(
1122 IN RTMP_ADAPTER *pAd)
1123{
1124 WPDMA_GLO_CFG_STRUC GloCfg;
1125
1126
1127 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1128 GloCfg.word &= 0xff0;
1129 GloCfg.field.EnTXWriteBackDDONE =1;
1130 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1131}
1132
1133
1134/*
1135========================================================================
1136Routine Description:
1137 Enable DMA.
1138
1139Arguments:
1140 *pAd the raxx interface data pointer
1141
1142Return Value:
1143 None
1144
1145Note:
1146========================================================================
1147*/
1148VOID RT28XXDMAEnable(
1149 IN RTMP_ADAPTER *pAd)
1150{
1151 WPDMA_GLO_CFG_STRUC GloCfg;
1152 int i = 0;
1153
1154 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
1155 do
1156 {
1157 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1158 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1159 break;
1160
1161 DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
1162 RTMPusecDelay(1000);
1163 i++;
1164 }while ( i <200);
1165
1166 RTMPusecDelay(50);
1167
1168 GloCfg.field.EnTXWriteBackDDONE = 1;
1169 GloCfg.field.WPDMABurstSIZE = 2;
1170 GloCfg.field.EnableRxDMA = 1;
1171 GloCfg.field.EnableTxDMA = 1;
1172
1173 DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
1174 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1175
1176}
1177
1178/*
1179========================================================================
1180Routine Description:
1181 Write Beacon buffer to Asic.
1182
1183Arguments:
1184 *pAd the raxx interface data pointer
1185
1186Return Value:
1187 None
1188
1189Note:
1190========================================================================
1191*/
1192VOID RT28xx_UpdateBeaconToAsic(
1193 IN RTMP_ADAPTER *pAd,
1194 IN INT apidx,
1195 IN ULONG FrameLen,
1196 IN ULONG UpdatePos)
1197{
1198 ULONG CapInfoPos = 0;
1199 UCHAR *ptr, *ptr_update, *ptr_capinfo;
1200 UINT i;
1201 BOOLEAN bBcnReq = FALSE;
1202 UCHAR bcn_idx = 0;
1203
1204 {
1205 DBGPRINT(RT_DEBUG_ERROR, ("%s() : No valid Interface be found.\n", __FUNCTION__));
1206 return;
1207 }
1208
1209 if (bBcnReq == FALSE)
1210 {
1211 /* when the ra interface is down, do not send its beacon frame */
1212 /* clear all zero */
1213 for(i=0; i<TXWI_SIZE; i+=4)
1214 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
1215 }
1216 else
1217 {
1218 ptr = (PUCHAR)&pAd->BeaconTxWI;
1219#ifdef RT_BIG_ENDIAN
1220 RTMPWIEndianChange(ptr, TYPE_TXWI);
1221#endif
1222 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
1223 {
1224 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
1225 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longptr);
1226 ptr += 4;
1227 }
1228
1229 // Update CapabilityInfo in Beacon
1230 for (i = CapInfoPos; i < (CapInfoPos+2); i++)
1231 {
1232 RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_capinfo);
1233 ptr_capinfo ++;
1234 }
1235
1236 if (FrameLen > UpdatePos)
1237 {
1238 for (i= UpdatePos; i< (FrameLen); i++)
1239 {
1240 RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_update);
1241 ptr_update ++;
1242 }
1243 }
1244
1245 }
1246
1247}
1248
1249#ifdef CONFIG_STA_SUPPORT
1250VOID RTMPInitPCIeLinkCtrlValue(
1251 IN PRTMP_ADAPTER pAd)
1252{
1253}
1254
1255VOID RTMPFindHostPCIDev(
1256 IN PRTMP_ADAPTER pAd)
1257{
1258}
1259
1260/*
1261 ========================================================================
1262
1263 Routine Description:
1264
1265 Arguments:
1266 Level = RESTORE_HALT : Restore PCI host and Ralink PCIe Link Control field to its default value.
1267 Level = Other Value : Restore from dot11 power save or radio off status. And force PCI host Link Control fields to 0x1
1268
1269 ========================================================================
1270*/
1271VOID RTMPPCIeLinkCtrlValueRestore(
1272 IN PRTMP_ADAPTER pAd,
1273 IN UCHAR Level)
1274{
1275}
1276
1277/*
1278 ========================================================================
1279
1280 Routine Description:
1281
1282 Arguments:
1283 Max : limit Host PCI and Ralink PCIe device's LINK CONTROL field's value.
1284 Because now frequently set our device to mode 1 or mode 3 will cause problem.
1285
1286 ========================================================================
1287*/
1288VOID RTMPPCIeLinkCtrlSetting(
1289 IN PRTMP_ADAPTER pAd,
1290 IN USHORT Max)
1291{
1292}
1293#endif // CONFIG_STA_SUPPORT //
1294
1295VOID rt2860_stop(struct net_device *net_dev)
1296{
1297 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL;
1298 if (net_dev == NULL)
1299 {
1300 DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
1301 }
1302 else
1303 pAd = (PRTMP_ADAPTER)net_dev->priv;
1304
1305 if (pAd != NULL)
1306 {
1307 // stop interface
1308 netif_carrier_off(net_dev);
1309 netif_stop_queue(net_dev);
1310
1311 // mark device as removed from system and therefore no longer available
1312 netif_device_detach(net_dev);
1313
1314 // mark halt flag
1315 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
1316 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1317
1318 // take down the device
1319 rt28xx_close((PNET_DEV)net_dev);
1320 RT_MOD_DEC_USE_COUNT();
1321 }
1322 return;
1323}
1324
1325/*
1326 * invaild or writeback cache
1327 * and convert virtual address to physical address
1328 */
1329dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction)
1330{
1331 PRTMP_ADAPTER pAd;
1332 POS_COOKIE pObj;
1333
1334 /*
1335 ------ Porting Information ------
1336 > For Tx Alloc:
1337 mgmt packets => sd_idx = 0
1338 SwIdx: pAd->MgmtRing.TxCpuIdx
1339 pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa;
1340
1341 data packets => sd_idx = 1
1342 TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx
1343 QueIdx: pTxBlk->QueIdx
1344 pTxD : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa;
1345
1346 > For Rx Alloc:
1347 sd_idx = -1
1348 */
1349
1350 pAd = (PRTMP_ADAPTER)handle;
1351 pObj = (POS_COOKIE)pAd->OS_Cookie;
1352
1353 if (sd_idx == 1)
1354 {
1355 PTX_BLK pTxBlk;
1356 pTxBlk = (PTX_BLK)ptr;
1357 return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, direction);
1358 }
1359 else
1360 {
1361 return pci_map_single(pObj->pci_dev, ptr, size, direction);
1362 }
1363
1364}
1365
1366void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction)
1367{
1368 PRTMP_ADAPTER pAd;
1369 POS_COOKIE pObj;
1370
1371 pAd=(PRTMP_ADAPTER)handle;
1372 pObj = (POS_COOKIE)pAd->OS_Cookie;
1373
1374 pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);
1375
1376}
1377
diff --git a/drivers/staging/rt2860/Kconfig b/drivers/staging/rt2860/Kconfig
new file mode 100644
index 00000000000..7f44e5e7246
--- /dev/null
+++ b/drivers/staging/rt2860/Kconfig
@@ -0,0 +1,5 @@
1config RT2860
2 tristate "Ralink 2860 wireless support"
3 depends on PCI && X86 && WLAN_80211
4 ---help---
5 This is an experimental driver for the Ralink 2860 wireless chip.
diff --git a/drivers/staging/rt2860/Makefile b/drivers/staging/rt2860/Makefile
new file mode 100644
index 00000000000..3496a6409d3
--- /dev/null
+++ b/drivers/staging/rt2860/Makefile
@@ -0,0 +1,41 @@
1obj-$(CONFIG_RT2860) += rt2860sta.o
2
3# TODO: all of these should be removed
4EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
5EXTRA_CFLAGS += -DRT2860
6EXTRA_CFLAGS += -DCONFIG_STA_SUPPORT
7EXTRA_CFLAGS += -DDBG
8EXTRA_CFLAGS += -DDOT11_N_SUPPORT
9
10rt2860sta-objs := \
11 common/md5.o \
12 common/mlme.o \
13 common/rtmp_wep.o \
14 common/action.o \
15 common/cmm_data.o \
16 common/rtmp_init.o \
17 common/rtmp_tkip.o \
18 common/cmm_sync.o \
19 common/eeprom.o \
20 common/cmm_sanity.o \
21 common/cmm_info.o \
22 common/cmm_wpa.o \
23 common/dfs.o \
24 common/spectrum.o \
25 sta/assoc.o \
26 sta/aironet.o \
27 sta/auth.o \
28 sta/auth_rsp.o \
29 sta/sync.o \
30 sta/sanity.o \
31 sta/rtmp_data.o \
32 sta/connect.o \
33 sta/wpa.o \
34 rt_linux.o \
35 rt_profile.o \
36 rt_main_dev.o \
37 sta_ioctl.o \
38 common/ba_action.o \
39 common/2860_rtmp_init.o \
40 2860_main_dev.o \
41 common/cmm_data_2860.o
diff --git a/drivers/staging/rt2860/TODO b/drivers/staging/rt2860/TODO
new file mode 100644
index 00000000000..2f70b0faca3
--- /dev/null
+++ b/drivers/staging/rt2860/TODO
@@ -0,0 +1,17 @@
1I'm hesitant to add a TODO file here, as the wireless developers would
2really have people help them out on the "clean" rt2860 driver that can
3be found at the rt2860.sf.net site.
4
5But, if you wish to clean up this driver instead, here's a short list of
6things that need to be done to get it into a more mergable shape:
7
8TODO:
9 - checkpatch.pl clean
10 - sparse clean
11 - port to in-kernel 80211 stack
12 - remove reading from /etc/ config files
13 - review by the wireless developer community
14
15Please send any patches or complaints about this driver to Greg
16Kroah-Hartman <greg@kroah.com> and don't bother the upstream wireless
17kernel developers about it, they want nothing to do with it.
diff --git a/drivers/staging/rt2860/aironet.h b/drivers/staging/rt2860/aironet.h
new file mode 100644
index 00000000000..1e07b19b8cd
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/ap.h b/drivers/staging/rt2860/ap.h
new file mode 100644
index 00000000000..df6db281312
--- /dev/null
+++ b/drivers/staging/rt2860/ap.h
@@ -0,0 +1,557 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 ap.h
29
30 Abstract:
31 Miniport generic portion header file
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Paul Lin 08-01-2002 created
37 James Tan 09-06-2002 modified (Revise NTCRegTable)
38 John Chang 12-22-2004 modified for RT2561/2661. merge with STA driver
39*/
40#ifndef __AP_H__
41#define __AP_H__
42
43
44
45// ========================= AP RTMP.h ================================
46
47
48
49// =============================================================
50// Function Prototypes
51// =============================================================
52
53// ap_data.c
54
55BOOLEAN APBridgeToWirelessSta(
56 IN PRTMP_ADAPTER pAd,
57 IN PUCHAR pHeader,
58 IN UINT HdrLen,
59 IN PUCHAR pData,
60 IN UINT DataLen,
61 IN ULONG fromwdsidx);
62
63BOOLEAN APHandleRxDoneInterrupt(
64 IN PRTMP_ADAPTER pAd);
65
66VOID APSendPackets(
67 IN NDIS_HANDLE MiniportAdapterContext,
68 IN PPNDIS_PACKET ppPacketArray,
69 IN UINT NumberOfPackets);
70
71NDIS_STATUS APSendPacket(
72 IN PRTMP_ADAPTER pAd,
73 IN PNDIS_PACKET pPacket);
74
75
76NDIS_STATUS APHardTransmit(
77 IN PRTMP_ADAPTER pAd,
78 IN TX_BLK *pTxBlk,
79 IN UCHAR QueIdx);
80
81VOID APRxEAPOLFrameIndicate(
82 IN PRTMP_ADAPTER pAd,
83 IN MAC_TABLE_ENTRY *pEntry,
84 IN RX_BLK *pRxBlk,
85 IN UCHAR FromWhichBSSID);
86
87NDIS_STATUS APCheckRxError(
88 IN PRTMP_ADAPTER pAd,
89 IN PRT28XX_RXD_STRUC pRxD,
90 IN UCHAR Wcid);
91
92BOOLEAN APCheckClass2Class3Error(
93 IN PRTMP_ADAPTER pAd,
94 IN ULONG Wcid,
95 IN PHEADER_802_11 pHeader);
96
97VOID APHandleRxPsPoll(
98 IN PRTMP_ADAPTER pAd,
99 IN PUCHAR pAddr,
100 IN USHORT Aid,
101 IN BOOLEAN isActive);
102
103VOID RTMPDescriptorEndianChange(
104 IN PUCHAR pData,
105 IN ULONG DescriptorType);
106
107VOID RTMPFrameEndianChange(
108 IN PRTMP_ADAPTER pAd,
109 IN PUCHAR pData,
110 IN ULONG Dir,
111 IN BOOLEAN FromRxDoneInt);
112
113// ap_assoc.c
114
115VOID APAssocStateMachineInit(
116 IN PRTMP_ADAPTER pAd,
117 IN STATE_MACHINE *S,
118 OUT STATE_MACHINE_FUNC Trans[]);
119
120VOID APPeerAssocReqAction(
121 IN PRTMP_ADAPTER pAd,
122 IN MLME_QUEUE_ELEM *Elem);
123
124VOID APPeerReassocReqAction(
125 IN PRTMP_ADAPTER pAd,
126 IN MLME_QUEUE_ELEM *Elem);
127
128VOID APPeerDisassocReqAction(
129 IN PRTMP_ADAPTER pAd,
130 IN MLME_QUEUE_ELEM *Elem);
131
132VOID MbssKickOutStas(
133 IN PRTMP_ADAPTER pAd,
134 IN INT apidx,
135 IN USHORT Reason);
136
137VOID APMlmeKickOutSta(
138 IN PRTMP_ADAPTER pAd,
139 IN PUCHAR pStaAddr,
140 IN UCHAR Wcid,
141 IN USHORT Reason);
142
143VOID APMlmeDisassocReqAction(
144 IN PRTMP_ADAPTER pAd,
145 IN MLME_QUEUE_ELEM *Elem);
146
147VOID APCls3errAction(
148 IN PRTMP_ADAPTER pAd,
149 IN ULONG Wcid,
150 IN PHEADER_802_11 pHeader);
151
152
153USHORT APBuildAssociation(
154 IN PRTMP_ADAPTER pAd,
155 IN MAC_TABLE_ENTRY *pEntry,
156 IN USHORT CapabilityInfo,
157 IN UCHAR MaxSupportedRateIn500Kbps,
158 IN UCHAR *RSN,
159 IN UCHAR *pRSNLen,
160 IN BOOLEAN bWmmCapable,
161 IN ULONG RalinkIe,
162#ifdef DOT11N_DRAFT3
163 IN EXT_CAP_INFO_ELEMENT ExtCapInfo,
164#endif // DOT11N_DRAFT3 //
165 IN HT_CAPABILITY_IE *pHtCapability,
166 IN UCHAR HtCapabilityLen,
167 OUT USHORT *pAid);
168
169// ap_auth.c
170
171void APAuthStateMachineInit(
172 IN PRTMP_ADAPTER pAd,
173 IN STATE_MACHINE *Sm,
174 OUT STATE_MACHINE_FUNC Trans[]);
175
176VOID APMlmeDeauthReqAction(
177 IN PRTMP_ADAPTER pAd,
178 IN MLME_QUEUE_ELEM *Elem);
179
180VOID APCls2errAction(
181 IN PRTMP_ADAPTER pAd,
182 IN ULONG Wcid,
183 IN PHEADER_802_11 pHeader);
184
185// ap_authrsp.c
186
187VOID APAuthRspStateMachineInit(
188 IN PRTMP_ADAPTER pAd,
189 IN PSTATE_MACHINE Sm,
190 IN STATE_MACHINE_FUNC Trans[]);
191
192VOID APPeerAuthAtAuthRspIdleAction(
193 IN PRTMP_ADAPTER pAd,
194 IN MLME_QUEUE_ELEM *Elem);
195
196VOID APPeerDeauthReqAction(
197 IN PRTMP_ADAPTER pAd,
198 IN MLME_QUEUE_ELEM *Elem);
199
200VOID APPeerAuthSimpleRspGenAndSend(
201 IN PRTMP_ADAPTER pAd,
202 IN PHEADER_802_11 pHdr80211,
203 IN USHORT Alg,
204 IN USHORT Seq,
205 IN USHORT StatusCode);
206
207// ap_connect.c
208
209BOOLEAN BeaconTransmitRequired(
210 IN PRTMP_ADAPTER pAd,
211 IN INT apidx);
212
213VOID APMakeBssBeacon(
214 IN PRTMP_ADAPTER pAd,
215 IN INT apidx);
216
217VOID APUpdateBeaconFrame(
218 IN PRTMP_ADAPTER pAd,
219 IN INT apidx);
220
221VOID APMakeAllBssBeacon(
222 IN PRTMP_ADAPTER pAd);
223
224VOID APUpdateAllBeaconFrame(
225 IN PRTMP_ADAPTER pAd);
226
227
228// ap_sync.c
229
230VOID APSyncStateMachineInit(
231 IN PRTMP_ADAPTER pAd,
232 IN STATE_MACHINE *Sm,
233 OUT STATE_MACHINE_FUNC Trans[]);
234
235VOID APScanTimeout(
236 IN PVOID SystemSpecific1,
237 IN PVOID FunctionContext,
238 IN PVOID SystemSpecific2,
239 IN PVOID SystemSpecific3);
240
241VOID APInvalidStateWhenScan(
242 IN PRTMP_ADAPTER pAd,
243 IN MLME_QUEUE_ELEM *Elem);
244
245VOID APScanTimeoutAction(
246 IN PRTMP_ADAPTER pAd,
247 IN MLME_QUEUE_ELEM *Elem);
248
249VOID APPeerProbeReqAction(
250 IN PRTMP_ADAPTER pAd,
251 IN MLME_QUEUE_ELEM *Elem);
252
253VOID APPeerBeaconAction(
254 IN PRTMP_ADAPTER pAd,
255 IN MLME_QUEUE_ELEM *Elem);
256
257VOID APMlmeScanReqAction(
258 IN PRTMP_ADAPTER pAd,
259 IN MLME_QUEUE_ELEM *Elem);
260
261VOID APPeerBeaconAtScanAction(
262 IN PRTMP_ADAPTER pAd,
263 IN MLME_QUEUE_ELEM *Elem);
264
265VOID APScanCnclAction(
266 IN PRTMP_ADAPTER pAd,
267 IN MLME_QUEUE_ELEM *Elem);
268
269VOID ApSiteSurvey(
270 IN PRTMP_ADAPTER pAd);
271
272VOID SupportRate(
273 IN PUCHAR SupRate,
274 IN UCHAR SupRateLen,
275 IN PUCHAR ExtRate,
276 IN UCHAR ExtRateLen,
277 OUT PUCHAR *Rates,
278 OUT PUCHAR RatesLen,
279 OUT PUCHAR pMaxSupportRate);
280
281
282BOOLEAN ApScanRunning(
283 IN PRTMP_ADAPTER pAd);
284
285#ifdef DOT11N_DRAFT3
286VOID APOverlappingBSSScan(
287 IN RTMP_ADAPTER *pAd);
288#endif // DOT11N_DRAFT3 //
289
290// ap_wpa.c
291
292VOID APWpaStateMachineInit(
293 IN PRTMP_ADAPTER pAd,
294 IN STATE_MACHINE *Sm,
295 OUT STATE_MACHINE_FUNC Trans[]);
296
297// ap_mlme.c
298
299VOID APMlmePeriodicExec(
300 IN PRTMP_ADAPTER pAd);
301
302VOID APMlmeSelectTxRateTable(
303 IN PRTMP_ADAPTER pAd,
304 IN PMAC_TABLE_ENTRY pEntry,
305 IN PUCHAR *ppTable,
306 IN PUCHAR pTableSize,
307 IN PUCHAR pInitTxRateIdx);
308
309VOID APMlmeSetTxRate(
310 IN PRTMP_ADAPTER pAd,
311 IN PMAC_TABLE_ENTRY pEntry,
312 IN PRTMP_TX_RATE_SWITCH pTxRate);
313
314VOID APMlmeDynamicTxRateSwitching(
315 IN PRTMP_ADAPTER pAd);
316
317VOID APQuickResponeForRateUpExec(
318 IN PVOID SystemSpecific1,
319 IN PVOID FunctionContext,
320 IN PVOID SystemSpecific2,
321 IN PVOID SystemSpecific3);
322
323BOOLEAN APMsgTypeSubst(
324 IN PRTMP_ADAPTER pAd,
325 IN PFRAME_802_11 pFrame,
326 OUT INT *Machine,
327 OUT INT *MsgType);
328
329VOID APQuickResponeForRateUpExec(
330 IN PVOID SystemSpecific1,
331 IN PVOID FunctionContext,
332 IN PVOID SystemSpecific2,
333 IN PVOID SystemSpecific3);
334
335
336VOID RTMPSetPiggyBack(
337 IN PRTMP_ADAPTER pAd,
338 IN BOOLEAN bPiggyBack);
339
340VOID APAsicEvaluateRxAnt(
341 IN PRTMP_ADAPTER pAd);
342
343VOID APAsicRxAntEvalTimeout(
344 IN PRTMP_ADAPTER pAd);
345
346// ap.c
347
348VOID APSwitchChannel(
349 IN PRTMP_ADAPTER pAd,
350 IN INT Channel);
351
352NDIS_STATUS APInitialize(
353 IN PRTMP_ADAPTER pAd);
354
355VOID APShutdown(
356 IN PRTMP_ADAPTER pAd);
357
358VOID APStartUp(
359 IN PRTMP_ADAPTER pAd);
360
361VOID APStop(
362 IN PRTMP_ADAPTER pAd);
363
364VOID APCleanupPsQueue(
365 IN PRTMP_ADAPTER pAd,
366 IN PQUEUE_HEADER pQueue);
367
368VOID MacTableReset(
369 IN PRTMP_ADAPTER pAd);
370
371MAC_TABLE_ENTRY *MacTableInsertEntry(
372 IN PRTMP_ADAPTER pAd,
373 IN PUCHAR pAddr,
374 IN UCHAR apidx,
375 IN BOOLEAN CleanAll);
376
377BOOLEAN MacTableDeleteEntry(
378 IN PRTMP_ADAPTER pAd,
379 IN USHORT wcid,
380 IN PUCHAR pAddr);
381
382MAC_TABLE_ENTRY *MacTableLookup(
383 IN PRTMP_ADAPTER pAd,
384 IN PUCHAR pAddr);
385
386VOID MacTableMaintenance(
387 IN PRTMP_ADAPTER pAd);
388
389UINT32 MacTableAssocStaNumGet(
390 IN PRTMP_ADAPTER pAd);
391
392MAC_TABLE_ENTRY *APSsPsInquiry(
393 IN PRTMP_ADAPTER pAd,
394 IN PUCHAR pAddr,
395 OUT SST *Sst,
396 OUT USHORT *Aid,
397 OUT UCHAR *PsMode,
398 OUT UCHAR *Rate);
399
400BOOLEAN APPsIndicate(
401 IN PRTMP_ADAPTER pAd,
402 IN PUCHAR pAddr,
403 IN ULONG Wcid,
404 IN UCHAR Psm);
405
406VOID ApLogEvent(
407 IN PRTMP_ADAPTER pAd,
408 IN PUCHAR pAddr,
409 IN USHORT Event);
410
411#ifdef DOT11_N_SUPPORT
412VOID APUpdateOperationMode(
413 IN PRTMP_ADAPTER pAd);
414#endif // DOT11_N_SUPPORT //
415
416VOID APUpdateCapabilityAndErpIe(
417 IN PRTMP_ADAPTER pAd);
418
419BOOLEAN ApCheckAccessControlList(
420 IN PRTMP_ADAPTER pAd,
421 IN PUCHAR pAddr,
422 IN UCHAR Apidx);
423
424VOID ApUpdateAccessControlList(
425 IN PRTMP_ADAPTER pAd,
426 IN UCHAR Apidx);
427
428VOID ApEnqueueNullFrame(
429 IN PRTMP_ADAPTER pAd,
430 IN PUCHAR pAddr,
431 IN UCHAR TxRate,
432 IN UCHAR PID,
433 IN UCHAR apidx,
434 IN BOOLEAN bQosNull,
435 IN BOOLEAN bEOSP,
436 IN UCHAR OldUP);
437
438VOID ApSendFrame(
439 IN PRTMP_ADAPTER pAd,
440 IN PVOID pBuffer,
441 IN ULONG Length,
442 IN UCHAR TxRate,
443 IN UCHAR PID);
444
445VOID ApEnqueueAckFrame(
446 IN PRTMP_ADAPTER pAd,
447 IN PUCHAR pAddr,
448 IN UCHAR TxRate,
449 IN UCHAR apidx);
450
451UCHAR APAutoSelectChannel(
452 IN PRTMP_ADAPTER pAd,
453 IN BOOLEAN Optimal);
454
455// ap_sanity.c
456
457
458BOOLEAN PeerAssocReqCmmSanity(
459 IN PRTMP_ADAPTER pAd,
460 IN BOOLEAN isRessoc,
461 IN VOID *Msg,
462 IN ULONG MsgLen,
463 OUT PUCHAR pAddr2,
464 OUT USHORT *pCapabilityInfo,
465 OUT USHORT *pListenInterval,
466 OUT PUCHAR pApAddr,
467 OUT UCHAR *pSsidLen,
468 OUT char *Ssid,
469 OUT UCHAR *pRatesLen,
470 OUT UCHAR Rates[],
471 OUT UCHAR *RSN,
472 OUT UCHAR *pRSNLen,
473 OUT BOOLEAN *pbWmmCapable,
474 OUT ULONG *pRalinkIe,
475#ifdef DOT11N_DRAFT3
476 OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo,
477#endif // DOT11N_DRAFT3 //
478 OUT UCHAR *pHtCapabilityLen,
479 OUT HT_CAPABILITY_IE *pHtCapability);
480
481BOOLEAN PeerDisassocReqSanity(
482 IN PRTMP_ADAPTER pAd,
483 IN VOID *Msg,
484 IN ULONG MsgLen,
485 OUT PUCHAR pAddr2,
486 OUT USHORT *Reason);
487
488BOOLEAN PeerDeauthReqSanity(
489 IN PRTMP_ADAPTER pAd,
490 IN VOID *Msg,
491 IN ULONG MsgLen,
492 OUT PUCHAR pAddr2,
493 OUT USHORT *Reason);
494
495BOOLEAN APPeerAuthSanity(
496 IN PRTMP_ADAPTER pAd,
497 IN VOID *Msg,
498 IN ULONG MsgLen,
499 OUT PUCHAR pAddr1,
500 OUT PUCHAR pAddr2,
501 OUT USHORT *Alg,
502 OUT USHORT *Seq,
503 OUT USHORT *Status,
504 CHAR *ChlgText);
505
506BOOLEAN APPeerProbeReqSanity(
507 IN PRTMP_ADAPTER pAd,
508 IN VOID *Msg,
509 IN ULONG MsgLen,
510 OUT PUCHAR pAddr2,
511 OUT CHAR Ssid[],
512 OUT UCHAR *SsidLen);
513
514BOOLEAN APPeerBeaconAndProbeRspSanity(
515 IN PRTMP_ADAPTER pAd,
516 IN VOID *Msg,
517 IN ULONG MsgLen,
518 OUT PUCHAR pAddr2,
519 OUT PUCHAR pBssid,
520 OUT CHAR Ssid[],
521 OUT UCHAR *SsidLen,
522 OUT UCHAR *BssType,
523 OUT USHORT *BeaconPeriod,
524 OUT UCHAR *Channel,
525 OUT LARGE_INTEGER *Timestamp,
526 OUT USHORT *CapabilityInfo,
527 OUT UCHAR Rate[],
528 OUT UCHAR *RateLen,
529 OUT BOOLEAN *ExtendedRateIeExist,
530 OUT UCHAR *Erp);
531
532// ap_info.c
533
534#ifdef WIN_NDIS
535NDIS_STATUS APQueryInformation(
536 IN NDIS_HANDLE MiniportAdapterContext,
537 IN NDIS_OID Oid,
538 IN PVOID pInformationBuffer,
539 IN ULONG InformationBufferLength,
540 OUT PULONG pBytesWritten,
541 OUT PULONG pBytesNeeded);
542
543NDIS_STATUS APSetInformation(
544 IN NDIS_HANDLE MiniportAdapterContext,
545 IN NDIS_OID Oid,
546 IN PVOID pInformationBuffer,
547 IN ULONG InformationBufferLength,
548 OUT PULONG pBytesRead,
549 OUT PULONG pBytesNeeded);
550#endif
551
552
553// ================== end of AP RTMP.h ========================
554
555
556#endif // __AP_H__
557
diff --git a/drivers/staging/rt2860/chlist.h b/drivers/staging/rt2860/chlist.h
new file mode 100644
index 00000000000..9e15b9daeb8
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/common/2860_rtmp_init.c b/drivers/staging/rt2860/common/2860_rtmp_init.c
new file mode 100644
index 00000000000..546f304ec33
--- /dev/null
+++ b/drivers/staging/rt2860/common/2860_rtmp_init.c
@@ -0,0 +1,922 @@
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 2860_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
42
43
44
45/*
46 ========================================================================
47
48 Routine Description:
49 Allocate DMA memory blocks for send, receive
50
51 Arguments:
52 Adapter Pointer to our adapter
53
54 Return Value:
55 NDIS_STATUS_SUCCESS
56 NDIS_STATUS_FAILURE
57 NDIS_STATUS_RESOURCES
58
59 IRQL = PASSIVE_LEVEL
60
61 Note:
62
63 ========================================================================
64*/
65NDIS_STATUS RTMPAllocTxRxRingMemory(
66 IN PRTMP_ADAPTER pAd)
67{
68 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
69 ULONG RingBasePaHigh;
70 ULONG RingBasePaLow;
71 PVOID RingBaseVa;
72 INT index, num;
73 PTXD_STRUC pTxD;
74 PRXD_STRUC pRxD;
75 ULONG ErrorValue = 0;
76 PRTMP_TX_RING pTxRing;
77 PRTMP_DMABUF pDmaBuf;
78 PNDIS_PACKET pPacket;
79
80 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
81 do
82 {
83 //
84 // Allocate all ring descriptors, include TxD, RxD, MgmtD.
85 // Although each size is different, to prevent cacheline and alignment
86 // issue, I intentional set them all to 64 bytes.
87 //
88 for (num=0; num<NUM_OF_TX_RING; num++)
89 {
90 ULONG BufBasePaHigh;
91 ULONG BufBasePaLow;
92 PVOID BufBaseVa;
93
94 //
95 // Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA)
96 //
97 pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE;
98 RTMP_AllocateTxDescMemory(
99 pAd,
100 num,
101 pAd->TxDescRing[num].AllocSize,
102 FALSE,
103 &pAd->TxDescRing[num].AllocVa,
104 &pAd->TxDescRing[num].AllocPa);
105
106 if (pAd->TxDescRing[num].AllocVa == NULL)
107 {
108 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
109 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
110 Status = NDIS_STATUS_RESOURCES;
111 break;
112 }
113
114 // Zero init this memory block
115 NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize);
116
117 // Save PA & VA for further operation
118 RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa);
119 RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa);
120 RingBaseVa = pAd->TxDescRing[num].AllocVa;
121
122 //
123 // Allocate all 1st TXBuf's memory for this TxRing
124 //
125 pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
126 RTMP_AllocateFirstTxBuffer(
127 pAd,
128 num,
129 pAd->TxBufSpace[num].AllocSize,
130 FALSE,
131 &pAd->TxBufSpace[num].AllocVa,
132 &pAd->TxBufSpace[num].AllocPa);
133
134 if (pAd->TxBufSpace[num].AllocVa == NULL)
135 {
136 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
137 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
138 Status = NDIS_STATUS_RESOURCES;
139 break;
140 }
141
142 // Zero init this memory block
143 NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize);
144
145 // Save PA & VA for further operation
146 BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa);
147 BufBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa);
148 BufBaseVa = pAd->TxBufSpace[num].AllocVa;
149
150 //
151 // Initialize Tx Ring Descriptor and associated buffer memory
152 //
153 pTxRing = &pAd->TxRing[num];
154 for (index = 0; index < TX_RING_SIZE; index++)
155 {
156 pTxRing->Cell[index].pNdisPacket = NULL;
157 pTxRing->Cell[index].pNextNdisPacket = NULL;
158 // Init Tx Ring Size, Va, Pa variables
159 pTxRing->Cell[index].AllocSize = TXD_SIZE;
160 pTxRing->Cell[index].AllocVa = RingBaseVa;
161 RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh);
162 RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow);
163
164 // Setup Tx Buffer size & address. only 802.11 header will store in this space
165 pDmaBuf = &pTxRing->Cell[index].DmaBuf;
166 pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
167 pDmaBuf->AllocVa = BufBaseVa;
168 RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh);
169 RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow);
170
171 // link the pre-allocated TxBuf to TXD
172 pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa;
173 pTxD->SDPtr0 = BufBasePaLow;
174 // advance to next ring descriptor address
175 pTxD->DMADONE = 1;
176#ifdef RT_BIG_ENDIAN
177 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
178#endif
179 RingBasePaLow += TXD_SIZE;
180 RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
181
182 // advance to next TxBuf address
183 BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
184 BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
185 }
186 DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index));
187 }
188 if (Status == NDIS_STATUS_RESOURCES)
189 break;
190
191 //
192 // Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler
193 //
194 pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
195 RTMP_AllocateMgmtDescMemory(
196 pAd,
197 pAd->MgmtDescRing.AllocSize,
198 FALSE,
199 &pAd->MgmtDescRing.AllocVa,
200 &pAd->MgmtDescRing.AllocPa);
201
202 if (pAd->MgmtDescRing.AllocVa == NULL)
203 {
204 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
205 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
206 Status = NDIS_STATUS_RESOURCES;
207 break;
208 }
209
210 // Zero init this memory block
211 NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
212
213 // Save PA & VA for further operation
214 RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
215 RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa);
216 RingBaseVa = pAd->MgmtDescRing.AllocVa;
217
218 //
219 // Initialize MGMT Ring and associated buffer memory
220 //
221 for (index = 0; index < MGMT_RING_SIZE; index++)
222 {
223 pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
224 pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
225 // Init MGMT Ring Size, Va, Pa variables
226 pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
227 pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
228 RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh);
229 RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow);
230
231 // Offset to next ring descriptor address
232 RingBasePaLow += TXD_SIZE;
233 RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE;
234
235 // link the pre-allocated TxBuf to TXD
236 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa;
237 pTxD->DMADONE = 1;
238
239#ifdef RT_BIG_ENDIAN
240 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
241#endif
242 // no pre-allocated buffer required in MgmtRing for scatter-gather case
243 }
244 DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index));
245
246 //
247 // Allocate RX ring descriptor's memory except Tx ring which allocated eariler
248 //
249 pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
250 RTMP_AllocateRxDescMemory(
251 pAd,
252 pAd->RxDescRing.AllocSize,
253 FALSE,
254 &pAd->RxDescRing.AllocVa,
255 &pAd->RxDescRing.AllocPa);
256
257 if (pAd->RxDescRing.AllocVa == NULL)
258 {
259 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
260 DBGPRINT_ERR(("Failed to allocate a big buffer\n"));
261 Status = NDIS_STATUS_RESOURCES;
262 break;
263 }
264
265 // Zero init this memory block
266 NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize);
267
268
269 printk("RX DESC %p size = %ld\n", pAd->RxDescRing.AllocVa,
270 pAd->RxDescRing.AllocSize);
271
272 // Save PA & VA for further operation
273 RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
274 RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa);
275 RingBaseVa = pAd->RxDescRing.AllocVa;
276
277 //
278 // Initialize Rx Ring and associated buffer memory
279 //
280 for (index = 0; index < RX_RING_SIZE; index++)
281 {
282 // Init RX Ring Size, Va, Pa variables
283 pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
284 pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
285 RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh);
286 RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow);
287
288 // Offset to next ring descriptor address
289 RingBasePaLow += RXD_SIZE;
290 RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE;
291
292 // Setup Rx associated Buffer size & allocate share memory
293 pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
294 pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
295 pPacket = RTMP_AllocateRxPacketBuffer(
296 pAd,
297 pDmaBuf->AllocSize,
298 FALSE,
299 &pDmaBuf->AllocVa,
300 &pDmaBuf->AllocPa);
301
302 /* keep allocated rx packet */
303 pAd->RxRing.Cell[index].pNdisPacket = pPacket;
304
305 // Error handling
306 if (pDmaBuf->AllocVa == NULL)
307 {
308 ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
309 DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n"));
310 Status = NDIS_STATUS_RESOURCES;
311 break;
312 }
313
314 // Zero init this memory block
315 NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);
316
317 // Write RxD buffer address & allocated buffer length
318 pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
319 pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
320 pRxD->DDONE = 0;
321
322#ifdef RT_BIG_ENDIAN
323 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
324#endif
325 }
326
327 DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index));
328
329 } while (FALSE);
330
331
332 NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
333 pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
334
335 if (pAd->FragFrame.pFragPacket == NULL)
336 {
337 Status = NDIS_STATUS_RESOURCES;
338 }
339
340 if (Status != NDIS_STATUS_SUCCESS)
341 {
342 // Log error inforamtion
343 NdisWriteErrorLogEntry(
344 pAd->AdapterHandle,
345 NDIS_ERROR_CODE_OUT_OF_RESOURCES,
346 1,
347 ErrorValue);
348 }
349
350 DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
351 return Status;
352}
353
354
355/*
356 ========================================================================
357
358 Routine Description:
359 Initialize transmit data structures
360
361 Arguments:
362 Adapter Pointer to our adapter
363
364 Return Value:
365 None
366
367 IRQL = PASSIVE_LEVEL
368
369 Note:
370 Initialize all transmit releated private buffer, include those define
371 in RTMP_ADAPTER structure and all private data structures.
372
373 ========================================================================
374*/
375VOID NICInitTxRxRingAndBacklogQueue(
376 IN PRTMP_ADAPTER pAd)
377{
378 //WPDMA_GLO_CFG_STRUC GloCfg;
379 int i;
380
381 DBGPRINT(RT_DEBUG_TRACE, ("<--> NICInitTxRxRingAndBacklogQueue\n"));
382
383 // Initialize all transmit related software queues
384 InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_BE]);
385 InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_BK]);
386 InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_VI]);
387 InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_VO]);
388 InitializeQueueHeader(&pAd->TxSwQueue[QID_HCCA]);
389
390 // Init RX Ring index pointer
391 pAd->RxRing.RxSwReadIdx = 0;
392 pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
393
394 // Init TX rings index pointer
395 for (i=0; i<NUM_OF_TX_RING; i++)
396 {
397 pAd->TxRing[i].TxSwFreeIdx = 0;
398 pAd->TxRing[i].TxCpuIdx = 0;
399 }
400
401 // init MGMT ring index pointer
402 pAd->MgmtRing.TxSwFreeIdx = 0;
403 pAd->MgmtRing.TxCpuIdx = 0;
404
405 pAd->PrivateInfo.TxRingFullCnt = 0;
406}
407
408
409/*
410 ========================================================================
411
412 Routine Description:
413 Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero.
414
415 Arguments:
416 Adapter Pointer to our adapter
417
418 Return Value:
419 None
420
421 IRQL = PASSIVE_LEVEL
422 IRQL = DISPATCH_LEVEL
423
424 Note:
425 Reset NIC to initial state AS IS system boot up time.
426
427 ========================================================================
428*/
429VOID RTMPRingCleanUp(
430 IN PRTMP_ADAPTER pAd,
431 IN UCHAR RingType)
432{
433 PTXD_STRUC pTxD;
434 PRXD_STRUC pRxD;
435 PQUEUE_ENTRY pEntry;
436 PNDIS_PACKET pPacket;
437 int i;
438 PRTMP_TX_RING pTxRing;
439 unsigned long IrqFlags;
440
441 DBGPRINT(RT_DEBUG_TRACE,("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, pAd->RalinkCounters.PendingNdisPacketCount));
442 switch (RingType)
443 {
444 case QID_AC_BK:
445 case QID_AC_BE:
446 case QID_AC_VI:
447 case QID_AC_VO:
448 case QID_HCCA:
449 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
450 pTxRing = &pAd->TxRing[RingType];
451
452 // We have to clean all descriptors in case some error happened with reset
453 for (i=0; i<TX_RING_SIZE; i++) // We have to scan all TX ring
454 {
455 pTxD = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
456
457 pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNdisPacket;
458 // release scatter-and-gather NDIS_PACKET
459 if (pPacket)
460 {
461 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
462 pTxRing->Cell[i].pNdisPacket = NULL;
463 }
464
465 pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNextNdisPacket;
466 // release scatter-and-gather NDIS_PACKET
467 if (pPacket)
468 {
469 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
470 pTxRing->Cell[i].pNextNdisPacket = NULL;
471 }
472 }
473
474 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, &pTxRing->TxDmaIdx);
475 pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
476 pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
477 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, pTxRing->TxCpuIdx);
478
479 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
480 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
481 while (pAd->TxSwQueue[RingType].Head != NULL)
482 {
483 pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]);
484 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
485 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
486 DBGPRINT(RT_DEBUG_TRACE,("Release 1 NDIS packet from s/w backlog queue\n"));
487 }
488 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
489 break;
490
491 case QID_MGMT:
492 // We have to clean all descriptors in case some error happened with reset
493 NdisAcquireSpinLock(&pAd->MgmtRingLock);
494
495 for (i=0; i<MGMT_RING_SIZE; i++)
496 {
497 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[i].AllocVa;
498
499 pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNdisPacket;
500 // rlease scatter-and-gather NDIS_PACKET
501 if (pPacket)
502 {
503 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
504 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
505 }
506 pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
507
508 pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNextNdisPacket;
509 // release scatter-and-gather NDIS_PACKET
510 if (pPacket)
511 {
512 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
513 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
514 }
515 pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL;
516
517 }
518
519 RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx);
520 pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx;
521 pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx;
522 RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
523
524 NdisReleaseSpinLock(&pAd->MgmtRingLock);
525 pAd->RalinkCounters.MgmtRingFullCount = 0;
526 break;
527
528 case QID_RX:
529 // We have to clean all descriptors in case some error happened with reset
530 NdisAcquireSpinLock(&pAd->RxRingLock);
531
532 for (i=0; i<RX_RING_SIZE; i++)
533 {
534 pRxD = (PRXD_STRUC) pAd->RxRing.Cell[i].AllocVa;
535 pRxD->DDONE = 0 ;
536 }
537
538 RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
539 pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx;
540 pAd->RxRing.RxCpuIdx = ((pAd->RxRing.RxDmaIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxDmaIdx-1));
541 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
542
543 NdisReleaseSpinLock(&pAd->RxRingLock);
544 break;
545
546 default:
547 break;
548 }
549}
550
551
552NDIS_STATUS AdapterBlockAllocateMemory(
553 IN PVOID handle,
554 OUT PVOID *ppAd)
555{
556 PPCI_DEV pci_dev;
557 dma_addr_t *phy_addr;
558 POS_COOKIE pObj = (POS_COOKIE) handle;
559
560 pci_dev = pObj->pci_dev;
561 phy_addr = &pObj->pAd_pa;
562
563 *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); //pci_alloc_consistent(pci_dev, sizeof(RTMP_ADAPTER), phy_addr);
564
565 if (*ppAd)
566 {
567 NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
568 ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
569 return (NDIS_STATUS_SUCCESS);
570 } else {
571 return (NDIS_STATUS_FAILURE);
572 }
573}
574
575
576void RTMP_AllocateTxDescMemory(
577 IN PRTMP_ADAPTER pAd,
578 IN UINT Index,
579 IN ULONG Length,
580 IN BOOLEAN Cached,
581 OUT PVOID *VirtualAddress,
582 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
583{
584 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
585
586 *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
587
588}
589
590void RTMP_AllocateMgmtDescMemory(
591 IN PRTMP_ADAPTER pAd,
592 IN ULONG Length,
593 IN BOOLEAN Cached,
594 OUT PVOID *VirtualAddress,
595 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
596{
597 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
598
599 *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
600
601}
602
603void RTMP_AllocateRxDescMemory(
604 IN PRTMP_ADAPTER pAd,
605 IN ULONG Length,
606 IN BOOLEAN Cached,
607 OUT PVOID *VirtualAddress,
608 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
609{
610 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
611
612 *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
613
614}
615
616void RTMP_FreeRxDescMemory(
617 IN PRTMP_ADAPTER pAd,
618 IN ULONG Length,
619 IN PVOID VirtualAddress,
620 IN NDIS_PHYSICAL_ADDRESS PhysicalAddress)
621{
622 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
623
624 PCI_FREE_CONSISTENT(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress);
625}
626
627
628void RTMP_AllocateFirstTxBuffer(
629 IN PRTMP_ADAPTER pAd,
630 IN UINT Index,
631 IN ULONG Length,
632 IN BOOLEAN Cached,
633 OUT PVOID *VirtualAddress,
634 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
635{
636 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
637
638 *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
639}
640
641/*
642 * FUNCTION: Allocate a common buffer for DMA
643 * ARGUMENTS:
644 * AdapterHandle: AdapterHandle
645 * Length: Number of bytes to allocate
646 * Cached: Whether or not the memory can be cached
647 * VirtualAddress: Pointer to memory is returned here
648 * PhysicalAddress: Physical address corresponding to virtual address
649 */
650
651void RTMP_AllocateSharedMemory(
652 IN PRTMP_ADAPTER pAd,
653 IN ULONG Length,
654 IN BOOLEAN Cached,
655 OUT PVOID *VirtualAddress,
656 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
657{
658 POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
659
660 *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress);
661}
662
663VOID RTMPFreeTxRxRingMemory(
664 IN PRTMP_ADAPTER pAd)
665{
666 int index, num , j;
667 PRTMP_TX_RING pTxRing;
668 PTXD_STRUC pTxD;
669 PNDIS_PACKET pPacket;
670 unsigned int IrqFlags;
671
672 POS_COOKIE pObj =(POS_COOKIE) pAd->OS_Cookie;
673
674 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n"));
675
676 // Free TxSwQueue Packet
677 for (index=0; index <NUM_OF_TX_RING; index++)
678 {
679 PQUEUE_ENTRY pEntry;
680 PNDIS_PACKET pPacket;
681 PQUEUE_HEADER pQueue;
682
683 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
684 pQueue = &pAd->TxSwQueue[index];
685 while (pQueue->Head)
686 {
687 pEntry = RemoveHeadQueue(pQueue);
688 pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
689 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
690 }
691 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
692 }
693
694 // Free Tx Ring Packet
695 for (index=0;index< NUM_OF_TX_RING;index++)
696 {
697 pTxRing = &pAd->TxRing[index];
698
699 for (j=0; j< TX_RING_SIZE; j++)
700 {
701 pTxD = (PTXD_STRUC) (pTxRing->Cell[j].AllocVa);
702 pPacket = pTxRing->Cell[j].pNdisPacket;
703
704 if (pPacket)
705 {
706 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
707 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
708 }
709 //Always assign pNdisPacket as NULL after clear
710 pTxRing->Cell[j].pNdisPacket = NULL;
711
712 pPacket = pTxRing->Cell[j].pNextNdisPacket;
713
714 if (pPacket)
715 {
716 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
717 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
718 }
719 //Always assign pNextNdisPacket as NULL after clear
720 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
721
722 }
723 }
724
725 for (index = RX_RING_SIZE - 1 ; index >= 0; index--)
726 {
727 if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket))
728 {
729 PCI_UNMAP_SINGLE(pObj->pci_dev, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
730 RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS);
731 }
732 }
733 NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB));
734
735 if (pAd->RxDescRing.AllocVa)
736 {
737 PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->RxDescRing.AllocSize, pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocPa);
738 }
739 NdisZeroMemory(&pAd->RxDescRing, sizeof(RTMP_DMABUF));
740
741 if (pAd->MgmtDescRing.AllocVa)
742 {
743 PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->MgmtDescRing.AllocSize, pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocPa);
744 }
745 NdisZeroMemory(&pAd->MgmtDescRing, sizeof(RTMP_DMABUF));
746
747 for (num = 0; num < NUM_OF_TX_RING; num++)
748 {
749 if (pAd->TxBufSpace[num].AllocVa)
750 {
751 PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxBufSpace[num].AllocSize, pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocPa);
752 }
753 NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(RTMP_DMABUF));
754
755 if (pAd->TxDescRing[num].AllocVa)
756 {
757 PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxDescRing[num].AllocSize, pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocPa);
758 }
759 NdisZeroMemory(&pAd->TxDescRing[num], sizeof(RTMP_DMABUF));
760 }
761
762 if (pAd->FragFrame.pFragPacket)
763 RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
764
765 DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n"));
766}
767
768
769/*
770 * FUNCTION: Allocate a packet buffer for DMA
771 * ARGUMENTS:
772 * AdapterHandle: AdapterHandle
773 * Length: Number of bytes to allocate
774 * Cached: Whether or not the memory can be cached
775 * VirtualAddress: Pointer to memory is returned here
776 * PhysicalAddress: Physical address corresponding to virtual address
777 * Notes:
778 * Cached is ignored: always cached memory
779 */
780PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
781 IN PRTMP_ADAPTER pAd,
782 IN ULONG Length,
783 IN BOOLEAN Cached,
784 OUT PVOID *VirtualAddress,
785 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
786{
787 PNDIS_PACKET pkt;
788
789 pkt = RTPKT_TO_OSPKT(DEV_ALLOC_SKB(Length));
790
791 if (pkt == NULL) {
792 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate rx %ld size packet\n",Length));
793 }
794
795 if (pkt) {
796 RTMP_SET_PACKET_SOURCE(pkt, PKTSRC_NDIS);
797 *VirtualAddress = (PVOID) RTPKT_TO_OSPKT(pkt)->data;
798 *PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1, PCI_DMA_FROMDEVICE);
799 } else {
800 *VirtualAddress = (PVOID) NULL;
801 *PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) NULL;
802 }
803
804 return (PNDIS_PACKET) pkt;
805}
806
807
808VOID Invalid_Remaining_Packet(
809 IN PRTMP_ADAPTER pAd,
810 IN ULONG VirtualAddress)
811{
812 NDIS_PHYSICAL_ADDRESS PhysicalAddress;
813
814 PhysicalAddress = PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress+1600), RX_BUFFER_NORMSIZE-1600, -1, PCI_DMA_FROMDEVICE);
815}
816
817PNDIS_PACKET GetPacketFromRxRing(
818 IN PRTMP_ADAPTER pAd,
819 OUT PRT28XX_RXD_STRUC pSaveRxD,
820 OUT BOOLEAN *pbReschedule,
821 IN OUT UINT32 *pRxPending)
822{
823 PRXD_STRUC pRxD;
824#ifdef RT_BIG_ENDIAN
825 PRXD_STRUC pDestRxD;
826 RXD_STRUC RxD;
827#endif
828 PNDIS_PACKET pRxPacket = NULL;
829 PNDIS_PACKET pNewPacket;
830 PVOID AllocVa;
831 NDIS_PHYSICAL_ADDRESS AllocPa;
832 BOOLEAN bReschedule = FALSE;
833
834 RTMP_SEM_LOCK(&pAd->RxRingLock);
835
836 if (*pRxPending == 0)
837 {
838 // Get how may packets had been received
839 RTMP_IO_READ32(pAd, RX_DRX_IDX , &pAd->RxRing.RxDmaIdx);
840
841 if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx)
842 {
843 // no more rx packets
844 bReschedule = FALSE;
845 goto done;
846 }
847
848 // get rx pending count
849 if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
850 *pRxPending = pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
851 else
852 *pRxPending = pAd->RxRing.RxDmaIdx + RX_RING_SIZE - pAd->RxRing.RxSwReadIdx;
853
854 }
855
856#ifdef RT_BIG_ENDIAN
857 pDestRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa;
858 RxD = *pDestRxD;
859 pRxD = &RxD;
860 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
861#else
862 // Point to Rx indexed rx ring descriptor
863 pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa;
864#endif
865
866 if (pRxD->DDONE == 0)
867 {
868 *pRxPending = 0;
869 // DMAIndx had done but DDONE bit not ready
870 bReschedule = TRUE;
871 goto done;
872 }
873
874
875 // return rx descriptor
876 NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
877
878 pNewPacket = RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, &AllocVa, &AllocPa);
879
880 if (pNewPacket)
881 {
882 // unmap the rx buffer
883 PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa,
884 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
885 pRxPacket = pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket;
886
887 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize = RX_BUFFER_AGGRESIZE;
888 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket = (PNDIS_PACKET) pNewPacket;
889 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocVa = AllocVa;
890 pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa = AllocPa;
891 /* update SDP0 to new buffer of rx packet */
892 pRxD->SDP0 = AllocPa;
893 }
894 else
895 {
896 //printk("No Rx Buffer\n");
897 pRxPacket = NULL;
898 bReschedule = TRUE;
899 }
900
901 pRxD->DDONE = 0;
902
903 // had handled one rx packet
904 *pRxPending = *pRxPending - 1;
905
906 // update rx descriptor and kick rx
907#ifdef RT_BIG_ENDIAN
908 RTMPDescriptorEndianChange((PUCHAR)pRxD, TYPE_RXD);
909 WriteBackToDescriptor((PUCHAR)pDestRxD, (PUCHAR)pRxD, FALSE, TYPE_RXD);
910#endif
911 INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
912
913 pAd->RxRing.RxCpuIdx = (pAd->RxRing.RxSwReadIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxSwReadIdx-1);
914 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
915
916done:
917 RTMP_SEM_UNLOCK(&pAd->RxRingLock);
918 *pbReschedule = bReschedule;
919 return pRxPacket;
920}
921/* End of 2860_rtmp_init.c */
922
diff --git a/drivers/staging/rt2860/common/action.c b/drivers/staging/rt2860/common/action.c
new file mode 100644
index 00000000000..d6f530fb857
--- /dev/null
+++ b/drivers/staging/rt2860/common/action.c
@@ -0,0 +1,1031 @@
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#ifdef CONFIG_STA_SUPPORT
224 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
225 BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress);
226#endif // CONFIG_STA_SUPPORT //
227
228 FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL funciton.
229 FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; // make sure sequence not clear in DEL funciton.
230 FrameBar.BarControl.TID = pInfo->TID; // make sure sequence not clear in DEL funciton.
231 FrameBar.BarControl.ACKPolicy = IMMED_BA; // make sure sequence not clear in DEL funciton.
232 FrameBar.BarControl.Compressed = 1; // make sure sequence not clear in DEL funciton.
233 FrameBar.BarControl.MTID = 0; // make sure sequence not clear in DEL funciton.
234
235 MakeOutgoingFrame(pOutBuffer2, &FrameLen,
236 sizeof(FRAME_BAR), &FrameBar,
237 END_OF_ARGS);
238 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
239 MlmeFreeMemory(pAd, pOutBuffer2);
240 DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
241
242 // SEND DELBA FRAME
243 FrameLen = 0;
244#ifdef CONFIG_STA_SUPPORT
245 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
246 {
247 if (ADHOC_ON(pAd))
248 ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
249 else
250#ifdef QOS_DLS_SUPPORT
251 if (pAd->MacTab.Content[pInfo->Wcid].ValidAsDls)
252 ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
253 else
254#endif // QOS_DLS_SUPPORT //
255 ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
256 }
257#endif // CONFIG_STA_SUPPORT //
258 Frame.Category = CATEGORY_BA;
259 Frame.Action = DELBA;
260 Frame.DelbaParm.Initiator = pInfo->Initiator;
261 Frame.DelbaParm.TID = pInfo->TID;
262 Frame.ReasonCode = 39; // Time Out
263 *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm));
264 Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
265
266 MakeOutgoingFrame(pOutBuffer, &FrameLen,
267 sizeof(FRAME_DELBA_REQ), &Frame,
268 END_OF_ARGS);
269 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
270 MlmeFreeMemory(pAd, pOutBuffer);
271 DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator));
272 }
273}
274#endif // DOT11_N_SUPPORT //
275
276VOID MlmeQOSAction(
277 IN PRTMP_ADAPTER pAd,
278 IN MLME_QUEUE_ELEM *Elem)
279{
280}
281
282VOID MlmeDLSAction(
283 IN PRTMP_ADAPTER pAd,
284 IN MLME_QUEUE_ELEM *Elem)
285{
286}
287
288VOID MlmeInvalidAction(
289 IN PRTMP_ADAPTER pAd,
290 IN MLME_QUEUE_ELEM *Elem)
291{
292 //PUCHAR pOutBuffer = NULL;
293 //Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11
294}
295
296VOID PeerQOSAction(
297 IN PRTMP_ADAPTER pAd,
298 IN MLME_QUEUE_ELEM *Elem)
299{
300}
301
302#ifdef QOS_DLS_SUPPORT
303VOID PeerDLSAction(
304 IN PRTMP_ADAPTER pAd,
305 IN MLME_QUEUE_ELEM *Elem)
306{
307 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
308
309 switch(Action)
310 {
311 case ACTION_DLS_REQUEST:
312#ifdef CONFIG_STA_SUPPORT
313 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
314 PeerDlsReqAction(pAd, Elem);
315#endif // CONFIG_STA_SUPPORT //
316 break;
317
318 case ACTION_DLS_RESPONSE:
319#ifdef CONFIG_STA_SUPPORT
320 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
321 PeerDlsRspAction(pAd, Elem);
322#endif // CONFIG_STA_SUPPORT //
323 break;
324
325 case ACTION_DLS_TEARDOWN:
326#ifdef CONFIG_STA_SUPPORT
327 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
328 PeerDlsTearDownAction(pAd, Elem);
329#endif // CONFIG_STA_SUPPORT //
330 break;
331 }
332}
333#endif // QOS_DLS_SUPPORT //
334
335#ifdef DOT11_N_SUPPORT
336VOID PeerBAAction(
337 IN PRTMP_ADAPTER pAd,
338 IN MLME_QUEUE_ELEM *Elem)
339{
340 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
341
342 switch(Action)
343 {
344 case ADDBA_REQ:
345 PeerAddBAReqAction(pAd,Elem);
346 break;
347 case ADDBA_RESP:
348 PeerAddBARspAction(pAd,Elem);
349 break;
350 case DELBA:
351 PeerDelBAAction(pAd,Elem);
352 break;
353 }
354}
355
356
357#ifdef DOT11N_DRAFT3
358
359#ifdef CONFIG_STA_SUPPORT
360VOID StaPublicAction(
361 IN PRTMP_ADAPTER pAd,
362 IN UCHAR Bss2040Coexist)
363{
364 BSS_2040_COEXIST_IE BssCoexist;
365 MLME_SCAN_REQ_STRUCT ScanReq;
366
367 BssCoexist.word = Bss2040Coexist;
368 // 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
369 if ((BssCoexist.field.InfoReq == 1) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040)))
370 {
371 // Clear record first. After scan , will update those bit and send back to transmiter.
372 pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1;
373 pAd->CommonCfg.BSSCoexist2040.field.Intolerant40 = 0;
374 pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 0;
375 // Fill out stuff for scan request
376 ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST);
377 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
378 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
379 }
380}
381
382
383/*
384Description : Build Intolerant Channel Rerpot from Trigger event table.
385return : how many bytes copied.
386*/
387ULONG BuildIntolerantChannelRep(
388 IN PRTMP_ADAPTER pAd,
389 IN PUCHAR pDest)
390{
391 ULONG FrameLen = 0;
392 ULONG ReadOffset = 0;
393 UCHAR i;
394 UCHAR LastRegClass = 0xff;
395 PUCHAR pLen;
396
397 for ( i = 0;i < MAX_TRIGGER_EVENT;i++)
398 {
399 if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE)
400 {
401 if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == LastRegClass)
402 {
403 *(pDest + ReadOffset) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
404 *pLen++;
405 ReadOffset++;
406 FrameLen++;
407 }
408 else
409 {
410 *(pDest + ReadOffset) = IE_2040_BSS_INTOLERANT_REPORT; // IE
411 *(pDest + ReadOffset + 1) = 2; // Len = RegClass byte + channel byte.
412 pLen = pDest + ReadOffset + 1;
413 LastRegClass = pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass;
414 *(pDest + ReadOffset + 2) = LastRegClass; // Len = RegClass byte + channel byte.
415 *(pDest + ReadOffset + 3) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
416 FrameLen += 4;
417 ReadOffset += 4;
418 }
419
420 }
421 }
422 return FrameLen;
423}
424
425
426/*
427Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
428*/
429VOID Send2040CoexistAction(
430 IN PRTMP_ADAPTER pAd,
431 IN UCHAR Wcid,
432 IN BOOLEAN bAddIntolerantCha)
433{
434 PUCHAR pOutBuffer = NULL;
435 NDIS_STATUS NStatus;
436 FRAME_ACTION_HDR Frame;
437 ULONG FrameLen;
438 ULONG IntolerantChaRepLen;
439
440 IntolerantChaRepLen = 0;
441 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
442 if(NStatus != NDIS_STATUS_SUCCESS)
443 {
444 DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n"));
445 return;
446 }
447 ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->CommonCfg.Bssid);
448 Frame.Category = CATEGORY_PUBLIC;
449 Frame.Action = ACTION_BSS_2040_COEXIST;
450
451 MakeOutgoingFrame(pOutBuffer, &FrameLen,
452 sizeof(FRAME_ACTION_HDR), &Frame,
453 END_OF_ARGS);
454
455 *(pOutBuffer + FrameLen) = pAd->CommonCfg.BSSCoexist2040.word;
456 FrameLen++;
457
458 if (bAddIntolerantCha == TRUE)
459 IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen);
460
461 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen);
462 DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x ) \n", pAd->CommonCfg.BSSCoexist2040.word));
463
464}
465
466
467/*
468 ==========================================================================
469 Description:
470 After scan, Update 20/40 BSS Coexistence IE and send out.
471 According to 802.11n D3.03 11.14.10
472
473 Parameters:
474 ==========================================================================
475 */
476VOID Update2040CoexistFrameAndNotify(
477 IN PRTMP_ADAPTER pAd,
478 IN UCHAR Wcid,
479 IN BOOLEAN bAddIntolerantCha)
480{
481 BSS_2040_COEXIST_IE OldValue;
482
483 OldValue.word = pAd->CommonCfg.BSSCoexist2040.word;
484 if ((pAd->CommonCfg.TriggerEventTab.EventANo > 0) || (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0))
485 pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 1;
486
487 // Need to check !!!!
488 // How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first.!!!!!
489 // So Only check BSS20WidthReq change.
490 if (OldValue.field.BSS20WidthReq != pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq)
491 {
492 Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha);
493 }
494}
495#endif // CONFIG_STA_SUPPORT //
496
497
498BOOLEAN ChannelSwitchSanityCheck(
499 IN PRTMP_ADAPTER pAd,
500 IN UCHAR Wcid,
501 IN UCHAR NewChannel,
502 IN UCHAR Secondary)
503{
504 UCHAR i;
505
506 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
507 return FALSE;
508
509 if ((NewChannel > 7) && (Secondary == 1))
510 return FALSE;
511
512 if ((NewChannel < 5) && (Secondary == 3))
513 return FALSE;
514
515 // 0. Check if new channel is in the channellist.
516 for (i = 0;i < pAd->ChannelListNum;i++)
517 {
518 if (pAd->ChannelList[i].Channel == NewChannel)
519 {
520 break;
521 }
522 }
523
524 if (i == pAd->ChannelListNum)
525 return FALSE;
526
527 return TRUE;
528}
529
530
531VOID ChannelSwitchAction(
532 IN PRTMP_ADAPTER pAd,
533 IN UCHAR Wcid,
534 IN UCHAR NewChannel,
535 IN UCHAR Secondary)
536{
537 UCHAR BBPValue = 0;
538 ULONG MACValue;
539
540 DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d) \n", NewChannel, Secondary));
541
542 if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE)
543 return;
544
545 // 1. Switches to BW = 20.
546 if (Secondary == 0)
547 {
548 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
549 BBPValue&= (~0x18);
550 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
551 if (pAd->MACVersion == 0x28600100)
552 {
553 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
554 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
555 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
556 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
557 }
558 pAd->CommonCfg.BBPCurrentBW = BW_20;
559 pAd->CommonCfg.Channel = NewChannel;
560 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
561 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel,FALSE);
562 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
563 pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 0;
564 DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz !!! \n" ));
565 }
566 // 1. Switches to BW = 40 And Station supports BW = 40.
567 else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
568 {
569 pAd->CommonCfg.Channel = NewChannel;
570
571 if (Secondary == 1)
572 {
573 // Secondary above.
574 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
575 RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
576 MACValue &= 0xfe;
577 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
578 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
579 BBPValue&= (~0x18);
580 BBPValue|= (0x10);
581 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
582 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
583 BBPValue&= (~0x20);
584 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
585 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
586 }
587 else
588 {
589 // Secondary below.
590 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
591 RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
592 MACValue &= 0xfe;
593 MACValue |= 0x1;
594 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
595 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
596 BBPValue&= (~0x18);
597 BBPValue|= (0x10);
598 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
599 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
600 BBPValue&= (~0x20);
601 BBPValue|= (0x20);
602 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
603 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
604 }
605 pAd->CommonCfg.BBPCurrentBW = BW_40;
606 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
607 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
608 pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 1;
609 }
610}
611#endif // DOT11N_DRAFT3 //
612#endif // DOT11_N_SUPPORT //
613
614VOID PeerPublicAction(
615 IN PRTMP_ADAPTER pAd,
616 IN MLME_QUEUE_ELEM *Elem)
617{
618#ifdef DOT11N_DRAFT3
619 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
620#endif // DOT11N_DRAFT3 //
621
622 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
623 return;
624
625#ifdef DOT11N_DRAFT3
626 switch(Action)
627 {
628 case ACTION_BSS_2040_COEXIST: // Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
629 {
630 //UCHAR BssCoexist;
631 BSS_2040_COEXIST_ELEMENT *pCoexistInfo;
632 BSS_2040_COEXIST_IE *pBssCoexistIe;
633 BSS_2040_INTOLERANT_CH_REPORT *pIntolerantReport = NULL;
634
635 if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) )
636 {
637 DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen));
638 break;
639 }
640 DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
641 hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen);
642
643
644 pCoexistInfo = (BSS_2040_COEXIST_ELEMENT *) &Elem->Msg[LENGTH_802_11+2];
645 //hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));
646 if (Elem->MsgLen >= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT) + sizeof(BSS_2040_INTOLERANT_CH_REPORT)))
647 {
648 pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT));
649 }
650 //hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
651
652 pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe);
653
654#ifdef CONFIG_STA_SUPPORT
655 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
656 {
657 if (INFRA_ON(pAd))
658 {
659 StaPublicAction(pAd, pCoexistInfo);
660 }
661 }
662#endif // CONFIG_STA_SUPPORT //
663
664 }
665 break;
666 }
667
668#endif // DOT11N_DRAFT3 //
669
670}
671
672
673static VOID ReservedAction(
674 IN PRTMP_ADAPTER pAd,
675 IN MLME_QUEUE_ELEM *Elem)
676{
677 UCHAR Category;
678
679 if (Elem->MsgLen <= LENGTH_802_11)
680 {
681 return;
682 }
683
684 Category = Elem->Msg[LENGTH_802_11];
685 DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category));
686 hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
687}
688
689VOID PeerRMAction(
690 IN PRTMP_ADAPTER pAd,
691 IN MLME_QUEUE_ELEM *Elem)
692
693{
694 return;
695}
696
697#ifdef DOT11_N_SUPPORT
698static VOID respond_ht_information_exchange_action(
699 IN PRTMP_ADAPTER pAd,
700 IN MLME_QUEUE_ELEM *Elem)
701{
702 PUCHAR pOutBuffer = NULL;
703 NDIS_STATUS NStatus;
704 ULONG FrameLen;
705 FRAME_HT_INFO HTINFOframe, *pFrame;
706 UCHAR *pAddr;
707
708
709 // 2. Always send back ADDBA Response
710 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
711
712 if (NStatus != NDIS_STATUS_SUCCESS)
713 {
714 DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
715 return;
716 }
717
718 // get RA
719 pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
720 pAddr = pFrame->Hdr.Addr2;
721
722 NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO));
723 // 2-1. Prepare ADDBA Response frame.
724#ifdef CONFIG_STA_SUPPORT
725 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
726 {
727 if (ADHOC_ON(pAd))
728 ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
729 else
730 ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
731 }
732#endif // CONFIG_STA_SUPPORT //
733
734 HTINFOframe.Category = CATEGORY_HT;
735 HTINFOframe.Action = HT_INFO_EXCHANGE;
736 HTINFOframe.HT_Info.Request = 0;
737 HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
738 HTINFOframe.HT_Info.STA_Channel_Width = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
739
740 MakeOutgoingFrame(pOutBuffer, &FrameLen,
741 sizeof(FRAME_HT_INFO), &HTINFOframe,
742 END_OF_ARGS);
743
744 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
745 MlmeFreeMemory(pAd, pOutBuffer);
746}
747
748
749#ifdef DOT11N_DRAFT3
750VOID SendNotifyBWActionFrame(
751 IN PRTMP_ADAPTER pAd,
752 IN UCHAR Wcid,
753 IN UCHAR apidx)
754{
755 PUCHAR pOutBuffer = NULL;
756 NDIS_STATUS NStatus;
757 FRAME_ACTION_HDR Frame;
758 ULONG FrameLen;
759 PUCHAR pAddr1;
760
761
762 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
763 if(NStatus != NDIS_STATUS_SUCCESS)
764 {
765 DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n"));
766 return;
767 }
768
769 if (Wcid == MCAST_WCID)
770 pAddr1 = &BROADCAST_ADDR[0];
771 else
772 pAddr1 = pAd->MacTab.Content[Wcid].Addr;
773 ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
774
775 Frame.Category = CATEGORY_HT;
776 Frame.Action = NOTIFY_BW_ACTION;
777
778 MakeOutgoingFrame(pOutBuffer, &FrameLen,
779 sizeof(FRAME_ACTION_HDR), &Frame,
780 END_OF_ARGS);
781
782 *(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
783 FrameLen++;
784
785
786 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
787 DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth));
788
789}
790#endif // DOT11N_DRAFT3 //
791
792
793VOID PeerHTAction(
794 IN PRTMP_ADAPTER pAd,
795 IN MLME_QUEUE_ELEM *Elem)
796{
797 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
798
799 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
800 return;
801
802 switch(Action)
803 {
804 case NOTIFY_BW_ACTION:
805 DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
806#ifdef CONFIG_STA_SUPPORT
807 if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
808 {
809 // Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
810 // sending BW_Notify Action frame, and cause us to linkup and linkdown.
811 // In legacy mode, don't need to parse HT action frame.
812 DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
813 Elem->Msg[LENGTH_802_11+2] ));
814 break;
815 }
816#endif // CONFIG_STA_SUPPORT //
817
818 if (Elem->Msg[LENGTH_802_11+2] == 0) // 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
819 pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
820
821 break;
822 case SMPS_ACTION:
823 // 7.3.1.25
824 DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
825 if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
826 {
827 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
828 }
829 else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
830 {
831 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
832 }
833 else
834 {
835 pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
836 }
837
838 DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode));
839 // rt2860c : add something for smps change.
840 break;
841
842 case SETPCO_ACTION:
843 break;
844 case MIMO_CHA_MEASURE_ACTION:
845 break;
846 case HT_INFO_EXCHANGE:
847 {
848 HT_INFORMATION_OCTET *pHT_info;
849
850 pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
851 // 7.4.8.10
852 DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
853 if (pHT_info->Request)
854 {
855 respond_ht_information_exchange_action(pAd, Elem);
856 }
857 }
858 break;
859 }
860}
861
862
863/*
864 ==========================================================================
865 Description:
866 Retry sending ADDBA Reqest.
867
868 IRQL = DISPATCH_LEVEL
869
870 Parametrs:
871 p8023Header: if this is already 802.3 format, p8023Header is NULL
872
873 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
874 FALSE , then continue indicaterx at this moment.
875 ==========================================================================
876 */
877VOID ORIBATimerTimeout(
878 IN PRTMP_ADAPTER pAd)
879{
880 MAC_TABLE_ENTRY *pEntry;
881 INT i, total;
882 UCHAR TID;
883
884#ifdef RALINK_ATE
885 if (ATE_ON(pAd))
886 return;
887#endif // RALINK_ATE //
888
889 total = pAd->MacTab.Size * NUM_OF_TID;
890
891 for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
892 {
893 if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
894 {
895 pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
896 TID = pAd->BATable.BAOriEntry[i].TID;
897
898 ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
899 }
900 total --;
901 }
902}
903
904
905VOID SendRefreshBAR(
906 IN PRTMP_ADAPTER pAd,
907 IN MAC_TABLE_ENTRY *pEntry)
908{
909 FRAME_BAR FrameBar;
910 ULONG FrameLen;
911 NDIS_STATUS NStatus;
912 PUCHAR pOutBuffer = NULL;
913 USHORT Sequence;
914 UCHAR i, TID;
915 USHORT idx;
916 BA_ORI_ENTRY *pBAEntry;
917
918 for (i = 0; i <NUM_OF_TID; i++)
919 {
920 idx = pEntry->BAOriWcidArray[i];
921 if (idx == 0)
922 {
923 continue;
924 }
925 pBAEntry = &pAd->BATable.BAOriEntry[idx];
926
927 if (pBAEntry->ORI_BA_Status == Originator_Done)
928 {
929 TID = pBAEntry->TID;
930
931 ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
932
933 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
934 if(NStatus != NDIS_STATUS_SUCCESS)
935 {
936 DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
937 return;
938 }
939
940 Sequence = pEntry->TxSeq[TID];
941#ifdef CONFIG_STA_SUPPORT
942 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
943 BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress);
944#endif // CONFIG_STA_SUPPORT //
945
946 FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
947 FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton.
948 FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton.
949
950 MakeOutgoingFrame(pOutBuffer, &FrameLen,
951 sizeof(FRAME_BAR), &FrameBar,
952 END_OF_ARGS);
953 if (1) // Now we always send BAR.
954 {
955 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
956 }
957 MlmeFreeMemory(pAd, pOutBuffer);
958 }
959 }
960}
961#endif // DOT11_N_SUPPORT //
962
963VOID ActHeaderInit(
964 IN PRTMP_ADAPTER pAd,
965 IN OUT PHEADER_802_11 pHdr80211,
966 IN PUCHAR Addr1,
967 IN PUCHAR Addr2,
968 IN PUCHAR Addr3)
969{
970 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
971 pHdr80211->FC.Type = BTYPE_MGMT;
972 pHdr80211->FC.SubType = SUBTYPE_ACTION;
973
974 COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
975 COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
976 COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
977}
978
979VOID BarHeaderInit(
980 IN PRTMP_ADAPTER pAd,
981 IN OUT PFRAME_BAR pCntlBar,
982 IN PUCHAR pDA,
983 IN PUCHAR pSA)
984{
985 NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
986 pCntlBar->FC.Type = BTYPE_CNTL;
987 pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
988 pCntlBar->BarControl.MTID = 0;
989 pCntlBar->BarControl.Compressed = 1;
990 pCntlBar->BarControl.ACKPolicy = 0;
991
992
993 pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
994
995 COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
996 COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
997}
998
999
1000/*
1001 ==========================================================================
1002 Description:
1003 Insert Category and action code into the action frame.
1004
1005 Parametrs:
1006 1. frame buffer pointer.
1007 2. frame length.
1008 3. category code of the frame.
1009 4. action code of the frame.
1010
1011 Return : None.
1012 ==========================================================================
1013 */
1014VOID InsertActField(
1015 IN PRTMP_ADAPTER pAd,
1016 OUT PUCHAR pFrameBuf,
1017 OUT PULONG pFrameLen,
1018 IN UINT8 Category,
1019 IN UINT8 ActCode)
1020{
1021 ULONG TempLen;
1022
1023 MakeOutgoingFrame( pFrameBuf, &TempLen,
1024 1, &Category,
1025 1, &ActCode,
1026 END_OF_ARGS);
1027
1028 *pFrameLen = *pFrameLen + TempLen;
1029
1030 return;
1031}
diff --git a/drivers/staging/rt2860/common/action.h b/drivers/staging/rt2860/common/action.h
new file mode 100644
index 00000000000..ce3877dce81
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/common/ba_action.c b/drivers/staging/rt2860/common/ba_action.c
new file mode 100644
index 00000000000..8247aeb73a2
--- /dev/null
+++ b/drivers/staging/rt2860/common/ba_action.c
@@ -0,0 +1,1802 @@
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#ifdef DOT11_N_SUPPORT
29
30#include "../rt_config.h"
31
32
33
34#define BA_ORI_INIT_SEQ (pEntry->TxSeq[TID]) //1 // inital sequence number of BA session
35
36#define ORI_SESSION_MAX_RETRY 8
37#define ORI_BA_SESSION_TIMEOUT (2000) // ms
38#define REC_BA_SESSION_IDLE_TIMEOUT (1000) // ms
39
40#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
41#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * HZ)/1000) // system ticks -- 100 ms
42
43#define RESET_RCV_SEQ (0xFFFF)
44
45static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk);
46
47
48BA_ORI_ENTRY *BATableAllocOriEntry(
49 IN PRTMP_ADAPTER pAd,
50 OUT USHORT *Idx);
51
52BA_REC_ENTRY *BATableAllocRecEntry(
53 IN PRTMP_ADAPTER pAd,
54 OUT USHORT *Idx);
55
56VOID BAOriSessionSetupTimeout(
57 IN PVOID SystemSpecific1,
58 IN PVOID FunctionContext,
59 IN PVOID SystemSpecific2,
60 IN PVOID SystemSpecific3);
61
62VOID BARecSessionIdleTimeout(
63 IN PVOID SystemSpecific1,
64 IN PVOID FunctionContext,
65 IN PVOID SystemSpecific2,
66 IN PVOID SystemSpecific3);
67
68
69BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout);
70BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout);
71
72#define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk) \
73 Announce_Reordering_Packet(_pAd, _mpdu_blk);
74
75VOID BA_MaxWinSizeReasign(
76 IN PRTMP_ADAPTER pAd,
77 IN MAC_TABLE_ENTRY *pEntryPeer,
78 OUT UCHAR *pWinSize)
79{
80 UCHAR MaxSize;
81
82
83 if (pAd->MACVersion >= RALINK_2883_VERSION) // 3*3
84 {
85 if (pAd->MACVersion >= RALINK_3070_VERSION)
86 {
87 if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
88 MaxSize = 7; // for non-open mode
89 else
90 MaxSize = 13;
91 }
92 else
93 MaxSize = 31;
94 }
95 else if (pAd->MACVersion >= RALINK_2880E_VERSION) // 2880 e
96 {
97 if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
98 MaxSize = 7; // for non-open mode
99 else
100 MaxSize = 13;
101 }
102 else
103 MaxSize = 7;
104
105 DBGPRINT(RT_DEBUG_TRACE, ("ba> Win Size = %d, Max Size = %d\n",
106 *pWinSize, MaxSize));
107
108 if ((*pWinSize) > MaxSize)
109 {
110 DBGPRINT(RT_DEBUG_TRACE, ("ba> reassign max win size from %d to %d\n",
111 *pWinSize, MaxSize));
112
113 *pWinSize = MaxSize;
114 }
115}
116
117void Announce_Reordering_Packet(IN PRTMP_ADAPTER pAd,
118 IN struct reordering_mpdu *mpdu)
119{
120 PNDIS_PACKET pPacket;
121
122 pPacket = mpdu->pPacket;
123
124 if (mpdu->bAMSDU)
125 {
126 ASSERT(0);
127 BA_Reorder_AMSDU_Annnounce(pAd, pPacket);
128 }
129 else
130 {
131 //
132 // pass this 802.3 packet to upper layer or forward this packet to WM directly
133 //
134
135#ifdef CONFIG_STA_SUPPORT
136 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
137 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket, RTMP_GET_PACKET_IF(pPacket));
138#endif // CONFIG_STA_SUPPORT //
139 }
140}
141
142/*
143 * Insert a reordering mpdu into sorted linked list by sequence no.
144 */
145BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list, struct reordering_mpdu *mpdu)
146{
147
148 struct reordering_mpdu **ppScan = &list->next;
149
150 while (*ppScan != NULL)
151 {
152 if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ))
153 {
154 ppScan = &(*ppScan)->next;
155 }
156 else if ((*ppScan)->Sequence == mpdu->Sequence)
157 {
158 /* give up this duplicated frame */
159 return(FALSE);
160 }
161 else
162 {
163 /* find position */
164 break;
165 }
166 }
167
168 mpdu->next = *ppScan;
169 *ppScan = mpdu;
170 list->qlen++;
171 return TRUE;
172}
173
174
175/*
176 * caller lock critical section if necessary
177 */
178static inline void ba_enqueue(struct reordering_list *list, struct reordering_mpdu *mpdu_blk)
179{
180 list->qlen++;
181 mpdu_blk->next = list->next;
182 list->next = mpdu_blk;
183}
184
185/*
186 * caller lock critical section if necessary
187 */
188static inline struct reordering_mpdu * ba_dequeue(struct reordering_list *list)
189{
190 struct reordering_mpdu *mpdu_blk = NULL;
191
192 ASSERT(list);
193
194 if (list->qlen)
195 {
196 list->qlen--;
197 mpdu_blk = list->next;
198 if (mpdu_blk)
199 {
200 list->next = mpdu_blk->next;
201 mpdu_blk->next = NULL;
202 }
203 }
204 return mpdu_blk;
205}
206
207
208static inline struct reordering_mpdu *ba_reordering_mpdu_dequeue(struct reordering_list *list)
209{
210 return(ba_dequeue(list));
211}
212
213
214static inline struct reordering_mpdu *ba_reordering_mpdu_probe(struct reordering_list *list)
215 {
216 ASSERT(list);
217
218 return(list->next);
219 }
220
221
222/*
223 * free all resource for reordering mechanism
224 */
225void ba_reordering_resource_release(PRTMP_ADAPTER pAd)
226{
227 BA_TABLE *Tab;
228 PBA_REC_ENTRY pBAEntry;
229 struct reordering_mpdu *mpdu_blk;
230 int i;
231
232 Tab = &pAd->BATable;
233
234 /* I. release all pending reordering packet */
235 NdisAcquireSpinLock(&pAd->BATabLock);
236 for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
237 {
238 pBAEntry = &Tab->BARecEntry[i];
239 if (pBAEntry->REC_BA_Status != Recipient_NONE)
240 {
241 while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
242 {
243 ASSERT(mpdu_blk->pPacket);
244 RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket, NDIS_STATUS_FAILURE);
245 ba_mpdu_blk_free(pAd, mpdu_blk);
246 }
247 }
248 }
249 NdisReleaseSpinLock(&pAd->BATabLock);
250
251 ASSERT(pBAEntry->list.qlen == 0);
252 /* II. free memory of reordering mpdu table */
253 NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
254 os_free_mem(pAd, pAd->mpdu_blk_pool.mem);
255 NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
256}
257
258
259
260/*
261 * Allocate all resource for reordering mechanism
262 */
263BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num)
264{
265 int i;
266 PUCHAR mem;
267 struct reordering_mpdu *mpdu_blk;
268 struct reordering_list *freelist;
269
270 /* allocate spinlock */
271 NdisAllocateSpinLock(&pAd->mpdu_blk_pool.lock);
272
273 /* initialize freelist */
274 freelist = &pAd->mpdu_blk_pool.freelist;
275 freelist->next = NULL;
276 freelist->qlen = 0;
277
278 DBGPRINT(RT_DEBUG_TRACE, ("Allocate %d memory for BA reordering\n", (UINT32)(num*sizeof(struct reordering_mpdu))));
279
280 /* allocate number of mpdu_blk memory */
281 os_alloc_mem(pAd, (PUCHAR *)&mem, (num*sizeof(struct reordering_mpdu)));
282
283 pAd->mpdu_blk_pool.mem = mem;
284
285 if (mem == NULL)
286 {
287 DBGPRINT(RT_DEBUG_ERROR, ("Can't Allocate Memory for BA Reordering\n"));
288 return(FALSE);
289 }
290
291 /* build mpdu_blk free list */
292 for (i=0; i<num; i++)
293 {
294 /* get mpdu_blk */
295 mpdu_blk = (struct reordering_mpdu *) mem;
296 /* initial mpdu_blk */
297 NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
298 /* next mpdu_blk */
299 mem += sizeof(struct reordering_mpdu);
300 /* insert mpdu_blk into freelist */
301 ba_enqueue(freelist, mpdu_blk);
302 }
303
304 return(TRUE);
305}
306
307//static int blk_count=0; // sample take off, no use
308
309static struct reordering_mpdu *ba_mpdu_blk_alloc(PRTMP_ADAPTER pAd)
310{
311 struct reordering_mpdu *mpdu_blk;
312
313 NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
314 mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist);
315 if (mpdu_blk)
316 {
317// blk_count++;
318 /* reset mpdu_blk */
319 NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
320 }
321 NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
322 return mpdu_blk;
323}
324
325static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk)
326{
327 ASSERT(mpdu_blk);
328
329 NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
330// blk_count--;
331 ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk);
332 NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
333}
334
335
336static USHORT ba_indicate_reordering_mpdus_in_order(
337 IN PRTMP_ADAPTER pAd,
338 IN PBA_REC_ENTRY pBAEntry,
339 IN USHORT StartSeq)
340{
341 struct reordering_mpdu *mpdu_blk;
342 USHORT LastIndSeq = RESET_RCV_SEQ;
343
344 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
345
346 while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
347 {
348 /* find in-order frame */
349 if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ))
350 {
351 break;
352 }
353 /* dequeue in-order frame from reodering list */
354 mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
355 /* pass this frame up */
356 ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
357 /* move to next sequence */
358 StartSeq = mpdu_blk->Sequence;
359 LastIndSeq = StartSeq;
360 /* free mpdu_blk */
361 ba_mpdu_blk_free(pAd, mpdu_blk);
362 }
363
364 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
365
366 /* update last indicated sequence */
367 return LastIndSeq;
368}
369
370static void ba_indicate_reordering_mpdus_le_seq(
371 IN PRTMP_ADAPTER pAd,
372 IN PBA_REC_ENTRY pBAEntry,
373 IN USHORT Sequence)
374{
375 struct reordering_mpdu *mpdu_blk;
376
377 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
378 while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
379 {
380 /* find in-order frame */
381 if ((mpdu_blk->Sequence == Sequence) || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ))
382 {
383 /* dequeue in-order frame from reodering list */
384 mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
385 /* pass this frame up */
386 ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
387 /* free mpdu_blk */
388 ba_mpdu_blk_free(pAd, mpdu_blk);
389 }
390 else
391 {
392 break;
393 }
394 }
395 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
396}
397
398
399static void ba_refresh_reordering_mpdus(
400 IN PRTMP_ADAPTER pAd,
401 PBA_REC_ENTRY pBAEntry)
402{
403 struct reordering_mpdu *mpdu_blk;
404
405 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
406
407 /* dequeue in-order frame from reodering list */
408 while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
409 {
410 /* pass this frame up */
411 ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
412
413 pBAEntry->LastIndSeq = mpdu_blk->Sequence;
414 ba_mpdu_blk_free(pAd, mpdu_blk);
415
416 /* update last indicated sequence */
417 }
418 ASSERT(pBAEntry->list.qlen == 0);
419 pBAEntry->LastIndSeq = RESET_RCV_SEQ;
420 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
421}
422
423
424//static
425void ba_flush_reordering_timeout_mpdus(
426 IN PRTMP_ADAPTER pAd,
427 IN PBA_REC_ENTRY pBAEntry,
428 IN ULONG Now32)
429
430{
431 USHORT Sequence;
432
433// if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) &&
434// (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //||
435// (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) &&
436// (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8)))
437 if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT/6)))
438 &&(pBAEntry->list.qlen > 1)
439 )
440 {
441 DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
442 (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
443 pBAEntry->LastIndSeq));
444 ba_refresh_reordering_mpdus(pAd, pBAEntry);
445 pBAEntry->LastIndSeqAtTimer = Now32;
446 }
447 else
448 if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
449 && (pBAEntry->list.qlen > 0)
450 )
451 {
452// printk("timeout[%d] (%lx-%lx = %d > %d): %x, ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
453// (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), REORDERING_PACKET_TIMEOUT,
454// pBAEntry->LastIndSeq);
455 //
456 // force LastIndSeq to shift to LastIndSeq+1
457 //
458 Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ;
459 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
460 pBAEntry->LastIndSeqAtTimer = Now32;
461 pBAEntry->LastIndSeq = Sequence;
462 //
463 // indicate in-order mpdus
464 //
465 Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence);
466 if (Sequence != RESET_RCV_SEQ)
467 {
468 pBAEntry->LastIndSeq = Sequence;
469 }
470
471 //printk("%x, flush one!\n", pBAEntry->LastIndSeq);
472
473 }
474#if 0
475 else if (
476 (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT))) &&
477 (pBAEntry->list.qlen > 1))
478 )
479 {
480 DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%lx-%lx = %d > %d): %x\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
481 (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
482 pBAEntry->LastIndSeq));
483 ba_refresh_reordering_mpdus(pAd, pBAEntry);
484 pBAEntry->LastIndSeqAtTimer = Now32;
485 }
486#endif
487}
488
489
490/*
491 * generate ADDBA request to
492 * set up BA agreement
493 */
494VOID BAOriSessionSetUp(
495 IN PRTMP_ADAPTER pAd,
496 IN MAC_TABLE_ENTRY *pEntry,
497 IN UCHAR TID,
498 IN USHORT TimeOut,
499 IN ULONG DelayTime,
500 IN BOOLEAN isForced)
501
502{
503 //MLME_ADDBA_REQ_STRUCT AddbaReq;
504 BA_ORI_ENTRY *pBAEntry = NULL;
505 USHORT Idx;
506 BOOLEAN Cancelled;
507
508 if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE) && (isForced == FALSE))
509 return;
510
511 // if this entry is limited to use legacy tx mode, it doesn't generate BA.
512 if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT)
513 return;
514
515 if ((pEntry->BADeclineBitmap & (1<<TID)) && (isForced == FALSE))
516 {
517 // try again after 3 secs
518 DelayTime = 3000;
519// printk("DeCline BA from Peer\n");
520// return;
521 }
522
523
524 Idx = pEntry->BAOriWcidArray[TID];
525 if (Idx == 0)
526 {
527 // allocate a BA session
528 pBAEntry = BATableAllocOriEntry(pAd, &Idx);
529 if (pBAEntry == NULL)
530 {
531 DBGPRINT(RT_DEBUG_TRACE,("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
532 return;
533 }
534 }
535 else
536 {
537 pBAEntry =&pAd->BATable.BAOriEntry[Idx];
538 }
539
540 if (pBAEntry->ORI_BA_Status >= Originator_WaitRes)
541 {
542 return;
543 }
544
545 pEntry->BAOriWcidArray[TID] = Idx;
546
547 // Initialize BA session
548 pBAEntry->ORI_BA_Status = Originator_WaitRes;
549 pBAEntry->Wcid = pEntry->Aid;
550 pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
551 pBAEntry->Sequence = BA_ORI_INIT_SEQ;
552 pBAEntry->Token = 1; // (2008-01-21) Jan Lee recommends it - this token can't be 0
553 pBAEntry->TID = TID;
554 pBAEntry->TimeOutValue = TimeOut;
555 pBAEntry->pAdapter = pAd;
556
557 if (!(pEntry->TXBAbitmap & (1<<TID)))
558 {
559 RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
560 }
561 else
562 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
563
564 // set timer to send ADDBA request
565 RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime);
566}
567
568VOID BAOriSessionAdd(
569 IN PRTMP_ADAPTER pAd,
570 IN MAC_TABLE_ENTRY *pEntry,
571 IN PFRAME_ADDBA_RSP pFrame)
572{
573 BA_ORI_ENTRY *pBAEntry = NULL;
574 BOOLEAN Cancelled;
575 UCHAR TID;
576 USHORT Idx;
577 PUCHAR pOutBuffer2 = NULL;
578 NDIS_STATUS NStatus;
579 ULONG FrameLen;
580 FRAME_BAR FrameBar;
581
582 TID = pFrame->BaParm.TID;
583 Idx = pEntry->BAOriWcidArray[TID];
584 pBAEntry =&pAd->BATable.BAOriEntry[Idx];
585
586 // Start fill in parameters.
587 if ((Idx !=0) && (pBAEntry->TID == TID) && (pBAEntry->ORI_BA_Status == Originator_WaitRes))
588 {
589 pBAEntry->BAWinSize = min(pBAEntry->BAWinSize, ((UCHAR)pFrame->BaParm.BufSize));
590 BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize);
591
592 pBAEntry->TimeOutValue = pFrame->TimeOutValue;
593 pBAEntry->ORI_BA_Status = Originator_Done;
594 // reset sequence number
595 pBAEntry->Sequence = BA_ORI_INIT_SEQ;
596 // Set Bitmap flag.
597 pEntry->TXBAbitmap |= (1<<TID);
598 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
599
600 pBAEntry->ORIBATimer.TimerValue = 0; //pFrame->TimeOutValue;
601
602 DBGPRINT(RT_DEBUG_TRACE,("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n", __FUNCTION__, pEntry->TXBAbitmap,
603 pBAEntry->BAWinSize, pBAEntry->ORIBATimer.TimerValue));
604
605 // SEND BAR ;
606 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
607 if (NStatus != NDIS_STATUS_SUCCESS)
608 {
609 DBGPRINT(RT_DEBUG_TRACE,("BA - BAOriSessionAdd() allocate memory failed \n"));
610 return;
611 }
612
613
614#ifdef CONFIG_STA_SUPPORT
615 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
616 BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->CurrentAddress);
617#endif // CONFIG_STA_SUPPORT //
618
619 FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
620 FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; // make sure sequence not clear in DEL funciton.
621 FrameBar.BarControl.TID = pBAEntry->TID; // make sure sequence not clear in DEL funciton.
622 MakeOutgoingFrame(pOutBuffer2, &FrameLen,
623 sizeof(FRAME_BAR), &FrameBar,
624 END_OF_ARGS);
625 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
626 MlmeFreeMemory(pAd, pOutBuffer2);
627
628
629 if (pBAEntry->ORIBATimer.TimerValue)
630 RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); // in mSec
631 }
632}
633
634BOOLEAN BARecSessionAdd(
635 IN PRTMP_ADAPTER pAd,
636 IN MAC_TABLE_ENTRY *pEntry,
637 IN PFRAME_ADDBA_REQ pFrame)
638{
639 BA_REC_ENTRY *pBAEntry = NULL;
640 BOOLEAN Status = TRUE;
641 BOOLEAN Cancelled;
642 USHORT Idx;
643 UCHAR TID;
644 UCHAR BAWinSize;
645 //UINT32 Value;
646 //UINT offset;
647
648
649 ASSERT(pEntry);
650
651 // find TID
652 TID = pFrame->BaParm.TID;
653
654 BAWinSize = min(((UCHAR)pFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
655
656 // Intel patch
657 if (BAWinSize == 0)
658 {
659 BAWinSize = 64;
660 }
661
662 Idx = pEntry->BARecWcidArray[TID];
663
664
665 if (Idx == 0)
666 {
667 pBAEntry = BATableAllocRecEntry(pAd, &Idx);
668 }
669 else
670 {
671 pBAEntry = &pAd->BATable.BARecEntry[Idx];
672 // flush all pending reordering mpdus
673 ba_refresh_reordering_mpdus(pAd, pBAEntry);
674 }
675
676 DBGPRINT(RT_DEBUG_TRACE,("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __FUNCTION__, pAd->BATable.numAsRecipient, Idx,
677 pFrame->BaParm.BufSize, BAWinSize));
678
679 // Start fill in parameters.
680 if (pBAEntry != NULL)
681 {
682 ASSERT(pBAEntry->list.qlen == 0);
683
684 pBAEntry->REC_BA_Status = Recipient_HandleRes;
685 pBAEntry->BAWinSize = BAWinSize;
686 pBAEntry->Wcid = pEntry->Aid;
687 pBAEntry->TID = TID;
688 pBAEntry->TimeOutValue = pFrame->TimeOutValue;
689 pBAEntry->REC_BA_Status = Recipient_Accept;
690 // initial sequence number
691 pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq;
692
693 printk("Start Seq = %08x\n", pFrame->BaStartSeq.field.StartSeq);
694
695 if (pEntry->RXBAbitmap & (1<<TID))
696 {
697 RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
698 }
699 else
700 {
701 RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE);
702 }
703
704#if 0 // for debugging
705 RTMPSetTimer(&pBAEntry->RECBATimer, REC_BA_SESSION_IDLE_TIMEOUT);
706#endif
707
708 // Set Bitmap flag.
709 pEntry->RXBAbitmap |= (1<<TID);
710 pEntry->BARecWcidArray[TID] = Idx;
711
712 pEntry->BADeclineBitmap &= ~(1<<TID);
713
714 // Set BA session mask in WCID table.
715 RT28XX_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
716
717 DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
718 pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID]));
719 }
720 else
721 {
722 Status = FALSE;
723 DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n",
724 PRINT_MAC(pEntry->Addr), TID));
725 }
726 return(Status);
727}
728
729
730BA_REC_ENTRY *BATableAllocRecEntry(
731 IN PRTMP_ADAPTER pAd,
732 OUT USHORT *Idx)
733{
734 int i;
735 BA_REC_ENTRY *pBAEntry = NULL;
736
737
738 NdisAcquireSpinLock(&pAd->BATabLock);
739
740 if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION)
741 {
742 printk("BA Recipeint Session (%ld) > %d\n", pAd->BATable.numAsRecipient,
743 MAX_BARECI_SESSION);
744 goto done;
745 }
746
747 // reserve idx 0 to identify BAWcidArray[TID] as empty
748 for (i=1; i < MAX_LEN_OF_BA_REC_TABLE; i++)
749 {
750 pBAEntry =&pAd->BATable.BARecEntry[i];
751 if ((pBAEntry->REC_BA_Status == Recipient_NONE))
752 {
753 // get one
754 pAd->BATable.numAsRecipient++;
755 pBAEntry->REC_BA_Status = Recipient_USED;
756 *Idx = i;
757 break;
758 }
759 }
760
761done:
762 NdisReleaseSpinLock(&pAd->BATabLock);
763 return pBAEntry;
764}
765
766BA_ORI_ENTRY *BATableAllocOriEntry(
767 IN PRTMP_ADAPTER pAd,
768 OUT USHORT *Idx)
769{
770 int i;
771 BA_ORI_ENTRY *pBAEntry = NULL;
772
773 NdisAcquireSpinLock(&pAd->BATabLock);
774
775 if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE))
776 {
777 goto done;
778 }
779
780 // reserve idx 0 to identify BAWcidArray[TID] as empty
781 for (i=1; i<MAX_LEN_OF_BA_ORI_TABLE; i++)
782 {
783 pBAEntry =&pAd->BATable.BAOriEntry[i];
784 if ((pBAEntry->ORI_BA_Status == Originator_NONE))
785 {
786 // get one
787 pAd->BATable.numAsOriginator++;
788 pBAEntry->ORI_BA_Status = Originator_USED;
789 pBAEntry->pAdapter = pAd;
790 *Idx = i;
791 break;
792 }
793 }
794
795done:
796 NdisReleaseSpinLock(&pAd->BATabLock);
797 return pBAEntry;
798}
799
800
801VOID BATableFreeOriEntry(
802 IN PRTMP_ADAPTER pAd,
803 IN ULONG Idx)
804{
805 BA_ORI_ENTRY *pBAEntry = NULL;
806 MAC_TABLE_ENTRY *pEntry;
807
808
809 if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
810 return;
811
812 pBAEntry =&pAd->BATable.BAOriEntry[Idx];
813
814 if (pBAEntry->ORI_BA_Status != Originator_NONE)
815 {
816 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
817 pEntry->BAOriWcidArray[pBAEntry->TID] = 0;
818
819
820 NdisAcquireSpinLock(&pAd->BATabLock);
821 if (pBAEntry->ORI_BA_Status == Originator_Done)
822 {
823 pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) ));
824 DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
825 // Erase Bitmap flag.
826 }
827
828 ASSERT(pAd->BATable.numAsOriginator != 0);
829
830 pAd->BATable.numAsOriginator -= 1;
831
832 pBAEntry->ORI_BA_Status = Originator_NONE;
833 pBAEntry->Token = 0;
834 NdisReleaseSpinLock(&pAd->BATabLock);
835 }
836}
837
838
839VOID BATableFreeRecEntry(
840 IN PRTMP_ADAPTER pAd,
841 IN ULONG Idx)
842{
843 BA_REC_ENTRY *pBAEntry = NULL;
844 MAC_TABLE_ENTRY *pEntry;
845
846
847 if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE))
848 return;
849
850 pBAEntry =&pAd->BATable.BARecEntry[Idx];
851
852 if (pBAEntry->REC_BA_Status != Recipient_NONE)
853 {
854 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
855 pEntry->BARecWcidArray[pBAEntry->TID] = 0;
856
857 NdisAcquireSpinLock(&pAd->BATabLock);
858
859 ASSERT(pAd->BATable.numAsRecipient != 0);
860
861 pAd->BATable.numAsRecipient -= 1;
862
863 pBAEntry->REC_BA_Status = Recipient_NONE;
864 NdisReleaseSpinLock(&pAd->BATabLock);
865 }
866}
867
868
869VOID BAOriSessionTearDown(
870 IN OUT PRTMP_ADAPTER pAd,
871 IN UCHAR Wcid,
872 IN UCHAR TID,
873 IN BOOLEAN bPassive,
874 IN BOOLEAN bForceSend)
875{
876 ULONG Idx = 0;
877 BA_ORI_ENTRY *pBAEntry;
878 BOOLEAN Cancelled;
879
880 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
881 {
882 return;
883 }
884
885 //
886 // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
887 //
888 Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID];
889 if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
890 {
891 if (bForceSend == TRUE)
892 {
893 // force send specified TID DelBA
894 MLME_DELBA_REQ_STRUCT DelbaReq;
895 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
896
897 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
898 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
899
900 COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
901 DelbaReq.Wcid = Wcid;
902 DelbaReq.TID = TID;
903 DelbaReq.Initiator = ORIGINATOR;
904#if 1
905 Elem->MsgLen = sizeof(DelbaReq);
906 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
907 MlmeDELBAAction(pAd, Elem);
908 kfree(Elem);
909#else
910 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
911 RT28XX_MLME_HANDLER(pAd);
912#endif
913 }
914
915 return;
916 }
917
918 DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
919
920 pBAEntry = &pAd->BATable.BAOriEntry[Idx];
921 DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status));
922 //
923 // Prepare DelBA action frame and send to the peer.
924 //
925 if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done))
926 {
927 MLME_DELBA_REQ_STRUCT DelbaReq;
928 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
929
930 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
931 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
932
933 COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
934 DelbaReq.Wcid = Wcid;
935 DelbaReq.TID = pBAEntry->TID;
936 DelbaReq.Initiator = ORIGINATOR;
937#if 1
938 Elem->MsgLen = sizeof(DelbaReq);
939 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
940 MlmeDELBAAction(pAd, Elem);
941 kfree(Elem);
942#else
943 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
944 RT28XX_MLME_HANDLER(pAd);
945#endif
946 }
947 RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
948 BATableFreeOriEntry(pAd, Idx);
949
950 if (bPassive)
951 {
952 //BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE);
953 }
954}
955
956VOID BARecSessionTearDown(
957 IN OUT PRTMP_ADAPTER pAd,
958 IN UCHAR Wcid,
959 IN UCHAR TID,
960 IN BOOLEAN bPassive)
961{
962 ULONG Idx = 0;
963 BA_REC_ENTRY *pBAEntry;
964
965 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
966 {
967 return;
968 }
969
970 //
971 // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
972 //
973 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
974 if (Idx == 0)
975 return;
976
977 DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
978
979
980 pBAEntry = &pAd->BATable.BARecEntry[Idx];
981 DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status));
982 //
983 // Prepare DelBA action frame and send to the peer.
984 //
985 if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept))
986 {
987 MLME_DELBA_REQ_STRUCT DelbaReq;
988 BOOLEAN Cancelled;
989 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
990 //ULONG offset;
991 //UINT32 VALUE;
992
993 RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
994
995 //
996 // 1. Send DELBA Action Frame
997 //
998 if (bPassive == FALSE)
999 {
1000 NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
1001 NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
1002
1003 COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
1004 DelbaReq.Wcid = Wcid;
1005 DelbaReq.TID = TID;
1006 DelbaReq.Initiator = RECIPIENT;
1007#if 1
1008 Elem->MsgLen = sizeof(DelbaReq);
1009 NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
1010 MlmeDELBAAction(pAd, Elem);
1011 kfree(Elem);
1012#else
1013 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
1014 RT28XX_MLME_HANDLER(pAd);
1015#endif
1016 }
1017
1018
1019 //
1020 // 2. Free resource of BA session
1021 //
1022 // flush all pending reordering mpdus
1023 ba_refresh_reordering_mpdus(pAd, pBAEntry);
1024
1025 NdisAcquireSpinLock(&pAd->BATabLock);
1026
1027 // Erase Bitmap flag.
1028 pBAEntry->LastIndSeq = RESET_RCV_SEQ;
1029 pBAEntry->BAWinSize = 0;
1030 // Erase Bitmap flag at software mactable
1031 pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID)));
1032 pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
1033
1034 RT28XX_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
1035
1036 NdisReleaseSpinLock(&pAd->BATabLock);
1037
1038 }
1039
1040 BATableFreeRecEntry(pAd, Idx);
1041}
1042
1043VOID BASessionTearDownALL(
1044 IN OUT PRTMP_ADAPTER pAd,
1045 IN UCHAR Wcid)
1046{
1047 int i;
1048
1049 for (i=0; i<NUM_OF_TID; i++)
1050 {
1051 BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE);
1052 BARecSessionTearDown(pAd, Wcid, i, FALSE);
1053 }
1054}
1055
1056
1057/*
1058 ==========================================================================
1059 Description:
1060 Retry sending ADDBA Reqest.
1061
1062 IRQL = DISPATCH_LEVEL
1063
1064 Parametrs:
1065 p8023Header: if this is already 802.3 format, p8023Header is NULL
1066
1067 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
1068 FALSE , then continue indicaterx at this moment.
1069 ==========================================================================
1070 */
1071VOID BAOriSessionSetupTimeout(
1072 IN PVOID SystemSpecific1,
1073 IN PVOID FunctionContext,
1074 IN PVOID SystemSpecific2,
1075 IN PVOID SystemSpecific3)
1076{
1077 BA_ORI_ENTRY *pBAEntry = (BA_ORI_ENTRY *)FunctionContext;
1078 MAC_TABLE_ENTRY *pEntry;
1079 PRTMP_ADAPTER pAd;
1080
1081 if (pBAEntry == NULL)
1082 return;
1083
1084 pAd = pBAEntry->pAdapter;
1085
1086#ifdef CONFIG_STA_SUPPORT
1087 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1088 {
1089 // Do nothing if monitor mode is on
1090 if (MONITOR_ON(pAd))
1091 return;
1092 }
1093#endif // CONFIG_STA_SUPPORT //
1094
1095#ifdef RALINK_ATE
1096 // Nothing to do in ATE mode.
1097 if (ATE_ON(pAd))
1098 return;
1099#endif // RALINK_ATE //
1100
1101 pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
1102
1103 if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) && (pBAEntry->Token < ORI_SESSION_MAX_RETRY))
1104 {
1105 MLME_ADDBA_REQ_STRUCT AddbaReq;
1106
1107 NdisZeroMemory(&AddbaReq, sizeof(AddbaReq));
1108 COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr);
1109 AddbaReq.Wcid = (UCHAR)(pEntry->Aid);
1110 AddbaReq.TID = pBAEntry->TID;
1111 AddbaReq.BaBufSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
1112 AddbaReq.TimeOutValue = 0;
1113 AddbaReq.Token = pBAEntry->Token;
1114 MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq);
1115 RT28XX_MLME_HANDLER(pAd);
1116 DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
1117
1118 pBAEntry->Token++;
1119 RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
1120 }
1121 else
1122 {
1123 BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]);
1124 }
1125}
1126
1127/*
1128 ==========================================================================
1129 Description:
1130 Retry sending ADDBA Reqest.
1131
1132 IRQL = DISPATCH_LEVEL
1133
1134 Parametrs:
1135 p8023Header: if this is already 802.3 format, p8023Header is NULL
1136
1137 Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
1138 FALSE , then continue indicaterx at this moment.
1139 ==========================================================================
1140 */
1141VOID BARecSessionIdleTimeout(
1142 IN PVOID SystemSpecific1,
1143 IN PVOID FunctionContext,
1144 IN PVOID SystemSpecific2,
1145 IN PVOID SystemSpecific3)
1146{
1147
1148 BA_REC_ENTRY *pBAEntry = (BA_REC_ENTRY *)FunctionContext;
1149 PRTMP_ADAPTER pAd;
1150 ULONG Now32;
1151
1152 if (pBAEntry == NULL)
1153 return;
1154
1155 if ((pBAEntry->REC_BA_Status == Recipient_Accept))
1156 {
1157 NdisGetSystemUpTime(&Now32);
1158
1159 if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT)))
1160 {
1161 pAd = pBAEntry->pAdapter;
1162 // flush all pending reordering mpdus
1163 ba_refresh_reordering_mpdus(pAd, pBAEntry);
1164 printk("%ld: REC BA session Timeout\n", Now32);
1165 }
1166 }
1167}
1168
1169
1170VOID PeerAddBAReqAction(
1171 IN PRTMP_ADAPTER pAd,
1172 IN MLME_QUEUE_ELEM *Elem)
1173
1174{
1175 // 7.4.4.1
1176 //ULONG Idx;
1177 UCHAR Status = 1;
1178 UCHAR pAddr[6];
1179 FRAME_ADDBA_RSP ADDframe;
1180 PUCHAR pOutBuffer = NULL;
1181 NDIS_STATUS NStatus;
1182 PFRAME_ADDBA_REQ pAddreqFrame = NULL;
1183 //UCHAR BufSize;
1184 ULONG FrameLen;
1185 PULONG ptemp;
1186 PMAC_TABLE_ENTRY pMacEntry;
1187
1188 DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __FUNCTION__, Elem->Wcid));
1189
1190 //hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen);
1191
1192 //ADDBA Request from unknown peer, ignore this.
1193 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
1194 return;
1195
1196 pMacEntry = &pAd->MacTab.Content[Elem->Wcid];
1197 DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n"));
1198 ptemp = (PULONG)Elem->Msg;
1199 //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)));
1200
1201 if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr))
1202 {
1203
1204 if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry))
1205 {
1206 pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
1207 printk("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid);
1208 if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))
1209 Status = 0;
1210 else
1211 Status = 38; // more parameters have invalid values
1212 }
1213 else
1214 {
1215 Status = 37; // the request has been declined.
1216 }
1217 }
1218
1219 if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)
1220 ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);
1221
1222 pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
1223 // 2. Always send back ADDBA Response
1224 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1225 if (NStatus != NDIS_STATUS_SUCCESS)
1226 {
1227 DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n"));
1228 return;
1229 }
1230
1231 NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP));
1232 // 2-1. Prepare ADDBA Response frame.
1233#ifdef CONFIG_STA_SUPPORT
1234 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1235 {
1236 if (ADHOC_ON(pAd))
1237 ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1238 else
1239#ifdef QOS_DLS_SUPPORT
1240 if (pAd->MacTab.Content[Elem->Wcid].ValidAsDls)
1241 ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1242 else
1243#endif // QOS_DLS_SUPPORT //
1244 ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
1245 }
1246#endif // CONFIG_STA_SUPPORT //
1247 ADDframe.Category = CATEGORY_BA;
1248 ADDframe.Action = ADDBA_RESP;
1249 ADDframe.Token = pAddreqFrame->Token;
1250 // What is the Status code?? need to check.
1251 ADDframe.StatusCode = Status;
1252 ADDframe.BaParm.BAPolicy = IMMED_BA;
1253 ADDframe.BaParm.AMSDUSupported = 0;
1254 ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;
1255 ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
1256 if (ADDframe.BaParm.BufSize == 0)
1257 {
1258 ADDframe.BaParm.BufSize = 64;
1259 }
1260 ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue;
1261
1262 *(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm));
1263 ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode);
1264 ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue);
1265
1266 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1267 sizeof(FRAME_ADDBA_RSP), &ADDframe,
1268 END_OF_ARGS);
1269 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1270 MlmeFreeMemory(pAd, pOutBuffer);
1271
1272 DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __FUNCTION__, Elem->Wcid, ADDframe.BaParm.TID,
1273 ADDframe.BaParm.BufSize));
1274}
1275
1276
1277VOID PeerAddBARspAction(
1278 IN PRTMP_ADAPTER pAd,
1279 IN MLME_QUEUE_ELEM *Elem)
1280
1281{
1282 //UCHAR Idx, i;
1283 //PUCHAR pOutBuffer = NULL;
1284 PFRAME_ADDBA_RSP pFrame = NULL;
1285 //PBA_ORI_ENTRY pBAEntry;
1286
1287 //ADDBA Response from unknown peer, ignore this.
1288 if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
1289 return;
1290
1291 DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __FUNCTION__, Elem->Wcid));
1292
1293 //hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen);
1294
1295 if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen))
1296 {
1297 pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]);
1298
1299 DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode));
1300 switch (pFrame->StatusCode)
1301 {
1302 case 0:
1303 // I want a BAsession with this peer as an originator.
1304 BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame);
1305 break;
1306 default:
1307 // check status == USED ???
1308 BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE);
1309 break;
1310 }
1311 // Rcv Decline StatusCode
1312 if ((pFrame->StatusCode == 37)
1313#ifdef CONFIG_STA_SUPPORT
1314 || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) && (pFrame->StatusCode != 0))
1315#endif // CONFIG_STA_SUPPORT //
1316 )
1317 {
1318 pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->BaParm.TID;
1319 }
1320 }
1321}
1322
1323VOID PeerDelBAAction(
1324 IN PRTMP_ADAPTER pAd,
1325 IN MLME_QUEUE_ELEM *Elem)
1326
1327{
1328 //UCHAR Idx;
1329 //PUCHAR pOutBuffer = NULL;
1330 PFRAME_DELBA_REQ pDelFrame = NULL;
1331
1332 DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __FUNCTION__));
1333 //DELBA Request from unknown peer, ignore this.
1334 if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen))
1335 {
1336 pDelFrame = (PFRAME_DELBA_REQ)(&Elem->Msg[0]);
1337 if (pDelFrame->DelbaParm.Initiator == ORIGINATOR)
1338 {
1339 DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> ORIGINATOR\n"));
1340 BARecSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE);
1341 }
1342 else
1343 {
1344 DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n", pDelFrame->ReasonCode));
1345 //hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen);
1346 BAOriSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE, FALSE);
1347 }
1348 }
1349}
1350
1351
1352BOOLEAN CntlEnqueueForRecv(
1353 IN PRTMP_ADAPTER pAd,
1354 IN ULONG Wcid,
1355 IN ULONG MsgLen,
1356 IN PFRAME_BA_REQ pMsg)
1357{
1358 PFRAME_BA_REQ pFrame = pMsg;
1359 //PRTMP_REORDERBUF pBuffer;
1360 //PRTMP_REORDERBUF pDmaBuf;
1361 PBA_REC_ENTRY pBAEntry;
1362 //BOOLEAN Result;
1363 ULONG Idx;
1364 //UCHAR NumRxPkt;
1365 UCHAR TID;//, i;
1366
1367 TID = (UCHAR)pFrame->BARControl.TID;
1368
1369 DBGPRINT(RT_DEBUG_TRACE, ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __FUNCTION__, Wcid, TID));
1370 //hex_dump("BAR", (PCHAR) pFrame, MsgLen);
1371 // Do nothing if the driver is starting halt state.
1372 // This might happen when timer already been fired before cancel timer with mlmehalt
1373 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
1374 return FALSE;
1375
1376 // First check the size, it MUST not exceed the mlme queue size
1377 if (MsgLen > MGMT_DMA_BUFFER_SIZE)
1378 {
1379 DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
1380 return FALSE;
1381 }
1382 else if (MsgLen != sizeof(FRAME_BA_REQ))
1383 {
1384 DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
1385 return FALSE;
1386 }
1387 else if (MsgLen != sizeof(FRAME_BA_REQ))
1388 {
1389 DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
1390 return FALSE;
1391 }
1392
1393 if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8))
1394 {
1395 // if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search.
1396 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
1397 pBAEntry = &pAd->BATable.BARecEntry[Idx];
1398 }
1399 else
1400 {
1401 return FALSE;
1402 }
1403
1404 DBGPRINT(RT_DEBUG_TRACE, ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq ));
1405
1406 if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
1407 {
1408 //printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq);
1409 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);
1410 pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);
1411 }
1412 //ba_refresh_reordering_mpdus(pAd, pBAEntry);
1413 return TRUE;
1414}
1415
1416/*
1417Description : Send PSMP Action frame If PSMP mode switches.
1418*/
1419VOID SendPSMPAction(
1420 IN PRTMP_ADAPTER pAd,
1421 IN UCHAR Wcid,
1422 IN UCHAR Psmp)
1423{
1424 PUCHAR pOutBuffer = NULL;
1425 NDIS_STATUS NStatus;
1426 //ULONG Idx;
1427 FRAME_PSMP_ACTION Frame;
1428 ULONG FrameLen;
1429
1430 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1431 if (NStatus != NDIS_STATUS_SUCCESS)
1432 {
1433 DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
1434 return;
1435 }
1436#ifdef CONFIG_STA_SUPPORT
1437 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1438 ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
1439#endif // CONFIG_STA_SUPPORT //
1440
1441 Frame.Category = CATEGORY_HT;
1442 Frame.Action = SMPS_ACTION;
1443 switch (Psmp)
1444 {
1445 case MMPS_ENABLE:
1446 Frame.Psmp = 0;
1447 break;
1448 case MMPS_DYNAMIC:
1449 Frame.Psmp = 3;
1450 break;
1451 case MMPS_STATIC:
1452 Frame.Psmp = 1;
1453 break;
1454 }
1455 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1456 sizeof(FRAME_PSMP_ACTION), &Frame,
1457 END_OF_ARGS);
1458 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1459 MlmeFreeMemory(pAd, pOutBuffer);
1460 DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d ) \n", Frame.Psmp));
1461}
1462
1463
1464#define RADIO_MEASUREMENT_REQUEST_ACTION 0
1465
1466typedef struct PACKED
1467{
1468 UCHAR RegulatoryClass;
1469 UCHAR ChannelNumber;
1470 USHORT RandomInterval;
1471 USHORT MeasurementDuration;
1472 UCHAR MeasurementMode;
1473 UCHAR BSSID[MAC_ADDR_LEN];
1474 UCHAR ReportingCondition;
1475 UCHAR Threshold;
1476 UCHAR SSIDIE[2]; // 2 byte
1477} BEACON_REQUEST;
1478
1479typedef struct PACKED
1480{
1481 UCHAR ID;
1482 UCHAR Length;
1483 UCHAR Token;
1484 UCHAR RequestMode;
1485 UCHAR Type;
1486} MEASUREMENT_REQ;
1487
1488
1489
1490
1491void convert_reordering_packet_to_preAMSDU_or_802_3_packet(
1492 IN PRTMP_ADAPTER pAd,
1493 IN RX_BLK *pRxBlk,
1494 IN UCHAR FromWhichBSSID)
1495{
1496 PNDIS_PACKET pRxPkt;
1497 UCHAR Header802_3[LENGTH_802_3];
1498
1499 // 1. get 802.3 Header
1500 // 2. remove LLC
1501 // a. pointer pRxBlk->pData to payload
1502 // b. modify pRxBlk->DataSize
1503
1504#ifdef CONFIG_STA_SUPPORT
1505 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1506 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
1507#endif // CONFIG_STA_SUPPORT //
1508
1509 ASSERT(pRxBlk->pRxPacket);
1510 pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
1511
1512 RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
1513 RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData;
1514 RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize;
1515 RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len;
1516
1517 //
1518 // copy 802.3 header, if necessary
1519 //
1520 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
1521 {
1522
1523#ifdef CONFIG_STA_SUPPORT
1524 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1525 {
1526#ifdef LINUX
1527 NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
1528#endif
1529#ifdef UCOS
1530 NdisMoveMemory(net_pkt_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
1531#endif
1532 }
1533#endif // CONFIG_STA_SUPPORT //
1534 }
1535}
1536
1537
1538#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID) \
1539 do \
1540 { \
1541 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU)) \
1542 { \
1543 Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
1544 } \
1545 else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP)) \
1546 { \
1547 Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
1548 } \
1549 else \
1550 { \
1551 Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
1552 } \
1553 } while (0);
1554
1555
1556
1557static VOID ba_enqueue_reordering_packet(
1558 IN PRTMP_ADAPTER pAd,
1559 IN PBA_REC_ENTRY pBAEntry,
1560 IN RX_BLK *pRxBlk,
1561 IN UCHAR FromWhichBSSID)
1562{
1563 struct reordering_mpdu *mpdu_blk;
1564 UINT16 Sequence = (UINT16) pRxBlk->pHeader->Sequence;
1565
1566 mpdu_blk = ba_mpdu_blk_alloc(pAd);
1567 if (mpdu_blk != NULL)
1568 {
1569 // Write RxD buffer address & allocated buffer length
1570 NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
1571
1572 mpdu_blk->Sequence = Sequence;
1573
1574 mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);
1575
1576 convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, pRxBlk, FromWhichBSSID);
1577
1578 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
1579
1580 //
1581 // it is necessary for reordering packet to record
1582 // which BSS it come from
1583 //
1584 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
1585
1586 mpdu_blk->pPacket = pRxBlk->pRxPacket;
1587
1588 if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) == FALSE)
1589 {
1590 // had been already within reordering list
1591 // don't indicate
1592 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_SUCCESS);
1593 ba_mpdu_blk_free(pAd, mpdu_blk);
1594 }
1595
1596 ASSERT((0<= pBAEntry->list.qlen) && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
1597 NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
1598 }
1599 else
1600 {
1601#if 0
1602 DBGPRINT(RT_DEBUG_ERROR, ("!!! (%d:%d) Can't allocate reordering mpdu blk\n",
1603 blk_count, pBAEntry->list.qlen));
1604#else
1605 DBGPRINT(RT_DEBUG_ERROR, ("!!! (%d) Can't allocate reordering mpdu blk\n",
1606 pBAEntry->list.qlen));
1607#endif
1608 /*
1609 * flush all pending reordering mpdus
1610 * and receving mpdu to upper layer
1611 * make tcp/ip to take care reordering mechanism
1612 */
1613 //ba_refresh_reordering_mpdus(pAd, pBAEntry);
1614 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
1615
1616 pBAEntry->LastIndSeq = Sequence;
1617 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1618 }
1619}
1620
1621
1622/*
1623 ==========================================================================
1624 Description:
1625 Indicate this packet to upper layer or put it into reordering buffer
1626
1627 Parametrs:
1628 pRxBlk : carry necessary packet info 802.11 format
1629 FromWhichBSSID : the packet received from which BSS
1630
1631 Return :
1632 none
1633
1634 Note :
1635 the packet queued into reordering buffer need to cover to 802.3 format
1636 or pre_AMSDU format
1637 ==========================================================================
1638 */
1639
1640VOID Indicate_AMPDU_Packet(
1641 IN PRTMP_ADAPTER pAd,
1642 IN RX_BLK *pRxBlk,
1643 IN UCHAR FromWhichBSSID)
1644{
1645 USHORT Idx;
1646 PBA_REC_ENTRY pBAEntry = NULL;
1647 UINT16 Sequence = pRxBlk->pHeader->Sequence;
1648 ULONG Now32;
1649 UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
1650 UCHAR TID = pRxBlk->pRxWI->TID;
1651
1652
1653 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) && (pRxBlk->DataSize > MAX_RX_PKT_LEN))
1654 {
1655#if 0 // sample take off, no use
1656 static int err_size;
1657
1658 err_size++;
1659 if (err_size > 20) {
1660 printk("AMPDU DataSize = %d\n", pRxBlk->DataSize);
1661 hex_dump("802.11 Header", (UCHAR *)pRxBlk->pHeader, 24);
1662 hex_dump("Payload", pRxBlk->pData, 64);
1663 err_size = 0;
1664 }
1665#endif
1666 // release packet
1667 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1668 return;
1669 }
1670
1671
1672#if 0 // test
1673 /* Rec BA Session had been torn down */
1674 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1675 return;
1676#endif
1677
1678 if (Wcid < MAX_LEN_OF_MAC_TABLE)
1679 {
1680 Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
1681 if (Idx == 0)
1682 {
1683 /* Rec BA Session had been torn down */
1684 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1685 return;
1686 }
1687 pBAEntry = &pAd->BATable.BARecEntry[Idx];
1688 }
1689 else
1690 {
1691 // impossible !!!
1692 ASSERT(0);
1693 // release packet
1694 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1695 return;
1696 }
1697
1698 ASSERT(pBAEntry);
1699
1700 // update last rx time
1701 NdisGetSystemUpTime(&Now32);
1702
1703 pBAEntry->rcvSeq = Sequence;
1704
1705
1706 ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
1707 pBAEntry->LastIndSeqAtTimer = Now32;
1708
1709 //
1710 // Reset Last Indicate Sequence
1711 //
1712 if (pBAEntry->LastIndSeq == RESET_RCV_SEQ)
1713 {
1714 ASSERT((pBAEntry->list.qlen == 0) && (pBAEntry->list.next == NULL));
1715
1716 // reset rcv sequence of BA session
1717 pBAEntry->LastIndSeq = Sequence;
1718 pBAEntry->LastIndSeqAtTimer = Now32;
1719 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1720 return;
1721 }
1722
1723
1724 //
1725 // I. Check if in order.
1726 //
1727 if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
1728 {
1729 USHORT LastIndSeq;
1730
1731 pBAEntry->LastIndSeq = Sequence;
1732 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1733 LastIndSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
1734 if (LastIndSeq != RESET_RCV_SEQ)
1735 {
1736 pBAEntry->LastIndSeq = LastIndSeq;
1737 }
1738 pBAEntry->LastIndSeqAtTimer = Now32;
1739 }
1740 //
1741 // II. Drop Duplicated Packet
1742 //
1743 else if (Sequence == pBAEntry->LastIndSeq)
1744 {
1745
1746 // drop and release packet
1747 pBAEntry->nDropPacket++;
1748 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1749 }
1750 //
1751 // III. Drop Old Received Packet
1752 //
1753 else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
1754 {
1755
1756 // drop and release packet
1757 pBAEntry->nDropPacket++;
1758 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1759 }
1760 //
1761 // IV. Receive Sequence within Window Size
1762 //
1763 else if (SEQ_SMALLER(Sequence, (((pBAEntry->LastIndSeq+pBAEntry->BAWinSize+1)) & MAXSEQ), MAXSEQ))
1764 {
1765 ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
1766 }
1767 //
1768 // V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer
1769 //
1770 else
1771 {
1772#if 0
1773 ba_refresh_reordering_mpdus(pAd, pBAEntry);
1774 INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
1775#else
1776 LONG WinStartSeq, TmpSeq;
1777
1778
1779 TmpSeq = Sequence - (pBAEntry->BAWinSize) -1;
1780 if (TmpSeq < 0)
1781 {
1782 TmpSeq = (MAXSEQ+1) + TmpSeq;
1783 }
1784 WinStartSeq = (TmpSeq+1) & MAXSEQ;
1785 ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);
1786 pBAEntry->LastIndSeq = WinStartSeq; //TmpSeq;
1787
1788 pBAEntry->LastIndSeqAtTimer = Now32;
1789
1790 ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
1791
1792 TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
1793 if (TmpSeq != RESET_RCV_SEQ)
1794 {
1795 pBAEntry->LastIndSeq = TmpSeq;
1796 }
1797#endif
1798 }
1799}
1800
1801#endif // DOT11_N_SUPPORT //
1802
diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c
new file mode 100644
index 00000000000..292d34b31e1
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_data.c
@@ -0,0 +1,3469 @@
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};
70UCHAR default_sta_aifsn[]={3,7,2,2};
71
72UCHAR 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};
73
74
75/*
76 ========================================================================
77
78 Routine Description:
79 API for MLME to transmit management frame to AP (BSS Mode)
80 or station (IBSS Mode)
81
82 Arguments:
83 pAd Pointer to our adapter
84 pData Pointer to the outgoing 802.11 frame
85 Length Size of outgoing management frame
86
87 Return Value:
88 NDIS_STATUS_FAILURE
89 NDIS_STATUS_PENDING
90 NDIS_STATUS_SUCCESS
91
92 IRQL = PASSIVE_LEVEL
93 IRQL = DISPATCH_LEVEL
94
95 Note:
96
97 ========================================================================
98*/
99NDIS_STATUS MiniportMMRequest(
100 IN PRTMP_ADAPTER pAd,
101 IN UCHAR QueIdx,
102 IN PUCHAR pData,
103 IN UINT Length)
104{
105 PNDIS_PACKET pPacket;
106 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
107 ULONG FreeNum;
108#ifdef RT2860
109 unsigned long IrqFlags = 0;
110#endif // RT2860 //
111 UCHAR IrqState;
112 UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
113
114 ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
115
116 QueIdx=3;
117
118 // 2860C use Tx Ring
119
120 IrqState = pAd->irq_disabled;
121#ifdef RT2860
122 if ((pAd->MACVersion == 0x28600100) && (!IrqState))
123 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
124#endif // RT2860 //
125
126 do
127 {
128 // Reset is in progress, stop immediately
129 if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
130 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
131 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
132 {
133 Status = NDIS_STATUS_FAILURE;
134 break;
135 }
136
137 // Check Free priority queue
138 // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
139
140 // 2860C use Tx Ring
141 if (pAd->MACVersion == 0x28600100)
142 {
143 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
144 }
145 else
146 {
147 FreeNum = GET_MGMTRING_FREENO(pAd);
148 }
149
150 if ((FreeNum > 0))
151 {
152 // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
153 NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
154 Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
155 if (Status != NDIS_STATUS_SUCCESS)
156 {
157 DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
158 break;
159 }
160
161 //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
162 //pAd->CommonCfg.MlmeRate = RATE_2;
163
164
165 Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
166 if (Status != NDIS_STATUS_SUCCESS)
167 RTMPFreeNdisPacket(pAd, pPacket);
168 }
169 else
170 {
171 pAd->RalinkCounters.MgmtRingFullCount++;
172 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
173 QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
174 }
175
176 } while (FALSE);
177
178#ifdef RT2860
179 // 2860C use Tx Ring
180 if ((pAd->MACVersion == 0x28600100) && (!IrqState))
181 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
182#endif // RT2860 //
183
184 return Status;
185}
186
187
188#ifdef RT2860
189NDIS_STATUS MiniportMMRequestUnlock(
190 IN PRTMP_ADAPTER pAd,
191 IN UCHAR QueIdx,
192 IN PUCHAR pData,
193 IN UINT Length)
194{
195 PNDIS_PACKET pPacket;
196 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
197 ULONG FreeNum;
198 TXWI_STRUC TXWI;
199 ULONG SW_TX_IDX;
200 PTXD_STRUC pTxD;
201
202 QueIdx = 3;
203 ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
204
205 do
206 {
207 // Reset is in progress, stop immediately
208 if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
209 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
210 !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
211 {
212 Status = NDIS_STATUS_FAILURE;
213 break;
214 }
215
216 // Check Free priority queue
217 // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
218 // 2860C use Tx Ring
219 if (pAd->MACVersion == 0x28600100)
220 {
221 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
222 SW_TX_IDX = pAd->TxRing[QueIdx].TxCpuIdx;
223 pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SW_TX_IDX].AllocVa;
224 }
225 else
226 {
227 FreeNum = GET_MGMTRING_FREENO(pAd);
228 SW_TX_IDX = pAd->MgmtRing.TxCpuIdx;
229 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SW_TX_IDX].AllocVa;
230 }
231 if ((FreeNum > 0))
232 {
233 NdisZeroMemory(&TXWI, TXWI_SIZE);
234 Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&TXWI, TXWI_SIZE, pData, Length);
235 if (Status != NDIS_STATUS_SUCCESS)
236 {
237 DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
238 break;
239 }
240
241 Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
242 if (Status != NDIS_STATUS_SUCCESS)
243 RTMPFreeNdisPacket(pAd, pPacket);
244 }
245 else
246 {
247 pAd->RalinkCounters.MgmtRingFullCount++;
248 DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing\n", QueIdx));
249 }
250
251 } while (FALSE);
252
253
254 return Status;
255}
256#endif // RT2860 //
257
258
259/*
260 ========================================================================
261
262 Routine Description:
263 Copy frame from waiting queue into relative ring buffer and set
264 appropriate ASIC register to kick hardware transmit function
265
266 Arguments:
267 pAd Pointer to our adapter
268 pBuffer Pointer to memory of outgoing frame
269 Length Size of outgoing management frame
270
271 Return Value:
272 NDIS_STATUS_FAILURE
273 NDIS_STATUS_PENDING
274 NDIS_STATUS_SUCCESS
275
276 IRQL = PASSIVE_LEVEL
277 IRQL = DISPATCH_LEVEL
278
279 Note:
280
281 ========================================================================
282*/
283NDIS_STATUS MlmeHardTransmit(
284 IN PRTMP_ADAPTER pAd,
285 IN UCHAR QueIdx,
286 IN PNDIS_PACKET pPacket)
287{
288 if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
289 {
290 return NDIS_STATUS_FAILURE;
291 }
292
293#ifdef RT2860
294 if ( pAd->MACVersion == 0x28600100 )
295 return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
296 else
297#endif // RT2860 //
298 return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
299
300}
301
302
303#ifdef RT2860
304NDIS_STATUS MlmeHardTransmitTxRing(
305 IN PRTMP_ADAPTER pAd,
306 IN UCHAR QueIdx,
307 IN PNDIS_PACKET pPacket)
308{
309 PACKET_INFO PacketInfo;
310 PUCHAR pSrcBufVA;
311 UINT SrcBufLen;
312 PTXD_STRUC pTxD;
313#ifdef RT_BIG_ENDIAN
314 PTXD_STRUC pDestTxD;
315 TXD_STRUC TxD;
316#endif
317 PHEADER_802_11 pHeader_802_11;
318 BOOLEAN bAckRequired, bInsertTimestamp;
319 ULONG SrcBufPA;
320 UCHAR MlmeRate;
321 ULONG SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
322 PTXWI_STRUC pFirstTxWI;
323 ULONG FreeNum;
324 MAC_TABLE_ENTRY *pMacEntry = NULL;
325
326
327 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
328
329 if (pSrcBufVA == NULL)
330 {
331 // The buffer shouldn't be NULL
332 return NDIS_STATUS_FAILURE;
333 }
334
335 // Make sure MGMT ring resource won't be used by other threads
336 //NdisAcquireSpinLock(&pAd->TxRingLock);
337
338 FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
339
340 if (FreeNum == 0)
341 {
342 //NdisReleaseSpinLock(&pAd->TxRingLock);
343 return NDIS_STATUS_FAILURE;
344 }
345
346 SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
347
348#ifndef RT_BIG_ENDIAN
349 pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
350#else
351 pDestTxD = (PTXD_STRUC)pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
352 TxD = *pDestTxD;
353 pTxD = &TxD;
354 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
355#endif
356
357 if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket)
358 {
359 printk("MlmeHardTransmit Error\n");
360 return NDIS_STATUS_FAILURE;
361 }
362
363
364#ifdef CONFIG_STA_SUPPORT
365 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
366 {
367 // outgoing frame always wakeup PHY to prevent frame lost
368 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
369 AsicForceWakeup(pAd, TRUE);
370 }
371#endif // CONFIG_STA_SUPPORT //
372 pFirstTxWI =(PTXWI_STRUC)pSrcBufVA;
373
374 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE);
375 if (pHeader_802_11->Addr1[0] & 0x01)
376 {
377 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
378 }
379 else
380 {
381 MlmeRate = pAd->CommonCfg.MlmeRate;
382 }
383
384 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
385 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
386 {
387 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
388 }
389
390 // Verify Mlme rate for a / g bands.
391 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
392 MlmeRate = RATE_6;
393
394 //
395 // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
396 // Snice it's been set to 0 while on MgtMacHeaderInit
397 // By the way this will cause frame to be send on PWR_SAVE failed.
398 //
399 //
400 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
401#ifdef CONFIG_STA_SUPPORT
402 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
403 if (pHeader_802_11->FC.Type != BTYPE_DATA)
404 {
405 if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
406 {
407 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
408 }
409 else
410 {
411 pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave;
412 }
413 }
414#endif // CONFIG_STA_SUPPORT //
415
416 bInsertTimestamp = FALSE;
417 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
418 {
419 bAckRequired = FALSE;
420 }
421 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
422 {
423 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
424 {
425 bAckRequired = FALSE;
426 pHeader_802_11->Duration = 0;
427 }
428 else
429 {
430 bAckRequired = TRUE;
431 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
432 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
433 {
434 bInsertTimestamp = TRUE;
435 }
436 }
437 }
438 pHeader_802_11->Sequence = pAd->Sequence++;
439 if (pAd->Sequence > 0xfff)
440 pAd->Sequence = 0;
441 // Before radar detection done, mgmt frame can not be sent but probe req
442 // Because we need to use probe req to trigger driver to send probe req in passive scan
443 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
444 && (pAd->CommonCfg.bIEEE80211H == 1)
445 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
446 {
447 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
448 return (NDIS_STATUS_FAILURE);
449 }
450
451#ifdef RT_BIG_ENDIAN
452 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
453#endif
454 //
455 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
456 // should always has only one ohysical buffer, and the whole frame size equals
457 // to the first scatter buffer size
458 //
459
460 // Initialize TX Descriptor
461 // For inter-frame gap, the number is for this frame and next frame
462 // For MLME rate, we will fix as 2Mb to match other vendor's implement
463
464// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
465 // Only beacon use Nseq=TRUE. So here we use Nseq=FALSE.
466 if (pMacEntry == NULL)
467 {
468 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
469 0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
470 }
471 else
472 {
473 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
474 bInsertTimestamp, FALSE, bAckRequired, FALSE,
475 0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
476 pMacEntry->MaxHTPhyMode.field.MCS, 0,
477 (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
478 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
479 }
480
481 pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
482 pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
483#ifdef RT_BIG_ENDIAN
484 RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
485#endif
486 SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
487
488
489 RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
490 pTxD->LastSec0 = 1;
491 pTxD->LastSec1 = 1;
492 pTxD->SDLen0 = SrcBufLen;
493 pTxD->SDLen1 = 0;
494 pTxD->SDPtr0 = SrcBufPA;
495 pTxD->DMADONE = 0;
496
497#ifdef RT_BIG_ENDIAN
498 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
499 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
500#endif
501
502 pAd->RalinkCounters.KickTxCount++;
503 pAd->RalinkCounters.OneSecTxDoneCount++;
504
505 // Increase TX_CTX_IDX, but write to register later.
506 INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
507
508 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10, pAd->TxRing[QueIdx].TxCpuIdx);
509
510 return NDIS_STATUS_SUCCESS;
511}
512#endif // RT2860 //
513
514
515NDIS_STATUS MlmeHardTransmitMgmtRing(
516 IN PRTMP_ADAPTER pAd,
517 IN UCHAR QueIdx,
518 IN PNDIS_PACKET pPacket)
519{
520 PACKET_INFO PacketInfo;
521 PUCHAR pSrcBufVA;
522 UINT SrcBufLen;
523 PHEADER_802_11 pHeader_802_11;
524 BOOLEAN bAckRequired, bInsertTimestamp;
525 UCHAR MlmeRate;
526 PTXWI_STRUC pFirstTxWI;
527 MAC_TABLE_ENTRY *pMacEntry = NULL;
528
529 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
530 RTMP_SEM_LOCK(&pAd->MgmtRingLock);
531
532
533 if (pSrcBufVA == NULL)
534 {
535 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
536 return NDIS_STATUS_FAILURE;
537 }
538
539#ifdef CONFIG_STA_SUPPORT
540 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
541 {
542 // outgoing frame always wakeup PHY to prevent frame lost
543 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
544 AsicForceWakeup(pAd, TRUE);
545 }
546#endif // CONFIG_STA_SUPPORT //
547
548 pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE);
549 pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
550
551 if (pHeader_802_11->Addr1[0] & 0x01)
552 {
553 MlmeRate = pAd->CommonCfg.BasicMlmeRate;
554 }
555 else
556 {
557 MlmeRate = pAd->CommonCfg.MlmeRate;
558 }
559
560 // Verify Mlme rate for a / g bands.
561 if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
562 MlmeRate = RATE_6;
563
564 if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
565 (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
566 {
567 pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
568 }
569
570#ifdef CONFIG_STA_SUPPORT
571 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
572 {
573 // Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
574 if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
575#ifdef DOT11_N_SUPPORT
576 || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
577#endif // DOT11_N_SUPPORT //
578 )
579 {
580 if (pAd->LatchRfRegs.Channel > 14)
581 pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
582 else
583 pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
584 }
585 }
586#endif // CONFIG_STA_SUPPORT //
587
588 //
589 // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
590 // Snice it's been set to 0 while on MgtMacHeaderInit
591 // By the way this will cause frame to be send on PWR_SAVE failed.
592 //
593 // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
594 //
595 // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
596#ifdef CONFIG_STA_SUPPORT
597 // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
598 if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
599 {
600 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
601 (pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
602 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
603 else
604 pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
605 }
606#endif // CONFIG_STA_SUPPORT //
607
608 bInsertTimestamp = FALSE;
609 if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
610 {
611#ifdef CONFIG_STA_SUPPORT
612 //Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue.
613 if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
614 {
615 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
616 }
617#endif // CONFIG_STA_SUPPORT //
618 bAckRequired = FALSE;
619 }
620 else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
621 {
622 if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
623 {
624 bAckRequired = FALSE;
625 pHeader_802_11->Duration = 0;
626 }
627 else
628 {
629 bAckRequired = TRUE;
630 pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
631 if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
632 {
633 bInsertTimestamp = TRUE;
634 }
635 }
636 }
637
638 pHeader_802_11->Sequence = pAd->Sequence++;
639 if (pAd->Sequence >0xfff)
640 pAd->Sequence = 0;
641
642 // Before radar detection done, mgmt frame can not be sent but probe req
643 // Because we need to use probe req to trigger driver to send probe req in passive scan
644 if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
645 && (pAd->CommonCfg.bIEEE80211H == 1)
646 && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
647 {
648 DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
649 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
650 return (NDIS_STATUS_FAILURE);
651 }
652
653#ifdef RT_BIG_ENDIAN
654 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
655#endif
656
657 //
658 // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
659 // should always has only one ohysical buffer, and the whole frame size equals
660 // to the first scatter buffer size
661 //
662
663 // Initialize TX Descriptor
664 // For inter-frame gap, the number is for this frame and next frame
665 // For MLME rate, we will fix as 2Mb to match other vendor's implement
666
667// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
668 if (pMacEntry == NULL)
669 {
670 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
671 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
672 }
673 else
674 {
675 RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
676 bInsertTimestamp, FALSE, bAckRequired, FALSE,
677 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
678 pMacEntry->MaxHTPhyMode.field.MCS, 0,
679 (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
680 IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
681 }
682
683#ifdef RT_BIG_ENDIAN
684 RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
685#endif
686
687 // Now do hardware-depened kick out.
688 HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
689
690 // Make sure to release MGMT ring resource
691 RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
692 return NDIS_STATUS_SUCCESS;
693}
694
695
696/********************************************************************************
697
698 New DeQueue Procedures.
699
700 ********************************************************************************/
701
702#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \
703 do{ \
704 if (bIntContext == FALSE) \
705 RTMP_IRQ_LOCK((lock), IrqFlags); \
706 }while(0)
707
708#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \
709 do{ \
710 if (bIntContext == FALSE) \
711 RTMP_IRQ_UNLOCK((lock), IrqFlags); \
712 }while(0)
713
714/*
715 ========================================================================
716 Tx Path design algorithm:
717 Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
718 Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
719 Classification Rule=>
720 Multicast: (*addr1 & 0x01) == 0x01
721 Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
722 11N Rate : If peer support HT
723 (1).AMPDU -- If TXBA is negotiated.
724 (2).AMSDU -- If AMSDU is capable for both peer and ourself.
725 *). AMSDU can embedded in a AMPDU, but now we didn't support it.
726 (3).Normal -- Other packets which send as 11n rate.
727
728 B/G Rate : If peer is b/g only.
729 (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
730 (2).Normal -- Other packets which send as b/g rate.
731 Fragment:
732 The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
733
734 Classified Packet Handle Rule=>
735 Multicast:
736 No ACK, //pTxBlk->bAckRequired = FALSE;
737 No WMM, //pTxBlk->bWMM = FALSE;
738 No piggyback, //pTxBlk->bPiggyBack = FALSE;
739 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
740 Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use
741 the same policy to handle it.
742 Force LowRate, //pTxBlk->bForceLowRate = TRUE;
743
744 11N Rate :
745 No piggyback, //pTxBlk->bPiggyBack = FALSE;
746
747 (1).AMSDU
748 pTxBlk->bWMM = TRUE;
749 (2).AMPDU
750 pTxBlk->bWMM = TRUE;
751 (3).Normal
752
753 B/G Rate :
754 (1).ARALINK
755
756 (2).Normal
757 ========================================================================
758*/
759static UCHAR TxPktClassification(
760 IN RTMP_ADAPTER *pAd,
761 IN PNDIS_PACKET pPacket)
762{
763 UCHAR TxFrameType = TX_UNKOWN_FRAME;
764 UCHAR Wcid;
765 MAC_TABLE_ENTRY *pMacEntry = NULL;
766#ifdef DOT11_N_SUPPORT
767 BOOLEAN bHTRate = FALSE;
768#endif // DOT11_N_SUPPORT //
769
770 Wcid = RTMP_GET_PACKET_WCID(pPacket);
771 if (Wcid == MCAST_WCID)
772 { // Handle for RA is Broadcast/Multicast Address.
773 return TX_MCAST_FRAME;
774 }
775
776 // Handle for unicast packets
777 pMacEntry = &pAd->MacTab.Content[Wcid];
778 if (RTMP_GET_PACKET_LOWRATE(pPacket))
779 { // It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
780 TxFrameType = TX_LEGACY_FRAME;
781 }
782#ifdef DOT11_N_SUPPORT
783 else if (IS_HT_RATE(pMacEntry))
784 { // it's a 11n capable packet
785
786 // Depends on HTPhyMode to check if the peer support the HTRate transmission.
787 // Currently didn't support A-MSDU embedded in A-MPDU
788 bHTRate = TRUE;
789 if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
790 TxFrameType = TX_LEGACY_FRAME;
791#ifdef UAPSD_AP_SUPPORT
792 else if (RTMP_GET_PACKET_EOSP(pPacket))
793 TxFrameType = TX_LEGACY_FRAME;
794#endif // UAPSD_AP_SUPPORT //
795 else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
796 return TX_AMPDU_FRAME;
797 else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
798 return TX_AMSDU_FRAME;
799 else
800 TxFrameType = TX_LEGACY_FRAME;
801 }
802#endif // DOT11_N_SUPPORT //
803 else
804 { // it's a legacy b/g packet.
805 if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
806 (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
807 (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
808 { // if peer support Ralink Aggregation, we use it.
809 TxFrameType = TX_RALINK_FRAME;
810 }
811 else
812 {
813 TxFrameType = TX_LEGACY_FRAME;
814 }
815 }
816
817 // Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
818 if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
819 TxFrameType = TX_FRAG_FRAME;
820
821 return TxFrameType;
822}
823
824
825BOOLEAN RTMP_FillTxBlkInfo(
826 IN RTMP_ADAPTER *pAd,
827 IN TX_BLK *pTxBlk)
828{
829 PACKET_INFO PacketInfo;
830 PNDIS_PACKET pPacket;
831 PMAC_TABLE_ENTRY pMacEntry = NULL;
832
833 pPacket = pTxBlk->pPacket;
834 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
835
836 pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
837 pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
838 pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
839 pTxBlk->FrameGap = IFS_HTTXOP; // ASIC determine Frame Gap
840
841 if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
842 TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
843 else
844 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
845
846 // Default to clear this flag
847 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
848
849
850 if (pTxBlk->Wcid == MCAST_WCID)
851 {
852 pTxBlk->pMacEntry = NULL;
853 {
854#ifdef MCAST_RATE_SPECIFIC
855 PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
856 if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
857 pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
858 else
859#endif // MCAST_RATE_SPECIFIC //
860 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
861 }
862
863 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); // AckRequired = FALSE, when broadcast packet in Adhoc mode.
864 //TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
865 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
866 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
867 if (RTMP_GET_PACKET_MOREDATA(pPacket))
868 {
869 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
870 }
871
872 }
873 else
874 {
875 pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
876 pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
877
878 pMacEntry = pTxBlk->pMacEntry;
879
880
881 // For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
882 if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
883 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
884 else
885 TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
886
887 {
888
889#ifdef CONFIG_STA_SUPPORT
890 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
891 {
892
893 // If support WMM, enable it.
894 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
895 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
896 }
897#endif // CONFIG_STA_SUPPORT //
898 }
899
900 if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
901 {
902 if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
903 ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
904 { // Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
905 pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
906#ifdef DOT11_N_SUPPORT
907 // Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
908 if (IS_HT_STA(pTxBlk->pMacEntry) &&
909 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
910 ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
911 {
912 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
913 TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
914 }
915#endif // DOT11_N_SUPPORT //
916 }
917
918#ifdef DOT11_N_SUPPORT
919 if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
920 (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
921 { // Currently piggy-back only support when peer is operate in b/g mode.
922 TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
923 }
924#endif // DOT11_N_SUPPORT //
925
926 if (RTMP_GET_PACKET_MOREDATA(pPacket))
927 {
928 TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
929 }
930#ifdef UAPSD_AP_SUPPORT
931 if (RTMP_GET_PACKET_EOSP(pPacket))
932 {
933 TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
934 }
935#endif // UAPSD_AP_SUPPORT //
936 }
937 else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
938 {
939 TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
940 }
941
942 pMacEntry->DebugTxCount++;
943 }
944
945 return TRUE;
946
947FillTxBlkErr:
948 return FALSE;
949}
950
951
952BOOLEAN CanDoAggregateTransmit(
953 IN RTMP_ADAPTER *pAd,
954 IN NDIS_PACKET *pPacket,
955 IN TX_BLK *pTxBlk)
956{
957
958 //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
959
960 if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
961 return FALSE;
962
963 if (RTMP_GET_PACKET_DHCP(pPacket) ||
964 RTMP_GET_PACKET_EAPOL(pPacket) ||
965 RTMP_GET_PACKET_WAI(pPacket))
966 return FALSE;
967
968 if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
969 ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
970 { // For AMSDU, allow the packets with total length < max-amsdu size
971 return FALSE;
972 }
973
974 if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
975 (pTxBlk->TxPacketList.Number == 2))
976 { // For RALINK-Aggregation, allow two frames in one batch.
977 return FALSE;
978 }
979
980#ifdef CONFIG_STA_SUPPORT
981 if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
982 return TRUE;
983 else
984#endif // CONFIG_STA_SUPPORT //
985 return FALSE;
986
987}
988
989
990/*
991 ========================================================================
992
993 Routine Description:
994 To do the enqueue operation and extract the first item of waiting
995 list. If a number of available shared memory segments could meet
996 the request of extracted item, the extracted item will be fragmented
997 into shared memory segments.
998
999 Arguments:
1000 pAd Pointer to our adapter
1001 pQueue Pointer to Waiting Queue
1002
1003 Return Value:
1004 None
1005
1006 IRQL = DISPATCH_LEVEL
1007
1008 Note:
1009
1010 ========================================================================
1011*/
1012VOID RTMPDeQueuePacket(
1013 IN PRTMP_ADAPTER pAd,
1014 IN BOOLEAN bIntContext,
1015 IN UCHAR QIdx, /* BulkOutPipeId */
1016 IN UCHAR Max_Tx_Packets)
1017{
1018 PQUEUE_ENTRY pEntry = NULL;
1019 PNDIS_PACKET pPacket;
1020 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1021 UCHAR Count=0;
1022 PQUEUE_HEADER pQueue;
1023 ULONG FreeNumber[NUM_OF_TX_RING];
1024 UCHAR QueIdx, sQIdx, eQIdx;
1025 unsigned long IrqFlags = 0;
1026 BOOLEAN hasTxDesc = FALSE;
1027 TX_BLK TxBlk;
1028 TX_BLK *pTxBlk;
1029
1030#ifdef DBG_DIAGNOSE
1031 BOOLEAN firstRound;
1032 RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct;
1033#endif
1034
1035
1036 if (QIdx == NUM_OF_TX_RING)
1037 {
1038 sQIdx = 0;
1039 eQIdx = 3; // 4 ACs, start from 0.
1040 }
1041 else
1042 {
1043 sQIdx = eQIdx = QIdx;
1044 }
1045
1046 for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
1047 {
1048 Count=0;
1049
1050 RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
1051
1052#ifdef DBG_DIAGNOSE
1053 firstRound = ((QueIdx == 0) ? TRUE : FALSE);
1054#endif // DBG_DIAGNOSE //
1055
1056 while (1)
1057 {
1058 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
1059 fRTMP_ADAPTER_RADIO_OFF |
1060 fRTMP_ADAPTER_RESET_IN_PROGRESS |
1061 fRTMP_ADAPTER_HALT_IN_PROGRESS |
1062 fRTMP_ADAPTER_NIC_NOT_EXIST))))
1063 {
1064 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
1065 return;
1066 }
1067
1068 if (Count >= Max_Tx_Packets)
1069 break;
1070
1071 DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1072 if (&pAd->TxSwQueue[QueIdx] == NULL)
1073 {
1074#ifdef DBG_DIAGNOSE
1075 if (firstRound == TRUE)
1076 pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
1077#endif // DBG_DIAGNOSE //
1078 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1079 break;
1080 }
1081
1082#ifdef RT2860
1083 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
1084
1085#ifdef DBG_DIAGNOSE
1086 if (firstRound == TRUE)
1087 {
1088 UCHAR txDescNumLevel, txSwQNumLevel;
1089
1090 txDescNumLevel = (TX_RING_SIZE - FreeNumber[QueIdx]); // Number of occupied hw desc.
1091 txDescNumLevel = ((txDescNumLevel <=15) ? txDescNumLevel : 15);
1092 pDiagStruct->TxDescCnt[pDiagStruct->ArrayCurIdx][txDescNumLevel]++;
1093
1094 txSwQNumLevel = ((pAd->TxSwQueue[QueIdx].Number <=7) ? pAd->TxSwQueue[QueIdx].Number : 8);
1095 pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][txSwQNumLevel]++;
1096
1097 firstRound = FALSE;
1098 }
1099#endif // DBG_DIAGNOSE //
1100
1101 if (FreeNumber[QueIdx] <= 5)
1102 {
1103 // free Tx(QueIdx) resources
1104 RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
1105 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
1106 }
1107#endif // RT2860 //
1108
1109 // probe the Queue Head
1110 pQueue = &pAd->TxSwQueue[QueIdx];
1111 if ((pEntry = pQueue->Head) == NULL)
1112 {
1113 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1114 break;
1115 }
1116
1117 pTxBlk = &TxBlk;
1118 NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
1119 pTxBlk->QueIdx = QueIdx;
1120
1121 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
1122
1123 // Early check to make sure we have enoguh Tx Resource.
1124 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
1125 if (!hasTxDesc)
1126 {
1127 pAd->PrivateInfo.TxRingFullCnt++;
1128
1129 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1130
1131 break;
1132 }
1133
1134 pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
1135 pEntry = RemoveHeadQueue(pQueue);
1136 pTxBlk->TotalFrameNum++;
1137 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
1138 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
1139 pTxBlk->pPacket = pPacket;
1140 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
1141
1142 if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
1143 {
1144 // Enhance SW Aggregation Mechanism
1145 if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
1146 {
1147 InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
1148 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1149 break;
1150 }
1151
1152 do{
1153 if((pEntry = pQueue->Head) == NULL)
1154 break;
1155
1156 // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
1157 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
1158 FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
1159 hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
1160 if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
1161 break;
1162
1163 //Remove the packet from the TxSwQueue and insert into pTxBlk
1164 pEntry = RemoveHeadQueue(pQueue);
1165 ASSERT(pEntry);
1166 pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
1167 pTxBlk->TotalFrameNum++;
1168 pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
1169 pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
1170 InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
1171 }while(1);
1172
1173 if (pTxBlk->TxPacketList.Number == 1)
1174 pTxBlk->TxFrameType = TX_LEGACY_FRAME;
1175 }
1176
1177
1178 Count += pTxBlk->TxPacketList.Number;
1179
1180 // Do HardTransmit now.
1181#ifdef CONFIG_STA_SUPPORT
1182 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1183 Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
1184#endif // CONFIG_STA_SUPPORT //
1185
1186#ifdef RT2860
1187 DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
1188 // static rate also need NICUpdateFifoStaCounters() function.
1189 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1190 NICUpdateFifoStaCounters(pAd);
1191#endif // RT2860 //
1192 }
1193
1194 RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
1195
1196
1197#ifdef BLOCK_NET_IF
1198 if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE)
1199 && (pAd->TxSwQueue[QueIdx].Number < 1))
1200 {
1201 releaseNetIf(&pAd->blockQueueTab[QueIdx]);
1202 }
1203#endif // BLOCK_NET_IF //
1204
1205 }
1206
1207}
1208
1209
1210/*
1211 ========================================================================
1212
1213 Routine Description:
1214 Calculates the duration which is required to transmit out frames
1215 with given size and specified rate.
1216
1217 Arguments:
1218 pAd Pointer to our adapter
1219 Rate Transmit rate
1220 Size Frame size in units of byte
1221
1222 Return Value:
1223 Duration number in units of usec
1224
1225 IRQL = PASSIVE_LEVEL
1226 IRQL = DISPATCH_LEVEL
1227
1228 Note:
1229
1230 ========================================================================
1231*/
1232USHORT RTMPCalcDuration(
1233 IN PRTMP_ADAPTER pAd,
1234 IN UCHAR Rate,
1235 IN ULONG Size)
1236{
1237 ULONG Duration = 0;
1238
1239 if (Rate < RATE_FIRST_OFDM_RATE) // CCK
1240 {
1241 if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
1242 Duration = 96; // 72+24 preamble+plcp
1243 else
1244 Duration = 192; // 144+48 preamble+plcp
1245
1246 Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
1247 if ((Size << 4) % RateIdTo500Kbps[Rate])
1248 Duration ++;
1249 }
1250 else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
1251 {
1252 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1253 Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
1254 if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
1255 Duration += 4;
1256 }
1257 else //mimo rate
1258 {
1259 Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
1260 }
1261
1262 return (USHORT)Duration;
1263}
1264
1265
1266/*
1267 ========================================================================
1268
1269 Routine Description:
1270 Calculates the duration which is required to transmit out frames
1271 with given size and specified rate.
1272
1273 Arguments:
1274 pTxWI Pointer to head of each MPDU to HW.
1275 Ack Setting for Ack requirement bit
1276 Fragment Setting for Fragment bit
1277 RetryMode Setting for retry mode
1278 Ifs Setting for IFS gap
1279 Rate Setting for transmit rate
1280 Service Setting for service
1281 Length Frame length
1282 TxPreamble Short or Long preamble when using CCK rates
1283 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1284
1285 Return Value:
1286 None
1287
1288 IRQL = PASSIVE_LEVEL
1289 IRQL = DISPATCH_LEVEL
1290
1291 See also : BASmartHardTransmit() !!!
1292
1293 ========================================================================
1294*/
1295VOID RTMPWriteTxWI(
1296 IN PRTMP_ADAPTER pAd,
1297 IN PTXWI_STRUC pOutTxWI,
1298 IN BOOLEAN FRAG,
1299 IN BOOLEAN CFACK,
1300 IN BOOLEAN InsTimestamp,
1301 IN BOOLEAN AMPDU,
1302 IN BOOLEAN Ack,
1303 IN BOOLEAN NSeq, // HW new a sequence.
1304 IN UCHAR BASize,
1305 IN UCHAR WCID,
1306 IN ULONG Length,
1307 IN UCHAR PID,
1308 IN UCHAR TID,
1309 IN UCHAR TxRate,
1310 IN UCHAR Txopmode,
1311 IN BOOLEAN CfAck,
1312 IN HTTRANSMIT_SETTING *pTransmit)
1313{
1314 PMAC_TABLE_ENTRY pMac = NULL;
1315 TXWI_STRUC TxWI;
1316 PTXWI_STRUC pTxWI;
1317
1318 if (WCID < MAX_LEN_OF_MAC_TABLE)
1319 pMac = &pAd->MacTab.Content[WCID];
1320
1321 //
1322 // Always use Long preamble before verifiation short preamble functionality works well.
1323 // Todo: remove the following line if short preamble functionality works
1324 //
1325 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1326 NdisZeroMemory(&TxWI, TXWI_SIZE);
1327 pTxWI = &TxWI;
1328
1329 pTxWI->FRAG= FRAG;
1330
1331 pTxWI->CFACK = CFACK;
1332 pTxWI->TS= InsTimestamp;
1333 pTxWI->AMPDU = AMPDU;
1334 pTxWI->ACK = Ack;
1335 pTxWI->txop= Txopmode;
1336
1337 pTxWI->NSEQ = NSeq;
1338 // John tune the performace with Intel Client in 20 MHz performance
1339#ifdef DOT11_N_SUPPORT
1340 BASize = pAd->CommonCfg.TxBASize;
1341
1342 if( BASize >7 )
1343 BASize =7;
1344 pTxWI->BAWinSize = BASize;
1345 pTxWI->ShortGI = pTransmit->field.ShortGI;
1346 pTxWI->STBC = pTransmit->field.STBC;
1347#endif // DOT11_N_SUPPORT //
1348
1349 pTxWI->WirelessCliID = WCID;
1350 pTxWI->MPDUtotalByteCount = Length;
1351 pTxWI->PacketId = PID;
1352
1353 // If CCK or OFDM, BW must be 20
1354 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1355#ifdef DOT11N_DRAFT3
1356 if (pTxWI->BW)
1357 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1358#endif // DOT11N_DRAFT3 //
1359
1360 pTxWI->MCS = pTransmit->field.MCS;
1361 pTxWI->PHYMODE = pTransmit->field.MODE;
1362 pTxWI->CFACK = CfAck;
1363
1364#ifdef DOT11_N_SUPPORT
1365 if (pMac)
1366 {
1367 if (pAd->CommonCfg.bMIMOPSEnable)
1368 {
1369 if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1370 {
1371 // Dynamic MIMO Power Save Mode
1372 pTxWI->MIMOps = 1;
1373 }
1374 else if (pMac->MmpsMode == MMPS_STATIC)
1375 {
1376 // Static MIMO Power Save Mode
1377 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1378 {
1379 pTxWI->MCS = 7;
1380 pTxWI->MIMOps = 0;
1381 }
1382 }
1383 }
1384 //pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
1385 if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
1386 {
1387 pTxWI->MpduDensity = 7;
1388 }
1389 else
1390 {
1391 pTxWI->MpduDensity = pMac->MpduDensity;
1392 }
1393 }
1394#endif // DOT11_N_SUPPORT //
1395
1396 pTxWI->PacketId = pTxWI->MCS;
1397 NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
1398}
1399
1400
1401VOID RTMPWriteTxWI_Data(
1402 IN PRTMP_ADAPTER pAd,
1403 IN OUT PTXWI_STRUC pTxWI,
1404 IN TX_BLK *pTxBlk)
1405{
1406 HTTRANSMIT_SETTING *pTransmit;
1407 PMAC_TABLE_ENTRY pMacEntry;
1408#ifdef DOT11_N_SUPPORT
1409 UCHAR BASize;
1410#endif // DOT11_N_SUPPORT //
1411
1412
1413 ASSERT(pTxWI);
1414
1415 pTransmit = pTxBlk->pTransmit;
1416 pMacEntry = pTxBlk->pMacEntry;
1417
1418
1419 //
1420 // Always use Long preamble before verifiation short preamble functionality works well.
1421 // Todo: remove the following line if short preamble functionality works
1422 //
1423 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1424 NdisZeroMemory(pTxWI, TXWI_SIZE);
1425
1426 pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
1427 pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
1428 pTxWI->txop = pTxBlk->FrameGap;
1429
1430#ifdef CONFIG_STA_SUPPORT
1431#ifdef QOS_DLS_SUPPORT
1432 if (pMacEntry &&
1433 (pAd->StaCfg.BssType == BSS_INFRA) &&
1434 (pMacEntry->ValidAsDls == TRUE))
1435 pTxWI->WirelessCliID = BSSID_WCID;
1436 else
1437#endif // QOS_DLS_SUPPORT //
1438#endif // CONFIG_STA_SUPPORT //
1439 pTxWI->WirelessCliID = pTxBlk->Wcid;
1440
1441 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1442 pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
1443
1444 // If CCK or OFDM, BW must be 20
1445 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1446#ifdef DOT11_N_SUPPORT
1447#ifdef DOT11N_DRAFT3
1448 if (pTxWI->BW)
1449 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1450#endif // DOT11N_DRAFT3 //
1451 pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
1452
1453 // John tune the performace with Intel Client in 20 MHz performance
1454 BASize = pAd->CommonCfg.TxBASize;
1455 if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
1456 {
1457 UCHAR RABAOriIdx = 0; //The RA's BA Originator table index.
1458
1459 RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
1460 BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
1461 }
1462
1463 pTxWI->TxBF = pTransmit->field.TxBF;
1464 pTxWI->BAWinSize = BASize;
1465 pTxWI->ShortGI = pTransmit->field.ShortGI;
1466 pTxWI->STBC = pTransmit->field.STBC;
1467#endif // DOT11_N_SUPPORT //
1468
1469 pTxWI->MCS = pTransmit->field.MCS;
1470 pTxWI->PHYMODE = pTransmit->field.MODE;
1471
1472#ifdef DOT11_N_SUPPORT
1473 if (pMacEntry)
1474 {
1475 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1476 {
1477 // Dynamic MIMO Power Save Mode
1478 pTxWI->MIMOps = 1;
1479 }
1480 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1481 {
1482 // Static MIMO Power Save Mode
1483 if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
1484 {
1485 pTxWI->MCS = 7;
1486 pTxWI->MIMOps = 0;
1487 }
1488 }
1489
1490 if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
1491 {
1492 pTxWI->MpduDensity = 7;
1493 }
1494 else
1495 {
1496 pTxWI->MpduDensity = pMacEntry->MpduDensity;
1497 }
1498 }
1499#endif // DOT11_N_SUPPORT //
1500
1501#ifdef DBG_DIAGNOSE
1502 if (pTxBlk->QueIdx== 0)
1503 {
1504 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1505 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1506 }
1507#endif // DBG_DIAGNOSE //
1508
1509 // for rate adapation
1510 pTxWI->PacketId = pTxWI->MCS;
1511}
1512
1513
1514VOID RTMPWriteTxWI_Cache(
1515 IN PRTMP_ADAPTER pAd,
1516 IN OUT PTXWI_STRUC pTxWI,
1517 IN TX_BLK *pTxBlk)
1518{
1519 PHTTRANSMIT_SETTING pTransmit;
1520 PMAC_TABLE_ENTRY pMacEntry;
1521
1522 //
1523 // update TXWI
1524 //
1525 pMacEntry = pTxBlk->pMacEntry;
1526 pTransmit = pTxBlk->pTransmit;
1527
1528 if (pMacEntry->bAutoTxRateSwitch)
1529 {
1530 pTxWI->txop = IFS_HTTXOP;
1531
1532 // If CCK or OFDM, BW must be 20
1533 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
1534 pTxWI->ShortGI = pTransmit->field.ShortGI;
1535 pTxWI->STBC = pTransmit->field.STBC;
1536
1537 pTxWI->MCS = pTransmit->field.MCS;
1538 pTxWI->PHYMODE = pTransmit->field.MODE;
1539
1540 // set PID for TxRateSwitching
1541 pTxWI->PacketId = pTransmit->field.MCS;
1542 }
1543
1544#ifdef DOT11_N_SUPPORT
1545 pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
1546 pTxWI->MIMOps = 0;
1547
1548#ifdef DOT11N_DRAFT3
1549 if (pTxWI->BW)
1550 pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
1551#endif // DOT11N_DRAFT3 //
1552
1553 if (pAd->CommonCfg.bMIMOPSEnable)
1554 {
1555 // MIMO Power Save Mode
1556 if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
1557 {
1558 // Dynamic MIMO Power Save Mode
1559 pTxWI->MIMOps = 1;
1560 }
1561 else if (pMacEntry->MmpsMode == MMPS_STATIC)
1562 {
1563 // Static MIMO Power Save Mode
1564 if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
1565 {
1566 pTxWI->MCS = 7;
1567 pTxWI->MIMOps = 0;
1568 }
1569 }
1570 }
1571#endif // DOT11_N_SUPPORT //
1572
1573#ifdef DBG_DIAGNOSE
1574 if (pTxBlk->QueIdx== 0)
1575 {
1576 pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
1577 pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
1578 }
1579#endif // DBG_DIAGNOSE //
1580
1581 pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1582
1583}
1584
1585
1586/*
1587 ========================================================================
1588
1589 Routine Description:
1590 Calculates the duration which is required to transmit out frames
1591 with given size and specified rate.
1592
1593 Arguments:
1594 pTxD Pointer to transmit descriptor
1595 Ack Setting for Ack requirement bit
1596 Fragment Setting for Fragment bit
1597 RetryMode Setting for retry mode
1598 Ifs Setting for IFS gap
1599 Rate Setting for transmit rate
1600 Service Setting for service
1601 Length Frame length
1602 TxPreamble Short or Long preamble when using CCK rates
1603 QueIdx - 0-3, according to 802.11e/d4.4 June/2003
1604
1605 Return Value:
1606 None
1607
1608 IRQL = PASSIVE_LEVEL
1609 IRQL = DISPATCH_LEVEL
1610
1611 ========================================================================
1612*/
1613VOID RTMPWriteTxDescriptor(
1614 IN PRTMP_ADAPTER pAd,
1615 IN PTXD_STRUC pTxD,
1616 IN BOOLEAN bWIV,
1617 IN UCHAR QueueSEL)
1618{
1619 //
1620 // Always use Long preamble before verifiation short preamble functionality works well.
1621 // Todo: remove the following line if short preamble functionality works
1622 //
1623 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
1624
1625 pTxD->WIV = (bWIV) ? 1: 0;
1626 pTxD->QSEL= (QueueSEL);
1627 if (pAd->bGenOneHCCA == TRUE)
1628 pTxD->QSEL= FIFO_HCCA;
1629 pTxD->DMADONE = 0;
1630}
1631
1632
1633// should be called only when -
1634// 1. MEADIA_CONNECTED
1635// 2. AGGREGATION_IN_USED
1636// 3. Fragmentation not in used
1637// 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
1638BOOLEAN TxFrameIsAggregatible(
1639 IN PRTMP_ADAPTER pAd,
1640 IN PUCHAR pPrevAddr1,
1641 IN PUCHAR p8023hdr)
1642{
1643
1644 // can't aggregate EAPOL (802.1x) frame
1645 if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
1646 return FALSE;
1647
1648 // can't aggregate multicast/broadcast frame
1649 if (p8023hdr[0] & 0x01)
1650 return FALSE;
1651
1652 if (INFRA_ON(pAd)) // must be unicast to AP
1653 return TRUE;
1654 else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
1655 return TRUE;
1656 else
1657 return FALSE;
1658}
1659
1660
1661/*
1662 ========================================================================
1663
1664 Routine Description:
1665 Check the MSDU Aggregation policy
1666 1.HT aggregation is A-MSDU
1667 2.legaacy rate aggregation is software aggregation by Ralink.
1668
1669 Arguments:
1670
1671 Return Value:
1672
1673 Note:
1674
1675 ========================================================================
1676*/
1677BOOLEAN PeerIsAggreOn(
1678 IN PRTMP_ADAPTER pAd,
1679 IN ULONG TxRate,
1680 IN PMAC_TABLE_ENTRY pMacEntry)
1681{
1682 ULONG AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
1683
1684 if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
1685 {
1686#ifdef DOT11_N_SUPPORT
1687 if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
1688 {
1689 return TRUE;
1690 }
1691#endif // DOT11_N_SUPPORT //
1692
1693#ifdef AGGREGATION_SUPPORT
1694 if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
1695 { // legacy Ralink Aggregation support
1696 return TRUE;
1697 }
1698#endif // AGGREGATION_SUPPORT //
1699 }
1700
1701 return FALSE;
1702
1703}
1704
1705
1706/*
1707 ========================================================================
1708
1709 Routine Description:
1710 Check and fine the packet waiting in SW queue with highest priority
1711
1712 Arguments:
1713 pAd Pointer to our adapter
1714
1715 Return Value:
1716 pQueue Pointer to Waiting Queue
1717
1718 IRQL = DISPATCH_LEVEL
1719
1720 Note:
1721
1722 ========================================================================
1723*/
1724PQUEUE_HEADER RTMPCheckTxSwQueue(
1725 IN PRTMP_ADAPTER pAd,
1726 OUT PUCHAR pQueIdx)
1727{
1728
1729 ULONG Number;
1730
1731 Number = pAd->TxSwQueue[QID_AC_BK].Number
1732 + pAd->TxSwQueue[QID_AC_BE].Number
1733 + pAd->TxSwQueue[QID_AC_VI].Number
1734 + pAd->TxSwQueue[QID_AC_VO].Number
1735 + pAd->TxSwQueue[QID_HCCA].Number;
1736
1737 if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
1738 {
1739 *pQueIdx = QID_AC_VO;
1740 return (&pAd->TxSwQueue[QID_AC_VO]);
1741 }
1742 else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
1743 {
1744 *pQueIdx = QID_AC_VI;
1745 return (&pAd->TxSwQueue[QID_AC_VI]);
1746 }
1747 else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
1748 {
1749 *pQueIdx = QID_AC_BE;
1750 return (&pAd->TxSwQueue[QID_AC_BE]);
1751 }
1752 else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
1753 {
1754 *pQueIdx = QID_AC_BK;
1755 return (&pAd->TxSwQueue[QID_AC_BK]);
1756 }
1757 else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
1758 {
1759 *pQueIdx = QID_HCCA;
1760 return (&pAd->TxSwQueue[QID_HCCA]);
1761 }
1762
1763 // No packet pending in Tx Sw queue
1764 *pQueIdx = QID_AC_BK;
1765
1766 return (NULL);
1767}
1768
1769
1770#ifdef RT2860
1771BOOLEAN RTMPFreeTXDUponTxDmaDone(
1772 IN PRTMP_ADAPTER pAd,
1773 IN UCHAR QueIdx)
1774{
1775 PRTMP_TX_RING pTxRing;
1776 PTXD_STRUC pTxD;
1777#ifdef RT_BIG_ENDIAN
1778 PTXD_STRUC pDestTxD;
1779#endif
1780 PNDIS_PACKET pPacket;
1781 UCHAR FREE = 0;
1782 TXD_STRUC TxD, *pOriTxD;
1783 //ULONG IrqFlags;
1784 BOOLEAN bReschedule = FALSE;
1785
1786
1787 ASSERT(QueIdx < NUM_OF_TX_RING);
1788 pTxRing = &pAd->TxRing[QueIdx];
1789
1790 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx);
1791 while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx)
1792 {
1793#ifdef RALINK_ATE
1794#ifdef RALINK_28xx_QA
1795 PHEADER_802_11 pHeader80211;
1796
1797 if ((ATE_ON(pAd)) && (pAd->ate.bQATxStart == TRUE))
1798 {
1799 if (pAd->ate.QID == QueIdx)
1800 {
1801 pAd->ate.TxDoneCount++;
1802 //pAd->ate.Repeat++;
1803 pAd->RalinkCounters.KickTxCount++;
1804
1805 /* always use QID_AC_BE and FIFO_EDCA */
1806 ASSERT(pAd->ate.QID == 0);
1807 pAd->ate.TxAc0++;
1808
1809 FREE++;
1810#ifndef RT_BIG_ENDIAN
1811 pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
1812 pOriTxD = pTxD;
1813 NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
1814 pTxD = &TxD;
1815#else
1816 pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
1817 pOriTxD = pDestTxD ;
1818 TxD = *pDestTxD;
1819 pTxD = &TxD;
1820 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1821#endif
1822 pTxD->DMADONE = 0;
1823
1824 pHeader80211 = pTxRing->Cell[pTxRing->TxSwFreeIdx].DmaBuf.AllocVa + sizeof(TXWI_STRUC);
1825#ifdef RT_BIG_ENDIAN
1826 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader80211, DIR_READ, FALSE);
1827#endif
1828 pHeader80211->Sequence = ++pAd->ate.seq;
1829#ifdef RT_BIG_ENDIAN
1830 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader80211, DIR_WRITE, FALSE);
1831#endif
1832
1833 if ((pAd->ate.bQATxStart == TRUE) && (pAd->ate.Mode & ATE_TXFRAME) && (pAd->ate.TxDoneCount < pAd->ate.TxCount))
1834 {
1835 pAd->RalinkCounters.TransmittedByteCount += (pTxD->SDLen1 + pTxD->SDLen0);
1836 pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
1837 INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
1838 /* get tx_tdx_idx again */
1839 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF , &pTxRing->TxDmaIdx);
1840 goto kick_out;
1841 }
1842 else if ((pAd->ate.TxStatus == 1)/* or (pAd->ate.bQATxStart == TRUE) ??? */ && (pAd->ate.TxDoneCount == pAd->ate.TxCount))//<========================PETER
1843 {
1844 DBGPRINT(RT_DEBUG_TRACE,("all Tx is done\n"));
1845 // Tx status enters idle mode.
1846 pAd->ate.TxStatus = 0;
1847 }
1848 else if (!(pAd->ate.Mode & ATE_TXFRAME))
1849 {
1850 /* not complete sending yet, but someone press the Stop TX botton. */
1851 DBGPRINT(RT_DEBUG_ERROR,("not complete sending yet, but someone pressed the Stop TX bottom\n"));
1852 DBGPRINT(RT_DEBUG_ERROR,("pAd->ate.Mode = 0x%02x\n", pAd->ate.Mode));
1853 }
1854 else
1855 {
1856 DBGPRINT(RT_DEBUG_OFF,("pTxRing->TxSwFreeIdx = %d\n", pTxRing->TxSwFreeIdx));
1857 }
1858#ifndef RT_BIG_ENDIAN
1859 NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
1860#else
1861 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1862 *pDestTxD = TxD;
1863#endif // RT_BIG_ENDIAN //
1864
1865 INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
1866 continue;
1867 }
1868 }
1869#endif // RALINK_28xx_QA //
1870#endif // RALINK_ATE //
1871
1872 // static rate also need NICUpdateFifoStaCounters() function.
1873 //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
1874 NICUpdateFifoStaCounters(pAd);
1875
1876 /* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
1877 FREE++;
1878#ifndef RT_BIG_ENDIAN
1879 pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
1880 pOriTxD = pTxD;
1881 NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
1882 pTxD = &TxD;
1883#else
1884 pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
1885 pOriTxD = pDestTxD ;
1886 TxD = *pDestTxD;
1887 pTxD = &TxD;
1888 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1889#endif
1890
1891 pTxD->DMADONE = 0;
1892
1893
1894#ifdef RALINK_ATE
1895 /* Execution of this block is not allowed when ATE is running. */
1896 if (!(ATE_ON(pAd)))
1897#endif // RALINK_ATE //
1898/*====================================================================*/
1899 {
1900 pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
1901 if (pPacket)
1902 {
1903#ifdef CONFIG_5VT_ENHANCE
1904 if (RTMP_GET_PACKET_5VT(pPacket))
1905 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
1906 else
1907#endif // CONFIG_5VT_ENHANCE //
1908 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1909 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1910 }
1911 //Always assign pNdisPacket as NULL after clear
1912 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
1913
1914 pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
1915
1916 ASSERT(pPacket == NULL);
1917 if (pPacket)
1918 {
1919#ifdef CONFIG_5VT_ENHANCE
1920 if (RTMP_GET_PACKET_5VT(pPacket))
1921 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE);
1922 else
1923#endif // CONFIG_5VT_ENHANCE //
1924 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1925 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1926 }
1927 //Always assign pNextNdisPacket as NULL after clear
1928 pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL;
1929 }
1930/*====================================================================*/
1931
1932 pAd->RalinkCounters.TransmittedByteCount += (pTxD->SDLen1 + pTxD->SDLen0);
1933 pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++;
1934 INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
1935 /* get tx_tdx_idx again */
1936 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF , &pTxRing->TxDmaIdx);
1937#ifdef RT_BIG_ENDIAN
1938 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1939 *pDestTxD = TxD;
1940#else
1941 NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
1942#endif
1943
1944#ifdef RALINK_ATE
1945#ifdef RALINK_28xx_QA
1946kick_out:
1947#endif // RALINK_28xx_QA //
1948
1949 //
1950 // ATE_TXCONT mode also need to send some normal frames, so let it in.
1951 // ATE_STOP must be changed not to be 0xff
1952 // to prevent it from running into this block.
1953 //
1954 if ((pAd->ate.Mode & ATE_TXFRAME) && (pAd->ate.QID == QueIdx))
1955 {
1956 // TxDoneCount++ has been done if QA is used.
1957 if (pAd->ate.bQATxStart == FALSE)
1958 {
1959 pAd->ate.TxDoneCount++;
1960 }
1961 if (((pAd->ate.TxCount - pAd->ate.TxDoneCount + 1) >= TX_RING_SIZE))
1962 {
1963 /* Note : We increase TxCpuIdx here, not TxSwFreeIdx ! */
1964 INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
1965#ifndef RT_BIG_ENDIAN//<==========================PETER
1966 pTxD = (PTXD_STRUC) (pTxRing->Cell[pAd->TxRing[QueIdx].TxCpuIdx].AllocVa);
1967 pOriTxD = pTxD;
1968 NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC));
1969 pTxD = &TxD;
1970#else
1971 pDestTxD = (PTXD_STRUC) (pTxRing->Cell[pAd->TxRing[QueIdx].TxCpuIdx].AllocVa);
1972 pOriTxD = pDestTxD ;
1973 TxD = *pDestTxD;
1974 pTxD = &TxD;
1975 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1976#endif
1977 pTxD->DMADONE = 0;
1978#ifndef RT_BIG_ENDIAN//<==========================PETER
1979 NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC));
1980#else
1981 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1982 *pDestTxD = TxD;
1983#endif
1984 // kick Tx-Ring.
1985 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx * RINGREG_DIFF, pAd->TxRing[QueIdx].TxCpuIdx);
1986 pAd->RalinkCounters.KickTxCount++;
1987 }
1988 }
1989#endif // RALINK_ATE //
1990 }
1991
1992
1993 return bReschedule;
1994
1995}
1996
1997
1998/*
1999 ========================================================================
2000
2001 Routine Description:
2002 Process TX Rings DMA Done interrupt, running in DPC level
2003
2004 Arguments:
2005 Adapter Pointer to our adapter
2006
2007 Return Value:
2008 None
2009
2010 IRQL = DISPATCH_LEVEL
2011
2012 ========================================================================
2013*/
2014BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
2015 IN PRTMP_ADAPTER pAd,
2016 IN INT_SOURCE_CSR_STRUC TxRingBitmap)
2017{
2018 unsigned long IrqFlags;
2019 BOOLEAN bReschedule = FALSE;
2020
2021 // Make sure Tx ring resource won't be used by other threads
2022
2023 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
2024
2025 if (TxRingBitmap.field.Ac0DmaDone)
2026 bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
2027
2028 if (TxRingBitmap.field.HccaDmaDone)
2029 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA);
2030
2031 if (TxRingBitmap.field.Ac3DmaDone)
2032 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
2033
2034 if (TxRingBitmap.field.Ac2DmaDone)
2035 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
2036
2037 if (TxRingBitmap.field.Ac1DmaDone)
2038 bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
2039
2040 // Make sure to release Tx ring resource
2041 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
2042
2043 // Dequeue outgoing frames from TxSwQueue[] and process it
2044 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
2045
2046 return bReschedule;
2047}
2048
2049
2050/*
2051 ========================================================================
2052
2053 Routine Description:
2054 Process MGMT ring DMA done interrupt, running in DPC level
2055
2056 Arguments:
2057 pAd Pointer to our adapter
2058
2059 Return Value:
2060 None
2061
2062 IRQL = DISPATCH_LEVEL
2063
2064 Note:
2065
2066 ========================================================================
2067*/
2068VOID RTMPHandleMgmtRingDmaDoneInterrupt(
2069 IN PRTMP_ADAPTER pAd)
2070{
2071 PTXD_STRUC pTxD;
2072#ifdef RT_BIG_ENDIAN
2073 PTXD_STRUC pDestTxD;
2074 TXD_STRUC TxD;
2075#endif
2076 PNDIS_PACKET pPacket;
2077 UCHAR FREE = 0;
2078 PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
2079
2080 NdisAcquireSpinLock(&pAd->MgmtRingLock);
2081
2082 RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
2083 while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx)
2084 {
2085 FREE++;
2086#ifdef RT_BIG_ENDIAN
2087 pDestTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
2088 TxD = *pDestTxD;
2089 pTxD = &TxD;
2090 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2091#else
2092 pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa);
2093#endif
2094 pTxD->DMADONE = 0;
2095 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
2096
2097
2098 if (pPacket)
2099 {
2100 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
2101 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
2102 }
2103 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
2104
2105 pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
2106 if (pPacket)
2107 {
2108 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
2109 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
2110 }
2111 pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
2112 INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
2113
2114#ifdef RT_BIG_ENDIAN
2115 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
2116 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, TRUE, TYPE_TXD);
2117#endif
2118 }
2119 NdisReleaseSpinLock(&pAd->MgmtRingLock);
2120
2121}
2122
2123
2124/*
2125 ========================================================================
2126
2127 Routine Description:
2128 Arguments:
2129 Adapter Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
2130
2131 IRQL = DISPATCH_LEVEL
2132
2133 ========================================================================
2134*/
2135VOID RTMPHandleTBTTInterrupt(
2136 IN PRTMP_ADAPTER pAd)
2137{
2138 {
2139 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
2140 {
2141 }
2142 }
2143}
2144
2145
2146/*
2147 ========================================================================
2148
2149 Routine Description:
2150 Arguments:
2151 Adapter Pointer to our adapter. Rewrite beacon content before next send-out.
2152
2153 IRQL = DISPATCH_LEVEL
2154
2155 ========================================================================
2156*/
2157VOID RTMPHandlePreTBTTInterrupt(
2158 IN PRTMP_ADAPTER pAd)
2159{
2160 {
2161 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
2162 {
2163 DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n"));
2164 }
2165 }
2166
2167
2168}
2169
2170VOID RTMPHandleRxCoherentInterrupt(
2171 IN PRTMP_ADAPTER pAd)
2172{
2173 WPDMA_GLO_CFG_STRUC GloCfg;
2174
2175 if (pAd == NULL)
2176 {
2177 DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
2178 return;
2179 }
2180
2181 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
2182
2183 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word);
2184
2185 GloCfg.field.EnTXWriteBackDDONE = 0;
2186 GloCfg.field.EnableRxDMA = 0;
2187 GloCfg.field.EnableTxDMA = 0;
2188 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
2189
2190 RTMPRingCleanUp(pAd, QID_AC_BE);
2191 RTMPRingCleanUp(pAd, QID_AC_BK);
2192 RTMPRingCleanUp(pAd, QID_AC_VI);
2193 RTMPRingCleanUp(pAd, QID_AC_VO);
2194 RTMPRingCleanUp(pAd, QID_HCCA);
2195 RTMPRingCleanUp(pAd, QID_MGMT);
2196 RTMPRingCleanUp(pAd, QID_RX);
2197
2198 RTMPEnableRxTx(pAd);
2199
2200 DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
2201}
2202
2203
2204VOID DBGPRINT_TX_RING(
2205 IN PRTMP_ADAPTER pAd,
2206 IN UCHAR QueIdx)
2207{
2208 UINT32 Ac0Base;
2209 UINT32 Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
2210 int i;
2211 PULONG ptemp;
2212
2213 DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n " ));
2214 switch (QueIdx)
2215 {
2216 case QID_AC_BE:
2217 RTMP_IO_READ32(pAd, TX_BASE_PTR0, &Ac0Base);
2218 RTMP_IO_READ32(pAd, TX_CTX_IDX0, &Ac0SwIdx);
2219 RTMP_IO_READ32(pAd, TX_DTX_IDX0, &Ac0HwIdx);
2220 DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BE DESCRIPTOR \n " ));
2221 for (i=0;i<TX_RING_SIZE;i++)
2222 {
2223 ptemp= (PULONG)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
2224 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d] %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2225 }
2226 DBGPRINT_RAW(RT_DEBUG_TRACE, (" \n " ));
2227 break;
2228 case QID_AC_BK:
2229 RTMP_IO_READ32(pAd, TX_BASE_PTR1, &Ac0Base);
2230 RTMP_IO_READ32(pAd, TX_CTX_IDX1, &Ac0SwIdx);
2231 RTMP_IO_READ32(pAd, TX_DTX_IDX1, &Ac0HwIdx);
2232 DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_BK DESCRIPTOR \n " ));
2233 for (i=0;i<TX_RING_SIZE;i++)
2234 {
2235 ptemp= (PULONG)pAd->TxRing[QID_AC_BK].Cell[i].AllocVa;
2236 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d] %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2237 }
2238 DBGPRINT_RAW(RT_DEBUG_TRACE, (" \n " ));
2239 break;
2240 case QID_AC_VI:
2241 RTMP_IO_READ32(pAd, TX_BASE_PTR2, &Ac0Base);
2242 RTMP_IO_READ32(pAd, TX_CTX_IDX2, &Ac0SwIdx);
2243 RTMP_IO_READ32(pAd, TX_DTX_IDX2, &Ac0HwIdx);
2244 DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VI DESCRIPTOR \n " ));
2245 for (i=0;i<TX_RING_SIZE;i++)
2246 {
2247 ptemp= (PULONG)pAd->TxRing[QID_AC_VI].Cell[i].AllocVa;
2248 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d] %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2249 }
2250 DBGPRINT_RAW(RT_DEBUG_TRACE, (" \n " ));
2251 break;
2252 case QID_AC_VO:
2253 RTMP_IO_READ32(pAd, TX_BASE_PTR3, &Ac0Base);
2254 RTMP_IO_READ32(pAd, TX_CTX_IDX3, &Ac0SwIdx);
2255 RTMP_IO_READ32(pAd, TX_DTX_IDX3, &Ac0HwIdx);
2256 DBGPRINT_RAW(RT_DEBUG_TRACE, ("All QID_AC_VO DESCRIPTOR \n " ));
2257 for (i=0;i<TX_RING_SIZE;i++)
2258 {
2259 ptemp= (PULONG)pAd->TxRing[QID_AC_VO].Cell[i].AllocVa;
2260 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d] %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2261 }
2262 DBGPRINT_RAW(RT_DEBUG_TRACE, (" \n " ));
2263 break;
2264 case QID_MGMT:
2265 RTMP_IO_READ32(pAd, TX_BASE_PTR5, &Ac0Base);
2266 RTMP_IO_READ32(pAd, TX_CTX_IDX5, &Ac0SwIdx);
2267 RTMP_IO_READ32(pAd, TX_DTX_IDX5, &Ac0HwIdx);
2268 DBGPRINT_RAW(RT_DEBUG_TRACE, (" All QID_MGMT DESCRIPTOR \n " ));
2269 for (i=0;i<MGMT_RING_SIZE;i++)
2270 {
2271 ptemp= (PULONG)pAd->MgmtRing.Cell[i].AllocVa;
2272 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d] %08lx: %08lx: %08lx: %08lx\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2273 }
2274 DBGPRINT_RAW(RT_DEBUG_TRACE, (" \n " ));
2275 break;
2276
2277 default:
2278 DBGPRINT_ERR(("DBGPRINT_TX_RING(Ring %d) not supported\n", QueIdx));
2279 break;
2280 }
2281 AC0freeIdx = pAd->TxRing[QueIdx].TxSwFreeIdx;
2282
2283 DBGPRINT(RT_DEBUG_TRACE,("TxRing%d, TX_DTX_IDX=%d, TX_CTX_IDX=%d\n", QueIdx, Ac0HwIdx, Ac0SwIdx));
2284 DBGPRINT_RAW(RT_DEBUG_TRACE,(" TxSwFreeIdx[%d]", AC0freeIdx));
2285 DBGPRINT_RAW(RT_DEBUG_TRACE,(" pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
2286
2287
2288}
2289
2290
2291VOID DBGPRINT_RX_RING(
2292 IN PRTMP_ADAPTER pAd)
2293{
2294 UINT32 Ac0Base;
2295 UINT32 Ac0HwIdx = 0, Ac0SwIdx = 0, AC0freeIdx;
2296 int i;
2297 UINT32 *ptemp;
2298
2299 DBGPRINT_RAW(RT_DEBUG_TRACE, ("=====================================================\n " ));
2300 RTMP_IO_READ32(pAd, RX_BASE_PTR, &Ac0Base);
2301 RTMP_IO_READ32(pAd, RX_CRX_IDX, &Ac0SwIdx);
2302 RTMP_IO_READ32(pAd, RX_DRX_IDX, &Ac0HwIdx);
2303 AC0freeIdx = pAd->RxRing.RxSwReadIdx;
2304
2305 DBGPRINT_RAW(RT_DEBUG_TRACE, ("All RX DSP \n " ));
2306 for (i=0;i<RX_RING_SIZE;i++)
2307 {
2308 ptemp = (UINT32 *)pAd->RxRing.Cell[i].AllocVa;
2309 DBGPRINT_RAW(RT_DEBUG_TRACE, ("[%02d] %08x: %08x: %08x: %08x\n " , i, *ptemp,*(ptemp+1),*(ptemp+2),*(ptemp+3)));
2310 }
2311 DBGPRINT(RT_DEBUG_TRACE,("RxRing, RX_DRX_IDX=%d, RX_CRX_IDX=%d \n", Ac0HwIdx, Ac0SwIdx));
2312 DBGPRINT_RAW(RT_DEBUG_TRACE,(" RxSwReadIdx [%d]=", AC0freeIdx));
2313 DBGPRINT_RAW(RT_DEBUG_TRACE,(" pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
2314}
2315#endif // RT2860 //
2316
2317/*
2318 ========================================================================
2319
2320 Routine Description:
2321 Suspend MSDU transmission
2322
2323 Arguments:
2324 pAd Pointer to our adapter
2325
2326 Return Value:
2327 None
2328
2329 Note:
2330
2331 ========================================================================
2332*/
2333VOID RTMPSuspendMsduTransmission(
2334 IN PRTMP_ADAPTER pAd)
2335{
2336 DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
2337
2338
2339 //
2340 // Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
2341 // use Lowbound as R66 value on ScanNextChannel(...)
2342 //
2343 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
2344
2345 // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
2346 RTMPSetAGCInitValue(pAd, BW_20);
2347
2348 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2349}
2350
2351
2352/*
2353 ========================================================================
2354
2355 Routine Description:
2356 Resume MSDU transmission
2357
2358 Arguments:
2359 pAd Pointer to our adapter
2360
2361 Return Value:
2362 None
2363
2364 IRQL = DISPATCH_LEVEL
2365
2366 Note:
2367
2368 ========================================================================
2369*/
2370VOID RTMPResumeMsduTransmission(
2371 IN PRTMP_ADAPTER pAd)
2372{
2373 DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
2374
2375
2376 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
2377
2378 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2379 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
2380}
2381
2382
2383UINT deaggregate_AMSDU_announce(
2384 IN PRTMP_ADAPTER pAd,
2385 PNDIS_PACKET pPacket,
2386 IN PUCHAR pData,
2387 IN ULONG DataSize)
2388{
2389 USHORT PayloadSize;
2390 USHORT SubFrameSize;
2391 PHEADER_802_3 pAMSDUsubheader;
2392 UINT nMSDU;
2393 UCHAR Header802_3[14];
2394
2395 PUCHAR pPayload, pDA, pSA, pRemovedLLCSNAP;
2396 PNDIS_PACKET pClonePacket;
2397
2398
2399
2400 nMSDU = 0;
2401
2402 while (DataSize > LENGTH_802_3)
2403 {
2404
2405 nMSDU++;
2406
2407 pAMSDUsubheader = (PHEADER_802_3)pData;
2408 PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
2409 SubFrameSize = PayloadSize + LENGTH_802_3;
2410
2411
2412 if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
2413 {
2414 break;
2415 }
2416
2417 pPayload = pData + LENGTH_802_3;
2418 pDA = pData;
2419 pSA = pData + MAC_ADDR_LEN;
2420
2421 // convert to 802.3 header
2422 CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
2423
2424#ifdef CONFIG_STA_SUPPORT
2425 if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
2426 {
2427 // avoid local heap overflow, use dyanamic allocation
2428 MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
2429 memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
2430 Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
2431 WpaEAPOLKeyAction(pAd, Elem);
2432 kfree(Elem);
2433 }
2434#endif // CONFIG_STA_SUPPORT //
2435
2436#ifdef CONFIG_STA_SUPPORT
2437 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2438 {
2439 if (pRemovedLLCSNAP)
2440 {
2441 pPayload -= LENGTH_802_3;
2442 PayloadSize += LENGTH_802_3;
2443 NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
2444 }
2445 }
2446#endif // CONFIG_STA_SUPPORT //
2447
2448 pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
2449 if (pClonePacket)
2450 {
2451#ifdef CONFIG_STA_SUPPORT
2452 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2453 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
2454#endif // CONFIG_STA_SUPPORT //
2455 }
2456
2457
2458 // A-MSDU has padding to multiple of 4 including subframe header.
2459 // align SubFrameSize up to multiple of 4
2460 SubFrameSize = (SubFrameSize+3)&(~0x3);
2461
2462
2463 if (SubFrameSize > 1528 || SubFrameSize < 32)
2464 {
2465 break;
2466 }
2467
2468 if (DataSize > SubFrameSize)
2469 {
2470 pData += SubFrameSize;
2471 DataSize -= SubFrameSize;
2472 }
2473 else
2474 {
2475 // end of A-MSDU
2476 DataSize = 0;
2477 }
2478 }
2479
2480 // finally release original rx packet
2481 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
2482
2483 return nMSDU;
2484}
2485
2486
2487UINT BA_Reorder_AMSDU_Annnounce(
2488 IN PRTMP_ADAPTER pAd,
2489 IN PNDIS_PACKET pPacket)
2490{
2491 PUCHAR pData;
2492 USHORT DataSize;
2493 UINT nMSDU = 0;
2494
2495 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
2496 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
2497
2498 nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
2499
2500 return nMSDU;
2501}
2502
2503
2504/*
2505 ==========================================================================
2506 Description:
2507 Look up the MAC address in the MAC table. Return NULL if not found.
2508 Return:
2509 pEntry - pointer to the MAC entry; NULL is not found
2510 ==========================================================================
2511*/
2512MAC_TABLE_ENTRY *MacTableLookup(
2513 IN PRTMP_ADAPTER pAd,
2514 PUCHAR pAddr)
2515{
2516 ULONG HashIdx;
2517 MAC_TABLE_ENTRY *pEntry = NULL;
2518
2519 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2520 pEntry = pAd->MacTab.Hash[HashIdx];
2521
2522 while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
2523 {
2524 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2525 {
2526 break;
2527 }
2528 else
2529 pEntry = pEntry->pNext;
2530 }
2531
2532 return pEntry;
2533}
2534
2535MAC_TABLE_ENTRY *MacTableInsertEntry(
2536 IN PRTMP_ADAPTER pAd,
2537 IN PUCHAR pAddr,
2538 IN UCHAR apidx,
2539 IN BOOLEAN CleanAll)
2540{
2541 UCHAR HashIdx;
2542 int i, FirstWcid;
2543 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
2544
2545 // if FULL, return
2546 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
2547 return NULL;
2548
2549 FirstWcid = 1;
2550#ifdef CONFIG_STA_SUPPORT
2551 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2552 if (pAd->StaCfg.BssType == BSS_INFRA)
2553 FirstWcid = 2;
2554#endif // CONFIG_STA_SUPPORT //
2555
2556 // allocate one MAC entry
2557 NdisAcquireSpinLock(&pAd->MacTabLock);
2558 for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) // skip entry#0 so that "entry index == AID" for fast lookup
2559 {
2560 // pick up the first available vacancy
2561 if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
2562 (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
2563 (pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
2564 (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
2565#ifdef CONFIG_STA_SUPPORT
2566#ifdef QOS_DLS_SUPPORT
2567 && (pAd->MacTab.Content[i].ValidAsDls == FALSE)
2568#endif // QOS_DLS_SUPPORT //
2569#endif // CONFIG_STA_SUPPORT //
2570 )
2571 {
2572 pEntry = &pAd->MacTab.Content[i];
2573 if (CleanAll == TRUE)
2574 {
2575 pEntry->MaxSupportedRate = RATE_11;
2576 pEntry->CurrTxRate = RATE_11;
2577 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
2578 pEntry->PairwiseKey.KeyLen = 0;
2579 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
2580 }
2581#ifdef CONFIG_STA_SUPPORT
2582#ifdef QOS_DLS_SUPPORT
2583 if (apidx >= MIN_NET_DEVICE_FOR_DLS)
2584 {
2585 pEntry->ValidAsCLI = FALSE;
2586 pEntry->ValidAsWDS = FALSE;
2587 pEntry->ValidAsApCli = FALSE;
2588 pEntry->ValidAsMesh = FALSE;
2589 pEntry->ValidAsDls = TRUE;
2590 pEntry->isCached = FALSE;
2591 }
2592 else
2593#endif // QOS_DLS_SUPPORT //
2594#endif // CONFIG_STA_SUPPORT //
2595 {
2596
2597#ifdef CONFIG_STA_SUPPORT
2598 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2599 {
2600 pEntry->ValidAsCLI = TRUE;
2601 pEntry->ValidAsWDS = FALSE;
2602 pEntry->ValidAsApCli = FALSE;
2603 pEntry->ValidAsMesh = FALSE;
2604 pEntry->ValidAsDls = FALSE;
2605 }
2606#endif // CONFIG_STA_SUPPORT //
2607 }
2608
2609 pEntry->bIAmBadAtheros = FALSE;
2610 pEntry->pAd = pAd;
2611 pEntry->CMTimerRunning = FALSE;
2612 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
2613 pEntry->RSNIE_Len = 0;
2614 NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
2615 pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
2616
2617 if (pEntry->ValidAsMesh)
2618 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
2619 else if (pEntry->ValidAsApCli)
2620 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
2621 else if (pEntry->ValidAsWDS)
2622 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
2623#ifdef CONFIG_STA_SUPPORT
2624#ifdef QOS_DLS_SUPPORT
2625 else if (pEntry->ValidAsDls)
2626 pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS);
2627#endif // QOS_DLS_SUPPORT //
2628#endif // CONFIG_STA_SUPPORT //
2629 else
2630 pEntry->apidx = apidx;
2631
2632 {
2633
2634#ifdef CONFIG_STA_SUPPORT
2635 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2636 {
2637 pEntry->AuthMode = pAd->StaCfg.AuthMode;
2638 pEntry->WepStatus = pAd->StaCfg.WepStatus;
2639 pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
2640#ifdef RT2860
2641 AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i);
2642#endif // RT2860 //
2643 }
2644#endif // CONFIG_STA_SUPPORT //
2645 }
2646
2647 pEntry->GTKState = REKEY_NEGOTIATING;
2648 pEntry->PairwiseKey.KeyLen = 0;
2649 pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
2650#ifdef CONFIG_STA_SUPPORT
2651 if ((pAd->OpMode == OPMODE_STA) &&
2652 (pAd->StaCfg.BssType == BSS_ADHOC))
2653 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
2654 else
2655#ifdef QOS_DLS_SUPPORT
2656 if (pEntry->ValidAsDls == TRUE)
2657 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
2658 else
2659#endif //QOS_DLS_SUPPORT
2660#endif // CONFIG_STA_SUPPORT //
2661 pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2662 pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
2663 COPY_MAC_ADDR(pEntry->Addr, pAddr);
2664 pEntry->Sst = SST_NOT_AUTH;
2665 pEntry->AuthState = AS_NOT_AUTH;
2666 pEntry->Aid = (USHORT)i; //0;
2667 pEntry->CapabilityInfo = 0;
2668 pEntry->PsMode = PWR_ACTIVE;
2669 pEntry->PsQIdleCount = 0;
2670 pEntry->NoDataIdleCount = 0;
2671 pEntry->ContinueTxFailCnt = 0;
2672 InitializeQueueHeader(&pEntry->PsQueue);
2673
2674
2675 pAd->MacTab.Size ++;
2676 // Add this entry into ASIC RX WCID search table
2677 RT28XX_STA_ENTRY_ADD(pAd, pEntry);
2678
2679
2680
2681 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
2682 break;
2683 }
2684 }
2685
2686 // add this MAC entry into HASH table
2687 if (pEntry)
2688 {
2689 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2690 if (pAd->MacTab.Hash[HashIdx] == NULL)
2691 {
2692 pAd->MacTab.Hash[HashIdx] = pEntry;
2693 }
2694 else
2695 {
2696 pCurrEntry = pAd->MacTab.Hash[HashIdx];
2697 while (pCurrEntry->pNext != NULL)
2698 pCurrEntry = pCurrEntry->pNext;
2699 pCurrEntry->pNext = pEntry;
2700 }
2701 }
2702
2703 NdisReleaseSpinLock(&pAd->MacTabLock);
2704 return pEntry;
2705}
2706
2707/*
2708 ==========================================================================
2709 Description:
2710 Delete a specified client from MAC table
2711 ==========================================================================
2712 */
2713BOOLEAN MacTableDeleteEntry(
2714 IN PRTMP_ADAPTER pAd,
2715 IN USHORT wcid,
2716 IN PUCHAR pAddr)
2717{
2718 USHORT HashIdx;
2719 MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
2720 BOOLEAN Cancelled;
2721
2722 if (wcid >= MAX_LEN_OF_MAC_TABLE)
2723 return FALSE;
2724
2725 NdisAcquireSpinLock(&pAd->MacTabLock);
2726
2727 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2728 pEntry = &pAd->MacTab.Content[wcid];
2729
2730 if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
2731#ifdef CONFIG_STA_SUPPORT
2732#ifdef QOS_DLS_SUPPORT
2733 || pEntry->ValidAsDls
2734#endif // QOS_DLS_SUPPORT //
2735#endif // CONFIG_STA_SUPPORT //
2736 ))
2737 {
2738 if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2739 {
2740
2741 // Delete this entry from ASIC on-chip WCID Table
2742 RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
2743
2744#ifdef DOT11_N_SUPPORT
2745 // free resources of BA
2746 BASessionTearDownALL(pAd, pEntry->Aid);
2747#endif // DOT11_N_SUPPORT //
2748
2749
2750 pPrevEntry = NULL;
2751 pProbeEntry = pAd->MacTab.Hash[HashIdx];
2752 ASSERT(pProbeEntry);
2753
2754 // update Hash list
2755 do
2756 {
2757 if (pProbeEntry == pEntry)
2758 {
2759 if (pPrevEntry == NULL)
2760 {
2761 pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
2762 }
2763 else
2764 {
2765 pPrevEntry->pNext = pEntry->pNext;
2766 }
2767 break;
2768 }
2769
2770 pPrevEntry = pProbeEntry;
2771 pProbeEntry = pProbeEntry->pNext;
2772 } while (pProbeEntry);
2773
2774 // not found !!!
2775 ASSERT(pProbeEntry != NULL);
2776
2777 RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
2778
2779
2780 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
2781 {
2782 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
2783 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
2784 }
2785
2786
2787 NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
2788 pAd->MacTab.Size --;
2789 DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
2790 }
2791 else
2792 {
2793 printk("\n%s: Impossible Wcid = %d !!!!!\n", __FUNCTION__, wcid);
2794 }
2795 }
2796
2797 NdisReleaseSpinLock(&pAd->MacTabLock);
2798
2799 //Reset operating mode when no Sta.
2800 if (pAd->MacTab.Size == 0)
2801 {
2802#ifdef DOT11_N_SUPPORT
2803 pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
2804#endif // DOT11_N_SUPPORT //
2805 AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
2806 }
2807
2808 return TRUE;
2809}
2810
2811
2812/*
2813 ==========================================================================
2814 Description:
2815 This routine reset the entire MAC table. All packets pending in
2816 the power-saving queues are freed here.
2817 ==========================================================================
2818 */
2819VOID MacTableReset(
2820 IN PRTMP_ADAPTER pAd)
2821{
2822 int i;
2823
2824 DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
2825 //NdisAcquireSpinLock(&pAd->MacTabLock);
2826
2827 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2828 {
2829#ifdef RT2860
2830 RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
2831#endif // RT2860 //
2832 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2833 {
2834
2835#ifdef DOT11_N_SUPPORT
2836 // free resources of BA
2837 BASessionTearDownALL(pAd, i);
2838#endif // DOT11_N_SUPPORT //
2839
2840 pAd->MacTab.Content[i].ValidAsCLI = FALSE;
2841
2842
2843
2844
2845 //AsicDelWcidTab(pAd, i);
2846 }
2847 }
2848
2849 return;
2850}
2851
2852/*
2853 ==========================================================================
2854 Description:
2855
2856 IRQL = DISPATCH_LEVEL
2857
2858 ==========================================================================
2859*/
2860VOID AssocParmFill(
2861 IN PRTMP_ADAPTER pAd,
2862 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
2863 IN PUCHAR pAddr,
2864 IN USHORT CapabilityInfo,
2865 IN ULONG Timeout,
2866 IN USHORT ListenIntv)
2867{
2868 COPY_MAC_ADDR(AssocReq->Addr, pAddr);
2869 // Add mask to support 802.11b mode only
2870 AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
2871 AssocReq->Timeout = Timeout;
2872 AssocReq->ListenIntv = ListenIntv;
2873}
2874
2875
2876/*
2877 ==========================================================================
2878 Description:
2879
2880 IRQL = DISPATCH_LEVEL
2881
2882 ==========================================================================
2883*/
2884VOID DisassocParmFill(
2885 IN PRTMP_ADAPTER pAd,
2886 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
2887 IN PUCHAR pAddr,
2888 IN USHORT Reason)
2889{
2890 COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
2891 DisassocReq->Reason = Reason;
2892}
2893
2894
2895/*
2896 ========================================================================
2897
2898 Routine Description:
2899 Check the out going frame, if this is an DHCP or ARP datagram
2900 will be duplicate another frame at low data rate transmit.
2901
2902 Arguments:
2903 pAd Pointer to our adapter
2904 pPacket Pointer to outgoing Ndis frame
2905
2906 Return Value:
2907 TRUE To be duplicate at Low data rate transmit. (1mb)
2908 FALSE Do nothing.
2909
2910 IRQL = DISPATCH_LEVEL
2911
2912 Note:
2913
2914 MAC header + IP Header + UDP Header
2915 14 Bytes 20 Bytes
2916
2917 UDP Header
2918 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
2919 Source Port
2920 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
2921 Destination Port
2922
2923 port 0x43 means Bootstrap Protocol, server.
2924 Port 0x44 means Bootstrap Protocol, client.
2925
2926 ========================================================================
2927*/
2928
2929BOOLEAN RTMPCheckDHCPFrame(
2930 IN PRTMP_ADAPTER pAd,
2931 IN PNDIS_PACKET pPacket)
2932{
2933 PACKET_INFO PacketInfo;
2934 ULONG NumberOfBytesRead = 0;
2935 ULONG CurrentOffset = 0;
2936 PVOID pVirtualAddress = NULL;
2937 UINT NdisBufferLength;
2938 PUCHAR pSrc;
2939 USHORT Protocol;
2940 UCHAR ByteOffset36 = 0;
2941 UCHAR ByteOffset38 = 0;
2942 BOOLEAN ReadFirstParm = TRUE;
2943
2944 RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
2945
2946 NumberOfBytesRead += NdisBufferLength;
2947 pSrc = (PUCHAR) pVirtualAddress;
2948 Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
2949
2950 //
2951 // Check DHCP & BOOTP protocol
2952 //
2953 while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
2954 {
2955 if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
2956 {
2957 CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
2958 ByteOffset36 = *(pSrc + CurrentOffset);
2959 ReadFirstParm = FALSE;
2960 }
2961
2962 if (NumberOfBytesRead >= 37)
2963 {
2964 CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
2965 ByteOffset38 = *(pSrc + CurrentOffset);
2966 //End of Read
2967 break;
2968 }
2969 return FALSE;
2970 }
2971
2972 // Check for DHCP & BOOTP protocol
2973 if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
2974 {
2975 //
2976 // 2054 (hex 0806) for ARP datagrams
2977 // if this packet is not ARP datagrams, then do nothing
2978 // ARP datagrams will also be duplicate at 1mb broadcast frames
2979 //
2980 if (Protocol != 0x0806 )
2981 return FALSE;
2982 }
2983
2984 return TRUE;
2985}
2986
2987
2988BOOLEAN RTMPCheckEtherType(
2989 IN PRTMP_ADAPTER pAd,
2990 IN PNDIS_PACKET pPacket)
2991{
2992 USHORT TypeLen;
2993 UCHAR Byte0, Byte1;
2994 PUCHAR pSrcBuf;
2995 UINT32 pktLen;
2996 UINT16 srcPort, dstPort;
2997 BOOLEAN status = TRUE;
2998
2999
3000 pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
3001 pktLen = GET_OS_PKT_LEN(pPacket);
3002
3003 ASSERT(pSrcBuf);
3004
3005 RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
3006
3007 // get Ethernet protocol field
3008 TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
3009
3010 pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header.
3011
3012 if (TypeLen <= 1500)
3013 { // 802.3, 802.3 LLC
3014 /*
3015 DestMAC(6) + SrcMAC(6) + Lenght(2) +
3016 DSAP(1) + SSAP(1) + Control(1) +
3017 if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
3018 => + SNAP (5, OriginationID(3) + etherType(2))
3019 */
3020 if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
3021 {
3022 Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
3023 RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
3024 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
3025 pSrcBuf += 8; // Skip this LLC/SNAP header
3026 }
3027 else
3028 {
3029 //It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
3030 }
3031 }
3032
3033 // If it's a VLAN packet, get the real Type/Length field.
3034 if (TypeLen == 0x8100)
3035 {
3036 /* 0x8100 means VLAN packets */
3037
3038 /* Dest. MAC Address (6-bytes) +
3039 Source MAC Address (6-bytes) +
3040 Length/Type = 802.1Q Tag Type (2-byte) +
3041 Tag Control Information (2-bytes) +
3042 Length / Type (2-bytes) +
3043 data payload (0-n bytes) +
3044 Pad (0-p bytes) +
3045 Frame Check Sequence (4-bytes) */
3046
3047 RTMP_SET_PACKET_VLAN(pPacket, 1);
3048 Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
3049 TypeLen = (USHORT)((Byte0 << 8) + Byte1);
3050
3051 pSrcBuf += 4; // Skip the VLAN Header.
3052 }
3053
3054 switch (TypeLen)
3055 {
3056 case 0x0800:
3057 {
3058 ASSERT((pktLen > 34));
3059 if (*(pSrcBuf + 9) == 0x11)
3060 { // udp packet
3061 ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header
3062
3063 pSrcBuf += 20; // Skip the IP header
3064 srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
3065 dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
3066
3067 if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
3068 { //It's a BOOTP/DHCP packet
3069 RTMP_SET_PACKET_DHCP(pPacket, 1);
3070 }
3071 }
3072 }
3073 break;
3074 case 0x0806:
3075 {
3076 //ARP Packet.
3077 RTMP_SET_PACKET_DHCP(pPacket, 1);
3078 }
3079 break;
3080 case 0x888e:
3081 {
3082 // EAPOL Packet.
3083 RTMP_SET_PACKET_EAPOL(pPacket, 1);
3084 }
3085 break;
3086 default:
3087 status = FALSE;
3088 break;
3089 }
3090
3091 return status;
3092
3093}
3094
3095
3096
3097VOID Update_Rssi_Sample(
3098 IN PRTMP_ADAPTER pAd,
3099 IN RSSI_SAMPLE *pRssi,
3100 IN PRXWI_STRUC pRxWI)
3101 {
3102 CHAR rssi0 = pRxWI->RSSI0;
3103 CHAR rssi1 = pRxWI->RSSI1;
3104 CHAR rssi2 = pRxWI->RSSI2;
3105
3106 if (rssi0 != 0)
3107 {
3108 pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
3109 pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
3110 pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
3111 }
3112
3113 if (rssi1 != 0)
3114 {
3115 pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
3116 pRssi->AvgRssi1X8 = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
3117 pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
3118 }
3119
3120 if (rssi2 != 0)
3121 {
3122 pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
3123 pRssi->AvgRssi2X8 = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
3124 pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
3125 }
3126}
3127
3128
3129
3130// Normal legacy Rx packet indication
3131VOID Indicate_Legacy_Packet(
3132 IN PRTMP_ADAPTER pAd,
3133 IN RX_BLK *pRxBlk,
3134 IN UCHAR FromWhichBSSID)
3135{
3136 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
3137 UCHAR Header802_3[LENGTH_802_3];
3138
3139 // 1. get 802.3 Header
3140 // 2. remove LLC
3141 // a. pointer pRxBlk->pData to payload
3142 // b. modify pRxBlk->DataSize
3143#ifdef CONFIG_STA_SUPPORT
3144 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3145 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
3146#endif // CONFIG_STA_SUPPORT //
3147
3148 if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
3149 {
3150
3151 // release packet
3152 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
3153 return;
3154 }
3155
3156
3157 STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
3158
3159
3160 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
3161
3162 //
3163 // pass this 802.3 packet to upper layer or forward this packet to WM directly
3164 //
3165#ifdef CONFIG_STA_SUPPORT
3166 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3167 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
3168#endif // CONFIG_STA_SUPPORT //
3169
3170}
3171
3172
3173// Normal, AMPDU or AMSDU
3174VOID CmmRxnonRalinkFrameIndicate(
3175 IN PRTMP_ADAPTER pAd,
3176 IN RX_BLK *pRxBlk,
3177 IN UCHAR FromWhichBSSID)
3178{
3179#ifdef DOT11_N_SUPPORT
3180 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
3181 {
3182 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
3183 }
3184 else
3185#endif // DOT11_N_SUPPORT //
3186 {
3187#ifdef DOT11_N_SUPPORT
3188 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
3189 {
3190 // handle A-MSDU
3191 Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
3192 }
3193 else
3194#endif // DOT11_N_SUPPORT //
3195 {
3196 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
3197 }
3198 }
3199}
3200
3201
3202VOID CmmRxRalinkFrameIndicate(
3203 IN PRTMP_ADAPTER pAd,
3204 IN MAC_TABLE_ENTRY *pEntry,
3205 IN RX_BLK *pRxBlk,
3206 IN UCHAR FromWhichBSSID)
3207{
3208 UCHAR Header802_3[LENGTH_802_3];
3209 UINT16 Msdu2Size;
3210 UINT16 Payload1Size, Payload2Size;
3211 PUCHAR pData2;
3212 PNDIS_PACKET pPacket2 = NULL;
3213
3214
3215
3216 Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
3217
3218 if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
3219 {
3220 /* skip two byte MSDU2 len */
3221 pRxBlk->pData += 2;
3222 pRxBlk->DataSize -= 2;
3223 }
3224 else
3225 {
3226 // release packet
3227 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
3228 return;
3229 }
3230
3231 // get 802.3 Header and remove LLC
3232#ifdef CONFIG_STA_SUPPORT
3233 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3234 RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
3235#endif // CONFIG_STA_SUPPORT //
3236
3237
3238 ASSERT(pRxBlk->pRxPacket);
3239
3240 // Ralink Aggregation frame
3241 pAd->RalinkCounters.OneSecRxAggregationCount ++;
3242 Payload1Size = pRxBlk->DataSize - Msdu2Size;
3243 Payload2Size = Msdu2Size - LENGTH_802_3;
3244
3245 pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
3246#ifdef CONFIG_STA_SUPPORT
3247 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3248 pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
3249#endif // CONFIG_STA_SUPPORT //
3250
3251 if (!pPacket2)
3252 {
3253 // release packet
3254 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
3255 return;
3256 }
3257
3258 // update payload size of 1st packet
3259 pRxBlk->DataSize = Payload1Size;
3260 wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
3261
3262#ifdef CONFIG_STA_SUPPORT
3263 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3264 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
3265#endif // CONFIG_STA_SUPPORT //
3266
3267 if (pPacket2)
3268 {
3269#ifdef CONFIG_STA_SUPPORT
3270 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3271 ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
3272#endif // CONFIG_STA_SUPPORT //
3273 }
3274}
3275
3276
3277#define RESET_FRAGFRAME(_fragFrame) \
3278 { \
3279 _fragFrame.RxSize = 0; \
3280 _fragFrame.Sequence = 0; \
3281 _fragFrame.LastFrag = 0; \
3282 _fragFrame.Flags = 0; \
3283 }
3284
3285
3286PNDIS_PACKET RTMPDeFragmentDataFrame(
3287 IN PRTMP_ADAPTER pAd,
3288 IN RX_BLK *pRxBlk)
3289{
3290 PHEADER_802_11 pHeader = pRxBlk->pHeader;
3291 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
3292 UCHAR *pData = pRxBlk->pData;
3293 USHORT DataSize = pRxBlk->DataSize;
3294 PNDIS_PACKET pRetPacket = NULL;
3295 UCHAR *pFragBuffer = NULL;
3296 BOOLEAN bReassDone = FALSE;
3297 UCHAR HeaderRoom = 0;
3298
3299
3300 ASSERT(pHeader);
3301
3302 HeaderRoom = pData - (UCHAR *)pHeader;
3303
3304 // Re-assemble the fragmented packets
3305 if (pHeader->Frag == 0) // Frag. Number is 0 : First frag or only one pkt
3306 {
3307 // the first pkt of fragment, record it.
3308 if (pHeader->FC.MoreFrag)
3309 {
3310 ASSERT(pAd->FragFrame.pFragPacket);
3311 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
3312 pAd->FragFrame.RxSize = DataSize + HeaderRoom;
3313 NdisMoveMemory(pFragBuffer, pHeader, pAd->FragFrame.RxSize);
3314 pAd->FragFrame.Sequence = pHeader->Sequence;
3315 pAd->FragFrame.LastFrag = pHeader->Frag; // Should be 0
3316 ASSERT(pAd->FragFrame.LastFrag == 0);
3317 goto done; // end of processing this frame
3318 }
3319 }
3320 else //Middle & End of fragment
3321 {
3322 if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
3323 (pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
3324 {
3325 // Fragment is not the same sequence or out of fragment number order
3326 // Reset Fragment control blk
3327 RESET_FRAGFRAME(pAd->FragFrame);
3328 DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
3329 goto done; // give up this frame
3330 }
3331 else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
3332 {
3333 // Fragment frame is too large, it exeeds the maximum frame size.
3334 // Reset Fragment control blk
3335 RESET_FRAGFRAME(pAd->FragFrame);
3336 DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
3337 goto done; // give up this frame
3338 }
3339
3340 //
3341 // Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
3342 // In this case, we will dropt it.
3343 //
3344 if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
3345 {
3346 DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
3347 goto done; // give up this frame
3348 }
3349
3350 pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
3351
3352 // concatenate this fragment into the re-assembly buffer
3353 NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
3354 pAd->FragFrame.RxSize += DataSize;
3355 pAd->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
3356
3357 // Last fragment
3358 if (pHeader->FC.MoreFrag == FALSE)
3359 {
3360 bReassDone = TRUE;
3361 }
3362 }
3363
3364done:
3365 // always release rx fragmented packet
3366 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
3367
3368 // return defragmented packet if packet is reassembled completely
3369 // otherwise return NULL
3370 if (bReassDone)
3371 {
3372 PNDIS_PACKET pNewFragPacket;
3373
3374 // allocate a new packet buffer for fragment
3375 pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
3376 if (pNewFragPacket)
3377 {
3378 // update RxBlk
3379 pRetPacket = pAd->FragFrame.pFragPacket;
3380 pAd->FragFrame.pFragPacket = pNewFragPacket;
3381 pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
3382 pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
3383 pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
3384 pRxBlk->pRxPacket = pRetPacket;
3385 }
3386 else
3387 {
3388 RESET_FRAGFRAME(pAd->FragFrame);
3389 }
3390 }
3391
3392 return pRetPacket;
3393}
3394
3395
3396VOID Indicate_AMSDU_Packet(
3397 IN PRTMP_ADAPTER pAd,
3398 IN RX_BLK *pRxBlk,
3399 IN UCHAR FromWhichBSSID)
3400{
3401 UINT nMSDU;
3402
3403 update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
3404 RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
3405 nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
3406}
3407
3408VOID Indicate_EAPOL_Packet(
3409 IN PRTMP_ADAPTER pAd,
3410 IN RX_BLK *pRxBlk,
3411 IN UCHAR FromWhichBSSID)
3412{
3413 MAC_TABLE_ENTRY *pEntry = NULL;
3414
3415
3416#ifdef CONFIG_STA_SUPPORT
3417 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3418 {
3419 pEntry = &pAd->MacTab.Content[BSSID_WCID];
3420 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
3421 return;
3422 }
3423#endif // CONFIG_STA_SUPPORT //
3424
3425 if (pEntry == NULL)
3426 {
3427 DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
3428 // release packet
3429 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
3430 return;
3431 }
3432}
3433
3434#define BCN_TBTT_OFFSET 64 //defer 64 us
3435VOID ReSyncBeaconTime(
3436 IN PRTMP_ADAPTER pAd)
3437{
3438
3439 UINT32 Offset;
3440
3441
3442 Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
3443
3444 pAd->TbttTickCount++;
3445
3446 //
3447 // The updated BeaconInterval Value will affect Beacon Interval after two TBTT
3448 // beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
3449 //
3450 if (Offset == (BCN_TBTT_OFFSET-2))
3451 {
3452 BCN_TIME_CFG_STRUC csr;
3453 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
3454 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ; // ASIC register in units of 1/16 TU = 64us
3455 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
3456 }
3457 else
3458 {
3459 if (Offset == (BCN_TBTT_OFFSET-1))
3460 {
3461 BCN_TIME_CFG_STRUC csr;
3462
3463 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
3464 csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
3465 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
3466 }
3467 }
3468}
3469
diff --git a/drivers/staging/rt2860/common/cmm_data_2860.c b/drivers/staging/rt2860/common/cmm_data_2860.c
new file mode 100644
index 00000000000..4f414edd658
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_data_2860.c
@@ -0,0 +1,1240 @@
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 All functions in this file must be PCI-depended, or you should out your function
30 in other files.
31
32*/
33#include "../rt_config.h"
34
35extern RTMP_RF_REGS RF2850RegTable[];
36extern UCHAR NUM_OF_2850_CHNL;
37
38USHORT RtmpPCI_WriteTxResource(
39 IN PRTMP_ADAPTER pAd,
40 IN TX_BLK *pTxBlk,
41 IN BOOLEAN bIsLast,
42 OUT USHORT *FreeNumber)
43{
44
45 UCHAR *pDMAHeaderBufVA;
46 USHORT TxIdx, RetTxIdx;
47 PTXD_STRUC pTxD;
48 UINT32 BufBasePaLow;
49 PRTMP_TX_RING pTxRing;
50 USHORT hwHeaderLen;
51
52 //
53 // get Tx Ring Resource
54 //
55 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
56 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
57 pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
58 BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
59
60 // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
61 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
62 {
63 hwHeaderLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
64 }
65 else
66 {
67 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
68 }
69 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
70
71 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
72 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
73
74 //
75 // build Tx Descriptor
76 //
77
78 pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
79 NdisZeroMemory(pTxD, TXD_SIZE);
80
81 pTxD->SDPtr0 = BufBasePaLow;
82 pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
83 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
84 pTxD->SDLen1 = pTxBlk->SrcBufLen;
85 pTxD->LastSec0 = 0;
86 pTxD->LastSec1 = (bIsLast) ? 1 : 0;
87
88 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
89
90 RetTxIdx = TxIdx;
91 //
92 // Update Tx index
93 //
94 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
95 pTxRing->TxCpuIdx = TxIdx;
96
97 *FreeNumber -= 1;
98
99 return RetTxIdx;
100}
101
102
103USHORT RtmpPCI_WriteSingleTxResource(
104 IN PRTMP_ADAPTER pAd,
105 IN TX_BLK *pTxBlk,
106 IN BOOLEAN bIsLast,
107 OUT USHORT *FreeNumber)
108{
109
110 UCHAR *pDMAHeaderBufVA;
111 USHORT TxIdx, RetTxIdx;
112 PTXD_STRUC pTxD;
113#ifdef RT_BIG_ENDIAN
114 PTXD_STRUC pDestTxD;
115 TXD_STRUC TxD;
116#endif
117 UINT32 BufBasePaLow;
118 PRTMP_TX_RING pTxRing;
119 USHORT hwHeaderLen;
120
121 //
122 // get Tx Ring Resource
123 //
124 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
125 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
126 pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
127 BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
128
129 // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
130 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
131
132 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
133
134 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
135 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
136
137 //
138 // build Tx Descriptor
139 //
140#ifndef RT_BIG_ENDIAN
141 pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
142#else
143 pDestTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
144 TxD = *pDestTxD;
145 pTxD = &TxD;
146#endif
147 NdisZeroMemory(pTxD, TXD_SIZE);
148
149 pTxD->SDPtr0 = BufBasePaLow;
150 pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding
151 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
152 pTxD->SDLen1 = pTxBlk->SrcBufLen;
153 pTxD->LastSec0 = 0;
154 pTxD->LastSec1 = (bIsLast) ? 1 : 0;
155
156 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
157#ifdef RT_BIG_ENDIAN
158 RTMPWIEndianChange((PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE), TYPE_TXWI);
159 RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
160 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
161 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
162#endif // RT_BIG_ENDIAN //
163
164 RetTxIdx = TxIdx;
165 //
166 // Update Tx index
167 //
168 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
169 pTxRing->TxCpuIdx = TxIdx;
170
171 *FreeNumber -= 1;
172
173 return RetTxIdx;
174}
175
176
177USHORT RtmpPCI_WriteMultiTxResource(
178 IN PRTMP_ADAPTER pAd,
179 IN TX_BLK *pTxBlk,
180 IN UCHAR frameNum,
181 OUT USHORT *FreeNumber)
182{
183 BOOLEAN bIsLast;
184 UCHAR *pDMAHeaderBufVA;
185 USHORT TxIdx, RetTxIdx;
186 PTXD_STRUC pTxD;
187#ifdef RT_BIG_ENDIAN
188 PTXD_STRUC pDestTxD;
189 TXD_STRUC TxD;
190#endif
191 UINT32 BufBasePaLow;
192 PRTMP_TX_RING pTxRing;
193 USHORT hwHdrLen;
194 UINT32 firstDMALen;
195
196 bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0);
197
198 //
199 // get Tx Ring Resource
200 //
201 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
202 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
203 pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
204 BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
205
206 if (frameNum == 0)
207 {
208 // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
209 if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
210 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
211 hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
212 else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
213 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
214 hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
215 else
216 //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
217 hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
218
219 firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
220 }
221 else
222 {
223 firstDMALen = pTxBlk->MpduHeaderLen;
224 }
225
226 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
227
228 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
229 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
230
231 //
232 // build Tx Descriptor
233 //
234#ifndef RT_BIG_ENDIAN
235 pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
236#else
237 pDestTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
238 TxD = *pDestTxD;
239 pTxD = &TxD;
240#endif
241 NdisZeroMemory(pTxD, TXD_SIZE);
242
243 pTxD->SDPtr0 = BufBasePaLow;
244 pTxD->SDLen0 = firstDMALen; // include padding
245 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);;
246 pTxD->SDLen1 = pTxBlk->SrcBufLen;
247 pTxD->LastSec0 = 0;
248 pTxD->LastSec1 = (bIsLast) ? 1 : 0;
249
250 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
251
252#ifdef RT_BIG_ENDIAN
253 if (frameNum == 0)
254 RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
255
256 if (frameNum != 0)
257 RTMPWIEndianChange((PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE), TYPE_TXWI);
258
259 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
260 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
261#endif // RT_BIG_ENDIAN //
262
263 RetTxIdx = TxIdx;
264 //
265 // Update Tx index
266 //
267 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
268 pTxRing->TxCpuIdx = TxIdx;
269
270 *FreeNumber -= 1;
271
272 return RetTxIdx;
273
274}
275
276
277VOID RtmpPCI_FinalWriteTxResource(
278 IN PRTMP_ADAPTER pAd,
279 IN TX_BLK *pTxBlk,
280 IN USHORT totalMPDUSize,
281 IN USHORT FirstTxIdx)
282{
283
284 PTXWI_STRUC pTxWI;
285 PRTMP_TX_RING pTxRing;
286
287 //
288 // get Tx Ring Resource
289 //
290 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
291 pTxWI = (PTXWI_STRUC) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
292 pTxWI->MPDUtotalByteCount = totalMPDUSize;
293#ifdef RT_BIG_ENDIAN
294 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
295#endif // RT_BIG_ENDIAN //
296
297}
298
299
300VOID RtmpPCIDataLastTxIdx(
301 IN PRTMP_ADAPTER pAd,
302 IN UCHAR QueIdx,
303 IN USHORT LastTxIdx)
304{
305 PTXD_STRUC pTxD;
306#ifdef RT_BIG_ENDIAN
307 PTXD_STRUC pDestTxD;
308 TXD_STRUC TxD;
309#endif
310 PRTMP_TX_RING pTxRing;
311
312 //
313 // get Tx Ring Resource
314 //
315 pTxRing = &pAd->TxRing[QueIdx];
316
317 //
318 // build Tx Descriptor
319 //
320#ifndef RT_BIG_ENDIAN
321 pTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa;
322#else
323 pDestTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa;
324 TxD = *pDestTxD;
325 pTxD = &TxD;
326#endif
327
328 pTxD->LastSec1 = 1;
329
330#ifdef RT_BIG_ENDIAN
331 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
332 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
333#endif // RT_BIG_ENDIAN //
334
335}
336
337
338USHORT RtmpPCI_WriteFragTxResource(
339 IN PRTMP_ADAPTER pAd,
340 IN TX_BLK *pTxBlk,
341 IN UCHAR fragNum,
342 OUT USHORT *FreeNumber)
343{
344 UCHAR *pDMAHeaderBufVA;
345 USHORT TxIdx, RetTxIdx;
346 PTXD_STRUC pTxD;
347#ifdef RT_BIG_ENDIAN
348 PTXD_STRUC pDestTxD;
349 TXD_STRUC TxD;
350#endif
351 UINT32 BufBasePaLow;
352 PRTMP_TX_RING pTxRing;
353 USHORT hwHeaderLen;
354 UINT32 firstDMALen;
355
356 //
357 // Get Tx Ring Resource
358 //
359 pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
360 TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
361 pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
362 BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
363
364 //
365 // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
366 //
367 hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
368
369 firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;
370 NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
371
372
373 //
374 // Build Tx Descriptor
375 //
376#ifndef RT_BIG_ENDIAN
377 pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
378#else
379 pDestTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
380 TxD = *pDestTxD;
381 pTxD = &TxD;
382#endif
383 NdisZeroMemory(pTxD, TXD_SIZE);
384
385 if (fragNum == pTxBlk->TotalFragNum)
386 {
387 pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
388 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
389 }
390
391 pTxD->SDPtr0 = BufBasePaLow;
392 pTxD->SDLen0 = firstDMALen; // include padding
393 pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
394 pTxD->SDLen1 = pTxBlk->SrcBufLen;
395 pTxD->LastSec0 = 0;
396 pTxD->LastSec1 = 1;
397
398 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
399
400#ifdef RT_BIG_ENDIAN
401 RTMPWIEndianChange((PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE), TYPE_TXWI);
402 RTMPFrameEndianChange(pAd, (PUCHAR)(pDMAHeaderBufVA + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
403 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
404 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
405#endif // RT_BIG_ENDIAN //
406
407 RetTxIdx = TxIdx;
408 pTxBlk->Priv += pTxBlk->SrcBufLen;
409
410 //
411 // Update Tx index
412 //
413 INC_RING_INDEX(TxIdx, TX_RING_SIZE);
414 pTxRing->TxCpuIdx = TxIdx;
415
416 *FreeNumber -= 1;
417
418 return RetTxIdx;
419
420}
421
422/*
423 Must be run in Interrupt context
424 This function handle PCI specific TxDesc and cpu index update and kick the packet out.
425 */
426int RtmpPCIMgmtKickOut(
427 IN RTMP_ADAPTER *pAd,
428 IN UCHAR QueIdx,
429 IN PNDIS_PACKET pPacket,
430 IN PUCHAR pSrcBufVA,
431 IN UINT SrcBufLen)
432{
433 PTXD_STRUC pTxD;
434#ifdef RT_BIG_ENDIAN
435 PTXD_STRUC pDestTxD;
436 TXD_STRUC TxD;
437#endif
438 ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
439
440#ifdef RT_BIG_ENDIAN
441 pDestTxD = (PTXD_STRUC)pAd->MgmtRing.Cell[SwIdx].AllocVa;
442 TxD = *pDestTxD;
443 pTxD = &TxD;
444 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
445#else
446 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa;
447#endif
448
449 pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
450 pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
451
452 RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT);
453 pTxD->LastSec0 = 1;
454 pTxD->LastSec1 = 1;
455 pTxD->DMADONE = 0;
456 pTxD->SDLen1 = 0;
457 pTxD->SDPtr0 = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);;
458 pTxD->SDLen0 = SrcBufLen;
459
460#ifdef RT_BIG_ENDIAN
461 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
462 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
463#endif
464
465 pAd->RalinkCounters.KickTxCount++;
466 pAd->RalinkCounters.OneSecTxDoneCount++;
467
468 // Increase TX_CTX_IDX, but write to register later.
469 INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
470
471 RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
472
473 return 0;
474}
475
476
477#ifdef CONFIG_STA_SUPPORT
478/*
479 ========================================================================
480
481 Routine Description:
482 Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
483
484 Arguments:
485 pRxD Pointer to the Rx descriptor
486
487 Return Value:
488 NDIS_STATUS_SUCCESS No err
489 NDIS_STATUS_FAILURE Error
490
491 Note:
492
493 ========================================================================
494*/
495NDIS_STATUS RTMPCheckRxError(
496 IN PRTMP_ADAPTER pAd,
497 IN PHEADER_802_11 pHeader,
498 IN PRXWI_STRUC pRxWI,
499 IN PRT28XX_RXD_STRUC pRxD)
500{
501 PCIPHER_KEY pWpaKey;
502 INT dBm;
503
504 // Phy errors & CRC errors
505 if (/*(pRxD->PhyErr) ||*/ (pRxD->Crc))
506 {
507 // Check RSSI for Noise Hist statistic collection.
508 dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
509 if (dBm <= -87)
510 pAd->StaCfg.RPIDensity[0] += 1;
511 else if (dBm <= -82)
512 pAd->StaCfg.RPIDensity[1] += 1;
513 else if (dBm <= -77)
514 pAd->StaCfg.RPIDensity[2] += 1;
515 else if (dBm <= -72)
516 pAd->StaCfg.RPIDensity[3] += 1;
517 else if (dBm <= -67)
518 pAd->StaCfg.RPIDensity[4] += 1;
519 else if (dBm <= -62)
520 pAd->StaCfg.RPIDensity[5] += 1;
521 else if (dBm <= -57)
522 pAd->StaCfg.RPIDensity[6] += 1;
523 else if (dBm > -57)
524 pAd->StaCfg.RPIDensity[7] += 1;
525
526 return(NDIS_STATUS_FAILURE);
527 }
528
529 // Add Rx size to channel load counter, we should ignore error counts
530 pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14);
531
532 // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
533 if (pHeader != NULL)
534 {
535 if (pHeader->FC.ToDs)
536 {
537 return(NDIS_STATUS_FAILURE);
538 }
539 }
540
541 // Drop not U2M frames, cant's drop here because we will drop beacon in this case
542 // I am kind of doubting the U2M bit operation
543 // if (pRxD->U2M == 0)
544 // return(NDIS_STATUS_FAILURE);
545
546 // drop decyption fail frame
547 if (pRxD->CipherErr)
548 {
549 if (pRxD->CipherErr == 2)
550 {DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV ok but MICErr "));}
551 else if (pRxD->CipherErr == 1)
552 {DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV Err "));}
553 else if (pRxD->CipherErr == 3)
554 DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: Key not valid "));
555
556 if (((pRxD->CipherErr & 1) == 1) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
557 RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
558
559 DBGPRINT_RAW(RT_DEBUG_TRACE,(" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n",
560 pRxD->CipherErr,
561 pRxD->SDL0,
562 pRxD->Mcast | pRxD->Bcast,
563 pRxD->MyBss,
564 pRxWI->WirelessCliID,
565 pRxWI->KeyIndex));
566
567 //
568 // MIC Error
569 //
570 if (pRxD->CipherErr == 2)
571 {
572 pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
573#ifdef WPA_SUPPLICANT_SUPPORT
574 if (pAd->StaCfg.WpaSupplicantUP)
575 WpaSendMicFailureToWpaSupplicant(pAd,
576 (pWpaKey->Type == PAIRWISEKEY) ? TRUE:FALSE);
577 else
578#endif // WPA_SUPPLICANT_SUPPORT //
579 RTMPReportMicError(pAd, pWpaKey);
580
581 if (((pRxD->CipherErr & 2) == 2) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
582 RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
583
584 DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
585 }
586
587 if (pHeader == NULL)
588 return(NDIS_STATUS_SUCCESS);
589
590 return(NDIS_STATUS_FAILURE);
591 }
592
593 return(NDIS_STATUS_SUCCESS);
594}
595
596/*
597 ==========================================================================
598 Description:
599 This routine sends command to firmware and turn our chip to power save mode.
600 Both RadioOff and .11 power save function needs to call this routine.
601 Input:
602 Level = GUIRADIO_OFF : GUI Radio Off mode
603 Level = DOT11POWERSAVE : 802.11 power save mode
604 Level = RTMP_HALT : When Disable device.
605
606 ==========================================================================
607 */
608VOID RT28xxPciAsicRadioOff(
609 IN PRTMP_ADAPTER pAd,
610 IN UCHAR Level,
611 IN USHORT TbttNumToNextWakeUp)
612{
613 WPDMA_GLO_CFG_STRUC DmaCfg;
614 UCHAR i, tempBBP_R3 = 0;
615 BOOLEAN brc = FALSE, Cancelled;
616 UINT32 TbTTTime = 0;
617 UINT32 PsPollTime = 0, MACValue;
618 ULONG BeaconPeriodTime;
619 UINT32 RxDmaIdx, RxCpuIdx;
620 DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> TxCpuIdx = %d, TxDmaIdx = %d. RxCpuIdx = %d, RxDmaIdx = %d.\n", pAd->TxRing[0].TxCpuIdx, pAd->TxRing[0].TxDmaIdx, pAd->RxRing.RxCpuIdx, pAd->RxRing.RxDmaIdx));
621
622 // Check Rx DMA busy status, if more than half is occupied, give up this radio off.
623 RTMP_IO_READ32(pAd, RX_DRX_IDX , &RxDmaIdx);
624 RTMP_IO_READ32(pAd, RX_CRX_IDX , &RxCpuIdx);
625 if ((RxDmaIdx > RxCpuIdx) && ((RxDmaIdx - RxCpuIdx) > RX_RING_SIZE/3))
626 {
627 DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return1. RxDmaIdx = %d , RxCpuIdx = %d. \n", RxDmaIdx, RxCpuIdx));
628 return;
629 }
630 else if ((RxCpuIdx >= RxDmaIdx) && ((RxCpuIdx - RxDmaIdx) < RX_RING_SIZE/3))
631 {
632 DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return2. RxCpuIdx = %d. RxDmaIdx = %d , \n", RxCpuIdx, RxDmaIdx));
633 return;
634 }
635
636 // Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops.
637 pAd->bPCIclkOffDisableTx = TRUE;
638
639 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
640 {
641 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
642 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
643
644 if (Level == DOT11POWERSAVE)
645 {
646 RTMP_IO_READ32(pAd, TBTT_TIMER, &TbTTTime);
647 TbTTTime &= 0x1ffff;
648 // 00. check if need to do sleep in this DTIM period. If next beacon will arrive within 30ms , ...doesn't necessarily sleep.
649 // TbTTTime uint = 64us, LEAD_TIME unit = 1024us, PsPollTime unit = 1ms
650 if (((64*TbTTTime) <((LEAD_TIME*1024) + 40000)) && (TbttNumToNextWakeUp == 0))
651 {
652 DBGPRINT(RT_DEBUG_TRACE, ("TbTTTime = 0x%x , give up this sleep. \n", TbTTTime));
653 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
654 pAd->bPCIclkOffDisableTx = FALSE;
655 return;
656 }
657 else
658 {
659 PsPollTime = (64*TbTTTime- LEAD_TIME*1024)/1000;
660 PsPollTime -= 3;
661
662 BeaconPeriodTime = pAd->CommonCfg.BeaconPeriod*102/100;
663 if (TbttNumToNextWakeUp > 0)
664 PsPollTime += ((TbttNumToNextWakeUp -1) * BeaconPeriodTime);
665
666 pAd->Mlme.bPsPollTimerRunning = TRUE;
667 RTMPSetTimer(&pAd->Mlme.PsPollTimer, PsPollTime);
668 }
669 }
670 }
671
672 // 0. Disable Tx DMA.
673 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
674 DmaCfg.field.EnableTxDMA = 0;
675 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
676
677 // 1. Wait DMA not busy
678 i = 0;
679 do
680 {
681 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
682 if ((DmaCfg.field.TxDMABusy == 0) && (DmaCfg.field.RxDMABusy == 0))
683 break;
684 RTMPusecDelay(20);
685 i++;
686 }while(i < 50);
687
688 if (i >= 50)
689 {
690 DBGPRINT(RT_DEBUG_TRACE, ("DMA keeps busy. return on RT28xxPciAsicRadioOff ()\n"));
691 pAd->bPCIclkOffDisableTx = FALSE;
692 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
693 DmaCfg.field.EnableTxDMA = 1;
694 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
695 return;
696 }
697
698 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
699
700 // Set to 1R.
701 tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
702 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
703
704 // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
705 if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
706 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
707 {
708 // Must using 40MHz.
709 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
710 }
711 else
712 {
713 // Must using 20MHz.
714 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
715 }
716
717 // When PCI clock is off, don't want to service interrupt.
718 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
719
720 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
721 // Disable MAC Rx
722 RTMP_IO_READ32(pAd, MAC_SYS_CTRL , &MACValue);
723 MACValue &= 0xf7;
724 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL , MACValue);
725
726 // 2. Send Sleep command
727 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
728 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
729 AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x00); // send POWER-SAVE command to MCU. Timeout unit:40us.
730 // 2-1. Wait command success
731 // Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task.
732 brc = AsicCheckCommanOk(pAd, PowerSafeCID);
733
734 if (brc == FALSE)
735 {
736 // try again
737 AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x00); // send POWER-SAVE command to MCU. Timeout unit:40us.
738 //RTMPusecDelay(200);
739 brc = AsicCheckCommanOk(pAd, PowerSafeCID);
740 }
741
742 // 3. After 0x30 command is ok, send radio off command. lowbyte = 0 for power safe.
743 // If 0x30 command is not ok this time, we can ignore 0x35 command. It will make sure not cause firmware'r problem.
744 if ((Level == DOT11POWERSAVE) && (brc == TRUE))
745 {
746 AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 0, 0x00); // lowbyte = 0 means to do power safe, NOT turn off radio.
747 // 3-1. Wait command success
748 AsicCheckCommanOk(pAd, PowerRadioOffCID);
749 }
750 else if (brc == TRUE)
751 {
752 AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 1, 0x00); // lowbyte = 0 means to do power safe, NOT turn off radio.
753 // 3-1. Wait command success
754 AsicCheckCommanOk(pAd, PowerRadioOffCID);
755 }
756
757 // Wait DMA not busy
758 i = 0;
759 do
760 {
761 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
762 if (DmaCfg.field.RxDMABusy == 0)
763 break;
764 RTMPusecDelay(20);
765 i++;
766 }while(i < 50);
767
768 if (i >= 50)
769 {
770 DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy. on RT28xxPciAsicRadioOff ()\n"));
771 }
772 // disable DMA Rx.
773 {
774 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
775 DmaCfg.field.EnableRxDMA = 0;
776 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
777 }
778
779 if (Level == DOT11POWERSAVE)
780 {
781 AUTO_WAKEUP_STRUC AutoWakeupCfg;
782 //RTMPSetTimer(&pAd->Mlme.PsPollTimer, 90);
783
784 // we have decided to SLEEP, so at least do it for a BEACON period.
785 if (TbttNumToNextWakeUp == 0)
786 TbttNumToNextWakeUp = 1;
787
788 AutoWakeupCfg.word = 0;
789 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
790
791 // 1. Set auto wake up timer.
792 AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
793 AutoWakeupCfg.field.EnableAutoWakeup = 1;
794 AutoWakeupCfg.field.AutoLeadTime = LEAD_TIME;
795 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
796 }
797
798 // 4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value.
799 if (Level == RTMP_HALT)
800 {
801 if ((brc == TRUE) && (i < 50))
802 RTMPPCIeLinkCtrlSetting(pAd, 1);
803 }
804 // 4. Set PCI configuration Space Link Comtrol fields. Only Radio Off needs to call this function
805 else
806 {
807 if ((brc == TRUE) && (i < 50))
808 RTMPPCIeLinkCtrlSetting(pAd, 3);
809 }
810
811 pAd->bPCIclkOffDisableTx = FALSE;
812}
813
814
815/*
816 ==========================================================================
817 Description:
818 This routine sends command to firmware and turn our chip to wake up mode from power save mode.
819 Both RadioOn and .11 power save function needs to call this routine.
820 Input:
821 Level = GUIRADIO_OFF : call this function is from Radio Off to Radio On. Need to restore PCI host value.
822 Level = other value : normal wake up function.
823
824 ==========================================================================
825 */
826BOOLEAN RT28xxPciAsicRadioOn(
827 IN PRTMP_ADAPTER pAd,
828 IN UCHAR Level)
829{
830 WPDMA_GLO_CFG_STRUC DmaCfg;
831 BOOLEAN Cancelled, brv = TRUE;
832 UINT32 MACValue;
833
834 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
835 {
836 pAd->Mlme.bPsPollTimerRunning = FALSE;
837 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
838 if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE))
839 {
840 DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n"));
841 // 1. Set PCI Link Control in Configuration Space.
842 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
843 RTMPusecDelay(6000);
844 }
845 }
846
847 pAd->bPCIclkOff = FALSE;
848
849 // 2. Send wake up command.
850 AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
851
852 // 2-1. wait command ok.
853 brv = AsicCheckCommanOk(pAd, PowerWakeCID);
854 if (brv)
855 {
856 //RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT));
857 NICEnableInterrupt(pAd);
858
859 // 3. Enable Tx DMA.
860 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
861 DmaCfg.field.EnableTxDMA = 1;
862 DmaCfg.field.EnableRxDMA = 1;
863 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
864
865 // Eable MAC Rx
866 RTMP_IO_READ32(pAd, MAC_SYS_CTRL , &MACValue);
867 MACValue |= 0x8;
868 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL , MACValue);
869
870 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
871 if (Level == GUI_IDLE_POWER_SAVE)
872 {
873 // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
874 if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
875 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
876 {
877 // Must using 40MHz.
878 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
879 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
880 }
881 else
882 {
883 // Must using 20MHz.
884 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
885 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
886 }
887 }
888 return TRUE;
889 }
890 else
891 return FALSE;
892}
893
894VOID RT28xxPciStaAsicForceWakeup(
895 IN PRTMP_ADAPTER pAd,
896 IN BOOLEAN bFromTx)
897{
898 AUTO_WAKEUP_STRUC AutoWakeupCfg;
899
900 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
901 return;
902
903 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
904 {
905 DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
906 return;
907 }
908
909 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
910
911 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
912 {
913 // Support PCIe Advance Power Save
914 if (bFromTx == TRUE)
915 {
916 pAd->Mlme.bPsPollTimerRunning = FALSE;
917 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
918 RTMPusecDelay(3000);
919 DBGPRINT(RT_DEBUG_TRACE, ("=======AsicForceWakeup===bFromTx\n"));
920 }
921
922 AutoWakeupCfg.word = 0;
923 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
924
925 if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
926 {
927 // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
928 if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
929 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
930 {
931 // Must using 40MHz.
932 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
933 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
934 }
935 else
936 {
937 // Must using 20MHz.
938 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
939 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
940 }
941 }
942 }
943 else
944 {
945 // PCI, 2860-PCIe
946 AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x00);
947 AutoWakeupCfg.word = 0;
948 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
949 }
950
951 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
952 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
953 DBGPRINT(RT_DEBUG_TRACE, ("<=======RT28xxPciStaAsicForceWakeup\n"));
954}
955
956VOID RT28xxPciStaAsicSleepThenAutoWakeup(
957 IN PRTMP_ADAPTER pAd,
958 IN USHORT TbttNumToNextWakeUp)
959{
960 if (pAd->StaCfg.bRadio == FALSE)
961 {
962 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
963 return;
964 }
965 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
966 {
967 ULONG Now = 0;
968 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
969 {
970 DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
971 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
972 return;
973 }
974
975 NdisGetSystemUpTime(&Now);
976 // If last send NULL fram time is too close to this receiving beacon (within 8ms), don't go to sleep for this DTM.
977 // Because Some AP can't queuing outgoing frames immediately.
978 if (((pAd->Mlme.LastSendNULLpsmTime + 8) >= Now) && (pAd->Mlme.LastSendNULLpsmTime <= Now))
979 {
980 DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu : RxCountSinceLastNULL = %lu. \n", Now, pAd->Mlme.LastSendNULLpsmTime, pAd->RalinkCounters.RxCountSinceLastNULL));
981 return;
982 }
983 else if ((pAd->RalinkCounters.RxCountSinceLastNULL > 0) && ((pAd->Mlme.LastSendNULLpsmTime + pAd->CommonCfg.BeaconPeriod) >= Now))
984 {
985 DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu: RxCountSinceLastNULL = %lu > 0 \n", Now, pAd->Mlme.LastSendNULLpsmTime, pAd->RalinkCounters.RxCountSinceLastNULL));
986 return;
987 }
988
989 RT28xxPciAsicRadioOff(pAd, DOT11POWERSAVE, TbttNumToNextWakeUp);
990 }
991 else
992 {
993 AUTO_WAKEUP_STRUC AutoWakeupCfg;
994 // we have decided to SLEEP, so at least do it for a BEACON period.
995 if (TbttNumToNextWakeUp == 0)
996 TbttNumToNextWakeUp = 1;
997
998 AutoWakeupCfg.word = 0;
999 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1000 AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
1001 AutoWakeupCfg.field.EnableAutoWakeup = 1;
1002 AutoWakeupCfg.field.AutoLeadTime = 5;
1003 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1004 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x00); // send POWER-SAVE command to MCU. Timeout 40us.
1005 DBGPRINT(RT_DEBUG_TRACE, ("<-- %s, TbttNumToNextWakeUp=%d \n", __FUNCTION__, TbttNumToNextWakeUp));
1006 }
1007 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
1008}
1009
1010VOID PsPollWakeExec(
1011 IN PVOID SystemSpecific1,
1012 IN PVOID FunctionContext,
1013 IN PVOID SystemSpecific2,
1014 IN PVOID SystemSpecific3)
1015{
1016 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
1017 unsigned long flags;
1018
1019 DBGPRINT(RT_DEBUG_TRACE,("-->PsPollWakeExec \n"));
1020 RTMP_INT_LOCK(&pAd->irq_lock, flags);
1021 if (pAd->Mlme.bPsPollTimerRunning)
1022 {
1023 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
1024 }
1025 pAd->Mlme.bPsPollTimerRunning = FALSE;
1026 RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
1027}
1028
1029VOID RadioOnExec(
1030 IN PVOID SystemSpecific1,
1031 IN PVOID FunctionContext,
1032 IN PVOID SystemSpecific2,
1033 IN PVOID SystemSpecific3)
1034{
1035 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
1036 WPDMA_GLO_CFG_STRUC DmaCfg;
1037 BOOLEAN Cancelled;
1038
1039 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1040 {
1041 DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n"));
1042 RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
1043 return;
1044 }
1045
1046 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1047 {
1048 DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n"));
1049 RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
1050 return;
1051 }
1052 pAd->Mlme.bPsPollTimerRunning = FALSE;
1053 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1054 if (pAd->StaCfg.bRadio == TRUE)
1055 {
1056 pAd->bPCIclkOff = FALSE;
1057 RTMPRingCleanUp(pAd, QID_AC_BK);
1058 RTMPRingCleanUp(pAd, QID_AC_BE);
1059 RTMPRingCleanUp(pAd, QID_AC_VI);
1060 RTMPRingCleanUp(pAd, QID_AC_VO);
1061 RTMPRingCleanUp(pAd, QID_HCCA);
1062 RTMPRingCleanUp(pAd, QID_MGMT);
1063 RTMPRingCleanUp(pAd, QID_RX);
1064
1065 // 2. Send wake up command.
1066 AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
1067 // 2-1. wait command ok.
1068 AsicCheckCommanOk(pAd, PowerWakeCID);
1069
1070 // When PCI clock is off, don't want to service interrupt. So when back to clock on, enable interrupt.
1071 NICEnableInterrupt(pAd);
1072
1073 // 3. Enable Tx DMA.
1074 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
1075 DmaCfg.field.EnableTxDMA = 1;
1076 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
1077
1078 // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
1079 if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
1080 && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1081 {
1082 // Must using 40MHz.
1083 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1084 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1085 }
1086 else
1087 {
1088 // Must using 20MHz.
1089 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1090 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1091 }
1092
1093 // Clear Radio off flag
1094 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1095
1096 // Set LED
1097 RTMPSetLED(pAd, LED_RADIO_ON);
1098
1099 if (pAd->StaCfg.Psm == PWR_ACTIVE)
1100 {
1101 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
1102 }
1103 }
1104 else
1105 {
1106 RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
1107 }
1108}
1109
1110#endif // CONFIG_STA_SUPPORT //
1111
1112VOID RT28xxPciMlmeRadioOn(
1113 IN PRTMP_ADAPTER pAd)
1114{
1115 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1116 return;
1117
1118 DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __FUNCTION__));
1119
1120 if ((pAd->OpMode == OPMODE_AP) ||
1121 ((pAd->OpMode == OPMODE_STA) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))))
1122 {
1123 NICResetFromError(pAd);
1124
1125 RTMPRingCleanUp(pAd, QID_AC_BK);
1126 RTMPRingCleanUp(pAd, QID_AC_BE);
1127 RTMPRingCleanUp(pAd, QID_AC_VI);
1128 RTMPRingCleanUp(pAd, QID_AC_VO);
1129 RTMPRingCleanUp(pAd, QID_HCCA);
1130 RTMPRingCleanUp(pAd, QID_MGMT);
1131 RTMPRingCleanUp(pAd, QID_RX);
1132
1133 // Enable Tx/Rx
1134 RTMPEnableRxTx(pAd);
1135
1136 // Clear Radio off flag
1137 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1138
1139 // Set LED
1140 RTMPSetLED(pAd, LED_RADIO_ON);
1141 }
1142
1143#ifdef CONFIG_STA_SUPPORT
1144 if ((pAd->OpMode == OPMODE_STA) &&
1145 (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)))
1146 {
1147 BOOLEAN Cancelled;
1148
1149 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
1150
1151 pAd->Mlme.bPsPollTimerRunning = FALSE;
1152 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1153 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
1154 RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
1155 }
1156#endif // CONFIG_STA_SUPPORT //
1157}
1158
1159VOID RT28xxPciMlmeRadioOFF(
1160 IN PRTMP_ADAPTER pAd)
1161{
1162 WPDMA_GLO_CFG_STRUC GloCfg;
1163 UINT32 i;
1164
1165 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
1166 return;
1167
1168 DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __FUNCTION__));
1169
1170 // Set LED
1171 RTMPSetLED(pAd, LED_RADIO_OFF);
1172 // Set Radio off flag
1173 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1174
1175#ifdef CONFIG_STA_SUPPORT
1176 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1177 {
1178 BOOLEAN Cancelled;
1179 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1180 {
1181 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
1182 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1183 }
1184
1185 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1186 {
1187 BOOLEAN Cancelled;
1188 pAd->Mlme.bPsPollTimerRunning = FALSE;
1189 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1190 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
1191 }
1192
1193 // Link down first if any association exists
1194 if (INFRA_ON(pAd) || ADHOC_ON(pAd))
1195 LinkDown(pAd, FALSE);
1196 RTMPusecDelay(10000);
1197 //==========================================
1198 // Clean up old bss table
1199 BssTableInit(&pAd->ScanTab);
1200 }
1201#endif // CONFIG_STA_SUPPORT //
1202
1203 // Disable Tx/Rx DMA
1204 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
1205 GloCfg.field.EnableTxDMA = 0;
1206 GloCfg.field.EnableRxDMA = 0;
1207 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings
1208
1209
1210 // MAC_SYS_CTRL => value = 0x0 => 40mA
1211 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0);
1212
1213 // PWR_PIN_CFG => value = 0x0 => 40mA
1214 RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0);
1215
1216 // TX_PIN_CFG => value = 0x0 => 20mA
1217 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, 0);
1218
1219 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
1220 {
1221 // Must using 40MHz.
1222 AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
1223 }
1224 else
1225 {
1226 // Must using 20MHz.
1227 AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
1228 }
1229
1230 // Waiting for DMA idle
1231 i = 0;
1232 do
1233 {
1234 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1235 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1236 break;
1237
1238 RTMPusecDelay(1000);
1239 }while (i++ < 100);
1240}
diff --git a/drivers/staging/rt2860/common/cmm_info.c b/drivers/staging/rt2860/common/cmm_info.c
new file mode 100644
index 00000000000..0aadf8af633
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_info.c
@@ -0,0 +1,3417 @@
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#ifdef RT2860
818 INT i, QueIdx=0;
819 PRT28XX_RXD_STRUC pRxD;
820 PTXD_STRUC pTxD;
821 PRTMP_TX_RING pTxRing = &pAd->TxRing[QueIdx];
822 PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing;
823 PRTMP_RX_RING pRxRing = &pAd->RxRing;
824
825 for(i=0;i<TX_RING_SIZE;i++)
826 {
827 pTxD = (PTXD_STRUC) pTxRing->Cell[i].AllocVa;
828 printk("Desc #%d\n",i);
829 hex_dump("Tx Descriptor", (char *)pTxD, 16);
830 printk("pTxD->DMADONE = %x\n", pTxD->DMADONE);
831 }
832 printk("---------------------------------------------------\n");
833 for(i=0;i<MGMT_RING_SIZE;i++)
834 {
835 pTxD = (PTXD_STRUC) pMgmtRing->Cell[i].AllocVa;
836 printk("Desc #%d\n",i);
837 hex_dump("Mgmt Descriptor", (char *)pTxD, 16);
838 printk("pMgmt->DMADONE = %x\n", pTxD->DMADONE);
839 }
840 printk("---------------------------------------------------\n");
841 for(i=0;i<RX_RING_SIZE;i++)
842 {
843 pRxD = (PRT28XX_RXD_STRUC) pRxRing->Cell[i].AllocVa;
844 printk("Desc #%d\n",i);
845 hex_dump("Rx Descriptor", (char *)pRxD, 16);
846 printk("pRxD->DDONE = %x\n", pRxD->DDONE);
847 }
848#endif // RT2860 //
849
850 return TRUE;
851}
852
853/*
854 ==========================================================================
855 Description:
856 Reset statistics counter
857
858 Arguments:
859 pAdapter Pointer to our adapter
860 arg
861
862 Return:
863 TRUE if all parameters are OK, FALSE otherwise
864 ==========================================================================
865*/
866INT Set_ResetStatCounter_Proc(
867 IN PRTMP_ADAPTER pAd,
868 IN PUCHAR arg)
869{
870 DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n"));
871
872 // add the most up-to-date h/w raw counters into software counters
873 NICUpdateRawCounters(pAd);
874
875 NdisZeroMemory(&pAd->WlanCounters, sizeof(COUNTER_802_11));
876 NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3));
877 NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK));
878
879 return TRUE;
880}
881
882BOOLEAN RTMPCheckStrPrintAble(
883 IN CHAR *pInPutStr,
884 IN UCHAR strLen)
885{
886 UCHAR i=0;
887
888 for (i=0; i<strLen; i++)
889 {
890 if ((pInPutStr[i] < 0x21) ||
891 (pInPutStr[i] > 0x7E))
892 return FALSE;
893 }
894
895 return TRUE;
896}
897
898/*
899 ========================================================================
900
901 Routine Description:
902 Remove WPA Key process
903
904 Arguments:
905 pAd Pointer to our adapter
906 pBuf Pointer to the where the key stored
907
908 Return Value:
909 NDIS_SUCCESS Add key successfully
910
911 IRQL = DISPATCH_LEVEL
912
913 Note:
914
915 ========================================================================
916*/
917#ifdef CONFIG_STA_SUPPORT
918VOID RTMPSetDesiredRates(
919 IN PRTMP_ADAPTER pAdapter,
920 IN LONG Rates)
921{
922 NDIS_802_11_RATES aryRates;
923
924 memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
925 switch (pAdapter->CommonCfg.PhyMode)
926 {
927 case PHY_11A: // A only
928 switch (Rates)
929 {
930 case 6000000: //6M
931 aryRates[0] = 0x0c; // 6M
932 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
933 break;
934 case 9000000: //9M
935 aryRates[0] = 0x12; // 9M
936 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
937 break;
938 case 12000000: //12M
939 aryRates[0] = 0x18; // 12M
940 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
941 break;
942 case 18000000: //18M
943 aryRates[0] = 0x24; // 18M
944 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
945 break;
946 case 24000000: //24M
947 aryRates[0] = 0x30; // 24M
948 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
949 break;
950 case 36000000: //36M
951 aryRates[0] = 0x48; // 36M
952 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
953 break;
954 case 48000000: //48M
955 aryRates[0] = 0x60; // 48M
956 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
957 break;
958 case 54000000: //54M
959 aryRates[0] = 0x6c; // 54M
960 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
961 break;
962 case -1: //Auto
963 default:
964 aryRates[0] = 0x6c; // 54Mbps
965 aryRates[1] = 0x60; // 48Mbps
966 aryRates[2] = 0x48; // 36Mbps
967 aryRates[3] = 0x30; // 24Mbps
968 aryRates[4] = 0x24; // 18M
969 aryRates[5] = 0x18; // 12M
970 aryRates[6] = 0x12; // 9M
971 aryRates[7] = 0x0c; // 6M
972 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
973 break;
974 }
975 break;
976 case PHY_11BG_MIXED: // B/G Mixed
977 case PHY_11B: // B only
978 case PHY_11ABG_MIXED: // A/B/G Mixed
979 default:
980 switch (Rates)
981 {
982 case 1000000: //1M
983 aryRates[0] = 0x02;
984 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
985 break;
986 case 2000000: //2M
987 aryRates[0] = 0x04;
988 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
989 break;
990 case 5000000: //5.5M
991 aryRates[0] = 0x0b; // 5.5M
992 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
993 break;
994 case 11000000: //11M
995 aryRates[0] = 0x16; // 11M
996 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
997 break;
998 case 6000000: //6M
999 aryRates[0] = 0x0c; // 6M
1000 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
1001 break;
1002 case 9000000: //9M
1003 aryRates[0] = 0x12; // 9M
1004 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
1005 break;
1006 case 12000000: //12M
1007 aryRates[0] = 0x18; // 12M
1008 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
1009 break;
1010 case 18000000: //18M
1011 aryRates[0] = 0x24; // 18M
1012 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
1013 break;
1014 case 24000000: //24M
1015 aryRates[0] = 0x30; // 24M
1016 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
1017 break;
1018 case 36000000: //36M
1019 aryRates[0] = 0x48; // 36M
1020 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
1021 break;
1022 case 48000000: //48M
1023 aryRates[0] = 0x60; // 48M
1024 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
1025 break;
1026 case 54000000: //54M
1027 aryRates[0] = 0x6c; // 54M
1028 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
1029 break;
1030 case -1: //Auto
1031 default:
1032 if (pAdapter->CommonCfg.PhyMode == PHY_11B)
1033 { //B Only
1034 aryRates[0] = 0x16; // 11Mbps
1035 aryRates[1] = 0x0b; // 5.5Mbps
1036 aryRates[2] = 0x04; // 2Mbps
1037 aryRates[3] = 0x02; // 1Mbps
1038 }
1039 else
1040 { //(B/G) Mixed or (A/B/G) Mixed
1041 aryRates[0] = 0x6c; // 54Mbps
1042 aryRates[1] = 0x60; // 48Mbps
1043 aryRates[2] = 0x48; // 36Mbps
1044 aryRates[3] = 0x30; // 24Mbps
1045 aryRates[4] = 0x16; // 11Mbps
1046 aryRates[5] = 0x0b; // 5.5Mbps
1047 aryRates[6] = 0x04; // 2Mbps
1048 aryRates[7] = 0x02; // 1Mbps
1049 }
1050 pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
1051 break;
1052 }
1053 break;
1054 }
1055
1056 NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
1057 NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
1058 DBGPRINT(RT_DEBUG_TRACE, (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
1059 pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
1060 pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
1061 pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
1062 pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
1063 // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
1064 MlmeUpdateTxRates(pAdapter, FALSE, 0);
1065}
1066
1067NDIS_STATUS RTMPWPARemoveKeyProc(
1068 IN PRTMP_ADAPTER pAd,
1069 IN PVOID pBuf)
1070{
1071 PNDIS_802_11_REMOVE_KEY pKey;
1072 ULONG KeyIdx;
1073 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
1074 BOOLEAN bTxKey; // Set the key as transmit key
1075 BOOLEAN bPairwise; // Indicate the key is pairwise key
1076 BOOLEAN bKeyRSC; // indicate the receive SC set by KeyRSC value.
1077 // Otherwise, it will set by the NIC.
1078 BOOLEAN bAuthenticator; // indicate key is set by authenticator.
1079 INT i;
1080
1081 DBGPRINT(RT_DEBUG_TRACE,("---> RTMPWPARemoveKeyProc\n"));
1082
1083 pKey = (PNDIS_802_11_REMOVE_KEY) pBuf;
1084 KeyIdx = pKey->KeyIndex & 0xff;
1085 // Bit 31 of Add-key, Tx Key
1086 bTxKey = (pKey->KeyIndex & 0x80000000) ? TRUE : FALSE;
1087 // Bit 30 of Add-key PairwiseKey
1088 bPairwise = (pKey->KeyIndex & 0x40000000) ? TRUE : FALSE;
1089 // Bit 29 of Add-key KeyRSC
1090 bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
1091 // Bit 28 of Add-key Authenticator
1092 bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
1093
1094 // 1. If bTx is TRUE, return failure information
1095 if (bTxKey == TRUE)
1096 return(NDIS_STATUS_INVALID_DATA);
1097
1098 // 2. Check Pairwise Key
1099 if (bPairwise)
1100 {
1101 // a. If BSSID is broadcast, remove all pairwise keys.
1102 // b. If not broadcast, remove the pairwise specified by BSSID
1103 for (i = 0; i < SHARE_KEY_NUM; i++)
1104 {
1105 if (MAC_ADDR_EQUAL(pAd->SharedKey[BSS0][i].BssId, pKey->BSSID))
1106 {
1107 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%d)\n", i));
1108 pAd->SharedKey[BSS0][i].KeyLen = 0;
1109 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
1110 AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)i);
1111 Status = NDIS_STATUS_SUCCESS;
1112 break;
1113 }
1114 }
1115 }
1116 // 3. Group Key
1117 else
1118 {
1119 // a. If BSSID is broadcast, remove all group keys indexed
1120 // b. If BSSID matched, delete the group key indexed.
1121 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%ld)\n", KeyIdx));
1122 pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
1123 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
1124 AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx);
1125 Status = NDIS_STATUS_SUCCESS;
1126 }
1127
1128 return (Status);
1129}
1130#endif // CONFIG_STA_SUPPORT //
1131
1132
1133#ifdef CONFIG_STA_SUPPORT
1134/*
1135 ========================================================================
1136
1137 Routine Description:
1138 Remove All WPA Keys
1139
1140 Arguments:
1141 pAd Pointer to our adapter
1142
1143 Return Value:
1144 None
1145
1146 IRQL = DISPATCH_LEVEL
1147
1148 Note:
1149
1150 ========================================================================
1151*/
1152VOID RTMPWPARemoveAllKeys(
1153 IN PRTMP_ADAPTER pAd)
1154{
1155
1156 UCHAR i;
1157
1158 DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
1159
1160 // For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after
1161 // Link up. And it will be replaced if user changed it.
1162 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1163 return;
1164
1165 // For WPA-None, there is no need to remove it, since WinXP won't set it again after
1166 // Link up. And it will be replaced if user changed it.
1167 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1168 return;
1169
1170 // set BSSID wcid entry of the Pair-wise Key table as no-security mode
1171 AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID);
1172
1173 // set all shared key mode as no-security.
1174 for (i = 0; i < SHARE_KEY_NUM; i++)
1175 {
1176 DBGPRINT(RT_DEBUG_TRACE,("remove %s key #%d\n", CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
1177 NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(CIPHER_KEY));
1178
1179 AsicRemoveSharedKeyEntry(pAd, BSS0, i);
1180 }
1181
1182}
1183#endif // CONFIG_STA_SUPPORT //
1184
1185/*
1186 ========================================================================
1187 Routine Description:
1188 Change NIC PHY mode. Re-association may be necessary. possible settings
1189 include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED
1190
1191 Arguments:
1192 pAd - Pointer to our adapter
1193 phymode -
1194
1195 IRQL = PASSIVE_LEVEL
1196 IRQL = DISPATCH_LEVEL
1197
1198 ========================================================================
1199*/
1200VOID RTMPSetPhyMode(
1201 IN PRTMP_ADAPTER pAd,
1202 IN ULONG phymode)
1203{
1204 INT i;
1205 // the selected phymode must be supported by the RF IC encoded in E2PROM
1206
1207 // if no change, do nothing
1208 /* bug fix
1209 if (pAd->CommonCfg.PhyMode == phymode)
1210 return;
1211 */
1212 pAd->CommonCfg.PhyMode = (UCHAR)phymode;
1213
1214 DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
1215#ifdef EXT_BUILD_CHANNEL_LIST
1216 BuildChannelListEx(pAd);
1217#else
1218 BuildChannelList(pAd);
1219#endif // EXT_BUILD_CHANNEL_LIST //
1220
1221 // sanity check user setting
1222 for (i = 0; i < pAd->ChannelListNum; i++)
1223 {
1224 if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
1225 break;
1226 }
1227
1228 if (i == pAd->ChannelListNum)
1229 {
1230#ifdef CONFIG_STA_SUPPORT
1231 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1232 pAd->CommonCfg.Channel = FirstChannel(pAd);
1233#endif // CONFIG_STA_SUPPORT //
1234 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n", pAd->CommonCfg.Channel));
1235 }
1236
1237 NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
1238 NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
1239 NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
1240 switch (phymode) {
1241 case PHY_11B:
1242 pAd->CommonCfg.SupRate[0] = 0x82; // 1 mbps, in units of 0.5 Mbps, basic rate
1243 pAd->CommonCfg.SupRate[1] = 0x84; // 2 mbps, in units of 0.5 Mbps, basic rate
1244 pAd->CommonCfg.SupRate[2] = 0x8B; // 5.5 mbps, in units of 0.5 Mbps, basic rate
1245 pAd->CommonCfg.SupRate[3] = 0x96; // 11 mbps, in units of 0.5 Mbps, basic rate
1246 pAd->CommonCfg.SupRateLen = 4;
1247 pAd->CommonCfg.ExtRateLen = 0;
1248 pAd->CommonCfg.DesireRate[0] = 2; // 1 mbps, in units of 0.5 Mbps
1249 pAd->CommonCfg.DesireRate[1] = 4; // 2 mbps, in units of 0.5 Mbps
1250 pAd->CommonCfg.DesireRate[2] = 11; // 5.5 mbps, in units of 0.5 Mbps
1251 pAd->CommonCfg.DesireRate[3] = 22; // 11 mbps, in units of 0.5 Mbps
1252 //pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use
1253 break;
1254
1255 case PHY_11G:
1256 case PHY_11BG_MIXED:
1257 case PHY_11ABG_MIXED:
1258#ifdef DOT11_N_SUPPORT
1259 case PHY_11N_2_4G:
1260 case PHY_11ABGN_MIXED:
1261 case PHY_11BGN_MIXED:
1262 case PHY_11GN_MIXED:
1263#endif // DOT11_N_SUPPORT //
1264 pAd->CommonCfg.SupRate[0] = 0x82; // 1 mbps, in units of 0.5 Mbps, basic rate
1265 pAd->CommonCfg.SupRate[1] = 0x84; // 2 mbps, in units of 0.5 Mbps, basic rate
1266 pAd->CommonCfg.SupRate[2] = 0x8B; // 5.5 mbps, in units of 0.5 Mbps, basic rate
1267 pAd->CommonCfg.SupRate[3] = 0x96; // 11 mbps, in units of 0.5 Mbps, basic rate
1268 pAd->CommonCfg.SupRate[4] = 0x12; // 9 mbps, in units of 0.5 Mbps
1269 pAd->CommonCfg.SupRate[5] = 0x24; // 18 mbps, in units of 0.5 Mbps
1270 pAd->CommonCfg.SupRate[6] = 0x48; // 36 mbps, in units of 0.5 Mbps
1271 pAd->CommonCfg.SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
1272 pAd->CommonCfg.SupRateLen = 8;
1273 pAd->CommonCfg.ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps
1274 pAd->CommonCfg.ExtRate[1] = 0x18; // 12 mbps, in units of 0.5 Mbps
1275 pAd->CommonCfg.ExtRate[2] = 0x30; // 24 mbps, in units of 0.5 Mbps
1276 pAd->CommonCfg.ExtRate[3] = 0x60; // 48 mbps, in units of 0.5 Mbps
1277 pAd->CommonCfg.ExtRateLen = 4;
1278 pAd->CommonCfg.DesireRate[0] = 2; // 1 mbps, in units of 0.5 Mbps
1279 pAd->CommonCfg.DesireRate[1] = 4; // 2 mbps, in units of 0.5 Mbps
1280 pAd->CommonCfg.DesireRate[2] = 11; // 5.5 mbps, in units of 0.5 Mbps
1281 pAd->CommonCfg.DesireRate[3] = 22; // 11 mbps, in units of 0.5 Mbps
1282 pAd->CommonCfg.DesireRate[4] = 12; // 6 mbps, in units of 0.5 Mbps
1283 pAd->CommonCfg.DesireRate[5] = 18; // 9 mbps, in units of 0.5 Mbps
1284 pAd->CommonCfg.DesireRate[6] = 24; // 12 mbps, in units of 0.5 Mbps
1285 pAd->CommonCfg.DesireRate[7] = 36; // 18 mbps, in units of 0.5 Mbps
1286 pAd->CommonCfg.DesireRate[8] = 48; // 24 mbps, in units of 0.5 Mbps
1287 pAd->CommonCfg.DesireRate[9] = 72; // 36 mbps, in units of 0.5 Mbps
1288 pAd->CommonCfg.DesireRate[10] = 96; // 48 mbps, in units of 0.5 Mbps
1289 pAd->CommonCfg.DesireRate[11] = 108; // 54 mbps, in units of 0.5 Mbps
1290 break;
1291
1292 case PHY_11A:
1293#ifdef DOT11_N_SUPPORT
1294 case PHY_11AN_MIXED:
1295 case PHY_11AGN_MIXED:
1296 case PHY_11N_5G:
1297#endif // DOT11_N_SUPPORT //
1298 pAd->CommonCfg.SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
1299 pAd->CommonCfg.SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
1300 pAd->CommonCfg.SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
1301 pAd->CommonCfg.SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
1302 pAd->CommonCfg.SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
1303 pAd->CommonCfg.SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
1304 pAd->CommonCfg.SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
1305 pAd->CommonCfg.SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
1306 pAd->CommonCfg.SupRateLen = 8;
1307 pAd->CommonCfg.ExtRateLen = 0;
1308 pAd->CommonCfg.DesireRate[0] = 12; // 6 mbps, in units of 0.5 Mbps
1309 pAd->CommonCfg.DesireRate[1] = 18; // 9 mbps, in units of 0.5 Mbps
1310 pAd->CommonCfg.DesireRate[2] = 24; // 12 mbps, in units of 0.5 Mbps
1311 pAd->CommonCfg.DesireRate[3] = 36; // 18 mbps, in units of 0.5 Mbps
1312 pAd->CommonCfg.DesireRate[4] = 48; // 24 mbps, in units of 0.5 Mbps
1313 pAd->CommonCfg.DesireRate[5] = 72; // 36 mbps, in units of 0.5 Mbps
1314 pAd->CommonCfg.DesireRate[6] = 96; // 48 mbps, in units of 0.5 Mbps
1315 pAd->CommonCfg.DesireRate[7] = 108; // 54 mbps, in units of 0.5 Mbps
1316 //pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use
1317 break;
1318
1319 default:
1320 break;
1321 }
1322
1323
1324 pAd->CommonCfg.BandState = UNKNOWN_BAND;
1325}
1326
1327
1328#ifdef DOT11_N_SUPPORT
1329/*
1330 ========================================================================
1331 Routine Description:
1332 Caller ensures we has 802.11n support.
1333 Calls at setting HT from AP/STASetinformation
1334
1335 Arguments:
1336 pAd - Pointer to our adapter
1337 phymode -
1338
1339 ========================================================================
1340*/
1341VOID RTMPSetHT(
1342 IN PRTMP_ADAPTER pAd,
1343 IN OID_SET_HT_PHYMODE *pHTPhyMode)
1344{
1345 //ULONG *pmcs;
1346 UINT32 Value = 0;
1347 UCHAR BBPValue = 0;
1348 UCHAR BBP3Value = 0;
1349 UCHAR RxStream = pAd->CommonCfg.RxStream;
1350
1351 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
1352 pHTPhyMode->HtMode, pHTPhyMode->ExtOffset,
1353 pHTPhyMode->MCS, pHTPhyMode->BW,
1354 pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
1355
1356 // Don't zero supportedHyPhy structure.
1357 RTMPZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
1358 RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
1359 RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset));
1360 RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy, sizeof(pAd->CommonCfg.DesiredHtPhy));
1361
1362 if (pAd->CommonCfg.bRdg)
1363 {
1364 pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1;
1365 pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1;
1366 }
1367 else
1368 {
1369 pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0;
1370 pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0;
1371 }
1372
1373 pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3;
1374 pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3;
1375
1376 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit));
1377
1378 // Mimo power save, A-MSDU size,
1379 pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
1380 pAd->CommonCfg.DesiredHtPhy.AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize;
1381 pAd->CommonCfg.DesiredHtPhy.MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode;
1382 pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
1383
1384 pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
1385 pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
1386 pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
1387
1388 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
1389 pAd->CommonCfg.DesiredHtPhy.AmsduSize,
1390 pAd->CommonCfg.DesiredHtPhy.MimoPs,
1391 pAd->CommonCfg.DesiredHtPhy.MpduDensity,
1392 pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
1393
1394 if(pHTPhyMode->HtMode == HTMODE_GF)
1395 {
1396 pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1;
1397 pAd->CommonCfg.DesiredHtPhy.GF = 1;
1398 }
1399 else
1400 pAd->CommonCfg.DesiredHtPhy.GF = 0;
1401
1402 // Decide Rx MCSSet
1403 switch (RxStream)
1404 {
1405 case 1:
1406 pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
1407 pAd->CommonCfg.HtCapability.MCSSet[1] = 0x00;
1408 break;
1409
1410 case 2:
1411 pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
1412 pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
1413 break;
1414
1415 case 3: // 3*3
1416 pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
1417 pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
1418 pAd->CommonCfg.HtCapability.MCSSet[2] = 0xff;
1419 break;
1420 }
1421
1422 if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40) )
1423 {
1424 pHTPhyMode->BW = BW_20;
1425 pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1;
1426 }
1427
1428 if(pHTPhyMode->BW == BW_40)
1429 {
1430 pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1; // MCS 32
1431 pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1;
1432 if (pAd->CommonCfg.Channel <= 14)
1433 pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1;
1434
1435 pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1;
1436 pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
1437 pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE;
1438 // Set Regsiter for extension channel position.
1439 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
1440 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value);
1441 if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW))
1442 {
1443 Value |= 0x1;
1444 BBP3Value |= (0x20);
1445 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
1446 }
1447 else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE))
1448 {
1449 Value &= 0xfe;
1450 BBP3Value &= (~0x20);
1451 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
1452 }
1453
1454 // Turn on BBP 40MHz mode now only as AP .
1455 // Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.
1456 if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd)
1457 )
1458 {
1459 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
1460 BBPValue &= (~0x18);
1461 BBPValue |= 0x10;
1462 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
1463
1464 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value);
1465 pAd->CommonCfg.BBPCurrentBW = BW_40;
1466 }
1467 }
1468 else
1469 {
1470 pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0;
1471 pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0;
1472 pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
1473 pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE;
1474 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1475 // Turn on BBP 20MHz mode by request here.
1476 {
1477 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
1478 BBPValue &= (~0x18);
1479 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
1480 pAd->CommonCfg.BBPCurrentBW = BW_20;
1481 }
1482 }
1483
1484 if(pHTPhyMode->STBC == STBC_USE)
1485 {
1486 pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1;
1487 pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1;
1488 pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1;
1489 pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1;
1490 }
1491 else
1492 {
1493 pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
1494 pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
1495 }
1496
1497
1498 if(pHTPhyMode->SHORTGI == GI_400)
1499 {
1500 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
1501 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1;
1502 pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1;
1503 pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1;
1504 }
1505 else
1506 {
1507 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0;
1508 pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0;
1509 pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0;
1510 pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0;
1511 }
1512
1513 // We support link adaptation for unsolicit MCS feedback, set to 2.
1514 pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE; //MCSFBK_UNSOLICIT;
1515 pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel;
1516 // 1, the extension channel above the control channel.
1517
1518 // EDCA parameters used for AP's own transmission
1519 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
1520 {
1521 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
1522 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
1523 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
1524 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
1525 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
1526
1527 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
1528 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
1529 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
1530 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
1531
1532 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
1533 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
1534 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
1535 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
1536
1537 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
1538 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
1539 pAd->CommonCfg.APEdcaParm.Txop[2] = 94;
1540 pAd->CommonCfg.APEdcaParm.Txop[3] = 47;
1541 }
1542 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1543
1544
1545#ifdef CONFIG_STA_SUPPORT
1546 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1547 {
1548 RTMPSetIndividualHT(pAd, 0);
1549 }
1550#endif // CONFIG_STA_SUPPORT //
1551
1552}
1553
1554/*
1555 ========================================================================
1556 Routine Description:
1557 Caller ensures we has 802.11n support.
1558 Calls at setting HT from AP/STASetinformation
1559
1560 Arguments:
1561 pAd - Pointer to our adapter
1562 phymode -
1563
1564 ========================================================================
1565*/
1566VOID RTMPSetIndividualHT(
1567 IN PRTMP_ADAPTER pAd,
1568 IN UCHAR apidx)
1569{
1570 PRT_HT_PHY_INFO pDesired_ht_phy = NULL;
1571 UCHAR TxStream = pAd->CommonCfg.TxStream;
1572 UCHAR DesiredMcs = MCS_AUTO;
1573
1574 do
1575 {
1576
1577#ifdef CONFIG_STA_SUPPORT
1578 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1579 {
1580 pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo;
1581 DesiredMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
1582 //pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;
1583 break;
1584 }
1585#endif // CONFIG_STA_SUPPORT //
1586 } while (FALSE);
1587
1588 if (pDesired_ht_phy == NULL)
1589 {
1590 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
1591 return;
1592 }
1593 RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_HT_PHY_INFO));
1594
1595 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
1596 // Check the validity of MCS
1597 if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15)))
1598 {
1599 DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs));
1600 DesiredMcs = MCS_7;
1601 }
1602
1603 if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32))
1604 {
1605 DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
1606 DesiredMcs = MCS_0;
1607 }
1608
1609 pDesired_ht_phy->bHtEnable = TRUE;
1610
1611 // Decide desired Tx MCS
1612 switch (TxStream)
1613 {
1614 case 1:
1615 if (DesiredMcs == MCS_AUTO)
1616 {
1617 pDesired_ht_phy->MCSSet[0]= 0xff;
1618 pDesired_ht_phy->MCSSet[1]= 0x00;
1619 }
1620 else if (DesiredMcs <= MCS_7)
1621 {
1622 pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs;
1623 pDesired_ht_phy->MCSSet[1]= 0x00;
1624 }
1625 break;
1626
1627 case 2:
1628 if (DesiredMcs == MCS_AUTO)
1629 {
1630 pDesired_ht_phy->MCSSet[0]= 0xff;
1631 pDesired_ht_phy->MCSSet[1]= 0xff;
1632 }
1633 else if (DesiredMcs <= MCS_15)
1634 {
1635 ULONG mode;
1636
1637 mode = DesiredMcs / 8;
1638 if (mode < 2)
1639 pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
1640 }
1641 break;
1642
1643 case 3: // 3*3
1644 if (DesiredMcs == MCS_AUTO)
1645 {
1646 /* MCS0 ~ MCS23, 3 bytes */
1647 pDesired_ht_phy->MCSSet[0]= 0xff;
1648 pDesired_ht_phy->MCSSet[1]= 0xff;
1649 pDesired_ht_phy->MCSSet[2]= 0xff;
1650 }
1651 else if (DesiredMcs <= MCS_23)
1652 {
1653 ULONG mode;
1654
1655 mode = DesiredMcs / 8;
1656 if (mode < 3)
1657 pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
1658 }
1659 break;
1660 }
1661
1662 if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40)
1663 {
1664 if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32)
1665 pDesired_ht_phy->MCSSet[4] = 0x1;
1666 }
1667
1668 // update HT Rate setting
1669 if (pAd->OpMode == OPMODE_STA)
1670 MlmeUpdateHtTxRates(pAd, BSS0);
1671 else
1672 MlmeUpdateHtTxRates(pAd, apidx);
1673}
1674
1675
1676/*
1677 ========================================================================
1678 Routine Description:
1679 Update HT IE from our capability.
1680
1681 Arguments:
1682 Send all HT IE in beacon/probe rsp/assoc rsp/action frame.
1683
1684
1685 ========================================================================
1686*/
1687VOID RTMPUpdateHTIE(
1688 IN RT_HT_CAPABILITY *pRtHt,
1689 IN UCHAR *pMcsSet,
1690 OUT HT_CAPABILITY_IE *pHtCapability,
1691 OUT ADD_HT_INFO_IE *pAddHtInfo)
1692{
1693 RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE));
1694 RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE));
1695
1696 pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
1697 pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
1698 pHtCapability->HtCapInfo.GF = pRtHt->GF;
1699 pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
1700 pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
1701 pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
1702 pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
1703 pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
1704 pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
1705 pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
1706
1707 pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset ;
1708 pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
1709 pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
1710 pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
1711 RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet*/pMcsSet, 4); // rt2860 only support MCS max=32, no need to copy all 16 uchar.
1712
1713 DBGPRINT(RT_DEBUG_TRACE,("RTMPUpdateHTIE <== \n"));
1714}
1715#endif // DOT11_N_SUPPORT //
1716
1717/*
1718 ========================================================================
1719 Description:
1720 Add Client security information into ASIC WCID table and IVEIV table.
1721 Return:
1722 ========================================================================
1723*/
1724VOID RTMPAddWcidAttributeEntry(
1725 IN PRTMP_ADAPTER pAd,
1726 IN UCHAR BssIdx,
1727 IN UCHAR KeyIdx,
1728 IN UCHAR CipherAlg,
1729 IN MAC_TABLE_ENTRY *pEntry)
1730{
1731 UINT32 WCIDAttri = 0;
1732 USHORT offset;
1733 UCHAR IVEIV = 0;
1734 USHORT Wcid = 0;
1735
1736 {
1737#ifdef CONFIG_STA_SUPPORT
1738 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1739 {
1740 if (BssIdx > BSS0)
1741 {
1742 DBGPRINT(RT_DEBUG_ERROR, ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n", BssIdx));
1743 return;
1744 }
1745
1746 // 1. In ADHOC mode, the AID is wcid number. And NO mesh link exists.
1747 // 2. In Infra mode, the AID:1 MUST be wcid of infra STA.
1748 // the AID:2~ assign to mesh link entry.
1749 if (pEntry && ADHOC_ON(pAd))
1750 Wcid = pEntry->Aid;
1751 else if (pEntry && INFRA_ON(pAd))
1752 {
1753#ifdef QOS_DLS_SUPPORT
1754 if (pEntry->ValidAsDls == TRUE)
1755 Wcid = pEntry->Aid;
1756 else
1757#endif // QOS_DLS_SUPPORT //
1758 Wcid = BSSID_WCID;
1759 }
1760 else
1761 Wcid = MCAST_WCID;
1762 }
1763#endif // CONFIG_STA_SUPPORT //
1764 }
1765
1766 // Update WCID attribute table
1767 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
1768
1769#ifdef CONFIG_STA_SUPPORT
1770 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1771 {
1772 if (pEntry && pEntry->ValidAsMesh)
1773 WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
1774#ifdef QOS_DLS_SUPPORT
1775 else if ((pEntry) && (pEntry->ValidAsDls) &&
1776 ((CipherAlg == CIPHER_TKIP) ||
1777 (CipherAlg == CIPHER_TKIP_NO_MIC) ||
1778 (CipherAlg == CIPHER_AES) ||
1779 (CipherAlg == CIPHER_NONE)))
1780 WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
1781#endif // QOS_DLS_SUPPORT //
1782 else
1783 WCIDAttri = (CipherAlg<<1) | SHAREDKEYTABLE;
1784 }
1785#endif // CONFIG_STA_SUPPORT //
1786
1787 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
1788
1789
1790 // Update IV/EIV table
1791 offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
1792
1793 // WPA mode
1794 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) || (CipherAlg == CIPHER_AES))
1795 {
1796 // Eiv bit on. keyid always is 0 for pairwise key
1797 IVEIV = (KeyIdx <<6) | 0x20;
1798 }
1799 else
1800 {
1801 // WEP KeyIdx is default tx key.
1802 IVEIV = (KeyIdx << 6);
1803 }
1804
1805 // For key index and ext IV bit, so only need to update the position(offset+3).
1806#ifdef RT2860
1807 RTMP_IO_WRITE8(pAd, offset+3, IVEIV);
1808#endif // RT2860 //
1809
1810 DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
1811 DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri));
1812
1813}
1814
1815/*
1816 ==========================================================================
1817 Description:
1818 Parse encryption type
1819Arguments:
1820 pAdapter Pointer to our adapter
1821 wrq Pointer to the ioctl argument
1822
1823 Return Value:
1824 None
1825
1826 Note:
1827 ==========================================================================
1828*/
1829CHAR *GetEncryptType(CHAR enc)
1830{
1831 if(enc == Ndis802_11WEPDisabled)
1832 return "NONE";
1833 if(enc == Ndis802_11WEPEnabled)
1834 return "WEP";
1835 if(enc == Ndis802_11Encryption2Enabled)
1836 return "TKIP";
1837 if(enc == Ndis802_11Encryption3Enabled)
1838 return "AES";
1839 if(enc == Ndis802_11Encryption4Enabled)
1840 return "TKIPAES";
1841 else
1842 return "UNKNOW";
1843}
1844
1845CHAR *GetAuthMode(CHAR auth)
1846{
1847 if(auth == Ndis802_11AuthModeOpen)
1848 return "OPEN";
1849 if(auth == Ndis802_11AuthModeShared)
1850 return "SHARED";
1851 if(auth == Ndis802_11AuthModeAutoSwitch)
1852 return "AUTOWEP";
1853 if(auth == Ndis802_11AuthModeWPA)
1854 return "WPA";
1855 if(auth == Ndis802_11AuthModeWPAPSK)
1856 return "WPAPSK";
1857 if(auth == Ndis802_11AuthModeWPANone)
1858 return "WPANONE";
1859 if(auth == Ndis802_11AuthModeWPA2)
1860 return "WPA2";
1861 if(auth == Ndis802_11AuthModeWPA2PSK)
1862 return "WPA2PSK";
1863 if(auth == Ndis802_11AuthModeWPA1WPA2)
1864 return "WPA1WPA2";
1865 if(auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
1866 return "WPA1PSKWPA2PSK";
1867
1868 return "UNKNOW";
1869}
1870
1871#if 1 //#ifndef UCOS
1872/*
1873 ==========================================================================
1874 Description:
1875 Get site survey results
1876 Arguments:
1877 pAdapter Pointer to our adapter
1878 wrq Pointer to the ioctl argument
1879
1880 Return Value:
1881 None
1882
1883 Note:
1884 Usage:
1885 1.) UI needs to wait 4 seconds after issue a site survey command
1886 2.) iwpriv ra0 get_site_survey
1887 3.) UI needs to prepare at least 4096bytes to get the results
1888 ==========================================================================
1889*/
1890#define LINE_LEN (4+33+20+8+10+9+7+3) // Channel+SSID+Bssid+WepStatus+AuthMode+Signal+WiressMode+NetworkType
1891VOID RTMPIoctlGetSiteSurvey(
1892 IN PRTMP_ADAPTER pAdapter,
1893 IN struct iwreq *wrq)
1894{
1895 CHAR *msg;
1896 INT i=0;
1897 INT WaitCnt;
1898 INT Status=0;
1899 CHAR Ssid[MAX_LEN_OF_SSID +1];
1900 INT Rssi = 0, max_len = LINE_LEN;
1901 UINT Rssi_Quality = 0;
1902 NDIS_802_11_NETWORK_TYPE wireless_mode;
1903
1904 os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
1905
1906 if (msg == NULL)
1907 {
1908 DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
1909 return;
1910 }
1911
1912 memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
1913 memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1));
1914 sprintf(msg,"%s","\n");
1915 sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-8s%-10s%-9s%-7s%-3s\n",
1916 "Ch", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", " NT");
1917
1918 WaitCnt = 0;
1919#ifdef CONFIG_STA_SUPPORT
1920 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
1921 while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
1922 OS_WAIT(500);
1923#endif // CONFIG_STA_SUPPORT //
1924
1925 for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
1926 {
1927 if( pAdapter->ScanTab.BssEntry[i].Channel==0)
1928 break;
1929
1930 if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
1931 break;
1932
1933 //Channel
1934 sprintf(msg+strlen(msg),"%-4d", pAdapter->ScanTab.BssEntry[i].Channel);
1935 //SSID
1936 memcpy(Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
1937 Ssid[pAdapter->ScanTab.BssEntry[i].SsidLen] = '\0';
1938 sprintf(msg+strlen(msg),"%-33s", Ssid);
1939 //BSSID
1940 sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x ",
1941 pAdapter->ScanTab.BssEntry[i].Bssid[0],
1942 pAdapter->ScanTab.BssEntry[i].Bssid[1],
1943 pAdapter->ScanTab.BssEntry[i].Bssid[2],
1944 pAdapter->ScanTab.BssEntry[i].Bssid[3],
1945 pAdapter->ScanTab.BssEntry[i].Bssid[4],
1946 pAdapter->ScanTab.BssEntry[i].Bssid[5]);
1947 //Encryption Type
1948 sprintf(msg+strlen(msg),"%-8s",GetEncryptType(pAdapter->ScanTab.BssEntry[i].WepStatus));
1949 //Authentication Mode
1950 if (pAdapter->ScanTab.BssEntry[i].WepStatus == Ndis802_11WEPEnabled)
1951 sprintf(msg+strlen(msg),"%-10s", "UNKNOW");
1952 else
1953 sprintf(msg+strlen(msg),"%-10s",GetAuthMode(pAdapter->ScanTab.BssEntry[i].AuthMode));
1954 // Rssi
1955 Rssi = (INT)pAdapter->ScanTab.BssEntry[i].Rssi;
1956 if (Rssi >= -50)
1957 Rssi_Quality = 100;
1958 else if (Rssi >= -80) // between -50 ~ -80dbm
1959 Rssi_Quality = (UINT)(24 + ((Rssi + 80) * 26)/10);
1960 else if (Rssi >= -90) // between -80 ~ -90dbm
1961 Rssi_Quality = (UINT)(((Rssi + 90) * 26)/10);
1962 else // < -84 dbm
1963 Rssi_Quality = 0;
1964 sprintf(msg+strlen(msg),"%-9d", Rssi_Quality);
1965 // Wireless Mode
1966 wireless_mode = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
1967 if (wireless_mode == Ndis802_11FH ||
1968 wireless_mode == Ndis802_11DS)
1969 sprintf(msg+strlen(msg),"%-7s", "11b");
1970 else if (wireless_mode == Ndis802_11OFDM5)
1971 sprintf(msg+strlen(msg),"%-7s", "11a");
1972 else if (wireless_mode == Ndis802_11OFDM5_N)
1973 sprintf(msg+strlen(msg),"%-7s", "11a/n");
1974 else if (wireless_mode == Ndis802_11OFDM24)
1975 sprintf(msg+strlen(msg),"%-7s", "11b/g");
1976 else if (wireless_mode == Ndis802_11OFDM24_N)
1977 sprintf(msg+strlen(msg),"%-7s", "11b/g/n");
1978 else
1979 sprintf(msg+strlen(msg),"%-7s", "unknow");
1980 //Network Type
1981 if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_ADHOC)
1982 sprintf(msg+strlen(msg),"%-3s", " Ad");
1983 else
1984 sprintf(msg+strlen(msg),"%-3s", " In");
1985
1986 sprintf(msg+strlen(msg),"\n");
1987 }
1988
1989#ifdef CONFIG_STA_SUPPORT
1990 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
1991#endif // CONFIG_STA_SUPPORT //
1992 wrq->u.data.length = strlen(msg);
1993 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
1994
1995 DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - wrq->u.data.length = %d\n", wrq->u.data.length));
1996 os_free_mem(NULL, (PUCHAR)msg);
1997}
1998
1999
2000#define MAC_LINE_LEN (14+4+4+10+10+10+6+6) // Addr+aid+psm+datatime+rxbyte+txbyte+current tx rate+last tx rate
2001VOID RTMPIoctlGetMacTable(
2002 IN PRTMP_ADAPTER pAd,
2003 IN struct iwreq *wrq)
2004{
2005 INT i;
2006 RT_802_11_MAC_TABLE MacTab;
2007 char *msg;
2008
2009 MacTab.Num = 0;
2010 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
2011 {
2012 if (pAd->MacTab.Content[i].ValidAsCLI && (pAd->MacTab.Content[i].Sst == SST_ASSOC))
2013 {
2014 COPY_MAC_ADDR(MacTab.Entry[MacTab.Num].Addr, &pAd->MacTab.Content[i].Addr);
2015 MacTab.Entry[MacTab.Num].Aid = (UCHAR)pAd->MacTab.Content[i].Aid;
2016 MacTab.Entry[MacTab.Num].Psm = pAd->MacTab.Content[i].PsMode;
2017#ifdef DOT11_N_SUPPORT
2018 MacTab.Entry[MacTab.Num].MimoPs = pAd->MacTab.Content[i].MmpsMode;
2019#endif // DOT11_N_SUPPORT //
2020
2021 // Fill in RSSI per entry
2022 MacTab.Entry[MacTab.Num].AvgRssi0 = pAd->MacTab.Content[i].RssiSample.AvgRssi0;
2023 MacTab.Entry[MacTab.Num].AvgRssi1 = pAd->MacTab.Content[i].RssiSample.AvgRssi1;
2024 MacTab.Entry[MacTab.Num].AvgRssi2 = pAd->MacTab.Content[i].RssiSample.AvgRssi2;
2025
2026 // the connected time per entry
2027 MacTab.Entry[MacTab.Num].ConnectedTime = pAd->MacTab.Content[i].StaConnectTime;
2028 MacTab.Entry[MacTab.Num].TxRate.field.MCS = pAd->MacTab.Content[i].HTPhyMode.field.MCS;
2029 MacTab.Entry[MacTab.Num].TxRate.field.BW = pAd->MacTab.Content[i].HTPhyMode.field.BW;
2030 MacTab.Entry[MacTab.Num].TxRate.field.ShortGI = pAd->MacTab.Content[i].HTPhyMode.field.ShortGI;
2031 MacTab.Entry[MacTab.Num].TxRate.field.STBC = pAd->MacTab.Content[i].HTPhyMode.field.STBC;
2032 MacTab.Entry[MacTab.Num].TxRate.field.rsv = pAd->MacTab.Content[i].HTPhyMode.field.rsv;
2033 MacTab.Entry[MacTab.Num].TxRate.field.MODE = pAd->MacTab.Content[i].HTPhyMode.field.MODE;
2034 MacTab.Entry[MacTab.Num].TxRate.word = pAd->MacTab.Content[i].HTPhyMode.word;
2035
2036 MacTab.Num += 1;
2037 }
2038 }
2039 wrq->u.data.length = sizeof(RT_802_11_MAC_TABLE);
2040 if (copy_to_user(wrq->u.data.pointer, &MacTab, wrq->u.data.length))
2041 {
2042 DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
2043 }
2044
2045 msg = (CHAR *) kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
2046 memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN );
2047 sprintf(msg,"%s","\n");
2048 sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n",
2049 "MAC", "AID", "PSM", "LDT", "RxB", "TxB","CTxR", "LTxR");
2050
2051 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
2052 {
2053 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
2054 if (pEntry->ValidAsCLI && (pEntry->Sst == SST_ASSOC))
2055 {
2056 if((strlen(msg)+MAC_LINE_LEN ) >= (MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN) )
2057 break;
2058 sprintf(msg+strlen(msg),"%02x%02x%02x%02x%02x%02x ",
2059 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2060 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
2061 sprintf(msg+strlen(msg),"%-4d", (int)pEntry->Aid);
2062 sprintf(msg+strlen(msg),"%-4d", (int)pEntry->PsMode);
2063 sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.LastDataPacketTime*/); // ToDo
2064 sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalRxByteCount*/); // ToDo
2065 sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalTxByteCount*/); // ToDo
2066 sprintf(msg+strlen(msg),"%-6d",RateIdToMbps[pAd->MacTab.Content[i].CurrTxRate]);
2067 sprintf(msg+strlen(msg),"%-6d\n",0/*RateIdToMbps[pAd->MacTab.Content[i].LastTxRate]*/); // ToDo
2068 }
2069 }
2070 // for compatible with old API just do the printk to console
2071 //wrq->u.data.length = strlen(msg);
2072 //if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
2073 {
2074 DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
2075 }
2076
2077 kfree(msg);
2078}
2079#endif // UCOS //
2080
2081#ifdef DOT11_N_SUPPORT
2082INT Set_BASetup_Proc(
2083 IN PRTMP_ADAPTER pAd,
2084 IN PUCHAR arg)
2085{
2086 UCHAR mac[6], tid;
2087 char *token, sepValue[] = ":", DASH = '-';
2088 INT i;
2089 MAC_TABLE_ENTRY *pEntry;
2090
2091/*
2092 The BASetup inupt string format should be xx:xx:xx:xx:xx:xx-d,
2093 =>The six 2 digit hex-decimal number previous are the Mac address,
2094 =>The seventh decimal number is the tid value.
2095*/
2096 //printk("\n%s\n", arg);
2097
2098 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
2099 return FALSE;
2100
2101 token = strchr(arg, DASH);
2102 if ((token != NULL) && (strlen(token)>1))
2103 {
2104 tid = simple_strtol((token+1), 0, 10);
2105 if (tid > 15)
2106 return FALSE;
2107
2108 *token = '\0';
2109 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2110 {
2111 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2112 return FALSE;
2113 AtoH(token, (PUCHAR)(&mac[i]), 1);
2114 }
2115 if(i != 6)
2116 return FALSE;
2117
2118 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", mac[0], mac[1],
2119 mac[2], mac[3], mac[4], mac[5], tid);
2120
2121 pEntry = MacTableLookup(pAd, mac);
2122
2123 if (pEntry) {
2124 printk("\nSetup BA Session: Tid = %d\n", tid);
2125 BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE);
2126 }
2127
2128 return TRUE;
2129 }
2130
2131 return FALSE;
2132
2133}
2134
2135INT Set_BADecline_Proc(
2136 IN PRTMP_ADAPTER pAd,
2137 IN PUCHAR arg)
2138{
2139 ULONG bBADecline;
2140
2141 bBADecline = simple_strtol(arg, 0, 10);
2142
2143 if (bBADecline == 0)
2144 {
2145 pAd->CommonCfg.bBADecline = FALSE;
2146 }
2147 else if (bBADecline == 1)
2148 {
2149 pAd->CommonCfg.bBADecline = TRUE;
2150 }
2151 else
2152 {
2153 return FALSE; //Invalid argument
2154 }
2155
2156 DBGPRINT(RT_DEBUG_TRACE, ("Set_BADecline_Proc::(BADecline=%d)\n", pAd->CommonCfg.bBADecline));
2157
2158 return TRUE;
2159}
2160
2161INT Set_BAOriTearDown_Proc(
2162 IN PRTMP_ADAPTER pAd,
2163 IN PUCHAR arg)
2164{
2165 UCHAR mac[6], tid;
2166 char *token, sepValue[] = ":", DASH = '-';
2167 INT i;
2168 MAC_TABLE_ENTRY *pEntry;
2169
2170/*
2171 The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
2172 =>The six 2 digit hex-decimal number previous are the Mac address,
2173 =>The seventh decimal number is the tid value.
2174*/
2175 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
2176 return FALSE;
2177
2178 token = strchr(arg, DASH);
2179 if ((token != NULL) && (strlen(token)>1))
2180 {
2181 tid = simple_strtol((token+1), 0, 10);
2182 if (tid > NUM_OF_TID)
2183 return FALSE;
2184
2185 *token = '\0';
2186 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2187 {
2188 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2189 return FALSE;
2190 AtoH(token, (PUCHAR)(&mac[i]), 1);
2191 }
2192 if(i != 6)
2193 return FALSE;
2194
2195 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
2196 mac[2], mac[3], mac[4], mac[5], tid);
2197
2198 pEntry = MacTableLookup(pAd, mac);
2199
2200 if (pEntry) {
2201 printk("\nTear down Ori BA Session: Tid = %d\n", tid);
2202 BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE);
2203 }
2204
2205 return TRUE;
2206 }
2207
2208 return FALSE;
2209
2210}
2211
2212INT Set_BARecTearDown_Proc(
2213 IN PRTMP_ADAPTER pAd,
2214 IN PUCHAR arg)
2215{
2216 UCHAR mac[6], tid;
2217 char *token, sepValue[] = ":", DASH = '-';
2218 INT i;
2219 MAC_TABLE_ENTRY *pEntry;
2220
2221 //printk("\n%s\n", arg);
2222/*
2223 The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
2224 =>The six 2 digit hex-decimal number previous are the Mac address,
2225 =>The seventh decimal number is the tid value.
2226*/
2227 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
2228 return FALSE;
2229
2230 token = strchr(arg, DASH);
2231 if ((token != NULL) && (strlen(token)>1))
2232 {
2233 tid = simple_strtol((token+1), 0, 10);
2234 if (tid > NUM_OF_TID)
2235 return FALSE;
2236
2237 *token = '\0';
2238 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2239 {
2240 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2241 return FALSE;
2242 AtoH(token, (PUCHAR)(&mac[i]), 1);
2243 }
2244 if(i != 6)
2245 return FALSE;
2246
2247 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
2248 mac[2], mac[3], mac[4], mac[5], tid);
2249
2250 pEntry = MacTableLookup(pAd, mac);
2251
2252 if (pEntry) {
2253 printk("\nTear down Rec BA Session: Tid = %d\n", tid);
2254 BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE);
2255 }
2256
2257 return TRUE;
2258 }
2259
2260 return FALSE;
2261
2262}
2263
2264INT Set_HtBw_Proc(
2265 IN PRTMP_ADAPTER pAd,
2266 IN PUCHAR arg)
2267{
2268 ULONG HtBw;
2269
2270 HtBw = simple_strtol(arg, 0, 10);
2271 if (HtBw == BW_40)
2272 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
2273 else if (HtBw == BW_20)
2274 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
2275 else
2276 return FALSE; //Invalid argument
2277
2278 SetCommonHT(pAd);
2279
2280 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBw_Proc::(HtBw=%d)\n", pAd->CommonCfg.RegTransmitSetting.field.BW));
2281
2282 return TRUE;
2283}
2284
2285INT Set_HtMcs_Proc(
2286 IN PRTMP_ADAPTER pAd,
2287 IN PUCHAR arg)
2288{
2289 ULONG HtMcs, Mcs_tmp;
2290#ifdef CONFIG_STA_SUPPORT
2291 BOOLEAN bAutoRate = FALSE;
2292#endif // CONFIG_STA_SUPPORT //
2293
2294 Mcs_tmp = simple_strtol(arg, 0, 10);
2295
2296 if (Mcs_tmp <= 15 || Mcs_tmp == 32)
2297 HtMcs = Mcs_tmp;
2298 else
2299 HtMcs = MCS_AUTO;
2300
2301#ifdef CONFIG_STA_SUPPORT
2302 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2303 {
2304 pAd->StaCfg.DesiredTransmitSetting.field.MCS = HtMcs;
2305 pAd->StaCfg.bAutoTxRateSwitch = (HtMcs == MCS_AUTO) ? TRUE:FALSE;
2306 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(HtMcs=%d, bAutoTxRateSwitch = %d)\n",
2307 pAd->StaCfg.DesiredTransmitSetting.field.MCS, pAd->StaCfg.bAutoTxRateSwitch));
2308
2309 if ((pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED) ||
2310 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE < MODE_HTMIX))
2311 {
2312 if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
2313 (HtMcs >= 0 && HtMcs <= 3) &&
2314 (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_CCK))
2315 {
2316 RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs] * 1000000));
2317 }
2318 else if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
2319 (HtMcs >= 0 && HtMcs <= 7) &&
2320 (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_OFDM))
2321 {
2322 RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs+4] * 1000000));
2323 }
2324 else
2325 bAutoRate = TRUE;
2326
2327 if (bAutoRate)
2328 {
2329 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2330 RTMPSetDesiredRates(pAd, -1);
2331 }
2332 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(FixedTxMode=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode));
2333 }
2334 if (ADHOC_ON(pAd))
2335 return TRUE;
2336 }
2337#endif // CONFIG_STA_SUPPORT //
2338
2339 SetCommonHT(pAd);
2340
2341 return TRUE;
2342}
2343
2344INT Set_HtGi_Proc(
2345 IN PRTMP_ADAPTER pAd,
2346 IN PUCHAR arg)
2347{
2348 ULONG HtGi;
2349
2350 HtGi = simple_strtol(arg, 0, 10);
2351
2352 if ( HtGi == GI_400)
2353 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
2354 else if ( HtGi == GI_800 )
2355 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
2356 else
2357 return FALSE; //Invalid argument
2358
2359 SetCommonHT(pAd);
2360
2361 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtGi_Proc::(ShortGI=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.ShortGI));
2362
2363 return TRUE;
2364}
2365
2366
2367INT Set_HtTxBASize_Proc(
2368 IN PRTMP_ADAPTER pAd,
2369 IN PUCHAR arg)
2370{
2371 UCHAR Size;
2372
2373 Size = simple_strtol(arg, 0, 10);
2374
2375 if (Size <=0 || Size >=64)
2376 {
2377 Size = 8;
2378 }
2379 pAd->CommonCfg.TxBASize = Size-1;
2380 DBGPRINT(RT_DEBUG_ERROR, ("Set_HtTxBASize ::(TxBASize= %d)\n", Size));
2381
2382 return TRUE;
2383}
2384
2385
2386INT Set_HtOpMode_Proc(
2387 IN PRTMP_ADAPTER pAd,
2388 IN PUCHAR arg)
2389{
2390
2391 ULONG Value;
2392
2393 Value = simple_strtol(arg, 0, 10);
2394
2395 if (Value == HTMODE_GF)
2396 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
2397 else if ( Value == HTMODE_MM )
2398 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
2399 else
2400 return FALSE; //Invalid argument
2401
2402 SetCommonHT(pAd);
2403
2404 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtOpMode_Proc::(HtOpMode=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.HTMODE));
2405
2406 return TRUE;
2407
2408}
2409
2410INT Set_HtStbc_Proc(
2411 IN PRTMP_ADAPTER pAd,
2412 IN PUCHAR arg)
2413{
2414
2415 ULONG Value;
2416
2417 Value = simple_strtol(arg, 0, 10);
2418
2419 if (Value == STBC_USE)
2420 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
2421 else if ( Value == STBC_NONE )
2422 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
2423 else
2424 return FALSE; //Invalid argument
2425
2426 SetCommonHT(pAd);
2427
2428 DBGPRINT(RT_DEBUG_TRACE, ("Set_Stbc_Proc::(HtStbc=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.STBC));
2429
2430 return TRUE;
2431}
2432
2433INT Set_HtHtc_Proc(
2434 IN PRTMP_ADAPTER pAd,
2435 IN PUCHAR arg)
2436{
2437
2438 ULONG Value;
2439
2440 Value = simple_strtol(arg, 0, 10);
2441 if (Value == 0)
2442 pAd->HTCEnable = FALSE;
2443 else if ( Value ==1 )
2444 pAd->HTCEnable = TRUE;
2445 else
2446 return FALSE; //Invalid argument
2447
2448 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtHtc_Proc::(HtHtc=%d)\n",pAd->HTCEnable));
2449
2450 return TRUE;
2451}
2452
2453INT Set_HtExtcha_Proc(
2454 IN PRTMP_ADAPTER pAd,
2455 IN PUCHAR arg)
2456{
2457
2458 ULONG Value;
2459
2460 Value = simple_strtol(arg, 0, 10);
2461
2462 if (Value == 0)
2463 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
2464 else if ( Value ==1 )
2465 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
2466 else
2467 return FALSE; //Invalid argument
2468
2469 SetCommonHT(pAd);
2470
2471 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtExtcha_Proc::(HtExtcha=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.EXTCHA));
2472
2473 return TRUE;
2474}
2475
2476INT Set_HtMpduDensity_Proc(
2477 IN PRTMP_ADAPTER pAd,
2478 IN PUCHAR arg)
2479{
2480 ULONG Value;
2481
2482 Value = simple_strtol(arg, 0, 10);
2483
2484 if (Value <=7 && Value >= 0)
2485 pAd->CommonCfg.BACapability.field.MpduDensity = Value;
2486 else
2487 pAd->CommonCfg.BACapability.field.MpduDensity = 4;
2488
2489 SetCommonHT(pAd);
2490
2491 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMpduDensity_Proc::(HtMpduDensity=%d)\n",pAd->CommonCfg.BACapability.field.MpduDensity));
2492
2493 return TRUE;
2494}
2495
2496INT Set_HtBaWinSize_Proc(
2497 IN PRTMP_ADAPTER pAd,
2498 IN PUCHAR arg)
2499{
2500 ULONG Value;
2501
2502 Value = simple_strtol(arg, 0, 10);
2503
2504
2505 if (Value >=1 && Value <= 64)
2506 {
2507 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
2508 pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
2509 }
2510 else
2511 {
2512 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
2513 pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
2514 }
2515
2516 SetCommonHT(pAd);
2517
2518 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBaWinSize_Proc::(HtBaWinSize=%d)\n",pAd->CommonCfg.BACapability.field.RxBAWinLimit));
2519
2520 return TRUE;
2521}
2522
2523INT Set_HtRdg_Proc(
2524 IN PRTMP_ADAPTER pAd,
2525 IN PUCHAR arg)
2526{
2527 ULONG Value;
2528
2529 Value = simple_strtol(arg, 0, 10);
2530
2531 if (Value == 0)
2532 pAd->CommonCfg.bRdg = FALSE;
2533 else if ( Value ==1 )
2534 {
2535 pAd->HTCEnable = TRUE;
2536 pAd->CommonCfg.bRdg = TRUE;
2537 }
2538 else
2539 return FALSE; //Invalid argument
2540
2541 SetCommonHT(pAd);
2542
2543 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtRdg_Proc::(HtRdg=%d)\n",pAd->CommonCfg.bRdg));
2544
2545 return TRUE;
2546}
2547
2548INT Set_HtLinkAdapt_Proc(
2549 IN PRTMP_ADAPTER pAd,
2550 IN PUCHAR arg)
2551{
2552 ULONG Value;
2553
2554 Value = simple_strtol(arg, 0, 10);
2555 if (Value == 0)
2556 pAd->bLinkAdapt = FALSE;
2557 else if ( Value ==1 )
2558 {
2559 pAd->HTCEnable = TRUE;
2560 pAd->bLinkAdapt = TRUE;
2561 }
2562 else
2563 return FALSE; //Invalid argument
2564
2565 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtLinkAdapt_Proc::(HtLinkAdapt=%d)\n",pAd->bLinkAdapt));
2566
2567 return TRUE;
2568}
2569
2570INT Set_HtAmsdu_Proc(
2571 IN PRTMP_ADAPTER pAd,
2572 IN PUCHAR arg)
2573{
2574 ULONG Value;
2575
2576 Value = simple_strtol(arg, 0, 10);
2577 if (Value == 0)
2578 pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
2579 else if ( Value == 1 )
2580 pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
2581 else
2582 return FALSE; //Invalid argument
2583
2584 SetCommonHT(pAd);
2585
2586 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAmsdu_Proc::(HtAmsdu=%d)\n",pAd->CommonCfg.BACapability.field.AmsduEnable));
2587
2588 return TRUE;
2589}
2590
2591INT Set_HtAutoBa_Proc(
2592 IN PRTMP_ADAPTER pAd,
2593 IN PUCHAR arg)
2594{
2595 ULONG Value;
2596
2597 Value = simple_strtol(arg, 0, 10);
2598 if (Value == 0)
2599 pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
2600 else if (Value == 1)
2601 pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
2602 else
2603 return FALSE; //Invalid argument
2604
2605 pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
2606 SetCommonHT(pAd);
2607
2608 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAutoBa_Proc::(HtAutoBa=%d)\n",pAd->CommonCfg.BACapability.field.AutoBA));
2609
2610 return TRUE;
2611
2612}
2613
2614INT Set_HtProtect_Proc(
2615 IN PRTMP_ADAPTER pAd,
2616 IN PUCHAR arg)
2617{
2618 ULONG Value;
2619
2620 Value = simple_strtol(arg, 0, 10);
2621 if (Value == 0)
2622 pAd->CommonCfg.bHTProtect = FALSE;
2623 else if (Value == 1)
2624 pAd->CommonCfg.bHTProtect = TRUE;
2625 else
2626 return FALSE; //Invalid argument
2627
2628 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtProtect_Proc::(HtProtect=%d)\n",pAd->CommonCfg.bHTProtect));
2629
2630 return TRUE;
2631}
2632
2633INT Set_SendPSMPAction_Proc(
2634 IN PRTMP_ADAPTER pAd,
2635 IN PUCHAR arg)
2636{
2637 UCHAR mac[6], mode;
2638 char *token, sepValue[] = ":", DASH = '-';
2639 INT i;
2640 MAC_TABLE_ENTRY *pEntry;
2641
2642 //printk("\n%s\n", arg);
2643/*
2644 The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
2645 =>The six 2 digit hex-decimal number previous are the Mac address,
2646 =>The seventh decimal number is the mode value.
2647*/
2648 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and mode value in decimal format.
2649 return FALSE;
2650
2651 token = strchr(arg, DASH);
2652 if ((token != NULL) && (strlen(token)>1))
2653 {
2654 mode = simple_strtol((token+1), 0, 10);
2655 if (mode > MMPS_ENABLE)
2656 return FALSE;
2657
2658 *token = '\0';
2659 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2660 {
2661 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2662 return FALSE;
2663 AtoH(token, (PUCHAR)(&mac[i]), 1);
2664 }
2665 if(i != 6)
2666 return FALSE;
2667
2668 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
2669 mac[2], mac[3], mac[4], mac[5], mode);
2670
2671 pEntry = MacTableLookup(pAd, mac);
2672
2673 if (pEntry) {
2674 printk("\nSendPSMPAction MIPS mode = %d\n", mode);
2675 SendPSMPAction(pAd, pEntry->Aid, mode);
2676 }
2677
2678 return TRUE;
2679 }
2680
2681 return FALSE;
2682
2683
2684}
2685
2686INT Set_HtMIMOPSmode_Proc(
2687 IN PRTMP_ADAPTER pAd,
2688 IN PUCHAR arg)
2689{
2690 ULONG Value;
2691
2692 Value = simple_strtol(arg, 0, 10);
2693
2694 if (Value <=3 && Value >= 0)
2695 pAd->CommonCfg.BACapability.field.MMPSmode = Value;
2696 else
2697 pAd->CommonCfg.BACapability.field.MMPSmode = 3;
2698
2699 SetCommonHT(pAd);
2700
2701 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMIMOPSmode_Proc::(MIMOPS mode=%d)\n",pAd->CommonCfg.BACapability.field.MMPSmode));
2702
2703 return TRUE;
2704}
2705
2706
2707INT Set_ForceShortGI_Proc(
2708 IN PRTMP_ADAPTER pAd,
2709 IN PUCHAR arg)
2710{
2711 ULONG Value;
2712
2713 Value = simple_strtol(arg, 0, 10);
2714 if (Value == 0)
2715 pAd->WIFItestbed.bShortGI = FALSE;
2716 else if (Value == 1)
2717 pAd->WIFItestbed.bShortGI = TRUE;
2718 else
2719 return FALSE; //Invalid argument
2720
2721 SetCommonHT(pAd);
2722
2723 DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceShortGI_Proc::(ForceShortGI=%d)\n", pAd->WIFItestbed.bShortGI));
2724
2725 return TRUE;
2726}
2727
2728
2729
2730INT Set_ForceGF_Proc(
2731 IN PRTMP_ADAPTER pAd,
2732 IN PUCHAR arg)
2733{
2734 ULONG Value;
2735
2736 Value = simple_strtol(arg, 0, 10);
2737 if (Value == 0)
2738 pAd->WIFItestbed.bGreenField = FALSE;
2739 else if (Value == 1)
2740 pAd->WIFItestbed.bGreenField = TRUE;
2741 else
2742 return FALSE; //Invalid argument
2743
2744 SetCommonHT(pAd);
2745
2746 DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceGF_Proc::(ForceGF=%d)\n", pAd->WIFItestbed.bGreenField));
2747
2748 return TRUE;
2749}
2750
2751INT Set_HtMimoPs_Proc(
2752 IN PRTMP_ADAPTER pAd,
2753 IN PUCHAR arg)
2754{
2755 ULONG Value;
2756
2757 Value = simple_strtol(arg, 0, 10);
2758 if (Value == 0)
2759 pAd->CommonCfg.bMIMOPSEnable = FALSE;
2760 else if (Value == 1)
2761 pAd->CommonCfg.bMIMOPSEnable = TRUE;
2762 else
2763 return FALSE; //Invalid argument
2764
2765 DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMimoPs_Proc::(HtMimoPs=%d)\n",pAd->CommonCfg.bMIMOPSEnable));
2766
2767 return TRUE;
2768}
2769#endif // DOT11_N_SUPPORT //
2770
2771
2772#ifdef DOT11_N_SUPPORT
2773INT SetCommonHT(
2774 IN PRTMP_ADAPTER pAd)
2775{
2776 OID_SET_HT_PHYMODE SetHT;
2777
2778 if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
2779 return FALSE;
2780
2781 SetHT.PhyMode = pAd->CommonCfg.PhyMode;
2782 SetHT.TransmitNo = ((UCHAR)pAd->Antenna.field.TxPath);
2783 SetHT.HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
2784 SetHT.ExtOffset = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
2785 SetHT.MCS = MCS_AUTO;
2786 SetHT.BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW;
2787 SetHT.STBC = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC;
2788 SetHT.SHORTGI = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
2789
2790 RTMPSetHT(pAd, &SetHT);
2791
2792 return TRUE;
2793}
2794#endif // DOT11_N_SUPPORT //
2795
2796INT Set_FixedTxMode_Proc(
2797 IN PRTMP_ADAPTER pAd,
2798 IN PUCHAR arg)
2799{
2800 UCHAR fix_tx_mode = FIXED_TXMODE_HT;
2801
2802 if (strcmp(arg, "OFDM") == 0 || strcmp(arg, "ofdm") == 0)
2803 {
2804 fix_tx_mode = FIXED_TXMODE_OFDM;
2805 }
2806 else if (strcmp(arg, "CCK") == 0 || strcmp(arg, "cck") == 0)
2807 {
2808 fix_tx_mode = FIXED_TXMODE_CCK;
2809 }
2810
2811#ifdef CONFIG_STA_SUPPORT
2812 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2813 pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
2814#endif // CONFIG_STA_SUPPORT //
2815
2816 DBGPRINT(RT_DEBUG_TRACE, ("Set_FixedTxMode_Proc::(FixedTxMode=%d)\n", fix_tx_mode));
2817
2818 return TRUE;
2819}
2820
2821#ifdef CONFIG_APSTA_MIXED_SUPPORT
2822INT Set_OpMode_Proc(
2823 IN PRTMP_ADAPTER pAd,
2824 IN PUCHAR arg)
2825{
2826 ULONG Value;
2827
2828 Value = simple_strtol(arg, 0, 10);
2829
2830#ifdef RT2860
2831 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2832#endif // RT2860 //
2833 {
2834 DBGPRINT(RT_DEBUG_ERROR, ("Can not switch operate mode on interface up !! \n"));
2835 return FALSE;
2836 }
2837
2838 if (Value == 0)
2839 pAd->OpMode = OPMODE_STA;
2840 else if (Value == 1)
2841 pAd->OpMode = OPMODE_AP;
2842 else
2843 return FALSE; //Invalid argument
2844
2845 DBGPRINT(RT_DEBUG_TRACE, ("Set_OpMode_Proc::(OpMode=%s)\n", pAd->OpMode == 1 ? "AP Mode" : "STA Mode"));
2846
2847 return TRUE;
2848}
2849#endif // CONFIG_APSTA_MIXED_SUPPORT //
2850
2851
2852/////////////////////////////////////////////////////////////////////////
2853PCHAR RTMPGetRalinkAuthModeStr(
2854 IN NDIS_802_11_AUTHENTICATION_MODE authMode)
2855{
2856 switch(authMode)
2857 {
2858 case Ndis802_11AuthModeOpen:
2859 return "OPEN";
2860 default:
2861 case Ndis802_11AuthModeWPAPSK:
2862 return "WPAPSK";
2863 case Ndis802_11AuthModeShared:
2864 return "SHARED";
2865 case Ndis802_11AuthModeWPA:
2866 return "WPA";
2867 case Ndis802_11AuthModeWPA2:
2868 return "WPA2";
2869 case Ndis802_11AuthModeWPA2PSK:
2870 return "WPA2PSK";
2871 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
2872 return "WPAPSKWPA2PSK";
2873 case Ndis802_11AuthModeWPA1WPA2:
2874 return "WPA1WPA2";
2875 case Ndis802_11AuthModeWPANone:
2876 return "WPANONE";
2877 }
2878}
2879
2880PCHAR RTMPGetRalinkEncryModeStr(
2881 IN USHORT encryMode)
2882{
2883 switch(encryMode)
2884 {
2885 default:
2886 case Ndis802_11WEPDisabled:
2887 return "NONE";
2888 case Ndis802_11WEPEnabled:
2889 return "WEP";
2890 case Ndis802_11Encryption2Enabled:
2891 return "TKIP";
2892 case Ndis802_11Encryption3Enabled:
2893 return "AES";
2894 case Ndis802_11Encryption4Enabled:
2895 return "TKIPAES";
2896 }
2897}
2898
2899INT RTMPShowCfgValue(
2900 IN PRTMP_ADAPTER pAd,
2901 IN PUCHAR pName,
2902 IN PUCHAR pBuf)
2903{
2904 INT Status = 0;
2905
2906 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++)
2907 {
2908 if (!strcmp(pName, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name))
2909 {
2910 if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->show_proc(pAd, pBuf))
2911 Status = -EINVAL;
2912 break; //Exit for loop.
2913 }
2914 }
2915
2916 if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name == NULL)
2917 {
2918 sprintf(pBuf, "\n");
2919 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++)
2920 sprintf(pBuf, "%s%s\n", pBuf, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name);
2921 }
2922
2923 return Status;
2924}
2925
2926INT Show_SSID_Proc(
2927 IN PRTMP_ADAPTER pAd,
2928 OUT PUCHAR pBuf)
2929{
2930
2931#ifdef CONFIG_STA_SUPPORT
2932 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2933 sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid);
2934#endif // CONFIG_STA_SUPPORT //
2935 return 0;
2936}
2937
2938INT Show_WirelessMode_Proc(
2939 IN PRTMP_ADAPTER pAd,
2940 OUT PUCHAR pBuf)
2941{
2942 switch(pAd->CommonCfg.PhyMode)
2943 {
2944 case PHY_11BG_MIXED:
2945 sprintf(pBuf, "\t11B/G");
2946 break;
2947 case PHY_11B:
2948 sprintf(pBuf, "\t11B");
2949 break;
2950 case PHY_11A:
2951 sprintf(pBuf, "\t11A");
2952 break;
2953 case PHY_11ABG_MIXED:
2954 sprintf(pBuf, "\t11A/B/G");
2955 break;
2956 case PHY_11G:
2957 sprintf(pBuf, "\t11G");
2958 break;
2959#ifdef DOT11_N_SUPPORT
2960 case PHY_11ABGN_MIXED:
2961 sprintf(pBuf, "\t11A/B/G/N");
2962 break;
2963 case PHY_11N_2_4G:
2964 sprintf(pBuf, "\t11N only with 2.4G");
2965 break;
2966 case PHY_11GN_MIXED:
2967 sprintf(pBuf, "\t11G/N");
2968 break;
2969 case PHY_11AN_MIXED:
2970 sprintf(pBuf, "\t11A/N");
2971 break;
2972 case PHY_11BGN_MIXED:
2973 sprintf(pBuf, "\t11B/G/N");
2974 break;
2975 case PHY_11AGN_MIXED:
2976 sprintf(pBuf, "\t11A/G/N");
2977 break;
2978 case PHY_11N_5G:
2979 sprintf(pBuf, "\t11N only with 5G");
2980 break;
2981#endif // DOT11_N_SUPPORT //
2982 default:
2983 sprintf(pBuf, "\tUnknow Value(%d)", pAd->CommonCfg.PhyMode);
2984 break;
2985 }
2986 return 0;
2987}
2988
2989
2990INT Show_TxBurst_Proc(
2991 IN PRTMP_ADAPTER pAd,
2992 OUT PUCHAR pBuf)
2993{
2994 sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE");
2995 return 0;
2996}
2997
2998INT Show_TxPreamble_Proc(
2999 IN PRTMP_ADAPTER pAd,
3000 OUT PUCHAR pBuf)
3001{
3002 switch(pAd->CommonCfg.TxPreamble)
3003 {
3004 case Rt802_11PreambleShort:
3005 sprintf(pBuf, "\tShort");
3006 break;
3007 case Rt802_11PreambleLong:
3008 sprintf(pBuf, "\tLong");
3009 break;
3010 case Rt802_11PreambleAuto:
3011 sprintf(pBuf, "\tAuto");
3012 break;
3013 default:
3014 sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.TxPreamble);
3015 break;
3016 }
3017
3018 return 0;
3019}
3020
3021INT Show_TxPower_Proc(
3022 IN PRTMP_ADAPTER pAd,
3023 OUT PUCHAR pBuf)
3024{
3025 sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage);
3026 return 0;
3027}
3028
3029INT Show_Channel_Proc(
3030 IN PRTMP_ADAPTER pAd,
3031 OUT PUCHAR pBuf)
3032{
3033 sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel);
3034 return 0;
3035}
3036
3037INT Show_BGProtection_Proc(
3038 IN PRTMP_ADAPTER pAd,
3039 OUT PUCHAR pBuf)
3040{
3041 switch(pAd->CommonCfg.UseBGProtection)
3042 {
3043 case 1: //Always On
3044 sprintf(pBuf, "\tON");
3045 break;
3046 case 2: //Always OFF
3047 sprintf(pBuf, "\tOFF");
3048 break;
3049 case 0: //AUTO
3050 sprintf(pBuf, "\tAuto");
3051 break;
3052 default:
3053 sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.UseBGProtection);
3054 break;
3055 }
3056 return 0;
3057}
3058
3059INT Show_RTSThreshold_Proc(
3060 IN PRTMP_ADAPTER pAd,
3061 OUT PUCHAR pBuf)
3062{
3063 sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold);
3064 return 0;
3065}
3066
3067INT Show_FragThreshold_Proc(
3068 IN PRTMP_ADAPTER pAd,
3069 OUT PUCHAR pBuf)
3070{
3071 sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold);
3072 return 0;
3073}
3074
3075#ifdef DOT11_N_SUPPORT
3076INT Show_HtBw_Proc(
3077 IN PRTMP_ADAPTER pAd,
3078 OUT PUCHAR pBuf)
3079{
3080 if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
3081 {
3082 sprintf(pBuf, "\t40 MHz");
3083 }
3084 else
3085 {
3086 sprintf(pBuf, "\t20 MHz");
3087 }
3088 return 0;
3089}
3090
3091INT Show_HtMcs_Proc(
3092 IN PRTMP_ADAPTER pAd,
3093 OUT PUCHAR pBuf)
3094{
3095
3096#ifdef CONFIG_STA_SUPPORT
3097 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3098 sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS);
3099#endif // CONFIG_STA_SUPPORT //
3100 return 0;
3101}
3102
3103INT Show_HtGi_Proc(
3104 IN PRTMP_ADAPTER pAd,
3105 OUT PUCHAR pBuf)
3106{
3107 switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI)
3108 {
3109 case GI_400:
3110 sprintf(pBuf, "\tGI_400");
3111 break;
3112 case GI_800:
3113 sprintf(pBuf, "\tGI_800");
3114 break;
3115 default:
3116 sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.ShortGI);
3117 break;
3118 }
3119 return 0;
3120}
3121
3122INT Show_HtOpMode_Proc(
3123 IN PRTMP_ADAPTER pAd,
3124 OUT PUCHAR pBuf)
3125{
3126 switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE)
3127 {
3128 case HTMODE_GF:
3129 sprintf(pBuf, "\tGF");
3130 break;
3131 case HTMODE_MM:
3132 sprintf(pBuf, "\tMM");
3133 break;
3134 default:
3135 sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.HTMODE);
3136 break;
3137 }
3138 return 0;
3139}
3140
3141INT Show_HtExtcha_Proc(
3142 IN PRTMP_ADAPTER pAd,
3143 OUT PUCHAR pBuf)
3144{
3145 switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA)
3146 {
3147 case EXTCHA_BELOW:
3148 sprintf(pBuf, "\tBelow");
3149 break;
3150 case EXTCHA_ABOVE:
3151 sprintf(pBuf, "\tAbove");
3152 break;
3153 default:
3154 sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.EXTCHA);
3155 break;
3156 }
3157 return 0;
3158}
3159
3160
3161INT Show_HtMpduDensity_Proc(
3162 IN PRTMP_ADAPTER pAd,
3163 OUT PUCHAR pBuf)
3164{
3165 sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity);
3166 return 0;
3167}
3168
3169INT Show_HtBaWinSize_Proc(
3170 IN PRTMP_ADAPTER pAd,
3171 OUT PUCHAR pBuf)
3172{
3173 sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit);
3174 return 0;
3175}
3176
3177INT Show_HtRdg_Proc(
3178 IN PRTMP_ADAPTER pAd,
3179 OUT PUCHAR pBuf)
3180{
3181 sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE");
3182 return 0;
3183}
3184
3185INT Show_HtAmsdu_Proc(
3186 IN PRTMP_ADAPTER pAd,
3187 OUT PUCHAR pBuf)
3188{
3189 sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE");
3190 return 0;
3191}
3192
3193INT Show_HtAutoBa_Proc(
3194 IN PRTMP_ADAPTER pAd,
3195 OUT PUCHAR pBuf)
3196{
3197 sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE");
3198 return 0;
3199}
3200#endif // DOT11_N_SUPPORT //
3201
3202INT Show_CountryRegion_Proc(
3203 IN PRTMP_ADAPTER pAd,
3204 OUT PUCHAR pBuf)
3205{
3206 sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion);
3207 return 0;
3208}
3209
3210INT Show_CountryRegionABand_Proc(
3211 IN PRTMP_ADAPTER pAd,
3212 OUT PUCHAR pBuf)
3213{
3214 sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand);
3215 return 0;
3216}
3217
3218INT Show_CountryCode_Proc(
3219 IN PRTMP_ADAPTER pAd,
3220 OUT PUCHAR pBuf)
3221{
3222 sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode);
3223 return 0;
3224}
3225
3226#ifdef AGGREGATION_SUPPORT
3227INT Show_PktAggregate_Proc(
3228 IN PRTMP_ADAPTER pAd,
3229 OUT PUCHAR pBuf)
3230{
3231 sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE");
3232 return 0;
3233}
3234#endif // AGGREGATION_SUPPORT //
3235
3236#ifdef WMM_SUPPORT
3237INT Show_WmmCapable_Proc(
3238 IN PRTMP_ADAPTER pAd,
3239 OUT PUCHAR pBuf)
3240{
3241
3242#ifdef CONFIG_STA_SUPPORT
3243 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3244 sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE");
3245#endif // CONFIG_STA_SUPPORT //
3246
3247 return 0;
3248}
3249#endif // WMM_SUPPORT //
3250
3251INT Show_IEEE80211H_Proc(
3252 IN PRTMP_ADAPTER pAd,
3253 OUT PUCHAR pBuf)
3254{
3255 sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE");
3256 return 0;
3257}
3258
3259#ifdef CONFIG_STA_SUPPORT
3260INT Show_NetworkType_Proc(
3261 IN PRTMP_ADAPTER pAd,
3262 OUT PUCHAR pBuf)
3263{
3264 switch(pAd->StaCfg.BssType)
3265 {
3266 case BSS_ADHOC:
3267 sprintf(pBuf, "\tAdhoc");
3268 break;
3269 case BSS_INFRA:
3270 sprintf(pBuf, "\tInfra");
3271 break;
3272 case BSS_ANY:
3273 sprintf(pBuf, "\tAny");
3274 break;
3275 case BSS_MONITOR:
3276 sprintf(pBuf, "\tMonitor");
3277 break;
3278 default:
3279 sprintf(pBuf, "\tUnknow Value(%d)", pAd->StaCfg.BssType);
3280 break;
3281 }
3282 return 0;
3283}
3284#endif // CONFIG_STA_SUPPORT //
3285
3286INT Show_AuthMode_Proc(
3287 IN PRTMP_ADAPTER pAd,
3288 OUT PUCHAR pBuf)
3289{
3290 NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeOpen;
3291
3292#ifdef CONFIG_STA_SUPPORT
3293 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3294 AuthMode = pAd->StaCfg.AuthMode;
3295#endif // CONFIG_STA_SUPPORT //
3296
3297 if ((AuthMode >= Ndis802_11AuthModeOpen) &&
3298 (AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
3299 sprintf(pBuf, "\t%s", RTMPGetRalinkAuthModeStr(AuthMode));
3300 else
3301 sprintf(pBuf, "\tUnknow Value(%d)", AuthMode);
3302
3303 return 0;
3304}
3305
3306INT Show_EncrypType_Proc(
3307 IN PRTMP_ADAPTER pAd,
3308 OUT PUCHAR pBuf)
3309{
3310 NDIS_802_11_WEP_STATUS WepStatus = Ndis802_11WEPDisabled;
3311
3312#ifdef CONFIG_STA_SUPPORT
3313 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3314 WepStatus = pAd->StaCfg.WepStatus;
3315#endif // CONFIG_STA_SUPPORT //
3316
3317 if ((WepStatus >= Ndis802_11WEPEnabled) &&
3318 (WepStatus <= Ndis802_11Encryption4KeyAbsent))
3319 sprintf(pBuf, "\t%s", RTMPGetRalinkEncryModeStr(WepStatus));
3320 else
3321 sprintf(pBuf, "\tUnknow Value(%d)", WepStatus);
3322
3323 return 0;
3324}
3325
3326INT Show_DefaultKeyID_Proc(
3327 IN PRTMP_ADAPTER pAd,
3328 OUT PUCHAR pBuf)
3329{
3330 UCHAR DefaultKeyId = 0;
3331
3332#ifdef CONFIG_STA_SUPPORT
3333 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3334 DefaultKeyId = pAd->StaCfg.DefaultKeyId;
3335#endif // CONFIG_STA_SUPPORT //
3336
3337 sprintf(pBuf, "\t%d", DefaultKeyId);
3338
3339 return 0;
3340}
3341
3342INT Show_WepKey_Proc(
3343 IN PRTMP_ADAPTER pAd,
3344 IN INT KeyIdx,
3345 OUT PUCHAR pBuf)
3346{
3347 UCHAR Key[16] = {0}, KeyLength = 0;
3348 INT index = BSS0;
3349
3350 KeyLength = pAd->SharedKey[index][KeyIdx].KeyLen;
3351 NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength);
3352
3353 //check key string is ASCII or not
3354 if (RTMPCheckStrPrintAble(Key, KeyLength))
3355 sprintf(pBuf, "\t%s", Key);
3356 else
3357 {
3358 int idx;
3359 sprintf(pBuf, "\t");
3360 for (idx = 0; idx < KeyLength; idx++)
3361 sprintf(pBuf+strlen(pBuf), "%02X", Key[idx]);
3362 }
3363 return 0;
3364}
3365
3366INT Show_Key1_Proc(
3367 IN PRTMP_ADAPTER pAd,
3368 OUT PUCHAR pBuf)
3369{
3370 Show_WepKey_Proc(pAd, 0, pBuf);
3371 return 0;
3372}
3373
3374INT Show_Key2_Proc(
3375 IN PRTMP_ADAPTER pAd,
3376 OUT PUCHAR pBuf)
3377{
3378 Show_WepKey_Proc(pAd, 1, pBuf);
3379 return 0;
3380}
3381
3382INT Show_Key3_Proc(
3383 IN PRTMP_ADAPTER pAd,
3384 OUT PUCHAR pBuf)
3385{
3386 Show_WepKey_Proc(pAd, 2, pBuf);
3387 return 0;
3388}
3389
3390INT Show_Key4_Proc(
3391 IN PRTMP_ADAPTER pAd,
3392 OUT PUCHAR pBuf)
3393{
3394 Show_WepKey_Proc(pAd, 3, pBuf);
3395 return 0;
3396}
3397
3398INT Show_WPAPSK_Proc(
3399 IN PRTMP_ADAPTER pAd,
3400 OUT PUCHAR pBuf)
3401{
3402 INT idx;
3403 UCHAR PMK[32] = {0};
3404
3405
3406#ifdef CONFIG_STA_SUPPORT
3407 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3408 NdisMoveMemory(PMK, pAd->StaCfg.PMK, 32);
3409#endif // CONFIG_STA_SUPPORT //
3410
3411 sprintf(pBuf, "\tPMK = ");
3412 for (idx = 0; idx < 32; idx++)
3413 sprintf(pBuf+strlen(pBuf), "%02X", PMK[idx]);
3414
3415 return 0;
3416}
3417
diff --git a/drivers/staging/rt2860/common/cmm_sanity.c b/drivers/staging/rt2860/common/cmm_sanity.c
new file mode 100644
index 00000000000..b0f070d4313
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_sanity.c
@@ -0,0 +1,1633 @@
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 if ((pInfo->pAddr[0]&0x01) == 0x01)
85 {
86 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
87 return FALSE;
88 }
89
90 return TRUE;
91}
92
93/*
94 ==========================================================================
95 Description:
96 MLME message sanity check
97 Return:
98 TRUE if all parameters are OK, FALSE otherwise
99
100 IRQL = DISPATCH_LEVEL
101
102 ==========================================================================
103 */
104BOOLEAN MlmeDelBAReqSanity(
105 IN PRTMP_ADAPTER pAd,
106 IN VOID *Msg,
107 IN ULONG MsgLen)
108{
109 MLME_DELBA_REQ_STRUCT *pInfo;
110 pInfo = (MLME_DELBA_REQ_STRUCT *)Msg;
111
112 if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT)))
113 {
114 DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
115 return FALSE;
116 }
117
118 if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
119 {
120 DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
121 return FALSE;
122 }
123
124 if ((pInfo->TID & 0xf0))
125 {
126 DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
127 return FALSE;
128 }
129
130 if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0)
131 {
132 DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
133 return FALSE;
134 }
135
136 return TRUE;
137}
138
139BOOLEAN PeerAddBAReqActionSanity(
140 IN PRTMP_ADAPTER pAd,
141 IN VOID *pMsg,
142 IN ULONG MsgLen,
143 OUT PUCHAR pAddr2)
144{
145 PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
146 PFRAME_ADDBA_REQ pAddFrame;
147 pAddFrame = (PFRAME_ADDBA_REQ)(pMsg);
148 if (MsgLen < (sizeof(FRAME_ADDBA_REQ)))
149 {
150 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen));
151 return FALSE;
152 }
153 // we support immediate BA.
154 *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
155 pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
156 pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word);
157
158 if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
159 {
160 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
161 DBGPRINT(RT_DEBUG_ERROR,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, pAddFrame->BaParm.AMSDUSupported));
162 return FALSE;
163 }
164
165 // we support immediate BA.
166 if (pAddFrame->BaParm.TID &0xfff0)
167 {
168 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", pAddFrame->BaParm.TID));
169 return FALSE;
170 }
171 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
172 return TRUE;
173}
174
175BOOLEAN PeerAddBARspActionSanity(
176 IN PRTMP_ADAPTER pAd,
177 IN VOID *pMsg,
178 IN ULONG MsgLen)
179{
180 PFRAME_ADDBA_RSP pAddFrame;
181
182 pAddFrame = (PFRAME_ADDBA_RSP)(pMsg);
183 if (MsgLen < (sizeof(FRAME_ADDBA_RSP)))
184 {
185 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen));
186 return FALSE;
187 }
188 // we support immediate BA.
189 *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
190 pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode);
191 pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
192
193 if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
194 {
195 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
196 return FALSE;
197 }
198
199 // we support immediate BA.
200 if (pAddFrame->BaParm.TID &0xfff0)
201 {
202 DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", pAddFrame->BaParm.TID));
203 return FALSE;
204 }
205 return TRUE;
206
207}
208
209BOOLEAN PeerDelBAActionSanity(
210 IN PRTMP_ADAPTER pAd,
211 IN UCHAR Wcid,
212 IN VOID *pMsg,
213 IN ULONG MsgLen )
214{
215 //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
216 PFRAME_DELBA_REQ pDelFrame;
217 if (MsgLen != (sizeof(FRAME_DELBA_REQ)))
218 return FALSE;
219
220 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
221 return FALSE;
222
223 pDelFrame = (PFRAME_DELBA_REQ)(pMsg);
224
225 *(USHORT *)(&pDelFrame->DelbaParm) = cpu2le16(*(USHORT *)(&pDelFrame->DelbaParm));
226 pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode);
227
228 if (pDelFrame->DelbaParm.TID &0xfff0)
229 return FALSE;
230
231 return TRUE;
232}
233
234/*
235 ==========================================================================
236 Description:
237 MLME message sanity check
238 Return:
239 TRUE if all parameters are OK, FALSE otherwise
240
241 IRQL = DISPATCH_LEVEL
242
243 ==========================================================================
244 */
245BOOLEAN PeerBeaconAndProbeRspSanity(
246 IN PRTMP_ADAPTER pAd,
247 IN VOID *Msg,
248 IN ULONG MsgLen,
249 IN UCHAR MsgChannel,
250 OUT PUCHAR pAddr2,
251 OUT PUCHAR pBssid,
252 OUT CHAR Ssid[],
253 OUT UCHAR *pSsidLen,
254 OUT UCHAR *pBssType,
255 OUT USHORT *pBeaconPeriod,
256 OUT UCHAR *pChannel,
257 OUT UCHAR *pNewChannel,
258 OUT LARGE_INTEGER *pTimestamp,
259 OUT CF_PARM *pCfParm,
260 OUT USHORT *pAtimWin,
261 OUT USHORT *pCapabilityInfo,
262 OUT UCHAR *pErp,
263 OUT UCHAR *pDtimCount,
264 OUT UCHAR *pDtimPeriod,
265 OUT UCHAR *pBcastFlag,
266 OUT UCHAR *pMessageToMe,
267 OUT UCHAR SupRate[],
268 OUT UCHAR *pSupRateLen,
269 OUT UCHAR ExtRate[],
270 OUT UCHAR *pExtRateLen,
271 OUT UCHAR *pCkipFlag,
272 OUT UCHAR *pAironetCellPowerLimit,
273 OUT PEDCA_PARM pEdcaParm,
274 OUT PQBSS_LOAD_PARM pQbssLoad,
275 OUT PQOS_CAPABILITY_PARM pQosCapability,
276 OUT ULONG *pRalinkIe,
277 OUT UCHAR *pHtCapabilityLen,
278#ifdef CONFIG_STA_SUPPORT
279 OUT UCHAR *pPreNHtCapabilityLen,
280#endif // CONFIG_STA_SUPPORT //
281 OUT HT_CAPABILITY_IE *pHtCapability,
282 OUT UCHAR *AddHtInfoLen,
283 OUT ADD_HT_INFO_IE *AddHtInfo,
284 OUT UCHAR *NewExtChannelOffset, // Ht extension channel offset(above or below)
285 OUT USHORT *LengthVIE,
286 OUT PNDIS_802_11_VARIABLE_IEs pVIE)
287{
288 CHAR *Ptr;
289#ifdef CONFIG_STA_SUPPORT
290 CHAR TimLen;
291#endif // CONFIG_STA_SUPPORT //
292 PFRAME_802_11 pFrame;
293 PEID_STRUCT pEid;
294 UCHAR SubType;
295 UCHAR Sanity;
296 //UCHAR ECWMin, ECWMax;
297 //MAC_CSR9_STRUC Csr9;
298 ULONG Length = 0;
299
300 // For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel
301 // 1. If the AP is 11n enabled, then check the control channel.
302 // 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!)
303 UCHAR CtrlChannel = 0;
304
305 // Add for 3 necessary EID field check
306 Sanity = 0;
307
308 *pAtimWin = 0;
309 *pErp = 0;
310 *pDtimCount = 0;
311 *pDtimPeriod = 0;
312 *pBcastFlag = 0;
313 *pMessageToMe = 0;
314 *pExtRateLen = 0;
315 *pCkipFlag = 0; // Default of CkipFlag is 0
316 *pAironetCellPowerLimit = 0xFF; // Default of AironetCellPowerLimit is 0xFF
317 *LengthVIE = 0; // Set the length of VIE to init value 0
318 *pHtCapabilityLen = 0; // Set the length of VIE to init value 0
319#ifdef CONFIG_STA_SUPPORT
320 if (pAd->OpMode == OPMODE_STA)
321 *pPreNHtCapabilityLen = 0; // Set the length of VIE to init value 0
322#endif // CONFIG_STA_SUPPORT //
323 *AddHtInfoLen = 0; // Set the length of VIE to init value 0
324 *pRalinkIe = 0;
325 *pNewChannel = 0;
326 *NewExtChannelOffset = 0xff; //Default 0xff means no such IE
327 pCfParm->bValid = FALSE; // default: no IE_CF found
328 pQbssLoad->bValid = FALSE; // default: no IE_QBSS_LOAD found
329 pEdcaParm->bValid = FALSE; // default: no IE_EDCA_PARAMETER found
330 pQosCapability->bValid = FALSE; // default: no IE_QOS_CAPABILITY found
331
332 pFrame = (PFRAME_802_11)Msg;
333
334 // get subtype from header
335 SubType = (UCHAR)pFrame->Hdr.FC.SubType;
336
337 // get Addr2 and BSSID from header
338 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
339 COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
340
341 Ptr = pFrame->Octet;
342 Length += LENGTH_802_11;
343
344 // get timestamp from payload and advance the pointer
345 NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
346
347 pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart);
348 pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart);
349
350 Ptr += TIMESTAMP_LEN;
351 Length += TIMESTAMP_LEN;
352
353 // get beacon interval from payload and advance the pointer
354 NdisMoveMemory(pBeaconPeriod, Ptr, 2);
355 Ptr += 2;
356 Length += 2;
357
358 // get capability info from payload and advance the pointer
359 NdisMoveMemory(pCapabilityInfo, Ptr, 2);
360 Ptr += 2;
361 Length += 2;
362
363 if (CAP_IS_ESS_ON(*pCapabilityInfo))
364 *pBssType = BSS_INFRA;
365 else
366 *pBssType = BSS_ADHOC;
367
368 pEid = (PEID_STRUCT) Ptr;
369
370 // get variable fields from payload and advance the pointer
371 while ((Length + 2 + pEid->Len) <= MsgLen)
372 {
373 //
374 // Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow.
375 //
376 if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN)
377 {
378 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
379 (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN));
380 break;
381 }
382
383 switch(pEid->Eid)
384 {
385 case IE_SSID:
386 // Already has one SSID EID in this beacon, ignore the second one
387 if (Sanity & 0x1)
388 break;
389 if(pEid->Len <= MAX_LEN_OF_SSID)
390 {
391 NdisMoveMemory(Ssid, pEid->Octet, pEid->Len);
392 *pSsidLen = pEid->Len;
393 Sanity |= 0x1;
394 }
395 else
396 {
397 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
398 return FALSE;
399 }
400 break;
401
402 case IE_SUPP_RATES:
403 if(pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
404 {
405 Sanity |= 0x2;
406 NdisMoveMemory(SupRate, pEid->Octet, pEid->Len);
407 *pSupRateLen = pEid->Len;
408
409 // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
410 // from ScanTab. We should report as is. And filter out unsupported
411 // rates in MlmeAux.
412 // Check against the supported rates
413 // RTMPCheckRates(pAd, SupRate, pSupRateLen);
414 }
415 else
416 {
417 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid->Len));
418 return FALSE;
419 }
420 break;
421
422 case IE_HT_CAP:
423 if (pEid->Len >= SIZE_HT_CAP_IE) //Note: allow extension.!!
424 {
425 NdisMoveMemory(pHtCapability, pEid->Octet, sizeof(HT_CAPABILITY_IE));
426 *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
427
428 *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
429 *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
430
431#ifdef CONFIG_STA_SUPPORT
432 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
433 {
434 *pPreNHtCapabilityLen = 0; // Nnow we only support 26 bytes.
435
436 Ptr = (PUCHAR) pVIE;
437 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
438 *LengthVIE += (pEid->Len + 2);
439 }
440#endif // CONFIG_STA_SUPPORT //
441 }
442 else
443 {
444 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid->Len));
445 }
446
447 break;
448 case IE_ADD_HT:
449 if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
450 {
451 // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
452 // copy first sizeof(ADD_HT_INFO_IE)
453 NdisMoveMemory(AddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
454 *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
455
456 CtrlChannel = AddHtInfo->ControlChan;
457
458 *(USHORT *)(&AddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo2));
459 *(USHORT *)(&AddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo3));
460
461#ifdef CONFIG_STA_SUPPORT
462 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
463 {
464 Ptr = (PUCHAR) pVIE;
465 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
466 *LengthVIE += (pEid->Len + 2);
467 }
468#endif // CONFIG_STA_SUPPORT //
469 }
470 else
471 {
472 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
473 }
474
475 break;
476 case IE_SECONDARY_CH_OFFSET:
477 if (pEid->Len == 1)
478 {
479 *NewExtChannelOffset = pEid->Octet[0];
480 }
481 else
482 {
483 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
484 }
485
486 break;
487 case IE_FH_PARM:
488 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
489 break;
490
491 case IE_DS_PARM:
492 if(pEid->Len == 1)
493 {
494 *pChannel = *pEid->Octet;
495#ifdef CONFIG_STA_SUPPORT
496 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
497 {
498 if (ChannelSanity(pAd, *pChannel) == 0)
499 {
500
501 return FALSE;
502 }
503 }
504#endif // CONFIG_STA_SUPPORT //
505 Sanity |= 0x4;
506 }
507 else
508 {
509 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid->Len));
510 return FALSE;
511 }
512 break;
513
514 case IE_CF_PARM:
515 if(pEid->Len == 6)
516 {
517 pCfParm->bValid = TRUE;
518 pCfParm->CfpCount = pEid->Octet[0];
519 pCfParm->CfpPeriod = pEid->Octet[1];
520 pCfParm->CfpMaxDuration = pEid->Octet[2] + 256 * pEid->Octet[3];
521 pCfParm->CfpDurRemaining = pEid->Octet[4] + 256 * pEid->Octet[5];
522 }
523 else
524 {
525 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
526 return FALSE;
527 }
528 break;
529
530 case IE_IBSS_PARM:
531 if(pEid->Len == 2)
532 {
533 NdisMoveMemory(pAtimWin, pEid->Octet, pEid->Len);
534 }
535 else
536 {
537 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
538 return FALSE;
539 }
540 break;
541
542#ifdef CONFIG_STA_SUPPORT
543 case IE_TIM:
544 if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON)
545 {
546 GetTimBit((PUCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe);
547 }
548 break;
549#endif // CONFIG_STA_SUPPORT //
550 case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
551 if(pEid->Len == 3)
552 {
553 *pNewChannel = pEid->Octet[1]; //extract new channel number
554 }
555 break;
556
557 // New for WPA
558 // CCX v2 has the same IE, we need to parse that too
559 // Wifi WMM use the same IE vale, need to parse that too
560 // case IE_WPA:
561 case IE_VENDOR_SPECIFIC:
562 // Check the OUI version, filter out non-standard usage
563 if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7))
564 {
565 //*pRalinkIe = pEid->Octet[3];
566 if (pEid->Octet[3] != 0)
567 *pRalinkIe = pEid->Octet[3];
568 else
569 *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.
570 }
571#ifdef CONFIG_STA_SUPPORT
572#ifdef DOT11_N_SUPPORT
573 // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
574
575 // Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP,
576 // Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE
577 else if ((*pHtCapabilityLen == 0) && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, 3) && (pEid->Len >= 4) && (pAd->OpMode == OPMODE_STA))
578 {
579 if ((pEid->Octet[3] == OUI_PREN_HT_CAP) && (pEid->Len >= 30) && (*pHtCapabilityLen == 0))
580 {
581 NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
582 *pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
583 }
584
585 if ((pEid->Octet[3] == OUI_PREN_ADD_HT) && (pEid->Len >= 26))
586 {
587 NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
588 *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
589 }
590 }
591#endif // DOT11_N_SUPPORT //
592#endif // CONFIG_STA_SUPPORT //
593 else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
594 {
595 // Copy to pVIE which will report to microsoft bssid list.
596 Ptr = (PUCHAR) pVIE;
597 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
598 *LengthVIE += (pEid->Len + 2);
599 }
600 else if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
601 {
602 PUCHAR ptr;
603 int i;
604
605 // parsing EDCA parameters
606 pEdcaParm->bValid = TRUE;
607 pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
608 pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
609 pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
610 pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
611 pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
612 ptr = &pEid->Octet[8];
613 for (i=0; i<4; i++)
614 {
615 UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
616 pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); // b5 is ACM
617 pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; // b0~3 is AIFSN
618 pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f; // b0~4 is Cwmin
619 pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4; // b5~8 is Cwmax
620 pEdcaParm->Txop[aci] = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
621 ptr += 4; // point to next AC
622 }
623 }
624 else if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) && (pEid->Len == 7))
625 {
626 // parsing EDCA parameters
627 pEdcaParm->bValid = TRUE;
628 pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
629 pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
630 pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
631 pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
632 pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
633
634 // use default EDCA parameter
635 pEdcaParm->bACM[QID_AC_BE] = 0;
636 pEdcaParm->Aifsn[QID_AC_BE] = 3;
637 pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
638 pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
639 pEdcaParm->Txop[QID_AC_BE] = 0;
640
641 pEdcaParm->bACM[QID_AC_BK] = 0;
642 pEdcaParm->Aifsn[QID_AC_BK] = 7;
643 pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
644 pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
645 pEdcaParm->Txop[QID_AC_BK] = 0;
646
647 pEdcaParm->bACM[QID_AC_VI] = 0;
648 pEdcaParm->Aifsn[QID_AC_VI] = 2;
649 pEdcaParm->Cwmin[QID_AC_VI] = CW_MIN_IN_BITS-1;
650 pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
651 pEdcaParm->Txop[QID_AC_VI] = 96; // AC_VI: 96*32us ~= 3ms
652
653 pEdcaParm->bACM[QID_AC_VO] = 0;
654 pEdcaParm->Aifsn[QID_AC_VO] = 2;
655 pEdcaParm->Cwmin[QID_AC_VO] = CW_MIN_IN_BITS-2;
656 pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1;
657 pEdcaParm->Txop[QID_AC_VO] = 48; // AC_VO: 48*32us ~= 1.5ms
658 }
659 break;
660
661 case IE_EXT_SUPP_RATES:
662 if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
663 {
664 NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
665 *pExtRateLen = pEid->Len;
666
667 // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
668 // from ScanTab. We should report as is. And filter out unsupported
669 // rates in MlmeAux.
670 // Check against the supported rates
671 // RTMPCheckRates(pAd, ExtRate, pExtRateLen);
672 }
673 break;
674
675 case IE_ERP:
676 if (pEid->Len == 1)
677 {
678 *pErp = (UCHAR)pEid->Octet[0];
679 }
680 break;
681
682 case IE_AIRONET_CKIP:
683 // 0. Check Aironet IE length, it must be larger or equal to 28
684 // Cisco AP350 used length as 28
685 // Cisco AP12XX used length as 30
686 if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
687 break;
688
689 // 1. Copy CKIP flag byte to buffer for process
690 *pCkipFlag = *(pEid->Octet + 8);
691 break;
692
693 case IE_AP_TX_POWER:
694 // AP Control of Client Transmit Power
695 //0. Check Aironet IE length, it must be 6
696 if (pEid->Len != 0x06)
697 break;
698
699 // Get cell power limit in dBm
700 if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
701 *pAironetCellPowerLimit = *(pEid->Octet + 4);
702 break;
703
704 // WPA2 & 802.11i RSN
705 case IE_RSN:
706 // There is no OUI for version anymore, check the group cipher OUI before copying
707 if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
708 {
709 // Copy to pVIE which will report to microsoft bssid list.
710 Ptr = (PUCHAR) pVIE;
711 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
712 *LengthVIE += (pEid->Len + 2);
713 }
714 break;
715#ifdef CONFIG_STA_SUPPORT
716#ifdef EXT_BUILD_CHANNEL_LIST
717 case IE_COUNTRY:
718 Ptr = (PUCHAR) pVIE;
719 NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
720 *LengthVIE += (pEid->Len + 2);
721 break;
722#endif // EXT_BUILD_CHANNEL_LIST //
723#endif // CONFIG_STA_SUPPORT //
724
725 default:
726 break;
727 }
728
729 Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
730 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
731 }
732
733 // For some 11a AP. it did not have the channel EID, patch here
734#ifdef CONFIG_STA_SUPPORT
735 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
736 {
737 UCHAR LatchRfChannel = MsgChannel;
738 if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0))
739 {
740 if (CtrlChannel != 0)
741 *pChannel = CtrlChannel;
742 else
743 *pChannel = LatchRfChannel;
744 Sanity |= 0x4;
745 }
746 }
747#endif // CONFIG_STA_SUPPORT //
748
749 if (Sanity != 0x7)
750 {
751 DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
752 return FALSE;
753 }
754 else
755 {
756 return TRUE;
757 }
758
759}
760
761#ifdef DOT11N_DRAFT3
762/*
763 ==========================================================================
764 Description:
765 MLME message sanity check for some IE addressed in 802.11n d3.03.
766 Return:
767 TRUE if all parameters are OK, FALSE otherwise
768
769 IRQL = DISPATCH_LEVEL
770
771 ==========================================================================
772 */
773BOOLEAN PeerBeaconAndProbeRspSanity2(
774 IN PRTMP_ADAPTER pAd,
775 IN VOID *Msg,
776 IN ULONG MsgLen,
777 OUT UCHAR *RegClass)
778{
779 CHAR *Ptr;
780 PFRAME_802_11 pFrame;
781 PEID_STRUCT pEid;
782 ULONG Length = 0;
783
784 pFrame = (PFRAME_802_11)Msg;
785
786 *RegClass = 0;
787 Ptr = pFrame->Octet;
788 Length += LENGTH_802_11;
789
790 // get timestamp from payload and advance the pointer
791 Ptr += TIMESTAMP_LEN;
792 Length += TIMESTAMP_LEN;
793
794 // get beacon interval from payload and advance the pointer
795 Ptr += 2;
796 Length += 2;
797
798 // get capability info from payload and advance the pointer
799 Ptr += 2;
800 Length += 2;
801
802 pEid = (PEID_STRUCT) Ptr;
803
804 // get variable fields from payload and advance the pointer
805 while ((Length + 2 + pEid->Len) <= MsgLen)
806 {
807 switch(pEid->Eid)
808 {
809 case IE_SUPP_REG_CLASS:
810 if(pEid->Len > 0)
811 {
812 *RegClass = *pEid->Octet;
813 }
814 else
815 {
816 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
817 return FALSE;
818 }
819 break;
820 }
821
822 Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
823 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
824 }
825
826 return TRUE;
827
828}
829#endif // DOT11N_DRAFT3 //
830
831/*
832 ==========================================================================
833 Description:
834 MLME message sanity check
835 Return:
836 TRUE if all parameters are OK, FALSE otherwise
837 ==========================================================================
838 */
839BOOLEAN MlmeScanReqSanity(
840 IN PRTMP_ADAPTER pAd,
841 IN VOID *Msg,
842 IN ULONG MsgLen,
843 OUT UCHAR *pBssType,
844 OUT CHAR Ssid[],
845 OUT UCHAR *pSsidLen,
846 OUT UCHAR *pScanType)
847{
848 MLME_SCAN_REQ_STRUCT *Info;
849
850 Info = (MLME_SCAN_REQ_STRUCT *)(Msg);
851 *pBssType = Info->BssType;
852 *pSsidLen = Info->SsidLen;
853 NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
854 *pScanType = Info->ScanType;
855
856 if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY)
857 && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE
858#ifdef CONFIG_STA_SUPPORT
859 || *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE
860 || *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE
861#endif // CONFIG_STA_SUPPORT //
862 ))
863 {
864 return TRUE;
865 }
866 else
867 {
868 DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
869 return FALSE;
870 }
871}
872
873// IRQL = DISPATCH_LEVEL
874UCHAR ChannelSanity(
875 IN PRTMP_ADAPTER pAd,
876 IN UCHAR channel)
877{
878 int i;
879
880 for (i = 0; i < pAd->ChannelListNum; i ++)
881 {
882 if (channel == pAd->ChannelList[i].Channel)
883 return 1;
884 }
885 return 0;
886}
887
888/*
889 ==========================================================================
890 Description:
891 MLME message sanity check
892 Return:
893 TRUE if all parameters are OK, FALSE otherwise
894
895 IRQL = DISPATCH_LEVEL
896
897 ==========================================================================
898 */
899BOOLEAN PeerDeauthSanity(
900 IN PRTMP_ADAPTER pAd,
901 IN VOID *Msg,
902 IN ULONG MsgLen,
903 OUT PUCHAR pAddr2,
904 OUT USHORT *pReason)
905{
906 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
907
908 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
909 NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
910
911 return TRUE;
912}
913
914/*
915 ==========================================================================
916 Description:
917 MLME message sanity check
918 Return:
919 TRUE if all parameters are OK, FALSE otherwise
920
921 IRQL = DISPATCH_LEVEL
922
923 ==========================================================================
924 */
925BOOLEAN PeerAuthSanity(
926 IN PRTMP_ADAPTER pAd,
927 IN VOID *Msg,
928 IN ULONG MsgLen,
929 OUT PUCHAR pAddr,
930 OUT USHORT *pAlg,
931 OUT USHORT *pSeq,
932 OUT USHORT *pStatus,
933 CHAR *pChlgText)
934{
935 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
936
937 COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2);
938 NdisMoveMemory(pAlg, &pFrame->Octet[0], 2);
939 NdisMoveMemory(pSeq, &pFrame->Octet[2], 2);
940 NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
941
942 if ((*pAlg == Ndis802_11AuthModeOpen)
943#ifdef LEAP_SUPPORT
944 || (*pAlg == CISCO_AuthModeLEAP)
945#endif // LEAP_SUPPORT //
946 )
947 {
948 if (*pSeq == 1 || *pSeq == 2)
949 {
950 return TRUE;
951 }
952 else
953 {
954 DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
955 return FALSE;
956 }
957 }
958 else if (*pAlg == Ndis802_11AuthModeShared)
959 {
960 if (*pSeq == 1 || *pSeq == 4)
961 {
962 return TRUE;
963 }
964 else if (*pSeq == 2 || *pSeq == 3)
965 {
966 NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN);
967 return TRUE;
968 }
969 else
970 {
971 DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
972 return FALSE;
973 }
974 }
975 else
976 {
977 DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n"));
978 return FALSE;
979 }
980}
981
982/*
983 ==========================================================================
984 Description:
985 MLME message sanity check
986 Return:
987 TRUE if all parameters are OK, FALSE otherwise
988 ==========================================================================
989 */
990BOOLEAN MlmeAuthReqSanity(
991 IN PRTMP_ADAPTER pAd,
992 IN VOID *Msg,
993 IN ULONG MsgLen,
994 OUT PUCHAR pAddr,
995 OUT ULONG *pTimeout,
996 OUT USHORT *pAlg)
997{
998 MLME_AUTH_REQ_STRUCT *pInfo;
999
1000 pInfo = (MLME_AUTH_REQ_STRUCT *)Msg;
1001 COPY_MAC_ADDR(pAddr, pInfo->Addr);
1002 *pTimeout = pInfo->Timeout;
1003 *pAlg = pInfo->Alg;
1004
1005 if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen)
1006#ifdef LEAP_SUPPORT
1007 || (*pAlg == CISCO_AuthModeLEAP)
1008#endif // LEAP_SUPPORT //
1009 ) &&
1010 ((*pAddr & 0x01) == 0))
1011 {
1012 return TRUE;
1013 }
1014 else
1015 {
1016 DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n"));
1017 return FALSE;
1018 }
1019}
1020
1021/*
1022 ==========================================================================
1023 Description:
1024 MLME message sanity check
1025 Return:
1026 TRUE if all parameters are OK, FALSE otherwise
1027
1028 IRQL = DISPATCH_LEVEL
1029
1030 ==========================================================================
1031 */
1032BOOLEAN MlmeAssocReqSanity(
1033 IN PRTMP_ADAPTER pAd,
1034 IN VOID *Msg,
1035 IN ULONG MsgLen,
1036 OUT PUCHAR pApAddr,
1037 OUT USHORT *pCapabilityInfo,
1038 OUT ULONG *pTimeout,
1039 OUT USHORT *pListenIntv)
1040{
1041 MLME_ASSOC_REQ_STRUCT *pInfo;
1042
1043 pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg;
1044 *pTimeout = pInfo->Timeout; // timeout
1045 COPY_MAC_ADDR(pApAddr, pInfo->Addr); // AP address
1046 *pCapabilityInfo = pInfo->CapabilityInfo; // capability info
1047 *pListenIntv = pInfo->ListenIntv;
1048
1049 return TRUE;
1050}
1051
1052/*
1053 ==========================================================================
1054 Description:
1055 MLME message sanity check
1056 Return:
1057 TRUE if all parameters are OK, FALSE otherwise
1058
1059 IRQL = DISPATCH_LEVEL
1060
1061 ==========================================================================
1062 */
1063BOOLEAN PeerDisassocSanity(
1064 IN PRTMP_ADAPTER pAd,
1065 IN VOID *Msg,
1066 IN ULONG MsgLen,
1067 OUT PUCHAR pAddr2,
1068 OUT USHORT *pReason)
1069{
1070 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
1071
1072 COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
1073 NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
1074
1075 return TRUE;
1076}
1077
1078/*
1079 ========================================================================
1080 Routine Description:
1081 Sanity check NetworkType (11b, 11g or 11a)
1082
1083 Arguments:
1084 pBss - Pointer to BSS table.
1085
1086 Return Value:
1087 Ndis802_11DS .......(11b)
1088 Ndis802_11OFDM24....(11g)
1089 Ndis802_11OFDM5.....(11a)
1090
1091 IRQL = DISPATCH_LEVEL
1092
1093 ========================================================================
1094*/
1095NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
1096 IN PBSS_ENTRY pBss)
1097{
1098 NDIS_802_11_NETWORK_TYPE NetWorkType;
1099 UCHAR rate, i;
1100
1101 NetWorkType = Ndis802_11DS;
1102
1103 if (pBss->Channel <= 14)
1104 {
1105 //
1106 // First check support Rate.
1107 //
1108 for (i = 0; i < pBss->SupRateLen; i++)
1109 {
1110 rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
1111 if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
1112 {
1113 continue;
1114 }
1115 else
1116 {
1117 //
1118 // Otherwise (even rate > 108) means Ndis802_11OFDM24
1119 //
1120 NetWorkType = Ndis802_11OFDM24;
1121 break;
1122 }
1123 }
1124
1125 //
1126 // Second check Extend Rate.
1127 //
1128 if (NetWorkType != Ndis802_11OFDM24)
1129 {
1130 for (i = 0; i < pBss->ExtRateLen; i++)
1131 {
1132 rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
1133 if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
1134 {
1135 continue;
1136 }
1137 else
1138 {
1139 //
1140 // Otherwise (even rate > 108) means Ndis802_11OFDM24
1141 //
1142 NetWorkType = Ndis802_11OFDM24;
1143 break;
1144 }
1145 }
1146 }
1147 }
1148 else
1149 {
1150 NetWorkType = Ndis802_11OFDM5;
1151 }
1152
1153 if (pBss->HtCapabilityLen != 0)
1154 {
1155 if (NetWorkType == Ndis802_11OFDM5)
1156 NetWorkType = Ndis802_11OFDM5_N;
1157 else
1158 NetWorkType = Ndis802_11OFDM24_N;
1159 }
1160
1161 return NetWorkType;
1162}
1163
1164/*
1165 ==========================================================================
1166 Description:
1167 WPA message sanity check
1168 Return:
1169 TRUE if all parameters are OK, FALSE otherwise
1170 ==========================================================================
1171 */
1172BOOLEAN PeerWpaMessageSanity(
1173 IN PRTMP_ADAPTER pAd,
1174 IN PEAPOL_PACKET pMsg,
1175 IN ULONG MsgLen,
1176 IN UCHAR MsgType,
1177 IN MAC_TABLE_ENTRY *pEntry)
1178{
1179 UCHAR mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
1180 BOOLEAN bReplayDiff = FALSE;
1181 BOOLEAN bWPA2 = FALSE;
1182 KEY_INFO EapolKeyInfo;
1183 UCHAR GroupKeyIndex = 0;
1184
1185
1186 NdisZeroMemory(mic, sizeof(mic));
1187 NdisZeroMemory(digest, sizeof(digest));
1188 NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
1189 NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo));
1190
1191 NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO));
1192
1193 *((USHORT *)&EapolKeyInfo) = cpu2le16(*((USHORT *)&EapolKeyInfo));
1194
1195 // Choose WPA2 or not
1196 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
1197 bWPA2 = TRUE;
1198
1199 // 0. Check MsgType
1200 if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1))
1201 {
1202 DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType));
1203 return FALSE;
1204 }
1205
1206 // 1. Replay counter check
1207 if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) // For supplicant
1208 {
1209 // First validate replay counter, only accept message with larger replay counter.
1210 // Let equal pass, some AP start with all zero replay counter
1211 UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
1212
1213 NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
1214 if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) &&
1215 (RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
1216 {
1217 bReplayDiff = TRUE;
1218 }
1219 }
1220 else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) // For authenticator
1221 {
1222 // check Replay Counter coresponds to MSG from authenticator, otherwise discard
1223 if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
1224 {
1225 bReplayDiff = TRUE;
1226 }
1227 }
1228
1229 // Replay Counter different condition
1230 if (bReplayDiff)
1231 {
1232 // send wireless event - for replay counter different
1233 if (pAd->CommonCfg.bWirelessEvent)
1234 RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1235
1236 if (MsgType < EAPOL_GROUP_MSG_1)
1237 {
1238 DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType));
1239 }
1240 else
1241 {
1242 DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
1243 }
1244
1245 hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1246 hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
1247 return FALSE;
1248 }
1249
1250 // 2. Verify MIC except Pairwise Msg1
1251 if (MsgType != EAPOL_PAIR_MSG_1)
1252 {
1253 UCHAR rcvd_mic[LEN_KEY_DESC_MIC];
1254
1255 // Record the received MIC for check later
1256 NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1257 NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1258
1259 if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) // TKIP
1260 {
1261 hmac_md5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic);
1262 }
1263 else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled) // AES
1264 {
1265 HMAC_SHA1((PUCHAR)pMsg, MsgLen, pEntry->PTK, LEN_EAP_MICK, digest);
1266 NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
1267 }
1268
1269 if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC))
1270 {
1271 // send wireless event - for MIC different
1272 if (pAd->CommonCfg.bWirelessEvent)
1273 RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1274
1275 if (MsgType < EAPOL_GROUP_MSG_1)
1276 {
1277 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType));
1278 }
1279 else
1280 {
1281 DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
1282 }
1283
1284 hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
1285 hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC);
1286
1287 return FALSE;
1288 }
1289 }
1290
1291 // Extract the context of the Key Data field if it exist
1292 // The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is un-encrypted.
1293 // The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
1294 if (pMsg->KeyDesc.KeyDataLen[1] > 0)
1295 {
1296 // Decrypt this field
1297 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
1298 {
1299 if(pEntry->WepStatus == Ndis802_11Encryption3Enabled)
1300 {
1301 // AES
1302 AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA, pMsg->KeyDesc.KeyDataLen[1],pMsg->KeyDesc.KeyData);
1303 }
1304 else
1305 {
1306 INT i;
1307 UCHAR Key[32];
1308 // Decrypt TKIP GTK
1309 // Construct 32 bytes RC4 Key
1310 NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
1311 NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
1312 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
1313 //discard first 256 bytes
1314 for(i = 0; i < 256; i++)
1315 ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
1316 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
1317 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
1318 }
1319
1320 if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
1321 GroupKeyIndex = EapolKeyInfo.KeyIndex;
1322
1323 }
1324 else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2))
1325 {
1326 NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
1327 }
1328 else
1329 {
1330
1331 return TRUE;
1332 }
1333
1334 // Parse Key Data field to
1335 // 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)
1336 // 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2
1337 // 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)
1338 if (!RTMPParseEapolKeyData(pAd, KEYDATA, pMsg->KeyDesc.KeyDataLen[1], GroupKeyIndex, MsgType, bWPA2, pEntry))
1339 {
1340 return FALSE;
1341 }
1342 }
1343
1344 return TRUE;
1345
1346}
1347
1348#ifdef CONFIG_STA_SUPPORT
1349#ifdef QOS_DLS_SUPPORT
1350BOOLEAN MlmeDlsReqSanity(
1351 IN PRTMP_ADAPTER pAd,
1352 IN VOID *Msg,
1353 IN ULONG MsgLen,
1354 OUT PRT_802_11_DLS *pDLS,
1355 OUT PUSHORT pReason)
1356{
1357 MLME_DLS_REQ_STRUCT *pInfo;
1358
1359 pInfo = (MLME_DLS_REQ_STRUCT *)Msg;
1360
1361 *pDLS = pInfo->pDLS;
1362 *pReason = pInfo->Reason;
1363
1364 return TRUE;
1365}
1366#endif // QOS_DLS_SUPPORT //
1367#endif // CONFIG_STA_SUPPORT //
1368
1369#ifdef QOS_DLS_SUPPORT
1370BOOLEAN PeerDlsReqSanity(
1371 IN PRTMP_ADAPTER pAd,
1372 IN VOID *Msg,
1373 IN ULONG MsgLen,
1374 OUT PUCHAR pDA,
1375 OUT PUCHAR pSA,
1376 OUT USHORT *pCapabilityInfo,
1377 OUT USHORT *pDlsTimeout,
1378 OUT UCHAR *pRatesLen,
1379 OUT UCHAR Rates[],
1380 OUT UCHAR *pHtCapabilityLen,
1381 OUT HT_CAPABILITY_IE *pHtCapability)
1382{
1383 CHAR *Ptr;
1384 PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
1385 PEID_STRUCT eid_ptr;
1386
1387 // to prevent caller from using garbage output value
1388 *pCapabilityInfo = 0;
1389 *pDlsTimeout = 0;
1390 *pHtCapabilityLen = 0;
1391
1392 Ptr = Fr->Octet;
1393
1394 // offset to destination MAC address (Category and Action field)
1395 Ptr += 2;
1396
1397 // get DA from payload and advance the pointer
1398 NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
1399 Ptr += MAC_ADDR_LEN;
1400
1401 // get SA from payload and advance the pointer
1402 NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
1403 Ptr += MAC_ADDR_LEN;
1404
1405 // get capability info from payload and advance the pointer
1406 NdisMoveMemory(pCapabilityInfo, Ptr, 2);
1407 Ptr += 2;
1408
1409 // get capability info from payload and advance the pointer
1410 NdisMoveMemory(pDlsTimeout, Ptr, 2);
1411 Ptr += 2;
1412
1413 // Category and Action field + DA + SA + capability + Timeout
1414 eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
1415
1416 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
1417 {
1418 switch(eid_ptr->Eid)
1419 {
1420 case IE_SUPP_RATES:
1421 if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
1422 {
1423 NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
1424 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
1425 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]));
1426 *pRatesLen = eid_ptr->Len;
1427 }
1428 else
1429 {
1430 *pRatesLen = 8;
1431 Rates[0] = 0x82;
1432 Rates[1] = 0x84;
1433 Rates[2] = 0x8b;
1434 Rates[3] = 0x96;
1435 Rates[4] = 0x12;
1436 Rates[5] = 0x24;
1437 Rates[6] = 0x48;
1438 Rates[7] = 0x6c;
1439 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
1440 }
1441 break;
1442
1443 case IE_EXT_SUPP_RATES:
1444 if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
1445 {
1446 NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
1447 *pRatesLen = (*pRatesLen) + eid_ptr->Len;
1448 }
1449 else
1450 {
1451 NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
1452 *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
1453 }
1454 break;
1455
1456 case IE_HT_CAP:
1457 if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
1458 {
1459 NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
1460
1461 *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
1462 *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
1463 *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
1464
1465 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_HT_CAP\n"));
1466 }
1467 else
1468 {
1469 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
1470 }
1471 break;
1472
1473 default:
1474 break;
1475 }
1476
1477 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1478 }
1479
1480 return TRUE;
1481}
1482
1483BOOLEAN PeerDlsRspSanity(
1484 IN PRTMP_ADAPTER pAd,
1485 IN VOID *Msg,
1486 IN ULONG MsgLen,
1487 OUT PUCHAR pDA,
1488 OUT PUCHAR pSA,
1489 OUT USHORT *pCapabilityInfo,
1490 OUT USHORT *pStatus,
1491 OUT UCHAR *pRatesLen,
1492 OUT UCHAR Rates[],
1493 OUT UCHAR *pHtCapabilityLen,
1494 OUT HT_CAPABILITY_IE *pHtCapability)
1495{
1496 CHAR *Ptr;
1497 PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
1498 PEID_STRUCT eid_ptr;
1499
1500 // to prevent caller from using garbage output value
1501 *pStatus = 0;
1502 *pCapabilityInfo = 0;
1503 *pHtCapabilityLen = 0;
1504
1505 Ptr = Fr->Octet;
1506
1507 // offset to destination MAC address (Category and Action field)
1508 Ptr += 2;
1509
1510 // get status code from payload and advance the pointer
1511 NdisMoveMemory(pStatus, Ptr, 2);
1512 Ptr += 2;
1513
1514 // get DA from payload and advance the pointer
1515 NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
1516 Ptr += MAC_ADDR_LEN;
1517
1518 // get SA from payload and advance the pointer
1519 NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
1520 Ptr += MAC_ADDR_LEN;
1521
1522 if (pStatus == 0)
1523 {
1524 // get capability info from payload and advance the pointer
1525 NdisMoveMemory(pCapabilityInfo, Ptr, 2);
1526 Ptr += 2;
1527 }
1528
1529 // Category and Action field + status code + DA + SA + capability
1530 eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
1531
1532 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
1533 {
1534 switch(eid_ptr->Eid)
1535 {
1536 case IE_SUPP_RATES:
1537 if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
1538 {
1539 NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
1540 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
1541 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]));
1542 *pRatesLen = eid_ptr->Len;
1543 }
1544 else
1545 {
1546 *pRatesLen = 8;
1547 Rates[0] = 0x82;
1548 Rates[1] = 0x84;
1549 Rates[2] = 0x8b;
1550 Rates[3] = 0x96;
1551 Rates[4] = 0x12;
1552 Rates[5] = 0x24;
1553 Rates[6] = 0x48;
1554 Rates[7] = 0x6c;
1555 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
1556 }
1557 break;
1558
1559 case IE_EXT_SUPP_RATES:
1560 if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
1561 {
1562 NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
1563 *pRatesLen = (*pRatesLen) + eid_ptr->Len;
1564 }
1565 else
1566 {
1567 NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
1568 *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
1569 }
1570 break;
1571
1572 case IE_HT_CAP:
1573 if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
1574 {
1575 NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
1576
1577 *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
1578 *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
1579 *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
1580
1581 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_HT_CAP\n"));
1582 }
1583 else
1584 {
1585 DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
1586 }
1587 break;
1588
1589 default:
1590 break;
1591 }
1592
1593 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1594 }
1595
1596 return TRUE;
1597}
1598
1599BOOLEAN PeerDlsTearDownSanity(
1600 IN PRTMP_ADAPTER pAd,
1601 IN VOID *Msg,
1602 IN ULONG MsgLen,
1603 OUT PUCHAR pDA,
1604 OUT PUCHAR pSA,
1605 OUT USHORT *pReason)
1606{
1607 CHAR *Ptr;
1608 PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
1609
1610 // to prevent caller from using garbage output value
1611 *pReason = 0;
1612
1613 Ptr = Fr->Octet;
1614
1615 // offset to destination MAC address (Category and Action field)
1616 Ptr += 2;
1617
1618 // get DA from payload and advance the pointer
1619 NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
1620 Ptr += MAC_ADDR_LEN;
1621
1622 // get SA from payload and advance the pointer
1623 NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
1624 Ptr += MAC_ADDR_LEN;
1625
1626 // get reason code from payload and advance the pointer
1627 NdisMoveMemory(pReason, Ptr, 2);
1628 Ptr += 2;
1629
1630 return TRUE;
1631}
1632#endif // QOS_DLS_SUPPORT //
1633
diff --git a/drivers/staging/rt2860/common/cmm_sync.c b/drivers/staging/rt2860/common/cmm_sync.c
new file mode 100644
index 00000000000..40e4109118e
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_sync.c
@@ -0,0 +1,702 @@
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 else
467 {
468#ifdef CONFIG_STA_SUPPORT
469 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
470 {
471 // BBP and RF are not accessible in PS mode, we has to wake them up first
472 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
473 AsicForceWakeup(pAd, TRUE);
474
475 // leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
476 if (pAd->StaCfg.Psm == PWR_SAVE)
477 MlmeSetPsmBit(pAd, PWR_ACTIVE);
478 }
479#endif // CONFIG_STA_SUPPORT //
480
481 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
482 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
483
484#ifdef CONFIG_STA_SUPPORT
485 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
486 {
487 if (pAd->MlmeAux.Channel > 14)
488 {
489 if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
490 {
491 ScanType = SCAN_PASSIVE;
492 ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
493 }
494 }
495
496#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
497 // carrier detection
498 if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
499 {
500 ScanType = SCAN_PASSIVE;
501 ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
502 }
503#endif // CARRIER_DETECTION_SUPPORT //
504 }
505
506#endif // CONFIG_STA_SUPPORT //
507
508 //Global country domain(ch1-11:active scan, ch12-14 passive scan)
509 if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND))
510 {
511 ScanType = SCAN_PASSIVE;
512 }
513
514 // We need to shorten active scan time in order for WZC connect issue
515 // Chnage the channel scan time for CISCO stuff based on its IAPP announcement
516 if (ScanType == FAST_SCAN_ACTIVE)
517 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
518#ifdef CONFIG_STA_SUPPORT
519 else if (((ScanType == SCAN_CISCO_ACTIVE) ||
520 (ScanType == SCAN_CISCO_PASSIVE) ||
521 (ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
522 (ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
523 {
524 if (pAd->StaCfg.CCXScanTime < 25)
525 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
526 else
527 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
528 }
529#endif // CONFIG_STA_SUPPORT //
530 else // must be SCAN_PASSIVE or SCAN_ACTIVE
531 {
532 if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
533#ifdef DOT11_N_SUPPORT
534 || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
535#endif // DOT11_N_SUPPORT //
536 )
537 {
538 if (pAd->MlmeAux.Channel > 14)
539 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
540 else
541 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
542 }
543 else
544 RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
545 }
546
547 if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ||
548 (ScanType == SCAN_CISCO_ACTIVE))
549 {
550 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
551 if (NStatus != NDIS_STATUS_SUCCESS)
552 {
553 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
554#ifdef CONFIG_STA_SUPPORT
555 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
556 {
557 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
558 Status = MLME_FAIL_NO_RESOURCE;
559 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
560 }
561#endif // CONFIG_STA_SUPPORT //
562
563 return;
564 }
565
566 // There is no need to send broadcast probe request if active scan is in effect.
567 if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
568 )
569 SsidLen = pAd->MlmeAux.SsidLen;
570 else
571 SsidLen = 0;
572
573 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
574 MakeOutgoingFrame(pOutBuffer, &FrameLen,
575 sizeof(HEADER_802_11), &Hdr80211,
576 1, &SsidIe,
577 1, &SsidLen,
578 SsidLen, pAd->MlmeAux.Ssid,
579 1, &SupRateIe,
580 1, &pAd->CommonCfg.SupRateLen,
581 pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRate,
582 END_OF_ARGS);
583
584 if (pAd->CommonCfg.ExtRateLen)
585 {
586 ULONG Tmp;
587 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
588 1, &ExtRateIe,
589 1, &pAd->CommonCfg.ExtRateLen,
590 pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate,
591 END_OF_ARGS);
592 FrameLen += Tmp;
593 }
594
595#ifdef DOT11_N_SUPPORT
596 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
597 {
598 ULONG Tmp;
599 UCHAR HtLen;
600 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
601#ifdef RT_BIG_ENDIAN
602 HT_CAPABILITY_IE HtCapabilityTmp;
603#endif
604 if (pAd->bBroadComHT == TRUE)
605 {
606 HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
607#ifdef RT_BIG_ENDIAN
608 NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
609 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
610 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
611
612 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
613 1, &WpaIe,
614 1, &HtLen,
615 4, &BROADCOM[0],
616 pAd->MlmeAux.HtCapabilityLen, &HtCapabilityTmp,
617 END_OF_ARGS);
618#else
619 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
620 1, &WpaIe,
621 1, &HtLen,
622 4, &BROADCOM[0],
623 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
624 END_OF_ARGS);
625#endif // RT_BIG_ENDIAN //
626 }
627 else
628 {
629 HtLen = pAd->MlmeAux.HtCapabilityLen;
630#ifdef RT_BIG_ENDIAN
631 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE);
632 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
633 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
634
635 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
636 1, &HtCapIe,
637 1, &HtLen,
638 HtLen, &HtCapabilityTmp,
639 END_OF_ARGS);
640#else
641 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
642 1, &HtCapIe,
643 1, &HtLen,
644 HtLen, &pAd->CommonCfg.HtCapability,
645 END_OF_ARGS);
646#endif // RT_BIG_ENDIAN //
647 }
648 FrameLen += Tmp;
649
650#ifdef DOT11N_DRAFT3
651 if (pAd->CommonCfg.BACapability.field.b2040CoexistScanSup == 1)
652 {
653 ULONG Tmp;
654 HtLen = 1;
655 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
656 1, &ExtHtCapIe,
657 1, &HtLen,
658 1, &pAd->CommonCfg.BSSCoexist2040.word,
659 END_OF_ARGS);
660
661 FrameLen += Tmp;
662 }
663#endif // DOT11N_DRAFT3 //
664 }
665#endif // DOT11_N_SUPPORT //
666
667
668 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
669 MlmeFreeMemory(pAd, pOutBuffer);
670 }
671
672 // For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
673
674#ifdef CONFIG_STA_SUPPORT
675 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
676 pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
677#endif // CONFIG_STA_SUPPORT //
678
679 }
680}
681
682VOID MgtProbReqMacHeaderInit(
683 IN PRTMP_ADAPTER pAd,
684 IN OUT PHEADER_802_11 pHdr80211,
685 IN UCHAR SubType,
686 IN UCHAR ToDs,
687 IN PUCHAR pDA,
688 IN PUCHAR pBssid)
689{
690 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
691
692 pHdr80211->FC.Type = BTYPE_MGMT;
693 pHdr80211->FC.SubType = SubType;
694 if (SubType == SUBTYPE_ACK)
695 pHdr80211->FC.Type = BTYPE_CNTL;
696 pHdr80211->FC.ToDs = ToDs;
697 COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
698 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
699 COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
700}
701
702
diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c
new file mode 100644
index 00000000000..81c332ac252
--- /dev/null
+++ b/drivers/staging/rt2860/common/cmm_wpa.c
@@ -0,0 +1,1606 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 wpa.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Jan Lee 03-07-22 Initial
36 Paul Lin 03-11-28 Modify for supplicant
37*/
38#include "../rt_config.h"
39// WPA OUI
40UCHAR OUI_WPA_NONE_AKM[4] = {0x00, 0x50, 0xF2, 0x00};
41UCHAR OUI_WPA_VERSION[4] = {0x00, 0x50, 0xF2, 0x01};
42UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};
43UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};
44UCHAR OUI_WPA_8021X_AKM[4] = {0x00, 0x50, 0xF2, 0x01};
45UCHAR OUI_WPA_PSK_AKM[4] = {0x00, 0x50, 0xF2, 0x02};
46// WPA2 OUI
47UCHAR OUI_WPA2_WEP40[4] = {0x00, 0x0F, 0xAC, 0x01};
48UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
49UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
50UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01};
51UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02};
52// MSA OUI
53UCHAR OUI_MSA_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x05}; // Not yet final - IEEE 802.11s-D1.06
54UCHAR OUI_MSA_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x06}; // Not yet final - IEEE 802.11s-D1.06
55
56/*
57 ========================================================================
58
59 Routine Description:
60 The pseudo-random function(PRF) that hashes various inputs to
61 derive a pseudo-random value. To add liveness to the pseudo-random
62 value, a nonce should be one of the inputs.
63
64 It is used to generate PTK, GTK or some specific random value.
65
66 Arguments:
67 UCHAR *key, - the key material for HMAC_SHA1 use
68 INT key_len - the length of key
69 UCHAR *prefix - a prefix label
70 INT prefix_len - the length of the label
71 UCHAR *data - a specific data with variable length
72 INT data_len - the length of a specific data
73 INT len - the output lenght
74
75 Return Value:
76 UCHAR *output - the calculated result
77
78 Note:
79 802.11i-2004 Annex H.3
80
81 ========================================================================
82*/
83VOID PRF(
84 IN UCHAR *key,
85 IN INT key_len,
86 IN UCHAR *prefix,
87 IN INT prefix_len,
88 IN UCHAR *data,
89 IN INT data_len,
90 OUT UCHAR *output,
91 IN INT len)
92{
93 INT i;
94 UCHAR *input;
95 INT currentindex = 0;
96 INT total_len;
97
98 // Allocate memory for input
99 os_alloc_mem(NULL, (PUCHAR *)&input, 1024);
100
101 if (input == NULL)
102 {
103 DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n"));
104 return;
105 }
106
107 // Generate concatenation input
108 NdisMoveMemory(input, prefix, prefix_len);
109
110 // Concatenate a single octet containing 0
111 input[prefix_len] = 0;
112
113 // Concatenate specific data
114 NdisMoveMemory(&input[prefix_len + 1], data, data_len);
115 total_len = prefix_len + 1 + data_len;
116
117 // Concatenate a single octet containing 0
118 // This octet shall be update later
119 input[total_len] = 0;
120 total_len++;
121
122 // Iterate to calculate the result by hmac-sha-1
123 // Then concatenate to last result
124 for (i = 0; i < (len + 19) / 20; i++)
125 {
126 HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
127 currentindex += 20;
128
129 // update the last octet
130 input[total_len - 1]++;
131 }
132 os_free_mem(NULL, input);
133}
134
135/*
136 ========================================================================
137
138 Routine Description:
139 It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
140 It shall be called by 4-way handshake processing.
141
142 Arguments:
143 pAd - pointer to our pAdapter context
144 PMK - pointer to PMK
145 ANonce - pointer to ANonce
146 AA - pointer to Authenticator Address
147 SNonce - pointer to SNonce
148 SA - pointer to Supplicant Address
149 len - indicate the length of PTK (octet)
150
151 Return Value:
152 Output pointer to the PTK
153
154 Note:
155 Refer to IEEE 802.11i-2004 8.5.1.2
156
157 ========================================================================
158*/
159VOID WpaCountPTK(
160 IN PRTMP_ADAPTER pAd,
161 IN UCHAR *PMK,
162 IN UCHAR *ANonce,
163 IN UCHAR *AA,
164 IN UCHAR *SNonce,
165 IN UCHAR *SA,
166 OUT UCHAR *output,
167 IN UINT len)
168{
169 UCHAR concatenation[76];
170 UINT CurrPos = 0;
171 UCHAR temp[32];
172 UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
173 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
174
175 // initiate the concatenation input
176 NdisZeroMemory(temp, sizeof(temp));
177 NdisZeroMemory(concatenation, 76);
178
179 // Get smaller address
180 if (RTMPCompareMemory(SA, AA, 6) == 1)
181 NdisMoveMemory(concatenation, AA, 6);
182 else
183 NdisMoveMemory(concatenation, SA, 6);
184 CurrPos += 6;
185
186 // Get larger address
187 if (RTMPCompareMemory(SA, AA, 6) == 1)
188 NdisMoveMemory(&concatenation[CurrPos], SA, 6);
189 else
190 NdisMoveMemory(&concatenation[CurrPos], AA, 6);
191
192 // store the larger mac address for backward compatible of
193 // ralink proprietary STA-key issue
194 NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
195 CurrPos += 6;
196
197 // Get smaller Nonce
198 if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
199 NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue
200 else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
201 NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
202 else
203 NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
204 CurrPos += 32;
205
206 // Get larger Nonce
207 if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
208 NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue
209 else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
210 NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
211 else
212 NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
213 CurrPos += 32;
214
215 hex_dump("concatenation=", concatenation, 76);
216
217 // Use PRF to generate PTK
218 PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
219
220}
221
222/*
223 ========================================================================
224
225 Routine Description:
226 Generate random number by software.
227
228 Arguments:
229 pAd - pointer to our pAdapter context
230 macAddr - pointer to local MAC address
231
232 Return Value:
233
234 Note:
235 802.1ii-2004 Annex H.5
236
237 ========================================================================
238*/
239VOID GenRandom(
240 IN PRTMP_ADAPTER pAd,
241 IN UCHAR *macAddr,
242 OUT UCHAR *random)
243{
244 INT i, curr;
245 UCHAR local[80], KeyCounter[32];
246 UCHAR result[80];
247 ULONG CurrentTime;
248 UCHAR prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
249
250 // Zero the related information
251 NdisZeroMemory(result, 80);
252 NdisZeroMemory(local, 80);
253 NdisZeroMemory(KeyCounter, 32);
254
255 for (i = 0; i < 32; i++)
256 {
257 // copy the local MAC address
258 COPY_MAC_ADDR(local, macAddr);
259 curr = MAC_ADDR_LEN;
260
261 // concatenate the current time
262 NdisGetSystemUpTime(&CurrentTime);
263 NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
264 curr += sizeof(CurrentTime);
265
266 // concatenate the last result
267 NdisMoveMemory(&local[curr], result, 32);
268 curr += 32;
269
270 // concatenate a variable
271 NdisMoveMemory(&local[curr], &i, 2);
272 curr += 2;
273
274 // calculate the result
275 PRF(KeyCounter, 32, prefix,12, local, curr, result, 32);
276 }
277
278 NdisMoveMemory(random, result, 32);
279}
280
281/*
282 ========================================================================
283
284 Routine Description:
285 Build cipher suite in RSN-IE.
286 It only shall be called by RTMPMakeRSNIE.
287
288 Arguments:
289 pAd - pointer to our pAdapter context
290 ElementID - indicate the WPA1 or WPA2
291 WepStatus - indicate the encryption type
292 bMixCipher - a boolean to indicate the pairwise cipher and group
293 cipher are the same or not
294
295 Return Value:
296
297 Note:
298
299 ========================================================================
300*/
301static VOID RTMPInsertRsnIeCipher(
302 IN PRTMP_ADAPTER pAd,
303 IN UCHAR ElementID,
304 IN UINT WepStatus,
305 IN BOOLEAN bMixCipher,
306 IN UCHAR FlexibleCipher,
307 OUT PUCHAR pRsnIe,
308 OUT UCHAR *rsn_len)
309{
310 UCHAR PairwiseCnt;
311
312 *rsn_len = 0;
313
314 // decide WPA2 or WPA1
315 if (ElementID == Wpa2Ie)
316 {
317 RSNIE2 *pRsnie_cipher = (RSNIE2*)pRsnIe;
318
319 // Assign the verson as 1
320 pRsnie_cipher->version = 1;
321
322 switch (WepStatus)
323 {
324 // TKIP mode
325 case Ndis802_11Encryption2Enabled:
326 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
327 pRsnie_cipher->ucount = 1;
328 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
329 *rsn_len = sizeof(RSNIE2);
330 break;
331
332 // AES mode
333 case Ndis802_11Encryption3Enabled:
334 if (bMixCipher)
335 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
336 else
337 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4);
338 pRsnie_cipher->ucount = 1;
339 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
340 *rsn_len = sizeof(RSNIE2);
341 break;
342
343 // TKIP-AES mix mode
344 case Ndis802_11Encryption4Enabled:
345 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
346
347 PairwiseCnt = 1;
348 // Insert WPA2 TKIP as the first pairwise cipher
349 if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher))
350 {
351 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
352 // Insert WPA2 AES as the secondary pairwise cipher
353 if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher))
354 {
355 NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4);
356 PairwiseCnt = 2;
357 }
358 }
359 else
360 {
361 // Insert WPA2 AES as the first pairwise cipher
362 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
363 }
364
365 pRsnie_cipher->ucount = PairwiseCnt;
366 *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1));
367 break;
368 }
369
370 // swap for big-endian platform
371 pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
372 pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
373 }
374 else
375 {
376 RSNIE *pRsnie_cipher = (RSNIE*)pRsnIe;
377
378 // Assign OUI and version
379 NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
380 pRsnie_cipher->version = 1;
381
382 switch (WepStatus)
383 {
384 // TKIP mode
385 case Ndis802_11Encryption2Enabled:
386 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
387 pRsnie_cipher->ucount = 1;
388 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
389 *rsn_len = sizeof(RSNIE);
390 break;
391
392 // AES mode
393 case Ndis802_11Encryption3Enabled:
394 if (bMixCipher)
395 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
396 else
397 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4);
398 pRsnie_cipher->ucount = 1;
399 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
400 *rsn_len = sizeof(RSNIE);
401 break;
402
403 // TKIP-AES mix mode
404 case Ndis802_11Encryption4Enabled:
405 NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
406
407 PairwiseCnt = 1;
408 // Insert WPA TKIP as the first pairwise cipher
409 if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher))
410 {
411 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
412 // Insert WPA AES as the secondary pairwise cipher
413 if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher))
414 {
415 NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4);
416 PairwiseCnt = 2;
417 }
418 }
419 else
420 {
421 // Insert WPA AES as the first pairwise cipher
422 NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
423 }
424
425 pRsnie_cipher->ucount = PairwiseCnt;
426 *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1));
427 break;
428 }
429
430 // swap for big-endian platform
431 pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
432 pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
433 }
434
435}
436
437/*
438 ========================================================================
439
440 Routine Description:
441 Build AKM suite in RSN-IE.
442 It only shall be called by RTMPMakeRSNIE.
443
444 Arguments:
445 pAd - pointer to our pAdapter context
446 ElementID - indicate the WPA1 or WPA2
447 AuthMode - indicate the authentication mode
448 apidx - indicate the interface index
449
450 Return Value:
451
452 Note:
453
454 ========================================================================
455*/
456static VOID RTMPInsertRsnIeAKM(
457 IN PRTMP_ADAPTER pAd,
458 IN UCHAR ElementID,
459 IN UINT AuthMode,
460 IN UCHAR apidx,
461 OUT PUCHAR pRsnIe,
462 OUT UCHAR *rsn_len)
463{
464 RSNIE_AUTH *pRsnie_auth;
465
466 pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
467
468 // decide WPA2 or WPA1
469 if (ElementID == Wpa2Ie)
470 {
471 switch (AuthMode)
472 {
473 case Ndis802_11AuthModeWPA2:
474 case Ndis802_11AuthModeWPA1WPA2:
475 pRsnie_auth->acount = 1;
476 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
477 break;
478
479 case Ndis802_11AuthModeWPA2PSK:
480 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
481 pRsnie_auth->acount = 1;
482 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
483 break;
484 }
485 }
486 else
487 {
488 switch (AuthMode)
489 {
490 case Ndis802_11AuthModeWPA:
491 case Ndis802_11AuthModeWPA1WPA2:
492 pRsnie_auth->acount = 1;
493 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
494 break;
495
496 case Ndis802_11AuthModeWPAPSK:
497 case Ndis802_11AuthModeWPA1PSKWPA2PSK:
498 pRsnie_auth->acount = 1;
499 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
500 break;
501
502 case Ndis802_11AuthModeWPANone:
503 pRsnie_auth->acount = 1;
504 NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
505 break;
506 }
507 }
508
509 pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
510
511 (*rsn_len) += sizeof(RSNIE_AUTH); // update current RSNIE length
512
513}
514
515/*
516 ========================================================================
517
518 Routine Description:
519 Build capability in RSN-IE.
520 It only shall be called by RTMPMakeRSNIE.
521
522 Arguments:
523 pAd - pointer to our pAdapter context
524 ElementID - indicate the WPA1 or WPA2
525 apidx - indicate the interface index
526
527 Return Value:
528
529 Note:
530
531 ========================================================================
532*/
533static VOID RTMPInsertRsnIeCap(
534 IN PRTMP_ADAPTER pAd,
535 IN UCHAR ElementID,
536 IN UCHAR apidx,
537 OUT PUCHAR pRsnIe,
538 OUT UCHAR *rsn_len)
539{
540 RSN_CAPABILITIES *pRSN_Cap;
541
542 // it could be ignored in WPA1 mode
543 if (ElementID == WpaIe)
544 return;
545
546 pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len));
547
548
549 pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
550
551 (*rsn_len) += sizeof(RSN_CAPABILITIES); // update current RSNIE length
552
553}
554
555
556/*
557 ========================================================================
558
559 Routine Description:
560 Build RSN IE context. It is not included element-ID and length.
561
562 Arguments:
563 pAd - pointer to our pAdapter context
564 AuthMode - indicate the authentication mode
565 WepStatus - indicate the encryption type
566 apidx - indicate the interface index
567
568 Return Value:
569
570 Note:
571
572 ========================================================================
573*/
574VOID RTMPMakeRSNIE(
575 IN PRTMP_ADAPTER pAd,
576 IN UINT AuthMode,
577 IN UINT WepStatus,
578 IN UCHAR apidx)
579{
580 PUCHAR pRsnIe = NULL; // primary RSNIE
581 UCHAR *rsnielen_cur_p = 0; // the length of the primary RSNIE
582 UCHAR *rsnielen_ex_cur_p = 0; // the length of the secondary RSNIE
583 UCHAR PrimaryRsnie;
584 BOOLEAN bMixCipher = FALSE; // indicate the pairwise and group cipher are different
585 UCHAR p_offset;
586 WPA_MIX_PAIR_CIPHER FlexibleCipher = MIX_CIPHER_NOTUSE; // it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode
587
588 rsnielen_cur_p = NULL;
589 rsnielen_ex_cur_p = NULL;
590
591 {
592#ifdef CONFIG_STA_SUPPORT
593 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
594 {
595#ifdef WPA_SUPPLICANT_SUPPORT
596 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
597 {
598 if (AuthMode < Ndis802_11AuthModeWPA)
599 return;
600 }
601 else
602#endif // WPA_SUPPLICANT_SUPPORT //
603 {
604 // Support WPAPSK or WPA2PSK in STA-Infra mode
605 // Support WPANone in STA-Adhoc mode
606 if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
607 (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
608 (AuthMode != Ndis802_11AuthModeWPANone)
609 )
610 return;
611 }
612
613 DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n"));
614
615 // Zero RSNIE context
616 pAd->StaCfg.RSNIE_Len = 0;
617 NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
618
619 // Pointer to RSNIE
620 rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
621 pRsnIe = pAd->StaCfg.RSN_IE;
622
623 bMixCipher = pAd->StaCfg.bMixCipher;
624 }
625#endif // CONFIG_STA_SUPPORT //
626 }
627
628 // indicate primary RSNIE as WPA or WPA2
629 if ((AuthMode == Ndis802_11AuthModeWPA) ||
630 (AuthMode == Ndis802_11AuthModeWPAPSK) ||
631 (AuthMode == Ndis802_11AuthModeWPANone) ||
632 (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
633 (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
634 PrimaryRsnie = WpaIe;
635 else
636 PrimaryRsnie = Wpa2Ie;
637
638 {
639 // Build the primary RSNIE
640 // 1. insert cipher suite
641 RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
642
643 // 2. insert AKM
644 RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
645
646 // 3. insert capability
647 RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
648 }
649
650 // 4. update the RSNIE length
651 *rsnielen_cur_p = p_offset;
652
653 hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
654
655
656}
657
658/*
659 ==========================================================================
660 Description:
661 Check whether the received frame is EAP frame.
662
663 Arguments:
664 pAd - pointer to our pAdapter context
665 pEntry - pointer to active entry
666 pData - the received frame
667 DataByteCount - the received frame's length
668 FromWhichBSSID - indicate the interface index
669
670 Return:
671 TRUE - This frame is EAP frame
672 FALSE - otherwise
673 ==========================================================================
674*/
675BOOLEAN RTMPCheckWPAframe(
676 IN PRTMP_ADAPTER pAd,
677 IN PMAC_TABLE_ENTRY pEntry,
678 IN PUCHAR pData,
679 IN ULONG DataByteCount,
680 IN UCHAR FromWhichBSSID)
681{
682 ULONG Body_len;
683 BOOLEAN Cancelled;
684
685
686 if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
687 return FALSE;
688
689
690 // Skip LLC header
691 if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
692 // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL
693 NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6))
694 {
695 pData += 6;
696 }
697 // Skip 2-bytes EAPoL type
698 if (NdisEqualMemory(EAPOL, pData, 2))
699 {
700 pData += 2;
701 }
702 else
703 return FALSE;
704
705 switch (*(pData+1))
706 {
707 case EAPPacket:
708 Body_len = (*(pData+2)<<8) | (*(pData+3));
709 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len));
710 break;
711 case EAPOLStart:
712 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
713 if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
714 {
715 DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));
716 RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
717 pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
718 }
719 break;
720 case EAPOLLogoff:
721 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
722 break;
723 case EAPOLKey:
724 Body_len = (*(pData+2)<<8) | (*(pData+3));
725 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len));
726 break;
727 case EAPOLASFAlert:
728 DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
729 break;
730 default:
731 return FALSE;
732
733 }
734 return TRUE;
735}
736
737
738/*
739 ==========================================================================
740 Description:
741 ENCRYPT AES GTK before sending in EAPOL frame.
742 AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function.
743 This function references to RFC 3394 for aes key wrap algorithm.
744 Return:
745 ==========================================================================
746*/
747VOID AES_GTK_KEY_WRAP(
748 IN UCHAR *key,
749 IN UCHAR *plaintext,
750 IN UCHAR p_len,
751 OUT UCHAR *ciphertext)
752{
753 UCHAR A[8], BIN[16], BOUT[16];
754 UCHAR R[512];
755 INT num_blocks = p_len/8; // unit:64bits
756 INT i, j;
757 aes_context aesctx;
758 UCHAR xor;
759
760 rtmp_aes_set_key(&aesctx, key, 128);
761
762 // Init IA
763 for (i = 0; i < 8; i++)
764 A[i] = 0xa6;
765
766 //Input plaintext
767 for (i = 0; i < num_blocks; i++)
768 {
769 for (j = 0 ; j < 8; j++)
770 R[8 * (i + 1) + j] = plaintext[8 * i + j];
771 }
772
773 // Key Mix
774 for (j = 0; j < 6; j++)
775 {
776 for(i = 1; i <= num_blocks; i++)
777 {
778 //phase 1
779 NdisMoveMemory(BIN, A, 8);
780 NdisMoveMemory(&BIN[8], &R[8 * i], 8);
781 rtmp_aes_encrypt(&aesctx, BIN, BOUT);
782
783 NdisMoveMemory(A, &BOUT[0], 8);
784 xor = num_blocks * j + i;
785 A[7] = BOUT[7] ^ xor;
786 NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
787 }
788 }
789
790 // Output ciphertext
791 NdisMoveMemory(ciphertext, A, 8);
792
793 for (i = 1; i <= num_blocks; i++)
794 {
795 for (j = 0 ; j < 8; j++)
796 ciphertext[8 * i + j] = R[8 * i + j];
797 }
798}
799
800
801/*
802 ========================================================================
803
804 Routine Description:
805 Misc function to decrypt AES body
806
807 Arguments:
808
809 Return Value:
810
811 Note:
812 This function references to RFC 3394 for aes key unwrap algorithm.
813
814 ========================================================================
815*/
816VOID AES_GTK_KEY_UNWRAP(
817 IN UCHAR *key,
818 OUT UCHAR *plaintext,
819 IN UCHAR c_len,
820 IN UCHAR *ciphertext)
821
822{
823 UCHAR A[8], BIN[16], BOUT[16];
824 UCHAR xor;
825 INT i, j;
826 aes_context aesctx;
827 UCHAR *R;
828 INT num_blocks = c_len/8; // unit:64bits
829
830
831 os_alloc_mem(NULL, (PUCHAR *)&R, 512);
832
833 if (R == NULL)
834 {
835 DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
836 return;
837 } /* End of if */
838
839 // Initialize
840 NdisMoveMemory(A, ciphertext, 8);
841 //Input plaintext
842 for(i = 0; i < (c_len-8); i++)
843 {
844 R[ i] = ciphertext[i + 8];
845 }
846
847 rtmp_aes_set_key(&aesctx, key, 128);
848
849 for(j = 5; j >= 0; j--)
850 {
851 for(i = (num_blocks-1); i > 0; i--)
852 {
853 xor = (num_blocks -1 )* j + i;
854 NdisMoveMemory(BIN, A, 8);
855 BIN[7] = A[7] ^ xor;
856 NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
857 rtmp_aes_decrypt(&aesctx, BIN, BOUT);
858 NdisMoveMemory(A, &BOUT[0], 8);
859 NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
860 }
861 }
862
863 // OUTPUT
864 for(i = 0; i < c_len; i++)
865 {
866 plaintext[i] = R[i];
867 }
868
869
870 os_free_mem(NULL, R);
871}
872
873/*
874 ==========================================================================
875 Description:
876 Report the EAP message type
877
878 Arguments:
879 msg - EAPOL_PAIR_MSG_1
880 EAPOL_PAIR_MSG_2
881 EAPOL_PAIR_MSG_3
882 EAPOL_PAIR_MSG_4
883 EAPOL_GROUP_MSG_1
884 EAPOL_GROUP_MSG_2
885
886 Return:
887 message type string
888
889 ==========================================================================
890*/
891CHAR *GetEapolMsgType(CHAR msg)
892{
893 if(msg == EAPOL_PAIR_MSG_1)
894 return "Pairwise Message 1";
895 else if(msg == EAPOL_PAIR_MSG_2)
896 return "Pairwise Message 2";
897 else if(msg == EAPOL_PAIR_MSG_3)
898 return "Pairwise Message 3";
899 else if(msg == EAPOL_PAIR_MSG_4)
900 return "Pairwise Message 4";
901 else if(msg == EAPOL_GROUP_MSG_1)
902 return "Group Message 1";
903 else if(msg == EAPOL_GROUP_MSG_2)
904 return "Group Message 2";
905 else
906 return "Invalid Message";
907}
908
909
910/*
911 ========================================================================
912
913 Routine Description:
914 Check Sanity RSN IE of EAPoL message
915
916 Arguments:
917
918 Return Value:
919
920
921 ========================================================================
922*/
923BOOLEAN RTMPCheckRSNIE(
924 IN PRTMP_ADAPTER pAd,
925 IN PUCHAR pData,
926 IN UCHAR DataLen,
927 IN MAC_TABLE_ENTRY *pEntry,
928 OUT UCHAR *Offset)
929{
930 PUCHAR pVIE;
931 UCHAR len;
932 PEID_STRUCT pEid;
933 BOOLEAN result = FALSE;
934
935 pVIE = pData;
936 len = DataLen;
937 *Offset = 0;
938
939 while (len > sizeof(RSNIE2))
940 {
941 pEid = (PEID_STRUCT) pVIE;
942 // WPA RSN IE
943 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
944 {
945 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) &&
946 (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
947 (pEntry->RSNIE_Len == (pEid->Len + 2)))
948 {
949 result = TRUE;
950 }
951
952 *Offset += (pEid->Len + 2);
953 }
954 // WPA2 RSN IE
955 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
956 {
957 if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) &&
958 (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
959 (pEntry->RSNIE_Len == (pEid->Len + 2))/* ToDo-AlbertY for mesh*/)
960 {
961 result = TRUE;
962 }
963
964 *Offset += (pEid->Len + 2);
965 }
966 else
967 {
968 break;
969 }
970
971 pVIE += (pEid->Len + 2);
972 len -= (pEid->Len + 2);
973 }
974
975
976 return result;
977
978}
979
980
981/*
982 ========================================================================
983
984 Routine Description:
985 Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
986 GTK is encaptulated in KDE format at p.83 802.11i D10
987
988 Arguments:
989
990 Return Value:
991
992 Note:
993 802.11i D10
994
995 ========================================================================
996*/
997BOOLEAN RTMPParseEapolKeyData(
998 IN PRTMP_ADAPTER pAd,
999 IN PUCHAR pKeyData,
1000 IN UCHAR KeyDataLen,
1001 IN UCHAR GroupKeyIndex,
1002 IN UCHAR MsgType,
1003 IN BOOLEAN bWPA2,
1004 IN MAC_TABLE_ENTRY *pEntry)
1005{
1006 PKDE_ENCAP pKDE = NULL;
1007 PUCHAR pMyKeyData = pKeyData;
1008 UCHAR KeyDataLength = KeyDataLen;
1009 UCHAR GTKLEN = 0;
1010 UCHAR DefaultIdx = 0;
1011 UCHAR skip_offset;
1012
1013 // Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it
1014 if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3)
1015 {
1016 // Check RSN IE whether it is WPA2/WPA2PSK
1017 if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset))
1018 {
1019 // send wireless event - for RSN IE different
1020 if (pAd->CommonCfg.bWirelessEvent)
1021 RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
1022
1023 DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType));
1024 hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
1025 hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len);
1026
1027 return FALSE;
1028 }
1029 else
1030 {
1031 if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3)
1032 {
1033 // skip RSN IE
1034 pMyKeyData += skip_offset;
1035 KeyDataLength -= skip_offset;
1036 DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
1037 }
1038 else
1039 return TRUE;
1040 }
1041 }
1042
1043 DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
1044
1045 // Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2
1046 if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1))
1047 {
1048 if (KeyDataLength >= 8) // KDE format exclude GTK length
1049 {
1050 pKDE = (PKDE_ENCAP) pMyKeyData;
1051
1052
1053 DefaultIdx = pKDE->GTKEncap.Kid;
1054
1055 // Sanity check - KED length
1056 if (KeyDataLength < (pKDE->Len + 2))
1057 {
1058 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
1059 return FALSE;
1060 }
1061
1062 // Get GTK length - refer to IEEE 802.11i-2004 p.82
1063 GTKLEN = pKDE->Len -6;
1064 if (GTKLEN < LEN_AES_KEY)
1065 {
1066 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
1067 return FALSE;
1068 }
1069
1070 }
1071 else
1072 {
1073 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n"));
1074 return FALSE;
1075 }
1076
1077 DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN));
1078 // skip it
1079 pMyKeyData += 8;
1080 KeyDataLength -= 8;
1081
1082 }
1083 else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1)
1084 {
1085 DefaultIdx = GroupKeyIndex;
1086 DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx));
1087 }
1088
1089 // Sanity check - shared key index must be 1 ~ 3
1090 if (DefaultIdx < 1 || DefaultIdx > 3)
1091 {
1092 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
1093 return FALSE;
1094 }
1095
1096
1097#ifdef CONFIG_STA_SUPPORT
1098 // Todo
1099#endif // CONFIG_STA_SUPPORT //
1100
1101 return TRUE;
1102
1103}
1104
1105
1106/*
1107 ========================================================================
1108
1109 Routine Description:
1110 Construct EAPoL message for WPA handshaking
1111 Its format is below,
1112
1113 +--------------------+
1114 | Protocol Version | 1 octet
1115 +--------------------+
1116 | Protocol Type | 1 octet
1117 +--------------------+
1118 | Body Length | 2 octets
1119 +--------------------+
1120 | Descriptor Type | 1 octet
1121 +--------------------+
1122 | Key Information | 2 octets
1123 +--------------------+
1124 | Key Length | 1 octet
1125 +--------------------+
1126 | Key Repaly Counter | 8 octets
1127 +--------------------+
1128 | Key Nonce | 32 octets
1129 +--------------------+
1130 | Key IV | 16 octets
1131 +--------------------+
1132 | Key RSC | 8 octets
1133 +--------------------+
1134 | Key ID or Reserved | 8 octets
1135 +--------------------+
1136 | Key MIC | 16 octets
1137 +--------------------+
1138 | Key Data Length | 2 octets
1139 +--------------------+
1140 | Key Data | n octets
1141 +--------------------+
1142
1143
1144 Arguments:
1145 pAd Pointer to our adapter
1146
1147 Return Value:
1148 None
1149
1150 Note:
1151
1152 ========================================================================
1153*/
1154VOID ConstructEapolMsg(
1155 IN PRTMP_ADAPTER pAd,
1156 IN UCHAR AuthMode,
1157 IN UCHAR WepStatus,
1158 IN UCHAR GroupKeyWepStatus,
1159 IN UCHAR MsgType,
1160 IN UCHAR DefaultKeyIdx,
1161 IN UCHAR *ReplayCounter,
1162 IN UCHAR *KeyNonce,
1163 IN UCHAR *TxRSC,
1164 IN UCHAR *PTK,
1165 IN UCHAR *GTK,
1166 IN UCHAR *RSNIE,
1167 IN UCHAR RSNIE_Len,
1168 OUT PEAPOL_PACKET pMsg)
1169{
1170 BOOLEAN bWPA2 = FALSE;
1171
1172 // Choose WPA2 or not
1173 if ((AuthMode == Ndis802_11AuthModeWPA2) || (AuthMode == Ndis802_11AuthModeWPA2PSK))
1174 bWPA2 = TRUE;
1175
1176 // Init Packet and Fill header
1177 pMsg->ProVer = EAPOL_VER;
1178 pMsg->ProType = EAPOLKey;
1179
1180 // Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field
1181 pMsg->Body_Len[1] = LEN_EAPOL_KEY_MSG;
1182
1183 // Fill in EAPoL descriptor
1184 if (bWPA2)
1185 pMsg->KeyDesc.Type = WPA2_KEY_DESC;
1186 else
1187 pMsg->KeyDesc.Type = WPA1_KEY_DESC;
1188
1189 // Fill in Key information, refer to IEEE Std 802.11i-2004 page 78
1190 // When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used.
1191 pMsg->KeyDesc.KeyInfo.KeyDescVer =
1192 (((WepStatus == Ndis802_11Encryption3Enabled) || (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1193
1194 // Specify Key Type as Group(0) or Pairwise(1)
1195 if (MsgType >= EAPOL_GROUP_MSG_1)
1196 pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
1197 else
1198 pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
1199
1200 // Specify Key Index, only group_msg1_WPA1
1201 if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
1202 pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
1203
1204 if (MsgType == EAPOL_PAIR_MSG_3)
1205 pMsg->KeyDesc.KeyInfo.Install = 1;
1206
1207 if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))
1208 pMsg->KeyDesc.KeyInfo.KeyAck = 1;
1209
1210 if (MsgType != EAPOL_PAIR_MSG_1)
1211 pMsg->KeyDesc.KeyInfo.KeyMic = 1;
1212
1213 if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)))
1214 {
1215 pMsg->KeyDesc.KeyInfo.Secure = 1;
1216 }
1217
1218 if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
1219 {
1220 pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
1221 }
1222
1223 // key Information element has done.
1224 *(USHORT *)(&pMsg->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo));
1225
1226 // Fill in Key Length
1227 {
1228 if (MsgType >= EAPOL_GROUP_MSG_1)
1229 {
1230 // the length of group key cipher
1231 pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY);
1232 }
1233 else
1234 {
1235 // the length of pairwise key cipher
1236 pMsg->KeyDesc.KeyLength[1] = ((WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);
1237 }
1238 }
1239
1240 // Fill in replay counter
1241 NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, ReplayCounter, LEN_KEY_DESC_REPLAY);
1242
1243 // Fill Key Nonce field
1244 // ANonce : pairwise_msg1 & pairwise_msg3
1245 // SNonce : pairwise_msg2
1246 // GNonce : group_msg1_wpa1
1247 if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
1248 NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE);
1249
1250 // Fill key IV - WPA2 as 0, WPA1 as random
1251 if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
1252 {
1253 // Suggest IV be random number plus some number,
1254 NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV);
1255 pMsg->KeyDesc.KeyIv[15] += 2;
1256 }
1257
1258 // Fill Key RSC field
1259 // It contains the RSC for the GTK being installed.
1260 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
1261 {
1262 NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
1263 }
1264
1265 // Clear Key MIC field for MIC calculation later
1266 NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1267
1268 ConstructEapolKeyData(pAd,
1269 AuthMode,
1270 WepStatus,
1271 GroupKeyWepStatus,
1272 MsgType,
1273 DefaultKeyIdx,
1274 bWPA2,
1275 PTK,
1276 GTK,
1277 RSNIE,
1278 RSNIE_Len,
1279 pMsg);
1280
1281 // Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.
1282 if (MsgType != EAPOL_PAIR_MSG_1)
1283 {
1284 CalculateMIC(pAd, WepStatus, PTK, pMsg);
1285 }
1286
1287 DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
1288 DBGPRINT(RT_DEBUG_TRACE, (" Body length = %d \n", pMsg->Body_Len[1]));
1289 DBGPRINT(RT_DEBUG_TRACE, (" Key length = %d \n", pMsg->KeyDesc.KeyLength[1]));
1290
1291
1292}
1293
1294/*
1295 ========================================================================
1296
1297 Routine Description:
1298 Construct the Key Data field of EAPoL message
1299
1300 Arguments:
1301 pAd Pointer to our adapter
1302 Elem Message body
1303
1304 Return Value:
1305 None
1306
1307 Note:
1308
1309 ========================================================================
1310*/
1311VOID ConstructEapolKeyData(
1312 IN PRTMP_ADAPTER pAd,
1313 IN UCHAR AuthMode,
1314 IN UCHAR WepStatus,
1315 IN UCHAR GroupKeyWepStatus,
1316 IN UCHAR MsgType,
1317 IN UCHAR DefaultKeyIdx,
1318 IN BOOLEAN bWPA2Capable,
1319 IN UCHAR *PTK,
1320 IN UCHAR *GTK,
1321 IN UCHAR *RSNIE,
1322 IN UCHAR RSNIE_LEN,
1323 OUT PEAPOL_PACKET pMsg)
1324{
1325 UCHAR *mpool, *Key_Data, *Rc4GTK;
1326 UCHAR ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)];
1327 UCHAR data_offset;
1328
1329
1330 if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
1331 return;
1332
1333 // allocate memory pool
1334 os_alloc_mem(pAd, (PUCHAR *)&mpool, 1500);
1335
1336 if (mpool == NULL)
1337 return;
1338
1339 /* Rc4GTK Len = 512 */
1340 Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4);
1341 /* Key_Data Len = 512 */
1342 Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4);
1343
1344 NdisZeroMemory(Key_Data, 512);
1345 pMsg->KeyDesc.KeyDataLen[1] = 0;
1346 data_offset = 0;
1347
1348 // Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3
1349 if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3)))
1350 {
1351 if (bWPA2Capable)
1352 Key_Data[data_offset + 0] = IE_WPA2;
1353 else
1354 Key_Data[data_offset + 0] = IE_WPA;
1355
1356 Key_Data[data_offset + 1] = RSNIE_LEN;
1357 NdisMoveMemory(&Key_Data[data_offset + 2], RSNIE, RSNIE_LEN);
1358 data_offset += (2 + RSNIE_LEN);
1359 }
1360
1361 // Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2
1362 if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
1363 {
1364 // Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h
1365 Key_Data[data_offset + 0] = 0xDD;
1366
1367 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
1368 {
1369 Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField)
1370 }
1371 else
1372 {
1373 Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField)
1374 }
1375
1376 Key_Data[data_offset + 2] = 0x00;
1377 Key_Data[data_offset + 3] = 0x0F;
1378 Key_Data[data_offset + 4] = 0xAC;
1379 Key_Data[data_offset + 5] = 0x01;
1380
1381 // GTK KDE format - 802.11i-2004 Figure-43x
1382 Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
1383 Key_Data[data_offset + 7] = 0x00; // Reserved Byte
1384
1385 data_offset += 8;
1386 }
1387
1388
1389 // Encapsulate GTK and encrypt the key-data field with KEK.
1390 // Only for pairwise_msg3_WPA2 and group_msg1
1391 if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1))
1392 {
1393 // Fill in GTK
1394 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
1395 {
1396 NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY);
1397 data_offset += LEN_AES_KEY;
1398 }
1399 else
1400 {
1401 NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH);
1402 data_offset += TKIP_GTK_LENGTH;
1403 }
1404
1405 // Still dont know why, but if not append will occur "GTK not include in MSG3"
1406 // Patch for compatibility between zero config and funk
1407 if (MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
1408 {
1409 if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
1410 {
1411 Key_Data[data_offset + 0] = 0xDD;
1412 Key_Data[data_offset + 1] = 0;
1413 data_offset += 2;
1414 }
1415 else
1416 {
1417 Key_Data[data_offset + 0] = 0xDD;
1418 Key_Data[data_offset + 1] = 0;
1419 Key_Data[data_offset + 2] = 0;
1420 Key_Data[data_offset + 3] = 0;
1421 Key_Data[data_offset + 4] = 0;
1422 Key_Data[data_offset + 5] = 0;
1423 data_offset += 6;
1424 }
1425 }
1426
1427 // Encrypt the data material in key data field
1428 if (WepStatus == Ndis802_11Encryption3Enabled)
1429 {
1430 AES_GTK_KEY_WRAP(&PTK[16], Key_Data, data_offset, Rc4GTK);
1431 // AES wrap function will grow 8 bytes in length
1432 data_offset += 8;
1433 }
1434 else
1435 {
1436 // PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)
1437 // put TxTsc in Key RSC field
1438 pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
1439
1440 // ekey is the contanetion of IV-field, and PTK[16]->PTK[31]
1441 NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV);
1442 NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &PTK[16], LEN_EAP_EK);
1443 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); //INIT SBOX, KEYLEN+3(IV)
1444 pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset);
1445 WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset);
1446 }
1447
1448 NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
1449 }
1450 else
1451 {
1452 NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
1453 }
1454
1455 // set key data length field and total length
1456 pMsg->KeyDesc.KeyDataLen[1] = data_offset;
1457 pMsg->Body_Len[1] += data_offset;
1458
1459 os_free_mem(pAd, mpool);
1460
1461}
1462
1463/*
1464 ========================================================================
1465
1466 Routine Description:
1467 Calcaulate MIC. It is used during 4-ways handsharking.
1468
1469 Arguments:
1470 pAd - pointer to our pAdapter context
1471 PeerWepStatus - indicate the encryption type
1472
1473 Return Value:
1474
1475 Note:
1476
1477 ========================================================================
1478*/
1479VOID CalculateMIC(
1480 IN PRTMP_ADAPTER pAd,
1481 IN UCHAR PeerWepStatus,
1482 IN UCHAR *PTK,
1483 OUT PEAPOL_PACKET pMsg)
1484{
1485 UCHAR *OutBuffer;
1486 ULONG FrameLen = 0;
1487 UCHAR mic[LEN_KEY_DESC_MIC];
1488 UCHAR digest[80];
1489
1490 // allocate memory for MIC calculation
1491 os_alloc_mem(pAd, (PUCHAR *)&OutBuffer, 512);
1492
1493 if (OutBuffer == NULL)
1494 {
1495 DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n"));
1496 return;
1497 }
1498
1499 // make a frame for calculating MIC.
1500 MakeOutgoingFrame(OutBuffer, &FrameLen,
1501 pMsg->Body_Len[1] + 4, pMsg,
1502 END_OF_ARGS);
1503
1504 NdisZeroMemory(mic, sizeof(mic));
1505
1506 // Calculate MIC
1507 if (PeerWepStatus == Ndis802_11Encryption3Enabled)
1508 {
1509 HMAC_SHA1(OutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
1510 NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
1511 }
1512 else
1513 {
1514 hmac_md5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic);
1515 }
1516
1517 // store the calculated MIC
1518 NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
1519
1520 os_free_mem(pAd, OutBuffer);
1521}
1522
1523/*
1524 ========================================================================
1525
1526 Routine Description:
1527 Some received frames can't decrypt by Asic, so decrypt them by software.
1528
1529 Arguments:
1530 pAd - pointer to our pAdapter context
1531 PeerWepStatus - indicate the encryption type
1532
1533 Return Value:
1534 NDIS_STATUS_SUCCESS - decryption successful
1535 NDIS_STATUS_FAILURE - decryption failure
1536
1537 ========================================================================
1538*/
1539NDIS_STATUS RTMPSoftDecryptBroadCastData(
1540 IN PRTMP_ADAPTER pAd,
1541 IN RX_BLK *pRxBlk,
1542 IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,
1543 IN PCIPHER_KEY pShard_key)
1544{
1545 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
1546
1547
1548
1549 // handle WEP decryption
1550 if (GroupCipher == Ndis802_11Encryption1Enabled)
1551 {
1552 if (RTMPSoftDecryptWEP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, pShard_key))
1553 {
1554
1555 //Minus IV[4] & ICV[4]
1556 pRxWI->MPDUtotalByteCount -= 8;
1557 }
1558 else
1559 {
1560 DBGPRINT(RT_DEBUG_ERROR, ("ERROR : Software decrypt WEP data fails.\n"));
1561 // give up this frame
1562 return NDIS_STATUS_FAILURE;
1563 }
1564 }
1565 // handle TKIP decryption
1566 else if (GroupCipher == Ndis802_11Encryption2Enabled)
1567 {
1568 if (RTMPSoftDecryptTKIP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, pShard_key))
1569 {
1570
1571 //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
1572 pRxWI->MPDUtotalByteCount -= 20;
1573 }
1574 else
1575 {
1576 DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
1577 // give up this frame
1578 return NDIS_STATUS_FAILURE;
1579 }
1580 }
1581 // handle AES decryption
1582 else if (GroupCipher == Ndis802_11Encryption3Enabled)
1583 {
1584 if (RTMPSoftDecryptAES(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount , pShard_key))
1585 {
1586
1587 //8 bytes MIC, 8 bytes IV/EIV (CCMP Header)
1588 pRxWI->MPDUtotalByteCount -= 16;
1589 }
1590 else
1591 {
1592 DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptAES Failed\n"));
1593 // give up this frame
1594 return NDIS_STATUS_FAILURE;
1595 }
1596 }
1597 else
1598 {
1599 // give up this frame
1600 return NDIS_STATUS_FAILURE;
1601 }
1602
1603 return NDIS_STATUS_SUCCESS;
1604
1605}
1606
diff --git a/drivers/staging/rt2860/common/dfs.c b/drivers/staging/rt2860/common/dfs.c
new file mode 100644
index 00000000000..23cf1510e2d
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/common/eeprom.c b/drivers/staging/rt2860/common/eeprom.c
new file mode 100644
index 00000000000..bed2d666629
--- /dev/null
+++ b/drivers/staging/rt2860/common/eeprom.c
@@ -0,0 +1,244 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 eeprom.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36*/
37#include "../rt_config.h"
38
39// IRQL = PASSIVE_LEVEL
40VOID RaiseClock(
41 IN PRTMP_ADAPTER pAd,
42 IN UINT32 *x)
43{
44 *x = *x | EESK;
45 RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
46 RTMPusecDelay(1); // Max frequency = 1MHz in Spec. definition
47}
48
49// IRQL = PASSIVE_LEVEL
50VOID LowerClock(
51 IN PRTMP_ADAPTER pAd,
52 IN UINT32 *x)
53{
54 *x = *x & ~EESK;
55 RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
56 RTMPusecDelay(1);
57}
58
59// IRQL = PASSIVE_LEVEL
60USHORT ShiftInBits(
61 IN PRTMP_ADAPTER pAd)
62{
63 UINT32 x,i;
64 USHORT data=0;
65
66 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
67
68 x &= ~( EEDO | EEDI);
69
70 for(i=0; i<16; i++)
71 {
72 data = data << 1;
73 RaiseClock(pAd, &x);
74
75 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
76
77 x &= ~(EEDI);
78 if(x & EEDO)
79 data |= 1;
80
81 LowerClock(pAd, &x);
82 }
83
84 return data;
85}
86
87// IRQL = PASSIVE_LEVEL
88VOID ShiftOutBits(
89 IN PRTMP_ADAPTER pAd,
90 IN USHORT data,
91 IN USHORT count)
92{
93 UINT32 x,mask;
94
95 mask = 0x01 << (count - 1);
96 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
97
98 x &= ~(EEDO | EEDI);
99
100 do
101 {
102 x &= ~EEDI;
103 if(data & mask) x |= EEDI;
104
105 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
106
107 RaiseClock(pAd, &x);
108 LowerClock(pAd, &x);
109
110 mask = mask >> 1;
111 } while(mask);
112
113 x &= ~EEDI;
114 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
115}
116
117// IRQL = PASSIVE_LEVEL
118VOID EEpromCleanup(
119 IN PRTMP_ADAPTER pAd)
120{
121 UINT32 x;
122
123 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
124
125 x &= ~(EECS | EEDI);
126 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
127
128 RaiseClock(pAd, &x);
129 LowerClock(pAd, &x);
130}
131
132VOID EWEN(
133 IN PRTMP_ADAPTER pAd)
134{
135 UINT32 x;
136
137 // reset bits and set EECS
138 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
139 x &= ~(EEDI | EEDO | EESK);
140 x |= EECS;
141 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
142
143 // kick a pulse
144 RaiseClock(pAd, &x);
145 LowerClock(pAd, &x);
146
147 // output the read_opcode and six pulse in that order
148 ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
149 ShiftOutBits(pAd, 0, 6);
150
151 EEpromCleanup(pAd);
152}
153
154VOID EWDS(
155 IN PRTMP_ADAPTER pAd)
156{
157 UINT32 x;
158
159 // reset bits and set EECS
160 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
161 x &= ~(EEDI | EEDO | EESK);
162 x |= EECS;
163 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
164
165 // kick a pulse
166 RaiseClock(pAd, &x);
167 LowerClock(pAd, &x);
168
169 // output the read_opcode and six pulse in that order
170 ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
171 ShiftOutBits(pAd, 0, 6);
172
173 EEpromCleanup(pAd);
174}
175
176// IRQL = PASSIVE_LEVEL
177USHORT RTMP_EEPROM_READ16(
178 IN PRTMP_ADAPTER pAd,
179 IN USHORT Offset)
180{
181 UINT32 x;
182 USHORT data;
183
184 Offset /= 2;
185 // reset bits and set EECS
186 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
187 x &= ~(EEDI | EEDO | EESK);
188 x |= EECS;
189 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
190
191 // kick a pulse
192 RaiseClock(pAd, &x);
193 LowerClock(pAd, &x);
194
195 // output the read_opcode and register number in that order
196 ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
197 ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
198
199 // Now read the data (16 bits) in from the selected EEPROM word
200 data = ShiftInBits(pAd);
201
202 EEpromCleanup(pAd);
203
204 return data;
205} //ReadEEprom
206
207VOID RTMP_EEPROM_WRITE16(
208 IN PRTMP_ADAPTER pAd,
209 IN USHORT Offset,
210 IN USHORT Data)
211{
212 UINT32 x;
213
214 Offset /= 2;
215
216 EWEN(pAd);
217
218 // reset bits and set EECS
219 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
220 x &= ~(EEDI | EEDO | EESK);
221 x |= EECS;
222 RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
223
224 // kick a pulse
225 RaiseClock(pAd, &x);
226 LowerClock(pAd, &x);
227
228 // output the read_opcode ,register number and data in that order
229 ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
230 ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
231 ShiftOutBits(pAd, Data, 16); // 16-bit access
232
233 // read DO status
234 RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
235
236 EEpromCleanup(pAd);
237
238 RTMPusecDelay(10000); //delay for twp(MAX)=10ms
239
240 EWDS(pAd);
241
242 EEpromCleanup(pAd);
243}
244
diff --git a/drivers/staging/rt2860/common/firmware.h b/drivers/staging/rt2860/common/firmware.h
new file mode 100644
index 00000000000..e72996f42c0
--- /dev/null
+++ b/drivers/staging/rt2860/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 [] = {
470x02, 0x03, 0x5e, 0x02, 0x02, 0xb1, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x82, 0xff, 0xff,
480xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x33, 0xc0, 0xe0,
490xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,
500x12, 0x10, 0x09, 0x90, 0x04, 0x16, 0xe0, 0x30, 0xe3, 0x03, 0x74, 0x08, 0xf0, 0x90, 0x04, 0x14,
510xe0, 0x20, 0xe7, 0x03, 0x02, 0x00, 0xcb, 0x74, 0x80, 0xf0, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x2f,
520x90, 0x04, 0x04, 0xe0, 0x24, 0xcf, 0x60, 0x30, 0x14, 0x60, 0x42, 0x24, 0xe2, 0x60, 0x47, 0x14,
530x60, 0x55, 0x24, 0x21, 0x70, 0x60, 0xe5, 0x55, 0x24, 0xfe, 0x60, 0x07, 0x14, 0x60, 0x08, 0x24,
540x02, 0x70, 0x08, 0x7d, 0x01, 0x80, 0x28, 0x7d, 0x02, 0x80, 0x24, 0x90, 0x70, 0x10, 0xe0, 0xf5,
550x50, 0x85, 0x2f, 0x40, 0xd2, 0x01, 0x80, 0x3e, 0xe5, 0x55, 0x64, 0x03, 0x60, 0x04, 0xe5, 0x55,
560x70, 0x04, 0x7d, 0x02, 0x80, 0x09, 0x85, 0x2f, 0x41, 0xd2, 0x02, 0x80, 0x29, 0xad, 0x55, 0xaf,
570x2f, 0x12, 0x02, 0x8d, 0x80, 0x20, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x47, 0x90, 0x70, 0x11, 0xe0,
580xf5, 0x44, 0x12, 0x10, 0x25, 0x80, 0x06, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x45, 0xe4, 0xfd, 0xaf,
590x2f, 0x12, 0x02, 0x8d, 0xd2, 0x04, 0x90, 0x70, 0x13, 0xe4, 0xf0, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0,
600x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x53, 0xc2,
610xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d,
620xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x30, 0x90,
630x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10,
640x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a,
650x0d, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x02, 0x2c, 0x74, 0xff, 0xf0, 0xc2, 0x05,
660xd2, 0xaf, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0xe8, 0xc0, 0xe0,
670xe9, 0xc0, 0xe0, 0xea, 0xc0, 0xe0, 0xeb, 0xc0, 0xe0, 0xec, 0xc0, 0xe0, 0xed, 0xc0, 0xe0, 0xee,
680xc0, 0xe0, 0xef, 0xc0, 0xe0, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x12, 0xd2, 0xaf, 0xd0,
690xe0, 0xff, 0xd0, 0xe0, 0xfe, 0xd0, 0xe0, 0xfd, 0xd0, 0xe0, 0xfc, 0xd0, 0xe0, 0xfb, 0xd0, 0xe0,
700xfa, 0xd0, 0xe0, 0xf9, 0xd0, 0xe0, 0xf8, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0,
710xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0xc2,
720xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x0c, 0x30, 0x58, 0x0a, 0xe5, 0x54, 0x60, 0x04, 0x15, 0x54,
730x80, 0x02, 0xc2, 0x58, 0x30, 0x59, 0x0a, 0xe5, 0x50, 0x60, 0x04, 0x15, 0x50, 0x80, 0x02, 0xc2,
740x59, 0xd5, 0x53, 0x07, 0x30, 0x60, 0x04, 0x15, 0x46, 0xd2, 0x04, 0x30, 0x45, 0x03, 0x12, 0x10,
750x0f, 0xc2, 0x8d, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32,
760x12, 0x02, 0xd3, 0x30, 0x45, 0x03, 0x12, 0x10, 0x03, 0x30, 0x01, 0x06, 0x20, 0x09, 0x03, 0x12,
770x10, 0x1c, 0x30, 0x02, 0x06, 0x20, 0x0a, 0x03, 0x12, 0x10, 0x1f, 0x30, 0x03, 0x06, 0x20, 0x0b,
780x03, 0x12, 0x10, 0x1f, 0x30, 0x04, 0x06, 0x20, 0x0c, 0x03, 0x12, 0x10, 0x22, 0x20, 0x13, 0x09,
790x20, 0x11, 0x06, 0xe5, 0x2b, 0x45, 0x2c, 0x60, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0xa9, 0x12,
800x02, 0xec, 0x80, 0xbf, 0xc2, 0x43, 0xd2, 0x45, 0xe4, 0xf5, 0x20, 0xf5, 0x21, 0xf5, 0x53, 0xf5,
810x46, 0xf5, 0x2b, 0xf5, 0x2c, 0xc2, 0x42, 0xf5, 0x51, 0xf5, 0x52, 0xf5, 0x55, 0x90, 0x04, 0x18,
820x74, 0x80, 0xf0, 0x90, 0x04, 0x1a, 0x74, 0x08, 0xf0, 0xc2, 0x19, 0xc2, 0x18, 0xc2, 0x1a, 0x22,
830xc8, 0xef, 0xc8, 0xe6, 0xfa, 0x08, 0xe6, 0x4a, 0x60, 0x0c, 0xc8, 0xef, 0xc8, 0x08, 0xe6, 0x16,
840x18, 0x70, 0x01, 0x16, 0xc3, 0x22, 0xed, 0x24, 0xff, 0xfd, 0xec, 0x34, 0xff, 0xc8, 0xef, 0xc8,
850xf6, 0x08, 0xc6, 0xed, 0xc6, 0xd3, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12,
860x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83,
870xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0xef, 0xf4, 0x60,
880x1f, 0xe4, 0xfe, 0x12, 0x03, 0x6a, 0xe0, 0xb4, 0xff, 0x12, 0x12, 0x03, 0x6a, 0xef, 0xf0, 0x74,
890x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xe3,
900x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf,
910x30, 0x45, 0x03, 0x12, 0x10, 0x06, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0,
920xd0, 0xe0, 0x32, 0xc2, 0xaf, 0x12, 0x00, 0x06, 0x12, 0x02, 0x14, 0x12, 0x03, 0x1c, 0xe4, 0xf5,
930x22, 0xf5, 0x47, 0x90, 0x04, 0x00, 0x74, 0x80, 0xf0, 0xd2, 0xaf, 0x22, 0x30, 0x45, 0x03, 0x12,
940x10, 0x15, 0xe5, 0x20, 0x70, 0x03, 0x20, 0x10, 0x03, 0x30, 0x11, 0x03, 0x43, 0x87, 0x01, 0x22,
950xc0, 0x2a, 0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x2a, 0x0a, 0x22, 0xc0, 0x2a,
960x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x2a, 0x18, 0x22, 0x75, 0x89, 0x02, 0xe4,
970xf5, 0x8c, 0xf5, 0x8a, 0xf5, 0x88, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x18, 0xd2, 0x8c, 0x75,
980xa8, 0x05, 0x22, 0xce, 0xef, 0xce, 0xee, 0x60, 0x08, 0x7f, 0xff, 0x12, 0x03, 0x80, 0x1e, 0x80,
990xf5, 0x22, 0xc8, 0xef, 0xc8, 0xe6, 0x60, 0x03, 0x16, 0xc3, 0x22, 0xed, 0x14, 0xf6, 0xd3, 0x22,
1000xc8, 0xef, 0xc8, 0xe6, 0x60, 0x06, 0x16, 0xe6, 0x24, 0xff, 0xb3, 0x22, 0xc3, 0x22, 0x78, 0x7f,
1010xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x5f, 0x02, 0x01, 0xd0, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4,
1020x34, 0x70, 0xf5, 0x83, 0x22, 0xef, 0x90, 0x03, 0x7e, 0x93, 0x90, 0x03, 0x00, 0x73, 0x0a, 0x18,
1030xef, 0x60, 0x03, 0x1f, 0x80, 0xfa, 0x22, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1040xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1050xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1060xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1070xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1080xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1090xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1100xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1110xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1120xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1130xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1140xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1150xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1160xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1170xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1180xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1190xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1200xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1210xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1220xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1230xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1240xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1250xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1260xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1270xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1280xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1290xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1300xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1310xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1320xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1330xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1340xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1350xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1360xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1370xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1380xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1390xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1400xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1410xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1420xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1430xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1440xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1450xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1460xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1470xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1480xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1490xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1500xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1510xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1520xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1530xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1540xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1550xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1560xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1570xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1580xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1590xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1600xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1610xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1620xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1630xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1640xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1650xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1660xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1670xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1680xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1690xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1700xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1710xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1720xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1730xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1740xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1750xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1760xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1770xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1780xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1790xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1800xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1810xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1820xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1830xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1840xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1850xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1860xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1870xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1880xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1890xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1900xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1910xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1920xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1930xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1940xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1950xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1960xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1970xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1980xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1990xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2000xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2010xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2020xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2030xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2040xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2050xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2060xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2070xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2080xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2090xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2100xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2110xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2120xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2130xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2140xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2150xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2160xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2170xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2180xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2190xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2200xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2210xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2220xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2230xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2240xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2250xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2260xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2270xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2280xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2290xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2300xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2310xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2320xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2330xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2340xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2350xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2360xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2370xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2380xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2390xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2400xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2410xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2420xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2430xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2440xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2450xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2460xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2470xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2480xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2490xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2500xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2510xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2520xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2530xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2540xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2550xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2560xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2570xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2580xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2590xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2600xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2610xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2620xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2630xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2640xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2650xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2660xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2670xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2680xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2690xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2700xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2710xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2720xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2730xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2740xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2750xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2760xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2770xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2780xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2790xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2800xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2810xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2820xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2830xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2840xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2850xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2860xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2870xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2880xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2890xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2900xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2910xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2920xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2930xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2940xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2950xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2960xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2970xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2980xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
2990xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3000xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3010xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3020xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3030xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x3b, 0x02, 0x10, 0x3c, 0x02, 0x12, 0xb8, 0x02,
3040x12, 0xb9, 0x02, 0x13, 0x3e, 0x02, 0x13, 0x3f, 0xc3, 0x22, 0xff, 0xff, 0x02, 0x16, 0x56, 0x02,
3050x17, 0x6b, 0x02, 0x14, 0x2a, 0x02, 0x13, 0x40, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x00,
3060xd8, 0x30, 0x06, 0x06, 0x20, 0x0e, 0x03, 0x12, 0x18, 0x5e, 0x22, 0x22, 0x90, 0x04, 0x14, 0xe0,
3070x20, 0xe7, 0x03, 0x02, 0x12, 0xb7, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0,
3080x12, 0x02, 0x67, 0x11, 0x4e, 0x30, 0x11, 0x25, 0x31, 0x10, 0x87, 0x33, 0x10, 0xaa, 0x34, 0x10,
3090xc3, 0x35, 0x11, 0x57, 0x50, 0x11, 0x7b, 0x51, 0x11, 0x84, 0x52, 0x11, 0x84, 0x53, 0x11, 0x84,
3100x54, 0x11, 0xc5, 0x55, 0x11, 0xdc, 0x70, 0x12, 0x07, 0x71, 0x12, 0x34, 0x72, 0x12, 0x5e, 0x80,
3110x12, 0x81, 0x83, 0x00, 0x00, 0x12, 0xb7, 0x75, 0x24, 0x05, 0x75, 0x25, 0xdc, 0x90, 0x70, 0x9f,
3120x74, 0x12, 0xf0, 0xd2, 0x18, 0xd2, 0x61, 0x75, 0x35, 0x0d, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
3130x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0xb7, 0x02, 0x12, 0xaa, 0xc2, 0x18, 0x90, 0x01, 0x14, 0xe0,
3140x54, 0xfd, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0xb7,
3150x02, 0x12, 0xaa, 0xe5, 0x55, 0x64, 0x02, 0x70, 0x37, 0x90, 0x70, 0x10, 0xe0, 0x60, 0x08, 0x90,
3160x01, 0x0d, 0x74, 0x09, 0xf0, 0x80, 0x25, 0xe5, 0x34, 0x14, 0x60, 0x0a, 0x14, 0x60, 0x0f, 0x14,
3170x60, 0x14, 0x24, 0x03, 0x70, 0x16, 0x90, 0x01, 0x0d, 0x74, 0x08, 0xf0, 0x80, 0x0e, 0x90, 0x01,
3180x0d, 0x74, 0x0b, 0xf0, 0x80, 0x06, 0x90, 0x01, 0x0d, 0x74, 0x1b, 0xf0, 0x7d, 0x01, 0x80, 0x02,
3190x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x1b, 0x90,
3200x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02,
3210x12, 0xb7, 0x02, 0x12, 0xaa, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf, 0x56, 0x12,
3220x02, 0x8d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4,
3230x70, 0x03, 0x02, 0x12, 0xb7, 0x02, 0x12, 0xaa, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22, 0x90, 0x70,
3240x11, 0xe0, 0x24, 0xff, 0x92, 0x1b, 0x22, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60,
3250x03, 0x02, 0x12, 0xb7, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60,
3260x03, 0x02, 0x12, 0xb7, 0x75, 0x4e, 0x03, 0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24,
3270xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70,
3280x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff,
3290x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90,
3300x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02,
3310x12, 0xb7, 0x02, 0x12, 0xaa, 0xe5, 0x47, 0xb4, 0x07, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x07,
3320xf5, 0x26, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0xd2, 0x04, 0x22, 0x90, 0x70, 0x10, 0xe0,
3330xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02,
3340x8d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
3350x03, 0x02, 0x12, 0xb7, 0x02, 0x12, 0xaa, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0,
3360xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90,
3370x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02,
3380x12, 0xb7, 0x80, 0x76, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x26, 0xff, 0xc2, 0x19, 0xc2, 0x18,
3390xc2, 0x1a, 0x75, 0x34, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, 0x04, 0x14, 0x74,
3400x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x5b, 0x80, 0x4c, 0x90, 0x70,
3410x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90,
3420x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x38, 0x80,
3430x29, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x34, 0xd3, 0x94, 0x00, 0x40, 0x07, 0x90, 0x01, 0x0d, 0xe0,
3440x54, 0xfb, 0xf0, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x8d, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0,
3450xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x0d, 0x90, 0x70, 0x25, 0xe0, 0x44, 0x01,
3460xf0, 0x90, 0x02, 0x2c, 0x74, 0xff, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x60, 0x03, 0x02, 0x13, 0x3d,
3470xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0xa2, 0x19,
3480xe4, 0x33, 0x90, 0x70, 0x90, 0xf0, 0xa2, 0x18, 0xe4, 0x33, 0xa3, 0xf0, 0x30, 0x19, 0x4d, 0x90,
3490x70, 0x98, 0x74, 0x23, 0xf0, 0xa3, 0xe5, 0x25, 0xf0, 0xe5, 0x24, 0xa3, 0xf0, 0x7f, 0x35, 0x7d,
3500x32, 0x12, 0x03, 0x42, 0x50, 0x09, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf7, 0xf0, 0xd2, 0x06, 0xe5,
3510x35, 0xd3, 0x94, 0x10, 0x40, 0x1e, 0x30, 0x1a, 0x1b, 0xc2, 0x1a, 0xa2, 0x18, 0x92, 0x19, 0x20,
3520x19, 0x12, 0x90, 0x04, 0x09, 0xe0, 0x54, 0xdd, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x08, 0xf0,
3530xc2, 0x61, 0xd2, 0x03, 0xe5, 0x35, 0xb4, 0x0b, 0x14, 0xd2, 0x03, 0x22, 0xe4, 0xf5, 0x35, 0xa2,
3540x18, 0x92, 0x19, 0x30, 0x19, 0x07, 0x90, 0x04, 0x09, 0xe0, 0x44, 0x22, 0xf0, 0x22, 0x22, 0x22,
3550xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x02, 0x67, 0x13, 0x62, 0x00, 0x13, 0xf5, 0x04, 0x13,
3560xf1, 0x08, 0x13, 0xcc, 0x10, 0x13, 0x76, 0x20, 0x13, 0x96, 0x60, 0x13, 0xa7, 0xa0, 0x00, 0x00,
3570x13, 0xf7, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60,
3580x03, 0x02, 0x13, 0xf7, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4,
3590x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70,
3600x66, 0x53, 0x43, 0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5,
3610x47, 0x64, 0x06, 0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b,
3620xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06,
3630x70, 0x35, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04,
3640x06, 0x53, 0x5e, 0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75,
3650x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80,
3660x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x38, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff,
3670xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3,
3680xe5, 0x4a, 0xf0, 0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3,
3690xe5, 0x42, 0xf0, 0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0,
3700x70, 0x03, 0x12, 0x16, 0x36, 0x12, 0x14, 0x3f, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2,
3710xaf, 0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x1c, 0x80, 0x08, 0xe5, 0x4e, 0x45,
3720x4f, 0x24, 0xff, 0x92, 0x1c, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x1d, 0x74,
3730x1e, 0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x38, 0x70, 0x13, 0x30, 0x1c, 0x05, 0xe5,
3740x5f, 0x20, 0xe5, 0x0b, 0x30, 0x1d, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5,
3750x38, 0x70, 0x05, 0x75, 0x38, 0x0c, 0x80, 0x02, 0x15, 0x38, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f,
3760xe5, 0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5,
3770x47, 0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x38,
3780x70, 0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x38, 0x70, 0x05, 0x75, 0x38, 0x07, 0x80, 0x02,
3790x15, 0x38, 0xd2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5, 0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5,
3800x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a,
3810x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c, 0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0,
3820x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x15, 0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2,
3830xe3, 0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
3840x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x15, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2,
3850xe3, 0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
3860x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x15, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2,
3870xe3, 0x80, 0x0c, 0xe5, 0x46, 0x54, 0xf0, 0xff, 0xbf, 0xf0, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
3880x71, 0x92, 0x70, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x46, 0x90,
3890x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe,
3900x60, 0x1f, 0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x35, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0d,
3910x80, 0x07, 0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x04, 0x54, 0xfe, 0xf0, 0x22, 0x44, 0x01, 0xf0,
3920x22, 0xe5, 0x46, 0x30, 0xe3, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02, 0x28, 0xe0,
3930x54, 0xfe, 0x4f, 0xf0, 0x22, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x03, 0x02, 0x16, 0x35, 0xf5, 0x27,
3940x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x26, 0x14, 0x60, 0x26, 0x14, 0x60, 0x2e, 0x14,
3950x60, 0x36, 0x24, 0x03, 0x70, 0x5f, 0xe5, 0x46, 0x13, 0x13, 0x13, 0x54, 0x1f, 0x75, 0xf0, 0x03,
3960x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff,
3970x80, 0x02, 0xa2, 0x47, 0x92, 0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x3f, 0xe5, 0x46, 0x30,
3980xe3, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe3, 0x0d, 0x54, 0x70, 0xc3,
3990x94, 0x60, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20, 0x47,
4000x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2, 0x47,
4010xb3, 0x92, 0x39, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90, 0x02, 0x28, 0xe0,
4020x54, 0xfc, 0x45, 0x27, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x45,
4030x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f, 0x50, 0xd2, 0x59,
4040x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x30, 0xc2, 0xaf, 0xe5, 0x51, 0x14, 0x60, 0x4a,
4050x14, 0x60, 0x6a, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x4c, 0xd2, 0x59, 0x75, 0x55, 0x01, 0x20,
4060x19, 0x1c, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x20, 0xe1, 0x23, 0x90, 0x04, 0x34,
4070xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3, 0xe0, 0xb4, 0x02, 0x12, 0x7f, 0x20,
4080x12, 0x16, 0x4c, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x02, 0x17, 0x4c,
4090xe5, 0x50, 0x70, 0x06, 0x75, 0x30, 0x03, 0x02, 0x17, 0x4c, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03,
4100x70, 0x15, 0x7f, 0x20, 0x12, 0x16, 0x4c, 0x20, 0x19, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfb,
4110xf0, 0x75, 0x51, 0x02, 0x02, 0x17, 0x4c, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x7a, 0x20, 0x19, 0x0f,
4120x90, 0x02, 0x08, 0xe0, 0x20, 0xe3, 0x6c, 0x90, 0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x64, 0x90,
4130x12, 0x04, 0x74, 0x0a, 0xf0, 0x30, 0x1b, 0x11, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3,
4140xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x20, 0x19, 0x07, 0x90, 0x04, 0x01, 0xe0,
4150x44, 0x10, 0xf0, 0xe5, 0x34, 0xf4, 0x90, 0x04, 0x01, 0x60, 0x06, 0xe0, 0x54, 0xfb, 0xf0, 0x80,
4160x04, 0xe0, 0x54, 0xf9, 0xf0, 0x20, 0x19, 0x07, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x04, 0xf0, 0xe5,
4170x34, 0xf4, 0x60, 0x14, 0x90, 0x01, 0x0d, 0xe0, 0xf5, 0x33, 0xe5, 0x34, 0xd3, 0x94, 0x02, 0x40,
4180x07, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfd, 0xf0, 0x75, 0x30, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5,
4190x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x30, 0x03, 0xf5, 0x51, 0xe5, 0x30, 0x60, 0x18,
4200xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0x20, 0x19, 0x0e, 0xad, 0x30, 0xaf, 0x40, 0x12, 0x18,
4210x2a, 0xe5, 0x30, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x0e,
4220xe4, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d, 0x02, 0xaf, 0x40, 0x12, 0x18, 0x2a, 0xe5, 0x52,
4230x14, 0x60, 0x55, 0x14, 0x60, 0x2f, 0x24, 0x02, 0x60, 0x03, 0x02, 0x18, 0x27, 0xe5, 0x34, 0xf4,
4240x60, 0x23, 0xe5, 0x34, 0xd3, 0x94, 0x02, 0x40, 0x16, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x02, 0xf0,
4250x90, 0x01, 0x0d, 0xe0, 0x20, 0xe3, 0x03, 0x02, 0x18, 0x27, 0x7f, 0x50, 0x12, 0x16, 0x51, 0x75,
4260x52, 0x02, 0x75, 0x55, 0x03, 0xe5, 0x34, 0xf4, 0x60, 0x0a, 0xe5, 0x54, 0x70, 0x69, 0x90, 0x01,
4270x0d, 0xe5, 0x33, 0xf0, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfb, 0xf0, 0x7f, 0x20, 0x12, 0x16, 0x51,
4280x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x80, 0x4f, 0xe5, 0x54, 0x70, 0x4b, 0x90, 0x04, 0x01, 0xe0,
4290x44, 0x0e, 0xf0, 0x20, 0x19, 0x04, 0xe0, 0x54, 0xef, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44, 0x0f,
4300xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74, 0x03,
4310xf0, 0x20, 0x19, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44,
4320x0c, 0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41,
4330x12, 0x18, 0x2a, 0x80, 0x02, 0xc2, 0x03, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe,
4340x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14,
4350x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4,
4360x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x20, 0x19,
4370x03, 0x02, 0x19, 0x0f, 0x90, 0x70, 0x80, 0xe0, 0x04, 0xf0, 0x90, 0x04, 0x37, 0xe0, 0x30, 0xe5,
4380x03, 0x02, 0x19, 0x0b, 0x90, 0x04, 0x28, 0xe0, 0xf5, 0x31, 0xa3, 0xe0, 0xf5, 0x30, 0xf5, 0x32,
4390xe4, 0xf5, 0x37, 0x90, 0x70, 0x81, 0xe0, 0x04, 0xf0, 0x90, 0x70, 0x82, 0xe0, 0x04, 0xf0, 0xe5,
4400x32, 0x75, 0xf0, 0x80, 0xa4, 0x24, 0x00, 0xff, 0xe5, 0xf0, 0x34, 0x80, 0xfe, 0xe5, 0x30, 0x65,
4410x32, 0x70, 0x05, 0xfc, 0x7d, 0x18, 0x80, 0x04, 0x7c, 0x00, 0x7d, 0x00, 0xef, 0x2d, 0xff, 0xee,
4420x3c, 0xfe, 0x12, 0x19, 0x10, 0x50, 0x25, 0x90, 0x70, 0x83, 0xe0, 0x04, 0xf0, 0x90, 0x01, 0x14,
4430xe0, 0x44, 0x02, 0xf0, 0xe0, 0x30, 0xe1, 0x06, 0x90, 0x70, 0x92, 0x74, 0x45, 0xf0, 0x90, 0x70,
4440x93, 0xe0, 0x04, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x90, 0x70, 0x94, 0xf0, 0xe5, 0x32, 0x65, 0x31,
4450x60, 0x10, 0xe4, 0x25, 0x32, 0xff, 0xe4, 0x34, 0x80, 0x8f, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x32,
4460x80, 0x97, 0x90, 0x04, 0x10, 0x74, 0x01, 0xf0, 0x90, 0x04, 0x28, 0xe5, 0x31, 0xf0, 0xa3, 0xe5,
4470x30, 0xf0, 0x90, 0x04, 0x11, 0x74, 0x01, 0xf0, 0x02, 0x18, 0x6a, 0xc2, 0x06, 0xd2, 0x1a, 0x22,
4480x90, 0x70, 0x84, 0xe5, 0x37, 0xf0, 0xc3, 0x94, 0x06, 0x50, 0x19, 0x8f, 0x82, 0x8e, 0x83, 0xe0,
4490xb4, 0xff, 0x07, 0x05, 0x37, 0xe4, 0xf5, 0x36, 0x80, 0x59, 0xe4, 0xf5, 0x37, 0x8f, 0x82, 0x8e,
4500x83, 0xf0, 0x80, 0x4f, 0xe5, 0x36, 0x75, 0xf0, 0x06, 0x84, 0x74, 0x08, 0x25, 0xf0, 0xf5, 0x82,
4510xe4, 0x34, 0x10, 0xf5, 0x83, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0x6d, 0x70, 0x30,
4520x90, 0x70, 0x88, 0xe0, 0x04, 0xf0, 0xa3, 0xe0, 0xfd, 0xd3, 0x95, 0x37, 0x40, 0x02, 0x80, 0x02,
4530xad, 0x37, 0x90, 0x70, 0x89, 0xed, 0xf0, 0x05, 0x37, 0x05, 0x36, 0xe5, 0x36, 0x75, 0xf0, 0x06,
4540x84, 0x74, 0x8a, 0x25, 0xf0, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xec, 0xf0, 0x80, 0x03,
4550xe4, 0xf5, 0x37, 0x0f, 0xbf, 0x00, 0x01, 0x0e, 0xef, 0x54, 0x7f, 0x60, 0x0a, 0xe5, 0x37, 0xc3,
4560x94, 0x4e, 0x50, 0x03, 0x02, 0x19, 0x10, 0xe5, 0x37, 0xb4, 0x4e, 0x03, 0xd3, 0x80, 0x01, 0xc3,
4570x22, 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, 0x0b, 0x94, 0xeb, } ;
diff --git a/drivers/staging/rt2860/common/md5.c b/drivers/staging/rt2860/common/md5.c
new file mode 100644
index 00000000000..774776b4b8c
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c
new file mode 100644
index 00000000000..229747095ae
--- /dev/null
+++ b/drivers/staging/rt2860/common/mlme.c
@@ -0,0 +1,8667 @@
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 0x05, 0x20, 20, 15, 30,
252 0x06, 0x20, 21, 8, 20,
253 0x07, 0x20, 22, 8, 20,
254 0x08, 0x20, 23, 8, 25,
255 0x09, 0x22, 23, 8, 25,
256};
257
258UCHAR RateSwitchTable11BGN2SForABand[] = {
259// 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)
260 0x0b, 0x09, 0, 0, 0, // Initial used item after association
261 0x00, 0x21, 0, 30,101, //50
262 0x01, 0x21, 1, 20, 50,
263 0x02, 0x21, 2, 20, 50,
264 0x03, 0x21, 3, 15, 50,
265 0x04, 0x21, 4, 15, 30,
266 0x05, 0x21, 5, 15, 30,
267 0x06, 0x20, 12, 15, 30,
268 0x07, 0x20, 13, 8, 20,
269 0x08, 0x20, 14, 8, 20,
270 0x09, 0x20, 15, 8, 25,
271 0x0a, 0x22, 15, 8, 25,
272};
273
274UCHAR RateSwitchTable11BGN3SForABand[] = { // 3*3
275// 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)
276 0x0c, 0x09, 0, 0, 0, // Initial used item after association
277 0x00, 0x21, 0, 30,101, //50
278 0x01, 0x21, 1, 20, 50,
279 0x02, 0x21, 2, 20, 50,
280 0x03, 0x21, 3, 15, 50,
281 0x04, 0x21, 4, 15, 30,
282 0x05, 0x21, 5, 15, 30,
283 0x06, 0x21, 12, 15, 30,
284 0x07, 0x20, 20, 15, 30,
285 0x08, 0x20, 21, 8, 20,
286 0x09, 0x20, 22, 8, 20,
287 0x0a, 0x20, 23, 8, 25,
288 0x0b, 0x22, 23, 8, 25,
289};
290#endif // DOT11_N_SUPPORT //
291
292PUCHAR ReasonString[] = {
293 /* 0 */ "Reserved",
294 /* 1 */ "Unspecified Reason",
295 /* 2 */ "Previous Auth no longer valid",
296 /* 3 */ "STA is leaving / has left",
297 /* 4 */ "DIS-ASSOC due to inactivity",
298 /* 5 */ "AP unable to hanle all associations",
299 /* 6 */ "class 2 error",
300 /* 7 */ "class 3 error",
301 /* 8 */ "STA is leaving / has left",
302 /* 9 */ "require auth before assoc/re-assoc",
303 /* 10 */ "Reserved",
304 /* 11 */ "Reserved",
305 /* 12 */ "Reserved",
306 /* 13 */ "invalid IE",
307 /* 14 */ "MIC error",
308 /* 15 */ "4-way handshake timeout",
309 /* 16 */ "2-way (group key) handshake timeout",
310 /* 17 */ "4-way handshake IE diff among AssosReq/Rsp/Beacon",
311 /* 18 */
312};
313
314extern UCHAR OfdmRateToRxwiMCS[];
315// since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
316// otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
317ULONG BasicRateMask[12] = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
318 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
319 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
320
321UCHAR MULTICAST_ADDR[MAC_ADDR_LEN] = {0x1, 0x00, 0x00, 0x00, 0x00, 0x00};
322UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
323UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
324
325// e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
326// this value, then it's quaranteed capable of operating in 36 mbps TX rate in
327// clean environment.
328// TxRate: 1 2 5.5 11 6 9 12 18 24 36 48 54 72 100
329CHAR RssiSafeLevelForTxRate[] ={ -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
330
331UCHAR RateIdToMbps[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
332USHORT RateIdTo500Kbps[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
333
334UCHAR SsidIe = IE_SSID;
335UCHAR SupRateIe = IE_SUPP_RATES;
336UCHAR ExtRateIe = IE_EXT_SUPP_RATES;
337#ifdef DOT11_N_SUPPORT
338UCHAR HtCapIe = IE_HT_CAP;
339UCHAR AddHtInfoIe = IE_ADD_HT;
340UCHAR NewExtChanIe = IE_SECONDARY_CH_OFFSET;
341#ifdef DOT11N_DRAFT3
342UCHAR ExtHtCapIe = IE_EXT_CAPABILITY;
343#endif // DOT11N_DRAFT3 //
344#endif // DOT11_N_SUPPORT //
345UCHAR ErpIe = IE_ERP;
346UCHAR DsIe = IE_DS_PARM;
347UCHAR TimIe = IE_TIM;
348UCHAR WpaIe = IE_WPA;
349UCHAR Wpa2Ie = IE_WPA2;
350UCHAR IbssIe = IE_IBSS_PARM;
351UCHAR Ccx2Ie = IE_CCX_V2;
352
353extern UCHAR WPA_OUI[];
354
355UCHAR SES_OUI[] = {0x00, 0x90, 0x4c};
356
357UCHAR ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
358 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
359
360// Reset the RFIC setting to new series
361RTMP_RF_REGS RF2850RegTable[] = {
362// ch R1 R2 R3(TX0~4=0) R4
363 {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
364 {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
365 {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
366 {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
367 {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
368 {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
369 {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
370 {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
371 {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
372 {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
373 {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
374 {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
375 {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
376 {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
377
378 // 802.11 UNI / HyperLan 2
379 {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
380 {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
381 {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
382 {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
383 {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
384 {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
385 {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
386 {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
387 {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
388 {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
389 {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
390 {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
391
392 // 802.11 HyperLan 2
393 {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
394
395 // 2008.04.30 modified
396 // The system team has AN to improve the EVM value
397 // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
398 {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
399 {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
400 {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
401
402 {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
403 {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
404 {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
405 {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
406 {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
407 {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
408 {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
409 {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
410 {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
411 {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
412 {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
413 {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
414
415 // 802.11 UNII
416 {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
417 {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
418 {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
419 {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
420 {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
421 {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
422 {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
423
424 // Japan
425 {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
426 {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
427 {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
428 {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
429 {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
430 {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
431 {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
432
433 // still lack of MMAC(Japan) ch 34,38,42,46
434};
435UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
436
437FREQUENCY_ITEM FreqItems3020[] =
438{
439 /**************************************************/
440 // ISM : 2.4 to 2.483 GHz //
441 /**************************************************/
442 // 11g
443 /**************************************************/
444 //-CH---N-------R---K-----------
445 {1, 241, 2, 2},
446 {2, 241, 2, 7},
447 {3, 242, 2, 2},
448 {4, 242, 2, 7},
449 {5, 243, 2, 2},
450 {6, 243, 2, 7},
451 {7, 244, 2, 2},
452 {8, 244, 2, 7},
453 {9, 245, 2, 2},
454 {10, 245, 2, 7},
455 {11, 246, 2, 2},
456 {12, 246, 2, 7},
457 {13, 247, 2, 2},
458 {14, 248, 2, 4},
459};
460#define NUM_OF_3020_CHNL (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM))
461
462/*
463 ==========================================================================
464 Description:
465 initialize the MLME task and its data structure (queue, spinlock,
466 timer, state machines).
467
468 IRQL = PASSIVE_LEVEL
469
470 Return:
471 always return NDIS_STATUS_SUCCESS
472
473 ==========================================================================
474*/
475NDIS_STATUS MlmeInit(
476 IN PRTMP_ADAPTER pAd)
477{
478 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
479
480 DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
481
482 do
483 {
484 Status = MlmeQueueInit(&pAd->Mlme.Queue);
485 if(Status != NDIS_STATUS_SUCCESS)
486 break;
487
488 pAd->Mlme.bRunning = FALSE;
489 NdisAllocateSpinLock(&pAd->Mlme.TaskLock);
490
491#ifdef CONFIG_STA_SUPPORT
492 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
493 {
494 BssTableInit(&pAd->ScanTab);
495
496 // init STA state machines
497 AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc);
498 AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
499 AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
500 SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
501 WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc);
502 AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc);
503
504#ifdef QOS_DLS_SUPPORT
505 DlsStateMachineInit(pAd, &pAd->Mlme.DlsMachine, pAd->Mlme.DlsFunc);
506#endif // QOS_DLS_SUPPORT //
507
508
509 // Since we are using switch/case to implement it, the init is different from the above
510 // state machine init
511 MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
512 }
513#endif // CONFIG_STA_SUPPORT //
514
515
516
517 ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
518
519 // Init mlme periodic timer
520 RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
521
522 // Set mlme periodic timer
523 RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
524
525 // software-based RX Antenna diversity
526 RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
527
528
529#ifdef CONFIG_STA_SUPPORT
530#ifdef RT2860
531 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
532 {
533 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
534 {
535 // only PCIe cards need these two timers
536 RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE);
537 RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
538 }
539 }
540#endif // RT2860 //
541#endif // CONFIG_STA_SUPPORT //
542
543 } while (FALSE);
544
545 DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
546
547 return Status;
548}
549
550/*
551 ==========================================================================
552 Description:
553 main loop of the MLME
554 Pre:
555 Mlme has to be initialized, and there are something inside the queue
556 Note:
557 This function is invoked from MPSetInformation and MPReceive;
558 This task guarantee only one MlmeHandler will run.
559
560 IRQL = DISPATCH_LEVEL
561
562 ==========================================================================
563 */
564VOID MlmeHandler(
565 IN PRTMP_ADAPTER pAd)
566{
567 MLME_QUEUE_ELEM *Elem = NULL;
568#ifdef APCLI_SUPPORT
569 SHORT apcliIfIndex;
570#endif
571
572 // Only accept MLME and Frame from peer side, no other (control/data) frame should
573 // get into this state machine
574
575 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
576 if(pAd->Mlme.bRunning)
577 {
578 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
579 return;
580 }
581 else
582 {
583 pAd->Mlme.bRunning = TRUE;
584 }
585 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
586
587 while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
588 {
589 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
590 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
591 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
592 {
593 DBGPRINT(RT_DEBUG_TRACE, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd->Mlme.Queue.Num));
594 break;
595 }
596
597#ifdef RALINK_ATE
598 if(ATE_ON(pAd))
599 {
600 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now in MlmeHandler\n"));
601 break;
602 }
603#endif // RALINK_ATE //
604
605 //From message type, determine which state machine I should drive
606 if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
607 {
608
609 // if dequeue success
610 switch (Elem->Machine)
611 {
612 // STA state machines
613#ifdef CONFIG_STA_SUPPORT
614 case ASSOC_STATE_MACHINE:
615 StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem);
616 break;
617 case AUTH_STATE_MACHINE:
618 StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem);
619 break;
620 case AUTH_RSP_STATE_MACHINE:
621 StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem);
622 break;
623 case SYNC_STATE_MACHINE:
624 StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem);
625 break;
626 case MLME_CNTL_STATE_MACHINE:
627 MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem);
628 break;
629 case WPA_PSK_STATE_MACHINE:
630 StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
631 break;
632#ifdef LEAP_SUPPORT
633 case LEAP_STATE_MACHINE:
634 LeapMachinePerformAction(pAd, &pAd->Mlme.LeapMachine, Elem);
635 break;
636#endif
637 case AIRONET_STATE_MACHINE:
638 StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem);
639 break;
640
641#ifdef QOS_DLS_SUPPORT
642 case DLS_STATE_MACHINE:
643 StateMachinePerformAction(pAd, &pAd->Mlme.DlsMachine, Elem);
644 break;
645#endif // QOS_DLS_SUPPORT //
646#endif // CONFIG_STA_SUPPORT //
647
648 case ACTION_STATE_MACHINE:
649 StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
650 break;
651
652
653
654
655 default:
656 DBGPRINT(RT_DEBUG_TRACE, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem->Machine));
657 break;
658 } // end of switch
659
660 // free MLME element
661 Elem->Occupied = FALSE;
662 Elem->MsgLen = 0;
663
664 }
665 else {
666 DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
667 }
668 }
669
670 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
671 pAd->Mlme.bRunning = FALSE;
672 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
673}
674
675/*
676 ==========================================================================
677 Description:
678 Destructor of MLME (Destroy queue, state machine, spin lock and timer)
679 Parameters:
680 Adapter - NIC Adapter pointer
681 Post:
682 The MLME task will no longer work properly
683
684 IRQL = PASSIVE_LEVEL
685
686 ==========================================================================
687 */
688VOID MlmeHalt(
689 IN PRTMP_ADAPTER pAd)
690{
691 BOOLEAN Cancelled;
692
693 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
694
695 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
696 {
697 // disable BEACON generation and other BEACON related hardware timers
698 AsicDisableSync(pAd);
699 }
700
701#ifdef CONFIG_STA_SUPPORT
702 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
703 {
704#ifdef QOS_DLS_SUPPORT
705 UCHAR i;
706#endif // QOS_DLS_SUPPORT //
707 // Cancel pending timers
708 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
709 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
710 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
711 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
712 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
713 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
714#ifdef RT2860
715 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
716 {
717 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
718 RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
719 }
720#endif // RT2860 //
721
722#ifdef QOS_DLS_SUPPORT
723 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
724 {
725 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
726 }
727#endif // QOS_DLS_SUPPORT //
728 }
729#endif // CONFIG_STA_SUPPORT //
730
731 RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
732 RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled);
733
734
735
736 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
737 {
738 // Set LED
739 RTMPSetLED(pAd, LED_HALT);
740 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
741 }
742
743 RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled
744
745 MlmeQueueDestroy(&pAd->Mlme.Queue);
746 NdisFreeSpinLock(&pAd->Mlme.TaskLock);
747
748 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
749}
750
751VOID MlmeResetRalinkCounters(
752 IN PRTMP_ADAPTER pAd)
753{
754 pAd->RalinkCounters.LastOneSecRxOkDataCnt = pAd->RalinkCounters.OneSecRxOkDataCnt;
755 // clear all OneSecxxx counters.
756 pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
757 pAd->RalinkCounters.OneSecFalseCCACnt = 0;
758 pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
759 pAd->RalinkCounters.OneSecRxOkCnt = 0;
760 pAd->RalinkCounters.OneSecTxFailCount = 0;
761 pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
762 pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
763 pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
764
765 // TODO: for debug only. to be removed
766 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
767 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
768 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
769 pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0;
770 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0;
771 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0;
772 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0;
773 pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0;
774 pAd->RalinkCounters.OneSecTxDoneCount = 0;
775 pAd->RalinkCounters.OneSecRxCount = 0;
776 pAd->RalinkCounters.OneSecTxAggregationCount = 0;
777 pAd->RalinkCounters.OneSecRxAggregationCount = 0;
778
779 return;
780}
781
782unsigned long rx_AMSDU;
783unsigned long rx_Total;
784
785/*
786 ==========================================================================
787 Description:
788 This routine is executed periodically to -
789 1. Decide if it's a right time to turn on PwrMgmt bit of all
790 outgoiing frames
791 2. Calculate ChannelQuality based on statistics of the last
792 period, so that TX rate won't toggling very frequently between a
793 successful TX and a failed TX.
794 3. If the calculated ChannelQuality indicated current connection not
795 healthy, then a ROAMing attempt is tried here.
796
797 IRQL = DISPATCH_LEVEL
798
799 ==========================================================================
800 */
801#define ADHOC_BEACON_LOST_TIME (8*OS_HZ) // 8 sec
802VOID MlmePeriodicExec(
803 IN PVOID SystemSpecific1,
804 IN PVOID FunctionContext,
805 IN PVOID SystemSpecific2,
806 IN PVOID SystemSpecific3)
807{
808 ULONG TxTotalCnt;
809 PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
810
811#ifdef CONFIG_STA_SUPPORT
812#ifdef RT2860
813 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
814 {
815 // If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
816 // Move code to here, because following code will return when radio is off
817 if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) && (pAd->StaCfg.bHardwareRadio == TRUE) &&
818 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
819 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
820 (pAd->bPCIclkOff == FALSE))
821 {
822 UINT32 data = 0;
823
824 // Read GPIO pin2 as Hardware controlled radio state
825 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
826 if (data & 0x04)
827 {
828 pAd->StaCfg.bHwRadio = TRUE;
829 }
830 else
831 {
832 pAd->StaCfg.bHwRadio = FALSE;
833 }
834 if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
835 {
836 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
837 if (pAd->StaCfg.bRadio == TRUE)
838 {
839 MlmeRadioOn(pAd);
840 // Update extra information
841 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
842 }
843 else
844 {
845 MlmeRadioOff(pAd);
846 // Update extra information
847 pAd->ExtraInfo = HW_RADIO_OFF;
848 }
849 }
850 }
851 }
852#endif // RT2860 //
853#endif // CONFIG_STA_SUPPORT //
854
855 // Do nothing if the driver is starting halt state.
856 // This might happen when timer already been fired before cancel timer with mlmehalt
857 if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS |
858 fRTMP_ADAPTER_RADIO_OFF |
859 fRTMP_ADAPTER_RADIO_MEASUREMENT |
860 fRTMP_ADAPTER_RESET_IN_PROGRESS))))
861 return;
862
863 RT28XX_MLME_PRE_SANITY_CHECK(pAd);
864
865#ifdef RALINK_ATE
866 /* Do not show RSSI until "Normal 1 second Mlme PeriodicExec". */
867 if (ATE_ON(pAd))
868 {
869 if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE != (MLME_TASK_EXEC_MULTIPLE - 1))
870 {
871 pAd->Mlme.PeriodicRound ++;
872 return;
873 }
874 }
875#endif // RALINK_ATE //
876
877#ifdef CONFIG_STA_SUPPORT
878 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
879 {
880 // Do nothing if monitor mode is on
881 if (MONITOR_ON(pAd))
882 return;
883
884 if (pAd->Mlme.PeriodicRound & 0x1)
885 {
886 // This is the fix for wifi 11n extension channel overlapping test case. for 2860D
887 if (((pAd->MACVersion & 0xffff) == 0x0101) &&
888 (STA_TGN_WIFI_ON(pAd)) &&
889 (pAd->CommonCfg.IOTestParm.bToggle == FALSE))
890
891 {
892 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
893 pAd->CommonCfg.IOTestParm.bToggle = TRUE;
894 }
895 else if ((STA_TGN_WIFI_ON(pAd)) &&
896 ((pAd->MACVersion & 0xffff) == 0x0101))
897 {
898 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
899 pAd->CommonCfg.IOTestParm.bToggle = FALSE;
900 }
901 }
902 }
903#endif // CONFIG_STA_SUPPORT //
904
905 pAd->bUpdateBcnCntDone = FALSE;
906
907// RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
908 pAd->Mlme.PeriodicRound ++;
909
910 // execute every 500ms
911 if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
912 {
913#ifdef CONFIG_STA_SUPPORT
914 // perform dynamic tx rate switching based on past TX history
915 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
916 {
917 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
918 )
919 && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
920 MlmeDynamicTxRateSwitching(pAd);
921 }
922#endif // CONFIG_STA_SUPPORT //
923 }
924
925 // Normal 1 second Mlme PeriodicExec.
926 if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0)
927 {
928 pAd->Mlme.OneSecPeriodicRound ++;
929
930#ifdef RALINK_ATE
931 if (ATE_ON(pAd))
932 {
933 /* request from Baron : move this routine from later to here */
934 /* for showing Rx error count in ATE RXFRAME */
935 NICUpdateRawCounters(pAd);
936 if (pAd->ate.bRxFer == 1)
937 {
938 pAd->ate.RxTotalCnt += pAd->ate.RxCntPerSec;
939 ate_print(KERN_EMERG "MlmePeriodicExec: Rx packet cnt = %d/%d\n", pAd->ate.RxCntPerSec, pAd->ate.RxTotalCnt);
940 pAd->ate.RxCntPerSec = 0;
941
942 if (pAd->ate.RxAntennaSel == 0)
943 ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi0=%d, AvgRssi1=%d, AvgRssi2=%d\n\n",
944 pAd->ate.AvgRssi0, pAd->ate.AvgRssi1, pAd->ate.AvgRssi2);
945 else
946 ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi=%d\n\n", pAd->ate.AvgRssi0);
947 }
948 MlmeResetRalinkCounters(pAd);
949 return;
950 }
951#endif // RALINK_ATE //
952
953
954 if (rx_Total)
955 {
956
957 // reset counters
958 rx_AMSDU = 0;
959 rx_Total = 0;
960 }
961
962 // Media status changed, report to NDIS
963 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
964 {
965 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
966 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
967 {
968 pAd->IndicateMediaState = NdisMediaStateConnected;
969 RTMP_IndicateMediaState(pAd);
970
971 }
972 else
973 {
974 pAd->IndicateMediaState = NdisMediaStateDisconnected;
975 RTMP_IndicateMediaState(pAd);
976 }
977 }
978
979 NdisGetSystemUpTime(&pAd->Mlme.Now32);
980
981 // add the most up-to-date h/w raw counters into software variable, so that
982 // the dynamic tuning mechanism below are based on most up-to-date information
983 NICUpdateRawCounters(pAd);
984
985
986#ifdef DOT11_N_SUPPORT
987 // Need statistics after read counter. So put after NICUpdateRawCounters
988 ORIBATimerTimeout(pAd);
989#endif // DOT11_N_SUPPORT //
990
991
992 // The time period for checking antenna is according to traffic
993 if (pAd->Mlme.bEnableAutoAntennaCheck)
994 {
995 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
996 pAd->RalinkCounters.OneSecTxRetryOkCount +
997 pAd->RalinkCounters.OneSecTxFailCount;
998
999 if (TxTotalCnt > 50)
1000 {
1001 if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
1002 {
1003 AsicEvaluateRxAnt(pAd);
1004 }
1005 }
1006 else
1007 {
1008 if (pAd->Mlme.OneSecPeriodicRound % 3 == 0)
1009 {
1010 AsicEvaluateRxAnt(pAd);
1011 }
1012 }
1013 }
1014
1015#ifdef CONFIG_STA_SUPPORT
1016 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1017 STAMlmePeriodicExec(pAd);
1018#endif // CONFIG_STA_SUPPORT //
1019
1020 MlmeResetRalinkCounters(pAd);
1021
1022#ifdef CONFIG_STA_SUPPORT
1023 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1024 {
1025#ifdef RT2860
1026 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
1027#endif // RT2860 //
1028 {
1029 // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
1030 // and sending CTS-to-self over and over.
1031 // Software Patch Solution:
1032 // 1. Polling debug state register 0x10F4 every one second.
1033 // 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
1034 // 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
1035
1036 UINT32 MacReg = 0;
1037
1038 RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
1039 if (((MacReg & 0x20000000) && (MacReg & 0x80)) || ((MacReg & 0x20000000) && (MacReg & 0x20)))
1040 {
1041 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
1042 RTMPusecDelay(1);
1043 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
1044
1045 DBGPRINT(RT_DEBUG_WARN,("Warning, MAC specific condition occurs \n"));
1046 }
1047 }
1048 }
1049#endif // CONFIG_STA_SUPPORT //
1050
1051 RT28XX_MLME_HANDLER(pAd);
1052 }
1053
1054
1055 pAd->bUpdateBcnCntDone = FALSE;
1056}
1057
1058#ifdef CONFIG_STA_SUPPORT
1059VOID STAMlmePeriodicExec(
1060 PRTMP_ADAPTER pAd)
1061{
1062 ULONG TxTotalCnt;
1063
1064//
1065// We return here in ATE mode, because the statistics
1066// that ATE needs are not collected via this routine.
1067//
1068#ifdef RALINK_ATE
1069 // It is supposed that we will never reach here in ATE mode.
1070 ASSERT(!(ATE_ON(pAd)));
1071 if (ATE_ON(pAd))
1072 return;
1073#endif // RALINK_ATE //
1074
1075#ifdef WPA_SUPPLICANT_SUPPORT
1076 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
1077#endif // WPA_SUPPLICANT_SUPPORT //
1078 {
1079 // WPA MIC error should block association attempt for 60 seconds
1080 if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32))
1081 pAd->StaCfg.bBlockAssoc = FALSE;
1082 }
1083
1084 if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
1085 {
1086 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1087 {
1088 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1089 }
1090 pAd->PreMediaState = pAd->IndicateMediaState;
1091 }
1092
1093
1094
1095
1096 AsicStaBbpTuning(pAd);
1097
1098 TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
1099 pAd->RalinkCounters.OneSecTxRetryOkCount +
1100 pAd->RalinkCounters.OneSecTxFailCount;
1101
1102 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1103 {
1104 // update channel quality for Roaming and UI LinkQuality display
1105 MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32);
1106 }
1107
1108 // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
1109 // Radio is currently in noisy environment
1110 if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1111 AsicAdjustTxPower(pAd);
1112
1113 if (INFRA_ON(pAd))
1114 {
1115#ifdef QOS_DLS_SUPPORT
1116 // Check DLS time out, then tear down those session
1117 RTMPCheckDLSTimeOut(pAd);
1118#endif // QOS_DLS_SUPPORT //
1119
1120 // Is PSM bit consistent with user power management policy?
1121 // This is the only place that will set PSM bit ON.
1122 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1123 MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
1124
1125 pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
1126
1127 if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) &&
1128 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
1129 ((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600)))
1130 {
1131 RTMPSetAGCInitValue(pAd, BW_20);
1132 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
1133 }
1134
1135 {
1136 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
1137 {
1138 // When APSD is enabled, the period changes as 20 sec
1139 if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
1140 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1141 }
1142 else
1143 {
1144 // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
1145 if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
1146 {
1147 if (pAd->CommonCfg.bWmmCapable)
1148 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
1149 else
1150 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
1151 }
1152 }
1153 }
1154
1155 if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
1156 {
1157 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1158 pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
1159 pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime;
1160
1161 // Lost AP, send disconnect & link down event
1162 LinkDown(pAd, FALSE);
1163
1164#ifdef WPA_SUPPLICANT_SUPPORT
1165#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1166 if (pAd->StaCfg.WpaSupplicantUP)
1167 {
1168 union iwreq_data wrqu;
1169 //send disassociate event to wpa_supplicant
1170 memset(&wrqu, 0, sizeof(wrqu));
1171 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
1172 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1173 }
1174#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1175#endif // WPA_SUPPLICANT_SUPPORT //
1176
1177#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1178 {
1179 union iwreq_data wrqu;
1180 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1181 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1182 }
1183#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1184
1185 MlmeAutoReconnectLastSSID(pAd);
1186 }
1187 else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
1188 {
1189 pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
1190 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
1191 MlmeAutoReconnectLastSSID(pAd);
1192 }
1193
1194 // Add auto seamless roaming
1195 if (pAd->StaCfg.bFastRoaming)
1196 {
1197 SHORT dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam;
1198
1199 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));
1200
1201 if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam)
1202 {
1203 MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32);
1204 }
1205 }
1206 }
1207 else if (ADHOC_ON(pAd))
1208 {
1209 // 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails
1210 // the "TX BEACON competition" for the entire past 1 sec.
1211 // So that even when ASIC's BEACONgen engine been blocked
1212 // by peer's BEACON due to slower system clock, this STA still can send out
1213 // minimum BEACON to tell the peer I'm alive.
1214 // drawback is that this BEACON won't be well aligned at TBTT boundary.
1215 // EnqueueBeaconFrame(pAd); // software send BEACON
1216
1217 // if all 11b peers leave this BSS more than 5 seconds, update Tx rate,
1218 // restore outgoing BEACON to support B/G-mixed mode
1219 if ((pAd->CommonCfg.Channel <= 14) &&
1220 (pAd->CommonCfg.MaxTxRate <= RATE_11) &&
1221 (pAd->CommonCfg.MaxDesiredRate > RATE_11) &&
1222 ((pAd->StaCfg.Last11bBeaconRxTime + 5*OS_HZ) < pAd->Mlme.Now32))
1223 {
1224 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11B peer left, update Tx rates\n"));
1225 NdisMoveMemory(pAd->StaActive.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
1226 pAd->StaActive.SupRateLen = pAd->CommonCfg.SupRateLen;
1227 MlmeUpdateTxRates(pAd, FALSE, 0);
1228 MakeIbssBeacon(pAd); // re-build BEACON frame
1229 AsicEnableIbssSync(pAd); // copy to on-chip memory
1230 pAd->StaCfg.AdhocBOnlyJoined = FALSE;
1231 }
1232
1233#ifdef DOT11_N_SUPPORT
1234 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1235 {
1236 if ((pAd->StaCfg.AdhocBGJoined) &&
1237 ((pAd->StaCfg.Last11gBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
1238 {
1239 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11G peer left\n"));
1240 pAd->StaCfg.AdhocBGJoined = FALSE;
1241 }
1242
1243 if ((pAd->StaCfg.Adhoc20NJoined) &&
1244 ((pAd->StaCfg.Last20NBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32))
1245 {
1246 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 20MHz N peer left\n"));
1247 pAd->StaCfg.Adhoc20NJoined = FALSE;
1248 }
1249 }
1250#endif // DOT11_N_SUPPORT //
1251
1252 //radar detect
1253 if ((pAd->CommonCfg.Channel > 14)
1254 && (pAd->CommonCfg.bIEEE80211H == 1)
1255 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1256 {
1257 RadarDetectPeriodic(pAd);
1258 }
1259
1260 // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
1261 // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
1262 // join later.
1263 if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) &&
1264 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1265 {
1266 MLME_START_REQ_STRUCT StartReq;
1267
1268 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
1269 LinkDown(pAd, FALSE);
1270
1271 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
1272 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
1273 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
1274 }
1275 }
1276 else // no INFRA nor ADHOC connection
1277 {
1278
1279 if (pAd->StaCfg.bScanReqIsFromWebUI &&
1280 ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32))
1281 goto SKIP_AUTO_SCAN_CONN;
1282 else
1283 pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
1284
1285 if ((pAd->StaCfg.bAutoReconnect == TRUE)
1286 && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
1287 && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1288 {
1289 if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
1290 {
1291 MLME_SCAN_REQ_STRUCT ScanReq;
1292
1293 if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
1294 {
1295 DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
1296 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
1297 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
1298 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
1299 // Reset Missed scan number
1300 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1301 }
1302 else if (pAd->StaCfg.BssType == BSS_ADHOC) // Quit the forever scan when in a very clean room
1303 MlmeAutoReconnectLastSSID(pAd);
1304 }
1305 else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1306 {
1307 if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
1308 {
1309 MlmeAutoScan(pAd);
1310 pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
1311 }
1312 else
1313 {
1314#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1315 if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
1316 {
1317 if ((pAd->Mlme.OneSecPeriodicRound % 5) == 1)
1318 MlmeAutoReconnectLastSSID(pAd);
1319 }
1320 else
1321#endif // CARRIER_DETECTION_SUPPORT //
1322 MlmeAutoReconnectLastSSID(pAd);
1323 }
1324 }
1325 }
1326 }
1327
1328SKIP_AUTO_SCAN_CONN:
1329
1330#ifdef DOT11_N_SUPPORT
1331 if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
1332 {
1333 pAd->MacTab.fAnyBASession = TRUE;
1334 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE, FALSE);
1335 }
1336 else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
1337 {
1338 pAd->MacTab.fAnyBASession = FALSE;
1339 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1340 }
1341#endif // DOT11_N_SUPPORT //
1342
1343
1344#ifdef DOT11_N_SUPPORT
1345#ifdef DOT11N_DRAFT3
1346 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040))
1347 TriEventCounterMaintenance(pAd);
1348#endif // DOT11N_DRAFT3 //
1349#endif // DOT11_N_SUPPORT //
1350
1351 return;
1352}
1353
1354// Link down report
1355VOID LinkDownExec(
1356 IN PVOID SystemSpecific1,
1357 IN PVOID FunctionContext,
1358 IN PVOID SystemSpecific2,
1359 IN PVOID SystemSpecific3)
1360{
1361
1362 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
1363
1364 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1365 RTMP_IndicateMediaState(pAd);
1366 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1367}
1368
1369// IRQL = DISPATCH_LEVEL
1370VOID MlmeAutoScan(
1371 IN PRTMP_ADAPTER pAd)
1372{
1373 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1374 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1375 {
1376 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
1377 MlmeEnqueue(pAd,
1378 MLME_CNTL_STATE_MACHINE,
1379 OID_802_11_BSSID_LIST_SCAN,
1380 0,
1381 NULL);
1382 RT28XX_MLME_HANDLER(pAd);
1383 }
1384}
1385
1386// IRQL = DISPATCH_LEVEL
1387VOID MlmeAutoReconnectLastSSID(
1388 IN PRTMP_ADAPTER pAd)
1389{
1390
1391
1392 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1393 if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
1394 (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
1395 {
1396 NDIS_802_11_SSID OidSsid;
1397 OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
1398 NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
1399
1400 DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
1401 MlmeEnqueue(pAd,
1402 MLME_CNTL_STATE_MACHINE,
1403 OID_802_11_SSID,
1404 sizeof(NDIS_802_11_SSID),
1405 &OidSsid);
1406 RT28XX_MLME_HANDLER(pAd);
1407 }
1408}
1409#endif // CONFIG_STA_SUPPORT //
1410
1411/*
1412 ==========================================================================
1413 Validate SSID for connection try and rescan purpose
1414 Valid SSID will have visible chars only.
1415 The valid length is from 0 to 32.
1416 IRQL = DISPATCH_LEVEL
1417 ==========================================================================
1418 */
1419BOOLEAN MlmeValidateSSID(
1420 IN PUCHAR pSsid,
1421 IN UCHAR SsidLen)
1422{
1423 int index;
1424
1425 if (SsidLen > MAX_LEN_OF_SSID)
1426 return (FALSE);
1427
1428 // Check each character value
1429 for (index = 0; index < SsidLen; index++)
1430 {
1431 if (pSsid[index] < 0x20)
1432 return (FALSE);
1433 }
1434
1435 // All checked
1436 return (TRUE);
1437}
1438
1439VOID MlmeSelectTxRateTable(
1440 IN PRTMP_ADAPTER pAd,
1441 IN PMAC_TABLE_ENTRY pEntry,
1442 IN PUCHAR *ppTable,
1443 IN PUCHAR pTableSize,
1444 IN PUCHAR pInitTxRateIdx)
1445{
1446 do
1447 {
1448 // decide the rate table for tuning
1449 if (pAd->CommonCfg.TxRateTableSize > 0)
1450 {
1451 *ppTable = RateSwitchTable;
1452 *pTableSize = RateSwitchTable[0];
1453 *pInitTxRateIdx = RateSwitchTable[1];
1454
1455 break;
1456 }
1457
1458#ifdef CONFIG_STA_SUPPORT
1459 if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
1460 {
1461#ifdef DOT11_N_SUPPORT
1462 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
1463 !pAd->StaCfg.AdhocBOnlyJoined &&
1464 !pAd->StaCfg.AdhocBGJoined &&
1465 (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1466 ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
1467 {// 11N 1S Adhoc
1468 *ppTable = RateSwitchTable11N1S;
1469 *pTableSize = RateSwitchTable11N1S[0];
1470 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1471
1472 }
1473 else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
1474 !pAd->StaCfg.AdhocBOnlyJoined &&
1475 !pAd->StaCfg.AdhocBGJoined &&
1476 (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
1477 (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) &&
1478 (pAd->Antenna.field.TxPath == 2))
1479 {// 11N 2S Adhoc
1480 if (pAd->LatchRfRegs.Channel <= 14)
1481 {
1482 *ppTable = RateSwitchTable11N2S;
1483 *pTableSize = RateSwitchTable11N2S[0];
1484 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1485 }
1486 else
1487 {
1488 *ppTable = RateSwitchTable11N2SForABand;
1489 *pTableSize = RateSwitchTable11N2SForABand[0];
1490 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1491 }
1492
1493 }
1494 else
1495#endif // DOT11_N_SUPPORT //
1496 if (pAd->CommonCfg.PhyMode == PHY_11B)
1497 {
1498 *ppTable = RateSwitchTable11B;
1499 *pTableSize = RateSwitchTable11B[0];
1500 *pInitTxRateIdx = RateSwitchTable11B[1];
1501
1502 }
1503 else if((pAd->LatchRfRegs.Channel <= 14) && (pAd->StaCfg.AdhocBOnlyJoined == TRUE))
1504 {
1505 // USe B Table when Only b-only Station in my IBSS .
1506 *ppTable = RateSwitchTable11B;
1507 *pTableSize = RateSwitchTable11B[0];
1508 *pInitTxRateIdx = RateSwitchTable11B[1];
1509
1510 }
1511 else if (pAd->LatchRfRegs.Channel <= 14)
1512 {
1513 *ppTable = RateSwitchTable11BG;
1514 *pTableSize = RateSwitchTable11BG[0];
1515 *pInitTxRateIdx = RateSwitchTable11BG[1];
1516
1517 }
1518 else
1519 {
1520 *ppTable = RateSwitchTable11G;
1521 *pTableSize = RateSwitchTable11G[0];
1522 *pInitTxRateIdx = RateSwitchTable11G[1];
1523
1524 }
1525 break;
1526 }
1527#endif // CONFIG_STA_SUPPORT //
1528
1529#ifdef DOT11_N_SUPPORT
1530 if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1531 ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
1532 {// 11BGN 1S AP
1533 *ppTable = RateSwitchTable11BGN1S;
1534 *pTableSize = RateSwitchTable11BGN1S[0];
1535 *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
1536
1537 break;
1538 }
1539
1540 if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
1541 (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
1542 {// 11BGN 2S AP
1543 if (pAd->LatchRfRegs.Channel <= 14)
1544 {
1545 *ppTable = RateSwitchTable11BGN2S;
1546 *pTableSize = RateSwitchTable11BGN2S[0];
1547 *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
1548
1549 }
1550 else
1551 {
1552 *ppTable = RateSwitchTable11BGN2SForABand;
1553 *pTableSize = RateSwitchTable11BGN2SForABand[0];
1554 *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
1555
1556 }
1557 break;
1558 }
1559
1560 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
1561 {// 11N 1S AP
1562 *ppTable = RateSwitchTable11N1S;
1563 *pTableSize = RateSwitchTable11N1S[0];
1564 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1565
1566 break;
1567 }
1568
1569 if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
1570 {// 11N 2S AP
1571 if (pAd->LatchRfRegs.Channel <= 14)
1572 {
1573 *ppTable = RateSwitchTable11N2S;
1574 *pTableSize = RateSwitchTable11N2S[0];
1575 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1576 }
1577 else
1578 {
1579 *ppTable = RateSwitchTable11N2SForABand;
1580 *pTableSize = RateSwitchTable11N2SForABand[0];
1581 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1582 }
1583
1584 break;
1585 }
1586#endif // DOT11_N_SUPPORT //
1587 //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1588 if ((pEntry->RateLen == 4)
1589#ifdef DOT11_N_SUPPORT
1590 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1591#endif // DOT11_N_SUPPORT //
1592 )
1593 {// B only AP
1594 *ppTable = RateSwitchTable11B;
1595 *pTableSize = RateSwitchTable11B[0];
1596 *pInitTxRateIdx = RateSwitchTable11B[1];
1597
1598 break;
1599 }
1600
1601 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1602 if ((pEntry->RateLen > 8)
1603#ifdef DOT11_N_SUPPORT
1604 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1605#endif // DOT11_N_SUPPORT //
1606 )
1607 {// B/G mixed AP
1608 *ppTable = RateSwitchTable11BG;
1609 *pTableSize = RateSwitchTable11BG[0];
1610 *pInitTxRateIdx = RateSwitchTable11BG[1];
1611
1612 break;
1613 }
1614
1615 //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1616 if ((pEntry->RateLen == 8)
1617#ifdef DOT11_N_SUPPORT
1618 && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
1619#endif // DOT11_N_SUPPORT //
1620 )
1621 {// G only AP
1622 *ppTable = RateSwitchTable11G;
1623 *pTableSize = RateSwitchTable11G[0];
1624 *pInitTxRateIdx = RateSwitchTable11G[1];
1625
1626 break;
1627 }
1628#ifdef DOT11_N_SUPPORT
1629#endif // DOT11_N_SUPPORT //
1630
1631#ifdef CONFIG_STA_SUPPORT
1632 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1633 {
1634#ifdef DOT11_N_SUPPORT
1635 //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
1636 if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
1637#endif // DOT11_N_SUPPORT //
1638 { // Legacy mode
1639 if (pAd->CommonCfg.MaxTxRate <= RATE_11)
1640 {
1641 *ppTable = RateSwitchTable11B;
1642 *pTableSize = RateSwitchTable11B[0];
1643 *pInitTxRateIdx = RateSwitchTable11B[1];
1644 }
1645 else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
1646 {
1647 *ppTable = RateSwitchTable11G;
1648 *pTableSize = RateSwitchTable11G[0];
1649 *pInitTxRateIdx = RateSwitchTable11G[1];
1650
1651 }
1652 else
1653 {
1654 *ppTable = RateSwitchTable11BG;
1655 *pTableSize = RateSwitchTable11BG[0];
1656 *pInitTxRateIdx = RateSwitchTable11BG[1];
1657 }
1658 break;
1659 }
1660#ifdef DOT11_N_SUPPORT
1661 if (pAd->LatchRfRegs.Channel <= 14)
1662 {
1663 if (pAd->CommonCfg.TxStream == 1)
1664 {
1665 *ppTable = RateSwitchTable11N1S;
1666 *pTableSize = RateSwitchTable11N1S[0];
1667 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1668 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
1669 }
1670 else
1671 {
1672 *ppTable = RateSwitchTable11N2S;
1673 *pTableSize = RateSwitchTable11N2S[0];
1674 *pInitTxRateIdx = RateSwitchTable11N2S[1];
1675 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
1676 }
1677 }
1678 else
1679 {
1680 if (pAd->CommonCfg.TxStream == 1)
1681 {
1682 *ppTable = RateSwitchTable11N1S;
1683 *pTableSize = RateSwitchTable11N1S[0];
1684 *pInitTxRateIdx = RateSwitchTable11N1S[1];
1685 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
1686 }
1687 else
1688 {
1689 *ppTable = RateSwitchTable11N2SForABand;
1690 *pTableSize = RateSwitchTable11N2SForABand[0];
1691 *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
1692 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
1693 }
1694 }
1695#endif // DOT11_N_SUPPORT //
1696 DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
1697 pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
1698 }
1699#endif // CONFIG_STA_SUPPORT //
1700 } while(FALSE);
1701}
1702
1703#ifdef CONFIG_STA_SUPPORT
1704/*
1705 ==========================================================================
1706 Description:
1707 This routine checks if there're other APs out there capable for
1708 roaming. Caller should call this routine only when Link up in INFRA mode
1709 and channel quality is below CQI_GOOD_THRESHOLD.
1710
1711 IRQL = DISPATCH_LEVEL
1712
1713 Output:
1714 ==========================================================================
1715 */
1716VOID MlmeCheckForRoaming(
1717 IN PRTMP_ADAPTER pAd,
1718 IN ULONG Now32)
1719{
1720 USHORT i;
1721 BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
1722 BSS_ENTRY *pBss;
1723
1724 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
1725 // put all roaming candidates into RoamTab, and sort in RSSI order
1726 BssTableInit(pRoamTab);
1727 for (i = 0; i < pAd->ScanTab.BssNr; i++)
1728 {
1729 pBss = &pAd->ScanTab.BssEntry[i];
1730
1731 if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32)
1732 continue; // AP disappear
1733 if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
1734 continue; // RSSI too weak. forget it.
1735 if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
1736 continue; // skip current AP
1737 if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
1738 continue; // only AP with stronger RSSI is eligible for roaming
1739
1740 // AP passing all above rules is put into roaming candidate table
1741 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
1742 pRoamTab->BssNr += 1;
1743 }
1744
1745 if (pRoamTab->BssNr > 0)
1746 {
1747 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1748 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1749 {
1750 pAd->RalinkCounters.PoorCQIRoamingCount ++;
1751 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
1752 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
1753 RT28XX_MLME_HANDLER(pAd);
1754 }
1755 }
1756 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
1757}
1758
1759/*
1760 ==========================================================================
1761 Description:
1762 This routine checks if there're other APs out there capable for
1763 roaming. Caller should call this routine only when link up in INFRA mode
1764 and channel quality is below CQI_GOOD_THRESHOLD.
1765
1766 IRQL = DISPATCH_LEVEL
1767
1768 Output:
1769 ==========================================================================
1770 */
1771VOID MlmeCheckForFastRoaming(
1772 IN PRTMP_ADAPTER pAd,
1773 IN ULONG Now)
1774{
1775 USHORT i;
1776 BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
1777 BSS_ENTRY *pBss;
1778
1779 DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
1780 // put all roaming candidates into RoamTab, and sort in RSSI order
1781 BssTableInit(pRoamTab);
1782 for (i = 0; i < pAd->ScanTab.BssNr; i++)
1783 {
1784 pBss = &pAd->ScanTab.BssEntry[i];
1785
1786 if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
1787 continue; // RSSI too weak. forget it.
1788 if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
1789 continue; // skip current AP
1790 if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
1791 continue; // skip different SSID
1792 if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
1793 continue; // skip AP without better RSSI
1794
1795 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));
1796 // AP passing all above rules is put into roaming candidate table
1797 NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
1798 pRoamTab->BssNr += 1;
1799 }
1800
1801 if (pRoamTab->BssNr > 0)
1802 {
1803 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1804 if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
1805 {
1806 pAd->RalinkCounters.PoorCQIRoamingCount ++;
1807 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
1808 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
1809 RT28XX_MLME_HANDLER(pAd);
1810 }
1811 }
1812 // Maybe site survey required
1813 else
1814 {
1815 if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)
1816 {
1817 // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
1818 DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
1819 pAd->StaCfg.ScanCnt = 2;
1820 pAd->StaCfg.LastScanTime = Now;
1821 MlmeAutoScan(pAd);
1822 }
1823 }
1824
1825 DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
1826}
1827
1828/*
1829 ==========================================================================
1830 Description:
1831 This routine calculates TxPER, RxPER of the past N-sec period. And
1832 according to the calculation result, ChannelQuality is calculated here
1833 to decide if current AP is still doing the job.
1834
1835 If ChannelQuality is not good, a ROAMing attempt may be tried later.
1836 Output:
1837 StaCfg.ChannelQuality - 0..100
1838
1839 IRQL = DISPATCH_LEVEL
1840
1841 NOTE: This routine decide channle quality based on RX CRC error ratio.
1842 Caller should make sure a function call to NICUpdateRawCounters(pAd)
1843 is performed right before this routine, so that this routine can decide
1844 channel quality based on the most up-to-date information
1845 ==========================================================================
1846 */
1847VOID MlmeCalculateChannelQuality(
1848 IN PRTMP_ADAPTER pAd,
1849 IN ULONG Now32)
1850{
1851 ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
1852 ULONG RxCnt, RxPER;
1853 UCHAR NorRssi;
1854 CHAR MaxRssi;
1855 ULONG BeaconLostTime = BEACON_LOST_TIME;
1856
1857#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1858 // longer beacon lost time when carrier detection enabled
1859 if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
1860 {
1861 BeaconLostTime = BEACON_LOST_TIME + BEACON_LOST_TIME/2;
1862 }
1863#endif // CARRIER_DETECTION_SUPPORT //
1864
1865 MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
1866
1867 //
1868 // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
1869 //
1870 TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;
1871 TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;
1872 if (TxCnt < 5)
1873 {
1874 TxPER = 0;
1875 TxPRR = 0;
1876 }
1877 else
1878 {
1879 TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt;
1880 TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;
1881 }
1882
1883 //
1884 // calculate RX PER - don't take RxPER into consideration if too few sample
1885 //
1886 RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;
1887 if (RxCnt < 5)
1888 RxPER = 0;
1889 else
1890 RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;
1891
1892 //
1893 // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
1894 //
1895 if (INFRA_ON(pAd) &&
1896 (pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic
1897 (pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32))
1898 {
1899 DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
1900 pAd->Mlme.ChannelQuality = 0;
1901 }
1902 else
1903 {
1904 // Normalize Rssi
1905 if (MaxRssi > -40)
1906 NorRssi = 100;
1907 else if (MaxRssi < -90)
1908 NorRssi = 0;
1909 else
1910 NorRssi = (MaxRssi + 90) * 2;
1911
1912 // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
1913 pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi +
1914 TX_WEIGHTING * (100 - TxPRR) +
1915 RX_WEIGHTING* (100 - RxPER)) / 100;
1916 if (pAd->Mlme.ChannelQuality >= 100)
1917 pAd->Mlme.ChannelQuality = 100;
1918 }
1919
1920}
1921
1922VOID MlmeSetTxRate(
1923 IN PRTMP_ADAPTER pAd,
1924 IN PMAC_TABLE_ENTRY pEntry,
1925 IN PRTMP_TX_RATE_SWITCH pTxRate)
1926{
1927 UCHAR MaxMode = MODE_OFDM;
1928
1929#ifdef DOT11_N_SUPPORT
1930 MaxMode = MODE_HTGREENFIELD;
1931
1932 if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
1933 pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
1934 else
1935#endif // DOT11_N_SUPPORT //
1936 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
1937
1938 if (pTxRate->CurrMCS < MCS_AUTO)
1939 pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
1940
1941 if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
1942 pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
1943
1944 if (ADHOC_ON(pAd))
1945 {
1946 // If peer adhoc is b-only mode, we can't send 11g rate.
1947 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1948 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1949
1950 //
1951 // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
1952 //
1953 pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
1954 pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
1955 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1956
1957 // Patch speed error in status page
1958 pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
1959 }
1960 else
1961 {
1962 if (pTxRate->Mode <= MaxMode)
1963 pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
1964
1965#ifdef DOT11_N_SUPPORT
1966 if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
1967 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
1968 else
1969#endif // DOT11_N_SUPPORT //
1970 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1971
1972#ifdef DOT11_N_SUPPORT
1973 // Reexam each bandwidth's SGI support.
1974 if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
1975 {
1976 if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
1977 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1978 if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
1979 pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
1980 }
1981
1982 // Turn RTS/CTS rate to 6Mbps.
1983 if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
1984 {
1985 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1986 if (pAd->MacTab.fAnyBASession)
1987 {
1988 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1989 }
1990 else
1991 {
1992 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
1993 }
1994 }
1995 else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
1996 {
1997 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
1998 if (pAd->MacTab.fAnyBASession)
1999 {
2000 AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
2001 }
2002 else
2003 {
2004 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
2005 }
2006 }
2007 else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
2008 {
2009 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
2010
2011 }
2012 else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
2013 {
2014 AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
2015 }
2016#endif // DOT11_N_SUPPORT //
2017
2018 pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
2019 pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
2020 pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
2021 pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
2022#ifdef DOT11_N_SUPPORT
2023 if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
2024 pAd->WIFItestbed.bGreenField)
2025 pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
2026#endif // DOT11_N_SUPPORT //
2027 }
2028
2029 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
2030}
2031
2032/*
2033 ==========================================================================
2034 Description:
2035 This routine calculates the acumulated TxPER of eaxh TxRate. And
2036 according to the calculation result, change CommonCfg.TxRate which
2037 is the stable TX Rate we expect the Radio situation could sustained.
2038
2039 CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
2040 Output:
2041 CommonCfg.TxRate -
2042
2043 IRQL = DISPATCH_LEVEL
2044
2045 NOTE:
2046 call this routine every second
2047 ==========================================================================
2048 */
2049VOID MlmeDynamicTxRateSwitching(
2050 IN PRTMP_ADAPTER pAd)
2051{
2052 UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
2053 ULONG i, AccuTxTotalCnt = 0, TxTotalCnt;
2054 ULONG TxErrorRatio = 0;
2055 BOOLEAN bTxRateChanged, bUpgradeQuality = FALSE;
2056 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
2057 PUCHAR pTable;
2058 UCHAR TableSize = 0;
2059 UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
2060 CHAR Rssi, RssiOffset = 0;
2061 TX_STA_CNT1_STRUC StaTx1;
2062 TX_STA_CNT0_STRUC TxStaCnt0;
2063 ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
2064 MAC_TABLE_ENTRY *pEntry;
2065
2066#ifdef RALINK_ATE
2067 if (ATE_ON(pAd))
2068 {
2069 return;
2070 }
2071#endif // RALINK_ATE //
2072
2073 /*if (pAd->Antenna.field.RxPath > 1)
2074 Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
2075 else
2076 Rssi = pAd->StaCfg.RssiSample.AvgRssi0;*/
2077
2078 //
2079 // walk through MAC table, see if need to change AP's TX rate toward each entry
2080 //
2081 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
2082 {
2083 pEntry = &pAd->MacTab.Content[i];
2084
2085 // check if this entry need to switch rate automatically
2086 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2087 continue;
2088
2089 if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
2090 {
2091 Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.RssiSample.AvgRssi0, (CHAR)pAd->StaCfg.RssiSample.AvgRssi1, (CHAR)pAd->StaCfg.RssiSample.AvgRssi2);
2092
2093 // Update statistic counter
2094 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2095 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2096 pAd->bUpdateBcnCntDone = TRUE;
2097 TxRetransmit = StaTx1.field.TxRetransmit;
2098 TxSuccess = StaTx1.field.TxSuccess;
2099 TxFailCount = TxStaCnt0.field.TxFailCount;
2100 TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
2101
2102 pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2103 pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2104 pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2105 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2106 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2107 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2108
2109 // if no traffic in the past 1-sec period, don't change TX rate,
2110 // but clear all bad history. because the bad history may affect the next
2111 // Chariot throughput test
2112 AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
2113 pAd->RalinkCounters.OneSecTxRetryOkCount +
2114 pAd->RalinkCounters.OneSecTxFailCount;
2115
2116 if (TxTotalCnt)
2117 TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
2118 }
2119 else
2120 {
2121 Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2);
2122
2123 TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
2124 pEntry->OneSecTxRetryOkCount +
2125 pEntry->OneSecTxFailCount;
2126
2127 if (TxTotalCnt)
2128 TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
2129 }
2130
2131 CurrRateIdx = pEntry->CurrTxRateIndex;
2132
2133 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
2134
2135 if (CurrRateIdx >= TableSize)
2136 {
2137 CurrRateIdx = TableSize - 1;
2138 }
2139
2140 // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
2141 // So need to sync here.
2142 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2143 if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
2144 //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
2145 )
2146 {
2147
2148 // Need to sync Real Tx rate and our record.
2149 // Then return for next DRS.
2150 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
2151 pEntry->CurrTxRateIndex = InitTxRateIdx;
2152 MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
2153
2154 // reset all OneSecTx counters
2155 RESET_ONE_SEC_TX_CNT(pEntry);
2156 continue;
2157 }
2158
2159 // decide the next upgrade rate and downgrade rate, if any
2160 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
2161 {
2162 UpRateIdx = CurrRateIdx + 1;
2163 DownRateIdx = CurrRateIdx -1;
2164 }
2165 else if (CurrRateIdx == 0)
2166 {
2167 UpRateIdx = CurrRateIdx + 1;
2168 DownRateIdx = CurrRateIdx;
2169 }
2170 else if (CurrRateIdx == (TableSize - 1))
2171 {
2172 UpRateIdx = CurrRateIdx;
2173 DownRateIdx = CurrRateIdx - 1;
2174 }
2175
2176 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2177
2178#ifdef DOT11_N_SUPPORT
2179 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
2180 {
2181 TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
2182 TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
2183 }
2184 else
2185#endif // DOT11_N_SUPPORT //
2186 {
2187 TrainUp = pCurrTxRate->TrainUp;
2188 TrainDown = pCurrTxRate->TrainDown;
2189 }
2190
2191 //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
2192
2193 //
2194 // Keep the last time TxRateChangeAction status.
2195 //
2196 pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
2197
2198
2199
2200 //
2201 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2202 // (criteria copied from RT2500 for Netopia case)
2203 //
2204 if (TxTotalCnt <= 15)
2205 {
2206 CHAR idx = 0;
2207 UCHAR TxRateIdx;
2208 //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2209 UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0;
2210 UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
2211 UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
2212
2213 // check the existence and index of each needed MCS
2214 while (idx < pTable[0])
2215 {
2216 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
2217
2218 if (pCurrTxRate->CurrMCS == MCS_0)
2219 {
2220 MCS0 = idx;
2221 }
2222 else if (pCurrTxRate->CurrMCS == MCS_1)
2223 {
2224 MCS1 = idx;
2225 }
2226 else if (pCurrTxRate->CurrMCS == MCS_2)
2227 {
2228 MCS2 = idx;
2229 }
2230 else if (pCurrTxRate->CurrMCS == MCS_3)
2231 {
2232 MCS3 = idx;
2233 }
2234 else if (pCurrTxRate->CurrMCS == MCS_4)
2235 {
2236 MCS4 = idx;
2237 }
2238 else if (pCurrTxRate->CurrMCS == MCS_5)
2239 {
2240 MCS5 = idx;
2241 }
2242 else if (pCurrTxRate->CurrMCS == MCS_6)
2243 {
2244 MCS6 = idx;
2245 }
2246 //else if (pCurrTxRate->CurrMCS == MCS_7)
2247 else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) // prevent the highest MCS using short GI when 1T and low throughput
2248 {
2249 MCS7 = idx;
2250 }
2251 else if (pCurrTxRate->CurrMCS == MCS_12)
2252 {
2253 MCS12 = idx;
2254 }
2255 else if (pCurrTxRate->CurrMCS == MCS_13)
2256 {
2257 MCS13 = idx;
2258 }
2259 else if (pCurrTxRate->CurrMCS == MCS_14)
2260 {
2261 MCS14 = idx;
2262 }
2263 //else if ((pCurrTxRate->CurrMCS == MCS_15)/* && (pCurrTxRate->ShortGI == GI_800)*/) //we hope to use ShortGI as initial rate
2264 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
2265 {
2266 MCS15 = idx;
2267 }
2268 else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
2269 {
2270 MCS20 = idx;
2271 }
2272 else if (pCurrTxRate->CurrMCS == MCS_21)
2273 {
2274 MCS21 = idx;
2275 }
2276 else if (pCurrTxRate->CurrMCS == MCS_22)
2277 {
2278 MCS22 = idx;
2279 }
2280 else if (pCurrTxRate->CurrMCS == MCS_23)
2281 {
2282 MCS23 = idx;
2283 }
2284 idx ++;
2285 }
2286
2287 if (pAd->LatchRfRegs.Channel <= 14)
2288 {
2289 if (pAd->NicConfig2.field.ExternalLNAForG)
2290 {
2291 RssiOffset = 2;
2292 }
2293 else
2294 {
2295 RssiOffset = 5;
2296 }
2297 }
2298 else
2299 {
2300 if (pAd->NicConfig2.field.ExternalLNAForA)
2301 {
2302 RssiOffset = 5;
2303 }
2304 else
2305 {
2306 RssiOffset = 8;
2307 }
2308 }
2309#ifdef DOT11_N_SUPPORT
2310 /*if (MCS15)*/
2311 if ((pTable == RateSwitchTable11BGN3S) ||
2312 (pTable == RateSwitchTable11N3S) ||
2313 (pTable == RateSwitchTable))
2314 {// N mode with 3 stream // 3*3
2315 if (MCS23 && (Rssi >= -70))
2316 TxRateIdx = MCS15;
2317 else if (MCS22 && (Rssi >= -72))
2318 TxRateIdx = MCS14;
2319 else if (MCS21 && (Rssi >= -76))
2320 TxRateIdx = MCS13;
2321 else if (MCS20 && (Rssi >= -78))
2322 TxRateIdx = MCS12;
2323 else if (MCS4 && (Rssi >= -82))
2324 TxRateIdx = MCS4;
2325 else if (MCS3 && (Rssi >= -84))
2326 TxRateIdx = MCS3;
2327 else if (MCS2 && (Rssi >= -86))
2328 TxRateIdx = MCS2;
2329 else if (MCS1 && (Rssi >= -88))
2330 TxRateIdx = MCS1;
2331 else
2332 TxRateIdx = MCS0;
2333 }
2334 else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
2335 {// N mode with 2 stream
2336 if (MCS15 && (Rssi >= (-70+RssiOffset)))
2337 TxRateIdx = MCS15;
2338 else if (MCS14 && (Rssi >= (-72+RssiOffset)))
2339 TxRateIdx = MCS14;
2340 else if (MCS13 && (Rssi >= (-76+RssiOffset)))
2341 TxRateIdx = MCS13;
2342 else if (MCS12 && (Rssi >= (-78+RssiOffset)))
2343 TxRateIdx = MCS12;
2344 else if (MCS4 && (Rssi >= (-82+RssiOffset)))
2345 TxRateIdx = MCS4;
2346 else if (MCS3 && (Rssi >= (-84+RssiOffset)))
2347 TxRateIdx = MCS3;
2348 else if (MCS2 && (Rssi >= (-86+RssiOffset)))
2349 TxRateIdx = MCS2;
2350 else if (MCS1 && (Rssi >= (-88+RssiOffset)))
2351 TxRateIdx = MCS1;
2352 else
2353 TxRateIdx = MCS0;
2354 }
2355 else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
2356 {// N mode with 1 stream
2357 if (MCS7 && (Rssi > (-72+RssiOffset)))
2358 TxRateIdx = MCS7;
2359 else if (MCS6 && (Rssi > (-74+RssiOffset)))
2360 TxRateIdx = MCS6;
2361 else if (MCS5 && (Rssi > (-77+RssiOffset)))
2362 TxRateIdx = MCS5;
2363 else if (MCS4 && (Rssi > (-79+RssiOffset)))
2364 TxRateIdx = MCS4;
2365 else if (MCS3 && (Rssi > (-81+RssiOffset)))
2366 TxRateIdx = MCS3;
2367 else if (MCS2 && (Rssi > (-83+RssiOffset)))
2368 TxRateIdx = MCS2;
2369 else if (MCS1 && (Rssi > (-86+RssiOffset)))
2370 TxRateIdx = MCS1;
2371 else
2372 TxRateIdx = MCS0;
2373 }
2374 else
2375#endif // DOT11_N_SUPPORT //
2376 {// Legacy mode
2377 if (MCS7 && (Rssi > -70))
2378 TxRateIdx = MCS7;
2379 else if (MCS6 && (Rssi > -74))
2380 TxRateIdx = MCS6;
2381 else if (MCS5 && (Rssi > -78))
2382 TxRateIdx = MCS5;
2383 else if (MCS4 && (Rssi > -82))
2384 TxRateIdx = MCS4;
2385 else if (MCS4 == 0) // for B-only mode
2386 TxRateIdx = MCS3;
2387 else if (MCS3 && (Rssi > -85))
2388 TxRateIdx = MCS3;
2389 else if (MCS2 && (Rssi > -87))
2390 TxRateIdx = MCS2;
2391 else if (MCS1 && (Rssi > -90))
2392 TxRateIdx = MCS1;
2393 else
2394 TxRateIdx = MCS0;
2395 }
2396
2397 {
2398 pEntry->CurrTxRateIndex = TxRateIdx;
2399 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
2400 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2401 }
2402
2403 NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2404 NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2405 pEntry->fLastSecAccordingRSSI = TRUE;
2406 // reset all OneSecTx counters
2407 RESET_ONE_SEC_TX_CNT(pEntry);
2408
2409 continue;
2410 }
2411
2412 if (pEntry->fLastSecAccordingRSSI == TRUE)
2413 {
2414 pEntry->fLastSecAccordingRSSI = FALSE;
2415 pEntry->LastSecTxRateChangeAction = 0;
2416 // reset all OneSecTx counters
2417 RESET_ONE_SEC_TX_CNT(pEntry);
2418
2419 continue;
2420 }
2421
2422 do
2423 {
2424 BOOLEAN bTrainUpDown = FALSE;
2425
2426 pEntry->CurrTxRateStableTime ++;
2427
2428 // downgrade TX quality if PER >= Rate-Down threshold
2429 if (TxErrorRatio >= TrainDown)
2430 {
2431 bTrainUpDown = TRUE;
2432 pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2433 }
2434 // upgrade TX quality if PER <= Rate-Up threshold
2435 else if (TxErrorRatio <= TrainUp)
2436 {
2437 bTrainUpDown = TRUE;
2438 bUpgradeQuality = TRUE;
2439 if (pEntry->TxQuality[CurrRateIdx])
2440 pEntry->TxQuality[CurrRateIdx] --; // quality very good in CurrRate
2441
2442 if (pEntry->TxRateUpPenalty)
2443 pEntry->TxRateUpPenalty --;
2444 else if (pEntry->TxQuality[UpRateIdx])
2445 pEntry->TxQuality[UpRateIdx] --; // may improve next UP rate's quality
2446 }
2447
2448 pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
2449
2450 if (bTrainUpDown)
2451 {
2452 // perform DRS - consider TxRate Down first, then rate up.
2453 if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
2454 {
2455 pEntry->CurrTxRateIndex = DownRateIdx;
2456 }
2457 else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
2458 {
2459 pEntry->CurrTxRateIndex = UpRateIdx;
2460 }
2461 }
2462 } while (FALSE);
2463
2464 // if rate-up happen, clear all bad history of all TX rates
2465 if (pEntry->CurrTxRateIndex > CurrRateIdx)
2466 {
2467 pEntry->CurrTxRateStableTime = 0;
2468 pEntry->TxRateUpPenalty = 0;
2469 pEntry->LastSecTxRateChangeAction = 1; // rate UP
2470 NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2471 NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2472
2473 //
2474 // For TxRate fast train up
2475 //
2476 if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
2477 {
2478 RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
2479
2480 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
2481 }
2482 bTxRateChanged = TRUE;
2483 }
2484 // if rate-down happen, only clear DownRate's bad history
2485 else if (pEntry->CurrTxRateIndex < CurrRateIdx)
2486 {
2487 pEntry->CurrTxRateStableTime = 0;
2488 pEntry->TxRateUpPenalty = 0; // no penalty
2489 pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
2490 pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
2491 pEntry->PER[pEntry->CurrTxRateIndex] = 0;
2492
2493 //
2494 // For TxRate fast train down
2495 //
2496 if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
2497 {
2498 RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
2499
2500 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
2501 }
2502 bTxRateChanged = TRUE;
2503 }
2504 else
2505 {
2506 pEntry->LastSecTxRateChangeAction = 0; // rate no change
2507 bTxRateChanged = FALSE;
2508 }
2509
2510 pEntry->LastTxOkCount = TxSuccess;
2511
2512 // reset all OneSecTx counters
2513 RESET_ONE_SEC_TX_CNT(pEntry);
2514
2515 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
2516 if (bTxRateChanged && pNextTxRate)
2517 {
2518 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2519 }
2520 }
2521}
2522
2523/*
2524 ========================================================================
2525 Routine Description:
2526 Station side, Auto TxRate faster train up timer call back function.
2527
2528 Arguments:
2529 SystemSpecific1 - Not used.
2530 FunctionContext - Pointer to our Adapter context.
2531 SystemSpecific2 - Not used.
2532 SystemSpecific3 - Not used.
2533
2534 Return Value:
2535 None
2536
2537 ========================================================================
2538*/
2539VOID StaQuickResponeForRateUpExec(
2540 IN PVOID SystemSpecific1,
2541 IN PVOID FunctionContext,
2542 IN PVOID SystemSpecific2,
2543 IN PVOID SystemSpecific3)
2544{
2545 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
2546 UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
2547 ULONG TxTotalCnt;
2548 ULONG TxErrorRatio = 0;
2549 BOOLEAN bTxRateChanged = TRUE; //, bUpgradeQuality = FALSE;
2550 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
2551 PUCHAR pTable;
2552 UCHAR TableSize = 0;
2553 UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
2554 TX_STA_CNT1_STRUC StaTx1;
2555 TX_STA_CNT0_STRUC TxStaCnt0;
2556 CHAR Rssi, ratio;
2557 ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
2558 MAC_TABLE_ENTRY *pEntry;
2559 ULONG i;
2560
2561 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
2562
2563 //
2564 // walk through MAC table, see if need to change AP's TX rate toward each entry
2565 //
2566 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
2567 {
2568 pEntry = &pAd->MacTab.Content[i];
2569
2570 // check if this entry need to switch rate automatically
2571 if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
2572 continue;
2573
2574 //Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2);
2575 if (pAd->Antenna.field.TxPath > 1)
2576 Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
2577 else
2578 Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
2579
2580 CurrRateIdx = pAd->CommonCfg.TxRateIndex;
2581
2582 MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
2583
2584 // decide the next upgrade rate and downgrade rate, if any
2585 if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
2586 {
2587 UpRateIdx = CurrRateIdx + 1;
2588 DownRateIdx = CurrRateIdx -1;
2589 }
2590 else if (CurrRateIdx == 0)
2591 {
2592 UpRateIdx = CurrRateIdx + 1;
2593 DownRateIdx = CurrRateIdx;
2594 }
2595 else if (CurrRateIdx == (TableSize - 1))
2596 {
2597 UpRateIdx = CurrRateIdx;
2598 DownRateIdx = CurrRateIdx - 1;
2599 }
2600
2601 pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
2602
2603#ifdef DOT11_N_SUPPORT
2604 if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
2605 {
2606 TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
2607 TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
2608 }
2609 else
2610#endif // DOT11_N_SUPPORT //
2611 {
2612 TrainUp = pCurrTxRate->TrainUp;
2613 TrainDown = pCurrTxRate->TrainDown;
2614 }
2615
2616 if (pAd->MacTab.Size == 1)
2617 {
2618 // Update statistic counter
2619 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2620 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2621
2622 TxRetransmit = StaTx1.field.TxRetransmit;
2623 TxSuccess = StaTx1.field.TxSuccess;
2624 TxFailCount = TxStaCnt0.field.TxFailCount;
2625 TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
2626
2627 pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2628 pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2629 pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2630 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2631 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2632 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2633
2634 if (TxTotalCnt)
2635 TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
2636 }
2637 else
2638 {
2639 TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
2640 pEntry->OneSecTxRetryOkCount +
2641 pEntry->OneSecTxFailCount;
2642
2643 if (TxTotalCnt)
2644 TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
2645 }
2646
2647
2648 //
2649 // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
2650 // (criteria copied from RT2500 for Netopia case)
2651 //
2652 if (TxTotalCnt <= 12)
2653 {
2654 NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2655 NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2656
2657 if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
2658 {
2659 pAd->CommonCfg.TxRateIndex = DownRateIdx;
2660 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2661 }
2662 else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
2663 {
2664 pAd->CommonCfg.TxRateIndex = UpRateIdx;
2665 }
2666
2667 DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
2668 return;
2669 }
2670
2671 do
2672 {
2673 ULONG OneSecTxNoRetryOKRationCount;
2674
2675 if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
2676 ratio = 5;
2677 else
2678 ratio = 4;
2679
2680 // downgrade TX quality if PER >= Rate-Down threshold
2681 if (TxErrorRatio >= TrainDown)
2682 {
2683 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2684 }
2685
2686 pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
2687
2688 OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
2689
2690 // perform DRS - consider TxRate Down first, then rate up.
2691 if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
2692 {
2693 if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
2694 {
2695 pAd->CommonCfg.TxRateIndex = DownRateIdx;
2696 pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
2697
2698 }
2699
2700 }
2701 else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
2702 {
2703 if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
2704 {
2705
2706 }
2707 else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
2708 {
2709 pAd->CommonCfg.TxRateIndex = UpRateIdx;
2710 }
2711 }
2712 }while (FALSE);
2713
2714 // if rate-up happen, clear all bad history of all TX rates
2715 if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
2716 {
2717 pAd->DrsCounters.TxRateUpPenalty = 0;
2718 NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
2719 NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
2720 }
2721 // if rate-down happen, only clear DownRate's bad history
2722 else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
2723 {
2724 DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
2725
2726 pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty
2727 pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
2728 pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
2729 }
2730 else
2731 {
2732 bTxRateChanged = FALSE;
2733 }
2734
2735 pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
2736 if (bTxRateChanged && pNextTxRate)
2737 {
2738 MlmeSetTxRate(pAd, pEntry, pNextTxRate);
2739 }
2740 }
2741}
2742
2743/*
2744 ==========================================================================
2745 Description:
2746 This routine is executed periodically inside MlmePeriodicExec() after
2747 association with an AP.
2748 It checks if StaCfg.Psm is consistent with user policy (recorded in
2749 StaCfg.WindowsPowerMode). If not, enforce user policy. However,
2750 there're some conditions to consider:
2751 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
2752 the time when Mibss==TRUE
2753 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
2754 if outgoing traffic available in TxRing or MgmtRing.
2755 Output:
2756 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
2757
2758 IRQL = DISPATCH_LEVEL
2759
2760 ==========================================================================
2761 */
2762VOID MlmeCheckPsmChange(
2763 IN PRTMP_ADAPTER pAd,
2764 IN ULONG Now32)
2765{
2766 ULONG PowerMode;
2767
2768 // condition -
2769 // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
2770 // 2. user wants either MAX_PSP or FAST_PSP
2771 // 3. but current psm is not in PWR_SAVE
2772 // 4. CNTL state machine is not doing SCANning
2773 // 5. no TX SUCCESS event for the past 1-sec period
2774#ifdef NDIS51_MINIPORT
2775 if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery)
2776 PowerMode = pAd->StaCfg.WindowsBatteryPowerMode;
2777 else
2778#endif
2779 PowerMode = pAd->StaCfg.WindowsPowerMode;
2780
2781 if (INFRA_ON(pAd) &&
2782 (PowerMode != Ndis802_11PowerModeCAM) &&
2783 (pAd->StaCfg.Psm == PWR_ACTIVE) &&
2784 (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
2785 {
2786 NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
2787 pAd->RalinkCounters.RxCountSinceLastNULL = 0;
2788 MlmeSetPsmBit(pAd, PWR_SAVE);
2789 if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
2790 {
2791 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
2792 }
2793 else
2794 {
2795 RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
2796 }
2797 }
2798}
2799
2800// IRQL = PASSIVE_LEVEL
2801// IRQL = DISPATCH_LEVEL
2802VOID MlmeSetPsmBit(
2803 IN PRTMP_ADAPTER pAd,
2804 IN USHORT psm)
2805{
2806 AUTO_RSP_CFG_STRUC csr4;
2807
2808 pAd->StaCfg.Psm = psm;
2809 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
2810 csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
2811 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
2812 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
2813}
2814#endif // CONFIG_STA_SUPPORT //
2815
2816
2817// IRQL = DISPATCH_LEVEL
2818VOID MlmeSetTxPreamble(
2819 IN PRTMP_ADAPTER pAd,
2820 IN USHORT TxPreamble)
2821{
2822 AUTO_RSP_CFG_STRUC csr4;
2823
2824 //
2825 // Always use Long preamble before verifiation short preamble functionality works well.
2826 // Todo: remove the following line if short preamble functionality works
2827 //
2828 //TxPreamble = Rt802_11PreambleLong;
2829
2830 RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
2831 if (TxPreamble == Rt802_11PreambleLong)
2832 {
2833 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
2834 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2835 csr4.field.AutoResponderPreamble = 0;
2836 }
2837 else
2838 {
2839 // NOTE: 1Mbps should always use long preamble
2840 DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
2841 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2842 csr4.field.AutoResponderPreamble = 1;
2843 }
2844
2845 RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
2846}
2847
2848/*
2849 ==========================================================================
2850 Description:
2851 Update basic rate bitmap
2852 ==========================================================================
2853 */
2854
2855VOID UpdateBasicRateBitmap(
2856 IN PRTMP_ADAPTER pAdapter)
2857{
2858 INT i, j;
2859 /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
2860 UCHAR rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
2861 UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
2862 UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
2863 ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
2864
2865
2866 /* if A mode, always use fix BasicRateBitMap */
2867 //if (pAdapter->CommonCfg.Channel == PHY_11A)
2868 if (pAdapter->CommonCfg.Channel > 14)
2869 pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
2870 /* End of if */
2871
2872 if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
2873 {
2874 /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
2875 return;
2876 } /* End of if */
2877
2878 for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2879 {
2880 sup_p[i] &= 0x7f;
2881 ext_p[i] &= 0x7f;
2882 } /* End of for */
2883
2884 for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2885 {
2886 if (bitmap & (1 << i))
2887 {
2888 for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
2889 {
2890 if (sup_p[j] == rate[i])
2891 sup_p[j] |= 0x80;
2892 /* End of if */
2893 } /* End of for */
2894
2895 for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
2896 {
2897 if (ext_p[j] == rate[i])
2898 ext_p[j] |= 0x80;
2899 /* End of if */
2900 } /* End of for */
2901 } /* End of if */
2902 } /* End of for */
2903} /* End of UpdateBasicRateBitmap */
2904
2905// IRQL = PASSIVE_LEVEL
2906// IRQL = DISPATCH_LEVEL
2907// bLinkUp is to identify the inital link speed.
2908// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
2909VOID MlmeUpdateTxRates(
2910 IN PRTMP_ADAPTER pAd,
2911 IN BOOLEAN bLinkUp,
2912 IN UCHAR apidx)
2913{
2914 int i, num;
2915 UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
2916 UCHAR MinSupport = RATE_54;
2917 ULONG BasicRateBitmap = 0;
2918 UCHAR CurrBasicRate = RATE_1;
2919 UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
2920 PHTTRANSMIT_SETTING pHtPhy = NULL;
2921 PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
2922 PHTTRANSMIT_SETTING pMinHtPhy = NULL;
2923 BOOLEAN *auto_rate_cur_p;
2924 UCHAR HtMcs = MCS_AUTO;
2925
2926 // find max desired rate
2927 UpdateBasicRateBitmap(pAd);
2928
2929 num = 0;
2930 auto_rate_cur_p = NULL;
2931 for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
2932 {
2933 switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
2934 {
2935 case 2: Rate = RATE_1; num++; break;
2936 case 4: Rate = RATE_2; num++; break;
2937 case 11: Rate = RATE_5_5; num++; break;
2938 case 22: Rate = RATE_11; num++; break;
2939 case 12: Rate = RATE_6; num++; break;
2940 case 18: Rate = RATE_9; num++; break;
2941 case 24: Rate = RATE_12; num++; break;
2942 case 36: Rate = RATE_18; num++; break;
2943 case 48: Rate = RATE_24; num++; break;
2944 case 72: Rate = RATE_36; num++; break;
2945 case 96: Rate = RATE_48; num++; break;
2946 case 108: Rate = RATE_54; num++; break;
2947 //default: Rate = RATE_1; break;
2948 }
2949 if (MaxDesire < Rate) MaxDesire = Rate;
2950 }
2951
2952//===========================================================================
2953//===========================================================================
2954
2955#ifdef CONFIG_STA_SUPPORT
2956 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2957 {
2958 pHtPhy = &pAd->StaCfg.HTPhyMode;
2959 pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
2960 pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
2961
2962 auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
2963 HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
2964
2965 if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
2966 (pAd->CommonCfg.PhyMode == PHY_11B) &&
2967 (MaxDesire > RATE_11))
2968 {
2969 MaxDesire = RATE_11;
2970 }
2971 }
2972#endif // CONFIG_STA_SUPPORT //
2973
2974 pAd->CommonCfg.MaxDesiredRate = MaxDesire;
2975 pMinHtPhy->word = 0;
2976 pMaxHtPhy->word = 0;
2977 pHtPhy->word = 0;
2978
2979 // Auto rate switching is enabled only if more than one DESIRED RATES are
2980 // specified; otherwise disabled
2981 if (num <= 1)
2982 {
2983 *auto_rate_cur_p = FALSE;
2984 }
2985 else
2986 {
2987 *auto_rate_cur_p = TRUE;
2988 }
2989
2990#if 1
2991 if (HtMcs != MCS_AUTO)
2992 {
2993 *auto_rate_cur_p = FALSE;
2994 }
2995 else
2996 {
2997 *auto_rate_cur_p = TRUE;
2998 }
2999#endif
3000
3001#ifdef CONFIG_STA_SUPPORT
3002 if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
3003 {
3004 pSupRate = &pAd->StaActive.SupRate[0];
3005 pExtRate = &pAd->StaActive.ExtRate[0];
3006 SupRateLen = pAd->StaActive.SupRateLen;
3007 ExtRateLen = pAd->StaActive.ExtRateLen;
3008 }
3009 else
3010#endif // CONFIG_STA_SUPPORT //
3011 {
3012 pSupRate = &pAd->CommonCfg.SupRate[0];
3013 pExtRate = &pAd->CommonCfg.ExtRate[0];
3014 SupRateLen = pAd->CommonCfg.SupRateLen;
3015 ExtRateLen = pAd->CommonCfg.ExtRateLen;
3016 }
3017
3018 // find max supported rate
3019 for (i=0; i<SupRateLen; i++)
3020 {
3021 switch (pSupRate[i] & 0x7f)
3022 {
3023 case 2: Rate = RATE_1; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
3024 case 4: Rate = RATE_2; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
3025 case 11: Rate = RATE_5_5; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
3026 case 22: Rate = RATE_11; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
3027 case 12: Rate = RATE_6; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
3028 case 18: Rate = RATE_9; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
3029 case 24: Rate = RATE_12; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
3030 case 36: Rate = RATE_18; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
3031 case 48: Rate = RATE_24; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
3032 case 72: Rate = RATE_36; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
3033 case 96: Rate = RATE_48; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
3034 case 108: Rate = RATE_54; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
3035 default: Rate = RATE_1; break;
3036 }
3037 if (MaxSupport < Rate) MaxSupport = Rate;
3038
3039 if (MinSupport > Rate) MinSupport = Rate;
3040 }
3041
3042 for (i=0; i<ExtRateLen; i++)
3043 {
3044 switch (pExtRate[i] & 0x7f)
3045 {
3046 case 2: Rate = RATE_1; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
3047 case 4: Rate = RATE_2; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
3048 case 11: Rate = RATE_5_5; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
3049 case 22: Rate = RATE_11; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
3050 case 12: Rate = RATE_6; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
3051 case 18: Rate = RATE_9; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
3052 case 24: Rate = RATE_12; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
3053 case 36: Rate = RATE_18; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
3054 case 48: Rate = RATE_24; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
3055 case 72: Rate = RATE_36; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
3056 case 96: Rate = RATE_48; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
3057 case 108: Rate = RATE_54; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
3058 default: Rate = RATE_1; break;
3059 }
3060 if (MaxSupport < Rate) MaxSupport = Rate;
3061
3062 if (MinSupport > Rate) MinSupport = Rate;
3063 }
3064
3065 RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
3066
3067 // calculate the exptected ACK rate for each TX rate. This info is used to caculate
3068 // the DURATION field of outgoing uniicast DATA/MGMT frame
3069 for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
3070 {
3071 if (BasicRateBitmap & (0x01 << i))
3072 CurrBasicRate = (UCHAR)i;
3073 pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
3074 }
3075
3076 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
3077 // max tx rate = min {max desire rate, max supported rate}
3078 if (MaxSupport < MaxDesire)
3079 pAd->CommonCfg.MaxTxRate = MaxSupport;
3080 else
3081 pAd->CommonCfg.MaxTxRate = MaxDesire;
3082
3083 pAd->CommonCfg.MinTxRate = MinSupport;
3084 if (*auto_rate_cur_p)
3085 {
3086 short dbm = 0;
3087#ifdef CONFIG_STA_SUPPORT
3088 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3089 dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
3090#endif // CONFIG_STA_SUPPORT //
3091 if (bLinkUp == TRUE)
3092 pAd->CommonCfg.TxRate = RATE_24;
3093 else
3094 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3095
3096 if (dbm < -75)
3097 pAd->CommonCfg.TxRate = RATE_11;
3098 else if (dbm < -70)
3099 pAd->CommonCfg.TxRate = RATE_24;
3100
3101 // should never exceed MaxTxRate (consider 11B-only mode)
3102 if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
3103 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3104
3105 pAd->CommonCfg.TxRateIndex = 0;
3106 }
3107 else
3108 {
3109 pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
3110 pHtPhy->field.MCS = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
3111 pHtPhy->field.MODE = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
3112
3113 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC = pHtPhy->field.STBC;
3114 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI;
3115 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS = pHtPhy->field.MCS;
3116 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE = pHtPhy->field.MODE;
3117 }
3118
3119 if (pAd->CommonCfg.TxRate <= RATE_11)
3120 {
3121 pMaxHtPhy->field.MODE = MODE_CCK;
3122 pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
3123 pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
3124 }
3125 else
3126 {
3127 pMaxHtPhy->field.MODE = MODE_OFDM;
3128 pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
3129 if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
3130 {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
3131 else
3132 {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
3133 }
3134
3135 pHtPhy->word = (pMaxHtPhy->word);
3136 if (bLinkUp && (pAd->OpMode == OPMODE_STA))
3137 {
3138 pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
3139 pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
3140 pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
3141 }
3142 else
3143 {
3144 switch (pAd->CommonCfg.PhyMode)
3145 {
3146 case PHY_11BG_MIXED:
3147 case PHY_11B:
3148#ifdef DOT11_N_SUPPORT
3149 case PHY_11BGN_MIXED:
3150#endif // DOT11_N_SUPPORT //
3151 pAd->CommonCfg.MlmeRate = RATE_1;
3152 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3153 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3154 pAd->CommonCfg.RtsRate = RATE_11;
3155 break;
3156 case PHY_11G:
3157 case PHY_11A:
3158#ifdef DOT11_N_SUPPORT
3159 case PHY_11AGN_MIXED:
3160 case PHY_11GN_MIXED:
3161 case PHY_11N_2_4G:
3162 case PHY_11AN_MIXED:
3163 case PHY_11N_5G:
3164#endif // DOT11_N_SUPPORT //
3165 pAd->CommonCfg.MlmeRate = RATE_6;
3166 pAd->CommonCfg.RtsRate = RATE_6;
3167 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3168 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3169 break;
3170 case PHY_11ABG_MIXED:
3171#ifdef DOT11_N_SUPPORT
3172 case PHY_11ABGN_MIXED:
3173#endif // DOT11_N_SUPPORT //
3174 if (pAd->CommonCfg.Channel <= 14)
3175 {
3176 pAd->CommonCfg.MlmeRate = RATE_1;
3177 pAd->CommonCfg.RtsRate = RATE_1;
3178 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
3179 pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
3180 }
3181 else
3182 {
3183 pAd->CommonCfg.MlmeRate = RATE_6;
3184 pAd->CommonCfg.RtsRate = RATE_6;
3185 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3186 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3187 }
3188 break;
3189 default: // error
3190 pAd->CommonCfg.MlmeRate = RATE_6;
3191 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3192 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
3193 pAd->CommonCfg.RtsRate = RATE_1;
3194 break;
3195 }
3196 //
3197 // Keep Basic Mlme Rate.
3198 //
3199 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
3200 if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
3201 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
3202 else
3203 pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
3204 pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
3205 }
3206
3207 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
3208 RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
3209 /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
3210 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
3211 RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
3212 DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
3213 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 ));
3214}
3215
3216#ifdef DOT11_N_SUPPORT
3217/*
3218 ==========================================================================
3219 Description:
3220 This function update HT Rate setting.
3221 Input Wcid value is valid for 2 case :
3222 1. it's used for Station in infra mode that copy AP rate to Mactable.
3223 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
3224
3225 IRQL = DISPATCH_LEVEL
3226
3227 ==========================================================================
3228 */
3229VOID MlmeUpdateHtTxRates(
3230 IN PRTMP_ADAPTER pAd,
3231 IN UCHAR apidx)
3232{
3233 UCHAR StbcMcs; //j, StbcMcs, bitmask;
3234 CHAR i; // 3*3
3235 RT_HT_CAPABILITY *pRtHtCap = NULL;
3236 RT_HT_PHY_INFO *pActiveHtPhy = NULL;
3237 ULONG BasicMCS;
3238 UCHAR j, bitmask;
3239 PRT_HT_PHY_INFO pDesireHtPhy = NULL;
3240 PHTTRANSMIT_SETTING pHtPhy = NULL;
3241 PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
3242 PHTTRANSMIT_SETTING pMinHtPhy = NULL;
3243 BOOLEAN *auto_rate_cur_p;
3244
3245 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
3246
3247 auto_rate_cur_p = NULL;
3248
3249#ifdef CONFIG_STA_SUPPORT
3250 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3251 {
3252 pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
3253 pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
3254 pHtPhy = &pAd->StaCfg.HTPhyMode;
3255 pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
3256 pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
3257
3258 auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
3259 }
3260#endif // CONFIG_STA_SUPPORT //
3261
3262#ifdef CONFIG_STA_SUPPORT
3263 if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
3264 {
3265 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
3266 return;
3267
3268 pRtHtCap = &pAd->StaActive.SupportedHtPhy;
3269 pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
3270 StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
3271 BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
3272 if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
3273 pMaxHtPhy->field.STBC = STBC_USE;
3274 else
3275 pMaxHtPhy->field.STBC = STBC_NONE;
3276 }
3277 else
3278#endif // CONFIG_STA_SUPPORT //
3279 {
3280 if (pDesireHtPhy->bHtEnable == FALSE)
3281 return;
3282
3283 pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
3284 StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
3285 BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
3286 if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
3287 pMaxHtPhy->field.STBC = STBC_USE;
3288 else
3289 pMaxHtPhy->field.STBC = STBC_NONE;
3290 }
3291
3292 // Decide MAX ht rate.
3293 if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
3294 pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
3295 else
3296 pMaxHtPhy->field.MODE = MODE_HTMIX;
3297
3298 if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
3299 pMaxHtPhy->field.BW = BW_40;
3300 else
3301 pMaxHtPhy->field.BW = BW_20;
3302
3303 if (pMaxHtPhy->field.BW == BW_20)
3304 pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
3305 else
3306 pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
3307
3308 for (i=23; i>=0; i--) // 3*3
3309 {
3310 j = i/8;
3311 bitmask = (1<<(i-(j*8)));
3312
3313 if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
3314 {
3315 pMaxHtPhy->field.MCS = i;
3316 break;
3317 }
3318
3319 if (i==0)
3320 break;
3321 }
3322
3323 // Copy MIN ht rate. rt2860???
3324 pMinHtPhy->field.BW = BW_20;
3325 pMinHtPhy->field.MCS = 0;
3326 pMinHtPhy->field.STBC = 0;
3327 pMinHtPhy->field.ShortGI = 0;
3328 //If STA assigns fixed rate. update to fixed here.
3329#ifdef CONFIG_STA_SUPPORT
3330 if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
3331 {
3332 if (pDesireHtPhy->MCSSet[4] != 0)
3333 {
3334 pMaxHtPhy->field.MCS = 32;
3335 pMinHtPhy->field.MCS = 32;
3336 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
3337 }
3338
3339 for (i=23; (CHAR)i >= 0; i--) // 3*3
3340 {
3341 j = i/8;
3342 bitmask = (1<<(i-(j*8)));
3343 if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
3344 {
3345 pMaxHtPhy->field.MCS = i;
3346 pMinHtPhy->field.MCS = i;
3347 break;
3348 }
3349 if (i==0)
3350 break;
3351 }
3352 }
3353#endif // CONFIG_STA_SUPPORT //
3354
3355
3356 // Decide ht rate
3357 pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
3358 pHtPhy->field.BW = pMaxHtPhy->field.BW;
3359 pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
3360 pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
3361 pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
3362
3363 // use default now. rt2860
3364 if (pDesireHtPhy->MCSSet[0] != 0xff)
3365 *auto_rate_cur_p = FALSE;
3366 else
3367 *auto_rate_cur_p = TRUE;
3368
3369 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
3370 DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
3371 pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
3372 DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
3373}
3374#endif // DOT11_N_SUPPORT //
3375
3376// IRQL = DISPATCH_LEVEL
3377VOID MlmeRadioOff(
3378 IN PRTMP_ADAPTER pAd)
3379{
3380 RT28XX_MLME_RADIO_OFF(pAd);
3381}
3382
3383// IRQL = DISPATCH_LEVEL
3384VOID MlmeRadioOn(
3385 IN PRTMP_ADAPTER pAd)
3386{
3387 RT28XX_MLME_RADIO_ON(pAd);
3388}
3389
3390// ===========================================================================================
3391// bss_table.c
3392// ===========================================================================================
3393
3394
3395/*! \brief initialize BSS table
3396 * \param p_tab pointer to the table
3397 * \return none
3398 * \pre
3399 * \post
3400
3401 IRQL = PASSIVE_LEVEL
3402 IRQL = DISPATCH_LEVEL
3403
3404 */
3405VOID BssTableInit(
3406 IN BSS_TABLE *Tab)
3407{
3408 int i;
3409
3410 Tab->BssNr = 0;
3411 Tab->BssOverlapNr = 0;
3412 for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
3413 {
3414 NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
3415 Tab->BssEntry[i].Rssi = -127; // initial the rssi as a minimum value
3416 }
3417}
3418
3419#ifdef DOT11_N_SUPPORT
3420VOID BATableInit(
3421 IN PRTMP_ADAPTER pAd,
3422 IN BA_TABLE *Tab)
3423{
3424 int i;
3425
3426 Tab->numAsOriginator = 0;
3427 Tab->numAsRecipient = 0;
3428 NdisAllocateSpinLock(&pAd->BATabLock);
3429 for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
3430 {
3431 Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
3432 NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
3433 }
3434 for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
3435 {
3436 Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
3437 }
3438}
3439#endif // DOT11_N_SUPPORT //
3440
3441/*! \brief search the BSS table by SSID
3442 * \param p_tab pointer to the bss table
3443 * \param ssid SSID string
3444 * \return index of the table, BSS_NOT_FOUND if not in the table
3445 * \pre
3446 * \post
3447 * \note search by sequential search
3448
3449 IRQL = DISPATCH_LEVEL
3450
3451 */
3452ULONG BssTableSearch(
3453 IN BSS_TABLE *Tab,
3454 IN PUCHAR pBssid,
3455 IN UCHAR Channel)
3456{
3457 UCHAR i;
3458
3459 for (i = 0; i < Tab->BssNr; i++)
3460 {
3461 //
3462 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3463 // We should distinguish this case.
3464 //
3465 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3466 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3467 MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
3468 {
3469 return i;
3470 }
3471 }
3472 return (ULONG)BSS_NOT_FOUND;
3473}
3474
3475ULONG BssSsidTableSearch(
3476 IN BSS_TABLE *Tab,
3477 IN PUCHAR pBssid,
3478 IN PUCHAR pSsid,
3479 IN UCHAR SsidLen,
3480 IN UCHAR Channel)
3481{
3482 UCHAR i;
3483
3484 for (i = 0; i < Tab->BssNr; i++)
3485 {
3486 //
3487 // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
3488 // We should distinguish this case.
3489 //
3490 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3491 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3492 MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
3493 SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
3494 {
3495 return i;
3496 }
3497 }
3498 return (ULONG)BSS_NOT_FOUND;
3499}
3500
3501ULONG BssTableSearchWithSSID(
3502 IN BSS_TABLE *Tab,
3503 IN PUCHAR Bssid,
3504 IN PUCHAR pSsid,
3505 IN UCHAR SsidLen,
3506 IN UCHAR Channel)
3507{
3508 UCHAR i;
3509
3510 for (i = 0; i < Tab->BssNr; i++)
3511 {
3512 if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
3513 ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
3514 MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
3515 (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
3516 (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
3517 (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
3518 {
3519 return i;
3520 }
3521 }
3522 return (ULONG)BSS_NOT_FOUND;
3523}
3524
3525// IRQL = DISPATCH_LEVEL
3526VOID BssTableDeleteEntry(
3527 IN OUT BSS_TABLE *Tab,
3528 IN PUCHAR pBssid,
3529 IN UCHAR Channel)
3530{
3531 UCHAR i, j;
3532
3533 for (i = 0; i < Tab->BssNr; i++)
3534 {
3535 if ((Tab->BssEntry[i].Channel == Channel) &&
3536 (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
3537 {
3538 for (j = i; j < Tab->BssNr - 1; j++)
3539 {
3540 NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
3541 }
3542 NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
3543 Tab->BssNr -= 1;
3544 return;
3545 }
3546 }
3547}
3548
3549#ifdef DOT11_N_SUPPORT
3550/*
3551 ========================================================================
3552 Routine Description:
3553 Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
3554
3555 Arguments:
3556 // IRQL = DISPATCH_LEVEL
3557 ========================================================================
3558*/
3559VOID BATableDeleteORIEntry(
3560 IN OUT PRTMP_ADAPTER pAd,
3561 IN BA_ORI_ENTRY *pBAORIEntry)
3562{
3563
3564 if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
3565 {
3566 NdisAcquireSpinLock(&pAd->BATabLock);
3567 if (pBAORIEntry->ORI_BA_Status == Originator_Done)
3568 {
3569 pAd->BATable.numAsOriginator -= 1;
3570 DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
3571 // Erase Bitmap flag.
3572 }
3573 pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) )); // If STA mode, erase flag here
3574 pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0; // If STA mode, erase flag here
3575 pBAORIEntry->ORI_BA_Status = Originator_NONE;
3576 pBAORIEntry->Token = 1;
3577 // Not clear Sequence here.
3578 NdisReleaseSpinLock(&pAd->BATabLock);
3579 }
3580}
3581#endif // DOT11_N_SUPPORT //
3582
3583/*! \brief
3584 * \param
3585 * \return
3586 * \pre
3587 * \post
3588
3589 IRQL = DISPATCH_LEVEL
3590
3591 */
3592VOID BssEntrySet(
3593 IN PRTMP_ADAPTER pAd,
3594 OUT BSS_ENTRY *pBss,
3595 IN PUCHAR pBssid,
3596 IN CHAR Ssid[],
3597 IN UCHAR SsidLen,
3598 IN UCHAR BssType,
3599 IN USHORT BeaconPeriod,
3600 IN PCF_PARM pCfParm,
3601 IN USHORT AtimWin,
3602 IN USHORT CapabilityInfo,
3603 IN UCHAR SupRate[],
3604 IN UCHAR SupRateLen,
3605 IN UCHAR ExtRate[],
3606 IN UCHAR ExtRateLen,
3607 IN HT_CAPABILITY_IE *pHtCapability,
3608 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
3609 IN UCHAR HtCapabilityLen,
3610 IN UCHAR AddHtInfoLen,
3611 IN UCHAR NewExtChanOffset,
3612 IN UCHAR Channel,
3613 IN CHAR Rssi,
3614 IN LARGE_INTEGER TimeStamp,
3615 IN UCHAR CkipFlag,
3616 IN PEDCA_PARM pEdcaParm,
3617 IN PQOS_CAPABILITY_PARM pQosCapability,
3618 IN PQBSS_LOAD_PARM pQbssLoad,
3619 IN USHORT LengthVIE,
3620 IN PNDIS_802_11_VARIABLE_IEs pVIE)
3621{
3622 COPY_MAC_ADDR(pBss->Bssid, pBssid);
3623 // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
3624 pBss->Hidden = 1;
3625 if (SsidLen > 0)
3626 {
3627 // For hidden SSID AP, it might send beacon with SSID len equal to 0
3628 // Or send beacon /probe response with SSID len matching real SSID length,
3629 // but SSID is all zero. such as "00-00-00-00" with length 4.
3630 // We have to prevent this case overwrite correct table
3631 if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
3632 {
3633 NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
3634 NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
3635 pBss->SsidLen = SsidLen;
3636 pBss->Hidden = 0;
3637 }
3638 }
3639 else
3640 pBss->SsidLen = 0;
3641 pBss->BssType = BssType;
3642 pBss->BeaconPeriod = BeaconPeriod;
3643 if (BssType == BSS_INFRA)
3644 {
3645 if (pCfParm->bValid)
3646 {
3647 pBss->CfpCount = pCfParm->CfpCount;
3648 pBss->CfpPeriod = pCfParm->CfpPeriod;
3649 pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
3650 pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
3651 }
3652 }
3653 else
3654 {
3655 pBss->AtimWin = AtimWin;
3656 }
3657
3658 pBss->CapabilityInfo = CapabilityInfo;
3659 // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
3660 // Combine with AuthMode, they will decide the connection methods.
3661 pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
3662 ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3663 if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
3664 NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
3665 else
3666 NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
3667 pBss->SupRateLen = SupRateLen;
3668 ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
3669 NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
3670 NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
3671 NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
3672 pBss->NewExtChanOffset = NewExtChanOffset;
3673 pBss->ExtRateLen = ExtRateLen;
3674 pBss->Channel = Channel;
3675 pBss->CentralChannel = Channel;
3676 pBss->Rssi = Rssi;
3677 // Update CkipFlag. if not exists, the value is 0x0
3678 pBss->CkipFlag = CkipFlag;
3679
3680 // New for microsoft Fixed IEs
3681 NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
3682 pBss->FixIEs.BeaconInterval = BeaconPeriod;
3683 pBss->FixIEs.Capabilities = CapabilityInfo;
3684
3685 // New for microsoft Variable IEs
3686 if (LengthVIE != 0)
3687 {
3688 pBss->VarIELen = LengthVIE;
3689 NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
3690 }
3691 else
3692 {
3693 pBss->VarIELen = 0;
3694 }
3695
3696 pBss->AddHtInfoLen = 0;
3697 pBss->HtCapabilityLen = 0;
3698#ifdef DOT11_N_SUPPORT
3699 if (HtCapabilityLen> 0)
3700 {
3701 pBss->HtCapabilityLen = HtCapabilityLen;
3702 NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
3703 if (AddHtInfoLen > 0)
3704 {
3705 pBss->AddHtInfoLen = AddHtInfoLen;
3706 NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
3707
3708 if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3709 {
3710 pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
3711 }
3712 else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
3713 {
3714 pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
3715 }
3716 }
3717 }
3718#endif // DOT11_N_SUPPORT //
3719
3720 BssCipherParse(pBss);
3721
3722 // new for QOS
3723 if (pEdcaParm)
3724 NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
3725 else
3726 pBss->EdcaParm.bValid = FALSE;
3727 if (pQosCapability)
3728 NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
3729 else
3730 pBss->QosCapability.bValid = FALSE;
3731 if (pQbssLoad)
3732 NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
3733 else
3734 pBss->QbssLoad.bValid = FALSE;
3735
3736#ifdef CONFIG_STA_SUPPORT
3737 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3738 {
3739 PEID_STRUCT pEid;
3740 USHORT Length = 0;
3741
3742
3743 NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
3744 NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
3745#ifdef EXT_BUILD_CHANNEL_LIST
3746 NdisZeroMemory(&pBss->CountryString[0], 3);
3747 pBss->bHasCountryIE = FALSE;
3748#endif // EXT_BUILD_CHANNEL_LIST //
3749 pEid = (PEID_STRUCT) pVIE;
3750 while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
3751 {
3752 switch(pEid->Eid)
3753 {
3754 case IE_WPA:
3755 if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
3756 {
3757 if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
3758 {
3759 pBss->WpaIE.IELen = 0;
3760 break;
3761 }
3762 pBss->WpaIE.IELen = pEid->Len + 2;
3763 NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
3764 }
3765 break;
3766 case IE_RSN:
3767 if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
3768 {
3769 if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
3770 {
3771 pBss->RsnIE.IELen = 0;
3772 break;
3773 }
3774 pBss->RsnIE.IELen = pEid->Len + 2;
3775 NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
3776 }
3777 break;
3778#ifdef EXT_BUILD_CHANNEL_LIST
3779 case IE_COUNTRY:
3780 NdisMoveMemory(&pBss->CountryString[0], pEid->Octet, 3);
3781 pBss->bHasCountryIE = TRUE;
3782 break;
3783#endif // EXT_BUILD_CHANNEL_LIST //
3784 }
3785 Length = Length + 2 + (USHORT)pEid->Len; // Eid[1] + Len[1]+ content[Len]
3786 pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
3787 }
3788 }
3789#endif // CONFIG_STA_SUPPORT //
3790}
3791
3792/*!
3793 * \brief insert an entry into the bss table
3794 * \param p_tab The BSS table
3795 * \param Bssid BSSID
3796 * \param ssid SSID
3797 * \param ssid_len Length of SSID
3798 * \param bss_type
3799 * \param beacon_period
3800 * \param timestamp
3801 * \param p_cf
3802 * \param atim_win
3803 * \param cap
3804 * \param rates
3805 * \param rates_len
3806 * \param channel_idx
3807 * \return none
3808 * \pre
3809 * \post
3810 * \note If SSID is identical, the old entry will be replaced by the new one
3811
3812 IRQL = DISPATCH_LEVEL
3813
3814 */
3815ULONG BssTableSetEntry(
3816 IN PRTMP_ADAPTER pAd,
3817 OUT BSS_TABLE *Tab,
3818 IN PUCHAR pBssid,
3819 IN CHAR Ssid[],
3820 IN UCHAR SsidLen,
3821 IN UCHAR BssType,
3822 IN USHORT BeaconPeriod,
3823 IN CF_PARM *CfParm,
3824 IN USHORT AtimWin,
3825 IN USHORT CapabilityInfo,
3826 IN UCHAR SupRate[],
3827 IN UCHAR SupRateLen,
3828 IN UCHAR ExtRate[],
3829 IN UCHAR ExtRateLen,
3830 IN HT_CAPABILITY_IE *pHtCapability,
3831 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
3832 IN UCHAR HtCapabilityLen,
3833 IN UCHAR AddHtInfoLen,
3834 IN UCHAR NewExtChanOffset,
3835 IN UCHAR ChannelNo,
3836 IN CHAR Rssi,
3837 IN LARGE_INTEGER TimeStamp,
3838 IN UCHAR CkipFlag,
3839 IN PEDCA_PARM pEdcaParm,
3840 IN PQOS_CAPABILITY_PARM pQosCapability,
3841 IN PQBSS_LOAD_PARM pQbssLoad,
3842 IN USHORT LengthVIE,
3843 IN PNDIS_802_11_VARIABLE_IEs pVIE)
3844{
3845 ULONG Idx;
3846
3847 Idx = BssTableSearchWithSSID(Tab, pBssid, Ssid, SsidLen, ChannelNo);
3848 if (Idx == BSS_NOT_FOUND)
3849 {
3850 if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
3851 {
3852 //
3853 // It may happen when BSS Table was full.
3854 // The desired AP will not be added into BSS Table
3855 // In this case, if we found the desired AP then overwrite BSS Table.
3856 //
3857 if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
3858 {
3859 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
3860 SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
3861 {
3862 Idx = Tab->BssOverlapNr;
3863 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
3864 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3865 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3866 Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
3867 }
3868 return Idx;
3869 }
3870 else
3871 {
3872 return BSS_NOT_FOUND;
3873 }
3874 }
3875 Idx = Tab->BssNr;
3876 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
3877 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3878 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3879 Tab->BssNr++;
3880 }
3881 else
3882 {
3883 BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
3884 CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
3885 NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
3886 }
3887
3888 return Idx;
3889}
3890
3891#ifdef CONFIG_STA_SUPPORT
3892#ifdef DOT11_N_SUPPORT
3893#ifdef DOT11N_DRAFT3
3894VOID TriEventInit(
3895 IN PRTMP_ADAPTER pAd)
3896{
3897 UCHAR i;
3898
3899 for (i = 0;i < MAX_TRIGGER_EVENT;i++)
3900 pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
3901
3902 pAd->CommonCfg.TriggerEventTab.EventANo = 0;
3903 pAd->CommonCfg.TriggerEventTab.EventBCountDown = 0;
3904}
3905
3906ULONG TriEventTableSetEntry(
3907 IN PRTMP_ADAPTER pAd,
3908 OUT TRIGGER_EVENT_TAB *Tab,
3909 IN PUCHAR pBssid,
3910 IN HT_CAPABILITY_IE *pHtCapability,
3911 IN UCHAR HtCapabilityLen,
3912 IN UCHAR RegClass,
3913 IN UCHAR ChannelNo)
3914{
3915 // Event A
3916 if (HtCapabilityLen == 0)
3917 {
3918 if (Tab->EventANo < MAX_TRIGGER_EVENT)
3919 {
3920 RTMPMoveMemory(Tab->EventA[Tab->EventANo].BSSID, pBssid, 6);
3921 Tab->EventA[Tab->EventANo].bValid = TRUE;
3922 Tab->EventA[Tab->EventANo].Channel = ChannelNo;
3923 Tab->EventA[Tab->EventANo].CDCounter = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
3924 if (RegClass != 0)
3925 {
3926 // Beacon has Regulatory class IE. So use beacon's
3927 Tab->EventA[Tab->EventANo].RegClass = RegClass;
3928 }
3929 else
3930 {
3931 // Use Station's Regulatory class instead.
3932 if (pAd->StaActive.SupportedHtPhy.bHtEnable == TRUE)
3933 {
3934 if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
3935 {
3936 Tab->EventA[Tab->EventANo].RegClass = 32;
3937 }
3938 else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
3939 Tab->EventA[Tab->EventANo].RegClass = 33;
3940 }
3941 else
3942 Tab->EventA[Tab->EventANo].RegClass = ??;
3943
3944 }
3945
3946 Tab->EventANo ++;
3947 }
3948 }
3949 else if (pHtCapability->HtCapInfo.Intolerant40)
3950 {
3951 Tab->EventBCountDown = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
3952 }
3953
3954}
3955
3956/*
3957 ========================================================================
3958 Routine Description:
3959 Trigger Event table Maintainence called once every second.
3960
3961 Arguments:
3962 // IRQL = DISPATCH_LEVEL
3963 ========================================================================
3964*/
3965VOID TriEventCounterMaintenance(
3966 IN PRTMP_ADAPTER pAd)
3967{
3968 UCHAR i;
3969 BOOLEAN bNotify = FALSE;
3970 for (i = 0;i < MAX_TRIGGER_EVENT;i++)
3971 {
3972 if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid && (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter > 0))
3973 {
3974 pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter--;
3975 if (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter == 0)
3976 {
3977 pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
3978 pAd->CommonCfg.TriggerEventTab.EventANo --;
3979 // Need to send 20/40 Coexistence Notify frame if has status change.
3980 bNotify = TRUE;
3981 }
3982 }
3983 }
3984 if (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0)
3985 {
3986 pAd->CommonCfg.TriggerEventTab.EventBCountDown--;
3987 if (pAd->CommonCfg.TriggerEventTab.EventBCountDown == 0)
3988 bNotify = TRUE;
3989 }
3990
3991 if (bNotify == TRUE)
3992 Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
3993}
3994#endif // DOT11N_DRAFT3 //
3995#endif // DOT11_N_SUPPORT //
3996
3997// IRQL = DISPATCH_LEVEL
3998VOID BssTableSsidSort(
3999 IN PRTMP_ADAPTER pAd,
4000 OUT BSS_TABLE *OutTab,
4001 IN CHAR Ssid[],
4002 IN UCHAR SsidLen)
4003{
4004 INT i;
4005 BssTableInit(OutTab);
4006
4007 for (i = 0; i < pAd->ScanTab.BssNr; i++)
4008 {
4009 BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
4010 BOOLEAN bIsHiddenApIncluded = FALSE;
4011
4012 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
4013 (pAd->MlmeAux.Channel > 14) &&
4014 RadarChannelCheck(pAd, pInBss->Channel))
4015#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
4016 || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
4017#endif // CARRIER_DETECTION_SUPPORT //
4018 )
4019 {
4020 if (pInBss->Hidden)
4021 bIsHiddenApIncluded = TRUE;
4022 }
4023
4024 if ((pInBss->BssType == pAd->StaCfg.BssType) &&
4025 (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
4026 {
4027 BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
4028
4029
4030#ifdef EXT_BUILD_CHANNEL_LIST
4031 // If no Country IE exists no Connection will be established when IEEE80211dClientMode is strict.
4032 if ((pAd->StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict) &&
4033 (pInBss->bHasCountryIE == FALSE))
4034 {
4035 DBGPRINT(RT_DEBUG_TRACE,("StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict, but this AP doesn't have country IE.\n"));
4036 continue;
4037 }
4038#endif // EXT_BUILD_CHANNEL_LIST //
4039
4040#ifdef DOT11_N_SUPPORT
4041 // 2.4G/5G N only mode
4042 if ((pInBss->HtCapabilityLen == 0) &&
4043 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
4044 {
4045 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
4046 continue;
4047 }
4048#endif // DOT11_N_SUPPORT //
4049
4050 // New for WPA2
4051 // Check the Authmode first
4052 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
4053 {
4054 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
4055 if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
4056 // None matched
4057 continue;
4058
4059 // Check cipher suite, AP must have more secured cipher than station setting
4060 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
4061 {
4062 // If it's not mixed mode, we should only let BSS pass with the same encryption
4063 if (pInBss->WPA.bMixMode == FALSE)
4064 if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
4065 continue;
4066
4067 // check group cipher
4068 if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
4069 continue;
4070
4071 // check pairwise cipher, skip if none matched
4072 // If profile set to AES, let it pass without question.
4073 // If profile set to TKIP, we must find one mateched
4074 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4075 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
4076 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
4077 continue;
4078 }
4079 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
4080 {
4081 // If it's not mixed mode, we should only let BSS pass with the same encryption
4082 if (pInBss->WPA2.bMixMode == FALSE)
4083 if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
4084 continue;
4085
4086 // check group cipher
4087 if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
4088 continue;
4089
4090 // check pairwise cipher, skip if none matched
4091 // If profile set to AES, let it pass without question.
4092 // If profile set to TKIP, we must find one mateched
4093 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4094 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
4095 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
4096 continue;
4097 }
4098 }
4099 // Bss Type matched, SSID matched.
4100 // We will check wepstatus for qualification Bss
4101 else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
4102 {
4103 DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
4104 //
4105 // For the SESv2 case, we will not qualify WepStatus.
4106 //
4107 if (!pInBss->bSES)
4108 continue;
4109 }
4110
4111 // Since the AP is using hidden SSID, and we are trying to connect to ANY
4112 // It definitely will fail. So, skip it.
4113 // CCX also require not even try to connect it!!
4114 if (SsidLen == 0)
4115 continue;
4116
4117#ifdef DOT11_N_SUPPORT
4118 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
4119 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
4120 if ((pInBss->CentralChannel != pInBss->Channel) &&
4121 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
4122 {
4123 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
4124 {
4125 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
4126 SetCommonHT(pAd);
4127 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
4128 }
4129 else
4130 {
4131 if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
4132 {
4133 SetCommonHT(pAd);
4134 }
4135 }
4136 }
4137#endif // DOT11_N_SUPPORT //
4138
4139 // copy matching BSS from InTab to OutTab
4140 NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
4141
4142 OutTab->BssNr++;
4143 }
4144 else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
4145 {
4146 BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
4147
4148
4149#ifdef DOT11_N_SUPPORT
4150 // 2.4G/5G N only mode
4151 if ((pInBss->HtCapabilityLen == 0) &&
4152 ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
4153 {
4154 DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
4155 continue;
4156 }
4157#endif // DOT11_N_SUPPORT //
4158
4159 // New for WPA2
4160 // Check the Authmode first
4161 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
4162 {
4163 // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
4164 if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
4165 // None matched
4166 continue;
4167
4168 // Check cipher suite, AP must have more secured cipher than station setting
4169 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
4170 {
4171 // If it's not mixed mode, we should only let BSS pass with the same encryption
4172 if (pInBss->WPA.bMixMode == FALSE)
4173 if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
4174 continue;
4175
4176 // check group cipher
4177 if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
4178 continue;
4179
4180 // check pairwise cipher, skip if none matched
4181 // If profile set to AES, let it pass without question.
4182 // If profile set to TKIP, we must find one mateched
4183 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4184 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
4185 (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
4186 continue;
4187 }
4188 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
4189 {
4190 // If it's not mixed mode, we should only let BSS pass with the same encryption
4191 if (pInBss->WPA2.bMixMode == FALSE)
4192 if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
4193 continue;
4194
4195 // check group cipher
4196 if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
4197 continue;
4198
4199 // check pairwise cipher, skip if none matched
4200 // If profile set to AES, let it pass without question.
4201 // If profile set to TKIP, we must find one mateched
4202 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
4203 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
4204 (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
4205 continue;
4206 }
4207 }
4208 // Bss Type matched, SSID matched.
4209 // We will check wepstatus for qualification Bss
4210 else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
4211 continue;
4212
4213#ifdef DOT11_N_SUPPORT
4214 // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
4215 // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
4216 if ((pInBss->CentralChannel != pInBss->Channel) &&
4217 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
4218 {
4219 if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
4220 {
4221 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
4222 SetCommonHT(pAd);
4223 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
4224 }
4225 }
4226#endif // DOT11_N_SUPPORT //
4227
4228 // copy matching BSS from InTab to OutTab
4229 NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
4230
4231 OutTab->BssNr++;
4232 }
4233
4234 if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
4235 break;
4236 }
4237
4238 BssTableSortByRssi(OutTab);
4239}
4240
4241
4242// IRQL = DISPATCH_LEVEL
4243VOID BssTableSortByRssi(
4244 IN OUT BSS_TABLE *OutTab)
4245{
4246 INT i, j;
4247 BSS_ENTRY TmpBss;
4248
4249 for (i = 0; i < OutTab->BssNr - 1; i++)
4250 {
4251 for (j = i+1; j < OutTab->BssNr; j++)
4252 {
4253 if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
4254 {
4255 NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
4256 NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
4257 NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
4258 }
4259 }
4260 }
4261}
4262#endif // CONFIG_STA_SUPPORT //
4263
4264
4265VOID BssCipherParse(
4266 IN OUT PBSS_ENTRY pBss)
4267{
4268 PEID_STRUCT pEid;
4269 PUCHAR pTmp;
4270 PRSN_IE_HEADER_STRUCT pRsnHeader;
4271 PCIPHER_SUITE_STRUCT pCipher;
4272 PAKM_SUITE_STRUCT pAKM;
4273 USHORT Count;
4274 INT Length;
4275 NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
4276
4277 //
4278 // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
4279 //
4280 if (pBss->Privacy)
4281 {
4282 pBss->WepStatus = Ndis802_11WEPEnabled;
4283 }
4284 else
4285 {
4286 pBss->WepStatus = Ndis802_11WEPDisabled;
4287 }
4288 // Set default to disable & open authentication before parsing variable IE
4289 pBss->AuthMode = Ndis802_11AuthModeOpen;
4290 pBss->AuthModeAux = Ndis802_11AuthModeOpen;
4291
4292 // Init WPA setting
4293 pBss->WPA.PairCipher = Ndis802_11WEPDisabled;
4294 pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
4295 pBss->WPA.GroupCipher = Ndis802_11WEPDisabled;
4296 pBss->WPA.RsnCapability = 0;
4297 pBss->WPA.bMixMode = FALSE;
4298
4299 // Init WPA2 setting
4300 pBss->WPA2.PairCipher = Ndis802_11WEPDisabled;
4301 pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
4302 pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
4303 pBss->WPA2.RsnCapability = 0;
4304 pBss->WPA2.bMixMode = FALSE;
4305
4306
4307 Length = (INT) pBss->VarIELen;
4308
4309 while (Length > 0)
4310 {
4311 // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
4312 pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
4313 pEid = (PEID_STRUCT) pTmp;
4314 switch (pEid->Eid)
4315 {
4316 case IE_WPA:
4317 //Parse Cisco IE_WPA (LEAP, CCKM, etc.)
4318 if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3))
4319 {
4320 pTmp += 11;
4321 switch (*pTmp)
4322 {
4323 case 1:
4324 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4325 pBss->WepStatus = Ndis802_11Encryption1Enabled;
4326 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4327 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4328 break;
4329 case 2:
4330 pBss->WepStatus = Ndis802_11Encryption2Enabled;
4331 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4332 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4333 break;
4334 case 4:
4335 pBss->WepStatus = Ndis802_11Encryption3Enabled;
4336 pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
4337 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
4338 break;
4339 default:
4340 break;
4341 }
4342
4343 // if Cisco IE_WPA, break
4344 break;
4345 }
4346 else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
4347 {
4348 pBss->bSES = TRUE;
4349 break;
4350 }
4351 else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
4352 {
4353 // if unsupported vendor specific IE
4354 break;
4355 }
4356 // Skip OUI, version, and multicast suite
4357 // This part should be improved in the future when AP supported multiple cipher suite.
4358 // For now, it's OK since almost all APs have fixed cipher suite supported.
4359 // pTmp = (PUCHAR) pEid->Octet;
4360 pTmp += 11;
4361
4362 // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
4363 // Value Meaning
4364 // 0 None
4365 // 1 WEP-40
4366 // 2 Tkip
4367 // 3 WRAP
4368 // 4 AES
4369 // 5 WEP-104
4370 // Parse group cipher
4371 switch (*pTmp)
4372 {
4373 case 1:
4374 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4375 pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
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 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4493 pBss->WPA2.GroupCipher = Ndis802_11Encryption1Enabled;
4494 break;
4495 case 2:
4496 pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
4497 break;
4498 case 4:
4499 pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
4500 break;
4501 default:
4502 break;
4503 }
4504 // set to correct offset for next parsing
4505 pTmp += sizeof(CIPHER_SUITE_STRUCT);
4506
4507 // 2. Get pairwise cipher counts
4508 //Count = *(PUSHORT) pTmp;
4509 Count = (pTmp[1]<<8) + pTmp[0];
4510 pTmp += sizeof(USHORT);
4511
4512 // 3. Get pairwise cipher
4513 // Parsing all unicast cipher suite
4514 while (Count > 0)
4515 {
4516 // Skip OUI
4517 pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
4518 TmpCipher = Ndis802_11WEPDisabled;
4519 switch (pCipher->Type)
4520 {
4521 case 1:
4522 case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
4523 TmpCipher = Ndis802_11Encryption1Enabled;
4524 break;
4525 case 2:
4526 TmpCipher = Ndis802_11Encryption2Enabled;
4527 break;
4528 case 4:
4529 TmpCipher = Ndis802_11Encryption3Enabled;
4530 break;
4531 default:
4532 break;
4533 }
4534 if (TmpCipher > pBss->WPA2.PairCipher)
4535 {
4536 // Move the lower cipher suite to PairCipherAux
4537 pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
4538 pBss->WPA2.PairCipher = TmpCipher;
4539 }
4540 else
4541 {
4542 pBss->WPA2.PairCipherAux = TmpCipher;
4543 }
4544 pTmp += sizeof(CIPHER_SUITE_STRUCT);
4545 Count--;
4546 }
4547
4548 // 4. get AKM suite counts
4549 //Count = *(PUSHORT) pTmp;
4550 Count = (pTmp[1]<<8) + pTmp[0];
4551 pTmp += sizeof(USHORT);
4552
4553 // 5. Get AKM ciphers
4554 pAKM = (PAKM_SUITE_STRUCT) pTmp;
4555 if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
4556 break;
4557
4558 switch (pAKM->Type)
4559 {
4560 case 1:
4561 // Set AP support WPA mode
4562 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4563 pBss->AuthMode = Ndis802_11AuthModeWPA2;
4564 else
4565 pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
4566 break;
4567 case 2:
4568 // Set AP support WPA mode
4569 if (pBss->AuthMode == Ndis802_11AuthModeOpen)
4570 pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
4571 else
4572 pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
4573 break;
4574 default:
4575 break;
4576 }
4577 pTmp += (Count * sizeof(AKM_SUITE_STRUCT));
4578
4579 // Fixed for WPA-None
4580 if (pBss->BssType == BSS_ADHOC)
4581 {
4582 pBss->AuthMode = Ndis802_11AuthModeWPANone;
4583 pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
4584 pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
4585 pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
4586 pBss->WepStatus = pBss->WPA.GroupCipher;
4587 // Patched bugs for old driver
4588 if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
4589 pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
4590 }
4591 pBss->WepStatus = pBss->WPA2.PairCipher;
4592
4593 // 6. Get RSN capability
4594 //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
4595 pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
4596 pTmp += sizeof(USHORT);
4597
4598 // Check the Pair & Group, if different, turn on mixed mode flag
4599 if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
4600 pBss->WPA2.bMixMode = TRUE;
4601
4602 break;
4603 default:
4604 break;
4605 }
4606 Length -= (pEid->Len + 2);
4607 }
4608}
4609
4610// ===========================================================================================
4611// mac_table.c
4612// ===========================================================================================
4613
4614/*! \brief generates a random mac address value for IBSS BSSID
4615 * \param Addr the bssid location
4616 * \return none
4617 * \pre
4618 * \post
4619 */
4620VOID MacAddrRandomBssid(
4621 IN PRTMP_ADAPTER pAd,
4622 OUT PUCHAR pAddr)
4623{
4624 INT i;
4625
4626 for (i = 0; i < MAC_ADDR_LEN; i++)
4627 {
4628 pAddr[i] = RandomByte(pAd);
4629 }
4630
4631 pAddr[0] = (pAddr[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx
4632}
4633
4634/*! \brief init the management mac frame header
4635 * \param p_hdr mac header
4636 * \param subtype subtype of the frame
4637 * \param p_ds destination address, don't care if it is a broadcast address
4638 * \return none
4639 * \pre the station has the following information in the pAd->StaCfg
4640 * - bssid
4641 * - station address
4642 * \post
4643 * \note this function initializes the following field
4644
4645 IRQL = PASSIVE_LEVEL
4646 IRQL = DISPATCH_LEVEL
4647
4648 */
4649VOID MgtMacHeaderInit(
4650 IN PRTMP_ADAPTER pAd,
4651 IN OUT PHEADER_802_11 pHdr80211,
4652 IN UCHAR SubType,
4653 IN UCHAR ToDs,
4654 IN PUCHAR pDA,
4655 IN PUCHAR pBssid)
4656{
4657 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
4658
4659 pHdr80211->FC.Type = BTYPE_MGMT;
4660 pHdr80211->FC.SubType = SubType;
4661 pHdr80211->FC.ToDs = ToDs;
4662 COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
4663#ifdef CONFIG_STA_SUPPORT
4664 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4665 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
4666#endif // CONFIG_STA_SUPPORT //
4667 COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
4668}
4669
4670// ===========================================================================================
4671// mem_mgmt.c
4672// ===========================================================================================
4673
4674/*!***************************************************************************
4675 * This routine build an outgoing frame, and fill all information specified
4676 * in argument list to the frame body. The actual frame size is the summation
4677 * of all arguments.
4678 * input params:
4679 * Buffer - pointer to a pre-allocated memory segment
4680 * args - a list of <int arg_size, arg> pairs.
4681 * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
4682 * function will FAIL!!!
4683 * return:
4684 * Size of the buffer
4685 * usage:
4686 * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
4687
4688 IRQL = PASSIVE_LEVEL
4689 IRQL = DISPATCH_LEVEL
4690
4691 ****************************************************************************/
4692ULONG MakeOutgoingFrame(
4693 OUT CHAR *Buffer,
4694 OUT ULONG *FrameLen, ...)
4695{
4696 CHAR *p;
4697 int leng;
4698 ULONG TotLeng;
4699 va_list Args;
4700
4701 // calculates the total length
4702 TotLeng = 0;
4703 va_start(Args, FrameLen);
4704 do
4705 {
4706 leng = va_arg(Args, int);
4707 if (leng == END_OF_ARGS)
4708 {
4709 break;
4710 }
4711 p = va_arg(Args, PVOID);
4712 NdisMoveMemory(&Buffer[TotLeng], p, leng);
4713 TotLeng = TotLeng + leng;
4714 } while(TRUE);
4715
4716 va_end(Args); /* clean up */
4717 *FrameLen = TotLeng;
4718 return TotLeng;
4719}
4720
4721// ===========================================================================================
4722// mlme_queue.c
4723// ===========================================================================================
4724
4725/*! \brief Initialize The MLME Queue, used by MLME Functions
4726 * \param *Queue The MLME Queue
4727 * \return Always Return NDIS_STATE_SUCCESS in this implementation
4728 * \pre
4729 * \post
4730 * \note Because this is done only once (at the init stage), no need to be locked
4731
4732 IRQL = PASSIVE_LEVEL
4733
4734 */
4735NDIS_STATUS MlmeQueueInit(
4736 IN MLME_QUEUE *Queue)
4737{
4738 INT i;
4739
4740 NdisAllocateSpinLock(&Queue->Lock);
4741
4742 Queue->Num = 0;
4743 Queue->Head = 0;
4744 Queue->Tail = 0;
4745
4746 for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
4747 {
4748 Queue->Entry[i].Occupied = FALSE;
4749 Queue->Entry[i].MsgLen = 0;
4750 NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
4751 }
4752
4753 return NDIS_STATUS_SUCCESS;
4754}
4755
4756/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
4757 * \param *Queue The MLME Queue
4758 * \param Machine The State Machine Id
4759 * \param MsgType The Message Type
4760 * \param MsgLen The Message length
4761 * \param *Msg The message pointer
4762 * \return TRUE if enqueue is successful, FALSE if the queue is full
4763 * \pre
4764 * \post
4765 * \note The message has to be initialized
4766
4767 IRQL = PASSIVE_LEVEL
4768 IRQL = DISPATCH_LEVEL
4769
4770 */
4771BOOLEAN MlmeEnqueue(
4772 IN PRTMP_ADAPTER pAd,
4773 IN ULONG Machine,
4774 IN ULONG MsgType,
4775 IN ULONG MsgLen,
4776 IN VOID *Msg)
4777{
4778 INT Tail;
4779 MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
4780
4781 // Do nothing if the driver is starting halt state.
4782 // This might happen when timer already been fired before cancel timer with mlmehalt
4783 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
4784 return FALSE;
4785
4786 // First check the size, it MUST not exceed the mlme queue size
4787 if (MsgLen > MGMT_DMA_BUFFER_SIZE)
4788 {
4789 DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
4790 return FALSE;
4791 }
4792
4793 if (MlmeQueueFull(Queue))
4794 {
4795 return FALSE;
4796 }
4797
4798 NdisAcquireSpinLock(&(Queue->Lock));
4799 Tail = Queue->Tail;
4800 Queue->Tail++;
4801 Queue->Num++;
4802 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
4803 {
4804 Queue->Tail = 0;
4805 }
4806
4807 Queue->Entry[Tail].Wcid = RESERVED_WCID;
4808 Queue->Entry[Tail].Occupied = TRUE;
4809 Queue->Entry[Tail].Machine = Machine;
4810 Queue->Entry[Tail].MsgType = MsgType;
4811 Queue->Entry[Tail].MsgLen = MsgLen;
4812
4813 if (Msg != NULL)
4814 {
4815 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4816 }
4817
4818 NdisReleaseSpinLock(&(Queue->Lock));
4819 return TRUE;
4820}
4821
4822/*! \brief This function is used when Recv gets a MLME message
4823 * \param *Queue The MLME Queue
4824 * \param TimeStampHigh The upper 32 bit of timestamp
4825 * \param TimeStampLow The lower 32 bit of timestamp
4826 * \param Rssi The receiving RSSI strength
4827 * \param MsgLen The length of the message
4828 * \param *Msg The message pointer
4829 * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
4830 * \pre
4831 * \post
4832
4833 IRQL = DISPATCH_LEVEL
4834
4835 */
4836BOOLEAN MlmeEnqueueForRecv(
4837 IN PRTMP_ADAPTER pAd,
4838 IN ULONG Wcid,
4839 IN ULONG TimeStampHigh,
4840 IN ULONG TimeStampLow,
4841 IN UCHAR Rssi0,
4842 IN UCHAR Rssi1,
4843 IN UCHAR Rssi2,
4844 IN ULONG MsgLen,
4845 IN VOID *Msg,
4846 IN UCHAR Signal)
4847{
4848 INT Tail, Machine;
4849 PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
4850 INT MsgType;
4851 MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
4852
4853#ifdef RALINK_ATE
4854 /* Nothing to do in ATE mode */
4855 if(ATE_ON(pAd))
4856 return FALSE;
4857#endif // RALINK_ATE //
4858
4859 // Do nothing if the driver is starting halt state.
4860 // This might happen when timer already been fired before cancel timer with mlmehalt
4861 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
4862 {
4863 DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
4864 return FALSE;
4865 }
4866
4867 // First check the size, it MUST not exceed the mlme queue size
4868 if (MsgLen > MGMT_DMA_BUFFER_SIZE)
4869 {
4870 DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
4871 return FALSE;
4872 }
4873
4874 if (MlmeQueueFull(Queue))
4875 {
4876 return FALSE;
4877 }
4878
4879#ifdef CONFIG_STA_SUPPORT
4880 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4881 {
4882 if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
4883 {
4884 DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
4885 return FALSE;
4886 }
4887 }
4888#endif // CONFIG_STA_SUPPORT //
4889
4890 // OK, we got all the informations, it is time to put things into queue
4891 NdisAcquireSpinLock(&(Queue->Lock));
4892 Tail = Queue->Tail;
4893 Queue->Tail++;
4894 Queue->Num++;
4895 if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
4896 {
4897 Queue->Tail = 0;
4898 }
4899 Queue->Entry[Tail].Occupied = TRUE;
4900 Queue->Entry[Tail].Machine = Machine;
4901 Queue->Entry[Tail].MsgType = MsgType;
4902 Queue->Entry[Tail].MsgLen = MsgLen;
4903 Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
4904 Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
4905 Queue->Entry[Tail].Rssi0 = Rssi0;
4906 Queue->Entry[Tail].Rssi1 = Rssi1;
4907 Queue->Entry[Tail].Rssi2 = Rssi2;
4908 Queue->Entry[Tail].Signal = Signal;
4909 Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
4910
4911 Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
4912
4913 if (Msg != NULL)
4914 {
4915 NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
4916 }
4917
4918 NdisReleaseSpinLock(&(Queue->Lock));
4919
4920 RT28XX_MLME_HANDLER(pAd);
4921
4922 return TRUE;
4923}
4924
4925
4926/*! \brief Dequeue a message from the MLME Queue
4927 * \param *Queue The MLME Queue
4928 * \param *Elem The message dequeued from MLME Queue
4929 * \return TRUE if the Elem contains something, FALSE otherwise
4930 * \pre
4931 * \post
4932
4933 IRQL = DISPATCH_LEVEL
4934
4935 */
4936BOOLEAN MlmeDequeue(
4937 IN MLME_QUEUE *Queue,
4938 OUT MLME_QUEUE_ELEM **Elem)
4939{
4940 NdisAcquireSpinLock(&(Queue->Lock));
4941 *Elem = &(Queue->Entry[Queue->Head]);
4942 Queue->Num--;
4943 Queue->Head++;
4944 if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
4945 {
4946 Queue->Head = 0;
4947 }
4948 NdisReleaseSpinLock(&(Queue->Lock));
4949 return TRUE;
4950}
4951
4952// IRQL = DISPATCH_LEVEL
4953VOID MlmeRestartStateMachine(
4954 IN PRTMP_ADAPTER pAd)
4955{
4956#ifdef RT2860
4957 MLME_QUEUE_ELEM *Elem = NULL;
4958#endif // RT2860 //
4959#ifdef CONFIG_STA_SUPPORT
4960 BOOLEAN Cancelled;
4961#endif // CONFIG_STA_SUPPORT //
4962
4963 DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
4964
4965#ifdef RT2860
4966 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
4967 if(pAd->Mlme.bRunning)
4968 {
4969 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
4970 return;
4971 }
4972 else
4973 {
4974 pAd->Mlme.bRunning = TRUE;
4975 }
4976 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
4977
4978 // Remove all Mlme queues elements
4979 while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
4980 {
4981 //From message type, determine which state machine I should drive
4982 if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
4983 {
4984 // free MLME element
4985 Elem->Occupied = FALSE;
4986 Elem->MsgLen = 0;
4987
4988 }
4989 else {
4990 DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
4991 }
4992 }
4993#endif // RT2860 //
4994
4995#ifdef CONFIG_STA_SUPPORT
4996 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
4997 {
4998#ifdef QOS_DLS_SUPPORT
4999 UCHAR i;
5000#endif // QOS_DLS_SUPPORT //
5001 // Cancel all timer events
5002 // Be careful to cancel new added timer
5003 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
5004 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
5005 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
5006 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
5007 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
5008 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
5009
5010#ifdef QOS_DLS_SUPPORT
5011 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
5012 {
5013 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
5014 }
5015#endif // QOS_DLS_SUPPORT //
5016 }
5017#endif // CONFIG_STA_SUPPORT //
5018
5019 // Change back to original channel in case of doing scan
5020 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
5021 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
5022
5023 // Resume MSDU which is turned off durning scan
5024 RTMPResumeMsduTransmission(pAd);
5025
5026#ifdef CONFIG_STA_SUPPORT
5027 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
5028 {
5029 // Set all state machines back IDLE
5030 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
5031 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
5032 pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
5033 pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
5034 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
5035 pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
5036#ifdef QOS_DLS_SUPPORT
5037 pAd->Mlme.DlsMachine.CurrState = DLS_IDLE;
5038#endif // QOS_DLS_SUPPORT //
5039 }
5040#endif // CONFIG_STA_SUPPORT //
5041
5042#ifdef RT2860
5043 // Remove running state
5044 NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
5045 pAd->Mlme.bRunning = FALSE;
5046 NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
5047#endif // RT2860 //
5048}
5049
5050/*! \brief test if the MLME Queue is empty
5051 * \param *Queue The MLME Queue
5052 * \return TRUE if the Queue is empty, FALSE otherwise
5053 * \pre
5054 * \post
5055
5056 IRQL = DISPATCH_LEVEL
5057
5058 */
5059BOOLEAN MlmeQueueEmpty(
5060 IN MLME_QUEUE *Queue)
5061{
5062 BOOLEAN Ans;
5063
5064 NdisAcquireSpinLock(&(Queue->Lock));
5065 Ans = (Queue->Num == 0);
5066 NdisReleaseSpinLock(&(Queue->Lock));
5067
5068 return Ans;
5069}
5070
5071/*! \brief test if the MLME Queue is full
5072 * \param *Queue The MLME Queue
5073 * \return TRUE if the Queue is empty, FALSE otherwise
5074 * \pre
5075 * \post
5076
5077 IRQL = PASSIVE_LEVEL
5078 IRQL = DISPATCH_LEVEL
5079
5080 */
5081BOOLEAN MlmeQueueFull(
5082 IN MLME_QUEUE *Queue)
5083{
5084 BOOLEAN Ans;
5085
5086 NdisAcquireSpinLock(&(Queue->Lock));
5087 Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
5088 NdisReleaseSpinLock(&(Queue->Lock));
5089
5090 return Ans;
5091}
5092
5093/*! \brief The destructor of MLME Queue
5094 * \param
5095 * \return
5096 * \pre
5097 * \post
5098 * \note Clear Mlme Queue, Set Queue->Num to Zero.
5099
5100 IRQL = PASSIVE_LEVEL
5101
5102 */
5103VOID MlmeQueueDestroy(
5104 IN MLME_QUEUE *pQueue)
5105{
5106 NdisAcquireSpinLock(&(pQueue->Lock));
5107 pQueue->Num = 0;
5108 pQueue->Head = 0;
5109 pQueue->Tail = 0;
5110 NdisReleaseSpinLock(&(pQueue->Lock));
5111 NdisFreeSpinLock(&(pQueue->Lock));
5112}
5113
5114/*! \brief To substitute the message type if the message is coming from external
5115 * \param pFrame The frame received
5116 * \param *Machine The state machine
5117 * \param *MsgType the message type for the state machine
5118 * \return TRUE if the substitution is successful, FALSE otherwise
5119 * \pre
5120 * \post
5121
5122 IRQL = DISPATCH_LEVEL
5123
5124 */
5125#ifdef CONFIG_STA_SUPPORT
5126BOOLEAN MsgTypeSubst(
5127 IN PRTMP_ADAPTER pAd,
5128 IN PFRAME_802_11 pFrame,
5129 OUT INT *Machine,
5130 OUT INT *MsgType)
5131{
5132 USHORT Seq;
5133 UCHAR EAPType;
5134 PUCHAR pData;
5135
5136 // Pointer to start of data frames including SNAP header
5137 pData = (PUCHAR) pFrame + LENGTH_802_11;
5138
5139 // The only data type will pass to this function is EAPOL frame
5140 if (pFrame->Hdr.FC.Type == BTYPE_DATA)
5141 {
5142 if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H))
5143 {
5144 // Cisco Aironet SNAP header
5145 *Machine = AIRONET_STATE_MACHINE;
5146 *MsgType = MT2_AIRONET_MSG;
5147 return (TRUE);
5148 }
5149#ifdef LEAP_SUPPORT
5150 if ( pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP ) //LEAP
5151 {
5152 // LEAP frames
5153 *Machine = LEAP_STATE_MACHINE;
5154 EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
5155 return (LeapMsgTypeSubst(EAPType, MsgType));
5156 }
5157 else
5158#endif // LEAP_SUPPORT //
5159 {
5160 *Machine = WPA_PSK_STATE_MACHINE;
5161 EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
5162 return(WpaMsgTypeSubst(EAPType, MsgType));
5163 }
5164 }
5165
5166 switch (pFrame->Hdr.FC.SubType)
5167 {
5168 case SUBTYPE_ASSOC_REQ:
5169 *Machine = ASSOC_STATE_MACHINE;
5170 *MsgType = MT2_PEER_ASSOC_REQ;
5171 break;
5172 case SUBTYPE_ASSOC_RSP:
5173 *Machine = ASSOC_STATE_MACHINE;
5174 *MsgType = MT2_PEER_ASSOC_RSP;
5175 break;
5176 case SUBTYPE_REASSOC_REQ:
5177 *Machine = ASSOC_STATE_MACHINE;
5178 *MsgType = MT2_PEER_REASSOC_REQ;
5179 break;
5180 case SUBTYPE_REASSOC_RSP:
5181 *Machine = ASSOC_STATE_MACHINE;
5182 *MsgType = MT2_PEER_REASSOC_RSP;
5183 break;
5184 case SUBTYPE_PROBE_REQ:
5185 *Machine = SYNC_STATE_MACHINE;
5186 *MsgType = MT2_PEER_PROBE_REQ;
5187 break;
5188 case SUBTYPE_PROBE_RSP:
5189 *Machine = SYNC_STATE_MACHINE;
5190 *MsgType = MT2_PEER_PROBE_RSP;
5191 break;
5192 case SUBTYPE_BEACON:
5193 *Machine = SYNC_STATE_MACHINE;
5194 *MsgType = MT2_PEER_BEACON;
5195 break;
5196 case SUBTYPE_ATIM:
5197 *Machine = SYNC_STATE_MACHINE;
5198 *MsgType = MT2_PEER_ATIM;
5199 break;
5200 case SUBTYPE_DISASSOC:
5201 *Machine = ASSOC_STATE_MACHINE;
5202 *MsgType = MT2_PEER_DISASSOC_REQ;
5203 break;
5204 case SUBTYPE_AUTH:
5205 // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
5206 NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
5207 if (Seq == 1 || Seq == 3)
5208 {
5209 *Machine = AUTH_RSP_STATE_MACHINE;
5210 *MsgType = MT2_PEER_AUTH_ODD;
5211 }
5212 else if (Seq == 2 || Seq == 4)
5213 {
5214 *Machine = AUTH_STATE_MACHINE;
5215 *MsgType = MT2_PEER_AUTH_EVEN;
5216 }
5217 else
5218 {
5219 return FALSE;
5220 }
5221 break;
5222 case SUBTYPE_DEAUTH:
5223 *Machine = AUTH_RSP_STATE_MACHINE;
5224 *MsgType = MT2_PEER_DEAUTH;
5225 break;
5226 case SUBTYPE_ACTION:
5227 *Machine = ACTION_STATE_MACHINE;
5228 // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
5229 if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
5230 {
5231 *MsgType = MT2_ACT_INVALID;
5232 }
5233 else
5234 {
5235 *MsgType = (pFrame->Octet[0]&0x7F);
5236 }
5237 break;
5238 default:
5239 return FALSE;
5240 break;
5241 }
5242
5243 return TRUE;
5244}
5245#endif // CONFIG_STA_SUPPORT //
5246
5247// ===========================================================================================
5248// state_machine.c
5249// ===========================================================================================
5250
5251/*! \brief Initialize the state machine.
5252 * \param *S pointer to the state machine
5253 * \param Trans State machine transition function
5254 * \param StNr number of states
5255 * \param MsgNr number of messages
5256 * \param DefFunc default function, when there is invalid state/message combination
5257 * \param InitState initial state of the state machine
5258 * \param Base StateMachine base, internal use only
5259 * \pre p_sm should be a legal pointer
5260 * \post
5261
5262 IRQL = PASSIVE_LEVEL
5263
5264 */
5265VOID StateMachineInit(
5266 IN STATE_MACHINE *S,
5267 IN STATE_MACHINE_FUNC Trans[],
5268 IN ULONG StNr,
5269 IN ULONG MsgNr,
5270 IN STATE_MACHINE_FUNC DefFunc,
5271 IN ULONG InitState,
5272 IN ULONG Base)
5273{
5274 ULONG i, j;
5275
5276 // set number of states and messages
5277 S->NrState = StNr;
5278 S->NrMsg = MsgNr;
5279 S->Base = Base;
5280
5281 S->TransFunc = Trans;
5282
5283 // init all state transition to default function
5284 for (i = 0; i < StNr; i++)
5285 {
5286 for (j = 0; j < MsgNr; j++)
5287 {
5288 S->TransFunc[i * MsgNr + j] = DefFunc;
5289 }
5290 }
5291
5292 // set the starting state
5293 S->CurrState = InitState;
5294}
5295
5296/*! \brief This function fills in the function pointer into the cell in the state machine
5297 * \param *S pointer to the state machine
5298 * \param St state
5299 * \param Msg incoming message
5300 * \param f the function to be executed when (state, message) combination occurs at the state machine
5301 * \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
5302 * \post
5303
5304 IRQL = PASSIVE_LEVEL
5305
5306 */
5307VOID StateMachineSetAction(
5308 IN STATE_MACHINE *S,
5309 IN ULONG St,
5310 IN ULONG Msg,
5311 IN STATE_MACHINE_FUNC Func)
5312{
5313 ULONG MsgIdx;
5314
5315 MsgIdx = Msg - S->Base;
5316
5317 if (St < S->NrState && MsgIdx < S->NrMsg)
5318 {
5319 // boundary checking before setting the action
5320 S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
5321 }
5322}
5323
5324/*! \brief This function does the state transition
5325 * \param *Adapter the NIC adapter pointer
5326 * \param *S the state machine
5327 * \param *Elem the message to be executed
5328 * \return None
5329
5330 IRQL = DISPATCH_LEVEL
5331
5332 */
5333VOID StateMachinePerformAction(
5334 IN PRTMP_ADAPTER pAd,
5335 IN STATE_MACHINE *S,
5336 IN MLME_QUEUE_ELEM *Elem)
5337{
5338 (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
5339}
5340
5341/*
5342 ==========================================================================
5343 Description:
5344 The drop function, when machine executes this, the message is simply
5345 ignored. This function does nothing, the message is freed in
5346 StateMachinePerformAction()
5347 ==========================================================================
5348 */
5349VOID Drop(
5350 IN PRTMP_ADAPTER pAd,
5351 IN MLME_QUEUE_ELEM *Elem)
5352{
5353}
5354
5355// ===========================================================================================
5356// lfsr.c
5357// ===========================================================================================
5358
5359/*
5360 ==========================================================================
5361 Description:
5362
5363 IRQL = PASSIVE_LEVEL
5364
5365 ==========================================================================
5366 */
5367VOID LfsrInit(
5368 IN PRTMP_ADAPTER pAd,
5369 IN ULONG Seed)
5370{
5371 if (Seed == 0)
5372 pAd->Mlme.ShiftReg = 1;
5373 else
5374 pAd->Mlme.ShiftReg = Seed;
5375}
5376
5377/*
5378 ==========================================================================
5379 Description:
5380 ==========================================================================
5381 */
5382UCHAR RandomByte(
5383 IN PRTMP_ADAPTER pAd)
5384{
5385 ULONG i;
5386 UCHAR R, Result;
5387
5388 R = 0;
5389
5390 if (pAd->Mlme.ShiftReg == 0)
5391 NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
5392
5393 for (i = 0; i < 8; i++)
5394 {
5395 if (pAd->Mlme.ShiftReg & 0x00000001)
5396 {
5397 pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
5398 Result = 1;
5399 }
5400 else
5401 {
5402 pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
5403 Result = 0;
5404 }
5405 R = (R << 1) | Result;
5406 }
5407
5408 return R;
5409}
5410
5411VOID AsicUpdateAutoFallBackTable(
5412 IN PRTMP_ADAPTER pAd,
5413 IN PUCHAR pRateTable)
5414{
5415 UCHAR i;
5416 HT_FBK_CFG0_STRUC HtCfg0;
5417 HT_FBK_CFG1_STRUC HtCfg1;
5418 LG_FBK_CFG0_STRUC LgCfg0;
5419 LG_FBK_CFG1_STRUC LgCfg1;
5420 PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate;
5421
5422 // set to initial value
5423 HtCfg0.word = 0x65432100;
5424 HtCfg1.word = 0xedcba988;
5425 LgCfg0.word = 0xedcba988;
5426 LgCfg1.word = 0x00002100;
5427
5428 pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
5429 for (i = 1; i < *((PUCHAR) pRateTable); i++)
5430 {
5431 pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
5432 switch (pCurrTxRate->Mode)
5433 {
5434 case 0: //CCK
5435 break;
5436 case 1: //OFDM
5437 {
5438 switch(pCurrTxRate->CurrMCS)
5439 {
5440 case 0:
5441 LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5442 break;
5443 case 1:
5444 LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5445 break;
5446 case 2:
5447 LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5448 break;
5449 case 3:
5450 LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5451 break;
5452 case 4:
5453 LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5454 break;
5455 case 5:
5456 LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5457 break;
5458 case 6:
5459 LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5460 break;
5461 case 7:
5462 LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
5463 break;
5464 }
5465 }
5466 break;
5467#ifdef DOT11_N_SUPPORT
5468 case 2: //HT-MIX
5469 case 3: //HT-GF
5470 {
5471 if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
5472 {
5473 switch(pCurrTxRate->CurrMCS)
5474 {
5475 case 0:
5476 HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
5477 break;
5478 case 1:
5479 HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
5480 break;
5481 case 2:
5482 HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
5483 break;
5484 case 3:
5485 HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
5486 break;
5487 case 4:
5488 HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
5489 break;
5490 case 5:
5491 HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
5492 break;
5493 case 6:
5494 HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
5495 break;
5496 case 7:
5497 HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
5498 break;
5499 case 8:
5500 HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
5501 break;
5502 case 9:
5503 HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
5504 break;
5505 case 10:
5506 HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
5507 break;
5508 case 11:
5509 HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
5510 break;
5511 case 12:
5512 HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
5513 break;
5514 case 13:
5515 HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
5516 break;
5517 case 14:
5518 HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
5519 break;
5520 case 15:
5521 HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
5522 break;
5523 default:
5524 DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
5525 }
5526 }
5527 }
5528 break;
5529#endif // DOT11_N_SUPPORT //
5530 }
5531
5532 pNextTxRate = pCurrTxRate;
5533 }
5534
5535 RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
5536 RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
5537 RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
5538 RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
5539}
5540
5541/*
5542 ========================================================================
5543
5544 Routine Description:
5545 Set MAC register value according operation mode.
5546 OperationMode AND bNonGFExist are for MM and GF Proteciton.
5547 If MM or GF mask is not set, those passing argument doesn't not take effect.
5548
5549 Operation mode meaning:
5550 = 0 : Pure HT, no preotection.
5551 = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
5552 = 0x10: No Transmission in 40M is protected.
5553 = 0x11: Transmission in both 40M and 20M shall be protected
5554 if (bNonGFExist)
5555 we should choose not to use GF. But still set correct ASIC registers.
5556 ========================================================================
5557*/
5558VOID AsicUpdateProtect(
5559 IN PRTMP_ADAPTER pAd,
5560 IN USHORT OperationMode,
5561 IN UCHAR SetMask,
5562 IN BOOLEAN bDisableBGProtect,
5563 IN BOOLEAN bNonGFExist)
5564{
5565 PROT_CFG_STRUC ProtCfg, ProtCfg4;
5566 UINT32 Protect[6];
5567 USHORT offset;
5568 UCHAR i;
5569 UINT32 MacReg = 0;
5570
5571#ifdef RALINK_ATE
5572 if (ATE_ON(pAd))
5573 return;
5574#endif // RALINK_ATE //
5575
5576#ifdef DOT11_N_SUPPORT
5577 if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
5578 {
5579 return;
5580 }
5581
5582 if (pAd->BATable.numAsOriginator)
5583 {
5584 //
5585 // enable the RTS/CTS to avoid channel collision
5586 //
5587 SetMask = ALLN_SETPROTECT;
5588 OperationMode = 8;
5589 }
5590#endif // DOT11_N_SUPPORT //
5591
5592 // Config ASIC RTS threshold register
5593 RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
5594 MacReg &= 0xFF0000FF;
5595#if 0
5596 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
5597#else
5598 // If the user want disable RtsThreshold and enbale Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
5599 if ((
5600#ifdef DOT11_N_SUPPORT
5601 (pAd->CommonCfg.BACapability.field.AmsduEnable) ||
5602#endif // DOT11_N_SUPPORT //
5603 (pAd->CommonCfg.bAggregationCapable == TRUE))
5604 && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
5605 {
5606 MacReg |= (0x1000 << 8);
5607 }
5608 else
5609 {
5610 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
5611 }
5612#endif
5613
5614 RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
5615
5616 // Initial common protection settings
5617 RTMPZeroMemory(Protect, sizeof(Protect));
5618 ProtCfg4.word = 0;
5619 ProtCfg.word = 0;
5620 ProtCfg.field.TxopAllowGF40 = 1;
5621 ProtCfg.field.TxopAllowGF20 = 1;
5622 ProtCfg.field.TxopAllowMM40 = 1;
5623 ProtCfg.field.TxopAllowMM20 = 1;
5624 ProtCfg.field.TxopAllowOfdm = 1;
5625 ProtCfg.field.TxopAllowCck = 1;
5626 ProtCfg.field.RTSThEn = 1;
5627 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5628
5629 // update PHY mode and rate
5630 if (pAd->CommonCfg.Channel > 14)
5631 ProtCfg.field.ProtectRate = 0x4000;
5632 ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
5633
5634 // Handle legacy(B/G) protection
5635 if (bDisableBGProtect)
5636 {
5637 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5638 ProtCfg.field.ProtectCtrl = 0;
5639 Protect[0] = ProtCfg.word;
5640 Protect[1] = ProtCfg.word;
5641 }
5642 else
5643 {
5644 //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
5645 ProtCfg.field.ProtectCtrl = 0; // CCK do not need to be protected
5646 Protect[0] = ProtCfg.word;
5647 ProtCfg.field.ProtectCtrl = ASIC_CTS; // OFDM needs using CCK to protect
5648 Protect[1] = ProtCfg.word;
5649 }
5650
5651#ifdef DOT11_N_SUPPORT
5652 // Decide HT frame protection.
5653 if ((SetMask & ALLN_SETPROTECT) != 0)
5654 {
5655 switch(OperationMode)
5656 {
5657 case 0x0:
5658 // NO PROTECT
5659 // 1.All STAs in the BSS are 20/40 MHz HT
5660 // 2. in ai 20/40MHz BSS
5661 // 3. all STAs are 20MHz in a 20MHz BSS
5662 // Pure HT. no protection.
5663
5664 // MM20_PROT_CFG
5665 // Reserved (31:27)
5666 // PROT_TXOP(25:20) -- 010111
5667 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5668 // PROT_CTRL(17:16) -- 00 (None)
5669 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5670 Protect[2] = 0x01744004;
5671
5672 // MM40_PROT_CFG
5673 // Reserved (31:27)
5674 // PROT_TXOP(25:20) -- 111111
5675 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5676 // PROT_CTRL(17:16) -- 00 (None)
5677 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5678 Protect[3] = 0x03f44084;
5679
5680 // CF20_PROT_CFG
5681 // Reserved (31:27)
5682 // PROT_TXOP(25:20) -- 010111
5683 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5684 // PROT_CTRL(17:16) -- 00 (None)
5685 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
5686 Protect[4] = 0x01744004;
5687
5688 // CF40_PROT_CFG
5689 // Reserved (31:27)
5690 // PROT_TXOP(25:20) -- 111111
5691 // PROT_NAV(19:18) -- 01 (Short NAV protection)
5692 // PROT_CTRL(17:16) -- 00 (None)
5693 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
5694 Protect[5] = 0x03f44084;
5695
5696 if (bNonGFExist)
5697 {
5698 // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
5699 // PROT_CTRL(17:16) -- 01 (RTS/CTS)
5700 Protect[4] = 0x01754004;
5701 Protect[5] = 0x03f54084;
5702 }
5703 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
5704 break;
5705
5706 case 1:
5707 // This is "HT non-member protection mode."
5708 // If there may be non-HT STAs my BSS
5709 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5710 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
5711 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
5712 {
5713 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5714 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
5715 }
5716 //Assign Protection method for 20&40 MHz packets
5717 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5718 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5719 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5720 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5721 Protect[2] = ProtCfg.word;
5722 Protect[3] = ProtCfg4.word;
5723 Protect[4] = ProtCfg.word;
5724 Protect[5] = ProtCfg4.word;
5725 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5726 break;
5727
5728 case 2:
5729 // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
5730 ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
5731 ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
5732
5733 //Assign Protection method for 40MHz packets
5734 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5735 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5736 Protect[2] = ProtCfg.word;
5737 Protect[3] = ProtCfg4.word;
5738 if (bNonGFExist)
5739 {
5740 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5741 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5742 }
5743 Protect[4] = ProtCfg.word;
5744 Protect[5] = ProtCfg4.word;
5745
5746 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
5747 break;
5748
5749 case 3:
5750 // HT mixed mode. PROTECT ALL!
5751 // Assign Rate
5752 ProtCfg.word = 0x01744004; //duplicaet legacy 24M. BW set 1.
5753 ProtCfg4.word = 0x03f44084;
5754 // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
5755 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
5756 {
5757 ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
5758 ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
5759 }
5760 //Assign Protection method for 20&40 MHz packets
5761 ProtCfg.field.ProtectCtrl = ASIC_RTS;
5762 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
5763 ProtCfg4.field.ProtectCtrl = ASIC_RTS;
5764 ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
5765 Protect[2] = ProtCfg.word;
5766 Protect[3] = ProtCfg4.word;
5767 Protect[4] = ProtCfg.word;
5768 Protect[5] = ProtCfg4.word;
5769 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5770 break;
5771
5772 case 8:
5773 // Special on for Atheros problem n chip.
5774 Protect[2] = 0x01754004;
5775 Protect[3] = 0x03f54084;
5776 Protect[4] = 0x01754004;
5777 Protect[5] = 0x03f54084;
5778 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
5779 break;
5780 }
5781 }
5782#endif // DOT11_N_SUPPORT //
5783
5784 offset = CCK_PROT_CFG;
5785 for (i = 0;i < 6;i++)
5786 {
5787 if ((SetMask & (1<< i)))
5788 {
5789 RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
5790 }
5791 }
5792}
5793
5794/*
5795 ==========================================================================
5796 Description:
5797
5798 IRQL = PASSIVE_LEVEL
5799 IRQL = DISPATCH_LEVEL
5800
5801 ==========================================================================
5802 */
5803VOID AsicSwitchChannel(
5804 IN PRTMP_ADAPTER pAd,
5805 IN UCHAR Channel,
5806 IN BOOLEAN bScan)
5807{
5808 ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
5809 CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
5810 UCHAR index;
5811 UINT32 Value = 0; //BbpReg, Value;
5812 RTMP_RF_REGS *RFRegTable;
5813
5814 // Search Tx power value
5815 for (index = 0; index < pAd->ChannelListNum; index++)
5816 {
5817 if (Channel == pAd->ChannelList[index].Channel)
5818 {
5819 TxPwer = pAd->ChannelList[index].Power;
5820 TxPwer2 = pAd->ChannelList[index].Power2;
5821 break;
5822 }
5823 }
5824
5825 if (index == MAX_NUM_OF_CHANNELS)
5826 {
5827 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Cant find the Channel#%d \n", Channel));
5828 }
5829
5830 {
5831 RFRegTable = RF2850RegTable;
5832
5833 switch (pAd->RfIcType)
5834 {
5835 case RFIC_2820:
5836 case RFIC_2850:
5837 case RFIC_2720:
5838 case RFIC_2750:
5839
5840 for (index = 0; index < NUM_OF_2850_CHNL; index++)
5841 {
5842 if (Channel == RFRegTable[index].Channel)
5843 {
5844 R2 = RFRegTable[index].R2;
5845 if (pAd->Antenna.field.TxPath == 1)
5846 {
5847 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
5848 }
5849
5850 if (pAd->Antenna.field.RxPath == 2)
5851 {
5852 R2 |= 0x40; // write 1 to off Rxpath.
5853 }
5854 else if (pAd->Antenna.field.RxPath == 1)
5855 {
5856 R2 |= 0x20040; // write 1 to off RxPath
5857 }
5858
5859 if (Channel > 14)
5860 {
5861 // initialize R3, R4
5862 R3 = (RFRegTable[index].R3 & 0xffffc1ff);
5863 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
5864
5865 // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
5866 // R3
5867 if ((TxPwer >= -7) && (TxPwer < 0))
5868 {
5869 TxPwer = (7+TxPwer);
5870 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
5871 R3 |= (TxPwer << 10);
5872 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
5873 }
5874 else
5875 {
5876 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
5877 R3 |= (TxPwer << 10) | (1 << 9);
5878 }
5879
5880 // R4
5881 if ((TxPwer2 >= -7) && (TxPwer2 < 0))
5882 {
5883 TxPwer2 = (7+TxPwer2);
5884 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
5885 R4 |= (TxPwer2 << 7);
5886 DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
5887 }
5888 else
5889 {
5890 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
5891 R4 |= (TxPwer2 << 7) | (1 << 6);
5892 }
5893 }
5894 else
5895 {
5896 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
5897 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
5898 }
5899
5900 // Based on BBP current mode before changing RF channel.
5901 if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
5902 {
5903 R4 |=0x200000;
5904 }
5905
5906 // Update variables
5907 pAd->LatchRfRegs.Channel = Channel;
5908 pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
5909 pAd->LatchRfRegs.R2 = R2;
5910 pAd->LatchRfRegs.R3 = R3;
5911 pAd->LatchRfRegs.R4 = R4;
5912
5913 // Set RF value 1's set R3[bit2] = [0]
5914 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
5915 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
5916 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
5917 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
5918
5919 RTMPusecDelay(200);
5920
5921 // Set RF value 2's set R3[bit2] = [1]
5922 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
5923 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
5924 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
5925 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
5926
5927 RTMPusecDelay(200);
5928
5929 // Set RF value 3's set R3[bit2] = [0]
5930 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
5931 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
5932 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
5933 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
5934
5935 break;
5936 }
5937 }
5938 break;
5939
5940 default:
5941 break;
5942 }
5943 }
5944
5945 // Change BBP setting during siwtch from a->g, g->a
5946 if (Channel <= 14)
5947 {
5948 ULONG TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
5949
5950 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
5951 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
5952 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
5953 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.
5954 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
5955
5956 // Rx High power VGA offset for LNA select
5957 if (pAd->NicConfig2.field.ExternalLNAForG)
5958 {
5959 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
5960 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
5961 }
5962 else
5963 {
5964 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
5965 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
5966 }
5967
5968 // 5G band selection PIN, bit1 and bit2 are complement
5969 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
5970 Value &= (~0x6);
5971 Value |= (0x04);
5972 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
5973
5974 // Turn off unused PA or LNA when only 1T or 1R
5975 if (pAd->Antenna.field.TxPath == 1)
5976 {
5977 TxPinCfg &= 0xFFFFFFF3;
5978 }
5979 if (pAd->Antenna.field.RxPath == 1)
5980 {
5981 TxPinCfg &= 0xFFFFF3FF;
5982 }
5983
5984 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
5985 }
5986 else
5987 {
5988 ULONG TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
5989
5990 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
5991 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
5992 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
5993 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.
5994 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
5995
5996 // Rx High power VGA offset for LNA select
5997 if (pAd->NicConfig2.field.ExternalLNAForA)
5998 {
5999 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
6000 }
6001 else
6002 {
6003 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
6004 }
6005
6006 // 5G band selection PIN, bit1 and bit2 are complement
6007 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
6008 Value &= (~0x6);
6009 Value |= (0x02);
6010 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
6011
6012 // Turn off unused PA or LNA when only 1T or 1R
6013 if (pAd->Antenna.field.TxPath == 1)
6014 {
6015 TxPinCfg &= 0xFFFFFFF3;
6016 }
6017 if (pAd->Antenna.field.RxPath == 1)
6018 {
6019 TxPinCfg &= 0xFFFFF3FF;
6020 }
6021
6022 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
6023 }
6024
6025 // R66 should be set according to Channel and use 20MHz when scanning
6026 //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
6027 if (bScan)
6028 RTMPSetAGCInitValue(pAd, BW_20);
6029 else
6030 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
6031
6032 //
6033 // On 11A, We should delay and wait RF/BBP to be stable
6034 // and the appropriate time should be 1000 micro seconds
6035 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
6036 //
6037 RTMPusecDelay(1000);
6038
6039 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",
6040 Channel,
6041 pAd->RfIcType,
6042 (R3 & 0x00003e00) >> 9,
6043 (R4 & 0x000007c0) >> 6,
6044 pAd->Antenna.field.TxPath,
6045 pAd->LatchRfRegs.R1,
6046 pAd->LatchRfRegs.R2,
6047 pAd->LatchRfRegs.R3,
6048 pAd->LatchRfRegs.R4));
6049}
6050
6051/*
6052 ==========================================================================
6053 Description:
6054 This function is required for 2421 only, and should not be used during
6055 site survey. It's only required after NIC decided to stay at a channel
6056 for a longer period.
6057 When this function is called, it's always after AsicSwitchChannel().
6058
6059 IRQL = PASSIVE_LEVEL
6060 IRQL = DISPATCH_LEVEL
6061
6062 ==========================================================================
6063 */
6064VOID AsicLockChannel(
6065 IN PRTMP_ADAPTER pAd,
6066 IN UCHAR Channel)
6067{
6068}
6069
6070/*
6071 ==========================================================================
6072 Description:
6073
6074 IRQL = PASSIVE_LEVEL
6075 IRQL = DISPATCH_LEVEL
6076
6077 ==========================================================================
6078 */
6079VOID AsicAntennaSelect(
6080 IN PRTMP_ADAPTER pAd,
6081 IN UCHAR Channel)
6082{
6083}
6084
6085/*
6086 ========================================================================
6087
6088 Routine Description:
6089 Antenna miscellaneous setting.
6090
6091 Arguments:
6092 pAd Pointer to our adapter
6093 BandState Indicate current Band State.
6094
6095 Return Value:
6096 None
6097
6098 IRQL <= DISPATCH_LEVEL
6099
6100 Note:
6101 1.) Frame End type control
6102 only valid for G only (RF_2527 & RF_2529)
6103 0: means DPDT, set BBP R4 bit 5 to 1
6104 1: means SPDT, set BBP R4 bit 5 to 0
6105
6106
6107 ========================================================================
6108*/
6109VOID AsicAntennaSetting(
6110 IN PRTMP_ADAPTER pAd,
6111 IN ABGBAND_STATE BandState)
6112{
6113}
6114
6115VOID AsicRfTuningExec(
6116 IN PVOID SystemSpecific1,
6117 IN PVOID FunctionContext,
6118 IN PVOID SystemSpecific2,
6119 IN PVOID SystemSpecific3)
6120{
6121}
6122
6123/*
6124 ==========================================================================
6125 Description:
6126 Gives CCK TX rate 2 more dB TX power.
6127 This routine works only in LINK UP in INFRASTRUCTURE mode.
6128
6129 calculate desired Tx power in RF R3.Tx0~5, should consider -
6130 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
6131 1. TxPowerPercentage
6132 2. auto calibration based on TSSI feedback
6133 3. extra 2 db for CCK
6134 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
6135
6136 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
6137 it should be called AFTER MlmeDynamicTxRatSwitching()
6138 ==========================================================================
6139 */
6140VOID AsicAdjustTxPower(
6141 IN PRTMP_ADAPTER pAd)
6142{
6143 INT i, j;
6144 CHAR DeltaPwr = 0;
6145 BOOLEAN bAutoTxAgc = FALSE;
6146 UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
6147 UCHAR BbpR1 = 0, BbpR49 = 0, idx;
6148 PCHAR pTxAgcCompensate;
6149 ULONG TxPwr[5];
6150 CHAR Value;
6151
6152 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
6153 {
6154 if (pAd->CommonCfg.CentralChannel > 14)
6155 {
6156 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
6157 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
6158 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
6159 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
6160 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
6161 }
6162 else
6163 {
6164 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
6165 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
6166 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
6167 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
6168 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
6169 }
6170 }
6171 else
6172 {
6173 if (pAd->CommonCfg.Channel > 14)
6174 {
6175 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
6176 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
6177 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
6178 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
6179 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
6180 }
6181 else
6182 {
6183 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
6184 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
6185 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
6186 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
6187 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
6188 }
6189 }
6190
6191 // TX power compensation for temperature variation based on TSSI. try every 4 second
6192 if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
6193 {
6194 if (pAd->CommonCfg.Channel <= 14)
6195 {
6196 /* bg channel */
6197 bAutoTxAgc = pAd->bAutoTxAgcG;
6198 TssiRef = pAd->TssiRefG;
6199 pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
6200 pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
6201 TxAgcStep = pAd->TxAgcStepG;
6202 pTxAgcCompensate = &pAd->TxAgcCompensateG;
6203 }
6204 else
6205 {
6206 /* a channel */
6207 bAutoTxAgc = pAd->bAutoTxAgcA;
6208 TssiRef = pAd->TssiRefA;
6209 pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
6210 pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
6211 TxAgcStep = pAd->TxAgcStepA;
6212 pTxAgcCompensate = &pAd->TxAgcCompensateA;
6213 }
6214
6215 if (bAutoTxAgc)
6216 {
6217 /* BbpR1 is unsigned char */
6218 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
6219
6220 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
6221 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
6222 /* step value is defined in pAd->TxAgcStepG for tx power value */
6223
6224 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
6225 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
6226 above value are examined in mass factory production */
6227 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
6228
6229 /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
6230 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
6231 /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
6232
6233 if (BbpR49 > pTssiMinusBoundary[1])
6234 {
6235 // Reading is larger than the reference value
6236 // check for how large we need to decrease the Tx power
6237 for (idx = 1; idx < 5; idx++)
6238 {
6239 if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
6240 break;
6241 }
6242 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
6243 *pTxAgcCompensate = -(TxAgcStep * (idx-1));
6244
6245 DeltaPwr += (*pTxAgcCompensate);
6246 DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
6247 BbpR49, TssiRef, TxAgcStep, idx-1));
6248 }
6249 else if (BbpR49 < pTssiPlusBoundary[1])
6250 {
6251 // Reading is smaller than the reference value
6252 // check for how large we need to increase the Tx power
6253 for (idx = 1; idx < 5; idx++)
6254 {
6255 if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
6256 break;
6257 }
6258 // The index is the step we should increase, idx = 0 means there is nothing to compensate
6259 *pTxAgcCompensate = TxAgcStep * (idx-1);
6260 DeltaPwr += (*pTxAgcCompensate);
6261 DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6262 BbpR49, TssiRef, TxAgcStep, idx-1));
6263 }
6264 else
6265 {
6266 *pTxAgcCompensate = 0;
6267 DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
6268 BbpR49, TssiRef, TxAgcStep, 0));
6269 }
6270 }
6271 }
6272 else
6273 {
6274 if (pAd->CommonCfg.Channel <= 14)
6275 {
6276 bAutoTxAgc = pAd->bAutoTxAgcG;
6277 pTxAgcCompensate = &pAd->TxAgcCompensateG;
6278 }
6279 else
6280 {
6281 bAutoTxAgc = pAd->bAutoTxAgcA;
6282 pTxAgcCompensate = &pAd->TxAgcCompensateA;
6283 }
6284
6285 if (bAutoTxAgc)
6286 DeltaPwr += (*pTxAgcCompensate);
6287 }
6288
6289 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
6290 BbpR1 &= 0xFC;
6291
6292#ifdef SINGLE_SKU
6293 // Handle regulatory max tx power constrain
6294 do
6295 {
6296 UCHAR TxPwrInEEPROM = 0xFF, CountryTxPwr = 0xFF, criterion;
6297 UCHAR AdjustMaxTxPwr[40];
6298
6299 if (pAd->CommonCfg.Channel > 14) // 5G band
6300 TxPwrInEEPROM = ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF00) >> 8);
6301 else // 2.4G band
6302 TxPwrInEEPROM = (pAd->CommonCfg.DefineMaxTxPwr & 0x00FF);
6303 CountryTxPwr = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
6304
6305 // error handling, range check
6306 if ((TxPwrInEEPROM > 0x50) || (CountryTxPwr > 0x50))
6307 {
6308 DBGPRINT(RT_DEBUG_ERROR,("AsicAdjustTxPower - Invalid max tx power (=0x%02x), CountryTxPwr=%d\n", TxPwrInEEPROM, CountryTxPwr));
6309 break;
6310 }
6311
6312 criterion = *((PUCHAR)TxPwr + 2) & 0xF; // FAE use OFDM 6M as criterion
6313
6314 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (criterion=%d, TxPwrInEEPROM=%d, CountryTxPwr=%d)\n", criterion, TxPwrInEEPROM, CountryTxPwr));
6315
6316 // Adjust max tx power according to the relationship of tx power in E2PROM
6317 for (i=0; i<5; i++)
6318 {
6319 // CCK will have 4dBm larger than OFDM
6320 // Therefore, we should separate to parse the tx power field
6321 if (i == 0)
6322 {
6323 for (j=0; j<8; j++)
6324 {
6325 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
6326
6327 if (j < 4)
6328 {
6329 // CCK will have 4dBm larger than OFDM
6330 AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion) + 4;
6331 }
6332 else
6333 {
6334 AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
6335 }
6336 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6337 }
6338 }
6339 else
6340 {
6341 for (j=0; j<8; j++)
6342 {
6343 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
6344
6345 AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
6346 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6347 }
6348 }
6349 }
6350
6351 // Adjust tx power according to the relationship
6352 for (i=0; i<5; i++)
6353 {
6354 if (TxPwr[i] != 0xffffffff)
6355 {
6356 for (j=0; j<8; j++)
6357 {
6358 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
6359
6360 // The system tx power is larger than the regulatory, the power should be restrain
6361 if (AdjustMaxTxPwr[i*8+j] > CountryTxPwr)
6362 {
6363 // decrease to zero and don't need to take care BBPR1
6364 if ((Value - (AdjustMaxTxPwr[i*8+j] - CountryTxPwr)) > 0)
6365 Value -= (AdjustMaxTxPwr[i*8+j] - CountryTxPwr);
6366 else
6367 Value = 0;
6368
6369 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6370 }
6371 else
6372 DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d, no change)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
6373
6374 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
6375 }
6376 }
6377 }
6378 } while (FALSE);
6379#endif // SINGLE_SKU //
6380
6381 /* calculate delta power based on the percentage specified from UI */
6382 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
6383 // We lower TX power here according to the percentage specified from UI
6384 if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
6385 ;
6386 else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
6387 ;
6388 else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
6389 {
6390 DeltaPwr -= 1;
6391 }
6392 else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
6393 {
6394 DeltaPwr -= 3;
6395 }
6396 else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
6397 {
6398 BbpR1 |= 0x01;
6399 }
6400 else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
6401 {
6402 BbpR1 |= 0x01;
6403 DeltaPwr -= 3;
6404 }
6405 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
6406 {
6407 BbpR1 |= 0x02;
6408 }
6409
6410 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
6411
6412 /* reset different new tx power for different TX rate */
6413 for(i=0; i<5; i++)
6414 {
6415 if (TxPwr[i] != 0xffffffff)
6416 {
6417 for (j=0; j<8; j++)
6418 {
6419 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
6420
6421 if ((Value + DeltaPwr) < 0)
6422 {
6423 Value = 0; /* min */
6424 }
6425 else if ((Value + DeltaPwr) > 0xF)
6426 {
6427 Value = 0xF; /* max */
6428 }
6429 else
6430 {
6431 Value += DeltaPwr; /* temperature compensation */
6432 }
6433
6434 /* fill new value to CSR offset */
6435 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
6436 }
6437
6438 /* write tx power value to CSR */
6439 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
6440 TX power for OFDM 6M/9M
6441 TX power for CCK5.5M/11M
6442 TX power for CCK1M/2M */
6443 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
6444 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
6445 }
6446 }
6447
6448}
6449
6450#ifdef CONFIG_STA_SUPPORT
6451/*
6452 ==========================================================================
6453 Description:
6454 put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
6455 automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
6456 the wakeup timer timeout. Driver has to issue a separate command to wake
6457 PHY up.
6458
6459 IRQL = DISPATCH_LEVEL
6460
6461 ==========================================================================
6462 */
6463VOID AsicSleepThenAutoWakeup(
6464 IN PRTMP_ADAPTER pAd,
6465 IN USHORT TbttNumToNextWakeUp)
6466{
6467 RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
6468}
6469
6470/*
6471 ==========================================================================
6472 Description:
6473 AsicForceWakeup() is used whenever manual wakeup is required
6474 AsicForceSleep() should only be used when not in INFRA BSS. When
6475 in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
6476 ==========================================================================
6477 */
6478VOID AsicForceSleep(
6479 IN PRTMP_ADAPTER pAd)
6480{
6481
6482}
6483
6484/*
6485 ==========================================================================
6486 Description:
6487 AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
6488 expired.
6489
6490 IRQL = PASSIVE_LEVEL
6491 IRQL = DISPATCH_LEVEL
6492 ==========================================================================
6493 */
6494VOID AsicForceWakeup(
6495 IN PRTMP_ADAPTER pAd,
6496 IN BOOLEAN bFromTx)
6497{
6498 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
6499 RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
6500}
6501#endif // CONFIG_STA_SUPPORT //
6502/*
6503 ==========================================================================
6504 Description:
6505 Set My BSSID
6506
6507 IRQL = DISPATCH_LEVEL
6508
6509 ==========================================================================
6510 */
6511VOID AsicSetBssid(
6512 IN PRTMP_ADAPTER pAd,
6513 IN PUCHAR pBssid)
6514{
6515 ULONG Addr4;
6516 DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
6517 pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
6518
6519 Addr4 = (ULONG)(pBssid[0]) |
6520 (ULONG)(pBssid[1] << 8) |
6521 (ULONG)(pBssid[2] << 16) |
6522 (ULONG)(pBssid[3] << 24);
6523 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
6524
6525 Addr4 = 0;
6526 // always one BSSID in STA mode
6527 Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
6528
6529 RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
6530}
6531
6532VOID AsicSetMcastWC(
6533 IN PRTMP_ADAPTER pAd)
6534{
6535 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
6536 USHORT offset;
6537
6538 pEntry->Sst = SST_ASSOC;
6539 pEntry->Aid = MCAST_WCID; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
6540 pEntry->PsMode = PWR_ACTIVE;
6541 pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
6542 offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
6543}
6544
6545/*
6546 ==========================================================================
6547 Description:
6548
6549 IRQL = DISPATCH_LEVEL
6550
6551 ==========================================================================
6552 */
6553VOID AsicDelWcidTab(
6554 IN PRTMP_ADAPTER pAd,
6555 IN UCHAR Wcid)
6556{
6557 ULONG Addr0 = 0x0, Addr1 = 0x0;
6558 ULONG offset;
6559
6560 DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
6561 offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
6562 RTMP_IO_WRITE32(pAd, offset, Addr0);
6563 offset += 4;
6564 RTMP_IO_WRITE32(pAd, offset, Addr1);
6565}
6566
6567/*
6568 ==========================================================================
6569 Description:
6570
6571 IRQL = DISPATCH_LEVEL
6572
6573 ==========================================================================
6574 */
6575VOID AsicEnableRDG(
6576 IN PRTMP_ADAPTER pAd)
6577{
6578 TX_LINK_CFG_STRUC TxLinkCfg;
6579 UINT32 Data = 0;
6580
6581 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
6582 TxLinkCfg.field.TxRDGEn = 1;
6583 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
6584
6585 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
6586 Data &= 0xFFFFFF00;
6587 Data |= 0x80;
6588 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
6589
6590 //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
6591}
6592
6593/*
6594 ==========================================================================
6595 Description:
6596
6597 IRQL = DISPATCH_LEVEL
6598
6599 ==========================================================================
6600 */
6601VOID AsicDisableRDG(
6602 IN PRTMP_ADAPTER pAd)
6603{
6604 TX_LINK_CFG_STRUC TxLinkCfg;
6605 UINT32 Data = 0;
6606
6607
6608 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
6609 TxLinkCfg.field.TxRDGEn = 0;
6610 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
6611
6612 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
6613
6614 Data &= 0xFFFFFF00;
6615 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
6616#ifdef DOT11_N_SUPPORT
6617 && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
6618#endif // DOT11_N_SUPPORT //
6619 )
6620 {
6621 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6622 if (pAd->CommonCfg.bEnableTxBurst)
6623 Data |= 0x20;
6624 }
6625 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
6626}
6627
6628/*
6629 ==========================================================================
6630 Description:
6631
6632 IRQL = PASSIVE_LEVEL
6633 IRQL = DISPATCH_LEVEL
6634
6635 ==========================================================================
6636 */
6637VOID AsicDisableSync(
6638 IN PRTMP_ADAPTER pAd)
6639{
6640 BCN_TIME_CFG_STRUC csr;
6641
6642 DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
6643
6644 // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
6645 // that NIC will never wakes up because TSF stops and no more
6646 // TBTT interrupts
6647 pAd->TbttTickCount = 0;
6648 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
6649 csr.field.bBeaconGen = 0;
6650 csr.field.bTBTTEnable = 0;
6651 csr.field.TsfSyncMode = 0;
6652 csr.field.bTsfTicking = 0;
6653 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
6654
6655}
6656
6657/*
6658 ==========================================================================
6659 Description:
6660
6661 IRQL = DISPATCH_LEVEL
6662
6663 ==========================================================================
6664 */
6665VOID AsicEnableBssSync(
6666 IN PRTMP_ADAPTER pAd)
6667{
6668 BCN_TIME_CFG_STRUC csr;
6669
6670 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
6671
6672 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
6673#ifdef CONFIG_STA_SUPPORT
6674 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6675 {
6676 csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
6677 csr.field.bTsfTicking = 1;
6678 csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
6679 csr.field.bBeaconGen = 0; // do NOT generate BEACON
6680 csr.field.bTBTTEnable = 1;
6681 }
6682#endif // CONFIG_STA_SUPPORT //
6683 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
6684}
6685
6686/*
6687 ==========================================================================
6688 Description:
6689 Note:
6690 BEACON frame in shared memory should be built ok before this routine
6691 can be called. Otherwise, a garbage frame maybe transmitted out every
6692 Beacon period.
6693
6694 IRQL = DISPATCH_LEVEL
6695
6696 ==========================================================================
6697 */
6698VOID AsicEnableIbssSync(
6699 IN PRTMP_ADAPTER pAd)
6700{
6701 BCN_TIME_CFG_STRUC csr9;
6702 PUCHAR ptr;
6703 UINT i;
6704
6705 DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
6706
6707 RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
6708 csr9.field.bBeaconGen = 0;
6709 csr9.field.bTBTTEnable = 0;
6710 csr9.field.bTsfTicking = 0;
6711 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
6712
6713#ifdef RT2860
6714 // move BEACON TXD and frame content to on-chip memory
6715 ptr = (PUCHAR)&pAd->BeaconTxWI;
6716 for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
6717 {
6718 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
6719 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
6720 ptr += 4;
6721 }
6722
6723 // start right after the 16-byte TXWI field
6724 ptr = pAd->BeaconBuf;
6725 for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4)
6726 {
6727 UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
6728 RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
6729 ptr +=4;
6730 }
6731#endif // RT2860 //
6732
6733 // start sending BEACON
6734 csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
6735 csr9.field.bTsfTicking = 1;
6736 csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
6737 csr9.field.bTBTTEnable = 1;
6738 csr9.field.bBeaconGen = 1;
6739 RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
6740}
6741
6742/*
6743 ==========================================================================
6744 Description:
6745
6746 IRQL = PASSIVE_LEVEL
6747 IRQL = DISPATCH_LEVEL
6748
6749 ==========================================================================
6750 */
6751VOID AsicSetEdcaParm(
6752 IN PRTMP_ADAPTER pAd,
6753 IN PEDCA_PARM pEdcaParm)
6754{
6755 EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
6756 AC_TXOP_CSR0_STRUC csr0;
6757 AC_TXOP_CSR1_STRUC csr1;
6758 AIFSN_CSR_STRUC AifsnCsr;
6759 CWMIN_CSR_STRUC CwminCsr;
6760 CWMAX_CSR_STRUC CwmaxCsr;
6761 int i;
6762
6763 Ac0Cfg.word = 0;
6764 Ac1Cfg.word = 0;
6765 Ac2Cfg.word = 0;
6766 Ac3Cfg.word = 0;
6767 if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
6768 {
6769 DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
6770 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
6771 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
6772 {
6773 if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
6774 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
6775 }
6776
6777 //========================================================
6778 // MAC Register has a copy .
6779 //========================================================
6780 if( pAd->CommonCfg.bEnableTxBurst )
6781 {
6782 // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
6783 Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
6784 }
6785 else
6786 Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
6787 Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
6788 Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
6789 Ac0Cfg.field.Aifsn = 2;
6790 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
6791
6792 Ac1Cfg.field.AcTxop = 0; // QID_AC_BK
6793 Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
6794 Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
6795 Ac1Cfg.field.Aifsn = 2;
6796 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
6797
6798 if (pAd->CommonCfg.PhyMode == PHY_11B)
6799 {
6800 Ac2Cfg.field.AcTxop = 192; // AC_VI: 192*32us ~= 6ms
6801 Ac3Cfg.field.AcTxop = 96; // AC_VO: 96*32us ~= 3ms
6802 }
6803 else
6804 {
6805 Ac2Cfg.field.AcTxop = 96; // AC_VI: 96*32us ~= 3ms
6806 Ac3Cfg.field.AcTxop = 48; // AC_VO: 48*32us ~= 1.5ms
6807 }
6808 Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
6809 Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
6810 Ac2Cfg.field.Aifsn = 2;
6811 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
6812 Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
6813 Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
6814 Ac3Cfg.field.Aifsn = 2;
6815 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
6816
6817 //========================================================
6818 // DMA Register has a copy too.
6819 //========================================================
6820 csr0.field.Ac0Txop = 0; // QID_AC_BE
6821 csr0.field.Ac1Txop = 0; // QID_AC_BK
6822 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
6823 if (pAd->CommonCfg.PhyMode == PHY_11B)
6824 {
6825 csr1.field.Ac2Txop = 192; // AC_VI: 192*32us ~= 6ms
6826 csr1.field.Ac3Txop = 96; // AC_VO: 96*32us ~= 3ms
6827 }
6828 else
6829 {
6830 csr1.field.Ac2Txop = 96; // AC_VI: 96*32us ~= 3ms
6831 csr1.field.Ac3Txop = 48; // AC_VO: 48*32us ~= 1.5ms
6832 }
6833 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
6834
6835 CwminCsr.word = 0;
6836 CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
6837 CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
6838 CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
6839 CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
6840 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
6841
6842 CwmaxCsr.word = 0;
6843 CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
6844 CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
6845 CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
6846 CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
6847 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
6848
6849 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
6850
6851 NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
6852 }
6853 else
6854 {
6855 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
6856 //========================================================
6857 // MAC Register has a copy.
6858 //========================================================
6859 //
6860 // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
6861 // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
6862 //
6863 //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
6864
6865 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
6866 Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
6867 Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
6868 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
6869
6870 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
6871 Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
6872 Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
6873 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
6874
6875 Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
6876 Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
6877 Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
6878 Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI];
6879#ifdef CONFIG_STA_SUPPORT
6880 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6881 {
6882 // Tuning for Wi-Fi WMM S06
6883 if (pAd->CommonCfg.bWiFiTest &&
6884 pEdcaParm->Aifsn[QID_AC_VI] == 10)
6885 Ac2Cfg.field.Aifsn -= 1;
6886
6887 // Tuning for TGn Wi-Fi 5.2.32
6888 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
6889 if (STA_TGN_WIFI_ON(pAd) &&
6890 pEdcaParm->Aifsn[QID_AC_VI] == 10)
6891 {
6892 Ac0Cfg.field.Aifsn = 3;
6893 Ac2Cfg.field.AcTxop = 5;
6894 }
6895 }
6896#endif // CONFIG_STA_SUPPORT //
6897
6898 Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
6899 Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
6900 Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
6901 Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
6902
6903//#ifdef WIFI_TEST
6904 if (pAd->CommonCfg.bWiFiTest)
6905 {
6906 if (Ac3Cfg.field.AcTxop == 102)
6907 {
6908 Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
6909 Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
6910 Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
6911 Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];
6912 Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
6913 } /* End of if */
6914 }
6915//#endif // WIFI_TEST //
6916
6917 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
6918 RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
6919 RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
6920 RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
6921
6922
6923 //========================================================
6924 // DMA Register has a copy too.
6925 //========================================================
6926 csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
6927 csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
6928 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
6929
6930 csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
6931 csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
6932 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
6933
6934 CwminCsr.word = 0;
6935 CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
6936 CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
6937 CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
6938#ifdef CONFIG_STA_SUPPORT
6939 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6940 CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
6941#endif // CONFIG_STA_SUPPORT //
6942 RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
6943
6944 CwmaxCsr.word = 0;
6945 CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
6946 CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
6947 CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
6948 CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
6949 RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
6950
6951 AifsnCsr.word = 0;
6952 AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
6953 AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
6954 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
6955#ifdef CONFIG_STA_SUPPORT
6956 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6957 {
6958 // Tuning for Wi-Fi WMM S06
6959 if (pAd->CommonCfg.bWiFiTest &&
6960 pEdcaParm->Aifsn[QID_AC_VI] == 10)
6961 AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
6962
6963 // Tuning for TGn Wi-Fi 5.2.32
6964 // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
6965 if (STA_TGN_WIFI_ON(pAd) &&
6966 pEdcaParm->Aifsn[QID_AC_VI] == 10)
6967 {
6968 AifsnCsr.field.Aifsn0 = 3;
6969 AifsnCsr.field.Aifsn2 = 7;
6970 }
6971 }
6972#endif // CONFIG_STA_SUPPORT //
6973
6974#ifdef CONFIG_STA_SUPPORT
6975 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
6976 AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
6977#endif // CONFIG_STA_SUPPORT //
6978 RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
6979
6980 NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
6981 if (!ADHOC_ON(pAd))
6982 {
6983 DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount));
6984 DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n",
6985 pEdcaParm->Aifsn[0],
6986 pEdcaParm->Cwmin[0],
6987 pEdcaParm->Cwmax[0],
6988 pEdcaParm->Txop[0]<<5,
6989 pEdcaParm->bACM[0]));
6990 DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n",
6991 pEdcaParm->Aifsn[1],
6992 pEdcaParm->Cwmin[1],
6993 pEdcaParm->Cwmax[1],
6994 pEdcaParm->Txop[1]<<5,
6995 pEdcaParm->bACM[1]));
6996 DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n",
6997 pEdcaParm->Aifsn[2],
6998 pEdcaParm->Cwmin[2],
6999 pEdcaParm->Cwmax[2],
7000 pEdcaParm->Txop[2]<<5,
7001 pEdcaParm->bACM[2]));
7002 DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n",
7003 pEdcaParm->Aifsn[3],
7004 pEdcaParm->Cwmin[3],
7005 pEdcaParm->Cwmax[3],
7006 pEdcaParm->Txop[3]<<5,
7007 pEdcaParm->bACM[3]));
7008 }
7009 }
7010}
7011
7012/*
7013 ==========================================================================
7014 Description:
7015
7016 IRQL = PASSIVE_LEVEL
7017 IRQL = DISPATCH_LEVEL
7018
7019 ==========================================================================
7020 */
7021VOID AsicSetSlotTime(
7022 IN PRTMP_ADAPTER pAd,
7023 IN BOOLEAN bUseShortSlotTime)
7024{
7025 ULONG SlotTime;
7026 UINT32 RegValue = 0;
7027
7028#ifdef CONFIG_STA_SUPPORT
7029 if (pAd->CommonCfg.Channel > 14)
7030 bUseShortSlotTime = TRUE;
7031#endif // CONFIG_STA_SUPPORT //
7032
7033 if (bUseShortSlotTime)
7034 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
7035 else
7036 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
7037
7038 SlotTime = (bUseShortSlotTime)? 9 : 20;
7039
7040#ifdef CONFIG_STA_SUPPORT
7041 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7042 {
7043 // force using short SLOT time for FAE to demo performance when TxBurst is ON
7044 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
7045#ifdef DOT11_N_SUPPORT
7046 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))
7047#endif // DOT11_N_SUPPORT //
7048 )
7049 {
7050 // In this case, we will think it is doing Wi-Fi test
7051 // And we will not set to short slot when bEnableTxBurst is TRUE.
7052 }
7053 else if (pAd->CommonCfg.bEnableTxBurst)
7054 SlotTime = 9;
7055 }
7056#endif // CONFIG_STA_SUPPORT //
7057
7058 //
7059 // For some reasons, always set it to short slot time.
7060 //
7061 // ToDo: Should consider capability with 11B
7062 //
7063#ifdef CONFIG_STA_SUPPORT
7064 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
7065 {
7066 if (pAd->StaCfg.BssType == BSS_ADHOC)
7067 SlotTime = 20;
7068 }
7069#endif // CONFIG_STA_SUPPORT //
7070
7071 RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
7072 RegValue = RegValue & 0xFFFFFF00;
7073
7074 RegValue |= SlotTime;
7075
7076 RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
7077}
7078
7079/*
7080 ========================================================================
7081 Description:
7082 Add Shared key information into ASIC.
7083 Update shared key, TxMic and RxMic to Asic Shared key table
7084 Update its cipherAlg to Asic Shared key Mode.
7085
7086 Return:
7087 ========================================================================
7088*/
7089VOID AsicAddSharedKeyEntry(
7090 IN PRTMP_ADAPTER pAd,
7091 IN UCHAR BssIndex,
7092 IN UCHAR KeyIdx,
7093 IN UCHAR CipherAlg,
7094 IN PUCHAR pKey,
7095 IN PUCHAR pTxMic,
7096 IN PUCHAR pRxMic)
7097{
7098 ULONG offset; //, csr0;
7099 SHAREDKEY_MODE_STRUC csr1;
7100#ifdef RT2860
7101 INT i;
7102#endif // RT2860 //
7103
7104 DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
7105//============================================================================================
7106
7107 DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
7108 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7109 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]));
7110 if (pRxMic)
7111 {
7112 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7113 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
7114 }
7115 if (pTxMic)
7116 {
7117 DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7118 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
7119 }
7120//============================================================================================
7121 //
7122 // fill key material - key + TX MIC + RX MIC
7123 //
7124#ifdef RT2860
7125 offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
7126 for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
7127 {
7128 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
7129 }
7130
7131 offset += MAX_LEN_OF_SHARE_KEY;
7132 if (pTxMic)
7133 {
7134 for (i=0; i<8; i++)
7135 {
7136 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
7137 }
7138 }
7139
7140 offset += 8;
7141 if (pRxMic)
7142 {
7143 for (i=0; i<8; i++)
7144 {
7145 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
7146 }
7147 }
7148#endif // RT2860 //
7149
7150
7151 //
7152 // Update cipher algorithm. WSTA always use BSS0
7153 //
7154 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
7155 DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
7156 if ((BssIndex%2) == 0)
7157 {
7158 if (KeyIdx == 0)
7159 csr1.field.Bss0Key0CipherAlg = CipherAlg;
7160 else if (KeyIdx == 1)
7161 csr1.field.Bss0Key1CipherAlg = CipherAlg;
7162 else if (KeyIdx == 2)
7163 csr1.field.Bss0Key2CipherAlg = CipherAlg;
7164 else
7165 csr1.field.Bss0Key3CipherAlg = CipherAlg;
7166 }
7167 else
7168 {
7169 if (KeyIdx == 0)
7170 csr1.field.Bss1Key0CipherAlg = CipherAlg;
7171 else if (KeyIdx == 1)
7172 csr1.field.Bss1Key1CipherAlg = CipherAlg;
7173 else if (KeyIdx == 2)
7174 csr1.field.Bss1Key2CipherAlg = CipherAlg;
7175 else
7176 csr1.field.Bss1Key3CipherAlg = CipherAlg;
7177 }
7178 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
7179 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
7180
7181}
7182
7183// IRQL = DISPATCH_LEVEL
7184VOID AsicRemoveSharedKeyEntry(
7185 IN PRTMP_ADAPTER pAd,
7186 IN UCHAR BssIndex,
7187 IN UCHAR KeyIdx)
7188{
7189 //ULONG SecCsr0;
7190 SHAREDKEY_MODE_STRUC csr1;
7191
7192 DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
7193
7194 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
7195 if ((BssIndex%2) == 0)
7196 {
7197 if (KeyIdx == 0)
7198 csr1.field.Bss0Key0CipherAlg = 0;
7199 else if (KeyIdx == 1)
7200 csr1.field.Bss0Key1CipherAlg = 0;
7201 else if (KeyIdx == 2)
7202 csr1.field.Bss0Key2CipherAlg = 0;
7203 else
7204 csr1.field.Bss0Key3CipherAlg = 0;
7205 }
7206 else
7207 {
7208 if (KeyIdx == 0)
7209 csr1.field.Bss1Key0CipherAlg = 0;
7210 else if (KeyIdx == 1)
7211 csr1.field.Bss1Key1CipherAlg = 0;
7212 else if (KeyIdx == 2)
7213 csr1.field.Bss1Key2CipherAlg = 0;
7214 else
7215 csr1.field.Bss1Key3CipherAlg = 0;
7216 }
7217 DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
7218 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
7219 ASSERT(BssIndex < 4);
7220 ASSERT(KeyIdx < 4);
7221
7222}
7223
7224
7225VOID AsicUpdateWCIDAttribute(
7226 IN PRTMP_ADAPTER pAd,
7227 IN USHORT WCID,
7228 IN UCHAR BssIndex,
7229 IN UCHAR CipherAlg,
7230 IN BOOLEAN bUsePairewiseKeyTable)
7231{
7232 ULONG WCIDAttri = 0, offset;
7233
7234 //
7235 // Update WCID attribute.
7236 // Only TxKey could update WCID attribute.
7237 //
7238 offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
7239 WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
7240 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
7241}
7242
7243VOID AsicUpdateWCIDIVEIV(
7244 IN PRTMP_ADAPTER pAd,
7245 IN USHORT WCID,
7246 IN ULONG uIV,
7247 IN ULONG uEIV)
7248{
7249 ULONG offset;
7250
7251 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
7252
7253 RTMP_IO_WRITE32(pAd, offset, uIV);
7254 RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
7255}
7256
7257VOID AsicUpdateRxWCIDTable(
7258 IN PRTMP_ADAPTER pAd,
7259 IN USHORT WCID,
7260 IN PUCHAR pAddr)
7261{
7262 ULONG offset;
7263 ULONG Addr;
7264
7265 offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
7266 Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
7267 RTMP_IO_WRITE32(pAd, offset, Addr);
7268 Addr = pAddr[4] + (pAddr[5] << 8);
7269 RTMP_IO_WRITE32(pAd, offset + 4, Addr);
7270}
7271
7272
7273/*
7274 ========================================================================
7275
7276 Routine Description:
7277 Set Cipher Key, Cipher algorithm, IV/EIV to Asic
7278
7279 Arguments:
7280 pAd Pointer to our adapter
7281 WCID WCID Entry number.
7282 BssIndex BSSID index, station or none multiple BSSID support
7283 this value should be 0.
7284 KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
7285 pCipherKey Pointer to Cipher Key.
7286 bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
7287 otherwise PairewiseKey table
7288 bTxKey This is the transmit key if enabled.
7289
7290 Return Value:
7291 None
7292
7293 Note:
7294 This routine will set the relative key stuff to Asic including WCID attribute,
7295 Cipher Key, Cipher algorithm and IV/EIV.
7296
7297 IV/EIV will be update if this CipherKey is the transmission key because
7298 ASIC will base on IV's KeyID value to select Cipher Key.
7299
7300 If bTxKey sets to FALSE, this is not the TX key, but it could be
7301 RX key
7302
7303 For AP mode bTxKey must be always set to TRUE.
7304 ========================================================================
7305*/
7306VOID AsicAddKeyEntry(
7307 IN PRTMP_ADAPTER pAd,
7308 IN USHORT WCID,
7309 IN UCHAR BssIndex,
7310 IN UCHAR KeyIdx,
7311 IN PCIPHER_KEY pCipherKey,
7312 IN BOOLEAN bUsePairewiseKeyTable,
7313 IN BOOLEAN bTxKey)
7314{
7315 ULONG offset;
7316 UCHAR IV4 = 0;
7317 PUCHAR pKey = pCipherKey->Key;
7318 PUCHAR pTxMic = pCipherKey->TxMic;
7319 PUCHAR pRxMic = pCipherKey->RxMic;
7320 PUCHAR pTxtsc = pCipherKey->TxTsc;
7321 UCHAR CipherAlg = pCipherKey->CipherAlg;
7322 SHAREDKEY_MODE_STRUC csr1;
7323#ifdef RT2860
7324 UCHAR i;
7325#endif // RT2860 //
7326
7327 DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
7328 //
7329 // 1.) decide key table offset
7330 //
7331 if (bUsePairewiseKeyTable)
7332 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
7333 else
7334 offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
7335
7336 //
7337 // 2.) Set Key to Asic
7338 //
7339 //for (i = 0; i < KeyLen; i++)
7340#ifdef RT2860
7341 for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
7342 {
7343 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
7344 }
7345 offset += MAX_LEN_OF_PEER_KEY;
7346
7347 //
7348 // 3.) Set MIC key if available
7349 //
7350 if (pTxMic)
7351 {
7352 for (i = 0; i < 8; i++)
7353 {
7354 RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
7355 }
7356 }
7357 offset += LEN_TKIP_TXMICK;
7358
7359 if (pRxMic)
7360 {
7361 for (i = 0; i < 8; i++)
7362 {
7363 RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
7364 }
7365 }
7366#endif // RT2860 //
7367
7368
7369 //
7370 // 4.) Modify IV/EIV if needs
7371 // This will force Asic to use this key ID by setting IV.
7372 //
7373 if (bTxKey)
7374 {
7375#ifdef RT2860
7376 offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
7377 //
7378 // Write IV
7379 //
7380 RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
7381 RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
7382 RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
7383
7384 IV4 = (KeyIdx << 6);
7385 if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
7386 IV4 |= 0x20; // turn on extension bit means EIV existence
7387
7388 RTMP_IO_WRITE8(pAd, offset + 3, IV4);
7389
7390 //
7391 // Write EIV
7392 //
7393 offset += 4;
7394 for (i = 0; i < 4; i++)
7395 {
7396 RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
7397 }
7398#endif // RT2860 //
7399
7400 AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
7401 }
7402
7403 if (!bUsePairewiseKeyTable)
7404 {
7405 //
7406 // Only update the shared key security mode
7407 //
7408 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
7409 if ((BssIndex % 2) == 0)
7410 {
7411 if (KeyIdx == 0)
7412 csr1.field.Bss0Key0CipherAlg = CipherAlg;
7413 else if (KeyIdx == 1)
7414 csr1.field.Bss0Key1CipherAlg = CipherAlg;
7415 else if (KeyIdx == 2)
7416 csr1.field.Bss0Key2CipherAlg = CipherAlg;
7417 else
7418 csr1.field.Bss0Key3CipherAlg = CipherAlg;
7419 }
7420 else
7421 {
7422 if (KeyIdx == 0)
7423 csr1.field.Bss1Key0CipherAlg = CipherAlg;
7424 else if (KeyIdx == 1)
7425 csr1.field.Bss1Key1CipherAlg = CipherAlg;
7426 else if (KeyIdx == 2)
7427 csr1.field.Bss1Key2CipherAlg = CipherAlg;
7428 else
7429 csr1.field.Bss1Key3CipherAlg = CipherAlg;
7430 }
7431 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
7432 }
7433
7434 DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
7435}
7436
7437
7438/*
7439 ========================================================================
7440 Description:
7441 Add Pair-wise key material into ASIC.
7442 Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
7443
7444 Return:
7445 ========================================================================
7446*/
7447VOID AsicAddPairwiseKeyEntry(
7448 IN PRTMP_ADAPTER pAd,
7449 IN PUCHAR pAddr,
7450 IN UCHAR WCID,
7451 IN CIPHER_KEY *pCipherKey)
7452{
7453 INT i;
7454 ULONG offset;
7455 PUCHAR pKey = pCipherKey->Key;
7456 PUCHAR pTxMic = pCipherKey->TxMic;
7457 PUCHAR pRxMic = pCipherKey->RxMic;
7458#ifdef DBG
7459 UCHAR CipherAlg = pCipherKey->CipherAlg;
7460#endif // DBG //
7461
7462 // EKEY
7463 offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
7464#ifdef RT2860
7465 for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
7466 {
7467 RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
7468 }
7469#endif // RT2860 //
7470 for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
7471 {
7472 UINT32 Value;
7473 RTMP_IO_READ32(pAd, offset + i, &Value);
7474 }
7475
7476 offset += MAX_LEN_OF_PEER_KEY;
7477
7478 // MIC KEY
7479 if (pTxMic)
7480 {
7481#ifdef RT2860
7482 for (i=0; i<8; i++)
7483 {
7484 RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
7485 }
7486#endif // RT2860 //
7487 }
7488 offset += 8;
7489 if (pRxMic)
7490 {
7491#ifdef RT2860
7492 for (i=0; i<8; i++)
7493 {
7494 RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
7495 }
7496#endif // RT2860 //
7497 }
7498
7499 DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
7500 DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7501 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]));
7502 if (pRxMic)
7503 {
7504 DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7505 pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
7506 }
7507 if (pTxMic)
7508 {
7509 DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
7510 pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
7511 }
7512}
7513/*
7514 ========================================================================
7515 Description:
7516 Remove Pair-wise key material from ASIC.
7517
7518 Return:
7519 ========================================================================
7520*/
7521VOID AsicRemovePairwiseKeyEntry(
7522 IN PRTMP_ADAPTER pAd,
7523 IN UCHAR BssIdx,
7524 IN UCHAR Wcid)
7525{
7526 ULONG WCIDAttri;
7527 USHORT offset;
7528
7529 // re-set the entry's WCID attribute as OPEN-NONE.
7530 offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
7531 WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
7532 RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
7533}
7534
7535BOOLEAN AsicSendCommandToMcu(
7536 IN PRTMP_ADAPTER pAd,
7537 IN UCHAR Command,
7538 IN UCHAR Token,
7539 IN UCHAR Arg0,
7540 IN UCHAR Arg1)
7541{
7542 HOST_CMD_CSR_STRUC H2MCmd;
7543 H2M_MAILBOX_STRUC H2MMailbox;
7544 ULONG i = 0;
7545#ifdef RT2860
7546#ifdef RALINK_ATE
7547 static UINT32 j = 0;
7548#endif // RALINK_ATE //
7549#endif // RT2860 //
7550 do
7551 {
7552 RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
7553 if (H2MMailbox.field.Owner == 0)
7554 break;
7555
7556 RTMPusecDelay(2);
7557 } while(i++ < 100);
7558
7559 if (i >= 100)
7560 {
7561#ifdef RT2860
7562#ifdef RALINK_ATE
7563 if (pAd->ate.bFWLoading == TRUE)
7564 {
7565 /* reloading firmware when received iwpriv cmd "ATE=ATESTOP" */
7566 if (j > 0)
7567 {
7568 if (j % 64 != 0)
7569 {
7570 DBGPRINT(RT_DEBUG_ERROR, ("#"));
7571 }
7572 else
7573 {
7574 DBGPRINT(RT_DEBUG_ERROR, ("\n"));
7575 }
7576 ++j;
7577 }
7578 else if (j == 0)
7579 {
7580 DBGPRINT(RT_DEBUG_ERROR, ("Loading firmware. Please wait for a moment...\n"));
7581 ++j;
7582 }
7583 }
7584 else
7585#endif // RALINK_ATE //
7586#endif // RT2860 //
7587 {
7588 DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
7589 }
7590 return FALSE;
7591 }
7592
7593#ifdef RT2860
7594#ifdef RALINK_ATE
7595 else if (pAd->ate.bFWLoading == TRUE)
7596 {
7597 /* reloading of firmware is completed */
7598 pAd->ate.bFWLoading = FALSE;
7599 DBGPRINT(RT_DEBUG_ERROR, ("\n"));
7600 j = 0;
7601 }
7602#endif // RALINK_ATE //
7603#endif // RT2860 //
7604
7605 H2MMailbox.field.Owner = 1; // pass ownership to MCU
7606 H2MMailbox.field.CmdToken = Token;
7607 H2MMailbox.field.HighByte = Arg1;
7608 H2MMailbox.field.LowByte = Arg0;
7609 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
7610
7611 H2MCmd.word = 0;
7612 H2MCmd.field.HostCommand = Command;
7613 RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
7614
7615 if (Command != 0x80)
7616 {
7617 }
7618
7619 return TRUE;
7620}
7621
7622#ifdef RT2860
7623BOOLEAN AsicCheckCommanOk(
7624 IN PRTMP_ADAPTER pAd,
7625 IN UCHAR Command)
7626{
7627 UINT32 CmdStatus = 0, CID = 0, i;
7628 UINT32 ThisCIDMask = 0;
7629
7630 i = 0;
7631 do
7632 {
7633 RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
7634 // Find where the command is. Because this is randomly specified by firmware.
7635 if ((CID & CID0MASK) == Command)
7636 {
7637 ThisCIDMask = CID0MASK;
7638 break;
7639 }
7640 else if ((((CID & CID1MASK)>>8) & 0xff) == Command)
7641 {
7642 ThisCIDMask = CID1MASK;
7643 break;
7644 }
7645 else if ((((CID & CID2MASK)>>16) & 0xff) == Command)
7646 {
7647 ThisCIDMask = CID2MASK;
7648 break;
7649 }
7650 else if ((((CID & CID3MASK)>>24) & 0xff) == Command)
7651 {
7652 ThisCIDMask = CID3MASK;
7653 break;
7654 }
7655
7656 RTMPusecDelay(100);
7657 i++;
7658 }while (i < 200);
7659
7660 // Get CommandStatus Value
7661 RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
7662
7663 // This command's status is at the same position as command. So AND command position's bitmask to read status.
7664 if (i < 200)
7665 {
7666 // If Status is 1, the comamnd is success.
7667 if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100)
7668 || ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000))
7669 {
7670 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
7671 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
7672 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
7673 return TRUE;
7674 }
7675 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus));
7676 }
7677 else
7678 {
7679 DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus));
7680 }
7681 // Clear Command and Status.
7682 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
7683 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
7684
7685 return FALSE;
7686}
7687#endif // RT2860 //
7688
7689/*
7690 ========================================================================
7691
7692 Routine Description:
7693 Verify the support rate for different PHY type
7694
7695 Arguments:
7696 pAd Pointer to our adapter
7697
7698 Return Value:
7699 None
7700
7701 IRQL = PASSIVE_LEVEL
7702
7703 ========================================================================
7704*/
7705VOID RTMPCheckRates(
7706 IN PRTMP_ADAPTER pAd,
7707 IN OUT UCHAR SupRate[],
7708 IN OUT UCHAR *SupRateLen)
7709{
7710 UCHAR RateIdx, i, j;
7711 UCHAR NewRate[12], NewRateLen;
7712
7713 NewRateLen = 0;
7714
7715 if (pAd->CommonCfg.PhyMode == PHY_11B)
7716 RateIdx = 4;
7717 else
7718 RateIdx = 12;
7719
7720 // Check for support rates exclude basic rate bit
7721 for (i = 0; i < *SupRateLen; i++)
7722 for (j = 0; j < RateIdx; j++)
7723 if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
7724 NewRate[NewRateLen++] = SupRate[i];
7725
7726 *SupRateLen = NewRateLen;
7727 NdisMoveMemory(SupRate, NewRate, NewRateLen);
7728}
7729
7730#ifdef CONFIG_STA_SUPPORT
7731#ifdef DOT11_N_SUPPORT
7732BOOLEAN RTMPCheckChannel(
7733 IN PRTMP_ADAPTER pAd,
7734 IN UCHAR CentralChannel,
7735 IN UCHAR Channel)
7736{
7737 UCHAR k;
7738 UCHAR UpperChannel = 0, LowerChannel = 0;
7739 UCHAR NoEffectChannelinList = 0;
7740
7741 // Find upper and lower channel according to 40MHz current operation.
7742 if (CentralChannel < Channel)
7743 {
7744 UpperChannel = Channel;
7745 if (CentralChannel > 2)
7746 LowerChannel = CentralChannel - 2;
7747 else
7748 return FALSE;
7749 }
7750 else if (CentralChannel > Channel)
7751 {
7752 UpperChannel = CentralChannel + 2;
7753 LowerChannel = Channel;
7754 }
7755
7756 for (k = 0;k < pAd->ChannelListNum;k++)
7757 {
7758 if (pAd->ChannelList[k].Channel == UpperChannel)
7759 {
7760 NoEffectChannelinList ++;
7761 }
7762 if (pAd->ChannelList[k].Channel == LowerChannel)
7763 {
7764 NoEffectChannelinList ++;
7765 }
7766 }
7767
7768 DBGPRINT(RT_DEBUG_TRACE,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList));
7769 if (NoEffectChannelinList == 2)
7770 return TRUE;
7771 else
7772 return FALSE;
7773}
7774
7775/*
7776 ========================================================================
7777
7778 Routine Description:
7779 Verify the support rate for HT phy type
7780
7781 Arguments:
7782 pAd Pointer to our adapter
7783
7784 Return Value:
7785 FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability. (AP Mode)
7786
7787 IRQL = PASSIVE_LEVEL
7788
7789 ========================================================================
7790*/
7791BOOLEAN RTMPCheckHt(
7792 IN PRTMP_ADAPTER pAd,
7793 IN UCHAR Wcid,
7794 IN HT_CAPABILITY_IE *pHtCapability,
7795 IN ADD_HT_INFO_IE *pAddHtInfo)
7796{
7797 if (Wcid >= MAX_LEN_OF_MAC_TABLE)
7798 return FALSE;
7799
7800 // If use AMSDU, set flag.
7801 if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
7802 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_AMSDU_INUSED);
7803 // Save Peer Capability
7804 if (pHtCapability->HtCapInfo.ShortGIfor20)
7805 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI20_CAPABLE);
7806 if (pHtCapability->HtCapInfo.ShortGIfor40)
7807 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI40_CAPABLE);
7808 if (pHtCapability->HtCapInfo.TxSTBC)
7809 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_TxSTBC_CAPABLE);
7810 if (pHtCapability->HtCapInfo.RxSTBC)
7811 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RxSTBC_CAPABLE);
7812 if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
7813 {
7814 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RDG_CAPABLE);
7815 }
7816
7817 if (Wcid < MAX_LEN_OF_MAC_TABLE)
7818 {
7819 pAd->MacTab.Content[Wcid].MpduDensity = pHtCapability->HtCapParm.MpduDensity;
7820 }
7821
7822 // Will check ChannelWidth for MCSSet[4] below
7823 pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
7824 switch (pAd->CommonCfg.RxStream)
7825 {
7826 case 1:
7827 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
7828 pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
7829 pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
7830 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
7831 break;
7832 case 2:
7833 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
7834 pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
7835 pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
7836 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
7837 break;
7838 case 3:
7839 pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
7840 pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
7841 pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
7842 pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
7843 break;
7844 }
7845
7846 pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.ChannelWidth;
7847
7848 DBGPRINT(RT_DEBUG_TRACE, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
7849 pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, pAddHtInfo->AddHtInfo.RecomWidth, pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
7850 pAd->NicConfig2.field.BW40MAvailForA, pAd->NicConfig2.field.BW40MAvailForG, pAd->CommonCfg.PhyMode));
7851
7852 pAd->MlmeAux.HtCapability.HtCapInfo.GF = pHtCapability->HtCapInfo.GF &pAd->CommonCfg.DesiredHtPhy.GF;
7853
7854 // Send Assoc Req with my HT capability.
7855 pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize = pAd->CommonCfg.DesiredHtPhy.AmsduSize;
7856 pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs = pAd->CommonCfg.DesiredHtPhy.MimoPs;
7857 pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20);
7858 pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40);
7859 pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC = (pAd->CommonCfg.DesiredHtPhy.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC);
7860 pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC = (pAd->CommonCfg.DesiredHtPhy.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC);
7861 pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
7862 pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
7863 pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
7864 pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
7865 if (pAd->CommonCfg.bRdg)
7866 {
7867 pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport;
7868 pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
7869 }
7870
7871 if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
7872 pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0; // BW20 can't transmit MCS32
7873
7874 COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
7875 return TRUE;
7876}
7877#endif // DOT11_N_SUPPORT //
7878#endif // CONFIG_STA_SUPPORT //
7879
7880/*
7881 ========================================================================
7882
7883 Routine Description:
7884 Verify the support rate for different PHY type
7885
7886 Arguments:
7887 pAd Pointer to our adapter
7888
7889 Return Value:
7890 None
7891
7892 IRQL = PASSIVE_LEVEL
7893
7894 ========================================================================
7895*/
7896VOID RTMPUpdateMlmeRate(
7897 IN PRTMP_ADAPTER pAd)
7898{
7899 UCHAR MinimumRate;
7900 UCHAR ProperMlmeRate; //= RATE_54;
7901 UCHAR i, j, RateIdx = 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
7902 BOOLEAN bMatch = FALSE;
7903
7904 switch (pAd->CommonCfg.PhyMode)
7905 {
7906 case PHY_11B:
7907 ProperMlmeRate = RATE_11;
7908 MinimumRate = RATE_1;
7909 break;
7910 case PHY_11BG_MIXED:
7911#ifdef DOT11_N_SUPPORT
7912 case PHY_11ABGN_MIXED:
7913 case PHY_11BGN_MIXED:
7914#endif // DOT11_N_SUPPORT //
7915 if ((pAd->MlmeAux.SupRateLen == 4) &&
7916 (pAd->MlmeAux.ExtRateLen == 0))
7917 // B only AP
7918 ProperMlmeRate = RATE_11;
7919 else
7920 ProperMlmeRate = RATE_24;
7921
7922 if (pAd->MlmeAux.Channel <= 14)
7923 MinimumRate = RATE_1;
7924 else
7925 MinimumRate = RATE_6;
7926 break;
7927 case PHY_11A:
7928#ifdef DOT11_N_SUPPORT
7929 case PHY_11N_2_4G: // rt2860 need to check mlmerate for 802.11n
7930 case PHY_11GN_MIXED:
7931 case PHY_11AGN_MIXED:
7932 case PHY_11AN_MIXED:
7933 case PHY_11N_5G:
7934#endif // DOT11_N_SUPPORT //
7935 ProperMlmeRate = RATE_24;
7936 MinimumRate = RATE_6;
7937 break;
7938 case PHY_11ABG_MIXED:
7939 ProperMlmeRate = RATE_24;
7940 if (pAd->MlmeAux.Channel <= 14)
7941 MinimumRate = RATE_1;
7942 else
7943 MinimumRate = RATE_6;
7944 break;
7945 default: // error
7946 ProperMlmeRate = RATE_1;
7947 MinimumRate = RATE_1;
7948 break;
7949 }
7950
7951 for (i = 0; i < pAd->MlmeAux.SupRateLen; i++)
7952 {
7953 for (j = 0; j < RateIdx; j++)
7954 {
7955 if ((pAd->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
7956 {
7957 if (j == ProperMlmeRate)
7958 {
7959 bMatch = TRUE;
7960 break;
7961 }
7962 }
7963 }
7964
7965 if (bMatch)
7966 break;
7967 }
7968
7969 if (bMatch == FALSE)
7970 {
7971 for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++)
7972 {
7973 for (j = 0; j < RateIdx; j++)
7974 {
7975 if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
7976 {
7977 if (j == ProperMlmeRate)
7978 {
7979 bMatch = TRUE;
7980 break;
7981 }
7982 }
7983 }
7984
7985 if (bMatch)
7986 break;
7987 }
7988 }
7989
7990 if (bMatch == FALSE)
7991 {
7992 ProperMlmeRate = MinimumRate;
7993 }
7994
7995 pAd->CommonCfg.MlmeRate = MinimumRate;
7996 pAd->CommonCfg.RtsRate = ProperMlmeRate;
7997 if (pAd->CommonCfg.MlmeRate >= RATE_6)
7998 {
7999 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
8000 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
8001 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
8002 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
8003 }
8004 else
8005 {
8006 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
8007 pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
8008 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK;
8009 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate;
8010 }
8011
8012 DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n" , pAd->CommonCfg.MlmeTransmit.word));
8013}
8014
8015CHAR RTMPMaxRssi(
8016 IN PRTMP_ADAPTER pAd,
8017 IN CHAR Rssi0,
8018 IN CHAR Rssi1,
8019 IN CHAR Rssi2)
8020{
8021 CHAR larger = -127;
8022
8023 if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0))
8024 {
8025 larger = Rssi0;
8026 }
8027
8028 if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0))
8029 {
8030 larger = max(Rssi0, Rssi1);
8031 }
8032
8033 if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0))
8034 {
8035 larger = max(larger, Rssi2);
8036 }
8037
8038 if (larger == -127)
8039 larger = 0;
8040
8041 return larger;
8042}
8043
8044/*
8045 ========================================================================
8046 Routine Description:
8047 Periodic evaluate antenna link status
8048
8049 Arguments:
8050 pAd - Adapter pointer
8051
8052 Return Value:
8053 None
8054
8055 ========================================================================
8056*/
8057VOID AsicEvaluateRxAnt(
8058 IN PRTMP_ADAPTER pAd)
8059{
8060 UCHAR BBPR3 = 0;
8061
8062#ifdef RALINK_ATE
8063 if (ATE_ON(pAd))
8064 return;
8065#endif // RALINK_ATE //
8066
8067
8068#ifdef CONFIG_STA_SUPPORT
8069 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8070 {
8071 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
8072 fRTMP_ADAPTER_HALT_IN_PROGRESS |
8073 fRTMP_ADAPTER_RADIO_OFF |
8074 fRTMP_ADAPTER_NIC_NOT_EXIST |
8075 fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
8076 return;
8077
8078 if (pAd->StaCfg.Psm == PWR_SAVE)
8079 return;
8080 }
8081#endif // CONFIG_STA_SUPPORT //
8082
8083 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
8084 BBPR3 &= (~0x18);
8085 if(pAd->Antenna.field.RxPath == 3)
8086 {
8087 BBPR3 |= (0x10);
8088 }
8089 else if(pAd->Antenna.field.RxPath == 2)
8090 {
8091 BBPR3 |= (0x8);
8092 }
8093 else if(pAd->Antenna.field.RxPath == 1)
8094 {
8095 BBPR3 |= (0x0);
8096 }
8097 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8098#ifdef CONFIG_STA_SUPPORT
8099#ifdef RT2860
8100 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8101 pAd->StaCfg.BBPR3 = BBPR3;
8102#endif // RT2860 //
8103#endif // CONFIG_STA_SUPPORT //
8104 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
8105 )
8106 {
8107 ULONG TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
8108 pAd->RalinkCounters.OneSecTxRetryOkCount +
8109 pAd->RalinkCounters.OneSecTxFailCount;
8110
8111 if (TxTotalCnt > 50)
8112 {
8113 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
8114 pAd->Mlme.bLowThroughput = FALSE;
8115 }
8116 else
8117 {
8118 RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
8119 pAd->Mlme.bLowThroughput = TRUE;
8120 }
8121 }
8122}
8123
8124/*
8125 ========================================================================
8126 Routine Description:
8127 After evaluation, check antenna link status
8128
8129 Arguments:
8130 pAd - Adapter pointer
8131
8132 Return Value:
8133 None
8134
8135 ========================================================================
8136*/
8137VOID AsicRxAntEvalTimeout(
8138 IN PVOID SystemSpecific1,
8139 IN PVOID FunctionContext,
8140 IN PVOID SystemSpecific2,
8141 IN PVOID SystemSpecific3)
8142{
8143 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
8144#ifdef CONFIG_STA_SUPPORT
8145 UCHAR BBPR3 = 0;
8146 CHAR larger = -127, rssi0, rssi1, rssi2;
8147#endif // CONFIG_STA_SUPPORT //
8148
8149#ifdef RALINK_ATE
8150 if (ATE_ON(pAd))
8151 return;
8152#endif // RALINK_ATE //
8153
8154
8155#ifdef CONFIG_STA_SUPPORT
8156 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8157 {
8158 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
8159 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
8160 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF) ||
8161 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
8162 return;
8163
8164 if (pAd->StaCfg.Psm == PWR_SAVE)
8165 return;
8166
8167
8168 // if the traffic is low, use average rssi as the criteria
8169 if (pAd->Mlme.bLowThroughput == TRUE)
8170 {
8171 rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
8172 rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
8173 rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
8174 }
8175 else
8176 {
8177 rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
8178 rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
8179 rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
8180 }
8181
8182 if(pAd->Antenna.field.RxPath == 3)
8183 {
8184 larger = max(rssi0, rssi1);
8185
8186 if (larger > (rssi2 + 20))
8187 pAd->Mlme.RealRxPath = 2;
8188 else
8189 pAd->Mlme.RealRxPath = 3;
8190 }
8191 else if(pAd->Antenna.field.RxPath == 2)
8192 {
8193 if (rssi0 > (rssi1 + 20))
8194 pAd->Mlme.RealRxPath = 1;
8195 else
8196 pAd->Mlme.RealRxPath = 2;
8197 }
8198
8199 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
8200 BBPR3 &= (~0x18);
8201 if(pAd->Mlme.RealRxPath == 3)
8202 {
8203 BBPR3 |= (0x10);
8204 }
8205 else if(pAd->Mlme.RealRxPath == 2)
8206 {
8207 BBPR3 |= (0x8);
8208 }
8209 else if(pAd->Mlme.RealRxPath == 1)
8210 {
8211 BBPR3 |= (0x0);
8212 }
8213 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
8214#ifdef RT2860
8215 pAd->StaCfg.BBPR3 = BBPR3;
8216#endif // RT2860 //
8217 }
8218
8219#endif // CONFIG_STA_SUPPORT //
8220
8221}
8222
8223
8224
8225VOID APSDPeriodicExec(
8226 IN PVOID SystemSpecific1,
8227 IN PVOID FunctionContext,
8228 IN PVOID SystemSpecific2,
8229 IN PVOID SystemSpecific3)
8230{
8231 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
8232
8233 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
8234 return;
8235
8236 pAd->CommonCfg.TriggerTimerCount++;
8237
8238}
8239
8240/*
8241 ========================================================================
8242 Routine Description:
8243 Set/reset MAC registers according to bPiggyBack parameter
8244
8245 Arguments:
8246 pAd - Adapter pointer
8247 bPiggyBack - Enable / Disable Piggy-Back
8248
8249 Return Value:
8250 None
8251
8252 ========================================================================
8253*/
8254VOID RTMPSetPiggyBack(
8255 IN PRTMP_ADAPTER pAd,
8256 IN BOOLEAN bPiggyBack)
8257{
8258 TX_LINK_CFG_STRUC TxLinkCfg;
8259
8260 RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
8261
8262 TxLinkCfg.field.TxCFAckEn = bPiggyBack;
8263 RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
8264}
8265
8266/*
8267 ========================================================================
8268 Routine Description:
8269 check if this entry need to switch rate automatically
8270
8271 Arguments:
8272 pAd
8273 pEntry
8274
8275 Return Value:
8276 TURE
8277 FALSE
8278
8279 ========================================================================
8280*/
8281BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
8282 IN PRTMP_ADAPTER pAd,
8283 IN PMAC_TABLE_ENTRY pEntry)
8284{
8285 BOOLEAN result = TRUE;
8286
8287
8288#ifdef CONFIG_STA_SUPPORT
8289 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8290 {
8291 // only associated STA counts
8292 if (pEntry && (pEntry->ValidAsCLI) && (pEntry->Sst == SST_ASSOC))
8293 {
8294 result = pAd->StaCfg.bAutoTxRateSwitch;
8295 }
8296 else
8297 result = FALSE;
8298
8299#ifdef QOS_DLS_SUPPORT
8300 if (pEntry && (pEntry->ValidAsDls))
8301 result = pAd->StaCfg.bAutoTxRateSwitch;
8302#endif // QOS_DLS_SUPPORT //
8303 }
8304#endif // CONFIG_STA_SUPPORT //
8305
8306
8307
8308 return result;
8309}
8310
8311
8312BOOLEAN RTMPAutoRateSwitchCheck(
8313 IN PRTMP_ADAPTER pAd)
8314{
8315
8316#ifdef CONFIG_STA_SUPPORT
8317 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8318 {
8319 if (pAd->StaCfg.bAutoTxRateSwitch)
8320 return TRUE;
8321 }
8322#endif // CONFIG_STA_SUPPORT //
8323 return FALSE;
8324}
8325
8326
8327/*
8328 ========================================================================
8329 Routine Description:
8330 check if this entry need to fix tx legacy rate
8331
8332 Arguments:
8333 pAd
8334 pEntry
8335
8336 Return Value:
8337 TURE
8338 FALSE
8339
8340 ========================================================================
8341*/
8342UCHAR RTMPStaFixedTxMode(
8343 IN PRTMP_ADAPTER pAd,
8344 IN PMAC_TABLE_ENTRY pEntry)
8345{
8346 UCHAR tx_mode = FIXED_TXMODE_HT;
8347
8348
8349#ifdef CONFIG_STA_SUPPORT
8350 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
8351 {
8352 tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
8353 }
8354#endif // CONFIG_STA_SUPPORT //
8355
8356 return tx_mode;
8357}
8358
8359/*
8360 ========================================================================
8361 Routine Description:
8362 Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
8363
8364 Arguments:
8365 pAd
8366 pEntry
8367
8368 Return Value:
8369 TURE
8370 FALSE
8371
8372 ========================================================================
8373*/
8374VOID RTMPUpdateLegacyTxSetting(
8375 UCHAR fixed_tx_mode,
8376 PMAC_TABLE_ENTRY pEntry)
8377{
8378 HTTRANSMIT_SETTING TransmitSetting;
8379
8380 if (fixed_tx_mode == FIXED_TXMODE_HT)
8381 return;
8382
8383 TransmitSetting.word = 0;
8384
8385 TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
8386 TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
8387
8388 if (fixed_tx_mode == FIXED_TXMODE_CCK)
8389 {
8390 TransmitSetting.field.MODE = MODE_CCK;
8391 // CCK mode allow MCS 0~3
8392 if (TransmitSetting.field.MCS > MCS_3)
8393 TransmitSetting.field.MCS = MCS_3;
8394 }
8395 else
8396 {
8397 TransmitSetting.field.MODE = MODE_OFDM;
8398 // OFDM mode allow MCS 0~7
8399 if (TransmitSetting.field.MCS > MCS_7)
8400 TransmitSetting.field.MCS = MCS_7;
8401 }
8402
8403 if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE)
8404 {
8405 pEntry->HTPhyMode.word = TransmitSetting.word;
8406 DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
8407 pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS));
8408 }
8409}
8410
8411#ifdef CONFIG_STA_SUPPORT
8412/*
8413 ==========================================================================
8414 Description:
8415 dynamic tune BBP R66 to find a balance between sensibility and
8416 noise isolation
8417
8418 IRQL = DISPATCH_LEVEL
8419
8420 ==========================================================================
8421 */
8422VOID AsicStaBbpTuning(
8423 IN PRTMP_ADAPTER pAd)
8424{
8425 UCHAR OrigR66Value = 0, R66;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
8426 CHAR Rssi;
8427
8428 // 2860C did not support Fase CCA, therefore can't tune
8429 if (pAd->MACVersion == 0x28600100)
8430 return;
8431
8432 //
8433 // work as a STA
8434 //
8435 if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) // no R66 tuning when SCANNING
8436 return;
8437
8438 if ((pAd->OpMode == OPMODE_STA)
8439 && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
8440 )
8441 && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
8442#ifdef RT2860
8443 && (pAd->bPCIclkOff == FALSE)
8444#endif // RT2860 //
8445 )
8446 {
8447 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
8448 R66 = OrigR66Value;
8449
8450 if (pAd->Antenna.field.RxPath > 1)
8451 Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
8452 else
8453 Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
8454
8455 if (pAd->LatchRfRegs.Channel <= 14)
8456 { //BG band
8457 {
8458 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8459 {
8460 R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
8461 if (OrigR66Value != R66)
8462 {
8463 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8464 }
8465 }
8466 else
8467 {
8468 R66 = 0x2E + GET_LNA_GAIN(pAd);
8469 if (OrigR66Value != R66)
8470 {
8471 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8472 }
8473 }
8474 }
8475 }
8476 else
8477 { //A band
8478 if (pAd->CommonCfg.BBPCurrentBW == BW_20)
8479 {
8480 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8481 {
8482 R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
8483 if (OrigR66Value != R66)
8484 {
8485 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8486 }
8487 }
8488 else
8489 {
8490 R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3;
8491 if (OrigR66Value != R66)
8492 {
8493 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8494 }
8495 }
8496 }
8497 else
8498 {
8499 if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
8500 {
8501 R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
8502 if (OrigR66Value != R66)
8503 {
8504 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8505 }
8506 }
8507 else
8508 {
8509 R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3;
8510 if (OrigR66Value != R66)
8511 {
8512 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8513 }
8514 }
8515 }
8516 }
8517
8518
8519 }
8520}
8521#endif // CONFIG_STA_SUPPORT //
8522
8523VOID RTMPSetAGCInitValue(
8524 IN PRTMP_ADAPTER pAd,
8525 IN UCHAR BandWidth)
8526{
8527 UCHAR R66 = 0x30;
8528
8529 if (pAd->LatchRfRegs.Channel <= 14)
8530 { // BG band
8531 R66 = 0x2E + GET_LNA_GAIN(pAd);
8532 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8533 }
8534 else
8535 { //A band
8536 if (BandWidth == BW_20)
8537 {
8538 R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
8539 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8540 }
8541#ifdef DOT11_N_SUPPORT
8542 else
8543 {
8544 R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
8545 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
8546 }
8547#endif // DOT11_N_SUPPORT //
8548 }
8549
8550}
8551
8552VOID AsicTurnOffRFClk(
8553 IN PRTMP_ADAPTER pAd,
8554 IN UCHAR Channel)
8555{
8556
8557 // RF R2 bit 18 = 0
8558 UINT32 R1 = 0, R2 = 0, R3 = 0;
8559 UCHAR index;
8560 RTMP_RF_REGS *RFRegTable;
8561
8562 RFRegTable = RF2850RegTable;
8563
8564 switch (pAd->RfIcType)
8565 {
8566 case RFIC_2820:
8567 case RFIC_2850:
8568 case RFIC_2720:
8569 case RFIC_2750:
8570
8571 for (index = 0; index < NUM_OF_2850_CHNL; index++)
8572 {
8573 if (Channel == RFRegTable[index].Channel)
8574 {
8575 R1 = RFRegTable[index].R1 & 0xffffdfff;
8576 R2 = RFRegTable[index].R2 & 0xfffbffff;
8577 R3 = RFRegTable[index].R3 & 0xfff3ffff;
8578
8579 RTMP_RF_IO_WRITE32(pAd, R1);
8580 RTMP_RF_IO_WRITE32(pAd, R2);
8581
8582 // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
8583 // Set RF R2 bit18=0, R3 bit[18:19]=0
8584 //if (pAd->StaCfg.bRadio == FALSE)
8585 if (1)
8586 {
8587 RTMP_RF_IO_WRITE32(pAd, R3);
8588
8589 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
8590 Channel, pAd->RfIcType, R2, R3));
8591 }
8592 else
8593 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
8594 Channel, pAd->RfIcType, R2));
8595 break;
8596 }
8597 }
8598 break;
8599
8600 default:
8601 break;
8602 }
8603}
8604
8605
8606VOID AsicTurnOnRFClk(
8607 IN PRTMP_ADAPTER pAd,
8608 IN UCHAR Channel)
8609{
8610
8611 // RF R2 bit 18 = 0
8612 UINT32 R1 = 0, R2 = 0, R3 = 0;
8613 UCHAR index;
8614 RTMP_RF_REGS *RFRegTable;
8615
8616 RFRegTable = RF2850RegTable;
8617
8618 switch (pAd->RfIcType)
8619 {
8620 case RFIC_2820:
8621 case RFIC_2850:
8622 case RFIC_2720:
8623 case RFIC_2750:
8624
8625 for (index = 0; index < NUM_OF_2850_CHNL; index++)
8626 {
8627 if (Channel == RFRegTable[index].Channel)
8628 {
8629 R3 = pAd->LatchRfRegs.R3;
8630 R3 &= 0xfff3ffff;
8631 R3 |= 0x00080000;
8632 RTMP_RF_IO_WRITE32(pAd, R3);
8633
8634 R1 = RFRegTable[index].R1;
8635 RTMP_RF_IO_WRITE32(pAd, R1);
8636
8637 R2 = RFRegTable[index].R2;
8638 if (pAd->Antenna.field.TxPath == 1)
8639 {
8640 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
8641 }
8642
8643 if (pAd->Antenna.field.RxPath == 2)
8644 {
8645 R2 |= 0x40; // write 1 to off Rxpath.
8646 }
8647 else if (pAd->Antenna.field.RxPath == 1)
8648 {
8649 R2 |= 0x20040; // write 1 to off RxPath
8650 }
8651 RTMP_RF_IO_WRITE32(pAd, R2);
8652
8653 break;
8654 }
8655 }
8656 break;
8657
8658 default:
8659 break;
8660 }
8661
8662 DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
8663 Channel,
8664 pAd->RfIcType,
8665 R2));
8666}
8667
diff --git a/drivers/staging/rt2860/common/netif_block.c b/drivers/staging/rt2860/common/netif_block.c
new file mode 100644
index 00000000000..d3f7d087e7f
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/common/netif_block.h b/drivers/staging/rt2860/common/netif_block.h
new file mode 100644
index 00000000000..6e5151c4109
--- /dev/null
+++ b/drivers/staging/rt2860/common/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/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c
new file mode 100644
index 00000000000..9b81443d24b
--- /dev/null
+++ b/drivers/staging/rt2860/common/rtmp_init.c
@@ -0,0 +1,3757 @@
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
43UCHAR BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
44ULONG BIT32[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008,
45 0x00000010, 0x00000020, 0x00000040, 0x00000080,
46 0x00000100, 0x00000200, 0x00000400, 0x00000800,
47 0x00001000, 0x00002000, 0x00004000, 0x00008000,
48 0x00010000, 0x00020000, 0x00040000, 0x00080000,
49 0x00100000, 0x00200000, 0x00400000, 0x00800000,
50 0x01000000, 0x02000000, 0x04000000, 0x08000000,
51 0x10000000, 0x20000000, 0x40000000, 0x80000000};
52
53char* CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128"};
54
55const unsigned short ccitt_16Table[] = {
56 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
57 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
58 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
59 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
60 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
61 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
62 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
63 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
64 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
65 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
66 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
67 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
68 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
69 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
70 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
71 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
72 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
73 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
74 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
75 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
76 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
77 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
78 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
79 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
80 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
81 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
82 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
83 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
84 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
85 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
86 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
87 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
88};
89#define ByteCRC16(v, crc) \
90 (unsigned short)((crc << 8) ^ ccitt_16Table[((crc >> 8) ^ (v)) & 255])
91
92unsigned char BitReverse(unsigned char x)
93{
94 int i;
95 unsigned char Temp=0;
96 for(i=0; ; i++)
97 {
98 if(x & 0x80) Temp |= 0x80;
99 if(i==7) break;
100 x <<= 1;
101 Temp >>= 1;
102 }
103 return Temp;
104}
105
106//
107// BBP register initialization set
108//
109REG_PAIR BBPRegTable[] = {
110 {BBP_R65, 0x2C}, // fix rssi issue
111 {BBP_R66, 0x38}, // Also set this default value to pAd->BbpTuning.R66CurrentValue at initial
112 {BBP_R69, 0x12},
113 {BBP_R70, 0xa}, // BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa
114 {BBP_R73, 0x10},
115 {BBP_R81, 0x37},
116 {BBP_R82, 0x62},
117 {BBP_R83, 0x6A},
118 {BBP_R84, 0x99}, // 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before
119 {BBP_R86, 0x00}, // middle range issue, Rory @2008-01-28
120 {BBP_R91, 0x04}, // middle range issue, Rory @2008-01-28
121 {BBP_R92, 0x00}, // middle range issue, Rory @2008-01-28
122 {BBP_R103, 0x00}, // near range high-power issue, requested from Gary @2008-0528
123 {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.
124};
125#define NUM_BBP_REG_PARMS (sizeof(BBPRegTable) / sizeof(REG_PAIR))
126
127//
128// RF register initialization set
129//
130
131//
132// ASIC register initialization sets
133//
134
135RTMP_REG_PAIR MACRegTable[] = {
136#if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200)
137 {BCN_OFFSET0, 0xf8f0e8e0}, /* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */
138 {BCN_OFFSET1, 0x6f77d0c8}, /* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */
139#elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100)
140 {BCN_OFFSET0, 0xece8e4e0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
141 {BCN_OFFSET1, 0xfcf8f4f0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
142#else
143 #error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]!!!
144#endif // HW_BEACON_OFFSET //
145
146 {LEGACY_BASIC_RATE, 0x0000013f}, // Basic rate set bitmap
147 {HT_BASIC_RATE, 0x00008003}, // Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI.
148 {MAC_SYS_CTRL, 0x00}, // 0x1004, , default Disable RX
149 {RX_FILTR_CFG, 0x17f97}, //0x1400 , RX filter control,
150 {BKOFF_SLOT_CFG, 0x209}, // default set short slot time, CC_DELAY_TIME should be 2
151 {TX_SW_CFG0, 0x0}, // Gary,2008-05-21 for CWC test
152 {TX_SW_CFG1, 0x80606}, // Gary,2006-08-23
153 {TX_LINK_CFG, 0x1020}, // Gary,2006-08-23
154 {TX_TIMEOUT_CFG, 0x000a2090}, // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01
155 {MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000}, // 0x3018, MAX frame length. Max PSDU = 16kbytes.
156 {LED_CFG, 0x7f031e46}, // Gary, 2006-08-23
157 {PBF_MAX_PCNT, 0x1F3FBF9F}, //0x1F3f7f9f}, //Jan, 2006/04/20
158 {TX_RTY_CFG, 0x47d01f0f}, // Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03
159 {AUTO_RSP_CFG, 0x00000013}, // Initial Auto_Responder, because QA will turn off Auto-Responder
160 {CCK_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
161 {OFDM_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
162 {GF20_PROT_CFG, 0x01744004}, // set 19:18 --> Short NAV for MIMO PS
163 {GF40_PROT_CFG, 0x03F44084},
164 {MM20_PROT_CFG, 0x01744004},
165#ifdef RT2860
166 {MM40_PROT_CFG, 0x03F54084},
167#endif // RT2860 //
168 {TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f*/ /*0x000024bf*/}, //Extension channel backoff.
169 {TX_RTS_CFG, 0x00092b20},
170 {EXP_ACK_TIME, 0x002400ca}, // default value
171 {TXOP_HLDR_ET, 0x00000002},
172
173 /* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us
174 is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0
175 and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping
176 will always lost. So we change the SIFS of CCK from 10us to 16us. */
177 {XIFS_TIME_CFG, 0x33a41010},
178 {PWR_PIN_CFG, 0x00000003}, // patch for 2880-E
179};
180
181
182#ifdef CONFIG_STA_SUPPORT
183RTMP_REG_PAIR STAMACRegTable[] = {
184 {WMM_AIFSN_CFG, 0x00002273},
185 {WMM_CWMIN_CFG, 0x00002344},
186 {WMM_CWMAX_CFG, 0x000034aa},
187};
188#endif // CONFIG_STA_SUPPORT //
189
190#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR))
191#ifdef CONFIG_STA_SUPPORT
192#define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR))
193#endif // CONFIG_STA_SUPPORT //
194
195
196// New 8k byte firmware size for RT3071/RT3072
197#define FIRMWAREIMAGE_MAX_LENGTH 0x2000
198#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR))
199#define FIRMWARE_MAJOR_VERSION 0
200
201#define FIRMWAREIMAGEV1_LENGTH 0x1000
202#define FIRMWAREIMAGEV2_LENGTH 0x1000
203
204#ifdef RT2860
205#define FIRMWARE_MINOR_VERSION 2
206#endif // RT2860 //
207
208
209/*
210 ========================================================================
211
212 Routine Description:
213 Allocate RTMP_ADAPTER data block and do some initialization
214
215 Arguments:
216 Adapter Pointer to our adapter
217
218 Return Value:
219 NDIS_STATUS_SUCCESS
220 NDIS_STATUS_FAILURE
221
222 IRQL = PASSIVE_LEVEL
223
224 Note:
225
226 ========================================================================
227*/
228NDIS_STATUS RTMPAllocAdapterBlock(
229 IN PVOID handle,
230 OUT PRTMP_ADAPTER *ppAdapter)
231{
232 PRTMP_ADAPTER pAd;
233 NDIS_STATUS Status;
234 INT index;
235 UCHAR *pBeaconBuf = NULL;
236
237 DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n"));
238
239 *ppAdapter = NULL;
240
241 do
242 {
243 // Allocate RTMP_ADAPTER memory block
244 pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG);
245 if (pBeaconBuf == NULL)
246 {
247 Status = NDIS_STATUS_FAILURE;
248 DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n"));
249 break;
250 }
251
252 Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd);
253 if (Status != NDIS_STATUS_SUCCESS)
254 {
255 DBGPRINT_ERR(("Failed to allocate memory - ADAPTER\n"));
256 break;
257 }
258 pAd->BeaconBuf = pBeaconBuf;
259 printk("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER));
260
261
262 // Init spin locks
263 NdisAllocateSpinLock(&pAd->MgmtRingLock);
264#ifdef RT2860
265 NdisAllocateSpinLock(&pAd->RxRingLock);
266#endif // RT2860 //
267
268 for (index =0 ; index < NUM_OF_TX_RING; index++)
269 {
270 NdisAllocateSpinLock(&pAd->TxSwQueueLock[index]);
271 NdisAllocateSpinLock(&pAd->DeQueueLock[index]);
272 pAd->DeQueueRunning[index] = FALSE;
273 }
274
275 NdisAllocateSpinLock(&pAd->irq_lock);
276
277 } while (FALSE);
278
279 if ((Status != NDIS_STATUS_SUCCESS) && (pBeaconBuf))
280 kfree(pBeaconBuf);
281
282 *ppAdapter = pAd;
283
284 DBGPRINT_S(Status, ("<-- RTMPAllocAdapterBlock, Status=%x\n", Status));
285 return Status;
286}
287
288/*
289 ========================================================================
290
291 Routine Description:
292 Read initial Tx power per MCS and BW from EEPROM
293
294 Arguments:
295 Adapter Pointer to our adapter
296
297 Return Value:
298 None
299
300 IRQL = PASSIVE_LEVEL
301
302 Note:
303
304 ========================================================================
305*/
306VOID RTMPReadTxPwrPerRate(
307 IN PRTMP_ADAPTER pAd)
308{
309 ULONG data, Adata, Gdata;
310 USHORT i, value, value2;
311 INT Apwrdelta, Gpwrdelta;
312 UCHAR t1,t2,t3,t4;
313 BOOLEAN bValid, bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
314
315 //
316 // Get power delta for 20MHz and 40MHz.
317 //
318 DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n"));
319 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2);
320 Apwrdelta = 0;
321 Gpwrdelta = 0;
322
323 if ((value2 & 0xff) != 0xff)
324 {
325 if ((value2 & 0x80))
326 Gpwrdelta = (value2&0xf);
327
328 if ((value2 & 0x40))
329 bGpwrdeltaMinus = FALSE;
330 else
331 bGpwrdeltaMinus = TRUE;
332 }
333 if ((value2 & 0xff00) != 0xff00)
334 {
335 if ((value2 & 0x8000))
336 Apwrdelta = ((value2&0xf00)>>8);
337
338 if ((value2 & 0x4000))
339 bApwrdeltaMinus = FALSE;
340 else
341 bApwrdeltaMinus = TRUE;
342 }
343 DBGPRINT(RT_DEBUG_TRACE, ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta));
344
345 //
346 // Get Txpower per MCS for 20MHz in 2.4G.
347 //
348 for (i=0; i<5; i++)
349 {
350 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4, value);
351 data = value;
352 if (bApwrdeltaMinus == FALSE)
353 {
354 t1 = (value&0xf)+(Apwrdelta);
355 if (t1 > 0xf)
356 t1 = 0xf;
357 t2 = ((value&0xf0)>>4)+(Apwrdelta);
358 if (t2 > 0xf)
359 t2 = 0xf;
360 t3 = ((value&0xf00)>>8)+(Apwrdelta);
361 if (t3 > 0xf)
362 t3 = 0xf;
363 t4 = ((value&0xf000)>>12)+(Apwrdelta);
364 if (t4 > 0xf)
365 t4 = 0xf;
366 }
367 else
368 {
369 if ((value&0xf) > Apwrdelta)
370 t1 = (value&0xf)-(Apwrdelta);
371 else
372 t1 = 0;
373 if (((value&0xf0)>>4) > Apwrdelta)
374 t2 = ((value&0xf0)>>4)-(Apwrdelta);
375 else
376 t2 = 0;
377 if (((value&0xf00)>>8) > Apwrdelta)
378 t3 = ((value&0xf00)>>8)-(Apwrdelta);
379 else
380 t3 = 0;
381 if (((value&0xf000)>>12) > Apwrdelta)
382 t4 = ((value&0xf000)>>12)-(Apwrdelta);
383 else
384 t4 = 0;
385 }
386 Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
387 if (bGpwrdeltaMinus == FALSE)
388 {
389 t1 = (value&0xf)+(Gpwrdelta);
390 if (t1 > 0xf)
391 t1 = 0xf;
392 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
393 if (t2 > 0xf)
394 t2 = 0xf;
395 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
396 if (t3 > 0xf)
397 t3 = 0xf;
398 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
399 if (t4 > 0xf)
400 t4 = 0xf;
401 }
402 else
403 {
404 if ((value&0xf) > Gpwrdelta)
405 t1 = (value&0xf)-(Gpwrdelta);
406 else
407 t1 = 0;
408 if (((value&0xf0)>>4) > Gpwrdelta)
409 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
410 else
411 t2 = 0;
412 if (((value&0xf00)>>8) > Gpwrdelta)
413 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
414 else
415 t3 = 0;
416 if (((value&0xf000)>>12) > Gpwrdelta)
417 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
418 else
419 t4 = 0;
420 }
421 Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
422
423 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4 + 2, value);
424 if (bApwrdeltaMinus == FALSE)
425 {
426 t1 = (value&0xf)+(Apwrdelta);
427 if (t1 > 0xf)
428 t1 = 0xf;
429 t2 = ((value&0xf0)>>4)+(Apwrdelta);
430 if (t2 > 0xf)
431 t2 = 0xf;
432 t3 = ((value&0xf00)>>8)+(Apwrdelta);
433 if (t3 > 0xf)
434 t3 = 0xf;
435 t4 = ((value&0xf000)>>12)+(Apwrdelta);
436 if (t4 > 0xf)
437 t4 = 0xf;
438 }
439 else
440 {
441 if ((value&0xf) > Apwrdelta)
442 t1 = (value&0xf)-(Apwrdelta);
443 else
444 t1 = 0;
445 if (((value&0xf0)>>4) > Apwrdelta)
446 t2 = ((value&0xf0)>>4)-(Apwrdelta);
447 else
448 t2 = 0;
449 if (((value&0xf00)>>8) > Apwrdelta)
450 t3 = ((value&0xf00)>>8)-(Apwrdelta);
451 else
452 t3 = 0;
453 if (((value&0xf000)>>12) > Apwrdelta)
454 t4 = ((value&0xf000)>>12)-(Apwrdelta);
455 else
456 t4 = 0;
457 }
458 Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
459 if (bGpwrdeltaMinus == FALSE)
460 {
461 t1 = (value&0xf)+(Gpwrdelta);
462 if (t1 > 0xf)
463 t1 = 0xf;
464 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
465 if (t2 > 0xf)
466 t2 = 0xf;
467 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
468 if (t3 > 0xf)
469 t3 = 0xf;
470 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
471 if (t4 > 0xf)
472 t4 = 0xf;
473 }
474 else
475 {
476 if ((value&0xf) > Gpwrdelta)
477 t1 = (value&0xf)-(Gpwrdelta);
478 else
479 t1 = 0;
480 if (((value&0xf0)>>4) > Gpwrdelta)
481 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
482 else
483 t2 = 0;
484 if (((value&0xf00)>>8) > Gpwrdelta)
485 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
486 else
487 t3 = 0;
488 if (((value&0xf000)>>12) > Gpwrdelta)
489 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
490 else
491 t4 = 0;
492 }
493 Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
494 data |= (value<<16);
495
496 pAd->Tx20MPwrCfgABand[i] = pAd->Tx40MPwrCfgABand[i] = Adata;
497 pAd->Tx20MPwrCfgGBand[i] = pAd->Tx40MPwrCfgGBand[i] = Gdata;
498
499 if (data != 0xffffffff)
500 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data);
501 DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%lx, Adata = %lx, Gdata = %lx \n", data, Adata, Gdata));
502 }
503
504 //
505 // Check this block is valid for 40MHz in 2.4G. If invalid, use parameter for 20MHz in 2.4G
506 //
507 bValid = TRUE;
508 for (i=0; i<6; i++)
509 {
510 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + 2 + i*2, value);
511 if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
512 {
513 bValid = FALSE;
514 break;
515 }
516 }
517
518 //
519 // Get Txpower per MCS for 40MHz in 2.4G.
520 //
521 if (bValid)
522 {
523 for (i=0; i<4; i++)
524 {
525 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4, value);
526 if (bGpwrdeltaMinus == FALSE)
527 {
528 t1 = (value&0xf)+(Gpwrdelta);
529 if (t1 > 0xf)
530 t1 = 0xf;
531 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
532 if (t2 > 0xf)
533 t2 = 0xf;
534 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
535 if (t3 > 0xf)
536 t3 = 0xf;
537 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
538 if (t4 > 0xf)
539 t4 = 0xf;
540 }
541 else
542 {
543 if ((value&0xf) > Gpwrdelta)
544 t1 = (value&0xf)-(Gpwrdelta);
545 else
546 t1 = 0;
547 if (((value&0xf0)>>4) > Gpwrdelta)
548 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
549 else
550 t2 = 0;
551 if (((value&0xf00)>>8) > Gpwrdelta)
552 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
553 else
554 t3 = 0;
555 if (((value&0xf000)>>12) > Gpwrdelta)
556 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
557 else
558 t4 = 0;
559 }
560 Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
561
562 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4 + 2, value);
563 if (bGpwrdeltaMinus == FALSE)
564 {
565 t1 = (value&0xf)+(Gpwrdelta);
566 if (t1 > 0xf)
567 t1 = 0xf;
568 t2 = ((value&0xf0)>>4)+(Gpwrdelta);
569 if (t2 > 0xf)
570 t2 = 0xf;
571 t3 = ((value&0xf00)>>8)+(Gpwrdelta);
572 if (t3 > 0xf)
573 t3 = 0xf;
574 t4 = ((value&0xf000)>>12)+(Gpwrdelta);
575 if (t4 > 0xf)
576 t4 = 0xf;
577 }
578 else
579 {
580 if ((value&0xf) > Gpwrdelta)
581 t1 = (value&0xf)-(Gpwrdelta);
582 else
583 t1 = 0;
584 if (((value&0xf0)>>4) > Gpwrdelta)
585 t2 = ((value&0xf0)>>4)-(Gpwrdelta);
586 else
587 t2 = 0;
588 if (((value&0xf00)>>8) > Gpwrdelta)
589 t3 = ((value&0xf00)>>8)-(Gpwrdelta);
590 else
591 t3 = 0;
592 if (((value&0xf000)>>12) > Gpwrdelta)
593 t4 = ((value&0xf000)>>12)-(Gpwrdelta);
594 else
595 t4 = 0;
596 }
597 Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
598
599 if (i == 0)
600 pAd->Tx40MPwrCfgGBand[i+1] = (pAd->Tx40MPwrCfgGBand[i+1] & 0x0000FFFF) | (Gdata & 0xFFFF0000);
601 else
602 pAd->Tx40MPwrCfgGBand[i+1] = Gdata;
603
604 DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 2.4G band, Gdata = %lx \n", Gdata));
605 }
606 }
607
608 //
609 // Check this block is valid for 20MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
610 //
611 bValid = TRUE;
612 for (i=0; i<8; i++)
613 {
614 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + 2 + i*2, value);
615 if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
616 {
617 bValid = FALSE;
618 break;
619 }
620 }
621
622 //
623 // Get Txpower per MCS for 20MHz in 5G.
624 //
625 if (bValid)
626 {
627 for (i=0; i<5; i++)
628 {
629 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4, value);
630 if (bApwrdeltaMinus == FALSE)
631 {
632 t1 = (value&0xf)+(Apwrdelta);
633 if (t1 > 0xf)
634 t1 = 0xf;
635 t2 = ((value&0xf0)>>4)+(Apwrdelta);
636 if (t2 > 0xf)
637 t2 = 0xf;
638 t3 = ((value&0xf00)>>8)+(Apwrdelta);
639 if (t3 > 0xf)
640 t3 = 0xf;
641 t4 = ((value&0xf000)>>12)+(Apwrdelta);
642 if (t4 > 0xf)
643 t4 = 0xf;
644 }
645 else
646 {
647 if ((value&0xf) > Apwrdelta)
648 t1 = (value&0xf)-(Apwrdelta);
649 else
650 t1 = 0;
651 if (((value&0xf0)>>4) > Apwrdelta)
652 t2 = ((value&0xf0)>>4)-(Apwrdelta);
653 else
654 t2 = 0;
655 if (((value&0xf00)>>8) > Apwrdelta)
656 t3 = ((value&0xf00)>>8)-(Apwrdelta);
657 else
658 t3 = 0;
659 if (((value&0xf000)>>12) > Apwrdelta)
660 t4 = ((value&0xf000)>>12)-(Apwrdelta);
661 else
662 t4 = 0;
663 }
664 Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
665
666 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4 + 2, value);
667 if (bApwrdeltaMinus == FALSE)
668 {
669 t1 = (value&0xf)+(Apwrdelta);
670 if (t1 > 0xf)
671 t1 = 0xf;
672 t2 = ((value&0xf0)>>4)+(Apwrdelta);
673 if (t2 > 0xf)
674 t2 = 0xf;
675 t3 = ((value&0xf00)>>8)+(Apwrdelta);
676 if (t3 > 0xf)
677 t3 = 0xf;
678 t4 = ((value&0xf000)>>12)+(Apwrdelta);
679 if (t4 > 0xf)
680 t4 = 0xf;
681 }
682 else
683 {
684 if ((value&0xf) > Apwrdelta)
685 t1 = (value&0xf)-(Apwrdelta);
686 else
687 t1 = 0;
688 if (((value&0xf0)>>4) > Apwrdelta)
689 t2 = ((value&0xf0)>>4)-(Apwrdelta);
690 else
691 t2 = 0;
692 if (((value&0xf00)>>8) > Apwrdelta)
693 t3 = ((value&0xf00)>>8)-(Apwrdelta);
694 else
695 t3 = 0;
696 if (((value&0xf000)>>12) > Apwrdelta)
697 t4 = ((value&0xf000)>>12)-(Apwrdelta);
698 else
699 t4 = 0;
700 }
701 Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
702
703 if (i == 0)
704 pAd->Tx20MPwrCfgABand[i] = (pAd->Tx20MPwrCfgABand[i] & 0x0000FFFF) | (Adata & 0xFFFF0000);
705 else
706 pAd->Tx20MPwrCfgABand[i] = Adata;
707
708 DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 5GHz band, Adata = %lx \n", Adata));
709 }
710 }
711
712 //
713 // Check this block is valid for 40MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
714 //
715 bValid = TRUE;
716 for (i=0; i<6; i++)
717 {
718 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + 2 + i*2, value);
719 if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
720 {
721 bValid = FALSE;
722 break;
723 }
724 }
725
726 //
727 // Get Txpower per MCS for 40MHz in 5G.
728 //
729 if (bValid)
730 {
731 for (i=0; i<4; i++)
732 {
733 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4, value);
734 if (bApwrdeltaMinus == FALSE)
735 {
736 t1 = (value&0xf)+(Apwrdelta);
737 if (t1 > 0xf)
738 t1 = 0xf;
739 t2 = ((value&0xf0)>>4)+(Apwrdelta);
740 if (t2 > 0xf)
741 t2 = 0xf;
742 t3 = ((value&0xf00)>>8)+(Apwrdelta);
743 if (t3 > 0xf)
744 t3 = 0xf;
745 t4 = ((value&0xf000)>>12)+(Apwrdelta);
746 if (t4 > 0xf)
747 t4 = 0xf;
748 }
749 else
750 {
751 if ((value&0xf) > Apwrdelta)
752 t1 = (value&0xf)-(Apwrdelta);
753 else
754 t1 = 0;
755 if (((value&0xf0)>>4) > Apwrdelta)
756 t2 = ((value&0xf0)>>4)-(Apwrdelta);
757 else
758 t2 = 0;
759 if (((value&0xf00)>>8) > Apwrdelta)
760 t3 = ((value&0xf00)>>8)-(Apwrdelta);
761 else
762 t3 = 0;
763 if (((value&0xf000)>>12) > Apwrdelta)
764 t4 = ((value&0xf000)>>12)-(Apwrdelta);
765 else
766 t4 = 0;
767 }
768 Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
769
770 RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4 + 2, value);
771 if (bApwrdeltaMinus == FALSE)
772 {
773 t1 = (value&0xf)+(Apwrdelta);
774 if (t1 > 0xf)
775 t1 = 0xf;
776 t2 = ((value&0xf0)>>4)+(Apwrdelta);
777 if (t2 > 0xf)
778 t2 = 0xf;
779 t3 = ((value&0xf00)>>8)+(Apwrdelta);
780 if (t3 > 0xf)
781 t3 = 0xf;
782 t4 = ((value&0xf000)>>12)+(Apwrdelta);
783 if (t4 > 0xf)
784 t4 = 0xf;
785 }
786 else
787 {
788 if ((value&0xf) > Apwrdelta)
789 t1 = (value&0xf)-(Apwrdelta);
790 else
791 t1 = 0;
792 if (((value&0xf0)>>4) > Apwrdelta)
793 t2 = ((value&0xf0)>>4)-(Apwrdelta);
794 else
795 t2 = 0;
796 if (((value&0xf00)>>8) > Apwrdelta)
797 t3 = ((value&0xf00)>>8)-(Apwrdelta);
798 else
799 t3 = 0;
800 if (((value&0xf000)>>12) > Apwrdelta)
801 t4 = ((value&0xf000)>>12)-(Apwrdelta);
802 else
803 t4 = 0;
804 }
805 Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
806
807 if (i == 0)
808 pAd->Tx40MPwrCfgABand[i+1] = (pAd->Tx40MPwrCfgABand[i+1] & 0x0000FFFF) | (Adata & 0xFFFF0000);
809 else
810 pAd->Tx40MPwrCfgABand[i+1] = Adata;
811
812 DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 5GHz band, Adata = %lx \n", Adata));
813 }
814 }
815}
816
817
818/*
819 ========================================================================
820
821 Routine Description:
822 Read initial channel power parameters from EEPROM
823
824 Arguments:
825 Adapter Pointer to our adapter
826
827 Return Value:
828 None
829
830 IRQL = PASSIVE_LEVEL
831
832 Note:
833
834 ========================================================================
835*/
836VOID RTMPReadChannelPwr(
837 IN PRTMP_ADAPTER pAd)
838{
839 UCHAR i, choffset;
840 EEPROM_TX_PWR_STRUC Power;
841 EEPROM_TX_PWR_STRUC Power2;
842
843 // Read Tx power value for all channels
844 // Value from 1 - 0x7f. Default value is 24.
845 // Power value : 2.4G 0x00 (0) ~ 0x1F (31)
846 // : 5.5G 0xF9 (-7) ~ 0x0F (15)
847
848 // 0. 11b/g, ch1 - ch 14
849 for (i = 0; i < 7; i++)
850 {
851 RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2, Power.word);
852 RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2, Power2.word);
853 pAd->TxPower[i * 2].Channel = i * 2 + 1;
854 pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2;
855
856 if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0))
857 pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER;
858 else
859 pAd->TxPower[i * 2].Power = Power.field.Byte0;
860
861 if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0))
862 pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER;
863 else
864 pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1;
865
866 if ((Power2.field.Byte0 > 31) || (Power2.field.Byte0 < 0))
867 pAd->TxPower[i * 2].Power2 = DEFAULT_RF_TX_POWER;
868 else
869 pAd->TxPower[i * 2].Power2 = Power2.field.Byte0;
870
871 if ((Power2.field.Byte1 > 31) || (Power2.field.Byte1 < 0))
872 pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER;
873 else
874 pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1;
875 }
876
877 // 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz)
878 // 1.1 Fill up channel
879 choffset = 14;
880 for (i = 0; i < 4; i++)
881 {
882 pAd->TxPower[3 * i + choffset + 0].Channel = 36 + i * 8 + 0;
883 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
884 pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
885
886 pAd->TxPower[3 * i + choffset + 1].Channel = 36 + i * 8 + 2;
887 pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
888 pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
889
890 pAd->TxPower[3 * i + choffset + 2].Channel = 36 + i * 8 + 4;
891 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
892 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
893 }
894
895 // 1.2 Fill up power
896 for (i = 0; i < 6; i++)
897 {
898 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2, Power.word);
899 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2, Power2.word);
900
901 if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
902 pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
903
904 if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
905 pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
906
907 if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
908 pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
909
910 if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
911 pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
912 }
913
914 // 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)
915 // 2.1 Fill up channel
916 choffset = 14 + 12;
917 for (i = 0; i < 5; i++)
918 {
919 pAd->TxPower[3 * i + choffset + 0].Channel = 100 + i * 8 + 0;
920 pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
921 pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
922
923 pAd->TxPower[3 * i + choffset + 1].Channel = 100 + i * 8 + 2;
924 pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
925 pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
926
927 pAd->TxPower[3 * i + choffset + 2].Channel = 100 + i * 8 + 4;
928 pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
929 pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
930 }
931 pAd->TxPower[3 * 5 + choffset + 0].Channel = 140;
932 pAd->TxPower[3 * 5 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
933 pAd->TxPower[3 * 5 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
934
935 // 2.2 Fill up power
936 for (i = 0; i < 8; i++)
937 {
938 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
939 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + 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 // 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165 (including central frequency in BW 40MHz)
955 // 3.1 Fill up channel
956 choffset = 14 + 12 + 16;
957 for (i = 0; i < 2; i++)
958 {
959 pAd->TxPower[3 * i + choffset + 0].Channel = 149 + 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 = 149 + 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 = 149 + 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 * 2 + choffset + 0].Channel = 165;
972 pAd->TxPower[3 * 2 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
973 pAd->TxPower[3 * 2 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
974
975 // 3.2 Fill up power
976 for (i = 0; i < 4; i++)
977 {
978 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
979 RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
980
981 if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
982 pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
983
984 if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
985 pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
986
987 if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
988 pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
989
990 if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
991 pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
992 }
993
994 // 4. Print and Debug
995 choffset = 14 + 12 + 16 + 7;
996
997
998#if 0
999 // Init the 802.11j channel number for TX channel power
1000 // 0. 20MHz
1001 for (i = 0; i < 3; i++)
1002 {
1003 pAd->TxPower11J[i].Channel = 8 + i * 4;
1004 pAd->TxPower11J[i].BW = BW_20;
1005 }
1006
1007 for (i = 0; i < 4; i++)
1008 {
1009 pAd->TxPower11J[i + 3].Channel = 34 + i * 4;
1010 pAd->TxPower11J[i + 3].BW = BW_20;
1011 }
1012
1013 for (i = 0; i < 4; i++)
1014 {
1015 pAd->TxPower11J[i + 7].Channel = 184 + i * 4;
1016 pAd->TxPower11J[i + 7].BW = BW_20;
1017 }
1018
1019 // 0. 10MHz
1020 for (i = 0; i < 2; i++)
1021 {
1022 pAd->TxPower11J[i + 11].Channel = 7 + i;
1023 pAd->TxPower11J[i + 11].BW = BW_10;
1024 }
1025 pAd->TxPower11J[13].Channel = 11;
1026 pAd->TxPower11J[13].BW = BW_10;
1027
1028 for (i = 0; i < 3; i++)
1029 {
1030 pAd->TxPower11J[i + 14].Channel = 183 + i;
1031 pAd->TxPower11J[i + 14].BW= BW_10;
1032 }
1033
1034 for (i = 0; i < 3; i++)
1035 {
1036 pAd->TxPower11J[i + 17].Channel = 187 + i;
1037 pAd->TxPower11J[i + 17].BW = BW_10;
1038 }
1039 for (i = 0; i < 10; i++)
1040 {
1041 Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_Japan_TX_PWR_OFFSET + i * 2);
1042 Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_Japan_TX2_PWR_OFFSET + i * 2);
1043
1044 if ((Power.field.Byte0 < 36) && (Power.field.Byte0 > -6))
1045 pAd->TxPower11J[i * 2].Power = Power.field.Byte0;
1046
1047 if ((Power.field.Byte1 < 36) && (Power.field.Byte1 > -6))
1048 pAd->TxPower11J[i * 2 + 1].Power = Power.field.Byte1;
1049
1050 if ((Power2.field.Byte0 < 36) && (Power2.field.Byte0 > -6))
1051 pAd->TxPower11J[i * 2].Power2 = Power2.field.Byte0;
1052
1053 if ((Power2.field.Byte1 < 36) && (Power2.field.Byte1 > -6))
1054 pAd->TxPower11J[i * 2 + 1].Power2 = Power2.field.Byte1;
1055 }
1056#endif
1057}
1058
1059/*
1060 ========================================================================
1061
1062 Routine Description:
1063 Read the following from the registry
1064 1. All the parameters
1065 2. NetworkAddres
1066
1067 Arguments:
1068 Adapter Pointer to our adapter
1069 WrapperConfigurationContext For use by NdisOpenConfiguration
1070
1071 Return Value:
1072 NDIS_STATUS_SUCCESS
1073 NDIS_STATUS_FAILURE
1074 NDIS_STATUS_RESOURCES
1075
1076 IRQL = PASSIVE_LEVEL
1077
1078 Note:
1079
1080 ========================================================================
1081*/
1082NDIS_STATUS NICReadRegParameters(
1083 IN PRTMP_ADAPTER pAd,
1084 IN NDIS_HANDLE WrapperConfigurationContext
1085 )
1086{
1087 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1088 DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
1089 return Status;
1090}
1091
1092
1093
1094
1095/*
1096 ========================================================================
1097
1098 Routine Description:
1099 Read initial parameters from EEPROM
1100
1101 Arguments:
1102 Adapter Pointer to our adapter
1103
1104 Return Value:
1105 None
1106
1107 IRQL = PASSIVE_LEVEL
1108
1109 Note:
1110
1111 ========================================================================
1112*/
1113VOID NICReadEEPROMParameters(
1114 IN PRTMP_ADAPTER pAd,
1115 IN PUCHAR mac_addr)
1116{
1117 UINT32 data = 0;
1118 USHORT i, value, value2;
1119 UCHAR TmpPhy;
1120 EEPROM_TX_PWR_STRUC Power;
1121 EEPROM_VERSION_STRUC Version;
1122 EEPROM_ANTENNA_STRUC Antenna;
1123 EEPROM_NIC_CONFIG2_STRUC NicConfig2;
1124
1125 DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n"));
1126
1127 // Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8
1128 RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
1129 DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data));
1130
1131 if((data & 0x30) == 0)
1132 pAd->EEPROMAddressNum = 6; // 93C46
1133 else if((data & 0x30) == 0x10)
1134 pAd->EEPROMAddressNum = 8; // 93C66
1135 else
1136 pAd->EEPROMAddressNum = 8; // 93C86
1137 DBGPRINT(RT_DEBUG_TRACE, ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum ));
1138
1139 // RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize
1140 // MAC address registers according to E2PROM setting
1141 if (mac_addr == NULL ||
1142 strlen(mac_addr) != 17 ||
1143 mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' ||
1144 mac_addr[11] != ':' || mac_addr[14] != ':')
1145 {
1146 USHORT Addr01,Addr23,Addr45 ;
1147
1148 RT28xx_EEPROM_READ16(pAd, 0x04, Addr01);
1149 RT28xx_EEPROM_READ16(pAd, 0x06, Addr23);
1150 RT28xx_EEPROM_READ16(pAd, 0x08, Addr45);
1151
1152 pAd->PermanentAddress[0] = (UCHAR)(Addr01 & 0xff);
1153 pAd->PermanentAddress[1] = (UCHAR)(Addr01 >> 8);
1154 pAd->PermanentAddress[2] = (UCHAR)(Addr23 & 0xff);
1155 pAd->PermanentAddress[3] = (UCHAR)(Addr23 >> 8);
1156 pAd->PermanentAddress[4] = (UCHAR)(Addr45 & 0xff);
1157 pAd->PermanentAddress[5] = (UCHAR)(Addr45 >> 8);
1158
1159 DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from E2PROM \n"));
1160 }
1161 else
1162 {
1163 INT j;
1164 PUCHAR macptr;
1165
1166 macptr = mac_addr;
1167
1168 for (j=0; j<MAC_ADDR_LEN; j++)
1169 {
1170 AtoH(macptr, &pAd->PermanentAddress[j], 1);
1171 macptr=macptr+3;
1172 }
1173
1174 DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from module parameter \n"));
1175 }
1176
1177
1178 {
1179 //more conveninet to test mbssid, so ap's bssid &0xf1
1180 if (pAd->PermanentAddress[0] == 0xff)
1181 pAd->PermanentAddress[0] = RandomByte(pAd)&0xf8;
1182
1183 //if (pAd->PermanentAddress[5] == 0xff)
1184 // pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8;
1185
1186 DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
1187 pAd->PermanentAddress[0], pAd->PermanentAddress[1],
1188 pAd->PermanentAddress[2], pAd->PermanentAddress[3],
1189 pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
1190 if (pAd->bLocalAdminMAC == FALSE)
1191 {
1192 MAC_DW0_STRUC csr2;
1193 MAC_DW1_STRUC csr3;
1194 COPY_MAC_ADDR(pAd->CurrentAddress, pAd->PermanentAddress);
1195 csr2.field.Byte0 = pAd->CurrentAddress[0];
1196 csr2.field.Byte1 = pAd->CurrentAddress[1];
1197 csr2.field.Byte2 = pAd->CurrentAddress[2];
1198 csr2.field.Byte3 = pAd->CurrentAddress[3];
1199 RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word);
1200 csr3.word = 0;
1201 csr3.field.Byte4 = pAd->CurrentAddress[4];
1202 csr3.field.Byte5 = pAd->CurrentAddress[5];
1203 csr3.field.U2MeMask = 0xff;
1204 RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word);
1205 DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
1206 pAd->PermanentAddress[0], pAd->PermanentAddress[1],
1207 pAd->PermanentAddress[2], pAd->PermanentAddress[3],
1208 pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
1209 }
1210 }
1211
1212 // if not return early. cause fail at emulation.
1213 // Init the channel number for TX channel power
1214 RTMPReadChannelPwr(pAd);
1215
1216 // if E2PROM version mismatch with driver's expectation, then skip
1217 // all subsequent E2RPOM retieval and set a system error bit to notify GUI
1218 RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word);
1219 pAd->EepromVersion = Version.field.Version + Version.field.FaeReleaseNumber * 256;
1220 DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: Version = %d, FAE release #%d\n", Version.field.Version, Version.field.FaeReleaseNumber));
1221
1222 if (Version.field.Version > VALID_EEPROM_VERSION)
1223 {
1224 DBGPRINT_ERR(("E2PROM: WRONG VERSION 0x%x, should be %d\n",Version.field.Version, VALID_EEPROM_VERSION));
1225 /*pAd->SystemErrorBitmap |= 0x00000001;
1226
1227 // hard-code default value when no proper E2PROM installed
1228 pAd->bAutoTxAgcA = FALSE;
1229 pAd->bAutoTxAgcG = FALSE;
1230
1231 // Default the channel power
1232 for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
1233 pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
1234
1235 // Default the channel power
1236 for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++)
1237 pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER;
1238
1239 for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
1240 pAd->EEPROMDefaultValue[i] = 0xffff;
1241 return; */
1242 }
1243
1244 // Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd
1245 RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value);
1246 pAd->EEPROMDefaultValue[0] = value;
1247
1248 RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value);
1249 pAd->EEPROMDefaultValue[1] = value;
1250
1251 RT28xx_EEPROM_READ16(pAd, 0x38, value); // Country Region
1252 pAd->EEPROMDefaultValue[2] = value;
1253
1254 for(i = 0; i < 8; i++)
1255 {
1256 RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i*2, value);
1257 pAd->EEPROMDefaultValue[i+3] = value;
1258 }
1259
1260 // We have to parse NIC configuration 0 at here.
1261 // If TSSI did not have preloaded value, it should reset the TxAutoAgc to false
1262 // Therefore, we have to read TxAutoAgc control beforehand.
1263 // Read Tx AGC control bit
1264 Antenna.word = pAd->EEPROMDefaultValue[0];
1265 if (Antenna.word == 0xFFFF)
1266 {
1267 Antenna.word = 0;
1268 Antenna.field.RfIcType = RFIC_2820;
1269 Antenna.field.TxPath = 1;
1270 Antenna.field.RxPath = 2;
1271 DBGPRINT(RT_DEBUG_WARN, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
1272 }
1273
1274 // Choose the desired Tx&Rx stream.
1275 if ((pAd->CommonCfg.TxStream == 0) || (pAd->CommonCfg.TxStream > Antenna.field.TxPath))
1276 pAd->CommonCfg.TxStream = Antenna.field.TxPath;
1277
1278 if ((pAd->CommonCfg.RxStream == 0) || (pAd->CommonCfg.RxStream > Antenna.field.RxPath))
1279 {
1280 pAd->CommonCfg.RxStream = Antenna.field.RxPath;
1281
1282 if ((pAd->MACVersion < RALINK_2883_VERSION) &&
1283 (pAd->CommonCfg.RxStream > 2))
1284 {
1285 // only 2 Rx streams for RT2860 series
1286 pAd->CommonCfg.RxStream = 2;
1287 }
1288 }
1289
1290 // 3*3
1291 // read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2
1292 // yet implement
1293 for(i=0; i<3; i++)
1294 {
1295 }
1296
1297 NicConfig2.word = pAd->EEPROMDefaultValue[1];
1298
1299
1300
1301#ifdef CONFIG_STA_SUPPORT
1302 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1303 {
1304 NicConfig2.word = 0;
1305 if ((NicConfig2.word & 0x00ff) == 0xff)
1306 {
1307 NicConfig2.word &= 0xff00;
1308 }
1309
1310 if ((NicConfig2.word >> 8) == 0xff)
1311 {
1312 NicConfig2.word &= 0x00ff;
1313 }
1314 }
1315#endif // CONFIG_STA_SUPPORT //
1316
1317 if (NicConfig2.field.DynamicTxAgcControl == 1)
1318 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
1319 else
1320 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
1321
1322 DBGPRINT_RAW(RT_DEBUG_TRACE, ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n", Antenna.field.RxPath, Antenna.field.TxPath));
1323
1324 // Save the antenna for future use
1325 pAd->Antenna.word = Antenna.word;
1326
1327 //
1328 // Reset PhyMode if we don't support 802.11a
1329 // Only RFIC_2850 & RFIC_2750 support 802.11a
1330 //
1331 if ((Antenna.field.RfIcType != RFIC_2850) && (Antenna.field.RfIcType != RFIC_2750))
1332 {
1333 if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) ||
1334 (pAd->CommonCfg.PhyMode == PHY_11A))
1335 pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;
1336#ifdef DOT11_N_SUPPORT
1337 else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) ||
1338 (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) ||
1339 (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) ||
1340 (pAd->CommonCfg.PhyMode == PHY_11N_5G))
1341 pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED;
1342#endif // DOT11_N_SUPPORT //
1343 }
1344
1345 // Read TSSI reference and TSSI boundary for temperature compensation. This is ugly
1346 // 0. 11b/g
1347 {
1348 /* these are tempature reference value (0x00 ~ 0xFE)
1349 ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
1350 TssiPlusBoundaryG [4] [3] [2] [1] [0] (smaller) +
1351 TssiMinusBoundaryG[0] [1] [2] [3] [4] (larger) */
1352 RT28xx_EEPROM_READ16(pAd, 0x6E, Power.word);
1353 pAd->TssiMinusBoundaryG[4] = Power.field.Byte0;
1354 pAd->TssiMinusBoundaryG[3] = Power.field.Byte1;
1355 RT28xx_EEPROM_READ16(pAd, 0x70, Power.word);
1356 pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
1357 pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
1358 RT28xx_EEPROM_READ16(pAd, 0x72, Power.word);
1359 pAd->TssiRefG = Power.field.Byte0; /* reference value [0] */
1360 pAd->TssiPlusBoundaryG[1] = Power.field.Byte1;
1361 RT28xx_EEPROM_READ16(pAd, 0x74, Power.word);
1362 pAd->TssiPlusBoundaryG[2] = Power.field.Byte0;
1363 pAd->TssiPlusBoundaryG[3] = Power.field.Byte1;
1364 RT28xx_EEPROM_READ16(pAd, 0x76, Power.word);
1365 pAd->TssiPlusBoundaryG[4] = Power.field.Byte0;
1366 pAd->TxAgcStepG = Power.field.Byte1;
1367 pAd->TxAgcCompensateG = 0;
1368 pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG;
1369 pAd->TssiPlusBoundaryG[0] = pAd->TssiRefG;
1370
1371 // Disable TxAgc if the based value is not right
1372 if (pAd->TssiRefG == 0xff)
1373 pAd->bAutoTxAgcG = FALSE;
1374
1375 DBGPRINT(RT_DEBUG_TRACE,("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
1376 pAd->TssiMinusBoundaryG[4], pAd->TssiMinusBoundaryG[3], pAd->TssiMinusBoundaryG[2], pAd->TssiMinusBoundaryG[1],
1377 pAd->TssiRefG,
1378 pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2], pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4],
1379 pAd->TxAgcStepG, pAd->bAutoTxAgcG));
1380 }
1381 // 1. 11a
1382 {
1383 RT28xx_EEPROM_READ16(pAd, 0xD4, Power.word);
1384 pAd->TssiMinusBoundaryA[4] = Power.field.Byte0;
1385 pAd->TssiMinusBoundaryA[3] = Power.field.Byte1;
1386 RT28xx_EEPROM_READ16(pAd, 0xD6, Power.word);
1387 pAd->TssiMinusBoundaryA[2] = Power.field.Byte0;
1388 pAd->TssiMinusBoundaryA[1] = Power.field.Byte1;
1389 RT28xx_EEPROM_READ16(pAd, 0xD8, Power.word);
1390 pAd->TssiRefA = Power.field.Byte0;
1391 pAd->TssiPlusBoundaryA[1] = Power.field.Byte1;
1392 RT28xx_EEPROM_READ16(pAd, 0xDA, Power.word);
1393 pAd->TssiPlusBoundaryA[2] = Power.field.Byte0;
1394 pAd->TssiPlusBoundaryA[3] = Power.field.Byte1;
1395 RT28xx_EEPROM_READ16(pAd, 0xDC, Power.word);
1396 pAd->TssiPlusBoundaryA[4] = Power.field.Byte0;
1397 pAd->TxAgcStepA = Power.field.Byte1;
1398 pAd->TxAgcCompensateA = 0;
1399 pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA;
1400 pAd->TssiPlusBoundaryA[0] = pAd->TssiRefA;
1401
1402 // Disable TxAgc if the based value is not right
1403 if (pAd->TssiRefA == 0xff)
1404 pAd->bAutoTxAgcA = FALSE;
1405
1406 DBGPRINT(RT_DEBUG_TRACE,("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
1407 pAd->TssiMinusBoundaryA[4], pAd->TssiMinusBoundaryA[3], pAd->TssiMinusBoundaryA[2], pAd->TssiMinusBoundaryA[1],
1408 pAd->TssiRefA,
1409 pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2], pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4],
1410 pAd->TxAgcStepA, pAd->bAutoTxAgcA));
1411 }
1412 pAd->BbpRssiToDbmDelta = 0x0;
1413
1414 // Read frequency offset setting for RF
1415 RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value);
1416 if ((value & 0x00FF) != 0x00FF)
1417 pAd->RfFreqOffset = (ULONG) (value & 0x00FF);
1418 else
1419 pAd->RfFreqOffset = 0;
1420 DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
1421
1422 //CountryRegion byte offset (38h)
1423 value = pAd->EEPROMDefaultValue[2] >> 8; // 2.4G band
1424 value2 = pAd->EEPROMDefaultValue[2] & 0x00FF; // 5G band
1425
1426 if ((value <= REGION_MAXIMUM_BG_BAND) && (value2 <= REGION_MAXIMUM_A_BAND))
1427 {
1428 pAd->CommonCfg.CountryRegion = ((UCHAR) value) | 0x80;
1429 pAd->CommonCfg.CountryRegionForABand = ((UCHAR) value2) | 0x80;
1430 TmpPhy = pAd->CommonCfg.PhyMode;
1431 pAd->CommonCfg.PhyMode = 0xff;
1432 RTMPSetPhyMode(pAd, TmpPhy);
1433#ifdef DOT11_N_SUPPORT
1434 SetCommonHT(pAd);
1435#endif // DOT11_N_SUPPORT //
1436 }
1437
1438 //
1439 // Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch.
1440 // The valid value are (-10 ~ 10)
1441 //
1442 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value);
1443 pAd->BGRssiOffset0 = value & 0x00ff;
1444 pAd->BGRssiOffset1 = (value >> 8);
1445 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET+2, value);
1446 pAd->BGRssiOffset2 = value & 0x00ff;
1447 pAd->ALNAGain1 = (value >> 8);
1448 RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value);
1449 pAd->BLNAGain = value & 0x00ff;
1450 pAd->ALNAGain0 = (value >> 8);
1451
1452 // Validate 11b/g RSSI_0 offset.
1453 if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10))
1454 pAd->BGRssiOffset0 = 0;
1455
1456 // Validate 11b/g RSSI_1 offset.
1457 if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10))
1458 pAd->BGRssiOffset1 = 0;
1459
1460 // Validate 11b/g RSSI_2 offset.
1461 if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10))
1462 pAd->BGRssiOffset2 = 0;
1463
1464 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value);
1465 pAd->ARssiOffset0 = value & 0x00ff;
1466 pAd->ARssiOffset1 = (value >> 8);
1467 RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET+2), value);
1468 pAd->ARssiOffset2 = value & 0x00ff;
1469 pAd->ALNAGain2 = (value >> 8);
1470
1471 if (((UCHAR)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00))
1472 pAd->ALNAGain1 = pAd->ALNAGain0;
1473 if (((UCHAR)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00))
1474 pAd->ALNAGain2 = pAd->ALNAGain0;
1475
1476 // Validate 11a RSSI_0 offset.
1477 if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10))
1478 pAd->ARssiOffset0 = 0;
1479
1480 // Validate 11a RSSI_1 offset.
1481 if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10))
1482 pAd->ARssiOffset1 = 0;
1483
1484 //Validate 11a RSSI_2 offset.
1485 if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10))
1486 pAd->ARssiOffset2 = 0;
1487
1488 //
1489 // Get LED Setting.
1490 //
1491 RT28xx_EEPROM_READ16(pAd, 0x3a, value);
1492 pAd->LedCntl.word = (value&0xff00) >> 8;
1493 RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value);
1494 pAd->Led1 = value;
1495 RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value);
1496 pAd->Led2 = value;
1497 RT28xx_EEPROM_READ16(pAd, EEPROM_LED3_OFFSET, value);
1498 pAd->Led3 = value;
1499
1500 RTMPReadTxPwrPerRate(pAd);
1501
1502#ifdef SINGLE_SKU
1503 //pAd->CommonCfg.DefineMaxTxPwr = RTMP_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR);
1504 RT28xx_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR, pAd->CommonCfg.DefineMaxTxPwr);
1505#endif // SINGLE_SKU //
1506
1507 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
1508}
1509
1510/*
1511 ========================================================================
1512
1513 Routine Description:
1514 Set default value from EEPROM
1515
1516 Arguments:
1517 Adapter Pointer to our adapter
1518
1519 Return Value:
1520 None
1521
1522 IRQL = PASSIVE_LEVEL
1523
1524 Note:
1525
1526 ========================================================================
1527*/
1528VOID NICInitAsicFromEEPROM(
1529 IN PRTMP_ADAPTER pAd)
1530{
1531#ifdef CONFIG_STA_SUPPORT
1532 UINT32 data = 0;
1533 UCHAR BBPR1 = 0;
1534#endif // CONFIG_STA_SUPPORT //
1535 USHORT i;
1536 EEPROM_ANTENNA_STRUC Antenna;
1537 EEPROM_NIC_CONFIG2_STRUC NicConfig2;
1538 UCHAR BBPR3 = 0;
1539
1540 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n"));
1541 for(i = 3; i < NUM_EEPROM_BBP_PARMS; i++)
1542 {
1543 UCHAR BbpRegIdx, BbpValue;
1544
1545 if ((pAd->EEPROMDefaultValue[i] != 0xFFFF) && (pAd->EEPROMDefaultValue[i] != 0))
1546 {
1547 BbpRegIdx = (UCHAR)(pAd->EEPROMDefaultValue[i] >> 8);
1548 BbpValue = (UCHAR)(pAd->EEPROMDefaultValue[i] & 0xff);
1549 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue);
1550 }
1551 }
1552
1553 Antenna.word = pAd->Antenna.word;
1554 pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
1555 pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
1556
1557 NicConfig2.word = pAd->EEPROMDefaultValue[1];
1558
1559
1560 // Save the antenna for future use
1561 pAd->NicConfig2.word = NicConfig2.word;
1562
1563 //
1564 // Send LED Setting to MCU.
1565 //
1566 if (pAd->LedCntl.word == 0xFF)
1567 {
1568 pAd->LedCntl.word = 0x01;
1569 pAd->Led1 = 0x5555;
1570 pAd->Led2 = 0x2221;
1571
1572#ifdef RT2860
1573 pAd->Led3 = 0xA9F8;
1574#endif // RT2860 //
1575 }
1576
1577 AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
1578 AsicSendCommandToMcu(pAd, 0x53, 0xff, (UCHAR)pAd->Led2, (UCHAR)(pAd->Led2 >> 8));
1579 AsicSendCommandToMcu(pAd, 0x54, 0xff, (UCHAR)pAd->Led3, (UCHAR)(pAd->Led3 >> 8));
1580 pAd->LedIndicatorStregth = 0xFF;
1581 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, before link up
1582
1583#ifdef CONFIG_STA_SUPPORT
1584 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1585 {
1586 // Read Hardware controlled Radio state enable bit
1587 if (NicConfig2.field.HardwareRadioControl == 1)
1588 {
1589 pAd->StaCfg.bHardwareRadio = TRUE;
1590
1591 // Read GPIO pin2 as Hardware controlled radio state
1592 RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
1593 if ((data & 0x04) == 0)
1594 {
1595 pAd->StaCfg.bHwRadio = FALSE;
1596 pAd->StaCfg.bRadio = FALSE;
1597 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
1598 }
1599 }
1600 else
1601 pAd->StaCfg.bHardwareRadio = FALSE;
1602
1603 if (pAd->StaCfg.bRadio == FALSE)
1604 {
1605 RTMPSetLED(pAd, LED_RADIO_OFF);
1606 }
1607 else
1608 {
1609 RTMPSetLED(pAd, LED_RADIO_ON);
1610#ifdef RT2860
1611 AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
1612 AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
1613 // 2-1. wait command ok.
1614 AsicCheckCommanOk(pAd, PowerWakeCID);
1615#endif // RT2860 //
1616 }
1617 }
1618#endif // CONFIG_STA_SUPPORT //
1619
1620 // Turn off patching for cardbus controller
1621 if (NicConfig2.field.CardbusAcceleration == 1)
1622 {
1623 }
1624
1625 if (NicConfig2.field.DynamicTxAgcControl == 1)
1626 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
1627 else
1628 pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
1629 //
1630 // Since BBP has been progamed, to make sure BBP setting will be
1631 // upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND!!
1632 //
1633 pAd->CommonCfg.BandState = UNKNOWN_BAND;
1634
1635 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
1636 BBPR3 &= (~0x18);
1637 if(pAd->Antenna.field.RxPath == 3)
1638 {
1639 BBPR3 |= (0x10);
1640 }
1641 else if(pAd->Antenna.field.RxPath == 2)
1642 {
1643 BBPR3 |= (0x8);
1644 }
1645 else if(pAd->Antenna.field.RxPath == 1)
1646 {
1647 BBPR3 |= (0x0);
1648 }
1649 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
1650
1651#ifdef CONFIG_STA_SUPPORT
1652 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1653 {
1654 // Handle the difference when 1T
1655 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
1656 if(pAd->Antenna.field.TxPath == 1)
1657 {
1658 BBPR1 &= (~0x18);
1659 }
1660 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
1661
1662 DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n", pAd->CommonCfg.bHardwareRadio, pAd->CommonCfg.bHardwareRadio));
1663 }
1664#endif // CONFIG_STA_SUPPORT //
1665 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));
1666 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n"));
1667}
1668
1669/*
1670 ========================================================================
1671
1672 Routine Description:
1673 Initialize NIC hardware
1674
1675 Arguments:
1676 Adapter Pointer to our adapter
1677
1678 Return Value:
1679 None
1680
1681 IRQL = PASSIVE_LEVEL
1682
1683 Note:
1684
1685 ========================================================================
1686*/
1687NDIS_STATUS NICInitializeAdapter(
1688 IN PRTMP_ADAPTER pAd,
1689 IN BOOLEAN bHardReset)
1690{
1691 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1692 WPDMA_GLO_CFG_STRUC GloCfg;
1693#ifdef RT2860
1694 UINT32 Value;
1695 DELAY_INT_CFG_STRUC IntCfg;
1696#endif // RT2860 //
1697 ULONG i =0, j=0;
1698 AC_TXOP_CSR0_STRUC csr0;
1699
1700 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n"));
1701
1702 // 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
1703retry:
1704 i = 0;
1705 do
1706 {
1707 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1708 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1709 break;
1710
1711 RTMPusecDelay(1000);
1712 i++;
1713 }while ( i<100);
1714 DBGPRINT(RT_DEBUG_TRACE, ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word));
1715 GloCfg.word &= 0xff0;
1716 GloCfg.field.EnTXWriteBackDDONE =1;
1717 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1718
1719 // Record HW Beacon offset
1720 pAd->BeaconOffset[0] = HW_BEACON_BASE0;
1721 pAd->BeaconOffset[1] = HW_BEACON_BASE1;
1722 pAd->BeaconOffset[2] = HW_BEACON_BASE2;
1723 pAd->BeaconOffset[3] = HW_BEACON_BASE3;
1724 pAd->BeaconOffset[4] = HW_BEACON_BASE4;
1725 pAd->BeaconOffset[5] = HW_BEACON_BASE5;
1726 pAd->BeaconOffset[6] = HW_BEACON_BASE6;
1727 pAd->BeaconOffset[7] = HW_BEACON_BASE7;
1728
1729 //
1730 // write all shared Ring's base address into ASIC
1731 //
1732
1733 // asic simulation sequence put this ahead before loading firmware.
1734 // pbf hardware reset
1735#ifdef RT2860
1736 RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f); // 0x10000 for reset rx, 0x3f resets all 6 tx rings.
1737 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f);
1738 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00);
1739#endif // RT2860 //
1740
1741 // Initialze ASIC for TX & Rx operation
1742 if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
1743 {
1744 if (j++ == 0)
1745 {
1746 NICLoadFirmware(pAd);
1747 goto retry;
1748 }
1749 return NDIS_STATUS_FAILURE;
1750 }
1751
1752
1753#ifdef RT2860
1754 // Write AC_BK base address register
1755 Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa);
1756 RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value);
1757 DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR1 : 0x%x\n", Value));
1758
1759 // Write AC_BE base address register
1760 Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BE].Cell[0].AllocPa);
1761 RTMP_IO_WRITE32(pAd, TX_BASE_PTR0, Value);
1762 DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR0 : 0x%x\n", Value));
1763
1764 // Write AC_VI base address register
1765 Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VI].Cell[0].AllocPa);
1766 RTMP_IO_WRITE32(pAd, TX_BASE_PTR2, Value);
1767 DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR2 : 0x%x\n", Value));
1768
1769 // Write AC_VO base address register
1770 Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VO].Cell[0].AllocPa);
1771 RTMP_IO_WRITE32(pAd, TX_BASE_PTR3, Value);
1772 DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR3 : 0x%x\n", Value));
1773
1774 // Write HCCA base address register
1775 Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_HCCA].Cell[0].AllocPa);
1776 RTMP_IO_WRITE32(pAd, TX_BASE_PTR4, Value);
1777 DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR4 : 0x%x\n", Value));
1778
1779 // Write MGMT_BASE_CSR register
1780 Value = RTMP_GetPhysicalAddressLow(pAd->MgmtRing.Cell[0].AllocPa);
1781 RTMP_IO_WRITE32(pAd, TX_BASE_PTR5, Value);
1782 DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR5 : 0x%x\n", Value));
1783
1784 // Write RX_BASE_CSR register
1785 Value = RTMP_GetPhysicalAddressLow(pAd->RxRing.Cell[0].AllocPa);
1786 RTMP_IO_WRITE32(pAd, RX_BASE_PTR, Value);
1787 DBGPRINT(RT_DEBUG_TRACE, ("--> RX_BASE_PTR : 0x%x\n", Value));
1788
1789 // Init RX Ring index pointer
1790 pAd->RxRing.RxSwReadIdx = 0;
1791 pAd->RxRing.RxCpuIdx = RX_RING_SIZE-1;
1792 RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
1793
1794 // Init TX rings index pointer
1795 {
1796 for (i=0; i<NUM_OF_TX_RING; i++)
1797 {
1798 pAd->TxRing[i].TxSwFreeIdx = 0;
1799 pAd->TxRing[i].TxCpuIdx = 0;
1800 RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) , pAd->TxRing[i].TxCpuIdx);
1801 }
1802 }
1803
1804 // init MGMT ring index pointer
1805 pAd->MgmtRing.TxSwFreeIdx = 0;
1806 pAd->MgmtRing.TxCpuIdx = 0;
1807 RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
1808
1809 //
1810 // set each Ring's SIZE into ASIC. Descriptor Size is fixed by design.
1811 //
1812
1813 // Write TX_RING_CSR0 register
1814 Value = TX_RING_SIZE;
1815 RTMP_IO_WRITE32(pAd, TX_MAX_CNT0, Value);
1816 RTMP_IO_WRITE32(pAd, TX_MAX_CNT1, Value);
1817 RTMP_IO_WRITE32(pAd, TX_MAX_CNT2, Value);
1818 RTMP_IO_WRITE32(pAd, TX_MAX_CNT3, Value);
1819 RTMP_IO_WRITE32(pAd, TX_MAX_CNT4, Value);
1820 Value = MGMT_RING_SIZE;
1821 RTMP_IO_WRITE32(pAd, TX_MGMTMAX_CNT, Value);
1822
1823 // Write RX_RING_CSR register
1824 Value = RX_RING_SIZE;
1825 RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value);
1826#endif // RT2860 //
1827
1828
1829 // WMM parameter
1830 csr0.word = 0;
1831 RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
1832 if (pAd->CommonCfg.PhyMode == PHY_11B)
1833 {
1834 csr0.field.Ac0Txop = 192; // AC_VI: 192*32us ~= 6ms
1835 csr0.field.Ac1Txop = 96; // AC_VO: 96*32us ~= 3ms
1836 }
1837 else
1838 {
1839 csr0.field.Ac0Txop = 96; // AC_VI: 96*32us ~= 3ms
1840 csr0.field.Ac1Txop = 48; // AC_VO: 48*32us ~= 1.5ms
1841 }
1842 RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
1843
1844
1845#ifdef RT2860
1846 // 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
1847 i = 0;
1848 do
1849 {
1850 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
1851 if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
1852 break;
1853
1854 RTMPusecDelay(1000);
1855 i++;
1856 }while ( i < 100);
1857
1858 GloCfg.word &= 0xff0;
1859 GloCfg.field.EnTXWriteBackDDONE =1;
1860 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
1861
1862 IntCfg.word = 0;
1863 RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word);
1864#endif // RT2860 //
1865
1866
1867 // reset action
1868 // Load firmware
1869 // Status = NICLoadFirmware(pAd);
1870
1871 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n"));
1872 return Status;
1873}
1874
1875/*
1876 ========================================================================
1877
1878 Routine Description:
1879 Initialize ASIC
1880
1881 Arguments:
1882 Adapter Pointer to our adapter
1883
1884 Return Value:
1885 None
1886
1887 IRQL = PASSIVE_LEVEL
1888
1889 Note:
1890
1891 ========================================================================
1892*/
1893NDIS_STATUS NICInitializeAsic(
1894 IN PRTMP_ADAPTER pAd,
1895 IN BOOLEAN bHardReset)
1896{
1897 ULONG Index = 0;
1898 UCHAR R0 = 0xff;
1899 UINT32 MacCsr12 = 0, Counter = 0;
1900 USHORT KeyIdx;
1901 INT i,apidx;
1902
1903 DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
1904
1905#ifdef RT2860
1906 if (bHardReset == TRUE)
1907 {
1908 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
1909 }
1910 else
1911 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
1912
1913 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
1914 // Initialize MAC register to default value
1915 for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++)
1916 {
1917 RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register, MACRegTable[Index].Value);
1918 }
1919
1920
1921#ifdef CONFIG_STA_SUPPORT
1922 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1923 {
1924 for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++)
1925 {
1926 RTMP_IO_WRITE32(pAd, STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
1927 }
1928 }
1929#endif // CONFIG_STA_SUPPORT //
1930#endif // RT2860 //
1931
1932
1933 //
1934 // Before program BBP, we need to wait BBP/RF get wake up.
1935 //
1936 Index = 0;
1937 do
1938 {
1939 RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12);
1940
1941 if ((MacCsr12 & 0x03) == 0) // if BB.RF is stable
1942 break;
1943
1944 DBGPRINT(RT_DEBUG_TRACE, ("Check MAC_STATUS_CFG = Busy = %x\n", MacCsr12));
1945 RTMPusecDelay(1000);
1946 } while (Index++ < 100);
1947
1948 // The commands to firmware should be after these commands, these commands will init firmware
1949 // PCI and USB are not the same because PCI driver needs to wait for PCI bus ready
1950 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0); // initialize BBP R/W access agent
1951 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
1952 RTMPusecDelay(1000);
1953
1954 // Read BBP register, make sure BBP is up and running before write new data
1955 Index = 0;
1956 do
1957 {
1958 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0);
1959 DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0));
1960 } while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00)));
1961 //ASSERT(Index < 20); //this will cause BSOD on Check-build driver
1962
1963 if ((R0 == 0xff) || (R0 == 0x00))
1964 return NDIS_STATUS_FAILURE;
1965
1966 // Initialize BBP register to default value
1967 for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
1968 {
1969 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value);
1970 }
1971
1972 // for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
1973 if ((pAd->MACVersion&0xffff) != 0x0101)
1974 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
1975
1976
1977 if (pAd->MACVersion == 0x28600100)
1978 {
1979 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1980 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
1981 }
1982
1983 if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION) // 3*3
1984 {
1985 // enlarge MAX_LEN_CFG
1986 UINT32 csr;
1987 RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr);
1988 csr &= 0xFFF;
1989 csr |= 0x2000;
1990 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
1991 }
1992
1993
1994 // Add radio off control
1995#ifdef CONFIG_STA_SUPPORT
1996 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1997 {
1998 if (pAd->StaCfg.bRadio == FALSE)
1999 {
2000// RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
2001 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
2002 DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n"));
2003 }
2004 }
2005#endif // CONFIG_STA_SUPPORT //
2006
2007 // Clear raw counters
2008 RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
2009 RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
2010 RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
2011 RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
2012 RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
2013 RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
2014
2015 // ASIC will keep garbage value after boot
2016 // Clear all seared key table when initial
2017 // This routine can be ignored in radio-ON/OFF operation.
2018 if (bHardReset)
2019 {
2020 for (KeyIdx = 0; KeyIdx < 4; KeyIdx++)
2021 {
2022 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4*KeyIdx, 0);
2023 }
2024
2025 // Clear all pairwise key table when initial
2026 for (KeyIdx = 0; KeyIdx < 256; KeyIdx++)
2027 {
2028 RTMP_IO_WRITE32(pAd, MAC_WCID_ATTRIBUTE_BASE + (KeyIdx * HW_WCID_ATTRI_SIZE), 1);
2029 }
2030 }
2031
2032
2033 // It isn't necessary to clear this space when not hard reset.
2034 if (bHardReset == TRUE)
2035 {
2036 // clear all on-chip BEACON frame space
2037 for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++)
2038 {
2039 for (i = 0; i < HW_BEACON_OFFSET>>2; i+=4)
2040 RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00);
2041 }
2042 }
2043
2044#ifdef CONFIG_STA_SUPPORT
2045 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
2046 {
2047 // for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT.
2048 if ((pAd->MACVersion&0xffff) != 0x0101)
2049 RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f);
2050 }
2051#endif // CONFIG_STA_SUPPORT //
2052
2053 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n"));
2054 return NDIS_STATUS_SUCCESS;
2055}
2056
2057/*
2058 ========================================================================
2059
2060 Routine Description:
2061 Reset NIC Asics
2062
2063 Arguments:
2064 Adapter Pointer to our adapter
2065
2066 Return Value:
2067 None
2068
2069 IRQL = PASSIVE_LEVEL
2070
2071 Note:
2072 Reset NIC to initial state AS IS system boot up time.
2073
2074 ========================================================================
2075*/
2076VOID NICIssueReset(
2077 IN PRTMP_ADAPTER pAd)
2078{
2079 UINT32 Value = 0;
2080 DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n"));
2081
2082 // Disable Rx, register value supposed will remain after reset
2083 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
2084 Value &= (0xfffffff3);
2085 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
2086
2087 // Issue reset and clear from reset state
2088 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03); // 2004-09-17 change from 0x01
2089 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
2090
2091 DBGPRINT(RT_DEBUG_TRACE, ("<-- NICIssueReset\n"));
2092}
2093
2094/*
2095 ========================================================================
2096
2097 Routine Description:
2098 Check ASIC registers and find any reason the system might hang
2099
2100 Arguments:
2101 Adapter Pointer to our adapter
2102
2103 Return Value:
2104 None
2105
2106 IRQL = DISPATCH_LEVEL
2107
2108 ========================================================================
2109*/
2110BOOLEAN NICCheckForHang(
2111 IN PRTMP_ADAPTER pAd)
2112{
2113 return (FALSE);
2114}
2115
2116VOID NICUpdateFifoStaCounters(
2117 IN PRTMP_ADAPTER pAd)
2118{
2119 TX_STA_FIFO_STRUC StaFifo;
2120 MAC_TABLE_ENTRY *pEntry;
2121 UCHAR i = 0;
2122 UCHAR pid = 0, wcid = 0;
2123 CHAR reTry;
2124 UCHAR succMCS;
2125
2126#ifdef RALINK_ATE
2127 /* Nothing to do in ATE mode */
2128 if (ATE_ON(pAd))
2129 return;
2130#endif // RALINK_ATE //
2131
2132 do
2133 {
2134 RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
2135
2136 if (StaFifo.field.bValid == 0)
2137 break;
2138
2139 wcid = (UCHAR)StaFifo.field.wcid;
2140
2141
2142 /* ignore NoACK and MGMT frame use 0xFF as WCID */
2143 if ((StaFifo.field.TxAckRequired == 0) || (wcid >= MAX_LEN_OF_MAC_TABLE))
2144 {
2145 i++;
2146 continue;
2147 }
2148
2149 /* PID store Tx MCS Rate */
2150 pid = (UCHAR)StaFifo.field.PidType;
2151
2152 pEntry = &pAd->MacTab.Content[wcid];
2153
2154 pEntry->DebugFIFOCount++;
2155
2156#ifdef DOT11_N_SUPPORT
2157 if (StaFifo.field.TxBF) // 3*3
2158 pEntry->TxBFCount++;
2159#endif // DOT11_N_SUPPORT //
2160
2161#ifdef UAPSD_AP_SUPPORT
2162 UAPSD_SP_AUE_Handle(pAd, pEntry, StaFifo.field.TxSuccess);
2163#endif // UAPSD_AP_SUPPORT //
2164
2165 if (!StaFifo.field.TxSuccess)
2166 {
2167 pEntry->FIFOCount++;
2168 pEntry->OneSecTxFailCount++;
2169
2170 if (pEntry->FIFOCount >= 1)
2171 {
2172 DBGPRINT(RT_DEBUG_TRACE, ("#"));
2173#if 0
2174 SendRefreshBAR(pAd, pEntry);
2175 pEntry->NoBADataCountDown = 64;
2176#else
2177#ifdef DOT11_N_SUPPORT
2178 pEntry->NoBADataCountDown = 64;
2179#endif // DOT11_N_SUPPORT //
2180
2181 if(pEntry->PsMode == PWR_ACTIVE)
2182 {
2183#ifdef DOT11_N_SUPPORT
2184 int tid;
2185 for (tid=0; tid<NUM_OF_TID; tid++)
2186 {
2187 BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, FALSE);
2188 }
2189#endif // DOT11_N_SUPPORT //
2190
2191 // Update the continuous transmission counter except PS mode
2192 pEntry->ContinueTxFailCnt++;
2193 }
2194 else
2195 {
2196 // Clear the FIFOCount when sta in Power Save mode. Basically we assume
2197 // this tx error happened due to sta just go to sleep.
2198 pEntry->FIFOCount = 0;
2199 pEntry->ContinueTxFailCnt = 0;
2200 }
2201#endif
2202 //pEntry->FIFOCount = 0;
2203 }
2204 //pEntry->bSendBAR = TRUE;
2205 }
2206 else
2207 {
2208#ifdef DOT11_N_SUPPORT
2209 if ((pEntry->PsMode != PWR_SAVE) && (pEntry->NoBADataCountDown > 0))
2210 {
2211 pEntry->NoBADataCountDown--;
2212 if (pEntry->NoBADataCountDown==0)
2213 {
2214 DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
2215 }
2216 }
2217#endif // DOT11_N_SUPPORT //
2218 pEntry->FIFOCount = 0;
2219 pEntry->OneSecTxNoRetryOkCount++;
2220 // update NoDataIdleCount when sucessful send packet to STA.
2221 pEntry->NoDataIdleCount = 0;
2222 pEntry->ContinueTxFailCnt = 0;
2223 }
2224
2225 succMCS = StaFifo.field.SuccessRate & 0x7F;
2226
2227 reTry = pid - succMCS;
2228
2229 if (StaFifo.field.TxSuccess)
2230 {
2231 pEntry->TXMCSExpected[pid]++;
2232 if (pid == succMCS)
2233 {
2234 pEntry->TXMCSSuccessful[pid]++;
2235 }
2236 else
2237 {
2238 pEntry->TXMCSAutoFallBack[pid][succMCS]++;
2239 }
2240 }
2241 else
2242 {
2243 pEntry->TXMCSFailed[pid]++;
2244 }
2245
2246 if (reTry > 0)
2247 {
2248 if ((pid >= 12) && succMCS <=7)
2249 {
2250 reTry -= 4;
2251 }
2252 pEntry->OneSecTxRetryOkCount += reTry;
2253 }
2254
2255 i++;
2256 // ASIC store 16 stack
2257 } while ( i < (2*TX_RING_SIZE) );
2258
2259}
2260
2261/*
2262 ========================================================================
2263
2264 Routine Description:
2265 Read statistical counters from hardware registers and record them
2266 in software variables for later on query
2267
2268 Arguments:
2269 pAd Pointer to our adapter
2270
2271 Return Value:
2272 None
2273
2274 IRQL = DISPATCH_LEVEL
2275
2276 ========================================================================
2277*/
2278VOID NICUpdateRawCounters(
2279 IN PRTMP_ADAPTER pAd)
2280{
2281 UINT32 OldValue;
2282 RX_STA_CNT0_STRUC RxStaCnt0;
2283 RX_STA_CNT1_STRUC RxStaCnt1;
2284 RX_STA_CNT2_STRUC RxStaCnt2;
2285 TX_STA_CNT0_STRUC TxStaCnt0;
2286 TX_STA_CNT1_STRUC StaTx1;
2287 TX_STA_CNT2_STRUC StaTx2;
2288 TX_AGG_CNT_STRUC TxAggCnt;
2289 TX_AGG_CNT0_STRUC TxAggCnt0;
2290 TX_AGG_CNT1_STRUC TxAggCnt1;
2291 TX_AGG_CNT2_STRUC TxAggCnt2;
2292 TX_AGG_CNT3_STRUC TxAggCnt3;
2293 TX_AGG_CNT4_STRUC TxAggCnt4;
2294 TX_AGG_CNT5_STRUC TxAggCnt5;
2295 TX_AGG_CNT6_STRUC TxAggCnt6;
2296 TX_AGG_CNT7_STRUC TxAggCnt7;
2297
2298 RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word);
2299 RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word);
2300
2301 {
2302 RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
2303 // Update RX PLCP error counter
2304 pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr;
2305 // Update False CCA counter
2306 pAd->RalinkCounters.OneSecFalseCCACnt += RxStaCnt1.field.FalseCca;
2307 }
2308
2309 // Update FCS counters
2310 OldValue= pAd->WlanCounters.FCSErrorCount.u.LowPart;
2311 pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); // >> 7);
2312 if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue)
2313 pAd->WlanCounters.FCSErrorCount.u.HighPart++;
2314
2315 // Add FCS error count to private counters
2316 pAd->RalinkCounters.OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
2317 OldValue = pAd->RalinkCounters.RealFcsErrCount.u.LowPart;
2318 pAd->RalinkCounters.RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
2319 if (pAd->RalinkCounters.RealFcsErrCount.u.LowPart < OldValue)
2320 pAd->RalinkCounters.RealFcsErrCount.u.HighPart++;
2321
2322 // Update Duplicate Rcv check
2323 pAd->RalinkCounters.DuplicateRcv += RxStaCnt2.field.RxDupliCount;
2324 pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount;
2325 // Update RX Overflow counter
2326 pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
2327
2328 if (!pAd->bUpdateBcnCntDone)
2329 {
2330 // Update BEACON sent count
2331 RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
2332 RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
2333 RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
2334 pAd->RalinkCounters.OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount;
2335 pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
2336 pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
2337 pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
2338 pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
2339 pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
2340 pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
2341 }
2342
2343 {
2344 RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word);
2345 RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word);
2346 RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word);
2347 RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word);
2348 RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word);
2349 RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word);
2350 RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word);
2351 RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word);
2352 RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word);
2353 pAd->RalinkCounters.TxAggCount += TxAggCnt.field.AggTxCount;
2354 pAd->RalinkCounters.TxNonAggCount += TxAggCnt.field.NonAggTxCount;
2355 pAd->RalinkCounters.TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count;
2356 pAd->RalinkCounters.TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count;
2357
2358 pAd->RalinkCounters.TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count;
2359 pAd->RalinkCounters.TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count;
2360 pAd->RalinkCounters.TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count;
2361 pAd->RalinkCounters.TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count;
2362
2363 pAd->RalinkCounters.TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count;
2364 pAd->RalinkCounters.TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count;
2365 pAd->RalinkCounters.TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count;
2366 pAd->RalinkCounters.TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count;
2367
2368 pAd->RalinkCounters.TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count;
2369 pAd->RalinkCounters.TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count;
2370 pAd->RalinkCounters.TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count;
2371 pAd->RalinkCounters.TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count;
2372
2373 pAd->RalinkCounters.TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count;
2374 pAd->RalinkCounters.TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count;
2375
2376 // Calculate the transmitted A-MPDU count
2377 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count;
2378 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2);
2379
2380 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3);
2381 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4);
2382
2383 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5);
2384 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6);
2385
2386 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7);
2387 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8);
2388
2389 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9);
2390 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10);
2391
2392 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11);
2393 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12);
2394
2395 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13);
2396 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14);
2397
2398 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15);
2399 pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16);
2400 }
2401
2402#ifdef DBG_DIAGNOSE
2403 {
2404 RtmpDiagStruct *pDiag;
2405 COUNTER_RALINK *pRalinkCounters;
2406 UCHAR ArrayCurIdx, i;
2407
2408 pDiag = &pAd->DiagStruct;
2409 pRalinkCounters = &pAd->RalinkCounters;
2410 ArrayCurIdx = pDiag->ArrayCurIdx;
2411
2412 if (pDiag->inited == 0)
2413 {
2414 NdisZeroMemory(pDiag, sizeof(struct _RtmpDiagStrcut_));
2415 pDiag->ArrayStartIdx = pDiag->ArrayCurIdx = 0;
2416 pDiag->inited = 1;
2417 }
2418 else
2419 {
2420 // Tx
2421 pDiag->TxFailCnt[ArrayCurIdx] = TxStaCnt0.field.TxFailCount;
2422 pDiag->TxAggCnt[ArrayCurIdx] = TxAggCnt.field.AggTxCount;
2423 pDiag->TxNonAggCnt[ArrayCurIdx] = TxAggCnt.field.NonAggTxCount;
2424 pDiag->TxAMPDUCnt[ArrayCurIdx][0] = TxAggCnt0.field.AggSize1Count;
2425 pDiag->TxAMPDUCnt[ArrayCurIdx][1] = TxAggCnt0.field.AggSize2Count;
2426 pDiag->TxAMPDUCnt[ArrayCurIdx][2] = TxAggCnt1.field.AggSize3Count;
2427 pDiag->TxAMPDUCnt[ArrayCurIdx][3] = TxAggCnt1.field.AggSize4Count;
2428 pDiag->TxAMPDUCnt[ArrayCurIdx][4] = TxAggCnt2.field.AggSize5Count;
2429 pDiag->TxAMPDUCnt[ArrayCurIdx][5] = TxAggCnt2.field.AggSize6Count;
2430 pDiag->TxAMPDUCnt[ArrayCurIdx][6] = TxAggCnt3.field.AggSize7Count;
2431 pDiag->TxAMPDUCnt[ArrayCurIdx][7] = TxAggCnt3.field.AggSize8Count;
2432 pDiag->TxAMPDUCnt[ArrayCurIdx][8] = TxAggCnt4.field.AggSize9Count;
2433 pDiag->TxAMPDUCnt[ArrayCurIdx][9] = TxAggCnt4.field.AggSize10Count;
2434 pDiag->TxAMPDUCnt[ArrayCurIdx][10] = TxAggCnt5.field.AggSize11Count;
2435 pDiag->TxAMPDUCnt[ArrayCurIdx][11] = TxAggCnt5.field.AggSize12Count;
2436 pDiag->TxAMPDUCnt[ArrayCurIdx][12] = TxAggCnt6.field.AggSize13Count;
2437 pDiag->TxAMPDUCnt[ArrayCurIdx][13] = TxAggCnt6.field.AggSize14Count;
2438 pDiag->TxAMPDUCnt[ArrayCurIdx][14] = TxAggCnt7.field.AggSize15Count;
2439 pDiag->TxAMPDUCnt[ArrayCurIdx][15] = TxAggCnt7.field.AggSize16Count;
2440
2441 pDiag->RxCrcErrCnt[ArrayCurIdx] = RxStaCnt0.field.CrcErr;
2442
2443 INC_RING_INDEX(pDiag->ArrayCurIdx, DIAGNOSE_TIME);
2444 ArrayCurIdx = pDiag->ArrayCurIdx;
2445 for (i =0; i < 9; i++)
2446 {
2447 pDiag->TxDescCnt[ArrayCurIdx][i]= 0;
2448 pDiag->TxSWQueCnt[ArrayCurIdx][i] =0;
2449 pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
2450 pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
2451 }
2452 pDiag->TxDataCnt[ArrayCurIdx] = 0;
2453 pDiag->TxFailCnt[ArrayCurIdx] = 0;
2454 pDiag->RxDataCnt[ArrayCurIdx] = 0;
2455 pDiag->RxCrcErrCnt[ArrayCurIdx] = 0;
2456 for (i = 9; i < 24; i++) // 3*3
2457 {
2458 pDiag->TxDescCnt[ArrayCurIdx][i] = 0;
2459 pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
2460 pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
2461}
2462
2463 if (pDiag->ArrayCurIdx == pDiag->ArrayStartIdx)
2464 INC_RING_INDEX(pDiag->ArrayStartIdx, DIAGNOSE_TIME);
2465 }
2466
2467 }
2468#endif // DBG_DIAGNOSE //
2469
2470
2471}
2472
2473
2474/*
2475 ========================================================================
2476
2477 Routine Description:
2478 Reset NIC from error
2479
2480 Arguments:
2481 Adapter Pointer to our adapter
2482
2483 Return Value:
2484 None
2485
2486 IRQL = PASSIVE_LEVEL
2487
2488 Note:
2489 Reset NIC from error state
2490
2491 ========================================================================
2492*/
2493VOID NICResetFromError(
2494 IN PRTMP_ADAPTER pAd)
2495{
2496 // Reset BBP (according to alex, reset ASIC will force reset BBP
2497 // Therefore, skip the reset BBP
2498 // RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2);
2499
2500 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
2501 // Remove ASIC from reset state
2502 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
2503
2504 NICInitializeAdapter(pAd, FALSE);
2505 NICInitAsicFromEEPROM(pAd);
2506
2507 // Switch to current channel, since during reset process, the connection should remains on.
2508 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
2509 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
2510}
2511
2512/*
2513 ========================================================================
2514
2515 Routine Description:
2516 erase 8051 firmware image in MAC ASIC
2517
2518 Arguments:
2519 Adapter Pointer to our adapter
2520
2521 IRQL = PASSIVE_LEVEL
2522
2523 ========================================================================
2524*/
2525VOID NICEraseFirmware(
2526 IN PRTMP_ADAPTER pAd)
2527{
2528 ULONG i;
2529
2530 for(i=0; i<MAX_FIRMWARE_IMAGE_SIZE; i+=4)
2531 RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
2532
2533}/* End of NICEraseFirmware */
2534
2535/*
2536 ========================================================================
2537
2538 Routine Description:
2539 Load 8051 firmware RT2561.BIN file into MAC ASIC
2540
2541 Arguments:
2542 Adapter Pointer to our adapter
2543
2544 Return Value:
2545 NDIS_STATUS_SUCCESS firmware image load ok
2546 NDIS_STATUS_FAILURE image not found
2547
2548 IRQL = PASSIVE_LEVEL
2549
2550 ========================================================================
2551*/
2552NDIS_STATUS NICLoadFirmware(
2553 IN PRTMP_ADAPTER pAd)
2554{
2555#ifdef BIN_IN_FILE
2556#define NICLF_DEFAULT_USE() \
2557 flg_default_firm_use = TRUE; \
2558 printk("%s - Use default firmware!\n", __FUNCTION__);
2559
2560 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
2561 PUCHAR src;
2562 struct file *srcf;
2563 INT retval, orgfsuid, orgfsgid, i;
2564 mm_segment_t orgfs;
2565 PUCHAR pFirmwareImage;
2566 UINT FileLength = 0;
2567 UINT32 MacReg;
2568 ULONG Index;
2569 ULONG firm;
2570 BOOLEAN flg_default_firm_use = FALSE;
2571
2572
2573 DBGPRINT(RT_DEBUG_TRACE, ("===> %s\n", __FUNCTION__));
2574
2575 /* init */
2576 pFirmwareImage = NULL;
2577 src = RTMP_FIRMWARE_FILE_NAME;
2578
2579 /* save uid and gid used for filesystem access.
2580 set user and group to 0 (root) */
2581 orgfsuid = current->fsuid;
2582 orgfsgid = current->fsgid;
2583 current->fsuid = current->fsgid = 0;
2584 orgfs = get_fs();
2585 set_fs(KERNEL_DS);
2586
2587 pAd->FirmwareVersion = (FIRMWARE_MAJOR_VERSION << 8) + \
2588 FIRMWARE_MINOR_VERSION;
2589
2590
2591 /* allocate firmware buffer */
2592 pFirmwareImage = kmalloc(MAX_FIRMWARE_IMAGE_SIZE, MEM_ALLOC_FLAG);
2593 if (pFirmwareImage == NULL)
2594 {
2595 /* allocate fail, use default firmware array in firmware.h */
2596 printk("%s - Allocate memory fail!\n", __FUNCTION__);
2597 NICLF_DEFAULT_USE();
2598 }
2599 else
2600 {
2601 /* allocate ok! zero the firmware buffer */
2602 memset(pFirmwareImage, 0x00, MAX_FIRMWARE_IMAGE_SIZE);
2603 } /* End of if */
2604
2605
2606 /* if ok, read firmware file from *.bin file */
2607 if (flg_default_firm_use == FALSE)
2608 {
2609 do
2610 {
2611 /* open the bin file */
2612 srcf = filp_open(src, O_RDONLY, 0);
2613
2614 if (IS_ERR(srcf))
2615 {
2616 printk("%s - Error %ld opening %s\n",
2617 __FUNCTION__, -PTR_ERR(srcf), src);
2618 NICLF_DEFAULT_USE();
2619 break;
2620 } /* End of if */
2621
2622 /* the object must have a read method */
2623 if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
2624 {
2625 printk("%s - %s does not have a write method\n", __FUNCTION__, src);
2626 NICLF_DEFAULT_USE();
2627 break;
2628 } /* End of if */
2629
2630 /* read the firmware from the file *.bin */
2631 FileLength = srcf->f_op->read(srcf,
2632 pFirmwareImage,
2633 MAX_FIRMWARE_IMAGE_SIZE,
2634 &srcf->f_pos);
2635
2636 if (FileLength != MAX_FIRMWARE_IMAGE_SIZE)
2637 {
2638 printk("%s: error file length (=%d) in RT2860AP.BIN\n",
2639 __FUNCTION__, FileLength);
2640 NICLF_DEFAULT_USE();
2641 break;
2642 }
2643 else
2644 {
2645 PUCHAR ptr = pFirmwareImage;
2646 USHORT crc = 0xffff;
2647
2648
2649 /* calculate firmware CRC */
2650 for(i=0; i<(MAX_FIRMWARE_IMAGE_SIZE-2); i++, ptr++)
2651 crc = ByteCRC16(BitReverse(*ptr), crc);
2652 /* End of for */
2653
2654 if ((pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2] != \
2655 (UCHAR)BitReverse((UCHAR)(crc>>8))) ||
2656 (pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1] != \
2657 (UCHAR)BitReverse((UCHAR)crc)))
2658 {
2659 /* CRC fail */
2660 printk("%s: CRC = 0x%02x 0x%02x "
2661 "error, should be 0x%02x 0x%02x\n",
2662 __FUNCTION__,
2663 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2],
2664 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1],
2665 (UCHAR)(crc>>8), (UCHAR)(crc));
2666 NICLF_DEFAULT_USE();
2667 break;
2668 }
2669 else
2670 {
2671 /* firmware is ok */
2672 pAd->FirmwareVersion = \
2673 (pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4] << 8) +
2674 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3];
2675
2676 /* check if firmware version of the file is too old */
2677 if ((pAd->FirmwareVersion) < \
2678 ((FIRMWARE_MAJOR_VERSION << 8) +
2679 FIRMWARE_MINOR_VERSION))
2680 {
2681 printk("%s: firmware version too old!\n", __FUNCTION__);
2682 NICLF_DEFAULT_USE();
2683 break;
2684 } /* End of if */
2685 } /* End of if */
2686
2687 DBGPRINT(RT_DEBUG_TRACE,
2688 ("NICLoadFirmware: CRC ok, ver=%d.%d\n",
2689 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4],
2690 pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3]));
2691 } /* End of if (FileLength == MAX_FIRMWARE_IMAGE_SIZE) */
2692 break;
2693 } while(TRUE);
2694
2695 /* close firmware file */
2696 if (IS_ERR(srcf))
2697 ;
2698 else
2699 {
2700 retval = filp_close(srcf, NULL);
2701 if (retval)
2702 {
2703 DBGPRINT(RT_DEBUG_ERROR,
2704 ("--> Error %d closing %s\n", -retval, src));
2705 } /* End of if */
2706 } /* End of if */
2707 } /* End of if */
2708
2709
2710 /* write firmware to ASIC */
2711 if (flg_default_firm_use == TRUE)
2712 {
2713 /* use default fimeware, free allocated buffer */
2714 if (pFirmwareImage != NULL)
2715 kfree(pFirmwareImage);
2716 /* End of if */
2717
2718 /* use default *.bin array */
2719 pFirmwareImage = FirmwareImage;
2720 FileLength = sizeof(FirmwareImage);
2721 } /* End of if */
2722
2723 /* enable Host program ram write selection */
2724 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x10000);
2725
2726 for(i=0; i<FileLength; i+=4)
2727 {
2728 firm = pFirmwareImage[i] +
2729 (pFirmwareImage[i+3] << 24) +
2730 (pFirmwareImage[i+2] << 16) +
2731 (pFirmwareImage[i+1] << 8);
2732
2733 RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, firm);
2734 } /* End of for */
2735
2736 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00000);
2737 RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00001);
2738
2739 /* initialize BBP R/W access agent */
2740 RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);
2741 RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
2742
2743 if (flg_default_firm_use == FALSE)
2744 {
2745 /* use file firmware, free allocated buffer */
2746 if (pFirmwareImage != NULL)
2747 kfree(pFirmwareImage);
2748 /* End of if */
2749 } /* End of if */
2750
2751 set_fs(orgfs);
2752 current->fsuid = orgfsuid;
2753 current->fsgid = orgfsgid;
2754#else
2755
2756 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
2757 PUCHAR pFirmwareImage;
2758 ULONG FileLength, Index;
2759 //ULONG firm;
2760 UINT32 MacReg = 0;
2761
2762 pFirmwareImage = FirmwareImage;
2763 FileLength = sizeof(FirmwareImage);
2764 RT28XX_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
2765#endif
2766
2767 /* check if MCU is ready */
2768 Index = 0;
2769 do
2770 {
2771 RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
2772
2773 if (MacReg & 0x80)
2774 break;
2775
2776 RTMPusecDelay(1000);
2777 } while (Index++ < 1000);
2778
2779 if (Index >= 1000)
2780 {
2781 Status = NDIS_STATUS_FAILURE;
2782 DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
2783 } /* End of if */
2784
2785 DBGPRINT(RT_DEBUG_TRACE,
2786 ("<=== %s (status=%d)\n", __FUNCTION__, Status));
2787 return Status;
2788} /* End of NICLoadFirmware */
2789
2790
2791/*
2792 ========================================================================
2793
2794 Routine Description:
2795 Load Tx rate switching parameters
2796
2797 Arguments:
2798 Adapter Pointer to our adapter
2799
2800 Return Value:
2801 NDIS_STATUS_SUCCESS firmware image load ok
2802 NDIS_STATUS_FAILURE image not found
2803
2804 IRQL = PASSIVE_LEVEL
2805
2806 Rate Table Format:
2807 1. (B0: Valid Item number) (B1:Initial item from zero)
2808 2. Item Number(Dec) Mode(Hex) Current MCS(Dec) TrainUp(Dec) TrainDown(Dec)
2809
2810 ========================================================================
2811*/
2812NDIS_STATUS NICLoadRateSwitchingParams(
2813 IN PRTMP_ADAPTER pAd)
2814{
2815 return NDIS_STATUS_SUCCESS;
2816}
2817
2818/*
2819 ========================================================================
2820
2821 Routine Description:
2822 if pSrc1 all zero with length Length, return 0.
2823 If not all zero, return 1
2824
2825 Arguments:
2826 pSrc1
2827
2828 Return Value:
2829 1: not all zero
2830 0: all zero
2831
2832 IRQL = DISPATCH_LEVEL
2833
2834 Note:
2835
2836 ========================================================================
2837*/
2838ULONG RTMPNotAllZero(
2839 IN PVOID pSrc1,
2840 IN ULONG Length)
2841{
2842 PUCHAR pMem1;
2843 ULONG Index = 0;
2844
2845 pMem1 = (PUCHAR) pSrc1;
2846
2847 for (Index = 0; Index < Length; Index++)
2848 {
2849 if (pMem1[Index] != 0x0)
2850 {
2851 break;
2852 }
2853 }
2854
2855 if (Index == Length)
2856 {
2857 return (0);
2858 }
2859 else
2860 {
2861 return (1);
2862 }
2863}
2864
2865/*
2866 ========================================================================
2867
2868 Routine Description:
2869 Compare two memory block
2870
2871 Arguments:
2872 pSrc1 Pointer to first memory address
2873 pSrc2 Pointer to second memory address
2874
2875 Return Value:
2876 0: memory is equal
2877 1: pSrc1 memory is larger
2878 2: pSrc2 memory is larger
2879
2880 IRQL = DISPATCH_LEVEL
2881
2882 Note:
2883
2884 ========================================================================
2885*/
2886ULONG RTMPCompareMemory(
2887 IN PVOID pSrc1,
2888 IN PVOID pSrc2,
2889 IN ULONG Length)
2890{
2891 PUCHAR pMem1;
2892 PUCHAR pMem2;
2893 ULONG Index = 0;
2894
2895 pMem1 = (PUCHAR) pSrc1;
2896 pMem2 = (PUCHAR) pSrc2;
2897
2898 for (Index = 0; Index < Length; Index++)
2899 {
2900 if (pMem1[Index] > pMem2[Index])
2901 return (1);
2902 else if (pMem1[Index] < pMem2[Index])
2903 return (2);
2904 }
2905
2906 // Equal
2907 return (0);
2908}
2909
2910/*
2911 ========================================================================
2912
2913 Routine Description:
2914 Zero out memory block
2915
2916 Arguments:
2917 pSrc1 Pointer to memory address
2918 Length Size
2919
2920 Return Value:
2921 None
2922
2923 IRQL = PASSIVE_LEVEL
2924 IRQL = DISPATCH_LEVEL
2925
2926 Note:
2927
2928 ========================================================================
2929*/
2930VOID RTMPZeroMemory(
2931 IN PVOID pSrc,
2932 IN ULONG Length)
2933{
2934 PUCHAR pMem;
2935 ULONG Index = 0;
2936
2937 pMem = (PUCHAR) pSrc;
2938
2939 for (Index = 0; Index < Length; Index++)
2940 {
2941 pMem[Index] = 0x00;
2942 }
2943}
2944
2945VOID RTMPFillMemory(
2946 IN PVOID pSrc,
2947 IN ULONG Length,
2948 IN UCHAR Fill)
2949{
2950 PUCHAR pMem;
2951 ULONG Index = 0;
2952
2953 pMem = (PUCHAR) pSrc;
2954
2955 for (Index = 0; Index < Length; Index++)
2956 {
2957 pMem[Index] = Fill;
2958 }
2959}
2960
2961/*
2962 ========================================================================
2963
2964 Routine Description:
2965 Copy data from memory block 1 to memory block 2
2966
2967 Arguments:
2968 pDest Pointer to destination memory address
2969 pSrc Pointer to source memory address
2970 Length Copy size
2971
2972 Return Value:
2973 None
2974
2975 IRQL = PASSIVE_LEVEL
2976 IRQL = DISPATCH_LEVEL
2977
2978 Note:
2979
2980 ========================================================================
2981*/
2982VOID RTMPMoveMemory(
2983 OUT PVOID pDest,
2984 IN PVOID pSrc,
2985 IN ULONG Length)
2986{
2987 PUCHAR pMem1;
2988 PUCHAR pMem2;
2989 UINT Index;
2990
2991 ASSERT((Length==0) || (pDest && pSrc));
2992
2993 pMem1 = (PUCHAR) pDest;
2994 pMem2 = (PUCHAR) pSrc;
2995
2996 for (Index = 0; Index < Length; Index++)
2997 {
2998 pMem1[Index] = pMem2[Index];
2999 }
3000}
3001
3002/*
3003 ========================================================================
3004
3005 Routine Description:
3006 Initialize port configuration structure
3007
3008 Arguments:
3009 Adapter Pointer to our adapter
3010
3011 Return Value:
3012 None
3013
3014 IRQL = PASSIVE_LEVEL
3015
3016 Note:
3017
3018 ========================================================================
3019*/
3020VOID UserCfgInit(
3021 IN PRTMP_ADAPTER pAd)
3022{
3023 UINT key_index, bss_index;
3024
3025 DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
3026
3027 //
3028 // part I. intialize common configuration
3029 //
3030
3031 for(key_index=0; key_index<SHARE_KEY_NUM; key_index++)
3032 {
3033 for(bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++)
3034 {
3035 pAd->SharedKey[bss_index][key_index].KeyLen = 0;
3036 pAd->SharedKey[bss_index][key_index].CipherAlg = CIPHER_NONE;
3037 }
3038 }
3039
3040 pAd->Antenna.word = 0;
3041 pAd->CommonCfg.BBPCurrentBW = BW_20;
3042
3043 pAd->LedCntl.word = 0;
3044#ifdef RT2860
3045 pAd->LedIndicatorStregth = 0;
3046 pAd->RLnkCtrlOffset = 0;
3047 pAd->HostLnkCtrlOffset = 0;
3048#endif // RT2860 //
3049
3050 pAd->bAutoTxAgcA = FALSE; // Default is OFF
3051 pAd->bAutoTxAgcG = FALSE; // Default is OFF
3052 pAd->RfIcType = RFIC_2820;
3053
3054 // Init timer for reset complete event
3055 pAd->CommonCfg.CentralChannel = 1;
3056 pAd->bForcePrintTX = FALSE;
3057 pAd->bForcePrintRX = FALSE;
3058 pAd->bStaFifoTest = FALSE;
3059 pAd->bProtectionTest = FALSE;
3060 pAd->bHCCATest = FALSE;
3061 pAd->bGenOneHCCA = FALSE;
3062 pAd->CommonCfg.Dsifs = 10; // in units of usec
3063 pAd->CommonCfg.TxPower = 100; //mW
3064 pAd->CommonCfg.TxPowerPercentage = 0xffffffff; // AUTO
3065 pAd->CommonCfg.TxPowerDefault = 0xffffffff; // AUTO
3066 pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto; // use Long preamble on TX by defaut
3067 pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
3068 pAd->CommonCfg.RtsThreshold = 2347;
3069 pAd->CommonCfg.FragmentThreshold = 2346;
3070 pAd->CommonCfg.UseBGProtection = 0; // 0: AUTO
3071 pAd->CommonCfg.bEnableTxBurst = TRUE; //0;
3072 pAd->CommonCfg.PhyMode = 0xff; // unknown
3073 pAd->CommonCfg.BandState = UNKNOWN_BAND;
3074 pAd->CommonCfg.RadarDetect.CSPeriod = 10;
3075 pAd->CommonCfg.RadarDetect.CSCount = 0;
3076 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
3077 pAd->CommonCfg.RadarDetect.ChMovingTime = 65;
3078 pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3;
3079 pAd->CommonCfg.bAPSDCapable = FALSE;
3080 pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
3081 pAd->CommonCfg.TriggerTimerCount = 0;
3082 pAd->CommonCfg.bAPSDForcePowerSave = FALSE;
3083 pAd->CommonCfg.bCountryFlag = FALSE;
3084 pAd->CommonCfg.TxStream = 0;
3085 pAd->CommonCfg.RxStream = 0;
3086
3087 NdisZeroMemory(&pAd->BeaconTxWI, sizeof(pAd->BeaconTxWI));
3088
3089#ifdef DOT11_N_SUPPORT
3090 NdisZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
3091 pAd->HTCEnable = FALSE;
3092 pAd->bBroadComHT = FALSE;
3093 pAd->CommonCfg.bRdg = FALSE;
3094
3095#ifdef DOT11N_DRAFT3
3096 pAd->CommonCfg.Dot11OBssScanPassiveDwell = dot11OBSSScanPassiveDwell; // Unit : TU. 5~1000
3097 pAd->CommonCfg.Dot11OBssScanActiveDwell = dot11OBSSScanActiveDwell; // Unit : TU. 10~1000
3098 pAd->CommonCfg.Dot11BssWidthTriggerScanInt = dot11BSSWidthTriggerScanInterval; // Unit : Second
3099 pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = dot11OBSSScanPassiveTotalPerChannel; // Unit : TU. 200~10000
3100 pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = dot11OBSSScanActiveTotalPerChannel; // Unit : TU. 20~10000
3101 pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = dot11BSSWidthChannelTransactionDelayFactor;
3102 pAd->CommonCfg.Dot11OBssScanActivityThre = dot11BSSScanActivityThreshold; // Unit : percentage
3103 pAd->CommonCfg.Dot11BssWidthChanTranDelay = (pAd->CommonCfg.Dot11BssWidthTriggerScanInt * pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor);
3104#endif // DOT11N_DRAFT3 //
3105
3106 NdisZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
3107 pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
3108 pAd->CommonCfg.BACapability.field.MpduDensity = 0;
3109 pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
3110 pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; //32;
3111 pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64; //32;
3112 DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit. BACapability = 0x%x\n", pAd->CommonCfg.BACapability.word));
3113
3114 pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
3115 BATableInit(pAd, &pAd->BATable);
3116
3117 pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1;
3118 pAd->CommonCfg.bHTProtect = 1;
3119 pAd->CommonCfg.bMIMOPSEnable = TRUE;
3120 pAd->CommonCfg.bBADecline = FALSE;
3121 pAd->CommonCfg.bDisableReordering = FALSE;
3122
3123 pAd->CommonCfg.TxBASize = 7;
3124
3125 pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
3126#endif // DOT11_N_SUPPORT //
3127
3128 //pAd->CommonCfg.HTPhyMode.field.BW = BW_20;
3129 //pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO;
3130 //pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800;
3131 //pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE;
3132 pAd->CommonCfg.TxRate = RATE_6;
3133
3134 pAd->CommonCfg.MlmeTransmit.field.MCS = MCS_RATE_6;
3135 pAd->CommonCfg.MlmeTransmit.field.BW = BW_20;
3136 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
3137
3138 pAd->CommonCfg.BeaconPeriod = 100; // in mSec
3139
3140 //
3141 // part II. intialize STA specific configuration
3142 //
3143#ifdef CONFIG_STA_SUPPORT
3144 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3145 {
3146 RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT);
3147 RX_FILTER_CLEAR_FLAG(pAd, fRX_FILTER_ACCEPT_MULTICAST);
3148 RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_BROADCAST);
3149 RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_ALL_MULTICAST);
3150
3151 pAd->StaCfg.Psm = PWR_ACTIVE;
3152
3153 pAd->StaCfg.OrigWepStatus = Ndis802_11EncryptionDisabled;
3154 pAd->StaCfg.PairCipher = Ndis802_11EncryptionDisabled;
3155 pAd->StaCfg.GroupCipher = Ndis802_11EncryptionDisabled;
3156 pAd->StaCfg.bMixCipher = FALSE;
3157 pAd->StaCfg.DefaultKeyId = 0;
3158
3159 // 802.1x port control
3160 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
3161 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3162 pAd->StaCfg.LastMicErrorTime = 0;
3163 pAd->StaCfg.MicErrCnt = 0;
3164 pAd->StaCfg.bBlockAssoc = FALSE;
3165 pAd->StaCfg.WpaState = SS_NOTUSE;
3166
3167 pAd->CommonCfg.NdisRadioStateOff = FALSE; // New to support microsoft disable radio with OID command
3168
3169 pAd->StaCfg.RssiTrigger = 0;
3170 NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(RSSI_SAMPLE));
3171 pAd->StaCfg.RssiTriggerMode = RSSI_TRIGGERED_UPON_BELOW_THRESHOLD;
3172 pAd->StaCfg.AtimWin = 0;
3173 pAd->StaCfg.DefaultListenCount = 3;//default listen count;
3174 pAd->StaCfg.BssType = BSS_INFRA; // BSS_INFRA or BSS_ADHOC or BSS_MONITOR
3175 pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
3176 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
3177 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
3178
3179 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
3180 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3181 }
3182
3183#ifdef EXT_BUILD_CHANNEL_LIST
3184 pAd->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
3185#endif // EXT_BUILD_CHANNEL_LIST //
3186#endif // CONFIG_STA_SUPPORT //
3187
3188 // global variables mXXXX used in MAC protocol state machines
3189 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
3190 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
3191 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
3192
3193 // PHY specification
3194 pAd->CommonCfg.PhyMode = PHY_11BG_MIXED; // default PHY mode
3195 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); // CCK use LONG preamble
3196
3197#ifdef CONFIG_STA_SUPPORT
3198 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
3199 {
3200 // user desired power mode
3201 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
3202 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
3203 pAd->StaCfg.bWindowsACCAMEnable = FALSE;
3204
3205#ifdef LEAP_SUPPORT
3206 // CCX v1.0 releated init value
3207 RTMPInitTimer(pAd, &pAd->StaCfg.LeapAuthTimer, GET_TIMER_FUNCTION(LeapAuthTimeout), pAd, FALSE);
3208 pAd->StaCfg.LeapAuthMode = CISCO_AuthModeLEAPNone;
3209 pAd->StaCfg.bCkipOn = FALSE;
3210#endif // LEAP_SUPPORT //
3211
3212 RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer, GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec), pAd, FALSE);
3213 pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
3214
3215 // Patch for Ndtest
3216 pAd->StaCfg.ScanCnt = 0;
3217
3218 // CCX 2.0 control flag init
3219 pAd->StaCfg.CCXEnable = FALSE;
3220 pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
3221 pAd->StaCfg.CCXQosECWMin = 4;
3222 pAd->StaCfg.CCXQosECWMax = 10;
3223
3224 pAd->StaCfg.bHwRadio = TRUE; // Default Hardware Radio status is On
3225 pAd->StaCfg.bSwRadio = TRUE; // Default Software Radio status is On
3226 pAd->StaCfg.bRadio = TRUE; // bHwRadio && bSwRadio
3227 pAd->StaCfg.bHardwareRadio = FALSE; // Default is OFF
3228 pAd->StaCfg.bShowHiddenSSID = FALSE; // Default no show
3229
3230 // Nitro mode control
3231 pAd->StaCfg.bAutoReconnect = TRUE;
3232
3233 // Save the init time as last scan time, the system should do scan after 2 seconds.
3234 // This patch is for driver wake up from standby mode, system will do scan right away.
3235 pAd->StaCfg.LastScanTime = 0;
3236 NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1);
3237 sprintf(pAd->nickname, "%s", STA_NIC_DEVICE_NAME);
3238 RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), pAd, FALSE);
3239#ifdef WPA_SUPPLICANT_SUPPORT
3240 pAd->StaCfg.IEEE8021X = FALSE;
3241 pAd->StaCfg.IEEE8021x_required_keys = FALSE;
3242 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
3243#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
3244 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
3245#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
3246#endif // WPA_SUPPLICANT_SUPPORT //
3247
3248 }
3249#endif // CONFIG_STA_SUPPORT //
3250
3251 // Default for extra information is not valid
3252 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
3253
3254 // Default Config change flag
3255 pAd->bConfigChanged = FALSE;
3256
3257 //
3258 // part III. AP configurations
3259 //
3260
3261
3262 //
3263 // part IV. others
3264 //
3265 // dynamic BBP R66:sensibity tuning to overcome background noise
3266 pAd->BbpTuning.bEnable = TRUE;
3267 pAd->BbpTuning.FalseCcaLowerThreshold = 100;
3268 pAd->BbpTuning.FalseCcaUpperThreshold = 512;
3269 pAd->BbpTuning.R66Delta = 4;
3270 pAd->Mlme.bEnableAutoAntennaCheck = TRUE;
3271
3272 //
3273 // Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value.
3274 // if not initial this value, the default value will be 0.
3275 //
3276 pAd->BbpTuning.R66CurrentValue = 0x38;
3277
3278 pAd->Bbp94 = BBPR94_DEFAULT;
3279 pAd->BbpForCCK = FALSE;
3280
3281 // initialize MAC table and allocate spin lock
3282 NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
3283 InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
3284 NdisAllocateSpinLock(&pAd->MacTabLock);
3285
3286#ifdef RALINK_ATE
3287 NdisZeroMemory(&pAd->ate, sizeof(ATE_INFO));
3288 pAd->ate.Mode = ATE_STOP;
3289 pAd->ate.TxCount = 200;/* to exceed TX_RING_SIZE ... */
3290 pAd->ate.TxLength = 1024;
3291 pAd->ate.TxWI.ShortGI = 0;// LONG GI : 800 ns
3292 pAd->ate.TxWI.PHYMODE = MODE_CCK;
3293 pAd->ate.TxWI.MCS = 3;
3294 pAd->ate.TxWI.BW = BW_20;
3295 pAd->ate.Channel = 1;
3296 pAd->ate.QID = QID_AC_BE;
3297 pAd->ate.Addr1[0] = 0x00;
3298 pAd->ate.Addr1[1] = 0x11;
3299 pAd->ate.Addr1[2] = 0x22;
3300 pAd->ate.Addr1[3] = 0xAA;
3301 pAd->ate.Addr1[4] = 0xBB;
3302 pAd->ate.Addr1[5] = 0xCC;
3303 NdisMoveMemory(pAd->ate.Addr2, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
3304 NdisMoveMemory(pAd->ate.Addr3, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
3305 pAd->ate.bRxFer = 0;
3306 pAd->ate.bQATxStart = FALSE;
3307 pAd->ate.bQARxStart = FALSE;
3308#ifdef RT2860
3309 pAd->ate.bFWLoading = FALSE;
3310#endif // RT2860 //
3311#ifdef RALINK_28xx_QA
3312 //pAd->ate.Repeat = 0;
3313 pAd->ate.TxStatus = 0;
3314 pAd->ate.AtePid = THREAD_PID_INIT_VALUE;
3315#endif // RALINK_28xx_QA //
3316#endif // RALINK_ATE //
3317
3318
3319 pAd->CommonCfg.bWiFiTest = FALSE;
3320#ifdef RT2860
3321 pAd->bPCIclkOff = FALSE;
3322#endif // RT2860 //
3323
3324
3325 DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
3326}
3327
3328// IRQL = PASSIVE_LEVEL
3329UCHAR BtoH(char ch)
3330{
3331 if (ch >= '0' && ch <= '9') return (ch - '0'); // Handle numerals
3332 if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA); // Handle capitol hex digits
3333 if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA); // Handle small hex digits
3334 return(255);
3335}
3336
3337//
3338// FUNCTION: AtoH(char *, UCHAR *, int)
3339//
3340// PURPOSE: Converts ascii string to network order hex
3341//
3342// PARAMETERS:
3343// src - pointer to input ascii string
3344// dest - pointer to output hex
3345// destlen - size of dest
3346//
3347// COMMENTS:
3348//
3349// 2 ascii bytes make a hex byte so must put 1st ascii byte of pair
3350// into upper nibble and 2nd ascii byte of pair into lower nibble.
3351//
3352// IRQL = PASSIVE_LEVEL
3353
3354void AtoH(char * src, UCHAR * dest, int destlen)
3355{
3356 char * srcptr;
3357 PUCHAR destTemp;
3358
3359 srcptr = src;
3360 destTemp = (PUCHAR) dest;
3361
3362 while(destlen--)
3363 {
3364 *destTemp = BtoH(*srcptr++) << 4; // Put 1st ascii byte in upper nibble.
3365 *destTemp += BtoH(*srcptr++); // Add 2nd ascii byte to above.
3366 destTemp++;
3367 }
3368}
3369
3370VOID RTMPPatchMacBbpBug(
3371 IN PRTMP_ADAPTER pAd)
3372{
3373 ULONG Index;
3374
3375 // Initialize BBP register to default value
3376 for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
3377 {
3378 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, (UCHAR)BBPRegTable[Index].Value);
3379 }
3380
3381 // Initialize RF register to default value
3382 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
3383 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
3384
3385 // Re-init BBP register from EEPROM value
3386 NICInitAsicFromEEPROM(pAd);
3387}
3388
3389/*
3390 ========================================================================
3391
3392 Routine Description:
3393 Init timer objects
3394
3395 Arguments:
3396 pAd Pointer to our adapter
3397 pTimer Timer structure
3398 pTimerFunc Function to execute when timer expired
3399 Repeat Ture for period timer
3400
3401 Return Value:
3402 None
3403
3404 Note:
3405
3406 ========================================================================
3407*/
3408VOID RTMPInitTimer(
3409 IN PRTMP_ADAPTER pAd,
3410 IN PRALINK_TIMER_STRUCT pTimer,
3411 IN PVOID pTimerFunc,
3412 IN PVOID pData,
3413 IN BOOLEAN Repeat)
3414{
3415 //
3416 // Set Valid to TRUE for later used.
3417 // It will crash if we cancel a timer or set a timer
3418 // that we haven't initialize before.
3419 //
3420 pTimer->Valid = TRUE;
3421
3422 pTimer->PeriodicType = Repeat;
3423 pTimer->State = FALSE;
3424 pTimer->cookie = (ULONG) pData;
3425
3426
3427 RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (PVOID) pTimer);
3428}
3429
3430/*
3431 ========================================================================
3432
3433 Routine Description:
3434 Init timer objects
3435
3436 Arguments:
3437 pTimer Timer structure
3438 Value Timer value in milliseconds
3439
3440 Return Value:
3441 None
3442
3443 Note:
3444 To use this routine, must call RTMPInitTimer before.
3445
3446 ========================================================================
3447*/
3448VOID RTMPSetTimer(
3449 IN PRALINK_TIMER_STRUCT pTimer,
3450 IN ULONG Value)
3451{
3452 if (pTimer->Valid)
3453 {
3454 pTimer->TimerValue = Value;
3455 pTimer->State = FALSE;
3456 if (pTimer->PeriodicType == TRUE)
3457 {
3458 pTimer->Repeat = TRUE;
3459 RTMP_SetPeriodicTimer(&pTimer->TimerObj, Value);
3460 }
3461 else
3462 {
3463 pTimer->Repeat = FALSE;
3464 RTMP_OS_Add_Timer(&pTimer->TimerObj, Value);
3465 }
3466 }
3467 else
3468 {
3469 DBGPRINT_ERR(("RTMPSetTimer failed, Timer hasn't been initialize!\n"));
3470 }
3471}
3472
3473
3474/*
3475 ========================================================================
3476
3477 Routine Description:
3478 Init timer objects
3479
3480 Arguments:
3481 pTimer Timer structure
3482 Value Timer value in milliseconds
3483
3484 Return Value:
3485 None
3486
3487 Note:
3488 To use this routine, must call RTMPInitTimer before.
3489
3490 ========================================================================
3491*/
3492VOID RTMPModTimer(
3493 IN PRALINK_TIMER_STRUCT pTimer,
3494 IN ULONG Value)
3495{
3496 BOOLEAN Cancel;
3497
3498 if (pTimer->Valid)
3499 {
3500 pTimer->TimerValue = Value;
3501 pTimer->State = FALSE;
3502 if (pTimer->PeriodicType == TRUE)
3503 {
3504 RTMPCancelTimer(pTimer, &Cancel);
3505 RTMPSetTimer(pTimer, Value);
3506 }
3507 else
3508 {
3509 RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value);
3510 }
3511 }
3512 else
3513 {
3514 DBGPRINT_ERR(("RTMPModTimer failed, Timer hasn't been initialize!\n"));
3515 }
3516}
3517
3518/*
3519 ========================================================================
3520
3521 Routine Description:
3522 Cancel timer objects
3523
3524 Arguments:
3525 Adapter Pointer to our adapter
3526
3527 Return Value:
3528 None
3529
3530 IRQL = PASSIVE_LEVEL
3531 IRQL = DISPATCH_LEVEL
3532
3533 Note:
3534 1.) To use this routine, must call RTMPInitTimer before.
3535 2.) Reset NIC to initial state AS IS system boot up time.
3536
3537 ========================================================================
3538*/
3539VOID RTMPCancelTimer(
3540 IN PRALINK_TIMER_STRUCT pTimer,
3541 OUT BOOLEAN *pCancelled)
3542{
3543 if (pTimer->Valid)
3544 {
3545 if (pTimer->State == FALSE)
3546 pTimer->Repeat = FALSE;
3547 RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled);
3548
3549 if (*pCancelled == TRUE)
3550 pTimer->State = TRUE;
3551
3552 }
3553 else
3554 {
3555 //
3556 // NdisMCancelTimer just canced the timer and not mean release the timer.
3557 // And don't set the "Valid" to False. So that we can use this timer again.
3558 //
3559 DBGPRINT_ERR(("RTMPCancelTimer failed, Timer hasn't been initialize!\n"));
3560 }
3561}
3562
3563/*
3564 ========================================================================
3565
3566 Routine Description:
3567 Set LED Status
3568
3569 Arguments:
3570 pAd Pointer to our adapter
3571 Status LED Status
3572
3573 Return Value:
3574 None
3575
3576 IRQL = PASSIVE_LEVEL
3577 IRQL = DISPATCH_LEVEL
3578
3579 Note:
3580
3581 ========================================================================
3582*/
3583VOID RTMPSetLED(
3584 IN PRTMP_ADAPTER pAd,
3585 IN UCHAR Status)
3586{
3587 //ULONG data;
3588 UCHAR HighByte = 0;
3589 UCHAR LowByte;
3590
3591// In ATE mode of RT2860 AP/STA, we have erased 8051 firmware.
3592// So LED mode is not supported when ATE is running.
3593#ifdef RALINK_ATE
3594 if (ATE_ON(pAd))
3595 return;
3596#endif // RALINK_ATE //
3597
3598 LowByte = pAd->LedCntl.field.LedMode&0x7f;
3599 switch (Status)
3600 {
3601 case LED_LINK_DOWN:
3602 HighByte = 0x20;
3603 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3604 pAd->LedIndicatorStregth = 0;
3605 break;
3606 case LED_LINK_UP:
3607 if (pAd->CommonCfg.Channel > 14)
3608 HighByte = 0xa0;
3609 else
3610 HighByte = 0x60;
3611 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3612 break;
3613 case LED_RADIO_ON:
3614 HighByte = 0x20;
3615 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3616 break;
3617 case LED_HALT:
3618 LowByte = 0; // Driver sets MAC register and MAC controls LED
3619 case LED_RADIO_OFF:
3620 HighByte = 0;
3621 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3622 break;
3623 case LED_WPS:
3624 HighByte = 0x10;
3625 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3626 break;
3627 case LED_ON_SITE_SURVEY:
3628 HighByte = 0x08;
3629 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3630 break;
3631 case LED_POWER_UP:
3632 HighByte = 0x04;
3633 AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
3634 break;
3635 default:
3636 DBGPRINT(RT_DEBUG_WARN, ("RTMPSetLED::Unknown Status %d\n", Status));
3637 break;
3638 }
3639
3640 //
3641 // Keep LED status for LED SiteSurvey mode.
3642 // After SiteSurvey, we will set the LED mode to previous status.
3643 //
3644 if ((Status != LED_ON_SITE_SURVEY) && (Status != LED_POWER_UP))
3645 pAd->LedStatus = Status;
3646
3647 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetLED::Mode=%d,HighByte=0x%02x,LowByte=0x%02x\n", pAd->LedCntl.field.LedMode, HighByte, LowByte));
3648}
3649
3650/*
3651 ========================================================================
3652
3653 Routine Description:
3654 Set LED Signal Stregth
3655
3656 Arguments:
3657 pAd Pointer to our adapter
3658 Dbm Signal Stregth
3659
3660 Return Value:
3661 None
3662
3663 IRQL = PASSIVE_LEVEL
3664
3665 Note:
3666 Can be run on any IRQL level.
3667
3668 According to Microsoft Zero Config Wireless Signal Stregth definition as belows.
3669 <= -90 No Signal
3670 <= -81 Very Low
3671 <= -71 Low
3672 <= -67 Good
3673 <= -57 Very Good
3674 > -57 Excellent
3675 ========================================================================
3676*/
3677VOID RTMPSetSignalLED(
3678 IN PRTMP_ADAPTER pAd,
3679 IN NDIS_802_11_RSSI Dbm)
3680{
3681 UCHAR nLed = 0;
3682
3683 //
3684 // if not Signal Stregth, then do nothing.
3685 //
3686 if (pAd->LedCntl.field.LedMode != LED_MODE_SIGNAL_STREGTH)
3687 {
3688 return;
3689 }
3690
3691 if (Dbm <= -90)
3692 nLed = 0;
3693 else if (Dbm <= -81)
3694 nLed = 1;
3695 else if (Dbm <= -71)
3696 nLed = 3;
3697 else if (Dbm <= -67)
3698 nLed = 7;
3699 else if (Dbm <= -57)
3700 nLed = 15;
3701 else
3702 nLed = 31;
3703
3704 //
3705 // Update Signal Stregth to firmware if changed.
3706 //
3707 if (pAd->LedIndicatorStregth != nLed)
3708 {
3709 AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, pAd->LedCntl.field.Polarity);
3710 pAd->LedIndicatorStregth = nLed;
3711 }
3712}
3713
3714/*
3715 ========================================================================
3716
3717 Routine Description:
3718 Enable RX
3719
3720 Arguments:
3721 pAd Pointer to our adapter
3722
3723 Return Value:
3724 None
3725
3726 IRQL <= DISPATCH_LEVEL
3727
3728 Note:
3729 Before Enable RX, make sure you have enabled Interrupt.
3730 ========================================================================
3731*/
3732VOID RTMPEnableRxTx(
3733 IN PRTMP_ADAPTER pAd)
3734{
3735 DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
3736
3737 // Enable Rx DMA.
3738 RT28XXDMAEnable(pAd);
3739
3740 // enable RX of MAC block
3741 if (pAd->OpMode == OPMODE_AP)
3742 {
3743 UINT32 rx_filter_flag = APNORMAL;
3744
3745
3746 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); // enable RX of DMA block
3747 }
3748 else
3749 {
3750 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
3751 }
3752
3753 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
3754 DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n"));
3755}
3756
3757
diff --git a/drivers/staging/rt2860/common/rtmp_tkip.c b/drivers/staging/rt2860/common/rtmp_tkip.c
new file mode 100644
index 00000000000..a87ea3a5d3e
--- /dev/null
+++ b/drivers/staging/rt2860/common/rtmp_tkip.c
@@ -0,0 +1,1607 @@
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 NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); // Copy IV
474
475 *pIV16 = tkipIv.IV16.word;
476 *pIV32 = tkipIv.IV32;
477}
478
479/*
480 ========================================================================
481
482 Routine Description:
483 Init MIC Value calculation function which include set MIC key &
484 calculate first 16 bytes (DA + SA + priority + 0)
485
486 Arguments:
487 pAd Pointer to our adapter
488 pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
489 pDA Pointer to DA address
490 pSA Pointer to SA address
491 pMICKey pointer to MIC Key
492
493 Return Value:
494 None
495
496 Note:
497
498 ========================================================================
499*/
500VOID RTMPInitMICEngine(
501 IN PRTMP_ADAPTER pAd,
502 IN PUCHAR pKey,
503 IN PUCHAR pDA,
504 IN PUCHAR pSA,
505 IN UCHAR UserPriority,
506 IN PUCHAR pMICKey)
507{
508 ULONG Priority = UserPriority;
509
510 // Init MIC value calculation
511 RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
512 // DA
513 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
514 // SA
515 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
516 // Priority + 3 bytes of 0
517 RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4);
518}
519
520/*
521 ========================================================================
522
523 Routine Description:
524 Compare MIC value of received MSDU
525
526 Arguments:
527 pAd Pointer to our adapter
528 pSrc Pointer to the received Plain text data
529 pDA Pointer to DA address
530 pSA Pointer to SA address
531 pMICKey pointer to MIC Key
532 Len the length of the received plain text data exclude MIC value
533
534 Return Value:
535 TRUE MIC value matched
536 FALSE MIC value mismatched
537
538 IRQL = DISPATCH_LEVEL
539
540 Note:
541
542 ========================================================================
543*/
544BOOLEAN RTMPTkipCompareMICValue(
545 IN PRTMP_ADAPTER pAd,
546 IN PUCHAR pSrc,
547 IN PUCHAR pDA,
548 IN PUCHAR pSA,
549 IN PUCHAR pMICKey,
550 IN UCHAR UserPriority,
551 IN UINT Len)
552{
553 UCHAR OldMic[8];
554 ULONG Priority = UserPriority;
555
556 // Init MIC value calculation
557 RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
558 // DA
559 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
560 // SA
561 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
562 // Priority + 3 bytes of 0
563 RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
564
565 // Calculate MIC value from plain text data
566 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
567
568 // Get MIC valude from received frame
569 NdisMoveMemory(OldMic, pSrc + Len, 8);
570
571 // Get MIC value from decrypted plain data
572 RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
573
574 // Move MIC value from MSDU, this steps should move to data path.
575 // Since the MIC value might cross MPDUs.
576 if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
577 {
578 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); //MIC error.
579
580
581 return (FALSE);
582 }
583 return (TRUE);
584}
585
586/*
587 ========================================================================
588
589 Routine Description:
590 Compare MIC value of received MSDU
591
592 Arguments:
593 pAd Pointer to our adapter
594 pLLC LLC header
595 pSrc Pointer to the received Plain text data
596 pDA Pointer to DA address
597 pSA Pointer to SA address
598 pMICKey pointer to MIC Key
599 Len the length of the received plain text data exclude MIC value
600
601 Return Value:
602 TRUE MIC value matched
603 FALSE MIC value mismatched
604
605 IRQL = DISPATCH_LEVEL
606
607 Note:
608
609 ========================================================================
610*/
611BOOLEAN RTMPTkipCompareMICValueWithLLC(
612 IN PRTMP_ADAPTER pAd,
613 IN PUCHAR pLLC,
614 IN PUCHAR pSrc,
615 IN PUCHAR pDA,
616 IN PUCHAR pSA,
617 IN PUCHAR pMICKey,
618 IN UINT Len)
619{
620 UCHAR OldMic[8];
621 ULONG Priority = 0;
622
623 // Init MIC value calculation
624 RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
625 // DA
626 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
627 // SA
628 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
629 // Priority + 3 bytes of 0
630 RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
631
632 // Start with LLC header
633 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8);
634
635 // Calculate MIC value from plain text data
636 RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
637
638 // Get MIC valude from received frame
639 NdisMoveMemory(OldMic, pSrc + Len, 8);
640
641 // Get MIC value from decrypted plain data
642 RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
643
644 // Move MIC value from MSDU, this steps should move to data path.
645 // Since the MIC value might cross MPDUs.
646 if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
647 {
648 DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n")); //MIC error.
649
650
651 return (FALSE);
652 }
653 return (TRUE);
654}
655/*
656 ========================================================================
657
658 Routine Description:
659 Copy frame from waiting queue into relative ring buffer and set
660 appropriate ASIC register to kick hardware transmit function
661
662 Arguments:
663 pAd Pointer to our adapter
664 PNDIS_PACKET Pointer to Ndis Packet for MIC calculation
665 pEncap Pointer to LLC encap data
666 LenEncap Total encap length, might be 0 which indicates no encap
667
668 Return Value:
669 None
670
671 IRQL = DISPATCH_LEVEL
672
673 Note:
674
675 ========================================================================
676*/
677VOID RTMPCalculateMICValue(
678 IN PRTMP_ADAPTER pAd,
679 IN PNDIS_PACKET pPacket,
680 IN PUCHAR pEncap,
681 IN PCIPHER_KEY pKey,
682 IN UCHAR apidx)
683{
684 PACKET_INFO PacketInfo;
685 PUCHAR pSrcBufVA;
686 UINT SrcBufLen;
687 PUCHAR pSrc;
688 UCHAR UserPriority;
689 UCHAR vlan_offset = 0;
690
691 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
692
693 UserPriority = RTMP_GET_PACKET_UP(pPacket);
694 pSrc = pSrcBufVA;
695
696 // determine if this is a vlan packet
697 if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
698 vlan_offset = 4;
699
700 {
701 RTMPInitMICEngine(
702 pAd,
703 pKey->Key,
704 pSrc,
705 pSrc + 6,
706 UserPriority,
707 pKey->TxMic);
708 }
709
710
711 if (pEncap != NULL)
712 {
713 // LLC encapsulation
714 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
715 // Protocol Type
716 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2);
717 }
718 SrcBufLen -= (14 + vlan_offset);
719 pSrc += (14 + vlan_offset);
720 do
721 {
722 if (SrcBufLen > 0)
723 {
724 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
725 }
726
727 break; // No need handle next packet
728
729 } while (TRUE); // End of copying payload
730
731 // Compute the final MIC Value
732 RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
733}
734
735
736/************************************************************/
737/* tkip_sbox() */
738/* Returns a 16 bit value from a 64K entry table. The Table */
739/* is synthesized from two 256 entry byte wide tables. */
740/************************************************************/
741
742UINT tkip_sbox(UINT index)
743{
744 UINT index_low;
745 UINT index_high;
746 UINT left, right;
747
748 index_low = (index % 256);
749 index_high = ((index >> 8) % 256);
750
751 left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
752 right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
753
754 return (left ^ right);
755}
756
757UINT rotr1(UINT a)
758{
759 unsigned int b;
760
761 if ((a & 0x01) == 0x01)
762 {
763 b = (a >> 1) | 0x8000;
764 }
765 else
766 {
767 b = (a >> 1) & 0x7fff;
768 }
769 b = b % 65536;
770 return b;
771}
772
773VOID RTMPTkipMixKey(
774 UCHAR *key,
775 UCHAR *ta,
776 ULONG pnl, /* Least significant 16 bits of PN */
777 ULONG pnh, /* Most significant 32 bits of PN */
778 UCHAR *rc4key,
779 UINT *p1k)
780{
781
782 UINT tsc0;
783 UINT tsc1;
784 UINT tsc2;
785
786 UINT ppk0;
787 UINT ppk1;
788 UINT ppk2;
789 UINT ppk3;
790 UINT ppk4;
791 UINT ppk5;
792
793 INT i;
794 INT j;
795
796 tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
797 tsc1 = (unsigned int)(pnh % 65536);
798 tsc2 = (unsigned int)(pnl % 65536); /* lsb */
799
800 /* Phase 1, step 1 */
801 p1k[0] = tsc1;
802 p1k[1] = tsc0;
803 p1k[2] = (UINT)(ta[0] + (ta[1]*256));
804 p1k[3] = (UINT)(ta[2] + (ta[3]*256));
805 p1k[4] = (UINT)(ta[4] + (ta[5]*256));
806
807 /* Phase 1, step 2 */
808 for (i=0; i<8; i++)
809 {
810 j = 2*(i & 1);
811 p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536;
812 p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536;
813 p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536;
814 p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536;
815 p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536;
816 p1k[4] = (p1k[4] + i) % 65536;
817 }
818
819 /* Phase 2, Step 1 */
820 ppk0 = p1k[0];
821 ppk1 = p1k[1];
822 ppk2 = p1k[2];
823 ppk3 = p1k[3];
824 ppk4 = p1k[4];
825 ppk5 = (p1k[4] + tsc2) % 65536;
826
827 /* Phase2, Step 2 */
828 ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536);
829 ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536);
830 ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536);
831 ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536);
832 ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536);
833 ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536);
834
835 ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12]));
836 ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14]));
837 ppk2 = ppk2 + rotr1(ppk1);
838 ppk3 = ppk3 + rotr1(ppk2);
839 ppk4 = ppk4 + rotr1(ppk3);
840 ppk5 = ppk5 + rotr1(ppk4);
841
842 /* Phase 2, Step 3 */
843 /* Phase 2, Step 3 */
844
845 tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
846 tsc1 = (unsigned int)(pnh % 65536);
847 tsc2 = (unsigned int)(pnl % 65536); /* lsb */
848
849 rc4key[0] = (tsc2 >> 8) % 256;
850 rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
851 rc4key[2] = tsc2 % 256;
852 rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256;
853
854 rc4key[4] = ppk0 % 256;
855 rc4key[5] = (ppk0 >> 8) % 256;
856
857 rc4key[6] = ppk1 % 256;
858 rc4key[7] = (ppk1 >> 8) % 256;
859
860 rc4key[8] = ppk2 % 256;
861 rc4key[9] = (ppk2 >> 8) % 256;
862
863 rc4key[10] = ppk3 % 256;
864 rc4key[11] = (ppk3 >> 8) % 256;
865
866 rc4key[12] = ppk4 % 256;
867 rc4key[13] = (ppk4 >> 8) % 256;
868
869 rc4key[14] = ppk5 % 256;
870 rc4key[15] = (ppk5 >> 8) % 256;
871}
872
873
874/************************************************/
875/* construct_mic_header1() */
876/* Builds the first MIC header block from */
877/* header fields. */
878/************************************************/
879
880void construct_mic_header1(
881 unsigned char *mic_header1,
882 int header_length,
883 unsigned char *mpdu)
884{
885 mic_header1[0] = (unsigned char)((header_length - 2) / 256);
886 mic_header1[1] = (unsigned char)((header_length - 2) % 256);
887 mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
888 mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
889 mic_header1[4] = mpdu[4]; /* A1 */
890 mic_header1[5] = mpdu[5];
891 mic_header1[6] = mpdu[6];
892 mic_header1[7] = mpdu[7];
893 mic_header1[8] = mpdu[8];
894 mic_header1[9] = mpdu[9];
895 mic_header1[10] = mpdu[10]; /* A2 */
896 mic_header1[11] = mpdu[11];
897 mic_header1[12] = mpdu[12];
898 mic_header1[13] = mpdu[13];
899 mic_header1[14] = mpdu[14];
900 mic_header1[15] = mpdu[15];
901}
902
903/************************************************/
904/* construct_mic_header2() */
905/* Builds the last MIC header block from */
906/* header fields. */
907/************************************************/
908
909void construct_mic_header2(
910 unsigned char *mic_header2,
911 unsigned char *mpdu,
912 int a4_exists,
913 int qc_exists)
914{
915 int i;
916
917 for (i = 0; i<16; i++) mic_header2[i]=0x00;
918
919 mic_header2[0] = mpdu[16]; /* A3 */
920 mic_header2[1] = mpdu[17];
921 mic_header2[2] = mpdu[18];
922 mic_header2[3] = mpdu[19];
923 mic_header2[4] = mpdu[20];
924 mic_header2[5] = mpdu[21];
925
926 // In Sequence Control field, mute sequence numer bits (12-bit)
927 mic_header2[6] = mpdu[22] & 0x0f; /* SC */
928 mic_header2[7] = 0x00; /* mpdu[23]; */
929
930 if ((!qc_exists) & a4_exists)
931 {
932 for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
933
934 }
935
936 if (qc_exists && (!a4_exists))
937 {
938 mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
939 mic_header2[9] = mpdu[25] & 0x00;
940 }
941
942 if (qc_exists && a4_exists)
943 {
944 for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
945
946 mic_header2[14] = mpdu[30] & 0x0f;
947 mic_header2[15] = mpdu[31] & 0x00;
948 }
949}
950
951
952/************************************************/
953/* construct_mic_iv() */
954/* Builds the MIC IV from header fields and PN */
955/************************************************/
956
957void construct_mic_iv(
958 unsigned char *mic_iv,
959 int qc_exists,
960 int a4_exists,
961 unsigned char *mpdu,
962 unsigned int payload_length,
963 unsigned char *pn_vector)
964{
965 int i;
966
967 mic_iv[0] = 0x59;
968 if (qc_exists && a4_exists)
969 mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
970 if (qc_exists && !a4_exists)
971 mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
972 if (!qc_exists)
973 mic_iv[1] = 0x00;
974 for (i = 2; i < 8; i++)
975 mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
976#ifdef CONSISTENT_PN_ORDER
977 for (i = 8; i < 14; i++)
978 mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
979#else
980 for (i = 8; i < 14; i++)
981 mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
982#endif
983 i = (payload_length / 256);
984 i = (payload_length % 256);
985 mic_iv[14] = (unsigned char) (payload_length / 256);
986 mic_iv[15] = (unsigned char) (payload_length % 256);
987
988}
989
990
991
992/************************************/
993/* bitwise_xor() */
994/* A 128 bit, bitwise exclusive or */
995/************************************/
996
997void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
998{
999 int i;
1000 for (i=0; i<16; i++)
1001 {
1002 out[i] = ina[i] ^ inb[i];
1003 }
1004}
1005
1006
1007void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
1008{
1009 int round;
1010 int i;
1011 unsigned char intermediatea[16];
1012 unsigned char intermediateb[16];
1013 unsigned char round_key[16];
1014
1015 for(i=0; i<16; i++) round_key[i] = key[i];
1016
1017 for (round = 0; round < 11; round++)
1018 {
1019 if (round == 0)
1020 {
1021 xor_128(round_key, data, ciphertext);
1022 next_key(round_key, round);
1023 }
1024 else if (round == 10)
1025 {
1026 byte_sub(ciphertext, intermediatea);
1027 shift_row(intermediatea, intermediateb);
1028 xor_128(intermediateb, round_key, ciphertext);
1029 }
1030 else /* 1 - 9 */
1031 {
1032 byte_sub(ciphertext, intermediatea);
1033 shift_row(intermediatea, intermediateb);
1034 mix_column(&intermediateb[0], &intermediatea[0]);
1035 mix_column(&intermediateb[4], &intermediatea[4]);
1036 mix_column(&intermediateb[8], &intermediatea[8]);
1037 mix_column(&intermediateb[12], &intermediatea[12]);
1038 xor_128(intermediatea, round_key, ciphertext);
1039 next_key(round_key, round);
1040 }
1041 }
1042
1043}
1044
1045void construct_ctr_preload(
1046 unsigned char *ctr_preload,
1047 int a4_exists,
1048 int qc_exists,
1049 unsigned char *mpdu,
1050 unsigned char *pn_vector,
1051 int c)
1052{
1053
1054 int i = 0;
1055 for (i=0; i<16; i++) ctr_preload[i] = 0x00;
1056 i = 0;
1057
1058 ctr_preload[0] = 0x01; /* flag */
1059 if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
1060 if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f;
1061
1062 for (i = 2; i < 8; i++)
1063 ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
1064#ifdef CONSISTENT_PN_ORDER
1065 for (i = 8; i < 14; i++)
1066 ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
1067#else
1068 for (i = 8; i < 14; i++)
1069 ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
1070#endif
1071 ctr_preload[14] = (unsigned char) (c / 256); // Ctr
1072 ctr_preload[15] = (unsigned char) (c % 256);
1073
1074}
1075
1076
1077//
1078// TRUE: Success!
1079// FALSE: Decrypt Error!
1080//
1081BOOLEAN RTMPSoftDecryptTKIP(
1082 IN PRTMP_ADAPTER pAd,
1083 IN PUCHAR pData,
1084 IN ULONG DataByteCnt,
1085 IN UCHAR UserPriority,
1086 IN PCIPHER_KEY pWpaKey)
1087{
1088 UCHAR KeyID;
1089 UINT HeaderLen;
1090 UCHAR fc0;
1091 UCHAR fc1;
1092 USHORT fc;
1093 UINT frame_type;
1094 UINT frame_subtype;
1095 UINT from_ds;
1096 UINT to_ds;
1097 INT a4_exists;
1098 INT qc_exists;
1099 USHORT duration;
1100 USHORT seq_control;
1101 USHORT qos_control;
1102 UCHAR TA[MAC_ADDR_LEN];
1103 UCHAR DA[MAC_ADDR_LEN];
1104 UCHAR SA[MAC_ADDR_LEN];
1105 UCHAR RC4Key[16];
1106 UINT p1k[5]; //for mix_key;
1107 ULONG pnl;/* Least significant 16 bits of PN */
1108 ULONG pnh;/* Most significant 32 bits of PN */
1109 UINT num_blocks;
1110 UINT payload_remainder;
1111 ARCFOURCONTEXT ArcFourContext;
1112 UINT crc32 = 0;
1113 UINT trailfcs = 0;
1114 UCHAR MIC[8];
1115 UCHAR TrailMIC[8];
1116
1117#ifdef RT_BIG_ENDIAN
1118 RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
1119#endif
1120
1121 fc0 = *pData;
1122 fc1 = *(pData + 1);
1123
1124 fc = *((PUSHORT)pData);
1125
1126 frame_type = ((fc0 >> 2) & 0x03);
1127 frame_subtype = ((fc0 >> 4) & 0x0f);
1128
1129 from_ds = (fc1 & 0x2) >> 1;
1130 to_ds = (fc1 & 0x1);
1131
1132 a4_exists = (from_ds & to_ds);
1133 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
1134 (frame_subtype == 0x09) || /* Likely to change. */
1135 (frame_subtype == 0x0a) ||
1136 (frame_subtype == 0x0b)
1137 );
1138
1139 HeaderLen = 24;
1140 if (a4_exists)
1141 HeaderLen += 6;
1142
1143 KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
1144 KeyID = KeyID >> 6;
1145
1146 if (pWpaKey[KeyID].KeyLen == 0)
1147 {
1148 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", KeyID));
1149 return FALSE;
1150 }
1151
1152 duration = *((PUSHORT)(pData+2));
1153
1154 seq_control = *((PUSHORT)(pData+22));
1155
1156 if (qc_exists)
1157 {
1158 if (a4_exists)
1159 {
1160 qos_control = *((PUSHORT)(pData+30));
1161 }
1162 else
1163 {
1164 qos_control = *((PUSHORT)(pData+24));
1165 }
1166 }
1167
1168 if (to_ds == 0 && from_ds == 1)
1169 {
1170 NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
1171 NdisMoveMemory(SA, pData+16, MAC_ADDR_LEN);
1172 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); //BSSID
1173 }
1174 else if (to_ds == 0 && from_ds == 0 )
1175 {
1176 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
1177 NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
1178 NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
1179 }
1180 else if (to_ds == 1 && from_ds == 0)
1181 {
1182 NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
1183 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
1184 NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
1185 }
1186 else if (to_ds == 1 && from_ds == 1)
1187 {
1188 NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
1189 NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
1190 NdisMoveMemory(SA, pData+22, MAC_ADDR_LEN);
1191 }
1192
1193 num_blocks = (DataByteCnt - 16) / 16;
1194 payload_remainder = (DataByteCnt - 16) % 16;
1195
1196 pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
1197 pnh = *((PULONG)(pData + HeaderLen + 4));
1198 pnh = cpu2le32(pnh);
1199 RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
1200
1201 ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
1202
1203 ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
1204 NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
1205 crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4); //Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS).
1206 crc32 ^= 0xffffffff; /* complement */
1207
1208 if(crc32 != cpu2le32(trailfcs))
1209 {
1210 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n")); //ICV error.
1211
1212 return (FALSE);
1213 }
1214
1215 NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
1216 RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, pWpaKey[KeyID].RxMic);
1217 RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 12);
1218 RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
1219 NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
1220
1221 if (!NdisEqualMemory(MIC, TrailMIC, 8))
1222 {
1223 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); //MIC error.
1224 return (FALSE);
1225 }
1226
1227#ifdef RT_BIG_ENDIAN
1228 RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
1229#endif
1230 return TRUE;
1231}
1232
1233
1234
1235
1236BOOLEAN RTMPSoftDecryptAES(
1237 IN PRTMP_ADAPTER pAd,
1238 IN PUCHAR pData,
1239 IN ULONG DataByteCnt,
1240 IN PCIPHER_KEY pWpaKey)
1241{
1242 UCHAR KeyID;
1243 UINT HeaderLen;
1244 UCHAR PN[6];
1245 UINT payload_len;
1246 UINT num_blocks;
1247 UINT payload_remainder;
1248 USHORT fc;
1249 UCHAR fc0;
1250 UCHAR fc1;
1251 UINT frame_type;
1252 UINT frame_subtype;
1253 UINT from_ds;
1254 UINT to_ds;
1255 INT a4_exists;
1256 INT qc_exists;
1257 UCHAR aes_out[16];
1258 int payload_index;
1259 UINT i;
1260 UCHAR ctr_preload[16];
1261 UCHAR chain_buffer[16];
1262 UCHAR padded_buffer[16];
1263 UCHAR mic_iv[16];
1264 UCHAR mic_header1[16];
1265 UCHAR mic_header2[16];
1266 UCHAR MIC[8];
1267 UCHAR TrailMIC[8];
1268
1269#ifdef RT_BIG_ENDIAN
1270 RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
1271#endif
1272
1273 fc0 = *pData;
1274 fc1 = *(pData + 1);
1275
1276 fc = *((PUSHORT)pData);
1277
1278 frame_type = ((fc0 >> 2) & 0x03);
1279 frame_subtype = ((fc0 >> 4) & 0x0f);
1280
1281 from_ds = (fc1 & 0x2) >> 1;
1282 to_ds = (fc1 & 0x1);
1283
1284 a4_exists = (from_ds & to_ds);
1285 qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
1286 (frame_subtype == 0x09) || /* Likely to change. */
1287 (frame_subtype == 0x0a) ||
1288 (frame_subtype == 0x0b)
1289 );
1290
1291 HeaderLen = 24;
1292 if (a4_exists)
1293 HeaderLen += 6;
1294
1295 KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
1296 KeyID = KeyID >> 6;
1297
1298 if (pWpaKey[KeyID].KeyLen == 0)
1299 {
1300 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID));
1301 return FALSE;
1302 }
1303
1304 PN[0] = *(pData+ HeaderLen);
1305 PN[1] = *(pData+ HeaderLen + 1);
1306 PN[2] = *(pData+ HeaderLen + 4);
1307 PN[3] = *(pData+ HeaderLen + 5);
1308 PN[4] = *(pData+ HeaderLen + 6);
1309 PN[5] = *(pData+ HeaderLen + 7);
1310
1311 payload_len = DataByteCnt - HeaderLen - 8 - 8; // 8 bytes for CCMP header , 8 bytes for MIC
1312 payload_remainder = (payload_len) % 16;
1313 num_blocks = (payload_len) / 16;
1314
1315
1316
1317 // Find start of payload
1318 payload_index = HeaderLen + 8; //IV+EIV
1319
1320 for (i=0; i< num_blocks; i++)
1321 {
1322 construct_ctr_preload(ctr_preload,
1323 a4_exists,
1324 qc_exists,
1325 pData,
1326 PN,
1327 i+1 );
1328
1329 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
1330
1331 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
1332 NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
1333 payload_index += 16;
1334 }
1335
1336 //
1337 // If there is a short final block, then pad it
1338 // encrypt it and copy the unpadded part back
1339 //
1340 if (payload_remainder > 0)
1341 {
1342 construct_ctr_preload(ctr_preload,
1343 a4_exists,
1344 qc_exists,
1345 pData,
1346 PN,
1347 num_blocks + 1);
1348
1349 NdisZeroMemory(padded_buffer, 16);
1350 NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
1351
1352 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
1353
1354 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1355 NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder);
1356 payload_index += payload_remainder;
1357 }
1358
1359 //
1360 // Descrypt the MIC
1361 //
1362 construct_ctr_preload(ctr_preload,
1363 a4_exists,
1364 qc_exists,
1365 pData,
1366 PN,
1367 0);
1368 NdisZeroMemory(padded_buffer, 16);
1369 NdisMoveMemory(padded_buffer, pData + payload_index, 8);
1370
1371 aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
1372
1373 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1374
1375 NdisMoveMemory(TrailMIC, chain_buffer, 8);
1376
1377 //
1378 // Calculate MIC
1379 //
1380
1381 //Force the protected frame bit on
1382 *(pData + 1) = *(pData + 1) | 0x40;
1383
1384 // Find start of payload
1385 // Because the CCMP header has been removed
1386 payload_index = HeaderLen;
1387
1388 construct_mic_iv(
1389 mic_iv,
1390 qc_exists,
1391 a4_exists,
1392 pData,
1393 payload_len,
1394 PN);
1395
1396 construct_mic_header1(
1397 mic_header1,
1398 HeaderLen,
1399 pData);
1400
1401 construct_mic_header2(
1402 mic_header2,
1403 pData,
1404 a4_exists,
1405 qc_exists);
1406
1407 aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
1408 bitwise_xor(aes_out, mic_header1, chain_buffer);
1409 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1410 bitwise_xor(aes_out, mic_header2, chain_buffer);
1411 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1412
1413 // iterate through each 16 byte payload block
1414 for (i = 0; i < num_blocks; i++)
1415 {
1416 bitwise_xor(aes_out, pData + payload_index, chain_buffer);
1417 payload_index += 16;
1418 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1419 }
1420
1421 // Add on the final payload block if it needs padding
1422 if (payload_remainder > 0)
1423 {
1424 NdisZeroMemory(padded_buffer, 16);
1425 NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
1426
1427 bitwise_xor(aes_out, padded_buffer, chain_buffer);
1428 aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
1429 }
1430 // aes_out contains padded mic, discard most significant
1431 // 8 bytes to generate 64 bit MIC
1432 for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i];
1433
1434 if (!NdisEqualMemory(MIC, TrailMIC, 8))
1435 {
1436 DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); //MIC error.
1437 return FALSE;
1438 }
1439
1440#ifdef RT_BIG_ENDIAN
1441 RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
1442#endif
1443
1444 return TRUE;
1445}
1446
1447/****************************************/
1448/* aes128k128d() */
1449/* Performs a 128 bit AES encrypt with */
1450/* 128 bit data. */
1451/****************************************/
1452VOID xor_128(
1453 IN PUCHAR a,
1454 IN PUCHAR b,
1455 OUT PUCHAR out)
1456{
1457 INT i;
1458
1459 for (i=0;i<16; i++)
1460 {
1461 out[i] = a[i] ^ b[i];
1462 }
1463}
1464
1465VOID next_key(
1466 IN PUCHAR key,
1467 IN INT round)
1468{
1469 UCHAR rcon;
1470 UCHAR sbox_key[4];
1471 UCHAR rcon_table[12] =
1472 {
1473 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
1474 0x1b, 0x36, 0x36, 0x36
1475 };
1476
1477 sbox_key[0] = RTMPCkipSbox(key[13]);
1478 sbox_key[1] = RTMPCkipSbox(key[14]);
1479 sbox_key[2] = RTMPCkipSbox(key[15]);
1480 sbox_key[3] = RTMPCkipSbox(key[12]);
1481
1482 rcon = rcon_table[round];
1483
1484 xor_32(&key[0], sbox_key, &key[0]);
1485 key[0] = key[0] ^ rcon;
1486
1487 xor_32(&key[4], &key[0], &key[4]);
1488 xor_32(&key[8], &key[4], &key[8]);
1489 xor_32(&key[12], &key[8], &key[12]);
1490}
1491
1492VOID xor_32(
1493 IN PUCHAR a,
1494 IN PUCHAR b,
1495 OUT PUCHAR out)
1496{
1497 INT i;
1498
1499 for (i=0;i<4; i++)
1500 {
1501 out[i] = a[i] ^ b[i];
1502 }
1503}
1504
1505VOID byte_sub(
1506 IN PUCHAR in,
1507 OUT PUCHAR out)
1508{
1509 INT i;
1510
1511 for (i=0; i< 16; i++)
1512 {
1513 out[i] = RTMPCkipSbox(in[i]);
1514 }
1515}
1516
1517UCHAR RTMPCkipSbox(
1518 IN UCHAR a)
1519{
1520 return SboxTable[(int)a];
1521}
1522
1523VOID shift_row(
1524 IN PUCHAR in,
1525 OUT PUCHAR out)
1526{
1527 out[0] = in[0];
1528 out[1] = in[5];
1529 out[2] = in[10];
1530 out[3] = in[15];
1531 out[4] = in[4];
1532 out[5] = in[9];
1533 out[6] = in[14];
1534 out[7] = in[3];
1535 out[8] = in[8];
1536 out[9] = in[13];
1537 out[10] = in[2];
1538 out[11] = in[7];
1539 out[12] = in[12];
1540 out[13] = in[1];
1541 out[14] = in[6];
1542 out[15] = in[11];
1543}
1544
1545VOID mix_column(
1546 IN PUCHAR in,
1547 OUT PUCHAR out)
1548{
1549 INT i;
1550 UCHAR add1b[4];
1551 UCHAR add1bf7[4];
1552 UCHAR rotl[4];
1553 UCHAR swap_halfs[4];
1554 UCHAR andf7[4];
1555 UCHAR rotr[4];
1556 UCHAR temp[4];
1557 UCHAR tempb[4];
1558
1559 for (i=0 ; i<4; i++)
1560 {
1561 if ((in[i] & 0x80)== 0x80)
1562 add1b[i] = 0x1b;
1563 else
1564 add1b[i] = 0x00;
1565 }
1566
1567 swap_halfs[0] = in[2]; /* Swap halfs */
1568 swap_halfs[1] = in[3];
1569 swap_halfs[2] = in[0];
1570 swap_halfs[3] = in[1];
1571
1572 rotl[0] = in[3]; /* Rotate left 8 bits */
1573 rotl[1] = in[0];
1574 rotl[2] = in[1];
1575 rotl[3] = in[2];
1576
1577 andf7[0] = in[0] & 0x7f;
1578 andf7[1] = in[1] & 0x7f;
1579 andf7[2] = in[2] & 0x7f;
1580 andf7[3] = in[3] & 0x7f;
1581
1582 for (i = 3; i>0; i--) /* logical shift left 1 bit */
1583 {
1584 andf7[i] = andf7[i] << 1;
1585 if ((andf7[i-1] & 0x80) == 0x80)
1586 {
1587 andf7[i] = (andf7[i] | 0x01);
1588 }
1589 }
1590 andf7[0] = andf7[0] << 1;
1591 andf7[0] = andf7[0] & 0xfe;
1592
1593 xor_32(add1b, andf7, add1bf7);
1594
1595 xor_32(in, add1bf7, rotr);
1596
1597 temp[0] = rotr[0]; /* Rotate right 8 bits */
1598 rotr[0] = rotr[1];
1599 rotr[1] = rotr[2];
1600 rotr[2] = rotr[3];
1601 rotr[3] = temp[0];
1602
1603 xor_32(add1bf7, rotr, temp);
1604 xor_32(swap_halfs, rotl,tempb);
1605 xor_32(temp, tempb, out);
1606}
1607
diff --git a/drivers/staging/rt2860/common/rtmp_wep.c b/drivers/staging/rt2860/common/rtmp_wep.c
new file mode 100644
index 00000000000..ffe26c23795
--- /dev/null
+++ b/drivers/staging/rt2860/common/rtmp_wep.c
@@ -0,0 +1,499 @@
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/*
109 ========================================================================
110
111 Routine Description:
112 Init WEP function.
113
114 Arguments:
115 pAd Pointer to our adapter
116 pKey Pointer to the WEP KEY
117 KeyId WEP Key ID
118 KeyLen the length of WEP KEY
119 pDest Pointer to the destination which Encryption data will store in.
120
121 Return Value:
122 None
123
124 IRQL = DISPATCH_LEVEL
125
126 Note:
127
128 ========================================================================
129*/
130VOID RTMPInitWepEngine(
131 IN PRTMP_ADAPTER pAd,
132 IN PUCHAR pKey,
133 IN UCHAR KeyId,
134 IN UCHAR KeyLen,
135 IN OUT PUCHAR pDest)
136{
137 UINT i;
138 UCHAR WEPKEY[] = {
139 //IV
140 0x00, 0x11, 0x22,
141 //WEP KEY
142 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
143 };
144
145 pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
146
147#ifdef CONFIG_STA_SUPPORT
148 if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10) && (pAd->OpMode == OPMODE_STA))
149 {
150 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, pKey, KeyLen); //INIT SBOX, KEYLEN+3(IV)
151 NdisMoveMemory(pDest, pKey, 3); //Append Init Vector
152 }
153 else
154#endif // CONFIG_STA_SUPPORT //
155 {
156 NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
157
158 for(i = 0; i < 3; i++)
159 WEPKEY[i] = RandomByte(pAd); //Call mlme RandomByte() function.
160 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3); //INIT SBOX, KEYLEN+3(IV)
161
162 NdisMoveMemory(pDest, WEPKEY, 3); //Append Init Vector
163 }
164 *(pDest+3) = (KeyId << 6); //Append KEYID
165
166}
167
168/*
169 ========================================================================
170
171 Routine Description:
172 Encrypt transimitted data
173
174 Arguments:
175 pAd Pointer to our adapter
176 pSrc Pointer to the transimitted source data that will be encrypt
177 pDest Pointer to the destination where entryption data will be store in.
178 Len Indicate the length of the source data
179
180 Return Value:
181 None
182
183 IRQL = DISPATCH_LEVEL
184
185 Note:
186
187 ========================================================================
188*/
189VOID RTMPEncryptData(
190 IN PRTMP_ADAPTER pAd,
191 IN PUCHAR pSrc,
192 IN PUCHAR pDest,
193 IN UINT Len)
194{
195 pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
196 ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
197}
198
199
200/*
201 ========================================================================
202
203 Routine Description:
204 Decrypt received WEP data
205
206 Arguments:
207 pAdapter Pointer to our adapter
208 pSrc Pointer to the received data
209 Len the length of the received data
210
211 Return Value:
212 TRUE Decrypt WEP data success
213 FALSE Decrypt WEP data failed
214
215 Note:
216
217 ========================================================================
218*/
219BOOLEAN RTMPSoftDecryptWEP(
220 IN PRTMP_ADAPTER pAd,
221 IN PUCHAR pData,
222 IN ULONG DataByteCnt,
223 IN PCIPHER_KEY pGroupKey)
224{
225 UINT trailfcs;
226 UINT crc32;
227 UCHAR KeyIdx;
228 UCHAR WEPKEY[] = {
229 //IV
230 0x00, 0x11, 0x22,
231 //WEP KEY
232 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
233 };
234 UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11;
235 ULONG payload_len = DataByteCnt - LENGTH_802_11;
236
237 NdisMoveMemory(WEPKEY, pPayload, 3); //Get WEP IV
238
239 KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
240 if (pGroupKey[KeyIdx].KeyLen == 0)
241 return (FALSE);
242
243 NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen);
244 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3);
245 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4);
246 NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
247 crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8); //Skip last 4 bytes(FCS).
248 crc32 ^= 0xffffffff; /* complement */
249
250 if(crc32 != cpu2le32(trailfcs))
251 {
252 DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n")); //CRC error.
253 return (FALSE);
254 }
255 return (TRUE);
256}
257
258/*
259 ========================================================================
260
261 Routine Description:
262 The Stream Cipher Encryption Algorithm "ARCFOUR" initialize
263
264 Arguments:
265 Ctx Pointer to ARCFOUR CONTEXT (SBOX)
266 pKey Pointer to the WEP KEY
267 KeyLen Indicate the length fo the WEP KEY
268
269 Return Value:
270 None
271
272 IRQL = DISPATCH_LEVEL
273
274 Note:
275
276 ========================================================================
277*/
278VOID ARCFOUR_INIT(
279 IN PARCFOURCONTEXT Ctx,
280 IN PUCHAR pKey,
281 IN UINT KeyLen)
282{
283 UCHAR t, u;
284 UINT keyindex;
285 UINT stateindex;
286 PUCHAR state;
287 UINT counter;
288
289 state = Ctx->STATE;
290 Ctx->X = 0;
291 Ctx->Y = 0;
292 for (counter = 0; counter < 256; counter++)
293 state[counter] = (UCHAR)counter;
294 keyindex = 0;
295 stateindex = 0;
296 for (counter = 0; counter < 256; counter++)
297 {
298 t = state[counter];
299 stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
300 u = state[stateindex];
301 state[stateindex] = t;
302 state[counter] = u;
303 if (++keyindex >= KeyLen)
304 keyindex = 0;
305 }
306}
307
308/*
309 ========================================================================
310
311 Routine Description:
312 Get bytes from ARCFOUR CONTEXT (S-BOX)
313
314 Arguments:
315 Ctx Pointer to ARCFOUR CONTEXT (SBOX)
316
317 Return Value:
318 UCHAR - the value of the ARCFOUR CONTEXT (S-BOX)
319
320 Note:
321
322 ========================================================================
323*/
324UCHAR ARCFOUR_BYTE(
325 IN PARCFOURCONTEXT Ctx)
326{
327 UINT x;
328 UINT y;
329 UCHAR sx, sy;
330 PUCHAR state;
331
332 state = Ctx->STATE;
333 x = (Ctx->X + 1) & 0xff;
334 sx = state[x];
335 y = (sx + Ctx->Y) & 0xff;
336 sy = state[y];
337 Ctx->X = x;
338 Ctx->Y = y;
339 state[y] = sx;
340 state[x] = sy;
341
342 return(state[(sx + sy) & 0xff]);
343
344}
345
346/*
347 ========================================================================
348
349 Routine Description:
350 The Stream Cipher Decryption Algorithm
351
352 Arguments:
353 Ctx Pointer to ARCFOUR CONTEXT (SBOX)
354 pDest Pointer to the Destination
355 pSrc Pointer to the Source data
356 Len Indicate the length of the Source data
357
358 Return Value:
359 None
360
361 Note:
362
363 ========================================================================
364*/
365VOID ARCFOUR_DECRYPT(
366 IN PARCFOURCONTEXT Ctx,
367 IN PUCHAR pDest,
368 IN PUCHAR pSrc,
369 IN UINT Len)
370{
371 UINT i;
372
373 for (i = 0; i < Len; i++)
374 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
375}
376
377/*
378 ========================================================================
379
380 Routine Description:
381 The Stream Cipher Encryption Algorithm
382
383 Arguments:
384 Ctx Pointer to ARCFOUR CONTEXT (SBOX)
385 pDest Pointer to the Destination
386 pSrc Pointer to the Source data
387 Len Indicate the length of the Source dta
388
389 Return Value:
390 None
391
392 IRQL = DISPATCH_LEVEL
393
394 Note:
395
396 ========================================================================
397*/
398VOID ARCFOUR_ENCRYPT(
399 IN PARCFOURCONTEXT Ctx,
400 IN PUCHAR pDest,
401 IN PUCHAR pSrc,
402 IN UINT Len)
403{
404 UINT i;
405
406 for (i = 0; i < Len; i++)
407 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
408}
409
410/*
411 ========================================================================
412
413 Routine Description:
414 The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt GTK.
415
416 Arguments:
417 Ctx Pointer to ARCFOUR CONTEXT (SBOX)
418 pDest Pointer to the Destination
419 pSrc Pointer to the Source data
420 Len Indicate the length of the Source dta
421
422
423 ========================================================================
424*/
425
426VOID WPAARCFOUR_ENCRYPT(
427 IN PARCFOURCONTEXT Ctx,
428 IN PUCHAR pDest,
429 IN PUCHAR pSrc,
430 IN UINT Len)
431{
432 UINT i;
433 //discard first 256 bytes
434 for (i = 0; i < 256; i++)
435 ARCFOUR_BYTE(Ctx);
436
437 for (i = 0; i < Len; i++)
438 pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
439}
440
441
442/*
443 ========================================================================
444
445 Routine Description:
446 Calculate a new FCS given the current FCS and the new data.
447
448 Arguments:
449 Fcs the original FCS value
450 Cp pointer to the data which will be calculate the FCS
451 Len the length of the data
452
453 Return Value:
454 UINT - FCS 32 bits
455
456 IRQL = DISPATCH_LEVEL
457
458 Note:
459
460 ========================================================================
461*/
462UINT RTMP_CALC_FCS32(
463 IN UINT Fcs,
464 IN PUCHAR Cp,
465 IN INT Len)
466{
467 while (Len--)
468 Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
469
470 return (Fcs);
471}
472
473
474/*
475 ========================================================================
476
477 Routine Description:
478 Get last FCS and encrypt it to the destination
479
480 Arguments:
481 pDest Pointer to the Destination
482
483 Return Value:
484 None
485
486 Note:
487
488 ========================================================================
489*/
490VOID RTMPSetICV(
491 IN PRTMP_ADAPTER pAd,
492 IN PUCHAR pDest)
493{
494 pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff; /* complement */
495 pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
496
497 ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
498}
499
diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c
new file mode 100644
index 00000000000..85e636a607f
--- /dev/null
+++ b/drivers/staging/rt2860/common/spectrum.c
@@ -0,0 +1,1877 @@
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 Module Name:
29 action.c
30
31 Abstract:
32 Handle association related requests either from WSTA or from local MLME
33
34 Revision History:
35 Who When What
36 --------- ---------- ----------------------------------------------
37 Fonchi Wu 2008 created for 802.11h
38 */
39
40#include "../rt_config.h"
41#include "action.h"
42
43VOID MeasureReqTabInit(
44 IN PRTMP_ADAPTER pAd)
45{
46 NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
47
48 pAd->CommonCfg.pMeasureReqTab = kmalloc(sizeof(MEASURE_REQ_TAB), GFP_ATOMIC);
49 if (pAd->CommonCfg.pMeasureReqTab)
50 NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, sizeof(MEASURE_REQ_TAB));
51 else
52 DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __FUNCTION__));
53
54 return;
55}
56
57VOID MeasureReqTabExit(
58 IN PRTMP_ADAPTER pAd)
59{
60 NdisFreeSpinLock(pAd->CommonCfg.MeasureReqTabLock);
61
62 if (pAd->CommonCfg.pMeasureReqTab)
63 kfree(pAd->CommonCfg.pMeasureReqTab);
64 pAd->CommonCfg.pMeasureReqTab = NULL;
65
66 return;
67}
68
69static PMEASURE_REQ_ENTRY MeasureReqLookUp(
70 IN PRTMP_ADAPTER pAd,
71 IN UINT8 DialogToken)
72{
73 UINT HashIdx;
74 PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
75 PMEASURE_REQ_ENTRY pEntry = NULL;
76 PMEASURE_REQ_ENTRY pPrevEntry = NULL;
77
78 if (pTab == NULL)
79 {
80 DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
81 return NULL;
82 }
83
84 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
85
86 HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
87 pEntry = pTab->Hash[HashIdx];
88
89 while (pEntry)
90 {
91 if (pEntry->DialogToken == DialogToken)
92 break;
93 else
94 {
95 pPrevEntry = pEntry;
96 pEntry = pEntry->pNext;
97 }
98 }
99
100 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
101
102 return pEntry;
103}
104
105static PMEASURE_REQ_ENTRY MeasureReqInsert(
106 IN PRTMP_ADAPTER pAd,
107 IN UINT8 DialogToken)
108{
109 INT i;
110 ULONG HashIdx;
111 PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
112 PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry;
113 ULONG Now;
114
115 if(pTab == NULL)
116 {
117 DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
118 return NULL;
119 }
120
121 pEntry = MeasureReqLookUp(pAd, DialogToken);
122 if (pEntry == NULL)
123 {
124 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
125 for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++)
126 {
127 NdisGetSystemUpTime(&Now);
128 pEntry = &pTab->Content[i];
129
130 if ((pEntry->Valid == TRUE)
131 && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT)))
132 {
133 PMEASURE_REQ_ENTRY pPrevEntry = NULL;
134 ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
135 PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
136
137 // update Hash list
138 do
139 {
140 if (pProbeEntry == pEntry)
141 {
142 if (pPrevEntry == NULL)
143 {
144 pTab->Hash[HashIdx] = pEntry->pNext;
145 }
146 else
147 {
148 pPrevEntry->pNext = pEntry->pNext;
149 }
150 break;
151 }
152
153 pPrevEntry = pProbeEntry;
154 pProbeEntry = pProbeEntry->pNext;
155 } while (pProbeEntry);
156
157 NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
158 pTab->Size--;
159
160 break;
161 }
162
163 if (pEntry->Valid == FALSE)
164 break;
165 }
166
167 if (i < MAX_MEASURE_REQ_TAB_SIZE)
168 {
169 NdisGetSystemUpTime(&Now);
170 pEntry->lastTime = Now;
171 pEntry->Valid = TRUE;
172 pEntry->DialogToken = DialogToken;
173 pTab->Size++;
174 }
175 else
176 {
177 pEntry = NULL;
178 DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __FUNCTION__));
179 }
180
181 // add this Neighbor entry into HASH table
182 if (pEntry)
183 {
184 HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
185 if (pTab->Hash[HashIdx] == NULL)
186 {
187 pTab->Hash[HashIdx] = pEntry;
188 }
189 else
190 {
191 pCurrEntry = pTab->Hash[HashIdx];
192 while (pCurrEntry->pNext != NULL)
193 pCurrEntry = pCurrEntry->pNext;
194 pCurrEntry->pNext = pEntry;
195 }
196 }
197
198 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
199 }
200
201 return pEntry;
202}
203
204static VOID MeasureReqDelete(
205 IN PRTMP_ADAPTER pAd,
206 IN UINT8 DialogToken)
207{
208 PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
209 PMEASURE_REQ_ENTRY pEntry = NULL;
210
211 if(pTab == NULL)
212 {
213 DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
214 return;
215 }
216
217 // if empty, return
218 if (pTab->Size == 0)
219 {
220 DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
221 return;
222 }
223
224 pEntry = MeasureReqLookUp(pAd, DialogToken);
225 if (pEntry != NULL)
226 {
227 PMEASURE_REQ_ENTRY pPrevEntry = NULL;
228 ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
229 PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
230
231 RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
232 // update Hash list
233 do
234 {
235 if (pProbeEntry == pEntry)
236 {
237 if (pPrevEntry == NULL)
238 {
239 pTab->Hash[HashIdx] = pEntry->pNext;
240 }
241 else
242 {
243 pPrevEntry->pNext = pEntry->pNext;
244 }
245 break;
246 }
247
248 pPrevEntry = pProbeEntry;
249 pProbeEntry = pProbeEntry->pNext;
250 } while (pProbeEntry);
251
252 NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
253 pTab->Size--;
254
255 RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
256 }
257
258 return;
259}
260
261VOID TpcReqTabInit(
262 IN PRTMP_ADAPTER pAd)
263{
264 NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock);
265
266 pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(TPC_REQ_TAB), GFP_ATOMIC);
267 if (pAd->CommonCfg.pTpcReqTab)
268 NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(TPC_REQ_TAB));
269 else
270 DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __FUNCTION__));
271
272 return;
273}
274
275VOID TpcReqTabExit(
276 IN PRTMP_ADAPTER pAd)
277{
278 NdisFreeSpinLock(pAd->CommonCfg.TpcReqTabLock);
279
280 if (pAd->CommonCfg.pTpcReqTab)
281 kfree(pAd->CommonCfg.pTpcReqTab);
282 pAd->CommonCfg.pTpcReqTab = NULL;
283
284 return;
285}
286
287static PTPC_REQ_ENTRY TpcReqLookUp(
288 IN PRTMP_ADAPTER pAd,
289 IN UINT8 DialogToken)
290{
291 UINT HashIdx;
292 PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
293 PTPC_REQ_ENTRY pEntry = NULL;
294 PTPC_REQ_ENTRY pPrevEntry = NULL;
295
296 if (pTab == NULL)
297 {
298 DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
299 return NULL;
300 }
301
302 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
303
304 HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
305 pEntry = pTab->Hash[HashIdx];
306
307 while (pEntry)
308 {
309 if (pEntry->DialogToken == DialogToken)
310 break;
311 else
312 {
313 pPrevEntry = pEntry;
314 pEntry = pEntry->pNext;
315 }
316 }
317
318 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
319
320 return pEntry;
321}
322
323
324static PTPC_REQ_ENTRY TpcReqInsert(
325 IN PRTMP_ADAPTER pAd,
326 IN UINT8 DialogToken)
327{
328 INT i;
329 ULONG HashIdx;
330 PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
331 PTPC_REQ_ENTRY pEntry = NULL, pCurrEntry;
332 ULONG Now;
333
334 if(pTab == NULL)
335 {
336 DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
337 return NULL;
338 }
339
340 pEntry = TpcReqLookUp(pAd, DialogToken);
341 if (pEntry == NULL)
342 {
343 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
344 for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++)
345 {
346 NdisGetSystemUpTime(&Now);
347 pEntry = &pTab->Content[i];
348
349 if ((pEntry->Valid == TRUE)
350 && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + TPC_REQ_AGE_OUT)))
351 {
352 PTPC_REQ_ENTRY pPrevEntry = NULL;
353 ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
354 PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
355
356 // update Hash list
357 do
358 {
359 if (pProbeEntry == pEntry)
360 {
361 if (pPrevEntry == NULL)
362 {
363 pTab->Hash[HashIdx] = pEntry->pNext;
364 }
365 else
366 {
367 pPrevEntry->pNext = pEntry->pNext;
368 }
369 break;
370 }
371
372 pPrevEntry = pProbeEntry;
373 pProbeEntry = pProbeEntry->pNext;
374 } while (pProbeEntry);
375
376 NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
377 pTab->Size--;
378
379 break;
380 }
381
382 if (pEntry->Valid == FALSE)
383 break;
384 }
385
386 if (i < MAX_TPC_REQ_TAB_SIZE)
387 {
388 NdisGetSystemUpTime(&Now);
389 pEntry->lastTime = Now;
390 pEntry->Valid = TRUE;
391 pEntry->DialogToken = DialogToken;
392 pTab->Size++;
393 }
394 else
395 {
396 pEntry = NULL;
397 DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab tab full.\n", __FUNCTION__));
398 }
399
400 // add this Neighbor entry into HASH table
401 if (pEntry)
402 {
403 HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
404 if (pTab->Hash[HashIdx] == NULL)
405 {
406 pTab->Hash[HashIdx] = pEntry;
407 }
408 else
409 {
410 pCurrEntry = pTab->Hash[HashIdx];
411 while (pCurrEntry->pNext != NULL)
412 pCurrEntry = pCurrEntry->pNext;
413 pCurrEntry->pNext = pEntry;
414 }
415 }
416
417 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
418 }
419
420 return pEntry;
421}
422
423static VOID TpcReqDelete(
424 IN PRTMP_ADAPTER pAd,
425 IN UINT8 DialogToken)
426{
427 PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
428 PTPC_REQ_ENTRY pEntry = NULL;
429
430 if(pTab == NULL)
431 {
432 DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
433 return;
434 }
435
436 // if empty, return
437 if (pTab->Size == 0)
438 {
439 DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
440 return;
441 }
442
443 pEntry = TpcReqLookUp(pAd, DialogToken);
444 if (pEntry != NULL)
445 {
446 PTPC_REQ_ENTRY pPrevEntry = NULL;
447 ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
448 PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
449
450 RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
451 // update Hash list
452 do
453 {
454 if (pProbeEntry == pEntry)
455 {
456 if (pPrevEntry == NULL)
457 {
458 pTab->Hash[HashIdx] = pEntry->pNext;
459 }
460 else
461 {
462 pPrevEntry->pNext = pEntry->pNext;
463 }
464 break;
465 }
466
467 pPrevEntry = pProbeEntry;
468 pProbeEntry = pProbeEntry->pNext;
469 } while (pProbeEntry);
470
471 NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
472 pTab->Size--;
473
474 RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
475 }
476
477 return;
478}
479
480/*
481 ==========================================================================
482 Description:
483 Get Current TimeS tamp.
484
485 Parametrs:
486
487 Return : Current Time Stamp.
488 ==========================================================================
489 */
490static UINT64 GetCurrentTimeStamp(
491 IN PRTMP_ADAPTER pAd)
492{
493 // get current time stamp.
494 return 0;
495}
496
497/*
498 ==========================================================================
499 Description:
500 Get Current Transmit Power.
501
502 Parametrs:
503
504 Return : Current Time Stamp.
505 ==========================================================================
506 */
507static UINT8 GetCurTxPwr(
508 IN PRTMP_ADAPTER pAd,
509 IN UINT8 Wcid)
510{
511 return 16; /* 16 dBm */
512}
513
514/*
515 ==========================================================================
516 Description:
517 Insert Dialog Token into frame.
518
519 Parametrs:
520 1. frame buffer pointer.
521 2. frame length.
522 3. Dialog token.
523
524 Return : None.
525 ==========================================================================
526 */
527static VOID InsertDialogToken(
528 IN PRTMP_ADAPTER pAd,
529 OUT PUCHAR pFrameBuf,
530 OUT PULONG pFrameLen,
531 IN UINT8 DialogToken)
532{
533 ULONG TempLen;
534 MakeOutgoingFrame(pFrameBuf, &TempLen,
535 1, &DialogToken,
536 END_OF_ARGS);
537
538 *pFrameLen = *pFrameLen + TempLen;
539
540 return;
541}
542
543/*
544 ==========================================================================
545 Description:
546 Insert TPC Request IE into frame.
547
548 Parametrs:
549 1. frame buffer pointer.
550 2. frame length.
551
552 Return : None.
553 ==========================================================================
554 */
555 static VOID InsertTpcReqIE(
556 IN PRTMP_ADAPTER pAd,
557 OUT PUCHAR pFrameBuf,
558 OUT PULONG pFrameLen)
559{
560 ULONG TempLen;
561 ULONG Len = 0;
562 UINT8 ElementID = IE_TPC_REQUEST;
563
564 MakeOutgoingFrame(pFrameBuf, &TempLen,
565 1, &ElementID,
566 1, &Len,
567 END_OF_ARGS);
568
569 *pFrameLen = *pFrameLen + TempLen;
570
571 return;
572}
573
574/*
575 ==========================================================================
576 Description:
577 Insert TPC Report IE into frame.
578
579 Parametrs:
580 1. frame buffer pointer.
581 2. frame length.
582 3. Transmit Power.
583 4. Link Margin.
584
585 Return : None.
586 ==========================================================================
587 */
588 static VOID InsertTpcReportIE(
589 IN PRTMP_ADAPTER pAd,
590 OUT PUCHAR pFrameBuf,
591 OUT PULONG pFrameLen,
592 IN UINT8 TxPwr,
593 IN UINT8 LinkMargin)
594{
595 ULONG TempLen;
596 ULONG Len = sizeof(TPC_REPORT_INFO);
597 UINT8 ElementID = IE_TPC_REPORT;
598 TPC_REPORT_INFO TpcReportIE;
599
600 TpcReportIE.TxPwr = TxPwr;
601 TpcReportIE.LinkMargin = LinkMargin;
602
603 MakeOutgoingFrame(pFrameBuf, &TempLen,
604 1, &ElementID,
605 1, &Len,
606 Len, &TpcReportIE,
607 END_OF_ARGS);
608
609 *pFrameLen = *pFrameLen + TempLen;
610
611
612 return;
613}
614
615/*
616 ==========================================================================
617 Description:
618 Insert Channel Switch Announcement IE into frame.
619
620 Parametrs:
621 1. frame buffer pointer.
622 2. frame length.
623 3. channel switch announcement mode.
624 4. new selected channel.
625 5. channel switch announcement count.
626
627 Return : None.
628 ==========================================================================
629 */
630static VOID InsertChSwAnnIE(
631 IN PRTMP_ADAPTER pAd,
632 OUT PUCHAR pFrameBuf,
633 OUT PULONG pFrameLen,
634 IN UINT8 ChSwMode,
635 IN UINT8 NewChannel,
636 IN UINT8 ChSwCnt)
637{
638 ULONG TempLen;
639 ULONG Len = sizeof(CH_SW_ANN_INFO);
640 UINT8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
641 CH_SW_ANN_INFO ChSwAnnIE;
642
643 ChSwAnnIE.ChSwMode = ChSwMode;
644 ChSwAnnIE.Channel = NewChannel;
645 ChSwAnnIE.ChSwCnt = ChSwCnt;
646
647 MakeOutgoingFrame(pFrameBuf, &TempLen,
648 1, &ElementID,
649 1, &Len,
650 Len, &ChSwAnnIE,
651 END_OF_ARGS);
652
653 *pFrameLen = *pFrameLen + TempLen;
654
655
656 return;
657}
658
659/*
660 ==========================================================================
661 Description:
662 Insert Measure Request IE into frame.
663
664 Parametrs:
665 1. frame buffer pointer.
666 2. frame length.
667 3. Measure Token.
668 4. Measure Request Mode.
669 5. Measure Request Type.
670 6. Measure Channel.
671 7. Measure Start time.
672 8. Measure Duration.
673
674
675 Return : None.
676 ==========================================================================
677 */
678static VOID InsertMeasureReqIE(
679 IN PRTMP_ADAPTER pAd,
680 OUT PUCHAR pFrameBuf,
681 OUT PULONG pFrameLen,
682 IN PMEASURE_REQ_INFO pMeasureReqIE)
683{
684 ULONG TempLen;
685 UINT8 Len = sizeof(MEASURE_REQ_INFO);
686 UINT8 ElementID = IE_MEASUREMENT_REQUEST;
687
688 MakeOutgoingFrame(pFrameBuf, &TempLen,
689 1, &ElementID,
690 1, &Len,
691 Len, pMeasureReqIE,
692 END_OF_ARGS);
693
694 *pFrameLen = *pFrameLen + TempLen;
695
696 return;
697}
698
699/*
700 ==========================================================================
701 Description:
702 Insert Measure Report IE into frame.
703
704 Parametrs:
705 1. frame buffer pointer.
706 2. frame length.
707 3. Measure Token.
708 4. Measure Request Mode.
709 5. Measure Request Type.
710 6. Length of Report Infomation
711 7. Pointer of Report Infomation Buffer.
712
713 Return : None.
714 ==========================================================================
715 */
716static VOID InsertMeasureReportIE(
717 IN PRTMP_ADAPTER pAd,
718 OUT PUCHAR pFrameBuf,
719 OUT PULONG pFrameLen,
720 IN PMEASURE_REPORT_INFO pMeasureReportIE,
721 IN UINT8 ReportLnfoLen,
722 IN PUINT8 pReportInfo)
723{
724 ULONG TempLen;
725 ULONG Len;
726 UINT8 ElementID = IE_MEASUREMENT_REPORT;
727
728 Len = sizeof(MEASURE_REPORT_INFO) + ReportLnfoLen;
729
730 MakeOutgoingFrame(pFrameBuf, &TempLen,
731 1, &ElementID,
732 1, &Len,
733 Len, pMeasureReportIE,
734 END_OF_ARGS);
735
736 *pFrameLen = *pFrameLen + TempLen;
737
738 if ((ReportLnfoLen > 0) && (pReportInfo != NULL))
739 {
740 MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen,
741 ReportLnfoLen, pReportInfo,
742 END_OF_ARGS);
743
744 *pFrameLen = *pFrameLen + TempLen;
745 }
746 return;
747}
748
749/*
750 ==========================================================================
751 Description:
752 Prepare Measurement request action frame and enqueue it into
753 management queue waiting for transmition.
754
755 Parametrs:
756 1. the destination mac address of the frame.
757
758 Return : None.
759 ==========================================================================
760 */
761VOID EnqueueMeasurementReq(
762 IN PRTMP_ADAPTER pAd,
763 IN PUCHAR pDA,
764 IN UINT8 MeasureToken,
765 IN UINT8 MeasureReqMode,
766 IN UINT8 MeasureReqType,
767 IN UINT8 MeasureCh,
768 IN UINT16 MeasureDuration)
769{
770 PUCHAR pOutBuffer = NULL;
771 NDIS_STATUS NStatus;
772 ULONG FrameLen;
773 HEADER_802_11 ActHdr;
774 MEASURE_REQ_INFO MeasureReqIE;
775 UINT8 RmReqDailogToken = RandomByte(pAd);
776 UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
777
778 // build action frame header.
779 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
780 pAd->CurrentAddress);
781
782 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
783 if(NStatus != NDIS_STATUS_SUCCESS)
784 {
785 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
786 return;
787 }
788 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
789 FrameLen = sizeof(HEADER_802_11);
790
791 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRQ);
792
793 // fill Dialog Token
794 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, MeasureToken);
795
796 // prepare Measurement IE.
797 NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
798 MeasureReqIE.Token = RmReqDailogToken;
799 MeasureReqIE.ReqMode.word = MeasureReqMode;
800 MeasureReqIE.ReqType = MeasureReqType;
801 MeasureReqIE.MeasureReq.ChNum = MeasureCh;
802 MeasureReqIE.MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
803 MeasureReqIE.MeasureReq.MeasureDuration = cpu2le16(MeasureDuration);
804 InsertMeasureReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureReqIE);
805
806 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
807 MlmeFreeMemory(pAd, pOutBuffer);
808
809 return;
810}
811
812/*
813 ==========================================================================
814 Description:
815 Prepare Measurement report action frame and enqueue it into
816 management queue waiting for transmition.
817
818 Parametrs:
819 1. the destination mac address of the frame.
820
821 Return : None.
822 ==========================================================================
823 */
824VOID EnqueueMeasurementRep(
825 IN PRTMP_ADAPTER pAd,
826 IN PUCHAR pDA,
827 IN UINT8 DialogToken,
828 IN UINT8 MeasureToken,
829 IN UINT8 MeasureReqMode,
830 IN UINT8 MeasureReqType,
831 IN UINT8 ReportInfoLen,
832 IN PUINT8 pReportInfo)
833{
834 PUCHAR pOutBuffer = NULL;
835 NDIS_STATUS NStatus;
836 ULONG FrameLen;
837 HEADER_802_11 ActHdr;
838 MEASURE_REPORT_INFO MeasureRepIE;
839
840 // build action frame header.
841 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
842 pAd->CurrentAddress);
843
844 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
845 if(NStatus != NDIS_STATUS_SUCCESS)
846 {
847 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
848 return;
849 }
850 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
851 FrameLen = sizeof(HEADER_802_11);
852
853 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRP);
854
855 // fill Dialog Token
856 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
857
858 // prepare Measurement IE.
859 NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO));
860 MeasureRepIE.Token = MeasureToken;
861 MeasureRepIE.ReportMode.word = MeasureReqMode;
862 MeasureRepIE.ReportType = MeasureReqType;
863 InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo);
864
865 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
866 MlmeFreeMemory(pAd, pOutBuffer);
867
868 return;
869}
870
871/*
872 ==========================================================================
873 Description:
874 Prepare TPC Request action frame and enqueue it into
875 management queue waiting for transmition.
876
877 Parametrs:
878 1. the destination mac address of the frame.
879
880 Return : None.
881 ==========================================================================
882 */
883VOID EnqueueTPCReq(
884 IN PRTMP_ADAPTER pAd,
885 IN PUCHAR pDA,
886 IN UCHAR DialogToken)
887{
888 PUCHAR pOutBuffer = NULL;
889 NDIS_STATUS NStatus;
890 ULONG FrameLen;
891
892 HEADER_802_11 ActHdr;
893
894 // build action frame header.
895 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
896 pAd->CurrentAddress);
897
898 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
899 if(NStatus != NDIS_STATUS_SUCCESS)
900 {
901 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
902 return;
903 }
904 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
905 FrameLen = sizeof(HEADER_802_11);
906
907 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRQ);
908
909 // fill Dialog Token
910 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
911
912 // Insert TPC Request IE.
913 InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen);
914
915 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
916 MlmeFreeMemory(pAd, pOutBuffer);
917
918 return;
919}
920
921/*
922 ==========================================================================
923 Description:
924 Prepare TPC Report action frame and enqueue it into
925 management queue waiting for transmition.
926
927 Parametrs:
928 1. the destination mac address of the frame.
929
930 Return : None.
931 ==========================================================================
932 */
933VOID EnqueueTPCRep(
934 IN PRTMP_ADAPTER pAd,
935 IN PUCHAR pDA,
936 IN UINT8 DialogToken,
937 IN UINT8 TxPwr,
938 IN UINT8 LinkMargin)
939{
940 PUCHAR pOutBuffer = NULL;
941 NDIS_STATUS NStatus;
942 ULONG FrameLen;
943
944 HEADER_802_11 ActHdr;
945
946 // build action frame header.
947 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
948 pAd->CurrentAddress);
949
950 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
951 if(NStatus != NDIS_STATUS_SUCCESS)
952 {
953 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
954 return;
955 }
956 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
957 FrameLen = sizeof(HEADER_802_11);
958
959 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRP);
960
961 // fill Dialog Token
962 InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
963
964 // Insert TPC Request IE.
965 InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, LinkMargin);
966
967 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
968 MlmeFreeMemory(pAd, pOutBuffer);
969
970 return;
971}
972
973/*
974 ==========================================================================
975 Description:
976 Prepare Channel Switch Announcement action frame and enqueue it into
977 management queue waiting for transmition.
978
979 Parametrs:
980 1. the destination mac address of the frame.
981 2. Channel switch announcement mode.
982 2. a New selected channel.
983
984 Return : None.
985 ==========================================================================
986 */
987VOID EnqueueChSwAnn(
988 IN PRTMP_ADAPTER pAd,
989 IN PUCHAR pDA,
990 IN UINT8 ChSwMode,
991 IN UINT8 NewCh)
992{
993 PUCHAR pOutBuffer = NULL;
994 NDIS_STATUS NStatus;
995 ULONG FrameLen;
996
997 HEADER_802_11 ActHdr;
998
999 // build action frame header.
1000 MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
1001 pAd->CurrentAddress);
1002
1003 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
1004 if(NStatus != NDIS_STATUS_SUCCESS)
1005 {
1006 DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
1007 return;
1008 }
1009 NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
1010 FrameLen = sizeof(HEADER_802_11);
1011
1012 InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
1013
1014 InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode, NewCh, 0);
1015
1016 MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
1017 MlmeFreeMemory(pAd, pOutBuffer);
1018
1019 return;
1020}
1021
1022static BOOLEAN DfsRequirementCheck(
1023 IN PRTMP_ADAPTER pAd,
1024 IN UINT8 Channel)
1025{
1026 BOOLEAN Result = FALSE;
1027 INT i;
1028
1029 do
1030 {
1031 // check DFS procedure is running.
1032 // make sure DFS procedure won't start twice.
1033 if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
1034 {
1035 Result = FALSE;
1036 break;
1037 }
1038
1039 // check the new channel carried from Channel Switch Announcemnet is valid.
1040 for (i=0; i<pAd->ChannelListNum; i++)
1041 {
1042 if ((Channel == pAd->ChannelList[i].Channel)
1043 &&(pAd->ChannelList[i].RemainingTimeForUse == 0))
1044 {
1045 // found radar signal in the channel. the channel can't use at least for 30 minutes.
1046 pAd->ChannelList[i].RemainingTimeForUse = 1800;//30 min = 1800 sec
1047 Result = TRUE;
1048 break;
1049 }
1050 }
1051 } while(FALSE);
1052
1053 return Result;
1054}
1055
1056VOID NotifyChSwAnnToPeerAPs(
1057 IN PRTMP_ADAPTER pAd,
1058 IN PUCHAR pRA,
1059 IN PUCHAR pTA,
1060 IN UINT8 ChSwMode,
1061 IN UINT8 Channel)
1062{
1063#ifdef WDS_SUPPORT
1064 if (!((pRA[0] & 0xff) == 0xff)) // is pRA a broadcase address.
1065 {
1066 INT i;
1067 // info neighbor APs that Radar signal found throgh WDS link.
1068 for (i = 0; i < MAX_WDS_ENTRY; i++)
1069 {
1070 if (ValidWdsEntry(pAd, i))
1071 {
1072 PUCHAR pDA = pAd->WdsTab.WdsEntry[i].PeerWdsAddr;
1073
1074 // DA equal to SA. have no necessary orignal AP which found Radar signal.
1075 if (MAC_ADDR_EQUAL(pTA, pDA))
1076 continue;
1077
1078 // send Channel Switch Action frame to info Neighbro APs.
1079 EnqueueChSwAnn(pAd, pDA, ChSwMode, Channel);
1080 }
1081 }
1082 }
1083#endif // WDS_SUPPORT //
1084}
1085
1086static VOID StartDFSProcedure(
1087 IN PRTMP_ADAPTER pAd,
1088 IN UCHAR Channel,
1089 IN UINT8 ChSwMode)
1090{
1091 // start DFS procedure
1092 pAd->CommonCfg.Channel = Channel;
1093#ifdef DOT11_N_SUPPORT
1094 N_ChannelCheck(pAd);
1095#endif // DOT11_N_SUPPORT //
1096 pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE;
1097 pAd->CommonCfg.RadarDetect.CSCount = 0;
1098}
1099
1100/*
1101 ==========================================================================
1102 Description:
1103 Channel Switch Announcement action frame sanity check.
1104
1105 Parametrs:
1106 1. MLME message containing the received frame
1107 2. message length.
1108 3. Channel switch announcement infomation buffer.
1109
1110
1111 Return : None.
1112 ==========================================================================
1113 */
1114
1115/*
1116 Channel Switch Announcement IE.
1117 +----+-----+-----------+------------+-----------+
1118 | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt |
1119 +----+-----+-----------+------------+-----------+
1120 1 1 1 1 1
1121*/
1122static BOOLEAN PeerChSwAnnSanity(
1123 IN PRTMP_ADAPTER pAd,
1124 IN VOID *pMsg,
1125 IN ULONG MsgLen,
1126 OUT PCH_SW_ANN_INFO pChSwAnnInfo)
1127{
1128 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1129 PUCHAR pFramePtr = Fr->Octet;
1130 BOOLEAN result = FALSE;
1131 PEID_STRUCT eid_ptr;
1132
1133 // skip 802.11 header.
1134 MsgLen -= sizeof(HEADER_802_11);
1135
1136 // skip category and action code.
1137 pFramePtr += 2;
1138 MsgLen -= 2;
1139
1140 if (pChSwAnnInfo == NULL)
1141 return result;
1142
1143 eid_ptr = (PEID_STRUCT)pFramePtr;
1144 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1145 {
1146 switch(eid_ptr->Eid)
1147 {
1148 case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
1149 NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet, 1);
1150 NdisMoveMemory(&pChSwAnnInfo->Channel, eid_ptr->Octet + 1, 1);
1151 NdisMoveMemory(&pChSwAnnInfo->ChSwCnt, eid_ptr->Octet + 2, 1);
1152
1153 result = TRUE;
1154 break;
1155
1156 default:
1157 break;
1158 }
1159 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1160 }
1161
1162 return result;
1163}
1164
1165/*
1166 ==========================================================================
1167 Description:
1168 Measurement request action frame sanity check.
1169
1170 Parametrs:
1171 1. MLME message containing the received frame
1172 2. message length.
1173 3. Measurement request infomation buffer.
1174
1175 Return : None.
1176 ==========================================================================
1177 */
1178static BOOLEAN PeerMeasureReqSanity(
1179 IN PRTMP_ADAPTER pAd,
1180 IN VOID *pMsg,
1181 IN ULONG MsgLen,
1182 OUT PUINT8 pDialogToken,
1183 OUT PMEASURE_REQ_INFO pMeasureReqInfo)
1184{
1185 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1186 PUCHAR pFramePtr = Fr->Octet;
1187 BOOLEAN result = FALSE;
1188 PEID_STRUCT eid_ptr;
1189 PUCHAR ptr;
1190 UINT64 MeasureStartTime;
1191 UINT16 MeasureDuration;
1192
1193 // skip 802.11 header.
1194 MsgLen -= sizeof(HEADER_802_11);
1195
1196 // skip category and action code.
1197 pFramePtr += 2;
1198 MsgLen -= 2;
1199
1200 if (pMeasureReqInfo == NULL)
1201 return result;
1202
1203 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1204 pFramePtr += 1;
1205 MsgLen -= 1;
1206
1207 eid_ptr = (PEID_STRUCT)pFramePtr;
1208 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1209 {
1210 switch(eid_ptr->Eid)
1211 {
1212 case IE_MEASUREMENT_REQUEST:
1213 NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1);
1214 NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1);
1215 NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1);
1216 ptr = eid_ptr->Octet + 3;
1217 NdisMoveMemory(&pMeasureReqInfo->MeasureReq.ChNum, ptr, 1);
1218 NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
1219 pMeasureReqInfo->MeasureReq.MeasureStartTime = SWAP64(MeasureStartTime);
1220 NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
1221 pMeasureReqInfo->MeasureReq.MeasureDuration = SWAP16(MeasureDuration);
1222
1223 result = TRUE;
1224 break;
1225
1226 default:
1227 break;
1228 }
1229 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1230 }
1231
1232 return result;
1233}
1234
1235/*
1236 ==========================================================================
1237 Description:
1238 Measurement report action frame sanity check.
1239
1240 Parametrs:
1241 1. MLME message containing the received frame
1242 2. message length.
1243 3. Measurement report infomation buffer.
1244 4. basic report infomation buffer.
1245
1246 Return : None.
1247 ==========================================================================
1248 */
1249
1250/*
1251 Measurement Report IE.
1252 +----+-----+-------+-------------+--------------+----------------+
1253 | ID | Len | Token | Report Mode | Measure Type | Measure Report |
1254 +----+-----+-------+-------------+--------------+----------------+
1255 1 1 1 1 1 variable
1256
1257 Basic Report.
1258 +--------+------------+----------+-----+
1259 | Ch Num | Start Time | Duration | Map |
1260 +--------+------------+----------+-----+
1261 1 8 2 1
1262
1263 Map Field Bit Format.
1264 +-----+---------------+---------------------+-------+------------+----------+
1265 | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved |
1266 +-----+---------------+---------------------+-------+------------+----------+
1267 0 1 2 3 4 5-7
1268*/
1269static BOOLEAN PeerMeasureReportSanity(
1270 IN PRTMP_ADAPTER pAd,
1271 IN VOID *pMsg,
1272 IN ULONG MsgLen,
1273 OUT PUINT8 pDialogToken,
1274 OUT PMEASURE_REPORT_INFO pMeasureReportInfo,
1275 OUT PUINT8 pReportBuf)
1276{
1277 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1278 PUCHAR pFramePtr = Fr->Octet;
1279 BOOLEAN result = FALSE;
1280 PEID_STRUCT eid_ptr;
1281 PUCHAR ptr;
1282
1283 // skip 802.11 header.
1284 MsgLen -= sizeof(HEADER_802_11);
1285
1286 // skip category and action code.
1287 pFramePtr += 2;
1288 MsgLen -= 2;
1289
1290 if (pMeasureReportInfo == NULL)
1291 return result;
1292
1293 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1294 pFramePtr += 1;
1295 MsgLen -= 1;
1296
1297 eid_ptr = (PEID_STRUCT)pFramePtr;
1298 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1299 {
1300 switch(eid_ptr->Eid)
1301 {
1302 case IE_MEASUREMENT_REPORT:
1303 NdisMoveMemory(&pMeasureReportInfo->Token, eid_ptr->Octet, 1);
1304 NdisMoveMemory(&pMeasureReportInfo->ReportMode, eid_ptr->Octet + 1, 1);
1305 NdisMoveMemory(&pMeasureReportInfo->ReportType, eid_ptr->Octet + 2, 1);
1306 if (pMeasureReportInfo->ReportType == RM_BASIC)
1307 {
1308 PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf;
1309 ptr = eid_ptr->Octet + 3;
1310 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1311 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
1312 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
1313 NdisMoveMemory(&pReport->Map, ptr + 11, 1);
1314
1315 }
1316 else if (pMeasureReportInfo->ReportType == RM_CCA)
1317 {
1318 PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf;
1319 ptr = eid_ptr->Octet + 3;
1320 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1321 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
1322 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
1323 NdisMoveMemory(&pReport->CCA_Busy_Fraction, ptr + 11, 1);
1324
1325 }
1326 else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM)
1327 {
1328 PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf;
1329 ptr = eid_ptr->Octet + 3;
1330 NdisMoveMemory(&pReport->ChNum, ptr, 1);
1331 NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
1332 NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
1333 NdisMoveMemory(&pReport->RPI_Density, ptr + 11, 8);
1334 }
1335 result = TRUE;
1336 break;
1337
1338 default:
1339 break;
1340 }
1341 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1342 }
1343
1344 return result;
1345}
1346
1347/*
1348 ==========================================================================
1349 Description:
1350 TPC Request action frame sanity check.
1351
1352 Parametrs:
1353 1. MLME message containing the received frame
1354 2. message length.
1355 3. Dialog Token.
1356
1357 Return : None.
1358 ==========================================================================
1359 */
1360static BOOLEAN PeerTpcReqSanity(
1361 IN PRTMP_ADAPTER pAd,
1362 IN VOID *pMsg,
1363 IN ULONG MsgLen,
1364 OUT PUINT8 pDialogToken)
1365{
1366 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1367 PUCHAR pFramePtr = Fr->Octet;
1368 BOOLEAN result = FALSE;
1369 PEID_STRUCT eid_ptr;
1370
1371 MsgLen -= sizeof(HEADER_802_11);
1372
1373 // skip category and action code.
1374 pFramePtr += 2;
1375 MsgLen -= 2;
1376
1377 if (pDialogToken == NULL)
1378 return result;
1379
1380 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1381 pFramePtr += 1;
1382 MsgLen -= 1;
1383
1384 eid_ptr = (PEID_STRUCT)pFramePtr;
1385 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1386 {
1387 switch(eid_ptr->Eid)
1388 {
1389 case IE_TPC_REQUEST:
1390 result = TRUE;
1391 break;
1392
1393 default:
1394 break;
1395 }
1396 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1397 }
1398
1399 return result;
1400}
1401
1402/*
1403 ==========================================================================
1404 Description:
1405 TPC Report action frame sanity check.
1406
1407 Parametrs:
1408 1. MLME message containing the received frame
1409 2. message length.
1410 3. Dialog Token.
1411 4. TPC Report IE.
1412
1413 Return : None.
1414 ==========================================================================
1415 */
1416static BOOLEAN PeerTpcRepSanity(
1417 IN PRTMP_ADAPTER pAd,
1418 IN VOID *pMsg,
1419 IN ULONG MsgLen,
1420 OUT PUINT8 pDialogToken,
1421 OUT PTPC_REPORT_INFO pTpcRepInfo)
1422{
1423 PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
1424 PUCHAR pFramePtr = Fr->Octet;
1425 BOOLEAN result = FALSE;
1426 PEID_STRUCT eid_ptr;
1427
1428 MsgLen -= sizeof(HEADER_802_11);
1429
1430 // skip category and action code.
1431 pFramePtr += 2;
1432 MsgLen -= 2;
1433
1434 if (pDialogToken == NULL)
1435 return result;
1436
1437 NdisMoveMemory(pDialogToken, pFramePtr, 1);
1438 pFramePtr += 1;
1439 MsgLen -= 1;
1440
1441 eid_ptr = (PEID_STRUCT)pFramePtr;
1442 while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
1443 {
1444 switch(eid_ptr->Eid)
1445 {
1446 case IE_TPC_REPORT:
1447 NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1);
1448 NdisMoveMemory(&pTpcRepInfo->LinkMargin, eid_ptr->Octet + 1, 1);
1449 result = TRUE;
1450 break;
1451
1452 default:
1453 break;
1454 }
1455 eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
1456 }
1457
1458 return result;
1459}
1460
1461/*
1462 ==========================================================================
1463 Description:
1464 Channel Switch Announcement action frame handler.
1465
1466 Parametrs:
1467 Elme - MLME message containing the received frame
1468
1469 Return : None.
1470 ==========================================================================
1471 */
1472static VOID PeerChSwAnnAction(
1473 IN PRTMP_ADAPTER pAd,
1474 IN MLME_QUEUE_ELEM *Elem)
1475{
1476 CH_SW_ANN_INFO ChSwAnnInfo;
1477 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1478#ifdef CONFIG_STA_SUPPORT
1479 UCHAR index = 0, Channel = 0, NewChannel = 0;
1480 ULONG Bssidx = 0;
1481#endif // CONFIG_STA_SUPPORT //
1482
1483 NdisZeroMemory(&ChSwAnnInfo, sizeof(CH_SW_ANN_INFO));
1484 if (! PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo))
1485 {
1486 DBGPRINT(RT_DEBUG_TRACE, ("Invalid Channel Switch Action Frame.\n"));
1487 return;
1488 }
1489
1490
1491#ifdef CONFIG_STA_SUPPORT
1492 if (pAd->OpMode == OPMODE_STA)
1493 {
1494 Bssidx = BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3, pAd->CommonCfg.Channel);
1495 if (Bssidx == BSS_NOT_FOUND)
1496 {
1497 DBGPRINT(RT_DEBUG_TRACE, ("PeerChSwAnnAction - Bssidx is not found\n"));
1498 return;
1499 }
1500
1501 DBGPRINT(RT_DEBUG_TRACE, ("\n****Bssidx is %d, Channel = %d\n", index, pAd->ScanTab.BssEntry[Bssidx].Channel));
1502 hex_dump("SSID",pAd->ScanTab.BssEntry[Bssidx].Bssid ,6);
1503
1504 Channel = pAd->CommonCfg.Channel;
1505 NewChannel = ChSwAnnInfo.Channel;
1506
1507 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
1508 {
1509 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1510 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1511 AsicSwitchChannel(pAd, 1, FALSE);
1512 AsicLockChannel(pAd, 1);
1513 LinkDown(pAd, FALSE);
1514 MlmeQueueInit(&pAd->Mlme.Queue);
1515 BssTableInit(&pAd->ScanTab);
1516 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1517
1518 // channel sanity check
1519 for (index = 0 ; index < pAd->ChannelListNum; index++)
1520 {
1521 if (pAd->ChannelList[index].Channel == NewChannel)
1522 {
1523 pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
1524 pAd->CommonCfg.Channel = NewChannel;
1525 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1526 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1527 DBGPRINT(RT_DEBUG_TRACE, ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
1528 break;
1529 }
1530 }
1531
1532 if (index >= pAd->ChannelListNum)
1533 {
1534 DBGPRINT_ERR(("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
1535 }
1536 }
1537 }
1538#endif // CONFIG_STA_SUPPORT //
1539
1540 return;
1541}
1542
1543
1544/*
1545 ==========================================================================
1546 Description:
1547 Measurement Request action frame handler.
1548
1549 Parametrs:
1550 Elme - MLME message containing the received frame
1551
1552 Return : None.
1553 ==========================================================================
1554 */
1555static VOID PeerMeasureReqAction(
1556 IN PRTMP_ADAPTER pAd,
1557 IN MLME_QUEUE_ELEM *Elem)
1558{
1559 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1560 UINT8 DialogToken;
1561 MEASURE_REQ_INFO MeasureReqInfo;
1562 MEASURE_REPORT_MODE ReportMode;
1563
1564 if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo))
1565 {
1566 ReportMode.word = 0;
1567 ReportMode.field.Incapable = 1;
1568 EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken, MeasureReqInfo.Token, ReportMode.word, MeasureReqInfo.ReqType, 0, NULL);
1569 }
1570
1571 return;
1572}
1573
1574/*
1575 ==========================================================================
1576 Description:
1577 Measurement Report action frame handler.
1578
1579 Parametrs:
1580 Elme - MLME message containing the received frame
1581
1582 Return : None.
1583 ==========================================================================
1584 */
1585static VOID PeerMeasureReportAction(
1586 IN PRTMP_ADAPTER pAd,
1587 IN MLME_QUEUE_ELEM *Elem)
1588{
1589 MEASURE_REPORT_INFO MeasureReportInfo;
1590 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1591 UINT8 DialogToken;
1592 PUINT8 pMeasureReportInfo;
1593
1594// if (pAd->CommonCfg.bIEEE80211H != TRUE)
1595// return;
1596
1597 if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
1598 {
1599 DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __FUNCTION__, sizeof(MEASURE_RPI_REPORT)));
1600 return;
1601 }
1602
1603 NdisZeroMemory(&MeasureReportInfo, sizeof(MEASURE_REPORT_INFO));
1604 NdisZeroMemory(pMeasureReportInfo, sizeof(MEASURE_RPI_REPORT));
1605 if (PeerMeasureReportSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo, pMeasureReportInfo))
1606 {
1607 do {
1608 PMEASURE_REQ_ENTRY pEntry = NULL;
1609
1610 // Not a autonomous measure report.
1611 // check the dialog token field. drop it if the dialog token doesn't match.
1612 if ((DialogToken != 0)
1613 && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL))
1614 break;
1615
1616 if (pEntry != NULL)
1617 MeasureReqDelete(pAd, pEntry->DialogToken);
1618
1619 if (MeasureReportInfo.ReportType == RM_BASIC)
1620 {
1621 PMEASURE_BASIC_REPORT pBasicReport = (PMEASURE_BASIC_REPORT)pMeasureReportInfo;
1622 if ((pBasicReport->Map.field.Radar)
1623 && (DfsRequirementCheck(pAd, pBasicReport->ChNum) == TRUE))
1624 {
1625 NotifyChSwAnnToPeerAPs(pAd, pFr->Hdr.Addr1, pFr->Hdr.Addr2, 1, pBasicReport->ChNum);
1626 StartDFSProcedure(pAd, pBasicReport->ChNum, 1);
1627 }
1628 }
1629 } while (FALSE);
1630 }
1631 else
1632 DBGPRINT(RT_DEBUG_TRACE, ("Invalid Measurement Report Frame.\n"));
1633
1634 kfree(pMeasureReportInfo);
1635
1636 return;
1637}
1638
1639/*
1640 ==========================================================================
1641 Description:
1642 TPC Request action frame handler.
1643
1644 Parametrs:
1645 Elme - MLME message containing the received frame
1646
1647 Return : None.
1648 ==========================================================================
1649 */
1650static VOID PeerTpcReqAction(
1651 IN PRTMP_ADAPTER pAd,
1652 IN MLME_QUEUE_ELEM *Elem)
1653{
1654 PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
1655 PUCHAR pFramePtr = pFr->Octet;
1656 UINT8 DialogToken;
1657 UINT8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
1658 UINT8 LinkMargin = 0;
1659 CHAR RealRssi;
1660
1661 // link margin: Ratio of the received signal power to the minimum desired by the station (STA). The
1662 // STA may incorporate rate information and channel conditions, including interference, into its computation
1663 // of link margin.
1664
1665 RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
1666 ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
1667 ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1668
1669 // skip Category and action code.
1670 pFramePtr += 2;
1671
1672 // Dialog token.
1673 NdisMoveMemory(&DialogToken, pFramePtr, 1);
1674
1675 LinkMargin = (RealRssi / MIN_RCV_PWR);
1676 if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken))
1677 EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr, LinkMargin);
1678
1679 return;
1680}
1681
1682/*
1683 ==========================================================================
1684 Description:
1685 TPC Report action frame handler.
1686
1687 Parametrs:
1688 Elme - MLME message containing the received frame
1689
1690 Return : None.
1691 ==========================================================================
1692 */
1693static VOID PeerTpcRepAction(
1694 IN PRTMP_ADAPTER pAd,
1695 IN MLME_QUEUE_ELEM *Elem)
1696{
1697 UINT8 DialogToken;
1698 TPC_REPORT_INFO TpcRepInfo;
1699 PTPC_REQ_ENTRY pEntry = NULL;
1700
1701 NdisZeroMemory(&TpcRepInfo, sizeof(TPC_REPORT_INFO));
1702 if (PeerTpcRepSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo))
1703 {
1704 if ((pEntry = TpcReqLookUp(pAd, DialogToken)) != NULL)
1705 {
1706 TpcReqDelete(pAd, pEntry->DialogToken);
1707 DBGPRINT(RT_DEBUG_TRACE, ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
1708 __FUNCTION__, DialogToken, TpcRepInfo.TxPwr, TpcRepInfo.LinkMargin));
1709 }
1710 }
1711
1712 return;
1713}
1714
1715/*
1716 ==========================================================================
1717 Description:
1718 Spectrun action frames Handler such as channel switch annoucement,
1719 measurement report, measurement request actions frames.
1720
1721 Parametrs:
1722 Elme - MLME message containing the received frame
1723
1724 Return : None.
1725 ==========================================================================
1726 */
1727VOID PeerSpectrumAction(
1728 IN PRTMP_ADAPTER pAd,
1729 IN MLME_QUEUE_ELEM *Elem)
1730{
1731
1732 UCHAR Action = Elem->Msg[LENGTH_802_11+1];
1733
1734 if (pAd->CommonCfg.bIEEE80211H != TRUE)
1735 return;
1736
1737 switch(Action)
1738 {
1739 case SPEC_MRQ:
1740 // current rt2860 unable do such measure specified in Measurement Request.
1741 // reject all measurement request.
1742 PeerMeasureReqAction(pAd, Elem);
1743 break;
1744
1745 case SPEC_MRP:
1746 PeerMeasureReportAction(pAd, Elem);
1747 break;
1748
1749 case SPEC_TPCRQ:
1750 PeerTpcReqAction(pAd, Elem);
1751 break;
1752
1753 case SPEC_TPCRP:
1754 PeerTpcRepAction(pAd, Elem);
1755 break;
1756
1757 case SPEC_CHANNEL_SWITCH:
1758{
1759#ifdef DOT11N_DRAFT3
1760 SEC_CHA_OFFSET_IE Secondary;
1761 CHA_SWITCH_ANNOUNCE_IE ChannelSwitch;
1762
1763 // 802.11h only has Channel Switch Announcement IE.
1764 RTMPMoveMemory(&ChannelSwitch, &Elem->Msg[LENGTH_802_11+4], sizeof (CHA_SWITCH_ANNOUNCE_IE));
1765
1766 // 802.11n D3.03 adds secondary channel offset element in the end.
1767 if (Elem->MsgLen == (LENGTH_802_11 + 2 + sizeof (CHA_SWITCH_ANNOUNCE_IE) + sizeof (SEC_CHA_OFFSET_IE)))
1768 {
1769 RTMPMoveMemory(&Secondary, &Elem->Msg[LENGTH_802_11+9], sizeof (SEC_CHA_OFFSET_IE));
1770 }
1771 else
1772 {
1773 Secondary.SecondaryChannelOffset = 0;
1774 }
1775
1776 if ((Elem->Msg[LENGTH_802_11+2] == IE_CHANNEL_SWITCH_ANNOUNCEMENT) && (Elem->Msg[LENGTH_802_11+3] == 3))
1777 {
1778 ChannelSwitchAction(pAd, Elem->Wcid, ChannelSwitch.NewChannel, Secondary.SecondaryChannelOffset);
1779 }
1780#endif // DOT11N_DRAFT3 //
1781}
1782 PeerChSwAnnAction(pAd, Elem);
1783 break;
1784 }
1785
1786 return;
1787}
1788
1789/*
1790 ==========================================================================
1791 Description:
1792
1793 Parametrs:
1794
1795 Return : None.
1796 ==========================================================================
1797 */
1798INT Set_MeasureReq_Proc(
1799 IN PRTMP_ADAPTER pAd,
1800 IN PUCHAR arg)
1801{
1802 UINT Aid = 1;
1803 UINT ArgIdx;
1804 PUCHAR thisChar;
1805
1806 MEASURE_REQ_MODE MeasureReqMode;
1807 UINT8 MeasureReqToken = RandomByte(pAd);
1808 UINT8 MeasureReqType = RM_BASIC;
1809 UINT8 MeasureCh = 1;
1810
1811 ArgIdx = 1;
1812 while ((thisChar = strsep((char **)&arg, "-")) != NULL)
1813 {
1814 switch(ArgIdx)
1815 {
1816 case 1: // Aid.
1817 Aid = simple_strtol(thisChar, 0, 16);
1818 break;
1819
1820 case 2: // Measurement Request Type.
1821 MeasureReqType = simple_strtol(thisChar, 0, 16);
1822 if (MeasureReqType > 3)
1823 {
1824 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __FUNCTION__, MeasureReqType));
1825 return TRUE;
1826 }
1827 break;
1828
1829 case 3: // Measurement channel.
1830 MeasureCh = simple_strtol(thisChar, 0, 16);
1831 break;
1832 }
1833 ArgIdx++;
1834 }
1835
1836 DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __FUNCTION__, Aid, MeasureReqType, MeasureCh));
1837 if (!VALID_WCID(Aid))
1838 {
1839 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
1840 return TRUE;
1841 }
1842
1843 MeasureReqMode.word = 0;
1844 MeasureReqMode.field.Enable = 1;
1845
1846 MeasureReqInsert(pAd, MeasureReqToken);
1847
1848 EnqueueMeasurementReq(pAd, pAd->MacTab.Content[Aid].Addr,
1849 MeasureReqToken, MeasureReqMode.word, MeasureReqType, MeasureCh, 2000);
1850
1851 return TRUE;
1852}
1853
1854INT Set_TpcReq_Proc(
1855 IN PRTMP_ADAPTER pAd,
1856 IN PUCHAR arg)
1857{
1858 UINT Aid;
1859
1860 UINT8 TpcReqToken = RandomByte(pAd);
1861
1862 Aid = simple_strtol(arg, 0, 16);
1863
1864 DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __FUNCTION__, Aid));
1865 if (!VALID_WCID(Aid))
1866 {
1867 DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
1868 return TRUE;
1869 }
1870
1871 TpcReqInsert(pAd, TpcReqToken);
1872
1873 EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken);
1874
1875 return TRUE;
1876}
1877
diff --git a/drivers/staging/rt2860/config.mk b/drivers/staging/rt2860/config.mk
new file mode 100644
index 00000000000..f57d7bbffb2
--- /dev/null
+++ b/drivers/staging/rt2860/config.mk
@@ -0,0 +1,245 @@
1# Support ATE function
2HAS_ATE=n
3
4# Support 28xx QA ATE function
5HAS_28xx_QA=n
6
7# Support Wpa_Supplicant
8HAS_WPA_SUPPLICANT=n
9
10# Support Native WpaSupplicant for Network Maganger
11HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=n
12
13#Support Net interface block while Tx-Sw queue full
14HAS_BLOCK_NET_IF=n
15
16#Support DFS function
17HAS_DFS_SUPPORT=n
18
19#Support Carrier-Sense function
20HAS_CS_SUPPORT=n
21
22#ifdef MULTI_CARD
23# Support for Multiple Cards
24HAS_MC_SUPPORT=n
25#endif // MULTI_CARD //
26
27#Support for IEEE802.11e DLS
28HAS_QOS_DLS_SUPPORT=n
29
30#Support for EXT_CHANNEL
31HAS_EXT_BUILD_CHANNEL_LIST=n
32
33#Support for Net-SNMP
34HAS_SNMP_SUPPORT=n
35
36#Support features of Single SKU.
37HAS_SINGLE_SKU_SUPPORT=n
38
39#Support features of 802.11n
40HAS_DOT11_N_SUPPORT=y
41
42
43#################################################
44
45CC := $(CROSS_COMPILE)gcc
46LD := $(CROSS_COMPILE)ld
47
48WFLAGS := -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT -DLINUX -Wall -Wstrict-prototypes -Wno-trigraphs
49
50
51#################################################
52
53#ifdef CONFIG_STA_SUPPORT
54# config for STA mode
55
56ifeq ($(RT28xx_MODE),STA)
57WFLAGS += -DCONFIG_STA_SUPPORT -DDBG
58
59ifeq ($(HAS_WPA_SUPPLICANT),y)
60WFLAGS += -DWPA_SUPPLICANT_SUPPORT
61endif
62
63ifeq ($(HAS_NATIVE_WPA_SUPPLICANT_SUPPORT),y)
64WFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT
65endif
66
67ifeq ($(HAS_ATE),y)
68WFLAGS += -DRALINK_ATE
69ifeq ($(HAS_28xx_QA),y)
70WFLAGS += -DRALINK_28xx_QA
71endif
72endif
73
74ifeq ($(HAS_SNMP_SUPPORT),y)
75WFLAGS += -DSNMP_SUPPORT
76endif
77
78ifeq ($(HAS_QOS_DLS_SUPPORT),y)
79WFLAGS += -DQOS_DLS_SUPPORT
80endif
81
82ifeq ($(HAS_DOT11_N_SUPPORT),y)
83WFLAGS += -DDOT11_N_SUPPORT
84endif
85
86ifeq ($(HAS_CS_SUPPORT),y)
87WFLAGS += -DCARRIER_DETECTION_SUPPORT
88endif
89
90ifeq ($(HAS_SINGLE_SKU_SUPPORT),y)
91WFLAGS += -DSINGLE_SKU
92endif
93
94endif
95# endif of ifeq ($(RT28xx_MODE),STA)
96#endif // CONFIG_STA_SUPPORT //
97
98#################################################
99
100#################################################
101
102#
103# Common compiler flag
104#
105
106
107ifeq ($(HAS_EXT_BUILD_CHANNEL_LIST),y)
108WFLAGS += -DEXT_BUILD_CHANNEL_LIST
109endif
110
111ifeq ($(CHIPSET),2860)
112WFLAGS +=-DRT2860
113endif
114
115ifeq ($(CHIPSET),2870)
116WFLAGS +=-DRT2870
117endif
118
119ifeq ($(PLATFORM),5VT)
120#WFLAGS += -DCONFIG_5VT_ENHANCE
121endif
122
123ifeq ($(HAS_BLOCK_NET_IF),y)
124WFLAGS += -DBLOCK_NET_IF
125endif
126
127ifeq ($(HAS_DFS_SUPPORT),y)
128WFLAGS += -DDFS_SUPPORT
129endif
130
131#ifdef MULTI_CARD
132ifeq ($(HAS_MC_SUPPORT),y)
133WFLAGS += -DMULTIPLE_CARD_SUPPORT
134endif
135#endif // MULTI_CARD //
136
137ifeq ($(HAS_LLTD),y)
138WFLAGS += -DLLTD_SUPPORT
139endif
140
141ifeq ($(PLATFORM),IXP)
142WFLAGS += -DRT_BIG_ENDIAN
143endif
144
145ifeq ($(PLATFORM),IKANOS_V160)
146WFLAGS += -DRT_BIG_ENDIAN -DIKANOS_VX_1X0
147endif
148
149ifeq ($(PLATFORM),IKANOS_V180)
150WFLAGS += -DRT_BIG_ENDIAN -DIKANOS_VX_1X0
151endif
152
153ifeq ($(PLATFORM),INF_TWINPASS)
154WFLAGS += -DRT_BIG_ENDIAN -DINF_TWINPASS
155endif
156
157ifeq ($(PLATFORM),INF_DANUBE)
158WFLAGS += -DINF_DANUBE -DRT_BIG_ENDIAN
159endif
160
161ifeq ($(PLATFORM),CAVM_OCTEON)
162WFLAGS += -DRT_BIG_ENDIAN
163endif
164
165ifeq ($(PLATFORM),BRCM_6358)
166WFLAGS += -DRT_BIG_ENDIAN
167endif
168
169ifeq ($(PLATFORM),INF_AMAZON_SE)
170#WFLAGS += -DRT_BIG_ENDIAN -DINF_AMAZON_SE -DBG_FT_SUPPORT
171WFLAGS += -DRT_BIG_ENDIAN -DINF_AMAZON_SE
172endif
173
174#kernel build options for 2.4
175# move to Makefile outside LINUX_SRC := /opt/star/kernel/linux-2.4.27-star
176
177ifeq ($(PLATFORM),STAR)
178CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -Uarm -fno-common -pipe -mapcs-32 -D__LINUX_ARM_ARCH__=4 -march=armv4 -mshort-load-bytes -msoft-float -Uarm -DMODULE -DMODVERSIONS -include $(LINUX_SRC)/include/linux/modversions.h $(WFLAGS)
179
180export CFLAGS
181endif
182
183ifeq ($(PLATFORM),SIGMA)
184CFLAGS := -D__KERNEL__ -I$(RT28xx_DIR)/include -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -DEM86XX_CHIP=EM86XX_CHIPID_TANGO2 -DEM86XX_REVISION=6 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT2860_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -mabi=32 -march=mips32r2 -Wa,-32 -Wa,-march=mips32r2 -Wa,-mips32r2 -Wa,--trap -DMODULE $(WFLAGS)
185
186export CFLAGS
187endif
188
189ifeq ($(PLATFORM),SIGMA_8622)
190CFLAGS := -D__KERNEL__ -I$(CROSS_COMPILE_INCLUDE)/include -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fno-common -pipe -fno-builtin -D__linux__ -DNO_MM -mapcs-32 -march=armv4 -mtune=arm7tdmi -msoft-float -DMODULE -mshort-load-bytes -nostdinc -iwithprefix -DMODULE $(WFLAGS)
191export CFLAGS
192endif
193
194ifeq ($(PLATFORM),5VT)
195CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-omit-frame-pointer -mapcs -mno-sched-prolog -mabi=apcs-gnu -mno-thumb-interwork -D__LINUX_ARM_ARCH__=5 -march=armv5te -mtune=arm926ej-s --param max-inline-insns-single=40000 -Uarm -Wdeclaration-after-statement -Wno-pointer-sign -DMODULE $(WFLAGS)
196
197export CFLAGS
198endif
199
200ifeq ($(PLATFORM),IKANOS_V160)
201CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT28xx_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -march=lx4189 -Wa, -DMODULE $(WFLAGS)
202export CFLAGS
203endif
204
205ifeq ($(PLATFORM),IKANOS_V180)
206CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(LINUX_SRC)/include/asm/gcc -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-tango2 -I$(LINUX_SRC)/include/asm-mips/mach-generic -I$(RT28xx_DIR)/include -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -mips32r2 -Wa, -DMODULE $(WFLAGS)
207export CFLAGS
208endif
209
210ifeq ($(PLATFORM),INF_TWINPASS)
211CFLAGS := -D__KERNEL__ -DMODULE -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -G 0 -mno-abicalls -fno-pic -march=4kc -mips32 -Wa,--trap -pipe -mlong-calls $(WFLAGS)
212export CFLAGS
213endif
214
215ifeq ($(PLATFORM),INF_DANUBE)
216CFLAGS := -I$(RT28xx_DIR)/include $(WFLAGS) -Wundef -fno-strict-aliasing -fno-common -ffreestanding -Os -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic -pipe -msoft-float -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap -I$(LINUX_SRC)/include/asm-mips/mach-generic
217export CFLAGS
218endif
219
220ifeq ($(PLATFORM),BRCM_6358)
221CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include -nostdinc -iwithprefix include -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -I $(LINUX_SRC)/include/asm/gcc -G 0 -mno-abicalls -fno-pic -pipe -finline-limit=100000 -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap -I$(LINUX_SRC)/include/asm-mips/mach-bcm963xx -I$(LINUX_SRC)/include/asm-mips/mach-generic -Os -fomit-frame-pointer -Wdeclaration-after-statement -DMODULE -mlong-calls
222export CFLAGS
223endif
224
225ifeq ($(PLATFORM),PC)
226 ifneq (,$(findstring 2.4,$(LINUX_SRC)))
227 # Linux 2.4
228 CFLAGS := -D__KERNEL__ -I$(LINUX_SRC)/include -I$(RT28xx_DIR)/include -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -DMODULE -DMODVERSIONS -include $(LINUX_SRC)/include/linux/modversions.h $(WFLAGS)
229 export CFLAGS
230 else
231 # Linux 2.6
232 EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include
233 endif
234endif
235
236ifeq ($(PLATFORM),IXP)
237 EXTRA_CFLAGS := -v $(WFLAGS) -I$(RT28xx_DIR)/include -mbig-endian
238endif
239
240ifeq ($(PLATFORM),CAVM_OCTEON)
241 EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include \
242 -mabi=64 $(WFLAGS)
243export CFLAGS
244endif
245
diff --git a/drivers/staging/rt2860/dfs.h b/drivers/staging/rt2860/dfs.h
new file mode 100644
index 00000000000..752a6352d9d
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/leap.h b/drivers/staging/rt2860/leap.h
new file mode 100644
index 00000000000..6818c1ff4d7
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/link_list.h b/drivers/staging/rt2860/link_list.h
new file mode 100644
index 00000000000..f6521133fd5
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/md4.h b/drivers/staging/rt2860/md4.h
new file mode 100644
index 00000000000..f1e5b526350
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/md5.h b/drivers/staging/rt2860/md5.h
new file mode 100644
index 00000000000..d85db12170d
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/mlme.h b/drivers/staging/rt2860/mlme.h
new file mode 100644
index 00000000000..5cb61652b66
--- /dev/null
+++ b/drivers/staging/rt2860/mlme.h
@@ -0,0 +1,1447 @@
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// maximum supported capability information -
43// ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot
44#define SUPPORTED_CAPABILITY_INFO 0x0533
45
46#define END_OF_ARGS -1
47#define LFSR_MASK 0x80000057
48#define MLME_TASK_EXEC_INTV 100/*200*/ //
49#define LEAD_TIME 5
50#define MLME_TASK_EXEC_MULTIPLE 10 /*5*/ // MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec
51#define REORDER_EXEC_INTV 100 // 0.1 sec
52
53// The definition of Radar detection duration region
54#define CE 0
55#define FCC 1
56#define JAP 2
57#define JAP_W53 3
58#define JAP_W56 4
59#define MAX_RD_REGION 5
60
61#ifdef NDIS51_MINIPORT
62#define BEACON_LOST_TIME 4000 // 2048 msec = 2 sec
63#else
64#define BEACON_LOST_TIME 4 * OS_HZ // 2048 msec = 2 sec
65#endif
66
67#define DLS_TIMEOUT 1200 // unit: msec
68#define AUTH_TIMEOUT 300 // unit: msec
69#define ASSOC_TIMEOUT 300 // unit: msec
70#define JOIN_TIMEOUT 2 * OS_HZ // unit: msec
71#define SHORT_CHANNEL_TIME 90 // unit: msec
72#define MIN_CHANNEL_TIME 110 // unit: msec, for dual band scan
73#define MAX_CHANNEL_TIME 140 // unit: msec, for single band scan
74#define FAST_ACTIVE_SCAN_TIME 30 // Active scan waiting for probe response time
75#define CW_MIN_IN_BITS 4 // actual CwMin = 2^CW_MIN_IN_BITS - 1
76
77
78#ifdef CONFIG_STA_SUPPORT
79#ifndef CONFIG_AP_SUPPORT
80#define CW_MAX_IN_BITS 10 // actual CwMax = 2^CW_MAX_IN_BITS - 1
81#endif
82#endif // CONFIG_STA_SUPPORT //
83
84#ifdef CONFIG_APSTA_MIXED_SUPPORT
85extern UINT32 CW_MAX_IN_BITS;
86#endif // CONFIG_APSTA_MIXED_SUPPORT //
87
88// Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720).
89// SHould not refer to this constant anymore
90//#define RSSI_TO_DBM_OFFSET 120 // for RT2530 RSSI-115 = dBm
91#define RSSI_FOR_MID_TX_POWER -55 // -55 db is considered mid-distance
92#define RSSI_FOR_LOW_TX_POWER -45 // -45 db is considered very short distance and
93 // eligible to use a lower TX power
94#define RSSI_FOR_LOWEST_TX_POWER -30
95//#define MID_TX_POWER_DELTA 0 // 0 db from full TX power upon mid-distance to AP
96#define LOW_TX_POWER_DELTA 6 // -3 db from full TX power upon very short distance. 1 grade is 0.5 db
97#define LOWEST_TX_POWER_DELTA 16 // -8 db from full TX power upon shortest distance. 1 grade is 0.5 db
98
99#define RSSI_TRIGGERED_UPON_BELOW_THRESHOLD 0
100#define RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD 1
101#define RSSI_THRESHOLD_FOR_ROAMING 25
102#define RSSI_DELTA 5
103
104// Channel Quality Indication
105#define CQI_IS_GOOD(cqi) ((cqi) >= 50)
106//#define CQI_IS_FAIR(cqi) (((cqi) >= 20) && ((cqi) < 50))
107#define CQI_IS_POOR(cqi) (cqi < 50) //(((cqi) >= 5) && ((cqi) < 20))
108#define CQI_IS_BAD(cqi) (cqi < 5)
109#define CQI_IS_DEAD(cqi) (cqi == 0)
110
111// weighting factor to calculate Channel quality, total should be 100%
112#define RSSI_WEIGHTING 50
113#define TX_WEIGHTING 30
114#define RX_WEIGHTING 20
115
116#define BSS_NOT_FOUND 0xFFFFFFFF
117
118
119#ifdef CONFIG_STA_SUPPORT
120#define MAX_LEN_OF_MLME_QUEUE 40 //10
121#endif // CONFIG_STA_SUPPORT //
122
123#define SCAN_PASSIVE 18 // scan with no probe request, only wait beacon and probe response
124#define SCAN_ACTIVE 19 // scan with probe request, and wait beacon and probe response
125#define SCAN_CISCO_PASSIVE 20 // Single channel passive scan
126#define SCAN_CISCO_ACTIVE 21 // Single channel active scan
127#define SCAN_CISCO_NOISE 22 // Single channel passive scan for noise histogram collection
128#define SCAN_CISCO_CHANNEL_LOAD 23 // Single channel passive scan for channel load collection
129#define FAST_SCAN_ACTIVE 24 // scan with probe request, and wait beacon and probe response
130
131#ifdef DOT11N_DRAFT3
132#define SCAN_2040_BSS_COEXIST 26
133#endif // DOT11N_DRAFT3 //
134
135#define MAC_ADDR_IS_GROUP(Addr) (((Addr[0]) & 0x01))
136#define MAC_ADDR_HASH(Addr) (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
137#define MAC_ADDR_HASH_INDEX(Addr) (MAC_ADDR_HASH(Addr) % HASH_TABLE_SIZE)
138#define TID_MAC_HASH(Addr,TID) (TID^Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
139#define TID_MAC_HASH_INDEX(Addr,TID) (TID_MAC_HASH(Addr,TID) % HASH_TABLE_SIZE)
140
141// LED Control
142// assoiation ON. one LED ON. another blinking when TX, OFF when idle
143// no association, both LED off
144#define ASIC_LED_ACT_ON(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00031e46)
145#define ASIC_LED_ACT_OFF(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00001e46)
146
147// bit definition of the 2-byte pBEACON->Capability field
148#define CAP_IS_ESS_ON(x) (((x) & 0x0001) != 0)
149#define CAP_IS_IBSS_ON(x) (((x) & 0x0002) != 0)
150#define CAP_IS_CF_POLLABLE_ON(x) (((x) & 0x0004) != 0)
151#define CAP_IS_CF_POLL_REQ_ON(x) (((x) & 0x0008) != 0)
152#define CAP_IS_PRIVACY_ON(x) (((x) & 0x0010) != 0)
153#define CAP_IS_SHORT_PREAMBLE_ON(x) (((x) & 0x0020) != 0)
154#define CAP_IS_PBCC_ON(x) (((x) & 0x0040) != 0)
155#define CAP_IS_AGILITY_ON(x) (((x) & 0x0080) != 0)
156#define CAP_IS_SPECTRUM_MGMT(x) (((x) & 0x0100) != 0) // 802.11e d9
157#define CAP_IS_QOS(x) (((x) & 0x0200) != 0) // 802.11e d9
158#define CAP_IS_SHORT_SLOT(x) (((x) & 0x0400) != 0)
159#define CAP_IS_APSD(x) (((x) & 0x0800) != 0) // 802.11e d9
160#define CAP_IS_IMMED_BA(x) (((x) & 0x1000) != 0) // 802.11e d9
161#define CAP_IS_DSSS_OFDM(x) (((x) & 0x2000) != 0)
162#define CAP_IS_DELAY_BA(x) (((x) & 0x4000) != 0) // 802.11e d9
163
164#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))
165
166#define ERP_IS_NON_ERP_PRESENT(x) (((x) & 0x01) != 0) // 802.11g
167#define ERP_IS_USE_PROTECTION(x) (((x) & 0x02) != 0) // 802.11g
168#define ERP_IS_USE_BARKER_PREAMBLE(x) (((x) & 0x04) != 0) // 802.11g
169
170#define DRS_TX_QUALITY_WORST_BOUND 8// 3 // just test by gary
171#define DRS_PENALTY 8
172
173#define BA_NOTUSE 2
174//BA Policy subfiled value in ADDBA frame
175#define IMMED_BA 1
176#define DELAY_BA 0
177
178// BA Initiator subfield in DELBA frame
179#define ORIGINATOR 1
180#define RECIPIENT 0
181
182// ADDBA Status Code
183#define ADDBA_RESULTCODE_SUCCESS 0
184#define ADDBA_RESULTCODE_REFUSED 37
185#define ADDBA_RESULTCODE_INVALID_PARAMETERS 38
186
187// DELBA Reason Code
188#define DELBA_REASONCODE_QSTA_LEAVING 36
189#define DELBA_REASONCODE_END_BA 37
190#define DELBA_REASONCODE_UNKNOWN_BA 38
191#define DELBA_REASONCODE_TIMEOUT 39
192
193// reset all OneSecTx counters
194#define RESET_ONE_SEC_TX_CNT(__pEntry) \
195if (((__pEntry)) != NULL) \
196{ \
197 (__pEntry)->OneSecTxRetryOkCount = 0; \
198 (__pEntry)->OneSecTxFailCount = 0; \
199 (__pEntry)->OneSecTxNoRetryOkCount = 0; \
200}
201
202//
203// 802.11 frame formats
204//
205// HT Capability INFO field in HT Cap IE .
206typedef struct PACKED {
207#ifdef RT_BIG_ENDIAN
208 USHORT LSIGTxopProSup:1;
209 USHORT Forty_Mhz_Intolerant:1;
210 USHORT PSMP:1;
211 USHORT CCKmodein40:1;
212 USHORT AMsduSize:1;
213 USHORT DelayedBA:1; //rt2860c not support
214 USHORT RxSTBC:2;
215 USHORT TxSTBC:1;
216 USHORT ShortGIfor40:1; //for40MHz
217 USHORT ShortGIfor20:1;
218 USHORT GF:1; //green field
219 USHORT MimoPs:2;//momi power safe
220 USHORT ChannelWidth:1;
221 USHORT AdvCoding:1;
222#else
223 USHORT AdvCoding:1;
224 USHORT ChannelWidth:1;
225 USHORT MimoPs:2;//momi power safe
226 USHORT GF:1; //green field
227 USHORT ShortGIfor20:1;
228 USHORT ShortGIfor40:1; //for40MHz
229 USHORT TxSTBC:1;
230 USHORT RxSTBC:2;
231 USHORT DelayedBA:1; //rt2860c not support
232 USHORT AMsduSize:1; // only support as zero
233 USHORT CCKmodein40:1;
234 USHORT PSMP:1;
235 USHORT Forty_Mhz_Intolerant:1;
236 USHORT LSIGTxopProSup:1;
237#endif /* !RT_BIG_ENDIAN */
238} HT_CAP_INFO, *PHT_CAP_INFO;
239
240// HT Capability INFO field in HT Cap IE .
241typedef struct PACKED {
242#ifdef RT_BIG_ENDIAN
243 UCHAR rsv:3;//momi power safe
244 UCHAR MpduDensity:3;
245 UCHAR MaxRAmpduFactor:2;
246#else
247 UCHAR MaxRAmpduFactor:2;
248 UCHAR MpduDensity:3;
249 UCHAR rsv:3;//momi power safe
250#endif /* !RT_BIG_ENDIAN */
251} HT_CAP_PARM, *PHT_CAP_PARM;
252
253// HT Capability INFO field in HT Cap IE .
254typedef struct PACKED {
255 UCHAR MCSSet[10];
256 UCHAR SupRate[2]; // unit : 1Mbps
257#ifdef RT_BIG_ENDIAN
258 UCHAR rsv:3;
259 UCHAR MpduDensity:1;
260 UCHAR TxStream:2;
261 UCHAR TxRxNotEqual:1;
262 UCHAR TxMCSSetDefined:1;
263#else
264 UCHAR TxMCSSetDefined:1;
265 UCHAR TxRxNotEqual:1;
266 UCHAR TxStream:2;
267 UCHAR MpduDensity:1;
268 UCHAR rsv:3;
269#endif // RT_BIG_ENDIAN //
270 UCHAR rsv3[3];
271} HT_MCS_SET, *PHT_MCS_SET;
272
273// HT Capability INFO field in HT Cap IE .
274typedef struct PACKED {
275#ifdef RT_BIG_ENDIAN
276 USHORT rsv2:4;
277 USHORT RDGSupport:1; //reverse Direction Grant support
278 USHORT PlusHTC:1; //+HTC control field support
279 USHORT MCSFeedback:2; //0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback, 1:rsv.
280 USHORT rsv:5;//momi power safe
281 USHORT TranTime:2;
282 USHORT Pco:1;
283#else
284 USHORT Pco:1;
285 USHORT TranTime:2;
286 USHORT rsv:5;//momi power safe
287 USHORT MCSFeedback:2; //0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback, 1:rsv.
288 USHORT PlusHTC:1; //+HTC control field support
289 USHORT RDGSupport:1; //reverse Direction Grant support
290 USHORT rsv2:4;
291#endif /* RT_BIG_ENDIAN */
292} EXT_HT_CAP_INFO, *PEXT_HT_CAP_INFO;
293
294// HT Beamforming field in HT Cap IE .
295typedef struct PACKED _HT_BF_CAP{
296#ifdef RT_BIG_ENDIAN
297 ULONG rsv:3;
298 ULONG ChanEstimation:2;
299 ULONG CSIRowBFSup:2;
300 ULONG ComSteerBFAntSup:2;
301 ULONG NoComSteerBFAntSup:2;
302 ULONG CSIBFAntSup:2;
303 ULONG MinGrouping:2;
304 ULONG ExpComBF:2;
305 ULONG ExpNoComBF:2;
306 ULONG ExpCSIFbk:2;
307 ULONG ExpComSteerCapable:1;
308 ULONG ExpNoComSteerCapable:1;
309 ULONG ExpCSICapable:1;
310 ULONG Calibration:2;
311 ULONG ImpTxBFCapable:1;
312 ULONG TxNDPCapable:1;
313 ULONG RxNDPCapable:1;
314 ULONG TxSoundCapable:1;
315 ULONG RxSoundCapable:1;
316 ULONG TxBFRecCapable:1;
317#else
318 ULONG TxBFRecCapable:1;
319 ULONG RxSoundCapable:1;
320 ULONG TxSoundCapable:1;
321 ULONG RxNDPCapable:1;
322 ULONG TxNDPCapable:1;
323 ULONG ImpTxBFCapable:1;
324 ULONG Calibration:2;
325 ULONG ExpCSICapable:1;
326 ULONG ExpNoComSteerCapable:1;
327 ULONG ExpComSteerCapable:1;
328 ULONG ExpCSIFbk:2;
329 ULONG ExpNoComBF:2;
330 ULONG ExpComBF:2;
331 ULONG MinGrouping:2;
332 ULONG CSIBFAntSup:2;
333 ULONG NoComSteerBFAntSup:2;
334 ULONG ComSteerBFAntSup:2;
335 ULONG CSIRowBFSup:2;
336 ULONG ChanEstimation:2;
337 ULONG rsv:3;
338#endif // RT_BIG_ENDIAN //
339} HT_BF_CAP, *PHT_BF_CAP;
340
341// HT antenna selection field in HT Cap IE .
342typedef struct PACKED _HT_AS_CAP{
343#ifdef RT_BIG_ENDIAN
344 UCHAR rsv:1;
345 UCHAR TxSoundPPDU:1;
346 UCHAR RxASel:1;
347 UCHAR AntIndFbk:1;
348 UCHAR ExpCSIFbk:1;
349 UCHAR AntIndFbkTxASEL:1;
350 UCHAR ExpCSIFbkTxASEL:1;
351 UCHAR AntSelect:1;
352#else
353 UCHAR AntSelect:1;
354 UCHAR ExpCSIFbkTxASEL:1;
355 UCHAR AntIndFbkTxASEL:1;
356 UCHAR ExpCSIFbk:1;
357 UCHAR AntIndFbk:1;
358 UCHAR RxASel:1;
359 UCHAR TxSoundPPDU:1;
360 UCHAR rsv:1;
361#endif // RT_BIG_ENDIAN //
362} HT_AS_CAP, *PHT_AS_CAP;
363
364// Draft 1.0 set IE length 26, but is extensible..
365#define SIZE_HT_CAP_IE 26
366// The structure for HT Capability IE.
367typedef struct PACKED _HT_CAPABILITY_IE{
368 HT_CAP_INFO HtCapInfo;
369 HT_CAP_PARM HtCapParm;
370// HT_MCS_SET HtMCSSet;
371 UCHAR MCSSet[16];
372 EXT_HT_CAP_INFO ExtHtCapInfo;
373 HT_BF_CAP TxBFCap; // beamforming cap. rt2860c not support beamforming.
374 HT_AS_CAP ASCap; //antenna selection.
375} HT_CAPABILITY_IE, *PHT_CAPABILITY_IE;
376
377
378// 802.11n draft3 related structure definitions.
379// 7.3.2.60
380#define dot11OBSSScanPassiveDwell 20 // in TU. min amount of time that the STA continously scans each channel when performing an active OBSS scan.
381#define dot11OBSSScanActiveDwell 10 // in TU.min amount of time that the STA continously scans each channel when performing an passive OBSS scan.
382#define dot11BSSWidthTriggerScanInterval 300 // in sec. max interval between scan operations to be performed to detect BSS channel width trigger events.
383#define dot11OBSSScanPassiveTotalPerChannel 200 // in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan.
384#define dot11OBSSScanActiveTotalPerChannel 20 //in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan
385#define dot11BSSWidthChannelTransactionDelayFactor 5 // min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maxima
386 // interval between overlapping BSS scan operations.
387#define dot11BSSScanActivityThreshold 25 // in %%, max total time that a STA may be active on the medium during a period of
388 // (dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without
389 // being obligated to perform OBSS Scan operations. default is 25(== 0.25%)
390
391typedef struct PACKED _OVERLAP_BSS_SCAN_IE{
392 USHORT ScanPassiveDwell;
393 USHORT ScanActiveDwell;
394 USHORT TriggerScanInt; // Trigger scan interval
395 USHORT PassiveTalPerChannel; // passive total per channel
396 USHORT ActiveTalPerChannel; // active total per channel
397 USHORT DelayFactor; // BSS width channel transition delay factor
398 USHORT ScanActThre; // Scan Activity threshold
399}OVERLAP_BSS_SCAN_IE, *POVERLAP_BSS_SCAN_IE;
400
401
402// 7.3.2.56. 20/40 Coexistence element used in Element ID = 72 = IE_2040_BSS_COEXIST
403typedef union PACKED _BSS_2040_COEXIST_IE{
404 struct PACKED {
405 #ifdef RT_BIG_ENDIAN
406 UCHAR rsv:5;
407 UCHAR BSS20WidthReq:1;
408 UCHAR Intolerant40:1;
409 UCHAR InfoReq:1;
410 #else
411 UCHAR InfoReq:1;
412 UCHAR Intolerant40:1; // Inter-BSS. set 1 when prohibits a receiving BSS from operating as a 20/40 Mhz BSS.
413 UCHAR BSS20WidthReq:1; // Intra-BSS set 1 when prohibits a receiving AP from operating its BSS as a 20/40MHz BSS.
414 UCHAR rsv:5;
415#endif // RT_BIG_ENDIAN //
416 } field;
417 UCHAR word;
418} BSS_2040_COEXIST_IE, *PBSS_2040_COEXIST_IE;
419
420
421typedef struct _TRIGGER_EVENTA{
422 BOOLEAN bValid;
423 UCHAR BSSID[6];
424 UCHAR RegClass; // Regulatory Class
425 USHORT Channel;
426 ULONG CDCounter; // Maintain a seperate count down counter for each Event A.
427} TRIGGER_EVENTA, *PTRIGGER_EVENTA;
428
429// 20/40 trigger event table
430// If one Event A delete or created, or if Event B is detected or not detected, STA should send 2040BSSCoexistence to AP.
431#define MAX_TRIGGER_EVENT 64
432typedef struct _TRIGGER_EVENT_TAB{
433 UCHAR EventANo;
434 TRIGGER_EVENTA EventA[MAX_TRIGGER_EVENT];
435 ULONG EventBCountDown; // Count down counter for Event B.
436} TRIGGER_EVENT_TAB, *PTRIGGER_EVENT_TAB;
437
438// 7.3.27 20/40 Bss Coexistence Mgmt capability used in extended capabilities information IE( ID = 127 = IE_EXT_CAPABILITY).
439// This is the first octet and was defined in 802.11n D3.03 and 802.11yD9.0
440typedef struct PACKED _EXT_CAP_INFO_ELEMENT{
441#ifdef RT_BIG_ENDIAN
442 UCHAR rsv2:5;
443 UCHAR ExtendChannelSwitch:1;
444 UCHAR rsv:1;
445 UCHAR BssCoexistMgmtSupport:1;
446#else
447 UCHAR BssCoexistMgmtSupport:1;
448 UCHAR rsv:1;
449 UCHAR ExtendChannelSwitch:1;
450 UCHAR rsv2:5;
451#endif // RT_BIG_ENDIAN //
452}EXT_CAP_INFO_ELEMENT, *PEXT_CAP_INFO_ELEMENT;
453
454
455// 802.11n 7.3.2.61
456typedef struct PACKED _BSS_2040_COEXIST_ELEMENT{
457 UCHAR ElementID; // ID = IE_2040_BSS_COEXIST = 72
458 UCHAR Len;
459 BSS_2040_COEXIST_IE BssCoexistIe;
460}BSS_2040_COEXIST_ELEMENT, *PBSS_2040_COEXIST_ELEMENT;
461
462
463//802.11n 7.3.2.59
464typedef struct PACKED _BSS_2040_INTOLERANT_CH_REPORT{
465 UCHAR ElementID; // ID = IE_2040_BSS_INTOLERANT_REPORT = 73
466 UCHAR Len;
467 UCHAR RegulatoryClass;
468 UCHAR ChList[0];
469}BSS_2040_INTOLERANT_CH_REPORT, *PBSS_2040_INTOLERANT_CH_REPORT;
470
471
472// The structure for channel switch annoucement IE. This is in 802.11n D3.03
473typedef struct PACKED _CHA_SWITCH_ANNOUNCE_IE{
474 UCHAR SwitchMode; //channel switch mode
475 UCHAR NewChannel; //
476 UCHAR SwitchCount; //
477} CHA_SWITCH_ANNOUNCE_IE, *PCHA_SWITCH_ANNOUNCE_IE;
478
479
480// The structure for channel switch annoucement IE. This is in 802.11n D3.03
481typedef struct PACKED _SEC_CHA_OFFSET_IE{
482 UCHAR SecondaryChannelOffset; // 1: Secondary above, 3: Secondary below, 0: no Secondary
483} SEC_CHA_OFFSET_IE, *PSEC_CHA_OFFSET_IE;
484
485
486// This structure is extracted from struct RT_HT_CAPABILITY
487typedef struct {
488 BOOLEAN bHtEnable; // If we should use ht rate.
489 BOOLEAN bPreNHt; // If we should use ht rate.
490 //Substract from HT Capability IE
491 UCHAR MCSSet[16]; //only supoort MCS=0-15,32 ,
492} RT_HT_PHY_INFO, *PRT_HT_PHY_INFO;
493
494//This structure substracts ralink supports from all 802.11n-related features.
495//Features not listed here but contained in 802.11n spec are not supported in rt2860.
496typedef struct {
497#ifdef RT_BIG_ENDIAN
498 USHORT rsv:5;
499 USHORT AmsduSize:1; // Max receiving A-MSDU size
500 USHORT AmsduEnable:1; // Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
501 USHORT RxSTBC:2; // 2 bits
502 USHORT TxSTBC:1;
503 USHORT ShortGIfor40:1; //for40MHz
504 USHORT ShortGIfor20:1;
505 USHORT GF:1; //green field
506 USHORT MimoPs:2;//mimo power safe MMPS_
507 USHORT ChannelWidth:1;
508#else
509 USHORT ChannelWidth:1;
510 USHORT MimoPs:2;//mimo power safe MMPS_
511 USHORT GF:1; //green field
512 USHORT ShortGIfor20:1;
513 USHORT ShortGIfor40:1; //for40MHz
514 USHORT TxSTBC:1;
515 USHORT RxSTBC:2; // 2 bits
516 USHORT AmsduEnable:1; // Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
517 USHORT AmsduSize:1; // Max receiving A-MSDU size
518 USHORT rsv:5;
519#endif
520
521 //Substract from Addiont HT INFO IE
522#ifdef RT_BIG_ENDIAN
523 UCHAR RecomWidth:1;
524 UCHAR ExtChanOffset:2; // Please not the difference with following UCHAR NewExtChannelOffset; from 802.11n
525 UCHAR MpduDensity:3;
526 UCHAR MaxRAmpduFactor:2;
527#else
528 UCHAR MaxRAmpduFactor:2;
529 UCHAR MpduDensity:3;
530 UCHAR ExtChanOffset:2; // Please not the difference with following UCHAR NewExtChannelOffset; from 802.11n
531 UCHAR RecomWidth:1;
532#endif
533
534#ifdef RT_BIG_ENDIAN
535 USHORT rsv2:11;
536 USHORT OBSS_NonHTExist:1;
537 USHORT rsv3:1;
538 USHORT NonGfPresent:1;
539 USHORT OperaionMode:2;
540#else
541 USHORT OperaionMode:2;
542 USHORT NonGfPresent:1;
543 USHORT rsv3:1;
544 USHORT OBSS_NonHTExist:1;
545 USHORT rsv2:11;
546#endif
547
548 // New Extension Channel Offset IE
549 UCHAR NewExtChannelOffset;
550 // Extension Capability IE = 127
551 UCHAR BSSCoexist2040;
552} RT_HT_CAPABILITY, *PRT_HT_CAPABILITY;
553
554// field in Addtional HT Information IE .
555typedef struct PACKED {
556#ifdef RT_BIG_ENDIAN
557 UCHAR SerInterGranu:3;
558 UCHAR S_PSMPSup:1;
559 UCHAR RifsMode:1;
560 UCHAR RecomWidth:1;
561 UCHAR ExtChanOffset:2;
562#else
563 UCHAR ExtChanOffset:2;
564 UCHAR RecomWidth:1;
565 UCHAR RifsMode:1;
566 UCHAR S_PSMPSup:1; //Indicate support for scheduled PSMP
567 UCHAR SerInterGranu:3; //service interval granularity
568#endif
569} ADD_HTINFO, *PADD_HTINFO;
570
571typedef struct PACKED{
572#ifdef RT_BIG_ENDIAN
573 USHORT rsv2:11;
574 USHORT OBSS_NonHTExist:1;
575 USHORT rsv:1;
576 USHORT NonGfPresent:1;
577 USHORT OperaionMode:2;
578#else
579 USHORT OperaionMode:2;
580 USHORT NonGfPresent:1;
581 USHORT rsv:1;
582 USHORT OBSS_NonHTExist:1;
583 USHORT rsv2:11;
584#endif
585} ADD_HTINFO2, *PADD_HTINFO2;
586
587
588// TODO: Need sync with spec about the definition of StbcMcs. In Draft 3.03, it's reserved.
589typedef struct PACKED{
590#ifdef RT_BIG_ENDIAN
591 USHORT rsv:4;
592 USHORT PcoPhase:1;
593 USHORT PcoActive:1;
594 USHORT LsigTxopProt:1;
595 USHORT STBCBeacon:1;
596 USHORT DualCTSProtect:1;
597 USHORT DualBeacon:1;
598 USHORT StbcMcs:6;
599#else
600 USHORT StbcMcs:6;
601 USHORT DualBeacon:1;
602 USHORT DualCTSProtect:1;
603 USHORT STBCBeacon:1;
604 USHORT LsigTxopProt:1; // L-SIG TXOP protection full support
605 USHORT PcoActive:1;
606 USHORT PcoPhase:1;
607 USHORT rsv:4;
608#endif // RT_BIG_ENDIAN //
609} ADD_HTINFO3, *PADD_HTINFO3;
610
611#define SIZE_ADD_HT_INFO_IE 22
612typedef struct PACKED{
613 UCHAR ControlChan;
614 ADD_HTINFO AddHtInfo;
615 ADD_HTINFO2 AddHtInfo2;
616 ADD_HTINFO3 AddHtInfo3;
617 UCHAR MCSSet[16]; // Basic MCS set
618} ADD_HT_INFO_IE, *PADD_HT_INFO_IE;
619
620typedef struct PACKED{
621 UCHAR NewExtChanOffset;
622} NEW_EXT_CHAN_IE, *PNEW_EXT_CHAN_IE;
623
624
625// 4-byte HTC field. maybe included in any frame except non-QOS data frame. The Order bit must set 1.
626typedef struct PACKED {
627#ifdef RT_BIG_ENDIAN
628 UINT32 RDG:1; //RDG / More PPDU
629 UINT32 ACConstraint:1; //feedback request
630 UINT32 rsv:5; //calibration sequence
631 UINT32 ZLFAnnouce:1; // ZLF announcement
632 UINT32 CSISTEERING:2; //CSI/ STEERING
633 UINT32 FBKReq:2; //feedback request
634 UINT32 CalSeq:2; //calibration sequence
635 UINT32 CalPos:2; // calibration position
636 UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
637 UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB.
638 UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
639 UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback
640 UINT32 TRQ:1; //sounding request
641 UINT32 MA:1; //management action payload exist in (QoS Null+HTC)
642#else
643 UINT32 MA:1; //management action payload exist in (QoS Null+HTC)
644 UINT32 TRQ:1; //sounding request
645 UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback
646 UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
647 UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB.
648 UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
649 UINT32 CalPos:2; // calibration position
650 UINT32 CalSeq:2; //calibration sequence
651 UINT32 FBKReq:2; //feedback request
652 UINT32 CSISTEERING:2; //CSI/ STEERING
653 UINT32 ZLFAnnouce:1; // ZLF announcement
654 UINT32 rsv:5; //calibration sequence
655 UINT32 ACConstraint:1; //feedback request
656 UINT32 RDG:1; //RDG / More PPDU
657#endif /* !RT_BIG_ENDIAN */
658} HT_CONTROL, *PHT_CONTROL;
659
660// 2-byte QOS CONTROL field
661typedef struct PACKED {
662#ifdef RT_BIG_ENDIAN
663 USHORT Txop_QueueSize:8;
664 USHORT AMsduPresent:1;
665 USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA
666 USHORT EOSP:1;
667 USHORT TID:4;
668#else
669 USHORT TID:4;
670 USHORT EOSP:1;
671 USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA
672 USHORT AMsduPresent:1;
673 USHORT Txop_QueueSize:8;
674#endif /* !RT_BIG_ENDIAN */
675} QOS_CONTROL, *PQOS_CONTROL;
676
677// 2-byte Frame control field
678typedef struct PACKED {
679#ifdef RT_BIG_ENDIAN
680 USHORT Order:1; // Strict order expected
681 USHORT Wep:1; // Wep data
682 USHORT MoreData:1; // More data bit
683 USHORT PwrMgmt:1; // Power management bit
684 USHORT Retry:1; // Retry status bit
685 USHORT MoreFrag:1; // More fragment bit
686 USHORT FrDs:1; // From DS indication
687 USHORT ToDs:1; // To DS indication
688 USHORT SubType:4; // MSDU subtype
689 USHORT Type:2; // MSDU type
690 USHORT Ver:2; // Protocol version
691#else
692 USHORT Ver:2; // Protocol version
693 USHORT Type:2; // MSDU type
694 USHORT SubType:4; // MSDU subtype
695 USHORT ToDs:1; // To DS indication
696 USHORT FrDs:1; // From DS indication
697 USHORT MoreFrag:1; // More fragment bit
698 USHORT Retry:1; // Retry status bit
699 USHORT PwrMgmt:1; // Power management bit
700 USHORT MoreData:1; // More data bit
701 USHORT Wep:1; // Wep data
702 USHORT Order:1; // Strict order expected
703#endif /* !RT_BIG_ENDIAN */
704} FRAME_CONTROL, *PFRAME_CONTROL;
705
706typedef struct PACKED _HEADER_802_11 {
707 FRAME_CONTROL FC;
708 USHORT Duration;
709 UCHAR Addr1[MAC_ADDR_LEN];
710 UCHAR Addr2[MAC_ADDR_LEN];
711 UCHAR Addr3[MAC_ADDR_LEN];
712#ifdef RT_BIG_ENDIAN
713 USHORT Sequence:12;
714 USHORT Frag:4;
715#else
716 USHORT Frag:4;
717 USHORT Sequence:12;
718#endif /* !RT_BIG_ENDIAN */
719 UCHAR Octet[0];
720} HEADER_802_11, *PHEADER_802_11;
721
722typedef struct PACKED _FRAME_802_11 {
723 HEADER_802_11 Hdr;
724 UCHAR Octet[1];
725} FRAME_802_11, *PFRAME_802_11;
726
727// QoSNull embedding of management action. When HT Control MA field set to 1.
728typedef struct PACKED _MA_BODY {
729 UCHAR Category;
730 UCHAR Action;
731 UCHAR Octet[1];
732} MA_BODY, *PMA_BODY;
733
734typedef struct PACKED _HEADER_802_3 {
735 UCHAR DAAddr1[MAC_ADDR_LEN];
736 UCHAR SAAddr2[MAC_ADDR_LEN];
737 UCHAR Octet[2];
738} HEADER_802_3, *PHEADER_802_3;
739////Block ACK related format
740// 2-byte BA Parameter field in DELBA frames to terminate an already set up bA
741typedef struct PACKED{
742#ifdef RT_BIG_ENDIAN
743 USHORT TID:4; // value of TC os TS
744 USHORT Initiator:1; // 1: originator 0:recipient
745 USHORT Rsv:11; // always set to 0
746#else
747 USHORT Rsv:11; // always set to 0
748 USHORT Initiator:1; // 1: originator 0:recipient
749 USHORT TID:4; // value of TC os TS
750#endif /* !RT_BIG_ENDIAN */
751} DELBA_PARM, *PDELBA_PARM;
752
753// 2-byte BA Parameter Set field in ADDBA frames to signal parm for setting up a BA
754typedef struct PACKED {
755#ifdef RT_BIG_ENDIAN
756 USHORT BufSize:10; // number of buffe of size 2304 octetsr
757 USHORT TID:4; // value of TC os TS
758 USHORT BAPolicy:1; // 1: immediately BA 0:delayed BA
759 USHORT AMSDUSupported:1; // 0: not permitted 1: permitted
760#else
761 USHORT AMSDUSupported:1; // 0: not permitted 1: permitted
762 USHORT BAPolicy:1; // 1: immediately BA 0:delayed BA
763 USHORT TID:4; // value of TC os TS
764 USHORT BufSize:10; // number of buffe of size 2304 octetsr
765#endif /* !RT_BIG_ENDIAN */
766} BA_PARM, *PBA_PARM;
767
768// 2-byte BA Starting Seq CONTROL field
769typedef union PACKED {
770 struct PACKED {
771#ifdef RT_BIG_ENDIAN
772 USHORT StartSeq:12; // sequence number of the 1st MSDU for which this BAR is sent
773 USHORT FragNum:4; // always set to 0
774#else
775 USHORT FragNum:4; // always set to 0
776 USHORT StartSeq:12; // sequence number of the 1st MSDU for which this BAR is sent
777#endif /* RT_BIG_ENDIAN */
778 } field;
779 USHORT word;
780} BASEQ_CONTROL, *PBASEQ_CONTROL;
781
782//BAControl and BARControl are the same
783// 2-byte BA CONTROL field in BA frame
784typedef struct PACKED {
785#ifdef RT_BIG_ENDIAN
786 USHORT TID:4;
787 USHORT Rsv:9;
788 USHORT Compressed:1;
789 USHORT MTID:1; //EWC V1.24
790 USHORT ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK
791#else
792 USHORT ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK
793 USHORT MTID:1; //EWC V1.24
794 USHORT Compressed:1;
795 USHORT Rsv:9;
796 USHORT TID:4;
797#endif /* !RT_BIG_ENDIAN */
798} BA_CONTROL, *PBA_CONTROL;
799
800// 2-byte BAR CONTROL field in BAR frame
801typedef struct PACKED {
802#ifdef RT_BIG_ENDIAN
803 USHORT TID:4;
804 USHORT Rsv1:9;
805 USHORT Compressed:1;
806 USHORT MTID:1; //if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ
807 USHORT ACKPolicy:1;
808#else
809 USHORT ACKPolicy:1; // 0:normal ack, 1:no ack.
810 USHORT MTID:1; //if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ
811 USHORT Compressed:1;
812 USHORT Rsv1:9;
813 USHORT TID:4;
814#endif /* !RT_BIG_ENDIAN */
815} BAR_CONTROL, *PBAR_CONTROL;
816
817// BARControl in MTBAR frame
818typedef struct PACKED {
819#ifdef RT_BIG_ENDIAN
820 USHORT NumTID:4;
821 USHORT Rsv1:9;
822 USHORT Compressed:1;
823 USHORT MTID:1;
824 USHORT ACKPolicy:1;
825#else
826 USHORT ACKPolicy:1;
827 USHORT MTID:1;
828 USHORT Compressed:1;
829 USHORT Rsv1:9;
830 USHORT NumTID:4;
831#endif /* !RT_BIG_ENDIAN */
832} MTBAR_CONTROL, *PMTBAR_CONTROL;
833
834typedef struct PACKED {
835#ifdef RT_BIG_ENDIAN
836 USHORT TID:4;
837 USHORT Rsv1:12;
838#else
839 USHORT Rsv1:12;
840 USHORT TID:4;
841#endif /* !RT_BIG_ENDIAN */
842} PER_TID_INFO, *PPER_TID_INFO;
843
844typedef struct {
845 PER_TID_INFO PerTID;
846 BASEQ_CONTROL BAStartingSeq;
847} EACH_TID, *PEACH_TID;
848
849
850typedef struct PACKED _PSPOLL_FRAME {
851 FRAME_CONTROL FC;
852 USHORT Aid;
853 UCHAR Bssid[MAC_ADDR_LEN];
854 UCHAR Ta[MAC_ADDR_LEN];
855} PSPOLL_FRAME, *PPSPOLL_FRAME;
856
857typedef struct PACKED _RTS_FRAME {
858 FRAME_CONTROL FC;
859 USHORT Duration;
860 UCHAR Addr1[MAC_ADDR_LEN];
861 UCHAR Addr2[MAC_ADDR_LEN];
862}RTS_FRAME, *PRTS_FRAME;
863
864// BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap.
865typedef struct PACKED _FRAME_BA_REQ {
866 FRAME_CONTROL FC;
867 USHORT Duration;
868 UCHAR Addr1[MAC_ADDR_LEN];
869 UCHAR Addr2[MAC_ADDR_LEN];
870 BAR_CONTROL BARControl;
871 BASEQ_CONTROL BAStartingSeq;
872} FRAME_BA_REQ, *PFRAME_BA_REQ;
873
874typedef struct PACKED _FRAME_MTBA_REQ {
875 FRAME_CONTROL FC;
876 USHORT Duration;
877 UCHAR Addr1[MAC_ADDR_LEN];
878 UCHAR Addr2[MAC_ADDR_LEN];
879 MTBAR_CONTROL MTBARControl;
880 PER_TID_INFO PerTIDInfo;
881 BASEQ_CONTROL BAStartingSeq;
882} FRAME_MTBA_REQ, *PFRAME_MTBA_REQ;
883
884// Compressed format is mandantory in HT STA
885typedef struct PACKED _FRAME_MTBA {
886 FRAME_CONTROL FC;
887 USHORT Duration;
888 UCHAR Addr1[MAC_ADDR_LEN];
889 UCHAR Addr2[MAC_ADDR_LEN];
890 BA_CONTROL BAControl;
891 BASEQ_CONTROL BAStartingSeq;
892 UCHAR BitMap[8];
893} FRAME_MTBA, *PFRAME_MTBA;
894
895typedef struct PACKED _FRAME_PSMP_ACTION {
896 HEADER_802_11 Hdr;
897 UCHAR Category;
898 UCHAR Action;
899 UCHAR Psmp; // 7.3.1.25
900} FRAME_PSMP_ACTION, *PFRAME_PSMP_ACTION;
901
902typedef struct PACKED _FRAME_ACTION_HDR {
903 HEADER_802_11 Hdr;
904 UCHAR Category;
905 UCHAR Action;
906} FRAME_ACTION_HDR, *PFRAME_ACTION_HDR;
907
908//Action Frame
909//Action Frame Category:Spectrum, Action:Channel Switch. 7.3.2.20
910typedef struct PACKED _CHAN_SWITCH_ANNOUNCE {
911 UCHAR ElementID; // ID = IE_CHANNEL_SWITCH_ANNOUNCEMENT = 37
912 UCHAR Len;
913 CHA_SWITCH_ANNOUNCE_IE CSAnnounceIe;
914} CHAN_SWITCH_ANNOUNCE, *PCHAN_SWITCH_ANNOUNCE;
915
916
917//802.11n : 7.3.2.20a
918typedef struct PACKED _SECOND_CHAN_OFFSET {
919 UCHAR ElementID; // ID = IE_SECONDARY_CH_OFFSET = 62
920 UCHAR Len;
921 SEC_CHA_OFFSET_IE SecChOffsetIe;
922} SECOND_CHAN_OFFSET, *PSECOND_CHAN_OFFSET;
923
924
925typedef struct PACKED _FRAME_SPETRUM_CS {
926 HEADER_802_11 Hdr;
927 UCHAR Category;
928 UCHAR Action;
929 CHAN_SWITCH_ANNOUNCE CSAnnounce;
930 SECOND_CHAN_OFFSET SecondChannel;
931} FRAME_SPETRUM_CS, *PFRAME_SPETRUM_CS;
932
933
934typedef struct PACKED _FRAME_ADDBA_REQ {
935 HEADER_802_11 Hdr;
936 UCHAR Category;
937 UCHAR Action;
938 UCHAR Token; // 1
939 BA_PARM BaParm; // 2 - 10
940 USHORT TimeOutValue; // 0 - 0
941 BASEQ_CONTROL BaStartSeq; // 0-0
942} FRAME_ADDBA_REQ, *PFRAME_ADDBA_REQ;
943
944typedef struct PACKED _FRAME_ADDBA_RSP {
945 HEADER_802_11 Hdr;
946 UCHAR Category;
947 UCHAR Action;
948 UCHAR Token;
949 USHORT StatusCode;
950 BA_PARM BaParm; //0 - 2
951 USHORT TimeOutValue;
952} FRAME_ADDBA_RSP, *PFRAME_ADDBA_RSP;
953
954typedef struct PACKED _FRAME_DELBA_REQ {
955 HEADER_802_11 Hdr;
956 UCHAR Category;
957 UCHAR Action;
958 DELBA_PARM DelbaParm;
959 USHORT ReasonCode;
960} FRAME_DELBA_REQ, *PFRAME_DELBA_REQ;
961
962
963//7.2.1.7
964typedef struct PACKED _FRAME_BAR {
965 FRAME_CONTROL FC;
966 USHORT Duration;
967 UCHAR Addr1[MAC_ADDR_LEN];
968 UCHAR Addr2[MAC_ADDR_LEN];
969 BAR_CONTROL BarControl;
970 BASEQ_CONTROL StartingSeq;
971} FRAME_BAR, *PFRAME_BAR;
972
973//7.2.1.7
974typedef struct PACKED _FRAME_BA {
975 FRAME_CONTROL FC;
976 USHORT Duration;
977 UCHAR Addr1[MAC_ADDR_LEN];
978 UCHAR Addr2[MAC_ADDR_LEN];
979 BAR_CONTROL BarControl;
980 BASEQ_CONTROL StartingSeq;
981 UCHAR bitmask[8];
982} FRAME_BA, *PFRAME_BA;
983
984
985// Radio Measuement Request Frame Format
986typedef struct PACKED _FRAME_RM_REQ_ACTION {
987 HEADER_802_11 Hdr;
988 UCHAR Category;
989 UCHAR Action;
990 UCHAR Token;
991 USHORT Repetition;
992 UCHAR data[0];
993} FRAME_RM_REQ_ACTION, *PFRAME_RM_REQ_ACTION;
994
995typedef struct PACKED {
996 UCHAR ID;
997 UCHAR Length;
998 UCHAR ChannelSwitchMode;
999 UCHAR NewRegClass;
1000 UCHAR NewChannelNum;
1001 UCHAR ChannelSwitchCount;
1002} HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE, *PHT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE;
1003
1004
1005//
1006// _Limit must be the 2**n - 1
1007// _SEQ1 , _SEQ2 must be within 0 ~ _Limit
1008//
1009#define SEQ_STEPONE(_SEQ1, _SEQ2, _Limit) ((_SEQ1 == ((_SEQ2+1) & _Limit)))
1010#define SEQ_SMALLER(_SEQ1, _SEQ2, _Limit) (((_SEQ1-_SEQ2) & ((_Limit+1)>>1)))
1011#define SEQ_LARGER(_SEQ1, _SEQ2, _Limit) ((_SEQ1 != _SEQ2) && !(((_SEQ1-_SEQ2) & ((_Limit+1)>>1))))
1012#define SEQ_WITHIN_WIN(_SEQ1, _SEQ2, _WIN, _Limit) (SEQ_LARGER(_SEQ1, _SEQ2, _Limit) && \
1013 SEQ_SMALLER(_SEQ1, ((_SEQ2+_WIN+1)&_Limit), _Limit))
1014
1015//
1016// Contention-free parameter (without ID and Length)
1017//
1018typedef struct PACKED {
1019 BOOLEAN bValid; // 1: variable contains valid value
1020 UCHAR CfpCount;
1021 UCHAR CfpPeriod;
1022 USHORT CfpMaxDuration;
1023 USHORT CfpDurRemaining;
1024} CF_PARM, *PCF_PARM;
1025
1026typedef struct _CIPHER_SUITE {
1027 NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher 1, this one has more secured cipher suite
1028 NDIS_802_11_ENCRYPTION_STATUS PairCipherAux; // Unicast cipher 2 if AP announce two unicast cipher suite
1029 NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Group cipher
1030 USHORT RsnCapability; // RSN capability from beacon
1031 BOOLEAN bMixMode; // Indicate Pair & Group cipher might be different
1032} CIPHER_SUITE, *PCIPHER_SUITE;
1033
1034// EDCA configuration from AP's BEACON/ProbeRsp
1035typedef struct {
1036 BOOLEAN bValid; // 1: variable contains valid value
1037 BOOLEAN bAdd; // 1: variable contains valid value
1038 BOOLEAN bQAck;
1039 BOOLEAN bQueueRequest;
1040 BOOLEAN bTxopRequest;
1041 BOOLEAN bAPSDCapable;
1042// BOOLEAN bMoreDataAck;
1043 UCHAR EdcaUpdateCount;
1044 UCHAR Aifsn[4]; // 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO
1045 UCHAR Cwmin[4];
1046 UCHAR Cwmax[4];
1047 USHORT Txop[4]; // in unit of 32-us
1048 BOOLEAN bACM[4]; // 1: Admission Control of AC_BK is mandattory
1049} EDCA_PARM, *PEDCA_PARM;
1050
1051// QBSS LOAD information from QAP's BEACON/ProbeRsp
1052typedef struct {
1053 BOOLEAN bValid; // 1: variable contains valid value
1054 USHORT StaNum;
1055 UCHAR ChannelUtilization;
1056 USHORT RemainingAdmissionControl; // in unit of 32-us
1057} QBSS_LOAD_PARM, *PQBSS_LOAD_PARM;
1058
1059// QBSS Info field in QSTA's assoc req
1060typedef struct PACKED {
1061#ifdef RT_BIG_ENDIAN
1062 UCHAR Rsv2:1;
1063 UCHAR MaxSPLength:2;
1064 UCHAR Rsv1:1;
1065 UCHAR UAPSD_AC_BE:1;
1066 UCHAR UAPSD_AC_BK:1;
1067 UCHAR UAPSD_AC_VI:1;
1068 UCHAR UAPSD_AC_VO:1;
1069#else
1070 UCHAR UAPSD_AC_VO:1;
1071 UCHAR UAPSD_AC_VI:1;
1072 UCHAR UAPSD_AC_BK:1;
1073 UCHAR UAPSD_AC_BE:1;
1074 UCHAR Rsv1:1;
1075 UCHAR MaxSPLength:2;
1076 UCHAR Rsv2:1;
1077#endif /* !RT_BIG_ENDIAN */
1078} QBSS_STA_INFO_PARM, *PQBSS_STA_INFO_PARM;
1079
1080// QBSS Info field in QAP's Beacon/ProbeRsp
1081typedef struct PACKED {
1082#ifdef RT_BIG_ENDIAN
1083 UCHAR UAPSD:1;
1084 UCHAR Rsv:3;
1085 UCHAR ParamSetCount:4;
1086#else
1087 UCHAR ParamSetCount:4;
1088 UCHAR Rsv:3;
1089 UCHAR UAPSD:1;
1090#endif /* !RT_BIG_ENDIAN */
1091} QBSS_AP_INFO_PARM, *PQBSS_AP_INFO_PARM;
1092
1093// QOS Capability reported in QAP's BEACON/ProbeRsp
1094// QOS Capability sent out in QSTA's AssociateReq/ReAssociateReq
1095typedef struct {
1096 BOOLEAN bValid; // 1: variable contains valid value
1097 BOOLEAN bQAck;
1098 BOOLEAN bQueueRequest;
1099 BOOLEAN bTxopRequest;
1100// BOOLEAN bMoreDataAck;
1101 UCHAR EdcaUpdateCount;
1102} QOS_CAPABILITY_PARM, *PQOS_CAPABILITY_PARM;
1103
1104#ifdef CONFIG_STA_SUPPORT
1105typedef struct {
1106 UCHAR IELen;
1107 UCHAR IE[MAX_CUSTOM_LEN];
1108} WPA_IE_;
1109#endif // CONFIG_STA_SUPPORT //
1110
1111
1112typedef struct {
1113 UCHAR Bssid[MAC_ADDR_LEN];
1114 UCHAR Channel;
1115 UCHAR CentralChannel; //Store the wide-band central channel for 40MHz. .used in 40MHz AP. Or this is the same as Channel.
1116 UCHAR BssType;
1117 USHORT AtimWin;
1118 USHORT BeaconPeriod;
1119
1120 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
1121 UCHAR SupRateLen;
1122 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1123 UCHAR ExtRateLen;
1124 HT_CAPABILITY_IE HtCapability;
1125 UCHAR HtCapabilityLen;
1126 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1127 UCHAR AddHtInfoLen;
1128 UCHAR NewExtChanOffset;
1129 CHAR Rssi;
1130 UCHAR Privacy; // Indicate security function ON/OFF. Don't mess up with auth mode.
1131 UCHAR Hidden;
1132
1133 USHORT DtimPeriod;
1134 USHORT CapabilityInfo;
1135
1136 USHORT CfpCount;
1137 USHORT CfpPeriod;
1138 USHORT CfpMaxDuration;
1139 USHORT CfpDurRemaining;
1140 UCHAR SsidLen;
1141 CHAR Ssid[MAX_LEN_OF_SSID];
1142
1143 ULONG LastBeaconRxTime; // OS's timestamp
1144
1145 BOOLEAN bSES;
1146
1147 // New for WPA2
1148 CIPHER_SUITE WPA; // AP announced WPA cipher suite
1149 CIPHER_SUITE WPA2; // AP announced WPA2 cipher suite
1150
1151 // New for microsoft WPA support
1152 NDIS_802_11_FIXED_IEs FixIEs;
1153 NDIS_802_11_AUTHENTICATION_MODE AuthModeAux; // Addition mode for WPA2 / WPA capable AP
1154 NDIS_802_11_AUTHENTICATION_MODE AuthMode;
1155 NDIS_802_11_WEP_STATUS WepStatus; // Unicast Encryption Algorithm extract from VAR_IE
1156 USHORT VarIELen; // Length of next VIE include EID & Length
1157 UCHAR VarIEs[MAX_VIE_LEN];
1158
1159 // CCX Ckip information
1160 UCHAR CkipFlag;
1161
1162 // CCX 2 TSF
1163 UCHAR PTSF[4]; // Parent TSF
1164 UCHAR TTSF[8]; // Target TSF
1165
1166 // 802.11e d9, and WMM
1167 EDCA_PARM EdcaParm;
1168 QOS_CAPABILITY_PARM QosCapability;
1169 QBSS_LOAD_PARM QbssLoad;
1170#ifdef CONFIG_STA_SUPPORT
1171 WPA_IE_ WpaIE;
1172 WPA_IE_ RsnIE;
1173#ifdef EXT_BUILD_CHANNEL_LIST
1174 UCHAR CountryString[3];
1175 BOOLEAN bHasCountryIE;
1176#endif // EXT_BUILD_CHANNEL_LIST //
1177#endif // CONFIG_STA_SUPPORT //
1178} BSS_ENTRY, *PBSS_ENTRY;
1179
1180typedef struct {
1181 UCHAR BssNr;
1182 UCHAR BssOverlapNr;
1183 BSS_ENTRY BssEntry[MAX_LEN_OF_BSS_TABLE];
1184} BSS_TABLE, *PBSS_TABLE;
1185
1186
1187typedef struct _MLME_QUEUE_ELEM {
1188 ULONG Machine;
1189 ULONG MsgType;
1190 ULONG MsgLen;
1191 UCHAR Msg[MGMT_DMA_BUFFER_SIZE];
1192 LARGE_INTEGER TimeStamp;
1193 UCHAR Rssi0;
1194 UCHAR Rssi1;
1195 UCHAR Rssi2;
1196 UCHAR Signal;
1197 UCHAR Channel;
1198 UCHAR Wcid;
1199 BOOLEAN Occupied;
1200} MLME_QUEUE_ELEM, *PMLME_QUEUE_ELEM;
1201
1202typedef struct _MLME_QUEUE {
1203 ULONG Num;
1204 ULONG Head;
1205 ULONG Tail;
1206 NDIS_SPIN_LOCK Lock;
1207 MLME_QUEUE_ELEM Entry[MAX_LEN_OF_MLME_QUEUE];
1208} MLME_QUEUE, *PMLME_QUEUE;
1209
1210typedef VOID (*STATE_MACHINE_FUNC)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem);
1211
1212typedef struct _STATE_MACHINE {
1213 ULONG Base;
1214 ULONG NrState;
1215 ULONG NrMsg;
1216 ULONG CurrState;
1217 STATE_MACHINE_FUNC *TransFunc;
1218} STATE_MACHINE, *PSTATE_MACHINE;
1219
1220
1221// MLME AUX data structure that hold temporarliy settings during a connection attempt.
1222// Once this attemp succeeds, all settings will be copy to pAd->StaActive.
1223// A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of
1224// several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely
1225// separate this under-trial settings away from pAd->StaActive so that once
1226// this new attempt failed, driver can auto-recover back to the active settings.
1227typedef struct _MLME_AUX {
1228 UCHAR BssType;
1229 UCHAR Ssid[MAX_LEN_OF_SSID];
1230 UCHAR SsidLen;
1231 UCHAR Bssid[MAC_ADDR_LEN];
1232 UCHAR AutoReconnectSsid[MAX_LEN_OF_SSID];
1233 UCHAR AutoReconnectSsidLen;
1234 USHORT Alg;
1235 UCHAR ScanType;
1236 UCHAR Channel;
1237 UCHAR CentralChannel;
1238 USHORT Aid;
1239 USHORT CapabilityInfo;
1240 USHORT BeaconPeriod;
1241 USHORT CfpMaxDuration;
1242 USHORT CfpPeriod;
1243 USHORT AtimWin;
1244
1245 // Copy supported rate from desired AP's beacon. We are trying to match
1246 // AP's supported and extended rate settings.
1247 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
1248 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1249 UCHAR SupRateLen;
1250 UCHAR ExtRateLen;
1251 HT_CAPABILITY_IE HtCapability;
1252 UCHAR HtCapabilityLen;
1253 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1254 UCHAR NewExtChannelOffset;
1255 //RT_HT_CAPABILITY SupportedHtPhy;
1256
1257 // new for QOS
1258 QOS_CAPABILITY_PARM APQosCapability; // QOS capability of the current associated AP
1259 EDCA_PARM APEdcaParm; // EDCA parameters of the current associated AP
1260 QBSS_LOAD_PARM APQbssLoad; // QBSS load of the current associated AP
1261
1262 // new to keep Ralink specific feature
1263 ULONG APRalinkIe;
1264
1265 BSS_TABLE SsidBssTab; // AP list for the same SSID
1266 BSS_TABLE RoamTab; // AP list eligible for roaming
1267 ULONG BssIdx;
1268 ULONG RoamIdx;
1269
1270 BOOLEAN CurrReqIsFromNdis;
1271
1272 RALINK_TIMER_STRUCT BeaconTimer, ScanTimer;
1273 RALINK_TIMER_STRUCT AuthTimer;
1274 RALINK_TIMER_STRUCT AssocTimer, ReassocTimer, DisassocTimer;
1275} MLME_AUX, *PMLME_AUX;
1276
1277typedef struct _MLME_ADDBA_REQ_STRUCT{
1278 UCHAR Wcid; //
1279 UCHAR pAddr[MAC_ADDR_LEN];
1280 UCHAR BaBufSize;
1281 USHORT TimeOutValue;
1282 UCHAR TID;
1283 UCHAR Token;
1284 USHORT BaStartSeq;
1285} MLME_ADDBA_REQ_STRUCT, *PMLME_ADDBA_REQ_STRUCT;
1286
1287
1288typedef struct _MLME_DELBA_REQ_STRUCT{
1289 UCHAR Wcid; //
1290 UCHAR Addr[MAC_ADDR_LEN];
1291 UCHAR TID;
1292 UCHAR Initiator;
1293} MLME_DELBA_REQ_STRUCT, *PMLME_DELBA_REQ_STRUCT;
1294
1295// assoc struct is equal to reassoc
1296typedef struct _MLME_ASSOC_REQ_STRUCT{
1297 UCHAR Addr[MAC_ADDR_LEN];
1298 USHORT CapabilityInfo;
1299 USHORT ListenIntv;
1300 ULONG Timeout;
1301} MLME_ASSOC_REQ_STRUCT, *PMLME_ASSOC_REQ_STRUCT, MLME_REASSOC_REQ_STRUCT, *PMLME_REASSOC_REQ_STRUCT;
1302
1303typedef struct _MLME_DISASSOC_REQ_STRUCT{
1304 UCHAR Addr[MAC_ADDR_LEN];
1305 USHORT Reason;
1306} MLME_DISASSOC_REQ_STRUCT, *PMLME_DISASSOC_REQ_STRUCT;
1307
1308typedef struct _MLME_AUTH_REQ_STRUCT {
1309 UCHAR Addr[MAC_ADDR_LEN];
1310 USHORT Alg;
1311 ULONG Timeout;
1312} MLME_AUTH_REQ_STRUCT, *PMLME_AUTH_REQ_STRUCT;
1313
1314typedef struct _MLME_DEAUTH_REQ_STRUCT {
1315 UCHAR Addr[MAC_ADDR_LEN];
1316 USHORT Reason;
1317} MLME_DEAUTH_REQ_STRUCT, *PMLME_DEAUTH_REQ_STRUCT;
1318
1319typedef struct {
1320 ULONG BssIdx;
1321} MLME_JOIN_REQ_STRUCT;
1322
1323typedef struct _MLME_SCAN_REQ_STRUCT {
1324 UCHAR Bssid[MAC_ADDR_LEN];
1325 UCHAR BssType;
1326 UCHAR ScanType;
1327 UCHAR SsidLen;
1328 CHAR Ssid[MAX_LEN_OF_SSID];
1329} MLME_SCAN_REQ_STRUCT, *PMLME_SCAN_REQ_STRUCT;
1330
1331typedef struct _MLME_START_REQ_STRUCT {
1332 CHAR Ssid[MAX_LEN_OF_SSID];
1333 UCHAR SsidLen;
1334} MLME_START_REQ_STRUCT, *PMLME_START_REQ_STRUCT;
1335
1336#ifdef CONFIG_STA_SUPPORT
1337#ifdef QOS_DLS_SUPPORT
1338// structure for DLS
1339typedef struct _RT_802_11_DLS {
1340 USHORT TimeOut; // Use to time out while slience, unit: second , set by UI
1341 USHORT CountDownTimer; // Use to time out while slience,unit: second , used by driver only
1342 NDIS_802_11_MAC_ADDRESS MacAddr; // set by UI
1343 UCHAR Status; // 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
1344 BOOLEAN Valid; // 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
1345 RALINK_TIMER_STRUCT Timer; // Use to time out while handshake
1346 USHORT Sequence;
1347 USHORT MacTabMatchWCID; // ASIC
1348 BOOLEAN bHTCap;
1349 PVOID pAd;
1350} RT_802_11_DLS, *PRT_802_11_DLS;
1351
1352typedef struct _MLME_DLS_REQ_STRUCT {
1353 PRT_802_11_DLS pDLS;
1354 USHORT Reason;
1355} MLME_DLS_REQ_STRUCT, *PMLME_DLS_REQ_STRUCT;
1356#endif // QOS_DLS_SUPPORT //
1357#endif // CONFIG_STA_SUPPORT //
1358
1359typedef struct PACKED {
1360 UCHAR Eid;
1361 UCHAR Len;
1362 CHAR Octet[1];
1363} EID_STRUCT,*PEID_STRUCT, BEACON_EID_STRUCT, *PBEACON_EID_STRUCT;
1364
1365typedef struct PACKED _RTMP_TX_RATE_SWITCH
1366{
1367 UCHAR ItemNo;
1368#ifdef RT_BIG_ENDIAN
1369 UCHAR Rsv2:2;
1370 UCHAR Mode:2;
1371 UCHAR Rsv1:1;
1372 UCHAR BW:1;
1373 UCHAR ShortGI:1;
1374 UCHAR STBC:1;
1375#else
1376 UCHAR STBC:1;
1377 UCHAR ShortGI:1;
1378 UCHAR BW:1;
1379 UCHAR Rsv1:1;
1380 UCHAR Mode:2;
1381 UCHAR Rsv2:2;
1382#endif
1383 UCHAR CurrMCS;
1384 UCHAR TrainUp;
1385 UCHAR TrainDown;
1386} RRTMP_TX_RATE_SWITCH, *PRTMP_TX_RATE_SWITCH;
1387
1388// ========================== AP mlme.h ===============================
1389#define TBTT_PRELOAD_TIME 384 // usec. LomgPreamble + 24-byte at 1Mbps
1390#define DEFAULT_DTIM_PERIOD 1
1391
1392#define MAC_TABLE_AGEOUT_TIME 300 // unit: sec
1393#define MAC_TABLE_ASSOC_TIMEOUT 5 // unit: sec
1394#define MAC_TABLE_FULL(Tab) ((Tab).size == MAX_LEN_OF_MAC_TABLE)
1395
1396// AP shall drop the sta if contine Tx fail count reach it.
1397#define MAC_ENTRY_LIFE_CHECK_CNT 20 // packet cnt.
1398
1399// Value domain of pMacEntry->Sst
1400typedef enum _Sst {
1401 SST_NOT_AUTH, // 0: equivalent to IEEE 802.11/1999 state 1
1402 SST_AUTH, // 1: equivalent to IEEE 802.11/1999 state 2
1403 SST_ASSOC // 2: equivalent to IEEE 802.11/1999 state 3
1404} SST;
1405
1406// value domain of pMacEntry->AuthState
1407typedef enum _AuthState {
1408 AS_NOT_AUTH,
1409 AS_AUTH_OPEN, // STA has been authenticated using OPEN SYSTEM
1410 AS_AUTH_KEY, // STA has been authenticated using SHARED KEY
1411 AS_AUTHENTICATING // STA is waiting for AUTH seq#3 using SHARED KEY
1412} AUTH_STATE;
1413
1414//for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
1415typedef enum _ApWpaState {
1416 AS_NOTUSE, // 0
1417 AS_DISCONNECT, // 1
1418 AS_DISCONNECTED, // 2
1419 AS_INITIALIZE, // 3
1420 AS_AUTHENTICATION, // 4
1421 AS_AUTHENTICATION2, // 5
1422 AS_INITPMK, // 6
1423 AS_INITPSK, // 7
1424 AS_PTKSTART, // 8
1425 AS_PTKINIT_NEGOTIATING, // 9
1426 AS_PTKINITDONE, // 10
1427 AS_UPDATEKEYS, // 11
1428 AS_INTEGRITY_FAILURE, // 12
1429 AS_KEYUPDATE, // 13
1430} AP_WPA_STATE;
1431
1432// for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
1433typedef enum _GTKState {
1434 REKEY_NEGOTIATING,
1435 REKEY_ESTABLISHED,
1436 KEYERROR,
1437} GTK_STATE;
1438
1439// for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
1440typedef enum _WpaGTKState {
1441 SETKEYS,
1442 SETKEYS_DONE,
1443} WPA_GTK_STATE;
1444// ====================== end of AP mlme.h ============================
1445
1446
1447#endif // MLME_H__
diff --git a/drivers/staging/rt2860/oid.h b/drivers/staging/rt2860/oid.h
new file mode 100644
index 00000000000..f2f91b607c4
--- /dev/null
+++ b/drivers/staging/rt2860/oid.h
@@ -0,0 +1,995 @@
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
41#define TRUE 1
42#define FALSE 0
43//
44// IEEE 802.11 Structures and definitions
45//
46#define MAX_TX_POWER_LEVEL 100 /* mW */
47#define MAX_RSSI_TRIGGER -10 /* dBm */
48#define MIN_RSSI_TRIGGER -200 /* dBm */
49#define MAX_FRAG_THRESHOLD 2346 /* byte count */
50#define MIN_FRAG_THRESHOLD 256 /* byte count */
51#define MAX_RTS_THRESHOLD 2347 /* byte count */
52
53// new types for Media Specific Indications
54// Extension channel offset
55#define EXTCHA_NONE 0
56#define EXTCHA_ABOVE 0x1
57#define EXTCHA_BELOW 0x3
58
59// BW
60#define BAND_WIDTH_20 0
61#define BAND_WIDTH_40 1
62#define BAND_WIDTH_BOTH 2
63#define BAND_WIDTH_10 3 // 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
64// SHORTGI
65#define GAP_INTERVAL_400 1 // only support in HT mode
66#define GAP_INTERVAL_800 0
67#define GAP_INTERVAL_BOTH 2
68
69#define NdisMediaStateConnected 1
70#define NdisMediaStateDisconnected 0
71
72#define NDIS_802_11_LENGTH_SSID 32
73#define NDIS_802_11_LENGTH_RATES 8
74#define NDIS_802_11_LENGTH_RATES_EX 16
75#define MAC_ADDR_LENGTH 6
76#define MAX_NUM_OF_CHS 49 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc
77#define MAX_NUMBER_OF_EVENT 10 // entry # in EVENT table
78#define MAX_NUMBER_OF_MAC 32 // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
79#define MAX_NUMBER_OF_ACL 64
80#define MAX_LENGTH_OF_SUPPORT_RATES 12 // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
81#define MAX_NUMBER_OF_DLS_ENTRY 4
82
83#ifndef UNDER_CE
84
85#define OID_GEN_MACHINE_NAME 0x0001021A
86
87#ifdef RALINK_ATE
88#define RT_QUERY_ATE_TXDONE_COUNT 0x0401
89#endif // RALINK_ATE //
90#define RT_QUERY_SIGNAL_CONTEXT 0x0402
91#define RT_SET_IAPP_PID 0x0404
92#define RT_SET_APD_PID 0x0405
93#define RT_SET_DEL_MAC_ENTRY 0x0406
94
95//
96// IEEE 802.11 OIDs
97//
98#define OID_GET_SET_TOGGLE 0x8000
99
100#define OID_802_11_NETWORK_TYPES_SUPPORTED 0x0103
101#define OID_802_11_NETWORK_TYPE_IN_USE 0x0104
102#define OID_802_11_RSSI_TRIGGER 0x0107
103#define RT_OID_802_11_RSSI 0x0108 //rt2860 only , kathy
104#define RT_OID_802_11_RSSI_1 0x0109 //rt2860 only , kathy
105#define RT_OID_802_11_RSSI_2 0x010A //rt2860 only , kathy
106#define OID_802_11_NUMBER_OF_ANTENNAS 0x010B
107#define OID_802_11_RX_ANTENNA_SELECTED 0x010C
108#define OID_802_11_TX_ANTENNA_SELECTED 0x010D
109#define OID_802_11_SUPPORTED_RATES 0x010E
110#define OID_802_11_ADD_WEP 0x0112
111#define OID_802_11_REMOVE_WEP 0x0113
112#define OID_802_11_DISASSOCIATE 0x0114
113#define OID_802_11_PRIVACY_FILTER 0x0118
114#define OID_802_11_ASSOCIATION_INFORMATION 0x011E
115#define OID_802_11_TEST 0x011F
116#define RT_OID_802_11_COUNTRY_REGION 0x0507
117#define OID_802_11_BSSID_LIST_SCAN 0x0508
118#define OID_802_11_SSID 0x0509
119#define OID_802_11_BSSID 0x050A
120#define RT_OID_802_11_RADIO 0x050B
121#define RT_OID_802_11_PHY_MODE 0x050C
122#define RT_OID_802_11_STA_CONFIG 0x050D
123#define OID_802_11_DESIRED_RATES 0x050E
124#define RT_OID_802_11_PREAMBLE 0x050F
125#define OID_802_11_WEP_STATUS 0x0510
126#define OID_802_11_AUTHENTICATION_MODE 0x0511
127#define OID_802_11_INFRASTRUCTURE_MODE 0x0512
128#define RT_OID_802_11_RESET_COUNTERS 0x0513
129#define OID_802_11_RTS_THRESHOLD 0x0514
130#define OID_802_11_FRAGMENTATION_THRESHOLD 0x0515
131#define OID_802_11_POWER_MODE 0x0516
132#define OID_802_11_TX_POWER_LEVEL 0x0517
133#define RT_OID_802_11_ADD_WPA 0x0518
134#define OID_802_11_REMOVE_KEY 0x0519
135#define OID_802_11_ADD_KEY 0x0520
136#define OID_802_11_CONFIGURATION 0x0521
137#define OID_802_11_TX_PACKET_BURST 0x0522
138#define RT_OID_802_11_QUERY_NOISE_LEVEL 0x0523
139#define RT_OID_802_11_EXTRA_INFO 0x0524
140#ifdef DBG
141#define RT_OID_802_11_HARDWARE_REGISTER 0x0525
142#endif
143#define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS
144#define OID_802_11_DEAUTHENTICATION 0x0526
145#define OID_802_11_DROP_UNENCRYPTED 0x0527
146#define OID_802_11_MIC_FAILURE_REPORT_FRAME 0x0528
147
148// For 802.1x daemin using to require current driver configuration
149#define OID_802_11_RADIUS_QUERY_SETTING 0x0540
150
151#define RT_OID_DEVICE_NAME 0x0607
152#define RT_OID_VERSION_INFO 0x0608
153#define OID_802_11_BSSID_LIST 0x0609
154#define OID_802_3_CURRENT_ADDRESS 0x060A
155#define OID_GEN_MEDIA_CONNECT_STATUS 0x060B
156#define RT_OID_802_11_QUERY_LINK_STATUS 0x060C
157#define OID_802_11_RSSI 0x060D
158#define OID_802_11_STATISTICS 0x060E
159#define OID_GEN_RCV_OK 0x060F
160#define OID_GEN_RCV_NO_BUFFER 0x0610
161#define RT_OID_802_11_QUERY_EEPROM_VERSION 0x0611
162#define RT_OID_802_11_QUERY_FIRMWARE_VERSION 0x0612
163#define RT_OID_802_11_QUERY_LAST_RX_RATE 0x0613
164#define RT_OID_802_11_TX_POWER_LEVEL_1 0x0614
165#define RT_OID_802_11_QUERY_PIDVID 0x0615
166//for WPA_SUPPLICANT_SUPPORT
167#define OID_SET_COUNTERMEASURES 0x0616
168#define OID_802_11_SET_IEEE8021X 0x0617
169#define OID_802_11_SET_IEEE8021X_REQUIRE_KEY 0x0618
170#define OID_802_11_PMKID 0x0620
171#define RT_OID_WPA_SUPPLICANT_SUPPORT 0x0621
172#define RT_OID_WE_VERSION_COMPILED 0x0622
173#define RT_OID_NEW_DRIVER 0x0623
174
175
176//rt2860 , kathy
177#define RT_OID_802_11_SNR_0 0x0630
178#define RT_OID_802_11_SNR_1 0x0631
179#define RT_OID_802_11_QUERY_LAST_TX_RATE 0x0632
180#define RT_OID_802_11_QUERY_HT_PHYMODE 0x0633
181#define RT_OID_802_11_SET_HT_PHYMODE 0x0634
182#define OID_802_11_RELOAD_DEFAULTS 0x0635
183#define RT_OID_802_11_QUERY_APSD_SETTING 0x0636
184#define RT_OID_802_11_SET_APSD_SETTING 0x0637
185#define RT_OID_802_11_QUERY_APSD_PSM 0x0638
186#define RT_OID_802_11_SET_APSD_PSM 0x0639
187#define RT_OID_802_11_QUERY_DLS 0x063A
188#define RT_OID_802_11_SET_DLS 0x063B
189#define RT_OID_802_11_QUERY_DLS_PARAM 0x063C
190#define RT_OID_802_11_SET_DLS_PARAM 0x063D
191#define RT_OID_802_11_QUERY_WMM 0x063E
192#define RT_OID_802_11_SET_WMM 0x063F
193#define RT_OID_802_11_QUERY_IMME_BA_CAP 0x0640
194#define RT_OID_802_11_SET_IMME_BA_CAP 0x0641
195#define RT_OID_802_11_QUERY_BATABLE 0x0642
196#define RT_OID_802_11_ADD_IMME_BA 0x0643
197#define RT_OID_802_11_TEAR_IMME_BA 0x0644
198#define RT_OID_DRIVER_DEVICE_NAME 0x0645
199#define RT_OID_802_11_QUERY_DAT_HT_PHYMODE 0x0646
200#define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT 0x0647
201
202// Ralink defined OIDs
203// Dennis Lee move to platform specific
204
205#define RT_OID_802_11_BSSID (OID_GET_SET_TOGGLE | OID_802_11_BSSID)
206#define RT_OID_802_11_SSID (OID_GET_SET_TOGGLE | OID_802_11_SSID)
207#define RT_OID_802_11_INFRASTRUCTURE_MODE (OID_GET_SET_TOGGLE | OID_802_11_INFRASTRUCTURE_MODE)
208#define RT_OID_802_11_ADD_WEP (OID_GET_SET_TOGGLE | OID_802_11_ADD_WEP)
209#define RT_OID_802_11_ADD_KEY (OID_GET_SET_TOGGLE | OID_802_11_ADD_KEY)
210#define RT_OID_802_11_REMOVE_WEP (OID_GET_SET_TOGGLE | OID_802_11_REMOVE_WEP)
211#define RT_OID_802_11_REMOVE_KEY (OID_GET_SET_TOGGLE | OID_802_11_REMOVE_KEY)
212#define RT_OID_802_11_DISASSOCIATE (OID_GET_SET_TOGGLE | OID_802_11_DISASSOCIATE)
213#define RT_OID_802_11_AUTHENTICATION_MODE (OID_GET_SET_TOGGLE | OID_802_11_AUTHENTICATION_MODE)
214#define RT_OID_802_11_PRIVACY_FILTER (OID_GET_SET_TOGGLE | OID_802_11_PRIVACY_FILTER)
215#define RT_OID_802_11_BSSID_LIST_SCAN (OID_GET_SET_TOGGLE | OID_802_11_BSSID_LIST_SCAN)
216#define RT_OID_802_11_WEP_STATUS (OID_GET_SET_TOGGLE | OID_802_11_WEP_STATUS)
217#define RT_OID_802_11_RELOAD_DEFAULTS (OID_GET_SET_TOGGLE | OID_802_11_RELOAD_DEFAULTS)
218#define RT_OID_802_11_NETWORK_TYPE_IN_USE (OID_GET_SET_TOGGLE | OID_802_11_NETWORK_TYPE_IN_USE)
219#define RT_OID_802_11_TX_POWER_LEVEL (OID_GET_SET_TOGGLE | OID_802_11_TX_POWER_LEVEL)
220#define RT_OID_802_11_RSSI_TRIGGER (OID_GET_SET_TOGGLE | OID_802_11_RSSI_TRIGGER)
221#define RT_OID_802_11_FRAGMENTATION_THRESHOLD (OID_GET_SET_TOGGLE | OID_802_11_FRAGMENTATION_THRESHOLD)
222#define RT_OID_802_11_RTS_THRESHOLD (OID_GET_SET_TOGGLE | OID_802_11_RTS_THRESHOLD)
223#define RT_OID_802_11_RX_ANTENNA_SELECTED (OID_GET_SET_TOGGLE | OID_802_11_RX_ANTENNA_SELECTED)
224#define RT_OID_802_11_TX_ANTENNA_SELECTED (OID_GET_SET_TOGGLE | OID_802_11_TX_ANTENNA_SELECTED)
225#define RT_OID_802_11_SUPPORTED_RATES (OID_GET_SET_TOGGLE | OID_802_11_SUPPORTED_RATES)
226#define RT_OID_802_11_DESIRED_RATES (OID_GET_SET_TOGGLE | OID_802_11_DESIRED_RATES)
227#define RT_OID_802_11_CONFIGURATION (OID_GET_SET_TOGGLE | OID_802_11_CONFIGURATION)
228#define RT_OID_802_11_POWER_MODE (OID_GET_SET_TOGGLE | OID_802_11_POWER_MODE)
229
230typedef enum _NDIS_802_11_STATUS_TYPE
231{
232 Ndis802_11StatusType_Authentication,
233 Ndis802_11StatusType_MediaStreamMode,
234 Ndis802_11StatusType_PMKID_CandidateList,
235 Ndis802_11StatusTypeMax // not a real type, defined as an upper bound
236} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE;
237
238typedef UCHAR NDIS_802_11_MAC_ADDRESS[6];
239
240typedef struct _NDIS_802_11_STATUS_INDICATION
241{
242 NDIS_802_11_STATUS_TYPE StatusType;
243} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION;
244
245// mask for authentication/integrity fields
246#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f
247
248#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01
249#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02
250#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06
251#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E
252
253typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST
254{
255 ULONG Length; // Length of structure
256 NDIS_802_11_MAC_ADDRESS Bssid;
257 ULONG Flags;
258} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST;
259
260//Added new types for PMKID Candidate lists.
261typedef struct _PMKID_CANDIDATE {
262 NDIS_802_11_MAC_ADDRESS BSSID;
263 ULONG Flags;
264} PMKID_CANDIDATE, *PPMKID_CANDIDATE;
265
266typedef struct _NDIS_802_11_PMKID_CANDIDATE_LIST
267{
268 ULONG Version; // Version of the structure
269 ULONG NumCandidates; // No. of pmkid candidates
270 PMKID_CANDIDATE CandidateList[1];
271} NDIS_802_11_PMKID_CANDIDATE_LIST, *PNDIS_802_11_PMKID_CANDIDATE_LIST;
272
273//Flags for PMKID Candidate list structure
274#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
275
276// Added new types for OFDM 5G and 2.4G
277typedef enum _NDIS_802_11_NETWORK_TYPE
278{
279 Ndis802_11FH,
280 Ndis802_11DS,
281 Ndis802_11OFDM5,
282 Ndis802_11OFDM5_N,
283 Ndis802_11OFDM24,
284 Ndis802_11OFDM24_N,
285 Ndis802_11Automode,
286 Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound
287} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE;
288
289typedef struct _NDIS_802_11_NETWORK_TYPE_LIST
290{
291 UINT NumberOfItems; // in list below, at least 1
292 NDIS_802_11_NETWORK_TYPE NetworkType [1];
293} NDIS_802_11_NETWORK_TYPE_LIST, *PNDIS_802_11_NETWORK_TYPE_LIST;
294
295typedef enum _NDIS_802_11_POWER_MODE
296{
297 Ndis802_11PowerModeCAM,
298 Ndis802_11PowerModeMAX_PSP,
299 Ndis802_11PowerModeFast_PSP,
300 Ndis802_11PowerModeLegacy_PSP,
301 Ndis802_11PowerModeMax // not a real mode, defined as an upper bound
302} NDIS_802_11_POWER_MODE, *PNDIS_802_11_POWER_MODE;
303
304typedef ULONG NDIS_802_11_TX_POWER_LEVEL; // in milliwatts
305
306//
307// Received Signal Strength Indication
308//
309typedef LONG NDIS_802_11_RSSI; // in dBm
310
311typedef struct _NDIS_802_11_CONFIGURATION_FH
312{
313 ULONG Length; // Length of structure
314 ULONG HopPattern; // As defined by 802.11, MSB set
315 ULONG HopSet; // to one if non-802.11
316 ULONG DwellTime; // units are Kusec
317} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH;
318
319typedef struct _NDIS_802_11_CONFIGURATION
320{
321 ULONG Length; // Length of structure
322 ULONG BeaconPeriod; // units are Kusec
323 ULONG ATIMWindow; // units are Kusec
324 ULONG DSConfig; // Frequency, units are kHz
325 NDIS_802_11_CONFIGURATION_FH FHConfig;
326} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION;
327
328typedef struct _NDIS_802_11_STATISTICS
329{
330 ULONG Length; // Length of structure
331 LARGE_INTEGER TransmittedFragmentCount;
332 LARGE_INTEGER MulticastTransmittedFrameCount;
333 LARGE_INTEGER FailedCount;
334 LARGE_INTEGER RetryCount;
335 LARGE_INTEGER MultipleRetryCount;
336 LARGE_INTEGER RTSSuccessCount;
337 LARGE_INTEGER RTSFailureCount;
338 LARGE_INTEGER ACKFailureCount;
339 LARGE_INTEGER FrameDuplicateCount;
340 LARGE_INTEGER ReceivedFragmentCount;
341 LARGE_INTEGER MulticastReceivedFrameCount;
342 LARGE_INTEGER FCSErrorCount;
343 LARGE_INTEGER TKIPLocalMICFailures;
344 LARGE_INTEGER TKIPRemoteMICErrors;
345 LARGE_INTEGER TKIPICVErrors;
346 LARGE_INTEGER TKIPCounterMeasuresInvoked;
347 LARGE_INTEGER TKIPReplays;
348 LARGE_INTEGER CCMPFormatErrors;
349 LARGE_INTEGER CCMPReplays;
350 LARGE_INTEGER CCMPDecryptErrors;
351 LARGE_INTEGER FourWayHandshakeFailures;
352} NDIS_802_11_STATISTICS, *PNDIS_802_11_STATISTICS;
353
354typedef ULONG NDIS_802_11_KEY_INDEX;
355typedef ULONGLONG NDIS_802_11_KEY_RSC;
356
357#define MAX_RADIUS_SRV_NUM 2 // 802.1x failover number
358
359typedef struct PACKED _RADIUS_SRV_INFO {
360 UINT32 radius_ip;
361 UINT32 radius_port;
362 UCHAR radius_key[64];
363 UCHAR radius_key_len;
364} RADIUS_SRV_INFO, *PRADIUS_SRV_INFO;
365
366typedef struct PACKED _RADIUS_KEY_INFO
367{
368 UCHAR radius_srv_num;
369 RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM];
370 UCHAR ieee8021xWEP; // dynamic WEP
371 UCHAR key_index;
372 UCHAR key_length; // length of key in bytes
373 UCHAR key_material[13];
374} RADIUS_KEY_INFO, *PRADIUS_KEY_INFO;
375
376// It's used by 802.1x daemon to require relative configuration
377typedef struct PACKED _RADIUS_CONF
378{
379 UINT32 Length; // Length of this structure
380 UCHAR mbss_num; // indicate multiple BSS number
381 UINT32 own_ip_addr;
382 UINT32 retry_interval;
383 UINT32 session_timeout_interval;
384 UCHAR EAPifname[IFNAMSIZ];
385 UCHAR EAPifname_len;
386 UCHAR PreAuthifname[IFNAMSIZ];
387 UCHAR PreAuthifname_len;
388 RADIUS_KEY_INFO RadiusInfo[8/*MAX_MBSSID_NUM*/];
389} RADIUS_CONF, *PRADIUS_CONF;
390
391
392
393#ifdef CONFIG_STA_SUPPORT
394// Key mapping keys require a BSSID
395typedef struct _NDIS_802_11_KEY
396{
397 UINT Length; // Length of this structure
398 UINT KeyIndex;
399 UINT KeyLength; // length of key in bytes
400 NDIS_802_11_MAC_ADDRESS BSSID;
401 NDIS_802_11_KEY_RSC KeyRSC;
402 UCHAR KeyMaterial[1]; // variable length depending on above field
403} NDIS_802_11_KEY, *PNDIS_802_11_KEY;
404#endif // CONFIG_STA_SUPPORT //
405
406typedef struct _NDIS_802_11_REMOVE_KEY
407{
408 UINT Length; // Length of this structure
409 UINT KeyIndex;
410 NDIS_802_11_MAC_ADDRESS BSSID;
411} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY;
412
413typedef struct _NDIS_802_11_WEP
414{
415 UINT Length; // Length of this structure
416 UINT KeyIndex; // 0 is the per-client key, 1-N are the
417 // global keys
418 UINT KeyLength; // length of key in bytes
419 UCHAR KeyMaterial[1];// variable length depending on above field
420} NDIS_802_11_WEP, *PNDIS_802_11_WEP;
421
422
423typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE
424{
425 Ndis802_11IBSS,
426 Ndis802_11Infrastructure,
427 Ndis802_11AutoUnknown,
428 Ndis802_11Monitor,
429 Ndis802_11InfrastructureMax // Not a real value, defined as upper bound
430} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE;
431
432// Add new authentication modes
433typedef enum _NDIS_802_11_AUTHENTICATION_MODE
434{
435 Ndis802_11AuthModeOpen,
436 Ndis802_11AuthModeShared,
437 Ndis802_11AuthModeAutoSwitch,
438 Ndis802_11AuthModeWPA,
439 Ndis802_11AuthModeWPAPSK,
440 Ndis802_11AuthModeWPANone,
441 Ndis802_11AuthModeWPA2,
442 Ndis802_11AuthModeWPA2PSK,
443 Ndis802_11AuthModeWPA1WPA2,
444 Ndis802_11AuthModeWPA1PSKWPA2PSK,
445 Ndis802_11AuthModeMax // Not a real mode, defined as upper bound
446} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE;
447
448typedef UCHAR NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; // Set of 8 data rates
449typedef UCHAR NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; // Set of 16 data rates
450
451typedef struct PACKED _NDIS_802_11_SSID
452{
453 UINT SsidLength; // length of SSID field below, in bytes;
454 // this can be zero.
455 UCHAR Ssid[NDIS_802_11_LENGTH_SSID]; // SSID information field
456} NDIS_802_11_SSID, *PNDIS_802_11_SSID;
457
458
459typedef struct PACKED _NDIS_WLAN_BSSID
460{
461 ULONG Length; // Length of this structure
462 NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID
463 UCHAR Reserved[2];
464 NDIS_802_11_SSID Ssid; // SSID
465 ULONG Privacy; // WEP encryption requirement
466 NDIS_802_11_RSSI Rssi; // receive signal strength in dBm
467 NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
468 NDIS_802_11_CONFIGURATION Configuration;
469 NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
470 NDIS_802_11_RATES SupportedRates;
471} NDIS_WLAN_BSSID, *PNDIS_WLAN_BSSID;
472
473typedef struct PACKED _NDIS_802_11_BSSID_LIST
474{
475 UINT NumberOfItems; // in list below, at least 1
476 NDIS_WLAN_BSSID Bssid[1];
477} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST;
478
479// Added Capabilities, IELength and IEs for each BSSID
480typedef struct PACKED _NDIS_WLAN_BSSID_EX
481{
482 ULONG Length; // Length of this structure
483 NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID
484 UCHAR Reserved[2];
485 NDIS_802_11_SSID Ssid; // SSID
486 UINT Privacy; // WEP encryption requirement
487 NDIS_802_11_RSSI Rssi; // receive signal
488 // strength in dBm
489 NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
490 NDIS_802_11_CONFIGURATION Configuration;
491 NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
492 NDIS_802_11_RATES_EX SupportedRates;
493 ULONG IELength;
494 UCHAR IEs[1];
495} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX;
496
497typedef struct PACKED _NDIS_802_11_BSSID_LIST_EX
498{
499 UINT NumberOfItems; // in list below, at least 1
500 NDIS_WLAN_BSSID_EX Bssid[1];
501} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX;
502
503typedef struct PACKED _NDIS_802_11_FIXED_IEs
504{
505 UCHAR Timestamp[8];
506 USHORT BeaconInterval;
507 USHORT Capabilities;
508} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs;
509
510typedef struct _NDIS_802_11_VARIABLE_IEs
511{
512 UCHAR ElementID;
513 UCHAR Length; // Number of bytes in data field
514 UCHAR data[1];
515} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs;
516
517typedef ULONG NDIS_802_11_FRAGMENTATION_THRESHOLD;
518
519typedef ULONG NDIS_802_11_RTS_THRESHOLD;
520
521typedef ULONG NDIS_802_11_ANTENNA;
522
523typedef enum _NDIS_802_11_PRIVACY_FILTER
524{
525 Ndis802_11PrivFilterAcceptAll,
526 Ndis802_11PrivFilter8021xWEP
527} NDIS_802_11_PRIVACY_FILTER, *PNDIS_802_11_PRIVACY_FILTER;
528
529// Added new encryption types
530// Also aliased typedef to new name
531typedef enum _NDIS_802_11_WEP_STATUS
532{
533 Ndis802_11WEPEnabled,
534 Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
535 Ndis802_11WEPDisabled,
536 Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
537 Ndis802_11WEPKeyAbsent,
538 Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
539 Ndis802_11WEPNotSupported,
540 Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
541 Ndis802_11Encryption2Enabled,
542 Ndis802_11Encryption2KeyAbsent,
543 Ndis802_11Encryption3Enabled,
544 Ndis802_11Encryption3KeyAbsent,
545 Ndis802_11Encryption4Enabled, // TKIP or AES mix
546 Ndis802_11Encryption4KeyAbsent,
547} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
548 NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
549
550typedef enum _NDIS_802_11_RELOAD_DEFAULTS
551{
552 Ndis802_11ReloadWEPKeys
553} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS;
554
555#define NDIS_802_11_AI_REQFI_CAPABILITIES 1
556#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2
557#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4
558
559#define NDIS_802_11_AI_RESFI_CAPABILITIES 1
560#define NDIS_802_11_AI_RESFI_STATUSCODE 2
561#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4
562
563typedef struct _NDIS_802_11_AI_REQFI
564{
565 USHORT Capabilities;
566 USHORT ListenInterval;
567 NDIS_802_11_MAC_ADDRESS CurrentAPAddress;
568} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
569
570typedef struct _NDIS_802_11_AI_RESFI
571{
572 USHORT Capabilities;
573 USHORT StatusCode;
574 USHORT AssociationId;
575} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
576
577typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
578{
579 ULONG Length;
580 USHORT AvailableRequestFixedIEs;
581 NDIS_802_11_AI_REQFI RequestFixedIEs;
582 ULONG RequestIELength;
583 ULONG OffsetRequestIEs;
584 USHORT AvailableResponseFixedIEs;
585 NDIS_802_11_AI_RESFI ResponseFixedIEs;
586 ULONG ResponseIELength;
587 ULONG OffsetResponseIEs;
588} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
589
590typedef struct _NDIS_802_11_AUTHENTICATION_EVENT
591{
592 NDIS_802_11_STATUS_INDICATION Status;
593 NDIS_802_11_AUTHENTICATION_REQUEST Request[1];
594} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT;
595
596// 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE
597typedef enum _NDIS_802_11_MEDIA_STREAM_MODE
598{
599 Ndis802_11MediaStreamOff,
600 Ndis802_11MediaStreamOn,
601} NDIS_802_11_MEDIA_STREAM_MODE, *PNDIS_802_11_MEDIA_STREAM_MODE;
602
603// PMKID Structures
604typedef UCHAR NDIS_802_11_PMKID_VALUE[16];
605
606#ifdef CONFIG_STA_SUPPORT
607typedef struct _BSSID_INFO
608{
609 NDIS_802_11_MAC_ADDRESS BSSID;
610 NDIS_802_11_PMKID_VALUE PMKID;
611} BSSID_INFO, *PBSSID_INFO;
612
613typedef struct _NDIS_802_11_PMKID
614{
615 UINT Length;
616 UINT BSSIDInfoCount;
617 BSSID_INFO BSSIDInfo[1];
618} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID;
619#endif // CONFIG_STA_SUPPORT //
620
621
622typedef struct _NDIS_802_11_AUTHENTICATION_ENCRYPTION
623{
624 NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported;
625 NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported;
626} NDIS_802_11_AUTHENTICATION_ENCRYPTION, *PNDIS_802_11_AUTHENTICATION_ENCRYPTION;
627
628typedef struct _NDIS_802_11_CAPABILITY
629{
630 ULONG Length;
631 ULONG Version;
632 ULONG NoOfPMKIDs;
633 ULONG NoOfAuthEncryptPairsSupported;
634 NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1];
635} NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY;
636
637//#endif //of WIN 2k
638#endif //UNDER_CE
639
640#if WIRELESS_EXT <= 11
641#ifndef SIOCDEVPRIVATE
642#define SIOCDEVPRIVATE 0x8BE0
643#endif
644#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
645#endif
646
647#ifdef CONFIG_STA_SUPPORT
648#define RTPRIV_IOCTL_SET (SIOCIWFIRSTPRIV + 0x02)
649
650#ifdef DBG
651#define RTPRIV_IOCTL_BBP (SIOCIWFIRSTPRIV + 0x03)
652#define RTPRIV_IOCTL_MAC (SIOCIWFIRSTPRIV + 0x05)
653#define RTPRIV_IOCTL_E2P (SIOCIWFIRSTPRIV + 0x07)
654#endif
655
656#ifdef RALINK_ATE
657#ifdef RALINK_28xx_QA
658#define RTPRIV_IOCTL_ATE (SIOCIWFIRSTPRIV + 0x08)
659#endif // RALINK_28xx_QA //
660#endif // RALINK_ATE //
661
662#define RTPRIV_IOCTL_STATISTICS (SIOCIWFIRSTPRIV + 0x09)
663#define RTPRIV_IOCTL_ADD_PMKID_CACHE (SIOCIWFIRSTPRIV + 0x0A)
664#define RTPRIV_IOCTL_RADIUS_DATA (SIOCIWFIRSTPRIV + 0x0C)
665#define RTPRIV_IOCTL_GSITESURVEY (SIOCIWFIRSTPRIV + 0x0D)
666#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x0E) // Sync. with RT61 (for wpa_supplicant)
667#define RTPRIV_IOCTL_GET_MAC_TABLE (SIOCIWFIRSTPRIV + 0x0F)
668
669#define RTPRIV_IOCTL_SHOW (SIOCIWFIRSTPRIV + 0x11)
670enum {
671 SHOW_CONN_STATUS = 4,
672 SHOW_DRVIER_VERION = 5,
673 SHOW_BA_INFO = 6,
674 SHOW_DESC_INFO = 7,
675 RAIO_OFF = 10,
676 RAIO_ON = 11,
677#ifdef QOS_DLS_SUPPORT
678 SHOW_DLS_ENTRY_INFO = 19,
679#endif // QOS_DLS_SUPPORT //
680 SHOW_CFG_VALUE = 20,
681};
682
683#endif // CONFIG_STA_SUPPORT //
684
685#ifdef SNMP_SUPPORT
686//SNMP ieee 802dot11, kathy , 2008_0220
687// dot11res(3)
688#define RT_OID_802_11_MANUFACTUREROUI 0x0700
689#define RT_OID_802_11_MANUFACTURERNAME 0x0701
690#define RT_OID_802_11_RESOURCETYPEIDNAME 0x0702
691
692// dot11smt(1)
693#define RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED 0x0703
694#define RT_OID_802_11_POWERMANAGEMENTMODE 0x0704
695#define OID_802_11_WEPDEFAULTKEYVALUE 0x0705 // read , write
696#define OID_802_11_WEPDEFAULTKEYID 0x0706
697#define RT_OID_802_11_WEPKEYMAPPINGLENGTH 0x0707
698#define OID_802_11_SHORTRETRYLIMIT 0x0708
699#define OID_802_11_LONGRETRYLIMIT 0x0709
700#define RT_OID_802_11_PRODUCTID 0x0710
701#define RT_OID_802_11_MANUFACTUREID 0x0711
702
703// //dot11Phy(4)
704#define OID_802_11_CURRENTCHANNEL 0x0712
705
706//dot11mac
707#define RT_OID_802_11_MAC_ADDRESS 0x0713
708#endif // SNMP_SUPPORT //
709
710#define OID_802_11_BUILD_CHANNEL_EX 0x0714
711#define OID_802_11_GET_CH_LIST 0x0715
712#define OID_802_11_GET_COUNTRY_CODE 0x0716
713#define OID_802_11_GET_CHANNEL_GEOGRAPHY 0x0717
714
715#ifdef LLTD_SUPPORT
716// for consistency with RT61
717#define RT_OID_GET_PHY_MODE 0x761
718#endif // LLTD_SUPPORT //
719
720// New for MeetingHouse Api support
721#define OID_MH_802_1X_SUPPORTED 0xFFEDC100
722
723// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!!
724typedef union _HTTRANSMIT_SETTING {
725#ifdef RT_BIG_ENDIAN
726 struct {
727 USHORT MODE:2; // Use definition MODE_xxx.
728 USHORT TxBF:1;
729 USHORT rsv:2;
730 USHORT STBC:2; //SPACE
731 USHORT ShortGI:1;
732 USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
733 USHORT MCS:7; // MCS
734 } field;
735#else
736 struct {
737 USHORT MCS:7; // MCS
738 USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
739 USHORT ShortGI:1;
740 USHORT STBC:2; //SPACE
741 USHORT rsv:2;
742 USHORT TxBF:1;
743 USHORT MODE:2; // Use definition MODE_xxx.
744 } field;
745#endif
746 USHORT word;
747 } HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING;
748
749typedef enum _RT_802_11_PREAMBLE {
750 Rt802_11PreambleLong,
751 Rt802_11PreambleShort,
752 Rt802_11PreambleAuto
753} RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE;
754
755// Only for STA, need to sync with AP
756// 2005-03-08 match current RaConfig.
757typedef enum _RT_802_11_PHY_MODE {
758 PHY_11BG_MIXED = 0,
759 PHY_11B,
760 PHY_11A,
761 PHY_11ABG_MIXED,
762 PHY_11G,
763#ifdef DOT11_N_SUPPORT
764 PHY_11ABGN_MIXED, // both band 5
765 PHY_11N_2_4G, // 11n-only with 2.4G band 6
766 PHY_11GN_MIXED, // 2.4G band 7
767 PHY_11AN_MIXED, // 5G band 8
768 PHY_11BGN_MIXED, // if check 802.11b. 9
769 PHY_11AGN_MIXED, // if check 802.11b. 10
770 PHY_11N_5G, // 11n-only with 5G band 11
771#endif // DOT11_N_SUPPORT //
772} RT_802_11_PHY_MODE;
773
774// put all proprietery for-query objects here to reduce # of Query_OID
775typedef struct _RT_802_11_LINK_STATUS {
776 ULONG CurrTxRate; // in units of 0.5Mbps
777 ULONG ChannelQuality; // 0..100 %
778 ULONG TxByteCount; // both ok and fail
779 ULONG RxByteCount; // both ok and fail
780 ULONG CentralChannel; // 40MHz central channel number
781} RT_802_11_LINK_STATUS, *PRT_802_11_LINK_STATUS;
782
783typedef struct _RT_802_11_EVENT_LOG {
784 LARGE_INTEGER SystemTime; // timestammp via NdisGetCurrentSystemTime()
785 UCHAR Addr[MAC_ADDR_LENGTH];
786 USHORT Event; // EVENT_xxx
787} RT_802_11_EVENT_LOG, *PRT_802_11_EVENT_LOG;
788
789typedef struct _RT_802_11_EVENT_TABLE {
790 ULONG Num;
791 ULONG Rsv; // to align Log[] at LARGE_INEGER boundary
792 RT_802_11_EVENT_LOG Log[MAX_NUMBER_OF_EVENT];
793} RT_802_11_EVENT_TABLE, PRT_802_11_EVENT_TABLE;
794
795// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!!
796typedef union _MACHTTRANSMIT_SETTING {
797 struct {
798 USHORT MCS:7; // MCS
799 USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
800 USHORT ShortGI:1;
801 USHORT STBC:2; //SPACE
802 USHORT rsv:3;
803 USHORT MODE:2; // Use definition MODE_xxx.
804 } field;
805 USHORT word;
806 } MACHTTRANSMIT_SETTING, *PMACHTTRANSMIT_SETTING;
807
808typedef struct _RT_802_11_MAC_ENTRY {
809 UCHAR Addr[MAC_ADDR_LENGTH];
810 UCHAR Aid;
811 UCHAR Psm; // 0:PWR_ACTIVE, 1:PWR_SAVE
812 UCHAR MimoPs; // 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled
813 CHAR AvgRssi0;
814 CHAR AvgRssi1;
815 CHAR AvgRssi2;
816 UINT32 ConnectedTime;
817 MACHTTRANSMIT_SETTING TxRate;
818} RT_802_11_MAC_ENTRY, *PRT_802_11_MAC_ENTRY;
819
820typedef struct _RT_802_11_MAC_TABLE {
821 ULONG Num;
822 RT_802_11_MAC_ENTRY Entry[MAX_NUMBER_OF_MAC];
823} RT_802_11_MAC_TABLE, *PRT_802_11_MAC_TABLE;
824
825// structure for query/set hardware register - MAC, BBP, RF register
826typedef struct _RT_802_11_HARDWARE_REGISTER {
827 ULONG HardwareType; // 0:MAC, 1:BBP, 2:RF register, 3:EEPROM
828 ULONG Offset; // Q/S register offset addr
829 ULONG Data; // R/W data buffer
830} RT_802_11_HARDWARE_REGISTER, *PRT_802_11_HARDWARE_REGISTER;
831
832typedef struct _RT_802_11_AP_CONFIG {
833 ULONG EnableTxBurst; // 0-disable, 1-enable
834 ULONG EnableTurboRate; // 0-disable, 1-enable 72/100mbps turbo rate
835 ULONG IsolateInterStaTraffic; // 0-disable, 1-enable isolation
836 ULONG HideSsid; // 0-disable, 1-enable hiding
837 ULONG UseBGProtection; // 0-AUTO, 1-always ON, 2-always OFF
838 ULONG UseShortSlotTime; // 0-no use, 1-use 9-us short slot time
839 ULONG Rsv1; // must be 0
840 ULONG SystemErrorBitmap; // ignore upon SET, return system error upon QUERY
841} RT_802_11_AP_CONFIG, *PRT_802_11_AP_CONFIG;
842
843// structure to query/set STA_CONFIG
844typedef struct _RT_802_11_STA_CONFIG {
845 ULONG EnableTxBurst; // 0-disable, 1-enable
846 ULONG EnableTurboRate; // 0-disable, 1-enable 72/100mbps turbo rate
847 ULONG UseBGProtection; // 0-AUTO, 1-always ON, 2-always OFF
848 ULONG UseShortSlotTime; // 0-no use, 1-use 9-us short slot time when applicable
849 ULONG AdhocMode; // 0-11b rates only (WIFI spec), 1 - b/g mixed, 2 - g only
850 ULONG HwRadioStatus; // 0-OFF, 1-ON, default is 1, Read-Only
851 ULONG Rsv1; // must be 0
852 ULONG SystemErrorBitmap; // ignore upon SET, return system error upon QUERY
853} RT_802_11_STA_CONFIG, *PRT_802_11_STA_CONFIG;
854
855//
856// For OID Query or Set about BA structure
857//
858typedef struct _OID_BACAP_STRUC {
859 UCHAR RxBAWinLimit;
860 UCHAR TxBAWinLimit;
861 UCHAR Policy; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid
862 UCHAR MpduDensity; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid
863 UCHAR AmsduEnable; //Enable AMSDU transmisstion
864 UCHAR AmsduSize; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
865 UCHAR MMPSmode; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
866 BOOLEAN AutoBA; // Auto BA will automatically
867} OID_BACAP_STRUC, *POID_BACAP_STRUC;
868
869typedef struct _RT_802_11_ACL_ENTRY {
870 UCHAR Addr[MAC_ADDR_LENGTH];
871 USHORT Rsv;
872} RT_802_11_ACL_ENTRY, *PRT_802_11_ACL_ENTRY;
873
874typedef struct PACKED _RT_802_11_ACL {
875 ULONG Policy; // 0-disable, 1-positive list, 2-negative list
876 ULONG Num;
877 RT_802_11_ACL_ENTRY Entry[MAX_NUMBER_OF_ACL];
878} RT_802_11_ACL, *PRT_802_11_ACL;
879
880typedef struct _RT_802_11_WDS {
881 ULONG Num;
882 NDIS_802_11_MAC_ADDRESS Entry[24/*MAX_NUM_OF_WDS_LINK*/];
883 ULONG KeyLength;
884 UCHAR KeyMaterial[32];
885} RT_802_11_WDS, *PRT_802_11_WDS;
886
887typedef struct _RT_802_11_TX_RATES_ {
888 UCHAR SupRateLen;
889 UCHAR SupRate[MAX_LENGTH_OF_SUPPORT_RATES];
890 UCHAR ExtRateLen;
891 UCHAR ExtRate[MAX_LENGTH_OF_SUPPORT_RATES];
892} RT_802_11_TX_RATES, *PRT_802_11_TX_RATES;
893
894
895// Definition of extra information code
896#define GENERAL_LINK_UP 0x0 // Link is Up
897#define GENERAL_LINK_DOWN 0x1 // Link is Down
898#define HW_RADIO_OFF 0x2 // Hardware radio off
899#define SW_RADIO_OFF 0x3 // Software radio off
900#define AUTH_FAIL 0x4 // Open authentication fail
901#define AUTH_FAIL_KEYS 0x5 // Shared authentication fail
902#define ASSOC_FAIL 0x6 // Association failed
903#define EAP_MIC_FAILURE 0x7 // Deauthencation because MIC failure
904#define EAP_4WAY_TIMEOUT 0x8 // Deauthencation on 4-way handshake timeout
905#define EAP_GROUP_KEY_TIMEOUT 0x9 // Deauthencation on group key handshake timeout
906#define EAP_SUCCESS 0xa // EAP succeed
907#define DETECT_RADAR_SIGNAL 0xb // Radar signal occur in current channel
908#define EXTRA_INFO_MAX 0xb // Indicate Last OID
909
910#define EXTRA_INFO_CLEAR 0xffffffff
911
912// This is OID setting structure. So only GF or MM as Mode. This is valid when our wirelss mode has 802.11n in use.
913typedef struct {
914 RT_802_11_PHY_MODE PhyMode; //
915 UCHAR TransmitNo;
916 UCHAR HtMode; //HTMODE_GF or HTMODE_MM
917 UCHAR ExtOffset; //extension channel above or below
918 UCHAR MCS;
919 UCHAR BW;
920 UCHAR STBC;
921 UCHAR SHORTGI;
922 UCHAR rsv;
923} OID_SET_HT_PHYMODE, *POID_SET_HT_PHYMODE;
924
925#ifdef LLTD_SUPPORT
926typedef struct _RT_LLTD_ASSOICATION_ENTRY {
927 UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
928 unsigned short MOR; // maximum operational rate
929 UCHAR phyMode;
930} RT_LLTD_ASSOICATION_ENTRY, *PRT_LLTD_ASSOICATION_ENTRY;
931
932typedef struct _RT_LLTD_ASSOICATION_TABLE {
933 unsigned int Num;
934 RT_LLTD_ASSOICATION_ENTRY Entry[MAX_NUMBER_OF_MAC];
935} RT_LLTD_ASSOICATION_TABLE, *PRT_LLTD_ASSOICATION_TABLE;
936#endif // LLTD_SUPPORT //
937
938#ifdef CONFIG_STA_SUPPORT
939#ifdef QOS_DLS_SUPPORT
940//rt2860, kathy 2007-0118
941// structure for DLS
942typedef struct _RT_802_11_DLS_UI {
943 USHORT TimeOut; // unit: second , set by UI
944 USHORT CountDownTimer; // unit: second , used by driver only
945 NDIS_802_11_MAC_ADDRESS MacAddr; // set by UI
946 UCHAR Status; // 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
947 BOOLEAN Valid; // 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
948} RT_802_11_DLS_UI, *PRT_802_11_DLS_UI;
949
950typedef struct _RT_802_11_DLS_INFO {
951 RT_802_11_DLS_UI Entry[MAX_NUMBER_OF_DLS_ENTRY];
952 UCHAR num;
953} RT_802_11_DLS_INFO, *PRT_802_11_DLS_INFO;
954
955typedef enum _RT_802_11_DLS_MODE {
956 DLS_NONE,
957 DLS_WAIT_KEY,
958 DLS_FINISH
959} RT_802_11_DLS_MODE;
960#endif // QOS_DLS_SUPPORT //
961
962#ifdef WPA_SUPPLICANT_SUPPORT
963#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
964#define RT_ASSOC_EVENT_FLAG 0x0101
965#define RT_DISASSOC_EVENT_FLAG 0x0102
966#define RT_REQIE_EVENT_FLAG 0x0103
967#define RT_RESPIE_EVENT_FLAG 0x0104
968#define RT_ASSOCINFO_EVENT_FLAG 0x0105
969#define RT_PMKIDCAND_FLAG 0x0106
970#define RT_INTERFACE_DOWN 0x0107
971#define RT_INTERFACE_UP 0x0108
972#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
973#endif // WPA_SUPPLICANT_SUPPORT //
974#endif // CONFIG_STA_SUPPORT //
975
976#define MAX_CUSTOM_LEN 128
977
978#ifdef CONFIG_STA_SUPPORT
979typedef enum _RT_802_11_D_CLIENT_MODE
980{
981 Rt802_11_D_None,
982 Rt802_11_D_Flexible,
983 Rt802_11_D_Strict,
984} RT_802_11_D_CLIENT_MODE, *PRT_802_11_D_CLIENT_MODE;
985#endif // CONFIG_STA_SUPPORT //
986
987typedef struct _RT_CHANNEL_LIST_INFO
988{
989 UCHAR ChannelList[MAX_NUM_OF_CHS]; // list all supported channels for site survey
990 UCHAR ChannelListNum; // number of channel in ChannelList[]
991} RT_CHANNEL_LIST_INFO, *PRT_CHANNEL_LIST_INFO;
992
993
994#endif // _OID_H_
995
diff --git a/drivers/staging/rt2860/rt2860.h b/drivers/staging/rt2860/rt2860.h
new file mode 100644
index 00000000000..c8977d538f0
--- /dev/null
+++ b/drivers/staging/rt2860/rt2860.h
@@ -0,0 +1,349 @@
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 __RT2860_H__
29#define __RT2860_H__
30
31#define RT28xx_CHIP_NAME "RT2860"
32
33#define TXINFO_SIZE 0
34#define TXPADDING_SIZE 0
35
36/* ----------------- EEPROM Related MACRO ----------------- */
37#define RT28xx_EEPROM_READ16(pAd, offset, var) \
38 var = RTMP_EEPROM_READ16(pAd, offset)
39
40#define RT28xx_EEPROM_WRITE16(pAd, offset, var) \
41 RTMP_EEPROM_WRITE16(pAd, offset, var)
42
43/* ----------------- TASK/THREAD Related MACRO ----------------- */
44#define RT28XX_TASK_THREAD_INIT(pAd, Status) \
45 init_thread_task(pAd); NICInitTxRxRingAndBacklogQueue(pAd); \
46 Status = NDIS_STATUS_SUCCESS;
47
48/* function declarations */
49#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
50#define IRQ_HANDLE_TYPE irqreturn_t
51#else
52#define IRQ_HANDLE_TYPE void
53#endif
54
55IRQ_HANDLE_TYPE
56#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
57rt2860_interrupt(int irq, void *dev_instance);
58#else
59rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
60#endif
61
62/* ----------------- Frimware Related MACRO ----------------- */
63#define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \
64 do{ \
65 ULONG _i, _firm; \
66 RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000); \
67 \
68 for(_i=0; _i<_FwLen; _i+=4) \
69 { \
70 _firm = _pFwImage[_i] + \
71 (_pFwImage[_i+3] << 24) + \
72 (_pFwImage[_i+2] << 16) + \
73 (_pFwImage[_i+1] << 8); \
74 RTMP_IO_WRITE32(_pAd, FIRMWARE_IMAGE_BASE + _i, _firm); \
75 } \
76 RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00000); \
77 RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00001); \
78 \
79 /* initialize BBP R/W access agent */ \
80 RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, 0); \
81 RTMP_IO_WRITE32(_pAd, H2M_MAILBOX_CSR, 0); \
82 }while(0)
83
84/* ----------------- TX Related MACRO ----------------- */
85#define RT28XX_START_DEQUEUE(pAd, QueIdx, irqFlags) do{}while(0)
86#define RT28XX_STOP_DEQUEUE(pAd, QueIdx, irqFlags) do{}while(0)
87
88
89#define RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
90 ((freeNum) >= (ULONG)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3)) /* rough estimate we will use 3 more descriptor. */
91#define RT28XX_RELEASE_DESC_RESOURCE(pAd, QueIdx) \
92 do{}while(0)
93
94#define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \
95 (((freeNum != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum<3))
96 //(((freeNum) != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 1 /*0*/))
97
98
99#define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen) \
100 RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)
101
102#define RTMP_PKT_TAIL_PADDING 0
103
104#define fRTMP_ADAPTER_NEED_STOP_TX 0
105
106#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \
107 /* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)*/
108
109#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \
110 RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
111
112#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
113 RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
114
115#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \
116 RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)
117
118#define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx) \
119 RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)
120
121#define HAL_LastTxIdx(_pAd, _QueIdx,_LastTxIdx) \
122 /*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx)*/
123
124#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx) \
125 RTMP_IO_WRITE32((_pAd), TX_CTX_IDX0+((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx)
126/* RtmpPCIDataKickOut(_pAd, _pTxBlk, _QueIdx)*/
127
128#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \
129 MiniportMMRequest(_pAd, _QueIdx, _pNullFrame, _frameLen)
130
131#define GET_TXRING_FREENO(_pAd, _QueIdx) \
132 (_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[_QueIdx].TxCpuIdx) ? \
133 (_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \
134 : \
135 (_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1);
136
137
138#define GET_MGMTRING_FREENO(_pAd) \
139 (_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx) ? \
140 (_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \
141 : \
142 (_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1);
143
144
145/* ----------------- RX Related MACRO ----------------- */
146
147// no use
148#define RT28XX_RCV_PKT_GET_INIT(pAd)
149#define RT28XX_RV_A_BUF_END
150//#define RT28XX_RV_ALL_BUF_END
151
152
153/* ----------------- ASIC Related MACRO ----------------- */
154// no use
155#define RT28XX_DMA_POST_WRITE(pAd)
156
157// reset MAC of a station entry to 0x000000000000
158#define RT28XX_STA_ENTRY_MAC_RESET(pAd, Wcid) \
159 AsicDelWcidTab(pAd, Wcid);
160
161// add this entry into ASIC RX WCID search table
162#define RT28XX_STA_ENTRY_ADD(pAd, pEntry) \
163 AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
164
165// remove Pair-wise key material from ASIC
166#define RT28XX_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid) \
167 AsicRemovePairwiseKeyEntry(pAd, BssIdx, (UCHAR)Wcid);
168
169// add Client security information into ASIC WCID table and IVEIV table
170#define RT28XX_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry) \
171 RTMPAddWcidAttributeEntry(pAd, apidx, KeyID, \
172 pAd->SharedKey[apidx][KeyID].CipherAlg, pEntry);
173
174#define RT28XX_SECURITY_KEY_ADD(pAd, apidx, KeyID, pEntry) \
175 { /* update pairwise key information to ASIC Shared Key Table */ \
176 AsicAddSharedKeyEntry(pAd, apidx, KeyID, \
177 pAd->SharedKey[apidx][KeyID].CipherAlg, \
178 pAd->SharedKey[apidx][KeyID].Key, \
179 pAd->SharedKey[apidx][KeyID].TxMic, \
180 pAd->SharedKey[apidx][KeyID].RxMic); \
181 /* update ASIC WCID attribute table and IVEIV table */ \
182 RTMPAddWcidAttributeEntry(pAd, apidx, KeyID, \
183 pAd->SharedKey[apidx][KeyID].CipherAlg, \
184 pEntry); }
185
186
187// Insert the BA bitmap to ASIC for the Wcid entry
188#define RT28XX_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \
189 do{ \
190 UINT32 _Value = 0, _Offset; \
191 _Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4; \
192 RTMP_IO_READ32((_pAd), _Offset, &_Value); \
193 _Value |= (0x10000<<(_TID)); \
194 RTMP_IO_WRITE32((_pAd), _Offset, _Value); \
195 }while(0)
196
197
198// Remove the BA bitmap from ASIC for the Wcid entry
199// bitmap field starts at 0x10000 in ASIC WCID table
200#define RT28XX_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \
201 do{ \
202 UINT32 _Value = 0, _Offset; \
203 _Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4; \
204 RTMP_IO_READ32((_pAd), _Offset, &_Value); \
205 _Value &= (~(0x10000 << (_TID))); \
206 RTMP_IO_WRITE32((_pAd), _Offset, _Value); \
207 }while(0)
208
209
210/* ----------------- PCI/USB Related MACRO ----------------- */
211
212#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p) \
213 ((POS_COOKIE)handle)->pci_dev = dev_p;
214
215// set driver data
216#define RT28XX_DRVDATA_SET(_a) pci_set_drvdata(_a, net_dev);
217
218#define RT28XX_UNMAP() \
219{ if (net_dev->base_addr) { \
220 iounmap((void *)(net_dev->base_addr)); \
221 release_mem_region(pci_resource_start(dev_p, 0), \
222 pci_resource_len(dev_p, 0)); } \
223 if (net_dev->irq) pci_release_regions(dev_p); }
224
225#ifdef PCI_MSI_SUPPORT
226#define RTMP_MSI_ENABLE(_pAd) \
227{ POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
228 (_pAd)->HaveMsi = pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; }
229
230#define RTMP_MSI_DISABLE(_pAd) \
231{ POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
232 if (_pAd->HaveMsi == TRUE) \
233 pci_disable_msi(_pObj->pci_dev); \
234 _pAd->HaveMsi = FALSE; }
235#else
236#define RTMP_MSI_ENABLE(_pAd)
237#define RTMP_MSI_DISABLE(_pAd)
238#endif // PCI_MSI_SUPPORT //
239
240#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
241#define SA_SHIRQ IRQF_SHARED
242#endif
243
244#define RT28XX_IRQ_REQUEST(net_dev) \
245{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->priv); \
246 POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
247 RTMP_MSI_ENABLE(_pAd); \
248 if ((retval = request_irq(_pObj->pci_dev->irq, \
249 rt2860_interrupt, SA_SHIRQ, \
250 (net_dev)->name, (net_dev)))) { \
251 printk("RT2860: request_irq ERROR(%d)\n", retval); \
252 return retval; } }
253
254#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
255#define RT28XX_IRQ_RELEASE(net_dev) \
256{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->priv); \
257 POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
258 synchronize_irq(_pObj->pci_dev->irq); \
259 free_irq(_pObj->pci_dev->irq, (net_dev)); \
260 RTMP_MSI_DISABLE(_pAd); }
261#else
262#define RT28XX_IRQ_RELEASE(net_dev) \
263{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->priv); \
264 POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
265 free_irq(_pObj->pci_dev->irq, (net_dev)); \
266 RTMP_MSI_DISABLE(_pAd); }
267#endif
268
269#define RT28XX_IRQ_INIT(pAd) \
270 { pAd->int_enable_reg = ((DELAYINTMASK) | \
271 (RxINT|TxDataInt|TxMgmtInt)) & ~(0x03); \
272 pAd->int_disable_mask = 0; \
273 pAd->int_pending = 0; }
274
275#define RT28XX_IRQ_ENABLE(pAd) \
276 { /* clear garbage ints */ \
277 RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff); \
278 NICEnableInterrupt(pAd); }
279
280#define RT28XX_PUT_DEVICE(dev_p)
281
282
283/* ----------------- MLME Related MACRO ----------------- */
284#define RT28XX_MLME_HANDLER(pAd) MlmeHandler(pAd)
285
286#define RT28XX_MLME_PRE_SANITY_CHECK(pAd)
287
288#define RT28XX_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \
289 RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
290
291#define RT28XX_MLME_RESET_STATE_MACHINE(pAd) \
292 MlmeRestartStateMachine(pAd)
293
294#define RT28XX_HANDLE_COUNTER_MEASURE(_pAd, _pEntry) \
295 HandleCounterMeasure(_pAd, _pEntry)
296
297/* ----------------- Power Save Related MACRO ----------------- */
298#define RT28XX_PS_POLL_ENQUEUE(pAd) EnqueuePsPoll(pAd)
299
300//
301// Device ID & Vendor ID, these values should match EEPROM value
302//
303#define NIC2860_PCI_DEVICE_ID 0x0601
304#define NIC2860_PCIe_DEVICE_ID 0x0681
305#define NIC2760_PCI_DEVICE_ID 0x0701 // 1T/2R Cardbus ???
306#define NIC2790_PCIe_DEVICE_ID 0x0781 // 1T/2R miniCard
307
308#define NIC_PCI_VENDOR_ID 0x1814
309
310#define VEN_AWT_PCIe_DEVICE_ID 0x1059
311#define VEN_AWT_PCI_VENDOR_ID 0x1A3B
312
313// For RTMPPCIePowerLinkCtrlRestore () function
314#define RESTORE_HALT 1
315#define RESTORE_WAKEUP 2
316#define RESTORE_CLOSE 3
317
318#define PowerSafeCID 1
319#define PowerRadioOffCID 2
320#define PowerWakeCID 3
321#define CID0MASK 0x000000ff
322#define CID1MASK 0x0000ff00
323#define CID2MASK 0x00ff0000
324#define CID3MASK 0xff000000
325
326#define PCI_REG_READ_WORD(pci_dev, offset, Configuration) \
327 if (pci_read_config_word(pci_dev, offset, &reg16) == 0) \
328 Configuration = le2cpu16(reg16); \
329 else \
330 Configuration = 0;
331
332#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration) \
333 reg16 = cpu2le16(Configuration); \
334 pci_write_config_word(pci_dev, offset, reg16); \
335
336#define RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx) \
337 RT28xxPciStaAsicForceWakeup(pAd, bFromTx);
338
339#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
340 RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
341
342#define RT28XX_MLME_RADIO_ON(pAd) \
343 RT28xxPciMlmeRadioOn(pAd);
344
345#define RT28XX_MLME_RADIO_OFF(pAd) \
346 RT28xxPciMlmeRadioOFF(pAd);
347
348#endif //__RT2860_H__
349
diff --git a/drivers/staging/rt2860/rt28xx.h b/drivers/staging/rt2860/rt28xx.h
new file mode 100644
index 00000000000..ff23043e560
--- /dev/null
+++ b/drivers/staging/rt2860/rt28xx.h
@@ -0,0 +1,2714 @@
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// In order to support maximum 8 MBSS and its maximum length is 512 for each beacon
1630// Three section discontinue memory segments will be used.
1631// 1. The original region for BCN 0~3
1632// 2. Extract memory from FCE table for BCN 4~5
1633// 3. Extract memory from Pair-wise key table for BCN 6~7
1634// It occupied those memory of wcid 238~253 for BCN 6
1635// and wcid 222~237 for BCN 7
1636#define HW_BEACON_MAX_SIZE 0x1000 /* unit: byte */
1637#define HW_BEACON_BASE0 0x7800
1638#define HW_BEACON_BASE1 0x7A00
1639#define HW_BEACON_BASE2 0x7C00
1640#define HW_BEACON_BASE3 0x7E00
1641#define HW_BEACON_BASE4 0x7200
1642#define HW_BEACON_BASE5 0x7400
1643#define HW_BEACON_BASE6 0x5DC0
1644#define HW_BEACON_BASE7 0x5BC0
1645
1646#define HW_BEACON_MAX_COUNT 8
1647#define HW_BEACON_OFFSET 0x0200
1648#define HW_BEACON_CONTENT_LEN (HW_BEACON_OFFSET - TXWI_SIZE)
1649
1650// HOST-MCU shared memory - base address = 0x2100
1651#define HOST_CMD_CSR 0x404
1652#define H2M_MAILBOX_CSR 0x7010
1653#define H2M_MAILBOX_CID 0x7014
1654#define H2M_MAILBOX_STATUS 0x701c
1655#define H2M_INT_SRC 0x7024
1656#define H2M_BBP_AGENT 0x7028
1657#define M2H_CMD_DONE_CSR 0x000c
1658#define MCU_TXOP_ARRAY_BASE 0x000c // TODO: to be provided by Albert
1659#define MCU_TXOP_ENTRY_SIZE 32 // TODO: to be provided by Albert
1660#define MAX_NUM_OF_TXOP_ENTRY 16 // TODO: must be same with 8051 firmware
1661#define MCU_MBOX_VERSION 0x01 // TODO: to be confirmed by Albert
1662#define MCU_MBOX_VERSION_OFFSET 5 // TODO: to be provided by Albert
1663
1664//
1665// Host DMA registers - base address 0x200 . TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT,
1666//
1667//
1668// DMA RING DESCRIPTOR
1669//
1670#define E2PROM_CSR 0x0004
1671#define IO_CNTL_CSR 0x77d0
1672
1673#ifdef RT2860
1674// 8051 firmware image for RT2860 - base address = 0x4000
1675#define FIRMWARE_IMAGE_BASE 0x2000
1676#define MAX_FIRMWARE_IMAGE_SIZE 0x2000 // 8kbyte
1677#endif // RT2860 //
1678
1679
1680// ================================================================
1681// Tx / Rx / Mgmt ring descriptor definition
1682// ================================================================
1683
1684// the following PID values are used to mark outgoing frame type in TXD->PID so that
1685// proper TX statistics can be collected based on these categories
1686// b3-2 of PID field -
1687#define PID_MGMT 0x05
1688#define PID_BEACON 0x0c
1689#define PID_DATA_NORMALUCAST 0x02
1690#define PID_DATA_AMPDU 0x04
1691#define PID_DATA_NO_ACK 0x08
1692#define PID_DATA_NOT_NORM_ACK 0x03
1693// value domain of pTxD->HostQId (4-bit: 0~15)
1694#define QID_AC_BK 1 // meet ACI definition in 802.11e
1695#define QID_AC_BE 0 // meet ACI definition in 802.11e
1696#define QID_AC_VI 2
1697#define QID_AC_VO 3
1698#define QID_HCCA 4
1699#define NUM_OF_TX_RING 5
1700#define QID_MGMT 13
1701#define QID_RX 14
1702#define QID_OTHER 15
1703
1704
1705// ------------------------------------------------------
1706// BBP & RF definition
1707// ------------------------------------------------------
1708#define BUSY 1
1709#define IDLE 0
1710
1711#define RF_R00 0
1712#define RF_R01 1
1713#define RF_R02 2
1714#define RF_R03 3
1715#define RF_R04 4
1716#define RF_R05 5
1717#define RF_R06 6
1718#define RF_R07 7
1719#define RF_R08 8
1720#define RF_R09 9
1721#define RF_R10 10
1722#define RF_R11 11
1723#define RF_R12 12
1724#define RF_R13 13
1725#define RF_R14 14
1726#define RF_R15 15
1727#define RF_R16 16
1728#define RF_R17 17
1729#define RF_R18 18
1730#define RF_R19 19
1731#define RF_R20 20
1732#define RF_R21 21
1733#define RF_R22 22
1734#define RF_R23 23
1735#define RF_R24 24
1736#define RF_R25 25
1737#define RF_R26 26
1738#define RF_R27 27
1739#define RF_R28 28
1740#define RF_R29 29
1741#define RF_R30 30
1742#define RF_R31 31
1743
1744#define BBP_R0 0 // version
1745#define BBP_R1 1 // TSSI
1746#define BBP_R2 2 // TX configure
1747#define BBP_R3 3
1748#define BBP_R4 4
1749#define BBP_R5 5
1750#define BBP_R6 6
1751#define BBP_R14 14 // RX configure
1752#define BBP_R16 16
1753#define BBP_R17 17 // RX sensibility
1754#define BBP_R18 18
1755#define BBP_R21 21
1756#define BBP_R22 22
1757#define BBP_R24 24
1758#define BBP_R25 25
1759#define BBP_R49 49 //TSSI
1760#define BBP_R50 50
1761#define BBP_R51 51
1762#define BBP_R52 52
1763#define BBP_R55 55
1764#define BBP_R62 62 // Rx SQ0 Threshold HIGH
1765#define BBP_R63 63
1766#define BBP_R64 64
1767#define BBP_R65 65
1768#define BBP_R66 66
1769#define BBP_R67 67
1770#define BBP_R68 68
1771#define BBP_R69 69
1772#define BBP_R70 70 // Rx AGC SQ CCK Xcorr threshold
1773#define BBP_R73 73
1774#define BBP_R75 75
1775#define BBP_R77 77
1776#define BBP_R81 81
1777#define BBP_R82 82
1778#define BBP_R83 83
1779#define BBP_R84 84
1780#define BBP_R86 86
1781#define BBP_R91 91
1782#define BBP_R92 92
1783#define BBP_R94 94 // Tx Gain Control
1784#define BBP_R103 103
1785#define BBP_R105 105
1786#define BBP_R113 113
1787#define BBP_R114 114
1788#define BBP_R115 115
1789#define BBP_R116 116
1790#define BBP_R117 117
1791#define BBP_R118 118
1792#define BBP_R119 119
1793#define BBP_R120 120
1794#define BBP_R121 121
1795#define BBP_R122 122
1796#define BBP_R123 123
1797
1798
1799#define BBPR94_DEFAULT 0x06 // Add 1 value will gain 1db
1800
1801#define RSSI_FOR_VERY_LOW_SENSIBILITY -35
1802#define RSSI_FOR_LOW_SENSIBILITY -58
1803#define RSSI_FOR_MID_LOW_SENSIBILITY -80
1804#define RSSI_FOR_MID_SENSIBILITY -90
1805
1806//-------------------------------------------------------------------------
1807// EEPROM definition
1808//-------------------------------------------------------------------------
1809#define EEDO 0x08
1810#define EEDI 0x04
1811#define EECS 0x02
1812#define EESK 0x01
1813#define EERL 0x80
1814
1815#define EEPROM_WRITE_OPCODE 0x05
1816#define EEPROM_READ_OPCODE 0x06
1817#define EEPROM_EWDS_OPCODE 0x10
1818#define EEPROM_EWEN_OPCODE 0x13
1819
1820#define NUM_EEPROM_BBP_PARMS 19 // Include NIC Config 0, 1, CR, TX ALC step, BBPs
1821#define NUM_EEPROM_TX_G_PARMS 7
1822#define EEPROM_NIC1_OFFSET 0x34 // The address is from NIC config 0, not BBP register ID
1823#define EEPROM_NIC2_OFFSET 0x36 // The address is from NIC config 0, not BBP register ID
1824#define EEPROM_BBP_BASE_OFFSET 0xf0 // The address is from NIC config 0, not BBP register ID
1825#define EEPROM_G_TX_PWR_OFFSET 0x52
1826#define EEPROM_G_TX2_PWR_OFFSET 0x60
1827#define EEPROM_LED1_OFFSET 0x3c
1828#define EEPROM_LED2_OFFSET 0x3e
1829#define EEPROM_LED3_OFFSET 0x40
1830#define EEPROM_LNA_OFFSET 0x44
1831#define EEPROM_RSSI_BG_OFFSET 0x46
1832#define EEPROM_RSSI_A_OFFSET 0x4a
1833#define EEPROM_DEFINE_MAX_TXPWR 0x4e
1834#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G 0xde // 20MHZ 2.4G tx power.
1835#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G 0xee // 40MHZ 2.4G tx power.
1836#define EEPROM_TXPOWER_BYRATE_20MHZ_5G 0xfa // 20MHZ 5G tx power.
1837#define EEPROM_TXPOWER_BYRATE_40MHZ_5G 0x10a // 40MHZ 5G tx power.
1838#define EEPROM_A_TX_PWR_OFFSET 0x78
1839#define EEPROM_A_TX2_PWR_OFFSET 0xa6
1840#define EEPROM_VERSION_OFFSET 0x02
1841#define EEPROM_FREQ_OFFSET 0x3a
1842#define EEPROM_TXPOWER_BYRATE 0xde // 20MHZ power.
1843#define EEPROM_TXPOWER_DELTA 0x50 // 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ.
1844#define VALID_EEPROM_VERSION 1
1845
1846// PairKeyMode definition
1847#define PKMODE_NONE 0
1848#define PKMODE_WEP64 1
1849#define PKMODE_WEP128 2
1850#define PKMODE_TKIP 3
1851#define PKMODE_AES 4
1852#define PKMODE_CKIP64 5
1853#define PKMODE_CKIP128 6
1854#define PKMODE_TKIP_NO_MIC 7 // MIC appended by driver: not a valid value in hardware key table
1855
1856// =================================================================================
1857// WCID format
1858// =================================================================================
1859//7.1 WCID ENTRY format : 8bytes
1860typedef struct _WCID_ENTRY_STRUC {
1861 UCHAR RXBABitmap7; // bit0 for TID8, bit7 for TID 15
1862 UCHAR RXBABitmap0; // bit0 for TID0, bit7 for TID 7
1863 UCHAR MAC[6]; // 0 for shared key table. 1 for pairwise key table
1864} WCID_ENTRY_STRUC, *PWCID_ENTRY_STRUC;
1865
1866//8.1.1 SECURITY KEY format : 8DW
1867// 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table
1868typedef struct _HW_KEY_ENTRY { // 32-byte per entry
1869 UCHAR Key[16];
1870 UCHAR TxMic[8];
1871 UCHAR RxMic[8];
1872} HW_KEY_ENTRY, *PHW_KEY_ENTRY;
1873
1874//8.1.2 IV/EIV format : 2DW
1875
1876//8.1.3 RX attribute entry format : 1DW
1877#ifdef RT_BIG_ENDIAN
1878typedef struct _MAC_ATTRIBUTE_STRUC {
1879 UINT32 rsv:22;
1880 UINT32 RXWIUDF:3;
1881 UINT32 BSSIDIdx:3; //multipleBSS index for the WCID
1882 UINT32 PairKeyMode:3;
1883 UINT32 KeyTab:1; // 0 for shared key table. 1 for pairwise key table
1884} MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
1885#else
1886typedef struct _MAC_ATTRIBUTE_STRUC {
1887 UINT32 KeyTab:1; // 0 for shared key table. 1 for pairwise key table
1888 UINT32 PairKeyMode:3;
1889 UINT32 BSSIDIdx:3; //multipleBSS index for the WCID
1890 UINT32 RXWIUDF:3;
1891 UINT32 rsv:22;
1892} MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
1893#endif
1894
1895
1896// =================================================================================
1897// TX / RX ring descriptor format
1898// =================================================================================
1899
1900// the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO.
1901// MAC block use this TXINFO to control the transmission behavior of this frame.
1902#define FIFO_MGMT 0
1903#define FIFO_HCCA 1
1904#define FIFO_EDCA 2
1905
1906//
1907// TX descriptor format, Tx ring, Mgmt Ring
1908//
1909#ifdef RT_BIG_ENDIAN
1910typedef struct PACKED _TXD_STRUC {
1911 // Word 0
1912 UINT32 SDPtr0;
1913 // Word 1
1914 UINT32 DMADONE:1;
1915 UINT32 LastSec0:1;
1916 UINT32 SDLen0:14;
1917 UINT32 Burst:1;
1918 UINT32 LastSec1:1;
1919 UINT32 SDLen1:14;
1920 // Word 2
1921 UINT32 SDPtr1;
1922 // Word 3
1923 UINT32 ICO:1;
1924 UINT32 UCO:1;
1925 UINT32 TCO:1;
1926 UINT32 rsv:2;
1927 UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
1928 UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
1929 UINT32 rsv2:24;
1930} TXD_STRUC, *PTXD_STRUC;
1931#else
1932typedef struct PACKED _TXD_STRUC {
1933 // Word 0
1934 UINT32 SDPtr0;
1935 // Word 1
1936 UINT32 SDLen1:14;
1937 UINT32 LastSec1:1;
1938 UINT32 Burst:1;
1939 UINT32 SDLen0:14;
1940 UINT32 LastSec0:1;
1941 UINT32 DMADONE:1;
1942 //Word2
1943 UINT32 SDPtr1;
1944 //Word3
1945 UINT32 rsv2:24;
1946 UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
1947 UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
1948 UINT32 rsv:2;
1949 UINT32 TCO:1; //
1950 UINT32 UCO:1; //
1951 UINT32 ICO:1; //
1952} TXD_STRUC, *PTXD_STRUC;
1953#endif
1954
1955
1956//
1957// TXD Wireless Information format for Tx ring and Mgmt Ring
1958//
1959//txop : for txop mode
1960// 0:txop for the MPDU frame will be handles by ASIC by register
1961// 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS
1962#ifdef RT_BIG_ENDIAN
1963typedef struct PACKED _TXWI_STRUC {
1964 // Word 0
1965 UINT32 PHYMODE:2;
1966 UINT32 TxBF:1; // 3*3
1967 UINT32 rsv2:1;
1968 UINT32 Ifs:1; //
1969 UINT32 STBC:2; //channel bandwidth 20MHz or 40 MHz
1970 UINT32 ShortGI:1;
1971 UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
1972 UINT32 MCS:7;
1973
1974 UINT32 rsv:6;
1975 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.
1976 UINT32 MpduDensity:3;
1977 UINT32 AMPDU:1;
1978
1979 UINT32 TS:1;
1980 UINT32 CFACK:1;
1981 UINT32 MIMOps:1; // the remote peer is in dynamic MIMO-PS mode
1982 UINT32 FRAG:1; // 1 to inform TKIP engine this is a fragment.
1983 // Word 1
1984 UINT32 PacketId:4;
1985 UINT32 MPDUtotalByteCount:12;
1986 UINT32 WirelessCliID:8;
1987 UINT32 BAWinSize:6;
1988 UINT32 NSEQ:1;
1989 UINT32 ACK:1;
1990 // Word 2
1991 UINT32 IV;
1992 // Word 3
1993 UINT32 EIV;
1994} TXWI_STRUC, *PTXWI_STRUC;
1995#else
1996typedef struct PACKED _TXWI_STRUC {
1997 // Word 0
1998 UINT32 FRAG:1; // 1 to inform TKIP engine this is a fragment.
1999 UINT32 MIMOps:1; // the remote peer is in dynamic MIMO-PS mode
2000 UINT32 CFACK:1;
2001 UINT32 TS:1;
2002
2003 UINT32 AMPDU:1;
2004 UINT32 MpduDensity:3;
2005 UINT32 txop:2; //FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
2006 UINT32 rsv:6;
2007
2008 UINT32 MCS:7;
2009 UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
2010 UINT32 ShortGI:1;
2011 UINT32 STBC:2; // 1: STBC support MCS =0-7, 2,3 : RESERVE
2012 UINT32 Ifs:1; //
2013 UINT32 rsv2:1;
2014 UINT32 TxBF:1; // 3*3
2015 UINT32 PHYMODE:2;
2016 // Word 1
2017 UINT32 ACK:1;
2018 UINT32 NSEQ:1;
2019 UINT32 BAWinSize:6;
2020 UINT32 WirelessCliID:8;
2021 UINT32 MPDUtotalByteCount:12;
2022 UINT32 PacketId:4;
2023 //Word2
2024 UINT32 IV;
2025 //Word3
2026 UINT32 EIV;
2027} TXWI_STRUC, *PTXWI_STRUC;
2028#endif
2029//
2030// Rx descriptor format, Rx Ring
2031//
2032#ifdef RT2860
2033#ifdef RT_BIG_ENDIAN
2034typedef struct PACKED _RXD_STRUC {
2035 // Word 0
2036 UINT32 SDP0;
2037 // Word 1
2038 UINT32 DDONE:1;
2039 UINT32 LS0:1;
2040 UINT32 SDL0:14;
2041 UINT32 Rsv:2;
2042 UINT32 SDL1:14;
2043 // Word 2
2044 UINT32 SDP1;
2045 // Word 3
2046 UINT32 Rsv1:13;
2047 UINT32 PlcpRssil:1;// To be moved
2048 UINT32 PlcpSignal:1; // To be moved
2049 UINT32 Decrypted:1; // this frame is being decrypted.
2050 UINT32 AMPDU:1;
2051 UINT32 L2PAD:1;
2052 UINT32 RSSI:1;
2053 UINT32 HTC:1;
2054 UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header. obsolete.
2055 UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
2056 UINT32 Crc:1; // 1: CRC error
2057 UINT32 MyBss:1; // 1: this frame belongs to the same BSSID
2058 UINT32 Bcast:1; // 1: this is a broadcast frame
2059 UINT32 Mcast:1; // 1: this is a multicast frame
2060 UINT32 U2M:1; // 1: this RX frame is unicast to me
2061 UINT32 FRAG:1;
2062 UINT32 NULLDATA:1;
2063 UINT32 DATA:1;
2064 UINT32 BA:1;
2065
2066} RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
2067#else
2068typedef struct PACKED _RXD_STRUC {
2069 // Word 0
2070 UINT32 SDP0;
2071 // Word 1
2072 UINT32 SDL1:14;
2073 UINT32 Rsv:2;
2074 UINT32 SDL0:14;
2075 UINT32 LS0:1;
2076 UINT32 DDONE:1;
2077 // Word 2
2078 UINT32 SDP1;
2079 // Word 3
2080 UINT32 BA:1;
2081 UINT32 DATA:1;
2082 UINT32 NULLDATA:1;
2083 UINT32 FRAG:1;
2084 UINT32 U2M:1; // 1: this RX frame is unicast to me
2085 UINT32 Mcast:1; // 1: this is a multicast frame
2086 UINT32 Bcast:1; // 1: this is a broadcast frame
2087 UINT32 MyBss:1; // 1: this frame belongs to the same BSSID
2088 UINT32 Crc:1; // 1: CRC error
2089 UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
2090 UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header.
2091 UINT32 HTC:1;
2092 UINT32 RSSI:1;
2093 UINT32 L2PAD:1;
2094 UINT32 AMPDU:1;
2095 UINT32 Decrypted:1; // this frame is being decrypted.
2096 UINT32 PlcpSignal:1; // To be moved
2097 UINT32 PlcpRssil:1;// To be moved
2098 UINT32 Rsv1:13;
2099} RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
2100#endif
2101#endif // RT2860 //
2102//
2103// RXWI wireless information format, in PBF. invisible in driver.
2104//
2105#ifdef RT_BIG_ENDIAN
2106typedef struct PACKED _RXWI_STRUC {
2107 // Word 0
2108 UINT32 TID:4;
2109 UINT32 MPDUtotalByteCount:12;
2110 UINT32 UDF:3;
2111 UINT32 BSSID:3;
2112 UINT32 KeyIndex:2;
2113 UINT32 WirelessCliID:8;
2114 // Word 1
2115 UINT32 PHYMODE:2; // 1: this RX frame is unicast to me
2116 UINT32 rsv:3;
2117 UINT32 STBC:2;
2118 UINT32 ShortGI:1;
2119 UINT32 BW:1;
2120 UINT32 MCS:7;
2121 UINT32 SEQUENCE:12;
2122 UINT32 FRAG:4;
2123 // Word 2
2124 UINT32 rsv1:8;
2125 UINT32 RSSI2:8;
2126 UINT32 RSSI1:8;
2127 UINT32 RSSI0:8;
2128 // Word 3
2129 UINT32 rsv2:16;
2130 UINT32 SNR1:8;
2131 UINT32 SNR0:8;
2132} RXWI_STRUC, *PRXWI_STRUC;
2133#else
2134typedef struct PACKED _RXWI_STRUC {
2135 // Word 0
2136 UINT32 WirelessCliID:8;
2137 UINT32 KeyIndex:2;
2138 UINT32 BSSID:3;
2139 UINT32 UDF:3;
2140 UINT32 MPDUtotalByteCount:12;
2141 UINT32 TID:4;
2142 // Word 1
2143 UINT32 FRAG:4;
2144 UINT32 SEQUENCE:12;
2145 UINT32 MCS:7;
2146 UINT32 BW:1;
2147 UINT32 ShortGI:1;
2148 UINT32 STBC:2;
2149 UINT32 rsv:3;
2150 UINT32 PHYMODE:2; // 1: this RX frame is unicast to me
2151 //Word2
2152 UINT32 RSSI0:8;
2153 UINT32 RSSI1:8;
2154 UINT32 RSSI2:8;
2155 UINT32 rsv1:8;
2156 //Word3
2157 UINT32 SNR0:8;
2158 UINT32 SNR1:8;
2159 UINT32 rsv2:16;
2160} RXWI_STRUC, *PRXWI_STRUC;
2161#endif
2162
2163
2164// =================================================================================
2165// HOST-MCU communication data structure
2166// =================================================================================
2167
2168//
2169// H2M_MAILBOX_CSR: Host-to-MCU Mailbox
2170//
2171#ifdef RT_BIG_ENDIAN
2172typedef union _H2M_MAILBOX_STRUC {
2173 struct {
2174 UINT32 Owner:8;
2175 UINT32 CmdToken:8; // 0xff tells MCU not to report CmdDoneInt after excuting the command
2176 UINT32 HighByte:8;
2177 UINT32 LowByte:8;
2178 } field;
2179 UINT32 word;
2180} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
2181#else
2182typedef union _H2M_MAILBOX_STRUC {
2183 struct {
2184 UINT32 LowByte:8;
2185 UINT32 HighByte:8;
2186 UINT32 CmdToken:8;
2187 UINT32 Owner:8;
2188 } field;
2189 UINT32 word;
2190} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
2191#endif
2192
2193//
2194// M2H_CMD_DONE_CSR: MCU-to-Host command complete indication
2195//
2196#ifdef RT_BIG_ENDIAN
2197typedef union _M2H_CMD_DONE_STRUC {
2198 struct {
2199 UINT32 CmdToken3;
2200 UINT32 CmdToken2;
2201 UINT32 CmdToken1;
2202 UINT32 CmdToken0;
2203 } field;
2204 UINT32 word;
2205} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
2206#else
2207typedef union _M2H_CMD_DONE_STRUC {
2208 struct {
2209 UINT32 CmdToken0;
2210 UINT32 CmdToken1;
2211 UINT32 CmdToken2;
2212 UINT32 CmdToken3;
2213 } field;
2214 UINT32 word;
2215} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
2216#endif
2217
2218
2219
2220//
2221// MCU_LEDCS: MCU LED Control Setting.
2222//
2223#ifdef RT_BIG_ENDIAN
2224typedef union _MCU_LEDCS_STRUC {
2225 struct {
2226 UCHAR Polarity:1;
2227 UCHAR LedMode:7;
2228 } field;
2229 UCHAR word;
2230} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
2231#else
2232typedef union _MCU_LEDCS_STRUC {
2233 struct {
2234 UCHAR LedMode:7;
2235 UCHAR Polarity:1;
2236 } field;
2237 UCHAR word;
2238} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
2239#endif
2240// =================================================================================
2241// Register format
2242// =================================================================================
2243
2244
2245
2246//NAV_TIME_CFG :NAV
2247#ifdef RT_BIG_ENDIAN
2248typedef union _NAV_TIME_CFG_STRUC {
2249 struct {
2250 USHORT rsv:6;
2251 USHORT ZeroSifs:1; // Applied zero SIFS timer after OFDM RX 0: disable
2252 USHORT Eifs:9; // in unit of 1-us
2253 UCHAR SlotTime; // in unit of 1-us
2254 UCHAR Sifs; // in unit of 1-us
2255 } field;
2256 UINT32 word;
2257} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
2258#else
2259typedef union _NAV_TIME_CFG_STRUC {
2260 struct {
2261 UCHAR Sifs; // in unit of 1-us
2262 UCHAR SlotTime; // in unit of 1-us
2263 USHORT Eifs:9; // in unit of 1-us
2264 USHORT ZeroSifs:1; // Applied zero SIFS timer after OFDM RX 0: disable
2265 USHORT rsv:6;
2266 } field;
2267 UINT32 word;
2268} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
2269#endif
2270
2271
2272
2273
2274
2275//
2276// RX_FILTR_CFG: /RX configuration register
2277//
2278#ifdef RT_BIG_ENDIAN
2279typedef union RX_FILTR_CFG_STRUC {
2280 struct {
2281 UINT32 :15;
2282 UINT32 DropRsvCntlType:1;
2283
2284 UINT32 DropBAR:1; //
2285 UINT32 DropBA:1; //
2286 UINT32 DropPsPoll:1; // Drop Ps-Poll
2287 UINT32 DropRts:1; // Drop Ps-Poll
2288
2289 UINT32 DropCts:1; // Drop Ps-Poll
2290 UINT32 DropAck:1; // Drop Ps-Poll
2291 UINT32 DropCFEnd:1; // Drop Ps-Poll
2292 UINT32 DropCFEndAck:1; // Drop Ps-Poll
2293
2294 UINT32 DropDuplicate:1; // Drop duplicate frame
2295 UINT32 DropBcast:1; // Drop broadcast frames
2296 UINT32 DropMcast:1; // Drop multicast frames
2297 UINT32 DropVerErr:1; // Drop version error frame
2298
2299 UINT32 DropNotMyBSSID:1; // Drop fram ToDs bit is true
2300 UINT32 DropNotToMe:1; // Drop not to me unicast frame
2301 UINT32 DropPhyErr:1; // Drop physical error
2302 UINT32 DropCRCErr:1; // Drop CRC error
2303 } field;
2304 UINT32 word;
2305} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
2306#else
2307typedef union _RX_FILTR_CFG_STRUC {
2308 struct {
2309 UINT32 DropCRCErr:1; // Drop CRC error
2310 UINT32 DropPhyErr:1; // Drop physical error
2311 UINT32 DropNotToMe:1; // Drop not to me unicast frame
2312 UINT32 DropNotMyBSSID:1; // Drop fram ToDs bit is true
2313
2314 UINT32 DropVerErr:1; // Drop version error frame
2315 UINT32 DropMcast:1; // Drop multicast frames
2316 UINT32 DropBcast:1; // Drop broadcast frames
2317 UINT32 DropDuplicate:1; // Drop duplicate frame
2318
2319 UINT32 DropCFEndAck:1; // Drop Ps-Poll
2320 UINT32 DropCFEnd:1; // Drop Ps-Poll
2321 UINT32 DropAck:1; // Drop Ps-Poll
2322 UINT32 DropCts:1; // Drop Ps-Poll
2323
2324 UINT32 DropRts:1; // Drop Ps-Poll
2325 UINT32 DropPsPoll:1; // Drop Ps-Poll
2326 UINT32 DropBA:1; //
2327 UINT32 DropBAR:1; //
2328
2329 UINT32 DropRsvCntlType:1;
2330 UINT32 :15;
2331 } field;
2332 UINT32 word;
2333} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
2334#endif
2335
2336
2337
2338
2339//
2340// PHY_CSR4: RF serial control register
2341//
2342#ifdef RT_BIG_ENDIAN
2343typedef union _PHY_CSR4_STRUC {
2344 struct {
2345 UINT32 Busy:1; // 1: ASIC is busy execute RF programming.
2346 UINT32 PLL_LD:1; // RF PLL_LD status
2347 UINT32 IFSelect:1; // 1: select IF to program, 0: select RF to program
2348 UINT32 NumberOfBits:5; // Number of bits used in RFRegValue (I:20, RFMD:22)
2349 UINT32 RFRegValue:24; // Register value (include register id) serial out to RF/IF chip.
2350 } field;
2351 UINT32 word;
2352} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
2353#else
2354typedef union _PHY_CSR4_STRUC {
2355 struct {
2356 UINT32 RFRegValue:24; // Register value (include register id) serial out to RF/IF chip.
2357 UINT32 NumberOfBits:5; // Number of bits used in RFRegValue (I:20, RFMD:22)
2358 UINT32 IFSelect:1; // 1: select IF to program, 0: select RF to program
2359 UINT32 PLL_LD:1; // RF PLL_LD status
2360 UINT32 Busy:1; // 1: ASIC is busy execute RF programming.
2361 } field;
2362 UINT32 word;
2363} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
2364#endif
2365
2366
2367//
2368// SEC_CSR5: shared key table security mode register
2369//
2370#ifdef RT_BIG_ENDIAN
2371typedef union _SEC_CSR5_STRUC {
2372 struct {
2373 UINT32 :1;
2374 UINT32 Bss3Key3CipherAlg:3;
2375 UINT32 :1;
2376 UINT32 Bss3Key2CipherAlg:3;
2377 UINT32 :1;
2378 UINT32 Bss3Key1CipherAlg:3;
2379 UINT32 :1;
2380 UINT32 Bss3Key0CipherAlg:3;
2381 UINT32 :1;
2382 UINT32 Bss2Key3CipherAlg:3;
2383 UINT32 :1;
2384 UINT32 Bss2Key2CipherAlg:3;
2385 UINT32 :1;
2386 UINT32 Bss2Key1CipherAlg:3;
2387 UINT32 :1;
2388 UINT32 Bss2Key0CipherAlg:3;
2389 } field;
2390 UINT32 word;
2391} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
2392#else
2393typedef union _SEC_CSR5_STRUC {
2394 struct {
2395 UINT32 Bss2Key0CipherAlg:3;
2396 UINT32 :1;
2397 UINT32 Bss2Key1CipherAlg:3;
2398 UINT32 :1;
2399 UINT32 Bss2Key2CipherAlg:3;
2400 UINT32 :1;
2401 UINT32 Bss2Key3CipherAlg:3;
2402 UINT32 :1;
2403 UINT32 Bss3Key0CipherAlg:3;
2404 UINT32 :1;
2405 UINT32 Bss3Key1CipherAlg:3;
2406 UINT32 :1;
2407 UINT32 Bss3Key2CipherAlg:3;
2408 UINT32 :1;
2409 UINT32 Bss3Key3CipherAlg:3;
2410 UINT32 :1;
2411 } field;
2412 UINT32 word;
2413} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
2414#endif
2415
2416
2417//
2418// HOST_CMD_CSR: For HOST to interrupt embedded processor
2419//
2420#ifdef RT_BIG_ENDIAN
2421typedef union _HOST_CMD_CSR_STRUC {
2422 struct {
2423 UINT32 Rsv:24;
2424 UINT32 HostCommand:8;
2425 } field;
2426 UINT32 word;
2427} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
2428#else
2429typedef union _HOST_CMD_CSR_STRUC {
2430 struct {
2431 UINT32 HostCommand:8;
2432 UINT32 Rsv:24;
2433 } field;
2434 UINT32 word;
2435} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
2436#endif
2437
2438
2439//
2440// AIFSN_CSR: AIFSN for each EDCA AC
2441//
2442
2443
2444
2445//
2446// E2PROM_CSR: EEPROM control register
2447//
2448#ifdef RT_BIG_ENDIAN
2449typedef union _E2PROM_CSR_STRUC {
2450 struct {
2451 UINT32 Rsvd:25;
2452 UINT32 LoadStatus:1; // 1:loading, 0:done
2453 UINT32 Type:1; // 1: 93C46, 0:93C66
2454 UINT32 EepromDO:1;
2455 UINT32 EepromDI:1;
2456 UINT32 EepromCS:1;
2457 UINT32 EepromSK:1;
2458 UINT32 Reload:1; // Reload EEPROM content, write one to reload, self-cleared.
2459 } field;
2460 UINT32 word;
2461} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
2462#else
2463typedef union _E2PROM_CSR_STRUC {
2464 struct {
2465 UINT32 Reload:1; // Reload EEPROM content, write one to reload, self-cleared.
2466 UINT32 EepromSK:1;
2467 UINT32 EepromCS:1;
2468 UINT32 EepromDI:1;
2469 UINT32 EepromDO:1;
2470 UINT32 Type:1; // 1: 93C46, 0:93C66
2471 UINT32 LoadStatus:1; // 1:loading, 0:done
2472 UINT32 Rsvd:25;
2473 } field;
2474 UINT32 word;
2475} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
2476#endif
2477
2478
2479// -------------------------------------------------------------------
2480// E2PROM data layout
2481// -------------------------------------------------------------------
2482
2483//
2484// EEPROM antenna select format
2485//
2486#ifdef RT_BIG_ENDIAN
2487typedef union _EEPROM_ANTENNA_STRUC {
2488 struct {
2489 USHORT Rsv:4;
2490 USHORT RfIcType:4; // see E2PROM document
2491 USHORT TxPath:4; // 1: 1T, 2: 2T
2492 USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R
2493 } field;
2494 USHORT word;
2495} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
2496#else
2497typedef union _EEPROM_ANTENNA_STRUC {
2498 struct {
2499 USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R
2500 USHORT TxPath:4; // 1: 1T, 2: 2T
2501 USHORT RfIcType:4; // see E2PROM document
2502 USHORT Rsv:4;
2503 } field;
2504 USHORT word;
2505} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
2506#endif
2507
2508#ifdef RT_BIG_ENDIAN
2509typedef union _EEPROM_NIC_CINFIG2_STRUC {
2510 struct {
2511 USHORT Rsv2:6; // must be 0
2512 USHORT BW40MAvailForA:1; // 0:enable, 1:disable
2513 USHORT BW40MAvailForG:1; // 0:enable, 1:disable
2514 USHORT EnableWPSPBC:1; // WPS PBC Control bit
2515 USHORT BW40MSidebandForA:1;
2516 USHORT BW40MSidebandForG:1;
2517 USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable
2518 USHORT ExternalLNAForA:1; // external LNA enable for 5G
2519 USHORT ExternalLNAForG:1; // external LNA enable for 2.4G
2520 USHORT DynamicTxAgcControl:1; //
2521 USHORT HardwareRadioControl:1; // Whether RF is controlled by driver or HW. 1:enable hw control, 0:disable
2522 } field;
2523 USHORT word;
2524} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
2525#else
2526typedef union _EEPROM_NIC_CINFIG2_STRUC {
2527 struct {
2528 USHORT HardwareRadioControl:1; // 1:enable, 0:disable
2529 USHORT DynamicTxAgcControl:1; //
2530 USHORT ExternalLNAForG:1; //
2531 USHORT ExternalLNAForA:1; // external LNA enable for 2.4G
2532 USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable
2533 USHORT BW40MSidebandForG:1;
2534 USHORT BW40MSidebandForA:1;
2535 USHORT EnableWPSPBC:1; // WPS PBC Control bit
2536 USHORT BW40MAvailForG:1; // 0:enable, 1:disable
2537 USHORT BW40MAvailForA:1; // 0:enable, 1:disable
2538 USHORT Rsv2:6; // must be 0
2539 } field;
2540 USHORT word;
2541} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
2542#endif
2543
2544//
2545// TX_PWR Value valid range 0xFA(-6) ~ 0x24(36)
2546//
2547#ifdef RT_BIG_ENDIAN
2548typedef union _EEPROM_TX_PWR_STRUC {
2549 struct {
2550 CHAR Byte1; // High Byte
2551 CHAR Byte0; // Low Byte
2552 } field;
2553 USHORT word;
2554} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
2555#else
2556typedef union _EEPROM_TX_PWR_STRUC {
2557 struct {
2558 CHAR Byte0; // Low Byte
2559 CHAR Byte1; // High Byte
2560 } field;
2561 USHORT word;
2562} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
2563#endif
2564
2565#ifdef RT_BIG_ENDIAN
2566typedef union _EEPROM_VERSION_STRUC {
2567 struct {
2568 UCHAR Version; // High Byte
2569 UCHAR FaeReleaseNumber; // Low Byte
2570 } field;
2571 USHORT word;
2572} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
2573#else
2574typedef union _EEPROM_VERSION_STRUC {
2575 struct {
2576 UCHAR FaeReleaseNumber; // Low Byte
2577 UCHAR Version; // High Byte
2578 } field;
2579 USHORT word;
2580} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
2581#endif
2582
2583#ifdef RT_BIG_ENDIAN
2584typedef union _EEPROM_LED_STRUC {
2585 struct {
2586 USHORT Rsvd:3; // Reserved
2587 USHORT LedMode:5; // Led mode.
2588 USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting.
2589 USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting.
2590 USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting.
2591 USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting.
2592 USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting.
2593 USHORT PolarityACT:1; // Polarity ACT setting.
2594 USHORT PolarityRDY_A:1; // Polarity RDY_A setting.
2595 USHORT PolarityRDY_G:1; // Polarity RDY_G setting.
2596 } field;
2597 USHORT word;
2598} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
2599#else
2600typedef union _EEPROM_LED_STRUC {
2601 struct {
2602 USHORT PolarityRDY_G:1; // Polarity RDY_G setting.
2603 USHORT PolarityRDY_A:1; // Polarity RDY_A setting.
2604 USHORT PolarityACT:1; // Polarity ACT setting.
2605 USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting.
2606 USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting.
2607 USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting.
2608 USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting.
2609 USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting.
2610 USHORT LedMode:5; // Led mode.
2611 USHORT Rsvd:3; // Reserved
2612 } field;
2613 USHORT word;
2614} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
2615#endif
2616
2617#ifdef RT_BIG_ENDIAN
2618typedef union _EEPROM_TXPOWER_DELTA_STRUC {
2619 struct {
2620 UCHAR TxPowerEnable:1;// Enable
2621 UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value
2622 UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4)
2623 } field;
2624 UCHAR value;
2625} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
2626#else
2627typedef union _EEPROM_TXPOWER_DELTA_STRUC {
2628 struct {
2629 UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4)
2630 UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value
2631 UCHAR TxPowerEnable:1;// Enable
2632 } field;
2633 UCHAR value;
2634} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
2635#endif
2636
2637//
2638// QOS_CSR0: TXOP holder address0 register
2639//
2640#ifdef RT_BIG_ENDIAN
2641typedef union _QOS_CSR0_STRUC {
2642 struct {
2643 UCHAR Byte3; // MAC address byte 3
2644 UCHAR Byte2; // MAC address byte 2
2645 UCHAR Byte1; // MAC address byte 1
2646 UCHAR Byte0; // MAC address byte 0
2647 } field;
2648 UINT32 word;
2649} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
2650#else
2651typedef union _QOS_CSR0_STRUC {
2652 struct {
2653 UCHAR Byte0; // MAC address byte 0
2654 UCHAR Byte1; // MAC address byte 1
2655 UCHAR Byte2; // MAC address byte 2
2656 UCHAR Byte3; // MAC address byte 3
2657 } field;
2658 UINT32 word;
2659} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
2660#endif
2661
2662//
2663// QOS_CSR1: TXOP holder address1 register
2664//
2665#ifdef RT_BIG_ENDIAN
2666typedef union _QOS_CSR1_STRUC {
2667 struct {
2668 UCHAR Rsvd1;
2669 UCHAR Rsvd0;
2670 UCHAR Byte5; // MAC address byte 5
2671 UCHAR Byte4; // MAC address byte 4
2672 } field;
2673 UINT32 word;
2674} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
2675#else
2676typedef union _QOS_CSR1_STRUC {
2677 struct {
2678 UCHAR Byte4; // MAC address byte 4
2679 UCHAR Byte5; // MAC address byte 5
2680 UCHAR Rsvd0;
2681 UCHAR Rsvd1;
2682 } field;
2683 UINT32 word;
2684} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
2685#endif
2686
2687#define RF_CSR_CFG 0x500
2688#ifdef RT_BIG_ENDIAN
2689typedef union _RF_CSR_CFG_STRUC {
2690 struct {
2691 UINT Rsvd1:14; // Reserved
2692 UINT RF_CSR_KICK:1; // kick RF register read/write
2693 UINT RF_CSR_WR:1; // 0: read 1: write
2694 UINT Rsvd2:3; // Reserved
2695 UINT TESTCSR_RFACC_REGNUM:5; // RF register ID
2696 UINT RF_CSR_DATA:8; // DATA
2697 } field;
2698 UINT word;
2699} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
2700#else
2701typedef union _RF_CSR_CFG_STRUC {
2702 struct {
2703 UINT RF_CSR_DATA:8; // DATA
2704 UINT TESTCSR_RFACC_REGNUM:5; // RF register ID
2705 UINT Rsvd2:3; // Reserved
2706 UINT RF_CSR_WR:1; // 0: read 1: write
2707 UINT RF_CSR_KICK:1; // kick RF register read/write
2708 UINT Rsvd1:14; // Reserved
2709 } field;
2710 UINT word;
2711} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
2712#endif
2713
2714#endif // __RT28XX_H__
diff --git a/drivers/staging/rt2860/rt_ate.c b/drivers/staging/rt2860/rt_ate.c
new file mode 100644
index 00000000000..2f07db565c3
--- /dev/null
+++ b/drivers/staging/rt2860/rt_ate.c
@@ -0,0 +1,6025 @@
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 RALINK_ATE
31UCHAR 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
32extern RTMP_RF_REGS RF2850RegTable[];
33extern UCHAR NUM_OF_2850_CHNL;
34
35static CHAR CCKRateTable[] = {0, 1, 2, 3, 8, 9, 10, 11, -1}; /* CCK Mode. */
36static CHAR OFDMRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, -1}; /* OFDM Mode. */
37static CHAR HTMIXRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}; /* HT Mix Mode. */
38
39static INT TxDmaBusy(
40 IN PRTMP_ADAPTER pAd);
41
42static INT RxDmaBusy(
43 IN PRTMP_ADAPTER pAd);
44
45static VOID RtmpDmaEnable(
46 IN PRTMP_ADAPTER pAd,
47 IN INT Enable);
48
49static VOID BbpSoftReset(
50 IN PRTMP_ADAPTER pAd);
51
52static VOID RtmpRfIoWrite(
53 IN PRTMP_ADAPTER pAd);
54
55static INT ATESetUpFrame(
56 IN PRTMP_ADAPTER pAd,
57 IN UINT32 TxIdx);
58
59static INT ATETxPwrHandler(
60 IN PRTMP_ADAPTER pAd,
61 IN char index);
62
63static INT ATECmdHandler(
64 IN PRTMP_ADAPTER pAd,
65 IN PUCHAR arg);
66
67static int CheckMCSValid(
68 IN UCHAR Mode,
69 IN UCHAR Mcs);
70
71#ifdef RT2860
72static VOID ATEWriteTxWI(
73 IN PRTMP_ADAPTER pAd,
74 IN PTXWI_STRUC pOutTxWI,
75 IN BOOLEAN FRAG,
76 IN BOOLEAN CFACK,
77 IN BOOLEAN InsTimestamp,
78 IN BOOLEAN AMPDU,
79 IN BOOLEAN Ack,
80 IN BOOLEAN NSeq, // HW new a sequence.
81 IN UCHAR BASize,
82 IN UCHAR WCID,
83 IN ULONG Length,
84 IN UCHAR PID,
85 IN UCHAR TID,
86 IN UCHAR TxRate,
87 IN UCHAR Txopmode,
88 IN BOOLEAN CfAck,
89 IN HTTRANSMIT_SETTING *pTransmit);
90#endif // RT2860 //
91
92
93static VOID SetJapanFilter(
94 IN PRTMP_ADAPTER pAd);
95
96/*=========================end of prototype=========================*/
97
98#ifdef RT2860
99static INT TxDmaBusy(
100 IN PRTMP_ADAPTER pAd)
101{
102 INT result;
103 WPDMA_GLO_CFG_STRUC GloCfg;
104
105 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
106 if (GloCfg.field.TxDMABusy)
107 result = 1;
108 else
109 result = 0;
110
111 return result;
112}
113
114static INT RxDmaBusy(
115 IN PRTMP_ADAPTER pAd)
116{
117 INT result;
118 WPDMA_GLO_CFG_STRUC GloCfg;
119
120 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
121 if (GloCfg.field.RxDMABusy)
122 result = 1;
123 else
124 result = 0;
125
126 return result;
127}
128
129static VOID RtmpDmaEnable(
130 IN PRTMP_ADAPTER pAd,
131 IN INT Enable)
132{
133 BOOLEAN value;
134 ULONG WaitCnt;
135 WPDMA_GLO_CFG_STRUC GloCfg;
136
137 value = Enable > 0 ? 1 : 0;
138
139 // check DMA is in busy mode.
140 WaitCnt = 0;
141 while (TxDmaBusy(pAd) || RxDmaBusy(pAd))
142 {
143 RTMPusecDelay(10);
144 if (WaitCnt++ > 100)
145 break;
146 }
147
148 RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
149 GloCfg.field.EnableTxDMA = value;
150 GloCfg.field.EnableRxDMA = value;
151 RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings
152 RTMPusecDelay(5000);
153
154 return;
155}
156#endif // RT2860 //
157
158
159static VOID BbpSoftReset(
160 IN PRTMP_ADAPTER pAd)
161{
162 UCHAR BbpData = 0;
163
164 // Soft reset, set BBP R21 bit0=1->0
165 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
166 BbpData |= 0x00000001; //set bit0=1
167 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
168
169 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
170 BbpData &= ~(0x00000001); //set bit0=0
171 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
172
173 return;
174}
175
176static VOID RtmpRfIoWrite(
177 IN PRTMP_ADAPTER pAd)
178{
179 // Set RF value 1's set R3[bit2] = [0]
180 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
181 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
182 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
183 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
184
185 RTMPusecDelay(200);
186
187 // Set RF value 2's set R3[bit2] = [1]
188 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
189 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
190 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
191 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
192
193 RTMPusecDelay(200);
194
195 // Set RF value 3's set R3[bit2] = [0]
196 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
197 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
198 RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
199 RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
200
201 return;
202}
203
204static int CheckMCSValid(
205 UCHAR Mode,
206 UCHAR Mcs)
207{
208 int i;
209 PCHAR pRateTab;
210
211 switch(Mode)
212 {
213 case 0:
214 pRateTab = CCKRateTable;
215 break;
216 case 1:
217 pRateTab = OFDMRateTable;
218 break;
219 case 2:
220 case 3:
221 pRateTab = HTMIXRateTable;
222 break;
223 default:
224 ATEDBGPRINT(RT_DEBUG_ERROR, ("unrecognizable Tx Mode %d\n", Mode));
225 return -1;
226 break;
227 }
228
229 i = 0;
230 while(pRateTab[i] != -1)
231 {
232 if (pRateTab[i] == Mcs)
233 return 0;
234 i++;
235 }
236
237 return -1;
238}
239
240#if 1
241static INT ATETxPwrHandler(
242 IN PRTMP_ADAPTER pAd,
243 IN char index)
244{
245 ULONG R;
246 CHAR TxPower;
247 UCHAR Bbp94 = 0;
248 BOOLEAN bPowerReduce = FALSE;
249
250#ifdef RALINK_28xx_QA
251 if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
252 {
253 /* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
254 ** are not synchronized.
255 */
256/*
257 pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
258 pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
259*/
260 return 0;
261 }
262 else
263#endif // RALINK_28xx_QA //
264 {
265 TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
266
267 if (pAd->ate.Channel <= 14)
268 {
269 if (TxPower > 31)
270 {
271 //
272 // R3, R4 can't large than 31 (0x24), 31 ~ 36 used by BBP 94
273 //
274 R = 31;
275 if (TxPower <= 36)
276 Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
277 }
278 else if (TxPower < 0)
279 {
280 //
281 // R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
282 //
283 R = 0;
284 if (TxPower >= -6)
285 Bbp94 = BBPR94_DEFAULT + TxPower;
286 }
287 else
288 {
289 // 0 ~ 31
290 R = (ULONG) TxPower;
291 Bbp94 = BBPR94_DEFAULT;
292 }
293
294 ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
295 }
296 else// 5.5 GHz
297 {
298 if (TxPower > 15)
299 {
300 //
301 // R3, R4 can't large than 15 (0x0F)
302 //
303 R = 15;
304 }
305 else if (TxPower < 0)
306 {
307 //
308 // R3, R4 can't less than 0
309 //
310 // -1 ~ -7
311 ASSERT((TxPower >= -7));
312 R = (ULONG)(TxPower + 7);
313 bPowerReduce = TRUE;
314 }
315 else
316 {
317 // 0 ~ 15
318 R = (ULONG) TxPower;
319 }
320
321 ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%lu)\n", __FUNCTION__, TxPower, R));
322 }
323
324 if (pAd->ate.Channel <= 14)
325 {
326 if (index == 0)
327 {
328 R = R << 9; // shift TX power control to correct RF(R3) register bit position
329 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
330 pAd->LatchRfRegs.R3 = R;
331 }
332 else
333 {
334 R = R << 6; // shift TX power control to correct RF(R4) register bit position
335 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
336 pAd->LatchRfRegs.R4 = R;
337 }
338 }
339 else// 5.5GHz
340 {
341 if (bPowerReduce == FALSE)
342 {
343 if (index == 0)
344 {
345 R = (R << 10) | (1 << 9); // shift TX power control to correct RF(R3) register bit position
346 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
347 pAd->LatchRfRegs.R3 = R;
348 }
349 else
350 {
351 R = (R << 7) | (1 << 6); // shift TX power control to correct RF(R4) register bit position
352 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
353 pAd->LatchRfRegs.R4 = R;
354 }
355 }
356 else
357 {
358 if (index == 0)
359 {
360 R = (R << 10); // shift TX power control to correct RF(R3) register bit position
361 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
362
363 /* Clear bit 9 of R3 to reduce 7dB. */
364 pAd->LatchRfRegs.R3 = (R & (~(1 << 9)));
365 }
366 else
367 {
368 R = (R << 7); // shift TX power control to correct RF(R4) register bit position
369 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
370
371 /* Clear bit 6 of R4 to reduce 7dB. */
372 pAd->LatchRfRegs.R4 = (R & (~(1 << 6)));
373 }
374 }
375 }
376
377 RtmpRfIoWrite(pAd);
378
379 return 0;
380 }
381}
382#else// 1 //
383static INT ATETxPwrHandler(
384 IN PRTMP_ADAPTER pAd,
385 IN char index)
386{
387 ULONG R;
388 CHAR TxPower;
389 UCHAR Bbp94 = 0;
390
391#ifdef RALINK_28xx_QA
392 if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
393 {
394 // TODO: how to get current TxPower0/1 from pAd->LatchRfRegs ?
395 /* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
396 ** are not synchronized.
397 */
398/*
399 pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
400 pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
401*/
402 return 0;
403 }
404 else
405#endif // RALINK_28xx_QA //
406 {
407 TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
408
409 if (TxPower > 31)
410 {
411 //
412 // R3, R4 can't large than 36 (0x24), 31 ~ 36 used by BBP 94
413 //
414 R = 31;
415 if (TxPower <= 36)
416 Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
417 }
418 else if (TxPower < 0)
419 {
420 //
421 // R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
422 //
423 R = 0;
424 if (TxPower >= -6)
425 Bbp94 = BBPR94_DEFAULT + TxPower;
426 }
427 else
428 {
429 // 0 ~ 31
430 R = (ULONG) TxPower;
431 Bbp94 = BBPR94_DEFAULT;
432 }
433
434 ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R3=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
435
436 if (pAd->ate.Channel <= 14)
437 {
438 if (index == 0)
439 {
440 R = R << 9; // shift TX power control to correct RF(R3) register bit position
441 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
442 pAd->LatchRfRegs.R3 = R;
443 }
444 else
445 {
446 R = R << 6; // shift TX power control to correct RF(R4) register bit position
447 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
448 pAd->LatchRfRegs.R4 = R;
449 }
450 }
451 else
452 {
453 if (index == 0)
454 {
455 R = (R << 10) | (1 << 9); // shift TX power control to correct RF(R3) register bit position
456 R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
457 pAd->LatchRfRegs.R3 = R;
458 }
459 else
460 {
461 R = (R << 7) | (1 << 6); // shift TX power control to correct RF(R4) register bit position
462 R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
463 pAd->LatchRfRegs.R4 = R;
464 }
465 }
466
467 RtmpRfIoWrite(pAd);
468
469 return 0;
470 }
471}
472#endif // 1 //
473/*
474 ==========================================================================
475 Description:
476 Set ATE operation mode to
477 0. ATESTART = Start ATE Mode
478 1. ATESTOP = Stop ATE Mode
479 2. TXCONT = Continuous Transmit
480 3. TXCARR = Transmit Carrier
481 4. TXFRAME = Transmit Frames
482 5. RXFRAME = Receive Frames
483#ifdef RALINK_28xx_QA
484 6. TXSTOP = Stop Any Type of Transmition
485 7. RXSTOP = Stop Receiving Frames
486#endif // RALINK_28xx_QA //
487 Return:
488 TRUE if all parameters are OK, FALSE otherwise
489 ==========================================================================
490*/
491#ifdef RT2860
492static INT ATECmdHandler(
493 IN PRTMP_ADAPTER pAd,
494 IN PUCHAR arg)
495{
496 UINT32 Value = 0;
497 UCHAR BbpData;
498 UINT32 MacData = 0;
499 PTXD_STRUC pTxD;
500 INT index;
501 UINT i=0, atemode;
502 PRXD_STRUC pRxD;
503 PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];
504#ifndef UCOS
505 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
506#endif // UCOS //
507#ifdef RT_BIG_ENDIAN
508 PTXD_STRUC pDestTxD;
509 TXD_STRUC TxD;
510#endif
511 ATEDBGPRINT(RT_DEBUG_TRACE, ("===> ATECmdHandler()\n"));
512
513 ATEAsicSwitchChannel(pAd);
514 AsicLockChannel(pAd, pAd->ate.Channel);
515
516 RTMPusecDelay(5000);
517
518 // read MAC_SYS_CTRL and backup MAC_SYS_CTRL value.
519 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
520
521 // Default value in BBP R22 is 0x0.
522 BbpData = 0;
523
524 // clean bit4 to stop continuous Tx production test.
525 MacData &= 0xFFFFFFEF;
526
527 if (!strcmp(arg, "ATESTART")) //Enter ATE mode and set Tx/Rx Idle
528 {
529 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: ATESTART\n"));
530
531#ifndef UCOS
532 // check if we have removed the firmware
533 if (!(ATE_ON(pAd)))
534 {
535 NICEraseFirmware(pAd);
536 }
537#endif // !UCOS //
538 atemode = pAd->ate.Mode;
539 pAd->ate.Mode = ATE_START;
540// pAd->ate.TxDoneCount = pAd->ate.TxCount;
541 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
542
543 if (atemode & ATE_TXCARR)
544 {
545 // No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
546 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
547 BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
548 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
549 }
550 else if (atemode & ATE_TXCARRSUPP)
551 {
552 // No Cont. TX set BBP R22 bit7=0
553 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
554 BbpData &= ~(1 << 7); //set bit7=0
555 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
556
557 // No Carrier Suppression set BBP R24 bit0=0
558 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
559 BbpData &= 0xFFFFFFFE; //clear bit0
560 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
561 }
562 // We should free some resource which was allocated when ATE_TXFRAME , ATE_STOP, and ATE_TXCONT.
563 else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
564 {
565 PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];
566
567 if (atemode & ATE_TXCONT)
568 {
569 // No Cont. TX set BBP R22 bit7=0
570 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
571 BbpData &= ~(1 << 7); //set bit7=0
572 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
573 }
574 // Abort Tx, Rx DMA.
575 RtmpDmaEnable(pAd, 0);
576 for (i=0; i<TX_RING_SIZE; i++)
577 {
578 PNDIS_PACKET pPacket;
579
580#ifndef RT_BIG_ENDIAN
581 pTxD = (PTXD_STRUC)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
582#else
583 pDestTxD = (PTXD_STRUC)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
584 TxD = *pDestTxD;
585 pTxD = &TxD;
586 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
587#endif
588 pTxD->DMADONE = 0;
589 pPacket = pTxRing->Cell[i].pNdisPacket;
590 if (pPacket)
591 {
592 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
593 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
594 }
595 //Always assign pNdisPacket as NULL after clear
596 pTxRing->Cell[i].pNdisPacket = NULL;
597
598 pPacket = pTxRing->Cell[i].pNextNdisPacket;
599 if (pPacket)
600 {
601 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
602 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
603 }
604 //Always assign pNextNdisPacket as NULL after clear
605 pTxRing->Cell[i].pNextNdisPacket = NULL;
606#ifdef RT_BIG_ENDIAN
607 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
608 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
609#endif
610 }
611 // Start Tx, RX DMA
612 RtmpDmaEnable(pAd, 1);
613 }
614 // reset Rx statistics.
615 pAd->ate.LastSNR0 = 0;
616 pAd->ate.LastSNR1 = 0;
617 pAd->ate.LastRssi0 = 0;
618 pAd->ate.LastRssi1 = 0;
619 pAd->ate.LastRssi2 = 0;
620 pAd->ate.AvgRssi0 = 0;
621 pAd->ate.AvgRssi1 = 0;
622 pAd->ate.AvgRssi2 = 0;
623 pAd->ate.AvgRssi0X8 = 0;
624 pAd->ate.AvgRssi1X8 = 0;
625 pAd->ate.AvgRssi2X8 = 0;
626 pAd->ate.NumOfAvgRssiSample = 0;
627
628#ifdef RALINK_28xx_QA
629 // Tx frame
630 pAd->ate.bQATxStart = FALSE;
631 pAd->ate.bQARxStart = FALSE;
632 pAd->ate.seq = 0;
633
634 // counters
635 pAd->ate.U2M = 0;
636 pAd->ate.OtherData = 0;
637 pAd->ate.Beacon = 0;
638 pAd->ate.OtherCount = 0;
639 pAd->ate.TxAc0 = 0;
640 pAd->ate.TxAc1 = 0;
641 pAd->ate.TxAc2 = 0;
642 pAd->ate.TxAc3 = 0;
643 pAd->ate.TxHCCA = 0;
644 pAd->ate.TxMgmt = 0;
645 pAd->ate.RSSI0 = 0;
646 pAd->ate.RSSI1 = 0;
647 pAd->ate.RSSI2 = 0;
648 pAd->ate.SNR0 = 0;
649 pAd->ate.SNR1 = 0;
650
651 // control
652 pAd->ate.TxDoneCount = 0;
653 pAd->ate.TxStatus = 0; // task Tx status // 0 --> task is idle, 1 --> task is running
654#endif // RALINK_28xx_QA //
655
656 // Soft reset BBP.
657 BbpSoftReset(pAd);
658
659
660#ifdef CONFIG_STA_SUPPORT
661 //
662 // LinkDown() has "AsicDisableSync();" and "RTMP_BBP_IO_R/W8_BY_REG_ID();" inside.
663 //
664// LinkDown(pAd, FALSE);
665// AsicEnableBssSync(pAd);
666#ifndef UCOS
667 netif_stop_queue(pAd->net_dev);
668#endif // !UCOS //
669 //
670 // If we skip "LinkDown()", we should disable protection
671 // to prevent from sending out RTS or CTS-to-self.
672 //
673 ATEDisableAsicProtect(pAd);
674 RTMPStationStop(pAd);
675#endif // CONFIG_STA_SUPPORT //
676
677 /* Disable Tx */
678 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
679 Value &= ~(1 << 2);
680 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
681
682 /* Disable Rx */
683 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
684 Value &= ~(1 << 3);
685 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
686 }
687 else if (!strcmp(arg, "ATESTOP"))
688 {
689 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: ATESTOP\n"));
690
691 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
692 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); // recover the MAC_SYS_CTRL register back.
693
694 // Disable Tx, Rx
695 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
696 Value &= (0xfffffff3);
697 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
698
699 // Abort Tx, RX DMA.
700 RtmpDmaEnable(pAd, 0);
701
702#ifndef UCOS
703 pAd->ate.bFWLoading = TRUE;
704 Status = NICLoadFirmware(pAd);
705 if (Status != NDIS_STATUS_SUCCESS)
706 {
707 ATEDBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
708 return FALSE;
709 }
710#endif // !UCOS //
711 pAd->ate.Mode = ATE_STOP;
712
713
714#ifdef CONFIG_STA_SUPPORT
715 //
716 // Even the firmware has been loaded,
717 // we still could use ATE_BBP_IO_READ8_BY_REG_ID().
718 // But this is not suggested.
719 //
720 BbpSoftReset(pAd);
721#endif // CONFIG_STA_SUPPORT //
722
723 NICDisableInterrupt(pAd);
724
725 NICInitializeAdapter(pAd, TRUE);
726
727
728 // Reinitialize Rx Ring before Rx DMA is enabled.
729 // The nightmare of >>>RxCoherent<<< was gone !
730 for (index = 0; index < RX_RING_SIZE; index++)
731 {
732 pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa;
733 pRxD->DDONE = 0;
734 }
735
736 // We should read EEPROM for all cases.
737 NICReadEEPROMParameters(pAd, NULL);
738 NICInitAsicFromEEPROM(pAd);
739
740 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
741 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
742
743 //
744 // Enable Interrupt
745 //
746
747 //
748 // These steps are only for APAutoSelectChannel().
749 //
750#if 0
751 //pAd->bStaFifoTest = TRUE;
752 pAd->int_enable_reg = ((DELAYINTMASK) | (RxINT|TxDataInt|TxMgmtInt)) & ~(0x03);
753 pAd->int_disable_mask = 0;
754 pAd->int_pending = 0;
755#endif
756 RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff); // clear garbage interrupts
757 NICEnableInterrupt(pAd);
758
759
760/*=========================================================================*/
761 /* restore RX_FILTR_CFG */
762#ifdef CONFIG_STA_SUPPORT
763 /* restore RX_FILTR_CFG due to that QA maybe set it to 0x3 */
764 RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL);
765#endif // CONFIG_STA_SUPPORT //
766/*=========================================================================*/
767
768 // Enable Tx
769 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
770 Value |= (1 << 2);
771 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
772
773 // Enable Tx, Rx DMA.
774 RtmpDmaEnable(pAd, 1);
775
776 // Enable Rx
777 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
778 Value |= (1 << 3);
779 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
780
781
782#ifdef CONFIG_STA_SUPPORT
783 RTMPStationStart(pAd);
784#endif // CONFIG_STA_SUPPORT //
785#ifndef UCOS
786 netif_start_queue(pAd->net_dev);
787#endif // !UCOS //
788 }
789 else if (!strcmp(arg, "TXCARR")) // Tx Carrier
790 {
791 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCARR\n"));
792 pAd->ate.Mode |= ATE_TXCARR;
793
794 // QA has done the following steps if it is used.
795 if (pAd->ate.bQATxStart == FALSE)
796 {
797 // Soft reset BBP.
798 BbpSoftReset(pAd);
799
800 // Carrier Test set BBP R22 bit7=1, bit6=1, bit[5~0]=0x01
801 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
802 BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
803 BbpData |= 0x000000C1; //set bit7=1, bit6=1, bit[5~0]=0x01
804 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
805
806 // set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1
807 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
808 Value = Value | 0x00000010;
809 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
810 }
811 }
812 else if (!strcmp(arg, "TXCONT")) // Tx Continue
813 {
814 if (pAd->ate.bQATxStart == TRUE)
815 {
816 /* set MAC_SYS_CTRL(0x1004) bit4(Continuous Tx Production Test)
817 and bit2(MAC TX enable) back to zero. */
818 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
819 MacData &= 0xFFFFFFEB;
820 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
821
822 // set BBP R22 bit7=0
823 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
824 BbpData &= 0xFFFFFF7F; //set bit7=0
825 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
826 }
827
828 /* for TxCont mode.
829 ** Step 1: Send 50 packets first then wait for a moment.
830 ** Step 2: Send more 50 packet then start continue mode.
831 */
832 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCONT\n"));
833 // Step 1: send 50 packets first.
834 pAd->ate.Mode |= ATE_TXCONT;
835 pAd->ate.TxCount = 50;
836 /* Do it after Tx/Rx DMA is aborted. */
837// pAd->ate.TxDoneCount = 0;
838
839 // Soft reset BBP.
840 BbpSoftReset(pAd);
841
842 // Abort Tx, RX DMA.
843 RtmpDmaEnable(pAd, 0);
844
845 // Fix can't smooth kick
846 {
847 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QID_AC_BE * 0x10, &pTxRing->TxDmaIdx);
848 pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
849 pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
850 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * 0x10, pTxRing->TxCpuIdx);
851 }
852
853 pAd->ate.TxDoneCount = 0;
854
855 /* Only needed if we have to send some normal frames. */
856 SetJapanFilter(pAd);
857
858 for (i = 0; (i < TX_RING_SIZE-1) && (i < pAd->ate.TxCount); i++)
859 {
860 PNDIS_PACKET pPacket;
861 UINT32 TxIdx = pTxRing->TxCpuIdx;
862
863#ifndef RT_BIG_ENDIAN
864 pTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
865#else
866 pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
867 TxD = *pDestTxD;
868 pTxD = &TxD;
869 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
870#endif
871 // Clean current cell.
872 pPacket = pTxRing->Cell[TxIdx].pNdisPacket;
873 if (pPacket)
874 {
875 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
876 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
877 }
878 //Always assign pNdisPacket as NULL after clear
879 pTxRing->Cell[TxIdx].pNdisPacket = NULL;
880
881 pPacket = pTxRing->Cell[TxIdx].pNextNdisPacket;
882 if (pPacket)
883 {
884 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
885 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
886 }
887 //Always assign pNextNdisPacket as NULL after clear
888 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
889
890#ifdef RT_BIG_ENDIAN
891 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
892 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
893#endif
894
895 if (ATESetUpFrame(pAd, TxIdx) != 0)
896 break;
897
898 INC_RING_INDEX(pTxRing->TxCpuIdx, TX_RING_SIZE);
899 }
900
901 // Setup frame format.
902 ATESetUpFrame(pAd, pTxRing->TxCpuIdx);
903
904 // Start Tx, RX DMA.
905 RtmpDmaEnable(pAd, 1);
906
907 // Enable Tx
908 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
909 Value |= (1 << 2);
910 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
911
912 // Disable Rx
913 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
914 Value &= ~(1 << 3);
915 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
916
917#ifdef RALINK_28xx_QA
918 if (pAd->ate.bQATxStart == TRUE)
919 {
920 pAd->ate.TxStatus = 1;
921 //pAd->ate.Repeat = 0;
922 }
923#endif // RALINK_28xx_QA //
924
925 // kick Tx-Ring.
926 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * RINGREG_DIFF, pAd->TxRing[QID_AC_BE].TxCpuIdx);
927
928 RTMPusecDelay(5000);
929
930
931 // Step 2: send more 50 packets then start continue mode.
932 // Abort Tx, RX DMA.
933 RtmpDmaEnable(pAd, 0);
934
935 // Cont. TX set BBP R22 bit7=1
936 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
937 BbpData |= 0x00000080; //set bit7=1
938 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
939
940 pAd->ate.TxCount = 50;
941
942 // Fix can't smooth kick
943 {
944 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QID_AC_BE * 0x10, &pTxRing->TxDmaIdx);
945 pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
946 pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
947 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * 0x10, pTxRing->TxCpuIdx);
948 }
949
950 pAd->ate.TxDoneCount = 0;
951
952 SetJapanFilter(pAd);
953
954 for (i = 0; (i < TX_RING_SIZE-1) && (i < pAd->ate.TxCount); i++)
955 {
956 PNDIS_PACKET pPacket;
957 UINT32 TxIdx = pTxRing->TxCpuIdx;
958
959#ifndef RT_BIG_ENDIAN
960 pTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
961#else
962 pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
963 TxD = *pDestTxD;
964 pTxD = &TxD;
965 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
966#endif
967 // clean current cell.
968 pPacket = pTxRing->Cell[TxIdx].pNdisPacket;
969 if (pPacket)
970 {
971 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
972 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
973 }
974 //Always assign pNdisPacket as NULL after clear
975 pTxRing->Cell[TxIdx].pNdisPacket = NULL;
976
977 pPacket = pTxRing->Cell[TxIdx].pNextNdisPacket;
978 if (pPacket)
979 {
980 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
981 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
982 }
983 //Always assign pNextNdisPacket as NULL after clear
984 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
985
986#ifdef RT_BIG_ENDIAN
987 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
988 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
989#endif
990
991 if (ATESetUpFrame(pAd, TxIdx) != 0)
992 break;
993
994 INC_RING_INDEX(pTxRing->TxCpuIdx, TX_RING_SIZE);
995 }
996
997 ATESetUpFrame(pAd, pTxRing->TxCpuIdx);
998
999 // Start Tx, RX DMA.
1000 RtmpDmaEnable(pAd, 1);
1001
1002 // Enable Tx
1003 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1004 Value |= (1 << 2);
1005 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1006
1007 // Disable Rx
1008 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1009 Value &= ~(1 << 3);
1010 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1011
1012#ifdef RALINK_28xx_QA
1013 if (pAd->ate.bQATxStart == TRUE)
1014 {
1015 pAd->ate.TxStatus = 1;
1016 //pAd->ate.Repeat = 0;
1017 }
1018#endif // RALINK_28xx_QA //
1019
1020 // kick Tx-Ring.
1021 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * RINGREG_DIFF, pAd->TxRing[QID_AC_BE].TxCpuIdx);
1022
1023 RTMPusecDelay(500);
1024
1025 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
1026 MacData |= 0x00000010;
1027 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
1028 }
1029 else if (!strcmp(arg, "TXFRAME")) // Tx Frames
1030 {
1031 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXFRAME(Count=%d)\n", pAd->ate.TxCount));
1032 pAd->ate.Mode |= ATE_TXFRAME;
1033 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1034
1035 // Soft reset BBP.
1036 BbpSoftReset(pAd);
1037 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
1038
1039 // Abort Tx, RX DMA.
1040 RtmpDmaEnable(pAd, 0);
1041
1042 // Fix can't smooth kick
1043 {
1044 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QID_AC_BE * 0x10, &pTxRing->TxDmaIdx);
1045 pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
1046 pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
1047 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * 0x10, pTxRing->TxCpuIdx);
1048 }
1049
1050 pAd->ate.TxDoneCount = 0;
1051
1052 SetJapanFilter(pAd);
1053
1054 for (i = 0; (i < TX_RING_SIZE-1) && (i < pAd->ate.TxCount); i++)
1055 {
1056 PNDIS_PACKET pPacket;
1057 UINT32 TxIdx = pTxRing->TxCpuIdx;
1058
1059#ifndef RT_BIG_ENDIAN
1060 pTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
1061#else
1062 pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
1063 TxD = *pDestTxD;
1064 pTxD = &TxD;
1065 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1066#endif
1067 // Clean current cell.
1068 pPacket = pTxRing->Cell[TxIdx].pNdisPacket;
1069 if (pPacket)
1070 {
1071 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
1072 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1073 }
1074 //Always assign pNdisPacket as NULL after clear
1075 pTxRing->Cell[TxIdx].pNdisPacket = NULL;
1076
1077 pPacket = pTxRing->Cell[TxIdx].pNextNdisPacket;
1078 if (pPacket)
1079 {
1080 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1081 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1082 }
1083 //Always assign pNextNdisPacket as NULL after clear
1084 pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
1085
1086#ifdef RT_BIG_ENDIAN
1087 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1088 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
1089#endif
1090
1091 if (ATESetUpFrame(pAd, TxIdx) != 0)
1092 break;
1093
1094 INC_RING_INDEX(pTxRing->TxCpuIdx, TX_RING_SIZE);
1095
1096 }
1097
1098 ATESetUpFrame(pAd, pTxRing->TxCpuIdx);
1099
1100 // Start Tx, Rx DMA.
1101 RtmpDmaEnable(pAd, 1);
1102
1103 // Enable Tx
1104 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1105 Value |= (1 << 2);
1106 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1107#ifdef RALINK_28xx_QA
1108 // add this for LoopBack mode
1109 if (pAd->ate.bQARxStart == FALSE)
1110 {
1111 // Disable Rx
1112 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1113 Value &= ~(1 << 3);
1114 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1115 }
1116
1117 if (pAd->ate.bQATxStart == TRUE)
1118 {
1119 pAd->ate.TxStatus = 1;
1120 //pAd->ate.Repeat = 0;
1121 }
1122#else
1123 // Disable Rx
1124 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1125 Value &= ~(1 << 3);
1126 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1127#endif // RALINK_28xx_QA //
1128
1129 RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QID_AC_BE * RINGREG_DIFF, &pAd->TxRing[QID_AC_BE].TxDmaIdx);
1130 // kick Tx-Ring.
1131 RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QID_AC_BE * RINGREG_DIFF, pAd->TxRing[QID_AC_BE].TxCpuIdx);
1132
1133 pAd->RalinkCounters.KickTxCount++;
1134 }
1135#ifdef RALINK_28xx_QA
1136 else if (!strcmp(arg, "TXSTOP"))
1137 {
1138 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXSTOP\n"));
1139 atemode = pAd->ate.Mode;
1140 pAd->ate.Mode &= ATE_TXSTOP;
1141 pAd->ate.bQATxStart = FALSE;
1142// pAd->ate.TxDoneCount = pAd->ate.TxCount;
1143
1144 if (atemode & ATE_TXCARR)
1145 {
1146 // No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
1147 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1148 BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
1149 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1150 }
1151 else if (atemode & ATE_TXCARRSUPP)
1152 {
1153 // No Cont. TX set BBP R22 bit7=0
1154 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1155 BbpData &= ~(1 << 7); //set bit7=0
1156 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1157
1158 // No Carrier Suppression set BBP R24 bit0=0
1159 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
1160 BbpData &= 0xFFFFFFFE; //clear bit0
1161 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
1162 }
1163 // We should free some resource which allocate when ATE_TXFRAME , ATE_STOP, and ATE_TXCONT.
1164 else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
1165 {
1166
1167 PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];
1168
1169 if (atemode & ATE_TXCONT)
1170 {
1171 // No Cont. TX set BBP R22 bit7=0
1172 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
1173 BbpData &= ~(1 << 7); //set bit7=0
1174 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1175 }
1176
1177 // Abort Tx, Rx DMA.
1178 RtmpDmaEnable(pAd, 0);
1179 for (i=0; i<TX_RING_SIZE; i++)
1180 {
1181 PNDIS_PACKET pPacket;
1182
1183#ifndef RT_BIG_ENDIAN
1184 pTxD = (PTXD_STRUC)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
1185#else
1186 pDestTxD = (PTXD_STRUC)pAd->TxRing[QID_AC_BE].Cell[i].AllocVa;
1187 TxD = *pDestTxD;
1188 pTxD = &TxD;
1189 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1190#endif
1191 pTxD->DMADONE = 0;
1192 pPacket = pTxRing->Cell[i].pNdisPacket;
1193 if (pPacket)
1194 {
1195 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE);
1196 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1197 }
1198 //Always assign pNdisPacket as NULL after clear
1199 pTxRing->Cell[i].pNdisPacket = NULL;
1200
1201 pPacket = pTxRing->Cell[i].pNextNdisPacket;
1202 if (pPacket)
1203 {
1204 PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE);
1205 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
1206 }
1207 //Always assign pNextNdisPacket as NULL after clear
1208 pTxRing->Cell[i].pNextNdisPacket = NULL;
1209#ifdef RT_BIG_ENDIAN
1210 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
1211 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
1212#endif
1213 }
1214 // Enable Tx, Rx DMA
1215 RtmpDmaEnable(pAd, 1);
1216
1217 }
1218
1219 // control
1220// pAd->ate.TxDoneCount = 0;
1221 pAd->ate.TxStatus = 0; // task Tx status // 0 --> task is idle, 1 --> task is running
1222
1223 // Soft reset BBP.
1224 BbpSoftReset(pAd);
1225
1226 // Disable Tx
1227 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1228 Value &= ~(1 << 2);
1229 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1230 }
1231 else if (!strcmp(arg, "RXSTOP"))
1232 {
1233 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXSTOP\n"));
1234 atemode = pAd->ate.Mode;
1235 pAd->ate.Mode &= ATE_RXSTOP;
1236 pAd->ate.bQARxStart = FALSE;
1237// pAd->ate.TxDoneCount = pAd->ate.TxCount;
1238
1239 if (atemode & ATE_TXCARR)
1240 {
1241 ;
1242 }
1243 else if (atemode & ATE_TXCARRSUPP)
1244 {
1245 ;
1246 }
1247
1248 // We should free some resource which was allocated when ATE_TXFRAME , ATE_STOP, and ATE_TXCONT.
1249 else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
1250 {
1251 if (atemode & ATE_TXCONT)
1252 {
1253 ;
1254 }
1255 }
1256
1257 // control
1258// pAd->ate.TxDoneCount = 0;
1259// pAd->ate.TxStatus = 0; // task Tx status // 0 --> task is idle, 1 --> task is running
1260
1261 // Soft reset BBP.
1262 BbpSoftReset(pAd);
1263
1264 // Disable Rx
1265 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1266 Value &= ~(1 << 3);
1267 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1268 }
1269#endif // RALINK_28xx_QA //
1270 else if (!strcmp(arg, "RXFRAME")) // Rx Frames
1271 {
1272 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXFRAME\n"));
1273
1274 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
1275 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
1276
1277 pAd->ate.Mode |= ATE_RXFRAME;
1278
1279 // Disable Tx of MAC block.
1280 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1281 Value &= ~(1 << 2);
1282 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1283
1284 // Enable Rx of MAC block.
1285 RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
1286 Value |= (1 << 3);
1287 RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
1288 }
1289 else
1290 {
1291 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: Invalid arg!\n"));
1292 return FALSE;
1293 }
1294 RTMPusecDelay(5000);
1295
1296 ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATECmdHandler()\n"));
1297
1298 return TRUE;
1299}
1300#endif // RT2860 //
1301/* */
1302/* */
1303/*=======================End of RT2860=======================*/
1304
1305
1306/*======================Start of RT2870======================*/
1307/* */
1308/* */
1309
1310
1311INT Set_ATE_Proc(
1312 IN PRTMP_ADAPTER pAd,
1313 IN PUCHAR arg)
1314{
1315 if (ATECmdHandler(pAd, arg))
1316 {
1317 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Success\n"));
1318
1319
1320 return TRUE;
1321 }
1322 else
1323 {
1324 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Failed\n"));
1325 return FALSE;
1326 }
1327}
1328
1329/*
1330 ==========================================================================
1331 Description:
1332 Set ATE ADDR1=DA for TxFrame(AP : To DS = 0 ; From DS = 1)
1333 or
1334 Set ATE ADDR3=DA for TxFrame(STA : To DS = 1 ; From DS = 0)
1335
1336 Return:
1337 TRUE if all parameters are OK, FALSE otherwise
1338 ==========================================================================
1339*/
1340INT Set_ATE_DA_Proc(
1341 IN PRTMP_ADAPTER pAd,
1342 IN PUCHAR arg)
1343{
1344 CHAR *value;
1345 INT i;
1346
1347 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
1348 return FALSE;
1349
1350 for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
1351 {
1352 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
1353 return FALSE; //Invalid
1354
1355
1356#ifdef CONFIG_STA_SUPPORT
1357 AtoH(value, &pAd->ate.Addr3[i++], 1);
1358#endif // CONFIG_STA_SUPPORT //
1359 }
1360
1361 if(i != 6)
1362 return FALSE; //Invalid
1363
1364
1365#ifdef CONFIG_STA_SUPPORT
1366 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DA_Proc (DA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr3[0],
1367 pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]));
1368#endif // CONFIG_STA_SUPPORT //
1369
1370 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_DA_Proc Success\n"));
1371
1372 return TRUE;
1373}
1374
1375/*
1376 ==========================================================================
1377 Description:
1378 Set ATE ADDR3=SA for TxFrame(AP : To DS = 0 ; From DS = 1)
1379 or
1380 Set ATE ADDR2=SA for TxFrame(STA : To DS = 1 ; From DS = 0)
1381
1382 Return:
1383 TRUE if all parameters are OK, FALSE otherwise
1384 ==========================================================================
1385*/
1386INT Set_ATE_SA_Proc(
1387 IN PRTMP_ADAPTER pAd,
1388 IN PUCHAR arg)
1389{
1390 CHAR *value;
1391 INT i;
1392
1393 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
1394 return FALSE;
1395
1396 for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
1397 {
1398 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
1399 return FALSE; //Invalid
1400
1401
1402#ifdef CONFIG_STA_SUPPORT
1403 AtoH(value, &pAd->ate.Addr2[i++], 1);
1404#endif // CONFIG_STA_SUPPORT //
1405 }
1406
1407 if(i != 6)
1408 return FALSE; //Invalid
1409
1410
1411#ifdef CONFIG_STA_SUPPORT
1412 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_SA_Proc (SA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr2[0],
1413 pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]));
1414#endif // CONFIG_STA_SUPPORT //
1415
1416 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_SA_Proc Success\n"));
1417
1418 return TRUE;
1419}
1420
1421/*
1422 ==========================================================================
1423 Description:
1424 Set ATE ADDR2=BSSID for TxFrame(AP : To DS = 0 ; From DS = 1)
1425 or
1426 Set ATE ADDR1=BSSID for TxFrame(STA : To DS = 1 ; From DS = 0)
1427
1428 Return:
1429 TRUE if all parameters are OK, FALSE otherwise
1430 ==========================================================================
1431*/
1432INT Set_ATE_BSSID_Proc(
1433 IN PRTMP_ADAPTER pAd,
1434 IN PUCHAR arg)
1435{
1436 CHAR *value;
1437 INT i;
1438
1439 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
1440 return FALSE;
1441
1442 for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
1443 {
1444 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
1445 return FALSE; //Invalid
1446
1447
1448#ifdef CONFIG_STA_SUPPORT
1449 AtoH(value, &pAd->ate.Addr1[i++], 1);
1450#endif // CONFIG_STA_SUPPORT //
1451 }
1452
1453 if(i != 6)
1454 return FALSE; //Invalid
1455
1456
1457#ifdef CONFIG_STA_SUPPORT
1458 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_BSSID_Proc (BSSID = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr1[0],
1459 pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]));
1460#endif // CONFIG_STA_SUPPORT //
1461
1462 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_BSSID_Proc Success\n"));
1463
1464 return TRUE;
1465}
1466
1467/*
1468 ==========================================================================
1469 Description:
1470 Set ATE Tx Channel
1471
1472 Return:
1473 TRUE if all parameters are OK, FALSE otherwise
1474 ==========================================================================
1475*/
1476INT Set_ATE_CHANNEL_Proc(
1477 IN PRTMP_ADAPTER pAd,
1478 IN PUCHAR arg)
1479{
1480 UCHAR channel;
1481
1482 channel = simple_strtol(arg, 0, 10);
1483
1484 if ((channel < 1) || (channel > 216))// to allow A band channel : ((channel < 1) || (channel > 14))
1485 {
1486 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_CHANNEL_Proc::Out of range, it should be in range of 1~14.\n"));
1487 return FALSE;
1488 }
1489 pAd->ate.Channel = channel;
1490
1491 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_CHANNEL_Proc (ATE Channel = %d)\n", pAd->ate.Channel));
1492 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_CHANNEL_Proc Success\n"));
1493
1494
1495 return TRUE;
1496}
1497
1498/*
1499 ==========================================================================
1500 Description:
1501 Set ATE Tx Power0
1502
1503 Return:
1504 TRUE if all parameters are OK, FALSE otherwise
1505 ==========================================================================
1506*/
1507INT Set_ATE_TX_POWER0_Proc(
1508 IN PRTMP_ADAPTER pAd,
1509 IN PUCHAR arg)
1510{
1511 CHAR TxPower;
1512
1513 TxPower = simple_strtol(arg, 0, 10);
1514
1515 if (pAd->ate.Channel <= 14)
1516 {
1517 if ((TxPower > 31) || (TxPower < 0))
1518 {
1519 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
1520 return FALSE;
1521 }
1522 }
1523 else// 5.5GHz
1524 {
1525 if ((TxPower > 15) || (TxPower < -7))
1526 {
1527 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
1528 return FALSE;
1529 }
1530 }
1531
1532 pAd->ate.TxPower0 = TxPower;
1533 ATETxPwrHandler(pAd, 0);
1534 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER0_Proc Success\n"));
1535
1536
1537 return TRUE;
1538}
1539
1540/*
1541 ==========================================================================
1542 Description:
1543 Set ATE Tx Power1
1544
1545 Return:
1546 TRUE if all parameters are OK, FALSE otherwise
1547 ==========================================================================
1548*/
1549INT Set_ATE_TX_POWER1_Proc(
1550 IN PRTMP_ADAPTER pAd,
1551 IN PUCHAR arg)
1552{
1553 CHAR TxPower;
1554
1555 TxPower = simple_strtol(arg, 0, 10);
1556
1557 if (pAd->ate.Channel <= 14)
1558 {
1559 if ((TxPower > 31) || (TxPower < 0))
1560 {
1561 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
1562 return FALSE;
1563 }
1564 }
1565 else
1566 {
1567 if ((TxPower > 15) || (TxPower < -7))
1568 {
1569 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
1570 return FALSE;
1571 }
1572 }
1573
1574 pAd->ate.TxPower1 = TxPower;
1575 ATETxPwrHandler(pAd, 1);
1576 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER1_Proc Success\n"));
1577
1578
1579 return TRUE;
1580}
1581
1582/*
1583 ==========================================================================
1584 Description:
1585 Set ATE Tx Antenna
1586
1587 Return:
1588 TRUE if all parameters are OK, FALSE otherwise
1589 ==========================================================================
1590*/
1591INT Set_ATE_TX_Antenna_Proc(
1592 IN PRTMP_ADAPTER pAd,
1593 IN PUCHAR arg)
1594{
1595 CHAR value;
1596
1597 value = simple_strtol(arg, 0, 10);
1598
1599 if ((value > 2) || (value < 0))
1600 {
1601 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_Antenna_Proc::Out of range (Value=%d)\n", value));
1602 return FALSE;
1603 }
1604
1605 pAd->ate.TxAntennaSel = value;
1606
1607 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_Antenna_Proc (Antenna = %d)\n", pAd->ate.TxAntennaSel));
1608 ATEDBGPRINT(RT_DEBUG_TRACE,("Ralink: Set_ATE_TX_Antenna_Proc Success\n"));
1609
1610
1611 return TRUE;
1612}
1613
1614/*
1615 ==========================================================================
1616 Description:
1617 Set ATE Rx Antenna
1618
1619 Return:
1620 TRUE if all parameters are OK, FALSE otherwise
1621 ==========================================================================
1622*/
1623INT Set_ATE_RX_Antenna_Proc(
1624 IN PRTMP_ADAPTER pAd,
1625 IN PUCHAR arg)
1626{
1627 CHAR value;
1628
1629 value = simple_strtol(arg, 0, 10);
1630
1631 if ((value > 3) || (value < 0))
1632 {
1633 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_RX_Antenna_Proc::Out of range (Value=%d)\n", value));
1634 return FALSE;
1635 }
1636
1637 pAd->ate.RxAntennaSel = value;
1638
1639 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_Antenna_Proc (Antenna = %d)\n", pAd->ate.RxAntennaSel));
1640 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_Antenna_Proc Success\n"));
1641
1642
1643 return TRUE;
1644}
1645
1646/*
1647 ==========================================================================
1648 Description:
1649 Set ATE RF frequence offset
1650
1651 Return:
1652 TRUE if all parameters are OK, FALSE otherwise
1653 ==========================================================================
1654*/
1655INT Set_ATE_TX_FREQOFFSET_Proc(
1656 IN PRTMP_ADAPTER pAd,
1657 IN PUCHAR arg)
1658{
1659 UCHAR RFFreqOffset;
1660 ULONG R4;
1661
1662 RFFreqOffset = simple_strtol(arg, 0, 10);
1663
1664 if(RFFreqOffset >= 64)
1665 {
1666 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_FREQOFFSET_Proc::Out of range, it should be in range of 0~63.\n"));
1667 return FALSE;
1668 }
1669
1670 pAd->ate.RFFreqOffset = RFFreqOffset;
1671 R4 = pAd->ate.RFFreqOffset << 15; // shift TX power control to correct RF register bit position
1672 R4 |= (pAd->LatchRfRegs.R4 & ((~0x001f8000)));
1673 pAd->LatchRfRegs.R4 = R4;
1674
1675 RtmpRfIoWrite(pAd);
1676
1677 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_FREQOFFSET_Proc (RFFreqOffset = %d)\n", pAd->ate.RFFreqOffset));
1678 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_FREQOFFSET_Proc Success\n"));
1679
1680
1681 return TRUE;
1682}
1683
1684/*
1685 ==========================================================================
1686 Description:
1687 Set ATE RF BW
1688
1689 Return:
1690 TRUE if all parameters are OK, FALSE otherwise
1691 ==========================================================================
1692*/
1693INT Set_ATE_TX_BW_Proc(
1694 IN PRTMP_ADAPTER pAd,
1695 IN PUCHAR arg)
1696{
1697 int i;
1698 UCHAR value = 0;
1699 UCHAR BBPCurrentBW;
1700
1701 BBPCurrentBW = simple_strtol(arg, 0, 10);
1702
1703 if(BBPCurrentBW == 0)
1704 pAd->ate.TxWI.BW = BW_20;
1705 else
1706 pAd->ate.TxWI.BW = BW_40;
1707
1708 if(pAd->ate.TxWI.BW == BW_20)
1709 {
1710 if(pAd->ate.Channel <= 14)
1711 {
1712 for (i=0; i<5; i++)
1713 {
1714 if (pAd->Tx20MPwrCfgGBand[i] != 0xffffffff)
1715 {
1716 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgGBand[i]);
1717 RTMPusecDelay(5000);
1718 }
1719 }
1720 }
1721 else
1722 {
1723 for (i=0; i<5; i++)
1724 {
1725 if (pAd->Tx20MPwrCfgABand[i] != 0xffffffff)
1726 {
1727 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgABand[i]);
1728 RTMPusecDelay(5000);
1729 }
1730 }
1731 }
1732
1733 //Set BBP R4 bit[4:3]=0:0
1734 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
1735 value &= (~0x18);
1736 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
1737
1738 //Set BBP R66=0x3C
1739 value = 0x3C;
1740 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
1741 //Set BBP R68=0x0B
1742 //to improve Rx sensitivity.
1743 value = 0x0B;
1744 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
1745 //Set BBP R69=0x16
1746 value = 0x16;
1747 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
1748 //Set BBP R70=0x08
1749 value = 0x08;
1750 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
1751 //Set BBP R73=0x11
1752 value = 0x11;
1753 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
1754
1755 // If Channel=14, Bandwidth=20M and Mode=CCK, Set BBP R4 bit5=1
1756 // (Japan filter coefficients)
1757 // This segment of code will only works when ATETXMODE and ATECHANNEL
1758 // were set to MODE_CCK and 14 respectively before ATETXBW is set to 0.
1759 //=====================================================================
1760 if (pAd->ate.Channel == 14)
1761 {
1762 int TxMode = pAd->ate.TxWI.PHYMODE;
1763 if (TxMode == MODE_CCK)
1764 {
1765 // when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1
1766 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
1767 value |= 0x20; //set bit5=1
1768 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
1769 }
1770 }
1771
1772 //=====================================================================
1773 // If bandwidth != 40M, RF Reg4 bit 21 = 0.
1774 pAd->LatchRfRegs.R4 &= ~0x00200000;
1775 RtmpRfIoWrite(pAd);
1776 }
1777 else if(pAd->ate.TxWI.BW == BW_40)
1778 {
1779 if(pAd->ate.Channel <= 14)
1780 {
1781 for (i=0; i<5; i++)
1782 {
1783 if (pAd->Tx40MPwrCfgGBand[i] != 0xffffffff)
1784 {
1785 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgGBand[i]);
1786 RTMPusecDelay(5000);
1787 }
1788 }
1789 }
1790 else
1791 {
1792 for (i=0; i<5; i++)
1793 {
1794 if (pAd->Tx40MPwrCfgABand[i] != 0xffffffff)
1795 {
1796 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgABand[i]);
1797 RTMPusecDelay(5000);
1798 }
1799 }
1800#ifdef DOT11_N_SUPPORT
1801 if ((pAd->ate.TxWI.PHYMODE >= MODE_HTMIX) && (pAd->ate.TxWI.MCS == 7))
1802 {
1803 value = 0x28;
1804 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R67, value);
1805 }
1806#endif // DOT11_N_SUPPORT //
1807 }
1808
1809 //Set BBP R4 bit[4:3]=1:0
1810 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
1811 value &= (~0x18);
1812 value |= 0x10;
1813 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
1814
1815 //Set BBP R66=0x3C
1816 value = 0x3C;
1817 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
1818 //Set BBP R68=0x0C
1819 //to improve Rx sensitivity.
1820 value = 0x0C;
1821 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
1822 //Set BBP R69=0x1A
1823 value = 0x1A;
1824 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
1825 //Set BBP R70=0x0A
1826 value = 0x0A;
1827 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
1828 //Set BBP R73=0x16
1829 value = 0x16;
1830 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
1831
1832 // If bandwidth = 40M, set RF Reg4 bit 21 = 1.
1833 pAd->LatchRfRegs.R4 |= 0x00200000;
1834 RtmpRfIoWrite(pAd);
1835 }
1836
1837 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_BW_Proc (BBPCurrentBW = %d)\n", pAd->ate.TxWI.BW));
1838 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_BW_Proc Success\n"));
1839
1840
1841 return TRUE;
1842}
1843
1844/*
1845 ==========================================================================
1846 Description:
1847 Set ATE Tx frame length
1848
1849 Return:
1850 TRUE if all parameters are OK, FALSE otherwise
1851 ==========================================================================
1852*/
1853INT Set_ATE_TX_LENGTH_Proc(
1854 IN PRTMP_ADAPTER pAd,
1855 IN PUCHAR arg)
1856{
1857 pAd->ate.TxLength = simple_strtol(arg, 0, 10);
1858
1859 if((pAd->ate.TxLength < 24) || (pAd->ate.TxLength > (MAX_FRAME_SIZE - 34/* == 2312 */)))
1860 {
1861 pAd->ate.TxLength = (MAX_FRAME_SIZE - 34/* == 2312 */);
1862 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 */)));
1863 return FALSE;
1864 }
1865
1866 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_LENGTH_Proc (TxLength = %d)\n", pAd->ate.TxLength));
1867 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_LENGTH_Proc Success\n"));
1868
1869
1870 return TRUE;
1871}
1872
1873/*
1874 ==========================================================================
1875 Description:
1876 Set ATE Tx frame count
1877
1878 Return:
1879 TRUE if all parameters are OK, FALSE otherwise
1880 ==========================================================================
1881*/
1882INT Set_ATE_TX_COUNT_Proc(
1883 IN PRTMP_ADAPTER pAd,
1884 IN PUCHAR arg)
1885{
1886 pAd->ate.TxCount = simple_strtol(arg, 0, 10);
1887
1888 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pAd->ate.TxCount));
1889 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n"));
1890
1891
1892 return TRUE;
1893}
1894
1895/*
1896 ==========================================================================
1897 Description:
1898 Set ATE Tx frame MCS
1899
1900 Return:
1901 TRUE if all parameters are OK, FALSE otherwise
1902 ==========================================================================
1903*/
1904INT Set_ATE_TX_MCS_Proc(
1905 IN PRTMP_ADAPTER pAd,
1906 IN PUCHAR arg)
1907{
1908 UCHAR MCS;
1909 int result;
1910
1911 MCS = simple_strtol(arg, 0, 10);
1912 result = CheckMCSValid(pAd->ate.TxWI.PHYMODE, MCS);
1913
1914 if (result != -1)
1915 {
1916 pAd->ate.TxWI.MCS = (UCHAR)MCS;
1917 }
1918 else
1919 {
1920 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MCS_Proc::Out of range, refer to rate table.\n"));
1921 return FALSE;
1922 }
1923
1924 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MCS_Proc (MCS = %d)\n", pAd->ate.TxWI.MCS));
1925 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MCS_Proc Success\n"));
1926
1927
1928 return TRUE;
1929}
1930
1931/*
1932 ==========================================================================
1933 Description:
1934 Set ATE Tx frame Mode
1935 0: MODE_CCK
1936 1: MODE_OFDM
1937 2: MODE_HTMIX
1938 3: MODE_HTGREENFIELD
1939
1940 Return:
1941 TRUE if all parameters are OK, FALSE otherwise
1942 ==========================================================================
1943*/
1944INT Set_ATE_TX_MODE_Proc(
1945 IN PRTMP_ADAPTER pAd,
1946 IN PUCHAR arg)
1947{
1948 pAd->ate.TxWI.PHYMODE = simple_strtol(arg, 0, 10);
1949
1950 if(pAd->ate.TxWI.PHYMODE > 3)
1951 {
1952 pAd->ate.TxWI.PHYMODE = 0;
1953 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MODE_Proc::Out of range. it should be in range of 0~3\n"));
1954 ATEDBGPRINT(RT_DEBUG_ERROR, ("0: CCK, 1: OFDM, 2: HT_MIX, 3: HT_GREEN_FIELD.\n"));
1955 return FALSE;
1956 }
1957
1958 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MODE_Proc (TxMode = %d)\n", pAd->ate.TxWI.PHYMODE));
1959 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MODE_Proc Success\n"));
1960
1961
1962 return TRUE;
1963}
1964
1965/*
1966 ==========================================================================
1967 Description:
1968 Set ATE Tx frame GI
1969
1970 Return:
1971 TRUE if all parameters are OK, FALSE otherwise
1972 ==========================================================================
1973*/
1974INT Set_ATE_TX_GI_Proc(
1975 IN PRTMP_ADAPTER pAd,
1976 IN PUCHAR arg)
1977{
1978 pAd->ate.TxWI.ShortGI = simple_strtol(arg, 0, 10);
1979
1980 if(pAd->ate.TxWI.ShortGI > 1)
1981 {
1982 pAd->ate.TxWI.ShortGI = 0;
1983 ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_GI_Proc::Out of range\n"));
1984 return FALSE;
1985 }
1986
1987 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_GI_Proc (GI = %d)\n", pAd->ate.TxWI.ShortGI));
1988 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_GI_Proc Success\n"));
1989
1990
1991 return TRUE;
1992}
1993
1994/*
1995 ==========================================================================
1996 Description:
1997 ==========================================================================
1998 */
1999INT Set_ATE_RX_FER_Proc(
2000 IN PRTMP_ADAPTER pAd,
2001 IN PUCHAR arg)
2002{
2003 pAd->ate.bRxFer = simple_strtol(arg, 0, 10);
2004
2005 if (pAd->ate.bRxFer == 1)
2006 {
2007 pAd->ate.RxCntPerSec = 0;
2008 pAd->ate.RxTotalCnt = 0;
2009 }
2010
2011 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_FER_Proc (bRxFer = %d)\n", pAd->ate.bRxFer));
2012 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_FER_Proc Success\n"));
2013
2014
2015 return TRUE;
2016}
2017
2018INT Set_ATE_Read_RF_Proc(
2019 IN PRTMP_ADAPTER pAd,
2020 IN PUCHAR arg)
2021{
2022 ate_print(KERN_EMERG "R1 = %lx\n", pAd->LatchRfRegs.R1);
2023 ate_print(KERN_EMERG "R2 = %lx\n", pAd->LatchRfRegs.R2);
2024 ate_print(KERN_EMERG "R3 = %lx\n", pAd->LatchRfRegs.R3);
2025 ate_print(KERN_EMERG "R4 = %lx\n", pAd->LatchRfRegs.R4);
2026
2027 return TRUE;
2028}
2029
2030INT Set_ATE_Write_RF1_Proc(
2031 IN PRTMP_ADAPTER pAd,
2032 IN PUCHAR arg)
2033{
2034 UINT32 value = simple_strtol(arg, 0, 16);
2035
2036 pAd->LatchRfRegs.R1 = value;
2037 RtmpRfIoWrite(pAd);
2038
2039 return TRUE;
2040}
2041
2042INT Set_ATE_Write_RF2_Proc(
2043 IN PRTMP_ADAPTER pAd,
2044 IN PUCHAR arg)
2045{
2046 UINT32 value = simple_strtol(arg, 0, 16);
2047
2048 pAd->LatchRfRegs.R2 = value;
2049 RtmpRfIoWrite(pAd);
2050
2051 return TRUE;
2052}
2053
2054INT Set_ATE_Write_RF3_Proc(
2055 IN PRTMP_ADAPTER pAd,
2056 IN PUCHAR arg)
2057{
2058 UINT32 value = simple_strtol(arg, 0, 16);
2059
2060 pAd->LatchRfRegs.R3 = value;
2061 RtmpRfIoWrite(pAd);
2062
2063 return TRUE;
2064}
2065
2066INT Set_ATE_Write_RF4_Proc(
2067 IN PRTMP_ADAPTER pAd,
2068 IN PUCHAR arg)
2069{
2070 UINT32 value = simple_strtol(arg, 0, 16);
2071
2072 pAd->LatchRfRegs.R4 = value;
2073 RtmpRfIoWrite(pAd);
2074
2075 return TRUE;
2076}
2077
2078/*
2079 ==========================================================================
2080 Description:
2081 Load and Write EEPROM from a binary file prepared in advance.
2082
2083 Return:
2084 TRUE if all parameters are OK, FALSE otherwise
2085 ==========================================================================
2086*/
2087#ifndef UCOS
2088INT Set_ATE_Load_E2P_Proc(
2089 IN PRTMP_ADAPTER pAd,
2090 IN PUCHAR arg)
2091{
2092 BOOLEAN ret = FALSE;
2093 PUCHAR src = EEPROM_BIN_FILE_NAME;
2094 struct file *srcf;
2095 INT32 retval, orgfsuid, orgfsgid;
2096 mm_segment_t orgfs;
2097 USHORT WriteEEPROM[(EEPROM_SIZE/2)];
2098 UINT32 FileLength = 0;
2099 UINT32 value = simple_strtol(arg, 0, 10);
2100
2101 ATEDBGPRINT(RT_DEBUG_ERROR, ("===> %s (value=%d)\n\n", __FUNCTION__, value));
2102
2103 if (value > 0)
2104 {
2105 /* zero the e2p buffer */
2106 NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
2107
2108 /* save uid and gid used for filesystem access.
2109 ** set user and group to 0 (root)
2110 */
2111 orgfsuid = current->fsuid;
2112 orgfsgid = current->fsgid;
2113 /* as root */
2114 current->fsuid = current->fsgid = 0;
2115 orgfs = get_fs();
2116 set_fs(KERNEL_DS);
2117
2118 do
2119 {
2120 /* open the bin file */
2121 srcf = filp_open(src, O_RDONLY, 0);
2122
2123 if (IS_ERR(srcf))
2124 {
2125 ate_print("%s - Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(srcf), src);
2126 break;
2127 }
2128
2129 /* the object must have a read method */
2130 if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
2131 {
2132 ate_print("%s - %s does not have a read method\n", __FUNCTION__, src);
2133 break;
2134 }
2135
2136 /* read the firmware from the file *.bin */
2137 FileLength = srcf->f_op->read(srcf,
2138 (PUCHAR)WriteEEPROM,
2139 EEPROM_SIZE,
2140 &srcf->f_pos);
2141
2142 if (FileLength != EEPROM_SIZE)
2143 {
2144 ate_print("%s: error file length (=%d) in e2p.bin\n",
2145 __FUNCTION__, FileLength);
2146 break;
2147 }
2148 else
2149 {
2150 /* write the content of .bin file to EEPROM */
2151 rt_ee_write_all(pAd, WriteEEPROM);
2152 ret = TRUE;
2153 }
2154 break;
2155 } while(TRUE);
2156
2157 /* close firmware file */
2158 if (IS_ERR(srcf))
2159 {
2160 ;
2161 }
2162 else
2163 {
2164 retval = filp_close(srcf, NULL);
2165 if (retval)
2166 {
2167 ATEDBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src));
2168
2169 }
2170 }
2171
2172 /* restore */
2173 set_fs(orgfs);
2174 current->fsuid = orgfsuid;
2175 current->fsgid = orgfsgid;
2176 }
2177 ATEDBGPRINT(RT_DEBUG_ERROR, ("<=== %s (ret=%d)\n", __FUNCTION__, ret));
2178
2179 return ret;
2180
2181}
2182#else
2183INT Set_ATE_Load_E2P_Proc(
2184 IN PRTMP_ADAPTER pAd,
2185 IN PUCHAR arg)
2186{
2187 USHORT WriteEEPROM[(EEPROM_SIZE/2)];
2188 struct iwreq *wrq = (struct iwreq *)arg;
2189
2190 ATEDBGPRINT(RT_DEBUG_TRACE, ("===> %s (wrq->u.data.length = %d)\n\n", __FUNCTION__, wrq->u.data.length));
2191
2192 if (wrq->u.data.length != EEPROM_SIZE)
2193 {
2194 ate_print("%s: error length (=%d) from host\n",
2195 __FUNCTION__, wrq->u.data.length);
2196 return FALSE;
2197 }
2198 else/* (wrq->u.data.length == EEPROM_SIZE) */
2199 {
2200 /* zero the e2p buffer */
2201 NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
2202
2203 /* fill the local buffer */
2204 NdisMoveMemory((PUCHAR)WriteEEPROM, wrq->u.data.pointer, wrq->u.data.length);
2205
2206 do
2207 {
2208 /* write the content of .bin file to EEPROM */
2209 rt_ee_write_all(pAd, WriteEEPROM);
2210
2211 } while(FALSE);
2212 }
2213
2214 ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== %s\n", __FUNCTION__));
2215
2216 return TRUE;
2217
2218}
2219#endif // !UCOS //
2220
2221INT Set_ATE_Read_E2P_Proc(
2222 IN PRTMP_ADAPTER pAd,
2223 IN PUCHAR arg)
2224{
2225 USHORT buffer[EEPROM_SIZE/2];
2226 USHORT *p;
2227 int i;
2228
2229 rt_ee_read_all(pAd, (USHORT *)buffer);
2230 p = buffer;
2231 for (i = 0; i < (EEPROM_SIZE/2); i++)
2232 {
2233 ate_print("%4.4x ", *p);
2234 if (((i+1) % 16) == 0)
2235 ate_print("\n");
2236 p++;
2237 }
2238 return TRUE;
2239}
2240
2241INT Set_ATE_Show_Proc(
2242 IN PRTMP_ADAPTER pAd,
2243 IN PUCHAR arg)
2244{
2245 ate_print("Mode=%d\n", pAd->ate.Mode);
2246 ate_print("TxPower0=%d\n", pAd->ate.TxPower0);
2247 ate_print("TxPower1=%d\n", pAd->ate.TxPower1);
2248 ate_print("TxAntennaSel=%d\n", pAd->ate.TxAntennaSel);
2249 ate_print("RxAntennaSel=%d\n", pAd->ate.RxAntennaSel);
2250 ate_print("BBPCurrentBW=%d\n", pAd->ate.TxWI.BW);
2251 ate_print("GI=%d\n", pAd->ate.TxWI.ShortGI);
2252 ate_print("MCS=%d\n", pAd->ate.TxWI.MCS);
2253 ate_print("TxMode=%d\n", pAd->ate.TxWI.PHYMODE);
2254 ate_print("Addr1=%02x:%02x:%02x:%02x:%02x:%02x\n",
2255 pAd->ate.Addr1[0], pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]);
2256 ate_print("Addr2=%02x:%02x:%02x:%02x:%02x:%02x\n",
2257 pAd->ate.Addr2[0], pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]);
2258 ate_print("Addr3=%02x:%02x:%02x:%02x:%02x:%02x\n",
2259 pAd->ate.Addr3[0], pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]);
2260 ate_print("Channel=%d\n", pAd->ate.Channel);
2261 ate_print("TxLength=%d\n", pAd->ate.TxLength);
2262 ate_print("TxCount=%u\n", pAd->ate.TxCount);
2263 ate_print("RFFreqOffset=%d\n", pAd->ate.RFFreqOffset);
2264 ate_print(KERN_EMERG "Set_ATE_Show_Proc Success\n");
2265 return TRUE;
2266}
2267
2268INT Set_ATE_Help_Proc(
2269 IN PRTMP_ADAPTER pAd,
2270 IN PUCHAR arg)
2271{
2272 ate_print("ATE=ATESTART, ATESTOP, TXCONT, TXCARR, TXFRAME, RXFRAME\n");
2273 ate_print("ATEDA\n");
2274 ate_print("ATESA\n");
2275 ate_print("ATEBSSID\n");
2276 ate_print("ATECHANNEL, range:0~14(unless A band !)\n");
2277 ate_print("ATETXPOW0, set power level of antenna 1.\n");
2278 ate_print("ATETXPOW1, set power level of antenna 2.\n");
2279 ate_print("ATETXANT, set TX antenna. 0:all, 1:antenna one, 2:antenna two.\n");
2280 ate_print("ATERXANT, set RX antenna.0:all, 1:antenna one, 2:antenna two, 3:antenna three.\n");
2281 ate_print("ATETXFREQOFFSET, set frequency offset, range 0~63\n");
2282 ate_print("ATETXBW, set BandWidth, 0:20MHz, 1:40MHz.\n");
2283 ate_print("ATETXLEN, set Frame length, range 24~%d\n", (MAX_FRAME_SIZE - 34/* == 2312 */));
2284 ate_print("ATETXCNT, set how many frame going to transmit.\n");
2285 ate_print("ATETXMCS, set MCS, reference to rate table.\n");
2286 ate_print("ATETXMODE, set Mode 0:CCK, 1:OFDM, 2:HT-Mix, 3:GreenField, reference to rate table.\n");
2287 ate_print("ATETXGI, set GI interval, 0:Long, 1:Short\n");
2288 ate_print("ATERXFER, 0:disable Rx Frame error rate. 1:enable Rx Frame error rate.\n");
2289 ate_print("ATERRF, show all RF registers.\n");
2290 ate_print("ATEWRF1, set RF1 register.\n");
2291 ate_print("ATEWRF2, set RF2 register.\n");
2292 ate_print("ATEWRF3, set RF3 register.\n");
2293 ate_print("ATEWRF4, set RF4 register.\n");
2294 ate_print("ATELDE2P, load EEPROM from .bin file.\n");
2295 ate_print("ATERE2P, display all EEPROM content.\n");
2296 ate_print("ATESHOW, display all parameters of ATE.\n");
2297 ate_print("ATEHELP, online help.\n");
2298
2299 return TRUE;
2300}
2301
2302/*
2303 ==========================================================================
2304 Description:
2305
2306 AsicSwitchChannel() dedicated for ATE.
2307
2308 ==========================================================================
2309*/
2310VOID ATEAsicSwitchChannel(
2311 IN PRTMP_ADAPTER pAd)
2312{
2313 UINT32 R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0, Value = 0;
2314 CHAR TxPwer = 0, TxPwer2 = 0;
2315 UCHAR index, BbpValue = 0, R66 = 0x30;
2316 RTMP_RF_REGS *RFRegTable;
2317 UCHAR Channel;
2318
2319#ifdef RALINK_28xx_QA
2320 if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
2321 {
2322 if (pAd->ate.Channel != pAd->LatchRfRegs.Channel)
2323 {
2324 pAd->ate.Channel = pAd->LatchRfRegs.Channel;
2325 }
2326 return;
2327 }
2328 else
2329#endif // RALINK_28xx_QA //
2330 Channel = pAd->ate.Channel;
2331
2332 // Select antenna
2333 AsicAntennaSelect(pAd, Channel);
2334
2335 // fill Tx power value
2336 TxPwer = pAd->ate.TxPower0;
2337 TxPwer2 = pAd->ate.TxPower1;
2338
2339 RFRegTable = RF2850RegTable;
2340
2341 switch (pAd->RfIcType)
2342 {
2343 /* But only 2850 and 2750 support 5.5GHz band... */
2344 case RFIC_2820:
2345 case RFIC_2850:
2346 case RFIC_2720:
2347 case RFIC_2750:
2348
2349 for (index = 0; index < NUM_OF_2850_CHNL; index++)
2350 {
2351 if (Channel == RFRegTable[index].Channel)
2352 {
2353 R2 = RFRegTable[index].R2;
2354 if (pAd->Antenna.field.TxPath == 1)
2355 {
2356 R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
2357 }
2358
2359 if (pAd->Antenna.field.RxPath == 2)
2360 {
2361 switch (pAd->ate.RxAntennaSel)
2362 {
2363 case 1:
2364 R2 |= 0x20040;
2365 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2366 BbpValue &= 0xE4;
2367 BbpValue |= 0x00;
2368 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2369 break;
2370 case 2:
2371 R2 |= 0x10040;
2372 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2373 BbpValue &= 0xE4;
2374 BbpValue |= 0x01;
2375 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2376 break;
2377 default:
2378 R2 |= 0x40;
2379 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2380 BbpValue &= 0xE4;
2381 /* Only enable two Antenna to receive. */
2382 BbpValue |= 0x08;
2383 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2384 break;
2385 }
2386 }
2387 else if (pAd->Antenna.field.RxPath == 1)
2388 {
2389 R2 |= 0x20040; // write 1 to off RxPath
2390 }
2391
2392 if (pAd->Antenna.field.TxPath == 2)
2393 {
2394 if (pAd->ate.TxAntennaSel == 1)
2395 {
2396 R2 |= 0x4000; // If TX Antenna select is 1 , bit 14 = 1; Disable Ant 2
2397 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
2398 BbpValue &= 0xE7; //11100111B
2399 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
2400 }
2401 else if (pAd->ate.TxAntennaSel == 2)
2402 {
2403 R2 |= 0x8000; // If TX Antenna select is 2 , bit 15 = 1; Disable Ant 1
2404 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
2405 BbpValue &= 0xE7;
2406 BbpValue |= 0x08;
2407 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
2408 }
2409 else
2410 {
2411 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
2412 BbpValue &= 0xE7;
2413 BbpValue |= 0x10;
2414 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
2415 }
2416 }
2417 if (pAd->Antenna.field.RxPath == 3)
2418 {
2419 switch (pAd->ate.RxAntennaSel)
2420 {
2421 case 1:
2422 R2 |= 0x20040;
2423 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2424 BbpValue &= 0xE4;
2425 BbpValue |= 0x00;
2426 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2427 break;
2428 case 2:
2429 R2 |= 0x10040;
2430 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2431 BbpValue &= 0xE4;
2432 BbpValue |= 0x01;
2433 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2434 break;
2435 case 3:
2436 R2 |= 0x30000;
2437 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2438 BbpValue &= 0xE4;
2439 BbpValue |= 0x02;
2440 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2441 break;
2442 default:
2443 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
2444 BbpValue &= 0xE4;
2445 BbpValue |= 0x10;
2446 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
2447 break;
2448 }
2449 }
2450
2451 if (Channel > 14)
2452 {
2453 // initialize R3, R4
2454 R3 = (RFRegTable[index].R3 & 0xffffc1ff);
2455 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15);
2456
2457 // According the Rory's suggestion to solve the middle range issue.
2458 // 5.5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
2459 // R3
2460 if ((TxPwer >= -7) && (TxPwer < 0))
2461 {
2462 TxPwer = (7+TxPwer);
2463 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
2464 R3 |= (TxPwer << 10);
2465 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer=%d \n", TxPwer));
2466 }
2467 else
2468 {
2469 TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
2470 R3 |= (TxPwer << 10) | (1 << 9);
2471 }
2472
2473 // R4
2474 if ((TxPwer2 >= -7) && (TxPwer2 < 0))
2475 {
2476 TxPwer2 = (7+TxPwer2);
2477 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
2478 R4 |= (TxPwer2 << 7);
2479 ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
2480 }
2481 else
2482 {
2483 TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
2484 R4 |= (TxPwer2 << 7) | (1 << 6);
2485 }
2486 }
2487 else
2488 {
2489 R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
2490 R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15) | (TxPwer2 <<6);// Set freq offset & TxPwr1
2491 }
2492
2493 // Based on BBP current mode before changing RF channel.
2494 if (pAd->ate.TxWI.BW == BW_40)
2495 {
2496 R4 |=0x200000;
2497 }
2498
2499 // Update variables
2500 pAd->LatchRfRegs.Channel = Channel;
2501 pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
2502 pAd->LatchRfRegs.R2 = R2;
2503 pAd->LatchRfRegs.R3 = R3;
2504 pAd->LatchRfRegs.R4 = R4;
2505
2506 RtmpRfIoWrite(pAd);
2507
2508 break;
2509 }
2510 }
2511 break;
2512
2513 default:
2514 break;
2515 }
2516
2517 // Change BBP setting during switch from a->g, g->a
2518 if (Channel <= 14)
2519 {
2520 ULONG TxPinCfg = 0x00050F0A;// 2007.10.09 by Brian : 0x0005050A ==> 0x00050F0A
2521
2522 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
2523 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
2524 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
2525
2526 /* For 1T/2R chip only... */
2527 if (pAd->NicConfig2.field.ExternalLNAForG)
2528 {
2529 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
2530 }
2531 else
2532 {
2533 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
2534 }
2535
2536 // According the Rory's suggestion to solve the middle range issue.
2537 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
2538 ASSERT((BbpValue == 0x00));
2539 if ((BbpValue != 0x00))
2540 {
2541 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
2542 }
2543
2544 // 5.5GHz band selection PIN, bit1 and bit2 are complement
2545 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
2546 Value &= (~0x6);
2547 Value |= (0x04);
2548 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
2549
2550 // Turn off unused PA or LNA when only 1T or 1R.
2551 if (pAd->Antenna.field.TxPath == 1)
2552 {
2553 TxPinCfg &= 0xFFFFFFF3;
2554 }
2555 if (pAd->Antenna.field.RxPath == 1)
2556 {
2557 TxPinCfg &= 0xFFFFF3FF;
2558 }
2559
2560 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
2561 }
2562 else
2563 {
2564 ULONG TxPinCfg = 0x00050F05;//2007.10.09 by Brian : 0x00050505 ==> 0x00050F05
2565
2566 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
2567 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
2568 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
2569 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
2570
2571 // According the Rory's suggestion to solve the middle range issue.
2572 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
2573 ASSERT((BbpValue == 0x00));
2574 if ((BbpValue != 0x00))
2575 {
2576 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
2577 }
2578 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R91, &BbpValue);
2579 ASSERT((BbpValue == 0x04));
2580
2581 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R92, &BbpValue);
2582 ASSERT((BbpValue == 0x00));
2583
2584 // 5.5GHz band selection PIN, bit1 and bit2 are complement
2585 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
2586 Value &= (~0x6);
2587 Value |= (0x02);
2588 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
2589
2590 // Turn off unused PA or LNA when only 1T or 1R.
2591 if (pAd->Antenna.field.TxPath == 1)
2592 {
2593 TxPinCfg &= 0xFFFFFFF3;
2594 }
2595 if (pAd->Antenna.field.RxPath == 1)
2596 {
2597 TxPinCfg &= 0xFFFFF3FF;
2598 }
2599
2600 RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
2601 }
2602
2603 // R66 should be set according to Channel and use 20MHz when scanning
2604 if (Channel <= 14)
2605 {
2606 // BG band
2607 R66 = 0x2E + GET_LNA_GAIN(pAd);
2608 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
2609 }
2610 else
2611 {
2612 // 5.5 GHz band
2613 if (pAd->ate.TxWI.BW == BW_20)
2614 {
2615 R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
2616 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
2617 }
2618 else
2619 {
2620 R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
2621 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
2622 }
2623 }
2624
2625 //
2626 // On 11A, We should delay and wait RF/BBP to be stable
2627 // and the appropriate time should be 1000 micro seconds
2628 // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
2629 //
2630 RTMPusecDelay(1000);
2631
2632 if (Channel > 14)
2633 {
2634 // When 5.5GHz band the LSB of TxPwr will be used to reduced 7dB or not.
2635 ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
2636 Channel,
2637 pAd->RfIcType,
2638 pAd->Antenna.field.TxPath,
2639 pAd->LatchRfRegs.R1,
2640 pAd->LatchRfRegs.R2,
2641 pAd->LatchRfRegs.R3,
2642 pAd->LatchRfRegs.R4));
2643 }
2644 else
2645 {
2646 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",
2647 Channel,
2648 pAd->RfIcType,
2649 (R3 & 0x00003e00) >> 9,
2650 (R4 & 0x000007c0) >> 6,
2651 pAd->Antenna.field.TxPath,
2652 pAd->LatchRfRegs.R1,
2653 pAd->LatchRfRegs.R2,
2654 pAd->LatchRfRegs.R3,
2655 pAd->LatchRfRegs.R4));
2656 }
2657}
2658
2659//
2660// In fact, no one will call this routine so far !
2661//
2662/*
2663 ==========================================================================
2664 Description:
2665 Gives CCK TX rate 2 more dB TX power.
2666 This routine works only in ATE mode.
2667
2668 calculate desired Tx power in RF R3.Tx0~5, should consider -
2669 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
2670 1. TxPowerPercentage
2671 2. auto calibration based on TSSI feedback
2672 3. extra 2 db for CCK
2673 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
2674
2675 NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
2676 it should be called AFTER MlmeDynamicTxRateSwitching()
2677 ==========================================================================
2678 */
2679VOID ATEAsicAdjustTxPower(
2680 IN PRTMP_ADAPTER pAd)
2681{
2682 INT i, j;
2683 CHAR DeltaPwr = 0;
2684 BOOLEAN bAutoTxAgc = FALSE;
2685 UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
2686 UCHAR BbpR49 = 0, idx;
2687 PCHAR pTxAgcCompensate;
2688 ULONG TxPwr[5];
2689 CHAR Value;
2690
2691 /* no one calls this procedure so far */
2692 if (pAd->ate.TxWI.BW == BW_40)
2693 {
2694 if (pAd->ate.Channel > 14)
2695 {
2696 TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
2697 TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
2698 TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
2699 TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
2700 TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
2701 }
2702 else
2703 {
2704 TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
2705 TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
2706 TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
2707 TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
2708 TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
2709 }
2710 }
2711 else
2712 {
2713 if (pAd->ate.Channel > 14)
2714 {
2715 TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
2716 TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
2717 TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
2718 TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
2719 TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
2720 }
2721 else
2722 {
2723 TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
2724 TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
2725 TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
2726 TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
2727 TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
2728 }
2729 }
2730
2731 // TX power compensation for temperature variation based on TSSI.
2732 // Do it per 4 seconds.
2733 if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
2734 {
2735 if (pAd->ate.Channel <= 14)
2736 {
2737 /* bg channel */
2738 bAutoTxAgc = pAd->bAutoTxAgcG;
2739 TssiRef = pAd->TssiRefG;
2740 pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
2741 pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
2742 TxAgcStep = pAd->TxAgcStepG;
2743 pTxAgcCompensate = &pAd->TxAgcCompensateG;
2744 }
2745 else
2746 {
2747 /* a channel */
2748 bAutoTxAgc = pAd->bAutoTxAgcA;
2749 TssiRef = pAd->TssiRefA;
2750 pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
2751 pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
2752 TxAgcStep = pAd->TxAgcStepA;
2753 pTxAgcCompensate = &pAd->TxAgcCompensateA;
2754 }
2755
2756 if (bAutoTxAgc)
2757 {
2758 /* BbpR49 is unsigned char */
2759 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
2760
2761 /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
2762 /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
2763 /* step value is defined in pAd->TxAgcStepG for tx power value */
2764
2765 /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
2766 /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
2767 above value are examined in mass factory production */
2768 /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
2769
2770 /* plus is 0x10 ~ 0x40, minus is 0x60 ~ 0x90 */
2771 /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
2772 /* if value is 0x65, tx power will be -= TxAgcStep*(2-1) */
2773
2774 if (BbpR49 > pTssiMinusBoundary[1])
2775 {
2776 // Reading is larger than the reference value.
2777 // Check for how large we need to decrease the Tx power.
2778 for (idx = 1; idx < 5; idx++)
2779 {
2780 if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
2781 break;
2782 }
2783 // The index is the step we should decrease, idx = 0 means there is nothing to compensate
2784// if (R3 > (ULONG) (TxAgcStep * (idx-1)))
2785 *pTxAgcCompensate = -(TxAgcStep * (idx-1));
2786// else
2787// *pTxAgcCompensate = -((UCHAR)R3);
2788
2789 DeltaPwr += (*pTxAgcCompensate);
2790 ATEDBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
2791 BbpR49, TssiRef, TxAgcStep, idx-1));
2792 }
2793 else if (BbpR49 < pTssiPlusBoundary[1])
2794 {
2795 // Reading is smaller than the reference value
2796 // check for how large we need to increase the Tx power
2797 for (idx = 1; idx < 5; idx++)
2798 {
2799 if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
2800 break;
2801 }
2802 // The index is the step we should increase, idx = 0 means there is nothing to compensate
2803 *pTxAgcCompensate = TxAgcStep * (idx-1);
2804 DeltaPwr += (*pTxAgcCompensate);
2805 ATEDBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
2806 BbpR49, TssiRef, TxAgcStep, idx-1));
2807 }
2808 else
2809 {
2810 *pTxAgcCompensate = 0;
2811 ATEDBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
2812 BbpR49, TssiRef, TxAgcStep, 0));
2813 }
2814 }
2815 }
2816 else
2817 {
2818 if (pAd->ate.Channel <= 14)
2819 {
2820 bAutoTxAgc = pAd->bAutoTxAgcG;
2821 pTxAgcCompensate = &pAd->TxAgcCompensateG;
2822 }
2823 else
2824 {
2825 bAutoTxAgc = pAd->bAutoTxAgcA;
2826 pTxAgcCompensate = &pAd->TxAgcCompensateA;
2827 }
2828
2829 if (bAutoTxAgc)
2830 DeltaPwr += (*pTxAgcCompensate);
2831 }
2832
2833 /* calculate delta power based on the percentage specified from UI */
2834 // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
2835 // We lower TX power here according to the percentage specified from UI
2836 if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
2837 ;
2838 else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
2839 ;
2840 else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW
2841 {
2842 DeltaPwr -= 1;
2843 }
2844 else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW
2845 {
2846 DeltaPwr -= 3;
2847 }
2848 else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW
2849 {
2850 DeltaPwr -= 6;
2851 }
2852 else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW
2853 {
2854 DeltaPwr -= 9;
2855 }
2856 else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW
2857 {
2858 DeltaPwr -= 12;
2859 }
2860
2861 /* reset different new tx power for different TX rate */
2862 for(i=0; i<5; i++)
2863 {
2864 if (TxPwr[i] != 0xffffffff)
2865 {
2866 for (j=0; j<8; j++)
2867 {
2868 Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
2869
2870 if ((Value + DeltaPwr) < 0)
2871 {
2872 Value = 0; /* min */
2873 }
2874 else if ((Value + DeltaPwr) > 0xF)
2875 {
2876 Value = 0xF; /* max */
2877 }
2878 else
2879 {
2880 Value += DeltaPwr; /* temperature compensation */
2881 }
2882
2883 /* fill new value to CSR offset */
2884 TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
2885 }
2886
2887 /* write tx power value to CSR */
2888 /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
2889 TX power for OFDM 6M/9M
2890 TX power for CCK5.5M/11M
2891 TX power for CCK1M/2M */
2892 /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
2893 RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
2894
2895
2896 }
2897 }
2898
2899}
2900
2901/*
2902 ========================================================================
2903 Routine Description:
2904 Write TxWI for ATE mode.
2905
2906 Return Value:
2907 None
2908 ========================================================================
2909*/
2910#ifdef RT2860
2911static VOID ATEWriteTxWI(
2912 IN PRTMP_ADAPTER pAd,
2913 IN PTXWI_STRUC pOutTxWI,
2914 IN BOOLEAN FRAG,
2915 IN BOOLEAN CFACK,
2916 IN BOOLEAN InsTimestamp,
2917 IN BOOLEAN AMPDU,
2918 IN BOOLEAN Ack,
2919 IN BOOLEAN NSeq, // HW new a sequence.
2920 IN UCHAR BASize,
2921 IN UCHAR WCID,
2922 IN ULONG Length,
2923 IN UCHAR PID,
2924 IN UCHAR TID,
2925 IN UCHAR TxRate,
2926 IN UCHAR Txopmode,
2927 IN BOOLEAN CfAck,
2928 IN HTTRANSMIT_SETTING *pTransmit)
2929{
2930 TXWI_STRUC TxWI;
2931 PTXWI_STRUC pTxWI;
2932
2933 //
2934 // Always use Long preamble before verifiation short preamble functionality works well.
2935 // Todo: remove the following line if short preamble functionality works
2936 //
2937 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
2938 NdisZeroMemory(&TxWI, TXWI_SIZE);
2939 pTxWI = &TxWI;
2940
2941 pTxWI->FRAG= FRAG;
2942
2943 pTxWI->CFACK = CFACK;
2944 pTxWI->TS= InsTimestamp;
2945 pTxWI->AMPDU = AMPDU;
2946 pTxWI->ACK = Ack;
2947 pTxWI->txop= Txopmode;
2948
2949 pTxWI->NSEQ = NSeq;
2950 // John tune the performace with Intel Client in 20 MHz performance
2951 if( BASize >7 )
2952 BASize =7;
2953
2954 pTxWI->BAWinSize = BASize;
2955 pTxWI->WirelessCliID = WCID;
2956 pTxWI->MPDUtotalByteCount = Length;
2957 pTxWI->PacketId = PID;
2958
2959 // If CCK or OFDM, BW must be 20
2960 pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
2961 pTxWI->ShortGI = pTransmit->field.ShortGI;
2962 pTxWI->STBC = pTransmit->field.STBC;
2963
2964 pTxWI->MCS = pTransmit->field.MCS;
2965 pTxWI->PHYMODE = pTransmit->field.MODE;
2966 pTxWI->CFACK = CfAck;
2967 pTxWI->MIMOps = 0;
2968 pTxWI->MpduDensity = 0;
2969
2970 pTxWI->PacketId = pTxWI->MCS;
2971 NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
2972
2973 return;
2974}
2975#endif // RT2860 //
2976
2977/*
2978 ========================================================================
2979
2980 Routine Description:
2981 Disable protection for ATE.
2982 ========================================================================
2983*/
2984VOID ATEDisableAsicProtect(
2985 IN PRTMP_ADAPTER pAd)
2986{
2987 PROT_CFG_STRUC ProtCfg, ProtCfg4;
2988 UINT32 Protect[6];
2989 USHORT offset;
2990 UCHAR i;
2991 UINT32 MacReg = 0;
2992
2993 // Config ASIC RTS threshold register
2994 RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
2995 MacReg &= 0xFF0000FF;
2996 MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
2997 RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
2998
2999 // Initial common protection settings
3000 RTMPZeroMemory(Protect, sizeof(Protect));
3001 ProtCfg4.word = 0;
3002 ProtCfg.word = 0;
3003 ProtCfg.field.TxopAllowGF40 = 1;
3004 ProtCfg.field.TxopAllowGF20 = 1;
3005 ProtCfg.field.TxopAllowMM40 = 1;
3006 ProtCfg.field.TxopAllowMM20 = 1;
3007 ProtCfg.field.TxopAllowOfdm = 1;
3008 ProtCfg.field.TxopAllowCck = 1;
3009 ProtCfg.field.RTSThEn = 1;
3010 ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
3011
3012 // Handle legacy(B/G) protection
3013 ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
3014 ProtCfg.field.ProtectCtrl = 0;
3015 Protect[0] = ProtCfg.word;
3016 Protect[1] = ProtCfg.word;
3017
3018 // NO PROTECT
3019 // 1.All STAs in the BSS are 20/40 MHz HT
3020 // 2. in ai 20/40MHz BSS
3021 // 3. all STAs are 20MHz in a 20MHz BSS
3022 // Pure HT. no protection.
3023
3024 // MM20_PROT_CFG
3025 // Reserved (31:27)
3026 // PROT_TXOP(25:20) -- 010111
3027 // PROT_NAV(19:18) -- 01 (Short NAV protection)
3028 // PROT_CTRL(17:16) -- 00 (None)
3029 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
3030 Protect[2] = 0x01744004;
3031
3032 // MM40_PROT_CFG
3033 // Reserved (31:27)
3034 // PROT_TXOP(25:20) -- 111111
3035 // PROT_NAV(19:18) -- 01 (Short NAV protection)
3036 // PROT_CTRL(17:16) -- 00 (None)
3037 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
3038 Protect[3] = 0x03f44084;
3039
3040 // CF20_PROT_CFG
3041 // Reserved (31:27)
3042 // PROT_TXOP(25:20) -- 010111
3043 // PROT_NAV(19:18) -- 01 (Short NAV protection)
3044 // PROT_CTRL(17:16) -- 00 (None)
3045 // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
3046 Protect[4] = 0x01744004;
3047
3048 // CF40_PROT_CFG
3049 // Reserved (31:27)
3050 // PROT_TXOP(25:20) -- 111111
3051 // PROT_NAV(19:18) -- 01 (Short NAV protection)
3052 // PROT_CTRL(17:16) -- 00 (None)
3053 // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
3054 Protect[5] = 0x03f44084;
3055
3056 pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
3057
3058 offset = CCK_PROT_CFG;
3059 for (i = 0;i < 6;i++)
3060 RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
3061
3062}
3063
3064
3065/* There are two ways to convert Rssi */
3066#if 1
3067//
3068// The way used with GET_LNA_GAIN().
3069//
3070CHAR ATEConvertToRssi(
3071 IN PRTMP_ADAPTER pAd,
3072 IN CHAR Rssi,
3073 IN UCHAR RssiNumber)
3074{
3075 UCHAR RssiOffset, LNAGain;
3076
3077 // Rssi equals to zero should be an invalid value
3078 if (Rssi == 0)
3079 return -99;
3080
3081 LNAGain = GET_LNA_GAIN(pAd);
3082 if (pAd->LatchRfRegs.Channel > 14)
3083 {
3084 if (RssiNumber == 0)
3085 RssiOffset = pAd->ARssiOffset0;
3086 else if (RssiNumber == 1)
3087 RssiOffset = pAd->ARssiOffset1;
3088 else
3089 RssiOffset = pAd->ARssiOffset2;
3090 }
3091 else
3092 {
3093 if (RssiNumber == 0)
3094 RssiOffset = pAd->BGRssiOffset0;
3095 else if (RssiNumber == 1)
3096 RssiOffset = pAd->BGRssiOffset1;
3097 else
3098 RssiOffset = pAd->BGRssiOffset2;
3099 }
3100
3101 return (-12 - RssiOffset - LNAGain - Rssi);
3102}
3103#else
3104//
3105// The way originally used in ATE of rt2860ap.
3106//
3107CHAR ATEConvertToRssi(
3108 IN PRTMP_ADAPTER pAd,
3109 IN CHAR Rssi,
3110 IN UCHAR RssiNumber)
3111{
3112 UCHAR RssiOffset, LNAGain;
3113
3114 // Rssi equals to zero should be an invalid value
3115 if (Rssi == 0)
3116 return -99;
3117
3118 if (pAd->LatchRfRegs.Channel > 14)
3119 {
3120 LNAGain = pAd->ALNAGain;
3121 if (RssiNumber == 0)
3122 RssiOffset = pAd->ARssiOffset0;
3123 else if (RssiNumber == 1)
3124 RssiOffset = pAd->ARssiOffset1;
3125 else
3126 RssiOffset = pAd->ARssiOffset2;
3127 }
3128 else
3129 {
3130 LNAGain = pAd->BLNAGain;
3131 if (RssiNumber == 0)
3132 RssiOffset = pAd->BGRssiOffset0;
3133 else if (RssiNumber == 1)
3134 RssiOffset = pAd->BGRssiOffset1;
3135 else
3136 RssiOffset = pAd->BGRssiOffset2;
3137 }
3138
3139 return (-32 - RssiOffset + LNAGain - Rssi);
3140}
3141#endif /* end of #if 1 */
3142
3143/*
3144 ========================================================================
3145
3146 Routine Description:
3147 Set Japan filter coefficients if needed.
3148 Note:
3149 This routine should only be called when
3150 entering TXFRAME mode or TXCONT mode.
3151
3152 ========================================================================
3153*/
3154static VOID SetJapanFilter(
3155 IN PRTMP_ADAPTER pAd)
3156{
3157 UCHAR BbpData = 0;
3158
3159 //
3160 // If Channel=14 and Bandwidth=20M and Mode=CCK, set BBP R4 bit5=1
3161 // (Japan Tx filter coefficients)when (TXFRAME or TXCONT).
3162 //
3163 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpData);
3164
3165 if ((pAd->ate.TxWI.PHYMODE == MODE_CCK) && (pAd->ate.Channel == 14) && (pAd->ate.TxWI.BW == BW_20))
3166 {
3167 BbpData |= 0x20; // turn on
3168 ATEDBGPRINT(RT_DEBUG_TRACE, ("SetJapanFilter!!!\n"));
3169 }
3170 else
3171 {
3172 BbpData &= 0xdf; // turn off
3173 ATEDBGPRINT(RT_DEBUG_TRACE, ("ClearJapanFilter!!!\n"));
3174 }
3175
3176 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData);
3177}
3178
3179VOID ATESampleRssi(
3180 IN PRTMP_ADAPTER pAd,
3181 IN PRXWI_STRUC pRxWI)
3182{
3183 /* There are two ways to collect RSSI. */
3184#if 1
3185 //pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
3186 if (pRxWI->RSSI0 != 0)
3187 {
3188 pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
3189 pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
3190 pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3;
3191 }
3192 if (pRxWI->RSSI1 != 0)
3193 {
3194 pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
3195 pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
3196 pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3;
3197 }
3198 if (pRxWI->RSSI2 != 0)
3199 {
3200 pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
3201 pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
3202 pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3;
3203 }
3204
3205 pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);// CHAR ==> UCHAR ?
3206 pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);// CHAR ==> UCHAR ?
3207
3208 pAd->ate.NumOfAvgRssiSample ++;
3209#else
3210 pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);
3211 pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);
3212 pAd->ate.RxCntPerSec++;
3213 pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
3214 pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
3215 pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
3216 pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
3217 pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3;
3218 pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
3219 pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3;
3220 pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
3221 pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3;
3222 pAd->ate.NumOfAvgRssiSample ++;
3223#endif
3224}
3225
3226#ifdef CONFIG_STA_SUPPORT
3227VOID RTMPStationStop(
3228 IN PRTMP_ADAPTER pAd)
3229{
3230// BOOLEAN Cancelled;
3231
3232 ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStop\n"));
3233
3234#if 0
3235 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
3236 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
3237 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
3238 RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
3239 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
3240 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
3241#endif
3242 // For rx statistics, we need to keep this timer running.
3243// RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
3244
3245 ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStop\n"));
3246}
3247
3248VOID RTMPStationStart(
3249 IN PRTMP_ADAPTER pAd)
3250{
3251 ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStart\n"));
3252#ifdef RT2860
3253 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
3254 //
3255 // We did not cancel this timer when entering ATE mode.
3256 //
3257// RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
3258#endif // RT2860 //
3259 ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStart\n"));
3260}
3261#endif // CONFIG_STA_SUPPORT //
3262
3263/*
3264 ==========================================================================
3265 Description:
3266 Setup Frame format.
3267 NOTE:
3268 This routine should only be used in ATE mode.
3269 ==========================================================================
3270 */
3271#ifdef RT2860
3272static INT ATESetUpFrame(
3273 IN PRTMP_ADAPTER pAd,
3274 IN UINT32 TxIdx)
3275{
3276 UINT j;
3277 PTXD_STRUC pTxD;
3278#ifdef RT_BIG_ENDIAN
3279 PTXD_STRUC pDestTxD;
3280 TXD_STRUC TxD;
3281#endif
3282 PNDIS_PACKET pPacket;
3283 PUCHAR pDest;
3284 PVOID AllocVa;
3285 NDIS_PHYSICAL_ADDRESS AllocPa;
3286 HTTRANSMIT_SETTING TxHTPhyMode;
3287
3288 PRTMP_TX_RING pTxRing = &pAd->TxRing[QID_AC_BE];
3289 PTXWI_STRUC pTxWI = (PTXWI_STRUC) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
3290 PUCHAR pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
3291
3292#ifdef RALINK_28xx_QA
3293 PHEADER_802_11 pHeader80211;
3294#endif // RALINK_28xx_QA //
3295
3296 if (pAd->ate.bQATxStart == TRUE)
3297 {
3298 // always use QID_AC_BE and FIFO_EDCA
3299
3300 // fill TxWI
3301 TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
3302 TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
3303 TxHTPhyMode.field.STBC = 0;
3304 TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
3305 TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
3306 ATEWriteTxWI(pAd, pTxWI, pAd->ate.TxWI.FRAG, pAd->ate.TxWI.CFACK, pAd->ate.TxWI.TS, pAd->ate.TxWI.AMPDU, pAd->ate.TxWI.ACK, pAd->ate.TxWI.NSEQ,
3307 pAd->ate.TxWI.BAWinSize, 0, pAd->ate.TxWI.MPDUtotalByteCount, pAd->ate.TxWI.PacketId, 0, 0, pAd->ate.TxWI.txop/*IFS_HTTXOP*/, pAd->ate.TxWI.CFACK/*FALSE*/, &TxHTPhyMode);
3308 }
3309 else
3310 {
3311 TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
3312 TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
3313 TxHTPhyMode.field.STBC = 0;
3314 TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
3315 TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
3316 ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
3317 4, 0, pAd->ate.TxLength, 0, 0, 0, IFS_HTTXOP, FALSE, &TxHTPhyMode);
3318 }
3319
3320 // fill 802.11 header.
3321#ifdef RALINK_28xx_QA
3322 if (pAd->ate.bQATxStart == TRUE)
3323 {
3324 NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE, pAd->ate.Header, pAd->ate.HLen);
3325 }
3326 else
3327#endif // RALINK_28xx_QA //
3328 {
3329 NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE, TemplateFrame, LENGTH_802_11);
3330 NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE+4, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
3331 NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE+10, pAd->ate.Addr2, ETH_LENGTH_OF_ADDRESS);
3332 NdisMoveMemory(pDMAHeaderBufVA+TXWI_SIZE+16, pAd->ate.Addr3, ETH_LENGTH_OF_ADDRESS);
3333 }
3334
3335#ifdef RT_BIG_ENDIAN
3336 RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA)+TXWI_SIZE), DIR_READ, FALSE);
3337#endif // RT_BIG_ENDIAN //
3338
3339 /* alloc buffer for payload */
3340#ifdef RALINK_28xx_QA
3341 if (pAd->ate.bQATxStart == TRUE)
3342 {
3343 /* Why not use RTMP_AllocateTxPacketBuffer() instead of RTMP_AllocateRxPacketBuffer()? */
3344 pPacket = RTMP_AllocateRxPacketBuffer(pAd, pAd->ate.DLen + 0x100, FALSE, &AllocVa, &AllocPa);
3345 }
3346 else
3347#endif // RALINK_28xx_QA //
3348 {
3349 /* Why not use RTMP_AllocateTxPacketBuffer() instead of RTMP_AllocateRxPacketBuffer()? */
3350 pPacket = RTMP_AllocateRxPacketBuffer(pAd, pAd->ate.TxLength, FALSE, &AllocVa, &AllocPa);
3351 }
3352
3353 if (pPacket == NULL)
3354 {
3355 pAd->ate.TxCount = 0;
3356 ATEDBGPRINT(RT_DEBUG_TRACE, ("%s fail to alloc packet space.\n", __FUNCTION__));
3357 return -1;
3358 }
3359 pTxRing->Cell[TxIdx].pNextNdisPacket = pPacket;
3360
3361 pDest = (PUCHAR) AllocVa;
3362
3363#ifdef RALINK_28xx_QA
3364 if (pAd->ate.bQATxStart == TRUE)
3365 {
3366 RTPKT_TO_OSPKT(pPacket)->len = pAd->ate.DLen;
3367 }
3368 else
3369#endif // RALINK_28xx_QA //
3370 {
3371 RTPKT_TO_OSPKT(pPacket)->len = pAd->ate.TxLength - LENGTH_802_11;
3372 }
3373
3374 // Prepare frame payload
3375#ifdef RALINK_28xx_QA
3376 if (pAd->ate.bQATxStart == TRUE)
3377 {
3378 // copy pattern
3379 if ((pAd->ate.PLen != 0))
3380 {
3381 int j;
3382
3383 for (j = 0; j < pAd->ate.DLen; j+=pAd->ate.PLen)
3384 {
3385 memcpy(RTPKT_TO_OSPKT(pPacket)->data + j, pAd->ate.Pattern, pAd->ate.PLen);
3386 }
3387 }
3388 }
3389 else
3390#endif // RALINK_28xx_QA //
3391 {
3392 for(j = 0; j < RTPKT_TO_OSPKT(pPacket)->len; j++)
3393 pDest[j] = 0xA5;
3394 }
3395
3396 //
3397 // build Tx Descriptor
3398 //
3399#ifndef RT_BIG_ENDIAN
3400 pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa;
3401#else
3402 pDestTxD = (PTXD_STRUC)pTxRing->Cell[TxIdx].AllocVa;
3403 TxD = *pDestTxD;
3404 pTxD = &TxD;
3405#endif // !RT_BIG_ENDIAN //
3406
3407#ifdef RALINK_28xx_QA
3408 if (pAd->ate.bQATxStart == TRUE)
3409 {
3410 // prepare TxD
3411 NdisZeroMemory(pTxD, TXD_SIZE);
3412 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
3413 // build TX DESC
3414 pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
3415 pTxD->SDLen0 = TXWI_SIZE + pAd->ate.HLen;
3416 pTxD->LastSec0 = 0;
3417 pTxD->SDPtr1 = AllocPa;
3418 pTxD->SDLen1 = RTPKT_TO_OSPKT(pPacket)->len;
3419 pTxD->LastSec1 = 1;
3420
3421 pDest = (PUCHAR)pTxWI;
3422 pDest += TXWI_SIZE;
3423 pHeader80211 = (PHEADER_802_11)pDest;
3424
3425 // modify sequence number....
3426 if (pAd->ate.TxDoneCount == 0)
3427 {
3428 pAd->ate.seq = pHeader80211->Sequence;
3429 }
3430 else
3431 pHeader80211->Sequence = ++pAd->ate.seq;
3432 }
3433 else
3434#endif // RALINK_28xx_QA //
3435 {
3436 NdisZeroMemory(pTxD, TXD_SIZE);
3437 RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
3438 // build TX DESC
3439 pTxD->SDPtr0 = RTMP_GetPhysicalAddressLow (pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
3440 pTxD->SDLen0 = TXWI_SIZE + LENGTH_802_11;
3441 pTxD->LastSec0 = 0;
3442 pTxD->SDPtr1 = AllocPa;
3443 pTxD->SDLen1 = RTPKT_TO_OSPKT(pPacket)->len;
3444 pTxD->LastSec1 = 1;
3445 }
3446
3447#ifdef RT_BIG_ENDIAN
3448 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
3449 RTMPFrameEndianChange(pAd, (((PUCHAR)pDMAHeaderBufVA)+TXWI_SIZE), DIR_WRITE, FALSE);
3450 RTMPDescriptorEndianChange((PUCHAR)pTxD, TYPE_TXD);
3451 WriteBackToDescriptor((PUCHAR)pDestTxD, (PUCHAR)pTxD, FALSE, TYPE_TXD);
3452#endif // RT_BIG_ENDIAN //
3453 return 0;
3454}
3455/* */
3456/* */
3457/*=======================End of RT2860=======================*/
3458#endif // RT2860 //
3459
3460
3461VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
3462{
3463 USHORT i;
3464 USHORT value;
3465
3466 for (i = 0 ; i < EEPROM_SIZE/2 ; )
3467 {
3468 /* "value" is expecially for some compilers... */
3469 RT28xx_EEPROM_READ16(pAd, i*2, value);
3470 Data[i] = value;
3471 i++;
3472 }
3473}
3474
3475VOID rt_ee_write_all(PRTMP_ADAPTER pAd, USHORT *Data)
3476{
3477 USHORT i;
3478 USHORT value;
3479
3480 for (i = 0 ; i < EEPROM_SIZE/2 ; )
3481 {
3482 /* "value" is expecially for some compilers... */
3483 value = Data[i];
3484 RT28xx_EEPROM_WRITE16(pAd, i*2, value);
3485 i ++;
3486 }
3487}
3488#ifdef RALINK_28xx_QA
3489VOID ATE_QA_Statistics(
3490 IN PRTMP_ADAPTER pAd,
3491 IN PRXWI_STRUC pRxWI,
3492 IN PRT28XX_RXD_STRUC pRxD,
3493 IN PHEADER_802_11 pHeader)
3494{
3495 // update counter first
3496 if (pHeader != NULL)
3497 {
3498 if (pHeader->FC.Type == BTYPE_DATA)
3499 {
3500 if (pRxD->U2M)
3501 pAd->ate.U2M++;
3502 else
3503 pAd->ate.OtherData++;
3504 }
3505 else if (pHeader->FC.Type == BTYPE_MGMT)
3506 {
3507 if (pHeader->FC.SubType == SUBTYPE_BEACON)
3508 pAd->ate.Beacon++;
3509 else
3510 pAd->ate.OtherCount++;
3511 }
3512 else if (pHeader->FC.Type == BTYPE_CNTL)
3513 {
3514 pAd->ate.OtherCount++;
3515 }
3516 }
3517 pAd->ate.RSSI0 = pRxWI->RSSI0;
3518 pAd->ate.RSSI1 = pRxWI->RSSI1;
3519 pAd->ate.RSSI2 = pRxWI->RSSI2;
3520 pAd->ate.SNR0 = pRxWI->SNR0;
3521 pAd->ate.SNR1 = pRxWI->SNR1;
3522}
3523
3524/* command id with Cmd Type == 0x0008(for 28xx)/0x0005(for iNIC) */
3525#define RACFG_CMD_RF_WRITE_ALL 0x0000
3526#define RACFG_CMD_E2PROM_READ16 0x0001
3527#define RACFG_CMD_E2PROM_WRITE16 0x0002
3528#define RACFG_CMD_E2PROM_READ_ALL 0x0003
3529#define RACFG_CMD_E2PROM_WRITE_ALL 0x0004
3530#define RACFG_CMD_IO_READ 0x0005
3531#define RACFG_CMD_IO_WRITE 0x0006
3532#define RACFG_CMD_IO_READ_BULK 0x0007
3533#define RACFG_CMD_BBP_READ8 0x0008
3534#define RACFG_CMD_BBP_WRITE8 0x0009
3535#define RACFG_CMD_BBP_READ_ALL 0x000a
3536#define RACFG_CMD_GET_COUNTER 0x000b
3537#define RACFG_CMD_CLEAR_COUNTER 0x000c
3538
3539#define RACFG_CMD_RSV1 0x000d
3540#define RACFG_CMD_RSV2 0x000e
3541#define RACFG_CMD_RSV3 0x000f
3542
3543#define RACFG_CMD_TX_START 0x0010
3544#define RACFG_CMD_GET_TX_STATUS 0x0011
3545#define RACFG_CMD_TX_STOP 0x0012
3546#define RACFG_CMD_RX_START 0x0013
3547#define RACFG_CMD_RX_STOP 0x0014
3548#define RACFG_CMD_GET_NOISE_LEVEL 0x0015
3549
3550#define RACFG_CMD_ATE_START 0x0080
3551#define RACFG_CMD_ATE_STOP 0x0081
3552
3553#define RACFG_CMD_ATE_START_TX_CARRIER 0x0100
3554#define RACFG_CMD_ATE_START_TX_CONT 0x0101
3555#define RACFG_CMD_ATE_START_TX_FRAME 0x0102
3556#define RACFG_CMD_ATE_SET_BW 0x0103
3557#define RACFG_CMD_ATE_SET_TX_POWER0 0x0104
3558#define RACFG_CMD_ATE_SET_TX_POWER1 0x0105
3559#define RACFG_CMD_ATE_SET_FREQ_OFFSET 0x0106
3560#define RACFG_CMD_ATE_GET_STATISTICS 0x0107
3561#define RACFG_CMD_ATE_RESET_COUNTER 0x0108
3562#define RACFG_CMD_ATE_SEL_TX_ANTENNA 0x0109
3563#define RACFG_CMD_ATE_SEL_RX_ANTENNA 0x010a
3564#define RACFG_CMD_ATE_SET_PREAMBLE 0x010b
3565#define RACFG_CMD_ATE_SET_CHANNEL 0x010c
3566#define RACFG_CMD_ATE_SET_ADDR1 0x010d
3567#define RACFG_CMD_ATE_SET_ADDR2 0x010e
3568#define RACFG_CMD_ATE_SET_ADDR3 0x010f
3569#define RACFG_CMD_ATE_SET_RATE 0x0110
3570#define RACFG_CMD_ATE_SET_TX_FRAME_LEN 0x0111
3571#define RACFG_CMD_ATE_SET_TX_FRAME_COUNT 0x0112
3572#define RACFG_CMD_ATE_START_RX_FRAME 0x0113
3573#define RACFG_CMD_ATE_E2PROM_READ_BULK 0x0114
3574#define RACFG_CMD_ATE_E2PROM_WRITE_BULK 0x0115
3575#define RACFG_CMD_ATE_IO_WRITE_BULK 0x0116
3576#define RACFG_CMD_ATE_BBP_READ_BULK 0x0117
3577#define RACFG_CMD_ATE_BBP_WRITE_BULK 0x0118
3578#define RACFG_CMD_ATE_RF_READ_BULK 0x0119
3579#define RACFG_CMD_ATE_RF_WRITE_BULK 0x011a
3580
3581
3582
3583#define A2Hex(_X, _p) \
3584{ \
3585 UCHAR *p; \
3586 _X = 0; \
3587 p = _p; \
3588 while (((*p >= 'a') && (*p <= 'f')) || ((*p >= 'A') && (*p <= 'F')) || ((*p >= '0') && (*p <= '9'))) \
3589 { \
3590 if ((*p >= 'a') && (*p <= 'f')) \
3591 _X = _X * 16 + *p - 87; \
3592 else if ((*p >= 'A') && (*p <= 'F')) \
3593 _X = _X * 16 + *p - 55; \
3594 else if ((*p >= '0') && (*p <= '9')) \
3595 _X = _X * 16 + *p - 48; \
3596 p++; \
3597 } \
3598}
3599
3600
3601static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
3602static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
3603static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len);
3604
3605#ifdef UCOS
3606int ate_copy_to_user(
3607 IN PUCHAR payload,
3608 IN PUCHAR msg,
3609 IN INT len)
3610{
3611 memmove(payload, msg, len);
3612 return 0;
3613}
3614
3615#undef copy_to_user
3616#define copy_to_user(x,y,z) ate_copy_to_user((PUCHAR)x, (PUCHAR)y, z)
3617#endif // UCOS //
3618
3619#define LEN_OF_ARG 16
3620
3621VOID RtmpDoAte(
3622 IN PRTMP_ADAPTER pAdapter,
3623 IN struct iwreq *wrq)
3624{
3625 unsigned short Command_Id;
3626 struct ate_racfghdr *pRaCfg;
3627 INT Status = NDIS_STATUS_SUCCESS;
3628
3629
3630
3631 if((pRaCfg = kmalloc(sizeof(struct ate_racfghdr), GFP_KERNEL)) == NULL)
3632 {
3633 Status = -EINVAL;
3634 return;
3635 }
3636
3637 NdisZeroMemory(pRaCfg, sizeof(struct ate_racfghdr));
3638
3639 if (copy_from_user((PUCHAR)pRaCfg, wrq->u.data.pointer, wrq->u.data.length))
3640 {
3641 Status = -EFAULT;
3642 kfree(pRaCfg);
3643 return;
3644 }
3645
3646
3647 Command_Id = ntohs(pRaCfg->command_id);
3648
3649 ATEDBGPRINT(RT_DEBUG_TRACE,("\n%s: Command_Id = 0x%04x !\n", __FUNCTION__, Command_Id));
3650
3651 switch (Command_Id)
3652 {
3653 // We will get this command when QA starts.
3654 case RACFG_CMD_ATE_START:
3655 {
3656 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START\n"));
3657
3658 // prepare feedback as soon as we can to avoid QA timeout.
3659 pRaCfg->length = htons(2);
3660 pRaCfg->status = htons(0);
3661
3662 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
3663 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
3664 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
3665
3666 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
3667
3668 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
3669 {
3670 ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_ATE_START\n"));
3671 Status = -EFAULT;
3672 }
3673 else
3674 {
3675 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START is done !\n"));
3676 }
3677 Set_ATE_Proc(pAdapter, "ATESTART");
3678 }
3679 break;
3680
3681 // We will get this command either QA is closed or ated is killed by user.
3682 case RACFG_CMD_ATE_STOP:
3683 {
3684#ifndef UCOS
3685 INT32 ret;
3686#endif // !UCOS //
3687
3688 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_STOP\n"));
3689
3690 // Distinguish this command came from QA(via ated)
3691 // or ate daemon according to the existence of pid in payload.
3692 // No need to prepare feedback if this cmd came directly from ate daemon.
3693 pRaCfg->length = ntohs(pRaCfg->length);
3694
3695 if (pRaCfg->length == sizeof(pAdapter->ate.AtePid))
3696 {
3697 // This command came from QA.
3698 // Get the pid of ATE daemon.
3699 memcpy((UCHAR *)&pAdapter->ate.AtePid,
3700 (&pRaCfg->data[0]) - 2/* == &(pRaCfg->status) */,
3701 sizeof(pAdapter->ate.AtePid));
3702
3703 // prepare feedback as soon as we can to avoid QA timeout.
3704 pRaCfg->length = htons(2);
3705 pRaCfg->status = htons(0);
3706
3707 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
3708 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
3709 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
3710
3711 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
3712
3713 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
3714 {
3715 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_STOP\n"));
3716 Status = -EFAULT;
3717 }
3718
3719 //
3720 // kill ATE daemon when leaving ATE mode.
3721 // We must kill ATE daemon first before setting ATESTOP,
3722 // or Microsoft will report sth. wrong.
3723#ifndef UCOS
3724 ret = KILL_THREAD_PID(pAdapter->ate.AtePid, SIGTERM, 1);
3725 if (ret)
3726 {
3727 ATEDBGPRINT(RT_DEBUG_ERROR, ("%s: unable to signal thread\n", pAdapter->net_dev->name));
3728 }
3729#endif // !UCOS //
3730 }
3731
3732 // AP might have in ATE_STOP mode due to cmd from QA.
3733 if (ATE_ON(pAdapter))
3734 {
3735 // Someone has killed ate daemon while QA GUI is still open.
3736 Set_ATE_Proc(pAdapter, "ATESTOP");
3737 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_AP_START is done !\n"));
3738 }
3739 }
3740 break;
3741
3742 case RACFG_CMD_RF_WRITE_ALL:
3743 {
3744 UINT32 R1, R2, R3, R4;
3745 USHORT channel;
3746
3747 memcpy(&R1, pRaCfg->data-2, 4);
3748 memcpy(&R2, pRaCfg->data+2, 4);
3749 memcpy(&R3, pRaCfg->data+6, 4);
3750 memcpy(&R4, pRaCfg->data+10, 4);
3751 memcpy(&channel, pRaCfg->data+14, 2);
3752
3753 pAdapter->LatchRfRegs.R1 = ntohl(R1);
3754 pAdapter->LatchRfRegs.R2 = ntohl(R2);
3755 pAdapter->LatchRfRegs.R3 = ntohl(R3);
3756 pAdapter->LatchRfRegs.R4 = ntohl(R4);
3757 pAdapter->LatchRfRegs.Channel = ntohs(channel);
3758
3759 RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R1);
3760 RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R2);
3761 RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R3);
3762 RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R4);
3763
3764 // prepare feedback
3765 pRaCfg->length = htons(2);
3766 pRaCfg->status = htons(0);
3767
3768 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
3769 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
3770 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
3771
3772 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
3773 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
3774 {
3775 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RF_WRITE_ALL\n"));
3776 Status = -EFAULT;
3777 }
3778 else
3779 {
3780 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RF_WRITE_ALL is done !\n"));
3781 }
3782 }
3783 break;
3784
3785 case RACFG_CMD_E2PROM_READ16:
3786 {
3787 USHORT offset, value, tmp;
3788
3789 offset = ntohs(pRaCfg->status);
3790 /* "tmp" is expecially for some compilers... */
3791 RT28xx_EEPROM_READ16(pAdapter, offset, tmp);
3792 value = tmp;
3793 value = htons(value);
3794
3795 ATEDBGPRINT(RT_DEBUG_TRACE,("EEPROM Read offset = 0x%04x, value = 0x%04x\n", offset, value));
3796
3797 // prepare feedback
3798 pRaCfg->length = htons(4);
3799 pRaCfg->status = htons(0);
3800 memcpy(pRaCfg->data, &value, 2);
3801
3802 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
3803 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
3804 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
3805
3806 ATEDBGPRINT(RT_DEBUG_TRACE, ("sizeof(struct ate_racfghdr) = %d\n", sizeof(struct ate_racfghdr)));
3807 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
3808
3809 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
3810 {
3811 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ16\n"));
3812 Status = -EFAULT;
3813 }
3814 else
3815 {
3816 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ16 is done !\n"));
3817 }
3818 }
3819 break;
3820
3821 case RACFG_CMD_E2PROM_WRITE16:
3822 {
3823 USHORT offset, value;
3824
3825 offset = ntohs(pRaCfg->status);
3826 memcpy(&value, pRaCfg->data, 2);
3827 value = ntohs(value);
3828 RT28xx_EEPROM_WRITE16(pAdapter, offset, value);
3829
3830 // prepare feedback
3831 pRaCfg->length = htons(2);
3832 pRaCfg->status = htons(0);
3833 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
3834 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
3835 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
3836
3837 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
3838 {
3839 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE16\n"));
3840 Status = -EFAULT;
3841 }
3842 else
3843 {
3844 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_WRITE16 is done !\n"));
3845 }
3846 }
3847 break;
3848
3849 case RACFG_CMD_E2PROM_READ_ALL:
3850 {
3851 USHORT buffer[EEPROM_SIZE/2];
3852
3853 rt_ee_read_all(pAdapter,(USHORT *)buffer);
3854 memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer, EEPROM_SIZE);
3855
3856 // prepare feedback
3857 pRaCfg->length = htons(2+EEPROM_SIZE);
3858 pRaCfg->status = htons(0);
3859 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
3860 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
3861 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
3862
3863 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
3864 {
3865 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ_ALL\n"));
3866 Status = -EFAULT;
3867 }
3868 else
3869 {
3870 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ_ALL is done !\n"));
3871 }
3872 }
3873 break;
3874
3875 case RACFG_CMD_E2PROM_WRITE_ALL:
3876 {
3877 USHORT buffer[EEPROM_SIZE/2];
3878
3879 NdisZeroMemory((UCHAR *)buffer, EEPROM_SIZE);
3880 memcpy_exs(pAdapter, (UCHAR *)buffer, (UCHAR *)&pRaCfg->status, EEPROM_SIZE);
3881 rt_ee_write_all(pAdapter,(USHORT *)buffer);
3882
3883 // prepare feedback
3884 pRaCfg->length = htons(2);
3885 pRaCfg->status = htons(0);
3886 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
3887 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
3888 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
3889
3890 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
3891 {
3892 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE_ALL\n"));
3893 Status = -EFAULT;
3894 }
3895 else
3896 {
3897 ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_E2PROM_WRITE_ALL is done !\n"));
3898 }
3899
3900 }
3901 break;
3902
3903 case RACFG_CMD_IO_READ:
3904 {
3905 UINT32 offset;
3906 UINT32 value;
3907
3908 memcpy(&offset, &pRaCfg->status, 4);
3909 offset = ntohl(offset);
3910
3911 // We do not need the base address.
3912 // So just extract the offset out.
3913 offset &= 0x0000FFFF;
3914 RTMP_IO_READ32(pAdapter, offset, &value);
3915 value = htonl(value);
3916
3917 // prepare feedback
3918 pRaCfg->length = htons(6);
3919 pRaCfg->status = htons(0);
3920 memcpy(pRaCfg->data, &value, 4);
3921
3922 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
3923 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
3924 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
3925
3926 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
3927 {
3928 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ\n"));
3929 Status = -EFAULT;
3930 }
3931 else
3932 {
3933 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ is done !\n"));
3934 }
3935 }
3936 break;
3937
3938 case RACFG_CMD_IO_WRITE:
3939 {
3940 UINT32 offset, value;
3941
3942 memcpy(&offset, pRaCfg->data-2, 4);
3943 memcpy(&value, pRaCfg->data+2, 4);
3944
3945 offset = ntohl(offset);
3946
3947 // We do not need the base address.
3948 // So just extract out the offset.
3949 offset &= 0x0000FFFF;
3950 value = ntohl(value);
3951 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_IO_WRITE: offset = %x, value = %x\n", offset, value));
3952 RTMP_IO_WRITE32(pAdapter, offset, value);
3953
3954 // prepare feedback
3955 pRaCfg->length = htons(2);
3956 pRaCfg->status = htons(0);
3957 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
3958 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
3959 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
3960
3961 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
3962 {
3963 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_WRITE\n"));
3964 Status = -EFAULT;
3965 }
3966 else
3967 {
3968 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_WRITE is done !\n"));
3969 }
3970 }
3971 break;
3972
3973 case RACFG_CMD_IO_READ_BULK:
3974 {
3975 UINT32 offset;
3976 USHORT len;
3977
3978 memcpy(&offset, &pRaCfg->status, 4);
3979 offset = ntohl(offset);
3980
3981 // We do not need the base address.
3982 // So just extract the offset.
3983 offset &= 0x0000FFFF;
3984 memcpy(&len, pRaCfg->data+2, 2);
3985 len = ntohs(len);
3986
3987 if (len > 371)
3988 {
3989 ATEDBGPRINT(RT_DEBUG_TRACE,("len is too large, make it smaller\n"));
3990 pRaCfg->length = htons(2);
3991 pRaCfg->status = htons(1);
3992 break;
3993 }
3994
3995 RTMP_IO_READ_BULK(pAdapter, pRaCfg->data, (UCHAR *)offset, len*4);// unit in four bytes
3996
3997 // prepare feedback
3998 pRaCfg->length = htons(2+len*4);// unit in four bytes
3999 pRaCfg->status = htons(0);
4000 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4001 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4002 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4003
4004 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4005 {
4006 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ_BULK\n"));
4007 Status = -EFAULT;
4008 }
4009 else
4010 {
4011 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ_BULK is done !\n"));
4012 }
4013 }
4014 break;
4015
4016 case RACFG_CMD_BBP_READ8:
4017 {
4018 USHORT offset;
4019 UCHAR value;
4020
4021 value = 0;
4022 offset = ntohs(pRaCfg->status);
4023
4024 if (ATE_ON(pAdapter))
4025 {
4026 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value);
4027 }
4028 else
4029 {
4030 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value);
4031 }
4032 // prepare feedback
4033 pRaCfg->length = htons(3);
4034 pRaCfg->status = htons(0);
4035 pRaCfg->data[0] = value;
4036
4037 ATEDBGPRINT(RT_DEBUG_TRACE,("BBP value = %x\n", value));
4038
4039 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4040 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4041 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4042
4043 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4044 {
4045 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ8\n"));
4046 Status = -EFAULT;
4047 }
4048 else
4049 {
4050 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ8 is done !\n"));
4051 }
4052 }
4053 break;
4054 case RACFG_CMD_BBP_WRITE8:
4055 {
4056 USHORT offset;
4057 UCHAR value;
4058
4059 offset = ntohs(pRaCfg->status);
4060 memcpy(&value, pRaCfg->data, 1);
4061
4062 if (ATE_ON(pAdapter))
4063 {
4064 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value);
4065 }
4066 else
4067 {
4068 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value);
4069 }
4070
4071 if ((offset == BBP_R1) || (offset == BBP_R3))
4072 {
4073 SyncTxRxConfig(pAdapter, offset, value);
4074 }
4075
4076 // prepare feedback
4077 pRaCfg->length = htons(2);
4078 pRaCfg->status = htons(0);
4079 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4080 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4081 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4082
4083 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4084 {
4085 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_WRITE8\n"));
4086 Status = -EFAULT;
4087 }
4088 else
4089 {
4090 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_WRITE8 is done !\n"));
4091 }
4092 }
4093 break;
4094
4095 case RACFG_CMD_BBP_READ_ALL:
4096 {
4097 USHORT j;
4098
4099 for (j = 0; j < 137; j++)
4100 {
4101 pRaCfg->data[j] = 0;
4102
4103 if (ATE_ON(pAdapter))
4104 {
4105 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j]);
4106 }
4107 else
4108 {
4109 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j]);
4110 }
4111 }
4112
4113 // prepare feedback
4114 pRaCfg->length = htons(2+137);
4115 pRaCfg->status = htons(0);
4116
4117 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4118 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4119 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4120
4121 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4122 {
4123 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ_ALL\n"));
4124 Status = -EFAULT;
4125 }
4126 else
4127 {
4128 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ_ALL is done !\n"));
4129 }
4130 }
4131
4132 break;
4133
4134 case RACFG_CMD_ATE_E2PROM_READ_BULK:
4135 {
4136 USHORT offset;
4137 USHORT len;
4138 USHORT buffer[EEPROM_SIZE/2];
4139
4140 offset = ntohs(pRaCfg->status);
4141 memcpy(&len, pRaCfg->data, 2);
4142 len = ntohs(len);
4143
4144 rt_ee_read_all(pAdapter,(USHORT *)buffer);
4145 if (offset + len <= EEPROM_SIZE)
4146 memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer+offset, len);
4147 else
4148 ATEDBGPRINT(RT_DEBUG_ERROR, ("exceed EEPROM size\n"));
4149
4150 // prepare feedback
4151 pRaCfg->length = htons(2+len);
4152 pRaCfg->status = htons(0);
4153 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4154 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4155 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4156
4157 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4158 {
4159 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_READ_BULK\n"));
4160 Status = -EFAULT;
4161 }
4162 else
4163 {
4164 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_E2PROM_READ_BULK is done !\n"));
4165 }
4166
4167 }
4168 break;
4169
4170 case RACFG_CMD_ATE_E2PROM_WRITE_BULK:
4171 {
4172 USHORT offset;
4173 USHORT len;
4174 USHORT buffer[EEPROM_SIZE/2];
4175
4176 offset = ntohs(pRaCfg->status);
4177 memcpy(&len, pRaCfg->data, 2);
4178 len = ntohs(len);
4179
4180 rt_ee_read_all(pAdapter,(USHORT *)buffer);
4181 memcpy_exs(pAdapter, (UCHAR *)buffer + offset, (UCHAR *)pRaCfg->data + 2, len);
4182 rt_ee_write_all(pAdapter,(USHORT *)buffer);
4183
4184 // prepare feedback
4185 pRaCfg->length = htons(2);
4186 pRaCfg->status = htons(0);
4187 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4188 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4189 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4190 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4191 {
4192 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_WRITE_BULK\n"));
4193 Status = -EFAULT;
4194 }
4195 else
4196 {
4197 ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_E2PROM_WRITE_BULK is done !\n"));
4198 }
4199
4200 }
4201 break;
4202
4203 case RACFG_CMD_ATE_IO_WRITE_BULK:
4204 {
4205 UINT32 offset, i, value;
4206 USHORT len;
4207
4208 memcpy(&offset, &pRaCfg->status, 4);
4209 offset = ntohl(offset);
4210 memcpy(&len, pRaCfg->data+2, 2);
4211 len = ntohs(len);
4212
4213 for (i = 0; i < len; i += 4)
4214 {
4215 memcpy_exl(pAdapter, (UCHAR *)&value, pRaCfg->data+4+i, 4);
4216 printk("Write %x %x\n", offset + i, value);
4217 RTMP_IO_WRITE32(pAdapter, (offset +i) & 0xffff, value);
4218 }
4219
4220 // prepare feedback
4221 pRaCfg->length = htons(2);
4222 pRaCfg->status = htons(0);
4223 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4224 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4225 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4226 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4227 {
4228 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_IO_WRITE_BULK\n"));
4229 Status = -EFAULT;
4230 }
4231 else
4232 {
4233 ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_IO_WRITE_BULK is done !\n"));
4234 }
4235
4236 }
4237 break;
4238
4239 case RACFG_CMD_ATE_BBP_READ_BULK:
4240 {
4241 USHORT offset;
4242 USHORT len;
4243 USHORT j;
4244
4245 offset = ntohs(pRaCfg->status);
4246 memcpy(&len, pRaCfg->data, 2);
4247 len = ntohs(len);
4248
4249
4250 for (j = offset; j < (offset+len); j++)
4251 {
4252 pRaCfg->data[j - offset] = 0;
4253
4254 if (pAdapter->ate.Mode == ATE_STOP)
4255 {
4256 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]);
4257 }
4258 else
4259 {
4260 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]);
4261 }
4262 }
4263
4264 // prepare feedback
4265 pRaCfg->length = htons(2+len);
4266 pRaCfg->status = htons(0);
4267 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4268 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4269 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4270
4271 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4272 {
4273 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_READ_BULK\n"));
4274 Status = -EFAULT;
4275 }
4276 else
4277 {
4278 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_READ_BULK is done !\n"));
4279 }
4280
4281 }
4282 break;
4283
4284 case RACFG_CMD_ATE_BBP_WRITE_BULK:
4285 {
4286 USHORT offset;
4287 USHORT len;
4288 USHORT j;
4289 UCHAR *value;
4290
4291 offset = ntohs(pRaCfg->status);
4292 memcpy(&len, pRaCfg->data, 2);
4293 len = ntohs(len);
4294
4295 for (j = offset; j < (offset+len); j++)
4296 {
4297 value = pRaCfg->data + 2 + (j - offset);
4298 if (pAdapter->ate.Mode == ATE_STOP)
4299 {
4300 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j, *value);
4301 }
4302 else
4303 {
4304 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j, *value);
4305 }
4306 }
4307
4308 // prepare feedback
4309 pRaCfg->length = htons(2);
4310 pRaCfg->status = htons(0);
4311 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4312 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4313 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4314
4315 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4316 {
4317 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_WRITE_BULK\n"));
4318 Status = -EFAULT;
4319 }
4320 else
4321 {
4322 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_WRITE_BULK is done !\n"));
4323 }
4324 }
4325 break;
4326
4327#ifdef CONFIG_RALINK_RT3052
4328 case RACFG_CMD_ATE_RF_READ_BULK:
4329 {
4330 USHORT offset;
4331 USHORT len;
4332 USHORT j;
4333
4334 offset = ntohs(pRaCfg->status);
4335 memcpy(&len, pRaCfg->data, 2);
4336 len = ntohs(len);
4337
4338 for (j = offset; j < (offset+len); j++)
4339 {
4340 pRaCfg->data[j - offset] = 0;
4341 RT30xxReadRFRegister(pAdapter, j, &pRaCfg->data[j - offset]);
4342 }
4343
4344 // prepare feedback
4345 pRaCfg->length = htons(2+len);
4346 pRaCfg->status = htons(0);
4347 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4348 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4349 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4350
4351 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4352 {
4353 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_READ_BULK\n"));
4354 Status = -EFAULT;
4355 }
4356 else
4357 {
4358 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_READ_BULK is done !\n"));
4359 }
4360
4361 }
4362 break;
4363
4364 case RACFG_CMD_ATE_RF_WRITE_BULK:
4365 {
4366 USHORT offset;
4367 USHORT len;
4368 USHORT j;
4369 UCHAR *value;
4370
4371 offset = ntohs(pRaCfg->status);
4372 memcpy(&len, pRaCfg->data, 2);
4373 len = ntohs(len);
4374
4375 for (j = offset; j < (offset+len); j++)
4376 {
4377 value = pRaCfg->data + 2 + (j - offset);
4378 RT30xxWriteRFRegister(pAdapter, j, *value);
4379 }
4380
4381 // prepare feedback
4382 pRaCfg->length = htons(2);
4383 pRaCfg->status = htons(0);
4384 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4385 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4386 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4387
4388 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4389 {
4390 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_WRITE_BULK\n"));
4391 Status = -EFAULT;
4392 }
4393 else
4394 {
4395 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_WRITE_BULK is done !\n"));
4396 }
4397
4398 }
4399 break;
4400#endif
4401
4402
4403 case RACFG_CMD_GET_NOISE_LEVEL:
4404 {
4405 UCHAR channel;
4406 INT32 buffer[3][10];/* 3 : RxPath ; 10 : no. of per rssi samples */
4407
4408 channel = (ntohs(pRaCfg->status) & 0x00FF);
4409 CalNoiseLevel(pAdapter, channel, buffer);
4410 memcpy_exl(pAdapter, (UCHAR *)pRaCfg->data, (UCHAR *)&(buffer[0][0]), (sizeof(INT32)*3*10));
4411
4412 // prepare feedback
4413 pRaCfg->length = htons(2 + (sizeof(INT32)*3*10));
4414 pRaCfg->status = htons(0);
4415 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4416 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4417 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4418
4419 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4420 {
4421 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_NOISE_LEVEL\n"));
4422 Status = -EFAULT;
4423 }
4424 else
4425 {
4426 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_NOISE_LEVEL is done !\n"));
4427 }
4428 }
4429 break;
4430
4431 case RACFG_CMD_GET_COUNTER:
4432 {
4433 memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.U2M, 4);
4434 memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->ate.OtherData, 4);
4435 memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->ate.Beacon, 4);
4436 memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->ate.OtherCount, 4);
4437 memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->ate.TxAc0, 4);
4438 memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->ate.TxAc1, 4);
4439 memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->ate.TxAc2, 4);
4440 memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->ate.TxAc3, 4);
4441 memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->ate.TxHCCA, 4);
4442 memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->ate.TxMgmt, 4);
4443 memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&pAdapter->ate.RSSI0, 4);
4444 memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&pAdapter->ate.RSSI1, 4);
4445 memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&pAdapter->ate.RSSI2, 4);
4446 memcpy_exl(pAdapter, &pRaCfg->data[52], (UCHAR *)&pAdapter->ate.SNR0, 4);
4447 memcpy_exl(pAdapter, &pRaCfg->data[56], (UCHAR *)&pAdapter->ate.SNR1, 4);
4448
4449 pRaCfg->length = htons(2+60);
4450 pRaCfg->status = htons(0);
4451 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4452 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4453 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4454
4455 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4456 {
4457 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_COUNTER\n"));
4458 Status = -EFAULT;
4459 }
4460 else
4461 {
4462 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_COUNTER is done !\n"));
4463 }
4464 }
4465 break;
4466
4467 case RACFG_CMD_CLEAR_COUNTER:
4468 {
4469 pAdapter->ate.U2M = 0;
4470 pAdapter->ate.OtherData = 0;
4471 pAdapter->ate.Beacon = 0;
4472 pAdapter->ate.OtherCount = 0;
4473 pAdapter->ate.TxAc0 = 0;
4474 pAdapter->ate.TxAc1 = 0;
4475 pAdapter->ate.TxAc2 = 0;
4476 pAdapter->ate.TxAc3 = 0;
4477 pAdapter->ate.TxHCCA = 0;
4478 pAdapter->ate.TxMgmt = 0;
4479 pAdapter->ate.TxDoneCount = 0;
4480
4481 pRaCfg->length = htons(2);
4482 pRaCfg->status = htons(0);
4483
4484 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4485 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4486 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4487
4488 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4489 {
4490 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_CLEAR_COUNTER\n"));
4491 Status = -EFAULT;
4492 }
4493 else
4494 {
4495 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_CLEAR_COUNTER is done !\n"));
4496 }
4497 }
4498
4499 break;
4500
4501 case RACFG_CMD_TX_START:
4502 {
4503 USHORT *p;
4504 USHORT err = 1;
4505 UCHAR Bbp22Value = 0, Bbp24Value = 0;
4506
4507 if ((pAdapter->ate.TxStatus != 0) && (pAdapter->ate.Mode & ATE_TXFRAME))
4508 {
4509 ATEDBGPRINT(RT_DEBUG_TRACE,("Ate Tx is already running, to run next Tx, you must stop it first\n"));
4510 err = 2;
4511 goto TX_START_ERROR;
4512 }
4513 else if ((pAdapter->ate.TxStatus != 0) && !(pAdapter->ate.Mode & ATE_TXFRAME))
4514 {
4515 int i = 0;
4516
4517 while ((i++ < 10) && (pAdapter->ate.TxStatus != 0))
4518 {
4519 RTMPusecDelay(5000);
4520 }
4521
4522 // force it to stop
4523 pAdapter->ate.TxStatus = 0;
4524 pAdapter->ate.TxDoneCount = 0;
4525 //pAdapter->ate.Repeat = 0;
4526 pAdapter->ate.bQATxStart = FALSE;
4527 }
4528
4529 // If pRaCfg->length == 0, this "RACFG_CMD_TX_START" is for Carrier test or Carrier Suppression.
4530 if (ntohs(pRaCfg->length) != 0)
4531 {
4532 // Get frame info
4533
4534 NdisMoveMemory(&pAdapter->ate.TxWI, pRaCfg->data + 2, 16);
4535#ifdef RT_BIG_ENDIAN
4536 RTMPWIEndianChange((PUCHAR)&pAdapter->ate.TxWI, TYPE_TXWI);
4537#endif // RT_BIG_ENDIAN //
4538
4539 NdisMoveMemory(&pAdapter->ate.TxCount, pRaCfg->data + 18, 4);
4540 pAdapter->ate.TxCount = ntohl(pAdapter->ate.TxCount);
4541
4542 p = (USHORT *)(&pRaCfg->data[22]);
4543 //p = pRaCfg->data + 22;
4544 // always use QID_AC_BE
4545 pAdapter->ate.QID = 0;
4546 p = (USHORT *)(&pRaCfg->data[24]);
4547 //p = pRaCfg->data + 24;
4548 pAdapter->ate.HLen = ntohs(*p);
4549
4550 if (pAdapter->ate.HLen > 32)
4551 {
4552 ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.HLen > 32\n"));
4553 err = 3;
4554 goto TX_START_ERROR;
4555 }
4556
4557 NdisMoveMemory(&pAdapter->ate.Header, pRaCfg->data + 26, pAdapter->ate.HLen);
4558
4559
4560 pAdapter->ate.PLen = ntohs(pRaCfg->length) - (pAdapter->ate.HLen + 28);
4561
4562 if (pAdapter->ate.PLen > 32)
4563 {
4564 ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.PLen > 32\n"));
4565 err = 4;
4566 goto TX_START_ERROR;
4567 }
4568
4569 NdisMoveMemory(&pAdapter->ate.Pattern, pRaCfg->data + 26 + pAdapter->ate.HLen, pAdapter->ate.PLen);
4570 pAdapter->ate.DLen = pAdapter->ate.TxWI.MPDUtotalByteCount - pAdapter->ate.HLen;
4571 }
4572
4573 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R22, &Bbp22Value);
4574
4575 switch (Bbp22Value)
4576 {
4577 case BBP22_TXFRAME:
4578 {
4579 if (pAdapter->ate.TxCount == 0)
4580 {
4581#ifdef RT2860
4582 pAdapter->ate.TxCount = 0xFFFFFFFF;
4583#endif // RT2860 //
4584 }
4585 ATEDBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n"));
4586 pAdapter->ate.bQATxStart = TRUE;
4587 Set_ATE_Proc(pAdapter, "TXFRAME");
4588 }
4589 break;
4590
4591 case BBP22_TXCONT_OR_CARRSUPP:
4592 {
4593 ATEDBGPRINT(RT_DEBUG_TRACE,("BBP22_TXCONT_OR_CARRSUPP\n"));
4594 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, 24, &Bbp24Value);
4595
4596 switch (Bbp24Value)
4597 {
4598 case BBP24_TXCONT:
4599 {
4600 ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCONT\n"));
4601 pAdapter->ate.bQATxStart = TRUE;
4602 Set_ATE_Proc(pAdapter, "TXCONT");
4603 }
4604 break;
4605
4606 case BBP24_CARRSUPP:
4607 {
4608 ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARRSUPP\n"));
4609 pAdapter->ate.bQATxStart = TRUE;
4610 pAdapter->ate.Mode |= ATE_TXCARRSUPP;
4611 }
4612 break;
4613
4614 default:
4615 {
4616 ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
4617 }
4618 break;
4619 }
4620 }
4621 break;
4622
4623 case BBP22_TXCARR:
4624 {
4625 ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARR\n"));
4626 pAdapter->ate.bQATxStart = TRUE;
4627 Set_ATE_Proc(pAdapter, "TXCARR");
4628 }
4629 break;
4630
4631 default:
4632 {
4633 ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
4634 }
4635 break;
4636 }
4637
4638 if (pAdapter->ate.bQATxStart == TRUE)
4639 {
4640 // prepare feedback
4641 pRaCfg->length = htons(2);
4642 pRaCfg->status = htons(0);
4643
4644 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4645 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4646 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4647
4648 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4649 {
4650 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() was failed in case RACFG_CMD_TX_START\n"));
4651 Status = -EFAULT;
4652 }
4653 else
4654 {
4655 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_START is done !\n"));
4656 }
4657 break;
4658 }
4659
4660TX_START_ERROR:
4661 // prepare feedback
4662 pRaCfg->length = htons(2);
4663 pRaCfg->status = htons(err);
4664
4665 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4666 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4667 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4668 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4669 {
4670 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_TX_START\n"));
4671 Status = -EFAULT;
4672 }
4673 else
4674 {
4675 ATEDBGPRINT(RT_DEBUG_TRACE, ("feedback of TX_START_ERROR is done !\n"));
4676 }
4677 }
4678 break;
4679
4680 case RACFG_CMD_GET_TX_STATUS:
4681 {
4682 UINT32 count;
4683
4684 // prepare feedback
4685 pRaCfg->length = htons(6);
4686 pRaCfg->status = htons(0);
4687 count = htonl(pAdapter->ate.TxDoneCount);
4688 NdisMoveMemory(pRaCfg->data, &count, 4);
4689 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4690 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4691 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4692
4693 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4694 {
4695 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_TX_STATUS\n"));
4696 Status = -EFAULT;
4697 }
4698 else
4699 {
4700 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_TX_STATUS is done !\n"));
4701 }
4702 }
4703 break;
4704
4705 case RACFG_CMD_TX_STOP:
4706 {
4707 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_TX_STOP\n"));
4708
4709 Set_ATE_Proc(pAdapter, "TXSTOP");
4710
4711 // prepare feedback
4712 pRaCfg->length = htons(2);
4713 pRaCfg->status = htons(0);
4714 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4715 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4716 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4717
4718 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4719 {
4720 ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_TX_STOP\n"));
4721 Status = -EFAULT;
4722 }
4723 else
4724 {
4725 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_STOP is done !\n"));
4726 }
4727 }
4728 break;
4729
4730 case RACFG_CMD_RX_START:
4731 {
4732 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
4733
4734 pAdapter->ate.bQARxStart = TRUE;
4735 Set_ATE_Proc(pAdapter, "RXFRAME");
4736
4737 // prepare feedback
4738 pRaCfg->length = htons(2);
4739 pRaCfg->status = htons(0);
4740 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4741 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4742 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4743
4744 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4745 {
4746 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
4747 Status = -EFAULT;
4748 }
4749 else
4750 {
4751 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
4752 }
4753 }
4754 break;
4755
4756 case RACFG_CMD_RX_STOP:
4757 {
4758 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_STOP\n"));
4759
4760 Set_ATE_Proc(pAdapter, "RXSTOP");
4761
4762 // prepare feedback
4763 pRaCfg->length = htons(2);
4764 pRaCfg->status = htons(0);
4765 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4766 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4767 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4768
4769 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4770 {
4771 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_STOP\n"));
4772 Status = -EFAULT;
4773 }
4774 else
4775 {
4776 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_STOP is done !\n"));
4777 }
4778 }
4779 break;
4780
4781 /* The following cases are for new ATE GUI(not QA). */
4782 /*==================================================*/
4783 case RACFG_CMD_ATE_START_TX_CARRIER:
4784 {
4785 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CARRIER\n"));
4786
4787 Set_ATE_Proc(pAdapter, "TXCARR");
4788
4789 pRaCfg->length = htons(2);
4790 pRaCfg->status = htons(0);
4791
4792 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4793 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4794 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4795
4796 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
4797
4798 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4799 {
4800 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CARRIER\n"));
4801 Status = -EFAULT;
4802 }
4803 else
4804 {
4805 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CARRIER is done !\n"));
4806 }
4807 }
4808 break;
4809
4810 case RACFG_CMD_ATE_START_TX_CONT:
4811 {
4812 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CONT\n"));
4813
4814 Set_ATE_Proc(pAdapter, "TXCONT");
4815
4816 pRaCfg->length = htons(2);
4817 pRaCfg->status = htons(0);
4818
4819 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4820 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4821 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4822
4823 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.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_START_TX_CONT\n"));
4828 Status = -EFAULT;
4829 }
4830 else
4831 {
4832 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CONT is done !\n"));
4833 }
4834 }
4835 break;
4836
4837 case RACFG_CMD_ATE_START_TX_FRAME:
4838 {
4839 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_FRAME\n"));
4840
4841 Set_ATE_Proc(pAdapter, "TXFRAME");
4842
4843 pRaCfg->length = htons(2);
4844 pRaCfg->status = htons(0);
4845
4846 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4847 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4848 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4849
4850 ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
4851
4852 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4853 {
4854 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_FRAME\n"));
4855 Status = -EFAULT;
4856 }
4857 else
4858 {
4859 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_FRAME is done !\n"));
4860 }
4861 }
4862 break;
4863
4864 case RACFG_CMD_ATE_SET_BW:
4865 {
4866 SHORT value = 0;
4867 UCHAR str[LEN_OF_ARG];
4868
4869 NdisZeroMemory(str, LEN_OF_ARG);
4870
4871 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_BW\n"));
4872
4873 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
4874 value = ntohs(value);
4875 sprintf((PCHAR)str, "%d", value);
4876
4877 Set_ATE_TX_BW_Proc(pAdapter, str);
4878
4879 // prepare feedback
4880 pRaCfg->length = htons(2);
4881 pRaCfg->status = htons(0);
4882 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4883 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4884 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4885
4886 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4887 {
4888 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_BW\n"));
4889 Status = -EFAULT;
4890 }
4891 else
4892 {
4893 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_BW is done !\n"));
4894 }
4895 }
4896 break;
4897
4898 case RACFG_CMD_ATE_SET_TX_POWER0:
4899 {
4900 SHORT value = 0;
4901 UCHAR str[LEN_OF_ARG];
4902
4903 NdisZeroMemory(str, LEN_OF_ARG);
4904
4905 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER0\n"));
4906
4907 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
4908 value = ntohs(value);
4909 sprintf((PCHAR)str, "%d", value);
4910 Set_ATE_TX_POWER0_Proc(pAdapter, str);
4911
4912 // prepare feedback
4913 pRaCfg->length = htons(2);
4914 pRaCfg->status = htons(0);
4915 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4916 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4917 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4918
4919 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4920 {
4921 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER0\n"));
4922 Status = -EFAULT;
4923 }
4924 else
4925 {
4926 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER0 is done !\n"));
4927 }
4928 }
4929 break;
4930
4931 case RACFG_CMD_ATE_SET_TX_POWER1:
4932 {
4933 SHORT value = 0;
4934 UCHAR str[LEN_OF_ARG];
4935
4936 NdisZeroMemory(str, LEN_OF_ARG);
4937
4938 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER1\n"));
4939
4940 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
4941 value = ntohs(value);
4942 sprintf((PCHAR)str, "%d", value);
4943 Set_ATE_TX_POWER1_Proc(pAdapter, str);
4944
4945 // prepare feedback
4946 pRaCfg->length = htons(2);
4947 pRaCfg->status = htons(0);
4948 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4949 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4950 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4951
4952 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4953 {
4954 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER1\n"));
4955 Status = -EFAULT;
4956 }
4957 else
4958 {
4959 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER1 is done !\n"));
4960 }
4961 }
4962 break;
4963
4964 case RACFG_CMD_ATE_SET_FREQ_OFFSET:
4965 {
4966 SHORT value = 0;
4967 UCHAR str[LEN_OF_ARG];
4968
4969 NdisZeroMemory(str, LEN_OF_ARG);
4970
4971 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
4972
4973 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
4974 value = ntohs(value);
4975 sprintf((PCHAR)str, "%d", value);
4976 Set_ATE_TX_FREQOFFSET_Proc(pAdapter, str);
4977
4978 // prepare feedback
4979 pRaCfg->length = htons(2);
4980 pRaCfg->status = htons(0);
4981 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
4982 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
4983 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
4984
4985 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
4986 {
4987 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
4988 Status = -EFAULT;
4989 }
4990 else
4991 {
4992 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_FREQ_OFFSET is done !\n"));
4993 }
4994 }
4995 break;
4996
4997 case RACFG_CMD_ATE_GET_STATISTICS:
4998 {
4999 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_GET_STATISTICS\n"));
5000
5001 memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.TxDoneCount, 4);
5002 memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->WlanCounters.RetryCount.u.LowPart, 4);
5003 memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->WlanCounters.FailedCount.u.LowPart, 4);
5004 memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->WlanCounters.RTSSuccessCount.u.LowPart, 4);
5005 memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->WlanCounters.RTSFailureCount.u.LowPart, 4);
5006 memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart, 4);
5007 memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->WlanCounters.FCSErrorCount.u.LowPart, 4);
5008 memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->Counters8023.RxNoBuffer, 4);
5009 memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart, 4);
5010 memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->RalinkCounters.OneSecFalseCCACnt, 4);
5011
5012 if (pAdapter->ate.RxAntennaSel == 0)
5013 {
5014 INT32 RSSI0 = 0;
5015 INT32 RSSI1 = 0;
5016 INT32 RSSI2 = 0;
5017
5018 RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
5019 RSSI1 = (INT32)(pAdapter->ate.LastRssi1 - pAdapter->BbpRssiToDbmDelta);
5020 RSSI2 = (INT32)(pAdapter->ate.LastRssi2 - pAdapter->BbpRssiToDbmDelta);
5021 memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
5022 memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&RSSI1, 4);
5023 memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&RSSI2, 4);
5024 pRaCfg->length = htons(2+52);
5025 }
5026 else
5027 {
5028 INT32 RSSI0 = 0;
5029
5030 RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
5031 memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
5032 pRaCfg->length = htons(2+44);
5033 }
5034 pRaCfg->status = htons(0);
5035 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5036 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5037 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5038
5039 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5040 {
5041 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_GET_STATISTICS\n"));
5042 Status = -EFAULT;
5043 }
5044 else
5045 {
5046 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_GET_STATISTICS is done !\n"));
5047 }
5048 }
5049 break;
5050
5051 case RACFG_CMD_ATE_RESET_COUNTER:
5052 {
5053 SHORT value = 1;
5054 UCHAR str[LEN_OF_ARG];
5055
5056 NdisZeroMemory(str, LEN_OF_ARG);
5057
5058 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_RESET_COUNTER\n"));
5059
5060 sprintf((PCHAR)str, "%d", value);
5061 Set_ResetStatCounter_Proc(pAdapter, str);
5062
5063 pAdapter->ate.TxDoneCount = 0;
5064
5065 pRaCfg->length = htons(2);
5066 pRaCfg->status = htons(0);
5067
5068 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5069 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5070 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5071
5072 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5073 {
5074 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RESET_COUNTER\n"));
5075 Status = -EFAULT;
5076 }
5077 else
5078 {
5079 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RESET_COUNTER is done !\n"));
5080 }
5081 }
5082
5083 break;
5084
5085 case RACFG_CMD_ATE_SEL_TX_ANTENNA:
5086 {
5087 SHORT value = 0;
5088 UCHAR str[LEN_OF_ARG];
5089
5090 NdisZeroMemory(str, LEN_OF_ARG);
5091
5092 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
5093
5094 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5095 value = ntohs(value);
5096 sprintf((PCHAR)str, "%d", value);
5097 Set_ATE_TX_Antenna_Proc(pAdapter, str);
5098
5099 // prepare feedback
5100 pRaCfg->length = htons(2);
5101 pRaCfg->status = htons(0);
5102 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5103 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5104 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5105
5106 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5107 {
5108 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
5109 Status = -EFAULT;
5110 }
5111 else
5112 {
5113 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_TX_ANTENNA is done !\n"));
5114 }
5115 }
5116 break;
5117
5118 case RACFG_CMD_ATE_SEL_RX_ANTENNA:
5119 {
5120 SHORT value = 0;
5121 UCHAR str[LEN_OF_ARG];
5122
5123 NdisZeroMemory(str, LEN_OF_ARG);
5124
5125 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
5126
5127 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5128 value = ntohs(value);
5129 sprintf((PCHAR)str, "%d", value);
5130 Set_ATE_RX_Antenna_Proc(pAdapter, str);
5131
5132 // prepare feedback
5133 pRaCfg->length = htons(2);
5134 pRaCfg->status = htons(0);
5135 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5136 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5137 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5138
5139 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5140 {
5141 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
5142 Status = -EFAULT;
5143 }
5144 else
5145 {
5146 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_RX_ANTENNA is done !\n"));
5147 }
5148 }
5149 break;
5150
5151 case RACFG_CMD_ATE_SET_PREAMBLE:
5152 {
5153 SHORT value = 0;
5154 UCHAR str[LEN_OF_ARG];
5155
5156 NdisZeroMemory(str, LEN_OF_ARG);
5157
5158 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_PREAMBLE\n"));
5159
5160 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5161 value = ntohs(value);
5162 sprintf((PCHAR)str, "%d", value);
5163 Set_ATE_TX_MODE_Proc(pAdapter, str);
5164
5165 // prepare feedback
5166 pRaCfg->length = htons(2);
5167 pRaCfg->status = htons(0);
5168 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5169 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5170 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5171
5172 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5173 {
5174 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_PREAMBLE\n"));
5175 Status = -EFAULT;
5176 }
5177 else
5178 {
5179 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_PREAMBLE is done !\n"));
5180 }
5181 }
5182 break;
5183
5184 case RACFG_CMD_ATE_SET_CHANNEL:
5185 {
5186 SHORT value = 0;
5187 UCHAR str[LEN_OF_ARG];
5188
5189 NdisZeroMemory(str, LEN_OF_ARG);
5190
5191 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_CHANNEL\n"));
5192
5193 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5194 value = ntohs(value);
5195 sprintf((PCHAR)str, "%d", value);
5196 Set_ATE_CHANNEL_Proc(pAdapter, str);
5197
5198 // prepare feedback
5199 pRaCfg->length = htons(2);
5200 pRaCfg->status = htons(0);
5201 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5202 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5203 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5204
5205 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5206 {
5207 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_CHANNEL\n"));
5208 Status = -EFAULT;
5209 }
5210 else
5211 {
5212 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_CHANNEL is done !\n"));
5213 }
5214 }
5215 break;
5216
5217 case RACFG_CMD_ATE_SET_ADDR1:
5218 {
5219 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR1\n"));
5220
5221 // Addr is an array of UCHAR,
5222 // so no need to perform endian swap.
5223 memcpy(pAdapter->ate.Addr1, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
5224
5225 // prepare feedback
5226 pRaCfg->length = htons(2);
5227 pRaCfg->status = htons(0);
5228 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5229 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5230 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5231
5232 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5233 {
5234 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR1\n"));
5235 Status = -EFAULT;
5236 }
5237 else
5238 {
5239 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR1 is done !\n (ADDR1 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr1[0],
5240 pAdapter->ate.Addr1[1], pAdapter->ate.Addr1[2], pAdapter->ate.Addr1[3], pAdapter->ate.Addr1[4], pAdapter->ate.Addr1[5]));
5241 }
5242 }
5243 break;
5244
5245 case RACFG_CMD_ATE_SET_ADDR2:
5246 {
5247 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR2\n"));
5248
5249 // Addr is an array of UCHAR,
5250 // so no need to perform endian swap.
5251 memcpy(pAdapter->ate.Addr2, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
5252
5253 // prepare feedback
5254 pRaCfg->length = htons(2);
5255 pRaCfg->status = htons(0);
5256 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5257 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5258 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5259
5260 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5261 {
5262 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR2\n"));
5263 Status = -EFAULT;
5264 }
5265 else
5266 {
5267 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR2 is done !\n (ADDR2 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr2[0],
5268 pAdapter->ate.Addr2[1], pAdapter->ate.Addr2[2], pAdapter->ate.Addr2[3], pAdapter->ate.Addr2[4], pAdapter->ate.Addr2[5]));
5269 }
5270 }
5271 break;
5272
5273 case RACFG_CMD_ATE_SET_ADDR3:
5274 {
5275 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR3\n"));
5276
5277 // Addr is an array of UCHAR,
5278 // so no need to perform endian swap.
5279 memcpy(pAdapter->ate.Addr3, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
5280
5281 // prepare feedback
5282 pRaCfg->length = htons(2);
5283 pRaCfg->status = htons(0);
5284 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5285 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5286 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5287
5288 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5289 {
5290 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR3\n"));
5291 Status = -EFAULT;
5292 }
5293 else
5294 {
5295 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR3 is done !\n (ADDR3 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr3[0],
5296 pAdapter->ate.Addr3[1], pAdapter->ate.Addr3[2], pAdapter->ate.Addr3[3], pAdapter->ate.Addr3[4], pAdapter->ate.Addr3[5]));
5297 }
5298 }
5299 break;
5300
5301 case RACFG_CMD_ATE_SET_RATE:
5302 {
5303 SHORT value = 0;
5304 UCHAR str[LEN_OF_ARG];
5305
5306 NdisZeroMemory(str, LEN_OF_ARG);
5307
5308 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_RATE\n"));
5309
5310 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5311 value = ntohs(value);
5312 sprintf((PCHAR)str, "%d", value);
5313 Set_ATE_TX_MCS_Proc(pAdapter, str);
5314
5315 // prepare feedback
5316 pRaCfg->length = htons(2);
5317 pRaCfg->status = htons(0);
5318 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5319 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5320 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5321
5322 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5323 {
5324 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_RATE\n"));
5325 Status = -EFAULT;
5326 }
5327 else
5328 {
5329 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_RATE is done !\n"));
5330 }
5331 }
5332 break;
5333
5334 case RACFG_CMD_ATE_SET_TX_FRAME_LEN:
5335 {
5336 SHORT value = 0;
5337 UCHAR str[LEN_OF_ARG];
5338
5339 NdisZeroMemory(str, LEN_OF_ARG);
5340
5341 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
5342
5343 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5344 value = ntohs(value);
5345 sprintf((PCHAR)str, "%d", value);
5346 Set_ATE_TX_LENGTH_Proc(pAdapter, str);
5347
5348 // prepare feedback
5349 pRaCfg->length = htons(2);
5350 pRaCfg->status = htons(0);
5351 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5352 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5353 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5354
5355 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5356 {
5357 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
5358 Status = -EFAULT;
5359 }
5360 else
5361 {
5362 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_LEN is done !\n"));
5363 }
5364 }
5365 break;
5366
5367 case RACFG_CMD_ATE_SET_TX_FRAME_COUNT:
5368 {
5369 USHORT value = 0;
5370 UCHAR str[LEN_OF_ARG];
5371
5372 NdisZeroMemory(str, LEN_OF_ARG);
5373
5374 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
5375
5376 memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
5377 value = ntohs(value);
5378#ifdef RT2860
5379 /* TX_FRAME_COUNT == 0 means tx infinitely */
5380 if (value == 0)
5381 {
5382 /* Use TxCount = 0xFFFFFFFF to approximate the infinity. */
5383 pAdapter->ate.TxCount = 0xFFFFFFFF;
5384 ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pAdapter->ate.TxCount));
5385 ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n"));
5386
5387
5388 }
5389 else
5390#endif // RT2860 //
5391 {
5392 sprintf((PCHAR)str, "%d", value);
5393 Set_ATE_TX_COUNT_Proc(pAdapter, str);
5394 }
5395
5396 // prepare feedback
5397 pRaCfg->length = htons(2);
5398 pRaCfg->status = htons(0);
5399 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5400 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5401 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5402
5403 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5404 {
5405 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
5406 Status = -EFAULT;
5407 }
5408 else
5409 {
5410 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_COUNT is done !\n"));
5411 }
5412 }
5413 break;
5414
5415 case RACFG_CMD_ATE_START_RX_FRAME:
5416 {
5417 ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
5418
5419 Set_ATE_Proc(pAdapter, "RXFRAME");
5420
5421 // prepare feedback
5422 pRaCfg->length = htons(2);
5423 pRaCfg->status = htons(0);
5424 wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
5425 + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
5426 + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
5427
5428 if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
5429 {
5430 ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
5431 Status = -EFAULT;
5432 }
5433 else
5434 {
5435 ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
5436 }
5437 }
5438 break;
5439 default:
5440 break;
5441 }
5442 ASSERT(pRaCfg != NULL);
5443 if (pRaCfg != NULL)
5444 {
5445 kfree(pRaCfg);
5446 }
5447 return;
5448}
5449
5450VOID BubbleSort(INT32 n, INT32 a[])
5451{
5452 INT32 k, j, temp;
5453
5454 for (k = n-1; k>0; k--)
5455 {
5456 for (j = 0; j<k; j++)
5457 {
5458 if(a[j] > a[j+1])
5459 {
5460 temp = a[j];
5461 a[j]=a[j+1];
5462 a[j+1]=temp;
5463 }
5464 }
5465 }
5466}
5467
5468VOID CalNoiseLevel(PRTMP_ADAPTER pAd, UCHAR channel, INT32 RSSI[3][10])
5469{
5470 INT32 RSSI0, RSSI1, RSSI2;
5471 CHAR Rssi0Offset, Rssi1Offset, Rssi2Offset;
5472 UCHAR BbpR50Rssi0 = 0, BbpR51Rssi1 = 0, BbpR52Rssi2 = 0;
5473 UCHAR Org_BBP66value = 0, Org_BBP69value = 0, Org_BBP70value = 0, data = 0;
5474 USHORT LNA_Gain = 0;
5475 INT32 j = 0;
5476 UCHAR Org_Channel = pAd->ate.Channel;
5477 USHORT GainValue = 0, OffsetValue = 0;
5478
5479 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &Org_BBP66value);
5480 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R69, &Org_BBP69value);
5481 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R70, &Org_BBP70value);
5482
5483 //**********************************************************************
5484 // Read the value of LNA gain and Rssi offset
5485 //**********************************************************************
5486 RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, GainValue);
5487
5488 // for Noise Level
5489 if (channel <= 14)
5490 {
5491 LNA_Gain = GainValue & 0x00FF;
5492
5493 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, OffsetValue);
5494 Rssi0Offset = OffsetValue & 0x00FF;
5495 Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
5496 RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_BG_OFFSET + 2)/* 0x48 */, OffsetValue);
5497 Rssi2Offset = OffsetValue & 0x00FF;
5498 }
5499 else
5500 {
5501 LNA_Gain = (GainValue & 0xFF00) >> 8;
5502
5503 RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, OffsetValue);
5504 Rssi0Offset = OffsetValue & 0x00FF;
5505 Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
5506 RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2)/* 0x4C */, OffsetValue);
5507 Rssi2Offset = OffsetValue & 0x00FF;
5508 }
5509 //**********************************************************************
5510 {
5511 pAd->ate.Channel = channel;
5512 ATEAsicSwitchChannel(pAd);
5513 mdelay(5);
5514
5515 data = 0x10;
5516 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, data);
5517 data = 0x40;
5518 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, data);
5519 data = 0x40;
5520 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, data);
5521 mdelay(5);
5522
5523 // Start Rx
5524 pAd->ate.bQARxStart = TRUE;
5525 Set_ATE_Proc(pAd, "RXFRAME");
5526
5527 mdelay(5);
5528
5529 for (j = 0; j < 10; j++)
5530 {
5531 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R50, &BbpR50Rssi0);
5532 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R51, &BbpR51Rssi1);
5533 ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R52, &BbpR52Rssi2);
5534
5535 mdelay(10);
5536
5537 // Calculate RSSI 0
5538 if (BbpR50Rssi0 == 0)
5539 {
5540 RSSI0 = -100;
5541 }
5542 else
5543 {
5544 RSSI0 = (INT32)(-12 - BbpR50Rssi0 - LNA_Gain - Rssi0Offset);
5545 }
5546 RSSI[0][j] = RSSI0;
5547
5548 if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
5549 {
5550 // Calculate RSSI 1
5551 if (BbpR51Rssi1 == 0)
5552 {
5553 RSSI1 = -100;
5554 }
5555 else
5556 {
5557 RSSI1 = (INT32)(-12 - BbpR51Rssi1 - LNA_Gain - Rssi1Offset);
5558 }
5559 RSSI[1][j] = RSSI1;
5560 }
5561
5562 if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
5563 {
5564 // Calculate RSSI 2
5565 if (BbpR52Rssi2 == 0)
5566 RSSI2 = -100;
5567 else
5568 RSSI2 = (INT32)(-12 - BbpR52Rssi2 - LNA_Gain - Rssi2Offset);
5569
5570 RSSI[2][j] = RSSI2;
5571 }
5572 }
5573
5574 // Stop Rx
5575 Set_ATE_Proc(pAd, "RXSTOP");
5576
5577 mdelay(5);
5578
5579#if 0// Debug Message................
5580 ate_print("\n**********************************************************\n");
5581 ate_print("Noise Level: Channel %d\n", channel);
5582 ate_print("RSSI0 = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
5583 RSSI[0][0], RSSI[0][1], RSSI[0][2],
5584 RSSI[0][3], RSSI[0][4], RSSI[0][5],
5585 RSSI[0][6], RSSI[0][7], RSSI[0][8],
5586 RSSI[0][9]);
5587 if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
5588 {
5589 ate_print("RSSI1 = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
5590 RSSI[1][0], RSSI[1][1], RSSI[1][2],
5591 RSSI[1][3], RSSI[1][4], RSSI[1][5],
5592 RSSI[1][6], RSSI[1][7], RSSI[1][8],
5593 RSSI[1][9]);
5594 }
5595 if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
5596 {
5597 ate_print("RSSI2 = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
5598 RSSI[2][0], RSSI[2][1], RSSI[2][2],
5599 RSSI[2][3], RSSI[2][4], RSSI[2][5],
5600 RSSI[2][6], RSSI[2][7], RSSI[2][8],
5601 RSSI[2][9]);
5602 }
5603#endif // 0 //
5604 BubbleSort(10, RSSI[0]); // 1R
5605
5606 if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
5607 {
5608 BubbleSort(10, RSSI[1]);
5609 }
5610
5611 if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
5612 {
5613 BubbleSort(10, RSSI[2]);
5614 }
5615
5616#if 0// Debug Message................
5617 ate_print("\nAfter Sorting....Channel %d\n", channel);
5618 ate_print("RSSI0 = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
5619 RSSI[0][0], RSSI[0][1], RSSI[0][2],
5620 RSSI[0][3], RSSI[0][4], RSSI[0][5],
5621 RSSI[0][6], RSSI[0][7], RSSI[0][8],
5622 RSSI[0][9]);
5623 if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
5624 {
5625 ate_print("RSSI1 = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
5626 RSSI[1][0], RSSI[1][1], RSSI[1][2],
5627 RSSI[1][3], RSSI[1][4], RSSI[1][5],
5628 RSSI[1][6], RSSI[1][7], RSSI[1][8],
5629 RSSI[1][9]);
5630 }
5631 if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
5632 {
5633 ate_print("RSSI2 = %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
5634 RSSI[2][0], RSSI[2][1], RSSI[2][2],
5635 RSSI[2][3], RSSI[2][4], RSSI[2][5],
5636 RSSI[2][6], RSSI[2][7], RSSI[2][8],
5637 RSSI[2][9]);
5638 }
5639 ate_print("**********************************************************\n");
5640#endif // 0 //
5641 }
5642
5643 pAd->ate.Channel = Org_Channel;
5644 ATEAsicSwitchChannel(pAd);
5645
5646 // Restore original value
5647 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, Org_BBP66value);
5648 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, Org_BBP69value);
5649 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, Org_BBP70value);
5650
5651 return;
5652}
5653
5654BOOLEAN SyncTxRxConfig(PRTMP_ADAPTER pAd, USHORT offset, UCHAR value)
5655{
5656 UCHAR tmp = 0, bbp_data = 0;
5657
5658 if (ATE_ON(pAd))
5659 {
5660 ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
5661 }
5662 else
5663 {
5664 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
5665 }
5666
5667 /* confirm again */
5668 ASSERT(bbp_data == value);
5669
5670 switch(offset)
5671 {
5672 case BBP_R1:
5673 /* Need to sync. tx configuration with legacy ATE. */
5674 tmp = (bbp_data & ((1 << 4) | (1 << 3))/* 0x18 */) >> 3;
5675 switch(tmp)
5676 {
5677 /* The BBP R1 bit[4:3] = 2 :: Both DACs will be used by QA. */
5678 case 2:
5679 /* All */
5680 pAd->ate.TxAntennaSel = 0;
5681 break;
5682 /* The BBP R1 bit[4:3] = 0 :: DAC 0 will be used by QA. */
5683 case 0:
5684 /* Antenna one */
5685 pAd->ate.TxAntennaSel = 1;
5686 break;
5687 /* The BBP R1 bit[4:3] = 1 :: DAC 1 will be used by QA. */
5688 case 1:
5689 /* Antenna two */
5690 pAd->ate.TxAntennaSel = 2;
5691 break;
5692 default:
5693 DBGPRINT(RT_DEBUG_TRACE, ("%s -- Sth. wrong! : return FALSE; \n", __FUNCTION__));
5694 return FALSE;
5695 }
5696 break;/* case BBP_R1 */
5697
5698 case BBP_R3:
5699 /* Need to sync. rx configuration with legacy ATE. */
5700 tmp = (bbp_data & ((1 << 1) | (1 << 0))/* 0x03 */);
5701 switch(tmp)
5702 {
5703 /* The BBP R3 bit[1:0] = 3 :: All ADCs will be used by QA. */
5704 case 3:
5705 /* All */
5706 pAd->ate.RxAntennaSel = 0;
5707 break;
5708 /* The BBP R3 bit[1:0] = 0 :: ADC 0 will be used by QA, */
5709 /* unless the BBP R3 bit[4:3] = 2 */
5710 case 0:
5711 /* Antenna one */
5712 pAd->ate.RxAntennaSel = 1;
5713 tmp = ((bbp_data & ((1 << 4) | (1 << 3))/* 0x03 */) >> 3);
5714 if (tmp == 2)// 3R
5715 {
5716 /* Default : All ADCs will be used by QA */
5717 pAd->ate.RxAntennaSel = 0;
5718 }
5719 break;
5720 /* The BBP R3 bit[1:0] = 1 :: ADC 1 will be used by QA. */
5721 case 1:
5722 /* Antenna two */
5723 pAd->ate.RxAntennaSel = 2;
5724 break;
5725 /* The BBP R3 bit[1:0] = 2 :: ADC 2 will be used by QA. */
5726 case 2:
5727 /* Antenna three */
5728 pAd->ate.RxAntennaSel = 3;
5729 break;
5730 default:
5731 DBGPRINT(RT_DEBUG_ERROR, ("%s -- Impossible! : return FALSE; \n", __FUNCTION__));
5732 return FALSE;
5733 }
5734 break;/* case BBP_R3 */
5735
5736 default:
5737 DBGPRINT(RT_DEBUG_ERROR, ("%s -- Sth. wrong! : return FALSE; \n", __FUNCTION__));
5738 return FALSE;
5739
5740 }
5741 return TRUE;
5742}
5743
5744static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
5745{
5746 ULONG i, Value = 0;
5747 ULONG *pDst, *pSrc;
5748 UCHAR *p8;
5749
5750 p8 = src;
5751 pDst = (ULONG *) dst;
5752 pSrc = (ULONG *) src;
5753
5754 for (i = 0 ; i < (len/4); i++)
5755 {
5756 /* For alignment issue, we need a variable "Value". */
5757 memmove(&Value, pSrc, 4);
5758 Value = htonl(Value);
5759 memmove(pDst, &Value, 4);
5760 pDst++;
5761 pSrc++;
5762 }
5763 if ((len % 4) != 0)
5764 {
5765 /* wish that it will never reach here */
5766 memmove(&Value, pSrc, (len % 4));
5767 Value = htonl(Value);
5768 memmove(pDst, &Value, (len % 4));
5769 }
5770}
5771
5772static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
5773{
5774 ULONG i;
5775 UCHAR *pDst, *pSrc;
5776
5777 pDst = dst;
5778 pSrc = src;
5779
5780 for (i = 0; i < (len/2); i++)
5781 {
5782 memmove(pDst, pSrc, 2);
5783 *((USHORT *)pDst) = htons(*((USHORT *)pDst));
5784 pDst+=2;
5785 pSrc+=2;
5786 }
5787
5788 if ((len % 2) != 0)
5789 {
5790 memmove(pDst, pSrc, 1);
5791 }
5792}
5793
5794static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len)
5795{
5796 UINT32 i, Value;
5797 UINT32 *pDst, *pSrc;
5798
5799 pDst = (UINT32 *) dst;
5800 pSrc = (UINT32 *) src;
5801
5802 for (i = 0 ; i < (len/4); i++)
5803 {
5804 RTMP_IO_READ32(pAd, (ULONG)pSrc, &Value);
5805 Value = htonl(Value);
5806 memmove(pDst, &Value, 4);
5807 pDst++;
5808 pSrc++;
5809 }
5810 return;
5811}
5812
5813// TODO:
5814#if 0
5815/* These work only when RALINK_ATE is defined */
5816INT Set_TxStart_Proc(
5817 IN PRTMP_ADAPTER pAd,
5818 IN PUCHAR arg)
5819{
5820 ULONG value = simple_strtol(arg, 0, 10);
5821 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};
5822 POS_COOKIE pObj;
5823
5824 if (pAd->ate.TxStatus != 0)
5825 return FALSE;
5826
5827 pAd->ate.TxInfo = 0x04000000;
5828 bzero(&pAd->ate.TxWI, sizeof(TXWI_STRUC));
5829 pAd->ate.TxWI.PHYMODE = 0;// MODE_CCK
5830 pAd->ate.TxWI.MPDUtotalByteCount = 1226;
5831 pAd->ate.TxWI.MCS = 3;
5832 //pAd->ate.Mode = ATE_START;
5833 pAd->ate.Mode |= ATE_TXFRAME;
5834 pAd->ate.TxCount = value;
5835 pAd->ate.QID = 0;
5836 pAd->ate.HLen = 26;
5837 pAd->ate.PLen = 0;
5838 pAd->ate.DLen = 1200;
5839 memcpy(pAd->ate.Header, buffer, 26);
5840 pAd->ate.bQATxStart = TRUE;
5841 //pObj = (POS_COOKIE) pAd->OS_Cookie;
5842 //tasklet_hi_schedule(&pObj->AteTxTask);
5843 return TRUE;
5844}
5845#endif /* end of #if 0 */
5846
5847INT Set_TxStop_Proc(
5848 IN PRTMP_ADAPTER pAd,
5849 IN PUCHAR arg)
5850{
5851 ATEDBGPRINT(RT_DEBUG_TRACE,("Set_TxStop_Proc\n"));
5852
5853 if (Set_ATE_Proc(pAd, "TXSTOP"))
5854 {
5855 return TRUE;
5856}
5857 else
5858 {
5859 return FALSE;
5860 }
5861}
5862
5863INT Set_RxStop_Proc(
5864 IN PRTMP_ADAPTER pAd,
5865 IN PUCHAR arg)
5866{
5867 ATEDBGPRINT(RT_DEBUG_TRACE,("Set_RxStop_Proc\n"));
5868
5869 if (Set_ATE_Proc(pAd, "RXSTOP"))
5870 {
5871 return TRUE;
5872}
5873 else
5874 {
5875 return FALSE;
5876 }
5877}
5878
5879#if 0
5880INT Set_EEWrite_Proc(
5881 IN PRTMP_ADAPTER pAd,
5882 IN PUCHAR arg)
5883{
5884 USHORT offset = 0, value;
5885 PUCHAR p2 = arg;
5886
5887 while((*p2 != ':') && (*p2 != '\0'))
5888 {
5889 p2++;
5890 }
5891
5892 if (*p2 == ':')
5893 {
5894 A2Hex(offset, arg);
5895 A2Hex(value, p2+ 1);
5896 }
5897 else
5898 {
5899 A2Hex(value, arg);
5900 }
5901
5902 if (offset >= EEPROM_SIZE)
5903 {
5904 ate_print("Offset can not exceed EEPROM_SIZE( == 0x%04x)\n", EEPROM_SIZE);
5905 return FALSE;
5906 }
5907
5908 RTMP_EEPROM_WRITE16(pAd, offset, value);
5909
5910 return TRUE;
5911}
5912
5913INT Set_BBPRead_Proc(
5914 IN PRTMP_ADAPTER pAd,
5915 IN PUCHAR arg)
5916{
5917 UCHAR value = 0, offset;
5918
5919 A2Hex(offset, arg);
5920
5921 if (ATE_ON(pAd))
5922 {
5923 ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &value);
5924 }
5925 else
5926 {
5927 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, &value);
5928 }
5929
5930 ate_print("%x\n", value);
5931
5932 return TRUE;
5933}
5934
5935
5936INT Set_BBPWrite_Proc(
5937 IN PRTMP_ADAPTER pAd,
5938 IN PUCHAR arg)
5939{
5940 USHORT offset = 0;
5941 PUCHAR p2 = arg;
5942 UCHAR value;
5943
5944 while((*p2 != ':') && (*p2 != '\0'))
5945 {
5946 p2++;
5947 }
5948
5949 if (*p2 == ':')
5950 {
5951 A2Hex(offset, arg);
5952 A2Hex(value, p2+ 1);
5953 }
5954 else
5955 {
5956 A2Hex(value, arg);
5957 }
5958
5959 if (ATE_ON(pAd))
5960 {
5961 ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, offset, value);
5962 }
5963 else
5964 {
5965 RTNP_BBP_IO_WRITE8_BY_REG_ID(pAd, offset, value);
5966 }
5967
5968 return TRUE;
5969}
5970
5971INT Set_RFWrite_Proc(
5972 IN PRTMP_ADAPTER pAd,
5973 IN PUCHAR arg)
5974{
5975 PUCHAR p2, p3, p4;
5976 ULONG R1, R2, R3, R4;
5977
5978 p2 = arg;
5979
5980 while((*p2 != ':') && (*p2 != '\0'))
5981 {
5982 p2++;
5983 }
5984
5985 if (*p2 != ':')
5986 return FALSE;
5987
5988 p3 = p2 + 1;
5989
5990 while((*p3 != ':') && (*p3 != '\0'))
5991 {
5992 p3++;
5993 }
5994
5995 if (*p3 != ':')
5996 return FALSE;
5997
5998 p4 = p3 + 1;
5999
6000 while((*p4 != ':') && (*p4 != '\0'))
6001 {
6002 p4++;
6003 }
6004
6005 if (*p4 != ':')
6006 return FALSE;
6007
6008
6009 A2Hex(R1, arg);
6010 A2Hex(R2, p2 + 1);
6011 A2Hex(R3, p3 + 1);
6012 A2Hex(R4, p4 + 1);
6013
6014 RTMP_RF_IO_WRITE32(pAd, R1);
6015 RTMP_RF_IO_WRITE32(pAd, R2);
6016 RTMP_RF_IO_WRITE32(pAd, R3);
6017 RTMP_RF_IO_WRITE32(pAd, R4);
6018
6019 return TRUE;
6020}
6021#endif // end of #if 0 //
6022#endif // RALINK_28xx_QA //
6023
6024#endif // RALINK_ATE //
6025
diff --git a/drivers/staging/rt2860/rt_ate.h b/drivers/staging/rt2860/rt_ate.h
new file mode 100644
index 00000000000..48aa70d2f01
--- /dev/null
+++ b/drivers/staging/rt2860/rt_ate.h
@@ -0,0 +1,353 @@
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#ifdef RT2860
35#define EEPROM_SIZE 0x200
36#ifdef CONFIG_STA_SUPPORT
37#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2860STA/e2p.bin"
38#endif // CONFIG_STA_SUPPORT //
39#endif // RT2860 //
40
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#ifdef RT2860
73#define ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
74{ \
75 BBP_CSR_CFG_STRUC BbpCsr; \
76 int i, k; \
77 for (i=0; i<MAX_BUSY_COUNT; i++) \
78 { \
79 RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word); \
80 if (BbpCsr.field.Busy == BUSY) \
81 { \
82 continue; \
83 } \
84 BbpCsr.word = 0; \
85 BbpCsr.field.fRead = 1; \
86 BbpCsr.field.BBP_RW_MODE = 1; \
87 BbpCsr.field.Busy = 1; \
88 BbpCsr.field.RegNum = _I; \
89 RTMP_IO_WRITE32(_A, BBP_CSR_CFG, BbpCsr.word); \
90 for (k=0; k<MAX_BUSY_COUNT; k++) \
91 { \
92 RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word); \
93 if (BbpCsr.field.Busy == IDLE) \
94 break; \
95 } \
96 if ((BbpCsr.field.Busy == IDLE) && \
97 (BbpCsr.field.RegNum == _I)) \
98 { \
99 *(_pV) = (UCHAR)BbpCsr.field.Value; \
100 break; \
101 } \
102 } \
103 if (BbpCsr.field.Busy == BUSY) \
104 { \
105 ATEDBGPRINT(RT_DEBUG_ERROR, ("BBP read R%d fail\n", _I)); \
106 *(_pV) = (_A)->BbpWriteLatch[_I]; \
107 } \
108}
109
110#define ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \
111{ \
112 BBP_CSR_CFG_STRUC BbpCsr; \
113 int BusyCnt; \
114 for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++) \
115 { \
116 RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word); \
117 if (BbpCsr.field.Busy == BUSY) \
118 continue; \
119 BbpCsr.word = 0; \
120 BbpCsr.field.fRead = 0; \
121 BbpCsr.field.BBP_RW_MODE = 1; \
122 BbpCsr.field.Busy = 1; \
123 BbpCsr.field.Value = _V; \
124 BbpCsr.field.RegNum = _I; \
125 RTMP_IO_WRITE32(_A, BBP_CSR_CFG, BbpCsr.word); \
126 (_A)->BbpWriteLatch[_I] = _V; \
127 break; \
128 } \
129 if (BusyCnt == MAX_BUSY_COUNT) \
130 { \
131 ATEDBGPRINT(RT_DEBUG_ERROR, ("BBP write R%d fail\n", _I)); \
132 } \
133}
134#endif // RT2860 //
135
136/* RT2880_iNIC will define RT2860. */
137#ifdef RT2860
138#define EEPROM_SIZE 0x200
139/* iNIC has its own EEPROM_BIN_FILE_NAME */
140#ifndef UCOS
141#ifdef CONFIG_STA_SUPPORT
142#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2860STA/e2p.bin"
143#endif // CONFIG_STA_SUPPORT //
144#endif // !UCOS //
145#endif // RT2860 //
146
147
148
149VOID rt_ee_read_all(
150 IN PRTMP_ADAPTER pAd,
151 OUT USHORT *Data);
152
153
154VOID rt_ee_write_all(
155 IN PRTMP_ADAPTER pAd,
156 IN USHORT *Data);
157
158INT Set_ATE_Proc(
159 IN PRTMP_ADAPTER pAd,
160 IN PUCHAR arg);
161
162INT Set_ATE_DA_Proc(
163 IN PRTMP_ADAPTER pAd,
164 IN PUCHAR arg);
165
166INT Set_ATE_SA_Proc(
167 IN PRTMP_ADAPTER pAd,
168 IN PUCHAR arg);
169
170INT Set_ATE_BSSID_Proc(
171 IN PRTMP_ADAPTER pAd,
172 IN PUCHAR arg);
173
174INT Set_ATE_CHANNEL_Proc(
175 IN PRTMP_ADAPTER pAd,
176 IN PUCHAR arg);
177
178INT Set_ATE_TX_POWER0_Proc(
179 IN PRTMP_ADAPTER pAd,
180 IN PUCHAR arg);
181
182INT Set_ATE_TX_POWER1_Proc(
183 IN PRTMP_ADAPTER pAd,
184 IN PUCHAR arg);
185
186INT Set_ATE_TX_Antenna_Proc(
187 IN PRTMP_ADAPTER pAd,
188 IN PUCHAR arg);
189
190INT Set_ATE_RX_Antenna_Proc(
191 IN PRTMP_ADAPTER pAd,
192 IN PUCHAR arg);
193
194INT Set_ATE_TX_FREQOFFSET_Proc(
195 IN PRTMP_ADAPTER pAd,
196 IN PUCHAR arg);
197
198INT Set_ATE_TX_BW_Proc(
199 IN PRTMP_ADAPTER pAd,
200 IN PUCHAR arg);
201
202INT Set_ATE_TX_LENGTH_Proc(
203 IN PRTMP_ADAPTER pAd,
204 IN PUCHAR arg);
205
206INT Set_ATE_TX_COUNT_Proc(
207 IN PRTMP_ADAPTER pAd,
208 IN PUCHAR arg);
209
210INT Set_ATE_TX_MCS_Proc(
211 IN PRTMP_ADAPTER pAd,
212 IN PUCHAR arg);
213
214INT Set_ATE_TX_MODE_Proc(
215 IN PRTMP_ADAPTER pAd,
216 IN PUCHAR arg);
217
218INT Set_ATE_TX_GI_Proc(
219 IN PRTMP_ADAPTER pAd,
220 IN PUCHAR arg);
221
222
223INT Set_ATE_RX_FER_Proc(
224 IN PRTMP_ADAPTER pAd,
225 IN PUCHAR arg);
226
227INT Set_ATE_Read_RF_Proc(
228 IN PRTMP_ADAPTER pAd,
229 IN PUCHAR arg);
230
231INT Set_ATE_Write_RF1_Proc(
232 IN PRTMP_ADAPTER pAd,
233 IN PUCHAR arg);
234
235INT Set_ATE_Write_RF2_Proc(
236 IN PRTMP_ADAPTER pAd,
237 IN PUCHAR arg);
238
239INT Set_ATE_Write_RF3_Proc(
240 IN PRTMP_ADAPTER pAd,
241 IN PUCHAR arg);
242
243INT Set_ATE_Write_RF4_Proc(
244 IN PRTMP_ADAPTER pAd,
245 IN PUCHAR arg);
246
247INT Set_ATE_Load_E2P_Proc(
248 IN PRTMP_ADAPTER pAd,
249 IN PUCHAR arg);
250
251INT Set_ATE_Read_E2P_Proc(
252 IN PRTMP_ADAPTER pAd,
253 IN PUCHAR arg);
254
255INT Set_ATE_Show_Proc(
256 IN PRTMP_ADAPTER pAd,
257 IN PUCHAR arg);
258
259INT Set_ATE_Help_Proc(
260 IN PRTMP_ADAPTER pAd,
261 IN PUCHAR arg);
262
263#ifdef RALINK_ATE
264#ifdef RALINK_28xx_QA
265VOID ATE_QA_Statistics(
266 IN PRTMP_ADAPTER pAd,
267 IN PRXWI_STRUC pRxWI,
268 IN PRT28XX_RXD_STRUC p28xxRxD,
269 IN PHEADER_802_11 pHeader);
270
271VOID RtmpDoAte(
272 IN PRTMP_ADAPTER pAdapter,
273 IN struct iwreq *wrq);
274
275VOID BubbleSort(
276 IN INT32 n,
277 IN INT32 a[]);
278
279VOID CalNoiseLevel(
280 IN PRTMP_ADAPTER pAdapter,
281 IN UCHAR channel,
282 OUT INT32 buffer[3][10]);
283
284BOOLEAN SyncTxRxConfig(
285 IN PRTMP_ADAPTER pAdapter,
286 IN USHORT offset,
287 IN UCHAR value);
288
289#if 0
290INT Set_TxStart_Proc(
291 IN PRTMP_ADAPTER pAd,
292 IN PUCHAR arg);
293#endif // 0 //
294
295INT Set_TxStop_Proc(
296 IN PRTMP_ADAPTER pAd,
297 IN PUCHAR arg);
298
299INT Set_RxStop_Proc(
300 IN PRTMP_ADAPTER pAd,
301 IN PUCHAR arg);
302
303#if 0
304INT Set_EERead_Proc(
305 IN PRTMP_ADAPTER pAd,
306 IN PUCHAR arg);
307
308INT Set_EEWrite_Proc(
309 IN PRTMP_ADAPTER pAd,
310 IN PUCHAR arg);
311
312INT Set_BBPRead_Proc(
313 IN PRTMP_ADAPTER pAd,
314 IN PUCHAR arg);
315
316INT Set_BBPWrite_Proc(
317 IN PRTMP_ADAPTER pAd,
318 IN PUCHAR arg);
319
320INT Set_RFWrite_Proc(
321 IN PRTMP_ADAPTER pAd,
322 IN PUCHAR arg);
323#endif // end of #if 0 //
324#endif // RALINK_28xx_QA //
325#endif // RALINK_ATE //
326
327VOID ATEAsicSwitchChannel(
328 IN PRTMP_ADAPTER pAd);
329
330VOID ATEAsicAdjustTxPower(
331 IN PRTMP_ADAPTER pAd);
332
333VOID ATEDisableAsicProtect(
334 IN PRTMP_ADAPTER pAd);
335
336CHAR ATEConvertToRssi(
337 IN PRTMP_ADAPTER pAd,
338 IN CHAR Rssi,
339 IN UCHAR RssiNumber);
340
341VOID ATESampleRssi(
342 IN PRTMP_ADAPTER pAd,
343 IN PRXWI_STRUC pRxWI);
344
345
346#ifdef CONFIG_STA_SUPPORT
347VOID RTMPStationStop(
348 IN PRTMP_ADAPTER pAd);
349
350VOID RTMPStationStart(
351 IN PRTMP_ADAPTER pAd);
352#endif // CONFIG_STA_SUPPORT //
353#endif // __ATE_H__ //
diff --git a/drivers/staging/rt2860/rt_config.h b/drivers/staging/rt2860/rt_config.h
new file mode 100644
index 00000000000..7ee7a405b02
--- /dev/null
+++ b/drivers/staging/rt2860/rt_config.h
@@ -0,0 +1,101 @@
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#ifdef RT2860
57#include "rt2860.h"
58#endif // RT2860 //
59
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#ifdef LEAP_SUPPORT
72#include "leap.h"
73#endif // LEAP_SUPPORT //
74
75#ifdef BLOCK_NET_IF
76#include "netif_block.h"
77#endif // BLOCK_NET_IF //
78
79#ifdef IGMP_SNOOP_SUPPORT
80#include "igmp_snoop.h"
81#endif // IGMP_SNOOP_SUPPORT //
82
83#ifdef RALINK_ATE
84#include "rt_ate.h"
85#endif // RALINK_ATE //
86
87#ifdef CONFIG_STA_SUPPORT
88#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
89#ifndef WPA_SUPPLICANT_SUPPORT
90#error "Build for being controlled by NetworkManager or wext, please set HAS_WPA_SUPPLICANT=y and HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y"
91#endif // WPA_SUPPLICANT_SUPPORT //
92#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
93
94#endif // CONFIG_STA_SUPPORT //
95
96#ifdef IKANOS_VX_1X0
97#include "vr_ikans.h"
98#endif // IKANOS_VX_1X0 //
99
100#endif // __RT_CONFIG_H__
101
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
new file mode 100644
index 00000000000..374c174c88e
--- /dev/null
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -0,0 +1,1054 @@
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);
33BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
34BUILD_TIMER_FUNCTION(APSDPeriodicExec);
35BUILD_TIMER_FUNCTION(AsicRfTuningExec);
36
37
38#ifdef CONFIG_STA_SUPPORT
39BUILD_TIMER_FUNCTION(BeaconTimeout);
40BUILD_TIMER_FUNCTION(ScanTimeout);
41BUILD_TIMER_FUNCTION(AuthTimeout);
42BUILD_TIMER_FUNCTION(AssocTimeout);
43BUILD_TIMER_FUNCTION(ReassocTimeout);
44BUILD_TIMER_FUNCTION(DisassocTimeout);
45BUILD_TIMER_FUNCTION(LinkDownExec);
46#ifdef LEAP_SUPPORT
47BUILD_TIMER_FUNCTION(LeapAuthTimeout);
48#endif
49BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
50BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
51#ifdef RT2860
52BUILD_TIMER_FUNCTION(PsPollWakeExec);
53BUILD_TIMER_FUNCTION(RadioOnExec);
54#endif // RT2860 //
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#ifdef RT2860
297 NdisFreeSpinLock(&pAd->RxRingLock);
298#endif // RT2860 //
299
300 for (index =0 ; index < NUM_OF_TX_RING; index++)
301 {
302 NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
303 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
304 pAd->DeQueueRunning[index] = FALSE;
305 }
306
307 NdisFreeSpinLock(&pAd->irq_lock);
308
309 vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
310 kfree(os_cookie);
311}
312
313BOOLEAN OS_Need_Clone_Packet(void)
314{
315 return (FALSE);
316}
317
318
319
320/*
321 ========================================================================
322
323 Routine Description:
324 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
325 must have only one NDIS BUFFER
326 return - byte copied. 0 means can't create NDIS PACKET
327 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
328
329 Arguments:
330 pAd Pointer to our adapter
331 pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
332 *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
333
334 Return Value:
335 NDIS_STATUS_SUCCESS
336 NDIS_STATUS_FAILURE
337
338 Note:
339
340 ========================================================================
341*/
342NDIS_STATUS RTMPCloneNdisPacket(
343 IN PRTMP_ADAPTER pAd,
344 IN BOOLEAN pInsAMSDUHdr,
345 IN PNDIS_PACKET pInPacket,
346 OUT PNDIS_PACKET *ppOutPacket)
347{
348
349 struct sk_buff *pkt;
350
351 ASSERT(pInPacket);
352 ASSERT(ppOutPacket);
353
354 // 1. Allocate a packet
355 pkt = dev_alloc_skb(2048);
356
357 if (pkt == NULL)
358 {
359 return NDIS_STATUS_FAILURE;
360 }
361
362 skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
363 NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
364 *ppOutPacket = OSPKT_TO_RTPKT(pkt);
365
366
367 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
368
369 printk("###Clone###\n");
370
371 return NDIS_STATUS_SUCCESS;
372}
373
374
375// the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
376NDIS_STATUS RTMPAllocateNdisPacket(
377 IN PRTMP_ADAPTER pAd,
378 OUT PNDIS_PACKET *ppPacket,
379 IN PUCHAR pHeader,
380 IN UINT HeaderLen,
381 IN PUCHAR pData,
382 IN UINT DataLen)
383{
384 PNDIS_PACKET pPacket;
385 ASSERT(pData);
386 ASSERT(DataLen);
387
388 // 1. Allocate a packet
389 pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
390 if (pPacket == NULL)
391 {
392 *ppPacket = NULL;
393#ifdef DEBUG
394 printk("RTMPAllocateNdisPacket Fail\n\n");
395#endif
396 return NDIS_STATUS_FAILURE;
397 }
398
399 // 2. clone the frame content
400 if (HeaderLen > 0)
401 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
402 if (DataLen > 0)
403 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
404
405 // 3. update length of packet
406 skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
407
408 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
409// printk("%s : pPacket = %p, len = %d\n", __FUNCTION__, pPacket, GET_OS_PKT_LEN(pPacket));
410 *ppPacket = pPacket;
411 return NDIS_STATUS_SUCCESS;
412}
413
414/*
415 ========================================================================
416 Description:
417 This routine frees a miniport internally allocated NDIS_PACKET and its
418 corresponding NDIS_BUFFER and allocated memory.
419 ========================================================================
420*/
421VOID RTMPFreeNdisPacket(
422 IN PRTMP_ADAPTER pAd,
423 IN PNDIS_PACKET pPacket)
424{
425 dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
426}
427
428
429// IRQL = DISPATCH_LEVEL
430// NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
431// scatter gather buffer
432NDIS_STATUS Sniff2BytesFromNdisBuffer(
433 IN PNDIS_BUFFER pFirstBuffer,
434 IN UCHAR DesiredOffset,
435 OUT PUCHAR pByte0,
436 OUT PUCHAR pByte1)
437{
438 *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
439 *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
440
441 return NDIS_STATUS_SUCCESS;
442}
443
444
445void RTMP_QueryPacketInfo(
446 IN PNDIS_PACKET pPacket,
447 OUT PACKET_INFO *pPacketInfo,
448 OUT PUCHAR *pSrcBufVA,
449 OUT UINT *pSrcBufLen)
450{
451 pPacketInfo->BufferCount = 1;
452 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
453 pPacketInfo->PhysicalBufferCount = 1;
454 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
455
456 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
457 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
458}
459
460void RTMP_QueryNextPacketInfo(
461 IN PNDIS_PACKET *ppPacket,
462 OUT PACKET_INFO *pPacketInfo,
463 OUT PUCHAR *pSrcBufVA,
464 OUT UINT *pSrcBufLen)
465{
466 PNDIS_PACKET pPacket = NULL;
467
468 if (*ppPacket)
469 pPacket = GET_OS_PKT_NEXT(*ppPacket);
470
471 if (pPacket)
472 {
473 pPacketInfo->BufferCount = 1;
474 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
475 pPacketInfo->PhysicalBufferCount = 1;
476 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
477
478 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
479 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
480 *ppPacket = GET_OS_PKT_NEXT(pPacket);
481 }
482 else
483 {
484 pPacketInfo->BufferCount = 0;
485 pPacketInfo->pFirstBuffer = NULL;
486 pPacketInfo->PhysicalBufferCount = 0;
487 pPacketInfo->TotalPacketLength = 0;
488
489 *pSrcBufVA = NULL;
490 *pSrcBufLen = 0;
491 *ppPacket = NULL;
492 }
493}
494
495// not yet support MBSS
496PNET_DEV get_netdev_from_bssid(
497 IN PRTMP_ADAPTER pAd,
498 IN UCHAR FromWhichBSSID)
499{
500 PNET_DEV dev_p = NULL;
501
502#ifdef CONFIG_STA_SUPPORT
503 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
504 {
505 dev_p = pAd->net_dev;
506 }
507#endif // CONFIG_STA_SUPPORT //
508
509 ASSERT(dev_p);
510 return dev_p; /* return one of MBSS */
511}
512
513PNDIS_PACKET DuplicatePacket(
514 IN PRTMP_ADAPTER pAd,
515 IN PNDIS_PACKET pPacket,
516 IN UCHAR FromWhichBSSID)
517{
518 struct sk_buff *skb;
519 PNDIS_PACKET pRetPacket = NULL;
520 USHORT DataSize;
521 UCHAR *pData;
522
523 DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
524 pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
525
526
527 skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
528 if (skb)
529 {
530 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
531 pRetPacket = OSPKT_TO_RTPKT(skb);
532 }
533
534 return pRetPacket;
535
536}
537
538PNDIS_PACKET duplicate_pkt(
539 IN PRTMP_ADAPTER pAd,
540 IN PUCHAR pHeader802_3,
541 IN UINT HdrLen,
542 IN PUCHAR pData,
543 IN ULONG DataSize,
544 IN UCHAR FromWhichBSSID)
545{
546 struct sk_buff *skb;
547 PNDIS_PACKET pPacket = NULL;
548
549
550 if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
551 {
552 skb_reserve(skb, 2);
553 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
554 skb_put(skb, HdrLen);
555 NdisMoveMemory(skb->tail, pData, DataSize);
556 skb_put(skb, DataSize);
557 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
558 pPacket = OSPKT_TO_RTPKT(skb);
559 }
560
561 return pPacket;
562}
563
564
565#define TKIP_TX_MIC_SIZE 8
566PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
567 IN PRTMP_ADAPTER pAd,
568 IN PNDIS_PACKET pPacket)
569{
570 struct sk_buff *skb, *newskb;
571
572
573 skb = RTPKT_TO_OSPKT(pPacket);
574 if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
575 {
576 // alloc a new skb and copy the packet
577 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
578 dev_kfree_skb_any(skb);
579 if (newskb == NULL)
580 {
581 DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
582 return NULL;
583 }
584 skb = newskb;
585 }
586
587 return OSPKT_TO_RTPKT(skb);
588}
589
590
591
592
593PNDIS_PACKET ClonePacket(
594 IN PRTMP_ADAPTER pAd,
595 IN PNDIS_PACKET pPacket,
596 IN PUCHAR pData,
597 IN ULONG DataSize)
598{
599 struct sk_buff *pRxPkt;
600 struct sk_buff *pClonedPkt;
601
602 ASSERT(pPacket);
603 pRxPkt = RTPKT_TO_OSPKT(pPacket);
604
605 // clone the packet
606 pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
607
608 if (pClonedPkt)
609 {
610 // set the correct dataptr and data len
611 pClonedPkt->dev = pRxPkt->dev;
612 pClonedPkt->data = pData;
613 pClonedPkt->len = DataSize;
614 pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
615 ASSERT(DataSize < 1530);
616 }
617 return pClonedPkt;
618}
619
620//
621// change OS packet DataPtr and DataLen
622//
623void update_os_packet_info(
624 IN PRTMP_ADAPTER pAd,
625 IN RX_BLK *pRxBlk,
626 IN UCHAR FromWhichBSSID)
627{
628 struct sk_buff *pOSPkt;
629
630 ASSERT(pRxBlk->pRxPacket);
631 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
632
633 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
634 pOSPkt->data = pRxBlk->pData;
635 pOSPkt->len = pRxBlk->DataSize;
636 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
637}
638
639
640void wlan_802_11_to_802_3_packet(
641 IN PRTMP_ADAPTER pAd,
642 IN RX_BLK *pRxBlk,
643 IN PUCHAR pHeader802_3,
644 IN UCHAR FromWhichBSSID)
645{
646 struct sk_buff *pOSPkt;
647
648 ASSERT(pRxBlk->pRxPacket);
649 ASSERT(pHeader802_3);
650
651 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
652
653 pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
654 pOSPkt->data = pRxBlk->pData;
655 pOSPkt->len = pRxBlk->DataSize;
656 pOSPkt->tail = pOSPkt->data + pOSPkt->len;
657
658 //
659 // copy 802.3 header
660 //
661 //
662
663#ifdef CONFIG_STA_SUPPORT
664 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
665 NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
666#endif // CONFIG_STA_SUPPORT //
667 }
668
669
670
671void announce_802_3_packet(
672 IN PRTMP_ADAPTER pAd,
673 IN PNDIS_PACKET pPacket)
674{
675
676 struct sk_buff *pRxPkt;
677
678 ASSERT(pPacket);
679
680 pRxPkt = RTPKT_TO_OSPKT(pPacket);
681
682 /* Push up the protocol stack */
683#ifdef IKANOS_VX_1X0
684 IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
685#else
686 pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
687
688 netif_rx(pRxPkt);
689#endif // IKANOS_VX_1X0 //
690}
691
692
693PRTMP_SCATTER_GATHER_LIST
694rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
695{
696 sg->NumberOfElements = 1;
697 sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
698 sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
699 return (sg);
700}
701
702void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
703{
704 unsigned char *pt;
705 int x;
706
707 if (RTDebugLevel < RT_DEBUG_TRACE)
708 return;
709
710 pt = pSrcBufVA;
711 printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
712 for (x=0; x<SrcBufLen; x++)
713 {
714 if (x % 16 == 0)
715 printk("0x%04x : ", x);
716 printk("%02x ", ((unsigned char)pt[x]));
717 if (x%16 == 15) printk("\n");
718 }
719 printk("\n");
720}
721
722/*
723 ========================================================================
724
725 Routine Description:
726 Send log message through wireless event
727
728 Support standard iw_event with IWEVCUSTOM. It is used below.
729
730 iwreq_data.data.flags is used to store event_flag that is defined by user.
731 iwreq_data.data.length is the length of the event log.
732
733 The format of the event log is composed of the entry's MAC address and
734 the desired log message (refer to pWirelessEventText).
735
736 ex: 11:22:33:44:55:66 has associated successfully
737
738 p.s. The requirement of Wireless Extension is v15 or newer.
739
740 ========================================================================
741*/
742VOID RTMPSendWirelessEvent(
743 IN PRTMP_ADAPTER pAd,
744 IN USHORT Event_flag,
745 IN PUCHAR pAddr,
746 IN UCHAR BssIdx,
747 IN CHAR Rssi)
748{
749#if WIRELESS_EXT >= 15
750
751 union iwreq_data wrqu;
752 PUCHAR pBuf = NULL, pBufPtr = NULL;
753 USHORT event, type, BufLen;
754 UCHAR event_table_len = 0;
755
756 type = Event_flag & 0xFF00;
757 event = Event_flag & 0x00FF;
758
759 switch (type)
760 {
761 case IW_SYS_EVENT_FLAG_START:
762 event_table_len = IW_SYS_EVENT_TYPE_NUM;
763 break;
764
765 case IW_SPOOF_EVENT_FLAG_START:
766 event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
767 break;
768
769 case IW_FLOOD_EVENT_FLAG_START:
770 event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
771 break;
772 }
773
774 if (event_table_len == 0)
775 {
776 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __FUNCTION__, type));
777 return;
778 }
779
780 if (event >= event_table_len)
781 {
782 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __FUNCTION__, event));
783 return;
784 }
785
786 //Allocate memory and copy the msg.
787 if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
788 {
789 //Prepare the payload
790 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
791
792 pBufPtr = pBuf;
793
794 if (pAddr)
795 pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
796 else if (BssIdx < MAX_MBSSID_NUM)
797 pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
798 else
799 pBufPtr += sprintf(pBufPtr, "(RT2860) ");
800
801 if (type == IW_SYS_EVENT_FLAG_START)
802 pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
803 else if (type == IW_SPOOF_EVENT_FLAG_START)
804 pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
805 else if (type == IW_FLOOD_EVENT_FLAG_START)
806 pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
807 else
808 pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
809
810 pBufPtr[pBufPtr - pBuf] = '\0';
811 BufLen = pBufPtr - pBuf;
812
813 memset(&wrqu, 0, sizeof(wrqu));
814 wrqu.data.flags = Event_flag;
815 wrqu.data.length = BufLen;
816
817 //send wireless event
818 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
819
820 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __FUNCTION__, pBuf));
821
822 kfree(pBuf);
823 }
824 else
825 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __FUNCTION__));
826#else
827 DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __FUNCTION__));
828#endif /* WIRELESS_EXT >= 15 */
829}
830
831
832#ifdef CONFIG_STA_SUPPORT
833void send_monitor_packets(
834 IN PRTMP_ADAPTER pAd,
835 IN RX_BLK *pRxBlk)
836{
837 struct sk_buff *pOSPkt;
838 wlan_ng_prism2_header *ph;
839 int rate_index = 0;
840 USHORT header_len = 0;
841 UCHAR temp_header[40] = {0};
842
843 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
844 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,
845 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};
846
847
848 ASSERT(pRxBlk->pRxPacket);
849 if (pRxBlk->DataSize < 10)
850 {
851 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __FUNCTION__, pRxBlk->DataSize));
852 goto err_free_sk_buff;
853 }
854
855 if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
856 {
857 DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __FUNCTION__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
858 goto err_free_sk_buff;
859 }
860
861 pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
862 pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
863 if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
864 {
865 pRxBlk->DataSize -= LENGTH_802_11;
866 if ((pRxBlk->pHeader->FC.ToDs == 1) &&
867 (pRxBlk->pHeader->FC.FrDs == 1))
868 header_len = LENGTH_802_11_WITH_ADDR4;
869 else
870 header_len = LENGTH_802_11;
871
872 // QOS
873 if (pRxBlk->pHeader->FC.SubType & 0x08)
874 {
875 header_len += 2;
876 // Data skip QOS contorl field
877 pRxBlk->DataSize -=2;
878 }
879
880 // Order bit: A-Ralink or HTC+
881 if (pRxBlk->pHeader->FC.Order)
882 {
883 header_len += 4;
884 // Data skip HTC contorl field
885 pRxBlk->DataSize -= 4;
886 }
887
888 // Copy Header
889 if (header_len <= 40)
890 NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
891
892 // skip HW padding
893 if (pRxBlk->RxD.L2PAD)
894 pRxBlk->pData += (header_len + 2);
895 else
896 pRxBlk->pData += header_len;
897 } //end if
898
899
900 if (pRxBlk->DataSize < pOSPkt->len) {
901 skb_trim(pOSPkt,pRxBlk->DataSize);
902 } else {
903 skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
904 } //end if
905
906 if ((pRxBlk->pData - pOSPkt->data) > 0) {
907 skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
908 skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
909 } //end if
910
911 if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
912 if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
913 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __FUNCTION__));
914 goto err_free_sk_buff;
915 } //end if
916 } //end if
917
918 if (header_len > 0)
919 NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
920
921 ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
922 NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
923
924 ph->msgcode = DIDmsg_lnxind_wlansniffrm;
925 ph->msglen = sizeof(wlan_ng_prism2_header);
926 strcpy(ph->devname, pAd->net_dev->name);
927
928 ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
929 ph->hosttime.status = 0;
930 ph->hosttime.len = 4;
931 ph->hosttime.data = jiffies;
932
933 ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
934 ph->mactime.status = 0;
935 ph->mactime.len = 0;
936 ph->mactime.data = 0;
937
938 ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
939 ph->istx.status = 0;
940 ph->istx.len = 0;
941 ph->istx.data = 0;
942
943 ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
944 ph->channel.status = 0;
945 ph->channel.len = 4;
946
947 ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
948
949 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
950 ph->rssi.status = 0;
951 ph->rssi.len = 4;
952 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));;
953
954 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
955 ph->signal.status = 0;
956 ph->signal.len = 4;
957 ph->signal.data = 0; //rssi + noise;
958
959 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
960 ph->noise.status = 0;
961 ph->noise.len = 4;
962 ph->noise.data = 0;
963
964#ifdef DOT11_N_SUPPORT
965 if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
966 {
967 rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
968 }
969 else
970#endif // DOT11_N_SUPPORT //
971 if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
972 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
973 else
974 rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
975 if (rate_index < 0)
976 rate_index = 0;
977 if (rate_index > 255)
978 rate_index = 255;
979
980 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
981 ph->rate.status = 0;
982 ph->rate.len = 4;
983 ph->rate.data = ralinkrate[rate_index];
984
985 ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
986 ph->frmlen.status = 0;
987 ph->frmlen.len = 4;
988 ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
989
990
991 pOSPkt->pkt_type = PACKET_OTHERHOST;
992 pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
993 pOSPkt->ip_summed = CHECKSUM_NONE;
994 netif_rx(pOSPkt);
995
996 return;
997
998err_free_sk_buff:
999 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
1000 return;
1001
1002}
1003#endif // CONFIG_STA_SUPPORT //
1004
1005
1006void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
1007{
1008
1009#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1010 daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
1011
1012 allow_signal(SIGTERM);
1013 allow_signal(SIGKILL);
1014 current->flags |= PF_NOFREEZE;
1015#else
1016 unsigned long flags;
1017
1018 daemonize();
1019 reparent_to_init();
1020 strcpy(current->comm, pThreadName);
1021
1022 siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
1023
1024 /* Allow interception of SIGKILL only
1025 * Don't allow other signals to interrupt the transmission */
1026#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
1027 spin_lock_irqsave(&current->sigmask_lock, flags);
1028 flush_signals(current);
1029 recalc_sigpending(current);
1030 spin_unlock_irqrestore(&current->sigmask_lock, flags);
1031#endif
1032#endif
1033
1034 /* signal that we've started the thread */
1035 complete(pNotify);
1036
1037}
1038
1039void RTMP_IndicateMediaState(
1040 IN PRTMP_ADAPTER pAd)
1041{
1042 if (pAd->CommonCfg.bWirelessEvent)
1043 {
1044 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1045 {
1046 RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1047 }
1048 else
1049 {
1050 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1051 }
1052 }
1053}
1054
diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h
new file mode 100644
index 00000000000..0cc7cf23d76
--- /dev/null
+++ b/drivers/staging/rt2860/rt_linux.h
@@ -0,0 +1,926 @@
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#ifdef RT2860
94#define STA_PROFILE_PATH "/etc/Wireless/RT2860STA/RT2860STA.dat"
95#define STA_RTMP_FIRMWARE_FILE_NAME "/etc/Wireless/RT2860STA/RT2860STA.bin"
96#define STA_NIC_DEVICE_NAME "RT2860STA"
97#define STA_DRIVER_VERSION "1.8.0.0"
98#ifdef MULTIPLE_CARD_SUPPORT
99#define CARD_INFO_PATH "/etc/Wireless/RT2860STA/RT2860STACard.dat"
100#endif // MULTIPLE_CARD_SUPPORT //
101#endif // RT2860 //
102
103
104#endif // CONFIG_STA_SUPPORT //
105
106#ifdef RT2860
107#ifndef PCI_DEVICE
108#define PCI_DEVICE(vend,dev) \
109 .vendor = (vend), .device = (dev), \
110 .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
111#endif // PCI_DEVICE //
112#endif // RT2860 //
113
114#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
115
116#define RTMP_TIME_AFTER(a,b) \
117 (typecheck(unsigned long, (unsigned long)a) && \
118 typecheck(unsigned long, (unsigned long)b) && \
119 ((long)(b) - (long)(a) < 0))
120
121#define RTMP_TIME_AFTER_EQ(a,b) \
122 (typecheck(unsigned long, (unsigned long)a) && \
123 typecheck(unsigned long, (unsigned long)b) && \
124 ((long)(a) - (long)(b) >= 0))
125#define RTMP_TIME_BEFORE(a,b) RTMP_TIME_AFTER_EQ(b,a)
126#else
127#define RTMP_TIME_AFTER(a,b) time_after(a, b)
128#endif
129
130#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
131#define RT_MOD_INC_USE_COUNT() \
132 if (!try_module_get(THIS_MODULE)) \
133 { \
134 DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot reserve module\n", __FUNCTION__)); \
135 return -1; \
136 }
137
138#define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE);
139#else
140#define RT_MOD_INC_USE_COUNT() MOD_INC_USE_COUNT;
141#define RT_MOD_DEC_USE_COUNT() MOD_DEC_USE_COUNT;
142#endif
143
144#define OS_HZ HZ
145
146#define ETH_LENGTH_OF_ADDRESS 6
147
148#define IN
149#define OUT
150
151#define NDIS_STATUS INT
152#define NDIS_STATUS_SUCCESS 0x00
153#define NDIS_STATUS_FAILURE 0x01
154#define NDIS_STATUS_INVALID_DATA 0x02
155#define NDIS_STATUS_RESOURCES 0x03
156
157#define MIN_NET_DEVICE_FOR_AID 0x00 //0x00~0x3f
158#define MIN_NET_DEVICE_FOR_MBSSID 0x00 //0x00,0x10,0x20,0x30
159#define MIN_NET_DEVICE_FOR_WDS 0x10 //0x40,0x50,0x60,0x70
160#define MIN_NET_DEVICE_FOR_APCLI 0x20
161#define MIN_NET_DEVICE_FOR_MESH 0x30
162#ifdef CONFIG_STA_SUPPORT
163#define MIN_NET_DEVICE_FOR_DLS 0x40
164#endif // CONFIG_STA_SUPPORT //
165
166
167#ifdef CONFIG_STA_SUPPORT
168#define NDIS_PACKET_TYPE_DIRECTED 0
169#define NDIS_PACKET_TYPE_MULTICAST 1
170#define NDIS_PACKET_TYPE_BROADCAST 2
171#define NDIS_PACKET_TYPE_ALL_MULTICAST 3
172#endif // CONFIG_STA_SUPPORT //
173
174#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
175typedef struct pid * THREAD_PID;
176#define THREAD_PID_INIT_VALUE NULL
177#define GET_PID(_v) find_get_pid(_v)
178#define GET_PID_NUMBER(_v) pid_nr(_v)
179#define CHECK_PID_LEGALITY(_pid) if (pid_nr(_pid) >= 0)
180#define KILL_THREAD_PID(_A, _B, _C) kill_pid(_A, _B, _C)
181#else
182typedef pid_t THREAD_PID;
183#define THREAD_PID_INIT_VALUE -1
184#define GET_PID(_v) _v
185#define GET_PID_NUMBER(_v) _v
186#define CHECK_PID_LEGALITY(_pid) if (_pid >= 0)
187#define KILL_THREAD_PID(_A, _B, _C) kill_proc(_A, _B, _C)
188#endif
189
190struct os_lock {
191 spinlock_t lock;
192 unsigned long flags;
193};
194
195
196struct os_cookie {
197#ifdef RT2860
198 struct pci_dev *pci_dev;
199 struct pci_dev *parent_pci_dev;
200 dma_addr_t pAd_pa;
201#endif // RT2860 //
202
203
204 struct tasklet_struct rx_done_task;
205 struct tasklet_struct mgmt_dma_done_task;
206 struct tasklet_struct ac0_dma_done_task;
207 struct tasklet_struct ac1_dma_done_task;
208 struct tasklet_struct ac2_dma_done_task;
209 struct tasklet_struct ac3_dma_done_task;
210 struct tasklet_struct hcca_dma_done_task;
211 struct tasklet_struct tbtt_task;
212#ifdef RT2860
213 struct tasklet_struct fifo_statistic_full_task;
214#endif // RT2860 //
215
216
217 unsigned long apd_pid; //802.1x daemon pid
218 INT ioctl_if_type;
219 INT ioctl_if;
220};
221
222typedef struct _VIRTUAL_ADAPTER
223{
224 struct net_device *RtmpDev;
225 struct net_device *VirtualDev;
226} VIRTUAL_ADAPTER, PVIRTUAL_ADAPTER;
227
228#undef ASSERT
229#define ASSERT(x) \
230{ \
231 if (!(x)) \
232 { \
233 printk(KERN_WARNING __FILE__ ":%d assert " #x "failed\n", __LINE__); \
234 } \
235}
236
237typedef struct os_cookie * POS_COOKIE;
238typedef struct pci_dev * PPCI_DEV;
239typedef struct net_device * PNET_DEV;
240typedef void * PNDIS_PACKET;
241typedef char NDIS_PACKET;
242typedef PNDIS_PACKET * PPNDIS_PACKET;
243typedef dma_addr_t NDIS_PHYSICAL_ADDRESS;
244typedef dma_addr_t * PNDIS_PHYSICAL_ADDRESS;
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#ifdef RT2860
270#define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \
271 linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir)
272
273#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) \
274 linux_pci_unmap_single(_handle, _ptr, _size, _dir)
275
276#define PCI_ALLOC_CONSISTENT(_pci_dev, _size, _ptr) \
277 pci_alloc_consistent(_pci_dev, _size, _ptr)
278
279#define PCI_FREE_CONSISTENT(_pci_dev, _size, _virtual_addr, _physical_addr) \
280 pci_free_consistent(_pci_dev, _size, _virtual_addr, _physical_addr)
281
282#define DEV_ALLOC_SKB(_length) \
283 dev_alloc_skb(_length)
284#endif // RT2860 //
285
286
287
288#define BEACON_FRAME_DMA_CACHE_WBACK(_ptr, _size) \
289 dma_cache_wback(_ptr, _size)
290
291
292//////////////////////////////////////////
293//
294//////////////////////////////////////////
295
296
297#define NdisMIndicateStatus(_w, _x, _y, _z)
298
299
300typedef struct timer_list RTMP_OS_TIMER;
301
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} RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT;
313
314
315
316
317//#define DBG 1
318
319//
320// MACRO for debugging information
321//
322
323#ifdef DBG
324extern ULONG RTDebugLevel;
325
326#define DBGPRINT_RAW(Level, Fmt) \
327{ \
328 if (Level <= RTDebugLevel) \
329 { \
330 printk Fmt; \
331 } \
332}
333
334#define DBGPRINT(Level, Fmt) DBGPRINT_RAW(Level, Fmt)
335
336
337#define DBGPRINT_ERR(Fmt) \
338{ \
339 printk("ERROR!!! "); \
340 printk Fmt; \
341}
342
343#define DBGPRINT_S(Status, Fmt) \
344{ \
345 printk Fmt; \
346}
347
348
349#else
350#define DBGPRINT(Level, Fmt)
351#define DBGPRINT_RAW(Level, Fmt)
352#define DBGPRINT_S(Status, Fmt)
353#define DBGPRINT_ERR(Fmt)
354#endif
355
356
357//
358// spin_lock enhanced for Nested spin lock
359//
360#define NdisAllocateSpinLock(__lock) \
361{ \
362 spin_lock_init((spinlock_t *)(__lock)); \
363}
364
365#define NdisFreeSpinLock(lock) \
366{ \
367}
368
369
370#define RTMP_SEM_LOCK(__lock) \
371{ \
372 spin_lock_bh((spinlock_t *)(__lock)); \
373}
374
375#define RTMP_SEM_UNLOCK(__lock) \
376{ \
377 spin_unlock_bh((spinlock_t *)(__lock)); \
378}
379
380// sample, use semaphore lock to replace IRQ lock, 2007/11/15
381#define RTMP_IRQ_LOCK(__lock, __irqflags) \
382{ \
383 __irqflags = 0; \
384 spin_lock_bh((spinlock_t *)(__lock)); \
385 pAd->irq_disabled |= 1; \
386}
387
388#define RTMP_IRQ_UNLOCK(__lock, __irqflag) \
389{ \
390 pAd->irq_disabled &= 0; \
391 spin_unlock_bh((spinlock_t *)(__lock)); \
392}
393
394#define RTMP_INT_LOCK(__lock, __irqflags) \
395{ \
396 spin_lock_irqsave((spinlock_t *)__lock, __irqflags); \
397}
398
399#define RTMP_INT_UNLOCK(__lock, __irqflag) \
400{ \
401 spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag)); \
402}
403
404#ifdef RT2860
405#if defined(INF_TWINPASS) || defined(INF_DANUBE) || defined(IKANOS_VX_1X0)
406//Patch for ASIC turst read/write bug, needs to remove after metel fix
407#define RTMP_IO_READ32(_A, _R, _pV) \
408{ \
409 if ((_A)->bPCIclkOff == FALSE) \
410 { \
411 (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \
412 (*_pV = readl((void *)((_A)->CSRBaseAddress + (_R)))); \
413 (*_pV = SWAP32(*((UINT32 *)(_pV)))); \
414 } \
415}
416#define RTMP_IO_READ8(_A, _R, _pV) \
417{ \
418 (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \
419 (*_pV = readb((void *)((_A)->CSRBaseAddress + (_R)))); \
420}
421#define RTMP_IO_WRITE32(_A, _R, _V) \
422{ \
423 if ((_A)->bPCIclkOff == FALSE) \
424 { \
425 UINT32 _Val; \
426 _Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \
427 _Val = SWAP32(_V); \
428 writel(_Val, (void *)((_A)->CSRBaseAddress + (_R))); \
429 } \
430}
431#define RTMP_IO_WRITE8(_A, _R, _V) \
432{ \
433 UINT Val; \
434 Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \
435 writeb((_V), (PUCHAR)((_A)->CSRBaseAddress + (_R))); \
436}
437#define RTMP_IO_WRITE16(_A, _R, _V) \
438{ \
439 UINT Val; \
440 Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \
441 writew(SWAP16((_V)), (PUSHORT)((_A)->CSRBaseAddress + (_R))); \
442}
443#else
444//Patch for ASIC turst read/write bug, needs to remove after metel fix
445#define RTMP_IO_READ32(_A, _R, _pV) \
446{ \
447 if ((_A)->bPCIclkOff == FALSE) \
448 { \
449 (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \
450 (*_pV = readl((void *)((_A)->CSRBaseAddress + (_R)))); \
451 } \
452 else \
453 *_pV = 0; \
454}
455#define RTMP_IO_READ8(_A, _R, _pV) \
456{ \
457 (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \
458 (*_pV = readb((void *)((_A)->CSRBaseAddress + (_R)))); \
459}
460#define RTMP_IO_WRITE32(_A, _R, _V) \
461{ \
462 if ((_A)->bPCIclkOff == FALSE) \
463 { \
464 UINT Val; \
465 Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \
466 writel(_V, (void *)((_A)->CSRBaseAddress + (_R))); \
467 } \
468}
469#if defined(BRCM_6358)
470#define RTMP_IO_WRITE8(_A, _R, _V) \
471{ \
472 ULONG Val; \
473 UCHAR _i; \
474 _i = (_R & 0x3); \
475 Val = readl((void *)((_A)->CSRBaseAddress + (_R - _i))); \
476 Val = Val & (~(0x000000ff << ((_i)*8))); \
477 Val = Val | ((ULONG)_V << ((_i)*8)); \
478 writel((Val), (void *)((_A)->CSRBaseAddress + (_R - _i))); \
479}
480#else
481#define RTMP_IO_WRITE8(_A, _R, _V) \
482{ \
483 UINT Val; \
484 Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \
485 writeb((_V), (PUCHAR)((_A)->CSRBaseAddress + (_R))); \
486}
487#endif
488#define RTMP_IO_WRITE16(_A, _R, _V) \
489{ \
490 UINT Val; \
491 Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \
492 writew((_V), (PUSHORT)((_A)->CSRBaseAddress + (_R))); \
493}
494#endif
495#endif // RT2860 //
496
497
498#ifndef wait_event_interruptible_timeout
499#define __wait_event_interruptible_timeout(wq, condition, ret) \
500do { \
501 wait_queue_t __wait; \
502 init_waitqueue_entry(&__wait, current); \
503 add_wait_queue(&wq, &__wait); \
504 for (;;) { \
505 set_current_state(TASK_INTERRUPTIBLE); \
506 if (condition) \
507 break; \
508 if (!signal_pending(current)) { \
509 ret = schedule_timeout(ret); \
510 if (!ret) \
511 break; \
512 continue; \
513 } \
514 ret = -ERESTARTSYS; \
515 break; \
516 } \
517 current->state = TASK_RUNNING; \
518 remove_wait_queue(&wq, &__wait); \
519} while (0)
520
521#define wait_event_interruptible_timeout(wq, condition, timeout) \
522({ \
523 long __ret = timeout; \
524 if (!(condition)) \
525 __wait_event_interruptible_timeout(wq, condition, __ret); \
526 __ret; \
527})
528#endif
529#define ONE_TICK 1
530#define OS_WAIT(_time) \
531{ int _i; \
532 long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\
533 wait_queue_head_t _wait; \
534 init_waitqueue_head(&_wait); \
535 for (_i=0; _i<(_loop); _i++) \
536 wait_event_interruptible_timeout(_wait, 0, ONE_TICK); }
537
538
539/* Modified by Wu Xi-Kun 4/21/2006 */
540typedef void (*TIMER_FUNCTION)(unsigned long);
541
542#define COPY_MAC_ADDR(Addr1, Addr2) memcpy((Addr1), (Addr2), MAC_ADDR_LEN)
543
544#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
545#define MlmeFreeMemory(_pAd, _pVA) os_free_mem(_pAd, _pVA)
546
547#ifdef RT2860
548#define BUILD_TIMER_FUNCTION(_func) \
549void linux_##_func(unsigned long data) \
550{ \
551 PRALINK_TIMER_STRUCT pTimer = (PRALINK_TIMER_STRUCT) data; \
552 \
553 _func(NULL, (PVOID) pTimer->cookie, NULL, pTimer); \
554 if (pTimer->Repeat) \
555 RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); \
556}
557#endif // RT2860 //
558
559
560
561#define DECLARE_TIMER_FUNCTION(_func) \
562void linux_##_func(unsigned long data)
563
564#define GET_TIMER_FUNCTION(_func) \
565 linux_##_func
566
567DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
568DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
569DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
570DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
571DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
572
573
574#ifdef CONFIG_STA_SUPPORT
575DECLARE_TIMER_FUNCTION(BeaconTimeout);
576DECLARE_TIMER_FUNCTION(ScanTimeout);
577DECLARE_TIMER_FUNCTION(AuthTimeout);
578DECLARE_TIMER_FUNCTION(AssocTimeout);
579DECLARE_TIMER_FUNCTION(ReassocTimeout);
580DECLARE_TIMER_FUNCTION(DisassocTimeout);
581DECLARE_TIMER_FUNCTION(LinkDownExec);
582#ifdef LEAP_SUPPORT
583DECLARE_TIMER_FUNCTION(LeapAuthTimeout);
584#endif
585DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
586DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
587DECLARE_TIMER_FUNCTION(PsPollWakeExec);
588DECLARE_TIMER_FUNCTION(RadioOnExec);
589
590#ifdef QOS_DLS_SUPPORT
591DECLARE_TIMER_FUNCTION(DlsTimeoutAction);
592#endif // QOS_DLS_SUPPORT //
593#endif // CONFIG_STA_SUPPORT //
594
595void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time);
596
597
598/*
599 * packet helper
600 * - convert internal rt packet to os packet or
601 * os packet to rt packet
602 */
603#define RTPKT_TO_OSPKT(_p) ((struct sk_buff *)(_p))
604#define OSPKT_TO_RTPKT(_p) ((PNDIS_PACKET)(_p))
605
606#define GET_OS_PKT_DATAPTR(_pkt) \
607 (RTPKT_TO_OSPKT(_pkt)->data)
608
609#define GET_OS_PKT_LEN(_pkt) \
610 (RTPKT_TO_OSPKT(_pkt)->len)
611
612#define GET_OS_PKT_DATATAIL(_pkt) \
613 (RTPKT_TO_OSPKT(_pkt)->tail)
614
615#define GET_OS_PKT_HEAD(_pkt) \
616 (RTPKT_TO_OSPKT(_pkt)->head)
617
618#define GET_OS_PKT_END(_pkt) \
619 (RTPKT_TO_OSPKT(_pkt)->end)
620
621#define GET_OS_PKT_NETDEV(_pkt) \
622 (RTPKT_TO_OSPKT(_pkt)->dev)
623
624#define GET_OS_PKT_TYPE(_pkt) \
625 (RTPKT_TO_OSPKT(_pkt))
626
627#define GET_OS_PKT_NEXT(_pkt) \
628 (RTPKT_TO_OSPKT(_pkt)->next)
629
630
631#define OS_NTOHS(_Val) \
632 (ntohs(_Val))
633#define OS_HTONS(_Val) \
634 (htons(_Val))
635#define OS_NTOHL(_Val) \
636 (ntohl(_Val))
637#define OS_HTONL(_Val) \
638 (htonl(_Val))
639
640/* statistics counter */
641#define STATS_INC_RX_PACKETS(_pAd, _dev)
642#define STATS_INC_TX_PACKETS(_pAd, _dev)
643
644#define STATS_INC_RX_BYTESS(_pAd, _dev, len)
645#define STATS_INC_TX_BYTESS(_pAd, _dev, len)
646
647#define STATS_INC_RX_ERRORS(_pAd, _dev)
648#define STATS_INC_TX_ERRORS(_pAd, _dev)
649
650#define STATS_INC_RX_DROPPED(_pAd, _dev)
651#define STATS_INC_TX_DROPPED(_pAd, _dev)
652
653
654#define CB_OFF 10
655
656
657// check DDK NDIS_PACKET data structure and find out only MiniportReservedEx[0..7] can be used by our driver without
658// ambiguity. Fields after pPacket->MiniportReservedEx[8] may be used by other wrapper layer thus crashes the driver
659//
660
661// User Priority
662#define RTMP_SET_PACKET_UP(_p, _prio) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio)
663#define RTMP_GET_PACKET_UP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0])
664
665// Fragment #
666#define RTMP_SET_PACKET_FRAGMENTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1] = _num)
667#define RTMP_GET_PACKET_FRAGMENTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1])
668
669// 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.
670//(this value also as MAC(on-chip WCID) table index)
671// 0x80~0xff: TX to a WDS link. b0~6: WDS index
672#define RTMP_SET_PACKET_WCID(_p, _wdsidx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2] = _wdsidx)
673#define RTMP_GET_PACKET_WCID(_p) ((UCHAR)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2]))
674
675// 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet
676#define RTMP_SET_PACKET_SOURCE(_p, _pktsrc) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3] = _pktsrc)
677#define RTMP_GET_PACKET_SOURCE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3])
678
679// RTS/CTS-to-self protection method
680#define RTMP_SET_PACKET_RTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4] = _num)
681#define RTMP_GET_PACKET_RTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4])
682// see RTMP_S(G)ET_PACKET_EMACTAB
683
684// TX rate index
685#define RTMP_SET_PACKET_TXRATE(_p, _rate) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5] = _rate)
686#define RTMP_GET_PACKET_TXRATE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5])
687
688// From which Interface
689#define RTMP_SET_PACKET_IF(_p, _ifdx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6] = _ifdx)
690#define RTMP_GET_PACKET_IF(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6])
691#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss) RTMP_SET_PACKET_IF((_p), (_bss))
692#define RTMP_SET_PACKET_NET_DEVICE_WDS(_p, _bss) RTMP_SET_PACKET_IF((_p), ((_bss) + MIN_NET_DEVICE_FOR_WDS))
693#define RTMP_SET_PACKET_NET_DEVICE_APCLI(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_APCLI))
694#define RTMP_SET_PACKET_NET_DEVICE_MESH(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_MESH))
695#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p) RTMP_GET_PACKET_IF((_p))
696#define RTMP_GET_PACKET_NET_DEVICE(_p) RTMP_GET_PACKET_IF((_p))
697
698#define RTMP_SET_PACKET_MOREDATA(_p, _morebit) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7] = _morebit)
699#define RTMP_GET_PACKET_MOREDATA(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7])
700
701
702#if 0
703//#define RTMP_SET_PACKET_DHCP(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg)
704//#define RTMP_GET_PACKET_DHCP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11])
705#else
706//
707// Sepcific Pakcet Type definition
708//
709#define RTMP_PACKET_SPECIFIC_CB_OFFSET 11
710
711#define RTMP_PACKET_SPECIFIC_DHCP 0x01
712#define RTMP_PACKET_SPECIFIC_EAPOL 0x02
713#define RTMP_PACKET_SPECIFIC_IPV4 0x04
714#define RTMP_PACKET_SPECIFIC_WAI 0x08
715#define RTMP_PACKET_SPECIFIC_VLAN 0x10
716#define RTMP_PACKET_SPECIFIC_LLCSNAP 0x20
717
718//Specific
719#define RTMP_SET_PACKET_SPECIFIC(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg)
720
721//DHCP
722#define RTMP_SET_PACKET_DHCP(_p, _flg) \
723 do{ \
724 if (_flg) \
725 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_DHCP); \
726 else \
727 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_DHCP); \
728 }while(0)
729#define RTMP_GET_PACKET_DHCP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_DHCP)
730
731//EAPOL
732#define RTMP_SET_PACKET_EAPOL(_p, _flg) \
733 do{ \
734 if (_flg) \
735 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_EAPOL); \
736 else \
737 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_EAPOL); \
738 }while(0)
739#define RTMP_GET_PACKET_EAPOL(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_EAPOL)
740
741//WAI
742#define RTMP_SET_PACKET_WAI(_p, _flg) \
743 do{ \
744 if (_flg) \
745 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_WAI); \
746 else \
747 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_WAI); \
748 }while(0)
749#define RTMP_GET_PACKET_WAI(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_WAI)
750
751#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))
752
753//VLAN
754#define RTMP_SET_PACKET_VLAN(_p, _flg) \
755 do{ \
756 if (_flg) \
757 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_VLAN); \
758 else \
759 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_VLAN); \
760 }while(0)
761#define RTMP_GET_PACKET_VLAN(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_VLAN)
762
763//LLC/SNAP
764#define RTMP_SET_PACKET_LLCSNAP(_p, _flg) \
765 do{ \
766 if (_flg) \
767 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_LLCSNAP); \
768 else \
769 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_LLCSNAP); \
770 }while(0)
771
772#define RTMP_GET_PACKET_LLCSNAP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_LLCSNAP)
773
774// IP
775#define RTMP_SET_PACKET_IPV4(_p, _flg) \
776 do{ \
777 if (_flg) \
778 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_IPV4); \
779 else \
780 (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_IPV4); \
781 }while(0)
782
783#define RTMP_GET_PACKET_IPV4(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_IPV4)
784
785#endif
786
787
788// If this flag is set, it indicates that this EAPoL frame MUST be clear.
789#define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg)
790#define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12])
791
792#define RTMP_SET_PACKET_5VT(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg)
793#define RTMP_GET_PACKET_5VT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22])
794
795#ifdef CONFIG_5VT_ENHANCE
796#define BRIDGE_TAG 0x35564252 // depends on 5VT define in br_input.c
797#endif
798
799
800#define NDIS_SET_PACKET_STATUS(_p, _status)
801
802
803#define GET_SG_LIST_FROM_PACKET(_p, _sc) \
804 rt_get_sg_list_from_packet(_p, _sc)
805
806#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
807#define NdisZeroMemory(Destination, Length) memset(Destination, 0, Length)
808#define NdisFillMemory(Destination, Length, Fill) memset(Destination, Fill, Length)
809#define NdisEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length))
810#define RTMPEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length))
811
812
813#define RTMP_INC_REF(_A) 0
814#define RTMP_DEC_REF(_A) 0
815#define RTMP_GET_REF(_A) 0
816
817
818
819/*
820 * ULONG
821 * RTMP_GetPhysicalAddressLow(
822 * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);
823 */
824#define RTMP_GetPhysicalAddressLow(PhysicalAddress) (PhysicalAddress)
825
826/*
827 * ULONG
828 * RTMP_GetPhysicalAddressHigh(
829 * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);
830 */
831#define RTMP_GetPhysicalAddressHigh(PhysicalAddress) (0)
832
833/*
834 * VOID
835 * RTMP_SetPhysicalAddressLow(
836 * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
837 * IN ULONG Value);
838 */
839#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value) \
840 PhysicalAddress = Value;
841
842/*
843 * VOID
844 * RTMP_SetPhysicalAddressHigh(
845 * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
846 * IN ULONG Value);
847 */
848#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value)
849
850
851//CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
852#define QUEUE_ENTRY_TO_PACKET(pEntry) \
853 (PNDIS_PACKET)(pEntry)
854
855#define PACKET_TO_QUEUE_ENTRY(pPacket) \
856 (PQUEUE_ENTRY)(pPacket)
857
858
859#ifndef CONTAINING_RECORD
860#define CONTAINING_RECORD(address, type, field) \
861((type *)((PCHAR)(address) - offsetof(type, field)))
862#endif
863
864
865#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status) \
866{ \
867 RTMPFreeNdisPacket(_pAd, _pPacket); \
868}
869
870
871#define SWITCH_PhyAB(_pAA, _pBB) \
872{ \
873 ULONG AABasePaHigh; \
874 ULONG AABasePaLow; \
875 ULONG BBBasePaHigh; \
876 ULONG BBBasePaLow; \
877 BBBasePaHigh = RTMP_GetPhysicalAddressHigh(_pBB); \
878 BBBasePaLow = RTMP_GetPhysicalAddressLow(_pBB); \
879 AABasePaHigh = RTMP_GetPhysicalAddressHigh(_pAA); \
880 AABasePaLow = RTMP_GetPhysicalAddressLow(_pAA); \
881 RTMP_SetPhysicalAddressHigh(_pAA, BBBasePaHigh); \
882 RTMP_SetPhysicalAddressLow(_pAA, BBBasePaLow); \
883 RTMP_SetPhysicalAddressHigh(_pBB, AABasePaHigh); \
884 RTMP_SetPhysicalAddressLow(_pBB, AABasePaLow); \
885}
886
887
888#define NdisWriteErrorLogEntry(_a, _b, _c, _d)
889#define NdisMAllocateMapRegisters(_a, _b, _c, _d, _e) NDIS_STATUS_SUCCESS
890
891
892#define NdisAcquireSpinLock RTMP_SEM_LOCK
893#define NdisReleaseSpinLock RTMP_SEM_UNLOCK
894
895static inline void NdisGetSystemUpTime(ULONG *time)
896{
897 *time = jiffies;
898}
899
900//pPacket = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
901#define QUEUE_ENTRY_TO_PKT(pEntry) \
902 ((PNDIS_PACKET) (pEntry))
903
904int rt28xx_packet_xmit(struct sk_buff *skb);
905
906
907
908void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify);
909
910#ifdef RT2860
911#if !defined(PCI_CAP_ID_EXP)
912#define PCI_CAP_ID_EXP 0x10
913#endif
914
915#if !defined(PCI_EXP_LNKCTL)
916#define PCI_EXP_LNKCTL 0x10
917#endif
918
919#if !defined(PCI_CLASS_BRIDGE_PCI)
920#define PCI_CLASS_BRIDGE_PCI 0x0604
921#endif
922
923#define PCIBUS_INTEL_VENDOR 0x8086
924#endif // RT2860 //
925
926
diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c
new file mode 100644
index 00000000000..98d1bbb003e
--- /dev/null
+++ b/drivers/staging/rt2860/rt_main_dev.c
@@ -0,0 +1,1686 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rt_main_dev.c
29
30 Abstract:
31 Create and register network interface.
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Sample Mar/21/07 Merge RT2870 and RT2860 drivers.
37*/
38
39#include "rt_config.h"
40
41#define FORTY_MHZ_INTOLERANT_INTERVAL (60*1000) // 1 min
42
43#ifdef MULTIPLE_CARD_SUPPORT
44// record whether the card in the card list is used in the card file
45UINT8 MC_CardUsed[MAX_NUM_OF_MULTIPLE_CARD];
46// record used card mac address in the card list
47static UINT8 MC_CardMac[MAX_NUM_OF_MULTIPLE_CARD][6];
48#endif // MULTIPLE_CARD_SUPPORT //
49
50#ifdef CONFIG_APSTA_MIXED_SUPPORT
51UINT32 CW_MAX_IN_BITS;
52#endif // CONFIG_APSTA_MIXED_SUPPORT //
53
54/*---------------------------------------------------------------------*/
55/* Private Variables Used */
56/*---------------------------------------------------------------------*/
57//static RALINK_TIMER_STRUCT PeriodicTimer;
58
59char *mac = ""; // default 00:00:00:00:00:00
60char *hostname = ""; // default CMPC
61#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
62MODULE_PARM (mac, "s");
63#else
64module_param (mac, charp, 0);
65#endif
66MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
67
68
69/*---------------------------------------------------------------------*/
70/* Prototypes of Functions Used */
71/*---------------------------------------------------------------------*/
72#ifdef DOT11_N_SUPPORT
73extern BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
74extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
75#endif // DOT11_N_SUPPORT //
76extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd);
77
78#ifdef RT2860
79extern void init_thread_task(PRTMP_ADAPTER pAd);
80#endif // RT2860 //
81
82// public function prototype
83INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
84 IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
85
86// private function prototype
87static int rt28xx_init(IN struct net_device *net_dev);
88INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
89
90#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
91struct net_device *alloc_netdev(
92 int sizeof_priv,
93 const char *mask,
94 void (*setup)(struct net_device *));
95#endif // LINUX_VERSION_CODE //
96
97static void CfgInitHook(PRTMP_ADAPTER pAd);
98
99#ifdef CONFIG_STA_SUPPORT
100extern const struct iw_handler_def rt28xx_iw_handler_def;
101#endif // CONFIG_STA_SUPPORT //
102
103#ifdef CONFIG_APSTA_MIXED_SUPPORT
104extern const struct iw_handler_def rt28xx_ap_iw_handler_def;
105#endif // CONFIG_APSTA_MIXED_SUPPORT //
106
107#if WIRELESS_EXT >= 12
108// This function will be called when query /proc
109struct iw_statistics *rt28xx_get_wireless_stats(
110 IN struct net_device *net_dev);
111#endif
112
113struct net_device_stats *RT28xx_get_ether_stats(
114 IN struct net_device *net_dev);
115
116/*
117========================================================================
118Routine Description:
119 Close raxx interface.
120
121Arguments:
122 *net_dev the raxx interface pointer
123
124Return Value:
125 0 Open OK
126 otherwise Open Fail
127
128Note:
129 1. if open fail, kernel will not call the close function.
130 2. Free memory for
131 (1) Mlme Memory Handler: MlmeHalt()
132 (2) TX & RX: RTMPFreeTxRxRingMemory()
133 (3) BA Reordering: ba_reordering_resource_release()
134========================================================================
135*/
136int MainVirtualIF_close(IN struct net_device *net_dev)
137{
138 RTMP_ADAPTER *pAd = net_dev->priv;
139
140 // Sanity check for pAd
141 if (pAd == NULL)
142 return 0; // close ok
143
144 netif_carrier_off(pAd->net_dev);
145 netif_stop_queue(pAd->net_dev);
146
147
148 VIRTUAL_IF_DOWN(pAd);
149
150 RT_MOD_DEC_USE_COUNT();
151
152 return 0; // close ok
153}
154
155/*
156========================================================================
157Routine Description:
158 Open raxx interface.
159
160Arguments:
161 *net_dev the raxx interface pointer
162
163Return Value:
164 0 Open OK
165 otherwise Open Fail
166
167Note:
168 1. if open fail, kernel will not call the close function.
169 2. Free memory for
170 (1) Mlme Memory Handler: MlmeHalt()
171 (2) TX & RX: RTMPFreeTxRxRingMemory()
172 (3) BA Reordering: ba_reordering_resource_release()
173========================================================================
174*/
175int MainVirtualIF_open(IN struct net_device *net_dev)
176{
177 RTMP_ADAPTER *pAd = net_dev->priv;
178
179 // Sanity check for pAd
180 if (pAd == NULL)
181 return 0; // close ok
182
183 if (VIRTUAL_IF_UP(pAd) != 0)
184 return -1;
185
186 // increase MODULE use count
187 RT_MOD_INC_USE_COUNT();
188
189 netif_start_queue(net_dev);
190 netif_carrier_on(net_dev);
191 netif_wake_queue(net_dev);
192
193 return 0;
194}
195
196/*
197========================================================================
198Routine Description:
199 Close raxx interface.
200
201Arguments:
202 *net_dev the raxx interface pointer
203
204Return Value:
205 0 Open OK
206 otherwise Open Fail
207
208Note:
209 1. if open fail, kernel will not call the close function.
210 2. Free memory for
211 (1) Mlme Memory Handler: MlmeHalt()
212 (2) TX & RX: RTMPFreeTxRxRingMemory()
213 (3) BA Reordering: ba_reordering_resource_release()
214========================================================================
215*/
216int rt28xx_close(IN PNET_DEV dev)
217{
218 struct net_device * net_dev = (struct net_device *)dev;
219 RTMP_ADAPTER *pAd = net_dev->priv;
220 BOOLEAN Cancelled = FALSE;
221 UINT32 i = 0;
222
223
224 DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
225
226 // Sanity check for pAd
227 if (pAd == NULL)
228 return 0; // close ok
229
230
231#ifdef WDS_SUPPORT
232 WdsDown(pAd);
233#endif // WDS_SUPPORT //
234
235#ifdef CONFIG_STA_SUPPORT
236 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
237 {
238#ifdef RT2860
239 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
240#endif // RT2860 //
241
242 // If dirver doesn't wake up firmware here,
243 // NICLoadFirmware will hang forever when interface is up again.
244 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
245 {
246 AsicForceWakeup(pAd, TRUE);
247 }
248
249#ifdef QOS_DLS_SUPPORT
250 // send DLS-TEAR_DOWN message,
251 if (pAd->CommonCfg.bDLSCapable)
252 {
253 UCHAR i;
254
255 // tear down local dls table entry
256 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
257 {
258 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
259 {
260 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
261 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
262 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
263 }
264 }
265
266 // tear down peer dls table entry
267 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
268 {
269 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
270 {
271 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
272 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
273 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
274 }
275 }
276 RT28XX_MLME_HANDLER(pAd);
277 }
278#endif // QOS_DLS_SUPPORT //
279
280 if (INFRA_ON(pAd) &&
281 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
282 {
283 MLME_DISASSOC_REQ_STRUCT DisReq;
284 MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
285
286 COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
287 DisReq.Reason = REASON_DEAUTH_STA_LEAVING;
288
289 MsgElem->Machine = ASSOC_STATE_MACHINE;
290 MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
291 MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
292 NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
293
294 // Prevent to connect AP again in STAMlmePeriodicExec
295 pAd->MlmeAux.AutoReconnectSsidLen= 32;
296 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
297
298 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
299 MlmeDisassocReqAction(pAd, MsgElem);
300 kfree(MsgElem);
301
302 RTMPusecDelay(1000);
303 }
304
305
306#ifdef CCX_SUPPORT
307 RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &Cancelled);
308#endif
309
310 RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
311 RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
312
313#ifdef WPA_SUPPLICANT_SUPPORT
314#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
315 {
316 union iwreq_data wrqu;
317 // send wireless event to wpa_supplicant for infroming interface down.
318 memset(&wrqu, 0, sizeof(wrqu));
319 wrqu.data.flags = RT_INTERFACE_DOWN;
320 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
321 }
322#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
323#endif // WPA_SUPPLICANT_SUPPORT //
324
325 MlmeRadioOff(pAd);
326#ifdef RT2860
327 pAd->bPCIclkOff = FALSE;
328#endif // RT2860 //
329 }
330#endif // CONFIG_STA_SUPPORT //
331
332 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
333
334 for (i = 0 ; i < NUM_OF_TX_RING; i++)
335 {
336 while (pAd->DeQueueRunning[i] == TRUE)
337 {
338 printk("Waiting for TxQueue[%d] done..........\n", i);
339 RTMPusecDelay(1000);
340 }
341 }
342
343 // Stop Mlme state machine
344 MlmeHalt(pAd);
345
346 // Close kernel threads or tasklets
347 kill_thread_task(pAd);
348
349
350#ifdef CONFIG_STA_SUPPORT
351 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
352 {
353 MacTableReset(pAd);
354 }
355#endif // CONFIG_STA_SUPPORT //
356
357
358 MeasureReqTabExit(pAd);
359 TpcReqTabExit(pAd);
360
361
362#ifdef RT2860
363 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
364 {
365 NICDisableInterrupt(pAd);
366 }
367
368 // Disable Rx, register value supposed will remain after reset
369 NICIssueReset(pAd);
370
371 // Free IRQ
372 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
373 {
374 // Deregister interrupt function
375 RT28XX_IRQ_RELEASE(net_dev)
376 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
377 }
378#endif // RT2860 //
379
380
381 // Free Ring or USB buffers
382 RTMPFreeTxRxRingMemory(pAd);
383
384 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
385
386#ifdef DOT11_N_SUPPORT
387 // Free BA reorder resource
388 ba_reordering_resource_release(pAd);
389#endif // DOT11_N_SUPPORT //
390
391
392 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
393
394 return 0; // close ok
395} /* End of rt28xx_close */
396
397static int rt28xx_init(IN struct net_device *net_dev)
398{
399 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)net_dev->priv;
400 UINT index;
401 UCHAR TmpPhy;
402 NDIS_STATUS Status;
403 UINT32 MacCsr0 = 0;
404
405
406#ifdef DOT11_N_SUPPORT
407 // Allocate BA Reordering memory
408 ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
409#endif // DOT11_N_SUPPORT //
410
411 // Make sure MAC gets ready.
412 index = 0;
413 do
414 {
415 RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
416 pAd->MACVersion = MacCsr0;
417
418 if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
419 break;
420
421 RTMPusecDelay(10);
422 } while (index++ < 100);
423
424 DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
425
426 // Disable DMA
427 RT28XXDMADisable(pAd);
428
429
430 // Load 8051 firmware
431 Status = NICLoadFirmware(pAd);
432 if (Status != NDIS_STATUS_SUCCESS)
433 {
434 DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
435 goto err1;
436 }
437
438 NICLoadRateSwitchingParams(pAd);
439
440 // Disable interrupts here which is as soon as possible
441 // This statement should never be true. We might consider to remove it later
442#ifdef RT2860
443 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
444 {
445 NICDisableInterrupt(pAd);
446 }
447#endif // RT2860 //
448
449 Status = RTMPAllocTxRxRingMemory(pAd);
450 if (Status != NDIS_STATUS_SUCCESS)
451 {
452 DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status));
453 goto err1;
454 }
455
456 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
457
458 // initialize MLME
459 //
460
461 Status = MlmeInit(pAd);
462 if (Status != NDIS_STATUS_SUCCESS)
463 {
464 DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
465 goto err2;
466 }
467
468 // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default
469 //
470 UserCfgInit(pAd);
471
472
473 RT28XX_TASK_THREAD_INIT(pAd, Status);
474 if (Status != NDIS_STATUS_SUCCESS)
475 goto err1;
476
477 CfgInitHook(pAd);
478
479
480#ifdef BLOCK_NET_IF
481 initblockQueueTab(pAd);
482#endif // BLOCK_NET_IF //
483
484#ifdef CONFIG_STA_SUPPORT
485 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
486 NdisAllocateSpinLock(&pAd->MacTabLock);
487#endif // CONFIG_STA_SUPPORT //
488
489 MeasureReqTabInit(pAd);
490 TpcReqTabInit(pAd);
491
492 //
493 // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset
494 //
495 Status = NICInitializeAdapter(pAd, TRUE);
496 if (Status != NDIS_STATUS_SUCCESS)
497 {
498 DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status));
499 if (Status != NDIS_STATUS_SUCCESS)
500 goto err3;
501 }
502
503 // Read parameters from Config File
504 Status = RTMPReadParametersHook(pAd);
505
506 printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
507 if (Status != NDIS_STATUS_SUCCESS)
508 {
509 DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status));
510 goto err4;
511 }
512
513
514
515 //Init Ba Capability parameters.
516#ifdef DOT11_N_SUPPORT
517 pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
518 pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
519 pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
520 pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
521 // UPdata to HT IE
522 pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
523 pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
524 pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
525#endif // DOT11_N_SUPPORT //
526
527 printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
528
529 // We should read EEPROM for all cases. rt2860b
530 NICReadEEPROMParameters(pAd, mac);
531
532 printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
533
534 NICInitAsicFromEEPROM(pAd); //rt2860b
535
536 // Set PHY to appropriate mode
537 TmpPhy = pAd->CommonCfg.PhyMode;
538 pAd->CommonCfg.PhyMode = 0xff;
539 RTMPSetPhyMode(pAd, TmpPhy);
540#ifdef DOT11_N_SUPPORT
541 SetCommonHT(pAd);
542#endif // DOT11_N_SUPPORT //
543
544 // No valid channels.
545 if (pAd->ChannelListNum == 0)
546 {
547 printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n");
548 goto err4;
549 }
550
551#ifdef DOT11_N_SUPPORT
552 printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0],
553 pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2],
554 pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]);
555#endif // DOT11_N_SUPPORT //
556
557#ifdef IKANOS_VX_1X0
558 VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress);
559#endif // IKANOS_VX_1X0 //
560
561 //
562 // Initialize RF register to default value
563 //
564 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
565 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
566
567 // 8051 firmware require the signal during booting time.
568 AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00);
569
570 if (pAd && (Status != NDIS_STATUS_SUCCESS))
571 {
572 //
573 // Undo everything if it failed
574 //
575 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
576 {
577 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
578 }
579 }
580 else if (pAd)
581 {
582 // Microsoft HCT require driver send a disconnect event after driver initialization.
583 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
584 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
585 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
586
587
588 }// end of else
589
590
591 DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status));
592
593 return TRUE;
594
595
596err4:
597err3:
598 MlmeHalt(pAd);
599err2:
600 RTMPFreeTxRxRingMemory(pAd);
601err1:
602
603#ifdef DOT11_N_SUPPORT
604 os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool
605#endif // DOT11_N_SUPPORT //
606 RT28XX_IRQ_RELEASE(net_dev);
607
608 // shall not set priv to NULL here because the priv didn't been free yet.
609 //net_dev->priv = 0;
610#ifdef INF_AMAZON_SE
611err0:
612#endif // INF_AMAZON_SE //
613 printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME);
614 return FALSE;
615} /* End of rt28xx_init */
616
617
618/*
619========================================================================
620Routine Description:
621 Open raxx interface.
622
623Arguments:
624 *net_dev the raxx interface pointer
625
626Return Value:
627 0 Open OK
628 otherwise Open Fail
629
630Note:
631========================================================================
632*/
633int rt28xx_open(IN PNET_DEV dev)
634{
635 struct net_device * net_dev = (struct net_device *)dev;
636 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)net_dev->priv;
637 int retval = 0;
638 POS_COOKIE pObj;
639
640
641 // Sanity check for pAd
642 if (pAd == NULL)
643 {
644 /* if 1st open fail, pAd will be free;
645 So the net_dev->priv will be NULL in 2rd open */
646 return -1;
647 }
648
649#ifdef CONFIG_APSTA_MIXED_SUPPORT
650 if (pAd->OpMode == OPMODE_AP)
651 {
652 CW_MAX_IN_BITS = 6;
653 }
654 else if (pAd->OpMode == OPMODE_STA)
655 {
656 CW_MAX_IN_BITS = 10;
657 }
658
659#if WIRELESS_EXT >= 12
660 if (net_dev->priv_flags == INT_MAIN)
661 {
662 if (pAd->OpMode == OPMODE_AP)
663 net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def;
664 else if (pAd->OpMode == OPMODE_STA)
665 net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def;
666 }
667#endif // WIRELESS_EXT >= 12 //
668#endif // CONFIG_APSTA_MIXED_SUPPORT //
669
670#ifdef CONFIG_STA_SUPPORT
671#ifdef RT2860
672 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
673 {
674 // If dirver doesn't wake up firmware here,
675 // NICLoadFirmware will hang forever when interface is up again.
676 // RT2860 PCI
677 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) &&
678 OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
679 {
680 AUTO_WAKEUP_STRUC AutoWakeupCfg;
681 AsicForceWakeup(pAd, TRUE);
682 AutoWakeupCfg.word = 0;
683 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
684 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
685 }
686 }
687#endif // RT2860 //
688#endif // CONFIG_STA_SUPPORT //
689
690 // Init
691 pObj = (POS_COOKIE)pAd->OS_Cookie;
692
693 // reset Adapter flags
694 RTMP_CLEAR_FLAGS(pAd);
695
696 // Request interrupt service routine for PCI device
697 // register the interrupt routine with the os
698 RT28XX_IRQ_REQUEST(net_dev);
699
700
701 // Init BssTab & ChannelInfo tabbles for auto channel select.
702
703
704 // Chip & other init
705 if (rt28xx_init(net_dev) == FALSE)
706 goto err;
707
708#ifdef CONFIG_STA_SUPPORT
709 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
710 {
711 NdisZeroMemory(pAd->StaCfg.dev_name, 16);
712 NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
713 }
714#endif // CONFIG_STA_SUPPORT //
715
716 // Set up the Mac address
717 NdisMoveMemory(net_dev->dev_addr, (void *) pAd->CurrentAddress, 6);
718
719 // Init IRQ parameters
720 RT28XX_IRQ_INIT(pAd);
721
722 // Various AP function init
723
724#ifdef CONFIG_STA_SUPPORT
725 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
726 {
727#ifdef WPA_SUPPLICANT_SUPPORT
728#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
729 {
730 union iwreq_data wrqu;
731 // send wireless event to wpa_supplicant for infroming interface down.
732 memset(&wrqu, 0, sizeof(wrqu));
733 wrqu.data.flags = RT_INTERFACE_UP;
734 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
735 }
736#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
737#endif // WPA_SUPPLICANT_SUPPORT //
738
739 }
740#endif // CONFIG_STA_SUPPORT //
741
742 // Enable Interrupt
743 RT28XX_IRQ_ENABLE(pAd);
744
745 // Now Enable RxTx
746 RTMPEnableRxTx(pAd);
747 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
748
749 {
750 UINT32 reg = 0;
751 RTMP_IO_READ32(pAd, 0x1300, &reg); // clear garbage interrupts
752 printk("0x1300 = %08x\n", reg);
753 }
754
755#ifdef CONFIG_STA_SUPPORT
756#ifdef RT2860
757 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
758 RTMPInitPCIeLinkCtrlValue(pAd);
759#endif // RT2860 //
760#endif // CONFIG_STA_SUPPORT //
761
762 return (retval);
763
764err:
765 return (-1);
766} /* End of rt28xx_open */
767
768
769/* Must not be called for mdev and apdev */
770static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd)
771{
772 NDIS_STATUS Status;
773 INT i=0;
774 CHAR slot_name[IFNAMSIZ];
775 struct net_device *device;
776
777
778 //ether_setup(dev);
779 dev->hard_start_xmit = rt28xx_send_packets;
780
781#ifdef IKANOS_VX_1X0
782 dev->hard_start_xmit = IKANOS_DataFramesTx;
783#endif // IKANOS_VX_1X0 //
784
785#ifdef CONFIG_STA_SUPPORT
786#if WIRELESS_EXT >= 12
787 if (pAd->OpMode == OPMODE_STA)
788 {
789 dev->wireless_handlers = &rt28xx_iw_handler_def;
790 }
791#endif //WIRELESS_EXT >= 12
792#endif // CONFIG_STA_SUPPORT //
793
794#ifdef CONFIG_APSTA_MIXED_SUPPORT
795#if WIRELESS_EXT >= 12
796 if (pAd->OpMode == OPMODE_AP)
797 {
798 dev->wireless_handlers = &rt28xx_ap_iw_handler_def;
799 }
800#endif //WIRELESS_EXT >= 12
801#endif // CONFIG_APSTA_MIXED_SUPPORT //
802
803#if WIRELESS_EXT < 21
804 dev->get_wireless_stats = rt28xx_get_wireless_stats;
805#endif
806 dev->get_stats = RT28xx_get_ether_stats;
807 dev->open = MainVirtualIF_open; //rt28xx_open;
808 dev->stop = MainVirtualIF_close; //rt28xx_close;
809 dev->priv_flags = INT_MAIN;
810 dev->do_ioctl = rt28xx_ioctl;
811#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
812 dev->validate_addr = NULL;
813#endif
814 // find available device name
815 for (i = 0; i < 8; i++)
816 {
817#ifdef MULTIPLE_CARD_SUPPORT
818 if (pAd->MC_RowID >= 0)
819 sprintf(slot_name, "ra%02d_%d", pAd->MC_RowID, i);
820 else
821#endif // MULTIPLE_CARD_SUPPORT //
822 sprintf(slot_name, "ra%d", i);
823
824#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
825#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
826#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
827 device = dev_get_by_name(dev_net(dev), slot_name);
828#else
829 device = dev_get_by_name(dev->nd_net, slot_name);
830#endif
831#else
832 device = dev_get_by_name(slot_name);
833#endif
834 if (device != NULL) dev_put(device);
835#else
836 for (device = dev_base; device != NULL; device = device->next)
837 {
838 if (strncmp(device->name, slot_name, 4) == 0)
839 break;
840 }
841#endif
842 if(device == NULL)
843 break;
844 }
845
846 if(i == 8)
847 {
848 DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n"));
849 Status = NDIS_STATUS_FAILURE;
850 }
851 else
852 {
853#ifdef MULTIPLE_CARD_SUPPORT
854 if (pAd->MC_RowID >= 0)
855 sprintf(dev->name, "ra%02d_%d", pAd->MC_RowID, i);
856 else
857#endif // MULTIPLE_CARD_SUPPORT //
858 sprintf(dev->name, "ra%d", i);
859 Status = NDIS_STATUS_SUCCESS;
860 }
861
862 return Status;
863
864}
865
866
867#ifdef MULTIPLE_CARD_SUPPORT
868/*
869========================================================================
870Routine Description:
871 Get card profile path.
872
873Arguments:
874 pAd
875
876Return Value:
877 TRUE - Find a card profile
878 FALSE - use default profile
879
880Note:
881========================================================================
882*/
883extern INT RTMPGetKeyParameter(
884 IN PCHAR key,
885 OUT PCHAR dest,
886 IN INT destsize,
887 IN PCHAR buffer);
888
889BOOLEAN RTMP_CardInfoRead(
890 IN PRTMP_ADAPTER pAd)
891{
892#define MC_SELECT_CARDID 0 /* use CARD ID (0 ~ 31) to identify different cards */
893#define MC_SELECT_MAC 1 /* use CARD MAC to identify different cards */
894#define MC_SELECT_CARDTYPE 2 /* use CARD type (abgn or bgn) to identify different cards */
895
896#define LETTER_CASE_TRANSLATE(txt_p, card_id) \
897 { UINT32 _len; char _char; \
898 for(_len=0; _len<strlen(card_id); _len++) { \
899 _char = *(txt_p + _len); \
900 if (('A' <= _char) && (_char <= 'Z')) \
901 *(txt_p+_len) = 'a'+(_char-'A'); \
902 } }
903
904 struct file *srcf;
905 INT retval, orgfsuid, orgfsgid;
906 mm_segment_t orgfs;
907 CHAR *buffer, *tmpbuf, card_id_buf[30], RFIC_word[30];
908 BOOLEAN flg_match_ok = FALSE;
909 INT32 card_select_method;
910 INT32 card_free_id, card_nouse_id, card_same_mac_id, card_match_id;
911 EEPROM_ANTENNA_STRUC antenna;
912 USHORT addr01, addr23, addr45;
913 UINT8 mac[6];
914 UINT32 data, card_index;
915 UCHAR *start_ptr;
916
917
918 // init
919 buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
920 if (buffer == NULL)
921 return FALSE;
922
923 tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
924 if(tmpbuf == NULL)
925 {
926 kfree(buffer);
927 return NDIS_STATUS_FAILURE;
928 }
929
930 orgfsuid = current->fsuid;
931 orgfsgid = current->fsgid;
932 current->fsuid = current->fsgid = 0;
933 orgfs = get_fs();
934 set_fs(KERNEL_DS);
935
936 // get RF IC type
937 RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
938
939 if ((data & 0x30) == 0)
940 pAd->EEPROMAddressNum = 6; // 93C46
941 else if ((data & 0x30) == 0x10)
942 pAd->EEPROMAddressNum = 8; // 93C66
943 else
944 pAd->EEPROMAddressNum = 8; // 93C86
945
946 RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, antenna.word);
947
948 if ((antenna.field.RfIcType == RFIC_2850) ||
949 (antenna.field.RfIcType == RFIC_2750))
950 {
951 /* ABGN card */
952 strcpy(RFIC_word, "abgn");
953 }
954 else
955 {
956 /* BGN card */
957 strcpy(RFIC_word, "bgn");
958 }
959
960 // get MAC address
961 RT28xx_EEPROM_READ16(pAd, 0x04, addr01);
962 RT28xx_EEPROM_READ16(pAd, 0x06, addr23);
963 RT28xx_EEPROM_READ16(pAd, 0x08, addr45);
964
965 mac[0] = (UCHAR)(addr01 & 0xff);
966 mac[1] = (UCHAR)(addr01 >> 8);
967 mac[2] = (UCHAR)(addr23 & 0xff);
968 mac[3] = (UCHAR)(addr23 >> 8);
969 mac[4] = (UCHAR)(addr45 & 0xff);
970 mac[5] = (UCHAR)(addr45 >> 8);
971
972 // open card information file
973 srcf = filp_open(CARD_INFO_PATH, O_RDONLY, 0);
974 if (IS_ERR(srcf))
975 {
976 /* card information file does not exist */
977 DBGPRINT(RT_DEBUG_TRACE,
978 ("--> Error %ld opening %s\n", -PTR_ERR(srcf), CARD_INFO_PATH));
979 return FALSE;
980 }
981
982 if (srcf->f_op && srcf->f_op->read)
983 {
984 /* card information file exists so reading the card information */
985 memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
986 retval = srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
987 if (retval < 0)
988 {
989 /* read fail */
990 DBGPRINT(RT_DEBUG_TRACE,
991 ("--> Read %s error %d\n", CARD_INFO_PATH, -retval));
992 }
993 else
994 {
995 /* get card selection method */
996 memset(tmpbuf, 0x00, MAX_PARAM_BUFFER_SIZE);
997 card_select_method = MC_SELECT_CARDTYPE; // default
998
999 if (RTMPGetKeyParameter("SELECT", tmpbuf, 256, buffer))
1000 {
1001 if (strcmp(tmpbuf, "CARDID") == 0)
1002 card_select_method = MC_SELECT_CARDID;
1003 else if (strcmp(tmpbuf, "MAC") == 0)
1004 card_select_method = MC_SELECT_MAC;
1005 else if (strcmp(tmpbuf, "CARDTYPE") == 0)
1006 card_select_method = MC_SELECT_CARDTYPE;
1007 }
1008
1009 DBGPRINT(RT_DEBUG_TRACE,
1010 ("MC> Card Selection = %d\n", card_select_method));
1011
1012 // init
1013 card_free_id = -1;
1014 card_nouse_id = -1;
1015 card_same_mac_id = -1;
1016 card_match_id = -1;
1017
1018 // search current card information records
1019 for(card_index=0;
1020 card_index<MAX_NUM_OF_MULTIPLE_CARD;
1021 card_index++)
1022 {
1023 if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
1024 (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
1025 {
1026 // MAC is all-0 so the entry is available
1027 MC_CardUsed[card_index] = 0;
1028
1029 if (card_free_id < 0)
1030 card_free_id = card_index; // 1st free entry
1031 }
1032 else
1033 {
1034 if (memcmp(MC_CardMac[card_index], mac, 6) == 0)
1035 {
1036 // we find the entry with same MAC
1037 if (card_same_mac_id < 0)
1038 card_same_mac_id = card_index; // 1st same entry
1039 }
1040 else
1041 {
1042 // MAC is not all-0 but used flag == 0
1043 if ((MC_CardUsed[card_index] == 0) &&
1044 (card_nouse_id < 0))
1045 {
1046 card_nouse_id = card_index; // 1st available entry
1047 }
1048 }
1049 }
1050 }
1051
1052 DBGPRINT(RT_DEBUG_TRACE,
1053 ("MC> Free = %d, Same = %d, NOUSE = %d\n",
1054 card_free_id, card_same_mac_id, card_nouse_id));
1055
1056 if ((card_same_mac_id >= 0) &&
1057 ((card_select_method == MC_SELECT_CARDID) ||
1058 (card_select_method == MC_SELECT_CARDTYPE)))
1059 {
1060 // same MAC entry is found
1061 card_match_id = card_same_mac_id;
1062
1063 if (card_select_method == MC_SELECT_CARDTYPE)
1064 {
1065 // for CARDTYPE
1066 sprintf(card_id_buf, "%02dCARDTYPE%s",
1067 card_match_id, RFIC_word);
1068
1069 if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
1070 {
1071 // we found the card ID
1072 LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
1073 }
1074 }
1075 }
1076 else
1077 {
1078 // the card is 1st plug-in, try to find the match card profile
1079 switch(card_select_method)
1080 {
1081 case MC_SELECT_CARDID: // CARDID
1082 default:
1083 if (card_free_id >= 0)
1084 card_match_id = card_free_id;
1085 else
1086 card_match_id = card_nouse_id;
1087 break;
1088
1089 case MC_SELECT_MAC: // MAC
1090 sprintf(card_id_buf, "MAC%02x:%02x:%02x:%02x:%02x:%02x",
1091 mac[0], mac[1], mac[2],
1092 mac[3], mac[4], mac[5]);
1093
1094 /* try to find the key word in the card file */
1095 if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
1096 {
1097 LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
1098
1099 /* get the row ID (2 ASCII characters) */
1100 start_ptr -= 2;
1101 card_id_buf[0] = *(start_ptr);
1102 card_id_buf[1] = *(start_ptr+1);
1103 card_id_buf[2] = 0x00;
1104
1105 card_match_id = simple_strtol(card_id_buf, 0, 10);
1106 }
1107 break;
1108
1109 case MC_SELECT_CARDTYPE: // CARDTYPE
1110 card_nouse_id = -1;
1111
1112 for(card_index=0;
1113 card_index<MAX_NUM_OF_MULTIPLE_CARD;
1114 card_index++)
1115 {
1116 sprintf(card_id_buf, "%02dCARDTYPE%s",
1117 card_index, RFIC_word);
1118
1119 if ((start_ptr=rtstrstruncasecmp(buffer,
1120 card_id_buf)) != NULL)
1121 {
1122 LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
1123
1124 if (MC_CardUsed[card_index] == 0)
1125 {
1126 /* current the card profile is not used */
1127 if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
1128 (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
1129 {
1130 // find it and no previous card use it
1131 card_match_id = card_index;
1132 break;
1133 }
1134 else
1135 {
1136 // ever a card use it
1137 if (card_nouse_id < 0)
1138 card_nouse_id = card_index;
1139 }
1140 }
1141 }
1142 }
1143
1144 // if not find a free one, use the available one
1145 if (card_match_id < 0)
1146 card_match_id = card_nouse_id;
1147 break;
1148 }
1149 }
1150
1151 if (card_match_id >= 0)
1152 {
1153 // make up search keyword
1154 switch(card_select_method)
1155 {
1156 case MC_SELECT_CARDID: // CARDID
1157 sprintf(card_id_buf, "%02dCARDID", card_match_id);
1158 break;
1159
1160 case MC_SELECT_MAC: // MAC
1161 sprintf(card_id_buf,
1162 "%02dmac%02x:%02x:%02x:%02x:%02x:%02x",
1163 card_match_id,
1164 mac[0], mac[1], mac[2],
1165 mac[3], mac[4], mac[5]);
1166 break;
1167
1168 case MC_SELECT_CARDTYPE: // CARDTYPE
1169 default:
1170 sprintf(card_id_buf, "%02dcardtype%s",
1171 card_match_id, RFIC_word);
1172 break;
1173 }
1174
1175 DBGPRINT(RT_DEBUG_TRACE, ("Search Keyword = %s\n", card_id_buf));
1176
1177 // read card file path
1178 if (RTMPGetKeyParameter(card_id_buf, tmpbuf, 256, buffer))
1179 {
1180 if (strlen(tmpbuf) < sizeof(pAd->MC_FileName))
1181 {
1182 // backup card information
1183 pAd->MC_RowID = card_match_id; /* base 0 */
1184 MC_CardUsed[card_match_id] = 1;
1185 memcpy(MC_CardMac[card_match_id], mac, sizeof(mac));
1186
1187 // backup card file path
1188 NdisMoveMemory(pAd->MC_FileName, tmpbuf , strlen(tmpbuf));
1189 pAd->MC_FileName[strlen(tmpbuf)] = '\0';
1190 flg_match_ok = TRUE;
1191
1192 DBGPRINT(RT_DEBUG_TRACE,
1193 ("Card Profile Name = %s\n", pAd->MC_FileName));
1194 }
1195 else
1196 {
1197 DBGPRINT(RT_DEBUG_ERROR,
1198 ("Card Profile Name length too large!\n"));
1199 }
1200 }
1201 else
1202 {
1203 DBGPRINT(RT_DEBUG_ERROR,
1204 ("Can not find search key word in card.dat!\n"));
1205 }
1206
1207 if ((flg_match_ok != TRUE) &&
1208 (card_match_id < MAX_NUM_OF_MULTIPLE_CARD))
1209 {
1210 MC_CardUsed[card_match_id] = 0;
1211 memset(MC_CardMac[card_match_id], 0, sizeof(mac));
1212 }
1213 } // if (card_match_id >= 0)
1214 }
1215 }
1216
1217 // close file
1218 retval = filp_close(srcf, NULL);
1219 set_fs(orgfs);
1220 current->fsuid = orgfsuid;
1221 current->fsgid = orgfsgid;
1222 kfree(buffer);
1223 kfree(tmpbuf);
1224 return flg_match_ok;
1225}
1226#endif // MULTIPLE_CARD_SUPPORT //
1227
1228
1229/*
1230========================================================================
1231Routine Description:
1232 Probe RT28XX chipset.
1233
1234Arguments:
1235 _dev_p Point to the PCI or USB device
1236 _dev_id_p Point to the PCI or USB device ID
1237
1238Return Value:
1239 0 Probe OK
1240 -ENODEV Probe Fail
1241
1242Note:
1243========================================================================
1244*/
1245INT __devinit rt28xx_probe(
1246 IN void *_dev_p,
1247 IN void *_dev_id_p,
1248 IN UINT argc,
1249 OUT PRTMP_ADAPTER *ppAd)
1250{
1251 struct net_device *net_dev;
1252 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) NULL;
1253 INT status;
1254 PVOID handle;
1255#ifdef RT2860
1256 struct pci_dev *dev_p = (struct pci_dev *)_dev_p;
1257#endif // RT2860 //
1258
1259
1260#ifdef CONFIG_STA_SUPPORT
1261 DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
1262#endif // CONFIG_STA_SUPPORT //
1263
1264#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
1265 net_dev = alloc_netdev(sizeof(PRTMP_ADAPTER), "eth%d", ether_setup);
1266#else
1267 net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));
1268#endif
1269 if (net_dev == NULL)
1270 {
1271 printk("alloc_netdev failed\n");
1272
1273#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1274#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
1275 module_put(THIS_MODULE);
1276#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
1277#else
1278 MOD_DEC_USE_COUNT;
1279#endif
1280 goto err_out;
1281 }
1282
1283#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1284 SET_MODULE_OWNER(net_dev);
1285#endif
1286
1287 netif_stop_queue(net_dev);
1288#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1289/* for supporting Network Manager */
1290/* Set the sysfs physical device reference for the network logical device
1291 * if set prior to registration will cause a symlink during initialization.
1292 */
1293#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
1294 SET_NETDEV_DEV(net_dev, &(dev_p->dev));
1295#endif
1296#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1297
1298 // Allocate RTMP_ADAPTER miniport adapter structure
1299 handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
1300 RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p);
1301
1302 status = RTMPAllocAdapterBlock(handle, &pAd);
1303 if (status != NDIS_STATUS_SUCCESS)
1304 goto err_out_free_netdev;
1305
1306 net_dev->priv = (PVOID)pAd;
1307 pAd->net_dev = net_dev; // must be before RT28XXNetDevInit()
1308
1309 RT28XXNetDevInit(_dev_p, net_dev, pAd);
1310
1311#ifdef CONFIG_STA_SUPPORT
1312 pAd->StaCfg.OriDevType = net_dev->type;
1313#endif // CONFIG_STA_SUPPORT //
1314
1315 // Post config
1316#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1317 if (RT28XXProbePostConfig(_dev_p, pAd, argc) == FALSE)
1318 goto err_out_unmap;
1319#else
1320 if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE)
1321 goto err_out_unmap;
1322#endif // LINUX_VERSION_CODE //
1323
1324#ifdef CONFIG_STA_SUPPORT
1325 pAd->OpMode = OPMODE_STA;
1326#endif // CONFIG_STA_SUPPORT //
1327
1328
1329#ifdef MULTIPLE_CARD_SUPPORT
1330 // find its profile path
1331 pAd->MC_RowID = -1; // use default profile path
1332 RTMP_CardInfoRead(pAd);
1333
1334 if (pAd->MC_RowID == -1)
1335#ifdef CONFIG_STA_SUPPORT
1336 strcpy(pAd->MC_FileName, STA_PROFILE_PATH);
1337#endif // CONFIG_STA_SUPPORT //
1338
1339 DBGPRINT(RT_DEBUG_TRACE,
1340 ("MC> ROW = %d, PATH = %s\n", pAd->MC_RowID, pAd->MC_FileName));
1341#endif // MULTIPLE_CARD_SUPPORT //
1342
1343 // sample move
1344 if (rt_ieee80211_if_setup(net_dev, pAd) != NDIS_STATUS_SUCCESS)
1345 goto err_out_unmap;
1346
1347 // Register this device
1348 status = register_netdev(net_dev);
1349 if (status)
1350 goto err_out_unmap;
1351
1352 // Set driver data
1353 RT28XX_DRVDATA_SET(_dev_p);
1354
1355 *ppAd = pAd;
1356 return 0; // probe ok
1357
1358
1359 /* --------------------------- ERROR HANDLE --------------------------- */
1360err_out_unmap:
1361 RTMPFreeAdapter(pAd);
1362 RT28XX_UNMAP();
1363
1364err_out_free_netdev:
1365#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1366 free_netdev(net_dev);
1367#else
1368 kfree(net_dev);
1369#endif
1370
1371err_out:
1372 RT28XX_PUT_DEVICE(dev_p);
1373
1374#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1375 return (LONG)NULL;
1376#else
1377 return -ENODEV; /* probe fail */
1378#endif // LINUX_VERSION_CODE //
1379} /* End of rt28xx_probe */
1380
1381
1382/*
1383========================================================================
1384Routine Description:
1385 The entry point for Linux kernel sent packet to our driver.
1386
1387Arguments:
1388 sk_buff *skb the pointer refer to a sk_buffer.
1389
1390Return Value:
1391 0
1392
1393Note:
1394 This function is the entry point of Tx Path for Os delivery packet to
1395 our driver. You only can put OS-depened & STA/AP common handle procedures
1396 in here.
1397========================================================================
1398*/
1399int rt28xx_packet_xmit(struct sk_buff *skb)
1400{
1401 struct net_device *net_dev = skb->dev;
1402 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) net_dev->priv;
1403 int status = 0;
1404 PNDIS_PACKET pPacket = (PNDIS_PACKET) skb;
1405
1406 /* RT2870STA does this in RTMPSendPackets() */
1407#ifdef RALINK_ATE
1408 if (ATE_ON(pAd))
1409 {
1410 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
1411 return 0;
1412 }
1413#endif // RALINK_ATE //
1414
1415#ifdef CONFIG_STA_SUPPORT
1416 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1417 {
1418 // Drop send request since we are in monitor mode
1419 if (MONITOR_ON(pAd))
1420 {
1421 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1422 goto done;
1423 }
1424 }
1425#endif // CONFIG_STA_SUPPORT //
1426
1427 // EapolStart size is 18
1428 if (skb->len < 14)
1429 {
1430 //printk("bad packet size: %d\n", pkt->len);
1431 hex_dump("bad packet", skb->data, skb->len);
1432 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1433 goto done;
1434 }
1435
1436 RTMP_SET_PACKET_5VT(pPacket, 0);
1437#ifdef CONFIG_5VT_ENHANCE
1438 if (*(int*)(skb->cb) == BRIDGE_TAG) {
1439 RTMP_SET_PACKET_5VT(pPacket, 1);
1440 }
1441#endif
1442
1443
1444
1445#ifdef CONFIG_STA_SUPPORT
1446 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1447 {
1448
1449 STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
1450 }
1451
1452#endif // CONFIG_STA_SUPPORT //
1453
1454 status = 0;
1455done:
1456
1457 return status;
1458}
1459
1460
1461/*
1462========================================================================
1463Routine Description:
1464 Send a packet to WLAN.
1465
1466Arguments:
1467 skb_p points to our adapter
1468 dev_p which WLAN network interface
1469
1470Return Value:
1471 0: transmit successfully
1472 otherwise: transmit fail
1473
1474Note:
1475========================================================================
1476*/
1477INT rt28xx_send_packets(
1478 IN struct sk_buff *skb_p,
1479 IN struct net_device *net_dev)
1480{
1481 RTMP_ADAPTER *pAd = net_dev->priv;
1482 if (!(net_dev->flags & IFF_UP))
1483 {
1484 RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE);
1485 return 0;
1486 }
1487
1488 NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15);
1489 RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
1490
1491 return rt28xx_packet_xmit(skb_p);
1492
1493} /* End of MBSS_VirtualIF_PacketSend */
1494
1495
1496
1497
1498#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
1499struct net_device *alloc_netdev(
1500 int sizeof_priv,
1501 const char *mask,
1502 void (*setup)(struct net_device *))
1503{
1504 struct net_device *dev;
1505 INT alloc_size;
1506
1507
1508 /* ensure 32-byte alignment of the private area */
1509 alloc_size = sizeof (*dev) + sizeof_priv + 31;
1510
1511 dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
1512 if (dev == NULL)
1513 {
1514 DBGPRINT(RT_DEBUG_ERROR,
1515 ("alloc_netdev: Unable to allocate device memory.\n"));
1516 return NULL;
1517 }
1518
1519 memset(dev, 0, alloc_size);
1520
1521 if (sizeof_priv)
1522 dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
1523
1524 setup(dev);
1525 strcpy(dev->name, mask);
1526
1527 return dev;
1528}
1529#endif // LINUX_VERSION_CODE //
1530
1531
1532void CfgInitHook(PRTMP_ADAPTER pAd)
1533{
1534 pAd->bBroadComHT = TRUE;
1535} /* End of CfgInitHook */
1536
1537
1538#if WIRELESS_EXT >= 12
1539// This function will be called when query /proc
1540struct iw_statistics *rt28xx_get_wireless_stats(
1541 IN struct net_device *net_dev)
1542{
1543 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) net_dev->priv;
1544
1545
1546 DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
1547
1548 pAd->iw_stats.status = 0; // Status - device dependent for now
1549
1550 // link quality
1551 pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
1552 if(pAd->iw_stats.qual.qual > 100)
1553 pAd->iw_stats.qual.qual = 100;
1554
1555#ifdef CONFIG_STA_SUPPORT
1556 if (pAd->OpMode == OPMODE_STA)
1557 pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
1558#endif // CONFIG_STA_SUPPORT //
1559
1560 pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm)
1561
1562 pAd->iw_stats.qual.noise += 256 - 143;
1563 pAd->iw_stats.qual.updated = 1; // Flags to know if updated
1564#ifdef IW_QUAL_DBM
1565 pAd->iw_stats.qual.updated |= IW_QUAL_DBM; // Level + Noise are dBm
1566#endif // IW_QUAL_DBM //
1567
1568 pAd->iw_stats.discard.nwid = 0; // Rx : Wrong nwid/essid
1569 pAd->iw_stats.miss.beacon = 0; // Missed beacons/superframe
1570
1571 DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
1572 return &pAd->iw_stats;
1573} /* End of rt28xx_get_wireless_stats */
1574#endif // WIRELESS_EXT //
1575
1576
1577
1578void tbtt_tasklet(unsigned long data)
1579{
1580#define MAX_TX_IN_TBTT (16)
1581
1582}
1583
1584INT rt28xx_ioctl(
1585 IN struct net_device *net_dev,
1586 IN OUT struct ifreq *rq,
1587 IN INT cmd)
1588{
1589 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1590 RTMP_ADAPTER *pAd = NULL;
1591 INT ret = 0;
1592
1593 if (net_dev->priv_flags == INT_MAIN)
1594 {
1595 pAd = net_dev->priv;
1596 }
1597 else
1598 {
1599 pVirtualAd = net_dev->priv;
1600 pAd = pVirtualAd->RtmpDev->priv;
1601 }
1602
1603 if (pAd == NULL)
1604 {
1605 /* if 1st open fail, pAd will be free;
1606 So the net_dev->priv will be NULL in 2rd open */
1607 return -ENETDOWN;
1608 }
1609
1610
1611#ifdef CONFIG_STA_SUPPORT
1612 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1613 {
1614 ret = rt28xx_sta_ioctl(net_dev, rq, cmd);
1615 }
1616#endif // CONFIG_STA_SUPPORT //
1617
1618 return ret;
1619}
1620
1621/*
1622 ========================================================================
1623
1624 Routine Description:
1625 return ethernet statistics counter
1626
1627 Arguments:
1628 net_dev Pointer to net_device
1629
1630 Return Value:
1631 net_device_stats*
1632
1633 Note:
1634
1635 ========================================================================
1636*/
1637struct net_device_stats *RT28xx_get_ether_stats(
1638 IN struct net_device *net_dev)
1639{
1640 RTMP_ADAPTER *pAd = NULL;
1641
1642 if (net_dev)
1643 pAd = net_dev->priv;
1644
1645 if (pAd)
1646 {
1647
1648 pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
1649 pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
1650
1651 pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
1652 pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
1653
1654 pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
1655 pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
1656
1657 pAd->stats.rx_dropped = 0;
1658 pAd->stats.tx_dropped = 0;
1659
1660 pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart; // multicast packets received
1661 pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions; // Collision packets
1662
1663 pAd->stats.rx_length_errors = 0;
1664 pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer; // receiver ring buff overflow
1665 pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error
1666 pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors; // recv'd frame alignment error
1667 pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer; // recv'r fifo overrun
1668 pAd->stats.rx_missed_errors = 0; // receiver missed packet
1669
1670 // detailed tx_errors
1671 pAd->stats.tx_aborted_errors = 0;
1672 pAd->stats.tx_carrier_errors = 0;
1673 pAd->stats.tx_fifo_errors = 0;
1674 pAd->stats.tx_heartbeat_errors = 0;
1675 pAd->stats.tx_window_errors = 0;
1676
1677 // for cslip etc
1678 pAd->stats.rx_compressed = 0;
1679 pAd->stats.tx_compressed = 0;
1680
1681 return &pAd->stats;
1682 }
1683 else
1684 return NULL;
1685}
1686
diff --git a/drivers/staging/rt2860/rt_profile.c b/drivers/staging/rt2860/rt_profile.c
new file mode 100644
index 00000000000..a38e557a9ec
--- /dev/null
+++ b/drivers/staging/rt2860/rt_profile.c
@@ -0,0 +1,1976 @@
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 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
1182 pAd->CommonCfg.bEnableTxBurst = TRUE;
1183 else //Disable
1184 pAd->CommonCfg.bEnableTxBurst = FALSE;
1185 DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
1186 }
1187
1188#ifdef AGGREGATION_SUPPORT
1189 //PktAggregate
1190 if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, buffer))
1191 {
1192 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
1193 pAd->CommonCfg.bAggregationCapable = TRUE;
1194 else //Disable
1195 pAd->CommonCfg.bAggregationCapable = FALSE;
1196#ifdef PIGGYBACK_SUPPORT
1197 pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
1198#endif // PIGGYBACK_SUPPORT //
1199 DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
1200 }
1201#else
1202 pAd->CommonCfg.bAggregationCapable = FALSE;
1203 pAd->CommonCfg.bPiggyBackCapable = FALSE;
1204#endif // AGGREGATION_SUPPORT //
1205
1206 // WmmCapable
1207
1208#ifdef CONFIG_STA_SUPPORT
1209 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1210 rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, buffer);
1211#endif // CONFIG_STA_SUPPORT //
1212
1213 //ShortSlot
1214 if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, buffer))
1215 {
1216 if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
1217 pAd->CommonCfg.bUseShortSlotTime = TRUE;
1218 else //Disable
1219 pAd->CommonCfg.bUseShortSlotTime = FALSE;
1220
1221 DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
1222 }
1223 //IEEE80211H
1224 if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, buffer))
1225 {
1226 for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
1227 {
1228 if(simple_strtol(macptr, 0, 10) != 0) //Enable
1229 pAd->CommonCfg.bIEEE80211H = TRUE;
1230 else //Disable
1231 pAd->CommonCfg.bIEEE80211H = FALSE;
1232
1233 DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
1234 }
1235 }
1236 //CSPeriod
1237 if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, buffer))
1238 {
1239 if(simple_strtol(tmpbuf, 0, 10) != 0)
1240 pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
1241 else
1242 pAd->CommonCfg.RadarDetect.CSPeriod = 0;
1243
1244 DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
1245 }
1246
1247 //RDRegion
1248 if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, buffer))
1249 {
1250 if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
1251 {
1252 pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W53;
1253 pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
1254 }
1255 else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
1256 {
1257 pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W56;
1258 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1259 }
1260 else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
1261 {
1262 pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
1263 pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
1264 }
1265 else if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
1266 {
1267 pAd->CommonCfg.RadarDetect.RDDurRegion = FCC;
1268 pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
1269 }
1270 else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
1271 {
1272 pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1273 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1274 }
1275 else
1276 {
1277 pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1278 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1279 }
1280
1281 DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RadarDetect.RDDurRegion));
1282 }
1283 else
1284 {
1285 pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1286 pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1287 }
1288
1289 //WirelessEvent
1290 if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, buffer))
1291 {
1292#if WIRELESS_EXT >= 15
1293 if(simple_strtol(tmpbuf, 0, 10) != 0)
1294 pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
1295 else
1296 pAd->CommonCfg.bWirelessEvent = 0; // disable
1297#else
1298 pAd->CommonCfg.bWirelessEvent = 0; // disable
1299#endif
1300 DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
1301 }
1302 if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, buffer))
1303 {
1304 if(simple_strtol(tmpbuf, 0, 10) != 0)
1305 pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
1306 else
1307 pAd->CommonCfg.bWiFiTest = 0; // disable
1308
1309 DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
1310 }
1311 //AuthMode
1312 if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, buffer))
1313 {
1314#ifdef CONFIG_STA_SUPPORT
1315 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1316 {
1317 if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
1318 pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
1319 else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
1320 pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1321 else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
1322 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
1323 else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
1324 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
1325 else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
1326 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
1327#ifdef WPA_SUPPLICANT_SUPPORT
1328 else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
1329 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
1330 else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
1331 pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
1332#endif // WPA_SUPPLICANT_SUPPORT //
1333 else
1334 pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1335
1336 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1337
1338 DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
1339 }
1340#endif // CONFIG_STA_SUPPORT //
1341 }
1342 //EncrypType
1343 if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, buffer))
1344 {
1345
1346#ifdef CONFIG_STA_SUPPORT
1347 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1348 {
1349 if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
1350 pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1351 else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
1352 pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
1353 else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
1354 pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
1355 else
1356 pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1357
1358 // Update all wepstatus related
1359 pAd->StaCfg.PairCipher = pAd->StaCfg.WepStatus;
1360 pAd->StaCfg.GroupCipher = pAd->StaCfg.WepStatus;
1361 pAd->StaCfg.OrigWepStatus = pAd->StaCfg.WepStatus;
1362 pAd->StaCfg.bMixCipher = FALSE;
1363
1364 DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
1365 }
1366#endif // CONFIG_STA_SUPPORT //
1367 }
1368
1369
1370
1371#ifdef CONFIG_STA_SUPPORT
1372 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1373 {
1374 if(RTMPGetCriticalParameter("WPAPSK", tmpbuf, 512, buffer))
1375 {
1376 int err=0;
1377
1378 tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
1379
1380 if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
1381 (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
1382 (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
1383 )
1384 {
1385 err = 1;
1386 }
1387 else if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) < 64))
1388 {
1389 PasswordHash((char *)tmpbuf, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, keyMaterial);
1390 NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
1391
1392 }
1393 else if (strlen(tmpbuf) == 64)
1394 {
1395 AtoH(tmpbuf, keyMaterial, 32);
1396 NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
1397 }
1398 else
1399 {
1400 err = 1;
1401 DBGPRINT(RT_DEBUG_ERROR, ("%s::(WPAPSK key-string required 8 ~ 64 characters!)\n", __FUNCTION__));
1402 }
1403
1404 if (err == 0)
1405 {
1406 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1407 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1408 {
1409 // Start STA supplicant state machine
1410 pAd->StaCfg.WpaState = SS_START;
1411 }
1412 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1413 {
1414 pAd->StaCfg.WpaState = SS_NOTUSE;
1415 }
1416
1417 DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __FUNCTION__, tmpbuf));
1418 }
1419 }
1420 }
1421#endif // CONFIG_STA_SUPPORT //
1422
1423 //DefaultKeyID, KeyType, KeyStr
1424 rtmp_read_key_parms_from_file(pAd, tmpbuf, buffer);
1425
1426#ifdef DOT11_N_SUPPORT
1427 HTParametersHook(pAd, tmpbuf, buffer);
1428#endif // DOT11_N_SUPPORT //
1429
1430
1431#ifdef CARRIER_DETECTION_SUPPORT
1432 //CarrierDetect
1433 if(RTMPGetKeyParameter("CarrierDetect", tmpbuf, 128, buffer))
1434 {
1435 if ((strncmp(tmpbuf, "0", 1) == 0))
1436 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
1437 else if ((strncmp(tmpbuf, "1", 1) == 0))
1438 pAd->CommonCfg.CarrierDetect.Enable = TRUE;
1439 else
1440 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
1441
1442 DBGPRINT(RT_DEBUG_TRACE, ("CarrierDetect.Enable=%d\n", pAd->CommonCfg.CarrierDetect.Enable));
1443 }
1444 else
1445 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
1446#endif // CARRIER_DETECTION_SUPPORT //
1447
1448#ifdef CONFIG_STA_SUPPORT
1449 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1450 {
1451 //PSMode
1452 if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer))
1453 {
1454 if (pAd->StaCfg.BssType == BSS_INFRA)
1455 {
1456 if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
1457 {
1458 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1459 // to exclude certain situations.
1460 // MlmeSetPsm(pAd, PWR_SAVE);
1461 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1462 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1463 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
1464 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
1465 pAd->StaCfg.DefaultListenCount = 5;
1466 }
1467 else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
1468 || (strcmp(tmpbuf, "FAST_PSP") == 0))
1469 {
1470 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1471 // to exclude certain situations.
1472 // MlmeSetPsmBit(pAd, PWR_SAVE);
1473 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1474 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1475 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
1476 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
1477 pAd->StaCfg.DefaultListenCount = 3;
1478 }
1479 else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
1480 || (strcmp(tmpbuf, "LEGACY_PSP") == 0))
1481 {
1482 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1483 // to exclude certain situations.
1484 // MlmeSetPsmBit(pAd, PWR_SAVE);
1485 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1486 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1487 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
1488 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
1489 pAd->StaCfg.DefaultListenCount = 3;
1490 }
1491 else
1492 { //Default Ndis802_11PowerModeCAM
1493 // clear PSM bit immediately
1494 MlmeSetPsmBit(pAd, PWR_ACTIVE);
1495 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1496 if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1497 pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
1498 pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
1499 }
1500 DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
1501 }
1502 }
1503 // FastRoaming
1504 if (RTMPGetKeyParameter("FastRoaming", tmpbuf, 32, buffer))
1505 {
1506 if (simple_strtol(tmpbuf, 0, 10) == 0)
1507 pAd->StaCfg.bFastRoaming = FALSE;
1508 else
1509 pAd->StaCfg.bFastRoaming = TRUE;
1510
1511 DBGPRINT(RT_DEBUG_TRACE, ("FastRoaming=%d\n", pAd->StaCfg.bFastRoaming));
1512 }
1513 // RoamThreshold
1514 if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, buffer))
1515 {
1516 long lInfo = simple_strtol(tmpbuf, 0, 10);
1517
1518 if (lInfo > 90 || lInfo < 60)
1519 pAd->StaCfg.dBmToRoam = -70;
1520 else
1521 pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
1522
1523 DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d dBm\n", pAd->StaCfg.dBmToRoam));
1524 }
1525
1526 if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, buffer))
1527 {
1528 if(simple_strtol(tmpbuf, 0, 10) == 0)
1529 pAd->StaCfg.bTGnWifiTest = FALSE;
1530 else
1531 pAd->StaCfg.bTGnWifiTest = TRUE;
1532 DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
1533 }
1534 }
1535#endif // CONFIG_STA_SUPPORT //
1536
1537 }
1538 }
1539 else
1540 {
1541 DBGPRINT(RT_DEBUG_TRACE, ("--> %s does not have a write method\n", src));
1542 }
1543
1544 retval=filp_close(srcf,NULL);
1545
1546 if (retval)
1547 {
1548 DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
1549 }
1550 }
1551 }
1552
1553 set_fs(orgfs);
1554 current->fsuid = orgfsuid;
1555 current->fsgid = orgfsgid;
1556
1557 kfree(buffer);
1558 kfree(tmpbuf);
1559
1560 return (NDIS_STATUS_SUCCESS);
1561}
1562
1563#ifdef DOT11_N_SUPPORT
1564static void HTParametersHook(
1565 IN PRTMP_ADAPTER pAd,
1566 IN CHAR *pValueStr,
1567 IN CHAR *pInput)
1568{
1569
1570 INT Value;
1571
1572 if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput))
1573 {
1574 Value = simple_strtol(pValueStr, 0, 10);
1575 if (Value == 0)
1576 {
1577 pAd->CommonCfg.bHTProtect = FALSE;
1578 }
1579 else
1580 {
1581 pAd->CommonCfg.bHTProtect = TRUE;
1582 }
1583 DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection = %s\n", (Value==0) ? "Disable" : "Enable"));
1584 }
1585
1586 if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput))
1587 {
1588 Value = simple_strtol(pValueStr, 0, 10);
1589 if (Value == 0)
1590 {
1591 pAd->CommonCfg.bMIMOPSEnable = FALSE;
1592 }
1593 else
1594 {
1595 pAd->CommonCfg.bMIMOPSEnable = TRUE;
1596 }
1597 DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable = %s\n", (Value==0) ? "Disable" : "Enable"));
1598 }
1599
1600
1601 if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput))
1602 {
1603 Value = simple_strtol(pValueStr, 0, 10);
1604 if (Value > MMPS_ENABLE)
1605 {
1606 pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
1607 }
1608 else
1609 {
1610 //TODO: add mimo power saving mechanism
1611 pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
1612 //pAd->CommonCfg.BACapability.field.MMPSmode = Value;
1613 }
1614 DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode = %d\n", Value));
1615 }
1616
1617 if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput))
1618 {
1619 Value = simple_strtol(pValueStr, 0, 10);
1620 if (Value == 0)
1621 {
1622 pAd->CommonCfg.bBADecline = FALSE;
1623 }
1624 else
1625 {
1626 pAd->CommonCfg.bBADecline = TRUE;
1627 }
1628 DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline = %s\n", (Value==0) ? "Disable" : "Enable"));
1629 }
1630
1631
1632 if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput))
1633 {
1634 Value = simple_strtol(pValueStr, 0, 10);
1635 if (Value == 0)
1636 {
1637 pAd->CommonCfg.bDisableReordering = FALSE;
1638 }
1639 else
1640 {
1641 pAd->CommonCfg.bDisableReordering = TRUE;
1642 }
1643 DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering = %s\n", (Value==0) ? "Disable" : "Enable"));
1644 }
1645
1646 if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput))
1647 {
1648 Value = simple_strtol(pValueStr, 0, 10);
1649 if (Value == 0)
1650 {
1651 pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
1652 }
1653 else
1654 {
1655 pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
1656 }
1657 pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
1658 DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA = %s\n", (Value==0) ? "Disable" : "Enable"));
1659 }
1660
1661 // Tx_+HTC frame
1662 if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput))
1663 {
1664 Value = simple_strtol(pValueStr, 0, 10);
1665 if (Value == 0)
1666 {
1667 pAd->HTCEnable = FALSE;
1668 }
1669 else
1670 {
1671 pAd->HTCEnable = TRUE;
1672 }
1673 DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
1674 }
1675
1676 // Enable HT Link Adaptation Control
1677 if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput))
1678 {
1679 Value = simple_strtol(pValueStr, 0, 10);
1680 if (Value == 0)
1681 {
1682 pAd->bLinkAdapt = FALSE;
1683 }
1684 else
1685 {
1686 pAd->HTCEnable = TRUE;
1687 pAd->bLinkAdapt = TRUE;
1688 }
1689 DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
1690 }
1691
1692 // Reverse Direction Mechanism
1693 if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput))
1694 {
1695 Value = simple_strtol(pValueStr, 0, 10);
1696 if (Value == 0)
1697 {
1698 pAd->CommonCfg.bRdg = FALSE;
1699 }
1700 else
1701 {
1702 pAd->HTCEnable = TRUE;
1703 pAd->CommonCfg.bRdg = TRUE;
1704 }
1705 DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
1706 }
1707
1708
1709
1710
1711 // Tx A-MSUD ?
1712 if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput))
1713 {
1714 Value = simple_strtol(pValueStr, 0, 10);
1715 if (Value == 0)
1716 {
1717 pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
1718 }
1719 else
1720 {
1721 pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
1722 }
1723 DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
1724 }
1725
1726 // MPDU Density
1727 if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput))
1728 {
1729 Value = simple_strtol(pValueStr, 0, 10);
1730 if (Value <=7 && Value >= 0)
1731 {
1732 pAd->CommonCfg.BACapability.field.MpduDensity = Value;
1733 DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", Value));
1734 }
1735 else
1736 {
1737 pAd->CommonCfg.BACapability.field.MpduDensity = 4;
1738 DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
1739 }
1740 }
1741
1742 // Max Rx BA Window Size
1743 if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput))
1744 {
1745 Value = simple_strtol(pValueStr, 0, 10);
1746
1747 if (Value >=1 && Value <= 64)
1748 {
1749 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
1750 pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
1751 DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", Value));
1752 }
1753 else
1754 {
1755 pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
1756 pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
1757 DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
1758 }
1759
1760 }
1761
1762 // Guard Interval
1763 if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput))
1764 {
1765 Value = simple_strtol(pValueStr, 0, 10);
1766
1767 if (Value == GI_400)
1768 {
1769 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
1770 }
1771 else
1772 {
1773 pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
1774 }
1775
1776 DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
1777 }
1778
1779 // HT Operation Mode : Mixed Mode , Green Field
1780 if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput))
1781 {
1782 Value = simple_strtol(pValueStr, 0, 10);
1783
1784 if (Value == HTMODE_GF)
1785 {
1786
1787 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
1788 }
1789 else
1790 {
1791 pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
1792 }
1793
1794 DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
1795 }
1796
1797 // Fixed Tx mode : CCK, OFDM
1798 if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput))
1799 {
1800 UCHAR fix_tx_mode;
1801
1802#ifdef CONFIG_STA_SUPPORT
1803 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1804 {
1805 fix_tx_mode = FIXED_TXMODE_HT;
1806
1807 if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
1808 {
1809 fix_tx_mode = FIXED_TXMODE_OFDM;
1810 }
1811 else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
1812 {
1813 fix_tx_mode = FIXED_TXMODE_CCK;
1814 }
1815 else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
1816 {
1817 fix_tx_mode = FIXED_TXMODE_HT;
1818 }
1819 else
1820 {
1821 Value = simple_strtol(pValueStr, 0, 10);
1822 // 1 : CCK
1823 // 2 : OFDM
1824 // otherwise : HT
1825 if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
1826 fix_tx_mode = Value;
1827 else
1828 fix_tx_mode = FIXED_TXMODE_HT;
1829 }
1830
1831 pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
1832 DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
1833
1834 }
1835#endif // CONFIG_STA_SUPPORT //
1836 }
1837
1838
1839 // Channel Width
1840 if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput))
1841 {
1842 Value = simple_strtol(pValueStr, 0, 10);
1843
1844 if (Value == BW_40)
1845 {
1846 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
1847 }
1848 else
1849 {
1850 pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
1851 }
1852
1853#ifdef MCAST_RATE_SPECIFIC
1854 pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
1855#endif // MCAST_RATE_SPECIFIC //
1856
1857 DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
1858 }
1859
1860 if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput))
1861 {
1862 Value = simple_strtol(pValueStr, 0, 10);
1863
1864 if (Value == 0)
1865 {
1866
1867 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
1868 }
1869 else
1870 {
1871 pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
1872 }
1873
1874 DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
1875 }
1876
1877 // MSC
1878 if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput))
1879 {
1880
1881#ifdef CONFIG_STA_SUPPORT
1882 IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1883 {
1884 Value = simple_strtol(pValueStr, 0, 10);
1885
1886 if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
1887 {
1888 pAd->StaCfg.DesiredTransmitSetting.field.MCS = Value;
1889 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
1890 DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
1891 }
1892 else
1893 {
1894 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
1895 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
1896 DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
1897 }
1898 }
1899#endif // CONFIG_STA_SUPPORT //
1900 }
1901
1902 // STBC
1903 if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput))
1904 {
1905 Value = simple_strtol(pValueStr, 0, 10);
1906 if (Value == STBC_USE)
1907 {
1908 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
1909 }
1910 else
1911 {
1912 pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
1913 }
1914 DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
1915 }
1916
1917 // 40_Mhz_Intolerant
1918 if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput))
1919 {
1920 Value = simple_strtol(pValueStr, 0, 10);
1921 if (Value == 0)
1922 {
1923 pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
1924 }
1925 else
1926 {
1927 pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
1928 }
1929 DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
1930 }
1931 //HT_TxStream
1932 if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput))
1933 {
1934 switch (simple_strtol(pValueStr, 0, 10))
1935 {
1936 case 1:
1937 pAd->CommonCfg.TxStream = 1;
1938 break;
1939 case 2:
1940 pAd->CommonCfg.TxStream = 2;
1941 break;
1942 case 3: // 3*3
1943 default:
1944 pAd->CommonCfg.TxStream = 3;
1945
1946 if (pAd->MACVersion < RALINK_2883_VERSION)
1947 pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
1948 break;
1949 }
1950 DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
1951 }
1952 //HT_RxStream
1953 if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput))
1954 {
1955 switch (simple_strtol(pValueStr, 0, 10))
1956 {
1957 case 1:
1958 pAd->CommonCfg.RxStream = 1;
1959 break;
1960 case 2:
1961 pAd->CommonCfg.RxStream = 2;
1962 break;
1963 case 3:
1964 default:
1965 pAd->CommonCfg.RxStream = 3;
1966
1967 if (pAd->MACVersion < RALINK_2883_VERSION)
1968 pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
1969 break;
1970 }
1971 DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
1972 }
1973
1974}
1975#endif // DOT11_N_SUPPORT //
1976
diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h
new file mode 100644
index 00000000000..411954206c2
--- /dev/null
+++ b/drivers/staging/rt2860/rtmp.h
@@ -0,0 +1,7177 @@
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_DIAGNOSE 1
52
53#if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_STA_SUPPORT)
54#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd) if(_pAd->OpMode == OPMODE_AP)
55#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd) if(_pAd->OpMode == OPMODE_STA)
56#else
57#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd)
58#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd)
59#endif
60
61#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++)
62#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--)
63#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt)
64
65
66
67//
68// NDIS Version definitions
69//
70#ifdef NDIS50_MINIPORT
71#define RTMP_NDIS_MAJOR_VERSION 5
72#define RTMP_NDIS_MINOR_VERSION 0
73#endif
74
75#ifdef NDIS51_MINIPORT
76#define RTMP_NDIS_MAJOR_VERSION 5
77#define RTMP_NDIS_MINOR_VERSION 1
78#endif
79
80extern char NIC_VENDOR_DESC[];
81extern int NIC_VENDOR_DESC_LEN;
82
83extern unsigned char SNAP_AIRONET[];
84extern unsigned char CipherSuiteCiscoCCKM[];
85extern unsigned char CipherSuiteCiscoCCKMLen;
86extern unsigned char CipherSuiteCiscoCCKM24[];
87extern unsigned char CipherSuiteCiscoCCKM24Len;
88extern unsigned char CipherSuiteCCXTkip[];
89extern unsigned char CipherSuiteCCXTkipLen;
90extern unsigned char CISCO_OUI[];
91extern UCHAR BaSizeArray[4];
92
93extern UCHAR BROADCAST_ADDR[MAC_ADDR_LEN];
94extern UCHAR MULTICAST_ADDR[MAC_ADDR_LEN];
95extern UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN];
96extern ULONG BIT32[32];
97extern UCHAR BIT8[8];
98extern char* CipherName[];
99extern char* MCSToMbps[];
100extern UCHAR RxwiMCSToOfdmRate[12];
101extern UCHAR SNAP_802_1H[6];
102extern UCHAR SNAP_BRIDGE_TUNNEL[6];
103extern UCHAR SNAP_AIRONET[8];
104extern UCHAR CKIP_LLC_SNAP[8];
105extern UCHAR EAPOL_LLC_SNAP[8];
106extern UCHAR EAPOL[2];
107extern UCHAR IPX[2];
108extern UCHAR APPLE_TALK[2];
109extern UCHAR RateIdToPlcpSignal[12]; // see IEEE802.11a-1999 p.14
110extern UCHAR OfdmRateToRxwiMCS[];
111extern UCHAR OfdmSignalToRateId[16] ;
112extern UCHAR default_cwmin[4];
113extern UCHAR default_cwmax[4];
114extern UCHAR default_sta_aifsn[4];
115extern UCHAR MapUserPriorityToAccessCategory[8];
116
117extern USHORT RateUpPER[];
118extern USHORT RateDownPER[];
119extern UCHAR Phy11BNextRateDownward[];
120extern UCHAR Phy11BNextRateUpward[];
121extern UCHAR Phy11BGNextRateDownward[];
122extern UCHAR Phy11BGNextRateUpward[];
123extern UCHAR Phy11ANextRateDownward[];
124extern UCHAR Phy11ANextRateUpward[];
125extern CHAR RssiSafeLevelForTxRate[];
126extern UCHAR RateIdToMbps[];
127extern USHORT RateIdTo500Kbps[];
128
129extern UCHAR CipherSuiteWpaNoneTkip[];
130extern UCHAR CipherSuiteWpaNoneTkipLen;
131
132extern UCHAR CipherSuiteWpaNoneAes[];
133extern UCHAR CipherSuiteWpaNoneAesLen;
134
135extern UCHAR SsidIe;
136extern UCHAR SupRateIe;
137extern UCHAR ExtRateIe;
138
139#ifdef DOT11_N_SUPPORT
140extern UCHAR HtCapIe;
141extern UCHAR AddHtInfoIe;
142extern UCHAR NewExtChanIe;
143#ifdef DOT11N_DRAFT3
144extern UCHAR ExtHtCapIe;
145#endif // DOT11N_DRAFT3 //
146#endif // DOT11_N_SUPPORT //
147
148extern UCHAR ErpIe;
149extern UCHAR DsIe;
150extern UCHAR TimIe;
151extern UCHAR WpaIe;
152extern UCHAR Wpa2Ie;
153extern UCHAR IbssIe;
154extern UCHAR Ccx2Ie;
155
156extern UCHAR WPA_OUI[];
157extern UCHAR RSN_OUI[];
158extern UCHAR WME_INFO_ELEM[];
159extern UCHAR WME_PARM_ELEM[];
160extern UCHAR Ccx2QosInfo[];
161extern UCHAR Ccx2IeInfo[];
162extern UCHAR RALINK_OUI[];
163extern UCHAR PowerConstraintIE[];
164
165
166extern UCHAR RateSwitchTable[];
167extern UCHAR RateSwitchTable11B[];
168extern UCHAR RateSwitchTable11G[];
169extern UCHAR RateSwitchTable11BG[];
170
171#ifdef DOT11_N_SUPPORT
172extern UCHAR RateSwitchTable11BGN1S[];
173extern UCHAR RateSwitchTable11BGN2S[];
174extern UCHAR RateSwitchTable11BGN2SForABand[];
175extern UCHAR RateSwitchTable11N1S[];
176extern UCHAR RateSwitchTable11N2S[];
177extern UCHAR RateSwitchTable11N2SForABand[];
178
179#ifdef CONFIG_STA_SUPPORT
180extern UCHAR PRE_N_HT_OUI[];
181#endif // CONFIG_STA_SUPPORT //
182#endif // DOT11_N_SUPPORT //
183
184#define MAXSEQ (0xFFF)
185
186#ifdef RALINK_ATE
187typedef struct _ATE_INFO {
188 UCHAR Mode;
189 CHAR TxPower0;
190 CHAR TxPower1;
191 CHAR TxAntennaSel;
192 CHAR RxAntennaSel;
193 TXWI_STRUC TxWI; // TXWI
194 USHORT QID;
195 UCHAR Addr1[MAC_ADDR_LEN];
196 UCHAR Addr2[MAC_ADDR_LEN];
197 UCHAR Addr3[MAC_ADDR_LEN];
198 UCHAR Channel;
199 UINT32 TxLength;
200 UINT32 TxCount;
201 UINT32 TxDoneCount; // Tx DMA Done
202 UINT32 RFFreqOffset;
203 BOOLEAN bRxFer;
204 BOOLEAN bQATxStart; // Have compiled QA in and use it to ATE tx.
205 BOOLEAN bQARxStart; // Have compiled QA in and use it to ATE rx.
206#ifdef RT2860
207 BOOLEAN bFWLoading; // Reload firmware when ATE is done.
208#endif // RT2860 //
209 UINT32 RxTotalCnt;
210 UINT32 RxCntPerSec;
211
212 CHAR LastSNR0; // last received SNR
213 CHAR LastSNR1; // last received SNR for 2nd antenna
214 CHAR LastRssi0; // last received RSSI
215 CHAR LastRssi1; // last received RSSI for 2nd antenna
216 CHAR LastRssi2; // last received RSSI for 3rd antenna
217 CHAR AvgRssi0; // last 8 frames' average RSSI
218 CHAR AvgRssi1; // last 8 frames' average RSSI
219 CHAR AvgRssi2; // last 8 frames' average RSSI
220 SHORT AvgRssi0X8; // sum of last 8 frames' RSSI
221 SHORT AvgRssi1X8; // sum of last 8 frames' RSSI
222 SHORT AvgRssi2X8; // sum of last 8 frames' RSSI
223
224 UINT32 NumOfAvgRssiSample;
225
226#ifdef RALINK_28xx_QA
227 // Tx frame
228 USHORT HLen; // Header Length
229 USHORT PLen; // Pattern Length
230 UCHAR Header[32]; // Header buffer
231 UCHAR Pattern[32]; // Pattern buffer
232 USHORT DLen; // Data Length
233 USHORT seq;
234 UINT32 CID;
235 THREAD_PID AtePid;
236 // counters
237 UINT32 U2M;
238 UINT32 OtherData;
239 UINT32 Beacon;
240 UINT32 OtherCount;
241 UINT32 TxAc0;
242 UINT32 TxAc1;
243 UINT32 TxAc2;
244 UINT32 TxAc3;
245 UINT32 TxHCCA;
246 UINT32 TxMgmt;
247 UINT32 RSSI0;
248 UINT32 RSSI1;
249 UINT32 RSSI2;
250 UINT32 SNR0;
251 UINT32 SNR1;
252 // control
253 //UINT32 Repeat; // Tx Cpu count
254 UCHAR TxStatus; // task Tx status // 0 --> task is idle, 1 --> task is running
255#endif // RALINK_28xx_QA //
256} ATE_INFO, *PATE_INFO;
257
258#ifdef RALINK_28xx_QA
259struct ate_racfghdr {
260 UINT32 magic_no;
261 USHORT command_type;
262 USHORT command_id;
263 USHORT length;
264 USHORT sequence;
265 USHORT status;
266 UCHAR data[2046];
267} __attribute__((packed));
268#endif // RALINK_28xx_QA //
269#endif // RALINK_ATE //
270
271#ifdef DOT11_N_SUPPORT
272struct reordering_mpdu
273{
274 struct reordering_mpdu *next;
275 PNDIS_PACKET pPacket; /* coverted to 802.3 frame */
276 int Sequence; /* sequence number of MPDU */
277 BOOLEAN bAMSDU;
278};
279
280struct reordering_list
281{
282 struct reordering_mpdu *next;
283 int qlen;
284};
285
286struct reordering_mpdu_pool
287{
288 PVOID mem;
289 NDIS_SPIN_LOCK lock;
290 struct reordering_list freelist;
291};
292#endif // DOT11_N_SUPPORT //
293
294typedef struct _RSSI_SAMPLE {
295 CHAR LastRssi0; // last received RSSI
296 CHAR LastRssi1; // last received RSSI
297 CHAR LastRssi2; // last received RSSI
298 CHAR AvgRssi0;
299 CHAR AvgRssi1;
300 CHAR AvgRssi2;
301 SHORT AvgRssi0X8;
302 SHORT AvgRssi1X8;
303 SHORT AvgRssi2X8;
304} RSSI_SAMPLE;
305
306//
307// Queue structure and macros
308//
309typedef struct _QUEUE_ENTRY {
310 struct _QUEUE_ENTRY *Next;
311} QUEUE_ENTRY, *PQUEUE_ENTRY;
312
313// Queue structure
314typedef struct _QUEUE_HEADER {
315 PQUEUE_ENTRY Head;
316 PQUEUE_ENTRY Tail;
317 ULONG Number;
318} QUEUE_HEADER, *PQUEUE_HEADER;
319
320#define InitializeQueueHeader(QueueHeader) \
321{ \
322 (QueueHeader)->Head = (QueueHeader)->Tail = NULL; \
323 (QueueHeader)->Number = 0; \
324}
325
326#define RemoveHeadQueue(QueueHeader) \
327(QueueHeader)->Head; \
328{ \
329 PQUEUE_ENTRY pNext; \
330 if ((QueueHeader)->Head != NULL) \
331 { \
332 pNext = (QueueHeader)->Head->Next; \
333 (QueueHeader)->Head = pNext; \
334 if (pNext == NULL) \
335 (QueueHeader)->Tail = NULL; \
336 (QueueHeader)->Number--; \
337 } \
338}
339
340#define InsertHeadQueue(QueueHeader, QueueEntry) \
341{ \
342 ((PQUEUE_ENTRY)QueueEntry)->Next = (QueueHeader)->Head; \
343 (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \
344 if ((QueueHeader)->Tail == NULL) \
345 (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \
346 (QueueHeader)->Number++; \
347}
348
349#define InsertTailQueue(QueueHeader, QueueEntry) \
350{ \
351 ((PQUEUE_ENTRY)QueueEntry)->Next = NULL; \
352 if ((QueueHeader)->Tail) \
353 (QueueHeader)->Tail->Next = (PQUEUE_ENTRY)(QueueEntry); \
354 else \
355 (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \
356 (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \
357 (QueueHeader)->Number++; \
358}
359
360//
361// Macros for flag and ref count operations
362//
363#define RTMP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F))
364#define RTMP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F))
365#define RTMP_CLEAR_FLAGS(_M) ((_M)->Flags = 0)
366#define RTMP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0)
367#define RTMP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F))
368
369#define OPSTATUS_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags |= (_F))
370#define OPSTATUS_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F))
371#define OPSTATUS_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0)
372
373#define CLIENT_STATUS_SET_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags |= (_F))
374#define CLIENT_STATUS_CLEAR_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags &= ~(_F))
375#define CLIENT_STATUS_TEST_FLAG(_pEntry,_F) (((_pEntry)->ClientStatusFlags & (_F)) != 0)
376
377#define RX_FILTER_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter |= (_F))
378#define RX_FILTER_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter &= ~(_F))
379#define RX_FILTER_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.PacketFilter & (_F)) != 0)
380
381#ifdef CONFIG_STA_SUPPORT
382#define STA_NO_SECURITY_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
383#define STA_WEP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
384#define STA_TKIP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
385#define STA_AES_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
386
387#define STA_TGN_WIFI_ON(_p) (_p->StaCfg.bTGnWifiTest == TRUE)
388#endif // CONFIG_STA_SUPPORT //
389
390#define CKIP_KP_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x10) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
391#define CKIP_CMIC_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x08) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
392
393
394#define INC_RING_INDEX(_idx, _RingSize) \
395{ \
396 (_idx) = (_idx+1) % (_RingSize); \
397}
398
399#define IS_RT3070(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
400
401#define RING_PACKET_INIT(_TxRing, _idx) \
402{ \
403 _TxRing->Cell[_idx].pNdisPacket = NULL; \
404 _TxRing->Cell[_idx].pNextNdisPacket = NULL; \
405}
406
407#define TXDT_INIT(_TxD) \
408{ \
409 NdisZeroMemory(_TxD, TXD_SIZE); \
410 _TxD->DMADONE = 1; \
411}
412
413//Set last data segment
414#define RING_SET_LASTDS(_TxD, _IsSD0) \
415{ \
416 if (_IsSD0) {_TxD->LastSec0 = 1;} \
417 else {_TxD->LastSec1 = 1;} \
418}
419
420// Increase TxTsc value for next transmission
421// TODO:
422// When i==6, means TSC has done one full cycle, do re-keying stuff follow specs
423// Should send a special event microsoft defined to request re-key
424#define INC_TX_TSC(_tsc) \
425{ \
426 int i=0; \
427 while (++_tsc[i] == 0x0) \
428 { \
429 i++; \
430 if (i == 6) \
431 break; \
432 } \
433}
434
435#ifdef DOT11_N_SUPPORT
436// StaActive.SupportedHtPhy.MCSSet is copied from AP beacon. Don't need to update here.
437#define COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
438{ \
439 _pAd->StaActive.SupportedHtPhy.ChannelWidth = _pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth; \
440 _pAd->StaActive.SupportedHtPhy.MimoPs = _pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs; \
441 _pAd->StaActive.SupportedHtPhy.GF = _pAd->MlmeAux.HtCapability.HtCapInfo.GF; \
442 _pAd->StaActive.SupportedHtPhy.ShortGIfor20 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20; \
443 _pAd->StaActive.SupportedHtPhy.ShortGIfor40 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40; \
444 _pAd->StaActive.SupportedHtPhy.TxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC; \
445 _pAd->StaActive.SupportedHtPhy.RxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC; \
446 _pAd->StaActive.SupportedHtPhy.ExtChanOffset = _pAd->MlmeAux.AddHtInfo.AddHtInfo.ExtChanOffset; \
447 _pAd->StaActive.SupportedHtPhy.RecomWidth = _pAd->MlmeAux.AddHtInfo.AddHtInfo.RecomWidth; \
448 _pAd->StaActive.SupportedHtPhy.OperaionMode = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode; \
449 _pAd->StaActive.SupportedHtPhy.NonGfPresent = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent; \
450 NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(UCHAR) * 16);\
451}
452
453#define COPY_AP_HTSETTINGS_FROM_BEACON(_pAd, _pHtCapability) \
454{ \
455 _pAd->MacTab.Content[BSSID_WCID].AMsduSize = (UCHAR)(_pHtCapability->HtCapInfo.AMsduSize); \
456 _pAd->MacTab.Content[BSSID_WCID].MmpsMode= (UCHAR)(_pHtCapability->HtCapInfo.MimoPs); \
457 _pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (UCHAR)(_pHtCapability->HtCapParm.MaxRAmpduFactor); \
458}
459#endif // DOT11_N_SUPPORT //
460
461//
462// MACRO for 32-bit PCI register read / write
463//
464// Usage : RTMP_IO_READ32(
465// PRTMP_ADAPTER pAd,
466// ULONG Register_Offset,
467// PULONG pValue)
468//
469// RTMP_IO_WRITE32(
470// PRTMP_ADAPTER pAd,
471// ULONG Register_Offset,
472// ULONG Value)
473//
474
475//
476// BBP & RF are using indirect access. Before write any value into it.
477// We have to make sure there is no outstanding command pending via checking busy bit.
478//
479#define MAX_BUSY_COUNT 100 // Number of retry before failing access BBP & RF indirect register
480//
481#ifdef RT2860
482#define RTMP_RF_IO_WRITE32(_A, _V) \
483{ \
484 PHY_CSR4_STRUC Value; \
485 ULONG BusyCnt = 0; \
486 if ((_A)->bPCIclkOff) \
487 { \
488 return; \
489 } \
490 do { \
491 RTMP_IO_READ32(_A, RF_CSR_CFG0, &Value.word); \
492 if (Value.field.Busy == IDLE) \
493 break; \
494 BusyCnt++; \
495 } while (BusyCnt < MAX_BUSY_COUNT); \
496 if (BusyCnt < MAX_BUSY_COUNT) \
497 { \
498 RTMP_IO_WRITE32(_A, RF_CSR_CFG0, _V); \
499 } \
500}
501
502#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
503{ \
504 BBP_CSR_CFG_STRUC BbpCsr; \
505 int i, k; \
506 for (i=0; i<MAX_BUSY_COUNT; i++) \
507 { \
508 RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word); \
509 if (BbpCsr.field.Busy == BUSY) \
510 { \
511 continue; \
512 } \
513 BbpCsr.word = 0; \
514 BbpCsr.field.fRead = 1; \
515 BbpCsr.field.BBP_RW_MODE = 1; \
516 BbpCsr.field.Busy = 1; \
517 BbpCsr.field.RegNum = _I; \
518 RTMP_IO_WRITE32(_A, BBP_CSR_CFG, BbpCsr.word); \
519 for (k=0; k<MAX_BUSY_COUNT; k++) \
520 { \
521 RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word); \
522 if (BbpCsr.field.Busy == IDLE) \
523 break; \
524 } \
525 if ((BbpCsr.field.Busy == IDLE) && \
526 (BbpCsr.field.RegNum == _I)) \
527 { \
528 *(_pV) = (UCHAR)BbpCsr.field.Value; \
529 break; \
530 } \
531 } \
532 if (BbpCsr.field.Busy == BUSY) \
533 { \
534 DBGPRINT_ERR(("DFS BBP read R%d fail\n", _I)); \
535 *(_pV) = (_A)->BbpWriteLatch[_I]; \
536 } \
537}
538
539//#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) {}
540// Read BBP register by register's ID. Generate PER to test BA
541#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
542{ \
543 BBP_CSR_CFG_STRUC BbpCsr; \
544 int i, k; \
545 if ((_A)->bPCIclkOff == FALSE) \
546 { \
547 for (i=0; i<MAX_BUSY_COUNT; i++) \
548 { \
549 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
550 if (BbpCsr.field.Busy == BUSY) \
551 { \
552 continue; \
553 } \
554 BbpCsr.word = 0; \
555 BbpCsr.field.fRead = 1; \
556 BbpCsr.field.BBP_RW_MODE = 1; \
557 BbpCsr.field.Busy = 1; \
558 BbpCsr.field.RegNum = _I; \
559 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
560 AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
561 RTMPusecDelay(1000); \
562 for (k=0; k<MAX_BUSY_COUNT; k++) \
563 { \
564 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
565 if (BbpCsr.field.Busy == IDLE) \
566 break; \
567 } \
568 if ((BbpCsr.field.Busy == IDLE) && \
569 (BbpCsr.field.RegNum == _I)) \
570 { \
571 *(_pV) = (UCHAR)BbpCsr.field.Value; \
572 break; \
573 } \
574 } \
575 if (BbpCsr.field.Busy == BUSY) \
576 { \
577 DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word)); \
578 *(_pV) = (_A)->BbpWriteLatch[_I]; \
579 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
580 BbpCsr.field.Busy = 0; \
581 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
582 } \
583 } \
584}
585
586#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \
587{ \
588 BBP_CSR_CFG_STRUC BbpCsr; \
589 int BusyCnt; \
590 for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++) \
591 { \
592 RTMP_IO_READ32(_A, BBP_CSR_CFG, &BbpCsr.word); \
593 if (BbpCsr.field.Busy == BUSY) \
594 continue; \
595 BbpCsr.word = 0; \
596 BbpCsr.field.fRead = 0; \
597 BbpCsr.field.BBP_RW_MODE = 1; \
598 BbpCsr.field.Busy = 1; \
599 BbpCsr.field.Value = _V; \
600 BbpCsr.field.RegNum = _I; \
601 RTMP_IO_WRITE32(_A, BBP_CSR_CFG, BbpCsr.word); \
602 (_A)->BbpWriteLatch[_I] = _V; \
603 break; \
604 } \
605 if (BusyCnt == MAX_BUSY_COUNT) \
606 { \
607 DBGPRINT_ERR(("BBP write R%d fail\n", _I)); \
608 } \
609}
610
611// Write BBP register by register's ID & value
612#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \
613{ \
614 BBP_CSR_CFG_STRUC BbpCsr; \
615 int BusyCnt; \
616 if ((_A)->bPCIclkOff == FALSE) \
617 { \
618 for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++) \
619 { \
620 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
621 if (BbpCsr.field.Busy == BUSY) \
622 continue; \
623 BbpCsr.word = 0; \
624 BbpCsr.field.fRead = 0; \
625 BbpCsr.field.BBP_RW_MODE = 1; \
626 BbpCsr.field.Busy = 1; \
627 BbpCsr.field.Value = _V; \
628 BbpCsr.field.RegNum = _I; \
629 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
630 AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
631 if (_A->OpMode == OPMODE_AP) \
632 RTMPusecDelay(1000); \
633 (_A)->BbpWriteLatch[_I] = _V; \
634 break; \
635 } \
636 if (BusyCnt == MAX_BUSY_COUNT) \
637 { \
638 DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", _I, BbpCsr.word)); \
639 RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
640 BbpCsr.field.Busy = 0; \
641 RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
642 } \
643 } \
644}
645#endif // RT2860 //
646
647
648#define MAP_CHANNEL_ID_TO_KHZ(ch, khz) { \
649 switch (ch) \
650 { \
651 case 1: khz = 2412000; break; \
652 case 2: khz = 2417000; break; \
653 case 3: khz = 2422000; break; \
654 case 4: khz = 2427000; break; \
655 case 5: khz = 2432000; break; \
656 case 6: khz = 2437000; break; \
657 case 7: khz = 2442000; break; \
658 case 8: khz = 2447000; break; \
659 case 9: khz = 2452000; break; \
660 case 10: khz = 2457000; break; \
661 case 11: khz = 2462000; break; \
662 case 12: khz = 2467000; break; \
663 case 13: khz = 2472000; break; \
664 case 14: khz = 2484000; break; \
665 case 36: /* UNII */ khz = 5180000; break; \
666 case 40: /* UNII */ khz = 5200000; break; \
667 case 44: /* UNII */ khz = 5220000; break; \
668 case 48: /* UNII */ khz = 5240000; break; \
669 case 52: /* UNII */ khz = 5260000; break; \
670 case 56: /* UNII */ khz = 5280000; break; \
671 case 60: /* UNII */ khz = 5300000; break; \
672 case 64: /* UNII */ khz = 5320000; break; \
673 case 149: /* UNII */ khz = 5745000; break; \
674 case 153: /* UNII */ khz = 5765000; break; \
675 case 157: /* UNII */ khz = 5785000; break; \
676 case 161: /* UNII */ khz = 5805000; break; \
677 case 165: /* UNII */ khz = 5825000; break; \
678 case 100: /* HiperLAN2 */ khz = 5500000; break; \
679 case 104: /* HiperLAN2 */ khz = 5520000; break; \
680 case 108: /* HiperLAN2 */ khz = 5540000; break; \
681 case 112: /* HiperLAN2 */ khz = 5560000; break; \
682 case 116: /* HiperLAN2 */ khz = 5580000; break; \
683 case 120: /* HiperLAN2 */ khz = 5600000; break; \
684 case 124: /* HiperLAN2 */ khz = 5620000; break; \
685 case 128: /* HiperLAN2 */ khz = 5640000; break; \
686 case 132: /* HiperLAN2 */ khz = 5660000; break; \
687 case 136: /* HiperLAN2 */ khz = 5680000; break; \
688 case 140: /* HiperLAN2 */ khz = 5700000; break; \
689 case 34: /* Japan MMAC */ khz = 5170000; break; \
690 case 38: /* Japan MMAC */ khz = 5190000; break; \
691 case 42: /* Japan MMAC */ khz = 5210000; break; \
692 case 46: /* Japan MMAC */ khz = 5230000; break; \
693 case 184: /* Japan */ khz = 4920000; break; \
694 case 188: /* Japan */ khz = 4940000; break; \
695 case 192: /* Japan */ khz = 4960000; break; \
696 case 196: /* Japan */ khz = 4980000; break; \
697 case 208: /* Japan, means J08 */ khz = 5040000; break; \
698 case 212: /* Japan, means J12 */ khz = 5060000; break; \
699 case 216: /* Japan, means J16 */ khz = 5080000; break; \
700 default: khz = 2412000; break; \
701 } \
702 }
703
704#define MAP_KHZ_TO_CHANNEL_ID(khz, ch) { \
705 switch (khz) \
706 { \
707 case 2412000: ch = 1; break; \
708 case 2417000: ch = 2; break; \
709 case 2422000: ch = 3; break; \
710 case 2427000: ch = 4; break; \
711 case 2432000: ch = 5; break; \
712 case 2437000: ch = 6; break; \
713 case 2442000: ch = 7; break; \
714 case 2447000: ch = 8; break; \
715 case 2452000: ch = 9; break; \
716 case 2457000: ch = 10; break; \
717 case 2462000: ch = 11; break; \
718 case 2467000: ch = 12; break; \
719 case 2472000: ch = 13; break; \
720 case 2484000: ch = 14; break; \
721 case 5180000: ch = 36; /* UNII */ break; \
722 case 5200000: ch = 40; /* UNII */ break; \
723 case 5220000: ch = 44; /* UNII */ break; \
724 case 5240000: ch = 48; /* UNII */ break; \
725 case 5260000: ch = 52; /* UNII */ break; \
726 case 5280000: ch = 56; /* UNII */ break; \
727 case 5300000: ch = 60; /* UNII */ break; \
728 case 5320000: ch = 64; /* UNII */ break; \
729 case 5745000: ch = 149; /* UNII */ break; \
730 case 5765000: ch = 153; /* UNII */ break; \
731 case 5785000: ch = 157; /* UNII */ break; \
732 case 5805000: ch = 161; /* UNII */ break; \
733 case 5825000: ch = 165; /* UNII */ break; \
734 case 5500000: ch = 100; /* HiperLAN2 */ break; \
735 case 5520000: ch = 104; /* HiperLAN2 */ break; \
736 case 5540000: ch = 108; /* HiperLAN2 */ break; \
737 case 5560000: ch = 112; /* HiperLAN2 */ break; \
738 case 5580000: ch = 116; /* HiperLAN2 */ break; \
739 case 5600000: ch = 120; /* HiperLAN2 */ break; \
740 case 5620000: ch = 124; /* HiperLAN2 */ break; \
741 case 5640000: ch = 128; /* HiperLAN2 */ break; \
742 case 5660000: ch = 132; /* HiperLAN2 */ break; \
743 case 5680000: ch = 136; /* HiperLAN2 */ break; \
744 case 5700000: ch = 140; /* HiperLAN2 */ break; \
745 case 5170000: ch = 34; /* Japan MMAC */ break; \
746 case 5190000: ch = 38; /* Japan MMAC */ break; \
747 case 5210000: ch = 42; /* Japan MMAC */ break; \
748 case 5230000: ch = 46; /* Japan MMAC */ break; \
749 case 4920000: ch = 184; /* Japan */ break; \
750 case 4940000: ch = 188; /* Japan */ break; \
751 case 4960000: ch = 192; /* Japan */ break; \
752 case 4980000: ch = 196; /* Japan */ break; \
753 case 5040000: ch = 208; /* Japan, means J08 */ break; \
754 case 5060000: ch = 212; /* Japan, means J12 */ break; \
755 case 5080000: ch = 216; /* Japan, means J16 */ break; \
756 default: ch = 1; break; \
757 } \
758 }
759
760//
761// Common fragment list structure - Identical to the scatter gather frag list structure
762//
763#define NIC_MAX_PHYS_BUF_COUNT 8
764
765typedef struct _RTMP_SCATTER_GATHER_ELEMENT {
766 PVOID Address;
767 ULONG Length;
768 PULONG Reserved;
769} RTMP_SCATTER_GATHER_ELEMENT, *PRTMP_SCATTER_GATHER_ELEMENT;
770
771
772typedef struct _RTMP_SCATTER_GATHER_LIST {
773 ULONG NumberOfElements;
774 PULONG Reserved;
775 RTMP_SCATTER_GATHER_ELEMENT Elements[NIC_MAX_PHYS_BUF_COUNT];
776} RTMP_SCATTER_GATHER_LIST, *PRTMP_SCATTER_GATHER_LIST;
777
778//
779// Some utility macros
780//
781#ifndef min
782#define min(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
783#endif
784
785#ifndef max
786#define max(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
787#endif
788
789#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))))
790
791#define INC_COUNTER64(Val) (Val.QuadPart++)
792
793#define INFRA_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_INFRA_ON))
794#define ADHOC_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_ADHOC_ON))
795#define MONITOR_ON(_p) (((_p)->StaCfg.BssType) == BSS_MONITOR)
796#define IDLE_ON(_p) (!INFRA_ON(_p) && !ADHOC_ON(_p))
797
798// Check LEAP & CCKM flags
799#define LEAP_ON(_p) (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP)
800#define LEAP_CCKM_ON(_p) ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE))
801
802// if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required
803#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap) \
804{ \
805 if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500) \
806 { \
807 _pExtraLlcSnapEncap = SNAP_802_1H; \
808 if (NdisEqualMemory(IPX, _pBufVA + 12, 2) || \
809 NdisEqualMemory(APPLE_TALK, _pBufVA + 12, 2)) \
810 { \
811 _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \
812 } \
813 } \
814 else \
815 { \
816 _pExtraLlcSnapEncap = NULL; \
817 } \
818}
819
820// New Define for new Tx Path.
821#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(_pBufVA, _pExtraLlcSnapEncap) \
822{ \
823 if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500) \
824 { \
825 _pExtraLlcSnapEncap = SNAP_802_1H; \
826 if (NdisEqualMemory(IPX, _pBufVA, 2) || \
827 NdisEqualMemory(APPLE_TALK, _pBufVA, 2)) \
828 { \
829 _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \
830 } \
831 } \
832 else \
833 { \
834 _pExtraLlcSnapEncap = NULL; \
835 } \
836}
837
838
839#define MAKE_802_3_HEADER(_p, _pMac1, _pMac2, _pType) \
840{ \
841 NdisMoveMemory(_p, _pMac1, MAC_ADDR_LEN); \
842 NdisMoveMemory((_p + MAC_ADDR_LEN), _pMac2, MAC_ADDR_LEN); \
843 NdisMoveMemory((_p + MAC_ADDR_LEN * 2), _pType, LENGTH_802_3_TYPE); \
844}
845
846// if pData has no LLC/SNAP (neither RFC1042 nor Bridge tunnel), keep it that way.
847// else if the received frame is LLC/SNAP-encaped IPX or APPLETALK, preserve the LLC/SNAP field
848// else remove the LLC/SNAP field from the result Ethernet frame
849// Patch for WHQL only, which did not turn on Netbios but use IPX within its payload
850// Note:
851// _pData & _DataSize may be altered (remove 8-byte LLC/SNAP) by this MACRO
852// _pRemovedLLCSNAP: pointer to removed LLC/SNAP; NULL is not removed
853#define CONVERT_TO_802_3(_p8023hdr, _pDA, _pSA, _pData, _DataSize, _pRemovedLLCSNAP) \
854{ \
855 char LLC_Len[2]; \
856 \
857 _pRemovedLLCSNAP = NULL; \
858 if (NdisEqualMemory(SNAP_802_1H, _pData, 6) || \
859 NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6)) \
860 { \
861 PUCHAR pProto = _pData + 6; \
862 \
863 if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) && \
864 NdisEqualMemory(SNAP_802_1H, _pData, 6)) \
865 { \
866 LLC_Len[0] = (UCHAR)(_DataSize / 256); \
867 LLC_Len[1] = (UCHAR)(_DataSize % 256); \
868 MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \
869 } \
870 else \
871 { \
872 MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, pProto); \
873 _pRemovedLLCSNAP = _pData; \
874 _DataSize -= LENGTH_802_1_H; \
875 _pData += LENGTH_802_1_H; \
876 } \
877 } \
878 else \
879 { \
880 LLC_Len[0] = (UCHAR)(_DataSize / 256); \
881 LLC_Len[1] = (UCHAR)(_DataSize % 256); \
882 MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \
883 } \
884}
885
886#define SWITCH_AB( _pAA, _pBB) \
887{ \
888 PVOID pCC; \
889 pCC = _pBB; \
890 _pBB = _pAA; \
891 _pAA = pCC; \
892}
893
894// Enqueue this frame to MLME engine
895// We need to enqueue the whole frame because MLME need to pass data type
896// information from 802.11 header
897#ifdef RT2860
898#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal) \
899{ \
900 UINT32 High32TSF, Low32TSF; \
901 RTMP_IO_READ32(_pAd, TSF_TIMER_DW1, &High32TSF); \
902 RTMP_IO_READ32(_pAd, TSF_TIMER_DW0, &Low32TSF); \
903 MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal); \
904}
905#endif // RT2860 //
906
907#define NDIS_QUERY_BUFFER(_NdisBuf, _ppVA, _pBufLen) \
908 NdisQueryBuffer(_NdisBuf, _ppVA, _pBufLen)
909
910#define MAC_ADDR_EQUAL(pAddr1,pAddr2) RTMPEqualMemory((PVOID)(pAddr1), (PVOID)(pAddr2), MAC_ADDR_LEN)
911#define SSID_EQUAL(ssid1, len1, ssid2, len2) ((len1==len2) && (RTMPEqualMemory(ssid1, ssid2, len1)))
912
913//
914// Check if it is Japan W53(ch52,56,60,64) channel.
915//
916#define JapanChannelCheck(channel) ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64))
917
918#ifdef CONFIG_STA_SUPPORT
919#define STA_PORT_SECURED(_pAd) \
920{ \
921 _pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
922 NdisAcquireSpinLock(&_pAd->MacTabLock); \
923 _pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \
924 NdisReleaseSpinLock(&_pAd->MacTabLock); \
925}
926#endif // CONFIG_STA_SUPPORT //
927
928
929//
930// Register set pair for initialzation register set definition
931//
932typedef struct _RTMP_REG_PAIR
933{
934 ULONG Register;
935 ULONG Value;
936} RTMP_REG_PAIR, *PRTMP_REG_PAIR;
937
938typedef struct _REG_PAIR
939{
940 UCHAR Register;
941 UCHAR Value;
942} REG_PAIR, *PREG_PAIR;
943
944//
945// Register set pair for initialzation register set definition
946//
947typedef struct _RTMP_RF_REGS
948{
949 UCHAR Channel;
950 ULONG R1;
951 ULONG R2;
952 ULONG R3;
953 ULONG R4;
954} RTMP_RF_REGS, *PRTMP_RF_REGS;
955
956typedef struct _FREQUENCY_ITEM {
957 UCHAR Channel;
958 UCHAR N;
959 UCHAR R;
960 UCHAR K;
961} FREQUENCY_ITEM, *PFREQUENCY_ITEM;
962
963//
964// Data buffer for DMA operation, the buffer must be contiguous physical memory
965// Both DMA to / from CPU use the same structure.
966//
967typedef struct _RTMP_DMABUF
968{
969 ULONG AllocSize;
970 PVOID AllocVa; // TxBuf virtual address
971 NDIS_PHYSICAL_ADDRESS AllocPa; // TxBuf physical address
972} RTMP_DMABUF, *PRTMP_DMABUF;
973
974
975typedef union _HEADER_802_11_SEQ{
976#ifdef RT_BIG_ENDIAN
977 struct {
978 USHORT Sequence:12;
979 USHORT Frag:4;
980 } field;
981#else
982 struct {
983 USHORT Frag:4;
984 USHORT Sequence:12;
985 } field;
986#endif
987 USHORT value;
988} HEADER_802_11_SEQ, *PHEADER_802_11_SEQ;
989
990//
991// Data buffer for DMA operation, the buffer must be contiguous physical memory
992// Both DMA to / from CPU use the same structure.
993//
994typedef struct _RTMP_REORDERBUF
995{
996 BOOLEAN IsFull;
997 PVOID AllocVa; // TxBuf virtual address
998 UCHAR Header802_3[14];
999 HEADER_802_11_SEQ Sequence; //support compressed bitmap BA, so no consider fragment in BA
1000 UCHAR DataOffset;
1001 USHORT Datasize;
1002 ULONG AllocSize;
1003#ifdef RT2860
1004 NDIS_PHYSICAL_ADDRESS AllocPa; // TxBuf physical address
1005#endif // RT2860 //
1006} RTMP_REORDERBUF, *PRTMP_REORDERBUF;
1007
1008//
1009// Control block (Descriptor) for all ring descriptor DMA operation, buffer must be
1010// contiguous physical memory. NDIS_PACKET stored the binding Rx packet descriptor
1011// which won't be released, driver has to wait until upper layer return the packet
1012// before giveing up this rx ring descriptor to ASIC. NDIS_BUFFER is assocaited pair
1013// to describe the packet buffer. For Tx, NDIS_PACKET stored the tx packet descriptor
1014// which driver should ACK upper layer when the tx is physically done or failed.
1015//
1016typedef struct _RTMP_DMACB
1017{
1018 ULONG AllocSize; // Control block size
1019 PVOID AllocVa; // Control block virtual address
1020 NDIS_PHYSICAL_ADDRESS AllocPa; // Control block physical address
1021 PNDIS_PACKET pNdisPacket;
1022 PNDIS_PACKET pNextNdisPacket;
1023
1024 RTMP_DMABUF DmaBuf; // Associated DMA buffer structure
1025} RTMP_DMACB, *PRTMP_DMACB;
1026
1027typedef struct _RTMP_TX_BUF
1028{
1029 PQUEUE_ENTRY Next;
1030 UCHAR Index;
1031 ULONG AllocSize; // Control block size
1032 PVOID AllocVa; // Control block virtual address
1033 NDIS_PHYSICAL_ADDRESS AllocPa; // Control block physical address
1034} RTMP_TXBUF, *PRTMP_TXBUF;
1035
1036typedef struct _RTMP_RX_BUF
1037{
1038 BOOLEAN InUse;
1039 ULONG ByBaRecIndex;
1040 RTMP_REORDERBUF MAP_RXBuf[MAX_RX_REORDERBUF];
1041} RTMP_RXBUF, *PRTMP_RXBUF;
1042typedef struct _RTMP_TX_RING
1043{
1044 RTMP_DMACB Cell[TX_RING_SIZE];
1045 UINT32 TxCpuIdx;
1046 UINT32 TxDmaIdx;
1047 UINT32 TxSwFreeIdx; // software next free tx index
1048} RTMP_TX_RING, *PRTMP_TX_RING;
1049
1050typedef struct _RTMP_RX_RING
1051{
1052 RTMP_DMACB Cell[RX_RING_SIZE];
1053 UINT32 RxCpuIdx;
1054 UINT32 RxDmaIdx;
1055 INT32 RxSwReadIdx; // software next read index
1056} RTMP_RX_RING, *PRTMP_RX_RING;
1057
1058typedef struct _RTMP_MGMT_RING
1059{
1060 RTMP_DMACB Cell[MGMT_RING_SIZE];
1061 UINT32 TxCpuIdx;
1062 UINT32 TxDmaIdx;
1063 UINT32 TxSwFreeIdx; // software next free tx index
1064} RTMP_MGMT_RING, *PRTMP_MGMT_RING;
1065
1066//
1067// Statistic counter structure
1068//
1069typedef struct _COUNTER_802_3
1070{
1071 // General Stats
1072 ULONG GoodTransmits;
1073 ULONG GoodReceives;
1074 ULONG TxErrors;
1075 ULONG RxErrors;
1076 ULONG RxNoBuffer;
1077
1078 // Ethernet Stats
1079 ULONG RcvAlignmentErrors;
1080 ULONG OneCollision;
1081 ULONG MoreCollisions;
1082
1083} COUNTER_802_3, *PCOUNTER_802_3;
1084
1085typedef struct _COUNTER_802_11 {
1086 ULONG Length;
1087 LARGE_INTEGER LastTransmittedFragmentCount;
1088 LARGE_INTEGER TransmittedFragmentCount;
1089 LARGE_INTEGER MulticastTransmittedFrameCount;
1090 LARGE_INTEGER FailedCount;
1091 LARGE_INTEGER RetryCount;
1092 LARGE_INTEGER MultipleRetryCount;
1093 LARGE_INTEGER RTSSuccessCount;
1094 LARGE_INTEGER RTSFailureCount;
1095 LARGE_INTEGER ACKFailureCount;
1096 LARGE_INTEGER FrameDuplicateCount;
1097 LARGE_INTEGER ReceivedFragmentCount;
1098 LARGE_INTEGER MulticastReceivedFrameCount;
1099 LARGE_INTEGER FCSErrorCount;
1100} COUNTER_802_11, *PCOUNTER_802_11;
1101
1102typedef struct _COUNTER_RALINK {
1103 ULONG TransmittedByteCount; // both successful and failure, used to calculate TX throughput
1104 ULONG ReceivedByteCount; // both CRC okay and CRC error, used to calculate RX throughput
1105 ULONG BeenDisassociatedCount;
1106 ULONG BadCQIAutoRecoveryCount;
1107 ULONG PoorCQIRoamingCount;
1108 ULONG MgmtRingFullCount;
1109 ULONG RxCountSinceLastNULL;
1110 ULONG RxCount;
1111 ULONG RxRingErrCount;
1112 ULONG KickTxCount;
1113 ULONG TxRingErrCount;
1114 LARGE_INTEGER RealFcsErrCount;
1115 ULONG PendingNdisPacketCount;
1116
1117 ULONG OneSecOsTxCount[NUM_OF_TX_RING];
1118 ULONG OneSecDmaDoneCount[NUM_OF_TX_RING];
1119 UINT32 OneSecTxDoneCount;
1120 ULONG OneSecRxCount;
1121 UINT32 OneSecTxAggregationCount;
1122 UINT32 OneSecRxAggregationCount;
1123
1124 UINT32 OneSecFrameDuplicateCount;
1125
1126
1127 UINT32 OneSecTxNoRetryOkCount;
1128 UINT32 OneSecTxRetryOkCount;
1129 UINT32 OneSecTxFailCount;
1130 UINT32 OneSecFalseCCACnt; // CCA error count, for debug purpose, might move to global counter
1131 UINT32 OneSecRxOkCnt; // RX without error
1132 UINT32 OneSecRxOkDataCnt; // unicast-to-me DATA frame count
1133 UINT32 OneSecRxFcsErrCnt; // CRC error
1134 UINT32 OneSecBeaconSentCnt;
1135 UINT32 LastOneSecTotalTxCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
1136 UINT32 LastOneSecRxOkDataCnt; // OneSecRxOkDataCnt
1137 ULONG DuplicateRcv;
1138 ULONG TxAggCount;
1139 ULONG TxNonAggCount;
1140 ULONG TxAgg1MPDUCount;
1141 ULONG TxAgg2MPDUCount;
1142 ULONG TxAgg3MPDUCount;
1143 ULONG TxAgg4MPDUCount;
1144 ULONG TxAgg5MPDUCount;
1145 ULONG TxAgg6MPDUCount;
1146 ULONG TxAgg7MPDUCount;
1147 ULONG TxAgg8MPDUCount;
1148 ULONG TxAgg9MPDUCount;
1149 ULONG TxAgg10MPDUCount;
1150 ULONG TxAgg11MPDUCount;
1151 ULONG TxAgg12MPDUCount;
1152 ULONG TxAgg13MPDUCount;
1153 ULONG TxAgg14MPDUCount;
1154 ULONG TxAgg15MPDUCount;
1155 ULONG TxAgg16MPDUCount;
1156
1157 LARGE_INTEGER TransmittedOctetsInAMSDU;
1158 LARGE_INTEGER TransmittedAMSDUCount;
1159 LARGE_INTEGER ReceivedOctesInAMSDUCount;
1160 LARGE_INTEGER ReceivedAMSDUCount;
1161 LARGE_INTEGER TransmittedAMPDUCount;
1162 LARGE_INTEGER TransmittedMPDUsInAMPDUCount;
1163 LARGE_INTEGER TransmittedOctetsInAMPDUCount;
1164 LARGE_INTEGER MPDUInReceivedAMPDUCount;
1165} COUNTER_RALINK, *PCOUNTER_RALINK;
1166
1167typedef struct _PID_COUNTER {
1168 ULONG TxAckRequiredCount; // CRC error
1169 ULONG TxAggreCount;
1170 ULONG TxSuccessCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
1171 ULONG LastSuccessRate;
1172} PID_COUNTER, *PPID_COUNTER;
1173
1174typedef struct _COUNTER_DRS {
1175 // to record the each TX rate's quality. 0 is best, the bigger the worse.
1176 USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
1177 UCHAR PER[MAX_STEP_OF_TX_RATE_SWITCH];
1178 UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
1179 ULONG CurrTxRateStableTime; // # of second in current TX rate
1180 BOOLEAN fNoisyEnvironment;
1181 BOOLEAN fLastSecAccordingRSSI;
1182 UCHAR LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
1183 UCHAR LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
1184 ULONG LastTxOkCount;
1185} COUNTER_DRS, *PCOUNTER_DRS;
1186
1187//
1188// Arcfour Structure Added by PaulWu
1189//
1190typedef struct _ARCFOUR
1191{
1192 UINT X;
1193 UINT Y;
1194 UCHAR STATE[256];
1195} ARCFOURCONTEXT, *PARCFOURCONTEXT;
1196
1197// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI too. just copy to TXWI.
1198typedef struct _RECEIVE_SETTING {
1199#ifdef RT_BIG_ENDIAN
1200 USHORT MIMO:1;
1201 USHORT OFDM:1;
1202 USHORT rsv:3;
1203 USHORT STBC:2; //SPACE
1204 USHORT ShortGI:1;
1205 USHORT Mode:2; //channel bandwidth 20MHz or 40 MHz
1206 USHORT NumOfRX:2; // MIMO. WE HAVE 3R
1207#else
1208 USHORT NumOfRX:2; // MIMO. WE HAVE 3R
1209 USHORT Mode:2; //channel bandwidth 20MHz or 40 MHz
1210 USHORT ShortGI:1;
1211 USHORT STBC:2; //SPACE
1212 USHORT rsv:3;
1213 USHORT OFDM:1;
1214 USHORT MIMO:1;
1215#endif
1216 } RECEIVE_SETTING, *PRECEIVE_SETTING;
1217
1218// Shared key data structure
1219typedef struct _WEP_KEY {
1220 UCHAR KeyLen; // Key length for each key, 0: entry is invalid
1221 UCHAR Key[MAX_LEN_OF_KEY]; // right now we implement 4 keys, 128 bits max
1222} WEP_KEY, *PWEP_KEY;
1223
1224typedef struct _CIPHER_KEY {
1225 UCHAR Key[16]; // right now we implement 4 keys, 128 bits max
1226 UCHAR RxMic[8]; // make alignment
1227 UCHAR TxMic[8];
1228 UCHAR TxTsc[6]; // 48bit TSC value
1229 UCHAR RxTsc[6]; // 48bit TSC value
1230 UCHAR CipherAlg; // 0-none, 1:WEP64, 2:WEP128, 3:TKIP, 4:AES, 5:CKIP64, 6:CKIP128
1231 UCHAR KeyLen;
1232#ifdef CONFIG_STA_SUPPORT
1233 UCHAR BssId[6];
1234#endif // CONFIG_STA_SUPPORT //
1235 // Key length for each key, 0: entry is invalid
1236 UCHAR Type; // Indicate Pairwise/Group when reporting MIC error
1237} CIPHER_KEY, *PCIPHER_KEY;
1238
1239typedef struct _BBP_TUNING_STRUCT {
1240 BOOLEAN Enable;
1241 UCHAR FalseCcaCountUpperBound; // 100 per sec
1242 UCHAR FalseCcaCountLowerBound; // 10 per sec
1243 UCHAR R17LowerBound; // specified in E2PROM
1244 UCHAR R17UpperBound; // 0x68 according to David Tung
1245 UCHAR CurrentR17Value;
1246} BBP_TUNING, *PBBP_TUNING;
1247
1248typedef struct _SOFT_RX_ANT_DIVERSITY_STRUCT {
1249 UCHAR EvaluatePeriod; // 0:not evalute status, 1: evaluate status, 2: switching status
1250 UCHAR Pair1PrimaryRxAnt; // 0:Ant-E1, 1:Ant-E2
1251 UCHAR Pair1SecondaryRxAnt; // 0:Ant-E1, 1:Ant-E2
1252 UCHAR Pair2PrimaryRxAnt; // 0:Ant-E3, 1:Ant-E4
1253 UCHAR Pair2SecondaryRxAnt; // 0:Ant-E3, 1:Ant-E4
1254 SHORT Pair1AvgRssi[2]; // AvgRssi[0]:E1, AvgRssi[1]:E2
1255 SHORT Pair2AvgRssi[2]; // AvgRssi[0]:E3, AvgRssi[1]:E4
1256 SHORT Pair1LastAvgRssi; //
1257 SHORT Pair2LastAvgRssi; //
1258 ULONG RcvPktNumWhenEvaluate;
1259 BOOLEAN FirstPktArrivedWhenEvaluate;
1260 RALINK_TIMER_STRUCT RxAntDiversityTimer;
1261} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY;
1262
1263typedef struct _LEAP_AUTH_INFO {
1264 BOOLEAN Enabled; //Ture: Enable LEAP Authentication
1265 BOOLEAN CCKM; //Ture: Use Fast Reauthentication with CCKM
1266 UCHAR Reserve[2];
1267 UCHAR UserName[256]; //LEAP, User name
1268 ULONG UserNameLen;
1269 UCHAR Password[256]; //LEAP, User Password
1270 ULONG PasswordLen;
1271} LEAP_AUTH_INFO, *PLEAP_AUTH_INFO;
1272
1273typedef struct {
1274 UCHAR Addr[MAC_ADDR_LEN];
1275 UCHAR ErrorCode[2]; //00 01-Invalid authentication type
1276 //00 02-Authentication timeout
1277 //00 03-Challenge from AP failed
1278 //00 04-Challenge to AP failed
1279 BOOLEAN Reported;
1280} ROGUEAP_ENTRY, *PROGUEAP_ENTRY;
1281
1282typedef struct {
1283 UCHAR RogueApNr;
1284 ROGUEAP_ENTRY RogueApEntry[MAX_LEN_OF_BSS_TABLE];
1285} ROGUEAP_TABLE, *PROGUEAP_TABLE;
1286
1287typedef struct {
1288 BOOLEAN Enable;
1289 UCHAR Delta;
1290 BOOLEAN PlusSign;
1291} CCK_TX_POWER_CALIBRATE, *PCCK_TX_POWER_CALIBRATE;
1292
1293//
1294// Receive Tuple Cache Format
1295//
1296typedef struct _TUPLE_CACHE {
1297 BOOLEAN Valid;
1298 UCHAR MacAddress[MAC_ADDR_LEN];
1299 USHORT Sequence;
1300 USHORT Frag;
1301} TUPLE_CACHE, *PTUPLE_CACHE;
1302
1303//
1304// Fragment Frame structure
1305//
1306typedef struct _FRAGMENT_FRAME {
1307 PNDIS_PACKET pFragPacket;
1308 ULONG RxSize;
1309 USHORT Sequence;
1310 USHORT LastFrag;
1311 ULONG Flags; // Some extra frame information. bit 0: LLC presented
1312} FRAGMENT_FRAME, *PFRAGMENT_FRAME;
1313
1314
1315//
1316// Packet information for NdisQueryPacket
1317//
1318typedef struct _PACKET_INFO {
1319 UINT PhysicalBufferCount; // Physical breaks of buffer descripor chained
1320 UINT BufferCount ; // Number of Buffer descriptor chained
1321 UINT TotalPacketLength ; // Self explained
1322 PNDIS_BUFFER pFirstBuffer; // Pointer to first buffer descriptor
1323} PACKET_INFO, *PPACKET_INFO;
1324
1325//
1326// Tkip Key structure which RC4 key & MIC calculation
1327//
1328typedef struct _TKIP_KEY_INFO {
1329 UINT nBytesInM; // # bytes in M for MICKEY
1330 ULONG IV16;
1331 ULONG IV32;
1332 ULONG K0; // for MICKEY Low
1333 ULONG K1; // for MICKEY Hig
1334 ULONG L; // Current state for MICKEY
1335 ULONG R; // Current state for MICKEY
1336 ULONG M; // Message accumulator for MICKEY
1337 UCHAR RC4KEY[16];
1338 UCHAR MIC[8];
1339} TKIP_KEY_INFO, *PTKIP_KEY_INFO;
1340
1341//
1342// Private / Misc data, counters for driver internal use
1343//
1344typedef struct __PRIVATE_STRUC {
1345 UINT SystemResetCnt; // System reset counter
1346 UINT TxRingFullCnt; // Tx ring full occurrance number
1347 UINT PhyRxErrCnt; // PHY Rx error count, for debug purpose, might move to global counter
1348 // Variables for WEP encryption / decryption in rtmp_wep.c
1349 UINT FCSCRC32;
1350 ARCFOURCONTEXT WEPCONTEXT;
1351 // Tkip stuff
1352 TKIP_KEY_INFO Tx;
1353 TKIP_KEY_INFO Rx;
1354} PRIVATE_STRUC, *PPRIVATE_STRUC;
1355
1356// structure to tune BBP R66 (BBP TUNING)
1357typedef struct _BBP_R66_TUNING {
1358 BOOLEAN bEnable;
1359 USHORT FalseCcaLowerThreshold; // default 100
1360 USHORT FalseCcaUpperThreshold; // default 512
1361 UCHAR R66Delta;
1362 UCHAR R66CurrentValue;
1363 BOOLEAN R66LowerUpperSelect; //Before LinkUp, Used LowerBound or UpperBound as R66 value.
1364} BBP_R66_TUNING, *PBBP_R66_TUNING;
1365
1366// structure to store channel TX power
1367typedef struct _CHANNEL_TX_POWER {
1368 USHORT RemainingTimeForUse; //unit: sec
1369 UCHAR Channel;
1370#ifdef DOT11N_DRAFT3
1371 BOOLEAN bEffectedChannel; // For BW 40 operating in 2.4GHz , the "effected channel" is the channel that is covered in 40Mhz.
1372#endif // DOT11N_DRAFT3 //
1373 CHAR Power;
1374 CHAR Power2;
1375 UCHAR MaxTxPwr;
1376 UCHAR DfsReq;
1377} CHANNEL_TX_POWER, *PCHANNEL_TX_POWER;
1378
1379// structure to store 802.11j channel TX power
1380typedef struct _CHANNEL_11J_TX_POWER {
1381 UCHAR Channel;
1382 UCHAR BW; // BW_10 or BW_20
1383 CHAR Power;
1384 CHAR Power2;
1385 USHORT RemainingTimeForUse; //unit: sec
1386} CHANNEL_11J_TX_POWER, *PCHANNEL_11J_TX_POWER;
1387
1388typedef enum _ABGBAND_STATE_ {
1389 UNKNOWN_BAND,
1390 BG_BAND,
1391 A_BAND,
1392} ABGBAND_STATE;
1393
1394typedef struct _MLME_STRUCT {
1395#ifdef CONFIG_STA_SUPPORT
1396 // STA state machines
1397 STATE_MACHINE CntlMachine;
1398 STATE_MACHINE AssocMachine;
1399 STATE_MACHINE AuthMachine;
1400 STATE_MACHINE AuthRspMachine;
1401 STATE_MACHINE SyncMachine;
1402 STATE_MACHINE WpaPskMachine;
1403 STATE_MACHINE LeapMachine;
1404 STATE_MACHINE AironetMachine;
1405 STATE_MACHINE_FUNC AssocFunc[ASSOC_FUNC_SIZE];
1406 STATE_MACHINE_FUNC AuthFunc[AUTH_FUNC_SIZE];
1407 STATE_MACHINE_FUNC AuthRspFunc[AUTH_RSP_FUNC_SIZE];
1408 STATE_MACHINE_FUNC SyncFunc[SYNC_FUNC_SIZE];
1409 STATE_MACHINE_FUNC WpaPskFunc[WPA_PSK_FUNC_SIZE];
1410 STATE_MACHINE_FUNC AironetFunc[AIRONET_FUNC_SIZE];
1411#endif // CONFIG_STA_SUPPORT //
1412 STATE_MACHINE_FUNC ActFunc[ACT_FUNC_SIZE];
1413 // Action
1414 STATE_MACHINE ActMachine;
1415
1416
1417#ifdef QOS_DLS_SUPPORT
1418 STATE_MACHINE DlsMachine;
1419 STATE_MACHINE_FUNC DlsFunc[DLS_FUNC_SIZE];
1420#endif // QOS_DLS_SUPPORT //
1421
1422
1423
1424
1425 ULONG ChannelQuality; // 0..100, Channel Quality Indication for Roaming
1426 ULONG Now32; // latch the value of NdisGetSystemUpTime()
1427 ULONG LastSendNULLpsmTime;
1428
1429 BOOLEAN bRunning;
1430 NDIS_SPIN_LOCK TaskLock;
1431 MLME_QUEUE Queue;
1432
1433 UINT ShiftReg;
1434
1435 RALINK_TIMER_STRUCT PeriodicTimer;
1436 RALINK_TIMER_STRUCT APSDPeriodicTimer;
1437 RALINK_TIMER_STRUCT LinkDownTimer;
1438 RALINK_TIMER_STRUCT LinkUpTimer;
1439#ifdef RT2860
1440 UCHAR bPsPollTimerRunning;
1441 RALINK_TIMER_STRUCT PsPollTimer;
1442 RALINK_TIMER_STRUCT RadioOnOffTimer;
1443#endif // RT2860 //
1444 ULONG PeriodicRound;
1445 ULONG OneSecPeriodicRound;
1446
1447 UCHAR RealRxPath;
1448 BOOLEAN bLowThroughput;
1449 BOOLEAN bEnableAutoAntennaCheck;
1450 RALINK_TIMER_STRUCT RxAntEvalTimer;
1451
1452
1453} MLME_STRUCT, *PMLME_STRUCT;
1454
1455// structure for radar detection and channel switch
1456typedef struct _RADAR_DETECT_STRUCT {
1457 UCHAR CSCount; //Channel switch counter
1458 UCHAR CSPeriod; //Channel switch period (beacon count)
1459 UCHAR RDCount; //Radar detection counter
1460 UCHAR RDMode; //Radar Detection mode
1461 UCHAR RDDurRegion; //Radar detection duration region
1462 UCHAR BBPR16;
1463 UCHAR BBPR17;
1464 UCHAR BBPR18;
1465 UCHAR BBPR21;
1466 UCHAR BBPR22;
1467 UCHAR BBPR64;
1468 ULONG InServiceMonitorCount; // unit: sec
1469 UINT8 DfsSessionTime;
1470 BOOLEAN bFastDfs;
1471 UINT8 ChMovingTime;
1472 UINT8 LongPulseRadarTh;
1473} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT;
1474
1475#ifdef CARRIER_DETECTION_SUPPORT
1476typedef enum CD_STATE_n
1477{
1478 CD_NORMAL,
1479 CD_SILENCE,
1480 CD_MAX_STATE
1481} CD_STATE;
1482
1483typedef struct CARRIER_DETECTION_s
1484{
1485 BOOLEAN Enable;
1486 UINT8 CDSessionTime;
1487 UINT8 CDPeriod;
1488 CD_STATE CD_State;
1489} CARRIER_DETECTION, *PCARRIER_DETECTION;
1490#endif // CARRIER_DETECTION_SUPPORT //
1491
1492typedef enum _REC_BLOCKACK_STATUS
1493{
1494 Recipient_NONE=0,
1495 Recipient_USED,
1496 Recipient_HandleRes,
1497 Recipient_Accept
1498} REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS;
1499
1500typedef enum _ORI_BLOCKACK_STATUS
1501{
1502 Originator_NONE=0,
1503 Originator_USED,
1504 Originator_WaitRes,
1505 Originator_Done
1506} ORI_BLOCKACK_STATUS, *PORI_BLOCKACK_STATUS;
1507
1508#ifdef DOT11_N_SUPPORT
1509typedef struct _BA_ORI_ENTRY{
1510 UCHAR Wcid;
1511 UCHAR TID;
1512 UCHAR BAWinSize;
1513 UCHAR Token;
1514// Sequence is to fill every outgoing QoS DATA frame's sequence field in 802.11 header.
1515 USHORT Sequence;
1516 USHORT TimeOutValue;
1517 ORI_BLOCKACK_STATUS ORI_BA_Status;
1518 RALINK_TIMER_STRUCT ORIBATimer;
1519 PVOID pAdapter;
1520} BA_ORI_ENTRY, *PBA_ORI_ENTRY;
1521
1522typedef struct _BA_REC_ENTRY {
1523 UCHAR Wcid;
1524 UCHAR TID;
1525 UCHAR BAWinSize; // 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU.
1526 USHORT LastIndSeq;
1527 USHORT TimeOutValue;
1528 RALINK_TIMER_STRUCT RECBATimer;
1529 ULONG LastIndSeqAtTimer;
1530 ULONG nDropPacket;
1531 ULONG rcvSeq;
1532 REC_BLOCKACK_STATUS REC_BA_Status;
1533 NDIS_SPIN_LOCK RxReRingLock; // Rx Ring spinlock
1534 PVOID pAdapter;
1535 struct reordering_list list;
1536} BA_REC_ENTRY, *PBA_REC_ENTRY;
1537
1538
1539typedef struct {
1540 ULONG numAsRecipient; // I am recipient of numAsRecipient clients. These client are in the BARecEntry[]
1541 ULONG numAsOriginator; // I am originator of numAsOriginator clients. These clients are in the BAOriEntry[]
1542 BA_ORI_ENTRY BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE];
1543 BA_REC_ENTRY BARecEntry[MAX_LEN_OF_BA_REC_TABLE];
1544} BA_TABLE, *PBA_TABLE;
1545
1546//For QureyBATableOID use;
1547typedef struct PACKED _OID_BA_REC_ENTRY{
1548 UCHAR MACAddr[MAC_ADDR_LEN];
1549 UCHAR BaBitmap; // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize
1550 UCHAR rsv;
1551 UCHAR BufSize[8];
1552 REC_BLOCKACK_STATUS REC_BA_Status[8];
1553} OID_BA_REC_ENTRY, *POID_BA_REC_ENTRY;
1554
1555//For QureyBATableOID use;
1556typedef struct PACKED _OID_BA_ORI_ENTRY{
1557 UCHAR MACAddr[MAC_ADDR_LEN];
1558 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
1559 UCHAR rsv;
1560 UCHAR BufSize[8];
1561 ORI_BLOCKACK_STATUS ORI_BA_Status[8];
1562} OID_BA_ORI_ENTRY, *POID_BA_ORI_ENTRY;
1563
1564typedef struct _QUERYBA_TABLE{
1565 OID_BA_ORI_ENTRY BAOriEntry[32];
1566 OID_BA_REC_ENTRY BARecEntry[32];
1567 UCHAR OriNum;// Number of below BAOriEntry
1568 UCHAR RecNum;// Number of below BARecEntry
1569} QUERYBA_TABLE, *PQUERYBA_TABLE;
1570
1571typedef union _BACAP_STRUC {
1572#ifdef RT_BIG_ENDIAN
1573 struct {
1574 UINT32 :4;
1575 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.
1576 UINT32 bHtAdhoc:1; // adhoc can use ht rate.
1577 UINT32 MMPSmode:2; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
1578 UINT32 AmsduSize:1; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
1579 UINT32 AmsduEnable:1; //Enable AMSDU transmisstion
1580 UINT32 MpduDensity:3;
1581 UINT32 Policy:2; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use
1582 UINT32 AutoBA:1; // automatically BA
1583 UINT32 TxBAWinLimit:8;
1584 UINT32 RxBAWinLimit:8;
1585 } field;
1586#else
1587 struct {
1588 UINT32 RxBAWinLimit:8;
1589 UINT32 TxBAWinLimit:8;
1590 UINT32 AutoBA:1; // automatically BA
1591 UINT32 Policy:2; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use
1592 UINT32 MpduDensity:3;
1593 UINT32 AmsduEnable:1; //Enable AMSDU transmisstion
1594 UINT32 AmsduSize:1; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
1595 UINT32 MMPSmode:2; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
1596 UINT32 bHtAdhoc:1; // adhoc can use ht rate.
1597 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.
1598 UINT32 :4;
1599 } field;
1600#endif
1601 UINT32 word;
1602} BACAP_STRUC, *PBACAP_STRUC;
1603#endif // DOT11_N_SUPPORT //
1604
1605//This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second. (Details see MLMEPeriodic)
1606typedef struct _IOT_STRUC {
1607 UCHAR Threshold[2];
1608 UCHAR ReorderTimeOutNum[MAX_LEN_OF_BA_REC_TABLE]; // compare with threshold[0]
1609 UCHAR RefreshNum[MAX_LEN_OF_BA_REC_TABLE]; // compare with threshold[1]
1610 ULONG OneSecInWindowCount;
1611 ULONG OneSecFrameDuplicateCount;
1612 ULONG OneSecOutWindowCount;
1613 UCHAR DelOriAct;
1614 UCHAR DelRecAct;
1615 UCHAR RTSShortProt;
1616 UCHAR RTSLongProt;
1617 BOOLEAN bRTSLongProtOn;
1618#ifdef CONFIG_STA_SUPPORT
1619 BOOLEAN bLastAtheros;
1620 BOOLEAN bCurrentAtheros;
1621 BOOLEAN bNowAtherosBurstOn;
1622 BOOLEAN bNextDisableRxBA;
1623 BOOLEAN bToggle;
1624#endif // CONFIG_STA_SUPPORT //
1625} IOT_STRUC, *PIOT_STRUC;
1626
1627// This is the registry setting for 802.11n transmit setting. Used in advanced page.
1628typedef union _REG_TRANSMIT_SETTING {
1629#ifdef RT_BIG_ENDIAN
1630 struct {
1631 UINT32 rsv:13;
1632 UINT32 EXTCHA:2;
1633 UINT32 HTMODE:1;
1634 UINT32 TRANSNO:2;
1635 UINT32 STBC:1; //SPACE
1636 UINT32 ShortGI:1;
1637 UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
1638 UINT32 TxBF:1; // 3*3
1639 UINT32 rsv0:10;
1640 } field;
1641#else
1642 struct {
1643 UINT32 rsv0:10;
1644 UINT32 TxBF:1;
1645 UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
1646 UINT32 ShortGI:1;
1647 UINT32 STBC:1; //SPACE
1648 UINT32 TRANSNO:2;
1649 UINT32 HTMODE:1;
1650 UINT32 EXTCHA:2;
1651 UINT32 rsv:13;
1652 } field;
1653#endif
1654 UINT32 word;
1655} REG_TRANSMIT_SETTING, *PREG_TRANSMIT_SETTING;
1656
1657typedef union _DESIRED_TRANSMIT_SETTING {
1658#ifdef RT_BIG_ENDIAN
1659 struct {
1660 USHORT rsv:3;
1661 USHORT FixedTxMode:2; // If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
1662 USHORT PhyMode:4;
1663 USHORT MCS:7; // MCS
1664 } field;
1665#else
1666 struct {
1667 USHORT MCS:7; // MCS
1668 USHORT PhyMode:4;
1669 USHORT FixedTxMode:2; // If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
1670 USHORT rsv:3;
1671 } field;
1672#endif
1673 USHORT word;
1674 } DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING;
1675
1676typedef struct {
1677 BOOLEAN IsRecipient;
1678 UCHAR MACAddr[MAC_ADDR_LEN];
1679 UCHAR TID;
1680 UCHAR nMSDU;
1681 USHORT TimeOut;
1682 BOOLEAN bAllTid; // If True, delete all TID for BA sessions with this MACaddr.
1683} OID_ADD_BA_ENTRY, *POID_ADD_BA_ENTRY;
1684
1685//
1686// Multiple SSID structure
1687//
1688#define WLAN_MAX_NUM_OF_TIM ((MAX_LEN_OF_MAC_TABLE >> 3) + 1) /* /8 + 1 */
1689#define WLAN_CT_TIM_BCMC_OFFSET 0 /* unit: 32B */
1690
1691/* clear bcmc TIM bit */
1692#define WLAN_MR_TIM_BCMC_CLEAR(apidx) \
1693 pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] &= ~BIT8[0];
1694
1695/* set bcmc TIM bit */
1696#define WLAN_MR_TIM_BCMC_SET(apidx) \
1697 pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] |= BIT8[0];
1698
1699/* clear a station PS TIM bit */
1700#define WLAN_MR_TIM_BIT_CLEAR(ad_p, apidx, wcid) \
1701 { UCHAR tim_offset = wcid >> 3; \
1702 UCHAR bit_offset = wcid & 0x7; \
1703 ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] &= (~BIT8[bit_offset]); }
1704
1705/* set a station PS TIM bit */
1706#define WLAN_MR_TIM_BIT_SET(ad_p, apidx, wcid) \
1707 { UCHAR tim_offset = wcid >> 3; \
1708 UCHAR bit_offset = wcid & 0x7; \
1709 ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] |= BIT8[bit_offset]; }
1710
1711
1712typedef struct _MULTISSID_STRUCT {
1713 UCHAR Bssid[MAC_ADDR_LEN];
1714 UCHAR SsidLen;
1715 CHAR Ssid[MAX_LEN_OF_SSID];
1716 USHORT CapabilityInfo;
1717
1718 PNET_DEV MSSIDDev;
1719
1720 NDIS_802_11_AUTHENTICATION_MODE AuthMode;
1721 NDIS_802_11_WEP_STATUS WepStatus;
1722 NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
1723 WPA_MIX_PAIR_CIPHER WpaMixPairCipher;
1724
1725 ULONG TxCount;
1726 ULONG RxCount;
1727 ULONG ReceivedByteCount;
1728 ULONG TransmittedByteCount;
1729 ULONG RxErrorCount;
1730 ULONG RxDropCount;
1731
1732 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
1733 RT_HT_PHY_INFO DesiredHtPhyInfo;
1734 DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting. this is for reading registry setting only. not useful.
1735 BOOLEAN bAutoTxRateSwitch;
1736
1737 UCHAR DefaultKeyId;
1738
1739 UCHAR TxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11, ...
1740 UCHAR DesiredRates[MAX_LEN_OF_SUPPORTED_RATES];// OID_802_11_DESIRED_RATES
1741 UCHAR DesiredRatesIndex;
1742 UCHAR MaxTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
1743
1744 UCHAR TimBitmaps[WLAN_MAX_NUM_OF_TIM];
1745
1746 // WPA
1747 UCHAR GMK[32];
1748 UCHAR PMK[32];
1749 UCHAR GTK[32];
1750 BOOLEAN IEEE8021X;
1751 BOOLEAN PreAuth;
1752 UCHAR GNonce[32];
1753 UCHAR PortSecured;
1754 NDIS_802_11_PRIVACY_FILTER PrivacyFilter;
1755 UCHAR BANClass3Data;
1756 ULONG IsolateInterStaTraffic;
1757
1758 UCHAR RSNIE_Len[2];
1759 UCHAR RSN_IE[2][MAX_LEN_OF_RSNIE];
1760
1761
1762 UCHAR TimIELocationInBeacon;
1763 UCHAR CapabilityInfoLocationInBeacon;
1764 // outgoing BEACON frame buffer and corresponding TXWI
1765 // PTXWI_STRUC BeaconTxWI; //
1766 CHAR BeaconBuf[MAX_BEACON_SIZE]; // NOTE: BeaconBuf should be 4-byte aligned
1767
1768 BOOLEAN bHideSsid;
1769 UINT16 StationKeepAliveTime; // unit: second
1770
1771 USHORT VLAN_VID;
1772 USHORT VLAN_Priority;
1773
1774 RT_802_11_ACL AccessControlList;
1775
1776 // EDCA Qos
1777 BOOLEAN bWmmCapable; // 0:disable WMM, 1:enable WMM
1778 BOOLEAN bDLSCapable; // 0:disable DLS, 1:enable DLS
1779
1780 UCHAR DlsPTK[64]; // Due to windows dirver count on meetinghouse to handle 4-way shake
1781
1782 // For 802.1x daemon setting per BSS
1783 UCHAR radius_srv_num;
1784 RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM];
1785
1786#ifdef RTL865X_SOC
1787 unsigned int mylinkid;
1788#endif
1789
1790
1791 UINT32 RcvdConflictSsidCount;
1792 UINT32 RcvdSpoofedAssocRespCount;
1793 UINT32 RcvdSpoofedReassocRespCount;
1794 UINT32 RcvdSpoofedProbeRespCount;
1795 UINT32 RcvdSpoofedBeaconCount;
1796 UINT32 RcvdSpoofedDisassocCount;
1797 UINT32 RcvdSpoofedAuthCount;
1798 UINT32 RcvdSpoofedDeauthCount;
1799 UINT32 RcvdSpoofedUnknownMgmtCount;
1800 UINT32 RcvdReplayAttackCount;
1801
1802 CHAR RssiOfRcvdConflictSsid;
1803 CHAR RssiOfRcvdSpoofedAssocResp;
1804 CHAR RssiOfRcvdSpoofedReassocResp;
1805 CHAR RssiOfRcvdSpoofedProbeResp;
1806 CHAR RssiOfRcvdSpoofedBeacon;
1807 CHAR RssiOfRcvdSpoofedDisassoc;
1808 CHAR RssiOfRcvdSpoofedAuth;
1809 CHAR RssiOfRcvdSpoofedDeauth;
1810 CHAR RssiOfRcvdSpoofedUnknownMgmt;
1811 CHAR RssiOfRcvdReplayAttack;
1812
1813 BOOLEAN bBcnSntReq;
1814 UCHAR BcnBufIdx;
1815} MULTISSID_STRUCT, *PMULTISSID_STRUCT;
1816
1817
1818
1819#ifdef DOT11N_DRAFT3
1820typedef enum _BSS2040COEXIST_FLAG{
1821 BSS_2040_COEXIST_DISABLE = 0,
1822 BSS_2040_COEXIST_TIMER_FIRED = 1,
1823 BSS_2040_COEXIST_INFO_SYNC = 2,
1824 BSS_2040_COEXIST_INFO_NOTIFY = 4,
1825}BSS2040COEXIST_FLAG;
1826#endif // DOT11N_DRAFT3 //
1827
1828// configuration common to OPMODE_AP as well as OPMODE_STA
1829typedef struct _COMMON_CONFIG {
1830
1831 BOOLEAN bCountryFlag;
1832 UCHAR CountryCode[3];
1833 UCHAR Geography;
1834 UCHAR CountryRegion; // Enum of country region, 0:FCC, 1:IC, 2:ETSI, 3:SPAIN, 4:France, 5:MKK, 6:MKK1, 7:Israel
1835 UCHAR CountryRegionForABand; // Enum of country region for A band
1836 UCHAR PhyMode; // PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED
1837 USHORT Dsifs; // in units of usec
1838 ULONG PacketFilter; // Packet filter for receiving
1839
1840 CHAR Ssid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
1841 UCHAR SsidLen; // the actual ssid length in used
1842 UCHAR LastSsidLen; // the actual ssid length in used
1843 CHAR LastSsid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
1844 UCHAR LastBssid[MAC_ADDR_LEN];
1845
1846 UCHAR Bssid[MAC_ADDR_LEN];
1847 USHORT BeaconPeriod;
1848 UCHAR Channel;
1849 UCHAR CentralChannel; // Central Channel when using 40MHz is indicating. not real channel.
1850
1851 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
1852 UCHAR SupRateLen;
1853 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1854 UCHAR ExtRateLen;
1855 UCHAR DesireRate[MAX_LEN_OF_SUPPORTED_RATES]; // OID_802_11_DESIRED_RATES
1856 UCHAR MaxDesiredRate;
1857 UCHAR ExpectedACKRate[MAX_LEN_OF_SUPPORTED_RATES];
1858
1859 ULONG BasicRateBitmap; // backup basic ratebitmap
1860
1861 BOOLEAN bAPSDCapable;
1862 BOOLEAN bInServicePeriod;
1863 BOOLEAN bAPSDAC_BE;
1864 BOOLEAN bAPSDAC_BK;
1865 BOOLEAN bAPSDAC_VI;
1866 BOOLEAN bAPSDAC_VO;
1867 BOOLEAN bNeedSendTriggerFrame;
1868 BOOLEAN bAPSDForcePowerSave; // Force power save mode, should only use in APSD-STAUT
1869 ULONG TriggerTimerCount;
1870 UCHAR MaxSPLength;
1871 UCHAR BBPCurrentBW; // BW_10, BW_20, BW_40
1872 REG_TRANSMIT_SETTING RegTransmitSetting; //registry transmit setting. this is for reading registry setting only. not useful.
1873 UCHAR TxRate; // Same value to fill in TXD. TxRate is 6-bit
1874 UCHAR MaxTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
1875 UCHAR TxRateIndex; // Tx rate index in RateSwitchTable
1876 UCHAR TxRateTableSize; // Valid Tx rate table size in RateSwitchTable
1877 UCHAR MinTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
1878 UCHAR RtsRate; // RATE_xxx
1879 HTTRANSMIT_SETTING MlmeTransmit; // MGMT frame PHY rate setting when operatin at Ht rate.
1880 UCHAR MlmeRate; // RATE_xxx, used to send MLME frames
1881 UCHAR BasicMlmeRate; // Default Rate for sending MLME frames
1882
1883 USHORT RtsThreshold; // in unit of BYTE
1884 USHORT FragmentThreshold; // in unit of BYTE
1885
1886 UCHAR TxPower; // in unit of mW
1887 ULONG TxPowerPercentage; // 0~100 %
1888 ULONG TxPowerDefault; // keep for TxPowerPercentage
1889
1890#ifdef DOT11_N_SUPPORT
1891 BACAP_STRUC BACapability; // NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0
1892 BACAP_STRUC REGBACapability; // NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0
1893#endif // DOT11_N_SUPPORT //
1894 IOT_STRUC IOTestParm; // 802.11n InterOpbility Test Parameter;
1895 ULONG TxPreamble; // Rt802_11PreambleLong, Rt802_11PreambleShort, Rt802_11PreambleAuto
1896 BOOLEAN bUseZeroToDisableFragment; // Microsoft use 0 as disable
1897 ULONG UseBGProtection; // 0: auto, 1: always use, 2: always not use
1898 BOOLEAN bUseShortSlotTime; // 0: disable, 1 - use short slot (9us)
1899 BOOLEAN bEnableTxBurst; // 1: enble TX PACKET BURST, 0: disable TX PACKET BURST
1900 BOOLEAN bAggregationCapable; // 1: enable TX aggregation when the peer supports it
1901 BOOLEAN bPiggyBackCapable; // 1: enable TX piggy-back according MAC's version
1902 BOOLEAN bIEEE80211H; // 1: enable IEEE802.11h spec.
1903 ULONG DisableOLBCDetect; // 0: enable OLBC detect; 1 disable OLBC detect
1904
1905#ifdef DOT11_N_SUPPORT
1906 BOOLEAN bRdg;
1907#endif // DOT11_N_SUPPORT //
1908 BOOLEAN bWmmCapable; // 0:disable WMM, 1:enable WMM
1909 QOS_CAPABILITY_PARM APQosCapability; // QOS capability of the current associated AP
1910 EDCA_PARM APEdcaParm; // EDCA parameters of the current associated AP
1911 QBSS_LOAD_PARM APQbssLoad; // QBSS load of the current associated AP
1912 UCHAR AckPolicy[4]; // ACK policy of the specified AC. see ACK_xxx
1913#ifdef CONFIG_STA_SUPPORT
1914 BOOLEAN bDLSCapable; // 0:disable DLS, 1:enable DLS
1915#endif // CONFIG_STA_SUPPORT //
1916 // a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
1917 // BOOLEAN control, either ON or OFF. These flags should always be accessed via
1918 // OPSTATUS_TEST_FLAG(), OPSTATUS_SET_FLAG(), OP_STATUS_CLEAR_FLAG() macros.
1919 // see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition
1920 ULONG OpStatusFlags;
1921
1922 BOOLEAN NdisRadioStateOff; //For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff.
1923 ABGBAND_STATE BandState; // For setting BBP used on B/G or A mode.
1924
1925 // IEEE802.11H--DFS.
1926 RADAR_DETECT_STRUCT RadarDetect;
1927
1928#ifdef CARRIER_DETECTION_SUPPORT
1929 CARRIER_DETECTION CarrierDetect;
1930#endif // CARRIER_DETECTION_SUPPORT //
1931
1932#ifdef DOT11_N_SUPPORT
1933 // HT
1934 UCHAR BASize; // USer desired BAWindowSize. Should not exceed our max capability
1935 //RT_HT_CAPABILITY SupportedHtPhy;
1936 RT_HT_CAPABILITY DesiredHtPhy;
1937 HT_CAPABILITY_IE HtCapability;
1938 ADD_HT_INFO_IE AddHTInfo; // Useful as AP.
1939 //This IE is used with channel switch announcement element when changing to a new 40MHz.
1940 //This IE is included in channel switch ammouncement frames 7.4.1.5, beacons, probe Rsp.
1941 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
1942
1943#ifdef DOT11N_DRAFT3
1944 UCHAR Bss2040CoexistFlag; // bit 0: bBssCoexistTimerRunning, bit 1: NeedSyncAddHtInfo.
1945 RALINK_TIMER_STRUCT Bss2040CoexistTimer;
1946
1947 //This IE is used for 20/40 BSS Coexistence.
1948 BSS_2040_COEXIST_IE BSS2040CoexistInfo;
1949 // ====== 11n D3.0 =======================>
1950 USHORT Dot11OBssScanPassiveDwell; // Unit : TU. 5~1000
1951 USHORT Dot11OBssScanActiveDwell; // Unit : TU. 10~1000
1952 USHORT Dot11BssWidthTriggerScanInt; // Unit : Second
1953 USHORT Dot11OBssScanPassiveTotalPerChannel; // Unit : TU. 200~10000
1954 USHORT Dot11OBssScanActiveTotalPerChannel; // Unit : TU. 20~10000
1955 USHORT Dot11BssWidthChanTranDelayFactor;
1956 USHORT Dot11OBssScanActivityThre; // Unit : percentage
1957
1958 ULONG Dot11BssWidthChanTranDelay; // multiple of (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
1959 ULONG CountDownCtr; // CountDown Counter from (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
1960
1961 NDIS_SPIN_LOCK TriggerEventTabLock;
1962 BSS_2040_COEXIST_IE LastBSSCoexist2040;
1963 BSS_2040_COEXIST_IE BSSCoexist2040;
1964 TRIGGER_EVENT_TAB TriggerEventTab;
1965 UCHAR ChannelListIdx;
1966 // <====== 11n D3.0 =======================
1967 BOOLEAN bOverlapScanning;
1968#endif // DOT11N_DRAFT3 //
1969
1970 BOOLEAN bHTProtect;
1971 BOOLEAN bMIMOPSEnable;
1972 BOOLEAN bBADecline;
1973 BOOLEAN bDisableReordering;
1974 BOOLEAN bForty_Mhz_Intolerant;
1975 BOOLEAN bExtChannelSwitchAnnouncement;
1976 BOOLEAN bRcvBSSWidthTriggerEvents;
1977 ULONG LastRcvBSSWidthTriggerEventsTime;
1978
1979 UCHAR TxBASize;
1980#endif // DOT11_N_SUPPORT //
1981
1982 // Enable wireless event
1983 BOOLEAN bWirelessEvent;
1984 BOOLEAN bWiFiTest; // Enable this parameter for WiFi test
1985
1986 // Tx & Rx Stream number selection
1987 UCHAR TxStream;
1988 UCHAR RxStream;
1989
1990 // transmit phy mode, trasmit rate for Multicast.
1991#ifdef MCAST_RATE_SPECIFIC
1992 UCHAR McastTransmitMcs;
1993 UCHAR McastTransmitPhyMode;
1994#endif // MCAST_RATE_SPECIFIC //
1995
1996 BOOLEAN bHardwareRadio; // Hardware controlled Radio enabled
1997
1998
1999
2000 NDIS_SPIN_LOCK MeasureReqTabLock;
2001 PMEASURE_REQ_TAB pMeasureReqTab;
2002
2003 NDIS_SPIN_LOCK TpcReqTabLock;
2004 PTPC_REQ_TAB pTpcReqTab;
2005
2006 // transmit phy mode, trasmit rate for Multicast.
2007#ifdef MCAST_RATE_SPECIFIC
2008 HTTRANSMIT_SETTING MCastPhyMode;
2009#endif // MCAST_RATE_SPECIFIC //
2010
2011#ifdef SINGLE_SKU
2012 UINT16 DefineMaxTxPwr;
2013#endif // SINGLE_SKU //
2014
2015
2016} COMMON_CONFIG, *PCOMMON_CONFIG;
2017
2018
2019#ifdef CONFIG_STA_SUPPORT
2020/* Modified by Wu Xi-Kun 4/21/2006 */
2021// STA configuration and status
2022typedef struct _STA_ADMIN_CONFIG {
2023 // GROUP 1 -
2024 // User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
2025 // the user intended configuration, but not necessary fully equal to the final
2026 // settings in ACTIVE BSS after negotiation/compromize with the BSS holder (either
2027 // AP or IBSS holder).
2028 // Once initialized, user configuration can only be changed via OID_xxx
2029 UCHAR BssType; // BSS_INFRA or BSS_ADHOC
2030 USHORT AtimWin; // used when starting a new IBSS
2031
2032 // GROUP 2 -
2033 // User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
2034 // the user intended configuration, and should be always applied to the final
2035 // settings in ACTIVE BSS without compromising with the BSS holder.
2036 // Once initialized, user configuration can only be changed via OID_xxx
2037 UCHAR RssiTrigger;
2038 UCHAR RssiTriggerMode; // RSSI_TRIGGERED_UPON_BELOW_THRESHOLD or RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD
2039 USHORT DefaultListenCount; // default listen count;
2040 ULONG WindowsPowerMode; // Power mode for AC power
2041 ULONG WindowsBatteryPowerMode; // Power mode for battery if exists
2042 BOOLEAN bWindowsACCAMEnable; // Enable CAM power mode when AC on
2043 BOOLEAN bAutoReconnect; // Set to TRUE when setting OID_802_11_SSID with no matching BSSID
2044 ULONG WindowsPowerProfile; // Windows power profile, for NDIS5.1 PnP
2045
2046 // MIB:ieee802dot11.dot11smt(1).dot11StationConfigTable(1)
2047 USHORT Psm; // power management mode (PWR_ACTIVE|PWR_SAVE)
2048 USHORT DisassocReason;
2049 UCHAR DisassocSta[MAC_ADDR_LEN];
2050 USHORT DeauthReason;
2051 UCHAR DeauthSta[MAC_ADDR_LEN];
2052 USHORT AuthFailReason;
2053 UCHAR AuthFailSta[MAC_ADDR_LEN];
2054
2055 NDIS_802_11_PRIVACY_FILTER PrivacyFilter; // PrivacyFilter enum for 802.1X
2056 NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
2057 NDIS_802_11_WEP_STATUS WepStatus;
2058 NDIS_802_11_WEP_STATUS OrigWepStatus; // Original wep status set from OID
2059
2060 // Add to support different cipher suite for WPA2/WPA mode
2061 NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Multicast cipher suite
2062 NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher suite
2063 BOOLEAN bMixCipher; // Indicate current Pair & Group use different cipher suites
2064 USHORT RsnCapability;
2065
2066 NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
2067
2068 UCHAR PMK[32]; // WPA PSK mode PMK
2069 UCHAR PTK[64]; // WPA PSK mode PTK
2070 UCHAR GTK[32]; // GTK from authenticator
2071 BSSID_INFO SavedPMK[PMKID_NO];
2072 UINT SavedPMKNum; // Saved PMKID number
2073
2074 UCHAR DefaultKeyId;
2075
2076
2077 // WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
2078 UCHAR PortSecured;
2079
2080 // For WPA countermeasures
2081 ULONG LastMicErrorTime; // record last MIC error time
2082 ULONG MicErrCnt; // Should be 0, 1, 2, then reset to zero (after disassoiciation).
2083 BOOLEAN bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred.
2084 // For WPA-PSK supplicant state
2085 WPA_STATE WpaState; // Default is SS_NOTUSE and handled by microsoft 802.1x
2086 UCHAR ReplayCounter[8];
2087 UCHAR ANonce[32]; // ANonce for WPA-PSK from aurhenticator
2088 UCHAR SNonce[32]; // SNonce for WPA-PSK
2089
2090 UCHAR LastSNR0; // last received BEACON's SNR
2091 UCHAR LastSNR1; // last received BEACON's SNR for 2nd antenna
2092 RSSI_SAMPLE RssiSample;
2093 ULONG NumOfAvgRssiSample;
2094
2095 ULONG LastBeaconRxTime; // OS's timestamp of the last BEACON RX time
2096 ULONG Last11bBeaconRxTime; // OS's timestamp of the last 11B BEACON RX time
2097 ULONG Last11gBeaconRxTime; // OS's timestamp of the last 11G BEACON RX time
2098 ULONG Last20NBeaconRxTime; // OS's timestamp of the last 20MHz N BEACON RX time
2099
2100 ULONG LastScanTime; // Record last scan time for issue BSSID_SCAN_LIST
2101 ULONG ScanCnt; // Scan counts since most recent SSID, BSSID, SCAN OID request
2102 BOOLEAN bSwRadio; // Software controlled Radio On/Off, TRUE: On
2103 BOOLEAN bHwRadio; // Hardware controlled Radio On/Off, TRUE: On
2104 BOOLEAN bRadio; // Radio state, And of Sw & Hw radio state
2105 BOOLEAN bHardwareRadio; // Hardware controlled Radio enabled
2106 BOOLEAN bShowHiddenSSID; // Show all known SSID in SSID list get operation
2107
2108 BOOLEAN AdhocBOnlyJoined; // Indicate Adhoc B Join.
2109 BOOLEAN AdhocBGJoined; // Indicate Adhoc B/G Join.
2110 BOOLEAN Adhoc20NJoined; // Indicate Adhoc 20MHz N Join.
2111
2112 // New for WPA, windows want us to to keep association information and
2113 // Fixed IEs from last association response
2114 NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo;
2115 USHORT ReqVarIELen; // Length of next VIE include EID & Length
2116 UCHAR ReqVarIEs[MAX_VIE_LEN]; // The content saved here should be little-endian format.
2117 USHORT ResVarIELen; // Length of next VIE include EID & Length
2118 UCHAR ResVarIEs[MAX_VIE_LEN];
2119
2120 UCHAR RSNIE_Len;
2121 UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; // The content saved here should be little-endian format.
2122
2123 // New variables used for CCX 1.0
2124 BOOLEAN bCkipOn;
2125 BOOLEAN bCkipCmicOn;
2126 UCHAR CkipFlag;
2127 UCHAR GIV[3]; //for CCX iv
2128 UCHAR RxSEQ[4];
2129 UCHAR TxSEQ[4];
2130 UCHAR CKIPMIC[4];
2131 UCHAR LeapAuthMode;
2132 LEAP_AUTH_INFO LeapAuthInfo;
2133 UCHAR HashPwd[16];
2134 UCHAR NetworkChallenge[8];
2135 UCHAR NetworkChallengeResponse[24];
2136 UCHAR PeerChallenge[8];
2137
2138 UCHAR PeerChallengeResponse[24];
2139 UCHAR SessionKey[16]; //Network session keys (NSK)
2140 RALINK_TIMER_STRUCT LeapAuthTimer;
2141 ROGUEAP_TABLE RogueApTab; //Cisco CCX1 Rogue AP Detection
2142
2143 // New control flags for CCX
2144 CCX_CONTROL CCXControl; // Master administration state
2145 BOOLEAN CCXEnable; // Actual CCX state
2146 UCHAR CCXScanChannel; // Selected channel for CCX beacon request
2147 USHORT CCXScanTime; // Time out to wait for beacon and probe response
2148 UCHAR CCXReqType; // Current processing CCX request type
2149 BSS_TABLE CCXBssTab; // BSS Table
2150 UCHAR FrameReportBuf[2048]; // Buffer for creating frame report
2151 USHORT FrameReportLen; // Current Frame report length
2152 ULONG CLBusyBytes; // Save the total bytes received durning channel load scan time
2153 USHORT RPIDensity[8]; // Array for RPI density collection
2154 // Start address of each BSS table within FrameReportBuf
2155 // It's important to update the RxPower of the corresponding Bss
2156 USHORT BssReportOffset[MAX_LEN_OF_BSS_TABLE];
2157 USHORT BeaconToken; // Token for beacon report
2158 ULONG LastBssIndex; // Most current reported Bss index
2159 RM_REQUEST_ACTION MeasurementRequest[16]; // Saved measurement request
2160 UCHAR RMReqCnt; // Number of measurement request saved.
2161 UCHAR CurrentRMReqIdx; // Number of measurement request saved.
2162 BOOLEAN ParallelReq; // Parallel measurement, only one request performed,
2163 // It must be the same channel with maximum duration
2164 USHORT ParallelDuration; // Maximum duration for parallel measurement
2165 UCHAR ParallelChannel; // Only one channel with parallel measurement
2166 USHORT IAPPToken; // IAPP dialog token
2167 UCHAR CCXQosECWMin; // Cisco QOS ECWMin for AC 0
2168 UCHAR CCXQosECWMax; // Cisco QOS ECWMax for AC 0
2169 // Hack for channel load and noise histogram parameters
2170 UCHAR NHFactor; // Parameter for Noise histogram
2171 UCHAR CLFactor; // Parameter for channel load
2172
2173 UCHAR KRK[16]; //Key Refresh Key.
2174 UCHAR BTK[32]; //Base Transient Key
2175 BOOLEAN CCKMLinkUpFlag;
2176 ULONG CCKMRN; //(Re)Association request number.
2177 LARGE_INTEGER CCKMBeaconAtJoinTimeStamp; //TSF timer for Re-assocaite to the new AP
2178 UCHAR AironetCellPowerLimit; //in dBm
2179 UCHAR AironetIPAddress[4]; //eg. 192.168.1.1
2180 BOOLEAN CCXAdjacentAPReportFlag; //flag for determining report Assoc Lost time
2181 CHAR CCXAdjacentAPSsid[MAX_LEN_OF_SSID]; //Adjacent AP's SSID report
2182 UCHAR CCXAdjacentAPSsidLen; // the actual ssid length in used
2183 UCHAR CCXAdjacentAPBssid[MAC_ADDR_LEN]; //Adjacent AP's BSSID report
2184 USHORT CCXAdjacentAPChannel;
2185 ULONG CCXAdjacentAPLinkDownTime; //for Spec S32.
2186
2187 RALINK_TIMER_STRUCT StaQuickResponeForRateUpTimer;
2188 BOOLEAN StaQuickResponeForRateUpTimerRunning;
2189
2190 UCHAR DtimCount; // 0.. DtimPeriod-1
2191 UCHAR DtimPeriod; // default = 3
2192
2193#ifdef QOS_DLS_SUPPORT
2194 RT_802_11_DLS DLSEntry[MAX_NUM_OF_DLS_ENTRY];
2195 UCHAR DlsReplayCounter[8];
2196#endif // QOS_DLS_SUPPORT //
2197 ////////////////////////////////////////////////////////////////////////////////////////
2198 // This is only for WHQL test.
2199 BOOLEAN WhqlTest;
2200 ////////////////////////////////////////////////////////////////////////////////////////
2201
2202 RALINK_TIMER_STRUCT WpaDisassocAndBlockAssocTimer;
2203 // Fast Roaming
2204 BOOLEAN bFastRoaming; // 0:disable fast roaming, 1:enable fast roaming
2205 CHAR dBmToRoam; // the condition to roam when receiving Rssi less than this value. It's negative value.
2206
2207#ifdef WPA_SUPPLICANT_SUPPORT
2208 BOOLEAN IEEE8021X;
2209 BOOLEAN IEEE8021x_required_keys;
2210 CIPHER_KEY DesireSharedKey[4]; // Record user desired WEP keys
2211 UCHAR DesireSharedKeyId;
2212
2213 // 0: driver ignores wpa_supplicant
2214 // 1: wpa_supplicant initiates scanning and AP selection
2215 // 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters
2216 UCHAR WpaSupplicantUP;
2217 UCHAR WpaSupplicantScanCount;
2218#endif // WPA_SUPPLICANT_SUPPORT //
2219
2220 CHAR dev_name[16];
2221 USHORT OriDevType;
2222
2223 BOOLEAN bTGnWifiTest;
2224 BOOLEAN bScanReqIsFromWebUI;
2225
2226 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
2227 DESIRED_TRANSMIT_SETTING DesiredTransmitSetting;
2228 RT_HT_PHY_INFO DesiredHtPhyInfo;
2229 BOOLEAN bAutoTxRateSwitch;
2230
2231#ifdef RT2860
2232 UCHAR BBPR3;
2233#endif // RT2860 //
2234
2235#ifdef EXT_BUILD_CHANNEL_LIST
2236 UCHAR IEEE80211dClientMode;
2237 UCHAR StaOriCountryCode[3];
2238 UCHAR StaOriGeography;
2239#endif // EXT_BUILD_CHANNEL_LIST //
2240} STA_ADMIN_CONFIG, *PSTA_ADMIN_CONFIG;
2241
2242// This data structure keep the current active BSS/IBSS's configuration that this STA
2243// had agreed upon joining the network. Which means these parameters are usually decided
2244// by the BSS/IBSS creator instead of user configuration. Data in this data structurre
2245// is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE.
2246// Normally, after SCAN or failed roaming attempts, we need to recover back to
2247// the current active settings.
2248typedef struct _STA_ACTIVE_CONFIG {
2249 USHORT Aid;
2250 USHORT AtimWin; // in kusec; IBSS parameter set element
2251 USHORT CapabilityInfo;
2252 USHORT CfpMaxDuration;
2253 USHORT CfpPeriod;
2254
2255 // Copy supported rate from desired AP's beacon. We are trying to match
2256 // AP's supported and extended rate settings.
2257 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2258 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2259 UCHAR SupRateLen;
2260 UCHAR ExtRateLen;
2261 // Copy supported ht from desired AP's beacon. We are trying to match
2262 RT_HT_PHY_INFO SupportedPhyInfo;
2263 RT_HT_CAPABILITY SupportedHtPhy;
2264} STA_ACTIVE_CONFIG, *PSTA_ACTIVE_CONFIG;
2265#endif // CONFIG_STA_SUPPORT //
2266
2267// ----------- start of AP --------------------------
2268// AUTH-RSP State Machine Aux data structure
2269typedef struct _AP_MLME_AUX {
2270 UCHAR Addr[MAC_ADDR_LEN];
2271 USHORT Alg;
2272 CHAR Challenge[CIPHER_TEXT_LEN];
2273} AP_MLME_AUX, *PAP_MLME_AUX;
2274
2275// structure to define WPA Group Key Rekey Interval
2276typedef struct PACKED _RT_802_11_WPA_REKEY {
2277 ULONG ReKeyMethod; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
2278 ULONG ReKeyInterval; // time-based: seconds, packet-based: kilo-packets
2279} RT_WPA_REKEY,*PRT_WPA_REKEY, RT_802_11_WPA_REKEY, *PRT_802_11_WPA_REKEY;
2280
2281typedef struct _MAC_TABLE_ENTRY {
2282 //Choose 1 from ValidAsWDS and ValidAsCLI to validize.
2283 BOOLEAN ValidAsCLI; // Sta mode, set this TRUE after Linkup,too.
2284 BOOLEAN ValidAsWDS; // This is WDS Entry. only for AP mode.
2285 BOOLEAN ValidAsApCli; //This is a AP-Client entry, only for AP mode which enable AP-Client functions.
2286 BOOLEAN ValidAsMesh;
2287 BOOLEAN ValidAsDls; // This is DLS Entry. only for STA mode.
2288 BOOLEAN isCached;
2289 BOOLEAN bIAmBadAtheros; // Flag if this is Atheros chip that has IOT problem. We need to turn on RTS/CTS protection.
2290
2291 UCHAR EnqueueEapolStartTimerRunning; // Enqueue EAPoL-Start for triggering EAP SM
2292 //jan for wpa
2293 // record which entry revoke MIC Failure , if it leaves the BSS itself, AP won't update aMICFailTime MIB
2294 UCHAR CMTimerRunning;
2295 UCHAR apidx; // MBSS number
2296 UCHAR RSNIE_Len;
2297 UCHAR RSN_IE[MAX_LEN_OF_RSNIE];
2298 UCHAR ANonce[LEN_KEY_DESC_NONCE];
2299 UCHAR R_Counter[LEN_KEY_DESC_REPLAY];
2300 UCHAR PTK[64];
2301 UCHAR ReTryCounter;
2302 RALINK_TIMER_STRUCT RetryTimer;
2303 RALINK_TIMER_STRUCT EnqueueStartForPSKTimer; // A timer which enqueue EAPoL-Start for triggering PSK SM
2304 NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
2305 NDIS_802_11_WEP_STATUS WepStatus;
2306 AP_WPA_STATE WpaState;
2307 GTK_STATE GTKState;
2308 USHORT PortSecured;
2309 NDIS_802_11_PRIVACY_FILTER PrivacyFilter; // PrivacyFilter enum for 802.1X
2310 CIPHER_KEY PairwiseKey;
2311 PVOID pAd;
2312 INT PMKID_CacheIdx;
2313 UCHAR PMKID[LEN_PMKID];
2314
2315
2316 UCHAR Addr[MAC_ADDR_LEN];
2317 UCHAR PsMode;
2318 SST Sst;
2319 AUTH_STATE AuthState; // for SHARED KEY authentication state machine used only
2320 BOOLEAN IsReassocSta; // Indicate whether this is a reassociation procedure
2321 USHORT Aid;
2322 USHORT CapabilityInfo;
2323 UCHAR LastRssi;
2324 ULONG NoDataIdleCount;
2325 UINT16 StationKeepAliveCount; // unit: second
2326 ULONG PsQIdleCount;
2327 QUEUE_HEADER PsQueue;
2328
2329 UINT32 StaConnectTime; // the live time of this station since associated with AP
2330
2331
2332#ifdef DOT11_N_SUPPORT
2333 BOOLEAN bSendBAR;
2334 USHORT NoBADataCountDown;
2335
2336 UINT32 CachedBuf[16]; // UINT (4 bytes) for alignment
2337 UINT TxBFCount; // 3*3
2338#endif // DOT11_N_SUPPORT //
2339 UINT FIFOCount;
2340 UINT DebugFIFOCount;
2341 UINT DebugTxCount;
2342 BOOLEAN bDlsInit;
2343
2344
2345//====================================================
2346//WDS entry needs these
2347// rt2860 add this. if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab
2348 UINT MatchWDSTabIdx;
2349 UCHAR MaxSupportedRate;
2350 UCHAR CurrTxRate;
2351 UCHAR CurrTxRateIndex;
2352 // to record the each TX rate's quality. 0 is best, the bigger the worse.
2353 USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
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} MAC_TABLE_ENTRY, *PMAC_TABLE_ENTRY;
2423
2424typedef struct _MAC_TABLE {
2425 USHORT Size;
2426 MAC_TABLE_ENTRY *Hash[HASH_TABLE_SIZE];
2427 MAC_TABLE_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
2428 QUEUE_HEADER McastPsQueue;
2429 ULONG PsQIdleCount;
2430 BOOLEAN fAnyStationInPsm;
2431 BOOLEAN fAnyStationBadAtheros; // Check if any Station is atheros 802.11n Chip. We need to use RTS/CTS with Atheros 802,.11n chip.
2432 BOOLEAN fAnyTxOPForceDisable; // Check if it is necessary to disable BE TxOP
2433#ifdef DOT11_N_SUPPORT
2434 BOOLEAN fAnyStationIsLegacy; // Check if I use legacy rate to transmit to my BSS Station/
2435 BOOLEAN fAnyStationNonGF; // Check if any Station can't support GF.
2436 BOOLEAN fAnyStation20Only; // Check if any Station can't support GF.
2437 BOOLEAN fAnyStationMIMOPSDynamic; // Check if any Station is MIMO Dynamic
2438 BOOLEAN fAnyBASession; // Check if there is BA session. Force turn on RTS/CTS
2439#endif // DOT11_N_SUPPORT //
2440} MAC_TABLE, *PMAC_TABLE;
2441
2442#ifdef DOT11_N_SUPPORT
2443#define IS_HT_STA(_pMacEntry) \
2444 (_pMacEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX)
2445
2446#define IS_HT_RATE(_pMacEntry) \
2447 (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
2448
2449#define PEER_IS_HT_RATE(_pMacEntry) \
2450 (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
2451#endif // DOT11_N_SUPPORT //
2452
2453typedef struct _WDS_ENTRY {
2454 BOOLEAN Valid;
2455 UCHAR Addr[MAC_ADDR_LEN];
2456 ULONG NoDataIdleCount;
2457 struct _WDS_ENTRY *pNext;
2458} WDS_ENTRY, *PWDS_ENTRY;
2459
2460typedef struct _WDS_TABLE_ENTRY {
2461 USHORT Size;
2462 UCHAR WdsAddr[MAC_ADDR_LEN];
2463 WDS_ENTRY *Hash[HASH_TABLE_SIZE];
2464 WDS_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
2465 UCHAR MaxSupportedRate;
2466 UCHAR CurrTxRate;
2467 USHORT TxQuality[MAX_LEN_OF_SUPPORTED_RATES];
2468 USHORT OneSecTxOkCount;
2469 USHORT OneSecTxRetryOkCount;
2470 USHORT OneSecTxFailCount;
2471 ULONG CurrTxRateStableTime; // # of second in current TX rate
2472 UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
2473} WDS_TABLE_ENTRY, *PWDS_TABLE_ENTRY;
2474
2475typedef struct _RT_802_11_WDS_ENTRY {
2476 PNET_DEV dev;
2477 UCHAR Valid;
2478 UCHAR PhyMode;
2479 UCHAR PeerWdsAddr[MAC_ADDR_LEN];
2480 UCHAR MacTabMatchWCID; // ASIC
2481 NDIS_802_11_WEP_STATUS WepStatus;
2482 UCHAR KeyIdx;
2483 CIPHER_KEY WdsKey;
2484 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
2485 RT_HT_PHY_INFO DesiredHtPhyInfo;
2486 BOOLEAN bAutoTxRateSwitch;
2487 DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting.
2488} RT_802_11_WDS_ENTRY, *PRT_802_11_WDS_ENTRY;
2489
2490typedef struct _WDS_TABLE {
2491 UCHAR Mode;
2492 ULONG Size;
2493 RT_802_11_WDS_ENTRY WdsEntry[MAX_WDS_ENTRY];
2494} WDS_TABLE, *PWDS_TABLE;
2495
2496typedef struct _APCLI_STRUCT {
2497 PNET_DEV dev;
2498#ifdef RTL865X_SOC
2499 unsigned int mylinkid;
2500#endif
2501 BOOLEAN Enable; // Set it as 1 if the apcli interface was configured to "1" or by iwpriv cmd "ApCliEnable"
2502 BOOLEAN Valid; // Set it as 1 if the apcli interface associated success to remote AP.
2503 UCHAR MacTabWCID; //WCID value, which point to the entry of ASIC Mac table.
2504 UCHAR SsidLen;
2505 CHAR Ssid[MAX_LEN_OF_SSID];
2506
2507 UCHAR CfgSsidLen;
2508 CHAR CfgSsid[MAX_LEN_OF_SSID];
2509 UCHAR CfgApCliBssid[ETH_LENGTH_OF_ADDRESS];
2510 UCHAR CurrentAddress[ETH_LENGTH_OF_ADDRESS];
2511
2512 ULONG ApCliRcvBeaconTime;
2513
2514 ULONG CtrlCurrState;
2515 ULONG SyncCurrState;
2516 ULONG AuthCurrState;
2517 ULONG AssocCurrState;
2518 ULONG WpaPskCurrState;
2519
2520 USHORT AuthReqCnt;
2521 USHORT AssocReqCnt;
2522
2523 ULONG ClientStatusFlags;
2524 UCHAR MpduDensity;
2525
2526 NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
2527 NDIS_802_11_WEP_STATUS WepStatus;
2528
2529 // Add to support different cipher suite for WPA2/WPA mode
2530 NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Multicast cipher suite
2531 NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher suite
2532 BOOLEAN bMixCipher; // Indicate current Pair & Group use different cipher suites
2533 USHORT RsnCapability;
2534
2535 UCHAR PSK[100]; // reserve PSK key material
2536 UCHAR PSKLen;
2537 UCHAR PMK[32]; // WPA PSK mode PMK
2538 UCHAR GTK[32]; // GTK from authenticator
2539
2540 CIPHER_KEY SharedKey[SHARE_KEY_NUM];
2541 UCHAR DefaultKeyId;
2542
2543 // store RSN_IE built by driver
2544 UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; // The content saved here should be convert to little-endian format.
2545 UCHAR RSNIE_Len;
2546
2547 // For WPA countermeasures
2548 ULONG LastMicErrorTime; // record last MIC error time
2549 BOOLEAN bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred.
2550
2551 // For WPA-PSK supplicant state
2552 UCHAR SNonce[32]; // SNonce for WPA-PSK
2553 UCHAR GNonce[32]; // GNonce for WPA-PSK from authenticator
2554
2555#ifdef WSC_AP_SUPPORT
2556 WSC_CTRL WscControl;
2557#endif // WSC_AP_SUPPORT //
2558
2559 HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
2560 RT_HT_PHY_INFO DesiredHtPhyInfo;
2561 BOOLEAN bAutoTxRateSwitch;
2562 DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting.
2563} APCLI_STRUCT, *PAPCLI_STRUCT;
2564
2565// ----------- end of AP ----------------------------
2566
2567#ifdef BLOCK_NET_IF
2568typedef struct _BLOCK_QUEUE_ENTRY
2569{
2570 BOOLEAN SwTxQueueBlockFlag;
2571 LIST_HEADER NetIfList;
2572} BLOCK_QUEUE_ENTRY, *PBLOCK_QUEUE_ENTRY;
2573#endif // BLOCK_NET_IF //
2574
2575struct wificonf
2576{
2577 BOOLEAN bShortGI;
2578 BOOLEAN bGreenField;
2579};
2580
2581
2582
2583
2584typedef struct _INF_PCI_CONFIG
2585{
2586 PUCHAR CSRBaseAddress; // PCI MMIO Base Address, all access will use
2587}INF_PCI_CONFIG;
2588
2589typedef struct _INF_USB_CONFIG
2590{
2591 UINT BulkInEpAddr; // bulk-in endpoint address
2592 UINT BulkOutEpAddr[6]; // bulk-out endpoint address
2593
2594}INF_USB_CONFIG;
2595
2596#ifdef IKANOS_VX_1X0
2597 typedef void (*IkanosWlanTxCbFuncP)(void *, void *);
2598
2599 struct IKANOS_TX_INFO
2600 {
2601 struct net_device *netdev;
2602 IkanosWlanTxCbFuncP *fp;
2603 };
2604#endif // IKANOS_VX_1X0 //
2605
2606#ifdef NINTENDO_AP
2607typedef struct _NINDO_CTRL_BLOCK {
2608
2609 RT_NINTENDO_TABLE DS_TABLE;
2610
2611#ifdef CHIP25XX
2612 spinlock_t NINTENDO_TABLE_Lock;
2613#else
2614 NDIS_SPIN_LOCK NINTENDO_TABLE_Lock;
2615#endif // CHIP25XX //
2616
2617 UCHAR NINTENDO_UP_BUFFER[512];
2618 UCHAR Local_KeyIdx;
2619 CIPHER_KEY Local_SharedKey;
2620 UCHAR Local_bHideSsid;
2621 UCHAR Local_AuthMode;
2622 UCHAR Local_WepStatus;
2623 USHORT Local_CapabilityInfo;
2624} NINDO_CTRL_BLOCK;
2625#endif // NINTENDO_AP //
2626
2627
2628#ifdef DBG_DIAGNOSE
2629#define DIAGNOSE_TIME 10 // 10 sec
2630typedef struct _RtmpDiagStrcut_
2631{ // Diagnosis Related element
2632 unsigned char inited;
2633 unsigned char qIdx;
2634 unsigned char ArrayStartIdx;
2635 unsigned char ArrayCurIdx;
2636 // Tx Related Count
2637 USHORT TxDataCnt[DIAGNOSE_TIME];
2638 USHORT TxFailCnt[DIAGNOSE_TIME];
2639 USHORT TxDescCnt[DIAGNOSE_TIME][24]; // 3*3 // TxDesc queue length in scale of 0~14, >=15
2640 USHORT TxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
2641 USHORT TxSWQueCnt[DIAGNOSE_TIME][9]; // TxSwQueue length in scale of 0, 1, 2, 3, 4, 5, 6, 7, >=8
2642
2643 USHORT TxAggCnt[DIAGNOSE_TIME];
2644 USHORT TxNonAggCnt[DIAGNOSE_TIME];
2645 USHORT TxAMPDUCnt[DIAGNOSE_TIME][24]; // 3*3 // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
2646 USHORT TxRalinkCnt[DIAGNOSE_TIME]; // TxRalink Aggregation Count in 1 sec scale.
2647 USHORT TxAMSDUCnt[DIAGNOSE_TIME]; // TxAMSUD Aggregation Count in 1 sec scale.
2648
2649 // Rx Related Count
2650 USHORT RxDataCnt[DIAGNOSE_TIME]; // Rx Total Data count.
2651 USHORT RxCrcErrCnt[DIAGNOSE_TIME];
2652 USHORT RxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
2653}RtmpDiagStruct;
2654#endif // DBG_DIAGNOSE //
2655
2656
2657//
2658// The miniport adapter structure
2659//
2660typedef struct _RTMP_ADAPTER
2661{
2662 PVOID OS_Cookie; // save specific structure relative to OS
2663 PNET_DEV net_dev;
2664 ULONG VirtualIfCnt;
2665
2666#ifdef RT2860
2667 USHORT LnkCtrlBitMask;
2668 USHORT RLnkCtrlConfiguration;
2669 USHORT RLnkCtrlOffset;
2670 USHORT HostLnkCtrlConfiguration;
2671 USHORT HostLnkCtrlOffset;
2672 USHORT PCIePowerSaveLevel;
2673 BOOLEAN bPCIclkOff; // flag that indicate if the PICE power status in Configuration SPace..
2674 BOOLEAN bPCIclkOffDisableTx; //
2675
2676
2677/*****************************************************************************************/
2678/* PCI related parameters */
2679/*****************************************************************************************/
2680 PUCHAR CSRBaseAddress; // PCI MMIO Base Address, all access will use
2681
2682 UINT int_enable_reg;
2683 UINT int_disable_mask;
2684 UINT int_pending;
2685
2686
2687 RTMP_DMABUF TxBufSpace[NUM_OF_TX_RING]; // Shared memory of all 1st pre-allocated TxBuf associated with each TXD
2688 RTMP_DMABUF RxDescRing; // Shared memory for RX descriptors
2689 RTMP_DMABUF TxDescRing[NUM_OF_TX_RING]; // Shared memory for Tx descriptors
2690 RTMP_TX_RING TxRing[NUM_OF_TX_RING]; // AC0~4 + HCCA
2691#endif // RT2860 //
2692
2693
2694 NDIS_SPIN_LOCK irq_lock;
2695 UCHAR irq_disabled;
2696
2697
2698
2699/*****************************************************************************************/
2700 /* Both PCI/USB related parameters */
2701/*****************************************************************************************/
2702
2703
2704/*****************************************************************************************/
2705/* Tx related parameters */
2706/*****************************************************************************************/
2707 BOOLEAN DeQueueRunning[NUM_OF_TX_RING]; // for ensuring RTUSBDeQueuePacket get call once
2708 NDIS_SPIN_LOCK DeQueueLock[NUM_OF_TX_RING];
2709
2710
2711 // resource for software backlog queues
2712 QUEUE_HEADER TxSwQueue[NUM_OF_TX_RING]; // 4 AC + 1 HCCA
2713 NDIS_SPIN_LOCK TxSwQueueLock[NUM_OF_TX_RING]; // TxSwQueue spinlock
2714
2715 RTMP_DMABUF MgmtDescRing; // Shared memory for MGMT descriptors
2716 RTMP_MGMT_RING MgmtRing;
2717 NDIS_SPIN_LOCK MgmtRingLock; // Prio Ring spinlock
2718
2719
2720/*****************************************************************************************/
2721/* Rx related parameters */
2722/*****************************************************************************************/
2723
2724#ifdef RT2860
2725 RTMP_RX_RING RxRing;
2726 NDIS_SPIN_LOCK RxRingLock; // Rx Ring spinlock
2727#endif // RT2860 //
2728
2729
2730
2731/*****************************************************************************************/
2732/* ASIC related parameters */
2733/*****************************************************************************************/
2734 UINT32 MACVersion; // MAC version. Record rt2860C(0x28600100) or rt2860D (0x28600101)..
2735
2736 // ---------------------------
2737 // E2PROM
2738 // ---------------------------
2739 ULONG EepromVersion; // byte 0: version, byte 1: revision, byte 2~3: unused
2740 UCHAR EEPROMAddressNum; // 93c46=6 93c66=8
2741 USHORT EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS];
2742 ULONG FirmwareVersion; // byte 0: Minor version, byte 1: Major version, otherwise unused.
2743
2744 // ---------------------------
2745 // BBP Control
2746 // ---------------------------
2747 UCHAR BbpWriteLatch[140]; // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID
2748 UCHAR BbpRssiToDbmDelta;
2749 BBP_R66_TUNING BbpTuning;
2750
2751 // ----------------------------
2752 // RFIC control
2753 // ----------------------------
2754 UCHAR RfIcType; // RFIC_xxx
2755 ULONG RfFreqOffset; // Frequency offset for channel switching
2756 RTMP_RF_REGS LatchRfRegs; // latch th latest RF programming value since RF IC doesn't support READ
2757
2758 EEPROM_ANTENNA_STRUC Antenna; // Since ANtenna definition is different for a & g. We need to save it for future reference.
2759 EEPROM_NIC_CONFIG2_STRUC NicConfig2;
2760
2761 // This soft Rx Antenna Diversity mechanism is used only when user set
2762 // RX Antenna = DIVERSITY ON
2763 SOFT_RX_ANT_DIVERSITY RxAnt;
2764
2765 UCHAR RFProgSeq;
2766 CHANNEL_TX_POWER TxPower[MAX_NUM_OF_CHANNELS]; // Store Tx power value for all channels.
2767 CHANNEL_TX_POWER ChannelList[MAX_NUM_OF_CHANNELS]; // list all supported channels for site survey
2768 CHANNEL_11J_TX_POWER TxPower11J[MAX_NUM_OF_11JCHANNELS]; // 802.11j channel and bw
2769 CHANNEL_11J_TX_POWER ChannelList11J[MAX_NUM_OF_11JCHANNELS]; // list all supported channels for site survey
2770
2771 UCHAR ChannelListNum; // number of channel in ChannelList[]
2772 UCHAR Bbp94;
2773 BOOLEAN BbpForCCK;
2774 ULONG Tx20MPwrCfgABand[5];
2775 ULONG Tx20MPwrCfgGBand[5];
2776 ULONG Tx40MPwrCfgABand[5];
2777 ULONG Tx40MPwrCfgGBand[5];
2778
2779 BOOLEAN bAutoTxAgcA; // Enable driver auto Tx Agc control
2780 UCHAR TssiRefA; // Store Tssi reference value as 25 temperature.
2781 UCHAR TssiPlusBoundaryA[5]; // Tssi boundary for increase Tx power to compensate.
2782 UCHAR TssiMinusBoundaryA[5]; // Tssi boundary for decrease Tx power to compensate.
2783 UCHAR TxAgcStepA; // Store Tx TSSI delta increment / decrement value
2784 CHAR TxAgcCompensateA; // Store the compensation (TxAgcStep * (idx-1))
2785
2786 BOOLEAN bAutoTxAgcG; // Enable driver auto Tx Agc control
2787 UCHAR TssiRefG; // Store Tssi reference value as 25 temperature.
2788 UCHAR TssiPlusBoundaryG[5]; // Tssi boundary for increase Tx power to compensate.
2789 UCHAR TssiMinusBoundaryG[5]; // Tssi boundary for decrease Tx power to compensate.
2790 UCHAR TxAgcStepG; // Store Tx TSSI delta increment / decrement value
2791 CHAR TxAgcCompensateG; // Store the compensation (TxAgcStep * (idx-1))
2792
2793 //+++For RT2870, the parameteres is start from BGRssiOffset1 ~ BGRssiOffset3
2794 CHAR BGRssiOffset0; // Store B/G RSSI#0 Offset value on EEPROM 0x46h
2795 CHAR BGRssiOffset1; // Store B/G RSSI#1 Offset value
2796 CHAR BGRssiOffset2; // Store B/G RSSI#2 Offset value
2797 //---
2798
2799 //+++For RT2870, the parameteres is start from ARssiOffset1 ~ ARssiOffset3
2800 CHAR ARssiOffset0; // Store A RSSI#0 Offset value on EEPROM 0x4Ah
2801 CHAR ARssiOffset1; // Store A RSSI#1 Offset value
2802 CHAR ARssiOffset2; // Store A RSSI#2 Offset value
2803 //---
2804
2805 CHAR BLNAGain; // Store B/G external LNA#0 value on EEPROM 0x44h
2806 CHAR ALNAGain0; // Store A external LNA#0 value for ch36~64
2807 CHAR ALNAGain1; // Store A external LNA#1 value for ch100~128
2808 CHAR ALNAGain2; // Store A external LNA#2 value for ch132~165
2809
2810 // ----------------------------
2811 // LED control
2812 // ----------------------------
2813 MCU_LEDCS_STRUC LedCntl;
2814 USHORT Led1; // read from EEPROM 0x3c
2815 USHORT Led2; // EEPROM 0x3e
2816 USHORT Led3; // EEPROM 0x40
2817 UCHAR LedIndicatorStregth;
2818 UCHAR RssiSingalstrengthOffet;
2819 BOOLEAN bLedOnScanning;
2820 UCHAR LedStatus;
2821
2822/*****************************************************************************************/
2823/* 802.11 related parameters */
2824/*****************************************************************************************/
2825 // outgoing BEACON frame buffer and corresponding TXD
2826 TXWI_STRUC BeaconTxWI;
2827 PUCHAR BeaconBuf;
2828 USHORT BeaconOffset[HW_BEACON_MAX_COUNT];
2829
2830 // pre-build PS-POLL and NULL frame upon link up. for efficiency purpose.
2831 PSPOLL_FRAME PsPollFrame;
2832 HEADER_802_11 NullFrame;
2833
2834//=========AP===========
2835
2836
2837//=======STA===========
2838#ifdef CONFIG_STA_SUPPORT
2839/* Modified by Wu Xi-Kun 4/21/2006 */
2840 // -----------------------------------------------
2841 // STA specific configuration & operation status
2842 // used only when pAd->OpMode == OPMODE_STA
2843 // -----------------------------------------------
2844 STA_ADMIN_CONFIG StaCfg; // user desired settings
2845 STA_ACTIVE_CONFIG StaActive; // valid only when ADHOC_ON(pAd) || INFRA_ON(pAd)
2846 CHAR nickname[IW_ESSID_MAX_SIZE+1]; // nickname, only used in the iwconfig i/f
2847 NDIS_MEDIA_STATE PreMediaState;
2848#endif // CONFIG_STA_SUPPORT //
2849
2850//=======Common===========
2851 // OP mode: either AP or STA
2852 UCHAR OpMode; // OPMODE_STA, OPMODE_AP
2853
2854 NDIS_MEDIA_STATE IndicateMediaState; // Base on Indication state, default is NdisMediaStateDisConnected
2855
2856 // MAT related parameters
2857
2858 // configuration: read from Registry & E2PROM
2859 BOOLEAN bLocalAdminMAC; // Use user changed MAC
2860 UCHAR PermanentAddress[MAC_ADDR_LEN]; // Factory default MAC address
2861 UCHAR CurrentAddress[MAC_ADDR_LEN]; // User changed MAC address
2862
2863 // ------------------------------------------------------
2864 // common configuration to both OPMODE_STA and OPMODE_AP
2865 // ------------------------------------------------------
2866 COMMON_CONFIG CommonCfg;
2867 MLME_STRUCT Mlme;
2868
2869 // AP needs those vaiables for site survey feature.
2870 MLME_AUX MlmeAux; // temporary settings used during MLME state machine
2871 BSS_TABLE ScanTab; // store the latest SCAN result
2872
2873 //About MacTab, the sta driver will use #0 and #1 for multicast and AP.
2874 MAC_TABLE MacTab; // ASIC on-chip WCID entry table. At TX, ASIC always use key according to this on-chip table.
2875 NDIS_SPIN_LOCK MacTabLock;
2876
2877#ifdef DOT11_N_SUPPORT
2878 BA_TABLE BATable;
2879#endif // DOT11_N_SUPPORT //
2880 NDIS_SPIN_LOCK BATabLock;
2881 RALINK_TIMER_STRUCT RECBATimer;
2882
2883 // encryption/decryption KEY tables
2884 CIPHER_KEY SharedKey[MAX_MBSSID_NUM][4]; // STA always use SharedKey[BSS0][0..3]
2885
2886 // RX re-assembly buffer for fragmentation
2887 FRAGMENT_FRAME FragFrame; // Frame storage for fragment frame
2888
2889 // various Counters
2890 COUNTER_802_3 Counters8023; // 802.3 counters
2891 COUNTER_802_11 WlanCounters; // 802.11 MIB counters
2892 COUNTER_RALINK RalinkCounters; // Ralink propriety counters
2893 COUNTER_DRS DrsCounters; // counters for Dynamic TX Rate Switching
2894 PRIVATE_STRUC PrivateInfo; // Private information & counters
2895
2896 // flags, see fRTMP_ADAPTER_xxx flags
2897 ULONG Flags; // Represent current device status
2898
2899 // current TX sequence #
2900 USHORT Sequence;
2901
2902#ifdef UNDER_CE
2903 NDIS_HANDLE hGiISR;
2904#endif
2905
2906
2907 // Control disconnect / connect event generation
2908 //+++Didn't used anymore
2909 ULONG LinkDownTime;
2910 //---
2911 ULONG LastRxRate;
2912 ULONG LastTxRate;
2913 //+++Used only for Station
2914 BOOLEAN bConfigChanged; // Config Change flag for the same SSID setting
2915 //---
2916
2917 ULONG ExtraInfo; // Extra information for displaying status
2918 ULONG SystemErrorBitmap; // b0: E2PROM version error
2919
2920 //+++Didn't used anymore
2921 ULONG MacIcVersion; // MAC/BBP serial interface issue solved after ver.D
2922 //---
2923
2924 // ---------------------------
2925 // System event log
2926 // ---------------------------
2927 RT_802_11_EVENT_TABLE EventTab;
2928
2929
2930 BOOLEAN HTCEnable;
2931
2932 /*****************************************************************************************/
2933 /* Statistic related parameters */
2934 /*****************************************************************************************/
2935
2936 BOOLEAN bUpdateBcnCntDone;
2937 ULONG watchDogMacDeadlock; // prevent MAC/BBP into deadlock condition
2938 // ----------------------------
2939 // DEBUG paramerts
2940 // ----------------------------
2941 BOOLEAN bBanAllBaSetup;
2942 BOOLEAN bPromiscuous;
2943
2944 // ----------------------------
2945 // rt2860c emulation-use Parameters
2946 // ----------------------------
2947 ULONG rtsaccu[30];
2948 ULONG ctsaccu[30];
2949 ULONG cfendaccu[30];
2950 ULONG bacontent[16];
2951 ULONG rxint[RX_RING_SIZE+1];
2952 UCHAR rcvba[60];
2953 BOOLEAN bLinkAdapt;
2954 BOOLEAN bForcePrintTX;
2955 BOOLEAN bForcePrintRX;
2956 BOOLEAN bDisablescanning; //defined in RT2870 USB
2957 BOOLEAN bStaFifoTest;
2958 BOOLEAN bProtectionTest;
2959 BOOLEAN bHCCATest;
2960 BOOLEAN bGenOneHCCA;
2961 BOOLEAN bBroadComHT;
2962 //+++Following add from RT2870 USB.
2963 ULONG BulkOutReq;
2964 ULONG BulkOutComplete;
2965 ULONG BulkOutCompleteOther;
2966 ULONG BulkOutCompleteCancel; // seems not use now?
2967 ULONG BulkInReq;
2968 ULONG BulkInComplete;
2969 ULONG BulkInCompleteFail;
2970 //---
2971
2972 struct wificonf WIFItestbed;
2973
2974#ifdef RALINK_ATE
2975 ATE_INFO ate;
2976#endif // RALINK_ATE //
2977
2978#ifdef DOT11_N_SUPPORT
2979 struct reordering_mpdu_pool mpdu_blk_pool;
2980#endif // DOT11_N_SUPPORT //
2981
2982 ULONG OneSecondnonBEpackets; // record non BE packets per second
2983
2984#if WIRELESS_EXT >= 12
2985 struct iw_statistics iw_stats;
2986#endif
2987
2988 struct net_device_stats stats;
2989
2990#ifdef BLOCK_NET_IF
2991 BLOCK_QUEUE_ENTRY blockQueueTab[NUM_OF_TX_RING];
2992#endif // BLOCK_NET_IF //
2993
2994
2995
2996#ifdef MULTIPLE_CARD_SUPPORT
2997 INT32 MC_RowID;
2998 UCHAR MC_FileName[256];
2999#endif // MULTIPLE_CARD_SUPPORT //
3000
3001 ULONG TbttTickCount;
3002#ifdef PCI_MSI_SUPPORT
3003 BOOLEAN HaveMsi;
3004#endif // PCI_MSI_SUPPORT //
3005
3006
3007 UCHAR is_on;
3008
3009#define TIME_BASE (1000000/OS_HZ)
3010#define TIME_ONE_SECOND (1000000/TIME_BASE)
3011 UCHAR flg_be_adjust;
3012 ULONG be_adjust_last_time;
3013
3014#ifdef NINTENDO_AP
3015 NINDO_CTRL_BLOCK nindo_ctrl_block;
3016#endif // NINTENDO_AP //
3017
3018
3019#ifdef IKANOS_VX_1X0
3020 struct IKANOS_TX_INFO IkanosTxInfo;
3021 struct IKANOS_TX_INFO IkanosRxInfo[MAX_MBSSID_NUM + MAX_WDS_ENTRY + MAX_APCLI_NUM + MAX_MESH_NUM];
3022#endif // IKANOS_VX_1X0 //
3023
3024
3025#ifdef DBG_DIAGNOSE
3026 RtmpDiagStruct DiagStruct;
3027#endif // DBG_DIAGNOSE //
3028
3029
3030 UINT8 PM_FlgSuspend;
3031} RTMP_ADAPTER, *PRTMP_ADAPTER;
3032
3033//
3034// Cisco IAPP format
3035//
3036typedef struct _CISCO_IAPP_CONTENT_
3037{
3038 USHORT Length; //IAPP Length
3039 UCHAR MessageType; //IAPP type
3040 UCHAR FunctionCode; //IAPP function type
3041 UCHAR DestinaionMAC[MAC_ADDR_LEN];
3042 UCHAR SourceMAC[MAC_ADDR_LEN];
3043 USHORT Tag; //Tag(element IE) - Adjacent AP report
3044 USHORT TagLength; //Length of element not including 4 byte header
3045 UCHAR OUI[4]; //0x00, 0x40, 0x96, 0x00
3046 UCHAR PreviousAP[MAC_ADDR_LEN]; //MAC Address of access point
3047 USHORT Channel;
3048 USHORT SsidLen;
3049 UCHAR Ssid[MAX_LEN_OF_SSID];
3050 USHORT Seconds; //Seconds that the client has been disassociated.
3051} CISCO_IAPP_CONTENT, *PCISCO_IAPP_CONTENT;
3052
3053#define DELAYINTMASK 0x0003fffb
3054#define INTMASK 0x0003fffb
3055#define IndMask 0x0003fffc
3056#define RxINT 0x00000005 // Delayed Rx or indivi rx
3057#define TxDataInt 0x000000fa // Delayed Tx or indivi tx
3058#define TxMgmtInt 0x00000102 // Delayed Tx or indivi tx
3059#define TxCoherent 0x00020000 // tx coherent
3060#define RxCoherent 0x00010000 // rx coherent
3061#define McuCommand 0x00000200 // mcu
3062#define PreTBTTInt 0x00001000 // Pre-TBTT interrupt
3063#define TBTTInt 0x00000800 // TBTT interrupt
3064#define GPTimeOutInt 0x00008000 // GPtimeout interrupt
3065#define AutoWakeupInt 0x00004000 // AutoWakeupInt interrupt
3066#define FifoStaFullInt 0x00002000 // fifo statistics full interrupt
3067
3068
3069typedef struct _RX_BLK_
3070{
3071 RT28XX_RXD_STRUC RxD;
3072 PRXWI_STRUC pRxWI;
3073 PHEADER_802_11 pHeader;
3074 PNDIS_PACKET pRxPacket;
3075 UCHAR *pData;
3076 USHORT DataSize;
3077 USHORT Flags;
3078 UCHAR UserPriority; // for calculate TKIP MIC using
3079} RX_BLK;
3080
3081
3082#define RX_BLK_SET_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags |= _flag)
3083#define RX_BLK_TEST_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags & _flag)
3084#define RX_BLK_CLEAR_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags &= ~(_flag))
3085
3086
3087#define fRX_WDS 0x0001
3088#define fRX_AMSDU 0x0002
3089#define fRX_ARALINK 0x0004
3090#define fRX_HTC 0x0008
3091#define fRX_PAD 0x0010
3092#define fRX_AMPDU 0x0020
3093#define fRX_QOS 0x0040
3094#define fRX_INFRA 0x0080
3095#define fRX_EAP 0x0100
3096#define fRX_MESH 0x0200
3097#define fRX_APCLI 0x0400
3098#define fRX_DLS 0x0800
3099#define fRX_WPI 0x1000
3100
3101#define LENGTH_AMSDU_SUBFRAMEHEAD 14
3102#define LENGTH_ARALINK_SUBFRAMEHEAD 14
3103#define LENGTH_ARALINK_HEADER_FIELD 2
3104
3105#define TX_UNKOWN_FRAME 0x00
3106#define TX_MCAST_FRAME 0x01
3107#define TX_LEGACY_FRAME 0x02
3108#define TX_AMPDU_FRAME 0x04
3109#define TX_AMSDU_FRAME 0x08
3110#define TX_RALINK_FRAME 0x10
3111#define TX_FRAG_FRAME 0x20
3112
3113
3114// Currently the sizeof(TX_BLK) is 148 bytes.
3115typedef struct _TX_BLK_
3116{
3117 UCHAR QueIdx;
3118 UCHAR TxFrameType; // Indicate the Transmission type of the all frames in one batch
3119 UCHAR TotalFrameNum; // Total frame number want to send-out in one batch
3120 USHORT TotalFragNum; // Total frame fragments required in one batch
3121 USHORT TotalFrameLen; // Total length of all frames want to send-out in one batch
3122
3123 QUEUE_HEADER TxPacketList;
3124 MAC_TABLE_ENTRY *pMacEntry; // NULL: packet with 802.11 RA field is multicast/broadcast address
3125 HTTRANSMIT_SETTING *pTransmit;
3126
3127 // Following structure used for the characteristics of a specific packet.
3128 PNDIS_PACKET pPacket;
3129 PUCHAR pSrcBufHeader; // Reference to the head of sk_buff->data
3130 PUCHAR pSrcBufData; // Reference to the sk_buff->data, will changed depends on hanlding progresss
3131 UINT SrcBufLen; // Length of packet payload which not including Layer 2 header
3132 PUCHAR pExtraLlcSnapEncap; // NULL means no extra LLC/SNAP is required
3133 UCHAR HeaderBuf[80]; // TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP
3134 UCHAR MpduHeaderLen; // 802.11 header length NOT including the padding
3135 UCHAR HdrPadLen; // recording Header Padding Length;
3136 UCHAR apidx; // The interface associated to this packet
3137 UCHAR Wcid; // The MAC entry associated to this packet
3138 UCHAR UserPriority; // priority class of packet
3139 UCHAR FrameGap; // what kind of IFS this packet use
3140 UCHAR MpduReqNum; // number of fragments of this frame
3141 UCHAR TxRate; // TODO: Obsoleted? Should change to MCS?
3142 UCHAR CipherAlg; // cipher alogrithm
3143 PCIPHER_KEY pKey;
3144
3145
3146
3147 USHORT Flags; //See following definitions for detail.
3148
3149 //YOU SHOULD NOT TOUCH IT! Following parameters are used for hardware-depended layer.
3150 ULONG Priv; // Hardware specific value saved in here.
3151} TX_BLK, *PTX_BLK;
3152
3153
3154#define fTX_bRtsRequired 0x0001 // Indicate if need send RTS frame for protection. Not used in RT2860/RT2870.
3155#define fTX_bAckRequired 0x0002 // the packet need ack response
3156#define fTX_bPiggyBack 0x0004 // Legacy device use Piggback or not
3157#define fTX_bHTRate 0x0008 // allow to use HT rate
3158#define fTX_bForceNonQoS 0x0010 // force to transmit frame without WMM-QoS in HT mode
3159#define fTX_bAllowFrag 0x0020 // allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment
3160#define fTX_bMoreData 0x0040 // there are more data packets in PowerSave Queue
3161#define fTX_bWMM 0x0080 // QOS Data
3162
3163#define fTX_bClearEAPFrame 0x0100
3164
3165#define TX_BLK_ASSIGN_FLAG(_pTxBlk, _flag, value) \
3166 do { \
3167 if (value) \
3168 (_pTxBlk->Flags |= _flag) \
3169 else \
3170 (_pTxBlk->Flags &= ~(_flag)) \
3171 }while(0)
3172
3173#define TX_BLK_SET_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags |= _flag)
3174#define TX_BLK_TEST_FLAG(_pTxBlk, _flag) (((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0)
3175#define TX_BLK_CLEAR_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags &= ~(_flag))
3176
3177
3178
3179
3180
3181//------------------------------------------------------------------------------------------
3182
3183
3184#ifdef RT2860
3185//
3186// Enable & Disable NIC interrupt via writing interrupt mask register
3187// Since it use ADAPTER structure, it have to be put after structure definition.
3188//
3189__inline VOID NICDisableInterrupt(
3190 IN PRTMP_ADAPTER pAd)
3191{
3192 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, 0x0); // 0: disable
3193 //RTMP_IO_WRITE32(pAd, PBF_INT_ENA, 0x0); // 0x418 is for firmware . SW doesn't handle here.
3194 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
3195}
3196
3197__inline VOID NICEnableInterrupt(
3198 IN PRTMP_ADAPTER pAd)
3199{
3200 //
3201 // Flag "fOP_STATUS_DOZE" On, means ASIC put to sleep, else means ASIC WakeUp
3202 // To prevent System hang, we should enalbe the interrupt when
3203 // ASIC is already Wake Up.
3204 //
3205 // RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
3206 // RT2860 => when ASIC is sleeping, MAC register can be read and written.
3207 //if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
3208 {
3209 RTMP_IO_WRITE32(pAd, INT_MASK_CSR, pAd->int_enable_reg /*DELAYINTMASK*/); // 1:enable
3210 }
3211 //else
3212 // DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n"));
3213
3214 //RTMP_IO_WRITE32(pAd, PBF_INT_ENA, 0x00000030); // 1 : enable
3215 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
3216}
3217#endif // RT2860 //
3218
3219#ifdef RT_BIG_ENDIAN
3220static inline VOID WriteBackToDescriptor(
3221 IN PUCHAR Dest,
3222 IN PUCHAR Src,
3223 IN BOOLEAN DoEncrypt,
3224 IN ULONG DescriptorType)
3225{
3226 UINT32 *p1, *p2;
3227
3228 p1 = ((UINT32 *)Dest);
3229 p2 = ((UINT32 *)Src);
3230
3231 *p1 = *p2;
3232 *(p1+2) = *(p2+2);
3233 *(p1+3) = *(p2+3);
3234 *(p1+1) = *(p2+1); // Word 1; this must be written back last
3235}
3236
3237/*
3238 ========================================================================
3239
3240 Routine Description:
3241 Endian conversion of Tx/Rx descriptor .
3242
3243 Arguments:
3244 pAd Pointer to our adapter
3245 pData Pointer to Tx/Rx descriptor
3246 DescriptorType Direction of the frame
3247
3248 Return Value:
3249 None
3250
3251 Note:
3252 Call this function when read or update descriptor
3253 ========================================================================
3254*/
3255static inline VOID RTMPWIEndianChange(
3256 IN PUCHAR pData,
3257 IN ULONG DescriptorType)
3258{
3259 int size;
3260 int i;
3261
3262 size = ((DescriptorType == TYPE_TXWI) ? TXWI_SIZE : RXWI_SIZE);
3263
3264 if(DescriptorType == TYPE_TXWI)
3265 {
3266 *((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData))); // Byte 0~3
3267 *((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData+4))); // Byte 4~7
3268 }
3269 else
3270 {
3271 for(i=0; i < size/4 ; i++)
3272 *(((UINT32 *)pData) +i) = SWAP32(*(((UINT32 *)pData)+i));
3273 }
3274}
3275
3276/*
3277 ========================================================================
3278
3279 Routine Description:
3280 Endian conversion of Tx/Rx descriptor .
3281
3282 Arguments:
3283 pAd Pointer to our adapter
3284 pData Pointer to Tx/Rx descriptor
3285 DescriptorType Direction of the frame
3286
3287 Return Value:
3288 None
3289
3290 Note:
3291 Call this function when read or update descriptor
3292 ========================================================================
3293*/
3294#ifdef RT2860
3295static inline VOID RTMPDescriptorEndianChange(
3296 IN PUCHAR pData,
3297 IN ULONG DescriptorType)
3298{
3299 *((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData))); // Byte 0~3
3300 *((UINT32 *)(pData + 8)) = SWAP32(*((UINT32 *)(pData+8))); // Byte 8~11
3301 *((UINT32 *)(pData +12)) = SWAP32(*((UINT32 *)(pData + 12))); // Byte 12~15
3302 *((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData + 4))); // Byte 4~7, this must be swapped last
3303}
3304#endif // RT2860 //
3305
3306/*
3307 ========================================================================
3308
3309 Routine Description:
3310 Endian conversion of all kinds of 802.11 frames .
3311
3312 Arguments:
3313 pAd Pointer to our adapter
3314 pData Pointer to the 802.11 frame structure
3315 Dir Direction of the frame
3316 FromRxDoneInt Caller is from RxDone interrupt
3317
3318 Return Value:
3319 None
3320
3321 Note:
3322 Call this function when read or update buffer data
3323 ========================================================================
3324*/
3325static inline VOID RTMPFrameEndianChange(
3326 IN PRTMP_ADAPTER pAd,
3327 IN PUCHAR pData,
3328 IN ULONG Dir,
3329 IN BOOLEAN FromRxDoneInt)
3330{
3331 PHEADER_802_11 pFrame;
3332 PUCHAR pMacHdr;
3333
3334 // swab 16 bit fields - Frame Control field
3335 if(Dir == DIR_READ)
3336 {
3337 *(USHORT *)pData = SWAP16(*(USHORT *)pData);
3338 }
3339
3340 pFrame = (PHEADER_802_11) pData;
3341 pMacHdr = (PUCHAR) pFrame;
3342
3343 // swab 16 bit fields - Duration/ID field
3344 *(USHORT *)(pMacHdr + 2) = SWAP16(*(USHORT *)(pMacHdr + 2));
3345
3346 // swab 16 bit fields - Sequence Control field
3347 *(USHORT *)(pMacHdr + 22) = SWAP16(*(USHORT *)(pMacHdr + 22));
3348
3349 if(pFrame->FC.Type == BTYPE_MGMT)
3350 {
3351 switch(pFrame->FC.SubType)
3352 {
3353 case SUBTYPE_ASSOC_REQ:
3354 case SUBTYPE_REASSOC_REQ:
3355 // swab 16 bit fields - CapabilityInfo field
3356 pMacHdr += sizeof(HEADER_802_11);
3357 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3358
3359 // swab 16 bit fields - Listen Interval field
3360 pMacHdr += 2;
3361 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3362 break;
3363
3364 case SUBTYPE_ASSOC_RSP:
3365 case SUBTYPE_REASSOC_RSP:
3366 // swab 16 bit fields - CapabilityInfo field
3367 pMacHdr += sizeof(HEADER_802_11);
3368 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3369
3370 // swab 16 bit fields - Status Code field
3371 pMacHdr += 2;
3372 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3373
3374 // swab 16 bit fields - AID field
3375 pMacHdr += 2;
3376 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3377 break;
3378
3379 case SUBTYPE_AUTH:
3380 // If from APHandleRxDoneInterrupt routine, it is still a encrypt format.
3381 // The convertion is delayed to RTMPHandleDecryptionDoneInterrupt.
3382 if(!FromRxDoneInt && pFrame->FC.Wep == 1)
3383 break;
3384 else
3385 {
3386 // swab 16 bit fields - Auth Alg No. field
3387 pMacHdr += sizeof(HEADER_802_11);
3388 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3389
3390 // swab 16 bit fields - Auth Seq No. field
3391 pMacHdr += 2;
3392 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3393
3394 // swab 16 bit fields - Status Code field
3395 pMacHdr += 2;
3396 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3397 }
3398 break;
3399
3400 case SUBTYPE_BEACON:
3401 case SUBTYPE_PROBE_RSP:
3402 // swab 16 bit fields - BeaconInterval field
3403 pMacHdr += (sizeof(HEADER_802_11) + TIMESTAMP_LEN);
3404 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3405
3406 // swab 16 bit fields - CapabilityInfo field
3407 pMacHdr += sizeof(USHORT);
3408 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3409 break;
3410
3411 case SUBTYPE_DEAUTH:
3412 case SUBTYPE_DISASSOC:
3413 // swab 16 bit fields - Reason code field
3414 pMacHdr += sizeof(HEADER_802_11);
3415 *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
3416 break;
3417 }
3418 }
3419 else if( pFrame->FC.Type == BTYPE_DATA )
3420 {
3421 }
3422 else if(pFrame->FC.Type == BTYPE_CNTL)
3423 {
3424 switch(pFrame->FC.SubType)
3425 {
3426 case SUBTYPE_BLOCK_ACK_REQ:
3427 {
3428 PFRAME_BA_REQ pBAReq = (PFRAME_BA_REQ)pFrame;
3429 *(USHORT *)(&pBAReq->BARControl) = SWAP16(*(USHORT *)(&pBAReq->BARControl));
3430 pBAReq->BAStartingSeq.word = SWAP16(pBAReq->BAStartingSeq.word);
3431 }
3432 break;
3433 case SUBTYPE_BLOCK_ACK:
3434 // For Block Ack packet, the HT_CONTROL field is in the same offset with Addr3
3435 *(UINT32 *)(&pFrame->Addr3[0]) = SWAP32(*(UINT32 *)(&pFrame->Addr3[0]));
3436 break;
3437
3438 case SUBTYPE_ACK:
3439 //For ACK packet, the HT_CONTROL field is in the same offset with Addr2
3440 *(UINT32 *)(&pFrame->Addr2[0])= SWAP32(*(UINT32 *)(&pFrame->Addr2[0]));
3441 break;
3442 }
3443 }
3444 else
3445 {
3446 DBGPRINT(RT_DEBUG_ERROR,("Invalid Frame Type!!!\n"));
3447 }
3448
3449 // swab 16 bit fields - Frame Control
3450 if(Dir == DIR_WRITE)
3451 {
3452 *(USHORT *)pData = SWAP16(*(USHORT *)pData);
3453 }
3454}
3455#endif // RT_BIG_ENDIAN //
3456
3457
3458static inline VOID ConvertMulticastIP2MAC(
3459 IN PUCHAR pIpAddr,
3460 IN PUCHAR *ppMacAddr,
3461 IN UINT16 ProtoType)
3462{
3463 if (pIpAddr == NULL)
3464 return;
3465
3466 if (ppMacAddr == NULL || *ppMacAddr == NULL)
3467 return;
3468
3469 switch (ProtoType)
3470 {
3471 case ETH_P_IPV6:
3472// memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
3473 *(*ppMacAddr) = 0x33;
3474 *(*ppMacAddr + 1) = 0x33;
3475 *(*ppMacAddr + 2) = pIpAddr[12];
3476 *(*ppMacAddr + 3) = pIpAddr[13];
3477 *(*ppMacAddr + 4) = pIpAddr[14];
3478 *(*ppMacAddr + 5) = pIpAddr[15];
3479 break;
3480
3481 case ETH_P_IP:
3482 default:
3483// memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
3484 *(*ppMacAddr) = 0x01;
3485 *(*ppMacAddr + 1) = 0x00;
3486 *(*ppMacAddr + 2) = 0x5e;
3487 *(*ppMacAddr + 3) = pIpAddr[1] & 0x7f;
3488 *(*ppMacAddr + 4) = pIpAddr[2];
3489 *(*ppMacAddr + 5) = pIpAddr[3];
3490 break;
3491 }
3492
3493 return;
3494}
3495
3496BOOLEAN RTMPCheckForHang(
3497 IN NDIS_HANDLE MiniportAdapterContext
3498 );
3499
3500VOID RTMPHalt(
3501 IN NDIS_HANDLE MiniportAdapterContext
3502 );
3503
3504//
3505// Private routines in rtmp_init.c
3506//
3507NDIS_STATUS RTMPAllocAdapterBlock(
3508 IN PVOID handle,
3509 OUT PRTMP_ADAPTER *ppAdapter
3510 );
3511
3512NDIS_STATUS RTMPAllocTxRxRingMemory(
3513 IN PRTMP_ADAPTER pAd
3514 );
3515
3516NDIS_STATUS RTMPFindAdapter(
3517 IN PRTMP_ADAPTER pAd,
3518 IN NDIS_HANDLE WrapperConfigurationContext
3519 );
3520
3521NDIS_STATUS RTMPReadParametersHook(
3522 IN PRTMP_ADAPTER pAd
3523 );
3524
3525VOID RTMPFreeAdapter(
3526 IN PRTMP_ADAPTER pAd
3527 );
3528
3529NDIS_STATUS NICReadRegParameters(
3530 IN PRTMP_ADAPTER pAd,
3531 IN NDIS_HANDLE WrapperConfigurationContext
3532 );
3533
3534
3535VOID NICReadEEPROMParameters(
3536 IN PRTMP_ADAPTER pAd,
3537 IN PUCHAR mac_addr);
3538
3539VOID NICInitAsicFromEEPROM(
3540 IN PRTMP_ADAPTER pAd);
3541
3542VOID NICInitTxRxRingAndBacklogQueue(
3543 IN PRTMP_ADAPTER pAd);
3544
3545NDIS_STATUS NICInitializeAdapter(
3546 IN PRTMP_ADAPTER pAd,
3547 IN BOOLEAN bHardReset);
3548
3549NDIS_STATUS NICInitializeAsic(
3550 IN PRTMP_ADAPTER pAd,
3551 IN BOOLEAN bHardReset);
3552
3553VOID NICIssueReset(
3554 IN PRTMP_ADAPTER pAd);
3555
3556VOID RTMPRingCleanUp(
3557 IN PRTMP_ADAPTER pAd,
3558 IN UCHAR RingType);
3559
3560VOID RxTest(
3561 IN PRTMP_ADAPTER pAd);
3562
3563NDIS_STATUS DbgSendPacket(
3564 IN PRTMP_ADAPTER pAd,
3565 IN PNDIS_PACKET pPacket);
3566
3567VOID UserCfgInit(
3568 IN PRTMP_ADAPTER pAd);
3569
3570VOID NICResetFromError(
3571 IN PRTMP_ADAPTER pAd);
3572
3573VOID NICEraseFirmware(
3574 IN PRTMP_ADAPTER pAd);
3575
3576NDIS_STATUS NICLoadFirmware(
3577 IN PRTMP_ADAPTER pAd);
3578
3579NDIS_STATUS NICLoadRateSwitchingParams(
3580 IN PRTMP_ADAPTER pAd);
3581
3582BOOLEAN NICCheckForHang(
3583 IN PRTMP_ADAPTER pAd);
3584
3585VOID NICUpdateFifoStaCounters(
3586 IN PRTMP_ADAPTER pAd);
3587
3588VOID NICUpdateRawCounters(
3589 IN PRTMP_ADAPTER pAd);
3590
3591ULONG RTMPNotAllZero(
3592 IN PVOID pSrc1,
3593 IN ULONG Length);
3594
3595VOID RTMPZeroMemory(
3596 IN PVOID pSrc,
3597 IN ULONG Length);
3598
3599ULONG RTMPCompareMemory(
3600 IN PVOID pSrc1,
3601 IN PVOID pSrc2,
3602 IN ULONG Length);
3603
3604VOID RTMPMoveMemory(
3605 OUT PVOID pDest,
3606 IN PVOID pSrc,
3607 IN ULONG Length);
3608
3609VOID AtoH(
3610 char *src,
3611 UCHAR *dest,
3612 int destlen);
3613
3614UCHAR BtoH(
3615 char ch);
3616
3617VOID RTMPPatchMacBbpBug(
3618 IN PRTMP_ADAPTER pAd);
3619
3620VOID RTMPPatchCardBus(
3621 IN PRTMP_ADAPTER pAdapter);
3622
3623VOID RTMPPatchRalinkCardBus(
3624 IN PRTMP_ADAPTER pAdapter,
3625 IN ULONG Bus);
3626
3627ULONG RTMPReadCBConfig(
3628 IN ULONG Bus,
3629 IN ULONG Slot,
3630 IN ULONG Func,
3631 IN ULONG Offset);
3632
3633VOID RTMPWriteCBConfig(
3634 IN ULONG Bus,
3635 IN ULONG Slot,
3636 IN ULONG Func,
3637 IN ULONG Offset,
3638 IN ULONG Value);
3639
3640VOID RTMPInitTimer(
3641 IN PRTMP_ADAPTER pAd,
3642 IN PRALINK_TIMER_STRUCT pTimer,
3643 IN PVOID pTimerFunc,
3644 IN PVOID pData,
3645 IN BOOLEAN Repeat);
3646
3647VOID RTMPSetTimer(
3648 IN PRALINK_TIMER_STRUCT pTimer,
3649 IN ULONG Value);
3650
3651
3652VOID RTMPModTimer(
3653 IN PRALINK_TIMER_STRUCT pTimer,
3654 IN ULONG Value);
3655
3656VOID RTMPCancelTimer(
3657 IN PRALINK_TIMER_STRUCT pTimer,
3658 OUT BOOLEAN *pCancelled);
3659
3660VOID RTMPSetLED(
3661 IN PRTMP_ADAPTER pAd,
3662 IN UCHAR Status);
3663
3664VOID RTMPSetSignalLED(
3665 IN PRTMP_ADAPTER pAd,
3666 IN NDIS_802_11_RSSI Dbm);
3667
3668VOID RTMPEnableRxTx(
3669 IN PRTMP_ADAPTER pAd);
3670
3671//
3672// prototype in action.c
3673//
3674VOID ActionStateMachineInit(
3675 IN PRTMP_ADAPTER pAd,
3676 IN STATE_MACHINE *S,
3677 OUT STATE_MACHINE_FUNC Trans[]);
3678
3679VOID MlmeADDBAAction(
3680 IN PRTMP_ADAPTER pAd,
3681 IN MLME_QUEUE_ELEM *Elem);
3682
3683VOID MlmeDELBAAction(
3684 IN PRTMP_ADAPTER pAd,
3685 IN MLME_QUEUE_ELEM *Elem);
3686
3687VOID MlmeDLSAction(
3688 IN PRTMP_ADAPTER pAd,
3689 IN MLME_QUEUE_ELEM *Elem);
3690
3691VOID MlmeInvalidAction(
3692 IN PRTMP_ADAPTER pAd,
3693 IN MLME_QUEUE_ELEM *Elem);
3694
3695VOID MlmeQOSAction(
3696 IN PRTMP_ADAPTER pAd,
3697 IN MLME_QUEUE_ELEM *Elem);
3698
3699#ifdef DOT11_N_SUPPORT
3700VOID PeerAddBAReqAction(
3701 IN PRTMP_ADAPTER pAd,
3702 IN MLME_QUEUE_ELEM *Elem);
3703
3704VOID PeerAddBARspAction(
3705 IN PRTMP_ADAPTER pAd,
3706 IN MLME_QUEUE_ELEM *Elem);
3707
3708VOID PeerDelBAAction(
3709 IN PRTMP_ADAPTER pAd,
3710 IN MLME_QUEUE_ELEM *Elem);
3711
3712VOID PeerBAAction(
3713 IN PRTMP_ADAPTER pAd,
3714 IN MLME_QUEUE_ELEM *Elem);
3715#endif // DOT11_N_SUPPORT //
3716
3717VOID SendPSMPAction(
3718 IN PRTMP_ADAPTER pAd,
3719 IN UCHAR Wcid,
3720 IN UCHAR Psmp);
3721
3722
3723#ifdef DOT11N_DRAFT3
3724VOID SendBSS2040CoexistMgmtAction(
3725 IN PRTMP_ADAPTER pAd,
3726 IN UCHAR Wcid,
3727 IN UCHAR apidx,
3728 IN UCHAR InfoReq);
3729
3730VOID SendNotifyBWActionFrame(
3731 IN PRTMP_ADAPTER pAd,
3732 IN UCHAR Wcid,
3733 IN UCHAR apidx);
3734
3735BOOLEAN ChannelSwitchSanityCheck(
3736 IN PRTMP_ADAPTER pAd,
3737 IN UCHAR Wcid,
3738 IN UCHAR NewChannel,
3739 IN UCHAR Secondary);
3740
3741VOID ChannelSwitchAction(
3742 IN PRTMP_ADAPTER pAd,
3743 IN UCHAR Wcid,
3744 IN UCHAR Channel,
3745 IN UCHAR Secondary);
3746
3747ULONG BuildIntolerantChannelRep(
3748 IN PRTMP_ADAPTER pAd,
3749 IN PUCHAR pDest);
3750
3751VOID Update2040CoexistFrameAndNotify(
3752 IN PRTMP_ADAPTER pAd,
3753 IN UCHAR Wcid,
3754 IN BOOLEAN bAddIntolerantCha);
3755
3756VOID Send2040CoexistAction(
3757 IN PRTMP_ADAPTER pAd,
3758 IN UCHAR Wcid,
3759 IN BOOLEAN bAddIntolerantCha);
3760#endif // DOT11N_DRAFT3 //
3761
3762VOID PeerRMAction(
3763 IN PRTMP_ADAPTER pAd,
3764 IN MLME_QUEUE_ELEM *Elem);
3765
3766VOID PeerPublicAction(
3767 IN PRTMP_ADAPTER pAd,
3768 IN MLME_QUEUE_ELEM *Elem);
3769
3770#ifdef CONFIG_STA_SUPPORT
3771VOID StaPublicAction(
3772 IN PRTMP_ADAPTER pAd,
3773 IN UCHAR Bss2040Coexist);
3774#endif // CONFIG_STA_SUPPORT //
3775
3776
3777VOID PeerBSSTranAction(
3778 IN PRTMP_ADAPTER pAd,
3779 IN MLME_QUEUE_ELEM *Elem);
3780
3781#ifdef DOT11_N_SUPPORT
3782VOID PeerHTAction(
3783 IN PRTMP_ADAPTER pAd,
3784 IN MLME_QUEUE_ELEM *Elem);
3785#endif // DOT11_N_SUPPORT //
3786
3787VOID PeerQOSAction(
3788 IN PRTMP_ADAPTER pAd,
3789 IN MLME_QUEUE_ELEM *Elem);
3790
3791#ifdef QOS_DLS_SUPPORT
3792VOID PeerDLSAction(
3793 IN PRTMP_ADAPTER pAd,
3794 IN MLME_QUEUE_ELEM *Elem);
3795#endif // QOS_DLS_SUPPORT //
3796
3797#ifdef CONFIG_STA_SUPPORT
3798#ifdef QOS_DLS_SUPPORT
3799VOID DlsParmFill(
3800 IN PRTMP_ADAPTER pAd,
3801 IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
3802 IN PRT_802_11_DLS pDls,
3803 IN USHORT reason);
3804#endif // QOS_DLS_SUPPORT //
3805#endif // CONFIG_STA_SUPPORT //
3806
3807#ifdef DOT11_N_SUPPORT
3808VOID RECBATimerTimeout(
3809 IN PVOID SystemSpecific1,
3810 IN PVOID FunctionContext,
3811 IN PVOID SystemSpecific2,
3812 IN PVOID SystemSpecific3);
3813
3814VOID ORIBATimerTimeout(
3815 IN PRTMP_ADAPTER pAd);
3816
3817VOID SendRefreshBAR(
3818 IN PRTMP_ADAPTER pAd,
3819 IN MAC_TABLE_ENTRY *pEntry);
3820#endif // DOT11_N_SUPPORT //
3821
3822VOID ActHeaderInit(
3823 IN PRTMP_ADAPTER pAd,
3824 IN OUT PHEADER_802_11 pHdr80211,
3825 IN PUCHAR Addr1,
3826 IN PUCHAR Addr2,
3827 IN PUCHAR Addr3);
3828
3829VOID BarHeaderInit(
3830 IN PRTMP_ADAPTER pAd,
3831 IN OUT PFRAME_BAR pCntlBar,
3832 IN PUCHAR pDA,
3833 IN PUCHAR pSA);
3834
3835VOID InsertActField(
3836 IN PRTMP_ADAPTER pAd,
3837 OUT PUCHAR pFrameBuf,
3838 OUT PULONG pFrameLen,
3839 IN UINT8 Category,
3840 IN UINT8 ActCode);
3841
3842BOOLEAN QosBADataParse(
3843 IN PRTMP_ADAPTER pAd,
3844 IN BOOLEAN bAMSDU,
3845 IN PUCHAR p8023Header,
3846 IN UCHAR WCID,
3847 IN UCHAR TID,
3848 IN USHORT Sequence,
3849 IN UCHAR DataOffset,
3850 IN USHORT Datasize,
3851 IN UINT CurRxIndex);
3852
3853#ifdef DOT11_N_SUPPORT
3854BOOLEAN CntlEnqueueForRecv(
3855 IN PRTMP_ADAPTER pAd,
3856 IN ULONG Wcid,
3857 IN ULONG MsgLen,
3858 IN PFRAME_BA_REQ pMsg);
3859
3860VOID BaAutoManSwitch(
3861 IN PRTMP_ADAPTER pAd);
3862#endif // DOT11_N_SUPPORT //
3863
3864VOID HTIOTCheck(
3865 IN PRTMP_ADAPTER pAd,
3866 IN UCHAR BatRecIdx);
3867
3868//
3869// Private routines in rtmp_data.c
3870//
3871BOOLEAN RTMPHandleRxDoneInterrupt(
3872 IN PRTMP_ADAPTER pAd);
3873
3874VOID RTMPHandleTxDoneInterrupt(
3875 IN PRTMP_ADAPTER pAd);
3876
3877BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
3878 IN PRTMP_ADAPTER pAd,
3879 IN INT_SOURCE_CSR_STRUC TxRingBitmap);
3880
3881VOID RTMPHandleMgmtRingDmaDoneInterrupt(
3882 IN PRTMP_ADAPTER pAd);
3883
3884VOID RTMPHandleTBTTInterrupt(
3885 IN PRTMP_ADAPTER pAd);
3886
3887VOID RTMPHandlePreTBTTInterrupt(
3888 IN PRTMP_ADAPTER pAd);
3889
3890void RTMPHandleTwakeupInterrupt(
3891 IN PRTMP_ADAPTER pAd);
3892
3893VOID RTMPHandleRxCoherentInterrupt(
3894 IN PRTMP_ADAPTER pAd);
3895
3896BOOLEAN TxFrameIsAggregatible(
3897 IN PRTMP_ADAPTER pAd,
3898 IN PUCHAR pPrevAddr1,
3899 IN PUCHAR p8023hdr);
3900
3901BOOLEAN PeerIsAggreOn(
3902 IN PRTMP_ADAPTER pAd,
3903 IN ULONG TxRate,
3904 IN PMAC_TABLE_ENTRY pMacEntry);
3905
3906NDIS_STATUS Sniff2BytesFromNdisBuffer(
3907 IN PNDIS_BUFFER pFirstBuffer,
3908 IN UCHAR DesiredOffset,
3909 OUT PUCHAR pByte0,
3910 OUT PUCHAR pByte1);
3911
3912NDIS_STATUS STASendPacket(
3913 IN PRTMP_ADAPTER pAd,
3914 IN PNDIS_PACKET pPacket);
3915
3916VOID STASendPackets(
3917 IN NDIS_HANDLE MiniportAdapterContext,
3918 IN PPNDIS_PACKET ppPacketArray,
3919 IN UINT NumberOfPackets);
3920
3921VOID RTMPDeQueuePacket(
3922 IN PRTMP_ADAPTER pAd,
3923 IN BOOLEAN bIntContext,
3924 IN UCHAR QueIdx,
3925 IN UCHAR Max_Tx_Packets);
3926
3927NDIS_STATUS RTMPHardTransmit(
3928 IN PRTMP_ADAPTER pAd,
3929 IN PNDIS_PACKET pPacket,
3930 IN UCHAR QueIdx,
3931 OUT PULONG pFreeTXDLeft);
3932
3933NDIS_STATUS STAHardTransmit(
3934 IN PRTMP_ADAPTER pAd,
3935 IN TX_BLK *pTxBlk,
3936 IN UCHAR QueIdx);
3937
3938VOID STARxEAPOLFrameIndicate(
3939 IN PRTMP_ADAPTER pAd,
3940 IN MAC_TABLE_ENTRY *pEntry,
3941 IN RX_BLK *pRxBlk,
3942 IN UCHAR FromWhichBSSID);
3943
3944NDIS_STATUS RTMPFreeTXDRequest(
3945 IN PRTMP_ADAPTER pAd,
3946 IN UCHAR RingType,
3947 IN UCHAR NumberRequired,
3948 IN PUCHAR FreeNumberIs);
3949
3950NDIS_STATUS MlmeHardTransmit(
3951 IN PRTMP_ADAPTER pAd,
3952 IN UCHAR QueIdx,
3953 IN PNDIS_PACKET pPacket);
3954
3955NDIS_STATUS MlmeHardTransmitMgmtRing(
3956 IN PRTMP_ADAPTER pAd,
3957 IN UCHAR QueIdx,
3958 IN PNDIS_PACKET pPacket);
3959
3960NDIS_STATUS MlmeHardTransmitTxRing(
3961 IN PRTMP_ADAPTER pAd,
3962 IN UCHAR QueIdx,
3963 IN PNDIS_PACKET pPacket);
3964
3965USHORT RTMPCalcDuration(
3966 IN PRTMP_ADAPTER pAd,
3967 IN UCHAR Rate,
3968 IN ULONG Size);
3969
3970VOID RTMPWriteTxWI(
3971 IN PRTMP_ADAPTER pAd,
3972 IN PTXWI_STRUC pTxWI,
3973 IN BOOLEAN FRAG,
3974 IN BOOLEAN CFACK,
3975 IN BOOLEAN InsTimestamp,
3976 IN BOOLEAN AMPDU,
3977 IN BOOLEAN Ack,
3978 IN BOOLEAN NSeq, // HW new a sequence.
3979 IN UCHAR BASize,
3980 IN UCHAR WCID,
3981 IN ULONG Length,
3982 IN UCHAR PID,
3983 IN UCHAR TID,
3984 IN UCHAR TxRate,
3985 IN UCHAR Txopmode,
3986 IN BOOLEAN CfAck,
3987 IN HTTRANSMIT_SETTING *pTransmit);
3988
3989
3990VOID RTMPWriteTxWI_Data(
3991 IN PRTMP_ADAPTER pAd,
3992 IN OUT PTXWI_STRUC pTxWI,
3993 IN TX_BLK *pTxBlk);
3994
3995
3996VOID RTMPWriteTxWI_Cache(
3997 IN PRTMP_ADAPTER pAd,
3998 IN OUT PTXWI_STRUC pTxWI,
3999 IN TX_BLK *pTxBlk);
4000
4001VOID RTMPWriteTxDescriptor(
4002 IN PRTMP_ADAPTER pAd,
4003 IN PTXD_STRUC pTxD,
4004 IN BOOLEAN bWIV,
4005 IN UCHAR QSEL);
4006
4007VOID RTMPSuspendMsduTransmission(
4008 IN PRTMP_ADAPTER pAd);
4009
4010VOID RTMPResumeMsduTransmission(
4011 IN PRTMP_ADAPTER pAd);
4012
4013NDIS_STATUS MiniportMMRequest(
4014 IN PRTMP_ADAPTER pAd,
4015 IN UCHAR QueIdx,
4016 IN PUCHAR pData,
4017 IN UINT Length);
4018
4019VOID RTMPSendNullFrame(
4020 IN PRTMP_ADAPTER pAd,
4021 IN UCHAR TxRate,
4022 IN BOOLEAN bQosNull);
4023
4024VOID RTMPSendDisassociationFrame(
4025 IN PRTMP_ADAPTER pAd);
4026
4027VOID RTMPSendRTSFrame(
4028 IN PRTMP_ADAPTER pAd,
4029 IN PUCHAR pDA,
4030 IN unsigned int NextMpduSize,
4031 IN UCHAR TxRate,
4032 IN UCHAR RTSRate,
4033 IN USHORT AckDuration,
4034 IN UCHAR QueIdx,
4035 IN UCHAR FrameGap);
4036
4037
4038NDIS_STATUS RTMPApplyPacketFilter(
4039 IN PRTMP_ADAPTER pAd,
4040 IN PRT28XX_RXD_STRUC pRxD,
4041 IN PHEADER_802_11 pHeader);
4042
4043PQUEUE_HEADER RTMPCheckTxSwQueue(
4044 IN PRTMP_ADAPTER pAd,
4045 OUT UCHAR *QueIdx);
4046
4047#ifdef CONFIG_STA_SUPPORT
4048VOID RTMPReportMicError(
4049 IN PRTMP_ADAPTER pAd,
4050 IN PCIPHER_KEY pWpaKey);
4051
4052VOID WpaMicFailureReportFrame(
4053 IN PRTMP_ADAPTER pAd,
4054 IN MLME_QUEUE_ELEM *Elem);
4055
4056VOID WpaDisassocApAndBlockAssoc(
4057 IN PVOID SystemSpecific1,
4058 IN PVOID FunctionContext,
4059 IN PVOID SystemSpecific2,
4060 IN PVOID SystemSpecific3);
4061#endif // CONFIG_STA_SUPPORT //
4062
4063NDIS_STATUS RTMPCloneNdisPacket(
4064 IN PRTMP_ADAPTER pAd,
4065 IN BOOLEAN pInsAMSDUHdr,
4066 IN PNDIS_PACKET pInPacket,
4067 OUT PNDIS_PACKET *ppOutPacket);
4068
4069NDIS_STATUS RTMPAllocateNdisPacket(
4070 IN PRTMP_ADAPTER pAd,
4071 IN PNDIS_PACKET *pPacket,
4072 IN PUCHAR pHeader,
4073 IN UINT HeaderLen,
4074 IN PUCHAR pData,
4075 IN UINT DataLen);
4076
4077VOID RTMPFreeNdisPacket(
4078 IN PRTMP_ADAPTER pAd,
4079 IN PNDIS_PACKET pPacket);
4080
4081BOOLEAN RTMPFreeTXDUponTxDmaDone(
4082 IN PRTMP_ADAPTER pAd,
4083 IN UCHAR QueIdx);
4084
4085BOOLEAN RTMPCheckDHCPFrame(
4086 IN PRTMP_ADAPTER pAd,
4087 IN PNDIS_PACKET pPacket);
4088
4089
4090BOOLEAN RTMPCheckEtherType(
4091 IN PRTMP_ADAPTER pAd,
4092 IN PNDIS_PACKET pPacket);
4093
4094
4095VOID RTMPCckBbpTuning(
4096 IN PRTMP_ADAPTER pAd,
4097 IN UINT TxRate);
4098
4099//
4100// Private routines in rtmp_wep.c
4101//
4102VOID RTMPInitWepEngine(
4103 IN PRTMP_ADAPTER pAd,
4104 IN PUCHAR pKey,
4105 IN UCHAR KeyId,
4106 IN UCHAR KeyLen,
4107 IN PUCHAR pDest);
4108
4109VOID RTMPEncryptData(
4110 IN PRTMP_ADAPTER pAd,
4111 IN PUCHAR pSrc,
4112 IN PUCHAR pDest,
4113 IN UINT Len);
4114
4115BOOLEAN RTMPDecryptData(
4116 IN PRTMP_ADAPTER pAdapter,
4117 IN PUCHAR pSrc,
4118 IN UINT Len,
4119 IN UINT idx);
4120
4121BOOLEAN RTMPSoftDecryptWEP(
4122 IN PRTMP_ADAPTER pAd,
4123 IN PUCHAR pData,
4124 IN ULONG DataByteCnt,
4125 IN PCIPHER_KEY pGroupKey);
4126
4127VOID RTMPSetICV(
4128 IN PRTMP_ADAPTER pAd,
4129 IN PUCHAR pDest);
4130
4131VOID ARCFOUR_INIT(
4132 IN PARCFOURCONTEXT Ctx,
4133 IN PUCHAR pKey,
4134 IN UINT KeyLen);
4135
4136UCHAR ARCFOUR_BYTE(
4137 IN PARCFOURCONTEXT Ctx);
4138
4139VOID ARCFOUR_DECRYPT(
4140 IN PARCFOURCONTEXT Ctx,
4141 IN PUCHAR pDest,
4142 IN PUCHAR pSrc,
4143 IN UINT Len);
4144
4145VOID ARCFOUR_ENCRYPT(
4146 IN PARCFOURCONTEXT Ctx,
4147 IN PUCHAR pDest,
4148 IN PUCHAR pSrc,
4149 IN UINT Len);
4150
4151VOID WPAARCFOUR_ENCRYPT(
4152 IN PARCFOURCONTEXT Ctx,
4153 IN PUCHAR pDest,
4154 IN PUCHAR pSrc,
4155 IN UINT Len);
4156
4157UINT RTMP_CALC_FCS32(
4158 IN UINT Fcs,
4159 IN PUCHAR Cp,
4160 IN INT Len);
4161
4162//
4163// MLME routines
4164//
4165
4166// Asic/RF/BBP related functions
4167
4168VOID AsicAdjustTxPower(
4169 IN PRTMP_ADAPTER pAd);
4170
4171VOID AsicUpdateProtect(
4172 IN PRTMP_ADAPTER pAd,
4173 IN USHORT OperaionMode,
4174 IN UCHAR SetMask,
4175 IN BOOLEAN bDisableBGProtect,
4176 IN BOOLEAN bNonGFExist);
4177
4178VOID AsicSwitchChannel(
4179 IN PRTMP_ADAPTER pAd,
4180 IN UCHAR Channel,
4181 IN BOOLEAN bScan);
4182
4183VOID AsicLockChannel(
4184 IN PRTMP_ADAPTER pAd,
4185 IN UCHAR Channel) ;
4186
4187VOID AsicAntennaSelect(
4188 IN PRTMP_ADAPTER pAd,
4189 IN UCHAR Channel);
4190
4191VOID AsicAntennaSetting(
4192 IN PRTMP_ADAPTER pAd,
4193 IN ABGBAND_STATE BandState);
4194
4195VOID AsicRfTuningExec(
4196 IN PVOID SystemSpecific1,
4197 IN PVOID FunctionContext,
4198 IN PVOID SystemSpecific2,
4199 IN PVOID SystemSpecific3);
4200
4201#ifdef CONFIG_STA_SUPPORT
4202VOID AsicSleepThenAutoWakeup(
4203 IN PRTMP_ADAPTER pAd,
4204 IN USHORT TbttNumToNextWakeUp);
4205
4206VOID AsicForceSleep(
4207 IN PRTMP_ADAPTER pAd);
4208
4209VOID AsicForceWakeup(
4210 IN PRTMP_ADAPTER pAd,
4211 IN BOOLEAN bFromTx);
4212#endif // CONFIG_STA_SUPPORT //
4213
4214VOID AsicSetBssid(
4215 IN PRTMP_ADAPTER pAd,
4216 IN PUCHAR pBssid);
4217
4218VOID AsicSetMcastWC(
4219 IN PRTMP_ADAPTER pAd);
4220
4221VOID AsicDelWcidTab(
4222 IN PRTMP_ADAPTER pAd,
4223 IN UCHAR Wcid);
4224
4225VOID AsicEnableRDG(
4226 IN PRTMP_ADAPTER pAd);
4227
4228VOID AsicDisableRDG(
4229 IN PRTMP_ADAPTER pAd);
4230
4231VOID AsicDisableSync(
4232 IN PRTMP_ADAPTER pAd);
4233
4234VOID AsicEnableBssSync(
4235 IN PRTMP_ADAPTER pAd);
4236
4237VOID AsicEnableIbssSync(
4238 IN PRTMP_ADAPTER pAd);
4239
4240VOID AsicSetEdcaParm(
4241 IN PRTMP_ADAPTER pAd,
4242 IN PEDCA_PARM pEdcaParm);
4243
4244VOID AsicSetSlotTime(
4245 IN PRTMP_ADAPTER pAd,
4246 IN BOOLEAN bUseShortSlotTime);
4247
4248VOID AsicAddSharedKeyEntry(
4249 IN PRTMP_ADAPTER pAd,
4250 IN UCHAR BssIndex,
4251 IN UCHAR KeyIdx,
4252 IN UCHAR CipherAlg,
4253 IN PUCHAR pKey,
4254 IN PUCHAR pTxMic,
4255 IN PUCHAR pRxMic);
4256
4257VOID AsicRemoveSharedKeyEntry(
4258 IN PRTMP_ADAPTER pAd,
4259 IN UCHAR BssIndex,
4260 IN UCHAR KeyIdx);
4261
4262VOID AsicUpdateWCIDAttribute(
4263 IN PRTMP_ADAPTER pAd,
4264 IN USHORT WCID,
4265 IN UCHAR BssIndex,
4266 IN UCHAR CipherAlg,
4267 IN BOOLEAN bUsePairewiseKeyTable);
4268
4269VOID AsicUpdateWCIDIVEIV(
4270 IN PRTMP_ADAPTER pAd,
4271 IN USHORT WCID,
4272 IN ULONG uIV,
4273 IN ULONG uEIV);
4274
4275VOID AsicUpdateRxWCIDTable(
4276 IN PRTMP_ADAPTER pAd,
4277 IN USHORT WCID,
4278 IN PUCHAR pAddr);
4279
4280VOID AsicAddKeyEntry(
4281 IN PRTMP_ADAPTER pAd,
4282 IN USHORT WCID,
4283 IN UCHAR BssIndex,
4284 IN UCHAR KeyIdx,
4285 IN PCIPHER_KEY pCipherKey,
4286 IN BOOLEAN bUsePairewiseKeyTable,
4287 IN BOOLEAN bTxKey);
4288
4289VOID AsicAddPairwiseKeyEntry(
4290 IN PRTMP_ADAPTER pAd,
4291 IN PUCHAR pAddr,
4292 IN UCHAR WCID,
4293 IN CIPHER_KEY *pCipherKey);
4294
4295VOID AsicRemovePairwiseKeyEntry(
4296 IN PRTMP_ADAPTER pAd,
4297 IN UCHAR BssIdx,
4298 IN UCHAR Wcid);
4299
4300BOOLEAN AsicSendCommandToMcu(
4301 IN PRTMP_ADAPTER pAd,
4302 IN UCHAR Command,
4303 IN UCHAR Token,
4304 IN UCHAR Arg0,
4305 IN UCHAR Arg1);
4306
4307#ifdef RT2860
4308BOOLEAN AsicCheckCommanOk(
4309 IN PRTMP_ADAPTER pAd,
4310 IN UCHAR Command);
4311#endif // RT2860 //
4312
4313VOID MacAddrRandomBssid(
4314 IN PRTMP_ADAPTER pAd,
4315 OUT PUCHAR pAddr);
4316
4317VOID MgtMacHeaderInit(
4318 IN PRTMP_ADAPTER pAd,
4319 IN OUT PHEADER_802_11 pHdr80211,
4320 IN UCHAR SubType,
4321 IN UCHAR ToDs,
4322 IN PUCHAR pDA,
4323 IN PUCHAR pBssid);
4324
4325VOID MlmeRadioOff(
4326 IN PRTMP_ADAPTER pAd);
4327
4328VOID MlmeRadioOn(
4329 IN PRTMP_ADAPTER pAd);
4330
4331
4332VOID BssTableInit(
4333 IN BSS_TABLE *Tab);
4334
4335#ifdef DOT11_N_SUPPORT
4336VOID BATableInit(
4337 IN PRTMP_ADAPTER pAd,
4338 IN BA_TABLE *Tab);
4339#endif // DOT11_N_SUPPORT //
4340
4341ULONG BssTableSearch(
4342 IN BSS_TABLE *Tab,
4343 IN PUCHAR pBssid,
4344 IN UCHAR Channel);
4345
4346ULONG BssSsidTableSearch(
4347 IN BSS_TABLE *Tab,
4348 IN PUCHAR pBssid,
4349 IN PUCHAR pSsid,
4350 IN UCHAR SsidLen,
4351 IN UCHAR Channel);
4352
4353ULONG BssTableSearchWithSSID(
4354 IN BSS_TABLE *Tab,
4355 IN PUCHAR Bssid,
4356 IN PUCHAR pSsid,
4357 IN UCHAR SsidLen,
4358 IN UCHAR Channel);
4359
4360VOID BssTableDeleteEntry(
4361 IN OUT PBSS_TABLE pTab,
4362 IN PUCHAR pBssid,
4363 IN UCHAR Channel);
4364
4365#ifdef DOT11_N_SUPPORT
4366VOID BATableDeleteORIEntry(
4367 IN OUT PRTMP_ADAPTER pAd,
4368 IN BA_ORI_ENTRY *pBAORIEntry);
4369
4370VOID BATableDeleteRECEntry(
4371 IN OUT PRTMP_ADAPTER pAd,
4372 IN BA_REC_ENTRY *pBARECEntry);
4373
4374VOID BATableTearORIEntry(
4375 IN OUT PRTMP_ADAPTER pAd,
4376 IN UCHAR TID,
4377 IN UCHAR Wcid,
4378 IN BOOLEAN bForceDelete,
4379 IN BOOLEAN ALL);
4380
4381VOID BATableTearRECEntry(
4382 IN OUT PRTMP_ADAPTER pAd,
4383 IN UCHAR TID,
4384 IN UCHAR WCID,
4385 IN BOOLEAN ALL);
4386#endif // DOT11_N_SUPPORT //
4387
4388VOID BssEntrySet(
4389 IN PRTMP_ADAPTER pAd,
4390 OUT PBSS_ENTRY pBss,
4391 IN PUCHAR pBssid,
4392 IN CHAR Ssid[],
4393 IN UCHAR SsidLen,
4394 IN UCHAR BssType,
4395 IN USHORT BeaconPeriod,
4396 IN PCF_PARM CfParm,
4397 IN USHORT AtimWin,
4398 IN USHORT CapabilityInfo,
4399 IN UCHAR SupRate[],
4400 IN UCHAR SupRateLen,
4401 IN UCHAR ExtRate[],
4402 IN UCHAR ExtRateLen,
4403 IN HT_CAPABILITY_IE *pHtCapability,
4404 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
4405 IN UCHAR HtCapabilityLen,
4406 IN UCHAR AddHtInfoLen,
4407 IN UCHAR NewExtChanOffset,
4408 IN UCHAR Channel,
4409 IN CHAR Rssi,
4410 IN LARGE_INTEGER TimeStamp,
4411 IN UCHAR CkipFlag,
4412 IN PEDCA_PARM pEdcaParm,
4413 IN PQOS_CAPABILITY_PARM pQosCapability,
4414 IN PQBSS_LOAD_PARM pQbssLoad,
4415 IN USHORT LengthVIE,
4416 IN PNDIS_802_11_VARIABLE_IEs pVIE);
4417
4418ULONG BssTableSetEntry(
4419 IN PRTMP_ADAPTER pAd,
4420 OUT PBSS_TABLE pTab,
4421 IN PUCHAR pBssid,
4422 IN CHAR Ssid[],
4423 IN UCHAR SsidLen,
4424 IN UCHAR BssType,
4425 IN USHORT BeaconPeriod,
4426 IN CF_PARM *CfParm,
4427 IN USHORT AtimWin,
4428 IN USHORT CapabilityInfo,
4429 IN UCHAR SupRate[],
4430 IN UCHAR SupRateLen,
4431 IN UCHAR ExtRate[],
4432 IN UCHAR ExtRateLen,
4433 IN HT_CAPABILITY_IE *pHtCapability,
4434 IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
4435 IN UCHAR HtCapabilityLen,
4436 IN UCHAR AddHtInfoLen,
4437 IN UCHAR NewExtChanOffset,
4438 IN UCHAR Channel,
4439 IN CHAR Rssi,
4440 IN LARGE_INTEGER TimeStamp,
4441 IN UCHAR CkipFlag,
4442 IN PEDCA_PARM pEdcaParm,
4443 IN PQOS_CAPABILITY_PARM pQosCapability,
4444 IN PQBSS_LOAD_PARM pQbssLoad,
4445 IN USHORT LengthVIE,
4446 IN PNDIS_802_11_VARIABLE_IEs pVIE);
4447
4448#ifdef DOT11_N_SUPPORT
4449VOID BATableInsertEntry(
4450 IN PRTMP_ADAPTER pAd,
4451 IN USHORT Aid,
4452 IN USHORT TimeOutValue,
4453 IN USHORT StartingSeq,
4454 IN UCHAR TID,
4455 IN UCHAR BAWinSize,
4456 IN UCHAR OriginatorStatus,
4457 IN BOOLEAN IsRecipient);
4458
4459#ifdef DOT11N_DRAFT3
4460VOID Bss2040CoexistTimeOut(
4461 IN PVOID SystemSpecific1,
4462 IN PVOID FunctionContext,
4463 IN PVOID SystemSpecific2,
4464 IN PVOID SystemSpecific3);
4465
4466
4467VOID TriEventInit(
4468 IN PRTMP_ADAPTER pAd);
4469
4470ULONG TriEventTableSetEntry(
4471 IN PRTMP_ADAPTER pAd,
4472 OUT TRIGGER_EVENT_TAB *Tab,
4473 IN PUCHAR pBssid,
4474 IN HT_CAPABILITY_IE *pHtCapability,
4475 IN UCHAR HtCapabilityLen,
4476 IN UCHAR RegClass,
4477 IN UCHAR ChannelNo);
4478
4479VOID TriEventCounterMaintenance(
4480 IN PRTMP_ADAPTER pAd);
4481#endif // DOT11N_DRAFT3 //
4482#endif // DOT11_N_SUPPORT //
4483
4484VOID BssTableSsidSort(
4485 IN PRTMP_ADAPTER pAd,
4486 OUT BSS_TABLE *OutTab,
4487 IN CHAR Ssid[],
4488 IN UCHAR SsidLen);
4489
4490VOID BssTableSortByRssi(
4491 IN OUT BSS_TABLE *OutTab);
4492
4493VOID BssCipherParse(
4494 IN OUT PBSS_ENTRY pBss);
4495
4496NDIS_STATUS MlmeQueueInit(
4497 IN MLME_QUEUE *Queue);
4498
4499VOID MlmeQueueDestroy(
4500 IN MLME_QUEUE *Queue);
4501
4502BOOLEAN MlmeEnqueue(
4503 IN PRTMP_ADAPTER pAd,
4504 IN ULONG Machine,
4505 IN ULONG MsgType,
4506 IN ULONG MsgLen,
4507 IN VOID *Msg);
4508
4509BOOLEAN MlmeEnqueueForRecv(
4510 IN PRTMP_ADAPTER pAd,
4511 IN ULONG Wcid,
4512 IN ULONG TimeStampHigh,
4513 IN ULONG TimeStampLow,
4514 IN UCHAR Rssi0,
4515 IN UCHAR Rssi1,
4516 IN UCHAR Rssi2,
4517 IN ULONG MsgLen,
4518 IN PVOID Msg,
4519 IN UCHAR Signal);
4520
4521
4522BOOLEAN MlmeDequeue(
4523 IN MLME_QUEUE *Queue,
4524 OUT MLME_QUEUE_ELEM **Elem);
4525
4526VOID MlmeRestartStateMachine(
4527 IN PRTMP_ADAPTER pAd);
4528
4529BOOLEAN MlmeQueueEmpty(
4530 IN MLME_QUEUE *Queue);
4531
4532BOOLEAN MlmeQueueFull(
4533 IN MLME_QUEUE *Queue);
4534
4535BOOLEAN MsgTypeSubst(
4536 IN PRTMP_ADAPTER pAd,
4537 IN PFRAME_802_11 pFrame,
4538 OUT INT *Machine,
4539 OUT INT *MsgType);
4540
4541VOID StateMachineInit(
4542 IN STATE_MACHINE *Sm,
4543 IN STATE_MACHINE_FUNC Trans[],
4544 IN ULONG StNr,
4545 IN ULONG MsgNr,
4546 IN STATE_MACHINE_FUNC DefFunc,
4547 IN ULONG InitState,
4548 IN ULONG Base);
4549
4550VOID StateMachineSetAction(
4551 IN STATE_MACHINE *S,
4552 IN ULONG St,
4553 ULONG Msg,
4554 IN STATE_MACHINE_FUNC F);
4555
4556VOID StateMachinePerformAction(
4557 IN PRTMP_ADAPTER pAd,
4558 IN STATE_MACHINE *S,
4559 IN MLME_QUEUE_ELEM *Elem);
4560
4561VOID Drop(
4562 IN PRTMP_ADAPTER pAd,
4563 IN MLME_QUEUE_ELEM *Elem);
4564
4565VOID AssocStateMachineInit(
4566 IN PRTMP_ADAPTER pAd,
4567 IN STATE_MACHINE *Sm,
4568 OUT STATE_MACHINE_FUNC Trans[]);
4569
4570VOID ReassocTimeout(
4571 IN PVOID SystemSpecific1,
4572 IN PVOID FunctionContext,
4573 IN PVOID SystemSpecific2,
4574 IN PVOID SystemSpecific3);
4575
4576VOID AssocTimeout(
4577 IN PVOID SystemSpecific1,
4578 IN PVOID FunctionContext,
4579 IN PVOID SystemSpecific2,
4580 IN PVOID SystemSpecific3);
4581
4582VOID DisassocTimeout(
4583 IN PVOID SystemSpecific1,
4584 IN PVOID FunctionContext,
4585 IN PVOID SystemSpecific2,
4586 IN PVOID SystemSpecific3);
4587
4588//----------------------------------------------
4589VOID MlmeDisassocReqAction(
4590 IN PRTMP_ADAPTER pAd,
4591 IN MLME_QUEUE_ELEM *Elem);
4592
4593VOID MlmeAssocReqAction(
4594 IN PRTMP_ADAPTER pAd,
4595 IN MLME_QUEUE_ELEM *Elem);
4596
4597VOID MlmeReassocReqAction(
4598 IN PRTMP_ADAPTER pAd,
4599 IN MLME_QUEUE_ELEM *Elem);
4600
4601VOID MlmeDisassocReqAction(
4602 IN PRTMP_ADAPTER pAd,
4603 IN MLME_QUEUE_ELEM *Elem);
4604
4605VOID PeerAssocRspAction(
4606 IN PRTMP_ADAPTER pAd,
4607 IN MLME_QUEUE_ELEM *Elem);
4608
4609VOID PeerReassocRspAction(
4610 IN PRTMP_ADAPTER pAd,
4611 IN MLME_QUEUE_ELEM *Elem);
4612
4613VOID PeerDisassocAction(
4614 IN PRTMP_ADAPTER pAd,
4615 IN MLME_QUEUE_ELEM *Elem);
4616
4617VOID DisassocTimeoutAction(
4618 IN PRTMP_ADAPTER pAd,
4619 IN MLME_QUEUE_ELEM *Elem);
4620
4621VOID AssocTimeoutAction(
4622 IN PRTMP_ADAPTER pAd,
4623 IN MLME_QUEUE_ELEM *Elem);
4624
4625VOID ReassocTimeoutAction(
4626 IN PRTMP_ADAPTER pAd,
4627 IN MLME_QUEUE_ELEM *Elem);
4628
4629VOID Cls3errAction(
4630 IN PRTMP_ADAPTER pAd,
4631 IN PUCHAR pAddr);
4632
4633VOID SwitchBetweenWepAndCkip(
4634 IN PRTMP_ADAPTER pAd);
4635
4636VOID InvalidStateWhenAssoc(
4637 IN PRTMP_ADAPTER pAd,
4638 IN MLME_QUEUE_ELEM *Elem);
4639
4640VOID InvalidStateWhenReassoc(
4641 IN PRTMP_ADAPTER pAd,
4642 IN MLME_QUEUE_ELEM *Elem);
4643
4644VOID InvalidStateWhenDisassociate(
4645 IN PRTMP_ADAPTER pAd,
4646 IN MLME_QUEUE_ELEM *Elem);
4647
4648
4649VOID ComposePsPoll(
4650 IN PRTMP_ADAPTER pAd);
4651
4652VOID ComposeNullFrame(
4653 IN PRTMP_ADAPTER pAd);
4654
4655VOID AssocPostProc(
4656 IN PRTMP_ADAPTER pAd,
4657 IN PUCHAR pAddr2,
4658 IN USHORT CapabilityInfo,
4659 IN USHORT Aid,
4660 IN UCHAR SupRate[],
4661 IN UCHAR SupRateLen,
4662 IN UCHAR ExtRate[],
4663 IN UCHAR ExtRateLen,
4664 IN PEDCA_PARM pEdcaParm,
4665 IN HT_CAPABILITY_IE *pHtCapability,
4666 IN UCHAR HtCapabilityLen,
4667 IN ADD_HT_INFO_IE *pAddHtInfo);
4668
4669VOID AuthStateMachineInit(
4670 IN PRTMP_ADAPTER pAd,
4671 IN PSTATE_MACHINE sm,
4672 OUT STATE_MACHINE_FUNC Trans[]);
4673
4674VOID AuthTimeout(
4675 IN PVOID SystemSpecific1,
4676 IN PVOID FunctionContext,
4677 IN PVOID SystemSpecific2,
4678 IN PVOID SystemSpecific3);
4679
4680VOID MlmeAuthReqAction(
4681 IN PRTMP_ADAPTER pAd,
4682 IN MLME_QUEUE_ELEM *Elem);
4683
4684VOID PeerAuthRspAtSeq2Action(
4685 IN PRTMP_ADAPTER pAd,
4686 IN MLME_QUEUE_ELEM *Elem);
4687
4688VOID PeerAuthRspAtSeq4Action(
4689 IN PRTMP_ADAPTER pAd,
4690 IN MLME_QUEUE_ELEM *Elem);
4691
4692VOID AuthTimeoutAction(
4693 IN PRTMP_ADAPTER pAd,
4694 IN MLME_QUEUE_ELEM *Elem);
4695
4696VOID Cls2errAction(
4697 IN PRTMP_ADAPTER pAd,
4698 IN PUCHAR pAddr);
4699
4700VOID MlmeDeauthReqAction(
4701 IN PRTMP_ADAPTER pAd,
4702 IN MLME_QUEUE_ELEM *Elem);
4703
4704VOID InvalidStateWhenAuth(
4705 IN PRTMP_ADAPTER pAd,
4706 IN MLME_QUEUE_ELEM *Elem);
4707
4708//=============================================
4709
4710VOID AuthRspStateMachineInit(
4711 IN PRTMP_ADAPTER pAd,
4712 IN PSTATE_MACHINE Sm,
4713 IN STATE_MACHINE_FUNC Trans[]);
4714
4715VOID PeerDeauthAction(
4716 IN PRTMP_ADAPTER pAd,
4717 IN MLME_QUEUE_ELEM *Elem);
4718
4719VOID PeerAuthSimpleRspGenAndSend(
4720 IN PRTMP_ADAPTER pAd,
4721 IN PHEADER_802_11 pHdr80211,
4722 IN USHORT Alg,
4723 IN USHORT Seq,
4724 IN USHORT Reason,
4725 IN USHORT Status);
4726
4727//
4728// Private routines in dls.c
4729//
4730
4731#ifdef CONFIG_STA_SUPPORT
4732#ifdef QOS_DLS_SUPPORT
4733void DlsStateMachineInit(
4734 IN PRTMP_ADAPTER pAd,
4735 IN STATE_MACHINE *Sm,
4736 OUT STATE_MACHINE_FUNC Trans[]);
4737
4738VOID MlmeDlsReqAction(
4739 IN PRTMP_ADAPTER pAd,
4740 IN MLME_QUEUE_ELEM *Elem);
4741
4742VOID PeerDlsReqAction(
4743 IN PRTMP_ADAPTER pAd,
4744 IN MLME_QUEUE_ELEM *Elem);
4745
4746VOID PeerDlsRspAction(
4747 IN PRTMP_ADAPTER pAd,
4748 IN MLME_QUEUE_ELEM *Elem);
4749
4750VOID MlmeDlsTearDownAction(
4751 IN PRTMP_ADAPTER pAd,
4752 IN MLME_QUEUE_ELEM *Elem);
4753
4754VOID PeerDlsTearDownAction(
4755 IN PRTMP_ADAPTER pAd,
4756 IN MLME_QUEUE_ELEM *Elem);
4757
4758VOID RTMPCheckDLSTimeOut(
4759 IN PRTMP_ADAPTER pAd);
4760
4761BOOLEAN RTMPRcvFrameDLSCheck(
4762 IN PRTMP_ADAPTER pAd,
4763 IN PHEADER_802_11 pHeader,
4764 IN ULONG Len,
4765 IN PRT28XX_RXD_STRUC pRxD);
4766
4767INT RTMPCheckDLSFrame(
4768 IN PRTMP_ADAPTER pAd,
4769 IN PUCHAR pDA);
4770
4771VOID RTMPSendDLSTearDownFrame(
4772 IN PRTMP_ADAPTER pAd,
4773 IN PUCHAR pDA);
4774
4775NDIS_STATUS RTMPSendSTAKeyRequest(
4776 IN PRTMP_ADAPTER pAd,
4777 IN PUCHAR pDA);
4778
4779NDIS_STATUS RTMPSendSTAKeyHandShake(
4780 IN PRTMP_ADAPTER pAd,
4781 IN PUCHAR pDA);
4782
4783VOID DlsTimeoutAction(
4784 IN PVOID SystemSpecific1,
4785 IN PVOID FunctionContext,
4786 IN PVOID SystemSpecific2,
4787 IN PVOID SystemSpecific3);
4788
4789BOOLEAN MlmeDlsReqSanity(
4790 IN PRTMP_ADAPTER pAd,
4791 IN VOID *Msg,
4792 IN ULONG MsgLen,
4793 OUT PRT_802_11_DLS *pDLS,
4794 OUT PUSHORT pReason);
4795
4796INT Set_DlsEntryInfo_Display_Proc(
4797 IN PRTMP_ADAPTER pAd,
4798 IN PUCHAR arg);
4799
4800MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
4801 IN PRTMP_ADAPTER pAd,
4802 IN PUCHAR pAddr,
4803 IN UINT DlsEntryIdx);
4804
4805BOOLEAN MacTableDeleteDlsEntry(
4806 IN PRTMP_ADAPTER pAd,
4807 IN USHORT wcid,
4808 IN PUCHAR pAddr);
4809
4810MAC_TABLE_ENTRY *DlsEntryTableLookup(
4811 IN PRTMP_ADAPTER pAd,
4812 IN PUCHAR pAddr,
4813 IN BOOLEAN bResetIdelCount);
4814
4815MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
4816 IN PRTMP_ADAPTER pAd,
4817 IN UCHAR wcid,
4818 IN PUCHAR pAddr,
4819 IN BOOLEAN bResetIdelCount);
4820
4821INT Set_DlsAddEntry_Proc(
4822 IN PRTMP_ADAPTER pAd,
4823 IN PUCHAR arg);
4824
4825INT Set_DlsTearDownEntry_Proc(
4826 IN PRTMP_ADAPTER pAd,
4827 IN PUCHAR arg);
4828#endif // QOS_DLS_SUPPORT //
4829#endif // CONFIG_STA_SUPPORT //
4830
4831#ifdef QOS_DLS_SUPPORT
4832BOOLEAN PeerDlsReqSanity(
4833 IN PRTMP_ADAPTER pAd,
4834 IN VOID *Msg,
4835 IN ULONG MsgLen,
4836 OUT PUCHAR pDA,
4837 OUT PUCHAR pSA,
4838 OUT USHORT *pCapabilityInfo,
4839 OUT USHORT *pDlsTimeout,
4840 OUT UCHAR *pRatesLen,
4841 OUT UCHAR Rates[],
4842 OUT UCHAR *pHtCapabilityLen,
4843 OUT HT_CAPABILITY_IE *pHtCapability);
4844
4845BOOLEAN PeerDlsRspSanity(
4846 IN PRTMP_ADAPTER pAd,
4847 IN VOID *Msg,
4848 IN ULONG MsgLen,
4849 OUT PUCHAR pDA,
4850 OUT PUCHAR pSA,
4851 OUT USHORT *pCapabilityInfo,
4852 OUT USHORT *pStatus,
4853 OUT UCHAR *pRatesLen,
4854 OUT UCHAR Rates[],
4855 OUT UCHAR *pHtCapabilityLen,
4856 OUT HT_CAPABILITY_IE *pHtCapability);
4857
4858BOOLEAN PeerDlsTearDownSanity(
4859 IN PRTMP_ADAPTER pAd,
4860 IN VOID *Msg,
4861 IN ULONG MsgLen,
4862 OUT PUCHAR pDA,
4863 OUT PUCHAR pSA,
4864 OUT USHORT *pReason);
4865#endif // QOS_DLS_SUPPORT //
4866
4867//========================================
4868
4869VOID SyncStateMachineInit(
4870 IN PRTMP_ADAPTER pAd,
4871 IN STATE_MACHINE *Sm,
4872 OUT STATE_MACHINE_FUNC Trans[]);
4873
4874VOID BeaconTimeout(
4875 IN PVOID SystemSpecific1,
4876 IN PVOID FunctionContext,
4877 IN PVOID SystemSpecific2,
4878 IN PVOID SystemSpecific3);
4879
4880VOID ScanTimeout(
4881 IN PVOID SystemSpecific1,
4882 IN PVOID FunctionContext,
4883 IN PVOID SystemSpecific2,
4884 IN PVOID SystemSpecific3);
4885
4886VOID MlmeScanReqAction(
4887 IN PRTMP_ADAPTER pAd,
4888 IN MLME_QUEUE_ELEM *Elem);
4889
4890VOID InvalidStateWhenScan(
4891 IN PRTMP_ADAPTER pAd,
4892 IN MLME_QUEUE_ELEM *Elem);
4893
4894VOID InvalidStateWhenJoin(
4895 IN PRTMP_ADAPTER pAd,
4896 IN MLME_QUEUE_ELEM *Elem);
4897
4898VOID InvalidStateWhenStart(
4899 IN PRTMP_ADAPTER pAd,
4900 IN MLME_QUEUE_ELEM *Elem);
4901
4902VOID PeerBeacon(
4903 IN PRTMP_ADAPTER pAd,
4904 IN MLME_QUEUE_ELEM *Elem);
4905
4906VOID EnqueueProbeRequest(
4907 IN PRTMP_ADAPTER pAd);
4908
4909BOOLEAN ScanRunning(
4910 IN PRTMP_ADAPTER pAd);
4911//=========================================
4912
4913VOID MlmeCntlInit(
4914 IN PRTMP_ADAPTER pAd,
4915 IN STATE_MACHINE *S,
4916 OUT STATE_MACHINE_FUNC Trans[]);
4917
4918VOID MlmeCntlMachinePerformAction(
4919 IN PRTMP_ADAPTER pAd,
4920 IN STATE_MACHINE *S,
4921 IN MLME_QUEUE_ELEM *Elem);
4922
4923VOID CntlIdleProc(
4924 IN PRTMP_ADAPTER pAd,
4925 IN MLME_QUEUE_ELEM *Elem);
4926
4927VOID CntlOidScanProc(
4928 IN PRTMP_ADAPTER pAd,
4929 IN MLME_QUEUE_ELEM *Elem);
4930
4931VOID CntlOidSsidProc(
4932 IN PRTMP_ADAPTER pAd,
4933 IN MLME_QUEUE_ELEM * Elem);
4934
4935VOID CntlOidRTBssidProc(
4936 IN PRTMP_ADAPTER pAd,
4937 IN MLME_QUEUE_ELEM * Elem);
4938
4939VOID CntlMlmeRoamingProc(
4940 IN PRTMP_ADAPTER pAd,
4941 IN MLME_QUEUE_ELEM * Elem);
4942
4943VOID CntlWaitDisassocProc(
4944 IN PRTMP_ADAPTER pAd,
4945 IN MLME_QUEUE_ELEM *Elem);
4946
4947VOID CntlWaitJoinProc(
4948 IN PRTMP_ADAPTER pAd,
4949 IN MLME_QUEUE_ELEM *Elem);
4950
4951VOID CntlWaitReassocProc(
4952 IN PRTMP_ADAPTER pAd,
4953 IN MLME_QUEUE_ELEM *Elem);
4954
4955VOID CntlWaitStartProc(
4956 IN PRTMP_ADAPTER pAd,
4957 IN MLME_QUEUE_ELEM *Elem);
4958
4959VOID CntlWaitAuthProc(
4960 IN PRTMP_ADAPTER pAd,
4961 IN MLME_QUEUE_ELEM *Elem);
4962
4963VOID CntlWaitAuthProc2(
4964 IN PRTMP_ADAPTER pAd,
4965 IN MLME_QUEUE_ELEM *Elem);
4966
4967VOID CntlWaitAssocProc(
4968 IN PRTMP_ADAPTER pAd,
4969 IN MLME_QUEUE_ELEM *Elem);
4970
4971#ifdef QOS_DLS_SUPPORT
4972VOID CntlOidDLSSetupProc(
4973 IN PRTMP_ADAPTER pAd,
4974 IN MLME_QUEUE_ELEM *Elem);
4975#endif // QOS_DLS_SUPPORT //
4976
4977VOID LinkUp(
4978 IN PRTMP_ADAPTER pAd,
4979 IN UCHAR BssType);
4980
4981VOID LinkDown(
4982 IN PRTMP_ADAPTER pAd,
4983 IN BOOLEAN IsReqFromAP);
4984
4985VOID IterateOnBssTab(
4986 IN PRTMP_ADAPTER pAd);
4987
4988VOID IterateOnBssTab2(
4989 IN PRTMP_ADAPTER pAd);;
4990
4991VOID JoinParmFill(
4992 IN PRTMP_ADAPTER pAd,
4993 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
4994 IN ULONG BssIdx);
4995
4996VOID AssocParmFill(
4997 IN PRTMP_ADAPTER pAd,
4998 IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
4999 IN PUCHAR pAddr,
5000 IN USHORT CapabilityInfo,
5001 IN ULONG Timeout,
5002 IN USHORT ListenIntv);
5003
5004VOID ScanParmFill(
5005 IN PRTMP_ADAPTER pAd,
5006 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
5007 IN CHAR Ssid[],
5008 IN UCHAR SsidLen,
5009 IN UCHAR BssType,
5010 IN UCHAR ScanType);
5011
5012VOID DisassocParmFill(
5013 IN PRTMP_ADAPTER pAd,
5014 IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
5015 IN PUCHAR pAddr,
5016 IN USHORT Reason);
5017
5018VOID StartParmFill(
5019 IN PRTMP_ADAPTER pAd,
5020 IN OUT MLME_START_REQ_STRUCT *StartReq,
5021 IN CHAR Ssid[],
5022 IN UCHAR SsidLen);
5023
5024VOID AuthParmFill(
5025 IN PRTMP_ADAPTER pAd,
5026 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
5027 IN PUCHAR pAddr,
5028 IN USHORT Alg);
5029
5030VOID EnqueuePsPoll(
5031 IN PRTMP_ADAPTER pAd);
5032
5033VOID EnqueueBeaconFrame(
5034 IN PRTMP_ADAPTER pAd);
5035
5036VOID MlmeJoinReqAction(
5037 IN PRTMP_ADAPTER pAd,
5038 IN MLME_QUEUE_ELEM *Elem);
5039
5040VOID MlmeScanReqAction(
5041 IN PRTMP_ADAPTER pAd,
5042 IN MLME_QUEUE_ELEM *Elem);
5043
5044VOID MlmeStartReqAction(
5045 IN PRTMP_ADAPTER pAd,
5046 IN MLME_QUEUE_ELEM *Elem);
5047
5048VOID ScanTimeoutAction(
5049 IN PRTMP_ADAPTER pAd,
5050 IN MLME_QUEUE_ELEM *Elem);
5051
5052VOID BeaconTimeoutAtJoinAction(
5053 IN PRTMP_ADAPTER pAd,
5054 IN MLME_QUEUE_ELEM *Elem);
5055
5056VOID PeerBeaconAtScanAction(
5057 IN PRTMP_ADAPTER pAd,
5058 IN MLME_QUEUE_ELEM *Elem);
5059
5060VOID PeerBeaconAtJoinAction(
5061 IN PRTMP_ADAPTER pAd,
5062 IN MLME_QUEUE_ELEM *Elem);
5063
5064VOID PeerBeacon(
5065 IN PRTMP_ADAPTER pAd,
5066 IN MLME_QUEUE_ELEM *Elem);
5067
5068VOID PeerProbeReqAction(
5069 IN PRTMP_ADAPTER pAd,
5070 IN MLME_QUEUE_ELEM *Elem);
5071
5072VOID ScanNextChannel(
5073 IN PRTMP_ADAPTER pAd);
5074
5075ULONG MakeIbssBeacon(
5076 IN PRTMP_ADAPTER pAd);
5077
5078VOID CCXAdjacentAPReport(
5079 IN PRTMP_ADAPTER pAd);
5080
5081BOOLEAN MlmeScanReqSanity(
5082 IN PRTMP_ADAPTER pAd,
5083 IN VOID *Msg,
5084 IN ULONG MsgLen,
5085 OUT UCHAR *BssType,
5086 OUT CHAR ssid[],
5087 OUT UCHAR *SsidLen,
5088 OUT UCHAR *ScanType);
5089
5090BOOLEAN PeerBeaconAndProbeRspSanity(
5091 IN PRTMP_ADAPTER pAd,
5092 IN VOID *Msg,
5093 IN ULONG MsgLen,
5094 IN UCHAR MsgChannel,
5095 OUT PUCHAR pAddr2,
5096 OUT PUCHAR pBssid,
5097 OUT CHAR Ssid[],
5098 OUT UCHAR *pSsidLen,
5099 OUT UCHAR *pBssType,
5100 OUT USHORT *pBeaconPeriod,
5101 OUT UCHAR *pChannel,
5102 OUT UCHAR *pNewChannel,
5103 OUT LARGE_INTEGER *pTimestamp,
5104 OUT CF_PARM *pCfParm,
5105 OUT USHORT *pAtimWin,
5106 OUT USHORT *pCapabilityInfo,
5107 OUT UCHAR *pErp,
5108 OUT UCHAR *pDtimCount,
5109 OUT UCHAR *pDtimPeriod,
5110 OUT UCHAR *pBcastFlag,
5111 OUT UCHAR *pMessageToMe,
5112 OUT UCHAR SupRate[],
5113 OUT UCHAR *pSupRateLen,
5114 OUT UCHAR ExtRate[],
5115 OUT UCHAR *pExtRateLen,
5116 OUT UCHAR *pCkipFlag,
5117 OUT UCHAR *pAironetCellPowerLimit,
5118 OUT PEDCA_PARM pEdcaParm,
5119 OUT PQBSS_LOAD_PARM pQbssLoad,
5120 OUT PQOS_CAPABILITY_PARM pQosCapability,
5121 OUT ULONG *pRalinkIe,
5122 OUT UCHAR *pHtCapabilityLen,
5123#ifdef CONFIG_STA_SUPPORT
5124 OUT UCHAR *pPreNHtCapabilityLen,
5125#endif // CONFIG_STA_SUPPORT //
5126 OUT HT_CAPABILITY_IE *pHtCapability,
5127 OUT UCHAR *AddHtInfoLen,
5128 OUT ADD_HT_INFO_IE *AddHtInfo,
5129 OUT UCHAR *NewExtChannel,
5130 OUT USHORT *LengthVIE,
5131 OUT PNDIS_802_11_VARIABLE_IEs pVIE);
5132
5133BOOLEAN PeerAddBAReqActionSanity(
5134 IN PRTMP_ADAPTER pAd,
5135 IN VOID *pMsg,
5136 IN ULONG MsgLen,
5137 OUT PUCHAR pAddr2);
5138
5139BOOLEAN PeerAddBARspActionSanity(
5140 IN PRTMP_ADAPTER pAd,
5141 IN VOID *pMsg,
5142 IN ULONG MsgLen);
5143
5144BOOLEAN PeerDelBAActionSanity(
5145 IN PRTMP_ADAPTER pAd,
5146 IN UCHAR Wcid,
5147 IN VOID *pMsg,
5148 IN ULONG MsgLen);
5149
5150BOOLEAN MlmeAssocReqSanity(
5151 IN PRTMP_ADAPTER pAd,
5152 IN VOID *Msg,
5153 IN ULONG MsgLen,
5154 OUT PUCHAR pApAddr,
5155 OUT USHORT *CapabilityInfo,
5156 OUT ULONG *Timeout,
5157 OUT USHORT *ListenIntv);
5158
5159BOOLEAN MlmeAuthReqSanity(
5160 IN PRTMP_ADAPTER pAd,
5161 IN VOID *Msg,
5162 IN ULONG MsgLen,
5163 OUT PUCHAR pAddr,
5164 OUT ULONG *Timeout,
5165 OUT USHORT *Alg);
5166
5167BOOLEAN MlmeStartReqSanity(
5168 IN PRTMP_ADAPTER pAd,
5169 IN VOID *Msg,
5170 IN ULONG MsgLen,
5171 OUT CHAR Ssid[],
5172 OUT UCHAR *Ssidlen);
5173
5174BOOLEAN PeerAuthSanity(
5175 IN PRTMP_ADAPTER pAd,
5176 IN VOID *Msg,
5177 IN ULONG MsgLen,
5178 OUT PUCHAR pAddr,
5179 OUT USHORT *Alg,
5180 OUT USHORT *Seq,
5181 OUT USHORT *Status,
5182 OUT CHAR ChlgText[]);
5183
5184BOOLEAN PeerAssocRspSanity(
5185 IN PRTMP_ADAPTER pAd,
5186 IN VOID *pMsg,
5187 IN ULONG MsgLen,
5188 OUT PUCHAR pAddr2,
5189 OUT USHORT *pCapabilityInfo,
5190 OUT USHORT *pStatus,
5191 OUT USHORT *pAid,
5192 OUT UCHAR SupRate[],
5193 OUT UCHAR *pSupRateLen,
5194 OUT UCHAR ExtRate[],
5195 OUT UCHAR *pExtRateLen,
5196 OUT HT_CAPABILITY_IE *pHtCapability,
5197 OUT ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
5198 OUT UCHAR *pHtCapabilityLen,
5199 OUT UCHAR *pAddHtInfoLen,
5200 OUT UCHAR *pNewExtChannelOffset,
5201 OUT PEDCA_PARM pEdcaParm,
5202 OUT UCHAR *pCkipFlag);
5203
5204BOOLEAN PeerDisassocSanity(
5205 IN PRTMP_ADAPTER pAd,
5206 IN VOID *Msg,
5207 IN ULONG MsgLen,
5208 OUT PUCHAR pAddr2,
5209 OUT USHORT *Reason);
5210
5211BOOLEAN PeerWpaMessageSanity(
5212 IN PRTMP_ADAPTER pAd,
5213 IN PEAPOL_PACKET pMsg,
5214 IN ULONG MsgLen,
5215 IN UCHAR MsgType,
5216 IN MAC_TABLE_ENTRY *pEntry);
5217
5218BOOLEAN PeerDeauthSanity(
5219 IN PRTMP_ADAPTER pAd,
5220 IN VOID *Msg,
5221 IN ULONG MsgLen,
5222 OUT PUCHAR pAddr2,
5223 OUT USHORT *Reason);
5224
5225BOOLEAN PeerProbeReqSanity(
5226 IN PRTMP_ADAPTER pAd,
5227 IN VOID *Msg,
5228 IN ULONG MsgLen,
5229 OUT PUCHAR pAddr2,
5230 OUT CHAR Ssid[],
5231 OUT UCHAR *pSsidLen);
5232
5233BOOLEAN GetTimBit(
5234 IN CHAR *Ptr,
5235 IN USHORT Aid,
5236 OUT UCHAR *TimLen,
5237 OUT UCHAR *BcastFlag,
5238 OUT UCHAR *DtimCount,
5239 OUT UCHAR *DtimPeriod,
5240 OUT UCHAR *MessageToMe);
5241
5242UCHAR ChannelSanity(
5243 IN PRTMP_ADAPTER pAd,
5244 IN UCHAR channel);
5245
5246NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
5247 IN PBSS_ENTRY pBss);
5248
5249BOOLEAN MlmeDelBAReqSanity(
5250 IN PRTMP_ADAPTER pAd,
5251 IN VOID *Msg,
5252 IN ULONG MsgLen);
5253
5254BOOLEAN MlmeAddBAReqSanity(
5255 IN PRTMP_ADAPTER pAd,
5256 IN VOID *Msg,
5257 IN ULONG MsgLen,
5258 OUT PUCHAR pAddr2);
5259
5260ULONG MakeOutgoingFrame(
5261 OUT CHAR *Buffer,
5262 OUT ULONG *Length, ...);
5263
5264VOID LfsrInit(
5265 IN PRTMP_ADAPTER pAd,
5266 IN ULONG Seed);
5267
5268UCHAR RandomByte(
5269 IN PRTMP_ADAPTER pAd);
5270
5271VOID AsicUpdateAutoFallBackTable(
5272 IN PRTMP_ADAPTER pAd,
5273 IN PUCHAR pTxRate);
5274
5275VOID MlmePeriodicExec(
5276 IN PVOID SystemSpecific1,
5277 IN PVOID FunctionContext,
5278 IN PVOID SystemSpecific2,
5279 IN PVOID SystemSpecific3);
5280
5281VOID LinkDownExec(
5282 IN PVOID SystemSpecific1,
5283 IN PVOID FunctionContext,
5284 IN PVOID SystemSpecific2,
5285 IN PVOID SystemSpecific3);
5286
5287VOID LinkUpExec(
5288 IN PVOID SystemSpecific1,
5289 IN PVOID FunctionContext,
5290 IN PVOID SystemSpecific2,
5291 IN PVOID SystemSpecific3);
5292
5293VOID STAMlmePeriodicExec(
5294 PRTMP_ADAPTER pAd);
5295
5296VOID MlmeAutoScan(
5297 IN PRTMP_ADAPTER pAd);
5298
5299VOID MlmeAutoReconnectLastSSID(
5300 IN PRTMP_ADAPTER pAd);
5301
5302BOOLEAN MlmeValidateSSID(
5303 IN PUCHAR pSsid,
5304 IN UCHAR SsidLen);
5305
5306VOID MlmeCheckForRoaming(
5307 IN PRTMP_ADAPTER pAd,
5308 IN ULONG Now32);
5309
5310VOID MlmeCheckForFastRoaming(
5311 IN PRTMP_ADAPTER pAd,
5312 IN ULONG Now);
5313
5314VOID MlmeDynamicTxRateSwitching(
5315 IN PRTMP_ADAPTER pAd);
5316
5317VOID MlmeSetTxRate(
5318 IN PRTMP_ADAPTER pAd,
5319 IN PMAC_TABLE_ENTRY pEntry,
5320 IN PRTMP_TX_RATE_SWITCH pTxRate);
5321
5322VOID MlmeSelectTxRateTable(
5323 IN PRTMP_ADAPTER pAd,
5324 IN PMAC_TABLE_ENTRY pEntry,
5325 IN PUCHAR *ppTable,
5326 IN PUCHAR pTableSize,
5327 IN PUCHAR pInitTxRateIdx);
5328
5329VOID MlmeCalculateChannelQuality(
5330 IN PRTMP_ADAPTER pAd,
5331 IN ULONG Now);
5332
5333VOID MlmeCheckPsmChange(
5334 IN PRTMP_ADAPTER pAd,
5335 IN ULONG Now32);
5336
5337VOID MlmeSetPsmBit(
5338 IN PRTMP_ADAPTER pAd,
5339 IN USHORT psm);
5340
5341VOID MlmeSetTxPreamble(
5342 IN PRTMP_ADAPTER pAd,
5343 IN USHORT TxPreamble);
5344
5345VOID UpdateBasicRateBitmap(
5346 IN PRTMP_ADAPTER pAd);
5347
5348VOID MlmeUpdateTxRates(
5349 IN PRTMP_ADAPTER pAd,
5350 IN BOOLEAN bLinkUp,
5351 IN UCHAR apidx);
5352
5353#ifdef DOT11_N_SUPPORT
5354VOID MlmeUpdateHtTxRates(
5355 IN PRTMP_ADAPTER pAd,
5356 IN UCHAR apidx);
5357#endif // DOT11_N_SUPPORT //
5358
5359VOID RTMPCheckRates(
5360 IN PRTMP_ADAPTER pAd,
5361 IN OUT UCHAR SupRate[],
5362 IN OUT UCHAR *SupRateLen);
5363
5364#ifdef CONFIG_STA_SUPPORT
5365BOOLEAN RTMPCheckChannel(
5366 IN PRTMP_ADAPTER pAd,
5367 IN UCHAR CentralChannel,
5368 IN UCHAR Channel);
5369#endif // CONFIG_STA_SUPPORT //
5370
5371BOOLEAN RTMPCheckHt(
5372 IN PRTMP_ADAPTER pAd,
5373 IN UCHAR Wcid,
5374 IN OUT HT_CAPABILITY_IE *pHtCapability,
5375 IN OUT ADD_HT_INFO_IE *pAddHtInfo);
5376
5377VOID StaQuickResponeForRateUpExec(
5378 IN PVOID SystemSpecific1,
5379 IN PVOID FunctionContext,
5380 IN PVOID SystemSpecific2,
5381 IN PVOID SystemSpecific3);
5382
5383VOID AsicBbpTuning1(
5384 IN PRTMP_ADAPTER pAd);
5385
5386VOID AsicBbpTuning2(
5387 IN PRTMP_ADAPTER pAd);
5388
5389VOID RTMPUpdateMlmeRate(
5390 IN PRTMP_ADAPTER pAd);
5391
5392CHAR RTMPMaxRssi(
5393 IN PRTMP_ADAPTER pAd,
5394 IN CHAR Rssi0,
5395 IN CHAR Rssi1,
5396 IN CHAR Rssi2);
5397
5398VOID AsicEvaluateRxAnt(
5399 IN PRTMP_ADAPTER pAd);
5400
5401VOID AsicRxAntEvalTimeout(
5402 IN PVOID SystemSpecific1,
5403 IN PVOID FunctionContext,
5404 IN PVOID SystemSpecific2,
5405 IN PVOID SystemSpecific3);
5406
5407VOID APSDPeriodicExec(
5408 IN PVOID SystemSpecific1,
5409 IN PVOID FunctionContext,
5410 IN PVOID SystemSpecific2,
5411 IN PVOID SystemSpecific3);
5412
5413BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
5414 IN PRTMP_ADAPTER pAd,
5415 IN PMAC_TABLE_ENTRY pEntry);
5416
5417UCHAR RTMPStaFixedTxMode(
5418 IN PRTMP_ADAPTER pAd,
5419 IN PMAC_TABLE_ENTRY pEntry);
5420
5421VOID RTMPUpdateLegacyTxSetting(
5422 UCHAR fixed_tx_mode,
5423 PMAC_TABLE_ENTRY pEntry);
5424
5425BOOLEAN RTMPAutoRateSwitchCheck(
5426 IN PRTMP_ADAPTER pAd);
5427
5428NDIS_STATUS MlmeInit(
5429 IN PRTMP_ADAPTER pAd);
5430
5431VOID MlmeHandler(
5432 IN PRTMP_ADAPTER pAd);
5433
5434VOID MlmeHalt(
5435 IN PRTMP_ADAPTER pAd);
5436
5437VOID MlmeResetRalinkCounters(
5438 IN PRTMP_ADAPTER pAd);
5439
5440VOID BuildChannelList(
5441 IN PRTMP_ADAPTER pAd);
5442
5443UCHAR FirstChannel(
5444 IN PRTMP_ADAPTER pAd);
5445
5446UCHAR NextChannel(
5447 IN PRTMP_ADAPTER pAd,
5448 IN UCHAR channel);
5449
5450VOID ChangeToCellPowerLimit(
5451 IN PRTMP_ADAPTER pAd,
5452 IN UCHAR AironetCellPowerLimit);
5453
5454VOID RaiseClock(
5455 IN PRTMP_ADAPTER pAd,
5456 IN UINT32 *x);
5457
5458VOID LowerClock(
5459 IN PRTMP_ADAPTER pAd,
5460 IN UINT32 *x);
5461
5462USHORT ShiftInBits(
5463 IN PRTMP_ADAPTER pAd);
5464
5465VOID ShiftOutBits(
5466 IN PRTMP_ADAPTER pAd,
5467 IN USHORT data,
5468 IN USHORT count);
5469
5470VOID EEpromCleanup(
5471 IN PRTMP_ADAPTER pAd);
5472
5473VOID EWDS(
5474 IN PRTMP_ADAPTER pAd);
5475
5476VOID EWEN(
5477 IN PRTMP_ADAPTER pAd);
5478
5479USHORT RTMP_EEPROM_READ16(
5480 IN PRTMP_ADAPTER pAd,
5481 IN USHORT Offset);
5482
5483VOID RTMP_EEPROM_WRITE16(
5484 IN PRTMP_ADAPTER pAd,
5485 IN USHORT Offset,
5486 IN USHORT Data);
5487
5488//
5489// Prototypes of function definition in rtmp_tkip.c
5490//
5491VOID RTMPInitTkipEngine(
5492 IN PRTMP_ADAPTER pAd,
5493 IN PUCHAR pTKey,
5494 IN UCHAR KeyId,
5495 IN PUCHAR pTA,
5496 IN PUCHAR pMICKey,
5497 IN PUCHAR pTSC,
5498 OUT PULONG pIV16,
5499 OUT PULONG pIV32);
5500
5501VOID RTMPInitMICEngine(
5502 IN PRTMP_ADAPTER pAd,
5503 IN PUCHAR pKey,
5504 IN PUCHAR pDA,
5505 IN PUCHAR pSA,
5506 IN UCHAR UserPriority,
5507 IN PUCHAR pMICKey);
5508
5509BOOLEAN RTMPTkipCompareMICValue(
5510 IN PRTMP_ADAPTER pAd,
5511 IN PUCHAR pSrc,
5512 IN PUCHAR pDA,
5513 IN PUCHAR pSA,
5514 IN PUCHAR pMICKey,
5515 IN UCHAR UserPriority,
5516 IN UINT Len);
5517
5518VOID RTMPCalculateMICValue(
5519 IN PRTMP_ADAPTER pAd,
5520 IN PNDIS_PACKET pPacket,
5521 IN PUCHAR pEncap,
5522 IN PCIPHER_KEY pKey,
5523 IN UCHAR apidx);
5524
5525BOOLEAN RTMPTkipCompareMICValueWithLLC(
5526 IN PRTMP_ADAPTER pAd,
5527 IN PUCHAR pLLC,
5528 IN PUCHAR pSrc,
5529 IN PUCHAR pDA,
5530 IN PUCHAR pSA,
5531 IN PUCHAR pMICKey,
5532 IN UINT Len);
5533
5534VOID RTMPTkipAppendByte(
5535 IN PTKIP_KEY_INFO pTkip,
5536 IN UCHAR uChar);
5537
5538VOID RTMPTkipAppend(
5539 IN PTKIP_KEY_INFO pTkip,
5540 IN PUCHAR pSrc,
5541 IN UINT nBytes);
5542
5543VOID RTMPTkipGetMIC(
5544 IN PTKIP_KEY_INFO pTkip);
5545
5546BOOLEAN RTMPSoftDecryptTKIP(
5547 IN PRTMP_ADAPTER pAd,
5548 IN PUCHAR pData,
5549 IN ULONG DataByteCnt,
5550 IN UCHAR UserPriority,
5551 IN PCIPHER_KEY pWpaKey);
5552
5553BOOLEAN RTMPSoftDecryptAES(
5554 IN PRTMP_ADAPTER pAd,
5555 IN PUCHAR pData,
5556 IN ULONG DataByteCnt,
5557 IN PCIPHER_KEY pWpaKey);
5558
5559//
5560// Prototypes of function definition in cmm_info.c
5561//
5562NDIS_STATUS RTMPWPARemoveKeyProc(
5563 IN PRTMP_ADAPTER pAd,
5564 IN PVOID pBuf);
5565
5566VOID RTMPWPARemoveAllKeys(
5567 IN PRTMP_ADAPTER pAd);
5568
5569BOOLEAN RTMPCheckStrPrintAble(
5570 IN CHAR *pInPutStr,
5571 IN UCHAR strLen);
5572
5573VOID RTMPSetPhyMode(
5574 IN PRTMP_ADAPTER pAd,
5575 IN ULONG phymode);
5576
5577VOID RTMPUpdateHTIE(
5578 IN RT_HT_CAPABILITY *pRtHt,
5579 IN UCHAR *pMcsSet,
5580 OUT HT_CAPABILITY_IE *pHtCapability,
5581 OUT ADD_HT_INFO_IE *pAddHtInfo);
5582
5583VOID RTMPAddWcidAttributeEntry(
5584 IN PRTMP_ADAPTER pAd,
5585 IN UCHAR BssIdx,
5586 IN UCHAR KeyIdx,
5587 IN UCHAR CipherAlg,
5588 IN MAC_TABLE_ENTRY *pEntry);
5589
5590CHAR *GetEncryptType(
5591 CHAR enc);
5592
5593CHAR *GetAuthMode(
5594 CHAR auth);
5595
5596VOID RTMPIoctlGetSiteSurvey(
5597 IN PRTMP_ADAPTER pAdapter,
5598 IN struct iwreq *wrq);
5599
5600VOID RTMPIoctlGetMacTable(
5601 IN PRTMP_ADAPTER pAd,
5602 IN struct iwreq *wrq);
5603
5604VOID RTMPIndicateWPA2Status(
5605 IN PRTMP_ADAPTER pAdapter);
5606
5607VOID RTMPOPModeSwitching(
5608 IN PRTMP_ADAPTER pAd);
5609
5610#ifdef CONFIG_STA_SUPPORT
5611VOID RTMPAddBSSIDCipher(
5612 IN PRTMP_ADAPTER pAd,
5613 IN UCHAR Aid,
5614 IN PNDIS_802_11_KEY pKey,
5615 IN UCHAR CipherAlg);
5616#endif // CONFIG_STA_SUPPORT //
5617
5618#ifdef DOT11_N_SUPPORT
5619VOID RTMPSetHT(
5620 IN PRTMP_ADAPTER pAd,
5621 IN OID_SET_HT_PHYMODE *pHTPhyMode);
5622
5623VOID RTMPSetIndividualHT(
5624 IN PRTMP_ADAPTER pAd,
5625 IN UCHAR apidx);
5626#endif // DOT11_N_SUPPORT //
5627
5628VOID RTMPSendWirelessEvent(
5629 IN PRTMP_ADAPTER pAd,
5630 IN USHORT Event_flag,
5631 IN PUCHAR pAddr,
5632 IN UCHAR BssIdx,
5633 IN CHAR Rssi);
5634
5635VOID NICUpdateCntlCounters(
5636 IN PRTMP_ADAPTER pAd,
5637 IN PHEADER_802_11 pHeader,
5638 IN UCHAR SubType,
5639 IN PRXWI_STRUC pRxWI);
5640//
5641// prototype in wpa.c
5642//
5643BOOLEAN WpaMsgTypeSubst(
5644 IN UCHAR EAPType,
5645 OUT INT *MsgType);
5646
5647VOID WpaPskStateMachineInit(
5648 IN PRTMP_ADAPTER pAd,
5649 IN STATE_MACHINE *S,
5650 OUT STATE_MACHINE_FUNC Trans[]);
5651
5652VOID WpaEAPOLKeyAction(
5653 IN PRTMP_ADAPTER pAd,
5654 IN MLME_QUEUE_ELEM *Elem);
5655
5656VOID WpaPairMsg1Action(
5657 IN PRTMP_ADAPTER pAd,
5658 IN MLME_QUEUE_ELEM *Elem);
5659
5660VOID WpaPairMsg3Action(
5661 IN PRTMP_ADAPTER pAd,
5662 IN MLME_QUEUE_ELEM *Elem);
5663
5664VOID WpaGroupMsg1Action(
5665 IN PRTMP_ADAPTER pAd,
5666 IN MLME_QUEUE_ELEM *Elem);
5667
5668VOID WpaMacHeaderInit(
5669 IN PRTMP_ADAPTER pAd,
5670 IN OUT PHEADER_802_11 pHdr80211,
5671 IN UCHAR wep,
5672 IN PUCHAR pAddr1);
5673
5674VOID Wpa2PairMsg1Action(
5675 IN PRTMP_ADAPTER pAd,
5676 IN MLME_QUEUE_ELEM *Elem);
5677
5678VOID Wpa2PairMsg3Action(
5679 IN PRTMP_ADAPTER pAd,
5680 IN MLME_QUEUE_ELEM *Elem);
5681
5682BOOLEAN ParseKeyData(
5683 IN PRTMP_ADAPTER pAd,
5684 IN PUCHAR pKeyData,
5685 IN UCHAR KeyDataLen,
5686 IN UCHAR bPairewise);
5687
5688VOID RTMPToWirelessSta(
5689 IN PRTMP_ADAPTER pAd,
5690 IN PUCHAR pHeader802_3,
5691 IN UINT HdrLen,
5692 IN PUCHAR pData,
5693 IN UINT DataLen,
5694 IN BOOLEAN is4wayFrame);
5695
5696VOID HMAC_SHA1(
5697 IN UCHAR *text,
5698 IN UINT text_len,
5699 IN UCHAR *key,
5700 IN UINT key_len,
5701 IN UCHAR *digest);
5702
5703VOID PRF(
5704 IN UCHAR *key,
5705 IN INT key_len,
5706 IN UCHAR *prefix,
5707 IN INT prefix_len,
5708 IN UCHAR *data,
5709 IN INT data_len,
5710 OUT UCHAR *output,
5711 IN INT len);
5712
5713VOID CCKMPRF(
5714 IN UCHAR *key,
5715 IN INT key_len,
5716 IN UCHAR *data,
5717 IN INT data_len,
5718 OUT UCHAR *output,
5719 IN INT len);
5720
5721VOID WpaCountPTK(
5722 IN PRTMP_ADAPTER pAd,
5723 IN UCHAR *PMK,
5724 IN UCHAR *ANonce,
5725 IN UCHAR *AA,
5726 IN UCHAR *SNonce,
5727 IN UCHAR *SA,
5728 OUT UCHAR *output,
5729 IN UINT len);
5730
5731VOID GenRandom(
5732 IN PRTMP_ADAPTER pAd,
5733 IN UCHAR *macAddr,
5734 OUT UCHAR *random);
5735
5736//
5737// prototype in aironet.c
5738//
5739VOID AironetStateMachineInit(
5740 IN PRTMP_ADAPTER pAd,
5741 IN STATE_MACHINE *S,
5742 OUT STATE_MACHINE_FUNC Trans[]);
5743
5744VOID AironetMsgAction(
5745 IN PRTMP_ADAPTER pAd,
5746 IN MLME_QUEUE_ELEM *Elem);
5747
5748VOID AironetRequestAction(
5749 IN PRTMP_ADAPTER pAd,
5750 IN MLME_QUEUE_ELEM *Elem);
5751
5752VOID ChannelLoadRequestAction(
5753 IN PRTMP_ADAPTER pAd,
5754 IN UCHAR Index);
5755
5756VOID NoiseHistRequestAction(
5757 IN PRTMP_ADAPTER pAd,
5758 IN UCHAR Index);
5759
5760VOID BeaconRequestAction(
5761 IN PRTMP_ADAPTER pAd,
5762 IN UCHAR Index);
5763
5764VOID AironetReportAction(
5765 IN PRTMP_ADAPTER pAd,
5766 IN MLME_QUEUE_ELEM *Elem);
5767
5768VOID ChannelLoadReportAction(
5769 IN PRTMP_ADAPTER pAd,
5770 IN UCHAR Index);
5771
5772VOID NoiseHistReportAction(
5773 IN PRTMP_ADAPTER pAd,
5774 IN UCHAR Index);
5775
5776VOID AironetFinalReportAction(
5777 IN PRTMP_ADAPTER pAd);
5778
5779VOID BeaconReportAction(
5780 IN PRTMP_ADAPTER pAd,
5781 IN UCHAR Index);
5782
5783VOID AironetAddBeaconReport(
5784 IN PRTMP_ADAPTER pAd,
5785 IN ULONG Index,
5786 IN PMLME_QUEUE_ELEM pElem);
5787
5788VOID AironetCreateBeaconReportFromBssTable(
5789 IN PRTMP_ADAPTER pAd);
5790
5791VOID DBGPRINT_TX_RING(
5792 IN PRTMP_ADAPTER pAd,
5793 IN UCHAR QueIdx);
5794
5795VOID DBGPRINT_RX_RING(
5796 IN PRTMP_ADAPTER pAd);
5797
5798CHAR ConvertToRssi(
5799 IN PRTMP_ADAPTER pAd,
5800 IN CHAR Rssi,
5801 IN UCHAR RssiNumber);
5802
5803
5804#ifdef DOT11N_DRAFT3
5805VOID BuildEffectedChannelList(
5806 IN PRTMP_ADAPTER pAd);
5807#endif // DOT11N_DRAFT3 //
5808
5809
5810VOID APAsicEvaluateRxAnt(
5811 IN PRTMP_ADAPTER pAd);
5812
5813
5814VOID APAsicRxAntEvalTimeout(
5815 IN PRTMP_ADAPTER pAd);
5816
5817//
5818// function prototype in cmm_wpa.c
5819//
5820BOOLEAN RTMPCheckWPAframe(
5821 IN PRTMP_ADAPTER pAd,
5822 IN PMAC_TABLE_ENTRY pEntry,
5823 IN PUCHAR pData,
5824 IN ULONG DataByteCount,
5825 IN UCHAR FromWhichBSSID);
5826
5827VOID AES_GTK_KEY_UNWRAP(
5828 IN UCHAR *key,
5829 OUT UCHAR *plaintext,
5830 IN UCHAR c_len,
5831 IN UCHAR *ciphertext);
5832
5833BOOLEAN RTMPCheckRSNIE(
5834 IN PRTMP_ADAPTER pAd,
5835 IN PUCHAR pData,
5836 IN UCHAR DataLen,
5837 IN MAC_TABLE_ENTRY *pEntry,
5838 OUT UCHAR *Offset);
5839
5840BOOLEAN RTMPParseEapolKeyData(
5841 IN PRTMP_ADAPTER pAd,
5842 IN PUCHAR pKeyData,
5843 IN UCHAR KeyDataLen,
5844 IN UCHAR GroupKeyIndex,
5845 IN UCHAR MsgType,
5846 IN BOOLEAN bWPA2,
5847 IN MAC_TABLE_ENTRY *pEntry);
5848
5849VOID ConstructEapolMsg(
5850 IN PRTMP_ADAPTER pAd,
5851 IN UCHAR PeerAuthMode,
5852 IN UCHAR PeerWepStatus,
5853 IN UCHAR MyGroupKeyWepStatus,
5854 IN UCHAR MsgType,
5855 IN UCHAR DefaultKeyIdx,
5856 IN UCHAR *ReplayCounter,
5857 IN UCHAR *KeyNonce,
5858 IN UCHAR *TxRSC,
5859 IN UCHAR *PTK,
5860 IN UCHAR *GTK,
5861 IN UCHAR *RSNIE,
5862 IN UCHAR RSNIE_Len,
5863 OUT PEAPOL_PACKET pMsg);
5864
5865VOID CalculateMIC(
5866 IN PRTMP_ADAPTER pAd,
5867 IN UCHAR PeerWepStatus,
5868 IN UCHAR *PTK,
5869 OUT PEAPOL_PACKET pMsg);
5870
5871NDIS_STATUS RTMPSoftDecryptBroadCastData(
5872 IN PRTMP_ADAPTER pAd,
5873 IN RX_BLK *pRxBlk,
5874 IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,
5875 IN PCIPHER_KEY pShard_key);
5876
5877VOID ConstructEapolKeyData(
5878 IN PRTMP_ADAPTER pAd,
5879 IN UCHAR PeerAuthMode,
5880 IN UCHAR PeerWepStatus,
5881 IN UCHAR GroupKeyWepStatus,
5882 IN UCHAR MsgType,
5883 IN UCHAR DefaultKeyIdx,
5884 IN BOOLEAN bWPA2Capable,
5885 IN UCHAR *PTK,
5886 IN UCHAR *GTK,
5887 IN UCHAR *RSNIE,
5888 IN UCHAR RSNIE_LEN,
5889 OUT PEAPOL_PACKET pMsg);
5890
5891VOID RTMPMakeRSNIE(
5892 IN PRTMP_ADAPTER pAd,
5893 IN UINT AuthMode,
5894 IN UINT WepStatus,
5895 IN UCHAR apidx);
5896
5897//
5898// function prototype in ap_wpa.c
5899//
5900
5901BOOLEAN APWpaMsgTypeSubst(
5902 IN UCHAR EAPType,
5903 OUT INT *MsgType) ;
5904
5905MAC_TABLE_ENTRY *PACInquiry(
5906 IN PRTMP_ADAPTER pAd,
5907 IN ULONG Wcid);
5908
5909BOOLEAN RTMPCheckMcast(
5910 IN PRTMP_ADAPTER pAd,
5911 IN PEID_STRUCT eid_ptr,
5912 IN MAC_TABLE_ENTRY *pEntry);
5913
5914BOOLEAN RTMPCheckUcast(
5915 IN PRTMP_ADAPTER pAd,
5916 IN PEID_STRUCT eid_ptr,
5917 IN MAC_TABLE_ENTRY *pEntry);
5918
5919BOOLEAN RTMPCheckAUTH(
5920 IN PRTMP_ADAPTER pAd,
5921 IN PEID_STRUCT eid_ptr,
5922 IN MAC_TABLE_ENTRY *pEntry);
5923
5924VOID WPAStart4WayHS(
5925 IN PRTMP_ADAPTER pAd,
5926 IN MAC_TABLE_ENTRY *pEntry,
5927 IN ULONG TimeInterval);
5928
5929VOID WPAStart2WayGroupHS(
5930 IN PRTMP_ADAPTER pAd,
5931 IN MAC_TABLE_ENTRY *pEntry);
5932
5933VOID APWpaEAPPacketAction(
5934 IN PRTMP_ADAPTER pAd,
5935 IN MLME_QUEUE_ELEM *Elem);
5936
5937VOID APWpaEAPOLStartAction(
5938 IN PRTMP_ADAPTER pAd,
5939 IN MLME_QUEUE_ELEM *Elem);
5940
5941VOID APWpaEAPOLLogoffAction(
5942 IN PRTMP_ADAPTER pAd,
5943 IN MLME_QUEUE_ELEM *Elem);
5944
5945VOID APWpaEAPOLKeyAction(
5946 IN PRTMP_ADAPTER pAd,
5947 IN MLME_QUEUE_ELEM *Elem);
5948
5949VOID APWpaEAPOLASFAlertAction(
5950 IN PRTMP_ADAPTER pAd,
5951 IN MLME_QUEUE_ELEM *Elem);
5952
5953VOID HandleCounterMeasure(
5954 IN PRTMP_ADAPTER pAd,
5955 IN MAC_TABLE_ENTRY *pEntry);
5956
5957VOID PeerPairMsg2Action(
5958 IN PRTMP_ADAPTER pAd,
5959 IN MAC_TABLE_ENTRY *pEntry,
5960 IN MLME_QUEUE_ELEM *Elem);
5961
5962VOID PeerPairMsg4Action(
5963 IN PRTMP_ADAPTER pAd,
5964 IN MAC_TABLE_ENTRY *pEntry,
5965 IN MLME_QUEUE_ELEM *Elem);
5966
5967VOID CMTimerExec(
5968 IN PVOID SystemSpecific1,
5969 IN PVOID FunctionContext,
5970 IN PVOID SystemSpecific2,
5971 IN PVOID SystemSpecific3);
5972
5973VOID WPARetryExec(
5974 IN PVOID SystemSpecific1,
5975 IN PVOID FunctionContext,
5976 IN PVOID SystemSpecific2,
5977 IN PVOID SystemSpecific3);
5978
5979VOID EnqueueStartForPSKExec(
5980 IN PVOID SystemSpecific1,
5981 IN PVOID FunctionContext,
5982 IN PVOID SystemSpecific2,
5983 IN PVOID SystemSpecific3);
5984
5985VOID RTMPHandleSTAKey(
5986 IN PRTMP_ADAPTER pAdapter,
5987 IN MAC_TABLE_ENTRY *pEntry,
5988 IN MLME_QUEUE_ELEM *Elem);
5989
5990VOID PeerGroupMsg2Action(
5991 IN PRTMP_ADAPTER pAd,
5992 IN PMAC_TABLE_ENTRY pEntry,
5993 IN VOID *Msg,
5994 IN UINT MsgLen);
5995
5996VOID PairDisAssocAction(
5997 IN PRTMP_ADAPTER pAd,
5998 IN PMAC_TABLE_ENTRY pEntry,
5999 IN USHORT Reason);
6000
6001VOID MlmeDeAuthAction(
6002 IN PRTMP_ADAPTER pAd,
6003 IN PMAC_TABLE_ENTRY pEntry,
6004 IN USHORT Reason);
6005
6006VOID GREKEYPeriodicExec(
6007 IN PVOID SystemSpecific1,
6008 IN PVOID FunctionContext,
6009 IN PVOID SystemSpecific2,
6010 IN PVOID SystemSpecific3);
6011
6012VOID CountGTK(
6013 IN UCHAR *PMK,
6014 IN UCHAR *GNonce,
6015 IN UCHAR *AA,
6016 OUT UCHAR *output,
6017 IN UINT len);
6018
6019VOID GetSmall(
6020 IN PVOID pSrc1,
6021 IN PVOID pSrc2,
6022 OUT PUCHAR out,
6023 IN ULONG Length);
6024
6025VOID GetLarge(
6026 IN PVOID pSrc1,
6027 IN PVOID pSrc2,
6028 OUT PUCHAR out,
6029 IN ULONG Length);
6030
6031VOID APGenRandom(
6032 IN PRTMP_ADAPTER pAd,
6033 OUT UCHAR *random);
6034
6035VOID AES_GTK_KEY_WRAP(
6036 IN UCHAR *key,
6037 IN UCHAR *plaintext,
6038 IN UCHAR p_len,
6039 OUT UCHAR *ciphertext);
6040
6041VOID WpaSend(
6042 IN PRTMP_ADAPTER pAdapter,
6043 IN PUCHAR pPacket,
6044 IN ULONG Len);
6045
6046VOID APToWirelessSta(
6047 IN PRTMP_ADAPTER pAd,
6048 IN MAC_TABLE_ENTRY *pEntry,
6049 IN PUCHAR pHeader802_3,
6050 IN UINT HdrLen,
6051 IN PUCHAR pData,
6052 IN UINT DataLen,
6053 IN BOOLEAN bClearFrame);
6054
6055VOID RTMPAddPMKIDCache(
6056 IN PRTMP_ADAPTER pAd,
6057 IN INT apidx,
6058 IN PUCHAR pAddr,
6059 IN UCHAR *PMKID,
6060 IN UCHAR *PMK);
6061
6062INT RTMPSearchPMKIDCache(
6063 IN PRTMP_ADAPTER pAd,
6064 IN INT apidx,
6065 IN PUCHAR pAddr);
6066
6067VOID RTMPDeletePMKIDCache(
6068 IN PRTMP_ADAPTER pAd,
6069 IN INT apidx,
6070 IN INT idx);
6071
6072VOID RTMPMaintainPMKIDCache(
6073 IN PRTMP_ADAPTER pAd);
6074
6075VOID RTMPSendTriggerFrame(
6076 IN PRTMP_ADAPTER pAd,
6077 IN PVOID pBuffer,
6078 IN ULONG Length,
6079 IN UCHAR TxRate,
6080 IN BOOLEAN bQosNull);
6081
6082
6083/* timeout -- ms */
6084VOID RTMP_SetPeriodicTimer(
6085 IN NDIS_MINIPORT_TIMER *pTimer,
6086 IN unsigned long timeout);
6087
6088VOID RTMP_OS_Init_Timer(
6089 IN PRTMP_ADAPTER pAd,
6090 IN NDIS_MINIPORT_TIMER *pTimer,
6091 IN TIMER_FUNCTION function,
6092 IN PVOID data);
6093
6094VOID RTMP_OS_Add_Timer(
6095 IN NDIS_MINIPORT_TIMER *pTimer,
6096 IN unsigned long timeout);
6097
6098VOID RTMP_OS_Mod_Timer(
6099 IN NDIS_MINIPORT_TIMER *pTimer,
6100 IN unsigned long timeout);
6101
6102
6103VOID RTMP_OS_Del_Timer(
6104 IN NDIS_MINIPORT_TIMER *pTimer,
6105 OUT BOOLEAN *pCancelled);
6106
6107
6108VOID RTMP_OS_Release_Packet(
6109 IN PRTMP_ADAPTER pAd,
6110 IN PQUEUE_ENTRY pEntry);
6111
6112VOID RTMPusecDelay(
6113 IN ULONG usec);
6114
6115NDIS_STATUS os_alloc_mem(
6116 IN PRTMP_ADAPTER pAd,
6117 OUT PUCHAR *mem,
6118 IN ULONG size);
6119
6120NDIS_STATUS os_free_mem(
6121 IN PRTMP_ADAPTER pAd,
6122 IN PUCHAR mem);
6123
6124
6125void RTMP_AllocateSharedMemory(
6126 IN PRTMP_ADAPTER pAd,
6127 IN ULONG Length,
6128 IN BOOLEAN Cached,
6129 OUT PVOID *VirtualAddress,
6130 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6131
6132VOID RTMPFreeTxRxRingMemory(
6133 IN PRTMP_ADAPTER pAd);
6134
6135NDIS_STATUS AdapterBlockAllocateMemory(
6136 IN PVOID handle,
6137 OUT PVOID *ppAd);
6138
6139void RTMP_AllocateTxDescMemory(
6140 IN PRTMP_ADAPTER pAd,
6141 IN UINT Index,
6142 IN ULONG Length,
6143 IN BOOLEAN Cached,
6144 OUT PVOID *VirtualAddress,
6145 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6146
6147void RTMP_AllocateFirstTxBuffer(
6148 IN PRTMP_ADAPTER pAd,
6149 IN UINT Index,
6150 IN ULONG Length,
6151 IN BOOLEAN Cached,
6152 OUT PVOID *VirtualAddress,
6153 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6154
6155void RTMP_AllocateMgmtDescMemory(
6156 IN PRTMP_ADAPTER pAd,
6157 IN ULONG Length,
6158 IN BOOLEAN Cached,
6159 OUT PVOID *VirtualAddress,
6160 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6161
6162void RTMP_AllocateRxDescMemory(
6163 IN PRTMP_ADAPTER pAd,
6164 IN ULONG Length,
6165 IN BOOLEAN Cached,
6166 OUT PVOID *VirtualAddress,
6167 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6168
6169PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
6170 IN PRTMP_ADAPTER pAd,
6171 IN ULONG Length,
6172 IN BOOLEAN Cached,
6173 OUT PVOID *VirtualAddress,
6174 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
6175
6176PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
6177 IN PRTMP_ADAPTER pAd,
6178 IN ULONG Length,
6179 IN BOOLEAN Cached,
6180 OUT PVOID *VirtualAddress);
6181
6182PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
6183 IN PRTMP_ADAPTER pAd,
6184 IN ULONG Length);
6185
6186void RTMP_QueryPacketInfo(
6187 IN PNDIS_PACKET pPacket,
6188 OUT PACKET_INFO *pPacketInfo,
6189 OUT PUCHAR *pSrcBufVA,
6190 OUT UINT *pSrcBufLen);
6191
6192void RTMP_QueryNextPacketInfo(
6193 IN PNDIS_PACKET *ppPacket,
6194 OUT PACKET_INFO *pPacketInfo,
6195 OUT PUCHAR *pSrcBufVA,
6196 OUT UINT *pSrcBufLen);
6197
6198
6199BOOLEAN RTMP_FillTxBlkInfo(
6200 IN RTMP_ADAPTER *pAd,
6201 IN TX_BLK *pTxBlk);
6202
6203
6204PRTMP_SCATTER_GATHER_LIST
6205rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg);
6206
6207
6208 void announce_802_3_packet(
6209 IN PRTMP_ADAPTER pAd,
6210 IN PNDIS_PACKET pPacket);
6211
6212
6213UINT BA_Reorder_AMSDU_Annnounce(
6214 IN PRTMP_ADAPTER pAd,
6215 IN PNDIS_PACKET pPacket);
6216
6217
6218UINT Handle_AMSDU_Packet(
6219 IN PRTMP_ADAPTER pAd,
6220 IN PUCHAR pData,
6221 IN ULONG DataSize,
6222 IN UCHAR FromWhichBSSID);
6223
6224
6225void convert_802_11_to_802_3_packet(
6226 IN PRTMP_ADAPTER pAd,
6227 IN PNDIS_PACKET pPacket,
6228 IN PUCHAR p8023hdr,
6229 IN PUCHAR pData,
6230 IN ULONG DataSize,
6231 IN UCHAR FromWhichBSSID);
6232
6233
6234PNET_DEV get_netdev_from_bssid(
6235 IN PRTMP_ADAPTER pAd,
6236 IN UCHAR FromWhichBSSID);
6237
6238
6239PNDIS_PACKET duplicate_pkt(
6240 IN PRTMP_ADAPTER pAd,
6241 IN PUCHAR pHeader802_3,
6242 IN UINT HdrLen,
6243 IN PUCHAR pData,
6244 IN ULONG DataSize,
6245 IN UCHAR FromWhichBSSID);
6246
6247
6248PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
6249 IN PRTMP_ADAPTER pAd,
6250 IN PNDIS_PACKET pOldPkt);
6251
6252PNDIS_PACKET duplicate_pkt_with_VLAN(
6253 IN PRTMP_ADAPTER pAd,
6254 IN PUCHAR pHeader802_3,
6255 IN UINT HdrLen,
6256 IN PUCHAR pData,
6257 IN ULONG DataSize,
6258 IN UCHAR FromWhichBSSID);
6259
6260PNDIS_PACKET duplicate_pkt_with_WPI(
6261 IN PRTMP_ADAPTER pAd,
6262 IN PNDIS_PACKET pPacket,
6263 IN UINT32 ext_head_len,
6264 IN UINT32 ext_tail_len);
6265
6266UCHAR VLAN_8023_Header_Copy(
6267 IN PRTMP_ADAPTER pAd,
6268 IN PUCHAR pHeader802_3,
6269 IN UINT HdrLen,
6270 OUT PUCHAR pData,
6271 IN UCHAR FromWhichBSSID);
6272
6273#ifdef DOT11_N_SUPPORT
6274void ba_flush_reordering_timeout_mpdus(
6275 IN PRTMP_ADAPTER pAd,
6276 IN PBA_REC_ENTRY pBAEntry,
6277 IN ULONG Now32);
6278
6279
6280VOID BAOriSessionSetUp(
6281 IN PRTMP_ADAPTER pAd,
6282 IN MAC_TABLE_ENTRY *pEntry,
6283 IN UCHAR TID,
6284 IN USHORT TimeOut,
6285 IN ULONG DelayTime,
6286 IN BOOLEAN isForced);
6287
6288VOID BASessionTearDownALL(
6289 IN OUT PRTMP_ADAPTER pAd,
6290 IN UCHAR Wcid);
6291#endif // DOT11_N_SUPPORT //
6292
6293BOOLEAN OS_Need_Clone_Packet(void);
6294
6295
6296VOID build_tx_packet(
6297 IN PRTMP_ADAPTER pAd,
6298 IN PNDIS_PACKET pPacket,
6299 IN PUCHAR pFrame,
6300 IN ULONG FrameLen);
6301
6302
6303VOID BAOriSessionTearDown(
6304 IN OUT PRTMP_ADAPTER pAd,
6305 IN UCHAR Wcid,
6306 IN UCHAR TID,
6307 IN BOOLEAN bPassive,
6308 IN BOOLEAN bForceSend);
6309
6310VOID BARecSessionTearDown(
6311 IN OUT PRTMP_ADAPTER pAd,
6312 IN UCHAR Wcid,
6313 IN UCHAR TID,
6314 IN BOOLEAN bPassive);
6315
6316BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
6317void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
6318
6319ULONG AutoChBssInsertEntry(
6320 IN PRTMP_ADAPTER pAd,
6321 IN PUCHAR pBssid,
6322 IN CHAR Ssid[],
6323 IN UCHAR SsidLen,
6324 IN UCHAR ChannelNo,
6325 IN CHAR Rssi);
6326
6327void AutoChBssTableInit(
6328 IN PRTMP_ADAPTER pAd);
6329
6330void ChannelInfoInit(
6331 IN PRTMP_ADAPTER pAd);
6332
6333void AutoChBssTableDestroy(
6334 IN PRTMP_ADAPTER pAd);
6335
6336void ChannelInfoDestroy(
6337 IN PRTMP_ADAPTER pAd);
6338
6339UCHAR New_ApAutoSelectChannel(
6340 IN PRTMP_ADAPTER pAd);
6341
6342BOOLEAN rtstrmactohex(
6343 IN char *s1,
6344 IN char *s2);
6345
6346BOOLEAN rtstrcasecmp(
6347 IN char *s1,
6348 IN char *s2);
6349
6350char *rtstrstruncasecmp(
6351 IN char *s1,
6352 IN char *s2);
6353
6354char *rtstrstr(
6355 IN const char * s1,
6356 IN const char * s2);
6357
6358char *rstrtok(
6359 IN char * s,
6360 IN const char * ct);
6361
6362int rtinet_aton(
6363 const char *cp,
6364 unsigned int *addr);
6365
6366////////// common ioctl functions //////////
6367INT Set_DriverVersion_Proc(
6368 IN PRTMP_ADAPTER pAd,
6369 IN PUCHAR arg);
6370
6371INT Set_CountryRegion_Proc(
6372 IN PRTMP_ADAPTER pAd,
6373 IN PUCHAR arg);
6374
6375INT Set_CountryRegionABand_Proc(
6376 IN PRTMP_ADAPTER pAd,
6377 IN PUCHAR arg);
6378
6379INT Set_WirelessMode_Proc(
6380 IN PRTMP_ADAPTER pAd,
6381 IN PUCHAR arg);
6382
6383INT Set_Channel_Proc(
6384 IN PRTMP_ADAPTER pAd,
6385 IN PUCHAR arg);
6386
6387INT Set_ShortSlot_Proc(
6388 IN PRTMP_ADAPTER pAd,
6389 IN PUCHAR arg);
6390
6391INT Set_TxPower_Proc(
6392 IN PRTMP_ADAPTER pAd,
6393 IN PUCHAR arg);
6394
6395INT Set_BGProtection_Proc(
6396 IN PRTMP_ADAPTER pAd,
6397 IN PUCHAR arg);
6398
6399INT Set_TxPreamble_Proc(
6400 IN PRTMP_ADAPTER pAd,
6401 IN PUCHAR arg);
6402
6403INT Set_RTSThreshold_Proc(
6404 IN PRTMP_ADAPTER pAd,
6405 IN PUCHAR arg);
6406
6407INT Set_FragThreshold_Proc(
6408 IN PRTMP_ADAPTER pAd,
6409 IN PUCHAR arg);
6410
6411INT Set_TxBurst_Proc(
6412 IN PRTMP_ADAPTER pAd,
6413 IN PUCHAR arg);
6414
6415#ifdef AGGREGATION_SUPPORT
6416INT Set_PktAggregate_Proc(
6417 IN PRTMP_ADAPTER pAd,
6418 IN PUCHAR arg);
6419#endif
6420
6421INT Set_IEEE80211H_Proc(
6422 IN PRTMP_ADAPTER pAd,
6423 IN PUCHAR arg);
6424
6425#ifdef DBG
6426INT Set_Debug_Proc(
6427 IN PRTMP_ADAPTER pAd,
6428 IN PUCHAR arg);
6429#endif
6430
6431INT Show_DescInfo_Proc(
6432 IN PRTMP_ADAPTER pAd,
6433 IN PUCHAR arg);
6434
6435INT Set_ResetStatCounter_Proc(
6436 IN PRTMP_ADAPTER pAd,
6437 IN PUCHAR arg);
6438
6439#ifdef DOT11_N_SUPPORT
6440INT Set_BASetup_Proc(
6441 IN PRTMP_ADAPTER pAd,
6442 IN PUCHAR arg);
6443
6444INT Set_BADecline_Proc(
6445 IN PRTMP_ADAPTER pAd,
6446 IN PUCHAR arg);
6447
6448INT Set_BAOriTearDown_Proc(
6449 IN PRTMP_ADAPTER pAd,
6450 IN PUCHAR arg);
6451
6452INT Set_BARecTearDown_Proc(
6453 IN PRTMP_ADAPTER pAd,
6454 IN PUCHAR arg);
6455
6456INT Set_HtBw_Proc(
6457 IN PRTMP_ADAPTER pAd,
6458 IN PUCHAR arg);
6459
6460INT Set_HtMcs_Proc(
6461 IN PRTMP_ADAPTER pAd,
6462 IN PUCHAR arg);
6463
6464INT Set_HtGi_Proc(
6465 IN PRTMP_ADAPTER pAd,
6466 IN PUCHAR arg);
6467
6468INT Set_HtOpMode_Proc(
6469 IN PRTMP_ADAPTER pAd,
6470 IN PUCHAR arg);
6471
6472INT Set_HtStbc_Proc(
6473 IN PRTMP_ADAPTER pAd,
6474 IN PUCHAR arg);
6475
6476INT Set_HtHtc_Proc(
6477 IN PRTMP_ADAPTER pAd,
6478 IN PUCHAR arg);
6479
6480INT Set_HtExtcha_Proc(
6481 IN PRTMP_ADAPTER pAd,
6482 IN PUCHAR arg);
6483
6484INT Set_HtMpduDensity_Proc(
6485 IN PRTMP_ADAPTER pAd,
6486 IN PUCHAR arg);
6487
6488INT Set_HtBaWinSize_Proc(
6489 IN PRTMP_ADAPTER pAd,
6490 IN PUCHAR arg);
6491
6492INT Set_HtRdg_Proc(
6493 IN PRTMP_ADAPTER pAd,
6494 IN PUCHAR arg);
6495
6496INT Set_HtLinkAdapt_Proc(
6497 IN PRTMP_ADAPTER pAd,
6498 IN PUCHAR arg);
6499
6500INT Set_HtAmsdu_Proc(
6501 IN PRTMP_ADAPTER pAd,
6502 IN PUCHAR arg);
6503
6504INT Set_HtAutoBa_Proc(
6505 IN PRTMP_ADAPTER pAd,
6506 IN PUCHAR arg);
6507
6508INT Set_HtProtect_Proc(
6509 IN PRTMP_ADAPTER pAd,
6510 IN PUCHAR arg);
6511
6512INT Set_HtMimoPs_Proc(
6513 IN PRTMP_ADAPTER pAd,
6514 IN PUCHAR arg);
6515
6516
6517INT Set_ForceShortGI_Proc(
6518 IN PRTMP_ADAPTER pAd,
6519 IN PUCHAR arg);
6520
6521INT Set_ForceGF_Proc(
6522 IN PRTMP_ADAPTER pAd,
6523 IN PUCHAR arg);
6524
6525INT SetCommonHT(
6526 IN PRTMP_ADAPTER pAd);
6527
6528INT Set_SendPSMPAction_Proc(
6529 IN PRTMP_ADAPTER pAd,
6530 IN PUCHAR arg);
6531
6532INT Set_HtMIMOPSmode_Proc(
6533 IN PRTMP_ADAPTER pAd,
6534 IN PUCHAR arg);
6535
6536
6537INT Set_HtTxBASize_Proc(
6538 IN PRTMP_ADAPTER pAd,
6539 IN PUCHAR arg);
6540#endif // DOT11_N_SUPPORT //
6541
6542
6543
6544#ifdef CONFIG_STA_SUPPORT
6545//Dls , kathy
6546VOID RTMPSendDLSTearDownFrame(
6547 IN PRTMP_ADAPTER pAd,
6548 IN PUCHAR pDA);
6549
6550#ifdef DOT11_N_SUPPORT
6551//Block ACK
6552VOID QueryBATABLE(
6553 IN PRTMP_ADAPTER pAd,
6554 OUT PQUERYBA_TABLE pBAT);
6555#endif // DOT11_N_SUPPORT //
6556
6557#ifdef WPA_SUPPLICANT_SUPPORT
6558INT WpaCheckEapCode(
6559 IN PRTMP_ADAPTER pAd,
6560 IN PUCHAR pFrame,
6561 IN USHORT FrameLen,
6562 IN USHORT OffSet);
6563
6564VOID WpaSendMicFailureToWpaSupplicant(
6565 IN PRTMP_ADAPTER pAd,
6566 IN BOOLEAN bUnicast);
6567
6568VOID SendAssocIEsToWpaSupplicant(
6569 IN PRTMP_ADAPTER pAd);
6570#endif // WPA_SUPPLICANT_SUPPORT //
6571
6572#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
6573int wext_notify_event_assoc(
6574 IN RTMP_ADAPTER *pAd);
6575#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
6576
6577#endif // CONFIG_STA_SUPPORT //
6578
6579
6580
6581#ifdef DOT11_N_SUPPORT
6582VOID Handle_BSS_Width_Trigger_Events(
6583 IN PRTMP_ADAPTER pAd);
6584
6585void build_ext_channel_switch_ie(
6586 IN PRTMP_ADAPTER pAd,
6587 IN HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE *pIE);
6588#endif // DOT11_N_SUPPORT //
6589
6590
6591BOOLEAN APRxDoneInterruptHandle(
6592 IN PRTMP_ADAPTER pAd);
6593
6594BOOLEAN STARxDoneInterruptHandle(
6595 IN PRTMP_ADAPTER pAd,
6596 IN BOOLEAN argc);
6597
6598#ifdef DOT11_N_SUPPORT
6599// AMPDU packet indication
6600VOID Indicate_AMPDU_Packet(
6601 IN PRTMP_ADAPTER pAd,
6602 IN RX_BLK *pRxBlk,
6603 IN UCHAR FromWhichBSSID);
6604
6605// AMSDU packet indication
6606VOID Indicate_AMSDU_Packet(
6607 IN PRTMP_ADAPTER pAd,
6608 IN RX_BLK *pRxBlk,
6609 IN UCHAR FromWhichBSSID);
6610#endif // DOT11_N_SUPPORT //
6611
6612// Normal legacy Rx packet indication
6613VOID Indicate_Legacy_Packet(
6614 IN PRTMP_ADAPTER pAd,
6615 IN RX_BLK *pRxBlk,
6616 IN UCHAR FromWhichBSSID);
6617
6618VOID Indicate_EAPOL_Packet(
6619 IN PRTMP_ADAPTER pAd,
6620 IN RX_BLK *pRxBlk,
6621 IN UCHAR FromWhichBSSID);
6622
6623void update_os_packet_info(
6624 IN PRTMP_ADAPTER pAd,
6625 IN RX_BLK *pRxBlk,
6626 IN UCHAR FromWhichBSSID);
6627
6628void wlan_802_11_to_802_3_packet(
6629 IN PRTMP_ADAPTER pAd,
6630 IN RX_BLK *pRxBlk,
6631 IN PUCHAR pHeader802_3,
6632 IN UCHAR FromWhichBSSID);
6633
6634UINT deaggregate_AMSDU_announce(
6635 IN PRTMP_ADAPTER pAd,
6636 PNDIS_PACKET pPacket,
6637 IN PUCHAR pData,
6638 IN ULONG DataSize);
6639
6640
6641#ifdef CONFIG_STA_SUPPORT
6642// remove LLC and get 802_3 Header
6643#define RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(_pRxBlk, _pHeader802_3) \
6644{ \
6645 PUCHAR _pRemovedLLCSNAP = NULL, _pDA, _pSA; \
6646 \
6647 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH)) \
6648 { \
6649 _pDA = _pRxBlk->pHeader->Addr3; \
6650 _pSA = (PUCHAR)_pRxBlk->pHeader + sizeof(HEADER_802_11); \
6651 } \
6652 else \
6653 { \
6654 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_INFRA)) \
6655 { \
6656 _pDA = _pRxBlk->pHeader->Addr1; \
6657 if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_DLS)) \
6658 _pSA = _pRxBlk->pHeader->Addr2; \
6659 else \
6660 _pSA = _pRxBlk->pHeader->Addr3; \
6661 } \
6662 else \
6663 { \
6664 _pDA = _pRxBlk->pHeader->Addr1; \
6665 _pSA = _pRxBlk->pHeader->Addr2; \
6666 } \
6667 } \
6668 \
6669 CONVERT_TO_802_3(_pHeader802_3, _pDA, _pSA, _pRxBlk->pData, \
6670 _pRxBlk->DataSize, _pRemovedLLCSNAP); \
6671}
6672#endif // CONFIG_STA_SUPPORT //
6673
6674
6675BOOLEAN APFowardWirelessStaToWirelessSta(
6676 IN PRTMP_ADAPTER pAd,
6677 IN PNDIS_PACKET pPacket,
6678 IN ULONG FromWhichBSSID);
6679
6680VOID Announce_or_Forward_802_3_Packet(
6681 IN PRTMP_ADAPTER pAd,
6682 IN PNDIS_PACKET pPacket,
6683 IN UCHAR FromWhichBSSID);
6684
6685VOID Sta_Announce_or_Forward_802_3_Packet(
6686 IN PRTMP_ADAPTER pAd,
6687 IN PNDIS_PACKET pPacket,
6688 IN UCHAR FromWhichBSSID);
6689
6690
6691#ifdef CONFIG_STA_SUPPORT
6692#define ANNOUNCE_OR_FORWARD_802_3_PACKET(_pAd, _pPacket, _FromWhichBSS)\
6693 Sta_Announce_or_Forward_802_3_Packet(_pAd, _pPacket, _FromWhichBSS);
6694 //announce_802_3_packet(_pAd, _pPacket);
6695#endif // CONFIG_STA_SUPPORT //
6696
6697
6698PNDIS_PACKET DuplicatePacket(
6699 IN PRTMP_ADAPTER pAd,
6700 IN PNDIS_PACKET pPacket,
6701 IN UCHAR FromWhichBSSID);
6702
6703
6704PNDIS_PACKET ClonePacket(
6705 IN PRTMP_ADAPTER pAd,
6706 IN PNDIS_PACKET pPacket,
6707 IN PUCHAR pData,
6708 IN ULONG DataSize);
6709
6710
6711// Normal, AMPDU or AMSDU
6712VOID CmmRxnonRalinkFrameIndicate(
6713 IN PRTMP_ADAPTER pAd,
6714 IN RX_BLK *pRxBlk,
6715 IN UCHAR FromWhichBSSID);
6716
6717VOID CmmRxRalinkFrameIndicate(
6718 IN PRTMP_ADAPTER pAd,
6719 IN MAC_TABLE_ENTRY *pEntry,
6720 IN RX_BLK *pRxBlk,
6721 IN UCHAR FromWhichBSSID);
6722
6723VOID Update_Rssi_Sample(
6724 IN PRTMP_ADAPTER pAd,
6725 IN RSSI_SAMPLE *pRssi,
6726 IN PRXWI_STRUC pRxWI);
6727
6728PNDIS_PACKET GetPacketFromRxRing(
6729 IN PRTMP_ADAPTER pAd,
6730 OUT PRT28XX_RXD_STRUC pSaveRxD,
6731 OUT BOOLEAN *pbReschedule,
6732 IN OUT UINT32 *pRxPending);
6733
6734PNDIS_PACKET RTMPDeFragmentDataFrame(
6735 IN PRTMP_ADAPTER pAd,
6736 IN RX_BLK *pRxBlk);
6737
6738////////////////////////////////////////
6739
6740
6741
6742
6743
6744#ifdef SNMP_SUPPORT
6745//for snmp , kathy
6746typedef struct _DefaultKeyIdxValue
6747{
6748 UCHAR KeyIdx;
6749 UCHAR Value[16];
6750} DefaultKeyIdxValue, *PDefaultKeyIdxValue;
6751#endif
6752
6753
6754#ifdef CONFIG_STA_SUPPORT
6755enum {
6756 DIDmsg_lnxind_wlansniffrm = 0x00000044,
6757 DIDmsg_lnxind_wlansniffrm_hosttime = 0x00010044,
6758 DIDmsg_lnxind_wlansniffrm_mactime = 0x00020044,
6759 DIDmsg_lnxind_wlansniffrm_channel = 0x00030044,
6760 DIDmsg_lnxind_wlansniffrm_rssi = 0x00040044,
6761 DIDmsg_lnxind_wlansniffrm_sq = 0x00050044,
6762 DIDmsg_lnxind_wlansniffrm_signal = 0x00060044,
6763 DIDmsg_lnxind_wlansniffrm_noise = 0x00070044,
6764 DIDmsg_lnxind_wlansniffrm_rate = 0x00080044,
6765 DIDmsg_lnxind_wlansniffrm_istx = 0x00090044,
6766 DIDmsg_lnxind_wlansniffrm_frmlen = 0x000A0044
6767};
6768enum {
6769 P80211ENUM_msgitem_status_no_value = 0x00
6770};
6771enum {
6772 P80211ENUM_truth_false = 0x00,
6773 P80211ENUM_truth_true = 0x01
6774};
6775
6776/* Definition from madwifi */
6777typedef struct {
6778 UINT32 did;
6779 UINT16 status;
6780 UINT16 len;
6781 UINT32 data;
6782} p80211item_uint32_t;
6783
6784typedef struct {
6785 UINT32 msgcode;
6786 UINT32 msglen;
6787#define WLAN_DEVNAMELEN_MAX 16
6788 UINT8 devname[WLAN_DEVNAMELEN_MAX];
6789 p80211item_uint32_t hosttime;
6790 p80211item_uint32_t mactime;
6791 p80211item_uint32_t channel;
6792 p80211item_uint32_t rssi;
6793 p80211item_uint32_t sq;
6794 p80211item_uint32_t signal;
6795 p80211item_uint32_t noise;
6796 p80211item_uint32_t rate;
6797 p80211item_uint32_t istx;
6798 p80211item_uint32_t frmlen;
6799} wlan_ng_prism2_header;
6800
6801/* The radio capture header precedes the 802.11 header. */
6802typedef struct PACKED _ieee80211_radiotap_header {
6803 UINT8 it_version; /* Version 0. Only increases
6804 * for drastic changes,
6805 * introduction of compatible
6806 * new fields does not count.
6807 */
6808 UINT8 it_pad;
6809 UINT16 it_len; /* length of the whole
6810 * header in bytes, including
6811 * it_version, it_pad,
6812 * it_len, and data fields.
6813 */
6814 UINT32 it_present; /* A bitmap telling which
6815 * fields are present. Set bit 31
6816 * (0x80000000) to extend the
6817 * bitmap by another 32 bits.
6818 * Additional extensions are made
6819 * by setting bit 31.
6820 */
6821}ieee80211_radiotap_header ;
6822
6823enum ieee80211_radiotap_type {
6824 IEEE80211_RADIOTAP_TSFT = 0,
6825 IEEE80211_RADIOTAP_FLAGS = 1,
6826 IEEE80211_RADIOTAP_RATE = 2,
6827 IEEE80211_RADIOTAP_CHANNEL = 3,
6828 IEEE80211_RADIOTAP_FHSS = 4,
6829 IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
6830 IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
6831 IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
6832 IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
6833 IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
6834 IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
6835 IEEE80211_RADIOTAP_ANTENNA = 11,
6836 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
6837 IEEE80211_RADIOTAP_DB_ANTNOISE = 13
6838};
6839
6840#define WLAN_RADIOTAP_PRESENT ( \
6841 (1 << IEEE80211_RADIOTAP_TSFT) | \
6842 (1 << IEEE80211_RADIOTAP_FLAGS) | \
6843 (1 << IEEE80211_RADIOTAP_RATE) | \
6844 0)
6845
6846typedef struct _wlan_radiotap_header {
6847 ieee80211_radiotap_header wt_ihdr;
6848 INT64 wt_tsft;
6849 UINT8 wt_flags;
6850 UINT8 wt_rate;
6851} wlan_radiotap_header;
6852/* Definition from madwifi */
6853
6854void send_monitor_packets(
6855 IN PRTMP_ADAPTER pAd,
6856 IN RX_BLK *pRxBlk);
6857
6858#if WIRELESS_EXT >= 12
6859// This function will be called when query /proc
6860struct iw_statistics *rt28xx_get_wireless_stats(
6861 IN struct net_device *net_dev);
6862#endif
6863
6864VOID RTMPSetDesiredRates(
6865 IN PRTMP_ADAPTER pAdapter,
6866 IN LONG Rates);
6867#endif // CONFIG_STA_SUPPORT //
6868
6869INT Set_FixedTxMode_Proc(
6870 IN PRTMP_ADAPTER pAd,
6871 IN PUCHAR arg);
6872
6873#ifdef CONFIG_APSTA_MIXED_SUPPORT
6874INT Set_OpMode_Proc(
6875 IN PRTMP_ADAPTER pAd,
6876 IN PUCHAR arg);
6877#endif // CONFIG_APSTA_MIXED_SUPPORT //
6878
6879static inline char* GetPhyMode(
6880 int Mode)
6881{
6882 switch(Mode)
6883 {
6884 case MODE_CCK:
6885 return "CCK";
6886
6887 case MODE_OFDM:
6888 return "OFDM";
6889#ifdef DOT11_N_SUPPORT
6890 case MODE_HTMIX:
6891 return "HTMIX";
6892
6893 case MODE_HTGREENFIELD:
6894 return "GREEN";
6895#endif // DOT11_N_SUPPORT //
6896 default:
6897 return "N/A";
6898 }
6899}
6900
6901
6902static inline char* GetBW(
6903 int BW)
6904{
6905 switch(BW)
6906 {
6907 case BW_10:
6908 return "10M";
6909
6910 case BW_20:
6911 return "20M";
6912#ifdef DOT11_N_SUPPORT
6913 case BW_40:
6914 return "40M";
6915#endif // DOT11_N_SUPPORT //
6916 default:
6917 return "N/A";
6918 }
6919}
6920
6921
6922VOID RT28xxThreadTerminate(
6923 IN RTMP_ADAPTER *pAd);
6924
6925BOOLEAN RT28XXChipsetCheck(
6926 IN void *_dev_p);
6927
6928BOOLEAN RT28XXNetDevInit(
6929 IN void *_dev_p,
6930 IN struct net_device *net_dev,
6931 IN RTMP_ADAPTER *pAd);
6932
6933BOOLEAN RT28XXProbePostConfig(
6934 IN void *_dev_p,
6935 IN RTMP_ADAPTER *pAd,
6936 IN INT32 argc);
6937
6938VOID RT28XXDMADisable(
6939 IN RTMP_ADAPTER *pAd);
6940
6941VOID RT28XXDMAEnable(
6942 IN RTMP_ADAPTER *pAd);
6943
6944VOID RT28xx_UpdateBeaconToAsic(
6945 IN RTMP_ADAPTER * pAd,
6946 IN INT apidx,
6947 IN ULONG BeaconLen,
6948 IN ULONG UpdatePos);
6949
6950INT rt28xx_ioctl(
6951 IN struct net_device *net_dev,
6952 IN OUT struct ifreq *rq,
6953 IN INT cmd);
6954
6955
6956#ifdef CONFIG_STA_SUPPORT
6957INT rt28xx_sta_ioctl(
6958 IN struct net_device *net_dev,
6959 IN OUT struct ifreq *rq,
6960 IN INT cmd);
6961#endif // CONFIG_STA_SUPPORT //
6962
6963BOOLEAN RT28XXSecurityKeyAdd(
6964 IN PRTMP_ADAPTER pAd,
6965 IN ULONG apidx,
6966 IN ULONG KeyIdx,
6967 IN MAC_TABLE_ENTRY *pEntry);
6968
6969////////////////////////////////////////
6970PNDIS_PACKET GetPacketFromRxRing(
6971 IN PRTMP_ADAPTER pAd,
6972 OUT PRT28XX_RXD_STRUC pSaveRxD,
6973 OUT BOOLEAN *pbReschedule,
6974 IN OUT UINT32 *pRxPending);
6975
6976
6977void kill_thread_task(PRTMP_ADAPTER pAd);
6978
6979void tbtt_tasklet(unsigned long data);
6980
6981#ifdef RT2860
6982//
6983// Function Prototype in cmm_data_2860.c
6984//
6985USHORT RtmpPCI_WriteTxResource(
6986 IN PRTMP_ADAPTER pAd,
6987 IN TX_BLK *pTxBlk,
6988 IN BOOLEAN bIsLast,
6989 OUT USHORT *FreeNumber);
6990
6991USHORT RtmpPCI_WriteSingleTxResource(
6992 IN PRTMP_ADAPTER pAd,
6993 IN TX_BLK *pTxBlk,
6994 IN BOOLEAN bIsLast,
6995 OUT USHORT *FreeNumber);
6996
6997USHORT RtmpPCI_WriteMultiTxResource(
6998 IN PRTMP_ADAPTER pAd,
6999 IN TX_BLK *pTxBlk,
7000 IN UCHAR frameNum,
7001 OUT USHORT *FreeNumber);
7002
7003USHORT RtmpPCI_WriteFragTxResource(
7004 IN PRTMP_ADAPTER pAd,
7005 IN TX_BLK *pTxBlk,
7006 IN UCHAR fragNum,
7007 OUT USHORT *FreeNumber);
7008
7009USHORT RtmpPCI_WriteSubTxResource(
7010 IN PRTMP_ADAPTER pAd,
7011 IN TX_BLK *pTxBlk,
7012 IN BOOLEAN bIsLast,
7013 OUT USHORT *FreeNumber);
7014
7015VOID RtmpPCI_FinalWriteTxResource(
7016 IN PRTMP_ADAPTER pAd,
7017 IN TX_BLK *pTxBlk,
7018 IN USHORT totalMPDUSize,
7019 IN USHORT FirstTxIdx);
7020
7021VOID RtmpPCIDataLastTxIdx(
7022 IN PRTMP_ADAPTER pAd,
7023 IN UCHAR QueIdx,
7024 IN USHORT LastTxIdx);
7025
7026VOID RtmpPCIDataKickOut(
7027 IN PRTMP_ADAPTER pAd,
7028 IN TX_BLK *pTxBlk,
7029 IN UCHAR QueIdx);
7030
7031
7032int RtmpPCIMgmtKickOut(
7033 IN RTMP_ADAPTER *pAd,
7034 IN UCHAR QueIdx,
7035 IN PNDIS_PACKET pPacket,
7036 IN PUCHAR pSrcBufVA,
7037 IN UINT SrcBufLen);
7038
7039
7040NDIS_STATUS RTMPCheckRxError(
7041 IN PRTMP_ADAPTER pAd,
7042 IN PHEADER_802_11 pHeader,
7043 IN PRXWI_STRUC pRxWI,
7044 IN PRT28XX_RXD_STRUC pRxD);
7045
7046#ifdef CONFIG_STA_SUPPORT
7047VOID RTMPInitPCIeLinkCtrlValue(
7048 IN PRTMP_ADAPTER pAd);
7049
7050VOID RTMPFindHostPCIDev(
7051 IN PRTMP_ADAPTER pAd);
7052
7053VOID RTMPPCIeLinkCtrlValueRestore(
7054 IN PRTMP_ADAPTER pAd,
7055 IN UCHAR Level);
7056
7057VOID RTMPPCIeLinkCtrlSetting(
7058 IN PRTMP_ADAPTER pAd,
7059 IN USHORT Max);
7060
7061VOID RT28xxPciAsicRadioOff(
7062 IN PRTMP_ADAPTER pAd,
7063 IN UCHAR Level,
7064 IN USHORT TbttNumToNextWakeUp);
7065
7066BOOLEAN RT28xxPciAsicRadioOn(
7067 IN PRTMP_ADAPTER pAd,
7068 IN UCHAR Level);
7069
7070VOID RT28xxPciStaAsicForceWakeup(
7071 IN PRTMP_ADAPTER pAd,
7072 IN BOOLEAN bFromTx);
7073
7074VOID RT28xxPciStaAsicSleepThenAutoWakeup(
7075 IN PRTMP_ADAPTER pAd,
7076 IN USHORT TbttNumToNextWakeUp);
7077
7078VOID PsPollWakeExec(
7079 IN PVOID SystemSpecific1,
7080 IN PVOID FunctionContext,
7081 IN PVOID SystemSpecific2,
7082 IN PVOID SystemSpecific3);
7083
7084VOID RadioOnExec(
7085 IN PVOID SystemSpecific1,
7086 IN PVOID FunctionContext,
7087 IN PVOID SystemSpecific2,
7088 IN PVOID SystemSpecific3);
7089#endif // CONFIG_STA_SUPPORT //
7090
7091VOID RT28xxPciMlmeRadioOn(
7092 IN PRTMP_ADAPTER pAd);
7093
7094VOID RT28xxPciMlmeRadioOFF(
7095 IN PRTMP_ADAPTER pAd);
7096#endif // RT2860 //
7097
7098VOID AsicTurnOffRFClk(
7099 IN PRTMP_ADAPTER pAd,
7100 IN UCHAR Channel);
7101
7102VOID AsicTurnOnRFClk(
7103 IN PRTMP_ADAPTER pAd,
7104 IN UCHAR Channel);
7105
7106
7107////////////////////////////////////////
7108
7109VOID QBSS_LoadInit(
7110 IN RTMP_ADAPTER *pAd);
7111
7112UINT32 QBSS_LoadElementAppend(
7113 IN RTMP_ADAPTER *pAd,
7114 OUT UINT8 *buf_p);
7115
7116VOID QBSS_LoadUpdate(
7117 IN RTMP_ADAPTER *pAd);
7118
7119///////////////////////////////////////
7120INT RTMPShowCfgValue(
7121 IN PRTMP_ADAPTER pAd,
7122 IN PUCHAR pName,
7123 IN PUCHAR pBuf);
7124
7125PCHAR RTMPGetRalinkAuthModeStr(
7126 IN NDIS_802_11_AUTHENTICATION_MODE authMode);
7127
7128PCHAR RTMPGetRalinkEncryModeStr(
7129 IN USHORT encryMode);
7130//////////////////////////////////////
7131
7132#ifdef CONFIG_STA_SUPPORT
7133VOID AsicStaBbpTuning(
7134 IN PRTMP_ADAPTER pAd);
7135#endif // CONFIG_STA_SUPPORT //
7136
7137void RTMP_IndicateMediaState(
7138 IN PRTMP_ADAPTER pAd);
7139
7140VOID ReSyncBeaconTime(
7141 IN PRTMP_ADAPTER pAd);
7142
7143VOID RTMPSetAGCInitValue(
7144 IN PRTMP_ADAPTER pAd,
7145 IN UCHAR BandWidth);
7146
7147int rt28xx_close(IN PNET_DEV dev);
7148int rt28xx_open(IN PNET_DEV dev);
7149
7150__inline INT VIRTUAL_IF_UP(PRTMP_ADAPTER pAd)
7151{
7152extern VOID MeshMakeBeacon(IN PRTMP_ADAPTER pAd, IN UCHAR idx);
7153extern VOID MeshUpdateBeaconFrame(IN PRTMP_ADAPTER pAd, IN UCHAR idx);
7154
7155 if (VIRTUAL_IF_NUM(pAd) == 0)
7156 {
7157 if (rt28xx_open(pAd->net_dev) != 0)
7158 return -1;
7159 }
7160 else
7161 {
7162 }
7163 VIRTUAL_IF_INC(pAd);
7164 return 0;
7165}
7166
7167__inline VOID VIRTUAL_IF_DOWN(PRTMP_ADAPTER pAd)
7168{
7169 VIRTUAL_IF_DEC(pAd);
7170 if (VIRTUAL_IF_NUM(pAd) == 0)
7171 rt28xx_close(pAd->net_dev);
7172 return;
7173}
7174
7175
7176#endif // __RTMP_H__
7177
diff --git a/drivers/staging/rt2860/rtmp_ckipmic.h b/drivers/staging/rt2860/rtmp_ckipmic.h
new file mode 100644
index 00000000000..a3d949a39d3
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/rtmp_def.h b/drivers/staging/rt2860/rtmp_def.h
new file mode 100644
index 00000000000..bb6f37b0bdc
--- /dev/null
+++ b/drivers/staging/rt2860/rtmp_def.h
@@ -0,0 +1,1588 @@
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 RALINK_2883_VERSION ((UINT32)0x28830300)
67#define RALINK_2880E_VERSION ((UINT32)0x28720200)
68#define RALINK_3070_VERSION ((UINT32)0x30700200)
69
70//
71// NDIS version in use by the NIC driver.
72// The high byte is the major version. The low byte is the minor version.
73//
74#ifdef NDIS51_MINIPORT
75#define NIC_DRIVER_VERSION 0x0501
76#else
77#define NIC_DRIVER_VERSION 0x0500
78#endif
79
80//
81// NDIS media type, current is ethernet, change if native wireless supported
82//
83#define NIC_MEDIA_TYPE NdisMedium802_3
84#define NIC_PCI_HDR_LENGTH 0xe2
85#define NIC_MAX_PACKET_SIZE 2304
86#define NIC_HEADER_SIZE 14
87#define MAX_MAP_REGISTERS_NEEDED 32
88#define MIN_MAP_REGISTERS_NEEDED 2 //Todo: should consider fragment issue.
89
90//
91// interface type, we use PCI
92//
93#define NIC_INTERFACE_TYPE NdisInterfacePci
94#define NIC_INTERRUPT_MODE NdisInterruptLevelSensitive
95
96//
97// buffer size passed in NdisMQueryAdapterResources
98// We should only need three adapter resources (IO, interrupt and memory),
99// Some devices get extra resources, so have room for 10 resources
100// UF_SIZE (sizeof(NDIS_RESOURCE_LIST) + (10*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)))
101
102
103#define NIC_RESOURCE_B//
104// IO space length
105//
106#define NIC_MAP_IOSPACE_LENGTH sizeof(CSR_STRUC)
107
108#define MAX_RX_PKT_LEN 1520
109
110//
111// Entry number for each DMA descriptor ring
112//
113
114#ifdef RT2860
115#define TX_RING_SIZE 64 //64
116#define MGMT_RING_SIZE 128
117#define RX_RING_SIZE 128 //64
118#define MAX_TX_PROCESS TX_RING_SIZE //8
119#define MAX_DMA_DONE_PROCESS TX_RING_SIZE
120#define MAX_TX_DONE_PROCESS TX_RING_SIZE //8
121#define LOCAL_TXBUF_SIZE 2
122#endif // RT2860 //
123
124
125#ifdef MULTIPLE_CARD_SUPPORT
126// MC: Multple Cards
127#define MAX_NUM_OF_MULTIPLE_CARD 32
128#endif // MULTIPLE_CARD_SUPPORT //
129
130#define MAX_RX_PROCESS 128 //64 //32
131#define NUM_OF_LOCAL_TXBUF 2
132#define TXD_SIZE 16
133#define TXWI_SIZE 16
134#define RXD_SIZE 16
135#define RXWI_SIZE 16
136// TXINFO_SIZE + TXWI_SIZE + 802.11 Header Size + AMSDU sub frame header
137#define TX_DMA_1ST_BUFFER_SIZE 96 // only the 1st physical buffer is pre-allocated
138#define MGMT_DMA_BUFFER_SIZE 1536 //2048
139#define RX_BUFFER_AGGRESIZE 3840 //3904 //3968 //4096 //2048 //4096
140#define RX_BUFFER_NORMSIZE 3840 //3904 //3968 //4096 //2048 //4096
141#define TX_BUFFER_NORMSIZE RX_BUFFER_NORMSIZE
142#define MAX_FRAME_SIZE 2346 // Maximum 802.11 frame size
143#define MAX_AGGREGATION_SIZE 3840 //3904 //3968 //4096
144#define MAX_NUM_OF_TUPLE_CACHE 2
145#define MAX_MCAST_LIST_SIZE 32
146#define MAX_LEN_OF_VENDOR_DESC 64
147//#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
148#define MAX_SIZE_OF_MCAST_PSQ 32
149
150#define MAX_RX_PROCESS_CNT (RX_RING_SIZE)
151
152
153#define MAX_PACKETS_IN_QUEUE (512) //(512) // to pass WMM A5-WPAPSK
154#define MAX_PACKETS_IN_MCAST_PS_QUEUE 32
155#define MAX_PACKETS_IN_PS_QUEUE 128 //32
156#define WMM_NUM_OF_AC 4 /* AC0, AC1, AC2, and AC3 */
157
158
159
160// RxFilter
161#define STANORMAL 0x17f97
162#define APNORMAL 0x15f97
163//
164// RTMP_ADAPTER flags
165//
166#define fRTMP_ADAPTER_MAP_REGISTER 0x00000001
167#define fRTMP_ADAPTER_INTERRUPT_IN_USE 0x00000002
168#define fRTMP_ADAPTER_HARDWARE_ERROR 0x00000004
169#define fRTMP_ADAPTER_SCATTER_GATHER 0x00000008
170#define fRTMP_ADAPTER_SEND_PACKET_ERROR 0x00000010
171#define fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS 0x00000020
172#define fRTMP_ADAPTER_HALT_IN_PROGRESS 0x00000040
173#define fRTMP_ADAPTER_RESET_IN_PROGRESS 0x00000080
174#define fRTMP_ADAPTER_NIC_NOT_EXIST 0x00000100
175#define fRTMP_ADAPTER_TX_RING_ALLOCATED 0x00000200
176#define fRTMP_ADAPTER_REMOVE_IN_PROGRESS 0x00000400
177#define fRTMP_ADAPTER_MIMORATE_INUSED 0x00000800
178#define fRTMP_ADAPTER_RX_RING_ALLOCATED 0x00001000
179#define fRTMP_ADAPTER_INTERRUPT_ACTIVE 0x00002000
180#define fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS 0x00004000
181#define fRTMP_ADAPTER_REASSOC_IN_PROGRESS 0x00008000
182#define fRTMP_ADAPTER_MEDIA_STATE_PENDING 0x00010000
183#define fRTMP_ADAPTER_RADIO_OFF 0x00020000
184#define fRTMP_ADAPTER_BULKOUT_RESET 0x00040000
185#define fRTMP_ADAPTER_BULKIN_RESET 0x00080000
186#define fRTMP_ADAPTER_RDG_ACTIVE 0x00100000
187#define fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE 0x00200000
188#define fRTMP_ADAPTER_SCAN_2040 0x04000000
189#define fRTMP_ADAPTER_RADIO_MEASUREMENT 0x08000000
190
191#define fRTMP_ADAPTER_START_UP 0x10000000 //Devive already initialized and enabled Tx/Rx.
192#define fRTMP_ADAPTER_MEDIA_STATE_CHANGE 0x20000000
193#define fRTMP_ADAPTER_IDLE_RADIO_OFF 0x40000000
194
195//
196// STA operation status flags
197//
198#define fOP_STATUS_INFRA_ON 0x00000001
199#define fOP_STATUS_ADHOC_ON 0x00000002
200#define fOP_STATUS_BG_PROTECTION_INUSED 0x00000004
201#define fOP_STATUS_SHORT_SLOT_INUSED 0x00000008
202#define fOP_STATUS_SHORT_PREAMBLE_INUSED 0x00000010
203#define fOP_STATUS_RECEIVE_DTIM 0x00000020
204#define fOP_STATUS_MEDIA_STATE_CONNECTED 0x00000080
205#define fOP_STATUS_WMM_INUSED 0x00000100
206#define fOP_STATUS_AGGREGATION_INUSED 0x00000200
207#define fOP_STATUS_DOZE 0x00000400 // debug purpose
208#define fOP_STATUS_PIGGYBACK_INUSED 0x00000800 // piggy-back, and aggregation
209#define fOP_STATUS_APSD_INUSED 0x00001000
210#define fOP_STATUS_TX_AMSDU_INUSED 0x00002000
211#define fOP_STATUS_MAX_RETRY_ENABLED 0x00004000
212#define fOP_STATUS_WAKEUP_NOW 0x00008000
213#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE 0x00020000
214
215#ifdef DOT11N_DRAFT3
216#define fOP_STATUS_SCAN_2040 0x00040000
217#endif // DOT11N_DRAFT3 //
218
219#define CCKSETPROTECT 0x1
220#define OFDMSETPROTECT 0x2
221#define MM20SETPROTECT 0x4
222#define MM40SETPROTECT 0x8
223#define GF20SETPROTECT 0x10
224#define GR40SETPROTECT 0x20
225#define ALLN_SETPROTECT (GR40SETPROTECT | GF20SETPROTECT | MM40SETPROTECT | MM20SETPROTECT)
226
227//
228// AP's client table operation status flags
229//
230#define fCLIENT_STATUS_WMM_CAPABLE 0x00000001 // CLIENT can parse QOS DATA frame
231#define fCLIENT_STATUS_AGGREGATION_CAPABLE 0x00000002 // CLIENT can receive Ralink's proprietary TX aggregation frame
232#define fCLIENT_STATUS_PIGGYBACK_CAPABLE 0x00000004 // CLIENT support piggy-back
233#define fCLIENT_STATUS_AMSDU_INUSED 0x00000008
234#define fCLIENT_STATUS_SGI20_CAPABLE 0x00000010
235#define fCLIENT_STATUS_SGI40_CAPABLE 0x00000020
236#define fCLIENT_STATUS_TxSTBC_CAPABLE 0x00000040
237#define fCLIENT_STATUS_RxSTBC_CAPABLE 0x00000080
238#define fCLIENT_STATUS_HTC_CAPABLE 0x00000100
239#define fCLIENT_STATUS_RDG_CAPABLE 0x00000200
240#define fCLIENT_STATUS_MCSFEEDBACK_CAPABLE 0x00000400
241#define fCLIENT_STATUS_APSD_CAPABLE 0x00000800 /* UAPSD STATION */
242
243#ifdef DOT11N_DRAFT3
244#define fCLIENT_STATUS_BSSCOEXIST_CAPABLE 0x00001000
245#endif // DOT11N_DRAFT3 //
246
247#define fCLIENT_STATUS_RALINK_CHIPSET 0x00100000
248//
249// STA configuration flags
250//
251
252// 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case
253#define HT_NO_PROTECT 0
254#define HT_LEGACY_PROTECT 1
255#define HT_40_PROTECT 2
256#define HT_2040_PROTECT 3
257#define HT_RTSCTS_6M 7
258//following is our own definition in order to turn on our ASIC protection register in INFRASTRUCTURE.
259#define HT_ATHEROS 8 // rt2860c has problem with atheros chip. we need to turn on RTS/CTS .
260#define HT_FORCERTSCTS 9 // Force turn on RTS/CTS first. then go to evaluate if this force RTS is necessary.
261
262//
263// RX Packet Filter control flags. Apply on pAd->PacketFilter
264//
265#define fRX_FILTER_ACCEPT_DIRECT NDIS_PACKET_TYPE_DIRECTED
266#define fRX_FILTER_ACCEPT_MULTICAST NDIS_PACKET_TYPE_MULTICAST
267#define fRX_FILTER_ACCEPT_BROADCAST NDIS_PACKET_TYPE_BROADCAST
268#define fRX_FILTER_ACCEPT_ALL_MULTICAST NDIS_PACKET_TYPE_ALL_MULTICAST
269
270//
271// Error code section
272//
273// NDIS_ERROR_CODE_ADAPTER_NOT_FOUND
274#define ERRLOG_READ_PCI_SLOT_FAILED 0x00000101L
275#define ERRLOG_WRITE_PCI_SLOT_FAILED 0x00000102L
276#define ERRLOG_VENDOR_DEVICE_NOMATCH 0x00000103L
277
278// NDIS_ERROR_CODE_ADAPTER_DISABLED
279#define ERRLOG_BUS_MASTER_DISABLED 0x00000201L
280
281// NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION
282#define ERRLOG_INVALID_SPEED_DUPLEX 0x00000301L
283#define ERRLOG_SET_SECONDARY_FAILED 0x00000302L
284
285// NDIS_ERROR_CODE_OUT_OF_RESOURCES
286#define ERRLOG_OUT_OF_MEMORY 0x00000401L
287#define ERRLOG_OUT_OF_SHARED_MEMORY 0x00000402L
288#define ERRLOG_OUT_OF_MAP_REGISTERS 0x00000403L
289#define ERRLOG_OUT_OF_BUFFER_POOL 0x00000404L
290#define ERRLOG_OUT_OF_NDIS_BUFFER 0x00000405L
291#define ERRLOG_OUT_OF_PACKET_POOL 0x00000406L
292#define ERRLOG_OUT_OF_NDIS_PACKET 0x00000407L
293#define ERRLOG_OUT_OF_LOOKASIDE_MEMORY 0x00000408L
294
295// NDIS_ERROR_CODE_HARDWARE_FAILURE
296#define ERRLOG_SELFTEST_FAILED 0x00000501L
297#define ERRLOG_INITIALIZE_ADAPTER 0x00000502L
298#define ERRLOG_REMOVE_MINIPORT 0x00000503L
299
300// NDIS_ERROR_CODE_RESOURCE_CONFLICT
301#define ERRLOG_MAP_IO_SPACE 0x00000601L
302#define ERRLOG_QUERY_ADAPTER_RESOURCES 0x00000602L
303#define ERRLOG_NO_IO_RESOURCE 0x00000603L
304#define ERRLOG_NO_INTERRUPT_RESOURCE 0x00000604L
305#define ERRLOG_NO_MEMORY_RESOURCE 0x00000605L
306
307
308// WDS definition
309#define MAX_WDS_ENTRY 4
310#define WDS_PAIRWISE_KEY_OFFSET 60 // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
311
312#define WDS_DISABLE_MODE 0
313#define WDS_RESTRICT_MODE 1
314#define WDS_BRIDGE_MODE 2
315#define WDS_REPEATER_MODE 3
316#define WDS_LAZY_MODE 4
317
318
319#define MAX_MESH_NUM 0
320
321#define MAX_APCLI_NUM 0
322#ifdef APCLI_SUPPORT
323#undef MAX_APCLI_NUM
324#define MAX_APCLI_NUM 1
325#endif // APCLI_SUPPORT //
326
327#define MAX_MBSSID_NUM 1
328#ifdef MBSS_SUPPORT
329#undef MAX_MBSSID_NUM
330#define MAX_MBSSID_NUM (8 - MAX_MESH_NUM - MAX_APCLI_NUM)
331#endif // MBSS_SUPPORT //
332
333/* sanity check for apidx */
334#define MBSS_MR_APIDX_SANITY_CHECK(apidx) \
335 { if (apidx > MAX_MBSSID_NUM) { \
336 printk("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __FUNCTION__, apidx); \
337 apidx = MAIN_MBSSID; } }
338
339#define VALID_WCID(_wcid) ((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE )
340
341#define MAIN_MBSSID 0
342#define FIRST_MBSSID 1
343
344
345#define MAX_BEACON_SIZE 512
346// If the MAX_MBSSID_NUM is larger than 6,
347// it shall reserve some WCID space(wcid 222~253) for beacon frames.
348// - these wcid 238~253 are reserved for beacon#6(ra6).
349// - these wcid 222~237 are reserved for beacon#7(ra7).
350#if defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 8)
351#define HW_RESERVED_WCID 222
352#elif defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 7)
353#define HW_RESERVED_WCID 238
354#else
355#define HW_RESERVED_WCID 255
356#endif
357
358// Then dedicate wcid of DFS and Carrier-Sense.
359#define DFS_CTS_WCID (HW_RESERVED_WCID - 1)
360#define CS_CTS_WCID (HW_RESERVED_WCID - 2)
361#define LAST_SPECIFIC_WCID (HW_RESERVED_WCID - 2)
362
363// If MAX_MBSSID_NUM is 8, the maximum available wcid for the associated STA is 211.
364// If MAX_MBSSID_NUM is 7, the maximum available wcid for the associated STA is 228.
365#define MAX_AVAILABLE_CLIENT_WCID (LAST_SPECIFIC_WCID - MAX_MBSSID_NUM - 1)
366
367// TX need WCID to find Cipher Key
368// these wcid 212 ~ 219 are reserved for bc/mc packets if MAX_MBSSID_NUM is 8.
369#define GET_GroupKey_WCID(__wcid, __bssidx) \
370 { \
371 __wcid = LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM) + __bssidx; \
372 }
373
374#define IsGroupKeyWCID(__wcid) (((__wcid) < LAST_SPECIFIC_WCID) && ((__wcid) >= (LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM))))
375
376
377// definition to support multiple BSSID
378#define BSS0 0
379#define BSS1 1
380#define BSS2 2
381#define BSS3 3
382#define BSS4 4
383#define BSS5 5
384#define BSS6 6
385#define BSS7 7
386
387
388//============================================================
389// Length definitions
390#define PEER_KEY_NO 2
391#define MAC_ADDR_LEN 6
392#define TIMESTAMP_LEN 8
393#define MAX_LEN_OF_SUPPORTED_RATES MAX_LENGTH_OF_SUPPORT_RATES // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
394#define MAX_LEN_OF_KEY 32 // 32 octets == 256 bits, Redefine for WPA
395#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
396#define MAX_NUM_OF_11JCHANNELS 20 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
397#define MAX_LEN_OF_SSID 32
398#define CIPHER_TEXT_LEN 128
399#define HASH_TABLE_SIZE 256
400#define MAX_VIE_LEN 1024 // New for WPA cipher suite variable IE sizes.
401#define MAX_SUPPORT_MCS 32
402
403//============================================================
404// ASIC WCID Table definition.
405//============================================================
406#define BSSID_WCID 1 // in infra mode, always put bssid with this WCID
407#define MCAST_WCID 0x0
408#define BSS0Mcast_WCID 0x0
409#define BSS1Mcast_WCID 0xf8
410#define BSS2Mcast_WCID 0xf9
411#define BSS3Mcast_WCID 0xfa
412#define BSS4Mcast_WCID 0xfb
413#define BSS5Mcast_WCID 0xfc
414#define BSS6Mcast_WCID 0xfd
415#define BSS7Mcast_WCID 0xfe
416#define RESERVED_WCID 0xff
417
418#define MAX_NUM_OF_ACL_LIST MAX_NUMBER_OF_ACL
419
420#define MAX_LEN_OF_MAC_TABLE MAX_NUMBER_OF_MAC // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
421
422#if MAX_LEN_OF_MAC_TABLE>MAX_AVAILABLE_CLIENT_WCID
423#error MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID!!!!
424#endif
425
426#define MAX_NUM_OF_WDS_LINK_PERBSSID 3
427#define MAX_NUM_OF_WDS_LINK (MAX_NUM_OF_WDS_LINK_PERBSSID*MAX_MBSSID_NUM)
428#define MAX_NUM_OF_EVENT MAX_NUMBER_OF_EVENT
429#define WDS_LINK_START_WCID (MAX_LEN_OF_MAC_TABLE-1)
430
431#define NUM_OF_TID 8
432#define MAX_AID_BA 4
433#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
434#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
435#define MAX_LEN_OF_BSS_TABLE 64
436#define MAX_REORDERING_MPDU_NUM 512
437
438// key related definitions
439#define SHARE_KEY_NUM 4
440#define MAX_LEN_OF_SHARE_KEY 16 // byte count
441#define MAX_LEN_OF_PEER_KEY 16 // byte count
442#define PAIRWISE_KEY_NUM 64 // in MAC ASIC pairwise key table
443#define GROUP_KEY_NUM 4
444#define PMK_LEN 32
445#define WDS_PAIRWISE_KEY_OFFSET 60 // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
446#define PMKID_NO 4 // Number of PMKID saved supported
447#define MAX_LEN_OF_MLME_BUFFER 2048
448
449// power status related definitions
450#define PWR_ACTIVE 0
451#define PWR_SAVE 1
452#define PWR_MMPS 2 //MIMO power save
453
454// Auth and Assoc mode related definitions
455#define AUTH_MODE_OPEN 0x00
456#define AUTH_MODE_KEY 0x01
457
458// BSS Type definitions
459#define BSS_ADHOC 0 // = Ndis802_11IBSS
460#define BSS_INFRA 1 // = Ndis802_11Infrastructure
461#define BSS_ANY 2 // = Ndis802_11AutoUnknown
462#define BSS_MONITOR 3 // = Ndis802_11Monitor
463
464
465// Reason code definitions
466#define REASON_RESERVED 0
467#define REASON_UNSPECIFY 1
468#define REASON_NO_LONGER_VALID 2
469#define REASON_DEAUTH_STA_LEAVING 3
470#define REASON_DISASSOC_INACTIVE 4
471#define REASON_DISASSPC_AP_UNABLE 5
472#define REASON_CLS2ERR 6
473#define REASON_CLS3ERR 7
474#define REASON_DISASSOC_STA_LEAVING 8
475#define REASON_STA_REQ_ASSOC_NOT_AUTH 9
476#define REASON_INVALID_IE 13
477#define REASON_MIC_FAILURE 14
478#define REASON_4_WAY_TIMEOUT 15
479#define REASON_GROUP_KEY_HS_TIMEOUT 16
480#define REASON_IE_DIFFERENT 17
481#define REASON_MCIPHER_NOT_VALID 18
482#define REASON_UCIPHER_NOT_VALID 19
483#define REASON_AKMP_NOT_VALID 20
484#define REASON_UNSUPPORT_RSNE_VER 21
485#define REASON_INVALID_RSNE_CAP 22
486#define REASON_8021X_AUTH_FAIL 23
487#define REASON_CIPHER_SUITE_REJECTED 24
488#define REASON_DECLINED 37
489
490#define REASON_QOS_UNSPECIFY 32
491#define REASON_QOS_LACK_BANDWIDTH 33
492#define REASON_POOR_CHANNEL_CONDITION 34
493#define REASON_QOS_OUTSIDE_TXOP_LIMITION 35
494#define REASON_QOS_QSTA_LEAVING_QBSS 36
495#define REASON_QOS_UNWANTED_MECHANISM 37
496#define REASON_QOS_MECH_SETUP_REQUIRED 38
497#define REASON_QOS_REQUEST_TIMEOUT 39
498#define REASON_QOS_CIPHER_NOT_SUPPORT 45
499
500// Status code definitions
501#define MLME_SUCCESS 0
502#define MLME_UNSPECIFY_FAIL 1
503#define MLME_CANNOT_SUPPORT_CAP 10
504#define MLME_REASSOC_DENY_ASSOC_EXIST 11
505#define MLME_ASSOC_DENY_OUT_SCOPE 12
506#define MLME_ALG_NOT_SUPPORT 13
507#define MLME_SEQ_NR_OUT_OF_SEQUENCE 14
508#define MLME_REJ_CHALLENGE_FAILURE 15
509#define MLME_REJ_TIMEOUT 16
510#define MLME_ASSOC_REJ_UNABLE_HANDLE_STA 17
511#define MLME_ASSOC_REJ_DATA_RATE 18
512
513#define MLME_ASSOC_REJ_NO_EXT_RATE 22
514#define MLME_ASSOC_REJ_NO_EXT_RATE_PBCC 23
515#define MLME_ASSOC_REJ_NO_CCK_OFDM 24
516
517#define MLME_QOS_UNSPECIFY 32
518#define MLME_REQUEST_DECLINED 37
519#define MLME_REQUEST_WITH_INVALID_PARAM 38
520#define MLME_DLS_NOT_ALLOW_IN_QBSS 48
521#define MLME_DEST_STA_NOT_IN_QBSS 49
522#define MLME_DEST_STA_IS_NOT_A_QSTA 50
523
524#define MLME_INVALID_FORMAT 0x51
525#define MLME_FAIL_NO_RESOURCE 0x52
526#define MLME_STATE_MACHINE_REJECT 0x53
527#define MLME_MAC_TABLE_FAIL 0x54
528
529// IE code
530#define IE_SSID 0
531#define IE_SUPP_RATES 1
532#define IE_FH_PARM 2
533#define IE_DS_PARM 3
534#define IE_CF_PARM 4
535#define IE_TIM 5
536#define IE_IBSS_PARM 6
537#define IE_COUNTRY 7 // 802.11d
538#define IE_802_11D_REQUEST 10 // 802.11d
539#define IE_QBSS_LOAD 11 // 802.11e d9
540#define IE_EDCA_PARAMETER 12 // 802.11e d9
541#define IE_TSPEC 13 // 802.11e d9
542#define IE_TCLAS 14 // 802.11e d9
543#define IE_SCHEDULE 15 // 802.11e d9
544#define IE_CHALLENGE_TEXT 16
545#define IE_POWER_CONSTRAINT 32 // 802.11h d3.3
546#define IE_POWER_CAPABILITY 33 // 802.11h d3.3
547#define IE_TPC_REQUEST 34 // 802.11h d3.3
548#define IE_TPC_REPORT 35 // 802.11h d3.3
549#define IE_SUPP_CHANNELS 36 // 802.11h d3.3
550#define IE_CHANNEL_SWITCH_ANNOUNCEMENT 37 // 802.11h d3.3
551#define IE_MEASUREMENT_REQUEST 38 // 802.11h d3.3
552#define IE_MEASUREMENT_REPORT 39 // 802.11h d3.3
553#define IE_QUIET 40 // 802.11h d3.3
554#define IE_IBSS_DFS 41 // 802.11h d3.3
555#define IE_ERP 42 // 802.11g
556#define IE_TS_DELAY 43 // 802.11e d9
557#define IE_TCLAS_PROCESSING 44 // 802.11e d9
558#define IE_QOS_CAPABILITY 46 // 802.11e d6
559#define IE_HT_CAP 45 // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
560#define IE_AP_CHANNEL_REPORT 51 // 802.11k d6
561#define IE_HT_CAP2 52 // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
562#define IE_RSN 48 // 802.11i d3.0
563#define IE_WPA2 48 // WPA2
564#define IE_EXT_SUPP_RATES 50 // 802.11g
565#define IE_SUPP_REG_CLASS 59 // 802.11y. Supported regulatory classes.
566#define IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT 60 // 802.11n
567#define IE_ADD_HT 61 // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
568#define IE_ADD_HT2 53 // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
569
570
571// For 802.11n D3.03
572//#define IE_NEW_EXT_CHA_OFFSET 62 // 802.11n d1. New extension channel offset elemet
573#define IE_SECONDARY_CH_OFFSET 62 // 802.11n D3.03 Secondary Channel Offset element
574#define IE_2040_BSS_COEXIST 72 // 802.11n D3.0.3
575#define IE_2040_BSS_INTOLERANT_REPORT 73 // 802.11n D3.03
576#define IE_OVERLAPBSS_SCAN_PARM 74 // 802.11n D3.03
577#define IE_EXT_CAPABILITY 127 // 802.11n D3.03
578
579
580#define IE_WPA 221 // WPA
581#define IE_VENDOR_SPECIFIC 221 // Wifi WMM (WME)
582
583#define OUI_BROADCOM_HT 51 //
584#define OUI_BROADCOM_HTADD 52 //
585#define OUI_PREN_HT_CAP 51 //
586#define OUI_PREN_ADD_HT 52 //
587
588// CCX information
589#define IE_AIRONET_CKIP 133 // CCX1.0 ID 85H for CKIP
590#define IE_AP_TX_POWER 150 // CCX 2.0 for AP transmit power
591#define IE_MEASUREMENT_CAPABILITY 221 // CCX 2.0
592#define IE_CCX_V2 221
593#define IE_AIRONET_IPADDRESS 149 // CCX ID 95H for IP Address
594#define IE_AIRONET_CCKMREASSOC 156 // CCX ID 9CH for CCKM Reassociation Request element
595#define CKIP_NEGOTIATION_LENGTH 30
596#define AIRONET_IPADDRESS_LENGTH 10
597#define AIRONET_CCKMREASSOC_LENGTH 24
598
599// ========================================================
600// MLME state machine definition
601// ========================================================
602
603// STA MLME state mahcines
604#define ASSOC_STATE_MACHINE 1
605#define AUTH_STATE_MACHINE 2
606#define AUTH_RSP_STATE_MACHINE 3
607#define SYNC_STATE_MACHINE 4
608#define MLME_CNTL_STATE_MACHINE 5
609#define WPA_PSK_STATE_MACHINE 6
610#define LEAP_STATE_MACHINE 7
611#define AIRONET_STATE_MACHINE 8
612#define ACTION_STATE_MACHINE 9
613
614// AP MLME state machines
615#define AP_ASSOC_STATE_MACHINE 11
616#define AP_AUTH_STATE_MACHINE 12
617#define AP_AUTH_RSP_STATE_MACHINE 13
618#define AP_SYNC_STATE_MACHINE 14
619#define AP_CNTL_STATE_MACHINE 15
620#define AP_WPA_STATE_MACHINE 16
621
622#ifdef QOS_DLS_SUPPORT
623#define DLS_STATE_MACHINE 26
624#endif // QOS_DLS_SUPPORT //
625
626//
627// STA's CONTROL/CONNECT state machine: states, events, total function #
628//
629#define CNTL_IDLE 0
630#define CNTL_WAIT_DISASSOC 1
631#define CNTL_WAIT_JOIN 2
632#define CNTL_WAIT_REASSOC 3
633#define CNTL_WAIT_START 4
634#define CNTL_WAIT_AUTH 5
635#define CNTL_WAIT_ASSOC 6
636#define CNTL_WAIT_AUTH2 7
637#define CNTL_WAIT_OID_LIST_SCAN 8
638#define CNTL_WAIT_OID_DISASSOC 9
639
640#define MT2_ASSOC_CONF 34
641#define MT2_AUTH_CONF 35
642#define MT2_DEAUTH_CONF 36
643#define MT2_DISASSOC_CONF 37
644#define MT2_REASSOC_CONF 38
645#define MT2_PWR_MGMT_CONF 39
646#define MT2_JOIN_CONF 40
647#define MT2_SCAN_CONF 41
648#define MT2_START_CONF 42
649#define MT2_GET_CONF 43
650#define MT2_SET_CONF 44
651#define MT2_RESET_CONF 45
652#define MT2_MLME_ROAMING_REQ 52
653
654#define CNTL_FUNC_SIZE 1
655
656//
657// STA's ASSOC state machine: states, events, total function #
658//
659#define ASSOC_IDLE 0
660#define ASSOC_WAIT_RSP 1
661#define REASSOC_WAIT_RSP 2
662#define DISASSOC_WAIT_RSP 3
663#define MAX_ASSOC_STATE 4
664
665#define ASSOC_MACHINE_BASE 0
666#define MT2_MLME_ASSOC_REQ 0
667#define MT2_MLME_REASSOC_REQ 1
668#define MT2_MLME_DISASSOC_REQ 2
669#define MT2_PEER_DISASSOC_REQ 3
670#define MT2_PEER_ASSOC_REQ 4
671#define MT2_PEER_ASSOC_RSP 5
672#define MT2_PEER_REASSOC_REQ 6
673#define MT2_PEER_REASSOC_RSP 7
674#define MT2_DISASSOC_TIMEOUT 8
675#define MT2_ASSOC_TIMEOUT 9
676#define MT2_REASSOC_TIMEOUT 10
677#define MAX_ASSOC_MSG 11
678
679#define ASSOC_FUNC_SIZE (MAX_ASSOC_STATE * MAX_ASSOC_MSG)
680
681//
682// ACT state machine: states, events, total function #
683//
684#define ACT_IDLE 0
685#define MAX_ACT_STATE 1
686
687#define ACT_MACHINE_BASE 0
688
689//Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please don'es modify it by your self.
690//Category
691#define MT2_PEER_SPECTRUM_CATE 0
692#define MT2_PEER_QOS_CATE 1
693#define MT2_PEER_DLS_CATE 2
694#define MT2_PEER_BA_CATE 3
695#define MT2_PEER_PUBLIC_CATE 4
696#define MT2_PEER_RM_CATE 5
697#define MT2_PEER_HT_CATE 7 // 7.4.7
698#define MAX_PEER_CATE_MSG 7
699#define MT2_MLME_ADD_BA_CATE 8
700#define MT2_MLME_ORI_DELBA_CATE 9
701#define MT2_MLME_REC_DELBA_CATE 10
702#define MT2_MLME_QOS_CATE 11
703#define MT2_MLME_DLS_CATE 12
704#define MT2_ACT_INVALID 13
705#define MAX_ACT_MSG 14
706
707//Category field
708#define CATEGORY_SPECTRUM 0
709#define CATEGORY_QOS 1
710#define CATEGORY_DLS 2
711#define CATEGORY_BA 3
712#define CATEGORY_PUBLIC 4
713#define CATEGORY_RM 5
714#define CATEGORY_HT 7
715
716
717// DLS Action frame definition
718#define ACTION_DLS_REQUEST 0
719#define ACTION_DLS_RESPONSE 1
720#define ACTION_DLS_TEARDOWN 2
721
722//Spectrum Action field value 802.11h 7.4.1
723#define SPEC_MRQ 0 // Request
724#define SPEC_MRP 1 //Report
725#define SPEC_TPCRQ 2
726#define SPEC_TPCRP 3
727#define SPEC_CHANNEL_SWITCH 4
728
729
730//BA Action field value
731#define ADDBA_REQ 0
732#define ADDBA_RESP 1
733#define DELBA 2
734
735//Public's Action field value in Public Category. Some in 802.11y and some in 11n
736#define ACTION_BSS_2040_COEXIST 0 // 11n
737#define ACTION_DSE_ENABLEMENT 1 // 11y D9.0
738#define ACTION_DSE_DEENABLEMENT 2 // 11y D9.0
739#define ACTION_DSE_REG_LOCATION_ANNOUNCE 3 // 11y D9.0
740#define ACTION_EXT_CH_SWITCH_ANNOUNCE 4 // 11y D9.0
741#define ACTION_DSE_MEASUREMENT_REQ 5 // 11y D9.0
742#define ACTION_DSE_MEASUREMENT_REPORT 6 // 11y D9.0
743#define ACTION_MEASUREMENT_PILOT_ACTION 7 // 11y D9.0
744#define ACTION_DSE_POWER_CONSTRAINT 8 // 11y D9.0
745
746
747//HT Action field value
748#define NOTIFY_BW_ACTION 0
749#define SMPS_ACTION 1
750#define PSMP_ACTION 2
751#define SETPCO_ACTION 3
752#define MIMO_CHA_MEASURE_ACTION 4
753#define MIMO_N_BEACONFORM 5
754#define MIMO_BEACONFORM 6
755#define ANTENNA_SELECT 7
756#define HT_INFO_EXCHANGE 8
757
758#define ACT_FUNC_SIZE (MAX_ACT_STATE * MAX_ACT_MSG)
759//
760// STA's AUTHENTICATION state machine: states, evvents, total function #
761//
762#define AUTH_REQ_IDLE 0
763#define AUTH_WAIT_SEQ2 1
764#define AUTH_WAIT_SEQ4 2
765#define MAX_AUTH_STATE 3
766
767#define AUTH_MACHINE_BASE 0
768#define MT2_MLME_AUTH_REQ 0
769#define MT2_PEER_AUTH_EVEN 1
770#define MT2_AUTH_TIMEOUT 2
771#define MAX_AUTH_MSG 3
772
773#define AUTH_FUNC_SIZE (MAX_AUTH_STATE * MAX_AUTH_MSG)
774
775//
776// STA's AUTH_RSP state machine: states, events, total function #
777//
778#define AUTH_RSP_IDLE 0
779#define AUTH_RSP_WAIT_CHAL 1
780#define MAX_AUTH_RSP_STATE 2
781
782#define AUTH_RSP_MACHINE_BASE 0
783#define MT2_AUTH_CHALLENGE_TIMEOUT 0
784#define MT2_PEER_AUTH_ODD 1
785#define MT2_PEER_DEAUTH 2
786#define MAX_AUTH_RSP_MSG 3
787
788#define AUTH_RSP_FUNC_SIZE (MAX_AUTH_RSP_STATE * MAX_AUTH_RSP_MSG)
789
790//
791// STA's SYNC state machine: states, events, total function #
792//
793#define SYNC_IDLE 0 // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
794#define JOIN_WAIT_BEACON 1
795#define SCAN_LISTEN 2
796#define MAX_SYNC_STATE 3
797
798#define SYNC_MACHINE_BASE 0
799#define MT2_MLME_SCAN_REQ 0
800#define MT2_MLME_JOIN_REQ 1
801#define MT2_MLME_START_REQ 2
802#define MT2_PEER_BEACON 3
803#define MT2_PEER_PROBE_RSP 4
804#define MT2_PEER_ATIM 5
805#define MT2_SCAN_TIMEOUT 6
806#define MT2_BEACON_TIMEOUT 7
807#define MT2_ATIM_TIMEOUT 8
808#define MT2_PEER_PROBE_REQ 9
809#define MAX_SYNC_MSG 10
810
811#define SYNC_FUNC_SIZE (MAX_SYNC_STATE * MAX_SYNC_MSG)
812
813//Messages for the DLS state machine
814#define DLS_IDLE 0
815#define MAX_DLS_STATE 1
816
817#define DLS_MACHINE_BASE 0
818#define MT2_MLME_DLS_REQ 0
819#define MT2_PEER_DLS_REQ 1
820#define MT2_PEER_DLS_RSP 2
821#define MT2_MLME_DLS_TEAR_DOWN 3
822#define MT2_PEER_DLS_TEAR_DOWN 4
823#define MAX_DLS_MSG 5
824
825#define DLS_FUNC_SIZE (MAX_DLS_STATE * MAX_DLS_MSG)
826
827//
828// STA's WPA-PSK State machine: states, events, total function #
829//
830#define WPA_PSK_IDLE 0
831#define MAX_WPA_PSK_STATE 1
832
833#define WPA_MACHINE_BASE 0
834#define MT2_EAPPacket 0
835#define MT2_EAPOLStart 1
836#define MT2_EAPOLLogoff 2
837#define MT2_EAPOLKey 3
838#define MT2_EAPOLASFAlert 4
839#define MAX_WPA_PSK_MSG 5
840
841#define WPA_PSK_FUNC_SIZE (MAX_WPA_PSK_STATE * MAX_WPA_PSK_MSG)
842
843//
844// STA's CISCO-AIRONET State machine: states, events, total function #
845//
846#define AIRONET_IDLE 0
847#define AIRONET_SCANNING 1
848#define MAX_AIRONET_STATE 2
849
850#define AIRONET_MACHINE_BASE 0
851#define MT2_AIRONET_MSG 0
852#define MT2_AIRONET_SCAN_REQ 1
853#define MT2_AIRONET_SCAN_DONE 2
854#define MAX_AIRONET_MSG 3
855
856#define AIRONET_FUNC_SIZE (MAX_AIRONET_STATE * MAX_AIRONET_MSG)
857
858//
859// AP's CONTROL/CONNECT state machine: states, events, total function #
860//
861#define AP_CNTL_FUNC_SIZE 1
862
863//
864// AP's ASSOC state machine: states, events, total function #
865//
866#define AP_ASSOC_IDLE 0
867#define AP_MAX_ASSOC_STATE 1
868
869#define AP_ASSOC_MACHINE_BASE 0
870#define APMT2_MLME_DISASSOC_REQ 0
871#define APMT2_PEER_DISASSOC_REQ 1
872#define APMT2_PEER_ASSOC_REQ 2
873#define APMT2_PEER_REASSOC_REQ 3
874#define APMT2_CLS3ERR 4
875#define AP_MAX_ASSOC_MSG 5
876
877#define AP_ASSOC_FUNC_SIZE (AP_MAX_ASSOC_STATE * AP_MAX_ASSOC_MSG)
878
879//
880// AP's AUTHENTICATION state machine: states, events, total function #
881//
882#define AP_AUTH_REQ_IDLE 0
883#define AP_MAX_AUTH_STATE 1
884
885#define AP_AUTH_MACHINE_BASE 0
886#define APMT2_MLME_DEAUTH_REQ 0
887#define APMT2_CLS2ERR 1
888#define AP_MAX_AUTH_MSG 2
889
890#define AP_AUTH_FUNC_SIZE (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG)
891
892//
893// AP's AUTH-RSP state machine: states, events, total function #
894//
895#define AP_AUTH_RSP_IDLE 0
896#define AP_MAX_AUTH_RSP_STATE 1
897
898#define AP_AUTH_RSP_MACHINE_BASE 0
899#define APMT2_AUTH_CHALLENGE_TIMEOUT 0
900#define APMT2_PEER_AUTH_ODD 1
901#define APMT2_PEER_DEAUTH 2
902#define AP_MAX_AUTH_RSP_MSG 3
903
904#define AP_AUTH_RSP_FUNC_SIZE (AP_MAX_AUTH_RSP_STATE * AP_MAX_AUTH_RSP_MSG)
905
906//
907// AP's SYNC state machine: states, events, total function #
908//
909#define AP_SYNC_IDLE 0
910#define AP_SCAN_LISTEN 1
911#define AP_MAX_SYNC_STATE 2
912
913#define AP_SYNC_MACHINE_BASE 0
914#define APMT2_PEER_PROBE_REQ 0
915#define APMT2_PEER_BEACON 1
916#define APMT2_MLME_SCAN_REQ 2
917#define APMT2_PEER_PROBE_RSP 3
918#define APMT2_SCAN_TIMEOUT 4
919#define APMT2_MLME_SCAN_CNCL 5
920#define AP_MAX_SYNC_MSG 6
921
922#define AP_SYNC_FUNC_SIZE (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG)
923
924//
925// AP's WPA state machine: states, events, total function #
926//
927#define AP_WPA_PTK 0
928#define AP_MAX_WPA_PTK_STATE 1
929
930#define AP_WPA_MACHINE_BASE 0
931#define APMT2_EAPPacket 0
932#define APMT2_EAPOLStart 1
933#define APMT2_EAPOLLogoff 2
934#define APMT2_EAPOLKey 3
935#define APMT2_EAPOLASFAlert 4
936#define AP_MAX_WPA_MSG 5
937
938#define AP_WPA_FUNC_SIZE (AP_MAX_WPA_PTK_STATE * AP_MAX_WPA_MSG)
939
940#ifdef APCLI_SUPPORT
941//ApCli authentication state machine
942#define APCLI_AUTH_REQ_IDLE 0
943#define APCLI_AUTH_WAIT_SEQ2 1
944#define APCLI_AUTH_WAIT_SEQ4 2
945#define APCLI_MAX_AUTH_STATE 3
946
947#define APCLI_AUTH_MACHINE_BASE 0
948#define APCLI_MT2_MLME_AUTH_REQ 0
949#define APCLI_MT2_MLME_DEAUTH_REQ 1
950#define APCLI_MT2_PEER_AUTH_EVEN 2
951#define APCLI_MT2_PEER_DEAUTH 3
952#define APCLI_MT2_AUTH_TIMEOUT 4
953#define APCLI_MAX_AUTH_MSG 5
954
955#define APCLI_AUTH_FUNC_SIZE (APCLI_MAX_AUTH_STATE * APCLI_MAX_AUTH_MSG)
956
957//ApCli association state machine
958#define APCLI_ASSOC_IDLE 0
959#define APCLI_ASSOC_WAIT_RSP 1
960#define APCLI_MAX_ASSOC_STATE 2
961
962#define APCLI_ASSOC_MACHINE_BASE 0
963#define APCLI_MT2_MLME_ASSOC_REQ 0
964#define APCLI_MT2_MLME_DISASSOC_REQ 1
965#define APCLI_MT2_PEER_DISASSOC_REQ 2
966#define APCLI_MT2_PEER_ASSOC_RSP 3
967#define APCLI_MT2_ASSOC_TIMEOUT 4
968#define APCLI_MAX_ASSOC_MSG 5
969
970#define APCLI_ASSOC_FUNC_SIZE (APCLI_MAX_ASSOC_STATE * APCLI_MAX_ASSOC_MSG)
971
972//ApCli sync state machine
973#define APCLI_SYNC_IDLE 0 // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
974#define APCLI_JOIN_WAIT_PROBE_RSP 1
975#define APCLI_MAX_SYNC_STATE 2
976
977#define APCLI_SYNC_MACHINE_BASE 0
978#define APCLI_MT2_MLME_PROBE_REQ 0
979#define APCLI_MT2_PEER_PROBE_RSP 1
980#define APCLI_MT2_PROBE_TIMEOUT 2
981#define APCLI_MAX_SYNC_MSG 3
982
983#define APCLI_SYNC_FUNC_SIZE (APCLI_MAX_SYNC_STATE * APCLI_MAX_SYNC_MSG)
984
985//ApCli ctrl state machine
986#define APCLI_CTRL_DISCONNECTED 0 // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
987#define APCLI_CTRL_PROBE 1
988#define APCLI_CTRL_AUTH 2
989#define APCLI_CTRL_AUTH_2 3
990#define APCLI_CTRL_ASSOC 4
991#define APCLI_CTRL_DEASSOC 5
992#define APCLI_CTRL_CONNECTED 6
993#define APCLI_MAX_CTRL_STATE 7
994
995#define APCLI_CTRL_MACHINE_BASE 0
996#define APCLI_CTRL_JOIN_REQ 0
997#define APCLI_CTRL_PROBE_RSP 1
998#define APCLI_CTRL_AUTH_RSP 2
999#define APCLI_CTRL_DISCONNECT_REQ 3
1000#define APCLI_CTRL_PEER_DISCONNECT_REQ 4
1001#define APCLI_CTRL_ASSOC_RSP 5
1002#define APCLI_CTRL_DEASSOC_RSP 6
1003#define APCLI_CTRL_JOIN_REQ_TIMEOUT 7
1004#define APCLI_CTRL_AUTH_REQ_TIMEOUT 8
1005#define APCLI_CTRL_ASSOC_REQ_TIMEOUT 9
1006#define APCLI_MAX_CTRL_MSG 10
1007
1008#define APCLI_CTRL_FUNC_SIZE (APCLI_MAX_CTRL_STATE * APCLI_MAX_CTRL_MSG)
1009
1010#endif // APCLI_SUPPORT //
1011
1012
1013// =============================================================================
1014
1015// value domain of 802.11 header FC.Tyte, which is b3..b2 of the 1st-byte of MAC header
1016#define BTYPE_MGMT 0
1017#define BTYPE_CNTL 1
1018#define BTYPE_DATA 2
1019
1020// value domain of 802.11 MGMT frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
1021#define SUBTYPE_ASSOC_REQ 0
1022#define SUBTYPE_ASSOC_RSP 1
1023#define SUBTYPE_REASSOC_REQ 2
1024#define SUBTYPE_REASSOC_RSP 3
1025#define SUBTYPE_PROBE_REQ 4
1026#define SUBTYPE_PROBE_RSP 5
1027#define SUBTYPE_BEACON 8
1028#define SUBTYPE_ATIM 9
1029#define SUBTYPE_DISASSOC 10
1030#define SUBTYPE_AUTH 11
1031#define SUBTYPE_DEAUTH 12
1032#define SUBTYPE_ACTION 13
1033#define SUBTYPE_ACTION_NO_ACK 14
1034
1035// value domain of 802.11 CNTL frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
1036#define SUBTYPE_WRAPPER 7
1037#define SUBTYPE_BLOCK_ACK_REQ 8
1038#define SUBTYPE_BLOCK_ACK 9
1039#define SUBTYPE_PS_POLL 10
1040#define SUBTYPE_RTS 11
1041#define SUBTYPE_CTS 12
1042#define SUBTYPE_ACK 13
1043#define SUBTYPE_CFEND 14
1044#define SUBTYPE_CFEND_CFACK 15
1045
1046// value domain of 802.11 DATA frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
1047#define SUBTYPE_DATA 0
1048#define SUBTYPE_DATA_CFACK 1
1049#define SUBTYPE_DATA_CFPOLL 2
1050#define SUBTYPE_DATA_CFACK_CFPOLL 3
1051#define SUBTYPE_NULL_FUNC 4
1052#define SUBTYPE_CFACK 5
1053#define SUBTYPE_CFPOLL 6
1054#define SUBTYPE_CFACK_CFPOLL 7
1055#define SUBTYPE_QDATA 8
1056#define SUBTYPE_QDATA_CFACK 9
1057#define SUBTYPE_QDATA_CFPOLL 10
1058#define SUBTYPE_QDATA_CFACK_CFPOLL 11
1059#define SUBTYPE_QOS_NULL 12
1060#define SUBTYPE_QOS_CFACK 13
1061#define SUBTYPE_QOS_CFPOLL 14
1062#define SUBTYPE_QOS_CFACK_CFPOLL 15
1063
1064// ACK policy of QOS Control field bit 6:5
1065#define NORMAL_ACK 0x00 // b6:5 = 00
1066#define NO_ACK 0x20 // b6:5 = 01
1067#define NO_EXPLICIT_ACK 0x40 // b6:5 = 10
1068#define BLOCK_ACK 0x60 // b6:5 = 11
1069
1070//
1071// rtmp_data.c use these definition
1072//
1073#define LENGTH_802_11 24
1074#define LENGTH_802_11_AND_H 30
1075#define LENGTH_802_11_CRC_H 34
1076#define LENGTH_802_11_CRC 28
1077#define LENGTH_802_11_WITH_ADDR4 30
1078#define LENGTH_802_3 14
1079#define LENGTH_802_3_TYPE 2
1080#define LENGTH_802_1_H 8
1081#define LENGTH_EAPOL_H 4
1082#define LENGTH_WMMQOS_H 2
1083#define LENGTH_CRC 4
1084#define MAX_SEQ_NUMBER 0x0fff
1085#define LENGTH_802_3_NO_TYPE 12
1086#define LENGTH_802_1Q 4 /* VLAN related */
1087
1088// STA_CSR4.field.TxResult
1089#define TX_RESULT_SUCCESS 0
1090#define TX_RESULT_ZERO_LENGTH 1
1091#define TX_RESULT_UNDER_RUN 2
1092#define TX_RESULT_OHY_ERROR 4
1093#define TX_RESULT_RETRY_FAIL 6
1094
1095// All PHY rate summary in TXD
1096// Preamble MODE in TxD
1097#define MODE_CCK 0
1098#define MODE_OFDM 1
1099#ifdef DOT11_N_SUPPORT
1100#define MODE_HTMIX 2
1101#define MODE_HTGREENFIELD 3
1102#endif // DOT11_N_SUPPORT //
1103// MCS for CCK. BW.SGI.STBC are reserved
1104#define MCS_LONGP_RATE_1 0 // long preamble CCK 1Mbps
1105#define MCS_LONGP_RATE_2 1 // long preamble CCK 1Mbps
1106#define MCS_LONGP_RATE_5_5 2
1107#define MCS_LONGP_RATE_11 3
1108#define MCS_SHORTP_RATE_1 4 // long preamble CCK 1Mbps. short is forbidden in 1Mbps
1109#define MCS_SHORTP_RATE_2 5 // short preamble CCK 2Mbps
1110#define MCS_SHORTP_RATE_5_5 6
1111#define MCS_SHORTP_RATE_11 7
1112// To send duplicate legacy OFDM. set BW=BW_40. SGI.STBC are reserved
1113#define MCS_RATE_6 0 // legacy OFDM
1114#define MCS_RATE_9 1 // OFDM
1115#define MCS_RATE_12 2 // OFDM
1116#define MCS_RATE_18 3 // OFDM
1117#define MCS_RATE_24 4 // OFDM
1118#define MCS_RATE_36 5 // OFDM
1119#define MCS_RATE_48 6 // OFDM
1120#define MCS_RATE_54 7 // OFDM
1121// HT
1122#define MCS_0 0 // 1S
1123#define MCS_1 1
1124#define MCS_2 2
1125#define MCS_3 3
1126#define MCS_4 4
1127#define MCS_5 5
1128#define MCS_6 6
1129#define MCS_7 7
1130#define MCS_8 8 // 2S
1131#define MCS_9 9
1132#define MCS_10 10
1133#define MCS_11 11
1134#define MCS_12 12
1135#define MCS_13 13
1136#define MCS_14 14
1137#define MCS_15 15
1138#define MCS_16 16 // 3*3
1139#define MCS_17 17
1140#define MCS_18 18
1141#define MCS_19 19
1142#define MCS_20 20
1143#define MCS_21 21
1144#define MCS_22 22
1145#define MCS_23 23
1146#define MCS_32 32
1147#define MCS_AUTO 33
1148
1149#ifdef DOT11_N_SUPPORT
1150// OID_HTPHYMODE
1151// MODE
1152#define HTMODE_MM 0
1153#define HTMODE_GF 1
1154#endif // DOT11_N_SUPPORT //
1155
1156// Fixed Tx MODE - HT, CCK or OFDM
1157#define FIXED_TXMODE_HT 0
1158#define FIXED_TXMODE_CCK 1
1159#define FIXED_TXMODE_OFDM 2
1160// BW
1161#define BW_20 BAND_WIDTH_20
1162#define BW_40 BAND_WIDTH_40
1163#define BW_BOTH BAND_WIDTH_BOTH
1164#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.
1165
1166#ifdef DOT11_N_SUPPORT
1167// SHORTGI
1168#define GI_400 GAP_INTERVAL_400 // only support in HT mode
1169#define GI_BOTH GAP_INTERVAL_BOTH
1170#endif // DOT11_N_SUPPORT //
1171#define GI_800 GAP_INTERVAL_800
1172// STBC
1173#define STBC_NONE 0
1174#ifdef DOT11_N_SUPPORT
1175#define STBC_USE 1 // limited use in rt2860b phy
1176#define RXSTBC_ONE 1 // rx support of one spatial stream
1177#define RXSTBC_TWO 2 // rx support of 1 and 2 spatial stream
1178#define RXSTBC_THR 3 // rx support of 1~3 spatial stream
1179// MCS FEEDBACK
1180#define MCSFBK_NONE 0 // not support mcs feedback /
1181#define MCSFBK_RSV 1 // reserved
1182#define MCSFBK_UNSOLICIT 2 // only support unsolict mcs feedback
1183#define MCSFBK_MRQ 3 // response to both MRQ and unsolict mcs feedback
1184
1185// MIMO power safe
1186#define MMPS_STATIC 0
1187#define MMPS_DYNAMIC 1
1188#define MMPS_RSV 2
1189#define MMPS_ENABLE 3
1190
1191
1192// A-MSDU size
1193#define AMSDU_0 0
1194#define AMSDU_1 1
1195
1196#endif // DOT11_N_SUPPORT //
1197
1198// MCS use 7 bits
1199#define TXRATEMIMO 0x80
1200#define TXRATEMCS 0x7F
1201#define TXRATEOFDM 0x7F
1202#define RATE_1 0
1203#define RATE_2 1
1204#define RATE_5_5 2
1205#define RATE_11 3
1206#define RATE_6 4 // OFDM
1207#define RATE_9 5 // OFDM
1208#define RATE_12 6 // OFDM
1209#define RATE_18 7 // OFDM
1210#define RATE_24 8 // OFDM
1211#define RATE_36 9 // OFDM
1212#define RATE_48 10 // OFDM
1213#define RATE_54 11 // OFDM
1214#define RATE_FIRST_OFDM_RATE RATE_6
1215#define RATE_LAST_OFDM_RATE RATE_54
1216#define RATE_6_5 12 // HT mix
1217#define RATE_13 13 // HT mix
1218#define RATE_19_5 14 // HT mix
1219#define RATE_26 15 // HT mix
1220#define RATE_39 16 // HT mix
1221#define RATE_52 17 // HT mix
1222#define RATE_58_5 18 // HT mix
1223#define RATE_65 19 // HT mix
1224#define RATE_78 20 // HT mix
1225#define RATE_104 21 // HT mix
1226#define RATE_117 22 // HT mix
1227#define RATE_130 23 // HT mix
1228//#define RATE_AUTO_SWITCH 255 // for StaCfg.FixedTxRate only
1229#define HTRATE_0 12
1230#define RATE_FIRST_MM_RATE HTRATE_0
1231#define RATE_FIRST_HT_RATE HTRATE_0
1232#define RATE_LAST_HT_RATE HTRATE_0
1233
1234// pTxWI->txop
1235#define IFS_HTTXOP 0 // The txop will be handles by ASIC.
1236#define IFS_PIFS 1
1237#define IFS_SIFS 2
1238#define IFS_BACKOFF 3
1239
1240// pTxD->RetryMode
1241#define LONG_RETRY 1
1242#define SHORT_RETRY 0
1243
1244// Country Region definition
1245#define REGION_MINIMUM_BG_BAND 0
1246#define REGION_0_BG_BAND 0 // 1-11
1247#define REGION_1_BG_BAND 1 // 1-13
1248#define REGION_2_BG_BAND 2 // 10-11
1249#define REGION_3_BG_BAND 3 // 10-13
1250#define REGION_4_BG_BAND 4 // 14
1251#define REGION_5_BG_BAND 5 // 1-14
1252#define REGION_6_BG_BAND 6 // 3-9
1253#define REGION_7_BG_BAND 7 // 5-13
1254#define REGION_31_BG_BAND 31 // 5-13
1255#define REGION_MAXIMUM_BG_BAND 7
1256
1257#define REGION_MINIMUM_A_BAND 0
1258#define REGION_0_A_BAND 0 // 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165
1259#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
1260#define REGION_2_A_BAND 2 // 36, 40, 44, 48, 52, 56, 60, 64
1261#define REGION_3_A_BAND 3 // 52, 56, 60, 64, 149, 153, 157, 161
1262#define REGION_4_A_BAND 4 // 149, 153, 157, 161, 165
1263#define REGION_5_A_BAND 5 // 149, 153, 157, 161
1264#define REGION_6_A_BAND 6 // 36, 40, 44, 48
1265#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
1266#define REGION_8_A_BAND 8 // 52, 56, 60, 64
1267#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
1268#define REGION_10_A_BAND 10 // 36, 40, 44, 48, 149, 153, 157, 161, 165
1269#define REGION_11_A_BAND 11 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161
1270#define REGION_MAXIMUM_A_BAND 11
1271
1272// pTxD->CipherAlg
1273#define CIPHER_NONE 0
1274#define CIPHER_WEP64 1
1275#define CIPHER_WEP128 2
1276#define CIPHER_TKIP 3
1277#define CIPHER_AES 4
1278#define CIPHER_CKIP64 5
1279#define CIPHER_CKIP128 6
1280#define CIPHER_TKIP_NO_MIC 7 // MIC appended by driver: not a valid value in hardware key table
1281#define CIPHER_SMS4 8
1282
1283// value domain of pAd->RfIcType
1284#define RFIC_2820 1 // 2.4G 2T3R
1285#define RFIC_2850 2 // 2.4G/5G 2T3R
1286#define RFIC_2720 3 // 2.4G 1T2R
1287#define RFIC_2750 4 // 2.4G/5G 1T2R
1288#define RFIC_3020 5 // 2.4G 1T1R
1289#define RFIC_2020 6 // 2.4G B/G
1290
1291// LED Status.
1292#define LED_LINK_DOWN 0
1293#define LED_LINK_UP 1
1294#define LED_RADIO_OFF 2
1295#define LED_RADIO_ON 3
1296#define LED_HALT 4
1297#define LED_WPS 5
1298#define LED_ON_SITE_SURVEY 6
1299#define LED_POWER_UP 7
1300
1301// value domain of pAd->LedCntl.LedMode and E2PROM
1302#define LED_MODE_DEFAULT 0
1303#define LED_MODE_TWO_LED 1
1304#define LED_MODE_SIGNAL_STREGTH 8 // EEPROM define =8
1305
1306// RC4 init value, used fro WEP & TKIP
1307#define PPPINITFCS32 0xffffffff /* Initial FCS value */
1308
1309// value domain of pAd->StaCfg.PortSecured. 802.1X controlled port definition
1310#define WPA_802_1X_PORT_SECURED 1
1311#define WPA_802_1X_PORT_NOT_SECURED 2
1312
1313#define PAIRWISE_KEY 1
1314#define GROUP_KEY 2
1315
1316//definition of DRS
1317#define MAX_STEP_OF_TX_RATE_SWITCH 32
1318
1319
1320// pre-allocated free NDIS PACKET/BUFFER poll for internal usage
1321#define MAX_NUM_OF_FREE_NDIS_PACKET 128
1322
1323//Block ACK
1324#define MAX_TX_REORDERBUF 64
1325#define MAX_RX_REORDERBUF 64
1326#define DEFAULT_TX_TIMEOUT 30
1327#define DEFAULT_RX_TIMEOUT 30
1328
1329// definition of Recipient or Originator
1330#define I_RECIPIENT TRUE
1331#define I_ORIGINATOR FALSE
1332
1333#define DEFAULT_BBP_TX_POWER 0
1334#define DEFAULT_RF_TX_POWER 5
1335
1336#define MAX_INI_BUFFER_SIZE 4096
1337#define MAX_PARAM_BUFFER_SIZE (2048) // enough for ACL (18*64)
1338 //18 : the length of Mac address acceptable format "01:02:03:04:05:06;")
1339 //64 : MAX_NUM_OF_ACL_LIST
1340// definition of pAd->OpMode
1341#define OPMODE_STA 0
1342#define OPMODE_AP 1
1343//#define OPMODE_L3_BRG 2 // as AP and STA at the same time
1344
1345#ifdef RT_BIG_ENDIAN
1346#define DIR_READ 0
1347#define DIR_WRITE 1
1348#define TYPE_TXD 0
1349#define TYPE_RXD 1
1350#define TYPE_TXINFO 0
1351#define TYPE_RXINFO 1
1352#define TYPE_TXWI 0
1353#define TYPE_RXWI 1
1354#endif
1355
1356// ========================= AP rtmp_def.h ===========================
1357// value domain for pAd->EventTab.Log[].Event
1358#define EVENT_RESET_ACCESS_POINT 0 // Log = "hh:mm:ss Restart Access Point"
1359#define EVENT_ASSOCIATED 1 // Log = "hh:mm:ss STA 00:01:02:03:04:05 associated"
1360#define EVENT_DISASSOCIATED 2 // Log = "hh:mm:ss STA 00:01:02:03:04:05 left this BSS"
1361#define EVENT_AGED_OUT 3 // Log = "hh:mm:ss STA 00:01:02:03:04:05 was aged-out and removed from this BSS"
1362#define EVENT_COUNTER_M 4
1363#define EVENT_INVALID_PSK 5
1364#define EVENT_MAX_EVENT_TYPE 6
1365// ==== end of AP rtmp_def.h ============
1366
1367// definition RSSI Number
1368#define RSSI_0 0
1369#define RSSI_1 1
1370#define RSSI_2 2
1371
1372// definition of radar detection
1373#define RD_NORMAL_MODE 0 // Not found radar signal
1374#define RD_SWITCHING_MODE 1 // Found radar signal, and doing channel switch
1375#define RD_SILENCE_MODE 2 // After channel switch, need to be silence a while to ensure radar not found
1376
1377//Driver defined cid for mapping status and command.
1378#define SLEEPCID 0x11
1379#define WAKECID 0x22
1380#define QUERYPOWERCID 0x33
1381#define OWNERMCU 0x1
1382#define OWNERCPU 0x0
1383
1384// MBSSID definition
1385#define ENTRY_NOT_FOUND 0xFF
1386
1387
1388/* After Linux 2.6.9,
1389 * VLAN module use Private (from user) interface flags (netdevice->priv_flags).
1390 * #define IFF_802_1Q_VLAN 0x1 -- 802.1Q VLAN device. in if.h
1391 * ref to ip_sabotage_out() [ out->priv_flags & IFF_802_1Q_VLAN ] in br_netfilter.c
1392 *
1393 * For this reason, we MUST use EVEN value in priv_flags
1394 */
1395#define INT_MAIN 0x0100
1396#define INT_MBSSID 0x0200
1397#define INT_WDS 0x0300
1398#define INT_APCLI 0x0400
1399#define INT_MESH 0x0500
1400
1401// Use bitmap to allow coexist of ATE_TXFRAME and ATE_RXFRAME(i.e.,to support LoopBack mode)
1402#ifdef RALINK_ATE
1403#define ATE_START 0x00 // Start ATE
1404#define ATE_STOP 0x80 // Stop ATE
1405#define ATE_TXCONT 0x05 // Continuous Transmit
1406#define ATE_TXCARR 0x09 // Transmit Carrier
1407#define ATE_TXCARRSUPP 0x11 // Transmit Carrier Suppression
1408#define ATE_TXFRAME 0x01 // Transmit Frames
1409#define ATE_RXFRAME 0x02 // Receive Frames
1410#ifdef RALINK_28xx_QA
1411#define ATE_TXSTOP 0xe2 // Stop Transmition(i.e., TXCONT, TXCARR, TXCARRSUPP, and TXFRAME)
1412#define ATE_RXSTOP 0xfd // Stop receiving Frames
1413#define BBP22_TXFRAME 0x00 // Transmit Frames
1414#define BBP22_TXCONT_OR_CARRSUPP 0x80 // Continuous Transmit or Carrier Suppression
1415#define BBP22_TXCARR 0xc1 // Transmit Carrier
1416#define BBP24_TXCONT 0x00 // Continuous Transmit
1417#define BBP24_CARRSUPP 0x01 // Carrier Suppression
1418#endif // RALINK_28xx_QA //
1419#endif // RALINK_ATE //
1420
1421// WEP Key TYPE
1422#define WEP_HEXADECIMAL_TYPE 0
1423#define WEP_ASCII_TYPE 1
1424
1425
1426
1427// WIRELESS EVENTS definition
1428/* Max number of char in custom event, refer to wireless_tools.28/wireless.20.h */
1429#define IW_CUSTOM_MAX_LEN 255 /* In bytes */
1430
1431// For system event - start
1432#define IW_SYS_EVENT_FLAG_START 0x0200
1433#define IW_ASSOC_EVENT_FLAG 0x0200
1434#define IW_DISASSOC_EVENT_FLAG 0x0201
1435#define IW_DEAUTH_EVENT_FLAG 0x0202
1436#define IW_AGEOUT_EVENT_FLAG 0x0203
1437#define IW_COUNTER_MEASURES_EVENT_FLAG 0x0204
1438#define IW_REPLAY_COUNTER_DIFF_EVENT_FLAG 0x0205
1439#define IW_RSNIE_DIFF_EVENT_FLAG 0x0206
1440#define IW_MIC_DIFF_EVENT_FLAG 0x0207
1441#define IW_ICV_ERROR_EVENT_FLAG 0x0208
1442#define IW_MIC_ERROR_EVENT_FLAG 0x0209
1443#define IW_GROUP_HS_TIMEOUT_EVENT_FLAG 0x020A
1444#define IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG 0x020B
1445#define IW_RSNIE_SANITY_FAIL_EVENT_FLAG 0x020C
1446#define IW_SET_KEY_DONE_WPA1_EVENT_FLAG 0x020D
1447#define IW_SET_KEY_DONE_WPA2_EVENT_FLAG 0x020E
1448#define IW_STA_LINKUP_EVENT_FLAG 0x020F
1449#define IW_STA_LINKDOWN_EVENT_FLAG 0x0210
1450#define IW_SCAN_COMPLETED_EVENT_FLAG 0x0211
1451#define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG 0x0212
1452// if add new system event flag, please upadte the IW_SYS_EVENT_FLAG_END
1453#define IW_SYS_EVENT_FLAG_END 0x0212
1454#define IW_SYS_EVENT_TYPE_NUM (IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1)
1455// For system event - end
1456
1457// For spoof attack event - start
1458#define IW_SPOOF_EVENT_FLAG_START 0x0300
1459#define IW_CONFLICT_SSID_EVENT_FLAG 0x0300
1460#define IW_SPOOF_ASSOC_RESP_EVENT_FLAG 0x0301
1461#define IW_SPOOF_REASSOC_RESP_EVENT_FLAG 0x0302
1462#define IW_SPOOF_PROBE_RESP_EVENT_FLAG 0x0303
1463#define IW_SPOOF_BEACON_EVENT_FLAG 0x0304
1464#define IW_SPOOF_DISASSOC_EVENT_FLAG 0x0305
1465#define IW_SPOOF_AUTH_EVENT_FLAG 0x0306
1466#define IW_SPOOF_DEAUTH_EVENT_FLAG 0x0307
1467#define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG 0x0308
1468#define IW_REPLAY_ATTACK_EVENT_FLAG 0x0309
1469// if add new spoof attack event flag, please upadte the IW_SPOOF_EVENT_FLAG_END
1470#define IW_SPOOF_EVENT_FLAG_END 0x0309
1471#define IW_SPOOF_EVENT_TYPE_NUM (IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1)
1472// For spoof attack event - end
1473
1474// For flooding attack event - start
1475#define IW_FLOOD_EVENT_FLAG_START 0x0400
1476#define IW_FLOOD_AUTH_EVENT_FLAG 0x0400
1477#define IW_FLOOD_ASSOC_REQ_EVENT_FLAG 0x0401
1478#define IW_FLOOD_REASSOC_REQ_EVENT_FLAG 0x0402
1479#define IW_FLOOD_PROBE_REQ_EVENT_FLAG 0x0403
1480#define IW_FLOOD_DISASSOC_EVENT_FLAG 0x0404
1481#define IW_FLOOD_DEAUTH_EVENT_FLAG 0x0405
1482#define IW_FLOOD_EAP_REQ_EVENT_FLAG 0x0406
1483// if add new flooding attack event flag, please upadte the IW_FLOOD_EVENT_FLAG_END
1484#define IW_FLOOD_EVENT_FLAG_END 0x0406
1485#define IW_FLOOD_EVENT_TYPE_NUM (IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1)
1486// For flooding attack - end
1487
1488// End - WIRELESS EVENTS definition
1489
1490#ifdef CONFIG_STA_SUPPORT
1491// definition for DLS, kathy
1492#define MAX_NUM_OF_INIT_DLS_ENTRY 1
1493#define MAX_NUM_OF_DLS_ENTRY MAX_NUMBER_OF_DLS_ENTRY
1494
1495//Block ACK , rt2860, kathy
1496#define MAX_TX_REORDERBUF 64
1497#define MAX_RX_REORDERBUF 64
1498#define DEFAULT_TX_TIMEOUT 30
1499#define DEFAULT_RX_TIMEOUT 30
1500#ifndef CONFIG_AP_SUPPORT
1501#define MAX_BARECI_SESSION 8
1502#endif
1503
1504#ifndef IW_ESSID_MAX_SIZE
1505/* Maximum size of the ESSID and pAd->nickname strings */
1506#define IW_ESSID_MAX_SIZE 32
1507#endif
1508#endif // CONFIG_STA_SUPPORT //
1509
1510#ifdef MCAST_RATE_SPECIFIC
1511#define MCAST_DISABLE 0
1512#define MCAST_CCK 1
1513#define MCAST_OFDM 2
1514#define MCAST_HTMIX 3
1515#endif // MCAST_RATE_SPECIFIC //
1516
1517// For AsicRadioOff/AsicRadioOn function
1518#define DOT11POWERSAVE 0
1519#define GUIRADIO_OFF 1
1520#define RTMP_HALT 2
1521#define GUI_IDLE_POWER_SAVE 3
1522// --
1523
1524
1525// definition for WpaSupport flag
1526#define WPA_SUPPLICANT_DISABLE 0
1527#define WPA_SUPPLICANT_ENABLE 1
1528#define WPA_SUPPLICANT_ENABLE_WITH_WEB_UI 2
1529
1530// Endian byte swapping codes
1531#define SWAP16(x) \
1532 ((UINT16)( \
1533 (((UINT16)(x) & (UINT16) 0x00ffU) << 8) | \
1534 (((UINT16)(x) & (UINT16) 0xff00U) >> 8) ))
1535
1536#define SWAP32(x) \
1537 ((UINT32)( \
1538 (((UINT32)(x) & (UINT32) 0x000000ffUL) << 24) | \
1539 (((UINT32)(x) & (UINT32) 0x0000ff00UL) << 8) | \
1540 (((UINT32)(x) & (UINT32) 0x00ff0000UL) >> 8) | \
1541 (((UINT32)(x) & (UINT32) 0xff000000UL) >> 24) ))
1542
1543#define SWAP64(x) \
1544 ((UINT64)( \
1545 (UINT64)(((UINT64)(x) & (UINT64) 0x00000000000000ffULL) << 56) | \
1546 (UINT64)(((UINT64)(x) & (UINT64) 0x000000000000ff00ULL) << 40) | \
1547 (UINT64)(((UINT64)(x) & (UINT64) 0x0000000000ff0000ULL) << 24) | \
1548 (UINT64)(((UINT64)(x) & (UINT64) 0x00000000ff000000ULL) << 8) | \
1549 (UINT64)(((UINT64)(x) & (UINT64) 0x000000ff00000000ULL) >> 8) | \
1550 (UINT64)(((UINT64)(x) & (UINT64) 0x0000ff0000000000ULL) >> 24) | \
1551 (UINT64)(((UINT64)(x) & (UINT64) 0x00ff000000000000ULL) >> 40) | \
1552 (UINT64)(((UINT64)(x) & (UINT64) 0xff00000000000000ULL) >> 56) ))
1553
1554#ifdef RT_BIG_ENDIAN
1555
1556#define cpu2le64(x) SWAP64((x))
1557#define le2cpu64(x) SWAP64((x))
1558#define cpu2le32(x) SWAP32((x))
1559#define le2cpu32(x) SWAP32((x))
1560#define cpu2le16(x) SWAP16((x))
1561#define le2cpu16(x) SWAP16((x))
1562#define cpu2be64(x) ((UINT64)(x))
1563#define be2cpu64(x) ((UINT64)(x))
1564#define cpu2be32(x) ((UINT32)(x))
1565#define be2cpu32(x) ((UINT32)(x))
1566#define cpu2be16(x) ((UINT16)(x))
1567#define be2cpu16(x) ((UINT16)(x))
1568
1569#else // Little_Endian
1570
1571#define cpu2le64(x) ((UINT64)(x))
1572#define le2cpu64(x) ((UINT64)(x))
1573#define cpu2le32(x) ((UINT32)(x))
1574#define le2cpu32(x) ((UINT32)(x))
1575#define cpu2le16(x) ((UINT16)(x))
1576#define le2cpu16(x) ((UINT16)(x))
1577#define cpu2be64(x) SWAP64((x))
1578#define be2cpu64(x) SWAP64((x))
1579#define cpu2be32(x) SWAP32((x))
1580#define be2cpu32(x) SWAP32((x))
1581#define cpu2be16(x) SWAP16((x))
1582#define be2cpu16(x) SWAP16((x))
1583
1584#endif // RT_BIG_ENDIAN
1585
1586#endif // __RTMP_DEF_H__
1587
1588
diff --git a/drivers/staging/rt2860/rtmp_type.h b/drivers/staging/rt2860/rtmp_type.h
new file mode 100644
index 00000000000..1fd7df1e179
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/spectrum.h b/drivers/staging/rt2860/spectrum.h
new file mode 100644
index 00000000000..60f25dbdba9
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/spectrum_def.h b/drivers/staging/rt2860/spectrum_def.h
new file mode 100644
index 00000000000..4ca4817bba0
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/sta/aironet.c b/drivers/staging/rt2860/sta/aironet.c
new file mode 100644
index 00000000000..4af4a190618
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/sta/assoc.c b/drivers/staging/rt2860/sta/assoc.c
new file mode 100644
index 00000000000..42db753eed7
--- /dev/null
+++ b/drivers/staging/rt2860/sta/assoc.c
@@ -0,0 +1,1826 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 assoc.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John 2004-9-3 porting from RT2500
36*/
37#include "../rt_config.h"
38
39UCHAR CipherWpaTemplate[] = {
40 0xdd, // WPA IE
41 0x16, // Length
42 0x00, 0x50, 0xf2, 0x01, // oui
43 0x01, 0x00, // Version
44 0x00, 0x50, 0xf2, 0x02, // Multicast
45 0x01, 0x00, // Number of unicast
46 0x00, 0x50, 0xf2, 0x02, // unicast
47 0x01, 0x00, // number of authentication method
48 0x00, 0x50, 0xf2, 0x01 // authentication
49 };
50
51UCHAR CipherWpa2Template[] = {
52 0x30, // RSN IE
53 0x14, // Length
54 0x01, 0x00, // Version
55 0x00, 0x0f, 0xac, 0x02, // group cipher, TKIP
56 0x01, 0x00, // number of pairwise
57 0x00, 0x0f, 0xac, 0x02, // unicast
58 0x01, 0x00, // number of authentication method
59 0x00, 0x0f, 0xac, 0x02, // authentication
60 0x00, 0x00, // RSN capability
61 };
62
63UCHAR Ccx2IeInfo[] = { 0x00, 0x40, 0x96, 0x03, 0x02};
64
65/*
66 ==========================================================================
67 Description:
68 association state machine init, including state transition and timer init
69 Parameters:
70 S - pointer to the association state machine
71
72 IRQL = PASSIVE_LEVEL
73
74 ==========================================================================
75 */
76VOID AssocStateMachineInit(
77 IN PRTMP_ADAPTER pAd,
78 IN STATE_MACHINE *S,
79 OUT STATE_MACHINE_FUNC Trans[])
80{
81 StateMachineInit(S, Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG, (STATE_MACHINE_FUNC)Drop, ASSOC_IDLE, ASSOC_MACHINE_BASE);
82
83 // first column
84 StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)MlmeAssocReqAction);
85 StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)MlmeReassocReqAction);
86 StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)MlmeDisassocReqAction);
87 StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
88
89 // second column
90 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
91 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
92 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
93 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
94 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
95 //
96 // Patch 3Com AP MOde:3CRWE454G72
97 // We send Assoc request frame to this AP, it always send Reassoc Rsp not Associate Rsp.
98 //
99 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
100 StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT, (STATE_MACHINE_FUNC)AssocTimeoutAction);
101
102 // third column
103 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
104 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
105 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
106 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
107 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
108 //
109 // Patch, AP doesn't send Reassociate Rsp frame to Station.
110 //
111 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
112 StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT, (STATE_MACHINE_FUNC)ReassocTimeoutAction);
113
114 // fourth column
115 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
116 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
117 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
118 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
119 StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT, (STATE_MACHINE_FUNC)DisassocTimeoutAction);
120
121 // initialize the timer
122 RTMPInitTimer(pAd, &pAd->MlmeAux.AssocTimer, GET_TIMER_FUNCTION(AssocTimeout), pAd, FALSE);
123 RTMPInitTimer(pAd, &pAd->MlmeAux.ReassocTimer, GET_TIMER_FUNCTION(ReassocTimeout), pAd, FALSE);
124 RTMPInitTimer(pAd, &pAd->MlmeAux.DisassocTimer, GET_TIMER_FUNCTION(DisassocTimeout), pAd, FALSE);
125}
126
127/*
128 ==========================================================================
129 Description:
130 Association timeout procedure. After association timeout, this function
131 will be called and it will put a message into the MLME queue
132 Parameters:
133 Standard timer parameters
134
135 IRQL = DISPATCH_LEVEL
136
137 ==========================================================================
138 */
139VOID AssocTimeout(IN PVOID SystemSpecific1,
140 IN PVOID FunctionContext,
141 IN PVOID SystemSpecific2,
142 IN PVOID SystemSpecific3)
143{
144 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
145
146 // Do nothing if the driver is starting halt state.
147 // This might happen when timer already been fired before cancel timer with mlmehalt
148 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
149 return;
150
151 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL);
152 RT28XX_MLME_HANDLER(pAd);
153}
154
155/*
156 ==========================================================================
157 Description:
158 Reassociation timeout procedure. After reassociation timeout, this
159 function will be called and put a message into the MLME queue
160 Parameters:
161 Standard timer parameters
162
163 IRQL = DISPATCH_LEVEL
164
165 ==========================================================================
166 */
167VOID ReassocTimeout(IN PVOID SystemSpecific1,
168 IN PVOID FunctionContext,
169 IN PVOID SystemSpecific2,
170 IN PVOID SystemSpecific3)
171{
172 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
173
174 // Do nothing if the driver is starting halt state.
175 // This might happen when timer already been fired before cancel timer with mlmehalt
176 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
177 return;
178
179 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL);
180 RT28XX_MLME_HANDLER(pAd);
181}
182
183/*
184 ==========================================================================
185 Description:
186 Disassociation timeout procedure. After disassociation timeout, this
187 function will be called and put a message into the MLME queue
188 Parameters:
189 Standard timer parameters
190
191 IRQL = DISPATCH_LEVEL
192
193 ==========================================================================
194 */
195VOID DisassocTimeout(IN PVOID SystemSpecific1,
196 IN PVOID FunctionContext,
197 IN PVOID SystemSpecific2,
198 IN PVOID SystemSpecific3)
199{
200 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
201
202 // Do nothing if the driver is starting halt state.
203 // This might happen when timer already been fired before cancel timer with mlmehalt
204 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
205 return;
206
207 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL);
208 RT28XX_MLME_HANDLER(pAd);
209}
210
211/*
212 ==========================================================================
213 Description:
214 mlme assoc req handling procedure
215 Parameters:
216 Adapter - Adapter pointer
217 Elem - MLME Queue Element
218 Pre:
219 the station has been authenticated and the following information is stored in the config
220 -# SSID
221 -# supported rates and their length
222 -# listen interval (Adapter->StaCfg.default_listen_count)
223 -# Transmit power (Adapter->StaCfg.tx_power)
224 Post :
225 -# An association request frame is generated and sent to the air
226 -# Association timer starts
227 -# Association state -> ASSOC_WAIT_RSP
228
229 IRQL = DISPATCH_LEVEL
230
231 ==========================================================================
232 */
233VOID MlmeAssocReqAction(
234 IN PRTMP_ADAPTER pAd,
235 IN MLME_QUEUE_ELEM *Elem)
236{
237 UCHAR ApAddr[6];
238 HEADER_802_11 AssocHdr;
239 UCHAR Ccx2Len = 5;
240 UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
241 USHORT ListenIntv;
242 ULONG Timeout;
243 USHORT CapabilityInfo;
244 BOOLEAN TimerCancelled;
245 PUCHAR pOutBuffer = NULL;
246 NDIS_STATUS NStatus;
247 ULONG FrameLen = 0;
248 ULONG tmp;
249 USHORT VarIesOffset;
250 UCHAR CkipFlag;
251 UCHAR CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
252 UCHAR AironetCkipIe = IE_AIRONET_CKIP;
253 UCHAR AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
254 UCHAR AironetIPAddressIE = IE_AIRONET_IPADDRESS;
255 UCHAR AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
256 UCHAR AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
257 USHORT Status;
258
259 // Block all authentication request durning WPA block period
260 if (pAd->StaCfg.bBlockAssoc == TRUE)
261 {
262 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block Assoc request durning WPA block period!\n"));
263 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
264 Status = MLME_STATE_MACHINE_REJECT;
265 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
266 }
267 // check sanity first
268 else if (MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
269 {
270 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
271 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
272
273 // Get an unused nonpaged memory
274 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
275 if (NStatus != NDIS_STATUS_SUCCESS)
276 {
277 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() allocate memory failed \n"));
278 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
279 Status = MLME_FAIL_NO_RESOURCE;
280 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
281 return;
282 }
283
284 // Add by James 03/06/27
285 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
286 // Association don't need to report MAC address
287 pAd->StaCfg.AssocInfo.AvailableRequestFixedIEs =
288 NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL;
289 pAd->StaCfg.AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo;
290 pAd->StaCfg.AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv;
291 // Only reassociate need this
292 //COPY_MAC_ADDR(pAd->StaCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr);
293 pAd->StaCfg.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
294
295 NdisZeroMemory(pAd->StaCfg.ReqVarIEs, MAX_VIE_LEN);
296 // First add SSID
297 VarIesOffset = 0;
298 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SsidIe, 1);
299 VarIesOffset += 1;
300 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SsidLen, 1);
301 VarIesOffset += 1;
302 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
303 VarIesOffset += pAd->MlmeAux.SsidLen;
304
305 // Second add Supported rates
306 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SupRateIe, 1);
307 VarIesOffset += 1;
308 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SupRateLen, 1);
309 VarIesOffset += 1;
310 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen);
311 VarIesOffset += pAd->MlmeAux.SupRateLen;
312 // End Add by James
313
314 if ((pAd->CommonCfg.Channel > 14) &&
315 (pAd->CommonCfg.bIEEE80211H == TRUE))
316 CapabilityInfo |= 0x0100;
317
318 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send ASSOC request...\n"));
319 MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr);
320
321 // Build basic frame first
322 MakeOutgoingFrame(pOutBuffer, &FrameLen,
323 sizeof(HEADER_802_11), &AssocHdr,
324 2, &CapabilityInfo,
325 2, &ListenIntv,
326 1, &SsidIe,
327 1, &pAd->MlmeAux.SsidLen,
328 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
329 1, &SupRateIe,
330 1, &pAd->MlmeAux.SupRateLen,
331 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
332 END_OF_ARGS);
333
334 if (pAd->MlmeAux.ExtRateLen != 0)
335 {
336 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
337 1, &ExtRateIe,
338 1, &pAd->MlmeAux.ExtRateLen,
339 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
340 END_OF_ARGS);
341 FrameLen += tmp;
342 }
343
344#ifdef DOT11_N_SUPPORT
345 // HT
346 if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
347 {
348 ULONG TmpLen;
349 UCHAR HtLen;
350 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
351 if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
352 {
353 HtLen = SIZE_HT_CAP_IE + 4;
354 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
355 1, &WpaIe,
356 1, &HtLen,
357 4, &BROADCOM[0],
358 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
359 END_OF_ARGS);
360 }
361 else
362 {
363#ifdef RT_BIG_ENDIAN
364 HT_CAPABILITY_IE HtCapabilityTmp;
365#endif
366
367#ifndef RT_BIG_ENDIAN
368 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
369 1, &HtCapIe,
370 1, &pAd->MlmeAux.HtCapabilityLen,
371 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
372 END_OF_ARGS);
373#else
374 NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE));
375 NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, pAd->MlmeAux.HtCapabilityLen);
376 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
377 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
378
379 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
380 1, &HtCapIe,
381 1, &pAd->MlmeAux.HtCapabilityLen,
382 pAd->MlmeAux.HtCapabilityLen,&HtCapabilityTmp,
383 END_OF_ARGS);
384#endif
385 }
386 FrameLen += TmpLen;
387 }
388#endif // DOT11_N_SUPPORT //
389
390 // add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
391 // Case I: (Aggregation + Piggy-Back)
392 // 1. user enable aggregation, AND
393 // 2. Mac support piggy-back
394 // 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
395 // Case II: (Aggregation)
396 // 1. user enable aggregation, AND
397 // 2. AP annouces it's AGGREGATION-capable in BEACON
398 if (pAd->CommonCfg.bAggregationCapable)
399 {
400 if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
401 {
402 ULONG TmpLen;
403 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
404 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
405 9, RalinkIe,
406 END_OF_ARGS);
407 FrameLen += TmpLen;
408 }
409 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
410 {
411 ULONG TmpLen;
412 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
413 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
414 9, RalinkIe,
415 END_OF_ARGS);
416 FrameLen += TmpLen;
417 }
418 }
419 else
420 {
421 ULONG TmpLen;
422 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, 0x00, 0x00, 0x00};
423 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
424 9, RalinkIe,
425 END_OF_ARGS);
426 FrameLen += TmpLen;
427 }
428
429 if (pAd->MlmeAux.APEdcaParm.bValid)
430 {
431 if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
432 {
433 QBSS_STA_INFO_PARM QosInfo;
434
435 NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
436 QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
437 QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
438 QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
439 QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
440 QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
441 WmeIe[8] |= *(PUCHAR)&QosInfo;
442 }
443 else
444 {
445 // The Parameter Set Count is set to ¡§0¡¨ in the association request frames
446 // WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f);
447 }
448
449 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
450 9, &WmeIe[0],
451 END_OF_ARGS);
452 FrameLen += tmp;
453 }
454
455 //
456 // Let WPA(#221) Element ID on the end of this association frame.
457 // Otherwise some AP will fail on parsing Element ID and set status fail on Assoc Rsp.
458 // For example: Put Vendor Specific IE on the front of WPA IE.
459 // This happens on AP (Model No:Linksys WRK54G)
460 //
461 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
462 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
463 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
464 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
465 )
466 )
467 {
468 UCHAR RSNIe = IE_WPA;
469
470 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
471 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
472 {
473 RSNIe = IE_WPA2;
474 }
475
476#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
477#ifdef SIOCSIWGENIE
478 if (pAd->StaCfg.WpaSupplicantUP != 1)
479#endif // SIOCSIWGENIE //
480#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
481 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
482
483 // Check for WPA PMK cache list
484 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
485 {
486 INT idx;
487 BOOLEAN FoundPMK = FALSE;
488 // Search chched PMKID, append it if existed
489 for (idx = 0; idx < PMKID_NO; idx++)
490 {
491 if (NdisEqualMemory(ApAddr, &pAd->StaCfg.SavedPMK[idx].BSSID, 6))
492 {
493 FoundPMK = TRUE;
494 break;
495 }
496 }
497
498 if (FoundPMK)
499 {
500 // Set PMK number
501 *(PUSHORT) &pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len] = 1;
502 NdisMoveMemory(&pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len + 2], &pAd->StaCfg.SavedPMK[idx].PMKID, 16);
503 pAd->StaCfg.RSNIE_Len += 18;
504 }
505 }
506
507#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
508#ifdef SIOCSIWGENIE
509 if (pAd->StaCfg.WpaSupplicantUP == 1)
510 {
511 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
512 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
513 END_OF_ARGS);
514 }
515 else
516#endif
517#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
518 {
519 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
520 1, &RSNIe,
521 1, &pAd->StaCfg.RSNIE_Len,
522 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
523 END_OF_ARGS);
524 }
525
526 FrameLen += tmp;
527
528#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
529#ifdef SIOCSIWGENIE
530 if (pAd->StaCfg.WpaSupplicantUP != 1)
531#endif
532#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
533 {
534 // Append Variable IE
535 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
536 VarIesOffset += 1;
537 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->StaCfg.RSNIE_Len, 1);
538 VarIesOffset += 1;
539 }
540 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
541 VarIesOffset += pAd->StaCfg.RSNIE_Len;
542
543 // Set Variable IEs Length
544 pAd->StaCfg.ReqVarIELen = VarIesOffset;
545 }
546
547 // We have update that at PeerBeaconAtJoinRequest()
548 CkipFlag = pAd->StaCfg.CkipFlag;
549 if (CkipFlag != 0)
550 {
551 NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
552 CkipNegotiationBuffer[2] = 0x66;
553 // Make it try KP & MIC, since we have to follow the result from AssocRsp
554 CkipNegotiationBuffer[8] = 0x18;
555 CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
556 CkipFlag = 0x18;
557
558 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
559 1, &AironetCkipIe,
560 1, &AironetCkipLen,
561 AironetCkipLen, CkipNegotiationBuffer,
562 END_OF_ARGS);
563 FrameLen += tmp;
564 }
565
566 // Add CCX v2 request if CCX2 admin state is on
567 if (pAd->StaCfg.CCXControl.field.Enable == 1)
568 {
569
570 //
571 // Add AironetIPAddressIE for Cisco CCX 2.X
572 // Add CCX Version
573 //
574 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
575 1, &AironetIPAddressIE,
576 1, &AironetIPAddressLen,
577 AironetIPAddressLen, AironetIPAddressBuffer,
578 1, &Ccx2Ie,
579 1, &Ccx2Len,
580 Ccx2Len, Ccx2IeInfo,
581 END_OF_ARGS);
582 FrameLen += tmp;
583
584 //
585 // Add CipherSuite CCKM or LeapTkip if setting.
586 //
587#ifdef LEAP_SUPPORT
588 if (LEAP_CCKM_ON(pAd))
589 {
590 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
591 CipherSuiteCiscoCCKMLen, CipherSuiteCiscoCCKM,
592 END_OF_ARGS);
593 FrameLen += tmp;
594
595 // Third add RSN
596 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, CipherSuiteCiscoCCKM, CipherSuiteCiscoCCKMLen); //Save CipherSuite
597 VarIesOffset += CipherSuiteCiscoCCKMLen;
598 }
599 else if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled))
600 {
601 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
602 CipherSuiteCCXTkipLen, CipherSuiteCCXTkip,
603 END_OF_ARGS);
604 FrameLen += tmp;
605
606 // Third add RSN
607 NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, CipherSuiteCCXTkip, CipherSuiteCCXTkipLen);
608 VarIesOffset += CipherSuiteCCXTkipLen;
609 }
610#endif // LEAP_SUPPORT //
611
612 // Add by James 03/06/27
613 // Set Variable IEs Length
614 pAd->StaCfg.ReqVarIELen = VarIesOffset;
615 pAd->StaCfg.AssocInfo.RequestIELength = VarIesOffset;
616
617 // OffsetResponseIEs follow ReqVarIE
618 pAd->StaCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->StaCfg.ReqVarIELen;
619 // End Add by James
620 }
621
622
623 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
624 MlmeFreeMemory(pAd, pOutBuffer);
625
626 RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout);
627 pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP;
628 }
629 else
630 {
631 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n"));
632 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
633 Status = MLME_INVALID_FORMAT;
634 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
635 }
636
637}
638
639/*
640 ==========================================================================
641 Description:
642 mlme reassoc req handling procedure
643 Parameters:
644 Elem -
645 Pre:
646 -# SSID (Adapter->StaCfg.ssid[])
647 -# BSSID (AP address, Adapter->StaCfg.bssid)
648 -# Supported rates (Adapter->StaCfg.supported_rates[])
649 -# Supported rates length (Adapter->StaCfg.supported_rates_len)
650 -# Tx power (Adapter->StaCfg.tx_power)
651
652 IRQL = DISPATCH_LEVEL
653
654 ==========================================================================
655 */
656VOID MlmeReassocReqAction(
657 IN PRTMP_ADAPTER pAd,
658 IN MLME_QUEUE_ELEM *Elem)
659{
660 UCHAR ApAddr[6];
661 HEADER_802_11 ReassocHdr;
662 UCHAR Ccx2Len = 5;
663 UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
664 USHORT CapabilityInfo, ListenIntv;
665 ULONG Timeout;
666 ULONG FrameLen = 0;
667 BOOLEAN TimerCancelled;
668 NDIS_STATUS NStatus;
669 ULONG tmp;
670 PUCHAR pOutBuffer = NULL;
671//CCX 2.X
672#ifdef LEAP_SUPPORT
673 UCHAR CkipFlag;
674 UCHAR CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
675 UCHAR AironetCkipIe = IE_AIRONET_CKIP;
676 UCHAR AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
677 UCHAR AironetIPAddressIE = IE_AIRONET_IPADDRESS;
678 UCHAR AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
679 UCHAR AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
680 UCHAR AironetCCKMReassocIE = IE_AIRONET_CCKMREASSOC;
681 UCHAR AironetCCKMReassocLen = AIRONET_CCKMREASSOC_LENGTH;
682 UCHAR AironetCCKMReassocBuffer[AIRONET_CCKMREASSOC_LENGTH];
683 UCHAR AironetOUI[] = {0x00, 0x40, 0x96, 0x00};
684 UCHAR MICMN[16];
685 UCHAR CalcMicBuffer[80];
686 ULONG CalcMicBufferLen = 0;
687#endif // LEAP_SUPPORT //
688 USHORT Status;
689
690 // Block all authentication request durning WPA block period
691 if (pAd->StaCfg.bBlockAssoc == TRUE)
692 {
693 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block ReAssoc request durning WPA block period!\n"));
694 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
695 Status = MLME_STATE_MACHINE_REJECT;
696 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
697 }
698 // the parameters are the same as the association
699 else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
700 {
701 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
702
703 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
704 if(NStatus != NDIS_STATUS_SUCCESS)
705 {
706 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() allocate memory failed \n"));
707 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
708 Status = MLME_FAIL_NO_RESOURCE;
709 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
710 return;
711 }
712
713 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
714
715 // make frame, use bssid as the AP address??
716 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send RE-ASSOC request...\n"));
717 MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, ApAddr, ApAddr);
718 MakeOutgoingFrame(pOutBuffer, &FrameLen,
719 sizeof(HEADER_802_11), &ReassocHdr,
720 2, &CapabilityInfo,
721 2, &ListenIntv,
722 MAC_ADDR_LEN, ApAddr,
723 1, &SsidIe,
724 1, &pAd->MlmeAux.SsidLen,
725 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
726 1, &SupRateIe,
727 1, &pAd->MlmeAux.SupRateLen,
728 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
729 END_OF_ARGS);
730
731 if (pAd->MlmeAux.ExtRateLen != 0)
732 {
733 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
734 1, &ExtRateIe,
735 1, &pAd->MlmeAux.ExtRateLen,
736 pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
737 END_OF_ARGS);
738 FrameLen += tmp;
739 }
740
741 if (pAd->MlmeAux.APEdcaParm.bValid)
742 {
743 if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
744 {
745 QBSS_STA_INFO_PARM QosInfo;
746
747 NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
748 QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
749 QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
750 QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
751 QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
752 QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
753 WmeIe[8] |= *(PUCHAR)&QosInfo;
754 }
755
756 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
757 9, &WmeIe[0],
758 END_OF_ARGS);
759 FrameLen += tmp;
760 }
761
762#ifdef DOT11_N_SUPPORT
763 // HT
764 if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
765 {
766 ULONG TmpLen;
767 UCHAR HtLen;
768 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
769 if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
770 {
771 HtLen = SIZE_HT_CAP_IE + 4;
772 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
773 1, &WpaIe,
774 1, &HtLen,
775 4, &BROADCOM[0],
776 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
777 END_OF_ARGS);
778 }
779 else
780 {
781 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
782 1, &HtCapIe,
783 1, &pAd->MlmeAux.HtCapabilityLen,
784 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
785 END_OF_ARGS);
786 }
787 FrameLen += TmpLen;
788 }
789#endif // DOT11_N_SUPPORT //
790
791 // add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
792 // Case I: (Aggregation + Piggy-Back)
793 // 1. user enable aggregation, AND
794 // 2. Mac support piggy-back
795 // 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
796 // Case II: (Aggregation)
797 // 1. user enable aggregation, AND
798 // 2. AP annouces it's AGGREGATION-capable in BEACON
799 if (pAd->CommonCfg.bAggregationCapable)
800 {
801 if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
802 {
803 ULONG TmpLen;
804 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
805 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
806 9, RalinkIe,
807 END_OF_ARGS);
808 FrameLen += TmpLen;
809 }
810 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
811 {
812 ULONG TmpLen;
813 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
814 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
815 9, RalinkIe,
816 END_OF_ARGS);
817 FrameLen += TmpLen;
818 }
819 }
820 else
821 {
822 ULONG TmpLen;
823 UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04, 0x00, 0x00, 0x00};
824 MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
825 9, RalinkIe,
826 END_OF_ARGS);
827 FrameLen += TmpLen;
828 }
829#ifdef LEAP_SUPPORT
830 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
831 {
832 CkipFlag = pAd->StaCfg.CkipFlag; // We have update that at PeerBeaconAtJoinRequest()
833 if (CkipFlag != 0)
834 {
835 NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
836 CkipNegotiationBuffer[2] = 0x66;
837 // Make it try KP & MIC, since we have to follow the result from AssocRsp
838 CkipNegotiationBuffer[8] = 0x18;
839 CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
840
841 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
842 1, &AironetCkipIe,
843 1, &AironetCkipLen,
844 AironetCkipLen, CkipNegotiationBuffer,
845 END_OF_ARGS);
846 FrameLen += tmp;
847 }
848
849 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
850 1, &AironetIPAddressIE,
851 1, &AironetIPAddressLen,
852 AironetIPAddressLen, AironetIPAddressBuffer,
853 END_OF_ARGS);
854 FrameLen += tmp;
855
856 //
857 // The RN is incremented before each reassociation request.
858 //
859 pAd->StaCfg.CCKMRN++;
860 //
861 // Calculate MIC = hmac-md5(krk, STA-ID|BSSID|RSNIE|TSF|RN);
862 //
863 COPY_MAC_ADDR(CalcMicBuffer, pAd->CurrentAddress);
864 CalcMicBufferLen = MAC_ADDR_LEN;
865 COPY_MAC_ADDR(CalcMicBuffer + CalcMicBufferLen, pAd->MlmeAux.Bssid);
866 CalcMicBufferLen += MAC_ADDR_LEN;
867 NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, CipherSuiteCiscoCCKM, CipherSuiteCiscoCCKMLen);
868 CalcMicBufferLen += CipherSuiteCiscoCCKMLen;
869 NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, (PUCHAR) &pAd->StaCfg.CCKMBeaconAtJoinTimeStamp, sizeof(pAd->StaCfg.CCKMBeaconAtJoinTimeStamp));
870 CalcMicBufferLen += sizeof(pAd->StaCfg.CCKMBeaconAtJoinTimeStamp);
871 NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, (PUCHAR)&pAd->StaCfg.CCKMRN, sizeof(pAd->StaCfg.CCKMRN));
872 CalcMicBufferLen += sizeof(pAd->StaCfg.CCKMRN);
873 hmac_md5(pAd->StaCfg.KRK, LEN_EAP_MICK, CalcMicBuffer, CalcMicBufferLen, MICMN);
874
875 //
876 // fill up CCKM reassociation request element
877 //
878 NdisMoveMemory(AironetCCKMReassocBuffer, AironetOUI, 4);
879 NdisMoveMemory(AironetCCKMReassocBuffer + 4, (PUCHAR)&pAd->StaCfg.CCKMBeaconAtJoinTimeStamp, 8);
880 NdisMoveMemory(AironetCCKMReassocBuffer + 12, (PUCHAR) &pAd->StaCfg.CCKMRN, 4);
881 NdisMoveMemory(AironetCCKMReassocBuffer +16, MICMN, 8);
882
883 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
884 1, &AironetCCKMReassocIE,
885 1, &AironetCCKMReassocLen,
886 AironetCCKMReassocLen, AironetCCKMReassocBuffer,
887 END_OF_ARGS);
888 FrameLen += tmp;
889
890 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
891 CipherSuiteCiscoCCKMLen,CipherSuiteCiscoCCKM,
892 END_OF_ARGS);
893 FrameLen += tmp;
894 }
895#endif // LEAP_SUPPORT //
896
897 // Add CCX v2 request if CCX2 admin state is on
898 if (pAd->StaCfg.CCXControl.field.Enable == 1)
899 {
900 //
901 // Add CCX Version
902 //
903 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
904 1, &Ccx2Ie,
905 1, &Ccx2Len,
906 Ccx2Len, Ccx2IeInfo,
907 END_OF_ARGS);
908 FrameLen += tmp;
909 }
910
911 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
912 MlmeFreeMemory(pAd, pOutBuffer);
913
914 RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout); /* in mSec */
915 pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP;
916 }
917 else
918 {
919 DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!!!! \n"));
920 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
921 Status = MLME_INVALID_FORMAT;
922 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
923 }
924}
925
926/*
927 ==========================================================================
928 Description:
929 Upper layer issues disassoc request
930 Parameters:
931 Elem -
932
933 IRQL = PASSIVE_LEVEL
934
935 ==========================================================================
936 */
937VOID MlmeDisassocReqAction(
938 IN PRTMP_ADAPTER pAd,
939 IN MLME_QUEUE_ELEM *Elem)
940{
941 PMLME_DISASSOC_REQ_STRUCT pDisassocReq;
942 HEADER_802_11 DisassocHdr;
943 PHEADER_802_11 pDisassocHdr;
944 PUCHAR pOutBuffer = NULL;
945 ULONG FrameLen = 0;
946 NDIS_STATUS NStatus;
947 BOOLEAN TimerCancelled;
948 ULONG Timeout = 0;
949 USHORT Status;
950
951#ifdef QOS_DLS_SUPPORT
952 // send DLS-TEAR_DOWN message,
953 if (pAd->CommonCfg.bDLSCapable)
954 {
955 UCHAR i;
956
957 // tear down local dls table entry
958 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
959 {
960 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
961 {
962 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
963 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
964 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
965 }
966 }
967
968 // tear down peer dls table entry
969 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
970 {
971 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
972 {
973 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
974 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
975 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
976 }
977 }
978 }
979#endif // QOS_DLS_SUPPORT //
980
981 // skip sanity check
982 pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg);
983
984 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
985 if (NStatus != NDIS_STATUS_SUCCESS)
986 {
987 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n"));
988 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
989 Status = MLME_FAIL_NO_RESOURCE;
990 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
991 return;
992 }
993
994
995
996 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &TimerCancelled);
997
998 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send DISASSOC request[BSSID::%02x:%02x:%02x:%02x:%02x:%02x (Reason=%d)\n",
999 pDisassocReq->Addr[0], pDisassocReq->Addr[1], pDisassocReq->Addr[2],
1000 pDisassocReq->Addr[3], pDisassocReq->Addr[4], pDisassocReq->Addr[5], pDisassocReq->Reason));
1001 MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr); // patch peap ttls switching issue
1002 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1003 sizeof(HEADER_802_11),&DisassocHdr,
1004 2, &pDisassocReq->Reason,
1005 END_OF_ARGS);
1006 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1007
1008 // To patch Instance and Buffalo(N) AP
1009 // Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
1010 // Therefore, we send both of them.
1011 pDisassocHdr = (PHEADER_802_11)pOutBuffer;
1012 pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
1013 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1014
1015 MlmeFreeMemory(pAd, pOutBuffer);
1016
1017 pAd->StaCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING;
1018 COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pDisassocReq->Addr);
1019
1020 RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */
1021 pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
1022
1023#ifdef WPA_SUPPLICANT_SUPPORT
1024#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1025 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1026 {
1027 union iwreq_data wrqu;
1028 //send disassociate event to wpa_supplicant
1029 memset(&wrqu, 0, sizeof(wrqu));
1030 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
1031 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1032 }
1033#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1034#endif // WPA_SUPPLICANT_SUPPORT //
1035
1036#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1037 {
1038 union iwreq_data wrqu;
1039 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1040 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1041 }
1042#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1043
1044}
1045
1046/*
1047 ==========================================================================
1048 Description:
1049 peer sends assoc rsp back
1050 Parameters:
1051 Elme - MLME message containing the received frame
1052
1053 IRQL = DISPATCH_LEVEL
1054
1055 ==========================================================================
1056 */
1057VOID PeerAssocRspAction(
1058 IN PRTMP_ADAPTER pAd,
1059 IN MLME_QUEUE_ELEM *Elem)
1060{
1061 USHORT CapabilityInfo, Status, Aid;
1062 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
1063 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
1064 UCHAR Addr2[MAC_ADDR_LEN];
1065 BOOLEAN TimerCancelled;
1066 UCHAR CkipFlag;
1067 EDCA_PARM EdcaParm;
1068 HT_CAPABILITY_IE HtCapability;
1069 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1070 UCHAR HtCapabilityLen;
1071 UCHAR AddHtInfoLen;
1072 UCHAR NewExtChannelOffset = 0xff;
1073
1074 if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
1075 &HtCapability,&AddHtInfo, &HtCapabilityLen,&AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
1076 {
1077 // The frame is for me ?
1078 if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid))
1079 {
1080 DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status));
1081#ifdef DOT11_N_SUPPORT
1082 DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n",Elem->Wcid, pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1083#endif // DOT11_N_SUPPORT //
1084 RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
1085 if(Status == MLME_SUCCESS)
1086 {
1087 // go to procedure listed on page 376
1088 AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
1089 &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
1090
1091#ifdef WPA_SUPPLICANT_SUPPORT
1092#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1093 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1094 {
1095 union iwreq_data wrqu;
1096
1097 SendAssocIEsToWpaSupplicant(pAd);
1098 memset(&wrqu, 0, sizeof(wrqu));
1099 wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
1100 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1101 }
1102#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1103#endif // WPA_SUPPLICANT_SUPPORT //
1104
1105#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1106 {
1107 union iwreq_data wrqu;
1108 wext_notify_event_assoc(pAd);
1109
1110 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1111 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
1112 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1113
1114 }
1115#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1116
1117
1118 pAd->StaCfg.CkipFlag = CkipFlag;
1119 if (CkipFlag & 0x18)
1120 {
1121 NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
1122 NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
1123 NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
1124 pAd->StaCfg.GIV[0] = RandomByte(pAd);
1125 pAd->StaCfg.GIV[1] = RandomByte(pAd);
1126 pAd->StaCfg.GIV[2] = RandomByte(pAd);
1127 pAd->StaCfg.bCkipOn = TRUE;
1128 DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
1129 }
1130 }
1131 else
1132 {
1133 // Faile on Association, we need to check the status code
1134 // Is that a Rogue AP?
1135#ifdef LEAP_SUPPORT
1136 if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (Status == MLME_ALG_NOT_SUPPORT))
1137 { //Possibly Rogue AP
1138 RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, pAd->MlmeAux.Bssid, LEAP_REASON_INVALID_AUTH);
1139 }
1140#endif // LEAP_SUPPORT //
1141 }
1142 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1143 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
1144 }
1145 }
1146 else
1147 {
1148 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerAssocRspAction() sanity check fail\n"));
1149 }
1150}
1151
1152/*
1153 ==========================================================================
1154 Description:
1155 peer sends reassoc rsp
1156 Parametrs:
1157 Elem - MLME message cntaining the received frame
1158
1159 IRQL = DISPATCH_LEVEL
1160
1161 ==========================================================================
1162 */
1163VOID PeerReassocRspAction(
1164 IN PRTMP_ADAPTER pAd,
1165 IN MLME_QUEUE_ELEM *Elem)
1166{
1167 USHORT CapabilityInfo;
1168 USHORT Status;
1169 USHORT Aid;
1170 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
1171 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
1172 UCHAR Addr2[MAC_ADDR_LEN];
1173 UCHAR CkipFlag;
1174 BOOLEAN TimerCancelled;
1175 EDCA_PARM EdcaParm;
1176 HT_CAPABILITY_IE HtCapability;
1177 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1178 UCHAR HtCapabilityLen;
1179 UCHAR AddHtInfoLen;
1180 UCHAR NewExtChannelOffset = 0xff;
1181
1182 if(PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
1183 &HtCapability, &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
1184 {
1185 if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) // The frame is for me ?
1186 {
1187 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status));
1188 RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
1189
1190 if(Status == MLME_SUCCESS)
1191 {
1192 // go to procedure listed on page 376
1193 AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
1194 &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
1195
1196#ifdef WPA_SUPPLICANT_SUPPORT
1197#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1198 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1199 {
1200 union iwreq_data wrqu;
1201
1202 SendAssocIEsToWpaSupplicant(pAd);
1203 memset(&wrqu, 0, sizeof(wrqu));
1204 wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
1205 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1206 }
1207#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1208#endif // WPA_SUPPLICANT_SUPPORT //
1209
1210#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1211 {
1212 union iwreq_data wrqu;
1213 wext_notify_event_assoc(pAd);
1214
1215 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1216 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
1217 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1218
1219 }
1220#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1221
1222 }
1223
1224 //
1225 // Cisco Leap CCKM supported Re-association.
1226 //
1227#ifdef LEAP_SUPPORT
1228 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
1229 {
1230 if (CCKMAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen) == TRUE)
1231 {
1232 pAd->StaCfg.CkipFlag = CkipFlag;
1233 if (CkipFlag & 0x18)
1234 {
1235 NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
1236 NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
1237 NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
1238 pAd->StaCfg.GIV[0] = RandomByte(pAd);
1239 pAd->StaCfg.GIV[1] = RandomByte(pAd);
1240 pAd->StaCfg.GIV[2] = RandomByte(pAd);
1241 pAd->StaCfg.bCkipOn = TRUE;
1242 DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
1243 }
1244
1245 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1246 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1247 }
1248 else
1249 {
1250 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - CCKMAssocRspSanity() sanity check fail\n"));
1251 }
1252 }
1253 else
1254#endif // LEAP_SUPPORT //
1255 {
1256 // CkipFlag is no use for reassociate
1257 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1258 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1259 }
1260 }
1261 }
1262 else
1263 {
1264 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerReassocRspAction() sanity check fail\n"));
1265 }
1266
1267}
1268
1269/*
1270 ==========================================================================
1271 Description:
1272 procedures on IEEE 802.11/1999 p.376
1273 Parametrs:
1274
1275 IRQL = DISPATCH_LEVEL
1276
1277 ==========================================================================
1278 */
1279VOID AssocPostProc(
1280 IN PRTMP_ADAPTER pAd,
1281 IN PUCHAR pAddr2,
1282 IN USHORT CapabilityInfo,
1283 IN USHORT Aid,
1284 IN UCHAR SupRate[],
1285 IN UCHAR SupRateLen,
1286 IN UCHAR ExtRate[],
1287 IN UCHAR ExtRateLen,
1288 IN PEDCA_PARM pEdcaParm,
1289 IN HT_CAPABILITY_IE *pHtCapability,
1290 IN UCHAR HtCapabilityLen,
1291 IN ADD_HT_INFO_IE *pAddHtInfo) // AP might use this additional ht info IE
1292{
1293 ULONG Idx;
1294
1295 pAd->MlmeAux.BssType = BSS_INFRA;
1296 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2);
1297 pAd->MlmeAux.Aid = Aid;
1298 pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
1299#ifdef DOT11_N_SUPPORT
1300 // Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on.
1301 if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE))
1302 {
1303 pEdcaParm->bValid = TRUE;
1304 pEdcaParm->Aifsn[0] = 3;
1305 pEdcaParm->Aifsn[1] = 7;
1306 pEdcaParm->Aifsn[2] = 2;
1307 pEdcaParm->Aifsn[3] = 2;
1308
1309 pEdcaParm->Cwmin[0] = 4;
1310 pEdcaParm->Cwmin[1] = 4;
1311 pEdcaParm->Cwmin[2] = 3;
1312 pEdcaParm->Cwmin[3] = 2;
1313
1314 pEdcaParm->Cwmax[0] = 10;
1315 pEdcaParm->Cwmax[1] = 10;
1316 pEdcaParm->Cwmax[2] = 4;
1317 pEdcaParm->Cwmax[3] = 3;
1318
1319 pEdcaParm->Txop[0] = 0;
1320 pEdcaParm->Txop[1] = 0;
1321 pEdcaParm->Txop[2] = 96;
1322 pEdcaParm->Txop[3] = 48;
1323
1324 }
1325#endif // DOT11_N_SUPPORT //
1326
1327 NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
1328
1329 // filter out un-supported rates
1330 pAd->MlmeAux.SupRateLen = SupRateLen;
1331 NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
1332 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
1333
1334 // filter out un-supported rates
1335 pAd->MlmeAux.ExtRateLen = ExtRateLen;
1336 NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
1337 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
1338
1339#ifdef DOT11_N_SUPPORT
1340 if (HtCapabilityLen > 0)
1341 {
1342 RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo);
1343 }
1344 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n", pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1345
1346 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> (Mmps=%d, AmsduSize=%d, )\n",
1347 pAd->MacTab.Content[BSSID_WCID].MmpsMode, pAd->MacTab.Content[BSSID_WCID].AMsduSize));
1348#endif // DOT11_N_SUPPORT //
1349
1350 // Set New WPA information
1351 Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel);
1352 if (Idx == BSS_NOT_FOUND)
1353 {
1354 DBGPRINT_ERR(("ASSOC - Can't find BSS after receiving Assoc response\n"));
1355 }
1356 else
1357 {
1358 // Init variable
1359 pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0;
1360 NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, MAX_LEN_OF_RSNIE);
1361
1362 // Store appropriate RSN_IE for WPA SM negotiation later
1363 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0))
1364 {
1365 PUCHAR pVIE;
1366 USHORT len;
1367 PEID_STRUCT pEid;
1368
1369 pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs;
1370 len = pAd->ScanTab.BssEntry[Idx].VarIELen;
1371
1372 while (len > 0)
1373 {
1374 pEid = (PEID_STRUCT) pVIE;
1375 // For WPA/WPAPSK
1376 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
1377 && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1378 {
1379 NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
1380 pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
1381 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n"));
1382 }
1383 // For WPA2/WPA2PSK
1384 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
1385 && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1386 {
1387 NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
1388 pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
1389 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n"));
1390 }
1391
1392 pVIE += (pEid->Len + 2);
1393 len -= (pEid->Len + 2);
1394 }
1395 }
1396
1397 if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0)
1398 {
1399 DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> no RSN_IE \n"));
1400 }
1401 else
1402 {
1403 hex_dump("RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
1404 }
1405 }
1406}
1407
1408/*
1409 ==========================================================================
1410 Description:
1411 left part of IEEE 802.11/1999 p.374
1412 Parameters:
1413 Elem - MLME message containing the received frame
1414
1415 IRQL = DISPATCH_LEVEL
1416
1417 ==========================================================================
1418 */
1419VOID PeerDisassocAction(
1420 IN PRTMP_ADAPTER pAd,
1421 IN MLME_QUEUE_ELEM *Elem)
1422{
1423 UCHAR Addr2[MAC_ADDR_LEN];
1424 USHORT Reason;
1425
1426 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction()\n"));
1427 if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
1428 {
1429 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() Reason = %d\n", Reason));
1430 if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2))
1431 {
1432
1433 if (pAd->CommonCfg.bWirelessEvent)
1434 {
1435 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1436 }
1437
1438
1439#ifdef LEAP_SUPPORT
1440 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1441 {
1442 // Cisco_LEAP has start a timer
1443 // We should cancel it if using LEAP
1444 RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &TimerCancelled);
1445 //Check is it mach the LEAP Authentication failed as possible a Rogue AP
1446 //on it's PortSecured not equal to WPA_802_1X_PORT_SECURED while process the Association.
1447 if ((pAd->Mlme.LeapMachine.CurrState != LEAP_IDLE) && (pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
1448 {
1449 RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_AUTH_TIMEOUT);
1450 }
1451 }
1452#endif // LEAP_SUPPORT //
1453 //
1454 // Get Current System time and Turn on AdjacentAPReport
1455 //
1456 NdisGetSystemUpTime(&pAd->StaCfg.CCXAdjacentAPLinkDownTime);
1457 pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
1458 LinkDown(pAd, TRUE);
1459 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1460
1461#ifdef WPA_SUPPLICANT_SUPPORT
1462#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1463 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
1464 {
1465 union iwreq_data wrqu;
1466 //send disassociate event to wpa_supplicant
1467 memset(&wrqu, 0, sizeof(wrqu));
1468 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
1469 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1470 }
1471#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1472#endif // WPA_SUPPLICANT_SUPPORT //
1473
1474#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1475 {
1476 union iwreq_data wrqu;
1477 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1478 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1479 }
1480#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1481 }
1482 }
1483 else
1484 {
1485 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() sanity check fail\n"));
1486 }
1487
1488}
1489
1490/*
1491 ==========================================================================
1492 Description:
1493 what the state machine will do after assoc timeout
1494 Parameters:
1495 Elme -
1496
1497 IRQL = DISPATCH_LEVEL
1498
1499 ==========================================================================
1500 */
1501VOID AssocTimeoutAction(
1502 IN PRTMP_ADAPTER pAd,
1503 IN MLME_QUEUE_ELEM *Elem)
1504{
1505 USHORT Status;
1506 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - AssocTimeoutAction\n"));
1507 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1508 Status = MLME_REJ_TIMEOUT;
1509 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
1510}
1511
1512/*
1513 ==========================================================================
1514 Description:
1515 what the state machine will do after reassoc timeout
1516
1517 IRQL = DISPATCH_LEVEL
1518
1519 ==========================================================================
1520 */
1521VOID ReassocTimeoutAction(
1522 IN PRTMP_ADAPTER pAd,
1523 IN MLME_QUEUE_ELEM *Elem)
1524{
1525 USHORT Status;
1526 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - ReassocTimeoutAction\n"));
1527 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1528 Status = MLME_REJ_TIMEOUT;
1529 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1530}
1531
1532/*
1533 ==========================================================================
1534 Description:
1535 what the state machine will do after disassoc timeout
1536
1537 IRQL = DISPATCH_LEVEL
1538
1539 ==========================================================================
1540 */
1541VOID DisassocTimeoutAction(
1542 IN PRTMP_ADAPTER pAd,
1543 IN MLME_QUEUE_ELEM *Elem)
1544{
1545 USHORT Status;
1546 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - DisassocTimeoutAction\n"));
1547 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1548 Status = MLME_SUCCESS;
1549 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
1550}
1551
1552VOID InvalidStateWhenAssoc(
1553 IN PRTMP_ADAPTER pAd,
1554 IN MLME_QUEUE_ELEM *Elem)
1555{
1556 USHORT Status;
1557 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n",
1558 pAd->Mlme.AssocMachine.CurrState));
1559 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1560 Status = MLME_STATE_MACHINE_REJECT;
1561 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
1562}
1563
1564VOID InvalidStateWhenReassoc(
1565 IN PRTMP_ADAPTER pAd,
1566 IN MLME_QUEUE_ELEM *Elem)
1567{
1568 USHORT Status;
1569 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n",
1570 pAd->Mlme.AssocMachine.CurrState));
1571 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1572 Status = MLME_STATE_MACHINE_REJECT;
1573 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
1574}
1575
1576VOID InvalidStateWhenDisassociate(
1577 IN PRTMP_ADAPTER pAd,
1578 IN MLME_QUEUE_ELEM *Elem)
1579{
1580 USHORT Status;
1581 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n",
1582 pAd->Mlme.AssocMachine.CurrState));
1583 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
1584 Status = MLME_STATE_MACHINE_REJECT;
1585 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
1586}
1587
1588/*
1589 ==========================================================================
1590 Description:
1591 right part of IEEE 802.11/1999 page 374
1592 Note:
1593 This event should never cause ASSOC state machine perform state
1594 transition, and has no relationship with CNTL machine. So we separate
1595 this routine as a service outside of ASSOC state transition table.
1596
1597 IRQL = DISPATCH_LEVEL
1598
1599 ==========================================================================
1600 */
1601VOID Cls3errAction(
1602 IN PRTMP_ADAPTER pAd,
1603 IN PUCHAR pAddr)
1604{
1605 HEADER_802_11 DisassocHdr;
1606 PHEADER_802_11 pDisassocHdr;
1607 PUCHAR pOutBuffer = NULL;
1608 ULONG FrameLen = 0;
1609 NDIS_STATUS NStatus;
1610 USHORT Reason = REASON_CLS3ERR;
1611
1612 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1613 if (NStatus != NDIS_STATUS_SUCCESS)
1614 return;
1615
1616 DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Class 3 Error, Send DISASSOC frame\n"));
1617 MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->CommonCfg.Bssid); // patch peap ttls switching issue
1618 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1619 sizeof(HEADER_802_11),&DisassocHdr,
1620 2, &Reason,
1621 END_OF_ARGS);
1622 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1623
1624 // To patch Instance and Buffalo(N) AP
1625 // Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
1626 // Therefore, we send both of them.
1627 pDisassocHdr = (PHEADER_802_11)pOutBuffer;
1628 pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
1629 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1630
1631 MlmeFreeMemory(pAd, pOutBuffer);
1632
1633 pAd->StaCfg.DisassocReason = REASON_CLS3ERR;
1634 COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr);
1635}
1636
1637 /*
1638 ==========================================================================
1639 Description:
1640 Switch between WEP and CKIP upon new association up.
1641 Parameters:
1642
1643 IRQL = DISPATCH_LEVEL
1644
1645 ==========================================================================
1646 */
1647VOID SwitchBetweenWepAndCkip(
1648 IN PRTMP_ADAPTER pAd)
1649{
1650 int i;
1651 SHAREDKEY_MODE_STRUC csr1;
1652
1653 // if KP is required. change the CipherAlg in hardware shard key table from WEP
1654 // to CKIP. else remain as WEP
1655 if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10))
1656 {
1657 // modify hardware key table so that MAC use correct algorithm to decrypt RX
1658 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
1659 if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP64)
1660 csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP64;
1661 else if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP128)
1662 csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP128;
1663
1664 if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP64)
1665 csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP64;
1666 else if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP128)
1667 csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP128;
1668
1669 if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP64)
1670 csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP64;
1671 else if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP128)
1672 csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP128;
1673
1674 if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP64)
1675 csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP64;
1676 else if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP128)
1677 csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP128;
1678 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
1679 DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
1680
1681 // modify software key table so that driver can specify correct algorithm in TXD upon TX
1682 for (i=0; i<SHARE_KEY_NUM; i++)
1683 {
1684 if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP64)
1685 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP64;
1686 else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP128)
1687 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP128;
1688 }
1689 }
1690
1691 // else if KP NOT inused. change the CipherAlg in hardware shard key table from CKIP
1692 // to WEP.
1693 else
1694 {
1695 // modify hardware key table so that MAC use correct algorithm to decrypt RX
1696 RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
1697 if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP64)
1698 csr1.field.Bss0Key0CipherAlg = CIPHER_WEP64;
1699 else if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP128)
1700 csr1.field.Bss0Key0CipherAlg = CIPHER_WEP128;
1701
1702 if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP64)
1703 csr1.field.Bss0Key1CipherAlg = CIPHER_WEP64;
1704 else if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP128)
1705 csr1.field.Bss0Key1CipherAlg = CIPHER_WEP128;
1706
1707 if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP64)
1708 csr1.field.Bss0Key2CipherAlg = CIPHER_WEP64;
1709 else if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP128)
1710 csr1.field.Bss0Key2CipherAlg = CIPHER_WEP128;
1711
1712 if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP64)
1713 csr1.field.Bss0Key3CipherAlg = CIPHER_WEP64;
1714 else if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP128)
1715 csr1.field.Bss0Key3CipherAlg = CIPHER_WEP128;
1716
1717 // modify software key table so that driver can specify correct algorithm in TXD upon TX
1718 for (i=0; i<SHARE_KEY_NUM; i++)
1719 {
1720 if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP64)
1721 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP64;
1722 else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP128)
1723 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP128;
1724 }
1725
1726 //
1727 // On WPA-NONE, must update CipherAlg.
1728 // Because the OID_802_11_WEP_STATUS was been set after OID_802_11_ADD_KEY
1729 // and CipherAlg will be CIPHER_NONE by Windows ZeroConfig.
1730 // So we need to update CipherAlg after connect.
1731 //
1732 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1733 {
1734 for (i = 0; i < SHARE_KEY_NUM; i++)
1735 {
1736 if (pAd->SharedKey[BSS0][i].KeyLen != 0)
1737 {
1738 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
1739 {
1740 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_TKIP;
1741 }
1742 else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1743 {
1744 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_AES;
1745 }
1746 }
1747 else
1748 {
1749 pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
1750 }
1751 }
1752
1753 csr1.field.Bss0Key0CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
1754 csr1.field.Bss0Key1CipherAlg = pAd->SharedKey[BSS0][1].CipherAlg;
1755 csr1.field.Bss0Key2CipherAlg = pAd->SharedKey[BSS0][2].CipherAlg;
1756 csr1.field.Bss0Key3CipherAlg = pAd->SharedKey[BSS0][3].CipherAlg;
1757 }
1758 RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
1759 DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
1760 }
1761}
1762
1763#ifdef WPA_SUPPLICANT_SUPPORT
1764#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1765VOID SendAssocIEsToWpaSupplicant(
1766 IN PRTMP_ADAPTER pAd)
1767{
1768 union iwreq_data wrqu;
1769 unsigned char custom[IW_CUSTOM_MAX] = {0};
1770
1771 if ((pAd->StaCfg.ReqVarIELen + 17) <= IW_CUSTOM_MAX)
1772 {
1773 sprintf(custom, "ASSOCINFO_ReqIEs=");
1774 NdisMoveMemory(custom+17, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
1775 memset(&wrqu, 0, sizeof(wrqu));
1776 wrqu.data.length = pAd->StaCfg.ReqVarIELen + 17;
1777 wrqu.data.flags = RT_REQIE_EVENT_FLAG;
1778 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
1779
1780 memset(&wrqu, 0, sizeof(wrqu));
1781 wrqu.data.flags = RT_ASSOCINFO_EVENT_FLAG;
1782 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1783 }
1784 else
1785 DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen + 17 > MAX_CUSTOM_LEN\n"));
1786
1787 return;
1788}
1789#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1790#endif // WPA_SUPPLICANT_SUPPORT //
1791
1792#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1793int wext_notify_event_assoc(
1794 IN RTMP_ADAPTER *pAd)
1795{
1796 union iwreq_data wrqu;
1797 char custom[IW_CUSTOM_MAX] = {0};
1798
1799#if WIRELESS_EXT > 17
1800 if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX)
1801 {
1802 wrqu.data.length = pAd->StaCfg.ReqVarIELen;
1803 memcpy(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
1804 wireless_send_event(pAd->net_dev, IWEVASSOCREQIE, &wrqu, custom);
1805 }
1806 else
1807 DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
1808#else
1809 if (((pAd->StaCfg.ReqVarIELen*2) + 17) <= IW_CUSTOM_MAX)
1810 {
1811 UCHAR idx;
1812 wrqu.data.length = (pAd->StaCfg.ReqVarIELen*2) + 17;
1813 sprintf(custom, "ASSOCINFO(ReqIEs=");
1814 for (idx=0; idx<pAd->StaCfg.ReqVarIELen; idx++)
1815 sprintf(custom, "%s%02x", custom, pAd->StaCfg.ReqVarIEs[idx]);
1816 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
1817 }
1818 else
1819 DBGPRINT(RT_DEBUG_TRACE, ("(pAd->StaCfg.ReqVarIELen*2) + 17 > MAX_CUSTOM_LEN\n"));
1820#endif
1821
1822 return 0;
1823
1824}
1825#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1826
diff --git a/drivers/staging/rt2860/sta/auth.c b/drivers/staging/rt2860/sta/auth.c
new file mode 100644
index 00000000000..73fb8d6ea76
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/sta/auth_rsp.c b/drivers/staging/rt2860/sta/auth_rsp.c
new file mode 100644
index 00000000000..f7aa4b99cf5
--- /dev/null
+++ b/drivers/staging/rt2860/sta/auth_rsp.c
@@ -0,0 +1,167 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 auth_rsp.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John 2004-10-1 copy from RT2560
36*/
37#include "../rt_config.h"
38
39/*
40 ==========================================================================
41 Description:
42 authentication state machine init procedure
43 Parameters:
44 Sm - the state machine
45
46 IRQL = PASSIVE_LEVEL
47
48 ==========================================================================
49 */
50VOID AuthRspStateMachineInit(
51 IN PRTMP_ADAPTER pAd,
52 IN PSTATE_MACHINE Sm,
53 IN STATE_MACHINE_FUNC Trans[])
54{
55 StateMachineInit(Sm, Trans, MAX_AUTH_RSP_STATE, MAX_AUTH_RSP_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_RSP_IDLE, AUTH_RSP_MACHINE_BASE);
56
57 // column 1
58 StateMachineSetAction(Sm, AUTH_RSP_IDLE, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
59
60 // column 2
61 StateMachineSetAction(Sm, AUTH_RSP_WAIT_CHAL, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
62
63}
64
65/*
66 ==========================================================================
67 Description:
68
69 IRQL = DISPATCH_LEVEL
70
71 ==========================================================================
72*/
73VOID PeerAuthSimpleRspGenAndSend(
74 IN PRTMP_ADAPTER pAd,
75 IN PHEADER_802_11 pHdr80211,
76 IN USHORT Alg,
77 IN USHORT Seq,
78 IN USHORT Reason,
79 IN USHORT Status)
80{
81 HEADER_802_11 AuthHdr;
82 ULONG FrameLen = 0;
83 PUCHAR pOutBuffer = NULL;
84 NDIS_STATUS NStatus;
85
86 if (Reason != MLME_SUCCESS)
87 {
88 DBGPRINT(RT_DEBUG_TRACE, ("Peer AUTH fail...\n"));
89 return;
90 }
91
92 //Get an unused nonpaged memory
93 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
94 if (NStatus != NDIS_STATUS_SUCCESS)
95 return;
96
97 DBGPRINT(RT_DEBUG_TRACE, ("Send AUTH response (seq#2)...\n"));
98 MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr80211->Addr2, pAd->MlmeAux.Bssid);
99 MakeOutgoingFrame(pOutBuffer, &FrameLen,
100 sizeof(HEADER_802_11), &AuthHdr,
101 2, &Alg,
102 2, &Seq,
103 2, &Reason,
104 END_OF_ARGS);
105 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
106 MlmeFreeMemory(pAd, pOutBuffer);
107}
108
109/*
110 ==========================================================================
111 Description:
112
113 IRQL = DISPATCH_LEVEL
114
115 ==========================================================================
116*/
117VOID PeerDeauthAction(
118 IN PRTMP_ADAPTER pAd,
119 IN PMLME_QUEUE_ELEM Elem)
120{
121 UCHAR Addr2[MAC_ADDR_LEN];
122 USHORT Reason;
123
124 if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
125 {
126 if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid))
127 {
128 DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n", Reason));
129
130
131#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
132 {
133 union iwreq_data wrqu;
134 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
135 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
136 }
137#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
138
139
140 // send wireless event - for deauthentication
141 if (pAd->CommonCfg.bWirelessEvent)
142 RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
143
144 LinkDown(pAd, TRUE);
145
146 // Authentication Mode Cisco_LEAP has start a timer
147 // We should cancel it if using LEAP
148#ifdef LEAP_SUPPORT
149 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
150 {
151 RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &TimerCancelled);
152 //Check is it mach the LEAP Authentication failed as possible a Rogue AP
153 //on it's PortSecured not equal to WPA_802_1X_PORT_SECURED while process the Authenticaton.
154 if ((pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED) && (pAd->Mlme.LeapMachine.CurrState != LEAP_IDLE))
155 {
156 RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_AUTH_TIMEOUT);
157 }
158 }
159#endif // LEAP_SUPPORT //
160 }
161 }
162 else
163 {
164 DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - PeerDeauthAction() sanity check fail\n"));
165 }
166}
167
diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c
new file mode 100644
index 00000000000..36f28f8b4aa
--- /dev/null
+++ b/drivers/staging/rt2860/sta/connect.c
@@ -0,0 +1,2751 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 connect.c
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 John 2004-08-08 Major modification from RT2560
36*/
37#include "../rt_config.h"
38
39UCHAR CipherSuiteWpaNoneTkip[] = {
40 0x00, 0x50, 0xf2, 0x01, // oui
41 0x01, 0x00, // Version
42 0x00, 0x50, 0xf2, 0x02, // Multicast
43 0x01, 0x00, // Number of unicast
44 0x00, 0x50, 0xf2, 0x02, // unicast
45 0x01, 0x00, // number of authentication method
46 0x00, 0x50, 0xf2, 0x00 // authentication
47 };
48UCHAR CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
49
50UCHAR CipherSuiteWpaNoneAes[] = {
51 0x00, 0x50, 0xf2, 0x01, // oui
52 0x01, 0x00, // Version
53 0x00, 0x50, 0xf2, 0x04, // Multicast
54 0x01, 0x00, // Number of unicast
55 0x00, 0x50, 0xf2, 0x04, // unicast
56 0x01, 0x00, // number of authentication method
57 0x00, 0x50, 0xf2, 0x00 // authentication
58 };
59UCHAR CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
60
61// The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS,
62// or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS
63// All settings successfuly negotiated furing MLME state machines become final settings
64// and are copied to pAd->StaActive
65#define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
66{ \
67 (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \
68 NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
69 COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \
70 (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel; \
71 (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel; \
72 (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid; \
73 (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin; \
74 (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo; \
75 (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod; \
76 (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration; \
77 (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod; \
78 (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen; \
79 NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
80 (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen; \
81 NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
82 NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\
83 NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\
84 NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\
85 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid); \
86 (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid; \
87 (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
88 COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
89 (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
90}
91
92/*
93 ==========================================================================
94 Description:
95
96 IRQL = PASSIVE_LEVEL
97
98 ==========================================================================
99*/
100VOID MlmeCntlInit(
101 IN PRTMP_ADAPTER pAd,
102 IN STATE_MACHINE *S,
103 OUT STATE_MACHINE_FUNC Trans[])
104{
105 // Control state machine differs from other state machines, the interface
106 // follows the standard interface
107 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
108}
109
110/*
111 ==========================================================================
112 Description:
113
114 IRQL = DISPATCH_LEVEL
115
116 ==========================================================================
117*/
118VOID MlmeCntlMachinePerformAction(
119 IN PRTMP_ADAPTER pAd,
120 IN STATE_MACHINE *S,
121 IN MLME_QUEUE_ELEM *Elem)
122{
123 switch(pAd->Mlme.CntlMachine.CurrState)
124 {
125 case CNTL_IDLE:
126 {
127 CntlIdleProc(pAd, Elem);
128 }
129 break;
130 case CNTL_WAIT_DISASSOC:
131 CntlWaitDisassocProc(pAd, Elem);
132 break;
133 case CNTL_WAIT_JOIN:
134 CntlWaitJoinProc(pAd, Elem);
135 break;
136
137 // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
138 // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
139 // Therefore not protected by NDIS's "only one outstanding OID request"
140 // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
141 // Current approach is to block new SET request at RTMPSetInformation()
142 // when CntlMachine.CurrState is not CNTL_IDLE
143 case CNTL_WAIT_REASSOC:
144 CntlWaitReassocProc(pAd, Elem);
145 break;
146
147 case CNTL_WAIT_START:
148 CntlWaitStartProc(pAd, Elem);
149 break;
150 case CNTL_WAIT_AUTH:
151 CntlWaitAuthProc(pAd, Elem);
152 break;
153 case CNTL_WAIT_AUTH2:
154 CntlWaitAuthProc2(pAd, Elem);
155 break;
156 case CNTL_WAIT_ASSOC:
157 CntlWaitAssocProc(pAd, Elem);
158 break;
159
160 case CNTL_WAIT_OID_LIST_SCAN:
161 if(Elem->MsgType == MT2_SCAN_CONF)
162 {
163 // Resume TxRing after SCANING complete. We hope the out-of-service time
164 // won't be too long to let upper layer time-out the waiting frames
165 RTMPResumeMsduTransmission(pAd);
166 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
167 {
168 // Cisco scan request is finished, prepare beacon report
169 MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
170 }
171 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
172
173 //
174 // Set LED status to previous status.
175 //
176 if (pAd->bLedOnScanning)
177 {
178 pAd->bLedOnScanning = FALSE;
179 RTMPSetLED(pAd, pAd->LedStatus);
180 }
181#ifdef DOT11N_DRAFT3
182 // AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone.
183 if (pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1)
184 {
185 Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
186 }
187#endif // DOT11N_DRAFT3 //
188 }
189 break;
190
191 case CNTL_WAIT_OID_DISASSOC:
192 if (Elem->MsgType == MT2_DISASSOC_CONF)
193 {
194 LinkDown(pAd, FALSE);
195 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
196 }
197 break;
198 default:
199 DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
200 break;
201 }
202}
203
204
205/*
206 ==========================================================================
207 Description:
208
209 IRQL = DISPATCH_LEVEL
210
211 ==========================================================================
212*/
213VOID CntlIdleProc(
214 IN PRTMP_ADAPTER pAd,
215 IN MLME_QUEUE_ELEM *Elem)
216{
217 MLME_DISASSOC_REQ_STRUCT DisassocReq;
218
219 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
220 return;
221
222 switch(Elem->MsgType)
223 {
224 case OID_802_11_SSID:
225 CntlOidSsidProc(pAd, Elem);
226 break;
227
228 case OID_802_11_BSSID:
229 CntlOidRTBssidProc(pAd,Elem);
230 break;
231
232 case OID_802_11_BSSID_LIST_SCAN:
233 CntlOidScanProc(pAd,Elem);
234 break;
235
236 case OID_802_11_DISASSOCIATE:
237#ifdef RALINK_ATE
238 if(ATE_ON(pAd))
239 {
240 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
241 break;
242 }
243#endif // RALINK_ATE //
244 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
245 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
246 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
247#ifdef WPA_SUPPLICANT_SUPPORT
248 if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
249#endif // WPA_SUPPLICANT_SUPPORT //
250 {
251 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
252 // Since calling this indicate user don't want to connect to that SSID anymore.
253 pAd->MlmeAux.AutoReconnectSsidLen= 32;
254 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
255 }
256 break;
257
258 case MT2_MLME_ROAMING_REQ:
259 CntlMlmeRoamingProc(pAd, Elem);
260 break;
261
262 case OID_802_11_MIC_FAILURE_REPORT_FRAME:
263 WpaMicFailureReportFrame(pAd, Elem);
264 break;
265
266#ifdef QOS_DLS_SUPPORT
267 case RT_OID_802_11_SET_DLS_PARAM:
268 CntlOidDLSSetupProc(pAd, Elem);
269 break;
270#endif // QOS_DLS_SUPPORT //
271
272 default:
273 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
274 break;
275 }
276}
277
278VOID CntlOidScanProc(
279 IN PRTMP_ADAPTER pAd,
280 IN MLME_QUEUE_ELEM *Elem)
281{
282 MLME_SCAN_REQ_STRUCT ScanReq;
283 ULONG BssIdx = BSS_NOT_FOUND;
284 BSS_ENTRY CurrBss;
285
286#ifdef RALINK_ATE
287/* Disable scanning when ATE is running. */
288 if (ATE_ON(pAd))
289 return;
290#endif // RALINK_ATE //
291
292
293 // record current BSS if network is connected.
294 // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
295 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
296 {
297 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
298 if (BssIdx != BSS_NOT_FOUND)
299 {
300 NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
301 }
302 }
303
304 // clean up previous SCAN result, add current BSS back to table if any
305 BssTableInit(&pAd->ScanTab);
306 if (BssIdx != BSS_NOT_FOUND)
307 {
308 // DDK Note: If the NIC is associated with a particular BSSID and SSID
309 // that are not contained in the list of BSSIDs generated by this scan, the
310 // BSSID description of the currently associated BSSID and SSID should be
311 // appended to the list of BSSIDs in the NIC's database.
312 // To ensure this, we append this BSS as the first entry in SCAN result
313 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
314 pAd->ScanTab.BssNr = 1;
315 }
316
317 ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
318 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
319 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
320 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
321}
322
323/*
324 ==========================================================================
325 Description:
326 Before calling this routine, user desired SSID should already been
327 recorded in CommonCfg.Ssid[]
328 IRQL = DISPATCH_LEVEL
329
330 ==========================================================================
331*/
332VOID CntlOidSsidProc(
333 IN PRTMP_ADAPTER pAd,
334 IN MLME_QUEUE_ELEM * Elem)
335{
336 PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
337 MLME_DISASSOC_REQ_STRUCT DisassocReq;
338 ULONG Now;
339
340 // Step 1. record the desired user settings to MlmeAux
341 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
342 NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
343 pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
344 NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
345 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
346
347
348 //
349 // Update Reconnect Ssid, that user desired to connect.
350 //
351 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
352 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
353 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
354
355 // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
356 // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
357 BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
358
359 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
360 pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
361 NdisGetSystemUpTime(&Now);
362
363 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
364 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
365 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
366 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
367 {
368 // Case 1. already connected with an AP who has the desired SSID
369 // with highest RSSI
370
371 // Add checking Mode "LEAP" for CCX 1.0
372 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
373 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
374 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
375 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
376#ifdef LEAP_SUPPORT
377 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
378#endif // LEAP_SUPPORT //
379 ) &&
380 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
381 {
382 // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
383 // connection process
384 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
385 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
386 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
387 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
388 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
389 }
390 else if (pAd->bConfigChanged == TRUE)
391 {
392 // case 1.2 Important Config has changed, we have to reconnect to the same AP
393 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
394 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
395 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
396 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
397 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
398 }
399 else
400 {
401 // case 1.3. already connected to the SSID with highest RSSI.
402 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
403 //
404 // (HCT 12.1) 1c_wlan_mediaevents required
405 // media connect events are indicated when associating with the same AP
406 //
407 if (INFRA_ON(pAd))
408 {
409 //
410 // Since MediaState already is NdisMediaStateConnected
411 // We just indicate the connect event again to meet the WHQL required.
412 //
413 pAd->IndicateMediaState = NdisMediaStateConnected;
414 RTMP_IndicateMediaState(pAd);
415 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
416 }
417
418 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
419#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
420 {
421 union iwreq_data wrqu;
422
423 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
424 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
425 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
426
427 }
428#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
429 }
430 }
431 else if (INFRA_ON(pAd))
432 {
433 //
434 // For RT61
435 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
436 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
437 // But media status is connected, so the SSID not report correctly.
438 //
439 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
440 {
441 //
442 // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
443 //
444 pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
445 }
446 // case 2. active INFRA association existent
447 // roaming is done within miniport driver, nothing to do with configuration
448 // utility. so upon a new SET(OID_802_11_SSID) is received, we just
449 // disassociate with the current associated AP,
450 // then perform a new association with this new SSID, no matter the
451 // new/old SSID are the same or not.
452 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
453 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
454 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
455 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
456 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
457 }
458 else
459 {
460 if (ADHOC_ON(pAd))
461 {
462 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
463 LinkDown(pAd, FALSE);
464 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
465 pAd->IndicateMediaState = NdisMediaStateDisconnected;
466 RTMP_IndicateMediaState(pAd);
467 pAd->ExtraInfo = GENERAL_LINK_DOWN;
468 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
469 }
470
471 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
472 (pAd->StaCfg.bAutoReconnect == TRUE) &&
473 (pAd->MlmeAux.BssType == BSS_INFRA) &&
474 (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
475 )
476 {
477 MLME_SCAN_REQ_STRUCT ScanReq;
478
479 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
480 ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
481 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
482 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
483 // Reset Missed scan number
484 pAd->StaCfg.LastScanTime = Now;
485 }
486 else
487 {
488 pAd->MlmeAux.BssIdx = 0;
489 IterateOnBssTab(pAd);
490 }
491 }
492}
493
494
495/*
496 ==========================================================================
497 Description:
498
499 IRQL = DISPATCH_LEVEL
500
501 ==========================================================================
502*/
503VOID CntlOidRTBssidProc(
504 IN PRTMP_ADAPTER pAd,
505 IN MLME_QUEUE_ELEM * Elem)
506{
507 ULONG BssIdx;
508 PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
509 MLME_DISASSOC_REQ_STRUCT DisassocReq;
510 MLME_JOIN_REQ_STRUCT JoinReq;
511
512#ifdef RALINK_ATE
513/* No need to perform this routine when ATE is running. */
514 if (ATE_ON(pAd))
515 return;
516#endif // RALINK_ATE //
517
518 // record user desired settings
519 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
520 pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
521
522 //
523 // Update Reconnect Ssid, that user desired to connect.
524 //
525 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
526 pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
527 NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
528
529 // find the desired BSS in the latest SCAN result table
530 BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
531 if (BssIdx == BSS_NOT_FOUND)
532 {
533 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
534 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
535 return;
536 }
537
538 // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
539 // Because we need this entry to become the JOIN target in later on SYNC state machine
540 pAd->MlmeAux.BssIdx = 0;
541 pAd->MlmeAux.SsidBssTab.BssNr = 1;
542 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
543
544 // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
545 // we just follow normal procedure. The reason of user doing this may because he/she changed
546 // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
547 // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
548 // checking, we'll disassociate then re-do normal association with this AP at the new channel.
549 // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
550 // connection when setting the same BSSID.
551 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
552 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
553 {
554 // already connected to the same BSSID, go back to idle state directly
555 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
556 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
557#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
558 {
559 union iwreq_data wrqu;
560
561 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
562 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
563 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
564
565 }
566#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
567 }
568 else
569 {
570 if (INFRA_ON(pAd))
571 {
572 // disassoc from current AP first
573 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
574 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
575 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
576 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
577
578 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
579 }
580 else
581 {
582 if (ADHOC_ON(pAd))
583 {
584 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
585 LinkDown(pAd, FALSE);
586 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
587 pAd->IndicateMediaState = NdisMediaStateDisconnected;
588 RTMP_IndicateMediaState(pAd);
589 pAd->ExtraInfo = GENERAL_LINK_DOWN;
590 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
591 }
592
593 // Change the wepstatus to original wepstatus
594 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
595 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
596 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
597
598 // Check cipher suite, AP must have more secured cipher than station setting
599 // Set the Pairwise and Group cipher to match the intended AP setting
600 // We can only connect to AP with less secured cipher setting
601 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
602 {
603 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
604
605 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
606 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
607 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
608 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
609 else // There is no PairCipher Aux, downgrade our capability to TKIP
610 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
611 }
612 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
613 {
614 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
615
616 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
617 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
618 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
619 pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
620 else // There is no PairCipher Aux, downgrade our capability to TKIP
621 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
622
623 // RSN capability
624 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
625 }
626
627 // Set Mix cipher flag
628 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
629 if (pAd->StaCfg.bMixCipher == TRUE)
630 {
631 // If mix cipher, re-build RSNIE
632 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
633 }
634 // No active association, join the BSS immediately
635 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
636 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
637
638 JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
639 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
640
641 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
642 }
643 }
644}
645
646// Roaming is the only external request triggering CNTL state machine
647// despite of other "SET OID" operation. All "SET OID" related oerations
648// happen in sequence, because no other SET OID will be sent to this device
649// until the the previous SET operation is complete (successful o failed).
650// So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
651// or been corrupted by other "SET OID"?
652//
653// IRQL = DISPATCH_LEVEL
654VOID CntlMlmeRoamingProc(
655 IN PRTMP_ADAPTER pAd,
656 IN MLME_QUEUE_ELEM *Elem)
657{
658 // TODO:
659 // AP in different channel may show lower RSSI than actual value??
660 // should we add a weighting factor to compensate it?
661 DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
662
663 NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
664 pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
665
666 BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
667 pAd->MlmeAux.BssIdx = 0;
668 IterateOnBssTab(pAd);
669}
670
671#ifdef QOS_DLS_SUPPORT
672/*
673 ==========================================================================
674 Description:
675
676 IRQL = DISPATCH_LEVEL
677
678 ==========================================================================
679*/
680VOID CntlOidDLSSetupProc(
681 IN PRTMP_ADAPTER pAd,
682 IN MLME_QUEUE_ELEM *Elem)
683{
684 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)Elem->Msg;
685 MLME_DLS_REQ_STRUCT MlmeDlsReq;
686 INT i;
687 USHORT reason = REASON_UNSPECIFY;
688
689 DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n",
690 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5],
691 pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer));
692
693 if (!pAd->CommonCfg.bDLSCapable)
694 return;
695
696 // DLS will not be supported when Adhoc mode
697 if (INFRA_ON(pAd))
698 {
699 for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++)
700 {
701 if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
702 (pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
703 {
704 // 1. Same setting, just drop it
705 DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n"));
706 break;
707 }
708 else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
709 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
710 {
711 // 2. Disable DLS link case, just tear down DLS link
712 reason = REASON_QOS_UNWANTED_MECHANISM;
713 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
714 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
715 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
716 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
717 DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n"));
718 break;
719 }
720 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid)
721 {
722 // 3. Enable case, start DLS setup procedure
723 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
724
725 //Update countdown timer
726 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
727 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
728 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
729 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n"));
730 break;
731 }
732 else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
733 (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
734 {
735 // 4. update mac case, tear down old DLS and setup new DLS
736 reason = REASON_QOS_UNWANTED_MECHANISM;
737 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
738 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
739 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
740 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
741 NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
742 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
743 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
744 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS tear down and restart case\n"));
745 break;
746 }
747 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
748 MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr) && (pAd->StaCfg.DLSEntry[i].TimeOut != pDLS->TimeOut))
749 {
750 // 5. update timeout case, start DLS setup procedure (no tear down)
751 pAd->StaCfg.DLSEntry[i].TimeOut = pDLS->TimeOut;
752 //Update countdown timer
753 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
754 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
755 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
756 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS update timeout case\n"));
757 break;
758 }
759 else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
760 (pAd->StaCfg.DLSEntry[i].Status != DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
761 {
762 // 6. re-setup case, start DLS setup procedure (no tear down)
763 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
764 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
765 DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS retry setup procedure\n"));
766 break;
767 }
768 else
769 {
770 DBGPRINT(RT_DEBUG_WARN,("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n",
771 i, pAd->StaCfg.DLSEntry[i].Valid, pAd->StaCfg.DLSEntry[i].Status, pAd->StaCfg.DLSEntry[i].TimeOut));
772 }
773 }
774 }
775}
776#endif // QOS_DLS_SUPPORT //
777
778/*
779 ==========================================================================
780 Description:
781
782 IRQL = DISPATCH_LEVEL
783
784 ==========================================================================
785*/
786VOID CntlWaitDisassocProc(
787 IN PRTMP_ADAPTER pAd,
788 IN MLME_QUEUE_ELEM *Elem)
789{
790 MLME_START_REQ_STRUCT StartReq;
791
792 if (Elem->MsgType == MT2_DISASSOC_CONF)
793 {
794 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
795
796 if (pAd->CommonCfg.bWirelessEvent)
797 {
798 RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
799 }
800
801 LinkDown(pAd, FALSE);
802
803 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
804 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
805 {
806 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
807 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
808 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
809 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
810 }
811 // case 2. try each matched BSS
812 else
813 {
814 pAd->MlmeAux.BssIdx = 0;
815
816 IterateOnBssTab(pAd);
817 }
818 }
819}
820
821/*
822 ==========================================================================
823 Description:
824
825 IRQL = DISPATCH_LEVEL
826
827 ==========================================================================
828*/
829VOID CntlWaitJoinProc(
830 IN PRTMP_ADAPTER pAd,
831 IN MLME_QUEUE_ELEM *Elem)
832{
833 USHORT Reason;
834 MLME_AUTH_REQ_STRUCT AuthReq;
835
836 if (Elem->MsgType == MT2_JOIN_CONF)
837 {
838 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
839 if (Reason == MLME_SUCCESS)
840 {
841 // 1. joined an IBSS, we are pretty much done here
842 if (pAd->MlmeAux.BssType == BSS_ADHOC)
843 {
844 //
845 // 5G bands rules of Japan:
846 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
847 //
848 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
849 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
850 )
851 {
852 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
853 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
854 return;
855 }
856
857 LinkUp(pAd, BSS_ADHOC);
858 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
859 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
860 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
861 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
862
863 pAd->IndicateMediaState = NdisMediaStateConnected;
864 pAd->ExtraInfo = GENERAL_LINK_UP;
865 }
866 // 2. joined a new INFRA network, start from authentication
867 else
868 {
869#ifdef LEAP_SUPPORT
870 // Add AuthMode "LEAP" for CCX 1.X
871 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
872 {
873 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
874 }
875 else
876#endif // LEAP_SUPPORT //
877 {
878 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
879 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
880 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
881 {
882 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
883 }
884 else
885 {
886 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
887 }
888 }
889 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
890 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
891
892 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
893 }
894 }
895 else
896 {
897 // 3. failed, try next BSS
898 pAd->MlmeAux.BssIdx++;
899 IterateOnBssTab(pAd);
900 }
901 }
902}
903
904
905/*
906 ==========================================================================
907 Description:
908
909 IRQL = DISPATCH_LEVEL
910
911 ==========================================================================
912*/
913VOID CntlWaitStartProc(
914 IN PRTMP_ADAPTER pAd,
915 IN MLME_QUEUE_ELEM *Elem)
916{
917 USHORT Result;
918
919 if (Elem->MsgType == MT2_START_CONF)
920 {
921 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
922 if (Result == MLME_SUCCESS)
923 {
924 //
925 // 5G bands rules of Japan:
926 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
927 //
928 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
929 RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
930 )
931 {
932 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
933 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
934 return;
935 }
936#ifdef DOT11_N_SUPPORT
937 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
938 {
939 N_ChannelCheck(pAd);
940 SetCommonHT(pAd);
941 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
942 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
943 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
944 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
945 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
946 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
947
948 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
949 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
950 {
951 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
952 }
953 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
954 (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
955 {
956 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
957 }
958 }
959 else
960#endif // DOT11_N_SUPPORT //
961 {
962 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
963 }
964 LinkUp(pAd, BSS_ADHOC);
965 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
966 // Before send beacon, driver need do radar detection
967 if ((pAd->CommonCfg.Channel > 14 )
968 && (pAd->CommonCfg.bIEEE80211H == 1)
969 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
970 {
971 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
972 pAd->CommonCfg.RadarDetect.RDCount = 0;
973#ifdef DFS_SUPPORT
974 BbpRadarDetectionStart(pAd);
975#endif // DFS_SUPPORT //
976 }
977
978 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
979 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
980 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
981 }
982 else
983 {
984 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
985 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
986 }
987 }
988}
989
990/*
991 ==========================================================================
992 Description:
993
994 IRQL = DISPATCH_LEVEL
995
996 ==========================================================================
997*/
998VOID CntlWaitAuthProc(
999 IN PRTMP_ADAPTER pAd,
1000 IN MLME_QUEUE_ELEM *Elem)
1001{
1002 USHORT Reason;
1003 MLME_ASSOC_REQ_STRUCT AssocReq;
1004 MLME_AUTH_REQ_STRUCT AuthReq;
1005
1006 if (Elem->MsgType == MT2_AUTH_CONF)
1007 {
1008 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1009 if (Reason == MLME_SUCCESS)
1010 {
1011 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1012 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1013 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1014
1015#ifdef LEAP_SUPPORT
1016 //
1017 // Cisco Leap CCKM supported Re-association.
1018 //
1019 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
1020 {
1021 //if CCKM is turn on , that's mean Fast Reauthentication
1022 //Use CCKM Reassociation instead of normal association for Fast Roaming.
1023 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
1024 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1025
1026 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
1027 }
1028 else
1029#endif // LEAP_SUPPORT //
1030 {
1031 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1032 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1033
1034 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1035 }
1036 }
1037 else
1038 {
1039 // This fail may because of the AP already keep us in its MAC table without
1040 // ageing-out. The previous authentication attempt must have let it remove us.
1041 // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
1042 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
1043#ifdef LEAP_SUPPORT
1044 //Add AuthMode "LEAP" for CCX 1.X
1045 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1046 {
1047 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
1048 }
1049 else
1050#endif // LEAP_SUPPORT //
1051 {
1052 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
1053 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
1054 {
1055 // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
1056 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
1057 }
1058 else
1059 {
1060 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1061 }
1062 }
1063 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1064 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1065
1066 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1067 }
1068 }
1069}
1070
1071/*
1072 ==========================================================================
1073 Description:
1074
1075 IRQL = DISPATCH_LEVEL
1076
1077 ==========================================================================
1078*/
1079VOID CntlWaitAuthProc2(
1080 IN PRTMP_ADAPTER pAd,
1081 IN MLME_QUEUE_ELEM *Elem)
1082{
1083 USHORT Reason;
1084 MLME_ASSOC_REQ_STRUCT AssocReq;
1085 MLME_AUTH_REQ_STRUCT AuthReq;
1086
1087 if (Elem->MsgType == MT2_AUTH_CONF)
1088 {
1089 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1090 if (Reason == MLME_SUCCESS)
1091 {
1092 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
1093 AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
1094 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
1095 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
1096 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
1097
1098 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
1099 }
1100 else
1101 {
1102#ifdef LEAP_SUPPORT
1103 // Process LEAP first, since it use different control variable
1104 // We don't want to affect other poven operation
1105 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1106 {
1107 // LEAP Auth not success, try next BSS
1108 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
1109 DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
1110 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1111 pAd->MlmeAux.BssIdx++;
1112 IterateOnBssTab(pAd);
1113 }
1114 else
1115#endif // LEAP_SUPPORT //
1116 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
1117 (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
1118 {
1119 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
1120 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
1121 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
1122 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
1123
1124 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
1125 }
1126 else
1127 {
1128 // not success, try next BSS
1129 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
1130 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
1131 pAd->MlmeAux.BssIdx++;
1132 IterateOnBssTab(pAd);
1133 }
1134 }
1135 }
1136}
1137
1138/*
1139 ==========================================================================
1140 Description:
1141
1142 IRQL = DISPATCH_LEVEL
1143
1144 ==========================================================================
1145*/
1146VOID CntlWaitAssocProc(
1147 IN PRTMP_ADAPTER pAd,
1148 IN MLME_QUEUE_ELEM *Elem)
1149{
1150 USHORT Reason;
1151
1152 if (Elem->MsgType == MT2_ASSOC_CONF)
1153 {
1154 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1155 if (Reason == MLME_SUCCESS)
1156 {
1157 LinkUp(pAd, BSS_INFRA);
1158 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1159 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1160
1161 if (pAd->CommonCfg.bWirelessEvent)
1162 {
1163 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1164 }
1165 }
1166 else
1167 {
1168 // not success, try next BSS
1169 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1170 pAd->MlmeAux.BssIdx++;
1171 IterateOnBssTab(pAd);
1172 }
1173 }
1174}
1175
1176/*
1177 ==========================================================================
1178 Description:
1179
1180 IRQL = DISPATCH_LEVEL
1181
1182 ==========================================================================
1183*/
1184VOID CntlWaitReassocProc(
1185 IN PRTMP_ADAPTER pAd,
1186 IN MLME_QUEUE_ELEM *Elem)
1187{
1188 USHORT Result;
1189
1190 if (Elem->MsgType == MT2_REASSOC_CONF)
1191 {
1192 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1193 if (Result == MLME_SUCCESS)
1194 {
1195 //
1196 // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1197 //
1198 LinkUp(pAd, BSS_INFRA);
1199
1200 // send wireless event - for association
1201 if (pAd->CommonCfg.bWirelessEvent)
1202 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1203
1204
1205#ifdef LEAP_SUPPORT
1206 if (LEAP_CCKM_ON(pAd))
1207 {
1208 STA_PORT_SECURED(pAd);
1209 pAd->StaCfg.WpaState = SS_FINISH;
1210 }
1211#endif // LEAP_SUPPORT //
1212 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1213 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1214 }
1215 else
1216 {
1217 // reassoc failed, try to pick next BSS in the BSS Table
1218 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1219 pAd->MlmeAux.RoamIdx++;
1220 IterateOnBssTab2(pAd);
1221 }
1222 }
1223}
1224
1225/*
1226 ==========================================================================
1227 Description:
1228
1229 IRQL = DISPATCH_LEVEL
1230
1231 ==========================================================================
1232*/
1233VOID LinkUp(
1234 IN PRTMP_ADAPTER pAd,
1235 IN UCHAR BssType)
1236{
1237 ULONG Now;
1238 UINT32 Data;
1239 BOOLEAN Cancelled;
1240 UCHAR Value = 0, idx;
1241 MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1242
1243 pEntry = &pAd->MacTab.Content[BSSID_WCID];
1244
1245 //
1246 // ASSOC - DisassocTimeoutAction
1247 // CNTL - Dis-associate successful
1248 // !!! LINK DOWN !!!
1249 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1250 //
1251 // To prevent DisassocTimeoutAction to call Link down after we link up,
1252 // cancel the DisassocTimer no matter what it start or not.
1253 //
1254 RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
1255
1256 COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1257
1258#ifdef DOT11_N_SUPPORT
1259 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1260#endif // DOT11_N_SUPPORT //
1261 // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1262 // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1263 // to examine if cipher algorithm switching is required.
1264 //rt2860b. Don't know why need this
1265 SwitchBetweenWepAndCkip(pAd);
1266
1267#ifdef RT2860
1268 // Before power save before link up function, We will force use 1R.
1269 // So after link up, check Rx antenna # again.
1270 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1271 if(pAd->Antenna.field.RxPath == 3)
1272 {
1273 Value |= (0x10);
1274 }
1275 else if(pAd->Antenna.field.RxPath == 2)
1276 {
1277 Value |= (0x8);
1278 }
1279 else if(pAd->Antenna.field.RxPath == 1)
1280 {
1281 Value |= (0x0);
1282 }
1283 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1284 pAd->StaCfg.BBPR3 = Value;
1285#endif // RT2860 //
1286
1287 if (BssType == BSS_ADHOC)
1288 {
1289 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1290 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1291
1292#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
1293 // No carrier detection when adhoc
1294 // CarrierDetectionStop(pAd);
1295 pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
1296#endif // CARRIER_DETECTION_SUPPORT //
1297
1298 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1299 }
1300 else
1301 {
1302 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1303 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1304
1305 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1306 }
1307
1308 // 3*3
1309 // reset Tx beamforming bit
1310 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1311 Value &= (~0x01);
1312 Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1313 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1314
1315#ifdef DOT11_N_SUPPORT
1316 // Change to AP channel
1317 if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1318 {
1319 // Must using 40MHz.
1320 pAd->CommonCfg.BBPCurrentBW = BW_40;
1321 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1322 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1323
1324 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1325 Value &= (~0x18);
1326 Value |= 0x10;
1327 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1328
1329 // RX : control channel at lower
1330 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1331 Value &= (~0x20);
1332 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1333#ifdef RT2860
1334 pAd->StaCfg.BBPR3 = Value;
1335#endif // RT2860 //
1336
1337 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1338 Data &= 0xfffffffe;
1339 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1340
1341 if (pAd->MACVersion == 0x28600100)
1342 {
1343 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1344 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1345 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1346 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1347 }
1348
1349 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1350 }
1351 else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1352 {
1353 // Must using 40MHz.
1354 pAd->CommonCfg.BBPCurrentBW = BW_40;
1355 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1356 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1357
1358 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1359 Value &= (~0x18);
1360 Value |= 0x10;
1361 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1362
1363 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1364 Data |= 0x1;
1365 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1366
1367 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1368 Value |= (0x20);
1369 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1370#ifdef RT2860
1371 pAd->StaCfg.BBPR3 = Value;
1372#endif // RT2860 //
1373
1374 if (pAd->MACVersion == 0x28600100)
1375 {
1376 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1377 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1378 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1379 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1380 }
1381
1382 DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1383 }
1384 else
1385#endif // DOT11_N_SUPPORT //
1386 {
1387 pAd->CommonCfg.BBPCurrentBW = BW_20;
1388 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1389 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1390 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1391
1392 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1393 Value &= (~0x18);
1394 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1395
1396 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1397 Data &= 0xfffffffe;
1398 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1399
1400 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1401 Value &= (~0x20);
1402 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1403#ifdef RT2860
1404 pAd->StaCfg.BBPR3 = Value;
1405#endif // RT2860 //
1406
1407 if (pAd->MACVersion == 0x28600100)
1408 {
1409 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1410 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1411 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1412 DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1413 }
1414
1415 DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1416 }
1417
1418 RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1419 //
1420 // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1421 //
1422 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1423
1424 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1425 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1426
1427#ifdef DOT11_N_SUPPORT
1428 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1429#endif // DOT11_N_SUPPORT //
1430
1431 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1432
1433 AsicSetSlotTime(pAd, TRUE);
1434 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1435
1436 // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1437 AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1438
1439#ifdef DOT11_N_SUPPORT
1440 if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1441 {
1442 // Update HT protectionfor based on AP's operating mode.
1443 if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1444 {
1445 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
1446 }
1447 else
1448 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
1449 }
1450#endif // DOT11_N_SUPPORT //
1451
1452 NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1453
1454 NdisGetSystemUpTime(&Now);
1455 pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
1456
1457 if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1458 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1459 {
1460 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1461 }
1462
1463 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1464
1465 if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1466 {
1467#ifdef DFS_SUPPORT
1468 RadarDetectionStop(pAd);
1469#endif // DFS_SUPPORT //
1470 }
1471 pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1472
1473 if (BssType == BSS_ADHOC)
1474 {
1475 MakeIbssBeacon(pAd);
1476 if ((pAd->CommonCfg.Channel > 14)
1477 && (pAd->CommonCfg.bIEEE80211H == 1)
1478 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1479 {
1480 ; //Do nothing
1481 }
1482 else
1483 {
1484 AsicEnableIbssSync(pAd);
1485 }
1486
1487 // In ad hoc mode, use MAC table from index 1.
1488 // 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.
1489 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1490 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1491
1492 // If WEP is enabled, add key material and cipherAlg into Asic
1493 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1494
1495 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1496 {
1497 PUCHAR Key;
1498 UCHAR CipherAlg;
1499
1500 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1501 {
1502 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1503 Key = pAd->SharedKey[BSS0][idx].Key;
1504
1505 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1506 {
1507 // Set key material and cipherAlg to Asic
1508 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1509
1510 if (idx == pAd->StaCfg.DefaultKeyId)
1511 {
1512 // Update WCID attribute table and IVEIV table for this group key table
1513 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1514 }
1515 }
1516
1517
1518 }
1519 }
1520 // If WPANone is enabled, add key material and cipherAlg into Asic
1521 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1522 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1523 {
1524 pAd->StaCfg.DefaultKeyId = 0; // always be zero
1525
1526 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1527 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1528 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1529
1530 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1531 {
1532 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1533 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1534 }
1535
1536 // Decide its ChiperAlg
1537 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1538 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1539 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1540 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1541 else
1542 {
1543 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1544 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1545 }
1546
1547 // Set key material and cipherAlg to Asic
1548 AsicAddSharedKeyEntry(pAd,
1549 BSS0,
1550 0,
1551 pAd->SharedKey[BSS0][0].CipherAlg,
1552 pAd->SharedKey[BSS0][0].Key,
1553 pAd->SharedKey[BSS0][0].TxMic,
1554 pAd->SharedKey[BSS0][0].RxMic);
1555
1556 // Update WCID attribute table and IVEIV table for this group key table
1557 RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1558
1559 }
1560
1561 }
1562 else // BSS_INFRA
1563 {
1564 // Check the new SSID with last SSID
1565 while (Cancelled == TRUE)
1566 {
1567 if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1568 {
1569 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1570 {
1571 // Link to the old one no linkdown is required.
1572 break;
1573 }
1574 }
1575 // Send link down event before set to link up
1576 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1577 RTMP_IndicateMediaState(pAd);
1578 pAd->ExtraInfo = GENERAL_LINK_DOWN;
1579 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1580 break;
1581 }
1582
1583 //
1584 // On WPA mode, Remove All Keys if not connect to the last BSSID
1585 // Key will be set after 4-way handshake.
1586 //
1587 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1588 {
1589 ULONG IV;
1590
1591 // Remove all WPA keys
1592 RTMPWPARemoveAllKeys(pAd);
1593 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1594 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1595
1596 // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1597 // If IV related values are too large in GroupMsg2, AP would ignore this message.
1598 IV = 0;
1599 IV |= (pAd->StaCfg.DefaultKeyId << 30);
1600 AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1601 }
1602 // NOTE:
1603 // the decision of using "short slot time" or not may change dynamically due to
1604 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1605
1606 // NOTE:
1607 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1608 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1609
1610 ComposePsPoll(pAd);
1611 ComposeNullFrame(pAd);
1612
1613 AsicEnableBssSync(pAd);
1614
1615 // Add BSSID to WCID search table
1616 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1617
1618 NdisAcquireSpinLock(&pAd->MacTabLock);
1619 // add this BSSID entry into HASH table
1620 {
1621 UCHAR HashIdx;
1622
1623 //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1624 HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1625 if (pAd->MacTab.Hash[HashIdx] == NULL)
1626 {
1627 pAd->MacTab.Hash[HashIdx] = pEntry;
1628 }
1629 else
1630 {
1631 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1632 while (pCurrEntry->pNext != NULL)
1633 pCurrEntry = pCurrEntry->pNext;
1634 pCurrEntry->pNext = pEntry;
1635 }
1636 }
1637 NdisReleaseSpinLock(&pAd->MacTabLock);
1638
1639
1640 // If WEP is enabled, add paiewise and shared key
1641#ifdef WPA_SUPPLICANT_SUPPORT
1642 if (((pAd->StaCfg.WpaSupplicantUP)&&
1643 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1644 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1645 ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1646 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1647#else
1648 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1649#endif // WPA_SUPPLICANT_SUPPORT //
1650 {
1651 PUCHAR Key;
1652 UCHAR CipherAlg;
1653
1654 for (idx=0; idx < SHARE_KEY_NUM; idx++)
1655 {
1656 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1657 Key = pAd->SharedKey[BSS0][idx].Key;
1658
1659 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1660 {
1661 // Set key material and cipherAlg to Asic
1662 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1663
1664 if (idx == pAd->StaCfg.DefaultKeyId)
1665 {
1666 // Assign group key info
1667 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1668
1669 // Assign pairwise key info
1670 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1671 }
1672 }
1673 }
1674 }
1675
1676 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1677 // should wait until at least 2 active nodes in this BSSID.
1678 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1679
1680 // For GUI ++
1681 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1682 {
1683 pAd->IndicateMediaState = NdisMediaStateConnected;
1684 pAd->ExtraInfo = GENERAL_LINK_UP;
1685 }
1686 // --
1687 RTMP_IndicateMediaState(pAd);
1688
1689 // Add BSSID in my MAC Table.
1690 NdisAcquireSpinLock(&pAd->MacTabLock);
1691 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1692 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1693 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1694 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
1695 pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
1696 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1697 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1698 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1699 NdisReleaseSpinLock(&pAd->MacTabLock);
1700
1701 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
1702 pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1703
1704 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1705#ifdef DOT11_N_SUPPORT
1706 MlmeUpdateHtTxRates(pAd, BSS0);
1707 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1708#endif // DOT11_N_SUPPORT //
1709
1710 //
1711 // Report Adjacent AP report.
1712 //
1713#ifdef LEAP_SUPPORT
1714 CCXAdjacentAPReport(pAd);
1715#endif // LEAP_SUPPORT //
1716
1717 if (pAd->CommonCfg.bAggregationCapable)
1718 {
1719 if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1720 {
1721
1722 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1723 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1724 RTMPSetPiggyBack(pAd, TRUE);
1725 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1726 }
1727 else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1728 {
1729 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1730 }
1731 }
1732
1733 if (pAd->MlmeAux.APRalinkIe != 0x0)
1734 {
1735#ifdef DOT11_N_SUPPORT
1736 if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1737 {
1738 AsicEnableRDG(pAd);
1739 }
1740#endif // DOT11_N_SUPPORT //
1741 OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1742 CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1743 }
1744 else
1745 {
1746 OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1747 CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1748 }
1749 }
1750
1751#ifdef DOT11_N_SUPPORT
1752 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));
1753#endif // DOT11_N_SUPPORT //
1754
1755 // Set LED
1756 RTMPSetLED(pAd, LED_LINK_UP);
1757
1758 pAd->Mlme.PeriodicRound = 0;
1759 pAd->Mlme.OneSecPeriodicRound = 0;
1760 pAd->bConfigChanged = FALSE; // Reset config flag
1761 pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
1762
1763 // Set asic auto fall back
1764 {
1765 PUCHAR pTable;
1766 UCHAR TableSize = 0;
1767
1768 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1769 AsicUpdateAutoFallBackTable(pAd, pTable);
1770 }
1771
1772 NdisAcquireSpinLock(&pAd->MacTabLock);
1773 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1774 pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1775 if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1776 {
1777 pEntry->bAutoTxRateSwitch = FALSE;
1778#ifdef DOT11_N_SUPPORT
1779 if (pEntry->HTPhyMode.field.MCS == 32)
1780 pEntry->HTPhyMode.field.ShortGI = GI_800;
1781
1782 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1783 pEntry->HTPhyMode.field.STBC = STBC_NONE;
1784#endif // DOT11_N_SUPPORT //
1785 // If the legacy mode is set, overwrite the transmit setting of this entry.
1786 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1787 RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1788 }
1789 else
1790 pEntry->bAutoTxRateSwitch = TRUE;
1791 NdisReleaseSpinLock(&pAd->MacTabLock);
1792
1793 // Let Link Status Page display first initial rate.
1794 pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1795 // Select DAC according to HT or Legacy
1796 if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1797 {
1798 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1799 Value &= (~0x18);
1800 if (pAd->Antenna.field.TxPath == 2)
1801 {
1802 Value |= 0x10;
1803 }
1804 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1805 }
1806 else
1807 {
1808 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1809 Value &= (~0x18);
1810 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1811 }
1812
1813#ifdef DOT11_N_SUPPORT
1814 if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1815 {
1816 }
1817 else if (pEntry->MaxRAmpduFactor == 0)
1818 {
1819 // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1820 // Because our Init value is 1 at MACRegTable.
1821 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1822 }
1823#endif // DOT11_N_SUPPORT //
1824
1825 // Patch for Marvel AP to gain high throughput
1826 // Need to set as following,
1827 // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1828 // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1829 // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1830 // 4. kick per two packets when dequeue
1831 //
1832 // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1833 //
1834 // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
1835#ifdef DOT11_N_SUPPORT
1836 if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1837 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1838 {
1839 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1840 Data &= 0xFFFFFF00;
1841 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1842
1843 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1844 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1845 }
1846 else
1847#endif // DOT11_N_SUPPORT //
1848 if (pAd->CommonCfg.bEnableTxBurst)
1849 {
1850 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1851 Data &= 0xFFFFFF00;
1852 Data |= 0x60;
1853 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1854 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1855
1856 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1857 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1858 }
1859 else
1860 {
1861 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1862 Data &= 0xFFFFFF00;
1863 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1864
1865 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1866 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1867 }
1868
1869#ifdef DOT11_N_SUPPORT
1870 // Re-check to turn on TX burst or not.
1871 if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1872 {
1873 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1874 if (pAd->CommonCfg.bEnableTxBurst)
1875 {
1876 UINT32 MACValue = 0;
1877 // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
1878 // I didn't change PBF_MAX_PCNT setting.
1879 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1880 MACValue &= 0xFFFFFF00;
1881 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1882 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1883 }
1884 }
1885 else
1886 {
1887 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1888 }
1889#endif // DOT11_N_SUPPORT //
1890
1891 pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1892 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1893 DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1894 // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1895 // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1896 // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1897
1898 if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1899 {
1900 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1901 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1902 }
1903
1904 NdisAcquireSpinLock(&pAd->MacTabLock);
1905 pEntry->PortSecured = pAd->StaCfg.PortSecured;
1906 NdisReleaseSpinLock(&pAd->MacTabLock);
1907
1908 //
1909 // Patch Atheros AP TX will breakdown issue.
1910 // AP Model: DLink DWL-8200AP
1911 //
1912 if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1913 {
1914 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1915 }
1916 else
1917 {
1918 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1919 }
1920
1921 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1922
1923#ifdef DOT11_N_SUPPORT
1924#ifdef DOT11N_DRAFT3
1925 if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
1926 {
1927 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
1928 BuildEffectedChannelList(pAd);
1929 }
1930#endif // DOT11N_DRAFT3 //
1931#endif // DOT11_N_SUPPORT //
1932}
1933
1934/*
1935 ==========================================================================
1936
1937 Routine Description:
1938 Disconnect current BSSID
1939
1940 Arguments:
1941 pAd - Pointer to our adapter
1942 IsReqFromAP - Request from AP
1943
1944 Return Value:
1945 None
1946
1947 IRQL = DISPATCH_LEVEL
1948
1949 Note:
1950 We need more information to know it's this requst from AP.
1951 If yes! we need to do extra handling, for example, remove the WPA key.
1952 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1953 remove while auto reconnect.
1954 Disconnect request from AP, it means we will start afresh 4-way handshaking
1955 on WPA mode.
1956
1957 ==========================================================================
1958*/
1959VOID LinkDown(
1960 IN PRTMP_ADAPTER pAd,
1961 IN BOOLEAN IsReqFromAP)
1962{
1963 UCHAR i, ByteValue = 0;
1964
1965 // Do nothing if monitor mode is on
1966 if (MONITOR_ON(pAd))
1967 return;
1968
1969#ifdef RALINK_ATE
1970 // Nothing to do in ATE mode.
1971 if (ATE_ON(pAd))
1972 return;
1973#endif // RALINK_ATE //
1974
1975 if (pAd->CommonCfg.bWirelessEvent)
1976 {
1977 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1978 }
1979
1980 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1981 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1982
1983#ifdef RT2860
1984 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1985 {
1986 BOOLEAN Cancelled;
1987 pAd->Mlme.bPsPollTimerRunning = FALSE;
1988 RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1989 }
1990
1991 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1992 {
1993 AUTO_WAKEUP_STRUC AutoWakeupCfg;
1994 AsicForceWakeup(pAd, TRUE);
1995 AutoWakeupCfg.word = 0;
1996 RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
1997 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1998 }
1999
2000 pAd->bPCIclkOff = FALSE;
2001#endif // RT2860 //
2002 if (ADHOC_ON(pAd)) // Adhoc mode link down
2003 {
2004 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
2005
2006 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
2007 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2008 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2009 RTMP_IndicateMediaState(pAd);
2010 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2011 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2012 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
2013 }
2014 else // Infra structure mode
2015 {
2016 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
2017
2018#ifdef QOS_DLS_SUPPORT
2019 // DLS tear down frame must be sent before link down
2020 // send DLS-TEAR_DOWN message
2021 if (pAd->CommonCfg.bDLSCapable)
2022 {
2023 // tear down local dls table entry
2024 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
2025 {
2026 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2027 {
2028 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2029 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2030 }
2031 }
2032
2033 // tear down peer dls table entry
2034 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
2035 {
2036 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2037 {
2038 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
2039 RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
2040 }
2041 }
2042 }
2043#endif // QOS_DLS_SUPPORT //
2044
2045 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
2046 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
2047
2048 // Saved last SSID for linkup comparison
2049 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
2050 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
2051 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
2052 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
2053 {
2054 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2055 RTMP_IndicateMediaState(pAd);
2056 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2057 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
2058 pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
2059 }
2060 else
2061 {
2062 //
2063 // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
2064 // Otherwise lost beacon or receive De-Authentication from AP,
2065 // then we should delete BSSID from BssTable.
2066 // If we don't delete from entry, roaming will fail.
2067 //
2068 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
2069 }
2070
2071 // restore back to -
2072 // 1. long slot (20 us) or short slot (9 us) time
2073 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
2074 // 3. short preamble
2075 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
2076
2077 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
2078 {
2079 //
2080 // Record current AP's information.
2081 // for later used reporting Adjacent AP report.
2082 //
2083 pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
2084 pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
2085 NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
2086 COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
2087 }
2088
2089#ifdef EXT_BUILD_CHANNEL_LIST
2090 // Country IE of the AP will be evaluated and will be used.
2091 if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
2092 {
2093 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
2094 pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
2095 BuildChannelListEx(pAd);
2096 }
2097#endif // EXT_BUILD_CHANNEL_LIST //
2098
2099 }
2100
2101 for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
2102 {
2103 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
2104 MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
2105 }
2106
2107 pAd->StaCfg.CCXQosECWMin = 4;
2108 pAd->StaCfg.CCXQosECWMax = 10;
2109
2110 AsicSetSlotTime(pAd, TRUE); //FALSE);
2111 AsicSetEdcaParm(pAd, NULL);
2112
2113 // Set LED
2114 RTMPSetLED(pAd, LED_LINK_DOWN);
2115 pAd->LedIndicatorStregth = 0xF0;
2116 RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
2117
2118 AsicDisableSync(pAd);
2119
2120 pAd->Mlme.PeriodicRound = 0;
2121 pAd->Mlme.OneSecPeriodicRound = 0;
2122
2123 if (pAd->StaCfg.BssType == BSS_INFRA)
2124 {
2125 // Remove StaCfg Information after link down
2126 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
2127 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
2128 pAd->CommonCfg.SsidLen = 0;
2129 }
2130#ifdef DOT11_N_SUPPORT
2131 NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
2132 NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
2133 pAd->MlmeAux.HtCapabilityLen = 0;
2134 pAd->MlmeAux.NewExtChannelOffset = 0xff;
2135#endif // DOT11_N_SUPPORT //
2136
2137 // Reset WPA-PSK state. Only reset when supplicant enabled
2138 if (pAd->StaCfg.WpaState != SS_NOTUSE)
2139 {
2140 pAd->StaCfg.WpaState = SS_START;
2141 // Clear Replay counter
2142 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
2143
2144#ifdef QOS_DLS_SUPPORT
2145 if (pAd->CommonCfg.bDLSCapable)
2146 NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
2147#endif // QOS_DLS_SUPPORT //
2148 }
2149
2150
2151 //
2152 // if link down come from AP, we need to remove all WPA keys on WPA mode.
2153 // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
2154 //
2155 if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
2156 {
2157 // Remove all WPA keys
2158 RTMPWPARemoveAllKeys(pAd);
2159 }
2160
2161 // 802.1x port control
2162#ifdef WPA_SUPPLICANT_SUPPORT
2163 // Prevent clear PortSecured here with static WEP
2164 // NetworkManger set security policy first then set SSID to connect AP.
2165 if (pAd->StaCfg.WpaSupplicantUP &&
2166 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
2167 (pAd->StaCfg.IEEE8021X == FALSE))
2168 {
2169 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
2170 }
2171 else
2172#endif // WPA_SUPPLICANT_SUPPORT //
2173 {
2174 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2175 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
2176 }
2177
2178 NdisAcquireSpinLock(&pAd->MacTabLock);
2179 pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
2180 NdisReleaseSpinLock(&pAd->MacTabLock);
2181
2182 pAd->StaCfg.MicErrCnt = 0;
2183
2184 // Turn off Ckip control flag
2185 pAd->StaCfg.bCkipOn = FALSE;
2186 pAd->StaCfg.CCXEnable = FALSE;
2187
2188 pAd->IndicateMediaState = NdisMediaStateDisconnected;
2189 // Update extra information to link is up
2190 pAd->ExtraInfo = GENERAL_LINK_DOWN;
2191
2192 pAd->StaCfg.AdhocBOnlyJoined = FALSE;
2193 pAd->StaCfg.AdhocBGJoined = FALSE;
2194 pAd->StaCfg.Adhoc20NJoined = FALSE;
2195 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2196
2197 // Reset the Current AP's IP address
2198 NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
2199
2200 // Clean association information
2201 NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
2202 pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
2203 pAd->StaCfg.ReqVarIELen = 0;
2204 pAd->StaCfg.ResVarIELen = 0;
2205
2206 //
2207 // Reset RSSI value after link down
2208 //
2209 pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2210 pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2211 pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2212 pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2213 pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2214 pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2215
2216 // Restore MlmeRate
2217 pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2218 pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2219
2220#ifdef DOT11_N_SUPPORT
2221 //
2222 // After Link down, reset piggy-back setting in ASIC. Disable RDG.
2223 //
2224 if (pAd->CommonCfg.BBPCurrentBW == BW_40)
2225 {
2226 pAd->CommonCfg.BBPCurrentBW = BW_20;
2227 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2228 ByteValue &= (~0x18);
2229 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2230 }
2231#endif // DOT11_N_SUPPORT //
2232 // Reset DAC
2233 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2234 ByteValue &= (~0x18);
2235 if (pAd->Antenna.field.TxPath == 2)
2236 {
2237 ByteValue |= 0x10;
2238 }
2239 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2240
2241 RTMPSetPiggyBack(pAd,FALSE);
2242 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2243
2244#ifdef DOT11_N_SUPPORT
2245 pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2246#endif // DOT11_N_SUPPORT //
2247
2248 // Restore all settings in the following.
2249 AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2250 AsicDisableRDG(pAd);
2251 pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2252 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2253
2254#ifdef DOT11_N_SUPPORT
2255#ifdef DOT11N_DRAFT3
2256 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
2257 pAd->CommonCfg.BSSCoexist2040.word = 0;
2258 TriEventInit(pAd);
2259 for (i = 0; i < (pAd->ChannelListNum - 1); i++)
2260 {
2261 pAd->ChannelList[i].bEffectedChannel = FALSE;
2262 }
2263#endif // DOT11N_DRAFT3 //
2264#endif // DOT11_N_SUPPORT //
2265
2266 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2267 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2268
2269#ifdef WPA_SUPPLICANT_SUPPORT
2270#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2271 if (pAd->StaCfg.WpaSupplicantUP) {
2272 union iwreq_data wrqu;
2273 //send disassociate event to wpa_supplicant
2274 memset(&wrqu, 0, sizeof(wrqu));
2275 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2276 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2277 }
2278#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2279#endif // WPA_SUPPLICANT_SUPPORT //
2280
2281#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2282 {
2283 union iwreq_data wrqu;
2284 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2285 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2286 }
2287#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2288}
2289
2290/*
2291 ==========================================================================
2292 Description:
2293
2294 IRQL = DISPATCH_LEVEL
2295
2296 ==========================================================================
2297*/
2298VOID IterateOnBssTab(
2299 IN PRTMP_ADAPTER pAd)
2300{
2301 MLME_START_REQ_STRUCT StartReq;
2302 MLME_JOIN_REQ_STRUCT JoinReq;
2303 ULONG BssIdx;
2304
2305 // Change the wepstatus to original wepstatus
2306 pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
2307 pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
2308 pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2309
2310 BssIdx = pAd->MlmeAux.BssIdx;
2311 if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2312 {
2313 // Check cipher suite, AP must have more secured cipher than station setting
2314 // Set the Pairwise and Group cipher to match the intended AP setting
2315 // We can only connect to AP with less secured cipher setting
2316 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2317 {
2318 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2319
2320 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2321 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2322 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2323 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2324 else // There is no PairCipher Aux, downgrade our capability to TKIP
2325 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2326 }
2327 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2328 {
2329 pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2330
2331 if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2332 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2333 else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2334 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2335 else // There is no PairCipher Aux, downgrade our capability to TKIP
2336 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2337
2338 // RSN capability
2339 pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2340 }
2341
2342 // Set Mix cipher flag
2343 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2344 if (pAd->StaCfg.bMixCipher == TRUE)
2345 {
2346 // If mix cipher, re-build RSNIE
2347 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2348 }
2349
2350 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2351 JoinParmFill(pAd, &JoinReq, BssIdx);
2352 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2353 &JoinReq);
2354 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2355 }
2356 else if (pAd->StaCfg.BssType == BSS_ADHOC)
2357 {
2358 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2359 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2360 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2361 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2362 }
2363 else // no more BSS
2364 {
2365 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2366 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2367 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2368 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2369 }
2370}
2371
2372// for re-association only
2373// IRQL = DISPATCH_LEVEL
2374VOID IterateOnBssTab2(
2375 IN PRTMP_ADAPTER pAd)
2376{
2377 MLME_REASSOC_REQ_STRUCT ReassocReq;
2378 ULONG BssIdx;
2379 BSS_ENTRY *pBss;
2380
2381 BssIdx = pAd->MlmeAux.RoamIdx;
2382 pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2383
2384 if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2385 {
2386 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2387
2388 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2389 AsicLockChannel(pAd, pBss->Channel);
2390
2391 // reassociate message has the same structure as associate message
2392 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2393 ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2394 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2395 sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2396
2397 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2398 }
2399 else // no more BSS
2400 {
2401 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2402 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2403 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2404 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2405 }
2406}
2407
2408/*
2409 ==========================================================================
2410 Description:
2411
2412 IRQL = DISPATCH_LEVEL
2413
2414 ==========================================================================
2415*/
2416VOID JoinParmFill(
2417 IN PRTMP_ADAPTER pAd,
2418 IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2419 IN ULONG BssIdx)
2420{
2421 JoinReq->BssIdx = BssIdx;
2422}
2423
2424/*
2425 ==========================================================================
2426 Description:
2427
2428 IRQL = DISPATCH_LEVEL
2429
2430 ==========================================================================
2431*/
2432VOID ScanParmFill(
2433 IN PRTMP_ADAPTER pAd,
2434 IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2435 IN CHAR Ssid[],
2436 IN UCHAR SsidLen,
2437 IN UCHAR BssType,
2438 IN UCHAR ScanType)
2439{
2440 NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2441 ScanReq->SsidLen = SsidLen;
2442 NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2443 ScanReq->BssType = BssType;
2444 ScanReq->ScanType = ScanType;
2445}
2446
2447#ifdef QOS_DLS_SUPPORT
2448/*
2449 ==========================================================================
2450 Description:
2451
2452 IRQL = DISPATCH_LEVEL
2453
2454 ==========================================================================
2455*/
2456VOID DlsParmFill(
2457 IN PRTMP_ADAPTER pAd,
2458 IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
2459 IN PRT_802_11_DLS pDls,
2460 IN USHORT reason)
2461{
2462 pDlsReq->pDLS = pDls;
2463 pDlsReq->Reason = reason;
2464}
2465#endif // QOS_DLS_SUPPORT //
2466
2467/*
2468 ==========================================================================
2469 Description:
2470
2471 IRQL = DISPATCH_LEVEL
2472
2473 ==========================================================================
2474*/
2475VOID StartParmFill(
2476 IN PRTMP_ADAPTER pAd,
2477 IN OUT MLME_START_REQ_STRUCT *StartReq,
2478 IN CHAR Ssid[],
2479 IN UCHAR SsidLen)
2480{
2481 ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2482 NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2483 StartReq->SsidLen = SsidLen;
2484}
2485
2486/*
2487 ==========================================================================
2488 Description:
2489
2490 IRQL = DISPATCH_LEVEL
2491
2492 ==========================================================================
2493*/
2494VOID AuthParmFill(
2495 IN PRTMP_ADAPTER pAd,
2496 IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2497 IN PUCHAR pAddr,
2498 IN USHORT Alg)
2499{
2500 COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2501 AuthReq->Alg = Alg;
2502 AuthReq->Timeout = AUTH_TIMEOUT;
2503}
2504
2505/*
2506 ==========================================================================
2507 Description:
2508
2509 IRQL = DISPATCH_LEVEL
2510
2511 ==========================================================================
2512 */
2513#ifdef RT2860
2514VOID ComposePsPoll(
2515 IN PRTMP_ADAPTER pAd)
2516{
2517 NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2518 pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2519 pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2520 pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2521 COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2522 COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2523}
2524
2525// IRQL = DISPATCH_LEVEL
2526VOID ComposeNullFrame(
2527 IN PRTMP_ADAPTER pAd)
2528{
2529 NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2530 pAd->NullFrame.FC.Type = BTYPE_DATA;
2531 pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2532 pAd->NullFrame.FC.ToDs = 1;
2533 COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2534 COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2535 COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2536}
2537#endif // RT2860 //
2538
2539
2540
2541
2542/*
2543 ==========================================================================
2544 Description:
2545 Pre-build a BEACON frame in the shared memory
2546
2547 IRQL = PASSIVE_LEVEL
2548 IRQL = DISPATCH_LEVEL
2549
2550 ==========================================================================
2551*/
2552ULONG MakeIbssBeacon(
2553 IN PRTMP_ADAPTER pAd)
2554{
2555 UCHAR DsLen = 1, IbssLen = 2;
2556 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
2557 HEADER_802_11 BcnHdr;
2558 USHORT CapabilityInfo;
2559 LARGE_INTEGER FakeTimestamp;
2560 ULONG FrameLen = 0;
2561 PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
2562 CHAR *pBeaconFrame = pAd->BeaconBuf;
2563 BOOLEAN Privacy;
2564 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2565 UCHAR SupRateLen = 0;
2566 UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2567 UCHAR ExtRateLen = 0;
2568 UCHAR RSNIe = IE_WPA;
2569
2570 if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2571 {
2572 SupRate[0] = 0x82; // 1 mbps
2573 SupRate[1] = 0x84; // 2 mbps
2574 SupRate[2] = 0x8b; // 5.5 mbps
2575 SupRate[3] = 0x96; // 11 mbps
2576 SupRateLen = 4;
2577 ExtRateLen = 0;
2578 }
2579 else if (pAd->CommonCfg.Channel > 14)
2580 {
2581 SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
2582 SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2583 SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
2584 SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2585 SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
2586 SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2587 SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2588 SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2589 SupRateLen = 8;
2590 ExtRateLen = 0;
2591
2592 //
2593 // Also Update MlmeRate & RtsRate for G only & A only
2594 //
2595 pAd->CommonCfg.MlmeRate = RATE_6;
2596 pAd->CommonCfg.RtsRate = RATE_6;
2597 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2598 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2599 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2600 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2601 }
2602 else
2603 {
2604 SupRate[0] = 0x82; // 1 mbps
2605 SupRate[1] = 0x84; // 2 mbps
2606 SupRate[2] = 0x8b; // 5.5 mbps
2607 SupRate[3] = 0x96; // 11 mbps
2608 SupRateLen = 4;
2609
2610 ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
2611 ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
2612 ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
2613 ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
2614 ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
2615 ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
2616 ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
2617 ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
2618 ExtRateLen = 8;
2619 }
2620
2621 pAd->StaActive.SupRateLen = SupRateLen;
2622 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2623 pAd->StaActive.ExtRateLen = ExtRateLen;
2624 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2625
2626 // compose IBSS beacon frame
2627 MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2628 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2629 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2630 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2631 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2632
2633 MakeOutgoingFrame(pBeaconFrame, &FrameLen,
2634 sizeof(HEADER_802_11), &BcnHdr,
2635 TIMESTAMP_LEN, &FakeTimestamp,
2636 2, &pAd->CommonCfg.BeaconPeriod,
2637 2, &CapabilityInfo,
2638 1, &SsidIe,
2639 1, &pAd->CommonCfg.SsidLen,
2640 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
2641 1, &SupRateIe,
2642 1, &SupRateLen,
2643 SupRateLen, SupRate,
2644 1, &DsIe,
2645 1, &DsLen,
2646 1, &pAd->CommonCfg.Channel,
2647 1, &IbssIe,
2648 1, &IbssLen,
2649 2, &pAd->StaActive.AtimWin,
2650 END_OF_ARGS);
2651
2652 // add ERP_IE and EXT_RAE IE of in 802.11g
2653 if (ExtRateLen)
2654 {
2655 ULONG tmp;
2656
2657 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2658 3, LocalErpIe,
2659 1, &ExtRateIe,
2660 1, &ExtRateLen,
2661 ExtRateLen, ExtRate,
2662 END_OF_ARGS);
2663 FrameLen += tmp;
2664 }
2665
2666 // If adhoc secruity is set for WPA-None, append the cipher suite IE
2667 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2668 {
2669 ULONG tmp;
2670 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2671
2672 MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
2673 1, &RSNIe,
2674 1, &pAd->StaCfg.RSNIE_Len,
2675 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
2676 END_OF_ARGS);
2677 FrameLen += tmp;
2678 }
2679
2680#ifdef DOT11_N_SUPPORT
2681 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2682 {
2683 ULONG TmpLen;
2684 UCHAR HtLen, HtLen1;
2685
2686#ifdef RT_BIG_ENDIAN
2687 HT_CAPABILITY_IE HtCapabilityTmp;
2688 ADD_HT_INFO_IE addHTInfoTmp;
2689 USHORT b2lTmp, b2lTmp2;
2690#endif
2691
2692 // add HT Capability IE
2693 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2694 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2695#ifndef RT_BIG_ENDIAN
2696 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2697 1, &HtCapIe,
2698 1, &HtLen,
2699 HtLen, &pAd->CommonCfg.HtCapability,
2700 1, &AddHtInfoIe,
2701 1, &HtLen1,
2702 HtLen1, &pAd->CommonCfg.AddHTInfo,
2703 END_OF_ARGS);
2704#else
2705 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2706 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2707 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2708
2709 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2710 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2711 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2712
2713 MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
2714 1, &HtCapIe,
2715 1, &HtLen,
2716 HtLen, &HtCapabilityTmp,
2717 1, &AddHtInfoIe,
2718 1, &HtLen1,
2719 HtLen1, &addHTInfoTmp,
2720 END_OF_ARGS);
2721#endif
2722 FrameLen += TmpLen;
2723 }
2724#endif // DOT11_N_SUPPORT //
2725
2726 //beacon use reserved WCID 0xff
2727 if (pAd->CommonCfg.Channel > 14)
2728 {
2729 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2730 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2731 }
2732 else
2733 {
2734 // Set to use 1Mbps for Adhoc beacon.
2735 HTTRANSMIT_SETTING Transmit;
2736 Transmit.word = 0;
2737 RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2738 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2739 }
2740
2741#ifdef RT_BIG_ENDIAN
2742 RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2743 RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2744#endif
2745
2746 DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2747 FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));
2748 return FrameLen;
2749}
2750
2751
diff --git a/drivers/staging/rt2860/sta/dls.c b/drivers/staging/rt2860/sta/dls.c
new file mode 100644
index 00000000000..78fb28976fd
--- /dev/null
+++ b/drivers/staging/rt2860/sta/dls.c
@@ -0,0 +1,2201 @@
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 RT2860
1423 AsicAddPairwiseKeyEntry(pAd,
1424 pAd->StaCfg.DLSEntry[i].MacAddr,
1425 (UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
1426 &PairwiseKey);
1427
1428 RTMPAddWcidAttributeEntry(pAd,
1429 BSS0,
1430 0,
1431 PairwiseKey.CipherAlg,
1432 pEntry);
1433
1434#endif // RT2860 //
1435 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1436 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
1437
1438 RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
1439
1440 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
1441 }
1442 else
1443 {
1444 // Data frame, update timeout value
1445 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1446 {
1447 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1448 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1449 }
1450 }
1451
1452 bFindEntry = TRUE;
1453 }
1454 }
1455
1456 // update peer dls table entry
1457 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1458 {
1459 if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
1460 {
1461 if (bSTAKeyFrame)
1462 {
1463 PMAC_TABLE_ENTRY pEntry = NULL;
1464
1465 // STAKey frame, add pairwise key table, and send STAkey Msg-2
1466 pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
1467 RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
1468
1469 PairwiseKey.KeyLen = LEN_TKIP_EK;
1470 NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
1471 NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
1472 NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
1473
1474 PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
1475
1476 pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
1477 //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
1478 //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
1479 // Add Pair-wise key to Asic
1480#ifdef RT2860
1481 AsicAddPairwiseKeyEntry(pAd,
1482 pAd->StaCfg.DLSEntry[i].MacAddr,
1483 (UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
1484 &PairwiseKey);
1485
1486 RTMPAddWcidAttributeEntry(pAd,
1487 BSS0,
1488 0,
1489 PairwiseKey.CipherAlg,
1490 pEntry);
1491#endif // RT2860 //
1492 NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
1493 DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
1494
1495 // If support WPA or WPA2, start STAKey hand shake,
1496 // If failed hand shake, just tear down peer DLS
1497 if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS)
1498 {
1499 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1500 USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
1501
1502 pAd->StaCfg.DLSEntry[i].Valid = FALSE;
1503 pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
1504 DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
1505 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1506 }
1507 else
1508 {
1509 DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
1510 }
1511 }
1512 else
1513 {
1514 // Data frame, update timeout value
1515 if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1516 {
1517 pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
1518 }
1519 }
1520
1521 bFindEntry = TRUE;
1522 }
1523 }
1524
1525
1526 return bSTAKeyFrame;
1527}
1528
1529/*
1530 ========================================================================
1531
1532 Routine Description:
1533 Check if the frame can be sent through DLS direct link interface
1534
1535 Arguments:
1536 pAd Pointer to adapter
1537
1538 Return Value:
1539 DLS entry index
1540
1541 Note:
1542
1543 ========================================================================
1544*/
1545INT RTMPCheckDLSFrame(
1546 IN PRTMP_ADAPTER pAd,
1547 IN PUCHAR pDA)
1548{
1549 INT rval = -1;
1550 INT i;
1551
1552 if (!pAd->CommonCfg.bDLSCapable)
1553 return rval;
1554
1555 if (!INFRA_ON(pAd))
1556 return rval;
1557
1558 do{
1559 // check local dls table entry
1560 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1561 {
1562 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1563 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1564 {
1565 rval = i;
1566 break;
1567 }
1568 }
1569
1570 // check peer dls table entry
1571 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1572 {
1573 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
1574 MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1575 {
1576 rval = i;
1577 break;
1578 }
1579 }
1580 } while (FALSE);
1581
1582 return rval;
1583}
1584
1585/*
1586 ==========================================================================
1587 Description:
1588
1589 IRQL = DISPATCH_LEVEL
1590
1591 ==========================================================================
1592 */
1593VOID RTMPSendDLSTearDownFrame(
1594 IN PRTMP_ADAPTER pAd,
1595 IN PUCHAR pDA)
1596{
1597 PUCHAR pOutBuffer = NULL;
1598 NDIS_STATUS NStatus;
1599 HEADER_802_11 DlsTearDownHdr;
1600 ULONG FrameLen = 0;
1601 USHORT Reason = REASON_QOS_QSTA_LEAVING_QBSS;
1602 UCHAR Category = CATEGORY_DLS;
1603 UCHAR Action = ACTION_DLS_TEARDOWN;
1604 UCHAR i = 0;
1605
1606 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
1607 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
1608 return;
1609
1610 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
1611
1612 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1613 if (NStatus != NDIS_STATUS_SUCCESS)
1614 {
1615 DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
1616 return;
1617 }
1618
1619 ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
1620 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1621 sizeof(HEADER_802_11), &DlsTearDownHdr,
1622 1, &Category,
1623 1, &Action,
1624 6, pDA,
1625 6, pAd->CurrentAddress,
1626 2, &Reason,
1627 END_OF_ARGS);
1628
1629 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1630 MlmeFreeMemory(pAd, pOutBuffer);
1631
1632 // Remove key in local dls table entry
1633 for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
1634 {
1635 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1636 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1637 {
1638 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1639 }
1640 }
1641
1642 // Remove key in peer dls table entry
1643 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
1644 {
1645 if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
1646 && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
1647 {
1648 MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
1649 }
1650 }
1651
1652 DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
1653}
1654
1655/*
1656 ==========================================================================
1657 Description:
1658
1659 IRQL = DISPATCH_LEVEL
1660
1661 ==========================================================================
1662 */
1663NDIS_STATUS RTMPSendSTAKeyRequest(
1664 IN PRTMP_ADAPTER pAd,
1665 IN PUCHAR pDA)
1666{
1667 UCHAR Header802_3[14];
1668 NDIS_STATUS NStatus;
1669 ULONG FrameLen = 0;
1670 EAPOL_PACKET Packet;
1671 UCHAR Mic[16];
1672 UCHAR digest[80];
1673 PUCHAR pOutBuffer = NULL;
1674 PNDIS_PACKET pNdisPacket;
1675 UCHAR temp[64];
1676 UCHAR DlsPTK[80];
1677
1678 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]));
1679
1680 pAd->Sequence ++;
1681 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1682
1683 // Zero message body
1684 NdisZeroMemory(&Packet, sizeof(Packet));
1685 Packet.ProVer = EAPOL_VER;
1686 Packet.ProType = EAPOLKey;
1687 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE andPeer MAC address
1688
1689 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1690 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1691 {
1692 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1693 }
1694 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1695 {
1696 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1697 }
1698
1699 // Key descriptor version
1700 Packet.KeyDesc.KeyInfo.KeyDescVer =
1701 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1702
1703 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1704 Packet.KeyDesc.KeyInfo.Secure = 1;
1705 Packet.KeyDesc.KeyInfo.Request = 1;
1706
1707 Packet.KeyDesc.KeyDataLen[1] = 12;
1708
1709 // use our own OUI to distinguish proprietary with standard.
1710 Packet.KeyDesc.KeyData[0] = 0xDD;
1711 Packet.KeyDesc.KeyData[1] = 0x0A;
1712 Packet.KeyDesc.KeyData[2] = 0x00;
1713 Packet.KeyDesc.KeyData[3] = 0x0C;
1714 Packet.KeyDesc.KeyData[4] = 0x43;
1715 Packet.KeyDesc.KeyData[5] = 0x03;
1716 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1717
1718 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1719
1720 // Allocate buffer for transmitting message
1721 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1722 if (NStatus != NDIS_STATUS_SUCCESS)
1723 return NStatus;
1724
1725 // Prepare EAPOL frame for MIC calculation
1726 // Be careful, only EAPOL frame is counted for MIC calculation
1727 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1728 Packet.Body_Len[1] + 4, &Packet,
1729 END_OF_ARGS);
1730
1731 // use proprietary PTK
1732 NdisZeroMemory(temp, 64);
1733 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1734 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1735
1736 // calculate MIC
1737 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1738 {
1739 // AES
1740 NdisZeroMemory(digest, sizeof(digest));
1741 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1742 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1743 }
1744 else
1745 {
1746 NdisZeroMemory(Mic, sizeof(Mic));
1747 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1748 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1749 }
1750
1751 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1752 sizeof(Header802_3), Header802_3,
1753 Packet.Body_Len[1] + 4, &Packet,
1754 END_OF_ARGS);
1755
1756 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1757 if (NStatus == NDIS_STATUS_SUCCESS)
1758 {
1759 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1760 STASendPacket(pAd, pNdisPacket);
1761 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1762 }
1763
1764 MlmeFreeMemory(pAd, pOutBuffer);
1765
1766 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1767
1768 return NStatus;
1769}
1770
1771/*
1772 ==========================================================================
1773 Description:
1774
1775 IRQL = DISPATCH_LEVEL
1776
1777 ==========================================================================
1778 */
1779NDIS_STATUS RTMPSendSTAKeyHandShake(
1780 IN PRTMP_ADAPTER pAd,
1781 IN PUCHAR pDA)
1782{
1783 UCHAR Header802_3[14];
1784 NDIS_STATUS NStatus;
1785 ULONG FrameLen = 0;
1786 EAPOL_PACKET Packet;
1787 UCHAR Mic[16];
1788 UCHAR digest[80];
1789 PUCHAR pOutBuffer = NULL;
1790 PNDIS_PACKET pNdisPacket;
1791 UCHAR temp[64];
1792 UCHAR DlsPTK[80]; // Due to dirver can not get PTK, use proprietary PTK
1793
1794 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]));
1795
1796 pAd->Sequence ++;
1797 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1798
1799 // Zero message body
1800 NdisZeroMemory(&Packet, sizeof(Packet));
1801 Packet.ProVer = EAPOL_VER;
1802 Packet.ProType = EAPOLKey;
1803 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE and Peer MAC address
1804
1805 // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
1806 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
1807 {
1808 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1809 }
1810 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1811 {
1812 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1813 }
1814
1815 // Key descriptor version
1816 Packet.KeyDesc.KeyInfo.KeyDescVer =
1817 (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
1818
1819 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1820 Packet.KeyDesc.KeyInfo.Secure = 1;
1821
1822 Packet.KeyDesc.KeyDataLen[1] = 12;
1823
1824 // use our own OUI to distinguish proprietary with standard.
1825 Packet.KeyDesc.KeyData[0] = 0xDD;
1826 Packet.KeyDesc.KeyData[1] = 0x0A;
1827 Packet.KeyDesc.KeyData[2] = 0x00;
1828 Packet.KeyDesc.KeyData[3] = 0x0C;
1829 Packet.KeyDesc.KeyData[4] = 0x43;
1830 Packet.KeyDesc.KeyData[5] = 0x03;
1831 NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
1832
1833 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
1834
1835 // Allocate buffer for transmitting message
1836 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
1837 if (NStatus != NDIS_STATUS_SUCCESS)
1838 return NStatus;
1839
1840 // Prepare EAPOL frame for MIC calculation
1841 // Be careful, only EAPOL frame is counted for MIC calculation
1842 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1843 Packet.Body_Len[1] + 4, &Packet,
1844 END_OF_ARGS);
1845
1846 // use proprietary PTK
1847 NdisZeroMemory(temp, 64);
1848 NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
1849 WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
1850
1851 // calculate MIC
1852 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1853 {
1854 // AES
1855 NdisZeroMemory(digest, sizeof(digest));
1856 HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
1857 NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
1858 }
1859 else
1860 {
1861 NdisZeroMemory(Mic, sizeof(Mic));
1862 hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1863 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1864 }
1865
1866 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1867 sizeof(Header802_3), Header802_3,
1868 Packet.Body_Len[1] + 4, &Packet,
1869 END_OF_ARGS);
1870
1871 NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
1872 if (NStatus == NDIS_STATUS_SUCCESS)
1873 {
1874 RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
1875 STASendPacket(pAd, pNdisPacket);
1876 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
1877 }
1878
1879 MlmeFreeMemory(pAd, pOutBuffer);
1880
1881 DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
1882
1883 return NStatus;
1884}
1885
1886VOID DlsTimeoutAction(
1887 IN PVOID SystemSpecific1,
1888 IN PVOID FunctionContext,
1889 IN PVOID SystemSpecific2,
1890 IN PVOID SystemSpecific3)
1891{
1892 MLME_DLS_REQ_STRUCT MlmeDlsReq;
1893 USHORT reason;
1894 PRT_802_11_DLS pDLS = (PRT_802_11_DLS)FunctionContext;
1895 PRTMP_ADAPTER pAd = pDLS->pAd;
1896
1897 DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
1898 pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5]));
1899
1900 if ((pDLS) && (pDLS->Valid))
1901 {
1902 reason = REASON_QOS_REQUEST_TIMEOUT;
1903 pDLS->Valid = FALSE;
1904 pDLS->Status = DLS_NONE;
1905 DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason);
1906 MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
1907 RT28XX_MLME_HANDLER(pAd);
1908 }
1909}
1910
1911/*
1912================================================================
1913Description : because DLS and CLI share the same WCID table in ASIC.
1914Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE.
1915Also fills the pairwise key.
1916Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
1917from index MAX_AID_BA.
1918================================================================
1919*/
1920MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
1921 IN PRTMP_ADAPTER pAd,
1922 IN PUCHAR pAddr,
1923 IN UINT DlsEntryIdx)
1924{
1925 PMAC_TABLE_ENTRY pEntry = NULL;
1926
1927 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
1928 // if FULL, return
1929 if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
1930 return NULL;
1931
1932 do
1933 {
1934 if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
1935 break;
1936
1937 // allocate one MAC entry
1938 pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
1939 if (pEntry)
1940 {
1941 pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid;
1942 pEntry->MatchDlsEntryIdx = DlsEntryIdx;
1943 pEntry->AuthMode = pAd->StaCfg.AuthMode;
1944 pEntry->WepStatus = pAd->StaCfg.WepStatus;
1945 pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
1946
1947 DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
1948
1949 // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
1950 if ((pEntry->ValidAsDls) && (pEntry->WepStatus == Ndis802_11WEPEnabled))
1951 {
1952 UCHAR KeyIdx = 0;
1953 UCHAR CipherAlg = 0;
1954
1955 KeyIdx = pAd->StaCfg.DefaultKeyId;
1956
1957 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1958
1959 RTMPAddWcidAttributeEntry(pAd,
1960 BSS0,
1961 pAd->StaCfg.DefaultKeyId,
1962 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1963 pEntry);
1964 }
1965
1966 break;
1967 }
1968 } while(FALSE);
1969
1970 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
1971
1972 return pEntry;
1973}
1974
1975
1976/*
1977 ==========================================================================
1978 Description:
1979 Delete all Mesh Entry in pAd->MacTab
1980 ==========================================================================
1981 */
1982BOOLEAN MacTableDeleteDlsEntry(
1983 IN PRTMP_ADAPTER pAd,
1984 IN USHORT wcid,
1985 IN PUCHAR pAddr)
1986{
1987 DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
1988
1989 if (!VALID_WCID(wcid))
1990 return FALSE;
1991
1992 MacTableDeleteEntry(pAd, wcid, pAddr);
1993
1994 DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
1995
1996 return TRUE;
1997}
1998
1999MAC_TABLE_ENTRY *DlsEntryTableLookup(
2000 IN PRTMP_ADAPTER pAd,
2001 IN PUCHAR pAddr,
2002 IN BOOLEAN bResetIdelCount)
2003{
2004 ULONG HashIdx;
2005 MAC_TABLE_ENTRY *pEntry = NULL;
2006
2007 RTMP_SEM_LOCK(&pAd->MacTabLock);
2008 HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
2009 pEntry = pAd->MacTab.Hash[HashIdx];
2010
2011 while (pEntry)
2012 {
2013 if ((pEntry->ValidAsDls == TRUE)
2014 && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
2015 {
2016 if(bResetIdelCount)
2017 pEntry->NoDataIdleCount = 0;
2018 break;
2019 }
2020 else
2021 pEntry = pEntry->pNext;
2022 }
2023
2024 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2025 return pEntry;
2026}
2027
2028MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
2029 IN PRTMP_ADAPTER pAd,
2030 IN UCHAR wcid,
2031 IN PUCHAR pAddr,
2032 IN BOOLEAN bResetIdelCount)
2033{
2034 ULONG DLsIndex;
2035 PMAC_TABLE_ENTRY pCurEntry = NULL;
2036 PMAC_TABLE_ENTRY pEntry = NULL;
2037
2038 if (!VALID_WCID(wcid))
2039 return NULL;
2040
2041 RTMP_SEM_LOCK(&pAd->MacTabLock);
2042
2043 do
2044 {
2045 pCurEntry = &pAd->MacTab.Content[wcid];
2046
2047 DLsIndex = 0xff;
2048 if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
2049 {
2050 DLsIndex = pCurEntry->MatchDlsEntryIdx;
2051 }
2052
2053 if (DLsIndex == 0xff)
2054 break;
2055
2056 if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
2057 {
2058 if(bResetIdelCount)
2059 pCurEntry->NoDataIdleCount = 0;
2060 pEntry = pCurEntry;
2061 break;
2062 }
2063 } while(FALSE);
2064
2065 RTMP_SEM_UNLOCK(&pAd->MacTabLock);
2066
2067 return pEntry;
2068}
2069
2070INT Set_DlsEntryInfo_Display_Proc(
2071 IN PRTMP_ADAPTER pAd,
2072 IN PUCHAR arg)
2073{
2074 INT i;
2075
2076 printk("\n%-19s%-8s\n", "MAC", "TIMEOUT\n");
2077 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
2078 {
2079 if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
2080 {
2081 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[pAd->StaCfg.DLSEntry[i].MacTabMatchWCID];
2082
2083 printk("%02x:%02x:%02x:%02x:%02x:%02x ",
2084 pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2],
2085 pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5]);
2086 printk("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut);
2087
2088 printk("\n");
2089 printk("\n%-19s%-4s%-4s%-4s%-4s%-8s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n",
2090 "MAC", "AID", "BSS", "PSM", "WMM", "MIMOPS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC");
2091 printk("%02X:%02X:%02X:%02X:%02X:%02X ",
2092 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2093 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
2094 printk("%-4d", (int)pEntry->Aid);
2095 printk("%-4d", (int)pEntry->apidx);
2096 printk("%-4d", (int)pEntry->PsMode);
2097 printk("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE));
2098 printk("%-8d", (int)pEntry->MmpsMode);
2099 printk("%-7d", pEntry->RssiSample.AvgRssi0);
2100 printk("%-7d", pEntry->RssiSample.AvgRssi1);
2101 printk("%-7d", pEntry->RssiSample.AvgRssi2);
2102 printk("%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE));
2103 printk("%-6s", GetBW(pEntry->HTPhyMode.field.BW));
2104 printk("%-6d", pEntry->HTPhyMode.field.MCS);
2105 printk("%-6d", pEntry->HTPhyMode.field.ShortGI);
2106 printk("%-6d", pEntry->HTPhyMode.field.STBC);
2107 printk("%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount,
2108 (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0);
2109 printk("\n");
2110
2111 }
2112 }
2113
2114 return TRUE;
2115}
2116
2117INT Set_DlsAddEntry_Proc(
2118 IN PRTMP_ADAPTER pAd,
2119 IN PUCHAR arg)
2120{
2121 UCHAR mac[MAC_ADDR_LEN];
2122 USHORT Timeout;
2123 char *token, sepValue[] = ":", DASH = '-';
2124 INT i;
2125 RT_802_11_DLS Dls;
2126
2127 if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
2128 return FALSE;
2129
2130 token = strchr(arg, DASH);
2131 if ((token != NULL) && (strlen(token)>1))
2132 {
2133 Timeout = simple_strtol((token+1), 0, 10);
2134
2135 *token = '\0';
2136 for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
2137 {
2138 if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
2139 return FALSE;
2140 AtoH(token, (PUCHAR)(&mac[i]), 1);
2141 }
2142 if(i != 6)
2143 return FALSE;
2144
2145 printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1],
2146 mac[2], mac[3], mac[4], mac[5], (int)Timeout);
2147
2148 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2149 Dls.TimeOut = Timeout;
2150 COPY_MAC_ADDR(Dls.MacAddr, mac);
2151 Dls.Valid = 1;
2152
2153 MlmeEnqueue(pAd,
2154 MLME_CNTL_STATE_MACHINE,
2155 RT_OID_802_11_SET_DLS_PARAM,
2156 sizeof(RT_802_11_DLS),
2157 &Dls);
2158
2159 return TRUE;
2160 }
2161
2162 return FALSE;
2163
2164}
2165
2166INT Set_DlsTearDownEntry_Proc(
2167 IN PRTMP_ADAPTER pAd,
2168 IN PUCHAR arg)
2169{
2170 UCHAR macAddr[MAC_ADDR_LEN];
2171 CHAR *value;
2172 INT i;
2173 RT_802_11_DLS Dls;
2174
2175 if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
2176 return FALSE;
2177
2178 for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
2179 {
2180 if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
2181 return FALSE; //Invalid
2182
2183 AtoH(value, &macAddr[i++], 2);
2184 }
2185
2186 printk("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1],
2187 macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
2188
2189 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
2190 COPY_MAC_ADDR(Dls.MacAddr, macAddr);
2191 Dls.Valid = 0;
2192
2193 MlmeEnqueue(pAd,
2194 MLME_CNTL_STATE_MACHINE,
2195 RT_OID_802_11_SET_DLS_PARAM,
2196 sizeof(RT_802_11_DLS),
2197 &Dls);
2198
2199 return TRUE;
2200}
2201
diff --git a/drivers/staging/rt2860/sta/rtmp_data.c b/drivers/staging/rt2860/sta/rtmp_data.c
new file mode 100644
index 00000000000..36aff247cd9
--- /dev/null
+++ b/drivers/staging/rt2860/sta/rtmp_data.c
@@ -0,0 +1,2614 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_data.c
29
30 Abstract:
31 Data path subroutines
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 John Aug/17/04 major modification for RT2561/2661
37 Jan Lee Mar/17/06 major modification for RT2860 New Ring Design
38*/
39#include "../rt_config.h"
40
41
42
43VOID STARxEAPOLFrameIndicate(
44 IN PRTMP_ADAPTER pAd,
45 IN MAC_TABLE_ENTRY *pEntry,
46 IN RX_BLK *pRxBlk,
47 IN UCHAR FromWhichBSSID)
48{
49 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
50 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
51 UCHAR *pTmpBuf;
52
53#ifdef WPA_SUPPLICANT_SUPPORT
54 if (pAd->StaCfg.WpaSupplicantUP)
55 {
56 // All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon)
57 // TBD : process fragmented EAPol frames
58 {
59 // In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable
60 if ( pAd->StaCfg.IEEE8021X == TRUE &&
61 (EAP_CODE_SUCCESS == WpaCheckEapCode(pAd, pRxBlk->pData, pRxBlk->DataSize, LENGTH_802_1_H)))
62 {
63 PUCHAR Key;
64 UCHAR CipherAlg;
65 int idx = 0;
66
67 DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n"));
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 RT2860
79 MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID];
80
81 // Set key material and cipherAlg to Asic
82 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
83
84 // Assign group key info
85 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
86
87 // Assign pairwise key info
88 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
89
90 pAd->IndicateMediaState = NdisMediaStateConnected;
91 pAd->ExtraInfo = GENERAL_LINK_UP;
92#endif // RT2860 //
93 // For Preventing ShardKey Table is cleared by remove key procedure.
94 pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
95 pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
96 NdisMoveMemory(pAd->SharedKey[BSS0][idx].Key,
97 pAd->StaCfg.DesireSharedKey[idx].Key,
98 pAd->StaCfg.DesireSharedKey[idx].KeyLen);
99 }
100 }
101 }
102
103 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
104 return;
105 }
106 }
107 else
108#endif // WPA_SUPPLICANT_SUPPORT //
109 {
110 // Special DATA frame that has to pass to MLME
111 // 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process
112 // 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process
113 {
114 pTmpBuf = pRxBlk->pData - LENGTH_802_11;
115 NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
116 REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
117 DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! report EAPOL/AIRONET DATA to MLME (len=%d) !!!\n", pRxBlk->DataSize));
118 }
119 }
120
121 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
122 return;
123
124}
125
126VOID STARxDataFrameAnnounce(
127 IN PRTMP_ADAPTER pAd,
128 IN MAC_TABLE_ENTRY *pEntry,
129 IN RX_BLK *pRxBlk,
130 IN UCHAR FromWhichBSSID)
131{
132
133 // non-EAP frame
134 if (!RTMPCheckWPAframe(pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID))
135 {
136 {
137 // drop all non-EAP DATA frame before
138 // this client's Port-Access-Control is secured
139 if (pRxBlk->pHeader->FC.Wep)
140 {
141 // unsupported cipher suite
142 if (pAd->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
143 {
144 // release packet
145 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
146 return;
147 }
148 }
149 else
150 {
151 // encryption in-use but receive a non-EAPOL clear text frame, drop it
152 if ((pAd->StaCfg.WepStatus != Ndis802_11EncryptionDisabled) &&
153 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
154 {
155 // release packet
156 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
157 return;
158 }
159 }
160 }
161 RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
162 if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK))
163 {
164 // Normal legacy, AMPDU or AMSDU
165 CmmRxnonRalinkFrameIndicate(pAd, pRxBlk, FromWhichBSSID);
166
167 }
168 else
169 {
170 // ARALINK
171 CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
172 }
173#ifdef QOS_DLS_SUPPORT
174 RX_BLK_CLEAR_FLAG(pRxBlk, fRX_DLS);
175#endif // QOS_DLS_SUPPORT //
176 }
177 else
178 {
179 RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
180#ifdef DOT11_N_SUPPORT
181 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
182 {
183 Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
184 }
185 else
186#endif // DOT11_N_SUPPORT //
187 {
188 // Determin the destination of the EAP frame
189 // to WPA state machine or upper layer
190 STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
191 }
192 }
193}
194
195
196// For TKIP frame, calculate the MIC value
197BOOLEAN STACheckTkipMICValue(
198 IN PRTMP_ADAPTER pAd,
199 IN MAC_TABLE_ENTRY *pEntry,
200 IN RX_BLK *pRxBlk)
201{
202 PHEADER_802_11 pHeader = pRxBlk->pHeader;
203 UCHAR *pData = pRxBlk->pData;
204 USHORT DataSize = pRxBlk->DataSize;
205 UCHAR UserPriority = pRxBlk->UserPriority;
206 PCIPHER_KEY pWpaKey;
207 UCHAR *pDA, *pSA;
208
209 pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];
210
211 pDA = pHeader->Addr1;
212 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA))
213 {
214 pSA = pHeader->Addr3;
215 }
216 else
217 {
218 pSA = pHeader->Addr2;
219 }
220
221 if (RTMPTkipCompareMICValue(pAd,
222 pData,
223 pDA,
224 pSA,
225 pWpaKey->RxMic,
226 UserPriority,
227 DataSize) == FALSE)
228 {
229 DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error 2\n"));
230
231#ifdef WPA_SUPPLICANT_SUPPORT
232 if (pAd->StaCfg.WpaSupplicantUP)
233 {
234 WpaSendMicFailureToWpaSupplicant(pAd, (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE);
235 }
236 else
237#endif // WPA_SUPPLICANT_SUPPORT //
238 {
239 RTMPReportMicError(pAd, pWpaKey);
240 }
241
242 // release packet
243 RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
244 return FALSE;
245 }
246
247 return TRUE;
248}
249
250
251//
252// All Rx routines use RX_BLK structure to hande rx events
253// It is very important to build pRxBlk attributes
254// 1. pHeader pointer to 802.11 Header
255// 2. pData pointer to payload including LLC (just skip Header)
256// 3. set payload size including LLC to DataSize
257// 4. set some flags with RX_BLK_SET_FLAG()
258//
259VOID STAHandleRxDataFrame(
260 IN PRTMP_ADAPTER pAd,
261 IN RX_BLK *pRxBlk)
262{
263 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
264 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
265 PHEADER_802_11 pHeader = pRxBlk->pHeader;
266 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
267 BOOLEAN bFragment = FALSE;
268 MAC_TABLE_ENTRY *pEntry = NULL;
269 UCHAR FromWhichBSSID = BSS0;
270 UCHAR UserPriority = 0;
271
272 {
273 // before LINK UP, all DATA frames are rejected
274 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
275 {
276 // release packet
277 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
278 return;
279 }
280
281#ifdef QOS_DLS_SUPPORT
282 //if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
283 if (RTMPRcvFrameDLSCheck(pAd, pHeader, pRxWI->MPDUtotalByteCount, pRxD))
284 {
285 return;
286 }
287#endif // QOS_DLS_SUPPORT //
288
289 // Drop not my BSS frames
290 if (pRxD->MyBss == 0)
291 {
292 {
293 // release packet
294 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
295 return;
296 }
297 }
298
299 pAd->RalinkCounters.RxCountSinceLastNULL++;
300 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && (pHeader->FC.SubType & 0x08))
301 {
302 UCHAR *pData;
303 DBGPRINT(RT_DEBUG_TRACE,("bAPSDCapable\n"));
304
305 // Qos bit 4
306 pData = (PUCHAR)pHeader + LENGTH_802_11;
307 if ((*pData >> 4) & 0x01)
308 {
309 DBGPRINT(RT_DEBUG_TRACE,("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
310 pAd->CommonCfg.bInServicePeriod = FALSE;
311
312 // Force driver to fall into sleep mode when rcv EOSP frame
313 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
314 {
315 USHORT TbttNumToNextWakeUp;
316 USHORT NextDtim = pAd->StaCfg.DtimPeriod;
317 ULONG Now;
318
319 NdisGetSystemUpTime(&Now);
320 NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;
321
322 TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
323 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
324 TbttNumToNextWakeUp = NextDtim;
325
326 MlmeSetPsmBit(pAd, PWR_SAVE);
327 // if WMM-APSD is failed, try to disable following line
328 AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
329 }
330 }
331
332 if ((pHeader->FC.MoreData) && (pAd->CommonCfg.bInServicePeriod))
333 {
334 DBGPRINT(RT_DEBUG_TRACE,("Sending another trigger frame when More Data bit is set to 1\n"));
335 }
336 }
337
338 // Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame
339 if ((pHeader->FC.SubType & 0x04)) // bit 2 : no DATA
340 {
341 // release packet
342 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
343 return;
344 }
345
346 // Drop not my BSS frame (we can not only check the MyBss bit in RxD)
347#ifdef QOS_DLS_SUPPORT
348 if (!pAd->CommonCfg.bDLSCapable)
349 {
350#endif // QOS_DLS_SUPPORT //
351 if (INFRA_ON(pAd))
352 {
353 // Infrastructure mode, check address 2 for BSSID
354 if (!RTMPEqualMemory(&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6))
355 {
356 // Receive frame not my BSSID
357 // release packet
358 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
359 return;
360 }
361 }
362 else // Ad-Hoc mode or Not associated
363 {
364 // Ad-Hoc mode, check address 3 for BSSID
365 if (!RTMPEqualMemory(&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6))
366 {
367 // Receive frame not my BSSID
368 // release packet
369 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
370 return;
371 }
372 }
373#ifdef QOS_DLS_SUPPORT
374 }
375#endif // QOS_DLS_SUPPORT //
376
377 //
378 // find pEntry
379 //
380 if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE)
381 {
382 pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
383 }
384 else
385 {
386 // 1. release packet if infra mode
387 // 2. new a pEntry if ad-hoc mode
388 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
389 return;
390 }
391
392 // infra or ad-hoc
393 if (INFRA_ON(pAd))
394 {
395 RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
396#ifdef QOS_DLS_SUPPORT
397 if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
398 RX_BLK_SET_FLAG(pRxBlk, fRX_DLS);
399 else
400#endif // QOS_DLS_SUPPORT //
401 ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
402 }
403
404 // check Atheros Client
405 if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1) && (pHeader->FC.Retry ))
406 {
407 pEntry->bIAmBadAtheros = TRUE;
408 pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
409 pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
410 if (!STA_AES_ON(pAd))
411 {
412 AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE, FALSE);
413 }
414 }
415 }
416
417 pRxBlk->pData = (UCHAR *)pHeader;
418
419 //
420 // update RxBlk->pData, DataSize
421 // 802.11 Header, QOS, HTC, Hw Padding
422 //
423
424 // 1. skip 802.11 HEADER
425 {
426 pRxBlk->pData += LENGTH_802_11;
427 pRxBlk->DataSize -= LENGTH_802_11;
428 }
429
430 // 2. QOS
431 if (pHeader->FC.SubType & 0x08)
432 {
433 RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
434 UserPriority = *(pRxBlk->pData) & 0x0f;
435 // bit 7 in QoS Control field signals the HT A-MSDU format
436 if ((*pRxBlk->pData) & 0x80)
437 {
438 RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
439 }
440
441 // skip QOS contorl field
442 pRxBlk->pData += 2;
443 pRxBlk->DataSize -=2;
444 }
445 pRxBlk->UserPriority = UserPriority;
446
447 // 3. Order bit: A-Ralink or HTC+
448 if (pHeader->FC.Order)
449 {
450#ifdef AGGREGATION_SUPPORT
451 if ((pRxWI->PHYMODE <= MODE_OFDM) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
452 {
453 RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
454 }
455 else
456#endif
457 {
458#ifdef DOT11_N_SUPPORT
459 RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
460 // skip HTC contorl field
461 pRxBlk->pData += 4;
462 pRxBlk->DataSize -= 4;
463#endif // DOT11_N_SUPPORT //
464 }
465 }
466
467 // 4. skip HW padding
468 if (pRxD->L2PAD)
469 {
470 // just move pData pointer
471 // because DataSize excluding HW padding
472 RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
473 pRxBlk->pData += 2;
474 }
475
476#ifdef DOT11_N_SUPPORT
477 if (pRxD->BA)
478 {
479 RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
480 }
481#endif // DOT11_N_SUPPORT //
482
483
484 //
485 // Case I Process Broadcast & Multicast data frame
486 //
487 if (pRxD->Bcast || pRxD->Mcast)
488 {
489 INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
490
491 // Drop Mcast/Bcast frame with fragment bit on
492 if (pHeader->FC.MoreFrag)
493 {
494 // release packet
495 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
496 return;
497 }
498
499 // Filter out Bcast frame which AP relayed for us
500 if (pHeader->FC.FrDs && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress))
501 {
502 // release packet
503 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
504 return;
505 }
506
507 Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
508 return;
509 }
510 else if (pRxD->U2M)
511 {
512 pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
513
514
515#ifdef QOS_DLS_SUPPORT
516 if (RX_BLK_TEST_FLAG(pRxBlk, fRX_DLS))
517 {
518 MAC_TABLE_ENTRY *pDlsEntry = NULL;
519
520 pDlsEntry = DlsEntryTableLookupByWcid(pAd, pRxWI->WirelessCliID, pHeader->Addr2, TRUE);
521 if(pDlsEntry)
522 Update_Rssi_Sample(pAd, &pDlsEntry->RssiSample, pRxWI);
523 }
524 else
525#endif // QOS_DLS_SUPPORT //
526 if (ADHOC_ON(pAd))
527 {
528 pEntry = MacTableLookup(pAd, pHeader->Addr2);
529 if (pEntry)
530 Update_Rssi_Sample(pAd, &pEntry->RssiSample, pRxWI);
531 }
532
533
534 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
535
536 pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
537 pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
538
539 pAd->RalinkCounters.OneSecRxOkDataCnt++;
540
541
542 if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0)))
543 {
544 // re-assemble the fragmented packets
545 // return complete frame (pRxPacket) or NULL
546 bFragment = TRUE;
547 pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
548 }
549
550 if (pRxPacket)
551 {
552 pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
553
554 // process complete frame
555 if (bFragment && (pRxD->Decrypted) && (pEntry->WepStatus == Ndis802_11Encryption2Enabled))
556 {
557 // Minus MIC length
558 pRxBlk->DataSize -= 8;
559
560 // For TKIP frame, calculate the MIC value
561 if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) == FALSE)
562 {
563 return;
564 }
565 }
566
567 STARxDataFrameAnnounce(pAd, pEntry, pRxBlk, FromWhichBSSID);
568 return;
569 }
570 else
571 {
572 // just return
573 // because RTMPDeFragmentDataFrame() will release rx packet,
574 // if packet is fragmented
575 return;
576 }
577 }
578
579 ASSERT(0);
580 // release packet
581 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
582}
583
584VOID STAHandleRxMgmtFrame(
585 IN PRTMP_ADAPTER pAd,
586 IN RX_BLK *pRxBlk)
587{
588 PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
589 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
590 PHEADER_802_11 pHeader = pRxBlk->pHeader;
591 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
592
593 do
594 {
595
596 // We should collect RSSI not only U2M data but also my beacon
597 if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2)))
598 {
599 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
600
601 pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
602 pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
603 }
604
605 // First check the size, it MUST not exceed the mlme queue size
606 if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE)
607 {
608 DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount));
609 break;
610 }
611
612 REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader, pRxWI->MPDUtotalByteCount,
613 pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
614 } while (FALSE);
615
616 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
617}
618
619VOID STAHandleRxControlFrame(
620 IN PRTMP_ADAPTER pAd,
621 IN RX_BLK *pRxBlk)
622{
623#ifdef DOT11_N_SUPPORT
624 PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
625#endif // DOT11_N_SUPPORT //
626 PHEADER_802_11 pHeader = pRxBlk->pHeader;
627 PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
628
629 switch (pHeader->FC.SubType)
630 {
631 case SUBTYPE_BLOCK_ACK_REQ:
632#ifdef DOT11_N_SUPPORT
633 {
634 CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, (pRxWI->MPDUtotalByteCount), (PFRAME_BA_REQ)pHeader);
635 }
636 break;
637#endif // DOT11_N_SUPPORT //
638 case SUBTYPE_BLOCK_ACK:
639 case SUBTYPE_ACK:
640 default:
641 break;
642 }
643
644 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
645}
646
647
648/*
649 ========================================================================
650
651 Routine Description:
652 Process RxDone interrupt, running in DPC level
653
654 Arguments:
655 pAd Pointer to our adapter
656
657 Return Value:
658 None
659
660 IRQL = DISPATCH_LEVEL
661
662 Note:
663 This routine has to maintain Rx ring read pointer.
664 Need to consider QOS DATA format when converting to 802.3
665 ========================================================================
666*/
667BOOLEAN STARxDoneInterruptHandle(
668 IN PRTMP_ADAPTER pAd,
669 IN BOOLEAN argc)
670{
671 NDIS_STATUS Status;
672 UINT32 RxProcessed, RxPending;
673 BOOLEAN bReschedule = FALSE;
674 RT28XX_RXD_STRUC *pRxD;
675 UCHAR *pData;
676 PRXWI_STRUC pRxWI;
677 PNDIS_PACKET pRxPacket;
678 PHEADER_802_11 pHeader;
679 RX_BLK RxCell;
680
681 RxProcessed = RxPending = 0;
682
683 // process whole rx ring
684 while (1)
685 {
686
687 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
688 fRTMP_ADAPTER_RESET_IN_PROGRESS |
689 fRTMP_ADAPTER_HALT_IN_PROGRESS |
690 fRTMP_ADAPTER_NIC_NOT_EXIST) ||
691 !RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_START_UP))
692 {
693 break;
694 }
695
696#ifdef RT2860
697 if (RxProcessed++ > MAX_RX_PROCESS_CNT)
698 {
699 // need to reschedule rx handle
700 bReschedule = TRUE;
701 break;
702 }
703#endif // RT2860 //
704
705 RxProcessed ++; // test
706
707 // 1. allocate a new data packet into rx ring to replace received packet
708 // then processing the received packet
709 // 2. the callee must take charge of release of packet
710 // 3. As far as driver is concerned ,
711 // the rx packet must
712 // a. be indicated to upper layer or
713 // b. be released if it is discarded
714 pRxPacket = GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule, &RxPending);
715 if (pRxPacket == NULL)
716 {
717 // no more packet to process
718 break;
719 }
720
721 // get rx ring descriptor
722 pRxD = &(RxCell.RxD);
723 // get rx data buffer
724 pData = GET_OS_PKT_DATAPTR(pRxPacket);
725 pRxWI = (PRXWI_STRUC) pData;
726 pHeader = (PHEADER_802_11) (pData+RXWI_SIZE) ;
727
728#ifdef RT_BIG_ENDIAN
729 RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, TRUE);
730 RTMPWIEndianChange((PUCHAR)pRxWI, TYPE_RXWI);
731#endif
732
733 // build RxCell
734 RxCell.pRxWI = pRxWI;
735 RxCell.pHeader = pHeader;
736 RxCell.pRxPacket = pRxPacket;
737 RxCell.pData = (UCHAR *) pHeader;
738 RxCell.DataSize = pRxWI->MPDUtotalByteCount;
739 RxCell.Flags = 0;
740
741 // Increase Total receive byte counter after real data received no mater any error or not
742 pAd->RalinkCounters.ReceivedByteCount += pRxWI->MPDUtotalByteCount;
743 pAd->RalinkCounters.RxCount ++;
744
745 INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
746
747 if (pRxWI->MPDUtotalByteCount < 14)
748 Status = NDIS_STATUS_FAILURE;
749
750 if (MONITOR_ON(pAd))
751 {
752 send_monitor_packets(pAd, &RxCell);
753 break;
754 }
755 /* RT2870 invokes STARxDoneInterruptHandle() in rtusb_bulk.c */
756#ifdef RALINK_ATE
757 if (ATE_ON(pAd))
758 {
759 pAd->ate.RxCntPerSec++;
760 ATESampleRssi(pAd, pRxWI);
761#ifdef RALINK_28xx_QA
762 if (pAd->ate.bQARxStart == TRUE)
763 {
764 /* (*pRxD) has been swapped in GetPacketFromRxRing() */
765 ATE_QA_Statistics(pAd, pRxWI, pRxD, pHeader);
766 }
767#endif // RALINK_28xx_QA //
768 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
769 continue;
770 }
771#endif // RALINK_ATE //
772
773 // Check for all RxD errors
774 Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
775
776 // Handle the received frame
777 if (Status == NDIS_STATUS_SUCCESS)
778 {
779 switch (pHeader->FC.Type)
780 {
781 // CASE I, receive a DATA frame
782 case BTYPE_DATA:
783 {
784 // process DATA frame
785 STAHandleRxDataFrame(pAd, &RxCell);
786 }
787 break;
788 // CASE II, receive a MGMT frame
789 case BTYPE_MGMT:
790 {
791 STAHandleRxMgmtFrame(pAd, &RxCell);
792 }
793 break;
794 // CASE III. receive a CNTL frame
795 case BTYPE_CNTL:
796 {
797 STAHandleRxControlFrame(pAd, &RxCell);
798 }
799 break;
800 // discard other type
801 default:
802 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
803 break;
804 }
805 }
806 else
807 {
808 pAd->Counters8023.RxErrors++;
809 // discard this frame
810 RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
811 }
812 }
813
814 return bReschedule;
815}
816
817/*
818 ========================================================================
819
820 Routine Description:
821 Arguments:
822 pAd Pointer to our adapter
823
824 IRQL = DISPATCH_LEVEL
825
826 ========================================================================
827*/
828VOID RTMPHandleTwakeupInterrupt(
829 IN PRTMP_ADAPTER pAd)
830{
831 AsicForceWakeup(pAd, FALSE);
832}
833
834/*
835========================================================================
836Routine Description:
837 Early checking and OS-depened parsing for Tx packet send to our STA driver.
838
839Arguments:
840 NDIS_HANDLE MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd.
841 PPNDIS_PACKET ppPacketArray The packet array need to do transmission.
842 UINT NumberOfPackets Number of packet in packet array.
843
844Return Value:
845 NONE
846
847Note:
848 This function do early checking and classification for send-out packet.
849 You only can put OS-depened & STA related code in here.
850========================================================================
851*/
852VOID STASendPackets(
853 IN NDIS_HANDLE MiniportAdapterContext,
854 IN PPNDIS_PACKET ppPacketArray,
855 IN UINT NumberOfPackets)
856{
857 UINT Index;
858 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) MiniportAdapterContext;
859 PNDIS_PACKET pPacket;
860 BOOLEAN allowToSend = FALSE;
861
862
863 for (Index = 0; Index < NumberOfPackets; Index++)
864 {
865 pPacket = ppPacketArray[Index];
866
867 do
868 {
869 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
870 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
871 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
872 {
873 // Drop send request since hardware is in reset state
874 break;
875 }
876 else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd))
877 {
878 // Drop send request since there are no physical connection yet
879 break;
880 }
881 else
882 {
883 // Record that orignal packet source is from NDIS layer,so that
884 // later on driver knows how to release this NDIS PACKET
885#ifdef QOS_DLS_SUPPORT
886 MAC_TABLE_ENTRY *pEntry;
887 PUCHAR pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
888
889 pEntry = MacTableLookup(pAd, pSrcBufVA);
890 if (pEntry && (pEntry->ValidAsDls == TRUE))
891 {
892 RTMP_SET_PACKET_WCID(pPacket, pEntry->Aid);
893 }
894 else
895#endif // QOS_DLS_SUPPORT //
896 RTMP_SET_PACKET_WCID(pPacket, 0); // this field is useless when in STA mode
897 RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
898 NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING);
899 pAd->RalinkCounters.PendingNdisPacketCount++;
900
901 allowToSend = TRUE;
902 }
903 } while(FALSE);
904
905 if (allowToSend == TRUE)
906 STASendPacket(pAd, pPacket);
907 else
908 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
909 }
910
911 // Dequeue outgoing frames from TxSwQueue[] and process it
912 RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
913
914}
915
916
917/*
918========================================================================
919Routine Description:
920 This routine is used to do packet parsing and classification for Tx packet
921 to STA device, and it will en-queue packets to our TxSwQueue depends on AC
922 class.
923
924Arguments:
925 pAd Pointer to our adapter
926 pPacket Pointer to send packet
927
928Return Value:
929 NDIS_STATUS_SUCCESS If succes to queue the packet into TxSwQueue.
930 NDIS_STATUS_FAILURE If failed to do en-queue.
931
932Note:
933 You only can put OS-indepened & STA related code in here.
934========================================================================
935*/
936NDIS_STATUS STASendPacket(
937 IN PRTMP_ADAPTER pAd,
938 IN PNDIS_PACKET pPacket)
939{
940 PACKET_INFO PacketInfo;
941 PUCHAR pSrcBufVA;
942 UINT SrcBufLen;
943 UINT AllowFragSize;
944 UCHAR NumberOfFrag;
945 UCHAR QueIdx, UserPriority;
946 MAC_TABLE_ENTRY *pEntry = NULL;
947 unsigned int IrqFlags;
948 UCHAR FlgIsIP = 0;
949 UCHAR Rate;
950
951 // Prepare packet information structure for buffer descriptor
952 // chained within a single NDIS packet.
953 RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
954
955 if (pSrcBufVA == NULL)
956 {
957 DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> pSrcBufVA == NULL !!!SrcBufLen=%x\n",SrcBufLen));
958 // Resourece is low, system did not allocate virtual address
959 // return NDIS_STATUS_FAILURE directly to upper layer
960 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
961 return NDIS_STATUS_FAILURE;
962 }
963
964
965 if (SrcBufLen < 14)
966 {
967 DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> Ndis Packet buffer error !!!\n"));
968 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
969 return (NDIS_STATUS_FAILURE);
970 }
971
972 // In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry.
973 // Note multicast packets in adhoc also use BSSID_WCID index.
974 {
975 if(INFRA_ON(pAd))
976 {
977#ifdef QOS_DLS_SUPPORT
978 USHORT tmpWcid;
979
980 tmpWcid = RTMP_GET_PACKET_WCID(pPacket);
981 if (VALID_WCID(tmpWcid) &&
982 (pAd->MacTab.Content[tmpWcid].ValidAsDls== TRUE))
983 {
984 pEntry = &pAd->MacTab.Content[tmpWcid];
985 Rate = pAd->MacTab.Content[tmpWcid].CurrTxRate;
986 }
987 else
988#endif // QOS_DLS_SUPPORT //
989 {
990 pEntry = &pAd->MacTab.Content[BSSID_WCID];
991 RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
992 Rate = pAd->CommonCfg.TxRate;
993 }
994 }
995 else if (ADHOC_ON(pAd))
996 {
997 if (*pSrcBufVA & 0x01)
998 {
999 RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
1000 pEntry = &pAd->MacTab.Content[MCAST_WCID];
1001 }
1002 else
1003 {
1004 pEntry = MacTableLookup(pAd, pSrcBufVA);
1005 }
1006 Rate = pAd->CommonCfg.TxRate;
1007 }
1008 }
1009
1010 if (!pEntry)
1011 {
1012 DBGPRINT(RT_DEBUG_ERROR,("STASendPacket->Cannot find pEntry(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n", PRINT_MAC(pSrcBufVA)));
1013 // Resourece is low, system did not allocate virtual address
1014 // return NDIS_STATUS_FAILURE directly to upper layer
1015 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1016 return NDIS_STATUS_FAILURE;
1017 }
1018
1019 if (ADHOC_ON(pAd)
1020 )
1021 {
1022 RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid);
1023 }
1024
1025 //
1026 // Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags.
1027 // Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL).
1028 RTMPCheckEtherType(pAd, pPacket);
1029
1030
1031
1032 //
1033 // WPA 802.1x secured port control - drop all non-802.1x frame before port secured
1034 //
1035 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1036 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1037 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
1038 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1039#ifdef WPA_SUPPLICANT_SUPPORT
1040 || (pAd->StaCfg.IEEE8021X == TRUE)
1041#endif // WPA_SUPPLICANT_SUPPORT //
1042#ifdef LEAP_SUPPORT
1043 || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
1044#endif // LEAP_SUPPORT //
1045 )
1046 && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAd->StaCfg.MicErrCnt >= 2))
1047 && (RTMP_GET_PACKET_EAPOL(pPacket)== FALSE)
1048 )
1049 {
1050 DBGPRINT(RT_DEBUG_TRACE,("STASendPacket --> Drop packet before port secured !!!\n"));
1051 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1052
1053 return (NDIS_STATUS_FAILURE);
1054 }
1055
1056
1057 // STEP 1. Decide number of fragments required to deliver this MSDU.
1058 // The estimation here is not very accurate because difficult to
1059 // take encryption overhead into consideration here. The result
1060 // "NumberOfFrag" is then just used to pre-check if enough free
1061 // TXD are available to hold this MSDU.
1062
1063
1064 if (*pSrcBufVA & 0x01) // fragmentation not allowed on multicast & broadcast
1065 NumberOfFrag = 1;
1066 else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
1067 NumberOfFrag = 1; // Aggregation overwhelms fragmentation
1068 else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
1069 NumberOfFrag = 1; // Aggregation overwhelms fragmentation
1070#ifdef DOT11_N_SUPPORT
1071 else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX) || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
1072 NumberOfFrag = 1; // MIMO RATE overwhelms fragmentation
1073#endif // DOT11_N_SUPPORT //
1074 else
1075 {
1076 // The calculated "NumberOfFrag" is a rough estimation because of various
1077 // encryption/encapsulation overhead not taken into consideration. This number is just
1078 // used to make sure enough free TXD are available before fragmentation takes place.
1079 // In case the actual required number of fragments of an NDIS packet
1080 // excceeds "NumberOfFrag"caculated here and not enough free TXD available, the
1081 // last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of
1082 // resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should
1083 // rarely happen and the penalty is just like a TX RETRY fail. Affordable.
1084
1085 AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
1086 NumberOfFrag = ((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;
1087 // To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size
1088 if (((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)
1089 {
1090 NumberOfFrag--;
1091 }
1092 }
1093
1094 // Save fragment number to Ndis packet reserved field
1095 RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
1096
1097
1098 // STEP 2. Check the requirement of RTS:
1099 // If multiple fragment required, RTS is required only for the first fragment
1100 // if the fragment size large than RTS threshold
1101 // For RT28xx, Let ASIC send RTS/CTS
1102 RTMP_SET_PACKET_RTS(pPacket, 0);
1103 RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
1104
1105 //
1106 // STEP 3. Traffic classification. outcome = <UserPriority, QueIdx>
1107 //
1108 UserPriority = 0;
1109 QueIdx = QID_AC_BE;
1110 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
1111 {
1112 USHORT Protocol;
1113 UCHAR LlcSnapLen = 0, Byte0, Byte1;
1114 do
1115 {
1116 // get Ethernet protocol field
1117 Protocol = (USHORT)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
1118 if (Protocol <= 1500)
1119 {
1120 // get Ethernet protocol field from LLC/SNAP
1121 if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + 6, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
1122 break;
1123
1124 Protocol = (USHORT)((Byte0 << 8) + Byte1);
1125 LlcSnapLen = 8;
1126 }
1127
1128 // always AC_BE for non-IP packet
1129 if (Protocol != 0x0800)
1130 break;
1131
1132 // get IP header
1133 if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
1134 break;
1135
1136 // return AC_BE if packet is not IPv4
1137 if ((Byte0 & 0xf0) != 0x40)
1138 break;
1139
1140 FlgIsIP = 1;
1141 UserPriority = (Byte1 & 0xe0) >> 5;
1142 QueIdx = MapUserPriorityToAccessCategory[UserPriority];
1143
1144 // TODO: have to check ACM bit. apply TSPEC if ACM is ON
1145 // TODO: downgrade UP & QueIdx before passing ACM
1146 if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx])
1147 {
1148 UserPriority = 0;
1149 QueIdx = QID_AC_BE;
1150 }
1151 } while (FALSE);
1152 }
1153
1154 RTMP_SET_PACKET_UP(pPacket, UserPriority);
1155
1156
1157
1158 // Make sure SendTxWait queue resource won't be used by other threads
1159 RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
1160 if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE)
1161 {
1162 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1163#ifdef BLOCK_NET_IF
1164 StopNetIfQueue(pAd, QueIdx, pPacket);
1165#endif // BLOCK_NET_IF //
1166 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1167
1168 return NDIS_STATUS_FAILURE;
1169 }
1170 else
1171 {
1172 InsertTailQueue(&pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
1173 }
1174 RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
1175
1176#ifdef DOT11_N_SUPPORT
1177 if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE)&&
1178 (pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1179 {
1180 if (((pEntry->TXBAbitmap & (1<<UserPriority)) == 0) &&
1181 ((pEntry->BADeclineBitmap & (1<<UserPriority)) == 0) &&
1182 (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
1183 // For IOT compatibility, if
1184 // 1. It is Ralink chip or
1185 // 2. It is OPEN or AES mode,
1186 // then BA session can be bulit.
1187 && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0) ||
1188 (pEntry->WepStatus == Ndis802_11WEPDisabled || pEntry->WepStatus == Ndis802_11Encryption3Enabled))
1189 )
1190 {
1191 BAOriSessionSetUp(pAd, pEntry, 0, 0, 10, FALSE);
1192 }
1193 }
1194#endif // DOT11_N_SUPPORT //
1195
1196 pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; // TODO: for debug only. to be removed
1197 return NDIS_STATUS_SUCCESS;
1198}
1199
1200
1201/*
1202 ========================================================================
1203
1204 Routine Description:
1205 This subroutine will scan through releative ring descriptor to find
1206 out avaliable free ring descriptor and compare with request size.
1207
1208 Arguments:
1209 pAd Pointer to our adapter
1210 QueIdx Selected TX Ring
1211
1212 Return Value:
1213 NDIS_STATUS_FAILURE Not enough free descriptor
1214 NDIS_STATUS_SUCCESS Enough free descriptor
1215
1216 IRQL = PASSIVE_LEVEL
1217 IRQL = DISPATCH_LEVEL
1218
1219 Note:
1220
1221 ========================================================================
1222*/
1223#ifdef RT2860
1224NDIS_STATUS RTMPFreeTXDRequest(
1225 IN PRTMP_ADAPTER pAd,
1226 IN UCHAR QueIdx,
1227 IN UCHAR NumberRequired,
1228 IN PUCHAR FreeNumberIs)
1229{
1230 ULONG FreeNumber = 0;
1231 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
1232
1233 switch (QueIdx)
1234 {
1235 case QID_AC_BK:
1236 case QID_AC_BE:
1237 case QID_AC_VI:
1238 case QID_AC_VO:
1239 case QID_HCCA:
1240 if (pAd->TxRing[QueIdx].TxSwFreeIdx > pAd->TxRing[QueIdx].TxCpuIdx)
1241 FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx - pAd->TxRing[QueIdx].TxCpuIdx - 1;
1242 else
1243 FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx + TX_RING_SIZE - pAd->TxRing[QueIdx].TxCpuIdx - 1;
1244
1245 if (FreeNumber >= NumberRequired)
1246 Status = NDIS_STATUS_SUCCESS;
1247 break;
1248
1249 case QID_MGMT:
1250 if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx)
1251 FreeNumber = pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx - 1;
1252 else
1253 FreeNumber = pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - pAd->MgmtRing.TxCpuIdx - 1;
1254
1255 if (FreeNumber >= NumberRequired)
1256 Status = NDIS_STATUS_SUCCESS;
1257 break;
1258
1259 default:
1260 DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
1261 break;
1262 }
1263 *FreeNumberIs = (UCHAR)FreeNumber;
1264
1265 return (Status);
1266}
1267#endif // RT2860 //
1268
1269
1270
1271VOID RTMPSendDisassociationFrame(
1272 IN PRTMP_ADAPTER pAd)
1273{
1274}
1275
1276VOID RTMPSendNullFrame(
1277 IN PRTMP_ADAPTER pAd,
1278 IN UCHAR TxRate,
1279 IN BOOLEAN bQosNull)
1280{
1281 UCHAR NullFrame[48];
1282 ULONG Length;
1283 PHEADER_802_11 pHeader_802_11;
1284
1285
1286#ifdef RALINK_ATE
1287 if(ATE_ON(pAd))
1288 {
1289 return;
1290 }
1291#endif // RALINK_ATE //
1292
1293 // WPA 802.1x secured port control
1294 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1295 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1296 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
1297 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1298#ifdef WPA_SUPPLICANT_SUPPORT
1299 || (pAd->StaCfg.IEEE8021X == TRUE)
1300#endif
1301 ) &&
1302 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1303 {
1304 return;
1305 }
1306
1307 NdisZeroMemory(NullFrame, 48);
1308 Length = sizeof(HEADER_802_11);
1309
1310 pHeader_802_11 = (PHEADER_802_11) NullFrame;
1311
1312 pHeader_802_11->FC.Type = BTYPE_DATA;
1313 pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
1314 pHeader_802_11->FC.ToDs = 1;
1315 COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
1316 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1317 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1318
1319 if (pAd->CommonCfg.bAPSDForcePowerSave)
1320 {
1321 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
1322 }
1323 else
1324 {
1325 pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE) ? 1: 0;
1326 }
1327 pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
1328
1329 pAd->Sequence++;
1330 pHeader_802_11->Sequence = pAd->Sequence;
1331
1332 // Prepare QosNull function frame
1333 if (bQosNull)
1334 {
1335 pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;
1336
1337 // copy QOS control bytes
1338 NullFrame[Length] = 0;
1339 NullFrame[Length+1] = 0;
1340 Length += 2;// if pad with 2 bytes for alignment, APSD will fail
1341 }
1342
1343 HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);
1344
1345}
1346
1347// IRQL = DISPATCH_LEVEL
1348VOID RTMPSendRTSFrame(
1349 IN PRTMP_ADAPTER pAd,
1350 IN PUCHAR pDA,
1351 IN unsigned int NextMpduSize,
1352 IN UCHAR TxRate,
1353 IN UCHAR RTSRate,
1354 IN USHORT AckDuration,
1355 IN UCHAR QueIdx,
1356 IN UCHAR FrameGap)
1357{
1358}
1359
1360
1361
1362// --------------------------------------------------------
1363// FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM
1364// Find the WPA key, either Group or Pairwise Key
1365// LEAP + TKIP also use WPA key.
1366// --------------------------------------------------------
1367// Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst
1368// In Cisco CCX 2.0 Leap Authentication
1369// WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey
1370// Instead of the SharedKey, SharedKey Length may be Zero.
1371VOID STAFindCipherAlgorithm(
1372 IN PRTMP_ADAPTER pAd,
1373 IN TX_BLK *pTxBlk)
1374{
1375 NDIS_802_11_ENCRYPTION_STATUS Cipher; // To indicate cipher used for this packet
1376 UCHAR CipherAlg = CIPHER_NONE; // cipher alogrithm
1377 UCHAR KeyIdx = 0xff;
1378 PUCHAR pSrcBufVA;
1379 PCIPHER_KEY pKey = NULL;
1380
1381 pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);
1382
1383 {
1384 // Select Cipher
1385 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
1386 Cipher = pAd->StaCfg.GroupCipher; // Cipher for Multicast or Broadcast
1387 else
1388 Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast
1389
1390 if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
1391 {
1392 ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <= CIPHER_CKIP128);
1393
1394 // 4-way handshaking frame must be clear
1395 if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) && (pAd->SharedKey[BSS0][0].CipherAlg) &&
1396 (pAd->SharedKey[BSS0][0].KeyLen))
1397 {
1398 CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
1399 KeyIdx = 0;
1400 }
1401 }
1402 else if (Cipher == Ndis802_11Encryption1Enabled)
1403 {
1404#ifdef LEAP_SUPPORT
1405 if (pAd->StaCfg.CkipFlag & 0x10) // Cisco CKIP KP is on
1406 {
1407 if (LEAP_CCKM_ON(pAd))
1408 {
1409 if (((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))))
1410 KeyIdx = 1;
1411 else
1412 KeyIdx = 0;
1413 }
1414 else
1415 KeyIdx = pAd->StaCfg.DefaultKeyId;
1416 }
1417 else if (pAd->StaCfg.CkipFlag & 0x08) // only CKIP CMIC
1418 KeyIdx = pAd->StaCfg.DefaultKeyId;
1419 else if (LEAP_CCKM_ON(pAd))
1420 {
1421 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
1422 KeyIdx = 1;
1423 else
1424 KeyIdx = 0;
1425 }
1426 else // standard WEP64 or WEP128
1427#endif // LEAP_SUPPORT //
1428 KeyIdx = pAd->StaCfg.DefaultKeyId;
1429 }
1430 else if ((Cipher == Ndis802_11Encryption2Enabled) ||
1431 (Cipher == Ndis802_11Encryption3Enabled))
1432 {
1433 if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) // multicast
1434 KeyIdx = pAd->StaCfg.DefaultKeyId;
1435 else if (pAd->SharedKey[BSS0][0].KeyLen)
1436 KeyIdx = 0;
1437 else
1438 KeyIdx = pAd->StaCfg.DefaultKeyId;
1439 }
1440
1441 if (KeyIdx == 0xff)
1442 CipherAlg = CIPHER_NONE;
1443 else if ((Cipher == Ndis802_11EncryptionDisabled) || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
1444 CipherAlg = CIPHER_NONE;
1445#ifdef WPA_SUPPLICANT_SUPPORT
1446 else if ( pAd->StaCfg.WpaSupplicantUP &&
1447 (Cipher == Ndis802_11Encryption1Enabled) &&
1448 (pAd->StaCfg.IEEE8021X == TRUE) &&
1449 (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1450 CipherAlg = CIPHER_NONE;
1451#endif // WPA_SUPPLICANT_SUPPORT //
1452 else
1453 {
1454 //Header_802_11.FC.Wep = 1;
1455 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
1456 pKey = &pAd->SharedKey[BSS0][KeyIdx];
1457 }
1458 }
1459
1460 pTxBlk->CipherAlg = CipherAlg;
1461 pTxBlk->pKey = pKey;
1462}
1463
1464
1465VOID STABuildCommon802_11Header(
1466 IN PRTMP_ADAPTER pAd,
1467 IN TX_BLK *pTxBlk)
1468{
1469
1470 HEADER_802_11 *pHeader_802_11;
1471#ifdef QOS_DLS_SUPPORT
1472 BOOLEAN bDLSFrame = FALSE;
1473 INT DlsEntryIndex = 0;
1474#endif // QOS_DLS_SUPPORT //
1475
1476 //
1477 // MAKE A COMMON 802.11 HEADER
1478 //
1479
1480 // normal wlan header size : 24 octets
1481 pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
1482
1483 pHeader_802_11 = (HEADER_802_11 *) &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1484
1485 NdisZeroMemory(pHeader_802_11, sizeof(HEADER_802_11));
1486
1487 pHeader_802_11->FC.FrDs = 0;
1488 pHeader_802_11->FC.Type = BTYPE_DATA;
1489 pHeader_802_11->FC.SubType = ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : SUBTYPE_DATA);
1490
1491#ifdef QOS_DLS_SUPPORT
1492 if (INFRA_ON(pAd))
1493 {
1494 // Check if the frame can be sent through DLS direct link interface
1495 // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
1496 DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
1497 if (DlsEntryIndex >= 0)
1498 bDLSFrame = TRUE;
1499 else
1500 bDLSFrame = FALSE;
1501 }
1502#endif // QOS_DLS_SUPPORT //
1503
1504 if (pTxBlk->pMacEntry)
1505 {
1506 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS))
1507 {
1508 pHeader_802_11->Sequence = pTxBlk->pMacEntry->NonQosDataSeq;
1509 pTxBlk->pMacEntry->NonQosDataSeq = (pTxBlk->pMacEntry->NonQosDataSeq+1) & MAXSEQ;
1510 }
1511 else
1512 {
1513#ifdef QOS_DLS_SUPPORT
1514 if (bDLSFrame)
1515 {
1516 pHeader_802_11->Sequence = pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence;
1517 pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence = (pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence+1) & MAXSEQ;
1518 }
1519 else
1520#endif // QOS_DLS_SUPPORT //
1521 {
1522 pHeader_802_11->Sequence = pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority];
1523 pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
1524 }
1525 }
1526 }
1527 else
1528 {
1529 pHeader_802_11->Sequence = pAd->Sequence;
1530 pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; // next sequence
1531 }
1532
1533 pHeader_802_11->Frag = 0;
1534
1535 pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
1536
1537 {
1538 if (INFRA_ON(pAd))
1539 {
1540#ifdef QOS_DLS_SUPPORT
1541 if (bDLSFrame)
1542 {
1543 COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
1544 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1545 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1546 pHeader_802_11->FC.ToDs = 0;
1547 }
1548 else
1549#endif // QOS_DLS_SUPPORT //
1550 {
1551 COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
1552 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1553 COPY_MAC_ADDR(pHeader_802_11->Addr3, pTxBlk->pSrcBufHeader);
1554 pHeader_802_11->FC.ToDs = 1;
1555 }
1556 }
1557 else if (ADHOC_ON(pAd))
1558 {
1559 COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
1560 COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
1561 COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
1562 pHeader_802_11->FC.ToDs = 0;
1563 }
1564 }
1565
1566 if (pTxBlk->CipherAlg != CIPHER_NONE)
1567 pHeader_802_11->FC.Wep = 1;
1568
1569 // -----------------------------------------------------------------
1570 // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
1571 // -----------------------------------------------------------------
1572 if (pAd->CommonCfg.bAPSDForcePowerSave)
1573 pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
1574 else
1575 pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
1576}
1577
1578#ifdef DOT11_N_SUPPORT
1579VOID STABuildCache802_11Header(
1580 IN RTMP_ADAPTER *pAd,
1581 IN TX_BLK *pTxBlk,
1582 IN UCHAR *pHeader)
1583{
1584 MAC_TABLE_ENTRY *pMacEntry;
1585 PHEADER_802_11 pHeader80211;
1586
1587 pHeader80211 = (PHEADER_802_11)pHeader;
1588 pMacEntry = pTxBlk->pMacEntry;
1589
1590 //
1591 // Update the cached 802.11 HEADER
1592 //
1593
1594 // normal wlan header size : 24 octets
1595 pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
1596
1597 // More Bit
1598 pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
1599
1600 // Sequence
1601 pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
1602 pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
1603
1604 {
1605 // Check if the frame can be sent through DLS direct link interface
1606 // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
1607#ifdef QOS_DLS_SUPPORT
1608 BOOLEAN bDLSFrame = FALSE;
1609 INT DlsEntryIndex = 0;
1610
1611 DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
1612 if (DlsEntryIndex >= 0)
1613 bDLSFrame = TRUE;
1614 else
1615 bDLSFrame = FALSE;
1616#endif // QOS_DLS_SUPPORT //
1617
1618 // The addr3 of normal packet send from DS is Dest Mac address.
1619#ifdef QOS_DLS_SUPPORT
1620 if (bDLSFrame)
1621 {
1622 COPY_MAC_ADDR(pHeader80211->Addr1, pTxBlk->pSrcBufHeader);
1623 COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
1624 pHeader80211->FC.ToDs = 0;
1625 }
1626 else
1627#endif // QOS_DLS_SUPPORT //
1628 if (ADHOC_ON(pAd))
1629 COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
1630 else
1631 COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader);
1632 }
1633
1634 // -----------------------------------------------------------------
1635 // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
1636 // -----------------------------------------------------------------
1637 if (pAd->CommonCfg.bAPSDForcePowerSave)
1638 pHeader80211->FC.PwrMgmt = PWR_SAVE;
1639 else
1640 pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
1641}
1642#endif // DOT11_N_SUPPORT //
1643
1644static inline PUCHAR STA_Build_ARalink_Frame_Header(
1645 IN RTMP_ADAPTER *pAd,
1646 IN TX_BLK *pTxBlk)
1647{
1648 PUCHAR pHeaderBufPtr;
1649 HEADER_802_11 *pHeader_802_11;
1650 PNDIS_PACKET pNextPacket;
1651 UINT32 nextBufLen;
1652 PQUEUE_ENTRY pQEntry;
1653
1654 STAFindCipherAlgorithm(pAd, pTxBlk);
1655 STABuildCommon802_11Header(pAd, pTxBlk);
1656
1657
1658 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1659 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
1660
1661 // steal "order" bit to mark "aggregation"
1662 pHeader_802_11->FC.Order = 1;
1663
1664 // skip common header
1665 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1666
1667 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
1668 {
1669 //
1670 // build QOS Control bytes
1671 //
1672 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1673
1674 *(pHeaderBufPtr+1) = 0;
1675 pHeaderBufPtr +=2;
1676 pTxBlk->MpduHeaderLen += 2;
1677 }
1678
1679 // padding at front of LLC header. LLC header should at 4-bytes aligment.
1680 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
1681 pHeaderBufPtr = (PCHAR)ROUND_UP(pHeaderBufPtr, 4);
1682 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1683
1684 // For RA Aggregation,
1685 // put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format
1686 pQEntry = pTxBlk->TxPacketList.Head;
1687 pNextPacket = QUEUE_ENTRY_TO_PKT(pQEntry);
1688 nextBufLen = GET_OS_PKT_LEN(pNextPacket);
1689 if (RTMP_GET_PACKET_VLAN(pNextPacket))
1690 nextBufLen -= LENGTH_802_1Q;
1691
1692 *pHeaderBufPtr = (UCHAR)nextBufLen & 0xff;
1693 *(pHeaderBufPtr+1) = (UCHAR)(nextBufLen >> 8);
1694
1695 pHeaderBufPtr += 2;
1696 pTxBlk->MpduHeaderLen += 2;
1697
1698 return pHeaderBufPtr;
1699
1700}
1701
1702#ifdef DOT11_N_SUPPORT
1703static inline PUCHAR STA_Build_AMSDU_Frame_Header(
1704 IN RTMP_ADAPTER *pAd,
1705 IN TX_BLK *pTxBlk)
1706{
1707 PUCHAR pHeaderBufPtr;//, pSaveBufPtr;
1708 HEADER_802_11 *pHeader_802_11;
1709
1710
1711 STAFindCipherAlgorithm(pAd, pTxBlk);
1712 STABuildCommon802_11Header(pAd, pTxBlk);
1713
1714 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1715 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
1716
1717 // skip common header
1718 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1719
1720 //
1721 // build QOS Control bytes
1722 //
1723 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1724
1725 //
1726 // A-MSDU packet
1727 //
1728 *pHeaderBufPtr |= 0x80;
1729
1730 *(pHeaderBufPtr+1) = 0;
1731 pHeaderBufPtr +=2;
1732 pTxBlk->MpduHeaderLen += 2;
1733
1734 //pSaveBufPtr = pHeaderBufPtr;
1735
1736 //
1737 // padding at front of LLC header
1738 // LLC header should locate at 4-octets aligment
1739 //
1740 // @@@ MpduHeaderLen excluding padding @@@
1741 //
1742 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
1743 pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
1744 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1745
1746 return pHeaderBufPtr;
1747
1748}
1749
1750
1751VOID STA_AMPDU_Frame_Tx(
1752 IN PRTMP_ADAPTER pAd,
1753 IN TX_BLK *pTxBlk)
1754{
1755 HEADER_802_11 *pHeader_802_11;
1756 PUCHAR pHeaderBufPtr;
1757 USHORT FreeNumber;
1758 MAC_TABLE_ENTRY *pMacEntry;
1759 BOOLEAN bVLANPkt;
1760 PQUEUE_ENTRY pQEntry;
1761
1762 ASSERT(pTxBlk);
1763
1764 while(pTxBlk->TxPacketList.Head)
1765 {
1766 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1767 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1768 if ( RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
1769 {
1770 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
1771 continue;
1772 }
1773
1774 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
1775
1776 pMacEntry = pTxBlk->pMacEntry;
1777 if (pMacEntry->isCached)
1778 {
1779 // NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]!!!!
1780 NdisMoveMemory((PUCHAR)&pTxBlk->HeaderBuf[TXINFO_SIZE], (PUCHAR)&pMacEntry->CachedBuf[0], TXWI_SIZE + sizeof(HEADER_802_11));
1781 pHeaderBufPtr = (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
1782 STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
1783 }
1784 else
1785 {
1786 STAFindCipherAlgorithm(pAd, pTxBlk);
1787 STABuildCommon802_11Header(pAd, pTxBlk);
1788
1789 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
1790 }
1791
1792
1793 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
1794
1795 // skip common header
1796 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
1797
1798 //
1799 // build QOS Control bytes
1800 //
1801 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
1802 *(pHeaderBufPtr+1) = 0;
1803 pHeaderBufPtr +=2;
1804 pTxBlk->MpduHeaderLen += 2;
1805
1806 //
1807 // build HTC+
1808 // HTC control filed following QoS field
1809 //
1810 if ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_RDG_CAPABLE))
1811 {
1812 if (pMacEntry->isCached == FALSE)
1813 {
1814 // mark HTC bit
1815 pHeader_802_11->FC.Order = 1;
1816
1817 NdisZeroMemory(pHeaderBufPtr, 4);
1818 *(pHeaderBufPtr+3) |= 0x80;
1819 }
1820 pHeaderBufPtr += 4;
1821 pTxBlk->MpduHeaderLen += 4;
1822 }
1823
1824 //pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE;
1825 ASSERT(pTxBlk->MpduHeaderLen >= 24);
1826
1827 // skip 802.3 header
1828 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
1829 pTxBlk->SrcBufLen -= LENGTH_802_3;
1830
1831 // skip vlan tag
1832 if (bVLANPkt)
1833 {
1834 pTxBlk->pSrcBufData += LENGTH_802_1Q;
1835 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
1836 }
1837
1838 //
1839 // padding at front of LLC header
1840 // LLC header should locate at 4-octets aligment
1841 //
1842 // @@@ MpduHeaderLen excluding padding @@@
1843 //
1844 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
1845 pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
1846 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
1847
1848 {
1849
1850 //
1851 // Insert LLC-SNAP encapsulation - 8 octets
1852 //
1853 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
1854 if (pTxBlk->pExtraLlcSnapEncap)
1855 {
1856 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
1857 pHeaderBufPtr += 6;
1858 // get 2 octets (TypeofLen)
1859 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
1860 pHeaderBufPtr += 2;
1861 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
1862 }
1863
1864 }
1865
1866 if (pMacEntry->isCached)
1867 {
1868 RTMPWriteTxWI_Cache(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
1869 }
1870 else
1871 {
1872 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
1873
1874 NdisZeroMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), sizeof(pMacEntry->CachedBuf));
1875 NdisMoveMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (pHeaderBufPtr - (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE])));
1876 pMacEntry->isCached = TRUE;
1877 }
1878
1879 // calculate Transmitted AMPDU count and ByteCount
1880 {
1881 pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart ++;
1882 pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.QuadPart += pTxBlk->SrcBufLen;
1883 }
1884
1885 //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
1886
1887 HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
1888
1889 //
1890 // Kick out Tx
1891 //
1892 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
1893
1894 pAd->RalinkCounters.KickTxCount++;
1895 pAd->RalinkCounters.OneSecTxDoneCount++;
1896 }
1897
1898}
1899
1900
1901VOID STA_AMSDU_Frame_Tx(
1902 IN PRTMP_ADAPTER pAd,
1903 IN TX_BLK *pTxBlk)
1904{
1905 PUCHAR pHeaderBufPtr;
1906 USHORT FreeNumber;
1907 USHORT subFramePayloadLen = 0; // AMSDU Subframe length without AMSDU-Header / Padding.
1908 USHORT totalMPDUSize=0;
1909 UCHAR *subFrameHeader;
1910 UCHAR padding = 0;
1911 USHORT FirstTx = 0, LastTxIdx = 0;
1912 BOOLEAN bVLANPkt;
1913 int frameNum = 0;
1914 PQUEUE_ENTRY pQEntry;
1915
1916
1917 ASSERT(pTxBlk);
1918
1919 ASSERT((pTxBlk->TxPacketList.Number > 1));
1920
1921 while(pTxBlk->TxPacketList.Head)
1922 {
1923 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
1924 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
1925 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
1926 {
1927 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
1928 continue;
1929 }
1930
1931 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
1932
1933 // skip 802.3 header
1934 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
1935 pTxBlk->SrcBufLen -= LENGTH_802_3;
1936
1937 // skip vlan tag
1938 if (bVLANPkt)
1939 {
1940 pTxBlk->pSrcBufData += LENGTH_802_1Q;
1941 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
1942 }
1943
1944 if (frameNum == 0)
1945 {
1946 pHeaderBufPtr = STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
1947
1948 // NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled.
1949 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
1950 }
1951 else
1952 {
1953 pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
1954 padding = ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen, 4) - (LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen);
1955 NdisZeroMemory(pHeaderBufPtr, padding + LENGTH_AMSDU_SUBFRAMEHEAD);
1956 pHeaderBufPtr += padding;
1957 pTxBlk->MpduHeaderLen = padding;
1958 }
1959
1960 //
1961 // A-MSDU subframe
1962 // DA(6)+SA(6)+Length(2) + LLC/SNAP Encap
1963 //
1964 subFrameHeader = pHeaderBufPtr;
1965 subFramePayloadLen = pTxBlk->SrcBufLen;
1966
1967 NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
1968
1969
1970 pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
1971 pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;
1972
1973
1974 //
1975 // Insert LLC-SNAP encapsulation - 8 octets
1976 //
1977 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
1978
1979 subFramePayloadLen = pTxBlk->SrcBufLen;
1980
1981 if (pTxBlk->pExtraLlcSnapEncap)
1982 {
1983 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
1984 pHeaderBufPtr += 6;
1985 // get 2 octets (TypeofLen)
1986 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
1987 pHeaderBufPtr += 2;
1988 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
1989 subFramePayloadLen += LENGTH_802_1_H;
1990 }
1991
1992 // update subFrame Length field
1993 subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
1994 subFrameHeader[13] = subFramePayloadLen & 0xFF;
1995
1996 totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
1997
1998 if (frameNum ==0)
1999 FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2000 else
2001 LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2002
2003 frameNum++;
2004
2005 pAd->RalinkCounters.KickTxCount++;
2006 pAd->RalinkCounters.OneSecTxDoneCount++;
2007
2008 // calculate Transmitted AMSDU Count and ByteCount
2009 {
2010 pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart ++;
2011 pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart += totalMPDUSize;
2012 }
2013
2014 }
2015
2016 HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
2017 HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
2018
2019 //
2020 // Kick out Tx
2021 //
2022 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2023}
2024#endif // DOT11_N_SUPPORT //
2025
2026VOID STA_Legacy_Frame_Tx(
2027 IN PRTMP_ADAPTER pAd,
2028 IN TX_BLK *pTxBlk)
2029{
2030 HEADER_802_11 *pHeader_802_11;
2031 PUCHAR pHeaderBufPtr;
2032 USHORT FreeNumber;
2033 BOOLEAN bVLANPkt;
2034 PQUEUE_ENTRY pQEntry;
2035
2036 ASSERT(pTxBlk);
2037
2038
2039 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2040 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2041 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
2042 {
2043 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2044 return;
2045 }
2046
2047 if (pTxBlk->TxFrameType == TX_MCAST_FRAME)
2048 {
2049 INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
2050 }
2051
2052 if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket))
2053 TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired);
2054 else
2055 TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired);
2056
2057 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2058
2059 if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate)
2060 pTxBlk->TxRate = pAd->CommonCfg.MinTxRate;
2061
2062 STAFindCipherAlgorithm(pAd, pTxBlk);
2063 STABuildCommon802_11Header(pAd, pTxBlk);
2064
2065
2066 // skip 802.3 header
2067 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2068 pTxBlk->SrcBufLen -= LENGTH_802_3;
2069
2070 // skip vlan tag
2071 if (bVLANPkt)
2072 {
2073 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2074 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2075 }
2076
2077 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
2078 pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
2079
2080 // skip common header
2081 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
2082
2083 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
2084 {
2085 //
2086 // build QOS Control bytes
2087 //
2088 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
2089 *(pHeaderBufPtr+1) = 0;
2090 pHeaderBufPtr +=2;
2091 pTxBlk->MpduHeaderLen += 2;
2092 }
2093
2094 // The remaining content of MPDU header should locate at 4-octets aligment
2095 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
2096 pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
2097 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
2098
2099 {
2100
2101 //
2102 // Insert LLC-SNAP encapsulation - 8 octets
2103 //
2104 //
2105 // if original Ethernet frame contains no LLC/SNAP,
2106 // then an extra LLC/SNAP encap is required
2107 //
2108 EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
2109 if (pTxBlk->pExtraLlcSnapEncap)
2110 {
2111 UCHAR vlan_size;
2112
2113 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2114 pHeaderBufPtr += 6;
2115 // skip vlan tag
2116 vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
2117 // get 2 octets (TypeofLen)
2118 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
2119 pHeaderBufPtr += 2;
2120 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2121 }
2122
2123 }
2124
2125 //
2126 // prepare for TXWI
2127 // use Wcid as Key Index
2128 //
2129
2130 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
2131
2132 //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
2133
2134 HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
2135
2136 pAd->RalinkCounters.KickTxCount++;
2137 pAd->RalinkCounters.OneSecTxDoneCount++;
2138
2139 //
2140 // Kick out Tx
2141 //
2142 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2143}
2144
2145
2146VOID STA_ARalink_Frame_Tx(
2147 IN PRTMP_ADAPTER pAd,
2148 IN TX_BLK *pTxBlk)
2149{
2150 PUCHAR pHeaderBufPtr;
2151 USHORT FreeNumber;
2152 USHORT totalMPDUSize=0;
2153 USHORT FirstTx, LastTxIdx;
2154 int frameNum = 0;
2155 BOOLEAN bVLANPkt;
2156 PQUEUE_ENTRY pQEntry;
2157
2158
2159 ASSERT(pTxBlk);
2160
2161 ASSERT((pTxBlk->TxPacketList.Number== 2));
2162
2163
2164 FirstTx = LastTxIdx = 0; // Is it ok init they as 0?
2165 while(pTxBlk->TxPacketList.Head)
2166 {
2167 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2168 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2169
2170 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
2171 {
2172 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2173 continue;
2174 }
2175
2176 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2177
2178 // skip 802.3 header
2179 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2180 pTxBlk->SrcBufLen -= LENGTH_802_3;
2181
2182 // skip vlan tag
2183 if (bVLANPkt)
2184 {
2185 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2186 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2187 }
2188
2189 if (frameNum == 0)
2190 { // For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header
2191
2192 pHeaderBufPtr = STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
2193
2194 // It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount
2195 // will be updated after final frame was handled.
2196 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
2197
2198
2199 //
2200 // Insert LLC-SNAP encapsulation - 8 octets
2201 //
2202 EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
2203
2204 if (pTxBlk->pExtraLlcSnapEncap)
2205 {
2206 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2207 pHeaderBufPtr += 6;
2208 // get 2 octets (TypeofLen)
2209 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
2210 pHeaderBufPtr += 2;
2211 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2212 }
2213 }
2214 else
2215 { // For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0.
2216
2217 pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
2218 pTxBlk->MpduHeaderLen = 0;
2219
2220 // A-Ralink sub-sequent frame header is the same as 802.3 header.
2221 // DA(6)+SA(6)+FrameType(2)
2222 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader, 12);
2223 pHeaderBufPtr += 12;
2224 // get 2 octets (TypeofLen)
2225 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
2226 pHeaderBufPtr += 2;
2227 pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
2228 }
2229
2230 totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
2231
2232 //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
2233 if (frameNum ==0)
2234 FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2235 else
2236 LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
2237
2238 frameNum++;
2239
2240 pAd->RalinkCounters.OneSecTxAggregationCount++;
2241 pAd->RalinkCounters.KickTxCount++;
2242 pAd->RalinkCounters.OneSecTxDoneCount++;
2243
2244 }
2245
2246 HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
2247 HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
2248
2249 //
2250 // Kick out Tx
2251 //
2252 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2253
2254}
2255
2256
2257VOID STA_Fragment_Frame_Tx(
2258 IN RTMP_ADAPTER *pAd,
2259 IN TX_BLK *pTxBlk)
2260{
2261 HEADER_802_11 *pHeader_802_11;
2262 PUCHAR pHeaderBufPtr;
2263 USHORT FreeNumber;
2264 UCHAR fragNum = 0;
2265 PACKET_INFO PacketInfo;
2266 USHORT EncryptionOverhead = 0;
2267 UINT32 FreeMpduSize, SrcRemainingBytes;
2268 USHORT AckDuration;
2269 UINT NextMpduSize;
2270 BOOLEAN bVLANPkt;
2271 PQUEUE_ENTRY pQEntry;
2272
2273
2274 ASSERT(pTxBlk);
2275
2276 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2277 pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2278 if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
2279 {
2280 RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
2281 return;
2282 }
2283
2284 ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag));
2285 bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
2286
2287 STAFindCipherAlgorithm(pAd, pTxBlk);
2288 STABuildCommon802_11Header(pAd, pTxBlk);
2289
2290 if (pTxBlk->CipherAlg == CIPHER_TKIP)
2291 {
2292 pTxBlk->pPacket = duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
2293 if (pTxBlk->pPacket == NULL)
2294 return;
2295 RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
2296 }
2297
2298 // skip 802.3 header
2299 pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
2300 pTxBlk->SrcBufLen -= LENGTH_802_3;
2301
2302
2303 // skip vlan tag
2304 if (bVLANPkt)
2305 {
2306 pTxBlk->pSrcBufData += LENGTH_802_1Q;
2307 pTxBlk->SrcBufLen -= LENGTH_802_1Q;
2308 }
2309
2310 pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
2311 pHeader_802_11 = (HEADER_802_11 *)pHeaderBufPtr;
2312
2313
2314 // skip common header
2315 pHeaderBufPtr += pTxBlk->MpduHeaderLen;
2316
2317 if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
2318 {
2319 //
2320 // build QOS Control bytes
2321 //
2322 *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
2323
2324 *(pHeaderBufPtr+1) = 0;
2325 pHeaderBufPtr +=2;
2326 pTxBlk->MpduHeaderLen += 2;
2327 }
2328
2329 //
2330 // padding at front of LLC header
2331 // LLC header should locate at 4-octets aligment
2332 //
2333 pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
2334 pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
2335 pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
2336
2337
2338
2339 //
2340 // Insert LLC-SNAP encapsulation - 8 octets
2341 //
2342 //
2343 // if original Ethernet frame contains no LLC/SNAP,
2344 // then an extra LLC/SNAP encap is required
2345 //
2346 EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
2347 if (pTxBlk->pExtraLlcSnapEncap)
2348 {
2349 UCHAR vlan_size;
2350
2351 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
2352 pHeaderBufPtr += 6;
2353 // skip vlan tag
2354 vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
2355 // get 2 octets (TypeofLen)
2356 NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
2357 pHeaderBufPtr += 2;
2358 pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
2359 }
2360
2361
2362 // If TKIP is used and fragmentation is required. Driver has to
2363 // append TKIP MIC at tail of the scatter buffer
2364 // MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC
2365 if (pTxBlk->CipherAlg == CIPHER_TKIP)
2366 {
2367
2368 // NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust
2369 // to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress.
2370 NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen, &pAd->PrivateInfo.Tx.MIC[0], 8);
2371 //skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8);
2372 pTxBlk->SrcBufLen += 8;
2373 pTxBlk->TotalFrameLen += 8;
2374 pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
2375 }
2376
2377 //
2378 // calcuate the overhead bytes that encryption algorithm may add. This
2379 // affects the calculate of "duration" field
2380 //
2381 if ((pTxBlk->CipherAlg == CIPHER_WEP64) || (pTxBlk->CipherAlg == CIPHER_WEP128))
2382 EncryptionOverhead = 8; //WEP: IV[4] + ICV[4];
2383 else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
2384 EncryptionOverhead = 12;//TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength
2385 else if (pTxBlk->CipherAlg == CIPHER_TKIP)
2386 EncryptionOverhead = 20;//TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8]
2387 else if (pTxBlk->CipherAlg == CIPHER_AES)
2388 EncryptionOverhead = 16; // AES: IV[4] + EIV[4] + MIC[8]
2389 else
2390 EncryptionOverhead = 0;
2391
2392 // decide how much time an ACK/CTS frame will consume in the air
2393 AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14);
2394
2395 // Init the total payload length of this frame.
2396 SrcRemainingBytes = pTxBlk->SrcBufLen;
2397
2398 pTxBlk->TotalFragNum = 0xff;
2399
2400 do {
2401
2402 FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC;
2403
2404 FreeMpduSize -= pTxBlk->MpduHeaderLen;
2405
2406 if (SrcRemainingBytes <= FreeMpduSize)
2407 { // this is the last or only fragment
2408
2409 pTxBlk->SrcBufLen = SrcRemainingBytes;
2410
2411 pHeader_802_11->FC.MoreFrag = 0;
2412 pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + AckDuration;
2413
2414 // Indicate the lower layer that this's the last fragment.
2415 pTxBlk->TotalFragNum = fragNum;
2416 }
2417 else
2418 { // more fragment is required
2419
2420 pTxBlk->SrcBufLen = FreeMpduSize;
2421
2422 NextMpduSize = min(((UINT)SrcRemainingBytes - pTxBlk->SrcBufLen), ((UINT)pAd->CommonCfg.FragmentThreshold));
2423 pHeader_802_11->FC.MoreFrag = 1;
2424 pHeader_802_11->Duration = (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) + RTMPCalcDuration(pAd, pTxBlk->TxRate, NextMpduSize + EncryptionOverhead);
2425 }
2426
2427 if (fragNum == 0)
2428 pTxBlk->FrameGap = IFS_HTTXOP;
2429 else
2430 pTxBlk->FrameGap = IFS_SIFS;
2431
2432 RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
2433
2434 HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);
2435
2436 pAd->RalinkCounters.KickTxCount++;
2437 pAd->RalinkCounters.OneSecTxDoneCount++;
2438
2439 // Update the frame number, remaining size of the NDIS packet payload.
2440
2441 // space for 802.11 header.
2442 if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
2443 pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;
2444
2445 fragNum++;
2446 SrcRemainingBytes -= pTxBlk->SrcBufLen;
2447 pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;
2448
2449 pHeader_802_11->Frag++; // increase Frag #
2450
2451 }while(SrcRemainingBytes > 0);
2452
2453 //
2454 // Kick out Tx
2455 //
2456 HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
2457}
2458
2459
2460#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) \
2461 while(_pTxBlk->TxPacketList.Head) \
2462 { \
2463 _pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList); \
2464 RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status); \
2465 }
2466
2467
2468/*
2469 ========================================================================
2470
2471 Routine Description:
2472 Copy frame from waiting queue into relative ring buffer and set
2473 appropriate ASIC register to kick hardware encryption before really
2474 sent out to air.
2475
2476 Arguments:
2477 pAd Pointer to our adapter
2478 PNDIS_PACKET Pointer to outgoing Ndis frame
2479 NumberOfFrag Number of fragment required
2480
2481 Return Value:
2482 None
2483
2484 IRQL = DISPATCH_LEVEL
2485
2486 Note:
2487
2488 ========================================================================
2489*/
2490NDIS_STATUS STAHardTransmit(
2491 IN PRTMP_ADAPTER pAd,
2492 IN TX_BLK *pTxBlk,
2493 IN UCHAR QueIdx)
2494{
2495 NDIS_PACKET *pPacket;
2496 PQUEUE_ENTRY pQEntry;
2497
2498 // ---------------------------------------------
2499 // STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION.
2500 // ---------------------------------------------
2501 //
2502 ASSERT(pTxBlk->TxPacketList.Number);
2503 if (pTxBlk->TxPacketList.Head == NULL)
2504 {
2505 DBGPRINT(RT_DEBUG_ERROR, ("pTxBlk->TotalFrameNum == %ld!\n", pTxBlk->TxPacketList.Number));
2506 return NDIS_STATUS_FAILURE;
2507 }
2508
2509 pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);
2510
2511#if 0 //def CARRIER_DETECTION_SUPPORT // Roger sync Carrier
2512 if ((pAd->CommonCfg.CarrierDetect.Enable == TRUE) && (isCarrierDetectExist(pAd) == TRUE))
2513 {
2514 DBGPRINT(RT_DEBUG_INFO,("STAHardTransmit --> radar detect not in normal mode !!!\n"));
2515 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
2516 return (NDIS_STATUS_FAILURE);
2517 }
2518#endif // CARRIER_DETECTION_SUPPORT //
2519
2520 // ------------------------------------------------------------------
2521 // STEP 1. WAKE UP PHY
2522 // outgoing frame always wakeup PHY to prevent frame lost and
2523 // turn off PSM bit to improve performance
2524 // ------------------------------------------------------------------
2525 // not to change PSM bit, just send this frame out?
2526 if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
2527 {
2528 DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicForceWakeup At HardTx\n"));
2529 AsicForceWakeup(pAd, TRUE);
2530 }
2531
2532 // It should not change PSM bit, when APSD turn on.
2533 if ((!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
2534 || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
2535 || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket)))
2536 {
2537 if ((pAd->StaCfg.Psm == PWR_SAVE) &&
2538 (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP))
2539 MlmeSetPsmBit(pAd, PWR_ACTIVE);
2540 }
2541
2542 switch (pTxBlk->TxFrameType)
2543 {
2544#ifdef DOT11_N_SUPPORT
2545 case TX_AMPDU_FRAME:
2546 STA_AMPDU_Frame_Tx(pAd, pTxBlk);
2547 break;
2548 case TX_AMSDU_FRAME:
2549 STA_AMSDU_Frame_Tx(pAd, pTxBlk);
2550 break;
2551#endif // DOT11_N_SUPPORT //
2552 case TX_LEGACY_FRAME:
2553 STA_Legacy_Frame_Tx(pAd, pTxBlk);
2554 break;
2555 case TX_MCAST_FRAME:
2556 STA_Legacy_Frame_Tx(pAd, pTxBlk);
2557 break;
2558 case TX_RALINK_FRAME:
2559 STA_ARalink_Frame_Tx(pAd, pTxBlk);
2560 break;
2561 case TX_FRAG_FRAME:
2562 STA_Fragment_Frame_Tx(pAd, pTxBlk);
2563 break;
2564 default:
2565 {
2566 // It should not happened!
2567 DBGPRINT(RT_DEBUG_ERROR, ("Send a pacekt was not classified!! It should not happen!\n"));
2568 while(pTxBlk->TxPacketList.Number)
2569 {
2570 pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
2571 pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
2572 if (pPacket)
2573 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
2574 }
2575 }
2576 break;
2577 }
2578
2579 return (NDIS_STATUS_SUCCESS);
2580
2581}
2582
2583ULONG HashBytesPolynomial(UCHAR *value, unsigned int len)
2584{
2585 unsigned char *word = value;
2586 unsigned int ret = 0;
2587 unsigned int i;
2588
2589 for(i=0; i < len; i++)
2590 {
2591 int mod = i % 32;
2592 ret ^=(unsigned int) (word[i]) << mod;
2593 ret ^=(unsigned int) (word[i]) >> (32 - mod);
2594 }
2595 return ret;
2596}
2597
2598VOID Sta_Announce_or_Forward_802_3_Packet(
2599 IN PRTMP_ADAPTER pAd,
2600 IN PNDIS_PACKET pPacket,
2601 IN UCHAR FromWhichBSSID)
2602{
2603 if (TRUE
2604 )
2605 {
2606 announce_802_3_packet(pAd, pPacket);
2607 }
2608 else
2609 {
2610 // release packet
2611 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
2612 }
2613}
2614
diff --git a/drivers/staging/rt2860/sta/sanity.c b/drivers/staging/rt2860/sta/sanity.c
new file mode 100644
index 00000000000..239872464be
--- /dev/null
+++ b/drivers/staging/rt2860/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/rt2860/sta/sync.c b/drivers/staging/rt2860/sta/sync.c
new file mode 100644
index 00000000000..a94b4b7330e
--- /dev/null
+++ b/drivers/staging/rt2860/sta/sync.c
@@ -0,0 +1,1961 @@
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 AC0_DEF_TXOP 0
41#define AC1_DEF_TXOP 0
42#define AC2_DEF_TXOP 94
43#define AC3_DEF_TXOP 47
44
45VOID AdhocTurnOnQos(
46 IN PRTMP_ADAPTER pAd)
47{
48 // Turn on QOs if use HT rate.
49 if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
50 {
51 pAd->CommonCfg.APEdcaParm.bValid = TRUE;
52 pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
53 pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
54 pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
55 pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
56
57 pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
58 pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
59 pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
60 pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
61
62 pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
63 pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
64 pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
65 pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
66
67 pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
68 pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
69 pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
70 pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
71 }
72 AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
73}
74
75/*
76 ==========================================================================
77 Description:
78 The sync state machine,
79 Parameters:
80 Sm - pointer to the state machine
81 Note:
82 the state machine looks like the following
83
84 ==========================================================================
85 */
86VOID SyncStateMachineInit(
87 IN PRTMP_ADAPTER pAd,
88 IN STATE_MACHINE *Sm,
89 OUT STATE_MACHINE_FUNC Trans[])
90{
91 StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE);
92
93 // column 1
94 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction);
95 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction);
96 StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction);
97 StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon);
98 StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction);
99
100 //column 2
101 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
102 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
103 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
104 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction);
105 StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction);
106
107 // column 3
108 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
109 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
110 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
111 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
112 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
113 StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction);
114
115 // timer init
116 RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
117 RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
118}
119
120/*
121 ==========================================================================
122 Description:
123 Beacon timeout handler, executed in timer thread
124
125 IRQL = DISPATCH_LEVEL
126
127 ==========================================================================
128 */
129VOID BeaconTimeout(
130 IN PVOID SystemSpecific1,
131 IN PVOID FunctionContext,
132 IN PVOID SystemSpecific2,
133 IN PVOID SystemSpecific3)
134{
135 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
136
137 DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n"));
138
139 // Do nothing if the driver is starting halt state.
140 // This might happen when timer already been fired before cancel timer with mlmehalt
141 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
142 return;
143
144#ifdef DOT11_N_SUPPORT
145 if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
146 )
147 {
148 UCHAR BBPValue = 0;
149 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
150 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
151 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
152 BBPValue &= (~0x18);
153 BBPValue |= 0x10;
154 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
155 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
156 }
157#endif // DOT11_N_SUPPORT //
158
159 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
160 RT28XX_MLME_HANDLER(pAd);
161}
162
163/*
164 ==========================================================================
165 Description:
166 Scan timeout handler, executed in timer thread
167
168 IRQL = DISPATCH_LEVEL
169
170 ==========================================================================
171 */
172VOID ScanTimeout(
173 IN PVOID SystemSpecific1,
174 IN PVOID FunctionContext,
175 IN PVOID SystemSpecific2,
176 IN PVOID SystemSpecific3)
177{
178 RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
179
180
181 // Do nothing if the driver is starting halt state.
182 // This might happen when timer already been fired before cancel timer with mlmehalt
183 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
184 return;
185
186 if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL))
187 {
188 RT28XX_MLME_HANDLER(pAd);
189 }
190 else
191 {
192 // To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
193 pAd->MlmeAux.Channel = 0;
194 ScanNextChannel(pAd);
195 if (pAd->CommonCfg.bWirelessEvent)
196 {
197 RTMPSendWirelessEvent(pAd, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
198 }
199 }
200}
201
202/*
203 ==========================================================================
204 Description:
205 MLME SCAN req state machine procedure
206 ==========================================================================
207 */
208VOID MlmeScanReqAction(
209 IN PRTMP_ADAPTER pAd,
210 IN MLME_QUEUE_ELEM *Elem)
211{
212 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
213 BOOLEAN TimerCancelled;
214 ULONG Now;
215 USHORT Status;
216 PHEADER_802_11 pHdr80211;
217 PUCHAR pOutBuffer = NULL;
218 NDIS_STATUS NStatus;
219
220 // Check the total scan tries for one single OID command
221 // If this is the CCX 2.0 Case, skip that!
222 if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
223 {
224 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n"));
225 return;
226 }
227
228 // Increase the scan retry counters.
229 pAd->StaCfg.ScanCnt++;
230
231#ifdef RT2860
232 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
233 (IDLE_ON(pAd)) &&
234 (pAd->StaCfg.bRadio == TRUE) &&
235 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
236 {
237 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
238 }
239#endif // RT2860 //
240
241 // first check the parameter sanity
242 if (MlmeScanReqSanity(pAd,
243 Elem->Msg,
244 Elem->MsgLen,
245 &BssType,
246 Ssid,
247 &SsidLen,
248 &ScanType))
249 {
250
251 // Check for channel load and noise hist request
252 // Suspend MSDU only at scan request, not the last two mentioned
253 if ((ScanType == SCAN_CISCO_NOISE) || (ScanType == SCAN_CISCO_CHANNEL_LOAD))
254 {
255 if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
256 RTMPSuspendMsduTransmission(pAd); // Suspend MSDU transmission here
257 }
258 else
259 {
260 // Suspend MSDU transmission here
261 RTMPSuspendMsduTransmission(pAd);
262 }
263
264 //
265 // To prevent data lost.
266 // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
267 // And should send an NULL data with turned PSM bit off to AP, when scan progress done
268 //
269 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
270 {
271 NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
272 if (NStatus == NDIS_STATUS_SUCCESS)
273 {
274 pHdr80211 = (PHEADER_802_11) pOutBuffer;
275 MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
276 pHdr80211->Duration = 0;
277 pHdr80211->FC.Type = BTYPE_DATA;
278 pHdr80211->FC.PwrMgmt = PWR_SAVE;
279
280 // Send using priority queue
281 MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
282 DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
283 MlmeFreeMemory(pAd, pOutBuffer);
284 RTMPusecDelay(5000);
285 }
286 }
287
288 NdisGetSystemUpTime(&Now);
289 pAd->StaCfg.LastScanTime = Now;
290 // reset all the timers
291 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
292 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
293
294 // record desired BSS parameters
295 pAd->MlmeAux.BssType = BssType;
296 pAd->MlmeAux.ScanType = ScanType;
297 pAd->MlmeAux.SsidLen = SsidLen;
298 NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
299 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
300
301 // start from the first channel
302 pAd->MlmeAux.Channel = FirstChannel(pAd);
303
304 // Change the scan channel when dealing with CCX beacon report
305 if ((ScanType == SCAN_CISCO_PASSIVE) || (ScanType == SCAN_CISCO_ACTIVE) ||
306 (ScanType == SCAN_CISCO_CHANNEL_LOAD) || (ScanType == SCAN_CISCO_NOISE))
307 pAd->MlmeAux.Channel = pAd->StaCfg.CCXScanChannel;
308
309 // Let BBP register at 20MHz to do scan
310 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
311 BBPValue &= (~0x18);
312 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
313 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
314 ScanNextChannel(pAd);
315 }
316 else
317 {
318 DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
319 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
320 Status = MLME_INVALID_FORMAT;
321 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
322 }
323}
324
325/*
326 ==========================================================================
327 Description:
328 MLME JOIN req state machine procedure
329 ==========================================================================
330 */
331VOID MlmeJoinReqAction(
332 IN PRTMP_ADAPTER pAd,
333 IN MLME_QUEUE_ELEM *Elem)
334{
335 UCHAR BBPValue = 0;
336 BSS_ENTRY *pBss;
337 BOOLEAN TimerCancelled;
338 HEADER_802_11 Hdr80211;
339 NDIS_STATUS NStatus;
340 ULONG FrameLen = 0;
341 PUCHAR pOutBuffer = NULL;
342 PUCHAR pSupRate = NULL;
343 UCHAR SupRateLen;
344 PUCHAR pExtRate = NULL;
345 UCHAR ExtRateLen;
346 UCHAR ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
347 UCHAR ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR);
348 MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg);
349
350 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
351
352#ifdef RT2860
353 if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
354 (IDLE_ON(pAd)) &&
355 (pAd->StaCfg.bRadio == TRUE) &&
356 (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
357 {
358 RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
359 }
360#endif // RT2860 //
361
362 // reset all the timers
363 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
364 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
365
366 pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
367
368 // record the desired SSID & BSSID we're waiting for
369 COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
370
371 // If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
372 if (pBss->Hidden == 0)
373 {
374 NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
375 pAd->MlmeAux.SsidLen = pBss->SsidLen;
376 }
377
378 pAd->MlmeAux.BssType = pBss->BssType;
379 pAd->MlmeAux.Channel = pBss->Channel;
380 pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
381
382#ifdef EXT_BUILD_CHANNEL_LIST
383 // Country IE of the AP will be evaluated and will be used.
384 if ((pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None) &&
385 (pBss->bHasCountryIE == TRUE))
386 {
387 NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pBss->CountryString[0], 2);
388 if (pBss->CountryString[2] == 'I')
389 pAd->CommonCfg.Geography = IDOR;
390 else if (pBss->CountryString[2] == 'O')
391 pAd->CommonCfg.Geography = ODOR;
392 else
393 pAd->CommonCfg.Geography = BOTH;
394 BuildChannelListEx(pAd);
395 }
396#endif // EXT_BUILD_CHANNEL_LIST //
397
398 // Let BBP register at 20MHz to do scan
399 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
400 BBPValue &= (~0x18);
401 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
402 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
403
404 // switch channel and waiting for beacon timer
405 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
406 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
407 RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
408
409 do
410 {
411 if (((pAd->CommonCfg.bIEEE80211H == 1) &&
412 (pAd->MlmeAux.Channel > 14) &&
413 RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
414#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
415 || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
416#endif // CARRIER_DETECTION_SUPPORT //
417 )
418 {
419 //
420 // We can't send any Probe request frame to meet 802.11h.
421 //
422 if (pBss->Hidden == 0)
423 break;
424 }
425
426 //
427 // send probe request
428 //
429 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
430 if (NStatus == NDIS_STATUS_SUCCESS)
431 {
432 if (pAd->MlmeAux.Channel <= 14)
433 {
434 pSupRate = pAd->CommonCfg.SupRate;
435 SupRateLen = pAd->CommonCfg.SupRateLen;
436 pExtRate = pAd->CommonCfg.ExtRate;
437 ExtRateLen = pAd->CommonCfg.ExtRateLen;
438 }
439 else
440 {
441 //
442 // Overwrite Support Rate, CCK rate are not allowed
443 //
444 pSupRate = ASupRate;
445 SupRateLen = ASupRateLen;
446 ExtRateLen = 0;
447 }
448
449 if (pAd->MlmeAux.BssType == BSS_INFRA)
450 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, pAd->MlmeAux.Bssid);
451 else
452 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
453
454 MakeOutgoingFrame(pOutBuffer, &FrameLen,
455 sizeof(HEADER_802_11), &Hdr80211,
456 1, &SsidIe,
457 1, &pAd->MlmeAux.SsidLen,
458 pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
459 1, &SupRateIe,
460 1, &SupRateLen,
461 SupRateLen, pSupRate,
462 END_OF_ARGS);
463
464 if (ExtRateLen)
465 {
466 ULONG Tmp;
467 MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
468 1, &ExtRateIe,
469 1, &ExtRateLen,
470 ExtRateLen, pExtRate,
471 END_OF_ARGS);
472 FrameLen += Tmp;
473 }
474
475
476 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
477 MlmeFreeMemory(pAd, pOutBuffer);
478 }
479 } while (FALSE);
480
481 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
482 pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
483
484 pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
485}
486
487/*
488 ==========================================================================
489 Description:
490 MLME START Request state machine procedure, starting an IBSS
491 ==========================================================================
492 */
493VOID MlmeStartReqAction(
494 IN PRTMP_ADAPTER pAd,
495 IN MLME_QUEUE_ELEM *Elem)
496{
497 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen;
498 BOOLEAN TimerCancelled;
499
500 // New for WPA security suites
501 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
502 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
503 LARGE_INTEGER TimeStamp;
504 BOOLEAN Privacy;
505 USHORT Status;
506
507 // Init Variable IE structure
508 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
509 pVIE->Length = 0;
510 TimeStamp.u.LowPart = 0;
511 TimeStamp.u.HighPart = 0;
512
513 if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, Ssid, &SsidLen))
514 {
515 // reset all the timers
516 RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
517 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
518
519 //
520 // Start a new IBSS. All IBSS parameters are decided now....
521 //
522 DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
523 pAd->MlmeAux.BssType = BSS_ADHOC;
524 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
525 pAd->MlmeAux.SsidLen = SsidLen;
526
527 // generate a radom number as BSSID
528 MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
529 DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
530
531 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
532 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
533 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
534 pAd->MlmeAux.CapabilityInfo = CAP_GENERATE(0,1,Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 1, 0);
535 pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
536 pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin;
537 pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
538
539 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
540 pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
541
542 pAd->MlmeAux.SupRateLen= pAd->CommonCfg.SupRateLen;
543 NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
544 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
545 pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
546 NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
547 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
548#ifdef DOT11_N_SUPPORT
549 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
550 {
551 RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
552 pAd->MlmeAux.HtCapabilityLen = sizeof(HT_CAPABILITY_IE);
553 // Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
554 DBGPRINT(RT_DEBUG_TRACE, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
555 }
556 else
557#endif // DOT11_N_SUPPORT //
558 {
559 pAd->MlmeAux.HtCapabilityLen = 0;
560 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
561 }
562 // temporarily not support QOS in IBSS
563 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
564 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
565 NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
566
567 AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
568 AsicLockChannel(pAd, pAd->MlmeAux.Channel);
569
570 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
571 pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
572
573 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
574 Status = MLME_SUCCESS;
575 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
576 }
577 else
578 {
579 DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
580 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
581 Status = MLME_INVALID_FORMAT;
582 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
583 }
584}
585
586/*
587 ==========================================================================
588 Description:
589 peer sends beacon back when scanning
590 ==========================================================================
591 */
592VOID PeerBeaconAtScanAction(
593 IN PRTMP_ADAPTER pAd,
594 IN MLME_QUEUE_ELEM *Elem)
595{
596 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
597 UCHAR Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
598 SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
599 CF_PARM CfParm;
600 USHORT BeaconPeriod, AtimWin, CapabilityInfo;
601 PFRAME_802_11 pFrame;
602 LARGE_INTEGER TimeStamp;
603 UCHAR Erp;
604 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
605 UCHAR SupRateLen, ExtRateLen;
606 USHORT LenVIE;
607 UCHAR CkipFlag;
608 UCHAR AironetCellPowerLimit;
609 EDCA_PARM EdcaParm;
610 QBSS_LOAD_PARM QbssLoad;
611 QOS_CAPABILITY_PARM QosCapability;
612 ULONG RalinkIe;
613 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
614 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
615 HT_CAPABILITY_IE HtCapability;
616 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
617 UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
618 UCHAR AddHtInfoLen;
619 UCHAR NewExtChannelOffset = 0xff;
620
621 pFrame = (PFRAME_802_11) Elem->Msg;
622 // Init Variable IE structure
623 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
624 pVIE->Length = 0;
625#ifdef DOT11_N_SUPPORT
626 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
627 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
628#endif // DOT11_N_SUPPORT //
629
630 if (PeerBeaconAndProbeRspSanity(pAd,
631 Elem->Msg,
632 Elem->MsgLen,
633 Elem->Channel,
634 Addr2,
635 Bssid,
636 Ssid,
637 &SsidLen,
638 &BssType,
639 &BeaconPeriod,
640 &Channel,
641 &NewChannel,
642 &TimeStamp,
643 &CfParm,
644 &AtimWin,
645 &CapabilityInfo,
646 &Erp,
647 &DtimCount,
648 &DtimPeriod,
649 &BcastFlag,
650 &MessageToMe,
651 SupRate,
652 &SupRateLen,
653 ExtRate,
654 &ExtRateLen,
655 &CkipFlag,
656 &AironetCellPowerLimit,
657 &EdcaParm,
658 &QbssLoad,
659 &QosCapability,
660 &RalinkIe,
661 &HtCapabilityLen,
662 &PreNHtCapabilityLen,
663 &HtCapability,
664 &AddHtInfoLen,
665 &AddHtInfo,
666 &NewExtChannelOffset,
667 &LenVIE,
668 pVIE))
669 {
670 ULONG Idx;
671 CHAR Rssi = 0;
672
673 Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
674 if (Idx != BSS_NOT_FOUND)
675 Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
676
677 Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
678
679
680#ifdef DOT11_N_SUPPORT
681 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
682 HtCapabilityLen = SIZE_HT_CAP_IE;
683#endif // DOT11_N_SUPPORT //
684 if ((pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) && (Channel == pAd->StaCfg.CCXScanChannel))
685 {
686 Idx = BssTableSetEntry(pAd, &pAd->StaCfg.CCXBssTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
687 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen,ExtRate, ExtRateLen, &HtCapability,
688 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
689 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
690 if (Idx != BSS_NOT_FOUND)
691 {
692 NdisMoveMemory(pAd->StaCfg.CCXBssTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
693 NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
694 NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
695 if (pAd->StaCfg.CCXReqType == MSRN_TYPE_BEACON_REQ)
696 AironetAddBeaconReport(pAd, Idx, Elem);
697 }
698 }
699 else
700 {
701 Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
702 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
703 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
704 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
705#ifdef DOT11_N_SUPPORT
706#ifdef DOT11N_DRAFT3
707 if (pAd->ChannelList[pAd->CommonCfg.ChannelListIdx].bEffectedChannel == TRUE)
708 {
709 UCHAR RegClass;
710 PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &RegClass);
711 TriEventTableSetEntry(pAd, &pAd->CommonCfg.TriggerEventTab, Bssid, &HtCapability, HtCapabilityLen, RegClass, Channel);
712 }
713#endif // DOT11N_DRAFT3 //
714#endif // DOT11_N_SUPPORT //
715 if (Idx != BSS_NOT_FOUND)
716 {
717 NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
718 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
719 NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
720 }
721 }
722 }
723 // sanity check fail, ignored
724}
725
726/*
727 ==========================================================================
728 Description:
729 When waiting joining the (I)BSS, beacon received from external
730 ==========================================================================
731 */
732VOID PeerBeaconAtJoinAction(
733 IN PRTMP_ADAPTER pAd,
734 IN MLME_QUEUE_ELEM *Elem)
735{
736 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
737 UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
738 DtimCount, DtimPeriod, BcastFlag, NewChannel;
739 LARGE_INTEGER TimeStamp;
740 USHORT BeaconPeriod, AtimWin, CapabilityInfo;
741 CF_PARM Cf;
742 BOOLEAN TimerCancelled;
743 UCHAR Erp;
744 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
745 UCHAR SupRateLen, ExtRateLen;
746 UCHAR CkipFlag;
747 USHORT LenVIE;
748 UCHAR AironetCellPowerLimit;
749 EDCA_PARM EdcaParm;
750 QBSS_LOAD_PARM QbssLoad;
751 QOS_CAPABILITY_PARM QosCapability;
752 USHORT Status;
753 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
754 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
755 ULONG RalinkIe;
756 ULONG Idx;
757 HT_CAPABILITY_IE HtCapability;
758 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
759 UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
760 UCHAR AddHtInfoLen;
761 UCHAR NewExtChannelOffset = 0xff;
762#ifdef DOT11_N_SUPPORT
763 UCHAR CentralChannel;
764#endif // DOT11_N_SUPPORT //
765
766 // Init Variable IE structure
767 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
768 pVIE->Length = 0;
769 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
770 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
771
772
773 if (PeerBeaconAndProbeRspSanity(pAd,
774 Elem->Msg,
775 Elem->MsgLen,
776 Elem->Channel,
777 Addr2,
778 Bssid,
779 Ssid,
780 &SsidLen,
781 &BssType,
782 &BeaconPeriod,
783 &Channel,
784 &NewChannel,
785 &TimeStamp,
786 &Cf,
787 &AtimWin,
788 &CapabilityInfo,
789 &Erp,
790 &DtimCount,
791 &DtimPeriod,
792 &BcastFlag,
793 &MessageToMe,
794 SupRate,
795 &SupRateLen,
796 ExtRate,
797 &ExtRateLen,
798 &CkipFlag,
799 &AironetCellPowerLimit,
800 &EdcaParm,
801 &QbssLoad,
802 &QosCapability,
803 &RalinkIe,
804 &HtCapabilityLen,
805 &PreNHtCapabilityLen,
806 &HtCapability,
807 &AddHtInfoLen,
808 &AddHtInfo,
809 &NewExtChannelOffset,
810 &LenVIE,
811 pVIE))
812 {
813 // Disqualify 11b only adhoc when we are in 11g only adhoc mode
814 if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12))
815 return;
816
817 // BEACON from desired BSS/IBSS found. We should be able to decide most
818 // BSS parameters here.
819 // Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
820 // Do we need to receover back all parameters belonging to previous BSS?
821 // A. Should be not. There's no back-door recover to previous AP. It still need
822 // a new JOIN-AUTH-ASSOC sequence.
823 if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid))
824 {
825 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel));
826 RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
827
828 // Update RSSI to prevent No signal display when cards first initialized
829 pAd->StaCfg.RssiSample.LastRssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
830 pAd->StaCfg.RssiSample.LastRssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
831 pAd->StaCfg.RssiSample.LastRssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
832 pAd->StaCfg.RssiSample.AvgRssi0 = pAd->StaCfg.RssiSample.LastRssi0;
833 pAd->StaCfg.RssiSample.AvgRssi0X8 = pAd->StaCfg.RssiSample.AvgRssi0 << 3;
834 pAd->StaCfg.RssiSample.AvgRssi1 = pAd->StaCfg.RssiSample.LastRssi1;
835 pAd->StaCfg.RssiSample.AvgRssi1X8 = pAd->StaCfg.RssiSample.AvgRssi1 << 3;
836 pAd->StaCfg.RssiSample.AvgRssi2 = pAd->StaCfg.RssiSample.LastRssi2;
837 pAd->StaCfg.RssiSample.AvgRssi2X8 = pAd->StaCfg.RssiSample.AvgRssi2 << 3;
838
839 //
840 // We need to check if SSID only set to any, then we can record the current SSID.
841 // Otherwise will cause hidden SSID association failed.
842 //
843 if (pAd->MlmeAux.SsidLen == 0)
844 {
845 NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
846 pAd->MlmeAux.SsidLen = SsidLen;
847 }
848 else
849 {
850 Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel);
851
852 if (Idx != BSS_NOT_FOUND)
853 {
854 //
855 // Multiple SSID case, used correct CapabilityInfo
856 //
857 CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
858 }
859 }
860 NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
861 pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
862 pAd->MlmeAux.BssType = BssType;
863 pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
864 pAd->MlmeAux.Channel = Channel;
865 pAd->MlmeAux.AtimWin = AtimWin;
866 pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
867 pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
868 pAd->MlmeAux.APRalinkIe = RalinkIe;
869
870 // Copy AP's supported rate to MlmeAux for creating assoication request
871 // Also filter out not supported rate
872 pAd->MlmeAux.SupRateLen = SupRateLen;
873 NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
874 RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
875 pAd->MlmeAux.ExtRateLen = ExtRateLen;
876 NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
877 RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
878
879 NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16);
880#ifdef DOT11_N_SUPPORT
881 pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
882 pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
883
884 // filter out un-supported ht rates
885 if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
886 {
887 RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
888 RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE);
889
890 // StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
891 NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
892 pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
893 pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
894 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
895 if (PreNHtCapabilityLen > 0)
896 pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE;
897 RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo);
898 // Copy AP Parameter to StaActive. This is also in LinkUp.
899 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
900 pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth));
901
902 if (AddHtInfoLen > 0)
903 {
904 CentralChannel = AddHtInfo.ControlChan;
905 // Check again the Bandwidth capability of this AP.
906 if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
907 {
908 CentralChannel = AddHtInfo.ControlChan - 2;
909 }
910 else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
911 {
912 CentralChannel = AddHtInfo.ControlChan + 2;
913 }
914
915 // Check Error .
916 if (pAd->MlmeAux.CentralChannel != CentralChannel)
917 DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel));
918
919 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, AddHtInfo.ControlChan));
920
921 }
922
923 }
924 else
925#endif // DOT11_N_SUPPORT //
926 {
927 // To prevent error, let legacy AP must have same CentralChannel and Channel.
928 if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0))
929 pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel;
930
931 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
932 RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
933 RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
934 }
935
936 RTMPUpdateMlmeRate(pAd);
937
938 // copy QOS related information
939 if ((pAd->CommonCfg.bWmmCapable)
940#ifdef DOT11_N_SUPPORT
941 || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
942#endif // DOT11_N_SUPPORT //
943 )
944 {
945 NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM));
946 NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
947 NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
948 }
949 else
950 {
951 NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
952 NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
953 NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
954 }
955
956 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
957 pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
958
959#ifdef LEAP_SUPPORT
960 // Update CkipFlag
961 pAd->StaCfg.CkipFlag = CkipFlag;
962
963 // Keep TimeStamp for Re-Association used.
964 if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
965 pAd->StaCfg.CCKMBeaconAtJoinTimeStamp = TimeStamp;
966#endif // LEAP_SUPPORT //
967
968 if (AironetCellPowerLimit != 0xFF)
969 {
970 //We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
971 ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
972 }
973 else //Used the default TX Power Percentage.
974 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
975
976 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
977 Status = MLME_SUCCESS;
978 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
979 }
980 // not to me BEACON, ignored
981 }
982 // sanity check fail, ignore this frame
983}
984
985/*
986 ==========================================================================
987 Description:
988 receive BEACON from peer
989
990 IRQL = DISPATCH_LEVEL
991
992 ==========================================================================
993 */
994VOID PeerBeacon(
995 IN PRTMP_ADAPTER pAd,
996 IN MLME_QUEUE_ELEM *Elem)
997{
998 UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
999 CHAR Ssid[MAX_LEN_OF_SSID];
1000 CF_PARM CfParm;
1001 UCHAR SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0;
1002 UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0;
1003 USHORT CapabilityInfo, AtimWin, BeaconPeriod;
1004 LARGE_INTEGER TimeStamp;
1005 USHORT TbttNumToNextWakeUp;
1006 UCHAR Erp;
1007 UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
1008 UCHAR SupRateLen, ExtRateLen;
1009 UCHAR CkipFlag;
1010 USHORT LenVIE;
1011 UCHAR AironetCellPowerLimit;
1012 EDCA_PARM EdcaParm;
1013 QBSS_LOAD_PARM QbssLoad;
1014 QOS_CAPABILITY_PARM QosCapability;
1015 ULONG RalinkIe;
1016 // New for WPA security suites
1017 UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
1018 NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
1019 HT_CAPABILITY_IE HtCapability;
1020 ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
1021 UCHAR HtCapabilityLen, PreNHtCapabilityLen;
1022 UCHAR AddHtInfoLen;
1023 UCHAR NewExtChannelOffset = 0xff;
1024
1025
1026#ifdef RALINK_ATE
1027 if (ATE_ON(pAd))
1028 {
1029 return;
1030 }
1031#endif // RALINK_ATE //
1032
1033 if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
1034 ))
1035 return;
1036
1037 // Init Variable IE structure
1038 pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
1039 pVIE->Length = 0;
1040 RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
1041 RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
1042
1043 if (PeerBeaconAndProbeRspSanity(pAd,
1044 Elem->Msg,
1045 Elem->MsgLen,
1046 Elem->Channel,
1047 Addr2,
1048 Bssid,
1049 Ssid,
1050 &SsidLen,
1051 &BssType,
1052 &BeaconPeriod,
1053 &Channel,
1054 &NewChannel,
1055 &TimeStamp,
1056 &CfParm,
1057 &AtimWin,
1058 &CapabilityInfo,
1059 &Erp,
1060 &DtimCount,
1061 &DtimPeriod,
1062 &BcastFlag,
1063 &MessageToMe,
1064 SupRate,
1065 &SupRateLen,
1066 ExtRate,
1067 &ExtRateLen,
1068 &CkipFlag,
1069 &AironetCellPowerLimit,
1070 &EdcaParm,
1071 &QbssLoad,
1072 &QosCapability,
1073 &RalinkIe,
1074 &HtCapabilityLen,
1075 &PreNHtCapabilityLen,
1076 &HtCapability,
1077 &AddHtInfoLen,
1078 &AddHtInfo,
1079 &NewExtChannelOffset,
1080 &LenVIE,
1081 pVIE))
1082 {
1083 BOOLEAN is_my_bssid, is_my_ssid;
1084 ULONG Bssidx, Now;
1085 BSS_ENTRY *pBss;
1086 CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
1087
1088 is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE;
1089 is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE;
1090
1091
1092 // ignore BEACON not for my SSID
1093 if ((! is_my_ssid) && (! is_my_bssid))
1094 return;
1095
1096 // It means STA waits disassoc completely from this AP, ignores this beacon.
1097 if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
1098 return;
1099
1100#ifdef DOT11_N_SUPPORT
1101 // Copy Control channel for this BSSID.
1102 if (AddHtInfoLen != 0)
1103 Channel = AddHtInfo.ControlChan;
1104
1105 if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
1106 HtCapabilityLen = SIZE_HT_CAP_IE;
1107#endif // DOT11_N_SUPPORT //
1108
1109 //
1110 // Housekeeping "SsidBssTab" table for later-on ROAMing usage.
1111 //
1112 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1113 if (Bssidx == BSS_NOT_FOUND)
1114 {
1115 // discover new AP of this network, create BSS entry
1116 Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
1117 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,
1118 &HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel,
1119 RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability,
1120 &QbssLoad, LenVIE, pVIE);
1121 if (Bssidx == BSS_NOT_FOUND) // return if BSS table full
1122 return;
1123
1124 NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4);
1125 NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
1126 NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
1127
1128
1129
1130 }
1131
1132 if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
1133 {
1134 // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
1135 // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
1136 AsicSwitchChannel(pAd, 1, FALSE);
1137 AsicLockChannel(pAd, 1);
1138 LinkDown(pAd, FALSE);
1139 MlmeQueueInit(&pAd->Mlme.Queue);
1140 BssTableInit(&pAd->ScanTab);
1141 RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
1142
1143 // channel sanity check
1144 for (index = 0 ; index < pAd->ChannelListNum; index++)
1145 {
1146 if (pAd->ChannelList[index].Channel == NewChannel)
1147 {
1148 pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
1149 pAd->CommonCfg.Channel = NewChannel;
1150 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1151 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1152 DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
1153 break;
1154 }
1155 }
1156
1157 if (index >= pAd->ChannelListNum)
1158 {
1159 DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
1160 }
1161 }
1162
1163 // if the ssid matched & bssid unmatched, we should select the bssid with large value.
1164 // This might happened when two STA start at the same time
1165 if ((! is_my_bssid) && ADHOC_ON(pAd))
1166 {
1167 INT i;
1168
1169 // Add the safeguard against the mismatch of adhoc wep status
1170 if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
1171 {
1172 return;
1173 }
1174
1175 // collapse into the ADHOC network which has bigger BSSID value.
1176 for (i = 0; i < 6; i++)
1177 {
1178 if (Bssid[i] > pAd->CommonCfg.Bssid[i])
1179 {
1180 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
1181 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
1182 AsicDisableSync(pAd);
1183 COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid);
1184 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1185 MakeIbssBeacon(pAd); // re-build BEACON frame
1186 AsicEnableIbssSync(pAd); // copy BEACON frame to on-chip memory
1187 is_my_bssid = TRUE;
1188 break;
1189 }
1190 else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
1191 break;
1192 }
1193 }
1194
1195
1196 NdisGetSystemUpTime(&Now);
1197 pBss = &pAd->ScanTab.BssEntry[Bssidx];
1198 pBss->Rssi = RealRssi; // lastest RSSI
1199 pBss->LastBeaconRxTime = Now; // last RX timestamp
1200
1201 //
1202 // BEACON from my BSSID - either IBSS or INFRA network
1203 //
1204 if (is_my_bssid)
1205 {
1206 RXWI_STRUC RxWI;
1207
1208 pAd->StaCfg.DtimCount = DtimCount;
1209 pAd->StaCfg.DtimPeriod = DtimPeriod;
1210 pAd->StaCfg.LastBeaconRxTime = Now;
1211
1212
1213 RxWI.RSSI0 = Elem->Rssi0;
1214 RxWI.RSSI1 = Elem->Rssi1;
1215 RxWI.RSSI2 = Elem->Rssi2;
1216
1217 Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
1218 if (AironetCellPowerLimit != 0xFF)
1219 {
1220 //
1221 // We get the Cisco (ccx) "TxPower Limit" required
1222 // Changed to appropriate TxPower Limit for Ciso Compatible Extensions
1223 //
1224 ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
1225 }
1226 else
1227 {
1228 //
1229 // AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
1230 // Used the default TX Power Percentage, that set from UI.
1231 //
1232 pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
1233 }
1234
1235 // at least one 11b peer joined. downgrade the MaxTxRate to 11Mbps
1236 // after last 11b peer left for several seconds, we'll auto switch back to 11G rate
1237 // in MlmePeriodicExec()
1238 if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
1239 {
1240 BOOLEAN bRestart;
1241 BOOLEAN bnRestart;
1242
1243 bRestart = FALSE;
1244 bnRestart = FALSE;
1245
1246 do
1247 {
1248 if ((SupRateLen+ExtRateLen <= 4) && (pAd->CommonCfg.MaxTxRate > RATE_11))
1249 {
1250 if (pAd->StaCfg.AdhocBOnlyJoined == FALSE)
1251 {
1252 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - 11b peer joined. down-grade to 11b TX rates \n"));
1253 bRestart = TRUE;
1254 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
1255 pAd->StaActive.SupRateLen = SupRateLen;
1256 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
1257 pAd->StaActive.ExtRateLen = ExtRateLen;
1258 pAd->StaCfg.AdhocBOnlyJoined = TRUE;
1259 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1260 AsicSetEdcaParm(pAd, NULL);
1261 }
1262
1263 // this timestamp is for MlmePeriodicExec() to check if all 11B peers have left
1264 pAd->StaCfg.Last11bBeaconRxTime = Now;
1265 break;
1266 }
1267#ifdef DOT11_N_SUPPORT
1268 // Update Ht Phy.
1269 if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
1270 {
1271 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
1272 !pAd->StaCfg.AdhocBGJoined &&
1273 !pAd->StaCfg.AdhocBOnlyJoined)
1274 AdhocTurnOnQos(pAd);
1275
1276 // Handle rate switch issue when Adhoc mode
1277 if ((SupRateLen+ExtRateLen >= 8) && (HtCapability.MCSSet[0] == 0) && (HtCapability.MCSSet[1] == 0))
1278 {
1279 if (pAd->StaCfg.AdhocBGJoined == FALSE)
1280 {
1281 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - 11g peer joined. down-grade to 11g TX rates \n"));
1282 bRestart = TRUE;
1283 NdisMoveMemory(pAd->StaActive.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
1284 pAd->StaActive.SupRateLen = SupRateLen;
1285 NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
1286 pAd->StaActive.ExtRateLen = ExtRateLen;
1287 pAd->StaCfg.AdhocBGJoined = TRUE;
1288 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
1289 AsicSetEdcaParm(pAd, NULL);
1290 }
1291
1292 // this timestamp is for MlmePeriodicExec() to check if all 11g peers have left
1293 pAd->StaCfg.Last11gBeaconRxTime = Now;
1294 break;
1295 }
1296 else if (!pAd->StaCfg.AdhocBGJoined &&
1297 !pAd->StaCfg.AdhocBOnlyJoined &&
1298 (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) &&
1299 (HtCapability.HtCapInfo.ChannelWidth == BW_20))
1300 {
1301 if (pAd->StaCfg.Adhoc20NJoined == FALSE)
1302 {
1303 UCHAR ByteValue = 0;
1304
1305 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1306
1307 pAd->StaCfg.Adhoc20NJoined = TRUE;
1308 NdisMoveMemory(&pAd->MlmeAux.HtCapability, &HtCapability, SIZE_HT_CAP_IE);
1309 if (AddHtInfoLen != 0)
1310 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, AddHtInfoLen);
1311 NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
1312
1313 RTMPCheckHt(pAd, Elem->Wcid, &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
1314 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1315 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
1316 bRestart = TRUE;
1317 bnRestart = TRUE;
1318 }
1319 // this timestamp is for MlmePeriodicExec() to check if all 20MHz N peers have left
1320 pAd->StaCfg.Last20NBeaconRxTime = Now;
1321 }
1322
1323 }
1324 else
1325#endif // DOT11_N_SUPPORT //
1326 {
1327 RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
1328 RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
1329 }
1330 }while (FALSE);
1331
1332 // If peer Adhoc is legacy mode, I don't need to call MlmeUpdateHtTxRates no matter I support HT or not
1333 if ((bRestart == TRUE) && (bnRestart == FALSE))
1334 {
1335 MlmeUpdateTxRates(pAd, FALSE, 0);
1336 MakeIbssBeacon(pAd); // re-build BEACON frame
1337 AsicEnableIbssSync(pAd); // copy to on-chip memory
1338 }
1339#ifdef DOT11_N_SUPPORT
1340 else if ((bRestart == TRUE) && (bnRestart == TRUE))
1341 {
1342 MlmeUpdateTxRates(pAd, FALSE, BSS0);
1343 MlmeUpdateHtTxRates(pAd, BSS0);
1344 MakeIbssBeacon(pAd); // re-build BEACON frame
1345 AsicEnableIbssSync(pAd); // copy to on-chip memory
1346 }
1347#endif // DOT11_N_SUPPORT //
1348
1349 // At least another peer in this IBSS, declare MediaState as CONNECTED
1350 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
1351 {
1352 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1353
1354 pAd->IndicateMediaState = NdisMediaStateConnected;
1355 RTMP_IndicateMediaState(pAd);
1356 pAd->ExtraInfo = GENERAL_LINK_UP;
1357 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1358
1359 // 2003/03/12 - john
1360 // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
1361 // "site survey" result should always include the current connected network.
1362 //
1363 Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
1364 if (Bssidx == BSS_NOT_FOUND)
1365 {
1366 Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
1367 &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
1368 &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
1369 &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
1370 }
1371 DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
1372 }
1373
1374 // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
1375 // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
1376 if (ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID))
1377 {
1378 UCHAR idx;
1379 MAC_TABLE_ENTRY *pEntry;
1380
1381 // look up the existing table
1382 pEntry = MacTableLookup(pAd, Addr2);
1383 if (pEntry == NULL)
1384 {
1385 // Another adhoc joining, add to our MAC table.
1386 pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
1387 if (pEntry)
1388 {
1389 pEntry->Sst = SST_ASSOC;
1390 idx = pAd->StaCfg.DefaultKeyId;
1391 // After InsertEntry, Write to ASIC on-chip table.
1392 RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
1393 DBGPRINT(RT_DEBUG_TRACE, ("ADHOC %x:%x:%x:%x:%x:%x join in.Entry=%d\n", Addr2[0],Addr2[1],Addr2[2],Addr2[3],Addr2[4],Addr2[5], pEntry->Aid));
1394
1395 pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1396 if (HtCapabilityLen <= 0)
1397 {
1398 pEntry->HTPhyMode.field.STBC = 0;
1399 pEntry->HTPhyMode.field.BW = 0;
1400 pEntry->HTPhyMode.field.ShortGI = 0;
1401 if ((SupRateLen+ExtRateLen <= 4) && (pAd->CommonCfg.Channel <= 14))
1402 {
1403 pEntry->HTPhyMode.field.MODE = MODE_CCK;
1404 }
1405 else
1406 {
1407 pEntry->HTPhyMode.field.MODE = MODE_OFDM;
1408 }
1409 MlmeUpdateTxRates(pAd, FALSE, 0);
1410 }
1411#ifdef DOT11_N_SUPPORT
1412 else
1413 {
1414 MlmeUpdateTxRates(pAd, FALSE, 0);
1415 MlmeUpdateHtTxRates(pAd, BSS0);
1416 }
1417#endif // DOT11_N_SUPPORT //
1418
1419#ifdef WPA_SUPPLICANT_SUPPORT
1420#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
1421 if (pAd->StaCfg.WpaSupplicantUP)
1422 {
1423 union iwreq_data wrqu;
1424
1425 SendAssocIEsToWpaSupplicant(pAd);
1426 memset(&wrqu, 0, sizeof(wrqu));
1427 wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
1428 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
1429 }
1430#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1431#endif // WPA_SUPPLICANT_SUPPORT //
1432
1433#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1434 {
1435 union iwreq_data wrqu;
1436 wext_notify_event_assoc(pAd);
1437
1438 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
1439 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
1440 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
1441
1442 }
1443#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1444 }
1445 }
1446 }
1447 }
1448
1449 if (INFRA_ON(pAd))
1450 {
1451 BOOLEAN bUseShortSlot, bUseBGProtection;
1452
1453 // decide to use/change to -
1454 // 1. long slot (20 us) or short slot (9 us) time
1455 // 2. turn on/off RTS/CTS and/or CTS-to-self protection
1456 // 3. short preamble
1457
1458 //bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
1459 bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo);
1460 if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
1461 AsicSetSlotTime(pAd, bUseShortSlot);
1462
1463 bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || // always use
1464 ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp));
1465
1466 if (pAd->CommonCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
1467 bUseBGProtection = FALSE;
1468
1469 if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
1470 {
1471 if (bUseBGProtection)
1472 {
1473 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1474 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
1475 }
1476 else
1477 {
1478 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1479 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
1480 }
1481
1482 DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection));
1483 }
1484
1485#ifdef DOT11_N_SUPPORT
1486 // check Ht protection mode. and adhere to the Non-GF device indication by AP.
1487 if ((AddHtInfoLen != 0) &&
1488 ((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) ||
1489 (AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent)))
1490 {
1491 pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent;
1492 pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode;
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 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode));
1501 }
1502#endif // DOT11_N_SUPPORT //
1503
1504 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) &&
1505 ERP_IS_USE_BARKER_PREAMBLE(Erp))
1506 {
1507 MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
1508 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n"));
1509 }
1510
1511 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
1512 (EdcaParm.bValid == TRUE) &&
1513 (EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount))
1514 {
1515 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
1516 pAd->CommonCfg.APEdcaParm.EdcaUpdateCount,
1517 EdcaParm.EdcaUpdateCount));
1518 AsicSetEdcaParm(pAd, &EdcaParm);
1519 }
1520
1521 // copy QOS related information
1522 NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
1523 NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
1524 }
1525
1526 // only INFRASTRUCTURE mode support power-saving feature
1527 if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave))
1528 {
1529 UCHAR FreeNumber;
1530 // 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
1531 // 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
1532 // 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
1533 // 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
1534 // 5. otherwise, put PHY back to sleep to save battery.
1535 if (MessageToMe)
1536 {
1537#ifdef RT2860
1538 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1539 {
1540 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
1541 // Turn clk to 80Mhz.
1542 }
1543#endif // RT2860 //
1544 if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
1545 pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
1546 {
1547 pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
1548 }
1549 else
1550 RT28XX_PS_POLL_ENQUEUE(pAd);
1551 }
1552 else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
1553 {
1554#ifdef RT2860
1555 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1556 {
1557 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
1558 }
1559#endif // RT2860 //
1560 }
1561 else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) ||
1562 (pAd->TxSwQueue[QID_AC_BE].Number != 0) ||
1563 (pAd->TxSwQueue[QID_AC_VI].Number != 0) ||
1564 (pAd->TxSwQueue[QID_AC_VO].Number != 0) ||
1565 (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1566 (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1567 (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1568 (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
1569 (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS))
1570 {
1571 // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
1572 // can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
1573#ifdef RT2860
1574 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1575 {
1576 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
1577 }
1578#endif // RT2860 //
1579 }
1580 else
1581 {
1582 USHORT NextDtim = DtimCount;
1583
1584 if (NextDtim == 0)
1585 NextDtim = DtimPeriod;
1586
1587 TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
1588 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
1589 TbttNumToNextWakeUp = NextDtim;
1590
1591 if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
1592 {
1593 AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
1594 }
1595 }
1596 }
1597 }
1598 // not my BSSID, ignore it
1599 }
1600 // sanity check fail, ignore this frame
1601}
1602
1603/*
1604 ==========================================================================
1605 Description:
1606 Receive PROBE REQ from remote peer when operating in IBSS mode
1607 ==========================================================================
1608 */
1609VOID PeerProbeReqAction(
1610 IN PRTMP_ADAPTER pAd,
1611 IN MLME_QUEUE_ELEM *Elem)
1612{
1613 UCHAR Addr2[MAC_ADDR_LEN];
1614 CHAR Ssid[MAX_LEN_OF_SSID];
1615 UCHAR SsidLen;
1616#ifdef DOT11_N_SUPPORT
1617 UCHAR HtLen, AddHtLen, NewExtLen;
1618#endif // DOT11_N_SUPPORT //
1619 HEADER_802_11 ProbeRspHdr;
1620 NDIS_STATUS NStatus;
1621 PUCHAR pOutBuffer = NULL;
1622 ULONG FrameLen = 0;
1623 LARGE_INTEGER FakeTimestamp;
1624 UCHAR DsLen = 1, IbssLen = 2;
1625 UCHAR LocalErpIe[3] = {IE_ERP, 1, 0};
1626 BOOLEAN Privacy;
1627 USHORT CapabilityInfo;
1628 UCHAR RSNIe = IE_WPA;
1629
1630 if (! ADHOC_ON(pAd))
1631 return;
1632
1633 if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
1634 {
1635 if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
1636 {
1637 // allocate and send out ProbeRsp frame
1638 NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1639 if (NStatus != NDIS_STATUS_SUCCESS)
1640 return;
1641
1642 //pAd->StaCfg.AtimWin = 0; // ??????
1643
1644 Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
1645 (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
1646 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
1647 CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
1648
1649 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1650 sizeof(HEADER_802_11), &ProbeRspHdr,
1651 TIMESTAMP_LEN, &FakeTimestamp,
1652 2, &pAd->CommonCfg.BeaconPeriod,
1653 2, &CapabilityInfo,
1654 1, &SsidIe,
1655 1, &pAd->CommonCfg.SsidLen,
1656 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1657 1, &SupRateIe,
1658 1, &pAd->StaActive.SupRateLen,
1659 pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
1660 1, &DsIe,
1661 1, &DsLen,
1662 1, &pAd->CommonCfg.Channel,
1663 1, &IbssIe,
1664 1, &IbssLen,
1665 2, &pAd->StaActive.AtimWin,
1666 END_OF_ARGS);
1667
1668 if (pAd->StaActive.ExtRateLen)
1669 {
1670 ULONG tmp;
1671 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1672 3, LocalErpIe,
1673 1, &ExtRateIe,
1674 1, &pAd->StaActive.ExtRateLen,
1675 pAd->StaActive.ExtRateLen, &pAd->StaActive.ExtRate,
1676 END_OF_ARGS);
1677 FrameLen += tmp;
1678 }
1679
1680 // If adhoc secruity is set for WPA-None, append the cipher suite IE
1681 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1682 {
1683 ULONG tmp;
1684 MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1685 1, &RSNIe,
1686 1, &pAd->StaCfg.RSNIE_Len,
1687 pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
1688 END_OF_ARGS);
1689 FrameLen += tmp;
1690 }
1691#ifdef DOT11_N_SUPPORT
1692 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
1693 {
1694 ULONG TmpLen;
1695 UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
1696 HtLen = sizeof(pAd->CommonCfg.HtCapability);
1697 AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
1698 NewExtLen = 1;
1699 //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
1700 if (pAd->bBroadComHT == TRUE)
1701 {
1702 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
1703 1, &WpaIe,
1704 4, &BROADCOM[0],
1705 pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
1706 END_OF_ARGS);
1707 }
1708 else
1709 {
1710 MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
1711 1, &HtCapIe,
1712 1, &HtLen,
1713 sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability,
1714 1, &AddHtInfoIe,
1715 1, &AddHtLen,
1716 sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo,
1717 1, &NewExtChanIe,
1718 1, &NewExtLen,
1719 sizeof(NEW_EXT_CHAN_IE), &pAd->CommonCfg.NewExtChanOffset,
1720 END_OF_ARGS);
1721 }
1722 FrameLen += TmpLen;
1723 }
1724#endif // DOT11_N_SUPPORT //
1725 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1726 MlmeFreeMemory(pAd, pOutBuffer);
1727 }
1728 }
1729}
1730
1731VOID BeaconTimeoutAtJoinAction(
1732 IN PRTMP_ADAPTER pAd,
1733 IN MLME_QUEUE_ELEM *Elem)
1734{
1735 USHORT Status;
1736 DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
1737 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1738 Status = MLME_REJ_TIMEOUT;
1739 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1740}
1741
1742/*
1743 ==========================================================================
1744 Description:
1745 Scan timeout procedure. basically add channel index by 1 and rescan
1746 ==========================================================================
1747 */
1748VOID ScanTimeoutAction(
1749 IN PRTMP_ADAPTER pAd,
1750 IN MLME_QUEUE_ELEM *Elem)
1751{
1752 pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
1753
1754 // Only one channel scanned for CISCO beacon request
1755 if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
1756 (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
1757 (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
1758 (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
1759 pAd->MlmeAux.Channel = 0;
1760
1761 // this routine will stop if pAd->MlmeAux.Channel == 0
1762 ScanNextChannel(pAd);
1763}
1764
1765/*
1766 ==========================================================================
1767 Description:
1768 ==========================================================================
1769 */
1770VOID InvalidStateWhenScan(
1771 IN PRTMP_ADAPTER pAd,
1772 IN MLME_QUEUE_ELEM *Elem)
1773{
1774 USHORT Status;
1775 DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1776 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1777 Status = MLME_STATE_MACHINE_REJECT;
1778 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
1779}
1780
1781/*
1782 ==========================================================================
1783 Description:
1784 ==========================================================================
1785 */
1786VOID InvalidStateWhenJoin(
1787 IN PRTMP_ADAPTER pAd,
1788 IN MLME_QUEUE_ELEM *Elem)
1789{
1790 USHORT Status;
1791 DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1792 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1793 Status = MLME_STATE_MACHINE_REJECT;
1794 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
1795}
1796
1797/*
1798 ==========================================================================
1799 Description:
1800 ==========================================================================
1801 */
1802VOID InvalidStateWhenStart(
1803 IN PRTMP_ADAPTER pAd,
1804 IN MLME_QUEUE_ELEM *Elem)
1805{
1806 USHORT Status;
1807 DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
1808 pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
1809 Status = MLME_STATE_MACHINE_REJECT;
1810 MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
1811}
1812
1813/*
1814 ==========================================================================
1815 Description:
1816
1817 IRQL = DISPATCH_LEVEL
1818
1819 ==========================================================================
1820 */
1821VOID EnqueuePsPoll(
1822 IN PRTMP_ADAPTER pAd)
1823{
1824#ifdef RALINK_ATE
1825 if (ATE_ON(pAd))
1826 {
1827 return;
1828 }
1829#endif // RALINK_ATE //
1830
1831
1832 if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
1833 pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
1834 MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
1835}
1836
1837
1838/*
1839 ==========================================================================
1840 Description:
1841 ==========================================================================
1842 */
1843VOID EnqueueProbeRequest(
1844 IN PRTMP_ADAPTER pAd)
1845{
1846 NDIS_STATUS NState;
1847 PUCHAR pOutBuffer;
1848 ULONG FrameLen = 0;
1849 HEADER_802_11 Hdr80211;
1850
1851 DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
1852
1853 NState = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
1854 if (NState == NDIS_STATUS_SUCCESS)
1855 {
1856 MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
1857
1858 // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
1859 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1860 sizeof(HEADER_802_11), &Hdr80211,
1861 1, &SsidIe,
1862 1, &pAd->CommonCfg.SsidLen,
1863 pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
1864 1, &SupRateIe,
1865 1, &pAd->StaActive.SupRateLen,
1866 pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
1867 END_OF_ARGS);
1868 MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
1869 MlmeFreeMemory(pAd, pOutBuffer);
1870 }
1871
1872}
1873
1874#ifdef DOT11_N_SUPPORT
1875#ifdef DOT11N_DRAFT3
1876VOID BuildEffectedChannelList(
1877 IN PRTMP_ADAPTER pAd)
1878{
1879 UCHAR EChannel[11];
1880 UCHAR i, j, k;
1881 UCHAR UpperChannel = 0, LowerChannel = 0;
1882
1883 RTMPZeroMemory(EChannel, 11);
1884 i = 0;
1885 // Find upper channel and lower channel.
1886 if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
1887 {
1888 UpperChannel = pAd->CommonCfg.Channel;
1889 LowerChannel = pAd->CommonCfg.CentralChannel;
1890 }
1891 else if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
1892 {
1893 UpperChannel = pAd->CommonCfg.CentralChannel;
1894 LowerChannel = pAd->CommonCfg.Channel;
1895 }
1896 else
1897 {
1898 return;
1899 }
1900
1901 // Record channels that is below lower channel..
1902 if (LowerChannel > 1)
1903 {
1904 EChannel[0] = LowerChannel - 1;
1905 i = 1;
1906 if (LowerChannel > 2)
1907 {
1908 EChannel[1] = LowerChannel - 2;
1909 i = 2;
1910 if (LowerChannel > 3)
1911 {
1912 EChannel[2] = LowerChannel - 3;
1913 i = 3;
1914 }
1915 }
1916 }
1917 // Record channels that is between lower channel and upper channel.
1918 for (k = LowerChannel;k < UpperChannel;k++)
1919 {
1920 EChannel[i] = k;
1921 i++;
1922 }
1923 // Record channels that is above upper channel..
1924 if (LowerChannel < 11)
1925 {
1926 EChannel[i] = UpperChannel + 1;
1927 i++;
1928 if (LowerChannel < 10)
1929 {
1930 EChannel[i] = LowerChannel + 2;
1931 i++;
1932 if (LowerChannel < 9)
1933 {
1934 EChannel[i] = LowerChannel + 3;
1935 i++;
1936 }
1937 }
1938 }
1939 //
1940 for (j = 0;j < i;j++)
1941 {
1942 for (k = 0;k < pAd->ChannelListNum;k++)
1943 {
1944 if (pAd->ChannelList[k].Channel == EChannel[j])
1945 {
1946 pAd->ChannelList[k].bEffectedChannel = TRUE;
1947 DBGPRINT(RT_DEBUG_TRACE,(" EffectedChannel( =%d)\n", EChannel[j]));
1948 break;
1949 }
1950 }
1951 }
1952}
1953#endif // DOT11N_DRAFT3 //
1954#endif // DOT11_N_SUPPORT //
1955
1956BOOLEAN ScanRunning(
1957 IN PRTMP_ADAPTER pAd)
1958{
1959 return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;
1960}
1961
diff --git a/drivers/staging/rt2860/sta/wpa.c b/drivers/staging/rt2860/sta/wpa.c
new file mode 100644
index 00000000000..774c6567ae5
--- /dev/null
+++ b/drivers/staging/rt2860/sta/wpa.c
@@ -0,0 +1,2086 @@
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 STA_PORT_SECURED(pAd);
1218
1219 // Indicate Connected for GUI
1220 pAd->IndicateMediaState = NdisMediaStateConnected;
1221
1222 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
1223 os_free_mem(pAd, (PUCHAR)mpool);
1224
1225
1226 // send wireless event - for set key done WPA2
1227 if (pAd->CommonCfg.bWirelessEvent)
1228 RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, BSS0, 0);
1229
1230 DBGPRINT(RT_DEBUG_ERROR, ("Wpa2PairMsg3Action <-----\n"));
1231
1232}
1233
1234/*
1235 ========================================================================
1236
1237 Routine Description:
1238 Process Group key 2-way handshaking
1239
1240 Arguments:
1241 pAd Pointer to our adapter
1242 Elem Message body
1243
1244 Return Value:
1245 None
1246
1247 Note:
1248
1249 ========================================================================
1250*/
1251VOID WpaGroupMsg1Action(
1252 IN PRTMP_ADAPTER pAd,
1253 IN MLME_QUEUE_ELEM *Elem)
1254
1255{
1256 PUCHAR pOutBuffer = NULL;
1257 UCHAR Header802_3[14];
1258 ULONG FrameLen = 0;
1259 EAPOL_PACKET Packet;
1260 PEAPOL_PACKET pGroup;
1261 UCHAR *mpool, *digest, *KEYDATA;
1262 UCHAR Mic[16], OldMic[16];
1263 UCHAR GTK[32], Key[32];
1264 KEY_INFO peerKeyInfo;
1265
1266 // allocate memory
1267 os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
1268
1269 if(mpool == NULL)
1270 return;
1271
1272 // digest Len = 80.
1273 digest = (UCHAR *) ROUND_UP(mpool, 4);
1274 // KEYDATA Len = 512.
1275 KEYDATA = (UCHAR *) ROUND_UP(digest + 80, 4);
1276
1277 DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action ----->\n"));
1278
1279 // Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8)
1280 pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
1281
1282 NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
1283 NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pGroup->KeyDesc.KeyInfo, sizeof(KEY_INFO));
1284
1285 *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
1286
1287 // 0. Check cipher type match
1288 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
1289 {
1290 os_free_mem(pAd, (PUCHAR)mpool);
1291 return;
1292 }
1293 else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
1294 {
1295 os_free_mem(pAd, (PUCHAR)mpool);
1296 return;
1297 }
1298
1299 // 1. Verify Replay counter
1300 // Check Replay Counter, it has to be larger than last one. No need to be exact one larger
1301 if(RTMPCompareMemory(pGroup->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
1302 {
1303 os_free_mem(pAd, (PUCHAR)mpool);
1304 return;
1305 }
1306
1307 // Update new replay counter
1308 NdisMoveMemory(pAd->StaCfg.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1309
1310 // 2. Verify MIC is valid
1311 // Save the MIC and replace with zero
1312 NdisMoveMemory(OldMic, pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1313 NdisZeroMemory(pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
1314
1315 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1316 { // AES
1317 HMAC_SHA1((PUCHAR) pGroup, pGroup->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
1318 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1319 }
1320 else
1321 { // TKIP
1322 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pGroup, pGroup->Body_Len[1] + 4, Mic);
1323 }
1324
1325 if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
1326 {
1327 DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
1328 MlmeFreeMemory(pAd, (PUCHAR)mpool);
1329 return;
1330 }
1331 else
1332 DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
1333
1334
1335 // 3. Decrypt GTK from Key Data
1336 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1337 {
1338 // Decrypt AES GTK
1339 AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pGroup->KeyDesc.KeyDataLen[1], pGroup->KeyDesc.KeyData);
1340 }
1341 else // TKIP
1342 {
1343 INT i;
1344
1345 // Decrypt TKIP GTK
1346 // Construct 32 bytes RC4 Key
1347 NdisMoveMemory(Key, pGroup->KeyDesc.KeyIv, 16);
1348 NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
1349 ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
1350 //discard first 256 bytes
1351 for(i = 0; i < 256; i++)
1352 ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
1353 // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
1354 ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pGroup->KeyDesc.KeyData, pGroup->KeyDesc.KeyDataLen[1]);
1355 }
1356
1357 // Process decrypted key data material
1358 // Parse keyData to handle KDE format for WPA2PSK
1359 if (peerKeyInfo.EKD_DL)
1360 {
1361 if (!ParseKeyData(pAd, KEYDATA, pGroup->KeyDesc.KeyDataLen[1], 0))
1362 {
1363 os_free_mem(pAd, (PUCHAR)mpool);
1364 return;
1365 }
1366 }
1367 else // WPAPSK
1368 {
1369 // set key material, TxMic and RxMic for WPAPSK
1370 NdisMoveMemory(GTK, KEYDATA, 32);
1371 NdisMoveMemory(pAd->StaCfg.GTK, GTK, 32);
1372 pAd->StaCfg.DefaultKeyId = peerKeyInfo.KeyIndex;
1373
1374 // Prepare pair-wise key information into shared key table
1375 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
1376 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
1377 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, GTK, LEN_TKIP_EK);
1378 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &GTK[16], LEN_TKIP_RXMICK);
1379 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &GTK[24], LEN_TKIP_TXMICK);
1380
1381 // Update Shared Key CipherAlg
1382 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
1383 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
1384 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
1385 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
1386 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
1387
1388 //hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
1389 }
1390
1391 // Update group key information to ASIC Shared Key Table
1392 AsicAddSharedKeyEntry(pAd,
1393 BSS0,
1394 pAd->StaCfg.DefaultKeyId,
1395 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1396 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
1397 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
1398 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
1399
1400 // Update ASIC WCID attribute table and IVEIV table
1401 RTMPAddWcidAttributeEntry(pAd,
1402 BSS0,
1403 pAd->StaCfg.DefaultKeyId,
1404 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
1405 NULL);
1406
1407 // set 802.1x port control
1408 STA_PORT_SECURED(pAd);
1409
1410 // Indicate Connected for GUI
1411 pAd->IndicateMediaState = NdisMediaStateConnected;
1412
1413 // init header and Fill Packet
1414 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1415
1416 // Zero Group message 1 body
1417 NdisZeroMemory(&Packet, sizeof(Packet));
1418 Packet.ProVer = EAPOL_VER;
1419 Packet.ProType = EAPOLKey;
1420 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
1421
1422 //
1423 // Group Message 2 as EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
1424 //
1425 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
1426 {
1427 Packet.KeyDesc.Type = WPA2_KEY_DESC;
1428 }
1429 else
1430 {
1431 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1432 }
1433
1434 // Key descriptor version and appropriate RSN IE
1435 Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
1436
1437 // Update Key Length
1438 Packet.KeyDesc.KeyLength[0] = pGroup->KeyDesc.KeyLength[0];
1439 Packet.KeyDesc.KeyLength[1] = pGroup->KeyDesc.KeyLength[1];
1440
1441 // Key Index as G-Msg 1
1442 if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
1443 Packet.KeyDesc.KeyInfo.KeyIndex = peerKeyInfo.KeyIndex;
1444
1445 // Key Type Group key
1446 Packet.KeyDesc.KeyInfo.KeyType = GROUPKEY;
1447
1448 // KeyMic field presented
1449 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1450
1451 // Secure bit
1452 Packet.KeyDesc.KeyInfo.Secure = 1;
1453
1454 // Convert to little-endian format.
1455 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
1456
1457 // Key Replay count
1458 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
1459
1460 // Out buffer for transmitting group message 2
1461 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
1462 if(pOutBuffer == NULL)
1463 {
1464 MlmeFreeMemory(pAd, (PUCHAR)mpool);
1465 return;
1466 }
1467
1468 // Prepare EAPOL frame for MIC calculation
1469 // Be careful, only EAPOL frame is counted for MIC calculation
1470 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1471 Packet.Body_Len[1] + 4, &Packet,
1472 END_OF_ARGS);
1473
1474 // Prepare and Fill MIC value
1475 NdisZeroMemory(Mic, sizeof(Mic));
1476 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1477 {
1478 // AES
1479 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
1480 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
1481 }
1482 else
1483 {
1484 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
1485 }
1486 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
1487
1488
1489 MakeOutgoingFrame(pOutBuffer, &FrameLen,
1490 LENGTH_802_3, &Header802_3,
1491 Packet.Body_Len[1] + 4, &Packet,
1492 END_OF_ARGS);
1493
1494
1495 // 5. Copy frame to Tx ring and prepare for encryption
1496 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
1497
1498 // 6 Free allocated memory
1499 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
1500 os_free_mem(pAd, (PUCHAR)mpool);
1501
1502 // send wireless event - for set key done WPA2
1503 if (pAd->CommonCfg.bWirelessEvent)
1504 RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1505
1506 DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action <-----\n"));
1507}
1508
1509/*
1510 ========================================================================
1511
1512 Routine Description:
1513 Init WPA MAC header
1514
1515 Arguments:
1516 pAd Pointer to our adapter
1517
1518 Return Value:
1519 None
1520
1521 Note:
1522
1523 ========================================================================
1524*/
1525VOID WpaMacHeaderInit(
1526 IN PRTMP_ADAPTER pAd,
1527 IN OUT PHEADER_802_11 pHdr80211,
1528 IN UCHAR wep,
1529 IN PUCHAR pAddr1)
1530{
1531 NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
1532 pHdr80211->FC.Type = BTYPE_DATA;
1533 pHdr80211->FC.ToDs = 1;
1534 if (wep == 1)
1535 pHdr80211->FC.Wep = 1;
1536
1537 // Addr1: BSSID, Addr2: SA, Addr3: DA
1538 COPY_MAC_ADDR(pHdr80211->Addr1, pAddr1);
1539 COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
1540 COPY_MAC_ADDR(pHdr80211->Addr3, pAd->CommonCfg.Bssid);
1541 pHdr80211->Sequence = pAd->Sequence;
1542}
1543
1544/*
1545 ========================================================================
1546
1547 Routine Description:
1548 Copy frame from waiting queue into relative ring buffer and set
1549 appropriate ASIC register to kick hardware encryption before really
1550 sent out to air.
1551
1552 Arguments:
1553 pAd Pointer to our adapter
1554 PNDIS_PACKET Pointer to outgoing Ndis frame
1555 NumberOfFrag Number of fragment required
1556
1557 Return Value:
1558 None
1559
1560 Note:
1561
1562 ========================================================================
1563*/
1564VOID RTMPToWirelessSta(
1565 IN PRTMP_ADAPTER pAd,
1566 IN PUCHAR pHeader802_3,
1567 IN UINT HdrLen,
1568 IN PUCHAR pData,
1569 IN UINT DataLen,
1570 IN BOOLEAN is4wayFrame)
1571
1572{
1573 NDIS_STATUS Status;
1574 PNDIS_PACKET pPacket;
1575 UCHAR Index;
1576
1577 do
1578 {
1579 // 1. build a NDIS packet and call RTMPSendPacket();
1580 // be careful about how/when to release this internal allocated NDIS PACKET buffer
1581 Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
1582 if (Status != NDIS_STATUS_SUCCESS)
1583 break;
1584
1585 if (is4wayFrame)
1586 RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
1587 else
1588 RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
1589
1590 // 2. send out the packet
1591 Status = STASendPacket(pAd, pPacket);
1592 if(Status == NDIS_STATUS_SUCCESS)
1593 {
1594 // Dequeue one frame from TxSwQueue0..3 queue and process it
1595 // There are three place calling dequeue for TX ring.
1596 // 1. Here, right after queueing the frame.
1597 // 2. At the end of TxRingTxDone service routine.
1598 // 3. Upon NDIS call RTMPSendPackets
1599 if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
1600 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
1601 {
1602 for(Index = 0; Index < 5; Index ++)
1603 if(pAd->TxSwQueue[Index].Number > 0)
1604 RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS);
1605 }
1606 }
1607 } while(FALSE);
1608
1609}
1610
1611/*
1612 ========================================================================
1613
1614 Routine Description:
1615 Check Sanity RSN IE form AP
1616
1617 Arguments:
1618
1619 Return Value:
1620
1621
1622 ========================================================================
1623*/
1624BOOLEAN CheckRSNIE(
1625 IN PRTMP_ADAPTER pAd,
1626 IN PUCHAR pData,
1627 IN UCHAR DataLen,
1628 OUT UCHAR *Offset)
1629{
1630 PUCHAR pVIE;
1631 UCHAR len;
1632 PEID_STRUCT pEid;
1633 BOOLEAN result = FALSE;
1634
1635 pVIE = pData;
1636 len = DataLen;
1637 *Offset = 0;
1638
1639 while (len > sizeof(RSNIE2))
1640 {
1641 pEid = (PEID_STRUCT) pVIE;
1642 // WPA RSN IE
1643 if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
1644 {
1645 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) &&
1646 (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
1647 (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
1648 {
1649 DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA/WPAPSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
1650 result = TRUE;
1651 }
1652
1653 *Offset += (pEid->Len + 2);
1654 }
1655 // WPA2 RSN IE
1656 else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
1657 {
1658 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) &&
1659 (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
1660 (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
1661 {
1662 DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
1663 result = TRUE;
1664 }
1665
1666 *Offset += (pEid->Len + 2);
1667 }
1668 else
1669 {
1670 break;
1671 }
1672
1673 pVIE += (pEid->Len + 2);
1674 len -= (pEid->Len + 2);
1675 }
1676
1677 DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> skip_offset(%d) \n", *Offset));
1678
1679 return result;
1680
1681}
1682
1683
1684/*
1685 ========================================================================
1686
1687 Routine Description:
1688 Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
1689 GTK is encaptulated in KDE format at p.83 802.11i D10
1690
1691 Arguments:
1692
1693 Return Value:
1694
1695 Note:
1696 802.11i D10
1697
1698 ========================================================================
1699*/
1700BOOLEAN ParseKeyData(
1701 IN PRTMP_ADAPTER pAd,
1702 IN PUCHAR pKeyData,
1703 IN UCHAR KeyDataLen,
1704 IN UCHAR bPairewise)
1705{
1706 PKDE_ENCAP pKDE = NULL;
1707 PUCHAR pMyKeyData = pKeyData;
1708 UCHAR KeyDataLength = KeyDataLen;
1709 UCHAR GTKLEN;
1710 UCHAR skip_offset;
1711
1712 // Verify The RSN IE contained in Pairewise-Msg 3 and skip it
1713 if (bPairewise)
1714 {
1715 // Check RSN IE whether it is WPA2/WPA2PSK
1716 if (!CheckRSNIE(pAd, pKeyData, KeyDataLen, &skip_offset))
1717 {
1718 DBGPRINT(RT_DEBUG_ERROR, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE mismatched \n"));
1719 hex_dump("Get KEYDATA :", pKeyData, KeyDataLen);
1720 return FALSE;
1721 }
1722 else
1723 {
1724 // skip RSN IE
1725 pMyKeyData += skip_offset;
1726 KeyDataLength -= skip_offset;
1727
1728 //DBGPRINT(RT_DEBUG_TRACE, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
1729 }
1730 }
1731
1732 DBGPRINT(RT_DEBUG_TRACE,("ParseKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
1733
1734 // Parse EKD format
1735 if (KeyDataLength >= 8)
1736 {
1737 pKDE = (PKDE_ENCAP) pMyKeyData;
1738 }
1739 else
1740 {
1741 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KeyDataLength is too short \n"));
1742 return FALSE;
1743 }
1744
1745
1746 // Sanity check - shared key index should not be 0
1747 if (pKDE->GTKEncap.Kid == 0)
1748 {
1749 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index zero \n"));
1750 return FALSE;
1751 }
1752
1753 // Sanity check - KED length
1754 if (KeyDataLength < (pKDE->Len + 2))
1755 {
1756 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
1757 return FALSE;
1758 }
1759
1760 // Get GTK length - refer to IEEE 802.11i-2004 p.82
1761 GTKLEN = pKDE->Len -6;
1762
1763 if (GTKLEN < LEN_AES_KEY)
1764 {
1765 DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
1766 return FALSE;
1767 }
1768 else
1769 DBGPRINT(RT_DEBUG_TRACE, ("GTK Key with KDE formet got index=%d, len=%d \n", pKDE->GTKEncap.Kid, GTKLEN));
1770
1771 // Update GTK
1772 // set key material, TxMic and RxMic for WPAPSK
1773 NdisMoveMemory(pAd->StaCfg.GTK, pKDE->GTKEncap.GTK, 32);
1774 pAd->StaCfg.DefaultKeyId = pKDE->GTKEncap.Kid;
1775
1776 // Update shared key table
1777 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
1778 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
1779 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKDE->GTKEncap.GTK, LEN_TKIP_EK);
1780 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &pKDE->GTKEncap.GTK[16], LEN_TKIP_RXMICK);
1781 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &pKDE->GTKEncap.GTK[24], LEN_TKIP_TXMICK);
1782
1783 // Update Shared Key CipherAlg
1784 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
1785 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
1786 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
1787 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
1788 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
1789
1790 return TRUE;
1791
1792}
1793
1794/*
1795 ========================================================================
1796
1797 Routine Description:
1798 Cisco CCKM PRF function
1799
1800 Arguments:
1801 key Cisco Base Transient Key (BTK)
1802 key_len The key length of the BTK
1803 data Ruquest Number(RN) + BSSID
1804 data_len The length of the data
1805 output Store for PTK(Pairwise transient keys)
1806 len The length of the output
1807 Return Value:
1808 None
1809
1810 Note:
1811 802.1i Annex F.9
1812
1813 ========================================================================
1814*/
1815VOID CCKMPRF(
1816 IN UCHAR *key,
1817 IN INT key_len,
1818 IN UCHAR *data,
1819 IN INT data_len,
1820 OUT UCHAR *output,
1821 IN INT len)
1822{
1823 INT i;
1824 UCHAR input[1024];
1825 INT currentindex = 0;
1826 INT total_len;
1827
1828 NdisMoveMemory(input, data, data_len);
1829 total_len = data_len;
1830 input[total_len] = 0;
1831 total_len++;
1832 for (i = 0; i < (len + 19) / 20; i++)
1833 {
1834 HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
1835 currentindex += 20;
1836 input[total_len - 1]++;
1837 }
1838}
1839
1840/*
1841 ========================================================================
1842
1843 Routine Description:
1844 Process MIC error indication and record MIC error timer.
1845
1846 Arguments:
1847 pAd Pointer to our adapter
1848 pWpaKey Pointer to the WPA key structure
1849
1850 Return Value:
1851 None
1852
1853 IRQL = DISPATCH_LEVEL
1854
1855 Note:
1856
1857 ========================================================================
1858*/
1859VOID RTMPReportMicError(
1860 IN PRTMP_ADAPTER pAd,
1861 IN PCIPHER_KEY pWpaKey)
1862{
1863 ULONG Now;
1864 UCHAR unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0);
1865
1866 // Record Last MIC error time and count
1867 Now = jiffies;
1868 if (pAd->StaCfg.MicErrCnt == 0)
1869 {
1870 pAd->StaCfg.MicErrCnt++;
1871 pAd->StaCfg.LastMicErrorTime = Now;
1872 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1873 }
1874 else if (pAd->StaCfg.MicErrCnt == 1)
1875 {
1876 if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now)
1877 {
1878 // Update Last MIC error time, this did not violate two MIC errors within 60 seconds
1879 pAd->StaCfg.LastMicErrorTime = Now;
1880 }
1881 else
1882 {
1883
1884 if (pAd->CommonCfg.bWirelessEvent)
1885 RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1886
1887 pAd->StaCfg.LastMicErrorTime = Now;
1888 // Violate MIC error counts, MIC countermeasures kicks in
1889 pAd->StaCfg.MicErrCnt++;
1890 }
1891 }
1892 else
1893 {
1894 // MIC error count >= 2
1895 // This should not happen
1896 ;
1897 }
1898 MlmeEnqueue(pAd,
1899 MLME_CNTL_STATE_MACHINE,
1900 OID_802_11_MIC_FAILURE_REPORT_FRAME,
1901 1,
1902 &unicastKey);
1903
1904 if (pAd->StaCfg.MicErrCnt == 2)
1905 {
1906 RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
1907 }
1908}
1909
1910
1911#ifdef WPA_SUPPLICANT_SUPPORT
1912#define LENGTH_EAP_H 4
1913// If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)).
1914INT WpaCheckEapCode(
1915 IN PRTMP_ADAPTER pAd,
1916 IN PUCHAR pFrame,
1917 IN USHORT FrameLen,
1918 IN USHORT OffSet)
1919{
1920
1921 PUCHAR pData;
1922 INT result = 0;
1923
1924 if( FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H )
1925 return result;
1926
1927 pData = pFrame + OffSet; // skip offset bytes
1928
1929 if(*(pData+1) == EAPPacket) // 802.1x header - Packet Type
1930 {
1931 result = *(pData+4); // EAP header - Code
1932 }
1933
1934 return result;
1935}
1936
1937VOID WpaSendMicFailureToWpaSupplicant(
1938 IN PRTMP_ADAPTER pAd,
1939 IN BOOLEAN bUnicast)
1940{
1941 union iwreq_data wrqu;
1942 char custom[IW_CUSTOM_MAX] = {0};
1943
1944 sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
1945 if (bUnicast)
1946 sprintf(custom, "%s unicast", custom);
1947 wrqu.data.length = strlen(custom);
1948 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
1949
1950 return;
1951}
1952#endif // WPA_SUPPLICANT_SUPPORT //
1953
1954VOID WpaMicFailureReportFrame(
1955 IN PRTMP_ADAPTER pAd,
1956 IN MLME_QUEUE_ELEM *Elem)
1957{
1958 PUCHAR pOutBuffer = NULL;
1959 UCHAR Header802_3[14];
1960 ULONG FrameLen = 0;
1961 EAPOL_PACKET Packet;
1962 UCHAR Mic[16];
1963 BOOLEAN bUnicast;
1964
1965 DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));
1966
1967 bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
1968 pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
1969
1970 // init 802.3 header and Fill Packet
1971 MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
1972
1973 NdisZeroMemory(&Packet, sizeof(Packet));
1974 Packet.ProVer = EAPOL_VER;
1975 Packet.ProType = EAPOLKey;
1976
1977 Packet.KeyDesc.Type = WPA1_KEY_DESC;
1978
1979 // Request field presented
1980 Packet.KeyDesc.KeyInfo.Request = 1;
1981
1982 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
1983 {
1984 Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
1985 }
1986 else // TKIP
1987 {
1988 Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
1989 }
1990
1991 Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
1992
1993 // KeyMic field presented
1994 Packet.KeyDesc.KeyInfo.KeyMic = 1;
1995
1996 // Error field presented
1997 Packet.KeyDesc.KeyInfo.Error = 1;
1998
1999 // Update packet length after decide Key data payload
2000 Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;
2001
2002 // Key Replay Count
2003 NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
2004 inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
2005
2006 // Convert to little-endian format.
2007 *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
2008
2009
2010 MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
2011 if(pOutBuffer == NULL)
2012 {
2013 return;
2014 }
2015
2016 // Prepare EAPOL frame for MIC calculation
2017 // Be careful, only EAPOL frame is counted for MIC calculation
2018 MakeOutgoingFrame(pOutBuffer, &FrameLen,
2019 Packet.Body_Len[1] + 4, &Packet,
2020 END_OF_ARGS);
2021
2022 // Prepare and Fill MIC value
2023 NdisZeroMemory(Mic, sizeof(Mic));
2024 if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
2025 { // AES
2026 UCHAR digest[20] = {0};
2027 HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
2028 NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
2029 }
2030 else
2031 { // TKIP
2032 hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
2033 }
2034 NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
2035
2036 MakeOutgoingFrame(pOutBuffer, &FrameLen,
2037 LENGTH_802_3, &Header802_3,
2038 Packet.Body_Len[1] + 4, &Packet,
2039 END_OF_ARGS);
2040
2041 // opy frame to Tx ring and send MIC failure report frame to authenticator
2042 RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
2043
2044 MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
2045
2046 DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
2047}
2048
2049/** from wpa_supplicant
2050 * inc_byte_array - Increment arbitrary length byte array by one
2051 * @counter: Pointer to byte array
2052 * @len: Length of the counter in bytes
2053 *
2054 * This function increments the last byte of the counter by one and continues
2055 * rolling over to more significant bytes if the byte was incremented from
2056 * 0xff to 0x00.
2057 */
2058void inc_byte_array(UCHAR *counter, int len)
2059{
2060 int pos = len - 1;
2061 while (pos >= 0) {
2062 counter[pos]++;
2063 if (counter[pos] != 0)
2064 break;
2065 pos--;
2066 }
2067}
2068
2069VOID WpaDisassocApAndBlockAssoc(
2070 IN PVOID SystemSpecific1,
2071 IN PVOID FunctionContext,
2072 IN PVOID SystemSpecific2,
2073 IN PVOID SystemSpecific3)
2074{
2075 RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext;
2076 MLME_DISASSOC_REQ_STRUCT DisassocReq;
2077
2078 // disassoc from current AP first
2079 DBGPRINT(RT_DEBUG_TRACE, ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
2080 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_MIC_FAILURE);
2081 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
2082
2083 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
2084 pAd->StaCfg.bBlockAssoc = TRUE;
2085}
2086
diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c
new file mode 100644
index 00000000000..87bf505b4df
--- /dev/null
+++ b/drivers/staging/rt2860/sta_ioctl.c
@@ -0,0 +1,6944 @@
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/* --- sub-ioctls relations --- */
105
106#ifdef DBG
107{ RTPRIV_IOCTL_BBP,
108 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
109 "bbp"},
110{ RTPRIV_IOCTL_MAC,
111 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
112 "mac"},
113{ RTPRIV_IOCTL_E2P,
114 IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
115 "e2p"},
116#endif /* DBG */
117
118{ RTPRIV_IOCTL_STATISTICS,
119 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
120 "stat"},
121{ RTPRIV_IOCTL_GSITESURVEY,
122 0, IW_PRIV_TYPE_CHAR | 1024,
123 "get_site_survey"},
124};
125
126INT Set_SSID_Proc(
127 IN PRTMP_ADAPTER pAdapter,
128 IN PUCHAR arg);
129
130#ifdef WMM_SUPPORT
131INT Set_WmmCapable_Proc(
132 IN PRTMP_ADAPTER pAd,
133 IN PUCHAR arg);
134#endif
135
136INT Set_NetworkType_Proc(
137 IN PRTMP_ADAPTER pAdapter,
138 IN PUCHAR arg);
139
140INT Set_AuthMode_Proc(
141 IN PRTMP_ADAPTER pAdapter,
142 IN PUCHAR arg);
143
144INT Set_EncrypType_Proc(
145 IN PRTMP_ADAPTER pAdapter,
146 IN PUCHAR arg);
147
148INT Set_DefaultKeyID_Proc(
149 IN PRTMP_ADAPTER pAdapter,
150 IN PUCHAR arg);
151
152INT Set_Key1_Proc(
153 IN PRTMP_ADAPTER pAdapter,
154 IN PUCHAR arg);
155
156INT Set_Key2_Proc(
157 IN PRTMP_ADAPTER pAdapter,
158 IN PUCHAR arg);
159
160INT Set_Key3_Proc(
161 IN PRTMP_ADAPTER pAdapter,
162 IN PUCHAR arg);
163
164INT Set_Key4_Proc(
165 IN PRTMP_ADAPTER pAdapter,
166 IN PUCHAR arg);
167
168INT Set_WPAPSK_Proc(
169 IN PRTMP_ADAPTER pAdapter,
170 IN PUCHAR arg);
171
172
173INT Set_PSMode_Proc(
174 IN PRTMP_ADAPTER pAdapter,
175 IN PUCHAR arg);
176
177#ifdef WPA_SUPPLICANT_SUPPORT
178INT Set_Wpa_Support(
179 IN PRTMP_ADAPTER pAd,
180 IN PUCHAR arg);
181#endif // WPA_SUPPLICANT_SUPPORT //
182
183#ifdef DBG
184VOID RTMPIoctlBBP(
185 IN PRTMP_ADAPTER pAdapter,
186 IN struct iwreq *wrq);
187
188VOID RTMPIoctlMAC(
189 IN PRTMP_ADAPTER pAdapter,
190 IN struct iwreq *wrq);
191
192VOID RTMPIoctlE2PROM(
193 IN PRTMP_ADAPTER pAdapter,
194 IN struct iwreq *wrq);
195#endif // DBG //
196
197
198NDIS_STATUS RTMPWPANoneAddKeyProc(
199 IN PRTMP_ADAPTER pAd,
200 IN PVOID pBuf);
201
202INT Set_FragTest_Proc(
203 IN PRTMP_ADAPTER pAdapter,
204 IN PUCHAR arg);
205
206#ifdef DOT11_N_SUPPORT
207INT Set_TGnWifiTest_Proc(
208 IN PRTMP_ADAPTER pAd,
209 IN PUCHAR arg);
210#endif // DOT11_N_SUPPORT //
211
212INT Set_LongRetryLimit_Proc(
213 IN PRTMP_ADAPTER pAdapter,
214 IN PUCHAR arg);
215
216INT Set_ShortRetryLimit_Proc(
217 IN PRTMP_ADAPTER pAdapter,
218 IN PUCHAR arg);
219
220#ifdef EXT_BUILD_CHANNEL_LIST
221INT Set_Ieee80211dClientMode_Proc(
222 IN PRTMP_ADAPTER pAdapter,
223 IN PUCHAR arg);
224#endif // EXT_BUILD_CHANNEL_LIST //
225
226#ifdef CARRIER_DETECTION_SUPPORT
227INT Set_CarrierDetect_Proc(
228 IN PRTMP_ADAPTER pAd,
229 IN PUCHAR arg);
230#endif // CARRIER_DETECTION_SUPPORT //
231
232static struct {
233 CHAR *name;
234 INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
235} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
236 {"DriverVersion", Set_DriverVersion_Proc},
237 {"CountryRegion", Set_CountryRegion_Proc},
238 {"CountryRegionABand", Set_CountryRegionABand_Proc},
239 {"SSID", Set_SSID_Proc},
240 {"WirelessMode", Set_WirelessMode_Proc},
241 {"TxBurst", Set_TxBurst_Proc},
242 {"TxPreamble", Set_TxPreamble_Proc},
243 {"TxPower", Set_TxPower_Proc},
244 {"Channel", Set_Channel_Proc},
245 {"BGProtection", Set_BGProtection_Proc},
246 {"RTSThreshold", Set_RTSThreshold_Proc},
247 {"FragThreshold", Set_FragThreshold_Proc},
248#ifdef DOT11_N_SUPPORT
249 {"HtBw", Set_HtBw_Proc},
250 {"HtMcs", Set_HtMcs_Proc},
251 {"HtGi", Set_HtGi_Proc},
252 {"HtOpMode", Set_HtOpMode_Proc},
253 {"HtExtcha", Set_HtExtcha_Proc},
254 {"HtMpduDensity", Set_HtMpduDensity_Proc},
255 {"HtBaWinSize", Set_HtBaWinSize_Proc},
256 {"HtRdg", Set_HtRdg_Proc},
257 {"HtAmsdu", Set_HtAmsdu_Proc},
258 {"HtAutoBa", Set_HtAutoBa_Proc},
259 {"HtBaDecline", Set_BADecline_Proc},
260 {"HtProtect", Set_HtProtect_Proc},
261 {"HtMimoPs", Set_HtMimoPs_Proc},
262#endif // DOT11_N_SUPPORT //
263
264#ifdef AGGREGATION_SUPPORT
265 {"PktAggregate", Set_PktAggregate_Proc},
266#endif
267
268#ifdef WMM_SUPPORT
269 {"WmmCapable", Set_WmmCapable_Proc},
270#endif
271 {"IEEE80211H", Set_IEEE80211H_Proc},
272 {"NetworkType", Set_NetworkType_Proc},
273 {"AuthMode", Set_AuthMode_Proc},
274 {"EncrypType", Set_EncrypType_Proc},
275 {"DefaultKeyID", Set_DefaultKeyID_Proc},
276 {"Key1", Set_Key1_Proc},
277 {"Key2", Set_Key2_Proc},
278 {"Key3", Set_Key3_Proc},
279 {"Key4", Set_Key4_Proc},
280 {"WPAPSK", Set_WPAPSK_Proc},
281 {"ResetCounter", Set_ResetStatCounter_Proc},
282 {"PSMode", Set_PSMode_Proc},
283#ifdef DBG
284 {"Debug", Set_Debug_Proc},
285#endif
286
287#ifdef RALINK_ATE
288 {"ATE", Set_ATE_Proc},
289 {"ATEDA", Set_ATE_DA_Proc},
290 {"ATESA", Set_ATE_SA_Proc},
291 {"ATEBSSID", Set_ATE_BSSID_Proc},
292 {"ATECHANNEL", Set_ATE_CHANNEL_Proc},
293 {"ATETXPOW0", Set_ATE_TX_POWER0_Proc},
294 {"ATETXPOW1", Set_ATE_TX_POWER1_Proc},
295 {"ATETXANT", Set_ATE_TX_Antenna_Proc},
296 {"ATERXANT", Set_ATE_RX_Antenna_Proc},
297 {"ATETXFREQOFFSET", Set_ATE_TX_FREQOFFSET_Proc},
298 {"ATETXBW", Set_ATE_TX_BW_Proc},
299 {"ATETXLEN", Set_ATE_TX_LENGTH_Proc},
300 {"ATETXCNT", Set_ATE_TX_COUNT_Proc},
301 {"ATETXMCS", Set_ATE_TX_MCS_Proc},
302 {"ATETXMODE", Set_ATE_TX_MODE_Proc},
303 {"ATETXGI", Set_ATE_TX_GI_Proc},
304 {"ATERXFER", Set_ATE_RX_FER_Proc},
305 {"ATERRF", Set_ATE_Read_RF_Proc},
306 {"ATEWRF1", Set_ATE_Write_RF1_Proc},
307 {"ATEWRF2", Set_ATE_Write_RF2_Proc},
308 {"ATEWRF3", Set_ATE_Write_RF3_Proc},
309 {"ATEWRF4", Set_ATE_Write_RF4_Proc},
310 {"ATELDE2P", Set_ATE_Load_E2P_Proc},
311 {"ATERE2P", Set_ATE_Read_E2P_Proc},
312 {"ATESHOW", Set_ATE_Show_Proc},
313 {"ATEHELP", Set_ATE_Help_Proc},
314
315#ifdef RALINK_28xx_QA
316 {"TxStop", Set_TxStop_Proc},
317 {"RxStop", Set_RxStop_Proc},
318#endif // RALINK_28xx_QA //
319#endif // RALINK_ATE //
320
321#ifdef WPA_SUPPLICANT_SUPPORT
322 {"WpaSupport", Set_Wpa_Support},
323#endif // WPA_SUPPLICANT_SUPPORT //
324
325
326
327 {"FixedTxMode", Set_FixedTxMode_Proc},
328#ifdef CONFIG_APSTA_MIXED_SUPPORT
329 {"OpMode", Set_OpMode_Proc},
330#endif // CONFIG_APSTA_MIXED_SUPPORT //
331#ifdef DOT11_N_SUPPORT
332 {"TGnWifiTest", Set_TGnWifiTest_Proc},
333 {"ForceGF", Set_ForceGF_Proc},
334#endif // DOT11_N_SUPPORT //
335#ifdef QOS_DLS_SUPPORT
336 {"DlsAddEntry", Set_DlsAddEntry_Proc},
337 {"DlsTearDownEntry", Set_DlsTearDownEntry_Proc},
338#endif // QOS_DLS_SUPPORT //
339 {"LongRetry", Set_LongRetryLimit_Proc},
340 {"ShortRetry", Set_ShortRetryLimit_Proc},
341#ifdef EXT_BUILD_CHANNEL_LIST
342 {"11dClientMode", Set_Ieee80211dClientMode_Proc},
343#endif // EXT_BUILD_CHANNEL_LIST //
344#ifdef CARRIER_DETECTION_SUPPORT
345 {"CarrierDetect", Set_CarrierDetect_Proc},
346#endif // CARRIER_DETECTION_SUPPORT //
347
348 {NULL,}
349};
350
351
352VOID RTMPAddKey(
353 IN PRTMP_ADAPTER pAd,
354 IN PNDIS_802_11_KEY pKey)
355{
356 ULONG KeyIdx;
357 MAC_TABLE_ENTRY *pEntry;
358
359 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
360
361 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
362 {
363 if (pKey->KeyIndex & 0x80000000)
364 {
365 if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
366 {
367 NdisZeroMemory(pAd->StaCfg.PMK, 32);
368 NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
369 goto end;
370 }
371 // Update PTK
372 NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
373 pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
374 NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
375#ifdef WPA_SUPPLICANT_SUPPORT
376 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
377 {
378 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
379 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
380 }
381 else
382#endif // WPA_SUPPLICANT_SUPPORT //
383 {
384 NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
385 NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
386 }
387
388 // Decide its ChiperAlg
389 if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
390 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
391 else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
392 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
393 else
394 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
395
396 // Update these related information to MAC_TABLE_ENTRY
397 pEntry = &pAd->MacTab.Content[BSSID_WCID];
398 NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
399 NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
400 NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
401 pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
402
403 // Update pairwise key information to ASIC Shared Key Table
404 AsicAddSharedKeyEntry(pAd,
405 BSS0,
406 0,
407 pAd->SharedKey[BSS0][0].CipherAlg,
408 pAd->SharedKey[BSS0][0].Key,
409 pAd->SharedKey[BSS0][0].TxMic,
410 pAd->SharedKey[BSS0][0].RxMic);
411
412 // Update ASIC WCID attribute table and IVEIV table
413 RTMPAddWcidAttributeEntry(pAd,
414 BSS0,
415 0,
416 pAd->SharedKey[BSS0][0].CipherAlg,
417 pEntry);
418
419 if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
420 {
421 // set 802.1x port control
422 STA_PORT_SECURED(pAd);
423
424 // Indicate Connected for GUI
425 pAd->IndicateMediaState = NdisMediaStateConnected;
426 }
427 }
428 else
429 {
430 // Update GTK
431 pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
432 NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
433 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
434 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
435#ifdef WPA_SUPPLICANT_SUPPORT
436 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
437 {
438 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
439 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
440 }
441 else
442#endif // WPA_SUPPLICANT_SUPPORT //
443 {
444 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
445 NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
446 }
447
448 // Update Shared Key CipherAlg
449 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
450 if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
451 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
452 else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
453 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
454
455 // Update group key information to ASIC Shared Key Table
456 AsicAddSharedKeyEntry(pAd,
457 BSS0,
458 pAd->StaCfg.DefaultKeyId,
459 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
460 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
461 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
462 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
463
464 // Update ASIC WCID attribute table and IVEIV table
465 RTMPAddWcidAttributeEntry(pAd,
466 BSS0,
467 pAd->StaCfg.DefaultKeyId,
468 pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
469 NULL);
470
471 // set 802.1x port control
472 STA_PORT_SECURED(pAd);
473
474 // Indicate Connected for GUI
475 pAd->IndicateMediaState = NdisMediaStateConnected;
476 }
477 }
478 else // dynamic WEP from wpa_supplicant
479 {
480 UCHAR CipherAlg;
481 PUCHAR Key;
482
483 if(pKey->KeyLength == 32)
484 goto end;
485
486 KeyIdx = pKey->KeyIndex & 0x0fffffff;
487
488 if (KeyIdx < 4)
489 {
490 // it is a default shared key, for Pairwise key setting
491 if (pKey->KeyIndex & 0x80000000)
492 {
493 pEntry = MacTableLookup(pAd, pKey->BSSID);
494
495 if (pEntry)
496 {
497 DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
498
499 // set key material and key length
500 pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
501 NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
502
503 // set Cipher type
504 if (pKey->KeyLength == 5)
505 pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
506 else
507 pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
508
509 // Add Pair-wise key to Asic
510 AsicAddPairwiseKeyEntry(
511 pAd,
512 pEntry->Addr,
513 (UCHAR)pEntry->Aid,
514 &pEntry->PairwiseKey);
515
516 // update WCID attribute table and IVEIV table for this entry
517 RTMPAddWcidAttributeEntry(
518 pAd,
519 BSS0,
520 KeyIdx, // The value may be not zero
521 pEntry->PairwiseKey.CipherAlg,
522 pEntry);
523
524 }
525 }
526 else
527 {
528 // Default key for tx (shared key)
529 pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
530
531 // set key material and key length
532 pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
533 NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
534
535 // Set Ciper type
536 if (pKey->KeyLength == 5)
537 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
538 else
539 pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
540
541 CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
542 Key = pAd->SharedKey[BSS0][KeyIdx].Key;
543
544 // Set Group key material to Asic
545 AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
546
547 // Update WCID attribute table and IVEIV table for this group key table
548 RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
549
550 }
551 }
552 }
553end:
554 return;
555}
556
557char * rtstrchr(const char * s, int c)
558{
559 for(; *s != (char) c; ++s)
560 if (*s == '\0')
561 return NULL;
562 return (char *) s;
563}
564
565/*
566This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
567*/
568
569int
570rt_ioctl_giwname(struct net_device *dev,
571 struct iw_request_info *info,
572 char *name, char *extra)
573{
574// PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
575
576#ifdef RT2860
577 strncpy(name, "RT2860 Wireless", IFNAMSIZ);
578#endif // RT2860 //
579 return 0;
580}
581
582int rt_ioctl_siwfreq(struct net_device *dev,
583 struct iw_request_info *info,
584 struct iw_freq *freq, char *extra)
585{
586 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
587 int chan = -1;
588
589 //check if the interface is down
590 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
591 {
592 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
593 return -ENETDOWN;
594 }
595
596
597 if (freq->e > 1)
598 return -EINVAL;
599
600 if((freq->e == 0) && (freq->m <= 1000))
601 chan = freq->m; // Setting by channel number
602 else
603 MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
604
605 if (ChannelSanity(pAdapter, chan) == TRUE)
606 {
607 pAdapter->CommonCfg.Channel = chan;
608 DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
609 }
610 else
611 return -EINVAL;
612
613 return 0;
614}
615int rt_ioctl_giwfreq(struct net_device *dev,
616 struct iw_request_info *info,
617 struct iw_freq *freq, char *extra)
618{
619 VIRTUAL_ADAPTER *pVirtualAd = NULL;
620 PRTMP_ADAPTER pAdapter = NULL;
621 UCHAR ch;
622 ULONG m;
623
624 if (dev->priv_flags == INT_MAIN)
625 {
626 pAdapter = dev->priv;
627 }
628 else
629 {
630 pVirtualAd = dev->priv;
631 if (pVirtualAd && pVirtualAd->RtmpDev)
632 pAdapter = pVirtualAd->RtmpDev->priv;
633 }
634
635 if (pAdapter == NULL)
636 {
637 /* if 1st open fail, pAd will be free;
638 So the net_dev->priv will be NULL in 2rd open */
639 return -ENETDOWN;
640 }
641
642 ch = pAdapter->CommonCfg.Channel;
643
644 DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq %d\n", ch));
645
646 MAP_CHANNEL_ID_TO_KHZ(ch, m);
647 freq->m = m * 100;
648 freq->e = 1;
649 return 0;
650}
651
652int rt_ioctl_siwmode(struct net_device *dev,
653 struct iw_request_info *info,
654 __u32 *mode, char *extra)
655{
656 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
657
658 //check if the interface is down
659 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
660 {
661 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
662 return -ENETDOWN;
663 }
664
665 switch (*mode)
666 {
667 case IW_MODE_ADHOC:
668 Set_NetworkType_Proc(pAdapter, "Adhoc");
669 break;
670 case IW_MODE_INFRA:
671 Set_NetworkType_Proc(pAdapter, "Infra");
672 break;
673#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
674 case IW_MODE_MONITOR:
675 Set_NetworkType_Proc(pAdapter, "Monitor");
676 break;
677#endif
678 default:
679 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
680 return -EINVAL;
681 }
682
683 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
684 pAdapter->StaCfg.WpaState = SS_NOTUSE;
685
686 return 0;
687}
688
689int rt_ioctl_giwmode(struct net_device *dev,
690 struct iw_request_info *info,
691 __u32 *mode, char *extra)
692{
693 PRTMP_ADAPTER pAdapter = NULL;
694 VIRTUAL_ADAPTER *pVirtualAd = NULL;
695
696 if (dev->priv_flags == INT_MAIN)
697 {
698 pAdapter = dev->priv;
699 }
700 else
701 {
702 pVirtualAd = dev->priv;
703 if (pVirtualAd && pVirtualAd->RtmpDev)
704 pAdapter = pVirtualAd->RtmpDev->priv;
705 }
706
707 if (pAdapter == NULL)
708 {
709 /* if 1st open fail, pAd will be free;
710 So the net_dev->priv will be NULL in 2rd open */
711 return -ENETDOWN;
712 }
713
714 if (ADHOC_ON(pAdapter))
715 *mode = IW_MODE_ADHOC;
716 else if (INFRA_ON(pAdapter))
717 *mode = IW_MODE_INFRA;
718#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
719 else if (MONITOR_ON(pAdapter))
720 {
721 *mode = IW_MODE_MONITOR;
722 }
723#endif
724 else
725 *mode = IW_MODE_AUTO;
726
727 DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
728 return 0;
729}
730
731int rt_ioctl_siwsens(struct net_device *dev,
732 struct iw_request_info *info,
733 char *name, char *extra)
734{
735 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
736
737 //check if the interface is down
738 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
739 {
740 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
741 return -ENETDOWN;
742 }
743
744 return 0;
745}
746
747int rt_ioctl_giwsens(struct net_device *dev,
748 struct iw_request_info *info,
749 char *name, char *extra)
750{
751 return 0;
752}
753
754int rt_ioctl_giwrange(struct net_device *dev,
755 struct iw_request_info *info,
756 struct iw_point *data, char *extra)
757{
758 PRTMP_ADAPTER pAdapter = NULL;
759 VIRTUAL_ADAPTER *pVirtualAd = NULL;
760 struct iw_range *range = (struct iw_range *) extra;
761 u16 val;
762 int i;
763
764 if (dev->priv_flags == INT_MAIN)
765 {
766 pAdapter = dev->priv;
767 }
768 else
769 {
770 pVirtualAd = dev->priv;
771 if (pVirtualAd && pVirtualAd->RtmpDev)
772 pAdapter = pVirtualAd->RtmpDev->priv;
773 }
774
775 if (pAdapter == NULL)
776 {
777 /* if 1st open fail, pAd will be free;
778 So the net_dev->priv will be NULL in 2rd open */
779 return -ENETDOWN;
780 }
781
782 DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
783 data->length = sizeof(struct iw_range);
784 memset(range, 0, sizeof(struct iw_range));
785
786 range->txpower_capa = IW_TXPOW_DBM;
787
788 if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
789 {
790 range->min_pmp = 1 * 1024;
791 range->max_pmp = 65535 * 1024;
792 range->min_pmt = 1 * 1024;
793 range->max_pmt = 1000 * 1024;
794 range->pmp_flags = IW_POWER_PERIOD;
795 range->pmt_flags = IW_POWER_TIMEOUT;
796 range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
797 IW_POWER_UNICAST_R | IW_POWER_ALL_R;
798 }
799
800 range->we_version_compiled = WIRELESS_EXT;
801 range->we_version_source = 14;
802
803 range->retry_capa = IW_RETRY_LIMIT;
804 range->retry_flags = IW_RETRY_LIMIT;
805 range->min_retry = 0;
806 range->max_retry = 255;
807
808 range->num_channels = pAdapter->ChannelListNum;
809
810 val = 0;
811 for (i = 1; i <= range->num_channels; i++)
812 {
813 u32 m;
814 range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
815 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
816 range->freq[val].m = m * 100; /* HZ */
817
818 range->freq[val].e = 1;
819 val++;
820 if (val == IW_MAX_FREQUENCIES)
821 break;
822 }
823 range->num_frequency = val;
824
825 range->max_qual.qual = 100; /* what is correct max? This was not
826 * documented exactly. At least
827 * 69 has been observed. */
828 range->max_qual.level = 0; /* dB */
829 range->max_qual.noise = 0; /* dB */
830
831 /* What would be suitable values for "average/typical" qual? */
832 range->avg_qual.qual = 20;
833 range->avg_qual.level = -60;
834 range->avg_qual.noise = -95;
835 range->sensitivity = 3;
836
837 range->max_encoding_tokens = NR_WEP_KEYS;
838 range->num_encoding_sizes = 2;
839 range->encoding_size[0] = 5;
840 range->encoding_size[1] = 13;
841
842 range->min_rts = 0;
843 range->max_rts = 2347;
844 range->min_frag = 256;
845 range->max_frag = 2346;
846
847#if WIRELESS_EXT > 17
848 /* IW_ENC_CAPA_* bit field */
849 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
850 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
851#endif
852
853 return 0;
854}
855
856int rt_ioctl_siwap(struct net_device *dev,
857 struct iw_request_info *info,
858 struct sockaddr *ap_addr, char *extra)
859{
860 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
861 NDIS_802_11_MAC_ADDRESS Bssid;
862
863 //check if the interface is down
864 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
865 {
866 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
867 return -ENETDOWN;
868 }
869
870 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
871 {
872 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
873 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
874 }
875
876 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
877 // this request, because this request is initiated by NDIS.
878 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
879 // Prevent to connect AP again in STAMlmePeriodicExec
880 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
881
882 memset(Bssid, 0, MAC_ADDR_LEN);
883 memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
884 MlmeEnqueue(pAdapter,
885 MLME_CNTL_STATE_MACHINE,
886 OID_802_11_BSSID,
887 sizeof(NDIS_802_11_MAC_ADDRESS),
888 (VOID *)&Bssid);
889
890 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
891 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
892
893 return 0;
894}
895
896int rt_ioctl_giwap(struct net_device *dev,
897 struct iw_request_info *info,
898 struct sockaddr *ap_addr, char *extra)
899{
900 PRTMP_ADAPTER pAdapter = NULL;
901 VIRTUAL_ADAPTER *pVirtualAd = NULL;
902
903 if (dev->priv_flags == INT_MAIN)
904 {
905 pAdapter = dev->priv;
906 }
907 else
908 {
909 pVirtualAd = dev->priv;
910 if (pVirtualAd && pVirtualAd->RtmpDev)
911 pAdapter = pVirtualAd->RtmpDev->priv;
912 }
913
914 if (pAdapter == NULL)
915 {
916 /* if 1st open fail, pAd will be free;
917 So the net_dev->priv will be NULL in 2rd open */
918 return -ENETDOWN;
919 }
920
921 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
922 {
923 ap_addr->sa_family = ARPHRD_ETHER;
924 memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
925 }
926#ifdef WPA_SUPPLICANT_SUPPORT
927 // Add for RT2870
928 else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
929 {
930 ap_addr->sa_family = ARPHRD_ETHER;
931 memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
932 }
933#endif // WPA_SUPPLICANT_SUPPORT //
934 else
935 {
936 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
937 return -ENOTCONN;
938 }
939
940 return 0;
941}
942
943/*
944 * Units are in db above the noise floor. That means the
945 * rssi values reported in the tx/rx descriptors in the
946 * driver are the SNR expressed in db.
947 *
948 * If you assume that the noise floor is -95, which is an
949 * excellent assumption 99.5 % of the time, then you can
950 * derive the absolute signal level (i.e. -95 + rssi).
951 * There are some other slight factors to take into account
952 * depending on whether the rssi measurement is from 11b,
953 * 11g, or 11a. These differences are at most 2db and
954 * can be documented.
955 *
956 * NB: various calculations are based on the orinoco/wavelan
957 * drivers for compatibility
958 */
959static void set_quality(PRTMP_ADAPTER pAdapter,
960 struct iw_quality *iq,
961 signed char rssi)
962{
963 __u8 ChannelQuality;
964
965 // Normalize Rssi
966 if (rssi >= -50)
967 ChannelQuality = 100;
968 else if (rssi >= -80) // between -50 ~ -80dbm
969 ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
970 else if (rssi >= -90) // between -80 ~ -90dbm
971 ChannelQuality = (__u8)((rssi + 90) * 26)/10;
972 else
973 ChannelQuality = 0;
974
975 iq->qual = (__u8)ChannelQuality;
976
977 iq->level = (__u8)(rssi);
978 iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); // noise level (dBm)
979 iq->noise += 256 - 143;
980 iq->updated = pAdapter->iw_stats.qual.updated;
981}
982
983int rt_ioctl_iwaplist(struct net_device *dev,
984 struct iw_request_info *info,
985 struct iw_point *data, char *extra)
986{
987 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
988
989 struct sockaddr addr[IW_MAX_AP];
990 struct iw_quality qual[IW_MAX_AP];
991 int i;
992
993 //check if the interface is down
994 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
995 {
996 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
997 data->length = 0;
998 return 0;
999 //return -ENETDOWN;
1000 }
1001
1002 for (i = 0; i <IW_MAX_AP ; i++)
1003 {
1004 if (i >= pAdapter->ScanTab.BssNr)
1005 break;
1006 addr[i].sa_family = ARPHRD_ETHER;
1007 memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
1008 set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
1009 }
1010 data->length = i;
1011 memcpy(extra, &addr, i*sizeof(addr[0]));
1012 data->flags = 1; /* signal quality present (sort of) */
1013 memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
1014
1015 return 0;
1016}
1017
1018#ifdef SIOCGIWSCAN
1019int rt_ioctl_siwscan(struct net_device *dev,
1020 struct iw_request_info *info,
1021 struct iw_point *data, char *extra)
1022{
1023 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1024
1025 ULONG Now;
1026 int Status = NDIS_STATUS_SUCCESS;
1027
1028 //check if the interface is down
1029 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1030 {
1031 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1032 return -ENETDOWN;
1033 }
1034
1035 if (MONITOR_ON(pAdapter))
1036 {
1037 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
1038 return -EINVAL;
1039 }
1040
1041
1042#ifdef WPA_SUPPLICANT_SUPPORT
1043 if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
1044 {
1045 pAdapter->StaCfg.WpaSupplicantScanCount++;
1046 }
1047#endif // WPA_SUPPLICANT_SUPPORT //
1048
1049 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
1050 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1051 return 0;
1052 do{
1053 Now = jiffies;
1054
1055#ifdef WPA_SUPPLICANT_SUPPORT
1056 if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
1057 (pAdapter->StaCfg.WpaSupplicantScanCount > 3))
1058 {
1059 DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
1060 Status = NDIS_STATUS_SUCCESS;
1061 break;
1062 }
1063#endif // WPA_SUPPLICANT_SUPPORT //
1064
1065 if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
1066 ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
1067 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
1068 (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
1069 {
1070 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
1071 Status = NDIS_STATUS_SUCCESS;
1072 break;
1073 }
1074
1075 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
1076 {
1077 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
1078 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
1079 }
1080
1081 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
1082 // this request, because this request is initiated by NDIS.
1083 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
1084 // Reset allowed scan retries
1085 pAdapter->StaCfg.ScanCnt = 0;
1086 pAdapter->StaCfg.LastScanTime = Now;
1087
1088 MlmeEnqueue(pAdapter,
1089 MLME_CNTL_STATE_MACHINE,
1090 OID_802_11_BSSID_LIST_SCAN,
1091 0,
1092 NULL);
1093
1094 Status = NDIS_STATUS_SUCCESS;
1095 RT28XX_MLME_HANDLER(pAdapter);
1096 }while(0);
1097 return 0;
1098}
1099
1100int rt_ioctl_giwscan(struct net_device *dev,
1101 struct iw_request_info *info,
1102 struct iw_point *data, char *extra)
1103{
1104
1105 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1106 int i=0;
1107 char *current_ev = extra, *previous_ev = extra;
1108 char *end_buf;
1109 char *current_val, custom[MAX_CUSTOM_LEN] = {0};
1110#ifndef IWEVGENIE
1111 char idx;
1112#endif // IWEVGENIE //
1113 struct iw_event iwe;
1114
1115 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
1116 {
1117 /*
1118 * Still scanning, indicate the caller should try again.
1119 */
1120 return -EAGAIN;
1121 }
1122
1123
1124#ifdef WPA_SUPPLICANT_SUPPORT
1125 if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
1126 {
1127 pAdapter->StaCfg.WpaSupplicantScanCount = 0;
1128 }
1129#endif // WPA_SUPPLICANT_SUPPORT //
1130
1131 if (pAdapter->ScanTab.BssNr == 0)
1132 {
1133 data->length = 0;
1134 return 0;
1135 }
1136
1137#if WIRELESS_EXT >= 17
1138 if (data->length > 0)
1139 end_buf = extra + data->length;
1140 else
1141 end_buf = extra + IW_SCAN_MAX_DATA;
1142#else
1143 end_buf = extra + IW_SCAN_MAX_DATA;
1144#endif
1145
1146 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
1147 {
1148 if (current_ev >= end_buf)
1149 {
1150#if WIRELESS_EXT >= 17
1151 return -E2BIG;
1152#else
1153 break;
1154#endif
1155 }
1156
1157 //MAC address
1158 //================================
1159 memset(&iwe, 0, sizeof(iwe));
1160 iwe.cmd = SIOCGIWAP;
1161 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1162 memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
1163
1164 previous_ev = current_ev;
1165 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN);
1166 if (current_ev == previous_ev)
1167#if WIRELESS_EXT >= 17
1168 return -E2BIG;
1169#else
1170 break;
1171#endif
1172
1173 //ESSID
1174 //================================
1175 memset(&iwe, 0, sizeof(iwe));
1176 iwe.cmd = SIOCGIWESSID;
1177 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
1178 iwe.u.data.flags = 1;
1179
1180 previous_ev = current_ev;
1181 current_ev = IWE_STREAM_ADD_POINT(info, current_ev,end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
1182 if (current_ev == previous_ev)
1183#if WIRELESS_EXT >= 17
1184 return -E2BIG;
1185#else
1186 break;
1187#endif
1188
1189 //Network Type
1190 //================================
1191 memset(&iwe, 0, sizeof(iwe));
1192 iwe.cmd = SIOCGIWMODE;
1193 if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
1194 {
1195 iwe.u.mode = IW_MODE_ADHOC;
1196 }
1197 else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
1198 {
1199 iwe.u.mode = IW_MODE_INFRA;
1200 }
1201 else
1202 {
1203 iwe.u.mode = IW_MODE_AUTO;
1204 }
1205 iwe.len = IW_EV_UINT_LEN;
1206
1207 previous_ev = current_ev;
1208 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
1209 if (current_ev == previous_ev)
1210#if WIRELESS_EXT >= 17
1211 return -E2BIG;
1212#else
1213 break;
1214#endif
1215
1216 //Channel and Frequency
1217 //================================
1218 memset(&iwe, 0, sizeof(iwe));
1219 iwe.cmd = SIOCGIWFREQ;
1220 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
1221 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1222 else
1223 iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
1224 iwe.u.freq.e = 0;
1225 iwe.u.freq.i = 0;
1226
1227 previous_ev = current_ev;
1228 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev,end_buf, &iwe, IW_EV_FREQ_LEN);
1229 if (current_ev == previous_ev)
1230#if WIRELESS_EXT >= 17
1231 return -E2BIG;
1232#else
1233 break;
1234#endif
1235
1236 //Add quality statistics
1237 //================================
1238 memset(&iwe, 0, sizeof(iwe));
1239 iwe.cmd = IWEVQUAL;
1240 iwe.u.qual.level = 0;
1241 iwe.u.qual.noise = 0;
1242 set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
1243 current_ev = IWE_STREAM_ADD_EVENT(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
1244 if (current_ev == previous_ev)
1245#if WIRELESS_EXT >= 17
1246 return -E2BIG;
1247#else
1248 break;
1249#endif
1250
1251 //Encyption key
1252 //================================
1253 memset(&iwe, 0, sizeof(iwe));
1254 iwe.cmd = SIOCGIWENCODE;
1255 if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
1256 iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1257 else
1258 iwe.u.data.flags = IW_ENCODE_DISABLED;
1259
1260 previous_ev = current_ev;
1261 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);
1262 if (current_ev == previous_ev)
1263#if WIRELESS_EXT >= 17
1264 return -E2BIG;
1265#else
1266 break;
1267#endif
1268
1269 //Bit Rate
1270 //================================
1271 if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
1272 {
1273 UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
1274 memset(&iwe, 0, sizeof(iwe));
1275 iwe.cmd = SIOCGIWRATE;
1276 current_val = current_ev + IW_EV_LCP_LEN;
1277 if (tmpRate == 0x82)
1278 iwe.u.bitrate.value = 1 * 1000000;
1279 else if (tmpRate == 0x84)
1280 iwe.u.bitrate.value = 2 * 1000000;
1281 else if (tmpRate == 0x8B)
1282 iwe.u.bitrate.value = 5.5 * 1000000;
1283 else if (tmpRate == 0x96)
1284 iwe.u.bitrate.value = 11 * 1000000;
1285 else
1286 iwe.u.bitrate.value = (tmpRate/2) * 1000000;
1287
1288 iwe.u.bitrate.disabled = 0;
1289 current_val = IWE_STREAM_ADD_VALUE(info, current_ev,
1290 current_val, end_buf, &iwe,
1291 IW_EV_PARAM_LEN);
1292
1293 if((current_val-current_ev)>IW_EV_LCP_LEN)
1294 current_ev = current_val;
1295 else
1296#if WIRELESS_EXT >= 17
1297 return -E2BIG;
1298#else
1299 break;
1300#endif
1301 }
1302
1303#ifdef IWEVGENIE
1304 //WPA IE
1305 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1306 {
1307 memset(&iwe, 0, sizeof(iwe));
1308 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1309 memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
1310 pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
1311 iwe.cmd = IWEVGENIE;
1312 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
1313 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1314 if (current_ev == previous_ev)
1315#if WIRELESS_EXT >= 17
1316 return -E2BIG;
1317#else
1318 break;
1319#endif
1320 }
1321
1322 //WPA2 IE
1323 if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1324 {
1325 memset(&iwe, 0, sizeof(iwe));
1326 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1327 memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
1328 pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
1329 iwe.cmd = IWEVGENIE;
1330 iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
1331 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1332 if (current_ev == previous_ev)
1333#if WIRELESS_EXT >= 17
1334 return -E2BIG;
1335#else
1336 break;
1337#endif
1338 }
1339#else
1340 //WPA IE
1341 //================================
1342 if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
1343 {
1344 NdisZeroMemory(&iwe, sizeof(iwe));
1345 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1346 iwe.cmd = IWEVCUSTOM;
1347 iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen * 2) + 7;
1348 NdisMoveMemory(custom, "wpa_ie=", 7);
1349 for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].WpaIE.IELen; idx++)
1350 sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].WpaIE.IE[idx]);
1351 previous_ev = current_ev;
1352 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1353 if (current_ev == previous_ev)
1354#if WIRELESS_EXT >= 17
1355 return -E2BIG;
1356#else
1357 break;
1358#endif
1359 }
1360
1361 //WPA2 IE
1362 if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
1363 {
1364 NdisZeroMemory(&iwe, sizeof(iwe));
1365 memset(&custom[0], 0, MAX_CUSTOM_LEN);
1366 iwe.cmd = IWEVCUSTOM;
1367 iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen * 2) + 7;
1368 NdisMoveMemory(custom, "rsn_ie=", 7);
1369 for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].RsnIE.IELen; idx++)
1370 sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].RsnIE.IE[idx]);
1371 previous_ev = current_ev;
1372 current_ev = IWE_STREAM_ADD_POINT(info, current_ev, end_buf, &iwe, custom);
1373 if (current_ev == previous_ev)
1374#if WIRELESS_EXT >= 17
1375 return -E2BIG;
1376#else
1377 break;
1378#endif
1379 }
1380#endif // IWEVGENIE //
1381 }
1382
1383 data->length = current_ev - extra;
1384 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
1385 DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
1386 return 0;
1387}
1388#endif
1389
1390int rt_ioctl_siwessid(struct net_device *dev,
1391 struct iw_request_info *info,
1392 struct iw_point *data, char *essid)
1393{
1394 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1395
1396 //check if the interface is down
1397 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1398 {
1399 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1400 return -ENETDOWN;
1401 }
1402
1403 if (data->flags)
1404 {
1405 PCHAR pSsidString = NULL;
1406
1407 // Includes null character.
1408 if (data->length > (IW_ESSID_MAX_SIZE + 1))
1409 return -E2BIG;
1410
1411 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
1412 if (pSsidString)
1413 {
1414 NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
1415 NdisMoveMemory(pSsidString, essid, data->length);
1416 if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
1417 return -EINVAL;
1418 }
1419 else
1420 return -ENOMEM;
1421 }
1422 else
1423 {
1424 // ANY ssid
1425 if (Set_SSID_Proc(pAdapter, "") == FALSE)
1426 return -EINVAL;
1427 }
1428 return 0;
1429}
1430
1431int rt_ioctl_giwessid(struct net_device *dev,
1432 struct iw_request_info *info,
1433 struct iw_point *data, char *essid)
1434{
1435 PRTMP_ADAPTER pAdapter = NULL;
1436 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1437
1438 if (dev->priv_flags == INT_MAIN)
1439 {
1440 pAdapter = dev->priv;
1441 }
1442 else
1443 {
1444 pVirtualAd = dev->priv;
1445 if (pVirtualAd && pVirtualAd->RtmpDev)
1446 pAdapter = pVirtualAd->RtmpDev->priv;
1447 }
1448
1449 if (pAdapter == NULL)
1450 {
1451 /* if 1st open fail, pAd will be free;
1452 So the net_dev->priv will be NULL in 2rd open */
1453 return -ENETDOWN;
1454 }
1455
1456 data->flags = 1;
1457 if (MONITOR_ON(pAdapter))
1458 {
1459 data->length = 0;
1460 return 0;
1461 }
1462
1463 if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
1464 {
1465 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
1466 data->length = pAdapter->CommonCfg.SsidLen;
1467 memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
1468 }
1469 else
1470 {//the ANY ssid was specified
1471 data->length = 0;
1472 DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
1473 }
1474
1475 return 0;
1476
1477}
1478
1479int rt_ioctl_siwnickn(struct net_device *dev,
1480 struct iw_request_info *info,
1481 struct iw_point *data, char *nickname)
1482{
1483 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1484
1485 //check if the interface is down
1486 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1487 {
1488 DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
1489 return -ENETDOWN;
1490 }
1491
1492 if (data->length > IW_ESSID_MAX_SIZE)
1493 return -EINVAL;
1494
1495 memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
1496 memcpy(pAdapter->nickname, nickname, data->length);
1497
1498
1499 return 0;
1500}
1501
1502int rt_ioctl_giwnickn(struct net_device *dev,
1503 struct iw_request_info *info,
1504 struct iw_point *data, char *nickname)
1505{
1506 PRTMP_ADAPTER pAdapter = NULL;
1507 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1508
1509 if (dev->priv_flags == INT_MAIN)
1510 {
1511 pAdapter = dev->priv;
1512 }
1513 else
1514 {
1515 pVirtualAd = dev->priv;
1516 if (pVirtualAd && pVirtualAd->RtmpDev)
1517 pAdapter = pVirtualAd->RtmpDev->priv;
1518 }
1519
1520 if (pAdapter == NULL)
1521 {
1522 /* if 1st open fail, pAd will be free;
1523 So the net_dev->priv will be NULL in 2rd open */
1524 return -ENETDOWN;
1525 }
1526
1527 if (data->length > strlen(pAdapter->nickname) + 1)
1528 data->length = strlen(pAdapter->nickname) + 1;
1529 if (data->length > 0) {
1530 memcpy(nickname, pAdapter->nickname, data->length-1);
1531 nickname[data->length-1] = '\0';
1532 }
1533 return 0;
1534}
1535
1536int rt_ioctl_siwrts(struct net_device *dev,
1537 struct iw_request_info *info,
1538 struct iw_param *rts, char *extra)
1539{
1540 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1541 u16 val;
1542
1543 //check if the interface is down
1544 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1545 {
1546 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1547 return -ENETDOWN;
1548 }
1549
1550 if (rts->disabled)
1551 val = MAX_RTS_THRESHOLD;
1552 else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
1553 return -EINVAL;
1554 else if (rts->value == 0)
1555 val = MAX_RTS_THRESHOLD;
1556 else
1557 val = rts->value;
1558
1559 if (val != pAdapter->CommonCfg.RtsThreshold)
1560 pAdapter->CommonCfg.RtsThreshold = val;
1561
1562 return 0;
1563}
1564
1565int rt_ioctl_giwrts(struct net_device *dev,
1566 struct iw_request_info *info,
1567 struct iw_param *rts, char *extra)
1568{
1569 PRTMP_ADAPTER pAdapter = NULL;
1570 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1571
1572 if (dev->priv_flags == INT_MAIN)
1573 {
1574 pAdapter = dev->priv;
1575 }
1576 else
1577 {
1578 pVirtualAd = dev->priv;
1579 if (pVirtualAd && pVirtualAd->RtmpDev)
1580 pAdapter = pVirtualAd->RtmpDev->priv;
1581 }
1582
1583 if (pAdapter == NULL)
1584 {
1585 /* if 1st open fail, pAd will be free;
1586 So the net_dev->priv will be NULL in 2rd open */
1587 return -ENETDOWN;
1588 }
1589
1590 //check if the interface is down
1591 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1592 {
1593 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1594 return -ENETDOWN;
1595 }
1596
1597 rts->value = pAdapter->CommonCfg.RtsThreshold;
1598 rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
1599 rts->fixed = 1;
1600
1601 return 0;
1602}
1603
1604int rt_ioctl_siwfrag(struct net_device *dev,
1605 struct iw_request_info *info,
1606 struct iw_param *frag, char *extra)
1607{
1608 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1609 u16 val;
1610
1611 //check if the interface is down
1612 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1613 {
1614 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1615 return -ENETDOWN;
1616 }
1617
1618 if (frag->disabled)
1619 val = MAX_FRAG_THRESHOLD;
1620 else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
1621 val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
1622 else if (frag->value == 0)
1623 val = MAX_FRAG_THRESHOLD;
1624 else
1625 return -EINVAL;
1626
1627 pAdapter->CommonCfg.FragmentThreshold = val;
1628 return 0;
1629}
1630
1631int rt_ioctl_giwfrag(struct net_device *dev,
1632 struct iw_request_info *info,
1633 struct iw_param *frag, char *extra)
1634{
1635 PRTMP_ADAPTER pAdapter = NULL;
1636 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1637
1638 if (dev->priv_flags == INT_MAIN)
1639 {
1640 pAdapter = dev->priv;
1641 }
1642 else
1643 {
1644 pVirtualAd = dev->priv;
1645 if (pVirtualAd && pVirtualAd->RtmpDev)
1646 pAdapter = pVirtualAd->RtmpDev->priv;
1647 }
1648
1649 if (pAdapter == NULL)
1650 {
1651 /* if 1st open fail, pAd will be free;
1652 So the net_dev->priv will be NULL in 2rd open */
1653 return -ENETDOWN;
1654 }
1655
1656 //check if the interface is down
1657 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1658 {
1659 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1660 return -ENETDOWN;
1661 }
1662
1663 frag->value = pAdapter->CommonCfg.FragmentThreshold;
1664 frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
1665 frag->fixed = 1;
1666
1667 return 0;
1668}
1669
1670#define MAX_WEP_KEY_SIZE 13
1671#define MIN_WEP_KEY_SIZE 5
1672int rt_ioctl_siwencode(struct net_device *dev,
1673 struct iw_request_info *info,
1674 struct iw_point *erq, char *extra)
1675{
1676 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
1677
1678 //check if the interface is down
1679 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1680 {
1681 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1682 return -ENETDOWN;
1683 }
1684
1685 if ((erq->length == 0) &&
1686 (erq->flags & IW_ENCODE_DISABLED))
1687 {
1688 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
1689 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
1690 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
1691 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1692 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1693 goto done;
1694 }
1695 else if ((erq->length == 0) &&
1696 (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN))
1697 {
1698 STA_PORT_SECURED(pAdapter);
1699 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
1700 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
1701 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
1702 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
1703 if (erq->flags & IW_ENCODE_RESTRICTED)
1704 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1705 else
1706 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1707 goto done;
1708 }
1709
1710 if (erq->length > 0)
1711 {
1712 int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
1713 /* Check the size of the key */
1714 if (erq->length > MAX_WEP_KEY_SIZE) {
1715 return -EINVAL;
1716 }
1717 /* Check key index */
1718 if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
1719 {
1720 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
1721 keyIdx, pAdapter->StaCfg.DefaultKeyId));
1722
1723 //Using default key
1724 keyIdx = pAdapter->StaCfg.DefaultKeyId;
1725 }
1726
1727 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
1728
1729 if (erq->length == MAX_WEP_KEY_SIZE)
1730 {
1731 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
1732 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
1733 }
1734 else if (erq->length == MIN_WEP_KEY_SIZE)
1735 {
1736 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
1737 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
1738 }
1739 else
1740 /* Disable the key */
1741 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
1742
1743 /* Check if the key is not marked as invalid */
1744 if(!(erq->flags & IW_ENCODE_NOKEY)) {
1745 /* Copy the key in the driver */
1746 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
1747 }
1748 }
1749 else
1750 {
1751 /* Do we want to just set the transmit key index ? */
1752 int index = (erq->flags & IW_ENCODE_INDEX) - 1;
1753 if ((index >= 0) && (index < 4))
1754 {
1755 pAdapter->StaCfg.DefaultKeyId = index;
1756 }
1757 else
1758 /* Don't complain if only change the mode */
1759 if(!erq->flags & IW_ENCODE_MODE) {
1760 return -EINVAL;
1761 }
1762 }
1763
1764done:
1765 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
1766 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
1767 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
1768 DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
1769 return 0;
1770}
1771
1772int
1773rt_ioctl_giwencode(struct net_device *dev,
1774 struct iw_request_info *info,
1775 struct iw_point *erq, char *key)
1776{
1777 int kid;
1778 PRTMP_ADAPTER pAdapter = NULL;
1779 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1780
1781 if (dev->priv_flags == INT_MAIN)
1782 {
1783 pAdapter = dev->priv;
1784 }
1785 else
1786 {
1787 pVirtualAd = dev->priv;
1788 if (pVirtualAd && pVirtualAd->RtmpDev)
1789 pAdapter = pVirtualAd->RtmpDev->priv;
1790 }
1791
1792 if (pAdapter == NULL)
1793 {
1794 /* if 1st open fail, pAd will be free;
1795 So the net_dev->priv will be NULL in 2rd open */
1796 return -ENETDOWN;
1797 }
1798
1799 //check if the interface is down
1800 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1801 {
1802 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1803 return -ENETDOWN;
1804 }
1805
1806 kid = erq->flags & IW_ENCODE_INDEX;
1807 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
1808
1809 if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
1810 {
1811 erq->length = 0;
1812 erq->flags = IW_ENCODE_DISABLED;
1813 }
1814 else if ((kid > 0) && (kid <=4))
1815 {
1816 // copy wep key
1817 erq->flags = kid ; /* NB: base 1 */
1818 if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
1819 erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
1820 memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
1821 //if ((kid == pAdapter->PortCfg.DefaultKeyId))
1822 //erq->flags |= IW_ENCODE_ENABLED; /* XXX */
1823 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1824 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1825 else
1826 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1827
1828 }
1829 else if (kid == 0)
1830 {
1831 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1832 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1833 else
1834 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1835 erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
1836 memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
1837 // copy default key ID
1838 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
1839 erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
1840 else
1841 erq->flags |= IW_ENCODE_OPEN; /* XXX */
1842 erq->flags = pAdapter->StaCfg.DefaultKeyId + 1; /* NB: base 1 */
1843 erq->flags |= IW_ENCODE_ENABLED; /* XXX */
1844 }
1845
1846 return 0;
1847
1848}
1849
1850static int
1851rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
1852 void *w, char *extra)
1853{
1854 VIRTUAL_ADAPTER *pVirtualAd = NULL;
1855 PRTMP_ADAPTER pAdapter;
1856 POS_COOKIE pObj;
1857 char *this_char = extra;
1858 char *value;
1859 int Status=0;
1860
1861 if (dev->priv_flags == INT_MAIN)
1862 {
1863 pAdapter = dev->priv;
1864 }
1865 else
1866 {
1867 pVirtualAd = dev->priv;
1868 pAdapter = pVirtualAd->RtmpDev->priv;
1869 }
1870 pObj = (POS_COOKIE) pAdapter->OS_Cookie;
1871
1872 if (pAdapter == NULL)
1873 {
1874 /* if 1st open fail, pAd will be free;
1875 So the net_dev->priv will be NULL in 2rd open */
1876 return -ENETDOWN;
1877 }
1878
1879 {
1880 pObj->ioctl_if_type = INT_MAIN;
1881 pObj->ioctl_if = MAIN_MBSSID;
1882 }
1883
1884 //check if the interface is down
1885 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
1886 {
1887 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
1888 return -ENETDOWN;
1889 }
1890
1891 if (!*this_char)
1892 return -EINVAL;
1893
1894 if ((value = rtstrchr(this_char, '=')) != NULL)
1895 *value++ = 0;
1896
1897 if (!value)
1898 return -EINVAL;
1899
1900 // reject setting nothing besides ANY ssid(ssidLen=0)
1901 if (!*value && (strcmp(this_char, "SSID") != 0))
1902 return -EINVAL;
1903
1904 for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
1905 {
1906 if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
1907 {
1908 if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
1909 { //FALSE:Set private failed then return Invalid argument
1910 Status = -EINVAL;
1911 }
1912 break; //Exit for loop.
1913 }
1914 }
1915
1916 if(PRTMP_PRIVATE_SET_PROC->name == NULL)
1917 { //Not found argument
1918 Status = -EINVAL;
1919 DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
1920 }
1921
1922 return Status;
1923}
1924
1925
1926static int
1927rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
1928 struct iw_point *wrq, char *extra)
1929{
1930 INT Status = 0;
1931 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
1932
1933 if (extra == NULL)
1934 {
1935 wrq->length = 0;
1936 return -EIO;
1937 }
1938
1939 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
1940 sprintf(extra, "\n\n");
1941
1942#ifdef RALINK_ATE
1943 if (ATE_ON(pAd))
1944 {
1945 sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->ate.TxDoneCount);
1946 //sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->ate.TxDoneCount);
1947 }
1948 else
1949#endif // RALINK_ATE //
1950 {
1951 sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
1952 sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1953 }
1954 sprintf(extra+strlen(extra), "Tx success after retry = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
1955 sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
1956 sprintf(extra+strlen(extra), "RTS Success Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
1957 sprintf(extra+strlen(extra), "RTS Fail Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
1958
1959 sprintf(extra+strlen(extra), "Rx success = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
1960 sprintf(extra+strlen(extra), "Rx with CRC = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
1961 sprintf(extra+strlen(extra), "Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
1962 sprintf(extra+strlen(extra), "Rx duplicate frame = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
1963
1964 sprintf(extra+strlen(extra), "False CCA (one second) = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
1965#ifdef RALINK_ATE
1966 if (ATE_ON(pAd))
1967 {
1968 if (pAd->ate.RxAntennaSel == 0)
1969 {
1970 sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
1971 sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta));
1972 sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta));
1973 }
1974 else
1975 {
1976 sprintf(extra+strlen(extra), "RSSI = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
1977 }
1978 }
1979 else
1980#endif // RALINK_ATE //
1981 {
1982 sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
1983 sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
1984 sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
1985 }
1986#ifdef WPA_SUPPLICANT_SUPPORT
1987 sprintf(extra+strlen(extra), "WpaSupplicantUP = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
1988#endif // WPA_SUPPLICANT_SUPPORT //
1989
1990
1991 wrq->length = strlen(extra) + 1; // 1: size of '\0'
1992 DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
1993
1994 return Status;
1995}
1996
1997#ifdef DOT11_N_SUPPORT
1998void getBaInfo(
1999 IN PRTMP_ADAPTER pAd,
2000 IN PUCHAR pOutBuf)
2001{
2002 INT i, j;
2003 BA_ORI_ENTRY *pOriBAEntry;
2004 BA_REC_ENTRY *pRecBAEntry;
2005
2006 for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
2007 {
2008 PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
2009 if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
2010 || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
2011 {
2012 sprintf(pOutBuf, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
2013 pOutBuf,
2014 pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
2015 pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
2016
2017 sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
2018 for (j=0; j < NUM_OF_TID; j++)
2019 {
2020 if (pEntry->BARecWcidArray[j] != 0)
2021 {
2022 pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
2023 sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
2024 }
2025 }
2026 sprintf(pOutBuf, "%s\n", pOutBuf);
2027
2028 sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
2029 for (j=0; j < NUM_OF_TID; j++)
2030 {
2031 if (pEntry->BAOriWcidArray[j] != 0)
2032 {
2033 pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
2034 sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
2035 }
2036 }
2037 sprintf(pOutBuf, "%s\n\n", pOutBuf);
2038 }
2039 if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
2040 break;
2041 }
2042
2043 return;
2044}
2045#endif // DOT11_N_SUPPORT //
2046
2047static int
2048rt_private_show(struct net_device *dev, struct iw_request_info *info,
2049 struct iw_point *wrq, char *extra)
2050{
2051 INT Status = 0;
2052 VIRTUAL_ADAPTER *pVirtualAd = NULL;
2053 PRTMP_ADAPTER pAd;
2054 POS_COOKIE pObj;
2055 u32 subcmd = wrq->flags;
2056
2057 if (dev->priv_flags == INT_MAIN)
2058 pAd = dev->priv;
2059 else
2060 {
2061 pVirtualAd = dev->priv;
2062 pAd = pVirtualAd->RtmpDev->priv;
2063 }
2064 pObj = (POS_COOKIE) pAd->OS_Cookie;
2065
2066 if (pAd == NULL)
2067 {
2068 /* if 1st open fail, pAd will be free;
2069 So the net_dev->priv will be NULL in 2rd open */
2070 return -ENETDOWN;
2071 }
2072
2073 if (extra == NULL)
2074 {
2075 wrq->length = 0;
2076 return -EIO;
2077 }
2078 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2079
2080 {
2081 pObj->ioctl_if_type = INT_MAIN;
2082 pObj->ioctl_if = MAIN_MBSSID;
2083 }
2084
2085 switch(subcmd)
2086 {
2087
2088 case SHOW_CONN_STATUS:
2089 if (MONITOR_ON(pAd))
2090 {
2091#ifdef DOT11_N_SUPPORT
2092 if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
2093 pAd->CommonCfg.RegTransmitSetting.field.BW)
2094 sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
2095 else
2096#endif // DOT11_N_SUPPORT //
2097 sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
2098 }
2099 else
2100 {
2101 if (pAd->IndicateMediaState == NdisMediaStateConnected)
2102 {
2103 if (INFRA_ON(pAd))
2104 {
2105 sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
2106 pAd->CommonCfg.Ssid,
2107 pAd->CommonCfg.Bssid[0],
2108 pAd->CommonCfg.Bssid[1],
2109 pAd->CommonCfg.Bssid[2],
2110 pAd->CommonCfg.Bssid[3],
2111 pAd->CommonCfg.Bssid[4],
2112 pAd->CommonCfg.Bssid[5]);
2113 DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
2114 }
2115 else if (ADHOC_ON(pAd))
2116 sprintf(extra, "Connected\n");
2117 }
2118 else
2119 {
2120 sprintf(extra, "Disconnected\n");
2121 DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
2122 }
2123 }
2124 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2125 break;
2126 case SHOW_DRVIER_VERION:
2127 sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
2128 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2129 break;
2130#ifdef DOT11_N_SUPPORT
2131 case SHOW_BA_INFO:
2132 getBaInfo(pAd, extra);
2133 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2134 break;
2135#endif // DOT11_N_SUPPORT //
2136 case SHOW_DESC_INFO:
2137 {
2138 Show_DescInfo_Proc(pAd, NULL);
2139 wrq->length = 0; // 1: size of '\0'
2140 }
2141 break;
2142 case RAIO_OFF:
2143 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2144 {
2145 sprintf(extra, "Scanning\n");
2146 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2147 break;
2148 }
2149 pAd->StaCfg.bSwRadio = FALSE;
2150 if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2151 {
2152 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2153 if (pAd->StaCfg.bRadio == FALSE)
2154 {
2155 MlmeRadioOff(pAd);
2156 // Update extra information
2157 pAd->ExtraInfo = SW_RADIO_OFF;
2158 }
2159 }
2160 sprintf(extra, "Radio Off\n");
2161 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2162 break;
2163 case RAIO_ON:
2164 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
2165 {
2166 sprintf(extra, "Scanning\n");
2167 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2168 break;
2169 }
2170 pAd->StaCfg.bSwRadio = TRUE;
2171 //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
2172 {
2173 pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
2174 if (pAd->StaCfg.bRadio == TRUE)
2175 {
2176 MlmeRadioOn(pAd);
2177 // Update extra information
2178 pAd->ExtraInfo = EXTRA_INFO_CLEAR;
2179 }
2180 }
2181 sprintf(extra, "Radio On\n");
2182 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2183 break;
2184
2185
2186#ifdef QOS_DLS_SUPPORT
2187 case SHOW_DLS_ENTRY_INFO:
2188 {
2189 Set_DlsEntryInfo_Display_Proc(pAd, NULL);
2190 wrq->length = 0; // 1: size of '\0'
2191 }
2192 break;
2193#endif // QOS_DLS_SUPPORT //
2194
2195 case SHOW_CFG_VALUE:
2196 {
2197 Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
2198 if (Status == 0)
2199 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2200 }
2201 break;
2202 default:
2203 DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __FUNCTION__, subcmd));
2204 break;
2205 }
2206
2207 return Status;
2208}
2209
2210#ifdef SIOCSIWMLME
2211int rt_ioctl_siwmlme(struct net_device *dev,
2212 struct iw_request_info *info,
2213 union iwreq_data *wrqu,
2214 char *extra)
2215{
2216 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2217 struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
2218 MLME_QUEUE_ELEM MsgElem;
2219 MLME_DISASSOC_REQ_STRUCT DisAssocReq;
2220 MLME_DEAUTH_REQ_STRUCT DeAuthReq;
2221
2222 DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
2223
2224 if (pMlme == NULL)
2225 return -EINVAL;
2226
2227 switch(pMlme->cmd)
2228 {
2229#ifdef IW_MLME_DEAUTH
2230 case IW_MLME_DEAUTH:
2231 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __FUNCTION__));
2232 COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
2233 DeAuthReq.Reason = pMlme->reason_code;
2234 MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
2235 NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
2236 MlmeDeauthReqAction(pAd, &MsgElem);
2237 if (INFRA_ON(pAd))
2238 {
2239 LinkDown(pAd, FALSE);
2240 pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
2241 }
2242 break;
2243#endif // IW_MLME_DEAUTH //
2244#ifdef IW_MLME_DISASSOC
2245 case IW_MLME_DISASSOC:
2246 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __FUNCTION__));
2247 COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
2248 DisAssocReq.Reason = pMlme->reason_code;
2249
2250 MsgElem.Machine = ASSOC_STATE_MACHINE;
2251 MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
2252 MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
2253 NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
2254
2255 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
2256 MlmeDisassocReqAction(pAd, &MsgElem);
2257 break;
2258#endif // IW_MLME_DISASSOC //
2259 default:
2260 DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __FUNCTION__));
2261 break;
2262 }
2263
2264 return 0;
2265}
2266#endif // SIOCSIWMLME //
2267
2268#if WIRELESS_EXT > 17
2269int rt_ioctl_siwauth(struct net_device *dev,
2270 struct iw_request_info *info,
2271 union iwreq_data *wrqu, char *extra)
2272{
2273 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2274 struct iw_param *param = &wrqu->param;
2275
2276 //check if the interface is down
2277 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2278 {
2279 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2280 return -ENETDOWN;
2281 }
2282 switch (param->flags & IW_AUTH_INDEX) {
2283 case IW_AUTH_WPA_VERSION:
2284 if (param->value == IW_AUTH_WPA_VERSION_WPA)
2285 {
2286 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
2287 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
2288 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
2289 }
2290 else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
2291 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
2292
2293 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
2294 break;
2295 case IW_AUTH_CIPHER_PAIRWISE:
2296 if (param->value == IW_AUTH_CIPHER_NONE)
2297 {
2298 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
2299 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2300 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
2301 }
2302 else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2303 param->value == IW_AUTH_CIPHER_WEP104)
2304 {
2305 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
2306 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2307 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
2308#ifdef WPA_SUPPLICANT_SUPPORT
2309 pAdapter->StaCfg.IEEE8021X = FALSE;
2310#endif // WPA_SUPPLICANT_SUPPORT //
2311 }
2312 else if (param->value == IW_AUTH_CIPHER_TKIP)
2313 {
2314 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
2315 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2316 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2317 }
2318 else if (param->value == IW_AUTH_CIPHER_CCMP)
2319 {
2320 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
2321 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
2322 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
2323 }
2324 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __FUNCTION__, param->value));
2325 break;
2326 case IW_AUTH_CIPHER_GROUP:
2327 if (param->value == IW_AUTH_CIPHER_NONE)
2328 {
2329 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
2330 }
2331 else if (param->value == IW_AUTH_CIPHER_WEP40 ||
2332 param->value == IW_AUTH_CIPHER_WEP104)
2333 {
2334 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
2335 }
2336 else if (param->value == IW_AUTH_CIPHER_TKIP)
2337 {
2338 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
2339 }
2340 else if (param->value == IW_AUTH_CIPHER_CCMP)
2341 {
2342 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
2343 }
2344 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __FUNCTION__, param->value));
2345 break;
2346 case IW_AUTH_KEY_MGMT:
2347 if (param->value == IW_AUTH_KEY_MGMT_802_1X)
2348 {
2349 if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
2350 {
2351 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
2352#ifdef WPA_SUPPLICANT_SUPPORT
2353 pAdapter->StaCfg.IEEE8021X = FALSE;
2354#endif // WPA_SUPPLICANT_SUPPORT //
2355 }
2356 else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
2357 {
2358 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
2359#ifdef WPA_SUPPLICANT_SUPPORT
2360 pAdapter->StaCfg.IEEE8021X = FALSE;
2361#endif // WPA_SUPPLICANT_SUPPORT //
2362 }
2363#ifdef WPA_SUPPLICANT_SUPPORT
2364 else
2365 // WEP 1x
2366 pAdapter->StaCfg.IEEE8021X = TRUE;
2367#endif // WPA_SUPPLICANT_SUPPORT //
2368 }
2369 else if (param->value == 0)
2370 {
2371 STA_PORT_SECURED(pAdapter);
2372 }
2373 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __FUNCTION__, param->value));
2374 break;
2375 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2376 break;
2377 case IW_AUTH_PRIVACY_INVOKED:
2378 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __FUNCTION__, param->value));
2379 break;
2380 case IW_AUTH_DROP_UNENCRYPTED:
2381 if (param->value != 0)
2382 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
2383 else
2384 {
2385 STA_PORT_SECURED(pAdapter);
2386 }
2387 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
2388 break;
2389 case IW_AUTH_80211_AUTH_ALG:
2390 if (param->value & IW_AUTH_ALG_SHARED_KEY)
2391 {
2392 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
2393 }
2394 else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
2395 {
2396 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
2397 }
2398 else
2399 return -EINVAL;
2400 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __FUNCTION__, param->value));
2401 break;
2402 case IW_AUTH_WPA_ENABLED:
2403 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __FUNCTION__, param->value));
2404 break;
2405 default:
2406 return -EOPNOTSUPP;
2407}
2408
2409 return 0;
2410}
2411
2412int rt_ioctl_giwauth(struct net_device *dev,
2413 struct iw_request_info *info,
2414 union iwreq_data *wrqu, char *extra)
2415{
2416 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2417 struct iw_param *param = &wrqu->param;
2418
2419 //check if the interface is down
2420 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2421 {
2422 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2423 return -ENETDOWN;
2424 }
2425
2426 switch (param->flags & IW_AUTH_INDEX) {
2427 case IW_AUTH_DROP_UNENCRYPTED:
2428 param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
2429 break;
2430
2431 case IW_AUTH_80211_AUTH_ALG:
2432 param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
2433 break;
2434
2435 case IW_AUTH_WPA_ENABLED:
2436 param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
2437 break;
2438
2439 default:
2440 return -EOPNOTSUPP;
2441 }
2442 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
2443 return 0;
2444}
2445
2446void fnSetCipherKey(
2447 IN PRTMP_ADAPTER pAdapter,
2448 IN INT keyIdx,
2449 IN UCHAR CipherAlg,
2450 IN BOOLEAN bGTK,
2451 IN struct iw_encode_ext *ext)
2452{
2453 NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2454 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
2455 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
2456 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
2457 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
2458 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
2459
2460 // Update group key information to ASIC Shared Key Table
2461 AsicAddSharedKeyEntry(pAdapter,
2462 BSS0,
2463 keyIdx,
2464 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2465 pAdapter->SharedKey[BSS0][keyIdx].Key,
2466 pAdapter->SharedKey[BSS0][keyIdx].TxMic,
2467 pAdapter->SharedKey[BSS0][keyIdx].RxMic);
2468
2469 if (bGTK)
2470 // Update ASIC WCID attribute table and IVEIV table
2471 RTMPAddWcidAttributeEntry(pAdapter,
2472 BSS0,
2473 keyIdx,
2474 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2475 NULL);
2476 else
2477 // Update ASIC WCID attribute table and IVEIV table
2478 RTMPAddWcidAttributeEntry(pAdapter,
2479 BSS0,
2480 keyIdx,
2481 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
2482 &pAdapter->MacTab.Content[BSSID_WCID]);
2483}
2484
2485int rt_ioctl_siwencodeext(struct net_device *dev,
2486 struct iw_request_info *info,
2487 union iwreq_data *wrqu,
2488 char *extra)
2489 {
2490 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2491 struct iw_point *encoding = &wrqu->encoding;
2492 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2493 int keyIdx, alg = ext->alg;
2494
2495 //check if the interface is down
2496 if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2497 {
2498 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
2499 return -ENETDOWN;
2500 }
2501
2502 if (encoding->flags & IW_ENCODE_DISABLED)
2503 {
2504 keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2505 // set BSSID wcid entry of the Pair-wise Key table as no-security mode
2506 AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
2507 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
2508 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
2509 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
2510 NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
2511 DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __FUNCTION__, encoding->flags));
2512 }
2513 else
2514 {
2515 // Get Key Index and convet to our own defined key index
2516 keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
2517 if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
2518 return -EINVAL;
2519
2520 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2521 {
2522 pAdapter->StaCfg.DefaultKeyId = keyIdx;
2523 DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __FUNCTION__, pAdapter->StaCfg.DefaultKeyId));
2524 }
2525
2526 switch (alg) {
2527 case IW_ENCODE_ALG_NONE:
2528 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __FUNCTION__));
2529 break;
2530 case IW_ENCODE_ALG_WEP:
2531 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __FUNCTION__, ext->key_len, keyIdx));
2532 if (ext->key_len == MAX_WEP_KEY_SIZE)
2533 {
2534 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
2535 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
2536 }
2537 else if (ext->key_len == MIN_WEP_KEY_SIZE)
2538 {
2539 pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
2540 pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
2541 }
2542 else
2543 return -EINVAL;
2544
2545 NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
2546 NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
2547 break;
2548 case IW_ENCODE_ALG_TKIP:
2549 DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __FUNCTION__, keyIdx, ext->key_len));
2550 if (ext->key_len == 32)
2551 {
2552 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2553 {
2554 fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
2555 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2556 {
2557 STA_PORT_SECURED(pAdapter);
2558 }
2559 }
2560 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2561 {
2562 fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
2563
2564 // set 802.1x port control
2565 STA_PORT_SECURED(pAdapter);
2566 }
2567 }
2568 else
2569 return -EINVAL;
2570 break;
2571 case IW_ENCODE_ALG_CCMP:
2572 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2573 {
2574 fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
2575 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
2576 STA_PORT_SECURED(pAdapter);
2577 }
2578 else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
2579 {
2580 fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
2581
2582 // set 802.1x port control
2583 STA_PORT_SECURED(pAdapter);
2584 }
2585 break;
2586 default:
2587 return -EINVAL;
2588 }
2589 }
2590
2591 return 0;
2592}
2593
2594int
2595rt_ioctl_giwencodeext(struct net_device *dev,
2596 struct iw_request_info *info,
2597 union iwreq_data *wrqu, char *extra)
2598{
2599 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2600 PCHAR pKey = NULL;
2601 struct iw_point *encoding = &wrqu->encoding;
2602 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
2603 int idx, max_key_len;
2604
2605 DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
2606
2607 max_key_len = encoding->length - sizeof(*ext);
2608 if (max_key_len < 0)
2609 return -EINVAL;
2610
2611 idx = encoding->flags & IW_ENCODE_INDEX;
2612 if (idx)
2613 {
2614 if (idx < 1 || idx > 4)
2615 return -EINVAL;
2616 idx--;
2617
2618 if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2619 (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
2620 {
2621 if (idx != pAd->StaCfg.DefaultKeyId)
2622 {
2623 ext->key_len = 0;
2624 return 0;
2625 }
2626 }
2627 }
2628 else
2629 idx = pAd->StaCfg.DefaultKeyId;
2630
2631 encoding->flags = idx + 1;
2632 memset(ext, 0, sizeof(*ext));
2633
2634 ext->key_len = 0;
2635 switch(pAd->StaCfg.WepStatus) {
2636 case Ndis802_11WEPDisabled:
2637 ext->alg = IW_ENCODE_ALG_NONE;
2638 encoding->flags |= IW_ENCODE_DISABLED;
2639 break;
2640 case Ndis802_11WEPEnabled:
2641 ext->alg = IW_ENCODE_ALG_WEP;
2642 if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
2643 return -E2BIG;
2644 else
2645 {
2646 ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
2647 pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
2648 }
2649 break;
2650 case Ndis802_11Encryption2Enabled:
2651 case Ndis802_11Encryption3Enabled:
2652 if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
2653 ext->alg = IW_ENCODE_ALG_TKIP;
2654 else
2655 ext->alg = IW_ENCODE_ALG_CCMP;
2656
2657 if (max_key_len < 32)
2658 return -E2BIG;
2659 else
2660 {
2661 ext->key_len = 32;
2662 pKey = &pAd->StaCfg.PMK[0];
2663 }
2664 break;
2665 default:
2666 return -EINVAL;
2667 }
2668
2669 if (ext->key_len && pKey)
2670 {
2671 encoding->flags |= IW_ENCODE_ENABLED;
2672 memcpy(ext->key, pKey, ext->key_len);
2673 }
2674
2675 return 0;
2676}
2677
2678#ifdef SIOCSIWGENIE
2679int rt_ioctl_siwgenie(struct net_device *dev,
2680 struct iw_request_info *info,
2681 union iwreq_data *wrqu, char *extra)
2682{
2683 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2684
2685 if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
2686 (wrqu->data.length && extra == NULL))
2687 return -EINVAL;
2688
2689 if (wrqu->data.length)
2690 {
2691 pAd->StaCfg.RSNIE_Len = wrqu->data.length;
2692 NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
2693 }
2694 else
2695 {
2696 pAd->StaCfg.RSNIE_Len = 0;
2697 NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
2698 }
2699
2700 return 0;
2701}
2702#endif // SIOCSIWGENIE //
2703
2704int rt_ioctl_giwgenie(struct net_device *dev,
2705 struct iw_request_info *info,
2706 union iwreq_data *wrqu, char *extra)
2707{
2708 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2709
2710 if ((pAd->StaCfg.RSNIE_Len == 0) ||
2711 (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
2712 {
2713 wrqu->data.length = 0;
2714 return 0;
2715 }
2716
2717#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2718#ifdef SIOCSIWGENIE
2719 if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
2720 {
2721 if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
2722 return -E2BIG;
2723
2724 wrqu->data.length = pAd->StaCfg.RSNIE_Len;
2725 memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2726 }
2727 else
2728#endif // SIOCSIWGENIE //
2729#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2730 {
2731 UCHAR RSNIe = IE_WPA;
2732
2733 if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
2734 return -E2BIG;
2735 wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
2736
2737 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
2738 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
2739 RSNIe = IE_RSN;
2740
2741 extra[0] = (char)RSNIe;
2742 extra[1] = pAd->StaCfg.RSNIE_Len;
2743 memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
2744 }
2745
2746 return 0;
2747}
2748
2749int rt_ioctl_siwpmksa(struct net_device *dev,
2750 struct iw_request_info *info,
2751 union iwreq_data *wrqu,
2752 char *extra)
2753{
2754 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2755 struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
2756 INT CachedIdx = 0, idx = 0;
2757
2758 if (pPmksa == NULL)
2759 return -EINVAL;
2760
2761 DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
2762 switch(pPmksa->cmd)
2763 {
2764 case IW_PMKSA_FLUSH:
2765 NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
2766 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
2767 break;
2768 case IW_PMKSA_REMOVE:
2769 for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2770 {
2771 // compare the BSSID
2772 if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2773 {
2774 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
2775 NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
2776 for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
2777 {
2778 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
2779 NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
2780 }
2781 pAd->StaCfg.SavedPMKNum--;
2782 break;
2783 }
2784 }
2785
2786 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
2787 break;
2788 case IW_PMKSA_ADD:
2789 for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
2790 {
2791 // compare the BSSID
2792 if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
2793 break;
2794 }
2795
2796 // Found, replace it
2797 if (CachedIdx < PMKID_NO)
2798 {
2799 DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2800 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2801 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2802 pAd->StaCfg.SavedPMKNum++;
2803 }
2804 // Not found, replace the last one
2805 else
2806 {
2807 // Randomly replace one
2808 CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
2809 DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
2810 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
2811 NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
2812 }
2813
2814 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
2815 break;
2816 default:
2817 DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
2818 break;
2819 }
2820
2821 return 0;
2822}
2823#endif // #if WIRELESS_EXT > 17
2824
2825#ifdef DBG
2826static int
2827rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info,
2828 struct iw_point *wrq, char *extra)
2829 {
2830 CHAR *this_char;
2831 CHAR *value = NULL;
2832 UCHAR regBBP = 0;
2833 UINT32 bbpId;
2834 UINT32 bbpValue;
2835 BOOLEAN bIsPrintAllBBP = FALSE;
2836 INT Status = 0;
2837 PRTMP_ADAPTER pAdapter = (PRTMP_ADAPTER) dev->priv;
2838
2839
2840 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2841
2842 if (wrq->length > 1) //No parameters.
2843 {
2844 sprintf(extra, "\n");
2845
2846 //Parsing Read or Write
2847 this_char = wrq->pointer;
2848 DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char));
2849 if (!*this_char)
2850 goto next;
2851
2852 if ((value = rtstrchr(this_char, '=')) != NULL)
2853 *value++ = 0;
2854
2855 if (!value || !*value)
2856 { //Read
2857 DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value));
2858 if (sscanf(this_char, "%d", &(bbpId)) == 1)
2859 {
2860 if (bbpId <= 136)
2861 {
2862#ifdef RALINK_ATE
2863 if (ATE_ON(pAdapter))
2864 {
2865 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2866 }
2867 else
2868#endif // RALINK_ATE //
2869 {
2870 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2871 }
2872 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2873 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2874 DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2875 }
2876 else
2877 {//Invalid parametes, so default printk all bbp
2878 bIsPrintAllBBP = TRUE;
2879 goto next;
2880 }
2881 }
2882 else
2883 { //Invalid parametes, so default printk all bbp
2884 bIsPrintAllBBP = TRUE;
2885 goto next;
2886 }
2887 }
2888 else
2889 { //Write
2890 if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1))
2891 {
2892 if (bbpId <= 136)
2893 {
2894#ifdef RALINK_ATE
2895 if (ATE_ON(pAdapter))
2896 {
2897 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2898 //Read it back for showing
2899 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2900 }
2901 else
2902#endif // RALINK_ATE //
2903 {
2904 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
2905 //Read it back for showing
2906 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2907 }
2908 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
2909 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2910 DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
2911 }
2912 else
2913 {//Invalid parametes, so default printk all bbp
2914 bIsPrintAllBBP = TRUE;
2915 goto next;
2916 }
2917 }
2918 else
2919 { //Invalid parametes, so default printk all bbp
2920 bIsPrintAllBBP = TRUE;
2921 goto next;
2922 }
2923 }
2924 }
2925 else
2926 bIsPrintAllBBP = TRUE;
2927
2928next:
2929 if (bIsPrintAllBBP)
2930 {
2931 memset(extra, 0x00, IW_PRIV_SIZE_MASK);
2932 sprintf(extra, "\n");
2933 for (bbpId = 0; bbpId <= 136; bbpId++)
2934 {
2935 if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 10))
2936 break;
2937#ifdef RALINK_ATE
2938 if (ATE_ON(pAdapter))
2939 {
2940 ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2941 }
2942 else
2943#endif // RALINK_ATE //
2944 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
2945 sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X ", bbpId, bbpId*2, regBBP);
2946 if (bbpId%5 == 4)
2947 sprintf(extra+strlen(extra), "\n");
2948 }
2949
2950 wrq->length = strlen(extra) + 1; // 1: size of '\0'
2951 DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->length));
2952 }
2953
2954 DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n"));
2955
2956 return Status;
2957}
2958#endif // DBG //
2959
2960int rt_ioctl_siwrate(struct net_device *dev,
2961 struct iw_request_info *info,
2962 union iwreq_data *wrqu, char *extra)
2963{
2964 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
2965 UINT32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
2966
2967 //check if the interface is down
2968 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
2969 {
2970 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
2971 return -ENETDOWN;
2972 }
2973
2974 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
2975 /* rate = -1 => auto rate
2976 rate = X, fixed = 1 => (fixed rate X)
2977 */
2978 if (rate == -1)
2979 {
2980 //Auto Rate
2981 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
2982 pAd->StaCfg.bAutoTxRateSwitch = TRUE;
2983 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
2984 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
2985 RTMPSetDesiredRates(pAd, -1);
2986
2987#ifdef DOT11_N_SUPPORT
2988 SetCommonHT(pAd);
2989#endif // DOT11_N_SUPPORT //
2990 }
2991 else
2992 {
2993 if (fixed)
2994 {
2995 pAd->StaCfg.bAutoTxRateSwitch = FALSE;
2996 if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
2997 (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
2998 RTMPSetDesiredRates(pAd, rate);
2999 else
3000 {
3001 pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
3002#ifdef DOT11_N_SUPPORT
3003 SetCommonHT(pAd);
3004#endif // DOT11_N_SUPPORT //
3005 }
3006 DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
3007 }
3008 else
3009 {
3010 // TODO: rate = X, fixed = 0 => (rates <= X)
3011 return -EOPNOTSUPP;
3012 }
3013 }
3014
3015 return 0;
3016}
3017
3018int rt_ioctl_giwrate(struct net_device *dev,
3019 struct iw_request_info *info,
3020 union iwreq_data *wrqu, char *extra)
3021{
3022 PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) dev->priv;
3023 int rate_index = 0, rate_count = 0;
3024 HTTRANSMIT_SETTING ht_setting;
3025 __s32 ralinkrate[] =
3026 {2, 4, 11, 22, // CCK
3027 12, 18, 24, 36, 48, 72, 96, 108, // OFDM
3028 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
3029 39, 78, 117, 156, 234, 312, 351, 390, // 20MHz, 800ns GI, MCS: 16 ~ 23
3030 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
3031 81, 162, 243, 324, 486, 648, 729, 810, // 40MHz, 800ns GI, MCS: 16 ~ 23
3032 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
3033 43, 87, 130, 173, 260, 317, 390, 433, // 20MHz, 400ns GI, MCS: 16 ~ 23
3034 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
3035 90, 180, 270, 360, 540, 720, 810, 900}; // 40MHz, 400ns GI, MCS: 16 ~ 23
3036
3037 rate_count = sizeof(ralinkrate)/sizeof(__s32);
3038 //check if the interface is down
3039 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
3040 {
3041 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
3042 return -ENETDOWN;
3043 }
3044
3045 if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
3046 (INFRA_ON(pAd)) &&
3047 ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
3048 ht_setting.word = pAd->StaCfg.HTPhyMode.word;
3049 else
3050 ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
3051
3052#ifdef DOT11_N_SUPPORT
3053 if (ht_setting.field.MODE >= MODE_HTMIX)
3054 {
3055 rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
3056 }
3057 else
3058#endif // DOT11_N_SUPPORT //
3059 if (ht_setting.field.MODE == MODE_OFDM)
3060 rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
3061 else if (ht_setting.field.MODE == MODE_CCK)
3062 rate_index = (UCHAR)(ht_setting.field.MCS);
3063
3064 if (rate_index < 0)
3065 rate_index = 0;
3066
3067 if (rate_index > rate_count)
3068 rate_index = rate_count;
3069
3070 wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
3071 wrqu->bitrate.disabled = 0;
3072
3073 return 0;
3074}
3075
3076static const iw_handler rt_handler[] =
3077{
3078 (iw_handler) NULL, /* SIOCSIWCOMMIT */
3079 (iw_handler) rt_ioctl_giwname, /* SIOCGIWNAME */
3080 (iw_handler) NULL, /* SIOCSIWNWID */
3081 (iw_handler) NULL, /* SIOCGIWNWID */
3082 (iw_handler) rt_ioctl_siwfreq, /* SIOCSIWFREQ */
3083 (iw_handler) rt_ioctl_giwfreq, /* SIOCGIWFREQ */
3084 (iw_handler) rt_ioctl_siwmode, /* SIOCSIWMODE */
3085 (iw_handler) rt_ioctl_giwmode, /* SIOCGIWMODE */
3086 (iw_handler) NULL, /* SIOCSIWSENS */
3087 (iw_handler) NULL, /* SIOCGIWSENS */
3088 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
3089 (iw_handler) rt_ioctl_giwrange, /* SIOCGIWRANGE */
3090 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
3091 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
3092 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
3093 (iw_handler) rt28xx_get_wireless_stats /* kernel code */, /* SIOCGIWSTATS */
3094 (iw_handler) NULL, /* SIOCSIWSPY */
3095 (iw_handler) NULL, /* SIOCGIWSPY */
3096 (iw_handler) NULL, /* SIOCSIWTHRSPY */
3097 (iw_handler) NULL, /* SIOCGIWTHRSPY */
3098 (iw_handler) rt_ioctl_siwap, /* SIOCSIWAP */
3099 (iw_handler) rt_ioctl_giwap, /* SIOCGIWAP */
3100#ifdef SIOCSIWMLME
3101 (iw_handler) rt_ioctl_siwmlme, /* SIOCSIWMLME */
3102#else
3103 (iw_handler) NULL, /* SIOCSIWMLME */
3104#endif // SIOCSIWMLME //
3105 (iw_handler) rt_ioctl_iwaplist, /* SIOCGIWAPLIST */
3106#ifdef SIOCGIWSCAN
3107 (iw_handler) rt_ioctl_siwscan, /* SIOCSIWSCAN */
3108 (iw_handler) rt_ioctl_giwscan, /* SIOCGIWSCAN */
3109#else
3110 (iw_handler) NULL, /* SIOCSIWSCAN */
3111 (iw_handler) NULL, /* SIOCGIWSCAN */
3112#endif /* SIOCGIWSCAN */
3113 (iw_handler) rt_ioctl_siwessid, /* SIOCSIWESSID */
3114 (iw_handler) rt_ioctl_giwessid, /* SIOCGIWESSID */
3115 (iw_handler) rt_ioctl_siwnickn, /* SIOCSIWNICKN */
3116 (iw_handler) rt_ioctl_giwnickn, /* SIOCGIWNICKN */
3117 (iw_handler) NULL, /* -- hole -- */
3118 (iw_handler) NULL, /* -- hole -- */
3119 (iw_handler) rt_ioctl_siwrate, /* SIOCSIWRATE */
3120 (iw_handler) rt_ioctl_giwrate, /* SIOCGIWRATE */
3121 (iw_handler) rt_ioctl_siwrts, /* SIOCSIWRTS */
3122 (iw_handler) rt_ioctl_giwrts, /* SIOCGIWRTS */
3123 (iw_handler) rt_ioctl_siwfrag, /* SIOCSIWFRAG */
3124 (iw_handler) rt_ioctl_giwfrag, /* SIOCGIWFRAG */
3125 (iw_handler) NULL, /* SIOCSIWTXPOW */
3126 (iw_handler) NULL, /* SIOCGIWTXPOW */
3127 (iw_handler) NULL, /* SIOCSIWRETRY */
3128 (iw_handler) NULL, /* SIOCGIWRETRY */
3129 (iw_handler) rt_ioctl_siwencode, /* SIOCSIWENCODE */
3130 (iw_handler) rt_ioctl_giwencode, /* SIOCGIWENCODE */
3131 (iw_handler) NULL, /* SIOCSIWPOWER */
3132 (iw_handler) NULL, /* SIOCGIWPOWER */
3133 (iw_handler) NULL, /* -- hole -- */
3134 (iw_handler) NULL, /* -- hole -- */
3135#if WIRELESS_EXT > 17
3136 (iw_handler) rt_ioctl_siwgenie, /* SIOCSIWGENIE */
3137 (iw_handler) rt_ioctl_giwgenie, /* SIOCGIWGENIE */
3138 (iw_handler) rt_ioctl_siwauth, /* SIOCSIWAUTH */
3139 (iw_handler) rt_ioctl_giwauth, /* SIOCGIWAUTH */
3140 (iw_handler) rt_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
3141 (iw_handler) rt_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
3142 (iw_handler) rt_ioctl_siwpmksa, /* SIOCSIWPMKSA */
3143#endif
3144};
3145
3146static const iw_handler rt_priv_handlers[] = {
3147 (iw_handler) NULL, /* + 0x00 */
3148 (iw_handler) NULL, /* + 0x01 */
3149#ifndef CONFIG_AP_SUPPORT
3150 (iw_handler) rt_ioctl_setparam, /* + 0x02 */
3151#else
3152 (iw_handler) NULL, /* + 0x02 */
3153#endif // CONFIG_AP_SUPPORT //
3154#ifdef DBG
3155 (iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
3156#else
3157 (iw_handler) NULL, /* + 0x03 */
3158#endif
3159 (iw_handler) NULL, /* + 0x04 */
3160 (iw_handler) NULL, /* + 0x05 */
3161 (iw_handler) NULL, /* + 0x06 */
3162 (iw_handler) NULL, /* + 0x07 */
3163 (iw_handler) NULL, /* + 0x08 */
3164 (iw_handler) rt_private_get_statistics, /* + 0x09 */
3165 (iw_handler) NULL, /* + 0x0A */
3166 (iw_handler) NULL, /* + 0x0B */
3167 (iw_handler) NULL, /* + 0x0C */
3168 (iw_handler) NULL, /* + 0x0D */
3169 (iw_handler) NULL, /* + 0x0E */
3170 (iw_handler) NULL, /* + 0x0F */
3171 (iw_handler) NULL, /* + 0x10 */
3172 (iw_handler) rt_private_show, /* + 0x11 */
3173 (iw_handler) NULL, /* + 0x12 */
3174 (iw_handler) NULL, /* + 0x13 */
3175 (iw_handler) NULL, /* + 0x15 */
3176 (iw_handler) NULL, /* + 0x17 */
3177 (iw_handler) NULL, /* + 0x18 */
3178};
3179
3180const struct iw_handler_def rt28xx_iw_handler_def =
3181{
3182#define N(a) (sizeof (a) / sizeof (a[0]))
3183 .standard = (iw_handler *) rt_handler,
3184 .num_standard = sizeof(rt_handler) / sizeof(iw_handler),
3185 .private = (iw_handler *) rt_priv_handlers,
3186 .num_private = N(rt_priv_handlers),
3187 .private_args = (struct iw_priv_args *) privtab,
3188 .num_private_args = N(privtab),
3189#if IW_HANDLER_VERSION >= 7
3190 .get_wireless_stats = rt28xx_get_wireless_stats,
3191#endif
3192};
3193
3194INT RTMPSetInformation(
3195 IN PRTMP_ADAPTER pAdapter,
3196 IN OUT struct ifreq *rq,
3197 IN INT cmd)
3198{
3199 struct iwreq *wrq = (struct iwreq *) rq;
3200 NDIS_802_11_SSID Ssid;
3201 NDIS_802_11_MAC_ADDRESS Bssid;
3202 RT_802_11_PHY_MODE PhyMode;
3203 RT_802_11_STA_CONFIG StaConfig;
3204 NDIS_802_11_RATES aryRates;
3205 RT_802_11_PREAMBLE Preamble;
3206 NDIS_802_11_WEP_STATUS WepStatus;
3207 NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeMax;
3208 NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
3209 NDIS_802_11_RTS_THRESHOLD RtsThresh;
3210 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
3211 NDIS_802_11_POWER_MODE PowerMode;
3212 PNDIS_802_11_KEY pKey = NULL;
3213 PNDIS_802_11_WEP pWepKey =NULL;
3214 PNDIS_802_11_REMOVE_KEY pRemoveKey = NULL;
3215 NDIS_802_11_CONFIGURATION Config, *pConfig = NULL;
3216 NDIS_802_11_NETWORK_TYPE NetType;
3217 ULONG Now;
3218 UINT KeyIdx = 0;
3219 INT Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
3220 ULONG PowerTemp;
3221 BOOLEAN RadioState;
3222 BOOLEAN StateMachineTouched = FALSE;
3223#ifdef DOT11_N_SUPPORT
3224 OID_SET_HT_PHYMODE HT_PhyMode; //11n ,kathy
3225#endif // DOT11_N_SUPPORT //
3226#ifdef WPA_SUPPLICANT_SUPPORT
3227 PNDIS_802_11_PMKID pPmkId = NULL;
3228 BOOLEAN IEEE8021xState = FALSE;
3229 BOOLEAN IEEE8021x_required_keys = FALSE;
3230 UCHAR wpa_supplicant_enable = 0;
3231#endif // WPA_SUPPLICANT_SUPPORT //
3232
3233#ifdef SNMP_SUPPORT
3234 TX_RTY_CFG_STRUC tx_rty_cfg;
3235 ULONG ShortRetryLimit, LongRetryLimit;
3236 UCHAR ctmp;
3237#endif // SNMP_SUPPORT //
3238
3239
3240#ifdef DOT11_N_SUPPORT
3241 MaxPhyMode = PHY_11N_5G;
3242#endif // DOT11_N_SUPPORT //
3243
3244
3245 DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(), 0x%08x\n", cmd&0x7FFF));
3246 switch(cmd & 0x7FFF) {
3247 case RT_OID_802_11_COUNTRY_REGION:
3248 if (wrq->u.data.length < sizeof(UCHAR))
3249 Status = -EINVAL;
3250 // Only avaliable when EEPROM not programming
3251 else if (!(pAdapter->CommonCfg.CountryRegion & 0x80) && !(pAdapter->CommonCfg.CountryRegionForABand & 0x80))
3252 {
3253 ULONG Country;
3254 UCHAR TmpPhy;
3255
3256 Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
3257 pAdapter->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
3258 pAdapter->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
3259 TmpPhy = pAdapter->CommonCfg.PhyMode;
3260 pAdapter->CommonCfg.PhyMode = 0xff;
3261 // Build all corresponding channel information
3262 RTMPSetPhyMode(pAdapter, TmpPhy);
3263#ifdef DOT11_N_SUPPORT
3264 SetCommonHT(pAdapter);
3265#endif // DOT11_N_SUPPORT //
3266 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d B/G:%d)\n", pAdapter->CommonCfg.CountryRegionForABand,
3267 pAdapter->CommonCfg.CountryRegion));
3268 }
3269 break;
3270 case OID_802_11_BSSID_LIST_SCAN:
3271 #ifdef RALINK_ATE
3272 if (ATE_ON(pAdapter))
3273 {
3274 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3275 break;
3276 }
3277#endif // RALINK_ATE //
3278 Now = jiffies;
3279 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAdapter->RalinkCounters.LastOneSecTotalTxCount));
3280
3281 if (MONITOR_ON(pAdapter))
3282 {
3283 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
3284 break;
3285 }
3286
3287 //Benson add 20080527, when radio off, sta don't need to scan
3288 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
3289 break;
3290
3291 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
3292 {
3293 DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
3294 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3295 Status = NDIS_STATUS_SUCCESS;
3296 break;
3297 }
3298
3299 if (pAdapter->RalinkCounters.LastOneSecTotalTxCount > 100)
3300 {
3301 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3302 Status = NDIS_STATUS_SUCCESS;
3303 pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
3304 break;
3305 }
3306
3307 if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
3308 ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
3309 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3310 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
3311 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
3312 (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
3313 {
3314 DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
3315 Status = NDIS_STATUS_SUCCESS;
3316 pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
3317 break;
3318 }
3319
3320
3321 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3322 {
3323 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3324 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3325 }
3326
3327 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3328 // this request, because this request is initiated by NDIS.
3329 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3330 // Reset allowed scan retries
3331 pAdapter->StaCfg.ScanCnt = 0;
3332 pAdapter->StaCfg.LastScanTime = Now;
3333
3334 pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
3335 RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
3336 MlmeEnqueue(pAdapter,
3337 MLME_CNTL_STATE_MACHINE,
3338 OID_802_11_BSSID_LIST_SCAN,
3339 0,
3340 NULL);
3341
3342 Status = NDIS_STATUS_SUCCESS;
3343 StateMachineTouched = TRUE;
3344 break;
3345 case OID_802_11_SSID:
3346 if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
3347 Status = -EINVAL;
3348 else
3349 {
3350 PCHAR pSsidString = NULL;
3351 Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
3352
3353 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
3354 if (Ssid.SsidLength > MAX_LEN_OF_SSID)
3355 Status = -EINVAL;
3356 else
3357 {
3358 if (Ssid.SsidLength == 0)
3359 {
3360 Set_SSID_Proc(pAdapter, "");
3361 }
3362 else
3363 {
3364 pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
3365 if (pSsidString)
3366 {
3367 NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
3368 NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
3369 Set_SSID_Proc(pAdapter, pSsidString);
3370 kfree(pSsidString);
3371 }
3372 else
3373 Status = -ENOMEM;
3374 }
3375 }
3376 }
3377 break;
3378 case OID_802_11_BSSID:
3379#ifdef RALINK_ATE
3380 if (ATE_ON(pAdapter))
3381 {
3382 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
3383 break;
3384 }
3385#endif // RALINK_ATE //
3386 if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
3387 Status = -EINVAL;
3388 else
3389 {
3390 Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
3391
3392 // tell CNTL state machine to call NdisMSetInformationComplete() after completing
3393 // this request, because this request is initiated by NDIS.
3394 pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
3395
3396 // Prevent to connect AP again in STAMlmePeriodicExec
3397 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
3398
3399 // Reset allowed scan retries
3400 pAdapter->StaCfg.ScanCnt = 0;
3401
3402 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
3403 {
3404 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
3405 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
3406 }
3407 MlmeEnqueue(pAdapter,
3408 MLME_CNTL_STATE_MACHINE,
3409 OID_802_11_BSSID,
3410 sizeof(NDIS_802_11_MAC_ADDRESS),
3411 (VOID *)&Bssid);
3412 Status = NDIS_STATUS_SUCCESS;
3413 StateMachineTouched = TRUE;
3414
3415 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
3416 Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
3417 }
3418 break;
3419 case RT_OID_802_11_RADIO:
3420 if (wrq->u.data.length != sizeof(BOOLEAN))
3421 Status = -EINVAL;
3422 else
3423 {
3424 Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
3425 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
3426 if (pAdapter->StaCfg.bSwRadio != RadioState)
3427 {
3428 pAdapter->StaCfg.bSwRadio = RadioState;
3429 if (pAdapter->StaCfg.bRadio != (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio))
3430 {
3431 pAdapter->StaCfg.bRadio = (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio);
3432 if (pAdapter->StaCfg.bRadio == TRUE)
3433 {
3434 MlmeRadioOn(pAdapter);
3435 // Update extra information
3436 pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;
3437 }
3438 else
3439 {
3440 MlmeRadioOff(pAdapter);
3441 // Update extra information
3442 pAdapter->ExtraInfo = SW_RADIO_OFF;
3443 }
3444 }
3445 }
3446 }
3447 break;
3448 case RT_OID_802_11_PHY_MODE:
3449 if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
3450 Status = -EINVAL;
3451 else
3452 {
3453 Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3454 if (PhyMode <= MaxPhyMode)
3455 {
3456 RTMPSetPhyMode(pAdapter, PhyMode);
3457#ifdef DOT11_N_SUPPORT
3458 SetCommonHT(pAdapter);
3459#endif // DOT11_N_SUPPORT //
3460 }
3461 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
3462 }
3463 break;
3464 case RT_OID_802_11_STA_CONFIG:
3465 if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
3466 Status = -EINVAL;
3467 else
3468 {
3469 Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
3470 pAdapter->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
3471 pAdapter->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
3472 pAdapter->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
3473 if ((pAdapter->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
3474 (StaConfig.AdhocMode <= MaxPhyMode))
3475 {
3476 // allow dynamic change of "USE OFDM rate or not" in ADHOC mode
3477 // if setting changed, need to reset current TX rate as well as BEACON frame format
3478 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
3479 {
3480 pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
3481 RTMPSetPhyMode(pAdapter, PhyMode);
3482 MlmeUpdateTxRates(pAdapter, FALSE, 0);
3483 MakeIbssBeacon(pAdapter); // re-build BEACON frame
3484 AsicEnableIbssSync(pAdapter); // copy to on-chip memory
3485 }
3486 }
3487 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
3488 pAdapter->CommonCfg.bEnableTxBurst,
3489 pAdapter->CommonCfg.UseBGProtection,
3490 pAdapter->CommonCfg.bUseShortSlotTime));
3491 }
3492 break;
3493 case OID_802_11_DESIRED_RATES:
3494 if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
3495 Status = -EINVAL;
3496 else
3497 {
3498 Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
3499 NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
3500 NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
3501 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
3502 pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
3503 pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
3504 pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
3505 pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
3506 // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
3507 MlmeUpdateTxRates(pAdapter, FALSE, 0);
3508 }
3509 break;
3510 case RT_OID_802_11_PREAMBLE:
3511 if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
3512 Status = -EINVAL;
3513 else
3514 {
3515 Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
3516 if (Preamble == Rt802_11PreambleShort)
3517 {
3518 pAdapter->CommonCfg.TxPreamble = Preamble;
3519 MlmeSetTxPreamble(pAdapter, Rt802_11PreambleShort);
3520 }
3521 else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
3522 {
3523 // if user wants AUTO, initialize to LONG here, then change according to AP's
3524 // capability upon association.
3525 pAdapter->CommonCfg.TxPreamble = Preamble;
3526 MlmeSetTxPreamble(pAdapter, Rt802_11PreambleLong);
3527 }
3528 else
3529 {
3530 Status = -EINVAL;
3531 break;
3532 }
3533 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
3534 }
3535 break;
3536 case OID_802_11_WEP_STATUS:
3537 if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
3538 Status = -EINVAL;
3539 else
3540 {
3541 Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
3542 // Since TKIP, AES, WEP are all supported. It should not have any invalid setting
3543 if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
3544 {
3545 if (pAdapter->StaCfg.WepStatus != WepStatus)
3546 {
3547 // Config has changed
3548 pAdapter->bConfigChanged = TRUE;
3549 }
3550 pAdapter->StaCfg.WepStatus = WepStatus;
3551 pAdapter->StaCfg.OrigWepStatus = WepStatus;
3552 pAdapter->StaCfg.PairCipher = WepStatus;
3553 pAdapter->StaCfg.GroupCipher = WepStatus;
3554 }
3555 else
3556 {
3557 Status = -EINVAL;
3558 break;
3559 }
3560 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
3561 }
3562 break;
3563 case OID_802_11_AUTHENTICATION_MODE:
3564 if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
3565 Status = -EINVAL;
3566 else
3567 {
3568 Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
3569 if (AuthMode > Ndis802_11AuthModeMax)
3570 {
3571 Status = -EINVAL;
3572 break;
3573 }
3574 else
3575 {
3576 if (pAdapter->StaCfg.AuthMode != AuthMode)
3577 {
3578 // Config has changed
3579 pAdapter->bConfigChanged = TRUE;
3580 }
3581 pAdapter->StaCfg.AuthMode = AuthMode;
3582 }
3583 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
3584 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAdapter->StaCfg.AuthMode));
3585 }
3586 break;
3587 case OID_802_11_INFRASTRUCTURE_MODE:
3588 if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
3589 Status = -EINVAL;
3590 else
3591 {
3592 Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
3593
3594 if (BssType == Ndis802_11IBSS)
3595 Set_NetworkType_Proc(pAdapter, "Adhoc");
3596 else if (BssType == Ndis802_11Infrastructure)
3597 Set_NetworkType_Proc(pAdapter, "Infra");
3598 else if (BssType == Ndis802_11Monitor)
3599 Set_NetworkType_Proc(pAdapter, "Monitor");
3600 else
3601 {
3602 Status = -EINVAL;
3603 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
3604 }
3605 }
3606 break;
3607 case OID_802_11_REMOVE_WEP:
3608 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
3609 if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
3610 {
3611 Status = -EINVAL;
3612 }
3613 else
3614 {
3615 KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
3616
3617 if (KeyIdx & 0x80000000)
3618 {
3619 // Should never set default bit when remove key
3620 Status = -EINVAL;
3621 }
3622 else
3623 {
3624 KeyIdx = KeyIdx & 0x0fffffff;
3625 if (KeyIdx >= 4){
3626 Status = -EINVAL;
3627 }
3628 else
3629 {
3630 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3631 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3632 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3633 }
3634 }
3635 }
3636 break;
3637 case RT_OID_802_11_RESET_COUNTERS:
3638 NdisZeroMemory(&pAdapter->WlanCounters, sizeof(COUNTER_802_11));
3639 NdisZeroMemory(&pAdapter->Counters8023, sizeof(COUNTER_802_3));
3640 NdisZeroMemory(&pAdapter->RalinkCounters, sizeof(COUNTER_RALINK));
3641 pAdapter->Counters8023.RxNoBuffer = 0;
3642 pAdapter->Counters8023.GoodReceives = 0;
3643 pAdapter->Counters8023.RxNoBuffer = 0;
3644 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
3645 break;
3646 case OID_802_11_RTS_THRESHOLD:
3647 if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
3648 Status = -EINVAL;
3649 else
3650 {
3651 Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
3652 if (RtsThresh > MAX_RTS_THRESHOLD)
3653 Status = -EINVAL;
3654 else
3655 pAdapter->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
3656 }
3657 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
3658 break;
3659 case OID_802_11_FRAGMENTATION_THRESHOLD:
3660 if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
3661 Status = -EINVAL;
3662 else
3663 {
3664 Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
3665 pAdapter->CommonCfg.bUseZeroToDisableFragment = FALSE;
3666 if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
3667 {
3668 if (FragThresh == 0)
3669 {
3670 pAdapter->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
3671 pAdapter->CommonCfg.bUseZeroToDisableFragment = TRUE;
3672 }
3673 else
3674 Status = -EINVAL;
3675 }
3676 else
3677 pAdapter->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
3678 }
3679 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
3680 break;
3681 case OID_802_11_POWER_MODE:
3682 if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
3683 Status = -EINVAL;
3684 else
3685 {
3686 Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
3687 if (PowerMode == Ndis802_11PowerModeCAM)
3688 Set_PSMode_Proc(pAdapter, "CAM");
3689 else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
3690 Set_PSMode_Proc(pAdapter, "Max_PSP");
3691 else if (PowerMode == Ndis802_11PowerModeFast_PSP)
3692 Set_PSMode_Proc(pAdapter, "Fast_PSP");
3693 else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
3694 Set_PSMode_Proc(pAdapter, "Legacy_PSP");
3695 else
3696 Status = -EINVAL;
3697 }
3698 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
3699 break;
3700 case RT_OID_802_11_TX_POWER_LEVEL_1:
3701 if (wrq->u.data.length < sizeof(ULONG))
3702 Status = -EINVAL;
3703 else
3704 {
3705 Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
3706 if (PowerTemp > 100)
3707 PowerTemp = 0xffffffff; // AUTO
3708 pAdapter->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
3709 pAdapter->CommonCfg.TxPowerPercentage = pAdapter->CommonCfg.TxPowerDefault;
3710 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
3711 }
3712 break;
3713 case OID_802_11_NETWORK_TYPE_IN_USE:
3714 if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
3715 Status = -EINVAL;
3716 else
3717 {
3718 Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
3719
3720 if (NetType == Ndis802_11DS)
3721 RTMPSetPhyMode(pAdapter, PHY_11B);
3722 else if (NetType == Ndis802_11OFDM24)
3723 RTMPSetPhyMode(pAdapter, PHY_11BG_MIXED);
3724 else if (NetType == Ndis802_11OFDM5)
3725 RTMPSetPhyMode(pAdapter, PHY_11A);
3726 else
3727 Status = -EINVAL;
3728#ifdef DOT11_N_SUPPORT
3729 if (Status == NDIS_STATUS_SUCCESS)
3730 SetCommonHT(pAdapter);
3731#endif // DOT11_N_SUPPORT //
3732 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
3733 }
3734 break;
3735 // For WPA PSK PMK key
3736 case RT_OID_802_11_ADD_WPA:
3737 pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3738 if(pKey == NULL)
3739 {
3740 Status = -ENOMEM;
3741 break;
3742 }
3743
3744 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3745 if (pKey->Length != wrq->u.data.length)
3746 {
3747 Status = -EINVAL;
3748 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
3749 }
3750 else
3751 {
3752 if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
3753 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
3754 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
3755 {
3756 Status = -EOPNOTSUPP;
3757 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
3758 }
3759 else if ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
3760 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
3761 (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) ) // Only for WPA PSK mode
3762 {
3763 NdisMoveMemory(pAdapter->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
3764 // Use RaConfig as PSK agent.
3765 // Start STA supplicant state machine
3766 if (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
3767 pAdapter->StaCfg.WpaState = SS_START;
3768
3769 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3770 }
3771 else
3772 {
3773 pAdapter->StaCfg.WpaState = SS_NOTUSE;
3774 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3775 }
3776 }
3777 kfree(pKey);
3778 break;
3779 case OID_802_11_REMOVE_KEY:
3780 pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3781 if(pRemoveKey == NULL)
3782 {
3783 Status = -ENOMEM;
3784 break;
3785 }
3786
3787 Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
3788 if (pRemoveKey->Length != wrq->u.data.length)
3789 {
3790 Status = -EINVAL;
3791 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
3792 }
3793 else
3794 {
3795 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
3796 {
3797 RTMPWPARemoveKeyProc(pAdapter, pRemoveKey);
3798 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
3799 }
3800 else
3801 {
3802 KeyIdx = pRemoveKey->KeyIndex;
3803
3804 if (KeyIdx & 0x80000000)
3805 {
3806 // Should never set default bit when remove key
3807 Status = -EINVAL;
3808 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
3809 }
3810 else
3811 {
3812 KeyIdx = KeyIdx & 0x0fffffff;
3813 if (KeyIdx > 3)
3814 {
3815 Status = -EINVAL;
3816 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
3817 }
3818 else
3819 {
3820 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
3821 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
3822 AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
3823 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
3824 }
3825 }
3826 }
3827 }
3828 kfree(pRemoveKey);
3829 break;
3830 // New for WPA
3831 case OID_802_11_ADD_KEY:
3832 pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
3833 if(pKey == NULL)
3834 {
3835 Status = -ENOMEM;
3836 break;
3837 }
3838 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
3839 if (pKey->Length != wrq->u.data.length)
3840 {
3841 Status = -EINVAL;
3842 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
3843 }
3844 else
3845 {
3846 RTMPAddKey(pAdapter, pKey);
3847 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
3848 }
3849 kfree(pKey);
3850 break;
3851 case OID_802_11_CONFIGURATION:
3852 if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
3853 Status = -EINVAL;
3854 else
3855 {
3856 Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
3857 pConfig = &Config;
3858
3859 if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
3860 pAdapter->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
3861
3862 pAdapter->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
3863 MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAdapter->CommonCfg.Channel);
3864 //
3865 // Save the channel on MlmeAux for CntlOidRTBssidProc used.
3866 //
3867 pAdapter->MlmeAux.Channel = pAdapter->CommonCfg.Channel;
3868
3869 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
3870 pConfig->BeaconPeriod, pConfig->ATIMWindow, pAdapter->CommonCfg.Channel));
3871 // Config has changed
3872 pAdapter->bConfigChanged = TRUE;
3873 }
3874 break;
3875#ifdef DOT11_N_SUPPORT
3876 case RT_OID_802_11_SET_HT_PHYMODE:
3877 if (wrq->u.data.length != sizeof(OID_SET_HT_PHYMODE))
3878 Status = -EINVAL;
3879 else
3880 {
3881 POID_SET_HT_PHYMODE pHTPhyMode = &HT_PhyMode;
3882
3883 Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
3884 DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode (PhyMode = %d,TransmitNo = %d, HtMode = %d, ExtOffset = %d , MCS = %d, BW = %d, STBC = %d, SHORTGI = %d) \n",
3885 pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
3886 pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
3887 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
3888 RTMPSetHT(pAdapter, pHTPhyMode);
3889 }
3890 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
3891 pAdapter->StaCfg.HTPhyMode.field.MCS, pAdapter->StaCfg.HTPhyMode.field.BW, pAdapter->StaCfg.HTPhyMode.field.ShortGI,
3892 pAdapter->StaCfg.HTPhyMode.field.STBC));
3893 break;
3894#endif // DOT11_N_SUPPORT //
3895 case RT_OID_802_11_SET_APSD_SETTING:
3896 if (wrq->u.data.length != sizeof(ULONG))
3897 Status = -EINVAL;
3898 else
3899 {
3900 ULONG apsd ;
3901 Status = copy_from_user(&apsd, wrq->u.data.pointer, wrq->u.data.length);
3902
3903 /*-------------------------------------------------------------------
3904 |B31~B7 | B6~B5 | B4 | B3 | B2 | B1 | B0 |
3905 ---------------------------------------------------------------------
3906 | Rsvd | Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD Capable |
3907 ---------------------------------------------------------------------*/
3908 pAdapter->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE : FALSE;
3909 pAdapter->CommonCfg.bAPSDAC_BE = ((apsd & 0x00000002) >> 1) ? TRUE : FALSE;
3910 pAdapter->CommonCfg.bAPSDAC_BK = ((apsd & 0x00000004) >> 2) ? TRUE : FALSE;
3911 pAdapter->CommonCfg.bAPSDAC_VI = ((apsd & 0x00000008) >> 3) ? TRUE : FALSE;
3912 pAdapter->CommonCfg.bAPSDAC_VO = ((apsd & 0x00000010) >> 4) ? TRUE : FALSE;
3913 pAdapter->CommonCfg.MaxSPLength = (UCHAR)((apsd & 0x00000060) >> 5);
3914
3915 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,
3916 pAdapter->CommonCfg.bAPSDAC_BE, pAdapter->CommonCfg.bAPSDAC_BK, pAdapter->CommonCfg.bAPSDAC_VI, pAdapter->CommonCfg.bAPSDAC_VO, pAdapter->CommonCfg.MaxSPLength));
3917 }
3918 break;
3919
3920 case RT_OID_802_11_SET_APSD_PSM:
3921 if (wrq->u.data.length != sizeof(ULONG))
3922 Status = -EINVAL;
3923 else
3924 {
3925 // Driver needs to notify AP when PSM changes
3926 Status = copy_from_user(&pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
3927 if (pAdapter->CommonCfg.bAPSDForcePowerSave != pAdapter->StaCfg.Psm)
3928 {
3929 MlmeSetPsmBit(pAdapter, pAdapter->CommonCfg.bAPSDForcePowerSave);
3930 RTMPSendNullFrame(pAdapter, pAdapter->CommonCfg.TxRate, TRUE);
3931 }
3932 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
3933 }
3934 break;
3935#ifdef QOS_DLS_SUPPORT
3936 case RT_OID_802_11_SET_DLS:
3937 if (wrq->u.data.length != sizeof(ULONG))
3938 Status = -EINVAL;
3939 else
3940 {
3941 BOOLEAN oldvalue = pAdapter->CommonCfg.bDLSCapable;
3942 Status = copy_from_user(&pAdapter->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
3943 if (oldvalue && !pAdapter->CommonCfg.bDLSCapable)
3944 {
3945 int i;
3946 // tear down local dls table entry
3947 for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
3948 {
3949 if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
3950 {
3951 pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
3952 pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
3953 RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
3954 }
3955 }
3956
3957 // tear down peer dls table entry
3958 for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
3959 {
3960 if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
3961 {
3962 pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
3963 pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
3964 RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
3965 }
3966 }
3967 }
3968
3969 DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAdapter->CommonCfg.bDLSCapable));
3970 }
3971 break;
3972
3973 case RT_OID_802_11_SET_DLS_PARAM:
3974 if (wrq->u.data.length != sizeof(RT_802_11_DLS_UI))
3975 Status = -EINVAL;
3976 else
3977 {
3978 RT_802_11_DLS Dls;
3979
3980 NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
3981 RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI));
3982 MlmeEnqueue(pAdapter,
3983 MLME_CNTL_STATE_MACHINE,
3984 RT_OID_802_11_SET_DLS_PARAM,
3985 sizeof(RT_802_11_DLS),
3986 &Dls);
3987 DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n"));
3988 }
3989 break;
3990#endif // QOS_DLS_SUPPORT //
3991 case RT_OID_802_11_SET_WMM:
3992 if (wrq->u.data.length != sizeof(BOOLEAN))
3993 Status = -EINVAL;
3994 else
3995 {
3996 Status = copy_from_user(&pAdapter->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
3997 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d) \n", pAdapter->CommonCfg.bWmmCapable));
3998 }
3999 break;
4000
4001 case OID_802_11_DISASSOCIATE:
4002#ifdef RALINK_ATE
4003 if (ATE_ON(pAdapter))
4004 {
4005 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4006 break;
4007 }
4008#endif // RALINK_ATE //
4009 //
4010 // Set NdisRadioStateOff to TRUE, instead of called MlmeRadioOff.
4011 // Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be 0
4012 // when query OID_802_11_BSSID_LIST.
4013 //
4014 // TRUE: NumberOfItems will set to 0.
4015 // FALSE: NumberOfItems no change.
4016 //
4017 pAdapter->CommonCfg.NdisRadioStateOff = TRUE;
4018 // Set to immediately send the media disconnect event
4019 pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
4020 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE \n"));
4021
4022 if (INFRA_ON(pAdapter))
4023 {
4024 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
4025 {
4026 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
4027 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
4028 }
4029
4030 MlmeEnqueue(pAdapter,
4031 MLME_CNTL_STATE_MACHINE,
4032 OID_802_11_DISASSOCIATE,
4033 0,
4034 NULL);
4035
4036 StateMachineTouched = TRUE;
4037 }
4038 break;
4039
4040#ifdef DOT11_N_SUPPORT
4041 case RT_OID_802_11_SET_IMME_BA_CAP:
4042 if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
4043 Status = -EINVAL;
4044 else
4045 {
4046 OID_BACAP_STRUC Orde ;
4047 Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
4048 if (Orde.Policy > BA_NOTUSE)
4049 {
4050 Status = NDIS_STATUS_INVALID_DATA;
4051 }
4052 else if (Orde.Policy == BA_NOTUSE)
4053 {
4054 pAdapter->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
4055 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4056 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4057 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4058 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4059 pAdapter->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
4060 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4061 // UPdata to HT IE
4062 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4063 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4064 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4065 }
4066 else
4067 {
4068 pAdapter->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
4069 pAdapter->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
4070 pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
4071 pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
4072 pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
4073 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
4074 pAdapter->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
4075 pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
4076
4077 // UPdata to HT IE
4078 pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
4079 pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
4080 pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
4081
4082 if (pAdapter->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
4083 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
4084
4085 }
4086
4087 pAdapter->CommonCfg.REGBACapability.word = pAdapter->CommonCfg.BACapability.word;
4088 DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAdapter->CommonCfg.BACapability.field.Policy,
4089 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit,pAdapter->CommonCfg.BACapability.field.TxBAWinLimit, pAdapter->CommonCfg.BACapability.field.AutoBA));
4090 DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAdapter->CommonCfg.DesiredHtPhy.MimoPs, pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable,
4091 pAdapter->CommonCfg.DesiredHtPhy.AmsduSize, pAdapter->CommonCfg.DesiredHtPhy.MpduDensity));
4092 }
4093
4094 break;
4095 case RT_OID_802_11_ADD_IMME_BA:
4096 DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
4097 if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4098 Status = -EINVAL;
4099 else
4100 {
4101 UCHAR index;
4102 OID_ADD_BA_ENTRY BA;
4103 MAC_TABLE_ENTRY *pEntry;
4104
4105 Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
4106 if (BA.TID > 15)
4107 {
4108 Status = NDIS_STATUS_INVALID_DATA;
4109 break;
4110 }
4111 else
4112 {
4113 //BATableInsertEntry
4114 //As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
4115 index = BA.TID;
4116 // in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
4117 pEntry = MacTableLookup(pAdapter, BA.MACAddr);
4118 if (!pEntry)
4119 {
4120 DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
4121 break;
4122 }
4123 if (BA.IsRecipient == FALSE)
4124 {
4125 if (pEntry->bIAmBadAtheros == TRUE)
4126 pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
4127
4128 BAOriSessionSetUp(pAdapter, pEntry, index, 0, 100, TRUE);
4129 }
4130 else
4131 {
4132 //BATableInsertEntry(pAdapter, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
4133 }
4134
4135 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
4136 BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
4137 , BA.MACAddr[4], BA.MACAddr[5]));
4138 }
4139 }
4140 break;
4141
4142 case RT_OID_802_11_TEAR_IMME_BA:
4143 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
4144 if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
4145 Status = -EINVAL;
4146 else
4147 {
4148 POID_ADD_BA_ENTRY pBA;
4149 MAC_TABLE_ENTRY *pEntry;
4150
4151 pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4152
4153 if (pBA == NULL)
4154 {
4155 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
4156 Status = NDIS_STATUS_FAILURE;
4157 }
4158 else
4159 {
4160 Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
4161 DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
4162
4163 if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
4164 {
4165 Status = NDIS_STATUS_INVALID_DATA;
4166 break;
4167 }
4168
4169 if (pBA->IsRecipient == FALSE)
4170 {
4171 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4172 DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
4173 if (pEntry)
4174 {
4175 DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
4176 BAOriSessionTearDown(pAdapter, pEntry->Aid, pBA->TID, FALSE, TRUE);
4177 }
4178 else
4179 DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4180 }
4181 else
4182 {
4183 pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
4184 if (pEntry)
4185 {
4186 BARecSessionTearDown( pAdapter, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
4187 }
4188 else
4189 DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
4190 }
4191 kfree(pBA);
4192 }
4193 }
4194 break;
4195#endif // DOT11_N_SUPPORT //
4196
4197 // For WPA_SUPPLICANT to set static wep key
4198 case OID_802_11_ADD_WEP:
4199 pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4200
4201 if(pWepKey == NULL)
4202 {
4203 Status = -ENOMEM;
4204 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
4205 break;
4206 }
4207 Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
4208 if (Status)
4209 {
4210 Status = -EINVAL;
4211 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
4212 }
4213 else
4214 {
4215 KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
4216 // KeyIdx must be 0 ~ 3
4217 if (KeyIdx > 4)
4218 {
4219 Status = -EINVAL;
4220 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
4221 }
4222 else
4223 {
4224 UCHAR CipherAlg = 0;
4225 PUCHAR Key;
4226
4227 // set key material and key length
4228 NdisZeroMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, 16);
4229 pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4230 NdisMoveMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4231
4232 switch(pWepKey->KeyLength)
4233 {
4234 case 5:
4235 CipherAlg = CIPHER_WEP64;
4236 break;
4237 case 13:
4238 CipherAlg = CIPHER_WEP128;
4239 break;
4240 default:
4241 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
4242 Status = -EINVAL;
4243 break;
4244 }
4245 pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
4246
4247 // Default key for tx (shared key)
4248 if (pWepKey->KeyIndex & 0x80000000)
4249 {
4250#ifdef WPA_SUPPLICANT_SUPPORT
4251 // set key material and key length
4252 NdisZeroMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
4253 pAdapter->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
4254 NdisMoveMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
4255 pAdapter->StaCfg.DesireSharedKeyId = KeyIdx;
4256 pAdapter->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
4257#endif // WPA_SUPPLICANT_SUPPORT //
4258 pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4259 }
4260
4261#ifdef WPA_SUPPLICANT_SUPPORT
4262 if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
4263#endif // WPA_SUPPLICANT_SUPPORT
4264 {
4265 Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
4266
4267 // Set key material and cipherAlg to Asic
4268 AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
4269
4270 if (pWepKey->KeyIndex & 0x80000000)
4271 {
4272 PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[BSSID_WCID];
4273 // Assign group key info
4274 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
4275 // Assign pairwise key info
4276 RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, pEntry);
4277 }
4278 }
4279 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"));
4280 }
4281 }
4282 kfree(pWepKey);
4283 break;
4284#ifdef WPA_SUPPLICANT_SUPPORT
4285 case OID_SET_COUNTERMEASURES:
4286 if (wrq->u.data.length != sizeof(int))
4287 Status = -EINVAL;
4288 else
4289 {
4290 int enabled = 0;
4291 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4292 if (enabled == 1)
4293 pAdapter->StaCfg.bBlockAssoc = TRUE;
4294 else
4295 // WPA MIC error should block association attempt for 60 seconds
4296 pAdapter->StaCfg.bBlockAssoc = FALSE;
4297 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAdapter->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
4298 }
4299 break;
4300 case RT_OID_WPA_SUPPLICANT_SUPPORT:
4301 if (wrq->u.data.length != sizeof(UCHAR))
4302 Status = -EINVAL;
4303 else
4304 {
4305 Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
4306 pAdapter->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
4307 DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
4308 }
4309 break;
4310 case OID_802_11_DEAUTHENTICATION:
4311 if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
4312 Status = -EINVAL;
4313 else
4314 {
4315 MLME_DEAUTH_REQ_STRUCT *pInfo;
4316 MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
4317
4318 pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
4319 Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
4320 MlmeDeauthReqAction(pAdapter, MsgElem);
4321 kfree(MsgElem);
4322
4323 if (INFRA_ON(pAdapter))
4324 {
4325 LinkDown(pAdapter, FALSE);
4326 pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
4327 }
4328 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
4329 }
4330 break;
4331 case OID_802_11_DROP_UNENCRYPTED:
4332 if (wrq->u.data.length != sizeof(int))
4333 Status = -EINVAL;
4334 else
4335 {
4336 int enabled = 0;
4337 Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
4338 if (enabled == 1)
4339 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
4340 else
4341 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
4342 NdisAcquireSpinLock(&pAdapter->MacTabLock);
4343 pAdapter->MacTab.Content[BSSID_WCID].PortSecured = pAdapter->StaCfg.PortSecured;
4344 NdisReleaseSpinLock(&pAdapter->MacTabLock);
4345 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
4346 }
4347 break;
4348 case OID_802_11_SET_IEEE8021X:
4349 if (wrq->u.data.length != sizeof(BOOLEAN))
4350 Status = -EINVAL;
4351 else
4352 {
4353 Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
4354 pAdapter->StaCfg.IEEE8021X = IEEE8021xState;
4355 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
4356 }
4357 break;
4358 case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
4359 if (wrq->u.data.length != sizeof(BOOLEAN))
4360 Status = -EINVAL;
4361 else
4362 {
4363 Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
4364 pAdapter->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
4365 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
4366 }
4367 break;
4368 case OID_802_11_PMKID:
4369 pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
4370
4371 if(pPmkId == NULL) {
4372 Status = -ENOMEM;
4373 break;
4374 }
4375 Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
4376
4377 // check the PMKID information
4378 if (pPmkId->BSSIDInfoCount == 0)
4379 NdisZeroMemory(pAdapter->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
4380 else
4381 {
4382 PBSSID_INFO pBssIdInfo;
4383 UINT BssIdx;
4384 UINT CachedIdx;
4385
4386 for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
4387 {
4388 // point to the indexed BSSID_INFO structure
4389 pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
4390 // Find the entry in the saved data base.
4391 for (CachedIdx = 0; CachedIdx < pAdapter->StaCfg.SavedPMKNum; CachedIdx++)
4392 {
4393 // compare the BSSID
4394 if (NdisEqualMemory(pBssIdInfo->BSSID, pAdapter->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
4395 break;
4396 }
4397
4398 // Found, replace it
4399 if (CachedIdx < PMKID_NO)
4400 {
4401 DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4402 NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4403 pAdapter->StaCfg.SavedPMKNum++;
4404 }
4405 // Not found, replace the last one
4406 else
4407 {
4408 // Randomly replace one
4409 CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
4410 DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
4411 NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
4412 }
4413 }
4414 }
4415 if(pPmkId)
4416 kfree(pPmkId);
4417 break;
4418#endif // WPA_SUPPLICANT_SUPPORT //
4419
4420
4421
4422#ifdef SNMP_SUPPORT
4423 case OID_802_11_SHORTRETRYLIMIT:
4424 if (wrq->u.data.length != sizeof(ULONG))
4425 Status = -EINVAL;
4426 else
4427 {
4428 Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4429 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4430 tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
4431 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4432 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit));
4433 }
4434 break;
4435
4436 case OID_802_11_LONGRETRYLIMIT:
4437 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n"));
4438 if (wrq->u.data.length != sizeof(ULONG))
4439 Status = -EINVAL;
4440 else
4441 {
4442 Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
4443 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
4444 tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
4445 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
4446 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit));
4447 }
4448 break;
4449
4450 case OID_802_11_WEPDEFAULTKEYVALUE:
4451 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n"));
4452 pKey = kmalloc(wrq->u.data.length, GFP_KERNEL);
4453 Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
4454 //pKey = &WepKey;
4455
4456 if ( pKey->Length != wrq->u.data.length)
4457 {
4458 Status = -EINVAL;
4459 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n"));
4460 }
4461 KeyIdx = pKey->KeyIndex & 0x0fffffff;
4462 DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength));
4463
4464 // it is a shared key
4465 if (KeyIdx > 4)
4466 Status = -EINVAL;
4467 else
4468 {
4469 pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
4470 NdisMoveMemory(&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
4471 if (pKey->KeyIndex & 0x80000000)
4472 {
4473 // Default key for tx (shared key)
4474 pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
4475 }
4476 //RestartAPIsRequired = TRUE;
4477 }
4478 break;
4479
4480
4481 case OID_802_11_WEPDEFAULTKEYID:
4482 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n"));
4483
4484 if (wrq->u.data.length != sizeof(UCHAR))
4485 Status = -EINVAL;
4486 else
4487 Status = copy_from_user(&pAdapter->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length);
4488
4489 break;
4490
4491
4492 case OID_802_11_CURRENTCHANNEL:
4493 DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n"));
4494 if (wrq->u.data.length != sizeof(UCHAR))
4495 Status = -EINVAL;
4496 else
4497 {
4498 Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length);
4499 sprintf(&ctmp,"%d", ctmp);
4500 Set_Channel_Proc(pAdapter, &ctmp);
4501 }
4502 break;
4503#endif
4504
4505
4506
4507 default:
4508 DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
4509 Status = -EOPNOTSUPP;
4510 break;
4511 }
4512
4513
4514 return Status;
4515}
4516
4517INT RTMPQueryInformation(
4518 IN PRTMP_ADAPTER pAdapter,
4519 IN OUT struct ifreq *rq,
4520 IN INT cmd)
4521{
4522 struct iwreq *wrq = (struct iwreq *) rq;
4523 NDIS_802_11_BSSID_LIST_EX *pBssidList = NULL;
4524 PNDIS_WLAN_BSSID_EX pBss;
4525 NDIS_802_11_SSID Ssid;
4526 NDIS_802_11_CONFIGURATION *pConfiguration = NULL;
4527 RT_802_11_LINK_STATUS *pLinkStatus = NULL;
4528 RT_802_11_STA_CONFIG *pStaConfig = NULL;
4529 NDIS_802_11_STATISTICS *pStatistics = NULL;
4530 NDIS_802_11_RTS_THRESHOLD RtsThresh;
4531 NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
4532 NDIS_802_11_POWER_MODE PowerMode;
4533 NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
4534 RT_802_11_PREAMBLE PreamType;
4535 NDIS_802_11_AUTHENTICATION_MODE AuthMode;
4536 NDIS_802_11_WEP_STATUS WepStatus;
4537 NDIS_MEDIA_STATE MediaState;
4538 ULONG BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
4539 USHORT BssLen = 0;
4540 PUCHAR pBuf = NULL, pPtr;
4541 INT Status = NDIS_STATUS_SUCCESS;
4542 UINT we_version_compiled;
4543 UCHAR i, Padding = 0;
4544 BOOLEAN RadioState;
4545 UCHAR driverVersion[8];
4546 OID_SET_HT_PHYMODE *pHTPhyMode = NULL;
4547
4548
4549#ifdef SNMP_SUPPORT
4550 //for snmp, kathy
4551 DefaultKeyIdxValue *pKeyIdxValue;
4552 INT valueLen;
4553 TX_RTY_CFG_STRUC tx_rty_cfg;
4554 ULONG ShortRetryLimit, LongRetryLimit;
4555 UCHAR tmp[64];
4556#endif //SNMP
4557
4558 switch(cmd)
4559 {
4560 case RT_OID_DEVICE_NAME:
4561 wrq->u.data.length = sizeof(STA_NIC_DEVICE_NAME);
4562 Status = copy_to_user(wrq->u.data.pointer, STA_NIC_DEVICE_NAME, wrq->u.data.length);
4563 break;
4564 case RT_OID_VERSION_INFO:
4565 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
4566 wrq->u.data.length = 8*sizeof(UCHAR);
4567 sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
4568 driverVersion[7] = '\0';
4569 if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
4570 {
4571 Status = -EFAULT;
4572 }
4573 break;
4574#ifdef RALINK_ATE
4575 case RT_QUERY_ATE_TXDONE_COUNT:
4576 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_QUERY_ATE_TXDONE_COUNT \n"));
4577 wrq->u.data.length = sizeof(UINT32);
4578 if (copy_to_user(wrq->u.data.pointer, &pAdapter->ate.TxDoneCount, wrq->u.data.length))
4579 {
4580 Status = -EFAULT;
4581 }
4582 break;
4583#endif // RALINK_ATE //
4584 case OID_802_11_BSSID_LIST:
4585 if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
4586 {
4587 /*
4588 * Still scanning, indicate the caller should try again.
4589 */
4590 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
4591 return -EAGAIN;
4592 }
4593 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAdapter->ScanTab.BssNr));
4594 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
4595 // Claculate total buffer size required
4596 BssBufSize = sizeof(ULONG);
4597
4598 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4599 {
4600 // Align pointer to 4 bytes boundary.
4601 //Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
4602 //if (Padding == 4)
4603 // Padding = 0;
4604 BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4605 }
4606
4607 // For safety issue, we add 256 bytes just in case
4608 BssBufSize += 256;
4609 // Allocate the same size as passed from higher layer
4610 pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
4611 if(pBuf == NULL)
4612 {
4613 Status = -ENOMEM;
4614 break;
4615 }
4616 // Init 802_11_BSSID_LIST_EX structure
4617 NdisZeroMemory(pBuf, BssBufSize);
4618 pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
4619 pBssidList->NumberOfItems = pAdapter->ScanTab.BssNr;
4620
4621 // Calculate total buffer length
4622 BssLen = 4; // Consist of NumberOfItems
4623 // Point to start of NDIS_WLAN_BSSID_EX
4624 // pPtr = pBuf + sizeof(ULONG);
4625 pPtr = (PUCHAR) &pBssidList->Bssid[0];
4626 for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
4627 {
4628 pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
4629 NdisMoveMemory(&pBss->MacAddress, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
4630 if ((pAdapter->ScanTab.BssEntry[i].Hidden == 1) && (pAdapter->StaCfg.bShowHiddenSSID == FALSE))
4631 {
4632 //
4633 // We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
4634 // and then failed to send EAPOl farame.
4635 //
4636 if ((pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAdapter->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
4637 {
4638 pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4639 NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4640 }
4641 else
4642 pBss->Ssid.SsidLength = 0;
4643 }
4644 else
4645 {
4646 pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
4647 NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
4648 }
4649 pBss->Privacy = pAdapter->ScanTab.BssEntry[i].Privacy;
4650 pBss->Rssi = pAdapter->ScanTab.BssEntry[i].Rssi - pAdapter->BbpRssiToDbmDelta;
4651 pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
4652 pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
4653 pBss->Configuration.BeaconPeriod = pAdapter->ScanTab.BssEntry[i].BeaconPeriod;
4654 pBss->Configuration.ATIMWindow = pAdapter->ScanTab.BssEntry[i].AtimWin;
4655
4656 MAP_CHANNEL_ID_TO_KHZ(pAdapter->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
4657
4658 if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_INFRA)
4659 pBss->InfrastructureMode = Ndis802_11Infrastructure;
4660 else
4661 pBss->InfrastructureMode = Ndis802_11IBSS;
4662
4663 NdisMoveMemory(pBss->SupportedRates, pAdapter->ScanTab.BssEntry[i].SupRate, pAdapter->ScanTab.BssEntry[i].SupRateLen);
4664 NdisMoveMemory(pBss->SupportedRates + pAdapter->ScanTab.BssEntry[i].SupRateLen,
4665 pAdapter->ScanTab.BssEntry[i].ExtRate,
4666 pAdapter->ScanTab.BssEntry[i].ExtRateLen);
4667
4668 if (pAdapter->ScanTab.BssEntry[i].VarIELen == 0)
4669 {
4670 pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
4671 NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4672 pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4673 }
4674 else
4675 {
4676 pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen);
4677 pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
4678 NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
4679 NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAdapter->ScanTab.BssEntry[i].VarIEs, pAdapter->ScanTab.BssEntry[i].VarIELen);
4680 pPtr += pAdapter->ScanTab.BssEntry[i].VarIELen;
4681 }
4682 pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
4683
4684#if WIRELESS_EXT < 17
4685 if ((BssLen + pBss->Length) < wrq->u.data.length)
4686 BssLen += pBss->Length;
4687 else
4688 {
4689 pBssidList->NumberOfItems = i;
4690 break;
4691 }
4692#else
4693 BssLen += pBss->Length;
4694#endif
4695 }
4696
4697#if WIRELESS_EXT < 17
4698 wrq->u.data.length = BssLen;
4699#else
4700 if (BssLen > wrq->u.data.length)
4701 {
4702 kfree(pBssidList);
4703 return -E2BIG;
4704 }
4705 else
4706 wrq->u.data.length = BssLen;
4707#endif
4708 Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
4709 kfree(pBssidList);
4710 break;
4711 case OID_802_3_CURRENT_ADDRESS:
4712 wrq->u.data.length = MAC_ADDR_LEN;
4713 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
4714 break;
4715 case OID_GEN_MEDIA_CONNECT_STATUS:
4716 if (pAdapter->IndicateMediaState == NdisMediaStateConnected)
4717 MediaState = NdisMediaStateConnected;
4718 else
4719 MediaState = NdisMediaStateDisconnected;
4720
4721 wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
4722 Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
4723 break;
4724 case OID_802_11_BSSID:
4725#ifdef RALINK_ATE
4726 if (ATE_ON(pAdapter))
4727 {
4728 DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
4729 Status = NDIS_STATUS_RESOURCES;
4730 break;
4731 }
4732#endif // RALINK_ATE //
4733 if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
4734 {
4735 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
4736
4737 }
4738 else
4739 {
4740 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
4741 Status = -ENOTCONN;
4742 }
4743 break;
4744 case OID_802_11_SSID:
4745 NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
4746 NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
4747 Ssid.SsidLength = pAdapter->CommonCfg.SsidLen;
4748 memcpy(Ssid.Ssid, pAdapter->CommonCfg.Ssid, Ssid.SsidLength);
4749 wrq->u.data.length = sizeof(NDIS_802_11_SSID);
4750 Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
4751 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
4752 break;
4753 case RT_OID_802_11_QUERY_LINK_STATUS:
4754 pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
4755 if (pLinkStatus)
4756 {
4757 pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAdapter->CommonCfg.TxRate]; // unit : 500 kbps
4758 pLinkStatus->ChannelQuality = pAdapter->Mlme.ChannelQuality;
4759 pLinkStatus->RxByteCount = pAdapter->RalinkCounters.ReceivedByteCount;
4760 pLinkStatus->TxByteCount = pAdapter->RalinkCounters.TransmittedByteCount;
4761 pLinkStatus->CentralChannel = pAdapter->CommonCfg.CentralChannel;
4762 wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
4763 Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
4764 kfree(pLinkStatus);
4765 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
4766 }
4767 else
4768 {
4769 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
4770 Status = -EFAULT;
4771 }
4772 break;
4773 case OID_802_11_CONFIGURATION:
4774 pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
4775 if (pConfiguration)
4776 {
4777 pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
4778 pConfiguration->BeaconPeriod = pAdapter->CommonCfg.BeaconPeriod;
4779 pConfiguration->ATIMWindow = pAdapter->StaActive.AtimWin;
4780 MAP_CHANNEL_ID_TO_KHZ(pAdapter->CommonCfg.Channel, pConfiguration->DSConfig);
4781 wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
4782 Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
4783 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
4784 pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAdapter->CommonCfg.Channel));
4785 kfree(pConfiguration);
4786 }
4787 else
4788 {
4789 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
4790 Status = -EFAULT;
4791 }
4792 break;
4793 case RT_OID_802_11_SNR_0:
4794 if ((pAdapter->StaCfg.LastSNR0 > 0))
4795 {
4796 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR0) * 3) / 16 ;
4797 wrq->u.data.length = sizeof(ulInfo);
4798 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4799 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
4800 }
4801 else
4802 Status = -EFAULT;
4803 break;
4804 case RT_OID_802_11_SNR_1:
4805 if ((pAdapter->Antenna.field.RxPath > 1) &&
4806 (pAdapter->StaCfg.LastSNR1 > 0))
4807 {
4808 ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR1) * 3) / 16 ;
4809 wrq->u.data.length = sizeof(ulInfo);
4810 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4811 DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
4812 }
4813 else
4814 Status = -EFAULT;
4815 DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAdapter->StaCfg.LastSNR1=%d)\n",pAdapter->StaCfg.LastSNR1));
4816 break;
4817 case OID_802_11_RSSI_TRIGGER:
4818 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0 - pAdapter->BbpRssiToDbmDelta;
4819 wrq->u.data.length = sizeof(ulInfo);
4820 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4821 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
4822 break;
4823 case OID_802_11_RSSI:
4824 case RT_OID_802_11_RSSI:
4825 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0;
4826 wrq->u.data.length = sizeof(ulInfo);
4827 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4828 break;
4829 case RT_OID_802_11_RSSI_1:
4830 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi1;
4831 wrq->u.data.length = sizeof(ulInfo);
4832 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4833 break;
4834 case RT_OID_802_11_RSSI_2:
4835 ulInfo = pAdapter->StaCfg.RssiSample.LastRssi2;
4836 wrq->u.data.length = sizeof(ulInfo);
4837 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4838 break;
4839 case OID_802_11_STATISTICS:
4840 pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
4841 if (pStatistics)
4842 {
4843 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
4844 // add the most up-to-date h/w raw counters into software counters
4845 NICUpdateRawCounters(pAdapter);
4846
4847 // Sanity check for calculation of sucessful count
4848 if (pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart < pAdapter->WlanCounters.RetryCount.QuadPart)
4849 pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4850
4851 pStatistics->TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart;
4852 pStatistics->MulticastTransmittedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
4853 pStatistics->FailedCount.QuadPart = pAdapter->WlanCounters.FailedCount.QuadPart;
4854 pStatistics->RetryCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
4855 pStatistics->MultipleRetryCount.QuadPart = pAdapter->WlanCounters.MultipleRetryCount.QuadPart;
4856 pStatistics->RTSSuccessCount.QuadPart = pAdapter->WlanCounters.RTSSuccessCount.QuadPart;
4857 pStatistics->RTSFailureCount.QuadPart = pAdapter->WlanCounters.RTSFailureCount.QuadPart;
4858 pStatistics->ACKFailureCount.QuadPart = pAdapter->WlanCounters.ACKFailureCount.QuadPart;
4859 pStatistics->FrameDuplicateCount.QuadPart = pAdapter->WlanCounters.FrameDuplicateCount.QuadPart;
4860 pStatistics->ReceivedFragmentCount.QuadPart = pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart;
4861 pStatistics->MulticastReceivedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastReceivedFrameCount.QuadPart;
4862#ifdef DBG
4863 pStatistics->FCSErrorCount = pAdapter->RalinkCounters.RealFcsErrCount;
4864#else
4865 pStatistics->FCSErrorCount.QuadPart = pAdapter->WlanCounters.FCSErrorCount.QuadPart;
4866 pStatistics->FrameDuplicateCount.u.LowPart = pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
4867#endif
4868 wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
4869 Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
4870 kfree(pStatistics);
4871 }
4872 else
4873 {
4874 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
4875 Status = -EFAULT;
4876 }
4877 break;
4878 case OID_GEN_RCV_OK:
4879 ulInfo = pAdapter->Counters8023.GoodReceives;
4880 wrq->u.data.length = sizeof(ulInfo);
4881 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4882 break;
4883 case OID_GEN_RCV_NO_BUFFER:
4884 ulInfo = pAdapter->Counters8023.RxNoBuffer;
4885 wrq->u.data.length = sizeof(ulInfo);
4886 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
4887 break;
4888 case RT_OID_802_11_PHY_MODE:
4889 ulInfo = (ULONG)pAdapter->CommonCfg.PhyMode;
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_PHY_MODE (=%ld)\n", ulInfo));
4893 break;
4894 case RT_OID_802_11_STA_CONFIG:
4895 pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
4896 if (pStaConfig)
4897 {
4898 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
4899 pStaConfig->EnableTxBurst = pAdapter->CommonCfg.bEnableTxBurst;
4900 pStaConfig->EnableTurboRate = 0;
4901 pStaConfig->UseBGProtection = pAdapter->CommonCfg.UseBGProtection;
4902 pStaConfig->UseShortSlotTime = pAdapter->CommonCfg.bUseShortSlotTime;
4903 //pStaConfig->AdhocMode = pAdapter->StaCfg.AdhocMode;
4904 pStaConfig->HwRadioStatus = (pAdapter->StaCfg.bHwRadio == TRUE) ? 1 : 0;
4905 pStaConfig->Rsv1 = 0;
4906 pStaConfig->SystemErrorBitmap = pAdapter->SystemErrorBitmap;
4907 wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
4908 Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
4909 kfree(pStaConfig);
4910 }
4911 else
4912 {
4913 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
4914 Status = -EFAULT;
4915 }
4916 break;
4917 case OID_802_11_RTS_THRESHOLD:
4918 RtsThresh = pAdapter->CommonCfg.RtsThreshold;
4919 wrq->u.data.length = sizeof(RtsThresh);
4920 Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
4921 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
4922 break;
4923 case OID_802_11_FRAGMENTATION_THRESHOLD:
4924 FragThresh = pAdapter->CommonCfg.FragmentThreshold;
4925 if (pAdapter->CommonCfg.bUseZeroToDisableFragment == TRUE)
4926 FragThresh = 0;
4927 wrq->u.data.length = sizeof(FragThresh);
4928 Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
4929 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
4930 break;
4931 case OID_802_11_POWER_MODE:
4932 PowerMode = pAdapter->StaCfg.WindowsPowerMode;
4933 wrq->u.data.length = sizeof(PowerMode);
4934 Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
4935 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
4936 break;
4937 case RT_OID_802_11_RADIO:
4938 RadioState = (BOOLEAN) pAdapter->StaCfg.bSwRadio;
4939 wrq->u.data.length = sizeof(RadioState);
4940 Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
4941 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
4942 break;
4943 case OID_802_11_INFRASTRUCTURE_MODE:
4944 if (pAdapter->StaCfg.BssType == BSS_ADHOC)
4945 BssType = Ndis802_11IBSS;
4946 else if (pAdapter->StaCfg.BssType == BSS_INFRA)
4947 BssType = Ndis802_11Infrastructure;
4948 else if (pAdapter->StaCfg.BssType == BSS_MONITOR)
4949 BssType = Ndis802_11Monitor;
4950 else
4951 BssType = Ndis802_11AutoUnknown;
4952
4953 wrq->u.data.length = sizeof(BssType);
4954 Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
4955 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
4956 break;
4957 case RT_OID_802_11_PREAMBLE:
4958 PreamType = pAdapter->CommonCfg.TxPreamble;
4959 wrq->u.data.length = sizeof(PreamType);
4960 Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
4961 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
4962 break;
4963 case OID_802_11_AUTHENTICATION_MODE:
4964 AuthMode = pAdapter->StaCfg.AuthMode;
4965 wrq->u.data.length = sizeof(AuthMode);
4966 Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
4967 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
4968 break;
4969 case OID_802_11_WEP_STATUS:
4970 WepStatus = pAdapter->StaCfg.WepStatus;
4971 wrq->u.data.length = sizeof(WepStatus);
4972 Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
4973 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
4974 break;
4975 case OID_802_11_TX_POWER_LEVEL:
4976 wrq->u.data.length = sizeof(ULONG);
4977 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPower, wrq->u.data.length);
4978 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAdapter->CommonCfg.TxPower));
4979 break;
4980 case RT_OID_802_11_TX_POWER_LEVEL_1:
4981 wrq->u.data.length = sizeof(ULONG);
4982 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPowerPercentage, wrq->u.data.length);
4983 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
4984 break;
4985 case OID_802_11_NETWORK_TYPES_SUPPORTED:
4986 if ((pAdapter->RfIcType == RFIC_2850) || (pAdapter->RfIcType == RFIC_2750))
4987 {
4988 NetworkTypeList[0] = 3; // NumberOfItems = 3
4989 NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
4990 NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
4991 NetworkTypeList[3] = Ndis802_11OFDM5; // NetworkType[3] = 11a
4992 wrq->u.data.length = 16;
4993 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
4994 }
4995 else
4996 {
4997 NetworkTypeList[0] = 2; // NumberOfItems = 2
4998 NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
4999 NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
5000 wrq->u.data.length = 12;
5001 Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
5002 }
5003 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
5004 break;
5005 case OID_802_11_NETWORK_TYPE_IN_USE:
5006 wrq->u.data.length = sizeof(ULONG);
5007 if (pAdapter->CommonCfg.PhyMode == PHY_11A)
5008 ulInfo = Ndis802_11OFDM5;
5009 else if ((pAdapter->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAdapter->CommonCfg.PhyMode == PHY_11G))
5010 ulInfo = Ndis802_11OFDM24;
5011 else
5012 ulInfo = Ndis802_11DS;
5013 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5014 break;
5015 case RT_OID_802_11_QUERY_LAST_RX_RATE:
5016 ulInfo = (ULONG)pAdapter->LastRxRate;
5017 wrq->u.data.length = sizeof(ulInfo);
5018 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5019 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
5020 break;
5021 case RT_OID_802_11_QUERY_LAST_TX_RATE:
5022 //ulInfo = (ULONG)pAdapter->LastTxRate;
5023 ulInfo = (ULONG)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word;
5024 wrq->u.data.length = sizeof(ulInfo);
5025 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5026 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
5027 break;
5028 case RT_OID_802_11_QUERY_EEPROM_VERSION:
5029 wrq->u.data.length = sizeof(ULONG);
5030 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->EepromVersion, wrq->u.data.length);
5031 break;
5032 case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
5033 wrq->u.data.length = sizeof(ULONG);
5034 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->FirmwareVersion, wrq->u.data.length);
5035 break;
5036 case RT_OID_802_11_QUERY_NOISE_LEVEL:
5037 wrq->u.data.length = sizeof(UCHAR);
5038 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->BbpWriteLatch[66], wrq->u.data.length);
5039 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAdapter->BbpWriteLatch[66]));
5040 break;
5041 case RT_OID_802_11_EXTRA_INFO:
5042 wrq->u.data.length = sizeof(ULONG);
5043 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->ExtraInfo, wrq->u.data.length);
5044 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAdapter->ExtraInfo));
5045 break;
5046 case RT_OID_WE_VERSION_COMPILED:
5047 wrq->u.data.length = sizeof(UINT);
5048 we_version_compiled = WIRELESS_EXT;
5049 Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
5050 break;
5051 case RT_OID_802_11_QUERY_APSD_SETTING:
5052 apsd = (pAdapter->CommonCfg.bAPSDCapable | (pAdapter->CommonCfg.bAPSDAC_BE << 1) | (pAdapter->CommonCfg.bAPSDAC_BK << 2)
5053 | (pAdapter->CommonCfg.bAPSDAC_VI << 3) | (pAdapter->CommonCfg.bAPSDAC_VO << 4) | (pAdapter->CommonCfg.MaxSPLength << 5));
5054
5055 wrq->u.data.length = sizeof(ULONG);
5056 Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
5057 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",
5058 apsd,pAdapter->CommonCfg.bAPSDCapable,pAdapter->CommonCfg.bAPSDAC_BE,pAdapter->CommonCfg.bAPSDAC_BK,pAdapter->CommonCfg.bAPSDAC_VI,pAdapter->CommonCfg.bAPSDAC_VO,pAdapter->CommonCfg.MaxSPLength));
5059 break;
5060 case RT_OID_802_11_QUERY_APSD_PSM:
5061 wrq->u.data.length = sizeof(ULONG);
5062 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
5063 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
5064 break;
5065 case RT_OID_802_11_QUERY_WMM:
5066 wrq->u.data.length = sizeof(BOOLEAN);
5067 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bWmmCapable, wrq->u.data.length);
5068 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n", pAdapter->CommonCfg.bWmmCapable));
5069 break;
5070#ifdef WPA_SUPPLICANT_SUPPORT
5071 case RT_OID_NEW_DRIVER:
5072 {
5073 UCHAR enabled = 1;
5074 wrq->u.data.length = sizeof(UCHAR);
5075 Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
5076 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
5077 }
5078 break;
5079 case RT_OID_WPA_SUPPLICANT_SUPPORT:
5080 wrq->u.data.length = sizeof(UCHAR);
5081 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.WpaSupplicantUP, wrq->u.data.length);
5082 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
5083 break;
5084#endif // WPA_SUPPLICANT_SUPPORT //
5085
5086 case RT_OID_DRIVER_DEVICE_NAME:
5087 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
5088 wrq->u.data.length = 16;
5089 if (copy_to_user(wrq->u.data.pointer, pAdapter->StaCfg.dev_name, wrq->u.data.length))
5090 {
5091 Status = -EFAULT;
5092 }
5093 break;
5094 case RT_OID_802_11_QUERY_HT_PHYMODE:
5095 pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5096 if (pHTPhyMode)
5097 {
5098 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5099 pHTPhyMode->HtMode = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
5100 pHTPhyMode->BW = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
5101 pHTPhyMode->MCS= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
5102 pHTPhyMode->SHORTGI= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
5103 pHTPhyMode->STBC= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
5104
5105 pHTPhyMode->ExtOffset = ((pAdapter->CommonCfg.CentralChannel < pAdapter->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
5106 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5107 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5108 {
5109 Status = -EFAULT;
5110 }
5111 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5112 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5113 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5114 }
5115 else
5116 {
5117 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5118 Status = -EFAULT;
5119 }
5120 break;
5121 case RT_OID_802_11_COUNTRY_REGION:
5122 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
5123 wrq->u.data.length = sizeof(ulInfo);
5124 ulInfo = pAdapter->CommonCfg.CountryRegionForABand;
5125 ulInfo = (ulInfo << 8)|(pAdapter->CommonCfg.CountryRegion);
5126 if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
5127 {
5128 Status = -EFAULT;
5129 }
5130 break;
5131 case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
5132 pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
5133 if (pHTPhyMode)
5134 {
5135 pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
5136 pHTPhyMode->HtMode = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.HTMODE;
5137 pHTPhyMode->BW = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.BW;
5138 pHTPhyMode->MCS= (UCHAR)pAdapter->StaCfg.DesiredTransmitSetting.field.MCS;
5139 pHTPhyMode->SHORTGI= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.ShortGI;
5140 pHTPhyMode->STBC= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.STBC;
5141
5142 wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
5143 if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
5144 {
5145 Status = -EFAULT;
5146 }
5147 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
5148 pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
5149 DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
5150 }
5151 else
5152 {
5153 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
5154 Status = -EFAULT;
5155 }
5156 break;
5157 case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
5158 wrq->u.data.length = sizeof(UCHAR);
5159 i = 0;
5160#ifdef MULTIPLE_CARD_SUPPORT
5161 i = 1;
5162#endif // MULTIPLE_CARD_SUPPORT //
5163 if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
5164 {
5165 Status = -EFAULT;
5166 }
5167 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
5168 break;
5169#ifdef SNMP_SUPPORT
5170 case RT_OID_802_11_MAC_ADDRESS:
5171 wrq->u.data.length = MAC_ADDR_LEN;
5172 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5173 break;
5174
5175 case RT_OID_802_11_MANUFACTUREROUI:
5176 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n"));
5177 wrq->u.data.length = ManufacturerOUI_LEN;
5178 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
5179 break;
5180
5181 case RT_OID_802_11_MANUFACTURERNAME:
5182 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n"));
5183 wrq->u.data.length = strlen(ManufacturerNAME);
5184 Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5185 break;
5186
5187 case RT_OID_802_11_RESOURCETYPEIDNAME:
5188 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n"));
5189 wrq->u.data.length = strlen(ResourceTypeIdName);
5190 Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length);
5191 break;
5192
5193 case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED:
5194 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n"));
5195 ulInfo = 1; // 1 is support wep else 2 is not support.
5196 wrq->u.data.length = sizeof(ulInfo);
5197 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5198 break;
5199
5200 case RT_OID_802_11_POWERMANAGEMENTMODE:
5201 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
5202 if (pAdapter->StaCfg.Psm == PSMP_ACTION)
5203 ulInfo = 1; // 1 is power active else 2 is power save.
5204 else
5205 ulInfo = 2;
5206
5207 wrq->u.data.length = sizeof(ulInfo);
5208 Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
5209 break;
5210
5211 case OID_802_11_WEPDEFAULTKEYVALUE:
5212 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n"));
5213 //KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId;
5214 pKeyIdxValue = wrq->u.data.pointer;
5215 DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
5216 valueLen = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
5217 NdisMoveMemory(pKeyIdxValue->Value,
5218 &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key,
5219 valueLen);
5220 pKeyIdxValue->Value[valueLen]='\0';
5221
5222 wrq->u.data.length = sizeof(DefaultKeyIdxValue);
5223
5224 Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length);
5225 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,
5226 pAdapter->SharedKey[BSS0][0].Key[0],
5227 pAdapter->SharedKey[BSS0][1].Key[0],
5228 pAdapter->SharedKey[BSS0][2].Key[0],
5229 pAdapter->SharedKey[BSS0][3].Key[0]));
5230 break;
5231
5232 case OID_802_11_WEPDEFAULTKEYID:
5233 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n"));
5234 wrq->u.data.length = sizeof(UCHAR);
5235 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length);
5236 DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAdapter->StaCfg.DefaultKeyId));
5237 break;
5238
5239 case RT_OID_802_11_WEPKEYMAPPINGLENGTH:
5240 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n"));
5241 wrq->u.data.length = sizeof(UCHAR);
5242 Status = copy_to_user(wrq->u.data.pointer,
5243 &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
5244 wrq->u.data.length);
5245 break;
5246
5247 case OID_802_11_SHORTRETRYLIMIT:
5248 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n"));
5249 wrq->u.data.length = sizeof(ULONG);
5250 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5251 ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit;
5252 DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld, tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit));
5253 Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length);
5254 break;
5255
5256 case OID_802_11_LONGRETRYLIMIT:
5257 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n"));
5258 wrq->u.data.length = sizeof(ULONG);
5259 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
5260 LongRetryLimit = tx_rty_cfg.field.LongRtyLimit;
5261 DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld, tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit));
5262 Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length);
5263 break;
5264
5265 case RT_OID_802_11_PRODUCTID:
5266 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
5267
5268#ifdef RT2860
5269 {
5270
5271 USHORT device_id;
5272 if (((POS_COOKIE)pAdapter->OS_Cookie)->pci_dev != NULL)
5273 pci_read_config_word(((POS_COOKIE)pAdapter->OS_Cookie)->pci_dev, PCI_DEVICE_ID, &device_id);
5274 else
5275 DBGPRINT(RT_DEBUG_TRACE, (" pci_dev = NULL\n"));
5276 sprintf(tmp, "%04x %04x\n", NIC_PCI_VENDOR_ID, device_id);
5277 }
5278#endif // RT2860 //
5279 wrq->u.data.length = strlen(tmp);
5280 Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
5281 break;
5282
5283 case RT_OID_802_11_MANUFACTUREID:
5284 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n"));
5285 wrq->u.data.length = strlen(ManufacturerNAME);
5286 Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
5287 break;
5288
5289 case OID_802_11_CURRENTCHANNEL:
5290 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n"));
5291 wrq->u.data.length = sizeof(UCHAR);
5292 DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAdapter->CommonCfg.Channel));
5293 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Channel, wrq->u.data.length);
5294 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5295 break;
5296#endif //SNMP_SUPPORT
5297
5298 case OID_802_11_BUILD_CHANNEL_EX:
5299 {
5300 UCHAR value;
5301 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
5302 wrq->u.data.length = sizeof(UCHAR);
5303#ifdef EXT_BUILD_CHANNEL_LIST
5304 DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n"));
5305 value = 1;
5306#else
5307 DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
5308 value = 0;
5309#endif // EXT_BUILD_CHANNEL_LIST //
5310 Status = copy_to_user(wrq->u.data.pointer, &value, 1);
5311 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5312 }
5313 break;
5314
5315 case OID_802_11_GET_CH_LIST:
5316 {
5317 PRT_CHANNEL_LIST_INFO pChListBuf;
5318
5319 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
5320 if (pAdapter->ChannelListNum == 0)
5321 {
5322 wrq->u.data.length = 0;
5323 break;
5324 }
5325
5326 pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
5327 if (pChListBuf == NULL)
5328 {
5329 wrq->u.data.length = 0;
5330 break;
5331 }
5332
5333 pChListBuf->ChannelListNum = pAdapter->ChannelListNum;
5334 for (i = 0; i < pChListBuf->ChannelListNum; i++)
5335 pChListBuf->ChannelList[i] = pAdapter->ChannelList[i].Channel;
5336
5337 wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
5338 Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
5339 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5340
5341 if (pChListBuf)
5342 kfree(pChListBuf);
5343 }
5344 break;
5345
5346 case OID_802_11_GET_COUNTRY_CODE:
5347 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
5348 wrq->u.data.length = 2;
5349 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.CountryCode, 2);
5350 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5351 break;
5352
5353 case OID_802_11_GET_CHANNEL_GEOGRAPHY:
5354 DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
5355 wrq->u.data.length = 1;
5356 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Geography, 1);
5357 DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
5358 break;
5359
5360
5361#ifdef QOS_DLS_SUPPORT
5362 case RT_OID_802_11_QUERY_DLS:
5363 wrq->u.data.length = sizeof(BOOLEAN);
5364 Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bDLSCapable, wrq->u.data.length);
5365 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAdapter->CommonCfg.bDLSCapable));
5366 break;
5367
5368 case RT_OID_802_11_QUERY_DLS_PARAM:
5369 {
5370 PRT_802_11_DLS_INFO pDlsInfo = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC);
5371 if (pDlsInfo == NULL)
5372 break;
5373
5374 for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
5375 {
5376 RTMPMoveMemory(&pDlsInfo->Entry[i], &pAdapter->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI));
5377 }
5378
5379 pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY;
5380 wrq->u.data.length = sizeof(RT_802_11_DLS_INFO);
5381 Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length);
5382 DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n"));
5383
5384 if (pDlsInfo)
5385 kfree(pDlsInfo);
5386 }
5387 break;
5388#endif // QOS_DLS_SUPPORT //
5389 default:
5390 DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
5391 Status = -EOPNOTSUPP;
5392 break;
5393 }
5394 return Status;
5395}
5396
5397INT rt28xx_sta_ioctl(
5398 IN struct net_device *net_dev,
5399 IN OUT struct ifreq *rq,
5400 IN INT cmd)
5401{
5402 POS_COOKIE pObj;
5403 VIRTUAL_ADAPTER *pVirtualAd = NULL;
5404 RTMP_ADAPTER *pAd = NULL;
5405 struct iwreq *wrq = (struct iwreq *) rq;
5406 BOOLEAN StateMachineTouched = FALSE;
5407 INT Status = NDIS_STATUS_SUCCESS;
5408 USHORT subcmd;
5409
5410 if (net_dev->priv_flags == INT_MAIN)
5411 {
5412 pAd = net_dev->priv;
5413 }
5414 else
5415 {
5416 pVirtualAd = net_dev->priv;
5417 pAd = pVirtualAd->RtmpDev->priv;
5418 }
5419 pObj = (POS_COOKIE) pAd->OS_Cookie;
5420
5421 if (pAd == NULL)
5422 {
5423 /* if 1st open fail, pAd will be free;
5424 So the net_dev->priv will be NULL in 2rd open */
5425 return -ENETDOWN;
5426 }
5427
5428 //check if the interface is down
5429 if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
5430 {
5431#ifdef CONFIG_APSTA_MIXED_SUPPORT
5432 if (wrq->u.data.pointer == NULL)
5433 {
5434 return Status;
5435 }
5436
5437 if (strstr(wrq->u.data.pointer, "OpMode") == NULL)
5438#endif // CONFIG_APSTA_MIXED_SUPPORT //
5439 {
5440 DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
5441 return -ENETDOWN;
5442 }
5443 }
5444
5445 { // determine this ioctl command is comming from which interface.
5446 pObj->ioctl_if_type = INT_MAIN;
5447 pObj->ioctl_if = MAIN_MBSSID;
5448 }
5449
5450 switch(cmd)
5451 {
5452#ifdef RALINK_ATE
5453#ifdef RALINK_28xx_QA
5454 case RTPRIV_IOCTL_ATE:
5455 {
5456 RtmpDoAte(pAd, wrq);
5457 }
5458 break;
5459#endif // RALINK_28xx_QA //
5460#endif // RALINK_ATE //
5461 case SIOCGIFHWADDR:
5462 DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
5463 memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
5464 break;
5465 case SIOCGIWNAME:
5466 {
5467 char *name=&wrq->u.name[0];
5468 rt_ioctl_giwname(net_dev, NULL, name, NULL);
5469 break;
5470 }
5471 case SIOCGIWESSID: //Get ESSID
5472 {
5473 struct iw_point *essid=&wrq->u.essid;
5474 rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
5475 break;
5476 }
5477 case SIOCSIWESSID: //Set ESSID
5478 {
5479 struct iw_point *essid=&wrq->u.essid;
5480 rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
5481 break;
5482 }
5483 case SIOCSIWNWID: // set network id (the cell)
5484 case SIOCGIWNWID: // get network id
5485 Status = -EOPNOTSUPP;
5486 break;
5487 case SIOCSIWFREQ: //set channel/frequency (Hz)
5488 {
5489 struct iw_freq *freq=&wrq->u.freq;
5490 rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
5491 break;
5492 }
5493 case SIOCGIWFREQ: // get channel/frequency (Hz)
5494 {
5495 struct iw_freq *freq=&wrq->u.freq;
5496 rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
5497 break;
5498 }
5499 case SIOCSIWNICKN: //set node name/nickname
5500 {
5501 struct iw_point *data=&wrq->u.data;
5502 rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
5503 break;
5504 }
5505 case SIOCGIWNICKN: //get node name/nickname
5506 {
5507 struct iw_point *data=&wrq->u.data;
5508 rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
5509 break;
5510 }
5511 case SIOCGIWRATE: //get default bit rate (bps)
5512 rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
5513 break;
5514 case SIOCSIWRATE: //set default bit rate (bps)
5515 rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
5516 break;
5517 case SIOCGIWRTS: // get RTS/CTS threshold (bytes)
5518 {
5519 struct iw_param *rts=&wrq->u.rts;
5520 rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
5521 break;
5522 }
5523 case SIOCSIWRTS: //set RTS/CTS threshold (bytes)
5524 {
5525 struct iw_param *rts=&wrq->u.rts;
5526 rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
5527 break;
5528 }
5529 case SIOCGIWFRAG: //get fragmentation thr (bytes)
5530 {
5531 struct iw_param *frag=&wrq->u.frag;
5532 rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
5533 break;
5534 }
5535 case SIOCSIWFRAG: //set fragmentation thr (bytes)
5536 {
5537 struct iw_param *frag=&wrq->u.frag;
5538 rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
5539 break;
5540 }
5541 case SIOCGIWENCODE: //get encoding token & mode
5542 {
5543 struct iw_point *erq=&wrq->u.encoding;
5544 if(erq->pointer)
5545 rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
5546 break;
5547 }
5548 case SIOCSIWENCODE: //set encoding token & mode
5549 {
5550 struct iw_point *erq=&wrq->u.encoding;
5551 if(erq->pointer)
5552 rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
5553 break;
5554 }
5555 case SIOCGIWAP: //get access point MAC addresses
5556 {
5557 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5558 rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5559 break;
5560 }
5561 case SIOCSIWAP: //set access point MAC addresses
5562 {
5563 struct sockaddr *ap_addr=&wrq->u.ap_addr;
5564 rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
5565 break;
5566 }
5567 case SIOCGIWMODE: //get operation mode
5568 {
5569 __u32 *mode=&wrq->u.mode;
5570 rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
5571 break;
5572 }
5573 case SIOCSIWMODE: //set operation mode
5574 {
5575 __u32 *mode=&wrq->u.mode;
5576 rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
5577 break;
5578 }
5579 case SIOCGIWSENS: //get sensitivity (dBm)
5580 case SIOCSIWSENS: //set sensitivity (dBm)
5581 case SIOCGIWPOWER: //get Power Management settings
5582 case SIOCSIWPOWER: //set Power Management settings
5583 case SIOCGIWTXPOW: //get transmit power (dBm)
5584 case SIOCSIWTXPOW: //set transmit power (dBm)
5585 case SIOCGIWRANGE: //Get range of parameters
5586 case SIOCGIWRETRY: //get retry limits and lifetime
5587 case SIOCSIWRETRY: //set retry limits and lifetime
5588 Status = -EOPNOTSUPP;
5589 break;
5590 case RT_PRIV_IOCTL:
5591 subcmd = wrq->u.data.flags;
5592 if( subcmd & OID_GET_SET_TOGGLE)
5593 Status = RTMPSetInformation(pAd, rq, subcmd);
5594 else
5595 Status = RTMPQueryInformation(pAd, rq, subcmd);
5596 break;
5597 case SIOCGIWPRIV:
5598 if (wrq->u.data.pointer)
5599 {
5600 if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
5601 break;
5602 wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
5603 if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
5604 Status = -EFAULT;
5605 }
5606 break;
5607 case RTPRIV_IOCTL_SET:
5608 if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
5609 break;
5610 rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
5611 break;
5612 case RTPRIV_IOCTL_GSITESURVEY:
5613 RTMPIoctlGetSiteSurvey(pAd, wrq);
5614 break;
5615#ifdef DBG
5616 case RTPRIV_IOCTL_MAC:
5617 RTMPIoctlMAC(pAd, wrq);
5618 break;
5619 case RTPRIV_IOCTL_E2P:
5620 RTMPIoctlE2PROM(pAd, wrq);
5621 break;
5622#endif // DBG //
5623 case SIOCETHTOOL:
5624 break;
5625 default:
5626 DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
5627 Status = -EOPNOTSUPP;
5628 break;
5629 }
5630
5631 if(StateMachineTouched) // Upper layer sent a MLME-related operations
5632 RT28XX_MLME_HANDLER(pAd);
5633
5634 return Status;
5635}
5636
5637/*
5638 ==========================================================================
5639 Description:
5640 Set SSID
5641 Return:
5642 TRUE if all parameters are OK, FALSE otherwise
5643 ==========================================================================
5644*/
5645INT Set_SSID_Proc(
5646 IN PRTMP_ADAPTER pAdapter,
5647 IN PUCHAR arg)
5648{
5649 NDIS_802_11_SSID Ssid, *pSsid=NULL;
5650 BOOLEAN StateMachineTouched = FALSE;
5651 int success = TRUE;
5652
5653 if( strlen(arg) <= MAX_LEN_OF_SSID)
5654 {
5655 NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
5656 if (strlen(arg) != 0)
5657 {
5658 NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
5659 Ssid.SsidLength = strlen(arg);
5660 }
5661 else //ANY ssid
5662 {
5663 Ssid.SsidLength = 0;
5664 memcpy(Ssid.Ssid, "", 0);
5665 pAdapter->StaCfg.BssType = BSS_INFRA;
5666 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5667 pAdapter->StaCfg.WepStatus = Ndis802_11EncryptionDisabled;
5668 }
5669 pSsid = &Ssid;
5670
5671 if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
5672 {
5673 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5674 DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
5675 }
5676
5677 pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
5678 pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
5679 pAdapter->bConfigChanged = TRUE;
5680
5681 MlmeEnqueue(pAdapter,
5682 MLME_CNTL_STATE_MACHINE,
5683 OID_802_11_SSID,
5684 sizeof(NDIS_802_11_SSID),
5685 (VOID *)pSsid);
5686
5687 StateMachineTouched = TRUE;
5688 DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
5689 }
5690 else
5691 success = FALSE;
5692
5693 if (StateMachineTouched) // Upper layer sent a MLME-related operations
5694 RT28XX_MLME_HANDLER(pAdapter);
5695
5696 return success;
5697}
5698
5699#ifdef WMM_SUPPORT
5700/*
5701 ==========================================================================
5702 Description:
5703 Set WmmCapable Enable or Disable
5704 Return:
5705 TRUE if all parameters are OK, FALSE otherwise
5706 ==========================================================================
5707*/
5708INT Set_WmmCapable_Proc(
5709 IN PRTMP_ADAPTER pAd,
5710 IN PUCHAR arg)
5711{
5712 BOOLEAN bWmmCapable;
5713
5714 bWmmCapable = simple_strtol(arg, 0, 10);
5715
5716 if ((bWmmCapable == 1)
5717 )
5718 pAd->CommonCfg.bWmmCapable = TRUE;
5719 else if (bWmmCapable == 0)
5720 pAd->CommonCfg.bWmmCapable = FALSE;
5721 else
5722 return FALSE; //Invalid argument
5723
5724 DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
5725 pAd->CommonCfg.bWmmCapable));
5726
5727 return TRUE;
5728}
5729#endif // WMM_SUPPORT //
5730
5731/*
5732 ==========================================================================
5733 Description:
5734 Set Network Type(Infrastructure/Adhoc mode)
5735 Return:
5736 TRUE if all parameters are OK, FALSE otherwise
5737 ==========================================================================
5738*/
5739INT Set_NetworkType_Proc(
5740 IN PRTMP_ADAPTER pAdapter,
5741 IN PUCHAR arg)
5742{
5743 UINT32 Value = 0;
5744
5745 if (strcmp(arg, "Adhoc") == 0)
5746 {
5747 if (pAdapter->StaCfg.BssType != BSS_ADHOC)
5748 {
5749 // Config has changed
5750 pAdapter->bConfigChanged = TRUE;
5751 if (MONITOR_ON(pAdapter))
5752 {
5753 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5754 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5755 Value &= (~0x80);
5756 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5757 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5758 pAdapter->StaCfg.bAutoReconnect = TRUE;
5759 LinkDown(pAdapter, FALSE);
5760 }
5761 if (INFRA_ON(pAdapter))
5762 {
5763 //BOOLEAN Cancelled;
5764 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5765 // Since calling this indicate user don't want to connect to that SSID anymore.
5766 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5767 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5768
5769 LinkDown(pAdapter, FALSE);
5770
5771 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
5772 }
5773 }
5774 pAdapter->StaCfg.BssType = BSS_ADHOC;
5775 pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5776 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
5777 }
5778 else if (strcmp(arg, "Infra") == 0)
5779 {
5780 if (pAdapter->StaCfg.BssType != BSS_INFRA)
5781 {
5782 // Config has changed
5783 pAdapter->bConfigChanged = TRUE;
5784 if (MONITOR_ON(pAdapter))
5785 {
5786 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
5787 RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5788 Value &= (~0x80);
5789 RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5790 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5791 pAdapter->StaCfg.bAutoReconnect = TRUE;
5792 LinkDown(pAdapter, FALSE);
5793 }
5794 if (ADHOC_ON(pAdapter))
5795 {
5796 // Set the AutoReconnectSsid to prevent it reconnect to old SSID
5797 // Since calling this indicate user don't want to connect to that SSID anymore.
5798 pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
5799 NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
5800
5801 LinkDown(pAdapter, FALSE);
5802 }
5803 }
5804 pAdapter->StaCfg.BssType = BSS_INFRA;
5805 pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
5806 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
5807
5808 pAdapter->StaCfg.BssType = BSS_INFRA;
5809 }
5810 else if (strcmp(arg, "Monitor") == 0)
5811 {
5812 UCHAR bbpValue = 0;
5813 BCN_TIME_CFG_STRUC csr;
5814 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
5815 OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
5816 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
5817 // disable all periodic state machine
5818 pAdapter->StaCfg.bAutoReconnect = FALSE;
5819 // reset all mlme state machine
5820 RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
5821 DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
5822 if (pAdapter->CommonCfg.CentralChannel == 0)
5823 {
5824#ifdef DOT11_N_SUPPORT
5825 if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
5826 pAdapter->CommonCfg.CentralChannel = 36;
5827 else
5828#endif // DOT11_N_SUPPORT //
5829 pAdapter->CommonCfg.CentralChannel = 6;
5830 }
5831#ifdef DOT11_N_SUPPORT
5832 else
5833 N_ChannelCheck(pAdapter);
5834#endif // DOT11_N_SUPPORT //
5835
5836#ifdef DOT11_N_SUPPORT
5837 if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5838 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5839 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
5840 {
5841 // 40MHz ,control channel at lower
5842 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5843 bbpValue &= (~0x18);
5844 bbpValue |= 0x10;
5845 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5846 pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5847 // RX : control channel at lower
5848 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5849 bbpValue &= (~0x20);
5850 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5851
5852 RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5853 Value &= 0xfffffffe;
5854 RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5855 pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
5856 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5857 AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5858 DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5859 pAdapter->CommonCfg.Channel,
5860 pAdapter->CommonCfg.CentralChannel));
5861 }
5862 else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
5863 pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
5864 pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
5865 {
5866 // 40MHz ,control channel at upper
5867 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5868 bbpValue &= (~0x18);
5869 bbpValue |= 0x10;
5870 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5871 pAdapter->CommonCfg.BBPCurrentBW = BW_40;
5872 RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
5873 Value |= 0x1;
5874 RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
5875
5876 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
5877 bbpValue |= (0x20);
5878 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
5879 pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
5880 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
5881 AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
5882 DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
5883 pAdapter->CommonCfg.Channel,
5884 pAdapter->CommonCfg.CentralChannel));
5885 }
5886 else
5887#endif // DOT11_N_SUPPORT //
5888 {
5889 // 20MHz
5890 RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
5891 bbpValue &= (~0x18);
5892 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
5893 pAdapter->CommonCfg.BBPCurrentBW = BW_20;
5894 AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
5895 AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
5896 DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
5897 }
5898 // Enable Rx with promiscuous reception
5899 RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
5900 // ASIC supporsts sniffer function with replacing RSSI with timestamp.
5901 //RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
5902 //Value |= (0x80);
5903 //RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
5904 // disable sync
5905 RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
5906 csr.field.bBeaconGen = 0;
5907 csr.field.bTBTTEnable = 0;
5908 csr.field.TsfSyncMode = 0;
5909 RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
5910
5911 pAdapter->StaCfg.BssType = BSS_MONITOR;
5912 pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
5913 DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
5914 }
5915
5916 // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
5917 pAdapter->StaCfg.WpaState = SS_NOTUSE;
5918
5919 DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
5920
5921 return TRUE;
5922}
5923
5924/*
5925 ==========================================================================
5926 Description:
5927 Set Authentication mode
5928 Return:
5929 TRUE if all parameters are OK, FALSE otherwise
5930 ==========================================================================
5931*/
5932INT Set_AuthMode_Proc(
5933 IN PRTMP_ADAPTER pAdapter,
5934 IN PUCHAR arg)
5935{
5936 if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
5937 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
5938 else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
5939 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
5940 else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
5941 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
5942 else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
5943 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
5944 else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
5945 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
5946 else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
5947 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
5948#ifdef WPA_SUPPLICANT_SUPPORT
5949 else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
5950 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
5951 else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
5952 pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
5953#endif // WPA_SUPPLICANT_SUPPORT //
5954 else
5955 return FALSE;
5956
5957 pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
5958
5959 DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
5960
5961 return TRUE;
5962}
5963
5964/*
5965 ==========================================================================
5966 Description:
5967 Set Encryption Type
5968 Return:
5969 TRUE if all parameters are OK, FALSE otherwise
5970 ==========================================================================
5971*/
5972INT Set_EncrypType_Proc(
5973 IN PRTMP_ADAPTER pAdapter,
5974 IN PUCHAR arg)
5975{
5976 if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
5977 {
5978 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5979 return TRUE; // do nothing
5980
5981 pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
5982 pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
5983 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
5984 }
5985 else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
5986 {
5987 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
5988 return TRUE; // do nothing
5989
5990 pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
5991 pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
5992 pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
5993 }
5994 else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
5995 {
5996 if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
5997 return TRUE; // do nothing
5998
5999 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
6000 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
6001 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
6002 }
6003 else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
6004 {
6005 if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
6006 return TRUE; // do nothing
6007
6008 pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
6009 pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
6010 pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
6011 }
6012 else
6013 return FALSE;
6014
6015 pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
6016
6017 DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
6018
6019 return TRUE;
6020}
6021
6022/*
6023 ==========================================================================
6024 Description:
6025 Set Default Key ID
6026 Return:
6027 TRUE if all parameters are OK, FALSE otherwise
6028 ==========================================================================
6029*/
6030INT Set_DefaultKeyID_Proc(
6031 IN PRTMP_ADAPTER pAdapter,
6032 IN PUCHAR arg)
6033{
6034 ULONG KeyIdx;
6035
6036 KeyIdx = simple_strtol(arg, 0, 10);
6037 if((KeyIdx >= 1 ) && (KeyIdx <= 4))
6038 pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
6039 else
6040 return FALSE; //Invalid argument
6041
6042 DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
6043
6044 return TRUE;
6045}
6046
6047/*
6048 ==========================================================================
6049 Description:
6050 Set WEP KEY1
6051 Return:
6052 TRUE if all parameters are OK, FALSE otherwise
6053 ==========================================================================
6054*/
6055INT Set_Key1_Proc(
6056 IN PRTMP_ADAPTER pAdapter,
6057 IN PUCHAR arg)
6058{
6059 int KeyLen;
6060 int i;
6061 UCHAR CipherAlg=CIPHER_WEP64;
6062
6063 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6064 return TRUE; // do nothing
6065
6066 KeyLen = strlen(arg);
6067
6068 switch (KeyLen)
6069 {
6070 case 5: //wep 40 Ascii type
6071 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6072 memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6073 CipherAlg = CIPHER_WEP64;
6074 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
6075 break;
6076 case 10: //wep 40 Hex type
6077 for(i=0; i < KeyLen; i++)
6078 {
6079 if( !isxdigit(*(arg+i)) )
6080 return FALSE; //Not Hex value;
6081 }
6082 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
6083 AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6084 CipherAlg = CIPHER_WEP64;
6085 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6086 break;
6087 case 13: //wep 104 Ascii type
6088 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
6089 memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
6090 CipherAlg = CIPHER_WEP128;
6091 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
6092 break;
6093 case 26: //wep 104 Hex type
6094 for(i=0; i < KeyLen; i++)
6095 {
6096 if( !isxdigit(*(arg+i)) )
6097 return FALSE; //Not Hex value;
6098 }
6099 pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
6100 AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
6101 CipherAlg = CIPHER_WEP128;
6102 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
6103 break;
6104 default: //Invalid argument
6105 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
6106 return FALSE;
6107 }
6108
6109 pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
6110
6111 // Set keys (into ASIC)
6112 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6113 ; // not support
6114 else // Old WEP stuff
6115 {
6116 AsicAddSharedKeyEntry(pAdapter,
6117 0,
6118 0,
6119 pAdapter->SharedKey[BSS0][0].CipherAlg,
6120 pAdapter->SharedKey[BSS0][0].Key,
6121 NULL,
6122 NULL);
6123 }
6124
6125 return TRUE;
6126}
6127/*
6128 ==========================================================================
6129
6130 Description:
6131 Set WEP KEY2
6132 Return:
6133 TRUE if all parameters are OK, FALSE otherwise
6134 ==========================================================================
6135*/
6136INT Set_Key2_Proc(
6137 IN PRTMP_ADAPTER pAdapter,
6138 IN PUCHAR arg)
6139{
6140 int KeyLen;
6141 int i;
6142 UCHAR CipherAlg=CIPHER_WEP64;
6143
6144 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6145 return TRUE; // do nothing
6146
6147 KeyLen = strlen(arg);
6148
6149 switch (KeyLen)
6150 {
6151 case 5: //wep 40 Ascii type
6152 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6153 memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6154 CipherAlg = CIPHER_WEP64;
6155 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6156 break;
6157 case 10: //wep 40 Hex type
6158 for(i=0; i < KeyLen; i++)
6159 {
6160 if( !isxdigit(*(arg+i)) )
6161 return FALSE; //Not Hex value;
6162 }
6163 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6164 AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6165 CipherAlg = CIPHER_WEP64;
6166 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6167 break;
6168 case 13: //wep 104 Ascii type
6169 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
6170 memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
6171 CipherAlg = CIPHER_WEP128;
6172 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
6173 break;
6174 case 26: //wep 104 Hex type
6175 for(i=0; i < KeyLen; i++)
6176 {
6177 if( !isxdigit(*(arg+i)) )
6178 return FALSE; //Not Hex value;
6179 }
6180 pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
6181 AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
6182 CipherAlg = CIPHER_WEP128;
6183 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
6184 break;
6185 default: //Invalid argument
6186 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
6187 return FALSE;
6188 }
6189 pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
6190
6191 // Set keys (into ASIC)
6192 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6193 ; // not support
6194 else // Old WEP stuff
6195 {
6196 AsicAddSharedKeyEntry(pAdapter,
6197 0,
6198 1,
6199 pAdapter->SharedKey[BSS0][1].CipherAlg,
6200 pAdapter->SharedKey[BSS0][1].Key,
6201 NULL,
6202 NULL);
6203 }
6204
6205 return TRUE;
6206}
6207/*
6208 ==========================================================================
6209 Description:
6210 Set WEP KEY3
6211 Return:
6212 TRUE if all parameters are OK, FALSE otherwise
6213 ==========================================================================
6214*/
6215INT Set_Key3_Proc(
6216 IN PRTMP_ADAPTER pAdapter,
6217 IN PUCHAR arg)
6218{
6219 int KeyLen;
6220 int i;
6221 UCHAR CipherAlg=CIPHER_WEP64;
6222
6223 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6224 return TRUE; // do nothing
6225
6226 KeyLen = strlen(arg);
6227
6228 switch (KeyLen)
6229 {
6230 case 5: //wep 40 Ascii type
6231 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6232 memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6233 CipherAlg = CIPHER_WEP64;
6234 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6235 break;
6236 case 10: //wep 40 Hex type
6237 for(i=0; i < KeyLen; i++)
6238 {
6239 if( !isxdigit(*(arg+i)) )
6240 return FALSE; //Not Hex value;
6241 }
6242 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6243 AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6244 CipherAlg = CIPHER_WEP64;
6245 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6246 break;
6247 case 13: //wep 104 Ascii type
6248 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
6249 memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
6250 CipherAlg = CIPHER_WEP128;
6251 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
6252 break;
6253 case 26: //wep 104 Hex type
6254 for(i=0; i < KeyLen; i++)
6255 {
6256 if( !isxdigit(*(arg+i)) )
6257 return FALSE; //Not Hex value;
6258 }
6259 pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
6260 AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
6261 CipherAlg = CIPHER_WEP128;
6262 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
6263 break;
6264 default: //Invalid argument
6265 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
6266 return FALSE;
6267 }
6268 pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
6269
6270 // Set keys (into ASIC)
6271 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6272 ; // not support
6273 else // Old WEP stuff
6274 {
6275 AsicAddSharedKeyEntry(pAdapter,
6276 0,
6277 2,
6278 pAdapter->SharedKey[BSS0][2].CipherAlg,
6279 pAdapter->SharedKey[BSS0][2].Key,
6280 NULL,
6281 NULL);
6282 }
6283
6284 return TRUE;
6285}
6286/*
6287 ==========================================================================
6288 Description:
6289 Set WEP KEY4
6290 Return:
6291 TRUE if all parameters are OK, FALSE otherwise
6292 ==========================================================================
6293*/
6294INT Set_Key4_Proc(
6295 IN PRTMP_ADAPTER pAdapter,
6296 IN PUCHAR arg)
6297{
6298 int KeyLen;
6299 int i;
6300 UCHAR CipherAlg=CIPHER_WEP64;
6301
6302 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6303 return TRUE; // do nothing
6304
6305 KeyLen = strlen(arg);
6306
6307 switch (KeyLen)
6308 {
6309 case 5: //wep 40 Ascii type
6310 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6311 memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6312 CipherAlg = CIPHER_WEP64;
6313 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6314 break;
6315 case 10: //wep 40 Hex type
6316 for(i=0; i < KeyLen; i++)
6317 {
6318 if( !isxdigit(*(arg+i)) )
6319 return FALSE; //Not Hex value;
6320 }
6321 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6322 AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6323 CipherAlg = CIPHER_WEP64;
6324 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6325 break;
6326 case 13: //wep 104 Ascii type
6327 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
6328 memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
6329 CipherAlg = CIPHER_WEP128;
6330 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
6331 break;
6332 case 26: //wep 104 Hex type
6333 for(i=0; i < KeyLen; i++)
6334 {
6335 if( !isxdigit(*(arg+i)) )
6336 return FALSE; //Not Hex value;
6337 }
6338 pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
6339 AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
6340 CipherAlg = CIPHER_WEP128;
6341 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
6342 break;
6343 default: //Invalid argument
6344 DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
6345 return FALSE;
6346 }
6347 pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
6348
6349 // Set keys (into ASIC)
6350 if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
6351 ; // not support
6352 else // Old WEP stuff
6353 {
6354 AsicAddSharedKeyEntry(pAdapter,
6355 0,
6356 3,
6357 pAdapter->SharedKey[BSS0][3].CipherAlg,
6358 pAdapter->SharedKey[BSS0][3].Key,
6359 NULL,
6360 NULL);
6361 }
6362
6363 return TRUE;
6364}
6365
6366/*
6367 ==========================================================================
6368 Description:
6369 Set WPA PSK key
6370 Return:
6371 TRUE if all parameters are OK, FALSE otherwise
6372 ==========================================================================
6373*/
6374INT Set_WPAPSK_Proc(
6375 IN PRTMP_ADAPTER pAdapter,
6376 IN PUCHAR arg)
6377{
6378 UCHAR keyMaterial[40];
6379
6380 if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
6381 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
6382 (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
6383 )
6384 return TRUE; // do nothing
6385
6386 DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
6387
6388 NdisZeroMemory(keyMaterial, 40);
6389
6390 if ((strlen(arg) < 8) || (strlen(arg) > 64))
6391 {
6392 DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
6393 return FALSE;
6394 }
6395
6396 if (strlen(arg) == 64)
6397 {
6398 AtoH(arg, keyMaterial, 32);
6399 NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6400
6401 }
6402 else
6403 {
6404 PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
6405 NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
6406 }
6407
6408
6409
6410 if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
6411 pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
6412 {
6413 pAdapter->StaCfg.WpaState = SS_NOTUSE;
6414 }
6415 else
6416 {
6417 // Start STA supplicant state machine
6418 pAdapter->StaCfg.WpaState = SS_START;
6419 }
6420
6421 return TRUE;
6422}
6423
6424/*
6425 ==========================================================================
6426 Description:
6427 Set Power Saving mode
6428 Return:
6429 TRUE if all parameters are OK, FALSE otherwise
6430 ==========================================================================
6431*/
6432INT Set_PSMode_Proc(
6433 IN PRTMP_ADAPTER pAdapter,
6434 IN PUCHAR arg)
6435{
6436 if (pAdapter->StaCfg.BssType == BSS_INFRA)
6437 {
6438 if ((strcmp(arg, "Max_PSP") == 0) ||
6439 (strcmp(arg, "max_psp") == 0) ||
6440 (strcmp(arg, "MAX_PSP") == 0))
6441 {
6442 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6443 // to exclude certain situations.
6444 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6445 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
6446 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
6447 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6448 pAdapter->StaCfg.DefaultListenCount = 5;
6449
6450 }
6451 else if ((strcmp(arg, "Fast_PSP") == 0) ||
6452 (strcmp(arg, "fast_psp") == 0) ||
6453 (strcmp(arg, "FAST_PSP") == 0))
6454 {
6455 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6456 // to exclude certain situations.
6457 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6458 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6459 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
6460 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
6461 pAdapter->StaCfg.DefaultListenCount = 3;
6462 }
6463 else if ((strcmp(arg, "Legacy_PSP") == 0) ||
6464 (strcmp(arg, "legacy_psp") == 0) ||
6465 (strcmp(arg, "LEGACY_PSP") == 0))
6466 {
6467 // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
6468 // to exclude certain situations.
6469 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6470 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6471 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
6472 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
6473 pAdapter->StaCfg.DefaultListenCount = 3;
6474 }
6475 else
6476 {
6477 //Default Ndis802_11PowerModeCAM
6478 // clear PSM bit immediately
6479 MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
6480 OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
6481 if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
6482 pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
6483 pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
6484 }
6485
6486 DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
6487 }
6488 else
6489 return FALSE;
6490
6491
6492 return TRUE;
6493}
6494
6495#ifdef WPA_SUPPLICANT_SUPPORT
6496/*
6497 ==========================================================================
6498 Description:
6499 Set WpaSupport flag.
6500 Value:
6501 0: Driver ignore wpa_supplicant.
6502 1: wpa_supplicant initiates scanning and AP selection.
6503 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
6504 Return:
6505 TRUE if all parameters are OK, FALSE otherwise
6506 ==========================================================================
6507*/
6508INT Set_Wpa_Support(
6509 IN PRTMP_ADAPTER pAd,
6510 IN PUCHAR arg)
6511{
6512
6513 if ( simple_strtol(arg, 0, 10) == 0)
6514 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6515 else if ( simple_strtol(arg, 0, 10) == 1)
6516 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
6517 else if ( simple_strtol(arg, 0, 10) == 2)
6518 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
6519 else
6520 pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
6521
6522 DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
6523
6524 return TRUE;
6525}
6526#endif // WPA_SUPPLICANT_SUPPORT //
6527
6528#ifdef DBG
6529/*
6530 ==========================================================================
6531 Description:
6532 Read / Write MAC
6533 Arguments:
6534 pAdapter Pointer to our adapter
6535 wrq Pointer to the ioctl argument
6536
6537 Return Value:
6538 None
6539
6540 Note:
6541 Usage:
6542 1.) iwpriv ra0 mac 0 ==> read MAC where Addr=0x0
6543 2.) iwpriv ra0 mac 0=12 ==> write MAC where Addr=0x0, value=12
6544 ==========================================================================
6545*/
6546VOID RTMPIoctlMAC(
6547 IN PRTMP_ADAPTER pAdapter,
6548 IN struct iwreq *wrq)
6549{
6550 CHAR *this_char;
6551 CHAR *value;
6552 INT j = 0, k = 0;
6553 CHAR msg[1024];
6554 CHAR arg[255];
6555 ULONG macAddr = 0;
6556 UCHAR temp[16], temp2[16];
6557 UINT32 macValue = 0;
6558 INT Status;
6559
6560
6561 memset(msg, 0x00, 1024);
6562 if (wrq->u.data.length > 1) //No parameters.
6563 {
6564 Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6565 sprintf(msg, "\n");
6566
6567 //Parsing Read or Write
6568 this_char = arg;
6569 if (!*this_char)
6570 goto next;
6571
6572 if ((value = rtstrchr(this_char, '=')) != NULL)
6573 *value++ = 0;
6574
6575 if (!value || !*value)
6576 { //Read
6577 // Sanity check
6578 if(strlen(this_char) > 4)
6579 goto next;
6580
6581 j = strlen(this_char);
6582 while(j-- > 0)
6583 {
6584 if(this_char[j] > 'f' || this_char[j] < '0')
6585 return;
6586 }
6587
6588 // Mac Addr
6589 k = j = strlen(this_char);
6590 while(j-- > 0)
6591 {
6592 this_char[4-k+j] = this_char[j];
6593 }
6594
6595 while(k < 4)
6596 this_char[3-k++]='0';
6597 this_char[4]='\0';
6598
6599 if(strlen(this_char) == 4)
6600 {
6601 AtoH(this_char, temp, 2);
6602 macAddr = *temp*256 + temp[1];
6603 if (macAddr < 0xFFFF)
6604 {
6605 RTMP_IO_READ32(pAdapter, macAddr, &macValue);
6606 DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
6607 sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr , macValue);
6608 }
6609 else
6610 {//Invalid parametes, so default printk all bbp
6611 goto next;
6612 }
6613 }
6614 }
6615 else
6616 { //Write
6617 memcpy(&temp2, value, strlen(value));
6618 temp2[strlen(value)] = '\0';
6619
6620 // Sanity check
6621 if((strlen(this_char) > 4) || strlen(temp2) > 8)
6622 goto next;
6623
6624 j = strlen(this_char);
6625 while(j-- > 0)
6626 {
6627 if(this_char[j] > 'f' || this_char[j] < '0')
6628 return;
6629 }
6630
6631 j = strlen(temp2);
6632 while(j-- > 0)
6633 {
6634 if(temp2[j] > 'f' || temp2[j] < '0')
6635 return;
6636 }
6637
6638 //MAC Addr
6639 k = j = strlen(this_char);
6640 while(j-- > 0)
6641 {
6642 this_char[4-k+j] = this_char[j];
6643 }
6644
6645 while(k < 4)
6646 this_char[3-k++]='0';
6647 this_char[4]='\0';
6648
6649 //MAC value
6650 k = j = strlen(temp2);
6651 while(j-- > 0)
6652 {
6653 temp2[8-k+j] = temp2[j];
6654 }
6655
6656 while(k < 8)
6657 temp2[7-k++]='0';
6658 temp2[8]='\0';
6659
6660 {
6661 AtoH(this_char, temp, 2);
6662 macAddr = *temp*256 + temp[1];
6663
6664 AtoH(temp2, temp, 4);
6665 macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
6666
6667 // debug mode
6668 if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
6669 {
6670 // 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
6671 if (macValue & 0x000000ff)
6672 {
6673 pAdapter->BbpTuning.bEnable = TRUE;
6674 DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
6675 }
6676 else
6677 {
6678 UCHAR R66;
6679 pAdapter->BbpTuning.bEnable = FALSE;
6680 R66 = 0x26 + GET_LNA_GAIN(pAdapter);
6681#ifdef RALINK_ATE
6682 if (ATE_ON(pAdapter))
6683 {
6684 ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6685 }
6686 else
6687#endif // RALINK_ATE //
6688 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
6689 DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
6690 }
6691 return;
6692 }
6693
6694 DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
6695
6696 RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
6697 sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr, macValue);
6698 }
6699 }
6700 }
6701next:
6702 if(strlen(msg) == 1)
6703 sprintf(msg+strlen(msg), "===>Error command format!");
6704
6705 // Copy the information into the user buffer
6706 wrq->u.data.length = strlen(msg);
6707 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6708
6709 DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
6710}
6711
6712/*
6713 ==========================================================================
6714 Description:
6715 Read / Write E2PROM
6716 Arguments:
6717 pAdapter Pointer to our adapter
6718 wrq Pointer to the ioctl argument
6719
6720 Return Value:
6721 None
6722
6723 Note:
6724 Usage:
6725 1.) iwpriv ra0 e2p 0 ==> read E2PROM where Addr=0x0
6726 2.) iwpriv ra0 e2p 0=1234 ==> write E2PROM where Addr=0x0, value=1234
6727 ==========================================================================
6728*/
6729VOID RTMPIoctlE2PROM(
6730 IN PRTMP_ADAPTER pAdapter,
6731 IN struct iwreq *wrq)
6732{
6733 CHAR *this_char;
6734 CHAR *value;
6735 INT j = 0, k = 0;
6736 CHAR msg[1024];
6737 CHAR arg[255];
6738 USHORT eepAddr = 0;
6739 UCHAR temp[16], temp2[16];
6740 USHORT eepValue;
6741 int Status;
6742
6743
6744 memset(msg, 0x00, 1024);
6745 if (wrq->u.data.length > 1) //No parameters.
6746 {
6747 Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
6748 sprintf(msg, "\n");
6749
6750 //Parsing Read or Write
6751 this_char = arg;
6752
6753
6754 if (!*this_char)
6755 goto next;
6756
6757 if ((value = rtstrchr(this_char, '=')) != NULL)
6758 *value++ = 0;
6759
6760 if (!value || !*value)
6761 { //Read
6762
6763 // Sanity check
6764 if(strlen(this_char) > 4)
6765 goto next;
6766
6767 j = strlen(this_char);
6768 while(j-- > 0)
6769 {
6770 if(this_char[j] > 'f' || this_char[j] < '0')
6771 return;
6772 }
6773
6774 // E2PROM addr
6775 k = j = strlen(this_char);
6776 while(j-- > 0)
6777 {
6778 this_char[4-k+j] = this_char[j];
6779 }
6780
6781 while(k < 4)
6782 this_char[3-k++]='0';
6783 this_char[4]='\0';
6784
6785 if(strlen(this_char) == 4)
6786 {
6787 AtoH(this_char, temp, 2);
6788 eepAddr = *temp*256 + temp[1];
6789 if (eepAddr < 0xFFFF)
6790 {
6791 RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
6792 sprintf(msg+strlen(msg), "[0x%04X]:0x%04X ", eepAddr , eepValue);
6793 }
6794 else
6795 {//Invalid parametes, so default printk all bbp
6796 goto next;
6797 }
6798 }
6799 }
6800 else
6801 { //Write
6802 memcpy(&temp2, value, strlen(value));
6803 temp2[strlen(value)] = '\0';
6804
6805 // Sanity check
6806 if((strlen(this_char) > 4) || strlen(temp2) > 8)
6807 goto next;
6808
6809 j = strlen(this_char);
6810 while(j-- > 0)
6811 {
6812 if(this_char[j] > 'f' || this_char[j] < '0')
6813 return;
6814 }
6815 j = strlen(temp2);
6816 while(j-- > 0)
6817 {
6818 if(temp2[j] > 'f' || temp2[j] < '0')
6819 return;
6820 }
6821
6822 //MAC Addr
6823 k = j = strlen(this_char);
6824 while(j-- > 0)
6825 {
6826 this_char[4-k+j] = this_char[j];
6827 }
6828
6829 while(k < 4)
6830 this_char[3-k++]='0';
6831 this_char[4]='\0';
6832
6833 //MAC value
6834 k = j = strlen(temp2);
6835 while(j-- > 0)
6836 {
6837 temp2[4-k+j] = temp2[j];
6838 }
6839
6840 while(k < 4)
6841 temp2[3-k++]='0';
6842 temp2[4]='\0';
6843
6844 AtoH(this_char, temp, 2);
6845 eepAddr = *temp*256 + temp[1];
6846
6847 AtoH(temp2, temp, 2);
6848 eepValue = *temp*256 + temp[1];
6849
6850 RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
6851 sprintf(msg+strlen(msg), "[0x%02X]:%02X ", eepAddr, eepValue);
6852 }
6853 }
6854next:
6855 if(strlen(msg) == 1)
6856 sprintf(msg+strlen(msg), "===>Error command format!");
6857
6858
6859 // Copy the information into the user buffer
6860 wrq->u.data.length = strlen(msg);
6861 Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
6862
6863 DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
6864}
6865#endif // DBG //
6866
6867
6868
6869
6870INT Set_TGnWifiTest_Proc(
6871 IN PRTMP_ADAPTER pAd,
6872 IN PUCHAR arg)
6873{
6874 if (simple_strtol(arg, 0, 10) == 0)
6875 pAd->StaCfg.bTGnWifiTest = FALSE;
6876 else
6877 pAd->StaCfg.bTGnWifiTest = TRUE;
6878
6879 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
6880 return TRUE;
6881}
6882
6883INT Set_LongRetryLimit_Proc(
6884 IN PRTMP_ADAPTER pAdapter,
6885 IN PUCHAR arg)
6886{
6887 TX_RTY_CFG_STRUC tx_rty_cfg;
6888 UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6889
6890 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6891 tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
6892 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6893 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6894 return TRUE;
6895}
6896
6897INT Set_ShortRetryLimit_Proc(
6898 IN PRTMP_ADAPTER pAdapter,
6899 IN PUCHAR arg)
6900{
6901 TX_RTY_CFG_STRUC tx_rty_cfg;
6902 UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
6903
6904 RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
6905 tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
6906 RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
6907 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
6908 return TRUE;
6909}
6910
6911#ifdef EXT_BUILD_CHANNEL_LIST
6912INT Set_Ieee80211dClientMode_Proc(
6913 IN PRTMP_ADAPTER pAdapter,
6914 IN PUCHAR arg)
6915{
6916 if (simple_strtol(arg, 0, 10) == 0)
6917 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
6918 else if (simple_strtol(arg, 0, 10) == 1)
6919 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible;
6920 else if (simple_strtol(arg, 0, 10) == 2)
6921 pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict;
6922 else
6923 return FALSE;
6924
6925 DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode));
6926 return TRUE;
6927}
6928#endif // EXT_BUILD_CHANNEL_LIST //
6929
6930#ifdef CARRIER_DETECTION_SUPPORT
6931INT Set_CarrierDetect_Proc(
6932 IN PRTMP_ADAPTER pAd,
6933 IN PUCHAR arg)
6934{
6935 if (simple_strtol(arg, 0, 10) == 0)
6936 pAd->CommonCfg.CarrierDetect.Enable = FALSE;
6937 else
6938 pAd->CommonCfg.CarrierDetect.Enable = TRUE;
6939
6940 DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable));
6941 return TRUE;
6942}
6943#endif // CARRIER_DETECTION_SUPPORT //
6944
diff --git a/drivers/staging/rt2860/wpa.h b/drivers/staging/rt2860/wpa.h
new file mode 100644
index 00000000000..88c7c8bf3fc
--- /dev/null
+++ b/drivers/staging/rt2860/wpa.h
@@ -0,0 +1,356 @@
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 wpa.h
29
30 Abstract:
31
32 Revision History:
33 Who When What
34 -------- ---------- ----------------------------------------------
35 Name Date Modification logs
36*/
37
38#ifndef __WPA_H__
39#define __WPA_H__
40
41// EAPOL Key descripter frame format related length
42#define LEN_KEY_DESC_NONCE 32
43#define LEN_KEY_DESC_IV 16
44#define LEN_KEY_DESC_RSC 8
45#define LEN_KEY_DESC_ID 8
46#define LEN_KEY_DESC_REPLAY 8
47#define LEN_KEY_DESC_MIC 16
48
49// The length is the EAPoL-Key frame except key data field.
50// Please refer to 802.11i-2004 ,Figure 43u in p.78
51#define LEN_EAPOL_KEY_MSG (sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE)
52
53// EAP Code Type.
54#define EAP_CODE_REQUEST 1
55#define EAP_CODE_RESPONSE 2
56#define EAP_CODE_SUCCESS 3
57#define EAP_CODE_FAILURE 4
58
59// EAPOL frame Protocol Version
60#define EAPOL_VER 1
61#define EAPOL_VER2 2
62
63// EAPOL-KEY Descriptor Type
64#define WPA1_KEY_DESC 0xfe
65#define WPA2_KEY_DESC 0x02
66
67// Key Descriptor Version of Key Information
68#define DESC_TYPE_TKIP 1
69#define DESC_TYPE_AES 2
70#define DESC_TYPE_MESH 3
71
72#define LEN_MSG1_2WAY 0x7f
73#define MAX_LEN_OF_EAP_HS 256
74
75#define LEN_MASTER_KEY 32
76
77// EAPOL EK, MK
78#define LEN_EAP_EK 16
79#define LEN_EAP_MICK 16
80#define LEN_EAP_KEY ((LEN_EAP_EK)+(LEN_EAP_MICK))
81// TKIP key related
82#define LEN_PMKID 16
83#define LEN_TKIP_EK 16
84#define LEN_TKIP_RXMICK 8
85#define LEN_TKIP_TXMICK 8
86#define LEN_AES_EK 16
87#define LEN_AES_KEY LEN_AES_EK
88#define LEN_TKIP_KEY ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
89#define TKIP_AP_TXMICK_OFFSET ((LEN_EAP_KEY)+(LEN_TKIP_EK))
90#define TKIP_AP_RXMICK_OFFSET (TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK)
91#define TKIP_GTK_LENGTH ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
92#define LEN_PTK ((LEN_EAP_KEY)+(LEN_TKIP_KEY))
93
94// RSN IE Length definition
95#define MAX_LEN_OF_RSNIE 90
96#define MIN_LEN_OF_RSNIE 8
97
98//EAP Packet Type
99#define EAPPacket 0
100#define EAPOLStart 1
101#define EAPOLLogoff 2
102#define EAPOLKey 3
103#define EAPOLASFAlert 4
104#define EAPTtypeMax 5
105
106#define EAPOL_MSG_INVALID 0
107#define EAPOL_PAIR_MSG_1 1
108#define EAPOL_PAIR_MSG_2 2
109#define EAPOL_PAIR_MSG_3 3
110#define EAPOL_PAIR_MSG_4 4
111#define EAPOL_GROUP_MSG_1 5
112#define EAPOL_GROUP_MSG_2 6
113
114#define PAIRWISEKEY 1
115#define GROUPKEY 0
116
117// Retry timer counter initial value
118#define PEER_MSG1_RETRY_TIMER_CTR 0
119#define PEER_MSG3_RETRY_TIMER_CTR 10
120#define GROUP_MSG1_RETRY_TIMER_CTR 20
121
122
123#define EAPOL_START_DISABLE 0
124#define EAPOL_START_PSK 1
125#define EAPOL_START_1X 2
126
127#define MIX_CIPHER_WPA_TKIP_ON(x) (((x) & 0x08) != 0)
128#define MIX_CIPHER_WPA_AES_ON(x) (((x) & 0x04) != 0)
129#define MIX_CIPHER_WPA2_TKIP_ON(x) (((x) & 0x02) != 0)
130#define MIX_CIPHER_WPA2_AES_ON(x) (((x) & 0x01) != 0)
131
132#define ROUND_UP(__x, __y) \
133 (((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1)))
134
135#define ADD_ONE_To_64BIT_VAR(_V) \
136{ \
137 UCHAR cnt = LEN_KEY_DESC_REPLAY; \
138 do \
139 { \
140 cnt--; \
141 _V[cnt]++; \
142 if (cnt == 0) \
143 break; \
144 }while (_V[cnt] == 0); \
145}
146
147#define IS_WPA_CAPABILITY(a) (((a) >= Ndis802_11AuthModeWPA) && ((a) <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
148
149// EAPOL Key Information definition within Key descriptor format
150typedef struct PACKED _KEY_INFO
151{
152#ifdef RT_BIG_ENDIAN
153 UCHAR KeyAck:1;
154 UCHAR Install:1;
155 UCHAR KeyIndex:2;
156 UCHAR KeyType:1;
157 UCHAR KeyDescVer:3;
158 UCHAR Rsvd:3;
159 UCHAR EKD_DL:1; // EKD for AP; DL for STA
160 UCHAR Request:1;
161 UCHAR Error:1;
162 UCHAR Secure:1;
163 UCHAR KeyMic:1;
164#else
165 UCHAR KeyMic:1;
166 UCHAR Secure:1;
167 UCHAR Error:1;
168 UCHAR Request:1;
169 UCHAR EKD_DL:1; // EKD for AP; DL for STA
170 UCHAR Rsvd:3;
171 UCHAR KeyDescVer:3;
172 UCHAR KeyType:1;
173 UCHAR KeyIndex:2;
174 UCHAR Install:1;
175 UCHAR KeyAck:1;
176#endif
177} KEY_INFO, *PKEY_INFO;
178
179// EAPOL Key descriptor format
180typedef struct PACKED _KEY_DESCRIPTER
181{
182 UCHAR Type;
183 KEY_INFO KeyInfo;
184 UCHAR KeyLength[2];
185 UCHAR ReplayCounter[LEN_KEY_DESC_REPLAY];
186 UCHAR KeyNonce[LEN_KEY_DESC_NONCE];
187 UCHAR KeyIv[LEN_KEY_DESC_IV];
188 UCHAR KeyRsc[LEN_KEY_DESC_RSC];
189 UCHAR KeyId[LEN_KEY_DESC_ID];
190 UCHAR KeyMic[LEN_KEY_DESC_MIC];
191 UCHAR KeyDataLen[2];
192 UCHAR KeyData[MAX_LEN_OF_RSNIE];
193} KEY_DESCRIPTER, *PKEY_DESCRIPTER;
194
195typedef struct PACKED _EAPOL_PACKET
196{
197 UCHAR ProVer;
198 UCHAR ProType;
199 UCHAR Body_Len[2];
200 KEY_DESCRIPTER KeyDesc;
201} EAPOL_PACKET, *PEAPOL_PACKET;
202
203//802.11i D10 page 83
204typedef struct PACKED _GTK_ENCAP
205{
206#ifndef RT_BIG_ENDIAN
207 UCHAR Kid:2;
208 UCHAR tx:1;
209 UCHAR rsv:5;
210 UCHAR rsv1;
211#else
212 UCHAR rsv:5;
213 UCHAR tx:1;
214 UCHAR Kid:2;
215 UCHAR rsv1;
216#endif
217 UCHAR GTK[TKIP_GTK_LENGTH];
218} GTK_ENCAP, *PGTK_ENCAP;
219
220typedef struct PACKED _KDE_ENCAP
221{
222 UCHAR Type;
223 UCHAR Len;
224 UCHAR OUI[3];
225 UCHAR DataType;
226 GTK_ENCAP GTKEncap;
227} KDE_ENCAP, *PKDE_ENCAP;
228
229// For WPA1
230typedef struct PACKED _RSNIE {
231 UCHAR oui[4];
232 USHORT version;
233 UCHAR mcast[4];
234 USHORT ucount;
235 struct PACKED {
236 UCHAR oui[4];
237 }ucast[1];
238} RSNIE, *PRSNIE;
239
240// For WPA2
241typedef struct PACKED _RSNIE2 {
242 USHORT version;
243 UCHAR mcast[4];
244 USHORT ucount;
245 struct PACKED {
246 UCHAR oui[4];
247 }ucast[1];
248} RSNIE2, *PRSNIE2;
249
250// AKM Suite
251typedef struct PACKED _RSNIE_AUTH {
252 USHORT acount;
253 struct PACKED {
254 UCHAR oui[4];
255 }auth[1];
256} RSNIE_AUTH,*PRSNIE_AUTH;
257
258typedef union PACKED _RSN_CAPABILITIES {
259 struct PACKED {
260#ifdef RT_BIG_ENDIAN
261 USHORT Rsvd:10;
262 USHORT GTKSA_R_Counter:2;
263 USHORT PTKSA_R_Counter:2;
264 USHORT No_Pairwise:1;
265 USHORT PreAuth:1;
266#else
267 USHORT PreAuth:1;
268 USHORT No_Pairwise:1;
269 USHORT PTKSA_R_Counter:2;
270 USHORT GTKSA_R_Counter:2;
271 USHORT Rsvd:10;
272#endif
273 } field;
274 USHORT word;
275} RSN_CAPABILITIES, *PRSN_CAPABILITIES;
276
277typedef struct PACKED _EAP_HDR {
278 UCHAR ProVer;
279 UCHAR ProType;
280 UCHAR Body_Len[2];
281 UCHAR code;
282 UCHAR identifier;
283 UCHAR length[2]; // including code and identifier, followed by length-2 octets of data
284} EAP_HDR, *PEAP_HDR;
285
286// For supplicant state machine states. 802.11i Draft 4.1, p. 97
287// We simplified it
288typedef enum _WpaState
289{
290 SS_NOTUSE, // 0
291 SS_START, // 1
292 SS_WAIT_MSG_3, // 2
293 SS_WAIT_GROUP, // 3
294 SS_FINISH, // 4
295 SS_KEYUPDATE, // 5
296} WPA_STATE;
297
298//
299// The definition of the cipher combination
300//
301// bit3 bit2 bit1 bit0
302// +------------+------------+
303// | WPA | WPA2 |
304// +------+-----+------+-----+
305// | TKIP | AES | TKIP | AES |
306// | 0 | 1 | 1 | 0 | -> 0x06
307// | 0 | 1 | 1 | 1 | -> 0x07
308// | 1 | 0 | 0 | 1 | -> 0x09
309// | 1 | 0 | 1 | 1 | -> 0x0B
310// | 1 | 1 | 0 | 1 | -> 0x0D
311// | 1 | 1 | 1 | 0 | -> 0x0E
312// | 1 | 1 | 1 | 1 | -> 0x0F
313// +------+-----+------+-----+
314//
315typedef enum _WpaMixPairCipher
316{
317 MIX_CIPHER_NOTUSE = 0x00,
318 WPA_NONE_WPA2_TKIPAES = 0x03, // WPA2-TKIPAES
319 WPA_AES_WPA2_TKIP = 0x06,
320 WPA_AES_WPA2_TKIPAES = 0x07,
321 WPA_TKIP_WPA2_AES = 0x09,
322 WPA_TKIP_WPA2_TKIPAES = 0x0B,
323 WPA_TKIPAES_WPA2_NONE = 0x0C, // WPA-TKIPAES
324 WPA_TKIPAES_WPA2_AES = 0x0D,
325 WPA_TKIPAES_WPA2_TKIP = 0x0E,
326 WPA_TKIPAES_WPA2_TKIPAES = 0x0F,
327} WPA_MIX_PAIR_CIPHER;
328
329typedef struct PACKED _RSN_IE_HEADER_STRUCT {
330 UCHAR Eid;
331 UCHAR Length;
332 USHORT Version; // Little endian format
333} RSN_IE_HEADER_STRUCT, *PRSN_IE_HEADER_STRUCT;
334
335// Cipher suite selector types
336typedef struct PACKED _CIPHER_SUITE_STRUCT {
337 UCHAR Oui[3];
338 UCHAR Type;
339} CIPHER_SUITE_STRUCT, *PCIPHER_SUITE_STRUCT;
340
341// Authentication and Key Management suite selector
342typedef struct PACKED _AKM_SUITE_STRUCT {
343 UCHAR Oui[3];
344 UCHAR Type;
345} AKM_SUITE_STRUCT, *PAKM_SUITE_STRUCT;
346
347// RSN capability
348typedef struct PACKED _RSN_CAPABILITY {
349 USHORT Rsv:10;
350 USHORT GTKSAReplayCnt:2;
351 USHORT PTKSAReplayCnt:2;
352 USHORT NoPairwise:1;
353 USHORT PreAuth:1;
354} RSN_CAPABILITY, *PRSN_CAPABILITY;
355
356#endif