--- drivers/staging/rt2860/2860_main_dev.c | 1319 --- drivers/staging/rt2860/Makefile | 26 drivers/staging/rt2860/aironet.h | 210 drivers/staging/rt2860/ap.h | 12 drivers/staging/rt2860/chip/mac_pci.h | 365 drivers/staging/rt2860/chip/mac_usb.h | 365 drivers/staging/rt2860/chip/rt2860.h | 56 drivers/staging/rt2860/chip/rt2870.h | 47 drivers/staging/rt2860/chip/rt3070.h | 68 drivers/staging/rt2860/chip/rt30xx.h | 48 drivers/staging/rt2860/chip/rtmp_mac.h | 1334 +++ drivers/staging/rt2860/chip/rtmp_phy.h | 405 + drivers/staging/rt2860/chips/rt3070.c | 185 drivers/staging/rt2860/chips/rt30xx.c | 525 + drivers/staging/rt2860/chlist.h | 1215 --- drivers/staging/rt2860/common/2860_rtmp_init.c | 897 -- drivers/staging/rt2860/common/action.c | 22 drivers/staging/rt2860/common/ba_action.c | 150 drivers/staging/rt2860/common/cmm_aes.c | 1554 ++++ drivers/staging/rt2860/common/cmm_asic.c | 2531 ++++++ drivers/staging/rt2860/common/cmm_cfg.c | 290 drivers/staging/rt2860/common/cmm_data.c | 890 -- drivers/staging/rt2860/common/cmm_data_2860.c | 1197 --- drivers/staging/rt2860/common/cmm_data_pci.c | 1163 +++ drivers/staging/rt2860/common/cmm_data_usb.c | 968 ++ drivers/staging/rt2860/common/cmm_info.c | 822 +- drivers/staging/rt2860/common/cmm_mac_pci.c | 1504 +++ drivers/staging/rt2860/common/cmm_mac_usb.c | 1216 +++ drivers/staging/rt2860/common/cmm_profile.c | 1793 ++++ drivers/staging/rt2860/common/cmm_sanity.c | 275 drivers/staging/rt2860/common/cmm_sync.c | 70 drivers/staging/rt2860/common/cmm_tkip.c | 951 ++ drivers/staging/rt2860/common/cmm_wep.c | 499 + drivers/staging/rt2860/common/cmm_wpa.c | 3332 +++++++- drivers/staging/rt2860/common/crypt_hmac.c | 279 drivers/staging/rt2860/common/crypt_md5.c | 352 drivers/staging/rt2860/common/crypt_sha2.c | 535 + drivers/staging/rt2860/common/dfs.c | 66 drivers/staging/rt2860/common/ee_efuse.c | 1525 ++++ drivers/staging/rt2860/common/ee_prom.c | 270 drivers/staging/rt2860/common/eeprom.c | 1462 --- drivers/staging/rt2860/common/firmware.h | 2 drivers/staging/rt2860/common/firmware_3070.h | 517 + drivers/staging/rt2860/common/md5.c | 1415 --- drivers/staging/rt2860/common/mlme.c | 9508 ++++++++----------------- drivers/staging/rt2860/common/rt_channel.c | 1280 +++ drivers/staging/rt2860/common/rt_rf.c | 194 drivers/staging/rt2860/common/rtmp_init.c | 1999 ++--- drivers/staging/rt2860/common/rtmp_mcu.c | 233 drivers/staging/rt2860/common/rtmp_timer.c | 323 drivers/staging/rt2860/common/rtmp_tkip.c | 1586 ---- drivers/staging/rt2860/common/rtmp_wep.c | 497 - drivers/staging/rt2860/common/spectrum.c | 460 + drivers/staging/rt2860/config.mk | 241 drivers/staging/rt2860/crypt_hmac.h | 82 drivers/staging/rt2860/crypt_md5.h | 80 drivers/staging/rt2860/crypt_sha2.h | 109 drivers/staging/rt2860/dfs.h | 32 drivers/staging/rt2860/eeprom.h | 93 drivers/staging/rt2860/iface/rtmp_pci.h | 83 drivers/staging/rt2860/iface/rtmp_usb.h | 200 drivers/staging/rt2860/md5.h | 107 drivers/staging/rt2860/mlme.h | 110 drivers/staging/rt2860/oid.h | 123 drivers/staging/rt2860/pci_main_dev.c | 873 ++ drivers/staging/rt2860/rt2860.h | 333 drivers/staging/rt2860/rt28xx.h | 1688 ---- drivers/staging/rt2860/rt_config.h | 37 drivers/staging/rt2860/rt_linux.c | 622 + drivers/staging/rt2860/rt_linux.h | 968 +- drivers/staging/rt2860/rt_main_dev.c | 751 - drivers/staging/rt2860/rt_pci_rbus.c | 889 ++ drivers/staging/rt2860/rt_profile.c | 1839 ---- drivers/staging/rt2860/rt_usb.c | 828 ++ drivers/staging/rt2860/rtmp.h | 2897 +++---- drivers/staging/rt2860/rtmp_chip.h | 265 drivers/staging/rt2860/rtmp_ckipmic.h | 35 drivers/staging/rt2860/rtmp_def.h | 298 drivers/staging/rt2860/rtmp_dot11.h | 102 drivers/staging/rt2860/rtmp_iface.h | 84 drivers/staging/rt2860/rtmp_mcu.h | 55 drivers/staging/rt2860/rtmp_os.h | 98 drivers/staging/rt2860/rtmp_timer.h | 156 drivers/staging/rt2860/rtmp_type.h | 55 drivers/staging/rt2860/rtusb_io.h | 189 drivers/staging/rt2860/spectrum.h | 169 drivers/staging/rt2860/spectrum_def.h | 148 drivers/staging/rt2860/sta/aironet.c | 1312 --- drivers/staging/rt2860/sta/assoc.c | 327 drivers/staging/rt2860/sta/auth.c | 138 drivers/staging/rt2860/sta/auth_rsp.c | 16 drivers/staging/rt2860/sta/connect.c | 637 - drivers/staging/rt2860/sta/dls.c | 2192 +++++ drivers/staging/rt2860/sta/rtmp_ckipmic.c | 577 + drivers/staging/rt2860/sta/rtmp_data.c | 257 drivers/staging/rt2860/sta/sanity.c | 44 drivers/staging/rt2860/sta/sync.c | 398 - drivers/staging/rt2860/sta/wpa.c | 1994 ----- drivers/staging/rt2860/sta_ioctl.c | 761 +- drivers/staging/rt2860/usb_main_dev.c | 897 ++ drivers/staging/rt2860/wpa.h | 104 drivers/staging/rt2870/2870_main_dev.c | 1530 ---- drivers/staging/rt2870/Makefile | 32 drivers/staging/rt2870/chips/rt3070.c | 1 drivers/staging/rt2870/chips/rt30xx.c | 1 drivers/staging/rt2870/common/2870_rtmp_init.c | 1730 ---- drivers/staging/rt2870/common/acction.c | 1 drivers/staging/rt2870/common/cmm_aes.c | 1 drivers/staging/rt2870/common/cmm_asic.c | 1 drivers/staging/rt2870/common/cmm_cfg.c | 1 drivers/staging/rt2870/common/cmm_data_2870.c | 936 -- drivers/staging/rt2870/common/cmm_data_usb.c | 1 drivers/staging/rt2870/common/cmm_mac_usb.c | 1 drivers/staging/rt2870/common/cmm_profile.c | 1 drivers/staging/rt2870/common/cmm_tkip.c | 1 drivers/staging/rt2870/common/cmm_wep.c | 1 drivers/staging/rt2870/common/crypt_hmac.c | 1 drivers/staging/rt2870/common/crypt_md5.c | 1 drivers/staging/rt2870/common/crypt_sha2.c | 1 drivers/staging/rt2870/common/ee_efuse.c | 1 drivers/staging/rt2870/common/rt_channel.c | 1 drivers/staging/rt2870/common/rt_rf.c | 1 drivers/staging/rt2870/common/rtmp_mcu.c | 1 drivers/staging/rt2870/common/rtmp_timer.c | 1 drivers/staging/rt2870/common/rtusb_bulk.c | 140 drivers/staging/rt2870/common/rtusb_data.c | 55 drivers/staging/rt2870/common/rtusb_io.c | 475 - drivers/staging/rt2870/rt2870.h | 583 - drivers/staging/rt2870/rt_usb.c | 1 drivers/staging/rt2870/usb_main_dev.c | 1 drivers/staging/rt3070/firmware.h | 2 131 files changed, 42982 insertions(+), 35622 deletions(-) Index: b/drivers/staging/rt2860/2860_main_dev.c =================================================================== --- a/drivers/staging/rt2860/2860_main_dev.c +++ /dev/null @@ -1,1319 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - - Module Name: - 2870_main_dev.c - - Abstract: - Create and register network interface. - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- -*/ - -#include "rt_config.h" - -extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p, - IN UINT argc, OUT PRTMP_ADAPTER *ppAd); - -static void rx_done_tasklet(unsigned long data); -static void mgmt_dma_done_tasklet(unsigned long data); -static void ac0_dma_done_tasklet(unsigned long data); -static void ac1_dma_done_tasklet(unsigned long data); -static void ac2_dma_done_tasklet(unsigned long data); -static void ac3_dma_done_tasklet(unsigned long data); -static void hcca_dma_done_tasklet(unsigned long data); -static void fifo_statistic_full_tasklet(unsigned long data); - - -/*---------------------------------------------------------------------*/ -/* Symbol & Macro Definitions */ -/*---------------------------------------------------------------------*/ -#define RT2860_INT_RX_DLY (1<<0) // bit 0 -#define RT2860_INT_TX_DLY (1<<1) // bit 1 -#define RT2860_INT_RX_DONE (1<<2) // bit 2 -#define RT2860_INT_AC0_DMA_DONE (1<<3) // bit 3 -#define RT2860_INT_AC1_DMA_DONE (1<<4) // bit 4 -#define RT2860_INT_AC2_DMA_DONE (1<<5) // bit 5 -#define RT2860_INT_AC3_DMA_DONE (1<<6) // bit 6 -#define RT2860_INT_HCCA_DMA_DONE (1<<7) // bit 7 -#define RT2860_INT_MGMT_DONE (1<<8) // bit 8 - -#define INT_RX RT2860_INT_RX_DONE - -#define INT_AC0_DLY (RT2860_INT_AC0_DMA_DONE) //| RT2860_INT_TX_DLY) -#define INT_AC1_DLY (RT2860_INT_AC1_DMA_DONE) //| RT2860_INT_TX_DLY) -#define INT_AC2_DLY (RT2860_INT_AC2_DMA_DONE) //| RT2860_INT_TX_DLY) -#define INT_AC3_DLY (RT2860_INT_AC3_DMA_DONE) //| RT2860_INT_TX_DLY) -#define INT_HCCA_DLY (RT2860_INT_HCCA_DMA_DONE) //| RT2860_INT_TX_DLY) -#define INT_MGMT_DLY RT2860_INT_MGMT_DONE - -/*---------------------------------------------------------------------*/ -/* Prototypes of Functions Used */ -/*---------------------------------------------------------------------*/ -/* function declarations */ -static INT __devinit rt2860_init_one (struct pci_dev *pci_dev, const struct pci_device_id *ent); -static VOID __devexit rt2860_remove_one(struct pci_dev *pci_dev); -static INT __devinit rt2860_probe(struct pci_dev *pci_dev, const struct pci_device_id *ent); -void init_thread_task(PRTMP_ADAPTER pAd); -static void __exit rt2860_cleanup_module(void); -static int __init rt2860_init_module(void); - -#ifdef CONFIG_PM -static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state); -static int rt2860_resume(struct pci_dev *pci_dev); -#endif // CONFIG_PM // - - -// -// Ralink PCI device table, include all supported chipsets -// -static struct pci_device_id rt2860_pci_tbl[] __devinitdata = -{ - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCI_DEVICE_ID)}, //RT28602.4G - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCIe_DEVICE_ID)}, - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2760_PCI_DEVICE_ID)}, - {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2790_PCIe_DEVICE_ID)}, - {PCI_DEVICE(VEN_AWT_PCI_VENDOR_ID, VEN_AWT_PCIe_DEVICE_ID)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7708)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7728)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7758)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7727)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7738)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7748)}, - {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7768)}, - {0,} // terminate list -}; - -MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl); -MODULE_LICENSE("GPL"); -#ifdef MODULE_VERSION -MODULE_VERSION(STA_DRIVER_VERSION); -#endif - -// -// Our PCI driver structure -// -static struct pci_driver rt2860_driver = -{ - name: "rt2860", - id_table: rt2860_pci_tbl, - probe: rt2860_init_one, - remove: __devexit_p(rt2860_remove_one), - -#ifdef CONFIG_PM - suspend: rt2860_suspend, - resume: rt2860_resume, -#endif -}; - - -#ifdef CONFIG_PM - -VOID RT2860RejectPendingPackets( - IN PRTMP_ADAPTER pAd) -{ - // clear PS packets - // clear TxSw packets -} - -static int rt2860_suspend( - struct pci_dev *pci_dev, - pm_message_t state) -{ - struct net_device *net_dev = pci_get_drvdata(pci_dev); - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; - INT32 retval; - - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n")); - - if (net_dev == NULL) - { - DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n")); - } - else - { - pAd = net_dev->ml_priv; - - /* we can not use IFF_UP because ra0 down but ra1 up */ - /* and 1 suspend/resume function for 1 module, not for each interface */ - /* so Linux will call suspend/resume function once */ - if (VIRTUAL_IF_NUM(pAd) > 0) - { - // avoid users do suspend after interface is down - - // stop interface - netif_carrier_off(net_dev); - netif_stop_queue(net_dev); - - // mark device as removed from system and therefore no longer available - netif_device_detach(net_dev); - - // mark halt flag - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - // take down the device - rt28xx_close((PNET_DEV)net_dev); - - RT_MOD_DEC_USE_COUNT(); - } - } - - // reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html - // enable device to generate PME# when suspended - // pci_choose_state(): Choose the power state of a PCI device to be suspended - retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1); - // save the PCI configuration space of a device before suspending - pci_save_state(pci_dev); - // disable PCI device after use - pci_disable_device(pci_dev); - - retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); - - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n")); - return retval; -} - -static int rt2860_resume( - struct pci_dev *pci_dev) -{ - struct net_device *net_dev = pci_get_drvdata(pci_dev); - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; - INT32 retval; - - - // set the power state of a PCI device - // PCI has 4 power states, DO (normal) ~ D3(less power) - // in include/linux/pci.h, you can find that - // #define PCI_D0 ((pci_power_t __force) 0) - // #define PCI_D1 ((pci_power_t __force) 1) - // #define PCI_D2 ((pci_power_t __force) 2) - // #define PCI_D3hot ((pci_power_t __force) 3) - // #define PCI_D3cold ((pci_power_t __force) 4) - // #define PCI_UNKNOWN ((pci_power_t __force) 5) - // #define PCI_POWER_ERROR ((pci_power_t __force) -1) - retval = pci_set_power_state(pci_dev, PCI_D0); - - // restore the saved state of a PCI device - pci_restore_state(pci_dev); - - // initialize device before it's used by a driver - if (pci_enable_device(pci_dev)) - { - printk("pci enable fail!\n"); - return 0; - } - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n")); - - if (net_dev == NULL) - { - DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n")); - } - else - pAd = net_dev->ml_priv; - - if (pAd != NULL) - { - /* we can not use IFF_UP because ra0 down but ra1 up */ - /* and 1 suspend/resume function for 1 module, not for each interface */ - /* so Linux will call suspend/resume function once */ - if (VIRTUAL_IF_NUM(pAd) > 0) - { - // mark device as attached from system and restart if needed - netif_device_attach(net_dev); - - if (rt28xx_open((PNET_DEV)net_dev) != 0) - { - // open fail - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n")); - return 0; - } - - // increase MODULE use count - RT_MOD_INC_USE_COUNT(); - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - netif_start_queue(net_dev); - netif_carrier_on(net_dev); - netif_wake_queue(net_dev); - } - } - - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n")); - return 0; -} -#endif // CONFIG_PM // - - -static INT __init rt2860_init_module(VOID) -{ - return pci_register_driver(&rt2860_driver); -} - - -// -// Driver module unload function -// -static VOID __exit rt2860_cleanup_module(VOID) -{ - pci_unregister_driver(&rt2860_driver); -} - -module_init(rt2860_init_module); -module_exit(rt2860_cleanup_module); - - -static INT __devinit rt2860_init_one ( - IN struct pci_dev *pci_dev, - IN const struct pci_device_id *ent) -{ - INT rc; - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_init_one\n")); - - // wake up and enable device - if (pci_enable_device (pci_dev)) - { - rc = -EIO; - } - else - { - rc = rt2860_probe(pci_dev, ent); - } - - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_init_one\n")); - return rc; -} - - -static VOID __devexit rt2860_remove_one( - IN struct pci_dev *pci_dev) -{ - struct net_device *net_dev = pci_get_drvdata(pci_dev); - RTMP_ADAPTER *pAd = net_dev->ml_priv; - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n")); - - if (pAd != NULL) - { - // Unregister network device - unregister_netdev(net_dev); - - // Unmap CSR base address - iounmap((char *)(net_dev->base_addr)); - - RTMPFreeAdapter(pAd); - - // release memory region - release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); - } - else - { - // Unregister network device - unregister_netdev(net_dev); - - // Unmap CSR base address - iounmap((char *)(net_dev->base_addr)); - - // release memory region - release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); - } - - // Free pre-allocated net_device memory - free_netdev(net_dev); -} - -// -// PCI device probe & initialization function -// -static INT __devinit rt2860_probe( - IN struct pci_dev *pci_dev, - IN const struct pci_device_id *ent) -{ - PRTMP_ADAPTER pAd; - INT rv = 0; - - rv = (INT)rt28xx_probe((void *)pci_dev, (void *)ent, 0, &pAd); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE); - return rv; -} - - -void init_thread_task(IN PRTMP_ADAPTER pAd) -{ - POS_COOKIE pObj; - - pObj = (POS_COOKIE) pAd->OS_Cookie; - - tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->hcca_dma_done_task, hcca_dma_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->fifo_statistic_full_task, fifo_statistic_full_tasklet, (unsigned long)pAd); -} - -void kill_thread_task(IN PRTMP_ADAPTER pAd) -{ - POS_COOKIE pObj; - - pObj = (POS_COOKIE) pAd->OS_Cookie; - - tasklet_kill(&pObj->rx_done_task); - tasklet_kill(&pObj->mgmt_dma_done_task); - tasklet_kill(&pObj->ac0_dma_done_task); - tasklet_kill(&pObj->ac1_dma_done_task); - tasklet_kill(&pObj->ac2_dma_done_task); - tasklet_kill(&pObj->ac3_dma_done_task); - tasklet_kill(&pObj->hcca_dma_done_task); - tasklet_kill(&pObj->tbtt_task); - tasklet_kill(&pObj->fifo_statistic_full_task); -} - - -static void rt2860_int_enable(PRTMP_ADAPTER pAd, unsigned int mode) -{ - u32 regValue; - - pAd->int_disable_mask &= ~(mode); - regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask); - RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); // 1:enable - - if (regValue != 0) - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE); -} - - -static void rt2860_int_disable(PRTMP_ADAPTER pAd, unsigned int mode) -{ - u32 regValue; - - pAd->int_disable_mask |= mode; - regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask); - RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); // 0: disable - - if (regValue == 0) - { - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE); - } -} - -static void mgmt_dma_done_tasklet(unsigned long data) -{ - unsigned long flags; - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; - INT_SOURCE_CSR_STRUC IntSource; - POS_COOKIE pObj; - - // Do nothing if the driver is starting halt state. - // This might happen when timer already been fired before cancel timer with mlmehalt - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (POS_COOKIE) pAd->OS_Cookie; - - IntSource.word = 0; - IntSource.field.MgmtDmaDone = 1; - pAd->int_pending &= ~INT_MGMT_DLY; - - RTMPHandleMgmtRingDmaDoneInterrupt(pAd); - - // if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any - // bug report output - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid lose of interrupts - */ - if (pAd->int_pending & INT_MGMT_DLY) - { - tasklet_hi_schedule(&pObj->mgmt_dma_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable TxDataInt again */ - rt2860_int_enable(pAd, INT_MGMT_DLY); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -} - -static void rx_done_tasklet(unsigned long data) -{ - unsigned long flags; - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; - BOOLEAN bReschedule = 0; - POS_COOKIE pObj; - - // Do nothing if the driver is starting halt state. - // This might happen when timer already been fired before cancel timer with mlmehalt - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (POS_COOKIE) pAd->OS_Cookie; - - pAd->int_pending &= ~(INT_RX); - - bReschedule = STARxDoneInterruptHandle(pAd, 0); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid rotting packet - */ - if (pAd->int_pending & INT_RX || bReschedule) - { - tasklet_hi_schedule(&pObj->rx_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable RxINT again */ - rt2860_int_enable(pAd, INT_RX); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - -} - -void fifo_statistic_full_tasklet(unsigned long data) -{ - unsigned long flags; - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; - POS_COOKIE pObj; - - // Do nothing if the driver is starting halt state. - // This might happen when timer already been fired before cancel timer with mlmehalt - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (POS_COOKIE) pAd->OS_Cookie; - - pAd->int_pending &= ~(FifoStaFullInt); - NICUpdateFifoStaCounters(pAd); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid rotting packet - */ - if (pAd->int_pending & FifoStaFullInt) - { - tasklet_hi_schedule(&pObj->fifo_statistic_full_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable RxINT again */ - - rt2860_int_enable(pAd, FifoStaFullInt); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - -} - -static void hcca_dma_done_tasklet(unsigned long data) -{ - unsigned long flags; - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; - INT_SOURCE_CSR_STRUC IntSource; - POS_COOKIE pObj; - - // Do nothing if the driver is starting halt state. - // This might happen when timer already been fired before cancel timer with mlmehalt - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (POS_COOKIE) pAd->OS_Cookie; - - - IntSource.word = 0; - IntSource.field.HccaDmaDone = 1; - pAd->int_pending &= ~INT_HCCA_DLY; - - RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid lose of interrupts - */ - if (pAd->int_pending & INT_HCCA_DLY) - { - tasklet_hi_schedule(&pObj->hcca_dma_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable TxDataInt again */ - rt2860_int_enable(pAd, INT_HCCA_DLY); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -} - -static void ac3_dma_done_tasklet(unsigned long data) -{ - unsigned long flags; - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; - INT_SOURCE_CSR_STRUC IntSource; - POS_COOKIE pObj; - BOOLEAN bReschedule = 0; - - // Do nothing if the driver is starting halt state. - // This might happen when timer already been fired before cancel timer with mlmehalt - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (POS_COOKIE) pAd->OS_Cookie; - - IntSource.word = 0; - IntSource.field.Ac3DmaDone = 1; - pAd->int_pending &= ~INT_AC3_DLY; - - bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid lose of interrupts - */ - if ((pAd->int_pending & INT_AC3_DLY) || bReschedule) - { - tasklet_hi_schedule(&pObj->ac3_dma_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable TxDataInt again */ - rt2860_int_enable(pAd, INT_AC3_DLY); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -} - -static void ac2_dma_done_tasklet(unsigned long data) -{ - unsigned long flags; - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; - INT_SOURCE_CSR_STRUC IntSource; - POS_COOKIE pObj; - BOOLEAN bReschedule = 0; - - // Do nothing if the driver is starting halt state. - // This might happen when timer already been fired before cancel timer with mlmehalt - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (POS_COOKIE) pAd->OS_Cookie; - - IntSource.word = 0; - IntSource.field.Ac2DmaDone = 1; - pAd->int_pending &= ~INT_AC2_DLY; - - bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - - /* - * double check to avoid lose of interrupts - */ - if ((pAd->int_pending & INT_AC2_DLY) || bReschedule) - { - tasklet_hi_schedule(&pObj->ac2_dma_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable TxDataInt again */ - rt2860_int_enable(pAd, INT_AC2_DLY); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -} - -static void ac1_dma_done_tasklet(unsigned long data) -{ - unsigned long flags; - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; - INT_SOURCE_CSR_STRUC IntSource; - POS_COOKIE pObj; - BOOLEAN bReschedule = 0; - - // Do nothing if the driver is starting halt state. - // This might happen when timer already been fired before cancel timer with mlmehalt - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (POS_COOKIE) pAd->OS_Cookie; - - IntSource.word = 0; - IntSource.field.Ac1DmaDone = 1; - pAd->int_pending &= ~INT_AC1_DLY; - - bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid lose of interrupts - */ - if ((pAd->int_pending & INT_AC1_DLY) || bReschedule) - { - tasklet_hi_schedule(&pObj->ac1_dma_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable TxDataInt again */ - rt2860_int_enable(pAd, INT_AC1_DLY); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -} - -static void ac0_dma_done_tasklet(unsigned long data) -{ - unsigned long flags; - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; - INT_SOURCE_CSR_STRUC IntSource; - POS_COOKIE pObj; - BOOLEAN bReschedule = 0; - - // Do nothing if the driver is starting halt state. - // This might happen when timer already been fired before cancel timer with mlmehalt - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return; - - pObj = (POS_COOKIE) pAd->OS_Cookie; - - IntSource.word = 0; - IntSource.field.Ac0DmaDone = 1; - pAd->int_pending &= ~INT_AC0_DLY; - - bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); - - RTMP_INT_LOCK(&pAd->irq_lock, flags); - /* - * double check to avoid lose of interrupts - */ - if ((pAd->int_pending & INT_AC0_DLY) || bReschedule) - { - tasklet_hi_schedule(&pObj->ac0_dma_done_task); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); - return; - } - - /* enable TxDataInt again */ - rt2860_int_enable(pAd, INT_AC0_DLY); - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -} - - -int print_int_count; - -IRQ_HANDLE_TYPE -rt2860_interrupt(int irq, void *dev_instance) -{ - struct net_device *net_dev = (struct net_device *) dev_instance; - PRTMP_ADAPTER pAd = net_dev->ml_priv; - INT_SOURCE_CSR_STRUC IntSource; - POS_COOKIE pObj; - BOOLEAN bOldValue; - - pObj = (POS_COOKIE) pAd->OS_Cookie; - - - /* Note 03312008: we can not return here before - RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word); - RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); - Or kernel will panic after ifconfig ra0 down sometimes */ - - - // - // Inital the Interrupt source. - // - IntSource.word = 0x00000000L; -// McuIntSource.word = 0x00000000L; - - // - // Get the interrupt sources & saved to local variable - // - //RTMP_IO_READ32(pAd, where, &McuIntSource.word); - //RTMP_IO_WRITE32(pAd, , McuIntSource.word); - - // - // Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp - // And at the same time, clock maybe turned off that say there is no DMA service. - // when ASIC get to sleep. - // To prevent system hang on power saving. - // We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up. - // - // RT2661 => when ASIC is sleeping, MAC register cannot be read and written. - // RT2860 => when ASIC is sleeping, MAC register can be read and written. - - bOldValue = pAd->bPCIclkOff; - pAd->bPCIclkOff = FALSE; - { - RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word); - RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear - } - pAd->bPCIclkOff = bOldValue; - - // Do nothing if Reset in progress - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || - RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) - { - return IRQ_HANDLED; - } - - // - // Handle interrupt, walk through all bits - // Should start from highest priority interrupt - // The priority can be adjust by altering processing if statement - // - - // If required spinlock, each interrupt service routine has to acquire - // and release itself. - // - - // Do nothing if NIC doesn't exist - if (IntSource.word == 0xffffffff) - { - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS); - printk("snowpin - IntSource.word == 0xffffffff\n"); - return IRQ_HANDLED; - } - - if (IntSource.word & TxCoherent) - { - DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n")); - RTMPHandleRxCoherentInterrupt(pAd); - } - - if (IntSource.word & RxCoherent) - { - DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n")); - RTMPHandleRxCoherentInterrupt(pAd); - } - - if (IntSource.word & FifoStaFullInt) - { -#if 1 - if ((pAd->int_disable_mask & FifoStaFullInt) == 0) - { - /* mask FifoStaFullInt */ - rt2860_int_disable(pAd, FifoStaFullInt); - tasklet_hi_schedule(&pObj->fifo_statistic_full_task); - } - pAd->int_pending |= FifoStaFullInt; -#else - NICUpdateFifoStaCounters(pAd); -#endif - } - - if (IntSource.word & INT_MGMT_DLY) - { - if ((pAd->int_disable_mask & INT_MGMT_DLY) ==0 ) - { - rt2860_int_disable(pAd, INT_MGMT_DLY); - tasklet_hi_schedule(&pObj->mgmt_dma_done_task); - } - pAd->int_pending |= INT_MGMT_DLY ; - } - - if (IntSource.word & INT_RX) - { - if ((pAd->int_disable_mask & INT_RX) == 0) - { - /* mask RxINT */ - rt2860_int_disable(pAd, INT_RX); - tasklet_hi_schedule(&pObj->rx_done_task); - } - pAd->int_pending |= INT_RX; - } - - if (IntSource.word & INT_HCCA_DLY) - { - - if ((pAd->int_disable_mask & INT_HCCA_DLY) == 0) - { - /* mask TxDataInt */ - rt2860_int_disable(pAd, INT_HCCA_DLY); - tasklet_hi_schedule(&pObj->hcca_dma_done_task); - } - pAd->int_pending |= INT_HCCA_DLY; - } - - if (IntSource.word & INT_AC3_DLY) - { - - if ((pAd->int_disable_mask & INT_AC3_DLY) == 0) - { - /* mask TxDataInt */ - rt2860_int_disable(pAd, INT_AC3_DLY); - tasklet_hi_schedule(&pObj->ac3_dma_done_task); - } - pAd->int_pending |= INT_AC3_DLY; - } - - if (IntSource.word & INT_AC2_DLY) - { - - if ((pAd->int_disable_mask & INT_AC2_DLY) == 0) - { - /* mask TxDataInt */ - rt2860_int_disable(pAd, INT_AC2_DLY); - tasklet_hi_schedule(&pObj->ac2_dma_done_task); - } - pAd->int_pending |= INT_AC2_DLY; - } - - if (IntSource.word & INT_AC1_DLY) - { - - pAd->int_pending |= INT_AC1_DLY; - - if ((pAd->int_disable_mask & INT_AC1_DLY) == 0) - { - /* mask TxDataInt */ - rt2860_int_disable(pAd, INT_AC1_DLY); - tasklet_hi_schedule(&pObj->ac1_dma_done_task); - } - - } - - if (IntSource.word & INT_AC0_DLY) - { - pAd->int_pending |= INT_AC0_DLY; - - if ((pAd->int_disable_mask & INT_AC0_DLY) == 0) - { - /* mask TxDataInt */ - rt2860_int_disable(pAd, INT_AC0_DLY); - tasklet_hi_schedule(&pObj->ac0_dma_done_task); - } - - } - - if (IntSource.word & PreTBTTInt) - { - RTMPHandlePreTBTTInterrupt(pAd); - } - - if (IntSource.word & TBTTInt) - { - RTMPHandleTBTTInterrupt(pAd); - } - - if (IntSource.word & AutoWakeupInt) - RTMPHandleTwakeupInterrupt(pAd); - - return IRQ_HANDLED; -} - -/* -======================================================================== -Routine Description: - Check the chipset vendor/product ID. - -Arguments: - _dev_p Point to the PCI or USB device - -Return Value: - TRUE Check ok - FALSE Check fail - -Note: -======================================================================== -*/ -BOOLEAN RT28XXChipsetCheck( - IN void *_dev_p) -{ - /* always TRUE */ - return TRUE; -} - - -/* -======================================================================== -Routine Description: - Init net device structure. - -Arguments: - _dev_p Point to the PCI or USB device - *net_dev Point to the net device - *pAd the raxx interface data pointer - -Return Value: - TRUE Init ok - FALSE Init fail - -Note: -======================================================================== -*/ -BOOLEAN RT28XXNetDevInit( - IN void *_dev_p, - IN struct net_device *net_dev, - IN RTMP_ADAPTER *pAd) -{ - struct pci_dev *pci_dev = (struct pci_dev *)_dev_p; - const CHAR *print_name; - ULONG csr_addr; - - - print_name = pci_dev ? pci_name(pci_dev) : "rt2860"; - - net_dev->base_addr = 0; - net_dev->irq = 0; - - if (pci_request_regions(pci_dev, print_name)) - goto err_out_free_netdev; - - // interrupt IRQ number - net_dev->irq = pci_dev->irq; - - // map physical address to virtual address for accessing register - csr_addr = (unsigned long) ioremap(pci_resource_start(pci_dev, 0), - pci_resource_len(pci_dev, 0)); - - if (!csr_addr) - { - DBGPRINT(RT_DEBUG_ERROR, - ("ioremap failed for device %s, region 0x%lX @ 0x%lX\n", - print_name, (ULONG)pci_resource_len(pci_dev, 0), - (ULONG)pci_resource_start(pci_dev, 0))); - goto err_out_free_res; - } - - // Save CSR virtual address and irq to device structure - net_dev->base_addr = csr_addr; - pAd->CSRBaseAddress = (PUCHAR)net_dev->base_addr; - - // Set DMA master - pci_set_master(pci_dev); - - net_dev->priv_flags = INT_MAIN; - - DBGPRINT(RT_DEBUG_TRACE, ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n", - net_dev->name, (ULONG)pci_resource_start(pci_dev, 0), - (ULONG)csr_addr, pci_dev->irq)); - return TRUE; - - - /* --------------------------- ERROR HANDLE --------------------------- */ -err_out_free_res: - pci_release_regions(pci_dev); -err_out_free_netdev: - /* free netdev in caller, not here */ - return FALSE; -} - - -/* -======================================================================== -Routine Description: - Init net device structure. - -Arguments: - _dev_p Point to the PCI or USB device - *pAd the raxx interface data pointer - -Return Value: - TRUE Config ok - FALSE Config fail - -Note: -======================================================================== -*/ -BOOLEAN RT28XXProbePostConfig( - IN void *_dev_p, - IN RTMP_ADAPTER *pAd, - IN INT32 argc) -{ - /* no use */ - return TRUE; -} - - -/* -======================================================================== -Routine Description: - Disable DMA. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -VOID RT28XXDMADisable( - IN RTMP_ADAPTER *pAd) -{ - WPDMA_GLO_CFG_STRUC GloCfg; - - - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - GloCfg.word &= 0xff0; - GloCfg.field.EnTXWriteBackDDONE =1; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); -} - - -/* -======================================================================== -Routine Description: - Enable DMA. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -VOID RT28XXDMAEnable( - IN RTMP_ADAPTER *pAd) -{ - WPDMA_GLO_CFG_STRUC GloCfg; - int i = 0; - - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4); - do - { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) - break; - - DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n")); - RTMPusecDelay(1000); - i++; - }while ( i <200); - - RTMPusecDelay(50); - - GloCfg.field.EnTXWriteBackDDONE = 1; - GloCfg.field.WPDMABurstSIZE = 2; - GloCfg.field.EnableRxDMA = 1; - GloCfg.field.EnableTxDMA = 1; - - DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word)); - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); - -} - -/* -======================================================================== -Routine Description: - Write Beacon buffer to Asic. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -VOID RT28xx_UpdateBeaconToAsic( - IN RTMP_ADAPTER *pAd, - IN INT apidx, - IN ULONG FrameLen, - IN ULONG UpdatePos) -{ - ULONG CapInfoPos = 0; - UCHAR *ptr, *ptr_update, *ptr_capinfo; - UINT i; - BOOLEAN bBcnReq = FALSE; - UCHAR bcn_idx = 0; - - { - DBGPRINT(RT_DEBUG_ERROR, ("%s() : No valid Interface be found.\n", __func__)); - return; - } - - if (bBcnReq == FALSE) - { - /* when the ra interface is down, do not send its beacon frame */ - /* clear all zero */ - for(i=0; iBeaconOffset[bcn_idx] + i, 0x00); - } - else - { - ptr = (PUCHAR)&pAd->BeaconTxWI; - - for (i=0; iBeaconOffset[bcn_idx] + i, longptr); - ptr += 4; - } - - // Update CapabilityInfo in Beacon - for (i = CapInfoPos; i < (CapInfoPos+2); i++) - { - RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_capinfo); - ptr_capinfo ++; - } - - if (FrameLen > UpdatePos) - { - for (i= UpdatePos; i< (FrameLen); i++) - { - RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_update); - ptr_update ++; - } - } - - } - -} - -VOID RTMPInitPCIeLinkCtrlValue( - IN PRTMP_ADAPTER pAd) -{ -} - -VOID RTMPFindHostPCIDev( - IN PRTMP_ADAPTER pAd) -{ -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - Level = RESTORE_HALT : Restore PCI host and Ralink PCIe Link Control field to its default value. - Level = Other Value : Restore from dot11 power save or radio off status. And force PCI host Link Control fields to 0x1 - - ======================================================================== -*/ -VOID RTMPPCIeLinkCtrlValueRestore( - IN PRTMP_ADAPTER pAd, - IN UCHAR Level) -{ -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - Max : limit Host PCI and Ralink PCIe device's LINK CONTROL field's value. - Because now frequently set our device to mode 1 or mode 3 will cause problem. - - ======================================================================== -*/ -VOID RTMPPCIeLinkCtrlSetting( - IN PRTMP_ADAPTER pAd, - IN USHORT Max) -{ -} - -VOID rt2860_stop(struct net_device *net_dev) -{ - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; - if (net_dev == NULL) - { - DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n")); - } - else - pAd = net_dev->ml_priv; - - if (pAd != NULL) - { - // stop interface - netif_carrier_off(net_dev); - netif_stop_queue(net_dev); - - // mark device as removed from system and therefore no longer available - netif_device_detach(net_dev); - - // mark halt flag - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - // take down the device - rt28xx_close((PNET_DEV)net_dev); - RT_MOD_DEC_USE_COUNT(); - } - return; -} - -/* - * invaild or writeback cache - * and convert virtual address to physical address - */ -dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction) -{ - PRTMP_ADAPTER pAd; - POS_COOKIE pObj; - - /* - ------ Porting Information ------ - > For Tx Alloc: - mgmt packets => sd_idx = 0 - SwIdx: pAd->MgmtRing.TxCpuIdx - pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa; - - data packets => sd_idx = 1 - TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx - QueIdx: pTxBlk->QueIdx - pTxD : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa; - - > For Rx Alloc: - sd_idx = -1 - */ - - pAd = (PRTMP_ADAPTER)handle; - pObj = (POS_COOKIE)pAd->OS_Cookie; - - if (sd_idx == 1) - { - PTX_BLK pTxBlk; - pTxBlk = (PTX_BLK)ptr; - return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, direction); - } - else - { - return pci_map_single(pObj->pci_dev, ptr, size, direction); - } - -} - -void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction) -{ - PRTMP_ADAPTER pAd; - POS_COOKIE pObj; - - pAd=(PRTMP_ADAPTER)handle; - pObj = (POS_COOKIE)pAd->OS_Cookie; - - pci_unmap_single(pObj->pci_dev, dma_addr, size, direction); - -} - Index: b/drivers/staging/rt2860/Makefile =================================================================== --- a/drivers/staging/rt2860/Makefile +++ b/drivers/staging/rt2860/Makefile @@ -2,26 +2,33 @@ obj-$(CONFIG_RT2860) += rt2860sta.o # TODO: all of these should be removed EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT -EXTRA_CFLAGS += -DRT2860 +EXTRA_CFLAGS += -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRT2860 EXTRA_CFLAGS += -DDBG rt2860sta-objs := \ - common/md5.o \ + common/crypt_md5.o \ + common/crypt_sha2.o \ + common/crypt_hmac.o \ common/mlme.o \ - common/rtmp_wep.o \ + common/cmm_wep.o \ common/action.o \ common/cmm_data.o \ common/rtmp_init.o \ - common/rtmp_tkip.o \ + common/cmm_tkip.o \ + common/cmm_aes.o \ common/cmm_sync.o \ common/eeprom.o \ common/cmm_sanity.o \ common/cmm_info.o \ + common/cmm_cfg.o \ common/cmm_wpa.o \ common/dfs.o \ common/spectrum.o \ + common/rtmp_timer.o \ + common/rt_channel.o \ + common/cmm_profile.o \ + common/cmm_asic.o \ sta/assoc.o \ - sta/aironet.o \ sta/auth.o \ sta/auth_rsp.o \ sta/sync.o \ @@ -34,6 +41,9 @@ rt2860sta-objs := \ rt_main_dev.o \ sta_ioctl.o \ common/ba_action.o \ - common/2860_rtmp_init.o \ - 2860_main_dev.o \ - common/cmm_data_2860.o + pci_main_dev.o \ + rt_pci_rbus.o \ + common/cmm_mac_pci.o \ + common/cmm_data_pci.o \ + common/ee_prom.o \ + common/rtmp_mcu.o Index: b/drivers/staging/rt2860/aironet.h =================================================================== --- a/drivers/staging/rt2860/aironet.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - - Module Name: - aironet.h - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs - Paul Lin 04-06-15 Initial -*/ - -#ifndef __AIRONET_H__ -#define __AIRONET_H__ - -// Measurement Type definition -#define MSRN_TYPE_UNUSED 0 -#define MSRN_TYPE_CHANNEL_LOAD_REQ 1 -#define MSRN_TYPE_NOISE_HIST_REQ 2 -#define MSRN_TYPE_BEACON_REQ 3 -#define MSRN_TYPE_FRAME_REQ 4 - -// Scan Mode in Beacon Request -#define MSRN_SCAN_MODE_PASSIVE 0 -#define MSRN_SCAN_MODE_ACTIVE 1 -#define MSRN_SCAN_MODE_BEACON_TABLE 2 - -// PHY type definition for Aironet beacon report, CCX 2 table 36-9 -#define PHY_FH 1 -#define PHY_DSS 2 -#define PHY_UNUSED 3 -#define PHY_OFDM 4 -#define PHY_HR_DSS 5 -#define PHY_ERP 6 - -// RPI table in dBm -#define RPI_0 0 // Power <= -87 -#define RPI_1 1 // -87 < Power <= -82 -#define RPI_2 2 // -82 < Power <= -77 -#define RPI_3 3 // -77 < Power <= -72 -#define RPI_4 4 // -72 < Power <= -67 -#define RPI_5 5 // -67 < Power <= -62 -#define RPI_6 6 // -62 < Power <= -57 -#define RPI_7 7 // -57 < Power - -// Cisco Aironet IAPP definetions -#define AIRONET_IAPP_TYPE 0x32 -#define AIRONET_IAPP_SUBTYPE_REQUEST 0x01 -#define AIRONET_IAPP_SUBTYPE_REPORT 0x81 - -// Measurement Request detail format -typedef struct _MEASUREMENT_REQUEST { - UCHAR Channel; - UCHAR ScanMode; // Use only in beacon request, other requests did not use this field - USHORT Duration; -} MEASUREMENT_REQUEST, *PMEASUREMENT_REQUEST; - -// Beacon Measurement Report -// All these field might change to UCHAR, because we didn't do anything to these report. -// We copy all these beacons and report to CCX 2 AP. -typedef struct _BEACON_REPORT { - UCHAR Channel; - UCHAR Spare; - USHORT Duration; - UCHAR PhyType; // Definiation is listed above table 36-9 - UCHAR RxPower; - UCHAR BSSID[6]; - UCHAR ParentTSF[4]; - UCHAR TargetTSF[8]; - USHORT BeaconInterval; - USHORT CapabilityInfo; -} BEACON_REPORT, *PBEACON_REPORT; - -// Frame Measurement Report (Optional) -typedef struct _FRAME_REPORT { - UCHAR Channel; - UCHAR Spare; - USHORT Duration; - UCHAR TA; - UCHAR BSSID[6]; - UCHAR RSSI; - UCHAR Count; -} FRAME_REPORT, *PFRAME_REPORT; - -#pragma pack(1) -// Channel Load Report -typedef struct _CHANNEL_LOAD_REPORT { - UCHAR Channel; - UCHAR Spare; - USHORT Duration; - UCHAR CCABusy; -} CHANNEL_LOAD_REPORT, *PCHANNEL_LOAD_REPORT; -#pragma pack() - -// Nosie Histogram Report -typedef struct _NOISE_HIST_REPORT { - UCHAR Channel; - UCHAR Spare; - USHORT Duration; - UCHAR Density[8]; -} NOISE_HIST_REPORT, *PNOISE_HIST_REPORT; - -// Radio Management Capability element -typedef struct _RADIO_MANAGEMENT_CAPABILITY { - UCHAR Eid; // TODO: Why the Eid is 1 byte, not normal 2 bytes??? - UCHAR Length; - UCHAR AironetOui[3]; // AIronet OUI (00 40 96) - UCHAR Type; // Type / Version - USHORT Status; // swap16 required -} RADIO_MANAGEMENT_CAPABILITY, *PRADIO_MANAGEMENT_CAPABILITY; - -// Measurement Mode Bit definition -typedef struct _MEASUREMENT_MODE { - UCHAR Rsvd:4; - UCHAR Report:1; - UCHAR NotUsed:1; - UCHAR Enable:1; - UCHAR Parallel:1; -} MEASUREMENT_MODE, *PMEASUREMENT_MODE; - -// Measurement Request element, This is little endian mode -typedef struct _MEASUREMENT_REQUEST_ELEMENT { - USHORT Eid; - USHORT Length; // swap16 required - USHORT Token; // non-zero unique token - UCHAR Mode; // Measurement Mode - UCHAR Type; // Measurement type -} MEASUREMENT_REQUEST_ELEMENT, *PMEASUREMENT_REQUEST_ELEMENT; - -// Measurement Report element, This is little endian mode -typedef struct _MEASUREMENT_REPORT_ELEMENT { - USHORT Eid; - USHORT Length; // swap16 required - USHORT Token; // non-zero unique token - UCHAR Mode; // Measurement Mode - UCHAR Type; // Measurement type -} MEASUREMENT_REPORT_ELEMENT, *PMEASUREMENT_REPORT_ELEMENT; - -// Cisco Aironet IAPP Frame Header, Network byte order used -typedef struct _AIRONET_IAPP_HEADER { - UCHAR CiscoSnapHeader[8]; // 8 bytes Cisco snap header - USHORT Length; // IAPP ID & length, remember to swap16 in LE system - UCHAR Type; // IAPP type - UCHAR SubType; // IAPP subtype - UCHAR DA[6]; // Destination MAC address - UCHAR SA[6]; // Source MAC address - USHORT Token; // Dialog token, no need to swap16 since it is for yoken usage only -} AIRONET_IAPP_HEADER, *PAIRONET_IAPP_HEADER; - -// Radio Measurement Request frame -typedef struct _AIRONET_RM_REQUEST_FRAME { - AIRONET_IAPP_HEADER IAPP; // Common header - UCHAR Delay; // Activation Delay - UCHAR Offset; // Measurement offset -} AIRONET_RM_REQUEST_FRAME, *PAIRONET_RM_REQUEST_FRAME; - -// Radio Measurement Report frame -typedef struct _AIRONET_RM_REPORT_FRAME { - AIRONET_IAPP_HEADER IAPP; // Common header -} AIRONET_RM_REPORT_FRAME, *PAIRONET_RM_REPORT_FRAME; - -// Saved element request actions which will saved in StaCfg. -typedef struct _RM_REQUEST_ACTION { - MEASUREMENT_REQUEST_ELEMENT ReqElem; // Saved request element - MEASUREMENT_REQUEST Measurement; // Saved measurement within the request element -} RM_REQUEST_ACTION, *PRM_REQUEST_ACTION; - -// CCX administration control -typedef union _CCX_CONTROL { - struct { - UINT32 Enable:1; // Enable CCX2 - UINT32 LeapEnable:1; // Enable LEAP at CCX2 - UINT32 RMEnable:1; // Radio Measurement Enable - UINT32 DCRMEnable:1; // Non serving channel Radio Measurement enable - UINT32 QOSEnable:1; // Enable QOS for CCX 2.0 support - UINT32 FastRoamEnable:1; // Enable fast roaming - UINT32 Rsvd:2; // Not used - UINT32 dBmToRoam:8; // the condition to roam when receiving Rssi less than this value. It's negative value. - UINT32 TuLimit:16; // Limit for different channel scan - } field; - UINT32 word; -} CCX_CONTROL, *PCCX_CONTROL; - -#endif // __AIRONET_H__ Index: b/drivers/staging/rt2860/ap.h =================================================================== --- a/drivers/staging/rt2860/ap.h +++ b/drivers/staging/rt2860/ap.h @@ -40,22 +40,24 @@ #ifndef __AP_H__ #define __AP_H__ -// ap_mlme.c +// ap_wpa.c +VOID WpaStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *Sm, + OUT STATE_MACHINE_FUNC Trans[]); -#ifdef RT2870 +#ifdef RTMP_MAC_USB VOID BeaconUpdateExec( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3); -#endif // RT2870 // +#endif // RTMP_MAC_USB // VOID RTMPSetPiggyBack( IN PRTMP_ADAPTER pAd, IN BOOLEAN bPiggyBack); -// ap.c - VOID MacTableReset( IN PRTMP_ADAPTER pAd); Index: b/drivers/staging/rt2860/chip/mac_pci.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/chip/mac_pci.h @@ -0,0 +1,365 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + mac_pci.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __MAC_PCI_H__ +#define __MAC_PCI_H__ + +#include "../rtmp_type.h" +#include "rtmp_mac.h" +#include "rtmp_phy.h" +#include "../rtmp_iface.h" +#include "../rtmp_dot11.h" + + +// +// Device ID & Vendor ID related definitions, +// NOTE: you should not add the new VendorID/DeviceID here unless you not sure it belongs to what chip. +// +#define NIC_PCI_VENDOR_ID 0x1814 +#define PCIBUS_INTEL_VENDOR 0x8086 + +#if !defined(PCI_CAP_ID_EXP) +#define PCI_CAP_ID_EXP 0x10 +#endif +#if !defined(PCI_EXP_LNKCTL) +#define PCI_EXP_LNKCTL 0x10 +#endif +#if !defined(PCI_CLASS_BRIDGE_PCI) +#define PCI_CLASS_BRIDGE_PCI 0x0604 +#endif + + + + + +#define TXINFO_SIZE 0 +#define RTMP_PKT_TAIL_PADDING 0 +#define fRTMP_ADAPTER_NEED_STOP_TX 0 + +#define AUX_CTRL 0x10c + +// +// TX descriptor format, Tx ring, Mgmt Ring +// +typedef struct PACKED _TXD_STRUC { + // Word 0 + UINT32 SDPtr0; + // Word 1 + UINT32 SDLen1:14; + UINT32 LastSec1:1; + UINT32 Burst:1; + UINT32 SDLen0:14; + UINT32 LastSec0:1; + UINT32 DMADONE:1; + //Word2 + UINT32 SDPtr1; + //Word3 + UINT32 rsv2:24; + UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition + UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA + UINT32 rsv:2; + UINT32 TCO:1; // + UINT32 UCO:1; // + UINT32 ICO:1; // +} TXD_STRUC, *PTXD_STRUC; + + +// +// Rx descriptor format, Rx Ring +// +typedef struct PACKED _RXD_STRUC{ + // Word 0 + UINT32 SDP0; + // Word 1 + UINT32 SDL1:14; + UINT32 Rsv:2; + UINT32 SDL0:14; + UINT32 LS0:1; + UINT32 DDONE:1; + // Word 2 + UINT32 SDP1; + // Word 3 + UINT32 BA:1; + UINT32 DATA:1; + UINT32 NULLDATA:1; + UINT32 FRAG:1; + UINT32 U2M:1; // 1: this RX frame is unicast to me + UINT32 Mcast:1; // 1: this is a multicast frame + UINT32 Bcast:1; // 1: this is a broadcast frame + UINT32 MyBss:1; // 1: this frame belongs to the same BSSID + UINT32 Crc:1; // 1: CRC error + UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid + UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header. + UINT32 HTC:1; + UINT32 RSSI:1; + UINT32 L2PAD:1; + UINT32 AMPDU:1; + UINT32 Decrypted:1; // this frame is being decrypted. + UINT32 PlcpSignal:1; // To be moved + UINT32 PlcpRssil:1;// To be moved + UINT32 Rsv1:13; +} RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC; + + +/* ----------------- EEPROM Related MACRO ----------------- */ + +// 8051 firmware image for RT2860 - base address = 0x4000 +#define FIRMWARE_IMAGE_BASE 0x2000 +#define MAX_FIRMWARE_IMAGE_SIZE 0x2000 // 8kbyte + + +/* ----------------- Frimware Related MACRO ----------------- */ +#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \ + do{ \ + ULONG _i, _firm; \ + RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000); \ + \ + for(_i=0; _i<_FwLen; _i+=4) \ + { \ + _firm = _pFwImage[_i] + \ + (_pFwImage[_i+3] << 24) + \ + (_pFwImage[_i+2] << 16) + \ + (_pFwImage[_i+1] << 8); \ + RTMP_IO_WRITE32(_pAd, FIRMWARE_IMAGE_BASE + _i, _firm); \ + } \ + RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00000); \ + RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00001); \ + \ + /* initialize BBP R/W access agent */ \ + RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, 0); \ + RTMP_IO_WRITE32(_pAd, H2M_MAILBOX_CSR, 0); \ + }while(0) + + +/* ----------------- TX Related MACRO ----------------- */ +#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags) do{}while(0) +#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags) do{}while(0) + + +#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \ + ((freeNum) >= (ULONG)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3)) /* rough estimate we will use 3 more descriptor. */ +#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx) \ + do{}while(0) + +#define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \ + (((freeNum != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum<3)) + //(((freeNum) != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 1 /*0*/)) + + +#define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen) \ + RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen) + +#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ + /* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)*/ + +#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \ + RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) + +#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \ + RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) + +#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \ + RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber) + +#define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx) \ + RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx) + +#define HAL_LastTxIdx(_pAd, _QueIdx,_LastTxIdx) \ + /*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx)*/ + +#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx) \ + RTMP_IO_WRITE32((_pAd), TX_CTX_IDX0+((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx) +/* RtmpPCIDataKickOut(_pAd, _pTxBlk, _QueIdx)*/ + +#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \ + MiniportMMRequest(_pAd, _QueIdx, _pNullFrame, _frameLen) + +#define GET_TXRING_FREENO(_pAd, _QueIdx) \ + (_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[_QueIdx].TxCpuIdx) ? \ + (_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \ + : \ + (_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1); + + +#define GET_MGMTRING_FREENO(_pAd) \ + (_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx) ? \ + (_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \ + : \ + (_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1); + + +/* ----------------- RX Related MACRO ----------------- */ + + +/* ----------------- ASIC Related MACRO ----------------- */ +// reset MAC of a station entry to 0x000000000000 +#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid) \ + AsicDelWcidTab(pAd, Wcid); + +// add this entry into ASIC RX WCID search table +#define RTMP_STA_ENTRY_ADD(pAd, pEntry) \ + AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr); + +// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet +// Set MAC register value according operation mode +#define RTMP_UPDATE_PROTECT(pAd) \ + AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0); +// end johnli + +// remove Pair-wise key material from ASIC +#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid) \ + AsicRemovePairwiseKeyEntry(pAd, BssIdx, (UCHAR)Wcid); + +// add Client security information into ASIC WCID table and IVEIV table +#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry) \ + RTMPAddWcidAttributeEntry(pAd, apidx, KeyID, \ + pAd->SharedKey[apidx][KeyID].CipherAlg, pEntry); + +#define RTMP_SECURITY_KEY_ADD(pAd, apidx, KeyID, pEntry) \ + { /* update pairwise key information to ASIC Shared Key Table */ \ + AsicAddSharedKeyEntry(pAd, apidx, KeyID, \ + pAd->SharedKey[apidx][KeyID].CipherAlg, \ + pAd->SharedKey[apidx][KeyID].Key, \ + pAd->SharedKey[apidx][KeyID].TxMic, \ + pAd->SharedKey[apidx][KeyID].RxMic); \ + /* update ASIC WCID attribute table and IVEIV table */ \ + RTMPAddWcidAttributeEntry(pAd, apidx, KeyID, \ + pAd->SharedKey[apidx][KeyID].CipherAlg, \ + pEntry); } + + +// Insert the BA bitmap to ASIC for the Wcid entry +#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \ + do{ \ + UINT32 _Value = 0, _Offset; \ + _Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4; \ + RTMP_IO_READ32((_pAd), _Offset, &_Value);\ + _Value |= (0x10000<<(_TID)); \ + RTMP_IO_WRITE32((_pAd), _Offset, _Value);\ + }while(0) + + +// Remove the BA bitmap from ASIC for the Wcid entry +// bitmap field starts at 0x10000 in ASIC WCID table +#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \ + do{ \ + UINT32 _Value = 0, _Offset; \ + _Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4; \ + RTMP_IO_READ32((_pAd), _Offset, &_Value); \ + _Value &= (~(0x10000 << (_TID))); \ + RTMP_IO_WRITE32((_pAd), _Offset, _Value); \ + }while(0) + + +/* ----------------- Interface Related MACRO ----------------- */ + +// +// Enable & Disable NIC interrupt via writing interrupt mask register +// Since it use ADAPTER structure, it have to be put after structure definition. +// +#define RTMP_ASIC_INTERRUPT_DISABLE(_pAd) \ + do{ \ + RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, 0x0); /* 0: disable */ \ + RTMP_CLEAR_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE); \ + }while(0) + +#define RTMP_ASIC_INTERRUPT_ENABLE(_pAd)\ + do{ \ + RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, (_pAd)->int_enable_reg /*DELAYINTMASK*/); /* 1:enable */ \ + RTMP_SET_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE); \ + }while(0) + + +#define RTMP_IRQ_INIT(pAd) \ + { pAd->int_enable_reg = ((DELAYINTMASK) | \ + (RxINT|TxDataInt|TxMgmtInt)) & ~(0x03); \ + pAd->int_disable_mask = 0; \ + pAd->int_pending = 0; } + +#define RTMP_IRQ_ENABLE(pAd) \ + { /* clear garbage ints */ \ + RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);\ + RTMP_ASIC_INTERRUPT_ENABLE(pAd); } + + +/* ----------------- MLME Related MACRO ----------------- */ +#define RTMP_MLME_HANDLER(pAd) MlmeHandler(pAd) + +#define RTMP_MLME_PRE_SANITY_CHECK(pAd) + +#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \ + RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); + +#define RTMP_MLME_RESET_STATE_MACHINE(pAd) \ + MlmeRestartStateMachine(pAd) + +#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)\ + HandleCounterMeasure(_pAd, _pEntry) + +/* ----------------- Power Save Related MACRO ----------------- */ +#define RTMP_PS_POLL_ENQUEUE(pAd) EnqueuePsPoll(pAd) + + +// For RTMPPCIePowerLinkCtrlRestore () function +#define RESTORE_HALT 1 +#define RESTORE_WAKEUP 2 +#define RESTORE_CLOSE 3 + +#define PowerSafeCID 1 +#define PowerRadioOffCID 2 +#define PowerWakeCID 3 +#define CID0MASK 0x000000ff +#define CID1MASK 0x0000ff00 +#define CID2MASK 0x00ff0000 +#define CID3MASK 0xff000000 + + +#define RTMP_STA_FORCE_WAKEUP(pAd, bFromTx) \ + RT28xxPciStaAsicForceWakeup(pAd, bFromTx); + +#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \ + RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp); + +#define RTMP_SET_PSM_BIT(_pAd, _val) \ + MlmeSetPsmBit(_pAd, _val); + +#define RTMP_MLME_RADIO_ON(pAd) \ + RT28xxPciMlmeRadioOn(pAd); + +#define RTMP_MLME_RADIO_OFF(pAd) \ + RT28xxPciMlmeRadioOFF(pAd); + +#endif //__MAC_PCI_H__ // Index: b/drivers/staging/rt2860/chip/mac_usb.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/chip/mac_usb.h @@ -0,0 +1,365 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + mac_usb.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __MAC_USB_H__ +#define __MAC_USB_H__ + +#include "../rtmp_type.h" +#include "rtmp_mac.h" +#include "rtmp_phy.h" +#include "../rtmp_iface.h" +#include "../rtmp_dot11.h" + + +#define USB_CYC_CFG 0x02a4 + +#define BEACON_RING_SIZE 2 +#define MGMTPIPEIDX 0 // EP6 is highest priority + +#define RTMP_PKT_TAIL_PADDING 11 // 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding) + +#define fRTMP_ADAPTER_NEED_STOP_TX \ + (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \ + fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \ + fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS) + +// +// RXINFO appends at the end of each rx packet. +// +#define RXINFO_SIZE 4 +#define RT2870_RXDMALEN_FIELD_SIZE 4 + +typedef struct PACKED _RXINFO_STRUC { + UINT32 BA:1; + UINT32 DATA:1; + UINT32 NULLDATA:1; + UINT32 FRAG:1; + UINT32 U2M:1; // 1: this RX frame is unicast to me + UINT32 Mcast:1; // 1: this is a multicast frame + UINT32 Bcast:1; // 1: this is a broadcast frame + UINT32 MyBss:1; // 1: this frame belongs to the same BSSID + UINT32 Crc:1; // 1: CRC error + UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid + UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header. + UINT32 HTC:1; + UINT32 RSSI:1; + UINT32 L2PAD:1; + UINT32 AMPDU:1; // To be moved + UINT32 Decrypted:1; + UINT32 PlcpRssil:1; + UINT32 CipherAlg:1; + UINT32 LastAMSDU:1; + UINT32 PlcpSignal:12; +} RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC; + + +// +// TXINFO +// +#define TXINFO_SIZE 4 + +typedef struct _TXINFO_STRUC { + // Word 0 + UINT32 USBDMATxPktLen:16; //used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame. + UINT32 rsv:8; + UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition + UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA + UINT32 SwUseLastRound:1; // Software use. + UINT32 rsv2:2; // Software use. + UINT32 USBDMANextVLD:1; //used ONLY in USB bulk Aggregation, NextValid + UINT32 USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint +} TXINFO_STRUC, *PTXINFO_STRUC; + + +// +// Management ring buffer format +// +typedef struct _MGMT_STRUC { + BOOLEAN Valid; + PUCHAR pBuffer; + ULONG Length; +} MGMT_STRUC, *PMGMT_STRUC; + + +//////////////////////////////////////////////////////////////////////////// +// The TX_BUFFER structure forms the transmitted USB packet to the device +//////////////////////////////////////////////////////////////////////////// +typedef struct __TX_BUFFER{ + union{ + UCHAR WirelessPacket[TX_BUFFER_NORMSIZE]; + HEADER_802_11 NullFrame; + PSPOLL_FRAME PsPollPacket; + RTS_FRAME RTSFrame; + }field; + UCHAR Aggregation[4]; //Buffer for save Aggregation size. +} TX_BUFFER, *PTX_BUFFER; + +typedef struct __HTTX_BUFFER{ + union{ + UCHAR WirelessPacket[MAX_TXBULK_SIZE]; + HEADER_802_11 NullFrame; + PSPOLL_FRAME PsPollPacket; + RTS_FRAME RTSFrame; + }field; + UCHAR Aggregation[4]; //Buffer for save Aggregation size. +} HTTX_BUFFER, *PHTTX_BUFFER; + + +// used to track driver-generated write irps +typedef struct _TX_CONTEXT +{ + PVOID pAd; //Initialized in MiniportInitialize + PURB pUrb; //Initialized in MiniportInitialize + PIRP pIrp; //used to cancel pending bulk out. + //Initialized in MiniportInitialize + PTX_BUFFER TransferBuffer; //Initialized in MiniportInitialize + ULONG BulkOutSize; + UCHAR BulkOutPipeId; + UCHAR SelfIdx; + BOOLEAN InUse; + BOOLEAN bWaitingBulkOut; // at least one packet is in this TxContext, ready for making IRP anytime. + BOOLEAN bFullForBulkOut; // all tx buffer are full , so waiting for tx bulkout. + BOOLEAN IRPPending; + BOOLEAN LastOne; + BOOLEAN bAggregatible; + UCHAR Header_802_3[LENGTH_802_3]; + UCHAR Rsv[2]; + ULONG DataOffset; + UINT TxRate; + dma_addr_t data_dma; // urb dma on linux + +} TX_CONTEXT, *PTX_CONTEXT, **PPTX_CONTEXT; + + +// used to track driver-generated write irps +typedef struct _HT_TX_CONTEXT +{ + PVOID pAd; //Initialized in MiniportInitialize + PURB pUrb; //Initialized in MiniportInitialize + PIRP pIrp; //used to cancel pending bulk out. + //Initialized in MiniportInitialize + PHTTX_BUFFER TransferBuffer; //Initialized in MiniportInitialize + ULONG BulkOutSize; // Indicate the total bulk-out size in bytes in one bulk-transmission + UCHAR BulkOutPipeId; + BOOLEAN IRPPending; + BOOLEAN LastOne; + BOOLEAN bCurWriting; + BOOLEAN bRingEmpty; + BOOLEAN bCopySavePad; + UCHAR SavedPad[8]; + UCHAR Header_802_3[LENGTH_802_3]; + ULONG CurWritePosition; // Indicate the buffer offset which packet will be inserted start from. + ULONG CurWriteRealPos; // Indicate the buffer offset which packet now are writing to. + ULONG NextBulkOutPosition; // Indicate the buffer start offset of a bulk-transmission + ULONG ENextBulkOutPosition; // Indicate the buffer end offset of a bulk-transmission + UINT TxRate; + dma_addr_t data_dma; // urb dma on linux +} HT_TX_CONTEXT, *PHT_TX_CONTEXT, **PPHT_TX_CONTEXT; + + +// +// Structure to keep track of receive packets and buffers to indicate +// receive data to the protocol. +// +typedef struct _RX_CONTEXT +{ + PUCHAR TransferBuffer; + PVOID pAd; + PIRP pIrp;//used to cancel pending bulk in. + PURB pUrb; + //These 2 Boolean shouldn't both be 1 at the same time. + ULONG BulkInOffset; // number of packets waiting for reordering . +// BOOLEAN ReorderInUse; // At least one packet in this buffer are in reordering buffer and wait for receive indication + BOOLEAN bRxHandling; // Notify this packet is being process now. + BOOLEAN InUse; // USB Hardware Occupied. Wait for USB HW to put packet. + BOOLEAN Readable; // Receive Complete back. OK for driver to indicate receiving packet. + BOOLEAN IRPPending; // TODO: To be removed + atomic_t IrpLock; + NDIS_SPIN_LOCK RxContextLock; + dma_addr_t data_dma; // urb dma on linux +} RX_CONTEXT, *PRX_CONTEXT; + + + +/****************************************************************************** + + USB Frimware Related MACRO + +******************************************************************************/ +// 8051 firmware image for usb - use last-half base address = 0x3000 +#define FIRMWARE_IMAGE_BASE 0x3000 +#define MAX_FIRMWARE_IMAGE_SIZE 0x1000 // 4kbyte + +#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \ + RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen) + + + +/****************************************************************************** + + USB TX Related MACRO + +******************************************************************************/ +#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags) \ + do{ \ + RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ + if (pAd->DeQueueRunning[QueIdx]) \ + { \ + RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\ + DBGPRINT(RT_DEBUG_OFF, ("DeQueueRunning[%d]= TRUE!\n", QueIdx)); \ + continue; \ + } \ + else \ + { \ + pAd->DeQueueRunning[QueIdx] = TRUE; \ + RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\ + } \ + }while(0) + +#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags) \ + do{ \ + RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ + pAd->DeQueueRunning[QueIdx] = FALSE; \ + RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ + }while(0) + +#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \ + (RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS) + +#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx) \ + do{}while(0) + +#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType) \ + ((_TxFrameType == TX_RALINK_FRAME) && (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx))) + +#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ + RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) + +#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \ + RtmpUSB_WriteSingleTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) + +#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \ + RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) + +#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \ + RtmpUSB_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) + +#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) \ + RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) + +#define HAL_LastTxIdx(pAd, QueIdx,TxIdx) \ + /*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx)*/ + +#define HAL_KickOutTx(pAd, pTxBlk, QueIdx) \ + RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx) + +#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) \ + RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) + +#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \ + RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen) + +#define GET_TXRING_FREENO(_pAd, _QueIdx) (_QueIdx) //(_pAd->TxRing[_QueIdx].TxSwFreeIdx) +#define GET_MGMTRING_FREENO(_pAd) (_pAd->MgmtRing.TxSwFreeIdx) + + +/* ----------------- RX Related MACRO ----------------- */ + + +/* + * Device Hardware Interface Related MACRO + */ +#define RTMP_IRQ_INIT(pAd) do{}while(0) +#define RTMP_IRQ_ENABLE(pAd) do{}while(0) + + +/* + * MLME Related MACRO + */ +#define RTMP_MLME_HANDLER(pAd) RTUSBMlmeUp(pAd) + +#define RTMP_MLME_PRE_SANITY_CHECK(pAd) \ + { if ((pAd->CommonCfg.bHardwareRadio == TRUE) && \ + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && \ + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { \ + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } } + +#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \ + { RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0); \ + RTUSBMlmeUp(pAd); } + +#define RTMP_MLME_RESET_STATE_MACHINE(pAd) \ + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL); \ + RTUSBMlmeUp(pAd); + +#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry) \ + { RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(MAC_TABLE_ENTRY)); \ + RTUSBMlmeUp(_pAd); \ + } + + +/* + * Power Save Related MACRO + */ +#define RTMP_PS_POLL_ENQUEUE(pAd) \ + { RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); \ + RTUSBKickBulkOut(pAd); } + +#define RTMP_STA_FORCE_WAKEUP(_pAd, bFromTx) \ + RT28xxUsbStaAsicForceWakeup(_pAd, bFromTx); + +#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \ + RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp); + +#define RTMP_SET_PSM_BIT(_pAd, _val) \ + {\ + if ((_pAd)->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP) \ + MlmeSetPsmBit(_pAd, _val);\ + else \ + { \ + USHORT _psm_val; \ + _psm_val = _val; \ + RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_SET_PSM_BIT, &(_psm_val), sizeof(USHORT)); \ + }\ + } + +#define RTMP_MLME_RADIO_ON(pAd) \ + RT28xxUsbMlmeRadioOn(pAd); + +#define RTMP_MLME_RADIO_OFF(pAd) \ + RT28xxUsbMlmeRadioOFF(pAd); + +#endif //__MAC_USB_H__ // Index: b/drivers/staging/rt2860/chip/rt2860.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/chip/rt2860.h @@ -0,0 +1,56 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + */ + +#ifndef __RT2860_H__ +#define __RT2860_H__ + +#include "mac_pci.h" + +#ifndef RTMP_PCI_SUPPORT +#error "For RT2860, you should define the compile flag -DRTMP_PCI_SUPPORT" +#endif + +#ifndef RTMP_MAC_PCI +#error "For RT2880, you should define the compile flag -DRTMP_MAC_PCI" +#endif + +// +// Device ID & Vendor ID, these values should match EEPROM value +// +#define NIC2860_PCI_DEVICE_ID 0x0601 +#define NIC2860_PCIe_DEVICE_ID 0x0681 +#define NIC2760_PCI_DEVICE_ID 0x0701 // 1T/2R Cardbus ??? +#define NIC2790_PCIe_DEVICE_ID 0x0781 // 1T/2R miniCard + + +#define VEN_AWT_PCIe_DEVICE_ID 0x1059 +#define VEN_AWT_PCI_VENDOR_ID 0x1A3B + +#define EDIMAX_PCI_VENDOR_ID 0x1432 + + +#endif //__RT2860_H__ // Index: b/drivers/staging/rt2860/chip/rt2870.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/chip/rt2870.h @@ -0,0 +1,47 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + */ +#ifndef __RT2870_H__ +#define __RT2870_H__ + +#ifdef RT2870 + +#ifndef RTMP_USB_SUPPORT +#error "For RT2870, you should define the compile flag -DRTMP_USB_SUPPORT" +#endif + +#ifndef RTMP_MAC_USB +#error "For RT2870, you should define the compile flag -DRTMP_MAC_USB" +#endif + +#include "../rtmp_type.h" +#include "mac_usb.h" + + +//#define RTMP_CHIP_NAME "RT2870" + +#endif // RT2870 // +#endif //__RT2870_H__ // Index: b/drivers/staging/rt2860/chip/rt3070.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/chip/rt3070.h @@ -0,0 +1,68 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rt3070.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __RT3070_H__ +#define __RT3070_H__ + +#ifdef RT3070 + + +#ifndef RTMP_USB_SUPPORT +#error "For RT3070, you should define the compile flag -DRTMP_USB_SUPPORT" +#endif + +#ifndef RTMP_MAC_USB +#error "For RT3070, you should define the compile flag -DRTMP_MAC_USB" +#endif + +#ifndef RTMP_RF_RW_SUPPORT +#error "For RT3070, you should define the compile flag -DRTMP_RF_RW_SUPPORT" +#endif + +#ifndef RT30xx +#error "For RT3070, you should define the compile flag -DRT30xx" +#endif + +#include "mac_usb.h" +#include "rt30xx.h" + +// +// Device ID & Vendor ID, these values should match EEPROM value +// + +#endif // RT3070 // + +#endif //__RT3070_H__ // Index: b/drivers/staging/rt2860/chip/rt30xx.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/chip/rt30xx.h @@ -0,0 +1,48 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rt30xx.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __RT30XX_H__ +#define __RT30XX_H__ + +#ifdef RT30xx + + +extern REG_PAIR RT30xx_RFRegTable[]; +extern UCHAR NUM_RF_REG_PARMS; + +#endif // RT30xx // + +#endif //__RT30XX_H__ // Index: b/drivers/staging/rt2860/chip/rtmp_mac.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/chip/rtmp_mac.h @@ -0,0 +1,1334 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rtmp_mac.h + + Abstract: + Ralink Wireless Chip MAC related definition & structures + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifndef __RTMP_MAC_H__ +#define __RTMP_MAC_H__ + + + +// ================================================================================= +// TX / RX ring descriptor format +// ================================================================================= + +// the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO. +// MAC block use this TXINFO to control the transmission behavior of this frame. +#define FIFO_MGMT 0 +#define FIFO_HCCA 1 +#define FIFO_EDCA 2 + + +// +// TXD Wireless Information format for Tx ring and Mgmt Ring +// +//txop : for txop mode +// 0:txop for the MPDU frame will be handles by ASIC by register +// 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS +typedef struct PACKED _TXWI_STRUC { + // Word 0 + // ex: 00 03 00 40 means txop = 3, PHYMODE = 1 + UINT32 FRAG:1; // 1 to inform TKIP engine this is a fragment. + UINT32 MIMOps:1; // the remote peer is in dynamic MIMO-PS mode + UINT32 CFACK:1; + UINT32 TS:1; + + UINT32 AMPDU:1; + UINT32 MpduDensity:3; + UINT32 txop:2; //FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful. + UINT32 rsv:6; + + UINT32 MCS:7; + UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz + UINT32 ShortGI:1; + UINT32 STBC:2; // 1: STBC support MCS =0-7, 2,3 : RESERVE + UINT32 Ifs:1; // +// UINT32 rsv2:2; //channel bandwidth 20MHz or 40 MHz + UINT32 rsv2:1; + UINT32 TxBF:1; // 3*3 + UINT32 PHYMODE:2; + // Word1 + // ex: 1c ff 38 00 means ACK=0, BAWinSize=7, MPDUtotalByteCount = 0x38 + UINT32 ACK:1; + UINT32 NSEQ:1; + UINT32 BAWinSize:6; + UINT32 WirelessCliID:8; + UINT32 MPDUtotalByteCount:12; + UINT32 PacketId:4; + //Word2 + UINT32 IV; + //Word3 + UINT32 EIV; +} TXWI_STRUC, *PTXWI_STRUC; + + +// +// RXWI wireless information format, in PBF. invisible in driver. +// +typedef struct PACKED _RXWI_STRUC { + // Word 0 + UINT32 WirelessCliID:8; + UINT32 KeyIndex:2; + UINT32 BSSID:3; + UINT32 UDF:3; + UINT32 MPDUtotalByteCount:12; + UINT32 TID:4; + // Word 1 + UINT32 FRAG:4; + UINT32 SEQUENCE:12; + UINT32 MCS:7; + UINT32 BW:1; + UINT32 ShortGI:1; + UINT32 STBC:2; + UINT32 rsv:3; + UINT32 PHYMODE:2; // 1: this RX frame is unicast to me + //Word2 + UINT32 RSSI0:8; + UINT32 RSSI1:8; + UINT32 RSSI2:8; + UINT32 rsv1:8; + //Word3 + UINT32 SNR0:8; + UINT32 SNR1:8; + UINT32 FOFFSET:8; // RT35xx + UINT32 rsv2:8; + /*UINT32 rsv2:16;*/ +} RXWI_STRUC, *PRXWI_STRUC; + + +// ================================================================================= +// Register format +// ================================================================================= + + +// +// SCH/DMA registers - base address 0x0200 +// +// INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit +// +#define DMA_CSR0 0x200 +#define INT_SOURCE_CSR 0x200 +typedef union _INT_SOURCE_CSR_STRUC { + struct { + UINT32 RxDelayINT:1; + UINT32 TxDelayINT:1; + UINT32 RxDone:1; + UINT32 Ac0DmaDone:1;//4 + UINT32 Ac1DmaDone:1; + UINT32 Ac2DmaDone:1; + UINT32 Ac3DmaDone:1; + UINT32 HccaDmaDone:1; // bit7 + UINT32 MgmtDmaDone:1; + UINT32 MCUCommandINT:1;//bit 9 + UINT32 RxTxCoherent:1; + UINT32 TBTTInt:1; + UINT32 PreTBTT:1; + UINT32 TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c + UINT32 AutoWakeup:1;//bit14 + UINT32 GPTimer:1; + UINT32 RxCoherent:1;//bit16 + UINT32 TxCoherent:1; + UINT32 :14; + } field; + UINT32 word; +} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC; + +// +// INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF +// +#define INT_MASK_CSR 0x204 +typedef union _INT_MASK_CSR_STRUC { + struct { + UINT32 RXDelay_INT_MSK:1; + UINT32 TxDelay:1; + UINT32 RxDone:1; + UINT32 Ac0DmaDone:1; + UINT32 Ac1DmaDone:1; + UINT32 Ac2DmaDone:1; + UINT32 Ac3DmaDone:1; + UINT32 HccaDmaDone:1; + UINT32 MgmtDmaDone:1; + UINT32 MCUCommandINT:1; + UINT32 :20; + UINT32 RxCoherent:1; + UINT32 TxCoherent:1; + } field; + UINT32 word; +} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC; + +#define WPDMA_GLO_CFG 0x208 +typedef union _WPDMA_GLO_CFG_STRUC { + struct { + UINT32 EnableTxDMA:1; + UINT32 TxDMABusy:1; + UINT32 EnableRxDMA:1; + UINT32 RxDMABusy:1; + UINT32 WPDMABurstSIZE:2; + UINT32 EnTXWriteBackDDONE:1; + UINT32 BigEndian:1; + UINT32 RXHdrScater:8; + UINT32 HDR_SEG_LEN:16; + } field; + UINT32 word; +} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC; + +#define WPDMA_RST_IDX 0x20c +typedef union _WPDMA_RST_IDX_STRUC { + struct { + UINT32 RST_DTX_IDX0:1; + UINT32 RST_DTX_IDX1:1; + UINT32 RST_DTX_IDX2:1; + UINT32 RST_DTX_IDX3:1; + UINT32 RST_DTX_IDX4:1; + UINT32 RST_DTX_IDX5:1; + UINT32 rsv:10; + UINT32 RST_DRX_IDX0:1; + UINT32 :15; + } field; + UINT32 word; +} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC; +#define DELAY_INT_CFG 0x0210 +typedef union _DELAY_INT_CFG_STRUC { + struct { + UINT32 RXMAX_PTIME:8; + UINT32 RXMAX_PINT:7; + UINT32 RXDLY_INT_EN:1; + UINT32 TXMAX_PTIME:8; + UINT32 TXMAX_PINT:7; + UINT32 TXDLY_INT_EN:1; + } field; + UINT32 word; +} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC; +#define WMM_AIFSN_CFG 0x0214 +typedef union _AIFSN_CSR_STRUC { + struct { + UINT32 Aifsn0:4; // for AC_BE + UINT32 Aifsn1:4; // for AC_BK + UINT32 Aifsn2:4; // for AC_VI + UINT32 Aifsn3:4; // for AC_VO + UINT32 Rsv:16; + } field; + UINT32 word; +} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC; +// +// CWMIN_CSR: CWmin for each EDCA AC +// +#define WMM_CWMIN_CFG 0x0218 +typedef union _CWMIN_CSR_STRUC { + struct { + UINT32 Cwmin0:4; // for AC_BE + UINT32 Cwmin1:4; // for AC_BK + UINT32 Cwmin2:4; // for AC_VI + UINT32 Cwmin3:4; // for AC_VO + UINT32 Rsv:16; + } field; + UINT32 word; +} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC; + +// +// CWMAX_CSR: CWmin for each EDCA AC +// +#define WMM_CWMAX_CFG 0x021c +typedef union _CWMAX_CSR_STRUC { + struct { + UINT32 Cwmax0:4; // for AC_BE + UINT32 Cwmax1:4; // for AC_BK + UINT32 Cwmax2:4; // for AC_VI + UINT32 Cwmax3:4; // for AC_VO + UINT32 Rsv:16; + } field; + UINT32 word; +} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC; + + +// +// AC_TXOP_CSR0: AC_BK/AC_BE TXOP register +// +#define WMM_TXOP0_CFG 0x0220 +typedef union _AC_TXOP_CSR0_STRUC { + struct { + USHORT Ac0Txop; // for AC_BK, in unit of 32us + USHORT Ac1Txop; // for AC_BE, in unit of 32us + } field; + UINT32 word; +} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC; + +// +// AC_TXOP_CSR1: AC_VO/AC_VI TXOP register +// +#define WMM_TXOP1_CFG 0x0224 +typedef union _AC_TXOP_CSR1_STRUC { + struct { + USHORT Ac2Txop; // for AC_VI, in unit of 32us + USHORT Ac3Txop; // for AC_VO, in unit of 32us + } field; + UINT32 word; +} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC; + + +#define RINGREG_DIFF 0x10 +#define GPIO_CTRL_CFG 0x0228 //MAC_CSR13 +#define MCU_CMD_CFG 0x022c +#define TX_BASE_PTR0 0x0230 //AC_BK base address +#define TX_MAX_CNT0 0x0234 +#define TX_CTX_IDX0 0x0238 +#define TX_DTX_IDX0 0x023c +#define TX_BASE_PTR1 0x0240 //AC_BE base address +#define TX_MAX_CNT1 0x0244 +#define TX_CTX_IDX1 0x0248 +#define TX_DTX_IDX1 0x024c +#define TX_BASE_PTR2 0x0250 //AC_VI base address +#define TX_MAX_CNT2 0x0254 +#define TX_CTX_IDX2 0x0258 +#define TX_DTX_IDX2 0x025c +#define TX_BASE_PTR3 0x0260 //AC_VO base address +#define TX_MAX_CNT3 0x0264 +#define TX_CTX_IDX3 0x0268 +#define TX_DTX_IDX3 0x026c +#define TX_BASE_PTR4 0x0270 //HCCA base address +#define TX_MAX_CNT4 0x0274 +#define TX_CTX_IDX4 0x0278 +#define TX_DTX_IDX4 0x027c +#define TX_BASE_PTR5 0x0280 //MGMT base address +#define TX_MAX_CNT5 0x0284 +#define TX_CTX_IDX5 0x0288 +#define TX_DTX_IDX5 0x028c +#define TX_MGMTMAX_CNT TX_MAX_CNT5 +#define TX_MGMTCTX_IDX TX_CTX_IDX5 +#define TX_MGMTDTX_IDX TX_DTX_IDX5 +#define RX_BASE_PTR 0x0290 //RX base address +#define RX_MAX_CNT 0x0294 +#define RX_CRX_IDX 0x0298 +#define RX_DRX_IDX 0x029c + + +#define USB_DMA_CFG 0x02a0 +typedef union _USB_DMA_CFG_STRUC { + struct { + UINT32 RxBulkAggTOut:8; //Rx Bulk Aggregation TimeOut in unit of 33ns + UINT32 RxBulkAggLmt:8; //Rx Bulk Aggregation Limit in unit of 256 bytes + UINT32 phyclear:1; //phy watch dog enable. write 1 + UINT32 rsv:2; + UINT32 TxClear:1; //Clear USB DMA TX path + UINT32 TxopHalt:1; //Halt TXOP count down when TX buffer is full. + UINT32 RxBulkAggEn:1; //Enable Rx Bulk Aggregation + UINT32 RxBulkEn:1; //Enable USB DMA Rx + UINT32 TxBulkEn:1; //Enable USB DMA Tx + UINT32 EpoutValid:6; //OUT endpoint data valid + UINT32 RxBusy:1; //USB DMA RX FSM busy + UINT32 TxBusy:1; //USB DMA TX FSM busy + } field; + UINT32 word; +} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC; + + +// +// 3 PBF registers +// +// +// Most are for debug. Driver doesn't touch PBF register. +#define PBF_SYS_CTRL 0x0400 +#define PBF_CFG 0x0408 +#define PBF_MAX_PCNT 0x040C +#define PBF_CTRL 0x0410 +#define PBF_INT_STA 0x0414 +#define PBF_INT_ENA 0x0418 +#define TXRXQ_PCNT 0x0438 +#define PBF_DBG 0x043c +#define PBF_CAP_CTRL 0x0440 + +#ifdef RT30xx +#ifdef RTMP_EFUSE_SUPPORT +// eFuse registers +#define EFUSE_CTRL 0x0580 +#define EFUSE_DATA0 0x0590 +#define EFUSE_DATA1 0x0594 +#define EFUSE_DATA2 0x0598 +#define EFUSE_DATA3 0x059c +#endif // RTMP_EFUSE_SUPPORT // +#endif // RT30xx // + +#define OSC_CTRL 0x5a4 +#define PCIE_PHY_TX_ATTENUATION_CTRL 0x05C8 +#define LDO_CFG0 0x05d4 +#define GPIO_SWITCH 0x05dc + + +// +// 4 MAC registers +// +// +// 4.1 MAC SYSTEM configuration registers (offset:0x1000) +// +#define MAC_CSR0 0x1000 +typedef union _ASIC_VER_ID_STRUC { + struct { + USHORT ASICRev; // reversion : 0 + USHORT ASICVer; // version : 2860 + } field; + UINT32 word; +} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC; +#define MAC_SYS_CTRL 0x1004 //MAC_CSR1 +#define MAC_ADDR_DW0 0x1008 // MAC ADDR DW0 +#define MAC_ADDR_DW1 0x100c // MAC ADDR DW1 +// +// MAC_CSR2: STA MAC register 0 +// +typedef union _MAC_DW0_STRUC { + struct { + UCHAR Byte0; // MAC address byte 0 + UCHAR Byte1; // MAC address byte 1 + UCHAR Byte2; // MAC address byte 2 + UCHAR Byte3; // MAC address byte 3 + } field; + UINT32 word; +} MAC_DW0_STRUC, *PMAC_DW0_STRUC; + +// +// MAC_CSR3: STA MAC register 1 +// +typedef union _MAC_DW1_STRUC { + struct { + UCHAR Byte4; // MAC address byte 4 + UCHAR Byte5; // MAC address byte 5 + UCHAR U2MeMask; + UCHAR Rsvd1; + } field; + UINT32 word; +} MAC_DW1_STRUC, *PMAC_DW1_STRUC; + +#define MAC_BSSID_DW0 0x1010 // MAC BSSID DW0 +#define MAC_BSSID_DW1 0x1014 // MAC BSSID DW1 + +// +// MAC_CSR5: BSSID register 1 +// +typedef union _MAC_CSR5_STRUC { + struct { + UCHAR Byte4; // BSSID byte 4 + UCHAR Byte5; // BSSID byte 5 + USHORT BssIdMask:2; // 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID + USHORT MBssBcnNum:3; + USHORT Rsvd:11; + } field; + UINT32 word; +} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC; + +#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 +#define BBP_CSR_CFG 0x101c // +// +// BBP_CSR_CFG: BBP serial control register +// +typedef union _BBP_CSR_CFG_STRUC { + struct { + UINT32 Value:8; // Register value to program into BBP + UINT32 RegNum:8; // Selected BBP register + UINT32 fRead:1; // 0: Write BBP, 1: Read BBP + UINT32 Busy:1; // 1: ASIC is busy execute BBP programming. + UINT32 BBP_PAR_DUR:1; // 0: 4 MAC clock cycles 1: 8 MAC clock cycles + UINT32 BBP_RW_MODE:1; // 0: use serial mode 1:parallel + UINT32 :12; + } field; + UINT32 word; +} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC; +#define RF_CSR_CFG0 0x1020 +// +// RF_CSR_CFG: RF control register +// +typedef union _RF_CSR_CFG0_STRUC { + struct { + UINT32 RegIdAndContent:24; // Register value to program into BBP + UINT32 bitwidth:5; // Selected BBP register + UINT32 StandbyMode:1; // 0: high when stand by 1: low when standby + UINT32 Sel:1; // 0:RF_LE0 activate 1:RF_LE1 activate + UINT32 Busy:1; // 0: idle 1: 8busy + } field; + UINT32 word; +} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC; +#define RF_CSR_CFG1 0x1024 +typedef union _RF_CSR_CFG1_STRUC { + struct { + UINT32 RegIdAndContent:24; // Register value to program into BBP + 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) + UINT32 rsv:7; // 0: idle 1: 8busy + } field; + UINT32 word; +} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC; +#define RF_CSR_CFG2 0x1028 // +typedef union _RF_CSR_CFG2_STRUC { + struct { + UINT32 RegIdAndContent:24; // Register value to program into BBP + UINT32 rsv:8; // 0: idle 1: 8busy + } field; + UINT32 word; +} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC; +#define LED_CFG 0x102c // MAC_CSR14 +typedef union _LED_CFG_STRUC { + struct { + UINT32 OnPeriod:8; // blinking on period unit 1ms + UINT32 OffPeriod:8; // blinking off period unit 1ms + UINT32 SlowBlinkPeriod:6; // slow blinking period. unit:1ms + UINT32 rsv:2; + UINT32 RLedMode:2; // red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on + UINT32 GLedMode:2; // green Led Mode + UINT32 YLedMode:2; // yellow Led Mode + UINT32 LedPolar:1; // Led Polarity. 0: active low1: active high + UINT32 :1; + } field; + UINT32 word; +} LED_CFG_STRUC, *PLED_CFG_STRUC; +// +// 4.2 MAC TIMING configuration registers (offset:0x1100) +// +#define XIFS_TIME_CFG 0x1100 // MAC_CSR8 MAC_CSR9 +typedef union _IFS_SLOT_CFG_STRUC { + struct { + UINT32 CckmSifsTime:8; // unit 1us. Applied after CCK RX/TX + UINT32 OfdmSifsTime:8; // unit 1us. Applied after OFDM RX/TX + UINT32 OfdmXifsTime:4; //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND + UINT32 EIFS:9; // unit 1us + UINT32 BBRxendEnable:1; // reference RXEND signal to begin XIFS defer + UINT32 rsv:2; + } field; + UINT32 word; +} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC; + +#define BKOFF_SLOT_CFG 0x1104 // mac_csr9 last 8 bits +#define NAV_TIME_CFG 0x1108 // NAV (MAC_CSR15) +#define CH_TIME_CFG 0x110C // Count as channel busy +#define PBF_LIFE_TIMER 0x1110 //TX/RX MPDU timestamp timer (free run)Unit: 1us +#define BCN_TIME_CFG 0x1114 // TXRX_CSR9 + +#define BCN_OFFSET0 0x042C +#define BCN_OFFSET1 0x0430 + +// +// BCN_TIME_CFG : Synchronization control register +// +typedef union _BCN_TIME_CFG_STRUC { + struct { + UINT32 BeaconInterval:16; // in unit of 1/16 TU + UINT32 bTsfTicking:1; // Enable TSF auto counting + UINT32 TsfSyncMode:2; // Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode + UINT32 bTBTTEnable:1; + UINT32 bBeaconGen:1; // Enable beacon generator + UINT32 :3; + UINT32 TxTimestampCompensate:8; + } field; + UINT32 word; +} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC; +#define TBTT_SYNC_CFG 0x1118 // txrx_csr10 +#define TSF_TIMER_DW0 0x111C // Local TSF timer lsb 32 bits. Read-only +#define TSF_TIMER_DW1 0x1120 // msb 32 bits. Read-only. +#define TBTT_TIMER 0x1124 // TImer remains till next TBTT. Read-only. TXRX_CSR14 +#define INT_TIMER_CFG 0x1128 // +#define INT_TIMER_EN 0x112c // GP-timer and pre-tbtt Int enable +#define CH_IDLE_STA 0x1130 // channel idle time +#define CH_BUSY_STA 0x1134 // channle busy time +// +// 4.2 MAC POWER configuration registers (offset:0x1200) +// +#define MAC_STATUS_CFG 0x1200 // old MAC_CSR12 +#define PWR_PIN_CFG 0x1204 // old MAC_CSR12 +#define AUTO_WAKEUP_CFG 0x1208 // old MAC_CSR10 +// +// AUTO_WAKEUP_CFG: Manual power control / status register +// +typedef union _AUTO_WAKEUP_STRUC { + struct { + UINT32 AutoLeadTime:8; + UINT32 NumofSleepingTbtt:7; // ForceWake has high privilege than PutToSleep when both set + UINT32 EnableAutoWakeup:1; // 0:sleep, 1:awake + UINT32 :16; + } field; + UINT32 word; +} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC; +// +// 4.3 MAC TX configuration registers (offset:0x1300) +// + +#define EDCA_AC0_CFG 0x1300 //AC_TXOP_CSR0 0x3474 +#define EDCA_AC1_CFG 0x1304 +#define EDCA_AC2_CFG 0x1308 +#define EDCA_AC3_CFG 0x130c +typedef union _EDCA_AC_CFG_STRUC { + struct { + UINT32 AcTxop:8; // in unit of 32us + UINT32 Aifsn:4; // # of slot time + UINT32 Cwmin:4; // + UINT32 Cwmax:4; //unit power of 2 + UINT32 :12; // + } field; + UINT32 word; +} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC; + +#define EDCA_TID_AC_MAP 0x1310 +#define TX_PWR_CFG_0 0x1314 +#define TX_PWR_CFG_1 0x1318 +#define TX_PWR_CFG_2 0x131C +#define TX_PWR_CFG_3 0x1320 +#define TX_PWR_CFG_4 0x1324 +#define TX_PIN_CFG 0x1328 +#define TX_BAND_CFG 0x132c // 0x1 use upper 20MHz. 0 juse lower 20MHz +#define TX_SW_CFG0 0x1330 +#define TX_SW_CFG1 0x1334 +#define TX_SW_CFG2 0x1338 +#define TXOP_THRES_CFG 0x133c +#define TXOP_CTRL_CFG 0x1340 +#define TX_RTS_CFG 0x1344 + +typedef union _TX_RTS_CFG_STRUC { + struct { + UINT32 AutoRtsRetryLimit:8; + UINT32 RtsThres:16; // unit:byte + UINT32 RtsFbkEn:1; // enable rts rate fallback + UINT32 rsv:7; // 1: HT non-STBC control frame enable + } field; + UINT32 word; +} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC; +#define TX_TIMEOUT_CFG 0x1348 +typedef union _TX_TIMEOUT_CFG_STRUC { + struct { + UINT32 rsv:4; + UINT32 MpduLifeTime:4; // expiration time = 2^(9+MPDU LIFE TIME) us + UINT32 RxAckTimeout:8; // unit:slot. Used for TX precedure + UINT32 TxopTimeout:8; //TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT) + UINT32 rsv2:8; // 1: HT non-STBC control frame enable + } field; + UINT32 word; +} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC; +#define TX_RTY_CFG 0x134c +typedef union PACKED _TX_RTY_CFG_STRUC { + struct { + UINT32 ShortRtyLimit:8; // short retry limit + UINT32 LongRtyLimit:8; //long retry limit + UINT32 LongRtyThre:12; // Long retry threshoold + UINT32 NonAggRtyMode:1; // Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer + UINT32 AggRtyMode:1; // Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer + UINT32 TxautoFBEnable:1; // Tx retry PHY rate auto fallback enable + UINT32 rsv:1; // 1: HT non-STBC control frame enable + } field; + UINT32 word; +} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC; +#define TX_LINK_CFG 0x1350 +typedef union PACKED _TX_LINK_CFG_STRUC { + struct PACKED { + UINT32 RemoteMFBLifeTime:8; //remote MFB life time. unit : 32us + UINT32 MFBEnable:1; // TX apply remote MFB 1:enable + UINT32 RemoteUMFSEnable:1; // remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7) + UINT32 TxMRQEn:1; // MCS request TX enable + UINT32 TxRDGEn:1; // RDG TX enable + UINT32 TxCFAckEn:1; // Piggyback CF-ACK enable + UINT32 rsv:3; // + UINT32 RemotMFB:8; // remote MCS feedback + UINT32 RemotMFS:8; //remote MCS feedback sequence number + } field; + UINT32 word; +} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC; +#define HT_FBK_CFG0 0x1354 +typedef union PACKED _HT_FBK_CFG0_STRUC { + struct { + UINT32 HTMCS0FBK:4; + UINT32 HTMCS1FBK:4; + UINT32 HTMCS2FBK:4; + UINT32 HTMCS3FBK:4; + UINT32 HTMCS4FBK:4; + UINT32 HTMCS5FBK:4; + UINT32 HTMCS6FBK:4; + UINT32 HTMCS7FBK:4; + } field; + UINT32 word; +} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC; +#define HT_FBK_CFG1 0x1358 +typedef union _HT_FBK_CFG1_STRUC { + struct { + UINT32 HTMCS8FBK:4; + UINT32 HTMCS9FBK:4; + UINT32 HTMCS10FBK:4; + UINT32 HTMCS11FBK:4; + UINT32 HTMCS12FBK:4; + UINT32 HTMCS13FBK:4; + UINT32 HTMCS14FBK:4; + UINT32 HTMCS15FBK:4; + } field; + UINT32 word; +} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC; +#define LG_FBK_CFG0 0x135c +typedef union _LG_FBK_CFG0_STRUC { + struct { + UINT32 OFDMMCS0FBK:4; //initial value is 0 + UINT32 OFDMMCS1FBK:4; //initial value is 0 + UINT32 OFDMMCS2FBK:4; //initial value is 1 + UINT32 OFDMMCS3FBK:4; //initial value is 2 + UINT32 OFDMMCS4FBK:4; //initial value is 3 + UINT32 OFDMMCS5FBK:4; //initial value is 4 + UINT32 OFDMMCS6FBK:4; //initial value is 5 + UINT32 OFDMMCS7FBK:4; //initial value is 6 + } field; + UINT32 word; +} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC; +#define LG_FBK_CFG1 0x1360 +typedef union _LG_FBK_CFG1_STRUC { + struct { + UINT32 CCKMCS0FBK:4; //initial value is 0 + UINT32 CCKMCS1FBK:4; //initial value is 0 + UINT32 CCKMCS2FBK:4; //initial value is 1 + UINT32 CCKMCS3FBK:4; //initial value is 2 + UINT32 rsv:16; + } field; + UINT32 word; +} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC; + + +//======================================================= +//================ Protection Paramater================================ +//======================================================= +#define CCK_PROT_CFG 0x1364 //CCK Protection +#define ASIC_SHORTNAV 1 +#define ASIC_LONGNAV 2 +#define ASIC_RTS 1 +#define ASIC_CTS 2 +typedef union _PROT_CFG_STRUC { + struct { + UINT32 ProtectRate:16; //Protection control frame rate for CCK TX(RTS/CTS/CFEnd). + UINT32 ProtectCtrl:2; //Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv + UINT32 ProtectNav:2; //TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv + UINT32 TxopAllowCck:1; //CCK TXOP allowance.0:disallow. + UINT32 TxopAllowOfdm:1; //CCK TXOP allowance.0:disallow. + UINT32 TxopAllowMM20:1; //CCK TXOP allowance. 0:disallow. + UINT32 TxopAllowMM40:1; //CCK TXOP allowance.0:disallow. + UINT32 TxopAllowGF20:1; //CCK TXOP allowance.0:disallow. + UINT32 TxopAllowGF40:1; //CCK TXOP allowance.0:disallow. + UINT32 RTSThEn:1; //RTS threshold enable on CCK TX + UINT32 rsv:5; + } field; + UINT32 word; +} PROT_CFG_STRUC, *PPROT_CFG_STRUC; + +#define OFDM_PROT_CFG 0x1368 //OFDM Protection +#define MM20_PROT_CFG 0x136C //MM20 Protection +#define MM40_PROT_CFG 0x1370 //MM40 Protection +#define GF20_PROT_CFG 0x1374 //GF20 Protection +#define GF40_PROT_CFG 0x1378 //GR40 Protection +#define EXP_CTS_TIME 0x137C // +#define EXP_ACK_TIME 0x1380 // + +// +// 4.4 MAC RX configuration registers (offset:0x1400) +// +#define RX_FILTR_CFG 0x1400 //TXRX_CSR0 +#define AUTO_RSP_CFG 0x1404 //TXRX_CSR4 +// +// TXRX_CSR4: Auto-Responder/ +// +typedef union _AUTO_RSP_CFG_STRUC { + struct { + UINT32 AutoResponderEnable:1; + UINT32 BACAckPolicyEnable:1; // 0:long, 1:short preamble + UINT32 CTS40MMode:1; // Response CTS 40MHz duplicate mode + UINT32 CTS40MRef:1; // Response CTS 40MHz duplicate mode + UINT32 AutoResponderPreamble:1; // 0:long, 1:short preamble + UINT32 rsv:1; // Power bit value in conrtrol frame + UINT32 DualCTSEn:1; // Power bit value in conrtrol frame + UINT32 AckCtsPsmBit:1; // Power bit value in conrtrol frame + UINT32 :24; + } field; + UINT32 word; +} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC; + +#define LEGACY_BASIC_RATE 0x1408 // TXRX_CSR5 0x3054 +#define HT_BASIC_RATE 0x140c +#define HT_CTRL_CFG 0x1410 +#define SIFS_COST_CFG 0x1414 +#define RX_PARSER_CFG 0x1418 //Set NAV for all received frames + +// +// 4.5 MAC Security configuration (offset:0x1500) +// +#define TX_SEC_CNT0 0x1500 // +#define RX_SEC_CNT0 0x1504 // +#define CCMP_FC_MUTE 0x1508 // +// +// 4.6 HCCA/PSMP (offset:0x1600) +// +#define TXOP_HLDR_ADDR0 0x1600 +#define TXOP_HLDR_ADDR1 0x1604 +#define TXOP_HLDR_ET 0x1608 +#define QOS_CFPOLL_RA_DW0 0x160c +#define QOS_CFPOLL_A1_DW1 0x1610 +#define QOS_CFPOLL_QC 0x1614 +// +// 4.7 MAC Statistis registers (offset:0x1700) +// +#define RX_STA_CNT0 0x1700 // +#define RX_STA_CNT1 0x1704 // +#define RX_STA_CNT2 0x1708 // + +// +// RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count +// +typedef union _RX_STA_CNT0_STRUC { + struct { + USHORT CrcErr; + USHORT PhyErr; + } field; + UINT32 word; +} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC; + +// +// RX_STA_CNT1_STRUC: RX False CCA count & RX LONG frame count +// +typedef union _RX_STA_CNT1_STRUC { + struct { + USHORT FalseCca; + USHORT PlcpErr; + } field; + UINT32 word; +} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC; + +// +// RX_STA_CNT2_STRUC: +// +typedef union _RX_STA_CNT2_STRUC { + struct { + USHORT RxDupliCount; + USHORT RxFifoOverflowCount; + } field; + UINT32 word; +} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC; +#define TX_STA_CNT0 0x170C // +// +// STA_CSR3: TX Beacon count +// +typedef union _TX_STA_CNT0_STRUC { + struct { + USHORT TxFailCount; + USHORT TxBeaconCount; + } field; + UINT32 word; +} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC; +#define TX_STA_CNT1 0x1710 // +// +// TX_STA_CNT1: TX tx count +// +typedef union _TX_STA_CNT1_STRUC { + struct { + USHORT TxSuccess; + USHORT TxRetransmit; + } field; + UINT32 word; +} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC; +#define TX_STA_CNT2 0x1714 // +// +// TX_STA_CNT2: TX tx count +// +typedef union _TX_STA_CNT2_STRUC { + struct { + USHORT TxZeroLenCount; + USHORT TxUnderFlowCount; + } field; + UINT32 word; +} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC; +#define TX_STA_FIFO 0x1718 // +// +// TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register +// +typedef union PACKED _TX_STA_FIFO_STRUC { + struct { + UINT32 bValid:1; // 1:This register contains a valid TX result + UINT32 PidType:4; + UINT32 TxSuccess:1; // Tx No retry success + UINT32 TxAggre:1; // Tx Retry Success + UINT32 TxAckRequired:1; // Tx fail + UINT32 wcid:8; //wireless client index +// UINT32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. + UINT32 SuccessRate:13; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. + UINT32 TxBF:1; + UINT32 Reserve:2; + } field; + UINT32 word; +} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC; +// Debug counter +#define TX_AGG_CNT 0x171c +typedef union _TX_AGG_CNT_STRUC { + struct { + USHORT NonAggTxCount; + USHORT AggTxCount; + } field; + UINT32 word; +} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC; +// Debug counter +#define TX_AGG_CNT0 0x1720 +typedef union _TX_AGG_CNT0_STRUC { + struct { + USHORT AggSize1Count; + USHORT AggSize2Count; + } field; + UINT32 word; +} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC; +// Debug counter +#define TX_AGG_CNT1 0x1724 +typedef union _TX_AGG_CNT1_STRUC { + struct { + USHORT AggSize3Count; + USHORT AggSize4Count; + } field; + UINT32 word; +} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC; +#define TX_AGG_CNT2 0x1728 +typedef union _TX_AGG_CNT2_STRUC { + struct { + USHORT AggSize5Count; + USHORT AggSize6Count; + } field; + UINT32 word; +} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC; +// Debug counter +#define TX_AGG_CNT3 0x172c +typedef union _TX_AGG_CNT3_STRUC { + struct { + USHORT AggSize7Count; + USHORT AggSize8Count; + } field; + UINT32 word; +} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC; +// Debug counter +#define TX_AGG_CNT4 0x1730 +typedef union _TX_AGG_CNT4_STRUC { + struct { + USHORT AggSize9Count; + USHORT AggSize10Count; + } field; + UINT32 word; +} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC; +#define TX_AGG_CNT5 0x1734 +typedef union _TX_AGG_CNT5_STRUC { + struct { + USHORT AggSize11Count; + USHORT AggSize12Count; + } field; + UINT32 word; +} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC; +#define TX_AGG_CNT6 0x1738 +typedef union _TX_AGG_CNT6_STRUC { + struct { + USHORT AggSize13Count; + USHORT AggSize14Count; + } field; + UINT32 word; +} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC; +#define TX_AGG_CNT7 0x173c +typedef union _TX_AGG_CNT7_STRUC { + struct { + USHORT AggSize15Count; + USHORT AggSize16Count; + } field; + UINT32 word; +} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC; +#define MPDU_DENSITY_CNT 0x1740 +typedef union _MPDU_DEN_CNT_STRUC { + struct { + USHORT TXZeroDelCount; //TX zero length delimiter count + USHORT RXZeroDelCount; //RX zero length delimiter count + } field; + UINT32 word; +} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC; +// +// TXRX control registers - base address 0x3000 +// +// rt2860b UNKNOWN reg use R/O Reg Addr 0x77d0 first.. +#define TXRX_CSR1 0x77d0 + +// +// Security key table memory, base address = 0x1000 +// +#define MAC_WCID_BASE 0x1800 //8-bytes(use only 6-bytes) * 256 entry = +#define HW_WCID_ENTRY_SIZE 8 +#define PAIRWISE_KEY_TABLE_BASE 0x4000 // 32-byte * 256-entry = -byte +#define HW_KEY_ENTRY_SIZE 0x20 +#define PAIRWISE_IVEIV_TABLE_BASE 0x6000 // 8-byte * 256-entry = -byte +#define MAC_IVEIV_TABLE_BASE 0x6000 // 8-byte * 256-entry = -byte +#define HW_IVEIV_ENTRY_SIZE 8 +#define MAC_WCID_ATTRIBUTE_BASE 0x6800 // 4-byte * 256-entry = -byte +#define HW_WCID_ATTRI_SIZE 4 +#define WCID_RESERVED 0x6bfc +#define SHARED_KEY_TABLE_BASE 0x6c00 // 32-byte * 16-entry = 512-byte +#define SHARED_KEY_MODE_BASE 0x7000 // 32-byte * 16-entry = 512-byte +#define HW_SHARED_KEY_MODE_SIZE 4 +#define SHAREDKEYTABLE 0 +#define PAIRWISEKEYTABLE 1 + + +typedef union _SHAREDKEY_MODE_STRUC { + struct { + UINT32 Bss0Key0CipherAlg:3; + UINT32 :1; + UINT32 Bss0Key1CipherAlg:3; + UINT32 :1; + UINT32 Bss0Key2CipherAlg:3; + UINT32 :1; + UINT32 Bss0Key3CipherAlg:3; + UINT32 :1; + UINT32 Bss1Key0CipherAlg:3; + UINT32 :1; + UINT32 Bss1Key1CipherAlg:3; + UINT32 :1; + UINT32 Bss1Key2CipherAlg:3; + UINT32 :1; + UINT32 Bss1Key3CipherAlg:3; + UINT32 :1; + } field; + UINT32 word; +} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC; +// 64-entry for pairwise key table +typedef struct _HW_WCID_ENTRY { // 8-byte per entry + UCHAR Address[6]; + UCHAR Rsv[2]; +} HW_WCID_ENTRY, PHW_WCID_ENTRY; + + +// ================================================================================= +// WCID format +// ================================================================================= +//7.1 WCID ENTRY format : 8bytes +typedef struct _WCID_ENTRY_STRUC { + UCHAR RXBABitmap7; // bit0 for TID8, bit7 for TID 15 + UCHAR RXBABitmap0; // bit0 for TID0, bit7 for TID 7 + UCHAR MAC[6]; // 0 for shared key table. 1 for pairwise key table +} WCID_ENTRY_STRUC, *PWCID_ENTRY_STRUC; + +//8.1.1 SECURITY KEY format : 8DW +// 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table +typedef struct _HW_KEY_ENTRY { // 32-byte per entry + UCHAR Key[16]; + UCHAR TxMic[8]; + UCHAR RxMic[8]; +} HW_KEY_ENTRY, *PHW_KEY_ENTRY; + +//8.1.2 IV/EIV format : 2DW + +//8.1.3 RX attribute entry format : 1DW +typedef struct _MAC_ATTRIBUTE_STRUC { + UINT32 KeyTab:1; // 0 for shared key table. 1 for pairwise key table + UINT32 PairKeyMode:3; + UINT32 BSSIDIdx:3; //multipleBSS index for the WCID + UINT32 RXWIUDF:3; + UINT32 rsv:22; +} MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC; + + +// ================================================================================= +// HOST-MCU communication data structure +// ================================================================================= + +// +// H2M_MAILBOX_CSR: Host-to-MCU Mailbox +// +typedef union _H2M_MAILBOX_STRUC { + struct { + UINT32 LowByte:8; + UINT32 HighByte:8; + UINT32 CmdToken:8; + UINT32 Owner:8; + } field; + UINT32 word; +} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC; + +// +// M2H_CMD_DONE_CSR: MCU-to-Host command complete indication +// +typedef union _M2H_CMD_DONE_STRUC { + struct { + UINT32 CmdToken0; + UINT32 CmdToken1; + UINT32 CmdToken2; + UINT32 CmdToken3; + } field; + UINT32 word; +} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC; + + +//NAV_TIME_CFG :NAV +typedef union _NAV_TIME_CFG_STRUC { + struct { + UCHAR Sifs; // in unit of 1-us + UCHAR SlotTime; // in unit of 1-us + USHORT Eifs:9; // in unit of 1-us + USHORT ZeroSifs:1; // Applied zero SIFS timer after OFDM RX 0: disable + USHORT rsv:6; + } field; + UINT32 word; +} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC; + + +// +// RX_FILTR_CFG: /RX configuration register +// +typedef union _RX_FILTR_CFG_STRUC { + struct { + UINT32 DropCRCErr:1; // Drop CRC error + UINT32 DropPhyErr:1; // Drop physical error + UINT32 DropNotToMe:1; // Drop not to me unicast frame + UINT32 DropNotMyBSSID:1; // Drop fram ToDs bit is true + + UINT32 DropVerErr:1; // Drop version error frame + UINT32 DropMcast:1; // Drop multicast frames + UINT32 DropBcast:1; // Drop broadcast frames + UINT32 DropDuplicate:1; // Drop duplicate frame + + UINT32 DropCFEndAck:1; // Drop Ps-Poll + UINT32 DropCFEnd:1; // Drop Ps-Poll + UINT32 DropAck:1; // Drop Ps-Poll + UINT32 DropCts:1; // Drop Ps-Poll + + UINT32 DropRts:1; // Drop Ps-Poll + UINT32 DropPsPoll:1; // Drop Ps-Poll + UINT32 DropBA:1; // + UINT32 DropBAR:1; // + + UINT32 DropRsvCntlType:1; + UINT32 :15; + } field; + UINT32 word; +} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC; + + + + +// +// PHY_CSR4: RF serial control register +// +typedef union _PHY_CSR4_STRUC { + struct { + UINT32 RFRegValue:24; // Register value (include register id) serial out to RF/IF chip. + UINT32 NumberOfBits:5; // Number of bits used in RFRegValue (I:20, RFMD:22) + UINT32 IFSelect:1; // 1: select IF to program, 0: select RF to program + UINT32 PLL_LD:1; // RF PLL_LD status + UINT32 Busy:1; // 1: ASIC is busy execute RF programming. + } field; + UINT32 word; +} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC; + + +// +// SEC_CSR5: shared key table security mode register +// +typedef union _SEC_CSR5_STRUC { + struct { + UINT32 Bss2Key0CipherAlg:3; + UINT32 :1; + UINT32 Bss2Key1CipherAlg:3; + UINT32 :1; + UINT32 Bss2Key2CipherAlg:3; + UINT32 :1; + UINT32 Bss2Key3CipherAlg:3; + UINT32 :1; + UINT32 Bss3Key0CipherAlg:3; + UINT32 :1; + UINT32 Bss3Key1CipherAlg:3; + UINT32 :1; + UINT32 Bss3Key2CipherAlg:3; + UINT32 :1; + UINT32 Bss3Key3CipherAlg:3; + UINT32 :1; + } field; + UINT32 word; +} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC; + + +// +// HOST_CMD_CSR: For HOST to interrupt embedded processor +// +typedef union _HOST_CMD_CSR_STRUC { + struct { + UINT32 HostCommand:8; + UINT32 Rsv:24; + } field; + UINT32 word; +} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC; + + +// +// AIFSN_CSR: AIFSN for each EDCA AC +// + + + +// +// E2PROM_CSR: EEPROM control register +// +typedef union _E2PROM_CSR_STRUC { + struct { + UINT32 Reload:1; // Reload EEPROM content, write one to reload, self-cleared. + UINT32 EepromSK:1; + UINT32 EepromCS:1; + UINT32 EepromDI:1; + UINT32 EepromDO:1; + UINT32 Type:1; // 1: 93C46, 0:93C66 + UINT32 LoadStatus:1; // 1:loading, 0:done + UINT32 Rsvd:25; + } field; + UINT32 word; +} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC; + +// +// QOS_CSR0: TXOP holder address0 register +// +typedef union _QOS_CSR0_STRUC { + struct { + UCHAR Byte0; // MAC address byte 0 + UCHAR Byte1; // MAC address byte 1 + UCHAR Byte2; // MAC address byte 2 + UCHAR Byte3; // MAC address byte 3 + } field; + UINT32 word; +} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC; + +// +// QOS_CSR1: TXOP holder address1 register +// +typedef union _QOS_CSR1_STRUC { + struct { + UCHAR Byte4; // MAC address byte 4 + UCHAR Byte5; // MAC address byte 5 + UCHAR Rsvd0; + UCHAR Rsvd1; + } field; + UINT32 word; +} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC; + +#define RF_CSR_CFG 0x500 +typedef union _RF_CSR_CFG_STRUC { + struct { + UINT RF_CSR_DATA:8; // DATA + UINT TESTCSR_RFACC_REGNUM:5; // RF register ID + UINT Rsvd2:3; // Reserved + UINT RF_CSR_WR:1; // 0: read 1: write + UINT RF_CSR_KICK:1; // kick RF register read/write + UINT Rsvd1:14; // Reserved + } field; + UINT word; +} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC; + + +// +// Other on-chip shared memory space, base = 0x2000 +// + +// CIS space - base address = 0x2000 +#define HW_CIS_BASE 0x2000 + +// Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function. +#define HW_CS_CTS_BASE 0x7700 +// DFS CTS frame base address. It's where mac stores CTS frame for DFS. +#define HW_DFS_CTS_BASE 0x7780 +#define HW_CTS_FRAME_SIZE 0x80 + +// 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes +// to save debugging settings +#define HW_DEBUG_SETTING_BASE 0x77f0 // 0x77f0~0x77ff total 16 bytes +#define HW_DEBUG_SETTING_BASE2 0x7770 // 0x77f0~0x77ff total 16 bytes + +// In order to support maximum 8 MBSS and its maximum length is 512 for each beacon +// Three section discontinue memory segments will be used. +// 1. The original region for BCN 0~3 +// 2. Extract memory from FCE table for BCN 4~5 +// 3. Extract memory from Pair-wise key table for BCN 6~7 +// It occupied those memory of wcid 238~253 for BCN 6 +// and wcid 222~237 for BCN 7 +#define HW_BEACON_MAX_SIZE 0x1000 /* unit: byte */ +#define HW_BEACON_BASE0 0x7800 +#define HW_BEACON_BASE1 0x7A00 +#define HW_BEACON_BASE2 0x7C00 +#define HW_BEACON_BASE3 0x7E00 +#define HW_BEACON_BASE4 0x7200 +#define HW_BEACON_BASE5 0x7400 +#define HW_BEACON_BASE6 0x5DC0 +#define HW_BEACON_BASE7 0x5BC0 + +#define HW_BEACON_MAX_COUNT 8 +#define HW_BEACON_OFFSET 0x0200 +#define HW_BEACON_CONTENT_LEN (HW_BEACON_OFFSET - TXWI_SIZE) + +// HOST-MCU shared memory - base address = 0x2100 +#define HOST_CMD_CSR 0x404 +#define H2M_MAILBOX_CSR 0x7010 +#define H2M_MAILBOX_CID 0x7014 +#define H2M_MAILBOX_STATUS 0x701c +#define H2M_INT_SRC 0x7024 +#define H2M_BBP_AGENT 0x7028 +#define M2H_CMD_DONE_CSR 0x000c +#define MCU_TXOP_ARRAY_BASE 0x000c // TODO: to be provided by Albert +#define MCU_TXOP_ENTRY_SIZE 32 // TODO: to be provided by Albert +#define MAX_NUM_OF_TXOP_ENTRY 16 // TODO: must be same with 8051 firmware +#define MCU_MBOX_VERSION 0x01 // TODO: to be confirmed by Albert +#define MCU_MBOX_VERSION_OFFSET 5 // TODO: to be provided by Albert + +// +// Host DMA registers - base address 0x200 . TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT, +// +// +// DMA RING DESCRIPTOR +// +#define E2PROM_CSR 0x0004 +#define IO_CNTL_CSR 0x77d0 + + + +// ================================================================ +// Tx / Rx / Mgmt ring descriptor definition +// ================================================================ + +// the following PID values are used to mark outgoing frame type in TXD->PID so that +// proper TX statistics can be collected based on these categories +// b3-2 of PID field - +#define PID_MGMT 0x05 +#define PID_BEACON 0x0c +#define PID_DATA_NORMALUCAST 0x02 +#define PID_DATA_AMPDU 0x04 +#define PID_DATA_NO_ACK 0x08 +#define PID_DATA_NOT_NORM_ACK 0x03 +// value domain of pTxD->HostQId (4-bit: 0~15) +#define QID_AC_BK 1 // meet ACI definition in 802.11e +#define QID_AC_BE 0 // meet ACI definition in 802.11e +#define QID_AC_VI 2 +#define QID_AC_VO 3 +#define QID_HCCA 4 +#define NUM_OF_TX_RING 4 +#define QID_MGMT 13 +#define QID_RX 14 +#define QID_OTHER 15 + +#endif // __RTMP_MAC_H__ // Index: b/drivers/staging/rt2860/chip/rtmp_phy.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/chip/rtmp_phy.h @@ -0,0 +1,405 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rtmp_phy.h + + Abstract: + Ralink Wireless Chip PHY(BBP/RF) related definition & structures + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifndef __RTMP_PHY_H__ +#define __RTMP_PHY_H__ + + +/* + RF sections +*/ +#define RF_R00 0 +#define RF_R01 1 +#define RF_R02 2 +#define RF_R03 3 +#define RF_R04 4 +#define RF_R05 5 +#define RF_R06 6 +#define RF_R07 7 +#define RF_R08 8 +#define RF_R09 9 +#define RF_R10 10 +#define RF_R11 11 +#define RF_R12 12 +#define RF_R13 13 +#define RF_R14 14 +#define RF_R15 15 +#define RF_R16 16 +#define RF_R17 17 +#define RF_R18 18 +#define RF_R19 19 +#define RF_R20 20 +#define RF_R21 21 +#define RF_R22 22 +#define RF_R23 23 +#define RF_R24 24 +#define RF_R25 25 +#define RF_R26 26 +#define RF_R27 27 +#define RF_R28 28 +#define RF_R29 29 +#define RF_R30 30 +#define RF_R31 31 + + +// value domain of pAd->RfIcType +#define RFIC_2820 1 // 2.4G 2T3R +#define RFIC_2850 2 // 2.4G/5G 2T3R +#define RFIC_2720 3 // 2.4G 1T2R +#define RFIC_2750 4 // 2.4G/5G 1T2R +#define RFIC_3020 5 // 2.4G 1T1R +#define RFIC_2020 6 // 2.4G B/G +#define RFIC_3021 7 // 2.4G 1T2R +#define RFIC_3022 8 // 2.4G 2T2R +#define RFIC_3052 9 // 2.4G/5G 2T2R + +/* + BBP sections +*/ +#define BBP_R0 0 // version +#define BBP_R1 1 // TSSI +#define BBP_R2 2 // TX configure +#define BBP_R3 3 +#define BBP_R4 4 +#define BBP_R5 5 +#define BBP_R6 6 +#define BBP_R14 14 // RX configure +#define BBP_R16 16 +#define BBP_R17 17 // RX sensibility +#define BBP_R18 18 +#define BBP_R21 21 +#define BBP_R22 22 +#define BBP_R24 24 +#define BBP_R25 25 +#define BBP_R26 26 +#define BBP_R27 27 +#define BBP_R31 31 +#define BBP_R49 49 //TSSI +#define BBP_R50 50 +#define BBP_R51 51 +#define BBP_R52 52 +#define BBP_R55 55 +#define BBP_R62 62 // Rx SQ0 Threshold HIGH +#define BBP_R63 63 +#define BBP_R64 64 +#define BBP_R65 65 +#define BBP_R66 66 +#define BBP_R67 67 +#define BBP_R68 68 +#define BBP_R69 69 +#define BBP_R70 70 // Rx AGC SQ CCK Xcorr threshold +#define BBP_R73 73 +#define BBP_R75 75 +#define BBP_R77 77 +#define BBP_R78 78 +#define BBP_R79 79 +#define BBP_R80 80 +#define BBP_R81 81 +#define BBP_R82 82 +#define BBP_R83 83 +#define BBP_R84 84 +#define BBP_R86 86 +#define BBP_R91 91 +#define BBP_R92 92 +#define BBP_R94 94 // Tx Gain Control +#define BBP_R103 103 +#define BBP_R105 105 +#define BBP_R106 106 +#define BBP_R113 113 +#define BBP_R114 114 +#define BBP_R115 115 +#define BBP_R116 116 +#define BBP_R117 117 +#define BBP_R118 118 +#define BBP_R119 119 +#define BBP_R120 120 +#define BBP_R121 121 +#define BBP_R122 122 +#define BBP_R123 123 +#ifdef RT30xx +#define BBP_R138 138 // add by johnli, RF power sequence setup, ADC dynamic on/off control +#endif // RT30xx // + +#define BBPR94_DEFAULT 0x06 // Add 1 value will gain 1db + +// +// BBP & RF are using indirect access. Before write any value into it. +// We have to make sure there is no outstanding command pending via checking busy bit. +// +#define MAX_BUSY_COUNT 100 // Number of retry before failing access BBP & RF indirect register + +//#define PHY_TR_SWITCH_TIME 5 // usec + +//#define BBP_R17_LOW_SENSIBILITY 0x50 +//#define BBP_R17_MID_SENSIBILITY 0x41 +//#define BBP_R17_DYNAMIC_UP_BOUND 0x40 + +#define RSSI_FOR_VERY_LOW_SENSIBILITY -35 +#define RSSI_FOR_LOW_SENSIBILITY -58 +#define RSSI_FOR_MID_LOW_SENSIBILITY -80 +#define RSSI_FOR_MID_SENSIBILITY -90 + +/***************************************************************************** + RF register Read/Write marco definition + *****************************************************************************/ +#ifdef RTMP_MAC_PCI +#define RTMP_RF_IO_WRITE32(_A, _V) \ +{ \ + if ((_A)->bPCIclkOff == FALSE) \ + { \ + PHY_CSR4_STRUC _value; \ + ULONG _busyCnt = 0; \ + \ + do { \ + RTMP_IO_READ32((_A), RF_CSR_CFG0, &_value.word); \ + if (_value.field.Busy == IDLE) \ + break; \ + _busyCnt++; \ + }while (_busyCnt < MAX_BUSY_COUNT); \ + if(_busyCnt < MAX_BUSY_COUNT) \ + { \ + RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V)); \ + } \ + } \ +} +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB +#define RTMP_RF_IO_WRITE32(_A, _V) RTUSBWriteRFRegister(_A, _V) +#endif // RTMP_MAC_USB // + +#ifdef RT30xx +#define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RT30xxReadRFRegister(_A, _I, _pV) +#define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RT30xxWriteRFRegister(_A, _I, _V) +#endif // RT30xx // + +/***************************************************************************** + BBP register Read/Write marco definitions. + we read/write the bbp value by register's ID. + Generate PER to test BA + *****************************************************************************/ +#ifdef RTMP_MAC_PCI +/* + basic marco for BBP read operation. + _pAd: the data structure pointer of RTMP_ADAPTER + _bbpID : the bbp register ID + _pV: data pointer used to save the value of queried bbp register. + _bViaMCU: if we need access the bbp via the MCU. +*/ +#define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU) \ + do{ \ + BBP_CSR_CFG_STRUC BbpCsr; \ + int _busyCnt, _secCnt, _regID; \ + \ + _regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \ + for (_busyCnt=0; _busyCntBbpWriteLatch[_bbpID]; \ + if ((_bViaMCU) == TRUE) \ + { \ + RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \ + BbpCsr.field.Busy = 0; \ + RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word); \ + } \ + } \ + }while(0) + +/* + This marco used for the BBP read operation which didn't need via MCU. +*/ +#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \ + RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE) + +/* + This marco used for the BBP read operation which need via MCU. + But for some chipset which didn't have mcu (e.g., RBUS based chipset), we + will use this function too and didn't access the bbp register via the MCU. +*/ +#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \ + do{ \ + if ((_A)->bPCIclkOff == FALSE) \ + { \ + if ((_A)->infType == RTMP_DEV_INF_RBUS) \ + RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE); \ + else \ + RTMP_BBP_IO_READ8((_A), (_I), (_pV), TRUE); \ + } \ + }while(0) + + +/* + basic marco for BBP write operation. + _pAd: the data structure pointer of RTMP_ADAPTER + _bbpID : the bbp register ID + _pV: data used to save the value of queried bbp register. + _bViaMCU: if we need access the bbp via the MCU. +*/ +#define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU) \ + do{ \ + BBP_CSR_CFG_STRUC BbpCsr; \ + int _busyCnt, _regID; \ + \ + _regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \ + for (_busyCnt=0; _busyCntOpMode == OPMODE_AP) \ + RTMPusecDelay(1000); \ + } \ + (_pAd)->BbpWriteLatch[_bbpID] = _pV; \ + break; \ + } \ + if (_busyCnt == MAX_BUSY_COUNT) \ + { \ + DBGPRINT_ERR(("BBP write R%d fail\n", _bbpID)); \ + if((_bViaMCU) == TRUE) \ + { \ + RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word); \ + BbpCsr.field.Busy = 0; \ + RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, BbpCsr.word); \ + } \ + } \ + }while(0) + + +/* + This marco used for the BBP write operation which didn't need via MCU. +*/ +#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV) \ + RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE) + +/* + This marco used for the BBP write operation which need via MCU. + But for some chipset which didn't have mcu (e.g., RBUS based chipset), we + will use this function too and didn't access the bbp register via the MCU. +*/ +#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV) \ + do{ \ + if ((_A)->bPCIclkOff == FALSE) \ + { \ + if ((_A)->infType == RTMP_DEV_INF_RBUS) \ + RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE); \ + else \ + RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), TRUE); \ + } \ + }while(0) + +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB +#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV) +#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V) + +#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V) +#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV) +#endif // RTMP_MAC_USB // + +#ifdef RT30xx +#define RTMP_ASIC_MMPS_DISABLE(_pAd) \ + do{ \ + UCHAR _bbpData; \ + UINT32 _macData; \ + /* disable MMPS BBP control register */ \ + RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData); \ + _bbpData &= ~(0x04); /*bit 2*/ \ + RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \ + \ + /* disable MMPS MAC control register */ \ + RTMP_IO_READ32(_pAd, 0x1210, &_macData); \ + _macData &= ~(0x09); /*bit 0, 3*/ \ + RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \ + }while(0) + + +#define RTMP_ASIC_MMPS_ENABLE(_pAd) \ + do{ \ + UCHAR _bbpData; \ + UINT32 _macData; \ + /* enable MMPS BBP control register */ \ + RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData); \ + _bbpData |= (0x04); /*bit 2*/ \ + RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData); \ + \ + /* enable MMPS MAC control register */ \ + RTMP_IO_READ32(_pAd, 0x1210, &_macData); \ + _macData |= (0x09); /*bit 0, 3*/ \ + RTMP_IO_WRITE32(_pAd, 0x1210, _macData); \ + }while(0) + +#endif // RT30xx // + +#endif // __RTMP_PHY_H__ // Index: b/drivers/staging/rt2860/chips/rt3070.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/chips/rt3070.c @@ -0,0 +1,185 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rt3070.c + + Abstract: + Specific funcitons and variables for RT3070 + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifdef RT3070 + +#include "../rt_config.h" + + +#ifndef RTMP_RF_RW_SUPPORT +#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip" +#endif // RTMP_RF_RW_SUPPORT // + + +VOID NICInitRT3070RFRegisters(IN PRTMP_ADAPTER pAd) +{ + INT i; + UCHAR RFValue; + + // Driver must read EEPROM to get RfIcType before initial RF registers + // Initialize RF register to default value + if (IS_RT3070(pAd) || IS_RT3071(pAd)) + { + // Init RF calibration + // Driver should toggle RF R30 bit7 before init RF registers + UINT32 RfReg = 0; + UINT32 data; + + RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg); + RfReg |= 0x80; + RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg); + RTMPusecDelay(1000); + RfReg &= 0x7F; + RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg); + + // Initialize RF register to default value + for (i = 0; i < NUM_RF_REG_PARMS; i++) + { + RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value); + } + + // add by johnli + if (IS_RT3070(pAd)) + { + // + // The DAC issue(LDO_CFG0) has been fixed in RT3070(F). + // The voltage raising patch is no longer needed for RT3070(F) + // + if ((pAd->MACVersion & 0xffff) < 0x0201) + { + // Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate + RTUSBReadMACRegister(pAd, LDO_CFG0, &data); + data = ((data & 0xF0FFFFFF) | 0x0D000000); + RTUSBWriteMACRegister(pAd, LDO_CFG0, data); + } + } + else if (IS_RT3071(pAd)) + { + // Driver should set RF R6 bit6 on before init RF registers + RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg); + RfReg |= 0x40; + RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg); + + // init R31 + RT30xxWriteRFRegister(pAd, RF_R31, 0x14); + + // RT3071 version E has fixed this issue + if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211)) + { + // patch tx EVM issue temporarily + RTUSBReadMACRegister(pAd, LDO_CFG0, &data); + data = ((data & 0xE0FFFFFF) | 0x0D000000); + RTUSBWriteMACRegister(pAd, LDO_CFG0, data); + } + else + { + RTMP_IO_READ32(pAd, LDO_CFG0, &data); + data = ((data & 0xE0FFFFFF) | 0x01000000); + RTMP_IO_WRITE32(pAd, LDO_CFG0, data); + } + + // patch LNA_PE_G1 failed issue + RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data); + data &= ~(0x20); + RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data); + } + + //For RF filter Calibration + RTMPFilterCalibration(pAd); + + // Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration() + // + // TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). + // Raising RF voltage is no longer needed for RT3070(F) + // + if ((IS_RT3070(pAd)) && ((pAd->MACVersion & 0xffff) < 0x0201)) + { + RT30xxWriteRFRegister(pAd, RF_R27, 0x3); + } + else if ((IS_RT3071(pAd)) && ((pAd->MACVersion & 0xffff) < 0x0211)) + { + RT30xxWriteRFRegister(pAd, RF_R27, 0x3); + } + + // set led open drain enable + RTUSBReadMACRegister(pAd, OPT_14, &data); + data |= 0x01; + RTUSBWriteMACRegister(pAd, OPT_14, data); + + // move from RT30xxLoadRFNormalModeSetup because it's needed for both RT3070 and RT3071 + // TX_LO1_en, RF R17 register Bit 3 to 0 + RT30xxReadRFRegister(pAd, RF_R17, &RFValue); + RFValue &= (~0x08); + // to fix rx long range issue + if (pAd->NicConfig2.field.ExternalLNAForG == 0) + { + if ((IS_RT3071(pAd) && ((pAd->MACVersion & 0xffff) >= 0x0211)) || IS_RT3070(pAd)) + { + RFValue |= 0x20; + } + } + // set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h + if (pAd->TxMixerGain24G >= 1) + { + RFValue &= (~0x7); // clean bit [2:0] + RFValue |= pAd->TxMixerGain24G; + } + RT30xxWriteRFRegister(pAd, RF_R17, RFValue); + + if (IS_RT3071(pAd)) + { + // add by johnli, RF power sequence setup, load RF normal operation-mode setup + RT30xxLoadRFNormalModeSetup(pAd); + } + else if (IS_RT3070(pAd)) + { + /* add by johnli, reset RF_R27 when interface down & up to fix throughput problem*/ + // LDORF_VC, RF R27 register Bit 2 to 0 + RT30xxReadRFRegister(pAd, RF_R27, &RFValue); + // TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). + // Raising RF voltage is no longer needed for RT3070(F) + if ((pAd->MACVersion & 0xffff) < 0x0201) + RFValue = (RFValue & (~0x77)) | 0x3; + else + RFValue = (RFValue & (~0x77)); + RT30xxWriteRFRegister(pAd, RF_R27, RFValue); + /* end johnli */ + } + } + +} +#endif // RT3070 // Index: b/drivers/staging/rt2860/chips/rt30xx.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/chips/rt30xx.c @@ -0,0 +1,525 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rt30xx.c + + Abstract: + Specific funcitons and variables for RT30xx. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + + +#ifdef RT30xx + + +#ifndef RTMP_RF_RW_SUPPORT +#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip" +#endif // RTMP_RF_RW_SUPPORT // + +#include "../rt_config.h" + + +// +// RF register initialization set +// +REG_PAIR RT30xx_RFRegTable[] = { + {RF_R04, 0x40}, + {RF_R05, 0x03}, + {RF_R06, 0x02}, + {RF_R07, 0x70}, + {RF_R09, 0x0F}, + {RF_R10, 0x41}, + {RF_R11, 0x21}, + {RF_R12, 0x7B}, + {RF_R14, 0x90}, + {RF_R15, 0x58}, + {RF_R16, 0xB3}, + {RF_R17, 0x92}, + {RF_R18, 0x2C}, + {RF_R19, 0x02}, + {RF_R20, 0xBA}, + {RF_R21, 0xDB}, + {RF_R24, 0x16}, + {RF_R25, 0x01}, + {RF_R29, 0x1F}, +}; + +UCHAR NUM_RF_REG_PARMS = (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR)); + + + +// Antenna divesity use GPIO3 and EESK pin for control +// Antenna and EEPROM access are both using EESK pin, +// Therefor we should avoid accessing EESK at the same time +// Then restore antenna after EEPROM access +// The original name of this function is AsicSetRxAnt(), now change to +//VOID AsicSetRxAnt( +VOID RT30xxSetRxAnt( + IN PRTMP_ADAPTER pAd, + IN UCHAR Ant) +{ + UINT32 Value; + UINT32 x; + + if ((pAd->EepromAccess) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) || + (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + return; + } + + // the antenna selection is through firmware and MAC register(GPIO3) + if (Ant == 0) + { + // Main antenna + AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x1, 0x0); + + RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); + Value &= ~(0x0808); + RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n")); + } + else + { + // Aux antenna + AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x0, 0x0); + RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); + Value &= ~(0x0808); + Value |= 0x08; + RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n")); + } +} + + +/* + ======================================================================== + + Routine Description: + For RF filter calibration purpose + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + + ======================================================================== +*/ +VOID RTMPFilterCalibration( + IN PRTMP_ADAPTER pAd) +{ + UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue=0; + UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0; + UCHAR RF_R24_Value = 0; + + // Give bbp filter initial value + pAd->Mlme.CaliBW20RfR24 = 0x1F; + pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40 + + do + { + if (loop == 1) //BandWidth = 40 MHz + { + // Write 0x27 to RF_R24 to program filter + RF_R24_Value = 0x27; + RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); + if (IS_RT3090(pAd) || IS_RT3572(pAd)|| IS_RT3390(pAd)) + FilterTarget = 0x15; + else + FilterTarget = 0x19; + + // when calibrate BW40, BBP mask must set to BW40. + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue&= (~0x18); + BBPValue|= (0x10); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + + // set to BW40 + RT30xxReadRFRegister(pAd, RF_R31, &value); + value |= 0x20; + RT30xxWriteRFRegister(pAd, RF_R31, value); + } + else //BandWidth = 20 MHz + { + // Write 0x07 to RF_R24 to program filter + RF_R24_Value = 0x07; + RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); + if (IS_RT3090(pAd) || IS_RT3572(pAd)|| IS_RT3390(pAd)) + FilterTarget = 0x13; + else + FilterTarget = 0x16; + + // set to BW20 + RT30xxReadRFRegister(pAd, RF_R31, &value); + value &= (~0x20); + RT30xxWriteRFRegister(pAd, RF_R31, value); + } + + // Write 0x01 to RF_R22 to enable baseband loopback mode + RT30xxReadRFRegister(pAd, RF_R22, &value); + value |= 0x01; + RT30xxWriteRFRegister(pAd, RF_R22, value); + + // Write 0x00 to BBP_R24 to set power & frequency of passband test tone + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0); + + do + { + // Write 0x90 to BBP_R25 to transmit test tone + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90); + + RTMPusecDelay(1000); + // Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0] + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value); + R55x = value & 0xFF; + + } while ((ReTry++ < 100) && (R55x == 0)); + + // Write 0x06 to BBP_R24 to set power & frequency of stopband test tone + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06); + + while(TRUE) + { + // Write 0x90 to BBP_R25 to transmit test tone + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90); + + //We need to wait for calibration + RTMPusecDelay(1000); + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value); + value &= 0xFF; + if ((R55x - value) < FilterTarget) + { + RF_R24_Value ++; + } + else if ((R55x - value) == FilterTarget) + { + RF_R24_Value ++; + count ++; + } + else + { + break; + } + + // prevent infinite loop cause driver hang. + if (loopcnt++ > 100) + { + DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt)); + break; + } + + // Write RF_R24 to program filter + RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); + } + + if (count > 0) + { + RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0)); + } + + // Store for future usage + if (loopcnt < 100) + { + if (loop++ == 0) + { + //BandWidth = 20 MHz + pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value; + } + else + { + //BandWidth = 40 MHz + pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value; + break; + } + } + else + break; + + RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); + + // reset count + count = 0; + } while(TRUE); + + // + // Set back to initial state + // + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0); + + RT30xxReadRFRegister(pAd, RF_R22, &value); + value &= ~(0x01); + RT30xxWriteRFRegister(pAd, RF_R22, value); + + // set BBP back to BW20 + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue&= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + + DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24)); +} + + +// add by johnli, RF power sequence setup +/* + ========================================================================== + Description: + + Load RF normal operation-mode setup + + ========================================================================== + */ +VOID RT30xxLoadRFNormalModeSetup( + IN PRTMP_ADAPTER pAd) +{ + UCHAR RFValue; + + // RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1 + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + RFValue = (RFValue & (~0x0C)) | 0x31; + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + + // TX_LO2_en, RF R15 register Bit 3 to 0 + RT30xxReadRFRegister(pAd, RF_R15, &RFValue); + RFValue &= (~0x08); + RT30xxWriteRFRegister(pAd, RF_R15, RFValue); + + /* move to NICInitRT30xxRFRegisters + // TX_LO1_en, RF R17 register Bit 3 to 0 + RT30xxReadRFRegister(pAd, RF_R17, &RFValue); + RFValue &= (~0x08); + // to fix rx long range issue + if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0)) + { + RFValue |= 0x20; + } + // set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h + if (pAd->TxMixerGain24G >= 2) + { + RFValue &= (~0x7); // clean bit [2:0] + RFValue |= pAd->TxMixerGain24G; + } + RT30xxWriteRFRegister(pAd, RF_R17, RFValue); + */ + + // RX_LO1_en, RF R20 register Bit 3 to 0 + RT30xxReadRFRegister(pAd, RF_R20, &RFValue); + RFValue &= (~0x08); + RT30xxWriteRFRegister(pAd, RF_R20, RFValue); + + // RX_LO2_en, RF R21 register Bit 3 to 0 + RT30xxReadRFRegister(pAd, RF_R21, &RFValue); + RFValue &= (~0x08); + RT30xxWriteRFRegister(pAd, RF_R21, RFValue); + + /* add by johnli, reset RF_R27 when interface down & up to fix throughput problem*/ + // LDORF_VC, RF R27 register Bit 2 to 0 + RT30xxReadRFRegister(pAd, RF_R27, &RFValue); + // TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). + // Raising RF voltage is no longer needed for RT3070(F) + if (IS_RT3090(pAd)) // RT309x and RT3071/72 + { + if ((pAd->MACVersion & 0xffff) < 0x0211) + RFValue = (RFValue & (~0x77)) | 0x3; + else + RFValue = (RFValue & (~0x77)); + RT30xxWriteRFRegister(pAd, RF_R27, RFValue); + } + /* end johnli */ +} + +/* + ========================================================================== + Description: + + Load RF sleep-mode setup + + ========================================================================== + */ +VOID RT30xxLoadRFSleepModeSetup( + IN PRTMP_ADAPTER pAd) +{ + UCHAR RFValue; + UINT32 MACValue; + + +#ifdef RTMP_MAC_USB + if(!IS_RT3572(pAd)) +#endif // RTMP_MAC_USB // + { + // RF_BLOCK_en. RF R1 register Bit 0 to 0 + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + RFValue &= (~0x01); + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + + // VCO_IC, RF R7 register Bit 4 & Bit 5 to 0 + RT30xxReadRFRegister(pAd, RF_R07, &RFValue); + RFValue &= (~0x30); + RT30xxWriteRFRegister(pAd, RF_R07, RFValue); + + // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0 + RT30xxReadRFRegister(pAd, RF_R09, &RFValue); + RFValue &= (~0x0E); + RT30xxWriteRFRegister(pAd, RF_R09, RFValue); + + // RX_CTB_en, RF R21 register Bit 7 to 0 + RT30xxReadRFRegister(pAd, RF_R21, &RFValue); + RFValue &= (~0x80); + RT30xxWriteRFRegister(pAd, RF_R21, RFValue); + } + + if (IS_RT3090(pAd) || // IS_RT3090 including RT309x and RT3071/72 + IS_RT3572(pAd) || + (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) + { +#ifdef RTMP_MAC_USB + if (!IS_RT3572(pAd)) +#endif // RTMP_MAC_USB // + { + RT30xxReadRFRegister(pAd, RF_R27, &RFValue); + RFValue |= 0x77; + RT30xxWriteRFRegister(pAd, RF_R27, RFValue); + } + + RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); + MACValue |= 0x1D000000; + RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); + } +} + +/* + ========================================================================== + Description: + + Reverse RF sleep-mode setup + + ========================================================================== + */ +VOID RT30xxReverseRFSleepModeSetup( + IN PRTMP_ADAPTER pAd) +{ + UCHAR RFValue; + UINT32 MACValue; + +#ifdef RTMP_MAC_USB + if(!IS_RT3572(pAd)) +#endif // RTMP_MAC_USB // + { + // RF_BLOCK_en, RF R1 register Bit 0 to 1 + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + RFValue |= 0x01; + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + + // VCO_IC, RF R7 register Bit 4 & Bit 5 to 1 + RT30xxReadRFRegister(pAd, RF_R07, &RFValue); + RFValue |= 0x30; + RT30xxWriteRFRegister(pAd, RF_R07, RFValue); + + // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1 + RT30xxReadRFRegister(pAd, RF_R09, &RFValue); + RFValue |= 0x0E; + RT30xxWriteRFRegister(pAd, RF_R09, RFValue); + + // RX_CTB_en, RF R21 register Bit 7 to 1 + RT30xxReadRFRegister(pAd, RF_R21, &RFValue); + RFValue |= 0x80; + RT30xxWriteRFRegister(pAd, RF_R21, RFValue); + } + + if (IS_RT3090(pAd) || // IS_RT3090 including RT309x and RT3071/72 + IS_RT3572(pAd) || + IS_RT3390(pAd) || + (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) + { +#ifdef RTMP_MAC_USB + if (!IS_RT3572(pAd)) +#endif // RTMP_MAC_USB // + { + RT30xxReadRFRegister(pAd, RF_R27, &RFValue); + if ((pAd->MACVersion & 0xffff) < 0x0211) + RFValue = (RFValue & (~0x77)) | 0x3; + else + RFValue = (RFValue & (~0x77)); + RT30xxWriteRFRegister(pAd, RF_R27, RFValue); + } + + // RT3071 version E has fixed this issue + if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211)) + { + // patch tx EVM issue temporarily + RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); + MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000); + RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); + } + else + { + RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); + MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000); + RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); + } + } + + if(IS_RT3572(pAd)) + RT30xxWriteRFRegister(pAd, RF_R08, 0x80); +} +// end johnli + +VOID RT30xxHaltAction( + IN PRTMP_ADAPTER pAd) +{ + UINT32 TxPinCfg = 0x00050F0F; + + // + // Turn off LNA_PE or TRSW_POL + // + if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)) + { + if ((IS_RT3071(pAd) || IS_RT3572(pAd)) +#ifdef RTMP_EFUSE_SUPPORT + && (pAd->bUseEfuse) +#endif // RTMP_EFUSE_SUPPORT // + ) + { + TxPinCfg &= 0xFFFBF0F0; // bit18 off + } + else + { + TxPinCfg &= 0xFFFFF0F0; + } + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + } +} + +#endif // RT30xx // Index: b/drivers/staging/rt2860/chlist.h =================================================================== --- a/drivers/staging/rt2860/chlist.h +++ b/drivers/staging/rt2860/chlist.h @@ -64,1182 +64,65 @@ typedef struct _CH_REGION { CH_DESP ChDesp[10]; } CH_REGION, *PCH_REGION; -static CH_REGION ChRegion[] = -{ - { // Antigua and Berbuda - "AG", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 - { 0}, // end - } - }, +extern CH_REGION ChRegion[]; - { // Argentina - "AR", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, +typedef struct _CH_FREQ_MAP_{ + UINT16 channel; + UINT16 freqKHz; +}CH_FREQ_MAP; + +extern CH_FREQ_MAP CH_HZ_ID_MAP[]; +extern int CH_HZ_ID_MAP_NUM; + + +#define MAP_CHANNEL_ID_TO_KHZ(_ch, _khz) \ + do{ \ + int _chIdx; \ + for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\ + { \ + if ((_ch) == CH_HZ_ID_MAP[_chIdx].channel) \ + { \ + (_khz) = CH_HZ_ID_MAP[_chIdx].freqKHz * 1000; \ + break; \ + } \ + } \ + if (_chIdx == CH_HZ_ID_MAP_NUM) \ + (_khz) = 2412000; \ + }while(0) + +#define MAP_KHZ_TO_CHANNEL_ID(_khz, _ch) \ + do{ \ + int _chIdx; \ + for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++)\ + { \ + if ((_khz) == CH_HZ_ID_MAP[_chIdx].freqKHz) \ + { \ + (_ch) = CH_HZ_ID_MAP[_chIdx].channel; \ + break; \ + } \ + } \ + if (_chIdx == CH_HZ_ID_MAP_NUM) \ + (_ch) = 1; \ + }while(0) - { // Aruba - "AW", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 - { 0}, // end - } - }, - { // Australia - "AU", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165 - { 0}, // end - } - }, +VOID BuildChannelListEx( + IN PRTMP_ADAPTER pAd); - { // Austria - "AT", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Bahamas - "BS", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165 - { 0}, // end - } - }, - - { // Barbados - "BB", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Bermuda - "BM", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Brazil - "BR", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 100, 11, 24, BOTH, FALSE}, // 5G, ch 100~140 - { 149, 5, 30, BOTH, FALSE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Belgium - "BE", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 18, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 18, IDOR, FALSE}, // 5G, ch 52~64 - { 0}, // end - } - }, - - { // Bulgaria - "BG", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Canada - "CA", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165 - { 0}, // end - } - }, - - { // Cayman IsLands - "KY", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Chile - "CL", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165 - { 0}, // end - } - }, - - { // China - "CN", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Colombia - "CO", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 - { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165 - { 0}, // end - } - }, - - { // Costa Rica - "CR", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Cyprus - "CY", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Czech_Republic - "CZ", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 0}, // end - } - }, - - { // Denmark - "DK", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Dominican Republic - "DO", - CE, - { - { 1, 0, 20, BOTH, FALSE}, // 2.4 G, ch 0 - { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Equador - "EC", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 100, 11, 27, BOTH, FALSE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // El Salvador - "SV", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 30, BOTH, TRUE}, // 5G, ch 52~64 - { 149, 4, 36, BOTH, TRUE}, // 5G, ch 149~165 - { 0}, // end - } - }, - - { // Finland - "FI", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // France - "FR", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 0}, // end - } - }, - - { // Germany - "DE", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Greece - "GR", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Guam - "GU", - CE, - { - { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 - { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 - { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165 - { 0}, // end - } - }, - - { // Guatemala - "GT", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Haiti - "HT", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Honduras - "HN", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Hong Kong - "HK", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64 - { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Hungary - "HU", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 0}, // end - } - }, - - { // Iceland - "IS", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // India - "IN", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 149, 4, 24, IDOR, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Indonesia - "ID", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Ireland - "IE", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Israel - "IL", - CE, - { - { 1, 3, 20, IDOR, FALSE}, // 2.4 G, ch 1~3 - { 4, 6, 20, BOTH, FALSE}, // 2.4 G, ch 4~9 - { 10, 4, 20, IDOR, FALSE}, // 2.4 G, ch 10~13 - { 0}, // end - } - }, - - { // Italy - "IT", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Japan - "JP", - JAP, - { - { 1, 14, 20, BOTH, FALSE}, // 2.4 G, ch 1~14 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 0}, // end - } - }, - - { // Jordan - "JO", - CE, - { - { 1, 13, 20, IDOR, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 149, 4, 23, IDOR, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Latvia - "LV", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Liechtenstein - "LI", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Lithuania - "LT", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Luxemburg - "LU", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Malaysia - "MY", - CE, - { - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165 - { 0}, // end - } - }, - - { // Malta - "MT", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Marocco - "MA", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48 - { 0}, // end - } - }, - - { // Mexico - "MX", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 5, 30, IDOR, FALSE}, // 5G, ch 149~165 - { 0}, // end - } - }, - - { // Netherlands - "NL", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // New Zealand - "NZ", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 24, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Norway - "NO", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Peru - "PE", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Portugal - "PT", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Poland - "PL", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Romania - "RO", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Russia - "RU", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 149, 4, 20, IDOR, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Saudi Arabia - "SA", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 4, 23, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Serbia_and_Montenegro - "CS", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 0}, // end - } - }, - - { // Singapore - "SG", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 - { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Slovakia - "SK", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Slovenia - "SI", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 0}, // end - } - }, - - { // South Africa - "ZA", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // South Korea - "KR", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64 - { 100, 8, 20, BOTH, FALSE}, // 5G, ch 100~128 - { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Spain - "ES", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 17, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Sweden - "SE", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Switzerland - "CH", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 - { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 0}, // end - } - }, - - { // Taiwan - "TW", - CE, - { - { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11 - { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64 - { 0}, // end - } - }, - - { // Turkey - "TR", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 - { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 - { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 - { 0}, // end - } - }, - - { // UK - "GB", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 - { 36, 4, 23, IDOR, FALSE}, // 5G, ch 52~64 - { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 0}, // end - } - }, - - { // Ukraine - "UA", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 - { 0}, // end - } - }, - - { // United_Arab_Emirates - "AE", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 - { 0}, // end - } - }, - - { // United_States - "US", - CE, - { - { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11 - { 36, 4, 17, IDOR, FALSE}, // 5G, ch 52~64 - { 52, 4, 24, BOTH, TRUE}, // 5G, ch 52~64 - { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 - { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165 - { 0}, // end - } - }, - - { // Venezuela - "VE", - CE, - { - { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 - { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161 - { 0}, // end - } - }, - - { // Default - "", - CE, - { - { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 - { 36, 4, 20, BOTH, FALSE}, // 5G, ch 52~64 - { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64 - { 100, 11, 20, BOTH, FALSE}, // 5G, ch 100~140 - { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165 - { 0}, // end - } - }, -}; - -static inline PCH_REGION GetChRegion( - IN PUCHAR CntryCode) -{ - INT loop = 0; - PCH_REGION pChRegion = NULL; - - while (strcmp(ChRegion[loop].CountReg, "") != 0) - { - if (strncmp(ChRegion[loop].CountReg, CntryCode, 2) == 0) - { - pChRegion = &ChRegion[loop]; - break; - } - loop++; - } - - if (pChRegion == NULL) - pChRegion = &ChRegion[loop]; - return pChRegion; -} - -static inline VOID ChBandCheck( - IN UCHAR PhyMode, - OUT PUCHAR pChType) -{ - switch(PhyMode) - { - case PHY_11A: - case PHY_11AN_MIXED: - *pChType = BAND_5G; - break; - case PHY_11ABG_MIXED: - case PHY_11AGN_MIXED: - case PHY_11ABGN_MIXED: - *pChType = BAND_BOTH; - break; - - default: - *pChType = BAND_24G; - break; - } -} - -static inline UCHAR FillChList( - IN PRTMP_ADAPTER pAd, - IN PCH_DESP pChDesp, - IN UCHAR Offset, - IN UCHAR increment) -{ - INT i, j, l; - UCHAR channel; - - j = Offset; - for (i = 0; i < pChDesp->NumOfCh; i++) - { - channel = pChDesp->FirstChannel + i * increment; - for (l=0; lTxPower[l].Channel) - { - pAd->ChannelList[j].Power = pAd->TxPower[l].Power; - pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2; - break; - } - } - if (l == MAX_NUM_OF_CHANNELS) - continue; - - pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment; - pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr; - pAd->ChannelList[j].DfsReq = pChDesp->DfsReq; - j++; - } - pAd->ChannelListNum = j; - - return j; -} - -static inline VOID CreateChList( - IN PRTMP_ADAPTER pAd, - IN PCH_REGION pChRegion, - IN UCHAR Geography) -{ - INT i; - UCHAR offset = 0; - PCH_DESP pChDesp; - UCHAR ChType; - UCHAR increment; - - if (pChRegion == NULL) - return; - - ChBandCheck(pAd->CommonCfg.PhyMode, &ChType); - - for (i=0; i<10; i++) - { - pChDesp = &pChRegion->ChDesp[i]; - if (pChDesp->FirstChannel == 0) - break; - - if (ChType == BAND_5G) - { - if (pChDesp->FirstChannel <= 14) - continue; - } - else if (ChType == BAND_24G) - { - if (pChDesp->FirstChannel > 14) - continue; - } - - if ((pChDesp->Geography == BOTH) - || (pChDesp->Geography == Geography)) - { - if (pChDesp->FirstChannel > 14) - increment = 4; - else - increment = 1; - offset = FillChList(pAd, pChDesp, offset, increment); - } - } -} - -static inline VOID BuildChannelListEx( - IN PRTMP_ADAPTER pAd) -{ - PCH_REGION pChReg; - - pChReg = GetChRegion(pAd->CommonCfg.CountryCode); - CreateChList(pAd, pChReg, pAd->CommonCfg.Geography); -} - -static inline VOID BuildBeaconChList( +VOID BuildBeaconChList( IN PRTMP_ADAPTER pAd, OUT PUCHAR pBuf, - OUT PULONG pBufLen) -{ - INT i; - ULONG TmpLen; - PCH_REGION pChRegion; - PCH_DESP pChDesp; - UCHAR ChType; - - pChRegion = GetChRegion(pAd->CommonCfg.CountryCode); - - if (pChRegion == NULL) - return; - - ChBandCheck(pAd->CommonCfg.PhyMode, &ChType); - *pBufLen = 0; - - for (i=0; i<10; i++) - { - pChDesp = &pChRegion->ChDesp[i]; - if (pChDesp->FirstChannel == 0) - break; - - if (ChType == BAND_5G) - { - if (pChDesp->FirstChannel <= 14) - continue; - } - else if (ChType == BAND_24G) - { - if (pChDesp->FirstChannel > 14) - continue; - } - - if ((pChDesp->Geography == BOTH) - || (pChDesp->Geography == pAd->CommonCfg.Geography)) - { - MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen, - 1, &pChDesp->FirstChannel, - 1, &pChDesp->NumOfCh, - 1, &pChDesp->MaxTxPwr, - END_OF_ARGS); - *pBufLen += TmpLen; - } - } -} - -static inline BOOLEAN IsValidChannel( - IN PRTMP_ADAPTER pAd, - IN UCHAR channel) - -{ - INT i; - - for (i = 0; i < pAd->ChannelListNum; i++) - { - if (pAd->ChannelList[i].Channel == channel) - break; - } - - if (i == pAd->ChannelListNum) - return FALSE; - else - return TRUE; -} - - -static inline UCHAR GetExtCh( - IN UCHAR Channel, - IN UCHAR Direction) -{ - CHAR ExtCh; - - if (Direction == EXTCHA_ABOVE) - ExtCh = Channel + 4; - else - ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0; - - return ExtCh; -} - - -static inline VOID N_ChannelCheck( - IN PRTMP_ADAPTER pAd) -{ - //UCHAR ChannelNum = pAd->ChannelListNum; - UCHAR Channel = pAd->CommonCfg.Channel; - - if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) - { - if (Channel > 14) - { - if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) || - (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157)) - { - pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE; - } - else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) || - (Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161)) - { - pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW; - } - else - { - pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; - } - } - else - { - do - { - UCHAR ExtCh; - UCHAR Dir = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA; - ExtCh = GetExtCh(Channel, Dir); - if (IsValidChannel(pAd, ExtCh)) - break; - - Dir = (Dir == EXTCHA_ABOVE) ? EXTCHA_BELOW : EXTCHA_ABOVE; - ExtCh = GetExtCh(Channel, Dir); - if (IsValidChannel(pAd, ExtCh)) - { - pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = Dir; - break; - } - pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; - } while(FALSE); - - if (Channel == 14) - { - pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; - //pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE; // We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT() - } - } - } - - -} + OUT PULONG pBufLen); +VOID N_ChannelCheck( + IN PRTMP_ADAPTER pAd); -static inline VOID N_SetCenCh( - IN PRTMP_ADAPTER pAd) -{ - if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) - { - if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE) - { - pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2; - } - else - { - if (pAd->CommonCfg.Channel == 14) - pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1; - else - pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2; - } - } - else - { - pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; - } -} +VOID N_SetCenCh( + IN PRTMP_ADAPTER pAd); -static inline UINT8 GetCuntryMaxTxPwr( +UINT8 GetCuntryMaxTxPwr( IN PRTMP_ADAPTER pAd, - IN UINT8 channel) -{ - int i; - for (i = 0; i < pAd->ChannelListNum; i++) - { - if (pAd->ChannelList[i].Channel == channel) - break; - } + IN UINT8 channel); - if (i == pAd->ChannelListNum) - return 0xff; - else - return pAd->ChannelList[i].MaxTxPwr; -} #endif // __CHLIST_H__ Index: b/drivers/staging/rt2860/common/2860_rtmp_init.c =================================================================== --- a/drivers/staging/rt2860/common/2860_rtmp_init.c +++ /dev/null @@ -1,897 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - - Module Name: - 2860_rtmp_init.c - - Abstract: - Miniport generic portion header file - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Paul Lin 2002-08-01 created - John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme - Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT. -*/ -#include "../rt_config.h" - - - - -/* - ======================================================================== - - Routine Description: - Allocate DMA memory blocks for send, receive - - Arguments: - Adapter Pointer to our adapter - - Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_FAILURE - NDIS_STATUS_RESOURCES - - IRQL = PASSIVE_LEVEL - - Note: - - ======================================================================== -*/ -NDIS_STATUS RTMPAllocTxRxRingMemory( - IN PRTMP_ADAPTER pAd) -{ - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - ULONG RingBasePaHigh; - ULONG RingBasePaLow; - PVOID RingBaseVa; - INT index, num; - PTXD_STRUC pTxD; - PRXD_STRUC pRxD; - ULONG ErrorValue = 0; - PRTMP_TX_RING pTxRing; - PRTMP_DMABUF pDmaBuf; - PNDIS_PACKET pPacket; - - DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); - do - { - // - // Allocate all ring descriptors, include TxD, RxD, MgmtD. - // Although each size is different, to prevent cacheline and alignment - // issue, I intentional set them all to 64 bytes. - // - for (num=0; numTxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE; - RTMP_AllocateTxDescMemory( - pAd, - num, - pAd->TxDescRing[num].AllocSize, - FALSE, - &pAd->TxDescRing[num].AllocVa, - &pAd->TxDescRing[num].AllocPa); - - if (pAd->TxDescRing[num].AllocVa == NULL) - { - ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR(("Failed to allocate a big buffer\n")); - Status = NDIS_STATUS_RESOURCES; - break; - } - - // Zero init this memory block - NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize); - - // Save PA & VA for further operation - RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa); - RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa); - RingBaseVa = pAd->TxDescRing[num].AllocVa; - - // - // Allocate all 1st TXBuf's memory for this TxRing - // - pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE; - RTMP_AllocateFirstTxBuffer( - pAd, - num, - pAd->TxBufSpace[num].AllocSize, - FALSE, - &pAd->TxBufSpace[num].AllocVa, - &pAd->TxBufSpace[num].AllocPa); - - if (pAd->TxBufSpace[num].AllocVa == NULL) - { - ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR(("Failed to allocate a big buffer\n")); - Status = NDIS_STATUS_RESOURCES; - break; - } - - // Zero init this memory block - NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize); - - // Save PA & VA for further operation - BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa); - BufBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa); - BufBaseVa = pAd->TxBufSpace[num].AllocVa; - - // - // Initialize Tx Ring Descriptor and associated buffer memory - // - pTxRing = &pAd->TxRing[num]; - for (index = 0; index < TX_RING_SIZE; index++) - { - pTxRing->Cell[index].pNdisPacket = NULL; - pTxRing->Cell[index].pNextNdisPacket = NULL; - // Init Tx Ring Size, Va, Pa variables - pTxRing->Cell[index].AllocSize = TXD_SIZE; - pTxRing->Cell[index].AllocVa = RingBaseVa; - RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh); - RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow); - - // Setup Tx Buffer size & address. only 802.11 header will store in this space - pDmaBuf = &pTxRing->Cell[index].DmaBuf; - pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE; - pDmaBuf->AllocVa = BufBaseVa; - RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh); - RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow); - - // link the pre-allocated TxBuf to TXD - pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa; - pTxD->SDPtr0 = BufBasePaLow; - // advance to next ring descriptor address - pTxD->DMADONE = 1; - RingBasePaLow += TXD_SIZE; - RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE; - - // advance to next TxBuf address - BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE; - BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE; - } - DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index)); - } - if (Status == NDIS_STATUS_RESOURCES) - break; - - // - // Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler - // - pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE; - RTMP_AllocateMgmtDescMemory( - pAd, - pAd->MgmtDescRing.AllocSize, - FALSE, - &pAd->MgmtDescRing.AllocVa, - &pAd->MgmtDescRing.AllocPa); - - if (pAd->MgmtDescRing.AllocVa == NULL) - { - ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR(("Failed to allocate a big buffer\n")); - Status = NDIS_STATUS_RESOURCES; - break; - } - - // Zero init this memory block - NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); - - // Save PA & VA for further operation - RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa); - RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa); - RingBaseVa = pAd->MgmtDescRing.AllocVa; - - // - // Initialize MGMT Ring and associated buffer memory - // - for (index = 0; index < MGMT_RING_SIZE; index++) - { - pAd->MgmtRing.Cell[index].pNdisPacket = NULL; - pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL; - // Init MGMT Ring Size, Va, Pa variables - pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE; - pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa; - RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh); - RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow); - - // Offset to next ring descriptor address - RingBasePaLow += TXD_SIZE; - RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE; - - // link the pre-allocated TxBuf to TXD - pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa; - pTxD->DMADONE = 1; - - // no pre-allocated buffer required in MgmtRing for scatter-gather case - } - DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index)); - - // - // Allocate RX ring descriptor's memory except Tx ring which allocated eariler - // - pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE; - RTMP_AllocateRxDescMemory( - pAd, - pAd->RxDescRing.AllocSize, - FALSE, - &pAd->RxDescRing.AllocVa, - &pAd->RxDescRing.AllocPa); - - if (pAd->RxDescRing.AllocVa == NULL) - { - ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR(("Failed to allocate a big buffer\n")); - Status = NDIS_STATUS_RESOURCES; - break; - } - - // Zero init this memory block - NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize); - - - printk("RX DESC %p size = %ld\n", pAd->RxDescRing.AllocVa, - pAd->RxDescRing.AllocSize); - - // Save PA & VA for further operation - RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa); - RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa); - RingBaseVa = pAd->RxDescRing.AllocVa; - - // - // Initialize Rx Ring and associated buffer memory - // - for (index = 0; index < RX_RING_SIZE; index++) - { - // Init RX Ring Size, Va, Pa variables - pAd->RxRing.Cell[index].AllocSize = RXD_SIZE; - pAd->RxRing.Cell[index].AllocVa = RingBaseVa; - RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh); - RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow); - - // Offset to next ring descriptor address - RingBasePaLow += RXD_SIZE; - RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE; - - // Setup Rx associated Buffer size & allocate share memory - pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf; - pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE; - pPacket = RTMP_AllocateRxPacketBuffer( - pAd, - pDmaBuf->AllocSize, - FALSE, - &pDmaBuf->AllocVa, - &pDmaBuf->AllocPa); - - /* keep allocated rx packet */ - pAd->RxRing.Cell[index].pNdisPacket = pPacket; - - // Error handling - if (pDmaBuf->AllocVa == NULL) - { - ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n")); - Status = NDIS_STATUS_RESOURCES; - break; - } - - // Zero init this memory block - NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize); - - // Write RxD buffer address & allocated buffer length - pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa; - pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa); - pRxD->DDONE = 0; - } - - DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index)); - - } while (FALSE); - - - NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME)); - pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); - - if (pAd->FragFrame.pFragPacket == NULL) - { - Status = NDIS_STATUS_RESOURCES; - } - - if (Status != NDIS_STATUS_SUCCESS) - { - // Log error inforamtion - NdisWriteErrorLogEntry( - pAd->AdapterHandle, - NDIS_ERROR_CODE_OUT_OF_RESOURCES, - 1, - ErrorValue); - } - - DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); - return Status; -} - - -/* - ======================================================================== - - Routine Description: - Initialize transmit data structures - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - Note: - Initialize all transmit releated private buffer, include those define - in RTMP_ADAPTER structure and all private data structures. - - ======================================================================== -*/ -VOID NICInitTxRxRingAndBacklogQueue( - IN PRTMP_ADAPTER pAd) -{ - //WPDMA_GLO_CFG_STRUC GloCfg; - int i; - - DBGPRINT(RT_DEBUG_TRACE, ("<--> NICInitTxRxRingAndBacklogQueue\n")); - - // Initialize all transmit related software queues - InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_BE]); - InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_BK]); - InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_VI]); - InitializeQueueHeader(&pAd->TxSwQueue[QID_AC_VO]); - InitializeQueueHeader(&pAd->TxSwQueue[QID_HCCA]); - - // Init RX Ring index pointer - pAd->RxRing.RxSwReadIdx = 0; - pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1; - - // Init TX rings index pointer - for (i=0; iTxRing[i].TxSwFreeIdx = 0; - pAd->TxRing[i].TxCpuIdx = 0; - } - - // init MGMT ring index pointer - pAd->MgmtRing.TxSwFreeIdx = 0; - pAd->MgmtRing.TxCpuIdx = 0; - - pAd->PrivateInfo.TxRingFullCnt = 0; -} - - -/* - ======================================================================== - - Routine Description: - Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero. - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - Note: - Reset NIC to initial state AS IS system boot up time. - - ======================================================================== -*/ -VOID RTMPRingCleanUp( - IN PRTMP_ADAPTER pAd, - IN UCHAR RingType) -{ - PTXD_STRUC pTxD; - PRXD_STRUC pRxD; - PQUEUE_ENTRY pEntry; - PNDIS_PACKET pPacket; - int i; - PRTMP_TX_RING pTxRing; - unsigned long IrqFlags; - - DBGPRINT(RT_DEBUG_TRACE,("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, pAd->RalinkCounters.PendingNdisPacketCount)); - switch (RingType) - { - case QID_AC_BK: - case QID_AC_BE: - case QID_AC_VI: - case QID_AC_VO: - case QID_HCCA: - RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); - pTxRing = &pAd->TxRing[RingType]; - - // We have to clean all descriptors in case some error happened with reset - for (i=0; iCell[i].AllocVa; - - pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNdisPacket; - // release scatter-and-gather NDIS_PACKET - if (pPacket) - { - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - pTxRing->Cell[i].pNdisPacket = NULL; - } - - pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNextNdisPacket; - // release scatter-and-gather NDIS_PACKET - if (pPacket) - { - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - pTxRing->Cell[i].pNextNdisPacket = NULL; - } - } - - RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, &pTxRing->TxDmaIdx); - pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx; - pTxRing->TxCpuIdx = pTxRing->TxDmaIdx; - RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, pTxRing->TxCpuIdx); - - RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); - RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); - while (pAd->TxSwQueue[RingType].Head != NULL) - { - pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]); - pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - DBGPRINT(RT_DEBUG_TRACE,("Release 1 NDIS packet from s/w backlog queue\n")); - } - RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); - break; - - case QID_MGMT: - // We have to clean all descriptors in case some error happened with reset - NdisAcquireSpinLock(&pAd->MgmtRingLock); - - for (i=0; iMgmtRing.Cell[i].AllocVa; - - pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNdisPacket; - // rlease scatter-and-gather NDIS_PACKET - if (pPacket) - { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - } - pAd->MgmtRing.Cell[i].pNdisPacket = NULL; - - pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNextNdisPacket; - // release scatter-and-gather NDIS_PACKET - if (pPacket) - { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - } - pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL; - - } - - RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx); - pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx; - pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx; - RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx); - - NdisReleaseSpinLock(&pAd->MgmtRingLock); - pAd->RalinkCounters.MgmtRingFullCount = 0; - break; - - case QID_RX: - // We have to clean all descriptors in case some error happened with reset - NdisAcquireSpinLock(&pAd->RxRingLock); - - for (i=0; iRxRing.Cell[i].AllocVa; - pRxD->DDONE = 0 ; - } - - RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx); - pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx; - pAd->RxRing.RxCpuIdx = ((pAd->RxRing.RxDmaIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxDmaIdx-1)); - RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx); - - NdisReleaseSpinLock(&pAd->RxRingLock); - break; - - default: - break; - } -} - - -NDIS_STATUS AdapterBlockAllocateMemory( - IN PVOID handle, - OUT PVOID *ppAd) -{ - PPCI_DEV pci_dev; - dma_addr_t *phy_addr; - POS_COOKIE pObj = (POS_COOKIE) handle; - - pci_dev = pObj->pci_dev; - phy_addr = &pObj->pAd_pa; - - *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); //pci_alloc_consistent(pci_dev, sizeof(RTMP_ADAPTER), phy_addr); - - if (*ppAd) - { - NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER)); - ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle; - return (NDIS_STATUS_SUCCESS); - } else { - return (NDIS_STATUS_FAILURE); - } -} - - -void RTMP_AllocateTxDescMemory( - IN PRTMP_ADAPTER pAd, - IN UINT Index, - IN ULONG Length, - IN BOOLEAN Cached, - OUT PVOID *VirtualAddress, - OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) -{ - POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; - - *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress); - -} - -void RTMP_AllocateMgmtDescMemory( - IN PRTMP_ADAPTER pAd, - IN ULONG Length, - IN BOOLEAN Cached, - OUT PVOID *VirtualAddress, - OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) -{ - POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; - - *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress); - -} - -void RTMP_AllocateRxDescMemory( - IN PRTMP_ADAPTER pAd, - IN ULONG Length, - IN BOOLEAN Cached, - OUT PVOID *VirtualAddress, - OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) -{ - POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; - - *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress); - -} - -void RTMP_FreeRxDescMemory( - IN PRTMP_ADAPTER pAd, - IN ULONG Length, - IN PVOID VirtualAddress, - IN NDIS_PHYSICAL_ADDRESS PhysicalAddress) -{ - POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; - - PCI_FREE_CONSISTENT(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress); -} - - -void RTMP_AllocateFirstTxBuffer( - IN PRTMP_ADAPTER pAd, - IN UINT Index, - IN ULONG Length, - IN BOOLEAN Cached, - OUT PVOID *VirtualAddress, - OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) -{ - POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; - - *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress); -} - -/* - * FUNCTION: Allocate a common buffer for DMA - * ARGUMENTS: - * AdapterHandle: AdapterHandle - * Length: Number of bytes to allocate - * Cached: Whether or not the memory can be cached - * VirtualAddress: Pointer to memory is returned here - * PhysicalAddress: Physical address corresponding to virtual address - */ - -void RTMP_AllocateSharedMemory( - IN PRTMP_ADAPTER pAd, - IN ULONG Length, - IN BOOLEAN Cached, - OUT PVOID *VirtualAddress, - OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) -{ - POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; - - *VirtualAddress = (PVOID)PCI_ALLOC_CONSISTENT(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress); -} - -VOID RTMPFreeTxRxRingMemory( - IN PRTMP_ADAPTER pAd) -{ - int index, num , j; - PRTMP_TX_RING pTxRing; - PTXD_STRUC pTxD; - PNDIS_PACKET pPacket; - unsigned int IrqFlags; - - POS_COOKIE pObj =(POS_COOKIE) pAd->OS_Cookie; - - DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n")); - - // Free TxSwQueue Packet - for (index=0; index irq_lock, IrqFlags); - pQueue = &pAd->TxSwQueue[index]; - while (pQueue->Head) - { - pEntry = RemoveHeadQueue(pQueue); - pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); - } - RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); - } - - // Free Tx Ring Packet - for (index=0;index< NUM_OF_TX_RING;index++) - { - pTxRing = &pAd->TxRing[index]; - - for (j=0; j< TX_RING_SIZE; j++) - { - pTxD = (PTXD_STRUC) (pTxRing->Cell[j].AllocVa); - pPacket = pTxRing->Cell[j].pNdisPacket; - - if (pPacket) - { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); - } - //Always assign pNdisPacket as NULL after clear - pTxRing->Cell[j].pNdisPacket = NULL; - - pPacket = pTxRing->Cell[j].pNextNdisPacket; - - if (pPacket) - { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); - } - //Always assign pNextNdisPacket as NULL after clear - pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL; - - } - } - - for (index = RX_RING_SIZE - 1 ; index >= 0; index--) - { - if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket)) - { - PCI_UNMAP_SINGLE(pObj->pci_dev, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE); - RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS); - } - } - NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB)); - - if (pAd->RxDescRing.AllocVa) - { - PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->RxDescRing.AllocSize, pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocPa); - } - NdisZeroMemory(&pAd->RxDescRing, sizeof(RTMP_DMABUF)); - - if (pAd->MgmtDescRing.AllocVa) - { - PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->MgmtDescRing.AllocSize, pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocPa); - } - NdisZeroMemory(&pAd->MgmtDescRing, sizeof(RTMP_DMABUF)); - - for (num = 0; num < NUM_OF_TX_RING; num++) - { - if (pAd->TxBufSpace[num].AllocVa) - { - PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxBufSpace[num].AllocSize, pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocPa); - } - NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(RTMP_DMABUF)); - - if (pAd->TxDescRing[num].AllocVa) - { - PCI_FREE_CONSISTENT(pObj->pci_dev, pAd->TxDescRing[num].AllocSize, pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocPa); - } - NdisZeroMemory(&pAd->TxDescRing[num], sizeof(RTMP_DMABUF)); - } - - if (pAd->FragFrame.pFragPacket) - RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS); - - DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n")); -} - - -/* - * FUNCTION: Allocate a packet buffer for DMA - * ARGUMENTS: - * AdapterHandle: AdapterHandle - * Length: Number of bytes to allocate - * Cached: Whether or not the memory can be cached - * VirtualAddress: Pointer to memory is returned here - * PhysicalAddress: Physical address corresponding to virtual address - * Notes: - * Cached is ignored: always cached memory - */ -PNDIS_PACKET RTMP_AllocateRxPacketBuffer( - IN PRTMP_ADAPTER pAd, - IN ULONG Length, - IN BOOLEAN Cached, - OUT PVOID *VirtualAddress, - OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) -{ - PNDIS_PACKET pkt; - - pkt = RTPKT_TO_OSPKT(DEV_ALLOC_SKB(Length)); - - if (pkt == NULL) { - DBGPRINT(RT_DEBUG_ERROR, ("can't allocate rx %ld size packet\n",Length)); - } - - if (pkt) { - RTMP_SET_PACKET_SOURCE(pkt, PKTSRC_NDIS); - *VirtualAddress = (PVOID) RTPKT_TO_OSPKT(pkt)->data; - *PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1, PCI_DMA_FROMDEVICE); - } else { - *VirtualAddress = (PVOID) NULL; - *PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) NULL; - } - - return (PNDIS_PACKET) pkt; -} - - -VOID Invalid_Remaining_Packet( - IN PRTMP_ADAPTER pAd, - IN ULONG VirtualAddress) -{ - NDIS_PHYSICAL_ADDRESS PhysicalAddress; - - PhysicalAddress = PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress+1600), RX_BUFFER_NORMSIZE-1600, -1, PCI_DMA_FROMDEVICE); -} - -PNDIS_PACKET GetPacketFromRxRing( - IN PRTMP_ADAPTER pAd, - OUT PRT28XX_RXD_STRUC pSaveRxD, - OUT BOOLEAN *pbReschedule, - IN OUT UINT32 *pRxPending) -{ - PRXD_STRUC pRxD; - PNDIS_PACKET pRxPacket = NULL; - PNDIS_PACKET pNewPacket; - PVOID AllocVa; - NDIS_PHYSICAL_ADDRESS AllocPa; - BOOLEAN bReschedule = FALSE; - - RTMP_SEM_LOCK(&pAd->RxRingLock); - - if (*pRxPending == 0) - { - // Get how may packets had been received - RTMP_IO_READ32(pAd, RX_DRX_IDX , &pAd->RxRing.RxDmaIdx); - - if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx) - { - // no more rx packets - bReschedule = FALSE; - goto done; - } - - // get rx pending count - if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx) - *pRxPending = pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx; - else - *pRxPending = pAd->RxRing.RxDmaIdx + RX_RING_SIZE - pAd->RxRing.RxSwReadIdx; - - } - - // Point to Rx indexed rx ring descriptor - pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].AllocVa; - - if (pRxD->DDONE == 0) - { - *pRxPending = 0; - // DMAIndx had done but DDONE bit not ready - bReschedule = TRUE; - goto done; - } - - - // return rx descriptor - NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE); - - pNewPacket = RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, &AllocVa, &AllocPa); - - if (pNewPacket) - { - // unmap the rx buffer - PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa, - pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE); - pRxPacket = pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket; - - pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocSize = RX_BUFFER_AGGRESIZE; - pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].pNdisPacket = (PNDIS_PACKET) pNewPacket; - pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocVa = AllocVa; - pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx].DmaBuf.AllocPa = AllocPa; - /* update SDP0 to new buffer of rx packet */ - pRxD->SDP0 = AllocPa; - } - else - { - //printk("No Rx Buffer\n"); - pRxPacket = NULL; - bReschedule = TRUE; - } - - pRxD->DDONE = 0; - - // had handled one rx packet - *pRxPending = *pRxPending - 1; - - // update rx descriptor and kick rx - INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE); - - pAd->RxRing.RxCpuIdx = (pAd->RxRing.RxSwReadIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxSwReadIdx-1); - RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx); - -done: - RTMP_SEM_UNLOCK(&pAd->RxRingLock); - *pbReschedule = bReschedule; - return pRxPacket; -} -/* End of 2860_rtmp_init.c */ - Index: b/drivers/staging/rt2860/common/action.c =================================================================== --- a/drivers/staging/rt2860/common/action.c +++ b/drivers/staging/rt2860/common/action.c @@ -150,7 +150,9 @@ VOID MlmeADDBAAction( MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_ADDBA_REQ), &Frame, END_OF_ARGS); - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + + MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[pInfo->TID]), pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize)); @@ -425,8 +427,10 @@ VOID PeerHTAction( case SETPCO_ACTION: break; + case MIMO_CHA_MEASURE_ACTION: break; + case HT_INFO_EXCHANGE: { HT_INFORMATION_OCTET *pHT_info; @@ -463,8 +467,14 @@ VOID ORIBATimerTimeout( { MAC_TABLE_ENTRY *pEntry; INT i, total; +// FRAME_BAR FrameBar; +// ULONG FrameLen; +// NDIS_STATUS NStatus; +// PUCHAR pOutBuffer = NULL; +// USHORT Sequence; UCHAR TID; + total = pAd->MacTab.Size * NUM_OF_TID; for (i = 1; ((i 0)) ; i++) @@ -527,9 +537,13 @@ VOID SendRefreshBAR( MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(FRAME_BAR), &FrameBar, END_OF_ARGS); + //if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET))) + if (1) // Now we always send BAR. + { + //MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen); + MiniportMMRequest(pAd, (MGMT_USE_QUEUE_FLAG | MapUserPriorityToAccessCategory[TID]), pOutBuffer, FrameLen); - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); - + } MlmeFreeMemory(pAd, pOutBuffer); } } @@ -557,6 +571,8 @@ VOID BarHeaderInit( IN PUCHAR pDA, IN PUCHAR pSA) { +// USHORT Duration; + NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR)); pCntlBar->FC.Type = BTYPE_CNTL; pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ; Index: b/drivers/staging/rt2860/common/ba_action.c =================================================================== --- a/drivers/staging/rt2860/common/ba_action.c +++ b/drivers/staging/rt2860/common/ba_action.c @@ -35,8 +35,8 @@ #define ORI_BA_SESSION_TIMEOUT (2000) // ms #define REC_BA_SESSION_IDLE_TIMEOUT (1000) // ms -#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms -#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * HZ)/1000) // system ticks -- 100 ms +#define REORDERING_PACKET_TIMEOUT ((100 * OS_HZ)/1000) // system ticks -- 100 ms +#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * OS_HZ)/1000) // system ticks -- 100 ms #define RESET_RCV_SEQ (0xFFFF) @@ -444,6 +444,9 @@ void ba_flush_reordering_timeout_mpdus( && (pBAEntry->list.qlen > 0) ) { +// DBGPRINT(RT_DEBUG_OFF, ("timeout[%d] (%lx-%lx = %d > %d): %x, ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer), +// (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), REORDERING_PACKET_TIMEOUT, +// pBAEntry->LastIndSeq)); // // force LastIndSeq to shift to LastIndSeq+1 // @@ -460,6 +463,8 @@ void ba_flush_reordering_timeout_mpdus( pBAEntry->LastIndSeq = Sequence; } + DBGPRINT(RT_DEBUG_OFF, ("%x, flush one!\n", pBAEntry->LastIndSeq)); + } } @@ -493,7 +498,7 @@ VOID BAOriSessionSetUp( { // try again after 3 secs DelayTime = 3000; -// printk("DeCline BA from Peer\n"); +// DBGPRINT(RT_DEBUG_TRACE, ("DeCline BA from Peer\n")); // return; } @@ -531,11 +536,6 @@ VOID BAOriSessionSetUp( pBAEntry->TimeOutValue = TimeOut; pBAEntry->pAdapter = pAd; - DBGPRINT(RT_DEBUG_TRACE,("Send AddBA to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d isForced:%d Wcid:%d\n" - ,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2] - ,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5] - ,TID,isForced,pEntry->Aid)); - if (!(pEntry->TXBAbitmap & (1<ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE); @@ -573,6 +573,8 @@ VOID BAOriSessionAdd( pBAEntry->TimeOutValue = pFrame->TimeOutValue; pBAEntry->ORI_BA_Status = Originator_Done; + pAd->BATable.numDoneOriginator ++; + // reset sequence number pBAEntry->Sequence = BA_ORI_INIT_SEQ; // Set Bitmap flag. @@ -668,7 +670,7 @@ BOOLEAN BARecSessionAdd( // initial sequence number pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq; - printk("Start Seq = %08x\n", pFrame->BaStartSeq.field.StartSeq); + DBGPRINT(RT_DEBUG_OFF, ("Start Seq = %08x\n", pFrame->BaStartSeq.field.StartSeq)); if (pEntry->RXBAbitmap & (1<BADeclineBitmap &= ~(1<Aid, TID); + RTMP_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID); DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n", pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID])); @@ -713,8 +715,8 @@ BA_REC_ENTRY *BATableAllocRecEntry( if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION) { - printk("BA Recipeint Session (%ld) > %d\n", pAd->BATable.numAsRecipient, - MAX_BARECI_SESSION); + DBGPRINT(RT_DEBUG_OFF, ("BA Recipeint Session (%ld) > %d\n", + pAd->BATable.numAsRecipient, MAX_BARECI_SESSION)); goto done; } @@ -794,6 +796,7 @@ VOID BATableFreeOriEntry( NdisAcquireSpinLock(&pAd->BATabLock); if (pBAEntry->ORI_BA_Status == Originator_Done) { + pAd->BATable.numDoneOriginator -= 1; pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) )); DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient)); // Erase Bitmap flag. @@ -867,9 +870,8 @@ VOID BAOriSessionTearDown( // force send specified TID DelBA MLME_DELBA_REQ_STRUCT DelbaReq; MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); - if (Elem == NULL) - return; - + if (Elem != NULL) + { NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); @@ -877,15 +879,15 @@ VOID BAOriSessionTearDown( DelbaReq.Wcid = Wcid; DelbaReq.TID = TID; DelbaReq.Initiator = ORIGINATOR; -#if 1 Elem->MsgLen = sizeof(DelbaReq); NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); MlmeDELBAAction(pAd, Elem); kfree(Elem); -#else - MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq); - RT28XX_MLME_HANDLER(pAd); -#endif + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s(bForceSend):alloc memory failed!\n", __func__)); + } } return; @@ -902,9 +904,8 @@ VOID BAOriSessionTearDown( { MLME_DELBA_REQ_STRUCT DelbaReq; MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); - if (Elem == NULL) - return; - + if (Elem != NULL) + { NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); @@ -912,15 +913,16 @@ VOID BAOriSessionTearDown( DelbaReq.Wcid = Wcid; DelbaReq.TID = pBAEntry->TID; DelbaReq.Initiator = ORIGINATOR; -#if 1 Elem->MsgLen = sizeof(DelbaReq); NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); MlmeDELBAAction(pAd, Elem); kfree(Elem); -#else - MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq); - RT28XX_MLME_HANDLER(pAd); -#endif + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __func__)); + return; + } } RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled); BATableFreeOriEntry(pAd, Idx); @@ -964,7 +966,6 @@ VOID BARecSessionTearDown( { MLME_DELBA_REQ_STRUCT DelbaReq; BOOLEAN Cancelled; - MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); //ULONG offset; //UINT32 VALUE; @@ -975,6 +976,9 @@ VOID BARecSessionTearDown( // if (bPassive == FALSE) { + MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); + if (Elem != NULL) + { NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM)); @@ -982,15 +986,16 @@ VOID BARecSessionTearDown( DelbaReq.Wcid = Wcid; DelbaReq.TID = TID; DelbaReq.Initiator = RECIPIENT; -#if 1 Elem->MsgLen = sizeof(DelbaReq); NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq)); MlmeDELBAAction(pAd, Elem); kfree(Elem); -#else - MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq); - RT28XX_MLME_HANDLER(pAd); -#endif + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s():alloc memory failed!\n", __func__)); + return; + } } @@ -1009,7 +1014,7 @@ VOID BARecSessionTearDown( pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID))); pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0; - RT28XX_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID); + RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID); NdisReleaseSpinLock(&pAd->BATabLock); @@ -1061,9 +1066,12 @@ VOID BAOriSessionSetupTimeout( pAd = pBAEntry->pAdapter; + { // Do nothing if monitor mode is on if (MONITOR_ON(pAd)) return; + } + pEntry = &pAd->MacTab.Content[pBAEntry->Wcid]; @@ -1079,12 +1087,9 @@ VOID BAOriSessionSetupTimeout( AddbaReq.TimeOutValue = 0; AddbaReq.Token = pBAEntry->Token; MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq); - RT28XX_MLME_HANDLER(pAd); - DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d Wcid:%d\n" - ,pBAEntry->Token - ,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2] - ,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5] - ,pBAEntry->TID,pEntry->Aid)); + RTMP_MLME_HANDLER(pAd); + DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token)); + pBAEntry->Token++; RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT); } @@ -1131,7 +1136,7 @@ VOID BARecSessionIdleTimeout( pAd = pBAEntry->pAdapter; // flush all pending reordering mpdus ba_refresh_reordering_mpdus(pAd, pBAEntry); - printk("%ld: REC BA session Timeout\n", Now32); + DBGPRINT(RT_DEBUG_OFF, ("%ld: REC BA session Timeout\n", Now32)); } } } @@ -1174,7 +1179,7 @@ VOID PeerAddBAReqAction( if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry)) { pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]); - printk("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid); + DBGPRINT(RT_DEBUG_OFF, ("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid)); if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame)) Status = 0; else @@ -1367,7 +1372,7 @@ BOOLEAN CntlEnqueueForRecv( if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ)) { - //printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq); + //DBGPRINT(RT_DEBUG_TRACE, ("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq)); ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq); pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1); } @@ -1388,8 +1393,6 @@ VOID SendPSMPAction( //ULONG Idx; FRAME_PSMP_ACTION Frame; ULONG FrameLen; - UCHAR bbpdata=0; - UINT32 macdata; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory if (NStatus != NDIS_STATUS_SUCCESS) @@ -1405,48 +1408,26 @@ VOID SendPSMPAction( switch (Psmp) { case MMPS_ENABLE: - if (IS_RT3090(pAd)) +#ifdef RT30xx + if (IS_RT30xx(pAd) + &&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1)) { - // disable MMPS BBP control register - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata); - bbpdata &= ~(0x04); //bit 2 - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata); - - // disable MMPS MAC control register - RTMP_IO_READ32(pAd, 0x1210, &macdata); - macdata &= ~(0x09); //bit 0, 3 - RTMP_IO_WRITE32(pAd, 0x1210, macdata); + RTMP_ASIC_MMPS_DISABLE(pAd); } +#endif // RT30xx // Frame.Psmp = 0; break; case MMPS_DYNAMIC: - if (IS_RT3090(pAd)) - { - // enable MMPS BBP control register - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata); - bbpdata |= 0x04; //bit 2 - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata); - - // enable MMPS MAC control register - RTMP_IO_READ32(pAd, 0x1210, &macdata); - macdata |= 0x09; //bit 0, 3 - RTMP_IO_WRITE32(pAd, 0x1210, macdata); - } Frame.Psmp = 3; break; case MMPS_STATIC: - if (IS_RT3090(pAd)) +#ifdef RT30xx + if (IS_RT30xx(pAd) + &&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1)) { - // enable MMPS BBP control register - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata); - bbpdata |= 0x04; //bit 2 - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata); - - // enable MMPS MAC control register - RTMP_IO_READ32(pAd, 0x1210, &macdata); - macdata |= 0x09; //bit 0, 3 - RTMP_IO_WRITE32(pAd, 0x1210, macdata); + RTMP_ASIC_MMPS_ENABLE(pAd); } +#endif // RT30xx // Frame.Psmp = 1; break; } @@ -1504,20 +1485,22 @@ void convert_reordering_packet_to_preAMS ASSERT(pRxBlk->pRxPacket); pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket); - RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); - RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData; - RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize; - RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len; + SET_OS_PKT_NETDEV(pRxPkt, get_netdev_from_bssid(pAd, FromWhichBSSID)); + SET_OS_PKT_DATAPTR(pRxPkt, pRxBlk->pData); + SET_OS_PKT_LEN(pRxPkt, pRxBlk->DataSize); + SET_OS_PKT_DATATAIL(pRxPkt, pRxBlk->pData, pRxBlk->DataSize); // // copy 802.3 header, if necessary // if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) { + { #ifdef LINUX NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3); #endif } + } } @@ -1550,7 +1533,8 @@ static VOID ba_enqueue_reordering_packet UINT16 Sequence = (UINT16) pRxBlk->pHeader->Sequence; mpdu_blk = ba_mpdu_blk_alloc(pAd); - if (mpdu_blk != NULL) + if ((mpdu_blk != NULL) && + (!RX_BLK_TEST_FLAG(pRxBlk, fRX_EAP))) { // Write RxD buffer address & allocated buffer length NdisAcquireSpinLock(&pBAEntry->RxReRingLock); Index: b/drivers/staging/rt2860/common/cmm_aes.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/cmm_aes.c @@ -0,0 +1,1554 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + cmm_aes.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Paul Wu 02-25-02 Initial +*/ + +#include "../rt_config.h" + + +typedef struct +{ + UINT32 erk[64]; /* encryption round keys */ + UINT32 drk[64]; /* decryption round keys */ + int nr; /* number of rounds */ +} +aes_context; + +/*****************************/ +/******** SBOX Table *********/ +/*****************************/ + +UCHAR SboxTable[256] = +{ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +}; + +VOID xor_32( + IN PUCHAR a, + IN PUCHAR b, + OUT PUCHAR out) +{ + INT i; + + for (i=0;i<4; i++) + { + out[i] = a[i] ^ b[i]; + } +} + +VOID xor_128( + IN PUCHAR a, + IN PUCHAR b, + OUT PUCHAR out) +{ + INT i; + + for (i=0;i<16; i++) + { + out[i] = a[i] ^ b[i]; + } +} + +UCHAR RTMPCkipSbox( + IN UCHAR a) +{ + return SboxTable[(int)a]; +} + +VOID next_key( + IN PUCHAR key, + IN INT round) +{ + UCHAR rcon; + UCHAR sbox_key[4]; + UCHAR rcon_table[12] = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, + 0x1b, 0x36, 0x36, 0x36 + }; + + sbox_key[0] = RTMPCkipSbox(key[13]); + sbox_key[1] = RTMPCkipSbox(key[14]); + sbox_key[2] = RTMPCkipSbox(key[15]); + sbox_key[3] = RTMPCkipSbox(key[12]); + + rcon = rcon_table[round]; + + xor_32(&key[0], sbox_key, &key[0]); + key[0] = key[0] ^ rcon; + + xor_32(&key[4], &key[0], &key[4]); + xor_32(&key[8], &key[4], &key[8]); + xor_32(&key[12], &key[8], &key[12]); +} + +VOID byte_sub( + IN PUCHAR in, + OUT PUCHAR out) +{ + INT i; + + for (i=0; i< 16; i++) + { + out[i] = RTMPCkipSbox(in[i]); + } +} + +/************************************/ +/* bitwise_xor() */ +/* A 128 bit, bitwise exclusive or */ +/************************************/ + +void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out) +{ + int i; + for (i=0; i<16; i++) + { + out[i] = ina[i] ^ inb[i]; + } +} + +VOID shift_row( + IN PUCHAR in, + OUT PUCHAR out) +{ + out[0] = in[0]; + out[1] = in[5]; + out[2] = in[10]; + out[3] = in[15]; + out[4] = in[4]; + out[5] = in[9]; + out[6] = in[14]; + out[7] = in[3]; + out[8] = in[8]; + out[9] = in[13]; + out[10] = in[2]; + out[11] = in[7]; + out[12] = in[12]; + out[13] = in[1]; + out[14] = in[6]; + out[15] = in[11]; +} + +VOID mix_column( + IN PUCHAR in, + OUT PUCHAR out) +{ + INT i; + UCHAR add1b[4]; + UCHAR add1bf7[4]; + UCHAR rotl[4]; + UCHAR swap_halfs[4]; + UCHAR andf7[4]; + UCHAR rotr[4]; + UCHAR temp[4]; + UCHAR tempb[4]; + + for (i=0 ; i<4; i++) + { + if ((in[i] & 0x80)== 0x80) + add1b[i] = 0x1b; + else + add1b[i] = 0x00; + } + + swap_halfs[0] = in[2]; /* Swap halfs */ + swap_halfs[1] = in[3]; + swap_halfs[2] = in[0]; + swap_halfs[3] = in[1]; + + rotl[0] = in[3]; /* Rotate left 8 bits */ + rotl[1] = in[0]; + rotl[2] = in[1]; + rotl[3] = in[2]; + + andf7[0] = in[0] & 0x7f; + andf7[1] = in[1] & 0x7f; + andf7[2] = in[2] & 0x7f; + andf7[3] = in[3] & 0x7f; + + for (i = 3; i>0; i--) /* logical shift left 1 bit */ + { + andf7[i] = andf7[i] << 1; + if ((andf7[i-1] & 0x80) == 0x80) + { + andf7[i] = (andf7[i] | 0x01); + } + } + andf7[0] = andf7[0] << 1; + andf7[0] = andf7[0] & 0xfe; + + xor_32(add1b, andf7, add1bf7); + + xor_32(in, add1bf7, rotr); + + temp[0] = rotr[0]; /* Rotate right 8 bits */ + rotr[0] = rotr[1]; + rotr[1] = rotr[2]; + rotr[2] = rotr[3]; + rotr[3] = temp[0]; + + xor_32(add1bf7, rotr, temp); + xor_32(swap_halfs, rotl,tempb); + xor_32(temp, tempb, out); +} + + +/************************************************/ +/* construct_mic_header1() */ +/* Builds the first MIC header block from */ +/* header fields. */ +/************************************************/ + +void construct_mic_header1( + unsigned char *mic_header1, + int header_length, + unsigned char *mpdu) +{ + mic_header1[0] = (unsigned char)((header_length - 2) / 256); + mic_header1[1] = (unsigned char)((header_length - 2) % 256); + mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */ + mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */ + mic_header1[4] = mpdu[4]; /* A1 */ + mic_header1[5] = mpdu[5]; + mic_header1[6] = mpdu[6]; + mic_header1[7] = mpdu[7]; + mic_header1[8] = mpdu[8]; + mic_header1[9] = mpdu[9]; + mic_header1[10] = mpdu[10]; /* A2 */ + mic_header1[11] = mpdu[11]; + mic_header1[12] = mpdu[12]; + mic_header1[13] = mpdu[13]; + mic_header1[14] = mpdu[14]; + mic_header1[15] = mpdu[15]; +} + +/************************************************/ +/* construct_mic_header2() */ +/* Builds the last MIC header block from */ +/* header fields. */ +/************************************************/ + +void construct_mic_header2( + unsigned char *mic_header2, + unsigned char *mpdu, + int a4_exists, + int qc_exists) +{ + int i; + + for (i = 0; i<16; i++) mic_header2[i]=0x00; + + mic_header2[0] = mpdu[16]; /* A3 */ + mic_header2[1] = mpdu[17]; + mic_header2[2] = mpdu[18]; + mic_header2[3] = mpdu[19]; + mic_header2[4] = mpdu[20]; + mic_header2[5] = mpdu[21]; + + // In Sequence Control field, mute sequence numer bits (12-bit) + mic_header2[6] = mpdu[22] & 0x0f; /* SC */ + mic_header2[7] = 0x00; /* mpdu[23]; */ + + if ((!qc_exists) & a4_exists) + { + for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */ + + } + + if (qc_exists && (!a4_exists)) + { + mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */ + mic_header2[9] = mpdu[25] & 0x00; + } + + if (qc_exists && a4_exists) + { + for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */ + + mic_header2[14] = mpdu[30] & 0x0f; + mic_header2[15] = mpdu[31] & 0x00; + } +} + + +/************************************************/ +/* construct_mic_iv() */ +/* Builds the MIC IV from header fields and PN */ +/************************************************/ + +void construct_mic_iv( + unsigned char *mic_iv, + int qc_exists, + int a4_exists, + unsigned char *mpdu, + unsigned int payload_length, + unsigned char *pn_vector) +{ + int i; + + mic_iv[0] = 0x59; + if (qc_exists && a4_exists) + mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */ + if (qc_exists && !a4_exists) + mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */ + if (!qc_exists) + mic_iv[1] = 0x00; + for (i = 2; i < 8; i++) + mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */ +#ifdef CONSISTENT_PN_ORDER + for (i = 8; i < 14; i++) + mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */ +#else + for (i = 8; i < 14; i++) + mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ +#endif + i = (payload_length / 256); + i = (payload_length % 256); + mic_iv[14] = (unsigned char) (payload_length / 256); + mic_iv[15] = (unsigned char) (payload_length % 256); + +} + +/****************************************/ +/* aes128k128d() */ +/* Performs a 128 bit AES encrypt with */ +/* 128 bit data. */ +/****************************************/ +void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext) +{ + int round; + int i; + unsigned char intermediatea[16]; + unsigned char intermediateb[16]; + unsigned char round_key[16]; + + for(i=0; i<16; i++) round_key[i] = key[i]; + + for (round = 0; round < 11; round++) + { + if (round == 0) + { + xor_128(round_key, data, ciphertext); + next_key(round_key, round); + } + else if (round == 10) + { + byte_sub(ciphertext, intermediatea); + shift_row(intermediatea, intermediateb); + xor_128(intermediateb, round_key, ciphertext); + } + else /* 1 - 9 */ + { + byte_sub(ciphertext, intermediatea); + shift_row(intermediatea, intermediateb); + mix_column(&intermediateb[0], &intermediatea[0]); + mix_column(&intermediateb[4], &intermediatea[4]); + mix_column(&intermediateb[8], &intermediatea[8]); + mix_column(&intermediateb[12], &intermediatea[12]); + xor_128(intermediatea, round_key, ciphertext); + next_key(round_key, round); + } + } + +} + +void construct_ctr_preload( + unsigned char *ctr_preload, + int a4_exists, + int qc_exists, + unsigned char *mpdu, + unsigned char *pn_vector, + int c) +{ + + int i = 0; + for (i=0; i<16; i++) ctr_preload[i] = 0x00; + i = 0; + + ctr_preload[0] = 0x01; /* flag */ + if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */ + if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f; + + for (i = 2; i < 8; i++) + ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */ +#ifdef CONSISTENT_PN_ORDER + for (i = 8; i < 14; i++) + ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */ +#else + for (i = 8; i < 14; i++) + ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */ +#endif + ctr_preload[14] = (unsigned char) (c / 256); // Ctr + ctr_preload[15] = (unsigned char) (c % 256); + +} + +BOOLEAN RTMPSoftDecryptAES( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pData, + IN ULONG DataByteCnt, + IN PCIPHER_KEY pWpaKey) +{ + UCHAR KeyID; + UINT HeaderLen; + UCHAR PN[6]; + UINT payload_len; + UINT num_blocks; + UINT payload_remainder; + USHORT fc; + UCHAR fc0; + UCHAR fc1; + UINT frame_type; + UINT frame_subtype; + UINT from_ds; + UINT to_ds; + INT a4_exists; + INT qc_exists; + UCHAR aes_out[16]; + int payload_index; + UINT i; + UCHAR ctr_preload[16]; + UCHAR chain_buffer[16]; + UCHAR padded_buffer[16]; + UCHAR mic_iv[16]; + UCHAR mic_header1[16]; + UCHAR mic_header2[16]; + UCHAR MIC[8]; + UCHAR TrailMIC[8]; + + + fc0 = *pData; + fc1 = *(pData + 1); + + fc = *((PUSHORT)pData); + + frame_type = ((fc0 >> 2) & 0x03); + frame_subtype = ((fc0 >> 4) & 0x0f); + + from_ds = (fc1 & 0x2) >> 1; + to_ds = (fc1 & 0x1); + + a4_exists = (from_ds & to_ds); + qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */ + (frame_subtype == 0x09) || /* Likely to change. */ + (frame_subtype == 0x0a) || + (frame_subtype == 0x0b) + ); + + HeaderLen = 24; + if (a4_exists) + HeaderLen += 6; + + KeyID = *((PUCHAR)(pData+ HeaderLen + 3)); + KeyID = KeyID >> 6; + + if (pWpaKey[KeyID].KeyLen == 0) + { + DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID)); + return FALSE; + } + + PN[0] = *(pData+ HeaderLen); + PN[1] = *(pData+ HeaderLen + 1); + PN[2] = *(pData+ HeaderLen + 4); + PN[3] = *(pData+ HeaderLen + 5); + PN[4] = *(pData+ HeaderLen + 6); + PN[5] = *(pData+ HeaderLen + 7); + + payload_len = DataByteCnt - HeaderLen - 8 - 8; // 8 bytes for CCMP header , 8 bytes for MIC + payload_remainder = (payload_len) % 16; + num_blocks = (payload_len) / 16; + + + + // Find start of payload + payload_index = HeaderLen + 8; //IV+EIV + + for (i=0; i< num_blocks; i++) + { + construct_ctr_preload(ctr_preload, + a4_exists, + qc_exists, + pData, + PN, + i+1 ); + + aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out); + + bitwise_xor(aes_out, pData + payload_index, chain_buffer); + NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16); + payload_index += 16; + } + + // + // If there is a short final block, then pad it + // encrypt it and copy the unpadded part back + // + if (payload_remainder > 0) + { + construct_ctr_preload(ctr_preload, + a4_exists, + qc_exists, + pData, + PN, + num_blocks + 1); + + NdisZeroMemory(padded_buffer, 16); + NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder); + + aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out); + + bitwise_xor(aes_out, padded_buffer, chain_buffer); + NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder); + payload_index += payload_remainder; + } + + // + // Descrypt the MIC + // + construct_ctr_preload(ctr_preload, + a4_exists, + qc_exists, + pData, + PN, + 0); + NdisZeroMemory(padded_buffer, 16); + NdisMoveMemory(padded_buffer, pData + payload_index, 8); + + aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out); + + bitwise_xor(aes_out, padded_buffer, chain_buffer); + + NdisMoveMemory(TrailMIC, chain_buffer, 8); + + + // + // Calculate MIC + // + + //Force the protected frame bit on + *(pData + 1) = *(pData + 1) | 0x40; + + // Find start of payload + // Because the CCMP header has been removed + payload_index = HeaderLen; + + construct_mic_iv( + mic_iv, + qc_exists, + a4_exists, + pData, + payload_len, + PN); + + construct_mic_header1( + mic_header1, + HeaderLen, + pData); + + construct_mic_header2( + mic_header2, + pData, + a4_exists, + qc_exists); + + aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out); + bitwise_xor(aes_out, mic_header1, chain_buffer); + aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out); + bitwise_xor(aes_out, mic_header2, chain_buffer); + aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out); + + // iterate through each 16 byte payload block + for (i = 0; i < num_blocks; i++) + { + bitwise_xor(aes_out, pData + payload_index, chain_buffer); + payload_index += 16; + aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out); + } + + // Add on the final payload block if it needs padding + if (payload_remainder > 0) + { + NdisZeroMemory(padded_buffer, 16); + NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder); + + bitwise_xor(aes_out, padded_buffer, chain_buffer); + aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out); + } + + // aes_out contains padded mic, discard most significant + // 8 bytes to generate 64 bit MIC + for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i]; + + if (!NdisEqualMemory(MIC, TrailMIC, 8)) + { + DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); //MIC error. + return FALSE; + } + + + return TRUE; +} + +/* ========================= AES En/Decryption ========================== */ +#ifndef uint8 +#define uint8 unsigned char +#endif + +#ifndef uint32 +#define uint32 unsigned int +#endif + +/* forward S-box */ +static uint32 FSb[256] = +{ + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, + 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, + 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, + 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, + 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, + 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, + 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, + 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, + 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, + 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, + 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, + 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, + 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, + 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, + 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 +}; + +/* forward table */ +#define FT \ +\ + V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \ + V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \ + V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \ + V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \ + V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \ + V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \ + V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \ + V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \ + V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \ + V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \ + V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \ + V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \ + V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \ + V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \ + V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \ + V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \ + V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \ + V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \ + V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \ + V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \ + V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \ + V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \ + V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \ + V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \ + V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \ + V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \ + V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \ + V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \ + V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \ + V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \ + V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \ + V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \ + V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \ + V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \ + V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \ + V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \ + V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \ + V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \ + V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \ + V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \ + V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \ + V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \ + V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \ + V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \ + V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \ + V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \ + V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \ + V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \ + V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \ + V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \ + V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \ + V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \ + V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \ + V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \ + V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \ + V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \ + V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \ + V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \ + V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \ + V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \ + V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \ + V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \ + V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \ + V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A) + +#define V(a,b,c,d) 0x##a##b##c##d +static uint32 FT0[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static uint32 FT1[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static uint32 FT2[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +static uint32 FT3[256] = { FT }; +#undef V + +#undef FT + +/* reverse S-box */ + +static uint32 RSb[256] = +{ + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, + 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, + 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, + 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, + 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, + 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, + 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, + 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, + 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, + 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, + 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, + 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; + +/* reverse table */ + +#define RT \ +\ + V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \ + V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \ + V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \ + V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \ + V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \ + V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \ + V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \ + V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \ + V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \ + V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \ + V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \ + V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \ + V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \ + V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \ + V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \ + V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \ + V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \ + V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \ + V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \ + V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \ + V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \ + V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \ + V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \ + V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \ + V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \ + V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \ + V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \ + V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \ + V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \ + V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \ + V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \ + V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \ + V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \ + V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \ + V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \ + V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \ + V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \ + V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \ + V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \ + V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \ + V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \ + V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \ + V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \ + V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \ + V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \ + V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \ + V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \ + V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \ + V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \ + V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \ + V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \ + V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \ + V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \ + V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \ + V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \ + V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \ + V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \ + V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \ + V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \ + V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \ + V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \ + V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \ + V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \ + V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42) + +#define V(a,b,c,d) 0x##a##b##c##d +static uint32 RT0[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static uint32 RT1[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static uint32 RT2[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +static uint32 RT3[256] = { RT }; +#undef V + +#undef RT + +/* round constants */ + +static uint32 RCON[10] = +{ + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000 +}; + +/* key schedule tables */ + +static int KT_init = 1; + +static uint32 KT0[256]; +static uint32 KT1[256]; +static uint32 KT2[256]; +static uint32 KT3[256]; + +/* platform-independant 32-bit integer manipulation macros */ + +#define GET_UINT32(n,b,i) \ +{ \ + (n) = ( (uint32) (b)[(i) ] << 24 ) \ + | ( (uint32) (b)[(i) + 1] << 16 ) \ + | ( (uint32) (b)[(i) + 2] << 8 ) \ + | ( (uint32) (b)[(i) + 3] ); \ +} + +#define PUT_UINT32(n,b,i) \ +{ \ + (b)[(i) ] = (uint8) ( (n) >> 24 ); \ + (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ + (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ + (b)[(i) + 3] = (uint8) ( (n) ); \ +} + + +int rt_aes_set_key( aes_context *ctx, uint8 *key, int nbits ) +{ + int i; + uint32 *RK, *SK; + + switch( nbits ) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return( 1 ); + } + + RK = (uint32 *) ctx->erk; + + for( i = 0; i < (nbits >> 5); i++ ) + { + GET_UINT32( RK[i], key, i * 4 ); + } + + /* setup encryption round keys */ + + switch( nbits ) + { + case 128: + + for( i = 0; i < 10; i++, RK += 4 ) + { + RK[4] = RK[0] ^ RCON[i] ^ + ( FSb[ (uint8) ( RK[3] >> 16 ) ] << 24 ) ^ + ( FSb[ (uint8) ( RK[3] >> 8 ) ] << 16 ) ^ + ( FSb[ (uint8) ( RK[3] ) ] << 8 ) ^ + ( FSb[ (uint8) ( RK[3] >> 24 ) ] ); + + RK[5] = RK[1] ^ RK[4]; + RK[6] = RK[2] ^ RK[5]; + RK[7] = RK[3] ^ RK[6]; + } + break; + + case 192: + + for( i = 0; i < 8; i++, RK += 6 ) + { + RK[6] = RK[0] ^ RCON[i] ^ + ( FSb[ (uint8) ( RK[5] >> 16 ) ] << 24 ) ^ + ( FSb[ (uint8) ( RK[5] >> 8 ) ] << 16 ) ^ + ( FSb[ (uint8) ( RK[5] ) ] << 8 ) ^ + ( FSb[ (uint8) ( RK[5] >> 24 ) ] ); + + RK[7] = RK[1] ^ RK[6]; + RK[8] = RK[2] ^ RK[7]; + RK[9] = RK[3] ^ RK[8]; + RK[10] = RK[4] ^ RK[9]; + RK[11] = RK[5] ^ RK[10]; + } + break; + + case 256: + + for( i = 0; i < 7; i++, RK += 8 ) + { + RK[8] = RK[0] ^ RCON[i] ^ + ( FSb[ (uint8) ( RK[7] >> 16 ) ] << 24 ) ^ + ( FSb[ (uint8) ( RK[7] >> 8 ) ] << 16 ) ^ + ( FSb[ (uint8) ( RK[7] ) ] << 8 ) ^ + ( FSb[ (uint8) ( RK[7] >> 24 ) ] ); + + RK[9] = RK[1] ^ RK[8]; + RK[10] = RK[2] ^ RK[9]; + RK[11] = RK[3] ^ RK[10]; + + RK[12] = RK[4] ^ + ( FSb[ (uint8) ( RK[11] >> 24 ) ] << 24 ) ^ + ( FSb[ (uint8) ( RK[11] >> 16 ) ] << 16 ) ^ + ( FSb[ (uint8) ( RK[11] >> 8 ) ] << 8 ) ^ + ( FSb[ (uint8) ( RK[11] ) ] ); + + RK[13] = RK[5] ^ RK[12]; + RK[14] = RK[6] ^ RK[13]; + RK[15] = RK[7] ^ RK[14]; + } + break; + } + + /* setup decryption round keys */ + + if( KT_init ) + { + for( i = 0; i < 256; i++ ) + { + KT0[i] = RT0[ FSb[i] ]; + KT1[i] = RT1[ FSb[i] ]; + KT2[i] = RT2[ FSb[i] ]; + KT3[i] = RT3[ FSb[i] ]; + } + + KT_init = 0; + } + + SK = (uint32 *) ctx->drk; + + *SK++ = *RK++; + *SK++ = *RK++; + *SK++ = *RK++; + *SK++ = *RK++; + + for( i = 1; i < ctx->nr; i++ ) + { + RK -= 8; + + *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ + KT1[ (uint8) ( *RK >> 16 ) ] ^ + KT2[ (uint8) ( *RK >> 8 ) ] ^ + KT3[ (uint8) ( *RK ) ]; RK++; + + *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ + KT1[ (uint8) ( *RK >> 16 ) ] ^ + KT2[ (uint8) ( *RK >> 8 ) ] ^ + KT3[ (uint8) ( *RK ) ]; RK++; + + *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ + KT1[ (uint8) ( *RK >> 16 ) ] ^ + KT2[ (uint8) ( *RK >> 8 ) ] ^ + KT3[ (uint8) ( *RK ) ]; RK++; + + *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ + KT1[ (uint8) ( *RK >> 16 ) ] ^ + KT2[ (uint8) ( *RK >> 8 ) ] ^ + KT3[ (uint8) ( *RK ) ]; RK++; + } + + RK -= 8; + + *SK++ = *RK++; + *SK++ = *RK++; + *SK++ = *RK++; + *SK++ = *RK++; + + return( 0 ); +} + +/* AES 128-bit block encryption routine */ + +void rt_aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16] ) +{ + uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + + RK = (uint32 *) ctx->erk; + GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; + GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; + GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; + GET_UINT32( X3, input, 12 ); X3 ^= RK[3]; + +#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + RK += 4; \ + \ + X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \ + FT1[ (uint8) ( Y1 >> 16 ) ] ^ \ + FT2[ (uint8) ( Y2 >> 8 ) ] ^ \ + FT3[ (uint8) ( Y3 ) ]; \ + \ + X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \ + FT1[ (uint8) ( Y2 >> 16 ) ] ^ \ + FT2[ (uint8) ( Y3 >> 8 ) ] ^ \ + FT3[ (uint8) ( Y0 ) ]; \ + \ + X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \ + FT1[ (uint8) ( Y3 >> 16 ) ] ^ \ + FT2[ (uint8) ( Y0 >> 8 ) ] ^ \ + FT3[ (uint8) ( Y1 ) ]; \ + \ + X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \ + FT1[ (uint8) ( Y0 >> 16 ) ] ^ \ + FT2[ (uint8) ( Y1 >> 8 ) ] ^ \ + FT3[ (uint8) ( Y2 ) ]; \ +} + + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ + + if( ctx->nr > 10 ) + { + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ + } + + if( ctx->nr > 12 ) + { + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ + } + + /* last round */ + + RK += 4; + + X0 = RK[0] ^ ( FSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ + ( FSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ + ( FSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ + ( FSb[ (uint8) ( Y3 ) ] ); + + X1 = RK[1] ^ ( FSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ + ( FSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ + ( FSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ + ( FSb[ (uint8) ( Y0 ) ] ); + + X2 = RK[2] ^ ( FSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ + ( FSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ + ( FSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ + ( FSb[ (uint8) ( Y1 ) ] ); + + X3 = RK[3] ^ ( FSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ + ( FSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ + ( FSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ + ( FSb[ (uint8) ( Y2 ) ] ); + + PUT_UINT32( X0, output, 0 ); + PUT_UINT32( X1, output, 4 ); + PUT_UINT32( X2, output, 8 ); + PUT_UINT32( X3, output, 12 ); +} + +/* AES 128-bit block decryption routine */ + +void rt_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ) +{ + uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + + RK = (uint32 *) ctx->drk; + + GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; + GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; + GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; + GET_UINT32( X3, input, 12 ); X3 ^= RK[3]; + +#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + RK += 4; \ + \ + X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \ + RT1[ (uint8) ( Y3 >> 16 ) ] ^ \ + RT2[ (uint8) ( Y2 >> 8 ) ] ^ \ + RT3[ (uint8) ( Y1 ) ]; \ + \ + X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \ + RT1[ (uint8) ( Y0 >> 16 ) ] ^ \ + RT2[ (uint8) ( Y3 >> 8 ) ] ^ \ + RT3[ (uint8) ( Y2 ) ]; \ + \ + X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \ + RT1[ (uint8) ( Y1 >> 16 ) ] ^ \ + RT2[ (uint8) ( Y0 >> 8 ) ] ^ \ + RT3[ (uint8) ( Y3 ) ]; \ + \ + X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \ + RT1[ (uint8) ( Y2 >> 16 ) ] ^ \ + RT2[ (uint8) ( Y1 >> 8 ) ] ^ \ + RT3[ (uint8) ( Y0 ) ]; \ +} + + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ + + if( ctx->nr > 10 ) + { + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ + } + + if( ctx->nr > 12 ) + { + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ + } + + /* last round */ + + RK += 4; + + X0 = RK[0] ^ ( RSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ + ( RSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ + ( RSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ + ( RSb[ (uint8) ( Y1 ) ] ); + + X1 = RK[1] ^ ( RSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ + ( RSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ + ( RSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ + ( RSb[ (uint8) ( Y2 ) ] ); + + X2 = RK[2] ^ ( RSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ + ( RSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ + ( RSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ + ( RSb[ (uint8) ( Y3 ) ] ); + + X3 = RK[3] ^ ( RSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ + ( RSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ + ( RSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ + ( RSb[ (uint8) ( Y0 ) ] ); + + PUT_UINT32( X0, output, 0 ); + PUT_UINT32( X1, output, 4 ); + PUT_UINT32( X2, output, 8 ); + PUT_UINT32( X3, output, 12 ); +} + +/* + ========================================================================== + Description: + ENCRYPT AES GTK before sending in EAPOL frame. + AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function. + This function references to RFC 3394 for aes key wrap algorithm. + Return: + ========================================================================== +*/ +VOID AES_GTK_KEY_WRAP( + IN UCHAR *key, + IN UCHAR *plaintext, + IN UINT32 p_len, + OUT UCHAR *ciphertext) +{ + UCHAR A[8], BIN[16], BOUT[16]; + UCHAR R[512]; + INT num_blocks = p_len/8; // unit:64bits + INT i, j; + aes_context aesctx; + UCHAR xor; + + rt_aes_set_key(&aesctx, key, 128); + + // Init IA + for (i = 0; i < 8; i++) + A[i] = 0xa6; + + //Input plaintext + for (i = 0; i < num_blocks; i++) + { + for (j = 0 ; j < 8; j++) + R[8 * (i + 1) + j] = plaintext[8 * i + j]; + } + + // Key Mix + for (j = 0; j < 6; j++) + { + for(i = 1; i <= num_blocks; i++) + { + //phase 1 + NdisMoveMemory(BIN, A, 8); + NdisMoveMemory(&BIN[8], &R[8 * i], 8); + rt_aes_encrypt(&aesctx, BIN, BOUT); + + NdisMoveMemory(A, &BOUT[0], 8); + xor = num_blocks * j + i; + A[7] = BOUT[7] ^ xor; + NdisMoveMemory(&R[8 * i], &BOUT[8], 8); + } + } + + // Output ciphertext + NdisMoveMemory(ciphertext, A, 8); + + for (i = 1; i <= num_blocks; i++) + { + for (j = 0 ; j < 8; j++) + ciphertext[8 * i + j] = R[8 * i + j]; + } +} + +/* + ======================================================================== + + Routine Description: + Misc function to decrypt AES body + + Arguments: + + Return Value: + + Note: + This function references to RFC 3394 for aes key unwrap algorithm. + + ======================================================================== +*/ +VOID AES_GTK_KEY_UNWRAP( + IN UCHAR *key, + OUT UCHAR *plaintext, + IN UINT32 c_len, + IN UCHAR *ciphertext) + +{ + UCHAR A[8], BIN[16], BOUT[16]; + UCHAR xor; + INT i, j; + aes_context aesctx; + UCHAR *R; + INT num_blocks = c_len/8; // unit:64bits + + + os_alloc_mem(NULL, (PUCHAR *)&R, 512); + + if (R == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n")); + return; + } /* End of if */ + + // Initialize + NdisMoveMemory(A, ciphertext, 8); + //Input plaintext + for(i = 0; i < (c_len-8); i++) + { + R[ i] = ciphertext[i + 8]; + } + + rt_aes_set_key(&aesctx, key, 128); + + for(j = 5; j >= 0; j--) + { + for(i = (num_blocks-1); i > 0; i--) + { + xor = (num_blocks -1 )* j + i; + NdisMoveMemory(BIN, A, 8); + BIN[7] = A[7] ^ xor; + NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8); + rt_aes_decrypt(&aesctx, BIN, BOUT); + NdisMoveMemory(A, &BOUT[0], 8); + NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8); + } + } + + // OUTPUT + for(i = 0; i < c_len; i++) + { + plaintext[i] = R[i]; + } + + + os_free_mem(NULL, R); +} + + +/* ======= The related function of AES-128-CMAC ======= */ +VOID leftshift_onebit( + IN PUCHAR input, + OUT PUCHAR output) +{ + INT i; + UCHAR overflow = 0; + + for (i=15; i>=0; i--) + { + output[i] = input[i] << 1; + output[i] |= overflow; + overflow = (input[i] & 0x80) ? 1 : 0; + } +} + +VOID do_padding( + IN PUCHAR lastb, + OUT PUCHAR pad, + IN INT len) +{ + INT j; + + for (j=0; j<16; j++) + { + if (j < len) + pad[j] = lastb[j]; + else if (j == len) + pad[j] = 0x80; + else + pad[j] = 0x00; + } + + +} + +/* + * The Subkey Generation Algorithm + */ +VOID generate_subkey( + IN PUCHAR key, + OUT PUCHAR K1, + OUT PUCHAR K2) +{ + aes_context aesctx; + UCHAR aes_128_key[16]; + UCHAR const_Zero[16]; + UCHAR tmp[16]; + UCHAR const_Rb[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87}; + + // initial the key material + memset(const_Zero, 0, 16); + memset(aes_128_key, 0, 16); + + // AES-128 with key is applied to an all-zero input block + rt_aes_set_key(&aesctx, key, 128); + rt_aes_encrypt(&aesctx, const_Zero, aes_128_key); + + // derive K1(128-bit first subkey) and K2(128-bit second subkey), refer to rfc-4493 ch 2.3 + if ((aes_128_key[0] & 0x80) == 0) + { + leftshift_onebit(aes_128_key, K1); + } + else + { + leftshift_onebit(aes_128_key, tmp); + xor_128(tmp, const_Rb, K1); + } + + if ((K1[0] & 0x80) == 0) + { + leftshift_onebit(K1, K2); + } + else + { + leftshift_onebit(K1, tmp); + xor_128(tmp, const_Rb, K2); + } + +} + +/* + * AES-CMAC Algorithm. (refer to rfc-4493 and SP800-38B) + * + * Input : key (128-bit key) + * input (message to be authenticated) + * len (length of the message in octets) + * + * output: mac (message authentication code) + */ +VOID AES_128_CMAC( + IN PUCHAR key, + IN PUCHAR input, + IN INT len, + OUT PUCHAR mac) +{ + UCHAR X[16], Y[16], M_last[16], padded[16]; + UCHAR K1[16], K2[16]; + aes_context aesctx; + INT n, i, flag; + + generate_subkey(key, K1, K2); + + n = (len+15) / 16; // n is number of rounds + + if (n == 0) + { + n = 1; + flag = 0; + } + else + { + if ((len%16) == 0) + flag = 1; // indicate that last block is a complete block + else + flag = 0; // indicate that last block is not a complete block + } + + if (flag) + { + xor_128(&input[16*(n-1)], K1, M_last); + } + else + { + do_padding(&input[16*(n-1)], padded, len%16); + xor_128(padded, K2, M_last); + } + + memset(X, 0, 16); + for (i=0; i5. + + // 802.11 HyperLan 2 + {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783}, + + // 2008.04.30 modified + // The system team has AN to improve the EVM value + // for channel 102 to 108 for the RT2850/RT2750 dual band solution. + {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793}, + {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3}, + {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193}, + + {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183}, + {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b}, + {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3}, + {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193}, + {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183}, + {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193}, + {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927 + {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3}, + {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b}, + {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193}, + {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b}, + {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183}, + + // 802.11 UNII + {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7}, + {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187}, + {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f}, + {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f}, + {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7}, + {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187}, + {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197}, + {167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f}, + {169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327}, + {171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307}, + {173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f}, + + // Japan + {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b}, + {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13}, + {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b}, + {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23}, + {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13}, + {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b}, + {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23}, + + // still lack of MMAC(Japan) ch 34,38,42,46 +}; +UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS)); + +FREQUENCY_ITEM FreqItems3020[] = +{ + /**************************************************/ + // ISM : 2.4 to 2.483 GHz // + /**************************************************/ + // 11g + /**************************************************/ + //-CH---N-------R---K----------- + {1, 241, 2, 2}, + {2, 241, 2, 7}, + {3, 242, 2, 2}, + {4, 242, 2, 7}, + {5, 243, 2, 2}, + {6, 243, 2, 7}, + {7, 244, 2, 2}, + {8, 244, 2, 7}, + {9, 245, 2, 2}, + {10, 245, 2, 7}, + {11, 246, 2, 2}, + {12, 246, 2, 7}, + {13, 247, 2, 2}, + {14, 248, 2, 4}, +}; +UCHAR NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM)); + + +VOID AsicUpdateAutoFallBackTable( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pRateTable) +{ + UCHAR i; + HT_FBK_CFG0_STRUC HtCfg0; + HT_FBK_CFG1_STRUC HtCfg1; + LG_FBK_CFG0_STRUC LgCfg0; + LG_FBK_CFG1_STRUC LgCfg1; + PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate; + + // set to initial value + HtCfg0.word = 0x65432100; + HtCfg1.word = 0xedcba988; + LgCfg0.word = 0xedcba988; + LgCfg1.word = 0x00002100; + + pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1; + for (i = 1; i < *((PUCHAR) pRateTable); i++) + { + pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i; + switch (pCurrTxRate->Mode) + { + case 0: //CCK + break; + case 1: //OFDM + { + switch(pCurrTxRate->CurrMCS) + { + case 0: + LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 1: + LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 2: + LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 3: + LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 4: + LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 5: + LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 6: + LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + case 7: + LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; + break; + } + } + break; + case 2: //HT-MIX + case 3: //HT-GF + { + if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS)) + { + switch(pCurrTxRate->CurrMCS) + { + case 0: + HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS; + break; + case 1: + HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS; + break; + case 2: + HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS; + break; + case 3: + HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS; + break; + case 4: + HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS; + break; + case 5: + HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS; + break; + case 6: + HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS; + break; + case 7: + HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS; + break; + case 8: + HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS; + break; + case 9: + HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS; + break; + case 10: + HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS; + break; + case 11: + HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS; + break; + case 12: + HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS; + break; + case 13: + HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS; + break; + case 14: + HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS; + break; + case 15: + HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS; + break; + default: + DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS)); + } + } + } + break; + } + + pNextTxRate = pCurrTxRate; + } + + RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word); + RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word); + RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word); + RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word); +} + +/* + ======================================================================== + + Routine Description: + Set MAC register value according operation mode. + OperationMode AND bNonGFExist are for MM and GF Proteciton. + If MM or GF mask is not set, those passing argument doesn't not take effect. + + Operation mode meaning: + = 0 : Pure HT, no preotection. + = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS. + = 0x10: No Transmission in 40M is protected. + = 0x11: Transmission in both 40M and 20M shall be protected + if (bNonGFExist) + we should choose not to use GF. But still set correct ASIC registers. + ======================================================================== +*/ +VOID AsicUpdateProtect( + IN PRTMP_ADAPTER pAd, + IN USHORT OperationMode, + IN UCHAR SetMask, + IN BOOLEAN bDisableBGProtect, + IN BOOLEAN bNonGFExist) +{ + PROT_CFG_STRUC ProtCfg, ProtCfg4; + UINT32 Protect[6]; + USHORT offset; + UCHAR i; + UINT32 MacReg = 0; + + + if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8)) + { + return; + } + + if (pAd->BATable.numDoneOriginator) + { + // + // enable the RTS/CTS to avoid channel collision + // + SetMask = ALLN_SETPROTECT; + OperationMode = 8; + } + + // Config ASIC RTS threshold register + RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg); + MacReg &= 0xFF0000FF; + // If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096 + if (( + (pAd->CommonCfg.BACapability.field.AmsduEnable) || + (pAd->CommonCfg.bAggregationCapable == TRUE)) + && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD) + { + MacReg |= (0x1000 << 8); + } + else + { + MacReg |= (pAd->CommonCfg.RtsThreshold << 8); + } + + RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg); + + // Initial common protection settings + RTMPZeroMemory(Protect, sizeof(Protect)); + ProtCfg4.word = 0; + ProtCfg.word = 0; + ProtCfg.field.TxopAllowGF40 = 1; + ProtCfg.field.TxopAllowGF20 = 1; + ProtCfg.field.TxopAllowMM40 = 1; + ProtCfg.field.TxopAllowMM20 = 1; + ProtCfg.field.TxopAllowOfdm = 1; + ProtCfg.field.TxopAllowCck = 1; + ProtCfg.field.RTSThEn = 1; + ProtCfg.field.ProtectNav = ASIC_SHORTNAV; + + // update PHY mode and rate + if (pAd->CommonCfg.Channel > 14) + ProtCfg.field.ProtectRate = 0x4000; + ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate; + + // Handle legacy(B/G) protection + if (bDisableBGProtect) + { + //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; + ProtCfg.field.ProtectCtrl = 0; + Protect[0] = ProtCfg.word; + Protect[1] = ProtCfg.word; + pAd->FlgCtsEnabled = 0; /* CTS-self is not used */ + } + else + { + //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; + ProtCfg.field.ProtectCtrl = 0; // CCK do not need to be protected + Protect[0] = ProtCfg.word; + ProtCfg.field.ProtectCtrl = ASIC_CTS; // OFDM needs using CCK to protect + Protect[1] = ProtCfg.word; + pAd->FlgCtsEnabled = 1; /* CTS-self is used */ + } + + // Decide HT frame protection. + if ((SetMask & ALLN_SETPROTECT) != 0) + { + switch(OperationMode) + { + case 0x0: + // NO PROTECT + // 1.All STAs in the BSS are 20/40 MHz HT + // 2. in ai 20/40MHz BSS + // 3. all STAs are 20MHz in a 20MHz BSS + // Pure HT. no protection. + + // MM20_PROT_CFG + // Reserved (31:27) + // PROT_TXOP(25:20) -- 010111 + // PROT_NAV(19:18) -- 01 (Short NAV protection) + // PROT_CTRL(17:16) -- 00 (None) + // PROT_RATE(15:0) -- 0x4004 (OFDM 24M) + Protect[2] = 0x01744004; + + // MM40_PROT_CFG + // Reserved (31:27) + // PROT_TXOP(25:20) -- 111111 + // PROT_NAV(19:18) -- 01 (Short NAV protection) + // PROT_CTRL(17:16) -- 00 (None) + // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M) + Protect[3] = 0x03f44084; + + // CF20_PROT_CFG + // Reserved (31:27) + // PROT_TXOP(25:20) -- 010111 + // PROT_NAV(19:18) -- 01 (Short NAV protection) + // PROT_CTRL(17:16) -- 00 (None) + // PROT_RATE(15:0) -- 0x4004 (OFDM 24M) + Protect[4] = 0x01744004; + + // CF40_PROT_CFG + // Reserved (31:27) + // PROT_TXOP(25:20) -- 111111 + // PROT_NAV(19:18) -- 01 (Short NAV protection) + // PROT_CTRL(17:16) -- 00 (None) + // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M) + Protect[5] = 0x03f44084; + + if (bNonGFExist) + { + // PROT_NAV(19:18) -- 01 (Short NAV protectiion) + // PROT_CTRL(17:16) -- 01 (RTS/CTS) + Protect[4] = 0x01754004; + Protect[5] = 0x03f54084; + } + pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE; + break; + + case 1: + // This is "HT non-member protection mode." + // If there may be non-HT STAs my BSS + ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None) + ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1. + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) + { + ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18.. + ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083; + } + //Assign Protection method for 20&40 MHz packets + ProtCfg.field.ProtectCtrl = ASIC_RTS; + ProtCfg.field.ProtectNav = ASIC_SHORTNAV; + ProtCfg4.field.ProtectCtrl = ASIC_RTS; + ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; + Protect[2] = ProtCfg.word; + Protect[3] = ProtCfg4.word; + Protect[4] = ProtCfg.word; + Protect[5] = ProtCfg4.word; + pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; + break; + + case 2: + // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets + ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None) + ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1. + + //Assign Protection method for 40MHz packets + ProtCfg4.field.ProtectCtrl = ASIC_RTS; + ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; + Protect[2] = ProtCfg.word; + Protect[3] = ProtCfg4.word; + if (bNonGFExist) + { + ProtCfg.field.ProtectCtrl = ASIC_RTS; + ProtCfg.field.ProtectNav = ASIC_SHORTNAV; + } + Protect[4] = ProtCfg.word; + Protect[5] = ProtCfg4.word; + + pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE; + break; + + case 3: + // HT mixed mode. PROTECT ALL! + // Assign Rate + ProtCfg.word = 0x01744004; //duplicaet legacy 24M. BW set 1. + ProtCfg4.word = 0x03f44084; + // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) + { + ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18.. + ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083 + } + //Assign Protection method for 20&40 MHz packets + ProtCfg.field.ProtectCtrl = ASIC_RTS; + ProtCfg.field.ProtectNav = ASIC_SHORTNAV; + ProtCfg4.field.ProtectCtrl = ASIC_RTS; + ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; + Protect[2] = ProtCfg.word; + Protect[3] = ProtCfg4.word; + Protect[4] = ProtCfg.word; + Protect[5] = ProtCfg4.word; + pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; + break; + + case 8: + // Special on for Atheros problem n chip. + Protect[2] = 0x01754004; + Protect[3] = 0x03f54084; + Protect[4] = 0x01754004; + Protect[5] = 0x03f54084; + pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; + break; + } + } + + offset = CCK_PROT_CFG; + for (i = 0;i < 6;i++) + { + if ((SetMask & (1<< i))) + { + RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]); + } +} +} + + +/* + ========================================================================== + Description: + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicSwitchChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel, + IN BOOLEAN bScan) +{ + ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0; + CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER; + UCHAR index; + UINT32 Value = 0; //BbpReg, Value; + RTMP_RF_REGS *RFRegTable; + UCHAR RFValue; + + RFValue = 0; + // Search Tx power value + // We can't use ChannelList to search channel, since some central channl's txpowr doesn't list + // in ChannelList, so use TxPower array instead. + // + for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) + { + if (Channel == pAd->TxPower[index].Channel) + { + TxPwer = pAd->TxPower[index].Power; + TxPwer2 = pAd->TxPower[index].Power2; + break; + } + } + + if (index == MAX_NUM_OF_CHANNELS) + { + DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel)); + } + +#ifdef RT30xx + // The RF programming sequence is difference between 3xxx and 2xxx + if ((IS_RT3070(pAd) || IS_RT3090(pAd)||IS_RT3390(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) || + (pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022))) + { + /* modify by WY for Read RF Reg. error */ + + for (index = 0; index < NUM_OF_3020_CHNL; index++) + { + if (Channel == FreqItems3020[index].Channel) + { + // Programming channel parameters + RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N); + RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K); + RT30xxReadRFRegister(pAd, RF_R06, &RFValue); + RFValue = (RFValue & 0xFC) | FreqItems3020[index].R; + RT30xxWriteRFRegister(pAd, RF_R06, RFValue); + + // Set Tx0 Power + RT30xxReadRFRegister(pAd, RF_R12, &RFValue); + RFValue = (RFValue & 0xE0) | TxPwer; + RT30xxWriteRFRegister(pAd, RF_R12, RFValue); + + // Set Tx1 Power + RT30xxReadRFRegister(pAd, RF_R13, &RFValue); + RFValue = (RFValue & 0xE0) | TxPwer2; + RT30xxWriteRFRegister(pAd, RF_R13, RFValue); + + // Tx/Rx Stream setting + RT30xxReadRFRegister(pAd, RF_R01, &RFValue); + //if (IS_RT3090(pAd)) + // RFValue |= 0x01; // Enable RF block. + RFValue &= 0x03; //clear bit[7~2] + if (pAd->Antenna.field.TxPath == 1) + RFValue |= 0xA0; + else if (pAd->Antenna.field.TxPath == 2) + RFValue |= 0x80; + if (pAd->Antenna.field.RxPath == 1) + RFValue |= 0x50; + else if (pAd->Antenna.field.RxPath == 2) + RFValue |= 0x40; + RT30xxWriteRFRegister(pAd, RF_R01, RFValue); + + // Set RF offset + RT30xxReadRFRegister(pAd, RF_R23, &RFValue); + RFValue = (RFValue & 0x80) | pAd->RfFreqOffset; + RT30xxWriteRFRegister(pAd, RF_R23, RFValue); + + // Set BW + if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40)) + { + RFValue = pAd->Mlme.CaliBW40RfR24; + //DISABLE_11N_CHECK(pAd); + } + else + { + RFValue = pAd->Mlme.CaliBW20RfR24; + } + RT30xxWriteRFRegister(pAd, RF_R24, RFValue); + RT30xxWriteRFRegister(pAd, RF_R31, RFValue); + + // Enable RF tuning + RT30xxReadRFRegister(pAd, RF_R07, &RFValue); + RFValue = RFValue | 0x1; + RT30xxWriteRFRegister(pAd, RF_R07, RFValue); + + // latch channel for future usage. + pAd->LatchRfRegs.Channel = Channel; + + DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", + Channel, + pAd->RfIcType, + TxPwer, + TxPwer2, + pAd->Antenna.field.TxPath, + FreqItems3020[index].N, + FreqItems3020[index].K, + FreqItems3020[index].R)); + + break; + } + } + } + else +#endif // RT30xx // + { + RFRegTable = RF2850RegTable; + switch (pAd->RfIcType) + { + case RFIC_2820: + case RFIC_2850: + case RFIC_2720: + case RFIC_2750: + + for (index = 0; index < NUM_OF_2850_CHNL; index++) + { + if (Channel == RFRegTable[index].Channel) + { + R2 = RFRegTable[index].R2; + if (pAd->Antenna.field.TxPath == 1) + { + R2 |= 0x4000; // If TXpath is 1, bit 14 = 1; + } + + if (pAd->Antenna.field.RxPath == 2) + { + R2 |= 0x40; // write 1 to off Rxpath. + } + else if (pAd->Antenna.field.RxPath == 1) + { + R2 |= 0x20040; // write 1 to off RxPath + } + + if (Channel > 14) + { + // initialize R3, R4 + R3 = (RFRegTable[index].R3 & 0xffffc1ff); + R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15); + + // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB + // R3 + if ((TxPwer >= -7) && (TxPwer < 0)) + { + TxPwer = (7+TxPwer); + TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer); + R3 |= (TxPwer << 10); + DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer)); + } + else + { + TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer); + R3 |= (TxPwer << 10) | (1 << 9); + } + + // R4 + if ((TxPwer2 >= -7) && (TxPwer2 < 0)) + { + TxPwer2 = (7+TxPwer2); + TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2); + R4 |= (TxPwer2 << 7); + DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2)); + } + else + { + TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2); + R4 |= (TxPwer2 << 7) | (1 << 6); + } + } + else + { + R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0 + R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1 + } + + // Based on BBP current mode before changing RF channel. + if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40)) + { + R4 |=0x200000; + } + + // Update variables + pAd->LatchRfRegs.Channel = Channel; + pAd->LatchRfRegs.R1 = RFRegTable[index].R1; + pAd->LatchRfRegs.R2 = R2; + pAd->LatchRfRegs.R3 = R3; + pAd->LatchRfRegs.R4 = R4; + + // Set RF value 1's set R3[bit2] = [0] + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04))); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); + + RTMPusecDelay(200); + + // Set RF value 2's set R3[bit2] = [1] + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04)); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); + + RTMPusecDelay(200); + + // Set RF value 3's set R3[bit2] = [0] + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); + RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04))); + RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); + + break; + } + } + break; + + default: + break; + } + + 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", + Channel, + pAd->RfIcType, + (R3 & 0x00003e00) >> 9, + (R4 & 0x000007c0) >> 6, + pAd->Antenna.field.TxPath, + pAd->LatchRfRegs.R1, + pAd->LatchRfRegs.R2, + pAd->LatchRfRegs.R3, + pAd->LatchRfRegs.R4)); + } + + // Change BBP setting during siwtch from a->g, g->a + if (Channel <= 14) + { + ULONG TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); + 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. + //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); + + // Rx High power VGA offset for LNA select + if (pAd->NicConfig2.field.ExternalLNAForG) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + + // 5G band selection PIN, bit1 and bit2 are complement + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x6); + Value |= (0x04); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + // Turn off unused PA or LNA when only 1T or 1R + if (pAd->Antenna.field.TxPath == 1) + { + TxPinCfg &= 0xFFFFFFF3; + } + if (pAd->Antenna.field.RxPath == 1) + { + TxPinCfg &= 0xFFFFF3FF; + } + + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + + } + else + { + ULONG TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505 + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); + 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. + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2); + + // Rx High power VGA offset for LNA select + if (pAd->NicConfig2.field.ExternalLNAForA) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); + } + else + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); + } + + // 5G band selection PIN, bit1 and bit2 are complement + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); + Value &= (~0x6); + Value |= (0x02); + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + + // Turn off unused PA or LNA when only 1T or 1R + if (pAd->Antenna.field.TxPath == 1) + { + TxPinCfg &= 0xFFFFFFF3; + } + if (pAd->Antenna.field.RxPath == 1) + { + TxPinCfg &= 0xFFFFF3FF; + } + + + RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); + + } + + // R66 should be set according to Channel and use 20MHz when scanning + //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd))); + if (bScan) + RTMPSetAGCInitValue(pAd, BW_20); + else + RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); + + // + // On 11A, We should delay and wait RF/BBP to be stable + // and the appropriate time should be 1000 micro seconds + // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. + // + RTMPusecDelay(1000); +} + +VOID AsicResetBBPAgent( +IN PRTMP_ADAPTER pAd) +{ + BBP_CSR_CFG_STRUC BbpCsr; + DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit.!! \n")); + // Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first. + RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word); + BbpCsr.field.Busy = 0; + RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word); +} + +/* + ========================================================================== + Description: + This function is required for 2421 only, and should not be used during + site survey. It's only required after NIC decided to stay at a channel + for a longer period. + When this function is called, it's always after AsicSwitchChannel(). + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicLockChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel) +{ +} + +VOID AsicRfTuningExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ +} + +/* + ========================================================================== + Description: + Gives CCK TX rate 2 more dB TX power. + This routine works only in LINK UP in INFRASTRUCTURE mode. + + calculate desired Tx power in RF R3.Tx0~5, should consider - + 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment) + 1. TxPowerPercentage + 2. auto calibration based on TSSI feedback + 3. extra 2 db for CCK + 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP + + NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment), + it should be called AFTER MlmeDynamicTxRatSwitching() + ========================================================================== + */ +VOID AsicAdjustTxPower( + IN PRTMP_ADAPTER pAd) +{ + INT i, j; + CHAR DeltaPwr = 0; + BOOLEAN bAutoTxAgc = FALSE; + UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep; + UCHAR BbpR1 = 0, BbpR49 = 0, idx; + PCHAR pTxAgcCompensate; + ULONG TxPwr[5]; + CHAR Value; + CHAR Rssi = -127; + + + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) || +#ifdef RTMP_MAC_PCI + (pAd->bPCIclkOff == TRUE) || +#endif // RTMP_MAC_PCI // + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) || + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + return; + + Rssi = RTMPMaxRssi(pAd, + pAd->StaCfg.RssiSample.AvgRssi0, + pAd->StaCfg.RssiSample.AvgRssi1, + pAd->StaCfg.RssiSample.AvgRssi2); + + if (pAd->CommonCfg.BBPCurrentBW == BW_40) + { + if (pAd->CommonCfg.CentralChannel > 14) + { + TxPwr[0] = pAd->Tx40MPwrCfgABand[0]; + TxPwr[1] = pAd->Tx40MPwrCfgABand[1]; + TxPwr[2] = pAd->Tx40MPwrCfgABand[2]; + TxPwr[3] = pAd->Tx40MPwrCfgABand[3]; + TxPwr[4] = pAd->Tx40MPwrCfgABand[4]; + } + else + { + TxPwr[0] = pAd->Tx40MPwrCfgGBand[0]; + TxPwr[1] = pAd->Tx40MPwrCfgGBand[1]; + TxPwr[2] = pAd->Tx40MPwrCfgGBand[2]; + TxPwr[3] = pAd->Tx40MPwrCfgGBand[3]; + TxPwr[4] = pAd->Tx40MPwrCfgGBand[4]; + } + } + else + { + if (pAd->CommonCfg.Channel > 14) + { + TxPwr[0] = pAd->Tx20MPwrCfgABand[0]; + TxPwr[1] = pAd->Tx20MPwrCfgABand[1]; + TxPwr[2] = pAd->Tx20MPwrCfgABand[2]; + TxPwr[3] = pAd->Tx20MPwrCfgABand[3]; + TxPwr[4] = pAd->Tx20MPwrCfgABand[4]; + } + else + { + TxPwr[0] = pAd->Tx20MPwrCfgGBand[0]; + TxPwr[1] = pAd->Tx20MPwrCfgGBand[1]; + TxPwr[2] = pAd->Tx20MPwrCfgGBand[2]; + TxPwr[3] = pAd->Tx20MPwrCfgGBand[3]; + TxPwr[4] = pAd->Tx20MPwrCfgGBand[4]; + } + } + + // TX power compensation for temperature variation based on TSSI. try every 4 second + if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) + { + if (pAd->CommonCfg.Channel <= 14) + { + /* bg channel */ + bAutoTxAgc = pAd->bAutoTxAgcG; + TssiRef = pAd->TssiRefG; + pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0]; + pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0]; + TxAgcStep = pAd->TxAgcStepG; + pTxAgcCompensate = &pAd->TxAgcCompensateG; + } + else + { + /* a channel */ + bAutoTxAgc = pAd->bAutoTxAgcA; + TssiRef = pAd->TssiRefA; + pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0]; + pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0]; + TxAgcStep = pAd->TxAgcStepA; + pTxAgcCompensate = &pAd->TxAgcCompensateA; + } + + if (bAutoTxAgc) + { + /* BbpR1 is unsigned char */ + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49); + + /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */ + /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */ + /* step value is defined in pAd->TxAgcStepG for tx power value */ + + /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */ + /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0 + above value are examined in mass factory production */ + /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */ + + /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */ + /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */ + /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */ + + if (BbpR49 > pTssiMinusBoundary[1]) + { + // Reading is larger than the reference value + // check for how large we need to decrease the Tx power + for (idx = 1; idx < 5; idx++) + { + if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range + break; + } + // The index is the step we should decrease, idx = 0 means there is nothing to compensate +// if (R3 > (ULONG) (TxAgcStep * (idx-1))) + *pTxAgcCompensate = -(TxAgcStep * (idx-1)); +// else +// *pTxAgcCompensate = -((UCHAR)R3); + + DeltaPwr += (*pTxAgcCompensate); + DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n", + BbpR49, TssiRef, TxAgcStep, idx-1)); + } + else if (BbpR49 < pTssiPlusBoundary[1]) + { + // Reading is smaller than the reference value + // check for how large we need to increase the Tx power + for (idx = 1; idx < 5; idx++) + { + if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range + break; + } + // The index is the step we should increase, idx = 0 means there is nothing to compensate + *pTxAgcCompensate = TxAgcStep * (idx-1); + DeltaPwr += (*pTxAgcCompensate); + DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", + BbpR49, TssiRef, TxAgcStep, idx-1)); + } + else + { + *pTxAgcCompensate = 0; + DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", + BbpR49, TssiRef, TxAgcStep, 0)); + } + } + } + else + { + if (pAd->CommonCfg.Channel <= 14) + { + bAutoTxAgc = pAd->bAutoTxAgcG; + pTxAgcCompensate = &pAd->TxAgcCompensateG; + } + else + { + bAutoTxAgc = pAd->bAutoTxAgcA; + pTxAgcCompensate = &pAd->TxAgcCompensateA; + } + + if (bAutoTxAgc) + DeltaPwr += (*pTxAgcCompensate); + } + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1); + BbpR1 &= 0xFC; + + + /* calculate delta power based on the percentage specified from UI */ + // E2PROM setting is calibrated for maximum TX power (i.e. 100%) + // We lower TX power here according to the percentage specified from UI + if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control + { + { + // to patch high power issue with some APs, like Belkin N1. + if (Rssi > -35) + { + BbpR1 |= 0x02; // DeltaPwr -= 12; + } + else if (Rssi > -40) + { + BbpR1 |= 0x01; // DeltaPwr -= 6; + } + else + ; + } + } + else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW + ; + else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1; + { + DeltaPwr -= 1; + } + else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3; + { + DeltaPwr -= 3; + } + else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6; + { + BbpR1 |= 0x01; + } + else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9; + { + BbpR1 |= 0x01; + DeltaPwr -= 3; + } + else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12; + { + BbpR1 |= 0x02; + } + + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1); + + /* reset different new tx power for different TX rate */ + for(i=0; i<5; i++) + { + if (TxPwr[i] != 0xffffffff) + { + for (j=0; j<8; j++) + { + Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */ + + if ((Value + DeltaPwr) < 0) + { + Value = 0; /* min */ + } + else if ((Value + DeltaPwr) > 0xF) + { + Value = 0xF; /* max */ + } + else + { + Value += DeltaPwr; /* temperature compensation */ + } + + /* fill new value to CSR offset */ + TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4); + } + + /* write tx power value to CSR */ + /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M + TX power for OFDM 6M/9M + TX power for CCK5.5M/11M + TX power for CCK1M/2M */ + /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */ + RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]); + } + } + + +} + + +/* + ========================================================================== + Description: + put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup + automatically. Instead, MCU will issue a TwakeUpInterrupt to host after + the wakeup timer timeout. Driver has to issue a separate command to wake + PHY up. + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicSleepThenAutoWakeup( + IN PRTMP_ADAPTER pAd, + IN USHORT TbttNumToNextWakeUp) +{ + RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp); +} + +/* + ========================================================================== + Description: + AsicForceWakeup() is used whenever manual wakeup is required + AsicForceSleep() should only be used when not in INFRA BSS. When + in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead. + ========================================================================== + */ +VOID AsicForceSleep( + IN PRTMP_ADAPTER pAd) +{ + +} + +/* + ========================================================================== + Description: + AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup) + expired. + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + ========================================================================== + */ +VOID AsicForceWakeup( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bFromTx) +{ + DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n")); + RTMP_STA_FORCE_WAKEUP(pAd, bFromTx); +} + + +/* + ========================================================================== + Description: + Set My BSSID + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicSetBssid( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pBssid) +{ + ULONG Addr4; + DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n", + pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5])); + + Addr4 = (ULONG)(pBssid[0]) | + (ULONG)(pBssid[1] << 8) | + (ULONG)(pBssid[2] << 16) | + (ULONG)(pBssid[3] << 24); + RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4); + + Addr4 = 0; + // always one BSSID in STA mode + Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8); + + RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4); +} + +VOID AsicSetMcastWC( + IN PRTMP_ADAPTER pAd) +{ + MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID]; + USHORT offset; + + pEntry->Sst = SST_ASSOC; + pEntry->Aid = MCAST_WCID; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index + pEntry->PsMode = PWR_ACTIVE; + pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate; + offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicDelWcidTab( + IN PRTMP_ADAPTER pAd, + IN UCHAR Wcid) +{ + ULONG Addr0 = 0x0, Addr1 = 0x0; + ULONG offset; + + DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid)); + offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE; + RTMP_IO_WRITE32(pAd, offset, Addr0); + offset += 4; + RTMP_IO_WRITE32(pAd, offset, Addr1); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicEnableRDG( + IN PRTMP_ADAPTER pAd) +{ + TX_LINK_CFG_STRUC TxLinkCfg; + UINT32 Data = 0; + + RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); + TxLinkCfg.field.TxRDGEn = 1; + RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); + + RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); + Data &= 0xFFFFFF00; + Data |= 0x80; + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); + + //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicDisableRDG( + IN PRTMP_ADAPTER pAd) +{ + TX_LINK_CFG_STRUC TxLinkCfg; + UINT32 Data = 0; + + + RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); + TxLinkCfg.field.TxRDGEn = 0; + RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); + + RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); + + Data &= 0xFFFFFF00; + //Data |= 0x20; +#ifndef WIFI_TEST + //if ( pAd->CommonCfg.bEnableTxBurst ) + // Data |= 0x60; // for performance issue not set the TXOP to 0 +#endif + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE) + && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE) + ) + { + // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode + if (pAd->CommonCfg.bEnableTxBurst) + Data |= 0x20; + } + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); +} + +/* + ========================================================================== + Description: + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicDisableSync( + IN PRTMP_ADAPTER pAd) +{ + BCN_TIME_CFG_STRUC csr; + + DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n")); + + // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect + // that NIC will never wakes up because TSF stops and no more + // TBTT interrupts + pAd->TbttTickCount = 0; + RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); + csr.field.bBeaconGen = 0; + csr.field.bTBTTEnable = 0; + csr.field.TsfSyncMode = 0; + csr.field.bTsfTicking = 0; + RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); + +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicEnableBssSync( + IN PRTMP_ADAPTER pAd) +{ + BCN_TIME_CFG_STRUC csr; + + DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n")); + + RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); +// RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000); + { + csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU + csr.field.bTsfTicking = 1; + csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode + csr.field.bBeaconGen = 0; // do NOT generate BEACON + csr.field.bTBTTEnable = 1; + } + RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); +} + +/* + ========================================================================== + Description: + Note: + BEACON frame in shared memory should be built ok before this routine + can be called. Otherwise, a garbage frame maybe transmitted out every + Beacon period. + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicEnableIbssSync( + IN PRTMP_ADAPTER pAd) +{ + BCN_TIME_CFG_STRUC csr9; + PUCHAR ptr; + UINT i; + + DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount)); + + RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word); + csr9.field.bBeaconGen = 0; + csr9.field.bTBTTEnable = 0; + csr9.field.bTsfTicking = 0; + RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word); + +#ifdef RTMP_MAC_PCI + // move BEACON TXD and frame content to on-chip memory + ptr = (PUCHAR)&pAd->BeaconTxWI; + for (i=0; iBeaconBuf; + for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4) + { + UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); + RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr); + ptr +=4; + } +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB + // move BEACON TXD and frame content to on-chip memory + ptr = (PUCHAR)&pAd->BeaconTxWI; + for (i=0; iBeaconBuf; + for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2) + { + //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); + //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr); + RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2); + ptr +=2; + } +#endif // RTMP_MAC_USB // + + // + // For Wi-Fi faily generated beacons between participating stations. + // Set TBTT phase adaptive adjustment step to 8us (default 16us) + // don't change settings 2006-5- by Jerry + //RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010); + + // start sending BEACON + csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU + csr9.field.bTsfTicking = 1; + csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode + csr9.field.bTBTTEnable = 1; + csr9.field.bBeaconGen = 1; + RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word); +} + +/* + ========================================================================== + Description: + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicSetEdcaParm( + IN PRTMP_ADAPTER pAd, + IN PEDCA_PARM pEdcaParm) +{ + EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg; + AC_TXOP_CSR0_STRUC csr0; + AC_TXOP_CSR1_STRUC csr1; + AIFSN_CSR_STRUC AifsnCsr; + CWMIN_CSR_STRUC CwminCsr; + CWMAX_CSR_STRUC CwmaxCsr; + int i; + + Ac0Cfg.word = 0; + Ac1Cfg.word = 0; + Ac2Cfg.word = 0; + Ac3Cfg.word = 0; + if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE)) + { + DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n")); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED); + for (i=0; iMacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli) + CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE); + } + + //======================================================== + // MAC Register has a copy . + //======================================================== +//#ifndef WIFI_TEST + if( pAd->CommonCfg.bEnableTxBurst ) + { + // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode + Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode + } + else + Ac0Cfg.field.AcTxop = 0; // QID_AC_BE +//#else +// Ac0Cfg.field.AcTxop = 0; // QID_AC_BE +//#endif + Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS; + Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS; + Ac0Cfg.field.Aifsn = 2; + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word); + + Ac1Cfg.field.AcTxop = 0; // QID_AC_BK + Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS; + Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS; + Ac1Cfg.field.Aifsn = 2; + RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word); + + if (pAd->CommonCfg.PhyMode == PHY_11B) + { + Ac2Cfg.field.AcTxop = 192; // AC_VI: 192*32us ~= 6ms + Ac3Cfg.field.AcTxop = 96; // AC_VO: 96*32us ~= 3ms + } + else + { + Ac2Cfg.field.AcTxop = 96; // AC_VI: 96*32us ~= 3ms + Ac3Cfg.field.AcTxop = 48; // AC_VO: 48*32us ~= 1.5ms + } + Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS; + Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS; + Ac2Cfg.field.Aifsn = 2; + RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word); + Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS; + Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS; + Ac3Cfg.field.Aifsn = 2; + RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word); + + //======================================================== + // DMA Register has a copy too. + //======================================================== + csr0.field.Ac0Txop = 0; // QID_AC_BE + csr0.field.Ac1Txop = 0; // QID_AC_BK + RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word); + if (pAd->CommonCfg.PhyMode == PHY_11B) + { + csr1.field.Ac2Txop = 192; // AC_VI: 192*32us ~= 6ms + csr1.field.Ac3Txop = 96; // AC_VO: 96*32us ~= 3ms + } + else + { + csr1.field.Ac2Txop = 96; // AC_VI: 96*32us ~= 3ms + csr1.field.Ac3Txop = 48; // AC_VO: 48*32us ~= 1.5ms + } + RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word); + + CwminCsr.word = 0; + CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS; + CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS; + CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS; + CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS; + RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word); + + CwmaxCsr.word = 0; + CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS; + CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS; + CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS; + CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS; + RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word); + + RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222); + + NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM)); + } + else + { + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED); + //======================================================== + // MAC Register has a copy. + //======================================================== + // + // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27 + // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue. + // + //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this + + Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE]; + Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE]; + Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE]; + Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1; + + Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK]; + Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2; + Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK]; + Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1; + + Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10; + if(pAd->Antenna.field.TxPath == 1) + { + Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1; + Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1; + } + else + { + Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI]; + Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI]; + } + Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1; +#ifdef RTMP_MAC_USB + Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 3; +#endif // RTMP_MAC_USB // + + { + // Tuning for Wi-Fi WMM S06 + if (pAd->CommonCfg.bWiFiTest && + pEdcaParm->Aifsn[QID_AC_VI] == 10) + Ac2Cfg.field.Aifsn -= 1; + + // Tuning for TGn Wi-Fi 5.2.32 + // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta + if (STA_TGN_WIFI_ON(pAd) && + pEdcaParm->Aifsn[QID_AC_VI] == 10) + { + Ac0Cfg.field.Aifsn = 3; + Ac2Cfg.field.AcTxop = 5; + } +#ifdef RT30xx + if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020) + { + // Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta. + Ac2Cfg.field.Aifsn = 5; + } +#endif // RT30xx // + } + + Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO]; + Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO]; + Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO]; + Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO]; + +//#ifdef WIFI_TEST + if (pAd->CommonCfg.bWiFiTest) + { + if (Ac3Cfg.field.AcTxop == 102) + { + Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10; + Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */ + Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK]; + Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; + Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI]; + } /* End of if */ + } +//#endif // WIFI_TEST // + + RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word); + RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word); + RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word); + RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word); + + + //======================================================== + // DMA Register has a copy too. + //======================================================== + csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop; + csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop; + RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word); + + csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop; + csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop; + RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word); + + CwminCsr.word = 0; + CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE]; + CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK]; + CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI]; + CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test + RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word); + + CwmaxCsr.word = 0; + CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE]; + CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK]; + CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI]; + CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO]; + RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word); + + AifsnCsr.word = 0; + AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE]; + AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK]; + AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI]; + + { + // Tuning for Wi-Fi WMM S06 + if (pAd->CommonCfg.bWiFiTest && + pEdcaParm->Aifsn[QID_AC_VI] == 10) + AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4; + + // Tuning for TGn Wi-Fi 5.2.32 + // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta + if (STA_TGN_WIFI_ON(pAd) && + pEdcaParm->Aifsn[QID_AC_VI] == 10) + { + AifsnCsr.field.Aifsn0 = 3; + AifsnCsr.field.Aifsn2 = 7; + } + + if (INFRA_ON(pAd)) + CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE); + } + + { + AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test +#ifdef RT30xx + // TODO: Shiang, this modification also suitable for RT3052/RT3050 ??? + if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020) + { + AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04. + } +#endif // RT30xx // + } + RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word); + + NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM)); + if (!ADHOC_ON(pAd)) + { + DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount)); + DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n", + pEdcaParm->Aifsn[0], + pEdcaParm->Cwmin[0], + pEdcaParm->Cwmax[0], + pEdcaParm->Txop[0]<<5, + pEdcaParm->bACM[0])); + DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n", + pEdcaParm->Aifsn[1], + pEdcaParm->Cwmin[1], + pEdcaParm->Cwmax[1], + pEdcaParm->Txop[1]<<5, + pEdcaParm->bACM[1])); + DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n", + pEdcaParm->Aifsn[2], + pEdcaParm->Cwmin[2], + pEdcaParm->Cwmax[2], + pEdcaParm->Txop[2]<<5, + pEdcaParm->bACM[2])); + DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n", + pEdcaParm->Aifsn[3], + pEdcaParm->Cwmin[3], + pEdcaParm->Cwmax[3], + pEdcaParm->Txop[3]<<5, + pEdcaParm->bACM[3])); + } + } + +} + +/* + ========================================================================== + Description: + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID AsicSetSlotTime( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bUseShortSlotTime) +{ + ULONG SlotTime; + UINT32 RegValue = 0; + + if (pAd->CommonCfg.Channel > 14) + bUseShortSlotTime = TRUE; + + if (bUseShortSlotTime && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)) + return; + else if ((!bUseShortSlotTime) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))) + return; + + if (bUseShortSlotTime) + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); + else + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); + + SlotTime = (bUseShortSlotTime)? 9 : 20; + + { + // force using short SLOT time for FAE to demo performance when TxBurst is ON + if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))) + || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)) + ) + { + // In this case, we will think it is doing Wi-Fi test + // And we will not set to short slot when bEnableTxBurst is TRUE. + } + else if (pAd->CommonCfg.bEnableTxBurst) + { + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); + SlotTime = 9; + } + } + + // + // For some reasons, always set it to short slot time. + // + // ToDo: Should consider capability with 11B + // + { + if (pAd->StaCfg.BssType == BSS_ADHOC) + { + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); + SlotTime = 20; + } + } + + RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue); + RegValue = RegValue & 0xFFFFFF00; + + RegValue |= SlotTime; + + RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue); +} + +/* + ======================================================================== + Description: + Add Shared key information into ASIC. + Update shared key, TxMic and RxMic to Asic Shared key table + Update its cipherAlg to Asic Shared key Mode. + + Return: + ======================================================================== +*/ +VOID AsicAddSharedKeyEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssIndex, + IN UCHAR KeyIdx, + IN UCHAR CipherAlg, + IN PUCHAR pKey, + IN PUCHAR pTxMic, + IN PUCHAR pRxMic) +{ + ULONG offset; //, csr0; + SHAREDKEY_MODE_STRUC csr1; +#ifdef RTMP_MAC_PCI + INT i; +#endif // RTMP_MAC_PCI // + + DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx)); +//============================================================================================ + + DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx)); + DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + 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])); + if (pRxMic) + { + DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7])); + } + if (pTxMic) + { + DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7])); + } +//============================================================================================ + // + // fill key material - key + TX MIC + RX MIC + // +#ifdef RTMP_MAC_PCI + offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE; + for (i=0; iKey; +// ULONG KeyLen = pCipherKey->KeyLen; + PUCHAR pTxMic = pCipherKey->TxMic; + PUCHAR pRxMic = pCipherKey->RxMic; + PUCHAR pTxtsc = pCipherKey->TxTsc; + UCHAR CipherAlg = pCipherKey->CipherAlg; + SHAREDKEY_MODE_STRUC csr1; +#ifdef RTMP_MAC_PCI + UCHAR i; +#endif // RTMP_MAC_PCI // + +// ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY); + + DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n")); + // + // 1.) decide key table offset + // + if (bUsePairewiseKeyTable) + offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE); + else + offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE; + + // + // 2.) Set Key to Asic + // + //for (i = 0; i < KeyLen; i++) +#ifdef RTMP_MAC_PCI + for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) + { + RTMP_IO_WRITE8(pAd, offset + i, pKey[i]); + } + offset += MAX_LEN_OF_PEER_KEY; + + // + // 3.) Set MIC key if available + // + if (pTxMic) + { + for (i = 0; i < 8; i++) + { + RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]); + } + } + offset += LEN_TKIP_TXMICK; + + if (pRxMic) + { + for (i = 0; i < 8; i++) + { + RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]); + } + } +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB + RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY); + offset += MAX_LEN_OF_PEER_KEY; + + // + // 3.) Set MIC key if available + // + if (pTxMic) + { + RTUSBMultiWrite(pAd, offset, pTxMic, 8); + } + offset += LEN_TKIP_TXMICK; + + if (pRxMic) + { + RTUSBMultiWrite(pAd, offset, pRxMic, 8); + } +#endif // RTMP_MAC_USB // + + // + // 4.) Modify IV/EIV if needs + // This will force Asic to use this key ID by setting IV. + // + if (bTxKey) + { +#ifdef RTMP_MAC_PCI + offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE); + // + // Write IV + // + RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]); + RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f)); + RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]); + + IV4 = (KeyIdx << 6); + if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES)) + IV4 |= 0x20; // turn on extension bit means EIV existence + + RTMP_IO_WRITE8(pAd, offset + 3, IV4); + + // + // Write EIV + // + offset += 4; + for (i = 0; i < 4; i++) + { + RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]); + } +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB + UINT32 tmpVal; + + // + // Write IV + // + IV4 = (KeyIdx << 6); + if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES)) + IV4 |= 0x20; // turn on extension bit means EIV existence + + tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24); + RTMP_IO_WRITE32(pAd, offset, tmpVal); + + // + // Write EIV + // + offset += 4; + RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]); +#endif // RTMP_MAC_USB // + + AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable); + } + + if (!bUsePairewiseKeyTable) + { + // + // Only update the shared key security mode + // + RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word); + if ((BssIndex % 2) == 0) + { + if (KeyIdx == 0) + csr1.field.Bss0Key0CipherAlg = CipherAlg; + else if (KeyIdx == 1) + csr1.field.Bss0Key1CipherAlg = CipherAlg; + else if (KeyIdx == 2) + csr1.field.Bss0Key2CipherAlg = CipherAlg; + else + csr1.field.Bss0Key3CipherAlg = CipherAlg; + } + else + { + if (KeyIdx == 0) + csr1.field.Bss1Key0CipherAlg = CipherAlg; + else if (KeyIdx == 1) + csr1.field.Bss1Key1CipherAlg = CipherAlg; + else if (KeyIdx == 2) + csr1.field.Bss1Key2CipherAlg = CipherAlg; + else + csr1.field.Bss1Key3CipherAlg = CipherAlg; + } + RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word); + } + + DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n")); +} + + +/* + ======================================================================== + Description: + Add Pair-wise key material into ASIC. + Update pairwise key, TxMic and RxMic to Asic Pair-wise key table + + Return: + ======================================================================== +*/ +VOID AsicAddPairwiseKeyEntry( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN UCHAR WCID, + IN CIPHER_KEY *pCipherKey) +{ + INT i; + ULONG offset; + PUCHAR pKey = pCipherKey->Key; + PUCHAR pTxMic = pCipherKey->TxMic; + PUCHAR pRxMic = pCipherKey->RxMic; +#ifdef DBG + UCHAR CipherAlg = pCipherKey->CipherAlg; +#endif // DBG // + + // EKEY + offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE); +#ifdef RTMP_MAC_PCI + for (i=0; iKey[0], MAX_LEN_OF_PEER_KEY); +#endif // RTMP_MAC_USB // + for (i=0; iTxMic[0], 8); +#endif // RTMP_MAC_USB // + } + offset += 8; + if (pRxMic) + { +#ifdef RTMP_MAC_PCI + for (i=0; i<8; i++) + { + RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]); + } +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB + RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8); +#endif // RTMP_MAC_USB // + } + + DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg])); + DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + 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])); + if (pRxMic) + { + DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7])); + } + if (pTxMic) + { + DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", + pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7])); + } +} +/* + ======================================================================== + Description: + Remove Pair-wise key material from ASIC. + + Return: + ======================================================================== +*/ +VOID AsicRemovePairwiseKeyEntry( + IN PRTMP_ADAPTER pAd, + IN UCHAR BssIdx, + IN UCHAR Wcid) +{ + ULONG WCIDAttri; + USHORT offset; + + // re-set the entry's WCID attribute as OPEN-NONE. + offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE); + WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE; + RTMP_IO_WRITE32(pAd, offset, WCIDAttri); +} + +BOOLEAN AsicSendCommandToMcu( + IN PRTMP_ADAPTER pAd, + IN UCHAR Command, + IN UCHAR Token, + IN UCHAR Arg0, + IN UCHAR Arg1) +{ + + if (pAd->chipOps.sendCommandToMcu) + pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1); + + return TRUE; +} + + +VOID AsicSetRxAnt( + IN PRTMP_ADAPTER pAd, + IN UCHAR Ant) +{ +#ifdef RT30xx + /* RT3572 ATE need not to do this. */ + RT30xxSetRxAnt(pAd, Ant); +#endif // RT30xx // +} + + +VOID AsicTurnOffRFClk( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel) +{ + if (pAd->chipOps.AsicRfTurnOff) + { + pAd->chipOps.AsicRfTurnOff(pAd); + } + else + { + // RF R2 bit 18 = 0 + UINT32 R1 = 0, R2 = 0, R3 = 0; + UCHAR index; + RTMP_RF_REGS *RFRegTable; + + RFRegTable = RF2850RegTable; + + switch (pAd->RfIcType) + { + case RFIC_2820: + case RFIC_2850: + case RFIC_2720: + case RFIC_2750: + + for (index = 0; index < NUM_OF_2850_CHNL; index++) + { + if (Channel == RFRegTable[index].Channel) + { + R1 = RFRegTable[index].R1 & 0xffffdfff; + R2 = RFRegTable[index].R2 & 0xfffbffff; + R3 = RFRegTable[index].R3 & 0xfff3ffff; + + RTMP_RF_IO_WRITE32(pAd, R1); + RTMP_RF_IO_WRITE32(pAd, R2); + + // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0. + // Set RF R2 bit18=0, R3 bit[18:19]=0 + //if (pAd->StaCfg.bRadio == FALSE) + if (1) + { + RTMP_RF_IO_WRITE32(pAd, R3); + + DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n", + Channel, pAd->RfIcType, R2, R3)); + } + else + DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n", + Channel, pAd->RfIcType, R2)); + break; + } + } + break; + + default: + break; + } + } +} + + +VOID AsicTurnOnRFClk( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel) +{ + // RF R2 bit 18 = 0 + UINT32 R1 = 0, R2 = 0, R3 = 0; + UCHAR index; + RTMP_RF_REGS *RFRegTable; + + + RFRegTable = RF2850RegTable; + + switch (pAd->RfIcType) + { + case RFIC_2820: + case RFIC_2850: + case RFIC_2720: + case RFIC_2750: + + for (index = 0; index < NUM_OF_2850_CHNL; index++) + { + if (Channel == RFRegTable[index].Channel) + { + R3 = pAd->LatchRfRegs.R3; + R3 &= 0xfff3ffff; + R3 |= 0x00080000; + RTMP_RF_IO_WRITE32(pAd, R3); + + R1 = RFRegTable[index].R1; + RTMP_RF_IO_WRITE32(pAd, R1); + + R2 = RFRegTable[index].R2; + if (pAd->Antenna.field.TxPath == 1) + { + R2 |= 0x4000; // If TXpath is 1, bit 14 = 1; + } + + if (pAd->Antenna.field.RxPath == 2) + { + R2 |= 0x40; // write 1 to off Rxpath. + } + else if (pAd->Antenna.field.RxPath == 1) + { + R2 |= 0x20040; // write 1 to off RxPath + } + RTMP_RF_IO_WRITE32(pAd, R2); + + break; + } + } + break; + + default: + break; + } + + DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n", + Channel, + pAd->RfIcType, + R2)); +} Index: b/drivers/staging/rt2860/common/cmm_cfg.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/cmm_cfg.c @@ -0,0 +1,290 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + cmm_cfg.c + + Abstract: + Ralink WiFi Driver configuration related subroutines + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- +*/ + + + +#include "../rt_config.h" + + +char* GetPhyMode( + int Mode) +{ + switch(Mode) + { + case MODE_CCK: + return "CCK"; + + case MODE_OFDM: + return "OFDM"; + case MODE_HTMIX: + return "HTMIX"; + + case MODE_HTGREENFIELD: + return "GREEN"; + default: + return "N/A"; + } +} + + +char* GetBW( + int BW) +{ + switch(BW) + { + case BW_10: + return "10M"; + + case BW_20: + return "20M"; + case BW_40: + return "40M"; + default: + return "N/A"; + } +} + + +/* + ========================================================================== + Description: + Set Country Region to pAd->CommonCfg.CountryRegion. + This command will not work, if the field of CountryRegion in eeprom is programmed. + + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT RT_CfgSetCountryRegion( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg, + IN INT band) +{ + LONG region, regionMax; + UCHAR *pCountryRegion; + + region = simple_strtol(arg, 0, 10); + + if (band == BAND_24G) + { + pCountryRegion = &pAd->CommonCfg.CountryRegion; + regionMax = REGION_MAXIMUM_BG_BAND; + } + else + { + pCountryRegion = &pAd->CommonCfg.CountryRegionForABand; + regionMax = REGION_MAXIMUM_A_BAND; + } + + // TODO: Is it neccesay for following check??? + // Country can be set only when EEPROM not programmed + if (*pCountryRegion & 0x80) + { + DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():CountryRegion in eeprom was programmed\n")); + return FALSE; + } + + if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND)) + { + *pCountryRegion= (UCHAR) region; + } + else if ((region == REGION_31_BG_BAND) && (band == BAND_24G)) + { + *pCountryRegion = (UCHAR) region; + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("CfgSetCountryRegion():region(%ld) out of range!\n", region)); + return FALSE; + } + + return TRUE; + +} + + +/* + ========================================================================== + Description: + Set Wireless Mode + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT RT_CfgSetWirelessMode( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + INT MaxPhyMode = PHY_11G; + LONG WirelessMode; + + MaxPhyMode = PHY_11N_5G; + + WirelessMode = simple_strtol(arg, 0, 10); + if (WirelessMode <= MaxPhyMode) + { + pAd->CommonCfg.PhyMode = WirelessMode; + return TRUE; + } + + return FALSE; + +} + + +INT RT_CfgSetShortSlot( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + LONG ShortSlot; + + ShortSlot = simple_strtol(arg, 0, 10); + + if (ShortSlot == 1) + pAd->CommonCfg.bUseShortSlotTime = TRUE; + else if (ShortSlot == 0) + pAd->CommonCfg.bUseShortSlotTime = FALSE; + else + return FALSE; //Invalid argument + + return TRUE; +} + + +/* + ========================================================================== + Description: + Set WEP KEY base on KeyIdx + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT RT_CfgSetWepKey( + IN PRTMP_ADAPTER pAd, + IN PSTRING keyString, + IN CIPHER_KEY *pSharedKey, + IN INT keyIdx) +{ + INT KeyLen; + INT i; + UCHAR CipherAlg = CIPHER_NONE; + BOOLEAN bKeyIsHex = FALSE; + + // TODO: Shall we do memset for the original key info?? + memset(pSharedKey, 0, sizeof(CIPHER_KEY)); + KeyLen = strlen(keyString); + switch (KeyLen) + { + case 5: //wep 40 Ascii type + case 13: //wep 104 Ascii type + bKeyIsHex = FALSE; + pSharedKey->KeyLen = KeyLen; + NdisMoveMemory(pSharedKey->Key, keyString, KeyLen); + break; + + case 10: //wep 40 Hex type + case 26: //wep 104 Hex type + for(i=0; i < KeyLen; i++) + { + if( !isxdigit(*(keyString+i)) ) + return FALSE; //Not Hex value; + } + bKeyIsHex = TRUE; + pSharedKey->KeyLen = KeyLen/2 ; + AtoH(keyString, pSharedKey->Key, pSharedKey->KeyLen); + break; + + default: //Invalid argument + DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey(keyIdx=%d):Invalid argument (arg=%s)\n", keyIdx, keyString)); + return FALSE; + } + + pSharedKey->CipherAlg = ((KeyLen % 5) ? CIPHER_WEP128 : CIPHER_WEP64); + DBGPRINT(RT_DEBUG_TRACE, ("RT_CfgSetWepKey:(KeyIdx=%d,type=%s, Alg=%s)\n", + keyIdx, (bKeyIsHex == FALSE ? "Ascii" : "Hex"), CipherName[CipherAlg])); + + return TRUE; +} + + +/* + ========================================================================== + Description: + Set WPA PSK key + + Arguments: + pAdapter Pointer to our adapter + keyString WPA pre-shared key string + pHashStr String used for password hash function + hashStrLen Lenght of the hash string + pPMKBuf Output buffer of WPAPSK key + + Return: + TRUE if all parameters are OK, FALSE otherwise + ========================================================================== +*/ +INT RT_CfgSetWPAPSKKey( + IN RTMP_ADAPTER *pAd, + IN PSTRING keyString, + IN UCHAR *pHashStr, + IN INT hashStrLen, + OUT PUCHAR pPMKBuf) +{ + int keyLen; + UCHAR keyMaterial[40]; + + keyLen = strlen(keyString); + if ((keyLen < 8) || (keyLen > 64)) + { + DBGPRINT(RT_DEBUG_TRACE, ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n", + keyLen, keyString)); + return FALSE; + } + + memset(pPMKBuf, 0, 32); + if (keyLen == 64) + { + AtoH(keyString, pPMKBuf, 32); + } + else + { + PasswordHash(keyString, pHashStr, hashStrLen, keyMaterial); + NdisMoveMemory(pPMKBuf, keyMaterial, 32); + } + + return TRUE; +} Index: b/drivers/staging/rt2860/common/cmm_data.c =================================================================== --- a/drivers/staging/rt2860/common/cmm_data.c +++ b/drivers/staging/rt2860/common/cmm_data.c @@ -25,9 +25,8 @@ ************************************************************************* */ -#include "../rt_config.h" -#define MAX_TX_IN_TBTT (16) +#include "../rt_config.h" UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; @@ -67,6 +66,7 @@ UCHAR RxwiMCSToOfdmRate[12] = { char* MCSToMbps[] = {"1Mbps","2Mbps","5.5Mbps","11Mbps","06Mbps","09Mbps","12Mbps","18Mbps","24Mbps","36Mbps","48Mbps","54Mbps","MM-0","MM-1","MM-2","MM-3","MM-4","MM-5","MM-6","MM-7","MM-8","MM-9","MM-10","MM-11","MM-12","MM-13","MM-14","MM-15","MM-32","ee1","ee2","ee3"}; UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2}; +//UCHAR default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1}; UCHAR default_sta_aifsn[]={3,7,2,2}; UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO}; @@ -105,28 +105,38 @@ NDIS_STATUS MiniportMMRequest( PNDIS_PACKET pPacket; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; ULONG FreeNum; -#ifdef RT2860 + UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN]; +#ifdef RTMP_MAC_PCI unsigned long IrqFlags = 0; -#endif UCHAR IrqState; - UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN]; +#endif // RTMP_MAC_PCI // + BOOLEAN bUseDataQ = FALSE; + int retryCnt = 0; ASSERT(Length <= MGMT_DMA_BUFFER_SIZE); - QueIdx=3; + if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG) + { + bUseDataQ = TRUE; + QueIdx &= (~MGMT_USE_QUEUE_FLAG); + } +#ifdef RTMP_MAC_PCI // 2860C use Tx Ring - IrqState = pAd->irq_disabled; - -#ifdef RT2860 - if ((pAd->MACVersion == 0x28600100) && (!IrqState)) + if (pAd->MACVersion == 0x28600100) + { + QueIdx = (bUseDataQ ==TRUE ? QueIdx : 3); + bUseDataQ = TRUE; + } + if (bUseDataQ && (!IrqState)) RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); -#endif +#endif // RTMP_MAC_PCI // + do { // Reset is in progress, stop immediately - if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)|| !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) { @@ -136,13 +146,16 @@ NDIS_STATUS MiniportMMRequest( // Check Free priority queue // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing. - - // 2860C use Tx Ring - if (pAd->MACVersion == 0x28600100) +#ifdef RTMP_MAC_PCI + if (bUseDataQ) { + retryCnt = MAX_DATAMM_RETRY; + // free Tx(QueIdx) resources + RTMPFreeTXDUponTxDmaDone(pAd, QueIdx); FreeNum = GET_TXRING_FREENO(pAd, QueIdx); } else +#endif // RTMP_MAC_PCI // { FreeNum = GET_MGMTRING_FREENO(pAd); } @@ -162,96 +175,51 @@ NDIS_STATUS MiniportMMRequest( //pAd->CommonCfg.MlmeRate = RATE_2; +#ifdef RTMP_MAC_PCI + if (bUseDataQ) + { + Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket); + retryCnt--; + } + else +#endif // RTMP_MAC_PCI // Status = MlmeHardTransmit(pAd, QueIdx, pPacket); - if (Status != NDIS_STATUS_SUCCESS) + if (Status == NDIS_STATUS_SUCCESS) + retryCnt = 0; + else RTMPFreeNdisPacket(pAd, pPacket); } else { pAd->RalinkCounters.MgmtRingFullCount++; +#ifdef RTMP_MAC_PCI + if (bUseDataQ) + { + retryCnt--; + DBGPRINT(RT_DEBUG_TRACE, ("retryCnt %d\n", retryCnt)); + if (retryCnt == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n", + QueIdx, pAd->RalinkCounters.MgmtRingFullCount)); + } + } +#endif // RTMP_MAC_PCI // DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n", QueIdx, pAd->RalinkCounters.MgmtRingFullCount)); } + } while (retryCnt > 0); - } while (FALSE); -#ifdef RT2860 - // 2860C use Tx Ring - if ((pAd->MACVersion == 0x28600100) && (!IrqState)) +#ifdef RTMP_MAC_PCI + if (bUseDataQ && (!IrqState)) RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); -#endif +#endif // RTMP_MAC_PCI // + return Status; } -#ifdef RT2860 -NDIS_STATUS MiniportMMRequestUnlock( - IN PRTMP_ADAPTER pAd, - IN UCHAR QueIdx, - IN PUCHAR pData, - IN UINT Length) -{ - PNDIS_PACKET pPacket; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - ULONG FreeNum; - TXWI_STRUC TXWI; - ULONG SW_TX_IDX; - PTXD_STRUC pTxD; - QueIdx = 3; - ASSERT(Length <= MGMT_DMA_BUFFER_SIZE); - do - { - // Reset is in progress, stop immediately - if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || - RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)|| - !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) - { - Status = NDIS_STATUS_FAILURE; - break; - } - - // Check Free priority queue - // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing. - // 2860C use Tx Ring - if (pAd->MACVersion == 0x28600100) - { - FreeNum = GET_TXRING_FREENO(pAd, QueIdx); - SW_TX_IDX = pAd->TxRing[QueIdx].TxCpuIdx; - pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SW_TX_IDX].AllocVa; - } - else - { - FreeNum = GET_MGMTRING_FREENO(pAd); - SW_TX_IDX = pAd->MgmtRing.TxCpuIdx; - pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SW_TX_IDX].AllocVa; - } - if ((FreeNum > 0)) - { - NdisZeroMemory(&TXWI, TXWI_SIZE); - Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&TXWI, TXWI_SIZE, pData, Length); - if (Status != NDIS_STATUS_SUCCESS) - { - DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n")); - break; - } - - Status = MlmeHardTransmit(pAd, QueIdx, pPacket); - if (Status != NDIS_STATUS_SUCCESS) - RTMPFreeNdisPacket(pAd, pPacket); - } - else - { - pAd->RalinkCounters.MgmtRingFullCount++; - DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing\n", QueIdx)); - } - - } while (FALSE); - - - return Status; -} -#endif /* ======================================================================== @@ -282,203 +250,33 @@ NDIS_STATUS MlmeHardTransmit( IN UCHAR QueIdx, IN PNDIS_PACKET pPacket) { - if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) - { - return NDIS_STATUS_FAILURE; - } - -#ifdef RT2860 - if ( pAd->MACVersion == 0x28600100 ) - return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket); - else -#endif - return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket); - -} - -#ifdef RT2860 -NDIS_STATUS MlmeHardTransmitTxRing( - IN PRTMP_ADAPTER pAd, - IN UCHAR QueIdx, - IN PNDIS_PACKET pPacket) -{ PACKET_INFO PacketInfo; PUCHAR pSrcBufVA; UINT SrcBufLen; - PTXD_STRUC pTxD; PHEADER_802_11 pHeader_802_11; - BOOLEAN bAckRequired, bInsertTimestamp; - ULONG SrcBufPA; - UCHAR MlmeRate; - ULONG SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; - PTXWI_STRUC pFirstTxWI; - ULONG FreeNum; - MAC_TABLE_ENTRY *pMacEntry = NULL; - - RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); - - if (pSrcBufVA == NULL) + if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) + ) { - // The buffer shouldn't be NULL return NDIS_STATUS_FAILURE; } - // Make sure MGMT ring resource won't be used by other threads - //NdisAcquireSpinLock(&pAd->TxRingLock); - - FreeNum = GET_TXRING_FREENO(pAd, QueIdx); - - if (FreeNum == 0) - { - //NdisReleaseSpinLock(&pAd->TxRingLock); + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); + if (pSrcBufVA == NULL) return NDIS_STATUS_FAILURE; - } - - SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; - pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa; + pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); - if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket) - { - printk("MlmeHardTransmit Error\n"); - return NDIS_STATUS_FAILURE; - } - - // outgoing frame always wakeup PHY to prevent frame lost - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - AsicForceWakeup(pAd, FROM_TX); - pFirstTxWI =(PTXWI_STRUC)pSrcBufVA; - - pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE); - if (pHeader_802_11->Addr1[0] & 0x01) - { - MlmeRate = pAd->CommonCfg.BasicMlmeRate; - } - else - { - MlmeRate = pAd->CommonCfg.MlmeRate; - } - - if ((pHeader_802_11->FC.Type == BTYPE_DATA) && - (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) - { - pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1); - } - - // Verify Mlme rate for a / g bands. - if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band - MlmeRate = RATE_6; - - // - // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) - // Snice it's been set to 0 while on MgtMacHeaderInit - // By the way this will cause frame to be send on PWR_SAVE failed. - // - // - // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame - - // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD - if (pHeader_802_11->FC.Type != BTYPE_DATA) - { - if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) - { - pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; - } - else - { - pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave; - } - } - - bInsertTimestamp = FALSE; - if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL - { - bAckRequired = FALSE; - } - else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame) - { - if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST - { - bAckRequired = FALSE; - pHeader_802_11->Duration = 0; - } - else - { - bAckRequired = TRUE; - pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14); - if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) - { - bInsertTimestamp = TRUE; - } - } - } - pHeader_802_11->Sequence = pAd->Sequence++; - if (pAd->Sequence > 0xfff) - pAd->Sequence = 0; - // Before radar detection done, mgmt frame can not be sent but probe req - // Because we need to use probe req to trigger driver to send probe req in passive scan - if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ) - && (pAd->CommonCfg.bIEEE80211H == 1) - && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) - { - DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n")); - return (NDIS_STATUS_FAILURE); - } - - // - // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET - // should always has only one ohysical buffer, and the whole frame size equals - // to the first scatter buffer size - // - - // Initialize TX Descriptor - // For inter-frame gap, the number is for this frame and next frame - // For MLME rate, we will fix as 2Mb to match other vendor's implement - -// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. - // Only beacon use Nseq=TRUE. So here we use Nseq=FALSE. - if (pMacEntry == NULL) - { - RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, - 0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); - } +#ifdef RTMP_MAC_PCI + if ( pAd->MACVersion == 0x28600100 ) + return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket); else - { - RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, - bInsertTimestamp, FALSE, bAckRequired, FALSE, - 0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE), - pMacEntry->MaxHTPhyMode.field.MCS, 0, - (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS, - IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode); - } - - pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket; - pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL; - - SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE); - - - RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA); - pTxD->LastSec0 = 1; - pTxD->LastSec1 = 1; - pTxD->SDLen0 = SrcBufLen; - pTxD->SDLen1 = 0; - pTxD->SDPtr0 = SrcBufPA; - pTxD->DMADONE = 0; - - pAd->RalinkCounters.KickTxCount++; - pAd->RalinkCounters.OneSecTxDoneCount++; - - // Increase TX_CTX_IDX, but write to register later. - INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE); - - RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10, pAd->TxRing[QueIdx].TxCpuIdx); +#endif // RTMP_MAC_PCI // + return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket); - return NDIS_STATUS_SUCCESS; } -#endif /* RT2860 */ + NDIS_STATUS MlmeHardTransmitMgmtRing( IN PRTMP_ADAPTER pAd, @@ -493,25 +291,24 @@ NDIS_STATUS MlmeHardTransmitMgmtRing( UCHAR MlmeRate; PTXWI_STRUC pFirstTxWI; MAC_TABLE_ENTRY *pMacEntry = NULL; + UCHAR PID; RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); - RTMP_SEM_LOCK(&pAd->MgmtRingLock); - + // Make sure MGMT ring resource won't be used by other threads + RTMP_SEM_LOCK(&pAd->MgmtRingLock); if (pSrcBufVA == NULL) { + // The buffer shouldn't be NULL RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); return NDIS_STATUS_FAILURE; } + { // outgoing frame always wakeup PHY to prevent frame lost if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) -#ifdef RT2860 - AsicForceWakeup(pAd, FROM_TX); -#endif -#ifdef RT2870 AsicForceWakeup(pAd, TRUE); -#endif + } pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE); pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE); @@ -553,20 +350,29 @@ NDIS_STATUS MlmeHardTransmitMgmtRing( // Snice it's been set to 0 while on MgtMacHeaderInit // By the way this will cause frame to be send on PWR_SAVE failed. // - // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE); + pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; // (pAd->StaCfg.Psm == PWR_SAVE); + // // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame - // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD - if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL)) +// if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL)) { - if ((pAd->StaCfg.Psm == PWR_SAVE) && - (pHeader_802_11->FC.SubType == SUBTYPE_ACTION)) + if ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) || + ((pHeader_802_11->FC.Type == BTYPE_DATA) && + ((pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL) || + (pHeader_802_11->FC.SubType == SUBTYPE_NULL_FUNC)))) + { + if (pAd->StaCfg.Psm == PWR_SAVE) pHeader_802_11->FC.PwrMgmt = PWR_SAVE; else - pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; + pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave; + } } + + + + bInsertTimestamp = FALSE; if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL { @@ -579,6 +385,9 @@ NDIS_STATUS MlmeHardTransmitMgmtRing( } else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame) { + //pAd->Sequence++; + //pHeader_802_11->Sequence = pAd->Sequence; + if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST { bAckRequired = FALSE; @@ -588,9 +397,14 @@ NDIS_STATUS MlmeHardTransmitMgmtRing( { bAckRequired = TRUE; pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14); - if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) + if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) && (pHeader_802_11->FC.Type == BTYPE_MGMT)) { bInsertTimestamp = TRUE; + bAckRequired = FALSE; // Disable ACK to prevent retry 0x1f for Probe Response + } + else if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) && (pHeader_802_11->FC.Type == BTYPE_MGMT)) + { + bAckRequired = FALSE; // Disable ACK to prevent retry 0x1f for Probe Request } } } @@ -606,28 +420,35 @@ NDIS_STATUS MlmeHardTransmitMgmtRing( && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) { DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n")); +// if (!IrqState) RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); return (NDIS_STATUS_FAILURE); } + // // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET - // should always has only one ohysical buffer, and the whole frame size equals + // should always has only one physical buffer, and the whole frame size equals // to the first scatter buffer size // // Initialize TX Descriptor // For inter-frame gap, the number is for this frame and next frame // For MLME rate, we will fix as 2Mb to match other vendor's implement +// pAd->CommonCfg.MlmeTransmit.field.MODE = 1; // management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. + PID = PID_MGMT; + + if (pMacEntry == NULL) { RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, - 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); + 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); } else { + /* dont use low rate to send QoS Null data frame */ RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), @@ -640,6 +461,7 @@ NDIS_STATUS MlmeHardTransmitMgmtRing( HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen); // Make sure to release MGMT ring resource +// if (!IrqState) RTMP_SEM_UNLOCK(&pAd->MgmtRingLock); return NDIS_STATUS_SUCCESS; } @@ -832,16 +654,25 @@ BOOLEAN RTMP_FillTxBlkInfo( else TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired); + if ((pAd->OpMode == OPMODE_STA) && + (ADHOC_ON(pAd)) && + (RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS))) { + if(pAd->CommonCfg.PSPXlink) + TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); + } + + { + { + // If support WMM, enable it. -#ifdef RT2860 - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) -#endif -#ifdef RT2870 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)) -#endif TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM); + +// if (pAd->StaCfg.bAutoTxRateSwitch) +// TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch); + } } if (pTxBlk->TxFrameType == TX_LEGACY_FRAME) @@ -896,7 +727,7 @@ BOOLEAN CanDoAggregateTransmit( IN TX_BLK *pTxBlk) { - //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType); + //DBGPRINT(RT_DEBUG_TRACE, ("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType)); if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID) return FALSE; @@ -922,6 +753,7 @@ BOOLEAN CanDoAggregateTransmit( return TRUE; else return FALSE; + } @@ -970,7 +802,6 @@ VOID RTMPDeQueuePacket( if (QIdx == NUM_OF_TX_RING) { sQIdx = 0; -//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) eQIdx = 3; // 4 ACs, start from 0. } else @@ -982,7 +813,7 @@ VOID RTMPDeQueuePacket( { Count=0; - RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags); + RTMP_START_DEQUEUE(pAd, QueIdx, IrqFlags); while (1) @@ -993,7 +824,7 @@ VOID RTMPDeQueuePacket( fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))) { - RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); + RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); return; } @@ -1006,7 +837,8 @@ VOID RTMPDeQueuePacket( DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); break; } -#ifdef RT2860 + +#ifdef RTMP_MAC_PCI FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx); @@ -1016,7 +848,8 @@ VOID RTMPDeQueuePacket( RTMPFreeTXDUponTxDmaDone(pAd, QueIdx); FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx); } -#endif /* RT2860 */ +#endif // RTMP_MAC_PCI // + // probe the Queue Head pQueue = &pAd->TxSwQueue[QueIdx]; if ((pEntry = pQueue->Head) == NULL) @@ -1027,12 +860,14 @@ VOID RTMPDeQueuePacket( pTxBlk = &TxBlk; NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK)); + //InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it. pTxBlk->QueIdx = QueIdx; - pPacket = QUEUE_ENTRY_TO_PKT(pEntry); + pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); + // Early check to make sure we have enoguh Tx Resource. - hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket); + hasTxDesc = RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket); if (!hasTxDesc) { pAd->PrivateInfo.TxRingFullCnt++; @@ -1065,16 +900,16 @@ VOID RTMPDeQueuePacket( break; // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation. - pPacket = QUEUE_ENTRY_TO_PKT(pEntry); + pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx); - hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket); + hasTxDesc = RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket); if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE)) break; //Remove the packet from the TxSwQueue and insert into pTxBlk pEntry = RemoveHeadQueue(pQueue); ASSERT(pEntry); - pPacket = QUEUE_ENTRY_TO_PKT(pEntry); + pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); pTxBlk->TotalFrameNum++; pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket); @@ -1085,29 +920,29 @@ VOID RTMPDeQueuePacket( pTxBlk->TxFrameType = TX_LEGACY_FRAME; } -#ifdef RT2870 +#ifdef RTMP_MAC_USB DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); -#endif // RT2870 // - +#endif // RTMP_MAC_USB // Count += pTxBlk->TxPacketList.Number; // Do HardTransmit now. Status = STAHardTransmit(pAd, pTxBlk, QueIdx); -#ifdef RT2860 +#ifdef RTMP_MAC_PCI DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags); // static rate also need NICUpdateFifoStaCounters() function. //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) NICUpdateFifoStaCounters(pAd); -#endif +#endif // RTMP_MAC_PCI // + } - RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); + RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags); -#ifdef RT2870 +#ifdef RTMP_MAC_USB if (!hasTxDesc) RTUSBKickBulkOut(pAd); -#endif // RT2870 // +#endif // RTMP_MAC_USB // } } @@ -1243,9 +1078,16 @@ VOID RTMPWriteTxWI( pTxWI->NSEQ = NSeq; // John tune the performace with Intel Client in 20 MHz performance BASize = pAd->CommonCfg.TxBASize; - + if (pAd->MACVersion == 0x28720200) + { + if( BASize >13 ) + BASize =13; + } + else + { if( BASize >7 ) BASize =7; + } pTxWI->BAWinSize = BASize; pTxWI->ShortGI = pTransmit->field.ShortGI; pTxWI->STBC = pTransmit->field.STBC; @@ -1387,7 +1229,7 @@ VOID RTMPWriteTxWI_Cache( IN OUT PTXWI_STRUC pTxWI, IN TX_BLK *pTxBlk) { - PHTTRANSMIT_SETTING pTransmit; + PHTTRANSMIT_SETTING /*pTxHTPhyMode,*/ pTransmit; PMAC_TABLE_ENTRY pMacEntry; // @@ -1396,6 +1238,9 @@ VOID RTMPWriteTxWI_Cache( pMacEntry = pTxBlk->pMacEntry; pTransmit = pTxBlk->pTransmit; + //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) + //if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry)) + //if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch)) if (pMacEntry->bAutoTxRateSwitch) { pTxWI->txop = IFS_HTTXOP; @@ -1440,53 +1285,6 @@ VOID RTMPWriteTxWI_Cache( } -/* - ======================================================================== - - Routine Description: - Calculates the duration which is required to transmit out frames - with given size and specified rate. - - Arguments: - pTxD Pointer to transmit descriptor - Ack Setting for Ack requirement bit - Fragment Setting for Fragment bit - RetryMode Setting for retry mode - Ifs Setting for IFS gap - Rate Setting for transmit rate - Service Setting for service - Length Frame length - TxPreamble Short or Long preamble when using CCK rates - QueIdx - 0-3, according to 802.11e/d4.4 June/2003 - - Return Value: - None - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -VOID RTMPWriteTxDescriptor( - IN PRTMP_ADAPTER pAd, - IN PTXD_STRUC pTxD, - IN BOOLEAN bWIV, - IN UCHAR QueueSEL) -{ - // - // Always use Long preamble before verifiation short preamble functionality works well. - // Todo: remove the following line if short preamble functionality works - // - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); - - pTxD->WIV = (bWIV) ? 1: 0; - pTxD->QSEL= (QueueSEL); - if (pAd->bGenOneHCCA == TRUE) - pTxD->QSEL= FIFO_HCCA; - pTxD->DMADONE = 0; -} - - // should be called only when - // 1. MEADIA_CONNECTED // 2. AGGREGATION_IN_USED @@ -1582,12 +1380,14 @@ PQUEUE_HEADER RTMPCheckTxSwQueue( { ULONG Number; + // 2004-11-15 to be removed. test aggregation only +// if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2)) +// return NULL; Number = pAd->TxSwQueue[QID_AC_BK].Number + pAd->TxSwQueue[QID_AC_BE].Number + pAd->TxSwQueue[QID_AC_VI].Number - + pAd->TxSwQueue[QID_AC_VO].Number - + pAd->TxSwQueue[QID_HCCA].Number; + + pAd->TxSwQueue[QID_AC_VO].Number; if (pAd->TxSwQueue[QID_AC_VO].Head != NULL) { @@ -1609,11 +1409,6 @@ PQUEUE_HEADER RTMPCheckTxSwQueue( *pQueIdx = QID_AC_BK; return (&pAd->TxSwQueue[QID_AC_BK]); } - else if (pAd->TxSwQueue[QID_HCCA].Head != NULL) - { - *pQueIdx = QID_HCCA; - return (&pAd->TxSwQueue[QID_HCCA]); - } // No packet pending in Tx Sw queue *pQueIdx = QID_AC_BK; @@ -1621,277 +1416,6 @@ PQUEUE_HEADER RTMPCheckTxSwQueue( return (NULL); } -#ifdef RT2860 -BOOLEAN RTMPFreeTXDUponTxDmaDone( - IN PRTMP_ADAPTER pAd, - IN UCHAR QueIdx) -{ - PRTMP_TX_RING pTxRing; - PTXD_STRUC pTxD; - PNDIS_PACKET pPacket; - UCHAR FREE = 0; - TXD_STRUC TxD, *pOriTxD; - //ULONG IrqFlags; - BOOLEAN bReschedule = FALSE; - - - ASSERT(QueIdx < NUM_OF_TX_RING); - pTxRing = &pAd->TxRing[QueIdx]; - - RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx); - while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx) - { - // static rate also need NICUpdateFifoStaCounters() function. - //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) - NICUpdateFifoStaCounters(pAd); - - /* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */ - FREE++; - pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa); - pOriTxD = pTxD; - NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC)); - pTxD = &TxD; - - pTxD->DMADONE = 0; - -/*====================================================================*/ - { - pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket; - if (pPacket) - { -#ifdef CONFIG_5VT_ENHANCE - if (RTMP_GET_PACKET_5VT(pPacket)) - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE); - else -#endif // CONFIG_5VT_ENHANCE // - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); - } - //Always assign pNdisPacket as NULL after clear - pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL; - - pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket; - - ASSERT(pPacket == NULL); - if (pPacket) - { -#ifdef CONFIG_5VT_ENHANCE - if (RTMP_GET_PACKET_5VT(pPacket)) - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE); - else -#endif // CONFIG_5VT_ENHANCE // - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); - } - //Always assign pNextNdisPacket as NULL after clear - pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL; - } -/*====================================================================*/ - - pAd->RalinkCounters.TransmittedByteCount += (pTxD->SDLen1 + pTxD->SDLen0); - pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++; - INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE); - /* get tx_tdx_idx again */ - RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF , &pTxRing->TxDmaIdx); - - NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC)); - } - - - return bReschedule; - -} - - -/* - ======================================================================== - - Routine Description: - Process TX Rings DMA Done interrupt, running in DPC level - - Arguments: - Adapter Pointer to our adapter - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -BOOLEAN RTMPHandleTxRingDmaDoneInterrupt( - IN PRTMP_ADAPTER pAd, - IN INT_SOURCE_CSR_STRUC TxRingBitmap) -{ - unsigned long IrqFlags; - BOOLEAN bReschedule = FALSE; - - // Make sure Tx ring resource won't be used by other threads - - RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); - - if (TxRingBitmap.field.Ac0DmaDone) - bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE); - - if (TxRingBitmap.field.HccaDmaDone) - bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA); - - if (TxRingBitmap.field.Ac3DmaDone) - bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO); - - if (TxRingBitmap.field.Ac2DmaDone) - bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI); - - if (TxRingBitmap.field.Ac1DmaDone) - bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK); - - // Make sure to release Tx ring resource - RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); - - // Dequeue outgoing frames from TxSwQueue[] and process it - RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); - - return bReschedule; -} - - -/* - ======================================================================== - - Routine Description: - Process MGMT ring DMA done interrupt, running in DPC level - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -VOID RTMPHandleMgmtRingDmaDoneInterrupt( - IN PRTMP_ADAPTER pAd) -{ - PTXD_STRUC pTxD; - PNDIS_PACKET pPacket; - UCHAR FREE = 0; - PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing; - - NdisAcquireSpinLock(&pAd->MgmtRingLock); - - RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx); - while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx) - { - FREE++; - pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa); - pTxD->DMADONE = 0; - pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket; - - - if (pPacket) - { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); - } - pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL; - - pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket; - if (pPacket) - { - PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); - RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); - } - pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL; - INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE); - } - NdisReleaseSpinLock(&pAd->MgmtRingLock); - -} - - -/* - ======================================================================== - - Routine Description: - Arguments: - Adapter Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon. - - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -VOID RTMPHandleTBTTInterrupt( - IN PRTMP_ADAPTER pAd) -{ - { - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - { - } - } -} - - -/* - ======================================================================== - - Routine Description: - Arguments: - Adapter Pointer to our adapter. Rewrite beacon content before next send-out. - - IRQL = DISPATCH_LEVEL - - ======================================================================== -*/ -VOID RTMPHandlePreTBTTInterrupt( - IN PRTMP_ADAPTER pAd) -{ - { - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - { - DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n")); - } - } - - -} - -VOID RTMPHandleRxCoherentInterrupt( - IN PRTMP_ADAPTER pAd) -{ - WPDMA_GLO_CFG_STRUC GloCfg; - - if (pAd == NULL) - { - DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n")); - return; - } - - DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n")); - - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word); - - GloCfg.field.EnTXWriteBackDDONE = 0; - GloCfg.field.EnableRxDMA = 0; - GloCfg.field.EnableTxDMA = 0; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); - - RTMPRingCleanUp(pAd, QID_AC_BE); - RTMPRingCleanUp(pAd, QID_AC_BK); - RTMPRingCleanUp(pAd, QID_AC_VI); - RTMPRingCleanUp(pAd, QID_AC_VO); - RTMPRingCleanUp(pAd, QID_HCCA); - RTMPRingCleanUp(pAd, QID_MGMT); - RTMPRingCleanUp(pAd, QID_RX); - - RTMPEnableRxTx(pAd); - - DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n")); -} -#endif /* RT2860 */ /* ======================================================================== @@ -1922,9 +1446,11 @@ VOID RTMPSuspendMsduTransmission( RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue); // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning) + //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd))); RTMPSetAGCInitValue(pAd, BW_20); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); + //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings } @@ -1949,8 +1475,11 @@ VOID RTMPSuspendMsduTransmission( VOID RTMPResumeMsduTransmission( IN PRTMP_ADAPTER pAd) { +// UCHAR IrqState; + DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n")); + // After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value // R66 should not be 0 if (pAd->BbpTuning.R66CurrentValue == 0) @@ -1962,6 +1491,11 @@ VOID RTMPResumeMsduTransmission( RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); +// sample, for IRQ LOCK to SEM LOCK +// IrqState = pAd->irq_disabled; +// if (IrqState) +// RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS); +// else RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); } @@ -1990,7 +1524,9 @@ UINT deaggregate_AMSDU_announce( nMSDU++; + //hex_dump("subheader", pData, 64); pAMSDUsubheader = (PHEADER_802_3)pData; + //pData += LENGTH_802_3; PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8); SubFrameSize = PayloadSize + LENGTH_802_3; @@ -2000,6 +1536,8 @@ UINT deaggregate_AMSDU_announce( break; } + //DBGPRINT(RT_DEBUG_TRACE,("%d subframe: Size = %d\n", nMSDU, PayloadSize)); + pPayload = pData + LENGTH_802_3; pDA = pData; pSA = pData + MAC_ADDR_LEN; @@ -2009,15 +1547,17 @@ UINT deaggregate_AMSDU_announce( if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) ) { - // avoid local heap overflow, use dyanamic allocation + /* avoid local heap overflow, use dyanamic allocation */ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); - if (Elem == NULL) - return; + if (Elem != NULL) + { memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize); Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize; - WpaEAPOLKeyAction(pAd, Elem); + //WpaEAPOLKeyAction(pAd, Elem); + REPORT_MGMT_FRAME_TO_MLME(pAd, BSSID_WCID, Elem->Msg, Elem->MsgLen, 0, 0, 0, 0); kfree(Elem); } + } { if (pRemovedLLCSNAP) @@ -2121,6 +1661,8 @@ MAC_TABLE_ENTRY *MacTableInsertEntry( UCHAR HashIdx; int i, FirstWcid; MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry; +// USHORT offset; +// ULONG addr; // if FULL, return if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE) @@ -2183,22 +1725,15 @@ MAC_TABLE_ENTRY *MacTableInsertEntry( pEntry->AuthMode = pAd->StaCfg.AuthMode; pEntry->WepStatus = pAd->StaCfg.WepStatus; pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; -#ifdef RT2860 +#ifdef RTMP_MAC_PCI AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i); -#endif +#endif // RTMP_MAC_PCI // } } pEntry->GTKState = REKEY_NEGOTIATING; pEntry->PairwiseKey.KeyLen = 0; pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; - -#ifdef RT2860 - if ((pAd->OpMode == OPMODE_STA) && - (pAd->StaCfg.BssType == BSS_ADHOC)) - pEntry->PortSecured = WPA_802_1X_PORT_SECURED; - else -#endif pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND; @@ -2210,13 +1745,14 @@ MAC_TABLE_ENTRY *MacTableInsertEntry( pEntry->PsMode = PWR_ACTIVE; pEntry->PsQIdleCount = 0; pEntry->NoDataIdleCount = 0; + pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT; pEntry->ContinueTxFailCnt = 0; InitializeQueueHeader(&pEntry->PsQueue); pAd->MacTab.Size ++; // Add this entry into ASIC RX WCID search table - RT28XX_STA_ENTRY_ADD(pAd, pEntry); + RTMP_STA_ENTRY_ADD(pAd, pEntry); @@ -2260,6 +1796,8 @@ BOOLEAN MacTableDeleteEntry( USHORT HashIdx; MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry; BOOLEAN Cancelled; + //USHORT offset; // unused variable + //UCHAR j; // unused variable if (wcid >= MAX_LEN_OF_MAC_TABLE) return FALSE; @@ -2267,6 +1805,7 @@ BOOLEAN MacTableDeleteEntry( NdisAcquireSpinLock(&pAd->MacTabLock); HashIdx = MAC_ADDR_HASH_INDEX(pAddr); + //pEntry = pAd->MacTab.Hash[HashIdx]; pEntry = &pAd->MacTab.Content[wcid]; if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh @@ -2276,7 +1815,7 @@ BOOLEAN MacTableDeleteEntry( { // Delete this entry from ASIC on-chip WCID Table - RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid); + RTMP_STA_ENTRY_MAC_RESET(pAd, wcid); // free resources of BA BASessionTearDownALL(pAd, pEntry->Aid); @@ -2308,7 +1847,7 @@ BOOLEAN MacTableDeleteEntry( // not found !!! ASSERT(pProbeEntry != NULL); - RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid); + RTMP_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid); if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE) @@ -2324,7 +1863,7 @@ BOOLEAN MacTableDeleteEntry( } else { - printk("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid); + DBGPRINT(RT_DEBUG_OFF, ("\n%s: Impossible Wcid = %d !!!!!\n", __func__, wcid)); } } @@ -2334,13 +1873,8 @@ BOOLEAN MacTableDeleteEntry( if (pAd->MacTab.Size == 0) { pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0; -#ifdef RT2860 - AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/); -#else - // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet - // Set MAC register value according operation mode - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0); -#endif + //AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/); + RTMP_UPDATE_PROTECT(pAd); // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet } return TRUE; @@ -2362,24 +1896,25 @@ VOID MacTableReset( DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n")); //NdisAcquireSpinLock(&pAd->MacTabLock); + for (i=1; iMacTab.Content[i].ValidAsCLI == TRUE) { + + // free resources of BA BASessionTearDownALL(pAd, i); pAd->MacTab.Content[i].ValidAsCLI = FALSE; - - -#ifdef RT2870 +#ifdef RTMP_MAC_USB NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6); - RT28XX_STA_ENTRY_MAC_RESET(pAd, i); -#endif // RT2870 // + RTMP_STA_ENTRY_MAC_RESET(pAd, i); +#endif // RTMP_MAC_USB // //AsicDelWcidTab(pAd, i); } @@ -2544,7 +2079,7 @@ BOOLEAN RTMPCheckEtherType( RTMP_SET_PACKET_SPECIFIC(pPacket, 0); // get Ethernet protocol field - TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13]; + TypeLen = (pSrcBuf[12] << 8) | pSrcBuf[13]; pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header. @@ -2558,7 +2093,7 @@ BOOLEAN RTMPCheckEtherType( */ if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03) { - Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1); + Sniff2BytesFromNdisBuffer((PNDIS_BUFFER)pSrcBuf, 6, &Byte0, &Byte1); RTMP_SET_PACKET_LLCSNAP(pPacket, 1); TypeLen = (USHORT)((Byte0 << 8) + Byte1); pSrcBuf += 8; // Skip this LLC/SNAP header @@ -2584,7 +2119,7 @@ BOOLEAN RTMPCheckEtherType( Frame Check Sequence (4-bytes) */ RTMP_SET_PACKET_VLAN(pPacket, 1); - Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1); + Sniff2BytesFromNdisBuffer((PNDIS_BUFFER)pSrcBuf, 2, &Byte0, &Byte1); TypeLen = (USHORT)((Byte0 << 8) + Byte1); pSrcBuf += 4; // Skip the VLAN Header. @@ -2600,8 +2135,8 @@ BOOLEAN RTMPCheckEtherType( ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header pSrcBuf += 20; // Skip the IP header - srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf)); - dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2))); + srcPort = OS_NTOHS(get_unaligned((PUINT16)(pSrcBuf))); + dstPort = OS_NTOHS(get_unaligned((PUINT16)(pSrcBuf+2))); if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44)) { //It's a BOOTP/DHCP packet @@ -2692,7 +2227,7 @@ VOID Indicate_Legacy_Packet( STATS_INC_RX_PACKETS(pAd, FromWhichBSSID); -#ifdef RT2870 +#ifdef RTMP_MAC_USB if (pAd->CommonCfg.bDisableReordering == 0) { PBA_REC_ENTRY pBAEntry; @@ -2701,7 +2236,7 @@ VOID Indicate_Legacy_Packet( UCHAR TID = pRxBlk->pRxWI->TID; USHORT Idx; -#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms +#define REORDERING_PACKET_TIMEOUT ((100 * OS_HZ)/1000) // system ticks -- 100 ms if (Wcid < MAX_LEN_OF_MAC_TABLE) { @@ -2715,14 +2250,15 @@ VOID Indicate_Legacy_Packet( RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT))) ) { - printk("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU); + DBGPRINT(RT_DEBUG_OFF, ("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", + pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU)); hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64); ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32); } } } } -#endif // RT2870 // +#endif // RTMP_MAC_USB // wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID); Index: b/drivers/staging/rt2860/common/cmm_data_2860.c =================================================================== --- a/drivers/staging/rt2860/common/cmm_data_2860.c +++ /dev/null @@ -1,1197 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* -*/ - -/* - All functions in this file must be PCI-depended, or you should out your function - in other files. - -*/ -#include "../rt_config.h" - -extern RTMP_RF_REGS RF2850RegTable[]; -extern UCHAR NUM_OF_2850_CHNL; - -USHORT RtmpPCI_WriteTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN BOOLEAN bIsLast, - OUT USHORT *FreeNumber) -{ - - UCHAR *pDMAHeaderBufVA; - USHORT TxIdx, RetTxIdx; - PTXD_STRUC pTxD; - UINT32 BufBasePaLow; - PRTMP_TX_RING pTxRing; - USHORT hwHeaderLen; - - // - // get Tx Ring Resource - // - pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; - TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx; - pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; - BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); - - // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer - if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) - { - hwHeaderLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD; - } - else - { - hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - } - NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen); - - pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket; - pTxRing->Cell[TxIdx].pNextNdisPacket = NULL; - - // - // build Tx Descriptor - // - - pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa; - NdisZeroMemory(pTxD, TXD_SIZE); - - pTxD->SDPtr0 = BufBasePaLow; - pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding - pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);; - pTxD->SDLen1 = pTxBlk->SrcBufLen; - pTxD->LastSec0 = 0; - pTxD->LastSec1 = (bIsLast) ? 1 : 0; - - RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); - - RetTxIdx = TxIdx; - // - // Update Tx index - // - INC_RING_INDEX(TxIdx, TX_RING_SIZE); - pTxRing->TxCpuIdx = TxIdx; - - *FreeNumber -= 1; - - return RetTxIdx; -} - - -USHORT RtmpPCI_WriteSingleTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN BOOLEAN bIsLast, - OUT USHORT *FreeNumber) -{ - - UCHAR *pDMAHeaderBufVA; - USHORT TxIdx, RetTxIdx; - PTXD_STRUC pTxD; - UINT32 BufBasePaLow; - PRTMP_TX_RING pTxRing; - USHORT hwHeaderLen; - - // - // get Tx Ring Resource - // - pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; - TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx; - pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; - BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); - - // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer - hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen); - - pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket; - pTxRing->Cell[TxIdx].pNextNdisPacket = NULL; - - // - // build Tx Descriptor - // - pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa; - - NdisZeroMemory(pTxD, TXD_SIZE); - - pTxD->SDPtr0 = BufBasePaLow; - pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding - pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);; - pTxD->SDLen1 = pTxBlk->SrcBufLen; - pTxD->LastSec0 = 0; - pTxD->LastSec1 = (bIsLast) ? 1 : 0; - - RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); - - RetTxIdx = TxIdx; - // - // Update Tx index - // - INC_RING_INDEX(TxIdx, TX_RING_SIZE); - pTxRing->TxCpuIdx = TxIdx; - - *FreeNumber -= 1; - - return RetTxIdx; -} - - -USHORT RtmpPCI_WriteMultiTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN UCHAR frameNum, - OUT USHORT *FreeNumber) -{ - BOOLEAN bIsLast; - UCHAR *pDMAHeaderBufVA; - USHORT TxIdx, RetTxIdx; - PTXD_STRUC pTxD; - UINT32 BufBasePaLow; - PRTMP_TX_RING pTxRing; - USHORT hwHdrLen; - UINT32 firstDMALen; - - bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0); - - // - // get Tx Ring Resource - // - pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; - TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx; - pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; - BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); - - if (frameNum == 0) - { - // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer - if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; - hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD; - else if (pTxBlk->TxFrameType == TX_RALINK_FRAME) - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; - hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD; - else - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); - hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen; - } - else - { - firstDMALen = pTxBlk->MpduHeaderLen; - } - - NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen); - - pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket; - pTxRing->Cell[TxIdx].pNextNdisPacket = NULL; - - // - // build Tx Descriptor - // - pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa; - - NdisZeroMemory(pTxD, TXD_SIZE); - - pTxD->SDPtr0 = BufBasePaLow; - pTxD->SDLen0 = firstDMALen; // include padding - pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);; - pTxD->SDLen1 = pTxBlk->SrcBufLen; - pTxD->LastSec0 = 0; - pTxD->LastSec1 = (bIsLast) ? 1 : 0; - - RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); - - RetTxIdx = TxIdx; - // - // Update Tx index - // - INC_RING_INDEX(TxIdx, TX_RING_SIZE); - pTxRing->TxCpuIdx = TxIdx; - - *FreeNumber -= 1; - - return RetTxIdx; - -} - - -VOID RtmpPCI_FinalWriteTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN USHORT totalMPDUSize, - IN USHORT FirstTxIdx) -{ - - PTXWI_STRUC pTxWI; - PRTMP_TX_RING pTxRing; - - // - // get Tx Ring Resource - // - pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; - pTxWI = (PTXWI_STRUC) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa; - pTxWI->MPDUtotalByteCount = totalMPDUSize; -} - - -VOID RtmpPCIDataLastTxIdx( - IN PRTMP_ADAPTER pAd, - IN UCHAR QueIdx, - IN USHORT LastTxIdx) -{ - PTXD_STRUC pTxD; - PRTMP_TX_RING pTxRing; - - // - // get Tx Ring Resource - // - pTxRing = &pAd->TxRing[QueIdx]; - - // - // build Tx Descriptor - // - pTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa; - - pTxD->LastSec1 = 1; -} - - -USHORT RtmpPCI_WriteFragTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN UCHAR fragNum, - OUT USHORT *FreeNumber) -{ - UCHAR *pDMAHeaderBufVA; - USHORT TxIdx, RetTxIdx; - PTXD_STRUC pTxD; - UINT32 BufBasePaLow; - PRTMP_TX_RING pTxRing; - USHORT hwHeaderLen; - UINT32 firstDMALen; - - // - // Get Tx Ring Resource - // - pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; - TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx; - pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; - BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); - - // - // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer - // - hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; - NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen); - - - // - // Build Tx Descriptor - // - pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa; - - NdisZeroMemory(pTxD, TXD_SIZE); - - if (fragNum == pTxBlk->TotalFragNum) - { - pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket; - pTxRing->Cell[TxIdx].pNextNdisPacket = NULL; - } - - pTxD->SDPtr0 = BufBasePaLow; - pTxD->SDLen0 = firstDMALen; // include padding - pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE); - pTxD->SDLen1 = pTxBlk->SrcBufLen; - pTxD->LastSec0 = 0; - pTxD->LastSec1 = 1; - - RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); - - RetTxIdx = TxIdx; - pTxBlk->Priv += pTxBlk->SrcBufLen; - - // - // Update Tx index - // - INC_RING_INDEX(TxIdx, TX_RING_SIZE); - pTxRing->TxCpuIdx = TxIdx; - - *FreeNumber -= 1; - - return RetTxIdx; - -} - -/* - Must be run in Interrupt context - This function handle PCI specific TxDesc and cpu index update and kick the packet out. - */ -int RtmpPCIMgmtKickOut( - IN RTMP_ADAPTER *pAd, - IN UCHAR QueIdx, - IN PNDIS_PACKET pPacket, - IN PUCHAR pSrcBufVA, - IN UINT SrcBufLen) -{ - PTXD_STRUC pTxD; - ULONG SwIdx = pAd->MgmtRing.TxCpuIdx; - - pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa; - - pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket; - pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL; - - RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT); - pTxD->LastSec0 = 1; - pTxD->LastSec1 = 1; - pTxD->DMADONE = 0; - pTxD->SDLen1 = 0; - pTxD->SDPtr0 = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);; - pTxD->SDLen0 = SrcBufLen; - - pAd->RalinkCounters.KickTxCount++; - pAd->RalinkCounters.OneSecTxDoneCount++; - - // Increase TX_CTX_IDX, but write to register later. - INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE); - - RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx); - - return 0; -} - -/* - ======================================================================== - - Routine Description: - Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound - - Arguments: - pRxD Pointer to the Rx descriptor - - Return Value: - NDIS_STATUS_SUCCESS No err - NDIS_STATUS_FAILURE Error - - Note: - - ======================================================================== -*/ -NDIS_STATUS RTMPCheckRxError( - IN PRTMP_ADAPTER pAd, - IN PHEADER_802_11 pHeader, - IN PRXWI_STRUC pRxWI, - IN PRT28XX_RXD_STRUC pRxD) -{ - PCIPHER_KEY pWpaKey; - INT dBm; - - // Phy errors & CRC errors - if (/*(pRxD->PhyErr) ||*/ (pRxD->Crc)) - { - // Check RSSI for Noise Hist statistic collection. - dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta; - if (dBm <= -87) - pAd->StaCfg.RPIDensity[0] += 1; - else if (dBm <= -82) - pAd->StaCfg.RPIDensity[1] += 1; - else if (dBm <= -77) - pAd->StaCfg.RPIDensity[2] += 1; - else if (dBm <= -72) - pAd->StaCfg.RPIDensity[3] += 1; - else if (dBm <= -67) - pAd->StaCfg.RPIDensity[4] += 1; - else if (dBm <= -62) - pAd->StaCfg.RPIDensity[5] += 1; - else if (dBm <= -57) - pAd->StaCfg.RPIDensity[6] += 1; - else if (dBm > -57) - pAd->StaCfg.RPIDensity[7] += 1; - - return(NDIS_STATUS_FAILURE); - } - - // Add Rx size to channel load counter, we should ignore error counts - pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14); - - // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics - if (pHeader != NULL) - { - if (pHeader->FC.ToDs) - { - return(NDIS_STATUS_FAILURE); - } - } - - // Drop not U2M frames, cant's drop here because we will drop beacon in this case - // I am kind of doubting the U2M bit operation - // if (pRxD->U2M == 0) - // return(NDIS_STATUS_FAILURE); - - // drop decyption fail frame - if (pRxD->CipherErr) - { - if (pRxD->CipherErr == 2) - {DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV ok but MICErr "));} - else if (pRxD->CipherErr == 1) - {DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV Err "));} - else if (pRxD->CipherErr == 3) - DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: Key not valid ")); - - if (((pRxD->CipherErr & 1) == 1) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd)) - RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); - - DBGPRINT_RAW(RT_DEBUG_TRACE,(" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n", - pRxD->CipherErr, - pRxD->SDL0, - pRxD->Mcast | pRxD->Bcast, - pRxD->MyBss, - pRxWI->WirelessCliID, - pRxWI->KeyIndex)); - - // - // MIC Error - // - if (pRxD->CipherErr == 2) - { - pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex]; - - if (pAd->StaCfg.WpaSupplicantUP) - WpaSendMicFailureToWpaSupplicant(pAd, - (pWpaKey->Type == PAIRWISEKEY) ? TRUE:FALSE); - else - RTMPReportMicError(pAd, pWpaKey); - - if (((pRxD->CipherErr & 2) == 2) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd)) - RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); - - DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n")); - } - - if (pHeader == NULL) - return(NDIS_STATUS_SUCCESS); - - return(NDIS_STATUS_FAILURE); - } - - return(NDIS_STATUS_SUCCESS); -} - -/* - ========================================================================== - Description: - This routine sends command to firmware and turn our chip to power save mode. - Both RadioOff and .11 power save function needs to call this routine. - Input: - Level = GUIRADIO_OFF : GUI Radio Off mode - Level = DOT11POWERSAVE : 802.11 power save mode - Level = RTMP_HALT : When Disable device. - - ========================================================================== - */ -VOID RT28xxPciAsicRadioOff( - IN PRTMP_ADAPTER pAd, - IN UCHAR Level, - IN USHORT TbttNumToNextWakeUp) -{ - WPDMA_GLO_CFG_STRUC DmaCfg; - UCHAR i, tempBBP_R3 = 0; - BOOLEAN brc = FALSE, Cancelled; - UINT32 TbTTTime = 0; - UINT32 PsPollTime = 0, MACValue; - ULONG BeaconPeriodTime; - UINT32 RxDmaIdx, RxCpuIdx; - 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)); - - // Check Rx DMA busy status, if more than half is occupied, give up this radio off. - RTMP_IO_READ32(pAd, RX_DRX_IDX , &RxDmaIdx); - RTMP_IO_READ32(pAd, RX_CRX_IDX , &RxCpuIdx); - if ((RxDmaIdx > RxCpuIdx) && ((RxDmaIdx - RxCpuIdx) > RX_RING_SIZE/3)) - { - DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return1. RxDmaIdx = %d , RxCpuIdx = %d. \n", RxDmaIdx, RxCpuIdx)); - return; - } - else if ((RxCpuIdx >= RxDmaIdx) && ((RxCpuIdx - RxDmaIdx) < RX_RING_SIZE/3)) - { - DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return2. RxCpuIdx = %d. RxDmaIdx = %d , \n", RxCpuIdx, RxDmaIdx)); - return; - } - - // Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops. - RTMP_SET_PSFLAG(pAd, fRTMP_PS_DISABLE_TX); - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) - { - RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - - if (Level == DOT11POWERSAVE) - { - RTMP_IO_READ32(pAd, TBTT_TIMER, &TbTTTime); - TbTTTime &= 0x1ffff; - // 00. check if need to do sleep in this DTIM period. If next beacon will arrive within 30ms , ...doesn't necessarily sleep. - // TbTTTime uint = 64us, LEAD_TIME unit = 1024us, PsPollTime unit = 1ms - if (((64*TbTTTime) <((LEAD_TIME*1024) + 40000)) && (TbttNumToNextWakeUp == 0)) - { - DBGPRINT(RT_DEBUG_TRACE, ("TbTTTime = 0x%x , give up this sleep. \n", TbTTTime)); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX); - return; - } - else - { - PsPollTime = (64*TbTTTime- LEAD_TIME*1024)/1000; - PsPollTime -= 3; - - BeaconPeriodTime = pAd->CommonCfg.BeaconPeriod*102/100; - if (TbttNumToNextWakeUp > 0) - PsPollTime += ((TbttNumToNextWakeUp -1) * BeaconPeriodTime); - - pAd->Mlme.bPsPollTimerRunning = TRUE; - RTMPSetTimer(&pAd->Mlme.PsPollTimer, PsPollTime); - } - } - } - - // 0. Disable Tx DMA. - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word); - DmaCfg.field.EnableTxDMA = 0; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word); - - // 1. Wait DMA not busy - i = 0; - do - { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word); - if ((DmaCfg.field.TxDMABusy == 0) && (DmaCfg.field.RxDMABusy == 0)) - break; - RTMPusecDelay(20); - i++; - }while(i < 50); - - if (i >= 50) - { - DBGPRINT(RT_DEBUG_TRACE, ("DMA keeps busy. return on RT28xxPciAsicRadioOff ()\n")); - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word); - DmaCfg.field.EnableTxDMA = 1; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word); - pAd->CheckDmaBusyCount++; - return; - } - else - { - pAd->CheckDmaBusyCount = 0; - } - - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); - - // Set to 1R. - if (pAd->Antenna.field.RxPath > 1) - { - tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3); - } - - // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. - if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel) - && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) - { - // Must using 40MHz. - AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel); - } - else - { - // Must using 20MHz. - AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel); - } - - if (Level != RTMP_HALT) - { - // Change Interrupt bitmask. - RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt); - } - else - { - NICDisableInterrupt(pAd); - } - - RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx); - // Disable MAC Rx - RTMP_IO_READ32(pAd, MAC_SYS_CTRL , &MACValue); - MACValue &= 0xf7; - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL , MACValue); - - // 2. Send Sleep command - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff); - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff); - // send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power - AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1); - // 2-1. Wait command success - // Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task. - brc = AsicCheckCommanOk(pAd, PowerSafeCID); - - if (brc == FALSE) - { - // try again - AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x01); // send POWER-SAVE command to MCU. Timeout unit:40us. - //RTMPusecDelay(200); - brc = AsicCheckCommanOk(pAd, PowerSafeCID); - } - - // 3. After 0x30 command is ok, send radio off command. lowbyte = 0 for power safe. - // If 0x30 command is not ok this time, we can ignore 0x35 command. It will make sure not cause firmware'r problem. - if ((Level == DOT11POWERSAVE) && (brc == TRUE)) - { - AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 0, 0x00); // lowbyte = 0 means to do power safe, NOT turn off radio. - // 3-1. Wait command success - AsicCheckCommanOk(pAd, PowerRadioOffCID); - } - else if (brc == TRUE) - { - AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 1, 0x00); // lowbyte = 0 means to do power safe, NOT turn off radio. - // 3-1. Wait command success - AsicCheckCommanOk(pAd, PowerRadioOffCID); - } - - // Wait DMA not busy - i = 0; - do - { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word); - if ((DmaCfg.field.RxDMABusy == 0) && (DmaCfg.field.TxDMABusy == 0)) - break; - RTMPusecDelay(20); - i++; - }while(i < 50); - - if (i >= 50) - { - pAd->CheckDmaBusyCount++; - DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy. on RT28xxPciAsicRadioOff ()\n")); - } - else - { - pAd->CheckDmaBusyCount = 0; - } - - if (Level == DOT11POWERSAVE) - { - AUTO_WAKEUP_STRUC AutoWakeupCfg; - //RTMPSetTimer(&pAd->Mlme.PsPollTimer, 90); - - // we have decided to SLEEP, so at least do it for a BEACON period. - if (TbttNumToNextWakeUp == 0) - TbttNumToNextWakeUp = 1; - - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - - // 1. Set auto wake up timer. - AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1; - AutoWakeupCfg.field.EnableAutoWakeup = 1; - AutoWakeupCfg.field.AutoLeadTime = LEAD_TIME; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - } - - // 4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value. - if (Level == RTMP_HALT) - { - if ((brc == TRUE) && (i < 50)) - RTMPPCIeLinkCtrlSetting(pAd, 0); - } - // 4. Set PCI configuration Space Link Comtrol fields. Only Radio Off needs to call this function - else - { - if ((brc == TRUE) && (i < 50)) - RTMPPCIeLinkCtrlSetting(pAd, 3); - } - - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX); -} - - -/* - ========================================================================== - Description: - This routine sends command to firmware and turn our chip to wake up mode from power save mode. - Both RadioOn and .11 power save function needs to call this routine. - Input: - Level = GUIRADIO_OFF : call this function is from Radio Off to Radio On. Need to restore PCI host value. - Level = other value : normal wake up function. - - ========================================================================== - */ -BOOLEAN RT28xxPciAsicRadioOn( - IN PRTMP_ADAPTER pAd, - IN UCHAR Level) -{ - WPDMA_GLO_CFG_STRUC DmaCfg; - BOOLEAN Cancelled, brv = TRUE; - UINT32 MACValue; - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) - { - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE) - || (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))) - { - DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n")); - // 1. Set PCI Link Control in Configuration Space. - RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP); - RTMPusecDelay(6000); - } - } - - pAd->bPCIclkOff = FALSE; - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x3a80); - // 2. Send wake up command. - AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02); - - // 2-1. wait command ok. - brv = AsicCheckCommanOk(pAd, PowerWakeCID); - if (brv) - { - NICEnableInterrupt(pAd); - - // 3. Enable Tx DMA. - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word); - DmaCfg.field.EnableTxDMA = 1; - DmaCfg.field.EnableRxDMA = 1; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word); - - // Eable MAC Rx - RTMP_IO_READ32(pAd, MAC_SYS_CTRL , &MACValue); - MACValue |= 0x8; - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL , MACValue); - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); - if (Level == GUI_IDLE_POWER_SAVE) - { - // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. - if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel) - && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) - { - // Must using 40MHz. - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); - } - else - { - // Must using 20MHz. - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - } - } - return TRUE; - } - else - return FALSE; -} - -VOID RT28xxPciStaAsicForceWakeup( - IN PRTMP_ADAPTER pAd, - IN UCHAR Level) -{ - AUTO_WAKEUP_STRUC AutoWakeupCfg; - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) - { - DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n")); - return; - } - - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW); - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) - { - // Support PCIe Advance Power Save - if (((Level == FROM_TX) && (pAd->Mlme.bPsPollTimerRunning == TRUE)) || - (Level == RTMP_HALT)) - { - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP); - RTMPusecDelay(5000); - DBGPRINT(RT_DEBUG_TRACE, ("=======AsicForceWakeup===bFromTx\n")); - } - - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - - // If this is called from Halt. ALWAYS force wakeup!!! - if (Level == RTMP_HALT) - { - RT28xxPciAsicRadioOn(pAd, RTMP_HALT); - } - else - { - if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE)) - { - // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. - if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel) - && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) - { - // Must using 40MHz. - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); - } - else - { - // Must using 20MHz. - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - } - } - } - } - else - { - // PCI, 2860-PCIe - AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x00); - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - } - - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW); - DBGPRINT(RT_DEBUG_TRACE, ("<=======RT28xxPciStaAsicForceWakeup\n")); -} - -VOID RT28xxPciStaAsicSleepThenAutoWakeup( - IN PRTMP_ADAPTER pAd, - IN USHORT TbttNumToNextWakeUp) -{ - if (pAd->StaCfg.bRadio == FALSE) - { - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - return; - } - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) - { - ULONG Now = 0; - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) - { - DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n")); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); - return; - } - - NdisGetSystemUpTime(&Now); - // If last send NULL fram time is too close to this receiving beacon (within 8ms), don't go to sleep for this DTM. - // Because Some AP can't queuing outgoing frames immediately. - if (((pAd->Mlme.LastSendNULLpsmTime + 8) >= Now) && (pAd->Mlme.LastSendNULLpsmTime <= Now)) - { - DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu : RxCountSinceLastNULL = %lu. \n", Now, pAd->Mlme.LastSendNULLpsmTime, pAd->RalinkCounters.RxCountSinceLastNULL)); - return; - } - else if ((pAd->RalinkCounters.RxCountSinceLastNULL > 0) && ((pAd->Mlme.LastSendNULLpsmTime + pAd->CommonCfg.BeaconPeriod) >= Now)) - { - DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu: RxCountSinceLastNULL = %lu > 0 \n", Now, pAd->Mlme.LastSendNULLpsmTime, pAd->RalinkCounters.RxCountSinceLastNULL)); - return; - } - - RT28xxPciAsicRadioOff(pAd, DOT11POWERSAVE, TbttNumToNextWakeUp); - } - else - { - AUTO_WAKEUP_STRUC AutoWakeupCfg; - // we have decided to SLEEP, so at least do it for a BEACON period. - if (TbttNumToNextWakeUp == 0) - TbttNumToNextWakeUp = 1; - - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1; - AutoWakeupCfg.field.EnableAutoWakeup = 1; - AutoWakeupCfg.field.AutoLeadTime = 5; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x00); // send POWER-SAVE command to MCU. Timeout 40us. - DBGPRINT(RT_DEBUG_TRACE, ("<-- %s, TbttNumToNextWakeUp=%d \n", __func__, TbttNumToNextWakeUp)); - } - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE); -} - -VOID PsPollWakeExec( - IN PVOID SystemSpecific1, - IN PVOID FunctionContext, - IN PVOID SystemSpecific2, - IN PVOID SystemSpecific3) -{ - RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; - unsigned long flags; - - DBGPRINT(RT_DEBUG_TRACE,("-->PsPollWakeExec \n")); - RTMP_INT_LOCK(&pAd->irq_lock, flags); - if (pAd->Mlme.bPsPollTimerRunning) - { - RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP); - } - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMP_INT_UNLOCK(&pAd->irq_lock, flags); -} - -VOID RadioOnExec( - IN PVOID SystemSpecific1, - IN PVOID FunctionContext, - IN PVOID SystemSpecific2, - IN PVOID SystemSpecific3) -{ - RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; - WPDMA_GLO_CFG_STRUC DmaCfg; - BOOLEAN Cancelled; - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - { - DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n")); - RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); - return; - } - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - { - DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n")); - RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); - return; - } - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - if (pAd->StaCfg.bRadio == TRUE) - { - pAd->bPCIclkOff = FALSE; - RTMPRingCleanUp(pAd, QID_AC_BK); - RTMPRingCleanUp(pAd, QID_AC_BE); - RTMPRingCleanUp(pAd, QID_AC_VI); - RTMPRingCleanUp(pAd, QID_AC_VO); - RTMPRingCleanUp(pAd, QID_HCCA); - RTMPRingCleanUp(pAd, QID_MGMT); - RTMPRingCleanUp(pAd, QID_RX); - - // 2. Send wake up command. - AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02); - // 2-1. wait command ok. - AsicCheckCommanOk(pAd, PowerWakeCID); - - // When PCI clock is off, don't want to service interrupt. So when back to clock on, enable interrupt. - NICEnableInterrupt(pAd); - - // 3. Enable Tx DMA. - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word); - DmaCfg.field.EnableTxDMA = 1; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word); - - // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. - if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel) - && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) - { - // Must using 40MHz. - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); - } - else - { - // Must using 20MHz. - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - } - - // Clear Radio off flag - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - // Set LED - RTMPSetLED(pAd, LED_RADIO_ON); - - if (pAd->StaCfg.Psm == PWR_ACTIVE) - { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); - } - } - else - { - RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0); - } -} - -VOID RT28xxPciMlmeRadioOn( - IN PRTMP_ADAPTER pAd) -{ - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) - return; - - DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__)); - - if ((pAd->OpMode == OPMODE_AP) || - ((pAd->OpMode == OPMODE_STA) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)))) - { - NICResetFromError(pAd); - - /* - RTMPRingCleanUp(pAd, QID_AC_BK); - RTMPRingCleanUp(pAd, QID_AC_BE); - RTMPRingCleanUp(pAd, QID_AC_VI); - RTMPRingCleanUp(pAd, QID_AC_VO); - RTMPRingCleanUp(pAd, QID_HCCA); - RTMPRingCleanUp(pAd, QID_MGMT); - RTMPRingCleanUp(pAd, QID_RX); - */ - - // Enable Tx/Rx - RTMPEnableRxTx(pAd); - - // Clear Radio off flag - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - // Set LED - RTMPSetLED(pAd, LED_RADIO_ON); - } - - if ((pAd->OpMode == OPMODE_STA) && - (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))) - { - BOOLEAN Cancelled; - - RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP); - - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); - RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); - } -} - -VOID RT28xxPciMlmeRadioOFF( - IN PRTMP_ADAPTER pAd) -{ - WPDMA_GLO_CFG_STRUC GloCfg; - UINT32 i; - - if (pAd->StaCfg.bRadio == TRUE) - { - DBGPRINT(RT_DEBUG_TRACE,("-->MlmeRadioOff() return on bRadio == TRUE; \n")); - return; - } - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) - return; - - DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__)); - - // Set LED - RTMPSetLED(pAd, LED_RADIO_OFF); - - { - BOOLEAN Cancelled; - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - { - RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); - } - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) - { - BOOLEAN Cancelled; - - // Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF). - if ((pAd->OpMode == OPMODE_STA) && - (IDLE_ON(pAd)) && - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) - { - RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); - } - - pAd->Mlme.bPsPollTimerRunning = FALSE; - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); - } - - // Link down first if any association exists - if (INFRA_ON(pAd) || ADHOC_ON(pAd)) - LinkDown(pAd, FALSE); - RTMPusecDelay(10000); - //========================================== - // Clean up old bss table - BssTableInit(&pAd->ScanTab); - - RTMPRingCleanUp(pAd, QID_AC_BK); - RTMPRingCleanUp(pAd, QID_AC_BE); - RTMPRingCleanUp(pAd, QID_AC_VI); - RTMPRingCleanUp(pAd, QID_AC_VO); - RTMPRingCleanUp(pAd, QID_HCCA); - RTMPRingCleanUp(pAd, QID_MGMT); - RTMPRingCleanUp(pAd, QID_RX); - - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) - { - RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 500); - return; - } - } - - // Set Radio off flag - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - // Disable Tx/Rx DMA - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA - GloCfg.field.EnableTxDMA = 0; - GloCfg.field.EnableRxDMA = 0; - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings - - - // MAC_SYS_CTRL => value = 0x0 => 40mA - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0); - - // PWR_PIN_CFG => value = 0x0 => 40mA - RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0); - - // TX_PIN_CFG => value = 0x0 => 20mA - RTMP_IO_WRITE32(pAd, TX_PIN_CFG, 0); - - if (pAd->CommonCfg.BBPCurrentBW == BW_40) - { - // Must using 40MHz. - AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel); - } - else - { - // Must using 20MHz. - AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel); - } - - // Waiting for DMA idle - i = 0; - do - { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) - break; - - RTMPusecDelay(1000); - }while (i++ < 100); -} Index: b/drivers/staging/rt2860/common/cmm_data_pci.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/cmm_data_pci.c @@ -0,0 +1,1163 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + */ + +/* + All functions in this file must be PCI-depended, or you should out your function + in other files. + +*/ +#include "../rt_config.h" + + +USHORT RtmpPCI_WriteTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN BOOLEAN bIsLast, + OUT USHORT *FreeNumber) +{ + + UCHAR *pDMAHeaderBufVA; + USHORT TxIdx, RetTxIdx; + PTXD_STRUC pTxD; + UINT32 BufBasePaLow; + PRTMP_TX_RING pTxRing; + USHORT hwHeaderLen; + + // + // get Tx Ring Resource + // + pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; + TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx; + pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; + BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); + + // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer + if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) + { + //hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; + hwHeaderLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD; + } + else + { + //hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); + hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; + } + NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen); + + pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket; + pTxRing->Cell[TxIdx].pNextNdisPacket = NULL; + + // + // build Tx Descriptor + // + + pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa; + NdisZeroMemory(pTxD, TXD_SIZE); + + pTxD->SDPtr0 = BufBasePaLow; + pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding + pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE); + pTxD->SDLen1 = pTxBlk->SrcBufLen; + pTxD->LastSec0 = 0; + pTxD->LastSec1 = (bIsLast) ? 1 : 0; + + RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); + + RetTxIdx = TxIdx; + // + // Update Tx index + // + INC_RING_INDEX(TxIdx, TX_RING_SIZE); + pTxRing->TxCpuIdx = TxIdx; + + *FreeNumber -= 1; + + return RetTxIdx; +} + + +USHORT RtmpPCI_WriteSingleTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN BOOLEAN bIsLast, + OUT USHORT *FreeNumber) +{ + + UCHAR *pDMAHeaderBufVA; + USHORT TxIdx, RetTxIdx; + PTXD_STRUC pTxD; + UINT32 BufBasePaLow; + PRTMP_TX_RING pTxRing; + USHORT hwHeaderLen; + + // + // get Tx Ring Resource + // + pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; + TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx; + pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; + BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); + + // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer + //hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); + hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; + + NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHeaderLen); + + pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket; + pTxRing->Cell[TxIdx].pNextNdisPacket = NULL; + + // + // build Tx Descriptor + // + pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa; + NdisZeroMemory(pTxD, TXD_SIZE); + + pTxD->SDPtr0 = BufBasePaLow; + pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; // include padding + pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);; + pTxD->SDLen1 = pTxBlk->SrcBufLen; + pTxD->LastSec0 = 0; + pTxD->LastSec1 = (bIsLast) ? 1 : 0; + + RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); + + RetTxIdx = TxIdx; + // + // Update Tx index + // + INC_RING_INDEX(TxIdx, TX_RING_SIZE); + pTxRing->TxCpuIdx = TxIdx; + + *FreeNumber -= 1; + + return RetTxIdx; +} + + +USHORT RtmpPCI_WriteMultiTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR frameNum, + OUT USHORT *FreeNumber) +{ + BOOLEAN bIsLast; + UCHAR *pDMAHeaderBufVA; + USHORT TxIdx, RetTxIdx; + PTXD_STRUC pTxD; + UINT32 BufBasePaLow; + PRTMP_TX_RING pTxRing; + USHORT hwHdrLen; + UINT32 firstDMALen; + + bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0); + + // + // get Tx Ring Resource + // + pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; + TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx; + pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; + BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); + + if (frameNum == 0) + { + // copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer + if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) + //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; + hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD; + else if (pTxBlk->TxFrameType == TX_RALINK_FRAME) + //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; + hwHdrLen = pTxBlk->MpduHeaderLen - LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD; + else + //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); + hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; + + firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen; + } + else + { + firstDMALen = pTxBlk->MpduHeaderLen; + } + + NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen); + + pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket; + pTxRing->Cell[TxIdx].pNextNdisPacket = NULL; + + // + // build Tx Descriptor + // + pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa; + NdisZeroMemory(pTxD, TXD_SIZE); + + pTxD->SDPtr0 = BufBasePaLow; + pTxD->SDLen0 = firstDMALen; // include padding + pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);; + pTxD->SDLen1 = pTxBlk->SrcBufLen; + pTxD->LastSec0 = 0; + pTxD->LastSec1 = (bIsLast) ? 1 : 0; + + RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); + + + RetTxIdx = TxIdx; + // + // Update Tx index + // + INC_RING_INDEX(TxIdx, TX_RING_SIZE); + pTxRing->TxCpuIdx = TxIdx; + + *FreeNumber -= 1; + + return RetTxIdx; + +} + + +VOID RtmpPCI_FinalWriteTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN USHORT totalMPDUSize, + IN USHORT FirstTxIdx) +{ + + PTXWI_STRUC pTxWI; + PRTMP_TX_RING pTxRing; + + // + // get Tx Ring Resource + // + pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; + pTxWI = (PTXWI_STRUC) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa; + pTxWI->MPDUtotalByteCount = totalMPDUSize; + +} + + +VOID RtmpPCIDataLastTxIdx( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN USHORT LastTxIdx) +{ + PTXD_STRUC pTxD; + PRTMP_TX_RING pTxRing; + + // + // get Tx Ring Resource + // + pTxRing = &pAd->TxRing[QueIdx]; + + // + // build Tx Descriptor + // + pTxD = (PTXD_STRUC) pTxRing->Cell[LastTxIdx].AllocVa; + + pTxD->LastSec1 = 1; + + +} + + +USHORT RtmpPCI_WriteFragTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR fragNum, + OUT USHORT *FreeNumber) +{ + UCHAR *pDMAHeaderBufVA; + USHORT TxIdx, RetTxIdx; + PTXD_STRUC pTxD; + UINT32 BufBasePaLow; + PRTMP_TX_RING pTxRing; + USHORT hwHeaderLen; + UINT32 firstDMALen; + + // + // Get Tx Ring Resource + // + pTxRing = &pAd->TxRing[pTxBlk->QueIdx]; + TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx; + pDMAHeaderBufVA = (PUCHAR) pTxRing->Cell[TxIdx].DmaBuf.AllocVa; + BufBasePaLow = RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa); + + // + // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer + // + //hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); + hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; + + firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; + NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen); + + + // + // Build Tx Descriptor + // + pTxD = (PTXD_STRUC) pTxRing->Cell[TxIdx].AllocVa; + NdisZeroMemory(pTxD, TXD_SIZE); + + if (fragNum == pTxBlk->TotalFragNum) + { + pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket; + pTxRing->Cell[TxIdx].pNextNdisPacket = NULL; + } + + pTxD->SDPtr0 = BufBasePaLow; + pTxD->SDLen0 = firstDMALen; // include padding + pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE); + pTxD->SDLen1 = pTxBlk->SrcBufLen; + pTxD->LastSec0 = 0; + pTxD->LastSec1 = 1; + + RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA); + + + RetTxIdx = TxIdx; + pTxBlk->Priv += pTxBlk->SrcBufLen; + + // + // Update Tx index + // + INC_RING_INDEX(TxIdx, TX_RING_SIZE); + pTxRing->TxCpuIdx = TxIdx; + + *FreeNumber -= 1; + + return RetTxIdx; + +} + + +/* + Must be run in Interrupt context + This function handle PCI specific TxDesc and cpu index update and kick the packet out. + */ +int RtmpPCIMgmtKickOut( + IN RTMP_ADAPTER *pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket, + IN PUCHAR pSrcBufVA, + IN UINT SrcBufLen) +{ + PTXD_STRUC pTxD; + ULONG SwIdx = pAd->MgmtRing.TxCpuIdx; + + pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa; + + pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket; + pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL; + + RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT); + pTxD->LastSec0 = 1; + pTxD->LastSec1 = 1; + pTxD->DMADONE = 0; + pTxD->SDLen1 = 0; + pTxD->SDPtr0 = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE); + pTxD->SDLen0 = SrcBufLen; + + +//================================================================== +/* DBGPRINT_RAW(RT_DEBUG_TRACE, ("MLMEHardTransmit\n")); + for (i = 0; i < (TXWI_SIZE+24); i++) + { + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("%x:", *(pSrcBufVA+i))); + if ( i%4 == 3) + DBGPRINT_RAW(RT_DEBUG_TRACE, (" :: ")); + if ( i%16 == 15) + DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n ")); + } + DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n "));*/ +//======================================================================= + + pAd->RalinkCounters.KickTxCount++; + pAd->RalinkCounters.OneSecTxDoneCount++; + + // Increase TX_CTX_IDX, but write to register later. + INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE); + + RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx); + + return 0; +} + + +/* + ======================================================================== + + Routine Description: + Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound + + Arguments: + pRxD Pointer to the Rx descriptor + + Return Value: + NDIS_STATUS_SUCCESS No err + NDIS_STATUS_FAILURE Error + + Note: + + ======================================================================== +*/ +NDIS_STATUS RTMPCheckRxError( + IN PRTMP_ADAPTER pAd, + IN PHEADER_802_11 pHeader, + IN PRXWI_STRUC pRxWI, + IN PRT28XX_RXD_STRUC pRxD) +{ + PCIPHER_KEY pWpaKey; + INT dBm; + + // Phy errors & CRC errors + if (/*(pRxD->PhyErr) ||*/ (pRxD->Crc)) + { + // Check RSSI for Noise Hist statistic collection. + dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta; + if (dBm <= -87) + pAd->StaCfg.RPIDensity[0] += 1; + else if (dBm <= -82) + pAd->StaCfg.RPIDensity[1] += 1; + else if (dBm <= -77) + pAd->StaCfg.RPIDensity[2] += 1; + else if (dBm <= -72) + pAd->StaCfg.RPIDensity[3] += 1; + else if (dBm <= -67) + pAd->StaCfg.RPIDensity[4] += 1; + else if (dBm <= -62) + pAd->StaCfg.RPIDensity[5] += 1; + else if (dBm <= -57) + pAd->StaCfg.RPIDensity[6] += 1; + else if (dBm > -57) + pAd->StaCfg.RPIDensity[7] += 1; + + return(NDIS_STATUS_FAILURE); + } + + // Add Rx size to channel load counter, we should ignore error counts + pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14); + + // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics + if (pHeader != NULL) + { + if (pHeader->FC.ToDs) + { + return(NDIS_STATUS_FAILURE); + } + } + + // Drop not U2M frames, cant's drop here because we will drop beacon in this case + // I am kind of doubting the U2M bit operation + // if (pRxD->U2M == 0) + // return(NDIS_STATUS_FAILURE); + + // drop decyption fail frame + if (pRxD->CipherErr) + { + if (pRxD->CipherErr == 2) + {DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV ok but MICErr "));} + else if (pRxD->CipherErr == 1) + {DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: ICV Err "));} + else if (pRxD->CipherErr == 3) + DBGPRINT_RAW(RT_DEBUG_TRACE,("pRxD ERROR: Key not valid ")); + + if (((pRxD->CipherErr & 1) == 1) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd)) + RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + + DBGPRINT_RAW(RT_DEBUG_TRACE,(" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n", + pRxD->CipherErr, + pRxD->SDL0, + pRxD->Mcast | pRxD->Bcast, + pRxD->MyBss, + pRxWI->WirelessCliID, +// CipherName[pRxD->CipherAlg], + pRxWI->KeyIndex)); + + // + // MIC Error + // + if (pRxD->CipherErr == 2) + { + pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex]; + if (pAd->StaCfg.WpaSupplicantUP) + WpaSendMicFailureToWpaSupplicant(pAd, + (pWpaKey->Type == PAIRWISEKEY) ? TRUE:FALSE); + else + RTMPReportMicError(pAd, pWpaKey); + + if (((pRxD->CipherErr & 2) == 2) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd)) + RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + + DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n")); + } + + if (pHeader == NULL) + return(NDIS_STATUS_SUCCESS); + /*if ((pRxD->CipherAlg == CIPHER_AES) && + (pHeader->Sequence == pAd->FragFrame.Sequence)) + { + // + // Acceptable since the First FragFrame no CipherErr problem. + // + return(NDIS_STATUS_SUCCESS); + }*/ + + return(NDIS_STATUS_FAILURE); + } + + return(NDIS_STATUS_SUCCESS); +} + + +BOOLEAN RTMPFreeTXDUponTxDmaDone( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx) +{ + PRTMP_TX_RING pTxRing; + PTXD_STRUC pTxD; + PNDIS_PACKET pPacket; + UCHAR FREE = 0; + TXD_STRUC TxD, *pOriTxD; + //ULONG IrqFlags; + BOOLEAN bReschedule = FALSE; + + + ASSERT(QueIdx < NUM_OF_TX_RING); + pTxRing = &pAd->TxRing[QueIdx]; + + RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF, &pTxRing->TxDmaIdx); + while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx) + { +// RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); + + // static rate also need NICUpdateFifoStaCounters() function. + //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) + NICUpdateFifoStaCounters(pAd); + + /* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */ + FREE++; + pTxD = (PTXD_STRUC) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa); + pOriTxD = pTxD; + NdisMoveMemory(&TxD, pTxD, sizeof(TXD_STRUC)); + pTxD = &TxD; + + pTxD->DMADONE = 0; + + + { + pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket; + if (pPacket) + { +#ifdef CONFIG_5VT_ENHANCE + if (RTMP_GET_PACKET_5VT(pPacket)) + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE); + else +#endif // CONFIG_5VT_ENHANCE // + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); + } + //Always assign pNdisPacket as NULL after clear + pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL; + + pPacket = pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket; + + ASSERT(pPacket == NULL); + if (pPacket) + { +#ifdef CONFIG_5VT_ENHANCE + if (RTMP_GET_PACKET_5VT(pPacket)) + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, 16, PCI_DMA_TODEVICE); + else +#endif // CONFIG_5VT_ENHANCE // + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); + } + //Always assign pNextNdisPacket as NULL after clear + pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL; + } + + pAd->RalinkCounters.TransmittedByteCount += (pTxD->SDLen1 + pTxD->SDLen0); + pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx] ++; + INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE); + /* get tx_tdx_idx again */ + RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF , &pTxRing->TxDmaIdx); + NdisMoveMemory(pOriTxD, pTxD, sizeof(TXD_STRUC)); + +// RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); + } + + + return bReschedule; + +} + + +/* + ======================================================================== + + Routine Description: + Process TX Rings DMA Done interrupt, running in DPC level + + Arguments: + Adapter Pointer to our adapter + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + ======================================================================== +*/ +BOOLEAN RTMPHandleTxRingDmaDoneInterrupt( + IN PRTMP_ADAPTER pAd, + IN INT_SOURCE_CSR_STRUC TxRingBitmap) +{ +// UCHAR Count = 0; + unsigned long IrqFlags; + BOOLEAN bReschedule = FALSE; + + // Make sure Tx ring resource won't be used by other threads + //NdisAcquireSpinLock(&pAd->TxRingLock); + + RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); + + if (TxRingBitmap.field.Ac0DmaDone) + bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE); + + if (TxRingBitmap.field.HccaDmaDone) + bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_HCCA); + + if (TxRingBitmap.field.Ac3DmaDone) + bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO); + + if (TxRingBitmap.field.Ac2DmaDone) + bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI); + + if (TxRingBitmap.field.Ac1DmaDone) + bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK); + + // Make sure to release Tx ring resource + //NdisReleaseSpinLock(&pAd->TxRingLock); + RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); + + // Dequeue outgoing frames from TxSwQueue[] and process it + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); + + return bReschedule; +} + + +/* + ======================================================================== + + Routine Description: + Process MGMT ring DMA done interrupt, running in DPC level + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPHandleMgmtRingDmaDoneInterrupt( + IN PRTMP_ADAPTER pAd) +{ + PTXD_STRUC pTxD; + PNDIS_PACKET pPacket; +// int i; + UCHAR FREE = 0; + PRTMP_MGMT_RING pMgmtRing = &pAd->MgmtRing; + + NdisAcquireSpinLock(&pAd->MgmtRingLock); + + RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx); + while (pMgmtRing->TxSwFreeIdx!= pMgmtRing->TxDmaIdx) + { + FREE++; + pTxD = (PTXD_STRUC) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].AllocVa); + pTxD->DMADONE = 0; + pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket; + + + if (pPacket) + { + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); + } + pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL; + + pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket; + if (pPacket) + { + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); + } + pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL; + INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE); + + } + NdisReleaseSpinLock(&pAd->MgmtRingLock); + +} + + +/* + ======================================================================== + + Routine Description: + Arguments: + Adapter Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon. + + IRQL = DISPATCH_LEVEL + + ======================================================================== +*/ +VOID RTMPHandleTBTTInterrupt( + IN PRTMP_ADAPTER pAd) +{ + { + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + { + } + } +} + + +/* + ======================================================================== + + Routine Description: + Arguments: + pAd Pointer to our adapter. Rewrite beacon content before next send-out. + + IRQL = DISPATCH_LEVEL + + ======================================================================== +*/ +VOID RTMPHandlePreTBTTInterrupt( + IN PRTMP_ADAPTER pAd) +{ + { + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + { + DBGPRINT(RT_DEBUG_TRACE, ("RTMPHandlePreTBTTInterrupt...\n")); + } + } + + +} + +VOID RTMPHandleRxCoherentInterrupt( + IN PRTMP_ADAPTER pAd) +{ + WPDMA_GLO_CFG_STRUC GloCfg; + + if (pAd == NULL) + { + DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n")); + return; + } + + DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n")); + + RTMP_IO_READ32(pAd, WPDMA_GLO_CFG , &GloCfg.word); + + GloCfg.field.EnTXWriteBackDDONE = 0; + GloCfg.field.EnableRxDMA = 0; + GloCfg.field.EnableTxDMA = 0; + RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); + + RTMPRingCleanUp(pAd, QID_AC_BE); + RTMPRingCleanUp(pAd, QID_AC_BK); + RTMPRingCleanUp(pAd, QID_AC_VI); + RTMPRingCleanUp(pAd, QID_AC_VO); + RTMPRingCleanUp(pAd, QID_HCCA); + RTMPRingCleanUp(pAd, QID_MGMT); + RTMPRingCleanUp(pAd, QID_RX); + + RTMPEnableRxTx(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n")); +} + +PNDIS_PACKET GetPacketFromRxRing( + IN PRTMP_ADAPTER pAd, + OUT PRT28XX_RXD_STRUC pSaveRxD, + OUT BOOLEAN *pbReschedule, + IN OUT UINT32 *pRxPending) +{ + PRXD_STRUC pRxD; + PNDIS_PACKET pRxPacket = NULL; + PNDIS_PACKET pNewPacket; + PVOID AllocVa; + NDIS_PHYSICAL_ADDRESS AllocPa; + BOOLEAN bReschedule = FALSE; + RTMP_DMACB *pRxCell; + + RTMP_SEM_LOCK(&pAd->RxRingLock); + + if (*pRxPending == 0) + { + // Get how may packets had been received + RTMP_IO_READ32(pAd, RX_DRX_IDX , &pAd->RxRing.RxDmaIdx); + + if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx) + { + // no more rx packets + bReschedule = FALSE; + goto done; + } + + // get rx pending count + if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx) + *pRxPending = pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx; + else + *pRxPending = pAd->RxRing.RxDmaIdx + RX_RING_SIZE - pAd->RxRing.RxSwReadIdx; + + } + + pRxCell = &pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx]; + + // Point to Rx indexed rx ring descriptor + pRxD = (PRXD_STRUC) pRxCell->AllocVa; + + if (pRxD->DDONE == 0) + { + *pRxPending = 0; + // DMAIndx had done but DDONE bit not ready + bReschedule = TRUE; + goto done; + } + + + // return rx descriptor + NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE); + + pNewPacket = RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE, &AllocVa, &AllocPa); + + if (pNewPacket) + { + // unmap the rx buffer + PCI_UNMAP_SINGLE(pAd, pRxCell->DmaBuf.AllocPa, + pRxCell->DmaBuf.AllocSize, PCI_DMA_FROMDEVICE); + pRxPacket = pRxCell->pNdisPacket; + + pRxCell->DmaBuf.AllocSize = RX_BUFFER_AGGRESIZE; + pRxCell->pNdisPacket = (PNDIS_PACKET) pNewPacket; + pRxCell->DmaBuf.AllocVa = AllocVa; + pRxCell->DmaBuf.AllocPa = AllocPa; + /* update SDP0 to new buffer of rx packet */ + pRxD->SDP0 = AllocPa; + } + else + { + //DBGPRINT(RT_DEBUG_TRACE,("No Rx Buffer\n")); + pRxPacket = NULL; + bReschedule = TRUE; + } + + pRxD->DDONE = 0; + + // had handled one rx packet + *pRxPending = *pRxPending - 1; + + // update rx descriptor and kick rx + INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE); + + pAd->RxRing.RxCpuIdx = (pAd->RxRing.RxSwReadIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxSwReadIdx-1); + RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx); + +done: + RTMP_SEM_UNLOCK(&pAd->RxRingLock); + *pbReschedule = bReschedule; + return pRxPacket; +} + + +NDIS_STATUS MlmeHardTransmitTxRing( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket) +{ + PACKET_INFO PacketInfo; + PUCHAR pSrcBufVA; + UINT SrcBufLen; + PTXD_STRUC pTxD; + PHEADER_802_11 pHeader_802_11; + BOOLEAN bAckRequired, bInsertTimestamp; + ULONG SrcBufPA; + //UCHAR TxBufIdx; + UCHAR MlmeRate; + ULONG SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; + PTXWI_STRUC pFirstTxWI; + //ULONG i; + //HTTRANSMIT_SETTING MlmeTransmit; //Rate for this MGMT frame. + ULONG FreeNum; + MAC_TABLE_ENTRY *pMacEntry = NULL; + + + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); + + + if (pSrcBufVA == NULL) + { + // The buffer shouldn't be NULL + return NDIS_STATUS_FAILURE; + } + + // Make sure MGMT ring resource won't be used by other threads + //NdisAcquireSpinLock(&pAd->TxRingLock); + + FreeNum = GET_TXRING_FREENO(pAd, QueIdx); + + if (FreeNum == 0) + { + //NdisReleaseSpinLock(&pAd->TxRingLock); + return NDIS_STATUS_FAILURE; + } + + SwIdx = pAd->TxRing[QueIdx].TxCpuIdx; + + pTxD = (PTXD_STRUC) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa; + + if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket) + { + DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n")); + //NdisReleaseSpinLock(&pAd->TxRingLock); + return NDIS_STATUS_FAILURE; + } + + { + // outgoing frame always wakeup PHY to prevent frame lost + // if (pAd->StaCfg.Psm == PWR_SAVE) + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + AsicForceWakeup(pAd, TRUE); + } + pFirstTxWI =(PTXWI_STRUC)pSrcBufVA; + + pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXWI_SIZE); + if (pHeader_802_11->Addr1[0] & 0x01) + { + MlmeRate = pAd->CommonCfg.BasicMlmeRate; + } + else + { + MlmeRate = pAd->CommonCfg.MlmeRate; + } + + if ((pHeader_802_11->FC.Type == BTYPE_DATA) && + (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) + { + pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1); + } + + // Verify Mlme rate for a / g bands. + if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band + MlmeRate = RATE_6; + + // + // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) + // Snice it's been set to 0 while on MgtMacHeaderInit + // By the way this will cause frame to be send on PWR_SAVE failed. + // + // + // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame + // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD + if (pHeader_802_11->FC.Type != BTYPE_DATA) + { + if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ) || !(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) + { + pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE; + } + else + { + pHeader_802_11->FC.PwrMgmt = pAd->CommonCfg.bAPSDForcePowerSave; + } + } + + bInsertTimestamp = FALSE; + if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL + { + bAckRequired = FALSE; + } + else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame) + { + if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST + { + bAckRequired = FALSE; + pHeader_802_11->Duration = 0; + } + else + { + bAckRequired = TRUE; + pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14); + if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) + { + bInsertTimestamp = TRUE; + } + } + } + pHeader_802_11->Sequence = pAd->Sequence++; + if (pAd->Sequence > 0xfff) + pAd->Sequence = 0; + // Before radar detection done, mgmt frame can not be sent but probe req + // Because we need to use probe req to trigger driver to send probe req in passive scan + if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ) + && (pAd->CommonCfg.bIEEE80211H == 1) + && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) + { + DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n")); + //NdisReleaseSpinLock(&pAd->TxRingLock); + return (NDIS_STATUS_FAILURE); + } + + // + // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET + // should always has only one ohysical buffer, and the whole frame size equals + // to the first scatter buffer size + // + + // Initialize TX Descriptor + // For inter-frame gap, the number is for this frame and next frame + // For MLME rate, we will fix as 2Mb to match other vendor's implement +// pAd->CommonCfg.MlmeTransmit.field.MODE = 1; + +// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. + // Only beacon use Nseq=TRUE. So here we use Nseq=FALSE. + if (pMacEntry == NULL) + { + RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE, + 0, RESERVED_WCID, (SrcBufLen - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); + } + else + { + RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, + bInsertTimestamp, FALSE, bAckRequired, FALSE, + 0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE), + pMacEntry->MaxHTPhyMode.field.MCS, 0, + (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS, + IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode); + } + + pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket; + pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL; +// pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE; + SrcBufPA = PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE); + + + RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA); + pTxD->LastSec0 = 1; + pTxD->LastSec1 = 1; + pTxD->SDLen0 = SrcBufLen; + pTxD->SDLen1 = 0; + pTxD->SDPtr0 = SrcBufPA; + pTxD->DMADONE = 0; + + + pAd->RalinkCounters.KickTxCount++; + pAd->RalinkCounters.OneSecTxDoneCount++; + + // Increase TX_CTX_IDX, but write to register later. + INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE); + + RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx*0x10, pAd->TxRing[QueIdx].TxCpuIdx); + + // Make sure to release MGMT ring resource +// NdisReleaseSpinLock(&pAd->TxRingLock); + + return NDIS_STATUS_SUCCESS; +} + + +NDIS_STATUS MlmeDataHardTransmit( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket) +{ + if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) + ) + { + return NDIS_STATUS_FAILURE; + } + + return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket); +} + + +/* + ======================================================================== + + Routine Description: + Calculates the duration which is required to transmit out frames + with given size and specified rate. + + Arguments: + pTxD Pointer to transmit descriptor + Ack Setting for Ack requirement bit + Fragment Setting for Fragment bit + RetryMode Setting for retry mode + Ifs Setting for IFS gap + Rate Setting for transmit rate + Service Setting for service + Length Frame length + TxPreamble Short or Long preamble when using CCK rates + QueIdx - 0-3, according to 802.11e/d4.4 June/2003 + + Return Value: + None + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ======================================================================== +*/ +VOID RTMPWriteTxDescriptor( + IN PRTMP_ADAPTER pAd, + IN PTXD_STRUC pTxD, + IN BOOLEAN bWIV, + IN UCHAR QueueSEL) +{ + // + // Always use Long preamble before verifiation short preamble functionality works well. + // Todo: remove the following line if short preamble functionality works + // + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); + + pTxD->WIV = (bWIV) ? 1: 0; + pTxD->QSEL= (QueueSEL); + //RT2860c?? fixed using EDCA queue for test... We doubt Queue1 has problem. 2006-09-26 Jan + //pTxD->QSEL= FIFO_EDCA; + if (pAd->bGenOneHCCA == TRUE) + pTxD->QSEL= FIFO_HCCA; + pTxD->DMADONE = 0; +} Index: b/drivers/staging/rt2860/common/cmm_data_usb.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/cmm_data_usb.c @@ -0,0 +1,968 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* +*/ + +/* + All functions in this file must be USB-depended, or you should out your function + in other files. + +*/ + +#ifdef RTMP_MAC_USB + + +#include "../rt_config.h" + + +/* + We can do copy the frame into pTxContext when match following conditions. + => + => + => +*/ +static inline NDIS_STATUS RtmpUSBCanDoWrite( + IN RTMP_ADAPTER *pAd, + IN UCHAR QueIdx, + IN HT_TX_CONTEXT *pHTTXContext) +{ + NDIS_STATUS canWrite = NDIS_STATUS_RESOURCES; + + if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition) + { + DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n")); + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); + } + else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE)) + { + DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n")); + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); + } + else if (pHTTXContext->bCurWriting == TRUE) + { + DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n")); + } + else + { + canWrite = NDIS_STATUS_SUCCESS; + } + + + return canWrite; +} + + +USHORT RtmpUSB_WriteSubTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN BOOLEAN bIsLast, + OUT USHORT *FreeNumber) +{ + + // Dummy function. Should be removed in the future. + return 0; + +} + +USHORT RtmpUSB_WriteFragTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR fragNum, + OUT USHORT *FreeNumber) +{ + HT_TX_CONTEXT *pHTTXContext; + USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length. + UINT32 fillOffset; + TXINFO_STRUC *pTxInfo; + TXWI_STRUC *pTxWI; + PUCHAR pWirelessPacket = NULL; + UCHAR QueIdx; + NDIS_STATUS Status; + unsigned long IrqFlags; + UINT32 USBDMApktLen = 0, DMAHdrLen, padding; + BOOLEAN TxQLastRound = FALSE; + + // + // get Tx Ring Resource & Dma Buffer address + // + QueIdx = pTxBlk->QueIdx; + pHTTXContext = &pAd->TxContext[QueIdx]; + + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + pHTTXContext = &pAd->TxContext[QueIdx]; + fillOffset = pHTTXContext->CurWritePosition; + + if(fragNum == 0) + { + // Check if we have enough space for this bulk-out batch. + Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); + if (Status == NDIS_STATUS_SUCCESS) + { + pHTTXContext->bCurWriting = TRUE; + + // Reserve space for 8 bytes padding. + if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) + { + pHTTXContext->ENextBulkOutPosition += 8; + pHTTXContext->CurWritePosition += 8; + fillOffset += 8; + } + pTxBlk->Priv = 0; + pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; + } + else + { + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); + return(Status); + } + } + else + { + // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. + Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE); + if (Status == NDIS_STATUS_SUCCESS) + { + fillOffset += pTxBlk->Priv; + } + else + { + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); + return(Status); + } + } + + NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE); + pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); + pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); + + pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; + + // copy TXWI + WLAN Header + LLC into DMA Header Buffer + //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); + hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; + + // Build our URB for USBD + DMAHdrLen = TXWI_SIZE + hwHdrLen; + USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen; + padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment + USBDMApktLen += padding; + + pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen); + + // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload + RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); + + if (fragNum == pTxBlk->TotalFragNum) + { + pTxInfo->USBDMATxburst = 0; + if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT) + { + pTxInfo->SwUseLastRound = 1; + TxQLastRound = TRUE; + } + } + else + { + pTxInfo->USBDMATxburst = 1; + } + + NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen); + pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); + pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); + + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); + + // Zero the last padding. + pWirelessPacket += pTxBlk->SrcBufLen; + NdisZeroMemory(pWirelessPacket, padding + 8); + + if (fragNum == pTxBlk->TotalFragNum) + { + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + // Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame. + pHTTXContext->CurWritePosition += pTxBlk->Priv; + if (TxQLastRound == TRUE) + pHTTXContext->CurWritePosition = 8; + pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; + + + // Finally, set bCurWriting as FALSE + pHTTXContext->bCurWriting = FALSE; + + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + // succeed and release the skb buffer + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); + } + + + return(Status); + +} + + +USHORT RtmpUSB_WriteSingleTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN BOOLEAN bIsLast, + OUT USHORT *FreeNumber) +{ + HT_TX_CONTEXT *pHTTXContext; + USHORT hwHdrLen; + UINT32 fillOffset; + TXINFO_STRUC *pTxInfo; + TXWI_STRUC *pTxWI; + PUCHAR pWirelessPacket; + UCHAR QueIdx; + unsigned long IrqFlags; + NDIS_STATUS Status; + UINT32 USBDMApktLen = 0, DMAHdrLen, padding; + BOOLEAN bTxQLastRound = FALSE; + + // For USB, didn't need PCI_MAP_SINGLE() + //SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE); + + + // + // get Tx Ring Resource & Dma Buffer address + // + QueIdx = pTxBlk->QueIdx; + + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + pHTTXContext = &pAd->TxContext[QueIdx]; + fillOffset = pHTTXContext->CurWritePosition; + + + + // Check ring full. + Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); + if(Status == NDIS_STATUS_SUCCESS) + { + pHTTXContext->bCurWriting = TRUE; + + pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); + pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); + + // Reserve space for 8 bytes padding. + if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) + { + pHTTXContext->ENextBulkOutPosition += 8; + pHTTXContext->CurWritePosition += 8; + fillOffset += 8; + } + pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; + + pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; + + // copy TXWI + WLAN Header + LLC into DMA Header Buffer + //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); + hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; + + // Build our URB for USBD + DMAHdrLen = TXWI_SIZE + hwHdrLen; + USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen; + padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment + USBDMApktLen += padding; + + pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen); + + // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload + RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); + + if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT) + { + pTxInfo->SwUseLastRound = 1; + bTxQLastRound = TRUE; + } + NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen); + pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); + + // We unlock it here to prevent the first 8 bytes maybe over-writed issue. + // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext. + // 2. An interrupt break our routine and handle bulk-out complete. + // 3. In the bulk-out compllete, it need to do another bulk-out, + // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, + // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. + // 4. Interrupt complete. + // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. + // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. + // and the packet will wrong. + pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); + pWirelessPacket += pTxBlk->SrcBufLen; + NdisZeroMemory(pWirelessPacket, padding + 8); + + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + pHTTXContext->CurWritePosition += pTxBlk->Priv; + if (bTxQLastRound) + pHTTXContext->CurWritePosition = 8; + pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; + + pHTTXContext->bCurWriting = FALSE; + } + + + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + + // succeed and release the skb buffer + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); + + return(Status); + +} + + +USHORT RtmpUSB_WriteMultiTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR frameNum, + OUT USHORT *FreeNumber) +{ + HT_TX_CONTEXT *pHTTXContext; + USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length. + UINT32 fillOffset; + TXINFO_STRUC *pTxInfo; + TXWI_STRUC *pTxWI; + PUCHAR pWirelessPacket = NULL; + UCHAR QueIdx; + NDIS_STATUS Status; + unsigned long IrqFlags; + //UINT32 USBDMApktLen = 0, DMAHdrLen, padding; + + // + // get Tx Ring Resource & Dma Buffer address + // + QueIdx = pTxBlk->QueIdx; + pHTTXContext = &pAd->TxContext[QueIdx]; + + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + if(frameNum == 0) + { + // Check if we have enough space for this bulk-out batch. + Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); + if (Status == NDIS_STATUS_SUCCESS) + { + pHTTXContext->bCurWriting = TRUE; + + pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); + pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); + + + // Reserve space for 8 bytes padding. + if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) + { + + pHTTXContext->CurWritePosition += 8; + pHTTXContext->ENextBulkOutPosition += 8; + } + fillOffset = pHTTXContext->CurWritePosition; + pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; + + pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; + + // + // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer + // + if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) + //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; + hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD; + else if (pTxBlk->TxFrameType == TX_RALINK_FRAME) + //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; + hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD; + else + //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); + hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; + + // Update the pTxBlk->Priv. + pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen; + + // pTxInfo->USBDMApktLen now just a temp value and will to correct latter. + RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); + + // Copy it. + NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv); + pHTTXContext->CurWriteRealPos += pTxBlk->Priv; + pWirelessPacket += pTxBlk->Priv; + } + } + else + { // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. + + Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE); + if (Status == NDIS_STATUS_SUCCESS) + { + fillOffset = (pHTTXContext->CurWritePosition + pTxBlk->Priv); + pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; + + //hwHdrLen = pTxBlk->MpduHeaderLen; + NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen); + pWirelessPacket += (pTxBlk->MpduHeaderLen); + pTxBlk->Priv += pTxBlk->MpduHeaderLen; + } + else + { // It should not happened now unless we are going to shutdown. + DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n")); + Status = NDIS_STATUS_FAILURE; + } + } + + + // We unlock it here to prevent the first 8 bytes maybe over-write issue. + // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext. + // 2. An interrupt break our routine and handle bulk-out complete. + // 3. In the bulk-out compllete, it need to do another bulk-out, + // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, + // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. + // 4. Interrupt complete. + // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. + // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. + // and the packet will wrong. + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition)); + goto done; + } + + // Copy the frame content into DMA buffer and update the pTxBlk->Priv + NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); + pWirelessPacket += pTxBlk->SrcBufLen; + pTxBlk->Priv += pTxBlk->SrcBufLen; + +done: + // Release the skb buffer here + RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); + + return(Status); + +} + + +VOID RtmpUSB_FinalWriteTxResource( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN USHORT totalMPDUSize, + IN USHORT TxIdx) +{ + UCHAR QueIdx; + HT_TX_CONTEXT *pHTTXContext; + UINT32 fillOffset; + TXINFO_STRUC *pTxInfo; + TXWI_STRUC *pTxWI; + UINT32 USBDMApktLen, padding; + unsigned long IrqFlags; + PUCHAR pWirelessPacket; + + QueIdx = pTxBlk->QueIdx; + pHTTXContext = &pAd->TxContext[QueIdx]; + + RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + + if (pHTTXContext->bCurWriting == TRUE) + { + fillOffset = pHTTXContext->CurWritePosition; + if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition)) + && (pHTTXContext->bCopySavePad == TRUE)) + pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]); + else + pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]); + + // + // Update TxInfo->USBDMApktLen , + // the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding + // + pTxInfo = (PTXINFO_STRUC)(pWirelessPacket); + + // Calculate the bulk-out padding + USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE; + padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment + USBDMApktLen += padding; + + pTxInfo->USBDMATxPktLen = USBDMApktLen; + + // + // Update TXWI->MPDUtotalByteCount , + // the length = 802.11 header + payload_of_all_batch_frames + pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE); + pTxWI->MPDUtotalByteCount = totalMPDUSize; + + // + // Update the pHTTXContext->CurWritePosition + // + pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen); + if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT) + { // Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame. + pHTTXContext->CurWritePosition = 8; + pTxInfo->SwUseLastRound = 1; + } + pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; + + + // + // Zero the last padding. + // + pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]); + NdisZeroMemory(pWirelessPacket, padding + 8); + + // Finally, set bCurWriting as FALSE + pHTTXContext->bCurWriting = FALSE; + + } + else + { // It should not happened now unless we are going to shutdown. + DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n")); + } + + RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); + +} + + +VOID RtmpUSBDataLastTxIdx( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN USHORT TxIdx) +{ + // DO nothing for USB. +} + + +/* + When can do bulk-out: + 1. TxSwFreeIdx < TX_RING_SIZE; + It means has at least one Ring entity is ready for bulk-out, kick it out. + 2. If TxSwFreeIdx == TX_RING_SIZE + Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out. + +*/ +VOID RtmpUSBDataKickOut( + IN PRTMP_ADAPTER pAd, + IN TX_BLK *pTxBlk, + IN UCHAR QueIdx) +{ + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); + RTUSBKickBulkOut(pAd); + +} + + +/* + Must be run in Interrupt context + This function handle RT2870 specific TxDesc and cpu index update and kick the packet out. + */ +int RtmpUSBMgmtKickOut( + IN RTMP_ADAPTER *pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket, + IN PUCHAR pSrcBufVA, + IN UINT SrcBufLen) +{ + PTXINFO_STRUC pTxInfo; + ULONG BulkOutSize; + UCHAR padLen; + PUCHAR pDest; + ULONG SwIdx = pAd->MgmtRing.TxCpuIdx; + PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa; + unsigned long IrqFlags; + + + pTxInfo = (PTXINFO_STRUC)(pSrcBufVA); + + // Build our URB for USBD + BulkOutSize = SrcBufLen; + BulkOutSize = (BulkOutSize + 3) & (~3); + RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); + + BulkOutSize += 4; // Always add 4 extra bytes at every packet. + + // If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. + if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0) + BulkOutSize += 4; + + padLen = BulkOutSize - SrcBufLen; + ASSERT((padLen <= RTMP_PKT_TAIL_PADDING)); + + // Now memzero all extra padding bytes. + pDest = (PUCHAR)(pSrcBufVA + SrcBufLen); + skb_put(GET_OS_PKT_TYPE(pPacket), padLen); + NdisZeroMemory(pDest, padLen); + + RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); + + pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket; + pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket)); + + // Length in TxInfo should be 8 less than bulkout size. + pMLMEContext->BulkOutSize = BulkOutSize; + pMLMEContext->InUse = TRUE; + pMLMEContext->bWaitingBulkOut = TRUE; + + + //for debug + //hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); + + //pAd->RalinkCounters.KickTxCount++; + //pAd->RalinkCounters.OneSecTxDoneCount++; + + //if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) + // needKickOut = TRUE; + + // Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX + pAd->MgmtRing.TxSwFreeIdx--; + INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE); + + RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); + //if (needKickOut) + RTUSBKickBulkOut(pAd); + + return 0; +} + + +VOID RtmpUSBNullFrameKickOut( + IN RTMP_ADAPTER *pAd, + IN UCHAR QueIdx, + IN UCHAR *pNullFrame, + IN UINT32 frameLen) +{ + if (pAd->NullContext.InUse == FALSE) + { + PTX_CONTEXT pNullContext; + PTXINFO_STRUC pTxInfo; + PTXWI_STRUC pTxWI; + PUCHAR pWirelessPkt; + + pNullContext = &(pAd->NullContext); + + // Set the in use bit + pNullContext->InUse = TRUE; + pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0]; + + RTMPZeroMemory(&pWirelessPkt[0], 100); + pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0]; + RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); + pTxInfo->QSEL = FIFO_EDCA; + pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE]; + RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)), + 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit); + + RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11)); + pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4; + + // Fill out frame length information for global Bulk out arbitor + //pNullContext->BulkOutSize = TransferBufferLength; + DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate])); + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); + + // Kick bulk out + RTUSBKickBulkOut(pAd); + } + +} + + +/* +======================================================================== +Routine Description: + Get a received packet. + +Arguments: + pAd device control block + pSaveRxD receive descriptor information + *pbReschedule need reschedule flag + *pRxPending pending received packet flag + +Return Value: + the recieved packet + +Note: +======================================================================== +*/ +PNDIS_PACKET GetPacketFromRxRing( + IN PRTMP_ADAPTER pAd, + OUT PRT28XX_RXD_STRUC pSaveRxD, + OUT BOOLEAN *pbReschedule, + IN OUT UINT32 *pRxPending) +{ + PRX_CONTEXT pRxContext; + PNDIS_PACKET pSkb; + PUCHAR pData; + ULONG ThisFrameLen; + ULONG RxBufferLength; + PRXWI_STRUC pRxWI; + + pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex]; + if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE)) + return NULL; + + RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition; + if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC))) + { + goto label_null; + } + + pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */ + // The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding) + ThisFrameLen = *pData + (*(pData+1)<<8); + if (ThisFrameLen == 0) + { + DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n", + pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset)); + goto label_null; + } + if ((ThisFrameLen&0x3) != 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n", + pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset)); + goto label_null; + } + + if ((ThisFrameLen + 8)> RxBufferLength) // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC)) + { + DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n", + pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition)); + + // error frame. finish this loop + goto label_null; + } + + // skip USB frame length field + pData += RT2870_RXDMALEN_FIELD_SIZE; + pRxWI = (PRXWI_STRUC)pData; + if (pRxWI->MPDUtotalByteCount > ThisFrameLen) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n", + __FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen)); + goto label_null; + } + + // allocate a rx packet + pSkb = dev_alloc_skb(ThisFrameLen); + if (pSkb == NULL) + { + DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__)); + goto label_null; + } + + // copy the rx packet + memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen); + RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0); + RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS); + + // copy RxD + *pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen); + + // update next packet read position. + pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC)) + + return pSkb; + +label_null: + + return NULL; +} + + +/* + ======================================================================== + + Routine Description: + Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound + + Arguments: + pRxD Pointer to the Rx descriptor + + Return Value: + NDIS_STATUS_SUCCESS No err + NDIS_STATUS_FAILURE Error + + Note: + + ======================================================================== +*/ +NDIS_STATUS RTMPCheckRxError( + IN PRTMP_ADAPTER pAd, + IN PHEADER_802_11 pHeader, + IN PRXWI_STRUC pRxWI, + IN PRT28XX_RXD_STRUC pRxINFO) +{ + PCIPHER_KEY pWpaKey; + INT dBm; + + if (pAd->bPromiscuous == TRUE) + return(NDIS_STATUS_SUCCESS); + if(pRxINFO == NULL) + return(NDIS_STATUS_FAILURE); + + // Phy errors & CRC errors + if (pRxINFO->Crc) + { + // Check RSSI for Noise Hist statistic collection. + dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta; + if (dBm <= -87) + pAd->StaCfg.RPIDensity[0] += 1; + else if (dBm <= -82) + pAd->StaCfg.RPIDensity[1] += 1; + else if (dBm <= -77) + pAd->StaCfg.RPIDensity[2] += 1; + else if (dBm <= -72) + pAd->StaCfg.RPIDensity[3] += 1; + else if (dBm <= -67) + pAd->StaCfg.RPIDensity[4] += 1; + else if (dBm <= -62) + pAd->StaCfg.RPIDensity[5] += 1; + else if (dBm <= -57) + pAd->StaCfg.RPIDensity[6] += 1; + else if (dBm > -57) + pAd->StaCfg.RPIDensity[7] += 1; + + return(NDIS_STATUS_FAILURE); + } + + // Add Rx size to channel load counter, we should ignore error counts + pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14); + + // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics + if (pHeader->FC.ToDs) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n")); + return NDIS_STATUS_FAILURE; + } + + // Paul 04-03 for OFDM Rx length issue + if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n")); + return NDIS_STATUS_FAILURE; + } + + // Drop not U2M frames, cant's drop here because we will drop beacon in this case + // I am kind of doubting the U2M bit operation + // if (pRxD->U2M == 0) + // return(NDIS_STATUS_FAILURE); + + // drop decyption fail frame + if (pRxINFO->Decrypted && pRxINFO->CipherErr) + { + + if (((pRxINFO->CipherErr & 1) == 1) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd)) + RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + + if (((pRxINFO->CipherErr & 2) == 2) && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd)) + RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + // + // MIC Error + // + if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss) + { + pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex]; + RTMPReportMicError(pAd, pWpaKey); + DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n")); + } + + if (pRxINFO->Decrypted && + (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) && + (pHeader->Sequence == pAd->FragFrame.Sequence)) + { + // + // Acceptable since the First FragFrame no CipherErr problem. + // + return(NDIS_STATUS_SUCCESS); + } + + return(NDIS_STATUS_FAILURE); + } + + return(NDIS_STATUS_SUCCESS); +} + +VOID RtmpUsbStaAsicForceWakeupTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; + + + if (pAd && pAd->Mlme.AutoWakeupTimerRunning) + { + AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); + + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); + pAd->Mlme.AutoWakeupTimerRunning = FALSE; + } +} + +VOID RT28xxUsbStaAsicForceWakeup( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bFromTx) +{ + BOOLEAN Canceled; + + if (pAd->Mlme.AutoWakeupTimerRunning) + RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Canceled); + + AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); + + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); +} + +VOID RT28xxUsbStaAsicSleepThenAutoWakeup( + IN PRTMP_ADAPTER pAd, + IN USHORT TbttNumToNextWakeUp) +{ + + + // we have decided to SLEEP, so at least do it for a BEACON period. + if (TbttNumToNextWakeUp == 0) + TbttNumToNextWakeUp = 1; + + RTMPSetTimer(&pAd->Mlme.AutoWakeupTimer, AUTO_WAKEUP_TIMEOUT); + pAd->Mlme.AutoWakeupTimerRunning = TRUE; + + AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); // send POWER-SAVE command to MCU. Timeout 40us. + + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE); + +} + +#endif // RTMP_MAC_USB // Index: b/drivers/staging/rt2860/common/cmm_info.c =================================================================== --- a/drivers/staging/rt2860/common/cmm_info.c +++ b/drivers/staging/rt2860/common/cmm_info.c @@ -23,153 +23,155 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * ************************************************************************* -*/ + */ #include "../rt_config.h" + INT Show_SSID_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_WirelessMode_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_TxBurst_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_TxPreamble_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_TxPower_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_Channel_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_BGProtection_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_RTSThreshold_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_FragThreshold_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_HtBw_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_HtMcs_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_HtGi_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_HtOpMode_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_HtExtcha_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_HtMpduDensity_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_HtBaWinSize_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_HtRdg_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_HtAmsdu_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_HtAutoBa_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_CountryRegion_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_CountryRegionABand_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_CountryCode_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); #ifdef AGGREGATION_SUPPORT INT Show_PktAggregate_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); #endif // AGGREGATION_SUPPORT // #ifdef WMM_SUPPORT INT Show_WmmCapable_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); #endif // WMM_SUPPORT // INT Show_IEEE80211H_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_NetworkType_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); + INT Show_AuthMode_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_EncrypType_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_DefaultKeyID_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_Key1_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_Key2_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_Key3_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_Key4_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); INT Show_WPAPSK_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf); + OUT PSTRING pBuf); static struct { - CHAR *name; - INT (*show_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg); + PSTRING name; + INT (*show_proc)(PRTMP_ADAPTER pAdapter, PSTRING arg); } *PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC, RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC[] = { {"SSID", Show_SSID_Proc}, {"WirelessMode", Show_WirelessMode_Proc}, @@ -223,8 +225,9 @@ static struct { */ INT Set_DriverVersion_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { + DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", STA_DRIVER_VERSION)); return TRUE; @@ -241,32 +244,14 @@ INT Set_DriverVersion_Proc( */ INT Set_CountryRegion_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { - ULONG region; + int retval; - region = simple_strtol(arg, 0, 10); - // Country can be set only when EEPROM not programmed - if (pAd->CommonCfg.CountryRegion & 0x80) - { - DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameter of CountryRegion in eeprom is programmed \n")); + retval = RT_CfgSetCountryRegion(pAd, arg, BAND_24G); + if (retval == FALSE) return FALSE; - } - - if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND)) - { - pAd->CommonCfg.CountryRegion = (UCHAR) region; - } - else if (region == REGION_31_BG_BAND) - { - pAd->CommonCfg.CountryRegion = (UCHAR) region; - } - else - { - DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameters out of range\n")); - return FALSE; - } // if set country region, driver needs to be reset BuildChannelList(pAd); @@ -287,28 +272,14 @@ INT Set_CountryRegion_Proc( */ INT Set_CountryRegionABand_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { - ULONG region; + int retval; - region = simple_strtol(arg, 0, 10); - // Country can be set only when EEPROM not programmed - if (pAd->CommonCfg.CountryRegionForABand & 0x80) - { - DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameter of CountryRegion in eeprom is programmed \n")); + retval = RT_CfgSetCountryRegion(pAd, arg, BAND_5G); + if (retval == FALSE) return FALSE; - } - - if((region >= 0) && (region <= REGION_MAXIMUM_A_BAND)) - { - pAd->CommonCfg.CountryRegionForABand = (UCHAR) region; - } - else - { - DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameters out of range\n")); - return FALSE; - } // if set country region, driver needs to be reset BuildChannelList(pAd); @@ -328,22 +299,17 @@ INT Set_CountryRegionABand_Proc( */ INT Set_WirelessMode_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { - ULONG WirelessMode; INT success = TRUE; - WirelessMode = simple_strtol(arg, 0, 10); - + success = RT_CfgSetWirelessMode(pAd, arg); + if (success) { - INT MaxPhyMode = PHY_11G; - - MaxPhyMode = PHY_11N_5G; - - if (WirelessMode <= MaxPhyMode) { - RTMPSetPhyMode(pAd, WirelessMode); + LONG WirelessMode = pAd->CommonCfg.PhyMode; + RTMPSetPhyMode(pAd, WirelessMode); if (WirelessMode >= PHY_11ABGN_MIXED) { pAd->CommonCfg.BACapability.field.AutoBA = TRUE; @@ -363,17 +329,10 @@ INT Set_WirelessMode_Proc( AsicEnableIbssSync(pAd); // copy to on-chip memory } } - else - { - success = FALSE; - } - } // it is needed to set SSID to take effect - if (success == TRUE) - { SetCommonHT(pAd); - DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%ld)\n", WirelessMode)); + DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%d)\n", pAd->CommonCfg.PhyMode)); } else { @@ -393,7 +352,7 @@ INT Set_WirelessMode_Proc( */ INT Set_Channel_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { INT success = TRUE; UCHAR Channel; @@ -450,24 +409,18 @@ INT Set_Channel_Proc( */ INT Set_ShortSlot_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { - ULONG ShortSlot; - - ShortSlot = simple_strtol(arg, 0, 10); - - if (ShortSlot == 1) - pAd->CommonCfg.bUseShortSlotTime = TRUE; - else if (ShortSlot == 0) - pAd->CommonCfg.bUseShortSlotTime = FALSE; - else - return FALSE; //Invalid argument + int retval; + retval = RT_CfgSetShortSlot(pAd, arg); + if (retval == TRUE) DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime)); - return TRUE; + return retval; } + /* ========================================================================== Description: @@ -478,12 +431,12 @@ INT Set_ShortSlot_Proc( */ INT Set_TxPower_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { - ULONG TxPower; + LONG TxPower; INT success = FALSE; - TxPower = (ULONG) simple_strtol(arg, 0, 10); + TxPower = simple_strtol(arg, 0, 10); if (TxPower <= 100) { { @@ -510,7 +463,7 @@ INT Set_TxPower_Proc( */ INT Set_BGProtection_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { switch (simple_strtol(arg, 0, 10)) { @@ -543,7 +496,7 @@ INT Set_BGProtection_Proc( */ INT Set_TxPreamble_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { RT_802_11_PREAMBLE Preamble; @@ -584,7 +537,7 @@ INT Set_TxPreamble_Proc( */ INT Set_RTSThreshold_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { NDIS_802_11_RTS_THRESHOLD RtsThresh; @@ -612,7 +565,7 @@ INT Set_RTSThreshold_Proc( */ INT Set_FragThreshold_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh; @@ -656,9 +609,9 @@ INT Set_FragThreshold_Proc( */ INT Set_TxBurst_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { - ULONG TxBurst; + LONG TxBurst; TxBurst = simple_strtol(arg, 0, 10); if (TxBurst == 1) @@ -684,9 +637,9 @@ INT Set_TxBurst_Proc( */ INT Set_PktAggregate_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { - ULONG aggre; + LONG aggre; aggre = simple_strtol(arg, 0, 10); @@ -715,9 +668,9 @@ INT Set_PktAggregate_Proc( */ INT Set_IEEE80211H_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { - ULONG ieee80211h; + LONG ieee80211h; ieee80211h = simple_strtol(arg, 0, 10); @@ -745,7 +698,7 @@ INT Set_IEEE80211H_Proc( */ INT Set_Debug_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Debug_Proc *******************\n")); @@ -760,10 +713,11 @@ INT Set_Debug_Proc( INT Show_DescInfo_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { -#ifdef RT2860 +#ifdef RTMP_MAC_PCI INT i, QueIdx=0; +// ULONG RegValue; PRT28XX_RXD_STRUC pRxD; PTXD_STRUC pTxD; PRTMP_TX_RING pTxRing = &pAd->TxRing[QueIdx]; @@ -773,27 +727,28 @@ INT Show_DescInfo_Proc( for(i=0;iCell[i].AllocVa; - printk("Desc #%d\n",i); - hex_dump("Tx Descriptor", (char *)pTxD, 16); - printk("pTxD->DMADONE = %x\n", pTxD->DMADONE); + DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i)); + hex_dump("Tx Descriptor", (PUCHAR)pTxD, 16); + DBGPRINT(RT_DEBUG_OFF, ("pTxD->DMADONE = %x\n", pTxD->DMADONE)); } - printk("---------------------------------------------------\n"); + DBGPRINT(RT_DEBUG_OFF, ("---------------------------------------------------\n")); for(i=0;iCell[i].AllocVa; - printk("Desc #%d\n",i); - hex_dump("Mgmt Descriptor", (char *)pTxD, 16); - printk("pMgmt->DMADONE = %x\n", pTxD->DMADONE); + DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i)); + hex_dump("Mgmt Descriptor", (PUCHAR)pTxD, 16); + DBGPRINT(RT_DEBUG_OFF, ("pMgmt->DMADONE = %x\n", pTxD->DMADONE)); } - printk("---------------------------------------------------\n"); + DBGPRINT(RT_DEBUG_OFF, ("---------------------------------------------------\n")); for(i=0;iCell[i].AllocVa; - printk("Desc #%d\n",i); - hex_dump("Rx Descriptor", (char *)pRxD, 16); - printk("pRxD->DDONE = %x\n", pRxD->DDONE); + DBGPRINT(RT_DEBUG_OFF, ("Desc #%d\n",i)); + hex_dump("Rx Descriptor", (PUCHAR)pRxD, 16); + DBGPRINT(RT_DEBUG_OFF, ("pRxD->DDONE = %x\n", pRxD->DDONE)); } -#endif /* RT2860 */ +#endif // RTMP_MAC_PCI // + return TRUE; } @@ -812,8 +767,11 @@ INT Show_DescInfo_Proc( */ INT Set_ResetStatCounter_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { + //UCHAR i; + //MAC_TABLE_ENTRY *pEntry; + DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n")); // add the most up-to-date h/w raw counters into software counters @@ -823,9 +781,33 @@ INT Set_ResetStatCounter_Proc( NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3)); NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK)); + // Reset HotSpot counter + + return TRUE; } +/* + ======================================================================== + + Routine Description: + Add WPA key process. + In Adhoc WPANONE, bPairwise = 0; KeyIdx = 0; + + Arguments: + pAd Pointer to our adapter + pBuf Pointer to the where the key stored + + Return Value: + NDIS_SUCCESS Add key successfully + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ + BOOLEAN RTMPCheckStrPrintAble( IN CHAR *pInPutStr, IN UCHAR strLen) @@ -1099,7 +1081,7 @@ VOID RTMPWPARemoveAllKeys( UCHAR i; DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus)); - + RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); // For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after // Link up. And it will be replaced if user changed it. if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) @@ -1121,9 +1103,33 @@ VOID RTMPWPARemoveAllKeys( AsicRemoveSharedKeyEntry(pAd, BSS0, i); } - + RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); } + +/* + ======================================================================== + + Routine Description: + As STA's BSSID is a WC too, it uses shared key table. + This function write correct unicast TX key to ASIC WCID. + And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey. + Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key) + Caller guarantee WEP calls this function when set Txkey, default key index=0~3. + + Arguments: + pAd Pointer to our adapter + pKey Pointer to the where the key stored + + Return Value: + NDIS_SUCCESS Add key successfully + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ /* ======================================================================== Routine Description: @@ -1146,6 +1152,11 @@ VOID RTMPSetPhyMode( INT i; // the selected phymode must be supported by the RF IC encoded in E2PROM + // if no change, do nothing + /* bug fix + if (pAd->CommonCfg.PhyMode == phymode) + return; + */ pAd->CommonCfg.PhyMode = (UCHAR)phymode; DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel)); @@ -1465,7 +1476,10 @@ VOID RTMPSetHT( } AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); + { RTMPSetIndividualHT(pAd, 0); + } + } /* @@ -1656,12 +1670,8 @@ VOID RTMPAddWcidAttributeEntry( // 1. In ADHOC mode, the AID is wcid number. And NO mesh link exists. // 2. In Infra mode, the AID:1 MUST be wcid of infra STA. // the AID:2~ assign to mesh link entry. - if (pEntry && ADHOC_ON(pAd)) + if (pEntry) Wcid = pEntry->Aid; - else if (pEntry && INFRA_ON(pAd)) - { - Wcid = BSSID_WCID; - } else Wcid = MCAST_WCID; } @@ -1696,12 +1706,12 @@ VOID RTMPAddWcidAttributeEntry( } // For key index and ext IV bit, so only need to update the position(offset+3). -#ifdef RT2860 +#ifdef RTMP_MAC_PCI RTMP_IO_WRITE8(pAd, offset+3, IVEIV); -#endif -#ifdef RT2870 +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV); -#endif // RT2870 // +#endif // RTMP_MAC_USB // DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg])); DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri)); @@ -1722,7 +1732,7 @@ Arguments: Note: ========================================================================== */ -CHAR *GetEncryptType(CHAR enc) +PSTRING GetEncryptType(CHAR enc) { if(enc == Ndis802_11WEPDisabled) return "NONE"; @@ -1738,7 +1748,7 @@ CHAR *GetEncryptType(CHAR enc) return "UNKNOW"; } -CHAR *GetAuthMode(CHAR auth) +PSTRING GetAuthMode(CHAR auth) { if(auth == Ndis802_11AuthModeOpen) return "OPEN"; @@ -1782,71 +1792,133 @@ CHAR *GetAuthMode(CHAR auth) 3.) UI needs to prepare at least 4096bytes to get the results ========================================================================== */ -#define LINE_LEN (4+33+20+8+10+9+7+3) // Channel+SSID+Bssid+WepStatus+AuthMode+Signal+WiressMode+NetworkType -VOID RTMPIoctlGetSiteSurvey( - IN PRTMP_ADAPTER pAdapter, - IN struct iwreq *wrq) +#define LINE_LEN (4+33+20+23+9+7+7+3) // Channel+SSID+Bssid+Security+Signal+WiressMode+ExtCh+NetworkType +VOID RTMPCommSiteSurveyData( + IN PSTRING msg, + IN PBSS_ENTRY pBss) { - CHAR *msg; - INT i=0; - INT WaitCnt; - INT Status=0; - CHAR Ssid[MAX_LEN_OF_SSID +1]; - INT Rssi = 0, max_len = LINE_LEN; + INT Rssi = 0; UINT Rssi_Quality = 0; NDIS_802_11_NETWORK_TYPE wireless_mode; + CHAR Ssid[MAX_LEN_OF_SSID +1]; + STRING SecurityStr[32] = {0}; + NDIS_802_11_ENCRYPTION_STATUS ap_cipher = Ndis802_11EncryptionDisabled; + NDIS_802_11_AUTHENTICATION_MODE ap_auth_mode = Ndis802_11AuthModeOpen; - os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len)); - - if (msg == NULL) - { - DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n")); - return; - } - - memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len ); memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1)); - sprintf(msg,"%s","\n"); - sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-8s%-10s%-9s%-7s%-3s\n", - "Ch", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", " NT"); - - WaitCnt = 0; - pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE; - - while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200)) - OS_WAIT(500); - - for(i=0; iScanTab.BssNr ;i++) - { - if( pAdapter->ScanTab.BssEntry[i].Channel==0) - break; - - if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA) - break; //Channel - sprintf(msg+strlen(msg),"%-4d", pAdapter->ScanTab.BssEntry[i].Channel); + sprintf(msg+strlen(msg),"%-4d", pBss->Channel); //SSID - memcpy(Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen); - Ssid[pAdapter->ScanTab.BssEntry[i].SsidLen] = '\0'; + memcpy(Ssid, pBss->Ssid, pBss->SsidLen); + Ssid[pBss->SsidLen] = '\0'; sprintf(msg+strlen(msg),"%-33s", Ssid); //BSSID sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x ", - pAdapter->ScanTab.BssEntry[i].Bssid[0], - pAdapter->ScanTab.BssEntry[i].Bssid[1], - pAdapter->ScanTab.BssEntry[i].Bssid[2], - pAdapter->ScanTab.BssEntry[i].Bssid[3], - pAdapter->ScanTab.BssEntry[i].Bssid[4], - pAdapter->ScanTab.BssEntry[i].Bssid[5]); - //Encryption Type - sprintf(msg+strlen(msg),"%-8s",GetEncryptType(pAdapter->ScanTab.BssEntry[i].WepStatus)); - //Authentication Mode - if (pAdapter->ScanTab.BssEntry[i].WepStatus == Ndis802_11WEPEnabled) - sprintf(msg+strlen(msg),"%-10s", "UNKNOW"); + pBss->Bssid[0], + pBss->Bssid[1], + pBss->Bssid[2], + pBss->Bssid[3], + pBss->Bssid[4], + pBss->Bssid[5]); + + //Security + if ((Ndis802_11AuthModeWPA <= pBss->AuthMode) && + (pBss->AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK)) + { + if (pBss->AuthModeAux == Ndis802_11AuthModeWPANone) + { + ap_auth_mode = pBss->AuthMode; + if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) + ap_cipher = pBss->WPA.PairCipher; + else + ap_cipher = Ndis802_11Encryption4Enabled; + } + else if (pBss->AuthModeAux == Ndis802_11AuthModeOpen) + { + ap_auth_mode = pBss->AuthMode; + if ((ap_auth_mode == Ndis802_11AuthModeWPA) || + (ap_auth_mode == Ndis802_11AuthModeWPAPSK)) + { + if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) + ap_cipher = pBss->WPA.PairCipher; + else + ap_cipher = Ndis802_11Encryption4Enabled; + } + else if ((ap_auth_mode == Ndis802_11AuthModeWPA2) || + (ap_auth_mode == Ndis802_11AuthModeWPA2PSK)) + { + if (pBss->WPA2.PairCipherAux == Ndis802_11WEPDisabled) + ap_cipher = pBss->WPA2.PairCipher; + else + ap_cipher = Ndis802_11Encryption4Enabled; + } + } + else if ((pBss->AuthMode == Ndis802_11AuthModeWPAPSK) || + (pBss->AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + if ((pBss->AuthModeAux == Ndis802_11AuthModeWPAPSK) || + (pBss->AuthModeAux == Ndis802_11AuthModeWPA2PSK)) + ap_auth_mode = Ndis802_11AuthModeWPA1PSKWPA2PSK; + else + ap_auth_mode = pBss->AuthMode; + + if (pBss->WPA.PairCipher != pBss->WPA2.PairCipher) + ap_cipher = Ndis802_11Encryption4Enabled; + else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) && + (pBss->WPA.PairCipherAux != pBss->WPA2.PairCipherAux)) + ap_cipher = Ndis802_11Encryption4Enabled; + else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) && + (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) && + (pBss->WPA.PairCipherAux != Ndis802_11WEPDisabled)) + ap_cipher = Ndis802_11Encryption4Enabled; + else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) && + (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) && + (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)) + ap_cipher = pBss->WPA.PairCipher; + } + else if ((pBss->AuthMode == Ndis802_11AuthModeWPA) || + (pBss->AuthMode == Ndis802_11AuthModeWPA2)) + { + if ((pBss->AuthModeAux == Ndis802_11AuthModeWPA) || + (pBss->AuthMode == Ndis802_11AuthModeWPA2)) + ap_auth_mode = Ndis802_11AuthModeWPA1WPA2; + else + ap_auth_mode = pBss->AuthMode; + + if (pBss->WPA.PairCipher != pBss->WPA2.PairCipher) + ap_cipher = Ndis802_11Encryption4Enabled; + else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) && + (pBss->WPA.PairCipherAux != pBss->WPA2.PairCipherAux)) + ap_cipher = Ndis802_11Encryption4Enabled; + else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) && + (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) && + (pBss->WPA.PairCipherAux != Ndis802_11WEPDisabled)) + ap_cipher = Ndis802_11Encryption4Enabled; + else if ((pBss->WPA.PairCipher == pBss->WPA2.PairCipher) && + (pBss->WPA.PairCipherAux == pBss->WPA2.PairCipherAux) && + (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)) + ap_cipher = pBss->WPA.PairCipher; + } + + sprintf(SecurityStr, "%s/%s", GetAuthMode((CHAR)ap_auth_mode), GetEncryptType((CHAR)ap_cipher)); + } + else + { + ap_auth_mode = pBss->AuthMode; + ap_cipher = pBss->WepStatus; + if (ap_cipher == Ndis802_11WEPDisabled) + sprintf(SecurityStr, "NONE"); + else if (ap_cipher == Ndis802_11WEPEnabled) + sprintf(SecurityStr, "WEP"); else - sprintf(msg+strlen(msg),"%-10s",GetAuthMode(pAdapter->ScanTab.BssEntry[i].AuthMode)); + sprintf(SecurityStr, "%s/%s", GetAuthMode((CHAR)ap_auth_mode), GetEncryptType((CHAR)ap_cipher)); + } + + sprintf(msg+strlen(msg), "%-23s", SecurityStr); + // Rssi - Rssi = (INT)pAdapter->ScanTab.BssEntry[i].Rssi; + Rssi = (INT)pBss->Rssi; if (Rssi >= -50) Rssi_Quality = 100; else if (Rssi >= -80) // between -50 ~ -80dbm @@ -1857,7 +1929,7 @@ VOID RTMPIoctlGetSiteSurvey( Rssi_Quality = 0; sprintf(msg+strlen(msg),"%-9d", Rssi_Quality); // Wireless Mode - wireless_mode = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]); + wireless_mode = NetworkTypeInUseSanity(pBss); if (wireless_mode == Ndis802_11FH || wireless_mode == Ndis802_11DS) sprintf(msg+strlen(msg),"%-7s", "11b"); @@ -1871,13 +1943,79 @@ VOID RTMPIoctlGetSiteSurvey( sprintf(msg+strlen(msg),"%-7s", "11b/g/n"); else sprintf(msg+strlen(msg),"%-7s", "unknow"); + + // Ext Channel + if (pBss->AddHtInfoLen > 0) + { + if (pBss->AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) + sprintf(msg+strlen(msg),"%-7s", " ABOVE"); + else if (pBss->AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) + sprintf(msg+strlen(msg),"%-7s", " BELOW"); + else + sprintf(msg+strlen(msg),"%-7s", " NONE"); + } + else + { + sprintf(msg+strlen(msg),"%-7s", " NONE"); + } + //Network Type - if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_ADHOC) + if (pBss->BssType == BSS_ADHOC) sprintf(msg+strlen(msg),"%-3s", " Ad"); else sprintf(msg+strlen(msg),"%-3s", " In"); sprintf(msg+strlen(msg),"\n"); + + return; +} + +VOID RTMPIoctlGetSiteSurvey( + IN PRTMP_ADAPTER pAdapter, + IN struct iwreq *wrq) +{ + PSTRING msg; + INT i=0; + INT WaitCnt; + INT Status=0; + INT max_len = LINE_LEN; + PBSS_ENTRY pBss; + + + os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len)); + + if (msg == NULL) + { + DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n")); + return; + } + + memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len ); + sprintf(msg,"%s","\n"); + sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-23s%-9s%-7s%-7s%-3s\n", + "Ch", "SSID", "BSSID", "Security", "Siganl(%)", "W-Mode", " ExtCH"," NT"); + + + + WaitCnt = 0; + pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE; + while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200)) + OS_WAIT(500); + + for(i=0; iScanTab.BssNr ;i++) + { + pBss = &pAdapter->ScanTab.BssEntry[i]; + + if( pBss->Channel==0) + break; + + if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA) + break; + + + RTMPCommSiteSurveyData(msg, pBss); + + } pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE; @@ -1932,7 +2070,12 @@ VOID RTMPIoctlGetMacTable( DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __func__)); } - msg = (CHAR *) kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG); + msg = kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG); + if (msg == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s():Alloc memory failed\n", __func__)); + return; + } memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN ); sprintf(msg,"%s","\n"); sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n", @@ -1967,12 +2110,14 @@ VOID RTMPIoctlGetMacTable( kfree(msg); } + INT Set_BASetup_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { UCHAR mac[6], tid; - char *token, sepValue[] = ":", DASH = '-'; + PSTRING token; + STRING sepValue[] = ":", DASH = '-'; INT i; MAC_TABLE_ENTRY *pEntry; @@ -1981,6 +2126,7 @@ INT Set_BASetup_Proc( =>The six 2 digit hex-decimal number previous are the Mac address, =>The seventh decimal number is the tid value. */ + //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg)); if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format. return FALSE; @@ -1988,7 +2134,7 @@ INT Set_BASetup_Proc( token = strchr(arg, DASH); if ((token != NULL) && (strlen(token)>1)) { - tid = simple_strtol((token+1), 0, 10); + tid = (UCHAR) simple_strtol((token+1), 0, 10); if (tid > 15) return FALSE; @@ -1997,18 +2143,18 @@ INT Set_BASetup_Proc( { if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) return FALSE; - AtoH(token, (PUCHAR)(&mac[i]), 1); + AtoH(token, (&mac[i]), 1); } if(i != 6) return FALSE; - printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", mac[0], mac[1], - mac[2], mac[3], mac[4], mac[5], tid); + DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid)); - pEntry = MacTableLookup(pAd, mac); + pEntry = MacTableLookup(pAd, (PUCHAR) mac); if (pEntry) { - printk("\nSetup BA Session: Tid = %d\n", tid); + DBGPRINT(RT_DEBUG_OFF, ("\nSetup BA Session: Tid = %d\n", tid)); BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE); } @@ -2021,7 +2167,7 @@ INT Set_BASetup_Proc( INT Set_BADecline_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG bBADecline; @@ -2047,13 +2193,15 @@ INT Set_BADecline_Proc( INT Set_BAOriTearDown_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { UCHAR mac[6], tid; - char *token, sepValue[] = ":", DASH = '-'; + PSTRING token; + STRING sepValue[] = ":", DASH = '-'; INT i; MAC_TABLE_ENTRY *pEntry; + //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg)); /* The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d, =>The six 2 digit hex-decimal number previous are the Mac address, @@ -2074,18 +2222,18 @@ INT Set_BAOriTearDown_Proc( { if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) return FALSE; - AtoH(token, (PUCHAR)(&mac[i]), 1); + AtoH(token, (&mac[i]), 1); } if(i != 6) return FALSE; - printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1], - mac[2], mac[3], mac[4], mac[5], tid); + DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid)); - pEntry = MacTableLookup(pAd, mac); + pEntry = MacTableLookup(pAd, (PUCHAR) mac); if (pEntry) { - printk("\nTear down Ori BA Session: Tid = %d\n", tid); + DBGPRINT(RT_DEBUG_OFF, ("\nTear down Ori BA Session: Tid = %d\n", tid)); BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE); } @@ -2098,14 +2246,15 @@ INT Set_BAOriTearDown_Proc( INT Set_BARecTearDown_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { UCHAR mac[6], tid; - char *token, sepValue[] = ":", DASH = '-'; + PSTRING token; + STRING sepValue[] = ":", DASH = '-'; INT i; MAC_TABLE_ENTRY *pEntry; - //printk("\n%s\n", arg); + //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg)); /* The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d, =>The six 2 digit hex-decimal number previous are the Mac address, @@ -2126,18 +2275,18 @@ INT Set_BARecTearDown_Proc( { if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) return FALSE; - AtoH(token, (PUCHAR)(&mac[i]), 1); + AtoH(token, (&mac[i]), 1); } if(i != 6) return FALSE; - printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1], - mac[2], mac[3], mac[4], mac[5], tid); + DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], tid)); - pEntry = MacTableLookup(pAd, mac); + pEntry = MacTableLookup(pAd, (PUCHAR) mac); if (pEntry) { - printk("\nTear down Rec BA Session: Tid = %d\n", tid); + DBGPRINT(RT_DEBUG_OFF, ("\nTear down Rec BA Session: Tid = %d\n", tid)); BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE); } @@ -2150,7 +2299,7 @@ INT Set_BARecTearDown_Proc( INT Set_HtBw_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG HtBw; @@ -2171,7 +2320,7 @@ INT Set_HtBw_Proc( INT Set_HtMcs_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG HtMcs, Mcs_tmp; BOOLEAN bAutoRate = FALSE; @@ -2225,7 +2374,7 @@ INT Set_HtMcs_Proc( INT Set_HtGi_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG HtGi; @@ -2248,7 +2397,7 @@ INT Set_HtGi_Proc( INT Set_HtTxBASize_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { UCHAR Size; @@ -2264,10 +2413,32 @@ INT Set_HtTxBASize_Proc( return TRUE; } +INT Set_HtDisallowTKIP_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG Value; + + Value = simple_strtol(arg, 0, 10); + + if (Value == 1) + { + pAd->CommonCfg.HT_DisallowTKIP = TRUE; + } + else + { + pAd->CommonCfg.HT_DisallowTKIP = FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("Set_HtDisallowTKIP_Proc ::%s\n", + (pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "enabled" : "disabled")); + + return TRUE; +} INT Set_HtOpMode_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2291,7 +2462,7 @@ INT Set_HtOpMode_Proc( INT Set_HtStbc_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2314,7 +2485,7 @@ INT Set_HtStbc_Proc( INT Set_HtHtc_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2334,7 +2505,7 @@ INT Set_HtHtc_Proc( INT Set_HtExtcha_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2357,7 +2528,7 @@ INT Set_HtExtcha_Proc( INT Set_HtMpduDensity_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2377,7 +2548,7 @@ INT Set_HtMpduDensity_Proc( INT Set_HtBaWinSize_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2404,7 +2575,7 @@ INT Set_HtBaWinSize_Proc( INT Set_HtRdg_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2429,7 +2600,7 @@ INT Set_HtRdg_Proc( INT Set_HtLinkAdapt_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2451,7 +2622,7 @@ INT Set_HtLinkAdapt_Proc( INT Set_HtAmsdu_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2472,7 +2643,7 @@ INT Set_HtAmsdu_Proc( INT Set_HtAutoBa_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2503,7 +2674,7 @@ INT Set_HtAutoBa_Proc( INT Set_HtProtect_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2522,14 +2693,15 @@ INT Set_HtProtect_Proc( INT Set_SendPSMPAction_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { UCHAR mac[6], mode; - char *token, sepValue[] = ":", DASH = '-'; + PSTRING token; + STRING sepValue[] = ":", DASH = '-'; INT i; MAC_TABLE_ENTRY *pEntry; - //printk("\n%s\n", arg); + //DBGPRINT(RT_DEBUG_TRACE,("\n%s\n", arg)); /* The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d, =>The six 2 digit hex-decimal number previous are the Mac address, @@ -2550,18 +2722,18 @@ INT Set_SendPSMPAction_Proc( { if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) return FALSE; - AtoH(token, (PUCHAR)(&mac[i]), 1); + AtoH(token, (&mac[i]), 1); } if(i != 6) return FALSE; - printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1], - mac[2], mac[3], mac[4], mac[5], mode); + DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mode)); pEntry = MacTableLookup(pAd, mac); if (pEntry) { - printk("\nSendPSMPAction MIPS mode = %d\n", mode); + DBGPRINT(RT_DEBUG_OFF, ("\nSendPSMPAction MIPS mode = %d\n", mode)); SendPSMPAction(pAd, pEntry->Aid, mode); } @@ -2575,7 +2747,7 @@ INT Set_SendPSMPAction_Proc( INT Set_HtMIMOPSmode_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2596,7 +2768,7 @@ INT Set_HtMIMOPSmode_Proc( INT Set_ForceShortGI_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2619,7 +2791,7 @@ INT Set_ForceShortGI_Proc( INT Set_ForceGF_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2640,7 +2812,7 @@ INT Set_ForceGF_Proc( INT Set_HtMimoPs_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { ULONG Value; @@ -2681,7 +2853,7 @@ INT SetCommonHT( INT Set_FixedTxMode_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { UCHAR fix_tx_mode = FIXED_TXMODE_HT; @@ -2701,8 +2873,57 @@ INT Set_FixedTxMode_Proc( return TRUE; } +#if defined(RT305x)||defined(RT3070) +INT Set_HiPower_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + pAdapter->CommonCfg.HighPowerPatchDisabled = !(simple_strtol(arg, 0, 10)); + + if (pAdapter->CommonCfg.HighPowerPatchDisabled != 0) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R82, 0x62); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R67, 0x20); +#ifdef RT3070 + if ((IS_RT3070(pAdapter) && ((pAdapter->MACVersion & 0xffff) < 0x0201))) +#endif // RT3070 // + RT30xxWriteRFRegister(pAdapter, RF_R27, 0x23); + } + return TRUE; +} +#endif + +INT Set_LongRetryLimit_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + TX_RTY_CFG_STRUC tx_rty_cfg; + UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10); + + RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word); + tx_rty_cfg.field.LongRtyLimit = LongRetryLimit; + RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word); + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word)); + return TRUE; +} + +INT Set_ShortRetryLimit_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg) +{ + TX_RTY_CFG_STRUC tx_rty_cfg; + UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10); + + RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word); + tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit; + RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word); + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word)); + return TRUE; +} + + ///////////////////////////////////////////////////////////////////////// -PCHAR RTMPGetRalinkAuthModeStr( +PSTRING RTMPGetRalinkAuthModeStr( IN NDIS_802_11_AUTHENTICATION_MODE authMode) { switch(authMode) @@ -2730,14 +2951,11 @@ PCHAR RTMPGetRalinkAuthModeStr( } } -PCHAR RTMPGetRalinkEncryModeStr( +PSTRING RTMPGetRalinkEncryModeStr( IN USHORT encryMode) { switch(encryMode) { -#if defined(RT2860) || defined(RT30xx) - default: -#endif case Ndis802_11WEPDisabled: return "NONE"; case Ndis802_11WEPEnabled: @@ -2748,17 +2966,15 @@ PCHAR RTMPGetRalinkEncryModeStr( return "AES"; case Ndis802_11Encryption4Enabled: return "TKIPAES"; -#if !defined(RT2860) && !defined(RT30xx) default: return "UNKNOW"; -#endif } } INT RTMPShowCfgValue( IN PRTMP_ADAPTER pAd, - IN PUCHAR pName, - IN PUCHAR pBuf) + IN PSTRING pName, + IN PSTRING pBuf) { INT Status = 0; @@ -2784,7 +3000,7 @@ INT RTMPShowCfgValue( INT Show_SSID_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid); return 0; @@ -2792,7 +3008,7 @@ INT Show_SSID_Proc( INT Show_WirelessMode_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { switch(pAd->CommonCfg.PhyMode) { @@ -2842,7 +3058,7 @@ INT Show_WirelessMode_Proc( INT Show_TxBurst_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE"); return 0; @@ -2850,7 +3066,7 @@ INT Show_TxBurst_Proc( INT Show_TxPreamble_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { switch(pAd->CommonCfg.TxPreamble) { @@ -2873,7 +3089,7 @@ INT Show_TxPreamble_Proc( INT Show_TxPower_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage); return 0; @@ -2881,7 +3097,7 @@ INT Show_TxPower_Proc( INT Show_Channel_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel); return 0; @@ -2889,7 +3105,7 @@ INT Show_Channel_Proc( INT Show_BGProtection_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { switch(pAd->CommonCfg.UseBGProtection) { @@ -2911,7 +3127,7 @@ INT Show_BGProtection_Proc( INT Show_RTSThreshold_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold); return 0; @@ -2919,7 +3135,7 @@ INT Show_RTSThreshold_Proc( INT Show_FragThreshold_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold); return 0; @@ -2927,7 +3143,7 @@ INT Show_FragThreshold_Proc( INT Show_HtBw_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) { @@ -2942,7 +3158,7 @@ INT Show_HtBw_Proc( INT Show_HtMcs_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS); return 0; @@ -2950,7 +3166,7 @@ INT Show_HtMcs_Proc( INT Show_HtGi_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI) { @@ -2969,7 +3185,7 @@ INT Show_HtGi_Proc( INT Show_HtOpMode_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE) { @@ -2988,7 +3204,7 @@ INT Show_HtOpMode_Proc( INT Show_HtExtcha_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA) { @@ -3008,7 +3224,7 @@ INT Show_HtExtcha_Proc( INT Show_HtMpduDensity_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity); return 0; @@ -3016,7 +3232,7 @@ INT Show_HtMpduDensity_Proc( INT Show_HtBaWinSize_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit); return 0; @@ -3024,7 +3240,7 @@ INT Show_HtBaWinSize_Proc( INT Show_HtRdg_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE"); return 0; @@ -3032,7 +3248,7 @@ INT Show_HtRdg_Proc( INT Show_HtAmsdu_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE"); return 0; @@ -3040,7 +3256,7 @@ INT Show_HtAmsdu_Proc( INT Show_HtAutoBa_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE"); return 0; @@ -3048,7 +3264,7 @@ INT Show_HtAutoBa_Proc( INT Show_CountryRegion_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion); return 0; @@ -3056,7 +3272,7 @@ INT Show_CountryRegion_Proc( INT Show_CountryRegionABand_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand); return 0; @@ -3064,7 +3280,7 @@ INT Show_CountryRegionABand_Proc( INT Show_CountryCode_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode); return 0; @@ -3073,7 +3289,7 @@ INT Show_CountryCode_Proc( #ifdef AGGREGATION_SUPPORT INT Show_PktAggregate_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE"); return 0; @@ -3083,7 +3299,7 @@ INT Show_PktAggregate_Proc( #ifdef WMM_SUPPORT INT Show_WmmCapable_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE"); @@ -3093,7 +3309,7 @@ INT Show_WmmCapable_Proc( INT Show_IEEE80211H_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE"); return 0; @@ -3101,7 +3317,7 @@ INT Show_IEEE80211H_Proc( INT Show_NetworkType_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { switch(pAd->StaCfg.BssType) { @@ -3124,9 +3340,11 @@ INT Show_NetworkType_Proc( return 0; } + + INT Show_AuthMode_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeOpen; @@ -3143,7 +3361,7 @@ INT Show_AuthMode_Proc( INT Show_EncrypType_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { NDIS_802_11_WEP_STATUS WepStatus = Ndis802_11WEPDisabled; @@ -3160,7 +3378,7 @@ INT Show_EncrypType_Proc( INT Show_DefaultKeyID_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { UCHAR DefaultKeyId = 0; @@ -3174,7 +3392,7 @@ INT Show_DefaultKeyID_Proc( INT Show_WepKey_Proc( IN PRTMP_ADAPTER pAd, IN INT KeyIdx, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { UCHAR Key[16] = {0}, KeyLength = 0; INT index = BSS0; @@ -3183,7 +3401,7 @@ INT Show_WepKey_Proc( NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength); //check key string is ASCII or not - if (RTMPCheckStrPrintAble(Key, KeyLength)) + if (RTMPCheckStrPrintAble((PCHAR)Key, KeyLength)) sprintf(pBuf, "\t%s", Key); else { @@ -3197,7 +3415,7 @@ INT Show_WepKey_Proc( INT Show_Key1_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { Show_WepKey_Proc(pAd, 0, pBuf); return 0; @@ -3205,7 +3423,7 @@ INT Show_Key1_Proc( INT Show_Key2_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { Show_WepKey_Proc(pAd, 1, pBuf); return 0; @@ -3213,7 +3431,7 @@ INT Show_Key2_Proc( INT Show_Key3_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { Show_WepKey_Proc(pAd, 2, pBuf); return 0; @@ -3221,7 +3439,7 @@ INT Show_Key3_Proc( INT Show_Key4_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { Show_WepKey_Proc(pAd, 3, pBuf); return 0; @@ -3229,7 +3447,7 @@ INT Show_Key4_Proc( INT Show_WPAPSK_Proc( IN PRTMP_ADAPTER pAd, - OUT PUCHAR pBuf) + OUT PSTRING pBuf) { INT idx; UCHAR PMK[32] = {0}; Index: b/drivers/staging/rt2860/common/cmm_mac_pci.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/cmm_mac_pci.c @@ -0,0 +1,1504 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* +*/ + + +#ifdef RTMP_MAC_PCI +#include "../rt_config.h" + + +/* + ======================================================================== + + Routine Description: + Allocate DMA memory blocks for send, receive + + Arguments: + Adapter Pointer to our adapter + + Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_RESOURCES + + IRQL = PASSIVE_LEVEL + + Note: + + ======================================================================== +*/ +NDIS_STATUS RTMPAllocTxRxRingMemory( + IN PRTMP_ADAPTER pAd) +{ + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + ULONG RingBasePaHigh; + ULONG RingBasePaLow; + PVOID RingBaseVa; + INT index, num; + PTXD_STRUC pTxD; + PRXD_STRUC pRxD; + ULONG ErrorValue = 0; + PRTMP_TX_RING pTxRing; + PRTMP_DMABUF pDmaBuf; + PNDIS_PACKET pPacket; +// PRTMP_REORDERBUF pReorderBuf; + + DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); + do + { + // + // Allocate all ring descriptors, include TxD, RxD, MgmtD. + // Although each size is different, to prevent cacheline and alignment + // issue, I intentional set them all to 64 bytes. + // + for (num=0; numTxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE; + RTMP_AllocateTxDescMemory( + pAd, + num, + pAd->TxDescRing[num].AllocSize, + FALSE, + &pAd->TxDescRing[num].AllocVa, + &pAd->TxDescRing[num].AllocPa); + + if (pAd->TxDescRing[num].AllocVa == NULL) + { + ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; + DBGPRINT_ERR(("Failed to allocate a big buffer\n")); + Status = NDIS_STATUS_RESOURCES; + break; + } + + // Zero init this memory block + NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize); + + // Save PA & VA for further operation + RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa); + RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa); + RingBaseVa = pAd->TxDescRing[num].AllocVa; + + // + // Allocate all 1st TXBuf's memory for this TxRing + // + pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE; + RTMP_AllocateFirstTxBuffer( + pAd, + num, + pAd->TxBufSpace[num].AllocSize, + FALSE, + &pAd->TxBufSpace[num].AllocVa, + &pAd->TxBufSpace[num].AllocPa); + + if (pAd->TxBufSpace[num].AllocVa == NULL) + { + ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; + DBGPRINT_ERR(("Failed to allocate a big buffer\n")); + Status = NDIS_STATUS_RESOURCES; + break; + } + + // Zero init this memory block + NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize); + + // Save PA & VA for further operation + BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa); + BufBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa); + BufBaseVa = pAd->TxBufSpace[num].AllocVa; + + // + // Initialize Tx Ring Descriptor and associated buffer memory + // + pTxRing = &pAd->TxRing[num]; + for (index = 0; index < TX_RING_SIZE; index++) + { + pTxRing->Cell[index].pNdisPacket = NULL; + pTxRing->Cell[index].pNextNdisPacket = NULL; + // Init Tx Ring Size, Va, Pa variables + pTxRing->Cell[index].AllocSize = TXD_SIZE; + pTxRing->Cell[index].AllocVa = RingBaseVa; + RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh); + RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow); + + // Setup Tx Buffer size & address. only 802.11 header will store in this space + pDmaBuf = &pTxRing->Cell[index].DmaBuf; + pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE; + pDmaBuf->AllocVa = BufBaseVa; + RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh); + RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow); + + // link the pre-allocated TxBuf to TXD + pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa; + pTxD->SDPtr0 = BufBasePaLow; + // advance to next ring descriptor address + pTxD->DMADONE = 1; + RingBasePaLow += TXD_SIZE; + RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE; + + // advance to next TxBuf address + BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE; + BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE; + } + DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index)); + } + if (Status == NDIS_STATUS_RESOURCES) + break; + + // + // Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler + // + pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE; + RTMP_AllocateMgmtDescMemory( + pAd, + pAd->MgmtDescRing.AllocSize, + FALSE, + &pAd->MgmtDescRing.AllocVa, + &pAd->MgmtDescRing.AllocPa); + + if (pAd->MgmtDescRing.AllocVa == NULL) + { + ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; + DBGPRINT_ERR(("Failed to allocate a big buffer\n")); + Status = NDIS_STATUS_RESOURCES; + break; + } + + // Zero init this memory block + NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); + + // Save PA & VA for further operation + RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa); + RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa); + RingBaseVa = pAd->MgmtDescRing.AllocVa; + + // + // Initialize MGMT Ring and associated buffer memory + // + for (index = 0; index < MGMT_RING_SIZE; index++) + { + pAd->MgmtRing.Cell[index].pNdisPacket = NULL; + pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL; + // Init MGMT Ring Size, Va, Pa variables + pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE; + pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa; + RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh); + RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow); + + // Offset to next ring descriptor address + RingBasePaLow += TXD_SIZE; + RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE; + + // link the pre-allocated TxBuf to TXD + pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa; + pTxD->DMADONE = 1; + + // no pre-allocated buffer required in MgmtRing for scatter-gather case + } + DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index)); + + // + // Allocate RX ring descriptor's memory except Tx ring which allocated eariler + // + pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE; + RTMP_AllocateRxDescMemory( + pAd, + pAd->RxDescRing.AllocSize, + FALSE, + &pAd->RxDescRing.AllocVa, + &pAd->RxDescRing.AllocPa); + + if (pAd->RxDescRing.AllocVa == NULL) + { + ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; + DBGPRINT_ERR(("Failed to allocate a big buffer\n")); + Status = NDIS_STATUS_RESOURCES; + break; + } + + // Zero init this memory block + NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize); + + + DBGPRINT(RT_DEBUG_OFF, + ("RX DESC %p size = %ld\n", pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize)); + + // Save PA & VA for further operation + RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa); + RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa); + RingBaseVa = pAd->RxDescRing.AllocVa; + + // + // Initialize Rx Ring and associated buffer memory + // + for (index = 0; index < RX_RING_SIZE; index++) + { + // Init RX Ring Size, Va, Pa variables + pAd->RxRing.Cell[index].AllocSize = RXD_SIZE; + pAd->RxRing.Cell[index].AllocVa = RingBaseVa; + RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh); + RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow); + + //NdisZeroMemory(RingBaseVa, RXD_SIZE); + + // Offset to next ring descriptor address + RingBasePaLow += RXD_SIZE; + RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE; + + // Setup Rx associated Buffer size & allocate share memory + pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf; + pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE; + pPacket = RTMP_AllocateRxPacketBuffer( + pAd, + pDmaBuf->AllocSize, + FALSE, + &pDmaBuf->AllocVa, + &pDmaBuf->AllocPa); + + /* keep allocated rx packet */ + pAd->RxRing.Cell[index].pNdisPacket = pPacket; + + // Error handling + if (pDmaBuf->AllocVa == NULL) + { + ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; + DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n")); + Status = NDIS_STATUS_RESOURCES; + break; + } + + // Zero init this memory block + NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize); + + // Write RxD buffer address & allocated buffer length + pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa; + pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa); + pRxD->DDONE = 0; + + } + + DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index)); + + } while (FALSE); + + + NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME)); + pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); + + if (pAd->FragFrame.pFragPacket == NULL) + { + Status = NDIS_STATUS_RESOURCES; + } + + if (Status != NDIS_STATUS_SUCCESS) + { + // Log error inforamtion + NdisWriteErrorLogEntry( + pAd->AdapterHandle, + NDIS_ERROR_CODE_OUT_OF_RESOURCES, + 1, + ErrorValue); + } + + // Following code segment get from original func:NICInitTxRxRingAndBacklogQueue(), now should integrate it to here. + { + DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTxRxRingAndBacklogQueue\n")); + +/* + // Disable DMA. + RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); + GloCfg.word &= 0xff0; + GloCfg.field.EnTXWriteBackDDONE =1; + RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); +*/ + + // Initialize all transmit related software queues + for(index = 0; index < NUM_OF_TX_RING; index++) + { + InitializeQueueHeader(&pAd->TxSwQueue[index]); + // Init TX rings index pointer + pAd->TxRing[index].TxSwFreeIdx = 0; + pAd->TxRing[index].TxCpuIdx = 0; + //RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) , pAd->TxRing[i].TX_CTX_IDX); + } + + // Init RX Ring index pointer + pAd->RxRing.RxSwReadIdx = 0; + pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1; + //RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RX_CRX_IDX0); + + + // init MGMT ring index pointer + pAd->MgmtRing.TxSwFreeIdx = 0; + pAd->MgmtRing.TxCpuIdx = 0; + + pAd->PrivateInfo.TxRingFullCnt = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTxRxRingAndBacklogQueue\n")); + } + + DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); + return Status; +} + + + + +/* + ======================================================================== + + Routine Description: + Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero. + + Arguments: + Adapter Pointer to our adapter + + Return Value: + None + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + Note: + Reset NIC to initial state AS IS system boot up time. + + ======================================================================== +*/ +VOID RTMPRingCleanUp( + IN PRTMP_ADAPTER pAd, + IN UCHAR RingType) +{ + PTXD_STRUC pTxD; + PRXD_STRUC pRxD; + PQUEUE_ENTRY pEntry; + PNDIS_PACKET pPacket; + int i; + PRTMP_TX_RING pTxRing; + unsigned long IrqFlags; + //UINT32 RxSwReadIdx; + + + DBGPRINT(RT_DEBUG_TRACE,("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType, pAd->RalinkCounters.PendingNdisPacketCount)); + switch (RingType) + { + case QID_AC_BK: + case QID_AC_BE: + case QID_AC_VI: + case QID_AC_VO: + case QID_HCCA: + + pTxRing = &pAd->TxRing[RingType]; + + RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); + // We have to clean all descriptors in case some error happened with reset + for (i=0; iCell[i].AllocVa; + + pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNdisPacket; + // release scatter-and-gather NDIS_PACKET + if (pPacket) + { + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + pTxRing->Cell[i].pNdisPacket = NULL; + } + + pPacket = (PNDIS_PACKET) pTxRing->Cell[i].pNextNdisPacket; + // release scatter-and-gather NDIS_PACKET + if (pPacket) + { + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + pTxRing->Cell[i].pNextNdisPacket = NULL; + } + } + + RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10, &pTxRing->TxDmaIdx); + pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx; + pTxRing->TxCpuIdx = pTxRing->TxDmaIdx; + RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10, pTxRing->TxCpuIdx); + + RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); + + RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); + while (pAd->TxSwQueue[RingType].Head != NULL) + { + pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]); + pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + DBGPRINT(RT_DEBUG_TRACE,("Release 1 NDIS packet from s/w backlog queue\n")); + } + RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); + break; + + case QID_MGMT: + // We have to clean all descriptors in case some error happened with reset + NdisAcquireSpinLock(&pAd->MgmtRingLock); + + for (i=0; iMgmtRing.Cell[i].AllocVa; + + pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNdisPacket; + // rlease scatter-and-gather NDIS_PACKET + if (pPacket) + { + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + } + pAd->MgmtRing.Cell[i].pNdisPacket = NULL; + + pPacket = (PNDIS_PACKET) pAd->MgmtRing.Cell[i].pNextNdisPacket; + // release scatter-and-gather NDIS_PACKET + if (pPacket) + { + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + } + pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL; + + } + + RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx); + pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx; + pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx; + RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx); + + NdisReleaseSpinLock(&pAd->MgmtRingLock); + pAd->RalinkCounters.MgmtRingFullCount = 0; + break; + + case QID_RX: + // We have to clean all descriptors in case some error happened with reset + NdisAcquireSpinLock(&pAd->RxRingLock); + + for (i=0; iRxRing.Cell[i].AllocVa; + pRxD->DDONE = 0 ; + } + + RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx); + pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx; + pAd->RxRing.RxCpuIdx = ((pAd->RxRing.RxDmaIdx == 0) ? (RX_RING_SIZE-1) : (pAd->RxRing.RxDmaIdx-1)); + RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx); + + NdisReleaseSpinLock(&pAd->RxRingLock); + break; + + default: + break; + } +} + + +VOID RTMPFreeTxRxRingMemory( + IN PRTMP_ADAPTER pAd) +{ + int index, num , j; + PRTMP_TX_RING pTxRing; + PTXD_STRUC pTxD; + PNDIS_PACKET pPacket; + unsigned int IrqFlags; + + //POS_COOKIE pObj =(POS_COOKIE) pAd->OS_Cookie; + + DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n")); + + // Free TxSwQueue Packet + for (index=0; index irq_lock, IrqFlags); + pQueue = &pAd->TxSwQueue[index]; + while (pQueue->Head) + { + pEntry = RemoveHeadQueue(pQueue); + pPacket = QUEUE_ENTRY_TO_PACKET(pEntry); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); + } + RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); + } + + // Free Tx Ring Packet + for (index=0;index< NUM_OF_TX_RING;index++) + { + pTxRing = &pAd->TxRing[index]; + + for (j=0; j< TX_RING_SIZE; j++) + { + pTxD = (PTXD_STRUC) (pTxRing->Cell[j].AllocVa); + pPacket = pTxRing->Cell[j].pNdisPacket; + + if (pPacket) + { + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0, PCI_DMA_TODEVICE); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); + } + //Always assign pNdisPacket as NULL after clear + pTxRing->Cell[j].pNdisPacket = NULL; + + pPacket = pTxRing->Cell[j].pNextNdisPacket; + + if (pPacket) + { + PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1, PCI_DMA_TODEVICE); + RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS); + } + //Always assign pNextNdisPacket as NULL after clear + pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket = NULL; + + } + } + + for (index = RX_RING_SIZE - 1 ; index >= 0; index--) + { + if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa) && (pAd->RxRing.Cell[index].pNdisPacket)) + { + PCI_UNMAP_SINGLE(pAd, pAd->RxRing.Cell[index].DmaBuf.AllocPa, pAd->RxRing.Cell[index].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE); + RELEASE_NDIS_PACKET(pAd, pAd->RxRing.Cell[index].pNdisPacket, NDIS_STATUS_SUCCESS); + } + } + NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(RTMP_DMACB)); + + if (pAd->RxDescRing.AllocVa) + { + RTMP_FreeDescMemory(pAd, pAd->RxDescRing.AllocSize, pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocPa); + } + NdisZeroMemory(&pAd->RxDescRing, sizeof(RTMP_DMABUF)); + + if (pAd->MgmtDescRing.AllocVa) + { + RTMP_FreeDescMemory(pAd, pAd->MgmtDescRing.AllocSize, pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocPa); + } + NdisZeroMemory(&pAd->MgmtDescRing, sizeof(RTMP_DMABUF)); + + for (num = 0; num < NUM_OF_TX_RING; num++) + { + if (pAd->TxBufSpace[num].AllocVa) + { + RTMP_FreeFirstTxBuffer(pAd, pAd->TxBufSpace[num].AllocSize, FALSE, pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocPa); + } + NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(RTMP_DMABUF)); + + if (pAd->TxDescRing[num].AllocVa) + { + RTMP_FreeDescMemory(pAd, pAd->TxDescRing[num].AllocSize, pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocPa); + } + NdisZeroMemory(&pAd->TxDescRing[num], sizeof(RTMP_DMABUF)); + } + + if (pAd->FragFrame.pFragPacket) + RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS); + + DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n")); +} + + +/*************************************************************************** + * + * register related procedures. + * + **************************************************************************/ +/* +======================================================================== +Routine Description: + Disable DMA. + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT28XXDMADisable( + IN RTMP_ADAPTER *pAd) +{ + WPDMA_GLO_CFG_STRUC GloCfg; + + + RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); + GloCfg.word &= 0xff0; + GloCfg.field.EnTXWriteBackDDONE =1; + RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); +} + + +/* +======================================================================== +Routine Description: + Enable DMA. + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT28XXDMAEnable( + IN RTMP_ADAPTER *pAd) +{ + WPDMA_GLO_CFG_STRUC GloCfg; + int i = 0; + + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4); + do + { + RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); + if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) + break; + + DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n")); + RTMPusecDelay(1000); + i++; + }while ( i <200); + + RTMPusecDelay(50); + + GloCfg.field.EnTXWriteBackDDONE = 1; + GloCfg.field.WPDMABurstSIZE = 2; + GloCfg.field.EnableRxDMA = 1; + GloCfg.field.EnableTxDMA = 1; + + DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word)); + RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); + +} + + +BOOLEAN AsicCheckCommanOk( + IN PRTMP_ADAPTER pAd, + IN UCHAR Command) +{ + UINT32 CmdStatus = 0, CID = 0, i; + UINT32 ThisCIDMask = 0; + + i = 0; + do + { + RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID); + // Find where the command is. Because this is randomly specified by firmware. + if ((CID & CID0MASK) == Command) + { + ThisCIDMask = CID0MASK; + break; + } + else if ((((CID & CID1MASK)>>8) & 0xff) == Command) + { + ThisCIDMask = CID1MASK; + break; + } + else if ((((CID & CID2MASK)>>16) & 0xff) == Command) + { + ThisCIDMask = CID2MASK; + break; + } + else if ((((CID & CID3MASK)>>24) & 0xff) == Command) + { + ThisCIDMask = CID3MASK; + break; + } + + RTMPusecDelay(100); + i++; + }while (i < 200); + + // Get CommandStatus Value + RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus); + + // This command's status is at the same position as command. So AND command position's bitmask to read status. + if (i < 200) + { + // If Status is 1, the comamnd is success. + if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100) + || ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000)) + { + DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus)); + RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff); + RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff); + return TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus)); + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus)); + } + // Clear Command and Status. + RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff); + RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff); + + return FALSE; +} + + +/* +======================================================================== +Routine Description: + Write Beacon buffer to Asic. + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT28xx_UpdateBeaconToAsic( + IN RTMP_ADAPTER *pAd, + IN INT apidx, + IN ULONG FrameLen, + IN ULONG UpdatePos) +{ + ULONG CapInfoPos = 0; + UCHAR *ptr, *ptr_update, *ptr_capinfo; + UINT i; + BOOLEAN bBcnReq = FALSE; + UCHAR bcn_idx = 0; + + + { + DBGPRINT(RT_DEBUG_ERROR, ("%s() : No valid Interface be found.\n", __func__)); + return; + } + + //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) + // || ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) + // || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) + // ) + if (bBcnReq == FALSE) + { + /* when the ra interface is down, do not send its beacon frame */ + /* clear all zero */ + for(i=0; iBeaconOffset[bcn_idx] + i, 0x00); + } + else + { + ptr = (PUCHAR)&pAd->BeaconTxWI; + for (i=0; iBeaconOffset[bcn_idx] + i, longptr); + ptr += 4; + } + + // Update CapabilityInfo in Beacon + for (i = CapInfoPos; i < (CapInfoPos+2); i++) + { + RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_capinfo); + ptr_capinfo ++; + } + + if (FrameLen > UpdatePos) + { + for (i= UpdatePos; i< (FrameLen); i++) + { + RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, *ptr_update); + ptr_update ++; + } + } + + } + +} + + +VOID RT28xxPciStaAsicForceWakeup( + IN PRTMP_ADAPTER pAd, + IN BOOLEAN bFromTx) +{ + AUTO_WAKEUP_STRUC AutoWakeupCfg; + + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + return; + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) + { + DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n")); + return; + } + + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW); + +#ifdef RTMP_PCI_SUPPORT + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + { + // Support PCIe Advance Power Save + if (bFromTx == TRUE) + { + pAd->Mlme.bPsPollTimerRunning = FALSE; + RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP); + RTMPusecDelay(3000); + DBGPRINT(RT_DEBUG_TRACE, ("=======AsicForceWakeup===bFromTx\n")); + } + + AutoWakeupCfg.word = 0; + RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); + + if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE)) + { + { + // end johnli + // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. + if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel) + && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) + { + // Must using 40MHz. + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + } + else + { + // Must using 20MHz. + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + } + } + } + } + else +#endif // RTMP_PCI_SUPPORT // + { + // PCI, 2860-PCIe + AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); + AutoWakeupCfg.word = 0; + RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); + } + + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW); + DBGPRINT(RT_DEBUG_TRACE, ("<=======RT28xxPciStaAsicForceWakeup\n")); +} + + +VOID RT28xxPciStaAsicSleepThenAutoWakeup( + IN PRTMP_ADAPTER pAd, + IN USHORT TbttNumToNextWakeUp) +{ + BOOLEAN brc; + + if (pAd->StaCfg.bRadio == FALSE) + { + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); + return; + } + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + { + ULONG Now = 0; + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) + { + DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n")); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); + return; + } + + NdisGetSystemUpTime(&Now); + // If last send NULL fram time is too close to this receiving beacon (within 8ms), don't go to sleep for this DTM. + // Because Some AP can't queuing outgoing frames immediately. + if (((pAd->Mlme.LastSendNULLpsmTime + 8) >= Now) && (pAd->Mlme.LastSendNULLpsmTime <= Now)) + { + DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu : RxCountSinceLastNULL = %lu. \n", Now, pAd->Mlme.LastSendNULLpsmTime, pAd->RalinkCounters.RxCountSinceLastNULL)); + return; + } + else if ((pAd->RalinkCounters.RxCountSinceLastNULL > 0) && ((pAd->Mlme.LastSendNULLpsmTime + pAd->CommonCfg.BeaconPeriod) >= Now)) + { + DBGPRINT(RT_DEBUG_TRACE, ("Now = %lu, LastSendNULLpsmTime=%lu: RxCountSinceLastNULL = %lu > 0 \n", Now, pAd->Mlme.LastSendNULLpsmTime, pAd->RalinkCounters.RxCountSinceLastNULL)); + return; + } + + brc = RT28xxPciAsicRadioOff(pAd, DOT11POWERSAVE, TbttNumToNextWakeUp); + if (brc==TRUE) + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE); + } + else + { + AUTO_WAKEUP_STRUC AutoWakeupCfg; + // we have decided to SLEEP, so at least do it for a BEACON period. + if (TbttNumToNextWakeUp == 0) + TbttNumToNextWakeUp = 1; + + //RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt); + + AutoWakeupCfg.word = 0; + RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); + AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1; + AutoWakeupCfg.field.EnableAutoWakeup = 1; + AutoWakeupCfg.field.AutoLeadTime = 5; + RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); + AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x00); // send POWER-SAVE command to MCU. Timeout 40us. + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE); + DBGPRINT(RT_DEBUG_TRACE, ("<-- %s, TbttNumToNextWakeUp=%d \n", __func__, TbttNumToNextWakeUp)); + } + +} + +#ifdef RTMP_PCI_SUPPORT +VOID PsPollWakeExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; + unsigned long flags; + + DBGPRINT(RT_DEBUG_TRACE,("-->PsPollWakeExec \n")); + RTMP_INT_LOCK(&pAd->irq_lock, flags); + if (pAd->Mlme.bPsPollTimerRunning) + { + RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP); + } + pAd->Mlme.bPsPollTimerRunning = FALSE; + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); +} + +VOID RadioOnExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + WPDMA_GLO_CFG_STRUC DmaCfg; + BOOLEAN Cancelled; + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + { + DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n")); + RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); + return; + } + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + { + DBGPRINT(RT_DEBUG_TRACE,("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n")); + RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); + return; + } + pAd->Mlme.bPsPollTimerRunning = FALSE; + RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); + if (pAd->StaCfg.bRadio == TRUE) + { + pAd->bPCIclkOff = FALSE; + RTMPRingCleanUp(pAd, QID_AC_BK); + RTMPRingCleanUp(pAd, QID_AC_BE); + RTMPRingCleanUp(pAd, QID_AC_VI); + RTMPRingCleanUp(pAd, QID_AC_VO); + RTMPRingCleanUp(pAd, QID_HCCA); + RTMPRingCleanUp(pAd, QID_MGMT); + RTMPRingCleanUp(pAd, QID_RX); + + // 2. Send wake up command. + AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02); + // 2-1. wait command ok. + AsicCheckCommanOk(pAd, PowerWakeCID); + + // When PCI clock is off, don't want to service interrupt. So when back to clock on, enable interrupt. + //RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT)); + RTMP_ASIC_INTERRUPT_ENABLE(pAd); + + // 3. Enable Tx DMA. + RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word); + DmaCfg.field.EnableTxDMA = 1; + RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word); + + // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. + if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel) + && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) + { + // Must using 40MHz. + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + } + else + { + // Must using 20MHz. + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + } + + if (pChipOps->AsicReverseRfFromSleepMode) + pChipOps->AsicReverseRfFromSleepMode(pAd); + + // Clear Radio off flag + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); + + // Set LED + RTMPSetLED(pAd, LED_RADIO_ON); + + if (pAd->StaCfg.Psm == PWR_ACTIVE) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); + } + } + else + { + RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0); + } +} +#endif // RTMP_PCI_SUPPORT // + + +/* + ========================================================================== + Description: + This routine sends command to firmware and turn our chip to wake up mode from power save mode. + Both RadioOn and .11 power save function needs to call this routine. + Input: + Level = GUIRADIO_OFF : call this function is from Radio Off to Radio On. Need to restore PCI host value. + Level = other value : normal wake up function. + + ========================================================================== + */ +BOOLEAN RT28xxPciAsicRadioOn( + IN PRTMP_ADAPTER pAd, + IN UCHAR Level) +{ + //WPDMA_GLO_CFG_STRUC DmaCfg; + BOOLEAN Cancelled; + //UINT32 MACValue; + + if (pAd->OpMode == OPMODE_AP && Level==DOT11POWERSAVE) + return FALSE; + +#ifdef RTMP_PCI_SUPPORT + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + { + pAd->Mlme.bPsPollTimerRunning = FALSE; + RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); + if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE)) + { + DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n")); + // 1. Set PCI Link Control in Configuration Space. + RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP); + RTMPusecDelay(6000); + } + } +#endif // RTMP_PCI_SUPPORT // + + pAd->bPCIclkOff = FALSE; + // 2. Send wake up command. + AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02); + pAd->bPCIclkOff = FALSE; + // 2-1. wait command ok. + AsicCheckCommanOk(pAd, PowerWakeCID); + RTMP_ASIC_INTERRUPT_ENABLE(pAd); + + + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); + if (Level == GUI_IDLE_POWER_SAVE) + { + { + // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. + { + if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel) + && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) + { + // Must using 40MHz. + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + } + else + { + // Must using 20MHz. + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + } + } + + } + } + return TRUE; + +} + + +/* + ========================================================================== + Description: + This routine sends command to firmware and turn our chip to power save mode. + Both RadioOff and .11 power save function needs to call this routine. + Input: + Level = GUIRADIO_OFF : GUI Radio Off mode + Level = DOT11POWERSAVE : 802.11 power save mode + Level = RTMP_HALT : When Disable device. + + ========================================================================== + */ +BOOLEAN RT28xxPciAsicRadioOff( + IN PRTMP_ADAPTER pAd, + IN UCHAR Level, + IN USHORT TbttNumToNextWakeUp) +{ + WPDMA_GLO_CFG_STRUC DmaCfg; + UCHAR i, tempBBP_R3 = 0; + BOOLEAN brc = FALSE, Cancelled; + UINT32 TbTTTime = 0; + UINT32 PsPollTime = 0/*, MACValue*/; + ULONG BeaconPeriodTime; + UINT32 RxDmaIdx, RxCpuIdx; + DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> Lv= %d, TxCpuIdx = %d, TxDmaIdx = %d. RxCpuIdx = %d, RxDmaIdx = %d.\n", Level,pAd->TxRing[0].TxCpuIdx, pAd->TxRing[0].TxDmaIdx, pAd->RxRing.RxCpuIdx, pAd->RxRing.RxDmaIdx)); + + if (pAd->OpMode == OPMODE_AP && Level==DOT11POWERSAVE) + return FALSE; + + // Check Rx DMA busy status, if more than half is occupied, give up this radio off. + RTMP_IO_READ32(pAd, RX_DRX_IDX , &RxDmaIdx); + RTMP_IO_READ32(pAd, RX_CRX_IDX , &RxCpuIdx); + if ((RxDmaIdx > RxCpuIdx) && ((RxDmaIdx - RxCpuIdx) > RX_RING_SIZE/3)) + { + DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return1. RxDmaIdx = %d , RxCpuIdx = %d. \n", RxDmaIdx, RxCpuIdx)); + return FALSE; + } + else if ((RxCpuIdx >= RxDmaIdx) && ((RxCpuIdx - RxDmaIdx) < RX_RING_SIZE/3)) + { + DBGPRINT(RT_DEBUG_TRACE, ("AsicRadioOff ===> return2. RxCpuIdx = %d. RxDmaIdx = %d , \n", RxCpuIdx, RxDmaIdx)); + return FALSE; + } + + // Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops. + pAd->bPCIclkOffDisableTx = TRUE; + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE) && pAd->OpMode == OPMODE_STA) + { + printk("==>fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE\n"); + RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); + RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); + + if (Level == DOT11POWERSAVE) + { + RTMP_IO_READ32(pAd, TBTT_TIMER, &TbTTTime); + TbTTTime &= 0x1ffff; + // 00. check if need to do sleep in this DTIM period. If next beacon will arrive within 30ms , ...doesn't necessarily sleep. + // TbTTTime uint = 64us, LEAD_TIME unit = 1024us, PsPollTime unit = 1ms + if (((64*TbTTTime) <((LEAD_TIME*1024) + 40000)) && (TbttNumToNextWakeUp == 0)) + { + DBGPRINT(RT_DEBUG_TRACE, ("TbTTTime = 0x%x , give up this sleep. \n", TbTTTime)); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); + pAd->bPCIclkOffDisableTx = FALSE; + return FALSE; + } + else + { + PsPollTime = (64*TbTTTime- LEAD_TIME*1024)/1000; + PsPollTime -= 3; + + BeaconPeriodTime = pAd->CommonCfg.BeaconPeriod*102/100; + if (TbttNumToNextWakeUp > 0) + PsPollTime += ((TbttNumToNextWakeUp -1) * BeaconPeriodTime); + + pAd->Mlme.bPsPollTimerRunning = TRUE; + RTMPSetTimer(&pAd->Mlme.PsPollTimer, PsPollTime); + } + } + } + + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF); + + // Set to 1R. + if (pAd->Antenna.field.RxPath > 1 && pAd->OpMode == OPMODE_STA) + { + tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3); + } + + // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. + if ((INFRA_ON(pAd) || pAd->OpMode == OPMODE_AP) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel) + && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) + { + // Must using 40MHz. + AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel); + } + else + { + // Must using 20MHz. + AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel); + } + + if (Level != RTMP_HALT) + { + // Change Interrupt bitmask. + // When PCI clock is off, don't want to service interrupt. + RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt); + } + else + { + RTMP_ASIC_INTERRUPT_DISABLE(pAd); + } + + + RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx); + // 2. Send Sleep command + RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff); + RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff); + // send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power + AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1); + // 2-1. Wait command success + // Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task. + brc = AsicCheckCommanOk(pAd, PowerSafeCID); + + // 3. After 0x30 command is ok, send radio off command. lowbyte = 0 for power safe. + // If 0x30 command is not ok this time, we can ignore 0x35 command. It will make sure not cause firmware'r problem. + if ((Level == DOT11POWERSAVE) && (brc == TRUE)) + { + AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 0, 0x00); // lowbyte = 0 means to do power safe, NOT turn off radio. + // 3-1. Wait command success + AsicCheckCommanOk(pAd, PowerRadioOffCID); + } + else if (brc == TRUE) + { + AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 1, 0x00); // lowbyte = 0 means to do power safe, NOT turn off radio. + // 3-1. Wait command success + AsicCheckCommanOk(pAd, PowerRadioOffCID); + } + + // 1. Wait DMA not busy + i = 0; + do + { + RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word); + if ((DmaCfg.field.RxDMABusy == 0) && (DmaCfg.field.TxDMABusy == 0)) + break; + RTMPusecDelay(20); + i++; + }while(i < 50); + + /* + if (i >= 50) + { + pAd->CheckDmaBusyCount++; + DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy. return on AsicRadioOff () CheckDmaBusyCount = %d \n", pAd->CheckDmaBusyCount)); + } + else + { + pAd->CheckDmaBusyCount = 0; + } + */ + + if (Level == DOT11POWERSAVE) + { + AUTO_WAKEUP_STRUC AutoWakeupCfg; + //RTMPSetTimer(&pAd->Mlme.PsPollTimer, 90); + + // we have decided to SLEEP, so at least do it for a BEACON period. + if (TbttNumToNextWakeUp == 0) + TbttNumToNextWakeUp = 1; + + AutoWakeupCfg.word = 0; + RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); + + // 1. Set auto wake up timer. + AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1; + AutoWakeupCfg.field.EnableAutoWakeup = 1; + AutoWakeupCfg.field.AutoLeadTime = LEAD_TIME; + RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); + } + +#ifdef RTMP_PCI_SUPPORT + // 4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value. + if (Level == RTMP_HALT && pAd->OpMode == OPMODE_STA) + { + if ((brc == TRUE) && (i < 50)) + RTMPPCIeLinkCtrlSetting(pAd, 1); + } + // 4. Set PCI configuration Space Link Comtrol fields. Only Radio Off needs to call this function + else if (pAd->OpMode == OPMODE_STA) + { + if ((brc == TRUE) && (i < 50)) + RTMPPCIeLinkCtrlSetting(pAd, 3); + } +#endif // RTMP_PCI_SUPPORT // + + pAd->bPCIclkOffDisableTx = FALSE; + return TRUE; +} + + + + +VOID RT28xxPciMlmeRadioOn( + IN PRTMP_ADAPTER pAd) +{ + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) + return; + + DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__)); + + if ((pAd->OpMode == OPMODE_AP) || + ((pAd->OpMode == OPMODE_STA) && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)))) + { + if (pAd->OpMode == OPMODE_AP) + RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); + + //NICResetFromError(pAd); + + RTMPRingCleanUp(pAd, QID_AC_BK); + RTMPRingCleanUp(pAd, QID_AC_BE); + RTMPRingCleanUp(pAd, QID_AC_VI); + RTMPRingCleanUp(pAd, QID_AC_VO); + RTMPRingCleanUp(pAd, QID_HCCA); + RTMPRingCleanUp(pAd, QID_MGMT); + RTMPRingCleanUp(pAd, QID_RX); + + if (pAd->OpMode == OPMODE_STA) + { + AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); + RTMPusecDelay(10000); + } + + // Enable Tx/Rx + RTMPEnableRxTx(pAd); + + // Clear Radio off flag + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); + + // Set LED + RTMPSetLED(pAd, LED_RADIO_ON); + } + +#ifdef RTMP_PCI_SUPPORT + if ((pAd->OpMode == OPMODE_STA) && + (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))) + { + BOOLEAN Cancelled; + + RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP); + + pAd->Mlme.bPsPollTimerRunning = FALSE; + RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); + RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); + RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); + } +#endif // RTMP_PCI_SUPPORT // +} + + +VOID RT28xxPciMlmeRadioOFF( + IN PRTMP_ADAPTER pAd) +{ + BOOLEAN brc=TRUE; + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) + return; + + // Link down first if any association exists + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + { + if (INFRA_ON(pAd) || ADHOC_ON(pAd)) + { + MLME_DISASSOC_REQ_STRUCT DisReq; + MLME_QUEUE_ELEM *pMsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); + + if (pMsgElem) + { + COPY_MAC_ADDR(&DisReq.Addr, pAd->CommonCfg.Bssid); + DisReq.Reason = REASON_DISASSOC_STA_LEAVING; + + pMsgElem->Machine = ASSOC_STATE_MACHINE; + pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ; + pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT); + NdisMoveMemory(pMsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT)); + + MlmeDisassocReqAction(pAd, pMsgElem); + kfree(pMsgElem); + + RTMPusecDelay(1000); + } + } + } + + DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__)); + + // Set Radio off flag + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); + + { + BOOLEAN Cancelled; + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + { + RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); + } + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + { + BOOLEAN Cancelled; + pAd->Mlme.bPsPollTimerRunning = FALSE; + RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); + RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); + } + + // Link down first if any association exists + if (INFRA_ON(pAd) || ADHOC_ON(pAd)) + LinkDown(pAd, FALSE); + RTMPusecDelay(10000); + //========================================== + // Clean up old bss table + BssTableInit(&pAd->ScanTab); + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + { + RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10); + return; + } + } + + // Set LED + RTMPSetLED(pAd, LED_RADIO_OFF); + + if (pAd->OpMode == OPMODE_AP) + brc=RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0); + + if (brc==FALSE) + { + DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __func__)); + } + + + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE) && + (pAd->OpMode == OPMODE_STA)) + AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); +} + +#endif // RTMP_MAC_PCI // Index: b/drivers/staging/rt2860/common/cmm_mac_usb.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/cmm_mac_usb.c @@ -0,0 +1,1216 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* +*/ + +#ifdef RTMP_MAC_USB + + +#include "../rt_config.h" + + +/* +======================================================================== +Routine Description: + Initialize receive data structures. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_RESOURCES + +Note: + Initialize all receive releated private buffer, include those define + in RTMP_ADAPTER structure and all private data structures. The mahor + work is to allocate buffer for each packet and chain buffer to + NDIS packet descriptor. +======================================================================== +*/ +NDIS_STATUS NICInitRecv( + IN PRTMP_ADAPTER pAd) +{ + UCHAR i; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + + DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n")); + pObj = pObj; + + //InterlockedExchange(&pAd->PendingRx, 0); + pAd->PendingRx = 0; + pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index + pAd->NextRxBulkInIndex = 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer + pAd->NextRxBulkInPosition = 0; + + for (i = 0; i < (RX_RING_SIZE); i++) + { + PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); + + //Allocate URB + pRxContext->pUrb = RTUSB_ALLOC_URB(0); + if (pRxContext->pUrb == NULL) + { + Status = NDIS_STATUS_RESOURCES; + goto out1; + } + + // Allocate transfer buffer + pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma); + if (pRxContext->TransferBuffer == NULL) + { + Status = NDIS_STATUS_RESOURCES; + goto out1; + } + + NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE); + + pRxContext->pAd = pAd; + pRxContext->pIrp = NULL; + pRxContext->InUse = FALSE; + pRxContext->IRPPending = FALSE; + pRxContext->Readable = FALSE; + //pRxContext->ReorderInUse = FALSE; + pRxContext->bRxHandling = FALSE; + pRxContext->BulkInOffset = 0; + } + + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status)); + return Status; + +out1: + for (i = 0; i < (RX_RING_SIZE); i++) + { + PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); + + if (NULL != pRxContext->TransferBuffer) + { + RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, + pRxContext->TransferBuffer, pRxContext->data_dma); + pRxContext->TransferBuffer = NULL; + } + + if (NULL != pRxContext->pUrb) + { + RTUSB_UNLINK_URB(pRxContext->pUrb); + RTUSB_FREE_URB(pRxContext->pUrb); + pRxContext->pUrb = NULL; + } + } + + return Status; +} + + +/* +======================================================================== +Routine Description: + Initialize transmit data structures. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_RESOURCES + +Note: +======================================================================== +*/ +NDIS_STATUS NICInitTransmit( + IN PRTMP_ADAPTER pAd) +{ +#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \ + Context->pUrb = RTUSB_ALLOC_URB(0); \ + if (Context->pUrb == NULL) { \ + DBGPRINT(RT_DEBUG_ERROR, msg1); \ + Status = NDIS_STATUS_RESOURCES; \ + goto err1; } \ + \ + Context->TransferBuffer = \ + (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \ + if (Context->TransferBuffer == NULL) { \ + DBGPRINT(RT_DEBUG_ERROR, msg2); \ + Status = NDIS_STATUS_RESOURCES; \ + goto err2; } + +#define LM_URB_FREE(pObj, Context, BufferSize) \ + if (NULL != Context->pUrb) { \ + RTUSB_UNLINK_URB(Context->pUrb); \ + RTUSB_FREE_URB(Context->pUrb); \ + Context->pUrb = NULL; } \ + if (NULL != Context->TransferBuffer) { \ + RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \ + Context->TransferBuffer, \ + Context->data_dma); \ + Context->TransferBuffer = NULL; } + + UCHAR i, acidx; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + PTX_CONTEXT pNullContext = &(pAd->NullContext); + PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext); + PTX_CONTEXT pRTSContext = &(pAd->RTSContext); + PTX_CONTEXT pMLMEContext = NULL; +// PHT_TX_CONTEXT pHTTXContext = NULL; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + PVOID RingBaseVa; +// RTMP_TX_RING *pTxRing; + RTMP_MGMT_RING *pMgmtRing; + + DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n")); + pObj = pObj; + + // Init 4 set of Tx parameters + for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++) + { + // Initialize all Transmit releated queues + InitializeQueueHeader(&pAd->TxSwQueue[acidx]); + + // Next Local tx ring pointer waiting for buck out + pAd->NextBulkOutIndex[acidx] = acidx; + pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag + //pAd->DataBulkDoneIdx[acidx] = 0; + } + + //pAd->NextMLMEIndex = 0; + //pAd->PushMgmtIndex = 0; + //pAd->PopMgmtIndex = 0; + //InterlockedExchange(&pAd->MgmtQueueSize, 0); + //InterlockedExchange(&pAd->TxCount, 0); + + //pAd->PrioRingFirstIndex = 0; + //pAd->PrioRingTxCnt = 0; + + do + { + // + // TX_RING_SIZE, 4 ACs + // + for(acidx=0; acidx<4; acidx++) + { + PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); + + NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT)); + //Allocate URB + LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status, + ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx), + done, + ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx), + out1); + + NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4); + pHTTXContext->pAd = pAd; + pHTTXContext->pIrp = NULL; + pHTTXContext->IRPPending = FALSE; + pHTTXContext->NextBulkOutPosition = 0; + pHTTXContext->ENextBulkOutPosition = 0; + pHTTXContext->CurWritePosition = 0; + pHTTXContext->CurWriteRealPos = 0; + pHTTXContext->BulkOutSize = 0; + pHTTXContext->BulkOutPipeId = acidx; + pHTTXContext->bRingEmpty = TRUE; + pHTTXContext->bCopySavePad = FALSE; + pAd->BulkOutPending[acidx] = FALSE; + } + + + // + // MGMT_RING_SIZE + // + + // Allocate MGMT ring descriptor's memory + pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT); + os_alloc_mem(pAd, (PUCHAR *)(&pAd->MgmtDescRing.AllocVa), pAd->MgmtDescRing.AllocSize); + if (pAd->MgmtDescRing.AllocVa == NULL) + { + DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n")); + Status = NDIS_STATUS_RESOURCES; + goto out1; + } + NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); + RingBaseVa = pAd->MgmtDescRing.AllocVa; + + // Initialize MGMT Ring and associated buffer memory + pMgmtRing = &pAd->MgmtRing; + for (i = 0; i < MGMT_RING_SIZE; i++) + { + // link the pre-allocated Mgmt buffer to MgmtRing.Cell + pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT); + pMgmtRing->Cell[i].AllocVa = RingBaseVa; + pMgmtRing->Cell[i].pNdisPacket = NULL; + pMgmtRing->Cell[i].pNextNdisPacket = NULL; + + //Allocate URB for MLMEContext + pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa; + pMLMEContext->pUrb = RTUSB_ALLOC_URB(0); + if (pMLMEContext->pUrb == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i)); + Status = NDIS_STATUS_RESOURCES; + goto out2; + } + pMLMEContext->pAd = pAd; + pMLMEContext->pIrp = NULL; + pMLMEContext->TransferBuffer = NULL; + pMLMEContext->InUse = FALSE; + pMLMEContext->IRPPending = FALSE; + pMLMEContext->bWaitingBulkOut = FALSE; + pMLMEContext->BulkOutSize = 0; + pMLMEContext->SelfIdx = i; + + // Offset to next ring descriptor address + RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT); + } + DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i)); + + //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1); + pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE; + pAd->MgmtRing.TxCpuIdx = 0; + pAd->MgmtRing.TxDmaIdx = 0; + + // + // BEACON_RING_SIZE + // + for(i=0; iBeaconContext[i]); + + + NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT)); + + //Allocate URB + LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, + ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i), + out2, + ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i), + out3); + + pBeaconContext->pAd = pAd; + pBeaconContext->pIrp = NULL; + pBeaconContext->InUse = FALSE; + pBeaconContext->IRPPending = FALSE; + } + + // + // NullContext + // + NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT)); + + //Allocate URB + LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, + ("<-- ERROR in Alloc TX NullContext urb!! \n"), + out3, + ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"), + out4); + + pNullContext->pAd = pAd; + pNullContext->pIrp = NULL; + pNullContext->InUse = FALSE; + pNullContext->IRPPending = FALSE; + + // + // RTSContext + // + NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT)); + + //Allocate URB + LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, + ("<-- ERROR in Alloc TX RTSContext urb!! \n"), + out4, + ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"), + out5); + + pRTSContext->pAd = pAd; + pRTSContext->pIrp = NULL; + pRTSContext->InUse = FALSE; + pRTSContext->IRPPending = FALSE; + + // + // PsPollContext + // + //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT)); + //Allocate URB + LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, + ("<-- ERROR in Alloc TX PsPollContext urb!! \n"), + out5, + ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"), + out6); + + pPsPollContext->pAd = pAd; + pPsPollContext->pIrp = NULL; + pPsPollContext->InUse = FALSE; + pPsPollContext->IRPPending = FALSE; + pPsPollContext->bAggregatible = FALSE; + pPsPollContext->LastOne = TRUE; + + } while (FALSE); + + +done: + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status)); + + return Status; + + /* --------------------------- ERROR HANDLE --------------------------- */ +out6: + LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER)); + +out5: + LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER)); + +out4: + LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER)); + +out3: + for(i=0; iBeaconContext[i]); + if (pBeaconContext) + LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER)); + } + +out2: + if (pAd->MgmtDescRing.AllocVa) + { + pMgmtRing = &pAd->MgmtRing; + for(i=0; iMgmtRing.Cell[i].AllocVa; + if (pMLMEContext) + LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER)); + } + os_free_mem(pAd, pAd->MgmtDescRing.AllocVa); + pAd->MgmtDescRing.AllocVa = NULL; + } + +out1: + for (acidx = 0; acidx < 4; acidx++) + { + PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]); + if (pTxContext) + LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER)); + } + + // Here we didn't have any pre-allocated memory need to free. + + return Status; +} + + +/* +======================================================================== +Routine Description: + Allocate DMA memory blocks for send, receive. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_RESOURCES + +Note: +======================================================================== +*/ +NDIS_STATUS RTMPAllocTxRxRingMemory( + IN PRTMP_ADAPTER pAd) +{ +// COUNTER_802_11 pCounter = &pAd->WlanCounters; + NDIS_STATUS Status; + INT num; + + + DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); + + + do + { + // Init the CmdQ and CmdQLock + NdisAllocateSpinLock(&pAd->CmdQLock); + NdisAcquireSpinLock(&pAd->CmdQLock); + RTUSBInitializeCmdQ(&pAd->CmdQ); + NdisReleaseSpinLock(&pAd->CmdQLock); + + + NdisAllocateSpinLock(&pAd->MLMEBulkOutLock); + //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock); + NdisAllocateSpinLock(&pAd->BulkOutLock[0]); + NdisAllocateSpinLock(&pAd->BulkOutLock[1]); + NdisAllocateSpinLock(&pAd->BulkOutLock[2]); + NdisAllocateSpinLock(&pAd->BulkOutLock[3]); + NdisAllocateSpinLock(&pAd->BulkOutLock[4]); + NdisAllocateSpinLock(&pAd->BulkOutLock[5]); + NdisAllocateSpinLock(&pAd->BulkInLock); + + for (num = 0; num < NUM_OF_TX_RING; num++) + { + NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]); + } + + +// NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX + +// NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit() +// NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit() + +// for(num=0; numBATable.BARecEntry[num].RxReRingLock); +// } + + // + // Init Mac Table + // +// MacTableInitialize(pAd); + + // + // Init send data structures and related parameters + // + Status = NICInitTransmit(pAd); + if (Status != NDIS_STATUS_SUCCESS) + break; + + // + // Init receive data structures and related parameters + // + Status = NICInitRecv(pAd); + if (Status != NDIS_STATUS_SUCCESS) + break; + + pAd->PendingIoCount = 1; + + } while (FALSE); + + NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME)); + pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); + + if (pAd->FragFrame.pFragPacket == NULL) + { + Status = NDIS_STATUS_RESOURCES; + } + + DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); + return Status; +} + + +/* +======================================================================== +Routine Description: + Calls USB_InterfaceStop and frees memory allocated for the URBs + calls NdisMDeregisterDevice and frees the memory + allocated in VNetInitialize for the Adapter Object + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RTMPFreeTxRxRingMemory( + IN PRTMP_ADAPTER pAd) +{ +#define LM_URB_FREE(pObj, Context, BufferSize) \ + if (NULL != Context->pUrb) { \ + RTUSB_UNLINK_URB(Context->pUrb); \ + RTUSB_FREE_URB(Context->pUrb); \ + Context->pUrb = NULL; } \ + if (NULL != Context->TransferBuffer) { \ + RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \ + Context->TransferBuffer, \ + Context->data_dma); \ + Context->TransferBuffer = NULL; } + + + UINT i, acidx; + PTX_CONTEXT pNullContext = &pAd->NullContext; + PTX_CONTEXT pPsPollContext = &pAd->PsPollContext; + PTX_CONTEXT pRTSContext = &pAd->RTSContext; +// PHT_TX_CONTEXT pHTTXContext; + //PRTMP_REORDERBUF pReorderBuf; + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; +// RTMP_TX_RING *pTxRing; + + DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n")); + pObj = pObj; + + // Free all resources for the RECEIVE buffer queue. + for(i=0; i<(RX_RING_SIZE); i++) + { + PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); + if (pRxContext) + LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE); + } + + // Free PsPoll frame resource + LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER)); + + // Free NULL frame resource + LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER)); + + // Free RTS frame resource + LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER)); + + + // Free beacon frame resource + for(i=0; iBeaconContext[i]); + if (pBeaconContext) + LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER)); + } + + + // Free mgmt frame resource + for(i = 0; i < MGMT_RING_SIZE; i++) + { + PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa; + //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER)); + if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) + { + RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket); + pAd->MgmtRing.Cell[i].pNdisPacket = NULL; + pMLMEContext->TransferBuffer = NULL; + } + + if (pMLMEContext) + { + if (NULL != pMLMEContext->pUrb) + { + RTUSB_UNLINK_URB(pMLMEContext->pUrb); + RTUSB_FREE_URB(pMLMEContext->pUrb); + pMLMEContext->pUrb = NULL; + } + } + } + if (pAd->MgmtDescRing.AllocVa) + os_free_mem(pAd, pAd->MgmtDescRing.AllocVa); + + + // Free Tx frame resource + for (acidx = 0; acidx < 4; acidx++) + { + PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); + if (pHTTXContext) + LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER)); + } + + if (pAd->FragFrame.pFragPacket) + RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS); + + for(i=0; i<6; i++) + { + NdisFreeSpinLock(&pAd->BulkOutLock[i]); + } + + NdisFreeSpinLock(&pAd->BulkInLock); + NdisFreeSpinLock(&pAd->MLMEBulkOutLock); + + NdisFreeSpinLock(&pAd->CmdQLock); + // Clear all pending bulk-out request flags. + RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff); + +// NdisFreeSpinLock(&pAd->MacTabLock); + +// for(i=0; iBATable.BARecEntry[i].RxReRingLock); +// } + + DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n")); +} + + +/* +======================================================================== +Routine Description: + Write WLAN MAC address to USB 2870. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + +Note: +======================================================================== +*/ +NDIS_STATUS RTUSBWriteHWMACAddress( + IN PRTMP_ADAPTER pAd) +{ + MAC_DW0_STRUC StaMacReg0; + MAC_DW1_STRUC StaMacReg1; + NDIS_STATUS Status = NDIS_STATUS_SUCCESS; + LARGE_INTEGER NOW; + + + // initialize the random number generator + RTMP_GetCurrentSystemTime(&NOW); + + if (pAd->bLocalAdminMAC != TRUE) + { + pAd->CurrentAddress[0] = pAd->PermanentAddress[0]; + pAd->CurrentAddress[1] = pAd->PermanentAddress[1]; + pAd->CurrentAddress[2] = pAd->PermanentAddress[2]; + pAd->CurrentAddress[3] = pAd->PermanentAddress[3]; + pAd->CurrentAddress[4] = pAd->PermanentAddress[4]; + pAd->CurrentAddress[5] = pAd->PermanentAddress[5]; + } + // Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC + StaMacReg0.field.Byte0 = pAd->CurrentAddress[0]; + StaMacReg0.field.Byte1 = pAd->CurrentAddress[1]; + StaMacReg0.field.Byte2 = pAd->CurrentAddress[2]; + StaMacReg0.field.Byte3 = pAd->CurrentAddress[3]; + StaMacReg1.field.Byte4 = pAd->CurrentAddress[4]; + StaMacReg1.field.Byte5 = pAd->CurrentAddress[5]; + StaMacReg1.field.U2MeMask = 0xff; + DBGPRINT_RAW(RT_DEBUG_TRACE, ("Local MAC = %02x:%02x:%02x:%02x:%02x:%02x\n", + pAd->CurrentAddress[0], pAd->CurrentAddress[1], pAd->CurrentAddress[2], + pAd->CurrentAddress[3], pAd->CurrentAddress[4], pAd->CurrentAddress[5])); + + RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word); + RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word); + return Status; +} + + +/* +======================================================================== +Routine Description: + Disable DMA. + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT28XXDMADisable( + IN RTMP_ADAPTER *pAd) +{ + // no use +} + + +/* +======================================================================== +Routine Description: + Enable DMA. + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT28XXDMAEnable( + IN RTMP_ADAPTER *pAd) +{ + WPDMA_GLO_CFG_STRUC GloCfg; + USB_DMA_CFG_STRUC UsbCfg; + int i = 0; + + + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4); + do + { + RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); + if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) + break; + + DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n")); + RTMPusecDelay(1000); + i++; + }while ( i <200); + + + RTMPusecDelay(50); + GloCfg.field.EnTXWriteBackDDONE = 1; + GloCfg.field.EnableRxDMA = 1; + GloCfg.field.EnableTxDMA = 1; + DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word)); + RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); + + UsbCfg.word = 0; + UsbCfg.field.phyclear = 0; + /* usb version is 1.1,do not use bulk in aggregation */ + if (pAd->BulkInMaxPacketSize == 512) + UsbCfg.field.RxBulkAggEn = 1; + /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */ + UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3; + UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */ + UsbCfg.field.RxBulkEn = 1; + UsbCfg.field.TxBulkEn = 1; + + RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word); + +} + +/******************************************************************** + * + * 2870 Beacon Update Related functions. + * + ********************************************************************/ + +/* +======================================================================== +Routine Description: + Write Beacon buffer to Asic. + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + None + +Note: +======================================================================== +*/ +VOID RT28xx_UpdateBeaconToAsic( + IN RTMP_ADAPTER *pAd, + IN INT apidx, + IN ULONG FrameLen, + IN ULONG UpdatePos) +{ + PUCHAR pBeaconFrame = NULL; + UCHAR *ptr; + UINT i, padding; + BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync; + UINT32 longValue; +// USHORT shortValue; + BOOLEAN bBcnReq = FALSE; + UCHAR bcn_idx = 0; + + + if (pBeaconFrame == NULL) + { + DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n")); + return; + } + + if (pBeaconSync == NULL) + { + DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n")); + return; + } + + //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) || + // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) + // ) + if (bBcnReq == FALSE) + { + /* when the ra interface is down, do not send its beacon frame */ + /* clear all zero */ + for(i=0; iBeaconOffset[bcn_idx] + i, 0x00); + } + pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx))); + NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE); + } + else + { + ptr = (PUCHAR)&pAd->BeaconTxWI; + if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE) + { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames. + pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx))); + NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE); + } + + if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx)) + { + for (i=0; iBeaconOffset[bcn_idx] + i, longValue); + ptr += 4; + } + } + + ptr = pBeaconSync->BeaconBuf[bcn_idx]; + padding = (FrameLen & 0x01); + NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding); + FrameLen += padding; + for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2) + { + if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE) + { + NdisMoveMemory(ptr, pBeaconFrame, 2); + //shortValue = *ptr + (*(ptr+1)<<8); + //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue); + RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2); + } + ptr +=2; + pBeaconFrame += 2; + } + + pBeaconSync->BeaconBitMap |= (1 << bcn_idx); + + // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame. +} + +} + + +VOID RTUSBBssBeaconStop( + IN RTMP_ADAPTER *pAd) +{ + BEACON_SYNC_STRUCT *pBeaconSync; + int i, offset; + BOOLEAN Cancelled = TRUE; + + pBeaconSync = pAd->CommonCfg.pBeaconSync; + if (pBeaconSync && pBeaconSync->EnableBeacon) + { + INT NumOfBcn; + + { + NumOfBcn = MAX_MESH_NUM; + } + + RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled); + + for(i=0; iBeaconBuf[i], HW_BEACON_OFFSET); + NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); + + for (offset=0; offsetBeaconOffset[i] + offset, 0x00); + + pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; + pBeaconSync->TimIELocationInBeacon[i] = 0; + } + pBeaconSync->BeaconBitMap = 0; + pBeaconSync->DtimBitOn = 0; + } +} + + +VOID RTUSBBssBeaconStart( + IN RTMP_ADAPTER *pAd) +{ + int apidx; + BEACON_SYNC_STRUCT *pBeaconSync; +// LARGE_INTEGER tsfTime, deltaTime; + + pBeaconSync = pAd->CommonCfg.pBeaconSync; + if (pBeaconSync && pBeaconSync->EnableBeacon) + { + INT NumOfBcn; + + { + NumOfBcn = MAX_MESH_NUM; + } + + for(apidx=0; apidxBeaconBuf[apidx], HW_BEACON_OFFSET); + pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon; + pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon; + NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE); + } + pBeaconSync->BeaconBitMap = 0; + pBeaconSync->DtimBitOn = 0; + pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE; + + pAd->CommonCfg.BeaconAdjust = 0; + pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10); + pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1; + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", + pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain)); + RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, 10 /*pAd->CommonCfg.BeaconPeriod*/); + + } +} + + +VOID RTUSBBssBeaconInit( + IN RTMP_ADAPTER *pAd) +{ + BEACON_SYNC_STRUCT *pBeaconSync; + int i; + + os_alloc_mem(pAd, (PUCHAR *)(&pAd->CommonCfg.pBeaconSync), sizeof(BEACON_SYNC_STRUCT)); + //NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG); + if (pAd->CommonCfg.pBeaconSync) + { + pBeaconSync = pAd->CommonCfg.pBeaconSync; + NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT)); + for(i=0; i < HW_BEACON_MAX_COUNT; i++) + { + NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET); + pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; + pBeaconSync->TimIELocationInBeacon[i] = 0; + NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); + } + pBeaconSync->BeaconBitMap = 0; + + //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE); + pBeaconSync->EnableBeacon = TRUE; + } +} + + +VOID RTUSBBssBeaconExit( + IN RTMP_ADAPTER *pAd) +{ + BEACON_SYNC_STRUCT *pBeaconSync; + BOOLEAN Cancelled = TRUE; + int i; + + if (pAd->CommonCfg.pBeaconSync) + { + pBeaconSync = pAd->CommonCfg.pBeaconSync; + pBeaconSync->EnableBeacon = FALSE; + RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled); + pBeaconSync->BeaconBitMap = 0; + + for(i=0; iBeaconBuf[i], HW_BEACON_OFFSET); + pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; + pBeaconSync->TimIELocationInBeacon[i] = 0; + NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); + } + + os_free_mem(pAd, pAd->CommonCfg.pBeaconSync); + pAd->CommonCfg.pBeaconSync = NULL; + } +} + + +/* + ======================================================================== + Routine Description: + For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism + to update the beacon context in each Beacon interval. Here we use a periodical timer + to simulate the TBTT interrupt to handle the beacon context update. + + Arguments: + SystemSpecific1 - Not used. + FunctionContext - Pointer to our Adapter context. + SystemSpecific2 - Not used. + SystemSpecific3 - Not used. + + Return Value: + None + + ======================================================================== +*/ +VOID BeaconUpdateExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext; + LARGE_INTEGER tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab; + UINT32 delta, delta2MS, period2US, remain, remain_low, remain_high; +// BOOLEAN positive; + + if (pAd->CommonCfg.IsUpdateBeacon==TRUE) + { + ReSyncBeaconTime(pAd); + + + } + + RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart); + RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart); + + + //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp); + period2US = (pAd->CommonCfg.BeaconPeriod << 10); + remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart; + remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10); + remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10); + delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain; + + delta2MS = (delta>>10); + if (delta2MS > 150) + { + pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100; + pAd->CommonCfg.IsUpdateBeacon=FALSE; + } + else + { + pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10; + pAd->CommonCfg.IsUpdateBeacon=TRUE; + } + +} + + +/******************************************************************** + * + * 2870 Radio on/off Related functions. + * + ********************************************************************/ +VOID RT28xxUsbMlmeRadioOn( + IN PRTMP_ADAPTER pAd) +{ + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + + DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n")); + + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) + return; + + { + AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); + RTMPusecDelay(10000); + } + //NICResetFromError(pAd); + + // Enable Tx/Rx + RTMPEnableRxTx(pAd); + + if (pChipOps->AsicReverseRfFromSleepMode) + pChipOps->AsicReverseRfFromSleepMode(pAd); + + // Clear Radio off flag + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); + + RTUSBBulkReceive(pAd); + + // Set LED + RTMPSetLED(pAd, LED_RADIO_ON); +} + + +VOID RT28xxUsbMlmeRadioOFF( + IN PRTMP_ADAPTER pAd) +{ + WPDMA_GLO_CFG_STRUC GloCfg; + UINT32 Value, i; + + DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n")); + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) + return; + + // Clear PMKID cache. + pAd->StaCfg.SavedPMKNum = 0; + RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(BSSID_INFO))); + + // Link down first if any association exists + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) + { + if (INFRA_ON(pAd) || ADHOC_ON(pAd)) + { + MLME_DISASSOC_REQ_STRUCT DisReq; + MLME_QUEUE_ELEM *pMsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); + + if (pMsgElem) + { + COPY_MAC_ADDR(&DisReq.Addr, pAd->CommonCfg.Bssid); + DisReq.Reason = REASON_DISASSOC_STA_LEAVING; + + pMsgElem->Machine = ASSOC_STATE_MACHINE; + pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ; + pMsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT); + NdisMoveMemory(pMsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT)); + + MlmeDisassocReqAction(pAd, pMsgElem); + kfree(pMsgElem); + + RTMPusecDelay(1000); + } + } + } + + // Set Radio off flag + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); + + { + // Link down first if any association exists + if (INFRA_ON(pAd) || ADHOC_ON(pAd)) + LinkDown(pAd, FALSE); + RTMPusecDelay(10000); + + //========================================== + // Clean up old bss table + BssTableInit(&pAd->ScanTab); + } + + // Set LED + RTMPSetLED(pAd, LED_RADIO_OFF); + + + if (pAd->CommonCfg.BBPCurrentBW == BW_40) + { + // Must using 40MHz. + AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel); + } + else + { + // Must using 20MHz. + AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel); + } + + // Disable Tx/Rx DMA + RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA + GloCfg.field.EnableTxDMA = 0; + GloCfg.field.EnableRxDMA = 0; + RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings + + // Waiting for DMA idle + i = 0; + do + { + RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); + if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) + break; + + RTMPusecDelay(1000); + }while (i++ < 100); + + // Disable MAC Tx/Rx + RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value); + Value &= (0xfffffff3); + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value); + + { + AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); + } +} + +#endif // RTMP_MAC_USB // Index: b/drivers/staging/rt2860/common/cmm_profile.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/cmm_profile.c @@ -0,0 +1,1793 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* +*/ + +#include "../rt_config.h" + + +#define ETH_MAC_ADDR_STR_LEN 17 // in format of xx:xx:xx:xx:xx:xx + +// We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed. +BOOLEAN rtstrmactohex(PSTRING s1, PSTRING s2) +{ + int i = 0; + PSTRING ptokS = s1, ptokE = s1; + + if (strlen(s1) != ETH_MAC_ADDR_STR_LEN) + return FALSE; + + while((*ptokS) != '\0') + { + if((ptokE = strchr(ptokS, ':')) != NULL) + *ptokE++ = '\0'; + if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1)))) + break; // fail + AtoH(ptokS, (PUCHAR)&s2[i++], 1); + ptokS = ptokE; + if (i == 6) + break; // parsing finished + } + + return ( i == 6 ? TRUE : FALSE); + +} + + +// we assume the s1 and s2 both are strings. +BOOLEAN rtstrcasecmp(PSTRING s1, PSTRING s2) +{ + PSTRING p1 = s1, p2 = s2; + + if (strlen(s1) != strlen(s2)) + return FALSE; + + while(*p1 != '\0') + { + if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20)) + return FALSE; + p1++; + p2++; + } + + return TRUE; +} + +// we assume the s1 (buffer) and s2 (key) both are strings. +PSTRING rtstrstruncasecmp(PSTRING s1, PSTRING s2) +{ + INT l1, l2, i; + char temp1, temp2; + + l2 = strlen(s2); + if (!l2) + return (char *) s1; + + l1 = strlen(s1); + + while (l1 >= l2) + { + l1--; + + for(i=0; i= l2) + { + l1--; + if (!memcmp(s1,s2,l2)) + return s1; + s1++; + } + + return NULL; +} + +/** + * rstrtok - Split a string into tokens + * @s: The string to be searched + * @ct: The characters to search for + * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture. + */ +PSTRING __rstrtok; +PSTRING rstrtok(PSTRING s,const PSTRING ct) +{ + PSTRING sbegin, send; + + sbegin = s ? s : __rstrtok; + if (!sbegin) + { + return NULL; + } + + sbegin += strspn(sbegin,ct); + if (*sbegin == '\0') + { + __rstrtok = NULL; + return( NULL ); + } + + send = strpbrk( sbegin, ct); + if (send && *send != '\0') + *send++ = '\0'; + + __rstrtok = send; + + return (sbegin); +} + +/** + * delimitcnt - return the count of a given delimiter in a given string. + * @s: The string to be searched. + * @ct: The delimiter to search for. + * Notice : We suppose the delimiter is a single-char string(for example : ";"). + */ +INT delimitcnt(PSTRING s,PSTRING ct) +{ + INT count = 0; + /* point to the beginning of the line */ + PSTRING token = s; + + for ( ;; ) + { + token = strpbrk(token, ct); /* search for delimiters */ + + if ( token == NULL ) + { + /* advanced to the terminating null character */ + break; + } + /* skip the delimiter */ + ++token; + + /* + * Print the found text: use len with %.*s to specify field width. + */ + + /* accumulate delimiter count */ + ++count; + } + return count; +} + +/* + * converts the Internet host address from the standard numbers-and-dots notation + * into binary data. + * returns nonzero if the address is valid, zero if not. + */ +int rtinet_aton(PSTRING cp, unsigned int *addr) +{ + unsigned int val; + int base, n; + STRING c; + unsigned int parts[4]; + unsigned int *pp = parts; + + for (;;) + { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, other=decimal. + */ + val = 0; + base = 10; + if (*cp == '0') + { + if (*++cp == 'x' || *cp == 'X') + base = 16, cp++; + else + base = 8; + } + while ((c = *cp) != '\0') + { + if (isdigit((unsigned char) c)) + { + val = (val * base) + (c - '0'); + cp++; + continue; + } + if (base == 16 && isxdigit((unsigned char) c)) + { + val = (val << 4) + + (c + 10 - (islower((unsigned char) c) ? 'a' : 'A')); + cp++; + continue; + } + break; + } + if (*cp == '.') + { + /* + * Internet format: a.b.c.d a.b.c (with c treated as 16-bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3 || val > 0xff) + return 0; + *pp++ = val, cp++; + } + else + break; + } + + /* + * Check for trailing junk. + */ + while (*cp) + if (!isspace((unsigned char) *cp++)) + return 0; + + /* + * Concoct the address according to the number of parts specified. + */ + n = pp - parts + 1; + switch (n) + { + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffff) + return 0; + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + return 0; + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + return 0; + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + + *addr = htonl(val); + return 1; + +} + +/* + ======================================================================== + + Routine Description: + Find key section for Get key parameter. + + Arguments: + buffer Pointer to the buffer to start find the key section + section the key of the secion to be find + + Return Value: + NULL Fail + Others Success + ======================================================================== +*/ +PSTRING RTMPFindSection( + IN PSTRING buffer) +{ + STRING temp_buf[32]; + PSTRING ptr; + + strcpy(temp_buf, "Default"); + + if((ptr = rtstrstr(buffer, temp_buf)) != NULL) + return (ptr+strlen("\n")); + else + return NULL; +} + +/* + ======================================================================== + + Routine Description: + Get key parameter. + + Arguments: + key Pointer to key string + dest Pointer to destination + destsize The datasize of the destination + buffer Pointer to the buffer to start find the key + bTrimSpace Set true if you want to strip the space character of the result pattern + + Return Value: + TRUE Success + FALSE Fail + + Note: + This routine get the value with the matched key (case case-sensitive) + For SSID and security key related parameters, we SHALL NOT trim the space(' ') character. + ======================================================================== +*/ +INT RTMPGetKeyParameter( + IN PSTRING key, + OUT PSTRING dest, + IN INT destsize, + IN PSTRING buffer, + IN BOOLEAN bTrimSpace) +{ + PSTRING pMemBuf, temp_buf1 = NULL, temp_buf2 = NULL; + PSTRING start_ptr, end_ptr; + PSTRING ptr; + PSTRING offset = NULL; + INT len, keyLen; + + + keyLen = strlen(key); + os_alloc_mem(NULL, (PUCHAR *)&pMemBuf, MAX_PARAM_BUFFER_SIZE * 2); + if (pMemBuf == NULL) + return (FALSE); + + memset(pMemBuf, 0, MAX_PARAM_BUFFER_SIZE * 2); + temp_buf1 = pMemBuf; + temp_buf2 = (PSTRING)(pMemBuf + MAX_PARAM_BUFFER_SIZE); + + + //find section + if((offset = RTMPFindSection(buffer)) == NULL) + { + os_free_mem(NULL, (PUCHAR)pMemBuf); + return (FALSE); + } + + strcpy(temp_buf1, "\n"); + strcat(temp_buf1, key); + strcat(temp_buf1, "="); + + //search key + if((start_ptr=rtstrstr(offset, temp_buf1)) == NULL) + { + os_free_mem(NULL, (PUCHAR)pMemBuf); + return (FALSE); + } + + start_ptr += strlen("\n"); + if((end_ptr = rtstrstr(start_ptr, "\n"))==NULL) + end_ptr = start_ptr+strlen(start_ptr); + + if (end_ptr= 1 ) && (KeyIdx <= 4)) + pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1); + else + pAd->StaCfg.DefaultKeyId = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId)); + } + } + + + for (idx = 0; idx < 4; idx++) + { + sprintf(tok_str, "Key%dType", idx + 1); + //Key1Type + if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, TRUE)) + { + for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) + { + /* + do sanity check for KeyType length; + or in station mode, the KeyType length > 1, + the code will overwrite the stack of caller + (RTMPSetProfileParameters) and cause srcbuf = NULL + */ + if (i < MAX_MBSSID_NUM) + KeyType[i] = simple_strtol(macptr, 0, 10); + } + + { + sprintf(tok_str, "Key%dStr", idx + 1); + if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, FALSE)) + { + rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx); + } + } + } + } +} + + + +static void rtmp_read_sta_wmm_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer) +{ + PSTRING macptr; + INT i=0; + BOOLEAN bWmmEnable = FALSE; + + //WmmCapable + if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable + { + pAd->CommonCfg.bWmmCapable = TRUE; + bWmmEnable = TRUE; + } + else //Disable + { + pAd->CommonCfg.bWmmCapable = FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable)); + } + + + //AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO + if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer, TRUE)) + { + for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) + { + pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10); + + DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i])); + } + } + + if (bWmmEnable) + { + //APSDCapable + if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable + pAd->CommonCfg.bAPSDCapable = TRUE; + else + pAd->CommonCfg.bAPSDCapable = FALSE; + + DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable)); + } + + //MaxSPLength + if(RTMPGetKeyParameter("MaxSPLength", tmpbuf, 10, buffer, TRUE)) + { + pAd->CommonCfg.MaxSPLength = simple_strtol(tmpbuf, 0, 10); + + DBGPRINT(RT_DEBUG_TRACE, ("MaxSPLength=%d\n", pAd->CommonCfg.MaxSPLength)); + } + + //APSDAC for AC_BE, AC_BK, AC_VI, AC_VO + if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer, TRUE)) + { + BOOLEAN apsd_ac[4]; + + for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) + { + apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10); + + DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d %d\n", i, apsd_ac[i])); + } + + pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0]; + pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1]; + pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2]; + pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3]; + + pAd->CommonCfg.bACMAPSDTr[0] = apsd_ac[0]; + pAd->CommonCfg.bACMAPSDTr[1] = apsd_ac[1]; + pAd->CommonCfg.bACMAPSDTr[2] = apsd_ac[2]; + pAd->CommonCfg.bACMAPSDTr[3] = apsd_ac[3]; + } + } + +} + + +static void HTParametersHook( + IN PRTMP_ADAPTER pAd, + IN PSTRING pValueStr, + IN PSTRING pInput) +{ + + long Value; + + if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.bHTProtect = FALSE; + } + else + { + pAd->CommonCfg.bHTProtect = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection = %s\n", (Value==0) ? "Disable" : "Enable")); + } + + if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.bMIMOPSEnable = FALSE; + } + else + { + pAd->CommonCfg.bMIMOPSEnable = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable = %s\n", (Value==0) ? "Disable" : "Enable")); + } + + + if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value > MMPS_ENABLE) + { + pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE; + } + else + { + //TODO: add mimo power saving mechanism + pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE; + //pAd->CommonCfg.BACapability.field.MMPSmode = Value; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode = %d\n", (INT) Value)); + } + + if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.bBADecline = FALSE; + } + else + { + pAd->CommonCfg.bBADecline = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline = %s\n", (Value==0) ? "Disable" : "Enable")); + } + + + if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.bDisableReordering = FALSE; + } + else + { + pAd->CommonCfg.bDisableReordering = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering = %s\n", (Value==0) ? "Disable" : "Enable")); + } + + if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.BACapability.field.AutoBA = FALSE; + pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE; + } + else + { + pAd->CommonCfg.BACapability.field.AutoBA = TRUE; + pAd->CommonCfg.BACapability.field.Policy = IMMED_BA; + } + pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA; + DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA = %s\n", (Value==0) ? "Disable" : "Enable")); + } + + // Tx_+HTC frame + if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->HTCEnable = FALSE; + } + else + { + pAd->HTCEnable = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable")); + } + + // Enable HT Link Adaptation Control + if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->bLinkAdapt = FALSE; + } + else + { + pAd->HTCEnable = TRUE; + pAd->bLinkAdapt = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)")); + } + + // Reverse Direction Mechanism + if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.bRdg = FALSE; + } + else + { + pAd->HTCEnable = TRUE; + pAd->CommonCfg.bRdg = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)")); + } + + + + + // Tx A-MSUD ? + if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE; + } + else + { + pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable")); + } + + // MPDU Density + if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value <=7 && Value >= 0) + { + pAd->CommonCfg.BACapability.field.MpduDensity = Value; + DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", (INT) Value)); + } + else + { + pAd->CommonCfg.BACapability.field.MpduDensity = 4; + DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4)); + } + } + + // Max Rx BA Window Size + if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + + if (Value >=1 && Value <= 64) + { + pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value; + pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value; + DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", (INT) Value)); + } + else + { + pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64; + pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; + DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n")); + } + + } + + // Guard Interval + if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + + if (Value == GI_400) + { + pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400; + } + else + { + pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800; + } + + DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" )); + } + + // HT Operation Mode : Mixed Mode , Green Field + if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + + if (Value == HTMODE_GF) + { + + pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF; + } + else + { + pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM; + } + + DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" )); + } + + // Fixed Tx mode : CCK, OFDM + if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput, TRUE)) + { + UCHAR fix_tx_mode; + + { + fix_tx_mode = FIXED_TXMODE_HT; + + if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0) + { + fix_tx_mode = FIXED_TXMODE_OFDM; + } + else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0) + { + fix_tx_mode = FIXED_TXMODE_CCK; + } + else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0) + { + fix_tx_mode = FIXED_TXMODE_HT; + } + else + { + Value = simple_strtol(pValueStr, 0, 10); + // 1 : CCK + // 2 : OFDM + // otherwise : HT + if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM) + fix_tx_mode = Value; + else + fix_tx_mode = FIXED_TXMODE_HT; + } + + pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode; + DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode)); + + } + } + + + // Channel Width + if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + + if (Value == BW_40) + { + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; + } + else + { + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; + } + +#ifdef MCAST_RATE_SPECIFIC + pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW; +#endif // MCAST_RATE_SPECIFIC // + + DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" )); + } + + if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + + if (Value == 0) + { + + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW; + } + else + { + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" )); + } + + // MSC + if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput, TRUE)) + { + { + Value = simple_strtol(pValueStr, 0, 10); + +// if ((Value >= 0 && Value <= 15) || (Value == 32)) + if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3 + { + pAd->StaCfg.DesiredTransmitSetting.field.MCS = Value; + pAd->StaCfg.bAutoTxRateSwitch = FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS)); + } + else + { + pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO; + pAd->StaCfg.bAutoTxRateSwitch = TRUE; + DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n")); + } + } + } + + // STBC + if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == STBC_USE) + { + pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE; + } + else + { + pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC)); + } + + // 40_Mhz_Intolerant + if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE; + } + else + { + pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant)); + } + //HT_TxStream + if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput, TRUE)) + { + switch (simple_strtol(pValueStr, 0, 10)) + { + case 1: + pAd->CommonCfg.TxStream = 1; + break; + case 2: + pAd->CommonCfg.TxStream = 2; + break; + case 3: // 3*3 + default: + pAd->CommonCfg.TxStream = 3; + + if (pAd->MACVersion < RALINK_2883_VERSION) + pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream)); + } + //HT_RxStream + if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput, TRUE)) + { + switch (simple_strtol(pValueStr, 0, 10)) + { + case 1: + pAd->CommonCfg.RxStream = 1; + break; + case 2: + pAd->CommonCfg.RxStream = 2; + break; + case 3: + default: + pAd->CommonCfg.RxStream = 3; + + if (pAd->MACVersion < RALINK_2883_VERSION) + pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream)); + } + //2008/11/05: KH add to support Antenna power-saving of AP<-- + //Green AP + if(RTMPGetKeyParameter("GreenAP", pValueStr, 10, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + if (Value == 0) + { + pAd->CommonCfg.bGreenAPEnable = FALSE; + } + else + { + pAd->CommonCfg.bGreenAPEnable = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("HT: Green AP= %d\n", pAd->CommonCfg.bGreenAPEnable)); + } + + // HT_DisallowTKIP + if (RTMPGetKeyParameter("HT_DisallowTKIP", pValueStr, 25, pInput, TRUE)) + { + Value = simple_strtol(pValueStr, 0, 10); + + if (Value == 1) + { + pAd->CommonCfg.HT_DisallowTKIP = TRUE; + } + else + { + pAd->CommonCfg.HT_DisallowTKIP = FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("HT: Disallow TKIP mode = %s\n", (pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "ON" : "OFF" )); + } + + + //2008/11/05:KH add to support Antenna power-saving of AP--> +} + + +NDIS_STATUS RTMPSetProfileParameters( + IN RTMP_ADAPTER *pAd, + IN PSTRING pBuffer) +{ + PSTRING tmpbuf; + ULONG RtsThresh; + ULONG FragThresh; + PSTRING macptr; + INT i = 0, retval; + tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG); + if(tmpbuf == NULL) + return NDIS_STATUS_FAILURE; + + do + { + // set file parameter to portcfg + //CountryRegion + if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, pBuffer, TRUE)) + { + retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_24G); + DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion)); + } + //CountryRegionABand + if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, pBuffer, TRUE)) + { + retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_5G); + DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand)); + } +#ifdef RTMP_EFUSE_SUPPORT +#ifdef RT30xx + //EfuseBufferMode + if(RTMPGetKeyParameter("EfuseBufferMode", tmpbuf, 25, pBuffer, TRUE)) + { + pAd->bEEPROMFile = (UCHAR) simple_strtol(tmpbuf, 0, 10); + DBGPRINT(RT_DEBUG_TRACE, ("EfuseBufferMode=%d\n", pAd->bUseEfuse)); + } +#endif // RT30xx // +#endif // RTMP_EFUSE_SUPPORT // + //CountryCode + if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, pBuffer, TRUE)) + { + NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2); + if (strlen((PSTRING) pAd->CommonCfg.CountryCode) != 0) + { + pAd->CommonCfg.bCountryFlag = TRUE; + } + DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode)); + } + //ChannelGeography + if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, pBuffer, TRUE)) + { + UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10); + if (Geography <= BOTH) + { + pAd->CommonCfg.Geography = Geography; + pAd->CommonCfg.CountryCode[2] = + (pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O'); + DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography)); + } + } + else + { + pAd->CommonCfg.Geography = BOTH; + pAd->CommonCfg.CountryCode[2] = ' '; + } + + { + //SSID + if (RTMPGetKeyParameter("SSID", tmpbuf, 256, pBuffer, FALSE)) + { + if (strlen(tmpbuf) <= 32) + { + pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf); + NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID); + NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen); + pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen; + NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID); + NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen); + pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen; + NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID); + NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen); + DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __func__, tmpbuf)); + } + } + } + + { + //NetworkType + if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, pBuffer, TRUE)) + { + pAd->bConfigChanged = TRUE; + if (strcmp(tmpbuf, "Adhoc") == 0) + pAd->StaCfg.BssType = BSS_ADHOC; + else //Default Infrastructure mode + pAd->StaCfg.BssType = BSS_INFRA; + // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key + pAd->StaCfg.WpaState = SS_NOTUSE; + DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __func__, pAd->StaCfg.BssType)); + } + } + //Channel + if(RTMPGetKeyParameter("Channel", tmpbuf, 10, pBuffer, TRUE)) + { + pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10); + DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel)); + } + //WirelessMode + if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, pBuffer, TRUE)) + { + RT_CfgSetWirelessMode(pAd, tmpbuf); + DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode)); + } + //BasicRate + if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, pBuffer, TRUE)) + { + pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10); + DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap)); + } + //BeaconPeriod + if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, pBuffer, TRUE)) + { + pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10); + DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod)); + } + //TxPower + if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, pBuffer, TRUE)) + { + pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10); + pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage; + DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage)); + } + //BGProtection + if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, pBuffer, TRUE)) + { + //#if 0 //#ifndef WIFI_TEST + // pAd->CommonCfg.UseBGProtection = 2;// disable b/g protection for throughput test + //#else + switch (simple_strtol(tmpbuf, 0, 10)) + { + case 1: //Always On + pAd->CommonCfg.UseBGProtection = 1; + break; + case 2: //Always OFF + pAd->CommonCfg.UseBGProtection = 2; + break; + case 0: //AUTO + default: + pAd->CommonCfg.UseBGProtection = 0; + break; + } + //#endif + DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection)); + } + //OLBCDetection + if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, pBuffer, TRUE)) + { + switch (simple_strtol(tmpbuf, 0, 10)) + { + case 1: //disable OLBC Detection + pAd->CommonCfg.DisableOLBCDetect = 1; + break; + case 0: //enable OLBC Detection + pAd->CommonCfg.DisableOLBCDetect = 0; + break; + default: + pAd->CommonCfg.DisableOLBCDetect= 0; + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect)); + } + //TxPreamble + if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, pBuffer, TRUE)) + { + switch (simple_strtol(tmpbuf, 0, 10)) + { + case Rt802_11PreambleShort: + pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort; + break; + case Rt802_11PreambleLong: + default: + pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong; + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble)); + } + //RTSThreshold + if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, pBuffer, TRUE)) + { + RtsThresh = simple_strtol(tmpbuf, 0, 10); + if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) ) + pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh; + else + pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD; + + DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold)); + } + //FragThreshold + if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, pBuffer, TRUE)) + { + FragThresh = simple_strtol(tmpbuf, 0, 10); + pAd->CommonCfg.bUseZeroToDisableFragment = FALSE; + + if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD) + { //illegal FragThresh so we set it to default + pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD; + pAd->CommonCfg.bUseZeroToDisableFragment = TRUE; + } + else if (FragThresh % 2 == 1) + { + // The length of each fragment shall always be an even number of octets, except for the last fragment + // of an MSDU or MMPDU, which may be either an even or an odd number of octets. + pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1); + } + else + { + pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh; + } + //pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC; + DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold)); + } + //TxBurst + if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, pBuffer, TRUE)) + { + //#ifdef WIFI_TEST + // pAd->CommonCfg.bEnableTxBurst = FALSE; + //#else + if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable + pAd->CommonCfg.bEnableTxBurst = TRUE; + else //Disable + pAd->CommonCfg.bEnableTxBurst = FALSE; + //#endif + DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst)); + } + +#ifdef AGGREGATION_SUPPORT + //PktAggregate + if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable + pAd->CommonCfg.bAggregationCapable = TRUE; + else //Disable + pAd->CommonCfg.bAggregationCapable = FALSE; +#ifdef PIGGYBACK_SUPPORT + pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable; +#endif // PIGGYBACK_SUPPORT // + DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable)); + } +#else + pAd->CommonCfg.bAggregationCapable = FALSE; + pAd->CommonCfg.bPiggyBackCapable = FALSE; +#endif // AGGREGATION_SUPPORT // + + // WmmCapable + + rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, pBuffer); + + //ShortSlot + if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, pBuffer, TRUE)) + { + RT_CfgSetShortSlot(pAd, tmpbuf); + DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime)); + } + //IEEE80211H + if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, pBuffer, TRUE)) + { + for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) + { + if(simple_strtol(macptr, 0, 10) != 0) //Enable + pAd->CommonCfg.bIEEE80211H = TRUE; + else //Disable + pAd->CommonCfg.bIEEE80211H = FALSE; + + DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H)); + } + } + //CSPeriod + if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) + pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10); + else + pAd->CommonCfg.RadarDetect.CSPeriod = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod)); + } + +#ifdef MERGE_ARCH_TEAM + // DfsLowerLimit + if(RTMPGetKeyParameter("DfsLowerLimit", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) + pAd->CommonCfg.RadarDetect.DfsLowerLimit = simple_strtol(tmpbuf, 0, 10); + + DBGPRINT(RT_DEBUG_TRACE, ("DfsLowerLimit=%ld\n", pAd->CommonCfg.RadarDetect.DfsLowerLimit)); + } + + // DfsUpperLimit + if(RTMPGetKeyParameter("DfsUpperLimit", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) + pAd->CommonCfg.RadarDetect.DfsUpperLimit = simple_strtol(tmpbuf, 0, 10); + + DBGPRINT(RT_DEBUG_TRACE, ("DfsUpperLimit=%ld\n", pAd->CommonCfg.RadarDetect.DfsUpperLimit)); + } + + // FixDfsLimit + if(RTMPGetKeyParameter("FixDfsLimit", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) + pAd->CommonCfg.RadarDetect.FixDfsLimit = TRUE; + else + pAd->CommonCfg.RadarDetect.FixDfsLimit = FALSE; + + DBGPRINT(RT_DEBUG_TRACE, ("FixDfsLimit=%d\n", pAd->CommonCfg.RadarDetect.FixDfsLimit)); + } + + // LongPulseRadarTh + if(RTMPGetKeyParameter("LongPulseRadarTh", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) + pAd->CommonCfg.RadarDetect.LongPulseRadarTh = simple_strtol(tmpbuf, 0, 10); + + DBGPRINT(RT_DEBUG_TRACE, ("LongPulseRadarTh=%d\n", pAd->CommonCfg.RadarDetect.LongPulseRadarTh)); + } + + // AvgRssiReq + if(RTMPGetKeyParameter("AvgRssiReq", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) + pAd->CommonCfg.RadarDetect.AvgRssiReq = simple_strtol(tmpbuf, 0, 10); + + DBGPRINT(RT_DEBUG_TRACE, ("AvgRssiReq=%d\n", pAd->CommonCfg.RadarDetect.AvgRssiReq)); + } + +#endif // MERGE_ARCH_TEAM // + + //RDRegion + if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, pBuffer, TRUE)) + { + RADAR_DETECT_STRUCT *pRadarDetect = &pAd->CommonCfg.RadarDetect; + if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0)) + { + pRadarDetect->RDDurRegion = JAP_W53; + pRadarDetect->DfsSessionTime = 15; + } + else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0)) + { + pRadarDetect->RDDurRegion = JAP_W56; + pRadarDetect->DfsSessionTime = 13; + } + else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0)) + { + pRadarDetect->RDDurRegion = JAP; + pRadarDetect->DfsSessionTime = 5; + } + else if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0)) + { + pRadarDetect->RDDurRegion = FCC; + pRadarDetect->DfsSessionTime = 5; +#ifdef DFS_FCC_BW40_FIX + pRadarDetect->DfsSessionFccOff = 0; +#endif // DFS_FCC_BW40_FIX // + } + else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0)) + { + pRadarDetect->RDDurRegion = CE; + pRadarDetect->DfsSessionTime = 13; + } + else + { + pRadarDetect->RDDurRegion = CE; + pRadarDetect->DfsSessionTime = 13; + } + + DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pRadarDetect->RDDurRegion)); + } + else + { + pAd->CommonCfg.RadarDetect.RDDurRegion = CE; + pAd->CommonCfg.RadarDetect.DfsSessionTime = 13; + } + + //WirelessEvent + if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) + pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10); + else + pAd->CommonCfg.bWirelessEvent = 0; // disable + DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent)); + } + if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) != 0) + pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10); + else + pAd->CommonCfg.bWiFiTest = 0; // disable + + DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest)); + } + //AuthMode + if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, pBuffer, TRUE)) + { + { + if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch; + else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared; + else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK; + else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone; + else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK; + else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA; + else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0)) + pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2; + else + pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen; + + pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; + + DBGPRINT(RT_DEBUG_TRACE, ("%s::(AuthMode=%d)\n", __func__, pAd->StaCfg.AuthMode)); + } + } + //EncrypType + if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, pBuffer, TRUE)) + { + { + if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0)) + pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled; + else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0)) + pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled; + else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0)) + pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled; + else + pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled; + + // Update all wepstatus related + pAd->StaCfg.PairCipher = pAd->StaCfg.WepStatus; + pAd->StaCfg.GroupCipher = pAd->StaCfg.WepStatus; + pAd->StaCfg.OrigWepStatus = pAd->StaCfg.WepStatus; + pAd->StaCfg.bMixCipher = FALSE; + + //RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0); + DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus)); + } + } + + { + if(RTMPGetKeyParameter("WPAPSK", tmpbuf, 512, pBuffer, FALSE)) + { + int ret = TRUE; + + tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input + + if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) && + (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) && + (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) + ) + { + ret = FALSE; + } + else + { + ret = RT_CfgSetWPAPSKKey(pAd, tmpbuf, (PUCHAR)pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->StaCfg.PMK); + } + + if (ret == TRUE) + { + RTMPZeroMemory(pAd->StaCfg.WpaPassPhrase, 64); + RTMPMoveMemory(pAd->StaCfg.WpaPassPhrase, tmpbuf, strlen(tmpbuf)); + pAd->StaCfg.WpaPassPhraseLen= strlen(tmpbuf); + + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + // Start STA supplicant state machine + pAd->StaCfg.WpaState = SS_START; + } + else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) + { + pAd->StaCfg.WpaState = SS_NOTUSE; + } + DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __func__, tmpbuf)); + } + } + } + + //DefaultKeyID, KeyType, KeyStr + rtmp_read_key_parms_from_file(pAd, tmpbuf, pBuffer); + + + //HSCounter + /*if(RTMPGetKeyParameter("HSCounter", tmpbuf, 10, pBuffer, TRUE)) + { + switch (simple_strtol(tmpbuf, 0, 10)) + { + case 1: //Enable + pAd->CommonCfg.bEnableHSCounter = TRUE; + break; + case 0: //Disable + default: + pAd->CommonCfg.bEnableHSCounter = FALSE; + break; + } + DBGPRINT(RT_DEBUG_TRACE, "HSCounter=%d\n", pAd->CommonCfg.bEnableHSCounter); + }*/ + + HTParametersHook(pAd, tmpbuf, pBuffer); + + { + //PSMode + if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, pBuffer, TRUE)) + { + if (pAd->StaCfg.BssType == BSS_INFRA) + { + if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0)) + { + // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange() + // to exclude certain situations. + // MlmeSetPsm(pAd, PWR_SAVE); + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); + if (pAd->StaCfg.bWindowsACCAMEnable == FALSE) + pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP; + pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP; + pAd->StaCfg.DefaultListenCount = 5; + } + else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0) + || (strcmp(tmpbuf, "FAST_PSP") == 0)) + { + // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange() + // to exclude certain situations. + // RTMP_SET_PSM_BIT(pAd, PWR_SAVE); + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); + if (pAd->StaCfg.bWindowsACCAMEnable == FALSE) + pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP; + pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP; + pAd->StaCfg.DefaultListenCount = 3; + } + else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0) + || (strcmp(tmpbuf, "LEGACY_PSP") == 0)) + { + // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange() + // to exclude certain situations. + // RTMP_SET_PSM_BIT(pAd, PWR_SAVE); + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); + if (pAd->StaCfg.bWindowsACCAMEnable == FALSE) + pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP; + pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP; + pAd->StaCfg.DefaultListenCount = 3; + } + else + { //Default Ndis802_11PowerModeCAM + // clear PSM bit immediately + RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE); + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); + if (pAd->StaCfg.bWindowsACCAMEnable == FALSE) + pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM; + pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM; + } + DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode)); + } + } + // AutoRoaming by RSSI + if (RTMPGetKeyParameter("AutoRoaming", tmpbuf, 32, pBuffer, TRUE)) + { + if (simple_strtol(tmpbuf, 0, 10) == 0) + pAd->StaCfg.bAutoRoaming = FALSE; + else + pAd->StaCfg.bAutoRoaming = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("AutoRoaming=%d\n", pAd->StaCfg.bAutoRoaming)); + } + // RoamThreshold + if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, pBuffer, TRUE)) + { + long lInfo = simple_strtol(tmpbuf, 0, 10); + + if (lInfo > 90 || lInfo < 60) + pAd->StaCfg.dBmToRoam = -70; + else + pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo; + + DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d dBm\n", pAd->StaCfg.dBmToRoam)); + } + + if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, pBuffer, TRUE)) + { + if(simple_strtol(tmpbuf, 0, 10) == 0) + pAd->StaCfg.bTGnWifiTest = FALSE; + else + pAd->StaCfg.bTGnWifiTest = TRUE; + DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest)); + } + + // Beacon Lost Time + if (RTMPGetKeyParameter("BeaconLostTime", tmpbuf, 32, pBuffer, TRUE)) + { + ULONG lInfo = (ULONG)simple_strtol(tmpbuf, 0, 10); + + if ((lInfo != 0) && (lInfo <= 60)) + pAd->StaCfg.BeaconLostTime = (lInfo * OS_HZ); + DBGPRINT(RT_DEBUG_TRACE, ("BeaconLostTime=%ld \n", pAd->StaCfg.BeaconLostTime)); + } + + + } + + + + + }while(0); + + + kfree(tmpbuf); + + return NDIS_STATUS_SUCCESS; + +} Index: b/drivers/staging/rt2860/common/cmm_sanity.c =================================================================== --- a/drivers/staging/rt2860/common/cmm_sanity.c +++ b/drivers/staging/rt2860/common/cmm_sanity.c @@ -81,6 +81,14 @@ BOOLEAN MlmeAddBAReqSanity( return FALSE; } + /* + if ((pInfo->BaBufSize > MAX_RX_REORDERBUF) || (pInfo->BaBufSize < 2)) + { + DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - Rx Reordering buffer too big or too small\n")); + return FALSE; + } + */ + if ((pInfo->pAddr[0]&0x01) == 0x01) { DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n")); @@ -151,7 +159,17 @@ BOOLEAN PeerAddBAReqActionSanity( return FALSE; } // we support immediate BA. +#ifdef UNALIGNMENT_SUPPORT + { + BA_PARM tmpBaParm; + + NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&pAddFrame->BaParm), sizeof(BA_PARM)); + *(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm)); + NdisMoveMemory((PUCHAR)(&pAddFrame->BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM)); + } +#else *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm)); +#endif pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue); pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word); @@ -177,6 +195,7 @@ BOOLEAN PeerAddBARspActionSanity( IN VOID *pMsg, IN ULONG MsgLen) { + //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg; PFRAME_ADDBA_RSP pAddFrame; pAddFrame = (PFRAME_ADDBA_RSP)(pMsg); @@ -186,7 +205,17 @@ BOOLEAN PeerAddBARspActionSanity( return FALSE; } // we support immediate BA. +#ifdef UNALIGNMENT_SUPPORT + { + BA_PARM tmpBaParm; + + NdisMoveMemory((PUCHAR)(&tmpBaParm), (PUCHAR)(&pAddFrame->BaParm), sizeof(BA_PARM)); + *(USHORT *)(&tmpBaParm) = cpu2le16(*(USHORT *)(&tmpBaParm)); + NdisMoveMemory((PUCHAR)(&pAddFrame->BaParm), (PUCHAR)(&tmpBaParm), sizeof(BA_PARM)); + } +#else *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm)); +#endif pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode); pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue); @@ -283,8 +312,8 @@ BOOLEAN PeerBeaconAndProbeRspSanity( OUT USHORT *LengthVIE, OUT PNDIS_802_11_VARIABLE_IEs pVIE) { - CHAR *Ptr; - CHAR TimLen; + UCHAR *Ptr; + UCHAR TimLen; PFRAME_802_11 pFrame; PEID_STRUCT pEid; UCHAR SubType; @@ -332,6 +361,8 @@ BOOLEAN PeerBeaconAndProbeRspSanity( COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3); +// hex_dump("Beacon", Msg, MsgLen); + Ptr = pFrame->Octet; Length += LENGTH_802_11; @@ -420,10 +451,19 @@ BOOLEAN PeerBeaconAndProbeRspSanity( *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes. *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo)); +#ifdef UNALIGNMENT_SUPPORT + { + EXT_HT_CAP_INFO extHtCapInfo; + NdisMoveMemory((PUCHAR)(&extHtCapInfo), (PUCHAR)(&pHtCapability->ExtHtCapInfo), sizeof(EXT_HT_CAP_INFO)); + *(USHORT *)(&extHtCapInfo) = cpu2le16(*(USHORT *)(&extHtCapInfo)); + NdisMoveMemory((PUCHAR)(&pHtCapability->ExtHtCapInfo), (PUCHAR)(&extHtCapInfo), sizeof(EXT_HT_CAP_INFO)); + } +#else *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo)); +#endif // UNALIGNMENT_SUPPORT // { - *pPreNHtCapabilityLen = 0; // Nnow we only support 26 bytes. + *pPreNHtCapabilityLen = 0; // Now we only support 26 bytes. Ptr = (PUCHAR) pVIE; NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2); @@ -529,10 +569,9 @@ BOOLEAN PeerBeaconAndProbeRspSanity( case IE_TIM: if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON) { - GetTimBit((PUCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe); + GetTimBit((PCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe); } break; - case IE_CHANNEL_SWITCH_ANNOUNCEMENT: if(pEid->Len == 3) { @@ -545,6 +584,26 @@ BOOLEAN PeerBeaconAndProbeRspSanity( // Wifi WMM use the same IE vale, need to parse that too // case IE_WPA: case IE_VENDOR_SPECIFIC: + // Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE. + // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. + /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4)) + { + if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30)) + { + { + NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE)); + *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes. + } + } + if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26)) + { + { + NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE)); + *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes. + } + } + } + */ // Check the OUI version, filter out non-standard usage if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7)) { @@ -638,6 +697,8 @@ BOOLEAN PeerBeaconAndProbeRspSanity( pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1; pEdcaParm->Txop[QID_AC_VO] = 48; // AC_VO: 48*32us ~= 1.5ms } + + break; case IE_EXT_SUPP_RATES: @@ -718,7 +779,7 @@ BOOLEAN PeerBeaconAndProbeRspSanity( if (Sanity != 0x7) { - DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity)); + DBGPRINT(RT_DEBUG_LOUD, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity)); return FALSE; } else @@ -755,8 +816,6 @@ BOOLEAN MlmeScanReqSanity( if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY) && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE - || *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE - || *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE )) { return TRUE; @@ -837,8 +896,7 @@ BOOLEAN PeerAuthSanity( NdisMoveMemory(pSeq, &pFrame->Octet[2], 2); NdisMoveMemory(pStatus, &pFrame->Octet[4], 2); - if ((*pAlg == Ndis802_11AuthModeOpen) - ) + if (*pAlg == AUTH_MODE_OPEN) { if (*pSeq == 1 || *pSeq == 2) { @@ -850,7 +908,7 @@ BOOLEAN PeerAuthSanity( return FALSE; } } - else if (*pAlg == Ndis802_11AuthModeShared) + else if (*pAlg == AUTH_MODE_KEY) { if (*pSeq == 1 || *pSeq == 4) { @@ -897,7 +955,7 @@ BOOLEAN MlmeAuthReqSanity( *pTimeout = pInfo->Timeout; *pAlg = pInfo->Alg; - if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen) + if (((*pAlg == AUTH_MODE_KEY) ||(*pAlg == AUTH_MODE_OPEN) ) && ((*pAddr & 0x01) == 0)) { @@ -1052,3 +1110,196 @@ NDIS_802_11_NETWORK_TYPE NetworkTypeInUs return NetWorkType; } + +/* + ========================================================================== + Description: + Check the validity of the received EAPoL frame + Return: + TRUE if all parameters are OK, + FALSE otherwise + ========================================================================== + */ +BOOLEAN PeerWpaMessageSanity( + IN PRTMP_ADAPTER pAd, + IN PEAPOL_PACKET pMsg, + IN ULONG MsgLen, + IN UCHAR MsgType, + IN MAC_TABLE_ENTRY *pEntry) +{ + UCHAR mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE]; + BOOLEAN bReplayDiff = FALSE; + BOOLEAN bWPA2 = FALSE; + KEY_INFO EapolKeyInfo; + UCHAR GroupKeyIndex = 0; + + + NdisZeroMemory(mic, sizeof(mic)); + NdisZeroMemory(digest, sizeof(digest)); + NdisZeroMemory(KEYDATA, sizeof(KEYDATA)); + NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo)); + + NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO)); + + *((USHORT *)&EapolKeyInfo) = cpu2le16(*((USHORT *)&EapolKeyInfo)); + + // Choose WPA2 or not + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) + bWPA2 = TRUE; + + // 0. Check MsgType + if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1)) + { + DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType)); + return FALSE; + } + + // 1. Replay counter check + if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) // For supplicant + { + // First validate replay counter, only accept message with larger replay counter. + // Let equal pass, some AP start with all zero replay counter + UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY]; + + NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY); + if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) && + (RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0)) + { + bReplayDiff = TRUE; + } + } + else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) // For authenticator + { + // check Replay Counter coresponds to MSG from authenticator, otherwise discard + if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY)) + { + bReplayDiff = TRUE; + } + } + + // Replay Counter different condition + if (bReplayDiff) + { + // send wireless event - for replay counter different + if (pAd->CommonCfg.bWirelessEvent) + RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + if (MsgType < EAPOL_GROUP_MSG_1) + { + DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType)); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4))); + } + + hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); + hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY); + return FALSE; + } + + // 2. Verify MIC except Pairwise Msg1 + if (MsgType != EAPOL_PAIR_MSG_1) + { + UCHAR rcvd_mic[LEN_KEY_DESC_MIC]; + + // Record the received MIC for check later + NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); + NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); + + if (EapolKeyInfo.KeyDescVer == DESC_TYPE_TKIP) // TKIP + { + HMAC_MD5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic, MD5_DIGEST_SIZE); + } + else if (EapolKeyInfo.KeyDescVer == DESC_TYPE_AES) // AES + { + HMAC_SHA1(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, digest, SHA1_DIGEST_SIZE); + NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); + } + + if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC)) + { + // send wireless event - for MIC different + if (pAd->CommonCfg.bWirelessEvent) + RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + if (MsgType < EAPOL_GROUP_MSG_1) + { + DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType)); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4))); + } + + hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC); + hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC); + + return FALSE; + } + } + + // 1. Decrypt the Key Data field if GTK is included. + // 2. Extract the context of the Key Data field if it exist. + // The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is clear. + // The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted. + if (CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen) > 0) + { + // Decrypt this field + if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1)) + { + if( + (EapolKeyInfo.KeyDescVer == DESC_TYPE_AES)) + { + // AES + AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA, + CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen), + pMsg->KeyDesc.KeyData); + } + else + { + INT i; + UCHAR Key[32]; + // Decrypt TKIP GTK + // Construct 32 bytes RC4 Key + NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16); + NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16); + ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32); + //discard first 256 bytes + for(i = 0; i < 256; i++) + ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT); + // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not + ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, + pMsg->KeyDesc.KeyData, + CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen)); + } + + if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) + GroupKeyIndex = EapolKeyInfo.KeyIndex; + + } + else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2)) + { + NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen)); + } + else + { + + return TRUE; + } + + // Parse Key Data field to + // 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2) + // 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2 + // 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2) + if (!RTMPParseEapolKeyData(pAd, KEYDATA, + CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyDataLen), + GroupKeyIndex, MsgType, bWPA2, pEntry)) + { + return FALSE; + } + } + + return TRUE; + +} Index: b/drivers/staging/rt2860/common/cmm_sync.c =================================================================== --- a/drivers/staging/rt2860/common/cmm_sync.c +++ b/drivers/staging/rt2860/common/cmm_sync.c @@ -25,7 +25,7 @@ ************************************************************************* Module Name: - sync.c + cmm_sync.c Abstract: @@ -64,11 +64,16 @@ UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52 UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165}; UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161}; UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48}; -UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}; +UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 169, 173}; UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64}; UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}; UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165}; UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161}; +UCHAR A_BAND_REGION_12_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}; +UCHAR A_BAND_REGION_13_CHANNEL_LIST[]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161}; +UCHAR A_BAND_REGION_14_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}; +UCHAR A_BAND_REGION_15_CHANNEL_LIST[]={149, 153, 157, 161, 165, 169, 173}; + //BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8. UCHAR BaSizeArray[4] = {8,16,32,64}; @@ -200,7 +205,22 @@ VOID BuildChannelList( num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR); pChannelList = A_BAND_REGION_11_CHANNEL_LIST; break; - + case REGION_12_A_BAND: + num = sizeof(A_BAND_REGION_12_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_12_CHANNEL_LIST; + break; + case REGION_13_A_BAND: + num = sizeof(A_BAND_REGION_13_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_13_CHANNEL_LIST; + break; + case REGION_14_A_BAND: + num = sizeof(A_BAND_REGION_14_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_14_CHANNEL_LIST; + break; + case REGION_15_A_BAND: + num = sizeof(A_BAND_REGION_15_CHANNEL_LIST)/sizeof(UCHAR); + pChannelList = A_BAND_REGION_15_CHANNEL_LIST; + break; default: // Error. should never happen DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand)); break; @@ -383,8 +403,11 @@ VOID ScanNextChannel( PHEADER_802_11 pHdr80211; UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME; + { if (MONITOR_ON(pAd)) return; + } + if (pAd->MlmeAux.Channel == 0) { @@ -409,6 +432,19 @@ VOID ScanNextChannel( } { +#ifdef RT2860 + /* + If all peer Ad-hoc clients leave, driver would do LinkDown and LinkUp. + In LinkUp, CommonCfg.Ssid would copy SSID from MlmeAux. + To prevent SSID is zero or wrong in Beacon, need to recover MlmeAux.SSID here. + */ + if (ADHOC_ON(pAd)) + { + NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); + pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen; + NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); + } +#endif // RT2860 // // // To prevent data lost. // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. @@ -438,29 +474,26 @@ VOID ScanNextChannel( MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status); } + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); } -#ifdef RT2870 +#ifdef RTMP_MAC_USB else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA)) { pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE); } -#endif // RT2870 // +#endif // RTMP_MAC_USB // else { { // BBP and RF are not accessible in PS mode, we has to wake them up first if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) -#ifdef RT2860 - AsicForceWakeup(pAd, FROM_TX); -#endif -#ifdef RT2870 AsicForceWakeup(pAd, TRUE); -#endif + // leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON if (pAd->StaCfg.Psm == PWR_SAVE) - MlmeSetPsmBit(pAd, PWR_ACTIVE); + RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE); } AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE); @@ -487,16 +520,6 @@ VOID ScanNextChannel( // Chnage the channel scan time for CISCO stuff based on its IAPP announcement if (ScanType == FAST_SCAN_ACTIVE) RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME); - else if (((ScanType == SCAN_CISCO_ACTIVE) || - (ScanType == SCAN_CISCO_PASSIVE) || - (ScanType == SCAN_CISCO_CHANNEL_LOAD) || - (ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA)) - { - if (pAd->StaCfg.CCXScanTime < 25) - RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2); - else - RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime); - } else // must be SCAN_PASSIVE or SCAN_ACTIVE { if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) @@ -512,8 +535,9 @@ VOID ScanNextChannel( RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME); } - if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) || - (ScanType == SCAN_CISCO_ACTIVE)) + if ((ScanType == SCAN_ACTIVE) + || (ScanType == FAST_SCAN_ACTIVE) + ) { NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory if (NStatus != NDIS_STATUS_SUCCESS) Index: b/drivers/staging/rt2860/common/cmm_tkip.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/cmm_tkip.c @@ -0,0 +1,951 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + cmm_tkip.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Paul Wu 02-25-02 Initial +*/ + +#include "../rt_config.h" + +// Rotation functions on 32 bit values +#define ROL32( A, n ) \ + ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) ) +#define ROR32( A, n ) ROL32( (A), 32-(n) ) + +UINT Tkip_Sbox_Lower[256] = +{ + 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54, + 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A, + 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B, + 0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B, + 0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F, + 0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F, + 0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5, + 0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F, + 0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB, + 0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97, + 0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED, + 0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A, + 0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94, + 0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3, + 0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04, + 0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D, + 0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39, + 0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95, + 0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83, + 0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76, + 0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4, + 0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B, + 0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0, + 0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18, + 0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51, + 0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85, + 0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12, + 0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9, + 0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7, + 0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A, + 0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8, + 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A +}; + +UINT Tkip_Sbox_Upper[256] = +{ + 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91, + 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC, + 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB, + 0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B, + 0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83, + 0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A, + 0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F, + 0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA, + 0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B, + 0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13, + 0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6, + 0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85, + 0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11, + 0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B, + 0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1, + 0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF, + 0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E, + 0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6, + 0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B, + 0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD, + 0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8, + 0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2, + 0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49, + 0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10, + 0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97, + 0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F, + 0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C, + 0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27, + 0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33, + 0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5, + 0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0, + 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C +}; + +// +// Expanded IV for TKIP function. +// +typedef struct PACKED _IV_CONTROL_ +{ + union PACKED + { + struct PACKED + { + UCHAR rc0; + UCHAR rc1; + UCHAR rc2; + + union PACKED + { + struct PACKED + { + UCHAR Rsvd:5; + UCHAR ExtIV:1; + UCHAR KeyID:2; + } field; + UCHAR Byte; + } CONTROL; + } field; + + ULONG word; + } IV16; + + ULONG IV32; +} TKIP_IV, *PTKIP_IV; + + +/* + ======================================================================== + + Routine Description: + Convert from UCHAR[] to ULONG in a portable way + + Arguments: + pMICKey pointer to MIC Key + + Return Value: + None + + Note: + + ======================================================================== +*/ +ULONG RTMPTkipGetUInt32( + IN PUCHAR pMICKey) +{ + ULONG res = 0; + INT i; + + for (i = 0; i < 4; i++) + { + res |= (*pMICKey++) << (8 * i); + } + + return res; +} + +/* + ======================================================================== + + Routine Description: + Convert from ULONG to UCHAR[] in a portable way + + Arguments: + pDst pointer to destination for convert ULONG to UCHAR[] + val the value for convert + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPTkipPutUInt32( + IN OUT PUCHAR pDst, + IN ULONG val) +{ + INT i; + + for(i = 0; i < 4; i++) + { + *pDst++ = (UCHAR) (val & 0xff); + val >>= 8; + } +} + +/* + ======================================================================== + + Routine Description: + Set the MIC Key. + + Arguments: + pAd Pointer to our adapter + pMICKey pointer to MIC Key + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPTkipSetMICKey( + IN PTKIP_KEY_INFO pTkip, + IN PUCHAR pMICKey) +{ + // Set the key + pTkip->K0 = RTMPTkipGetUInt32(pMICKey); + pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4); + // and reset the message + pTkip->L = pTkip->K0; + pTkip->R = pTkip->K1; + pTkip->nBytesInM = 0; + pTkip->M = 0; +} + +/* + ======================================================================== + + Routine Description: + Calculate the MIC Value. + + Arguments: + pAd Pointer to our adapter + uChar Append this uChar + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPTkipAppendByte( + IN PTKIP_KEY_INFO pTkip, + IN UCHAR uChar) +{ + // Append the byte to our word-sized buffer + pTkip->M |= (uChar << (8* pTkip->nBytesInM)); + pTkip->nBytesInM++; + // Process the word if it is full. + if( pTkip->nBytesInM >= 4 ) + { + pTkip->L ^= pTkip->M; + pTkip->R ^= ROL32( pTkip->L, 17 ); + pTkip->L += pTkip->R; + pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8); + pTkip->L += pTkip->R; + pTkip->R ^= ROL32( pTkip->L, 3 ); + pTkip->L += pTkip->R; + pTkip->R ^= ROR32( pTkip->L, 2 ); + pTkip->L += pTkip->R; + // Clear the buffer + pTkip->M = 0; + pTkip->nBytesInM = 0; + } +} + +/* + ======================================================================== + + Routine Description: + Calculate the MIC Value. + + Arguments: + pAd Pointer to our adapter + pSrc Pointer to source data for Calculate MIC Value + Len Indicate the length of the source data + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPTkipAppend( + IN PTKIP_KEY_INFO pTkip, + IN PUCHAR pSrc, + IN UINT nBytes) +{ + // This is simple + while(nBytes > 0) + { + RTMPTkipAppendByte(pTkip, *pSrc++); + nBytes--; + } +} + +/* + ======================================================================== + + Routine Description: + Get the MIC Value. + + Arguments: + pAd Pointer to our adapter + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + the MIC Value is store in pAd->PrivateInfo.MIC + ======================================================================== +*/ +VOID RTMPTkipGetMIC( + IN PTKIP_KEY_INFO pTkip) +{ + // Append the minimum padding + RTMPTkipAppendByte(pTkip, 0x5a ); + RTMPTkipAppendByte(pTkip, 0 ); + RTMPTkipAppendByte(pTkip, 0 ); + RTMPTkipAppendByte(pTkip, 0 ); + RTMPTkipAppendByte(pTkip, 0 ); + // and then zeroes until the length is a multiple of 4 + while( pTkip->nBytesInM != 0 ) + { + RTMPTkipAppendByte(pTkip, 0 ); + } + // The appendByte function has already computed the result. + RTMPTkipPutUInt32(pTkip->MIC, pTkip->L); + RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R); +} + +/* + ======================================================================== + + Routine Description: + Init Tkip function. + + Arguments: + pAd Pointer to our adapter + pTKey Pointer to the Temporal Key (TK), TK shall be 128bits. + KeyId TK Key ID + pTA Pointer to transmitter address + pMICKey pointer to MIC Key + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPInitTkipEngine( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pKey, + IN UCHAR KeyId, + IN PUCHAR pTA, + IN PUCHAR pMICKey, + IN PUCHAR pTSC, + OUT PULONG pIV16, + OUT PULONG pIV32) +{ + TKIP_IV tkipIv; + + // Prepare 8 bytes TKIP encapsulation for MPDU + NdisZeroMemory(&tkipIv, sizeof(TKIP_IV)); + tkipIv.IV16.field.rc0 = *(pTSC + 1); + tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f; + tkipIv.IV16.field.rc2 = *pTSC; + tkipIv.IV16.field.CONTROL.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV + tkipIv.IV16.field.CONTROL.field.KeyID = KeyId; +// tkipIv.IV32 = *(PULONG)(pTSC + 2); + NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); // Copy IV + + *pIV16 = tkipIv.IV16.word; + *pIV32 = tkipIv.IV32; +} + +/* + ======================================================================== + + Routine Description: + Init MIC Value calculation function which include set MIC key & + calculate first 16 bytes (DA + SA + priority + 0) + + Arguments: + pAd Pointer to our adapter + pTKey Pointer to the Temporal Key (TK), TK shall be 128bits. + pDA Pointer to DA address + pSA Pointer to SA address + pMICKey pointer to MIC Key + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID RTMPInitMICEngine( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pKey, + IN PUCHAR pDA, + IN PUCHAR pSA, + IN UCHAR UserPriority, + IN PUCHAR pMICKey) +{ + ULONG Priority = UserPriority; + + // Init MIC value calculation + RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey); + // DA + RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN); + // SA + RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN); + // Priority + 3 bytes of 0 + RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4); +} + +/* + ======================================================================== + + Routine Description: + Compare MIC value of received MSDU + + Arguments: + pAd Pointer to our adapter + pSrc Pointer to the received Plain text data + pDA Pointer to DA address + pSA Pointer to SA address + pMICKey pointer to MIC Key + Len the length of the received plain text data exclude MIC value + + Return Value: + TRUE MIC value matched + FALSE MIC value mismatched + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +BOOLEAN RTMPTkipCompareMICValue( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pSrc, + IN PUCHAR pDA, + IN PUCHAR pSA, + IN PUCHAR pMICKey, + IN UCHAR UserPriority, + IN UINT Len) +{ + UCHAR OldMic[8]; + ULONG Priority = UserPriority; + + // Init MIC value calculation + RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey); + // DA + RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN); + // SA + RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN); + // Priority + 3 bytes of 0 + RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4); + + // Calculate MIC value from plain text data + RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len); + + // Get MIC valude from received frame + NdisMoveMemory(OldMic, pSrc + Len, 8); + + // Get MIC value from decrypted plain data + RTMPTkipGetMIC(&pAd->PrivateInfo.Rx); + + // Move MIC value from MSDU, this steps should move to data path. + // Since the MIC value might cross MPDUs. + if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8)) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); //MIC error. + + + return (FALSE); + } + return (TRUE); +} + +/* + ======================================================================== + + Routine Description: + Compare MIC value of received MSDU + + Arguments: + pAd Pointer to our adapter + pLLC LLC header + pSrc Pointer to the received Plain text data + pDA Pointer to DA address + pSA Pointer to SA address + pMICKey pointer to MIC Key + Len the length of the received plain text data exclude MIC value + + Return Value: + TRUE MIC value matched + FALSE MIC value mismatched + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +BOOLEAN RTMPTkipCompareMICValueWithLLC( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pLLC, + IN PUCHAR pSrc, + IN PUCHAR pDA, + IN PUCHAR pSA, + IN PUCHAR pMICKey, + IN UINT Len) +{ + UCHAR OldMic[8]; + ULONG Priority = 0; + + // Init MIC value calculation + RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey); + // DA + RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN); + // SA + RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN); + // Priority + 3 bytes of 0 + RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4); + + // Start with LLC header + RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8); + + // Calculate MIC value from plain text data + RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len); + + // Get MIC valude from received frame + NdisMoveMemory(OldMic, pSrc + Len, 8); + + // Get MIC value from decrypted plain data + RTMPTkipGetMIC(&pAd->PrivateInfo.Rx); + + // Move MIC value from MSDU, this steps should move to data path. + // Since the MIC value might cross MPDUs. + if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8)) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n")); //MIC error. + + + return (FALSE); + } + return (TRUE); +} +/* + ======================================================================== + + Routine Description: + Copy frame from waiting queue into relative ring buffer and set + appropriate ASIC register to kick hardware transmit function + + Arguments: + pAd Pointer to our adapter + PNDIS_PACKET Pointer to Ndis Packet for MIC calculation + pEncap Pointer to LLC encap data + LenEncap Total encap length, might be 0 which indicates no encap + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPCalculateMICValue( + IN PRTMP_ADAPTER pAd, + IN PNDIS_PACKET pPacket, + IN PUCHAR pEncap, + IN PCIPHER_KEY pKey, + IN UCHAR apidx) +{ + PACKET_INFO PacketInfo; + PUCHAR pSrcBufVA; + UINT SrcBufLen; + PUCHAR pSrc; + UCHAR UserPriority; + UCHAR vlan_offset = 0; + + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); + + UserPriority = RTMP_GET_PACKET_UP(pPacket); + pSrc = pSrcBufVA; + + // determine if this is a vlan packet + if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100) + vlan_offset = 4; + + { + RTMPInitMICEngine( + pAd, + pKey->Key, + pSrc, + pSrc + 6, + UserPriority, + pKey->TxMic); + } + + + if (pEncap != NULL) + { + // LLC encapsulation + RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6); + // Protocol Type + RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2); + } + SrcBufLen -= (14 + vlan_offset); + pSrc += (14 + vlan_offset); + do + { + if (SrcBufLen > 0) + { + RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen); + } + + break; // No need handle next packet + + } while (TRUE); // End of copying payload + + // Compute the final MIC Value + RTMPTkipGetMIC(&pAd->PrivateInfo.Tx); +} + + +/************************************************************/ +/* tkip_sbox() */ +/* Returns a 16 bit value from a 64K entry table. The Table */ +/* is synthesized from two 256 entry byte wide tables. */ +/************************************************************/ + +UINT tkip_sbox(UINT index) +{ + UINT index_low; + UINT index_high; + UINT left, right; + + index_low = (index % 256); + index_high = ((index >> 8) % 256); + + left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256); + right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256); + + return (left ^ right); +} + +UINT rotr1(UINT a) +{ + unsigned int b; + + if ((a & 0x01) == 0x01) + { + b = (a >> 1) | 0x8000; + } + else + { + b = (a >> 1) & 0x7fff; + } + b = b % 65536; + return b; +} + +VOID RTMPTkipMixKey( + UCHAR *key, + UCHAR *ta, + ULONG pnl, /* Least significant 16 bits of PN */ + ULONG pnh, /* Most significant 32 bits of PN */ + UCHAR *rc4key, + UINT *p1k) +{ + + UINT tsc0; + UINT tsc1; + UINT tsc2; + + UINT ppk0; + UINT ppk1; + UINT ppk2; + UINT ppk3; + UINT ppk4; + UINT ppk5; + + INT i; + INT j; + + tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ + tsc1 = (unsigned int)(pnh % 65536); + tsc2 = (unsigned int)(pnl % 65536); /* lsb */ + + /* Phase 1, step 1 */ + p1k[0] = tsc1; + p1k[1] = tsc0; + p1k[2] = (UINT)(ta[0] + (ta[1]*256)); + p1k[3] = (UINT)(ta[2] + (ta[3]*256)); + p1k[4] = (UINT)(ta[4] + (ta[5]*256)); + + /* Phase 1, step 2 */ + for (i=0; i<8; i++) + { + j = 2*(i & 1); + p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536; + p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536; + p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536; + p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536; + p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536; + p1k[4] = (p1k[4] + i) % 65536; + } + + /* Phase 2, Step 1 */ + ppk0 = p1k[0]; + ppk1 = p1k[1]; + ppk2 = p1k[2]; + ppk3 = p1k[3]; + ppk4 = p1k[4]; + ppk5 = (p1k[4] + tsc2) % 65536; + + /* Phase2, Step 2 */ + ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536); + ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536); + ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536); + ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536); + ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536); + ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536); + + ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12])); + ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14])); + ppk2 = ppk2 + rotr1(ppk1); + ppk3 = ppk3 + rotr1(ppk2); + ppk4 = ppk4 + rotr1(ppk3); + ppk5 = ppk5 + rotr1(ppk4); + + /* Phase 2, Step 3 */ + /* Phase 2, Step 3 */ + + tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ + tsc1 = (unsigned int)(pnh % 65536); + tsc2 = (unsigned int)(pnl % 65536); /* lsb */ + + rc4key[0] = (tsc2 >> 8) % 256; + rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f; + rc4key[2] = tsc2 % 256; + rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256; + + rc4key[4] = ppk0 % 256; + rc4key[5] = (ppk0 >> 8) % 256; + + rc4key[6] = ppk1 % 256; + rc4key[7] = (ppk1 >> 8) % 256; + + rc4key[8] = ppk2 % 256; + rc4key[9] = (ppk2 >> 8) % 256; + + rc4key[10] = ppk3 % 256; + rc4key[11] = (ppk3 >> 8) % 256; + + rc4key[12] = ppk4 % 256; + rc4key[13] = (ppk4 >> 8) % 256; + + rc4key[14] = ppk5 % 256; + rc4key[15] = (ppk5 >> 8) % 256; +} + + +// +// TRUE: Success! +// FALSE: Decrypt Error! +// +BOOLEAN RTMPSoftDecryptTKIP( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pData, + IN ULONG DataByteCnt, + IN UCHAR UserPriority, + IN PCIPHER_KEY pWpaKey) +{ + UCHAR KeyID; + UINT HeaderLen; + UCHAR fc0; + UCHAR fc1; + USHORT fc; + UINT frame_type; + UINT frame_subtype; + UINT from_ds; + UINT to_ds; + INT a4_exists; + INT qc_exists; + USHORT duration; + USHORT seq_control; + USHORT qos_control; + UCHAR TA[MAC_ADDR_LEN]; + UCHAR DA[MAC_ADDR_LEN]; + UCHAR SA[MAC_ADDR_LEN]; + UCHAR RC4Key[16]; + UINT p1k[5]; //for mix_key; + ULONG pnl;/* Least significant 16 bits of PN */ + ULONG pnh;/* Most significant 32 bits of PN */ + UINT num_blocks; + UINT payload_remainder; + ARCFOURCONTEXT ArcFourContext; + UINT crc32 = 0; + UINT trailfcs = 0; + UCHAR MIC[8]; + UCHAR TrailMIC[8]; + + + fc0 = *pData; + fc1 = *(pData + 1); + + fc = *((PUSHORT)pData); + + frame_type = ((fc0 >> 2) & 0x03); + frame_subtype = ((fc0 >> 4) & 0x0f); + + from_ds = (fc1 & 0x2) >> 1; + to_ds = (fc1 & 0x1); + + a4_exists = (from_ds & to_ds); + qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */ + (frame_subtype == 0x09) || /* Likely to change. */ + (frame_subtype == 0x0a) || + (frame_subtype == 0x0b) + ); + + HeaderLen = 24; + if (a4_exists) + HeaderLen += 6; + + KeyID = *((PUCHAR)(pData+ HeaderLen + 3)); + KeyID = KeyID >> 6; + + if (pWpaKey[KeyID].KeyLen == 0) + { + DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", KeyID)); + return FALSE; + } + + duration = *((PUSHORT)(pData+2)); + + seq_control = *((PUSHORT)(pData+22)); + + if (qc_exists) + { + if (a4_exists) + { + qos_control = *((PUSHORT)(pData+30)); + } + else + { + qos_control = *((PUSHORT)(pData+24)); + } + } + + if (to_ds == 0 && from_ds == 1) + { + NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN); + NdisMoveMemory(SA, pData+16, MAC_ADDR_LEN); + NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); //BSSID + } + else if (to_ds == 0 && from_ds == 0 ) + { + NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); + NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN); + NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN); + } + else if (to_ds == 1 && from_ds == 0) + { + NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN); + NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); + NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN); + } + else if (to_ds == 1 && from_ds == 1) + { + NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); + NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN); + NdisMoveMemory(SA, pData+22, MAC_ADDR_LEN); + } + + num_blocks = (DataByteCnt - 16) / 16; + payload_remainder = (DataByteCnt - 16) % 16; + + pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2); + pnh = *((PULONG)(pData + HeaderLen + 4)); + pnh = cpu2le32(pnh); + RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k); + + ARCFOUR_INIT(&ArcFourContext, RC4Key, 16); + + ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8); + NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4); + crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4); //Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS). + crc32 ^= 0xffffffff; /* complement */ + + if(crc32 != cpu2le32(trailfcs)) + { + DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n")); //ICV error. + + return (FALSE); + } + + NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8); + RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, pWpaKey[KeyID].RxMic); + RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 12); + RTMPTkipGetMIC(&pAd->PrivateInfo.Tx); + NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8); + + if (!NdisEqualMemory(MIC, TrailMIC, 8)) + { + DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); //MIC error. + //RTMPReportMicError(pAd, &pWpaKey[KeyID]); // marked by AlbertY @ 20060630 + return (FALSE); + } + + //DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!!\n"); + return TRUE; +} Index: b/drivers/staging/rt2860/common/cmm_wep.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/cmm_wep.c @@ -0,0 +1,499 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rtmp_wep.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Paul Wu 10-28-02 Initial +*/ + +#include "../rt_config.h" + +UINT FCSTAB_32[256] = +{ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +/* +UCHAR WEPKEY[] = { + //IV + 0x00, 0x11, 0x22, + //WEP KEY + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC + }; + */ + +/* + ======================================================================== + + Routine Description: + Init WEP function. + + Arguments: + pAd Pointer to our adapter + pKey Pointer to the WEP KEY + KeyId WEP Key ID + KeyLen the length of WEP KEY + pDest Pointer to the destination which Encryption data will store in. + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPInitWepEngine( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pKey, + IN UCHAR KeyId, + IN UCHAR KeyLen, + IN OUT PUCHAR pDest) +{ + UINT i; + UCHAR WEPKEY[] = { + //IV + 0x00, 0x11, 0x22, + //WEP KEY + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC + }; + + pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32. + + { + NdisMoveMemory(WEPKEY + 3, pKey, KeyLen); + + for(i = 0; i < 3; i++) + WEPKEY[i] = RandomByte(pAd); //Call mlme RandomByte() function. + ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3); //INIT SBOX, KEYLEN+3(IV) + + NdisMoveMemory(pDest, WEPKEY, 3); //Append Init Vector + } + *(pDest+3) = (KeyId << 6); //Append KEYID + +} + +/* + ======================================================================== + + Routine Description: + Encrypt transimitted data + + Arguments: + pAd Pointer to our adapter + pSrc Pointer to the transimitted source data that will be encrypt + pDest Pointer to the destination where entryption data will be store in. + Len Indicate the length of the source data + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID RTMPEncryptData( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pSrc, + IN PUCHAR pDest, + IN UINT Len) +{ + pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len); + ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len); +} + + +/* + ======================================================================== + + Routine Description: + Decrypt received WEP data + + Arguments: + pAdapter Pointer to our adapter + pSrc Pointer to the received data + Len the length of the received data + + Return Value: + TRUE Decrypt WEP data success + FALSE Decrypt WEP data failed + + Note: + + ======================================================================== +*/ +BOOLEAN RTMPSoftDecryptWEP( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pData, + IN ULONG DataByteCnt, + IN PCIPHER_KEY pGroupKey) +{ + UINT trailfcs; + UINT crc32; + UCHAR KeyIdx; + UCHAR WEPKEY[] = { + //IV + 0x00, 0x11, 0x22, + //WEP KEY + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC + }; + UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11; + ULONG payload_len = DataByteCnt - LENGTH_802_11; + + NdisMoveMemory(WEPKEY, pPayload, 3); //Get WEP IV + + KeyIdx = (*(pPayload + 3) & 0xc0) >> 6; + if (pGroupKey[KeyIdx].KeyLen == 0) + return (FALSE); + + NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen); + ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3); + ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4); + NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4); + crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8); //Skip last 4 bytes(FCS). + crc32 ^= 0xffffffff; /* complement */ + + if(crc32 != cpu2le32(trailfcs)) + { + DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n")); //CRC error. + return (FALSE); + } + return (TRUE); +} + +/* + ======================================================================== + + Routine Description: + The Stream Cipher Encryption Algorithm "ARCFOUR" initialize + + Arguments: + Ctx Pointer to ARCFOUR CONTEXT (SBOX) + pKey Pointer to the WEP KEY + KeyLen Indicate the length fo the WEP KEY + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID ARCFOUR_INIT( + IN PARCFOURCONTEXT Ctx, + IN PUCHAR pKey, + IN UINT KeyLen) +{ + UCHAR t, u; + UINT keyindex; + UINT stateindex; + PUCHAR state; + UINT counter; + + state = Ctx->STATE; + Ctx->X = 0; + Ctx->Y = 0; + for (counter = 0; counter < 256; counter++) + state[counter] = (UCHAR)counter; + keyindex = 0; + stateindex = 0; + for (counter = 0; counter < 256; counter++) + { + t = state[counter]; + stateindex = (stateindex + pKey[keyindex] + t) & 0xff; + u = state[stateindex]; + state[stateindex] = t; + state[counter] = u; + if (++keyindex >= KeyLen) + keyindex = 0; + } +} + +/* + ======================================================================== + + Routine Description: + Get bytes from ARCFOUR CONTEXT (S-BOX) + + Arguments: + Ctx Pointer to ARCFOUR CONTEXT (SBOX) + + Return Value: + UCHAR - the value of the ARCFOUR CONTEXT (S-BOX) + + Note: + + ======================================================================== +*/ +UCHAR ARCFOUR_BYTE( + IN PARCFOURCONTEXT Ctx) +{ + UINT x; + UINT y; + UCHAR sx, sy; + PUCHAR state; + + state = Ctx->STATE; + x = (Ctx->X + 1) & 0xff; + sx = state[x]; + y = (sx + Ctx->Y) & 0xff; + sy = state[y]; + Ctx->X = x; + Ctx->Y = y; + state[y] = sx; + state[x] = sy; + + return(state[(sx + sy) & 0xff]); + +} + +/* + ======================================================================== + + Routine Description: + The Stream Cipher Decryption Algorithm + + Arguments: + Ctx Pointer to ARCFOUR CONTEXT (SBOX) + pDest Pointer to the Destination + pSrc Pointer to the Source data + Len Indicate the length of the Source data + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID ARCFOUR_DECRYPT( + IN PARCFOURCONTEXT Ctx, + IN PUCHAR pDest, + IN PUCHAR pSrc, + IN UINT Len) +{ + UINT i; + + for (i = 0; i < Len; i++) + pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx); +} + +/* + ======================================================================== + + Routine Description: + The Stream Cipher Encryption Algorithm + + Arguments: + Ctx Pointer to ARCFOUR CONTEXT (SBOX) + pDest Pointer to the Destination + pSrc Pointer to the Source data + Len Indicate the length of the Source dta + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +VOID ARCFOUR_ENCRYPT( + IN PARCFOURCONTEXT Ctx, + IN PUCHAR pDest, + IN PUCHAR pSrc, + IN UINT Len) +{ + UINT i; + + for (i = 0; i < Len; i++) + pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx); +} + +/* + ======================================================================== + + Routine Description: + The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt GTK. + + Arguments: + Ctx Pointer to ARCFOUR CONTEXT (SBOX) + pDest Pointer to the Destination + pSrc Pointer to the Source data + Len Indicate the length of the Source dta + + + ======================================================================== +*/ + +VOID WPAARCFOUR_ENCRYPT( + IN PARCFOURCONTEXT Ctx, + IN PUCHAR pDest, + IN PUCHAR pSrc, + IN UINT Len) +{ + UINT i; + //discard first 256 bytes + for (i = 0; i < 256; i++) + ARCFOUR_BYTE(Ctx); + + for (i = 0; i < Len; i++) + pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx); +} + + +/* + ======================================================================== + + Routine Description: + Calculate a new FCS given the current FCS and the new data. + + Arguments: + Fcs the original FCS value + Cp pointer to the data which will be calculate the FCS + Len the length of the data + + Return Value: + UINT - FCS 32 bits + + IRQL = DISPATCH_LEVEL + + Note: + + ======================================================================== +*/ +UINT RTMP_CALC_FCS32( + IN UINT Fcs, + IN PUCHAR Cp, + IN INT Len) +{ + while (Len--) + Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]); + + return (Fcs); +} + + +/* + ======================================================================== + + Routine Description: + Get last FCS and encrypt it to the destination + + Arguments: + pDest Pointer to the Destination + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID RTMPSetICV( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDest) +{ + pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff; /* complement */ + pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32); + + ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4); +} Index: b/drivers/staging/rt2860/common/cmm_wpa.c =================================================================== --- a/drivers/staging/rt2860/common/cmm_wpa.c +++ b/drivers/staging/rt2860/common/cmm_wpa.c @@ -52,173 +52,2084 @@ UCHAR OUI_WPA2_CCMP[4] = {0 UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01}; UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02}; UCHAR OUI_WPA2_WEP104[4] = {0x00, 0x0F, 0xAC, 0x05}; -// MSA OUI -UCHAR OUI_MSA_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x05}; // Not yet final - IEEE 802.11s-D1.06 -UCHAR OUI_MSA_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x06}; // Not yet final - IEEE 802.11s-D1.06 + + + +static VOID ConstructEapolKeyData( + IN PMAC_TABLE_ENTRY pEntry, + IN UCHAR GroupKeyWepStatus, + IN UCHAR keyDescVer, + IN UCHAR MsgType, + IN UCHAR DefaultKeyIdx, + IN UCHAR *GTK, + IN UCHAR *RSNIE, + IN UCHAR RSNIE_LEN, + OUT PEAPOL_PACKET pMsg); + +static VOID CalculateMIC( + IN UCHAR KeyDescVer, + IN UCHAR *PTK, + OUT PEAPOL_PACKET pMsg); + +static VOID WpaEAPPacketAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +static VOID WpaEAPOLASFAlertAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +static VOID WpaEAPOLLogoffAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +static VOID WpaEAPOLStartAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +static VOID WpaEAPOLKeyAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem); + +/* + ========================================================================== + Description: + association state machine init, including state transition and timer init + Parameters: + S - pointer to the association state machine + ========================================================================== + */ +VOID WpaStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + OUT STATE_MACHINE_FUNC Trans[]) +{ + StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_WPA_PTK_STATE, MAX_WPA_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PTK, WPA_MACHINE_BASE); + + StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket, (STATE_MACHINE_FUNC)WpaEAPPacketAction); + StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart, (STATE_MACHINE_FUNC)WpaEAPOLStartAction); + StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff, (STATE_MACHINE_FUNC)WpaEAPOLLogoffAction); + StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction); + StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert, (STATE_MACHINE_FUNC)WpaEAPOLASFAlertAction); +} + +/* + ========================================================================== + Description: + this is state machine function. + When receiving EAP packets which is for 802.1x authentication use. + Not use in PSK case + Return: + ========================================================================== +*/ +VOID WpaEAPPacketAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ +} + +VOID WpaEAPOLASFAlertAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ +} + +VOID WpaEAPOLLogoffAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ +} + +/* + ========================================================================== + Description: + Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c + Return: + ========================================================================== +*/ +VOID WpaEAPOLStartAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + MAC_TABLE_ENTRY *pEntry; + PHEADER_802_11 pHeader; + + DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n")); + + pHeader = (PHEADER_802_11)Elem->Msg; + + //For normaol PSK, we enqueue an EAPOL-Start command to trigger the process. + if (Elem->MsgLen == 6) + pEntry = MacTableLookup(pAd, Elem->Msg); + else + { + pEntry = MacTableLookup(pAd, pHeader->Addr2); + } + + if (pEntry) + { + DBGPRINT(RT_DEBUG_TRACE, (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n", pEntry->PortSecured, pEntry->WpaState, pEntry->AuthMode, pEntry->PMKID_CacheIdx)); + + if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED) + && (pEntry->WpaState < AS_PTKSTART) + && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) || ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND)))) + { + pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; + pEntry->WpaState = AS_INITPSK; + pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; + NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter)); + pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR; + + WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV); + } + } +} + +/* + ========================================================================== + Description: + This is state machine function. + When receiving EAPOL packets which is for 802.1x key management. + Use both in WPA, and WPAPSK case. + In this function, further dispatch to different functions according to the received packet. 3 categories are : + 1. normal 4-way pairwisekey and 2-way groupkey handshake + 2. MIC error (Countermeasures attack) report packet from STA. + 3. Request for pairwise/group key update from STA + Return: + ========================================================================== +*/ +VOID WpaEAPOLKeyAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + MAC_TABLE_ENTRY *pEntry; + PHEADER_802_11 pHeader; + PEAPOL_PACKET pEapol_packet; + KEY_INFO peerKeyInfo; + + DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n")); + + pHeader = (PHEADER_802_11)Elem->Msg; + pEapol_packet = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; + + NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo)); + NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pEapol_packet->KeyDesc.KeyInfo, sizeof(KEY_INFO)); + + hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet, (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H)); + + *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo)); + + do + { + pEntry = MacTableLookup(pAd, pHeader->Addr2); + + if (!pEntry || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) + break; + + if (pEntry->AuthMode < Ndis802_11AuthModeWPA) + break; + + DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPoL-Key frame from STA %02X-%02X-%02X-%02X-%02X-%02X\n", PRINT_MAC(pEntry->Addr))); + + if (((pEapol_packet->ProVer != EAPOL_VER) && (pEapol_packet->ProVer != EAPOL_VER2)) || + ((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC) && (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC))) + { + DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n")); + break; + } + + // The value 1 shall be used for all EAPOL-Key frames to and from a STA when + // neither the group nor pairwise ciphers are CCMP for Key Descriptor 1. + if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Key descripter version not match(TKIP) \n")); + break; + } + // The value 2 shall be used for all EAPOL-Key frames to and from a STA when + // either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2. + else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled) && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES)) + { + DBGPRINT(RT_DEBUG_ERROR, ("Key descripter version not match(AES) \n")); + break; + } + + // Check if this STA is in class 3 state and the WPA state is started + if ((pEntry->Sst == SST_ASSOC) && (pEntry->WpaState >= AS_INITPSK)) + { + // Check the Key Ack (bit 7) of the Key Information to determine the Authenticator + // or not. + // An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL- + // Key frame from the Authenticator must not have the Ack bit set. + if (peerKeyInfo.KeyAck == 1) + { + // The frame is snet by Authenticator. + // So the Supplicant side shall handle this. + + if ((peerKeyInfo.Secure == 0) && (peerKeyInfo.Request == 0) && + (peerKeyInfo.Error == 0) && (peerKeyInfo.KeyType == PAIRWISEKEY)) + { + // Process 1. the message 1 of 4-way HS in WPA or WPA2 + // EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) + // 2. the message 3 of 4-way HS in WPA + // EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) + if (peerKeyInfo.KeyMic == 0) + PeerPairMsg1Action(pAd, pEntry, Elem); + else + PeerPairMsg3Action(pAd, pEntry, Elem); + } + else if ((peerKeyInfo.Secure == 1) && + (peerKeyInfo.KeyMic == 1) && + (peerKeyInfo.Request == 0) && + (peerKeyInfo.Error == 0)) + { + // Process 1. the message 3 of 4-way HS in WPA2 + // EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) + // 2. the message 1 of group KS in WPA or WPA2 + // EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N]) + if (peerKeyInfo.KeyType == PAIRWISEKEY) + PeerPairMsg3Action(pAd, pEntry, Elem); + else + PeerGroupMsg1Action(pAd, pEntry, Elem); + } + } + else + { + // The frame is snet by Supplicant. + // So the Authenticator side shall handle this. + if ((peerKeyInfo.Request == 0) && + (peerKeyInfo.Error == 0) && + (peerKeyInfo.KeyMic == 1)) + { + if (peerKeyInfo.Secure == 0 && peerKeyInfo.KeyType == PAIRWISEKEY) + { + // EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data) + // Process 1. message 2 of 4-way HS in WPA or WPA2 + // 2. message 4 of 4-way HS in WPA + if (CONV_ARRARY_TO_UINT16(pEapol_packet->KeyDesc.KeyDataLen) == 0) + { + PeerPairMsg4Action(pAd, pEntry, Elem); + } + else + { + PeerPairMsg2Action(pAd, pEntry, Elem); + } + } + else if (peerKeyInfo.Secure == 1 && peerKeyInfo.KeyType == PAIRWISEKEY) + { + // EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0) + // Process message 4 of 4-way HS in WPA2 + PeerPairMsg4Action(pAd, pEntry, Elem); + } + else if (peerKeyInfo.Secure == 1 && peerKeyInfo.KeyType == GROUPKEY) + { + // EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0) + // Process message 2 of Group key HS in WPA or WPA2 + PeerGroupMsg2Action(pAd, pEntry, &Elem->Msg[LENGTH_802_11], (Elem->MsgLen - LENGTH_802_11)); + } + } + } + } + }while(FALSE); +} + +/* + ======================================================================== + + Routine Description: + Copy frame from waiting queue into relative ring buffer and set + appropriate ASIC register to kick hardware encryption before really + sent out to air. + + Arguments: + pAd Pointer to our adapter + PNDIS_PACKET Pointer to outgoing Ndis frame + NumberOfFrag Number of fragment required + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID RTMPToWirelessSta( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pHeader802_3, + IN UINT HdrLen, + IN PUCHAR pData, + IN UINT DataLen, + IN BOOLEAN bClearFrame) +{ + PNDIS_PACKET pPacket; + NDIS_STATUS Status; + + if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) + return; + + do { + // build a NDIS packet + Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen); + if (Status != NDIS_STATUS_SUCCESS) + break; + + + if (bClearFrame) + RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1); + else + RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0); + { + RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); + + RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID); // set a default value + if(pEntry->apidx != 0) + RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, pEntry->apidx); + + RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid); + RTMP_SET_PACKET_MOREDATA(pPacket, FALSE); + } + + { + // send out the packet + Status = STASendPacket(pAd, pPacket); + if (Status == NDIS_STATUS_SUCCESS) + { + UCHAR Index; + + // Dequeue one frame from TxSwQueue0..3 queue and process it + // There are three place calling dequeue for TX ring. + // 1. Here, right after queueing the frame. + // 2. At the end of TxRingTxDone service routine. + // 3. Upon NDIS call RTMPSendPackets + if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) + { + for(Index = 0; Index < 5; Index ++) + if(pAd->TxSwQueue[Index].Number > 0) + RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS); + } + } + } + + } while (FALSE); +} + +/* + ========================================================================== + Description: + This is a function to initilize 4-way handshake + + Return: + + ========================================================================== +*/ +VOID WPAStart4WayHS( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN ULONG TimeInterval) +{ + UCHAR Header802_3[14]; + EAPOL_PACKET EAPOLPKT; + PUINT8 pBssid = NULL; + UCHAR group_cipher = Ndis802_11WEPDisabled; + + DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n")); + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS)) + { + DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : The interface is closed...\n")); + return; + } + + + if (pBssid == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n")); + return; + } + + // Check the status + if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK)) + { + DBGPRINT(RT_DEBUG_ERROR, ("[ERROR]WPAStart4WayHS : Not expect calling\n")); + return; + } + + + // Increment replay counter by 1 + ADD_ONE_To_64BIT_VAR(pEntry->R_Counter); + + // Randomly generate ANonce + GenRandom(pAd, (UCHAR *)pBssid, pEntry->ANonce); + + // Construct EAPoL message - Pairwise Msg 1 + // EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) + NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET)); + ConstructEapolMsg(pEntry, + group_cipher, + EAPOL_PAIR_MSG_1, + 0, // Default key index + pEntry->ANonce, + NULL, // TxRSC + NULL, // GTK + NULL, // RSNIE + 0, // RSNIE length + &EAPOLPKT); + + + // Make outgoing frame + MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL); + RTMPToWirelessSta(pAd, pEntry, Header802_3, + LENGTH_802_3, (PUCHAR)&EAPOLPKT, + CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, + (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? FALSE : TRUE); + + // Trigger Retry Timer + RTMPModTimer(&pEntry->RetryTimer, TimeInterval); + + // Update State + pEntry->WpaState = AS_PTKSTART; + + DBGPRINT(RT_DEBUG_TRACE, ("<=== WPAStart4WayHS: send Msg1 of 4-way \n")); + +} + +/* + ======================================================================== + + Routine Description: + Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2 + + Arguments: + pAd Pointer to our adapter + Elem Message body + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID PeerPairMsg1Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR PTK[80]; + UCHAR Header802_3[14]; + PEAPOL_PACKET pMsg1; + UINT MsgLen; + EAPOL_PACKET EAPOLPKT; + PUINT8 pCurrentAddr = NULL; + PUINT8 pmk_ptr = NULL; + UCHAR group_cipher = Ndis802_11WEPDisabled; + PUINT8 rsnie_ptr = NULL; + UCHAR rsnie_len = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n")); + + if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) + return; + + if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2)) + return; + + { + pCurrentAddr = pAd->CurrentAddress; + pmk_ptr = pAd->StaCfg.PMK; + group_cipher = pAd->StaCfg.GroupCipher; + rsnie_ptr = pAd->StaCfg.RSN_IE; + rsnie_len = pAd->StaCfg.RSNIE_Len; + } + + // Store the received frame + pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; + MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; + + // Sanity Check peer Pairwise message 1 - Replay Counter + if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry) == FALSE) + return; + + // Store Replay counter, it will use to verify message 3 and construct message 2 + NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); + + // Store ANonce + NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE); + + // Generate random SNonce + GenRandom(pAd, (UCHAR *)pCurrentAddr, pEntry->SNonce); + + { + // Calculate PTK(ANonce, SNonce) + WpaDerivePTK(pAd, + pmk_ptr, + pEntry->ANonce, + pEntry->Addr, + pEntry->SNonce, + pCurrentAddr, + PTK, + LEN_PTK); + + // Save key to PTK entry + NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK); + } + + // Update WpaState + pEntry->WpaState = AS_PTKINIT_NEGOTIATING; + + // Construct EAPoL message - Pairwise Msg 2 + // EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2) + NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET)); + ConstructEapolMsg(pEntry, + group_cipher, + EAPOL_PAIR_MSG_2, + 0, // DefaultKeyIdx + pEntry->SNonce, + NULL, // TxRsc + NULL, // GTK + (UCHAR *)rsnie_ptr, + rsnie_len, + &EAPOLPKT); + + // Make outgoing frame + MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); + + RTMPToWirelessSta(pAd, pEntry, + Header802_3, sizeof(Header802_3), (PUCHAR)&EAPOLPKT, + CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, TRUE); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n")); +} + + +/* + ========================================================================== + Description: + When receiving the second packet of 4-way pairwisekey handshake. + Return: + ========================================================================== +*/ +VOID PeerPairMsg2Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR PTK[80]; + BOOLEAN Cancelled; + PHEADER_802_11 pHeader; + EAPOL_PACKET EAPOLPKT; + PEAPOL_PACKET pMsg2; + UINT MsgLen; + UCHAR Header802_3[LENGTH_802_3]; + UCHAR TxTsc[6]; + PUINT8 pBssid = NULL; + PUINT8 pmk_ptr = NULL; + PUINT8 gtk_ptr = NULL; + UCHAR default_key = 0; + UCHAR group_cipher = Ndis802_11WEPDisabled; + PUINT8 rsnie_ptr = NULL; + UCHAR rsnie_len = 0; + + DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n")); + + if ((!pEntry) || (!pEntry->ValidAsCLI)) + return; + + if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2)) + return; + + // check Entry in valid State + if (pEntry->WpaState < AS_PTKSTART) + return; + + + + // pointer to 802.11 header + pHeader = (PHEADER_802_11)Elem->Msg; + + // skip 802.11_header(24-byte) and LLC_header(8) + pMsg2 = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; + MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; + + // Store SNonce + NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE); + + { + // Derive PTK + WpaDerivePTK(pAd, + (UCHAR *)pmk_ptr, + pEntry->ANonce, // ANONCE + (UCHAR *)pBssid, + pEntry->SNonce, // SNONCE + pEntry->Addr, + PTK, + LEN_PTK); + + NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK); + } + + // Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE + if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry) == FALSE) + return; + + do + { + // delete retry timer + RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); + + // Change state + pEntry->WpaState = AS_PTKINIT_NEGOTIATING; + + // Increment replay counter by 1 + ADD_ONE_To_64BIT_VAR(pEntry->R_Counter); + + // Construct EAPoL message - Pairwise Msg 3 + NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET)); + ConstructEapolMsg(pEntry, + group_cipher, + EAPOL_PAIR_MSG_3, + default_key, + pEntry->ANonce, + TxTsc, + (UCHAR *)gtk_ptr, + (UCHAR *)rsnie_ptr, + rsnie_len, + &EAPOLPKT); + + // Make outgoing frame + MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL); + RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3, + (PUCHAR)&EAPOLPKT, + CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, + (pEntry->PortSecured == WPA_802_1X_PORT_SECURED) ? FALSE : TRUE); + + pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR; + RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV); + + // Update State + pEntry->WpaState = AS_PTKINIT_NEGOTIATING; + }while(FALSE); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n")); +} + +/* + ======================================================================== + + Routine Description: + Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4 + + Arguments: + pAd Pointer to our adapter + Elem Message body + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID PeerPairMsg3Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem) +{ + PHEADER_802_11 pHeader; + UCHAR Header802_3[14]; + EAPOL_PACKET EAPOLPKT; + PEAPOL_PACKET pMsg3; + UINT MsgLen; + PUINT8 pCurrentAddr = NULL; + UCHAR group_cipher = Ndis802_11WEPDisabled; + + DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n")); + + if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) + return; + + if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2)) + return; + + { + pCurrentAddr = pAd->CurrentAddress; + group_cipher = pAd->StaCfg.GroupCipher; + + } + + // Record 802.11 header & the received EAPOL packet Msg3 + pHeader = (PHEADER_802_11) Elem->Msg; + pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; + MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; + + // Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE + if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry) == FALSE) + return; + + // Save Replay counter, it will use construct message 4 + NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); + + // Double check ANonce + if (!NdisEqualMemory(pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) + { + return; + } + + // Construct EAPoL message - Pairwise Msg 4 + NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET)); + ConstructEapolMsg(pEntry, + group_cipher, + EAPOL_PAIR_MSG_4, + 0, // group key index not used in message 4 + NULL, // Nonce not used in message 4 + NULL, // TxRSC not used in message 4 + NULL, // GTK not used in message 4 + NULL, // RSN IE not used in message 4 + 0, + &EAPOLPKT); + + // Update WpaState + pEntry->WpaState = AS_PTKINITDONE; + + // Update pairwise key + { + PCIPHER_KEY pSharedKey; + + pSharedKey = &pAd->SharedKey[BSS0][0]; + + NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK); + + // Prepare pair-wise key information into shared key table + NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY)); + pSharedKey->KeyLen = LEN_TKIP_EK; + NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK); + NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK); + NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK); + + // Decide its ChiperAlg + if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) + pSharedKey->CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) + pSharedKey->CipherAlg = CIPHER_AES; + else + pSharedKey->CipherAlg = CIPHER_NONE; + + // Update these related information to MAC_TABLE_ENTRY + pEntry = &pAd->MacTab.Content[BSSID_WCID]; + NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK); + NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK); + NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK); + pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg; + + // Update pairwise key information to ASIC Shared Key Table + AsicAddSharedKeyEntry(pAd, + BSS0, + 0, + pSharedKey->CipherAlg, + pSharedKey->Key, + pSharedKey->TxMic, + pSharedKey->RxMic); + + // Update ASIC WCID attribute table and IVEIV table + RTMPAddWcidAttributeEntry(pAd, + BSS0, + 0, + pSharedKey->CipherAlg, + pEntry); + + } + + // open 802.1x port control and privacy filter + if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK || + pEntry->AuthMode == Ndis802_11AuthModeWPA2) + { + pEntry->PortSecured = WPA_802_1X_PORT_SECURED; + pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; + + STA_PORT_SECURED(pAd); + // Indicate Connected for GUI + pAd->IndicateMediaState = NdisMediaStateConnected; + DBGPRINT(RT_DEBUG_TRACE, ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n", + GetAuthMode(pEntry->AuthMode), + GetEncryptType(pEntry->WepStatus), + GetEncryptType(group_cipher))); + } + else + { + } + + // Init 802.3 header and send out + MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); + RTMPToWirelessSta(pAd, pEntry, + Header802_3, sizeof(Header802_3), + (PUCHAR)&EAPOLPKT, + CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, TRUE); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n")); +} + +/* + ========================================================================== + Description: + When receiving the last packet of 4-way pairwisekey handshake. + Initilize 2-way groupkey handshake following. + Return: + ========================================================================== +*/ +VOID PeerPairMsg4Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem) +{ + PEAPOL_PACKET pMsg4; + PHEADER_802_11 pHeader; + UINT MsgLen; + BOOLEAN Cancelled; + UCHAR group_cipher = Ndis802_11WEPDisabled; + + DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n")); + + do + { + if ((!pEntry) || (!pEntry->ValidAsCLI)) + break; + + if (Elem->MsgLen < (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2 ) ) + break; + + if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING) + break; + + + // pointer to 802.11 header + pHeader = (PHEADER_802_11)Elem->Msg; + + // skip 802.11_header(24-byte) and LLC_header(8) + pMsg4 = (PEAPOL_PACKET)&Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; + MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; + + // Sanity Check peer Pairwise message 4 - Replay Counter, MIC + if (PeerWpaMessageSanity(pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE) + break; + + // 3. uses the MLME.SETKEYS.request to configure PTK into MAC + NdisZeroMemory(&pEntry->PairwiseKey, sizeof(CIPHER_KEY)); + + // reset IVEIV in Asic + AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0); + + pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK; + NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32], LEN_TKIP_EK); + NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pEntry->PTK[TKIP_AP_RXMICK_OFFSET], LEN_TKIP_RXMICK); + NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pEntry->PTK[TKIP_AP_TXMICK_OFFSET], LEN_TKIP_TXMICK); + + // Set pairwise key to Asic + { + pEntry->PairwiseKey.CipherAlg = CIPHER_NONE; + if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) + pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP; + else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled) + pEntry->PairwiseKey.CipherAlg = CIPHER_AES; + + // Add Pair-wise key to Asic + AsicAddPairwiseKeyEntry( + pAd, + pEntry->Addr, + (UCHAR)pEntry->Aid, + &pEntry->PairwiseKey); + + // update WCID attribute table and IVEIV table for this entry + RTMPAddWcidAttributeEntry( + pAd, + pEntry->apidx, + 0, + pEntry->PairwiseKey.CipherAlg, + pEntry); + } + + // 4. upgrade state + pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; + pEntry->WpaState = AS_PTKINITDONE; + pEntry->PortSecured = WPA_802_1X_PORT_SECURED; + + + if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 || + pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) + { + pEntry->GTKState = REKEY_ESTABLISHED; + RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); + + + // send wireless event - for set key done WPA2 + if (pAd->CommonCfg.bWirelessEvent) + RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n", + pEntry->AuthMode, GetAuthMode(pEntry->AuthMode), + pEntry->WepStatus, GetEncryptType(pEntry->WepStatus), + group_cipher, + GetEncryptType(group_cipher))); + } + else + { + // 5. init Group 2-way handshake if necessary. + WPAStart2WayGroupHS(pAd, pEntry); + + pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR; + RTMPModTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV); + } + }while(FALSE); + +} + +/* + ========================================================================== + Description: + This is a function to send the first packet of 2-way groupkey handshake + Return: + + ========================================================================== +*/ +VOID WPAStart2WayGroupHS( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry) +{ + UCHAR Header802_3[14]; + UCHAR TxTsc[6]; + EAPOL_PACKET EAPOLPKT; + UCHAR group_cipher = Ndis802_11WEPDisabled; + UCHAR default_key = 0; + PUINT8 gnonce_ptr = NULL; + PUINT8 gtk_ptr = NULL; + PUINT8 pBssid = NULL; + + DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n")); + + if ((!pEntry) || (!pEntry->ValidAsCLI)) + return; + + + do + { + // Increment replay counter by 1 + ADD_ONE_To_64BIT_VAR(pEntry->R_Counter); + + // Construct EAPoL message - Group Msg 1 + NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET)); + ConstructEapolMsg(pEntry, + group_cipher, + EAPOL_GROUP_MSG_1, + default_key, + (UCHAR *)gnonce_ptr, + TxTsc, + (UCHAR *)gtk_ptr, + NULL, + 0, + &EAPOLPKT); + + // Make outgoing frame + MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL); + RTMPToWirelessSta(pAd, pEntry, + Header802_3, LENGTH_802_3, + (PUCHAR)&EAPOLPKT, + CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, FALSE); + + + + }while (FALSE); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n")); + + return; +} + +/* + ======================================================================== + + Routine Description: + Process Group key 2-way handshaking + + Arguments: + pAd Pointer to our adapter + Elem Message body + + Return Value: + None + + Note: + + ======================================================================== +*/ +VOID PeerGroupMsg1Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR Header802_3[14]; + EAPOL_PACKET EAPOLPKT; + PEAPOL_PACKET pGroup; + UINT MsgLen; + BOOLEAN Cancelled; + UCHAR default_key = 0; + UCHAR group_cipher = Ndis802_11WEPDisabled; + PUINT8 pCurrentAddr = NULL; + + DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n")); + + if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli))) + return; + + { + pCurrentAddr = pAd->CurrentAddress; + group_cipher = pAd->StaCfg.GroupCipher; + default_key = pAd->StaCfg.DefaultKeyId; + } + + // Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8) + pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; + MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H; + + // Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE + if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry) == FALSE) + return; + + // delete retry timer + RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); + + // Save Replay counter, it will use to construct message 2 + NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); + + // Construct EAPoL message - Group Msg 2 + NdisZeroMemory(&EAPOLPKT, sizeof(EAPOL_PACKET)); + ConstructEapolMsg(pEntry, + group_cipher, + EAPOL_GROUP_MSG_2, + default_key, + NULL, // Nonce not used + NULL, // TxRSC not used + NULL, // GTK not used + NULL, // RSN IE not used + 0, + &EAPOLPKT); + + // open 802.1x port control and privacy filter + pEntry->PortSecured = WPA_802_1X_PORT_SECURED; + pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; + + STA_PORT_SECURED(pAd); + // Indicate Connected for GUI + pAd->IndicateMediaState = NdisMediaStateConnected; + + DBGPRINT(RT_DEBUG_TRACE, ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n", + GetAuthMode(pEntry->AuthMode), + GetEncryptType(pEntry->WepStatus), + GetEncryptType(group_cipher))); + + // init header and Fill Packet and send Msg 2 to authenticator + MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL); + RTMPToWirelessSta(pAd, pEntry, + Header802_3, sizeof(Header802_3), + (PUCHAR)&EAPOLPKT, + CONV_ARRARY_TO_UINT16(EAPOLPKT.Body_Len) + 4, FALSE); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== PeerGroupMsg1Action: sned group message 2\n")); +} + +/* + ========================================================================== + Description: + When receiving the last packet of 2-way groupkey handshake. + Return: + ========================================================================== +*/ +VOID PeerGroupMsg2Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN VOID *Msg, + IN UINT MsgLen) +{ + UINT Len; + PUCHAR pData; + BOOLEAN Cancelled; + PEAPOL_PACKET pMsg2; + UCHAR group_cipher = Ndis802_11WEPDisabled; + + DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n")); + + do + { + if ((!pEntry) || (!pEntry->ValidAsCLI)) + break; + + if (MsgLen < (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE - 2)) + break; + + if (pEntry->WpaState != AS_PTKINITDONE) + break; + + + pData = (PUCHAR)Msg; + pMsg2 = (PEAPOL_PACKET) (pData + LENGTH_802_1_H); + Len = MsgLen - LENGTH_802_1_H; + + // Sanity Check peer group message 2 - Replay Counter, MIC + if (PeerWpaMessageSanity(pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE) + break; + + // 3. upgrade state + + RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); + pEntry->GTKState = REKEY_ESTABLISHED; + + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + // send wireless event - for set key done WPA2 + if (pAd->CommonCfg.bWirelessEvent) + RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n", + pEntry->AuthMode, GetAuthMode(pEntry->AuthMode), + pEntry->WepStatus, GetEncryptType(pEntry->WepStatus), + group_cipher, GetEncryptType(group_cipher))); + } + else + { + // send wireless event - for set key done WPA + if (pAd->CommonCfg.bWirelessEvent) + RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA1_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + DBGPRINT(RT_DEBUG_OFF, ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n", + pEntry->AuthMode, GetAuthMode(pEntry->AuthMode), + pEntry->WepStatus, GetEncryptType(pEntry->WepStatus), + group_cipher, GetEncryptType(group_cipher))); + } + }while(FALSE); +} + +/* + ======================================================================== + + Routine Description: + Classify WPA EAP message type + + Arguments: + EAPType Value of EAP message type + MsgType Internal Message definition for MLME state machine + + Return Value: + TRUE Found appropriate message type + FALSE No appropriate message type + + IRQL = DISPATCH_LEVEL + + Note: + All these constants are defined in wpa.h + For supplicant, there is only EAPOL Key message avaliable + + ======================================================================== +*/ +BOOLEAN WpaMsgTypeSubst( + IN UCHAR EAPType, + OUT INT *MsgType) +{ + switch (EAPType) + { + case EAPPacket: + *MsgType = MT2_EAPPacket; + break; + case EAPOLStart: + *MsgType = MT2_EAPOLStart; + break; + case EAPOLLogoff: + *MsgType = MT2_EAPOLLogoff; + break; + case EAPOLKey: + *MsgType = MT2_EAPOLKey; + break; + case EAPOLASFAlert: + *MsgType = MT2_EAPOLASFAlert; + break; + default: + return FALSE; + } + return TRUE; +} + +/* + ======================================================================== + + Routine Description: + The pseudo-random function(PRF) that hashes various inputs to + derive a pseudo-random value. To add liveness to the pseudo-random + value, a nonce should be one of the inputs. + + It is used to generate PTK, GTK or some specific random value. + + Arguments: + UCHAR *key, - the key material for HMAC_SHA1 use + INT key_len - the length of key + UCHAR *prefix - a prefix label + INT prefix_len - the length of the label + UCHAR *data - a specific data with variable length + INT data_len - the length of a specific data + INT len - the output lenght + + Return Value: + UCHAR *output - the calculated result + + Note: + 802.11i-2004 Annex H.3 + + ======================================================================== +*/ +VOID PRF( + IN UCHAR *key, + IN INT key_len, + IN UCHAR *prefix, + IN INT prefix_len, + IN UCHAR *data, + IN INT data_len, + OUT UCHAR *output, + IN INT len) +{ + INT i; + UCHAR *input; + INT currentindex = 0; + INT total_len; + + // Allocate memory for input + os_alloc_mem(NULL, (PUCHAR *)&input, 1024); + + if (input == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n")); + return; + } + + // Generate concatenation input + NdisMoveMemory(input, prefix, prefix_len); + + // Concatenate a single octet containing 0 + input[prefix_len] = 0; + + // Concatenate specific data + NdisMoveMemory(&input[prefix_len + 1], data, data_len); + total_len = prefix_len + 1 + data_len; + + // Concatenate a single octet containing 0 + // This octet shall be update later + input[total_len] = 0; + total_len++; + + // Iterate to calculate the result by hmac-sha-1 + // Then concatenate to last result + for (i = 0; i < (len + 19) / 20; i++) + { + HMAC_SHA1(key, key_len, input, total_len, &output[currentindex], SHA1_DIGEST_SIZE); + currentindex += 20; + + // update the last octet + input[total_len - 1]++; + } + os_free_mem(NULL, input); +} + +/* +* F(P, S, c, i) = U1 xor U2 xor ... Uc +* U1 = PRF(P, S || Int(i)) +* U2 = PRF(P, U1) +* Uc = PRF(P, Uc-1) +*/ + +static void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output) +{ + unsigned char digest[36], digest1[SHA1_DIGEST_SIZE]; + int i, j; + + /* U1 = PRF(P, S || int(i)) */ + memcpy(digest, ssid, ssidlength); + digest[ssidlength] = (unsigned char)((count>>24) & 0xff); + digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff); + digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff); + digest[ssidlength+3] = (unsigned char)(count & 0xff); + HMAC_SHA1((unsigned char*) password, (int) strlen(password), digest, ssidlength+4, digest1, SHA1_DIGEST_SIZE); // for WPA update + + /* output = U1 */ + memcpy(output, digest1, SHA1_DIGEST_SIZE); + + for (i = 1; i < iterations; i++) + { + /* Un = PRF(P, Un-1) */ + HMAC_SHA1((unsigned char*) password, (int) strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE); // for WPA update + memcpy(digest1, digest, SHA1_DIGEST_SIZE); + + /* output = output xor Un */ + for (j = 0; j < SHA1_DIGEST_SIZE; j++) + { + output[j] ^= digest[j]; + } + } +} + +/* +* password - ascii string up to 63 characters in length +* ssid - octet string up to 32 octets +* ssidlength - length of ssid in octets +* output must be 40 octets in length and outputs 256 bits of key +*/ +int PasswordHash(PSTRING password, PUCHAR ssid, INT ssidlength, PUCHAR output) +{ + if ((strlen(password) > 63) || (ssidlength > 32)) + return 0; + + F(password, ssid, ssidlength, 4096, 1, output); + F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]); + return 1; +} + + + +/* + ======================================================================== + + Routine Description: + It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK. + It shall be called by 4-way handshake processing. + + Arguments: + pAd - pointer to our pAdapter context + PMK - pointer to PMK + ANonce - pointer to ANonce + AA - pointer to Authenticator Address + SNonce - pointer to SNonce + SA - pointer to Supplicant Address + len - indicate the length of PTK (octet) + + Return Value: + Output pointer to the PTK + + Note: + Refer to IEEE 802.11i-2004 8.5.1.2 + + ======================================================================== +*/ +VOID WpaDerivePTK( + IN PRTMP_ADAPTER pAd, + IN UCHAR *PMK, + IN UCHAR *ANonce, + IN UCHAR *AA, + IN UCHAR *SNonce, + IN UCHAR *SA, + OUT UCHAR *output, + IN UINT len) +{ + UCHAR concatenation[76]; + UINT CurrPos = 0; + UCHAR temp[32]; + UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ', + 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'}; + + // initiate the concatenation input + NdisZeroMemory(temp, sizeof(temp)); + NdisZeroMemory(concatenation, 76); + + // Get smaller address + if (RTMPCompareMemory(SA, AA, 6) == 1) + NdisMoveMemory(concatenation, AA, 6); + else + NdisMoveMemory(concatenation, SA, 6); + CurrPos += 6; + + // Get larger address + if (RTMPCompareMemory(SA, AA, 6) == 1) + NdisMoveMemory(&concatenation[CurrPos], SA, 6); + else + NdisMoveMemory(&concatenation[CurrPos], AA, 6); + + // store the larger mac address for backward compatible of + // ralink proprietary STA-key issue + NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN); + CurrPos += 6; + + // Get smaller Nonce + if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) + NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue + else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) + NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); + else + NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); + CurrPos += 32; + + // Get larger Nonce + if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) + NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue + else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) + NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); + else + NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); + CurrPos += 32; + + hex_dump("concatenation=", concatenation, 76); + + // Use PRF to generate PTK + PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len); + +} + +/* + ======================================================================== + + Routine Description: + Generate random number by software. + + Arguments: + pAd - pointer to our pAdapter context + macAddr - pointer to local MAC address + + Return Value: + + Note: + 802.1ii-2004 Annex H.5 + + ======================================================================== +*/ +VOID GenRandom( + IN PRTMP_ADAPTER pAd, + IN UCHAR *macAddr, + OUT UCHAR *random) +{ + INT i, curr; + UCHAR local[80], KeyCounter[32]; + UCHAR result[80]; + ULONG CurrentTime; + UCHAR prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'}; + + // Zero the related information + NdisZeroMemory(result, 80); + NdisZeroMemory(local, 80); + NdisZeroMemory(KeyCounter, 32); + + for (i = 0; i < 32; i++) + { + // copy the local MAC address + COPY_MAC_ADDR(local, macAddr); + curr = MAC_ADDR_LEN; + + // concatenate the current time + NdisGetSystemUpTime(&CurrentTime); + NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime)); + curr += sizeof(CurrentTime); + + // concatenate the last result + NdisMoveMemory(&local[curr], result, 32); + curr += 32; + + // concatenate a variable + NdisMoveMemory(&local[curr], &i, 2); + curr += 2; + + // calculate the result + PRF(KeyCounter, 32, prefix,12, local, curr, result, 32); + } + + NdisMoveMemory(random, result, 32); +} + +/* + ======================================================================== + + Routine Description: + Build cipher suite in RSN-IE. + It only shall be called by RTMPMakeRSNIE. + + Arguments: + pAd - pointer to our pAdapter context + ElementID - indicate the WPA1 or WPA2 + WepStatus - indicate the encryption type + bMixCipher - a boolean to indicate the pairwise cipher and group + cipher are the same or not + + Return Value: + + Note: + + ======================================================================== +*/ +static VOID RTMPMakeRsnIeCipher( + IN PRTMP_ADAPTER pAd, + IN UCHAR ElementID, + IN UINT WepStatus, + IN BOOLEAN bMixCipher, + IN UCHAR FlexibleCipher, + OUT PUCHAR pRsnIe, + OUT UCHAR *rsn_len) +{ + UCHAR PairwiseCnt; + + *rsn_len = 0; + + // decide WPA2 or WPA1 + if (ElementID == Wpa2Ie) + { + RSNIE2 *pRsnie_cipher = (RSNIE2*)pRsnIe; + + // Assign the verson as 1 + pRsnie_cipher->version = 1; + + switch (WepStatus) + { + // TKIP mode + case Ndis802_11Encryption2Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); + pRsnie_cipher->ucount = 1; + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4); + *rsn_len = sizeof(RSNIE2); + break; + + // AES mode + case Ndis802_11Encryption3Enabled: + if (bMixCipher) + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); + else + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4); + pRsnie_cipher->ucount = 1; + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4); + *rsn_len = sizeof(RSNIE2); + break; + + // TKIP-AES mix mode + case Ndis802_11Encryption4Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); + + PairwiseCnt = 1; + // Insert WPA2 TKIP as the first pairwise cipher + if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) + { + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4); + // Insert WPA2 AES as the secondary pairwise cipher + if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) + { + NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4); + PairwiseCnt = 2; + } + } + else + { + // Insert WPA2 AES as the first pairwise cipher + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4); + } + + pRsnie_cipher->ucount = PairwiseCnt; + *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1)); + break; + } + + if ((pAd->OpMode == OPMODE_STA) && + (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) && + (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) + { + UINT GroupCipher = pAd->StaCfg.GroupCipher; + switch(GroupCipher) + { + case Ndis802_11GroupWEP40Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP40, 4); + break; + case Ndis802_11GroupWEP104Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP104, 4); + break; + } + } + + // swap for big-endian platform + pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version); + pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount); + } + else + { + RSNIE *pRsnie_cipher = (RSNIE*)pRsnIe; + + // Assign OUI and version + NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4); + pRsnie_cipher->version = 1; + + switch (WepStatus) + { + // TKIP mode + case Ndis802_11Encryption2Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); + pRsnie_cipher->ucount = 1; + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4); + *rsn_len = sizeof(RSNIE); + break; + + // AES mode + case Ndis802_11Encryption3Enabled: + if (bMixCipher) + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); + else + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4); + pRsnie_cipher->ucount = 1; + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4); + *rsn_len = sizeof(RSNIE); + break; + + // TKIP-AES mix mode + case Ndis802_11Encryption4Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); + + PairwiseCnt = 1; + // Insert WPA TKIP as the first pairwise cipher + if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) + { + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4); + // Insert WPA AES as the secondary pairwise cipher + if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) + { + NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4); + PairwiseCnt = 2; + } + } + else + { + // Insert WPA AES as the first pairwise cipher + NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4); + } + + pRsnie_cipher->ucount = PairwiseCnt; + *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1)); + break; + } + + if ((pAd->OpMode == OPMODE_STA) && + (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) && + (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) + { + UINT GroupCipher = pAd->StaCfg.GroupCipher; + switch(GroupCipher) + { + case Ndis802_11GroupWEP40Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP40, 4); + break; + case Ndis802_11GroupWEP104Enabled: + NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP104, 4); + break; + } + } + + // swap for big-endian platform + pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version); + pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount); + } +} + +/* + ======================================================================== + + Routine Description: + Build AKM suite in RSN-IE. + It only shall be called by RTMPMakeRSNIE. + + Arguments: + pAd - pointer to our pAdapter context + ElementID - indicate the WPA1 or WPA2 + AuthMode - indicate the authentication mode + apidx - indicate the interface index + + Return Value: + + Note: + + ======================================================================== +*/ +static VOID RTMPMakeRsnIeAKM( + IN PRTMP_ADAPTER pAd, + IN UCHAR ElementID, + IN UINT AuthMode, + IN UCHAR apidx, + OUT PUCHAR pRsnIe, + OUT UCHAR *rsn_len) +{ + RSNIE_AUTH *pRsnie_auth; + UCHAR AkmCnt = 1; // default as 1 + + pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len)); + + // decide WPA2 or WPA1 + if (ElementID == Wpa2Ie) + { + + switch (AuthMode) + { + case Ndis802_11AuthModeWPA2: + case Ndis802_11AuthModeWPA1WPA2: + NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4); + break; + + case Ndis802_11AuthModeWPA2PSK: + case Ndis802_11AuthModeWPA1PSKWPA2PSK: + NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4); + break; + default: + AkmCnt = 0; + break; + + } + } + else + { + switch (AuthMode) + { + case Ndis802_11AuthModeWPA: + case Ndis802_11AuthModeWPA1WPA2: + NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4); + break; + + case Ndis802_11AuthModeWPAPSK: + case Ndis802_11AuthModeWPA1PSKWPA2PSK: + NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4); + break; + + case Ndis802_11AuthModeWPANone: + NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4); + break; + default: + AkmCnt = 0; + break; + } + } + + pRsnie_auth->acount = AkmCnt; + pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount); + + // update current RSNIE length + (*rsn_len) += (sizeof(RSNIE_AUTH) + (4 * (AkmCnt - 1))); + +} + +/* + ======================================================================== + + Routine Description: + Build capability in RSN-IE. + It only shall be called by RTMPMakeRSNIE. + + Arguments: + pAd - pointer to our pAdapter context + ElementID - indicate the WPA1 or WPA2 + apidx - indicate the interface index + + Return Value: + + Note: + + ======================================================================== +*/ +static VOID RTMPMakeRsnIeCap( + IN PRTMP_ADAPTER pAd, + IN UCHAR ElementID, + IN UCHAR apidx, + OUT PUCHAR pRsnIe, + OUT UCHAR *rsn_len) +{ + RSN_CAPABILITIES *pRSN_Cap; + + // it could be ignored in WPA1 mode + if (ElementID == WpaIe) + return; + + pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len)); + + + pRSN_Cap->word = cpu2le16(pRSN_Cap->word); + + (*rsn_len) += sizeof(RSN_CAPABILITIES); // update current RSNIE length + +} + /* ======================================================================== - Routine Description: - The pseudo-random function(PRF) that hashes various inputs to - derive a pseudo-random value. To add liveness to the pseudo-random - value, a nonce should be one of the inputs. + Routine Description: + Build RSN IE context. It is not included element-ID and length. + + Arguments: + pAd - pointer to our pAdapter context + AuthMode - indicate the authentication mode + WepStatus - indicate the encryption type + apidx - indicate the interface index + + Return Value: + + Note: + + ======================================================================== +*/ +VOID RTMPMakeRSNIE( + IN PRTMP_ADAPTER pAd, + IN UINT AuthMode, + IN UINT WepStatus, + IN UCHAR apidx) +{ + PUCHAR pRsnIe = NULL; // primary RSNIE + UCHAR *rsnielen_cur_p = 0; // the length of the primary RSNIE + UCHAR *rsnielen_ex_cur_p = 0; // the length of the secondary RSNIE + UCHAR PrimaryRsnie; + BOOLEAN bMixCipher = FALSE; // indicate the pairwise and group cipher are different + UCHAR p_offset; + WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES; // it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode + + rsnielen_cur_p = NULL; + rsnielen_ex_cur_p = NULL; + + { + { + if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) + { + if (AuthMode < Ndis802_11AuthModeWPA) + return; + } + else + { + // Support WPAPSK or WPA2PSK in STA-Infra mode + // Support WPANone in STA-Adhoc mode + if ((AuthMode != Ndis802_11AuthModeWPAPSK) && + (AuthMode != Ndis802_11AuthModeWPA2PSK) && + (AuthMode != Ndis802_11AuthModeWPANone) + ) + return; + } + + DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n")); - It is used to generate PTK, GTK or some specific random value. + // Zero RSNIE context + pAd->StaCfg.RSNIE_Len = 0; + NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE); - Arguments: - UCHAR *key, - the key material for HMAC_SHA1 use - INT key_len - the length of key - UCHAR *prefix - a prefix label - INT prefix_len - the length of the label - UCHAR *data - a specific data with variable length - INT data_len - the length of a specific data - INT len - the output lenght + // Pointer to RSNIE + rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len; + pRsnIe = pAd->StaCfg.RSN_IE; - Return Value: - UCHAR *output - the calculated result + bMixCipher = pAd->StaCfg.bMixCipher; + } + } - Note: - 802.11i-2004 Annex H.3 + // indicate primary RSNIE as WPA or WPA2 + if ((AuthMode == Ndis802_11AuthModeWPA) || + (AuthMode == Ndis802_11AuthModeWPAPSK) || + (AuthMode == Ndis802_11AuthModeWPANone) || + (AuthMode == Ndis802_11AuthModeWPA1WPA2) || + (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) + PrimaryRsnie = WpaIe; + else + PrimaryRsnie = Wpa2Ie; - ======================================================================== + { + // Build the primary RSNIE + // 1. insert cipher suite + RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset); + + // 2. insert AKM + RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset); + + // 3. insert capability + RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset); + } + + // 4. update the RSNIE length + *rsnielen_cur_p = p_offset; + + hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p)); + + +} + +/* + ========================================================================== + Description: + Check whether the received frame is EAP frame. + + Arguments: + pAd - pointer to our pAdapter context + pEntry - pointer to active entry + pData - the received frame + DataByteCount - the received frame's length + FromWhichBSSID - indicate the interface index + + Return: + TRUE - This frame is EAP frame + FALSE - otherwise + ========================================================================== */ -VOID PRF( - IN UCHAR *key, - IN INT key_len, - IN UCHAR *prefix, - IN INT prefix_len, - IN UCHAR *data, - IN INT data_len, - OUT UCHAR *output, - IN INT len) +BOOLEAN RTMPCheckWPAframe( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pData, + IN ULONG DataByteCount, + IN UCHAR FromWhichBSSID) { - INT i; - UCHAR *input; - INT currentindex = 0; - INT total_len; + ULONG Body_len; + BOOLEAN Cancelled; - // Allocate memory for input - os_alloc_mem(NULL, (PUCHAR *)&input, 1024); - if (input == NULL) + if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H)) + return FALSE; + + + // Skip LLC header + if (NdisEqualMemory(SNAP_802_1H, pData, 6) || + // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL + NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)) { - DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n")); - return; + pData += 6; + } + // Skip 2-bytes EAPoL type + if (NdisEqualMemory(EAPOL, pData, 2)) + { + pData += 2; } + else + return FALSE; - // Generate concatenation input - NdisMoveMemory(input, prefix, prefix_len); + switch (*(pData+1)) + { + case EAPPacket: + Body_len = (*(pData+2)<<8) | (*(pData+3)); + DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len)); + break; + case EAPOLStart: + DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n")); + if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE) + { + DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n")); + RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled); + pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; + } + break; + case EAPOLLogoff: + DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n")); + break; + case EAPOLKey: + Body_len = (*(pData+2)<<8) | (*(pData+3)); + DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len)); + break; + case EAPOLASFAlert: + DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n")); + break; + default: + return FALSE; - // Concatenate a single octet containing 0 - input[prefix_len] = 0; + } + return TRUE; +} - // Concatenate specific data - NdisMoveMemory(&input[prefix_len + 1], data, data_len); - total_len = prefix_len + 1 + data_len; +/* + ========================================================================== + Description: + Report the EAP message type - // Concatenate a single octet containing 0 - // This octet shall be update later - input[total_len] = 0; - total_len++; + Arguments: + msg - EAPOL_PAIR_MSG_1 + EAPOL_PAIR_MSG_2 + EAPOL_PAIR_MSG_3 + EAPOL_PAIR_MSG_4 + EAPOL_GROUP_MSG_1 + EAPOL_GROUP_MSG_2 - // Iterate to calculate the result by hmac-sha-1 - // Then concatenate to last result - for (i = 0; i < (len + 19) / 20; i++) - { - HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]); - currentindex += 20; + Return: + message type string - // update the last octet - input[total_len - 1]++; - } - os_free_mem(NULL, input); + ========================================================================== +*/ +PSTRING GetEapolMsgType(CHAR msg) +{ + if(msg == EAPOL_PAIR_MSG_1) + return "Pairwise Message 1"; + else if(msg == EAPOL_PAIR_MSG_2) + return "Pairwise Message 2"; + else if(msg == EAPOL_PAIR_MSG_3) + return "Pairwise Message 3"; + else if(msg == EAPOL_PAIR_MSG_4) + return "Pairwise Message 4"; + else if(msg == EAPOL_GROUP_MSG_1) + return "Group Message 1"; + else if(msg == EAPOL_GROUP_MSG_2) + return "Group Message 2"; + else + return "Invalid Message"; } + /* ======================================================================== Routine Description: - It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK. - It shall be called by 4-way handshake processing. + Check Sanity RSN IE of EAPoL message Arguments: - pAd - pointer to our pAdapter context - PMK - pointer to PMK - ANonce - pointer to ANonce - AA - pointer to Authenticator Address - SNonce - pointer to SNonce - SA - pointer to Supplicant Address - len - indicate the length of PTK (octet) Return Value: - Output pointer to the PTK - Note: - Refer to IEEE 802.11i-2004 8.5.1.2 ======================================================================== */ -VOID WpaCountPTK( +BOOLEAN RTMPCheckRSNIE( IN PRTMP_ADAPTER pAd, - IN UCHAR *PMK, - IN UCHAR *ANonce, - IN UCHAR *AA, - IN UCHAR *SNonce, - IN UCHAR *SA, - OUT UCHAR *output, - IN UINT len) + IN PUCHAR pData, + IN UCHAR DataLen, + IN MAC_TABLE_ENTRY *pEntry, + OUT UCHAR *Offset) { - UCHAR concatenation[76]; - UINT CurrPos = 0; - UCHAR temp[32]; - UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ', - 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'}; - - // initiate the concatenation input - NdisZeroMemory(temp, sizeof(temp)); - NdisZeroMemory(concatenation, 76); + PUCHAR pVIE; + UCHAR len; + PEID_STRUCT pEid; + BOOLEAN result = FALSE; + + pVIE = pData; + len = DataLen; + *Offset = 0; - // Get smaller address - if (RTMPCompareMemory(SA, AA, 6) == 1) - NdisMoveMemory(concatenation, AA, 6); - else - NdisMoveMemory(concatenation, SA, 6); - CurrPos += 6; + while (len > sizeof(RSNIE2)) + { + pEid = (PEID_STRUCT) pVIE; + // WPA RSN IE + if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) + { + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) && + (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) && + (pEntry->RSNIE_Len == (pEid->Len + 2))) + { + result = TRUE; + } - // Get larger address - if (RTMPCompareMemory(SA, AA, 6) == 1) - NdisMoveMemory(&concatenation[CurrPos], SA, 6); - else - NdisMoveMemory(&concatenation[CurrPos], AA, 6); + *Offset += (pEid->Len + 2); + } + // WPA2 RSN IE + else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) + { + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) && + (pEid->Eid == pEntry->RSN_IE[0]) && + ((pEid->Len + 2) >= pEntry->RSNIE_Len) && + (NdisEqualMemory(pEid->Octet, &pEntry->RSN_IE[2], pEntry->RSNIE_Len - 2))) + { - // store the larger mac address for backward compatible of - // ralink proprietary STA-key issue - NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN); - CurrPos += 6; + result = TRUE; + } - // Get smaller Nonce - if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) - NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue - else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) - NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); + *Offset += (pEid->Len + 2); + } else - NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); - CurrPos += 32; + { + break; + } - // Get larger Nonce - if (RTMPCompareMemory(ANonce, SNonce, 32) == 0) - NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue - else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1) - NdisMoveMemory(&concatenation[CurrPos], ANonce, 32); - else - NdisMoveMemory(&concatenation[CurrPos], SNonce, 32); - CurrPos += 32; + pVIE += (pEid->Len + 2); + len -= (pEid->Len + 2); + } - hex_dump("concatenation=", concatenation, 76); - // Use PRF to generate PTK - PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len); + return result; } @@ -226,323 +2137,550 @@ VOID WpaCountPTK( ======================================================================== Routine Description: - Generate random number by software. + Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK. + GTK is encaptulated in KDE format at p.83 802.11i D10 Arguments: - pAd - pointer to our pAdapter context - macAddr - pointer to local MAC address Return Value: Note: - 802.1ii-2004 Annex H.5 + 802.11i D10 ======================================================================== */ -VOID GenRandom( +BOOLEAN RTMPParseEapolKeyData( IN PRTMP_ADAPTER pAd, - IN UCHAR *macAddr, - OUT UCHAR *random) + IN PUCHAR pKeyData, + IN UCHAR KeyDataLen, + IN UCHAR GroupKeyIndex, + IN UCHAR MsgType, + IN BOOLEAN bWPA2, + IN MAC_TABLE_ENTRY *pEntry) { - INT i, curr; - UCHAR local[80], KeyCounter[32]; - UCHAR result[80]; - ULONG CurrentTime; - UCHAR prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'}; + PKDE_ENCAP pKDE = NULL; + PUCHAR pMyKeyData = pKeyData; + UCHAR KeyDataLength = KeyDataLen; + UCHAR GTKLEN = 0; + UCHAR DefaultIdx = 0; + UCHAR skip_offset; - // Zero the related information - NdisZeroMemory(result, 80); - NdisZeroMemory(local, 80); - NdisZeroMemory(KeyCounter, 32); + // Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it + if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3) + { + // Check RSN IE whether it is WPA2/WPA2PSK + if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset)) + { + // send wireless event - for RSN IE different + if (pAd->CommonCfg.bWirelessEvent) + RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0); + + DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType)); + hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen); + hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len); - for (i = 0; i < 32; i++) + return FALSE; + } + else + { + if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3) + { + WpaShowAllsuite(pMyKeyData, skip_offset); + + // skip RSN IE + pMyKeyData += skip_offset; + KeyDataLength -= skip_offset; + DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset)); + } + else + return TRUE; + } + } + + DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength)); + //hex_dump("remain data", pMyKeyData, KeyDataLength); + + + // Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2 + if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)) { - // copy the local MAC address - COPY_MAC_ADDR(local, macAddr); - curr = MAC_ADDR_LEN; + if (KeyDataLength >= 8) // KDE format exclude GTK length + { + pKDE = (PKDE_ENCAP) pMyKeyData; - // concatenate the current time - NdisGetSystemUpTime(&CurrentTime); - NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime)); - curr += sizeof(CurrentTime); - // concatenate the last result - NdisMoveMemory(&local[curr], result, 32); - curr += 32; + DefaultIdx = pKDE->GTKEncap.Kid; - // concatenate a variable - NdisMoveMemory(&local[curr], &i, 2); - curr += 2; + // Sanity check - KED length + if (KeyDataLength < (pKDE->Len + 2)) + { + DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n")); + return FALSE; + } - // calculate the result - PRF(KeyCounter, 32, prefix,12, local, curr, result, 32); + // Get GTK length - refer to IEEE 802.11i-2004 p.82 + GTKLEN = pKDE->Len -6; + if (GTKLEN < LEN_AES_KEY) + { + DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN)); + return FALSE; + } + + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n")); + return FALSE; } - NdisMoveMemory(random, result, 32); + DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN)); + // skip it + pMyKeyData += 8; + KeyDataLength -= 8; + + } + else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) + { + DefaultIdx = GroupKeyIndex; + DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx)); + } + + // Sanity check - shared key index must be 1 ~ 3 + if (DefaultIdx < 1 || DefaultIdx > 3) + { + DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType))); + return FALSE; + } + + { + PCIPHER_KEY pSharedKey; + + // set key material, TxMic and RxMic + NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32); + pAd->StaCfg.DefaultKeyId = DefaultIdx; + + pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId]; + + // Prepare pair-wise key information into shared key table + NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY)); + pSharedKey->KeyLen = LEN_TKIP_EK; + NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK); + NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16], LEN_TKIP_RXMICK); + NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24], LEN_TKIP_TXMICK); + + // Update Shared Key CipherAlg + pSharedKey->CipherAlg = CIPHER_NONE; + if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled) + pSharedKey->CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled) + pSharedKey->CipherAlg = CIPHER_AES; + else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled) + pSharedKey->CipherAlg = CIPHER_WEP64; + else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled) + pSharedKey->CipherAlg = CIPHER_WEP128; + + + // Update group key information to ASIC Shared Key Table + AsicAddSharedKeyEntry(pAd, + BSS0, + pAd->StaCfg.DefaultKeyId, + pSharedKey->CipherAlg, + pSharedKey->Key, + pSharedKey->TxMic, + pSharedKey->RxMic); + + // Update ASIC WCID attribute table and IVEIV table + RTMPAddWcidAttributeEntry(pAd, + BSS0, + pAd->StaCfg.DefaultKeyId, + pSharedKey->CipherAlg, + NULL); + } + + return TRUE; + } + /* ======================================================================== Routine Description: - Build cipher suite in RSN-IE. - It only shall be called by RTMPMakeRSNIE. + Construct EAPoL message for WPA handshaking + Its format is below, + + +--------------------+ + | Protocol Version | 1 octet + +--------------------+ + | Protocol Type | 1 octet + +--------------------+ + | Body Length | 2 octets + +--------------------+ + | Descriptor Type | 1 octet + +--------------------+ + | Key Information | 2 octets + +--------------------+ + | Key Length | 1 octet + +--------------------+ + | Key Repaly Counter | 8 octets + +--------------------+ + | Key Nonce | 32 octets + +--------------------+ + | Key IV | 16 octets + +--------------------+ + | Key RSC | 8 octets + +--------------------+ + | Key ID or Reserved | 8 octets + +--------------------+ + | Key MIC | 16 octets + +--------------------+ + | Key Data Length | 2 octets + +--------------------+ + | Key Data | n octets + +--------------------+ + Arguments: - pAd - pointer to our pAdapter context - ElementID - indicate the WPA1 or WPA2 - WepStatus - indicate the encryption type - bMixCipher - a boolean to indicate the pairwise cipher and group - cipher are the same or not + pAd Pointer to our adapter Return Value: + None Note: ======================================================================== */ -static VOID RTMPInsertRsnIeCipher( - IN PRTMP_ADAPTER pAd, - IN UCHAR ElementID, - IN UINT WepStatus, - IN BOOLEAN bMixCipher, - IN UCHAR FlexibleCipher, - OUT PUCHAR pRsnIe, - OUT UCHAR *rsn_len) +VOID ConstructEapolMsg( + IN PMAC_TABLE_ENTRY pEntry, + IN UCHAR GroupKeyWepStatus, + IN UCHAR MsgType, + IN UCHAR DefaultKeyIdx, + IN UCHAR *KeyNonce, + IN UCHAR *TxRSC, + IN UCHAR *GTK, + IN UCHAR *RSNIE, + IN UCHAR RSNIE_Len, + OUT PEAPOL_PACKET pMsg) { - UCHAR PairwiseCnt; + BOOLEAN bWPA2 = FALSE; + UCHAR KeyDescVer; - *rsn_len = 0; + // Choose WPA2 or not + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || + (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) + bWPA2 = TRUE; + + // Init Packet and Fill header + pMsg->ProVer = EAPOL_VER; + pMsg->ProType = EAPOLKey; + + // Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field + SET_UINT16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG); + + // Fill in EAPoL descriptor + if (bWPA2) + pMsg->KeyDesc.Type = WPA2_KEY_DESC; + else + pMsg->KeyDesc.Type = WPA1_KEY_DESC; - // decide WPA2 or WPA1 - if (ElementID == Wpa2Ie) + // Key Descriptor Version (bits 0-2) specifies the key descriptor version type { - RSNIE2 *pRsnie_cipher = (RSNIE2*)pRsnIe; - - // Assign the verson as 1 - pRsnie_cipher->version = 1; + // Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 + // When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used. + KeyDescVer = (((pEntry->WepStatus == Ndis802_11Encryption3Enabled) || + (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP)); + } - switch (WepStatus) - { - // TKIP mode - case Ndis802_11Encryption2Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); - pRsnie_cipher->ucount = 1; - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4); - *rsn_len = sizeof(RSNIE2); - break; + pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer; - // AES mode - case Ndis802_11Encryption3Enabled: - if (bMixCipher) - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); + // Specify Key Type as Group(0) or Pairwise(1) + if (MsgType >= EAPOL_GROUP_MSG_1) + pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY; else - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4); - pRsnie_cipher->ucount = 1; - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4); - *rsn_len = sizeof(RSNIE2); - break; + pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY; - // TKIP-AES mix mode - case Ndis802_11Encryption4Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4); + // Specify Key Index, only group_msg1_WPA1 + if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)) + pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx; - PairwiseCnt = 1; - // Insert WPA2 TKIP as the first pairwise cipher - if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) - { - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4); - // Insert WPA2 AES as the secondary pairwise cipher - if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) + if (MsgType == EAPOL_PAIR_MSG_3) + pMsg->KeyDesc.KeyInfo.Install = 1; + + if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)) + pMsg->KeyDesc.KeyInfo.KeyAck = 1; + + if (MsgType != EAPOL_PAIR_MSG_1) + pMsg->KeyDesc.KeyInfo.KeyMic = 1; + + if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || + (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) { - NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4); - PairwiseCnt = 2; + pMsg->KeyDesc.KeyInfo.Secure = 1; } - } - else + + if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || + (MsgType == EAPOL_GROUP_MSG_1))) { - // Insert WPA2 AES as the first pairwise cipher - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4); + pMsg->KeyDesc.KeyInfo.EKD_DL = 1; } - pRsnie_cipher->ucount = PairwiseCnt; - *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1)); - break; - } + // key Information element has done. + *(USHORT *)(&pMsg->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo)); - if ((pAd->OpMode == OPMODE_STA) && - (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) && - (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) + // Fill in Key Length { - UINT GroupCipher = pAd->StaCfg.GroupCipher; - switch(GroupCipher) + if (MsgType >= EAPOL_GROUP_MSG_1) { - case Ndis802_11GroupWEP40Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP40, 4); - break; - case Ndis802_11GroupWEP104Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP104, 4); - break; - } - } - - // swap for big-endian platform - pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version); - pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount); + // the length of group key cipher + pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY); } else { - RSNIE *pRsnie_cipher = (RSNIE*)pRsnIe; - - // Assign OUI and version - NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4); - pRsnie_cipher->version = 1; - - switch (WepStatus) - { - // TKIP mode - case Ndis802_11Encryption2Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); - pRsnie_cipher->ucount = 1; - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4); - *rsn_len = sizeof(RSNIE); - break; + // the length of pairwise key cipher + pMsg->KeyDesc.KeyLength[1] = ((pEntry->WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY); + } + } - // AES mode - case Ndis802_11Encryption3Enabled: - if (bMixCipher) - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); - else - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4); - pRsnie_cipher->ucount = 1; - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4); - *rsn_len = sizeof(RSNIE); - break; + // Fill in replay counter + NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY); - // TKIP-AES mix mode - case Ndis802_11Encryption4Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4); + // Fill Key Nonce field + // ANonce : pairwise_msg1 & pairwise_msg3 + // SNonce : pairwise_msg2 + // GNonce : group_msg1_wpa1 + if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)))) + NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE); - PairwiseCnt = 1; - // Insert WPA TKIP as the first pairwise cipher - if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) - { - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4); - // Insert WPA AES as the secondary pairwise cipher - if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) + // Fill key IV - WPA2 as 0, WPA1 as random + if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) { - NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4); - PairwiseCnt = 2; - } + // Suggest IV be random number plus some number, + NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV); + pMsg->KeyDesc.KeyIv[15] += 2; } - else + + // Fill Key RSC field + // It contains the RSC for the GTK being installed. + if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1)) { - // Insert WPA AES as the first pairwise cipher - NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4); + NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6); } - pRsnie_cipher->ucount = PairwiseCnt; - *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1)); - break; - } + // Clear Key MIC field for MIC calculation later + NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); - if ((pAd->OpMode == OPMODE_STA) && - (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) && - (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) - { - UINT GroupCipher = pAd->StaCfg.GroupCipher; - switch(GroupCipher) + ConstructEapolKeyData(pEntry, + GroupKeyWepStatus, + KeyDescVer, + MsgType, + DefaultKeyIdx, + GTK, + RSNIE, + RSNIE_Len, + pMsg); + + // Calculate MIC and fill in KeyMic Field except Pairwise Msg 1. + if (MsgType != EAPOL_PAIR_MSG_1) { - case Ndis802_11GroupWEP40Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP40, 4); - break; - case Ndis802_11GroupWEP104Enabled: - NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP104, 4); - break; - } + CalculateMIC(KeyDescVer, pEntry->PTK, pMsg); } - // swap for big-endian platform - pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version); - pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount); - } + DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType))); + DBGPRINT(RT_DEBUG_TRACE, (" Body length = %d \n", CONV_ARRARY_TO_UINT16(pMsg->Body_Len))); + DBGPRINT(RT_DEBUG_TRACE, (" Key length = %d \n", CONV_ARRARY_TO_UINT16(pMsg->KeyDesc.KeyLength))); + + } /* ======================================================================== Routine Description: - Build AKM suite in RSN-IE. - It only shall be called by RTMPMakeRSNIE. + Construct the Key Data field of EAPoL message Arguments: - pAd - pointer to our pAdapter context - ElementID - indicate the WPA1 or WPA2 - AuthMode - indicate the authentication mode - apidx - indicate the interface index + pAd Pointer to our adapter + Elem Message body Return Value: + None Note: ======================================================================== */ -static VOID RTMPInsertRsnIeAKM( - IN PRTMP_ADAPTER pAd, - IN UCHAR ElementID, - IN UINT AuthMode, - IN UCHAR apidx, - OUT PUCHAR pRsnIe, - OUT UCHAR *rsn_len) +VOID ConstructEapolKeyData( + IN PMAC_TABLE_ENTRY pEntry, + IN UCHAR GroupKeyWepStatus, + IN UCHAR keyDescVer, + IN UCHAR MsgType, + IN UCHAR DefaultKeyIdx, + IN UCHAR *GTK, + IN UCHAR *RSNIE, + IN UCHAR RSNIE_LEN, + OUT PEAPOL_PACKET pMsg) { - RSNIE_AUTH *pRsnie_auth; + UCHAR *mpool, *Key_Data, *Rc4GTK; + UCHAR ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)]; + ULONG data_offset; + BOOLEAN bWPA2Capable = FALSE; + PRTMP_ADAPTER pAd = pEntry->pAd; + BOOLEAN GTK_Included = FALSE; + + // Choose WPA2 or not + if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || + (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) + bWPA2Capable = TRUE; + + if (MsgType == EAPOL_PAIR_MSG_1 || + MsgType == EAPOL_PAIR_MSG_4 || + MsgType == EAPOL_GROUP_MSG_2) + return; + + // allocate memory pool + os_alloc_mem(NULL, (PUCHAR *)&mpool, 1500); + + if (mpool == NULL) + return; + + /* Rc4GTK Len = 512 */ + Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4); + /* Key_Data Len = 512 */ + Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4); + + NdisZeroMemory(Key_Data, 512); + SET_UINT16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0); + data_offset = 0; + + // Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 + if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3))) + { + PUINT8 pmkid_ptr = NULL; + UINT8 pmkid_len = 0; + + + RTMPInsertRSNIE(&Key_Data[data_offset], + &data_offset, + RSNIE, + RSNIE_LEN, + pmkid_ptr, + pmkid_len); + } + + + // Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2 + if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))) + { + // Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h + Key_Data[data_offset + 0] = 0xDD; + + if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) + { + Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField) + } + else + { + Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField) + } + + Key_Data[data_offset + 2] = 0x00; + Key_Data[data_offset + 3] = 0x0F; + Key_Data[data_offset + 4] = 0xAC; + Key_Data[data_offset + 5] = 0x01; + + // GTK KDE format - 802.11i-2004 Figure-43x + Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03); + Key_Data[data_offset + 7] = 0x00; // Reserved Byte + + data_offset += 8; + } + + + // Encapsulate GTK + // Only for pairwise_msg3_WPA2 and group_msg1 + if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1)) + { + // Fill in GTK + if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) + { + NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY); + data_offset += LEN_AES_KEY; + } + else + { + NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH); + data_offset += TKIP_GTK_LENGTH; + } + + GTK_Included = TRUE; + } + + + // This whole key-data field shall be encrypted if a GTK is included. + // Encrypt the data material in key data field with KEK + if (GTK_Included) + { + //hex_dump("GTK_Included", Key_Data, data_offset); + + if ( + (keyDescVer == DESC_TYPE_AES)) + { + UCHAR remainder = 0; + UCHAR pad_len = 0; - pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len)); + // Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394, + // shall be used to encrypt the Key Data field using the KEK field from + // the derived PTK. + + // If the Key Data field uses the NIST AES key wrap, then the Key Data field + // shall be padded before encrypting if the key data length is less than 16 + // octets or if it is not a multiple of 8. The padding consists of appending + // a single octet 0xdd followed by zero or more 0x00 octets. + if ((remainder = data_offset & 0x07) != 0) + { + INT i; - // decide WPA2 or WPA1 - if (ElementID == Wpa2Ie) - { - switch (AuthMode) - { - case Ndis802_11AuthModeWPA2: - case Ndis802_11AuthModeWPA1WPA2: - pRsnie_auth->acount = 1; - NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4); - break; + pad_len = (8 - remainder); + Key_Data[data_offset] = 0xDD; + for (i = 1; i < pad_len; i++) + Key_Data[data_offset + i] = 0; - case Ndis802_11AuthModeWPA2PSK: - case Ndis802_11AuthModeWPA1PSKWPA2PSK: - pRsnie_auth->acount = 1; - NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4); - break; + data_offset += pad_len; } + + AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data, data_offset, Rc4GTK); + // AES wrap function will grow 8 bytes in length + data_offset += 8; } else { - switch (AuthMode) - { - case Ndis802_11AuthModeWPA: - case Ndis802_11AuthModeWPA1WPA2: - pRsnie_auth->acount = 1; - NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4); - break; + /* Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field + using the KEK field from the derived PTK. */ - case Ndis802_11AuthModeWPAPSK: - case Ndis802_11AuthModeWPA1PSKWPA2PSK: - pRsnie_auth->acount = 1; - NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4); - break; + // PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV) + // put TxTsc in Key RSC field + pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32. + + // ekey is the contanetion of IV-field, and PTK[16]->PTK[31] + NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV); + NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16], LEN_EAP_EK); + ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); //INIT SBOX, KEYLEN+3(IV) + pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset); + WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset); + } - case Ndis802_11AuthModeWPANone: - pRsnie_auth->acount = 1; - NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4); - break; + NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset); } + else + { + NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset); } - pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount); + // Update key data length field and total body length + SET_UINT16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset); + INC_UINT16_TO_ARRARY(pMsg->Body_Len, data_offset); - (*rsn_len) += sizeof(RSNIE_AUTH); // update current RSNIE length + os_free_mem(NULL, mpool); } @@ -550,13 +2688,11 @@ static VOID RTMPInsertRsnIeAKM( ======================================================================== Routine Description: - Build capability in RSN-IE. - It only shall be called by RTMPMakeRSNIE. + Calcaulate MIC. It is used during 4-ways handsharking. Arguments: pAd - pointer to our pAdapter context - ElementID - indicate the WPA1 or WPA2 - apidx - indicate the interface index + PeerWepStatus - indicate the encryption type Return Value: @@ -564,273 +2700,413 @@ static VOID RTMPInsertRsnIeAKM( ======================================================================== */ -static VOID RTMPInsertRsnIeCap( - IN PRTMP_ADAPTER pAd, - IN UCHAR ElementID, - IN UCHAR apidx, - OUT PUCHAR pRsnIe, - OUT UCHAR *rsn_len) +static VOID CalculateMIC( + IN UCHAR KeyDescVer, + IN UCHAR *PTK, + OUT PEAPOL_PACKET pMsg) { - RSN_CAPABILITIES *pRSN_Cap; + UCHAR *OutBuffer; + ULONG FrameLen = 0; + UCHAR mic[LEN_KEY_DESC_MIC]; + UCHAR digest[80]; - // it could be ignored in WPA1 mode - if (ElementID == WpaIe) + // allocate memory for MIC calculation + os_alloc_mem(NULL, (PUCHAR *)&OutBuffer, 512); + + if (OutBuffer == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n")); return; + } - pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len)); + // make a frame for calculating MIC. + MakeOutgoingFrame(OutBuffer, &FrameLen, + CONV_ARRARY_TO_UINT16(pMsg->Body_Len) + 4, pMsg, + END_OF_ARGS); + NdisZeroMemory(mic, sizeof(mic)); - pRSN_Cap->word = cpu2le16(pRSN_Cap->word); + // Calculate MIC + if (KeyDescVer == DESC_TYPE_AES) + { + HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE); + NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC); + } + else + { + HMAC_MD5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic, MD5_DIGEST_SIZE); + } - (*rsn_len) += sizeof(RSN_CAPABILITIES); // update current RSNIE length + // store the calculated MIC + NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC); + os_free_mem(NULL, OutBuffer); } - /* ======================================================================== Routine Description: - Build RSN IE context. It is not included element-ID and length. + Some received frames can't decrypt by Asic, so decrypt them by software. Arguments: pAd - pointer to our pAdapter context - AuthMode - indicate the authentication mode - WepStatus - indicate the encryption type - apidx - indicate the interface index + PeerWepStatus - indicate the encryption type Return Value: - - Note: + NDIS_STATUS_SUCCESS - decryption successful + NDIS_STATUS_FAILURE - decryption failure ======================================================================== */ -VOID RTMPMakeRSNIE( +NDIS_STATUS RTMPSoftDecryptBroadCastData( IN PRTMP_ADAPTER pAd, - IN UINT AuthMode, - IN UINT WepStatus, - IN UCHAR apidx) + IN RX_BLK *pRxBlk, + IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher, + IN PCIPHER_KEY pShard_key) { - PUCHAR pRsnIe = NULL; // primary RSNIE - UCHAR *rsnielen_cur_p = 0; // the length of the primary RSNIE - UCHAR *rsnielen_ex_cur_p = 0; // the length of the secondary RSNIE - UCHAR PrimaryRsnie; - BOOLEAN bMixCipher = FALSE; // indicate the pairwise and group cipher are different - UCHAR p_offset; - WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES; // it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode + PRXWI_STRUC pRxWI = pRxBlk->pRxWI; + - rsnielen_cur_p = NULL; - rsnielen_ex_cur_p = NULL; + // handle WEP decryption + if (GroupCipher == Ndis802_11Encryption1Enabled) { + if (RTMPSoftDecryptWEP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, pShard_key)) { - if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) + + //Minus IV[4] & ICV[4] + pRxWI->MPDUtotalByteCount -= 8; + } + else { - if (AuthMode < Ndis802_11AuthModeWPA) - return; + DBGPRINT(RT_DEBUG_ERROR, ("ERROR : Software decrypt WEP data fails.\n")); + // give up this frame + return NDIS_STATUS_FAILURE; + } + } + // handle TKIP decryption + else if (GroupCipher == Ndis802_11Encryption2Enabled) + { + if (RTMPSoftDecryptTKIP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, pShard_key)) + { + + //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV + pRxWI->MPDUtotalByteCount -= 20; } else { - // Support WPAPSK or WPA2PSK in STA-Infra mode - // Support WPANone in STA-Adhoc mode - if ((AuthMode != Ndis802_11AuthModeWPAPSK) && - (AuthMode != Ndis802_11AuthModeWPA2PSK) && - (AuthMode != Ndis802_11AuthModeWPANone) - ) - return; + DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptTKIP Failed\n")); + // give up this frame + return NDIS_STATUS_FAILURE; } + } + // handle AES decryption + else if (GroupCipher == Ndis802_11Encryption3Enabled) + { + if (RTMPSoftDecryptAES(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount , pShard_key)) + { - DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n")); + //8 bytes MIC, 8 bytes IV/EIV (CCMP Header) + pRxWI->MPDUtotalByteCount -= 16; + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptAES Failed\n")); + // give up this frame + return NDIS_STATUS_FAILURE; + } + } + else + { + // give up this frame + return NDIS_STATUS_FAILURE; + } - // Zero RSNIE context - pAd->StaCfg.RSNIE_Len = 0; - NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE); + return NDIS_STATUS_SUCCESS; - // Pointer to RSNIE - rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len; - pRsnIe = pAd->StaCfg.RSN_IE; +} - bMixCipher = pAd->StaCfg.bMixCipher; - } + +PUINT8 GetSuiteFromRSNIE( + IN PUINT8 rsnie, + IN UINT rsnie_len, + IN UINT8 type, + OUT UINT8 *count) +{ + PEID_STRUCT pEid; + INT len; + PUINT8 pBuf; + INT offset = 0; + PRSNIE_AUTH pAkm; + UINT16 acount; + BOOLEAN isWPA2 = FALSE; + + pEid = (PEID_STRUCT)rsnie; + len = rsnie_len - 2; // exclude IE and length + pBuf = (PUINT8)&pEid->Octet[0]; + + + + // set default value + *count = 0; + + // Check length + if ((len <= 0) || (pEid->Len != len)) + { + DBGPRINT_ERR(("%s : The length is invalid\n", __func__)); + return NULL; } - // indicate primary RSNIE as WPA or WPA2 - if ((AuthMode == Ndis802_11AuthModeWPA) || - (AuthMode == Ndis802_11AuthModeWPAPSK) || - (AuthMode == Ndis802_11AuthModeWPANone) || - (AuthMode == Ndis802_11AuthModeWPA1WPA2) || - (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) - PrimaryRsnie = WpaIe; - else - PrimaryRsnie = Wpa2Ie; + // Check WPA or WPA2 + if (pEid->Eid == IE_WPA) + { + PRSNIE pRsnie = (PRSNIE)pBuf; + UINT16 ucount; + if (len < sizeof(RSNIE)) { - // Build the primary RSNIE - // 1. insert cipher suite - RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset); + DBGPRINT_ERR(("%s : The length is too short for WPA\n", __func__)); + return NULL; + } - // 2. insert AKM - RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset); + // Get the count of pairwise cipher + ucount = cpu2le16(pRsnie->ucount); + if (ucount > 2) + { + DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n", + __func__, ucount)); + return NULL; + } - // 3. insert capability - RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset); + // Get the group cipher + if (type == GROUP_SUITE) + { + *count = 1; + return pRsnie->mcast; + } + // Get the pairwise cipher suite + else if (type == PAIRWISE_SUITE) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of pairwise cipher is %d\n", + __func__, ucount)); + *count = ucount; + return pRsnie->ucast[0].oui; } - // 4. update the RSNIE length - *rsnielen_cur_p = p_offset; + offset = sizeof(RSNIE) + (4 * (ucount - 1)); - hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p)); + } + else if (pEid->Eid == IE_RSN) + { + PRSNIE2 pRsnie = (PRSNIE2)pBuf; + UINT16 ucount; + isWPA2 = TRUE; -} + if (len < sizeof(RSNIE2)) + { + DBGPRINT_ERR(("%s : The length is too short for WPA2\n", __func__)); + return NULL; + } -/* - ========================================================================== - Description: - Check whether the received frame is EAP frame. + // Get the count of pairwise cipher + ucount = cpu2le16(pRsnie->ucount); + if (ucount > 2) + { + DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n", + __func__, ucount)); + return NULL; + } - Arguments: - pAd - pointer to our pAdapter context - pEntry - pointer to active entry - pData - the received frame - DataByteCount - the received frame's length - FromWhichBSSID - indicate the interface index + // Get the group cipher + if (type == GROUP_SUITE) + { + *count = 1; + return pRsnie->mcast; + } + // Get the pairwise cipher suite + else if (type == PAIRWISE_SUITE) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of pairwise cipher is %d\n", + __func__, ucount)); + *count = ucount; + return pRsnie->ucast[0].oui; + } - Return: - TRUE - This frame is EAP frame - FALSE - otherwise - ========================================================================== -*/ -BOOLEAN RTMPCheckWPAframe( - IN PRTMP_ADAPTER pAd, - IN PMAC_TABLE_ENTRY pEntry, - IN PUCHAR pData, - IN ULONG DataByteCount, - IN UCHAR FromWhichBSSID) -{ - ULONG Body_len; - BOOLEAN Cancelled; + offset = sizeof(RSNIE2) + (4 * (ucount - 1)); + + } + else + { + DBGPRINT_ERR(("%s : Unknown IE (%d)\n", __func__, pEid->Eid)); + return NULL; + } + // skip group cipher and pairwise cipher suite + pBuf += offset; + len -= offset; - if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H)) - return FALSE; + if (len < sizeof(RSNIE_AUTH)) + { + DBGPRINT_ERR(("%s : The length of RSNIE is too short\n", __func__)); + return NULL; + } + // pointer to AKM count + pAkm = (PRSNIE_AUTH)pBuf; - // Skip LLC header - if (NdisEqualMemory(SNAP_802_1H, pData, 6) || - // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL - NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)) + // Get the count of pairwise cipher + acount = cpu2le16(pAkm->acount); + if (acount > 2) { - pData += 6; + DBGPRINT_ERR(("%s : The count(%d) of AKM is invlaid\n", + __func__, acount)); + return NULL; } - // Skip 2-bytes EAPoL type - if (NdisEqualMemory(EAPOL, pData, 2)) + + // Get the AKM suite + if (type == AKM_SUITE) { - pData += 2; + DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n", + __func__, acount)); + *count = acount; + return pAkm->auth[0].oui; } - else - return FALSE; + offset = sizeof(RSNIE_AUTH) + (4 * (acount - 1)); - switch (*(pData+1)) + pBuf += offset; + len -= offset; + + // The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~)) + if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID)) { - case EAPPacket: - Body_len = (*(pData+2)<<8) | (*(pData+3)); - DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len)); - break; - case EAPOLStart: - DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n")); - if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE) + // Skip RSN capability and PMKID-Count + pBuf += (sizeof(RSN_CAPABILITIES) + 2); + len -= (sizeof(RSN_CAPABILITIES) + 2); + + // Get PMKID + if (type == PMKID_LIST) { - DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n")); - RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled); - pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE; + *count = 1; + return pBuf; } - break; - case EAPOLLogoff: - DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n")); - break; - case EAPOLKey: - Body_len = (*(pData+2)<<8) | (*(pData+3)); - DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len)); - break; - case EAPOLASFAlert: - DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n")); - break; - default: - return FALSE; - } - return TRUE; + else + { + DBGPRINT_ERR(("%s : it can't get any more information beyond AKM \n", __func__)); + return NULL; + } + + *count = 0; + //DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __func__, type)); + return NULL; + } -/* - ======================================================================== +VOID WpaShowAllsuite( + IN PUINT8 rsnie, + IN UINT rsnie_len) +{ + PUINT8 pSuite = NULL; + UINT8 count; - Routine Description: - Misc function to decrypt AES body + hex_dump("RSNIE", rsnie, rsnie_len); - Arguments: + // group cipher + if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count)) != NULL) + { + hex_dump("group cipher", pSuite, 4*count); + } - Return Value: + // pairwise cipher + if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count)) != NULL) + { + hex_dump("pairwise cipher", pSuite, 4*count); + } - Note: - This function references to RFC 3394 for aes key unwrap algorithm. + // AKM + if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count)) != NULL) + { + hex_dump("AKM suite", pSuite, 4*count); + } - ======================================================================== -*/ -VOID AES_GTK_KEY_UNWRAP( - IN UCHAR *key, - OUT UCHAR *plaintext, - IN UCHAR c_len, - IN UCHAR *ciphertext) + // PMKID + if ((pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count)) != NULL) + { + hex_dump("PMKID", pSuite, LEN_PMKID); + } + +} +VOID RTMPInsertRSNIE( + IN PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN PUINT8 rsnie_ptr, + IN UINT8 rsnie_len, + IN PUINT8 pmkid_ptr, + IN UINT8 pmkid_len) { - UCHAR A[8], BIN[16], BOUT[16]; - UCHAR xor; - INT i, j; - aes_context aesctx; - UCHAR *R; - INT num_blocks = c_len/8; // unit:64bits + PUCHAR pTmpBuf; + ULONG TempLen = 0; + UINT8 extra_len = 0; + UINT16 pmk_count = 0; + UCHAR ie_num; + UINT8 total_len = 0; + UCHAR WPA2_OUI[3]={0x00,0x0F,0xAC}; + pTmpBuf = pFrameBuf; - os_alloc_mem(NULL, (PUCHAR *)&R, 512); + /* PMKID-List Must larger than 0 and the multiple of 16. */ + if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0)) + { + extra_len = sizeof(UINT16) + pmkid_len; + + pmk_count = (pmkid_len >> 4); + pmk_count = cpu2le16(pmk_count); + } + else + { + DBGPRINT(RT_DEBUG_WARN, ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n", + __func__, pmkid_len)); + } - if (R == NULL) + if (rsnie_len != 0) { - DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n")); - return; - } /* End of if */ + ie_num = IE_WPA; + total_len = rsnie_len; - // Initialize - NdisMoveMemory(A, ciphertext, 8); - //Input plaintext - for(i = 0; i < (c_len-8); i++) + if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI))) { - R[ i] = ciphertext[i + 8]; + ie_num = IE_RSN; + total_len += extra_len; } - rtmp_aes_set_key(&aesctx, key, 128); + /* construct RSNIE body */ + MakeOutgoingFrame(pTmpBuf, &TempLen, + 1, &ie_num, + 1, &total_len, + rsnie_len, rsnie_ptr, + END_OF_ARGS); + + pTmpBuf += TempLen; + *pFrameLen = *pFrameLen + TempLen; - for(j = 5; j >= 0; j--) + if (ie_num == IE_RSN) { - for(i = (num_blocks-1); i > 0; i--) + /* Insert PMKID-List field */ + if (extra_len > 0) { - xor = (num_blocks -1 )* j + i; - NdisMoveMemory(BIN, A, 8); - BIN[7] = A[7] ^ xor; - NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8); - rtmp_aes_decrypt(&aesctx, BIN, BOUT); - NdisMoveMemory(A, &BOUT[0], 8); - NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8); + MakeOutgoingFrame(pTmpBuf, &TempLen, + 2, &pmk_count, + pmkid_len, pmkid_ptr, + END_OF_ARGS); + + pTmpBuf += TempLen; + *pFrameLen = *pFrameLen + TempLen; } } - - // OUTPUT - for(i = 0; i < c_len; i++) - { - plaintext[i] = R[i]; } - - os_free_mem(NULL, R); + return; } Index: b/drivers/staging/rt2860/common/crypt_hmac.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/crypt_hmac.c @@ -0,0 +1,279 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + *************************************************************************/ + +#include "../crypt_hmac.h" + + +#ifdef HMAC_SHA1_SUPPORT +/* +======================================================================== +Routine Description: + HMAC using SHA1 hash function + +Arguments: + key Secret key + key_len The length of the key in bytes + message Message context + message_len The length of message in bytes + macLen Request the length of message authentication code + +Return Value: + mac Message authentication code + +Note: + None +======================================================================== +*/ +VOID HMAC_SHA1 ( + IN const UINT8 Key[], + IN UINT KeyLen, + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 MAC[], + IN UINT MACLen) +{ + SHA1_CTX_STRUC sha_ctx1; + SHA1_CTX_STRUC sha_ctx2; + UINT8 K0[SHA1_BLOCK_SIZE]; + UINT8 Digest[SHA1_DIGEST_SIZE]; + UINT index; + + NdisZeroMemory(&sha_ctx1, sizeof(SHA1_CTX_STRUC)); + NdisZeroMemory(&sha_ctx2, sizeof(SHA1_CTX_STRUC)); + /* + * If the length of K = B(Block size): K0 = K. + * If the length of K > B: hash K to obtain an L byte string, + * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00). + * If the length of K < B: append zeros to the end of K to create a B-byte string K0 + */ + NdisZeroMemory(K0, SHA1_BLOCK_SIZE); + if (KeyLen <= SHA1_BLOCK_SIZE) + NdisMoveMemory(K0, Key, KeyLen); + else + RT_SHA1(Key, KeyLen, K0); + /* End of if */ + + /* Exclusive-Or K0 with ipad */ + /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */ + for (index = 0; index < SHA1_BLOCK_SIZE; index++) + K0[index] ^= 0x36; + /* End of for */ + + RT_SHA1_Init(&sha_ctx1); + /* H(K0^ipad) */ + SHA1_Append(&sha_ctx1, K0, sizeof(K0)); + /* H((K0^ipad)||text) */ + SHA1_Append(&sha_ctx1, Message, MessageLen); + SHA1_End(&sha_ctx1, Digest); + + /* Exclusive-Or K0 with opad and remove ipad */ + /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */ + for (index = 0; index < SHA1_BLOCK_SIZE; index++) + K0[index] ^= 0x36^0x5c; + /* End of for */ + + RT_SHA1_Init(&sha_ctx2); + /* H(K0^opad) */ + SHA1_Append(&sha_ctx2, K0, sizeof(K0)); + /* H( (K0^opad) || H((K0^ipad)||text) ) */ + SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE); + SHA1_End(&sha_ctx2, Digest); + + if (MACLen > SHA1_DIGEST_SIZE) + NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE); + else + NdisMoveMemory(MAC, Digest, MACLen); +} /* End of HMAC_SHA1 */ +#endif /* HMAC_SHA1_SUPPORT */ + + +#ifdef HMAC_SHA256_SUPPORT +/* +======================================================================== +Routine Description: + HMAC using SHA256 hash function + +Arguments: + key Secret key + key_len The length of the key in bytes + message Message context + message_len The length of message in bytes + macLen Request the length of message authentication code + +Return Value: + mac Message authentication code + +Note: + None +======================================================================== +*/ +VOID HMAC_SHA256 ( + IN const UINT8 Key[], + IN UINT KeyLen, + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 MAC[], + IN UINT MACLen) +{ + SHA256_CTX_STRUC sha_ctx1; + SHA256_CTX_STRUC sha_ctx2; + UINT8 K0[SHA256_BLOCK_SIZE]; + UINT8 Digest[SHA256_DIGEST_SIZE]; + UINT index; + + NdisZeroMemory(&sha_ctx1, sizeof(SHA256_CTX_STRUC)); + NdisZeroMemory(&sha_ctx2, sizeof(SHA256_CTX_STRUC)); + /* + * If the length of K = B(Block size): K0 = K. + * If the length of K > B: hash K to obtain an L byte string, + * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00). + * If the length of K < B: append zeros to the end of K to create a B-byte string K0 + */ + NdisZeroMemory(K0, SHA256_BLOCK_SIZE); + if (KeyLen <= SHA256_BLOCK_SIZE) { + NdisMoveMemory(K0, Key, KeyLen); + } else { + RT_SHA256(Key, KeyLen, K0); + } + + /* Exclusive-Or K0 with ipad */ + /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */ + for (index = 0; index < SHA256_BLOCK_SIZE; index++) + K0[index] ^= 0x36; + /* End of for */ + + SHA256_Init(&sha_ctx1); + /* H(K0^ipad) */ + SHA256_Append(&sha_ctx1, K0, sizeof(K0)); + /* H((K0^ipad)||text) */ + SHA256_Append(&sha_ctx1, Message, MessageLen); + SHA256_End(&sha_ctx1, Digest); + + /* Exclusive-Or K0 with opad and remove ipad */ + /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */ + for (index = 0; index < SHA256_BLOCK_SIZE; index++) + K0[index] ^= 0x36^0x5c; + /* End of for */ + + SHA256_Init(&sha_ctx2); + /* H(K0^opad) */ + SHA256_Append(&sha_ctx2, K0, sizeof(K0)); + /* H( (K0^opad) || H((K0^ipad)||text) ) */ + SHA256_Append(&sha_ctx2, Digest, SHA256_DIGEST_SIZE); + SHA256_End(&sha_ctx2, Digest); + + if (MACLen > SHA256_DIGEST_SIZE) + NdisMoveMemory(MAC, Digest,SHA256_DIGEST_SIZE); + else + NdisMoveMemory(MAC, Digest, MACLen); + +} /* End of HMAC_SHA256 */ +#endif /* HMAC_SHA256_SUPPORT */ + + +#ifdef HMAC_MD5_SUPPORT +/* +======================================================================== +Routine Description: + HMAC using MD5 hash function + +Arguments: + key Secret key + key_len The length of the key in bytes + message Message context + message_len The length of message in bytes + macLen Request the length of message authentication code + +Return Value: + mac Message authentication code + +Note: + None +======================================================================== +*/ +VOID HMAC_MD5( + IN const UINT8 Key[], + IN UINT KeyLen, + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 MAC[], + IN UINT MACLen) +{ + MD5_CTX_STRUC md5_ctx1; + MD5_CTX_STRUC md5_ctx2; + UINT8 K0[MD5_BLOCK_SIZE]; + UINT8 Digest[MD5_DIGEST_SIZE]; + UINT index; + + NdisZeroMemory(&md5_ctx1, sizeof(MD5_CTX_STRUC)); + NdisZeroMemory(&md5_ctx2, sizeof(MD5_CTX_STRUC)); + /* + * If the length of K = B(Block size): K0 = K. + * If the length of K > B: hash K to obtain an L byte string, + * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00). + * If the length of K < B: append zeros to the end of K to create a B-byte string K0 + */ + NdisZeroMemory(K0, MD5_BLOCK_SIZE); + if (KeyLen <= MD5_BLOCK_SIZE) { + NdisMoveMemory(K0, Key, KeyLen); + } else { + RT_MD5(Key, KeyLen, K0); + } + + /* Exclusive-Or K0 with ipad */ + /* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */ + for (index = 0; index < MD5_BLOCK_SIZE; index++) + K0[index] ^= 0x36; + /* End of for */ + + MD5_Init(&md5_ctx1); + /* H(K0^ipad) */ + MD5_Append(&md5_ctx1, K0, sizeof(K0)); + /* H((K0^ipad)||text) */ + MD5_Append(&md5_ctx1, Message, MessageLen); + MD5_End(&md5_ctx1, Digest); + + /* Exclusive-Or K0 with opad and remove ipad */ + /* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */ + for (index = 0; index < MD5_BLOCK_SIZE; index++) + K0[index] ^= 0x36^0x5c; + /* End of for */ + + MD5_Init(&md5_ctx2); + /* H(K0^opad) */ + MD5_Append(&md5_ctx2, K0, sizeof(K0)); + /* H( (K0^opad) || H((K0^ipad)||text) ) */ + MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE); + MD5_End(&md5_ctx2, Digest); + + if (MACLen > MD5_DIGEST_SIZE) + NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE); + else + NdisMoveMemory(MAC, Digest, MACLen); +} /* End of HMAC_SHA256 */ +#endif /* HMAC_MD5_SUPPORT */ + +/* End of crypt_hmac.c */ Index: b/drivers/staging/rt2860/common/crypt_md5.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/crypt_md5.c @@ -0,0 +1,352 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + *************************************************************************/ + +#include "../crypt_md5.h" + +#ifdef MD5_SUPPORT +/* + * F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +#define ROTL(x,n,w) ((x << n) | (x >> (w - n))) +#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */ + +#define ROUND1(a, b, c, d, x, s, ac) { \ + (a) += F((b),(c),(d)) + (x) + (UINT32)(ac); \ + (a) = ROTL32((a),(s)); \ + (a) += (b); \ +} +#define ROUND2(a, b, c, d, x, s, ac) { \ + (a) += G((b),(c),(d)) + (x) + (UINT32)(ac); \ + (a) = ROTL32((a),(s)); \ + (a) += (b); \ +} +#define ROUND3(a, b, c, d, x, s, ac) { \ + (a) += H((b),(c),(d)) + (x) + (UINT32)(ac); \ + (a) = ROTL32((a),(s)); \ + (a) += (b); \ +} +#define ROUND4(a, b, c, d, x, s, ac) { \ + (a) += I((b),(c),(d)) + (x) + (UINT32)(ac); \ + (a) = ROTL32((a),(s)); \ + (a) += (b); \ +} +static const UINT32 MD5_DefaultHashValue[4] = { + 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL +}; +#endif /* MD5_SUPPORT */ + + +#ifdef MD5_SUPPORT +/* +======================================================================== +Routine Description: + Initial Md5_CTX_STRUC + +Arguments: + pMD5_CTX Pointer to Md5_CTX_STRUC + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID MD5_Init ( + IN MD5_CTX_STRUC *pMD5_CTX) +{ + NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue, + sizeof(MD5_DefaultHashValue)); + NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE); + pMD5_CTX->BlockLen = 0; + pMD5_CTX->MessageLen = 0; +} /* End of MD5_Init */ + + +/* +======================================================================== +Routine Description: + MD5 computation for one block (512 bits) + +Arguments: + pMD5_CTX Pointer to Md5_CTX_STRUC + +Return Value: + None + +Note: + T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round +======================================================================== +*/ +VOID MD5_Hash ( + IN MD5_CTX_STRUC *pMD5_CTX) +{ + UINT32 X_i; + UINT32 X[16]; + UINT32 a,b,c,d; + + /* Prepare the message schedule, {X_i} */ + NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE); + for (X_i = 0; X_i < 16; X_i++) + X[X_i] = cpu2le32(X[X_i]); /* Endian Swap */ + /* End of for */ + + /* MD5 hash computation */ + /* Initialize the working variables */ + a = pMD5_CTX->HashValue[0]; + b = pMD5_CTX->HashValue[1]; + c = pMD5_CTX->HashValue[2]; + d = pMD5_CTX->HashValue[3]; + + /* + * Round 1 + * Let [abcd k s i] denote the operation + * a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s) + */ + ROUND1(a, b, c, d, X[ 0], 7, 0xd76aa478); /* 1 */ + ROUND1(d, a, b, c, X[ 1], 12, 0xe8c7b756); /* 2 */ + ROUND1(c, d, a, b, X[ 2], 17, 0x242070db); /* 3 */ + ROUND1(b, c, d, a, X[ 3], 22, 0xc1bdceee); /* 4 */ + ROUND1(a, b, c, d, X[ 4], 7, 0xf57c0faf); /* 5 */ + ROUND1(d, a, b, c, X[ 5], 12, 0x4787c62a); /* 6 */ + ROUND1(c, d, a, b, X[ 6], 17, 0xa8304613); /* 7 */ + ROUND1(b, c, d, a, X[ 7], 22, 0xfd469501); /* 8 */ + ROUND1(a, b, c, d, X[ 8], 7, 0x698098d8); /* 9 */ + ROUND1(d, a, b, c, X[ 9], 12, 0x8b44f7af); /* 10 */ + ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1); /* 11 */ + ROUND1(b, c, d, a, X[11], 22, 0x895cd7be); /* 12 */ + ROUND1(a, b, c, d, X[12], 7, 0x6b901122); /* 13 */ + ROUND1(d, a, b, c, X[13], 12, 0xfd987193); /* 14 */ + ROUND1(c, d, a, b, X[14], 17, 0xa679438e); /* 15 */ + ROUND1(b, c, d, a, X[15], 22, 0x49b40821); /* 16 */ + + /* + * Round 2 + * Let [abcd k s i] denote the operation + * a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s) + */ + ROUND2(a, b, c, d, X[ 1], 5, 0xf61e2562); /* 17 */ + ROUND2(d, a, b, c, X[ 6], 9, 0xc040b340); /* 18 */ + ROUND2(c, d, a, b, X[11], 14, 0x265e5a51); /* 19 */ + ROUND2(b, c, d, a, X[ 0], 20, 0xe9b6c7aa); /* 20 */ + ROUND2(a, b, c, d, X[ 5], 5, 0xd62f105d); /* 21 */ + ROUND2(d, a, b, c, X[10], 9, 0x2441453); /* 22 */ + ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681); /* 23 */ + ROUND2(b, c, d, a, X[ 4], 20, 0xe7d3fbc8); /* 24 */ + ROUND2(a, b, c, d, X[ 9], 5, 0x21e1cde6); /* 25 */ + ROUND2(d, a, b, c, X[14], 9, 0xc33707d6); /* 26 */ + ROUND2(c, d, a, b, X[ 3], 14, 0xf4d50d87); /* 27 */ + ROUND2(b, c, d, a, X[ 8], 20, 0x455a14ed); /* 28 */ + ROUND2(a, b, c, d, X[13], 5, 0xa9e3e905); /* 29 */ + ROUND2(d, a, b, c, X[ 2], 9, 0xfcefa3f8); /* 30 */ + ROUND2(c, d, a, b, X[ 7], 14, 0x676f02d9); /* 31 */ + ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a); /* 32 */ + + /* + * Round 3 + * Let [abcd k s t] denote the operation + * a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s) + */ + ROUND3(a, b, c, d, X[ 5], 4, 0xfffa3942); /* 33 */ + ROUND3(d, a, b, c, X[ 8], 11, 0x8771f681); /* 34 */ + ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122); /* 35 */ + ROUND3(b, c, d, a, X[14], 23, 0xfde5380c); /* 36 */ + ROUND3(a, b, c, d, X[ 1], 4, 0xa4beea44); /* 37 */ + ROUND3(d, a, b, c, X[ 4], 11, 0x4bdecfa9); /* 38 */ + ROUND3(c, d, a, b, X[ 7], 16, 0xf6bb4b60); /* 39 */ + ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70); /* 40 */ + ROUND3(a, b, c, d, X[13], 4, 0x289b7ec6); /* 41 */ + ROUND3(d, a, b, c, X[ 0], 11, 0xeaa127fa); /* 42 */ + ROUND3(c, d, a, b, X[ 3], 16, 0xd4ef3085); /* 43 */ + ROUND3(b, c, d, a, X[ 6], 23, 0x4881d05); /* 44 */ + ROUND3(a, b, c, d, X[ 9], 4, 0xd9d4d039); /* 45 */ + ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5); /* 46 */ + ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8); /* 47 */ + ROUND3(b, c, d, a, X[ 2], 23, 0xc4ac5665); /* 48 */ + + /* + * Round 4 + * Let [abcd k s t] denote the operation + * a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s) + */ + ROUND4(a, b, c, d, X[ 0], 6, 0xf4292244); /* 49 */ + ROUND4(d, a, b, c, X[ 7], 10, 0x432aff97); /* 50 */ + ROUND4(c, d, a, b, X[14], 15, 0xab9423a7); /* 51 */ + ROUND4(b, c, d, a, X[ 5], 21, 0xfc93a039); /* 52 */ + ROUND4(a, b, c, d, X[12], 6, 0x655b59c3); /* 53 */ + ROUND4(d, a, b, c, X[ 3], 10, 0x8f0ccc92); /* 54 */ + ROUND4(c, d, a, b, X[10], 15, 0xffeff47d); /* 55 */ + ROUND4(b, c, d, a, X[ 1], 21, 0x85845dd1); /* 56 */ + ROUND4(a, b, c, d, X[ 8], 6, 0x6fa87e4f); /* 57 */ + ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0); /* 58 */ + ROUND4(c, d, a, b, X[ 6], 15, 0xa3014314); /* 59 */ + ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1); /* 60 */ + ROUND4(a, b, c, d, X[ 4], 6, 0xf7537e82); /* 61 */ + ROUND4(d, a, b, c, X[11], 10, 0xbd3af235); /* 62 */ + ROUND4(c, d, a, b, X[ 2], 15, 0x2ad7d2bb); /* 63 */ + ROUND4(b, c, d, a, X[ 9], 21, 0xeb86d391); /* 64 */ + + /* Compute the i^th intermediate hash value H^(i) */ + pMD5_CTX->HashValue[0] += a; + pMD5_CTX->HashValue[1] += b; + pMD5_CTX->HashValue[2] += c; + pMD5_CTX->HashValue[3] += d; + + NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE); + pMD5_CTX->BlockLen = 0; +} /* End of MD5_Hash */ + + +/* +======================================================================== +Routine Description: + The message is appended to block. If block size > 64 bytes, the MD5_Hash +will be called. + +Arguments: + pMD5_CTX Pointer to MD5_CTX_STRUC + message Message context + messageLen The length of message in bytes + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID MD5_Append ( + IN MD5_CTX_STRUC *pMD5_CTX, + IN const UINT8 Message[], + IN UINT MessageLen) +{ + UINT appendLen = 0; + UINT diffLen = 0; + + while (appendLen != MessageLen) { + diffLen = MessageLen - appendLen; + if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) { + NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, + Message + appendLen, diffLen); + pMD5_CTX->BlockLen += diffLen; + appendLen += diffLen; + } + else + { + NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, + Message + appendLen, MD5_BLOCK_SIZE - pMD5_CTX->BlockLen); + appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen); + pMD5_CTX->BlockLen = MD5_BLOCK_SIZE; + MD5_Hash(pMD5_CTX); + } /* End of if */ + } /* End of while */ + pMD5_CTX->MessageLen += MessageLen; +} /* End of MD5_Append */ + + +/* +======================================================================== +Routine Description: + 1. Append bit 1 to end of the message + 2. Append the length of message in rightmost 64 bits + 3. Transform the Hash Value to digest message + +Arguments: + pMD5_CTX Pointer to MD5_CTX_STRUC + +Return Value: + digestMessage Digest message + +Note: + None +======================================================================== +*/ +VOID MD5_End ( + IN MD5_CTX_STRUC *pMD5_CTX, + OUT UINT8 DigestMessage[]) +{ + UINT index; + UINT64 message_length_bits; + + /* append 1 bits to end of the message */ + NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80); + + /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */ + if (pMD5_CTX->BlockLen > 55) + MD5_Hash(pMD5_CTX); + /* End of if */ + + /* Append the length of message in rightmost 64 bits */ + message_length_bits = pMD5_CTX->MessageLen*8; + message_length_bits = cpu2le64(message_length_bits); + NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8); + MD5_Hash(pMD5_CTX); + + /* Return message digest, transform the UINT32 hash value to bytes */ + for (index = 0; index < 4;index++) + pMD5_CTX->HashValue[index] = cpu2le32(pMD5_CTX->HashValue[index]); + /* End of for */ + NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE); +} /* End of MD5_End */ + + +/* +======================================================================== +Routine Description: + MD5 algorithm + +Arguments: + message Message context + messageLen The length of message in bytes + +Return Value: + digestMessage Digest message + +Note: + None +======================================================================== +*/ +VOID RT_MD5 ( + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 DigestMessage[]) +{ + MD5_CTX_STRUC md5_ctx; + + NdisZeroMemory(&md5_ctx, sizeof(MD5_CTX_STRUC)); + MD5_Init(&md5_ctx); + MD5_Append(&md5_ctx, Message, MessageLen); + MD5_End(&md5_ctx, DigestMessage); +} /* End of RT_MD5 */ + +#endif /* MD5_SUPPORT */ + +/* End of crypt_md5.c */ Index: b/drivers/staging/rt2860/common/crypt_sha2.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/crypt_sha2.c @@ -0,0 +1,535 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + *************************************************************************/ + +#include "../crypt_sha2.h" + +/* Basic operations */ +#define SHR(x,n) (x >> n) /* SHR(x)^n, right shift n bits , x is w-bit word, 0 <= n <= w */ +#define ROTR(x,n,w) ((x >> n) | (x << (w - n))) /* ROTR(x)^n, circular right shift n bits , x is w-bit word, 0 <= n <= w */ +#define ROTL(x,n,w) ((x << n) | (x >> (w - n))) /* ROTL(x)^n, circular left shift n bits , x is w-bit word, 0 <= n <= w */ +#define ROTR32(x,n) ROTR(x,n,32) /* 32 bits word */ +#define ROTL32(x,n) ROTL(x,n,32) /* 32 bits word */ + +/* Basic functions */ +#define Ch(x,y,z) ((x & y) ^ ((~x) & z)) +#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) +#define Parity(x,y,z) (x ^ y ^ z) + +#ifdef SHA1_SUPPORT +/* SHA1 constants */ +#define SHA1_MASK 0x0000000f +static const UINT32 SHA1_K[4] = { + 0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL +}; +static const UINT32 SHA1_DefaultHashValue[5] = { + 0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL +}; +#endif /* SHA1_SUPPORT */ + + +#ifdef SHA256_SUPPORT +/* SHA256 functions */ +#define Zsigma_256_0(x) (ROTR32(x,2) ^ ROTR32(x,13) ^ ROTR32(x,22)) +#define Zsigma_256_1(x) (ROTR32(x,6) ^ ROTR32(x,11) ^ ROTR32(x,25)) +#define Sigma_256_0(x) (ROTR32(x,7) ^ ROTR32(x,18) ^ SHR(x,3)) +#define Sigma_256_1(x) (ROTR32(x,17) ^ ROTR32(x,19) ^ SHR(x,10)) +/* SHA256 constants */ +static const UINT32 SHA256_K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; +static const UINT32 SHA256_DefaultHashValue[8] = { + 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, + 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL +}; +#endif /* SHA256_SUPPORT */ + + +#ifdef SHA1_SUPPORT +/* +======================================================================== +Routine Description: + Initial SHA1_CTX_STRUC + +Arguments: + pSHA_CTX Pointer to SHA1_CTX_STRUC + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID RT_SHA1_Init ( + IN SHA1_CTX_STRUC *pSHA_CTX) +{ + NdisMoveMemory(pSHA_CTX->HashValue, SHA1_DefaultHashValue, + sizeof(SHA1_DefaultHashValue)); + NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE); + pSHA_CTX->MessageLen = 0; + pSHA_CTX->BlockLen = 0; +} /* End of RT_SHA1_Init */ + + +/* +======================================================================== +Routine Description: + SHA1 computation for one block (512 bits) + +Arguments: + pSHA_CTX Pointer to SHA1_CTX_STRUC + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID SHA1_Hash ( + IN SHA1_CTX_STRUC *pSHA_CTX) +{ + UINT32 W_i,t,s; + UINT32 W[16]; + UINT32 a,b,c,d,e,T,f_t = 0; + + /* Prepare the message schedule, {W_i}, 0 < t < 15 */ + NdisMoveMemory(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE); + for (W_i = 0; W_i < 16; W_i++) + W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */ + /* End of for */ + + /* SHA256 hash computation */ + /* Initialize the working variables */ + a = pSHA_CTX->HashValue[0]; + b = pSHA_CTX->HashValue[1]; + c = pSHA_CTX->HashValue[2]; + d = pSHA_CTX->HashValue[3]; + e = pSHA_CTX->HashValue[4]; + + /* 80 rounds */ + for (t = 0;t < 80;t++) { + s = t & SHA1_MASK; + if (t > 15) { /* Prepare the message schedule, {W_i}, 16 < t < 79 */ + W[s] = (W[(s+13) & SHA1_MASK]) ^ (W[(s+8) & SHA1_MASK]) ^ (W[(s+2) & SHA1_MASK]) ^ W[s]; + W[s] = ROTL32(W[s],1); + } /* End of if */ + switch (t / 20) { + case 0: + f_t = Ch(b,c,d); + break; + case 1: + f_t = Parity(b,c,d); + break; + case 2: + f_t = Maj(b,c,d); + break; + case 3: + f_t = Parity(b,c,d); + break; + } /* End of switch */ + T = ROTL32(a,5) + f_t + e + SHA1_K[t / 20] + W[s]; + e = d; + d = c; + c = ROTL32(b,30); + b = a; + a = T; + } /* End of for */ + + /* Compute the i^th intermediate hash value H^(i) */ + pSHA_CTX->HashValue[0] += a; + pSHA_CTX->HashValue[1] += b; + pSHA_CTX->HashValue[2] += c; + pSHA_CTX->HashValue[3] += d; + pSHA_CTX->HashValue[4] += e; + + NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE); + pSHA_CTX->BlockLen = 0; +} /* End of SHA1_Hash */ + + +/* +======================================================================== +Routine Description: + The message is appended to block. If block size > 64 bytes, the SHA1_Hash +will be called. + +Arguments: + pSHA_CTX Pointer to SHA1_CTX_STRUC + message Message context + messageLen The length of message in bytes + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID SHA1_Append ( + IN SHA1_CTX_STRUC *pSHA_CTX, + IN const UINT8 Message[], + IN UINT MessageLen) +{ + UINT appendLen = 0; + UINT diffLen = 0; + + while (appendLen != MessageLen) { + diffLen = MessageLen - appendLen; + if ((pSHA_CTX->BlockLen + diffLen) < SHA1_BLOCK_SIZE) { + NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, + Message + appendLen, diffLen); + pSHA_CTX->BlockLen += diffLen; + appendLen += diffLen; + } + else + { + NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, + Message + appendLen, SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen); + appendLen += (SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen); + pSHA_CTX->BlockLen = SHA1_BLOCK_SIZE; + SHA1_Hash(pSHA_CTX); + } /* End of if */ + } /* End of while */ + pSHA_CTX->MessageLen += MessageLen; +} /* End of SHA1_Append */ + + +/* +======================================================================== +Routine Description: + 1. Append bit 1 to end of the message + 2. Append the length of message in rightmost 64 bits + 3. Transform the Hash Value to digest message + +Arguments: + pSHA_CTX Pointer to SHA1_CTX_STRUC + +Return Value: + digestMessage Digest message + +Note: + None +======================================================================== +*/ +VOID SHA1_End ( + IN SHA1_CTX_STRUC *pSHA_CTX, + OUT UINT8 DigestMessage[]) +{ + UINT index; + UINT64 message_length_bits; + + /* Append bit 1 to end of the message */ + NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80); + + /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */ + if (pSHA_CTX->BlockLen > 55) + SHA1_Hash(pSHA_CTX); + /* End of if */ + + /* Append the length of message in rightmost 64 bits */ + message_length_bits = pSHA_CTX->MessageLen*8; + message_length_bits = cpu2be64(message_length_bits); + NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8); + SHA1_Hash(pSHA_CTX); + + /* Return message digest, transform the UINT32 hash value to bytes */ + for (index = 0; index < 5;index++) + pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]); + /* End of for */ + NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA1_DIGEST_SIZE); +} /* End of SHA1_End */ + + +/* +======================================================================== +Routine Description: + SHA1 algorithm + +Arguments: + message Message context + messageLen The length of message in bytes + +Return Value: + digestMessage Digest message + +Note: + None +======================================================================== +*/ +VOID RT_SHA1 ( + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 DigestMessage[]) +{ + + SHA1_CTX_STRUC sha_ctx; + + NdisZeroMemory(&sha_ctx, sizeof(SHA1_CTX_STRUC)); + RT_SHA1_Init(&sha_ctx); + SHA1_Append(&sha_ctx, Message, MessageLen); + SHA1_End(&sha_ctx, DigestMessage); +} /* End of RT_SHA1 */ +#endif /* SHA1_SUPPORT */ + + +#ifdef SHA256_SUPPORT +/* +======================================================================== +Routine Description: + Initial SHA256_CTX_STRUC + +Arguments: + pSHA_CTX Pointer to SHA256_CTX_STRUC + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID SHA256_Init ( + IN SHA256_CTX_STRUC *pSHA_CTX) +{ + NdisMoveMemory(pSHA_CTX->HashValue, SHA256_DefaultHashValue, + sizeof(SHA256_DefaultHashValue)); + NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE); + pSHA_CTX->MessageLen = 0; + pSHA_CTX->BlockLen = 0; +} /* End of SHA256_Init */ + + +/* +======================================================================== +Routine Description: + SHA256 computation for one block (512 bits) + +Arguments: + pSHA_CTX Pointer to SHA256_CTX_STRUC + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID SHA256_Hash ( + IN SHA256_CTX_STRUC *pSHA_CTX) +{ + UINT32 W_i,t; + UINT32 W[64]; + UINT32 a,b,c,d,e,f,g,h,T1,T2; + + /* Prepare the message schedule, {W_i}, 0 < t < 15 */ + NdisMoveMemory(W, pSHA_CTX->Block, SHA256_BLOCK_SIZE); + for (W_i = 0; W_i < 16; W_i++) + W[W_i] = cpu2be32(W[W_i]); /* Endian Swap */ + /* End of for */ + + /* SHA256 hash computation */ + /* Initialize the working variables */ + a = pSHA_CTX->HashValue[0]; + b = pSHA_CTX->HashValue[1]; + c = pSHA_CTX->HashValue[2]; + d = pSHA_CTX->HashValue[3]; + e = pSHA_CTX->HashValue[4]; + f = pSHA_CTX->HashValue[5]; + g = pSHA_CTX->HashValue[6]; + h = pSHA_CTX->HashValue[7]; + + /* 64 rounds */ + for (t = 0;t < 64;t++) { + if (t > 15) /* Prepare the message schedule, {W_i}, 16 < t < 63 */ + W[t] = Sigma_256_1(W[t-2]) + W[t-7] + Sigma_256_0(W[t-15]) + W[t-16]; + /* End of if */ + T1 = h + Zsigma_256_1(e) + Ch(e,f,g) + SHA256_K[t] + W[t]; + T2 = Zsigma_256_0(a) + Maj(a,b,c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } /* End of for */ + + /* Compute the i^th intermediate hash value H^(i) */ + pSHA_CTX->HashValue[0] += a; + pSHA_CTX->HashValue[1] += b; + pSHA_CTX->HashValue[2] += c; + pSHA_CTX->HashValue[3] += d; + pSHA_CTX->HashValue[4] += e; + pSHA_CTX->HashValue[5] += f; + pSHA_CTX->HashValue[6] += g; + pSHA_CTX->HashValue[7] += h; + + NdisZeroMemory(pSHA_CTX->Block, SHA256_BLOCK_SIZE); + pSHA_CTX->BlockLen = 0; +} /* End of SHA256_Hash */ + + +/* +======================================================================== +Routine Description: + The message is appended to block. If block size > 64 bytes, the SHA256_Hash +will be called. + +Arguments: + pSHA_CTX Pointer to SHA256_CTX_STRUC + message Message context + messageLen The length of message in bytes + +Return Value: + None + +Note: + None +======================================================================== +*/ +VOID SHA256_Append ( + IN SHA256_CTX_STRUC *pSHA_CTX, + IN const UINT8 Message[], + IN UINT MessageLen) +{ + UINT appendLen = 0; + UINT diffLen = 0; + + while (appendLen != MessageLen) { + diffLen = MessageLen - appendLen; + if ((pSHA_CTX->BlockLen + diffLen) < SHA256_BLOCK_SIZE) { + NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, + Message + appendLen, diffLen); + pSHA_CTX->BlockLen += diffLen; + appendLen += diffLen; + } + else + { + NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, + Message + appendLen, SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen); + appendLen += (SHA256_BLOCK_SIZE - pSHA_CTX->BlockLen); + pSHA_CTX->BlockLen = SHA256_BLOCK_SIZE; + SHA256_Hash(pSHA_CTX); + } /* End of if */ + } /* End of while */ + pSHA_CTX->MessageLen += MessageLen; +} /* End of SHA256_Append */ + + +/* +======================================================================== +Routine Description: + 1. Append bit 1 to end of the message + 2. Append the length of message in rightmost 64 bits + 3. Transform the Hash Value to digest message + +Arguments: + pSHA_CTX Pointer to SHA256_CTX_STRUC + +Return Value: + digestMessage Digest message + +Note: + None +======================================================================== +*/ +VOID SHA256_End ( + IN SHA256_CTX_STRUC *pSHA_CTX, + OUT UINT8 DigestMessage[]) +{ + UINT index; + UINT64 message_length_bits; + + /* Append bit 1 to end of the message */ + NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80); + + /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */ + if (pSHA_CTX->BlockLen > 55) + SHA256_Hash(pSHA_CTX); + /* End of if */ + + /* Append the length of message in rightmost 64 bits */ + message_length_bits = pSHA_CTX->MessageLen*8; + message_length_bits = cpu2be64(message_length_bits); + NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8); + SHA256_Hash(pSHA_CTX); + + /* Return message digest, transform the UINT32 hash value to bytes */ + for (index = 0; index < 8;index++) + pSHA_CTX->HashValue[index] = cpu2be32(pSHA_CTX->HashValue[index]); + /* End of for */ + NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA256_DIGEST_SIZE); +} /* End of SHA256_End */ + + +/* +======================================================================== +Routine Description: + SHA256 algorithm + +Arguments: + message Message context + messageLen The length of message in bytes + +Return Value: + digestMessage Digest message + +Note: + None +======================================================================== +*/ +VOID RT_SHA256 ( + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 DigestMessage[]) +{ + SHA256_CTX_STRUC sha_ctx; + + NdisZeroMemory(&sha_ctx, sizeof(SHA256_CTX_STRUC)); + SHA256_Init(&sha_ctx); + SHA256_Append(&sha_ctx, Message, MessageLen); + SHA256_End(&sha_ctx, DigestMessage); +} /* End of RT_SHA256 */ +#endif /* SHA256_SUPPORT */ + +/* End of crypt_sha2.c */ Index: b/drivers/staging/rt2860/common/dfs.c =================================================================== --- a/drivers/staging/rt2860/common/dfs.c +++ b/drivers/staging/rt2860/common/dfs.c @@ -33,7 +33,6 @@ Revision History: Who When What -------- ---------- ---------------------------------------------- - Fonchi 03-12-2007 created */ #include "../rt_config.h" @@ -46,10 +45,15 @@ typedef struct _RADAR_DURATION_TABLE } RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE; -static UCHAR RdIdleTimeTable[MAX_RD_REGION][4] = + +UCHAR RdIdleTimeTable[MAX_RD_REGION][4] = { {9, 250, 250, 250}, // CE +#ifdef DFS_FCC_BW40_FIX + {1, 250, 250, 250}, // FCC +#else {4, 250, 250, 250}, // FCC +#endif {4, 250, 250, 250}, // JAP {15, 250, 250, 250}, // JAP_W53 {4, 250, 250, 250} // JAP_W56 @@ -80,11 +84,32 @@ VOID BbpRadarDetectionStart( RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff); +#ifdef MERGE_ARCH_TEAM + if ((pAd->CommonCfg.RadarDetect.RDDurRegion == JAP) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53) || (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56)) + { + pAd->CommonCfg.RadarDetect.RDDurRegion = JAP; + pAd->CommonCfg.RadarDetect.RDDurRegion = JapRadarType(pAd); + if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W56) + { + pAd->CommonCfg.RadarDetect.DfsSessionTime = 13; + } + else if (pAd->CommonCfg.RadarDetect.RDDurRegion == JAP_W53) + { + pAd->CommonCfg.RadarDetect.DfsSessionTime = 15; + } + } +#endif // MERGE_ARCH_TEAM // + RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ? (RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250; +#ifdef MERGE_ARCH_TEAM + + +#else // Original RT28xx source code. RTMP_IO_WRITE8(pAd, 0x7020, 0x1d); RTMP_IO_WRITE8(pAd, 0x7021, 0x40); +#endif // MERGE_ARCH_TEAM // RadarDetectionStart(pAd, 0, RadarPeriod); return; @@ -143,6 +168,17 @@ VOID RadarDetectionStart( CtsProtect = 0x03; break; + case JAP: + { + UCHAR RDDurRegion; + RDDurRegion = JapRadarType(pAd); + if (RDDurRegion == JAP_W56) + CtsProtect = 0x03; + else + CtsProtect = 0x02; + break; + } + case CE: case JAP_W53: default: @@ -210,7 +246,6 @@ BOOLEAN RadarChannelCheck( IN PRTMP_ADAPTER pAd, IN UCHAR Ch) { -#if 1 INT i; BOOLEAN result = FALSE; @@ -224,23 +259,6 @@ BOOLEAN RadarChannelCheck( } return result; -#else - INT i; - UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}; - - for (i=0; i<15; i++) - { - if (Ch == Channel[i]) - { - break; - } - } - - if (i != 15) - return TRUE; - else - return FALSE; -#endif } ULONG JapRadarType( @@ -399,11 +417,11 @@ VOID RadarDetectPeriodic( */ INT Set_ChMovingTime_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { UINT8 Value; - Value = simple_strtol(arg, 0, 10); + Value = (UINT8) simple_strtol(arg, 0, 10); pAd->CommonCfg.RadarDetect.ChMovingTime = Value; @@ -415,11 +433,11 @@ INT Set_ChMovingTime_Proc( INT Set_LongPulseRadarTh_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { UINT8 Value; - Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10); + Value = (UINT8) simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10); pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value; Index: b/drivers/staging/rt2860/common/ee_efuse.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/ee_efuse.c @@ -0,0 +1,1525 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + ee_efuse.c + + Abstract: + Miniport generic portion header file + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + + +#include "../rt_config.h" + + + +#define EFUSE_USAGE_MAP_START 0x2d0 +#define EFUSE_USAGE_MAP_END 0x2fc +#define EFUSE_USAGE_MAP_SIZE 45 + + + +#define EFUSE_EEPROM_DEFULT_FILE "RT30xxEEPROM.bin" +#define MAX_EEPROM_BIN_FILE_SIZE 1024 + + + +#define EFUSE_TAG 0x2fe + +typedef union _EFUSE_CTRL_STRUC { + struct { + UINT32 EFSROM_AOUT:6; + UINT32 EFSROM_MODE:2; + UINT32 EFSROM_LDO_OFF_TIME:6; + UINT32 EFSROM_LDO_ON_TIME:2; + UINT32 EFSROM_AIN:10; + UINT32 RESERVED:4; + UINT32 EFSROM_KICK:1; + UINT32 SEL_EFUSE:1; + } field; + UINT32 word; +} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC; + +static UCHAR eFuseReadRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + OUT USHORT* pData); + +static VOID eFuseReadPhysical( + IN PRTMP_ADAPTER pAd, + IN PUSHORT lpInBuffer, + IN ULONG nInBufferSize, + OUT PUSHORT lpOutBuffer, + IN ULONG nOutBufferSize); + +static VOID eFusePhysicalWriteRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + OUT USHORT* pData); + +static NTSTATUS eFuseWriteRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + IN USHORT* pData); + +static VOID eFuseWritePhysical( + IN PRTMP_ADAPTER pAd, + PUSHORT lpInBuffer, + ULONG nInBufferSize, + PUCHAR lpOutBuffer, + ULONG nOutBufferSize); + + +static NTSTATUS eFuseWriteRegistersFromBin( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + IN USHORT* pData); + + +/* +======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +UCHAR eFuseReadRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + OUT USHORT* pData) +{ + EFUSE_CTRL_STRUC eFuseCtrlStruc; + int i; + USHORT efuseDataOffset; + UINT32 data; + + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + + //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. + //Use the eeprom logical address and covert to address to block number + eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; + + //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0. + eFuseCtrlStruc.field.EFSROM_MODE = 0; + + //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. + eFuseCtrlStruc.field.EFSROM_KICK = 1; + + NdisMoveMemory(&data, &eFuseCtrlStruc, 4); + RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); + + //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. + i = 0; + while(i < 500) + { + //rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4); + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + { + break; + } + RTMPusecDelay(2); + i++; + } + + //if EFSROM_AOUT is not found in physical address, write 0xffff + if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f) + { + for(i=0; i> (8*(Offset & 0x3)); + + NdisMoveMemory(pData, &data, Length); + } + + return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT; + +} + +/* +======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +VOID eFusePhysicalReadRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + OUT USHORT* pData) +{ + EFUSE_CTRL_STRUC eFuseCtrlStruc; + int i; + USHORT efuseDataOffset; + UINT32 data; + + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + + //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. + eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; + + //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1. + //Read in physical view + eFuseCtrlStruc.field.EFSROM_MODE = 1; + + //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. + eFuseCtrlStruc.field.EFSROM_KICK = 1; + + NdisMoveMemory(&data, &eFuseCtrlStruc, 4); + RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); + + //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. + i = 0; + while(i < 500) + { + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + break; + RTMPusecDelay(2); + i++; + } + + //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590) + //Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits. + //The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes + //Decide which EFUSE_DATA to read + //590:F E D C + //594:B A 9 8 + //598:7 6 5 4 + //59C:3 2 1 0 + efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ; + + RTMP_IO_READ32(pAd, efuseDataOffset, &data); + + data = data >> (8*(Offset & 0x3)); + + NdisMoveMemory(pData, &data, Length); + +} + +/* +======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +static VOID eFuseReadPhysical( + IN PRTMP_ADAPTER pAd, + IN PUSHORT lpInBuffer, + IN ULONG nInBufferSize, + OUT PUSHORT lpOutBuffer, + IN ULONG nOutBufferSize +) +{ + USHORT* pInBuf = (USHORT*)lpInBuffer; + USHORT* pOutBuf = (USHORT*)lpOutBuffer; + + USHORT Offset = pInBuf[0]; //addr + USHORT Length = pInBuf[1]; //length + int i; + + for(i=0; i> 2; + data = pData[0] & 0xffff; + //The offset should be 0x***10 or 0x***00 + if((Offset % 4) != 0) + { + eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16); + } + else + { + eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data; + } + + efuseDataOffset = EFUSE_DATA3; + for(i=0; i< 4; i++) + { + RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]); + efuseDataOffset -= 4; + } + ///////////////////////////////////////////////////////////////// + + //Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. + + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + + eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; + + //Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3. + eFuseCtrlStruc.field.EFSROM_MODE = 3; + + //Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure. + eFuseCtrlStruc.field.EFSROM_KICK = 1; + + NdisMoveMemory(&data, &eFuseCtrlStruc, 4); + RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); + + //Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done. + i = 0; + + while(i < 500) + { + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + + if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + break; + + RTMPusecDelay(2); + i++; + } +} + +/* +======================================================================== + + Routine Description: + + Arguments: + + Return Value: + + Note: + +======================================================================== +*/ +static NTSTATUS eFuseWriteRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + IN USHORT* pData) +{ + USHORT i,Loop=0; + USHORT eFuseData; + USHORT LogicalAddress, BlkNum = 0xffff; + UCHAR EFSROM_AOUT; + + USHORT addr,tmpaddr, InBuf[3], tmpOffset; + USHORT buffer[8]; + BOOLEAN bWriteSuccess = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData)); + + //Step 0. find the entry in the mapping table + //The address of EEPROM is 2-bytes alignment. + //The last bit is used for alignment, so it must be 0. + tmpOffset = Offset & 0xfffe; + EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData); + + if( EFSROM_AOUT == 0x3f) + { //find available logical address pointer + //the logical address does not exist, find an empty one + //from the first address of block 45=16*45=0x2d0 to the last address of block 47 + //==>48*16-3(reserved)=2FC + for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2) + { + //Retrive the logical block nubmer form each logical address pointer + //It will access two logical address pointer each time. + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + if( (LogicalAddress & 0xff) == 0) + {//Not used logical address pointer + BlkNum = i-EFUSE_USAGE_MAP_START; + break; + } + else if(( (LogicalAddress >> 8) & 0xff) == 0) + {//Not used logical address pointer + if (i != EFUSE_USAGE_MAP_END) + { + BlkNum = i-EFUSE_USAGE_MAP_START+1; + } + break; + } + } + } + else + { + BlkNum = EFSROM_AOUT; + } + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum)); + + if(BlkNum == 0xffff) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n")); + return FALSE; + } + + //Step 1. Save data of this block which is pointed by the avaible logical address pointer + // read and save the original block data + for(i =0; i<8; i++) + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+2*i; + InBuf[1] = 2; + InBuf[2] = 0x0; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + + buffer[i] = InBuf[2]; + } + + //Step 2. Update the data in buffer, and write the data to Efuse + buffer[ (Offset >> 1) % 8] = pData[0]; + + do + { Loop++; + //Step 3. Write the data to Efuse + if(!bWriteSuccess) + { + for(i =0; i<8; i++) + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+2*i; + InBuf[1] = 2; + InBuf[2] = buffer[i]; + + eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2); + } + } + else + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+(Offset % 16); + InBuf[1] = 2; + InBuf[2] = pData[0]; + + eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2); + } + + //Step 4. Write mapping table + addr = EFUSE_USAGE_MAP_START+BlkNum; + + tmpaddr = addr; + + if(addr % 2 != 0) + addr = addr -1; + InBuf[0] = addr; + InBuf[1] = 2; + + //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry + tmpOffset = Offset; + tmpOffset >>= 4; + tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40; + tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80; + + // write the logical address + if(tmpaddr%2 != 0) + InBuf[2] = tmpOffset<<8; + else + InBuf[2] = tmpOffset; + + eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0); + + //Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted + bWriteSuccess = TRUE; + for(i =0; i<8; i++) + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+2*i; + InBuf[1] = 2; + InBuf[2] = 0x0; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + + if(buffer[i] != InBuf[2]) + { + bWriteSuccess = FALSE; + break; + } + } + + //Step 6. invlidate mapping entry and find a free mapping entry if not succeed + if (!bWriteSuccess) + { + DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum)); + + // the offset of current mapping entry + addr = EFUSE_USAGE_MAP_START+BlkNum; + + //find a new mapping entry + BlkNum = 0xffff; + for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2) + { + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + if( (LogicalAddress & 0xff) == 0) + { + BlkNum = i-EFUSE_USAGE_MAP_START; + break; + } + else if(( (LogicalAddress >> 8) & 0xff) == 0) + { + if (i != EFUSE_USAGE_MAP_END) + { + BlkNum = i+1-EFUSE_USAGE_MAP_START; + } + break; + } + } + DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum)); + if(BlkNum == 0xffff) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n")); + return FALSE; + } + + //invalidate the original mapping entry if new entry is not found + tmpaddr = addr; + + if(addr % 2 != 0) + addr = addr -1; + InBuf[0] = addr; + InBuf[1] = 2; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + + // write the logical address + if(tmpaddr%2 != 0) + { + // Invalidate the high byte + for (i=8; i<15; i++) + { + if( ( (InBuf[2] >> i) & 0x01) == 0) + { + InBuf[2] |= (0x1 <> i) & 0x01) == 0) + { + InBuf[2] |= (0x1 <bUseEfuse) + return FALSE; + for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2) + { + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + if( (LogicalAddress & 0xff) == 0) + { + efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1); + break; + } + else if(( (LogicalAddress >> 8) & 0xff) == 0) + { + efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i); + break; + } + + if(i == EFUSE_USAGE_MAP_END) + efusefreenum = 0; + } + printk("efuseFreeNumber is %d\n",efusefreenum); + return TRUE; +} + + +INT set_eFusedump_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ +USHORT InBuf[3]; + INT i=0; + if(!pAd->bUseEfuse) + return FALSE; + for(i =0; i0) + NdisMoveMemory(src, arg, strlen(arg)); + else + NdisMoveMemory(src, EFUSE_EEPROM_DEFULT_FILE, strlen(EFUSE_EEPROM_DEFULT_FILE)); + DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src)); + + RtmpOSFSInfoChange(&osfsInfo, TRUE); + + srcf = RtmpOSFileOpen(src, O_RDONLY, 0); + if (IS_FILE_OPEN_ERR(srcf)) + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error opening file %s\n", src)); + retval = FALSE; + goto recoverFS; + } + else + { + // The object must have a read method + while(RtmpOSFileRead(srcf, &buffer[i], 1)==1) + { + i++; + if(i>MAX_EEPROM_BIN_FILE_SIZE) + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error reading file %s, file size too large[>%d]\n", src, MAX_EEPROM_BIN_FILE_SIZE)); + retval = FALSE; + goto closeFile; + } + } + + retval = RtmpOSFileClose(srcf); + if (retval) + DBGPRINT(RT_DEBUG_TRACE, ("--> Error closing file %s\n", src)); + } + + + RtmpOSFSInfoChange(&osfsInfo, FALSE); + + for(j=0;j48*16-3(reserved)=2FC + bAllocateNewBlk=TRUE; + for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2) + { + //Retrive the logical block nubmer form each logical address pointer + //It will access two logical address pointer each time. + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + if( (LogicalAddress & 0xff) == 0) + {//Not used logical address pointer + BlkNum = i-EFUSE_USAGE_MAP_START; + break; + } + else if(( (LogicalAddress >> 8) & 0xff) == 0) + {//Not used logical address pointer + if (i != EFUSE_USAGE_MAP_END) + { + BlkNum = i-EFUSE_USAGE_MAP_START+1; + } + break; + } + } + } + else + { + bAllocateNewBlk=FALSE; + BlkNum = EFSROM_AOUT; + } + + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum)); + + if(BlkNum == 0xffff) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n")); + return FALSE; + } + //Step 1.1.0 + //If the block is not existing in mapping table, create one + //and write down the 16-bytes data to the new block + if(bAllocateNewBlk) + { + DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n")); + efuseDataOffset = EFUSE_DATA3; + for(i=0; i< 4; i++) + { + DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i])); + tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i]; + + + RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer); + efuseDataOffset -= 4; + + } + ///////////////////////////////////////////////////////////////// + + //Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ; + + //Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3. + eFuseCtrlStruc.field.EFSROM_MODE = 3; + + //Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure. + eFuseCtrlStruc.field.EFSROM_KICK = 1; + + NdisMoveMemory(&data, &eFuseCtrlStruc, 4); + + RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); + + //Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done. + i = 0; + while(i < 100) + { + RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); + + if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + break; + + RTMPusecDelay(2); + i++; + } + + } + else + { //Step1.2. + //If the same logical number is existing, check if the writting data and the data + //saving in this block are the same. + ///////////////////////////////////////////////////////////////// + //read current values of 16-byte block + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word); + + //Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. + eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; + + //Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1. + eFuseCtrlStruc.field.EFSROM_MODE = 0; + + //Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. + eFuseCtrlStruc.field.EFSROM_KICK = 1; + + NdisMoveMemory(&data, &eFuseCtrlStruc, 4); + RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); + + //Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. + i = 0; + while(i < 500) + { + RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); + + if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + break; + RTMPusecDelay(2); + i++; + } + + //Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590) + efuseDataOffset = EFUSE_DATA3; + for(i=0; i< 4; i++) + { + RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]); + efuseDataOffset -= 4; + } + //Step1.2.5. Check if the data of efuse and the writing data are the same. + for(i =0; i<4; i++) + { + tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i]; + DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer)); + + if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i])) + bNotWrite&=TRUE; + else + { + bNotWrite&=FALSE; + break; + } + } + if(!bNotWrite) + { + printk("The data is not the same\n"); + + for(i =0; i<8; i++) + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+2*i; + InBuf[1] = 2; + InBuf[2] = pData[i]; + + eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2); + } + + } + else + return TRUE; + } + + + + //Step 2. Write mapping table + addr = EFUSE_USAGE_MAP_START+BlkNum; + + tmpaddr = addr; + + if(addr % 2 != 0) + addr = addr -1; + InBuf[0] = addr; + InBuf[1] = 2; + + //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry + tmpOffset = Offset; + tmpOffset >>= 4; + tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40; + tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80; + + // write the logical address + if(tmpaddr%2 != 0) + InBuf[2] = tmpOffset<<8; + else + InBuf[2] = tmpOffset; + + eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0); + + //Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted + bWriteSuccess = TRUE; + for(i =0; i<8; i++) + { + addr = BlkNum * 0x10 ; + + InBuf[0] = addr+2*i; + InBuf[1] = 2; + InBuf[2] = 0x0; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2])); + if(pData[i] != InBuf[2]) + { + bWriteSuccess = FALSE; + break; + } + } + + //Step 4. invlidate mapping entry and find a free mapping entry if not succeed + + if (!bWriteSuccess&&Loop<2) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum)); + + // the offset of current mapping entry + addr = EFUSE_USAGE_MAP_START+BlkNum; + + //find a new mapping entry + BlkNum = 0xffff; + for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2) + { + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + if( (LogicalAddress & 0xff) == 0) + { + BlkNum = i-EFUSE_USAGE_MAP_START; + break; + } + else if(( (LogicalAddress >> 8) & 0xff) == 0) + { + if (i != EFUSE_USAGE_MAP_END) + { + BlkNum = i+1-EFUSE_USAGE_MAP_START; + } + break; + } + } + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum)); + if(BlkNum == 0xffff) + { + DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n")); + return FALSE; + } + + //invalidate the original mapping entry if new entry is not found + tmpaddr = addr; + + if(addr % 2 != 0) + addr = addr -1; + InBuf[0] = addr; + InBuf[1] = 2; + + eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); + + // write the logical address + if(tmpaddr%2 != 0) + { + // Invalidate the high byte + for (i=8; i<15; i++) + { + if( ( (InBuf[2] >> i) & 0x01) == 0) + { + InBuf[2] |= (0x1 <> i) & 0x01) == 0) + { + InBuf[2] |= (0x1 <bFroceEEPROMBuffer || pAd->bEEPROMFile) + { + DBGPRINT(RT_DEBUG_TRACE, ("Read from EEPROM Buffer\n")); + NdisMoveMemory(pValue, &(pAd->EEPROMImage[Offset]), 2); + } + else + eFuseReadRegisters(pAd, Offset, 2, pValue); + return (*pValue); +} + + +int rtmp_ee_efuse_write16( + IN RTMP_ADAPTER *pAd, + IN USHORT Offset, + IN USHORT data) +{ + if(pAd->bFroceEEPROMBuffer||pAd->bEEPROMFile) + { + DBGPRINT(RT_DEBUG_TRACE, ("Write to EEPROM Buffer\n")); + NdisMoveMemory(&(pAd->EEPROMImage[Offset]), &data, 2); + } + else + eFuseWriteRegisters(pAd, Offset, 2, &data); + return 0; +} + + +int RtmpEfuseSupportCheck( + IN RTMP_ADAPTER *pAd) +{ + USHORT value; + + if (IS_RT30xx(pAd)) + { + eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value); + pAd->EFuseTag = (value & 0xff); + } + return 0; +} + +INT set_eFuseBufferModeWriteBack_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UINT Enable; + + + if(strlen(arg)>0) + { + Enable= simple_strtol(arg, 0, 16); + } + else + return FALSE; + if(Enable==1) + { + DBGPRINT(RT_DEBUG_TRACE, ("set_eFuseBufferMode_Proc:: Call WRITEEEPROMBUF")); + eFuseWriteEeeppromBuf(pAd); + } + else + return FALSE; + return TRUE; +} + + +/* + ======================================================================== + + Routine Description: + Load EEPROM from bin file for eFuse mode + + Arguments: + Adapter Pointer to our adapter + + Return Value: + NDIS_STATUS_SUCCESS firmware image load ok + NDIS_STATUS_FAILURE image not found + + IRQL = PASSIVE_LEVEL + + ======================================================================== +*/ +INT eFuseLoadEEPROM( + IN PRTMP_ADAPTER pAd) +{ + PSTRING src = NULL; + INT retval; + RTMP_OS_FD srcf; + RTMP_OS_FS_INFO osFSInfo; + + + src=EFUSE_BUFFER_PATH; + DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src)); + + + RtmpOSFSInfoChange(&osFSInfo, TRUE); + + if (src && *src) + { + srcf = RtmpOSFileOpen(src, O_RDONLY, 0); + if (IS_FILE_OPEN_ERR(srcf)) + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src)); + return FALSE; + } + else + { + + memset(pAd->EEPROMImage, 0x00, MAX_EEPROM_BIN_FILE_SIZE); + + + retval =RtmpOSFileRead(srcf, (PSTRING)pAd->EEPROMImage, MAX_EEPROM_BIN_FILE_SIZE); + if (retval > 0) + { + RTMPSetProfileParameters(pAd, (PSTRING)pAd->EEPROMImage); + retval = NDIS_STATUS_SUCCESS; + } + else + DBGPRINT(RT_DEBUG_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval)); + + } + + + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n")); + return FALSE; + + } + + retval=RtmpOSFileClose(srcf); + + if (retval) + { + DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src)); + } + + + RtmpOSFSInfoChange(&osFSInfo, FALSE); + + return TRUE; +} + +INT eFuseWriteEeeppromBuf( + IN PRTMP_ADAPTER pAd) +{ + + PSTRING src = NULL; + INT retval; + RTMP_OS_FD srcf; + RTMP_OS_FS_INFO osFSInfo; + + + src=EFUSE_BUFFER_PATH; + DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src)); + + RtmpOSFSInfoChange(&osFSInfo, TRUE); + + + + if (src && *src) + { + srcf = RtmpOSFileOpen(src, O_WRONLY|O_CREAT, 0); + + if (IS_FILE_OPEN_ERR(srcf)) + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src)); + return FALSE; + } + else + { +/* + // The object must have a read method + if (srcf->f_op && srcf->f_op->write) + { + // The object must have a read method + srcf->f_op->write(srcf, pAd->EEPROMImage, 1024, &srcf->f_pos); + + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n")); + return FALSE; + } +*/ + + RtmpOSFileWrite(srcf, (PSTRING)pAd->EEPROMImage,MAX_EEPROM_BIN_FILE_SIZE); + + } + + + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n")); + return FALSE; + + } + + retval=RtmpOSFileClose(srcf); + + if (retval) + { + DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src)); + } + + RtmpOSFSInfoChange(&osFSInfo, FALSE); + return TRUE; +} + + +VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd, + PUINT EfuseFreeBlock) +{ + USHORT i; + USHORT LogicalAddress; + if(!pAd->bUseEfuse) + { + DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount Only supports efuse Mode\n")); + return ; + } + for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2) + { + eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); + if( (LogicalAddress & 0xff) == 0) + { + *EfuseFreeBlock= (UCHAR) (EFUSE_USAGE_MAP_END-i+1); + break; + } + else if(( (LogicalAddress >> 8) & 0xff) == 0) + { + *EfuseFreeBlock = (UCHAR) (EFUSE_USAGE_MAP_END-i); + break; + } + + if(i == EFUSE_USAGE_MAP_END) + *EfuseFreeBlock = 0; + } + DBGPRINT(RT_DEBUG_TRACE,("eFuseGetFreeBlockCount is 0x%x\n",*EfuseFreeBlock)); +} + +INT eFuse_init( + IN PRTMP_ADAPTER pAd) +{ + UINT EfuseFreeBlock=0; + DBGPRINT(RT_DEBUG_ERROR, ("NVM is Efuse and its size =%x[%x-%x] \n",EFUSE_USAGE_MAP_SIZE,EFUSE_USAGE_MAP_START,EFUSE_USAGE_MAP_END)); + eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock); + //If the used block of efuse is less than 5. We assume the default value + // of this efuse is empty and change to the buffer mode in odrder to + //bring up interfaces successfully. + if(EfuseFreeBlock > (EFUSE_USAGE_MAP_END-5)) + { + DBGPRINT(RT_DEBUG_ERROR, ("NVM is Efuse and the information is too less to bring up interface. Force to use EEPROM Buffer Mode\n")); + pAd->bFroceEEPROMBuffer = TRUE; + eFuseLoadEEPROM(pAd); + } + else + pAd->bFroceEEPROMBuffer = FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse and force to use EEPROM Buffer Mode=%x\n",pAd->bFroceEEPROMBuffer)); + + return 0; +} Index: b/drivers/staging/rt2860/common/ee_prom.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/ee_prom.c @@ -0,0 +1,270 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + ee_prom.c + + Abstract: + Miniport generic portion header file + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + + +#include "../rt_config.h" + + + +// IRQL = PASSIVE_LEVEL +static inline VOID RaiseClock( + IN PRTMP_ADAPTER pAd, + IN UINT32 *x) +{ + *x = *x | EESK; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x); + RTMPusecDelay(1); // Max frequency = 1MHz in Spec. definition +} + +// IRQL = PASSIVE_LEVEL +static inline VOID LowerClock( + IN PRTMP_ADAPTER pAd, + IN UINT32 *x) +{ + *x = *x & ~EESK; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x); + RTMPusecDelay(1); +} + +// IRQL = PASSIVE_LEVEL +static inline USHORT ShiftInBits( + IN PRTMP_ADAPTER pAd) +{ + UINT32 x,i; + USHORT data=0; + + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + + x &= ~( EEDO | EEDI); + + for(i=0; i<16; i++) + { + data = data << 1; + RaiseClock(pAd, &x); + + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + LowerClock(pAd, &x); //prevent read failed + + x &= ~(EEDI); + if(x & EEDO) + data |= 1; + } + + return data; +} + + +// IRQL = PASSIVE_LEVEL +static inline VOID ShiftOutBits( + IN PRTMP_ADAPTER pAd, + IN USHORT data, + IN USHORT count) +{ + UINT32 x,mask; + + mask = 0x01 << (count - 1); + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + + x &= ~(EEDO | EEDI); + + do + { + x &= ~EEDI; + if(data & mask) x |= EEDI; + + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + + mask = mask >> 1; + } while(mask); + + x &= ~EEDI; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); +} + + +// IRQL = PASSIVE_LEVEL +static inline VOID EEpromCleanup( + IN PRTMP_ADAPTER pAd) +{ + UINT32 x; + + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + + x &= ~(EECS | EEDI); + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + RaiseClock(pAd, &x); + LowerClock(pAd, &x); +} + + +static inline VOID EWEN( + IN PRTMP_ADAPTER pAd) +{ + UINT32 x; + + // reset bits and set EECS + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EEDI | EEDO | EESK); + x |= EECS; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + // kick a pulse + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + + // output the read_opcode and six pulse in that order + ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5); + ShiftOutBits(pAd, 0, 6); + + EEpromCleanup(pAd); +} + + +static inline VOID EWDS( + IN PRTMP_ADAPTER pAd) +{ + UINT32 x; + + // reset bits and set EECS + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EEDI | EEDO | EESK); + x |= EECS; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + // kick a pulse + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + + // output the read_opcode and six pulse in that order + ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5); + ShiftOutBits(pAd, 0, 6); + + EEpromCleanup(pAd); +} + + +// IRQL = PASSIVE_LEVEL +int rtmp_ee_prom_read16( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT USHORT *pValue) +{ + UINT32 x; + USHORT data; + + + Offset /= 2; + // reset bits and set EECS + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EEDI | EEDO | EESK); + x |= EECS; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + // patch can not access e-Fuse issue + if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) + { + // kick a pulse + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + } + + // output the read_opcode and register number in that order + ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3); + ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum); + + // Now read the data (16 bits) in from the selected EEPROM word + data = ShiftInBits(pAd); + + EEpromCleanup(pAd); + + + *pValue = data; + + return NDIS_STATUS_SUCCESS; +} + + +int rtmp_ee_prom_write16( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Data) +{ + UINT32 x; + + + Offset /= 2; + + EWEN(pAd); + + // reset bits and set EECS + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + x &= ~(EEDI | EEDO | EESK); + x |= EECS; + RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); + + // patch can not access e-Fuse issue + if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) + { + // kick a pulse + RaiseClock(pAd, &x); + LowerClock(pAd, &x); + } + + // output the read_opcode ,register number and data in that order + ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3); + ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum); + ShiftOutBits(pAd, Data, 16); // 16-bit access + + // read DO status + RTMP_IO_READ32(pAd, E2PROM_CSR, &x); + + EEpromCleanup(pAd); + + RTMPusecDelay(10000); //delay for twp(MAX)=10ms + + EWDS(pAd); + + EEpromCleanup(pAd); + + + return NDIS_STATUS_SUCCESS; + +} Index: b/drivers/staging/rt2860/common/eeprom.c =================================================================== --- a/drivers/staging/rt2860/common/eeprom.c +++ b/drivers/staging/rt2860/common/eeprom.c @@ -36,1444 +36,68 @@ */ #include "../rt_config.h" -// IRQL = PASSIVE_LEVEL -VOID RaiseClock( - IN PRTMP_ADAPTER pAd, - IN UINT32 *x) -{ - *x = *x | EESK; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x); - RTMPusecDelay(1); // Max frequency = 1MHz in Spec. definition -} - -// IRQL = PASSIVE_LEVEL -VOID LowerClock( - IN PRTMP_ADAPTER pAd, - IN UINT32 *x) -{ - *x = *x & ~EESK; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x); - RTMPusecDelay(1); -} - -// IRQL = PASSIVE_LEVEL -USHORT ShiftInBits( - IN PRTMP_ADAPTER pAd) -{ - UINT32 x,i; - USHORT data=0; - - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - - x &= ~( EEDO | EEDI); - - for(i=0; i<16; i++) - { - data = data << 1; - RaiseClock(pAd, &x); - - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - - LowerClock(pAd, &x); /* prevent read failed */ - - x &= ~(EEDI); - if(x & EEDO) - data |= 1; - } - - return data; -} - -// IRQL = PASSIVE_LEVEL -VOID ShiftOutBits( - IN PRTMP_ADAPTER pAd, - IN USHORT data, - IN USHORT count) -{ - UINT32 x,mask; - - mask = 0x01 << (count - 1); - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - - x &= ~(EEDO | EEDI); - - do - { - x &= ~EEDI; - if(data & mask) x |= EEDI; - - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - RaiseClock(pAd, &x); - LowerClock(pAd, &x); - - mask = mask >> 1; - } while(mask); - - x &= ~EEDI; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); -} - -// IRQL = PASSIVE_LEVEL -VOID EEpromCleanup( - IN PRTMP_ADAPTER pAd) -{ - UINT32 x; - - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - - x &= ~(EECS | EEDI); - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - RaiseClock(pAd, &x); - LowerClock(pAd, &x); -} - -VOID EWEN( - IN PRTMP_ADAPTER pAd) -{ - UINT32 x; - - // reset bits and set EECS - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - x &= ~(EEDI | EEDO | EESK); - x |= EECS; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - // kick a pulse - RaiseClock(pAd, &x); - LowerClock(pAd, &x); - - // output the read_opcode and six pulse in that order - ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5); - ShiftOutBits(pAd, 0, 6); - - EEpromCleanup(pAd); -} - -VOID EWDS( - IN PRTMP_ADAPTER pAd) -{ - UINT32 x; - - // reset bits and set EECS - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - x &= ~(EEDI | EEDO | EESK); - x |= EECS; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - // kick a pulse - RaiseClock(pAd, &x); - LowerClock(pAd, &x); - - // output the read_opcode and six pulse in that order - ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5); - ShiftOutBits(pAd, 0, 6); - - EEpromCleanup(pAd); -} - -// IRQL = PASSIVE_LEVEL -USHORT RTMP_EEPROM_READ16( - IN PRTMP_ADAPTER pAd, - IN USHORT Offset) -{ - UINT32 x; - USHORT data; - -#ifdef RT2870 - if (pAd->NicConfig2.field.AntDiversity) - { - pAd->EepromAccess = TRUE; - } -#endif - Offset /= 2; - // reset bits and set EECS - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - x &= ~(EEDI | EEDO | EESK); - x |= EECS; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - // patch can not access e-Fuse issue - if (!IS_RT3090(pAd)) - { - // kick a pulse - RaiseClock(pAd, &x); - LowerClock(pAd, &x); - } - - // output the read_opcode and register number in that order - ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3); - ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum); - - // Now read the data (16 bits) in from the selected EEPROM word - data = ShiftInBits(pAd); - - EEpromCleanup(pAd); - -#ifdef RT2870 - // Antenna and EEPROM access are both using EESK pin, - // Therefor we should avoid accessing EESK at the same time - // Then restore antenna after EEPROM access - if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020)) - { - pAd->EepromAccess = FALSE; - AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); - } -#endif - return data; -} //ReadEEprom -VOID RTMP_EEPROM_WRITE16( - IN PRTMP_ADAPTER pAd, - IN USHORT Offset, - IN USHORT Data) -{ - UINT32 x; - -#ifdef RT2870 - if (pAd->NicConfig2.field.AntDiversity) - { - pAd->EepromAccess = TRUE; - } -#endif - Offset /= 2; - - EWEN(pAd); - - // reset bits and set EECS - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - x &= ~(EEDI | EEDO | EESK); - x |= EECS; - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - // patch can not access e-Fuse issue - if (!IS_RT3090(pAd)) - { - // kick a pulse - RaiseClock(pAd, &x); - LowerClock(pAd, &x); - } - - // output the read_opcode ,register number and data in that order - ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3); - ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum); - ShiftOutBits(pAd, Data, 16); // 16-bit access - - // read DO status - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - - EEpromCleanup(pAd); - - RTMPusecDelay(10000); //delay for twp(MAX)=10ms - - EWDS(pAd); - - EEpromCleanup(pAd); - -#ifdef RT2870 - // Antenna and EEPROM access are both using EESK pin, - // Therefor we should avoid accessing EESK at the same time - // Then restore antenna after EEPROM access - if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020)) - { - pAd->EepromAccess = FALSE; - AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); - } -#endif -} - -#ifdef RT2870 -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -UCHAR eFuseReadRegisters( - IN PRTMP_ADAPTER pAd, - IN USHORT Offset, - IN USHORT Length, - OUT USHORT* pData) -{ - EFUSE_CTRL_STRUC eFuseCtrlStruc; - int i; - USHORT efuseDataOffset; - UINT32 data; - - RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); - - //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. - //Use the eeprom logical address and covert to address to block number - eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; - - //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0. - eFuseCtrlStruc.field.EFSROM_MODE = 0; - - //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. - eFuseCtrlStruc.field.EFSROM_KICK = 1; - - NdisMoveMemory(&data, &eFuseCtrlStruc, 4); - RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); - - //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. - i = 0; - while(i < 100) - { - //rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4); - RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); - if(eFuseCtrlStruc.field.EFSROM_KICK == 0) - { - break; - } - RTMPusecDelay(2); - i++; - } - - //if EFSROM_AOUT is not found in physical address, write 0xffff - if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f) - { - for(i=0; i> (8*(Offset & 0x3)); - - NdisMoveMemory(pData, &data, Length); - } - - return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT; - -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -VOID eFusePhysicalReadRegisters( - IN PRTMP_ADAPTER pAd, - IN USHORT Offset, - IN USHORT Length, - OUT USHORT* pData) -{ - EFUSE_CTRL_STRUC eFuseCtrlStruc; - int i; - USHORT efuseDataOffset; - UINT32 data; - - RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); - - //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. - eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; - - //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1. - //Read in physical view - eFuseCtrlStruc.field.EFSROM_MODE = 1; - - //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. - eFuseCtrlStruc.field.EFSROM_KICK = 1; - - NdisMoveMemory(&data, &eFuseCtrlStruc, 4); - RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); - - //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. - i = 0; - while(i < 100) - { - RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); - if(eFuseCtrlStruc.field.EFSROM_KICK == 0) - break; - RTMPusecDelay(2); - i++; - } - - //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590) - //Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits. - //The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes - //Decide which EFUSE_DATA to read - //590:F E D C - //594:B A 9 8 - //598:7 6 5 4 - //59C:3 2 1 0 - efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ; - - RTMP_IO_READ32(pAd, efuseDataOffset, &data); - - data = data >> (8*(Offset & 0x3)); - - NdisMoveMemory(pData, &data, Length); - -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -VOID eFuseReadPhysical( - IN PRTMP_ADAPTER pAd, - IN PUSHORT lpInBuffer, - IN ULONG nInBufferSize, - OUT PUSHORT lpOutBuffer, - IN ULONG nOutBufferSize -) -{ - USHORT* pInBuf = (USHORT*)lpInBuffer; - USHORT* pOutBuf = (USHORT*)lpOutBuffer; - - USHORT Offset = pInBuf[0]; //addr - USHORT Length = pInBuf[1]; //length - int i; - - for(i=0; i> 2; - data = pData[0] & 0xffff; - //The offset should be 0x***10 or 0x***00 - if((Offset % 4) != 0) - { - eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16); - } - else - { - eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data; - } - - efuseDataOffset = EFUSE_DATA3; - for(i=0; i< 4; i++) - { - RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]); - efuseDataOffset -= 4; - } - ///////////////////////////////////////////////////////////////// - - //Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. - eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; - - //Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3. - eFuseCtrlStruc.field.EFSROM_MODE = 3; - - //Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure. - eFuseCtrlStruc.field.EFSROM_KICK = 1; - - NdisMoveMemory(&data, &eFuseCtrlStruc, 4); - RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); - - //Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It��s done. - i = 0; - while(i < 100) - { - RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); - - if(eFuseCtrlStruc.field.EFSROM_KICK == 0) - break; - - RTMPusecDelay(2); - i++; - } -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -NTSTATUS eFuseWriteRegisters( - IN PRTMP_ADAPTER pAd, - IN USHORT Offset, - IN USHORT Length, - IN USHORT* pData) -{ - USHORT i; - USHORT eFuseData; - USHORT LogicalAddress, BlkNum = 0xffff; - UCHAR EFSROM_AOUT; - - USHORT addr,tmpaddr, InBuf[3], tmpOffset; - USHORT buffer[8]; - BOOLEAN bWriteSuccess = TRUE; - - DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData)); - - //Step 0. find the entry in the mapping table - //The address of EEPROM is 2-bytes alignment. - //The last bit is used for alignment, so it must be 0. - tmpOffset = Offset & 0xfffe; - EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData); - - if( EFSROM_AOUT == 0x3f) - { //find available logical address pointer - //the logical address does not exist, find an empty one - //from the first address of block 45=16*45=0x2d0 to the last address of block 47 - //==>48*16-3(reserved)=2FC - for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2) - { - //Retrive the logical block nubmer form each logical address pointer - //It will access two logical address pointer each time. - eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); - if( (LogicalAddress & 0xff) == 0) - {//Not used logical address pointer - BlkNum = i-EFUSE_USAGE_MAP_START; - break; - } - else if(( (LogicalAddress >> 8) & 0xff) == 0) - {//Not used logical address pointer - if (i != EFUSE_USAGE_MAP_END) - { - BlkNum = i-EFUSE_USAGE_MAP_START+1; - } - break; - } - } - } - else - { - BlkNum = EFSROM_AOUT; - } - - DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum)); - - if(BlkNum == 0xffff) - { - DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n")); - return FALSE; - } - - //Step 1. Save data of this block which is pointed by the avaible logical address pointer - // read and save the original block data - for(i =0; i<8; i++) - { - addr = BlkNum * 0x10 ; - - InBuf[0] = addr+2*i; - InBuf[1] = 2; - InBuf[2] = 0x0; - - eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); - - buffer[i] = InBuf[2]; - } - - //Step 2. Update the data in buffer, and write the data to Efuse - buffer[ (Offset >> 1) % 8] = pData[0]; +INT RtmpChipOpsEepromHook( + IN RTMP_ADAPTER *pAd, + IN INT infType) +{ + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; +#ifdef RT30xx +#ifdef RTMP_EFUSE_SUPPORT + UINT32 eFuseCtrl, MacCsr0; + int index; + index = 0; do { - //Step 3. Write the data to Efuse - if(!bWriteSuccess) - { - for(i =0; i<8; i++) - { - addr = BlkNum * 0x10 ; - - InBuf[0] = addr+2*i; - InBuf[1] = 2; - InBuf[2] = buffer[i]; - - eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2); - } - } - else - { - addr = BlkNum * 0x10 ; - - InBuf[0] = addr+(Offset % 16); - InBuf[1] = 2; - InBuf[2] = pData[0]; - - eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2); - } - - //Step 4. Write mapping table - addr = EFUSE_USAGE_MAP_START+BlkNum; - - tmpaddr = addr; - - if(addr % 2 != 0) - addr = addr -1; - InBuf[0] = addr; - InBuf[1] = 2; + RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); + pAd->MACVersion = MacCsr0; - //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry - tmpOffset = Offset; - tmpOffset >>= 4; - tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40; - tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80; - - // write the logical address - if(tmpaddr%2 != 0) - InBuf[2] = tmpOffset<<8; - else - InBuf[2] = tmpOffset; - - eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0); - - //Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted - bWriteSuccess = TRUE; - for(i =0; i<8; i++) - { - addr = BlkNum * 0x10 ; - - InBuf[0] = addr+2*i; - InBuf[1] = 2; - InBuf[2] = 0x0; - - eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); - - if(buffer[i] != InBuf[2]) - { - bWriteSuccess = FALSE; - break; - } - } - - //Step 6. invlidate mapping entry and find a free mapping entry if not succeed - if (!bWriteSuccess) - { - DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum)); - - // the offset of current mapping entry - addr = EFUSE_USAGE_MAP_START+BlkNum; - - //find a new mapping entry - BlkNum = 0xffff; - for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2) - { - eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); - if( (LogicalAddress & 0xff) == 0) - { - BlkNum = i-EFUSE_USAGE_MAP_START; - break; - } - else if(( (LogicalAddress >> 8) & 0xff) == 0) - { - if (i != EFUSE_USAGE_MAP_END) - { - BlkNum = i+1-EFUSE_USAGE_MAP_START; - } - break; - } - } - DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum)); - if(BlkNum == 0xffff) - { - DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n")); - return FALSE; - } - - //invalidate the original mapping entry if new entry is not found - tmpaddr = addr; - - if(addr % 2 != 0) - addr = addr -1; - InBuf[0] = addr; - InBuf[1] = 2; - - eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); - - // write the logical address - if(tmpaddr%2 != 0) - { - // Invalidate the high byte - for (i=8; i<15; i++) - { - if( ( (InBuf[2] >> i) & 0x01) == 0) - { - InBuf[2] |= (0x1 <> i) & 0x01) == 0) - { - InBuf[2] |= (0x1 <bUseEfuse) - return FALSE; - for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2) - { - eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); - if( (LogicalAddress & 0xff) == 0) - { - efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1); - break; - } - else if(( (LogicalAddress >> 8) & 0xff) == 0) - { - efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i); - break; - } - - if(i == EFUSE_USAGE_MAP_END) - efusefreenum = 0; - } - printk("efuseFreeNumber is %d\n",efusefreenum); - return TRUE; -} -INT set_eFusedump_Proc( - IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) -{ -USHORT InBuf[3]; - INT i=0; - if(!pAd->bUseEfuse) - return FALSE; - for(i =0; i0) - { - - NdisMoveMemory(src, arg, strlen(arg)); - } - - else - { - - NdisMoveMemory(src, "RT30xxEEPROM.bin", BinFileSize); - } - - DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src)); - buffer = kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG); - - if(buffer == NULL) - { - kfree(src); - return FALSE; -} - PDATA=kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG); - - if(PDATA==NULL) - { - kfree(src); - - kfree(buffer); - return FALSE; - } - - orgfs = get_fs(); - set_fs(KERNEL_DS); - - if (src && *src) - { - srcf = filp_open(src, O_RDONLY, 0); - if (IS_ERR(srcf)) - { - DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src)); - return FALSE; - } - else - { - // The object must have a read method - if (srcf->f_op && srcf->f_op->read) - { - memset(buffer, 0x00, MAX_EEPROM_BIN_FILE_SIZE); - while(srcf->f_op->read(srcf, &buffer[i], 1, &srcf->f_pos)==1) - { - DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[i])); - if((i+1)%8==0) - DBGPRINT(RT_DEBUG_TRACE, ("\n")); - i++; - if(i>=MAX_EEPROM_BIN_FILE_SIZE) - { - DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld reading %s, The file is too large[1024]\n", -PTR_ERR(srcf),src)); - kfree(PDATA); - kfree(buffer); - kfree(src); - return FALSE; - } - } - } - else - { - DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n")); - kfree(PDATA); - kfree(buffer); - kfree(src); - return FALSE; - } - } - - - } - else - { - DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n")); - kfree(PDATA); - kfree(buffer); - return FALSE; - - } - - - retval=filp_close(srcf,NULL); - - if (retval) - { - DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src)); - } - set_fs(orgfs); - - for(j=0;j48*16-3(reserved)=2FC - bAllocateNewBlk=TRUE; - for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2) - { - //Retrive the logical block nubmer form each logical address pointer - //It will access two logical address pointer each time. - eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); - if( (LogicalAddress & 0xff) == 0) - {//Not used logical address pointer - BlkNum = i-EFUSE_USAGE_MAP_START; - break; - } - else if(( (LogicalAddress >> 8) & 0xff) == 0) - {//Not used logical address pointer - if (i != EFUSE_USAGE_MAP_END) - { - BlkNum = i-EFUSE_USAGE_MAP_START+1; - } - break; - } - } - } - else - { - bAllocateNewBlk=FALSE; - BlkNum = EFSROM_AOUT; - } - - DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum)); - - if(BlkNum == 0xffff) - { - DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n")); - return FALSE; - } - //Step 1.1.0 - //If the block is not existing in mapping table, create one - //and write down the 16-bytes data to the new block - if(bAllocateNewBlk) - { - DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n")); - efuseDataOffset = EFUSE_DATA3; - for(i=0; i< 4; i++) - { - DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i])); - tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i]; - - - RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer); - efuseDataOffset -= 4; - - } - ///////////////////////////////////////////////////////////////// - - //Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. - eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ; - - //Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3. - eFuseCtrlStruc.field.EFSROM_MODE = 3; - - //Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure. - eFuseCtrlStruc.field.EFSROM_KICK = 1; - - NdisMoveMemory(&data, &eFuseCtrlStruc, 4); - - RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); - - //Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It��s done. - i = 0; - while(i < 100) - { - RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); - - if(eFuseCtrlStruc.field.EFSROM_KICK == 0) + if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF)) break; - RTMPusecDelay(2); - i++; - } - - } - else - { //Step1.2. - //If the same logical number is existing, check if the writting data and the data - //saving in this block are the same. - ///////////////////////////////////////////////////////////////// - //read current values of 16-byte block - RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); + RTMPusecDelay(10); + } while (index++ < 100); - //Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. - eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0; - - //Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1. - eFuseCtrlStruc.field.EFSROM_MODE = 0; - - //Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. - eFuseCtrlStruc.field.EFSROM_KICK = 1; - - NdisMoveMemory(&data, &eFuseCtrlStruc, 4); - RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data); - - //Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. - i = 0; - while(i < 100) - { - RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc); - - if(eFuseCtrlStruc.field.EFSROM_KICK == 0) - break; - RTMPusecDelay(2); - i++; - } - - //Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590) - efuseDataOffset = EFUSE_DATA3; - for(i=0; i< 4; i++) - { - RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]); - efuseDataOffset -= 4; - } - //Step1.2.5. Check if the data of efuse and the writing data are the same. - for(i =0; i<4; i++) - { - tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i]; - DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer)); - - if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i])) - bNotWrite&=TRUE; - else - { - bNotWrite&=FALSE; - break; - } - } - if(!bNotWrite) - { - printk("The data is not the same\n"); - - for(i =0; i<8; i++) + pAd->bUseEfuse=FALSE; + RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl); + pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0; + if(pAd->bUseEfuse) { - addr = BlkNum * 0x10 ; - - InBuf[0] = addr+2*i; - InBuf[1] = 2; - InBuf[2] = pData[i]; - - eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2); - } - - } - else - return TRUE; + pChipOps->eeinit = eFuse_init; + pChipOps->eeread = rtmp_ee_efuse_read16; + pChipOps->eewrite = rtmp_ee_efuse_write16; + return 0 ; } - - - - //Step 2. Write mapping table - addr = EFUSE_USAGE_MAP_START+BlkNum; - - tmpaddr = addr; - - if(addr % 2 != 0) - addr = addr -1; - InBuf[0] = addr; - InBuf[1] = 2; - - //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry - tmpOffset = Offset; - tmpOffset >>= 4; - tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40; - tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80; - - // write the logical address - if(tmpaddr%2 != 0) - InBuf[2] = tmpOffset<<8; else - InBuf[2] = tmpOffset; - - eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0); - - //Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted - bWriteSuccess = TRUE; - for(i =0; i<8; i++) - { - addr = BlkNum * 0x10 ; - - InBuf[0] = addr+2*i; - InBuf[1] = 2; - InBuf[2] = 0x0; - - eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); - DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2])); - if(pData[i] != InBuf[2]) { - bWriteSuccess = FALSE; - break; + pAd->bFroceEEPROMBuffer = FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n")); } - } - - //Step 4. invlidate mapping entry and find a free mapping entry if not succeed +#endif // RTMP_EFUSE_SUPPORT // +#endif // RT30xx // - if (!bWriteSuccess&&Loop<2) + switch(infType) { - DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum)); - - // the offset of current mapping entry - addr = EFUSE_USAGE_MAP_START+BlkNum; - - //find a new mapping entry - BlkNum = 0xffff; - for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2) - { - eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress); - if( (LogicalAddress & 0xff) == 0) - { - BlkNum = i-EFUSE_USAGE_MAP_START; +#ifdef RTMP_PCI_SUPPORT + case RTMP_DEV_INF_PCI: + pChipOps->eeinit = NULL; + pChipOps->eeread = rtmp_ee_prom_read16; + pChipOps->eewrite = rtmp_ee_prom_write16; break; - } - else if(( (LogicalAddress >> 8) & 0xff) == 0) - { - if (i != EFUSE_USAGE_MAP_END) - { - BlkNum = i+1-EFUSE_USAGE_MAP_START; - } +#endif // RTMP_PCI_SUPPORT // +#ifdef RTMP_USB_SUPPORT + case RTMP_DEV_INF_USB: + pChipOps->eeinit = NULL; + pChipOps->eeread = RTUSBReadEEPROM16; + pChipOps->eewrite = RTUSBWriteEEPROM16; break; - } - } - DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum)); - if(BlkNum == 0xffff) - { - DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n")); - return FALSE; - } - - //invalidate the original mapping entry if new entry is not found - tmpaddr = addr; +#endif // RTMP_USB_SUPPORT // - if(addr % 2 != 0) - addr = addr -1; - InBuf[0] = addr; - InBuf[1] = 2; - - eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); - - // write the logical address - if(tmpaddr%2 != 0) - { - // Invalidate the high byte - for (i=8; i<15; i++) - { - if( ( (InBuf[2] >> i) & 0x01) == 0) - { - InBuf[2] |= (0x1 <> i) & 0x01) == 0) - { - InBuf[2] |= (0x1 < 64) { - MD5_CTX ttcontext; - - MD5Init(&ttcontext); - MD5Update(&ttcontext, key, key_len); - MD5Final(tk, &ttcontext); - //key=(PUCHAR)ttcontext.buf; - key = tk; - key_len = 16; - } - - /* the HMAC_MD5 transform looks like: - * - * MD5(K XOR opad, MD5(K XOR ipad, text)) - * - * where K is an n byte key - * ipad is the byte 0x36 repeated 64 times - * opad is the byte 0x5c repeated 64 times - * and text is the data being protected */ - - /* start out by storing key in pads */ - NdisZeroMemory(k_ipad, sizeof(k_ipad)); - NdisZeroMemory(k_opad, sizeof(k_opad)); - //assert(key_len < sizeof(k_ipad)); - NdisMoveMemory(k_ipad, key, key_len); - NdisMoveMemory(k_opad, key, key_len); - - /* XOR key with ipad and opad values */ - for (i = 0; i < 64; i++) { - k_ipad[i] ^= 0x36; - k_opad[i] ^= 0x5c; - } - - /* perform inner MD5 */ - MD5Init(&context); /* init context for 1st pass */ - MD5Update(&context, k_ipad, 64); /* start with inner pad */ - MD5Update(&context, data, data_len); /* then text of datagram */ - MD5Final(mac, &context); /* finish up 1st pass */ - - /* perform outer MD5 */ - MD5Init(&context); /* init context for 2nd pass */ - MD5Update(&context, k_opad, 64); /* start with outer pad */ - MD5Update(&context, mac, 16); /* then results of 1st hash */ - MD5Final(mac, &context); /* finish up 2nd pass */ -} - -#define byteReverse(buf, len) /* Nothing */ - -/* ========================== MD5 implementation =========================== */ -// four base functions for MD5 -#define MD5_F1(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define MD5_F2(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define MD5_F3(x, y, z) ((x) ^ (y) ^ (z)) -#define MD5_F4(x, y, z) ((y) ^ ((x) | (~z))) -#define CYCLIC_LEFT_SHIFT(w, s) (((w) << (s)) | ((w) >> (32-(s)))) - -#define MD5Step(f, w, x, y, z, data, t, s) \ - ( w += f(x, y, z) + data + t, w = (CYCLIC_LEFT_SHIFT(w, s)) & 0xffffffff, w += x ) - - -/* - * Function Description: - * Initiate MD5 Context satisfied in RFC 1321 - * - * Arguments: - * pCtx Pointer to MD5 context - * - * Return Value: - * None - */ -VOID MD5Init(MD5_CTX *pCtx) -{ - pCtx->Buf[0]=0x67452301; - pCtx->Buf[1]=0xefcdab89; - pCtx->Buf[2]=0x98badcfe; - pCtx->Buf[3]=0x10325476; - - pCtx->LenInBitCount[0]=0; - pCtx->LenInBitCount[1]=0; -} - - -/* - * Function Description: - * Update MD5 Context, allow of an arrary of octets as the next portion - * of the message - * - * Arguments: - * pCtx Pointer to MD5 context - * pData Pointer to input data - * LenInBytes The length of input data (unit: byte) - * - * Return Value: - * None - * - * Note: - * Called after MD5Init or MD5Update(itself) - */ -VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes) -{ - - UINT32 TfTimes; - UINT32 temp; - unsigned int i; - - temp = pCtx->LenInBitCount[0]; - - pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3)); - - if (pCtx->LenInBitCount[0] < temp) - pCtx->LenInBitCount[1]++; //carry in - - pCtx->LenInBitCount[1] += LenInBytes >> 29; - - // mod 64 bytes - temp = (temp >> 3) & 0x3f; - - // process lacks of 64-byte data - if (temp) - { - UCHAR *pAds = (UCHAR *) pCtx->Input + temp; - - if ((temp+LenInBytes) < 64) - { - NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes); - return; - } - - NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp); - byteReverse(pCtx->Input, 16); - MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input); - - pData += 64-temp; - LenInBytes -= 64-temp; - } // end of if (temp) - - - TfTimes = (LenInBytes >> 6); - - for (i=TfTimes; i>0; i--) - { - NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64); - byteReverse(pCtx->Input, 16); - MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input); - pData += 64; - LenInBytes -= 64; - } // end of for - - // buffering lacks of 64-byte data - if(LenInBytes) - NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes); - -} - - -/* - * Function Description: - * Append padding bits and length of original message in the tail - * The message digest has to be completed in the end - * - * Arguments: - * Digest Output of Digest-Message for MD5 - * pCtx Pointer to MD5 context - * - * Return Value: - * None - * - * Note: - * Called after MD5Update - */ -VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx) -{ - UCHAR Remainder; - UCHAR PadLenInBytes; - UCHAR *pAppend=0; - unsigned int i; - - Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f); - - PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder); - - pAppend = (UCHAR *)pCtx->Input + Remainder; - - // padding bits without crossing block(64-byte based) boundary - if (Remainder < 56) - { - *pAppend = 0x80; - PadLenInBytes --; - - NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes); - - // add data-length field, from low to high - for (i=0; i<4; i++) - { - pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff); - pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff); - } - - byteReverse(pCtx->Input, 16); - MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input); - } // end of if - - // padding bits with crossing block(64-byte based) boundary - else - { - // the first block === - *pAppend = 0x80; - PadLenInBytes --; - - NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1)); - PadLenInBytes -= (64 - Remainder - 1); - - byteReverse(pCtx->Input, 16); - MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input); - - - // the second block === - NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes); - - // add data-length field - for (i=0; i<4; i++) - { - pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff); - pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff); - } - - byteReverse(pCtx->Input, 16); - MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input); - } // end of else - - - NdisMoveMemory((UCHAR *)Digest, (UINT32 *)pCtx->Buf, 16); // output - byteReverse((UCHAR *)Digest, 4); - NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free -} - - -/* - * Function Description: - * The central algorithm of MD5, consists of four rounds and sixteen - * steps per round - * - * Arguments: - * Buf Buffers of four states (output: 16 bytes) - * Mes Input data (input: 64 bytes) - * - * Return Value: - * None - * - * Note: - * Called by MD5Update or MD5Final - */ -VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16]) -{ - UINT32 Reg[4], Temp; - unsigned int i; - - static UCHAR LShiftVal[16] = - { - 7, 12, 17, 22, - 5, 9 , 14, 20, - 4, 11, 16, 23, - 6, 10, 15, 21, - }; - - - // [equal to 4294967296*abs(sin(index))] - static UINT32 MD5Table[64] = - { - 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, - 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, - 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, - - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, - 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, - 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, - - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, - 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, - 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, - - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, - 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, - 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 - }; - - - for (i=0; i<4; i++) - Reg[i]=Buf[i]; - - - // 64 steps in MD5 algorithm - for (i=0; i<16; i++) - { - MD5Step(MD5_F1, Reg[0], Reg[1], Reg[2], Reg[3], Mes[i], - MD5Table[i], LShiftVal[i & 0x3]); - - // one-word right shift - Temp = Reg[3]; - Reg[3] = Reg[2]; - Reg[2] = Reg[1]; - Reg[1] = Reg[0]; - Reg[0] = Temp; - } - for (i=16; i<32; i++) - { - MD5Step(MD5_F2, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(5*(i & 0xf)+1) & 0xf], - MD5Table[i], LShiftVal[(0x1 << 2)+(i & 0x3)]); - - // one-word right shift - Temp = Reg[3]; - Reg[3] = Reg[2]; - Reg[2] = Reg[1]; - Reg[1] = Reg[0]; - Reg[0] = Temp; - } - for (i=32; i<48; i++) - { - MD5Step(MD5_F3, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(3*(i & 0xf)+5) & 0xf], - MD5Table[i], LShiftVal[(0x1 << 3)+(i & 0x3)]); - - // one-word right shift - Temp = Reg[3]; - Reg[3] = Reg[2]; - Reg[2] = Reg[1]; - Reg[1] = Reg[0]; - Reg[0] = Temp; - } - for (i=48; i<64; i++) - { - MD5Step(MD5_F4, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(7*(i & 0xf)) & 0xf], - MD5Table[i], LShiftVal[(0x3 << 2)+(i & 0x3)]); - - // one-word right shift - Temp = Reg[3]; - Reg[3] = Reg[2]; - Reg[2] = Reg[1]; - Reg[1] = Reg[0]; - Reg[0] = Temp; - } - - - // (temporary)output - for (i=0; i<4; i++) - Buf[i] += Reg[i]; - -} - - - -/* ========================= SHA-1 implementation ========================== */ -// four base functions for SHA-1 -#define SHA1_F1(b, c, d) (((b) & (c)) | ((~b) & (d))) -#define SHA1_F2(b, c, d) ((b) ^ (c) ^ (d)) -#define SHA1_F3(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) - - -#define SHA1Step(f, a, b, c, d, e, w, k) \ - ( e += ( f(b, c, d) + w + k + CYCLIC_LEFT_SHIFT(a, 5)) & 0xffffffff, \ - b = CYCLIC_LEFT_SHIFT(b, 30) ) - -//Initiate SHA-1 Context satisfied in RFC 3174 -VOID SHAInit(SHA_CTX *pCtx) -{ - pCtx->Buf[0]=0x67452301; - pCtx->Buf[1]=0xefcdab89; - pCtx->Buf[2]=0x98badcfe; - pCtx->Buf[3]=0x10325476; - pCtx->Buf[4]=0xc3d2e1f0; - - pCtx->LenInBitCount[0]=0; - pCtx->LenInBitCount[1]=0; -} - -/* - * Function Description: - * Update SHA-1 Context, allow of an arrary of octets as the next - * portion of the message - * - * Arguments: - * pCtx Pointer to SHA-1 context - * pData Pointer to input data - * LenInBytes The length of input data (unit: byte) - * - * Return Value: - * error indicate more than pow(2,64) bits of data - * - * Note: - * Called after SHAInit or SHAUpdate(itself) - */ -UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes) -{ - UINT32 TfTimes; - UINT32 temp1,temp2; - unsigned int i; - UCHAR err=1; - - temp1 = pCtx->LenInBitCount[0]; - temp2 = pCtx->LenInBitCount[1]; - - pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3)); - if (pCtx->LenInBitCount[0] < temp1) - pCtx->LenInBitCount[1]++; //carry in - - - pCtx->LenInBitCount[1] = (UINT32) (pCtx->LenInBitCount[1] +(LenInBytes >> 29)); - if (pCtx->LenInBitCount[1] < temp2) - return (err); //check total length of original data - - - // mod 64 bytes - temp1 = (temp1 >> 3) & 0x3f; - - // process lacks of 64-byte data - if (temp1) - { - UCHAR *pAds = (UCHAR *) pCtx->Input + temp1; - - if ((temp1+LenInBytes) < 64) - { - NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes); - return (0); - } - - NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp1); - byteReverse((UCHAR *)pCtx->Input, 16); - - NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16); - SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input); - - pData += 64-temp1; - LenInBytes -= 64-temp1; - } // end of if (temp1) - - - TfTimes = (LenInBytes >> 6); - - for (i=TfTimes; i>0; i--) - { - NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64); - byteReverse((UCHAR *)pCtx->Input, 16); - - NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16); - SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input); - pData += 64; - LenInBytes -= 64; - } // end of for - - // buffering lacks of 64-byte data - if(LenInBytes) - NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes); - - return (0); - -} - -// Append padding bits and length of original message in the tail -// The message digest has to be completed in the end -VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20]) -{ - UCHAR Remainder; - UCHAR PadLenInBytes; - UCHAR *pAppend=0; - unsigned int i; - - Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f); - - pAppend = (UCHAR *)pCtx->Input + Remainder; - - PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder); - - // padding bits without crossing block(64-byte based) boundary - if (Remainder < 56) - { - *pAppend = 0x80; - PadLenInBytes --; - - NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes); - - // add data-length field, from high to low - for (i=0; i<4; i++) - { - pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff); - pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff); - } - - byteReverse((UCHAR *)pCtx->Input, 16); - NdisZeroMemory((UCHAR *)pCtx->Input + 64, 14); - SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input); - } // end of if - - // padding bits with crossing block(64-byte based) boundary - else - { - // the first block === - *pAppend = 0x80; - PadLenInBytes --; - - NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1)); - PadLenInBytes -= (64 - Remainder - 1); - - byteReverse((UCHAR *)pCtx->Input, 16); - NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16); - SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input); - - - // the second block === - NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes); - - // add data-length field - for (i=0; i<4; i++) - { - pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff); - pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff); - } - - byteReverse((UCHAR *)pCtx->Input, 16); - NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16); - SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input); - } // end of else - - - //Output, bytereverse - for (i=0; i<20; i++) - { - Digest [i] = (UCHAR)(pCtx->Buf[i>>2] >> 8*(3-(i & 0x3))); - } - - NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free -} - - -// The central algorithm of SHA-1, consists of four rounds and -// twenty steps per round -VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20]) -{ - UINT32 Reg[5],Temp; - unsigned int i; - UINT32 W[80]; - - static UINT32 SHA1Table[4] = { 0x5a827999, 0x6ed9eba1, - 0x8f1bbcdc, 0xca62c1d6 }; - - Reg[0]=Buf[0]; - Reg[1]=Buf[1]; - Reg[2]=Buf[2]; - Reg[3]=Buf[3]; - Reg[4]=Buf[4]; - - //the first octet of a word is stored in the 0th element, bytereverse - for(i = 0; i < 16; i++) - { - W[i] = (Mes[i] >> 24) & 0xff; - W[i] |= (Mes[i] >> 8 ) & 0xff00; - W[i] |= (Mes[i] << 8 ) & 0xff0000; - W[i] |= (Mes[i] << 24) & 0xff000000; - } - - - for (i = 0; i < 64; i++) - W[16+i] = CYCLIC_LEFT_SHIFT(W[i] ^ W[2+i] ^ W[8+i] ^ W[13+i], 1); - - - // 80 steps in SHA-1 algorithm - for (i=0; i<80; i++) - { - if (i<20) - SHA1Step(SHA1_F1, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], - W[i], SHA1Table[0]); - - else if (i>=20 && i<40) - SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], - W[i], SHA1Table[1]); - - else if (i>=40 && i<60) - SHA1Step(SHA1_F3, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], - W[i], SHA1Table[2]); - - else - SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4], - W[i], SHA1Table[3]); - - - // one-word right shift - Temp = Reg[4]; - Reg[4] = Reg[3]; - Reg[3] = Reg[2]; - Reg[2] = Reg[1]; - Reg[1] = Reg[0]; - Reg[0] = Temp; - - } // end of for-loop - - - // (temporary)output - for (i=0; i<5; i++) - Buf[i] += Reg[i]; - -} - - -/* ========================= AES En/Decryption ========================== */ - -/* forward S-box */ -static uint32 FSb[256] = -{ - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, - 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, - 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, - 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, - 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, - 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, - 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, - 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, - 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, - 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, - 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, - 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, - 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, - 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, - 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, - 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, - 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 -}; - -/* forward table */ -#define FT \ -\ - V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \ - V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \ - V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \ - V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \ - V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \ - V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \ - V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \ - V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \ - V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \ - V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \ - V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \ - V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \ - V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \ - V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \ - V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \ - V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \ - V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \ - V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \ - V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \ - V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \ - V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \ - V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \ - V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \ - V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \ - V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \ - V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \ - V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \ - V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \ - V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \ - V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \ - V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \ - V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \ - V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \ - V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \ - V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \ - V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \ - V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \ - V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \ - V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \ - V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \ - V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \ - V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \ - V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \ - V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \ - V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \ - V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \ - V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \ - V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \ - V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \ - V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \ - V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \ - V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \ - V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \ - V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \ - V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \ - V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \ - V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \ - V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \ - V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \ - V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \ - V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \ - V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \ - V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \ - V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A) - -#define V(a,b,c,d) 0x##a##b##c##d -static uint32 FT0[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static uint32 FT1[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static uint32 FT2[256] = { FT }; -#undef V - -#define V(a,b,c,d) 0x##b##c##d##a -static uint32 FT3[256] = { FT }; -#undef V - -#undef FT - -/* reverse S-box */ - -static uint32 RSb[256] = -{ - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, - 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, - 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, - 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, - 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, - 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, - 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, - 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, - 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, - 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, - 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, - 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, - 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, - 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, - 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, - 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D -}; - -/* reverse table */ - -#define RT \ -\ - V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \ - V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \ - V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \ - V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \ - V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \ - V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \ - V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \ - V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \ - V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \ - V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \ - V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \ - V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \ - V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \ - V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \ - V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \ - V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \ - V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \ - V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \ - V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \ - V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \ - V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \ - V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \ - V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \ - V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \ - V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \ - V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \ - V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \ - V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \ - V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \ - V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \ - V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \ - V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \ - V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \ - V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \ - V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \ - V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \ - V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \ - V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \ - V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \ - V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \ - V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \ - V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \ - V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \ - V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \ - V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \ - V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \ - V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \ - V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \ - V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \ - V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \ - V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \ - V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \ - V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \ - V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \ - V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \ - V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \ - V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \ - V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \ - V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \ - V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \ - V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \ - V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \ - V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \ - V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42) - -#define V(a,b,c,d) 0x##a##b##c##d -static uint32 RT0[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##d##a##b##c -static uint32 RT1[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##c##d##a##b -static uint32 RT2[256] = { RT }; -#undef V - -#define V(a,b,c,d) 0x##b##c##d##a -static uint32 RT3[256] = { RT }; -#undef V - -#undef RT - -/* round constants */ - -static uint32 RCON[10] = -{ - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000 -}; - -/* key schedule tables */ - -static int KT_init = 1; - -static uint32 KT0[256]; -static uint32 KT1[256]; -static uint32 KT2[256]; -static uint32 KT3[256]; - -/* platform-independant 32-bit integer manipulation macros */ - -#define GET_UINT32(n,b,i) \ -{ \ - (n) = ( (uint32) (b)[(i) ] << 24 ) \ - | ( (uint32) (b)[(i) + 1] << 16 ) \ - | ( (uint32) (b)[(i) + 2] << 8 ) \ - | ( (uint32) (b)[(i) + 3] ); \ -} - -#define PUT_UINT32(n,b,i) \ -{ \ - (b)[(i) ] = (uint8) ( (n) >> 24 ); \ - (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ - (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ - (b)[(i) + 3] = (uint8) ( (n) ); \ -} - -/* AES key scheduling routine */ - -int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits ) -{ - int i; - uint32 *RK, *SK; - - switch( nbits ) - { - case 128: ctx->nr = 10; break; - case 192: ctx->nr = 12; break; - case 256: ctx->nr = 14; break; - default : return( 1 ); - } - - RK = ctx->erk; - - for( i = 0; i < (nbits >> 5); i++ ) - { - GET_UINT32( RK[i], key, i * 4 ); - } - - /* setup encryption round keys */ - - switch( nbits ) - { - case 128: - - for( i = 0; i < 10; i++, RK += 4 ) - { - RK[4] = RK[0] ^ RCON[i] ^ - ( FSb[ (uint8) ( RK[3] >> 16 ) ] << 24 ) ^ - ( FSb[ (uint8) ( RK[3] >> 8 ) ] << 16 ) ^ - ( FSb[ (uint8) ( RK[3] ) ] << 8 ) ^ - ( FSb[ (uint8) ( RK[3] >> 24 ) ] ); - - RK[5] = RK[1] ^ RK[4]; - RK[6] = RK[2] ^ RK[5]; - RK[7] = RK[3] ^ RK[6]; - } - break; - - case 192: - - for( i = 0; i < 8; i++, RK += 6 ) - { - RK[6] = RK[0] ^ RCON[i] ^ - ( FSb[ (uint8) ( RK[5] >> 16 ) ] << 24 ) ^ - ( FSb[ (uint8) ( RK[5] >> 8 ) ] << 16 ) ^ - ( FSb[ (uint8) ( RK[5] ) ] << 8 ) ^ - ( FSb[ (uint8) ( RK[5] >> 24 ) ] ); - - RK[7] = RK[1] ^ RK[6]; - RK[8] = RK[2] ^ RK[7]; - RK[9] = RK[3] ^ RK[8]; - RK[10] = RK[4] ^ RK[9]; - RK[11] = RK[5] ^ RK[10]; - } - break; - - case 256: - - for( i = 0; i < 7; i++, RK += 8 ) - { - RK[8] = RK[0] ^ RCON[i] ^ - ( FSb[ (uint8) ( RK[7] >> 16 ) ] << 24 ) ^ - ( FSb[ (uint8) ( RK[7] >> 8 ) ] << 16 ) ^ - ( FSb[ (uint8) ( RK[7] ) ] << 8 ) ^ - ( FSb[ (uint8) ( RK[7] >> 24 ) ] ); - - RK[9] = RK[1] ^ RK[8]; - RK[10] = RK[2] ^ RK[9]; - RK[11] = RK[3] ^ RK[10]; - - RK[12] = RK[4] ^ - ( FSb[ (uint8) ( RK[11] >> 24 ) ] << 24 ) ^ - ( FSb[ (uint8) ( RK[11] >> 16 ) ] << 16 ) ^ - ( FSb[ (uint8) ( RK[11] >> 8 ) ] << 8 ) ^ - ( FSb[ (uint8) ( RK[11] ) ] ); - - RK[13] = RK[5] ^ RK[12]; - RK[14] = RK[6] ^ RK[13]; - RK[15] = RK[7] ^ RK[14]; - } - break; - } - - /* setup decryption round keys */ - - if( KT_init ) - { - for( i = 0; i < 256; i++ ) - { - KT0[i] = RT0[ FSb[i] ]; - KT1[i] = RT1[ FSb[i] ]; - KT2[i] = RT2[ FSb[i] ]; - KT3[i] = RT3[ FSb[i] ]; - } - - KT_init = 0; - } - - SK = ctx->drk; - - *SK++ = *RK++; - *SK++ = *RK++; - *SK++ = *RK++; - *SK++ = *RK++; - - for( i = 1; i < ctx->nr; i++ ) - { - RK -= 8; - - *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ - KT1[ (uint8) ( *RK >> 16 ) ] ^ - KT2[ (uint8) ( *RK >> 8 ) ] ^ - KT3[ (uint8) ( *RK ) ]; RK++; - - *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ - KT1[ (uint8) ( *RK >> 16 ) ] ^ - KT2[ (uint8) ( *RK >> 8 ) ] ^ - KT3[ (uint8) ( *RK ) ]; RK++; - - *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ - KT1[ (uint8) ( *RK >> 16 ) ] ^ - KT2[ (uint8) ( *RK >> 8 ) ] ^ - KT3[ (uint8) ( *RK ) ]; RK++; - - *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^ - KT1[ (uint8) ( *RK >> 16 ) ] ^ - KT2[ (uint8) ( *RK >> 8 ) ] ^ - KT3[ (uint8) ( *RK ) ]; RK++; - } - - RK -= 8; - - *SK++ = *RK++; - *SK++ = *RK++; - *SK++ = *RK++; - *SK++ = *RK++; - - return( 0 ); -} - -/* AES 128-bit block encryption routine */ - -void rtmp_aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16] ) -{ - uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - - RK = ctx->erk; - GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; - GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; - GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; - GET_UINT32( X3, input, 12 ); X3 ^= RK[3]; - -#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ -{ \ - RK += 4; \ - \ - X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \ - FT1[ (uint8) ( Y1 >> 16 ) ] ^ \ - FT2[ (uint8) ( Y2 >> 8 ) ] ^ \ - FT3[ (uint8) ( Y3 ) ]; \ - \ - X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \ - FT1[ (uint8) ( Y2 >> 16 ) ] ^ \ - FT2[ (uint8) ( Y3 >> 8 ) ] ^ \ - FT3[ (uint8) ( Y0 ) ]; \ - \ - X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \ - FT1[ (uint8) ( Y3 >> 16 ) ] ^ \ - FT2[ (uint8) ( Y0 >> 8 ) ] ^ \ - FT3[ (uint8) ( Y1 ) ]; \ - \ - X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \ - FT1[ (uint8) ( Y0 >> 16 ) ] ^ \ - FT2[ (uint8) ( Y1 >> 8 ) ] ^ \ - FT3[ (uint8) ( Y2 ) ]; \ -} - - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ - AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ - AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ - AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ - AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ - - if( ctx->nr > 10 ) - { - AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ - } - - if( ctx->nr > 12 ) - { - AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ - AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ - } - - /* last round */ - - RK += 4; - - X0 = RK[0] ^ ( FSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ - ( FSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ - ( FSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ - ( FSb[ (uint8) ( Y3 ) ] ); - - X1 = RK[1] ^ ( FSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ - ( FSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ - ( FSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ - ( FSb[ (uint8) ( Y0 ) ] ); - - X2 = RK[2] ^ ( FSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ - ( FSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ - ( FSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ - ( FSb[ (uint8) ( Y1 ) ] ); - - X3 = RK[3] ^ ( FSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ - ( FSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ - ( FSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ - ( FSb[ (uint8) ( Y2 ) ] ); - - PUT_UINT32( X0, output, 0 ); - PUT_UINT32( X1, output, 4 ); - PUT_UINT32( X2, output, 8 ); - PUT_UINT32( X3, output, 12 ); -} - -/* AES 128-bit block decryption routine */ - -void rtmp_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ) -{ - uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; - - RK = ctx->drk; - - GET_UINT32( X0, input, 0 ); X0 ^= RK[0]; - GET_UINT32( X1, input, 4 ); X1 ^= RK[1]; - GET_UINT32( X2, input, 8 ); X2 ^= RK[2]; - GET_UINT32( X3, input, 12 ); X3 ^= RK[3]; - -#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ -{ \ - RK += 4; \ - \ - X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \ - RT1[ (uint8) ( Y3 >> 16 ) ] ^ \ - RT2[ (uint8) ( Y2 >> 8 ) ] ^ \ - RT3[ (uint8) ( Y1 ) ]; \ - \ - X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \ - RT1[ (uint8) ( Y0 >> 16 ) ] ^ \ - RT2[ (uint8) ( Y3 >> 8 ) ] ^ \ - RT3[ (uint8) ( Y2 ) ]; \ - \ - X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \ - RT1[ (uint8) ( Y1 >> 16 ) ] ^ \ - RT2[ (uint8) ( Y0 >> 8 ) ] ^ \ - RT3[ (uint8) ( Y3 ) ]; \ - \ - X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \ - RT1[ (uint8) ( Y2 >> 16 ) ] ^ \ - RT2[ (uint8) ( Y1 >> 8 ) ] ^ \ - RT3[ (uint8) ( Y0 ) ]; \ -} - - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */ - AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */ - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */ - AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */ - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */ - AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */ - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */ - AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */ - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */ - - if( ctx->nr > 10 ) - { - AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */ - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */ - } - - if( ctx->nr > 12 ) - { - AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */ - AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */ - } - - /* last round */ - - RK += 4; - - X0 = RK[0] ^ ( RSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^ - ( RSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^ - ( RSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^ - ( RSb[ (uint8) ( Y1 ) ] ); - - X1 = RK[1] ^ ( RSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^ - ( RSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^ - ( RSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^ - ( RSb[ (uint8) ( Y2 ) ] ); - - X2 = RK[2] ^ ( RSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^ - ( RSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^ - ( RSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^ - ( RSb[ (uint8) ( Y3 ) ] ); - - X3 = RK[3] ^ ( RSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^ - ( RSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^ - ( RSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^ - ( RSb[ (uint8) ( Y0 ) ] ); - - PUT_UINT32( X0, output, 0 ); - PUT_UINT32( X1, output, 4 ); - PUT_UINT32( X2, output, 8 ); - PUT_UINT32( X3, output, 12 ); -} - -/* - ======================================================================== - - Routine Description: - SHA1 function - - Arguments: - - Return Value: - - Note: - - ======================================================================== -*/ -VOID HMAC_SHA1( - IN UCHAR *text, - IN UINT text_len, - IN UCHAR *key, - IN UINT key_len, - IN UCHAR *digest) -{ - SHA_CTX context; - UCHAR k_ipad[65]; /* inner padding - key XORd with ipad */ - UCHAR k_opad[65]; /* outer padding - key XORd with opad */ - INT i; - - // if key is longer than 64 bytes reset it to key=SHA1(key) - if (key_len > 64) - { - SHA_CTX tctx; - SHAInit(&tctx); - SHAUpdate(&tctx, key, key_len); - SHAFinal(&tctx, key); - key_len = 20; - } - NdisZeroMemory(k_ipad, sizeof(k_ipad)); - NdisZeroMemory(k_opad, sizeof(k_opad)); - NdisMoveMemory(k_ipad, key, key_len); - NdisMoveMemory(k_opad, key, key_len); - - // XOR key with ipad and opad values - for (i = 0; i < 64; i++) - { - k_ipad[i] ^= 0x36; - k_opad[i] ^= 0x5c; - } - - // perform inner SHA1 - SHAInit(&context); /* init context for 1st pass */ - SHAUpdate(&context, k_ipad, 64); /* start with inner pad */ - SHAUpdate(&context, text, text_len); /* then text of datagram */ - SHAFinal(&context, digest); /* finish up 1st pass */ - - //perform outer SHA1 - SHAInit(&context); /* init context for 2nd pass */ - SHAUpdate(&context, k_opad, 64); /* start with outer pad */ - SHAUpdate(&context, digest, 20); /* then results of 1st hash */ - SHAFinal(&context, digest); /* finish up 2nd pass */ - -} - -/* -* F(P, S, c, i) = U1 xor U2 xor ... Uc -* U1 = PRF(P, S || Int(i)) -* U2 = PRF(P, U1) -* Uc = PRF(P, Uc-1) -*/ - -void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output) -{ - unsigned char digest[36], digest1[SHA_DIGEST_LEN]; - int i, j; - - /* U1 = PRF(P, S || int(i)) */ - memcpy(digest, ssid, ssidlength); - digest[ssidlength] = (unsigned char)((count>>24) & 0xff); - digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff); - digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff); - digest[ssidlength+3] = (unsigned char)(count & 0xff); - HMAC_SHA1(digest, ssidlength+4, (unsigned char*) password, (int) strlen(password), digest1); // for WPA update - - /* output = U1 */ - memcpy(output, digest1, SHA_DIGEST_LEN); - - for (i = 1; i < iterations; i++) - { - /* Un = PRF(P, Un-1) */ - HMAC_SHA1(digest1, SHA_DIGEST_LEN, (unsigned char*) password, (int) strlen(password), digest); // for WPA update - memcpy(digest1, digest, SHA_DIGEST_LEN); - - /* output = output xor Un */ - for (j = 0; j < SHA_DIGEST_LEN; j++) - { - output[j] ^= digest[j]; - } - } -} -/* -* password - ascii string up to 63 characters in length -* ssid - octet string up to 32 octets -* ssidlength - length of ssid in octets -* output must be 40 octets in length and outputs 256 bits of key -*/ -int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output) -{ - if ((strlen(password) > 63) || (ssidlength > 32)) - return 0; - - F(password, ssid, ssidlength, 4096, 1, output); - F(password, ssid, ssidlength, 4096, 2, &output[SHA_DIGEST_LEN]); - return 1; -} - - Index: b/drivers/staging/rt2860/common/mlme.c =================================================================== --- a/drivers/staging/rt2860/common/mlme.c +++ b/drivers/staging/rt2860/common/mlme.c @@ -127,46 +127,54 @@ UCHAR RateSwitchTable11G[] = { UCHAR RateSwitchTable11N1S[] = { // 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) - 0x09, 0x00, 0, 0, 0, // Initial used item after association - 0x00, 0x21, 0, 30, 101, - 0x01, 0x21, 1, 20, 50, - 0x02, 0x21, 2, 20, 50, - 0x03, 0x21, 3, 15, 50, - 0x04, 0x21, 4, 15, 30, - 0x05, 0x21, 5, 10, 25, - 0x06, 0x21, 6, 8, 14, - 0x07, 0x21, 7, 8, 14, - 0x08, 0x23, 7, 8, 14, + 0x0c, 0x0a, 0, 0, 0, // Initial used item after association + 0x00, 0x00, 0, 40, 101, + 0x01, 0x00, 1, 40, 50, + 0x02, 0x00, 2, 25, 45, + 0x03, 0x21, 0, 20, 35, + 0x04, 0x21, 1, 20, 35, + 0x05, 0x21, 2, 20, 35, + 0x06, 0x21, 3, 15, 35, + 0x07, 0x21, 4, 15, 30, + 0x08, 0x21, 5, 10, 25, + 0x09, 0x21, 6, 8, 14, + 0x0a, 0x21, 7, 8, 14, + 0x0b, 0x23, 7, 8, 14, }; UCHAR RateSwitchTable11N2S[] = { // 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) - 0x0a, 0x00, 0, 0, 0, // Initial used item after association - 0x00, 0x21, 0, 30, 101, - 0x01, 0x21, 1, 20, 50, - 0x02, 0x21, 2, 20, 50, - 0x03, 0x21, 3, 15, 50, - 0x04, 0x21, 4, 15, 30, - 0x05, 0x20, 12, 15, 30, - 0x06, 0x20, 13, 8, 20, - 0x07, 0x20, 14, 8, 20, - 0x08, 0x20, 15, 8, 25, - 0x09, 0x22, 15, 8, 25, + 0x0e, 0x0c, 0, 0, 0, // Initial used item after association + 0x00, 0x00, 0, 40, 101, + 0x01, 0x00, 1, 40, 50, + 0x02, 0x00, 2, 25, 45, + 0x03, 0x21, 0, 20, 35, + 0x04, 0x21, 1, 20, 35, + 0x05, 0x21, 2, 20, 35, + 0x06, 0x21, 3, 15, 35, + 0x07, 0x21, 4, 15, 30, + 0x08, 0x20, 11, 15, 30, + 0x09, 0x20, 12, 15, 30, + 0x0a, 0x20, 13, 8, 20, + 0x0b, 0x20, 14, 8, 20, + 0x0c, 0x20, 15, 8, 25, + 0x0d, 0x22, 15, 8, 15, }; UCHAR RateSwitchTable11N3S[] = { // 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) - 0x0a, 0x00, 0, 0, 0, // Initial used item after association + 0x0b, 0x00, 0, 0, 0, // 0x0a, 0x00, 0, 0, 0, // Initial used item after association 0x00, 0x21, 0, 30, 101, 0x01, 0x21, 1, 20, 50, 0x02, 0x21, 2, 20, 50, 0x03, 0x21, 3, 15, 50, 0x04, 0x21, 4, 15, 30, - 0x05, 0x20, 12, 15, 30, - 0x06, 0x20, 13, 8, 20, - 0x07, 0x20, 14, 8, 20, - 0x08, 0x20, 15, 8, 25, - 0x09, 0x22, 15, 8, 25, + 0x05, 0x20, 11, 15, 30, // Required by System-Alan @ 20080812 + 0x06, 0x20, 12, 15, 30, // 0x05, 0x20, 12, 15, 30, + 0x07, 0x20, 13, 8, 20, // 0x06, 0x20, 13, 8, 20, + 0x08, 0x20, 14, 8, 20, // 0x07, 0x20, 14, 8, 20, + 0x09, 0x20, 15, 8, 25, // 0x08, 0x20, 15, 8, 25, + 0x0a, 0x22, 15, 8, 25, // 0x09, 0x22, 15, 8, 25, }; UCHAR RateSwitchTable11N2SForABand[] = { @@ -203,35 +211,38 @@ UCHAR RateSwitchTable11N3SForABand[] = { UCHAR RateSwitchTable11BGN1S[] = { // 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) - 0x0d, 0x00, 0, 0, 0, // Initial used item after association + 0x0c, 0x0a, 0, 0, 0, // Initial used item after association 0x00, 0x00, 0, 40, 101, 0x01, 0x00, 1, 40, 50, - 0x02, 0x00, 2, 35, 45, - 0x03, 0x00, 3, 20, 45, - 0x04, 0x21, 0, 30,101, //50 - 0x05, 0x21, 1, 20, 50, - 0x06, 0x21, 2, 20, 50, - 0x07, 0x21, 3, 15, 50, - 0x08, 0x21, 4, 15, 30, - 0x09, 0x21, 5, 10, 25, - 0x0a, 0x21, 6, 8, 14, - 0x0b, 0x21, 7, 8, 14, - 0x0c, 0x23, 7, 8, 14, + 0x02, 0x00, 2, 25, 45, + 0x03, 0x21, 0, 20, 35, + 0x04, 0x21, 1, 20, 35, + 0x05, 0x21, 2, 20, 35, + 0x06, 0x21, 3, 15, 35, + 0x07, 0x21, 4, 15, 30, + 0x08, 0x21, 5, 10, 25, + 0x09, 0x21, 6, 8, 14, + 0x0a, 0x21, 7, 8, 14, + 0x0b, 0x23, 7, 8, 14, }; UCHAR RateSwitchTable11BGN2S[] = { // 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) - 0x0a, 0x00, 0, 0, 0, // Initial used item after association - 0x00, 0x21, 0, 30,101, //50 - 0x01, 0x21, 1, 20, 50, - 0x02, 0x21, 2, 20, 50, - 0x03, 0x21, 3, 15, 50, - 0x04, 0x21, 4, 15, 30, - 0x05, 0x20, 12, 15, 30, - 0x06, 0x20, 13, 8, 20, - 0x07, 0x20, 14, 8, 20, - 0x08, 0x20, 15, 8, 25, - 0x09, 0x22, 15, 8, 25, + 0x0e, 0x0c, 0, 0, 0, // Initial used item after association + 0x00, 0x00, 0, 40, 101, + 0x01, 0x00, 1, 40, 50, + 0x02, 0x00, 2, 25, 45, + 0x03, 0x21, 0, 20, 35, + 0x04, 0x21, 1, 20, 35, + 0x05, 0x21, 2, 20, 35, + 0x06, 0x21, 3, 15, 35, + 0x07, 0x21, 4, 15, 30, + 0x08, 0x20, 11, 15, 30, + 0x09, 0x20, 12, 15, 30, + 0x0a, 0x20, 13, 8, 20, + 0x0b, 0x20, 14, 8, 20, + 0x0c, 0x20, 15, 8, 25, + 0x0d, 0x22, 15, 8, 15, }; UCHAR RateSwitchTable11BGN3S[] = { // 3*3 @@ -282,27 +293,6 @@ UCHAR RateSwitchTable11BGN3SForABand[] = 0x0b, 0x22, 23, 8, 25, }; -PUCHAR ReasonString[] = { - /* 0 */ "Reserved", - /* 1 */ "Unspecified Reason", - /* 2 */ "Previous Auth no longer valid", - /* 3 */ "STA is leaving / has left", - /* 4 */ "DIS-ASSOC due to inactivity", - /* 5 */ "AP unable to hanle all associations", - /* 6 */ "class 2 error", - /* 7 */ "class 3 error", - /* 8 */ "STA is leaving / has left", - /* 9 */ "require auth before assoc/re-assoc", - /* 10 */ "Reserved", - /* 11 */ "Reserved", - /* 12 */ "Reserved", - /* 13 */ "invalid IE", - /* 14 */ "MIC error", - /* 15 */ "4-way handshake timeout", - /* 16 */ "2-way (group key) handshake timeout", - /* 17 */ "4-way handshake IE diff among AssosReq/Rsp/Beacon", - /* 18 */ -}; extern UCHAR OfdmRateToRxwiMCS[]; // since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate. @@ -311,7 +301,6 @@ ULONG BasicRateMask[12] = {0xfffff001 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */, 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */}; -UCHAR MULTICAST_ADDR[MAC_ADDR_LEN] = {0x1, 0x00, 0x00, 0x00, 0x00, 0x00}; UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -336,7 +325,6 @@ UCHAR TimIe = IE_TIM; UCHAR WpaIe = IE_WPA; UCHAR Wpa2Ie = IE_WPA2; UCHAR IbssIe = IE_IBSS_PARM; -UCHAR Ccx2Ie = IE_CCX_V2; extern UCHAR WPA_OUI[]; @@ -345,107 +333,6 @@ UCHAR SES_OUI[] = {0x00, 0x90, 0x4c}; UCHAR ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; -// Reset the RFIC setting to new series -RTMP_RF_REGS RF2850RegTable[] = { -// ch R1 R2 R3(TX0~4=0) R4 - {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b}, - {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f}, - {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b}, - {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f}, - {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b}, - {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f}, - {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b}, - {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f}, - {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b}, - {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f}, - {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b}, - {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f}, - {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b}, - {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193}, - - // 802.11 UNI / HyperLan 2 - {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3}, - {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193}, - {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183}, - {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3}, - {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b}, - {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b}, - {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193}, - {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3}, - {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b}, - {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183}, - {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193}, - {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5. - - // 802.11 HyperLan 2 - {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783}, - - // 2008.04.30 modified - // The system team has AN to improve the EVM value - // for channel 102 to 108 for the RT2850/RT2750 dual band solution. - {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793}, - {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3}, - {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193}, - - {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183}, - {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b}, - {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3}, - {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193}, - {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183}, - {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193}, - {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927 - {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3}, - {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b}, - {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193}, - {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b}, - {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183}, - - // 802.11 UNII - {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7}, - {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187}, - {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f}, - {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f}, - {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7}, - {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187}, - {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197}, - - // Japan - {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b}, - {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13}, - {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b}, - {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23}, - {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13}, - {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b}, - {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23}, - - // still lack of MMAC(Japan) ch 34,38,42,46 -}; -UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS)); - -FREQUENCY_ITEM FreqItems3020[] = -{ - /**************************************************/ - // ISM : 2.4 to 2.483 GHz // - /**************************************************/ - // 11g - /**************************************************/ - //-CH---N-------R---K----------- - {1, 241, 2, 2}, - {2, 241, 2, 7}, - {3, 242, 2, 2}, - {4, 242, 2, 7}, - {5, 243, 2, 2}, - {6, 243, 2, 7}, - {7, 244, 2, 2}, - {8, 244, 2, 7}, - {9, 245, 2, 2}, - {10, 245, 2, 7}, - {11, 246, 2, 2}, - {12, 246, 2, 7}, - {13, 247, 2, 2}, - {14, 248, 2, 4}, -}; -UCHAR NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM)); /* ========================================================================== @@ -484,14 +371,19 @@ NDIS_STATUS MlmeInit( AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc); AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc); SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc); - WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc); - AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc); + + + // Since we are using switch/case to implement it, the init is different from the above // state machine init MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL); } + + WpaStateMachineInit(pAd, &pAd->Mlme.WpaMachine, pAd->Mlme.WpaFunc); + + ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc); // Init mlme periodic timer @@ -503,16 +395,24 @@ NDIS_STATUS MlmeInit( // software-based RX Antenna diversity RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE); -#ifdef RT2860 { +#ifdef RTMP_PCI_SUPPORT if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) { // only PCIe cards need these two timers RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer, GET_TIMER_FUNCTION(PsPollWakeExec), pAd, FALSE); RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE); } +#endif // RTMP_PCI_SUPPORT // + + RTMPInitTimer(pAd, &pAd->Mlme.LinkDownTimer, GET_TIMER_FUNCTION(LinkDownExec), pAd, FALSE); + +#ifdef RTMP_MAC_USB + RTMPInitTimer(pAd, &pAd->Mlme.AutoWakeupTimer, GET_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout), pAd, FALSE); + pAd->Mlme.AutoWakeupTimerRunning = FALSE; +#endif // RTMP_MAC_USB // } -#endif + } while (FALSE); DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n")); @@ -567,7 +467,7 @@ VOID MlmeHandler( //From message type, determine which state machine I should drive if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) { -#ifdef RT2870 +#ifdef RTMP_MAC_USB if (Elem->MsgType == MT2_RESET_CONF) { DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n")); @@ -576,7 +476,7 @@ VOID MlmeHandler( Elem->MsgLen = 0; continue; } -#endif // RT2870 // +#endif // RTMP_MAC_USB // // if dequeue success switch (Elem->Machine) @@ -600,14 +500,16 @@ VOID MlmeHandler( case WPA_PSK_STATE_MACHINE: StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem); break; - case AIRONET_STATE_MACHINE: - StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem); - break; + + + case ACTION_STATE_MACHINE: StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem); break; - + case WPA_STATE_MACHINE: + StateMachinePerformAction(pAd, &pAd->Mlme.WpaMachine, Elem); + break; default: @@ -647,9 +549,6 @@ VOID MlmeHalt( IN PRTMP_ADAPTER pAd) { BOOLEAN Cancelled; -#ifdef RT3070 - UINT32 TxPinCfg = 0x00050F0F; -#endif // RT3070 // DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n")); @@ -667,13 +566,21 @@ VOID MlmeHalt( RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled); RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled); RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); -#ifdef RT2860 + + +#ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) { RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled); } -#endif +#endif // RTMP_MAC_PCI // + + RTMPCancelTimer(&pAd->Mlme.LinkDownTimer, &Cancelled); + +#ifdef RTMP_MAC_USB + RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Cancelled); +#endif // RTMP_MAC_USB // } RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled); @@ -683,10 +590,12 @@ VOID MlmeHalt( if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) { + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + // Set LED RTMPSetLED(pAd, LED_HALT); RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it. -#ifdef RT2870 +#ifdef RTMP_MAC_USB { LED_CFG_STRUC LedCfg; RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word); @@ -696,17 +605,10 @@ VOID MlmeHalt( LedCfg.field.YLedMode = 0; RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word); } -#endif // RT2870 // -#ifdef RT3070 - // - // Turn off LNA_PE - // - if (IS_RT3070(pAd) || IS_RT3071(pAd)) - { - TxPinCfg &= 0xFFFFF0F0; - RTUSBWriteMACRegister(pAd, TX_PIN_CFG, TxPinCfg); - } -#endif // RT3070 // +#endif // RTMP_MAC_USB // + + if (pChipOps->AsicHaltAction) + pChipOps->AsicHaltAction(pAd); } RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled @@ -730,6 +632,8 @@ VOID MlmeResetRalinkCounters( pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0; pAd->RalinkCounters.OneSecTxRetryOkCount = 0; pAd->RalinkCounters.OneSecRxOkDataCnt = 0; + pAd->RalinkCounters.OneSecReceivedByteCount = 0; + pAd->RalinkCounters.OneSecTransmittedByteCount = 0; // TODO: for debug only. to be removed pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0; @@ -748,8 +652,6 @@ VOID MlmeResetRalinkCounters( return; } -unsigned long rx_AMSDU; -unsigned long rx_Total; /* ========================================================================== @@ -777,33 +679,19 @@ VOID MlmePeriodicExec( ULONG TxTotalCnt; PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext; -#ifdef RT2860 - //Baron 2008/07/10 - //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus)); - //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0. - //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1. - if(pAd->StaCfg.WepStatus<2) - { - pAd->StaCfg.WpaSupplicantUP = 0; - } - else - { - pAd->StaCfg.WpaSupplicantUP = 1; - } - +#ifdef RTMP_MAC_PCI { // If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second. // Move code to here, because following code will return when radio is off - if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) && - (pAd->StaCfg.bHardwareRadio == TRUE) && - (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) && + if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) && (pAd->StaCfg.bHardwareRadio == TRUE) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) + /*&&(pAd->bPCIclkOff == FALSE)*/) { UINT32 data = 0; // Read GPIO pin2 as Hardware controlled radio state - RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data); + RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data); if (data & 0x04) { pAd->StaCfg.bHwRadio = TRUE; @@ -830,7 +718,7 @@ VOID MlmePeriodicExec( } } } -#endif /* RT2860 */ +#endif // RTMP_MAC_PCI // // Do nothing if the driver is starting halt state. // This might happen when timer already been fired before cancel timer with mlmehalt @@ -840,46 +728,7 @@ VOID MlmePeriodicExec( fRTMP_ADAPTER_RESET_IN_PROGRESS)))) return; -#ifdef RT2860 - { - if ((pAd->RalinkCounters.LastReceivedByteCount == pAd->RalinkCounters.ReceivedByteCount) && (pAd->StaCfg.bRadio == TRUE)) - { - // If ReceiveByteCount doesn't change, increase SameRxByteCount by 1. - pAd->SameRxByteCount++; - } - else - pAd->SameRxByteCount = 0; - - // If after BBP, still not work...need to check to reset PBF&MAC. - if (pAd->SameRxByteCount == 702) - { - pAd->SameRxByteCount = 0; - AsicResetPBF(pAd); - AsicResetMAC(pAd); - } - - // If SameRxByteCount keeps happens for 2 second in infra mode, or for 60 seconds in idle mode. - if (((INFRA_ON(pAd)) && (pAd->SameRxByteCount > 20)) || ((IDLE_ON(pAd)) && (pAd->SameRxByteCount > 600))) - { - if ((pAd->StaCfg.bRadio == TRUE) && (pAd->SameRxByteCount < 700)) - { - DBGPRINT(RT_DEBUG_TRACE, ("---> SameRxByteCount = %lu !!!!!!!!!!!!!!! \n", pAd->SameRxByteCount)); - pAd->SameRxByteCount = 700; - AsicResetBBP(pAd); - } - } - - // Update lastReceiveByteCount. - pAd->RalinkCounters.LastReceivedByteCount = pAd->RalinkCounters.ReceivedByteCount; - - if ((pAd->CheckDmaBusyCount > 3) && (IDLE_ON(pAd))) - { - pAd->CheckDmaBusyCount = 0; - AsicResetFromDMABusy(pAd); - } - } -#endif /* RT2860 */ - RT28XX_MLME_PRE_SANITY_CHECK(pAd); + RTMP_MLME_PRE_SANITY_CHECK(pAd); { // Do nothing if monitor mode is on @@ -911,10 +760,11 @@ VOID MlmePeriodicExec( // RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3); pAd->Mlme.PeriodicRound ++; -#ifdef RT3070 +#ifdef RTMP_MAC_USB // execute every 100ms, update the Tx FIFO Cnt for update Tx Rate. NICUpdateFifoStaCounters(pAd); -#endif // RT3070 // +#endif // RTMP_MAC_USB // + // execute every 500ms if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/) { @@ -932,13 +782,10 @@ VOID MlmePeriodicExec( { pAd->Mlme.OneSecPeriodicRound ++; - if (rx_Total) - { - // reset counters - rx_AMSDU = 0; - rx_Total = 0; - } + + + //ORIBATimerTimeout(pAd); // Media status changed, report to NDIS if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE)) @@ -963,14 +810,23 @@ VOID MlmePeriodicExec( // the dynamic tuning mechanism below are based on most up-to-date information NICUpdateRawCounters(pAd); -#ifdef RT2870 - RT2870_WatchDog(pAd); -#endif // RT2870 // +#ifdef RTMP_MAC_USB + RTUSBWatchDog(pAd); +#endif // RTMP_MAC_USB // // Need statistics after read counter. So put after NICUpdateRawCounters ORIBATimerTimeout(pAd); + // if MGMT RING is full more than twice within 1 second, we consider there's + // a hardware problem stucking the TX path. In this case, try a hardware reset + // to recover the system + // if (pAd->RalinkCounters.MgmtRingFullCount >= 2) + // RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR); + // else + // pAd->RalinkCounters.MgmtRingFullCount = 0; + // The time period for checking antenna is according to traffic + { if (pAd->Mlme.bEnableAutoAntennaCheck) { TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + @@ -993,15 +849,16 @@ VOID MlmePeriodicExec( } } } + } STAMlmePeriodicExec(pAd); MlmeResetRalinkCounters(pAd); { -#ifdef RT2860 +#ifdef RTMP_MAC_PCI if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE)) -#endif +#endif // RTMP_MAC_PCI // { // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock // and sending CTS-to-self over and over. @@ -1024,112 +881,386 @@ VOID MlmePeriodicExec( } } - RT28XX_MLME_HANDLER(pAd); + RTMP_MLME_HANDLER(pAd); } + pAd->bUpdateBcnCntDone = FALSE; } -VOID STAMlmePeriodicExec( - PRTMP_ADAPTER pAd) + +/* + ========================================================================== + Validate SSID for connection try and rescan purpose + Valid SSID will have visible chars only. + The valid length is from 0 to 32. + IRQL = DISPATCH_LEVEL + ========================================================================== + */ +BOOLEAN MlmeValidateSSID( + IN PUCHAR pSsid, + IN UCHAR SsidLen) { -#ifdef RT2860 - ULONG TxTotalCnt; -#endif -#ifdef RT2870 - ULONG TxTotalCnt; - int i; -#endif + int index; - if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) + if (SsidLen > MAX_LEN_OF_SSID) + return (FALSE); + + // Check each character value + for (index = 0; index < SsidLen; index++) { - // WPA MIC error should block association attempt for 60 seconds - if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32)) - pAd->StaCfg.bBlockAssoc = FALSE; + if (pSsid[index] < 0x20) + return (FALSE); } -#ifdef RT2860 - //Baron 2008/07/10 - //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus)); - //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0. - //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1. - if(pAd->StaCfg.WepStatus<2) + // All checked + return (TRUE); +} + +VOID MlmeSelectTxRateTable( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR *ppTable, + IN PUCHAR pTableSize, + IN PUCHAR pInitTxRateIdx) +{ + do { - pAd->StaCfg.WpaSupplicantUP = 0; - } - else + // decide the rate table for tuning + if (pAd->CommonCfg.TxRateTableSize > 0) { - pAd->StaCfg.WpaSupplicantUP = 1; + *ppTable = RateSwitchTable; + *pTableSize = RateSwitchTable[0]; + *pInitTxRateIdx = RateSwitchTable[1]; + + break; } -#endif - if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent)) + if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd)) { - if (pAd->IndicateMediaState == NdisMediaStateConnected) + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && + (pEntry->HTCapability.MCSSet[0] == 0xff) && + ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) + {// 11N 1S Adhoc + *ppTable = RateSwitchTable11N1S; + *pTableSize = RateSwitchTable11N1S[0]; + *pInitTxRateIdx = RateSwitchTable11N1S[1]; + + } + else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && + (pEntry->HTCapability.MCSSet[0] == 0xff) && + (pEntry->HTCapability.MCSSet[1] == 0xff) && + (pAd->Antenna.field.TxPath == 2)) + {// 11N 2S Adhoc + if (pAd->LatchRfRegs.Channel <= 14) { - RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + *ppTable = RateSwitchTable11N2S; + *pTableSize = RateSwitchTable11N2S[0]; + *pInitTxRateIdx = RateSwitchTable11N2S[1]; } - pAd->PreMediaState = pAd->IndicateMediaState; + else + { + *ppTable = RateSwitchTable11N2SForABand; + *pTableSize = RateSwitchTable11N2SForABand[0]; + *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; } -#ifdef RT2860 - if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) && - (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) && - (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) && - (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) && - (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) - { - RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0); } -#endif + else + if ((pEntry->RateLen == 4) + && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) + ) + { + *ppTable = RateSwitchTable11B; + *pTableSize = RateSwitchTable11B[0]; + *pInitTxRateIdx = RateSwitchTable11B[1]; + } + else if (pAd->LatchRfRegs.Channel <= 14) + { + *ppTable = RateSwitchTable11BG; + *pTableSize = RateSwitchTable11BG[0]; + *pInitTxRateIdx = RateSwitchTable11BG[1]; + } + else + { + *ppTable = RateSwitchTable11G; + *pTableSize = RateSwitchTable11G[0]; + *pInitTxRateIdx = RateSwitchTable11G[1]; - AsicStaBbpTuning(pAd); + } + break; + } - TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + - pAd->RalinkCounters.OneSecTxRetryOkCount + - pAd->RalinkCounters.OneSecTxFailCount; + //if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && + // ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) + if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && + ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) + {// 11BGN 1S AP + *ppTable = RateSwitchTable11BGN1S; + *pTableSize = RateSwitchTable11BGN1S[0]; + *pInitTxRateIdx = RateSwitchTable11BGN1S[1]; - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) - { - // update channel quality for Roaming and UI LinkQuality display - MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32); + break; } - // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if - // Radio is currently in noisy environment - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - AsicAdjustTxPower(pAd); - - if (INFRA_ON(pAd)) + //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && + // (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) + if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && + (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) + {// 11BGN 2S AP + if (pAd->LatchRfRegs.Channel <= 14) { - // Is PSM bit consistent with user power management policy? - // This is the only place that will set PSM bit ON. - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - MlmeCheckPsmChange(pAd, pAd->Mlme.Now32); + *ppTable = RateSwitchTable11BGN2S; + *pTableSize = RateSwitchTable11BGN2S[0]; + *pInitTxRateIdx = RateSwitchTable11BGN2S[1]; - pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt; + } + else + { + *ppTable = RateSwitchTable11BGN2SForABand; + *pTableSize = RateSwitchTable11BGN2SForABand[0]; + *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1]; - if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) && - ((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600))) - { - RTMPSetAGCInitValue(pAd, BW_20); - DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd)))); + } + break; } - { - if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) - { - // When APSD is enabled, the period changes as 20 sec - if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8) - RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); - } - else - { - // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out) + //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) + if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) + {// 11N 1S AP + *ppTable = RateSwitchTable11N1S; + *pTableSize = RateSwitchTable11N1S[0]; + *pInitTxRateIdx = RateSwitchTable11N1S[1]; + + break; + } + + //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) + if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) + {// 11N 2S AP + if (pAd->LatchRfRegs.Channel <= 14) + { + *ppTable = RateSwitchTable11N2S; + *pTableSize = RateSwitchTable11N2S[0]; + *pInitTxRateIdx = RateSwitchTable11N2S[1]; + } + else + { + *ppTable = RateSwitchTable11N2SForABand; + *pTableSize = RateSwitchTable11N2SForABand[0]; + *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; + } + + break; + } + //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) + if ((pEntry->RateLen == 4 || pAd->CommonCfg.PhyMode==PHY_11B) + //Iverson mark for Adhoc b mode,sta will use rate 54 Mbps when connect with sta b/g/n mode + /* && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)*/ + ) + {// B only AP + *ppTable = RateSwitchTable11B; + *pTableSize = RateSwitchTable11B[0]; + *pInitTxRateIdx = RateSwitchTable11B[1]; + + break; + } + + //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) + if ((pEntry->RateLen > 8) + && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) + ) + {// B/G mixed AP + *ppTable = RateSwitchTable11BG; + *pTableSize = RateSwitchTable11BG[0]; + *pInitTxRateIdx = RateSwitchTable11BG[1]; + + break; + } + + //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) + if ((pEntry->RateLen == 8) + && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) + ) + {// G only AP + *ppTable = RateSwitchTable11G; + *pTableSize = RateSwitchTable11G[0]; + *pInitTxRateIdx = RateSwitchTable11G[1]; + + break; + } + + { + //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) + if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)) + { // Legacy mode + if (pAd->CommonCfg.MaxTxRate <= RATE_11) + { + *ppTable = RateSwitchTable11B; + *pTableSize = RateSwitchTable11B[0]; + *pInitTxRateIdx = RateSwitchTable11B[1]; + } + else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11)) + { + *ppTable = RateSwitchTable11G; + *pTableSize = RateSwitchTable11G[0]; + *pInitTxRateIdx = RateSwitchTable11G[1]; + + } + else + { + *ppTable = RateSwitchTable11BG; + *pTableSize = RateSwitchTable11BG[0]; + *pInitTxRateIdx = RateSwitchTable11BG[1]; + } + break; + } + if (pAd->LatchRfRegs.Channel <= 14) + { + if (pAd->CommonCfg.TxStream == 1) + { + *ppTable = RateSwitchTable11N1S; + *pTableSize = RateSwitchTable11N1S[0]; + *pInitTxRateIdx = RateSwitchTable11N1S[1]; + DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n")); + } + else + { + *ppTable = RateSwitchTable11N2S; + *pTableSize = RateSwitchTable11N2S[0]; + *pInitTxRateIdx = RateSwitchTable11N2S[1]; + DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n")); + } + } + else + { + if (pAd->CommonCfg.TxStream == 1) + { + *ppTable = RateSwitchTable11N1S; + *pTableSize = RateSwitchTable11N1S[0]; + *pInitTxRateIdx = RateSwitchTable11N1S[1]; + DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n")); + } + else + { + *ppTable = RateSwitchTable11N2SForABand; + *pTableSize = RateSwitchTable11N2SForABand[0]; + *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; + DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n")); + } + } + DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n", + pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1])); + } + } while(FALSE); +} + + +VOID STAMlmePeriodicExec( + PRTMP_ADAPTER pAd) +{ + ULONG TxTotalCnt; + int i; + + /* + We return here in ATE mode, because the statistics + that ATE need are not collected via this routine. + */ +#if defined(RT305x)||defined(RT3070) + // request by Gary, if Rssi0 > -42, BBP 82 need to be changed from 0x62 to 0x42, , bbp 67 need to be changed from 0x20 to 0x18 + if (!pAd->CommonCfg.HighPowerPatchDisabled) + { +#ifdef RT3070 + if ( (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) +#endif // RT3070 // + { + if ((pAd->StaCfg.RssiSample.AvgRssi0 != 0) && (pAd->StaCfg.RssiSample.AvgRssi0 > (pAd->BbpRssiToDbmDelta - 35))) + { + RT30xxWriteRFRegister(pAd, RF_R27, 0x20); + } + else + { + RT30xxWriteRFRegister(pAd, RF_R27, 0x23); + } + } + } +#endif + + if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) + { + // WPA MIC error should block association attempt for 60 seconds + if (pAd->StaCfg.bBlockAssoc && + RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastMicErrorTime + (60*OS_HZ))) + pAd->StaCfg.bBlockAssoc = FALSE; + } + + if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent)) + { + if (pAd->IndicateMediaState == NdisMediaStateConnected) + { + RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + } + pAd->PreMediaState = pAd->IndicateMediaState; + } + + + + + if (pAd->CommonCfg.PSPXlink && ADHOC_ON(pAd)) + { + } + else + { + AsicStaBbpTuning(pAd); + } + + TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + + pAd->RalinkCounters.OneSecTxRetryOkCount + + pAd->RalinkCounters.OneSecTxFailCount; + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) + { + // update channel quality for Roaming and UI LinkQuality display + MlmeCalculateChannelQuality(pAd, NULL, pAd->Mlme.Now32); + } + + // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if + // Radio is currently in noisy environment + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + AsicAdjustTxPower(pAd); + + if (INFRA_ON(pAd)) + { + + // Is PSM bit consistent with user power management policy? + // This is the only place that will set PSM bit ON. + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + MlmeCheckPsmChange(pAd, pAd->Mlme.Now32); + + pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt; + + if ((RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + (1*OS_HZ))) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) && + (((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt) < 600))) + { + RTMPSetAGCInitValue(pAd, BW_20); + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd)))); + } + + //if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) && + // (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)) + { + if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) + { + // When APSD is enabled, the period changes as 20 sec + if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8) + RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); + } + else + { + // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out) if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8) { if (pAd->CommonCfg.bWmmCapable) @@ -1143,18 +1274,18 @@ VOID STAMlmePeriodicExec( if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality)) { DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount)); - pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE; - pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime; + + if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)) + pAd->StaCfg.bLostAp = TRUE; // Lost AP, send disconnect & link down event LinkDown(pAd, FALSE); - { - union iwreq_data wrqu; - memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN); - wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); - } + RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0); + + // RTMPPatchMacBbpBug(pAd); MlmeAutoReconnectLastSSID(pAd); } else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality)) @@ -1164,76 +1295,46 @@ VOID STAMlmePeriodicExec( MlmeAutoReconnectLastSSID(pAd); } - // Add auto seamless roaming - if (pAd->StaCfg.bFastRoaming) + if (pAd->StaCfg.bAutoRoaming) { - SHORT dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam; - - 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)); + BOOLEAN rv = FALSE; + CHAR dBmToRoam = pAd->StaCfg.dBmToRoam; + CHAR MaxRssi = RTMPMaxRssi(pAd, + pAd->StaCfg.RssiSample.LastRssi0, + pAd->StaCfg.RssiSample.LastRssi1, + pAd->StaCfg.RssiSample.LastRssi2); - if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam) - { - MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32); - } - } - } - else if (ADHOC_ON(pAd)) + // Scanning, ignore Roaming + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) && + (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) && + (MaxRssi <= dBmToRoam)) { -#ifdef RT2860 - // 2003-04-17 john. this is a patch that driver forces a BEACON out if ASIC fails - // the "TX BEACON competition" for the entire past 1 sec. - // So that even when ASIC's BEACONgen engine been blocked - // by peer's BEACON due to slower system clock, this STA still can send out - // minimum BEACON to tell the peer I'm alive. - // drawback is that this BEACON won't be well aligned at TBTT boundary. - // EnqueueBeaconFrame(pAd); // software send BEACON + DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", MaxRssi, (CHAR)dBmToRoam)); - // if all 11b peers leave this BSS more than 5 seconds, update Tx rate, - // restore outgoing BEACON to support B/G-mixed mode - if ((pAd->CommonCfg.Channel <= 14) && - (pAd->CommonCfg.MaxTxRate <= RATE_11) && - (pAd->CommonCfg.MaxDesiredRate > RATE_11) && - ((pAd->StaCfg.Last11bBeaconRxTime + 5*OS_HZ) < pAd->Mlme.Now32)) - { - DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11B peer left, update Tx rates\n")); - NdisMoveMemory(pAd->StaActive.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES); - pAd->StaActive.SupRateLen = pAd->CommonCfg.SupRateLen; - MlmeUpdateTxRates(pAd, FALSE, 0); - MakeIbssBeacon(pAd); // re-build BEACON frame - AsicEnableIbssSync(pAd); // copy to on-chip memory - pAd->StaCfg.AdhocBOnlyJoined = FALSE; - } - if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) + // Add auto seamless roaming + if (rv == FALSE) + rv = MlmeCheckForFastRoaming(pAd); + + if (rv == FALSE) { - if ((pAd->StaCfg.AdhocBGJoined) && - ((pAd->StaCfg.Last11gBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32)) + if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32) { - DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 11G peer left\n")); - pAd->StaCfg.AdhocBGJoined = FALSE; + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n")); + pAd->StaCfg.ScanCnt = 2; + pAd->StaCfg.LastScanTime = pAd->Mlme.Now32; + MlmeAutoScan(pAd); } - - if ((pAd->StaCfg.Adhoc20NJoined) && - ((pAd->StaCfg.Last20NBeaconRxTime + 5 * OS_HZ) < pAd->Mlme.Now32)) - { - DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - last 20MHz N peer left\n")); - pAd->StaCfg.Adhoc20NJoined = FALSE; } } -#endif /* RT2860 */ - - //radar detect - if ((pAd->CommonCfg.Channel > 14) - && (pAd->CommonCfg.bIEEE80211H == 1) - && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) - { - RadarDetectPeriodic(pAd); } - + } + else if (ADHOC_ON(pAd)) + { // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can // join later. - if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) && + if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { MLME_START_REQ_STRUCT StartReq; @@ -1241,12 +1342,11 @@ VOID STAMlmePeriodicExec( DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n")); LinkDown(pAd, FALSE); - StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); + StartParmFill(pAd, &StartReq, (CHAR *)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START; } -#ifdef RT2870 for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) { MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i]; @@ -1254,16 +1354,15 @@ VOID STAMlmePeriodicExec( if (pEntry->ValidAsCLI == FALSE) continue; - if (pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) + if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME)) MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); } -#endif } else // no INFRA nor ADHOC connection { if (pAd->StaCfg.bScanReqIsFromWebUI && - ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32)) + RTMP_TIME_BEFORE(pAd->Mlme.Now32, pAd->StaCfg.LastScanTime + (30 * OS_HZ))) goto SKIP_AUTO_SCAN_CONN; else pAd->StaCfg.bScanReqIsFromWebUI = FALSE; @@ -1276,10 +1375,10 @@ VOID STAMlmePeriodicExec( { MLME_SCAN_REQ_STRUCT ScanReq; - if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32) + if (RTMP_TIME_AFTER(pAd->Mlme.Now32, pAd->StaCfg.LastScanTime + (10 * OS_HZ))) { DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid)); - ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE); + ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE); MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; // Reset Missed scan number @@ -1326,12 +1425,26 @@ VOID LinkDownExec( IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { - RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext; + if (pAd != NULL) + { + MLME_DISASSOC_REQ_STRUCT DisassocReq; + + if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) && + (INFRA_ON(pAd))) + { + DBGPRINT(RT_DEBUG_TRACE, ("LinkDownExec(): disassociate with current AP...\n")); + DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING); + MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, + sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; + pAd->IndicateMediaState = NdisMediaStateDisconnected; RTMP_IndicateMediaState(pAd); pAd->ExtraInfo = GENERAL_LINK_DOWN; + } + } } // IRQL = DISPATCH_LEVEL @@ -1345,9 +1458,9 @@ VOID MlmeAutoScan( MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_BSSID_LIST_SCAN, - 0, - NULL); - RT28XX_MLME_HANDLER(pAd); + pAd->MlmeAux.AutoReconnectSsidLen, + pAd->MlmeAux.AutoReconnectSsid); + RTMP_MLME_HANDLER(pAd); } } @@ -1355,10 +1468,29 @@ VOID MlmeAutoScan( VOID MlmeAutoReconnectLastSSID( IN PRTMP_ADAPTER pAd) { + if (pAd->StaCfg.bAutoConnectByBssid) + { + DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_BSSID setting - %02X:%02X:%02X:%02X:%02X:%02X\n", + pAd->MlmeAux.Bssid[0], + pAd->MlmeAux.Bssid[1], + pAd->MlmeAux.Bssid[2], + pAd->MlmeAux.Bssid[3], + pAd->MlmeAux.Bssid[4], + pAd->MlmeAux.Bssid[5])); + + pAd->MlmeAux.Channel = pAd->CommonCfg.Channel; + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + OID_802_11_BSSID, + MAC_ADDR_LEN, + pAd->MlmeAux.Bssid); + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + RTMP_MLME_HANDLER(pAd); + } // check CntlMachine.CurrState to avoid collision with NDIS SetOID request - if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) && + else if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) { NDIS_802_11_SSID OidSsid; @@ -1371,758 +1503,847 @@ VOID MlmeAutoReconnectLastSSID( OID_802_11_SSID, sizeof(NDIS_802_11_SSID), &OidSsid); - RT28XX_MLME_HANDLER(pAd); + RTMP_MLME_HANDLER(pAd); } } + /* ========================================================================== - Validate SSID for connection try and rescan purpose - Valid SSID will have visible chars only. - The valid length is from 0 to 32. + Description: + This routine checks if there're other APs out there capable for + roaming. Caller should call this routine only when Link up in INFRA mode + and channel quality is below CQI_GOOD_THRESHOLD. + IRQL = DISPATCH_LEVEL + + Output: ========================================================================== */ -BOOLEAN MlmeValidateSSID( - IN PUCHAR pSsid, - IN UCHAR SsidLen) +VOID MlmeCheckForRoaming( + IN PRTMP_ADAPTER pAd, + IN ULONG Now32) { - int index; - - if (SsidLen > MAX_LEN_OF_SSID) - return (FALSE); + USHORT i; + BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab; + BSS_ENTRY *pBss; - // Check each character value - for (index = 0; index < SsidLen; index++) + DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n")); + // put all roaming candidates into RoamTab, and sort in RSSI order + BssTableInit(pRoamTab); + for (i = 0; i < pAd->ScanTab.BssNr; i++) { - if (pSsid[index] < 0x20) - return (FALSE); + pBss = &pAd->ScanTab.BssEntry[i]; + + if ((pBss->LastBeaconRxTime + pAd->StaCfg.BeaconLostTime) < Now32) + continue; // AP disappear + if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING) + continue; // RSSI too weak. forget it. + if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid)) + continue; // skip current AP + if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA)) + continue; // only AP with stronger RSSI is eligible for roaming + + // AP passing all above rules is put into roaming candidate table + NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY)); + pRoamTab->BssNr += 1; } - // All checked - return (TRUE); + if (pRoamTab->BssNr > 0) + { + // check CntlMachine.CurrState to avoid collision with NDIS SetOID request + if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) + { + pAd->RalinkCounters.PoorCQIRoamingCount ++; + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount)); + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL); + RTMP_MLME_HANDLER(pAd); + } + } + DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr)); } -VOID MlmeSelectTxRateTable( - IN PRTMP_ADAPTER pAd, - IN PMAC_TABLE_ENTRY pEntry, - IN PUCHAR *ppTable, - IN PUCHAR pTableSize, - IN PUCHAR pInitTxRateIdx) +/* + ========================================================================== + Description: + This routine checks if there're other APs out there capable for + roaming. Caller should call this routine only when link up in INFRA mode + and channel quality is below CQI_GOOD_THRESHOLD. + + IRQL = DISPATCH_LEVEL + + Output: + ========================================================================== + */ +BOOLEAN MlmeCheckForFastRoaming( + IN PRTMP_ADAPTER pAd) { - do - { - // decide the rate table for tuning - if (pAd->CommonCfg.TxRateTableSize > 0) + USHORT i; + BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab; + BSS_ENTRY *pBss; + + DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n")); + // put all roaming candidates into RoamTab, and sort in RSSI order + BssTableInit(pRoamTab); + for (i = 0; i < pAd->ScanTab.BssNr; i++) { - *ppTable = RateSwitchTable; - *pTableSize = RateSwitchTable[0]; - *pInitTxRateIdx = RateSwitchTable[1]; + pBss = &pAd->ScanTab.BssEntry[i]; - break; + if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel)) + continue; // RSSI too weak. forget it. + if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid)) + continue; // skip current AP + if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)) + continue; // skip different SSID + if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA)) + continue; // skip AP without better RSSI + + 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)); + // AP passing all above rules is put into roaming candidate table + NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY)); + pRoamTab->BssNr += 1; } - if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd)) + DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr)); + if (pRoamTab->BssNr > 0) { - if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && -#ifdef RT2860 - !pAd->StaCfg.AdhocBOnlyJoined && - !pAd->StaCfg.AdhocBGJoined && - (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && - ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) -#endif -#ifdef RT2870 - (pEntry->HTCapability.MCSSet[0] == 0xff) && - ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) -#endif - {// 11N 1S Adhoc - *ppTable = RateSwitchTable11N1S; - *pTableSize = RateSwitchTable11N1S[0]; - *pInitTxRateIdx = RateSwitchTable11N1S[1]; - - } - else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && -#ifdef RT2860 - !pAd->StaCfg.AdhocBOnlyJoined && - !pAd->StaCfg.AdhocBGJoined && - (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && - (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && -#endif -#ifdef RT2870 - (pEntry->HTCapability.MCSSet[0] == 0xff) && - (pEntry->HTCapability.MCSSet[1] == 0xff) && -#endif - (pAd->Antenna.field.TxPath == 2)) - {// 11N 2S Adhoc - if (pAd->LatchRfRegs.Channel <= 14) + // check CntlMachine.CurrState to avoid collision with NDIS SetOID request + if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) { - *ppTable = RateSwitchTable11N2S; - *pTableSize = RateSwitchTable11N2S[0]; - *pInitTxRateIdx = RateSwitchTable11N2S[1]; + pAd->RalinkCounters.PoorCQIRoamingCount ++; + DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount)); + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL); + RTMP_MLME_HANDLER(pAd); + return TRUE; } - else - { - *ppTable = RateSwitchTable11N2SForABand; - *pTableSize = RateSwitchTable11N2SForABand[0]; - *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; } - } - else -#ifdef RT2860 - if (pAd->CommonCfg.PhyMode == PHY_11B) - { - *ppTable = RateSwitchTable11B; - *pTableSize = RateSwitchTable11B[0]; - *pInitTxRateIdx = RateSwitchTable11B[1]; + return FALSE; +} - } - else if((pAd->LatchRfRegs.Channel <= 14) && (pAd->StaCfg.AdhocBOnlyJoined == TRUE)) -#endif -#ifdef RT2870 - if ((pEntry->RateLen == 4) - && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) - ) -#endif - { - // USe B Table when Only b-only Station in my IBSS . - *ppTable = RateSwitchTable11B; - *pTableSize = RateSwitchTable11B[0]; - *pInitTxRateIdx = RateSwitchTable11B[1]; +VOID MlmeSetTxRate( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, + IN PRTMP_TX_RATE_SWITCH pTxRate) +{ + UCHAR MaxMode = MODE_OFDM; - } - else if (pAd->LatchRfRegs.Channel <= 14) - { - *ppTable = RateSwitchTable11BG; - *pTableSize = RateSwitchTable11BG[0]; - *pInitTxRateIdx = RateSwitchTable11BG[1]; + MaxMode = MODE_HTGREENFIELD; - } + if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2)) + pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE; else - { - *ppTable = RateSwitchTable11G; - *pTableSize = RateSwitchTable11G[0]; - *pInitTxRateIdx = RateSwitchTable11G[1]; - - } - break; - } + pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; - if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) && - ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) - {// 11BGN 1S AP - *ppTable = RateSwitchTable11BGN1S; - *pTableSize = RateSwitchTable11BGN1S[0]; - *pInitTxRateIdx = RateSwitchTable11BGN1S[1]; + if (pTxRate->CurrMCS < MCS_AUTO) + pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS; - break; - } + if (pAd->StaCfg.HTPhyMode.field.MCS > 7) + pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; - if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) && - (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) - {// 11BGN 2S AP - if (pAd->LatchRfRegs.Channel <= 14) + if (ADHOC_ON(pAd)) { - *ppTable = RateSwitchTable11BGN2S; - *pTableSize = RateSwitchTable11BGN2S[0]; - *pInitTxRateIdx = RateSwitchTable11BGN2S[1]; + // If peer adhoc is b-only mode, we can't send 11g rate. + pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; + pEntry->HTPhyMode.field.STBC = STBC_NONE; + + // + // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary + // + pEntry->HTPhyMode.field.MODE = pTxRate->Mode; + pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI; + pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + // Patch speed error in status page + pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE; } else { - *ppTable = RateSwitchTable11BGN2SForABand; - *pTableSize = RateSwitchTable11BGN2SForABand[0]; - *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1]; - - } - break; - } + if (pTxRate->Mode <= MaxMode) + pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode; - if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) - {// 11N 1S AP - *ppTable = RateSwitchTable11N1S; - *pTableSize = RateSwitchTable11N1S[0]; - *pInitTxRateIdx = RateSwitchTable11N1S[1]; + if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI)) + pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400; + else + pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; - break; + // Reexam each bandwidth's SGI support. + if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400) + { + if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE))) + pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; + if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE))) + pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; } - if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) - {// 11N 2S AP - if (pAd->LatchRfRegs.Channel <= 14) + // Turn RTS/CTS rate to 6Mbps. + if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0)) { - *ppTable = RateSwitchTable11N2S; - *pTableSize = RateSwitchTable11N2S[0]; - *pInitTxRateIdx = RateSwitchTable11N2S[1]; + pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + if (pAd->MacTab.fAnyBASession) + { + AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); } else { - *ppTable = RateSwitchTable11N2SForABand; - *pTableSize = RateSwitchTable11N2SForABand[0]; - *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; + AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + } } + else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8)) + { + pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + if (pAd->MacTab.fAnyBASession) + { + AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + } + else + { + AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + } + } + else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0)) + { + AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); - break; - } - - //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) - if (pEntry->RateLen == 4) - {// B only AP - *ppTable = RateSwitchTable11B; - *pTableSize = RateSwitchTable11B[0]; - *pInitTxRateIdx = RateSwitchTable11B[1]; - - break; - } - - //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) - if ((pEntry->RateLen > 8) - && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) - ) - {// B/G mixed AP - *ppTable = RateSwitchTable11BG; - *pTableSize = RateSwitchTable11BG[0]; - *pInitTxRateIdx = RateSwitchTable11BG[1]; - - break; - } - - //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) - if ((pEntry->RateLen == 8) - && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) - ) - {// G only AP - *ppTable = RateSwitchTable11G; - *pTableSize = RateSwitchTable11G[0]; - *pInitTxRateIdx = RateSwitchTable11G[1]; - - break; - } - - { - //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) - if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)) - { // Legacy mode - if (pAd->CommonCfg.MaxTxRate <= RATE_11) - { - *ppTable = RateSwitchTable11B; - *pTableSize = RateSwitchTable11B[0]; - *pInitTxRateIdx = RateSwitchTable11B[1]; - } - else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11)) - { - *ppTable = RateSwitchTable11G; - *pTableSize = RateSwitchTable11G[0]; - *pInitTxRateIdx = RateSwitchTable11G[1]; - - } - else - { - *ppTable = RateSwitchTable11BG; - *pTableSize = RateSwitchTable11BG[0]; - *pInitTxRateIdx = RateSwitchTable11BG[1]; - } - break; - } - - if (pAd->LatchRfRegs.Channel <= 14) - { - if (pAd->CommonCfg.TxStream == 1) - { - *ppTable = RateSwitchTable11N1S; - *pTableSize = RateSwitchTable11N1S[0]; - *pInitTxRateIdx = RateSwitchTable11N1S[1]; - DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n")); - } - else - { - *ppTable = RateSwitchTable11N2S; - *pTableSize = RateSwitchTable11N2S[0]; - *pInitTxRateIdx = RateSwitchTable11N2S[1]; - DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n")); - } - } - else - { - if (pAd->CommonCfg.TxStream == 1) - { - *ppTable = RateSwitchTable11N1S; - *pTableSize = RateSwitchTable11N1S[0]; - *pInitTxRateIdx = RateSwitchTable11N1S[1]; - DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n")); } - else + else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8)) { - *ppTable = RateSwitchTable11N2SForABand; - *pTableSize = RateSwitchTable11N2SForABand[0]; - *pInitTxRateIdx = RateSwitchTable11N2SForABand[1]; - DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n")); - } + AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); } - DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n", - pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1])); + pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC; + pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI; + pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE; + if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) && + pAd->WIFItestbed.bGreenField) + pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD; } - } while(FALSE); + + pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word); } /* ========================================================================== Description: - This routine checks if there're other APs out there capable for - roaming. Caller should call this routine only when Link up in INFRA mode - and channel quality is below CQI_GOOD_THRESHOLD. + This routine calculates the acumulated TxPER of eaxh TxRate. And + according to the calculation result, change CommonCfg.TxRate which + is the stable TX Rate we expect the Radio situation could sustained. + + CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate} + Output: + CommonCfg.TxRate - IRQL = DISPATCH_LEVEL - Output: + NOTE: + call this routine every second ========================================================================== */ -VOID MlmeCheckForRoaming( - IN PRTMP_ADAPTER pAd, - IN ULONG Now32) +VOID MlmeDynamicTxRateSwitching( + IN PRTMP_ADAPTER pAd) { - USHORT i; - BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab; - BSS_ENTRY *pBss; + UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx; + ULONG i, AccuTxTotalCnt = 0, TxTotalCnt; + ULONG TxErrorRatio = 0; + BOOLEAN bTxRateChanged = FALSE, bUpgradeQuality = FALSE; + PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL; + PUCHAR pTable; + UCHAR TableSize = 0; + UCHAR InitTxRateIdx = 0, TrainUp, TrainDown; + CHAR Rssi, RssiOffset = 0; + TX_STA_CNT1_STRUC StaTx1; + TX_STA_CNT0_STRUC TxStaCnt0; + ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0; + MAC_TABLE_ENTRY *pEntry; + RSSI_SAMPLE *pRssi = &pAd->StaCfg.RssiSample; - DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n")); - // put all roaming candidates into RoamTab, and sort in RSSI order - BssTableInit(pRoamTab); - for (i = 0; i < pAd->ScanTab.BssNr; i++) - { - pBss = &pAd->ScanTab.BssEntry[i]; - if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32) - continue; // AP disappear - if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING) - continue; // RSSI too weak. forget it. - if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid)) - continue; // skip current AP - if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA)) - continue; // only AP with stronger RSSI is eligible for roaming + // + // walk through MAC table, see if need to change AP's TX rate toward each entry + // + for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) + { + pEntry = &pAd->MacTab.Content[i]; - // AP passing all above rules is put into roaming candidate table - NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY)); - pRoamTab->BssNr += 1; - } + // check if this entry need to switch rate automatically + if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE) + continue; - if (pRoamTab->BssNr > 0) - { - // check CntlMachine.CurrState to avoid collision with NDIS SetOID request - if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) + if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls)) { - pAd->RalinkCounters.PoorCQIRoamingCount ++; - DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount)); - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL); - RT28XX_MLME_HANDLER(pAd); - } - } - DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr)); -} + Rssi = RTMPMaxRssi(pAd, + pRssi->AvgRssi0, + pRssi->AvgRssi1, + pRssi->AvgRssi2); -/* - ========================================================================== - Description: - This routine checks if there're other APs out there capable for - roaming. Caller should call this routine only when link up in INFRA mode - and channel quality is below CQI_GOOD_THRESHOLD. + // Update statistic counter + RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); + RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); + pAd->bUpdateBcnCntDone = TRUE; + TxRetransmit = StaTx1.field.TxRetransmit; + TxSuccess = StaTx1.field.TxSuccess; + TxFailCount = TxStaCnt0.field.TxFailCount; + TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount; - IRQL = DISPATCH_LEVEL + pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; + pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; + pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount; + pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess; + pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit; + pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount; - Output: - ========================================================================== - */ -VOID MlmeCheckForFastRoaming( - IN PRTMP_ADAPTER pAd, - IN ULONG Now) -{ - USHORT i; - BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab; - BSS_ENTRY *pBss; + // if no traffic in the past 1-sec period, don't change TX rate, + // but clear all bad history. because the bad history may affect the next + // Chariot throughput test + AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + + pAd->RalinkCounters.OneSecTxRetryOkCount + + pAd->RalinkCounters.OneSecTxFailCount; - DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n")); - // put all roaming candidates into RoamTab, and sort in RSSI order - BssTableInit(pRoamTab); - for (i = 0; i < pAd->ScanTab.BssNr; i++) + if (TxTotalCnt) + TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt; + } + else { - pBss = &pAd->ScanTab.BssEntry[i]; + if (INFRA_ON(pAd) && (i == 1)) + Rssi = RTMPMaxRssi(pAd, + pRssi->AvgRssi0, + pRssi->AvgRssi1, + pRssi->AvgRssi2); + else + Rssi = RTMPMaxRssi(pAd, + pEntry->RssiSample.AvgRssi0, + pEntry->RssiSample.AvgRssi1, + pEntry->RssiSample.AvgRssi2); - if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel)) - continue; // RSSI too weak. forget it. - if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid)) - continue; // skip current AP - if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)) - continue; // skip different SSID - if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA)) - continue; // skip AP without better RSSI + TxTotalCnt = pEntry->OneSecTxNoRetryOkCount + + pEntry->OneSecTxRetryOkCount + + pEntry->OneSecTxFailCount; - 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)); - // AP passing all above rules is put into roaming candidate table - NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY)); - pRoamTab->BssNr += 1; + if (TxTotalCnt) + TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt; } - if (pRoamTab->BssNr > 0) - { - // check CntlMachine.CurrState to avoid collision with NDIS SetOID request - if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) + if (TxTotalCnt) { - pAd->RalinkCounters.PoorCQIRoamingCount ++; - DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount)); - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL); - RT28XX_MLME_HANDLER(pAd); - } - } - // Maybe site survey required - else - { - if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now) + /* + Three AdHoc connections can not work normally if one AdHoc connection is disappeared from a heavy traffic environment generated by ping tool + We force to set LongRtyLimit and ShortRtyLimit to 0 to stop retransmitting packet, after a while, resoring original settings + */ + if (TxErrorRatio == 100) + { + TX_RTY_CFG_STRUC TxRtyCfg,TxRtyCfgtmp; + ULONG Index; + ULONG MACValue; + + RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word); + TxRtyCfgtmp.word = TxRtyCfg.word; + TxRtyCfg.field.LongRtyLimit = 0x0; + TxRtyCfg.field.ShortRtyLimit = 0x0; + RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word); + + RTMPusecDelay(1); + + Index = 0; + MACValue = 0; + do { - // check CntlMachine.CurrState to avoid collision with NDIS SetOID request - DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n")); - pAd->StaCfg.ScanCnt = 2; - pAd->StaCfg.LastScanTime = Now; - MlmeAutoScan(pAd); + RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); + if ((MACValue & 0xffffff) == 0) + break; + Index++; + RTMPusecDelay(1000); + }while((Index < 330)&&(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))); + + RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word); + TxRtyCfg.field.LongRtyLimit = TxRtyCfgtmp.field.LongRtyLimit; + TxRtyCfg.field.ShortRtyLimit = TxRtyCfgtmp.field.ShortRtyLimit; + RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word); } } - DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr)); -} + CurrRateIdx = pEntry->CurrTxRateIndex; -/* - ========================================================================== - Description: - This routine calculates TxPER, RxPER of the past N-sec period. And - according to the calculation result, ChannelQuality is calculated here - to decide if current AP is still doing the job. + MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx); - If ChannelQuality is not good, a ROAMing attempt may be tried later. - Output: - StaCfg.ChannelQuality - 0..100 + if (CurrRateIdx >= TableSize) + { + CurrRateIdx = TableSize - 1; + } - IRQL = DISPATCH_LEVEL + // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex. + // So need to sync here. + pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5]; + if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS) + //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE) + ) + { - NOTE: This routine decide channle quality based on RX CRC error ratio. - Caller should make sure a function call to NICUpdateRawCounters(pAd) - is performed right before this routine, so that this routine can decide - channel quality based on the most up-to-date information - ========================================================================== - */ -VOID MlmeCalculateChannelQuality( - IN PRTMP_ADAPTER pAd, - IN ULONG Now32) -{ - ULONG TxOkCnt, TxCnt, TxPER, TxPRR; - ULONG RxCnt, RxPER; - UCHAR NorRssi; - CHAR MaxRssi; - ULONG BeaconLostTime = BEACON_LOST_TIME; + // Need to sync Real Tx rate and our record. + // Then return for next DRS. + pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5]; + pEntry->CurrTxRateIndex = InitTxRateIdx; + MlmeSetTxRate(pAd, pEntry, pCurrTxRate); - MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2); + // reset all OneSecTx counters + RESET_ONE_SEC_TX_CNT(pEntry); + continue; + } - // - // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics - // - TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount; - TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount; - if (TxCnt < 5) + // decide the next upgrade rate and downgrade rate, if any + if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) { - TxPER = 0; - TxPRR = 0; + UpRateIdx = CurrRateIdx + 1; + DownRateIdx = CurrRateIdx -1; } - else + else if (CurrRateIdx == 0) + { + UpRateIdx = CurrRateIdx + 1; + DownRateIdx = CurrRateIdx; + } + else if (CurrRateIdx == (TableSize - 1)) { - TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt; - TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt; + UpRateIdx = CurrRateIdx; + DownRateIdx = CurrRateIdx - 1; } - // - // calculate RX PER - don't take RxPER into consideration if too few sample - // - RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt; - if (RxCnt < 5) - RxPER = 0; - else - RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt; + pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5]; - // - // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER - // - if (INFRA_ON(pAd) && - (pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic - (pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32)) + if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) { - DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt)); - pAd->Mlme.ChannelQuality = 0; + TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1)); + TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1)); } else { - // Normalize Rssi - if (MaxRssi > -40) - NorRssi = 100; - else if (MaxRssi < -90) - NorRssi = 0; - else - NorRssi = (MaxRssi + 90) * 2; - - // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0) - pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi + - TX_WEIGHTING * (100 - TxPRR) + - RX_WEIGHTING* (100 - RxPER)) / 100; - if (pAd->Mlme.ChannelQuality >= 100) - pAd->Mlme.ChannelQuality = 100; + TrainUp = pCurrTxRate->TrainUp; + TrainDown = pCurrTxRate->TrainDown; } -} - -VOID MlmeSetTxRate( - IN PRTMP_ADAPTER pAd, - IN PMAC_TABLE_ENTRY pEntry, - IN PRTMP_TX_RATE_SWITCH pTxRate) -{ - UCHAR MaxMode = MODE_OFDM; - - MaxMode = MODE_HTGREENFIELD; - - if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2)) - pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE; - else - pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; + //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction; - if (pTxRate->CurrMCS < MCS_AUTO) - pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS; + // + // Keep the last time TxRateChangeAction status. + // + pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction; - if (pAd->StaCfg.HTPhyMode.field.MCS > 7) - pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE; - if (ADHOC_ON(pAd)) - { - // If peer adhoc is b-only mode, we can't send 11g rate. - pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; - pEntry->HTPhyMode.field.STBC = STBC_NONE; // - // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary + // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI + // (criteria copied from RT2500 for Netopia case) // - pEntry->HTPhyMode.field.MODE = pTxRate->Mode; - pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI; - pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; - - // Patch speed error in status page - pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE; - } - else + if (TxTotalCnt <= 15) { - if (pTxRate->Mode <= MaxMode) - pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode; + CHAR idx = 0; + UCHAR TxRateIdx; + UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0; + UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0; + UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3 - if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI)) - pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400; - else - pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; + // check the existence and index of each needed MCS + while (idx < pTable[0]) + { + pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5]; - // Reexam each bandwidth's SGI support. - if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400) + if (pCurrTxRate->CurrMCS == MCS_0) { - if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE))) - pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; - if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE))) - pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800; + MCS0 = idx; } - - // Turn RTS/CTS rate to 6Mbps. - if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0)) + else if (pCurrTxRate->CurrMCS == MCS_1) { - pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; - if (pAd->MacTab.fAnyBASession) + MCS1 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_2) { - AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + MCS2 = idx; } - else + else if (pCurrTxRate->CurrMCS == MCS_3) { - AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + MCS3 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_4) + { + MCS4 = idx; } + else if (pCurrTxRate->CurrMCS == MCS_5) + { + MCS5 = idx; } - else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8)) + else if (pCurrTxRate->CurrMCS == MCS_6) { - pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; - if (pAd->MacTab.fAnyBASession) + MCS6 = idx; + } + //else if (pCurrTxRate->CurrMCS == MCS_7) + else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) // prevent the highest MCS using short GI when 1T and low throughput { - AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + MCS7 = idx; } - else + else if (pCurrTxRate->CurrMCS == MCS_12) { - AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + MCS12 = idx; } + else if (pCurrTxRate->CurrMCS == MCS_13) + { + MCS13 = idx; } - else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0)) + else if (pCurrTxRate->CurrMCS == MCS_14) { - AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); - + MCS14 = idx; } - else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8)) + //else if ((pCurrTxRate->CurrMCS == MCS_15)/* && (pCurrTxRate->ShortGI == GI_800)*/) //we hope to use ShortGI as initial rate + 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 { - AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent); + MCS15 = idx; } + else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3 + { + MCS20 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_21) + { + MCS21 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_22) + { + MCS22 = idx; + } + else if (pCurrTxRate->CurrMCS == MCS_23) + { + MCS23 = idx; + } + idx ++; + } - pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC; - pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI; - pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; - pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE; - - if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) && - pAd->WIFItestbed.bGreenField) - pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD; - } - - pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word); -} - -/* - ========================================================================== - Description: - This routine calculates the acumulated TxPER of eaxh TxRate. And - according to the calculation result, change CommonCfg.TxRate which - is the stable TX Rate we expect the Radio situation could sustained. - - CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate} - Output: - CommonCfg.TxRate - + if (pAd->LatchRfRegs.Channel <= 14) + { + if (pAd->NicConfig2.field.ExternalLNAForG) + { + RssiOffset = 2; + } + else + { + RssiOffset = 5; + } + } + else + { + if (pAd->NicConfig2.field.ExternalLNAForA) + { + RssiOffset = 5; + } + else + { + RssiOffset = 8; + } + } - IRQL = DISPATCH_LEVEL + /*if (MCS15)*/ + if ((pTable == RateSwitchTable11BGN3S) || + (pTable == RateSwitchTable11N3S) || + (pTable == RateSwitchTable)) + {// N mode with 3 stream // 3*3 + if (MCS23 && (Rssi >= -70)) + TxRateIdx = MCS23; + else if (MCS22 && (Rssi >= -72)) + TxRateIdx = MCS22; + else if (MCS21 && (Rssi >= -76)) + TxRateIdx = MCS21; + else if (MCS20 && (Rssi >= -78)) + TxRateIdx = MCS20; + else if (MCS4 && (Rssi >= -82)) + TxRateIdx = MCS4; + else if (MCS3 && (Rssi >= -84)) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi >= -86)) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi >= -88)) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + } +// else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable)) + else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3 + {// N mode with 2 stream + if (MCS15 && (Rssi >= (-70+RssiOffset))) + TxRateIdx = MCS15; + else if (MCS14 && (Rssi >= (-72+RssiOffset))) + TxRateIdx = MCS14; + else if (MCS13 && (Rssi >= (-76+RssiOffset))) + TxRateIdx = MCS13; + else if (MCS12 && (Rssi >= (-78+RssiOffset))) + TxRateIdx = MCS12; + else if (MCS4 && (Rssi >= (-82+RssiOffset))) + TxRateIdx = MCS4; + else if (MCS3 && (Rssi >= (-84+RssiOffset))) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi >= (-86+RssiOffset))) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi >= (-88+RssiOffset))) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + } + else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S)) + {// N mode with 1 stream + if (MCS7 && (Rssi > (-72+RssiOffset))) + TxRateIdx = MCS7; + else if (MCS6 && (Rssi > (-74+RssiOffset))) + TxRateIdx = MCS6; + else if (MCS5 && (Rssi > (-77+RssiOffset))) + TxRateIdx = MCS5; + else if (MCS4 && (Rssi > (-79+RssiOffset))) + TxRateIdx = MCS4; + else if (MCS3 && (Rssi > (-81+RssiOffset))) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi > (-83+RssiOffset))) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi > (-86+RssiOffset))) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + } + else + {// Legacy mode + if (MCS7 && (Rssi > -70)) + TxRateIdx = MCS7; + else if (MCS6 && (Rssi > -74)) + TxRateIdx = MCS6; + else if (MCS5 && (Rssi > -78)) + TxRateIdx = MCS5; + else if (MCS4 && (Rssi > -82)) + TxRateIdx = MCS4; + else if (MCS4 == 0) // for B-only mode + TxRateIdx = MCS3; + else if (MCS3 && (Rssi > -85)) + TxRateIdx = MCS3; + else if (MCS2 && (Rssi > -87)) + TxRateIdx = MCS2; + else if (MCS1 && (Rssi > -90)) + TxRateIdx = MCS1; + else + TxRateIdx = MCS0; + } - NOTE: - call this routine every second - ========================================================================== - */ -VOID MlmeDynamicTxRateSwitching( - IN PRTMP_ADAPTER pAd) -{ - UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx; - ULONG i, AccuTxTotalCnt = 0, TxTotalCnt; - ULONG TxErrorRatio = 0; - BOOLEAN bTxRateChanged, bUpgradeQuality = FALSE; - PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL; - PUCHAR pTable; - UCHAR TableSize = 0; - UCHAR InitTxRateIdx = 0, TrainUp, TrainDown; - CHAR Rssi, RssiOffset = 0; - TX_STA_CNT1_STRUC StaTx1; - TX_STA_CNT0_STRUC TxStaCnt0; - ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0; - MAC_TABLE_ENTRY *pEntry; + // if (TxRateIdx != pAd->CommonCfg.TxRateIndex) + { + pEntry->CurrTxRateIndex = TxRateIdx; + pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5]; + MlmeSetTxRate(pAd, pEntry, pNextTxRate); + } - // - // walk through MAC table, see if need to change AP's TX rate toward each entry - // - for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) - { - pEntry = &pAd->MacTab.Content[i]; + NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); + pEntry->fLastSecAccordingRSSI = TRUE; + // reset all OneSecTx counters + RESET_ONE_SEC_TX_CNT(pEntry); - // check if this entry need to switch rate automatically - if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE) continue; + } - if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls)) + if (pEntry->fLastSecAccordingRSSI == TRUE) { -#ifdef RT2860 - Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.RssiSample.AvgRssi0, (CHAR)pAd->StaCfg.RssiSample.AvgRssi1, (CHAR)pAd->StaCfg.RssiSample.AvgRssi2); -#endif -#ifdef RT2870 - Rssi = RTMPMaxRssi(pAd, - pAd->StaCfg.RssiSample.AvgRssi0, - pAd->StaCfg.RssiSample.AvgRssi1, - pAd->StaCfg.RssiSample.AvgRssi2); -#endif - - // Update statistic counter - RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); - RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); - pAd->bUpdateBcnCntDone = TRUE; - TxRetransmit = StaTx1.field.TxRetransmit; - TxSuccess = StaTx1.field.TxSuccess; - TxFailCount = TxStaCnt0.field.TxFailCount; - TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount; - - pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; - pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; - pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount; - pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess; - pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit; - pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount; - - // if no traffic in the past 1-sec period, don't change TX rate, - // but clear all bad history. because the bad history may affect the next - // Chariot throughput test - AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + - pAd->RalinkCounters.OneSecTxRetryOkCount + - pAd->RalinkCounters.OneSecTxFailCount; + pEntry->fLastSecAccordingRSSI = FALSE; + pEntry->LastSecTxRateChangeAction = 0; + // reset all OneSecTx counters + RESET_ONE_SEC_TX_CNT(pEntry); - if (TxTotalCnt) - TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt; + continue; } - else + + do { -#ifdef RT2860 - Rssi = RTMPMaxRssi(pAd, (CHAR)pEntry->RssiSample.AvgRssi0, (CHAR)pEntry->RssiSample.AvgRssi1, (CHAR)pEntry->RssiSample.AvgRssi2); -#endif -#ifdef RT2870 - if (INFRA_ON(pAd) && (i == 1)) - Rssi = RTMPMaxRssi(pAd, - pAd->StaCfg.RssiSample.AvgRssi0, - pAd->StaCfg.RssiSample.AvgRssi1, - pAd->StaCfg.RssiSample.AvgRssi2); - else - Rssi = RTMPMaxRssi(pAd, - pEntry->RssiSample.AvgRssi0, - pEntry->RssiSample.AvgRssi1, - pEntry->RssiSample.AvgRssi2); -#endif + BOOLEAN bTrainUpDown = FALSE; - TxTotalCnt = pEntry->OneSecTxNoRetryOkCount + - pEntry->OneSecTxRetryOkCount + - pEntry->OneSecTxFailCount; + pEntry->CurrTxRateStableTime ++; - if (TxTotalCnt) - TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt; - } + // downgrade TX quality if PER >= Rate-Down threshold + if (TxErrorRatio >= TrainDown) + { + bTrainUpDown = TRUE; + pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; + } + // upgrade TX quality if PER <= Rate-Up threshold + else if (TxErrorRatio <= TrainUp) + { + bTrainUpDown = TRUE; + bUpgradeQuality = TRUE; + if (pEntry->TxQuality[CurrRateIdx]) + pEntry->TxQuality[CurrRateIdx] --; // quality very good in CurrRate - CurrRateIdx = pEntry->CurrTxRateIndex; + if (pEntry->TxRateUpPenalty) + pEntry->TxRateUpPenalty --; + else if (pEntry->TxQuality[UpRateIdx]) + pEntry->TxQuality[UpRateIdx] --; // may improve next UP rate's quality + } - MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx); + pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio; - if (CurrRateIdx >= TableSize) - { - CurrRateIdx = TableSize - 1; - } + if (bTrainUpDown) + { + // perform DRS - consider TxRate Down first, then rate up. + if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND)) + { + pEntry->CurrTxRateIndex = DownRateIdx; + } + else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0)) + { + pEntry->CurrTxRateIndex = UpRateIdx; + } + } + } while (FALSE); - // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex. - // So need to sync here. - pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5]; - if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS) - //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE) - ) + // if rate-up happen, clear all bad history of all TX rates + if (pEntry->CurrTxRateIndex > CurrRateIdx) { + pEntry->CurrTxRateStableTime = 0; + pEntry->TxRateUpPenalty = 0; + pEntry->LastSecTxRateChangeAction = 1; // rate UP + NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); - // Need to sync Real Tx rate and our record. - // Then return for next DRS. - pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5]; - pEntry->CurrTxRateIndex = InitTxRateIdx; - MlmeSetTxRate(pAd, pEntry, pCurrTxRate); + // + // For TxRate fast train up + // + if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) + { + RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); - // reset all OneSecTx counters - RESET_ONE_SEC_TX_CNT(pEntry); - continue; + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE; + } + bTxRateChanged = TRUE; } - - // decide the next upgrade rate and downgrade rate, if any - if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) + // if rate-down happen, only clear DownRate's bad history + else if (pEntry->CurrTxRateIndex < CurrRateIdx) { - UpRateIdx = CurrRateIdx + 1; - DownRateIdx = CurrRateIdx -1; - } - else if (CurrRateIdx == 0) + pEntry->CurrTxRateStableTime = 0; + pEntry->TxRateUpPenalty = 0; // no penalty + pEntry->LastSecTxRateChangeAction = 2; // rate DOWN + pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0; + pEntry->PER[pEntry->CurrTxRateIndex] = 0; + + // + // For TxRate fast train down + // + if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) + { + RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); + + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE; + } + bTxRateChanged = TRUE; + } + else + { + pEntry->LastSecTxRateChangeAction = 0; // rate no change + bTxRateChanged = FALSE; + } + + pEntry->LastTxOkCount = TxSuccess; +#ifdef RT2860 + pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5]; +#endif // RT2860 // +#if defined(RT2870) || defined(RT3070) + { + UCHAR tmpTxRate; + + // to fix tcp ack issue + if (!bTxRateChanged && (pAd->RalinkCounters.OneSecReceivedByteCount > (pAd->RalinkCounters.OneSecTransmittedByteCount * 5))) + { + tmpTxRate = DownRateIdx; + DBGPRINT_RAW(RT_DEBUG_TRACE,("DRS: Rx(%d) is 5 times larger than Tx(%d), use low rate (curr=%d, tmp=%d)\n", + pAd->RalinkCounters.OneSecReceivedByteCount, pAd->RalinkCounters.OneSecTransmittedByteCount, pEntry->CurrTxRateIndex, tmpTxRate)); + } + else + { + tmpTxRate = pEntry->CurrTxRateIndex; + } + + pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(tmpTxRate+1)*5]; + } +#endif // RT2870 // + if (bTxRateChanged && pNextTxRate) + { + MlmeSetTxRate(pAd, pEntry, pNextTxRate); + } + // reset all OneSecTx counters + RESET_ONE_SEC_TX_CNT(pEntry); + } +} + +/* + ======================================================================== + Routine Description: + Station side, Auto TxRate faster train up timer call back function. + + Arguments: + SystemSpecific1 - Not used. + FunctionContext - Pointer to our Adapter context. + SystemSpecific2 - Not used. + SystemSpecific3 - Not used. + + Return Value: + None + + ======================================================================== +*/ +VOID StaQuickResponeForRateUpExec( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext; + UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0; + ULONG TxTotalCnt; + ULONG TxErrorRatio = 0; + BOOLEAN bTxRateChanged; //, bUpgradeQuality = FALSE; + PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL; + PUCHAR pTable; + UCHAR TableSize = 0; + UCHAR InitTxRateIdx = 0, TrainUp, TrainDown; + TX_STA_CNT1_STRUC StaTx1; + TX_STA_CNT0_STRUC TxStaCnt0; + CHAR Rssi, ratio; + ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0; + MAC_TABLE_ENTRY *pEntry; + ULONG i; + + pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE; + + // + // walk through MAC table, see if need to change AP's TX rate toward each entry + // + for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) + { + pEntry = &pAd->MacTab.Content[i]; + + // check if this entry need to switch rate automatically + if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE) + continue; + + if (INFRA_ON(pAd) && (i == 1)) + Rssi = RTMPMaxRssi(pAd, + pAd->StaCfg.RssiSample.AvgRssi0, + pAd->StaCfg.RssiSample.AvgRssi1, + pAd->StaCfg.RssiSample.AvgRssi2); + else + Rssi = RTMPMaxRssi(pAd, + pEntry->RssiSample.AvgRssi0, + pEntry->RssiSample.AvgRssi1, + pEntry->RssiSample.AvgRssi2); + + CurrRateIdx = pAd->CommonCfg.TxRateIndex; + + MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx); + + // decide the next upgrade rate and downgrade rate, if any + if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) + { + UpRateIdx = CurrRateIdx + 1; + DownRateIdx = CurrRateIdx -1; + } + else if (CurrRateIdx == 0) { UpRateIdx = CurrRateIdx + 1; DownRateIdx = CurrRateIdx; @@ -2146,329 +2367,128 @@ VOID MlmeDynamicTxRateSwitching( TrainDown = pCurrTxRate->TrainDown; } - //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction; + if (pAd->MacTab.Size == 1) + { + // Update statistic counter + RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); + RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); - // - // Keep the last time TxRateChangeAction status. - // - pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction; + TxRetransmit = StaTx1.field.TxRetransmit; + TxSuccess = StaTx1.field.TxSuccess; + TxFailCount = TxStaCnt0.field.TxFailCount; + TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount; + + pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; + pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; + pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount; + pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess; + pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit; + pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount; + + if (TxTotalCnt) + TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt; + } + else + { + TxTotalCnt = pEntry->OneSecTxNoRetryOkCount + + pEntry->OneSecTxRetryOkCount + + pEntry->OneSecTxFailCount; + if (TxTotalCnt) + TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt; + } // // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI // (criteria copied from RT2500 for Netopia case) // - if (TxTotalCnt <= 15) + if (TxTotalCnt <= 12) { - CHAR idx = 0; - UCHAR TxRateIdx; - //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0; - UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0; - UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0; - UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3 + NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); - // check the existence and index of each needed MCS - while (idx < pTable[0]) + if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx)) { - pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5]; + pAd->CommonCfg.TxRateIndex = DownRateIdx; + pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; + } + else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx)) + { + pAd->CommonCfg.TxRateIndex = UpRateIdx; + } - if (pCurrTxRate->CurrMCS == MCS_0) - { - MCS0 = idx; - } - else if (pCurrTxRate->CurrMCS == MCS_1) - { - MCS1 = idx; - } - else if (pCurrTxRate->CurrMCS == MCS_2) - { - MCS2 = idx; - } - else if (pCurrTxRate->CurrMCS == MCS_3) - { - MCS3 = idx; - } - else if (pCurrTxRate->CurrMCS == MCS_4) - { - MCS4 = idx; - } - else if (pCurrTxRate->CurrMCS == MCS_5) - { - MCS5 = idx; - } - else if (pCurrTxRate->CurrMCS == MCS_6) - { - MCS6 = idx; - } - //else if (pCurrTxRate->CurrMCS == MCS_7) - else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) // prevent the highest MCS using short GI when 1T and low throughput - { - MCS7 = idx; - } - else if (pCurrTxRate->CurrMCS == MCS_12) - { - MCS12 = idx; - } - else if (pCurrTxRate->CurrMCS == MCS_13) - { - MCS13 = idx; - } - else if (pCurrTxRate->CurrMCS == MCS_14) + DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n")); + return; + } + + do + { + ULONG OneSecTxNoRetryOKRationCount; + + if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0) + ratio = 5; + else + ratio = 4; + + // downgrade TX quality if PER >= Rate-Down threshold + if (TxErrorRatio >= TrainDown) + { + pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; + } + + pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio; + + OneSecTxNoRetryOKRationCount = (TxSuccess * ratio); + + // perform DRS - consider TxRate Down first, then rate up. + if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx)) + { + if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount) { - MCS14 = idx; + pAd->CommonCfg.TxRateIndex = DownRateIdx; + pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; + } - 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 + + } + else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx)) + { + if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown)) { - MCS15 = idx; + } - else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3 + else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount) { - MCS20 = idx; + pAd->CommonCfg.TxRateIndex = UpRateIdx; } - else if (pCurrTxRate->CurrMCS == MCS_21) - { - MCS21 = idx; - } - else if (pCurrTxRate->CurrMCS == MCS_22) - { - MCS22 = idx; - } - else if (pCurrTxRate->CurrMCS == MCS_23) - { - MCS23 = idx; - } - idx ++; - } - - if (pAd->LatchRfRegs.Channel <= 14) - { - if (pAd->NicConfig2.field.ExternalLNAForG) - { - RssiOffset = 2; - } - else - { - RssiOffset = 5; - } - } - else - { - if (pAd->NicConfig2.field.ExternalLNAForA) - { - RssiOffset = 5; - } - else - { - RssiOffset = 8; - } - } - - /*if (MCS15)*/ - if ((pTable == RateSwitchTable11BGN3S) || - (pTable == RateSwitchTable11N3S) || - (pTable == RateSwitchTable)) - {// N mode with 3 stream // 3*3 - if (MCS23 && (Rssi >= -70)) - TxRateIdx = MCS15; - else if (MCS22 && (Rssi >= -72)) - TxRateIdx = MCS14; - else if (MCS21 && (Rssi >= -76)) - TxRateIdx = MCS13; - else if (MCS20 && (Rssi >= -78)) - TxRateIdx = MCS12; - else if (MCS4 && (Rssi >= -82)) - TxRateIdx = MCS4; - else if (MCS3 && (Rssi >= -84)) - TxRateIdx = MCS3; - else if (MCS2 && (Rssi >= -86)) - TxRateIdx = MCS2; - else if (MCS1 && (Rssi >= -88)) - TxRateIdx = MCS1; - else - TxRateIdx = MCS0; - } - else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3 - {// N mode with 2 stream - if (MCS15 && (Rssi >= (-70+RssiOffset))) - TxRateIdx = MCS15; - else if (MCS14 && (Rssi >= (-72+RssiOffset))) - TxRateIdx = MCS14; - else if (MCS13 && (Rssi >= (-76+RssiOffset))) - TxRateIdx = MCS13; - else if (MCS12 && (Rssi >= (-78+RssiOffset))) - TxRateIdx = MCS12; - else if (MCS4 && (Rssi >= (-82+RssiOffset))) - TxRateIdx = MCS4; - else if (MCS3 && (Rssi >= (-84+RssiOffset))) - TxRateIdx = MCS3; - else if (MCS2 && (Rssi >= (-86+RssiOffset))) - TxRateIdx = MCS2; - else if (MCS1 && (Rssi >= (-88+RssiOffset))) - TxRateIdx = MCS1; - else - TxRateIdx = MCS0; - } - else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S)) - {// N mode with 1 stream - if (MCS7 && (Rssi > (-72+RssiOffset))) - TxRateIdx = MCS7; - else if (MCS6 && (Rssi > (-74+RssiOffset))) - TxRateIdx = MCS6; - else if (MCS5 && (Rssi > (-77+RssiOffset))) - TxRateIdx = MCS5; - else if (MCS4 && (Rssi > (-79+RssiOffset))) - TxRateIdx = MCS4; - else if (MCS3 && (Rssi > (-81+RssiOffset))) - TxRateIdx = MCS3; - else if (MCS2 && (Rssi > (-83+RssiOffset))) - TxRateIdx = MCS2; - else if (MCS1 && (Rssi > (-86+RssiOffset))) - TxRateIdx = MCS1; - else - TxRateIdx = MCS0; - } - else - {// Legacy mode - if (MCS7 && (Rssi > -70)) - TxRateIdx = MCS7; - else if (MCS6 && (Rssi > -74)) - TxRateIdx = MCS6; - else if (MCS5 && (Rssi > -78)) - TxRateIdx = MCS5; - else if (MCS4 && (Rssi > -82)) - TxRateIdx = MCS4; - else if (MCS4 == 0) // for B-only mode - TxRateIdx = MCS3; - else if (MCS3 && (Rssi > -85)) - TxRateIdx = MCS3; - else if (MCS2 && (Rssi > -87)) - TxRateIdx = MCS2; - else if (MCS1 && (Rssi > -90)) - TxRateIdx = MCS1; - else - TxRateIdx = MCS0; - } - - { - pEntry->CurrTxRateIndex = TxRateIdx; - pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5]; - MlmeSetTxRate(pAd, pEntry, pNextTxRate); } - - NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); - NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); - pEntry->fLastSecAccordingRSSI = TRUE; - // reset all OneSecTx counters - RESET_ONE_SEC_TX_CNT(pEntry); - - continue; - } - - if (pEntry->fLastSecAccordingRSSI == TRUE) - { - pEntry->fLastSecAccordingRSSI = FALSE; - pEntry->LastSecTxRateChangeAction = 0; - // reset all OneSecTx counters - RESET_ONE_SEC_TX_CNT(pEntry); - - continue; - } - - do - { - BOOLEAN bTrainUpDown = FALSE; - - pEntry->CurrTxRateStableTime ++; - - // downgrade TX quality if PER >= Rate-Down threshold - if (TxErrorRatio >= TrainDown) - { - bTrainUpDown = TRUE; - pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; - } - // upgrade TX quality if PER <= Rate-Up threshold - else if (TxErrorRatio <= TrainUp) - { - bTrainUpDown = TRUE; - bUpgradeQuality = TRUE; - if (pEntry->TxQuality[CurrRateIdx]) - pEntry->TxQuality[CurrRateIdx] --; // quality very good in CurrRate - - if (pEntry->TxRateUpPenalty) - pEntry->TxRateUpPenalty --; - else if (pEntry->TxQuality[UpRateIdx]) - pEntry->TxQuality[UpRateIdx] --; // may improve next UP rate's quality - } - - pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio; - - if (bTrainUpDown) - { - // perform DRS - consider TxRate Down first, then rate up. - if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND)) - { - pEntry->CurrTxRateIndex = DownRateIdx; - } - else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0)) - { - pEntry->CurrTxRateIndex = UpRateIdx; - } - } - } while (FALSE); + }while (FALSE); // if rate-up happen, clear all bad history of all TX rates - if (pEntry->CurrTxRateIndex > CurrRateIdx) + if (pAd->CommonCfg.TxRateIndex > CurrRateIdx) { - pEntry->CurrTxRateStableTime = 0; - pEntry->TxRateUpPenalty = 0; - pEntry->LastSecTxRateChangeAction = 1; // rate UP - NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); - NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); - - // - // For TxRate fast train up - // - if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) - { - RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); - - pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE; - } + pAd->DrsCounters.TxRateUpPenalty = 0; + NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); + NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); bTxRateChanged = TRUE; } // if rate-down happen, only clear DownRate's bad history - else if (pEntry->CurrTxRateIndex < CurrRateIdx) + else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx) { - pEntry->CurrTxRateStableTime = 0; - pEntry->TxRateUpPenalty = 0; // no penalty - pEntry->LastSecTxRateChangeAction = 2; // rate DOWN - pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0; - pEntry->PER[pEntry->CurrTxRateIndex] = 0; - - // - // For TxRate fast train down - // - if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) - { - RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); + DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex)); - pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE; - } + pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty + pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0; + pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0; bTxRateChanged = TRUE; } else { - pEntry->LastSecTxRateChangeAction = 0; // rate no change bTxRateChanged = FALSE; } - pEntry->LastTxOkCount = TxSuccess; - - // reset all OneSecTx counters - RESET_ONE_SEC_TX_CNT(pEntry); - - pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5]; + pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5]; if (bTxRateChanged && pNextTxRate) { MlmeSetTxRate(pAd, pEntry, pNextTxRate); @@ -2477,262 +2497,19 @@ VOID MlmeDynamicTxRateSwitching( } /* - ======================================================================== - Routine Description: - Station side, Auto TxRate faster train up timer call back function. - - Arguments: - SystemSpecific1 - Not used. - FunctionContext - Pointer to our Adapter context. - SystemSpecific2 - Not used. - SystemSpecific3 - Not used. - - Return Value: - None - - ======================================================================== -*/ -VOID StaQuickResponeForRateUpExec( - IN PVOID SystemSpecific1, - IN PVOID FunctionContext, - IN PVOID SystemSpecific2, - IN PVOID SystemSpecific3) -{ - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext; - UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0; - ULONG TxTotalCnt; - ULONG TxErrorRatio = 0; -#ifdef RT2860 - BOOLEAN bTxRateChanged = TRUE; //, bUpgradeQuality = FALSE; -#endif -#ifdef RT2870 - BOOLEAN bTxRateChanged; //, bUpgradeQuality = FALSE; -#endif - PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL; - PUCHAR pTable; - UCHAR TableSize = 0; - UCHAR InitTxRateIdx = 0, TrainUp, TrainDown; - TX_STA_CNT1_STRUC StaTx1; - TX_STA_CNT0_STRUC TxStaCnt0; - CHAR Rssi, ratio; - ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0; - MAC_TABLE_ENTRY *pEntry; - ULONG i; - - pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE; - - // - // walk through MAC table, see if need to change AP's TX rate toward each entry - // - for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) - { - pEntry = &pAd->MacTab.Content[i]; - - // check if this entry need to switch rate automatically - if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE) - continue; - -#ifdef RT2860 - //Rssi = RTMPMaxRssi(pAd, (CHAR)pAd->StaCfg.AvgRssi0, (CHAR)pAd->StaCfg.AvgRssi1, (CHAR)pAd->StaCfg.AvgRssi2); - if (pAd->Antenna.field.TxPath > 1) - Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1; - else - Rssi = pAd->StaCfg.RssiSample.AvgRssi0; -#endif -#ifdef RT2870 - if (INFRA_ON(pAd) && (i == 1)) - Rssi = RTMPMaxRssi(pAd, - pAd->StaCfg.RssiSample.AvgRssi0, - pAd->StaCfg.RssiSample.AvgRssi1, - pAd->StaCfg.RssiSample.AvgRssi2); - else - Rssi = RTMPMaxRssi(pAd, - pEntry->RssiSample.AvgRssi0, - pEntry->RssiSample.AvgRssi1, - pEntry->RssiSample.AvgRssi2); -#endif - - CurrRateIdx = pAd->CommonCfg.TxRateIndex; - - MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx); - - // decide the next upgrade rate and downgrade rate, if any - if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) - { - UpRateIdx = CurrRateIdx + 1; - DownRateIdx = CurrRateIdx -1; - } - else if (CurrRateIdx == 0) - { - UpRateIdx = CurrRateIdx + 1; - DownRateIdx = CurrRateIdx; - } - else if (CurrRateIdx == (TableSize - 1)) - { - UpRateIdx = CurrRateIdx; - DownRateIdx = CurrRateIdx - 1; - } - - pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5]; - - if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) - { - TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1)); - TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1)); - } - else - { - TrainUp = pCurrTxRate->TrainUp; - TrainDown = pCurrTxRate->TrainDown; - } - - if (pAd->MacTab.Size == 1) - { - // Update statistic counter - RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); - RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); - - TxRetransmit = StaTx1.field.TxRetransmit; - TxSuccess = StaTx1.field.TxSuccess; - TxFailCount = TxStaCnt0.field.TxFailCount; - TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount; - - pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; - pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; - pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount; - pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess; - pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit; - pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount; - - if (TxTotalCnt) - TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt; - } - else - { - TxTotalCnt = pEntry->OneSecTxNoRetryOkCount + - pEntry->OneSecTxRetryOkCount + - pEntry->OneSecTxFailCount; - - if (TxTotalCnt) - TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt; - } - - - // - // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI - // (criteria copied from RT2500 for Netopia case) - // - if (TxTotalCnt <= 12) - { - NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); - NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); - - if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx)) - { - pAd->CommonCfg.TxRateIndex = DownRateIdx; - pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; - } - else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx)) - { - pAd->CommonCfg.TxRateIndex = UpRateIdx; - } - - DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n")); - return; - } - - do - { - ULONG OneSecTxNoRetryOKRationCount; - - if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0) - ratio = 5; - else - ratio = 4; - - // downgrade TX quality if PER >= Rate-Down threshold - if (TxErrorRatio >= TrainDown) - { - pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; - } - - pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio; - - OneSecTxNoRetryOKRationCount = (TxSuccess * ratio); - - // perform DRS - consider TxRate Down first, then rate up. - if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx)) - { - if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount) - { - pAd->CommonCfg.TxRateIndex = DownRateIdx; - pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND; - - } - - } - else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx)) - { - if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown)) - { - - } - else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount) - { - pAd->CommonCfg.TxRateIndex = UpRateIdx; - } - } - }while (FALSE); - - // if rate-up happen, clear all bad history of all TX rates - if (pAd->CommonCfg.TxRateIndex > CurrRateIdx) - { - pAd->DrsCounters.TxRateUpPenalty = 0; - NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH); - NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH); -#ifdef RT2870 - bTxRateChanged = TRUE; -#endif - } - // if rate-down happen, only clear DownRate's bad history - else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx) - { - DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex)); - - pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty - pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0; - pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0; -#ifdef RT2870 - bTxRateChanged = TRUE; -#endif - } - else - { - bTxRateChanged = FALSE; - } - - pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5]; - if (bTxRateChanged && pNextTxRate) - { - MlmeSetTxRate(pAd, pEntry, pNextTxRate); - } - } -} - -/* - ========================================================================== - Description: - This routine is executed periodically inside MlmePeriodicExec() after - association with an AP. - It checks if StaCfg.Psm is consistent with user policy (recorded in - StaCfg.WindowsPowerMode). If not, enforce user policy. However, - there're some conditions to consider: - 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all - the time when Mibss==TRUE - 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE - if outgoing traffic available in TxRing or MgmtRing. - Output: - 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched + ========================================================================== + Description: + This routine is executed periodically inside MlmePeriodicExec() after + association with an AP. + It checks if StaCfg.Psm is consistent with user policy (recorded in + StaCfg.WindowsPowerMode). If not, enforce user policy. However, + there're some conditions to consider: + 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all + the time when Mibss==TRUE + 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE + if outgoing traffic available in TxRing or MgmtRing. + Output: + 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched IRQL = DISPATCH_LEVEL @@ -2750,34 +2527,21 @@ VOID MlmeCheckPsmChange( // 3. but current psm is not in PWR_SAVE // 4. CNTL state machine is not doing SCANning // 5. no TX SUCCESS event for the past 1-sec period -#ifdef NDIS51_MINIPORT - if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery) - PowerMode = pAd->StaCfg.WindowsBatteryPowerMode; - else -#endif PowerMode = pAd->StaCfg.WindowsPowerMode; if (INFRA_ON(pAd) && (PowerMode != Ndis802_11PowerModeCAM) && (pAd->StaCfg.Psm == PWR_ACTIVE) && -#ifdef RT2860 - RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)) -#else - (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)) -#endif +// (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) + (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)&& + RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP) + /*&& + (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) && + (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/) { - // add by johnli, use Rx OK data count per second to calculate throughput - // If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria - // Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps - if (((pAd->StaCfg.HTPhyMode.field.MCS <= 3) && - (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)100)) || - ((pAd->StaCfg.HTPhyMode.field.MCS > 3) && - (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)400))) - { - // Get this time NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime); pAd->RalinkCounters.RxCountSinceLastNULL = 0; - MlmeSetPsmBit(pAd, PWR_SAVE); + RTMP_SET_PSM_BIT(pAd, PWR_SAVE); if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) { RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE); @@ -2787,7 +2551,6 @@ VOID MlmeCheckPsmChange( RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); } } - } } // IRQL = PASSIVE_LEVEL @@ -2806,12 +2569,124 @@ VOID MlmeSetPsmBit( DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm)); } -// IRQL = DISPATCH_LEVEL -VOID MlmeSetTxPreamble( - IN PRTMP_ADAPTER pAd, - IN USHORT TxPreamble) -{ - AUTO_RSP_CFG_STRUC csr4; +/* + ========================================================================== + Description: + This routine calculates TxPER, RxPER of the past N-sec period. And + according to the calculation result, ChannelQuality is calculated here + to decide if current AP is still doing the job. + + If ChannelQuality is not good, a ROAMing attempt may be tried later. + Output: + StaCfg.ChannelQuality - 0..100 + + IRQL = DISPATCH_LEVEL + + NOTE: This routine decide channle quality based on RX CRC error ratio. + Caller should make sure a function call to NICUpdateRawCounters(pAd) + is performed right before this routine, so that this routine can decide + channel quality based on the most up-to-date information + ========================================================================== + */ +VOID MlmeCalculateChannelQuality( + IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pMacEntry, + IN ULONG Now32) +{ + ULONG TxOkCnt, TxCnt, TxPER, TxPRR; + ULONG RxCnt, RxPER; + UCHAR NorRssi; + CHAR MaxRssi; + RSSI_SAMPLE *pRssiSample = NULL; + UINT32 OneSecTxNoRetryOkCount = 0; + UINT32 OneSecTxRetryOkCount = 0; + UINT32 OneSecTxFailCount = 0; + UINT32 OneSecRxOkCnt = 0; + UINT32 OneSecRxFcsErrCnt = 0; + ULONG ChannelQuality = 0; // 0..100, Channel Quality Indication for Roaming + ULONG BeaconLostTime = pAd->StaCfg.BeaconLostTime; + + + if (pAd->OpMode == OPMODE_STA) + { + pRssiSample = &pAd->StaCfg.RssiSample; + OneSecTxNoRetryOkCount = pAd->RalinkCounters.OneSecTxNoRetryOkCount; + OneSecTxRetryOkCount = pAd->RalinkCounters.OneSecTxRetryOkCount; + OneSecTxFailCount = pAd->RalinkCounters.OneSecTxFailCount; + OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt; + OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt; + } + + MaxRssi = RTMPMaxRssi(pAd, pRssiSample->LastRssi0, + pRssiSample->LastRssi1, + pRssiSample->LastRssi2); + + // + // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics + // + TxOkCnt = OneSecTxNoRetryOkCount + OneSecTxRetryOkCount; + TxCnt = TxOkCnt + OneSecTxFailCount; + if (TxCnt < 5) + { + TxPER = 0; + TxPRR = 0; + } + else + { + TxPER = (OneSecTxFailCount * 100) / TxCnt; + TxPRR = ((TxCnt - OneSecTxNoRetryOkCount) * 100) / TxCnt; + } + + // + // calculate RX PER - don't take RxPER into consideration if too few sample + // + RxCnt = OneSecRxOkCnt + OneSecRxFcsErrCnt; + if (RxCnt < 5) + RxPER = 0; + else + RxPER = (OneSecRxFcsErrCnt * 100) / RxCnt; + + // + // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER + // + if ((pAd->OpMode == OPMODE_STA) && + INFRA_ON(pAd) && + (OneSecTxNoRetryOkCount < 2) && // no heavy traffic + ((pAd->StaCfg.LastBeaconRxTime + BeaconLostTime) < Now32)) + { + DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt)); + ChannelQuality = 0; + } + else + { + // Normalize Rssi + if (MaxRssi > -40) + NorRssi = 100; + else if (MaxRssi < -90) + NorRssi = 0; + else + NorRssi = (MaxRssi + 90) * 2; + + // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0) + ChannelQuality = (RSSI_WEIGHTING * NorRssi + + TX_WEIGHTING * (100 - TxPRR) + + RX_WEIGHTING* (100 - RxPER)) / 100; + } + + + if (pAd->OpMode == OPMODE_STA) + pAd->Mlme.ChannelQuality = (ChannelQuality > 100) ? 100 : ChannelQuality; + + +} + + +// IRQL = DISPATCH_LEVEL +VOID MlmeSetTxPreamble( + IN PRTMP_ADAPTER pAd, + IN USHORT TxPreamble) +{ + AUTO_RSP_CFG_STRUC csr4; // // Always use Long preamble before verifiation short preamble functionality works well. @@ -2968,23 +2843,29 @@ VOID MlmeUpdateTxRates( // specified; otherwise disabled if (num <= 1) { + //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); + //pAd->CommonCfg.bAutoTxRateSwitch = FALSE; *auto_rate_cur_p = FALSE; } else { + //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); + //pAd->CommonCfg.bAutoTxRateSwitch = TRUE; *auto_rate_cur_p = TRUE; } -#if 1 if (HtMcs != MCS_AUTO) { + //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); + //pAd->CommonCfg.bAutoTxRateSwitch = FALSE; *auto_rate_cur_p = FALSE; } else { + //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); + //pAd->CommonCfg.bAutoTxRateSwitch = TRUE; *auto_rate_cur_p = TRUE; } -#endif if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) { @@ -2994,4657 +2875,2250 @@ VOID MlmeUpdateTxRates( ExtRateLen = pAd->StaActive.ExtRateLen; } else - { - pSupRate = &pAd->CommonCfg.SupRate[0]; - pExtRate = &pAd->CommonCfg.ExtRate[0]; - SupRateLen = pAd->CommonCfg.SupRateLen; - ExtRateLen = pAd->CommonCfg.ExtRateLen; - } - - // find max supported rate - for (i=0; i Rate) MinSupport = Rate; - } - - for (i=0; i Rate) MinSupport = Rate; - } - - RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap); - - // calculate the exptected ACK rate for each TX rate. This info is used to caculate - // the DURATION field of outgoing uniicast DATA/MGMT frame - for (i=0; iCommonCfg.ExpectedACKRate[i] = CurrBasicRate; - } - - DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire])); - // max tx rate = min {max desire rate, max supported rate} - if (MaxSupport < MaxDesire) - pAd->CommonCfg.MaxTxRate = MaxSupport; - else - pAd->CommonCfg.MaxTxRate = MaxDesire; - - pAd->CommonCfg.MinTxRate = MinSupport; - if (*auto_rate_cur_p) - { - short dbm = 0; - - dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta; - - if (bLinkUp == TRUE) - pAd->CommonCfg.TxRate = RATE_24; - else - pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate; - - if (dbm < -75) - pAd->CommonCfg.TxRate = RATE_11; - else if (dbm < -70) - pAd->CommonCfg.TxRate = RATE_24; - - // should never exceed MaxTxRate (consider 11B-only mode) - if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate) - pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate; - - pAd->CommonCfg.TxRateIndex = 0; - } - else - { - pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate; - pHtPhy->field.MCS = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate; - pHtPhy->field.MODE = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK; - - pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC = pHtPhy->field.STBC; - pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI; - pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS = pHtPhy->field.MCS; - pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE = pHtPhy->field.MODE; - } - - if (pAd->CommonCfg.TxRate <= RATE_11) - { - pMaxHtPhy->field.MODE = MODE_CCK; - pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate; - pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate; - } - else - { - pMaxHtPhy->field.MODE = MODE_OFDM; - pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate]; - if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54)) - {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];} - else - {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;} - } - - pHtPhy->word = (pMaxHtPhy->word); - if (bLinkUp && (pAd->OpMode == OPMODE_STA)) - { - pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word; - pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word; - pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word; - } - else - { - switch (pAd->CommonCfg.PhyMode) - { - case PHY_11BG_MIXED: - case PHY_11B: - case PHY_11BGN_MIXED: - pAd->CommonCfg.MlmeRate = RATE_1; - pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; - pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1; - pAd->CommonCfg.RtsRate = RATE_11; - break; - case PHY_11G: - case PHY_11A: - case PHY_11AGN_MIXED: - case PHY_11GN_MIXED: - case PHY_11N_2_4G: - case PHY_11AN_MIXED: - case PHY_11N_5G: - pAd->CommonCfg.MlmeRate = RATE_6; - pAd->CommonCfg.RtsRate = RATE_6; - pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; - pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; - break; - case PHY_11ABG_MIXED: - case PHY_11ABGN_MIXED: - if (pAd->CommonCfg.Channel <= 14) - { - pAd->CommonCfg.MlmeRate = RATE_1; - pAd->CommonCfg.RtsRate = RATE_1; - pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; - pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1; - } - else - { - pAd->CommonCfg.MlmeRate = RATE_6; - pAd->CommonCfg.RtsRate = RATE_6; - pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; - pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; - } - break; - default: // error - pAd->CommonCfg.MlmeRate = RATE_6; - pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; - pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; - pAd->CommonCfg.RtsRate = RATE_1; - break; - } - // - // Keep Basic Mlme Rate. - // - pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word; - if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM) - pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24]; - else - pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1; - pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate; - } - - DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n", - RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate], - /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p)); - DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n", - RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap)); - DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n", - 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 )); -} - -/* - ========================================================================== - Description: - This function update HT Rate setting. - Input Wcid value is valid for 2 case : - 1. it's used for Station in infra mode that copy AP rate to Mactable. - 2. OR Station in adhoc mode to copy peer's HT rate to Mactable. - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -VOID MlmeUpdateHtTxRates( - IN PRTMP_ADAPTER pAd, - IN UCHAR apidx) -{ - UCHAR StbcMcs; //j, StbcMcs, bitmask; - CHAR i; // 3*3 - RT_HT_CAPABILITY *pRtHtCap = NULL; - RT_HT_PHY_INFO *pActiveHtPhy = NULL; - ULONG BasicMCS; - UCHAR j, bitmask; - PRT_HT_PHY_INFO pDesireHtPhy = NULL; - PHTTRANSMIT_SETTING pHtPhy = NULL; - PHTTRANSMIT_SETTING pMaxHtPhy = NULL; - PHTTRANSMIT_SETTING pMinHtPhy = NULL; - BOOLEAN *auto_rate_cur_p; - - DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n")); - - auto_rate_cur_p = NULL; - - { - pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo; - pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo; - pHtPhy = &pAd->StaCfg.HTPhyMode; - pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode; - pMinHtPhy = &pAd->StaCfg.MinHTPhyMode; - - auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch; - } - - if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) - { - if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) - return; - - pRtHtCap = &pAd->StaActive.SupportedHtPhy; - pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo; - StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs; - BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16); - if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2)) - pMaxHtPhy->field.STBC = STBC_USE; - else - pMaxHtPhy->field.STBC = STBC_NONE; - } - else - { - if (pDesireHtPhy->bHtEnable == FALSE) - return; - - pRtHtCap = &pAd->CommonCfg.DesiredHtPhy; - StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs; - BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16); - if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2)) - pMaxHtPhy->field.STBC = STBC_USE; - else - pMaxHtPhy->field.STBC = STBC_NONE; - } - - // Decide MAX ht rate. - if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF)) - pMaxHtPhy->field.MODE = MODE_HTGREENFIELD; - else - pMaxHtPhy->field.MODE = MODE_HTMIX; - - if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth)) - pMaxHtPhy->field.BW = BW_40; - else - pMaxHtPhy->field.BW = BW_20; - - if (pMaxHtPhy->field.BW == BW_20) - pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20); - else - pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40); - - for (i=23; i>=0; i--) // 3*3 - { - j = i/8; - bitmask = (1<<(i-(j*8))); - - if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask)) - { - pMaxHtPhy->field.MCS = i; - break; - } - - if (i==0) - break; - } - - // Copy MIN ht rate. rt2860??? - pMinHtPhy->field.BW = BW_20; - pMinHtPhy->field.MCS = 0; - pMinHtPhy->field.STBC = 0; - pMinHtPhy->field.ShortGI = 0; - //If STA assigns fixed rate. update to fixed here. - if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff)) - { - if (pDesireHtPhy->MCSSet[4] != 0) - { - pMaxHtPhy->field.MCS = 32; - pMinHtPhy->field.MCS = 32; - DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS)); - } - - for (i=23; (CHAR)i >= 0; i--) // 3*3 - { - j = i/8; - bitmask = (1<<(i-(j*8))); - if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask)) - { - pMaxHtPhy->field.MCS = i; - pMinHtPhy->field.MCS = i; - break; - } - if (i==0) - break; - } - } - - // Decide ht rate - pHtPhy->field.STBC = pMaxHtPhy->field.STBC; - pHtPhy->field.BW = pMaxHtPhy->field.BW; - pHtPhy->field.MODE = pMaxHtPhy->field.MODE; - pHtPhy->field.MCS = pMaxHtPhy->field.MCS; - pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI; - - // use default now. rt2860 - if (pDesireHtPhy->MCSSet[0] != 0xff) - *auto_rate_cur_p = FALSE; - else - *auto_rate_cur_p = TRUE; - - DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize )); - DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS, - pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE)); - DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n")); -} - -// IRQL = DISPATCH_LEVEL -VOID MlmeRadioOff( - IN PRTMP_ADAPTER pAd) -{ - RT28XX_MLME_RADIO_OFF(pAd); -} - -// IRQL = DISPATCH_LEVEL -VOID MlmeRadioOn( - IN PRTMP_ADAPTER pAd) -{ - RT28XX_MLME_RADIO_ON(pAd); -} - -// =========================================================================================== -// bss_table.c -// =========================================================================================== - - -/*! \brief initialize BSS table - * \param p_tab pointer to the table - * \return none - * \pre - * \post - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - */ -VOID BssTableInit( - IN BSS_TABLE *Tab) -{ - int i; - - Tab->BssNr = 0; - Tab->BssOverlapNr = 0; - for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++) - { - NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY)); - Tab->BssEntry[i].Rssi = -127; // initial the rssi as a minimum value - } -} - -VOID BATableInit( - IN PRTMP_ADAPTER pAd, - IN BA_TABLE *Tab) -{ - int i; - - Tab->numAsOriginator = 0; - Tab->numAsRecipient = 0; - NdisAllocateSpinLock(&pAd->BATabLock); - for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) - { - Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE; - NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock)); - } - for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++) - { - Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE; - } -} - -/*! \brief search the BSS table by SSID - * \param p_tab pointer to the bss table - * \param ssid SSID string - * \return index of the table, BSS_NOT_FOUND if not in the table - * \pre - * \post - * \note search by sequential search - - IRQL = DISPATCH_LEVEL - - */ -ULONG BssTableSearch( - IN BSS_TABLE *Tab, - IN PUCHAR pBssid, - IN UCHAR Channel) -{ - UCHAR i; - - for (i = 0; i < Tab->BssNr; i++) - { - // - // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. - // We should distinguish this case. - // - if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) || - ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) && - MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)) - { - return i; - } - } - return (ULONG)BSS_NOT_FOUND; -} - -ULONG BssSsidTableSearch( - IN BSS_TABLE *Tab, - IN PUCHAR pBssid, - IN PUCHAR pSsid, - IN UCHAR SsidLen, - IN UCHAR Channel) -{ - UCHAR i; - - for (i = 0; i < Tab->BssNr; i++) - { - // - // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. - // We should distinguish this case. - // - if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) || - ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) && - MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) && - SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen)) - { - return i; - } - } - return (ULONG)BSS_NOT_FOUND; -} - -ULONG BssTableSearchWithSSID( - IN BSS_TABLE *Tab, - IN PUCHAR Bssid, - IN PUCHAR pSsid, - IN UCHAR SsidLen, - IN UCHAR Channel) -{ - UCHAR i; - - for (i = 0; i < Tab->BssNr; i++) - { - if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) || - ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) && - MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) && - (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) || - (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) || - (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen)))) - { - return i; - } - } - return (ULONG)BSS_NOT_FOUND; -} - -// IRQL = DISPATCH_LEVEL -VOID BssTableDeleteEntry( - IN OUT BSS_TABLE *Tab, - IN PUCHAR pBssid, - IN UCHAR Channel) -{ - UCHAR i, j; - - for (i = 0; i < Tab->BssNr; i++) - { - if ((Tab->BssEntry[i].Channel == Channel) && - (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))) - { - for (j = i; j < Tab->BssNr - 1; j++) - { - NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY)); - } - NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY)); - Tab->BssNr -= 1; - return; - } - } -} - -/* - ======================================================================== - Routine Description: - Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed. - - Arguments: - // IRQL = DISPATCH_LEVEL - ======================================================================== -*/ -VOID BATableDeleteORIEntry( - IN OUT PRTMP_ADAPTER pAd, - IN BA_ORI_ENTRY *pBAORIEntry) -{ - - if (pBAORIEntry->ORI_BA_Status != Originator_NONE) - { - NdisAcquireSpinLock(&pAd->BATabLock); - if (pBAORIEntry->ORI_BA_Status == Originator_Done) - { - pAd->BATable.numAsOriginator -= 1; - DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient)); - // Erase Bitmap flag. - } - pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) )); // If STA mode, erase flag here - pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0; // If STA mode, erase flag here - pBAORIEntry->ORI_BA_Status = Originator_NONE; - pBAORIEntry->Token = 1; - // Not clear Sequence here. - NdisReleaseSpinLock(&pAd->BATabLock); - } -} - -/*! \brief - * \param - * \return - * \pre - * \post - - IRQL = DISPATCH_LEVEL - - */ -VOID BssEntrySet( - IN PRTMP_ADAPTER pAd, - OUT BSS_ENTRY *pBss, - IN PUCHAR pBssid, - IN CHAR Ssid[], - IN UCHAR SsidLen, - IN UCHAR BssType, - IN USHORT BeaconPeriod, - IN PCF_PARM pCfParm, - IN USHORT AtimWin, - IN USHORT CapabilityInfo, - IN UCHAR SupRate[], - IN UCHAR SupRateLen, - IN UCHAR ExtRate[], - IN UCHAR ExtRateLen, - IN HT_CAPABILITY_IE *pHtCapability, - IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE - IN UCHAR HtCapabilityLen, - IN UCHAR AddHtInfoLen, - IN UCHAR NewExtChanOffset, - IN UCHAR Channel, - IN CHAR Rssi, - IN LARGE_INTEGER TimeStamp, - IN UCHAR CkipFlag, - IN PEDCA_PARM pEdcaParm, - IN PQOS_CAPABILITY_PARM pQosCapability, - IN PQBSS_LOAD_PARM pQbssLoad, - IN USHORT LengthVIE, - IN PNDIS_802_11_VARIABLE_IEs pVIE) -{ - COPY_MAC_ADDR(pBss->Bssid, pBssid); - // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID - pBss->Hidden = 1; - if (SsidLen > 0) - { - // For hidden SSID AP, it might send beacon with SSID len equal to 0 - // Or send beacon /probe response with SSID len matching real SSID length, - // but SSID is all zero. such as "00-00-00-00" with length 4. - // We have to prevent this case overwrite correct table - if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0) - { - NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID); - NdisMoveMemory(pBss->Ssid, Ssid, SsidLen); - pBss->SsidLen = SsidLen; - pBss->Hidden = 0; - } - } - else - pBss->SsidLen = 0; - pBss->BssType = BssType; - pBss->BeaconPeriod = BeaconPeriod; - if (BssType == BSS_INFRA) - { - if (pCfParm->bValid) - { - pBss->CfpCount = pCfParm->CfpCount; - pBss->CfpPeriod = pCfParm->CfpPeriod; - pBss->CfpMaxDuration = pCfParm->CfpMaxDuration; - pBss->CfpDurRemaining = pCfParm->CfpDurRemaining; - } - } - else - { - pBss->AtimWin = AtimWin; - } - - pBss->CapabilityInfo = CapabilityInfo; - // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES - // Combine with AuthMode, they will decide the connection methods. - pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo); - ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES); - if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES) - NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen); - else - NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES); - pBss->SupRateLen = SupRateLen; - ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES); - NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen); - NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen); - NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen); - pBss->NewExtChanOffset = NewExtChanOffset; - pBss->ExtRateLen = ExtRateLen; - pBss->Channel = Channel; - pBss->CentralChannel = Channel; - pBss->Rssi = Rssi; - // Update CkipFlag. if not exists, the value is 0x0 - pBss->CkipFlag = CkipFlag; - - // New for microsoft Fixed IEs - NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8); - pBss->FixIEs.BeaconInterval = BeaconPeriod; - pBss->FixIEs.Capabilities = CapabilityInfo; - - // New for microsoft Variable IEs - if (LengthVIE != 0) - { - pBss->VarIELen = LengthVIE; - NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen); - } - else - { - pBss->VarIELen = 0; - } - - pBss->AddHtInfoLen = 0; - pBss->HtCapabilityLen = 0; - - if (HtCapabilityLen> 0) - { - pBss->HtCapabilityLen = HtCapabilityLen; - NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen); - if (AddHtInfoLen > 0) - { - pBss->AddHtInfoLen = AddHtInfoLen; - NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen); - - if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) - { - pBss->CentralChannel = pAddHtInfo->ControlChan - 2; - } - else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) - { - pBss->CentralChannel = pAddHtInfo->ControlChan + 2; - } - } - } - - BssCipherParse(pBss); - - // new for QOS - if (pEdcaParm) - NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM)); - else - pBss->EdcaParm.bValid = FALSE; - if (pQosCapability) - NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM)); - else - pBss->QosCapability.bValid = FALSE; - if (pQbssLoad) - NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM)); - else - pBss->QbssLoad.bValid = FALSE; - - { - PEID_STRUCT pEid; - USHORT Length = 0; - - - NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN); - NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN); - - pEid = (PEID_STRUCT) pVIE; - - while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE) - { - switch(pEid->Eid) - { - case IE_WPA: - if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) - { - if ((pEid->Len + 2) > MAX_CUSTOM_LEN) - { - pBss->WpaIE.IELen = 0; - break; - } - pBss->WpaIE.IELen = pEid->Len + 2; - NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen); - } - break; - case IE_RSN: - if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)) - { - if ((pEid->Len + 2) > MAX_CUSTOM_LEN) - { - pBss->RsnIE.IELen = 0; - break; - } - pBss->RsnIE.IELen = pEid->Len + 2; - NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen); - } - break; - } - Length = Length + 2 + (USHORT)pEid->Len; // Eid[1] + Len[1]+ content[Len] - pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len); - } - } -} - -/*! - * \brief insert an entry into the bss table - * \param p_tab The BSS table - * \param Bssid BSSID - * \param ssid SSID - * \param ssid_len Length of SSID - * \param bss_type - * \param beacon_period - * \param timestamp - * \param p_cf - * \param atim_win - * \param cap - * \param rates - * \param rates_len - * \param channel_idx - * \return none - * \pre - * \post - * \note If SSID is identical, the old entry will be replaced by the new one - - IRQL = DISPATCH_LEVEL - - */ -ULONG BssTableSetEntry( - IN PRTMP_ADAPTER pAd, - OUT BSS_TABLE *Tab, - IN PUCHAR pBssid, - IN CHAR Ssid[], - IN UCHAR SsidLen, - IN UCHAR BssType, - IN USHORT BeaconPeriod, - IN CF_PARM *CfParm, - IN USHORT AtimWin, - IN USHORT CapabilityInfo, - IN UCHAR SupRate[], - IN UCHAR SupRateLen, - IN UCHAR ExtRate[], - IN UCHAR ExtRateLen, - IN HT_CAPABILITY_IE *pHtCapability, - IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE - IN UCHAR HtCapabilityLen, - IN UCHAR AddHtInfoLen, - IN UCHAR NewExtChanOffset, - IN UCHAR ChannelNo, - IN CHAR Rssi, - IN LARGE_INTEGER TimeStamp, - IN UCHAR CkipFlag, - IN PEDCA_PARM pEdcaParm, - IN PQOS_CAPABILITY_PARM pQosCapability, - IN PQBSS_LOAD_PARM pQbssLoad, - IN USHORT LengthVIE, - IN PNDIS_802_11_VARIABLE_IEs pVIE) -{ - ULONG Idx; - - Idx = BssTableSearchWithSSID(Tab, pBssid, Ssid, SsidLen, ChannelNo); - if (Idx == BSS_NOT_FOUND) - { - if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE) - { - // - // It may happen when BSS Table was full. - // The desired AP will not be added into BSS Table - // In this case, if we found the desired AP then overwrite BSS Table. - // - if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) - { - if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) || - SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen)) - { - Idx = Tab->BssOverlapNr; - BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin, - CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, - NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE); - Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE; - } - return Idx; - } - else - { - return BSS_NOT_FOUND; - } - } - Idx = Tab->BssNr; - BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin, - CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, - NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE); - Tab->BssNr++; - } - else - { - /* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */ - if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) || - (NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen))) - { - BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin, - CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, - NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE); - } - } - - return Idx; -} - -// IRQL = DISPATCH_LEVEL -VOID BssTableSsidSort( - IN PRTMP_ADAPTER pAd, - OUT BSS_TABLE *OutTab, - IN CHAR Ssid[], - IN UCHAR SsidLen) -{ - INT i; - BssTableInit(OutTab); - - for (i = 0; i < pAd->ScanTab.BssNr; i++) - { - BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i]; - BOOLEAN bIsHiddenApIncluded = FALSE; - - if (((pAd->CommonCfg.bIEEE80211H == 1) && - (pAd->MlmeAux.Channel > 14) && - RadarChannelCheck(pAd, pInBss->Channel)) - ) - { - if (pInBss->Hidden) - bIsHiddenApIncluded = TRUE; - } - - if ((pInBss->BssType == pAd->StaCfg.BssType) && - (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded)) - { - BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr]; - - // 2.4G/5G N only mode - if ((pInBss->HtCapabilityLen == 0) && - ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) - { - DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n")); - continue; - } - - // New for WPA2 - // Check the Authmode first - if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) - { - // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode - if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux)) - // None matched - continue; - - // Check cipher suite, AP must have more secured cipher than station setting - if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) - { - // If it's not mixed mode, we should only let BSS pass with the same encryption - if (pInBss->WPA.bMixMode == FALSE) - if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher) - continue; - - // check group cipher - if (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled && - pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled && - pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) - continue; - - // check pairwise cipher, skip if none matched - // If profile set to AES, let it pass without question. - // If profile set to TKIP, we must find one mateched - if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) && - (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) && - (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux)) - continue; - } - else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) - { - // If it's not mixed mode, we should only let BSS pass with the same encryption - if (pInBss->WPA2.bMixMode == FALSE) - if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher) - continue; - - // check group cipher - if (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled && - pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled && - pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher) - continue; - - // check pairwise cipher, skip if none matched - // If profile set to AES, let it pass without question. - // If profile set to TKIP, we must find one mateched - if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) && - (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) && - (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux)) - continue; - } - } - // Bss Type matched, SSID matched. - // We will check wepstatus for qualification Bss - else if (pAd->StaCfg.WepStatus != pInBss->WepStatus) - { - DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus)); - // - // For the SESv2 case, we will not qualify WepStatus. - // - if (!pInBss->bSES) - continue; - } - - // Since the AP is using hidden SSID, and we are trying to connect to ANY - // It definitely will fail. So, skip it. - // CCX also require not even try to connect it!! - if (SsidLen == 0) - continue; - - // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region - // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, - if ((pInBss->CentralChannel != pInBss->Channel) && - (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) - { - if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE) - { - pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; - SetCommonHT(pAd); - pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; - } - else - { - if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20) - { - SetCommonHT(pAd); - } - } - } - - // copy matching BSS from InTab to OutTab - NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY)); - - OutTab->BssNr++; - } - else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0)) - { - BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr]; - - // 2.4G/5G N only mode - if ((pInBss->HtCapabilityLen == 0) && - ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) - { - DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n")); - continue; - } - - // New for WPA2 - // Check the Authmode first - if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) - { - // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode - if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux)) - // None matched - continue; - - // Check cipher suite, AP must have more secured cipher than station setting - if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) - { - // If it's not mixed mode, we should only let BSS pass with the same encryption - if (pInBss->WPA.bMixMode == FALSE) - if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher) - continue; - - // check group cipher - if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) - continue; - - // check pairwise cipher, skip if none matched - // If profile set to AES, let it pass without question. - // If profile set to TKIP, we must find one mateched - if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) && - (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) && - (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux)) - continue; - } - else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) - { - // If it's not mixed mode, we should only let BSS pass with the same encryption - if (pInBss->WPA2.bMixMode == FALSE) - if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher) - continue; - - // check group cipher - if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher) - continue; - - // check pairwise cipher, skip if none matched - // If profile set to AES, let it pass without question. - // If profile set to TKIP, we must find one mateched - if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) && - (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) && - (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux)) - continue; - } - } - // Bss Type matched, SSID matched. - // We will check wepstatus for qualification Bss - else if (pAd->StaCfg.WepStatus != pInBss->WepStatus) - continue; - - // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region - // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, - if ((pInBss->CentralChannel != pInBss->Channel) && - (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) - { - if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE) - { - pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; - SetCommonHT(pAd); - pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; - } - } - - // copy matching BSS from InTab to OutTab - NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY)); - - OutTab->BssNr++; - } - - if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE) - break; - } - - BssTableSortByRssi(OutTab); -} - - -// IRQL = DISPATCH_LEVEL -VOID BssTableSortByRssi( - IN OUT BSS_TABLE *OutTab) -{ - INT i, j; - BSS_ENTRY TmpBss; - - for (i = 0; i < OutTab->BssNr - 1; i++) - { - for (j = i+1; j < OutTab->BssNr; j++) - { - if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi) - { - NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY)); - NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY)); - NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY)); - } - } - } -} - -VOID BssCipherParse( - IN OUT PBSS_ENTRY pBss) -{ - PEID_STRUCT pEid; - PUCHAR pTmp; - PRSN_IE_HEADER_STRUCT pRsnHeader; - PCIPHER_SUITE_STRUCT pCipher; - PAKM_SUITE_STRUCT pAKM; - USHORT Count; - INT Length; - NDIS_802_11_ENCRYPTION_STATUS TmpCipher; - - // - // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame. - // - if (pBss->Privacy) - { - pBss->WepStatus = Ndis802_11WEPEnabled; - } - else - { - pBss->WepStatus = Ndis802_11WEPDisabled; - } - // Set default to disable & open authentication before parsing variable IE - pBss->AuthMode = Ndis802_11AuthModeOpen; - pBss->AuthModeAux = Ndis802_11AuthModeOpen; - - // Init WPA setting - pBss->WPA.PairCipher = Ndis802_11WEPDisabled; - pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled; - pBss->WPA.GroupCipher = Ndis802_11WEPDisabled; - pBss->WPA.RsnCapability = 0; - pBss->WPA.bMixMode = FALSE; - - // Init WPA2 setting - pBss->WPA2.PairCipher = Ndis802_11WEPDisabled; - pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled; - pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled; - pBss->WPA2.RsnCapability = 0; - pBss->WPA2.bMixMode = FALSE; - - - Length = (INT) pBss->VarIELen; - - while (Length > 0) - { - // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently - pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length; - pEid = (PEID_STRUCT) pTmp; - switch (pEid->Eid) - { - case IE_WPA: - //Parse Cisco IE_WPA (LEAP, CCKM, etc.) - if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3)) - { - pTmp += 11; - switch (*pTmp) - { - case 1: - case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway - pBss->WepStatus = Ndis802_11Encryption1Enabled; - pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled; - pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled; - break; - case 2: - pBss->WepStatus = Ndis802_11Encryption2Enabled; - pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled; - pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled; - break; - case 4: - pBss->WepStatus = Ndis802_11Encryption3Enabled; - pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled; - pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled; - break; - default: - break; - } - - // if Cisco IE_WPA, break - break; - } - else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7)) - { - pBss->bSES = TRUE; - break; - } - else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1) - { - // if unsupported vendor specific IE - break; - } - // Skip OUI, version, and multicast suite - // This part should be improved in the future when AP supported multiple cipher suite. - // For now, it's OK since almost all APs have fixed cipher suite supported. - // pTmp = (PUCHAR) pEid->Octet; - pTmp += 11; - - // Cipher Suite Selectors from Spec P802.11i/D3.2 P26. - // Value Meaning - // 0 None - // 1 WEP-40 - // 2 Tkip - // 3 WRAP - // 4 AES - // 5 WEP-104 - // Parse group cipher - switch (*pTmp) - { - case 1: - pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled; - break; - case 5: - pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled; - break; - case 2: - pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled; - break; - case 4: - pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled; - break; - default: - break; - } - // number of unicast suite - pTmp += 1; - - // skip all unicast cipher suites - //Count = *(PUSHORT) pTmp; - Count = (pTmp[1]<<8) + pTmp[0]; - pTmp += sizeof(USHORT); - - // Parsing all unicast cipher suite - while (Count > 0) - { - // Skip OUI - pTmp += 3; - TmpCipher = Ndis802_11WEPDisabled; - switch (*pTmp) - { - case 1: - case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway - TmpCipher = Ndis802_11Encryption1Enabled; - break; - case 2: - TmpCipher = Ndis802_11Encryption2Enabled; - break; - case 4: - TmpCipher = Ndis802_11Encryption3Enabled; - break; - default: - break; - } - if (TmpCipher > pBss->WPA.PairCipher) - { - // Move the lower cipher suite to PairCipherAux - pBss->WPA.PairCipherAux = pBss->WPA.PairCipher; - pBss->WPA.PairCipher = TmpCipher; - } - else - { - pBss->WPA.PairCipherAux = TmpCipher; - } - pTmp++; - Count--; - } - - // 4. get AKM suite counts - //Count = *(PUSHORT) pTmp; - Count = (pTmp[1]<<8) + pTmp[0]; - pTmp += sizeof(USHORT); - pTmp += 3; - - switch (*pTmp) - { - case 1: - // Set AP support WPA mode - if (pBss->AuthMode == Ndis802_11AuthModeOpen) - pBss->AuthMode = Ndis802_11AuthModeWPA; - else - pBss->AuthModeAux = Ndis802_11AuthModeWPA; - break; - case 2: - // Set AP support WPA mode - if (pBss->AuthMode == Ndis802_11AuthModeOpen) - pBss->AuthMode = Ndis802_11AuthModeWPAPSK; - else - pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK; - break; - default: - break; - } - pTmp += 1; - - // Fixed for WPA-None - if (pBss->BssType == BSS_ADHOC) - { - pBss->AuthMode = Ndis802_11AuthModeWPANone; - pBss->AuthModeAux = Ndis802_11AuthModeWPANone; - pBss->WepStatus = pBss->WPA.GroupCipher; - if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) - pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher; - } - else - pBss->WepStatus = pBss->WPA.PairCipher; - - // Check the Pair & Group, if different, turn on mixed mode flag - if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher) - pBss->WPA.bMixMode = TRUE; - - break; - - case IE_RSN: - pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp; - - // 0. Version must be 1 - if (le2cpu16(pRsnHeader->Version) != 1) - break; - pTmp += sizeof(RSN_IE_HEADER_STRUCT); - - // 1. Check group cipher - pCipher = (PCIPHER_SUITE_STRUCT) pTmp; - if (!RTMPEqualMemory(pTmp, RSN_OUI, 3)) - break; - - // Parse group cipher - switch (pCipher->Type) - { - case 1: - pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled; - break; - case 5: - pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled; - break; - case 2: - pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled; - break; - case 4: - pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled; - break; - default: - break; - } - // set to correct offset for next parsing - pTmp += sizeof(CIPHER_SUITE_STRUCT); - - // 2. Get pairwise cipher counts - //Count = *(PUSHORT) pTmp; - Count = (pTmp[1]<<8) + pTmp[0]; - pTmp += sizeof(USHORT); - - // 3. Get pairwise cipher - // Parsing all unicast cipher suite - while (Count > 0) - { - // Skip OUI - pCipher = (PCIPHER_SUITE_STRUCT) pTmp; - TmpCipher = Ndis802_11WEPDisabled; - switch (pCipher->Type) - { - case 1: - case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway - TmpCipher = Ndis802_11Encryption1Enabled; - break; - case 2: - TmpCipher = Ndis802_11Encryption2Enabled; - break; - case 4: - TmpCipher = Ndis802_11Encryption3Enabled; - break; - default: - break; - } - if (TmpCipher > pBss->WPA2.PairCipher) - { - // Move the lower cipher suite to PairCipherAux - pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher; - pBss->WPA2.PairCipher = TmpCipher; - } - else - { - pBss->WPA2.PairCipherAux = TmpCipher; - } - pTmp += sizeof(CIPHER_SUITE_STRUCT); - Count--; - } - - // 4. get AKM suite counts - //Count = *(PUSHORT) pTmp; - Count = (pTmp[1]<<8) + pTmp[0]; - pTmp += sizeof(USHORT); - - // 5. Get AKM ciphers - pAKM = (PAKM_SUITE_STRUCT) pTmp; - if (!RTMPEqualMemory(pTmp, RSN_OUI, 3)) - break; - - switch (pAKM->Type) - { - case 1: - // Set AP support WPA mode - if (pBss->AuthMode == Ndis802_11AuthModeOpen) - pBss->AuthMode = Ndis802_11AuthModeWPA2; - else - pBss->AuthModeAux = Ndis802_11AuthModeWPA2; - break; - case 2: - // Set AP support WPA mode - if (pBss->AuthMode == Ndis802_11AuthModeOpen) - pBss->AuthMode = Ndis802_11AuthModeWPA2PSK; - else - pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK; - break; - default: - break; - } - pTmp += (Count * sizeof(AKM_SUITE_STRUCT)); - - // Fixed for WPA-None - if (pBss->BssType == BSS_ADHOC) - { - pBss->AuthMode = Ndis802_11AuthModeWPANone; - pBss->AuthModeAux = Ndis802_11AuthModeWPANone; - pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux; - pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher; - pBss->WepStatus = pBss->WPA.GroupCipher; - if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) - pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher; - } - pBss->WepStatus = pBss->WPA2.PairCipher; + { + pSupRate = &pAd->CommonCfg.SupRate[0]; + pExtRate = &pAd->CommonCfg.ExtRate[0]; + SupRateLen = pAd->CommonCfg.SupRateLen; + ExtRateLen = pAd->CommonCfg.ExtRateLen; + } - // 6. Get RSN capability - //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp; - pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0]; - pTmp += sizeof(USHORT); + // find max supported rate + for (i=0; iWPA2.GroupCipher != pBss->WPA2.PairCipher) - pBss->WPA2.bMixMode = TRUE; + if (MinSupport > Rate) MinSupport = Rate; + } - break; - default: - break; + for (i=0; iLen + 2); + if (MaxSupport < Rate) MaxSupport = Rate; + + if (MinSupport > Rate) MinSupport = Rate; } -} -// =========================================================================================== -// mac_table.c -// =========================================================================================== + RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap); -/*! \brief generates a random mac address value for IBSS BSSID - * \param Addr the bssid location - * \return none - * \pre - * \post - */ -VOID MacAddrRandomBssid( - IN PRTMP_ADAPTER pAd, - OUT PUCHAR pAddr) -{ - INT i; + // bug fix + // pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap; - for (i = 0; i < MAC_ADDR_LEN; i++) + // calculate the exptected ACK rate for each TX rate. This info is used to caculate + // the DURATION field of outgoing uniicast DATA/MGMT frame + for (i=0; iCommonCfg.ExpectedACKRate[i] = CurrBasicRate; } - pAddr[0] = (pAddr[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx -} - -/*! \brief init the management mac frame header - * \param p_hdr mac header - * \param subtype subtype of the frame - * \param p_ds destination address, don't care if it is a broadcast address - * \return none - * \pre the station has the following information in the pAd->StaCfg - * - bssid - * - station address - * \post - * \note this function initializes the following field - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL + DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire])); + // max tx rate = min {max desire rate, max supported rate} + if (MaxSupport < MaxDesire) + pAd->CommonCfg.MaxTxRate = MaxSupport; + else + pAd->CommonCfg.MaxTxRate = MaxDesire; - */ -VOID MgtMacHeaderInit( - IN PRTMP_ADAPTER pAd, - IN OUT PHEADER_802_11 pHdr80211, - IN UCHAR SubType, - IN UCHAR ToDs, - IN PUCHAR pDA, - IN PUCHAR pBssid) -{ - NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11)); + pAd->CommonCfg.MinTxRate = MinSupport; + // 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success + // ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending + // on average RSSI + // 1. RSSI >= -70db, start at 54 Mbps (short distance) + // 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance) + // 3. -75 > RSSI, start at 11 Mbps (long distance) + //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)/* && + // OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)*/) + if (*auto_rate_cur_p) + { + short dbm = 0; - pHdr80211->FC.Type = BTYPE_MGMT; - pHdr80211->FC.SubType = SubType; - pHdr80211->FC.ToDs = ToDs; - COPY_MAC_ADDR(pHdr80211->Addr1, pDA); + dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta; - COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress); + if (bLinkUp == TRUE) + pAd->CommonCfg.TxRate = RATE_24; + else + pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate; - COPY_MAC_ADDR(pHdr80211->Addr3, pBssid); -} + if (dbm < -75) + pAd->CommonCfg.TxRate = RATE_11; + else if (dbm < -70) + pAd->CommonCfg.TxRate = RATE_24; -// =========================================================================================== -// mem_mgmt.c -// =========================================================================================== + // should never exceed MaxTxRate (consider 11B-only mode) + if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate) + pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate; -/*!*************************************************************************** - * This routine build an outgoing frame, and fill all information specified - * in argument list to the frame body. The actual frame size is the summation - * of all arguments. - * input params: - * Buffer - pointer to a pre-allocated memory segment - * args - a list of pairs. - * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this - * function will FAIL!!! - * return: - * Size of the buffer - * usage: - * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS); + pAd->CommonCfg.TxRateIndex = 0; + } + else + { + pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate; + pHtPhy->field.MCS = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate; + pHtPhy->field.MODE = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK; - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL + pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC = pHtPhy->field.STBC; + pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI; + pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS = pHtPhy->field.MCS; + pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE = pHtPhy->field.MODE; + } - ****************************************************************************/ -ULONG MakeOutgoingFrame( - OUT CHAR *Buffer, - OUT ULONG *FrameLen, ...) -{ - CHAR *p; - int leng; - ULONG TotLeng; - va_list Args; + if (pAd->CommonCfg.TxRate <= RATE_11) + { + pMaxHtPhy->field.MODE = MODE_CCK; + pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate; + pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate; + } + else + { + pMaxHtPhy->field.MODE = MODE_OFDM; + pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate]; + if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54)) + {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];} + else + {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;} + } - // calculates the total length - TotLeng = 0; - va_start(Args, FrameLen); - do + pHtPhy->word = (pMaxHtPhy->word); + if (bLinkUp && (pAd->OpMode == OPMODE_STA)) { - leng = va_arg(Args, int); - if (leng == END_OF_ARGS) + pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word; + pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word; + pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word; + } + else + { + switch (pAd->CommonCfg.PhyMode) { - break; + case PHY_11BG_MIXED: + case PHY_11B: + case PHY_11BGN_MIXED: + pAd->CommonCfg.MlmeRate = RATE_1; + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; + pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1; + +//#ifdef WIFI_TEST + pAd->CommonCfg.RtsRate = RATE_11; +//#else +// pAd->CommonCfg.RtsRate = RATE_1; +//#endif + break; + case PHY_11G: + case PHY_11A: + case PHY_11AGN_MIXED: + case PHY_11GN_MIXED: + case PHY_11N_2_4G: + case PHY_11AN_MIXED: + case PHY_11N_5G: + pAd->CommonCfg.MlmeRate = RATE_6; + pAd->CommonCfg.RtsRate = RATE_6; + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; + pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; + break; + case PHY_11ABG_MIXED: + case PHY_11ABGN_MIXED: + if (pAd->CommonCfg.Channel <= 14) + { + pAd->CommonCfg.MlmeRate = RATE_1; + pAd->CommonCfg.RtsRate = RATE_1; + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; + pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1; + } + else + { + pAd->CommonCfg.MlmeRate = RATE_6; + pAd->CommonCfg.RtsRate = RATE_6; + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; + pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; + } + break; + default: // error + pAd->CommonCfg.MlmeRate = RATE_6; + pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM; + pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate]; + pAd->CommonCfg.RtsRate = RATE_1; + break; } - p = va_arg(Args, PVOID); - NdisMoveMemory(&Buffer[TotLeng], p, leng); - TotLeng = TotLeng + leng; - } while(TRUE); + // + // Keep Basic Mlme Rate. + // + pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word; + if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM) + pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24]; + else + pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1; + pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate; + } - va_end(Args); /* clean up */ - *FrameLen = TotLeng; - return TotLeng; + DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n", + RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate], + /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p)); + DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n", + RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap)); + DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n", + 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 )); } -// =========================================================================================== -// mlme_queue.c -// =========================================================================================== - -/*! \brief Initialize The MLME Queue, used by MLME Functions - * \param *Queue The MLME Queue - * \return Always Return NDIS_STATE_SUCCESS in this implementation - * \pre - * \post - * \note Because this is done only once (at the init stage), no need to be locked +/* + ========================================================================== + Description: + This function update HT Rate setting. + Input Wcid value is valid for 2 case : + 1. it's used for Station in infra mode that copy AP rate to Mactable. + 2. OR Station in adhoc mode to copy peer's HT rate to Mactable. - IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + ========================================================================== */ -NDIS_STATUS MlmeQueueInit( - IN MLME_QUEUE *Queue) +VOID MlmeUpdateHtTxRates( + IN PRTMP_ADAPTER pAd, + IN UCHAR apidx) { - INT i; + UCHAR StbcMcs; //j, StbcMcs, bitmask; + CHAR i; // 3*3 + RT_HT_CAPABILITY *pRtHtCap = NULL; + RT_HT_PHY_INFO *pActiveHtPhy = NULL; + ULONG BasicMCS; + UCHAR j, bitmask; + PRT_HT_PHY_INFO pDesireHtPhy = NULL; + PHTTRANSMIT_SETTING pHtPhy = NULL; + PHTTRANSMIT_SETTING pMaxHtPhy = NULL; + PHTTRANSMIT_SETTING pMinHtPhy = NULL; + BOOLEAN *auto_rate_cur_p; - NdisAllocateSpinLock(&Queue->Lock); + DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n")); - Queue->Num = 0; - Queue->Head = 0; - Queue->Tail = 0; + auto_rate_cur_p = NULL; - for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++) { - Queue->Entry[i].Occupied = FALSE; - Queue->Entry[i].MsgLen = 0; - NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE); + pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo; + pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo; + pHtPhy = &pAd->StaCfg.HTPhyMode; + pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode; + pMinHtPhy = &pAd->StaCfg.MinHTPhyMode; + + auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch; } - return NDIS_STATUS_SUCCESS; -} + if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) + { + if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) + return; -/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread - * \param *Queue The MLME Queue - * \param Machine The State Machine Id - * \param MsgType The Message Type - * \param MsgLen The Message length - * \param *Msg The message pointer - * \return TRUE if enqueue is successful, FALSE if the queue is full - * \pre - * \post - * \note The message has to be initialized + pRtHtCap = &pAd->StaActive.SupportedHtPhy; + pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo; + StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs; + BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16); + if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2)) + pMaxHtPhy->field.STBC = STBC_USE; + else + pMaxHtPhy->field.STBC = STBC_NONE; + } + else + { + if (pDesireHtPhy->bHtEnable == FALSE) + return; - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL + pRtHtCap = &pAd->CommonCfg.DesiredHtPhy; + StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs; + BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16); + if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2)) + pMaxHtPhy->field.STBC = STBC_USE; + else + pMaxHtPhy->field.STBC = STBC_NONE; + } - */ -BOOLEAN MlmeEnqueue( - IN PRTMP_ADAPTER pAd, - IN ULONG Machine, - IN ULONG MsgType, - IN ULONG MsgLen, - IN VOID *Msg) -{ - INT Tail; - MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue; + // Decide MAX ht rate. + if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF)) + pMaxHtPhy->field.MODE = MODE_HTGREENFIELD; + else + pMaxHtPhy->field.MODE = MODE_HTMIX; - // Do nothing if the driver is starting halt state. - // This might happen when timer already been fired before cancel timer with mlmehalt - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - return FALSE; + if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth)) + pMaxHtPhy->field.BW = BW_40; + else + pMaxHtPhy->field.BW = BW_20; - // First check the size, it MUST not exceed the mlme queue size - if (MsgLen > MGMT_DMA_BUFFER_SIZE) + if (pMaxHtPhy->field.BW == BW_20) + pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20); + else + pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40); + + if (pDesireHtPhy->MCSSet[4] != 0) { - DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen)); - return FALSE; + pMaxHtPhy->field.MCS = 32; } - if (MlmeQueueFull(Queue)) + for (i=23; i>=0; i--) // 3*3 { - return FALSE; - } + j = i/8; + bitmask = (1<<(i-(j*8))); - NdisAcquireSpinLock(&(Queue->Lock)); - Tail = Queue->Tail; - Queue->Tail++; - Queue->Num++; - if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) + if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask)) { - Queue->Tail = 0; + pMaxHtPhy->field.MCS = i; + break; } - Queue->Entry[Tail].Wcid = RESERVED_WCID; - Queue->Entry[Tail].Occupied = TRUE; - Queue->Entry[Tail].Machine = Machine; - Queue->Entry[Tail].MsgType = MsgType; - Queue->Entry[Tail].MsgLen = MsgLen; + if (i==0) + break; + } - if (Msg != NULL) + // Copy MIN ht rate. rt2860??? + pMinHtPhy->field.BW = BW_20; + pMinHtPhy->field.MCS = 0; + pMinHtPhy->field.STBC = 0; + pMinHtPhy->field.ShortGI = 0; + //If STA assigns fixed rate. update to fixed here. + if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff)) { - NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen); + if (pDesireHtPhy->MCSSet[4] != 0) + { + pMaxHtPhy->field.MCS = 32; + pMinHtPhy->field.MCS = 32; + DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS)); } - NdisReleaseSpinLock(&(Queue->Lock)); - return TRUE; -} + for (i=23; (CHAR)i >= 0; i--) // 3*3 + { + j = i/8; + bitmask = (1<<(i-(j*8))); + if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask)) + { + pMaxHtPhy->field.MCS = i; + pMinHtPhy->field.MCS = i; + break; + } + if (i==0) + break; + } + } -/*! \brief This function is used when Recv gets a MLME message - * \param *Queue The MLME Queue - * \param TimeStampHigh The upper 32 bit of timestamp - * \param TimeStampLow The lower 32 bit of timestamp - * \param Rssi The receiving RSSI strength - * \param MsgLen The length of the message - * \param *Msg The message pointer - * \return TRUE if everything ok, FALSE otherwise (like Queue Full) - * \pre - * \post - IRQL = DISPATCH_LEVEL + // Decide ht rate + pHtPhy->field.STBC = pMaxHtPhy->field.STBC; + pHtPhy->field.BW = pMaxHtPhy->field.BW; + pHtPhy->field.MODE = pMaxHtPhy->field.MODE; + pHtPhy->field.MCS = pMaxHtPhy->field.MCS; + pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI; - */ -BOOLEAN MlmeEnqueueForRecv( - IN PRTMP_ADAPTER pAd, - IN ULONG Wcid, - IN ULONG TimeStampHigh, - IN ULONG TimeStampLow, - IN UCHAR Rssi0, - IN UCHAR Rssi1, - IN UCHAR Rssi2, - IN ULONG MsgLen, - IN VOID *Msg, - IN UCHAR Signal) -{ - INT Tail, Machine; - PFRAME_802_11 pFrame = (PFRAME_802_11)Msg; - INT MsgType; - MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue; + // use default now. rt2860 + if (pDesireHtPhy->MCSSet[0] != 0xff) + *auto_rate_cur_p = FALSE; + else + *auto_rate_cur_p = TRUE; - // Do nothing if the driver is starting halt state. - // This might happen when timer already been fired before cancel timer with mlmehalt - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) - { - DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n")); - return FALSE; - } + DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize )); + DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS, + pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE)); + DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n")); +} - // First check the size, it MUST not exceed the mlme queue size - if (MsgLen > MGMT_DMA_BUFFER_SIZE) - { - DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen)); - return FALSE; - } - if (MlmeQueueFull(Queue)) +VOID BATableInit( + IN PRTMP_ADAPTER pAd, + IN BA_TABLE *Tab) +{ + int i; + + Tab->numAsOriginator = 0; + Tab->numAsRecipient = 0; + Tab->numDoneOriginator = 0; + NdisAllocateSpinLock(&pAd->BATabLock); + for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) { - return FALSE; + Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE; + NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock)); } - + for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++) { - if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType)) - { - DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType)); - return FALSE; - } + Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE; } +} - // OK, we got all the informations, it is time to put things into queue - NdisAcquireSpinLock(&(Queue->Lock)); - Tail = Queue->Tail; - Queue->Tail++; - Queue->Num++; - if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) - { - Queue->Tail = 0; - } - Queue->Entry[Tail].Occupied = TRUE; - Queue->Entry[Tail].Machine = Machine; - Queue->Entry[Tail].MsgType = MsgType; - Queue->Entry[Tail].MsgLen = MsgLen; - Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow; - Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh; - Queue->Entry[Tail].Rssi0 = Rssi0; - Queue->Entry[Tail].Rssi1 = Rssi1; - Queue->Entry[Tail].Rssi2 = Rssi2; - Queue->Entry[Tail].Signal = Signal; - Queue->Entry[Tail].Wcid = (UCHAR)Wcid; +// IRQL = DISPATCH_LEVEL +VOID MlmeRadioOff( + IN PRTMP_ADAPTER pAd) +{ + RTMP_MLME_RADIO_OFF(pAd); +} - Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel; +// IRQL = DISPATCH_LEVEL +VOID MlmeRadioOn( + IN PRTMP_ADAPTER pAd) +{ + RTMP_MLME_RADIO_ON(pAd); +} - if (Msg != NULL) - { - NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen); - } +// =========================================================================================== +// bss_table.c +// =========================================================================================== - NdisReleaseSpinLock(&(Queue->Lock)); - RT28XX_MLME_HANDLER(pAd); +/*! \brief initialize BSS table + * \param p_tab pointer to the table + * \return none + * \pre + * \post + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL - return TRUE; + */ +VOID BssTableInit( + IN BSS_TABLE *Tab) +{ + int i; + + Tab->BssNr = 0; + Tab->BssOverlapNr = 0; + for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++) + { + NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY)); + Tab->BssEntry[i].Rssi = -127; // initial the rssi as a minimum value + } } -/*! \brief Dequeue a message from the MLME Queue - * \param *Queue The MLME Queue - * \param *Elem The message dequeued from MLME Queue - * \return TRUE if the Elem contains something, FALSE otherwise +/*! \brief search the BSS table by SSID + * \param p_tab pointer to the bss table + * \param ssid SSID string + * \return index of the table, BSS_NOT_FOUND if not in the table * \pre * \post + * \note search by sequential search IRQL = DISPATCH_LEVEL */ -BOOLEAN MlmeDequeue( - IN MLME_QUEUE *Queue, - OUT MLME_QUEUE_ELEM **Elem) +ULONG BssTableSearch( + IN BSS_TABLE *Tab, + IN PUCHAR pBssid, + IN UCHAR Channel) { - NdisAcquireSpinLock(&(Queue->Lock)); - *Elem = &(Queue->Entry[Queue->Head]); - Queue->Num--; - Queue->Head++; - if (Queue->Head == MAX_LEN_OF_MLME_QUEUE) + UCHAR i; + + for (i = 0; i < Tab->BssNr; i++) { - Queue->Head = 0; + // + // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. + // We should distinguish this case. + // + if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) || + ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) && + MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)) + { + return i; + } } - NdisReleaseSpinLock(&(Queue->Lock)); - return TRUE; + return (ULONG)BSS_NOT_FOUND; } -// IRQL = DISPATCH_LEVEL -VOID MlmeRestartStateMachine( - IN PRTMP_ADAPTER pAd) +ULONG BssSsidTableSearch( + IN BSS_TABLE *Tab, + IN PUCHAR pBssid, + IN PUCHAR pSsid, + IN UCHAR SsidLen, + IN UCHAR Channel) { -#ifdef RT2860 - MLME_QUEUE_ELEM *Elem = NULL; -#endif - BOOLEAN Cancelled; - - DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n")); - -#ifdef RT2860 - NdisAcquireSpinLock(&pAd->Mlme.TaskLock); - if(pAd->Mlme.bRunning) - { - NdisReleaseSpinLock(&pAd->Mlme.TaskLock); - return; - } - else - { - pAd->Mlme.bRunning = TRUE; - } - NdisReleaseSpinLock(&pAd->Mlme.TaskLock); + UCHAR i; - // Remove all Mlme queues elements - while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) + for (i = 0; i < Tab->BssNr; i++) { - //From message type, determine which state machine I should drive - if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) + // + // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. + // We should distinguish this case. + // + if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) || + ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) && + MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) && + SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen)) { - // free MLME element - Elem->Occupied = FALSE; - Elem->MsgLen = 0; - - } - else { - DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n")); + return i; } } -#endif /* RT2860 */ + return (ULONG)BSS_NOT_FOUND; +} + +ULONG BssTableSearchWithSSID( + IN BSS_TABLE *Tab, + IN PUCHAR Bssid, + IN PUCHAR pSsid, + IN UCHAR SsidLen, + IN UCHAR Channel) +{ + UCHAR i; + for (i = 0; i < Tab->BssNr; i++) { - // Cancel all timer events - // Be careful to cancel new added timer - RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled); - RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); + if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) || + ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) && + MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) && + (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) || + (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) || + (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen)))) + { + return i; + } } + return (ULONG)BSS_NOT_FOUND; +} - // Change back to original channel in case of doing scan - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - // Resume MSDU which is turned off durning scan - RTMPResumeMsduTransmission(pAd); +ULONG BssSsidTableSearchBySSID( + IN BSS_TABLE *Tab, + IN PUCHAR pSsid, + IN UCHAR SsidLen) +{ + UCHAR i; + for (i = 0; i < Tab->BssNr; i++) { - // Set all state machines back IDLE - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE; - pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; - pAd->Mlme.ActMachine.CurrState = ACT_IDLE; + if (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen)) + { + return i; } - -#ifdef RT2860 - // Remove running state - NdisAcquireSpinLock(&pAd->Mlme.TaskLock); - pAd->Mlme.bRunning = FALSE; - NdisReleaseSpinLock(&pAd->Mlme.TaskLock); -#endif + } + return (ULONG)BSS_NOT_FOUND; } -/*! \brief test if the MLME Queue is empty - * \param *Queue The MLME Queue - * \return TRUE if the Queue is empty, FALSE otherwise - * \pre - * \post - - IRQL = DISPATCH_LEVEL - */ -BOOLEAN MlmeQueueEmpty( - IN MLME_QUEUE *Queue) +// IRQL = DISPATCH_LEVEL +VOID BssTableDeleteEntry( + IN OUT BSS_TABLE *Tab, + IN PUCHAR pBssid, + IN UCHAR Channel) { - BOOLEAN Ans; - - NdisAcquireSpinLock(&(Queue->Lock)); - Ans = (Queue->Num == 0); - NdisReleaseSpinLock(&(Queue->Lock)); + UCHAR i, j; - return Ans; + for (i = 0; i < Tab->BssNr; i++) + { + if ((Tab->BssEntry[i].Channel == Channel) && + (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))) + { + for (j = i; j < Tab->BssNr - 1; j++) + { + NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY)); + } + NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY)); + Tab->BssNr -= 1; + return; + } + } } -/*! \brief test if the MLME Queue is full - * \param *Queue The MLME Queue - * \return TRUE if the Queue is empty, FALSE otherwise - * \pre - * \post - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL +/* + ======================================================================== + Routine Description: + Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed. - */ -BOOLEAN MlmeQueueFull( - IN MLME_QUEUE *Queue) + Arguments: + // IRQL = DISPATCH_LEVEL + ======================================================================== +*/ +VOID BATableDeleteORIEntry( + IN OUT PRTMP_ADAPTER pAd, + IN BA_ORI_ENTRY *pBAORIEntry) { - BOOLEAN Ans; - - NdisAcquireSpinLock(&(Queue->Lock)); - Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied); - NdisReleaseSpinLock(&(Queue->Lock)); - return Ans; + if (pBAORIEntry->ORI_BA_Status != Originator_NONE) + { + NdisAcquireSpinLock(&pAd->BATabLock); + if (pBAORIEntry->ORI_BA_Status == Originator_Done) + { + pAd->BATable.numAsOriginator -= 1; + DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient)); + // Erase Bitmap flag. + } + pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) )); // If STA mode, erase flag here + pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0; // If STA mode, erase flag here + pBAORIEntry->ORI_BA_Status = Originator_NONE; + pBAORIEntry->Token = 1; + // Not clear Sequence here. + NdisReleaseSpinLock(&pAd->BATabLock); + } } -/*! \brief The destructor of MLME Queue +/*! \brief * \param * \return * \pre * \post - * \note Clear Mlme Queue, Set Queue->Num to Zero. - - IRQL = PASSIVE_LEVEL - - */ -VOID MlmeQueueDestroy( - IN MLME_QUEUE *pQueue) -{ - NdisAcquireSpinLock(&(pQueue->Lock)); - pQueue->Num = 0; - pQueue->Head = 0; - pQueue->Tail = 0; - NdisReleaseSpinLock(&(pQueue->Lock)); - NdisFreeSpinLock(&(pQueue->Lock)); -} - -/*! \brief To substitute the message type if the message is coming from external - * \param pFrame The frame received - * \param *Machine The state machine - * \param *MsgType the message type for the state machine - * \return TRUE if the substitution is successful, FALSE otherwise - * \pre - * \post IRQL = DISPATCH_LEVEL */ -BOOLEAN MsgTypeSubst( - IN PRTMP_ADAPTER pAd, - IN PFRAME_802_11 pFrame, - OUT INT *Machine, - OUT INT *MsgType) +VOID BssEntrySet( + IN PRTMP_ADAPTER pAd, + OUT BSS_ENTRY *pBss, + IN PUCHAR pBssid, + IN CHAR Ssid[], + IN UCHAR SsidLen, + IN UCHAR BssType, + IN USHORT BeaconPeriod, + IN PCF_PARM pCfParm, + IN USHORT AtimWin, + IN USHORT CapabilityInfo, + IN UCHAR SupRate[], + IN UCHAR SupRateLen, + IN UCHAR ExtRate[], + IN UCHAR ExtRateLen, + IN HT_CAPABILITY_IE *pHtCapability, + IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE + IN UCHAR HtCapabilityLen, + IN UCHAR AddHtInfoLen, + IN UCHAR NewExtChanOffset, + IN UCHAR Channel, + IN CHAR Rssi, + IN LARGE_INTEGER TimeStamp, + IN UCHAR CkipFlag, + IN PEDCA_PARM pEdcaParm, + IN PQOS_CAPABILITY_PARM pQosCapability, + IN PQBSS_LOAD_PARM pQbssLoad, + IN USHORT LengthVIE, + IN PNDIS_802_11_VARIABLE_IEs pVIE) { - USHORT Seq; - UCHAR EAPType; - PUCHAR pData; - - // Pointer to start of data frames including SNAP header - pData = (PUCHAR) pFrame + LENGTH_802_11; - - // The only data type will pass to this function is EAPOL frame - if (pFrame->Hdr.FC.Type == BTYPE_DATA) + COPY_MAC_ADDR(pBss->Bssid, pBssid); + // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID + pBss->Hidden = 1; + if (SsidLen > 0) { - if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H)) + // For hidden SSID AP, it might send beacon with SSID len equal to 0 + // Or send beacon /probe response with SSID len matching real SSID length, + // but SSID is all zero. such as "00-00-00-00" with length 4. + // We have to prevent this case overwrite correct table + if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0) { - // Cisco Aironet SNAP header - *Machine = AIRONET_STATE_MACHINE; - *MsgType = MT2_AIRONET_MSG; - return (TRUE); + NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID); + NdisMoveMemory(pBss->Ssid, Ssid, SsidLen); + pBss->SsidLen = SsidLen; + pBss->Hidden = 0; } + } + else + pBss->SsidLen = 0; + pBss->BssType = BssType; + pBss->BeaconPeriod = BeaconPeriod; + if (BssType == BSS_INFRA) + { + if (pCfParm->bValid) { - *Machine = WPA_PSK_STATE_MACHINE; - EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1); - return(WpaMsgTypeSubst(EAPType, MsgType)); + pBss->CfpCount = pCfParm->CfpCount; + pBss->CfpPeriod = pCfParm->CfpPeriod; + pBss->CfpMaxDuration = pCfParm->CfpMaxDuration; + pBss->CfpDurRemaining = pCfParm->CfpDurRemaining; } } - - switch (pFrame->Hdr.FC.SubType) + else { - case SUBTYPE_ASSOC_REQ: - *Machine = ASSOC_STATE_MACHINE; - *MsgType = MT2_PEER_ASSOC_REQ; - break; - case SUBTYPE_ASSOC_RSP: - *Machine = ASSOC_STATE_MACHINE; - *MsgType = MT2_PEER_ASSOC_RSP; - break; - case SUBTYPE_REASSOC_REQ: - *Machine = ASSOC_STATE_MACHINE; - *MsgType = MT2_PEER_REASSOC_REQ; - break; - case SUBTYPE_REASSOC_RSP: - *Machine = ASSOC_STATE_MACHINE; - *MsgType = MT2_PEER_REASSOC_RSP; - break; - case SUBTYPE_PROBE_REQ: - *Machine = SYNC_STATE_MACHINE; - *MsgType = MT2_PEER_PROBE_REQ; - break; - case SUBTYPE_PROBE_RSP: - *Machine = SYNC_STATE_MACHINE; - *MsgType = MT2_PEER_PROBE_RSP; - break; - case SUBTYPE_BEACON: - *Machine = SYNC_STATE_MACHINE; - *MsgType = MT2_PEER_BEACON; - break; - case SUBTYPE_ATIM: - *Machine = SYNC_STATE_MACHINE; - *MsgType = MT2_PEER_ATIM; - break; - case SUBTYPE_DISASSOC: - *Machine = ASSOC_STATE_MACHINE; - *MsgType = MT2_PEER_DISASSOC_REQ; - break; - case SUBTYPE_AUTH: - // get the sequence number from payload 24 Mac Header + 2 bytes algorithm - NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT)); - if (Seq == 1 || Seq == 3) - { - *Machine = AUTH_RSP_STATE_MACHINE; - *MsgType = MT2_PEER_AUTH_ODD; - } - else if (Seq == 2 || Seq == 4) - { - *Machine = AUTH_STATE_MACHINE; - *MsgType = MT2_PEER_AUTH_EVEN; - } - else - { - return FALSE; - } - break; - case SUBTYPE_DEAUTH: - *Machine = AUTH_RSP_STATE_MACHINE; - *MsgType = MT2_PEER_DEAUTH; - break; - case SUBTYPE_ACTION: - *Machine = ACTION_STATE_MACHINE; - // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support - if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG) - { - *MsgType = MT2_ACT_INVALID; - } - else - { - *MsgType = (pFrame->Octet[0]&0x7F); - } - break; - default: - return FALSE; - break; + pBss->AtimWin = AtimWin; } - return TRUE; -} - -// =========================================================================================== -// state_machine.c -// =========================================================================================== - -/*! \brief Initialize the state machine. - * \param *S pointer to the state machine - * \param Trans State machine transition function - * \param StNr number of states - * \param MsgNr number of messages - * \param DefFunc default function, when there is invalid state/message combination - * \param InitState initial state of the state machine - * \param Base StateMachine base, internal use only - * \pre p_sm should be a legal pointer - * \post - - IRQL = PASSIVE_LEVEL - - */ -VOID StateMachineInit( - IN STATE_MACHINE *S, - IN STATE_MACHINE_FUNC Trans[], - IN ULONG StNr, - IN ULONG MsgNr, - IN STATE_MACHINE_FUNC DefFunc, - IN ULONG InitState, - IN ULONG Base) -{ - ULONG i, j; + pBss->CapabilityInfo = CapabilityInfo; + // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES + // Combine with AuthMode, they will decide the connection methods. + pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo); + ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES); + if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES) + NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen); + else + NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES); + pBss->SupRateLen = SupRateLen; + ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES); + NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen); + pBss->NewExtChanOffset = NewExtChanOffset; + pBss->ExtRateLen = ExtRateLen; + pBss->Channel = Channel; + pBss->CentralChannel = Channel; + pBss->Rssi = Rssi; + // Update CkipFlag. if not exists, the value is 0x0 + pBss->CkipFlag = CkipFlag; - // set number of states and messages - S->NrState = StNr; - S->NrMsg = MsgNr; - S->Base = Base; + // New for microsoft Fixed IEs + NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8); + pBss->FixIEs.BeaconInterval = BeaconPeriod; + pBss->FixIEs.Capabilities = CapabilityInfo; - S->TransFunc = Trans; + // New for microsoft Variable IEs + if (LengthVIE != 0) + { + pBss->VarIELen = LengthVIE; + NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen); + } + else + { + pBss->VarIELen = 0; + } - // init all state transition to default function - for (i = 0; i < StNr; i++) + pBss->AddHtInfoLen = 0; + pBss->HtCapabilityLen = 0; + if (HtCapabilityLen> 0) { - for (j = 0; j < MsgNr; j++) + pBss->HtCapabilityLen = HtCapabilityLen; + NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen); + if (AddHtInfoLen > 0) { - S->TransFunc[i * MsgNr + j] = DefFunc; + pBss->AddHtInfoLen = AddHtInfoLen; + NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen); + + if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) + { + pBss->CentralChannel = pAddHtInfo->ControlChan - 2; + } + else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40)) + { + pBss->CentralChannel = pAddHtInfo->ControlChan + 2; + } } } - // set the starting state - S->CurrState = InitState; -} - -/*! \brief This function fills in the function pointer into the cell in the state machine - * \param *S pointer to the state machine - * \param St state - * \param Msg incoming message - * \param f the function to be executed when (state, message) combination occurs at the state machine - * \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 - * \post + BssCipherParse(pBss); - IRQL = PASSIVE_LEVEL + // new for QOS + if (pEdcaParm) + NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM)); + else + pBss->EdcaParm.bValid = FALSE; + if (pQosCapability) + NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM)); + else + pBss->QosCapability.bValid = FALSE; + if (pQbssLoad) + NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM)); + else + pBss->QbssLoad.bValid = FALSE; - */ -VOID StateMachineSetAction( - IN STATE_MACHINE *S, - IN ULONG St, - IN ULONG Msg, - IN STATE_MACHINE_FUNC Func) -{ - ULONG MsgIdx; + { + PEID_STRUCT pEid; + USHORT Length = 0; - MsgIdx = Msg - S->Base; - if (St < S->NrState && MsgIdx < S->NrMsg) + NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN); + NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN); + pEid = (PEID_STRUCT) pVIE; + while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE) { - // boundary checking before setting the action - S->TransFunc[St * S->NrMsg + MsgIdx] = Func; + switch(pEid->Eid) + { + case IE_WPA: + if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) + { + if ((pEid->Len + 2) > MAX_CUSTOM_LEN) + { + pBss->WpaIE.IELen = 0; + break; + } + pBss->WpaIE.IELen = pEid->Len + 2; + NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen); + } + break; + case IE_RSN: + if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)) + { + if ((pEid->Len + 2) > MAX_CUSTOM_LEN) + { + pBss->RsnIE.IELen = 0; + break; + } + pBss->RsnIE.IELen = pEid->Len + 2; + NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen); + } + break; + } + Length = Length + 2 + (USHORT)pEid->Len; // Eid[1] + Len[1]+ content[Len] + pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len); + } } } -/*! \brief This function does the state transition - * \param *Adapter the NIC adapter pointer - * \param *S the state machine - * \param *Elem the message to be executed - * \return None +/*! + * \brief insert an entry into the bss table + * \param p_tab The BSS table + * \param Bssid BSSID + * \param ssid SSID + * \param ssid_len Length of SSID + * \param bss_type + * \param beacon_period + * \param timestamp + * \param p_cf + * \param atim_win + * \param cap + * \param rates + * \param rates_len + * \param channel_idx + * \return none + * \pre + * \post + * \note If SSID is identical, the old entry will be replaced by the new one IRQL = DISPATCH_LEVEL */ -VOID StateMachinePerformAction( - IN PRTMP_ADAPTER pAd, - IN STATE_MACHINE *S, - IN MLME_QUEUE_ELEM *Elem) -{ - (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem); -} - -/* - ========================================================================== - Description: - The drop function, when machine executes this, the message is simply - ignored. This function does nothing, the message is freed in - StateMachinePerformAction() - ========================================================================== - */ -VOID Drop( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem) -{ -} - -// =========================================================================================== -// lfsr.c -// =========================================================================================== - -/* - ========================================================================== - Description: - - IRQL = PASSIVE_LEVEL - - ========================================================================== - */ -VOID LfsrInit( - IN PRTMP_ADAPTER pAd, - IN ULONG Seed) -{ - if (Seed == 0) - pAd->Mlme.ShiftReg = 1; - else - pAd->Mlme.ShiftReg = Seed; -} - -/* - ========================================================================== - Description: - ========================================================================== - */ -UCHAR RandomByte( - IN PRTMP_ADAPTER pAd) +ULONG BssTableSetEntry( + IN PRTMP_ADAPTER pAd, + OUT BSS_TABLE *Tab, + IN PUCHAR pBssid, + IN CHAR Ssid[], + IN UCHAR SsidLen, + IN UCHAR BssType, + IN USHORT BeaconPeriod, + IN CF_PARM *CfParm, + IN USHORT AtimWin, + IN USHORT CapabilityInfo, + IN UCHAR SupRate[], + IN UCHAR SupRateLen, + IN UCHAR ExtRate[], + IN UCHAR ExtRateLen, + IN HT_CAPABILITY_IE *pHtCapability, + IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE + IN UCHAR HtCapabilityLen, + IN UCHAR AddHtInfoLen, + IN UCHAR NewExtChanOffset, + IN UCHAR ChannelNo, + IN CHAR Rssi, + IN LARGE_INTEGER TimeStamp, + IN UCHAR CkipFlag, + IN PEDCA_PARM pEdcaParm, + IN PQOS_CAPABILITY_PARM pQosCapability, + IN PQBSS_LOAD_PARM pQbssLoad, + IN USHORT LengthVIE, + IN PNDIS_802_11_VARIABLE_IEs pVIE) { - ULONG i; - UCHAR R, Result; - - R = 0; - - if (pAd->Mlme.ShiftReg == 0) - NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg); + ULONG Idx; - for (i = 0; i < 8; i++) + Idx = BssTableSearchWithSSID(Tab, pBssid, (UCHAR *)Ssid, SsidLen, ChannelNo); + if (Idx == BSS_NOT_FOUND) { - if (pAd->Mlme.ShiftReg & 0x00000001) - { - pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000; - Result = 1; + if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE) + { + // + // It may happen when BSS Table was full. + // The desired AP will not be added into BSS Table + // In this case, if we found the desired AP then overwrite BSS Table. + // + if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) + { + if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) || + SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen)) + { + Idx = Tab->BssOverlapNr; + BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin, + CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, + NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE); + Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE; + } + return Idx; + } + else + { + return BSS_NOT_FOUND; + } } - else + Idx = Tab->BssNr; + BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin, + CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, + NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE); + Tab->BssNr++; + } + else + { + /* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */ + if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) || + (NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen))) { - pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1; - Result = 0; + BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin, + CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen, + NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE); } - R = (R << 1) | Result; } - return R; + return Idx; } -VOID AsicUpdateAutoFallBackTable( + +// IRQL = DISPATCH_LEVEL +VOID BssTableSsidSort( IN PRTMP_ADAPTER pAd, - IN PUCHAR pRateTable) + OUT BSS_TABLE *OutTab, + IN CHAR Ssid[], + IN UCHAR SsidLen) { - UCHAR i; - HT_FBK_CFG0_STRUC HtCfg0; - HT_FBK_CFG1_STRUC HtCfg1; - LG_FBK_CFG0_STRUC LgCfg0; - LG_FBK_CFG1_STRUC LgCfg1; - PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate; - - // set to initial value - HtCfg0.word = 0x65432100; - HtCfg1.word = 0xedcba988; - LgCfg0.word = 0xedcba988; - LgCfg1.word = 0x00002100; + INT i; + BssTableInit(OutTab); - pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1; - for (i = 1; i < *((PUCHAR) pRateTable); i++) + for (i = 0; i < pAd->ScanTab.BssNr; i++) { - pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i; - switch (pCurrTxRate->Mode) - { - case 0: //CCK - break; - case 1: //OFDM - { - switch(pCurrTxRate->CurrMCS) - { - case 0: - LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; - break; - case 1: - LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; - break; - case 2: - LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; - break; - case 3: - LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; - break; - case 4: - LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; - break; - case 5: - LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; - break; - case 6: - LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; - break; - case 7: - LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS; - break; - } - } - break; - case 2: //HT-MIX - case 3: //HT-GF - { - if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS)) - { - switch(pCurrTxRate->CurrMCS) - { - case 0: - HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS; - break; - case 1: - HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS; - break; - case 2: - HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS; - break; - case 3: - HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS; - break; - case 4: - HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS; - break; - case 5: - HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS; - break; - case 6: - HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS; - break; - case 7: - HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS; - break; - case 8: - HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS; - break; - case 9: - HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS; - break; - case 10: - HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS; - break; - case 11: - HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS; - break; - case 12: - HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS; - break; - case 13: - HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS; - break; - case 14: - HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS; - break; - case 15: - HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS; - break; - default: - DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS)); - } - } - } - break; - } - - pNextTxRate = pCurrTxRate; - } + BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i]; + BOOLEAN bIsHiddenApIncluded = FALSE; - RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word); - RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word); - RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word); - RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word); + if (((pAd->CommonCfg.bIEEE80211H == 1) && + (pAd->MlmeAux.Channel > 14) && + RadarChannelCheck(pAd, pInBss->Channel)) + ) +{ + if (pInBss->Hidden) + bIsHiddenApIncluded = TRUE; } -/* - ======================================================================== + if ((pInBss->BssType == pAd->StaCfg.BssType) && + (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded)) + { + BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr]; - Routine Description: - Set MAC register value according operation mode. - OperationMode AND bNonGFExist are for MM and GF Proteciton. - If MM or GF mask is not set, those passing argument doesn't not take effect. - - Operation mode meaning: - = 0 : Pure HT, no preotection. - = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS. - = 0x10: No Transmission in 40M is protected. - = 0x11: Transmission in both 40M and 20M shall be protected - if (bNonGFExist) - we should choose not to use GF. But still set correct ASIC registers. - ======================================================================== -*/ -VOID AsicUpdateProtect( - IN PRTMP_ADAPTER pAd, - IN USHORT OperationMode, - IN UCHAR SetMask, - IN BOOLEAN bDisableBGProtect, - IN BOOLEAN bNonGFExist) -{ - PROT_CFG_STRUC ProtCfg, ProtCfg4; - UINT32 Protect[6]; - USHORT offset; - UCHAR i; - UINT32 MacReg = 0; - if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8)) - { - return; - } - if (pAd->BATable.numAsOriginator) + // 2.4G/5G N only mode + if ((pInBss->HtCapabilityLen == 0) && + ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) + { + DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n")); + continue; + } +#ifdef RT2860 + if ((pAd->CommonCfg.PhyMode == PHY_11GN_MIXED) && + ((pInBss->SupRateLen + pInBss->ExtRateLen) < 12)) { - // - // enable the RTS/CTS to avoid channel collision - // - SetMask = ALLN_SETPROTECT; - OperationMode = 8; + DBGPRINT(RT_DEBUG_TRACE,("STA is in GN-only Mode, this AP is in B mode.\n")); + continue; } +#endif // RT2860 // + // New for WPA2 + // Check the Authmode first + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + { + // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode + if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux)) + // None matched + continue; - // Config ASIC RTS threshold register - RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg); - MacReg &= 0xFF0000FF; - - // If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096 - if (( - (pAd->CommonCfg.BACapability.field.AmsduEnable) || - (pAd->CommonCfg.bAggregationCapable == TRUE)) - && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD) - { - MacReg |= (0x1000 << 8); - } - else - { - MacReg |= (pAd->CommonCfg.RtsThreshold << 8); - } + // Check cipher suite, AP must have more secured cipher than station setting + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) + { + // If it's not mixed mode, we should only let BSS pass with the same encryption + if (pInBss->WPA.bMixMode == FALSE) + if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher) + continue; - RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg); + // check group cipher + if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) && + (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) && + (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled)) + continue; - // Initial common protection settings - RTMPZeroMemory(Protect, sizeof(Protect)); - ProtCfg4.word = 0; - ProtCfg.word = 0; - ProtCfg.field.TxopAllowGF40 = 1; - ProtCfg.field.TxopAllowGF20 = 1; - ProtCfg.field.TxopAllowMM40 = 1; - ProtCfg.field.TxopAllowMM20 = 1; - ProtCfg.field.TxopAllowOfdm = 1; - ProtCfg.field.TxopAllowCck = 1; - ProtCfg.field.RTSThEn = 1; - ProtCfg.field.ProtectNav = ASIC_SHORTNAV; - - // update PHY mode and rate - if (pAd->CommonCfg.Channel > 14) - ProtCfg.field.ProtectRate = 0x4000; - ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate; - - // Handle legacy(B/G) protection - if (bDisableBGProtect) - { - //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; - ProtCfg.field.ProtectCtrl = 0; - Protect[0] = ProtCfg.word; - Protect[1] = ProtCfg.word; - } - else - { - //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; - ProtCfg.field.ProtectCtrl = 0; // CCK do not need to be protected - Protect[0] = ProtCfg.word; - ProtCfg.field.ProtectCtrl = ASIC_CTS; // OFDM needs using CCK to protect - Protect[1] = ProtCfg.word; - } - - // Decide HT frame protection. - if ((SetMask & ALLN_SETPROTECT) != 0) - { - switch(OperationMode) - { - case 0x0: - // NO PROTECT - // 1.All STAs in the BSS are 20/40 MHz HT - // 2. in ai 20/40MHz BSS - // 3. all STAs are 20MHz in a 20MHz BSS - // Pure HT. no protection. - - // MM20_PROT_CFG - // Reserved (31:27) - // PROT_TXOP(25:20) -- 010111 - // PROT_NAV(19:18) -- 01 (Short NAV protection) - // PROT_CTRL(17:16) -- 00 (None) - // PROT_RATE(15:0) -- 0x4004 (OFDM 24M) - Protect[2] = 0x01744004; - - // MM40_PROT_CFG - // Reserved (31:27) - // PROT_TXOP(25:20) -- 111111 - // PROT_NAV(19:18) -- 01 (Short NAV protection) - // PROT_CTRL(17:16) -- 00 (None) - // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M) - Protect[3] = 0x03f44084; - - // CF20_PROT_CFG - // Reserved (31:27) - // PROT_TXOP(25:20) -- 010111 - // PROT_NAV(19:18) -- 01 (Short NAV protection) - // PROT_CTRL(17:16) -- 00 (None) - // PROT_RATE(15:0) -- 0x4004 (OFDM 24M) - Protect[4] = 0x01744004; - - // CF40_PROT_CFG - // Reserved (31:27) - // PROT_TXOP(25:20) -- 111111 - // PROT_NAV(19:18) -- 01 (Short NAV protection) - // PROT_CTRL(17:16) -- 00 (None) - // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M) - Protect[5] = 0x03f44084; - - if (bNonGFExist) - { - // PROT_NAV(19:18) -- 01 (Short NAV protectiion) - // PROT_CTRL(17:16) -- 01 (RTS/CTS) - Protect[4] = 0x01754004; - Protect[5] = 0x03f54084; + // check pairwise cipher, skip if none matched + // If profile set to AES, let it pass without question. + // If profile set to TKIP, we must find one mateched + if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) && + (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) && + (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux)) + continue; } - pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE; - break; - - case 1: - // This is "HT non-member protection mode." - // If there may be non-HT STAs my BSS - ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None) - ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1. - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) - { - ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18.. - ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083; - } - //Assign Protection method for 20&40 MHz packets - ProtCfg.field.ProtectCtrl = ASIC_RTS; - ProtCfg.field.ProtectNav = ASIC_SHORTNAV; - ProtCfg4.field.ProtectCtrl = ASIC_RTS; - ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; - Protect[2] = ProtCfg.word; - Protect[3] = ProtCfg4.word; - Protect[4] = ProtCfg.word; - Protect[5] = ProtCfg4.word; - pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; - break; - - case 2: - // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets - ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None) - ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1. - - //Assign Protection method for 40MHz packets - ProtCfg4.field.ProtectCtrl = ASIC_RTS; - ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; - Protect[2] = ProtCfg.word; - Protect[3] = ProtCfg4.word; - if (bNonGFExist) + else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) { - ProtCfg.field.ProtectCtrl = ASIC_RTS; - ProtCfg.field.ProtectNav = ASIC_SHORTNAV; - } - Protect[4] = ProtCfg.word; - Protect[5] = ProtCfg4.word; + // If it's not mixed mode, we should only let BSS pass with the same encryption + if (pInBss->WPA2.bMixMode == FALSE) + if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher) + continue; - pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE; - break; + // check group cipher + if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) && + (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) && + (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled)) + continue; - case 3: - // HT mixed mode. PROTECT ALL! - // Assign Rate - ProtCfg.word = 0x01744004; //duplicaet legacy 24M. BW set 1. - ProtCfg4.word = 0x03f44084; - // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED)) - { - ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18.. - ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083 - } - //Assign Protection method for 20&40 MHz packets - ProtCfg.field.ProtectCtrl = ASIC_RTS; - ProtCfg.field.ProtectNav = ASIC_SHORTNAV; - ProtCfg4.field.ProtectCtrl = ASIC_RTS; - ProtCfg4.field.ProtectNav = ASIC_SHORTNAV; - Protect[2] = ProtCfg.word; - Protect[3] = ProtCfg4.word; - Protect[4] = ProtCfg.word; - Protect[5] = ProtCfg4.word; - pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; - break; + // check pairwise cipher, skip if none matched + // If profile set to AES, let it pass without question. + // If profile set to TKIP, we must find one mateched + if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) && + (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) && + (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux)) + continue; + } + } + // Bss Type matched, SSID matched. + // We will check wepstatus for qualification Bss + else if (pAd->StaCfg.WepStatus != pInBss->WepStatus) + { + DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus)); + // + // For the SESv2 case, we will not qualify WepStatus. + // + if (!pInBss->bSES) + continue; + } - case 8: - // Special on for Atheros problem n chip. - Protect[2] = 0x01754004; - Protect[3] = 0x03f54084; - Protect[4] = 0x01754004; - Protect[5] = 0x03f54084; - pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE; - break; - } - } + // Since the AP is using hidden SSID, and we are trying to connect to ANY + // It definitely will fail. So, skip it. + // CCX also require not even try to connect it!! + if (SsidLen == 0) + continue; - offset = CCK_PROT_CFG; - for (i = 0;i < 6;i++) + // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region + // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, + if ((pInBss->CentralChannel != pInBss->Channel) && + (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) { - if ((SetMask & (1<< i))) - { - RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]); + if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE) + { + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; + SetCommonHT(pAd); + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; + } + else + { + if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20) + { + SetCommonHT(pAd); + } } } -} - -#ifdef RT2870 -/* - ========================================================================== - Description: - - Load RF normal operation-mode setup - - ========================================================================== - */ -VOID RT30xxLoadRFNormalModeSetup( - IN PRTMP_ADAPTER pAd) -{ - UCHAR RFValue; - - // RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1 - RT30xxReadRFRegister(pAd, RF_R01, &RFValue); - RFValue = (RFValue & (~0x0C)) | 0x31; - RT30xxWriteRFRegister(pAd, RF_R01, RFValue); - - // TX_LO2_en, RF R15 register Bit 3 to 0 - RT30xxReadRFRegister(pAd, RF_R15, &RFValue); - RFValue &= (~0x08); - RT30xxWriteRFRegister(pAd, RF_R15, RFValue); - - // TX_LO1_en, RF R17 register Bit 3 to 0 - RT30xxReadRFRegister(pAd, RF_R17, &RFValue); - RFValue &= (~0x08); - // to fix rx long range issue - if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0)) - { - RFValue |= 0x20; - } - RT30xxWriteRFRegister(pAd, RF_R17, RFValue); - - // RX_LO1_en, RF R20 register Bit 3 to 0 - RT30xxReadRFRegister(pAd, RF_R20, &RFValue); - RFValue &= (~0x08); - RT30xxWriteRFRegister(pAd, RF_R20, RFValue); - - // RX_LO2_en, RF R21 register Bit 3 to 0 - RT30xxReadRFRegister(pAd, RF_R21, &RFValue); - RFValue &= (~0x08); - RT30xxWriteRFRegister(pAd, RF_R21, RFValue); - - // LDORF_VC, RF R27 register Bit 2 to 0 - RT30xxReadRFRegister(pAd, RF_R27, &RFValue); - if ((pAd->MACVersion & 0xffff) < 0x0211) - RFValue = (RFValue & (~0x77)) | 0x3; - else - RFValue = (RFValue & (~0x77)); - RT30xxWriteRFRegister(pAd, RF_R27, RFValue); - /* end johnli */ -} -/* - ========================================================================== - Description: - - Load RF sleep-mode setup - - ========================================================================== - */ -VOID RT30xxLoadRFSleepModeSetup( - IN PRTMP_ADAPTER pAd) -{ - UCHAR RFValue; - UINT32 MACValue; - - // RF_BLOCK_en. RF R1 register Bit 0 to 0 - RT30xxReadRFRegister(pAd, RF_R01, &RFValue); - RFValue &= (~0x01); - RT30xxWriteRFRegister(pAd, RF_R01, RFValue); - - // VCO_IC, RF R7 register Bit 4 & Bit 5 to 0 - RT30xxReadRFRegister(pAd, RF_R07, &RFValue); - RFValue &= (~0x30); - RT30xxWriteRFRegister(pAd, RF_R07, RFValue); - - // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0 - RT30xxReadRFRegister(pAd, RF_R09, &RFValue); - RFValue &= (~0x0E); - RT30xxWriteRFRegister(pAd, RF_R09, RFValue); - - // RX_CTB_en, RF R21 register Bit 7 to 0 - RT30xxReadRFRegister(pAd, RF_R21, &RFValue); - RFValue &= (~0x80); - RT30xxWriteRFRegister(pAd, RF_R21, RFValue); - - // LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1 - RT30xxReadRFRegister(pAd, RF_R27, &RFValue); - RFValue |= 0x77; - RT30xxWriteRFRegister(pAd, RF_R27, RFValue); - - RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); - MACValue |= 0x1D000000; - RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); -} - -/* - ========================================================================== - Description: - - Reverse RF sleep-mode setup + // copy matching BSS from InTab to OutTab + NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY)); - ========================================================================== - */ -VOID RT30xxReverseRFSleepModeSetup( - IN PRTMP_ADAPTER pAd) -{ - UCHAR RFValue; - UINT32 MACValue; + OutTab->BssNr++; + } + else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0)) + { + BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr]; - // RF_BLOCK_en, RF R1 register Bit 0 to 1 - RT30xxReadRFRegister(pAd, RF_R01, &RFValue); - RFValue |= 0x01; - RT30xxWriteRFRegister(pAd, RF_R01, RFValue); - - // VCO_IC, RF R7 register Bit 4 & Bit 5 to 1 - RT30xxReadRFRegister(pAd, RF_R07, &RFValue); - RFValue |= 0x30; - RT30xxWriteRFRegister(pAd, RF_R07, RFValue); - - // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1 - RT30xxReadRFRegister(pAd, RF_R09, &RFValue); - RFValue |= 0x0E; - RT30xxWriteRFRegister(pAd, RF_R09, RFValue); - - // RX_CTB_en, RF R21 register Bit 7 to 1 - RT30xxReadRFRegister(pAd, RF_R21, &RFValue); - RFValue |= 0x80; - RT30xxWriteRFRegister(pAd, RF_R21, RFValue); - - // LDORF_VC, RF R27 register Bit 2 to 0 - RT30xxReadRFRegister(pAd, RF_R27, &RFValue); - if ((pAd->MACVersion & 0xffff) < 0x0211) - RFValue = (RFValue & (~0x77)) | 0x3; - else - RFValue = (RFValue & (~0x77)); - RT30xxWriteRFRegister(pAd, RF_R27, RFValue); - // RT3071 version E has fixed this issue - if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211)) - { - // patch tx EVM issue temporarily - RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); - MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000); - RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); - } - else - { - RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue); - MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000); - RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue); - } -} -#endif + // 2.4G/5G N only mode + if ((pInBss->HtCapabilityLen == 0) && + ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) + { + DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n")); + continue; + } +#ifdef RT2860 + if ((pAd->CommonCfg.PhyMode == PHY_11GN_MIXED) && + ((pInBss->SupRateLen + pInBss->ExtRateLen) < 12)) + { + DBGPRINT(RT_DEBUG_TRACE,("STA is in GN-only Mode, this AP is in B mode.\n")); + continue; + } +#endif // RT2860 // + // New for WPA2 + // Check the Authmode first + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + { + // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode + if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux)) + // None matched + continue; -/* - ========================================================================== - Description: + // Check cipher suite, AP must have more secured cipher than station setting + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) + { + // If it's not mixed mode, we should only let BSS pass with the same encryption + if (pInBss->WPA.bMixMode == FALSE) + if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher) + continue; - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL + // check group cipher + if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) + continue; - ========================================================================== - */ -VOID AsicSwitchChannel( - IN PRTMP_ADAPTER pAd, - IN UCHAR Channel, - IN BOOLEAN bScan) -{ - ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0; - CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER; - UCHAR index; - UINT32 Value = 0; //BbpReg, Value; - RTMP_RF_REGS *RFRegTable; - - // Search Tx power value - // We can't use ChannelList to search channel, since some central channl's txpowr doesn't list - // in ChannelList, so use TxPower array instead. - // - for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) - { - if (Channel == pAd->TxPower[index].Channel) - { - TxPwer = pAd->TxPower[index].Power; - TxPwer2 = pAd->TxPower[index].Power2; - break; - } - } + // check pairwise cipher, skip if none matched + // If profile set to AES, let it pass without question. + // If profile set to TKIP, we must find one mateched + if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) && + (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) && + (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux)) + continue; + } + else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + // If it's not mixed mode, we should only let BSS pass with the same encryption + if (pInBss->WPA2.bMixMode == FALSE) + if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher) + continue; - if (index == MAX_NUM_OF_CHANNELS) - DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel)); + // check group cipher + if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher) + continue; -#ifdef RT2870 - // The RF programming sequence is difference between 3xxx and 2xxx - if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && ( - (pAd->RfIcType == RFIC_3022) || (pAd->RfIcType == RFIC_3021) || - (pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020))) - { - /* modify by WY for Read RF Reg. error */ - UCHAR RFValue; - - for (index = 0; index < NUM_OF_3020_CHNL; index++) - { - if (Channel == FreqItems3020[index].Channel) - { - // Programming channel parameters - RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N); - RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K); - - RT30xxReadRFRegister(pAd, RF_R06, &RFValue); - RFValue = (RFValue & 0xFC) | FreqItems3020[index].R; - RT30xxWriteRFRegister(pAd, RF_R06, RFValue); - - // Set Tx0 Power - RT30xxReadRFRegister(pAd, RF_R12, &RFValue); - RFValue = (RFValue & 0xE0) | TxPwer; - RT30xxWriteRFRegister(pAd, RF_R12, RFValue); - - // Set Tx1 Power - RT30xxReadRFRegister(pAd, RF_R13, &RFValue); - RFValue = (RFValue & 0xE0) | TxPwer2; - RT30xxWriteRFRegister(pAd, RF_R13, RFValue); - - // Tx/Rx Stream setting - RT30xxReadRFRegister(pAd, RF_R01, &RFValue); - //if (IS_RT3090(pAd)) - // RFValue |= 0x01; // Enable RF block. - RFValue &= 0x03; //clear bit[7~2] - if (pAd->Antenna.field.TxPath == 1) - RFValue |= 0xA0; - else if (pAd->Antenna.field.TxPath == 2) - RFValue |= 0x80; - if (pAd->Antenna.field.RxPath == 1) - RFValue |= 0x50; - else if (pAd->Antenna.field.RxPath == 2) - RFValue |= 0x40; - RT30xxWriteRFRegister(pAd, RF_R01, RFValue); - - // Set RF offset - RT30xxReadRFRegister(pAd, RF_R23, &RFValue); - RFValue = (RFValue & 0x80) | pAd->RfFreqOffset; - RT30xxWriteRFRegister(pAd, RF_R23, RFValue); + // check pairwise cipher, skip if none matched + // If profile set to AES, let it pass without question. + // If profile set to TKIP, we must find one mateched + if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) && + (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) && + (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux)) + continue; + } + } + // Bss Type matched, SSID matched. + // We will check wepstatus for qualification Bss + else if (pAd->StaCfg.WepStatus != pInBss->WepStatus) + continue; - // Set BW - if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40)) + // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region + // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, + if ((pInBss->CentralChannel != pInBss->Channel) && + (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) { - RFValue = pAd->Mlme.CaliBW40RfR24; - //DISABLE_11N_CHECK(pAd); - } - else + if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE) { - RFValue = pAd->Mlme.CaliBW20RfR24; + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; + SetCommonHT(pAd); + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; + } } - RT30xxWriteRFRegister(pAd, RF_R24, RFValue); - RT30xxWriteRFRegister(pAd, RF_R31, RFValue); - // Enable RF tuning - RT30xxReadRFRegister(pAd, RF_R07, &RFValue); - RFValue = RFValue | 0x1; - RT30xxWriteRFRegister(pAd, RF_R07, RFValue); - - // latch channel for future usage. - pAd->LatchRfRegs.Channel = Channel; - - DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", - Channel, - pAd->RfIcType, - TxPwer, - TxPwer2, - pAd->Antenna.field.TxPath, - FreqItems3020[index].N, - FreqItems3020[index].K, - FreqItems3020[index].R)); + // copy matching BSS from InTab to OutTab + NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY)); + + OutTab->BssNr++; + } + + if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE) break; } - } - DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n", - Channel, - pAd->RfIcType, - TxPwer, - TxPwer2, - pAd->Antenna.field.TxPath, - FreqItems3020[index].N, - FreqItems3020[index].K, - FreqItems3020[index].R)); - } - else -#endif // RT2870 // - { - RFRegTable = RF2850RegTable; + BssTableSortByRssi(OutTab); +} - switch (pAd->RfIcType) - { - case RFIC_2820: - case RFIC_2850: - case RFIC_2720: - case RFIC_2750: - for (index = 0; index < NUM_OF_2850_CHNL; index++) +// IRQL = DISPATCH_LEVEL +VOID BssTableSortByRssi( + IN OUT BSS_TABLE *OutTab) +{ + INT i, j; + BSS_ENTRY TmpBss; + + for (i = 0; i < OutTab->BssNr - 1; i++) { - if (Channel == RFRegTable[index].Channel) + for (j = i+1; j < OutTab->BssNr; j++) { - R2 = RFRegTable[index].R2; - if (pAd->Antenna.field.TxPath == 1) + if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi) { - R2 |= 0x4000; // If TXpath is 1, bit 14 = 1; + NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY)); + NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY)); + NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY)); } - - if (pAd->Antenna.field.RxPath == 2) - { - R2 |= 0x40; // write 1 to off Rxpath. } - else if (pAd->Antenna.field.RxPath == 1) - { - R2 |= 0x20040; // write 1 to off RxPath } +} - if (Channel > 14) - { - // initialize R3, R4 - R3 = (RFRegTable[index].R3 & 0xffffc1ff); - R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15); - - // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB - // R3 - if ((TxPwer >= -7) && (TxPwer < 0)) - { - TxPwer = (7+TxPwer); - TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer); - R3 |= (TxPwer << 10); - DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer)); - } - else - { - TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer); - R3 |= (TxPwer << 10) | (1 << 9); - } - // R4 - if ((TxPwer2 >= -7) && (TxPwer2 < 0)) - { - TxPwer2 = (7+TxPwer2); - TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2); - R4 |= (TxPwer2 << 7); - DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2)); - } - else +VOID BssCipherParse( + IN OUT PBSS_ENTRY pBss) +{ + PEID_STRUCT pEid; + PUCHAR pTmp; + PRSN_IE_HEADER_STRUCT pRsnHeader; + PCIPHER_SUITE_STRUCT pCipher; + PAKM_SUITE_STRUCT pAKM; + USHORT Count; + INT Length; + NDIS_802_11_ENCRYPTION_STATUS TmpCipher; + + // + // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame. + // + if (pBss->Privacy) { - TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2); - R4 |= (TxPwer2 << 7) | (1 << 6); - } + pBss->WepStatus = Ndis802_11WEPEnabled; } else { - R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0 - R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1 - } - - // Based on BBP current mode before changing RF channel. - if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40)) - { - R4 |=0x200000; + pBss->WepStatus = Ndis802_11WEPDisabled; } + // Set default to disable & open authentication before parsing variable IE + pBss->AuthMode = Ndis802_11AuthModeOpen; + pBss->AuthModeAux = Ndis802_11AuthModeOpen; - // Update variables - pAd->LatchRfRegs.Channel = Channel; - pAd->LatchRfRegs.R1 = RFRegTable[index].R1; - pAd->LatchRfRegs.R2 = R2; - pAd->LatchRfRegs.R3 = R3; - pAd->LatchRfRegs.R4 = R4; - - // Set RF value 1's set R3[bit2] = [0] - RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); - RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); - RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04))); - RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); - - RTMPusecDelay(200); - - // Set RF value 2's set R3[bit2] = [1] - RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); - RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); - RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04)); - RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); - - RTMPusecDelay(200); - - // Set RF value 3's set R3[bit2] = [0] - RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1); - RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2); - RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04))); - RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4); - - break; - } - } - break; + // Init WPA setting + pBss->WPA.PairCipher = Ndis802_11WEPDisabled; + pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled; + pBss->WPA.GroupCipher = Ndis802_11WEPDisabled; + pBss->WPA.RsnCapability = 0; + pBss->WPA.bMixMode = FALSE; - default: - break; - } - } + // Init WPA2 setting + pBss->WPA2.PairCipher = Ndis802_11WEPDisabled; + pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled; + pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled; + pBss->WPA2.RsnCapability = 0; + pBss->WPA2.bMixMode = FALSE; - // Change BBP setting during siwtch from a->g, g->a - if (Channel <= 14) - { - ULONG TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); - 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. - //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); + Length = (INT) pBss->VarIELen; - // Rx High power VGA offset for LNA select - if (pAd->NicConfig2.field.ExternalLNAForG) + while (Length > 0) { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); - } - else + // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently + pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length; + pEid = (PEID_STRUCT) pTmp; + switch (pEid->Eid) { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); - } - - // 5G band selection PIN, bit1 and bit2 are complement - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); - Value &= (~0x6); - Value |= (0x04); - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); - - // Turn off unused PA or LNA when only 1T or 1R - if (pAd->Antenna.field.TxPath == 1) + case IE_WPA: + if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7)) { - TxPinCfg &= 0xFFFFFFF3; + pBss->bSES = TRUE; + break; } - if (pAd->Antenna.field.RxPath == 1) + else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1) { - TxPinCfg &= 0xFFFFF3FF; + // if unsupported vendor specific IE + break; } + // Skip OUI, version, and multicast suite + // This part should be improved in the future when AP supported multiple cipher suite. + // For now, it's OK since almost all APs have fixed cipher suite supported. + // pTmp = (PUCHAR) pEid->Octet; + pTmp += 11; - RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); - } - else + // Cipher Suite Selectors from Spec P802.11i/D3.2 P26. + // Value Meaning + // 0 None + // 1 WEP-40 + // 2 Tkip + // 3 WRAP + // 4 AES + // 5 WEP-104 + // Parse group cipher + switch (*pTmp) { - ULONG TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505 - - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd))); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd))); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd))); - 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. - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2); - - // Rx High power VGA offset for LNA select - if (pAd->NicConfig2.field.ExternalLNAForA) - { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46); - } - else - { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50); - } + case 1: + pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled; + break; + case 5: + pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled; + break; + case 2: + pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled; + break; + case 4: + pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled; + break; + default: + break; + } + // number of unicast suite + pTmp += 1; - // 5G band selection PIN, bit1 and bit2 are complement - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value); - Value &= (~0x6); - Value |= (0x02); - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value); + // skip all unicast cipher suites + //Count = *(PUSHORT) pTmp; + Count = (pTmp[1]<<8) + pTmp[0]; + pTmp += sizeof(USHORT); - // Turn off unused PA or LNA when only 1T or 1R - if (pAd->Antenna.field.TxPath == 1) - { - TxPinCfg &= 0xFFFFFFF3; - } - if (pAd->Antenna.field.RxPath == 1) + // Parsing all unicast cipher suite + while (Count > 0) { - TxPinCfg &= 0xFFFFF3FF; - } - - RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg); - } - - // R66 should be set according to Channel and use 20MHz when scanning - //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd))); - if (bScan) - RTMPSetAGCInitValue(pAd, BW_20); - else - RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); - - // - // On 11A, We should delay and wait RF/BBP to be stable - // and the appropriate time should be 1000 micro seconds - // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. - // - RTMPusecDelay(1000); - - 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", - Channel, - pAd->RfIcType, - (R3 & 0x00003e00) >> 9, - (R4 & 0x000007c0) >> 6, - pAd->Antenna.field.TxPath, - pAd->LatchRfRegs.R1, - pAd->LatchRfRegs.R2, - pAd->LatchRfRegs.R3, - pAd->LatchRfRegs.R4)); -} - -/* - ========================================================================== - Description: - This function is required for 2421 only, and should not be used during - site survey. It's only required after NIC decided to stay at a channel - for a longer period. - When this function is called, it's always after AsicSwitchChannel(). - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -VOID AsicLockChannel( - IN PRTMP_ADAPTER pAd, - IN UCHAR Channel) -{ -} - -VOID AsicRfTuningExec( - IN PVOID SystemSpecific1, - IN PVOID FunctionContext, - IN PVOID SystemSpecific2, - IN PVOID SystemSpecific3) -{ -} - -/* - ========================================================================== - Description: - Gives CCK TX rate 2 more dB TX power. - This routine works only in LINK UP in INFRASTRUCTURE mode. - - calculate desired Tx power in RF R3.Tx0~5, should consider - - 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment) - 1. TxPowerPercentage - 2. auto calibration based on TSSI feedback - 3. extra 2 db for CCK - 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP - - NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment), - it should be called AFTER MlmeDynamicTxRatSwitching() - ========================================================================== - */ -VOID AsicAdjustTxPower( - IN PRTMP_ADAPTER pAd) -{ - INT i, j; - CHAR DeltaPwr = 0; - BOOLEAN bAutoTxAgc = FALSE; - UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep; - UCHAR BbpR1 = 0, BbpR49 = 0, idx; - PCHAR pTxAgcCompensate; - ULONG TxPwr[5]; - CHAR Value; - -#ifdef RT2860 - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) - || (pAd->bPCIclkOff == TRUE) - || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) - || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - return; -#endif - - if (pAd->CommonCfg.BBPCurrentBW == BW_40) - { - if (pAd->CommonCfg.CentralChannel > 14) + // Skip OUI + pTmp += 3; + TmpCipher = Ndis802_11WEPDisabled; + switch (*pTmp) { - TxPwr[0] = pAd->Tx40MPwrCfgABand[0]; - TxPwr[1] = pAd->Tx40MPwrCfgABand[1]; - TxPwr[2] = pAd->Tx40MPwrCfgABand[2]; - TxPwr[3] = pAd->Tx40MPwrCfgABand[3]; - TxPwr[4] = pAd->Tx40MPwrCfgABand[4]; + case 1: + case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway + TmpCipher = Ndis802_11Encryption1Enabled; + break; + case 2: + TmpCipher = Ndis802_11Encryption2Enabled; + break; + case 4: + TmpCipher = Ndis802_11Encryption3Enabled; + break; + default: + break; } - else + if (TmpCipher > pBss->WPA.PairCipher) { - TxPwr[0] = pAd->Tx40MPwrCfgGBand[0]; - TxPwr[1] = pAd->Tx40MPwrCfgGBand[1]; - TxPwr[2] = pAd->Tx40MPwrCfgGBand[2]; - TxPwr[3] = pAd->Tx40MPwrCfgGBand[3]; - TxPwr[4] = pAd->Tx40MPwrCfgGBand[4]; - } + // Move the lower cipher suite to PairCipherAux + pBss->WPA.PairCipherAux = pBss->WPA.PairCipher; + pBss->WPA.PairCipher = TmpCipher; } - else - { - if (pAd->CommonCfg.Channel > 14) - { - TxPwr[0] = pAd->Tx20MPwrCfgABand[0]; - TxPwr[1] = pAd->Tx20MPwrCfgABand[1]; - TxPwr[2] = pAd->Tx20MPwrCfgABand[2]; - TxPwr[3] = pAd->Tx20MPwrCfgABand[3]; - TxPwr[4] = pAd->Tx20MPwrCfgABand[4]; - } - else + else { - TxPwr[0] = pAd->Tx20MPwrCfgGBand[0]; - TxPwr[1] = pAd->Tx20MPwrCfgGBand[1]; - TxPwr[2] = pAd->Tx20MPwrCfgGBand[2]; - TxPwr[3] = pAd->Tx20MPwrCfgGBand[3]; - TxPwr[4] = pAd->Tx20MPwrCfgGBand[4]; - } + pBss->WPA.PairCipherAux = TmpCipher; + } + pTmp++; + Count--; } - // TX power compensation for temperature variation based on TSSI. try every 4 second - if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) - { - if (pAd->CommonCfg.Channel <= 14) - { - /* bg channel */ - bAutoTxAgc = pAd->bAutoTxAgcG; - TssiRef = pAd->TssiRefG; - pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0]; - pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0]; - TxAgcStep = pAd->TxAgcStepG; - pTxAgcCompensate = &pAd->TxAgcCompensateG; - } + // 4. get AKM suite counts + //Count = *(PUSHORT) pTmp; + Count = (pTmp[1]<<8) + pTmp[0]; + pTmp += sizeof(USHORT); + pTmp += 3; + + switch (*pTmp) + { + case 1: + // Set AP support WPA-enterprise mode + if (pBss->AuthMode == Ndis802_11AuthModeOpen) + pBss->AuthMode = Ndis802_11AuthModeWPA; + else + pBss->AuthModeAux = Ndis802_11AuthModeWPA; + break; + case 2: + // Set AP support WPA-PSK mode + if (pBss->AuthMode == Ndis802_11AuthModeOpen) + pBss->AuthMode = Ndis802_11AuthModeWPAPSK; else + pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK; + break; + default: + break; + } + pTmp += 1; + + // Fixed for WPA-None + if (pBss->BssType == BSS_ADHOC) { - /* a channel */ - bAutoTxAgc = pAd->bAutoTxAgcA; - TssiRef = pAd->TssiRefA; - pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0]; - pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0]; - TxAgcStep = pAd->TxAgcStepA; - pTxAgcCompensate = &pAd->TxAgcCompensateA; + pBss->AuthMode = Ndis802_11AuthModeWPANone; + pBss->AuthModeAux = Ndis802_11AuthModeWPANone; + pBss->WepStatus = pBss->WPA.GroupCipher; + // Patched bugs for old driver + if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) + pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher; } + else + pBss->WepStatus = pBss->WPA.PairCipher; - if (bAutoTxAgc) - { - /* BbpR1 is unsigned char */ - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49); + // Check the Pair & Group, if different, turn on mixed mode flag + if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher) + pBss->WPA.bMixMode = TRUE; - /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */ - /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */ - /* step value is defined in pAd->TxAgcStepG for tx power value */ + break; - /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */ - /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0 - above value are examined in mass factory production */ - /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */ + case IE_RSN: + pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp; - /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */ - /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */ - /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */ + // 0. Version must be 1 + if (le2cpu16(pRsnHeader->Version) != 1) + break; + pTmp += sizeof(RSN_IE_HEADER_STRUCT); - if (BbpR49 > pTssiMinusBoundary[1]) - { - // Reading is larger than the reference value - // check for how large we need to decrease the Tx power - for (idx = 1; idx < 5; idx++) - { - if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range + // 1. Check group cipher + pCipher = (PCIPHER_SUITE_STRUCT) pTmp; + if (!RTMPEqualMemory(pTmp, RSN_OUI, 3)) break; - } - // The index is the step we should decrease, idx = 0 means there is nothing to compensate - *pTxAgcCompensate = -(TxAgcStep * (idx-1)); - DeltaPwr += (*pTxAgcCompensate); - DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n", - BbpR49, TssiRef, TxAgcStep, idx-1)); - } - else if (BbpR49 < pTssiPlusBoundary[1]) - { - // Reading is smaller than the reference value - // check for how large we need to increase the Tx power - for (idx = 1; idx < 5; idx++) + // Parse group cipher + switch (pCipher->Type) { - if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range + case 1: + pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled; + break; + case 5: + pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled; + break; + case 2: + pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled; + break; + case 4: + pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled; + break; + default: break; } - // The index is the step we should increase, idx = 0 means there is nothing to compensate - *pTxAgcCompensate = TxAgcStep * (idx-1); - DeltaPwr += (*pTxAgcCompensate); - DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", - BbpR49, TssiRef, TxAgcStep, idx-1)); - } - else - { - *pTxAgcCompensate = 0; - DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n", - BbpR49, TssiRef, TxAgcStep, 0)); - } - } - } - else - { - if (pAd->CommonCfg.Channel <= 14) - { - bAutoTxAgc = pAd->bAutoTxAgcG; - pTxAgcCompensate = &pAd->TxAgcCompensateG; - } - else - { - bAutoTxAgc = pAd->bAutoTxAgcA; - pTxAgcCompensate = &pAd->TxAgcCompensateA; - } - - if (bAutoTxAgc) - DeltaPwr += (*pTxAgcCompensate); - } + // set to correct offset for next parsing + pTmp += sizeof(CIPHER_SUITE_STRUCT); - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1); - BbpR1 &= 0xFC; + // 2. Get pairwise cipher counts + //Count = *(PUSHORT) pTmp; + Count = (pTmp[1]<<8) + pTmp[0]; + pTmp += sizeof(USHORT); - /* calculate delta power based on the percentage specified from UI */ - // E2PROM setting is calibrated for maximum TX power (i.e. 100%) - // We lower TX power here according to the percentage specified from UI - if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control - ; - else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW - ; - else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1; + // 3. Get pairwise cipher + // Parsing all unicast cipher suite + while (Count > 0) { - DeltaPwr -= 1; - } - else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3; + // Skip OUI + pCipher = (PCIPHER_SUITE_STRUCT) pTmp; + TmpCipher = Ndis802_11WEPDisabled; + switch (pCipher->Type) { - DeltaPwr -= 3; + case 1: + case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway + TmpCipher = Ndis802_11Encryption1Enabled; + break; + case 2: + TmpCipher = Ndis802_11Encryption2Enabled; + break; + case 4: + TmpCipher = Ndis802_11Encryption3Enabled; + break; + default: + break; } - else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6; + if (TmpCipher > pBss->WPA2.PairCipher) { - BbpR1 |= 0x01; + // Move the lower cipher suite to PairCipherAux + pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher; + pBss->WPA2.PairCipher = TmpCipher; } - else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9; + else { - BbpR1 |= 0x01; - DeltaPwr -= 3; + pBss->WPA2.PairCipherAux = TmpCipher; } - else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12; - { - BbpR1 |= 0x02; + pTmp += sizeof(CIPHER_SUITE_STRUCT); + Count--; } - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1); + // 4. get AKM suite counts + //Count = *(PUSHORT) pTmp; + Count = (pTmp[1]<<8) + pTmp[0]; + pTmp += sizeof(USHORT); - /* reset different new tx power for different TX rate */ - for(i=0; i<5; i++) - { - if (TxPwr[i] != 0xffffffff) - { - for (j=0; j<8; j++) + // 5. Get AKM ciphers + // Parsing all AKM ciphers + while (Count > 0) { - Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */ + pAKM = (PAKM_SUITE_STRUCT) pTmp; + if (!RTMPEqualMemory(pTmp, RSN_OUI, 3)) + break; - if ((Value + DeltaPwr) < 0) - { - Value = 0; /* min */ - } - else if ((Value + DeltaPwr) > 0xF) + switch (pAKM->Type) { - Value = 0xF; /* max */ - } + case 1: + // Set AP support WPA-enterprise mode + if (pBss->AuthMode == Ndis802_11AuthModeOpen) + pBss->AuthMode = Ndis802_11AuthModeWPA2; else - { - Value += DeltaPwr; /* temperature compensation */ - } - - /* fill new value to CSR offset */ - TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4); - } - - /* write tx power value to CSR */ - /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M - TX power for OFDM 6M/9M - TX power for CCK5.5M/11M - TX power for CCK1M/2M */ - /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */ - RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]); - } - } - -} - -/* - ========================================================================== - Description: - put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup - automatically. Instead, MCU will issue a TwakeUpInterrupt to host after - the wakeup timer timeout. Driver has to issue a separate command to wake - PHY up. - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -VOID AsicSleepThenAutoWakeup( - IN PRTMP_ADAPTER pAd, - IN USHORT TbttNumToNextWakeUp) -{ - RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp); -} - -/* - ========================================================================== - Description: - AsicForceWakeup() is used whenever manual wakeup is required - AsicForceSleep() should only be used when not in INFRA BSS. When - in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead. - ========================================================================== - */ -VOID AsicForceSleep( - IN PRTMP_ADAPTER pAd) -{ - -} - -/* - ========================================================================== - Description: - AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup) - expired. - - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL - ========================================================================== - */ -VOID AsicForceWakeup( - IN PRTMP_ADAPTER pAd, -#ifdef RT2860 - IN UCHAR Level) -#endif -#ifdef RT2870 - IN BOOLEAN bFromTx) -#endif -{ - DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n")); -#ifdef RT2860 - RT28XX_STA_FORCE_WAKEUP(pAd, Level); -#endif -#ifdef RT2870 - RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx); -#endif -} - -/* - ========================================================================== - Description: - Set My BSSID - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -VOID AsicSetBssid( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pBssid) -{ - ULONG Addr4; - DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n", - pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5])); - - Addr4 = (ULONG)(pBssid[0]) | - (ULONG)(pBssid[1] << 8) | - (ULONG)(pBssid[2] << 16) | - (ULONG)(pBssid[3] << 24); - RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4); - - Addr4 = 0; - // always one BSSID in STA mode - Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8); - - RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4); -} - -VOID AsicSetMcastWC( - IN PRTMP_ADAPTER pAd) -{ - MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID]; - USHORT offset; - - pEntry->Sst = SST_ASSOC; - pEntry->Aid = MCAST_WCID; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index - pEntry->PsMode = PWR_ACTIVE; - pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate; - offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE; -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -VOID AsicDelWcidTab( - IN PRTMP_ADAPTER pAd, - IN UCHAR Wcid) -{ - ULONG Addr0 = 0x0, Addr1 = 0x0; - ULONG offset; - - DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid)); - offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE; - RTMP_IO_WRITE32(pAd, offset, Addr0); - offset += 4; - RTMP_IO_WRITE32(pAd, offset, Addr1); -} - -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL + pBss->AuthModeAux = Ndis802_11AuthModeWPA2; + break; + case 2: + // Set AP support WPA-PSK mode + if (pBss->AuthMode == Ndis802_11AuthModeOpen) + pBss->AuthMode = Ndis802_11AuthModeWPA2PSK; + else + pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK; + break; + default: + if (pBss->AuthMode == Ndis802_11AuthModeOpen) + pBss->AuthMode = Ndis802_11AuthModeMax; + else + pBss->AuthModeAux = Ndis802_11AuthModeMax; + break; + } + pTmp += (Count * sizeof(AKM_SUITE_STRUCT)); + Count--; + } - ========================================================================== - */ -VOID AsicEnableRDG( - IN PRTMP_ADAPTER pAd) -{ - TX_LINK_CFG_STRUC TxLinkCfg; - UINT32 Data = 0; + // Fixed for WPA-None + if (pBss->BssType == BSS_ADHOC) + { + pBss->AuthMode = Ndis802_11AuthModeWPANone; + pBss->AuthModeAux = Ndis802_11AuthModeWPANone; + pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux; + pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher; + pBss->WepStatus = pBss->WPA.GroupCipher; + // Patched bugs for old driver + if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled) + pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher; + } + pBss->WepStatus = pBss->WPA2.PairCipher; - RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); - TxLinkCfg.field.TxRDGEn = 1; - RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); + // 6. Get RSN capability + //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp; + pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0]; + pTmp += sizeof(USHORT); - RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); - Data &= 0xFFFFFF00; - Data |= 0x80; - RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); + // Check the Pair & Group, if different, turn on mixed mode flag + if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher) + pBss->WPA2.bMixMode = TRUE; - //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); + break; + default: + break; + } + Length -= (pEid->Len + 2); + } } -/* - ========================================================================== - Description: - - IRQL = DISPATCH_LEVEL +// =========================================================================================== +// mac_table.c +// =========================================================================================== - ========================================================================== +/*! \brief generates a random mac address value for IBSS BSSID + * \param Addr the bssid location + * \return none + * \pre + * \post */ -VOID AsicDisableRDG( - IN PRTMP_ADAPTER pAd) +VOID MacAddrRandomBssid( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pAddr) { - TX_LINK_CFG_STRUC TxLinkCfg; - UINT32 Data = 0; - - - RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word); - TxLinkCfg.field.TxRDGEn = 0; - RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word); - - RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data); + INT i; - Data &= 0xFFFFFF00; - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE) - && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE) - ) - { - // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode - if (pAd->CommonCfg.bEnableTxBurst) - Data |= 0x20; + for (i = 0; i < MAC_ADDR_LEN; i++) + { + pAddr[i] = RandomByte(pAd); } - RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data); + + pAddr[0] = (pAddr[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx } -/* - ========================================================================== - Description: +/*! \brief init the management mac frame header + * \param p_hdr mac header + * \param subtype subtype of the frame + * \param p_ds destination address, don't care if it is a broadcast address + * \return none + * \pre the station has the following information in the pAd->StaCfg + * - bssid + * - station address + * \post + * \note this function initializes the following field IRQL = PASSIVE_LEVEL IRQL = DISPATCH_LEVEL - ========================================================================== */ -VOID AsicDisableSync( - IN PRTMP_ADAPTER pAd) +VOID MgtMacHeaderInit( + IN PRTMP_ADAPTER pAd, + IN OUT PHEADER_802_11 pHdr80211, + IN UCHAR SubType, + IN UCHAR ToDs, + IN PUCHAR pDA, + IN PUCHAR pBssid) { - BCN_TIME_CFG_STRUC csr; - - DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n")); - - // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect - // that NIC will never wakes up because TSF stops and no more - // TBTT interrupts - pAd->TbttTickCount = 0; - RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); - csr.field.bBeaconGen = 0; - csr.field.bTBTTEnable = 0; - csr.field.TsfSyncMode = 0; - csr.field.bTsfTicking = 0; - RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); + NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11)); + pHdr80211->FC.Type = BTYPE_MGMT; + pHdr80211->FC.SubType = SubType; +// if (SubType == SUBTYPE_ACK) // sample, no use, it will conflict with ACTION frame sub type +// pHdr80211->FC.Type = BTYPE_CNTL; + pHdr80211->FC.ToDs = ToDs; + COPY_MAC_ADDR(pHdr80211->Addr1, pDA); + COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress); + COPY_MAC_ADDR(pHdr80211->Addr3, pBssid); } -/* - ========================================================================== - Description: +// =========================================================================================== +// mem_mgmt.c +// =========================================================================================== + +/*!*************************************************************************** + * This routine build an outgoing frame, and fill all information specified + * in argument list to the frame body. The actual frame size is the summation + * of all arguments. + * input params: + * Buffer - pointer to a pre-allocated memory segment + * args - a list of pairs. + * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this + * function will FAIL!!! + * return: + * Size of the buffer + * usage: + * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS); + IRQL = PASSIVE_LEVEL IRQL = DISPATCH_LEVEL - ========================================================================== - */ -VOID AsicEnableBssSync( - IN PRTMP_ADAPTER pAd) + ****************************************************************************/ +ULONG MakeOutgoingFrame( + OUT UCHAR *Buffer, + OUT ULONG *FrameLen, ...) { - BCN_TIME_CFG_STRUC csr; - - DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n")); - - RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word); + UCHAR *p; + int leng; + ULONG TotLeng; + va_list Args; + // calculates the total length + TotLeng = 0; + va_start(Args, FrameLen); + do { - csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU - csr.field.bTsfTicking = 1; - csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode - csr.field.bBeaconGen = 0; // do NOT generate BEACON - csr.field.bTBTTEnable = 1; + leng = va_arg(Args, int); + if (leng == END_OF_ARGS) + { + break; } + p = va_arg(Args, PVOID); + NdisMoveMemory(&Buffer[TotLeng], p, leng); + TotLeng = TotLeng + leng; + } while(TRUE); - RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word); + va_end(Args); /* clean up */ + *FrameLen = TotLeng; + return TotLeng; } -/* - ========================================================================== - Description: - Note: - BEACON frame in shared memory should be built ok before this routine - can be called. Otherwise, a garbage frame maybe transmitted out every - Beacon period. +// =========================================================================================== +// mlme_queue.c +// =========================================================================================== - IRQL = DISPATCH_LEVEL +/*! \brief Initialize The MLME Queue, used by MLME Functions + * \param *Queue The MLME Queue + * \return Always Return NDIS_STATE_SUCCESS in this implementation + * \pre + * \post + * \note Because this is done only once (at the init stage), no need to be locked + + IRQL = PASSIVE_LEVEL - ========================================================================== */ -VOID AsicEnableIbssSync( - IN PRTMP_ADAPTER pAd) +NDIS_STATUS MlmeQueueInit( + IN MLME_QUEUE *Queue) { - BCN_TIME_CFG_STRUC csr9; - PUCHAR ptr; - UINT i; - - DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount)); - - RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word); - csr9.field.bBeaconGen = 0; - csr9.field.bTBTTEnable = 0; - csr9.field.bTsfTicking = 0; - RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word); + INT i; -#ifdef RT2860 - // move BEACON TXD and frame content to on-chip memory - ptr = (PUCHAR)&pAd->BeaconTxWI; - for (i=0; iBeaconBuf; - for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=4) - { - UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); - RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr); - ptr +=4; - } -#endif -#ifdef RT2870 - // move BEACON TXD and frame content to on-chip memory - ptr = (PUCHAR)&pAd->BeaconTxWI; - for (i=0; iLock); + + Queue->Num = 0; + Queue->Head = 0; + Queue->Tail = 0; - // start right after the 16-byte TXWI field - ptr = pAd->BeaconBuf; - for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2) + for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++) { - RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2); - ptr +=2; + Queue->Entry[i].Occupied = FALSE; + Queue->Entry[i].MsgLen = 0; + NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE); } -#endif // RT2870 // - // start sending BEACON - csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU - csr9.field.bTsfTicking = 1; - csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode - csr9.field.bTBTTEnable = 1; - csr9.field.bBeaconGen = 1; - RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word); + return NDIS_STATUS_SUCCESS; } -/* - ========================================================================== - Description: +/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread + * \param *Queue The MLME Queue + * \param Machine The State Machine Id + * \param MsgType The Message Type + * \param MsgLen The Message length + * \param *Msg The message pointer + * \return TRUE if enqueue is successful, FALSE if the queue is full + * \pre + * \post + * \note The message has to be initialized IRQL = PASSIVE_LEVEL IRQL = DISPATCH_LEVEL - ========================================================================== */ -VOID AsicSetEdcaParm( +BOOLEAN MlmeEnqueue( IN PRTMP_ADAPTER pAd, - IN PEDCA_PARM pEdcaParm) + IN ULONG Machine, + IN ULONG MsgType, + IN ULONG MsgLen, + IN VOID *Msg) { - EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg; - AC_TXOP_CSR0_STRUC csr0; - AC_TXOP_CSR1_STRUC csr1; - AIFSN_CSR_STRUC AifsnCsr; - CWMIN_CSR_STRUC CwminCsr; - CWMAX_CSR_STRUC CwmaxCsr; - int i; + INT Tail; + MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue; - Ac0Cfg.word = 0; - Ac1Cfg.word = 0; - Ac2Cfg.word = 0; - Ac3Cfg.word = 0; - if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE)) - { - DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n")); - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED); - for (i=0; iMacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli) - CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE); - } - - //======================================================== - // MAC Register has a copy . - //======================================================== - if( pAd->CommonCfg.bEnableTxBurst ) - { - // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode - Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode - } - else - Ac0Cfg.field.AcTxop = 0; // QID_AC_BE - Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS; - Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS; - Ac0Cfg.field.Aifsn = 2; - RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word); - - Ac1Cfg.field.AcTxop = 0; // QID_AC_BK - Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS; - Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS; - Ac1Cfg.field.Aifsn = 2; - RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word); + // Do nothing if the driver is starting halt state. + // This might happen when timer already been fired before cancel timer with mlmehalt + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return FALSE; - if (pAd->CommonCfg.PhyMode == PHY_11B) - { - Ac2Cfg.field.AcTxop = 192; // AC_VI: 192*32us ~= 6ms - Ac3Cfg.field.AcTxop = 96; // AC_VO: 96*32us ~= 3ms - } - else + // First check the size, it MUST not exceed the mlme queue size + if (MsgLen > MGMT_DMA_BUFFER_SIZE) { - Ac2Cfg.field.AcTxop = 96; // AC_VI: 96*32us ~= 3ms - Ac3Cfg.field.AcTxop = 48; // AC_VO: 48*32us ~= 1.5ms - } - Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS; - Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS; - Ac2Cfg.field.Aifsn = 2; - RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word); - Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS; - Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS; - Ac3Cfg.field.Aifsn = 2; - RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word); - - //======================================================== - // DMA Register has a copy too. - //======================================================== - csr0.field.Ac0Txop = 0; // QID_AC_BE - csr0.field.Ac1Txop = 0; // QID_AC_BK - RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word); - if (pAd->CommonCfg.PhyMode == PHY_11B) + DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen)); + return FALSE; + } + + if (MlmeQueueFull(Queue)) { - csr1.field.Ac2Txop = 192; // AC_VI: 192*32us ~= 6ms - csr1.field.Ac3Txop = 96; // AC_VO: 96*32us ~= 3ms + return FALSE; + } + + NdisAcquireSpinLock(&(Queue->Lock)); + Tail = Queue->Tail; + Queue->Tail++; + Queue->Num++; + if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) + { + Queue->Tail = 0; } - else - { - csr1.field.Ac2Txop = 96; // AC_VI: 96*32us ~= 3ms - csr1.field.Ac3Txop = 48; // AC_VO: 48*32us ~= 1.5ms + + Queue->Entry[Tail].Wcid = RESERVED_WCID; + Queue->Entry[Tail].Occupied = TRUE; + Queue->Entry[Tail].Machine = Machine; + Queue->Entry[Tail].MsgType = MsgType; + Queue->Entry[Tail].MsgLen = MsgLen; + + if (Msg != NULL) + { + NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen); } - RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word); - CwminCsr.word = 0; - CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS; - CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS; - CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS; - CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS; - RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word); - - CwmaxCsr.word = 0; - CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS; - CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS; - CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS; - CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS; - RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word); + NdisReleaseSpinLock(&(Queue->Lock)); + return TRUE; +} + +/*! \brief This function is used when Recv gets a MLME message + * \param *Queue The MLME Queue + * \param TimeStampHigh The upper 32 bit of timestamp + * \param TimeStampLow The lower 32 bit of timestamp + * \param Rssi The receiving RSSI strength + * \param MsgLen The length of the message + * \param *Msg The message pointer + * \return TRUE if everything ok, FALSE otherwise (like Queue Full) + * \pre + * \post + + IRQL = DISPATCH_LEVEL + + */ +BOOLEAN MlmeEnqueueForRecv( + IN PRTMP_ADAPTER pAd, + IN ULONG Wcid, + IN ULONG TimeStampHigh, + IN ULONG TimeStampLow, + IN UCHAR Rssi0, + IN UCHAR Rssi1, + IN UCHAR Rssi2, + IN ULONG MsgLen, + IN VOID *Msg, + IN UCHAR Signal) +{ + INT Tail, Machine; + PFRAME_802_11 pFrame = (PFRAME_802_11)Msg; + INT MsgType; + MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue; - RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222); - NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM)); - } - else + // Do nothing if the driver is starting halt state. + // This might happen when timer already been fired before cancel timer with mlmehalt + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) { - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED); - //======================================================== - // MAC Register has a copy. - //======================================================== - // - // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27 - // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue. - // - //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this - - Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE]; - Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE]; - Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE]; - Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1; - - Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK]; - Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2; - Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK]; - Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1; + DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n")); + return FALSE; + } - Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10; - Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI]; - Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI]; - Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI]; + // First check the size, it MUST not exceed the mlme queue size + if (MsgLen > MGMT_DMA_BUFFER_SIZE) + { + DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen)); + return FALSE; + } + if (MlmeQueueFull(Queue)) { - // Tuning for Wi-Fi WMM S06 - if (pAd->CommonCfg.bWiFiTest && - pEdcaParm->Aifsn[QID_AC_VI] == 10) - Ac2Cfg.field.Aifsn -= 1; - - // Tuning for TGn Wi-Fi 5.2.32 - // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta - if (STA_TGN_WIFI_ON(pAd) && - pEdcaParm->Aifsn[QID_AC_VI] == 10) - { - Ac0Cfg.field.Aifsn = 3; - Ac2Cfg.field.AcTxop = 5; - } + return FALSE; + } -#ifdef RT2870 - if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020) { - // Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta. - Ac2Cfg.field.Aifsn = 5; + if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType)) + { + DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType)); + return FALSE; } -#endif } - Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO]; - Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO]; - Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO]; - Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO]; - -//#ifdef WIFI_TEST - if (pAd->CommonCfg.bWiFiTest) - { - if (Ac3Cfg.field.AcTxop == 102) - { - Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10; - Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */ - Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK]; - Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; - Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI]; - } /* End of if */ - } -//#endif // WIFI_TEST // - - RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word); - RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word); - RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word); - RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word); - - - //======================================================== - // DMA Register has a copy too. - //======================================================== - csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop; - csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop; - RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word); - - csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop; - csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop; - RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word); - - CwminCsr.word = 0; - CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE]; - CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK]; - CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI]; - - CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test - - RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word); - - CwmaxCsr.word = 0; - CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE]; - CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK]; - CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI]; - CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO]; - RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word); - - AifsnCsr.word = 0; - AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE]; - AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK]; - AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI]; - - { - // Tuning for Wi-Fi WMM S06 - if (pAd->CommonCfg.bWiFiTest && - pEdcaParm->Aifsn[QID_AC_VI] == 10) - AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4; - - // Tuning for TGn Wi-Fi 5.2.32 - // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta - if (STA_TGN_WIFI_ON(pAd) && - pEdcaParm->Aifsn[QID_AC_VI] == 10) - { - AifsnCsr.field.Aifsn0 = 3; - AifsnCsr.field.Aifsn2 = 7; - } -#ifdef RT2870 - if (INFRA_ON(pAd)) - CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE); -#endif + // OK, we got all the informations, it is time to put things into queue + NdisAcquireSpinLock(&(Queue->Lock)); + Tail = Queue->Tail; + Queue->Tail++; + Queue->Num++; + if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) + { + Queue->Tail = 0; } + Queue->Entry[Tail].Occupied = TRUE; + Queue->Entry[Tail].Machine = Machine; + Queue->Entry[Tail].MsgType = MsgType; + Queue->Entry[Tail].MsgLen = MsgLen; + Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow; + Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh; + Queue->Entry[Tail].Rssi0 = Rssi0; + Queue->Entry[Tail].Rssi1 = Rssi1; + Queue->Entry[Tail].Rssi2 = Rssi2; + Queue->Entry[Tail].Signal = Signal; + Queue->Entry[Tail].Wcid = (UCHAR)Wcid; - AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test -#ifdef RT2870 - if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020) - AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04. -#endif - RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word); + Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel; - NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM)); - if (!ADHOC_ON(pAd)) - { - DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount)); - DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n", - pEdcaParm->Aifsn[0], - pEdcaParm->Cwmin[0], - pEdcaParm->Cwmax[0], - pEdcaParm->Txop[0]<<5, - pEdcaParm->bACM[0])); - DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n", - pEdcaParm->Aifsn[1], - pEdcaParm->Cwmin[1], - pEdcaParm->Cwmax[1], - pEdcaParm->Txop[1]<<5, - pEdcaParm->bACM[1])); - DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n", - pEdcaParm->Aifsn[2], - pEdcaParm->Cwmin[2], - pEdcaParm->Cwmax[2], - pEdcaParm->Txop[2]<<5, - pEdcaParm->bACM[2])); - DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n", - pEdcaParm->Aifsn[3], - pEdcaParm->Cwmin[3], - pEdcaParm->Cwmax[3], - pEdcaParm->Txop[3]<<5, - pEdcaParm->bACM[3])); - } + if (Msg != NULL) + { + NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen); } -} -/* - ========================================================================== - Description: + NdisReleaseSpinLock(&(Queue->Lock)); - IRQL = PASSIVE_LEVEL - IRQL = DISPATCH_LEVEL + RTMP_MLME_HANDLER(pAd); - ========================================================================== - */ -VOID AsicSetSlotTime( - IN PRTMP_ADAPTER pAd, - IN BOOLEAN bUseShortSlotTime) -{ - ULONG SlotTime; - UINT32 RegValue = 0; + return TRUE; +} - if (pAd->CommonCfg.Channel > 14) - bUseShortSlotTime = TRUE; - if (bUseShortSlotTime) - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); - else - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED); +/*! \brief Dequeue a message from the MLME Queue + * \param *Queue The MLME Queue + * \param *Elem The message dequeued from MLME Queue + * \return TRUE if the Elem contains something, FALSE otherwise + * \pre + * \post - SlotTime = (bUseShortSlotTime)? 9 : 20; + IRQL = DISPATCH_LEVEL + */ +BOOLEAN MlmeDequeue( + IN MLME_QUEUE *Queue, + OUT MLME_QUEUE_ELEM **Elem) +{ + NdisAcquireSpinLock(&(Queue->Lock)); + *Elem = &(Queue->Entry[Queue->Head]); + Queue->Num--; + Queue->Head++; + if (Queue->Head == MAX_LEN_OF_MLME_QUEUE) { - // force using short SLOT time for FAE to demo performance when TxBurst is ON - if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))) - || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)) - ) - { - // In this case, we will think it is doing Wi-Fi test - // And we will not set to short slot when bEnableTxBurst is TRUE. - } - else if (pAd->CommonCfg.bEnableTxBurst) - SlotTime = 9; + Queue->Head = 0; } - - // - // For some reasons, always set it to short slot time. - // - // ToDo: Should consider capability with 11B - // - if (pAd->StaCfg.BssType == BSS_ADHOC) - SlotTime = 20; - - RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue); - RegValue = RegValue & 0xFFFFFF00; - - RegValue |= SlotTime; - - RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue); + NdisReleaseSpinLock(&(Queue->Lock)); + return TRUE; } -/* - ======================================================================== - Description: - Add Shared key information into ASIC. - Update shared key, TxMic and RxMic to Asic Shared key table - Update its cipherAlg to Asic Shared key Mode. - - Return: - ======================================================================== -*/ -VOID AsicAddSharedKeyEntry( - IN PRTMP_ADAPTER pAd, - IN UCHAR BssIndex, - IN UCHAR KeyIdx, - IN UCHAR CipherAlg, - IN PUCHAR pKey, - IN PUCHAR pTxMic, - IN PUCHAR pRxMic) +// IRQL = DISPATCH_LEVEL +VOID MlmeRestartStateMachine( + IN PRTMP_ADAPTER pAd) { - ULONG offset; //, csr0; - SHAREDKEY_MODE_STRUC csr1; -#ifdef RT2860 - INT i; -#endif +#ifdef RTMP_MAC_PCI + MLME_QUEUE_ELEM *Elem = NULL; +#endif // RTMP_MAC_PCI // + BOOLEAN Cancelled; - DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx)); -//============================================================================================ + DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n")); - DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx)); - DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - 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])); - if (pRxMic) +#ifdef RTMP_MAC_PCI + NdisAcquireSpinLock(&pAd->Mlme.TaskLock); + if(pAd->Mlme.bRunning) { - DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7])); + NdisReleaseSpinLock(&pAd->Mlme.TaskLock); + return; } - if (pTxMic) + else { - DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7])); + pAd->Mlme.bRunning = TRUE; } -//============================================================================================ - // - // fill key material - key + TX MIC + RX MIC - // + NdisReleaseSpinLock(&pAd->Mlme.TaskLock); - offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE; -#ifdef RT2860 - for (i=0; iMlme.Queue)) { -#ifdef RT2860 - for (i=0; i<8; i++) + //From message type, determine which state machine I should drive + if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) { - RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]); - } -#endif -#ifdef RT2870 - RTUSBMultiWrite(pAd, offset, pTxMic, 8); -#endif - } + // free MLME element + Elem->Occupied = FALSE; + Elem->MsgLen = 0; - offset += 8; - if (pRxMic) - { -#ifdef RT2860 - for (i=0; i<8; i++) - { - RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]); } -#endif -#ifdef RT2870 - RTUSBMultiWrite(pAd, offset, pRxMic, 8); -#endif + else { + DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n")); } - - - // - // Update cipher algorithm. WSTA always use BSS0 - // - RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word); - DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word)); - if ((BssIndex%2) == 0) - { - if (KeyIdx == 0) - csr1.field.Bss0Key0CipherAlg = CipherAlg; - else if (KeyIdx == 1) - csr1.field.Bss0Key1CipherAlg = CipherAlg; - else if (KeyIdx == 2) - csr1.field.Bss0Key2CipherAlg = CipherAlg; - else - csr1.field.Bss0Key3CipherAlg = CipherAlg; } - else +#endif // RTMP_MAC_PCI // + { - if (KeyIdx == 0) - csr1.field.Bss1Key0CipherAlg = CipherAlg; - else if (KeyIdx == 1) - csr1.field.Bss1Key1CipherAlg = CipherAlg; - else if (KeyIdx == 2) - csr1.field.Bss1Key2CipherAlg = CipherAlg; - else - csr1.field.Bss1Key3CipherAlg = CipherAlg; - } - DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word)); - RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word); + // Cancel all timer events + // Be careful to cancel new added timer + RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled); + RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); -} + } -// IRQL = DISPATCH_LEVEL -VOID AsicRemoveSharedKeyEntry( - IN PRTMP_ADAPTER pAd, - IN UCHAR BssIndex, - IN UCHAR KeyIdx) -{ - //ULONG SecCsr0; - SHAREDKEY_MODE_STRUC csr1; + // Change back to original channel in case of doing scan + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); - DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx)); + // Resume MSDU which is turned off durning scan + RTMPResumeMsduTransmission(pAd); - RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word); - if ((BssIndex%2) == 0) - { - if (KeyIdx == 0) - csr1.field.Bss0Key0CipherAlg = 0; - else if (KeyIdx == 1) - csr1.field.Bss0Key1CipherAlg = 0; - else if (KeyIdx == 2) - csr1.field.Bss0Key2CipherAlg = 0; - else - csr1.field.Bss0Key3CipherAlg = 0; - } - else { - if (KeyIdx == 0) - csr1.field.Bss1Key0CipherAlg = 0; - else if (KeyIdx == 1) - csr1.field.Bss1Key1CipherAlg = 0; - else if (KeyIdx == 2) - csr1.field.Bss1Key2CipherAlg = 0; - else - csr1.field.Bss1Key3CipherAlg = 0; + // Set all state machines back IDLE + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE; + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; + pAd->Mlme.ActMachine.CurrState = ACT_IDLE; } - DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word)); - RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word); - ASSERT(BssIndex < 4); - ASSERT(KeyIdx < 4); +#ifdef RTMP_MAC_PCI + // Remove running state + NdisAcquireSpinLock(&pAd->Mlme.TaskLock); + pAd->Mlme.bRunning = FALSE; + NdisReleaseSpinLock(&pAd->Mlme.TaskLock); +#endif // RTMP_MAC_PCI // } +/*! \brief test if the MLME Queue is empty + * \param *Queue The MLME Queue + * \return TRUE if the Queue is empty, FALSE otherwise + * \pre + * \post -VOID AsicUpdateWCIDAttribute( - IN PRTMP_ADAPTER pAd, - IN USHORT WCID, - IN UCHAR BssIndex, - IN UCHAR CipherAlg, - IN BOOLEAN bUsePairewiseKeyTable) -{ - ULONG WCIDAttri = 0, offset; - - // - // Update WCID attribute. - // Only TxKey could update WCID attribute. - // - offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE); - WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable); - RTMP_IO_WRITE32(pAd, offset, WCIDAttri); -} + IRQL = DISPATCH_LEVEL -VOID AsicUpdateWCIDIVEIV( - IN PRTMP_ADAPTER pAd, - IN USHORT WCID, - IN ULONG uIV, - IN ULONG uEIV) + */ +BOOLEAN MlmeQueueEmpty( + IN MLME_QUEUE *Queue) { - ULONG offset; + BOOLEAN Ans; - offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE); + NdisAcquireSpinLock(&(Queue->Lock)); + Ans = (Queue->Num == 0); + NdisReleaseSpinLock(&(Queue->Lock)); - RTMP_IO_WRITE32(pAd, offset, uIV); - RTMP_IO_WRITE32(pAd, offset + 4, uEIV); + return Ans; } -VOID AsicUpdateRxWCIDTable( - IN PRTMP_ADAPTER pAd, - IN USHORT WCID, - IN PUCHAR pAddr) -{ - ULONG offset; - ULONG Addr; +/*! \brief test if the MLME Queue is full + * \param *Queue The MLME Queue + * \return TRUE if the Queue is empty, FALSE otherwise + * \pre + * \post - offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE); - Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24); - RTMP_IO_WRITE32(pAd, offset, Addr); - Addr = pAddr[4] + (pAddr[5] << 8); - RTMP_IO_WRITE32(pAd, offset + 4, Addr); -} + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + */ +BOOLEAN MlmeQueueFull( + IN MLME_QUEUE *Queue) +{ + BOOLEAN Ans; -/* - ======================================================================== + NdisAcquireSpinLock(&(Queue->Lock)); + Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied); + NdisReleaseSpinLock(&(Queue->Lock)); - Routine Description: - Set Cipher Key, Cipher algorithm, IV/EIV to Asic + return Ans; +} - Arguments: - pAd Pointer to our adapter - WCID WCID Entry number. - BssIndex BSSID index, station or none multiple BSSID support - this value should be 0. - KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled - pCipherKey Pointer to Cipher Key. - bUsePairewiseKeyTable TRUE means saved the key in SharedKey table, - otherwise PairewiseKey table - bTxKey This is the transmit key if enabled. +/*! \brief The destructor of MLME Queue + * \param + * \return + * \pre + * \post + * \note Clear Mlme Queue, Set Queue->Num to Zero. - Return Value: - None + IRQL = PASSIVE_LEVEL - Note: - This routine will set the relative key stuff to Asic including WCID attribute, - Cipher Key, Cipher algorithm and IV/EIV. + */ +VOID MlmeQueueDestroy( + IN MLME_QUEUE *pQueue) +{ + NdisAcquireSpinLock(&(pQueue->Lock)); + pQueue->Num = 0; + pQueue->Head = 0; + pQueue->Tail = 0; + NdisReleaseSpinLock(&(pQueue->Lock)); + NdisFreeSpinLock(&(pQueue->Lock)); +} - IV/EIV will be update if this CipherKey is the transmission key because - ASIC will base on IV's KeyID value to select Cipher Key. - If bTxKey sets to FALSE, this is not the TX key, but it could be - RX key +/*! \brief To substitute the message type if the message is coming from external + * \param pFrame The frame received + * \param *Machine The state machine + * \param *MsgType the message type for the state machine + * \return TRUE if the substitution is successful, FALSE otherwise + * \pre + * \post - For AP mode bTxKey must be always set to TRUE. - ======================================================================== -*/ -VOID AsicAddKeyEntry( - IN PRTMP_ADAPTER pAd, - IN USHORT WCID, - IN UCHAR BssIndex, - IN UCHAR KeyIdx, - IN PCIPHER_KEY pCipherKey, - IN BOOLEAN bUsePairewiseKeyTable, - IN BOOLEAN bTxKey) -{ - ULONG offset; - UCHAR IV4 = 0; - PUCHAR pKey = pCipherKey->Key; - PUCHAR pTxMic = pCipherKey->TxMic; - PUCHAR pRxMic = pCipherKey->RxMic; - PUCHAR pTxtsc = pCipherKey->TxTsc; - UCHAR CipherAlg = pCipherKey->CipherAlg; - SHAREDKEY_MODE_STRUC csr1; -#ifdef RT2860 - UCHAR i; -#endif + IRQL = DISPATCH_LEVEL - DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n")); - // - // 1.) decide key table offset - // - if (bUsePairewiseKeyTable) - offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE); - else - offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE; + */ +BOOLEAN MsgTypeSubst( + IN PRTMP_ADAPTER pAd, + IN PFRAME_802_11 pFrame, + OUT INT *Machine, + OUT INT *MsgType) +{ + USHORT Seq, Alg; + UCHAR EAPType; + PUCHAR pData; - // - // 2.) Set Key to Asic - // - //for (i = 0; i < KeyLen; i++) -#ifdef RT2860 - for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) - { - RTMP_IO_WRITE8(pAd, offset + i, pKey[i]); - } -#endif -#ifdef RT2870 - RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY); -#endif - offset += MAX_LEN_OF_PEER_KEY; + // Pointer to start of data frames including SNAP header + pData = (PUCHAR) pFrame + LENGTH_802_11; - // - // 3.) Set MIC key if available - // - if (pTxMic) + // The only data type will pass to this function is EAPOL frame + if (pFrame->Hdr.FC.Type == BTYPE_DATA) { -#ifdef RT2860 - for (i = 0; i < 8; i++) { - RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]); + *Machine = WPA_STATE_MACHINE; + EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1); + return (WpaMsgTypeSubst(EAPType, (INT *) MsgType)); } -#endif -#ifdef RT2870 - RTUSBMultiWrite(pAd, offset, pTxMic, 8); -#endif } - offset += LEN_TKIP_TXMICK; - if (pRxMic) + switch (pFrame->Hdr.FC.SubType) { -#ifdef RT2860 - for (i = 0; i < 8; i++) + case SUBTYPE_ASSOC_REQ: + *Machine = ASSOC_STATE_MACHINE; + *MsgType = MT2_PEER_ASSOC_REQ; + break; + case SUBTYPE_ASSOC_RSP: + *Machine = ASSOC_STATE_MACHINE; + *MsgType = MT2_PEER_ASSOC_RSP; + break; + case SUBTYPE_REASSOC_REQ: + *Machine = ASSOC_STATE_MACHINE; + *MsgType = MT2_PEER_REASSOC_REQ; + break; + case SUBTYPE_REASSOC_RSP: + *Machine = ASSOC_STATE_MACHINE; + *MsgType = MT2_PEER_REASSOC_RSP; + break; + case SUBTYPE_PROBE_REQ: + *Machine = SYNC_STATE_MACHINE; + *MsgType = MT2_PEER_PROBE_REQ; + break; + case SUBTYPE_PROBE_RSP: + *Machine = SYNC_STATE_MACHINE; + *MsgType = MT2_PEER_PROBE_RSP; + break; + case SUBTYPE_BEACON: + *Machine = SYNC_STATE_MACHINE; + *MsgType = MT2_PEER_BEACON; + break; + case SUBTYPE_ATIM: + *Machine = SYNC_STATE_MACHINE; + *MsgType = MT2_PEER_ATIM; + break; + case SUBTYPE_DISASSOC: + *Machine = ASSOC_STATE_MACHINE; + *MsgType = MT2_PEER_DISASSOC_REQ; + break; + case SUBTYPE_AUTH: + // get the sequence number from payload 24 Mac Header + 2 bytes algorithm + NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT)); + NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(USHORT)); + if (Seq == 1 || Seq == 3) { - RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]); - } -#endif -#ifdef RT2870 - RTUSBMultiWrite(pAd, offset, pRxMic, 8); -#endif + *Machine = AUTH_RSP_STATE_MACHINE; + *MsgType = MT2_PEER_AUTH_ODD; } - - - // - // 4.) Modify IV/EIV if needs - // This will force Asic to use this key ID by setting IV. - // - if (bTxKey) + else if (Seq == 2 || Seq == 4) { -#ifdef RT2860 - offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE); - // - // Write IV - // - RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]); - RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f)); - RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]); - - IV4 = (KeyIdx << 6); - if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES)) - IV4 |= 0x20; // turn on extension bit means EIV existence - - RTMP_IO_WRITE8(pAd, offset + 3, IV4); - - // - // Write EIV - // - offset += 4; - for (i = 0; i < 4; i++) + if (Alg == AUTH_MODE_OPEN || Alg == AUTH_MODE_KEY) { - RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]); + *Machine = AUTH_STATE_MACHINE; + *MsgType = MT2_PEER_AUTH_EVEN; } - -#endif -#ifdef RT2870 - UINT32 tmpVal; - - // - // Write IV - // - IV4 = (KeyIdx << 6); - if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES)) - IV4 |= 0x20; // turn on extension bit means EIV existence - - tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24); - RTMP_IO_WRITE32(pAd, offset, tmpVal); - - // - // Write EIV - // - offset += 4; - RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]); -#endif // RT2870 // - AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable); } - - if (!bUsePairewiseKeyTable) + else { - // - // Only update the shared key security mode - // - RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word); - if ((BssIndex % 2) == 0) + return FALSE; + } + break; + case SUBTYPE_DEAUTH: + *Machine = AUTH_RSP_STATE_MACHINE; + *MsgType = MT2_PEER_DEAUTH; + break; + case SUBTYPE_ACTION: + *Machine = ACTION_STATE_MACHINE; + // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support + if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG) { - if (KeyIdx == 0) - csr1.field.Bss0Key0CipherAlg = CipherAlg; - else if (KeyIdx == 1) - csr1.field.Bss0Key1CipherAlg = CipherAlg; - else if (KeyIdx == 2) - csr1.field.Bss0Key2CipherAlg = CipherAlg; - else - csr1.field.Bss0Key3CipherAlg = CipherAlg; + *MsgType = MT2_ACT_INVALID; } else { - if (KeyIdx == 0) - csr1.field.Bss1Key0CipherAlg = CipherAlg; - else if (KeyIdx == 1) - csr1.field.Bss1Key1CipherAlg = CipherAlg; - else if (KeyIdx == 2) - csr1.field.Bss1Key2CipherAlg = CipherAlg; - else - csr1.field.Bss1Key3CipherAlg = CipherAlg; + *MsgType = (pFrame->Octet[0]&0x7F); } - RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word); + break; + default: + return FALSE; + break; } - DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n")); + return TRUE; } +// =========================================================================================== +// state_machine.c +// =========================================================================================== -/* - ======================================================================== - Description: - Add Pair-wise key material into ASIC. - Update pairwise key, TxMic and RxMic to Asic Pair-wise key table +/*! \brief Initialize the state machine. + * \param *S pointer to the state machine + * \param Trans State machine transition function + * \param StNr number of states + * \param MsgNr number of messages + * \param DefFunc default function, when there is invalid state/message combination + * \param InitState initial state of the state machine + * \param Base StateMachine base, internal use only + * \pre p_sm should be a legal pointer + * \post - Return: - ======================================================================== -*/ -VOID AsicAddPairwiseKeyEntry( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pAddr, - IN UCHAR WCID, - IN CIPHER_KEY *pCipherKey) + IRQL = PASSIVE_LEVEL + + */ +VOID StateMachineInit( + IN STATE_MACHINE *S, + IN STATE_MACHINE_FUNC Trans[], + IN ULONG StNr, + IN ULONG MsgNr, + IN STATE_MACHINE_FUNC DefFunc, + IN ULONG InitState, + IN ULONG Base) { - INT i; - ULONG offset; - PUCHAR pKey = pCipherKey->Key; - PUCHAR pTxMic = pCipherKey->TxMic; - PUCHAR pRxMic = pCipherKey->RxMic; -#ifdef DBG - UCHAR CipherAlg = pCipherKey->CipherAlg; -#endif // DBG // + ULONG i, j; - // EKEY - offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE); -#ifdef RT2860 - for (i=0; iKey[0], MAX_LEN_OF_PEER_KEY); -#endif // RT2870 // - for (i=0; iNrState = StNr; + S->NrMsg = MsgNr; + S->Base = Base; - offset += MAX_LEN_OF_PEER_KEY; + S->TransFunc = Trans; - // MIC KEY - if (pTxMic) - { -#ifdef RT2860 - for (i=0; i<8; i++) - { - RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]); - } -#endif -#ifdef RT2870 - RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8); -#endif // RT2870 // - } - offset += 8; - if (pRxMic) + // init all state transition to default function + for (i = 0; i < StNr; i++) { -#ifdef RT2860 - for (i=0; i<8; i++) + for (j = 0; j < MsgNr; j++) { - RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]); + S->TransFunc[i * MsgNr + j] = DefFunc; } -#endif -#ifdef RT2870 - RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8); -#endif // RT2870 // } - DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg])); - DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - 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])); - if (pRxMic) - { - DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7])); - } - if (pTxMic) + // set the starting state + S->CurrState = InitState; +} + +/*! \brief This function fills in the function pointer into the cell in the state machine + * \param *S pointer to the state machine + * \param St state + * \param Msg incoming message + * \param f the function to be executed when (state, message) combination occurs at the state machine + * \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 + * \post + + IRQL = PASSIVE_LEVEL + + */ +VOID StateMachineSetAction( + IN STATE_MACHINE *S, + IN ULONG St, + IN ULONG Msg, + IN STATE_MACHINE_FUNC Func) +{ + ULONG MsgIdx; + + MsgIdx = Msg - S->Base; + + if (St < S->NrState && MsgIdx < S->NrMsg) { - DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", - pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7])); + // boundary checking before setting the action + S->TransFunc[St * S->NrMsg + MsgIdx] = Func; } } + +/*! \brief This function does the state transition + * \param *Adapter the NIC adapter pointer + * \param *S the state machine + * \param *Elem the message to be executed + * \return None + + IRQL = DISPATCH_LEVEL + + */ +VOID StateMachinePerformAction( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *S, + IN MLME_QUEUE_ELEM *Elem) +{ + (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem); +} + /* - ======================================================================== + ========================================================================== Description: - Remove Pair-wise key material from ASIC. - - Return: - ======================================================================== -*/ -VOID AsicRemovePairwiseKeyEntry( + The drop function, when machine executes this, the message is simply + ignored. This function does nothing, the message is freed in + StateMachinePerformAction() + ========================================================================== + */ +VOID Drop( IN PRTMP_ADAPTER pAd, - IN UCHAR BssIdx, - IN UCHAR Wcid) + IN MLME_QUEUE_ELEM *Elem) { - ULONG WCIDAttri; - USHORT offset; - - // re-set the entry's WCID attribute as OPEN-NONE. - offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE); - WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE; - RTMP_IO_WRITE32(pAd, offset, WCIDAttri); } -BOOLEAN AsicSendCommandToMcu( - IN PRTMP_ADAPTER pAd, - IN UCHAR Command, - IN UCHAR Token, - IN UCHAR Arg0, - IN UCHAR Arg1) -{ - HOST_CMD_CSR_STRUC H2MCmd; - H2M_MAILBOX_STRUC H2MMailbox; - ULONG i = 0; - - do - { - RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word); - if (H2MMailbox.field.Owner == 0) - break; - - RTMPusecDelay(2); - } while(i++ < 100); - - if (i > 100) - { - { -#ifdef RT2860 - UINT32 Data; - - // Reset DMA - RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data); - Data |= 0x2; - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data); - - // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too. - // Reset DMA/CPU ring index - RTMPRingCleanUp(pAd, QID_AC_BK); - RTMPRingCleanUp(pAd, QID_AC_BE); - RTMPRingCleanUp(pAd, QID_AC_VI); - RTMPRingCleanUp(pAd, QID_AC_VO); - RTMPRingCleanUp(pAd, QID_HCCA); - RTMPRingCleanUp(pAd, QID_MGMT); - RTMPRingCleanUp(pAd, QID_RX); - - // Clear Reset - RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data); - Data &= 0xfffffffd; - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data); -#endif /* RT2860 */ - DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n")); - } - //return FALSE; -#ifdef RT2870 - return FALSE; -#endif - } +// =========================================================================================== +// lfsr.c +// =========================================================================================== - H2MMailbox.field.Owner = 1; // pass ownership to MCU - H2MMailbox.field.CmdToken = Token; - H2MMailbox.field.HighByte = Arg1; - H2MMailbox.field.LowByte = Arg0; - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word); - - H2MCmd.word = 0; - H2MCmd.field.HostCommand = Command; - RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word); +/* + ========================================================================== + Description: - if (Command != 0x80) - { - } + IRQL = PASSIVE_LEVEL - return TRUE; + ========================================================================== + */ +VOID LfsrInit( + IN PRTMP_ADAPTER pAd, + IN ULONG Seed) +{ + if (Seed == 0) + pAd->Mlme.ShiftReg = 1; + else + pAd->Mlme.ShiftReg = Seed; } -#ifdef RT2860 -BOOLEAN AsicCheckCommanOk( - IN PRTMP_ADAPTER pAd, - IN UCHAR Command) +/* + ========================================================================== + Description: + ========================================================================== + */ +UCHAR RandomByte( + IN PRTMP_ADAPTER pAd) { - UINT32 CmdStatus = 0, CID = 0, i; - UINT32 ThisCIDMask = 0; + ULONG i; + UCHAR R, Result; - i = 0; - do + R = 0; + + if (pAd->Mlme.ShiftReg == 0) + NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg); + + for (i = 0; i < 8; i++) { - RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID); - // Find where the command is. Because this is randomly specified by firmware. - if ((CID & CID0MASK) == Command) - { - ThisCIDMask = CID0MASK; - break; - } - else if ((((CID & CID1MASK)>>8) & 0xff) == Command) - { - ThisCIDMask = CID1MASK; - break; - } - else if ((((CID & CID2MASK)>>16) & 0xff) == Command) - { - ThisCIDMask = CID2MASK; - break; - } - else if ((((CID & CID3MASK)>>24) & 0xff) == Command) + if (pAd->Mlme.ShiftReg & 0x00000001) { - ThisCIDMask = CID3MASK; - break; - } - - RTMPusecDelay(100); - i++; - }while (i < 200); - - // Get CommandStatus Value - RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus); - - // This command's status is at the same position as command. So AND command position's bitmask to read status. - if (i < 200) - { - // If Status is 1, the comamnd is success. - if (((CmdStatus & ThisCIDMask) == 0x1) || ((CmdStatus & ThisCIDMask) == 0x100) - || ((CmdStatus & ThisCIDMask) == 0x10000) || ((CmdStatus & ThisCIDMask) == 0x1000000)) - { - DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus)); - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff); - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff); - return TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n", CID, CmdStatus)); + pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000; + Result = 1; } else { - DBGPRINT(RT_DEBUG_TRACE, ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n", Command, CmdStatus)); + pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1; + Result = 0; + } + R = (R << 1) | Result; } - // Clear Command and Status. - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff); - RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff); - return FALSE; + return R; } -#endif /* RT8260 */ + /* ======================================================================== @@ -7993,55 +5467,6 @@ CHAR RTMPMaxRssi( return larger; } -#ifdef RT2870 -// Antenna divesity use GPIO3 and EESK pin for control -// Antenna and EEPROM access are both using EESK pin, -// Therefor we should avoid accessing EESK at the same time -// Then restore antenna after EEPROM access -VOID AsicSetRxAnt( - IN PRTMP_ADAPTER pAd, - IN UCHAR Ant) -{ - UINT32 Value; - UINT32 x; - - if ((pAd->EepromAccess) || - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) || - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) || - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) || - (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) - { - return; - } - - // the antenna selection is through firmware and MAC register(GPIO3) - if (Ant == 0) - { - // Main antenna - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - x |= (EESK); - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); - Value &= ~(0x0808); - RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); - DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n")); - } - else - { - // Aux antenna - RTMP_IO_READ32(pAd, E2PROM_CSR, &x); - x &= ~(EESK); - RTMP_IO_WRITE32(pAd, E2PROM_CSR, x); - - RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value); - Value &= ~(0x0808); - Value |= 0x08; - RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value); - DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n")); - } -} -#endif /* ======================================================================== @@ -8065,39 +5490,21 @@ VOID AsicEvaluateRxAnt( fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_NIC_NOT_EXIST | - fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) - || OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) -#ifdef RT2870 + fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) || + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) +#ifdef RT30xx || (pAd->EepromAccess) -#endif +#endif // RT30xx // ) return; -#ifdef RT30xx - // two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove - // one is antenna diversity:there is only one antenna can rx and tx - // the other is failed antenna remove:two physical antenna can rx and tx - if (pAd->NicConfig2.field.AntDiversity) - { - DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n", - pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt)); - - AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt); - - pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt - pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE; - pAd->RxAnt.RcvPktNumWhenEvaluate = 0; - - // a one-shot timer to end the evalution - // dynamic adjust antenna evaluation period according to the traffic - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) - RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100); - else - RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300); - } - else -#endif + + { + //if (pAd->StaCfg.Psm == PWR_SAVE) + // return; + { + if (pAd->StaCfg.Psm == PWR_SAVE) return; @@ -8116,12 +5523,9 @@ VOID AsicEvaluateRxAnt( BBPR3 |= (0x0); } RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); - -#ifdef RT2860 +#ifdef RTMP_MAC_PCI pAd->StaCfg.BBPR3 = BBPR3; -#endif - } - +#endif // RTMP_MAC_PCI // if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) ) { @@ -8141,6 +5545,11 @@ VOID AsicEvaluateRxAnt( pAd->Mlme.bLowThroughput = TRUE; } } + } + + } + + } /* @@ -8169,48 +5578,17 @@ VOID AsicRxAntEvalTimeout( if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF | - fRTMP_ADAPTER_NIC_NOT_EXIST) - || OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) -#ifdef RT2870 + fRTMP_ADAPTER_NIC_NOT_EXIST) || + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) +#ifdef RT30xx || (pAd->EepromAccess) -#endif +#endif // RT30xx // ) return; { -#ifdef RT30xx - if (pAd->NicConfig2.field.AntDiversity) - { - if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt])) - { - UCHAR temp; - - // - // select PrimaryRxAntPair - // Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair. - // Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt - // - temp = pAd->RxAnt.Pair1PrimaryRxAnt; - pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt; - pAd->RxAnt.Pair1SecondaryRxAnt = temp; - - pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3); - pAd->RxAnt.EvaluateStableCnt = 0; - } - else - { - // if the evaluated antenna is not better than original, switch back to original antenna - AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); - pAd->RxAnt.EvaluateStableCnt ++; - } - - pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt - - DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n", - pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate)); - } - else -#endif + //if (pAd->StaCfg.Psm == PWR_SAVE) + // return; { if (pAd->StaCfg.Psm == PWR_SAVE) return; @@ -8261,13 +5639,16 @@ VOID AsicRxAntEvalTimeout( BBPR3 |= (0x0); } RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3); -#ifdef RT2860 +#ifdef RTMP_MAC_PCI pAd->StaCfg.BBPR3 = BBPR3; -#endif +#endif // RTMP_MAC_PCI // } } + + } + VOID APSDPeriodicExec( IN PVOID SystemSpecific1, IN PVOID FunctionContext, @@ -8281,6 +5662,18 @@ VOID APSDPeriodicExec( pAd->CommonCfg.TriggerTimerCount++; +// Driver should not send trigger frame, it should be send by application layer +/* + if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable + && (pAd->CommonCfg.bNeedSendTriggerFrame || + (((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO)))) + { + DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n")); + RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE); + pAd->CommonCfg.bNeedSendTriggerFrame = FALSE; + pAd->CommonCfg.TriggerTimerCount = 0; + pAd->CommonCfg.bInServicePeriod = TRUE; + }*/ } /* @@ -8347,9 +5740,10 @@ BOOLEAN RTMPCheckEntryEnableAutoRateSwit BOOLEAN RTMPAutoRateSwitchCheck( IN PRTMP_ADAPTER pAd) { + { if (pAd->StaCfg.bAutoTxRateSwitch) return TRUE; - + } return FALSE; } @@ -8375,7 +5769,9 @@ UCHAR RTMPStaFixedTxMode( { UCHAR tx_mode = FIXED_TXMODE_HT; + { tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode; + } return tx_mode; } @@ -8462,12 +5858,10 @@ VOID AsicStaBbpTuning( && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) ) && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) -#ifdef RT2860 - && (pAd->bPCIclkOff == FALSE)) -#endif -#ifdef RT2870 +#ifdef RTMP_MAC_PCI + && (pAd->bPCIclkOff == FALSE) +#endif // RTMP_MAC_PCI // ) -#endif { RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value); R66 = OrigR66Value; @@ -8479,26 +5873,31 @@ VOID AsicStaBbpTuning( if (pAd->LatchRfRegs.Channel <= 14) { //BG band -#ifdef RT2870 +#ifdef RT30xx // RT3070 is a no LNA solution, it should have different control regarding to AGC gain control // Otherwise, it will have some throughput side effect when low RSSI - if (IS_RT30xx(pAd)) + + if (IS_RT3070(pAd)||IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) { if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) { R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20; if (OrigR66Value != R66) + { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } + } else { R66 = 0x1C + 2*GET_LNA_GAIN(pAd); if (OrigR66Value != R66) + { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } } + } else -#endif // RT2870 // +#endif // RT30xx // { if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) { @@ -8564,108 +5963,6 @@ VOID AsicStaBbpTuning( } } -#ifdef RT2860 -VOID AsicResetFromDMABusy( - IN PRTMP_ADAPTER pAd) -{ - UINT32 Data; - BOOLEAN bCtrl = FALSE; - - DBGPRINT(RT_DEBUG_TRACE, ("---> AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n")); - - // Be sure restore link control value so we can write register. - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); - if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)) - { - DBGPRINT(RT_DEBUG_TRACE,("AsicResetFromDMABusy==>\n")); - RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT); - RTMPusecDelay(6000); - pAd->bPCIclkOff = FALSE; - bCtrl = TRUE; - } - // Reset DMA - RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data); - Data |= 0x2; - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data); - - // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too. - // Reset DMA/CPU ring index - RTMPRingCleanUp(pAd, QID_AC_BK); - RTMPRingCleanUp(pAd, QID_AC_BE); - RTMPRingCleanUp(pAd, QID_AC_VI); - RTMPRingCleanUp(pAd, QID_AC_VO); - RTMPRingCleanUp(pAd, QID_HCCA); - RTMPRingCleanUp(pAd, QID_MGMT); - RTMPRingCleanUp(pAd, QID_RX); - - // Clear Reset - RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data); - Data &= 0xfffffffd; - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data); - - // If in Radio off, should call RTMPPCIePowerLinkCtrl again. - if ((bCtrl == TRUE) && (pAd->StaCfg.bRadio == FALSE)) - RTMPPCIeLinkCtrlSetting(pAd, 3); - - RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS); - DBGPRINT(RT_DEBUG_TRACE, ("<--- AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n")); -} - -VOID AsicResetBBP( - IN PRTMP_ADAPTER pAd) -{ - DBGPRINT(RT_DEBUG_TRACE, ("---> Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n")); - - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0); - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x2); - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc); - - // After hard-reset BBP, initialize all BBP values. - NICRestoreBBPValue(pAd); - DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n")); -} - -VOID AsicResetMAC( - IN PRTMP_ADAPTER pAd) -{ - ULONG Data; - - DBGPRINT(RT_DEBUG_TRACE, ("---> AsicResetMAC !!!! \n")); - RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data); - Data |= 0x4; - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data); - Data &= 0xfffffffb; - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data); - - DBGPRINT(RT_DEBUG_TRACE, ("<--- AsicResetMAC !!!! \n")); -} - -VOID AsicResetPBF( - IN PRTMP_ADAPTER pAd) -{ - ULONG Value1, Value2; - ULONG Data; - - RTMP_IO_READ32(pAd, TXRXQ_PCNT, &Value1); - RTMP_IO_READ32(pAd, PBF_DBG, &Value2); - - Value2 &= 0xff; - // sum should be equals to 0xff, which is the total buffer size. - if ((Value1 + Value2) < 0xff) - { - DBGPRINT(RT_DEBUG_TRACE, ("---> Asic HardReset PBF !!!! \n")); - RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data); - Data |= 0x8; - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data); - Data &= 0xfffffff7; - RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data); - - DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset PBF !!!! \n")); - } -} -#endif /* RT2860 */ - VOID RTMPSetAGCInitValue( IN PRTMP_ADAPTER pAd, IN UCHAR BandWidth) @@ -8674,11 +5971,24 @@ VOID RTMPSetAGCInitValue( if (pAd->LatchRfRegs.Channel <= 14) { // BG band +#ifdef RT30xx + /* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */ + + if (IS_RT3070(pAd)||IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) + { + R66 = 0x1C + 2*GET_LNA_GAIN(pAd); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); + } + else +#endif // RT30xx // + { R66 = 0x2E + GET_LNA_GAIN(pAd); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } + } else { //A band + { if (BandWidth == BW_20) { R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3); @@ -8690,133 +6000,7 @@ VOID RTMPSetAGCInitValue( RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66); } } - -} - -VOID AsicTurnOffRFClk( - IN PRTMP_ADAPTER pAd, - IN UCHAR Channel) -{ - - // RF R2 bit 18 = 0 - UINT32 R1 = 0, R2 = 0, R3 = 0; - UCHAR index; - RTMP_RF_REGS *RFRegTable; - - // The RF programming sequence is difference between 3xxx and 2xxx - if (IS_RT3090(pAd)) - { - RT30xxLoadRFSleepModeSetup(pAd); // add by johnli, RF power sequence setup, load RF sleep-mode setup - return; - } - - RFRegTable = RF2850RegTable; - - switch (pAd->RfIcType) - { - case RFIC_2820: - case RFIC_2850: - case RFIC_2720: - case RFIC_2750: - - for (index = 0; index < NUM_OF_2850_CHNL; index++) - { - if (Channel == RFRegTable[index].Channel) - { - R1 = RFRegTable[index].R1 & 0xffffdfff; - R2 = RFRegTable[index].R2 & 0xfffbffff; - R3 = RFRegTable[index].R3 & 0xfff3ffff; - - RTMP_RF_IO_WRITE32(pAd, R1); - RTMP_RF_IO_WRITE32(pAd, R2); - - // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0. - // Set RF R2 bit18=0, R3 bit[18:19]=0 - //if (pAd->StaCfg.bRadio == FALSE) - if (1) - { - RTMP_RF_IO_WRITE32(pAd, R3); - - DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n", - Channel, pAd->RfIcType, R2, R3)); - } - else - DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n", - Channel, pAd->RfIcType, R2)); - break; - } - } - break; - - default: - break; - } -} - - -VOID AsicTurnOnRFClk( - IN PRTMP_ADAPTER pAd, - IN UCHAR Channel) -{ - - // RF R2 bit 18 = 0 - UINT32 R1 = 0, R2 = 0, R3 = 0; - UCHAR index; - RTMP_RF_REGS *RFRegTable; - - // The RF programming sequence is difference between 3xxx and 2xxx - if (IS_RT3090(pAd)) - return; - - RFRegTable = RF2850RegTable; - - switch (pAd->RfIcType) - { - case RFIC_2820: - case RFIC_2850: - case RFIC_2720: - case RFIC_2750: - - for (index = 0; index < NUM_OF_2850_CHNL; index++) - { - if (Channel == RFRegTable[index].Channel) - { - R3 = pAd->LatchRfRegs.R3; - R3 &= 0xfff3ffff; - R3 |= 0x00080000; - RTMP_RF_IO_WRITE32(pAd, R3); - - R1 = RFRegTable[index].R1; - RTMP_RF_IO_WRITE32(pAd, R1); - - R2 = RFRegTable[index].R2; - if (pAd->Antenna.field.TxPath == 1) - { - R2 |= 0x4000; // If TXpath is 1, bit 14 = 1; - } - - if (pAd->Antenna.field.RxPath == 2) - { - R2 |= 0x40; // write 1 to off Rxpath. - } - else if (pAd->Antenna.field.RxPath == 1) - { - R2 |= 0x20040; // write 1 to off RxPath - } - RTMP_RF_IO_WRITE32(pAd, R2); - - break; - } - } - break; - - default: - break; } - DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n", - Channel, - pAd->RfIcType, - R2)); } Index: b/drivers/staging/rt2860/common/rt_channel.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/rt_channel.c @@ -0,0 +1,1280 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* +*/ +#include "../rt_config.h" + + +CH_FREQ_MAP CH_HZ_ID_MAP[]= + { + {1, 2412}, + {2, 2417}, + {3, 2422}, + {4, 2427}, + {5, 2432}, + {6, 2437}, + {7, 2442}, + {8, 2447}, + {9, 2452}, + {10, 2457}, + {11, 2462}, + {12, 2467}, + {13, 2472}, + {14, 2484}, + + /* UNII */ + {36, 5180}, + {40, 5200}, + {44, 5220}, + {48, 5240}, + {52, 5260}, + {56, 5280}, + {60, 5300}, + {64, 5320}, + {149, 5745}, + {153, 5765}, + {157, 5785}, + {161, 5805}, + {165, 5825}, + {167, 5835}, + {169, 5845}, + {171, 5855}, + {173, 5865}, + + /* HiperLAN2 */ + {100, 5500}, + {104, 5520}, + {108, 5540}, + {112, 5560}, + {116, 5580}, + {120, 5600}, + {124, 5620}, + {128, 5640}, + {132, 5660}, + {136, 5680}, + {140, 5700}, + + /* Japan MMAC */ + {34, 5170}, + {38, 5190}, + {42, 5210}, + {46, 5230}, + + /* Japan */ + {184, 4920}, + {188, 4940}, + {192, 4960}, + {196, 4980}, + + {208, 5040}, /* Japan, means J08 */ + {212, 5060}, /* Japan, means J12 */ + {216, 5080}, /* Japan, means J16 */ +}; + +INT CH_HZ_ID_MAP_NUM = (sizeof(CH_HZ_ID_MAP)/sizeof(CH_FREQ_MAP)); + +CH_REGION ChRegion[] = +{ + { // Antigua and Berbuda + "AG", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Argentina + "AR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Aruba + "AW", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Australia + "AU", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165 + { 0}, // end + } + }, + + { // Austria + "AT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Bahamas + "BS", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165 + { 0}, // end + } + }, + + { // Barbados + "BB", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Bermuda + "BM", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Brazil + "BR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 100, 11, 24, BOTH, FALSE}, // 5G, ch 100~140 + { 149, 5, 30, BOTH, FALSE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Belgium + "BE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 18, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 18, IDOR, FALSE}, // 5G, ch 52~64 + { 0}, // end + } + }, + + { // Bulgaria + "BG", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Canada + "CA", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165 + { 0}, // end + } + }, + + { // Cayman IsLands + "KY", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Chile + "CL", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165 + { 0}, // end + } + }, + + { // China + "CN", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Colombia + "CO", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 + { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165 + { 0}, // end + } + }, + + { // Costa Rica + "CR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Cyprus + "CY", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Czech_Republic + "CZ", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 0}, // end + } + }, + + { // Denmark + "DK", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Dominican Republic + "DO", + CE, + { + { 1, 0, 20, BOTH, FALSE}, // 2.4 G, ch 0 + { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Equador + "EC", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 100, 11, 27, BOTH, FALSE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // El Salvador + "SV", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 30, BOTH, TRUE}, // 5G, ch 52~64 + { 149, 4, 36, BOTH, TRUE}, // 5G, ch 149~165 + { 0}, // end + } + }, + + { // Finland + "FI", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // France + "FR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 0}, // end + } + }, + + { // Germany + "DE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Greece + "GR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Guam + "GU", + CE, + { + { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 + { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140 + { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165 + { 0}, // end + } + }, + + { // Guatemala + "GT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Haiti + "HT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Honduras + "HN", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Hong Kong + "HK", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64 + { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Hungary + "HU", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 0}, // end + } + }, + + { // Iceland + "IS", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // India + "IN", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 149, 4, 24, IDOR, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Indonesia + "ID", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Ireland + "IE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Israel + "IL", + CE, + { + { 1, 3, 20, IDOR, FALSE}, // 2.4 G, ch 1~3 + { 4, 6, 20, BOTH, FALSE}, // 2.4 G, ch 4~9 + { 10, 4, 20, IDOR, FALSE}, // 2.4 G, ch 10~13 + { 0}, // end + } + }, + + { // Italy + "IT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Japan + "JP", + JAP, + { + { 1, 14, 20, BOTH, FALSE}, // 2.4 G, ch 1~14 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 0}, // end + } + }, + + { // Jordan + "JO", + CE, + { + { 1, 13, 20, IDOR, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 149, 4, 23, IDOR, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Latvia + "LV", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Liechtenstein + "LI", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Lithuania + "LT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Luxemburg + "LU", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Malaysia + "MY", + CE, + { + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165 + { 0}, // end + } + }, + + { // Malta + "MT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Marocco + "MA", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48 + { 0}, // end + } + }, + + { // Mexico + "MX", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 5, 30, IDOR, FALSE}, // 5G, ch 149~165 + { 0}, // end + } + }, + + { // Netherlands + "NL", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // New Zealand + "NZ", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 24, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Norway + "NO", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Peru + "PE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Portugal + "PT", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Poland + "PL", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Romania + "RO", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Russia + "RU", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 149, 4, 20, IDOR, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Saudi Arabia + "SA", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 4, 23, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Serbia_and_Montenegro + "CS", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 0}, // end + } + }, + + { // Singapore + "SG", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 + { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Slovakia + "SK", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Slovenia + "SI", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 0}, // end + } + }, + + { // South Africa + "ZA", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // South Korea + "KR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64 + { 100, 8, 20, BOTH, FALSE}, // 5G, ch 100~128 + { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Spain + "ES", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 17, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Sweden + "SE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Switzerland + "CH", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13 + { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 0}, // end + } + }, + + { // Taiwan + "TW", + CE, + { + { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11 + { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64 + { 0}, // end + } + }, + + { // Turkey + "TR", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 + { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48 + { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64 + { 0}, // end + } + }, + + { // UK + "GB", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 + { 36, 4, 23, IDOR, FALSE}, // 5G, ch 52~64 + { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 0}, // end + } + }, + + { // Ukraine + "UA", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 + { 0}, // end + } + }, + + { // United_Arab_Emirates + "AE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 + { 0}, // end + } + }, + + { // United_States + "US", + CE, + { + { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11 + { 36, 4, 17, IDOR, FALSE}, // 5G, ch 52~64 + { 52, 4, 24, BOTH, TRUE}, // 5G, ch 52~64 + { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140 + { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165 + { 0}, // end + } + }, + + { // Venezuela + "VE", + CE, + { + { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 + { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161 + { 0}, // end + } + }, + + { // Default + "", + CE, + { + { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11 + { 36, 4, 20, BOTH, FALSE}, // 5G, ch 52~64 + { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64 + { 100, 11, 20, BOTH, FALSE}, // 5G, ch 100~140 + { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165 + { 0}, // end + } + }, +}; + + +static PCH_REGION GetChRegion( + IN PUCHAR CntryCode) +{ + INT loop = 0; + PCH_REGION pChRegion = NULL; + + while (strcmp((PSTRING) ChRegion[loop].CountReg, "") != 0) + { + if (strncmp((PSTRING) ChRegion[loop].CountReg, (PSTRING) CntryCode, 2) == 0) + { + pChRegion = &ChRegion[loop]; + break; + } + loop++; + } + + if (pChRegion == NULL) + pChRegion = &ChRegion[loop]; + return pChRegion; +} + +static VOID ChBandCheck( + IN UCHAR PhyMode, + OUT PUCHAR pChType) +{ + switch(PhyMode) + { + case PHY_11A: + case PHY_11AN_MIXED: + *pChType = BAND_5G; + break; + case PHY_11ABG_MIXED: + case PHY_11AGN_MIXED: + case PHY_11ABGN_MIXED: + *pChType = BAND_BOTH; + break; + + default: + *pChType = BAND_24G; + break; + } +} + +static UCHAR FillChList( + IN PRTMP_ADAPTER pAd, + IN PCH_DESP pChDesp, + IN UCHAR Offset, + IN UCHAR increment) +{ + INT i, j, l; + UCHAR channel; + + j = Offset; + for (i = 0; i < pChDesp->NumOfCh; i++) + { + channel = pChDesp->FirstChannel + i * increment; + for (l=0; lTxPower[l].Channel) + { + pAd->ChannelList[j].Power = pAd->TxPower[l].Power; + pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2; + break; + } + } + if (l == MAX_NUM_OF_CHANNELS) + continue; + + pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment; + pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr; + pAd->ChannelList[j].DfsReq = pChDesp->DfsReq; + j++; + } + pAd->ChannelListNum = j; + + return j; +} + + +static inline VOID CreateChList( + IN PRTMP_ADAPTER pAd, + IN PCH_REGION pChRegion, + IN UCHAR Geography) +{ + INT i; + UCHAR offset = 0; + PCH_DESP pChDesp; + UCHAR ChType; + UCHAR increment; + + if (pChRegion == NULL) + return; + + ChBandCheck(pAd->CommonCfg.PhyMode, &ChType); + + for (i=0; i<10; i++) + { + pChDesp = &pChRegion->ChDesp[i]; + if (pChDesp->FirstChannel == 0) + break; + + if (ChType == BAND_5G) + { + if (pChDesp->FirstChannel <= 14) + continue; + } + else if (ChType == BAND_24G) + { + if (pChDesp->FirstChannel > 14) + continue; + } + + if ((pChDesp->Geography == BOTH) + || (pChDesp->Geography == Geography)) + { + if (pChDesp->FirstChannel > 14) + increment = 4; + else + increment = 1; + offset = FillChList(pAd, pChDesp, offset, increment); + } + } +} + + +VOID BuildChannelListEx( + IN PRTMP_ADAPTER pAd) +{ + PCH_REGION pChReg; + + pChReg = GetChRegion(pAd->CommonCfg.CountryCode); + CreateChList(pAd, pChReg, pAd->CommonCfg.Geography); +} + + +VOID BuildBeaconChList( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pBuf, + OUT PULONG pBufLen) +{ + INT i; + ULONG TmpLen; + PCH_REGION pChRegion; + PCH_DESP pChDesp; + UCHAR ChType; + + pChRegion = GetChRegion(pAd->CommonCfg.CountryCode); + + if (pChRegion == NULL) + return; + + ChBandCheck(pAd->CommonCfg.PhyMode, &ChType); + *pBufLen = 0; + + for (i=0; i<10; i++) + { + pChDesp = &pChRegion->ChDesp[i]; + if (pChDesp->FirstChannel == 0) + break; + + if (ChType == BAND_5G) + { + if (pChDesp->FirstChannel <= 14) + continue; + } + else if (ChType == BAND_24G) + { + if (pChDesp->FirstChannel > 14) + continue; + } + + if ((pChDesp->Geography == BOTH) + || (pChDesp->Geography == pAd->CommonCfg.Geography)) + { + MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen, + 1, &pChDesp->FirstChannel, + 1, &pChDesp->NumOfCh, + 1, &pChDesp->MaxTxPwr, + END_OF_ARGS); + *pBufLen += TmpLen; + } + } +} + + +static BOOLEAN IsValidChannel( + IN PRTMP_ADAPTER pAd, + IN UCHAR channel) + +{ + INT i; + + for (i = 0; i < pAd->ChannelListNum; i++) + { + if (pAd->ChannelList[i].Channel == channel) + break; + } + + if (i == pAd->ChannelListNum) + return FALSE; + else + return TRUE; +} + + +static UCHAR GetExtCh( + IN UCHAR Channel, + IN UCHAR Direction) +{ + CHAR ExtCh; + + if (Direction == EXTCHA_ABOVE) + ExtCh = Channel + 4; + else + ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0; + + return ExtCh; +} + + +VOID N_ChannelCheck( + IN PRTMP_ADAPTER pAd) +{ + //UCHAR ChannelNum = pAd->ChannelListNum; + UCHAR Channel = pAd->CommonCfg.Channel; + + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) + { + if (Channel > 14) + { + if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) || + (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157)) + { + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE; + } + else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) || + (Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161)) + { + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW; + } + else + { + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; + } + } + else + { + do + { + UCHAR ExtCh; + UCHAR Dir = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA; + ExtCh = GetExtCh(Channel, Dir); + if (IsValidChannel(pAd, ExtCh)) + break; + + Dir = (Dir == EXTCHA_ABOVE) ? EXTCHA_BELOW : EXTCHA_ABOVE; + ExtCh = GetExtCh(Channel, Dir); + if (IsValidChannel(pAd, ExtCh)) + { + pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = Dir; + break; + } + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; + } while(FALSE); + + if (Channel == 14) + { + pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; + //pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE; // We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT() + } + } + } + + +} + + +VOID N_SetCenCh( + IN PRTMP_ADAPTER pAd) +{ + if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) + { + if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE) + { + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2; + } + else + { + if (pAd->CommonCfg.Channel == 14) + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1; + else + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2; + } + } + else + { + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; + } +} + + +UINT8 GetCuntryMaxTxPwr( + IN PRTMP_ADAPTER pAd, + IN UINT8 channel) +{ + int i; + for (i = 0; i < pAd->ChannelListNum; i++) + { + if (pAd->ChannelList[i].Channel == channel) + break; + } + + if (i == pAd->ChannelListNum) + return 0xff; + else + return pAd->ChannelList[i].MaxTxPwr; +} Index: b/drivers/staging/rt2860/common/rt_rf.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/rt_rf.c @@ -0,0 +1,194 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rt_rf.c + + Abstract: + Ralink Wireless driver RF related functions + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + + +#include "../rt_config.h" + + +#ifdef RTMP_RF_RW_SUPPORT +/* + ======================================================================== + + Routine Description: Write RT30xx RF register through MAC + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NDIS_STATUS RT30xxWriteRFRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR regID, + IN UCHAR value) +{ + RF_CSR_CFG_STRUC rfcsr; + UINT i = 0; + + do + { + RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word); + + if (!rfcsr.field.RF_CSR_KICK) + break; + i++; + } + while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); + + if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); + return STATUS_UNSUCCESSFUL; + } + + rfcsr.field.RF_CSR_WR = 1; + rfcsr.field.RF_CSR_KICK = 1; + rfcsr.field.TESTCSR_RFACC_REGNUM = regID; + rfcsr.field.RF_CSR_DATA = value; + + RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); + + return NDIS_STATUS_SUCCESS; +} + + +/* + ======================================================================== + + Routine Description: Read RT30xx RF register through MAC + + Arguments: + + Return Value: + + IRQL = + + Note: + + ======================================================================== +*/ +NDIS_STATUS RT30xxReadRFRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR regID, + IN PUCHAR pValue) +{ + RF_CSR_CFG_STRUC rfcsr; + UINT i=0, k=0; + + for (i=0; ichipOps.AsicRfInit) + pAd->chipOps.AsicRfInit(pAd); +} + + +VOID RtmpChipOpsRFHook( + IN RTMP_ADAPTER *pAd) +{ + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + + pChipOps->pRFRegTable = NULL; + pChipOps->AsicRfInit = NULL; + pChipOps->AsicRfTurnOn = NULL; + pChipOps->AsicRfTurnOff = NULL; + pChipOps->AsicReverseRfFromSleepMode = NULL; + pChipOps->AsicHaltAction = NULL; + /* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */ + +#ifdef RT30xx + if (IS_RT30xx(pAd)) + { + pChipOps->pRFRegTable = RT30xx_RFRegTable; + pChipOps->AsicHaltAction = RT30xxHaltAction; +#ifdef RT3070 + if((IS_RT3070(pAd) || IS_RT3071(pAd)) && (pAd->infType == RTMP_DEV_INF_USB)) + { + pChipOps->AsicRfInit = NICInitRT3070RFRegisters; + if (IS_RT3071(pAd)) + { + pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup; + pChipOps->AsicReverseRfFromSleepMode = RT30xxReverseRFSleepModeSetup; + } + } +#endif // RT3070 // + } +#endif // RT30xx // +} + +#endif // RTMP_RF_RW_SUPPORT // Index: b/drivers/staging/rt2860/common/rtmp_init.c =================================================================== --- a/drivers/staging/rt2860/common/rtmp_init.c +++ b/drivers/staging/rt2860/common/rtmp_init.c @@ -33,30 +33,10 @@ Revision History: Who When What -------- ---------- ---------------------------------------------- - Paul Lin 2002-08-01 created - John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme - Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT. */ #include "../rt_config.h" -#ifdef RT2860 -#include "firmware.h" -#include -#endif -#ifdef RT2870 -/* New firmware handles both RT2870 and RT3070. */ -#include "../../rt3070/firmware.h" -#endif UCHAR BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; -ULONG BIT32[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x00000100, 0x00000200, 0x00000400, 0x00000800, - 0x00001000, 0x00002000, 0x00004000, 0x00008000, - 0x00010000, 0x00020000, 0x00040000, 0x00080000, - 0x00100000, 0x00200000, 0x00400000, 0x00800000, - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000}; - char* CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128"}; // @@ -77,36 +57,10 @@ REG_PAIR BBPRegTable[] = { {BBP_R92, 0x00}, // middle range issue, Rory @2008-01-28 {BBP_R103, 0x00}, // near range high-power issue, requested from Gary @2008-0528 {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. + {BBP_R106, 0x35}, // for ShortGI throughput }; #define NUM_BBP_REG_PARMS (sizeof(BBPRegTable) / sizeof(REG_PAIR)) -// -// RF register initialization set -// -#ifdef RT2870 -REG_PAIR RT30xx_RFRegTable[] = { - {RF_R04, 0x40}, - {RF_R05, 0x03}, - {RF_R06, 0x02}, - {RF_R07, 0x70}, - {RF_R09, 0x0F}, - {RF_R10, 0x41}, - {RF_R11, 0x21}, - {RF_R12, 0x7B}, - {RF_R14, 0x90}, - {RF_R15, 0x58}, - {RF_R16, 0xB3}, - {RF_R17, 0x92}, - {RF_R18, 0x2C}, - {RF_R19, 0x02}, - {RF_R20, 0xBA}, - {RF_R21, 0xDB}, - {RF_R24, 0x16}, - {RF_R25, 0x01}, - {RF_R29, 0x1F}, -}; -#define NUM_RF_REG_PARMS (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR)) -#endif // RT2870 // // // ASIC register initialization sets @@ -128,32 +82,59 @@ RTMP_REG_PAIR MACRegTable[] = { {MAC_SYS_CTRL, 0x00}, // 0x1004, , default Disable RX {RX_FILTR_CFG, 0x17f97}, //0x1400 , RX filter control, {BKOFF_SLOT_CFG, 0x209}, // default set short slot time, CC_DELAY_TIME should be 2 + //{TX_SW_CFG0, 0x40a06}, // Gary,2006-08-23 {TX_SW_CFG0, 0x0}, // Gary,2008-05-21 for CWC test {TX_SW_CFG1, 0x80606}, // Gary,2006-08-23 {TX_LINK_CFG, 0x1020}, // Gary,2006-08-23 + //{TX_TIMEOUT_CFG, 0x00182090}, // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT {TX_TIMEOUT_CFG, 0x000a2090}, // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01 {MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000}, // 0x3018, MAX frame length. Max PSDU = 16kbytes. {LED_CFG, 0x7f031e46}, // Gary, 2006-08-23 + +//#ifdef CONFIG_AP_SUPPORT +// {WMM_AIFSN_CFG, 0x00001173}, +// {WMM_CWMIN_CFG, 0x00002344}, +// {WMM_CWMAX_CFG, 0x000034a6}, +// {WMM_TXOP0_CFG, 0x00100020}, +// {WMM_TXOP1_CFG, 0x002F0038}, +//#endif // CONFIG_AP_SUPPORT // + +//#ifdef CONFIG_STA_SUPPORT +// {WMM_AIFSN_CFG, 0x00002273}, +// {WMM_CWMIN_CFG, 0x00002344}, +// {WMM_CWMAX_CFG, 0x000034aa}, +//#endif // CONFIG_STA_SUPPORT // {PBF_MAX_PCNT, 0x1F3FBF9F}, //0x1F3f7f9f}, //Jan, 2006/04/20 + //{TX_RTY_CFG, 0x6bb80408}, // Jan, 2006/11/16 +// WMM_ACM_SUPPORT +// {TX_RTY_CFG, 0x6bb80101}, // sample {TX_RTY_CFG, 0x47d01f0f}, // Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03 + {AUTO_RSP_CFG, 0x00000013}, // Initial Auto_Responder, because QA will turn off Auto-Responder {CCK_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. {OFDM_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. -//PS packets use Tx1Q (for HCCA) when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) -#ifdef RT2870 +#ifdef RTMP_MAC_USB {PBF_CFG, 0xf40006}, // Only enable Queue 2 {MM40_PROT_CFG, 0x3F44084}, // Initial Auto_Responder, because QA will turn off Auto-Responder {WPDMA_GLO_CFG, 0x00000030}, -#endif // RT2870 // +#endif // RTMP_MAC_USB // {GF20_PROT_CFG, 0x01744004}, // set 19:18 --> Short NAV for MIMO PS {GF40_PROT_CFG, 0x03F44084}, {MM20_PROT_CFG, 0x01744004}, -#ifdef RT2860 +#ifdef RTMP_MAC_PCI {MM40_PROT_CFG, 0x03F54084}, -#endif +#endif // RTMP_MAC_PCI // {TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f*/ /*0x000024bf*/}, //Extension channel backoff. {TX_RTS_CFG, 0x00092b20}, +//#ifdef WIFI_TEST {EXP_ACK_TIME, 0x002400ca}, // default value +//#else +// {EXP_ACK_TIME, 0x005400ca}, // suggested by Gray @ 20070323 for 11n intel-sta throughput +//#endif // end - WIFI_TEST // +//#ifdef CONFIG_AP_SUPPORT +// {TBTT_SYNC_CFG, 0x00422000}, // TBTT_ADJUST(7:0) == 0 +// {TBTT_SYNC_CFG, 0x00012000}, // TBTT_ADJUST(7:0) == 0 +//#endif // CONFIG_AP_SUPPORT // {TXOP_HLDR_ET, 0x00000002}, /* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us @@ -173,26 +154,6 @@ RTMP_REG_PAIR STAMACRegTable[] = { #define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR)) #define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR)) -#ifdef RT2870 -// -// RT2870 Firmware Spec only used 1 oct for version expression -// -#define FIRMWARE_MINOR_VERSION 7 - -#endif // RT2870 // - -// New 8k byte firmware size for RT3071/RT3072 -#define FIRMWAREIMAGE_MAX_LENGTH 0x2000 -#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR)) -#define FIRMWARE_MAJOR_VERSION 0 - -#define FIRMWAREIMAGEV1_LENGTH 0x1000 -#define FIRMWAREIMAGEV2_LENGTH 0x1000 - -#ifdef RT2860 -#define FIRMWARE_MINOR_VERSION 2 -#endif - /* ======================================================================== @@ -236,6 +197,7 @@ NDIS_STATUS RTMPAllocAdapterBlock( DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n")); break; } + NdisZeroMemory(pBeaconBuf, MAX_BEACON_SIZE); Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd); if (Status != NDIS_STATUS_SUCCESS) @@ -244,14 +206,14 @@ NDIS_STATUS RTMPAllocAdapterBlock( break; } pAd->BeaconBuf = pBeaconBuf; - printk("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER)); + DBGPRINT(RT_DEBUG_OFF, ("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER))); // Init spin locks NdisAllocateSpinLock(&pAd->MgmtRingLock); -#ifdef RT2860 +#ifdef RTMP_MAC_PCI NdisAllocateSpinLock(&pAd->RxRingLock); -#endif +#endif // RTMP_MAC_PCI // for (index =0 ; index < NUM_OF_TX_RING; index++) { @@ -298,7 +260,7 @@ VOID RTMPReadTxPwrPerRate( USHORT i, value, value2; INT Apwrdelta, Gpwrdelta; UCHAR t1,t2,t3,t4; - BOOLEAN bValid, bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE; + BOOLEAN bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE; // // Get power delta for 20MHz and 40MHz. @@ -481,325 +443,16 @@ VOID RTMPReadTxPwrPerRate( Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28)); data |= (value<<16); - pAd->Tx20MPwrCfgABand[i] = pAd->Tx40MPwrCfgABand[i] = Adata; - pAd->Tx20MPwrCfgGBand[i] = pAd->Tx40MPwrCfgGBand[i] = Gdata; + /* For 20M/40M Power Delta issue */ + pAd->Tx20MPwrCfgABand[i] = data; + pAd->Tx20MPwrCfgGBand[i] = data; + pAd->Tx40MPwrCfgABand[i] = Adata; + pAd->Tx40MPwrCfgGBand[i] = Gdata; if (data != 0xffffffff) RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data); DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%lx, Adata = %lx, Gdata = %lx \n", data, Adata, Gdata)); } - - // - // Check this block is valid for 40MHz in 2.4G. If invalid, use parameter for 20MHz in 2.4G - // - bValid = TRUE; - for (i=0; i<6; i++) - { - RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + 2 + i*2, value); - if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00)) - { - bValid = FALSE; - break; - } - } - - // - // Get Txpower per MCS for 40MHz in 2.4G. - // - if (bValid) - { - for (i=0; i<4; i++) - { - RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4, value); - if (bGpwrdeltaMinus == FALSE) - { - t1 = (value&0xf)+(Gpwrdelta); - if (t1 > 0xf) - t1 = 0xf; - t2 = ((value&0xf0)>>4)+(Gpwrdelta); - if (t2 > 0xf) - t2 = 0xf; - t3 = ((value&0xf00)>>8)+(Gpwrdelta); - if (t3 > 0xf) - t3 = 0xf; - t4 = ((value&0xf000)>>12)+(Gpwrdelta); - if (t4 > 0xf) - t4 = 0xf; - } - else - { - if ((value&0xf) > Gpwrdelta) - t1 = (value&0xf)-(Gpwrdelta); - else - t1 = 0; - if (((value&0xf0)>>4) > Gpwrdelta) - t2 = ((value&0xf0)>>4)-(Gpwrdelta); - else - t2 = 0; - if (((value&0xf00)>>8) > Gpwrdelta) - t3 = ((value&0xf00)>>8)-(Gpwrdelta); - else - t3 = 0; - if (((value&0xf000)>>12) > Gpwrdelta) - t4 = ((value&0xf000)>>12)-(Gpwrdelta); - else - t4 = 0; - } - Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12); - - RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4 + 2, value); - if (bGpwrdeltaMinus == FALSE) - { - t1 = (value&0xf)+(Gpwrdelta); - if (t1 > 0xf) - t1 = 0xf; - t2 = ((value&0xf0)>>4)+(Gpwrdelta); - if (t2 > 0xf) - t2 = 0xf; - t3 = ((value&0xf00)>>8)+(Gpwrdelta); - if (t3 > 0xf) - t3 = 0xf; - t4 = ((value&0xf000)>>12)+(Gpwrdelta); - if (t4 > 0xf) - t4 = 0xf; - } - else - { - if ((value&0xf) > Gpwrdelta) - t1 = (value&0xf)-(Gpwrdelta); - else - t1 = 0; - if (((value&0xf0)>>4) > Gpwrdelta) - t2 = ((value&0xf0)>>4)-(Gpwrdelta); - else - t2 = 0; - if (((value&0xf00)>>8) > Gpwrdelta) - t3 = ((value&0xf00)>>8)-(Gpwrdelta); - else - t3 = 0; - if (((value&0xf000)>>12) > Gpwrdelta) - t4 = ((value&0xf000)>>12)-(Gpwrdelta); - else - t4 = 0; - } - Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28)); - - if (i == 0) - pAd->Tx40MPwrCfgGBand[i+1] = (pAd->Tx40MPwrCfgGBand[i+1] & 0x0000FFFF) | (Gdata & 0xFFFF0000); - else - pAd->Tx40MPwrCfgGBand[i+1] = Gdata; - - DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 2.4G band, Gdata = %lx \n", Gdata)); - } - } - - // - // Check this block is valid for 20MHz in 5G. If invalid, use parameter for 20MHz in 2.4G - // - bValid = TRUE; - for (i=0; i<8; i++) - { - RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + 2 + i*2, value); - if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00)) - { - bValid = FALSE; - break; - } - } - - // - // Get Txpower per MCS for 20MHz in 5G. - // - if (bValid) - { - for (i=0; i<5; i++) - { - RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4, value); - if (bApwrdeltaMinus == FALSE) - { - t1 = (value&0xf)+(Apwrdelta); - if (t1 > 0xf) - t1 = 0xf; - t2 = ((value&0xf0)>>4)+(Apwrdelta); - if (t2 > 0xf) - t2 = 0xf; - t3 = ((value&0xf00)>>8)+(Apwrdelta); - if (t3 > 0xf) - t3 = 0xf; - t4 = ((value&0xf000)>>12)+(Apwrdelta); - if (t4 > 0xf) - t4 = 0xf; - } - else - { - if ((value&0xf) > Apwrdelta) - t1 = (value&0xf)-(Apwrdelta); - else - t1 = 0; - if (((value&0xf0)>>4) > Apwrdelta) - t2 = ((value&0xf0)>>4)-(Apwrdelta); - else - t2 = 0; - if (((value&0xf00)>>8) > Apwrdelta) - t3 = ((value&0xf00)>>8)-(Apwrdelta); - else - t3 = 0; - if (((value&0xf000)>>12) > Apwrdelta) - t4 = ((value&0xf000)>>12)-(Apwrdelta); - else - t4 = 0; - } - Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12); - - RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4 + 2, value); - if (bApwrdeltaMinus == FALSE) - { - t1 = (value&0xf)+(Apwrdelta); - if (t1 > 0xf) - t1 = 0xf; - t2 = ((value&0xf0)>>4)+(Apwrdelta); - if (t2 > 0xf) - t2 = 0xf; - t3 = ((value&0xf00)>>8)+(Apwrdelta); - if (t3 > 0xf) - t3 = 0xf; - t4 = ((value&0xf000)>>12)+(Apwrdelta); - if (t4 > 0xf) - t4 = 0xf; - } - else - { - if ((value&0xf) > Apwrdelta) - t1 = (value&0xf)-(Apwrdelta); - else - t1 = 0; - if (((value&0xf0)>>4) > Apwrdelta) - t2 = ((value&0xf0)>>4)-(Apwrdelta); - else - t2 = 0; - if (((value&0xf00)>>8) > Apwrdelta) - t3 = ((value&0xf00)>>8)-(Apwrdelta); - else - t3 = 0; - if (((value&0xf000)>>12) > Apwrdelta) - t4 = ((value&0xf000)>>12)-(Apwrdelta); - else - t4 = 0; - } - Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28)); - - if (i == 0) - pAd->Tx20MPwrCfgABand[i] = (pAd->Tx20MPwrCfgABand[i] & 0x0000FFFF) | (Adata & 0xFFFF0000); - else - pAd->Tx20MPwrCfgABand[i] = Adata; - - DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 5GHz band, Adata = %lx \n", Adata)); - } - } - - // - // Check this block is valid for 40MHz in 5G. If invalid, use parameter for 20MHz in 2.4G - // - bValid = TRUE; - for (i=0; i<6; i++) - { - RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + 2 + i*2, value); - if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00)) - { - bValid = FALSE; - break; - } - } - - // - // Get Txpower per MCS for 40MHz in 5G. - // - if (bValid) - { - for (i=0; i<4; i++) - { - RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4, value); - if (bApwrdeltaMinus == FALSE) - { - t1 = (value&0xf)+(Apwrdelta); - if (t1 > 0xf) - t1 = 0xf; - t2 = ((value&0xf0)>>4)+(Apwrdelta); - if (t2 > 0xf) - t2 = 0xf; - t3 = ((value&0xf00)>>8)+(Apwrdelta); - if (t3 > 0xf) - t3 = 0xf; - t4 = ((value&0xf000)>>12)+(Apwrdelta); - if (t4 > 0xf) - t4 = 0xf; - } - else - { - if ((value&0xf) > Apwrdelta) - t1 = (value&0xf)-(Apwrdelta); - else - t1 = 0; - if (((value&0xf0)>>4) > Apwrdelta) - t2 = ((value&0xf0)>>4)-(Apwrdelta); - else - t2 = 0; - if (((value&0xf00)>>8) > Apwrdelta) - t3 = ((value&0xf00)>>8)-(Apwrdelta); - else - t3 = 0; - if (((value&0xf000)>>12) > Apwrdelta) - t4 = ((value&0xf000)>>12)-(Apwrdelta); - else - t4 = 0; - } - Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12); - - RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4 + 2, value); - if (bApwrdeltaMinus == FALSE) - { - t1 = (value&0xf)+(Apwrdelta); - if (t1 > 0xf) - t1 = 0xf; - t2 = ((value&0xf0)>>4)+(Apwrdelta); - if (t2 > 0xf) - t2 = 0xf; - t3 = ((value&0xf00)>>8)+(Apwrdelta); - if (t3 > 0xf) - t3 = 0xf; - t4 = ((value&0xf000)>>12)+(Apwrdelta); - if (t4 > 0xf) - t4 = 0xf; - } - else - { - if ((value&0xf) > Apwrdelta) - t1 = (value&0xf)-(Apwrdelta); - else - t1 = 0; - if (((value&0xf0)>>4) > Apwrdelta) - t2 = ((value&0xf0)>>4)-(Apwrdelta); - else - t2 = 0; - if (((value&0xf00)>>8) > Apwrdelta) - t3 = ((value&0xf00)>>8)-(Apwrdelta); - else - t3 = 0; - if (((value&0xf000)>>12) > Apwrdelta) - t4 = ((value&0xf000)>>12)-(Apwrdelta); - else - t4 = 0; - } - Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28)); - - if (i == 0) - pAd->Tx40MPwrCfgABand[i+1] = (pAd->Tx40MPwrCfgABand[i+1] & 0x0000FFFF) | (Adata & 0xFFFF0000); - else - pAd->Tx40MPwrCfgABand[i+1] = Adata; - - DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 5GHz band, Adata = %lx \n", Adata)); - } - } } @@ -939,10 +592,11 @@ VOID RTMPReadChannelPwr( pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1; } - // 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165 (including central frequency in BW 40MHz) + // 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165, 167, 169; 171, 173 (including central frequency in BW 40MHz) // 3.1 Fill up channel choffset = 14 + 12 + 16; - for (i = 0; i < 2; i++) + /*for (i = 0; i < 2; i++)*/ + for (i = 0; i < 3; i++) { pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0; pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER; @@ -956,12 +610,17 @@ VOID RTMPReadChannelPwr( pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER; pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER; } - pAd->TxPower[3 * 2 + choffset + 0].Channel = 165; - pAd->TxPower[3 * 2 + choffset + 0].Power = DEFAULT_RF_TX_POWER; - pAd->TxPower[3 * 2 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * 3 + choffset + 0].Channel = 171; + pAd->TxPower[3 * 3 + choffset + 0].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * 3 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER; + + pAd->TxPower[3 * 3 + choffset + 1].Channel = 173; + pAd->TxPower[3 * 3 + choffset + 1].Power = DEFAULT_RF_TX_POWER; + pAd->TxPower[3 * 3 + choffset + 1].Power2 = DEFAULT_RF_TX_POWER; // 3.2 Fill up power - for (i = 0; i < 4; i++) + /*for (i = 0; i < 4; i++)*/ + for (i = 0; i < 6; i++) { RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word); RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word); @@ -980,7 +639,10 @@ VOID RTMPReadChannelPwr( } // 4. Print and Debug - choffset = 14 + 12 + 16 + 7; + /*choffset = 14 + 12 + 16 + 7;*/ + choffset = 14 + 12 + 16 + 11; + + } /* @@ -1017,267 +679,6 @@ NDIS_STATUS NICReadRegParameters( } -#ifdef RT2870 -/* - ======================================================================== - - Routine Description: - For RF filter calibration purpose - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = PASSIVE_LEVEL - - ======================================================================== -*/ -VOID RTMPFilterCalibration( - IN PRTMP_ADAPTER pAd) -{ - UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue=0; - UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0; - UCHAR RF_R24_Value = 0; - - // Give bbp filter initial value -#ifndef RT2870 - pAd->Mlme.CaliBW20RfR24 = 0x16; - pAd->Mlme.CaliBW40RfR24 = 0x36; //Bit[5] must be 1 for BW 40 -#else - pAd->Mlme.CaliBW20RfR24 = 0x1F; - pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40 -#endif - do - { - if (loop == 1) //BandWidth = 40 MHz - { - // Write 0x27 to RF_R24 to program filter - RF_R24_Value = 0x27; - RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); - if (IS_RT3090(pAd)) - FilterTarget = 0x15; - else - FilterTarget = 0x19; - - // when calibrate BW40, BBP mask must set to BW40. - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); - BBPValue&= (~0x18); - BBPValue|= (0x10); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); -#ifdef RT2870 - // set to BW40 - RT30xxReadRFRegister(pAd, RF_R31, &value); - value |= 0x20; - RT30xxWriteRFRegister(pAd, RF_R31, value); -#endif - } - else //BandWidth = 20 MHz - { - // Write 0x07 to RF_R24 to program filter - RF_R24_Value = 0x07; - RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); - if (IS_RT3090(pAd)) - FilterTarget = 0x13; - else - FilterTarget = 0x16; -#ifdef RT2870 - // set to BW20 - RT30xxReadRFRegister(pAd, RF_R31, &value); - value &= (~0x20); - RT30xxWriteRFRegister(pAd, RF_R31, value); -#endif - } - - // Write 0x01 to RF_R22 to enable baseband loopback mode - RT30xxReadRFRegister(pAd, RF_R22, &value); - value |= 0x01; - RT30xxWriteRFRegister(pAd, RF_R22, value); - - // Write 0x00 to BBP_R24 to set power & frequency of passband test tone - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0); - - do - { - // Write 0x90 to BBP_R25 to transmit test tone - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90); - - RTMPusecDelay(1000); - // Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0] - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value); - R55x = value & 0xFF; - - } while ((ReTry++ < 100) && (R55x == 0)); - - // Write 0x06 to BBP_R24 to set power & frequency of stopband test tone - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06); - - while(TRUE) - { - // Write 0x90 to BBP_R25 to transmit test tone - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90); - - //We need to wait for calibration - RTMPusecDelay(1000); - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value); - value &= 0xFF; - if ((R55x - value) < FilterTarget) - { - RF_R24_Value ++; - } - else if ((R55x - value) == FilterTarget) - { - RF_R24_Value ++; - count ++; - } - else - { - break; - } - - // prevent infinite loop cause driver hang. - if (loopcnt++ > 100) - { - DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt)); - break; - } - - // Write RF_R24 to program filter - RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); - } - - if (count > 0) - { - RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0)); - } - - // Store for future usage - if (loopcnt < 100) - { - if (loop++ == 0) - { - //BandWidth = 20 MHz - pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value; - } - else - { - //BandWidth = 40 MHz - pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value; - break; - } - } - else - break; - - RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value); - - // reset count - count = 0; - } while(TRUE); - - // - // Set back to initial state - // - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0); - - RT30xxReadRFRegister(pAd, RF_R22, &value); - value &= ~(0x01); - RT30xxWriteRFRegister(pAd, RF_R22, value); - - // set BBP back to BW20 - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); - BBPValue&= (~0x18); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); - - DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24)); -} - -VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd) -{ - INT i; - // Driver must read EEPROM to get RfIcType before initial RF registers - // Initialize RF register to default value - if (IS_RT3070(pAd) || IS_RT3071(pAd)) - { - // Init RF calibration - // Driver should toggle RF R30 bit7 before init RF registers - UINT32 RfReg = 0; - UINT32 data; - - RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg); - RfReg |= 0x80; - RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg); - RTMPusecDelay(1000); - RfReg &= 0x7F; - RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg); - - // Initialize RF register to default value - for (i = 0; i < NUM_RF_REG_PARMS; i++) - { - RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value); - } - - if (IS_RT3070(pAd)) - { - // Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate - RTUSBReadMACRegister(pAd, LDO_CFG0, &data); - data = ((data & 0xF0FFFFFF) | 0x0D000000); - RTUSBWriteMACRegister(pAd, LDO_CFG0, data); - } - else if (IS_RT3071(pAd)) - { - // Driver should set RF R6 bit6 on before init RF registers - RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg); - RfReg |= 0x40; - RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg); - - // init R31 - RT30xxWriteRFRegister(pAd, RF_R31, 0x14); - - // RT3071 version E has fixed this issue - if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211)) - { - // patch tx EVM issue temporarily - RTUSBReadMACRegister(pAd, LDO_CFG0, &data); - data = ((data & 0xE0FFFFFF) | 0x0D000000); - RTUSBWriteMACRegister(pAd, LDO_CFG0, data); - } - else - { - RTMP_IO_READ32(pAd, LDO_CFG0, &data); - data = ((data & 0xE0FFFFFF) | 0x01000000); - RTMP_IO_WRITE32(pAd, LDO_CFG0, data); - } - - // patch LNA_PE_G1 failed issue - RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data); - data &= ~(0x20); - RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data); - } - - //For RF filter Calibration - RTMPFilterCalibration(pAd); - - // Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration() - if ((pAd->MACVersion & 0xffff) < 0x0211) - RT30xxWriteRFRegister(pAd, RF_R27, 0x3); - - // set led open drain enable - RTUSBReadMACRegister(pAd, OPT_14, &data); - data |= 0x01; - RTUSBWriteMACRegister(pAd, OPT_14, data); - - if (IS_RT3071(pAd)) - { - // add by johnli, RF power sequence setup, load RF normal operation-mode setup - RT30xxLoadRFNormalModeSetup(pAd); - } - } -} -#endif // RT2870 // - - /* ======================================================================== @@ -1310,6 +711,18 @@ VOID NICReadEEPROMParameters( DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n")); + if (pAd->chipOps.eeinit) + pAd->chipOps.eeinit(pAd); +#ifdef RTMP_EFUSE_SUPPORT +#ifdef RT30xx + if(!pAd->bFroceEEPROMBuffer && pAd->bEEPROMFile) + { + DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters::(Efuse)Load to EEPROM Buffer Mode\n")); + eFuseLoadEEPROM(pAd); + } +#endif // RT30xx // +#endif // RTMP_EFUSE_SUPPORT // + // Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8 RTMP_IO_READ32(pAd, E2PROM_CSR, &data); DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data)); @@ -1325,7 +738,7 @@ VOID NICReadEEPROMParameters( // RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize // MAC address registers according to E2PROM setting if (mac_addr == NULL || - strlen(mac_addr) != 17 || + strlen((PSTRING) mac_addr) != 17 || mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' || mac_addr[11] != ':' || mac_addr[14] != ':') { @@ -1347,9 +760,9 @@ VOID NICReadEEPROMParameters( else { INT j; - PUCHAR macptr; + PSTRING macptr; - macptr = mac_addr; + macptr = (PSTRING) mac_addr; for (j=0; jPermanentAddress[0], pAd->PermanentAddress[1], - pAd->PermanentAddress[2], pAd->PermanentAddress[3], - pAd->PermanentAddress[4], pAd->PermanentAddress[5])); + PRINT_MAC(pAd->PermanentAddress))); } } @@ -1450,7 +861,8 @@ VOID NICReadEEPROMParameters( Antenna.word = pAd->EEPROMDefaultValue[0]; if (Antenna.word == 0xFFFF) { - if(IS_RT3090(pAd)) +#ifdef RT30xx + if(IS_RT3090(pAd)|| IS_RT3390(pAd)) { Antenna.word = 0; Antenna.field.RfIcType = RFIC_3020; @@ -1458,7 +870,9 @@ VOID NICReadEEPROMParameters( Antenna.field.RxPath = 1; } else +#endif // RT30xx // { + Antenna.word = 0; Antenna.field.RfIcType = RFIC_2820; Antenna.field.TxPath = 1; @@ -1514,11 +928,26 @@ VOID NICReadEEPROMParameters( // Save the antenna for future use pAd->Antenna.word = Antenna.word; + // Set the RfICType here, then we can initialize RFIC related operation callbacks + pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath; + pAd->RfIcType = (UCHAR) Antenna.field.RfIcType; + +#ifdef RTMP_RF_RW_SUPPORT + RtmpChipOpsRFHook(pAd); +#endif // RTMP_RF_RW_SUPPORT // + +#ifdef RTMP_MAC_PCI + sprintf((PSTRING) pAd->nickname, "RT2860STA"); +#endif // RTMP_MAC_PCI // + + // // Reset PhyMode if we don't support 802.11a // Only RFIC_2850 & RFIC_2750 support 802.11a // - if ((Antenna.field.RfIcType != RFIC_2850) && (Antenna.field.RfIcType != RFIC_2750)) + if ((Antenna.field.RfIcType != RFIC_2850) + && (Antenna.field.RfIcType != RFIC_2750) + && (Antenna.field.RfIcType != RFIC_3052)) { if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11A)) @@ -1671,11 +1100,31 @@ VOID NICReadEEPROMParameters( if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10)) pAd->ARssiOffset2 = 0; +#ifdef RT30xx + // + // Get TX mixer gain setting + // 0xff are invalid value + // Note: RT30xX default value is 0x00 and will program to RF_R17 only when this value is not zero. + // RT359X default value is 0x02 + // + if (IS_RT30xx(pAd) || IS_RT3572(pAd)) + { + RT28xx_EEPROM_READ16(pAd, EEPROM_TXMIXER_GAIN_2_4G, value); + pAd->TxMixerGain24G = 0; + value &= 0x00ff; + if (value != 0xff) + { + value &= 0x07; + pAd->TxMixerGain24G = (UCHAR)value; + } + } +#endif // RT30xx // + // // Get LED Setting. // RT28xx_EEPROM_READ16(pAd, 0x3a, value); - pAd->LedCntl.word = (value&0xff00) >> 8; + pAd->LedCntl.word = (value>>8); RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value); pAd->Led1 = value; RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value); @@ -1685,6 +1134,12 @@ VOID NICReadEEPROMParameters( RTMPReadTxPwrPerRate(pAd); +#ifdef RT30xx +#ifdef RTMP_EFUSE_SUPPORT + RtmpEfuseSupportCheck(pAd); +#endif // RTMP_EFUSE_SUPPORT // +#endif // RT30xx // + DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n")); } @@ -1712,7 +1167,7 @@ VOID NICInitAsicFromEEPROM( UINT32 data = 0; UCHAR BBPR1 = 0; USHORT i; - EEPROM_ANTENNA_STRUC Antenna; +// EEPROM_ANTENNA_STRUC Antenna; EEPROM_NIC_CONFIG2_STRUC NicConfig2; UCHAR BBPR3 = 0; @@ -1729,28 +1184,9 @@ VOID NICInitAsicFromEEPROM( } } -#ifndef RT2870 - Antenna.word = pAd->Antenna.word; -#else - Antenna.word = pAd->EEPROMDefaultValue[0]; - if (Antenna.word == 0xFFFF) - { - DBGPRINT(RT_DEBUG_ERROR, ("E2PROM error, hard code as 0x%04x\n", Antenna.word)); - BUG_ON(Antenna.word == 0xFFFF); - } -#endif - pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath; - pAd->RfIcType = (UCHAR) Antenna.field.RfIcType; - -#ifdef RT2870 - DBGPRINT(RT_DEBUG_WARN, ("pAd->RfIcType = %d, RealRxPath=%d, TxPath = %d\n", pAd->RfIcType, pAd->Mlme.RealRxPath,Antenna.field.TxPath)); - - // Save the antenna for future use - pAd->Antenna.word = Antenna.word; -#endif - NicConfig2.word = pAd->EEPROMDefaultValue[1]; - -#ifdef RT2870 + + NicConfig2.word = pAd->EEPROMDefaultValue[1]; + { if ((NicConfig2.word & 0x00ff) == 0xff) { @@ -1762,15 +1198,16 @@ VOID NICInitAsicFromEEPROM( NicConfig2.word &= 0x00ff; } } -#endif + // Save the antenna for future use pAd->NicConfig2.word = NicConfig2.word; -#ifdef RT2870 +#ifdef RT30xx // set default antenna as main if (pAd->RfIcType == RFIC_3020) AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt); -#endif +#endif // RT30xx // + // // Send LED Setting to MCU. // @@ -1779,19 +1216,21 @@ VOID NICInitAsicFromEEPROM( pAd->LedCntl.word = 0x01; pAd->Led1 = 0x5555; pAd->Led2 = 0x2221; -#ifdef RT2860 - pAd->Led3 = 0xA9F8; -#endif -#ifdef RT2870 +#ifdef RTMP_MAC_PCI + pAd->Led3 = 0xA9F8; +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB pAd->Led3 = 0x5627; -#endif // RT2870 // +#endif // RTMP_MAC_USB // } AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8)); AsicSendCommandToMcu(pAd, 0x53, 0xff, (UCHAR)pAd->Led2, (UCHAR)(pAd->Led2 >> 8)); AsicSendCommandToMcu(pAd, 0x54, 0xff, (UCHAR)pAd->Led3, (UCHAR)(pAd->Led3 >> 8)); - pAd->LedIndicatorStregth = 0xFF; + AsicSendCommandToMcu(pAd, 0x51, 0xff, 0, pAd->LedCntl.field.Polarity); + + pAd->LedIndicatorStrength = 0xFF; RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, before link up { @@ -1806,6 +1245,7 @@ VOID NICInitAsicFromEEPROM( { pAd->StaCfg.bHwRadio = FALSE; pAd->StaCfg.bRadio = FALSE; +// RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); } } @@ -1819,26 +1259,29 @@ VOID NICInitAsicFromEEPROM( else { RTMPSetLED(pAd, LED_RADIO_ON); -#ifdef RT2860 +#ifdef RTMP_MAC_PCI AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00); // 2-1. wait command ok. AsicCheckCommanOk(pAd, PowerWakeCID); -#endif +#endif // RTMP_MAC_PCI // } } // Turn off patching for cardbus controller if (NicConfig2.field.CardbusAcceleration == 1) { +// pAd->bTest1 = TRUE; } if (NicConfig2.field.DynamicTxAgcControl == 1) pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE; else pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE; - - /* BBP has been programmed so reset to UNKNOWN_BAND */ + // + // Since BBP has been progamed, to make sure BBP setting will be + // upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND!! + // pAd->CommonCfg.BandState = UNKNOWN_BAND; RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3); @@ -1866,10 +1309,53 @@ VOID NICInitAsicFromEEPROM( } RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1); - DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n", pAd->CommonCfg.bHardwareRadio, pAd->CommonCfg.bHardwareRadio)); + DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n", + pAd->CommonCfg.bHardwareRadio, pAd->CommonCfg.bHardwareRadio)); + } + +#ifdef RTMP_MAC_USB +#ifdef RT30xx + // update registers from EEPROM for RT3071 or later(3572/3592). + + if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) + { + UCHAR RegIdx, RegValue; + USHORT value; + + // after RT3071, write BBP from EEPROM 0xF0 to 0x102 + for (i = 0xF0; i <= 0x102; i = i+2) + { + value = 0xFFFF; + RT28xx_EEPROM_READ16(pAd, i, value); + if ((value != 0xFFFF) && (value != 0)) + { + RegIdx = (UCHAR)(value >> 8); + RegValue = (UCHAR)(value & 0xff); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, RegIdx, RegValue); + DBGPRINT(RT_DEBUG_TRACE, ("Update BBP Registers from EEPROM(0x%0x), BBP(0x%x) = 0x%x\n", i, RegIdx, RegValue)); + } + } + + // after RT3071, write RF from EEPROM 0x104 to 0x116 + for (i = 0x104; i <= 0x116; i = i+2) + { + value = 0xFFFF; + RT28xx_EEPROM_READ16(pAd, i, value); + if ((value != 0xFFFF) && (value != 0)) + { + RegIdx = (UCHAR)(value >> 8); + RegValue = (UCHAR)(value & 0xff); + RT30xxWriteRFRegister(pAd, RegIdx, RegValue); + DBGPRINT(RT_DEBUG_TRACE, ("Update RF Registers from EEPROM0x%x), BBP(0x%x) = 0x%x\n", i, RegIdx, RegValue)); + } + } } +#endif // RT30xx // +#endif // RTMP_MAC_USB // - 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)); + 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)); DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n")); } @@ -1897,10 +1383,11 @@ NDIS_STATUS NICInitializeAdapter( { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; WPDMA_GLO_CFG_STRUC GloCfg; -#ifdef RT2860 +#ifdef RTMP_MAC_PCI UINT32 Value; DELAY_INT_CFG_STRUC IntCfg; -#endif +#endif // RTMP_MAC_PCI // +// INT_MASK_CSR_STRUC IntMask; ULONG i =0, j=0; AC_TXOP_CSR0_STRUC csr0; @@ -1939,11 +1426,11 @@ retry: // asic simulation sequence put this ahead before loading firmware. // pbf hardware reset -#ifdef RT2860 +#ifdef RTMP_MAC_PCI RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f); // 0x10000 for reset rx, 0x3f resets all 6 tx rings. RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f); RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00); -#endif +#endif // RTMP_MAC_PCI // // Initialze ASIC for TX & Rx operation if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS) @@ -1957,7 +1444,7 @@ retry: } -#ifdef RT2860 +#ifdef RTMP_MAC_PCI // Write AC_BK base address register Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa); RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value); @@ -2030,7 +1517,7 @@ retry: // Write RX_RING_CSR register Value = RX_RING_SIZE; RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value); -#endif /* RT2860 */ +#endif // RTMP_MAC_PCI // // WMM parameter @@ -2049,7 +1536,7 @@ retry: RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word); -#ifdef RT2860 +#ifdef RTMP_MAC_PCI // 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits: i = 0; do @@ -2068,7 +1555,7 @@ retry: IntCfg.word = 0; RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word); -#endif +#endif // RTMP_MAC_PCI // // reset action @@ -2104,26 +1591,44 @@ NDIS_STATUS NICInitializeAsic( ULONG Index = 0; UCHAR R0 = 0xff; UINT32 MacCsr12 = 0, Counter = 0; -#ifdef RT2870 +#ifdef RTMP_MAC_USB UINT32 MacCsr0 = 0; NTSTATUS Status; UCHAR Value = 0xff; - UINT32 eFuseCtrl; -#endif +#endif // RTMP_MAC_USB // +#ifdef RT30xx + UCHAR bbpreg=0; + UCHAR RFValue=0; +#endif // RT30xx // USHORT KeyIdx; INT i,apidx; DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n")); -#ifdef RT2860 +#ifdef RTMP_MAC_PCI + RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x3); // To fix driver disable/enable hang issue when radio off if (bHardReset == TRUE) { RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3); } else RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1); -#endif -#ifdef RT2870 + + RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0); + // Initialize MAC register to default value + for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++) + { + RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register, MACRegTable[Index].Value); + } + + { + for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) + { + RTMP_IO_WRITE32(pAd, STAMACRegTable[Index].Register, STAMACRegTable[Index].Value); + } + } +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB // // Make sure MAC gets ready after NICLoadFirmware(). // @@ -2151,44 +1656,32 @@ NDIS_STATUS NICInitializeAsic( RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3); RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0); Status = RTUSBVenderReset(pAd); -#endif RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0); // Initialize MAC register to default value -#ifdef RT2860 - for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++) - { - RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register, MACRegTable[Index].Value); - } -#endif -#ifdef RT2870 for(Index=0; IndexNicConfig2.field.DACTestBit == 1) { - RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C); // To fix throughput drop drastically } else { @@ -2209,11 +1702,17 @@ NDIS_STATUS NICInitializeAsic( RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0); } } -#ifdef RT2870 else if (IS_RT3070(pAd)) { + if (((pAd->MACVersion & 0xffff) < 0x0201)) + { RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0); - RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C); // To fix throughput drop drastically + } + else + { + RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0); + } } #endif // RT30xx // @@ -2256,28 +1755,42 @@ NDIS_STATUS NICInitializeAsic( RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value); } -#ifndef RT2870 - // for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT. - if ((pAd->MACVersion&0xffff) != 0x0101) - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19); -#else +#ifdef RTMP_MAC_PCI + // TODO: shiang, check MACVersion, currently, rbus-based chip use this. + if (pAd->MACVersion == 0x28720200) + { + //UCHAR value; + ULONG value2; + + //disable MLD by Bruce 20080704 + //BBP_IO_READ8_BY_REG_ID(pAd, BBP_R105, &value); + //BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, value | 4); + + //Maximum PSDU length from 16K to 32K bytes + RTMP_IO_READ32(pAd, MAX_LEN_CFG, &value2); + value2 &= ~(0x3<<12); + value2 |= (0x2<<12); + RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, value2); + } +#endif // RTMP_MAC_PCI // + // for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT. // RT3090 should not program BBP R84 to 0x19, otherwise TX will block. - if (((pAd->MACVersion&0xffff) != 0x0101) && (!IS_RT30xx(pAd))) + //3070/71/72,3090,3090A( are included in RT30xx),3572,3390 + if (((pAd->MACVersion & 0xffff) != 0x0101) && !(IS_RT30xx(pAd)|| IS_RT3572(pAd) || IS_RT3390(pAd))) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19); +#ifdef RT30xx // add by johnli, RF power sequence setup - if (IS_RT30xx(pAd)) - { //update for RT3070/71/72/90/91/92. + if (IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) + { //update for RT3070/71/72/90/91/92,3572,3390. RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33); } - if (IS_RT3090(pAd)) + if (IS_RT3090(pAd)||IS_RT3390(pAd)) // RT309x, RT3071/72 { - UCHAR bbpreg=0; - // enable DC filter if ((pAd->MACVersion & 0xffff) >= 0x0211) { @@ -2307,7 +1820,38 @@ NDIS_STATUS NICInitializeAsic( RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg); } } -#endif + else if (IS_RT3070(pAd)) + { + if ((pAd->MACVersion & 0xffff) >= 0x0201) + { + // enable DC filter + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0); + + // improve power consumption in RT3070 Ver.F + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg); + bbpreg &= (~0x3); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg); + } + + // TX_LO1_en, RF R17 register Bit 3 to 0 + RT30xxReadRFRegister(pAd, RF_R17, &RFValue); + RFValue &= (~0x08); + // to fix rx long range issue + if (pAd->NicConfig2.field.ExternalLNAForG == 0) + { + RFValue |= 0x20; + } + // set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h + if (pAd->TxMixerGain24G >= 1) + { + RFValue &= (~0x7); // clean bit [2:0] + RFValue |= pAd->TxMixerGain24G; + } + RT30xxWriteRFRegister(pAd, RF_R17, RFValue); + } +// end johnli +#endif // RT30xx // + if (pAd->MACVersion == 0x28600100) { RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); @@ -2324,7 +1868,7 @@ NDIS_STATUS NICInitializeAsic( RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr); } -#ifdef RT2870 +#ifdef RTMP_MAC_USB { UCHAR MAC_Value[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0,0}; @@ -2335,7 +1879,7 @@ NDIS_STATUS NICInitializeAsic( RTUSBMultiWrite(pAd, (USHORT)(MAC_WCID_BASE + Index * 8), MAC_Value, 8); } } -#endif // RT2870 // +#endif // RTMP_MAC_USB // // Add radio off control { @@ -2356,7 +1900,7 @@ NDIS_STATUS NICInitializeAsic( RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter); // ASIC will keep garbage value after boot - // Clear all seared key table when initial + // Clear all shared key table when initial // This routine can be ignored in radio-ON/OFF operation. if (bHardReset) { @@ -2372,6 +1916,9 @@ NDIS_STATUS NICInitializeAsic( } } + // assert HOST ready bit +// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark +// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4); // It isn't necessary to clear this space when not hard reset. if (bHardReset == TRUE) @@ -2383,7 +1930,8 @@ NDIS_STATUS NICInitializeAsic( RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00); } } -#ifdef RT2870 + +#ifdef RTMP_MAC_USB AsicDisableSync(pAd); // Clear raw counters RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter); @@ -2397,19 +1945,7 @@ NDIS_STATUS NICInitializeAsic( Counter&=0xffffff00; Counter|=0x000001e; RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter); - - pAd->bUseEfuse=FALSE; - RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl); - pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0; - if(pAd->bUseEfuse) - { - DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse\n")); - } - else - { - DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n")); - } -#endif +#endif // RTMP_MAC_USB // { // for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT. @@ -2421,133 +1957,6 @@ NDIS_STATUS NICInitializeAsic( return NDIS_STATUS_SUCCESS; } - -#ifdef RT2860 -VOID NICRestoreBBPValue( - IN PRTMP_ADAPTER pAd) -{ - UCHAR index; - UCHAR Value = 0; - ULONG Data; - - DBGPRINT(RT_DEBUG_TRACE, ("---> NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!! \n")); - // Initialize BBP register to default value (rtmp_init.c) - for (index = 0; index < NUM_BBP_REG_PARMS; index++) - { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[index].Register, BBPRegTable[index].Value); - } - // copy from (rtmp_init.c) - if (pAd->MACVersion == 0x28600100) - { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12); - } - - // copy from (connect.c LinkUp function) - if (INFRA_ON(pAd)) - { - // Change to AP channel - if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) - { - // Must using 40MHz. - pAd->CommonCfg.BBPCurrentBW = BW_40; - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); - Value &= (~0x18); - Value |= 0x10; - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); - - // RX : control channel at lower - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); - Value &= (~0x20); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); - // Record BBPR3 setting, But don't keep R Antenna # information. - pAd->StaCfg.BBPR3 = Value; - - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); - Data &= 0xfffffffe; - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); - - if (pAd->MACVersion == 0x28600100) - { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); - DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); - } - - DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel )); - } - else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) - { - // Must using 40MHz. - pAd->CommonCfg.BBPCurrentBW = BW_40; - AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); - Value &= (~0x18); - Value |= 0x10; - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); - - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); - Data |= 0x1; - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); - Value |= (0x20); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); - // Record BBPR3 setting, But don't keep R Antenna # information. - pAd->StaCfg.BBPR3 = Value; - - if (pAd->MACVersion == 0x28600100) - { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); - DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); - } - - DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel )); - } - else - { - pAd->CommonCfg.BBPCurrentBW = BW_20; - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); - Value &= (~0x18); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); - - RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); - Data &= 0xfffffffe; - RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); - - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); - Value &= (~0x20); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); - // Record BBPR3 setting, But don't keep R Antenna # information. - pAd->StaCfg.BBPR3 = Value; - - if (pAd->MACVersion == 0x28600100) - { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08); - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11); - DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); - } - - DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz LINK UP !!! \n" )); - } - } - - DBGPRINT(RT_DEBUG_TRACE, ("<--- NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!! \n")); -} -#endif /* RT2860 */ - /* ======================================================================== @@ -2573,6 +1982,9 @@ VOID NICIssueReset( UINT32 Value = 0; DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n")); + // Abort Tx, prevent ASIC from writing to Host memory + //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000); + // Disable Rx, register value supposed will remain after reset RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value); Value &= (0xfffffff3); @@ -2676,7 +2088,9 @@ VOID NICUpdateFifoStaCounters( pEntry->FIFOCount = 0; pEntry->ContinueTxFailCnt = 0; } + //pEntry->FIFOCount = 0; } + //pEntry->bSendBAR = TRUE; } else { @@ -2752,7 +2166,9 @@ VOID NICUpdateFifoStaCounters( VOID NICUpdateRawCounters( IN PRTMP_ADAPTER pAd) { - UINT32 OldValue; + UINT32 OldValue;//, Value2; + //ULONG PageSum, OneSecTransmitCount; + //ULONG TxErrorRatio, Retry, Fail; RX_STA_CNT0_STRUC RxStaCnt0; RX_STA_CNT1_STRUC RxStaCnt1; RX_STA_CNT2_STRUC RxStaCnt2; @@ -2768,6 +2184,10 @@ VOID NICUpdateRawCounters( TX_AGG_CNT5_STRUC TxAggCnt5; TX_AGG_CNT6_STRUC TxAggCnt6; TX_AGG_CNT7_STRUC TxAggCnt7; + COUNTER_RALINK *pRalinkCounters; + + + pRalinkCounters = &pAd->RalinkCounters; RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word); RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word); @@ -2787,22 +2207,23 @@ VOID NICUpdateRawCounters( pAd->WlanCounters.FCSErrorCount.u.HighPart++; // Add FCS error count to private counters - pAd->RalinkCounters.OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr; - OldValue = pAd->RalinkCounters.RealFcsErrCount.u.LowPart; - pAd->RalinkCounters.RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr; - if (pAd->RalinkCounters.RealFcsErrCount.u.LowPart < OldValue) - pAd->RalinkCounters.RealFcsErrCount.u.HighPart++; + pRalinkCounters->OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr; + OldValue = pRalinkCounters->RealFcsErrCount.u.LowPart; + pRalinkCounters->RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr; + if (pRalinkCounters->RealFcsErrCount.u.LowPart < OldValue) + pRalinkCounters->RealFcsErrCount.u.HighPart++; // Update Duplicate Rcv check - pAd->RalinkCounters.DuplicateRcv += RxStaCnt2.field.RxDupliCount; + pRalinkCounters->DuplicateRcv += RxStaCnt2.field.RxDupliCount; pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount; // Update RX Overflow counter pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount); -#ifdef RT2870 - if (pAd->RalinkCounters.RxCount != pAd->watchDogRxCnt) + //pAd->RalinkCounters.RxCount = 0; +#ifdef RTMP_MAC_USB + if (pRalinkCounters->RxCount != pAd->watchDogRxCnt) { - pAd->watchDogRxCnt = pAd->RalinkCounters.RxCount; + pAd->watchDogRxCnt = pRalinkCounters->RxCount; pAd->watchDogRxOverFlowCnt = 0; } else @@ -2812,24 +2233,28 @@ VOID NICUpdateRawCounters( else pAd->watchDogRxOverFlowCnt = 0; } -#endif // RT2870 // +#endif // RTMP_MAC_USB // + //if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) || + // (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1))) if (!pAd->bUpdateBcnCntDone) { // Update BEACON sent count RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word); RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word); RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word); - pAd->RalinkCounters.OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount; - pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; - pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; - pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount; + pRalinkCounters->OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount; + pRalinkCounters->OneSecTxRetryOkCount += StaTx1.field.TxRetransmit; + pRalinkCounters->OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess; + pRalinkCounters->OneSecTxFailCount += TxStaCnt0.field.TxFailCount; pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess; pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit; pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount; } + + //if (pAd->bStaFifoTest == TRUE) { RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word); RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word); @@ -2840,53 +2265,53 @@ VOID NICUpdateRawCounters( RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word); RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word); RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word); - pAd->RalinkCounters.TxAggCount += TxAggCnt.field.AggTxCount; - pAd->RalinkCounters.TxNonAggCount += TxAggCnt.field.NonAggTxCount; - pAd->RalinkCounters.TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count; - pAd->RalinkCounters.TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count; - - pAd->RalinkCounters.TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count; - pAd->RalinkCounters.TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count; - pAd->RalinkCounters.TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count; - pAd->RalinkCounters.TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count; - - pAd->RalinkCounters.TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count; - pAd->RalinkCounters.TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count; - pAd->RalinkCounters.TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count; - pAd->RalinkCounters.TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count; - - pAd->RalinkCounters.TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count; - pAd->RalinkCounters.TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count; - pAd->RalinkCounters.TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count; - pAd->RalinkCounters.TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count; + pRalinkCounters->TxAggCount += TxAggCnt.field.AggTxCount; + pRalinkCounters->TxNonAggCount += TxAggCnt.field.NonAggTxCount; + pRalinkCounters->TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count; + pRalinkCounters->TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count; + + pRalinkCounters->TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count; + pRalinkCounters->TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count; + pRalinkCounters->TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count; + pRalinkCounters->TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count; + + pRalinkCounters->TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count; + pRalinkCounters->TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count; + pRalinkCounters->TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count; + pRalinkCounters->TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count; + + pRalinkCounters->TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count; + pRalinkCounters->TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count; + pRalinkCounters->TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count; + pRalinkCounters->TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count; - pAd->RalinkCounters.TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count; - pAd->RalinkCounters.TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count; + pRalinkCounters->TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count; + pRalinkCounters->TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count; // Calculate the transmitted A-MPDU count - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count; - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count; + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15); - pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15); + pRalinkCounters->TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16); } @@ -2932,112 +2357,38 @@ VOID NICResetFromError( AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); } -/* - ======================================================================== - Routine Description: - erase 8051 firmware image in MAC ASIC - - Arguments: - Adapter Pointer to our adapter - - IRQL = PASSIVE_LEVEL - - ======================================================================== -*/ -VOID NICEraseFirmware( +NDIS_STATUS NICLoadFirmware( IN PRTMP_ADAPTER pAd) { - ULONG i; + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + if (pAd->chipOps.loadFirmware) + status = pAd->chipOps.loadFirmware(pAd); - for(i=0; iMACVersion >> 16); -#endif // RT2870 // - - pFirmwareImage = FirmwareImage; - FileLength = sizeof(FirmwareImage); -#ifdef RT2870 - // New 8k byte firmware size for RT3071/RT3072 - //printk("Usb Chip\n"); - if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH) - //The firmware image consists of two parts. One is the origianl and the other is the new. - //Use Second Part - { - if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070)) - { // Use Firmware V2. - //printk("KH:Use New Version,part2\n"); - pFirmwareImage = (PUCHAR)&FirmwareImage[FIRMWAREIMAGEV1_LENGTH]; - FileLength = FIRMWAREIMAGEV2_LENGTH; - } - else - { - //printk("KH:Use New Version,part1\n"); - pFirmwareImage = FirmwareImage; - FileLength = FIRMWAREIMAGEV1_LENGTH; - } - } - else - { - DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n")); - Status = NDIS_STATUS_FAILURE; - } - -#endif // RT2870 // - - RT28XX_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength); - - /* check if MCU is ready */ - Index = 0; - do - { - RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg); - - if (MacReg & 0x80) - break; + if (pAd->chipOps.eraseFirmware) + pAd->chipOps.eraseFirmware(pAd); - RTMPusecDelay(1000); - } while (Index++ < 1000); - - if (Index > 1000) - { - Status = NDIS_STATUS_FAILURE; - DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n")); - } /* End of if */ - - DBGPRINT(RT_DEBUG_TRACE, - ("<=== %s (status=%d)\n", __func__, Status)); - return Status; -} /* End of NICLoadFirmware */ +}/* End of NICEraseFirmware */ /* @@ -3067,52 +2418,6 @@ NDIS_STATUS NICLoadRateSwitchingParams( return NDIS_STATUS_SUCCESS; } -/* - ======================================================================== - - Routine Description: - if pSrc1 all zero with length Length, return 0. - If not all zero, return 1 - - Arguments: - pSrc1 - - Return Value: - 1: not all zero - 0: all zero - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -ULONG RTMPNotAllZero( - IN PVOID pSrc1, - IN ULONG Length) -{ - PUCHAR pMem1; - ULONG Index = 0; - - pMem1 = (PUCHAR) pSrc1; - - for (Index = 0; Index < Length; Index++) - { - if (pMem1[Index] != 0x0) - { - break; - } - } - - if (Index == Length) - { - return (0); - } - else - { - return (1); - } -} /* ======================================================================== @@ -3194,21 +2499,6 @@ VOID RTMPZeroMemory( } } -VOID RTMPFillMemory( - IN PVOID pSrc, - IN ULONG Length, - IN UCHAR Fill) -{ - PUCHAR pMem; - ULONG Index = 0; - - pMem = (PUCHAR) pSrc; - - for (Index = 0; Index < Length; Index++) - { - pMem[Index] = Fill; - } -} /* ======================================================================== @@ -3272,6 +2562,7 @@ VOID RTMPMoveMemory( VOID UserCfgInit( IN PRTMP_ADAPTER pAd) { +// EDCA_PARM DefaultEdcaParm; UINT key_index, bss_index; DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n")); @@ -3279,7 +2570,7 @@ VOID UserCfgInit( // // part I. intialize common configuration // -#ifdef RT2870 +#ifdef RTMP_MAC_USB pAd->BulkOutReq = 0; pAd->BulkOutComplete = 0; @@ -3294,7 +2585,7 @@ VOID UserCfgInit( pAd->bUsbTxBulkAggre = 0; // init as unsed value to ensure driver will set to MCU once. - pAd->LedIndicatorStregth = 0xFF; + pAd->LedIndicatorStrength = 0xFF; pAd->CommonCfg.MaxPktOneTxBulk = 2; pAd->CommonCfg.TxBulkFactor = 1; @@ -3303,7 +2594,7 @@ VOID UserCfgInit( pAd->CommonCfg.TxPower = 100; //mW NdisZeroMemory(&pAd->CommonCfg.IOTestParm, sizeof(pAd->CommonCfg.IOTestParm)); -#endif // RT2870 // +#endif // RTMP_MAC_USB // for(key_index=0; key_indexEepromAccess = FALSE; -#endif + pAd->Antenna.word = 0; pAd->CommonCfg.BBPCurrentBW = BW_20; pAd->LedCntl.word = 0; -#ifdef RT2860 - pAd->LedIndicatorStregth = 0; +#ifdef RTMP_MAC_PCI + pAd->LedIndicatorStrength = 0; pAd->RLnkCtrlOffset = 0; pAd->HostLnkCtrlOffset = 0; - pAd->CheckDmaBusyCount = 0; -#endif +#endif // RTMP_MAC_PCI // pAd->bAutoTxAgcA = FALSE; // Default is OFF pAd->bAutoTxAgcG = FALSE; // Default is OFF @@ -3355,8 +2644,17 @@ VOID UserCfgInit( pAd->CommonCfg.RadarDetect.CSPeriod = 10; pAd->CommonCfg.RadarDetect.CSCount = 0; pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE; + + + + pAd->CommonCfg.RadarDetect.ChMovingTime = 65; +#ifdef MERGE_ARCH_TEAM + pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 2; + pAd->CommonCfg.RadarDetect.AvgRssiReq = -75; +#else // original rt28xx source code pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3; +#endif // MERGE_ARCH_TEAM // pAd->CommonCfg.bAPSDCapable = FALSE; pAd->CommonCfg.bNeedSendTriggerFrame = FALSE; pAd->CommonCfg.TriggerTimerCount = 0; @@ -3386,10 +2684,18 @@ VOID UserCfgInit( pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1; pAd->CommonCfg.bHTProtect = 1; pAd->CommonCfg.bMIMOPSEnable = TRUE; + //2008/11/05:KH add to support Antenna power-saving of AP<-- + pAd->CommonCfg.bGreenAPEnable=FALSE; + //2008/11/05:KH add to support Antenna power-saving of AP--> pAd->CommonCfg.bBADecline = FALSE; pAd->CommonCfg.bDisableReordering = FALSE; + if (pAd->MACVersion == 0x28720200) + { + pAd->CommonCfg.TxBASize = 13; //by Jerry recommend + }else{ pAd->CommonCfg.TxBASize = 7; + } pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word; @@ -3467,12 +2773,6 @@ VOID UserCfgInit( // Patch for Ndtest pAd->StaCfg.ScanCnt = 0; - // CCX 2.0 control flag init - pAd->StaCfg.CCXEnable = FALSE; - pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED; - pAd->StaCfg.CCXQosECWMin = 4; - pAd->StaCfg.CCXQosECWMax = 10; - pAd->StaCfg.bHwRadio = TRUE; // Default Hardware Radio status is On pAd->StaCfg.bSwRadio = TRUE; // Default Software Radio status is On pAd->StaCfg.bRadio = TRUE; // bHwRadio && bSwRadio @@ -3484,14 +2784,31 @@ VOID UserCfgInit( // Save the init time as last scan time, the system should do scan after 2 seconds. // This patch is for driver wake up from standby mode, system will do scan right away. - pAd->StaCfg.LastScanTime = 0; + NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime); + if (pAd->StaCfg.LastScanTime > 10 * OS_HZ) + pAd->StaCfg.LastScanTime -= (10 * OS_HZ); + NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1); - sprintf(pAd->nickname, "%s", STA_NIC_DEVICE_NAME); +#ifdef RTMP_MAC_USB + sprintf((PSTRING) pAd->nickname, "RT2870STA"); +#endif // RTMP_MAC_USB // RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), pAd, FALSE); pAd->StaCfg.IEEE8021X = FALSE; pAd->StaCfg.IEEE8021x_required_keys = FALSE; pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE; + pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE; pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE; + pAd->StaCfg.bLostAp = FALSE; + + NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8); + + + pAd->StaCfg.bAutoConnectByBssid = FALSE; + pAd->StaCfg.BeaconLostTime = BEACON_LOST_TIME; + NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64); + pAd->StaCfg.WpaPassPhraseLen = 0; + pAd->StaCfg.bAutoRoaming = FALSE; + pAd->StaCfg.bForceTxBurst = FALSE; } // Default for extra information is not valid @@ -3524,22 +2841,30 @@ VOID UserCfgInit( pAd->Bbp94 = BBPR94_DEFAULT; pAd->BbpForCCK = FALSE; + // Default is FALSE for test bit 1 + //pAd->bTest1 = FALSE; + // initialize MAC table and allocate spin lock NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE)); InitializeQueueHeader(&pAd->MacTab.McastPsQueue); NdisAllocateSpinLock(&pAd->MacTabLock); + //RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE); + //RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV); + + + pAd->CommonCfg.bWiFiTest = FALSE; -#ifdef RT2860 +#ifdef RTMP_MAC_PCI pAd->bPCIclkOff = FALSE; +#endif // RTMP_MAC_PCI // - RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); -#endif +RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n")); } // IRQL = PASSIVE_LEVEL -UCHAR BtoH(char ch) +UCHAR BtoH(STRING ch) { if (ch >= '0' && ch <= '9') return (ch - '0'); // Handle numerals if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA); // Handle capitol hex digits @@ -3564,9 +2889,9 @@ UCHAR BtoH(char ch) // // IRQL = PASSIVE_LEVEL -void AtoH(char * src, UCHAR * dest, int destlen) +void AtoH(PSTRING src, PUCHAR dest, int destlen) { - char * srcptr; + PSTRING srcptr; PUCHAR destTemp; srcptr = src; @@ -3580,24 +2905,10 @@ void AtoH(char * src, UCHAR * dest, int } } -VOID RTMPPatchMacBbpBug( - IN PRTMP_ADAPTER pAd) -{ - ULONG Index; - // Initialize BBP register to default value - for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++) - { - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, (UCHAR)BBPRegTable[Index].Value); - } - - // Initialize RF register to default value - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); +//+++Mark by shiang, not use now, need to remove after confirm +//---Mark by shiang, not use now, need to remove after confirm - // Re-init BBP register from EEPROM value - NICInitAsicFromEEPROM(pAd); -} /* ======================================================================== @@ -3636,9 +2947,9 @@ VOID RTMPInitTimer( pTimer->State = FALSE; pTimer->cookie = (ULONG) pData; -#ifdef RT2870 +#ifdef RTMP_TIMER_TASK_SUPPORT pTimer->pAd = pAd; -#endif // RT2870 // +#endif // RTMP_TIMER_TASK_SUPPORT // RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (PVOID) pTimer); } @@ -3760,24 +3071,20 @@ VOID RTMPCancelTimer( { if (pTimer->State == FALSE) pTimer->Repeat = FALSE; + RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled); if (*pCancelled == TRUE) pTimer->State = TRUE; -#ifdef RT2870 +#ifdef RTMP_TIMER_TASK_SUPPORT // We need to go-through the TimerQ to findout this timer handler and remove it if // it's still waiting for execution. - - RT2870_TimerQ_Remove(pTimer->pAd, pTimer); -#endif // RT2870 // + RtmpTimerQRemove(pTimer->pAd, pTimer); +#endif // RTMP_TIMER_TASK_SUPPORT // } else { - // - // NdisMCancelTimer just canced the timer and not mean release the timer. - // And don't set the "Valid" to False. So that we can use this timer again. - // DBGPRINT_ERR(("RTMPCancelTimer failed, Timer hasn't been initialize!\n")); } } @@ -3816,7 +3123,7 @@ VOID RTMPSetLED( case LED_LINK_DOWN: HighByte = 0x20; AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte); - pAd->LedIndicatorStregth = 0; + pAd->LedIndicatorStrength = 0; break; case LED_LINK_UP: if (pAd->CommonCfg.Channel > 14) @@ -3895,14 +3202,8 @@ VOID RTMPSetSignalLED( { UCHAR nLed = 0; - // - // if not Signal Stregth, then do nothing. - // - if (pAd->LedCntl.field.LedMode != LED_MODE_SIGNAL_STREGTH) + if (pAd->LedCntl.field.LedMode == LED_MODE_SIGNAL_STREGTH) { - return; - } - if (Dbm <= -90) nLed = 0; else if (Dbm <= -81) @@ -3919,10 +3220,11 @@ VOID RTMPSetSignalLED( // // Update Signal Stregth to firmware if changed. // - if (pAd->LedIndicatorStregth != nLed) + if (pAd->LedIndicatorStrength != nLed) { AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, pAd->LedCntl.field.Polarity); - pAd->LedIndicatorStregth = nLed; + pAd->LedIndicatorStrength = nLed; + } } } @@ -3947,6 +3249,10 @@ VOID RTMPSetSignalLED( VOID RTMPEnableRxTx( IN PRTMP_ADAPTER pAd) { +// WPDMA_GLO_CFG_STRUC GloCfg; +// ULONG i = 0; + UINT32 rx_filter_flag; + DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n")); // Enable Rx DMA. @@ -3955,14 +3261,18 @@ VOID RTMPEnableRxTx( // enable RX of MAC block if (pAd->OpMode == OPMODE_AP) { - UINT32 rx_filter_flag = APNORMAL; + rx_filter_flag = APNORMAL; RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); // enable RX of DMA block } else { - RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification. + if (pAd->CommonCfg.PSPXlink) + rx_filter_flag = PSPXLINK; + else + rx_filter_flag = STANORMAL; // Staion not drop control frame will fail WiFi Certification. + RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); } RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc); @@ -3970,3 +3280,380 @@ VOID RTMPEnableRxTx( } +//+++Add by shiang, move from os/linux/rt_main_dev.c +void CfgInitHook(PRTMP_ADAPTER pAd) +{ + pAd->bBroadComHT = TRUE; +} + + +int rt28xx_init( + IN PRTMP_ADAPTER pAd, + IN PSTRING pDefaultMac, + IN PSTRING pHostName) +{ + UINT index; + UCHAR TmpPhy; + NDIS_STATUS Status; + UINT32 MacCsr0 = 0; + + +#ifdef RTMP_MAC_PCI + { + // If dirver doesn't wake up firmware here, + // NICLoadFirmware will hang forever when interface is up again. + // RT2860 PCI + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) && + OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + { + AUTO_WAKEUP_STRUC AutoWakeupCfg; + AsicForceWakeup(pAd, TRUE); + AutoWakeupCfg.word = 0; + RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); + } + } +#endif // RTMP_MAC_PCI // + + + // reset Adapter flags + RTMP_CLEAR_FLAGS(pAd); + + // Init BssTab & ChannelInfo tabbles for auto channel select. + + // Allocate BA Reordering memory + ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM); + + // Make sure MAC gets ready. + index = 0; + do + { + RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); + pAd->MACVersion = MacCsr0; + + if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF)) + break; + + RTMPusecDelay(10); + } while (index++ < 100); + DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion)); + +#ifdef RTMP_MAC_PCI + + // To fix driver disable/enable hang issue when radio off + RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2); +#endif // RTMP_MAC_PCI // + + // Disable DMA + RT28XXDMADisable(pAd); + + + // Load 8051 firmware + Status = NICLoadFirmware(pAd); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status)); + goto err1; + } + + NICLoadRateSwitchingParams(pAd); + + // Disable interrupts here which is as soon as possible + // This statement should never be true. We might consider to remove it later +#ifdef RTMP_MAC_PCI + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) + { + RTMP_ASIC_INTERRUPT_DISABLE(pAd); + } +#endif // RTMP_MAC_PCI // + + Status = RTMPAllocTxRxRingMemory(pAd); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status)); + goto err1; + } + + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); + + // initialize MLME + // + + Status = RtmpMgmtTaskInit(pAd); + if (Status != NDIS_STATUS_SUCCESS) + goto err2; + + Status = MlmeInit(pAd); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status)); + goto err2; + } + + // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default + // + UserCfgInit(pAd); + Status = RtmpNetTaskInit(pAd); + if (Status != NDIS_STATUS_SUCCESS) + goto err3; + +// COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr); +// pAd->bForcePrintTX = TRUE; + + CfgInitHook(pAd); + + NdisAllocateSpinLock(&pAd->MacTabLock); + + MeasureReqTabInit(pAd); + TpcReqTabInit(pAd); + + // + // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset + // + Status = NICInitializeAdapter(pAd, TRUE); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status)); + if (Status != NDIS_STATUS_SUCCESS) + goto err3; + } + + // Read parameters from Config File + Status = RTMPReadParametersHook(pAd); + + DBGPRINT(RT_DEBUG_OFF, ("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); + if (Status != NDIS_STATUS_SUCCESS) + { + DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status)); +// goto err4; + Status = 0; + } + +#ifdef RTMP_MAC_USB + pAd->CommonCfg.bMultipleIRP = FALSE; + + if (pAd->CommonCfg.bMultipleIRP) + pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE; + else + pAd->CommonCfg.NumOfBulkInIRP = 1; +#endif // RTMP_MAC_USB // + + //Init Ba Capability parameters. +// RT28XX_BA_INIT(pAd); + pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; + pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; + pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; + pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; + // UPdata to HT IE + pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; + pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; + pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; + + // after reading Registry, we now know if in AP mode or STA mode + + // Load 8051 firmware; crash when FW image not existent + // Status = NICLoadFirmware(pAd); + // if (Status != NDIS_STATUS_SUCCESS) + // break; + + DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); + + // We should read EEPROM for all cases. rt2860b + NICReadEEPROMParameters(pAd, (PUCHAR)pDefaultMac); + + DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode)); + + NICInitAsicFromEEPROM(pAd); //rt2860b + + // Set PHY to appropriate mode + TmpPhy = pAd->CommonCfg.PhyMode; + pAd->CommonCfg.PhyMode = 0xff; + RTMPSetPhyMode(pAd, TmpPhy); + SetCommonHT(pAd); + + // No valid channels. + if (pAd->ChannelListNum == 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n")); + goto err4; + } + + DBGPRINT(RT_DEBUG_OFF, ("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0], + pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2], + pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4])); + +#ifdef RTMP_RF_RW_SUPPORT + //Init RT30xx RFRegisters after read RFIC type from EEPROM + NICInitRFRegisters(pAd); +#endif // RTMP_RF_RW_SUPPORT // + +// APInitialize(pAd); + + + // + // Initialize RF register to default value + // + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + + // 8051 firmware require the signal during booting time. + //2008/11/28:KH marked the following codes to patch Frequency offset bug + //AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00); + + if (pAd && (Status != NDIS_STATUS_SUCCESS)) + { + // + // Undo everything if it failed + // + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) + { +// NdisMDeregisterInterrupt(&pAd->Interrupt); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); + } +// RTMPFreeAdapter(pAd); // we will free it in disconnect() + } + else if (pAd) + { + // Microsoft HCT require driver send a disconnect event after driver initialization. + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); +// pAd->IndicateMediaState = NdisMediaStateDisconnected; + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE); + + DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n")); + +#ifdef RTMP_MAC_USB + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); + + // + // Support multiple BulkIn IRP, + // the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1. + // + for(index=0; indexCommonCfg.NumOfBulkInIRP; index++) + { + RTUSBBulkReceive(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" )); + } +#endif // RTMP_MAC_USB // + }// end of else + + + // Set up the Mac address + RtmpOSNetDevAddrSet(pAd->net_dev, &pAd->CurrentAddress[0]); + + DBGPRINT_S(Status, ("<==== rt28xx_init, Status=%x\n", Status)); + + return TRUE; + + +err4: +err3: + MlmeHalt(pAd); +err2: + RTMPFreeTxRxRingMemory(pAd); +err1: + + os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool + + // shall not set priv to NULL here because the priv didn't been free yet. + //net_dev->ml_priv = 0; +#ifdef ST +err0: +#endif // ST // + + DBGPRINT(RT_DEBUG_ERROR, ("!!! rt28xx Initialized fail !!!\n")); + return FALSE; +} +//---Add by shiang, move from os/linux/rt_main_dev.c + + +static INT RtmpChipOpsRegister( + IN RTMP_ADAPTER *pAd, + IN INT infType) +{ + RTMP_CHIP_OP *pChipOps = &pAd->chipOps; + int status; + + memset(pChipOps, 0, sizeof(RTMP_CHIP_OP)); + + /* set eeprom related hook functions */ + status = RtmpChipOpsEepromHook(pAd, infType); + + /* set mcu related hook functions */ + switch(infType) + { +#ifdef RTMP_PCI_SUPPORT + case RTMP_DEV_INF_PCI: + pChipOps->loadFirmware = RtmpAsicLoadFirmware; + pChipOps->eraseFirmware = RtmpAsicEraseFirmware; + pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu; + break; +#endif // RTMP_PCI_SUPPORT // +#ifdef RTMP_USB_SUPPORT + case RTMP_DEV_INF_USB: + pChipOps->loadFirmware = RtmpAsicLoadFirmware; + pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu; + break; +#endif // RTMP_USB_SUPPORT // + default: + break; + } + + return status; +} + + +INT RtmpRaDevCtrlInit( + IN RTMP_ADAPTER *pAd, + IN RTMP_INF_TYPE infType) +{ + //VOID *handle; + + // Assign the interface type. We need use it when do register/EEPROM access. + pAd->infType = infType; + + + pAd->OpMode = OPMODE_STA; + DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION)); + +#ifdef RTMP_MAC_USB + init_MUTEX(&(pAd->UsbVendorReq_semaphore)); + os_alloc_mem(pAd, (PUCHAR)&pAd->UsbVendorReqBuf, MAX_PARAM_BUFFER_SIZE - 1); + if (pAd->UsbVendorReqBuf == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("Allocate vendor request temp buffer failed!\n")); + return FALSE; + } +#endif // RTMP_MAC_USB // + + RtmpChipOpsRegister(pAd, infType); + + + return 0; +} + + +BOOLEAN RtmpRaDevCtrlExit(IN RTMP_ADAPTER *pAd) +{ + + + RTMPFreeAdapter(pAd); + + return TRUE; +} + + +// not yet support MBSS +PNET_DEV get_netdev_from_bssid( + IN PRTMP_ADAPTER pAd, + IN UCHAR FromWhichBSSID) +{ + PNET_DEV dev_p = NULL; + + { + dev_p = pAd->net_dev; + } + + ASSERT(dev_p); + return dev_p; /* return one of MBSS */ +} Index: b/drivers/staging/rt2860/common/rtmp_mcu.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/rtmp_mcu.c @@ -0,0 +1,233 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rtmp_mcu.c + + Abstract: + Miniport generic portion header file + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + + +#include "../rt_config.h" + +#ifdef RT2860 +#include "firmware.h" +#endif +#ifdef RT2870 +#include "../../rt3070/firmware.h" +#include "firmware_3070.h" +#endif + +#include + +//#define BIN_IN_FILE /* use *.bin firmware */ + +#ifdef RTMP_MAC_USB +// +// RT2870 Firmware Spec only used 1 oct for version expression +// +#define FIRMWARE_MINOR_VERSION 7 +#endif // RTMP_MAC_USB // + +// New 8k byte firmware size for RT3071/RT3072 +#define FIRMWAREIMAGE_MAX_LENGTH 0x2000 +#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR)) +#define FIRMWARE_MAJOR_VERSION 0 + +#define FIRMWAREIMAGEV1_LENGTH 0x1000 +#define FIRMWAREIMAGEV2_LENGTH 0x1000 + +#ifdef RTMP_MAC_PCI +#define FIRMWARE_MINOR_VERSION 2 +#endif // RTMP_MAC_PCI // + +/* + ======================================================================== + + Routine Description: + erase 8051 firmware image in MAC ASIC + + Arguments: + Adapter Pointer to our adapter + + IRQL = PASSIVE_LEVEL + + ======================================================================== +*/ +INT RtmpAsicEraseFirmware( + IN PRTMP_ADAPTER pAd) +{ + ULONG i; + + for(i=0; iMACVersion >> 16); + +// pFirmwareImage = FirmwareImage; +// FileLength = sizeof(FirmwareImage); + + // New 8k byte firmware size for RT3071/RT3072 + { +#ifdef RTMP_MAC_PCI + if ((Version == 0x2860) || (Version == 0x3572) || IS_RT3090(pAd)) + { + pFirmwareImage = FirmwareImage_2860; + FileLength = FIRMWAREIMAGE_MAX_LENGTH; + } +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB + /* the firmware image consists of two parts */ + if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070)) + { /* use the second part */ + //printk("KH:Use New Version,part2\n"); + pFirmwareImage = (PUCHAR)&FirmwareImage_3070[FIRMWAREIMAGEV1_LENGTH]; + FileLength = FIRMWAREIMAGEV2_LENGTH; + } + else + { + //printk("KH:Use New Version,part1\n"); + if (Version == 0x3070) + pFirmwareImage = FirmwareImage_3070; + else + pFirmwareImage = FirmwareImage_2870; + FileLength = FIRMWAREIMAGEV1_LENGTH; + } +#endif // RTMP_MAC_USB // + } + + RTMP_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength); + + + /* check if MCU is ready */ + Index = 0; + do + { + RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg); + + if (MacReg & 0x80) + break; + + RTMPusecDelay(1000); + } while (Index++ < 1000); + + if (Index > 1000) + { + DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n")); + Status = NDIS_STATUS_FAILURE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __func__, Status)); + + return Status; +} + + +INT RtmpAsicSendCommandToMcu( + IN PRTMP_ADAPTER pAd, + IN UCHAR Command, + IN UCHAR Token, + IN UCHAR Arg0, + IN UCHAR Arg1) +{ + HOST_CMD_CSR_STRUC H2MCmd; + H2M_MAILBOX_STRUC H2MMailbox; + ULONG i = 0; +#ifdef RTMP_MAC_PCI +#endif // RTMP_MAC_PCI // + + do + { + RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word); + if (H2MMailbox.field.Owner == 0) + break; + + RTMPusecDelay(2); + } while(i++ < 100); + + if (i > 100) + { +#ifdef RTMP_MAC_PCI +#endif // RTMP_MAC_PCI // + { + DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n")); + } + return FALSE; + } + +#ifdef RTMP_MAC_PCI +#endif // RTMP_MAC_PCI // + + H2MMailbox.field.Owner = 1; // pass ownership to MCU + H2MMailbox.field.CmdToken = Token; + H2MMailbox.field.HighByte = Arg1; + H2MMailbox.field.LowByte = Arg0; + RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word); + + H2MCmd.word = 0; + H2MCmd.field.HostCommand = Command; + RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word); + + if (Command != 0x80) + { + } + + return TRUE; +} Index: b/drivers/staging/rt2860/common/rtmp_timer.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/common/rtmp_timer.c @@ -0,0 +1,323 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rtmp_timer.c + + Abstract: + task for timer handling + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs + Shiang Tu 08-28-2008 init version + +*/ + +#include "../rt_config.h" + + +BUILD_TIMER_FUNCTION(MlmePeriodicExec); +//BUILD_TIMER_FUNCTION(MlmeRssiReportExec); +BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout); +BUILD_TIMER_FUNCTION(APSDPeriodicExec); +BUILD_TIMER_FUNCTION(AsicRfTuningExec); +#ifdef RTMP_MAC_USB +BUILD_TIMER_FUNCTION(BeaconUpdateExec); +#endif // RTMP_MAC_USB // + +BUILD_TIMER_FUNCTION(BeaconTimeout); +BUILD_TIMER_FUNCTION(ScanTimeout); +BUILD_TIMER_FUNCTION(AuthTimeout); +BUILD_TIMER_FUNCTION(AssocTimeout); +BUILD_TIMER_FUNCTION(ReassocTimeout); +BUILD_TIMER_FUNCTION(DisassocTimeout); +BUILD_TIMER_FUNCTION(LinkDownExec); +BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec); +BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc); +#ifdef RTMP_PCI_SUPPORT +BUILD_TIMER_FUNCTION(PsPollWakeExec); +BUILD_TIMER_FUNCTION(RadioOnExec); +#endif // RTMP_PCI_SUPPORT // +#ifdef RTMP_MAC_USB +BUILD_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout); +#endif // RTMP_MAC_USB // + +#if defined(AP_LED) || defined(STA_LED) +extern void LedCtrlMain( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); +BUILD_TIMER_FUNCTION(LedCtrlMain); +#endif + + +#ifdef RTMP_TIMER_TASK_SUPPORT +static void RtmpTimerQHandle(RTMP_ADAPTER *pAd) +{ +#ifndef KTHREAD_SUPPORT + int status; +#endif + RALINK_TIMER_STRUCT *pTimer; + RTMP_TIMER_TASK_ENTRY *pEntry; + unsigned long irqFlag; + RTMP_OS_TASK *pTask; + + + pTask = &pAd->timerTask; + while(!pTask->task_killed) + { + pTimer = NULL; + +#ifdef KTHREAD_SUPPORT + RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); +#else + RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); +#endif + + if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED) + break; + + // event happened. + while(pAd->TimerQ.pQHead) + { + RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag); + pEntry = pAd->TimerQ.pQHead; + if (pEntry) + { + pTimer = pEntry->pRaTimer; + + // update pQHead + pAd->TimerQ.pQHead = pEntry->pNext; + if (pEntry == pAd->TimerQ.pQTail) + pAd->TimerQ.pQTail = NULL; + + // return this queue entry to timerQFreeList. + pEntry->pNext = pAd->TimerQ.pQPollFreeList; + pAd->TimerQ.pQPollFreeList = pEntry; + } + RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag); + + if (pTimer) + { + if ((pTimer->handle != NULL) && (!pAd->PM_FlgSuspend)) + pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer); + if ((pTimer->Repeat) && (pTimer->State == FALSE)) + RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); + } + } + +#ifndef KTHREAD_SUPPORT + if (status != 0) + { + pAd->TimerQ.status = RTMP_TASK_STAT_STOPED; + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + break; + } +#endif + } +} + + +INT RtmpTimerQThread( + IN OUT PVOID Context) +{ + RTMP_OS_TASK *pTask; + PRTMP_ADAPTER pAd; + + + pTask = (RTMP_OS_TASK *)Context; + pAd = (PRTMP_ADAPTER)pTask->priv; + + RtmpOSTaskCustomize(pTask); + + RtmpTimerQHandle(pAd); + + DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__)); +#ifndef KTHREAD_SUPPORT + pTask->taskPID = THREAD_PID_INIT_VALUE; +#endif + /* notify the exit routine that we're actually exiting now + * + * complete()/wait_for_completion() is similar to up()/down(), + * except that complete() is safe in the case where the structure + * is getting deleted in a parallel mode of execution (i.e. just + * after the down() -- that's necessary for the thread-shutdown + * case. + * + * complete_and_exit() goes even further than this -- it is safe in + * the case that the thread of the caller is going away (not just + * the structure) -- this is necessary for the module-remove case. + * This is important in preemption kernels, which transfer the flow + * of execution immediately upon a complete(). + */ + RtmpOSTaskNotifyToExit(pTask); + + return 0; + +} + + +RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert( + IN RTMP_ADAPTER *pAd, + IN RALINK_TIMER_STRUCT *pTimer) +{ + RTMP_TIMER_TASK_ENTRY *pQNode = NULL, *pQTail; + unsigned long irqFlags; + RTMP_OS_TASK *pTask = &pAd->timerTask; + + RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags); + if (pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT) + { + if(pAd->TimerQ.pQPollFreeList) + { + pQNode = pAd->TimerQ.pQPollFreeList; + pAd->TimerQ.pQPollFreeList = pQNode->pNext; + + pQNode->pRaTimer = pTimer; + pQNode->pNext = NULL; + + pQTail = pAd->TimerQ.pQTail; + if (pAd->TimerQ.pQTail != NULL) + pQTail->pNext = pQNode; + pAd->TimerQ.pQTail = pQNode; + if (pAd->TimerQ.pQHead == NULL) + pAd->TimerQ.pQHead = pQNode; + } + } + RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags); + + if (pQNode) + { +#ifdef KTHREAD_SUPPORT + WAKE_UP(pTask); +#else + RTMP_SEM_EVENT_UP(&pTask->taskSema); +#endif + } + + return pQNode; +} + + +BOOLEAN RtmpTimerQRemove( + IN RTMP_ADAPTER *pAd, + IN RALINK_TIMER_STRUCT *pTimer) +{ + RTMP_TIMER_TASK_ENTRY *pNode, *pPrev = NULL; + unsigned long irqFlags; + + RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags); + if (pAd->TimerQ.status >= RTMP_TASK_STAT_INITED) + { + pNode = pAd->TimerQ.pQHead; + while (pNode) + { + if (pNode->pRaTimer == pTimer) + break; + pPrev = pNode; + pNode = pNode->pNext; + } + + // Now move it to freeList queue. + if (pNode) + { + if (pNode == pAd->TimerQ.pQHead) + pAd->TimerQ.pQHead = pNode->pNext; + if (pNode == pAd->TimerQ.pQTail) + pAd->TimerQ.pQTail = pPrev; + if (pPrev != NULL) + pPrev->pNext = pNode->pNext; + + // return this queue entry to timerQFreeList. + pNode->pNext = pAd->TimerQ.pQPollFreeList; + pAd->TimerQ.pQPollFreeList = pNode; + } + } + RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags); + + return TRUE; +} + + +void RtmpTimerQExit(RTMP_ADAPTER *pAd) +{ + RTMP_TIMER_TASK_ENTRY *pTimerQ; + unsigned long irqFlags; + + RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags); + while (pAd->TimerQ.pQHead) + { + pTimerQ = pAd->TimerQ.pQHead; + pAd->TimerQ.pQHead = pTimerQ->pNext; + // remove the timeQ + } + pAd->TimerQ.pQPollFreeList = NULL; + os_free_mem(pAd, pAd->TimerQ.pTimerQPoll); + pAd->TimerQ.pQTail = NULL; + pAd->TimerQ.pQHead = NULL; +#ifndef KTHREAD_SUPPORT + pAd->TimerQ.status = RTMP_TASK_STAT_STOPED; +#endif + RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags); + +} + + +void RtmpTimerQInit(RTMP_ADAPTER *pAd) +{ + int i; + RTMP_TIMER_TASK_ENTRY *pQNode, *pEntry; + unsigned long irqFlags; + + NdisAllocateSpinLock(&pAd->TimerQLock); + + NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ)); + + os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX); + if (pAd->TimerQ.pTimerQPoll) + { + pEntry = NULL; + pQNode = (RTMP_TIMER_TASK_ENTRY *)pAd->TimerQ.pTimerQPoll; + NdisZeroMemory(pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX); + + RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags); + for (i = 0 ;i pNext = pEntry; + pEntry = pQNode; + pQNode++; + } + pAd->TimerQ.pQPollFreeList = pEntry; + pAd->TimerQ.pQHead = NULL; + pAd->TimerQ.pQTail = NULL; + pAd->TimerQ.status = RTMP_TASK_STAT_INITED; + RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags); + } +} +#endif // RTMP_TIMER_TASK_SUPPORT // Index: b/drivers/staging/rt2860/common/rtmp_tkip.c =================================================================== --- a/drivers/staging/rt2860/common/rtmp_tkip.c +++ /dev/null @@ -1,1586 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - - Module Name: - rtmp_tkip.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Paul Wu 02-25-02 Initial -*/ - -#include "../rt_config.h" - -// Rotation functions on 32 bit values -#define ROL32( A, n ) \ - ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) ) -#define ROR32( A, n ) ROL32( (A), 32-(n) ) - -UINT Tkip_Sbox_Lower[256] = -{ - 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54, - 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A, - 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B, - 0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B, - 0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F, - 0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F, - 0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5, - 0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F, - 0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB, - 0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97, - 0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED, - 0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A, - 0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94, - 0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3, - 0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04, - 0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D, - 0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39, - 0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95, - 0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83, - 0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76, - 0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4, - 0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B, - 0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0, - 0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18, - 0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51, - 0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85, - 0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12, - 0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9, - 0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7, - 0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A, - 0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8, - 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A -}; - -UINT Tkip_Sbox_Upper[256] = -{ - 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91, - 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC, - 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB, - 0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B, - 0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83, - 0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A, - 0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F, - 0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA, - 0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B, - 0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13, - 0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6, - 0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85, - 0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11, - 0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B, - 0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1, - 0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF, - 0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E, - 0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6, - 0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B, - 0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD, - 0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8, - 0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2, - 0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49, - 0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10, - 0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97, - 0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F, - 0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C, - 0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27, - 0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33, - 0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5, - 0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0, - 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C -}; - -/*****************************/ -/******** SBOX Table *********/ -/*****************************/ - -UCHAR SboxTable[256] = -{ - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, - 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, - 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, - 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, - 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, - 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, - 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, - 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, - 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, - 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, - 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, - 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 -}; - -VOID xor_32( - IN PUCHAR a, - IN PUCHAR b, - OUT PUCHAR out); - -VOID xor_128( - IN PUCHAR a, - IN PUCHAR b, - OUT PUCHAR out); - -VOID next_key( - IN PUCHAR key, - IN INT round); - -VOID byte_sub( - IN PUCHAR in, - OUT PUCHAR out); - -VOID shift_row( - IN PUCHAR in, - OUT PUCHAR out); - -VOID mix_column( - IN PUCHAR in, - OUT PUCHAR out); - -UCHAR RTMPCkipSbox( - IN UCHAR a); -// -// Expanded IV for TKIP function. -// -typedef struct PACKED _IV_CONTROL_ -{ - union PACKED - { - struct PACKED - { - UCHAR rc0; - UCHAR rc1; - UCHAR rc2; - - union PACKED - { - struct PACKED - { - UCHAR Rsvd:5; - UCHAR ExtIV:1; - UCHAR KeyID:2; - } field; - UCHAR Byte; - } CONTROL; - } field; - - ULONG word; - } IV16; - - ULONG IV32; -} TKIP_IV, *PTKIP_IV; - - -/* - ======================================================================== - - Routine Description: - Convert from UCHAR[] to ULONG in a portable way - - Arguments: - pMICKey pointer to MIC Key - - Return Value: - None - - Note: - - ======================================================================== -*/ -ULONG RTMPTkipGetUInt32( - IN PUCHAR pMICKey) -{ - ULONG res = 0; - INT i; - - for (i = 0; i < 4; i++) - { - res |= (*pMICKey++) << (8 * i); - } - - return res; -} - -/* - ======================================================================== - - Routine Description: - Convert from ULONG to UCHAR[] in a portable way - - Arguments: - pDst pointer to destination for convert ULONG to UCHAR[] - val the value for convert - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -VOID RTMPTkipPutUInt32( - IN OUT PUCHAR pDst, - IN ULONG val) -{ - INT i; - - for(i = 0; i < 4; i++) - { - *pDst++ = (UCHAR) (val & 0xff); - val >>= 8; - } -} - -/* - ======================================================================== - - Routine Description: - Set the MIC Key. - - Arguments: - pAd Pointer to our adapter - pMICKey pointer to MIC Key - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -VOID RTMPTkipSetMICKey( - IN PTKIP_KEY_INFO pTkip, - IN PUCHAR pMICKey) -{ - // Set the key - pTkip->K0 = RTMPTkipGetUInt32(pMICKey); - pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4); - // and reset the message - pTkip->L = pTkip->K0; - pTkip->R = pTkip->K1; - pTkip->nBytesInM = 0; - pTkip->M = 0; -} - -/* - ======================================================================== - - Routine Description: - Calculate the MIC Value. - - Arguments: - pAd Pointer to our adapter - uChar Append this uChar - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -VOID RTMPTkipAppendByte( - IN PTKIP_KEY_INFO pTkip, - IN UCHAR uChar) -{ - // Append the byte to our word-sized buffer - pTkip->M |= (uChar << (8* pTkip->nBytesInM)); - pTkip->nBytesInM++; - // Process the word if it is full. - if( pTkip->nBytesInM >= 4 ) - { - pTkip->L ^= pTkip->M; - pTkip->R ^= ROL32( pTkip->L, 17 ); - pTkip->L += pTkip->R; - pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8); - pTkip->L += pTkip->R; - pTkip->R ^= ROL32( pTkip->L, 3 ); - pTkip->L += pTkip->R; - pTkip->R ^= ROR32( pTkip->L, 2 ); - pTkip->L += pTkip->R; - // Clear the buffer - pTkip->M = 0; - pTkip->nBytesInM = 0; - } -} - -/* - ======================================================================== - - Routine Description: - Calculate the MIC Value. - - Arguments: - pAd Pointer to our adapter - pSrc Pointer to source data for Calculate MIC Value - Len Indicate the length of the source data - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -VOID RTMPTkipAppend( - IN PTKIP_KEY_INFO pTkip, - IN PUCHAR pSrc, - IN UINT nBytes) -{ - // This is simple - while(nBytes > 0) - { - RTMPTkipAppendByte(pTkip, *pSrc++); - nBytes--; - } -} - -/* - ======================================================================== - - Routine Description: - Get the MIC Value. - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - the MIC Value is store in pAd->PrivateInfo.MIC - ======================================================================== -*/ -VOID RTMPTkipGetMIC( - IN PTKIP_KEY_INFO pTkip) -{ - // Append the minimum padding - RTMPTkipAppendByte(pTkip, 0x5a ); - RTMPTkipAppendByte(pTkip, 0 ); - RTMPTkipAppendByte(pTkip, 0 ); - RTMPTkipAppendByte(pTkip, 0 ); - RTMPTkipAppendByte(pTkip, 0 ); - // and then zeroes until the length is a multiple of 4 - while( pTkip->nBytesInM != 0 ) - { - RTMPTkipAppendByte(pTkip, 0 ); - } - // The appendByte function has already computed the result. - RTMPTkipPutUInt32(pTkip->MIC, pTkip->L); - RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R); -} - -/* - ======================================================================== - - Routine Description: - Init Tkip function. - - Arguments: - pAd Pointer to our adapter - pTKey Pointer to the Temporal Key (TK), TK shall be 128bits. - KeyId TK Key ID - pTA Pointer to transmitter address - pMICKey pointer to MIC Key - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -VOID RTMPInitTkipEngine( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pKey, - IN UCHAR KeyId, - IN PUCHAR pTA, - IN PUCHAR pMICKey, - IN PUCHAR pTSC, - OUT PULONG pIV16, - OUT PULONG pIV32) -{ - TKIP_IV tkipIv; - - // Prepare 8 bytes TKIP encapsulation for MPDU - NdisZeroMemory(&tkipIv, sizeof(TKIP_IV)); - tkipIv.IV16.field.rc0 = *(pTSC + 1); - tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f; - tkipIv.IV16.field.rc2 = *pTSC; - tkipIv.IV16.field.CONTROL.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV - tkipIv.IV16.field.CONTROL.field.KeyID = KeyId; - NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); // Copy IV - - *pIV16 = tkipIv.IV16.word; - *pIV32 = tkipIv.IV32; -} - -/* - ======================================================================== - - Routine Description: - Init MIC Value calculation function which include set MIC key & - calculate first 16 bytes (DA + SA + priority + 0) - - Arguments: - pAd Pointer to our adapter - pTKey Pointer to the Temporal Key (TK), TK shall be 128bits. - pDA Pointer to DA address - pSA Pointer to SA address - pMICKey pointer to MIC Key - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID RTMPInitMICEngine( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pKey, - IN PUCHAR pDA, - IN PUCHAR pSA, - IN UCHAR UserPriority, - IN PUCHAR pMICKey) -{ - ULONG Priority = UserPriority; - - // Init MIC value calculation - RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey); - // DA - RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN); - // SA - RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN); - // Priority + 3 bytes of 0 - RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4); -} - -/* - ======================================================================== - - Routine Description: - Compare MIC value of received MSDU - - Arguments: - pAd Pointer to our adapter - pSrc Pointer to the received Plain text data - pDA Pointer to DA address - pSA Pointer to SA address - pMICKey pointer to MIC Key - Len the length of the received plain text data exclude MIC value - - Return Value: - TRUE MIC value matched - FALSE MIC value mismatched - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -BOOLEAN RTMPTkipCompareMICValue( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pSrc, - IN PUCHAR pDA, - IN PUCHAR pSA, - IN PUCHAR pMICKey, - IN UCHAR UserPriority, - IN UINT Len) -{ - UCHAR OldMic[8]; - ULONG Priority = UserPriority; - - // Init MIC value calculation - RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey); - // DA - RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN); - // SA - RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN); - // Priority + 3 bytes of 0 - RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4); - - // Calculate MIC value from plain text data - RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len); - - // Get MIC valude from received frame - NdisMoveMemory(OldMic, pSrc + Len, 8); - - // Get MIC value from decrypted plain data - RTMPTkipGetMIC(&pAd->PrivateInfo.Rx); - - // Move MIC value from MSDU, this steps should move to data path. - // Since the MIC value might cross MPDUs. - if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8)) - { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); //MIC error. - - - return (FALSE); - } - return (TRUE); -} - -/* - ======================================================================== - - Routine Description: - Compare MIC value of received MSDU - - Arguments: - pAd Pointer to our adapter - pLLC LLC header - pSrc Pointer to the received Plain text data - pDA Pointer to DA address - pSA Pointer to SA address - pMICKey pointer to MIC Key - Len the length of the received plain text data exclude MIC value - - Return Value: - TRUE MIC value matched - FALSE MIC value mismatched - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -BOOLEAN RTMPTkipCompareMICValueWithLLC( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pLLC, - IN PUCHAR pSrc, - IN PUCHAR pDA, - IN PUCHAR pSA, - IN PUCHAR pMICKey, - IN UINT Len) -{ - UCHAR OldMic[8]; - ULONG Priority = 0; - - // Init MIC value calculation - RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey); - // DA - RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN); - // SA - RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN); - // Priority + 3 bytes of 0 - RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4); - - // Start with LLC header - RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8); - - // Calculate MIC value from plain text data - RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len); - - // Get MIC valude from received frame - NdisMoveMemory(OldMic, pSrc + Len, 8); - - // Get MIC value from decrypted plain data - RTMPTkipGetMIC(&pAd->PrivateInfo.Rx); - - // Move MIC value from MSDU, this steps should move to data path. - // Since the MIC value might cross MPDUs. - if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8)) - { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n")); //MIC error. - - - return (FALSE); - } - return (TRUE); -} -/* - ======================================================================== - - Routine Description: - Copy frame from waiting queue into relative ring buffer and set - appropriate ASIC register to kick hardware transmit function - - Arguments: - pAd Pointer to our adapter - PNDIS_PACKET Pointer to Ndis Packet for MIC calculation - pEncap Pointer to LLC encap data - LenEncap Total encap length, might be 0 which indicates no encap - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -VOID RTMPCalculateMICValue( - IN PRTMP_ADAPTER pAd, - IN PNDIS_PACKET pPacket, - IN PUCHAR pEncap, - IN PCIPHER_KEY pKey, - IN UCHAR apidx) -{ - PACKET_INFO PacketInfo; - PUCHAR pSrcBufVA; - UINT SrcBufLen; - PUCHAR pSrc; - UCHAR UserPriority; - UCHAR vlan_offset = 0; - - RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); - - UserPriority = RTMP_GET_PACKET_UP(pPacket); - pSrc = pSrcBufVA; - - // determine if this is a vlan packet - if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100) - vlan_offset = 4; - - { - RTMPInitMICEngine( - pAd, - pKey->Key, - pSrc, - pSrc + 6, - UserPriority, - pKey->TxMic); - } - - - if (pEncap != NULL) - { - // LLC encapsulation - RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6); - // Protocol Type - RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2); - } - SrcBufLen -= (14 + vlan_offset); - pSrc += (14 + vlan_offset); - do - { - if (SrcBufLen > 0) - { - RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen); - } - - break; // No need handle next packet - - } while (TRUE); // End of copying payload - - // Compute the final MIC Value - RTMPTkipGetMIC(&pAd->PrivateInfo.Tx); -} - - -/************************************************************/ -/* tkip_sbox() */ -/* Returns a 16 bit value from a 64K entry table. The Table */ -/* is synthesized from two 256 entry byte wide tables. */ -/************************************************************/ - -UINT tkip_sbox(UINT index) -{ - UINT index_low; - UINT index_high; - UINT left, right; - - index_low = (index % 256); - index_high = ((index >> 8) % 256); - - left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256); - right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256); - - return (left ^ right); -} - -UINT rotr1(UINT a) -{ - unsigned int b; - - if ((a & 0x01) == 0x01) - { - b = (a >> 1) | 0x8000; - } - else - { - b = (a >> 1) & 0x7fff; - } - b = b % 65536; - return b; -} - -VOID RTMPTkipMixKey( - UCHAR *key, - UCHAR *ta, - ULONG pnl, /* Least significant 16 bits of PN */ - ULONG pnh, /* Most significant 32 bits of PN */ - UCHAR *rc4key, - UINT *p1k) -{ - - UINT tsc0; - UINT tsc1; - UINT tsc2; - - UINT ppk0; - UINT ppk1; - UINT ppk2; - UINT ppk3; - UINT ppk4; - UINT ppk5; - - INT i; - INT j; - - tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ - tsc1 = (unsigned int)(pnh % 65536); - tsc2 = (unsigned int)(pnl % 65536); /* lsb */ - - /* Phase 1, step 1 */ - p1k[0] = tsc1; - p1k[1] = tsc0; - p1k[2] = (UINT)(ta[0] + (ta[1]*256)); - p1k[3] = (UINT)(ta[2] + (ta[3]*256)); - p1k[4] = (UINT)(ta[4] + (ta[5]*256)); - - /* Phase 1, step 2 */ - for (i=0; i<8; i++) - { - j = 2*(i & 1); - p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536; - p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536; - p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536; - p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536; - p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536; - p1k[4] = (p1k[4] + i) % 65536; - } - - /* Phase 2, Step 1 */ - ppk0 = p1k[0]; - ppk1 = p1k[1]; - ppk2 = p1k[2]; - ppk3 = p1k[3]; - ppk4 = p1k[4]; - ppk5 = (p1k[4] + tsc2) % 65536; - - /* Phase2, Step 2 */ - ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536); - ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536); - ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536); - ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536); - ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536); - ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536); - - ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12])); - ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14])); - ppk2 = ppk2 + rotr1(ppk1); - ppk3 = ppk3 + rotr1(ppk2); - ppk4 = ppk4 + rotr1(ppk3); - ppk5 = ppk5 + rotr1(ppk4); - - /* Phase 2, Step 3 */ - /* Phase 2, Step 3 */ - - tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ - tsc1 = (unsigned int)(pnh % 65536); - tsc2 = (unsigned int)(pnl % 65536); /* lsb */ - - rc4key[0] = (tsc2 >> 8) % 256; - rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f; - rc4key[2] = tsc2 % 256; - rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256; - - rc4key[4] = ppk0 % 256; - rc4key[5] = (ppk0 >> 8) % 256; - - rc4key[6] = ppk1 % 256; - rc4key[7] = (ppk1 >> 8) % 256; - - rc4key[8] = ppk2 % 256; - rc4key[9] = (ppk2 >> 8) % 256; - - rc4key[10] = ppk3 % 256; - rc4key[11] = (ppk3 >> 8) % 256; - - rc4key[12] = ppk4 % 256; - rc4key[13] = (ppk4 >> 8) % 256; - - rc4key[14] = ppk5 % 256; - rc4key[15] = (ppk5 >> 8) % 256; -} - - -/************************************************/ -/* construct_mic_header1() */ -/* Builds the first MIC header block from */ -/* header fields. */ -/************************************************/ - -void construct_mic_header1( - unsigned char *mic_header1, - int header_length, - unsigned char *mpdu) -{ - mic_header1[0] = (unsigned char)((header_length - 2) / 256); - mic_header1[1] = (unsigned char)((header_length - 2) % 256); - mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */ - mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */ - mic_header1[4] = mpdu[4]; /* A1 */ - mic_header1[5] = mpdu[5]; - mic_header1[6] = mpdu[6]; - mic_header1[7] = mpdu[7]; - mic_header1[8] = mpdu[8]; - mic_header1[9] = mpdu[9]; - mic_header1[10] = mpdu[10]; /* A2 */ - mic_header1[11] = mpdu[11]; - mic_header1[12] = mpdu[12]; - mic_header1[13] = mpdu[13]; - mic_header1[14] = mpdu[14]; - mic_header1[15] = mpdu[15]; -} - -/************************************************/ -/* construct_mic_header2() */ -/* Builds the last MIC header block from */ -/* header fields. */ -/************************************************/ - -void construct_mic_header2( - unsigned char *mic_header2, - unsigned char *mpdu, - int a4_exists, - int qc_exists) -{ - int i; - - for (i = 0; i<16; i++) mic_header2[i]=0x00; - - mic_header2[0] = mpdu[16]; /* A3 */ - mic_header2[1] = mpdu[17]; - mic_header2[2] = mpdu[18]; - mic_header2[3] = mpdu[19]; - mic_header2[4] = mpdu[20]; - mic_header2[5] = mpdu[21]; - - // In Sequence Control field, mute sequence numer bits (12-bit) - mic_header2[6] = mpdu[22] & 0x0f; /* SC */ - mic_header2[7] = 0x00; /* mpdu[23]; */ - - if ((!qc_exists) & a4_exists) - { - for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */ - - } - - if (qc_exists && (!a4_exists)) - { - mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */ - mic_header2[9] = mpdu[25] & 0x00; - } - - if (qc_exists && a4_exists) - { - for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */ - - mic_header2[14] = mpdu[30] & 0x0f; - mic_header2[15] = mpdu[31] & 0x00; - } -} - - -/************************************************/ -/* construct_mic_iv() */ -/* Builds the MIC IV from header fields and PN */ -/************************************************/ - -void construct_mic_iv( - unsigned char *mic_iv, - int qc_exists, - int a4_exists, - unsigned char *mpdu, - unsigned int payload_length, - unsigned char *pn_vector) -{ - int i; - - mic_iv[0] = 0x59; - if (qc_exists && a4_exists) - mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */ - if (qc_exists && !a4_exists) - mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */ - if (!qc_exists) - mic_iv[1] = 0x00; - for (i = 2; i < 8; i++) - mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */ -#ifdef CONSISTENT_PN_ORDER - for (i = 8; i < 14; i++) - mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */ -#else - for (i = 8; i < 14; i++) - mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */ -#endif - i = (payload_length / 256); - i = (payload_length % 256); - mic_iv[14] = (unsigned char) (payload_length / 256); - mic_iv[15] = (unsigned char) (payload_length % 256); - -} - - - -/************************************/ -/* bitwise_xor() */ -/* A 128 bit, bitwise exclusive or */ -/************************************/ - -void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out) -{ - int i; - for (i=0; i<16; i++) - { - out[i] = ina[i] ^ inb[i]; - } -} - - -void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext) -{ - int round; - int i; - unsigned char intermediatea[16]; - unsigned char intermediateb[16]; - unsigned char round_key[16]; - - for(i=0; i<16; i++) round_key[i] = key[i]; - - for (round = 0; round < 11; round++) - { - if (round == 0) - { - xor_128(round_key, data, ciphertext); - next_key(round_key, round); - } - else if (round == 10) - { - byte_sub(ciphertext, intermediatea); - shift_row(intermediatea, intermediateb); - xor_128(intermediateb, round_key, ciphertext); - } - else /* 1 - 9 */ - { - byte_sub(ciphertext, intermediatea); - shift_row(intermediatea, intermediateb); - mix_column(&intermediateb[0], &intermediatea[0]); - mix_column(&intermediateb[4], &intermediatea[4]); - mix_column(&intermediateb[8], &intermediatea[8]); - mix_column(&intermediateb[12], &intermediatea[12]); - xor_128(intermediatea, round_key, ciphertext); - next_key(round_key, round); - } - } - -} - -void construct_ctr_preload( - unsigned char *ctr_preload, - int a4_exists, - int qc_exists, - unsigned char *mpdu, - unsigned char *pn_vector, - int c) -{ - - int i = 0; - for (i=0; i<16; i++) ctr_preload[i] = 0x00; - i = 0; - - ctr_preload[0] = 0x01; /* flag */ - if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */ - if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f; - - for (i = 2; i < 8; i++) - ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */ -#ifdef CONSISTENT_PN_ORDER - for (i = 8; i < 14; i++) - ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */ -#else - for (i = 8; i < 14; i++) - ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */ -#endif - ctr_preload[14] = (unsigned char) (c / 256); // Ctr - ctr_preload[15] = (unsigned char) (c % 256); - -} - - -// -// TRUE: Success! -// FALSE: Decrypt Error! -// -BOOLEAN RTMPSoftDecryptTKIP( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pData, - IN ULONG DataByteCnt, - IN UCHAR UserPriority, - IN PCIPHER_KEY pWpaKey) -{ - UCHAR KeyID; - UINT HeaderLen; - UCHAR fc0; - UCHAR fc1; - USHORT fc; - UINT frame_type; - UINT frame_subtype; - UINT from_ds; - UINT to_ds; - INT a4_exists; - INT qc_exists; - USHORT duration; - USHORT seq_control; - USHORT qos_control; - UCHAR TA[MAC_ADDR_LEN]; - UCHAR DA[MAC_ADDR_LEN]; - UCHAR SA[MAC_ADDR_LEN]; - UCHAR RC4Key[16]; - UINT p1k[5]; //for mix_key; - ULONG pnl;/* Least significant 16 bits of PN */ - ULONG pnh;/* Most significant 32 bits of PN */ - UINT num_blocks; - UINT payload_remainder; - ARCFOURCONTEXT ArcFourContext; - UINT crc32 = 0; - UINT trailfcs = 0; - UCHAR MIC[8]; - UCHAR TrailMIC[8]; - - fc0 = *pData; - fc1 = *(pData + 1); - - fc = *((PUSHORT)pData); - - frame_type = ((fc0 >> 2) & 0x03); - frame_subtype = ((fc0 >> 4) & 0x0f); - - from_ds = (fc1 & 0x2) >> 1; - to_ds = (fc1 & 0x1); - - a4_exists = (from_ds & to_ds); - qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */ - (frame_subtype == 0x09) || /* Likely to change. */ - (frame_subtype == 0x0a) || - (frame_subtype == 0x0b) - ); - - HeaderLen = 24; - if (a4_exists) - HeaderLen += 6; - - KeyID = *((PUCHAR)(pData+ HeaderLen + 3)); - KeyID = KeyID >> 6; - - if (pWpaKey[KeyID].KeyLen == 0) - { - DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", KeyID)); - return FALSE; - } - - duration = *((PUSHORT)(pData+2)); - - seq_control = *((PUSHORT)(pData+22)); - - if (qc_exists) - { - if (a4_exists) - { - qos_control = *((PUSHORT)(pData+30)); - } - else - { - qos_control = *((PUSHORT)(pData+24)); - } - } - - if (to_ds == 0 && from_ds == 1) - { - NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN); - NdisMoveMemory(SA, pData+16, MAC_ADDR_LEN); - NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); //BSSID - } - else if (to_ds == 0 && from_ds == 0 ) - { - NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); - NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN); - NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN); - } - else if (to_ds == 1 && from_ds == 0) - { - NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN); - NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); - NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN); - } - else if (to_ds == 1 && from_ds == 1) - { - NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); - NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN); - NdisMoveMemory(SA, pData+22, MAC_ADDR_LEN); - } - - num_blocks = (DataByteCnt - 16) / 16; - payload_remainder = (DataByteCnt - 16) % 16; - - pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2); - pnh = *((PULONG)(pData + HeaderLen + 4)); - pnh = cpu2le32(pnh); - RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k); - - ARCFOUR_INIT(&ArcFourContext, RC4Key, 16); - - ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8); - NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4); - crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4); //Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS). - crc32 ^= 0xffffffff; /* complement */ - - if(crc32 != cpu2le32(trailfcs)) - { - DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n")); //ICV error. - - return (FALSE); - } - - NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8); - RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, pWpaKey[KeyID].RxMic); - RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 12); - RTMPTkipGetMIC(&pAd->PrivateInfo.Tx); - NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8); - - if (!NdisEqualMemory(MIC, TrailMIC, 8)) - { - DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); //MIC error. - return (FALSE); - } - - return TRUE; -} - - - - -BOOLEAN RTMPSoftDecryptAES( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pData, - IN ULONG DataByteCnt, - IN PCIPHER_KEY pWpaKey) -{ - UCHAR KeyID; - UINT HeaderLen; - UCHAR PN[6]; - UINT payload_len; - UINT num_blocks; - UINT payload_remainder; - USHORT fc; - UCHAR fc0; - UCHAR fc1; - UINT frame_type; - UINT frame_subtype; - UINT from_ds; - UINT to_ds; - INT a4_exists; - INT qc_exists; - UCHAR aes_out[16]; - int payload_index; - UINT i; - UCHAR ctr_preload[16]; - UCHAR chain_buffer[16]; - UCHAR padded_buffer[16]; - UCHAR mic_iv[16]; - UCHAR mic_header1[16]; - UCHAR mic_header2[16]; - UCHAR MIC[8]; - UCHAR TrailMIC[8]; - - fc0 = *pData; - fc1 = *(pData + 1); - - fc = *((PUSHORT)pData); - - frame_type = ((fc0 >> 2) & 0x03); - frame_subtype = ((fc0 >> 4) & 0x0f); - - from_ds = (fc1 & 0x2) >> 1; - to_ds = (fc1 & 0x1); - - a4_exists = (from_ds & to_ds); - qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */ - (frame_subtype == 0x09) || /* Likely to change. */ - (frame_subtype == 0x0a) || - (frame_subtype == 0x0b) - ); - - HeaderLen = 24; - if (a4_exists) - HeaderLen += 6; - - KeyID = *((PUCHAR)(pData+ HeaderLen + 3)); - KeyID = KeyID >> 6; - - if (pWpaKey[KeyID].KeyLen == 0) - { - DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID)); - return FALSE; - } - - PN[0] = *(pData+ HeaderLen); - PN[1] = *(pData+ HeaderLen + 1); - PN[2] = *(pData+ HeaderLen + 4); - PN[3] = *(pData+ HeaderLen + 5); - PN[4] = *(pData+ HeaderLen + 6); - PN[5] = *(pData+ HeaderLen + 7); - - payload_len = DataByteCnt - HeaderLen - 8 - 8; // 8 bytes for CCMP header , 8 bytes for MIC - payload_remainder = (payload_len) % 16; - num_blocks = (payload_len) / 16; - - - - // Find start of payload - payload_index = HeaderLen + 8; //IV+EIV - - for (i=0; i< num_blocks; i++) - { - construct_ctr_preload(ctr_preload, - a4_exists, - qc_exists, - pData, - PN, - i+1 ); - - aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out); - - bitwise_xor(aes_out, pData + payload_index, chain_buffer); - NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16); - payload_index += 16; - } - - // - // If there is a short final block, then pad it - // encrypt it and copy the unpadded part back - // - if (payload_remainder > 0) - { - construct_ctr_preload(ctr_preload, - a4_exists, - qc_exists, - pData, - PN, - num_blocks + 1); - - NdisZeroMemory(padded_buffer, 16); - NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder); - - aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out); - - bitwise_xor(aes_out, padded_buffer, chain_buffer); - NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder); - payload_index += payload_remainder; - } - - // - // Descrypt the MIC - // - construct_ctr_preload(ctr_preload, - a4_exists, - qc_exists, - pData, - PN, - 0); - NdisZeroMemory(padded_buffer, 16); - NdisMoveMemory(padded_buffer, pData + payload_index, 8); - - aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out); - - bitwise_xor(aes_out, padded_buffer, chain_buffer); - - NdisMoveMemory(TrailMIC, chain_buffer, 8); - - // - // Calculate MIC - // - - //Force the protected frame bit on - *(pData + 1) = *(pData + 1) | 0x40; - - // Find start of payload - // Because the CCMP header has been removed - payload_index = HeaderLen; - - construct_mic_iv( - mic_iv, - qc_exists, - a4_exists, - pData, - payload_len, - PN); - - construct_mic_header1( - mic_header1, - HeaderLen, - pData); - - construct_mic_header2( - mic_header2, - pData, - a4_exists, - qc_exists); - - aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out); - bitwise_xor(aes_out, mic_header1, chain_buffer); - aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out); - bitwise_xor(aes_out, mic_header2, chain_buffer); - aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out); - - // iterate through each 16 byte payload block - for (i = 0; i < num_blocks; i++) - { - bitwise_xor(aes_out, pData + payload_index, chain_buffer); - payload_index += 16; - aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out); - } - - // Add on the final payload block if it needs padding - if (payload_remainder > 0) - { - NdisZeroMemory(padded_buffer, 16); - NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder); - - bitwise_xor(aes_out, padded_buffer, chain_buffer); - aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out); - } - // aes_out contains padded mic, discard most significant - // 8 bytes to generate 64 bit MIC - for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i]; - - if (!NdisEqualMemory(MIC, TrailMIC, 8)) - { - DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); //MIC error. - return FALSE; - } - - return TRUE; -} - -/****************************************/ -/* aes128k128d() */ -/* Performs a 128 bit AES encrypt with */ -/* 128 bit data. */ -/****************************************/ -VOID xor_128( - IN PUCHAR a, - IN PUCHAR b, - OUT PUCHAR out) -{ - INT i; - - for (i=0;i<16; i++) - { - out[i] = a[i] ^ b[i]; - } -} - -VOID next_key( - IN PUCHAR key, - IN INT round) -{ - UCHAR rcon; - UCHAR sbox_key[4]; - UCHAR rcon_table[12] = - { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - 0x1b, 0x36, 0x36, 0x36 - }; - - sbox_key[0] = RTMPCkipSbox(key[13]); - sbox_key[1] = RTMPCkipSbox(key[14]); - sbox_key[2] = RTMPCkipSbox(key[15]); - sbox_key[3] = RTMPCkipSbox(key[12]); - - rcon = rcon_table[round]; - - xor_32(&key[0], sbox_key, &key[0]); - key[0] = key[0] ^ rcon; - - xor_32(&key[4], &key[0], &key[4]); - xor_32(&key[8], &key[4], &key[8]); - xor_32(&key[12], &key[8], &key[12]); -} - -VOID xor_32( - IN PUCHAR a, - IN PUCHAR b, - OUT PUCHAR out) -{ - INT i; - - for (i=0;i<4; i++) - { - out[i] = a[i] ^ b[i]; - } -} - -VOID byte_sub( - IN PUCHAR in, - OUT PUCHAR out) -{ - INT i; - - for (i=0; i< 16; i++) - { - out[i] = RTMPCkipSbox(in[i]); - } -} - -UCHAR RTMPCkipSbox( - IN UCHAR a) -{ - return SboxTable[(int)a]; -} - -VOID shift_row( - IN PUCHAR in, - OUT PUCHAR out) -{ - out[0] = in[0]; - out[1] = in[5]; - out[2] = in[10]; - out[3] = in[15]; - out[4] = in[4]; - out[5] = in[9]; - out[6] = in[14]; - out[7] = in[3]; - out[8] = in[8]; - out[9] = in[13]; - out[10] = in[2]; - out[11] = in[7]; - out[12] = in[12]; - out[13] = in[1]; - out[14] = in[6]; - out[15] = in[11]; -} - -VOID mix_column( - IN PUCHAR in, - OUT PUCHAR out) -{ - INT i; - UCHAR add1b[4]; - UCHAR add1bf7[4]; - UCHAR rotl[4]; - UCHAR swap_halfs[4]; - UCHAR andf7[4]; - UCHAR rotr[4]; - UCHAR temp[4]; - UCHAR tempb[4]; - - for (i=0 ; i<4; i++) - { - if ((in[i] & 0x80)== 0x80) - add1b[i] = 0x1b; - else - add1b[i] = 0x00; - } - - swap_halfs[0] = in[2]; /* Swap halfs */ - swap_halfs[1] = in[3]; - swap_halfs[2] = in[0]; - swap_halfs[3] = in[1]; - - rotl[0] = in[3]; /* Rotate left 8 bits */ - rotl[1] = in[0]; - rotl[2] = in[1]; - rotl[3] = in[2]; - - andf7[0] = in[0] & 0x7f; - andf7[1] = in[1] & 0x7f; - andf7[2] = in[2] & 0x7f; - andf7[3] = in[3] & 0x7f; - - for (i = 3; i>0; i--) /* logical shift left 1 bit */ - { - andf7[i] = andf7[i] << 1; - if ((andf7[i-1] & 0x80) == 0x80) - { - andf7[i] = (andf7[i] | 0x01); - } - } - andf7[0] = andf7[0] << 1; - andf7[0] = andf7[0] & 0xfe; - - xor_32(add1b, andf7, add1bf7); - - xor_32(in, add1bf7, rotr); - - temp[0] = rotr[0]; /* Rotate right 8 bits */ - rotr[0] = rotr[1]; - rotr[1] = rotr[2]; - rotr[2] = rotr[3]; - rotr[3] = temp[0]; - - xor_32(add1bf7, rotr, temp); - xor_32(swap_halfs, rotl,tempb); - xor_32(temp, tempb, out); -} - Index: b/drivers/staging/rt2860/common/rtmp_wep.c =================================================================== --- a/drivers/staging/rt2860/common/rtmp_wep.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - - Module Name: - rtmp_wep.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Paul Wu 10-28-02 Initial -*/ - -#include "../rt_config.h" - -UINT FCSTAB_32[256] = -{ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -/* - ======================================================================== - - Routine Description: - Init WEP function. - - Arguments: - pAd Pointer to our adapter - pKey Pointer to the WEP KEY - KeyId WEP Key ID - KeyLen the length of WEP KEY - pDest Pointer to the destination which Encryption data will store in. - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -VOID RTMPInitWepEngine( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pKey, - IN UCHAR KeyId, - IN UCHAR KeyLen, - IN OUT PUCHAR pDest) -{ - UINT i; - UCHAR WEPKEY[] = { - //IV - 0x00, 0x11, 0x22, - //WEP KEY - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC - }; - - pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32. - - if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10) && (pAd->OpMode == OPMODE_STA)) - { - ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, pKey, KeyLen); //INIT SBOX, KEYLEN+3(IV) - NdisMoveMemory(pDest, pKey, 3); //Append Init Vector - } - else - { - NdisMoveMemory(WEPKEY + 3, pKey, KeyLen); - - for(i = 0; i < 3; i++) - WEPKEY[i] = RandomByte(pAd); //Call mlme RandomByte() function. - ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3); //INIT SBOX, KEYLEN+3(IV) - - NdisMoveMemory(pDest, WEPKEY, 3); //Append Init Vector - } - *(pDest+3) = (KeyId << 6); //Append KEYID - -} - -/* - ======================================================================== - - Routine Description: - Encrypt transimitted data - - Arguments: - pAd Pointer to our adapter - pSrc Pointer to the transimitted source data that will be encrypt - pDest Pointer to the destination where entryption data will be store in. - Len Indicate the length of the source data - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -VOID RTMPEncryptData( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pSrc, - IN PUCHAR pDest, - IN UINT Len) -{ - pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len); - ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len); -} - - -/* - ======================================================================== - - Routine Description: - Decrypt received WEP data - - Arguments: - pAdapter Pointer to our adapter - pSrc Pointer to the received data - Len the length of the received data - - Return Value: - TRUE Decrypt WEP data success - FALSE Decrypt WEP data failed - - Note: - - ======================================================================== -*/ -BOOLEAN RTMPSoftDecryptWEP( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pData, - IN ULONG DataByteCnt, - IN PCIPHER_KEY pGroupKey) -{ - UINT trailfcs; - UINT crc32; - UCHAR KeyIdx; - UCHAR WEPKEY[] = { - //IV - 0x00, 0x11, 0x22, - //WEP KEY - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC - }; - UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11; - ULONG payload_len = DataByteCnt - LENGTH_802_11; - - NdisMoveMemory(WEPKEY, pPayload, 3); //Get WEP IV - - KeyIdx = (*(pPayload + 3) & 0xc0) >> 6; - if (pGroupKey[KeyIdx].KeyLen == 0) - return (FALSE); - - NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen); - ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3); - ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4); - NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4); - crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8); //Skip last 4 bytes(FCS). - crc32 ^= 0xffffffff; /* complement */ - - if(crc32 != cpu2le32(trailfcs)) - { - DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n")); //CRC error. - return (FALSE); - } - return (TRUE); -} - -/* - ======================================================================== - - Routine Description: - The Stream Cipher Encryption Algorithm "ARCFOUR" initialize - - Arguments: - Ctx Pointer to ARCFOUR CONTEXT (SBOX) - pKey Pointer to the WEP KEY - KeyLen Indicate the length fo the WEP KEY - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -VOID ARCFOUR_INIT( - IN PARCFOURCONTEXT Ctx, - IN PUCHAR pKey, - IN UINT KeyLen) -{ - UCHAR t, u; - UINT keyindex; - UINT stateindex; - PUCHAR state; - UINT counter; - - state = Ctx->STATE; - Ctx->X = 0; - Ctx->Y = 0; - for (counter = 0; counter < 256; counter++) - state[counter] = (UCHAR)counter; - keyindex = 0; - stateindex = 0; - for (counter = 0; counter < 256; counter++) - { - t = state[counter]; - stateindex = (stateindex + pKey[keyindex] + t) & 0xff; - u = state[stateindex]; - state[stateindex] = t; - state[counter] = u; - if (++keyindex >= KeyLen) - keyindex = 0; - } -} - -/* - ======================================================================== - - Routine Description: - Get bytes from ARCFOUR CONTEXT (S-BOX) - - Arguments: - Ctx Pointer to ARCFOUR CONTEXT (SBOX) - - Return Value: - UCHAR - the value of the ARCFOUR CONTEXT (S-BOX) - - Note: - - ======================================================================== -*/ -UCHAR ARCFOUR_BYTE( - IN PARCFOURCONTEXT Ctx) -{ - UINT x; - UINT y; - UCHAR sx, sy; - PUCHAR state; - - state = Ctx->STATE; - x = (Ctx->X + 1) & 0xff; - sx = state[x]; - y = (sx + Ctx->Y) & 0xff; - sy = state[y]; - Ctx->X = x; - Ctx->Y = y; - state[y] = sx; - state[x] = sy; - - return(state[(sx + sy) & 0xff]); - -} - -/* - ======================================================================== - - Routine Description: - The Stream Cipher Decryption Algorithm - - Arguments: - Ctx Pointer to ARCFOUR CONTEXT (SBOX) - pDest Pointer to the Destination - pSrc Pointer to the Source data - Len Indicate the length of the Source data - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID ARCFOUR_DECRYPT( - IN PARCFOURCONTEXT Ctx, - IN PUCHAR pDest, - IN PUCHAR pSrc, - IN UINT Len) -{ - UINT i; - - for (i = 0; i < Len; i++) - pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx); -} - -/* - ======================================================================== - - Routine Description: - The Stream Cipher Encryption Algorithm - - Arguments: - Ctx Pointer to ARCFOUR CONTEXT (SBOX) - pDest Pointer to the Destination - pSrc Pointer to the Source data - Len Indicate the length of the Source dta - - Return Value: - None - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -VOID ARCFOUR_ENCRYPT( - IN PARCFOURCONTEXT Ctx, - IN PUCHAR pDest, - IN PUCHAR pSrc, - IN UINT Len) -{ - UINT i; - - for (i = 0; i < Len; i++) - pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx); -} - -/* - ======================================================================== - - Routine Description: - The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt GTK. - - Arguments: - Ctx Pointer to ARCFOUR CONTEXT (SBOX) - pDest Pointer to the Destination - pSrc Pointer to the Source data - Len Indicate the length of the Source dta - - - ======================================================================== -*/ - -VOID WPAARCFOUR_ENCRYPT( - IN PARCFOURCONTEXT Ctx, - IN PUCHAR pDest, - IN PUCHAR pSrc, - IN UINT Len) -{ - UINT i; - //discard first 256 bytes - for (i = 0; i < 256; i++) - ARCFOUR_BYTE(Ctx); - - for (i = 0; i < Len; i++) - pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx); -} - - -/* - ======================================================================== - - Routine Description: - Calculate a new FCS given the current FCS and the new data. - - Arguments: - Fcs the original FCS value - Cp pointer to the data which will be calculate the FCS - Len the length of the data - - Return Value: - UINT - FCS 32 bits - - IRQL = DISPATCH_LEVEL - - Note: - - ======================================================================== -*/ -UINT RTMP_CALC_FCS32( - IN UINT Fcs, - IN PUCHAR Cp, - IN INT Len) -{ - while (Len--) - Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]); - - return (Fcs); -} - - -/* - ======================================================================== - - Routine Description: - Get last FCS and encrypt it to the destination - - Arguments: - pDest Pointer to the Destination - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID RTMPSetICV( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pDest) -{ - pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff; /* complement */ - pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32); - - ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4); -} - Index: b/drivers/staging/rt2860/common/spectrum.c =================================================================== --- a/drivers/staging/rt2860/common/spectrum.c +++ b/drivers/staging/rt2860/common/spectrum.c @@ -40,6 +40,239 @@ #include "../rt_config.h" #include "action.h" + +/* The regulatory information in the USA (US) */ +DOT11_REGULATORY_INFORMATION USARegulatoryInfo[] = +{ +/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ + {0, {0, 0, {0}}}, // Invlid entry + {1, {4, 16, {36, 40, 44, 48}}}, + {2, {4, 23, {52, 56, 60, 64}}}, + {3, {4, 29, {149, 153, 157, 161}}}, + {4, {11, 23, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}}, + {5, {5, 30, {149, 153, 157, 161, 165}}}, + {6, {10, 14, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}}, + {7, {10, 27, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}}, + {8, {5, 17, {11, 13, 15, 17, 19}}}, + {9, {5, 30, {11, 13, 15, 17, 19}}}, + {10, {2, 20, {21, 25}}}, + {11, {2, 33, {21, 25}}}, + {12, {11, 30, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}} +}; +#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION)) + + +/* The regulatory information in Europe */ +DOT11_REGULATORY_INFORMATION EuropeRegulatoryInfo[] = +{ +/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ + {0, {0, 0, {0}}}, // Invalid entry + {1, {4, 20, {36, 40, 44, 48}}}, + {2, {4, 20, {52, 56, 60, 64}}}, + {3, {11, 30, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}}}, + {4, {13, 20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}} +}; +#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION)) + + +/* The regulatory information in Japan */ +DOT11_REGULATORY_INFORMATION JapanRegulatoryInfo[] = +{ +/* "regulatory class" "number of channels" "Max Tx Pwr" "channel list" */ + {0, {0, 0, {0}}}, // Invalid entry + {1, {4, 22, {34, 38, 42, 46}}}, + {2, {3, 24, {8, 12, 16}}}, + {3, {3, 24, {8, 12, 16}}}, + {4, {3, 24, {8, 12, 16}}}, + {5, {3, 24, {8, 12, 16}}}, + {6, {3, 22, {8, 12, 16}}}, + {7, {4, 24, {184, 188, 192, 196}}}, + {8, {4, 24, {184, 188, 192, 196}}}, + {9, {4, 24, {184, 188, 192, 196}}}, + {10, {4, 24, {184, 188, 192, 196}}}, + {11, {4, 22, {184, 188, 192, 196}}}, + {12, {4, 24, {7, 8, 9, 11}}}, + {13, {4, 24, {7, 8, 9, 11}}}, + {14, {4, 24, {7, 8, 9, 11}}}, + {15, {4, 24, {7, 8, 9, 11}}}, + {16, {6, 24, {183, 184, 185, 187, 188, 189}}}, + {17, {6, 24, {183, 184, 185, 187, 188, 189}}}, + {18, {6, 24, {183, 184, 185, 187, 188, 189}}}, + {19, {6, 24, {183, 184, 185, 187, 188, 189}}}, + {20, {6, 17, {183, 184, 185, 187, 188, 189}}}, + {21, {6, 24, {6, 7, 8, 9, 10, 11}}}, + {22, {6, 24, {6, 7, 8, 9, 10, 11}}}, + {23, {6, 24, {6, 7, 8, 9, 10, 11}}}, + {24, {6, 24, {6, 7, 8, 9, 10, 11}}}, + {25, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, + {26, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, + {27, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, + {28, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}}}, + {29, {8, 17, {182, 183, 184, 185, 186, 187, 188, 189}}}, + {30, {13, 23, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}}, + {31, {1, 23, {14}}}, + {32, {4, 22, {52, 56, 60, 64}}} +}; +#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(DOT11_REGULATORY_INFORMATION)) + + +CHAR RTMP_GetTxPwr( + IN PRTMP_ADAPTER pAd, + IN HTTRANSMIT_SETTING HTTxMode) +{ +typedef struct __TX_PWR_CFG +{ + UINT8 Mode; + UINT8 MCS; + UINT16 req; + UINT8 shift; + UINT32 BitMask; +} TX_PWR_CFG; + + UINT32 Value; + INT Idx; + UINT8 PhyMode; + CHAR CurTxPwr; + UINT8 TxPwrRef = 0; + CHAR DaltaPwr; + ULONG TxPwr[5]; + + + TX_PWR_CFG TxPwrCfg[] = { + {MODE_CCK, 0, 0, 4, 0x000000f0}, + {MODE_CCK, 1, 0, 0, 0x0000000f}, + {MODE_CCK, 2, 0, 12, 0x0000f000}, + {MODE_CCK, 3, 0, 8, 0x00000f00}, + + {MODE_OFDM, 0, 0, 20, 0x00f00000}, + {MODE_OFDM, 1, 0, 16, 0x000f0000}, + {MODE_OFDM, 2, 0, 28, 0xf0000000}, + {MODE_OFDM, 3, 0, 24, 0x0f000000}, + {MODE_OFDM, 4, 1, 4, 0x000000f0}, + {MODE_OFDM, 5, 1, 0, 0x0000000f}, + {MODE_OFDM, 6, 1, 12, 0x0000f000}, + {MODE_OFDM, 7, 1, 8, 0x00000f00} + ,{MODE_HTMIX, 0, 1, 20, 0x00f00000}, + {MODE_HTMIX, 1, 1, 16, 0x000f0000}, + {MODE_HTMIX, 2, 1, 28, 0xf0000000}, + {MODE_HTMIX, 3, 1, 24, 0x0f000000}, + {MODE_HTMIX, 4, 2, 4, 0x000000f0}, + {MODE_HTMIX, 5, 2, 0, 0x0000000f}, + {MODE_HTMIX, 6, 2, 12, 0x0000f000}, + {MODE_HTMIX, 7, 2, 8, 0x00000f00}, + {MODE_HTMIX, 8, 2, 20, 0x00f00000}, + {MODE_HTMIX, 9, 2, 16, 0x000f0000}, + {MODE_HTMIX, 10, 2, 28, 0xf0000000}, + {MODE_HTMIX, 11, 2, 24, 0x0f000000}, + {MODE_HTMIX, 12, 3, 4, 0x000000f0}, + {MODE_HTMIX, 13, 3, 0, 0x0000000f}, + {MODE_HTMIX, 14, 3, 12, 0x0000f000}, + {MODE_HTMIX, 15, 3, 8, 0x00000f00} + }; +#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(TX_PWR_CFG)) + + CurTxPwr = 19; + + /* check Tx Power setting from UI. */ + if (pAd->CommonCfg.TxPowerPercentage > 90) + ; + else if (pAd->CommonCfg.TxPowerPercentage > 60) /* reduce Pwr for 1 dB. */ + CurTxPwr -= 1; + else if (pAd->CommonCfg.TxPowerPercentage > 30) /* reduce Pwr for 3 dB. */ + CurTxPwr -= 3; + else if (pAd->CommonCfg.TxPowerPercentage > 15) /* reduce Pwr for 6 dB. */ + CurTxPwr -= 6; + else if (pAd->CommonCfg.TxPowerPercentage > 9) /* reduce Pwr for 9 dB. */ + CurTxPwr -= 9; + else /* reduce Pwr for 12 dB. */ + CurTxPwr -= 12; + + if (pAd->CommonCfg.BBPCurrentBW == BW_40) + { + if (pAd->CommonCfg.CentralChannel > 14) + { + TxPwr[0] = pAd->Tx40MPwrCfgABand[0]; + TxPwr[1] = pAd->Tx40MPwrCfgABand[1]; + TxPwr[2] = pAd->Tx40MPwrCfgABand[2]; + TxPwr[3] = pAd->Tx40MPwrCfgABand[3]; + TxPwr[4] = pAd->Tx40MPwrCfgABand[4]; + } + else + { + TxPwr[0] = pAd->Tx40MPwrCfgGBand[0]; + TxPwr[1] = pAd->Tx40MPwrCfgGBand[1]; + TxPwr[2] = pAd->Tx40MPwrCfgGBand[2]; + TxPwr[3] = pAd->Tx40MPwrCfgGBand[3]; + TxPwr[4] = pAd->Tx40MPwrCfgGBand[4]; + } + } + else + { + if (pAd->CommonCfg.Channel > 14) + { + TxPwr[0] = pAd->Tx20MPwrCfgABand[0]; + TxPwr[1] = pAd->Tx20MPwrCfgABand[1]; + TxPwr[2] = pAd->Tx20MPwrCfgABand[2]; + TxPwr[3] = pAd->Tx20MPwrCfgABand[3]; + TxPwr[4] = pAd->Tx20MPwrCfgABand[4]; + } + else + { + TxPwr[0] = pAd->Tx20MPwrCfgGBand[0]; + TxPwr[1] = pAd->Tx20MPwrCfgGBand[1]; + TxPwr[2] = pAd->Tx20MPwrCfgGBand[2]; + TxPwr[3] = pAd->Tx20MPwrCfgGBand[3]; + TxPwr[4] = pAd->Tx20MPwrCfgGBand[4]; + } + } + + + switch(HTTxMode.field.MODE) + { + case MODE_CCK: + case MODE_OFDM: + Value = TxPwr[1]; + TxPwrRef = (Value & 0x00000f00) >> 8; + + break; + + case MODE_HTMIX: + case MODE_HTGREENFIELD: + if (pAd->CommonCfg.TxStream == 1) + { + Value = TxPwr[2]; + TxPwrRef = (Value & 0x00000f00) >> 8; + } + else if (pAd->CommonCfg.TxStream == 2) + { + Value = TxPwr[3]; + TxPwrRef = (Value & 0x00000f00) >> 8; + } + break; + } + + PhyMode = + (HTTxMode.field.MODE == MODE_HTGREENFIELD) + ? MODE_HTMIX : + HTTxMode.field.MODE; + + for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++) + { + if ((TxPwrCfg[Idx].Mode == PhyMode) + && (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS)) + { + Value = TxPwr[TxPwrCfg[Idx].req]; + DaltaPwr = TxPwrRef - (CHAR)((Value & TxPwrCfg[Idx].BitMask) + >> TxPwrCfg[Idx].shift); + CurTxPwr -= DaltaPwr; + break; + } + } + + return CurTxPwr; +} + + VOID MeasureReqTabInit( IN PRTMP_ADAPTER pAd) { @@ -57,7 +290,7 @@ VOID MeasureReqTabInit( VOID MeasureReqTabExit( IN PRTMP_ADAPTER pAd) { - NdisFreeSpinLock(pAd->CommonCfg.MeasureReqTabLock); + NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock); if (pAd->CommonCfg.pMeasureReqTab) kfree(pAd->CommonCfg.pMeasureReqTab); @@ -66,7 +299,7 @@ VOID MeasureReqTabExit( return; } -static PMEASURE_REQ_ENTRY MeasureReqLookUp( +PMEASURE_REQ_ENTRY MeasureReqLookUp( IN PRTMP_ADAPTER pAd, IN UINT8 DialogToken) { @@ -102,7 +335,7 @@ static PMEASURE_REQ_ENTRY MeasureReqLook return pEntry; } -static PMEASURE_REQ_ENTRY MeasureReqInsert( +PMEASURE_REQ_ENTRY MeasureReqInsert( IN PRTMP_ADAPTER pAd, IN UINT8 DialogToken) { @@ -201,7 +434,7 @@ static PMEASURE_REQ_ENTRY MeasureReqInse return pEntry; } -static VOID MeasureReqDelete( +VOID MeasureReqDelete( IN PRTMP_ADAPTER pAd, IN UINT8 DialogToken) { @@ -275,7 +508,7 @@ VOID TpcReqTabInit( VOID TpcReqTabExit( IN PRTMP_ADAPTER pAd) { - NdisFreeSpinLock(pAd->CommonCfg.TpcReqTabLock); + NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock); if (pAd->CommonCfg.pTpcReqTab) kfree(pAd->CommonCfg.pTpcReqTab); @@ -514,6 +747,72 @@ static UINT8 GetCurTxPwr( /* ========================================================================== Description: + Get Current Transmit Power. + + Parametrs: + + Return : Current Time Stamp. + ========================================================================== + */ +VOID InsertChannelRepIE( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN PSTRING pCountry, + IN UINT8 RegulatoryClass) +{ + ULONG TempLen; + UINT8 Len; + UINT8 IEId = IE_AP_CHANNEL_REPORT; + PUCHAR pChListPtr = NULL; + + Len = 1; + if (strncmp(pCountry, "US", 2) == 0) + { + if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: USA Unknow Requlatory class (%d)\n", + __func__, RegulatoryClass)); + return; + } + + Len += USARegulatoryInfo[RegulatoryClass].ChannelSet.NumberOfChannels; + pChListPtr = USARegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList; + } + else if (strncmp(pCountry, "JP", 2) == 0) + { + if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: JP Unknow Requlatory class (%d)\n", + __func__, RegulatoryClass)); + return; + } + + Len += JapanRegulatoryInfo[RegulatoryClass].ChannelSet.NumberOfChannels; + pChListPtr = JapanRegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList; + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n", + __func__, pCountry)); + return; + } + + MakeOutgoingFrame(pFrameBuf, &TempLen, + 1, &IEId, + 1, &Len, + 1, &RegulatoryClass, + Len -1, pChListPtr, + END_OF_ARGS); + + *pFrameLen = *pFrameLen + TempLen; + + return; +} + +/* + ========================================================================== + Description: Insert Dialog Token into frame. Parametrs: @@ -524,7 +823,7 @@ static UINT8 GetCurTxPwr( Return : None. ========================================================================== */ -static VOID InsertDialogToken( +VOID InsertDialogToken( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, @@ -585,7 +884,7 @@ static VOID InsertDialogToken( Return : None. ========================================================================== */ - static VOID InsertTpcReportIE( +VOID InsertTpcReportIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, @@ -679,16 +978,16 @@ static VOID InsertMeasureReqIE( IN PRTMP_ADAPTER pAd, OUT PUCHAR pFrameBuf, OUT PULONG pFrameLen, + IN UINT8 Len, IN PMEASURE_REQ_INFO pMeasureReqIE) { ULONG TempLen; - UINT8 Len = sizeof(MEASURE_REQ_INFO); UINT8 ElementID = IE_MEASUREMENT_REQUEST; MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &ElementID, 1, &Len, - Len, pMeasureReqIE, + sizeof(MEASURE_REQ_INFO), pMeasureReqIE, END_OF_ARGS); *pFrameLen = *pFrameLen + TempLen; @@ -758,53 +1057,43 @@ static VOID InsertMeasureReportIE( Return : None. ========================================================================== */ -VOID EnqueueMeasurementReq( +VOID MakeMeasurementReqFrame( IN PRTMP_ADAPTER pAd, - IN PUCHAR pDA, + OUT PUCHAR pOutBuffer, + OUT PULONG pFrameLen, + IN UINT8 TotalLen, + IN UINT8 Category, + IN UINT8 Action, IN UINT8 MeasureToken, IN UINT8 MeasureReqMode, IN UINT8 MeasureReqType, - IN UINT8 MeasureCh, - IN UINT16 MeasureDuration) + IN UINT8 NumOfRepetitions) { - PUCHAR pOutBuffer = NULL; - NDIS_STATUS NStatus; - ULONG FrameLen; - HEADER_802_11 ActHdr; + ULONG TempLen; MEASURE_REQ_INFO MeasureReqIE; - UINT8 RmReqDailogToken = RandomByte(pAd); - UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd); - // build action frame header. - MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA, - pAd->CurrentAddress); + InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category, Action); - NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory - if(NStatus != NDIS_STATUS_SUCCESS) - { - DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__)); - return; - } - NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); - FrameLen = sizeof(HEADER_802_11); + // fill Dialog Token + InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen, MeasureToken); - InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRQ); + /* fill Number of repetitions. */ + if (Category == CATEGORY_RM) + { + MakeOutgoingFrame((pOutBuffer+*pFrameLen), &TempLen, + 2, &NumOfRepetitions, + END_OF_ARGS); - // fill Dialog Token - InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, MeasureToken); + *pFrameLen += TempLen; + } // prepare Measurement IE. NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO)); - MeasureReqIE.Token = RmReqDailogToken; + MeasureReqIE.Token = MeasureToken; MeasureReqIE.ReqMode.word = MeasureReqMode; MeasureReqIE.ReqType = MeasureReqType; - MeasureReqIE.MeasureReq.ChNum = MeasureCh; - MeasureReqIE.MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime); - MeasureReqIE.MeasureReq.MeasureDuration = cpu2le16(MeasureDuration); - InsertMeasureReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureReqIE); - - MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); + InsertMeasureReqIE(pAd, (pOutBuffer+*pFrameLen), pFrameLen, + TotalLen, &MeasureReqIE); return; } @@ -858,7 +1147,7 @@ VOID EnqueueMeasurementRep( // prepare Measurement IE. NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO)); MeasureRepIE.Token = MeasureToken; - MeasureRepIE.ReportMode.word = MeasureReqMode; + MeasureRepIE.ReportMode = MeasureReqMode; MeasureRepIE.ReportType = MeasureReqType; InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo); @@ -1159,7 +1448,8 @@ static BOOLEAN PeerMeasureReqSanity( IN VOID *pMsg, IN ULONG MsgLen, OUT PUINT8 pDialogToken, - OUT PMEASURE_REQ_INFO pMeasureReqInfo) + OUT PMEASURE_REQ_INFO pMeasureReqInfo, + OUT PMEASURE_REQ pMeasureReq) { PFRAME_802_11 Fr = (PFRAME_802_11)pMsg; PUCHAR pFramePtr = Fr->Octet; @@ -1192,12 +1482,12 @@ static BOOLEAN PeerMeasureReqSanity( NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1); NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1); NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1); - ptr = eid_ptr->Octet + 3; - NdisMoveMemory(&pMeasureReqInfo->MeasureReq.ChNum, ptr, 1); + ptr = (PUCHAR)(eid_ptr->Octet + 3); + NdisMoveMemory(&pMeasureReq->ChNum, ptr, 1); NdisMoveMemory(&MeasureStartTime, ptr + 1, 8); - pMeasureReqInfo->MeasureReq.MeasureStartTime = SWAP64(MeasureStartTime); + pMeasureReq->MeasureStartTime = SWAP64(MeasureStartTime); NdisMoveMemory(&MeasureDuration, ptr + 9, 2); - pMeasureReqInfo->MeasureReq.MeasureDuration = SWAP16(MeasureDuration); + pMeasureReq->MeasureDuration = SWAP16(MeasureDuration); result = TRUE; break; @@ -1285,7 +1575,7 @@ static BOOLEAN PeerMeasureReportSanity( if (pMeasureReportInfo->ReportType == RM_BASIC) { PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf; - ptr = eid_ptr->Octet + 3; + ptr = (PUCHAR)(eid_ptr->Octet + 3); NdisMoveMemory(&pReport->ChNum, ptr, 1); NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8); NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2); @@ -1295,7 +1585,7 @@ static BOOLEAN PeerMeasureReportSanity( else if (pMeasureReportInfo->ReportType == RM_CCA) { PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf; - ptr = eid_ptr->Octet + 3; + ptr = (PUCHAR)(eid_ptr->Octet + 3); NdisMoveMemory(&pReport->ChNum, ptr, 1); NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8); NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2); @@ -1305,7 +1595,7 @@ static BOOLEAN PeerMeasureReportSanity( else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM) { PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf; - ptr = eid_ptr->Octet + 3; + ptr = (PUCHAR)(eid_ptr->Octet + 3); NdisMoveMemory(&pReport->ChNum, ptr, 1); NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8); NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2); @@ -1533,9 +1823,10 @@ static VOID PeerMeasureReqAction( PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg; UINT8 DialogToken; MEASURE_REQ_INFO MeasureReqInfo; + MEASURE_REQ MeasureReq; MEASURE_REPORT_MODE ReportMode; - if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo)) + if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo, &MeasureReq)) { ReportMode.word = 0; ReportMode.field.Incapable = 1; @@ -1729,8 +2020,8 @@ VOID PeerSpectrumAction( break; case SPEC_CHANNEL_SWITCH: -{ -} + + PeerChSwAnnAction(pAd, Elem); break; } @@ -1749,16 +2040,31 @@ VOID PeerSpectrumAction( */ INT Set_MeasureReq_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { UINT Aid = 1; UINT ArgIdx; - PUCHAR thisChar; + PSTRING thisChar; MEASURE_REQ_MODE MeasureReqMode; UINT8 MeasureReqToken = RandomByte(pAd); UINT8 MeasureReqType = RM_BASIC; UINT8 MeasureCh = 1; + UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd); + MEASURE_REQ MeasureReq; + UINT8 TotalLen; + + HEADER_802_11 ActHdr; + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen; + + NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory + if(NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __func__)); + goto END_OF_MEASURE_REQ; + } ArgIdx = 1; while ((thisChar = strsep((char **)&arg, "-")) != NULL) @@ -1766,7 +2072,7 @@ INT Set_MeasureReq_Proc( switch(ArgIdx) { case 1: // Aid. - Aid = simple_strtol(thisChar, 0, 16); + Aid = (UINT8) simple_strtol(thisChar, 0, 16); break; case 2: // Measurement Request Type. @@ -1774,12 +2080,12 @@ INT Set_MeasureReq_Proc( if (MeasureReqType > 3) { DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __func__, MeasureReqType)); - return TRUE; + goto END_OF_MEASURE_REQ; } break; case 3: // Measurement channel. - MeasureCh = simple_strtol(thisChar, 0, 16); + MeasureCh = (UINT8) simple_strtol(thisChar, 0, 16); break; } ArgIdx++; @@ -1789,7 +2095,7 @@ INT Set_MeasureReq_Proc( if (!VALID_WCID(Aid)) { DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __func__, Aid)); - return TRUE; + goto END_OF_MEASURE_REQ; } MeasureReqMode.word = 0; @@ -1797,21 +2103,49 @@ INT Set_MeasureReq_Proc( MeasureReqInsert(pAd, MeasureReqToken); - EnqueueMeasurementReq(pAd, pAd->MacTab.Content[Aid].Addr, - MeasureReqToken, MeasureReqMode.word, MeasureReqType, MeasureCh, 2000); + // build action frame header. + MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pAd->MacTab.Content[Aid].Addr, + pAd->CurrentAddress); + + NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11)); + FrameLen = sizeof(HEADER_802_11); + + TotalLen = sizeof(MEASURE_REQ_INFO) + sizeof(MEASURE_REQ); + + MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen, + sizeof(MEASURE_REQ_INFO), CATEGORY_RM, RM_BASIC, + MeasureReqToken, MeasureReqMode.word, + MeasureReqType, 0); + + MeasureReq.ChNum = MeasureCh; + MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime); + MeasureReq.MeasureDuration = cpu2le16(2000); + + { + ULONG TempLen; + MakeOutgoingFrame( pOutBuffer+FrameLen, &TempLen, + sizeof(MEASURE_REQ), &MeasureReq, + END_OF_ARGS); + FrameLen += TempLen; + } + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (UINT)FrameLen); + +END_OF_MEASURE_REQ: + MlmeFreeMemory(pAd, pOutBuffer); return TRUE; } INT Set_TpcReq_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { UINT Aid; UINT8 TpcReqToken = RandomByte(pAd); - Aid = simple_strtol(arg, 0, 16); + Aid = (UINT) simple_strtol(arg, 0, 16); DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __func__, Aid)); if (!VALID_WCID(Aid)) Index: b/drivers/staging/rt2860/config.mk =================================================================== --- a/drivers/staging/rt2860/config.mk +++ /dev/null @@ -1,241 +0,0 @@ -# Support ATE function -HAS_ATE=n - -# Support 28xx QA ATE function -HAS_28xx_QA=n - -# Support Wpa_Supplicant -HAS_WPA_SUPPLICANT=n - -# Support Native WpaSupplicant for Network Maganger -HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=n - -#Support Net interface block while Tx-Sw queue full -HAS_BLOCK_NET_IF=n - -#Support DFS function -HAS_DFS_SUPPORT=n - -#Support Carrier-Sense function -HAS_CS_SUPPORT=n - -#ifdef MULTI_CARD -# Support for Multiple Cards -HAS_MC_SUPPORT=n -#endif // MULTI_CARD // - -#Support for IEEE802.11e DLS -HAS_QOS_DLS_SUPPORT=n - -#Support for EXT_CHANNEL -HAS_EXT_BUILD_CHANNEL_LIST=n - -#Support for Net-SNMP -HAS_SNMP_SUPPORT=n - -#Support features of Single SKU. -HAS_SINGLE_SKU_SUPPORT=n - -#Support features of 802.11n -HAS_DOT11_N_SUPPORT=y - - -################################################# - -CC := $(CROSS_COMPILE)gcc -LD := $(CROSS_COMPILE)ld - -WFLAGS := -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT -DLINUX -Wall -Wstrict-prototypes -Wno-trigraphs - - -################################################# - -#ifdef CONFIG_STA_SUPPORT -# config for STA mode - -ifeq ($(RT28xx_MODE),STA) -WFLAGS += -DCONFIG_STA_SUPPORT -DDBG - -ifeq ($(HAS_WPA_SUPPLICANT),y) -WFLAGS += -DWPA_SUPPLICANT_SUPPORT -endif - -ifeq ($(HAS_NATIVE_WPA_SUPPLICANT_SUPPORT),y) -WFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT -endif - -ifeq ($(HAS_ATE),y) -WFLAGS += -DRALINK_ATE -ifeq ($(HAS_28xx_QA),y) -WFLAGS += -DRALINK_28xx_QA -endif -endif - -ifeq ($(HAS_SNMP_SUPPORT),y) -WFLAGS += -DSNMP_SUPPORT -endif - -ifeq ($(HAS_QOS_DLS_SUPPORT),y) -WFLAGS += -DQOS_DLS_SUPPORT -endif - -ifeq ($(HAS_DOT11_N_SUPPORT),y) -WFLAGS += -DDOT11_N_SUPPORT -endif - -ifeq ($(HAS_CS_SUPPORT),y) -WFLAGS += -DCARRIER_DETECTION_SUPPORT -endif - -ifeq ($(HAS_SINGLE_SKU_SUPPORT),y) -WFLAGS += -DSINGLE_SKU -endif - -endif -# endif of ifeq ($(RT28xx_MODE),STA) -#endif // CONFIG_STA_SUPPORT // - -################################################# - -################################################# - -# -# Common compiler flag -# - - -ifeq ($(HAS_EXT_BUILD_CHANNEL_LIST),y) -WFLAGS += -DEXT_BUILD_CHANNEL_LIST -endif - -ifeq ($(CHIPSET),2870) -WFLAGS +=-DRT2870 -endif - -ifeq ($(PLATFORM),5VT) -#WFLAGS += -DCONFIG_5VT_ENHANCE -endif - -ifeq ($(HAS_BLOCK_NET_IF),y) -WFLAGS += -DBLOCK_NET_IF -endif - -ifeq ($(HAS_DFS_SUPPORT),y) -WFLAGS += -DDFS_SUPPORT -endif - -#ifdef MULTI_CARD -ifeq ($(HAS_MC_SUPPORT),y) -WFLAGS += -DMULTIPLE_CARD_SUPPORT -endif -#endif // MULTI_CARD // - -ifeq ($(HAS_LLTD),y) -WFLAGS += -DLLTD_SUPPORT -endif - -ifeq ($(PLATFORM),IXP) -WFLAGS += -DRT_BIG_ENDIAN -endif - -ifeq ($(PLATFORM),IKANOS_V160) -WFLAGS += -DRT_BIG_ENDIAN -DIKANOS_VX_1X0 -endif - -ifeq ($(PLATFORM),IKANOS_V180) -WFLAGS += -DRT_BIG_ENDIAN -DIKANOS_VX_1X0 -endif - -ifeq ($(PLATFORM),INF_TWINPASS) -WFLAGS += -DRT_BIG_ENDIAN -DINF_TWINPASS -endif - -ifeq ($(PLATFORM),INF_DANUBE) -WFLAGS += -DINF_DANUBE -DRT_BIG_ENDIAN -endif - -ifeq ($(PLATFORM),CAVM_OCTEON) -WFLAGS += -DRT_BIG_ENDIAN -endif - -ifeq ($(PLATFORM),BRCM_6358) -WFLAGS += -DRT_BIG_ENDIAN -endif - -ifeq ($(PLATFORM),INF_AMAZON_SE) -#WFLAGS += -DRT_BIG_ENDIAN -DINF_AMAZON_SE -DBG_FT_SUPPORT -WFLAGS += -DRT_BIG_ENDIAN -DINF_AMAZON_SE -endif - -#kernel build options for 2.4 -# move to Makefile outside LINUX_SRC := /opt/star/kernel/linux-2.4.27-star - -ifeq ($(PLATFORM),STAR) -CFLAGS := -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) - -export CFLAGS -endif - -ifeq ($(PLATFORM),SIGMA) -CFLAGS := -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) - -export CFLAGS -endif - -ifeq ($(PLATFORM),SIGMA_8622) -CFLAGS := -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) -export CFLAGS -endif - -ifeq ($(PLATFORM),5VT) -CFLAGS := -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) - -export CFLAGS -endif - -ifeq ($(PLATFORM),IKANOS_V160) -CFLAGS := -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) -export CFLAGS -endif - -ifeq ($(PLATFORM),IKANOS_V180) -CFLAGS := -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) -export CFLAGS -endif - -ifeq ($(PLATFORM),INF_TWINPASS) -CFLAGS := -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) -export CFLAGS -endif - -ifeq ($(PLATFORM),INF_DANUBE) -CFLAGS := -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 -export CFLAGS -endif - -ifeq ($(PLATFORM),BRCM_6358) -CFLAGS := $(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 -export CFLAGS -endif - -ifeq ($(PLATFORM),PC) - ifneq (,$(findstring 2.4,$(LINUX_SRC))) - # Linux 2.4 - 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) - export CFLAGS - else - # Linux 2.6 - EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include - endif -endif - -ifeq ($(PLATFORM),IXP) - EXTRA_CFLAGS := -v $(WFLAGS) -I$(RT28xx_DIR)/include -mbig-endian -endif - -ifeq ($(PLATFORM),CAVM_OCTEON) - EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include \ - -mabi=64 $(WFLAGS) -export CFLAGS -endif - Index: b/drivers/staging/rt2860/crypt_hmac.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/crypt_hmac.h @@ -0,0 +1,82 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + */ + +/**************************************************************************** + Module Name: + HMAC + + Abstract: + FIPS 198: The Keyed-Hash Message Authentication Code (HMAC) + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2008/11/24 Create HMAC-SHA1, HMAC-SHA256 +***************************************************************************/ +#ifndef __CRYPT_HMAC_H__ +#define __CRYPT_HMAC_H__ + +#ifdef CRYPT_TESTPLAN +#include "crypt_testplan.h" +#else +#include "rt_config.h" +#endif /* CRYPT_TESTPLAN */ + +#ifdef SHA1_SUPPORT +#define HMAC_SHA1_SUPPORT +VOID HMAC_SHA1 ( + IN const UINT8 Key[], + IN UINT KeyLen, + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 MAC[], + IN UINT MACLen); +#endif /* SHA1_SUPPORT */ + +#ifdef SHA256_SUPPORT +#define HMAC_SHA256_SUPPORT +VOID HMAC_SHA256 ( + IN const UINT8 Key[], + IN UINT KeyLen, + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 MAC[], + IN UINT MACLen); +#endif /* SHA256_SUPPORT */ + +#ifdef MD5_SUPPORT +#define HMAC_MD5_SUPPORT +VOID HMAC_MD5 ( + IN const UINT8 Key[], + IN UINT KeyLen, + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 MAC[], + IN UINT MACLen); +#endif /* MD5_SUPPORT */ + +#endif /* __CRYPT_HMAC_H__ */ Index: b/drivers/staging/rt2860/crypt_md5.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/crypt_md5.h @@ -0,0 +1,80 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + */ + +/**************************************************************************** + Module Name: + MD5 + + Abstract: + RFC1321: The MD5 Message-Digest Algorithm + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2008/11/24 Create md5 +***************************************************************************/ + +#ifndef __CRYPT_MD5_H__ +#define __CRYPT_MD5_H__ + +#ifdef CRYPT_TESTPLAN +#include "crypt_testplan.h" +#else +#include "rt_config.h" +#endif /* CRYPT_TESTPLAN */ + +/* Algorithm options */ +#define MD5_SUPPORT + +#ifdef MD5_SUPPORT +#define MD5_BLOCK_SIZE 64 /* 512 bits = 64 bytes */ +#define MD5_DIGEST_SIZE 16 /* 128 bits = 16 bytes */ +typedef struct { + UINT32 HashValue[4]; + UINT64 MessageLen; + UINT8 Block[MD5_BLOCK_SIZE]; + UINT BlockLen; +} MD5_CTX_STRUC, *PMD5_CTX_STRUC; + +VOID MD5_Init ( + IN MD5_CTX_STRUC *pMD5_CTX); +VOID MD5_Hash ( + IN MD5_CTX_STRUC *pMD5_CTX); +VOID MD5_Append ( + IN MD5_CTX_STRUC *pMD5_CTX, + IN const UINT8 Message[], + IN UINT MessageLen); +VOID MD5_End ( + IN MD5_CTX_STRUC *pMD5_CTX, + OUT UINT8 DigestMessage[]); +VOID RT_MD5 ( + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 DigestMessage[]); +#endif /* MD5_SUPPORT */ + +#endif /* __CRYPT_MD5_H__ */ Index: b/drivers/staging/rt2860/crypt_sha2.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/crypt_sha2.h @@ -0,0 +1,109 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + */ + +/**************************************************************************** + Module Name: + SHA2 + + Abstract: + FIPS 180-2: Secure Hash Standard (SHS) + + Revision History: + Who When What + -------- ---------- ------------------------------------------ + Eddy 2008/11/24 Create SHA1 + Eddy 2008/07/23 Create SHA256 +***************************************************************************/ + +#ifndef __CRYPT_SHA2_H__ +#define __CRYPT_SHA2_H__ + +#ifdef CRYPT_TESTPLAN +#include "crypt_testplan.h" +#else +#include "rt_config.h" +#endif /* CRYPT_TESTPLAN */ + +/* Algorithm options */ +#define SHA1_SUPPORT +#define SHA256_SUPPORT + +#ifdef SHA1_SUPPORT +#define SHA1_BLOCK_SIZE 64 /* 512 bits = 64 bytes */ +#define SHA1_DIGEST_SIZE 20 /* 160 bits = 20 bytes */ +typedef struct _SHA1_CTX_STRUC { + UINT32 HashValue[5]; /* 5 = (SHA1_DIGEST_SIZE / 32) */ + UINT64 MessageLen; /* total size */ + UINT8 Block[SHA1_BLOCK_SIZE]; + UINT BlockLen; +} SHA1_CTX_STRUC, *PSHA1_CTX_STRUC; + +VOID RT_SHA1_Init ( + IN SHA1_CTX_STRUC *pSHA_CTX); +VOID SHA1_Hash ( + IN SHA1_CTX_STRUC *pSHA_CTX); +VOID SHA1_Append ( + IN SHA1_CTX_STRUC *pSHA_CTX, + IN const UINT8 Message[], + IN UINT MessageLen); +VOID SHA1_End ( + IN SHA1_CTX_STRUC *pSHA_CTX, + OUT UINT8 DigestMessage[]); +VOID RT_SHA1 ( + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 DigestMessage[]); +#endif /* SHA1_SUPPORT */ + +#ifdef SHA256_SUPPORT +#define SHA256_BLOCK_SIZE 64 /* 512 bits = 64 bytes */ +#define SHA256_DIGEST_SIZE 32 /* 256 bits = 32 bytes */ +typedef struct _SHA256_CTX_STRUC { + UINT32 HashValue[8]; /* 8 = (SHA256_DIGEST_SIZE / 32) */ + UINT64 MessageLen; /* total size */ + UINT8 Block[SHA256_BLOCK_SIZE]; + UINT BlockLen; +} SHA256_CTX_STRUC, *PSHA256_CTX_STRUC; + +VOID SHA256_Init ( + IN SHA256_CTX_STRUC *pSHA_CTX); +VOID SHA256_Hash ( + IN SHA256_CTX_STRUC *pSHA_CTX); +VOID SHA256_Append ( + IN SHA256_CTX_STRUC *pSHA_CTX, + IN const UINT8 Message[], + IN UINT MessageLen); +VOID SHA256_End ( + IN SHA256_CTX_STRUC *pSHA_CTX, + OUT UINT8 DigestMessage[]); +VOID RT_SHA256 ( + IN const UINT8 Message[], + IN UINT MessageLen, + OUT UINT8 DigestMessage[]); +#endif /* SHA256_SUPPORT */ + +#endif /* __CRYPT_SHA2_H__ */ Index: b/drivers/staging/rt2860/dfs.h =================================================================== --- a/drivers/staging/rt2860/dfs.h +++ b/drivers/staging/rt2860/dfs.h @@ -43,6 +43,33 @@ #define WIDTH_RD_CHECK 1 + +/************************************************************************* + * + * DFS Radar related definitions. + * + ************************************************************************/ +//#define CARRIER_DETECT_TASK_NUM 6 +//#define RADAR_DETECT_TASK_NUM 7 + +// McuRadarState && McuCarrierState for 2880-SW-MCU +#define FREE_FOR_TX 0 +#define WAIT_CTS_BEING_SENT 1 +#define DO_DETECTION 2 + +// McuRadarEvent +#define RADAR_EVENT_CTS_SENT 0x01 // Host signal MCU that CTS has been sent +#define RADAR_EVENT_CTS_CARRIER_SENT 0x02 // Host signal MCU that CTS has been sent (Carrier) +#define RADAR_EVENT_RADAR_DETECTING 0x04 // Radar detection is on going, carrier detection hold back +#define RADAR_EVENT_CARRIER_DETECTING 0x08 // Carrier detection is on going, radar detection hold back +#define RADAR_EVENT_WIDTH_RADAR 0x10 // BBP == 2 radar detected +#define RADAR_EVENT_CTS_KICKED 0x20 // Radar detection need to sent double CTS, first CTS sent + +// McuRadarCmd +#define DETECTION_STOP 0 +#define RADAR_DETECTION 1 +#define CARRIER_DETECTION 2 + VOID BbpRadarDetectionStart( IN PRTMP_ADAPTER pAd); @@ -77,12 +104,13 @@ ULONG RTMPReadRadarDuration( VOID RTMPCleanRadarDuration( IN PRTMP_ADAPTER pAd); + INT Set_ChMovingTime_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_LongPulseRadarTh_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); Index: b/drivers/staging/rt2860/eeprom.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/eeprom.h @@ -0,0 +1,93 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + + Module Name: + eeprom.h + + Abstract: + Miniport header file for eeprom related information + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ +#ifndef __EEPROM_H__ +#define __EEPROM_H__ + + + +#ifdef RTMP_PCI_SUPPORT +/************************************************************************* + * Public function declarations for prom-based chipset + ************************************************************************/ +int rtmp_ee_prom_read16( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT USHORT *pValue); + +int rtmp_ee_prom_write16( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT value); +#endif // RTMP_PCI_SUPPORT // +#ifdef RTMP_USB_SUPPORT +/************************************************************************* + * Public function declarations for usb-based prom chipset + ************************************************************************/ +NTSTATUS RTUSBReadEEPROM16( + IN PRTMP_ADAPTER pAd, + IN USHORT offset, + OUT PUSHORT pData); + +NTSTATUS RTUSBWriteEEPROM16( + IN RTMP_ADAPTER *pAd, + IN USHORT offset, + IN USHORT value); +#endif // RTMP_USB_SUPPORT // + +#ifdef RT30xx +#ifdef RTMP_EFUSE_SUPPORT +int rtmp_ee_efuse_read16( + IN RTMP_ADAPTER *pAd, + IN USHORT Offset, + OUT USHORT *pValue); + +int rtmp_ee_efuse_write16( + IN RTMP_ADAPTER *pAd, + IN USHORT Offset, + IN USHORT data); +#endif // RTMP_EFUSE_SUPPORT // +#endif // RT30xx // + +/************************************************************************* + * Public function declarations for prom operation callback functions setting + ************************************************************************/ +INT RtmpChipOpsEepromHook( + IN RTMP_ADAPTER *pAd, + IN INT infType); + +#endif // __EEPROM_H__ // Index: b/drivers/staging/rt2860/iface/rtmp_pci.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/iface/rtmp_pci.h @@ -0,0 +1,83 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* +*/ + +#ifndef __RTMP_PCI_H__ +#define __RTMP_PCI_H__ + +#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p) \ + ((POS_COOKIE)handle)->pci_dev = dev_p; + + +#ifdef LINUX +// set driver data +#define RT28XX_DRVDATA_SET(_a) pci_set_drvdata(_a, net_dev); + +#define RT28XX_PUT_DEVICE(dev_p) + +#ifndef SA_SHIRQ +#define SA_SHIRQ IRQF_SHARED +#endif + +#ifdef PCI_MSI_SUPPORT +#define RTMP_MSI_ENABLE(_pAd) \ + { POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \ + (_pAd)->HaveMsi = pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; \ + } + +#define RTMP_MSI_DISABLE(_pAd) \ + { POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \ + if (_pAd->HaveMsi == TRUE) \ + pci_disable_msi(_pObj->pci_dev); \ + _pAd->HaveMsi = FALSE; \ + } +#else +#define RTMP_MSI_ENABLE(_pAd) do{}while(0) +#define RTMP_MSI_DISABLE(_pAd) do{}while(0) +#endif // PCI_MSI_SUPPORT // + +#define RTMP_PCI_DEV_UNMAP() \ +{ if (net_dev->base_addr) { \ + iounmap((void *)(net_dev->base_addr)); \ + release_mem_region(pci_resource_start(dev_p, 0), \ + pci_resource_len(dev_p, 0)); } \ + if (net_dev->irq) pci_release_regions(dev_p); } + + +#define PCI_REG_READ_WORD(pci_dev, offset, Configuration) \ + if (pci_read_config_word(pci_dev, offset, ®16) == 0) \ + Configuration = le2cpu16(reg16); \ + else \ + Configuration = 0; + +#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration) \ + reg16 = cpu2le16(Configuration); \ + pci_write_config_word(pci_dev, offset, reg16); + +#endif // LINUX // + + +#endif // __RTMP_PCI_H__ // Index: b/drivers/staging/rt2860/iface/rtmp_usb.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/iface/rtmp_usb.h @@ -0,0 +1,200 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* +*/ + +#ifndef __RTMP_USB_H__ +#define __RTMP_USB_H__ + + +#include "../rtusb_io.h" + + +#ifdef LINUX +#include + +typedef struct usb_device * PUSB_DEV; +typedef struct urb *purbb_t; +typedef struct usb_ctrlrequest devctrlrequest; +#endif // LINUX // + +extern UCHAR EpToQueue[6]; + + +#define RXBULKAGGRE_ZISE 12 +#define MAX_TXBULK_LIMIT (LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1)) +#define MAX_TXBULK_SIZE (LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE) +#define MAX_RXBULK_SIZE (LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE) +#define MAX_MLME_HANDLER_MEMORY 20 + + +// Flags for Bulkflags control for bulk out data +// +#define fRTUSB_BULK_OUT_DATA_NULL 0x00000001 +#define fRTUSB_BULK_OUT_RTS 0x00000002 +#define fRTUSB_BULK_OUT_MLME 0x00000004 + +#define fRTUSB_BULK_OUT_PSPOLL 0x00000010 +#define fRTUSB_BULK_OUT_DATA_FRAG 0x00000020 +#define fRTUSB_BULK_OUT_DATA_FRAG_2 0x00000040 +#define fRTUSB_BULK_OUT_DATA_FRAG_3 0x00000080 +#define fRTUSB_BULK_OUT_DATA_FRAG_4 0x00000100 + +#define fRTUSB_BULK_OUT_DATA_NORMAL 0x00010000 +#define fRTUSB_BULK_OUT_DATA_NORMAL_2 0x00020000 +#define fRTUSB_BULK_OUT_DATA_NORMAL_3 0x00040000 +#define fRTUSB_BULK_OUT_DATA_NORMAL_4 0x00080000 + +// TODO:move to ./ate/include/iface/ate_usb.h + + +#define FREE_HTTX_RING(_pCookie, _pipeId, _txContext) \ +{ \ + if ((_txContext)->ENextBulkOutPosition == (_txContext)->CurWritePosition) \ + { \ + (_txContext)->bRingEmpty = TRUE; \ + } \ + /*NdisInterlockedDecrement(&(_p)->TxCount); */\ +} + + + +/****************************************************************************** + + USB Bulk operation related definitions + +******************************************************************************/ + +#ifdef LINUX +#define BULKAGGRE_ZISE 100 +#define RT28XX_PUT_DEVICE usb_put_dev +#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso, GFP_ATOMIC) +#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb, GFP_ATOMIC) +#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr) usb_buffer_alloc(pUsb_Dev, BufSize, GFP_ATOMIC, pDma_addr) +#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr) usb_buffer_free(pUsb_Dev, BufSize, pTransferBuf, Dma_addr) + +#define RTUSB_FREE_URB(pUrb) usb_free_urb(pUrb) + +// unlink urb +#define RTUSB_UNLINK_URB(pUrb) usb_kill_urb(pUrb) + +extern void dump_urb(struct urb* purb); + +#define InterlockedIncrement atomic_inc +#define NdisInterlockedIncrement atomic_inc +#define InterlockedDecrement atomic_dec +#define NdisInterlockedDecrement atomic_dec +#define InterlockedExchange atomic_set + +#endif // LINUX // + + + +#define NT_SUCCESS(status) (((status) >=0) ? (TRUE):(FALSE)) + + + +#define USBD_TRANSFER_DIRECTION_OUT 0 +#define USBD_TRANSFER_DIRECTION_IN 0 +#define USBD_SHORT_TRANSFER_OK 0 +#define PURB purbb_t + +#define PIRP PVOID +#define NDIS_OID UINT +#ifndef USB_ST_NOERROR +#define USB_ST_NOERROR 0 +#endif + +// vendor-specific control operations +#define CONTROL_TIMEOUT_JIFFIES ( (100 * OS_HZ) / 1000) +#define UNLINK_TIMEOUT_MS 3 + + +VOID RTUSBBulkOutDataPacketComplete(purbb_t purb, struct pt_regs *pt_regs); +VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs); +VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs); +VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs); +VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb, struct pt_regs *pt_regs); +VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs); + + +#ifdef KTHREAD_SUPPORT +#define RTUSBMlmeUp(pAd) \ + do{ \ + RTMP_OS_TASK *_pTask = &((pAd)->mlmeTask);\ + if (_pTask->kthread_task) \ + { \ + _pTask->kthread_running = TRUE; \ + wake_up(&_pTask->kthread_q); \ + } \ + }while(0) +#else +#define RTUSBMlmeUp(pAd) \ + do{ \ + RTMP_OS_TASK *_pTask = &((pAd)->mlmeTask);\ + CHECK_PID_LEGALITY(_pTask->taskPID) \ + { \ + RTMP_SEM_EVENT_UP(&(_pTask->taskSema)); \ + }\ + }while(0) +#endif + +#ifdef KTHREAD_SUPPORT +#define RTUSBCMDUp(pAd) \ + do{ \ + RTMP_OS_TASK *_pTask = &((pAd)->cmdQTask); \ + { \ + _pTask->kthread_running = TRUE; \ + wake_up(&_pTask->kthread_q); \ + } \ + }while(0) + +#else +#define RTUSBCMDUp(pAd) \ + do{ \ + RTMP_OS_TASK *_pTask = &((pAd)->cmdQTask); \ + CHECK_PID_LEGALITY(_pTask->taskPID) \ + {\ + RTMP_SEM_EVENT_UP(&(_pTask->taskSema)); \ + }\ + }while(0) +#endif + +#define DEVICE_VENDOR_REQUEST_OUT 0x40 +#define DEVICE_VENDOR_REQUEST_IN 0xc0 +//#define INTERFACE_VENDOR_REQUEST_OUT 0x41 +//#define INTERFACE_VENDOR_REQUEST_IN 0xc1 + +#define BULKOUT_MGMT_RESET_FLAG 0x80 + +#define RTUSB_SET_BULK_FLAG(_M, _F) ((_M)->BulkFlags |= (_F)) +#define RTUSB_CLEAR_BULK_FLAG(_M, _F) ((_M)->BulkFlags &= ~(_F)) +#define RTUSB_TEST_BULK_FLAG(_M, _F) (((_M)->BulkFlags & (_F)) != 0) + +#define RTMP_IRQ_REQUEST(net_dev) do{}while(0) +#define RTMP_IRQ_RELEASE(net_dev) do{}while(0) + + +#endif // __RTMP_USB_H__ // Index: b/drivers/staging/rt2860/md5.h =================================================================== --- a/drivers/staging/rt2860/md5.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - - Module Name: - md5.h - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs - jan 10-28-03 Initial - Rita 11-23-04 Modify MD5 and SHA-1 -*/ - -#ifndef uint8 -#define uint8 unsigned char -#endif - -#ifndef uint32 -#define uint32 unsigned long int -#endif - - -#ifndef __MD5_H__ -#define __MD5_H__ - -#define MD5_MAC_LEN 16 - -typedef struct _MD5_CTX { - UINT32 Buf[4]; // buffers of four states - UCHAR Input[64]; // input message - UINT32 LenInBitCount[2]; // length counter for input message, 0 up to 64 bits -} MD5_CTX; - -VOID MD5Init(MD5_CTX *pCtx); -VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes); -VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx); -VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16]); - -void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac); -void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac); - -// -// SHA context -// -typedef struct _SHA_CTX -{ - UINT32 Buf[5]; // buffers of five states - UCHAR Input[80]; // input message - UINT32 LenInBitCount[2]; // length counter for input message, 0 up to 64 bits - -} SHA_CTX; - -VOID SHAInit(SHA_CTX *pCtx); -UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes); -VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20]); -VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20]); - -#define SHA_DIGEST_LEN 20 -#endif // __MD5_H__ - -/******************************************************************************/ -#ifndef _AES_H -#define _AES_H - -typedef struct -{ - uint32 erk[64]; /* encryption round keys */ - uint32 drk[64]; /* decryption round keys */ - int nr; /* number of rounds */ -} -aes_context; - -int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits ); -void rtmp_aes_encrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ); -void rtmp_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] ); - -void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output); -int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output); - -#endif /* aes.h */ - Index: b/drivers/staging/rt2860/mlme.h =================================================================== --- a/drivers/staging/rt2860/mlme.h +++ b/drivers/staging/rt2860/mlme.h @@ -39,6 +39,10 @@ #ifndef __MLME_H__ #define __MLME_H__ +#include "rtmp_dot11.h" + + + // maximum supported capability information - // ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot #define SUPPORTED_CAPABILITY_INFO 0x0533 @@ -49,6 +53,7 @@ #define LEAD_TIME 5 #define MLME_TASK_EXEC_MULTIPLE 10 /*5*/ // MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec #define REORDER_EXEC_INTV 100 // 0.1 sec +//#define TBTT_PRELOAD_TIME 384 // usec. LomgPreamble + 24-byte at 1Mbps // The definition of Radar detection duration region #define CE 0 @@ -58,23 +63,24 @@ #define JAP_W56 4 #define MAX_RD_REGION 5 -#ifdef NDIS51_MINIPORT -#define BEACON_LOST_TIME 4000 // 2048 msec = 2 sec -#else #define BEACON_LOST_TIME 4 * OS_HZ // 2048 msec = 2 sec -#endif #define DLS_TIMEOUT 1200 // unit: msec #define AUTH_TIMEOUT 300 // unit: msec #define ASSOC_TIMEOUT 300 // unit: msec -#define JOIN_TIMEOUT 2 * OS_HZ // unit: msec +#define JOIN_TIMEOUT 2000 // unit: msec #define SHORT_CHANNEL_TIME 90 // unit: msec #define MIN_CHANNEL_TIME 110 // unit: msec, for dual band scan #define MAX_CHANNEL_TIME 140 // unit: msec, for single band scan #define FAST_ACTIVE_SCAN_TIME 30 // Active scan waiting for probe response time #define CW_MIN_IN_BITS 4 // actual CwMin = 2^CW_MIN_IN_BITS - 1 +#define LINK_DOWN_TIMEOUT 20000 // unit: msec +#define AUTO_WAKEUP_TIMEOUT 70 //unit: msec + + #define CW_MAX_IN_BITS 10 // actual CwMax = 2^CW_MAX_IN_BITS - 1 + // Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720). // SHould not refer to this constant anymore //#define RSSI_TO_DBM_OFFSET 120 // for RT2530 RSSI-115 = dBm @@ -103,8 +109,16 @@ #define TX_WEIGHTING 30 #define RX_WEIGHTING 20 +//#define PEER_KEY_NOT_USED 0 +//#define PEER_KEY_64_BIT 64 +//#define PEER_KEY_128_BIT 128 + +//#define PEER_KEY_64BIT_LEN 8 +//#define PEER_KEY_128BIT_LEN 16 + #define BSS_NOT_FOUND 0xFFFFFFFF + #define MAX_LEN_OF_MLME_QUEUE 40 //10 #define SCAN_PASSIVE 18 // scan with no probe request, only wait beacon and probe response @@ -115,6 +129,8 @@ #define SCAN_CISCO_CHANNEL_LOAD 23 // Single channel passive scan for channel load collection #define FAST_SCAN_ACTIVE 24 // scan with probe request, and wait beacon and probe response + +//#define BSS_TABLE_EMPTY(x) ((x).BssNr == 0) #define MAC_ADDR_IS_GROUP(Addr) (((Addr[0]) & 0x01)) #define MAC_ADDR_HASH(Addr) (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5]) #define MAC_ADDR_HASH_INDEX(Addr) (MAC_ADDR_HASH(Addr) % HASH_TABLE_SIZE) @@ -146,6 +162,8 @@ #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)) +//#define STA_QOS_CAPABILITY 0 // 1-byte. see 802.11e d9.0 for bit definition + #define ERP_IS_NON_ERP_PRESENT(x) (((x) & 0x01) != 0) // 802.11g #define ERP_IS_USE_PROTECTION(x) (((x) & 0x02) != 0) // 802.11g #define ERP_IS_USE_BARKER_PREAMBLE(x) (((x) & 0x04) != 0) // 802.11g @@ -290,7 +308,7 @@ typedef struct PACKED _HT_CAPABILITY_IE{ #define dot11BSSWidthTriggerScanInterval 300 // in sec. max interval between scan operations to be performed to detect BSS channel width trigger events. #define dot11OBSSScanPassiveTotalPerChannel 200 // in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan. #define dot11OBSSScanActiveTotalPerChannel 20 //in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan -#define dot11BSSWidthChannelTransactionDelayFactor 5 // min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maxima +#define dot11BSSWidthChannelTransactionDelayFactor 5 // min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maximum // interval between overlapping BSS scan operations. #define dot11BSSScanActivityThreshold 25 // in %%, max total time that a STA may be active on the medium during a period of // (dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without @@ -382,7 +400,7 @@ typedef struct { BOOLEAN bHtEnable; // If we should use ht rate. BOOLEAN bPreNHt; // If we should use ht rate. //Substract from HT Capability IE - UCHAR MCSSet[16]; //only supoort MCS=0-15,32 , + UCHAR MCSSet[16]; } RT_HT_PHY_INFO, *PRT_HT_PHY_INFO; //This structure substracts ralink supports from all 802.11n-related features. @@ -460,60 +478,6 @@ typedef struct PACKED{ UCHAR NewExtChanOffset; } NEW_EXT_CHAN_IE, *PNEW_EXT_CHAN_IE; - -// 4-byte HTC field. maybe included in any frame except non-QOS data frame. The Order bit must set 1. -typedef struct PACKED { - UINT32 MA:1; //management action payload exist in (QoS Null+HTC) - UINT32 TRQ:1; //sounding request - UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback - UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110. - UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB. - UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available - UINT32 CalPos:2; // calibration position - UINT32 CalSeq:2; //calibration sequence - UINT32 FBKReq:2; //feedback request - UINT32 CSISTEERING:2; //CSI/ STEERING - UINT32 ZLFAnnouce:1; // ZLF announcement - UINT32 rsv:5; //calibration sequence - UINT32 ACConstraint:1; //feedback request - UINT32 RDG:1; //RDG / More PPDU -} HT_CONTROL, *PHT_CONTROL; - -// 2-byte QOS CONTROL field -typedef struct PACKED { - USHORT TID:4; - USHORT EOSP:1; - USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA - USHORT AMsduPresent:1; - USHORT Txop_QueueSize:8; -} QOS_CONTROL, *PQOS_CONTROL; - -// 2-byte Frame control field -typedef struct PACKED { - USHORT Ver:2; // Protocol version - USHORT Type:2; // MSDU type - USHORT SubType:4; // MSDU subtype - USHORT ToDs:1; // To DS indication - USHORT FrDs:1; // From DS indication - USHORT MoreFrag:1; // More fragment bit - USHORT Retry:1; // Retry status bit - USHORT PwrMgmt:1; // Power management bit - USHORT MoreData:1; // More data bit - USHORT Wep:1; // Wep data - USHORT Order:1; // Strict order expected -} FRAME_CONTROL, *PFRAME_CONTROL; - -typedef struct PACKED _HEADER_802_11 { - FRAME_CONTROL FC; - USHORT Duration; - UCHAR Addr1[MAC_ADDR_LEN]; - UCHAR Addr2[MAC_ADDR_LEN]; - UCHAR Addr3[MAC_ADDR_LEN]; - USHORT Frag:4; - USHORT Sequence:12; - UCHAR Octet[0]; -} HEADER_802_11, *PHEADER_802_11; - typedef struct PACKED _FRAME_802_11 { HEADER_802_11 Hdr; UCHAR Octet[1]; @@ -595,20 +559,6 @@ typedef struct { } EACH_TID, *PEACH_TID; -typedef struct PACKED _PSPOLL_FRAME { - FRAME_CONTROL FC; - USHORT Aid; - UCHAR Bssid[MAC_ADDR_LEN]; - UCHAR Ta[MAC_ADDR_LEN]; -} PSPOLL_FRAME, *PPSPOLL_FRAME; - -typedef struct PACKED _RTS_FRAME { - FRAME_CONTROL FC; - USHORT Duration; - UCHAR Addr1[MAC_ADDR_LEN]; - UCHAR Addr2[MAC_ADDR_LEN]; -}RTS_FRAME, *PRTS_FRAME; - // BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap. typedef struct PACKED _FRAME_BA_REQ { FRAME_CONTROL FC; @@ -920,6 +870,9 @@ typedef struct _MLME_QUEUE_ELEM { UCHAR Channel; UCHAR Wcid; BOOLEAN Occupied; +#ifdef MLME_EX + USHORT Idx; +#endif // MLME_EX // } MLME_QUEUE_ELEM, *PMLME_QUEUE_ELEM; typedef struct _MLME_QUEUE { @@ -1059,7 +1012,7 @@ typedef struct _MLME_START_REQ_STRUCT { typedef struct PACKED { UCHAR Eid; UCHAR Len; - CHAR Octet[1]; + UCHAR Octet[1]; } EID_STRUCT,*PEID_STRUCT, BEACON_EID_STRUCT, *PBEACON_EID_STRUCT; typedef struct PACKED _RTMP_TX_RATE_SWITCH @@ -1080,6 +1033,11 @@ typedef struct PACKED _RTMP_TX_RATE_SWIT #define TBTT_PRELOAD_TIME 384 // usec. LomgPreamble + 24-byte at 1Mbps #define DEFAULT_DTIM_PERIOD 1 +// weighting factor to calculate Channel quality, total should be 100% +//#define RSSI_WEIGHTING 0 +//#define TX_WEIGHTING 40 +//#define RX_WEIGHTING 60 + #define MAC_TABLE_AGEOUT_TIME 300 // unit: sec #define MAC_TABLE_ASSOC_TIMEOUT 5 // unit: sec #define MAC_TABLE_FULL(Tab) ((Tab).size == MAX_LEN_OF_MAC_TABLE) Index: b/drivers/staging/rt2860/oid.h =================================================================== --- a/drivers/staging/rt2860/oid.h +++ b/drivers/staging/rt2860/oid.h @@ -37,9 +37,14 @@ #ifndef _OID_H_ #define _OID_H_ +//#include +#ifndef TRUE #define TRUE 1 +#endif +#ifndef FALSE #define FALSE 0 +#endif // // IEEE 802.11 Structures and definitions // @@ -73,24 +78,25 @@ #define NDIS_802_11_LENGTH_RATES 8 #define NDIS_802_11_LENGTH_RATES_EX 16 #define MAC_ADDR_LENGTH 6 -#define MAX_NUM_OF_CHS 49 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc +//#define MAX_NUM_OF_CHS 49 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc +#define MAX_NUM_OF_CHS 54 // 14 channels @2.4G + 12@UNII(lower/middle) + 16@HiperLAN2 + 11@UNII(upper) + 0 @Japan + 1 as NULL termination #define MAX_NUMBER_OF_EVENT 10 // entry # in EVENT table #define MAX_NUMBER_OF_MAC 32 // if MAX_MBSSID_NUM is 8, this value can't be larger than 211 #define MAX_NUMBER_OF_ACL 64 #define MAX_LENGTH_OF_SUPPORT_RATES 12 // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 #define MAX_NUMBER_OF_DLS_ENTRY 4 -#define OID_GEN_MACHINE_NAME 0x0001021A #define RT_QUERY_SIGNAL_CONTEXT 0x0402 #define RT_SET_IAPP_PID 0x0404 #define RT_SET_APD_PID 0x0405 #define RT_SET_DEL_MAC_ENTRY 0x0406 - +#define RT_QUERY_EVENT_TABLE 0x0407 // // IEEE 802.11 OIDs // #define OID_GET_SET_TOGGLE 0x8000 +#define OID_GET_SET_FROM_UI 0x4000 #define OID_802_11_ADD_WEP 0x0112 #define OID_802_11_DISASSOCIATE 0x0114 @@ -101,22 +107,28 @@ #define RT_OID_DEVICE_NAME 0x0607 #define RT_OID_VERSION_INFO 0x0608 +#define OID_802_11_BSSID_LIST 0x0609 +#define OID_802_3_CURRENT_ADDRESS 0x060A #define OID_GEN_MEDIA_CONNECT_STATUS 0x060B +#define RT_OID_802_11_QUERY_LINK_STATUS 0x060C +#define OID_802_11_RSSI 0x060D +#define OID_802_11_STATISTICS 0x060E #define OID_GEN_RCV_OK 0x060F #define OID_GEN_RCV_NO_BUFFER 0x0610 - +#define RT_OID_802_11_QUERY_EEPROM_VERSION 0x0611 +#define RT_OID_802_11_QUERY_FIRMWARE_VERSION 0x0612 +#define RT_OID_802_11_QUERY_LAST_RX_RATE 0x0613 +#define RT_OID_802_11_TX_POWER_LEVEL_1 0x0614 +#define RT_OID_802_11_QUERY_PIDVID 0x0615 +//for WPA_SUPPLICANT_SUPPORT #define OID_SET_COUNTERMEASURES 0x0616 #define RT_OID_WPA_SUPPLICANT_SUPPORT 0x0621 #define RT_OID_WE_VERSION_COMPILED 0x0622 #define RT_OID_NEW_DRIVER 0x0623 -//rt2860 , kathy #define RT_OID_DRIVER_DEVICE_NAME 0x0645 #define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT 0x0647 -// Ralink defined OIDs -// Dennis Lee move to platform specific - typedef enum _NDIS_802_11_STATUS_TYPE { Ndis802_11StatusType_Authentication, @@ -169,10 +181,10 @@ typedef enum _NDIS_802_11_NETWORK_TYPE Ndis802_11FH, Ndis802_11DS, Ndis802_11OFDM5, - Ndis802_11OFDM5_N, Ndis802_11OFDM24, - Ndis802_11OFDM24_N, Ndis802_11Automode, + Ndis802_11OFDM5_N, + Ndis802_11OFDM24_N, Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound } NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; @@ -271,13 +283,15 @@ typedef struct PACKED _RADIUS_CONF UINT32 own_ip_addr; UINT32 retry_interval; UINT32 session_timeout_interval; - UCHAR EAPifname[IFNAMSIZ]; - UCHAR EAPifname_len; - UCHAR PreAuthifname[IFNAMSIZ]; - UCHAR PreAuthifname_len; - RADIUS_KEY_INFO RadiusInfo[8/*MAX_MBSSID_NUM*/]; + UCHAR EAPifname[8][IFNAMSIZ]; + UCHAR EAPifname_len[8]; + UCHAR PreAuthifname[8][IFNAMSIZ]; + UCHAR PreAuthifname_len[8]; + RADIUS_KEY_INFO RadiusInfo[8]; } RADIUS_CONF, *PRADIUS_CONF; + + // Key mapping keys require a BSSID typedef struct _NDIS_802_11_KEY { @@ -289,6 +303,13 @@ typedef struct _NDIS_802_11_KEY UCHAR KeyMaterial[1]; // variable length depending on above field } NDIS_802_11_KEY, *PNDIS_802_11_KEY; +typedef struct _NDIS_802_11_PASSPHRASE +{ + UINT KeyLength; // length of key in bytes + NDIS_802_11_MAC_ADDRESS BSSID; + UCHAR KeyMaterial[1]; // variable length depending on above field +} NDIS_802_11_PASSPHRASE, *PNDIS_802_11_PASSPHRASE; + typedef struct _NDIS_802_11_REMOVE_KEY { UINT Length; // Length of this structure @@ -481,6 +502,19 @@ typedef struct _NDIS_802_11_AUTHENTICATI NDIS_802_11_AUTHENTICATION_REQUEST Request[1]; } NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT; +/* +typedef struct _NDIS_802_11_TEST +{ + ULONG Length; + ULONG Type; + union + { + NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent; + NDIS_802_11_RSSI RssiTrigger; + }; +} NDIS_802_11_TEST, *PNDIS_802_11_TEST; + */ + // 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE typedef enum _NDIS_802_11_MEDIA_STREAM_MODE { @@ -519,14 +553,18 @@ typedef struct _NDIS_802_11_CAPABILITY NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1]; } NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY; -#define RT_PRIV_IOCTL_EXT (SIOCIWFIRSTPRIV + 0x01) // Sync. with AP for wsc upnp daemon +#ifdef LINUX +#endif // LINUX // + + +#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x01) // Sync. with AP for wsc upnp daemon #define RTPRIV_IOCTL_SET (SIOCIWFIRSTPRIV + 0x02) #define RTPRIV_IOCTL_STATISTICS (SIOCIWFIRSTPRIV + 0x09) #define RTPRIV_IOCTL_ADD_PMKID_CACHE (SIOCIWFIRSTPRIV + 0x0A) #define RTPRIV_IOCTL_RADIUS_DATA (SIOCIWFIRSTPRIV + 0x0C) #define RTPRIV_IOCTL_GSITESURVEY (SIOCIWFIRSTPRIV + 0x0D) -#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x0E) // Sync. with RT61 (for wpa_supplicant) +#define RT_PRIV_IOCTL_EXT (SIOCIWFIRSTPRIV + 0x0E) // Sync. with RT61 (for wpa_supplicant) #define RTPRIV_IOCTL_GET_MAC_TABLE (SIOCIWFIRSTPRIV + 0x0F) #define RTPRIV_IOCTL_SHOW (SIOCIWFIRSTPRIV + 0x11) @@ -535,27 +573,61 @@ enum { SHOW_DRVIER_VERION = 5, SHOW_BA_INFO = 6, SHOW_DESC_INFO = 7, -#ifdef RT2870 +#ifdef RTMP_MAC_USB SHOW_RXBULK_INFO = 8, SHOW_TXBULK_INFO = 9, -#endif // RT2870 // +#endif // RTMP_MAC_USB // RAIO_OFF = 10, RAIO_ON = 11, SHOW_CFG_VALUE = 20, -#if !defined(RT2860) SHOW_ADHOC_ENTRY_INFO = 21, -#endif }; + + + + + +#define OID_802_11_BUILD_CHANNEL_EX 0x0714 +#define OID_802_11_GET_CH_LIST 0x0715 +#define OID_802_11_GET_COUNTRY_CODE 0x0716 +#define OID_802_11_GET_CHANNEL_GEOGRAPHY 0x0717 + +//#define RT_OID_802_11_STATISTICS (OID_GET_SET_TOGGLE | OID_802_11_STATISTICS) + +#define RT_OID_WSC_SET_PASSPHRASE 0x0740 // passphrase for wpa(2)-psk +#define RT_OID_WSC_DRIVER_AUTO_CONNECT 0x0741 +#define RT_OID_WSC_QUERY_DEFAULT_PROFILE 0x0742 +#define RT_OID_WSC_SET_CONN_BY_PROFILE_INDEX 0x0743 +#define RT_OID_WSC_SET_ACTION 0x0744 +#define RT_OID_WSC_SET_SSID 0x0745 +#define RT_OID_WSC_SET_PIN_CODE 0x0746 +#define RT_OID_WSC_SET_MODE 0x0747 // PIN or PBC +#define RT_OID_WSC_SET_CONF_MODE 0x0748 // Enrollee or Registrar +#define RT_OID_WSC_SET_PROFILE 0x0749 +#define RT_OID_WSC_CONFIG_STATUS 0x074F +#define RT_OID_802_11_WSC_QUERY_PROFILE 0x0750 +// for consistency with RT61 +#define RT_OID_WSC_QUERY_STATUS 0x0751 +#define RT_OID_WSC_PIN_CODE 0x0752 +#define RT_OID_WSC_UUID 0x0753 +#define RT_OID_WSC_SET_SELECTED_REGISTRAR 0x0754 +#define RT_OID_WSC_EAPMSG 0x0755 +#define RT_OID_WSC_MANUFACTURER 0x0756 +#define RT_OID_WSC_MODEL_NAME 0x0757 +#define RT_OID_WSC_MODEL_NO 0x0758 +#define RT_OID_WSC_SERIAL_NO 0x0759 +#define RT_OID_WSC_MAC_ADDRESS 0x0760 + #ifdef LLTD_SUPPORT // for consistency with RT61 #define RT_OID_GET_PHY_MODE 0x761 #endif // LLTD_SUPPORT // -#if defined(RT2860) || defined(RT30xx) + + // New for MeetingHouse Api support #define OID_MH_802_1X_SUPPORTED 0xFFEDC100 -#endif // MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!! typedef union _HTTRANSMIT_SETTING { @@ -564,6 +636,7 @@ typedef union _HTTRANSMIT_SETTING { USHORT BW:1; //channel bandwidth 20MHz or 40 MHz USHORT ShortGI:1; USHORT STBC:2; //SPACE +// USHORT rsv:3; USHORT rsv:2; USHORT TxBF:1; USHORT MODE:2; // Use definition MODE_xxx. @@ -577,7 +650,6 @@ typedef enum _RT_802_11_PREAMBLE { Rt802_11PreambleAuto } RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE; -// Only for STA, need to sync with AP typedef enum _RT_802_11_PHY_MODE { PHY_11BG_MIXED = 0, PHY_11B, @@ -772,7 +844,6 @@ typedef struct _RT_CHANNEL_LIST_INFO UCHAR ChannelListNum; // number of channel in ChannelList[] } RT_CHANNEL_LIST_INFO, *PRT_CHANNEL_LIST_INFO; -#ifdef RT2870 // WSC configured credential typedef struct _WSC_CREDENTIAL { @@ -790,9 +861,9 @@ typedef struct _WSC_CREDENTIAL typedef struct _WSC_PROFILE { UINT ProfileCnt; + UINT ApplyProfileIdx; // add by johnli, fix WPS test plan 5.1.1 WSC_CREDENTIAL Profile[8]; // Support up to 8 profiles } WSC_PROFILE, *PWSC_PROFILE; -#endif #endif // _OID_H_ Index: b/drivers/staging/rt2860/pci_main_dev.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/pci_main_dev.c @@ -0,0 +1,873 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + pci_main_dev.c + + Abstract: + Create and register network interface for PCI based chipsets in Linux platform. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#include "rt_config.h" +#include + +// +// Function declarations +// +extern int rt28xx_close(IN struct net_device *net_dev); +extern int rt28xx_open(struct net_device *net_dev); + +static VOID __devexit rt2860_remove_one(struct pci_dev *pci_dev); +static INT __devinit rt2860_probe(struct pci_dev *pci_dev, const struct pci_device_id *ent); +static void __exit rt2860_cleanup_module(void); +static int __init rt2860_init_module(void); + + static VOID RTMPInitPCIeDevice( + IN struct pci_dev *pci_dev, + IN PRTMP_ADAPTER pAd); + +#ifdef CONFIG_PM +static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state); +static int rt2860_resume(struct pci_dev *pci_dev); +#endif // CONFIG_PM // + +// +// Ralink PCI device table, include all supported chipsets +// +static struct pci_device_id rt2860_pci_tbl[] __devinitdata = +{ + {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCI_DEVICE_ID)}, //RT28602.4G + {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCIe_DEVICE_ID)}, + {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2760_PCI_DEVICE_ID)}, + {PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2790_PCIe_DEVICE_ID)}, + {PCI_DEVICE(VEN_AWT_PCI_VENDOR_ID, VEN_AWT_PCIe_DEVICE_ID)}, + {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7708)}, + {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7728)}, + {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7758)}, + {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7727)}, + {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7738)}, + {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7748)}, + {PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7768)}, + {0,} // terminate list +}; + +MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl); +MODULE_LICENSE("GPL"); +#ifdef MODULE_VERSION +MODULE_VERSION(STA_DRIVER_VERSION); +#endif + + +// +// Our PCI driver structure +// +static struct pci_driver rt2860_driver = +{ + name: "rt2860", + id_table: rt2860_pci_tbl, + probe: rt2860_probe, + remove: __devexit_p(rt2860_remove_one), +#ifdef CONFIG_PM + suspend: rt2860_suspend, + resume: rt2860_resume, +#endif +}; + + +/*************************************************************************** + * + * PCI device initialization related procedures. + * + ***************************************************************************/ +#ifdef CONFIG_PM + +VOID RT2860RejectPendingPackets( + IN PRTMP_ADAPTER pAd) +{ + // clear PS packets + // clear TxSw packets +} + +static int rt2860_suspend( + struct pci_dev *pci_dev, + pm_message_t state) +{ + struct net_device *net_dev = pci_get_drvdata(pci_dev); + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; + INT32 retval = 0; + + + DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n")); + + if (net_dev == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n")); + } + else + { + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + /* we can not use IFF_UP because ra0 down but ra1 up */ + /* and 1 suspend/resume function for 1 module, not for each interface */ + /* so Linux will call suspend/resume function once */ + if (VIRTUAL_IF_NUM(pAd) > 0) + { + // avoid users do suspend after interface is down + + // stop interface + netif_carrier_off(net_dev); + netif_stop_queue(net_dev); + + // mark device as removed from system and therefore no longer available + netif_device_detach(net_dev); + + // mark halt flag + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); + + // take down the device + rt28xx_close((PNET_DEV)net_dev); + + RT_MOD_DEC_USE_COUNT(); + } + } + + // reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html + // enable device to generate PME# when suspended + // pci_choose_state(): Choose the power state of a PCI device to be suspended + retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1); + // save the PCI configuration space of a device before suspending + pci_save_state(pci_dev); + // disable PCI device after use + pci_disable_device(pci_dev); + + retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n")); + return retval; +} + +static int rt2860_resume( + struct pci_dev *pci_dev) +{ + struct net_device *net_dev = pci_get_drvdata(pci_dev); + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; + INT32 retval; + + + // set the power state of a PCI device + // PCI has 4 power states, DO (normal) ~ D3(less power) + // in include/linux/pci.h, you can find that + // #define PCI_D0 ((pci_power_t __force) 0) + // #define PCI_D1 ((pci_power_t __force) 1) + // #define PCI_D2 ((pci_power_t __force) 2) + // #define PCI_D3hot ((pci_power_t __force) 3) + // #define PCI_D3cold ((pci_power_t __force) 4) + // #define PCI_UNKNOWN ((pci_power_t __force) 5) + // #define PCI_POWER_ERROR ((pci_power_t __force) -1) + retval = pci_set_power_state(pci_dev, PCI_D0); + + // restore the saved state of a PCI device + pci_restore_state(pci_dev); + + // initialize device before it's used by a driver + if (pci_enable_device(pci_dev)) + { + printk("pci enable fail!\n"); + return 0; + } + + DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n")); + + if (net_dev == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n")); + } + else + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + if (pAd != NULL) + { + /* we can not use IFF_UP because ra0 down but ra1 up */ + /* and 1 suspend/resume function for 1 module, not for each interface */ + /* so Linux will call suspend/resume function once */ + if (VIRTUAL_IF_NUM(pAd) > 0) + { + // mark device as attached from system and restart if needed + netif_device_attach(net_dev); + + if (rt28xx_open((PNET_DEV)net_dev) != 0) + { + // open fail + DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n")); + return 0; + } + + // increase MODULE use count + RT_MOD_INC_USE_COUNT(); + + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); + + netif_start_queue(net_dev); + netif_carrier_on(net_dev); + netif_wake_queue(net_dev); + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n")); + return 0; +} +#endif // CONFIG_PM // + + +static INT __init rt2860_init_module(VOID) +{ + return pci_register_driver(&rt2860_driver); +} + + +// +// Driver module unload function +// +static VOID __exit rt2860_cleanup_module(VOID) +{ + pci_unregister_driver(&rt2860_driver); +} + +module_init(rt2860_init_module); +module_exit(rt2860_cleanup_module); + + +// +// PCI device probe & initialization function +// +static INT __devinit rt2860_probe( + IN struct pci_dev *pci_dev, + IN const struct pci_device_id *pci_id) +{ + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; + struct net_device *net_dev; + PVOID handle; + PSTRING print_name; + ULONG csr_addr; + INT rv = 0; + RTMP_OS_NETDEV_OP_HOOK netDevHook; + + DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_probe\n")); + +//PCIDevInit============================================== + // wake up and enable device + if ((rv = pci_enable_device(pci_dev))!= 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("Enable PCI device failed, errno=%d!\n", rv)); + return rv; + } + + print_name = pci_name(pci_dev); + + if ((rv = pci_request_regions(pci_dev, print_name)) != 0) + { + DBGPRINT(RT_DEBUG_ERROR, ("Request PCI resource failed, errno=%d!\n", rv)); + goto err_out; + } + + // map physical address to virtual address for accessing register + csr_addr = (unsigned long) ioremap(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); + if (!csr_addr) + { + DBGPRINT(RT_DEBUG_ERROR, ("ioremap failed for device %s, region 0x%lX @ 0x%lX\n", + print_name, (ULONG)pci_resource_len(pci_dev, 0), (ULONG)pci_resource_start(pci_dev, 0))); + goto err_out_free_res; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n", print_name, + (ULONG)pci_resource_start(pci_dev, 0), (ULONG)csr_addr, pci_dev->irq)); + } + + // Set DMA master + pci_set_master(pci_dev); + + +//RtmpDevInit============================================== + // Allocate RTMP_ADAPTER adapter structure + handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL); + if (handle == NULL) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s(): Allocate memory for os handle failed!\n", __func__)); + goto err_out_iounmap; + } + + ((POS_COOKIE)handle)->pci_dev = pci_dev; + + rv = RTMPAllocAdapterBlock(handle, &pAd); //shiang: we may need the pci_dev for allocate structure of "RTMP_ADAPTER" + if (rv != NDIS_STATUS_SUCCESS) + goto err_out_iounmap; + // Here are the RTMP_ADAPTER structure with pci-bus specific parameters. + pAd->CSRBaseAddress = (PUCHAR)csr_addr; + DBGPRINT(RT_DEBUG_ERROR, ("pAd->CSRBaseAddress =0x%lx, csr_addr=0x%lx!\n", (ULONG)pAd->CSRBaseAddress, csr_addr)); + RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_PCI); + + +//NetDevInit============================================== + net_dev = RtmpPhyNetDevInit(pAd, &netDevHook); + if (net_dev == NULL) + goto err_out_free_radev; + + // Here are the net_device structure with pci-bus specific parameters. + net_dev->irq = pci_dev->irq; // Interrupt IRQ number + net_dev->base_addr = csr_addr; // Save CSR virtual address and irq to device structure + pci_set_drvdata(pci_dev, net_dev); // Set driver data + +/* for supporting Network Manager */ + /* Set the sysfs physical device reference for the network logical device + * if set prior to registration will cause a symlink during initialization. + */ + SET_NETDEV_DEV(net_dev, &(pci_dev->dev)); + + +//All done, it's time to register the net device to linux kernel. + // Register this device + rv = RtmpOSNetDevAttach(net_dev, &netDevHook); + if (rv) + goto err_out_free_netdev; + + pAd->StaCfg.OriDevType = net_dev->type; + RTMPInitPCIeDevice(pci_dev, pAd); + +#ifdef KTHREAD_SUPPORT +#endif // KTHREAD_SUPPORT // + + DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_probe\n")); + + return 0; // probe ok + + + /* --------------------------- ERROR HANDLE --------------------------- */ +err_out_free_netdev: + RtmpOSNetDevFree(net_dev); + +err_out_free_radev: + /* free RTMP_ADAPTER strcuture and os_cookie*/ + RTMPFreeAdapter(pAd); + +err_out_iounmap: + iounmap((void *)(csr_addr)); + release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); + +err_out_free_res: + pci_release_regions(pci_dev); + +err_out: + pci_disable_device(pci_dev); + + DBGPRINT(RT_DEBUG_ERROR, ("<=== rt2860_probe failed with rv = %d!\n", rv)); + + return -ENODEV; /* probe fail */ +} + + +static VOID __devexit rt2860_remove_one( + IN struct pci_dev *pci_dev) +{ + PNET_DEV net_dev = pci_get_drvdata(pci_dev); + RTMP_ADAPTER *pAd = NULL; + ULONG csr_addr = net_dev->base_addr; // pAd->CSRBaseAddress; + + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n")); + + if (pAd != NULL) + { + // Unregister/Free all allocated net_device. + RtmpPhyNetDevExit(pAd, net_dev); + + // Unmap CSR base address + iounmap((char *)(csr_addr)); + + // release memory region + release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); + + // Free RTMP_ADAPTER related structures. + RtmpRaDevCtrlExit(pAd); + + } + else + { + // Unregister network device + RtmpOSNetDevDetach(net_dev); + + // Unmap CSR base address + iounmap((char *)(net_dev->base_addr)); + + // release memory region + release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); + } + + // Free the root net_device + RtmpOSNetDevFree(net_dev); + +} + + +/* +======================================================================== +Routine Description: + Check the chipset vendor/product ID. + +Arguments: + _dev_p Point to the PCI or USB device + +Return Value: + TRUE Check ok + FALSE Check fail + +Note: +======================================================================== +*/ +BOOLEAN RT28XXChipsetCheck( + IN void *_dev_p) +{ + /* always TRUE */ + return TRUE; +} + + +/*************************************************************************** + * + * PCIe device initialization related procedures. + * + ***************************************************************************/ + static VOID RTMPInitPCIeDevice( + IN struct pci_dev *pci_dev, + IN PRTMP_ADAPTER pAd) +{ + USHORT device_id; + POS_COOKIE pObj; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + pci_read_config_word(pci_dev, PCI_DEVICE_ID, &device_id); + device_id = le2cpu16(device_id); + pObj->DeviceID = device_id; + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE); + if ( + (device_id == NIC2860_PCIe_DEVICE_ID) || + (device_id == NIC2790_PCIe_DEVICE_ID) || + (device_id == VEN_AWT_PCIe_DEVICE_ID) || + 0) + { + UINT32 MacCsr0 = 0, Index= 0; + do + { + RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); + + if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF)) + break; + + RTMPusecDelay(10); + } while (Index++ < 100); + + // Support advanced power save after 2892/2790. + // MAC version at offset 0x1000 is 0x2872XXXX/0x2870XXXX(PCIe, USB, SDIO). + if ((MacCsr0&0xffff0000) != 0x28600000) + { + OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE); + } + } +} + + +VOID RTMPInitPCIeLinkCtrlValue( + IN PRTMP_ADAPTER pAd) +{ + INT pos; + USHORT reg16, data2, PCIePowerSaveLevel, Configuration; + BOOLEAN bFindIntel = FALSE; + POS_COOKIE pObj; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + return; + + DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__)); + // Init EEPROM, and save settings + if (!IS_RT3090(pAd)) + { + RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel); + pAd->PCIePowerSaveLevel = PCIePowerSaveLevel & 0xff; + + if ((PCIePowerSaveLevel&0xff) == 0xff) + { + OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE); + DBGPRINT(RT_DEBUG_TRACE, ("====> PCIePowerSaveLevel = 0x%x.\n", PCIePowerSaveLevel)); + return; + } + else + { + PCIePowerSaveLevel &= 0x3; + RT28xx_EEPROM_READ16(pAd, 0x24, data2); + + if( !(((data2&0xff00) == 0x9200) && ((data2&0x80) !=0)) ) + { + if (PCIePowerSaveLevel > 1 ) + PCIePowerSaveLevel = 1; + } + + DBGPRINT(RT_DEBUG_TRACE, ("====> Write 0x83 = 0x%x.\n", PCIePowerSaveLevel)); + AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSaveLevel, 0x00); + RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel); + PCIePowerSaveLevel &= 0xff; + PCIePowerSaveLevel = PCIePowerSaveLevel >> 6; + switch(PCIePowerSaveLevel) + { + case 0: // Only support L0 + pAd->LnkCtrlBitMask = 0; + break; + case 1: // Only enable L0s + pAd->LnkCtrlBitMask = 1; + break; + case 2: // enable L1, L0s + pAd->LnkCtrlBitMask = 3; + break; + case 3: // sync with host clk and enable L1, L0s + pAd->LnkCtrlBitMask = 0x103; + break; + } + DBGPRINT(RT_DEBUG_TRACE, ("====> LnkCtrlBitMask = 0x%x.\n", pAd->LnkCtrlBitMask)); + } + } + else if (IS_RT3090(pAd)) + { + // 1. read setting from inf file. + // ..... + USHORT PCIePowerSetting = 0; + /* code from windows, default value of rt30xxPowerMode = 0 + PCIePowerSetting = pAd->StaCfg.PSControl.field.rt30xxPowerMode; + */ + DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xx Read PowerLevelMode = 0x%x.\n", PCIePowerSetting)); + // 2. Check EnableNewPS + /* + if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) + PCIePowerSetting = 1; + */ + + if ((pAd->MACVersion&0xffff) <= 0x0211) + { + // Chip Version E only allow 1 + PCIePowerSetting = 1; + DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xx Write 0x83 Command = 0x%x.\n", PCIePowerSetting)); + AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSetting, 0x00); + } + else + { + // Chip Version F only allow 1 or 2 + if ((PCIePowerSetting > 2) || (PCIePowerSetting == 0)) + PCIePowerSetting = 1; + DBGPRINT(RT_DEBUG_TRACE, ("====> rt30xx Write 0x83 Command = 0x%x.\n", PCIePowerSetting)); + AsicSendCommandToMcu(pAd, 0x83, 0xff, (UCHAR)PCIePowerSetting, 0x00); + } + + } + + // Find Ralink PCIe Device's Express Capability Offset + pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP); + + if (pos != 0) + { + // Ralink PCIe Device's Link Control Register Offset + pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL; + pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, ®16); + Configuration = le2cpu16(reg16); + DBGPRINT(RT_DEBUG_TRACE, ("Read (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n", + pAd->RLnkCtrlOffset, Configuration)); + pAd->RLnkCtrlConfiguration = (Configuration & 0x103); + Configuration &= 0xfefc; + Configuration |= (0x0); + if ((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID) + ||(pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)) + { + reg16 = cpu2le16(Configuration); + pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, reg16); + DBGPRINT(RT_DEBUG_TRACE, ("Write (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n", + pos + PCI_EXP_LNKCTL, Configuration)); + } + + RTMPFindHostPCIDev(pAd); + if (pObj->parent_pci_dev) + { + USHORT vendor_id; + + pci_read_config_word(pObj->parent_pci_dev, PCI_VENDOR_ID, &vendor_id); + vendor_id = le2cpu16(vendor_id); + if (vendor_id == PCIBUS_INTEL_VENDOR) + bFindIntel = TRUE; + + // Find PCI-to-PCI Bridge Express Capability Offset + pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP); + + if (pos != 0) + { + BOOLEAN bChange = FALSE; + // PCI-to-PCI Bridge Link Control Register Offset + pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL; + pci_read_config_word(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, ®16); + Configuration = le2cpu16(reg16); + DBGPRINT(RT_DEBUG_TRACE, ("Read (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n", + pAd->HostLnkCtrlOffset, Configuration)); + pAd->HostLnkCtrlConfiguration = (Configuration & 0x103); + Configuration &= 0xfefc; + Configuration |= (0x0); + + switch (pObj->DeviceID) + { + case NIC2860_PCIe_DEVICE_ID: + case NIC2790_PCIe_DEVICE_ID: + bChange = TRUE; + break; + default: + break; + } + + if (bChange) + { + reg16 = cpu2le16(Configuration); + pci_write_config_word(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, reg16); + DBGPRINT(RT_DEBUG_TRACE, ("Write (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n", + pAd->HostLnkCtrlOffset, Configuration)); + } + } + else + { + pAd->HostLnkCtrlOffset = 0; + DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot find PCI-to-PCI Bridge PCI Express Capability!\n", __func__)); + } + } + } + else + { + pAd->RLnkCtrlOffset = 0; + pAd->HostLnkCtrlOffset = 0; + DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot find Ralink PCIe Device's PCI Express Capability!\n", __func__)); + } + + if (bFindIntel == FALSE) + { + DBGPRINT(RT_DEBUG_TRACE, ("Doesn't find Intel PCI host controller. \n")); + // Doesn't switch L0, L1, So set PCIePowerSaveLevel to 0xff + pAd->PCIePowerSaveLevel = 0xff; + if ((pAd->RLnkCtrlOffset != 0) + ) + { + pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, ®16); + Configuration = le2cpu16(reg16); + DBGPRINT(RT_DEBUG_TRACE, ("Read (Ralink 30xx PCIe Link Control Register) offset 0x%x = 0x%x\n", + pAd->RLnkCtrlOffset, Configuration)); + pAd->RLnkCtrlConfiguration = (Configuration & 0x103); + Configuration &= 0xfefc; + Configuration |= (0x0); + reg16 = cpu2le16(Configuration); + pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset, reg16); + DBGPRINT(RT_DEBUG_TRACE, ("Write (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n", + pos + PCI_EXP_LNKCTL, Configuration)); + } + } +} + +VOID RTMPFindHostPCIDev( + IN PRTMP_ADAPTER pAd) +{ + USHORT reg16; + UCHAR reg8; + UINT DevFn; + PPCI_DEV pPci_dev; + POS_COOKIE pObj; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + return; + + DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__)); + + pObj->parent_pci_dev = NULL; + if (pObj->pci_dev->bus->parent) + { + for (DevFn = 0; DevFn < 255; DevFn++) + { + pPci_dev = pci_get_slot(pObj->pci_dev->bus->parent, DevFn); + if (pPci_dev) + { + pci_read_config_word(pPci_dev, PCI_CLASS_DEVICE, ®16); + reg16 = le2cpu16(reg16); + pci_read_config_byte(pPci_dev, PCI_CB_CARD_BUS, ®8); + if ((reg16 == PCI_CLASS_BRIDGE_PCI) && + (reg8 == pObj->pci_dev->bus->number)) + { + pObj->parent_pci_dev = pPci_dev; + } + } + } + } +} + +/* + ======================================================================== + + Routine Description: + + Arguments: + Level = RESTORE_HALT : Restore PCI host and Ralink PCIe Link Control field to its default value. + Level = Other Value : Restore from dot11 power save or radio off status. And force PCI host Link Control fields to 0x1 + + ======================================================================== +*/ +VOID RTMPPCIeLinkCtrlValueRestore( + IN PRTMP_ADAPTER pAd, + IN UCHAR Level) +{ + USHORT PCIePowerSaveLevel, reg16; + USHORT Configuration; + POS_COOKIE pObj; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + return; + + if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID) + ||(pObj->DeviceID == NIC2790_PCIe_DEVICE_ID))) + return; + + DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__)); + PCIePowerSaveLevel = pAd->PCIePowerSaveLevel; + if ((PCIePowerSaveLevel&0xff) == 0xff) + { + DBGPRINT(RT_DEBUG_TRACE,("return \n")); + return; + } + + if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0)) + { + PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration); + if ((Configuration != 0) && + (Configuration != 0xFFFF)) + { + Configuration &= 0xfefc; + // If call from interface down, restore to orginial setting. + if (Level == RESTORE_CLOSE) + { + Configuration |= pAd->HostLnkCtrlConfiguration; + } + else + Configuration |= 0x0; + PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, Configuration); + DBGPRINT(RT_DEBUG_TRACE, ("Restore PCI host : offset 0x%x = 0x%x\n", pAd->HostLnkCtrlOffset, Configuration)); + } + else + DBGPRINT(RT_DEBUG_ERROR, ("Restore PCI host : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n", Configuration)); + } + + if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0)) + { + PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration); + if ((Configuration != 0) && + (Configuration != 0xFFFF)) + { + Configuration &= 0xfefc; + // If call from interface down, restore to orginial setting. + if (Level == RESTORE_CLOSE) + Configuration |= pAd->RLnkCtrlConfiguration; + else + Configuration |= 0x0; + PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration); + DBGPRINT(RT_DEBUG_TRACE, ("Restore Ralink : offset 0x%x = 0x%x\n", pAd->RLnkCtrlOffset, Configuration)); + } + else + DBGPRINT(RT_DEBUG_ERROR, ("Restore Ralink : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n", Configuration)); + } + + DBGPRINT(RT_DEBUG_TRACE,("%s <===\n", __func__)); +} + +/* + ======================================================================== + + Routine Description: + + Arguments: + Max : limit Host PCI and Ralink PCIe device's LINK CONTROL field's value. + Because now frequently set our device to mode 1 or mode 3 will cause problem. + + ======================================================================== +*/ +VOID RTMPPCIeLinkCtrlSetting( + IN PRTMP_ADAPTER pAd, + IN USHORT Max) +{ + USHORT PCIePowerSaveLevel, reg16; + USHORT Configuration; + POS_COOKIE pObj; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) + return; + + if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID) + ||(pObj->DeviceID == NIC2790_PCIe_DEVICE_ID))) + return; + + DBGPRINT(RT_DEBUG_TRACE,("%s===>\n", __func__)); + PCIePowerSaveLevel = pAd->PCIePowerSaveLevel; + if ((PCIePowerSaveLevel&0xff) == 0xff) + { + DBGPRINT(RT_DEBUG_TRACE,("return \n")); + return; + } + PCIePowerSaveLevel = PCIePowerSaveLevel>>6; + + + if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0)) + { + // first 2892 chip not allow to frequently set mode 3. will cause hang problem. + if (PCIePowerSaveLevel > Max) + PCIePowerSaveLevel = Max; + + PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration); + Configuration |= 0x100; + PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset, Configuration); + DBGPRINT(RT_DEBUG_TRACE, ("Write Ralink device : offset 0x%x = 0x%x\n", pAd->RLnkCtrlOffset, Configuration)); + } + + DBGPRINT(RT_DEBUG_TRACE,("RTMPPCIePowerLinkCtrl <==============\n")); +} Index: b/drivers/staging/rt2860/rt2860.h =================================================================== --- a/drivers/staging/rt2860/rt2860.h +++ /dev/null @@ -1,333 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - */ - -#ifndef __RT2860_H__ -#define __RT2860_H__ - -#define RT28xx_CHIP_NAME "RT2860" - -#define TXINFO_SIZE 0 -#define TXPADDING_SIZE 0 - -/* ----------------- EEPROM Related MACRO ----------------- */ -#define RT28xx_EEPROM_READ16(pAd, offset, var) \ - var = RTMP_EEPROM_READ16(pAd, offset) - -#define RT28xx_EEPROM_WRITE16(pAd, offset, var) \ - RTMP_EEPROM_WRITE16(pAd, offset, var) - -/* ----------------- TASK/THREAD Related MACRO ----------------- */ -#define RT28XX_TASK_THREAD_INIT(pAd, Status) \ - init_thread_task(pAd); NICInitTxRxRingAndBacklogQueue(pAd); \ - Status = NDIS_STATUS_SUCCESS; - -/* function declarations */ -#define IRQ_HANDLE_TYPE irqreturn_t - -IRQ_HANDLE_TYPE -rt2860_interrupt(int irq, void *dev_instance); - -/* ----------------- Frimware Related MACRO ----------------- */ -#define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \ - do{ \ - ULONG _i, _firm; \ - RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000); \ - \ - for(_i=0; _i<_FwLen; _i+=4) \ - { \ - _firm = _pFwImage[_i] + \ - (_pFwImage[_i+3] << 24) + \ - (_pFwImage[_i+2] << 16) + \ - (_pFwImage[_i+1] << 8); \ - RTMP_IO_WRITE32(_pAd, FIRMWARE_IMAGE_BASE + _i, _firm); \ - } \ - RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00000); \ - RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00001); \ - \ - /* initialize BBP R/W access agent */ \ - RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, 0); \ - RTMP_IO_WRITE32(_pAd, H2M_MAILBOX_CSR, 0); \ - }while(0) - -/* ----------------- TX Related MACRO ----------------- */ -#define RT28XX_START_DEQUEUE(pAd, QueIdx, irqFlags) do{}while(0) -#define RT28XX_STOP_DEQUEUE(pAd, QueIdx, irqFlags) do{}while(0) - - -#define RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \ - ((freeNum) >= (ULONG)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3)) /* rough estimate we will use 3 more descriptor. */ -#define RT28XX_RELEASE_DESC_RESOURCE(pAd, QueIdx) \ - do{}while(0) - -#define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \ - (((freeNum != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum<3)) - //(((freeNum) != (TX_RING_SIZE-1)) && (pAd->TxSwQueue[QueIdx].Number == 1 /*0*/)) - - -#define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen) \ - RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen) - -#define RTMP_PKT_TAIL_PADDING 0 - -#define fRTMP_ADAPTER_NEED_STOP_TX 0 - -#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ - /* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)*/ - -#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \ - RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) - -#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \ - RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) - -#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \ - RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber) - -#define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx) \ - RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx) - -#define HAL_LastTxIdx(_pAd, _QueIdx,_LastTxIdx) \ - /*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx)*/ - -#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx) \ - RTMP_IO_WRITE32((_pAd), TX_CTX_IDX0+((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx) -/* RtmpPCIDataKickOut(_pAd, _pTxBlk, _QueIdx)*/ - -#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \ - MiniportMMRequest(_pAd, _QueIdx, _pNullFrame, _frameLen) - -#define GET_TXRING_FREENO(_pAd, _QueIdx) \ - (_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[_QueIdx].TxCpuIdx) ? \ - (_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \ - : \ - (_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1); - - -#define GET_MGMTRING_FREENO(_pAd) \ - (_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx) ? \ - (_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \ - : \ - (_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1); - - -/* ----------------- RX Related MACRO ----------------- */ - -// no use -#define RT28XX_RCV_PKT_GET_INIT(pAd) -#define RT28XX_RV_A_BUF_END -//#define RT28XX_RV_ALL_BUF_END - - -/* ----------------- ASIC Related MACRO ----------------- */ -// no use -#define RT28XX_DMA_POST_WRITE(pAd) - -// reset MAC of a station entry to 0x000000000000 -#define RT28XX_STA_ENTRY_MAC_RESET(pAd, Wcid) \ - AsicDelWcidTab(pAd, Wcid); - -// add this entry into ASIC RX WCID search table -#define RT28XX_STA_ENTRY_ADD(pAd, pEntry) \ - AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr); - -// remove Pair-wise key material from ASIC -#define RT28XX_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid) \ - AsicRemovePairwiseKeyEntry(pAd, BssIdx, (UCHAR)Wcid); - -// add Client security information into ASIC WCID table and IVEIV table -#define RT28XX_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry) \ - RTMPAddWcidAttributeEntry(pAd, apidx, KeyID, \ - pAd->SharedKey[apidx][KeyID].CipherAlg, pEntry); - -#define RT28XX_SECURITY_KEY_ADD(pAd, apidx, KeyID, pEntry) \ - { /* update pairwise key information to ASIC Shared Key Table */ \ - AsicAddSharedKeyEntry(pAd, apidx, KeyID, \ - pAd->SharedKey[apidx][KeyID].CipherAlg, \ - pAd->SharedKey[apidx][KeyID].Key, \ - pAd->SharedKey[apidx][KeyID].TxMic, \ - pAd->SharedKey[apidx][KeyID].RxMic); \ - /* update ASIC WCID attribute table and IVEIV table */ \ - RTMPAddWcidAttributeEntry(pAd, apidx, KeyID, \ - pAd->SharedKey[apidx][KeyID].CipherAlg, \ - pEntry); } - - -// Insert the BA bitmap to ASIC for the Wcid entry -#define RT28XX_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \ - do{ \ - UINT32 _Value = 0, _Offset; \ - _Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4; \ - RTMP_IO_READ32((_pAd), _Offset, &_Value); \ - _Value |= (0x10000<<(_TID)); \ - RTMP_IO_WRITE32((_pAd), _Offset, _Value); \ - }while(0) - - -// Remove the BA bitmap from ASIC for the Wcid entry -// bitmap field starts at 0x10000 in ASIC WCID table -#define RT28XX_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \ - do{ \ - UINT32 _Value = 0, _Offset; \ - _Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4; \ - RTMP_IO_READ32((_pAd), _Offset, &_Value); \ - _Value &= (~(0x10000 << (_TID))); \ - RTMP_IO_WRITE32((_pAd), _Offset, _Value); \ - }while(0) - - -/* ----------------- PCI/USB Related MACRO ----------------- */ - -#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p) \ - ((POS_COOKIE)handle)->pci_dev = dev_p; - -// set driver data -#define RT28XX_DRVDATA_SET(_a) pci_set_drvdata(_a, net_dev); - -#define RT28XX_UNMAP() \ -{ if (net_dev->base_addr) { \ - iounmap((void *)(net_dev->base_addr)); \ - release_mem_region(pci_resource_start(dev_p, 0), \ - pci_resource_len(dev_p, 0)); } \ - if (net_dev->irq) pci_release_regions(dev_p); } - -#ifdef PCI_MSI_SUPPORT -#define RTMP_MSI_ENABLE(_pAd) \ -{ POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \ - (_pAd)->HaveMsi = pci_enable_msi(_pObj->pci_dev) == 0 ? TRUE : FALSE; } - -#define RTMP_MSI_DISABLE(_pAd) \ -{ POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \ - if (_pAd->HaveMsi == TRUE) \ - pci_disable_msi(_pObj->pci_dev); \ - _pAd->HaveMsi = FALSE; } -#else -#define RTMP_MSI_ENABLE(_pAd) -#define RTMP_MSI_DISABLE(_pAd) -#endif // PCI_MSI_SUPPORT // - -#define SA_SHIRQ IRQF_SHARED - -#define RT28XX_IRQ_REQUEST(net_dev) \ -{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->ml_priv); \ - POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \ - RTMP_MSI_ENABLE(_pAd); \ - if ((retval = request_irq(_pObj->pci_dev->irq, \ - rt2860_interrupt, SA_SHIRQ, \ - (net_dev)->name, (net_dev)))) { \ - printk("RT2860: request_irq ERROR(%d)\n", retval); \ - return retval; } } - -#define RT28XX_IRQ_RELEASE(net_dev) \ -{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->ml_priv); \ - POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \ - synchronize_irq(_pObj->pci_dev->irq); \ - free_irq(_pObj->pci_dev->irq, (net_dev)); \ - RTMP_MSI_DISABLE(_pAd); } - -#define RT28XX_IRQ_INIT(pAd) \ - { pAd->int_enable_reg = ((DELAYINTMASK) | \ - (RxINT|TxDataInt|TxMgmtInt)) & ~(0x03); \ - pAd->int_disable_mask = 0; \ - pAd->int_pending = 0; } - -#define RT28XX_IRQ_ENABLE(pAd) \ - { /* clear garbage ints */ \ - RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff); \ - NICEnableInterrupt(pAd); } - -#define RT28XX_PUT_DEVICE(dev_p) - - -/* ----------------- MLME Related MACRO ----------------- */ -#define RT28XX_MLME_HANDLER(pAd) MlmeHandler(pAd) - -#define RT28XX_MLME_PRE_SANITY_CHECK(pAd) - -#define RT28XX_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \ - RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100); - -#define RT28XX_MLME_RESET_STATE_MACHINE(pAd) \ - MlmeRestartStateMachine(pAd) - -#define RT28XX_HANDLE_COUNTER_MEASURE(_pAd, _pEntry) \ - HandleCounterMeasure(_pAd, _pEntry) - -/* ----------------- Power Save Related MACRO ----------------- */ -#define RT28XX_PS_POLL_ENQUEUE(pAd) EnqueuePsPoll(pAd) - -// -// Device ID & Vendor ID, these values should match EEPROM value -// -#define NIC2860_PCI_DEVICE_ID 0x0601 -#define NIC2860_PCIe_DEVICE_ID 0x0681 -#define NIC2760_PCI_DEVICE_ID 0x0701 // 1T/2R Cardbus ??? -#define NIC2790_PCIe_DEVICE_ID 0x0781 // 1T/2R miniCard - -#define NIC_PCI_VENDOR_ID 0x1814 - -#define VEN_AWT_PCIe_DEVICE_ID 0x1059 -#define VEN_AWT_PCI_VENDOR_ID 0x1A3B - -#define EDIMAX_PCI_VENDOR_ID 0x1432 - -// For RTMPPCIePowerLinkCtrlRestore () function -#define RESTORE_HALT 1 -#define RESTORE_WAKEUP 2 -#define RESTORE_CLOSE 3 - -#define PowerSafeCID 1 -#define PowerRadioOffCID 2 -#define PowerWakeCID 3 -#define CID0MASK 0x000000ff -#define CID1MASK 0x0000ff00 -#define CID2MASK 0x00ff0000 -#define CID3MASK 0xff000000 - -#define PCI_REG_READ_WORD(pci_dev, offset, Configuration) \ - if (pci_read_config_word(pci_dev, offset, ®16) == 0) \ - Configuration = le2cpu16(reg16); \ - else \ - Configuration = 0; - -#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration) \ - reg16 = cpu2le16(Configuration); \ - pci_write_config_word(pci_dev, offset, reg16); \ - -#define RT28XX_STA_FORCE_WAKEUP(pAd, Level) \ - RT28xxPciStaAsicForceWakeup(pAd, Level); - -#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \ - RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp); - -#define RT28XX_MLME_RADIO_ON(pAd) \ - RT28xxPciMlmeRadioOn(pAd); - -#define RT28XX_MLME_RADIO_OFF(pAd) \ - RT28xxPciMlmeRadioOFF(pAd); - -#endif //__RT2860_H__ - Index: b/drivers/staging/rt2860/rt28xx.h =================================================================== --- a/drivers/staging/rt2860/rt28xx.h +++ /dev/null @@ -1,1688 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - - Module Name: - rt28xx.h - - Abstract: - RT28xx ASIC related definition & structures - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Jan Lee Jan-3-2006 created for RT2860c -*/ - -#ifndef __RT28XX_H__ -#define __RT28XX_H__ - - -// -// PCI registers - base address 0x0000 -// -#define PCI_CFG 0x0000 -#define PCI_EECTRL 0x0004 -#define PCI_MCUCTRL 0x0008 - -typedef int NTSTATUS; - -#define OPT_14 0x114 - -// -// SCH/DMA registers - base address 0x0200 -// -// INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit -// -#define DMA_CSR0 0x200 -#define INT_SOURCE_CSR 0x200 -typedef union _INT_SOURCE_CSR_STRUC { - struct { - UINT32 RxDelayINT:1; - UINT32 TxDelayINT:1; - UINT32 RxDone:1; - UINT32 Ac0DmaDone:1;//4 - UINT32 Ac1DmaDone:1; - UINT32 Ac2DmaDone:1; - UINT32 Ac3DmaDone:1; - UINT32 HccaDmaDone:1; // bit7 - UINT32 MgmtDmaDone:1; - UINT32 MCUCommandINT:1;//bit 9 - UINT32 RxTxCoherent:1; - UINT32 TBTTInt:1; - UINT32 PreTBTT:1; - UINT32 TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c - UINT32 AutoWakeup:1;//bit14 - UINT32 GPTimer:1; - UINT32 RxCoherent:1;//bit16 - UINT32 TxCoherent:1; - UINT32 :14; - } field; - UINT32 word; -} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC; - -// -// INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF -// -#define INT_MASK_CSR 0x204 -typedef union _INT_MASK_CSR_STRUC { - struct { - UINT32 RXDelay_INT_MSK:1; - UINT32 TxDelay:1; - UINT32 RxDone:1; - UINT32 Ac0DmaDone:1; - UINT32 Ac1DmaDone:1; - UINT32 Ac2DmaDone:1; - UINT32 Ac3DmaDone:1; - UINT32 HccaDmaDone:1; - UINT32 MgmtDmaDone:1; - UINT32 MCUCommandINT:1; - UINT32 :20; - UINT32 RxCoherent:1; - UINT32 TxCoherent:1; - } field; - UINT32 word; -} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC; - -#define WPDMA_GLO_CFG 0x208 -typedef union _WPDMA_GLO_CFG_STRUC { - struct { - UINT32 EnableTxDMA:1; - UINT32 TxDMABusy:1; - UINT32 EnableRxDMA:1; - UINT32 RxDMABusy:1; - UINT32 WPDMABurstSIZE:2; - UINT32 EnTXWriteBackDDONE:1; - UINT32 BigEndian:1; - UINT32 RXHdrScater:8; - UINT32 HDR_SEG_LEN:16; - } field; - UINT32 word; -} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC; - -#define WPDMA_RST_IDX 0x20c -typedef union _WPDMA_RST_IDX_STRUC { - struct { - UINT32 RST_DTX_IDX0:1; - UINT32 RST_DTX_IDX1:1; - UINT32 RST_DTX_IDX2:1; - UINT32 RST_DTX_IDX3:1; - UINT32 RST_DTX_IDX4:1; - UINT32 RST_DTX_IDX5:1; - UINT32 rsv:10; - UINT32 RST_DRX_IDX0:1; - UINT32 :15; - } field; - UINT32 word; -} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC; - -#define DELAY_INT_CFG 0x0210 -typedef union _DELAY_INT_CFG_STRUC { - struct { - UINT32 RXMAX_PTIME:8; - UINT32 RXMAX_PINT:7; - UINT32 RXDLY_INT_EN:1; - UINT32 TXMAX_PTIME:8; - UINT32 TXMAX_PINT:7; - UINT32 TXDLY_INT_EN:1; - } field; - UINT32 word; -} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC; - -#define WMM_AIFSN_CFG 0x0214 -typedef union _AIFSN_CSR_STRUC { - struct { - UINT32 Aifsn0:4; // for AC_BE - UINT32 Aifsn1:4; // for AC_BK - UINT32 Aifsn2:4; // for AC_VI - UINT32 Aifsn3:4; // for AC_VO - UINT32 Rsv:16; - } field; - UINT32 word; -} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC; - -// -// CWMIN_CSR: CWmin for each EDCA AC -// -#define WMM_CWMIN_CFG 0x0218 -typedef union _CWMIN_CSR_STRUC { - struct { - UINT32 Cwmin0:4; // for AC_BE - UINT32 Cwmin1:4; // for AC_BK - UINT32 Cwmin2:4; // for AC_VI - UINT32 Cwmin3:4; // for AC_VO - UINT32 Rsv:16; - } field; - UINT32 word; -} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC; - -// -// CWMAX_CSR: CWmin for each EDCA AC -// -#define WMM_CWMAX_CFG 0x021c -typedef union _CWMAX_CSR_STRUC { - struct { - UINT32 Cwmax0:4; // for AC_BE - UINT32 Cwmax1:4; // for AC_BK - UINT32 Cwmax2:4; // for AC_VI - UINT32 Cwmax3:4; // for AC_VO - UINT32 Rsv:16; - } field; - UINT32 word; -} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC; - -// -// AC_TXOP_CSR0: AC_BK/AC_BE TXOP register -// -#define WMM_TXOP0_CFG 0x0220 -typedef union _AC_TXOP_CSR0_STRUC { - struct { - USHORT Ac0Txop; // for AC_BK, in unit of 32us - USHORT Ac1Txop; // for AC_BE, in unit of 32us - } field; - UINT32 word; -} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC; - -// -// AC_TXOP_CSR1: AC_VO/AC_VI TXOP register -// -#define WMM_TXOP1_CFG 0x0224 -typedef union _AC_TXOP_CSR1_STRUC { - struct { - USHORT Ac2Txop; // for AC_VI, in unit of 32us - USHORT Ac3Txop; // for AC_VO, in unit of 32us - } field; - UINT32 word; -} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC; - -#define RINGREG_DIFF 0x10 -#define GPIO_CTRL_CFG 0x0228 //MAC_CSR13 -#define MCU_CMD_CFG 0x022c -#define TX_BASE_PTR0 0x0230 //AC_BK base address -#define TX_MAX_CNT0 0x0234 -#define TX_CTX_IDX0 0x0238 -#define TX_DTX_IDX0 0x023c -#define TX_BASE_PTR1 0x0240 //AC_BE base address -#define TX_MAX_CNT1 0x0244 -#define TX_CTX_IDX1 0x0248 -#define TX_DTX_IDX1 0x024c -#define TX_BASE_PTR2 0x0250 //AC_VI base address -#define TX_MAX_CNT2 0x0254 -#define TX_CTX_IDX2 0x0258 -#define TX_DTX_IDX2 0x025c -#define TX_BASE_PTR3 0x0260 //AC_VO base address -#define TX_MAX_CNT3 0x0264 -#define TX_CTX_IDX3 0x0268 -#define TX_DTX_IDX3 0x026c -#define TX_BASE_PTR4 0x0270 //HCCA base address -#define TX_MAX_CNT4 0x0274 -#define TX_CTX_IDX4 0x0278 -#define TX_DTX_IDX4 0x027c -#define TX_BASE_PTR5 0x0280 //MGMT base address -#define TX_MAX_CNT5 0x0284 -#define TX_CTX_IDX5 0x0288 -#define TX_DTX_IDX5 0x028c -#define TX_MGMTMAX_CNT TX_MAX_CNT5 -#define TX_MGMTCTX_IDX TX_CTX_IDX5 -#define TX_MGMTDTX_IDX TX_DTX_IDX5 -#define RX_BASE_PTR 0x0290 //RX base address -#define RX_MAX_CNT 0x0294 -#define RX_CRX_IDX 0x0298 -#define RX_DRX_IDX 0x029c -#define USB_DMA_CFG 0x02a0 - -typedef union _USB_DMA_CFG_STRUC { - struct { - UINT32 RxBulkAggTOut:8; //Rx Bulk Aggregation TimeOut in unit of 33ns - UINT32 RxBulkAggLmt:8; //Rx Bulk Aggregation Limit in unit of 256 bytes - UINT32 phyclear:1; //phy watch dog enable. write 1 - UINT32 rsv:2; - UINT32 TxClear:1; //Clear USB DMA TX path - UINT32 TxopHalt:1; //Halt TXOP count down when TX buffer is full. - UINT32 RxBulkAggEn:1; //Enable Rx Bulk Aggregation - UINT32 RxBulkEn:1; //Enable USB DMA Rx - UINT32 TxBulkEn:1; //Enable USB DMA Tx - UINT32 EpoutValid:6; //OUT endpoint data valid - UINT32 RxBusy:1; //USB DMA RX FSM busy - UINT32 TxBusy:1; //USB DMA TX FSM busy - } field; - UINT32 word; -} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC; - -// -// 3 PBF registers -// -// -// Most are for debug. Driver doesn't touch PBF register. -#define PBF_SYS_CTRL 0x0400 -#define PBF_CFG 0x0408 -#define PBF_MAX_PCNT 0x040C -#define PBF_CTRL 0x0410 -#define PBF_INT_STA 0x0414 -#define PBF_INT_ENA 0x0418 -#define TXRXQ_PCNT 0x0438 -#define PBF_DBG 0x043c -#define PBF_CAP_CTRL 0x0440 - -// eFuse registers -#define EFUSE_CTRL 0x0580 -#define EFUSE_DATA0 0x0590 -#define EFUSE_DATA1 0x0594 -#define EFUSE_DATA2 0x0598 -#define EFUSE_DATA3 0x059c -#define EFUSE_USAGE_MAP_START 0x2d0 -#define EFUSE_USAGE_MAP_END 0x2fc -#define EFUSE_TAG 0x2fe -#define EFUSE_USAGE_MAP_SIZE 45 - -typedef union _EFUSE_CTRL_STRUC { - struct { - UINT32 EFSROM_AOUT:6; - UINT32 EFSROM_MODE:2; - UINT32 EFSROM_LDO_OFF_TIME:6; - UINT32 EFSROM_LDO_ON_TIME:2; - UINT32 EFSROM_AIN:10; - UINT32 RESERVED:4; - UINT32 EFSROM_KICK:1; - UINT32 SEL_EFUSE:1; - } field; - UINT32 word; -} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC; - -#define LDO_CFG0 0x05d4 -#define GPIO_SWITCH 0x05dc - -// -// 4 MAC registers -// -// -// 4.1 MAC SYSTEM configuration registers (offset:0x1000) -// -#define MAC_CSR0 0x1000 -typedef union _ASIC_VER_ID_STRUC { - struct { - USHORT ASICRev; // reversion : 0 - USHORT ASICVer; // version : 2860 - } field; - UINT32 word; -} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC; - -#define MAC_SYS_CTRL 0x1004 //MAC_CSR1 -#define MAC_ADDR_DW0 0x1008 // MAC ADDR DW0 -#define MAC_ADDR_DW1 0x100c // MAC ADDR DW1 -// -// MAC_CSR2: STA MAC register 0 -// -typedef union _MAC_DW0_STRUC { - struct { - UCHAR Byte0; // MAC address byte 0 - UCHAR Byte1; // MAC address byte 1 - UCHAR Byte2; // MAC address byte 2 - UCHAR Byte3; // MAC address byte 3 - } field; - UINT32 word; -} MAC_DW0_STRUC, *PMAC_DW0_STRUC; - -// -// MAC_CSR3: STA MAC register 1 -// -typedef union _MAC_DW1_STRUC { - struct { - UCHAR Byte4; // MAC address byte 4 - UCHAR Byte5; // MAC address byte 5 - UCHAR U2MeMask; - UCHAR Rsvd1; - } field; - UINT32 word; -} MAC_DW1_STRUC, *PMAC_DW1_STRUC; - -#define MAC_BSSID_DW0 0x1010 // MAC BSSID DW0 -#define MAC_BSSID_DW1 0x1014 // MAC BSSID DW1 - -// -// MAC_CSR5: BSSID register 1 -// -typedef union _MAC_CSR5_STRUC { - struct { - UCHAR Byte4; // BSSID byte 4 - UCHAR Byte5; // BSSID byte 5 - USHORT BssIdMask:2; // 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID - USHORT MBssBcnNum:3; - USHORT Rsvd:11; - } field; - UINT32 word; -} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC; - -#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 -#define BBP_CSR_CFG 0x101c // -// -// BBP_CSR_CFG: BBP serial control register -// -typedef union _BBP_CSR_CFG_STRUC { - struct { - UINT32 Value:8; // Register value to program into BBP - UINT32 RegNum:8; // Selected BBP register - UINT32 fRead:1; // 0: Write BBP, 1: Read BBP - UINT32 Busy:1; // 1: ASIC is busy execute BBP programming. - UINT32 BBP_PAR_DUR:1; // 0: 4 MAC clock cycles 1: 8 MAC clock cycles - UINT32 BBP_RW_MODE:1; // 0: use serial mode 1:parallel - UINT32 :12; - } field; - UINT32 word; -} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC; - -#define RF_CSR_CFG0 0x1020 -// -// RF_CSR_CFG: RF control register -// -typedef union _RF_CSR_CFG0_STRUC { - struct { - UINT32 RegIdAndContent:24; // Register value to program into BBP - UINT32 bitwidth:5; // Selected BBP register - UINT32 StandbyMode:1; // 0: high when stand by 1: low when standby - UINT32 Sel:1; // 0:RF_LE0 activate 1:RF_LE1 activate - UINT32 Busy:1; // 0: idle 1: 8busy - } field; - UINT32 word; -} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC; - -#define RF_CSR_CFG1 0x1024 -typedef union _RF_CSR_CFG1_STRUC { - struct { - UINT32 RegIdAndContent:24; // Register value to program into BBP - 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) - UINT32 rsv:7; // 0: idle 1: 8busy - } field; - UINT32 word; -} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC; - -#define RF_CSR_CFG2 0x1028 // -typedef union _RF_CSR_CFG2_STRUC { - struct { - UINT32 RegIdAndContent:24; // Register value to program into BBP - UINT32 rsv:8; // 0: idle 1: 8busy - } field; - UINT32 word; -} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC; - -#define LED_CFG 0x102c // MAC_CSR14 -typedef union _LED_CFG_STRUC { - struct { - UINT32 OnPeriod:8; // blinking on period unit 1ms - UINT32 OffPeriod:8; // blinking off period unit 1ms - UINT32 SlowBlinkPeriod:6; // slow blinking period. unit:1ms - UINT32 rsv:2; - UINT32 RLedMode:2; // red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on - UINT32 GLedMode:2; // green Led Mode - UINT32 YLedMode:2; // yellow Led Mode - UINT32 LedPolar:1; // Led Polarity. 0: active low1: active high - UINT32 :1; - } field; - UINT32 word; -} LED_CFG_STRUC, *PLED_CFG_STRUC; - -// -// 4.2 MAC TIMING configuration registers (offset:0x1100) -// -#define XIFS_TIME_CFG 0x1100 // MAC_CSR8 MAC_CSR9 -typedef union _IFS_SLOT_CFG_STRUC { - struct { - UINT32 CckmSifsTime:8; // unit 1us. Applied after CCK RX/TX - UINT32 OfdmSifsTime:8; // unit 1us. Applied after OFDM RX/TX - UINT32 OfdmXifsTime:4; //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND - UINT32 EIFS:9; // unit 1us - UINT32 BBRxendEnable:1; // reference RXEND signal to begin XIFS defer - UINT32 rsv:2; - } field; - UINT32 word; -} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC; - -#define BKOFF_SLOT_CFG 0x1104 // mac_csr9 last 8 bits -#define NAV_TIME_CFG 0x1108 // NAV (MAC_CSR15) -#define CH_TIME_CFG 0x110C // Count as channel busy -#define PBF_LIFE_TIMER 0x1110 //TX/RX MPDU timestamp timer (free run)Unit: 1us -#define BCN_TIME_CFG 0x1114 // TXRX_CSR9 - -#define BCN_OFFSET0 0x042C -#define BCN_OFFSET1 0x0430 - -// -// BCN_TIME_CFG : Synchronization control register -// -typedef union _BCN_TIME_CFG_STRUC { - struct { - UINT32 BeaconInterval:16; // in unit of 1/16 TU - UINT32 bTsfTicking:1; // Enable TSF auto counting - UINT32 TsfSyncMode:2; // Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode - UINT32 bTBTTEnable:1; - UINT32 bBeaconGen:1; // Enable beacon generator - UINT32 :3; - UINT32 TxTimestampCompensate:8; - } field; - UINT32 word; -} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC; - -#define TBTT_SYNC_CFG 0x1118 // txrx_csr10 -#define TSF_TIMER_DW0 0x111C // Local TSF timer lsb 32 bits. Read-only -#define TSF_TIMER_DW1 0x1120 // msb 32 bits. Read-only. -#define TBTT_TIMER 0x1124 // TImer remains till next TBTT. Read-only. TXRX_CSR14 -#define INT_TIMER_CFG 0x1128 // -#define INT_TIMER_EN 0x112c // GP-timer and pre-tbtt Int enable -#define CH_IDLE_STA 0x1130 // channel idle time -#define CH_BUSY_STA 0x1134 // channle busy time -// -// 4.2 MAC POWER configuration registers (offset:0x1200) -// -#define MAC_STATUS_CFG 0x1200 // old MAC_CSR12 -#define PWR_PIN_CFG 0x1204 // old MAC_CSR12 -#define AUTO_WAKEUP_CFG 0x1208 // old MAC_CSR10 -// -// AUTO_WAKEUP_CFG: Manual power control / status register -// -typedef union _AUTO_WAKEUP_STRUC { - struct { - UINT32 AutoLeadTime:8; - UINT32 NumofSleepingTbtt:7; // ForceWake has high privilege than PutToSleep when both set - UINT32 EnableAutoWakeup:1; // 0:sleep, 1:awake - UINT32 :16; - } field; - UINT32 word; -} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC; - -// -// 4.3 MAC TX configuration registers (offset:0x1300) -// - -#define EDCA_AC0_CFG 0x1300 //AC_TXOP_CSR0 0x3474 -#define EDCA_AC1_CFG 0x1304 -#define EDCA_AC2_CFG 0x1308 -#define EDCA_AC3_CFG 0x130c -typedef union _EDCA_AC_CFG_STRUC { - struct { - UINT32 AcTxop:8; // in unit of 32us - UINT32 Aifsn:4; // # of slot time - UINT32 Cwmin:4; // - UINT32 Cwmax:4; //unit power of 2 - UINT32 :12; // - } field; - UINT32 word; -} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC; - -#define EDCA_TID_AC_MAP 0x1310 -#define TX_PWR_CFG_0 0x1314 -#define TX_PWR_CFG_1 0x1318 -#define TX_PWR_CFG_2 0x131C -#define TX_PWR_CFG_3 0x1320 -#define TX_PWR_CFG_4 0x1324 -#define TX_PIN_CFG 0x1328 -#define TX_BAND_CFG 0x132c // 0x1 use upper 20MHz. 0 juse lower 20MHz -#define TX_SW_CFG0 0x1330 -#define TX_SW_CFG1 0x1334 -#define TX_SW_CFG2 0x1338 -#define TXOP_THRES_CFG 0x133c -#define TXOP_CTRL_CFG 0x1340 -#define TX_RTS_CFG 0x1344 - -typedef union _TX_RTS_CFG_STRUC { - struct { - UINT32 AutoRtsRetryLimit:8; - UINT32 RtsThres:16; // unit:byte - UINT32 RtsFbkEn:1; // enable rts rate fallback - UINT32 rsv:7; // 1: HT non-STBC control frame enable - } field; - UINT32 word; -} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC; - -#define TX_TIMEOUT_CFG 0x1348 -typedef union _TX_TIMEOUT_CFG_STRUC { - struct { - UINT32 rsv:4; - UINT32 MpduLifeTime:4; // expiration time = 2^(9+MPDU LIFE TIME) us - UINT32 RxAckTimeout:8; // unit:slot. Used for TX precedure - UINT32 TxopTimeout:8; //TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT) - UINT32 rsv2:8; // 1: HT non-STBC control frame enable - } field; - UINT32 word; -} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC; - -#define TX_RTY_CFG 0x134c -typedef union PACKED _TX_RTY_CFG_STRUC { - struct { - UINT32 ShortRtyLimit:8; // short retry limit - UINT32 LongRtyLimit:8; //long retry limit - UINT32 LongRtyThre:12; // Long retry threshoold - UINT32 NonAggRtyMode:1; // Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer - UINT32 AggRtyMode:1; // Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer - UINT32 TxautoFBEnable:1; // Tx retry PHY rate auto fallback enable - UINT32 rsv:1; // 1: HT non-STBC control frame enable - } field; - UINT32 word; -} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC; - -#define TX_LINK_CFG 0x1350 -typedef union PACKED _TX_LINK_CFG_STRUC { - struct PACKED { - UINT32 RemoteMFBLifeTime:8; //remote MFB life time. unit : 32us - UINT32 MFBEnable:1; // TX apply remote MFB 1:enable - UINT32 RemoteUMFSEnable:1; // remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7) - UINT32 TxMRQEn:1; // MCS request TX enable - UINT32 TxRDGEn:1; // RDG TX enable - UINT32 TxCFAckEn:1; // Piggyback CF-ACK enable - UINT32 rsv:3; // - UINT32 RemotMFB:8; // remote MCS feedback - UINT32 RemotMFS:8; //remote MCS feedback sequence number - } field; - UINT32 word; -} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC; - -#define HT_FBK_CFG0 0x1354 -typedef union PACKED _HT_FBK_CFG0_STRUC { - struct { - UINT32 HTMCS0FBK:4; - UINT32 HTMCS1FBK:4; - UINT32 HTMCS2FBK:4; - UINT32 HTMCS3FBK:4; - UINT32 HTMCS4FBK:4; - UINT32 HTMCS5FBK:4; - UINT32 HTMCS6FBK:4; - UINT32 HTMCS7FBK:4; - } field; - UINT32 word; -} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC; - -#define HT_FBK_CFG1 0x1358 -typedef union _HT_FBK_CFG1_STRUC { - struct { - UINT32 HTMCS8FBK:4; - UINT32 HTMCS9FBK:4; - UINT32 HTMCS10FBK:4; - UINT32 HTMCS11FBK:4; - UINT32 HTMCS12FBK:4; - UINT32 HTMCS13FBK:4; - UINT32 HTMCS14FBK:4; - UINT32 HTMCS15FBK:4; - } field; - UINT32 word; -} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC; - -#define LG_FBK_CFG0 0x135c -typedef union _LG_FBK_CFG0_STRUC { - struct { - UINT32 OFDMMCS0FBK:4; //initial value is 0 - UINT32 OFDMMCS1FBK:4; //initial value is 0 - UINT32 OFDMMCS2FBK:4; //initial value is 1 - UINT32 OFDMMCS3FBK:4; //initial value is 2 - UINT32 OFDMMCS4FBK:4; //initial value is 3 - UINT32 OFDMMCS5FBK:4; //initial value is 4 - UINT32 OFDMMCS6FBK:4; //initial value is 5 - UINT32 OFDMMCS7FBK:4; //initial value is 6 - } field; - UINT32 word; -} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC; - -#define LG_FBK_CFG1 0x1360 -typedef union _LG_FBK_CFG1_STRUC { - struct { - UINT32 CCKMCS0FBK:4; //initial value is 0 - UINT32 CCKMCS1FBK:4; //initial value is 0 - UINT32 CCKMCS2FBK:4; //initial value is 1 - UINT32 CCKMCS3FBK:4; //initial value is 2 - UINT32 rsv:16; - } field; - UINT32 word; -} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC; - -//======================================================= -//================ Protection Paramater================================ -//======================================================= -#define CCK_PROT_CFG 0x1364 //CCK Protection -#define ASIC_SHORTNAV 1 -#define ASIC_LONGNAV 2 -#define ASIC_RTS 1 -#define ASIC_CTS 2 -typedef union _PROT_CFG_STRUC { - struct { - UINT32 ProtectRate:16; //Protection control frame rate for CCK TX(RTS/CTS/CFEnd). - UINT32 ProtectCtrl:2; //Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv - UINT32 ProtectNav:2; //TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv - UINT32 TxopAllowCck:1; //CCK TXOP allowance.0:disallow. - UINT32 TxopAllowOfdm:1; //CCK TXOP allowance.0:disallow. - UINT32 TxopAllowMM20:1; //CCK TXOP allowance. 0:disallow. - UINT32 TxopAllowMM40:1; //CCK TXOP allowance.0:disallow. - UINT32 TxopAllowGF20:1; //CCK TXOP allowance.0:disallow. - UINT32 TxopAllowGF40:1; //CCK TXOP allowance.0:disallow. - UINT32 RTSThEn:1; //RTS threshold enable on CCK TX - UINT32 rsv:5; - } field; - UINT32 word; -} PROT_CFG_STRUC, *PPROT_CFG_STRUC; - -#define OFDM_PROT_CFG 0x1368 //OFDM Protection -#define MM20_PROT_CFG 0x136C //MM20 Protection -#define MM40_PROT_CFG 0x1370 //MM40 Protection -#define GF20_PROT_CFG 0x1374 //GF20 Protection -#define GF40_PROT_CFG 0x1378 //GR40 Protection -#define EXP_CTS_TIME 0x137C // -#define EXP_ACK_TIME 0x1380 // - -// -// 4.4 MAC RX configuration registers (offset:0x1400) -// -#define RX_FILTR_CFG 0x1400 //TXRX_CSR0 -#define AUTO_RSP_CFG 0x1404 //TXRX_CSR4 -// -// TXRX_CSR4: Auto-Responder/ -// -typedef union _AUTO_RSP_CFG_STRUC { - struct { - UINT32 AutoResponderEnable:1; - UINT32 BACAckPolicyEnable:1; // 0:long, 1:short preamble - UINT32 CTS40MMode:1; // Response CTS 40MHz duplicate mode - UINT32 CTS40MRef:1; // Response CTS 40MHz duplicate mode - UINT32 AutoResponderPreamble:1; // 0:long, 1:short preamble - UINT32 rsv:1; // Power bit value in conrtrol frame - UINT32 DualCTSEn:1; // Power bit value in conrtrol frame - UINT32 AckCtsPsmBit:1; // Power bit value in conrtrol frame - UINT32 :24; - } field; - UINT32 word; -} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC; - -#define LEGACY_BASIC_RATE 0x1408 // TXRX_CSR5 0x3054 -#define HT_BASIC_RATE 0x140c -#define HT_CTRL_CFG 0x1410 -#define SIFS_COST_CFG 0x1414 -#define RX_PARSER_CFG 0x1418 //Set NAV for all received frames - -// -// 4.5 MAC Security configuration (offset:0x1500) -// -#define TX_SEC_CNT0 0x1500 // -#define RX_SEC_CNT0 0x1504 // -#define CCMP_FC_MUTE 0x1508 // -// -// 4.6 HCCA/PSMP (offset:0x1600) -// -#define TXOP_HLDR_ADDR0 0x1600 -#define TXOP_HLDR_ADDR1 0x1604 -#define TXOP_HLDR_ET 0x1608 -#define QOS_CFPOLL_RA_DW0 0x160c -#define QOS_CFPOLL_A1_DW1 0x1610 -#define QOS_CFPOLL_QC 0x1614 -// -// 4.7 MAC Statistis registers (offset:0x1700) -// -#define RX_STA_CNT0 0x1700 // -#define RX_STA_CNT1 0x1704 // -#define RX_STA_CNT2 0x1708 // - -// -// RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count -// -typedef union _RX_STA_CNT0_STRUC { - struct { - USHORT CrcErr; - USHORT PhyErr; - } field; - UINT32 word; -} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC; - -// -// RX_STA_CNT1_STRUC: RX False CCA count & RX LONG frame count -// -typedef union _RX_STA_CNT1_STRUC { - struct { - USHORT FalseCca; - USHORT PlcpErr; - } field; - UINT32 word; -} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC; - -// -// RX_STA_CNT2_STRUC: -// -typedef union _RX_STA_CNT2_STRUC { - struct { - USHORT RxDupliCount; - USHORT RxFifoOverflowCount; - } field; - UINT32 word; -} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC; - -#define TX_STA_CNT0 0x170C // -// -// STA_CSR3: TX Beacon count -// -typedef union _TX_STA_CNT0_STRUC { - struct { - USHORT TxFailCount; - USHORT TxBeaconCount; - } field; - UINT32 word; -} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC; - -#define TX_STA_CNT1 0x1710 // -// -// TX_STA_CNT1: TX tx count -// -typedef union _TX_STA_CNT1_STRUC { - struct { - USHORT TxSuccess; - USHORT TxRetransmit; - } field; - UINT32 word; -} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC; - -#define TX_STA_CNT2 0x1714 // -// -// TX_STA_CNT2: TX tx count -// -typedef union _TX_STA_CNT2_STRUC { - struct { - USHORT TxZeroLenCount; - USHORT TxUnderFlowCount; - } field; - UINT32 word; -} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC; - -#define TX_STA_FIFO 0x1718 // -// -// TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register -// -typedef union PACKED _TX_STA_FIFO_STRUC { - struct { - UINT32 bValid:1; // 1:This register contains a valid TX result - UINT32 PidType:4; - UINT32 TxSuccess:1; // Tx No retry success - UINT32 TxAggre:1; // Tx Retry Success - UINT32 TxAckRequired:1; // Tx fail - UINT32 wcid:8; //wireless client index -// UINT32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. - UINT32 SuccessRate:13; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. - UINT32 TxBF:1; - UINT32 Reserve:2; - } field; - UINT32 word; -} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC; - -// Debug counter -#define TX_AGG_CNT 0x171c -typedef union _TX_AGG_CNT_STRUC { - struct { - USHORT NonAggTxCount; - USHORT AggTxCount; - } field; - UINT32 word; -} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC; - -// Debug counter -#define TX_AGG_CNT0 0x1720 -typedef union _TX_AGG_CNT0_STRUC { - struct { - USHORT AggSize1Count; - USHORT AggSize2Count; - } field; - UINT32 word; -} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC; - -// Debug counter -#define TX_AGG_CNT1 0x1724 -typedef union _TX_AGG_CNT1_STRUC { - struct { - USHORT AggSize3Count; - USHORT AggSize4Count; - } field; - UINT32 word; -} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC; - -#define TX_AGG_CNT2 0x1728 -typedef union _TX_AGG_CNT2_STRUC { - struct { - USHORT AggSize5Count; - USHORT AggSize6Count; - } field; - UINT32 word; -} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC; - -// Debug counter -#define TX_AGG_CNT3 0x172c -typedef union _TX_AGG_CNT3_STRUC { - struct { - USHORT AggSize7Count; - USHORT AggSize8Count; - } field; - UINT32 word; -} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC; - -// Debug counter -#define TX_AGG_CNT4 0x1730 -typedef union _TX_AGG_CNT4_STRUC { - struct { - USHORT AggSize9Count; - USHORT AggSize10Count; - } field; - UINT32 word; -} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC; - -#define TX_AGG_CNT5 0x1734 -typedef union _TX_AGG_CNT5_STRUC { - struct { - USHORT AggSize11Count; - USHORT AggSize12Count; - } field; - UINT32 word; -} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC; - -#define TX_AGG_CNT6 0x1738 -typedef union _TX_AGG_CNT6_STRUC { - struct { - USHORT AggSize13Count; - USHORT AggSize14Count; - } field; - UINT32 word; -} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC; - -#define TX_AGG_CNT7 0x173c -typedef union _TX_AGG_CNT7_STRUC { - struct { - USHORT AggSize15Count; - USHORT AggSize16Count; - } field; - UINT32 word; -} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC; - -#define MPDU_DENSITY_CNT 0x1740 -typedef union _MPDU_DEN_CNT_STRUC { - struct { - USHORT TXZeroDelCount; //TX zero length delimiter count - USHORT RXZeroDelCount; //RX zero length delimiter count - } field; - UINT32 word; -} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC; - -// -// TXRX control registers - base address 0x3000 -// -// rt2860b UNKNOWN reg use R/O Reg Addr 0x77d0 first.. -#define TXRX_CSR1 0x77d0 - -// -// Security key table memory, base address = 0x1000 -// -#define MAC_WCID_BASE 0x1800 //8-bytes(use only 6-bytes) * 256 entry = -#define HW_WCID_ENTRY_SIZE 8 -#define PAIRWISE_KEY_TABLE_BASE 0x4000 // 32-byte * 256-entry = -byte -#define HW_KEY_ENTRY_SIZE 0x20 -#define PAIRWISE_IVEIV_TABLE_BASE 0x6000 // 8-byte * 256-entry = -byte -#define MAC_IVEIV_TABLE_BASE 0x6000 // 8-byte * 256-entry = -byte -#define HW_IVEIV_ENTRY_SIZE 8 -#define MAC_WCID_ATTRIBUTE_BASE 0x6800 // 4-byte * 256-entry = -byte -#define HW_WCID_ATTRI_SIZE 4 -#define WCID_RESERVED 0x6bfc -#define SHARED_KEY_TABLE_BASE 0x6c00 // 32-byte * 16-entry = 512-byte -#define SHARED_KEY_MODE_BASE 0x7000 // 32-byte * 16-entry = 512-byte -#define HW_SHARED_KEY_MODE_SIZE 4 -#define SHAREDKEYTABLE 0 -#define PAIRWISEKEYTABLE 1 - -typedef union _SHAREDKEY_MODE_STRUC { - struct { - UINT32 Bss0Key0CipherAlg:3; - UINT32 :1; - UINT32 Bss0Key1CipherAlg:3; - UINT32 :1; - UINT32 Bss0Key2CipherAlg:3; - UINT32 :1; - UINT32 Bss0Key3CipherAlg:3; - UINT32 :1; - UINT32 Bss1Key0CipherAlg:3; - UINT32 :1; - UINT32 Bss1Key1CipherAlg:3; - UINT32 :1; - UINT32 Bss1Key2CipherAlg:3; - UINT32 :1; - UINT32 Bss1Key3CipherAlg:3; - UINT32 :1; - } field; - UINT32 word; -} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC; - -// 64-entry for pairwise key table -typedef struct _HW_WCID_ENTRY { // 8-byte per entry - UCHAR Address[6]; - UCHAR Rsv[2]; -} HW_WCID_ENTRY, PHW_WCID_ENTRY; - - - -// -// Other on-chip shared memory space, base = 0x2000 -// - -// CIS space - base address = 0x2000 -#define HW_CIS_BASE 0x2000 - -// Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function. -#define HW_CS_CTS_BASE 0x7700 -// DFS CTS frame base address. It's where mac stores CTS frame for DFS. -#define HW_DFS_CTS_BASE 0x7780 -#define HW_CTS_FRAME_SIZE 0x80 - -// 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes -// to save debugging settings -#define HW_DEBUG_SETTING_BASE 0x77f0 // 0x77f0~0x77ff total 16 bytes -#define HW_DEBUG_SETTING_BASE2 0x7770 // 0x77f0~0x77ff total 16 bytes - -// In order to support maximum 8 MBSS and its maximum length is 512 for each beacon -// Three section discontinue memory segments will be used. -// 1. The original region for BCN 0~3 -// 2. Extract memory from FCE table for BCN 4~5 -// 3. Extract memory from Pair-wise key table for BCN 6~7 -// It occupied those memory of wcid 238~253 for BCN 6 -// and wcid 222~237 for BCN 7 -#define HW_BEACON_MAX_SIZE 0x1000 /* unit: byte */ -#define HW_BEACON_BASE0 0x7800 -#define HW_BEACON_BASE1 0x7A00 -#define HW_BEACON_BASE2 0x7C00 -#define HW_BEACON_BASE3 0x7E00 -#define HW_BEACON_BASE4 0x7200 -#define HW_BEACON_BASE5 0x7400 -#define HW_BEACON_BASE6 0x5DC0 -#define HW_BEACON_BASE7 0x5BC0 - -#define HW_BEACON_MAX_COUNT 8 -#define HW_BEACON_OFFSET 0x0200 -#define HW_BEACON_CONTENT_LEN (HW_BEACON_OFFSET - TXWI_SIZE) - -// HOST-MCU shared memory - base address = 0x2100 -#define HOST_CMD_CSR 0x404 -#define H2M_MAILBOX_CSR 0x7010 -#define H2M_MAILBOX_CID 0x7014 -#define H2M_MAILBOX_STATUS 0x701c -#define H2M_INT_SRC 0x7024 -#define H2M_BBP_AGENT 0x7028 -#define M2H_CMD_DONE_CSR 0x000c -#define MCU_TXOP_ARRAY_BASE 0x000c // TODO: to be provided by Albert -#define MCU_TXOP_ENTRY_SIZE 32 // TODO: to be provided by Albert -#define MAX_NUM_OF_TXOP_ENTRY 16 // TODO: must be same with 8051 firmware -#define MCU_MBOX_VERSION 0x01 // TODO: to be confirmed by Albert -#define MCU_MBOX_VERSION_OFFSET 5 // TODO: to be provided by Albert - -// -// Host DMA registers - base address 0x200 . TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT, -// -// -// DMA RING DESCRIPTOR -// -#define E2PROM_CSR 0x0004 -#define IO_CNTL_CSR 0x77d0 - -#ifdef RT2860 -// 8051 firmware image for RT2860 - base address = 0x4000 -#define FIRMWARE_IMAGE_BASE 0x2000 -#define MAX_FIRMWARE_IMAGE_SIZE 0x2000 // 8kbyte -#endif -#ifdef RT2870 -// 8051 firmware image for usb - use last-half base address = 0x3000 -#define FIRMWARE_IMAGE_BASE 0x3000 -#define MAX_FIRMWARE_IMAGE_SIZE 0x1000 // 4kbyte -#endif // RT2870 // - -// ================================================================ -// Tx / Rx / Mgmt ring descriptor definition -// ================================================================ - -// the following PID values are used to mark outgoing frame type in TXD->PID so that -// proper TX statistics can be collected based on these categories -// b3-2 of PID field - -#define PID_MGMT 0x05 -#define PID_BEACON 0x0c -#define PID_DATA_NORMALUCAST 0x02 -#define PID_DATA_AMPDU 0x04 -#define PID_DATA_NO_ACK 0x08 -#define PID_DATA_NOT_NORM_ACK 0x03 -// value domain of pTxD->HostQId (4-bit: 0~15) -#define QID_AC_BK 1 // meet ACI definition in 802.11e -#define QID_AC_BE 0 // meet ACI definition in 802.11e -#define QID_AC_VI 2 -#define QID_AC_VO 3 -#define QID_HCCA 4 -#define NUM_OF_TX_RING 5 -#define QID_MGMT 13 -#define QID_RX 14 -#define QID_OTHER 15 - - -// ------------------------------------------------------ -// BBP & RF definition -// ------------------------------------------------------ -#define BUSY 1 -#define IDLE 0 - -#define RF_R00 0 -#define RF_R01 1 -#define RF_R02 2 -#define RF_R03 3 -#define RF_R04 4 -#define RF_R05 5 -#define RF_R06 6 -#define RF_R07 7 -#define RF_R08 8 -#define RF_R09 9 -#define RF_R10 10 -#define RF_R11 11 -#define RF_R12 12 -#define RF_R13 13 -#define RF_R14 14 -#define RF_R15 15 -#define RF_R16 16 -#define RF_R17 17 -#define RF_R18 18 -#define RF_R19 19 -#define RF_R20 20 -#define RF_R21 21 -#define RF_R22 22 -#define RF_R23 23 -#define RF_R24 24 -#define RF_R25 25 -#define RF_R26 26 -#define RF_R27 27 -#define RF_R28 28 -#define RF_R29 29 -#define RF_R30 30 -#define RF_R31 31 - -#define BBP_R0 0 // version -#define BBP_R1 1 // TSSI -#define BBP_R2 2 // TX configure -#define BBP_R3 3 -#define BBP_R4 4 -#define BBP_R5 5 -#define BBP_R6 6 -#define BBP_R14 14 // RX configure -#define BBP_R16 16 -#define BBP_R17 17 // RX sensibility -#define BBP_R18 18 -#define BBP_R21 21 -#define BBP_R22 22 -#define BBP_R24 24 -#define BBP_R25 25 -#define BBP_R31 31 -#define BBP_R49 49 //TSSI -#define BBP_R50 50 -#define BBP_R51 51 -#define BBP_R52 52 -#define BBP_R55 55 -#define BBP_R62 62 // Rx SQ0 Threshold HIGH -#define BBP_R63 63 -#define BBP_R64 64 -#define BBP_R65 65 -#define BBP_R66 66 -#define BBP_R67 67 -#define BBP_R68 68 -#define BBP_R69 69 -#define BBP_R70 70 // Rx AGC SQ CCK Xcorr threshold -#define BBP_R73 73 -#define BBP_R75 75 -#define BBP_R77 77 -#define BBP_R79 79 -#define BBP_R80 80 -#define BBP_R81 81 -#define BBP_R82 82 -#define BBP_R83 83 -#define BBP_R84 84 -#define BBP_R86 86 -#define BBP_R91 91 -#define BBP_R92 92 -#define BBP_R94 94 // Tx Gain Control -#define BBP_R103 103 -#define BBP_R105 105 -#define BBP_R113 113 -#define BBP_R114 114 -#define BBP_R115 115 -#define BBP_R116 116 -#define BBP_R117 117 -#define BBP_R118 118 -#define BBP_R119 119 -#define BBP_R120 120 -#define BBP_R121 121 -#define BBP_R122 122 -#define BBP_R123 123 -#define BBP_R138 138 // add by johnli, RF power sequence setup, ADC dynamic on/off control - - -#define BBPR94_DEFAULT 0x06 // Add 1 value will gain 1db - -#define RSSI_FOR_VERY_LOW_SENSIBILITY -35 -#define RSSI_FOR_LOW_SENSIBILITY -58 -#define RSSI_FOR_MID_LOW_SENSIBILITY -80 -#define RSSI_FOR_MID_SENSIBILITY -90 - -//------------------------------------------------------------------------- -// EEPROM definition -//------------------------------------------------------------------------- -#define EEDO 0x08 -#define EEDI 0x04 -#define EECS 0x02 -#define EESK 0x01 -#define EERL 0x80 - -#define EEPROM_WRITE_OPCODE 0x05 -#define EEPROM_READ_OPCODE 0x06 -#define EEPROM_EWDS_OPCODE 0x10 -#define EEPROM_EWEN_OPCODE 0x13 - -#define NUM_EEPROM_BBP_PARMS 19 // Include NIC Config 0, 1, CR, TX ALC step, BBPs -#define NUM_EEPROM_TX_G_PARMS 7 -#define EEPROM_NIC1_OFFSET 0x34 // The address is from NIC config 0, not BBP register ID -#define EEPROM_NIC2_OFFSET 0x36 // The address is from NIC config 0, not BBP register ID -#define EEPROM_BBP_BASE_OFFSET 0xf0 // The address is from NIC config 0, not BBP register ID -#define EEPROM_G_TX_PWR_OFFSET 0x52 -#define EEPROM_G_TX2_PWR_OFFSET 0x60 -#define EEPROM_LED1_OFFSET 0x3c -#define EEPROM_LED2_OFFSET 0x3e -#define EEPROM_LED3_OFFSET 0x40 -#define EEPROM_LNA_OFFSET 0x44 -#define EEPROM_RSSI_BG_OFFSET 0x46 -#define EEPROM_RSSI_A_OFFSET 0x4a -#define EEPROM_DEFINE_MAX_TXPWR 0x4e -#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G 0xde // 20MHZ 2.4G tx power. -#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G 0xee // 40MHZ 2.4G tx power. -#define EEPROM_TXPOWER_BYRATE_20MHZ_5G 0xfa // 20MHZ 5G tx power. -#define EEPROM_TXPOWER_BYRATE_40MHZ_5G 0x10a // 40MHZ 5G tx power. -#define EEPROM_A_TX_PWR_OFFSET 0x78 -#define EEPROM_A_TX2_PWR_OFFSET 0xa6 -#define EEPROM_VERSION_OFFSET 0x02 -#define EEPROM_FREQ_OFFSET 0x3a -#define EEPROM_TXPOWER_BYRATE 0xde // 20MHZ power. -#define EEPROM_TXPOWER_DELTA 0x50 // 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ. -#define VALID_EEPROM_VERSION 1 - -// PairKeyMode definition -#define PKMODE_NONE 0 -#define PKMODE_WEP64 1 -#define PKMODE_WEP128 2 -#define PKMODE_TKIP 3 -#define PKMODE_AES 4 -#define PKMODE_CKIP64 5 -#define PKMODE_CKIP128 6 -#define PKMODE_TKIP_NO_MIC 7 // MIC appended by driver: not a valid value in hardware key table - -// ================================================================================= -// WCID format -// ================================================================================= -//7.1 WCID ENTRY format : 8bytes -typedef struct _WCID_ENTRY_STRUC { - UCHAR RXBABitmap7; // bit0 for TID8, bit7 for TID 15 - UCHAR RXBABitmap0; // bit0 for TID0, bit7 for TID 7 - UCHAR MAC[6]; // 0 for shared key table. 1 for pairwise key table -} WCID_ENTRY_STRUC, *PWCID_ENTRY_STRUC; - -//8.1.1 SECURITY KEY format : 8DW -// 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table -typedef struct _HW_KEY_ENTRY { // 32-byte per entry - UCHAR Key[16]; - UCHAR TxMic[8]; - UCHAR RxMic[8]; -} HW_KEY_ENTRY, *PHW_KEY_ENTRY; - -//8.1.2 IV/EIV format : 2DW - -//8.1.3 RX attribute entry format : 1DW -typedef struct _MAC_ATTRIBUTE_STRUC { - UINT32 KeyTab:1; // 0 for shared key table. 1 for pairwise key table - UINT32 PairKeyMode:3; - UINT32 BSSIDIdx:3; //multipleBSS index for the WCID - UINT32 RXWIUDF:3; - UINT32 rsv:22; -} MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC; - -// ================================================================================= -// TX / RX ring descriptor format -// ================================================================================= - -// the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO. -// MAC block use this TXINFO to control the transmission behavior of this frame. -#define FIFO_MGMT 0 -#define FIFO_HCCA 1 -#define FIFO_EDCA 2 - -// -// TX descriptor format, Tx ring, Mgmt Ring -// -typedef struct PACKED _TXD_STRUC { - // Word 0 - UINT32 SDPtr0; - // Word 1 - UINT32 SDLen1:14; - UINT32 LastSec1:1; - UINT32 Burst:1; - UINT32 SDLen0:14; - UINT32 LastSec0:1; - UINT32 DMADONE:1; - //Word2 - UINT32 SDPtr1; - //Word3 - UINT32 rsv2:24; - UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition - UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA - UINT32 rsv:2; - UINT32 TCO:1; // - UINT32 UCO:1; // - UINT32 ICO:1; // -} TXD_STRUC, *PTXD_STRUC; - -// -// TXD Wireless Information format for Tx ring and Mgmt Ring -// -//txop : for txop mode -// 0:txop for the MPDU frame will be handles by ASIC by register -// 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS -typedef struct PACKED _TXWI_STRUC { - // Word 0 - UINT32 FRAG:1; // 1 to inform TKIP engine this is a fragment. - UINT32 MIMOps:1; // the remote peer is in dynamic MIMO-PS mode - UINT32 CFACK:1; - UINT32 TS:1; - - UINT32 AMPDU:1; - UINT32 MpduDensity:3; - UINT32 txop:2; //FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful. - UINT32 rsv:6; - - UINT32 MCS:7; - UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz - UINT32 ShortGI:1; - UINT32 STBC:2; // 1: STBC support MCS =0-7, 2,3 : RESERVE - UINT32 Ifs:1; // - UINT32 rsv2:1; - UINT32 TxBF:1; // 3*3 - UINT32 PHYMODE:2; - // Word 1 - UINT32 ACK:1; - UINT32 NSEQ:1; - UINT32 BAWinSize:6; - UINT32 WirelessCliID:8; - UINT32 MPDUtotalByteCount:12; - UINT32 PacketId:4; - //Word2 - UINT32 IV; - //Word3 - UINT32 EIV; -} TXWI_STRUC, *PTXWI_STRUC; - -// -// Rx descriptor format, Rx Ring -// -#ifdef RT2860 -typedef struct PACKED _RXD_STRUC { - // Word 0 - UINT32 SDP0; - // Word 1 - UINT32 SDL1:14; - UINT32 Rsv:2; - UINT32 SDL0:14; - UINT32 LS0:1; - UINT32 DDONE:1; - // Word 2 - UINT32 SDP1; - // Word 3 - UINT32 BA:1; - UINT32 DATA:1; - UINT32 NULLDATA:1; - UINT32 FRAG:1; - UINT32 U2M:1; // 1: this RX frame is unicast to me - UINT32 Mcast:1; // 1: this is a multicast frame - UINT32 Bcast:1; // 1: this is a broadcast frame - UINT32 MyBss:1; // 1: this frame belongs to the same BSSID - UINT32 Crc:1; // 1: CRC error - UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid - UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header. - UINT32 HTC:1; - UINT32 RSSI:1; - UINT32 L2PAD:1; - UINT32 AMPDU:1; - UINT32 Decrypted:1; // this frame is being decrypted. - UINT32 PlcpSignal:1; // To be moved - UINT32 PlcpRssil:1;// To be moved - UINT32 Rsv1:13; -} RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC; -#endif /* RT2860 */ - -// -// RXWI wireless information format, in PBF. invisible in driver. -// -typedef struct PACKED _RXWI_STRUC { - // Word 0 - UINT32 WirelessCliID:8; - UINT32 KeyIndex:2; - UINT32 BSSID:3; - UINT32 UDF:3; - UINT32 MPDUtotalByteCount:12; - UINT32 TID:4; - // Word 1 - UINT32 FRAG:4; - UINT32 SEQUENCE:12; - UINT32 MCS:7; - UINT32 BW:1; - UINT32 ShortGI:1; - UINT32 STBC:2; - UINT32 rsv:3; - UINT32 PHYMODE:2; // 1: this RX frame is unicast to me - //Word2 - UINT32 RSSI0:8; - UINT32 RSSI1:8; - UINT32 RSSI2:8; - UINT32 rsv1:8; - //Word3 - UINT32 SNR0:8; - UINT32 SNR1:8; - UINT32 rsv2:16; -} RXWI_STRUC, *PRXWI_STRUC; - -// ================================================================================= -// HOST-MCU communication data structure -// ================================================================================= - -// -// H2M_MAILBOX_CSR: Host-to-MCU Mailbox -// -typedef union _H2M_MAILBOX_STRUC { - struct { - UINT32 LowByte:8; - UINT32 HighByte:8; - UINT32 CmdToken:8; - UINT32 Owner:8; - } field; - UINT32 word; -} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC; - -// -// M2H_CMD_DONE_CSR: MCU-to-Host command complete indication -// -typedef union _M2H_CMD_DONE_STRUC { - struct { - UINT32 CmdToken0; - UINT32 CmdToken1; - UINT32 CmdToken2; - UINT32 CmdToken3; - } field; - UINT32 word; -} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC; - -// -// MCU_LEDCS: MCU LED Control Setting. -// -typedef union _MCU_LEDCS_STRUC { - struct { - UCHAR LedMode:7; - UCHAR Polarity:1; - } field; - UCHAR word; -} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC; - -// ================================================================================= -// Register format -// ================================================================================= - - - -//NAV_TIME_CFG :NAV -typedef union _NAV_TIME_CFG_STRUC { - struct { - UCHAR Sifs; // in unit of 1-us - UCHAR SlotTime; // in unit of 1-us - USHORT Eifs:9; // in unit of 1-us - USHORT ZeroSifs:1; // Applied zero SIFS timer after OFDM RX 0: disable - USHORT rsv:6; - } field; - UINT32 word; -} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC; - -// -// RX_FILTR_CFG: /RX configuration register -// -typedef union _RX_FILTR_CFG_STRUC { - struct { - UINT32 DropCRCErr:1; // Drop CRC error - UINT32 DropPhyErr:1; // Drop physical error - UINT32 DropNotToMe:1; // Drop not to me unicast frame - UINT32 DropNotMyBSSID:1; // Drop fram ToDs bit is true - - UINT32 DropVerErr:1; // Drop version error frame - UINT32 DropMcast:1; // Drop multicast frames - UINT32 DropBcast:1; // Drop broadcast frames - UINT32 DropDuplicate:1; // Drop duplicate frame - - UINT32 DropCFEndAck:1; // Drop Ps-Poll - UINT32 DropCFEnd:1; // Drop Ps-Poll - UINT32 DropAck:1; // Drop Ps-Poll - UINT32 DropCts:1; // Drop Ps-Poll - - UINT32 DropRts:1; // Drop Ps-Poll - UINT32 DropPsPoll:1; // Drop Ps-Poll - UINT32 DropBA:1; // - UINT32 DropBAR:1; // - - UINT32 DropRsvCntlType:1; - UINT32 :15; - } field; - UINT32 word; -} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC; - -// -// PHY_CSR4: RF serial control register -// -typedef union _PHY_CSR4_STRUC { - struct { - UINT32 RFRegValue:24; // Register value (include register id) serial out to RF/IF chip. - UINT32 NumberOfBits:5; // Number of bits used in RFRegValue (I:20, RFMD:22) - UINT32 IFSelect:1; // 1: select IF to program, 0: select RF to program - UINT32 PLL_LD:1; // RF PLL_LD status - UINT32 Busy:1; // 1: ASIC is busy execute RF programming. - } field; - UINT32 word; -} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC; - -// -// SEC_CSR5: shared key table security mode register -// -typedef union _SEC_CSR5_STRUC { - struct { - UINT32 Bss2Key0CipherAlg:3; - UINT32 :1; - UINT32 Bss2Key1CipherAlg:3; - UINT32 :1; - UINT32 Bss2Key2CipherAlg:3; - UINT32 :1; - UINT32 Bss2Key3CipherAlg:3; - UINT32 :1; - UINT32 Bss3Key0CipherAlg:3; - UINT32 :1; - UINT32 Bss3Key1CipherAlg:3; - UINT32 :1; - UINT32 Bss3Key2CipherAlg:3; - UINT32 :1; - UINT32 Bss3Key3CipherAlg:3; - UINT32 :1; - } field; - UINT32 word; -} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC; - -// -// HOST_CMD_CSR: For HOST to interrupt embedded processor -// -typedef union _HOST_CMD_CSR_STRUC { - struct { - UINT32 HostCommand:8; - UINT32 Rsv:24; - } field; - UINT32 word; -} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC; - -// -// AIFSN_CSR: AIFSN for each EDCA AC -// - - - -// -// E2PROM_CSR: EEPROM control register -// -typedef union _E2PROM_CSR_STRUC { - struct { - UINT32 Reload:1; // Reload EEPROM content, write one to reload, self-cleared. - UINT32 EepromSK:1; - UINT32 EepromCS:1; - UINT32 EepromDI:1; - UINT32 EepromDO:1; - UINT32 Type:1; // 1: 93C46, 0:93C66 - UINT32 LoadStatus:1; // 1:loading, 0:done - UINT32 Rsvd:25; - } field; - UINT32 word; -} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC; - -// ------------------------------------------------------------------- -// E2PROM data layout -// ------------------------------------------------------------------- - -// -// EEPROM antenna select format -// -typedef union _EEPROM_ANTENNA_STRUC { - struct { - USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R - USHORT TxPath:4; // 1: 1T, 2: 2T - USHORT RfIcType:4; // see E2PROM document - USHORT Rsv:4; - } field; - USHORT word; -} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC; - -typedef union _EEPROM_NIC_CINFIG2_STRUC { - struct { - USHORT HardwareRadioControl:1; // 1:enable, 0:disable - USHORT DynamicTxAgcControl:1; // - USHORT ExternalLNAForG:1; // - USHORT ExternalLNAForA:1; // external LNA enable for 2.4G - USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable - USHORT BW40MSidebandForG:1; - USHORT BW40MSidebandForA:1; - USHORT EnableWPSPBC:1; // WPS PBC Control bit - USHORT BW40MAvailForG:1; // 0:enable, 1:disable - USHORT BW40MAvailForA:1; // 0:enable, 1:disable - USHORT Rsv1:1; // must be 0 - USHORT AntDiversity:1; // Antenna diversity - USHORT Rsv2:3; // must be 0 - USHORT DACTestBit:1; // control if driver should patch the DAC issue - } field; - USHORT word; -} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC; - -// -// TX_PWR Value valid range 0xFA(-6) ~ 0x24(36) -// -typedef union _EEPROM_TX_PWR_STRUC { - struct { - CHAR Byte0; // Low Byte - CHAR Byte1; // High Byte - } field; - USHORT word; -} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC; - -typedef union _EEPROM_VERSION_STRUC { - struct { - UCHAR FaeReleaseNumber; // Low Byte - UCHAR Version; // High Byte - } field; - USHORT word; -} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC; - -typedef union _EEPROM_LED_STRUC { - struct { - USHORT PolarityRDY_G:1; // Polarity RDY_G setting. - USHORT PolarityRDY_A:1; // Polarity RDY_A setting. - USHORT PolarityACT:1; // Polarity ACT setting. - USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting. - USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting. - USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting. - USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting. - USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting. - USHORT LedMode:5; // Led mode. - USHORT Rsvd:3; // Reserved - } field; - USHORT word; -} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC; - -typedef union _EEPROM_TXPOWER_DELTA_STRUC { - struct { - UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4) - UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value - UCHAR TxPowerEnable:1;// Enable - } field; - UCHAR value; -} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC; - -// -// QOS_CSR0: TXOP holder address0 register -// -typedef union _QOS_CSR0_STRUC { - struct { - UCHAR Byte0; // MAC address byte 0 - UCHAR Byte1; // MAC address byte 1 - UCHAR Byte2; // MAC address byte 2 - UCHAR Byte3; // MAC address byte 3 - } field; - UINT32 word; -} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC; - -// -// QOS_CSR1: TXOP holder address1 register -// -typedef union _QOS_CSR1_STRUC { - struct { - UCHAR Byte4; // MAC address byte 4 - UCHAR Byte5; // MAC address byte 5 - UCHAR Rsvd0; - UCHAR Rsvd1; - } field; - UINT32 word; -} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC; - -#define RF_CSR_CFG 0x500 -typedef union _RF_CSR_CFG_STRUC { - struct { - UINT RF_CSR_DATA:8; // DATA - UINT TESTCSR_RFACC_REGNUM:5; // RF register ID - UINT Rsvd2:3; // Reserved - UINT RF_CSR_WR:1; // 0: read 1: write - UINT RF_CSR_KICK:1; // kick RF register read/write - UINT Rsvd1:14; // Reserved - } field; - UINT word; -} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC; - -#endif // __RT28XX_H__ Index: b/drivers/staging/rt2860/rt_config.h =================================================================== --- a/drivers/staging/rt2860/rt_config.h +++ b/drivers/staging/rt2860/rt_config.h @@ -41,29 +41,42 @@ #define __RT_CONFIG_H__ #include "rtmp_type.h" -#ifdef LINUX -#include "rt_linux.h" -#endif -#include "rtmp_def.h" -#include "rt28xx.h" +#include "rtmp_os.h" -#ifdef RT2860 -#include "rt2860.h" -#endif -#ifdef RT2870 -#include "../rt2870/rt2870.h" -#endif // RT2870 // +#include "rtmp_def.h" +#include "rtmp_chip.h" +#include "rtmp_timer.h" #include "oid.h" #include "mlme.h" #include "wpa.h" -#include "md5.h" +#include "crypt_md5.h" +#include "crypt_sha2.h" +#include "crypt_hmac.h" #include "rtmp.h" #include "ap.h" #include "dfs.h" #include "chlist.h" #include "spectrum.h" +#ifdef MLME_EX +#include "mlme_ex_def.h" +#include "mlme_ex.h" +#endif // MLME_EX // + +#include "eeprom.h" +#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT) +#include "rtmp_mcu.h" +#endif + +#undef AP_WSC_INCLUDED +#undef STA_WSC_INCLUDED +#undef WSC_INCLUDED + + + + + #ifdef IGMP_SNOOP_SUPPORT #include "igmp_snoop.h" #endif // IGMP_SNOOP_SUPPORT // Index: b/drivers/staging/rt2860/rt_linux.c =================================================================== --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -29,27 +29,6 @@ ULONG RTDebugLevel = RT_DEBUG_ERROR; -BUILD_TIMER_FUNCTION(MlmePeriodicExec); -BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout); -BUILD_TIMER_FUNCTION(APSDPeriodicExec); -BUILD_TIMER_FUNCTION(AsicRfTuningExec); -#ifdef RT2870 -BUILD_TIMER_FUNCTION(BeaconUpdateExec); -#endif // RT2870 // - -BUILD_TIMER_FUNCTION(BeaconTimeout); -BUILD_TIMER_FUNCTION(ScanTimeout); -BUILD_TIMER_FUNCTION(AuthTimeout); -BUILD_TIMER_FUNCTION(AssocTimeout); -BUILD_TIMER_FUNCTION(ReassocTimeout); -BUILD_TIMER_FUNCTION(DisassocTimeout); -BUILD_TIMER_FUNCTION(LinkDownExec); -BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec); -BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc); -#ifdef RT2860 -BUILD_TIMER_FUNCTION(PsPollWakeExec); -BUILD_TIMER_FUNCTION(RadioOnExec); -#endif // for wireless system event message char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = { @@ -105,7 +84,7 @@ VOID RTMP_SetPeriodicTimer( IN NDIS_MINIPORT_TIMER *pTimer, IN unsigned long timeout) { - timeout = ((timeout*HZ) / 1000); + timeout = ((timeout*OS_HZ) / 1000); pTimer->expires = jiffies + timeout; add_timer(pTimer); } @@ -130,7 +109,7 @@ VOID RTMP_OS_Add_Timer( if (timer_pending(pTimer)) return; - timeout = ((timeout*HZ) / 1000); + timeout = ((timeout*OS_HZ) / 1000); pTimer->expires = jiffies + timeout; add_timer(pTimer); } @@ -139,7 +118,7 @@ VOID RTMP_OS_Mod_Timer( IN NDIS_MINIPORT_TIMER *pTimer, IN unsigned long timeout) { - timeout = ((timeout*HZ) / 1000); + timeout = ((timeout*OS_HZ) / 1000); mod_timer(pTimer, jiffies + timeout); } @@ -185,8 +164,8 @@ void RTMP_GetCurrentSystemTime(LARGE_INT // pAd MUST allow to be NULL NDIS_STATUS os_alloc_mem( - IN PRTMP_ADAPTER pAd, - OUT PUCHAR *mem, + IN RTMP_ADAPTER *pAd, + OUT UCHAR **mem, IN ULONG size) { *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC); @@ -199,7 +178,7 @@ NDIS_STATUS os_alloc_mem( // pAd MUST allow to be NULL NDIS_STATUS os_free_mem( IN PRTMP_ADAPTER pAd, - IN PUCHAR mem) + IN PVOID mem) { ASSERT(mem); @@ -208,6 +187,20 @@ NDIS_STATUS os_free_mem( } + + +PNDIS_PACKET RtmpOSNetPktAlloc( + IN RTMP_ADAPTER *pAd, + IN int size) +{ + struct sk_buff *skb; + /* Add 2 more bytes for ip header alignment*/ + skb = dev_alloc_skb(size+2); + + return ((PNDIS_PACKET)skb); +} + + PNDIS_PACKET RTMP_AllocateFragPacketBuffer( IN PRTMP_ADAPTER pAd, IN ULONG Length) @@ -282,13 +275,16 @@ VOID RTMPFreeAdapter( os_cookie=(POS_COOKIE)pAd->OS_Cookie; + if (pAd->BeaconBuf) kfree(pAd->BeaconBuf); NdisFreeSpinLock(&pAd->MgmtRingLock); -#ifdef RT2860 + +#ifdef RTMP_MAC_PCI NdisFreeSpinLock(&pAd->RxRingLock); -#endif +#endif // RTMP_MAC_PCI // + for (index =0 ; index < NUM_OF_TX_RING; index++) { NdisFreeSpinLock(&pAd->TxSwQueueLock[index]); @@ -298,7 +294,9 @@ VOID RTMPFreeAdapter( NdisFreeSpinLock(&pAd->irq_lock); + vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa); + if (os_cookie) kfree(os_cookie); } @@ -378,7 +376,7 @@ NDIS_STATUS RTMPAllocateNdisPacket( ASSERT(DataLen); // 1. Allocate a packet - pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE); + pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + RTMP_PKT_TAIL_PADDING); if (pPacket == NULL) { *ppPacket = NULL; @@ -441,7 +439,7 @@ void RTMP_QueryPacketInfo( OUT UINT *pSrcBufLen) { pPacketInfo->BufferCount = 1; - pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket); + pPacketInfo->pFirstBuffer = (PNDIS_BUFFER)GET_OS_PKT_DATAPTR(pPacket); pPacketInfo->PhysicalBufferCount = 1; pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket); @@ -463,7 +461,7 @@ void RTMP_QueryNextPacketInfo( if (pPacket) { pPacketInfo->BufferCount = 1; - pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket); + pPacketInfo->pFirstBuffer = (PNDIS_BUFFER)GET_OS_PKT_DATAPTR(pPacket); pPacketInfo->PhysicalBufferCount = 1; pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket); @@ -484,18 +482,6 @@ void RTMP_QueryNextPacketInfo( } } -// not yet support MBSS -PNET_DEV get_netdev_from_bssid( - IN PRTMP_ADAPTER pAd, - IN UCHAR FromWhichBSSID) -{ - PNET_DEV dev_p = NULL; - - dev_p = pAd->net_dev; - - ASSERT(dev_p); - return dev_p; /* return one of MBSS */ -} PNDIS_PACKET DuplicatePacket( IN PRTMP_ADAPTER pAd, @@ -537,9 +523,9 @@ PNDIS_PACKET duplicate_pkt( if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL) { skb_reserve(skb, 2); - NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen); + NdisMoveMemory(skb->tail, pHeader802_3, HdrLen); skb_put(skb, HdrLen); - NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize); + NdisMoveMemory(skb->tail, pData, DataSize); skb_put(skb, DataSize); skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID); pPacket = OSPKT_TO_RTPKT(skb); @@ -648,7 +634,9 @@ void wlan_802_11_to_802_3_packet( // NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3); -} + } + + void announce_802_3_packet( IN PRTMP_ADAPTER pAd, @@ -664,7 +652,14 @@ void announce_802_3_packet( /* Push up the protocol stack */ pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev); +//#ifdef CONFIG_5VT_ENHANCE +// *(int*)(pRxPkt->cb) = BRIDGE_TAG; +//#endif + + { netif_rx(pRxPkt); + } + } @@ -725,8 +720,8 @@ VOID RTMPSendWirelessEvent( IN CHAR Rssi) { - union iwreq_data wrqu; - PUCHAR pBuf = NULL, pBufPtr = NULL; + //union iwreq_data wrqu; + PSTRING pBuf = NULL, pBufPtr = NULL; USHORT event, type, BufLen; UCHAR event_table_len = 0; @@ -787,13 +782,7 @@ VOID RTMPSendWirelessEvent( pBufPtr[pBufPtr - pBuf] = '\0'; BufLen = pBufPtr - pBuf; - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.flags = Event_flag; - wrqu.data.length = BufLen; - - //send wireless event - wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf); - + RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL, (PUCHAR)pBuf, BufLen); //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); kfree(pBuf); @@ -895,7 +884,7 @@ void send_monitor_packets( ph->msgcode = DIDmsg_lnxind_wlansniffrm; ph->msglen = sizeof(wlan_ng_prism2_header); - strcpy(ph->devname, pAd->net_dev->name); + strcpy((PSTRING) ph->devname, (PSTRING) pAd->net_dev->name); ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; ph->hosttime.status = 0; @@ -971,18 +960,275 @@ err_free_sk_buff: } -void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify) + +/******************************************************************************* + + Device IRQ related functions. + + *******************************************************************************/ +int RtmpOSIRQRequest(IN PNET_DEV pNetDev) +{ + struct net_device *net_dev = pNetDev; + PRTMP_ADAPTER pAd = NULL; + int retval = 0; + + GET_PAD_FROM_NET_DEV(pAd, pNetDev); + + ASSERT(pAd); + +#ifdef RTMP_PCI_SUPPORT + if (pAd->infType == RTMP_DEV_INF_PCI) + { + POS_COOKIE _pObj = (POS_COOKIE)(pAd->OS_Cookie); + RTMP_MSI_ENABLE(pAd); + retval = request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ, (net_dev)->name, (net_dev)); + if (retval != 0) + printk("RT2860: request_irq ERROR(%d)\n", retval); + } +#endif // RTMP_PCI_SUPPORT // + + + return retval; + +} + + +int RtmpOSIRQRelease(IN PNET_DEV pNetDev) +{ + struct net_device *net_dev = pNetDev; + PRTMP_ADAPTER pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + ASSERT(pAd); + +#ifdef RTMP_PCI_SUPPORT + if (pAd->infType == RTMP_DEV_INF_PCI) + { + POS_COOKIE pObj = (POS_COOKIE)(pAd->OS_Cookie); + synchronize_irq(pObj->pci_dev->irq); + free_irq(pObj->pci_dev->irq, (net_dev)); + RTMP_MSI_DISABLE(pAd); + } +#endif // RTMP_PCI_SUPPORT // + + + return 0; +} + + +/******************************************************************************* + + File open/close related functions. + + *******************************************************************************/ +RTMP_OS_FD RtmpOSFileOpen(char *pPath, int flag, int mode) +{ + struct file *filePtr; + + filePtr = filp_open(pPath, flag, 0); + if (IS_ERR(filePtr)) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s(): Error %ld opening %s\n", __func__, -PTR_ERR(filePtr), pPath)); + } + + return (RTMP_OS_FD)filePtr; +} + +int RtmpOSFileClose(RTMP_OS_FD osfd) +{ + filp_close(osfd, NULL); + return 0; +} + + +void RtmpOSFileSeek(RTMP_OS_FD osfd, int offset) +{ + osfd->f_pos = offset; +} + + +int RtmpOSFileRead(RTMP_OS_FD osfd, char *pDataPtr, int readLen) +{ + // The object must have a read method + if (osfd->f_op && osfd->f_op->read) + { + return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos); + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n")); + return -1; + } +} + + +int RtmpOSFileWrite(RTMP_OS_FD osfd, char *pDataPtr, int writeLen) +{ + return osfd->f_op->write(osfd, pDataPtr, (size_t)writeLen, &osfd->f_pos); +} + + +void RtmpOSFSInfoChange(RTMP_OS_FS_INFO *pOSFSInfo, BOOLEAN bSet) +{ + if (bSet) + { + // Save uid and gid used for filesystem access. + // Set user and group to 0 (root) + pOSFSInfo->fsuid = current_fsuid(); + pOSFSInfo->fsgid = current_fsgid(); + pOSFSInfo->fs = get_fs(); + set_fs(KERNEL_DS); + } + else + { + set_fs(pOSFSInfo->fs); + } +} + + + +/******************************************************************************* + + Task create/management/kill related functions. + + *******************************************************************************/ +NDIS_STATUS RtmpOSTaskKill( + IN RTMP_OS_TASK *pTask) +{ + RTMP_ADAPTER *pAd; + int ret = NDIS_STATUS_FAILURE; + + pAd = (RTMP_ADAPTER *)pTask->priv; + +#ifdef KTHREAD_SUPPORT + if (pTask->kthread_task) + { + kthread_stop(pTask->kthread_task); + ret = NDIS_STATUS_SUCCESS; + } +#else + CHECK_PID_LEGALITY(pTask->taskPID) + { + printk("Terminate the task(%s) with pid(%d)!\n", pTask->taskName, GET_PID_NUMBER(pTask->taskPID)); + mb(); + pTask->task_killed = 1; + mb(); + ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1); + if (ret) + { + printk(KERN_WARNING "kill task(%s) with pid(%d) failed(retVal=%d)!\n", + pTask->taskName, GET_PID_NUMBER(pTask->taskPID), ret); + } + else + { + wait_for_completion(&pTask->taskComplete); + pTask->taskPID = THREAD_PID_INIT_VALUE; + pTask->task_killed = 0; + ret = NDIS_STATUS_SUCCESS; + } + } +#endif + + return ret; + +} + + +INT RtmpOSTaskNotifyToExit( + IN RTMP_OS_TASK *pTask) +{ + +#ifndef KTHREAD_SUPPORT + complete_and_exit(&pTask->taskComplete, 0); +#endif + + return 0; +} + + +void RtmpOSTaskCustomize( + IN RTMP_OS_TASK *pTask) { - daemonize(pThreadName /*"%s",pAd->net_dev->name*/); + +#ifndef KTHREAD_SUPPORT + + daemonize((PSTRING)&pTask->taskName[0]/*"%s",pAd->net_dev->name*/); allow_signal(SIGTERM); allow_signal(SIGKILL); current->flags |= PF_NOFREEZE; /* signal that we've started the thread */ - complete(pNotify); + complete(&pTask->taskComplete); + +#endif } + +NDIS_STATUS RtmpOSTaskAttach( + IN RTMP_OS_TASK *pTask, + IN int (*fn)(void *), + IN void *arg) +{ + NDIS_STATUS status = NDIS_STATUS_SUCCESS; + pid_t pid_number = -1; + +#ifdef KTHREAD_SUPPORT + pTask->task_killed = 0; + pTask->kthread_task = NULL; + pTask->kthread_task = kthread_run(fn, arg, pTask->taskName); + if (IS_ERR(pTask->kthread_task)) + status = NDIS_STATUS_FAILURE; +#else + pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS); + if (pid_number < 0) + { + DBGPRINT (RT_DEBUG_ERROR, ("Attach task(%s) failed!\n", pTask->taskName)); + status = NDIS_STATUS_FAILURE; + } + else + { + pTask->taskPID = GET_PID(pid_number); + + // Wait for the thread to start + wait_for_completion(&pTask->taskComplete); + status = NDIS_STATUS_SUCCESS; + } +#endif + return status; +} + + +NDIS_STATUS RtmpOSTaskInit( + IN RTMP_OS_TASK *pTask, + IN PSTRING pTaskName, + IN VOID *pPriv) +{ + int len; + + ASSERT(pTask); + +#ifndef KTHREAD_SUPPORT + NdisZeroMemory((PUCHAR)(pTask), sizeof(RTMP_OS_TASK)); +#endif + + len = strlen(pTaskName); + len = len > (RTMP_OS_TASK_NAME_LEN -1) ? (RTMP_OS_TASK_NAME_LEN-1) : len; + NdisMoveMemory(&pTask->taskName[0], pTaskName, len); + pTask->priv = pPriv; + +#ifndef KTHREAD_SUPPORT + RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema)); + pTask->taskPID = THREAD_PID_INIT_VALUE; + + init_completion (&pTask->taskComplete); +#endif + + return NDIS_STATUS_SUCCESS; +} + + void RTMP_IndicateMediaState( IN PRTMP_ADAPTER pAd) { @@ -999,3 +1245,259 @@ void RTMP_IndicateMediaState( } } +int RtmpOSWrielessEventSend( + IN RTMP_ADAPTER *pAd, + IN UINT32 eventType, + IN INT flags, + IN PUCHAR pSrcMac, + IN PUCHAR pData, + IN UINT32 dataLen) +{ + union iwreq_data wrqu; + + memset(&wrqu, 0, sizeof(wrqu)); + + if (flags>-1) + wrqu.data.flags = flags; + + if (pSrcMac) + memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN); + + if ((pData!= NULL) && (dataLen > 0)) + wrqu.data.length = dataLen; + + wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData); + return 0; +} + + +int RtmpOSNetDevAddrSet( + IN PNET_DEV pNetDev, + IN PUCHAR pMacAddr) +{ + struct net_device *net_dev; + RTMP_ADAPTER *pAd; + + net_dev = pNetDev; + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + // work-around for the SuSE due to it has it's own interface name management system. + { + NdisZeroMemory(pAd->StaCfg.dev_name, 16); + NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name)); + } + + NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6); + + return 0; +} + + + +/* + * Assign the network dev name for created Ralink WiFi interface. + */ +static int RtmpOSNetDevRequestName( + IN RTMP_ADAPTER *pAd, + IN PNET_DEV dev, + IN PSTRING pPrefixStr, + IN INT devIdx) +{ + PNET_DEV existNetDev; + STRING suffixName[IFNAMSIZ]; + STRING desiredName[IFNAMSIZ]; + int ifNameIdx, prefixLen, slotNameLen; + int Status; + + + prefixLen = strlen(pPrefixStr); + ASSERT((prefixLen < IFNAMSIZ)); + + for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) + { + memset(suffixName, 0, IFNAMSIZ); + memset(desiredName, 0, IFNAMSIZ); + strncpy(&desiredName[0], pPrefixStr, prefixLen); + + sprintf(suffixName, "%d", ifNameIdx); + + slotNameLen = strlen(suffixName); + ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ)); + strcat(desiredName, suffixName); + + existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]); + if (existNetDev == NULL) + break; + else + RtmpOSNetDeviceRefPut(existNetDev); + } + + if(ifNameIdx < 32) + { + strcpy(&dev->name[0], &desiredName[0]); + Status = NDIS_STATUS_SUCCESS; + } + else + { + DBGPRINT(RT_DEBUG_ERROR, + ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n", pPrefixStr)); + Status = NDIS_STATUS_FAILURE; + } + + return Status; +} + + +void RtmpOSNetDevClose( + IN PNET_DEV pNetDev) +{ + dev_close(pNetDev); +} + + +void RtmpOSNetDevFree(PNET_DEV pNetDev) +{ + ASSERT(pNetDev); + + free_netdev(pNetDev); +} + + +INT RtmpOSNetDevAlloc( + IN PNET_DEV *new_dev_p, + IN UINT32 privDataSize) +{ + // assign it as null first. + *new_dev_p = NULL; + + DBGPRINT(RT_DEBUG_TRACE, ("Allocate a net device with private data size=%d!\n", privDataSize)); + *new_dev_p = alloc_etherdev(privDataSize); + if (*new_dev_p) + return NDIS_STATUS_SUCCESS; + else + return NDIS_STATUS_FAILURE; +} + + +PNET_DEV RtmpOSNetDevGetByName(PNET_DEV pNetDev, PSTRING pDevName) +{ + PNET_DEV pTargetNetDev = NULL; + + pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName); + + return pTargetNetDev; +} + + +void RtmpOSNetDeviceRefPut(PNET_DEV pNetDev) +{ + /* + every time dev_get_by_name is called, and it has returned a valid struct + net_device*, dev_put should be called afterwards, because otherwise the + machine hangs when the device is unregistered (since dev->refcnt > 1). + */ + if(pNetDev) + dev_put(pNetDev); +} + + +INT RtmpOSNetDevDestory( + IN RTMP_ADAPTER *pAd, + IN PNET_DEV pNetDev) +{ + + // TODO: Need to fix this + printk("WARNING: This function(%s) not implement yet!!!\n", __func__); + return 0; +} + + +void RtmpOSNetDevDetach(PNET_DEV pNetDev) +{ + unregister_netdev(pNetDev); +} + + +int RtmpOSNetDevAttach( + IN PNET_DEV pNetDev, + IN RTMP_OS_NETDEV_OP_HOOK *pDevOpHook) +{ + int ret, rtnl_locked = FALSE; + + DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n")); + // If we need hook some callback function to the net device structrue, now do it. + if (pDevOpHook) + { + PRTMP_ADAPTER pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, pNetDev); + + pNetDev->netdev_ops = pDevOpHook->netdev_ops; + + /* OS specific flags, here we used to indicate if we are virtual interface */ + pNetDev->priv_flags = pDevOpHook->priv_flags; + + + if (pAd->OpMode == OPMODE_STA) + { + pNetDev->wireless_handlers = &rt28xx_iw_handler_def; + } + + + // copy the net device mac address to the net_device structure. + NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0], MAC_ADDR_LEN); + + rtnl_locked = pDevOpHook->needProtcted; + } + + if (rtnl_locked) + ret = register_netdevice(pNetDev); + else + ret = register_netdev(pNetDev); + + DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret)); + if (ret == 0) + return NDIS_STATUS_SUCCESS; + else + return NDIS_STATUS_FAILURE; +} + + +PNET_DEV RtmpOSNetDevCreate( + IN RTMP_ADAPTER *pAd, + IN INT devType, + IN INT devNum, + IN INT privMemSize, + IN PSTRING pNamePrefix) +{ + struct net_device *pNetDev = NULL; + int status; + + + /* allocate a new network device */ + status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize*/); + if (status != NDIS_STATUS_SUCCESS) + { + /* allocation fail, exit */ + DBGPRINT(RT_DEBUG_ERROR, ("Allocate network device fail (%s)...\n", pNamePrefix)); + return NULL; + } + + + /* find a available interface name, max 32 interfaces */ + status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum); + if (status != NDIS_STATUS_SUCCESS) + { + /* error! no any available ra name can be used! */ + DBGPRINT(RT_DEBUG_ERROR, ("Assign interface name (%s with suffix 0~32) failed...\n", pNamePrefix)); + RtmpOSNetDevFree(pNetDev); + + return NULL; + } + else + { + DBGPRINT(RT_DEBUG_TRACE, ("The name of the new %s interface is %s...\n", pNamePrefix, pNetDev->name)); + } + + return pNetDev; +} Index: b/drivers/staging/rt2860/rt_linux.h =================================================================== --- a/drivers/staging/rt2860/rt_linux.h +++ b/drivers/staging/rt2860/rt_linux.h @@ -23,27 +23,22 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * ************************************************************************* - */ -/***********************************************************************/ -/* */ -/* Program: rt_linux.c */ -/* Created: 4/21/2006 1:17:38 PM */ -/* Author: Wu Xi-Kun */ -/* Comments: `description` */ -/* */ -/*---------------------------------------------------------------------*/ -/* */ -/* History: */ -/* Revision 1.1 4/21/2006 1:17:38 PM xsikun */ -/* Initial revision */ -/* */ -/***********************************************************************/ + Module Name: + rt_linux.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- +*/ + +#ifndef __RT_LINUX_H__ +#define __RT_LINUX_H__ -#include "rtmp_type.h" #include #include - #include #include #include @@ -69,60 +64,80 @@ #define __KERNEL_SYSCALLS__ #include #include +#include +#include // for get_unaligned() +#define KTHREAD_SUPPORT 1 +// RT2870 2.1.0.0 has it disabled -#define MEM_ALLOC_FLAG (GFP_ATOMIC) //(GFP_DMA | GFP_ATOMIC) +#ifdef KTHREAD_SUPPORT +#include +#include +#endif // KTHREAD_SUPPORT // -#ifndef IFNAMSIZ -#define IFNAMSIZ 16 -#endif +#undef AP_WSC_INCLUDED +#undef STA_WSC_INCLUDED +#undef WSC_INCLUDED + + + + +#ifdef KTHREAD_SUPPORT +#endif // KTHREAD_SUPPORT // + +/*********************************************************************************** + * Profile related sections + ***********************************************************************************/ + + +#ifdef RTMP_MAC_PCI +#define STA_PROFILE_PATH "/etc/Wireless/RT2860STA/RT2860STA.dat" +#define STA_DRIVER_VERSION "2.1.0.0" +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB +#define STA_PROFILE_PATH "/etc/Wireless/RT2870STA/RT2870STA.dat" +#define STA_DRIVER_VERSION "2.1.0.0" +// RT3070 version: 2.1.1.0 +#endif // RTMP_MAC_USB // -//#define CONFIG_CKIP_SUPPORT +extern const struct iw_handler_def rt28xx_iw_handler_def; + +/*********************************************************************************** + * Compiler related definitions + ***********************************************************************************/ #undef __inline #define __inline static inline +#define IN +#define OUT +#define INOUT +#define NDIS_STATUS INT -typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_dev); -// add by kathy +/*********************************************************************************** + * OS Specific definitions and data structures + ***********************************************************************************/ +typedef struct pci_dev * PPCI_DEV; +typedef struct net_device * PNET_DEV; +typedef void * PNDIS_PACKET; +typedef char NDIS_PACKET; +typedef PNDIS_PACKET * PPNDIS_PACKET; +typedef dma_addr_t NDIS_PHYSICAL_ADDRESS; +typedef dma_addr_t * PNDIS_PHYSICAL_ADDRESS; +typedef void * NDIS_HANDLE; +typedef char * PNDIS_BUFFER; +typedef struct pid * RTMP_OS_PID; +typedef struct semaphore RTMP_OS_SEM; -/* order of "if defined()" is important, because for 3070 driver - both RT2870 and RT3070 are defined */ -#if defined(RT2860) - #define STA_PROFILE_PATH "/etc/Wireless/RT2860STA/RT2860STA.dat" - #define STA_RTMP_FIRMWARE_FILE_NAME "/etc/Wireless/RT2860STA/RT2860STA.bin" - #define STA_NIC_DEVICE_NAME "RT2860STA" - #define STA_DRIVER_VERSION "1.8.1.1" -#elif defined(RT3070) - #define STA_PROFILE_PATH "/etc/Wireless/RT3070STA/RT3070STA.dat" - #define STA_RT2870_IMAGE_FILE_NAME "/etc/Wireless/RT3070STA/rt2870.bin" - #define STA_NIC_DEVICE_NAME "RT3070STA" - #define STA_DRIVER_VERSION "2.0.1.0" -#elif defined(RT2870) - #define STA_PROFILE_PATH "/etc/Wireless/RT2870STA/RT2870STA.dat" - #define STA_RT2870_IMAGE_FILE_NAME "/etc/Wireless/RT2870STA/rt2870.bin" - #define STA_NIC_DEVICE_NAME "RT2870STA" - #define STA_DRIVER_VERSION "1.4.0.0" -#endif +typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_dev); -#ifdef RT2860 +#ifdef RTMP_MAC_PCI #ifndef PCI_DEVICE #define PCI_DEVICE(vend,dev) \ .vendor = (vend), .device = (dev), \ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID #endif // PCI_DEVICE // -#endif - -#define RTMP_TIME_AFTER(a,b) \ - (typecheck(unsigned long, (unsigned long)a) && \ - typecheck(unsigned long, (unsigned long)b) && \ - ((long)(b) - (long)(a) < 0)) - -#define RTMP_TIME_AFTER_EQ(a,b) \ - (typecheck(unsigned long, (unsigned long)a) && \ - typecheck(unsigned long, (unsigned long)b) && \ - ((long)(a) - (long)(b) >= 0)) -#define RTMP_TIME_BEFORE(a,b) RTMP_TIME_AFTER_EQ(b,a) +#endif // RTMP_MAC_PCI // #define RT_MOD_INC_USE_COUNT() \ if (!try_module_get(THIS_MODULE)) \ @@ -133,220 +148,336 @@ typedef int (*HARD_START_XMIT_FUNC)(stru #define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE); -#define OS_HZ HZ +#define RTMP_INC_REF(_A) 0 +#define RTMP_DEC_REF(_A) 0 +#define RTMP_GET_REF(_A) 0 -#define ETH_LENGTH_OF_ADDRESS 6 -#define IN -#define OUT +// This function will be called when query /proc +struct iw_statistics *rt28xx_get_wireless_stats( + IN struct net_device *net_dev); + + +/*********************************************************************************** + * Network related constant definitions + ***********************************************************************************/ +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif + +#define ETH_LENGTH_OF_ADDRESS 6 -#define NDIS_STATUS INT #define NDIS_STATUS_SUCCESS 0x00 #define NDIS_STATUS_FAILURE 0x01 #define NDIS_STATUS_INVALID_DATA 0x02 #define NDIS_STATUS_RESOURCES 0x03 +#define NDIS_SET_PACKET_STATUS(_p, _status) do{} while(0) +#define NdisWriteErrorLogEntry(_a, _b, _c, _d) do{} while(0) + +/* statistics counter */ +#define STATS_INC_RX_PACKETS(_pAd, _dev) +#define STATS_INC_TX_PACKETS(_pAd, _dev) + +#define STATS_INC_RX_BYTESS(_pAd, _dev, len) +#define STATS_INC_TX_BYTESS(_pAd, _dev, len) + +#define STATS_INC_RX_ERRORS(_pAd, _dev) +#define STATS_INC_TX_ERRORS(_pAd, _dev) + +#define STATS_INC_RX_DROPPED(_pAd, _dev) +#define STATS_INC_TX_DROPPED(_pAd, _dev) + + +/*********************************************************************************** + * Ralink Specific network related constant definitions + ***********************************************************************************/ #define MIN_NET_DEVICE_FOR_AID 0x00 //0x00~0x3f #define MIN_NET_DEVICE_FOR_MBSSID 0x00 //0x00,0x10,0x20,0x30 #define MIN_NET_DEVICE_FOR_WDS 0x10 //0x40,0x50,0x60,0x70 #define MIN_NET_DEVICE_FOR_APCLI 0x20 #define MIN_NET_DEVICE_FOR_MESH 0x30 #define MIN_NET_DEVICE_FOR_DLS 0x40 +#define NET_DEVICE_REAL_IDX_MASK 0x0f // for each operation mode, we maximum support 15 entities. + #define NDIS_PACKET_TYPE_DIRECTED 0 #define NDIS_PACKET_TYPE_MULTICAST 1 #define NDIS_PACKET_TYPE_BROADCAST 2 #define NDIS_PACKET_TYPE_ALL_MULTICAST 3 +#define NDIS_PACKET_TYPE_PROMISCUOUS 4 -struct os_lock { - spinlock_t lock; - unsigned long flags; -}; +/*********************************************************************************** + * OS signaling related constant definitions + ***********************************************************************************/ -struct os_cookie { -#ifdef RT2860 - struct pci_dev *pci_dev; - struct pci_dev *parent_pci_dev; - dma_addr_t pAd_pa; -#endif -#ifdef RT2870 - struct usb_device *pUsb_Dev; - struct pid *MLMEThr_pid; - struct pid *RTUSBCmdThr_pid; - struct pid *TimerQThr_pid; -#endif // RT2870 // - - struct tasklet_struct rx_done_task; - struct tasklet_struct mgmt_dma_done_task; - struct tasklet_struct ac0_dma_done_task; - struct tasklet_struct ac1_dma_done_task; - struct tasklet_struct ac2_dma_done_task; - struct tasklet_struct ac3_dma_done_task; - struct tasklet_struct hcca_dma_done_task; - struct tasklet_struct tbtt_task; -#ifdef RT2860 - struct tasklet_struct fifo_statistic_full_task; -#endif -#ifdef RT2870 - struct tasklet_struct null_frame_complete_task; - struct tasklet_struct rts_frame_complete_task; - struct tasklet_struct pspoll_frame_complete_task; -#endif // RT2870 // +/*********************************************************************************** + * OS file operation related data structure definitions + ***********************************************************************************/ +typedef struct file* RTMP_OS_FD; - unsigned long apd_pid; //802.1x daemon pid - INT ioctl_if_type; - INT ioctl_if; -}; +typedef struct _RTMP_OS_FS_INFO_ +{ + int fsuid; + int fsgid; + mm_segment_t fs; +}RTMP_OS_FS_INFO; -#undef ASSERT -#define ASSERT(x) +#define IS_FILE_OPEN_ERR(_fd) IS_ERR((_fd)) + + +/*********************************************************************************** + * OS semaphore related data structure and definitions + ***********************************************************************************/ +struct os_lock { + spinlock_t lock; + unsigned long flags; +}; -typedef struct os_cookie * POS_COOKIE; -typedef struct pci_dev * PPCI_DEV; -typedef struct net_device * PNET_DEV; -typedef void * PNDIS_PACKET; -typedef char NDIS_PACKET; -typedef PNDIS_PACKET * PPNDIS_PACKET; -typedef dma_addr_t NDIS_PHYSICAL_ADDRESS; -typedef dma_addr_t * PNDIS_PHYSICAL_ADDRESS; typedef spinlock_t NDIS_SPIN_LOCK; -typedef struct timer_list NDIS_MINIPORT_TIMER; -typedef void * NDIS_HANDLE; -typedef char * PNDIS_BUFFER; +// +// spin_lock enhanced for Nested spin lock +// +#define NdisAllocateSpinLock(__lock) \ +{ \ + spin_lock_init((spinlock_t *)(__lock)); \ +} +#define NdisFreeSpinLock(lock) \ + do{}while(0) -void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen); -dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction); -void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction); +#define RTMP_SEM_LOCK(__lock) \ +{ \ + spin_lock_bh((spinlock_t *)(__lock)); \ +} +#define RTMP_SEM_UNLOCK(__lock) \ +{ \ + spin_unlock_bh((spinlock_t *)(__lock)); \ +} -//////////////////////////////////////// -// MOVE TO rtmp.h ? -///////////////////////////////////////// -#define PKTSRC_NDIS 0x7f -#define PKTSRC_DRIVER 0x0f -#define PRINT_MAC(addr) \ - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] +// sample, use semaphore lock to replace IRQ lock, 2007/11/15 +#define RTMP_IRQ_LOCK(__lock, __irqflags) \ +{ \ + __irqflags = 0; \ + spin_lock_bh((spinlock_t *)(__lock)); \ + pAd->irq_disabled |= 1; \ +} -#define RT2860_PCI_DEVICE_ID 0x0601 +#define RTMP_IRQ_UNLOCK(__lock, __irqflag) \ +{ \ + pAd->irq_disabled &= 0; \ + spin_unlock_bh((spinlock_t *)(__lock)); \ +} -#ifdef RT2860 -#define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \ - linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir) +#define RTMP_INT_LOCK(__lock, __irqflags) \ +{ \ + spin_lock_irqsave((spinlock_t *)__lock, __irqflags); \ +} -#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) \ - linux_pci_unmap_single(_handle, _ptr, _size, _dir) +#define RTMP_INT_UNLOCK(__lock, __irqflag) \ +{ \ + spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag)); \ +} -#define PCI_ALLOC_CONSISTENT(_pci_dev, _size, _ptr) \ - pci_alloc_consistent(_pci_dev, _size, _ptr) +#define NdisAcquireSpinLock RTMP_SEM_LOCK +#define NdisReleaseSpinLock RTMP_SEM_UNLOCK -#define PCI_FREE_CONSISTENT(_pci_dev, _size, _virtual_addr, _physical_addr) \ - pci_free_consistent(_pci_dev, _size, _virtual_addr, _physical_addr) +#ifndef wait_event_interruptible_timeout +#define __wait_event_interruptible_timeout(wq, condition, ret) \ +do { \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + ret = schedule_timeout(ret); \ + if (!ret) \ + break; \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) -#define DEV_ALLOC_SKB(_length) \ - dev_alloc_skb(_length) +#define wait_event_interruptible_timeout(wq, condition, timeout) \ +({ \ + long __ret = timeout; \ + if (!(condition)) \ + __wait_event_interruptible_timeout(wq, condition, __ret); \ + __ret; \ +}) #endif -#ifdef RT2870 -#define PCI_MAP_SINGLE(_handle, _ptr, _size, _dir) (ULONG)0 -#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) -#endif // RT2870 // +#define RTMP_SEM_EVENT_INIT_LOCKED(_pSema) sema_init((_pSema), 0) +#define RTMP_SEM_EVENT_INIT(_pSema) sema_init((_pSema), 1) +#define RTMP_SEM_EVENT_WAIT(_pSema, _status) ((_status) = down_interruptible((_pSema))) +#define RTMP_SEM_EVENT_UP(_pSema) up(_pSema) + +#ifdef KTHREAD_SUPPORT +#define RTMP_WAIT_EVENT_INTERRUPTIBLE(_pAd, _pTask) \ +{ \ + wait_event_interruptible(_pTask->kthread_q, \ + _pTask->kthread_running || kthread_should_stop()); \ + _pTask->kthread_running = FALSE; \ + if (kthread_should_stop()) \ + { \ + RTMP_SET_FLAG(_pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); \ + break; \ + } \ +} +#endif +#ifdef KTHREAD_SUPPORT +#define WAKE_UP(_pTask) \ + do{ \ + if ((_pTask)->kthread_task) \ + { \ + (_pTask)->kthread_running = TRUE; \ + wake_up(&(_pTask)->kthread_q); \ + } \ + }while(0) +#endif + +/*********************************************************************************** + * OS Memory Access related data structure and definitions + ***********************************************************************************/ +#define MEM_ALLOC_FLAG (GFP_ATOMIC) //(GFP_DMA | GFP_ATOMIC) -#define BEACON_FRAME_DMA_CACHE_WBACK(_ptr, _size) \ - dma_cache_wback(_ptr, _size) +#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length) +#define NdisCopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length) +#define NdisZeroMemory(Destination, Length) memset(Destination, 0, Length) +#define NdisFillMemory(Destination, Length, Fill) memset(Destination, Fill, Length) +#define NdisCmpMemory(Destination, Source, Length) memcmp(Destination, Source, Length) +#define NdisEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length)) +#define RTMPEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length)) +#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE) +#define MlmeFreeMemory(_pAd, _pVA) os_free_mem(_pAd, _pVA) -////////////////////////////////////////// -// -////////////////////////////////////////// +#define COPY_MAC_ADDR(Addr1, Addr2) memcpy((Addr1), (Addr2), MAC_ADDR_LEN) -#define NdisMIndicateStatus(_w, _x, _y, _z) +/*********************************************************************************** + * OS task related data structure and definitions + ***********************************************************************************/ +#define RTMP_OS_MGMT_TASK_FLAGS CLONE_VM + +typedef struct pid * THREAD_PID; +#define THREAD_PID_INIT_VALUE NULL +#define GET_PID(_v) find_get_pid((_v)) +#define GET_PID_NUMBER(_v) pid_nr((_v)) +#define CHECK_PID_LEGALITY(_pid) if (pid_nr((_pid)) > 0) +#define KILL_THREAD_PID(_A, _B, _C) kill_pid((_A), (_B), (_C)) + +typedef struct tasklet_struct RTMP_NET_TASK_STRUCT; +typedef struct tasklet_struct *PRTMP_NET_TASK_STRUCT; + + +/*********************************************************************************** + * Timer related definitions and data structures. + **********************************************************************************/ +#define OS_HZ HZ +typedef struct timer_list NDIS_MINIPORT_TIMER; typedef struct timer_list RTMP_OS_TIMER; +typedef void (*TIMER_FUNCTION)(unsigned long); -#ifdef RT2870 -/* ----------------- Timer Related MARCO ---------------*/ -// In RT2870, we have a lot of timer functions and will read/write register, it's -// not allowed in Linux USB sub-system to do it ( because of sleep issue when submit -// to ctrl pipe). So we need a wrapper function to take care it. - -typedef VOID (*RT2870_TIMER_HANDLE)( - IN PVOID SystemSpecific1, - IN PVOID FunctionContext, - IN PVOID SystemSpecific2, - IN PVOID SystemSpecific3); -#endif // RT2870 // - - -typedef struct _RALINK_TIMER_STRUCT { - RTMP_OS_TIMER TimerObj; // Ndis Timer object - BOOLEAN Valid; // Set to True when call RTMPInitTimer - BOOLEAN State; // True if timer cancelled - BOOLEAN PeriodicType; // True if timer is periodic timer - BOOLEAN Repeat; // True if periodic timer - ULONG TimerValue; // Timer value in milliseconds - ULONG cookie; // os specific object -#ifdef RT2870 - RT2870_TIMER_HANDLE handle; - void *pAd; -#endif // RT2870 // -} RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT; +#define OS_WAIT(_time) \ +{ int _i; \ + long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\ + wait_queue_head_t _wait; \ + init_waitqueue_head(&_wait); \ + for (_i=0; _i<(_loop); _i++) \ + wait_event_interruptible_timeout(_wait, 0, ONE_TICK); } -#ifdef RT2870 +#define RTMP_TIME_AFTER(a,b) \ + (typecheck(unsigned long, (unsigned long)a) && \ + typecheck(unsigned long, (unsigned long)b) && \ + ((long)(b) - (long)(a) < 0)) -typedef enum _RT2870_KERNEL_THREAD_STATUS_ -{ - RT2870_THREAD_UNKNOWN = 0, - RT2870_THREAD_INITED = 1, - RT2870_THREAD_RUNNING = 2, - RT2870_THREAD_STOPED = 4, -}RT2870_KERNEL_THREAD_STATUS; +#define RTMP_TIME_AFTER_EQ(a,b) \ + (typecheck(unsigned long, (unsigned long)a) && \ + typecheck(unsigned long, (unsigned long)b) && \ + ((long)(a) - (long)(b) >= 0)) +#define RTMP_TIME_BEFORE(a,b) RTMP_TIME_AFTER_EQ(b,a) -#define RT2870_THREAD_CAN_DO_INSERT (RT2870_THREAD_INITED |RT2870_THREAD_RUNNING) +#define ONE_TICK 1 -typedef struct _RT2870_TIMER_ENTRY_ +static inline void NdisGetSystemUpTime(ULONG *time) { - RALINK_TIMER_STRUCT *pRaTimer; - struct _RT2870_TIMER_ENTRY_ *pNext; -}RT2870_TIMER_ENTRY; + *time = jiffies; +} -#define TIMER_QUEUE_SIZE_MAX 128 -typedef struct _RT2870_TIMER_QUEUE_ -{ - unsigned int status; - UCHAR *pTimerQPoll; - RT2870_TIMER_ENTRY *pQPollFreeList; - RT2870_TIMER_ENTRY *pQHead; - RT2870_TIMER_ENTRY *pQTail; -}RT2870_TIMER_QUEUE; -#endif // RT2870 // +/*********************************************************************************** + * OS specific cookie data structure binding to RTMP_ADAPTER + ***********************************************************************************/ + +struct os_cookie { +#ifdef RTMP_MAC_PCI + struct pci_dev *pci_dev; + struct pci_dev *parent_pci_dev; + USHORT DeviceID; + dma_addr_t pAd_pa; +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB + struct usb_device *pUsb_Dev; +#endif // RTMP_MAC_USB // + + RTMP_NET_TASK_STRUCT rx_done_task; + RTMP_NET_TASK_STRUCT mgmt_dma_done_task; + RTMP_NET_TASK_STRUCT ac0_dma_done_task; + RTMP_NET_TASK_STRUCT ac1_dma_done_task; + RTMP_NET_TASK_STRUCT ac2_dma_done_task; + RTMP_NET_TASK_STRUCT ac3_dma_done_task; + RTMP_NET_TASK_STRUCT tbtt_task; +#ifdef RTMP_MAC_PCI + RTMP_NET_TASK_STRUCT fifo_statistic_full_task; +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB + RTMP_NET_TASK_STRUCT null_frame_complete_task; + RTMP_NET_TASK_STRUCT rts_frame_complete_task; + RTMP_NET_TASK_STRUCT pspoll_frame_complete_task; +#endif // RTMP_MAC_USB // + unsigned long apd_pid; //802.1x daemon pid + INT ioctl_if_type; + INT ioctl_if; +}; -//#define DBG 1 +typedef struct os_cookie * POS_COOKIE; -// -// MACRO for debugging information -// + + +/*********************************************************************************** + * OS debugging and printing related definitions and data structure + ***********************************************************************************/ +#define PRINT_MAC(addr) \ + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5] #ifdef DBG extern ULONG RTDebugLevel; #define DBGPRINT_RAW(Level, Fmt) \ -{ \ +do{ \ if (Level <= RTDebugLevel) \ { \ printk Fmt; \ } \ -} +}while(0) #define DBGPRINT(Level, Fmt) DBGPRINT_RAW(Level, Fmt) @@ -370,55 +501,83 @@ extern ULONG RTDebugLevel; #define DBGPRINT_ERR(Fmt) #endif +#define ASSERT(x) -// -// spin_lock enhanced for Nested spin lock -// -#define NdisAllocateSpinLock(__lock) \ -{ \ - spin_lock_init((spinlock_t *)(__lock)); \ -} +void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen); -#define NdisFreeSpinLock(lock) \ -{ \ -} +/********************************************************************************************************* + The following code are not revised, temporary put it here. + *********************************************************************************************************/ -#define RTMP_SEM_LOCK(__lock) \ -{ \ - spin_lock_bh((spinlock_t *)(__lock)); \ -} -#define RTMP_SEM_UNLOCK(__lock) \ -{ \ - spin_unlock_bh((spinlock_t *)(__lock)); \ -} +/*********************************************************************************** + * Device DMA Access related definitions and data structures. + **********************************************************************************/ +#ifdef RTMP_MAC_PCI +dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction); +void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction); -// sample, use semaphore lock to replace IRQ lock, 2007/11/15 -#define RTMP_IRQ_LOCK(__lock, __irqflags) \ -{ \ - __irqflags = 0; \ - spin_lock_bh((spinlock_t *)(__lock)); \ - pAd->irq_disabled |= 1; \ -} +#define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \ + linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir) -#define RTMP_IRQ_UNLOCK(__lock, __irqflag) \ -{ \ - pAd->irq_disabled &= 0; \ - spin_unlock_bh((spinlock_t *)(__lock)); \ -} +#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) \ + linux_pci_unmap_single(_handle, _ptr, _size, _dir) -#define RTMP_INT_LOCK(__lock, __irqflags) \ -{ \ - spin_lock_irqsave((spinlock_t *)__lock, __irqflags); \ -} +#define PCI_ALLOC_CONSISTENT(_pci_dev, _size, _ptr) \ + pci_alloc_consistent(_pci_dev, _size, _ptr) + +#define PCI_FREE_CONSISTENT(_pci_dev, _size, _virtual_addr, _physical_addr) \ + pci_free_consistent(_pci_dev, _size, _virtual_addr, _physical_addr) + +#define DEV_ALLOC_SKB(_length) \ + dev_alloc_skb(_length) +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB +#define PCI_MAP_SINGLE(_handle, _ptr, _size, _dir) (ULONG)0 + +#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) +#endif // RTMP_MAC_USB // + +/* + * ULONG + * RTMP_GetPhysicalAddressLow( + * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress); + */ +#define RTMP_GetPhysicalAddressLow(PhysicalAddress) (PhysicalAddress) + +/* + * ULONG + * RTMP_GetPhysicalAddressHigh( + * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress); + */ +#define RTMP_GetPhysicalAddressHigh(PhysicalAddress) (0) + +/* + * VOID + * RTMP_SetPhysicalAddressLow( + * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress, + * IN ULONG Value); + */ +#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value) \ + PhysicalAddress = Value; + +/* + * VOID + * RTMP_SetPhysicalAddressHigh( + * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress, + * IN ULONG Value); + */ +#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value) + +#define NdisMIndicateStatus(_w, _x, _y, _z) -#define RTMP_INT_UNLOCK(__lock, __irqflag) \ -{ \ - spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag)); \ -} -#ifdef RT2860 + +/*********************************************************************************** + * Device Register I/O Access related definitions and data structures. + **********************************************************************************/ +#ifdef RTMP_MAC_PCI //Patch for ASIC turst read/write bug, needs to remove after metel fix #define RTMP_IO_READ32(_A, _R, _pV) \ { \ @@ -430,11 +589,7 @@ extern ULONG RTDebugLevel; else \ *_pV = 0; \ } -#define RTMP_IO_FORCE_READ32(_A, _R, _pV) \ -{ \ - (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \ - (*_pV = readl((void *)((_A)->CSRBaseAddress + (_R)))); \ -} + #define RTMP_IO_READ8(_A, _R, _pV) \ { \ (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \ @@ -446,153 +601,96 @@ extern ULONG RTDebugLevel; { \ UINT Val; \ Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \ - writel(_V, (void *)((_A)->CSRBaseAddress + (_R))); \ + writel((_V), (void *)((_A)->CSRBaseAddress + (_R))); \ } \ } + + + +#if defined(RALINK_2880) || defined(RALINK_3052) +#define RTMP_IO_WRITE8(_A, _R, _V) \ +{ \ + ULONG Val; \ + UCHAR _i; \ + _i = ((_R) & 0x3); \ + Val = readl((void *)((_A)->CSRBaseAddress + ((_R) - _i))); \ + Val = Val & (~(0x000000ff << ((_i)*8))); \ + Val = Val | ((ULONG)(_V) << ((_i)*8)); \ + writel((Val), (void *)((_A)->CSRBaseAddress + ((_R) - _i))); \ +} +#else #define RTMP_IO_WRITE8(_A, _R, _V) \ { \ UINT Val; \ Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \ writeb((_V), (PUCHAR)((_A)->CSRBaseAddress + (_R))); \ } +#endif // #if defined(BRCM_6358) || defined(RALINK_2880) // + #define RTMP_IO_WRITE16(_A, _R, _V) \ { \ UINT Val; \ Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)); \ writew((_V), (PUSHORT)((_A)->CSRBaseAddress + (_R))); \ } -#endif /* RT2860 */ -#ifdef RT2870 +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB //Patch for ASIC turst read/write bug, needs to remove after metel fix #define RTMP_IO_READ32(_A, _R, _pV) \ - RTUSBReadMACRegister(_A, _R, _pV) + RTUSBReadMACRegister((_A), (_R), (PUINT32) (_pV)) #define RTMP_IO_READ8(_A, _R, _pV) \ { \ } #define RTMP_IO_WRITE32(_A, _R, _V) \ - RTUSBWriteMACRegister(_A, _R, _V) - + RTUSBWriteMACRegister((_A), (_R), (UINT32) (_V)) #define RTMP_IO_WRITE8(_A, _R, _V) \ { \ USHORT _Val = _V; \ - RTUSBSingleWrite(_A, _R, _Val); \ + RTUSBSingleWrite((_A), (_R), (USHORT) (_Val)); \ } - #define RTMP_IO_WRITE16(_A, _R, _V) \ { \ - RTUSBSingleWrite(_A, _R, _V); \ + RTUSBSingleWrite((_A), (_R), (USHORT) (_V)); \ } -#endif // RT2870 // - -#ifndef wait_event_interruptible_timeout -#define __wait_event_interruptible_timeout(wq, condition, ret) \ -do { \ - wait_queue_t __wait; \ - init_waitqueue_entry(&__wait, current); \ - add_wait_queue(&wq, &__wait); \ - for (;;) { \ - set_current_state(TASK_INTERRUPTIBLE); \ - if (condition) \ - break; \ - if (!signal_pending(current)) { \ - ret = schedule_timeout(ret); \ - if (!ret) \ - break; \ - continue; \ - } \ - ret = -ERESTARTSYS; \ - break; \ - } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ -} while (0) - -#define wait_event_interruptible_timeout(wq, condition, timeout) \ -({ \ - long __ret = timeout; \ - if (!(condition)) \ - __wait_event_interruptible_timeout(wq, condition, __ret); \ - __ret; \ -}) -#endif -#define ONE_TICK 1 -#define OS_WAIT(_time) \ -{ int _i; \ - long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\ - wait_queue_head_t _wait; \ - init_waitqueue_head(&_wait); \ - for (_i=0; _i<(_loop); _i++) \ - wait_event_interruptible_timeout(_wait, 0, ONE_TICK); } +#endif // RTMP_MAC_USB // +/*********************************************************************************** + * Network Related data structure and marco definitions + ***********************************************************************************/ +#define PKTSRC_NDIS 0x7f +#define PKTSRC_DRIVER 0x0f -typedef void (*TIMER_FUNCTION)(unsigned long); +#define RTMP_OS_NETDEV_SET_PRIV(_pNetDev, _pPriv) ((_pNetDev)->ml_priv = (_pPriv)) +#define RTMP_OS_NETDEV_GET_PRIV(_pNetDev) ((_pNetDev)->ml_priv) +#define RTMP_OS_NETDEV_GET_DEVNAME(_pNetDev) ((_pNetDev)->name) +#define RTMP_OS_NETDEV_GET_PHYADDR(_PNETDEV) ((_PNETDEV)->dev_addr) + +#define RTMP_OS_NETDEV_START_QUEUE(_pNetDev) netif_start_queue((_pNetDev)) +#define RTMP_OS_NETDEV_STOP_QUEUE(_pNetDev) netif_stop_queue((_pNetDev)) +#define RTMP_OS_NETDEV_WAKE_QUEUE(_pNetDev) netif_wake_queue((_pNetDev)) +#define RTMP_OS_NETDEV_CARRIER_OFF(_pNetDev) netif_carrier_off((_pNetDev)) -#define COPY_MAC_ADDR(Addr1, Addr2) memcpy((Addr1), (Addr2), MAC_ADDR_LEN) +#define QUEUE_ENTRY_TO_PACKET(pEntry) \ + (PNDIS_PACKET)(pEntry) -#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE) -#define MlmeFreeMemory(_pAd, _pVA) os_free_mem(_pAd, _pVA) +#define PACKET_TO_QUEUE_ENTRY(pPacket) \ + (PQUEUE_ENTRY)(pPacket) -#ifdef RT2860 -#define BUILD_TIMER_FUNCTION(_func) \ -void linux_##_func(unsigned long data) \ -{ \ - PRALINK_TIMER_STRUCT pTimer = (PRALINK_TIMER_STRUCT) data; \ - \ - _func(NULL, (PVOID) pTimer->cookie, NULL, pTimer); \ - if (pTimer->Repeat) \ - RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); \ -} +#ifdef CONFIG_5VT_ENHANCE +#define BRIDGE_TAG 0x35564252 // depends on 5VT define in br_input.c #endif -#ifdef RT2870 -#define BUILD_TIMER_FUNCTION(_func) \ -void linux_##_func(unsigned long data) \ -{ \ - PRALINK_TIMER_STRUCT _pTimer = (PRALINK_TIMER_STRUCT)data; \ - RT2870_TIMER_ENTRY *_pQNode; \ - RTMP_ADAPTER *_pAd; \ - \ - _pTimer->handle = _func; \ - _pAd = (RTMP_ADAPTER *)_pTimer->pAd; \ - _pQNode = RT2870_TimerQ_Insert(_pAd, _pTimer); \ - if ((_pQNode == NULL) && (_pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)) \ - RTMP_OS_Add_Timer(&_pTimer->TimerObj, HZ); \ -} -#endif // RT2870 // - - -#define DECLARE_TIMER_FUNCTION(_func) \ -void linux_##_func(unsigned long data) - -#define GET_TIMER_FUNCTION(_func) \ - linux_##_func - -DECLARE_TIMER_FUNCTION(MlmePeriodicExec); -DECLARE_TIMER_FUNCTION(MlmeRssiReportExec); -DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout); -DECLARE_TIMER_FUNCTION(APSDPeriodicExec); -DECLARE_TIMER_FUNCTION(AsicRfTuningExec); -#ifdef RT2870 -DECLARE_TIMER_FUNCTION(BeaconUpdateExec); -#endif // RT2870 // - -DECLARE_TIMER_FUNCTION(BeaconTimeout); -DECLARE_TIMER_FUNCTION(ScanTimeout); -DECLARE_TIMER_FUNCTION(AuthTimeout); -DECLARE_TIMER_FUNCTION(AssocTimeout); -DECLARE_TIMER_FUNCTION(ReassocTimeout); -DECLARE_TIMER_FUNCTION(DisassocTimeout); -DECLARE_TIMER_FUNCTION(LinkDownExec); -DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec); -DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc); -DECLARE_TIMER_FUNCTION(PsPollWakeExec); -DECLARE_TIMER_FUNCTION(RadioOnExec); -void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time); +#define GET_SG_LIST_FROM_PACKET(_p, _sc) \ + rt_get_sg_list_from_packet(_p, _sc) +#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status) \ +{ \ + RTMPFreeNdisPacket(_pAd, _pPacket); \ +} /* * packet helper @@ -604,12 +702,18 @@ void RTMP_GetCurrentSystemTime(LARGE_INT #define GET_OS_PKT_DATAPTR(_pkt) \ (RTPKT_TO_OSPKT(_pkt)->data) +#define SET_OS_PKT_DATAPTR(_pkt, _dataPtr) \ + (RTPKT_TO_OSPKT(_pkt)->data) = (_dataPtr) #define GET_OS_PKT_LEN(_pkt) \ (RTPKT_TO_OSPKT(_pkt)->len) +#define SET_OS_PKT_LEN(_pkt, _len) \ + (RTPKT_TO_OSPKT(_pkt)->len) = (_len) #define GET_OS_PKT_DATATAIL(_pkt) \ (RTPKT_TO_OSPKT(_pkt)->tail) +#define SET_OS_PKT_DATATAIL(_pkt, _start, _len) \ + ((RTPKT_TO_OSPKT(_pkt))->tail) = (PUCHAR)((_start) + (_len)) #define GET_OS_PKT_HEAD(_pkt) \ (RTPKT_TO_OSPKT(_pkt)->head) @@ -619,6 +723,8 @@ void RTMP_GetCurrentSystemTime(LARGE_INT #define GET_OS_PKT_NETDEV(_pkt) \ (RTPKT_TO_OSPKT(_pkt)->dev) +#define SET_OS_PKT_NETDEV(_pkt, _pNetDev) \ + (RTPKT_TO_OSPKT(_pkt)->dev) = (_pNetDev) #define GET_OS_PKT_TYPE(_pkt) \ (RTPKT_TO_OSPKT(_pkt)) @@ -627,6 +733,8 @@ void RTMP_GetCurrentSystemTime(LARGE_INT (RTPKT_TO_OSPKT(_pkt)->next) +#define OS_PKT_CLONED(_pkt) skb_cloned(RTPKT_TO_OSPKT(_pkt)) + #define OS_NTOHS(_Val) \ (ntohs(_Val)) #define OS_HTONS(_Val) \ @@ -636,27 +744,8 @@ void RTMP_GetCurrentSystemTime(LARGE_INT #define OS_HTONL(_Val) \ (htonl(_Val)) -/* statistics counter */ -#define STATS_INC_RX_PACKETS(_pAd, _dev) -#define STATS_INC_TX_PACKETS(_pAd, _dev) - -#define STATS_INC_RX_BYTESS(_pAd, _dev, len) -#define STATS_INC_TX_BYTESS(_pAd, _dev, len) - -#define STATS_INC_RX_ERRORS(_pAd, _dev) -#define STATS_INC_TX_ERRORS(_pAd, _dev) - -#define STATS_INC_RX_DROPPED(_pAd, _dev) -#define STATS_INC_TX_DROPPED(_pAd, _dev) - - #define CB_OFF 10 - -// check DDK NDIS_PACKET data structure and find out only MiniportReservedEx[0..7] can be used by our driver without -// ambiguity. Fields after pPacket->MiniportReservedEx[8] may be used by other wrapper layer thus crashes the driver -// - // User Priority #define RTMP_SET_PACKET_UP(_p, _prio) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio) #define RTMP_GET_PACKET_UP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0]) @@ -782,137 +871,38 @@ void RTMP_GetCurrentSystemTime(LARGE_INT #define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg) #define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12]) -#define RTMP_SET_PACKET_5VT(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg) -#define RTMP_GET_PACKET_5VT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22]) - -#ifdef CONFIG_5VT_ENHANCE -#define BRIDGE_TAG 0x35564252 // depends on 5VT define in br_input.c -#endif - - -#define NDIS_SET_PACKET_STATUS(_p, _status) - - -#define GET_SG_LIST_FROM_PACKET(_p, _sc) \ - rt_get_sg_list_from_packet(_p, _sc) - -#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length) -#define NdisZeroMemory(Destination, Length) memset(Destination, 0, Length) -#define NdisFillMemory(Destination, Length, Fill) memset(Destination, Fill, Length) -#define NdisEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length)) -#define RTMPEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length)) - - -#define RTMP_INC_REF(_A) 0 -#define RTMP_DEC_REF(_A) 0 -#define RTMP_GET_REF(_A) 0 - - - -/* - * ULONG - * RTMP_GetPhysicalAddressLow( - * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress); - */ -#define RTMP_GetPhysicalAddressLow(PhysicalAddress) (PhysicalAddress) - -/* - * ULONG - * RTMP_GetPhysicalAddressHigh( - * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress); - */ -#define RTMP_GetPhysicalAddressHigh(PhysicalAddress) (0) - -/* - * VOID - * RTMP_SetPhysicalAddressLow( - * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress, - * IN ULONG Value); - */ -#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value) \ - PhysicalAddress = Value; - -/* - * VOID - * RTMP_SetPhysicalAddressHigh( - * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress, - * IN ULONG Value); - */ -#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value) - - -//CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx); -#define QUEUE_ENTRY_TO_PACKET(pEntry) \ - (PNDIS_PACKET)(pEntry) - -#define PACKET_TO_QUEUE_ENTRY(pPacket) \ - (PQUEUE_ENTRY)(pPacket) - - -#ifndef CONTAINING_RECORD -#define CONTAINING_RECORD(address, type, field) \ -((type *)((PCHAR)(address) - offsetof(type, field))) -#endif - - -#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status) \ -{ \ - RTMPFreeNdisPacket(_pAd, _pPacket); \ -} - - -#define SWITCH_PhyAB(_pAA, _pBB) \ -{ \ - ULONG AABasePaHigh; \ - ULONG AABasePaLow; \ - ULONG BBBasePaHigh; \ - ULONG BBBasePaLow; \ - BBBasePaHigh = RTMP_GetPhysicalAddressHigh(_pBB); \ - BBBasePaLow = RTMP_GetPhysicalAddressLow(_pBB); \ - AABasePaHigh = RTMP_GetPhysicalAddressHigh(_pAA); \ - AABasePaLow = RTMP_GetPhysicalAddressLow(_pAA); \ - RTMP_SetPhysicalAddressHigh(_pAA, BBBasePaHigh); \ - RTMP_SetPhysicalAddressLow(_pAA, BBBasePaLow); \ - RTMP_SetPhysicalAddressHigh(_pBB, AABasePaHigh); \ - RTMP_SetPhysicalAddressLow(_pBB, AABasePaLow); \ -} -#define NdisWriteErrorLogEntry(_a, _b, _c, _d) -#define NdisMAllocateMapRegisters(_a, _b, _c, _d, _e) NDIS_STATUS_SUCCESS +/* use bit3 of cb[CB_OFF+16] */ +#define RTMP_SET_PACKET_5VT(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg) +#define RTMP_GET_PACKET_5VT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22]) -#define NdisAcquireSpinLock RTMP_SEM_LOCK -#define NdisReleaseSpinLock RTMP_SEM_UNLOCK +/* Max skb->cb = 48B = [CB_OFF+38] */ -static inline void NdisGetSystemUpTime(ULONG *time) -{ - *time = jiffies; -} -//pPacket = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx); -#define QUEUE_ENTRY_TO_PKT(pEntry) \ - ((PNDIS_PACKET) (pEntry)) +/*********************************************************************************** + * Other function prototypes definitions + ***********************************************************************************/ +void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time); int rt28xx_packet_xmit(struct sk_buff *skb); +#ifdef RTMP_MAC_PCI +/* function declarations */ +#define IRQ_HANDLE_TYPE irqreturn_t +IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance); +#endif // RTMP_MAC_PCI // -void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify); - -#ifdef RT2860 -#if !defined(PCI_CAP_ID_EXP) -#define PCI_CAP_ID_EXP 0x10 -#endif +INT rt28xx_sta_ioctl( + IN PNET_DEV net_dev, + IN OUT struct ifreq *rq, + IN INT cmd); -#if !defined(PCI_EXP_LNKCTL) -#define PCI_EXP_LNKCTL 0x10 -#endif +extern int ra_mtd_write(int num, loff_t to, size_t len, const u_char *buf); +extern int ra_mtd_read(int num, loff_t from, size_t len, u_char *buf); -#if !defined(PCI_CLASS_BRIDGE_PCI) -#define PCI_CLASS_BRIDGE_PCI 0x0604 -#endif - -#define PCIBUS_INTEL_VENDOR 0x8086 -#endif +#define GET_PAD_FROM_NET_DEV(_pAd, _net_dev) (_pAd) = (PRTMP_ADAPTER)(_net_dev)->ml_priv; +#endif // __RT_LINUX_H__ // Index: b/drivers/staging/rt2860/rt_main_dev.c =================================================================== --- a/drivers/staging/rt2860/rt_main_dev.c +++ b/drivers/staging/rt2860/rt_main_dev.c @@ -33,20 +33,18 @@ Revision History: Who When What -------- ---------- ---------------------------------------------- - Sample Mar/21/07 Merge RT2870 and RT2860 drivers. */ #include "rt_config.h" -#define FORTY_MHZ_INTOLERANT_INTERVAL (60*1000) // 1 min + /*---------------------------------------------------------------------*/ /* Private Variables Used */ /*---------------------------------------------------------------------*/ -//static RALINK_TIMER_STRUCT PeriodicTimer; -char *mac = ""; // default 00:00:00:00:00:00 -char *hostname = ""; // default CMPC +PSTRING mac = ""; // default 00:00:00:00:00:00 +PSTRING hostname = ""; // default CMPC module_param (mac, charp, 0); MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr"); @@ -54,31 +52,16 @@ MODULE_PARM_DESC (mac, "rt28xx: wireless /*---------------------------------------------------------------------*/ /* Prototypes of Functions Used */ /*---------------------------------------------------------------------*/ -extern BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num); -extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd); -extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd); - -#ifdef RT2860 -extern void init_thread_task(PRTMP_ADAPTER pAd); -#endif // public function prototype -INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p, - IN UINT argc, OUT PRTMP_ADAPTER *ppAd); +int rt28xx_close(IN struct net_device *net_dev); +int rt28xx_open(struct net_device *net_dev); // private function prototype -static int rt28xx_init(IN struct net_device *net_dev); -INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev); - -static void CfgInitHook(PRTMP_ADAPTER pAd); - -extern const struct iw_handler_def rt28xx_iw_handler_def; +static INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev); -// This function will be called when query /proc -struct iw_statistics *rt28xx_get_wireless_stats( - IN struct net_device *net_dev); -struct net_device_stats *RT28xx_get_ether_stats( +static struct net_device_stats *RT28xx_get_ether_stats( IN struct net_device *net_dev); /* @@ -103,7 +86,9 @@ Note: */ int MainVirtualIF_close(IN struct net_device *net_dev) { - RTMP_ADAPTER *pAd = net_dev->ml_priv; + RTMP_ADAPTER *pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, net_dev); // Sanity check for pAd if (pAd == NULL) @@ -112,6 +97,40 @@ int MainVirtualIF_close(IN struct net_de netif_carrier_off(pAd->net_dev); netif_stop_queue(pAd->net_dev); + { + BOOLEAN Cancelled; + + if (INFRA_ON(pAd) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) + { + MLME_DISASSOC_REQ_STRUCT DisReq; + MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); + + if (MsgElem) + { + COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid); + DisReq.Reason = REASON_DEAUTH_STA_LEAVING; + + MsgElem->Machine = ASSOC_STATE_MACHINE; + MsgElem->MsgType = MT2_MLME_DISASSOC_REQ; + MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT); + NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT)); + + // Prevent to connect AP again in STAMlmePeriodicExec + pAd->MlmeAux.AutoReconnectSsidLen= 32; + NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen); + + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC; + MlmeDisassocReqAction(pAd, MsgElem); + kfree(MsgElem); + } + + RTMPusecDelay(1000); + } + + RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled); + RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled); + } VIRTUAL_IF_DOWN(pAd); @@ -142,7 +161,9 @@ Note: */ int MainVirtualIF_open(IN struct net_device *net_dev) { - RTMP_ADAPTER *pAd = net_dev->ml_priv; + RTMP_ADAPTER *pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, net_dev); // Sanity check for pAd if (pAd == NULL) @@ -184,83 +205,46 @@ Note: int rt28xx_close(IN PNET_DEV dev) { struct net_device * net_dev = (struct net_device *)dev; - RTMP_ADAPTER *pAd = net_dev->ml_priv; - BOOLEAN Cancelled = FALSE; + RTMP_ADAPTER *pAd = NULL; + BOOLEAN Cancelled; UINT32 i = 0; -#ifdef RT2870 - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup); + + GET_PAD_FROM_NET_DEV(pAd, net_dev); + +#ifdef RTMP_MAC_USB + DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup); DECLARE_WAITQUEUE(wait, current); //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); -#endif // RT2870 // - +#endif // RTMP_MAC_USB // DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n")); + Cancelled = FALSE; // Sanity check for pAd if (pAd == NULL) return 0; // close ok { +#ifdef RTMP_PCI_SUPPORT + RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE); +#endif // RTMP_PCI_SUPPORT // + // If dirver doesn't wake up firmware here, // NICLoadFirmware will hang forever when interface is up again. -#ifdef RT2860 - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) || - RTMP_SET_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) || - RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) -#endif -#ifdef RT2870 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) -#endif { -#ifdef RT2860 - AsicForceWakeup(pAd, RTMP_HALT); -#endif -#ifdef RT2870 AsicForceWakeup(pAd, TRUE); -#endif } - if (INFRA_ON(pAd) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) - { - MLME_DISASSOC_REQ_STRUCT DisReq; - MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); - - COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid); - DisReq.Reason = REASON_DEAUTH_STA_LEAVING; - - MsgElem->Machine = ASSOC_STATE_MACHINE; - MsgElem->MsgType = MT2_MLME_DISASSOC_REQ; - MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT); - NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT)); - - // Prevent to connect AP again in STAMlmePeriodicExec - pAd->MlmeAux.AutoReconnectSsidLen= 32; - NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen); - - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC; - MlmeDisassocReqAction(pAd, MsgElem); - kfree(MsgElem); - - RTMPusecDelay(1000); - } - -#ifdef RT2870 +#ifdef RTMP_MAC_USB RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); -#endif // RT2870 // - -#ifdef CCX_SUPPORT - RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &Cancelled); -#endif - - RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled); - RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled); +#endif // RTMP_MAC_USB // MlmeRadioOff(pAd); -#ifdef RT2860 +#ifdef RTMP_MAC_PCI pAd->bPCIclkOff = FALSE; -#endif +#endif // RTMP_MAC_PCI // } RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); @@ -269,12 +253,12 @@ int rt28xx_close(IN PNET_DEV dev) { while (pAd->DeQueueRunning[i] == TRUE) { - printk("Waiting for TxQueue[%d] done..........\n", i); + DBGPRINT(RT_DEBUG_TRACE, ("Waiting for TxQueue[%d] done..........\n", i)); RTMPusecDelay(1000); } } -#ifdef RT2870 +#ifdef RTMP_MAC_USB // ensure there are no more active urbs. add_wait_queue (&unlink_wakeup, &wait); pAd->wait = &unlink_wakeup; @@ -299,290 +283,89 @@ int rt28xx_close(IN PNET_DEV dev) } pAd->wait = NULL; remove_wait_queue (&unlink_wakeup, &wait); -#endif // RT2870 // - -#ifdef RT2870 - // We need clear timerQ related structure before exits of the timer thread. - RT2870_TimerQ_Exit(pAd); - // Close kernel threads or tasklets - RT28xxThreadTerminate(pAd); -#endif // RT2870 // +#endif // RTMP_MAC_USB // // Stop Mlme state machine MlmeHalt(pAd); - // Close kernel threads or tasklets - kill_thread_task(pAd); + // Close net tasklets + RtmpNetTaskExit(pAd); - MacTableReset(pAd); - - MeasureReqTabExit(pAd); - TpcReqTabExit(pAd); - -#ifdef RT2860 - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { - NICDisableInterrupt(pAd); + MacTableReset(pAd); } - // Disable Rx, register value supposed will remain after reset - NICIssueReset(pAd); - // Free IRQ - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) - { - // Deregister interrupt function - RT28XX_IRQ_RELEASE(net_dev) - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); - } -#endif - - // Free Ring or USB buffers - RTMPFreeTxRxRingMemory(pAd); - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - - // Free BA reorder resource - ba_reordering_resource_release(pAd); - - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP); - - return 0; // close ok -} /* End of rt28xx_close */ - -static int rt28xx_init(IN struct net_device *net_dev) -{ -#ifdef RT2860 - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)net_dev->ml_priv; -#endif -#ifdef RT2870 - PRTMP_ADAPTER pAd = net_dev->ml_priv; -#endif - UINT index; - UCHAR TmpPhy; - NDIS_STATUS Status; - UINT32 MacCsr0 = 0; - - // Allocate BA Reordering memory - ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM); - - // Make sure MAC gets ready. - index = 0; - do - { - RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); - pAd->MACVersion = MacCsr0; - - if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF)) - break; - - RTMPusecDelay(10); - } while (index++ < 100); + MeasureReqTabExit(pAd); + TpcReqTabExit(pAd); - DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion)); -/*Iverson patch PCIE L1 issue */ - // Disable DMA - RT28XXDMADisable(pAd); + // Close kernel threads + RtmpMgmtTaskExit(pAd); - // Load 8051 firmware - Status = NICLoadFirmware(pAd); - if (Status != NDIS_STATUS_SUCCESS) +#ifdef RTMP_MAC_PCI { - DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status)); - goto err1; - } + BOOLEAN brc; + // ULONG Value; - NICLoadRateSwitchingParams(pAd); - - // Disable interrupts here which is as soon as possible - // This statement should never be true. We might consider to remove it later -#ifdef RT2860 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { - NICDisableInterrupt(pAd); - } -#endif - - Status = RTMPAllocTxRxRingMemory(pAd); - if (Status != NDIS_STATUS_SUCCESS) - { - DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status)); - goto err1; + RTMP_ASIC_INTERRUPT_DISABLE(pAd); } - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); - - // initialize MLME - // - - Status = MlmeInit(pAd); - if (Status != NDIS_STATUS_SUCCESS) - { - DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status)); - goto err2; - } - - // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default - // - UserCfgInit(pAd); - -#ifdef RT2870 - // We need init timerQ related structure before create the timer thread. - RT2870_TimerQ_Init(pAd); -#endif // RT2870 // + // Receive packets to clear DMA index after disable interrupt. + //RTMPHandleRxDoneInterrupt(pAd); + // put to radio off to save power when driver unload. After radiooff, can't write /read register. So need to finish all + // register access before Radio off. - RT28XX_TASK_THREAD_INIT(pAd, Status); - if (Status != NDIS_STATUS_SUCCESS) - goto err1; - CfgInitHook(pAd); - - NdisAllocateSpinLock(&pAd->MacTabLock); - - MeasureReqTabInit(pAd); - TpcReqTabInit(pAd); - - // - // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset - // - Status = NICInitializeAdapter(pAd, TRUE); - if (Status != NDIS_STATUS_SUCCESS) + brc=RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0); + if (brc==FALSE) { - DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status)); - if (Status != NDIS_STATUS_SUCCESS) - goto err3; + DBGPRINT(RT_DEBUG_ERROR,("%s call RT28xxPciAsicRadioOff fail !!\n", __func__)); } - - // Read parameters from Config File - Status = RTMPReadParametersHook(pAd); - - printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode); - if (Status != NDIS_STATUS_SUCCESS) - { - DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status)); - goto err4; } -#ifdef RT2870 - pAd->CommonCfg.bMultipleIRP = FALSE; - - if (pAd->CommonCfg.bMultipleIRP) - pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE; - else - pAd->CommonCfg.NumOfBulkInIRP = 1; -#endif // RT2870 // - - //Init Ba Capability parameters. - pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; - pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; - pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; - pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; - // UPdata to HT IE - pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; - pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; - pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; - - printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode); - - // We should read EEPROM for all cases. rt2860b - NICReadEEPROMParameters(pAd, mac); - - printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode); - - NICInitAsicFromEEPROM(pAd); //rt2860b - - // Set PHY to appropriate mode - TmpPhy = pAd->CommonCfg.PhyMode; - pAd->CommonCfg.PhyMode = 0xff; - RTMPSetPhyMode(pAd, TmpPhy); - SetCommonHT(pAd); - - // No valid channels. - if (pAd->ChannelListNum == 0) +/* + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) { - printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n"); - goto err4; + RTMP_ASIC_INTERRUPT_DISABLE(pAd); } - printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0], - pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2], - pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]); - -#ifdef RT2870 - //Init RT30xx RFRegisters after read RFIC type from EEPROM - NICInitRT30xxRFRegisters(pAd); -#endif // RT2870 // - - - // - // Initialize RF register to default value - // - AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); - AsicLockChannel(pAd, pAd->CommonCfg.Channel); - -#ifndef RT2870 - // 8051 firmware require the signal during booting time. - AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00); -#endif + // Disable Rx, register value supposed will remain after reset + NICIssueReset(pAd); +*/ +#endif // RTMP_MAC_PCI // - if (pAd && (Status != NDIS_STATUS_SUCCESS)) - { - // - // Undo everything if it failed - // + // Free IRQ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { +#ifdef RTMP_MAC_PCI + // Deregister interrupt function + RtmpOSIRQRelease(net_dev); +#endif // RTMP_MAC_PCI // RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); } - } - else if (pAd) - { - // Microsoft HCT require driver send a disconnect event after driver initialization. - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE); - - DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n")); + // Free Ring or USB buffers + RTMPFreeTxRxRingMemory(pAd); -#ifdef RT2870 - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS); - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); - - // - // Support multiple BulkIn IRP, - // the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1. - // - for(index=0; indexCommonCfg.NumOfBulkInIRP; index++) - { - RTUSBBulkReceive(pAd); - DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" )); - } -#endif // RT2870 // - }// end of else + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + // Free BA reorder resource + ba_reordering_resource_release(pAd); - DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status)); - return TRUE; + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP); +/*+++Modify by woody to solve the bulk fail+++*/ + { + } -err4: -err3: - MlmeHalt(pAd); -err2: - RTMPFreeTxRxRingMemory(pAd); -err1: - os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool - RT28XX_IRQ_RELEASE(net_dev); - - // shall not set ml_priv to NULL here because the ml_priv didn't been free yet. - //net_dev->ml_priv = 0; - - printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME); - return FALSE; -} /* End of rt28xx_init */ + DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n")); + return 0; // close ok +} /* End of rt28xx_close */ /* @@ -603,10 +386,11 @@ Note: int rt28xx_open(IN PNET_DEV dev) { struct net_device * net_dev = (struct net_device *)dev; - PRTMP_ADAPTER pAd = net_dev->ml_priv; + PRTMP_ADAPTER pAd = NULL; int retval = 0; - POS_COOKIE pObj; + //POS_COOKIE pObj; + GET_PAD_FROM_NET_DEV(pAd, net_dev); // Sanity check for pAd if (pAd == NULL) @@ -616,37 +400,32 @@ int rt28xx_open(IN PNET_DEV dev) return -1; } - // Init - pObj = (POS_COOKIE)pAd->OS_Cookie; +#ifdef RTMP_PCI_SUPPORT + RTMPInitPCIeLinkCtrlValue(pAd); +#endif // RTMP_PCI_SUPPORT // + - // reset Adapter flags - RTMP_CLEAR_FLAGS(pAd); + if (net_dev->priv_flags == INT_MAIN) + { + if (pAd->OpMode == OPMODE_STA) + net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def; + } // Request interrupt service routine for PCI device // register the interrupt routine with the os - RT28XX_IRQ_REQUEST(net_dev); + RtmpOSIRQRequest(net_dev); - // Init BssTab & ChannelInfo tabbles for auto channel select. - + // Init IRQ parameters stored in pAd + RTMP_IRQ_INIT(pAd); // Chip & other init - if (rt28xx_init(net_dev) == FALSE) + if (rt28xx_init(pAd, mac, hostname) == FALSE) goto err; - NdisZeroMemory(pAd->StaCfg.dev_name, 16); - NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name)); - - // Set up the Mac address - NdisMoveMemory(net_dev->dev_addr, (void *) pAd->CurrentAddress, 6); - - // Init IRQ parameters - RT28XX_IRQ_INIT(pAd); - - // Various AP function init // Enable Interrupt - RT28XX_IRQ_ENABLE(pAd); + RTMP_IRQ_ENABLE(pAd); // Now Enable RxTx RTMPEnableRxTx(pAd); @@ -658,12 +437,26 @@ int rt28xx_open(IN PNET_DEV dev) printk("0x1300 = %08x\n", reg); } -#ifdef RT2860 - RTMPInitPCIeLinkCtrlValue(pAd); -#endif + { +// u32 reg; +// UINT8 byte; +// u16 tmp; + +// RTMP_IO_READ32(pAd, XIFS_TIME_CFG, ®); + +// tmp = 0x0805; +// reg = (reg & 0xffff0000) | tmp; +// RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); + + } + + return (retval); err: +//+++Add by shiang, move from rt28xx_init() to here. + RtmpOSIRQRelease(net_dev); +//---Add by shiang, move from rt28xx_init() to here. return (-1); } /* End of rt28xx_open */ @@ -678,155 +471,33 @@ static const struct net_device_ops rt286 .ndo_start_xmit = rt28xx_send_packets, }; -/* Must not be called for mdev and apdev */ -static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) +PNET_DEV RtmpPhyNetDevInit( + IN RTMP_ADAPTER *pAd, + IN RTMP_OS_NETDEV_OP_HOOK *pNetDevHook) { - NDIS_STATUS Status; - INT i=0; - CHAR slot_name[IFNAMSIZ]; - struct net_device *device; - - if (pAd->OpMode == OPMODE_STA) - { - dev->wireless_handlers = &rt28xx_iw_handler_def; - } - - dev->priv_flags = INT_MAIN; - dev->netdev_ops = &rt2860_netdev_ops; - // find available device name - for (i = 0; i < 8; i++) - { - sprintf(slot_name, "wlan%d", i); - - device = dev_get_by_name(dev_net(dev), slot_name); - if (device != NULL) - dev_put(device); - - if (device == NULL) - break; - } - - if(i == 8) - { - DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n")); - Status = NDIS_STATUS_FAILURE; - } - else - { - sprintf(dev->name, "wlan%d", i); - Status = NDIS_STATUS_SUCCESS; - } - - return Status; - -} - -/* -======================================================================== -Routine Description: - Probe RT28XX chipset. - -Arguments: - _dev_p Point to the PCI or USB device - _dev_id_p Point to the PCI or USB device ID - -Return Value: - 0 Probe OK - -ENODEV Probe Fail - -Note: -======================================================================== -*/ -INT __devinit rt28xx_probe( - IN void *_dev_p, - IN void *_dev_id_p, - IN UINT argc, - OUT PRTMP_ADAPTER *ppAd) -{ - struct net_device *net_dev; - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) NULL; - INT status; - PVOID handle; -#ifdef RT2860 - struct pci_dev *dev_p = (struct pci_dev *)_dev_p; -#endif -#ifdef RT2870 - struct usb_interface *intf = (struct usb_interface *)_dev_p; - struct usb_device *dev_p = interface_to_usbdev(intf); - - dev_p = usb_get_dev(dev_p); -#endif // RT2870 // - - DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION)); + struct net_device *net_dev = NULL; +// NDIS_STATUS Status; - net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER)); + net_dev = RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(PRTMP_ADAPTER), INF_MAIN_DEV_NAME); if (net_dev == NULL) { - printk("alloc_netdev failed\n"); - - goto err_out; + printk("RtmpPhyNetDevInit(): creation failed for main physical net device!\n"); + return NULL; } - netif_stop_queue(net_dev); - -/* for supporting Network Manager */ -/* Set the sysfs physical device reference for the network logical device - * if set prior to registration will cause a symlink during initialization. - */ - SET_NETDEV_DEV(net_dev, &(dev_p->dev)); - - // Allocate RTMP_ADAPTER miniport adapter structure - handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL); - if (handle == NULL) - goto err_out_free_netdev;; - RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p); - - status = RTMPAllocAdapterBlock(handle, &pAd); - if (status != NDIS_STATUS_SUCCESS) - goto err_out_free_netdev; + NdisZeroMemory((unsigned char *)pNetDevHook, sizeof(RTMP_OS_NETDEV_OP_HOOK)); + pNetDevHook->netdev_ops = &rt2860_netdev_ops; + pNetDevHook->priv_flags = INT_MAIN; + pNetDevHook->needProtcted = FALSE; net_dev->ml_priv = (PVOID)pAd; - pAd->net_dev = net_dev; // must be before RT28XXNetDevInit() - - RT28XXNetDevInit(_dev_p, net_dev, pAd); - - pAd->StaCfg.OriDevType = net_dev->type; + pAd->net_dev = net_dev; - // Post config - if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE) - goto err_out_unmap; - - pAd->OpMode = OPMODE_STA; - - // sample move - if (rt_ieee80211_if_setup(net_dev, pAd) != NDIS_STATUS_SUCCESS) - goto err_out_unmap; - - // Register this device - status = register_netdev(net_dev); - if (status) - goto err_out_unmap; - - // Set driver data - RT28XX_DRVDATA_SET(_dev_p); - - *ppAd = pAd; - return 0; // probe ok - - - /* --------------------------- ERROR HANDLE --------------------------- */ -err_out_unmap: - RTMPFreeAdapter(pAd); - RT28XX_UNMAP(); - -err_out_free_netdev: - free_netdev(net_dev); + netif_stop_queue(net_dev); -err_out: - RT28XX_PUT_DEVICE(dev_p); + return net_dev; - return -ENODEV; /* probe fail */ -} /* End of rt28xx_probe */ +} /* @@ -849,10 +520,14 @@ Note: int rt28xx_packet_xmit(struct sk_buff *skb) { struct net_device *net_dev = skb->dev; - PRTMP_ADAPTER pAd = net_dev->ml_priv; + PRTMP_ADAPTER pAd = NULL; int status = NETDEV_TX_OK; PNDIS_PACKET pPacket = (PNDIS_PACKET) skb; + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + /* RT2870STA does this in RTMPSendPackets() */ + { // Drop send request since we are in monitor mode if (MONITOR_ON(pAd)) @@ -871,14 +546,21 @@ int rt28xx_packet_xmit(struct sk_buff *s goto done; } + + RTMP_SET_PACKET_5VT(pPacket, 0); +// MiniportMMRequest(pAd, pkt->data, pkt->len); #ifdef CONFIG_5VT_ENHANCE if (*(int*)(skb->cb) == BRIDGE_TAG) { RTMP_SET_PACKET_5VT(pPacket, 1); } #endif + { + STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1); + } + status = NETDEV_TX_OK; done: @@ -903,11 +585,14 @@ Return Value: Note: ======================================================================== */ -INT rt28xx_send_packets( +static int rt28xx_send_packets( IN struct sk_buff *skb_p, IN struct net_device *net_dev) { - RTMP_ADAPTER *pAd = net_dev->ml_priv; + RTMP_ADAPTER *pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, net_dev); + if (!(net_dev->flags & IFF_UP)) { RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE); @@ -918,36 +603,35 @@ INT rt28xx_send_packets( RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID); return rt28xx_packet_xmit(skb_p); - -} /* End of MBSS_VirtualIF_PacketSend */ - - - - -void CfgInitHook(PRTMP_ADAPTER pAd) -{ - pAd->bBroadComHT = TRUE; -} /* End of CfgInitHook */ +} // This function will be called when query /proc struct iw_statistics *rt28xx_get_wireless_stats( IN struct net_device *net_dev) { - PRTMP_ADAPTER pAd = net_dev->ml_priv; + PRTMP_ADAPTER pAd = NULL; + GET_PAD_FROM_NET_DEV(pAd, net_dev); DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n")); pAd->iw_stats.status = 0; // Status - device dependent for now // link quality + if (pAd->OpMode == OPMODE_STA) pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10); + if(pAd->iw_stats.qual.qual > 100) pAd->iw_stats.qual.qual = 100; if (pAd->OpMode == OPMODE_STA) - pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2); + { + pAd->iw_stats.qual.level = + RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, + pAd->StaCfg.RssiSample.LastRssi1, + pAd->StaCfg.RssiSample.LastRssi2); + } pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm) @@ -962,13 +646,12 @@ struct iw_statistics *rt28xx_get_wireles DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n")); return &pAd->iw_stats; -} /* End of rt28xx_get_wireless_stats */ - +} void tbtt_tasklet(unsigned long data) { -#define MAX_TX_IN_TBTT (16) +//#define MAX_TX_IN_TBTT (16) } @@ -988,13 +671,13 @@ void tbtt_tasklet(unsigned long data) ======================================================================== */ -struct net_device_stats *RT28xx_get_ether_stats( +static struct net_device_stats *RT28xx_get_ether_stats( IN struct net_device *net_dev) { RTMP_ADAPTER *pAd = NULL; if (net_dev) - pAd = net_dev->ml_priv; + GET_PAD_FROM_NET_DEV(pAd, net_dev); if (pAd) { @@ -1038,3 +721,55 @@ struct net_device_stats *RT28xx_get_ethe return NULL; } + +BOOLEAN RtmpPhyNetDevExit( + IN RTMP_ADAPTER *pAd, + IN PNET_DEV net_dev) +{ + + + + // Unregister network device + if (net_dev != NULL) + { + printk("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n", net_dev->name); + RtmpOSNetDevDetach(net_dev); + } + + return TRUE; + +} + + +/* +======================================================================== +Routine Description: + Allocate memory for adapter control block. + +Arguments: + pAd Pointer to our adapter + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + NDIS_STATUS_RESOURCES + +Note: +======================================================================== +*/ +NDIS_STATUS AdapterBlockAllocateMemory( + IN PVOID handle, + OUT PVOID *ppAd) +{ + + *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); //pci_alloc_consistent(pci_dev, sizeof(RTMP_ADAPTER), phy_addr); + + if (*ppAd) + { + NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER)); + ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle; + return (NDIS_STATUS_SUCCESS); + } else { + return (NDIS_STATUS_FAILURE); + } +} Index: b/drivers/staging/rt2860/rt_pci_rbus.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/rt_pci_rbus.c @@ -0,0 +1,889 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rt_pci_rbus.c + + Abstract: + Create and register network interface. + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#include "rt_config.h" +#include + +IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance); + +static void rx_done_tasklet(unsigned long data); +static void mgmt_dma_done_tasklet(unsigned long data); +static void ac0_dma_done_tasklet(unsigned long data); +static void ac1_dma_done_tasklet(unsigned long data); +static void ac2_dma_done_tasklet(unsigned long data); +static void ac3_dma_done_tasklet(unsigned long data); +static void fifo_statistic_full_tasklet(unsigned long data); + + + +/*---------------------------------------------------------------------*/ +/* Symbol & Macro Definitions */ +/*---------------------------------------------------------------------*/ +#define RT2860_INT_RX_DLY (1<<0) // bit 0 +#define RT2860_INT_TX_DLY (1<<1) // bit 1 +#define RT2860_INT_RX_DONE (1<<2) // bit 2 +#define RT2860_INT_AC0_DMA_DONE (1<<3) // bit 3 +#define RT2860_INT_AC1_DMA_DONE (1<<4) // bit 4 +#define RT2860_INT_AC2_DMA_DONE (1<<5) // bit 5 +#define RT2860_INT_AC3_DMA_DONE (1<<6) // bit 6 +#define RT2860_INT_HCCA_DMA_DONE (1<<7) // bit 7 +#define RT2860_INT_MGMT_DONE (1<<8) // bit 8 + +#define INT_RX RT2860_INT_RX_DONE + +#define INT_AC0_DLY (RT2860_INT_AC0_DMA_DONE) //| RT2860_INT_TX_DLY) +#define INT_AC1_DLY (RT2860_INT_AC1_DMA_DONE) //| RT2860_INT_TX_DLY) +#define INT_AC2_DLY (RT2860_INT_AC2_DMA_DONE) //| RT2860_INT_TX_DLY) +#define INT_AC3_DLY (RT2860_INT_AC3_DMA_DONE) //| RT2860_INT_TX_DLY) +#define INT_HCCA_DLY (RT2860_INT_HCCA_DMA_DONE) //| RT2860_INT_TX_DLY) +#define INT_MGMT_DLY RT2860_INT_MGMT_DONE + + +/*************************************************************************** + * + * Interface-depended memory allocation/Free related procedures. + * Mainly for Hardware TxDesc/RxDesc/MgmtDesc, DMA Memory for TxData/RxData, etc., + * + **************************************************************************/ +// Function for TxDesc Memory allocation. +void RTMP_AllocateTxDescMemory( + IN PRTMP_ADAPTER pAd, + IN UINT Index, + IN ULONG Length, + IN BOOLEAN Cached, + OUT PVOID *VirtualAddress, + OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) +{ + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + + *VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress); + +} + + +// Function for MgmtDesc Memory allocation. +void RTMP_AllocateMgmtDescMemory( + IN PRTMP_ADAPTER pAd, + IN ULONG Length, + IN BOOLEAN Cached, + OUT PVOID *VirtualAddress, + OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) +{ + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + + *VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress); + +} + + +// Function for RxDesc Memory allocation. +void RTMP_AllocateRxDescMemory( + IN PRTMP_ADAPTER pAd, + IN ULONG Length, + IN BOOLEAN Cached, + OUT PVOID *VirtualAddress, + OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) +{ + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + + *VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress); + +} + + +// Function for free allocated Desc Memory. +void RTMP_FreeDescMemory( + IN PRTMP_ADAPTER pAd, + IN ULONG Length, + IN PVOID VirtualAddress, + IN NDIS_PHYSICAL_ADDRESS PhysicalAddress) +{ + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + + pci_free_consistent(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress); +} + + +// Function for TxData DMA Memory allocation. +void RTMP_AllocateFirstTxBuffer( + IN PRTMP_ADAPTER pAd, + IN UINT Index, + IN ULONG Length, + IN BOOLEAN Cached, + OUT PVOID *VirtualAddress, + OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) +{ + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + + *VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress); +} + + +void RTMP_FreeFirstTxBuffer( + IN PRTMP_ADAPTER pAd, + IN ULONG Length, + IN BOOLEAN Cached, + IN PVOID VirtualAddress, + IN NDIS_PHYSICAL_ADDRESS PhysicalAddress) +{ + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + + pci_free_consistent(pObj->pci_dev, Length, VirtualAddress, PhysicalAddress); +} + + +/* + * FUNCTION: Allocate a common buffer for DMA + * ARGUMENTS: + * AdapterHandle: AdapterHandle + * Length: Number of bytes to allocate + * Cached: Whether or not the memory can be cached + * VirtualAddress: Pointer to memory is returned here + * PhysicalAddress: Physical address corresponding to virtual address + */ +void RTMP_AllocateSharedMemory( + IN PRTMP_ADAPTER pAd, + IN ULONG Length, + IN BOOLEAN Cached, + OUT PVOID *VirtualAddress, + OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) +{ + POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + + *VirtualAddress = (PVOID)pci_alloc_consistent(pObj->pci_dev,sizeof(char)*Length, PhysicalAddress); +} + + +/* + * FUNCTION: Allocate a packet buffer for DMA + * ARGUMENTS: + * AdapterHandle: AdapterHandle + * Length: Number of bytes to allocate + * Cached: Whether or not the memory can be cached + * VirtualAddress: Pointer to memory is returned here + * PhysicalAddress: Physical address corresponding to virtual address + * Notes: + * Cached is ignored: always cached memory + */ +PNDIS_PACKET RTMP_AllocateRxPacketBuffer( + IN PRTMP_ADAPTER pAd, + IN ULONG Length, + IN BOOLEAN Cached, + OUT PVOID *VirtualAddress, + OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) +{ + struct sk_buff *pkt; + + pkt = dev_alloc_skb(Length); + + if (pkt == NULL) { + DBGPRINT(RT_DEBUG_ERROR, ("can't allocate rx %ld size packet\n",Length)); + } + + if (pkt) { + RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS); + *VirtualAddress = (PVOID) pkt->data; +//#ifdef CONFIG_5VT_ENHANCE +// *PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, 1600, PCI_DMA_FROMDEVICE); +//#else + *PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1, PCI_DMA_FROMDEVICE); +//#endif + } else { + *VirtualAddress = (PVOID) NULL; + *PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) NULL; + } + + return (PNDIS_PACKET) pkt; +} + + +VOID Invalid_Remaining_Packet( + IN PRTMP_ADAPTER pAd, + IN ULONG VirtualAddress) +{ + NDIS_PHYSICAL_ADDRESS PhysicalAddress; + + PhysicalAddress = PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress+1600), RX_BUFFER_NORMSIZE-1600, -1, PCI_DMA_FROMDEVICE); +} + + +NDIS_STATUS RtmpNetTaskInit(IN RTMP_ADAPTER *pAd) +{ + POS_COOKIE pObj; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->fifo_statistic_full_task, fifo_statistic_full_tasklet, (unsigned long)pAd); + + return NDIS_STATUS_SUCCESS; +} + + +void RtmpNetTaskExit(IN RTMP_ADAPTER *pAd) +{ + POS_COOKIE pObj; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + tasklet_kill(&pObj->rx_done_task); + tasklet_kill(&pObj->mgmt_dma_done_task); + tasklet_kill(&pObj->ac0_dma_done_task); + tasklet_kill(&pObj->ac1_dma_done_task); + tasklet_kill(&pObj->ac2_dma_done_task); + tasklet_kill(&pObj->ac3_dma_done_task); + tasklet_kill(&pObj->tbtt_task); + tasklet_kill(&pObj->fifo_statistic_full_task); +} + + +NDIS_STATUS RtmpMgmtTaskInit(IN RTMP_ADAPTER *pAd) +{ + + + return NDIS_STATUS_SUCCESS; +} + + +/* +======================================================================== +Routine Description: + Close kernel threads. + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + NONE + +Note: +======================================================================== +*/ +VOID RtmpMgmtTaskExit( + IN RTMP_ADAPTER *pAd) +{ + + + return; +} + + +static inline void rt2860_int_enable(PRTMP_ADAPTER pAd, unsigned int mode) +{ + u32 regValue; + + pAd->int_disable_mask &= ~(mode); + regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask); + //if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + { + RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); // 1:enable + } + //else + // DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n")); + + if (regValue != 0) + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE); +} + + +static inline void rt2860_int_disable(PRTMP_ADAPTER pAd, unsigned int mode) +{ + u32 regValue; + + pAd->int_disable_mask |= mode; + regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask); + RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue); // 0: disable + + if (regValue == 0) + { + RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE); + } +} + + +/*************************************************************************** + * + * tasklet related procedures. + * + **************************************************************************/ +static void mgmt_dma_done_tasklet(unsigned long data) +{ + unsigned long flags; + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; + INT_SOURCE_CSR_STRUC IntSource; + POS_COOKIE pObj; + + // Do nothing if the driver is starting halt state. + // This might happen when timer already been fired before cancel timer with mlmehalt + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + +// printk("mgmt_dma_done_process\n"); + IntSource.word = 0; + IntSource.field.MgmtDmaDone = 1; + pAd->int_pending &= ~INT_MGMT_DLY; + + RTMPHandleMgmtRingDmaDoneInterrupt(pAd); + + // if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any + // bug report output + RTMP_INT_LOCK(&pAd->irq_lock, flags); + /* + * double check to avoid lose of interrupts + */ + if (pAd->int_pending & INT_MGMT_DLY) + { + tasklet_hi_schedule(&pObj->mgmt_dma_done_task); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); + return; + } + + /* enable TxDataInt again */ + rt2860_int_enable(pAd, INT_MGMT_DLY); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); +} + + +static void rx_done_tasklet(unsigned long data) +{ + unsigned long flags; + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; + BOOLEAN bReschedule = 0; + POS_COOKIE pObj; + + // Do nothing if the driver is starting halt state. + // This might happen when timer already been fired before cancel timer with mlmehalt + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + +#ifdef UAPSD_AP_SUPPORT + UAPSD_TIMING_RECORD(pAd, UAPSD_TIMING_RECORD_TASKLET); +#endif // UAPSD_AP_SUPPORT // + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + pAd->int_pending &= ~(INT_RX); + bReschedule = STARxDoneInterruptHandle(pAd, 0); + +#ifdef UAPSD_AP_SUPPORT + UAPSD_TIMING_RECORD_STOP(); +#endif // UAPSD_AP_SUPPORT // + + RTMP_INT_LOCK(&pAd->irq_lock, flags); + /* + * double check to avoid rotting packet + */ + if (pAd->int_pending & INT_RX || bReschedule) + { + tasklet_hi_schedule(&pObj->rx_done_task); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); + return; + } + + /* enable RxINT again */ + rt2860_int_enable(pAd, INT_RX); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); + +} + + +void fifo_statistic_full_tasklet(unsigned long data) +{ + unsigned long flags; + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; + POS_COOKIE pObj; + + // Do nothing if the driver is starting halt state. + // This might happen when timer already been fired before cancel timer with mlmehalt + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + pAd->int_pending &= ~(FifoStaFullInt); + NICUpdateFifoStaCounters(pAd); + + RTMP_INT_LOCK(&pAd->irq_lock, flags); + /* + * double check to avoid rotting packet + */ + if (pAd->int_pending & FifoStaFullInt) + { + tasklet_hi_schedule(&pObj->fifo_statistic_full_task); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); + return; + } + + /* enable RxINT again */ + + rt2860_int_enable(pAd, FifoStaFullInt); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); + +} + +static void ac3_dma_done_tasklet(unsigned long data) +{ + unsigned long flags; + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; + INT_SOURCE_CSR_STRUC IntSource; + POS_COOKIE pObj; + BOOLEAN bReschedule = 0; + + // Do nothing if the driver is starting halt state. + // This might happen when timer already been fired before cancel timer with mlmehalt + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + +// printk("ac0_dma_done_process\n"); + IntSource.word = 0; + IntSource.field.Ac3DmaDone = 1; + pAd->int_pending &= ~INT_AC3_DLY; + + bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); + + RTMP_INT_LOCK(&pAd->irq_lock, flags); + /* + * double check to avoid lose of interrupts + */ + if ((pAd->int_pending & INT_AC3_DLY) || bReschedule) + { + tasklet_hi_schedule(&pObj->ac3_dma_done_task); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); + return; + } + + /* enable TxDataInt again */ + rt2860_int_enable(pAd, INT_AC3_DLY); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); +} + + +static void ac2_dma_done_tasklet(unsigned long data) +{ + unsigned long flags; + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; + INT_SOURCE_CSR_STRUC IntSource; + POS_COOKIE pObj; + BOOLEAN bReschedule = 0; + + // Do nothing if the driver is starting halt state. + // This might happen when timer already been fired before cancel timer with mlmehalt + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + IntSource.word = 0; + IntSource.field.Ac2DmaDone = 1; + pAd->int_pending &= ~INT_AC2_DLY; + + bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); + + RTMP_INT_LOCK(&pAd->irq_lock, flags); + + /* + * double check to avoid lose of interrupts + */ + if ((pAd->int_pending & INT_AC2_DLY) || bReschedule) + { + tasklet_hi_schedule(&pObj->ac2_dma_done_task); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); + return; + } + + /* enable TxDataInt again */ + rt2860_int_enable(pAd, INT_AC2_DLY); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); +} + + +static void ac1_dma_done_tasklet(unsigned long data) +{ + unsigned long flags; + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; + INT_SOURCE_CSR_STRUC IntSource; + POS_COOKIE pObj; + BOOLEAN bReschedule = 0; + + // Do nothing if the driver is starting halt state. + // This might happen when timer already been fired before cancel timer with mlmehalt + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + +// printk("ac0_dma_done_process\n"); + IntSource.word = 0; + IntSource.field.Ac1DmaDone = 1; + pAd->int_pending &= ~INT_AC1_DLY; + + bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); + + RTMP_INT_LOCK(&pAd->irq_lock, flags); + /* + * double check to avoid lose of interrupts + */ + if ((pAd->int_pending & INT_AC1_DLY) || bReschedule) + { + tasklet_hi_schedule(&pObj->ac1_dma_done_task); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); + return; + } + + /* enable TxDataInt again */ + rt2860_int_enable(pAd, INT_AC1_DLY); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); +} + + +static void ac0_dma_done_tasklet(unsigned long data) +{ + unsigned long flags; + PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) data; + INT_SOURCE_CSR_STRUC IntSource; + POS_COOKIE pObj; + BOOLEAN bReschedule = 0; + + // Do nothing if the driver is starting halt state. + // This might happen when timer already been fired before cancel timer with mlmehalt + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) + return; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + +// printk("ac0_dma_done_process\n"); + IntSource.word = 0; + IntSource.field.Ac0DmaDone = 1; + pAd->int_pending &= ~INT_AC0_DLY; + +// RTMPHandleMgmtRingDmaDoneInterrupt(pAd); + bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource); + + RTMP_INT_LOCK(&pAd->irq_lock, flags); + /* + * double check to avoid lose of interrupts + */ + if ((pAd->int_pending & INT_AC0_DLY) || bReschedule) + { + tasklet_hi_schedule(&pObj->ac0_dma_done_task); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); + return; + } + + /* enable TxDataInt again */ + rt2860_int_enable(pAd, INT_AC0_DLY); + RTMP_INT_UNLOCK(&pAd->irq_lock, flags); +} + + + + +/*************************************************************************** + * + * interrupt handler related procedures. + * + **************************************************************************/ +int print_int_count; + +IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance) +{ + struct net_device *net_dev = (struct net_device *) dev_instance; + PRTMP_ADAPTER pAd = NULL; + INT_SOURCE_CSR_STRUC IntSource; + POS_COOKIE pObj; + + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + + /* Note 03312008: we can not return here before + RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word); + RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); + Or kernel will panic after ifconfig ra0 down sometimes */ + + + // + // Inital the Interrupt source. + // + IntSource.word = 0x00000000L; +// McuIntSource.word = 0x00000000L; + + // + // Get the interrupt sources & saved to local variable + // + //RTMP_IO_READ32(pAd, where, &McuIntSource.word); + //RTMP_IO_WRITE32(pAd, , McuIntSource.word); + + // + // Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp + // And at the same time, clock maybe turned off that say there is no DMA service. + // when ASIC get to sleep. + // To prevent system hang on power saving. + // We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up. + // + // RT2661 => when ASIC is sleeping, MAC register cannot be read and written. + // RT2860 => when ASIC is sleeping, MAC register can be read and written. +// if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) + { + RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word); + RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear + } +// else +// DBGPRINT(RT_DEBUG_TRACE, (">>>fOP_STATUS_DOZE<<<\n")); + +// RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IsrAfterClear); +// RTMP_IO_READ32(pAd, MCU_INT_SOURCE_CSR, &McuIsrAfterClear); +// DBGPRINT(RT_DEBUG_INFO, ("====> RTMPHandleInterrupt(ISR=%08x,Mcu ISR=%08x, After clear ISR=%08x, MCU ISR=%08x)\n", +// IntSource.word, McuIntSource.word, IsrAfterClear, McuIsrAfterClear)); + + // Do nothing if Reset in progress + if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |fRTMP_ADAPTER_HALT_IN_PROGRESS))) + { + return IRQ_HANDLED; + } + + // + // Handle interrupt, walk through all bits + // Should start from highest priority interrupt + // The priority can be adjust by altering processing if statement + // + +#ifdef DBG + +#endif + + + pAd->bPCIclkOff = FALSE; + + // If required spinlock, each interrupt service routine has to acquire + // and release itself. + // + + // Do nothing if NIC doesn't exist + if (IntSource.word == 0xffffffff) + { + RTMP_SET_FLAG(pAd, (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS)); + return IRQ_HANDLED; + } + + if (IntSource.word & TxCoherent) + { + DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n")); + RTMPHandleRxCoherentInterrupt(pAd); + } + + if (IntSource.word & RxCoherent) + { + DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n")); + RTMPHandleRxCoherentInterrupt(pAd); + } + + if (IntSource.word & FifoStaFullInt) + { + if ((pAd->int_disable_mask & FifoStaFullInt) == 0) + { + /* mask FifoStaFullInt */ + rt2860_int_disable(pAd, FifoStaFullInt); + tasklet_hi_schedule(&pObj->fifo_statistic_full_task); + } + pAd->int_pending |= FifoStaFullInt; + } + + if (IntSource.word & INT_MGMT_DLY) + { + if ((pAd->int_disable_mask & INT_MGMT_DLY) ==0 ) + { + rt2860_int_disable(pAd, INT_MGMT_DLY); + tasklet_hi_schedule(&pObj->mgmt_dma_done_task); + } + pAd->int_pending |= INT_MGMT_DLY ; + } + + if (IntSource.word & INT_RX) + { + if ((pAd->int_disable_mask & INT_RX) == 0) + { + + /* mask RxINT */ + rt2860_int_disable(pAd, INT_RX); + tasklet_hi_schedule(&pObj->rx_done_task); + } + pAd->int_pending |= INT_RX; + } + + if (IntSource.word & INT_AC3_DLY) + { + + if ((pAd->int_disable_mask & INT_AC3_DLY) == 0) + { + /* mask TxDataInt */ + rt2860_int_disable(pAd, INT_AC3_DLY); + tasklet_hi_schedule(&pObj->ac3_dma_done_task); + } + pAd->int_pending |= INT_AC3_DLY; + } + + if (IntSource.word & INT_AC2_DLY) + { + + if ((pAd->int_disable_mask & INT_AC2_DLY) == 0) + { + /* mask TxDataInt */ + rt2860_int_disable(pAd, INT_AC2_DLY); + tasklet_hi_schedule(&pObj->ac2_dma_done_task); + } + pAd->int_pending |= INT_AC2_DLY; + } + + if (IntSource.word & INT_AC1_DLY) + { + + pAd->int_pending |= INT_AC1_DLY; + + if ((pAd->int_disable_mask & INT_AC1_DLY) == 0) + { + /* mask TxDataInt */ + rt2860_int_disable(pAd, INT_AC1_DLY); + tasklet_hi_schedule(&pObj->ac1_dma_done_task); + } + + } + + if (IntSource.word & INT_AC0_DLY) + { + +/* + if (IntSource.word & 0x2) { + u32 reg; + RTMP_IO_READ32(pAd, DELAY_INT_CFG, ®); + printk("IntSource.word = %08x, DELAY_REG = %08x\n", IntSource.word, reg); + } +*/ + pAd->int_pending |= INT_AC0_DLY; + + if ((pAd->int_disable_mask & INT_AC0_DLY) == 0) + { + /* mask TxDataInt */ + rt2860_int_disable(pAd, INT_AC0_DLY); + tasklet_hi_schedule(&pObj->ac0_dma_done_task); + } + + } + + + if (IntSource.word & PreTBTTInt) + { + RTMPHandlePreTBTTInterrupt(pAd); + } + + if (IntSource.word & TBTTInt) + { + RTMPHandleTBTTInterrupt(pAd); + } + + { + if (IntSource.word & AutoWakeupInt) + RTMPHandleTwakeupInterrupt(pAd); + } + + return IRQ_HANDLED; +} + +/* + * invaild or writeback cache + * and convert virtual address to physical address + */ +dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction) +{ + PRTMP_ADAPTER pAd; + POS_COOKIE pObj; + + /* + ------ Porting Information ------ + > For Tx Alloc: + mgmt packets => sd_idx = 0 + SwIdx: pAd->MgmtRing.TxCpuIdx + pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa; + + data packets => sd_idx = 1 + TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx + QueIdx: pTxBlk->QueIdx + pTxD : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa; + + > For Rx Alloc: + sd_idx = -1 + */ + + pAd = (PRTMP_ADAPTER)handle; + pObj = (POS_COOKIE)pAd->OS_Cookie; + + if (sd_idx == 1) + { + PTX_BLK pTxBlk; + pTxBlk = (PTX_BLK)ptr; + return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, direction); + } + else + { + return pci_map_single(pObj->pci_dev, ptr, size, direction); + } + +} + +void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction) +{ + PRTMP_ADAPTER pAd; + POS_COOKIE pObj; + + pAd=(PRTMP_ADAPTER)handle; + pObj = (POS_COOKIE)pAd->OS_Cookie; + + if (size > 0) + pci_unmap_single(pObj->pci_dev, dma_addr, size, direction); + +} Index: b/drivers/staging/rt2860/rt_profile.c =================================================================== --- a/drivers/staging/rt2860/rt_profile.c +++ b/drivers/staging/rt2860/rt_profile.c @@ -23,1840 +23,73 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * ************************************************************************* - */ -#include "rt_config.h" - -static void HTParametersHook( - IN PRTMP_ADAPTER pAd, - IN CHAR *pValueStr, - IN CHAR *pInput); - -#define ETH_MAC_ADDR_STR_LEN 17 // in format of xx:xx:xx:xx:xx:xx - -// We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed. -BOOLEAN rtstrmactohex(char *s1, char *s2) -{ - int i = 0; - char *ptokS = s1, *ptokE = s1; - - if (strlen(s1) != ETH_MAC_ADDR_STR_LEN) - return FALSE; - - while((*ptokS) != '\0') - { - if((ptokE = strchr(ptokS, ':')) != NULL) - *ptokE++ = '\0'; - if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1)))) - break; // fail - AtoH(ptokS, &s2[i++], 1); - ptokS = ptokE; - if (i == 6) - break; // parsing finished - } - - return ( i == 6 ? TRUE : FALSE); - -} - - -// we assume the s1 and s2 both are strings. -BOOLEAN rtstrcasecmp(char *s1, char *s2) -{ - char *p1 = s1, *p2 = s2; - - if (strlen(s1) != strlen(s2)) - return FALSE; - - while(*p1 != '\0') - { - if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20)) - return FALSE; - p1++; - p2++; - } - - return TRUE; -} - -// we assume the s1 (buffer) and s2 (key) both are strings. -char * rtstrstruncasecmp(char * s1, char * s2) -{ - INT l1, l2, i; - char temp1, temp2; - - l2 = strlen(s2); - if (!l2) - return (char *) s1; - - l1 = strlen(s1); - - while (l1 >= l2) - { - l1--; - - for(i=0; i= l2) - { - l1--; - if (!memcmp(s1,s2,l2)) - return (char *) s1; - s1++; - } - - return NULL; -} - -/** - * rstrtok - Split a string into tokens - * @s: The string to be searched - * @ct: The characters to search for - * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture. - */ -char * __rstrtok; -char * rstrtok(char * s,const char * ct) -{ - char *sbegin, *send; - - sbegin = s ? s : __rstrtok; - if (!sbegin) - { - return NULL; - } - - sbegin += strspn(sbegin,ct); - if (*sbegin == '\0') - { - __rstrtok = NULL; - return( NULL ); - } - - send = strpbrk( sbegin, ct); - if (send && *send != '\0') - *send++ = '\0'; - - __rstrtok = send; - - return (sbegin); -} - -/** - * delimitcnt - return the count of a given delimiter in a given string. - * @s: The string to be searched. - * @ct: The delimiter to search for. - * Notice : We suppose the delimiter is a single-char string(for example : ";"). - */ -INT delimitcnt(char * s,const char * ct) -{ - INT count = 0; - /* point to the beginning of the line */ - const char *token = s; + Abstract: - for ( ;; ) - { - token = strpbrk(token, ct); /* search for delimiters */ - - if ( token == NULL ) - { - /* advanced to the terminating null character */ - break; - } - /* skip the delimiter */ - ++token; - - /* - * Print the found text: use len with %.*s to specify field width. - */ - - /* accumulate delimiter count */ - ++count; - } - return count; -} - -/* - * converts the Internet host address from the standard numbers-and-dots notation - * into binary data. - * returns nonzero if the address is valid, zero if not. - */ -int rtinet_aton(const char *cp, unsigned int *addr) -{ - unsigned int val; - int base, n; - char c; - unsigned int parts[4]; - unsigned int *pp = parts; - - for (;;) - { - /* - * Collect number up to ``.''. - * Values are specified as for C: - * 0x=hex, 0=octal, other=decimal. - */ - val = 0; - base = 10; - if (*cp == '0') - { - if (*++cp == 'x' || *cp == 'X') - base = 16, cp++; - else - base = 8; - } - while ((c = *cp) != '\0') - { - if (isdigit((unsigned char) c)) - { - val = (val * base) + (c - '0'); - cp++; - continue; - } - if (base == 16 && isxdigit((unsigned char) c)) - { - val = (val << 4) + - (c + 10 - (islower((unsigned char) c) ? 'a' : 'A')); - cp++; - continue; - } - break; - } - if (*cp == '.') - { - /* - * Internet format: a.b.c.d a.b.c (with c treated as 16-bits) - * a.b (with b treated as 24 bits) - */ - if (pp >= parts + 3 || val > 0xff) - return 0; - *pp++ = val, cp++; - } - else - break; - } - - /* - * Check for trailing junk. - */ - while (*cp) - if (!isspace((unsigned char) *cp++)) - return 0; - - /* - * Concoct the address according to the number of parts specified. + Revision History: + Who When What + --------- ---------- ---------------------------------------------- */ - n = pp - parts + 1; - switch (n) - { - - case 1: /* a -- 32 bits */ - break; - - case 2: /* a.b -- 8.24 bits */ - if (val > 0xffffff) - return 0; - val |= parts[0] << 24; - break; - - case 3: /* a.b.c -- 8.8.16 bits */ - if (val > 0xffff) - return 0; - val |= (parts[0] << 24) | (parts[1] << 16); - break; - - case 4: /* a.b.c.d -- 8.8.8.8 bits */ - if (val > 0xff) - return 0; - val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); - break; - } - - *addr = htonl(val); - return 1; - -} - -/* - ======================================================================== - - Routine Description: - Find key section for Get key parameter. - - Arguments: - buffer Pointer to the buffer to start find the key section - section the key of the secion to be find - - Return Value: - NULL Fail - Others Success - ======================================================================== -*/ -PUCHAR RTMPFindSection( - IN PCHAR buffer) -{ - CHAR temp_buf[32]; - PUCHAR ptr; - - strcpy(temp_buf, "Default"); - - if((ptr = rtstrstr(buffer, temp_buf)) != NULL) - return (ptr+strlen("\n")); - else - return NULL; -} - -/* - ======================================================================== - - Routine Description: - Get key parameter. - - Arguments: - key Pointer to key string - dest Pointer to destination - destsize The datasize of the destination - buffer Pointer to the buffer to start find the key - - Return Value: - TRUE Success - FALSE Fail - - Note: - This routine get the value with the matched key (case case-sensitive) - ======================================================================== -*/ -INT RTMPGetKeyParameter( - IN PCHAR key, - OUT PCHAR dest, - IN INT destsize, - IN PCHAR buffer) -{ - UCHAR *temp_buf1 = NULL; - UCHAR *temp_buf2 = NULL; - CHAR *start_ptr; - CHAR *end_ptr; - CHAR *ptr; - CHAR *offset = 0; - INT len; - - //temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG); - os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE); - - if(temp_buf1 == NULL) - return (FALSE); - - //temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG); - os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE); - if(temp_buf2 == NULL) - { - os_free_mem(NULL, temp_buf1); - return (FALSE); - } - - //find section - if((offset = RTMPFindSection(buffer)) == NULL) - { - os_free_mem(NULL, temp_buf1); - os_free_mem(NULL, temp_buf2); - return (FALSE); - } - - strcpy(temp_buf1, "\n"); - strcat(temp_buf1, key); - strcat(temp_buf1, "="); - - //search key - if((start_ptr=rtstrstr(offset, temp_buf1))==NULL) - { - os_free_mem(NULL, temp_buf1); - os_free_mem(NULL, temp_buf2); - return (FALSE); - } - - start_ptr+=strlen("\n"); - if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL) - end_ptr=start_ptr+strlen(start_ptr); - - if (end_ptrSharedKey[i][idx].KeyLen = KeyLen / 2; - AtoH(keybuff, pAd->SharedKey[i][idx].Key, KeyLen / 2); - if (KeyLen == 10) - CipherAlg = CIPHER_WEP64; - else - CipherAlg = CIPHER_WEP128; - pAd->SharedKey[i][idx].CipherAlg = CipherAlg; - - DBGPRINT(RT_DEBUG_TRACE, ("I/F(wlan%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii")); - return 1; - } - else - {//Invalid key length - DBGPRINT(RT_DEBUG_ERROR, ("I/F(wlan%d) Key%dStr is Invalid key length! KeyLen = %ld!\n", i, idx+1, KeyLen)); - return 0; + retval = NDIS_STATUS_FAILURE; + DBGPRINT(RT_DEBUG_ERROR, ("Close file \"%s\" failed(errCode=%d)!\n", src, retval)); } } -} -static void rtmp_read_key_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer) -{ - char tok_str[16]; - PUCHAR macptr; - INT i = 0, idx; - ULONG KeyType[MAX_MBSSID_NUM]; - ULONG KeyIdx; - - NdisZeroMemory(KeyType, MAX_MBSSID_NUM); - - //DefaultKeyID - if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer)) - { - { - KeyIdx = simple_strtol(tmpbuf, 0, 10); - if((KeyIdx >= 1 ) && (KeyIdx <= 4)) - pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1); - else - pAd->StaCfg.DefaultKeyId = 0; - DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId)); - } + RtmpOSFSInfoChange(&osFSInfo, FALSE); } - - for (idx = 0; idx < 4; idx++) - { - sprintf(tok_str, "Key%dType", idx + 1); - //Key1Type - if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer)) - { - for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) - { - KeyType[i] = simple_strtol(macptr, 0, 10); - } - - { - sprintf(tok_str, "Key%dStr", idx + 1); - if (RTMPGetCriticalParameter(tok_str, tmpbuf, 128, buffer)) - { - rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx); - } - } - } - } -} - -static void rtmp_read_sta_wmm_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer) -{ - PUCHAR macptr; - INT i=0; - BOOLEAN bWmmEnable = FALSE; - - //WmmCapable - if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer)) - { - if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable - { - pAd->CommonCfg.bWmmCapable = TRUE; - bWmmEnable = TRUE; - } - else //Disable - { - pAd->CommonCfg.bWmmCapable = FALSE; - } - - DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable)); - } - - //AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO - if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer)) - { - for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) - { - pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10); - - DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i])); - } - } - - if (bWmmEnable) - { - //APSDCapable - if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer)) - { - if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable - pAd->CommonCfg.bAPSDCapable = TRUE; - else - pAd->CommonCfg.bAPSDCapable = FALSE; - - DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable)); - } - - //APSDAC for AC_BE, AC_BK, AC_VI, AC_VO - if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer)) - { - BOOLEAN apsd_ac[4]; - - for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) - { - apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10); - - DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d %d\n", i, apsd_ac[i])); - } - - pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0]; - pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1]; - pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2]; - pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3]; - } - } - -} - -NDIS_STATUS RTMPReadParametersHook( - IN PRTMP_ADAPTER pAd) -{ - PUCHAR src = NULL; - struct file *srcf; - INT retval; - mm_segment_t orgfs; - CHAR *buffer; - CHAR *tmpbuf; - ULONG RtsThresh; - ULONG FragThresh; - UCHAR keyMaterial[40]; - - PUCHAR macptr; - INT i = 0; - - buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG); - if(buffer == NULL) - return NDIS_STATUS_FAILURE; - - tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG); - if(tmpbuf == NULL) - { - kfree(buffer); - return NDIS_STATUS_FAILURE; - } - - src = STA_PROFILE_PATH; - - orgfs = get_fs(); - set_fs(KERNEL_DS); - - if (src && *src) - { - srcf = filp_open(src, O_RDONLY, 0); - if (IS_ERR(srcf)) - { - DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src)); - } - else - { - // The object must have a read method - if (srcf->f_op && srcf->f_op->read) - { - memset(buffer, 0x00, MAX_INI_BUFFER_SIZE); - retval=srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos); - if (retval < 0) - { - DBGPRINT(RT_DEBUG_TRACE, ("--> Read %s error %d\n", src, -retval)); - } - else - { - // set file parameter to portcfg - //CountryRegion - if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, buffer)) - { - pAd->CommonCfg.CountryRegion = (UCHAR) simple_strtol(tmpbuf, 0, 10); - DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion)); - } - //CountryRegionABand - if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, buffer)) - { - pAd->CommonCfg.CountryRegionForABand= (UCHAR) simple_strtol(tmpbuf, 0, 10); - DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand)); - } - //CountryCode - if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, buffer)) - { - NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2); - - if (strlen(pAd->CommonCfg.CountryCode) != 0) - { - pAd->CommonCfg.bCountryFlag = TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode)); - } - //ChannelGeography - if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, buffer)) - { - UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10); - if (Geography <= BOTH) - { - pAd->CommonCfg.Geography = Geography; - pAd->CommonCfg.CountryCode[2] = - (pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O'); - DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography)); - } - } - else - { - pAd->CommonCfg.Geography = BOTH; - pAd->CommonCfg.CountryCode[2] = ' '; - } - - { - //SSID - if (RTMPGetCriticalParameter("SSID", tmpbuf, 256, buffer)) - { - if (strlen(tmpbuf) <= 32) - { - pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf); - NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID); - NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen); - pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen; - NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID); - NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen); - pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen; - NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID); - NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen); - DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __func__, tmpbuf)); - } - } - } - - { - //NetworkType - if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, buffer)) - { - pAd->bConfigChanged = TRUE; - if (strcmp(tmpbuf, "Adhoc") == 0) - pAd->StaCfg.BssType = BSS_ADHOC; - else //Default Infrastructure mode - pAd->StaCfg.BssType = BSS_INFRA; - // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key - pAd->StaCfg.WpaState = SS_NOTUSE; - DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __func__, pAd->StaCfg.BssType)); - } - } - - //Channel - if(RTMPGetKeyParameter("Channel", tmpbuf, 10, buffer)) - { - pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10); - DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel)); - } - //WirelessMode - if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, buffer)) - { - int value = 0, maxPhyMode = PHY_11G; - - maxPhyMode = PHY_11N_5G; - - value = simple_strtol(tmpbuf, 0, 10); - - if (value <= maxPhyMode) - { - pAd->CommonCfg.PhyMode = value; - } - DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode)); - } - //BasicRate - if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, buffer)) - { - pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10); - DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap)); - } - //BeaconPeriod - if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, buffer)) - { - pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10); - DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod)); - } - //TxPower - if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, buffer)) - { - pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10); - - pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage; - - DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage)); - } - //BGProtection - if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, buffer)) - { - switch (simple_strtol(tmpbuf, 0, 10)) - { - case 1: //Always On - pAd->CommonCfg.UseBGProtection = 1; - break; - case 2: //Always OFF - pAd->CommonCfg.UseBGProtection = 2; - break; - case 0: //AUTO - default: - pAd->CommonCfg.UseBGProtection = 0; - break; - } - DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection)); - } - //OLBCDetection - if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, buffer)) - { - switch (simple_strtol(tmpbuf, 0, 10)) - { - case 1: //disable OLBC Detection - pAd->CommonCfg.DisableOLBCDetect = 1; - break; - case 0: //enable OLBC Detection - pAd->CommonCfg.DisableOLBCDetect = 0; - break; - default: - pAd->CommonCfg.DisableOLBCDetect= 0; - break; - } - DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect)); - } - //TxPreamble - if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, buffer)) - { - switch (simple_strtol(tmpbuf, 0, 10)) - { - case Rt802_11PreambleShort: - pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort; - break; - case Rt802_11PreambleLong: - default: - pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong; - break; - } - DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble)); - } - //RTSThreshold - if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, buffer)) - { - RtsThresh = simple_strtol(tmpbuf, 0, 10); - if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) ) - pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh; - else - pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD; - - DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold)); - } - //FragThreshold - if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, buffer)) - { - FragThresh = simple_strtol(tmpbuf, 0, 10); - pAd->CommonCfg.bUseZeroToDisableFragment = FALSE; - - if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD) - { //illegal FragThresh so we set it to default - pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD; - pAd->CommonCfg.bUseZeroToDisableFragment = TRUE; - } - else if (FragThresh % 2 == 1) - { - // The length of each fragment shall always be an even number of octets, except for the last fragment - // of an MSDU or MMPDU, which may be either an even or an odd number of octets. - pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1); - } - else - { - pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh; - } - //pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC; - DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold)); - } - //TxBurst - if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, buffer)) - { - if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable - pAd->CommonCfg.bEnableTxBurst = TRUE; - else //Disable - pAd->CommonCfg.bEnableTxBurst = FALSE; - DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst)); - } - -#ifdef AGGREGATION_SUPPORT - //PktAggregate - if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, buffer)) - { - if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable - pAd->CommonCfg.bAggregationCapable = TRUE; - else //Disable - pAd->CommonCfg.bAggregationCapable = FALSE; -#ifdef PIGGYBACK_SUPPORT - pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable; -#endif // PIGGYBACK_SUPPORT // - DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable)); - } -#else - pAd->CommonCfg.bAggregationCapable = FALSE; - pAd->CommonCfg.bPiggyBackCapable = FALSE; -#endif // AGGREGATION_SUPPORT // - - // WmmCapable - rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, buffer); - - //ShortSlot - if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, buffer)) - { - if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable - pAd->CommonCfg.bUseShortSlotTime = TRUE; - else //Disable - pAd->CommonCfg.bUseShortSlotTime = FALSE; - - DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime)); - } - //IEEE80211H - if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, buffer)) - { - for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) - { - if(simple_strtol(macptr, 0, 10) != 0) //Enable - pAd->CommonCfg.bIEEE80211H = TRUE; - else //Disable - pAd->CommonCfg.bIEEE80211H = FALSE; - - DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H)); - } - } - //CSPeriod - if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, buffer)) - { - if(simple_strtol(tmpbuf, 0, 10) != 0) - pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10); - else - pAd->CommonCfg.RadarDetect.CSPeriod = 0; - - DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod)); - } - - //RDRegion - if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, buffer)) - { - if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0)) - { - pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W53; - pAd->CommonCfg.RadarDetect.DfsSessionTime = 15; - } - else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0)) - { - pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W56; - pAd->CommonCfg.RadarDetect.DfsSessionTime = 13; - } - else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0)) - { - pAd->CommonCfg.RadarDetect.RDDurRegion = JAP; - pAd->CommonCfg.RadarDetect.DfsSessionTime = 5; - } - else if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0)) - { - pAd->CommonCfg.RadarDetect.RDDurRegion = FCC; - pAd->CommonCfg.RadarDetect.DfsSessionTime = 5; - } - else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0)) - { - pAd->CommonCfg.RadarDetect.RDDurRegion = CE; - pAd->CommonCfg.RadarDetect.DfsSessionTime = 13; - } - else - { - pAd->CommonCfg.RadarDetect.RDDurRegion = CE; - pAd->CommonCfg.RadarDetect.DfsSessionTime = 13; - } - - DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RadarDetect.RDDurRegion)); - } - else - { - pAd->CommonCfg.RadarDetect.RDDurRegion = CE; - pAd->CommonCfg.RadarDetect.DfsSessionTime = 13; - } - - //WirelessEvent - if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, buffer)) - { - if(simple_strtol(tmpbuf, 0, 10) != 0) - pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10); - else - pAd->CommonCfg.bWirelessEvent = 0; // disable - DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent)); - } - if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, buffer)) - { - if(simple_strtol(tmpbuf, 0, 10) != 0) - pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10); - else - pAd->CommonCfg.bWiFiTest = 0; // disable - - DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest)); - } - //AuthMode - if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, buffer)) - { - { - if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0)) - pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch; - else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0)) - pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared; - else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0)) - pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK; - else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0)) - pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone; - else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0)) - pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK; - else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0)) - pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA; - else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0)) - pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2; - else - pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen; - - pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; - - DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus)); - } - } - //EncrypType - if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, buffer)) - { - { - if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0)) - pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled; - else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0)) - pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled; - else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0)) - pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled; - else - pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled; - - // Update all wepstatus related - pAd->StaCfg.PairCipher = pAd->StaCfg.WepStatus; - pAd->StaCfg.GroupCipher = pAd->StaCfg.WepStatus; - pAd->StaCfg.OrigWepStatus = pAd->StaCfg.WepStatus; - pAd->StaCfg.bMixCipher = FALSE; - - DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus)); - } - } - - { - if(RTMPGetCriticalParameter("WPAPSK", tmpbuf, 512, buffer)) - { - int err=0; - - tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input - - if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) && - (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) && - (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) - ) - { - err = 1; - } - else if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) < 64)) - { - PasswordHash((char *)tmpbuf, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, keyMaterial); - NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32); - - } - else if (strlen(tmpbuf) == 64) - { - AtoH(tmpbuf, keyMaterial, 32); - NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32); - } - else - { - err = 1; - DBGPRINT(RT_DEBUG_ERROR, ("%s::(WPAPSK key-string required 8 ~ 64 characters!)\n", __func__)); - } - - if (err == 0) - { - if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || - (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) - { - // Start STA supplicant state machine - pAd->StaCfg.WpaState = SS_START; - } - else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) - { - pAd->StaCfg.WpaState = SS_NOTUSE; - } - - DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __func__, tmpbuf)); - } - } - } - - //DefaultKeyID, KeyType, KeyStr - rtmp_read_key_parms_from_file(pAd, tmpbuf, buffer); - - HTParametersHook(pAd, tmpbuf, buffer); - - { - //PSMode -#ifdef RT2860 - if (RTMPGetKeyParameter("PSMode", tmpbuf, 32, buffer)) -#endif -#ifdef RT2870 - if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer)) -#endif - { - if (pAd->StaCfg.BssType == BSS_INFRA) - { - if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0)) - { - // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange() - // to exclude certain situations. - // MlmeSetPsm(pAd, PWR_SAVE); - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); - if (pAd->StaCfg.bWindowsACCAMEnable == FALSE) - pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP; - pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP; - pAd->StaCfg.DefaultListenCount = 5; - } - else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0) - || (strcmp(tmpbuf, "FAST_PSP") == 0)) - { - // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange() - // to exclude certain situations. - // MlmeSetPsmBit(pAd, PWR_SAVE); - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); - if (pAd->StaCfg.bWindowsACCAMEnable == FALSE) - pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP; - pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP; - pAd->StaCfg.DefaultListenCount = 3; - } - else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0) - || (strcmp(tmpbuf, "LEGACY_PSP") == 0)) - { - // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange() - // to exclude certain situations. - // MlmeSetPsmBit(pAd, PWR_SAVE); - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); - if (pAd->StaCfg.bWindowsACCAMEnable == FALSE) - pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP; - pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP; - pAd->StaCfg.DefaultListenCount = 3; - } - else - { //Default Ndis802_11PowerModeCAM - // clear PSM bit immediately - MlmeSetPsmBit(pAd, PWR_ACTIVE); - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM); - if (pAd->StaCfg.bWindowsACCAMEnable == FALSE) - pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM; - pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM; - } - DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode)); - } - } - // FastRoaming - if (RTMPGetKeyParameter("FastRoaming", tmpbuf, 32, buffer)) - { - if (simple_strtol(tmpbuf, 0, 10) == 0) - pAd->StaCfg.bFastRoaming = FALSE; - else - pAd->StaCfg.bFastRoaming = TRUE; - - DBGPRINT(RT_DEBUG_TRACE, ("FastRoaming=%d\n", pAd->StaCfg.bFastRoaming)); - } - // RoamThreshold - if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, buffer)) - { - long lInfo = simple_strtol(tmpbuf, 0, 10); - - if (lInfo > 90 || lInfo < 60) - pAd->StaCfg.dBmToRoam = -70; - else - pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo; - - DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d dBm\n", pAd->StaCfg.dBmToRoam)); - } - - if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, buffer)) - { - if(simple_strtol(tmpbuf, 0, 10) == 0) - pAd->StaCfg.bTGnWifiTest = FALSE; - else - pAd->StaCfg.bTGnWifiTest = TRUE; - DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest)); - } - } - } - } - else - { - DBGPRINT(RT_DEBUG_TRACE, ("--> %s does not have a write method\n", src)); - } - - retval=filp_close(srcf,NULL); - - if (retval) - { - DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src)); - } - } - } - - set_fs(orgfs); - kfree(buffer); - kfree(tmpbuf); - - return (NDIS_STATUS_SUCCESS); -} - -static void HTParametersHook( - IN PRTMP_ADAPTER pAd, - IN CHAR *pValueStr, - IN CHAR *pInput) -{ - - INT Value; - - if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value == 0) - { - pAd->CommonCfg.bHTProtect = FALSE; - } - else - { - pAd->CommonCfg.bHTProtect = TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection = %s\n", (Value==0) ? "Disable" : "Enable")); - } - - if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value == 0) - { - pAd->CommonCfg.bMIMOPSEnable = FALSE; - } - else - { - pAd->CommonCfg.bMIMOPSEnable = TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable = %s\n", (Value==0) ? "Disable" : "Enable")); - } - - - if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value > MMPS_ENABLE) - { - pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE; - } - else - { - //TODO: add mimo power saving mechanism - pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE; - //pAd->CommonCfg.BACapability.field.MMPSmode = Value; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode = %d\n", Value)); - } - - if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value == 0) - { - pAd->CommonCfg.bBADecline = FALSE; - } - else - { - pAd->CommonCfg.bBADecline = TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline = %s\n", (Value==0) ? "Disable" : "Enable")); - } - - - if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value == 0) - { - pAd->CommonCfg.bDisableReordering = FALSE; - } - else - { - pAd->CommonCfg.bDisableReordering = TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering = %s\n", (Value==0) ? "Disable" : "Enable")); - } - - if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value == 0) - { - pAd->CommonCfg.BACapability.field.AutoBA = FALSE; - pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE; - } - else - { - pAd->CommonCfg.BACapability.field.AutoBA = TRUE; - pAd->CommonCfg.BACapability.field.Policy = IMMED_BA; - } - pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA; - pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy; - DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA = %s\n", (Value==0) ? "Disable" : "Enable")); - } - - // Tx_+HTC frame - if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value == 0) - { - pAd->HTCEnable = FALSE; - } - else - { - pAd->HTCEnable = TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable")); - } - - // Enable HT Link Adaptation Control - if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value == 0) - { - pAd->bLinkAdapt = FALSE; - } - else - { - pAd->HTCEnable = TRUE; - pAd->bLinkAdapt = TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)")); - } - - // Reverse Direction Mechanism - if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value == 0) - { - pAd->CommonCfg.bRdg = FALSE; - } - else - { - pAd->HTCEnable = TRUE; - pAd->CommonCfg.bRdg = TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)")); - } - - - - - // Tx A-MSUD ? - if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value == 0) - { - pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE; - } - else - { - pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable")); - } - - // MPDU Density - if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value <=7 && Value >= 0) - { - pAd->CommonCfg.BACapability.field.MpduDensity = Value; - DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", Value)); - } - else - { - pAd->CommonCfg.BACapability.field.MpduDensity = 4; - DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4)); - } - } - - // Max Rx BA Window Size - if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - - if (Value >=1 && Value <= 64) - { - pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value; - pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value; - DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", Value)); - } - else - { - pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64; - pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; - DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n")); - } - - } - - // Guard Interval - if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - - if (Value == GI_400) - { - pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400; - } - else - { - pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800; - } - - DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" )); - } - - // HT Operation Mode : Mixed Mode , Green Field - if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - - if (Value == HTMODE_GF) - { - - pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF; - } - else - { - pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM; - } - - DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" )); - } - - // Fixed Tx mode : CCK, OFDM - if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput)) - { - UCHAR fix_tx_mode; - - { - fix_tx_mode = FIXED_TXMODE_HT; - - if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0) - { - fix_tx_mode = FIXED_TXMODE_OFDM; - } - else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0) - { - fix_tx_mode = FIXED_TXMODE_CCK; - } - else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0) - { - fix_tx_mode = FIXED_TXMODE_HT; - } - else - { - Value = simple_strtol(pValueStr, 0, 10); - // 1 : CCK - // 2 : OFDM - // otherwise : HT - if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM) - fix_tx_mode = Value; - else - fix_tx_mode = FIXED_TXMODE_HT; - } - - pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode; - DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode)); - - } - } - - - // Channel Width - if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value == BW_40) - { - pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40; - } - else - { - pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20; - } - -#ifdef MCAST_RATE_SPECIFIC - pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW; -#endif // MCAST_RATE_SPECIFIC // - - DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" )); - } - - if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - - if (Value == 0) - { - - pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW; - } - else - { - pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE; - } - - DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" )); - } - - // MSC - if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput)) - { - { - Value = simple_strtol(pValueStr, 0, 10); - - if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3 - { - pAd->StaCfg.DesiredTransmitSetting.field.MCS = Value; - pAd->StaCfg.bAutoTxRateSwitch = FALSE; - DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS)); - } - else - { - pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO; - pAd->StaCfg.bAutoTxRateSwitch = TRUE; - DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n")); - } - } - } - - // STBC - if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value == STBC_USE) - { - pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE; - } - else - { - pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC)); - } - - // 40_Mhz_Intolerant - if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput)) - { - Value = simple_strtol(pValueStr, 0, 10); - if (Value == 0) - { - pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE; - } - else - { - pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant)); - } - //HT_TxStream - if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput)) - { - switch (simple_strtol(pValueStr, 0, 10)) - { - case 1: - pAd->CommonCfg.TxStream = 1; - break; - case 2: - pAd->CommonCfg.TxStream = 2; - break; - case 3: // 3*3 - default: - pAd->CommonCfg.TxStream = 3; - - if (pAd->MACVersion < RALINK_2883_VERSION) - pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series - break; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream)); - } - //HT_RxStream - if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput)) - { - switch (simple_strtol(pValueStr, 0, 10)) - { - case 1: - pAd->CommonCfg.RxStream = 1; - break; - case 2: - pAd->CommonCfg.RxStream = 2; - break; - case 3: - default: - pAd->CommonCfg.RxStream = 3; - - if (pAd->MACVersion < RALINK_2883_VERSION) - pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series - break; - } - DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream)); - } + return (retval); } + Index: b/drivers/staging/rt2860/rt_usb.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/rt_usb.c @@ -0,0 +1,828 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rtusb_bulk.c + + Abstract: + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs + +*/ + +#include "rt_config.h" + + void dump_urb(struct urb* purb) +{ + printk("urb :0x%08lx\n", (unsigned long)purb); + printk("\tdev :0x%08lx\n", (unsigned long)purb->dev); + printk("\t\tdev->state :0x%d\n", purb->dev->state); + printk("\tpipe :0x%08x\n", purb->pipe); + printk("\tstatus :%d\n", purb->status); + printk("\ttransfer_flags :0x%08x\n", purb->transfer_flags); + printk("\ttransfer_buffer :0x%08lx\n", (unsigned long)purb->transfer_buffer); + printk("\ttransfer_buffer_length:%d\n", purb->transfer_buffer_length); + printk("\tactual_length :%d\n", purb->actual_length); + printk("\tsetup_packet :0x%08lx\n", (unsigned long)purb->setup_packet); + printk("\tstart_frame :%d\n", purb->start_frame); + printk("\tnumber_of_packets :%d\n", purb->number_of_packets); + printk("\tinterval :%d\n", purb->interval); + printk("\terror_count :%d\n", purb->error_count); + printk("\tcontext :0x%08lx\n", (unsigned long)purb->context); + printk("\tcomplete :0x%08lx\n\n", (unsigned long)purb->complete); +} + +/* +======================================================================== +Routine Description: + Create kernel threads & tasklets. + +Arguments: + *net_dev Pointer to wireless net device interface + +Return Value: + NDIS_STATUS_SUCCESS + NDIS_STATUS_FAILURE + +Note: +======================================================================== +*/ +NDIS_STATUS RtmpMgmtTaskInit( + IN RTMP_ADAPTER *pAd) +{ + RTMP_OS_TASK *pTask; + NDIS_STATUS status; + + /* + Creat TimerQ Thread, We need init timerQ related structure before create the timer thread. + */ + RtmpTimerQInit(pAd); + + pTask = &pAd->timerTask; + RtmpOSTaskInit(pTask, "RtmpTimerTask", pAd); + status = RtmpOSTaskAttach(pTask, RtmpTimerQThread, pTask); + if (status == NDIS_STATUS_FAILURE) + { + printk (KERN_WARNING "%s: unable to start RtmpTimerQThread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev)); + return NDIS_STATUS_FAILURE; + } + + /* Creat MLME Thread */ + pTask = &pAd->mlmeTask; + RtmpOSTaskInit(pTask, "RtmpMlmeTask", pAd); + status = RtmpOSTaskAttach(pTask, MlmeThread, pTask); + if (status == NDIS_STATUS_FAILURE) + { + printk (KERN_WARNING "%s: unable to start MlmeThread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev)); + return NDIS_STATUS_FAILURE; + } + + /* Creat Command Thread */ + pTask = &pAd->cmdQTask; + RtmpOSTaskInit(pTask, "RtmpCmdQTask", pAd); + status = RtmpOSTaskAttach(pTask, RTUSBCmdThread, pTask); + if (status == NDIS_STATUS_FAILURE) + { + printk (KERN_WARNING "%s: unable to start RTUSBCmdThread\n", RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev)); + return NDIS_STATUS_FAILURE; + } + + + return NDIS_STATUS_SUCCESS; +} + + + +/* +======================================================================== +Routine Description: + Close kernel threads. + +Arguments: + *pAd the raxx interface data pointer + +Return Value: + NONE + +Note: +======================================================================== +*/ +VOID RtmpMgmtTaskExit( + IN RTMP_ADAPTER *pAd) +{ + INT ret; + RTMP_OS_TASK *pTask; + + // Sleep 50 milliseconds so pending io might finish normally + RTMPusecDelay(50000); + + // We want to wait until all pending receives and sends to the + // device object. We cancel any + // irps. Wait until sends and receives have stopped. + RTUSBCancelPendingIRPs(pAd); + + // We need clear timerQ related structure before exits of the timer thread. + RtmpTimerQExit(pAd); + + /* Terminate Mlme Thread */ + pTask = &pAd->mlmeTask; + ret = RtmpOSTaskKill(pTask); + if (ret == NDIS_STATUS_FAILURE) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", + RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName)); + } + + /* Terminate cmdQ thread */ + pTask = &pAd->cmdQTask; +#ifdef KTHREAD_SUPPORT + if (pTask->kthread_task) +#else + CHECK_PID_LEGALITY(pTask->taskPID) +#endif + { + mb(); + NdisAcquireSpinLock(&pAd->CmdQLock); + pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED; + NdisReleaseSpinLock(&pAd->CmdQLock); + mb(); + //RTUSBCMDUp(pAd); + ret = RtmpOSTaskKill(pTask); + if (ret == NDIS_STATUS_FAILURE) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", + RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName)); + } + pAd->CmdQ.CmdQState = RTMP_TASK_STAT_UNKNOWN; + } + + /* Terminate timer thread */ + pTask = &pAd->timerTask; + ret = RtmpOSTaskKill(pTask); + if (ret == NDIS_STATUS_FAILURE) + { + DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n", + RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev), pTask->taskName)); + } + + +} + + +static void rtusb_dataout_complete(unsigned long data) +{ + PRTMP_ADAPTER pAd; + purbb_t pUrb; + POS_COOKIE pObj; + PHT_TX_CONTEXT pHTTXContext; + UCHAR BulkOutPipeId; + NTSTATUS Status; + unsigned long IrqFlags; + + + pUrb = (purbb_t)data; + pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; + pAd = pHTTXContext->pAd; + pObj = (POS_COOKIE) pAd->OS_Cookie; + Status = pUrb->status; + + // Store BulkOut PipeId + BulkOutPipeId = pHTTXContext->BulkOutPipeId; + pAd->BulkOutDataOneSecCount++; + + //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition, + // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); + + RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + pAd->BulkOutPending[BulkOutPipeId] = FALSE; + pHTTXContext->IRPPending = FALSE; + pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; + + if (Status == USB_ST_NOERROR) + { + pAd->BulkOutComplete++; + + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + + pAd->Counters8023.GoodTransmits++; + //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); + FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext); + //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); + + + } + else // STATUS_OTHER + { + PUCHAR pBuf; + + pAd->BulkOutCompleteOther++; + + pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition]; + + if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST | + fRTMP_ADAPTER_BULKOUT_RESET))) + { + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + pAd->bulkResetPipeid = BulkOutPipeId; + pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq; + } + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); + + DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status)); + DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther)); + DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7])); + //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther)); + + } + + // + // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut + // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. + // + //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); + if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) && + (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) && + !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId))) + { + // Indicate There is data avaliable + RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); + } + //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); + + // Always call Bulk routine, even reset bulk. + // The protection of rest bulk should be in BulkOut routine + RTUSBKickBulkOut(pAd); +} + + +static void rtusb_null_frame_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PTX_CONTEXT pNullContext; + purbb_t pUrb; + NTSTATUS Status; + unsigned long irqFlag; + + + pUrb = (purbb_t)data; + pNullContext = (PTX_CONTEXT)pUrb->context; + pAd = pNullContext->pAd; + Status = pUrb->status; + + // Reset Null frame context flags + RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag); + pNullContext->IRPPending = FALSE; + pNullContext->InUse = FALSE; + pAd->BulkOutPending[0] = FALSE; + pAd->watchDogTxPendingCnt[0] = 0; + + if (Status == USB_ST_NOERROR) + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); + + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); + } + else // STATUS_OTHER + { + if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status)); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); + } + } + + // Always call Bulk routine, even reset bulk. + // The protectioon of rest bulk should be in BulkOut routine + RTUSBKickBulkOut(pAd); +} + + +static void rtusb_rts_frame_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PTX_CONTEXT pRTSContext; + purbb_t pUrb; + NTSTATUS Status; + unsigned long irqFlag; + + + pUrb = (purbb_t)data; + pRTSContext = (PTX_CONTEXT)pUrb->context; + pAd = pRTSContext->pAd; + Status = pUrb->status; + + // Reset RTS frame context flags + RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag); + pRTSContext->IRPPending = FALSE; + pRTSContext->InUse = FALSE; + + if (Status == USB_ST_NOERROR) + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); + } + else // STATUS_OTHER + { + if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n")); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); + } + } + + RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]); + pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE; + RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]); + + // Always call Bulk routine, even reset bulk. + // The protectioon of rest bulk should be in BulkOut routine + RTUSBKickBulkOut(pAd); + + +} + + +static void rtusb_pspoll_frame_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PTX_CONTEXT pPsPollContext; + purbb_t pUrb; + NTSTATUS Status; + + + + pUrb = (purbb_t)data; + pPsPollContext = (PTX_CONTEXT)pUrb->context; + pAd = pPsPollContext->pAd; + Status = pUrb->status; + + // Reset PsPoll context flags + pPsPollContext->IRPPending = FALSE; + pPsPollContext->InUse = FALSE; + pAd->watchDogTxPendingCnt[0] = 0; + + if (Status == USB_ST_NOERROR) + { + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); + } + else // STATUS_OTHER + { + if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n")); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + } + + RTMP_SEM_LOCK(&pAd->BulkOutLock[0]); + pAd->BulkOutPending[0] = FALSE; + RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]); + + // Always call Bulk routine, even reset bulk. + // The protectioon of rest bulk should be in BulkOut routine + RTUSBKickBulkOut(pAd); + +} + + +/* +======================================================================== +Routine Description: + Handle received packets. + +Arguments: + data - URB information pointer + +Return Value: + None + +Note: +======================================================================== +*/ +static void rx_done_tasklet(unsigned long data) +{ + purbb_t pUrb; + PRX_CONTEXT pRxContext; + PRTMP_ADAPTER pAd; + NTSTATUS Status; + unsigned int IrqFlags; + + pUrb = (purbb_t)data; + pRxContext = (PRX_CONTEXT)pUrb->context; + pAd = pRxContext->pAd; + Status = pUrb->status; + + + RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); + pRxContext->InUse = FALSE; + pRxContext->IRPPending = FALSE; + pRxContext->BulkInOffset += pUrb->actual_length; + //NdisInterlockedDecrement(&pAd->PendingRx); + pAd->PendingRx--; + + if (Status == USB_ST_NOERROR) + { + pAd->BulkInComplete++; + pAd->NextRxBulkInPosition = 0; + if (pRxContext->BulkInOffset) // As jan's comment, it may bulk-in success but size is zero. + { + pRxContext->Readable = TRUE; + INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE); + } + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + } + else // STATUS_OTHER + { + pAd->BulkInCompleteFail++; + // Still read this packet although it may comtain wrong bytes. + pRxContext->Readable = FALSE; + RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); + + // Parsing all packets. because after reset, the index will reset to all zero. + if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_BULKIN_RESET | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n", + Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length)); + + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0); + } + } + + ASSERT((pRxContext->InUse == pRxContext->IRPPending)); + + RTUSBBulkReceive(pAd); + + + return; + +} + + +static void rtusb_mgmt_dma_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PTX_CONTEXT pMLMEContext; + int index; + PNDIS_PACKET pPacket; + purbb_t pUrb; + NTSTATUS Status; + unsigned long IrqFlags; + + + pUrb = (purbb_t)data; + pMLMEContext = (PTX_CONTEXT)pUrb->context; + pAd = pMLMEContext->pAd; + Status = pUrb->status; + index = pMLMEContext->SelfIdx; + + ASSERT((pAd->MgmtRing.TxDmaIdx == index)); + + RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); + + + if (Status != USB_ST_NOERROR) + { + //Bulk-Out fail status handle + if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && + (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) + { + DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status)); + // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt? + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); + pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); + } + } + + pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); + + RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); + // Reset MLME context flags + pMLMEContext->IRPPending = FALSE; + pMLMEContext->InUse = FALSE; + pMLMEContext->bWaitingBulkOut = FALSE; + pMLMEContext->BulkOutSize = 0; + + pPacket = pAd->MgmtRing.Cell[index].pNdisPacket; + pAd->MgmtRing.Cell[index].pNdisPacket = NULL; + + // Increase MgmtRing Index + INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE); + pAd->MgmtRing.TxSwFreeIdx++; + RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); + + // No-matter success or fail, we free the mgmt packet. + if (pPacket) + RTMPFreeNdisPacket(pAd, pPacket); + + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + // do nothing and return directly. + } + else + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) && + ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)) + { // For Mgmt Bulk-Out failed, ignore it now. + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { + + // Always call Bulk routine, even reset bulk. + // The protectioon of rest bulk should be in BulkOut routine + if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */) + { + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); + } + RTUSBKickBulkOut(pAd); + } + } + + +} + +static void rtusb_ac3_dma_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PHT_TX_CONTEXT pHTTXContext; + UCHAR BulkOutPipeId = 3; + purbb_t pUrb; + + + pUrb = (purbb_t)data; + pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; + pAd = pHTTXContext->pAd; + + rtusb_dataout_complete((unsigned long)pUrb); + + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + // do nothing and return directly. + } + else + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) + { + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; + if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && + /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ + (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && + (pHTTXContext->bCurWriting == FALSE)) + { + RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); + } + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3); + RTUSBKickBulkOut(pAd); + } + } + + + return; +} + + +static void rtusb_ac2_dma_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PHT_TX_CONTEXT pHTTXContext; + UCHAR BulkOutPipeId = 2; + purbb_t pUrb; + + + pUrb = (purbb_t)data; + pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; + pAd = pHTTXContext->pAd; + + rtusb_dataout_complete((unsigned long)pUrb); + + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + // do nothing and return directly. + } + else + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) + { + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; + if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && + /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ + (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && + (pHTTXContext->bCurWriting == FALSE)) + { + RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); + } + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2); + RTUSBKickBulkOut(pAd); + } + } + + + return; +} + + +static void rtusb_ac1_dma_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PHT_TX_CONTEXT pHTTXContext; + UCHAR BulkOutPipeId = 1; + purbb_t pUrb; + + + pUrb = (purbb_t)data; + pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; + pAd = pHTTXContext->pAd; + + rtusb_dataout_complete((unsigned long)pUrb); + + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + // do nothing and return directly. + } + else + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) + { + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; + if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && + /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ + (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && + (pHTTXContext->bCurWriting == FALSE)) + { + RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); + } + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1); + RTUSBKickBulkOut(pAd); + } + } + return; + +} + + +static void rtusb_ac0_dma_done_tasklet(unsigned long data) +{ + PRTMP_ADAPTER pAd; + PHT_TX_CONTEXT pHTTXContext; + UCHAR BulkOutPipeId = 0; + purbb_t pUrb; + + + pUrb = (purbb_t)data; + pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; + pAd = pHTTXContext->pAd; + + rtusb_dataout_complete((unsigned long)pUrb); + + if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + // do nothing and return directly. + } + else + { + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) + { + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); + } + else + { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; + if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && + /* ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ + (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && + (pHTTXContext->bCurWriting == FALSE)) + { + RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); + } + + RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL); + RTUSBKickBulkOut(pAd); + } + } + + + return; + +} + + +NDIS_STATUS RtmpNetTaskInit( + IN RTMP_ADAPTER *pAd) +{ + POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + + // Create receive tasklet + tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd); + tasklet_init(&pObj->mgmt_dma_done_task, rtusb_mgmt_dma_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->ac0_dma_done_task, rtusb_ac0_dma_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->ac1_dma_done_task, rtusb_ac1_dma_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->ac2_dma_done_task, rtusb_ac2_dma_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->ac3_dma_done_task, rtusb_ac3_dma_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->null_frame_complete_task, rtusb_null_frame_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->rts_frame_complete_task, rtusb_rts_frame_done_tasklet, (unsigned long)pAd); + tasklet_init(&pObj->pspoll_frame_complete_task, rtusb_pspoll_frame_done_tasklet, (unsigned long)pAd); + + return NDIS_STATUS_SUCCESS; +} + + +void RtmpNetTaskExit(IN RTMP_ADAPTER *pAd) +{ + POS_COOKIE pObj; + + pObj = (POS_COOKIE) pAd->OS_Cookie; + + tasklet_kill(&pObj->rx_done_task); + tasklet_kill(&pObj->mgmt_dma_done_task); + tasklet_kill(&pObj->ac0_dma_done_task); + tasklet_kill(&pObj->ac1_dma_done_task); + tasklet_kill(&pObj->ac2_dma_done_task); + tasklet_kill(&pObj->ac3_dma_done_task); + tasklet_kill(&pObj->tbtt_task); + tasklet_kill(&pObj->null_frame_complete_task); + tasklet_kill(&pObj->rts_frame_complete_task); + tasklet_kill(&pObj->pspoll_frame_complete_task); +} Index: b/drivers/staging/rt2860/rtmp.h =================================================================== --- a/drivers/staging/rt2860/rtmp.h +++ b/drivers/staging/rt2860/rtmp.h @@ -42,140 +42,50 @@ #include "spectrum_def.h" -#include "aironet.h" +#include "rtmp_dot11.h" -#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++) -#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--) -#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt) +#ifdef MLME_EX +#include "mlme_ex_def.h" +#endif // MLME_EX // -#ifdef RT2870 -//////////////////////////////////////////////////////////////////////////// -// The TX_BUFFER structure forms the transmitted USB packet to the device -//////////////////////////////////////////////////////////////////////////// -typedef struct __TX_BUFFER{ - union { - UCHAR WirelessPacket[TX_BUFFER_NORMSIZE]; - HEADER_802_11 NullFrame; - PSPOLL_FRAME PsPollPacket; - RTS_FRAME RTSFrame; - }field; - UCHAR Aggregation[4]; //Buffer for save Aggregation size. -} TX_BUFFER, *PTX_BUFFER; - -typedef struct __HTTX_BUFFER{ - union { - UCHAR WirelessPacket[MAX_TXBULK_SIZE]; - HEADER_802_11 NullFrame; - PSPOLL_FRAME PsPollPacket; - RTS_FRAME RTSFrame; - }field; - UCHAR Aggregation[4]; //Buffer for save Aggregation size. -} HTTX_BUFFER, *PHTTX_BUFFER; +#undef AP_WSC_INCLUDED +#undef STA_WSC_INCLUDED +#undef WSC_INCLUDED -// used to track driver-generated write irps -typedef struct _TX_CONTEXT -{ - PVOID pAd; //Initialized in MiniportInitialize - PURB pUrb; //Initialized in MiniportInitialize - PIRP pIrp; //used to cancel pending bulk out. - //Initialized in MiniportInitialize - PTX_BUFFER TransferBuffer; //Initialized in MiniportInitialize - ULONG BulkOutSize; - UCHAR BulkOutPipeId; - UCHAR SelfIdx; - BOOLEAN InUse; - BOOLEAN bWaitingBulkOut; // at least one packet is in this TxContext, ready for making IRP anytime. - BOOLEAN bFullForBulkOut; // all tx buffer are full , so waiting for tx bulkout. - BOOLEAN IRPPending; - BOOLEAN LastOne; - BOOLEAN bAggregatible; - UCHAR Header_802_3[LENGTH_802_3]; - UCHAR Rsv[2]; - ULONG DataOffset; - UINT TxRate; - dma_addr_t data_dma; // urb dma on linux -} TX_CONTEXT, *PTX_CONTEXT, **PPTX_CONTEXT; +#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED) +#define WSC_INCLUDED +#endif -// used to track driver-generated write irps -typedef struct _HT_TX_CONTEXT -{ - PVOID pAd; //Initialized in MiniportInitialize - PURB pUrb; //Initialized in MiniportInitialize - PIRP pIrp; //used to cancel pending bulk out. - //Initialized in MiniportInitialize - PHTTX_BUFFER TransferBuffer; //Initialized in MiniportInitialize - ULONG BulkOutSize; // Indicate the total bulk-out size in bytes in one bulk-transmission - UCHAR BulkOutPipeId; - BOOLEAN IRPPending; - BOOLEAN LastOne; - BOOLEAN bCurWriting; - BOOLEAN bRingEmpty; - BOOLEAN bCopySavePad; - UCHAR SavedPad[8]; - UCHAR Header_802_3[LENGTH_802_3]; - ULONG CurWritePosition; // Indicate the buffer offset which packet will be inserted start from. - ULONG CurWriteRealPos; // Indicate the buffer offset which packet now are writing to. - ULONG NextBulkOutPosition; // Indicate the buffer start offset of a bulk-transmission - ULONG ENextBulkOutPosition; // Indicate the buffer end offset of a bulk-transmission - UINT TxRate; - dma_addr_t data_dma; // urb dma on linux -} HT_TX_CONTEXT, *PHT_TX_CONTEXT, **PPHT_TX_CONTEXT; +#include "rtmp_chip.h" -// -// Structure to keep track of receive packets and buffers to indicate -// receive data to the protocol. -// -typedef struct _RX_CONTEXT -{ - PUCHAR TransferBuffer; - PVOID pAd; - PIRP pIrp;//used to cancel pending bulk in. - PURB pUrb; - //These 2 Boolean shouldn't both be 1 at the same time. - ULONG BulkInOffset; // number of packets waiting for reordering . - BOOLEAN bRxHandling; // Notify this packet is being process now. - BOOLEAN InUse; // USB Hardware Occupied. Wait for USB HW to put packet. - BOOLEAN Readable; // Receive Complete back. OK for driver to indicate receiving packet. - BOOLEAN IRPPending; // TODO: To be removed - atomic_t IrpLock; - NDIS_SPIN_LOCK RxContextLock; - dma_addr_t data_dma; // urb dma on linux -} RX_CONTEXT, *PRX_CONTEXT; -#endif // RT2870 // +typedef struct _RTMP_ADAPTER RTMP_ADAPTER; +typedef struct _RTMP_ADAPTER *PRTMP_ADAPTER; -// -// NDIS Version definitions -// -#ifdef NDIS50_MINIPORT -#define RTMP_NDIS_MAJOR_VERSION 5 -#define RTMP_NDIS_MINOR_VERSION 0 -#endif +typedef struct _RTMP_CHIP_OP_ RTMP_CHIP_OP; -#ifdef NDIS51_MINIPORT -#define RTMP_NDIS_MAJOR_VERSION 5 -#define RTMP_NDIS_MINOR_VERSION 1 -#endif -extern char NIC_VENDOR_DESC[]; -extern int NIC_VENDOR_DESC_LEN; +//#define DBG 1 + +//#define DBG_DIAGNOSE 1 + + +//+++Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function +#define MAX_DATAMM_RETRY 3 +#define MGMT_USE_QUEUE_FLAG 0x80 +//---Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function + +#define MAXSEQ (0xFFF) extern unsigned char SNAP_AIRONET[]; -extern unsigned char CipherSuiteCiscoCCKM[]; -extern unsigned char CipherSuiteCiscoCCKMLen; -extern unsigned char CipherSuiteCiscoCCKM24[]; -extern unsigned char CipherSuiteCiscoCCKM24Len; -extern unsigned char CipherSuiteCCXTkip[]; -extern unsigned char CipherSuiteCCXTkipLen; extern unsigned char CISCO_OUI[]; extern UCHAR BaSizeArray[4]; extern UCHAR BROADCAST_ADDR[MAC_ADDR_LEN]; -extern UCHAR MULTICAST_ADDR[MAC_ADDR_LEN]; extern UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN]; extern ULONG BIT32[32]; extern UCHAR BIT8[8]; @@ -231,9 +141,11 @@ extern UCHAR WpaIe; extern UCHAR Wpa2Ie; extern UCHAR IbssIe; extern UCHAR Ccx2Ie; +extern UCHAR WapiIe; extern UCHAR WPA_OUI[]; extern UCHAR RSN_OUI[]; +extern UCHAR WAPI_OUI[]; extern UCHAR WME_INFO_ELEM[]; extern UCHAR WME_PARM_ELEM[]; extern UCHAR Ccx2QosInfo[]; @@ -256,28 +168,8 @@ extern UCHAR RateSwitchTable11N2SForABa extern UCHAR PRE_N_HT_OUI[]; -#define MAXSEQ (0xFFF) - -struct reordering_mpdu -{ - struct reordering_mpdu *next; - PNDIS_PACKET pPacket; /* coverted to 802.3 frame */ - int Sequence; /* sequence number of MPDU */ - BOOLEAN bAMSDU; -}; -struct reordering_list -{ - struct reordering_mpdu *next; - int qlen; -}; -struct reordering_mpdu_pool -{ - PVOID mem; - NDIS_SPIN_LOCK lock; - struct reordering_list freelist; -}; typedef struct _RSSI_SAMPLE { CHAR LastRssi0; // last received RSSI @@ -318,6 +210,7 @@ typedef struct _QUEUE_HEADER { if ((QueueHeader)->Head != NULL) \ { \ pNext = (QueueHeader)->Head->Next; \ + (QueueHeader)->Head->Next = NULL; \ (QueueHeader)->Head = pNext; \ if (pNext == NULL) \ (QueueHeader)->Tail = NULL; \ @@ -345,6 +238,19 @@ typedef struct _QUEUE_HEADER { (QueueHeader)->Number++; \ } +#define InsertTailQueueAc(pAd, pEntry, QueueHeader, QueueEntry) \ +{ \ + ((PQUEUE_ENTRY)QueueEntry)->Next = NULL; \ + if ((QueueHeader)->Tail) \ + (QueueHeader)->Tail->Next = (PQUEUE_ENTRY)(QueueEntry); \ + else \ + (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \ + (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \ + (QueueHeader)->Number++; \ +} + + + // // Macros for flag and ref count operations // @@ -353,15 +259,12 @@ typedef struct _QUEUE_HEADER { #define RTMP_CLEAR_FLAGS(_M) ((_M)->Flags = 0) #define RTMP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0) #define RTMP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F)) - -#ifdef RT2860 // Macro for power save flag. #define RTMP_SET_PSFLAG(_M, _F) ((_M)->PSFlags |= (_F)) #define RTMP_CLEAR_PSFLAG(_M, _F) ((_M)->PSFlags &= ~(_F)) #define RTMP_CLEAR_PSFLAGS(_M) ((_M)->PSFlags = 0) #define RTMP_TEST_PSFLAG(_M, _F) (((_M)->PSFlags & (_F)) != 0) #define RTMP_TEST_PSFLAGS(_M, _F) (((_M)->PSFlags & (_F)) == (_F)) -#endif #define OPSTATUS_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags |= (_F)) #define OPSTATUS_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F)) @@ -391,51 +294,6 @@ typedef struct _QUEUE_HEADER { (_idx) = (_idx+1) % (_RingSize); \ } -#ifdef RT2870 -// We will have a cost down version which mac version is 0x3090xxxx -#define IS_RT3090(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (((_pAd)->MACVersion & 0xffff0000) == 0x30900000)) -#else -#define IS_RT3090(_pAd) 0 -#endif -#define IS_RT3070(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30700000) -#ifdef RT2870 -#define IS_RT3071(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30710000) -#define IS_RT30xx(_pAd) (((_pAd)->MACVersion & 0xfff00000) == 0x30700000) -#endif - -#define RING_PACKET_INIT(_TxRing, _idx) \ -{ \ - _TxRing->Cell[_idx].pNdisPacket = NULL; \ - _TxRing->Cell[_idx].pNextNdisPacket = NULL; \ -} - -#define TXDT_INIT(_TxD) \ -{ \ - NdisZeroMemory(_TxD, TXD_SIZE); \ - _TxD->DMADONE = 1; \ -} - -//Set last data segment -#define RING_SET_LASTDS(_TxD, _IsSD0) \ -{ \ - if (_IsSD0) {_TxD->LastSec0 = 1;} \ - else {_TxD->LastSec1 = 1;} \ -} - -// Increase TxTsc value for next transmission -// TODO: -// When i==6, means TSC has done one full cycle, do re-keying stuff follow specs -// Should send a special event microsoft defined to request re-key -#define INC_TX_TSC(_tsc) \ -{ \ - int i=0; \ - while (++_tsc[i] == 0x0) \ - { \ - i++; \ - if (i == 6) \ - break; \ - } \ -} // StaActive.SupportedHtPhy.MCSSet is copied from AP beacon. Don't need to update here. #define COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \ @@ -475,301 +333,12 @@ typedef struct _QUEUE_HEADER { // ULONG Value) // -// -// BBP & RF are using indirect access. Before write any value into it. -// We have to make sure there is no outstanding command pending via checking busy bit. -// -#define MAX_BUSY_COUNT 100 // Number of retry before failing access BBP & RF indirect register -// -#ifdef RT2860 -#define RTMP_RF_IO_WRITE32(_A, _V) \ -{ \ - PHY_CSR4_STRUC Value; \ - ULONG BusyCnt = 0; \ - if ((_A)->bPCIclkOff) \ - { \ - return; \ - } \ - do { \ - RTMP_IO_READ32(_A, RF_CSR_CFG0, &Value.word); \ - if (Value.field.Busy == IDLE) \ - break; \ - BusyCnt++; \ - } while (BusyCnt < MAX_BUSY_COUNT); \ - if (BusyCnt < MAX_BUSY_COUNT) \ - { \ - RTMP_IO_WRITE32(_A, RF_CSR_CFG0, _V); \ - } \ -} - -#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \ -{ \ - BBP_CSR_CFG_STRUC BbpCsr; \ - int i, k; \ - for (i=0; iBbpWriteLatch[_I]; \ - } \ -} - -//#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) {} -// Read BBP register by register's ID. Generate PER to test BA -#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \ -{ \ - BBP_CSR_CFG_STRUC BbpCsr; \ - int i, k; \ - if ((_A)->bPCIclkOff == FALSE) \ - { \ - for (i=0; iBbpWriteLatch[_I]; \ - RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ - BbpCsr.field.Busy = 0; \ - RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ - } \ - } \ -} - -#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \ -{ \ - BBP_CSR_CFG_STRUC BbpCsr; \ - int BusyCnt; \ - for (BusyCnt=0; BusyCntBbpWriteLatch[_I] = _V; \ - break; \ - } \ - if (BusyCnt == MAX_BUSY_COUNT) \ - { \ - DBGPRINT_ERR(("BBP write R%d fail\n", _I)); \ - } \ -} - -// Write BBP register by register's ID & value -#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) \ -{ \ - BBP_CSR_CFG_STRUC BbpCsr; \ - int BusyCnt; \ - if ((_A)->bPCIclkOff == FALSE) \ - { \ - for (BusyCnt=0; BusyCntOpMode == OPMODE_AP) \ - RTMPusecDelay(1000); \ - (_A)->BbpWriteLatch[_I] = _V; \ - break; \ - } \ - if (BusyCnt == MAX_BUSY_COUNT) \ - { \ - DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", _I, BbpCsr.word)); \ - RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \ - BbpCsr.field.Busy = 0; \ - RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \ - } \ - } \ -} -#endif /* RT2860 */ -#ifdef RT2870 -#define RTMP_RF_IO_WRITE32(_A, _V) RTUSBWriteRFRegister(_A, _V) -#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV) -#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V) - -#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V) -#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV) -#endif // RT2870 // - -#define MAP_CHANNEL_ID_TO_KHZ(ch, khz) { \ - switch (ch) \ - { \ - case 1: khz = 2412000; break; \ - case 2: khz = 2417000; break; \ - case 3: khz = 2422000; break; \ - case 4: khz = 2427000; break; \ - case 5: khz = 2432000; break; \ - case 6: khz = 2437000; break; \ - case 7: khz = 2442000; break; \ - case 8: khz = 2447000; break; \ - case 9: khz = 2452000; break; \ - case 10: khz = 2457000; break; \ - case 11: khz = 2462000; break; \ - case 12: khz = 2467000; break; \ - case 13: khz = 2472000; break; \ - case 14: khz = 2484000; break; \ - case 36: /* UNII */ khz = 5180000; break; \ - case 40: /* UNII */ khz = 5200000; break; \ - case 44: /* UNII */ khz = 5220000; break; \ - case 48: /* UNII */ khz = 5240000; break; \ - case 52: /* UNII */ khz = 5260000; break; \ - case 56: /* UNII */ khz = 5280000; break; \ - case 60: /* UNII */ khz = 5300000; break; \ - case 64: /* UNII */ khz = 5320000; break; \ - case 149: /* UNII */ khz = 5745000; break; \ - case 153: /* UNII */ khz = 5765000; break; \ - case 157: /* UNII */ khz = 5785000; break; \ - case 161: /* UNII */ khz = 5805000; break; \ - case 165: /* UNII */ khz = 5825000; break; \ - case 100: /* HiperLAN2 */ khz = 5500000; break; \ - case 104: /* HiperLAN2 */ khz = 5520000; break; \ - case 108: /* HiperLAN2 */ khz = 5540000; break; \ - case 112: /* HiperLAN2 */ khz = 5560000; break; \ - case 116: /* HiperLAN2 */ khz = 5580000; break; \ - case 120: /* HiperLAN2 */ khz = 5600000; break; \ - case 124: /* HiperLAN2 */ khz = 5620000; break; \ - case 128: /* HiperLAN2 */ khz = 5640000; break; \ - case 132: /* HiperLAN2 */ khz = 5660000; break; \ - case 136: /* HiperLAN2 */ khz = 5680000; break; \ - case 140: /* HiperLAN2 */ khz = 5700000; break; \ - case 34: /* Japan MMAC */ khz = 5170000; break; \ - case 38: /* Japan MMAC */ khz = 5190000; break; \ - case 42: /* Japan MMAC */ khz = 5210000; break; \ - case 46: /* Japan MMAC */ khz = 5230000; break; \ - case 184: /* Japan */ khz = 4920000; break; \ - case 188: /* Japan */ khz = 4940000; break; \ - case 192: /* Japan */ khz = 4960000; break; \ - case 196: /* Japan */ khz = 4980000; break; \ - case 208: /* Japan, means J08 */ khz = 5040000; break; \ - case 212: /* Japan, means J12 */ khz = 5060000; break; \ - case 216: /* Japan, means J16 */ khz = 5080000; break; \ - default: khz = 2412000; break; \ - } \ - } - -#define MAP_KHZ_TO_CHANNEL_ID(khz, ch) { \ - switch (khz) \ - { \ - case 2412000: ch = 1; break; \ - case 2417000: ch = 2; break; \ - case 2422000: ch = 3; break; \ - case 2427000: ch = 4; break; \ - case 2432000: ch = 5; break; \ - case 2437000: ch = 6; break; \ - case 2442000: ch = 7; break; \ - case 2447000: ch = 8; break; \ - case 2452000: ch = 9; break; \ - case 2457000: ch = 10; break; \ - case 2462000: ch = 11; break; \ - case 2467000: ch = 12; break; \ - case 2472000: ch = 13; break; \ - case 2484000: ch = 14; break; \ - case 5180000: ch = 36; /* UNII */ break; \ - case 5200000: ch = 40; /* UNII */ break; \ - case 5220000: ch = 44; /* UNII */ break; \ - case 5240000: ch = 48; /* UNII */ break; \ - case 5260000: ch = 52; /* UNII */ break; \ - case 5280000: ch = 56; /* UNII */ break; \ - case 5300000: ch = 60; /* UNII */ break; \ - case 5320000: ch = 64; /* UNII */ break; \ - case 5745000: ch = 149; /* UNII */ break; \ - case 5765000: ch = 153; /* UNII */ break; \ - case 5785000: ch = 157; /* UNII */ break; \ - case 5805000: ch = 161; /* UNII */ break; \ - case 5825000: ch = 165; /* UNII */ break; \ - case 5500000: ch = 100; /* HiperLAN2 */ break; \ - case 5520000: ch = 104; /* HiperLAN2 */ break; \ - case 5540000: ch = 108; /* HiperLAN2 */ break; \ - case 5560000: ch = 112; /* HiperLAN2 */ break; \ - case 5580000: ch = 116; /* HiperLAN2 */ break; \ - case 5600000: ch = 120; /* HiperLAN2 */ break; \ - case 5620000: ch = 124; /* HiperLAN2 */ break; \ - case 5640000: ch = 128; /* HiperLAN2 */ break; \ - case 5660000: ch = 132; /* HiperLAN2 */ break; \ - case 5680000: ch = 136; /* HiperLAN2 */ break; \ - case 5700000: ch = 140; /* HiperLAN2 */ break; \ - case 5170000: ch = 34; /* Japan MMAC */ break; \ - case 5190000: ch = 38; /* Japan MMAC */ break; \ - case 5210000: ch = 42; /* Japan MMAC */ break; \ - case 5230000: ch = 46; /* Japan MMAC */ break; \ - case 4920000: ch = 184; /* Japan */ break; \ - case 4940000: ch = 188; /* Japan */ break; \ - case 4960000: ch = 192; /* Japan */ break; \ - case 4980000: ch = 196; /* Japan */ break; \ - case 5040000: ch = 208; /* Japan, means J08 */ break; \ - case 5060000: ch = 212; /* Japan, means J12 */ break; \ - case 5080000: ch = 216; /* Japan, means J16 */ break; \ - default: ch = 1; break; \ - } \ - } // // Common fragment list structure - Identical to the scatter gather frag list structure // +//#define RTMP_SCATTER_GATHER_ELEMENT SCATTER_GATHER_ELEMENT +//#define PRTMP_SCATTER_GATHER_ELEMENT PSCATTER_GATHER_ELEMENT #define NIC_MAX_PHYS_BUF_COUNT 8 typedef struct _RTMP_SCATTER_GATHER_ELEMENT { @@ -893,18 +462,11 @@ typedef struct _RTMP_SCATTER_GATHER_LIST } \ } -#define SWITCH_AB( _pAA, _pBB) \ -{ \ - PVOID pCC; \ - pCC = _pBB; \ - _pBB = _pAA; \ - _pAA = pCC; \ -} // Enqueue this frame to MLME engine // We need to enqueue the whole frame because MLME need to pass data type // information from 802.11 header -#ifdef RT2860 +#ifdef RTMP_MAC_PCI #define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal) \ { \ UINT32 High32TSF, Low32TSF; \ @@ -912,49 +474,14 @@ typedef struct _RTMP_SCATTER_GATHER_LIST RTMP_IO_READ32(_pAd, TSF_TIMER_DW0, &Low32TSF); \ MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal); \ } -#endif -#ifdef RT2870 +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB #define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal) \ { \ UINT32 High32TSF=0, Low32TSF=0; \ MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal); \ } -#endif // RT2870 // - -//Need to collect each ant's rssi concurrently -//rssi1 is report to pair2 Ant and rss2 is reprot to pair1 Ant when 4 Ant -#define COLLECT_RX_ANTENNA_AVERAGE_RSSI(_pAd, _rssi1, _rssi2) \ -{ \ - SHORT AvgRssi; \ - UCHAR UsedAnt; \ - if (_pAd->RxAnt.EvaluatePeriod == 0) \ - { \ - UsedAnt = _pAd->RxAnt.Pair1PrimaryRxAnt; \ - AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \ - if (AvgRssi < 0) \ - AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \ - else \ - AvgRssi = _rssi1 << 3; \ - _pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \ - } \ - else \ - { \ - UsedAnt = _pAd->RxAnt.Pair1SecondaryRxAnt; \ - AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \ - if ((AvgRssi < 0) && (_pAd->RxAnt.FirstPktArrivedWhenEvaluate)) \ - AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \ - else \ - { \ - _pAd->RxAnt.FirstPktArrivedWhenEvaluate = TRUE; \ - AvgRssi = _rssi1 << 3; \ - } \ - _pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \ - _pAd->RxAnt.RcvPktNumWhenEvaluate++; \ - } \ -} - -#define NDIS_QUERY_BUFFER(_NdisBuf, _ppVA, _pBufLen) \ - NdisQueryBuffer(_NdisBuf, _ppVA, _pBufLen) +#endif // RTMP_MAC_USB // #define MAC_ADDR_EQUAL(pAddr1,pAddr2) RTMPEqualMemory((PVOID)(pAddr1), (PVOID)(pAddr2), MAC_ADDR_LEN) #define SSID_EQUAL(ssid1, len1, ssid2, len2) ((len1==len2) && (RTMPEqualMemory(ssid1, ssid2, len1))) @@ -964,59 +491,21 @@ typedef struct _RTMP_SCATTER_GATHER_LIST // #define JapanChannelCheck(channel) ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64)) -#ifdef RT2860 +#define STA_EXTRA_SETTING(_pAd) + #define STA_PORT_SECURED(_pAd) \ { \ - _pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \ - RTMP_SET_PSFLAG(_pAd, fRTMP_PS_CAN_GO_SLEEP); \ - NdisAcquireSpinLock(&(_pAd)->MacTabLock); \ - _pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \ + BOOLEAN Cancelled; \ + (_pAd)->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \ + NdisAcquireSpinLock(&((_pAd)->MacTabLock)); \ + (_pAd)->MacTab.Content[BSSID_WCID].PortSecured = (_pAd)->StaCfg.PortSecured; \ + (_pAd)->MacTab.Content[BSSID_WCID].PrivacyFilter = Ndis802_11PrivFilterAcceptAll;\ NdisReleaseSpinLock(&(_pAd)->MacTabLock); \ + RTMPCancelTimer(&((_pAd)->Mlme.LinkDownTimer), &Cancelled);\ + STA_EXTRA_SETTING(_pAd); \ } -#endif -#ifdef RT2870 -#define STA_PORT_SECURED(_pAd) \ -{ \ - _pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \ - NdisAcquireSpinLock(&_pAd->MacTabLock); \ - _pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \ - NdisReleaseSpinLock(&_pAd->MacTabLock); \ -} -#endif - -// -// Register set pair for initialzation register set definition -// -typedef struct _RTMP_REG_PAIR -{ - ULONG Register; - ULONG Value; -} RTMP_REG_PAIR, *PRTMP_REG_PAIR; -typedef struct _REG_PAIR -{ - UCHAR Register; - UCHAR Value; -} REG_PAIR, *PREG_PAIR; -// -// Register set pair for initialzation register set definition -// -typedef struct _RTMP_RF_REGS -{ - UCHAR Channel; - ULONG R1; - ULONG R2; - ULONG R3; - ULONG R4; -} RTMP_RF_REGS, *PRTMP_RF_REGS; - -typedef struct _FREQUENCY_ITEM { - UCHAR Channel; - UCHAR N; - UCHAR R; - UCHAR K; -} FREQUENCY_ITEM, *PFREQUENCY_ITEM; // // Data buffer for DMA operation, the buffer must be contiguous physical memory @@ -1030,35 +519,6 @@ typedef struct _RTMP_DMABUF } RTMP_DMABUF, *PRTMP_DMABUF; -typedef union _HEADER_802_11_SEQ{ - struct { - USHORT Frag:4; - USHORT Sequence:12; - } field; - USHORT value; -} HEADER_802_11_SEQ, *PHEADER_802_11_SEQ; - -// -// Data buffer for DMA operation, the buffer must be contiguous physical memory -// Both DMA to / from CPU use the same structure. -// -typedef struct _RTMP_REORDERBUF -{ - BOOLEAN IsFull; - PVOID AllocVa; // TxBuf virtual address - UCHAR Header802_3[14]; - HEADER_802_11_SEQ Sequence; //support compressed bitmap BA, so no consider fragment in BA - UCHAR DataOffset; - USHORT Datasize; - ULONG AllocSize; -#ifdef RT2860 - NDIS_PHYSICAL_ADDRESS AllocPa; // TxBuf physical address -#endif -#ifdef RT2870 - PUCHAR AllocPa; -#endif // RT2870 // -} RTMP_REORDERBUF, *PRTMP_REORDERBUF; - // // Control block (Descriptor) for all ring descriptor DMA operation, buffer must be // contiguous physical memory. NDIS_PACKET stored the binding Rx packet descriptor @@ -1078,21 +538,7 @@ typedef struct _RTMP_DMACB RTMP_DMABUF DmaBuf; // Associated DMA buffer structure } RTMP_DMACB, *PRTMP_DMACB; -typedef struct _RTMP_TX_BUF -{ - PQUEUE_ENTRY Next; - UCHAR Index; - ULONG AllocSize; // Control block size - PVOID AllocVa; // Control block virtual address - NDIS_PHYSICAL_ADDRESS AllocPa; // Control block physical address -} RTMP_TXBUF, *PRTMP_TXBUF; -typedef struct _RTMP_RX_BUF -{ - BOOLEAN InUse; - ULONG ByBaRecIndex; - RTMP_REORDERBUF MAP_RXBuf[MAX_RX_REORDERBUF]; -} RTMP_RXBUF, *PRTMP_RXBUF; typedef struct _RTMP_TX_RING { RTMP_DMACB Cell[TX_RING_SIZE]; @@ -1155,9 +601,6 @@ typedef struct _COUNTER_802_11 { typedef struct _COUNTER_RALINK { ULONG TransmittedByteCount; // both successful and failure, used to calculate TX throughput -#ifdef RT2860 - ULONG LastReceivedByteCount; -#endif ULONG ReceivedByteCount; // both CRC okay and CRC error, used to calculate RX throughput ULONG BeenDisassociatedCount; ULONG BadCQIAutoRecoveryCount; @@ -1177,13 +620,10 @@ typedef struct _COUNTER_RALINK { ULONG OneSecRxCount; UINT32 OneSecTxAggregationCount; UINT32 OneSecRxAggregationCount; - + UINT32 OneSecReceivedByteCount; UINT32 OneSecFrameDuplicateCount; -#ifdef RT2870 - ULONG OneSecTransmittedByteCount; // both successful and failure, used to calculate TX throughput -#endif // RT2870 // - + UINT32 OneSecTransmittedByteCount; // both successful and failure, used to calculate TX throughput UINT32 OneSecTxNoRetryOkCount; UINT32 OneSecTxRetryOkCount; UINT32 OneSecTxFailCount; @@ -1224,12 +664,6 @@ typedef struct _COUNTER_RALINK { LARGE_INTEGER MPDUInReceivedAMPDUCount; } COUNTER_RALINK, *PCOUNTER_RALINK; -typedef struct _PID_COUNTER { - ULONG TxAckRequiredCount; // CRC error - ULONG TxAggreCount; - ULONG TxSuccessCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount - ULONG LastSuccessRate; -} PID_COUNTER, *PPID_COUNTER; typedef struct _COUNTER_DRS { // to record the each TX rate's quality. 0 is best, the bigger the worse. @@ -1244,33 +678,12 @@ typedef struct _COUNTER_DRS { ULONG LastTxOkCount; } COUNTER_DRS, *PCOUNTER_DRS; -// -// Arcfour Structure Added by PaulWu -// -typedef struct _ARCFOUR -{ - UINT X; - UINT Y; - UCHAR STATE[256]; -} ARCFOURCONTEXT, *PARCFOURCONTEXT; -// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI too. just copy to TXWI. -typedef struct _RECEIVE_SETTING { - USHORT NumOfRX:2; // MIMO. WE HAVE 3R - USHORT Mode:2; //channel bandwidth 20MHz or 40 MHz - USHORT ShortGI:1; - USHORT STBC:2; //SPACE - USHORT rsv:3; - USHORT OFDM:1; - USHORT MIMO:1; - } RECEIVE_SETTING, *PRECEIVE_SETTING; - -// Shared key data structure -typedef struct _WEP_KEY { - UCHAR KeyLen; // Key length for each key, 0: entry is invalid - UCHAR Key[MAX_LEN_OF_KEY]; // right now we implement 4 keys, 128 bits max -} WEP_KEY, *PWEP_KEY; + +/*************************************************************************** + * security key related data structure + **************************************************************************/ typedef struct _CIPHER_KEY { UCHAR Key[16]; // right now we implement 4 keys, 128 bits max UCHAR RxMic[8]; // make alignment @@ -1284,42 +697,47 @@ typedef struct _CIPHER_KEY { UCHAR Type; // Indicate Pairwise/Group when reporting MIC error } CIPHER_KEY, *PCIPHER_KEY; -typedef struct _BBP_TUNING_STRUCT { - BOOLEAN Enable; - UCHAR FalseCcaCountUpperBound; // 100 per sec - UCHAR FalseCcaCountLowerBound; // 10 per sec - UCHAR R17LowerBound; // specified in E2PROM - UCHAR R17UpperBound; // 0x68 according to David Tung - UCHAR CurrentR17Value; -} BBP_TUNING, *PBBP_TUNING; -typedef struct _SOFT_RX_ANT_DIVERSITY_STRUCT { - UCHAR EvaluatePeriod; // 0:not evalute status, 1: evaluate status, 2: switching status -#ifdef RT2870 - UCHAR EvaluateStableCnt; -#endif - UCHAR Pair1PrimaryRxAnt; // 0:Ant-E1, 1:Ant-E2 - UCHAR Pair1SecondaryRxAnt; // 0:Ant-E1, 1:Ant-E2 - UCHAR Pair2PrimaryRxAnt; // 0:Ant-E3, 1:Ant-E4 - UCHAR Pair2SecondaryRxAnt; // 0:Ant-E3, 1:Ant-E4 - SHORT Pair1AvgRssi[2]; // AvgRssi[0]:E1, AvgRssi[1]:E2 - SHORT Pair2AvgRssi[2]; // AvgRssi[0]:E3, AvgRssi[1]:E4 - SHORT Pair1LastAvgRssi; // - SHORT Pair2LastAvgRssi; // - ULONG RcvPktNumWhenEvaluate; - BOOLEAN FirstPktArrivedWhenEvaluate; - RALINK_TIMER_STRUCT RxAntDiversityTimer; -} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY; +// structure to define WPA Group Key Rekey Interval +typedef struct PACKED _RT_802_11_WPA_REKEY { + ULONG ReKeyMethod; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based + ULONG ReKeyInterval; // time-based: seconds, packet-based: kilo-packets +} RT_WPA_REKEY,*PRT_WPA_REKEY, RT_802_11_WPA_REKEY, *PRT_802_11_WPA_REKEY; + +#ifdef RTMP_MAC_USB +/*************************************************************************** + * RTUSB I/O related data structure + **************************************************************************/ +typedef struct _RT_SET_ASIC_WCID { + ULONG WCID; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based + ULONG SetTid; // time-based: seconds, packet-based: kilo-packets + ULONG DeleteTid; // time-based: seconds, packet-based: kilo-packets + UCHAR Addr[MAC_ADDR_LEN]; // avoid in interrupt when write key +} RT_SET_ASIC_WCID,*PRT_SET_ASIC_WCID; + +typedef struct _RT_SET_ASIC_WCID_ATTRI { + ULONG WCID; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based + ULONG Cipher; // ASIC Cipher definition + UCHAR Addr[ETH_LENGTH_OF_ADDRESS]; +} RT_SET_ASIC_WCID_ATTRI,*PRT_SET_ASIC_WCID_ATTRI; -typedef struct _LEAP_AUTH_INFO { - BOOLEAN Enabled; //Ture: Enable LEAP Authentication - BOOLEAN CCKM; //Ture: Use Fast Reauthentication with CCKM - UCHAR Reserve[2]; - UCHAR UserName[256]; //LEAP, User name - ULONG UserNameLen; - UCHAR Password[256]; //LEAP, User Password - ULONG PasswordLen; -} LEAP_AUTH_INFO, *PLEAP_AUTH_INFO; +// for USB interface, avoid in interrupt when write key +typedef struct RT_ADD_PAIRWISE_KEY_ENTRY { + UCHAR MacAddr[6]; + USHORT MacTabMatchWCID; // ASIC + CIPHER_KEY CipherKey; +} RT_ADD_PAIRWISE_KEY_ENTRY,*PRT_ADD_PAIRWISE_KEY_ENTRY; + +// Cipher suite type for mixed mode group cipher, P802.11i-2004 +typedef enum _RT_802_11_CIPHER_SUITE_TYPE { + Cipher_Type_NONE, + Cipher_Type_WEP40, + Cipher_Type_TKIP, + Cipher_Type_RSVD, + Cipher_Type_CCMP, + Cipher_Type_WEP104 +} RT_802_11_CIPHER_SUITE_TYPE, *PRT_802_11_CIPHER_SUITE_TYPE; +#endif // RTMP_MAC_USB // typedef struct { UCHAR Addr[MAC_ADDR_LEN]; @@ -1335,25 +753,30 @@ typedef struct { ROGUEAP_ENTRY RogueApEntry[MAX_LEN_OF_BSS_TABLE]; } ROGUEAP_TABLE, *PROGUEAP_TABLE; -typedef struct { - BOOLEAN Enable; - UCHAR Delta; - BOOLEAN PlusSign; -} CCK_TX_POWER_CALIBRATE, *PCCK_TX_POWER_CALIBRATE; - // -// Receive Tuple Cache Format +// Cisco IAPP format // -typedef struct _TUPLE_CACHE { - BOOLEAN Valid; - UCHAR MacAddress[MAC_ADDR_LEN]; - USHORT Sequence; - USHORT Frag; -} TUPLE_CACHE, *PTUPLE_CACHE; +typedef struct _CISCO_IAPP_CONTENT_ +{ + USHORT Length; //IAPP Length + UCHAR MessageType; //IAPP type + UCHAR FunctionCode; //IAPP function type + UCHAR DestinaionMAC[MAC_ADDR_LEN]; + UCHAR SourceMAC[MAC_ADDR_LEN]; + USHORT Tag; //Tag(element IE) - Adjacent AP report + USHORT TagLength; //Length of element not including 4 byte header + UCHAR OUI[4]; //0x00, 0x40, 0x96, 0x00 + UCHAR PreviousAP[MAC_ADDR_LEN]; //MAC Address of access point + USHORT Channel; + USHORT SsidLen; + UCHAR Ssid[MAX_LEN_OF_SSID]; + USHORT Seconds; //Seconds that the client has been disassociated. +} CISCO_IAPP_CONTENT, *PCISCO_IAPP_CONTENT; -// -// Fragment Frame structure -// + +/* + * Fragment Frame structure + */ typedef struct _FRAGMENT_FRAME { PNDIS_PACKET pFragPacket; ULONG RxSize; @@ -1373,6 +796,18 @@ typedef struct _PACKET_INFO { PNDIS_BUFFER pFirstBuffer; // Pointer to first buffer descriptor } PACKET_INFO, *PPACKET_INFO; + +// +// Arcfour Structure Added by PaulWu +// +typedef struct _ARCFOUR +{ + UINT X; + UINT Y; + UCHAR STATE[256]; +} ARCFOURCONTEXT, *PARCFOURCONTEXT; + + // // Tkip Key structure which RC4 key & MIC calculation // @@ -1404,6 +839,10 @@ typedef struct __PRIVATE_STRUC { TKIP_KEY_INFO Rx; } PRIVATE_STRUC, *PPRIVATE_STRUC; + +/*************************************************************************** + * Channel and BBP related data structures + **************************************************************************/ // structure to tune BBP R66 (BBP TUNING) typedef struct _BBP_R66_TUNING { BOOLEAN bEnable; @@ -1433,12 +872,67 @@ typedef struct _CHANNEL_11J_TX_POWER { USHORT RemainingTimeForUse; //unit: sec } CHANNEL_11J_TX_POWER, *PCHANNEL_11J_TX_POWER; +typedef struct _SOFT_RX_ANT_DIVERSITY_STRUCT { + UCHAR EvaluatePeriod; // 0:not evalute status, 1: evaluate status, 2: switching status + UCHAR EvaluateStableCnt; + UCHAR Pair1PrimaryRxAnt; // 0:Ant-E1, 1:Ant-E2 + UCHAR Pair1SecondaryRxAnt; // 0:Ant-E1, 1:Ant-E2 + UCHAR Pair2PrimaryRxAnt; // 0:Ant-E3, 1:Ant-E4 + UCHAR Pair2SecondaryRxAnt; // 0:Ant-E3, 1:Ant-E4 + SHORT Pair1AvgRssi[2]; // AvgRssi[0]:E1, AvgRssi[1]:E2 + SHORT Pair2AvgRssi[2]; // AvgRssi[0]:E3, AvgRssi[1]:E4 + SHORT Pair1LastAvgRssi; // + SHORT Pair2LastAvgRssi; // + ULONG RcvPktNumWhenEvaluate; + BOOLEAN FirstPktArrivedWhenEvaluate; + RALINK_TIMER_STRUCT RxAntDiversityTimer; +} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY; + + +/*************************************************************************** + * structure for radar detection and channel switch + **************************************************************************/ +typedef struct _RADAR_DETECT_STRUCT { + //BOOLEAN IEEE80211H; // 0: disable, 1: enable IEEE802.11h + UCHAR CSCount; //Channel switch counter + UCHAR CSPeriod; //Channel switch period (beacon count) + UCHAR RDCount; //Radar detection counter + UCHAR RDMode; //Radar Detection mode + UCHAR RDDurRegion; //Radar detection duration region + UCHAR BBPR16; + UCHAR BBPR17; + UCHAR BBPR18; + UCHAR BBPR21; + UCHAR BBPR22; + UCHAR BBPR64; + ULONG InServiceMonitorCount; // unit: sec + UINT8 DfsSessionTime; +#ifdef DFS_FCC_BW40_FIX + CHAR DfsSessionFccOff; +#endif + BOOLEAN bFastDfs; + UINT8 ChMovingTime; + UINT8 LongPulseRadarTh; +#ifdef MERGE_ARCH_TEAM + CHAR AvgRssiReq; + ULONG DfsLowerLimit; + ULONG DfsUpperLimit; + UINT8 FixDfsLimit; + ULONG upperlimit; + ULONG lowerlimit; +#endif // MERGE_ARCH_TEAM // +} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT; + typedef enum _ABGBAND_STATE_ { UNKNOWN_BAND, BG_BAND, A_BAND, } ABGBAND_STATE; + +/*************************************************************************** + * structure for MLME state machine + **************************************************************************/ typedef struct _MLME_STRUCT { // STA state machines STATE_MACHINE CntlMachine; @@ -1448,17 +942,23 @@ typedef struct _MLME_STRUCT { STATE_MACHINE SyncMachine; STATE_MACHINE WpaPskMachine; STATE_MACHINE LeapMachine; - STATE_MACHINE AironetMachine; STATE_MACHINE_FUNC AssocFunc[ASSOC_FUNC_SIZE]; STATE_MACHINE_FUNC AuthFunc[AUTH_FUNC_SIZE]; STATE_MACHINE_FUNC AuthRspFunc[AUTH_RSP_FUNC_SIZE]; STATE_MACHINE_FUNC SyncFunc[SYNC_FUNC_SIZE]; - STATE_MACHINE_FUNC WpaPskFunc[WPA_PSK_FUNC_SIZE]; - STATE_MACHINE_FUNC AironetFunc[AIRONET_FUNC_SIZE]; STATE_MACHINE_FUNC ActFunc[ACT_FUNC_SIZE]; // Action STATE_MACHINE ActMachine; + + + + // common WPA state machine + STATE_MACHINE WpaMachine; + STATE_MACHINE_FUNC WpaFunc[WPA_FUNC_SIZE]; + + + ULONG ChannelQuality; // 0..100, Channel Quality Indication for Roaming ULONG Now32; // latch the value of NdisGetSystemUpTime() ULONG LastSendNULLpsmTime; @@ -1473,11 +973,11 @@ typedef struct _MLME_STRUCT { RALINK_TIMER_STRUCT APSDPeriodicTimer; RALINK_TIMER_STRUCT LinkDownTimer; RALINK_TIMER_STRUCT LinkUpTimer; -#ifdef RT2860 +#ifdef RTMP_MAC_PCI UCHAR bPsPollTimerRunning; RALINK_TIMER_STRUCT PsPollTimer; RALINK_TIMER_STRUCT RadioOnOffTimer; -#endif +#endif // RTMP_MAC_PCI // ULONG PeriodicRound; ULONG OneSecPeriodicRound; @@ -1486,41 +986,51 @@ typedef struct _MLME_STRUCT { BOOLEAN bEnableAutoAntennaCheck; RALINK_TIMER_STRUCT RxAntEvalTimer; -#ifdef RT2870 +#ifdef RT30xx UCHAR CaliBW40RfR24; UCHAR CaliBW20RfR24; -#endif // RT2870 // +#endif // RT30xx // + +#ifdef RTMP_MAC_USB + RALINK_TIMER_STRUCT AutoWakeupTimer; + BOOLEAN AutoWakeupTimerRunning; +#endif // RTMP_MAC_USB // } MLME_STRUCT, *PMLME_STRUCT; -// structure for radar detection and channel switch -typedef struct _RADAR_DETECT_STRUCT { - UCHAR CSCount; //Channel switch counter - UCHAR CSPeriod; //Channel switch period (beacon count) - UCHAR RDCount; //Radar detection counter - UCHAR RDMode; //Radar Detection mode - UCHAR RDDurRegion; //Radar detection duration region - UCHAR BBPR16; - UCHAR BBPR17; - UCHAR BBPR18; - UCHAR BBPR21; - UCHAR BBPR22; - UCHAR BBPR64; - ULONG InServiceMonitorCount; // unit: sec - UINT8 DfsSessionTime; - BOOLEAN bFastDfs; - UINT8 ChMovingTime; - UINT8 LongPulseRadarTh; -} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT; -typedef enum _REC_BLOCKACK_STATUS +/*************************************************************************** + * 802.11 N related data structures + **************************************************************************/ +struct reordering_mpdu { - Recipient_NONE=0, - Recipient_USED, - Recipient_HandleRes, - Recipient_Accept -} REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS; - -typedef enum _ORI_BLOCKACK_STATUS + struct reordering_mpdu *next; + PNDIS_PACKET pPacket; /* coverted to 802.3 frame */ + int Sequence; /* sequence number of MPDU */ + BOOLEAN bAMSDU; +}; + +struct reordering_list +{ + struct reordering_mpdu *next; + int qlen; +}; + +struct reordering_mpdu_pool +{ + PVOID mem; + NDIS_SPIN_LOCK lock; + struct reordering_list freelist; +}; + +typedef enum _REC_BLOCKACK_STATUS +{ + Recipient_NONE=0, + Recipient_USED, + Recipient_HandleRes, + Recipient_Accept +} REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS; + +typedef enum _ORI_BLOCKACK_STATUS { Originator_NONE=0, Originator_USED, @@ -1545,14 +1055,21 @@ typedef struct _BA_REC_ENTRY { UCHAR Wcid; UCHAR TID; UCHAR BAWinSize; // 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU. + //UCHAR NumOfRxPkt; + //UCHAR Curindidx; // the head in the RX reordering buffer USHORT LastIndSeq; +// USHORT LastIndSeqAtTimer; USHORT TimeOutValue; RALINK_TIMER_STRUCT RECBATimer; ULONG LastIndSeqAtTimer; ULONG nDropPacket; ULONG rcvSeq; REC_BLOCKACK_STATUS REC_BA_Status; +// UCHAR RxBufIdxUsed; + // corresponding virtual address for RX reordering packet storage. + //RTMP_REORDERDMABUF MAP_RXBuf[MAX_RX_REORDERBUF]; NDIS_SPIN_LOCK RxReRingLock; // Rx Ring spinlock +// struct _BA_REC_ENTRY *pNext; PVOID pAdapter; struct reordering_list list; } BA_REC_ENTRY, *PBA_REC_ENTRY; @@ -1561,6 +1078,7 @@ typedef struct _BA_REC_ENTRY { typedef struct { ULONG numAsRecipient; // I am recipient of numAsRecipient clients. These client are in the BARecEntry[] ULONG numAsOriginator; // I am originator of numAsOriginator clients. These clients are in the BAOriEntry[] + ULONG numDoneOriginator; // count Done Originator sessions BA_ORI_ENTRY BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE]; BA_REC_ENTRY BARecEntry[MAX_LEN_OF_BA_REC_TABLE]; } BA_TABLE, *PBA_TABLE; @@ -1607,6 +1125,29 @@ typedef union _BACAP_STRUC { UINT32 word; } BACAP_STRUC, *PBACAP_STRUC; + +typedef struct { + BOOLEAN IsRecipient; + UCHAR MACAddr[MAC_ADDR_LEN]; + UCHAR TID; + UCHAR nMSDU; + USHORT TimeOut; + BOOLEAN bAllTid; // If True, delete all TID for BA sessions with this MACaddr. +} OID_ADD_BA_ENTRY, *POID_ADD_BA_ENTRY; + + + +#define IS_HT_STA(_pMacEntry) \ + (_pMacEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX) + +#define IS_HT_RATE(_pMacEntry) \ + (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) + +#define PEER_IS_HT_RATE(_pMacEntry) \ + (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) + + + //This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second. (Details see MLMEPeriodic) typedef struct _IOT_STRUC { UCHAR Threshold[2]; @@ -1630,6 +1171,8 @@ typedef struct _IOT_STRUC { // This is the registry setting for 802.11n transmit setting. Used in advanced page. typedef union _REG_TRANSMIT_SETTING { struct { + //UINT32 PhyMode:4; + //UINT32 MCS:7; // MCS UINT32 rsv0:10; UINT32 TxBF:1; UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz @@ -1653,18 +1196,26 @@ typedef union _DESIRED_TRANSMIT_SETTING USHORT word; } DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING; -typedef struct { - BOOLEAN IsRecipient; - UCHAR MACAddr[MAC_ADDR_LEN]; - UCHAR TID; - UCHAR nMSDU; - USHORT TimeOut; - BOOLEAN bAllTid; // If True, delete all TID for BA sessions with this MACaddr. -} OID_ADD_BA_ENTRY, *POID_ADD_BA_ENTRY; +#ifdef RTMP_MAC_USB +/*************************************************************************** + * USB-based chip Beacon related data structures + **************************************************************************/ +#define BEACON_BITMAP_MASK 0xff +typedef struct _BEACON_SYNC_STRUCT_ +{ + UCHAR BeaconBuf[HW_BEACON_MAX_COUNT][HW_BEACON_OFFSET]; + UCHAR BeaconTxWI[HW_BEACON_MAX_COUNT][TXWI_SIZE]; + ULONG TimIELocationInBeacon[HW_BEACON_MAX_COUNT]; + ULONG CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT]; + BOOLEAN EnableBeacon; // trigger to enable beacon transmission. + UCHAR BeaconBitMap; // NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change. + UCHAR DtimBitOn; // NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change. +}BEACON_SYNC_STRUCT; +#endif // RTMP_MAC_USB // -// -// Multiple SSID structure -// +/*************************************************************************** + * Multiple SSID related data structures + **************************************************************************/ #define WLAN_MAX_NUM_OF_TIM ((MAX_LEN_OF_MAC_TABLE >> 3) + 1) /* /8 + 1 */ #define WLAN_CT_TIM_BCMC_OFFSET 0 /* unit: 32B */ @@ -1688,124 +1239,6 @@ typedef struct { UCHAR bit_offset = wcid & 0x7; \ ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] |= BIT8[bit_offset]; } -#ifdef RT2870 -#define BEACON_BITMAP_MASK 0xff -typedef struct _BEACON_SYNC_STRUCT_ -{ - UCHAR BeaconBuf[HW_BEACON_MAX_COUNT][HW_BEACON_OFFSET]; - UCHAR BeaconTxWI[HW_BEACON_MAX_COUNT][TXWI_SIZE]; - ULONG TimIELocationInBeacon[HW_BEACON_MAX_COUNT]; - ULONG CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT]; - BOOLEAN EnableBeacon; // trigger to enable beacon transmission. - UCHAR BeaconBitMap; // NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change. - UCHAR DtimBitOn; // NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change. -}BEACON_SYNC_STRUCT; -#endif // RT2870 // - -typedef struct _MULTISSID_STRUCT { - UCHAR Bssid[MAC_ADDR_LEN]; - UCHAR SsidLen; - CHAR Ssid[MAX_LEN_OF_SSID]; - USHORT CapabilityInfo; - - PNET_DEV MSSIDDev; - - NDIS_802_11_AUTHENTICATION_MODE AuthMode; - NDIS_802_11_WEP_STATUS WepStatus; - NDIS_802_11_WEP_STATUS GroupKeyWepStatus; - WPA_MIX_PAIR_CIPHER WpaMixPairCipher; - - ULONG TxCount; - ULONG RxCount; - ULONG ReceivedByteCount; - ULONG TransmittedByteCount; - ULONG RxErrorCount; - ULONG RxDropCount; - - HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI. - RT_HT_PHY_INFO DesiredHtPhyInfo; - DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting. this is for reading registry setting only. not useful. - BOOLEAN bAutoTxRateSwitch; - - UCHAR DefaultKeyId; - - UCHAR TxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11, ... - UCHAR DesiredRates[MAX_LEN_OF_SUPPORTED_RATES];// OID_802_11_DESIRED_RATES - UCHAR DesiredRatesIndex; - UCHAR MaxTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11 - - UCHAR TimBitmaps[WLAN_MAX_NUM_OF_TIM]; - - // WPA - UCHAR GMK[32]; - UCHAR PMK[32]; - UCHAR GTK[32]; - BOOLEAN IEEE8021X; - BOOLEAN PreAuth; - UCHAR GNonce[32]; - UCHAR PortSecured; - NDIS_802_11_PRIVACY_FILTER PrivacyFilter; - UCHAR BANClass3Data; - ULONG IsolateInterStaTraffic; - - UCHAR RSNIE_Len[2]; - UCHAR RSN_IE[2][MAX_LEN_OF_RSNIE]; - - - UCHAR TimIELocationInBeacon; - UCHAR CapabilityInfoLocationInBeacon; - // outgoing BEACON frame buffer and corresponding TXWI - // PTXWI_STRUC BeaconTxWI; // - CHAR BeaconBuf[MAX_BEACON_SIZE]; // NOTE: BeaconBuf should be 4-byte aligned - - BOOLEAN bHideSsid; - UINT16 StationKeepAliveTime; // unit: second - - USHORT VLAN_VID; - USHORT VLAN_Priority; - - RT_802_11_ACL AccessControlList; - - // EDCA Qos - BOOLEAN bWmmCapable; // 0:disable WMM, 1:enable WMM - BOOLEAN bDLSCapable; // 0:disable DLS, 1:enable DLS - - UCHAR DlsPTK[64]; // Due to windows dirver count on meetinghouse to handle 4-way shake - - // For 802.1x daemon setting per BSS - UCHAR radius_srv_num; - RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM]; - -#ifdef RTL865X_SOC - unsigned int mylinkid; -#endif - - - UINT32 RcvdConflictSsidCount; - UINT32 RcvdSpoofedAssocRespCount; - UINT32 RcvdSpoofedReassocRespCount; - UINT32 RcvdSpoofedProbeRespCount; - UINT32 RcvdSpoofedBeaconCount; - UINT32 RcvdSpoofedDisassocCount; - UINT32 RcvdSpoofedAuthCount; - UINT32 RcvdSpoofedDeauthCount; - UINT32 RcvdSpoofedUnknownMgmtCount; - UINT32 RcvdReplayAttackCount; - - CHAR RssiOfRcvdConflictSsid; - CHAR RssiOfRcvdSpoofedAssocResp; - CHAR RssiOfRcvdSpoofedReassocResp; - CHAR RssiOfRcvdSpoofedProbeResp; - CHAR RssiOfRcvdSpoofedBeacon; - CHAR RssiOfRcvdSpoofedDisassoc; - CHAR RssiOfRcvdSpoofedAuth; - CHAR RssiOfRcvdSpoofedDeauth; - CHAR RssiOfRcvdSpoofedUnknownMgmt; - CHAR RssiOfRcvdReplayAttack; - - BOOLEAN bBcnSntReq; - UCHAR BcnBufIdx; -} MULTISSID_STRUCT, *PMULTISSID_STRUCT; // configuration common to OPMODE_AP as well as OPMODE_STA typedef struct _COMMON_CONFIG { @@ -1818,6 +1251,7 @@ typedef struct _COMMON_CONFIG { UCHAR PhyMode; // PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED USHORT Dsifs; // in units of usec ULONG PacketFilter; // Packet filter for receiving + UINT8 RegulatoryClass; CHAR Ssid[MAX_LEN_OF_SSID]; // NOT NULL-terminated UCHAR SsidLen; // the actual ssid length in used @@ -1846,16 +1280,27 @@ typedef struct _COMMON_CONFIG { BOOLEAN bAPSDAC_BK; BOOLEAN bAPSDAC_VI; BOOLEAN bAPSDAC_VO; + + /* because TSPEC can modify the APSD flag, we need to keep the APSD flag + requested in association stage from the station; + we need to recover the APSD flag after the TSPEC is deleted. */ + BOOLEAN bACMAPSDBackup[4]; /* for delivery-enabled & trigger-enabled both */ + BOOLEAN bACMAPSDTr[4]; /* no use */ + BOOLEAN bNeedSendTriggerFrame; BOOLEAN bAPSDForcePowerSave; // Force power save mode, should only use in APSD-STAUT ULONG TriggerTimerCount; UCHAR MaxSPLength; UCHAR BBPCurrentBW; // BW_10, BW_20, BW_40 + // move to MULTISSID_STRUCT for MBSS + //HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI. REG_TRANSMIT_SETTING RegTransmitSetting; //registry transmit setting. this is for reading registry setting only. not useful. + //UCHAR FixedTxMode; // Fixed Tx Mode (CCK, OFDM), for HT fixed tx mode (GF, MIX) , refer to RegTransmitSetting.field.HTMode UCHAR TxRate; // Same value to fill in TXD. TxRate is 6-bit UCHAR MaxTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11 UCHAR TxRateIndex; // Tx rate index in RateSwitchTable UCHAR TxRateTableSize; // Valid Tx rate table size in RateSwitchTable + //BOOLEAN bAutoTxRateSwitch; UCHAR MinTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11 UCHAR RtsRate; // RATE_xxx HTTRANSMIT_SETTING MlmeTransmit; // MGMT frame PHY rate setting when operatin at Ht rate. @@ -1868,6 +1313,7 @@ typedef struct _COMMON_CONFIG { UCHAR TxPower; // in unit of mW ULONG TxPowerPercentage; // 0~100 % ULONG TxPowerDefault; // keep for TxPowerPercentage + UINT8 PwrConstraint; BACAP_STRUC BACapability; // NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0 BACAP_STRUC REGBACapability; // NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0 @@ -1877,7 +1323,7 @@ typedef struct _COMMON_CONFIG { BOOLEAN bUseZeroToDisableFragment; // Microsoft use 0 as disable ULONG UseBGProtection; // 0: auto, 1: always use, 2: always not use BOOLEAN bUseShortSlotTime; // 0: disable, 1 - use short slot (9us) - BOOLEAN bEnableTxBurst; // 1: enble TX PACKET BURST, 0: disable TX PACKET BURST + BOOLEAN bEnableTxBurst; // 1: enble TX PACKET BURST (when BA is established or AP is not a legacy WMM AP), 0: disable TX PACKET BURST BOOLEAN bAggregationCapable; // 1: enable TX aggregation when the peer supports it BOOLEAN bPiggyBackCapable; // 1: enable TX piggy-back according MAC's version BOOLEAN bIEEE80211H; // 1: enable IEEE802.11h spec. @@ -1899,6 +1345,9 @@ typedef struct _COMMON_CONFIG { BOOLEAN NdisRadioStateOff; //For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff. ABGBAND_STATE BandState; // For setting BBP used on B/G or A mode. +#ifdef ANT_DIVERSITY_SUPPORT + BOOLEAN bRxAntDiversity; // 0:disable, 1:enable Software Rx Antenna Diversity. +#endif // ANT_DIVERSITY_SUPPORT // // IEEE802.11H--DFS. RADAR_DETECT_STRUCT RadarDetect; @@ -1916,6 +1365,9 @@ typedef struct _COMMON_CONFIG { BOOLEAN bHTProtect; BOOLEAN bMIMOPSEnable; BOOLEAN bBADecline; +//2008/11/05: KH add to support Antenna power-saving of AP<-- + BOOLEAN bGreenAPEnable; +//2008/11/05: KH add to support Antenna power-saving of AP--> BOOLEAN bDisableReordering; BOOLEAN bForty_Mhz_Intolerant; BOOLEAN bExtChannelSwitchAnnouncement; @@ -1940,7 +1392,7 @@ typedef struct _COMMON_CONFIG { BOOLEAN bHardwareRadio; // Hardware controlled Radio enabled -#ifdef RT2870 +#ifdef RTMP_MAC_USB BOOLEAN bMultipleIRP; // Multiple Bulk IN flag UCHAR NumOfBulkInIRP; // if bMultipleIRP == TRUE, NumOfBulkInIRP will be 4 otherwise be 1 RT_HT_CAPABILITY SupportedHtPhy; @@ -1948,13 +1400,13 @@ typedef struct _COMMON_CONFIG { UCHAR TxBulkFactor; UCHAR RxBulkFactor; + BOOLEAN IsUpdateBeacon; BEACON_SYNC_STRUCT *pBeaconSync; RALINK_TIMER_STRUCT BeaconUpdateTimer; UINT32 BeaconAdjust; UINT32 BeaconFactor; UINT32 BeaconRemain; -#endif // RT2870 // - +#endif // RTMP_MAC_USB // NDIS_SPIN_LOCK MeasureReqTabLock; PMEASURE_REQ_TAB pMeasureReqTab; @@ -1966,8 +1418,20 @@ typedef struct _COMMON_CONFIG { #ifdef MCAST_RATE_SPECIFIC HTTRANSMIT_SETTING MCastPhyMode; #endif // MCAST_RATE_SPECIFIC // + + + + BOOLEAN PSPXlink; // 0: Disable. 1: Enable + +#if defined(RT305x)||defined(RT30xx) + // request by Gary, for High Power issue + UCHAR HighPowerPatchDisabled; +#endif + + BOOLEAN HT_DisallowTKIP; /* Restrict the encryption type in 11n HT mode */ } COMMON_CONFIG, *PCOMMON_CONFIG; + /* Modified by Wu Xi-Kun 4/21/2006 */ // STA configuration and status typedef struct _STA_ADMIN_CONFIG { @@ -2016,6 +1480,8 @@ typedef struct _STA_ADMIN_CONFIG { NDIS_802_11_WEP_STATUS GroupKeyWepStatus; + UCHAR WpaPassPhrase[64]; // WPA PSK pass phrase + UINT WpaPassPhraseLen; // the length of WPA PSK pass phrase UCHAR PMK[32]; // WPA PSK mode PMK UCHAR PTK[64]; // WPA PSK mode PTK UCHAR GTK[32]; // GTK from authenticator @@ -2055,11 +1521,7 @@ typedef struct _STA_ADMIN_CONFIG { BOOLEAN bRadio; // Radio state, And of Sw & Hw radio state BOOLEAN bHardwareRadio; // Hardware controlled Radio enabled BOOLEAN bShowHiddenSSID; // Show all known SSID in SSID list get operation -#ifdef RT2860 - BOOLEAN AdhocBOnlyJoined; // Indicate Adhoc B Join. - BOOLEAN AdhocBGJoined; // Indicate Adhoc B/G Join. - BOOLEAN Adhoc20NJoined; // Indicate Adhoc 20MHz N Join. -#endif + // New for WPA, windows want us to to keep association information and // Fixed IEs from last association response NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo; @@ -2071,43 +1533,9 @@ typedef struct _STA_ADMIN_CONFIG { UCHAR RSNIE_Len; UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; // The content saved here should be little-endian format. - // New variables used for CCX 1.0 - BOOLEAN bCkipOn; - BOOLEAN bCkipCmicOn; - UCHAR CkipFlag; - UCHAR GIV[3]; //for CCX iv - UCHAR RxSEQ[4]; - UCHAR TxSEQ[4]; - UCHAR CKIPMIC[4]; - UCHAR LeapAuthMode; - LEAP_AUTH_INFO LeapAuthInfo; - UCHAR HashPwd[16]; - UCHAR NetworkChallenge[8]; - UCHAR NetworkChallengeResponse[24]; - UCHAR PeerChallenge[8]; - - UCHAR PeerChallengeResponse[24]; - UCHAR SessionKey[16]; //Network session keys (NSK) - RALINK_TIMER_STRUCT LeapAuthTimer; - ROGUEAP_TABLE RogueApTab; //Cisco CCX1 Rogue AP Detection - - // New control flags for CCX - CCX_CONTROL CCXControl; // Master administration state - BOOLEAN CCXEnable; // Actual CCX state - UCHAR CCXScanChannel; // Selected channel for CCX beacon request - USHORT CCXScanTime; // Time out to wait for beacon and probe response - UCHAR CCXReqType; // Current processing CCX request type - BSS_TABLE CCXBssTab; // BSS Table - UCHAR FrameReportBuf[2048]; // Buffer for creating frame report - USHORT FrameReportLen; // Current Frame report length ULONG CLBusyBytes; // Save the total bytes received durning channel load scan time USHORT RPIDensity[8]; // Array for RPI density collection - // Start address of each BSS table within FrameReportBuf - // It's important to update the RxPower of the corresponding Bss - USHORT BssReportOffset[MAX_LEN_OF_BSS_TABLE]; - USHORT BeaconToken; // Token for beacon report - ULONG LastBssIndex; // Most current reported Bss index - RM_REQUEST_ACTION MeasurementRequest[16]; // Saved measurement request + UCHAR RMReqCnt; // Number of measurement request saved. UCHAR CurrentRMReqIdx; // Number of measurement request saved. BOOLEAN ParallelReq; // Parallel measurement, only one request performed, @@ -2115,26 +1543,10 @@ typedef struct _STA_ADMIN_CONFIG { USHORT ParallelDuration; // Maximum duration for parallel measurement UCHAR ParallelChannel; // Only one channel with parallel measurement USHORT IAPPToken; // IAPP dialog token - UCHAR CCXQosECWMin; // Cisco QOS ECWMin for AC 0 - UCHAR CCXQosECWMax; // Cisco QOS ECWMax for AC 0 // Hack for channel load and noise histogram parameters UCHAR NHFactor; // Parameter for Noise histogram UCHAR CLFactor; // Parameter for channel load - UCHAR KRK[16]; //Key Refresh Key. - UCHAR BTK[32]; //Base Transient Key - BOOLEAN CCKMLinkUpFlag; - ULONG CCKMRN; //(Re)Association request number. - LARGE_INTEGER CCKMBeaconAtJoinTimeStamp; //TSF timer for Re-assocaite to the new AP - UCHAR AironetCellPowerLimit; //in dBm - UCHAR AironetIPAddress[4]; //eg. 192.168.1.1 - BOOLEAN CCXAdjacentAPReportFlag; //flag for determining report Assoc Lost time - CHAR CCXAdjacentAPSsid[MAX_LEN_OF_SSID]; //Adjacent AP's SSID report - UCHAR CCXAdjacentAPSsidLen; // the actual ssid length in used - UCHAR CCXAdjacentAPBssid[MAC_ADDR_LEN]; //Adjacent AP's BSSID report - USHORT CCXAdjacentAPChannel; - ULONG CCXAdjacentAPLinkDownTime; //for Spec S32. - RALINK_TIMER_STRUCT StaQuickResponeForRateUpTimer; BOOLEAN StaQuickResponeForRateUpTimerRunning; @@ -2148,7 +1560,7 @@ typedef struct _STA_ADMIN_CONFIG { RALINK_TIMER_STRUCT WpaDisassocAndBlockAssocTimer; // Fast Roaming - BOOLEAN bFastRoaming; // 0:disable fast roaming, 1:enable fast roaming + BOOLEAN bAutoRoaming; // 0:disable auto roaming by RSSI, 1:enable auto roaming by RSSI CHAR dBmToRoam; // the condition to roam when receiving Rssi less than this value. It's negative value. BOOLEAN IEEE8021X; @@ -2161,6 +1573,8 @@ typedef struct _STA_ADMIN_CONFIG { // 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters UCHAR WpaSupplicantUP; UCHAR WpaSupplicantScanCount; + BOOLEAN bRSN_IE_FromWpaSupplicant; + BOOLEAN bLostAp; CHAR dev_name[16]; USHORT OriDevType; @@ -2173,9 +1587,16 @@ typedef struct _STA_ADMIN_CONFIG { RT_HT_PHY_INFO DesiredHtPhyInfo; BOOLEAN bAutoTxRateSwitch; -#ifdef RT2860 +#ifdef RTMP_MAC_PCI UCHAR BBPR3; -#endif +#endif // RTMP_MAC_PCI // + + + + + BOOLEAN bAutoConnectByBssid; + ULONG BeaconLostTime; // seconds + BOOLEAN bForceTxBurst; // 1: force enble TX PACKET BURST, 0: disable } STA_ADMIN_CONFIG, *PSTA_ADMIN_CONFIG; // This data structure keep the current active BSS/IBSS's configuration that this STA @@ -2202,28 +1623,10 @@ typedef struct _STA_ACTIVE_CONFIG { RT_HT_CAPABILITY SupportedHtPhy; } STA_ACTIVE_CONFIG, *PSTA_ACTIVE_CONFIG; -#ifdef RT2870 -// for USB interface, avoid in interrupt when write key -typedef struct RT_ADD_PAIRWISE_KEY_ENTRY { - NDIS_802_11_MAC_ADDRESS MacAddr; - USHORT MacTabMatchWCID; // ASIC - CIPHER_KEY CipherKey; -} RT_ADD_PAIRWISE_KEY_ENTRY,*PRT_ADD_PAIRWISE_KEY_ENTRY; -#endif // RT2870 // -// ----------- start of AP -------------------------- -// AUTH-RSP State Machine Aux data structure -typedef struct _AP_MLME_AUX { - UCHAR Addr[MAC_ADDR_LEN]; - USHORT Alg; - CHAR Challenge[CIPHER_TEXT_LEN]; -} AP_MLME_AUX, *PAP_MLME_AUX; -// structure to define WPA Group Key Rekey Interval -typedef struct PACKED _RT_802_11_WPA_REKEY { - ULONG ReKeyMethod; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based - ULONG ReKeyInterval; // time-based: seconds, packet-based: kilo-packets -} RT_WPA_REKEY,*PRT_WPA_REKEY, RT_802_11_WPA_REKEY, *PRT_802_11_WPA_REKEY; + + typedef struct _MAC_TABLE_ENTRY { //Choose 1 from ValidAsWDS and ValidAsCLI to validize. @@ -2243,6 +1646,7 @@ typedef struct _MAC_TABLE_ENTRY { UCHAR RSNIE_Len; UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; UCHAR ANonce[LEN_KEY_DESC_NONCE]; + UCHAR SNonce[LEN_KEY_DESC_NONCE]; UCHAR R_Counter[LEN_KEY_DESC_REPLAY]; UCHAR PTK[64]; UCHAR ReTryCounter; @@ -2250,6 +1654,7 @@ typedef struct _MAC_TABLE_ENTRY { RALINK_TIMER_STRUCT EnqueueStartForPSKTimer; // A timer which enqueue EAPoL-Start for triggering PSK SM NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined NDIS_802_11_WEP_STATUS WepStatus; + NDIS_802_11_WEP_STATUS GroupKeyWepStatus; AP_WPA_STATE WpaState; GTK_STATE GTKState; USHORT PortSecured; @@ -2288,13 +1693,14 @@ typedef struct _MAC_TABLE_ENTRY { //==================================================== //WDS entry needs these -// rt2860 add this. if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab +// if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab UINT MatchWDSTabIdx; UCHAR MaxSupportedRate; UCHAR CurrTxRate; UCHAR CurrTxRateIndex; // to record the each TX rate's quality. 0 is best, the bigger the worse. USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH]; +// USHORT OneSecTxOkCount; UINT32 OneSecTxNoRetryOkCount; UINT32 OneSecTxRetryOkCount; UINT32 OneSecTxFailCount; @@ -2348,9 +1754,10 @@ typedef struct _MAC_TABLE_ENTRY { UINT32 TXMCSSuccessful[16]; UINT32 TXMCSFailed[16]; UINT32 TXMCSAutoFallBack[16][16]; -#ifdef RT2870 + ULONG LastBeaconRxTime; -#endif + + ULONG AssocDeadLine; } MAC_TABLE_ENTRY, *PMAC_TABLE_ENTRY; typedef struct _MAC_TABLE { @@ -2362,134 +1769,20 @@ typedef struct _MAC_TABLE { BOOLEAN fAnyStationInPsm; BOOLEAN fAnyStationBadAtheros; // Check if any Station is atheros 802.11n Chip. We need to use RTS/CTS with Atheros 802,.11n chip. BOOLEAN fAnyTxOPForceDisable; // Check if it is necessary to disable BE TxOP -#ifdef RT2870 BOOLEAN fAllStationAsRalink; // Check if all stations are ralink-chipset -#endif BOOLEAN fAnyStationIsLegacy; // Check if I use legacy rate to transmit to my BSS Station/ BOOLEAN fAnyStationNonGF; // Check if any Station can't support GF. BOOLEAN fAnyStation20Only; // Check if any Station can't support GF. BOOLEAN fAnyStationMIMOPSDynamic; // Check if any Station is MIMO Dynamic BOOLEAN fAnyBASession; // Check if there is BA session. Force turn on RTS/CTS +//2008/10/28: KH add to support Antenna power-saving of AP<-- +//2008/10/28: KH add to support Antenna power-saving of AP--> } MAC_TABLE, *PMAC_TABLE; -#define IS_HT_STA(_pMacEntry) \ - (_pMacEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX) - -#define IS_HT_RATE(_pMacEntry) \ - (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) - -#define PEER_IS_HT_RATE(_pMacEntry) \ - (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) - -typedef struct _WDS_ENTRY { - BOOLEAN Valid; - UCHAR Addr[MAC_ADDR_LEN]; - ULONG NoDataIdleCount; - struct _WDS_ENTRY *pNext; -} WDS_ENTRY, *PWDS_ENTRY; - -typedef struct _WDS_TABLE_ENTRY { - USHORT Size; - UCHAR WdsAddr[MAC_ADDR_LEN]; - WDS_ENTRY *Hash[HASH_TABLE_SIZE]; - WDS_ENTRY Content[MAX_LEN_OF_MAC_TABLE]; - UCHAR MaxSupportedRate; - UCHAR CurrTxRate; - USHORT TxQuality[MAX_LEN_OF_SUPPORTED_RATES]; - USHORT OneSecTxOkCount; - USHORT OneSecTxRetryOkCount; - USHORT OneSecTxFailCount; - ULONG CurrTxRateStableTime; // # of second in current TX rate - UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition -} WDS_TABLE_ENTRY, *PWDS_TABLE_ENTRY; - -typedef struct _RT_802_11_WDS_ENTRY { - PNET_DEV dev; - UCHAR Valid; - UCHAR PhyMode; - UCHAR PeerWdsAddr[MAC_ADDR_LEN]; - UCHAR MacTabMatchWCID; // ASIC - NDIS_802_11_WEP_STATUS WepStatus; - UCHAR KeyIdx; - CIPHER_KEY WdsKey; - HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode; - RT_HT_PHY_INFO DesiredHtPhyInfo; - BOOLEAN bAutoTxRateSwitch; - DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting. -} RT_802_11_WDS_ENTRY, *PRT_802_11_WDS_ENTRY; - -typedef struct _WDS_TABLE { - UCHAR Mode; - ULONG Size; - RT_802_11_WDS_ENTRY WdsEntry[MAX_WDS_ENTRY]; -} WDS_TABLE, *PWDS_TABLE; - -typedef struct _APCLI_STRUCT { - PNET_DEV dev; -#ifdef RTL865X_SOC - unsigned int mylinkid; -#endif - BOOLEAN Enable; // Set it as 1 if the apcli interface was configured to "1" or by iwpriv cmd "ApCliEnable" - BOOLEAN Valid; // Set it as 1 if the apcli interface associated success to remote AP. - UCHAR MacTabWCID; //WCID value, which point to the entry of ASIC Mac table. - UCHAR SsidLen; - CHAR Ssid[MAX_LEN_OF_SSID]; - - UCHAR CfgSsidLen; - CHAR CfgSsid[MAX_LEN_OF_SSID]; - UCHAR CfgApCliBssid[ETH_LENGTH_OF_ADDRESS]; - UCHAR CurrentAddress[ETH_LENGTH_OF_ADDRESS]; - - ULONG ApCliRcvBeaconTime; - - ULONG CtrlCurrState; - ULONG SyncCurrState; - ULONG AuthCurrState; - ULONG AssocCurrState; - ULONG WpaPskCurrState; - - USHORT AuthReqCnt; - USHORT AssocReqCnt; - - ULONG ClientStatusFlags; - UCHAR MpduDensity; - NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined - NDIS_802_11_WEP_STATUS WepStatus; - - // Add to support different cipher suite for WPA2/WPA mode - NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Multicast cipher suite - NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher suite - BOOLEAN bMixCipher; // Indicate current Pair & Group use different cipher suites - USHORT RsnCapability; - UCHAR PSK[100]; // reserve PSK key material - UCHAR PSKLen; - UCHAR PMK[32]; // WPA PSK mode PMK - UCHAR GTK[32]; // GTK from authenticator - - CIPHER_KEY SharedKey[SHARE_KEY_NUM]; - UCHAR DefaultKeyId; - - // store RSN_IE built by driver - UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; // The content saved here should be convert to little-endian format. - UCHAR RSNIE_Len; - - // For WPA countermeasures - ULONG LastMicErrorTime; // record last MIC error time - BOOLEAN bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred. - - // For WPA-PSK supplicant state - UCHAR SNonce[32]; // SNonce for WPA-PSK - UCHAR GNonce[32]; // GNonce for WPA-PSK from authenticator - HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode; - RT_HT_PHY_INFO DesiredHtPhyInfo; - BOOLEAN bAutoTxRateSwitch; - DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting. -} APCLI_STRUCT, *PAPCLI_STRUCT; -// ----------- end of AP ---------------------------- struct wificonf { @@ -2498,32 +1791,56 @@ struct wificonf }; - - -typedef struct _INF_PCI_CONFIG +typedef struct _RTMP_DEV_INFO_ { - PUCHAR CSRBaseAddress; // PCI MMIO Base Address, all access will use -}INF_PCI_CONFIG; + UCHAR chipName[16]; + RTMP_INF_TYPE infType; +}RTMP_DEV_INFO; -typedef struct _INF_USB_CONFIG -{ - UINT BulkInEpAddr; // bulk-in endpoint address - UINT BulkOutEpAddr[6]; // bulk-out endpoint address -}INF_USB_CONFIG; +struct _RTMP_CHIP_OP_ +{ + /* Calibration access related callback functions */ + int (*eeinit)(RTMP_ADAPTER *pAd); /* int (*eeinit)(RTMP_ADAPTER *pAd); */ + int (*eeread)(RTMP_ADAPTER *pAd, USHORT offset, PUSHORT pValue); /* int (*eeread)(RTMP_ADAPTER *pAd, int offset, PUSHORT pValue); */ + int (*eewrite)(RTMP_ADAPTER *pAd, USHORT offset, USHORT value);; /* int (*eewrite)(RTMP_ADAPTER *pAd, int offset, USHORT value); */ + + /* MCU related callback functions */ + int (*loadFirmware)(RTMP_ADAPTER *pAd); /* int (*loadFirmware)(RTMP_ADAPTER *pAd); */ + int (*eraseFirmware)(RTMP_ADAPTER *pAd); /* int (*eraseFirmware)(RTMP_ADAPTER *pAd); */ + int (*sendCommandToMcu)(RTMP_ADAPTER *pAd, UCHAR cmd, UCHAR token, UCHAR arg0, UCHAR arg1);; /* int (*sendCommandToMcu)(RTMP_ADAPTER *pAd, UCHAR cmd, UCHAR token, UCHAR arg0, UCHAR arg1); */ + + /* RF access related callback functions */ + REG_PAIR *pRFRegTable; + void (*AsicRfInit)(RTMP_ADAPTER *pAd); + void (*AsicRfTurnOn)(RTMP_ADAPTER *pAd); + void (*AsicRfTurnOff)(RTMP_ADAPTER *pAd); + void (*AsicReverseRfFromSleepMode)(RTMP_ADAPTER *pAd); + void (*AsicHaltAction)(RTMP_ADAPTER *pAd); +}; + // // The miniport adapter structure // -typedef struct _RTMP_ADAPTER +struct _RTMP_ADAPTER { PVOID OS_Cookie; // save specific structure relative to OS PNET_DEV net_dev; ULONG VirtualIfCnt; -#ifdef RT2860 + RTMP_CHIP_OP chipOps; + USHORT ThisTbttNumToNextWakeUp; + +#ifdef RTMP_MAC_PCI +/*****************************************************************************************/ +/* PCI related parameters */ +/*****************************************************************************************/ + PUCHAR CSRBaseAddress; // PCI MMIO Base Address, all access will use + unsigned int irq_num; + USHORT LnkCtrlBitMask; USHORT RLnkCtrlConfiguration; USHORT RLnkCtrlOffset; @@ -2531,15 +1848,7 @@ typedef struct _RTMP_ADAPTER USHORT HostLnkCtrlOffset; USHORT PCIePowerSaveLevel; BOOLEAN bPCIclkOff; // flag that indicate if the PICE power status in Configuration SPace.. - ULONG CheckDmaBusyCount; // Check Interrupt Status Register Count. - USHORT ThisTbttNumToNextWakeUp; - ULONG SameRxByteCount; - - -/*****************************************************************************************/ -/* PCI related parameters */ -/*****************************************************************************************/ - PUCHAR CSRBaseAddress; // PCI MMIO Base Address, all access will use + BOOLEAN bPCIclkOffDisableTx; // UINT int_enable_reg; UINT int_disable_mask; @@ -2550,12 +1859,13 @@ typedef struct _RTMP_ADAPTER RTMP_DMABUF RxDescRing; // Shared memory for RX descriptors RTMP_DMABUF TxDescRing[NUM_OF_TX_RING]; // Shared memory for Tx descriptors RTMP_TX_RING TxRing[NUM_OF_TX_RING]; // AC0~4 + HCCA -#endif +#endif // RTMP_MAC_PCI // + NDIS_SPIN_LOCK irq_lock; UCHAR irq_disabled; -#ifdef RT2870 +#ifdef RTMP_MAC_USB /*****************************************************************************************/ /* USB related parameters */ /*****************************************************************************************/ @@ -2572,34 +1882,38 @@ typedef struct _RTMP_ADAPTER ULONG BulkFlags; BOOLEAN bUsbTxBulkAggre; // Flags for bulk out data priority - - //======Timer Thread - RT2870_TIMER_QUEUE TimerQ; - NDIS_SPIN_LOCK TimerQLock; - - //======Cmd Thread CmdQ CmdQ; NDIS_SPIN_LOCK CmdQLock; // CmdQLock spinlock - - BOOLEAN TimerFunc_kill; - BOOLEAN mlme_kill; - + RTMP_OS_TASK cmdQTask; //======Semaphores (event) - struct semaphore mlme_semaphore; /* to sleep thread on */ - struct semaphore RTUSBCmd_semaphore; /* to sleep thread on */ - struct semaphore RTUSBTimer_semaphore; - struct completion TimerQComplete; - struct completion mlmeComplete; - struct completion CmdQComplete; + RTMP_OS_SEM UsbVendorReq_semaphore; + PVOID UsbVendorReqBuf; wait_queue_head_t *wait; -#endif // RT2870 // +#endif // RTMP_MAC_USB // + +/*****************************************************************************************/ +/* RBUS related parameters */ +/*****************************************************************************************/ /*****************************************************************************************/ - /* Both PCI/USB related parameters */ +/* Both PCI/USB related parameters */ +/*****************************************************************************************/ + //RTMP_DEV_INFO chipInfo; + RTMP_INF_TYPE infType; + +/*****************************************************************************************/ +/* Driver Mgmt related parameters */ /*****************************************************************************************/ + RTMP_OS_TASK mlmeTask; +#ifdef RTMP_TIMER_TASK_SUPPORT + // If you want use timer task to handle the timer related jobs, enable this. + RTMP_TIMER_TASK_QUEUE TimerQ; + NDIS_SPIN_LOCK TimerQLock; + RTMP_OS_TASK timerTask; +#endif // RTMP_TIMER_TASK_SUPPORT // /*****************************************************************************************/ @@ -2608,7 +1922,7 @@ typedef struct _RTMP_ADAPTER BOOLEAN DeQueueRunning[NUM_OF_TX_RING]; // for ensuring RTUSBDeQueuePacket get call once NDIS_SPIN_LOCK DeQueueLock[NUM_OF_TX_RING]; -#ifdef RT2870 +#ifdef RTMP_MAC_USB // Data related context and AC specified, 4 AC supported NDIS_SPIN_LOCK BulkOutLock[6]; // BulkOut spinlock for 4 ACs NDIS_SPIN_LOCK MLMEBulkOutLock; // MLME BulkOut lock @@ -2623,7 +1937,7 @@ typedef struct _RTMP_ADAPTER UCHAR bulkResetPipeid; BOOLEAN MgmtBulkPending; ULONG bulkResetReq[6]; -#endif // RT2870 // +#endif // RTMP_MAC_USB // // resource for software backlog queues QUEUE_HEADER TxSwQueue[NUM_OF_TX_RING]; // 4 AC + 1 HCCA @@ -2637,21 +1951,21 @@ typedef struct _RTMP_ADAPTER /*****************************************************************************************/ /* Rx related parameters */ /*****************************************************************************************/ -#ifdef RT2860 + +#ifdef RTMP_MAC_PCI RTMP_RX_RING RxRing; NDIS_SPIN_LOCK RxRingLock; // Rx Ring spinlock -#endif -#ifdef RT2870 +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB RX_CONTEXT RxContext[RX_RING_SIZE]; // 1 for redundant multiple IRP bulk in. NDIS_SPIN_LOCK BulkInLock; // BulkIn spinlock for 4 ACs - UCHAR PendingRx; // The Maxima pending Rx value should be RX_RING_SIZE. + UCHAR PendingRx; // The Maximum pending Rx value should be RX_RING_SIZE. UCHAR NextRxBulkInIndex; // Indicate the current RxContext Index which hold by Host controller. UCHAR NextRxBulkInReadIndex; // Indicate the current RxContext Index which driver can read & process it. ULONG NextRxBulkInPosition; // Want to contatenate 2 URB buffer while 1st is bulkin failed URB. This Position is 1st URB TransferLength. ULONG TransferBufferLength; // current length of the packet buffer ULONG ReadPosition; // current read position in a packet buffer -#endif // RT2870 // - +#endif // RTMP_MAC_USB // /*****************************************************************************************/ /* ASIC related parameters */ @@ -2662,18 +1976,22 @@ typedef struct _RTMP_ADAPTER // E2PROM // --------------------------- ULONG EepromVersion; // byte 0: version, byte 1: revision, byte 2~3: unused - UCHAR EEPROMAddressNum; // 93c46=6 93c66=8 + ULONG FirmwareVersion; // byte 0: Minor version, byte 1: Major version, otherwise unused. USHORT EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS]; -#ifdef RT2870 + UCHAR EEPROMAddressNum; // 93c46=6 93c66=8 BOOLEAN EepromAccess; -#endif - ULONG FirmwareVersion; // byte 0: Minor version, byte 1: Major version, otherwise unused. + UCHAR EFuseTag; + // --------------------------- // BBP Control // --------------------------- +#ifdef MERGE_ARCH_TEAM + UCHAR BbpWriteLatch[256]; // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID +#else UCHAR BbpWriteLatch[140]; // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID - UCHAR BbpRssiToDbmDelta; +#endif // MERGE_ARCH_TEAM // + CHAR BbpRssiToDbmDelta; // change from UCHAR to CHAR for high power BBP_R66_TUNING BbpTuning; // ---------------------------- @@ -2718,23 +2036,26 @@ typedef struct _RTMP_ADAPTER UCHAR TxAgcStepG; // Store Tx TSSI delta increment / decrement value CHAR TxAgcCompensateG; // Store the compensation (TxAgcStep * (idx-1)) - //+++For RT2870, the parameteres is start from BGRssiOffset1 ~ BGRssiOffset3 CHAR BGRssiOffset0; // Store B/G RSSI#0 Offset value on EEPROM 0x46h CHAR BGRssiOffset1; // Store B/G RSSI#1 Offset value CHAR BGRssiOffset2; // Store B/G RSSI#2 Offset value - //--- - //+++For RT2870, the parameteres is start from ARssiOffset1 ~ ARssiOffset3 CHAR ARssiOffset0; // Store A RSSI#0 Offset value on EEPROM 0x4Ah CHAR ARssiOffset1; // Store A RSSI#1 Offset value CHAR ARssiOffset2; // Store A RSSI#2 Offset value - //--- CHAR BLNAGain; // Store B/G external LNA#0 value on EEPROM 0x44h CHAR ALNAGain0; // Store A external LNA#0 value for ch36~64 CHAR ALNAGain1; // Store A external LNA#1 value for ch100~128 CHAR ALNAGain2; // Store A external LNA#2 value for ch132~165 - +#ifdef RT30xx + // for 3572 + UCHAR Bbp25; + UCHAR Bbp26; + + UCHAR TxMixerGain24G; // Tx mixer gain value from EEPROM to improve Tx EVM / Tx DAC, 2.4G + UCHAR TxMixerGain5G; +#endif // RT30xx // // ---------------------------- // LED control // ---------------------------- @@ -2742,7 +2063,7 @@ typedef struct _RTMP_ADAPTER USHORT Led1; // read from EEPROM 0x3c USHORT Led2; // EEPROM 0x3e USHORT Led3; // EEPROM 0x40 - UCHAR LedIndicatorStregth; + UCHAR LedIndicatorStrength; UCHAR RssiSingalstrengthOffet; BOOLEAN bLedOnScanning; UCHAR LedStatus; @@ -2759,20 +2080,17 @@ typedef struct _RTMP_ADAPTER PSPOLL_FRAME PsPollFrame; HEADER_802_11 NullFrame; -#ifdef RT2870 +#ifdef RTMP_MAC_USB TX_CONTEXT BeaconContext[BEACON_RING_SIZE]; TX_CONTEXT NullContext; TX_CONTEXT PsPollContext; TX_CONTEXT RTSContext; -#endif // RT2870 // - - +#endif // RTMP_MAC_USB // //=========AP=========== //=======STA=========== -/* Modified by Wu Xi-Kun 4/21/2006 */ // ----------------------------------------------- // STA specific configuration & operation status // used only when pAd->OpMode == OPMODE_STA @@ -2789,6 +2107,8 @@ typedef struct _RTMP_ADAPTER NDIS_MEDIA_STATE IndicateMediaState; // Base on Indication state, default is NdisMediaStateDisConnected + /* MAT related parameters */ + // configuration: read from Registry & E2PROM BOOLEAN bLocalAdminMAC; // Use user changed MAC UCHAR PermanentAddress[MAC_ADDR_LEN]; // Factory default MAC address @@ -2828,9 +2148,7 @@ typedef struct _RTMP_ADAPTER // flags, see fRTMP_ADAPTER_xxx flags ULONG Flags; // Represent current device status -#ifdef RT2860 ULONG PSFlags; // Power Save operation flag. -#endif // current TX sequence # USHORT Sequence; @@ -2863,36 +2181,38 @@ typedef struct _RTMP_ADAPTER /*****************************************************************************************/ /* Statistic related parameters */ /*****************************************************************************************/ -#ifdef RT2870 +#ifdef RTMP_MAC_USB ULONG BulkOutDataOneSecCount; ULONG BulkInDataOneSecCount; ULONG BulkLastOneSecCount; // BulkOutDataOneSecCount + BulkInDataOneSecCount ULONG watchDogRxCnt; ULONG watchDogRxOverFlowCnt; ULONG watchDogTxPendingCnt[NUM_OF_TX_RING]; -#endif // RT2870 // + INT TransferedLength[NUM_OF_TX_RING]; +#endif // RTMP_MAC_USB // BOOLEAN bUpdateBcnCntDone; ULONG watchDogMacDeadlock; // prevent MAC/BBP into deadlock condition // ---------------------------- // DEBUG paramerts // ---------------------------- + //ULONG DebugSetting[4]; BOOLEAN bBanAllBaSetup; BOOLEAN bPromiscuous; // ---------------------------- // rt2860c emulation-use Parameters // ---------------------------- - ULONG rtsaccu[30]; - ULONG ctsaccu[30]; - ULONG cfendaccu[30]; - ULONG bacontent[16]; - ULONG rxint[RX_RING_SIZE+1]; - UCHAR rcvba[60]; + //ULONG rtsaccu[30]; + //ULONG ctsaccu[30]; + //ULONG cfendaccu[30]; + //ULONG bacontent[16]; + //ULONG rxint[RX_RING_SIZE+1]; + //UCHAR rcvba[60]; BOOLEAN bLinkAdapt; BOOLEAN bForcePrintTX; BOOLEAN bForcePrintRX; - BOOLEAN bDisablescanning; //defined in RT2870 USB + //BOOLEAN bDisablescanning; //defined in RT2870 USB BOOLEAN bStaFifoTest; BOOLEAN bProtectionTest; BOOLEAN bHCCATest; @@ -2914,9 +2234,15 @@ typedef struct _RTMP_ADAPTER ULONG OneSecondnonBEpackets; // record non BE packets per second +#ifdef LINUX struct iw_statistics iw_stats; struct net_device_stats stats; +#endif // LINUX // + + + + ULONG TbttTickCount; #ifdef PCI_MSI_SUPPORT @@ -2933,32 +2259,24 @@ typedef struct _RTMP_ADAPTER + + + + + UINT8 FlgCtsEnabled; UINT8 PM_FlgSuspend; -#ifdef RT2870 +#ifdef RT30xx +#ifdef RTMP_EFUSE_SUPPORT BOOLEAN bUseEfuse; -#endif -} RTMP_ADAPTER, *PRTMP_ADAPTER; + BOOLEAN bEEPROMFile; + BOOLEAN bFroceEEPROMBuffer; + UCHAR EEPROMImage[1024]; +#endif // RTMP_EFUSE_SUPPORT // +#endif // RT30xx // +}; + -// -// Cisco IAPP format -// -typedef struct _CISCO_IAPP_CONTENT_ -{ - USHORT Length; //IAPP Length - UCHAR MessageType; //IAPP type - UCHAR FunctionCode; //IAPP function type - UCHAR DestinaionMAC[MAC_ADDR_LEN]; - UCHAR SourceMAC[MAC_ADDR_LEN]; - USHORT Tag; //Tag(element IE) - Adjacent AP report - USHORT TagLength; //Length of element not including 4 byte header - UCHAR OUI[4]; //0x00, 0x40, 0x96, 0x00 - UCHAR PreviousAP[MAC_ADDR_LEN]; //MAC Address of access point - USHORT Channel; - USHORT SsidLen; - UCHAR Ssid[MAX_LEN_OF_SSID]; - USHORT Seconds; //Seconds that the client has been disassociated. -} CISCO_IAPP_CONTENT, *PCISCO_IAPP_CONTENT; #define DELAYINTMASK 0x0003fffb #define INTMASK 0x0003fffb @@ -2976,8 +2294,12 @@ typedef struct _CISCO_IAPP_CONTENT_ #define FifoStaFullInt 0x00002000 // fifo statistics full interrupt +/*************************************************************************** + * Rx Path software control block related data structures + **************************************************************************/ typedef struct _RX_BLK_ { +// RXD_STRUC RxD; // sample RT28XX_RXD_STRUC RxD; PRXWI_STRUC pRxWI; PHEADER_802_11 pHeader; @@ -3012,6 +2334,10 @@ typedef struct _RX_BLK_ #define LENGTH_ARALINK_SUBFRAMEHEAD 14 #define LENGTH_ARALINK_HEADER_FIELD 2 + +/*************************************************************************** + * Tx Path software control block related data structures + **************************************************************************/ #define TX_UNKOWN_FRAME 0x00 #define TX_MCAST_FRAME 0x01 #define TX_LEGACY_FRAME 0x02 @@ -3040,7 +2366,9 @@ typedef struct _TX_BLK_ PUCHAR pSrcBufData; // Reference to the sk_buff->data, will changed depends on hanlding progresss UINT SrcBufLen; // Length of packet payload which not including Layer 2 header PUCHAR pExtraLlcSnapEncap; // NULL means no extra LLC/SNAP is required - UCHAR HeaderBuf[80]; // TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP + UCHAR HeaderBuf[128]; // TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP + //RT2870 2.1.0.0 uses only 80 bytes + //RT3070 2.1.1.0 uses only 96 bytes UCHAR MpduHeaderLen; // 802.11 header length NOT including the padding UCHAR HdrPadLen; // recording Header Padding Length; UCHAR apidx; // The interface associated to this packet @@ -3069,17 +2397,8 @@ typedef struct _TX_BLK_ #define fTX_bAllowFrag 0x0020 // allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment #define fTX_bMoreData 0x0040 // there are more data packets in PowerSave Queue #define fTX_bWMM 0x0080 // QOS Data - #define fTX_bClearEAPFrame 0x0100 -#define TX_BLK_ASSIGN_FLAG(_pTxBlk, _flag, value) \ - do { \ - if (value) \ - (_pTxBlk->Flags |= _flag) \ - else \ - (_pTxBlk->Flags &= ~(_flag)) \ - }while(0) - #define TX_BLK_SET_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags |= _flag) #define TX_BLK_TEST_FLAG(_pTxBlk, _flag) (((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0) #define TX_BLK_CLEAR_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags &= ~(_flag)) @@ -3088,42 +2407,10 @@ typedef struct _TX_BLK_ -//------------------------------------------------------------------------------------------ - -#ifdef RT2860 -// -// Enable & Disable NIC interrupt via writing interrupt mask register -// Since it use ADAPTER structure, it have to be put after structure definition. -// -__inline VOID NICDisableInterrupt( - IN PRTMP_ADAPTER pAd) -{ - RTMP_IO_WRITE32(pAd, INT_MASK_CSR, 0x0); // 0: disable - //RTMP_IO_WRITE32(pAd, PBF_INT_ENA, 0x0); // 0x418 is for firmware . SW doesn't handle here. - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE); -} - -__inline VOID NICEnableInterrupt( - IN PRTMP_ADAPTER pAd) -{ - // - // Flag "fOP_STATUS_DOZE" On, means ASIC put to sleep, else means ASIC WakeUp - // To prevent System hang, we should enalbe the interrupt when - // ASIC is already Wake Up. - // - // RT2661 => when ASIC is sleeping, MAC register cannot be read and written. - // RT2860 => when ASIC is sleeping, MAC register can be read and written. - //if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - { - RTMP_IO_WRITE32(pAd, INT_MASK_CSR, pAd->int_enable_reg /*DELAYINTMASK*/); // 1:enable - } - //else - // DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n")); - - //RTMP_IO_WRITE32(pAd, PBF_INT_ENA, 0x00000030); // 1 : enable - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE); -} +/*************************************************************************** + * Other static inline function definitions + **************************************************************************/ static inline VOID ConvertMulticastIP2MAC( IN PUCHAR pIpAddr, IN PUCHAR *ppMacAddr, @@ -3161,37 +2448,59 @@ static inline VOID ConvertMulticastIP2MA return; } -#endif /* RT2860 */ + + +char *GetPhyMode(int Mode); +char* GetBW(int BW); // // Private routines in rtmp_init.c // NDIS_STATUS RTMPAllocAdapterBlock( IN PVOID handle, - OUT PRTMP_ADAPTER *ppAdapter - ); + OUT PRTMP_ADAPTER *ppAdapter); NDIS_STATUS RTMPAllocTxRxRingMemory( - IN PRTMP_ADAPTER pAd - ); + IN PRTMP_ADAPTER pAd); NDIS_STATUS RTMPReadParametersHook( - IN PRTMP_ADAPTER pAd - ); + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS RTMPSetProfileParameters( + IN RTMP_ADAPTER *pAd, + IN PSTRING pBuffer); + +INT RTMPGetKeyParameter( + IN PSTRING key, + OUT PSTRING dest, + IN INT destsize, + IN PSTRING buffer, + IN BOOLEAN bTrimSpace); VOID RTMPFreeAdapter( - IN PRTMP_ADAPTER pAd - ); + IN PRTMP_ADAPTER pAd); NDIS_STATUS NICReadRegParameters( IN PRTMP_ADAPTER pAd, - IN NDIS_HANDLE WrapperConfigurationContext - ); + IN NDIS_HANDLE WrapperConfigurationContext); -#ifdef RT2870 -VOID NICInitRT30xxRFRegisters( +#ifdef RTMP_RF_RW_SUPPORT +VOID NICInitRFRegisters( IN PRTMP_ADAPTER pAd); -#endif // RT2870 // + +VOID RtmpChipOpsRFHook( + IN RTMP_ADAPTER *pAd); + +NDIS_STATUS RT30xxWriteRFRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR regID, + IN UCHAR value); + +NDIS_STATUS RT30xxReadRFRegister( + IN PRTMP_ADAPTER pAd, + IN UCHAR regID, + IN PUCHAR pValue); +#endif // RTMP_RF_RW_SUPPORT // VOID NICReadEEPROMParameters( IN PRTMP_ADAPTER pAd, @@ -3200,8 +2509,6 @@ VOID NICReadEEPROMParameters( VOID NICInitAsicFromEEPROM( IN PRTMP_ADAPTER pAd); -VOID NICInitTxRxRingAndBacklogQueue( - IN PRTMP_ADAPTER pAd); NDIS_STATUS NICInitializeAdapter( IN PRTMP_ADAPTER pAd, @@ -3210,10 +2517,7 @@ NDIS_STATUS NICInitializeAdapter( NDIS_STATUS NICInitializeAsic( IN PRTMP_ADAPTER pAd, IN BOOLEAN bHardReset); -#ifdef RT2860 -VOID NICRestoreBBPValue( - IN PRTMP_ADAPTER pAd); -#endif + VOID NICIssueReset( IN PRTMP_ADAPTER pAd); @@ -3227,10 +2531,10 @@ VOID UserCfgInit( VOID NICResetFromError( IN PRTMP_ADAPTER pAd); -VOID NICEraseFirmware( +NDIS_STATUS NICLoadFirmware( IN PRTMP_ADAPTER pAd); -NDIS_STATUS NICLoadFirmware( +VOID NICEraseFirmware( IN PRTMP_ADAPTER pAd); NDIS_STATUS NICLoadRateSwitchingParams( @@ -3245,10 +2549,6 @@ VOID NICUpdateFifoStaCounters( VOID NICUpdateRawCounters( IN PRTMP_ADAPTER pAd); -ULONG RTMPNotAllZero( - IN PVOID pSrc1, - IN ULONG Length); - VOID RTMPZeroMemory( IN PVOID pSrc, IN ULONG Length); @@ -3264,8 +2564,8 @@ VOID RTMPMoveMemory( IN ULONG Length); VOID AtoH( - char *src, - UCHAR *dest, + PSTRING src, + PUCHAR dest, int destlen); UCHAR BtoH( @@ -3383,6 +2683,7 @@ VOID SendRefreshBAR( IN PRTMP_ADAPTER pAd, IN MAC_TABLE_ENTRY *pEntry); + VOID ActHeaderInit( IN PRTMP_ADAPTER pAd, IN OUT PHEADER_802_11 pHdr80211, @@ -3444,6 +2745,7 @@ BOOLEAN PeerIsAggreOn( IN ULONG TxRate, IN PMAC_TABLE_ENTRY pMacEntry); + NDIS_STATUS Sniff2BytesFromNdisBuffer( IN PNDIS_BUFFER pFirstBuffer, IN UCHAR DesiredOffset, @@ -3498,11 +2800,24 @@ NDIS_STATUS MlmeHardTransmitMgmtRing( IN UCHAR QueIdx, IN PNDIS_PACKET pPacket); +#ifdef RTMP_MAC_PCI NDIS_STATUS MlmeHardTransmitTxRing( IN PRTMP_ADAPTER pAd, IN UCHAR QueIdx, IN PNDIS_PACKET pPacket); +NDIS_STATUS MlmeDataHardTransmit( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN PNDIS_PACKET pPacket); + +VOID RTMPWriteTxDescriptor( + IN PRTMP_ADAPTER pAd, + IN PTXD_STRUC pTxD, + IN BOOLEAN bWIV, + IN UCHAR QSEL); +#endif // RTMP_MAC_PCI // + USHORT RTMPCalcDuration( IN PRTMP_ADAPTER pAd, IN UCHAR Rate, @@ -3539,12 +2854,6 @@ VOID RTMPWriteTxWI_Cache( IN OUT PTXWI_STRUC pTxWI, IN TX_BLK *pTxBlk); -VOID RTMPWriteTxDescriptor( - IN PRTMP_ADAPTER pAd, - IN PTXD_STRUC pTxD, - IN BOOLEAN bWIV, - IN UCHAR QSEL); - VOID RTMPSuspendMsduTransmission( IN PRTMP_ADAPTER pAd); @@ -3557,6 +2866,9 @@ NDIS_STATUS MiniportMMRequest( IN PUCHAR pData, IN UINT Length); +//+++mark by shiang, now this function merge to MiniportMMRequest() +//---mark by shiang, now this function merge to MiniportMMRequest() + VOID RTMPSendNullFrame( IN PRTMP_ADAPTER pAd, IN UCHAR TxRate, @@ -3593,6 +2905,16 @@ VOID WpaDisassocApAndBlockAssoc( IN PVOID SystemSpecific2, IN PVOID SystemSpecific3); +VOID WpaStaPairwiseKeySetting( + IN PRTMP_ADAPTER pAd); + +VOID WpaStaGroupKeySetting( + IN PRTMP_ADAPTER pAd); + +VOID WpaSendEapolStart( + IN PRTMP_ADAPTER pAdapter, + IN PUCHAR pBssid); + NDIS_STATUS RTMPCloneNdisPacket( IN PRTMP_ADAPTER pAd, IN BOOLEAN pInsAMSDUHdr, @@ -3713,6 +3035,9 @@ VOID AsicRfTuningExec( IN PVOID SystemSpecific2, IN PVOID SystemSpecific3); +VOID AsicResetBBPAgent( + IN PRTMP_ADAPTER pAd); + VOID AsicSleepThenAutoWakeup( IN PRTMP_ADAPTER pAd, IN USHORT TbttNumToNextWakeUp); @@ -3722,12 +3047,7 @@ VOID AsicForceSleep( VOID AsicForceWakeup( IN PRTMP_ADAPTER pAd, -#ifdef RT2860 - IN UCHAR Level); -#endif -#ifdef RT2870 IN BOOLEAN bFromTx); -#endif VOID AsicSetBssid( IN PRTMP_ADAPTER pAd, @@ -3821,11 +3141,14 @@ BOOLEAN AsicSendCommandToMcu( IN UCHAR Token, IN UCHAR Arg0, IN UCHAR Arg1); -#ifdef RT2860 + + +#ifdef RTMP_MAC_PCI BOOLEAN AsicCheckCommanOk( IN PRTMP_ADAPTER pAd, IN UCHAR Command); -#endif +#endif // RTMP_MAC_PCI // + VOID MacAddrRandomBssid( IN PRTMP_ADAPTER pAd, OUT PUCHAR pAddr); @@ -3871,6 +3194,11 @@ ULONG BssTableSearchWithSSID( IN UCHAR SsidLen, IN UCHAR Channel); +ULONG BssSsidTableSearchBySSID( + IN BSS_TABLE *Tab, + IN PUCHAR pSsid, + IN UCHAR SsidLen); + VOID BssTableDeleteEntry( IN OUT PBSS_TABLE pTab, IN PUCHAR pBssid, @@ -4095,9 +3423,6 @@ VOID Cls3errAction( IN PRTMP_ADAPTER pAd, IN PUCHAR pAddr); -VOID SwitchBetweenWepAndCkip( - IN PRTMP_ADAPTER pAd); - VOID InvalidStateWhenAssoc( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem); @@ -4110,12 +3435,12 @@ VOID InvalidStateWhenDisassociate( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem); -#ifdef RT2870 +#ifdef RTMP_MAC_USB VOID MlmeCntlConfirm( IN PRTMP_ADAPTER pAd, IN ULONG MsgType, IN USHORT Msg); -#endif // RT2870 // +#endif // RTMP_MAC_USB // VOID ComposePsPoll( IN PRTMP_ADAPTER pAd); @@ -4325,7 +3650,7 @@ VOID AssocParmFill( VOID ScanParmFill( IN PRTMP_ADAPTER pAd, IN OUT MLME_SCAN_REQ_STRUCT *ScanReq, - IN CHAR Ssid[], + IN STRING Ssid[], IN UCHAR SsidLen, IN UCHAR BssType, IN UCHAR ScanType); @@ -4396,7 +3721,7 @@ VOID ScanNextChannel( ULONG MakeIbssBeacon( IN PRTMP_ADAPTER pAd); -VOID CCXAdjacentAPReport( +VOID InitChannelRelatedValue( IN PRTMP_ADAPTER pAd); BOOLEAN MlmeScanReqSanity( @@ -4527,6 +3852,13 @@ BOOLEAN PeerDisassocSanity( OUT PUCHAR pAddr2, OUT USHORT *Reason); +BOOLEAN PeerWpaMessageSanity( + IN PRTMP_ADAPTER pAd, + IN PEAPOL_PACKET pMsg, + IN ULONG MsgLen, + IN UCHAR MsgType, + IN MAC_TABLE_ENTRY *pEntry); + BOOLEAN PeerDeauthSanity( IN PRTMP_ADAPTER pAd, IN VOID *Msg, @@ -4570,7 +3902,7 @@ BOOLEAN MlmeAddBAReqSanity( OUT PUCHAR pAddr2); ULONG MakeOutgoingFrame( - OUT CHAR *Buffer, + OUT UCHAR *Buffer, OUT ULONG *Length, ...); VOID LfsrInit( @@ -4613,9 +3945,8 @@ VOID MlmeCheckForRoaming( IN PRTMP_ADAPTER pAd, IN ULONG Now32); -VOID MlmeCheckForFastRoaming( - IN PRTMP_ADAPTER pAd, - IN ULONG Now); +BOOLEAN MlmeCheckForFastRoaming( + IN PRTMP_ADAPTER pAd); VOID MlmeDynamicTxRateSwitching( IN PRTMP_ADAPTER pAd); @@ -4634,6 +3965,7 @@ VOID MlmeSelectTxRateTable( VOID MlmeCalculateChannelQuality( IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pMacEntry, IN ULONG Now); VOID MlmeCheckPsmChange( @@ -4691,10 +4023,91 @@ CHAR RTMPMaxRssi( IN CHAR Rssi1, IN CHAR Rssi2); +#ifdef RT30xx VOID AsicSetRxAnt( IN PRTMP_ADAPTER pAd, IN UCHAR Ant); +VOID RTMPFilterCalibration( + IN PRTMP_ADAPTER pAd); + +#ifdef RTMP_EFUSE_SUPPORT +//2008/09/11:KH add to support efuse<-- +INT set_eFuseGetFreeBlockCount_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT set_eFusedump_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT set_eFuseLoadFromBin_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +VOID eFusePhysicalReadRegisters( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN USHORT Length, + OUT USHORT* pData); + +int RtmpEfuseSupportCheck( + IN RTMP_ADAPTER *pAd); + +INT set_eFuseBufferModeWriteBack_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT eFuseLoadEEPROM( + IN PRTMP_ADAPTER pAd); + +INT eFuseWriteEeeppromBuf( + IN PRTMP_ADAPTER pAd); + +VOID eFuseGetFreeBlockCount(IN PRTMP_ADAPTER pAd, + PUINT EfuseFreeBlock); + +INT eFuse_init( + IN PRTMP_ADAPTER pAd); + +NTSTATUS eFuseRead( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + OUT PUCHAR pData, + IN USHORT Length); + +NTSTATUS eFuseWrite( + IN PRTMP_ADAPTER pAd, + IN USHORT Offset, + IN PUCHAR pData, + IN USHORT length); +//2008/09/11:KH add to support efuse--> +#endif // RTMP_EFUSE_SUPPORT // + +// add by johnli, RF power sequence setup +VOID RT30xxLoadRFNormalModeSetup( + IN PRTMP_ADAPTER pAd); + +VOID RT30xxLoadRFSleepModeSetup( + IN PRTMP_ADAPTER pAd); + +VOID RT30xxReverseRFSleepModeSetup( + IN PRTMP_ADAPTER pAd); +// end johnli + +#ifdef RT3070 +VOID NICInitRT3070RFRegisters( + IN RTMP_ADAPTER *pAd); +#endif // RT3070 // + +VOID RT30xxHaltAction( + IN PRTMP_ADAPTER pAd); + +VOID RT30xxSetRxAnt( + IN PRTMP_ADAPTER pAd, + IN UCHAR Ant); +#endif // RT30xx // + VOID AsicEvaluateRxAnt( IN PRTMP_ADAPTER pAd); @@ -4751,15 +4164,6 @@ VOID ChangeToCellPowerLimit( IN PRTMP_ADAPTER pAd, IN UCHAR AironetCellPowerLimit); -USHORT RTMP_EEPROM_READ16( - IN PRTMP_ADAPTER pAd, - IN USHORT Offset); - -VOID RTMP_EEPROM_WRITE16( - IN PRTMP_ADAPTER pAd, - IN USHORT Offset, - IN USHORT Data); - // // Prototypes of function definition in rtmp_tkip.c // @@ -4831,6 +4235,39 @@ BOOLEAN RTMPSoftDecryptAES( IN ULONG DataByteCnt, IN PCIPHER_KEY pWpaKey); + + +// +// Prototypes of function definition in cmm_info.c +// +INT RT_CfgSetCountryRegion( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg, + IN INT band); + +INT RT_CfgSetWirelessMode( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT RT_CfgSetShortSlot( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT RT_CfgSetWepKey( + IN PRTMP_ADAPTER pAd, + IN PSTRING keyString, + IN CIPHER_KEY *pSharedKey, + IN INT keyIdx); + +INT RT_CfgSetWPAPSKKey( + IN RTMP_ADAPTER *pAd, + IN PSTRING keyString, + IN UCHAR *pHashStr, + IN INT hashStrLen, + OUT PUCHAR pPMKBuf); + + + // // Prototypes of function definition in cmm_info.c // @@ -4862,26 +4299,12 @@ VOID RTMPAddWcidAttributeEntry( IN UCHAR CipherAlg, IN MAC_TABLE_ENTRY *pEntry); -CHAR *GetEncryptType( +PSTRING GetEncryptType( CHAR enc); -CHAR *GetAuthMode( +PSTRING GetAuthMode( CHAR auth); -VOID RTMPIoctlGetSiteSurvey( - IN PRTMP_ADAPTER pAdapter, - IN struct iwreq *wrq); - -VOID RTMPIoctlGetMacTable( - IN PRTMP_ADAPTER pAd, - IN struct iwreq *wrq); - -VOID RTMPAddBSSIDCipher( - IN PRTMP_ADAPTER pAd, - IN UCHAR Aid, - IN PNDIS_802_11_KEY pKey, - IN UCHAR CipherAlg); - VOID RTMPSetHT( IN PRTMP_ADAPTER pAd, IN OID_SET_HT_PHYMODE *pHTPhyMode); @@ -4897,88 +4320,24 @@ VOID RTMPSendWirelessEvent( IN UCHAR BssIdx, IN CHAR Rssi); -// -// prototype in wpa.c -// -BOOLEAN WpaMsgTypeSubst( - IN UCHAR EAPType, - OUT INT *MsgType); - -VOID WpaPskStateMachineInit( - IN PRTMP_ADAPTER pAd, - IN STATE_MACHINE *S, - OUT STATE_MACHINE_FUNC Trans[]); - -VOID WpaEAPOLKeyAction( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem); - -VOID WpaPairMsg1Action( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem); - -VOID WpaPairMsg3Action( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem); - -VOID WpaGroupMsg1Action( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem); - -VOID WpaMacHeaderInit( - IN PRTMP_ADAPTER pAd, - IN OUT PHEADER_802_11 pHdr80211, - IN UCHAR wep, - IN PUCHAR pAddr1); - -VOID Wpa2PairMsg1Action( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem); - -VOID Wpa2PairMsg3Action( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem); - -BOOLEAN ParseKeyData( +CHAR ConvertToRssi( IN PRTMP_ADAPTER pAd, - IN PUCHAR pKeyData, - IN UCHAR KeyDataLen, - IN UCHAR bPairewise); + IN CHAR Rssi, + IN UCHAR RssiNumber); +/*=================================== + Function prototype in cmm_wpa.c + =================================== */ VOID RTMPToWirelessSta( IN PRTMP_ADAPTER pAd, + IN PMAC_TABLE_ENTRY pEntry, IN PUCHAR pHeader802_3, IN UINT HdrLen, IN PUCHAR pData, IN UINT DataLen, - IN BOOLEAN is4wayFrame); - -VOID HMAC_SHA1( - IN UCHAR *text, - IN UINT text_len, - IN UCHAR *key, - IN UINT key_len, - IN UCHAR *digest); - -VOID PRF( - IN UCHAR *key, - IN INT key_len, - IN UCHAR *prefix, - IN INT prefix_len, - IN UCHAR *data, - IN INT data_len, - OUT UCHAR *output, - IN INT len); - -VOID CCKMPRF( - IN UCHAR *key, - IN INT key_len, - IN UCHAR *data, - IN INT data_len, - OUT UCHAR *output, - IN INT len); + IN BOOLEAN bClearFrame); -VOID WpaCountPTK( +VOID WpaDerivePTK( IN PRTMP_ADAPTER pAd, IN UCHAR *PMK, IN UCHAR *ANonce, @@ -4993,95 +4352,135 @@ VOID GenRandom( IN UCHAR *macAddr, OUT UCHAR *random); -// -// prototype in aironet.c -// -VOID AironetStateMachineInit( +BOOLEAN RTMPCheckWPAframe( IN PRTMP_ADAPTER pAd, - IN STATE_MACHINE *S, - OUT STATE_MACHINE_FUNC Trans[]); + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pData, + IN ULONG DataByteCount, + IN UCHAR FromWhichBSSID); -VOID AironetMsgAction( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem); +VOID AES_GTK_KEY_UNWRAP( + IN UCHAR *key, + OUT UCHAR *plaintext, + IN UINT32 c_len, + IN UCHAR *ciphertext); -VOID AironetRequestAction( +BOOLEAN RTMPParseEapolKeyData( IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem); + IN PUCHAR pKeyData, + IN UCHAR KeyDataLen, + IN UCHAR GroupKeyIndex, + IN UCHAR MsgType, + IN BOOLEAN bWPA2, + IN MAC_TABLE_ENTRY *pEntry); + +VOID ConstructEapolMsg( + IN PMAC_TABLE_ENTRY pEntry, + IN UCHAR GroupKeyWepStatus, + IN UCHAR MsgType, + IN UCHAR DefaultKeyIdx, + IN UCHAR *KeyNonce, + IN UCHAR *TxRSC, + IN UCHAR *GTK, + IN UCHAR *RSNIE, + IN UCHAR RSNIE_Len, + OUT PEAPOL_PACKET pMsg); + +NDIS_STATUS RTMPSoftDecryptBroadCastData( + IN PRTMP_ADAPTER pAd, + IN RX_BLK *pRxBlk, + IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher, + IN PCIPHER_KEY pShard_key); -VOID ChannelLoadRequestAction( +VOID RTMPMakeRSNIE( IN PRTMP_ADAPTER pAd, - IN UCHAR Index); + IN UINT AuthMode, + IN UINT WepStatus, + IN UCHAR apidx); -VOID NoiseHistRequestAction( +// +// function prototype in ap_wpa.c +// +VOID RTMPGetTxTscFromAsic( IN PRTMP_ADAPTER pAd, - IN UCHAR Index); + IN UCHAR apidx, + OUT PUCHAR pTxTsc); -VOID BeaconRequestAction( +VOID APInstallPairwiseKey( + PRTMP_ADAPTER pAd, + PMAC_TABLE_ENTRY pEntry); + +UINT APValidateRSNIE( IN PRTMP_ADAPTER pAd, - IN UCHAR Index); + IN PMAC_TABLE_ENTRY pEntry, + IN PUCHAR pRsnIe, + IN UCHAR rsnie_len); -VOID AironetReportAction( +VOID HandleCounterMeasure( IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem); + IN MAC_TABLE_ENTRY *pEntry); -VOID ChannelLoadReportAction( +VOID WPAStart4WayHS( IN PRTMP_ADAPTER pAd, - IN UCHAR Index); + IN MAC_TABLE_ENTRY *pEntry, + IN ULONG TimeInterval); -VOID NoiseHistReportAction( +VOID WPAStart2WayGroupHS( IN PRTMP_ADAPTER pAd, - IN UCHAR Index); + IN MAC_TABLE_ENTRY *pEntry); -VOID AironetFinalReportAction( - IN PRTMP_ADAPTER pAd); +VOID PeerPairMsg1Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem); -VOID BeaconReportAction( +VOID PeerPairMsg2Action( IN PRTMP_ADAPTER pAd, - IN UCHAR Index); + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem); -VOID AironetAddBeaconReport( +VOID PeerPairMsg3Action( IN PRTMP_ADAPTER pAd, - IN ULONG Index, - IN PMLME_QUEUE_ELEM pElem); + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem); -VOID AironetCreateBeaconReportFromBssTable( - IN PRTMP_ADAPTER pAd); +VOID PeerPairMsg4Action( + IN PRTMP_ADAPTER pAd, + IN MAC_TABLE_ENTRY *pEntry, + IN MLME_QUEUE_ELEM *Elem); -CHAR ConvertToRssi( +VOID PeerGroupMsg1Action( IN PRTMP_ADAPTER pAd, - IN CHAR Rssi, - IN UCHAR RssiNumber); + IN PMAC_TABLE_ENTRY pEntry, + IN MLME_QUEUE_ELEM *Elem); -// -// function prototype in cmm_wpa.c -// -BOOLEAN RTMPCheckWPAframe( +VOID PeerGroupMsg2Action( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, - IN PUCHAR pData, - IN ULONG DataByteCount, - IN UCHAR FromWhichBSSID); + IN VOID *Msg, + IN UINT MsgLen); -VOID AES_GTK_KEY_UNWRAP( - IN UCHAR *key, - OUT UCHAR *plaintext, - IN UCHAR c_len, - IN UCHAR *ciphertext); +VOID WpaDeriveGTK( + IN UCHAR *PMK, + IN UCHAR *GNonce, + IN UCHAR *AA, + OUT UCHAR *output, + IN UINT len); -VOID RTMPMakeRSNIE( - IN PRTMP_ADAPTER pAd, - IN UINT AuthMode, - IN UINT WepStatus, - IN UCHAR apidx); +VOID AES_GTK_KEY_WRAP( + IN UCHAR *key, + IN UCHAR *plaintext, + IN UINT32 p_len, + OUT UCHAR *ciphertext); + +VOID AES_128_CMAC( + IN PUCHAR key, + IN PUCHAR input, + IN INT len, + OUT PUCHAR mac); -// -// function prototype in ap_wpa.c -// +//typedef void (*TIMER_FUNCTION)(unsigned long); -VOID HandleCounterMeasure( - IN PRTMP_ADAPTER pAd, - IN MAC_TABLE_ENTRY *pEntry); /* timeout -- ms */ VOID RTMP_SetPeriodicTimer( @@ -5116,13 +4515,13 @@ VOID RTMPusecDelay( IN ULONG usec); NDIS_STATUS os_alloc_mem( - IN PRTMP_ADAPTER pAd, - OUT PUCHAR *mem, + IN RTMP_ADAPTER *pAd, + OUT UCHAR **mem, IN ULONG size); NDIS_STATUS os_free_mem( IN PRTMP_ADAPTER pAd, - IN PUCHAR mem); + IN PVOID mem); void RTMP_AllocateSharedMemory( @@ -5155,6 +4554,13 @@ void RTMP_AllocateFirstTxBuffer( OUT PVOID *VirtualAddress, OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress); +void RTMP_FreeFirstTxBuffer( + IN PRTMP_ADAPTER pAd, + IN ULONG Length, + IN BOOLEAN Cached, + IN PVOID VirtualAddress, + IN NDIS_PHYSICAL_ADDRESS PhysicalAddress); + void RTMP_AllocateMgmtDescMemory( IN PRTMP_ADAPTER pAd, IN ULONG Length, @@ -5169,6 +4575,16 @@ void RTMP_AllocateRxDescMemory( OUT PVOID *VirtualAddress, OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress); +void RTMP_FreeDescMemory( + IN PRTMP_ADAPTER pAd, + IN ULONG Length, + IN PVOID VirtualAddress, + IN NDIS_PHYSICAL_ADDRESS PhysicalAddress); + +PNDIS_PACKET RtmpOSNetPktAlloc( + IN RTMP_ADAPTER *pAd, + IN int size); + PNDIS_PACKET RTMP_AllocateRxPacketBuffer( IN PRTMP_ADAPTER pAd, IN ULONG Length, @@ -5279,203 +4695,210 @@ VOID BARecSessionTearDown( BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num); void ba_reordering_resource_release(PRTMP_ADAPTER pAd); + + + BOOLEAN rtstrmactohex( - IN char *s1, - IN char *s2); + IN PSTRING s1, + IN PSTRING s2); BOOLEAN rtstrcasecmp( - IN char *s1, - IN char *s2); + IN PSTRING s1, + IN PSTRING s2); -char *rtstrstruncasecmp( - IN char *s1, - IN char *s2); - -char *rtstrstr( - IN const char * s1, - IN const char * s2); - -char *rstrtok( - IN char * s, - IN const char * ct); +PSTRING rtstrstruncasecmp( + IN PSTRING s1, + IN PSTRING s2); + +PSTRING rtstrstr( + IN const PSTRING s1, + IN const PSTRING s2); + +PSTRING rstrtok( + IN PSTRING s, + IN const PSTRING ct); int rtinet_aton( - const char *cp, + const PSTRING cp, unsigned int *addr); ////////// common ioctl functions ////////// INT Set_DriverVersion_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_CountryRegion_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_CountryRegionABand_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_WirelessMode_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_Channel_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_ShortSlot_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_TxPower_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_BGProtection_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_TxPreamble_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_RTSThreshold_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_FragThreshold_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_TxBurst_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); #ifdef AGGREGATION_SUPPORT INT Set_PktAggregate_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); -#endif + IN PSTRING arg); +#endif // AGGREGATION_SUPPORT // INT Set_IEEE80211H_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); #ifdef DBG INT Set_Debug_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); #endif INT Show_DescInfo_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_ResetStatCounter_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_BASetup_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_BADecline_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_BAOriTearDown_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_BARecTearDown_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtBw_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtMcs_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtGi_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtOpMode_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtStbc_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtHtc_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtExtcha_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtMpduDensity_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtBaWinSize_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtRdg_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtLinkAdapt_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtAmsdu_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtAutoBa_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtProtect_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtMimoPs_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_ForceShortGI_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_ForceGF_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT SetCommonHT( IN PRTMP_ADAPTER pAd); INT Set_SendPSMPAction_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtMIMOPSmode_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_HtTxBASize_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); + +INT Set_HtDisallowTKIP_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); INT WpaCheckEapCode( IN PRTMP_ADAPTER pAd, @@ -5528,12 +4951,6 @@ void wlan_802_11_to_802_3_packet( IN PUCHAR pHeader802_3, IN UCHAR FromWhichBSSID); -UINT deaggregate_AMSDU_announce( - IN PRTMP_ADAPTER pAd, - PNDIS_PACKET pPacket, - IN PUCHAR pData, - IN ULONG DataSize); - // remove LLC and get 802_3 Header #define RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(_pRxBlk, _pHeader802_3) \ { \ @@ -5604,11 +5021,28 @@ VOID Update_Rssi_Sample( IN RSSI_SAMPLE *pRssi, IN PRXWI_STRUC pRxWI); +PNDIS_PACKET GetPacketFromRxRing( + IN PRTMP_ADAPTER pAd, + OUT PRT28XX_RXD_STRUC pSaveRxD, + OUT BOOLEAN *pbReschedule, + IN OUT UINT32 *pRxPending); + PNDIS_PACKET RTMPDeFragmentDataFrame( IN PRTMP_ADAPTER pAd, IN RX_BLK *pRxBlk); //////////////////////////////////////// + +VOID RTMPIoctlGetSiteSurvey( + IN PRTMP_ADAPTER pAdapter, + IN struct iwreq *wrq); + + + + + + + enum { DIDmsg_lnxind_wlansniffrm = 0x00000044, DIDmsg_lnxind_wlansniffrm_hosttime = 0x00010044, @@ -5712,9 +5146,6 @@ void send_monitor_packets( IN PRTMP_ADAPTER pAd, IN RX_BLK *pRxBlk); -// This function will be called when query /proc -struct iw_statistics *rt28xx_get_wireless_stats( - IN struct net_device *net_dev); VOID RTMPSetDesiredRates( IN PRTMP_ADAPTER pAdapter, @@ -5722,62 +5153,20 @@ VOID RTMPSetDesiredRates( INT Set_FixedTxMode_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); - -static inline char* GetPhyMode( - int Mode) -{ - switch(Mode) - { - case MODE_CCK: - return "CCK"; - - case MODE_OFDM: - return "OFDM"; - case MODE_HTMIX: - return "HTMIX"; - - case MODE_HTGREENFIELD: - return "GREEN"; - default: - return "N/A"; - } -} - - -static inline char* GetBW( - int BW) -{ - switch(BW) - { - case BW_10: - return "10M"; + IN PSTRING arg); - case BW_20: - return "20M"; - case BW_40: - return "40M"; - default: - return "N/A"; - } -} +INT Set_LongRetryLimit_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); -VOID RT28xxThreadTerminate( - IN RTMP_ADAPTER *pAd); +INT Set_ShortRetryLimit_Proc( + IN PRTMP_ADAPTER pAdapter, + IN PSTRING arg); BOOLEAN RT28XXChipsetCheck( IN void *_dev_p); -BOOLEAN RT28XXNetDevInit( - IN void *_dev_p, - IN struct net_device *net_dev, - IN RTMP_ADAPTER *pAd); - -BOOLEAN RT28XXProbePostConfig( - IN void *_dev_p, - IN RTMP_ADAPTER *pAd, - IN INT32 argc); VOID RT28XXDMADisable( IN RTMP_ADAPTER *pAd); @@ -5791,26 +5180,45 @@ VOID RT28xx_UpdateBeaconToAsic( IN ULONG BeaconLen, IN ULONG UpdatePos); -INT rt28xx_sta_ioctl( - IN struct net_device *net_dev, - IN OUT struct ifreq *rq, - IN INT cmd); - -//////////////////////////////////////// -PNDIS_PACKET GetPacketFromRxRing( +int rt28xx_init( IN PRTMP_ADAPTER pAd, - OUT PRT28XX_RXD_STRUC pSaveRxD, - OUT BOOLEAN *pbReschedule, - IN OUT UINT32 *pRxPending); + IN PSTRING pDefaultMac, + IN PSTRING pHostName); + +NDIS_STATUS RtmpNetTaskInit( + IN RTMP_ADAPTER *pAd); +VOID RtmpNetTaskExit( + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS RtmpMgmtTaskInit( + IN RTMP_ADAPTER *pAd); -void kill_thread_task(PRTMP_ADAPTER pAd); +VOID RtmpMgmtTaskExit( + IN RTMP_ADAPTER *pAd); void tbtt_tasklet(unsigned long data); -#ifdef RT2860 + +PNET_DEV RtmpPhyNetDevInit( + IN RTMP_ADAPTER *pAd, + IN RTMP_OS_NETDEV_OP_HOOK *pNetHook); + +BOOLEAN RtmpPhyNetDevExit( + IN RTMP_ADAPTER *pAd, + IN PNET_DEV net_dev); + +INT RtmpRaDevCtrlInit( + IN RTMP_ADAPTER *pAd, + IN RTMP_INF_TYPE infType); + +BOOLEAN RtmpRaDevCtrlExit( + IN RTMP_ADAPTER *pAd); + + +#ifdef RTMP_MAC_PCI // -// Function Prototype in cmm_data_2860.c +// Function Prototype in cmm_data_pci.c // USHORT RtmpPCI_WriteTxResource( IN PRTMP_ADAPTER pAd, @@ -5873,6 +5281,16 @@ NDIS_STATUS RTMPCheckRxError( IN PRXWI_STRUC pRxWI, IN PRT28XX_RXD_STRUC pRxD); +BOOLEAN RT28xxPciAsicRadioOff( + IN PRTMP_ADAPTER pAd, + IN UCHAR Level, + IN USHORT TbttNumToNextWakeUp); + +BOOLEAN RT28xxPciAsicRadioOn( + IN PRTMP_ADAPTER pAd, + IN UCHAR Level); + +#ifdef RTMP_PCI_SUPPORT VOID RTMPInitPCIeLinkCtrlValue( IN PRTMP_ADAPTER pAd); @@ -5887,23 +5305,6 @@ VOID RTMPPCIeLinkCtrlSetting( IN PRTMP_ADAPTER pAd, IN USHORT Max); -VOID RT28xxPciAsicRadioOff( - IN PRTMP_ADAPTER pAd, - IN UCHAR Level, - IN USHORT TbttNumToNextWakeUp); - -BOOLEAN RT28xxPciAsicRadioOn( - IN PRTMP_ADAPTER pAd, - IN UCHAR Level); - -VOID RT28xxPciStaAsicForceWakeup( - IN PRTMP_ADAPTER pAd, - IN UCHAR Level); - -VOID RT28xxPciStaAsicSleepThenAutoWakeup( - IN PRTMP_ADAPTER pAd, - IN USHORT TbttNumToNextWakeUp); - VOID PsPollWakeExec( IN PVOID SystemSpecific1, IN PVOID FunctionContext, @@ -5915,112 +5316,25 @@ VOID RadioOnExec( IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3); +#endif // RTMP_PCI_SUPPORT // -VOID RT28xxPciMlmeRadioOn( - IN PRTMP_ADAPTER pAd); - -VOID RT28xxPciMlmeRadioOFF( - IN PRTMP_ADAPTER pAd); -#endif /* RT2860 */ - -VOID AsicTurnOffRFClk( - IN PRTMP_ADAPTER pAd, - IN UCHAR Channel); - -VOID AsicTurnOnRFClk( - IN PRTMP_ADAPTER pAd, - IN UCHAR Channel); - -NTSTATUS RT30xxWriteRFRegister( - IN PRTMP_ADAPTER pAd, - IN UCHAR RegID, - IN UCHAR Value); - -NTSTATUS RT30xxReadRFRegister( - IN PRTMP_ADAPTER pAd, - IN UCHAR RegID, - IN PUCHAR pValue); - -UCHAR eFuseReadRegisters( - IN PRTMP_ADAPTER pAd, - IN USHORT Offset, - IN USHORT Length, - OUT USHORT* pData); - -VOID eFuseReadPhysical( - IN PRTMP_ADAPTER pAd, - IN PUSHORT lpInBuffer, - IN ULONG nInBufferSize, - OUT PUSHORT lpOutBuffer, - IN ULONG nOutBufferSize -); - -NTSTATUS eFuseRead( - IN PRTMP_ADAPTER pAd, - IN USHORT Offset, - OUT PUCHAR pData, - IN USHORT Length); - -VOID eFusePhysicalWriteRegisters( - IN PRTMP_ADAPTER pAd, - IN USHORT Offset, - IN USHORT Length, - OUT USHORT* pData); - -NTSTATUS eFuseWriteRegisters( - IN PRTMP_ADAPTER pAd, - IN USHORT Offset, - IN USHORT Length, - IN USHORT* pData); - -VOID eFuseWritePhysical( - IN PRTMP_ADAPTER pAd, - PUSHORT lpInBuffer, - ULONG nInBufferSize, - PUCHAR lpOutBuffer, - ULONG nOutBufferSize -); - -NTSTATUS eFuseWrite( - IN PRTMP_ADAPTER pAd, - IN USHORT Offset, - IN PUCHAR pData, - IN USHORT length); - -INT set_eFuseGetFreeBlockCount_Proc( - IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); - -INT set_eFusedump_Proc( - IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); - -INT set_eFuseLoadFromBin_Proc( - IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); - -NTSTATUS eFuseWriteRegistersFromBin( +VOID RT28xxPciStaAsicForceWakeup( IN PRTMP_ADAPTER pAd, - IN USHORT Offset, - IN USHORT Length, - IN USHORT* pData); + IN BOOLEAN bFromTx); -VOID eFusePhysicalReadRegisters( +VOID RT28xxPciStaAsicSleepThenAutoWakeup( IN PRTMP_ADAPTER pAd, - IN USHORT Offset, - IN USHORT Length, - OUT USHORT* pData); + IN USHORT TbttNumToNextWakeUp); -VOID RT30xxLoadRFNormalModeSetup( - IN PRTMP_ADAPTER pAd); -VOID RT30xxLoadRFSleepModeSetup( +VOID RT28xxPciMlmeRadioOn( IN PRTMP_ADAPTER pAd); -VOID RT30xxReverseRFSleepModeSetup( +VOID RT28xxPciMlmeRadioOFF( IN PRTMP_ADAPTER pAd); +#endif // RTMP_MAC_PCI // -#ifdef RT2870 +#ifdef RTMP_MAC_USB // // Function Prototype in rtusb_bulk.c // @@ -6037,6 +5351,10 @@ VOID RTUSBInitHTTxDesc( IN ULONG BulkOutSize, IN usb_complete_t Func); +VOID RTUSBInitRxDesc( + IN PRTMP_ADAPTER pAd, + IN PRX_CONTEXT pRxContext); + VOID RTUSBCleanUpDataBulkOutQueue( IN PRTMP_ADAPTER pAd); @@ -6083,6 +5401,9 @@ VOID RTUSBInitRxDesc( IN PRTMP_ADAPTER pAd, IN PRX_CONTEXT pRxContext); +VOID RTUSBBulkRxHandle( + IN unsigned long data); + // // Function Prototype in rtusb_io.c // @@ -6168,36 +5489,19 @@ VOID RTUSBDequeueCmd( INT RTUSBCmdThread( IN OUT PVOID Context); -INT TimerQThread( - IN OUT PVOID Context); - -RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert( - IN RTMP_ADAPTER *pAd, - IN RALINK_TIMER_STRUCT *pTimer); - -BOOLEAN RT2870_TimerQ_Remove( - IN RTMP_ADAPTER *pAd, - IN RALINK_TIMER_STRUCT *pTimer); - -void RT2870_TimerQ_Exit( - IN RTMP_ADAPTER *pAd); - -void RT2870_TimerQ_Init( +VOID RTUSBBssBeaconExit( IN RTMP_ADAPTER *pAd); -VOID RT2870_BssBeaconExit( +VOID RTUSBBssBeaconStop( IN RTMP_ADAPTER *pAd); -VOID RT2870_BssBeaconStop( - IN RTMP_ADAPTER *pAd); - -VOID RT2870_BssBeaconStart( +VOID RTUSBBssBeaconStart( IN RTMP_ADAPTER * pAd); -VOID RT2870_BssBeaconInit( +VOID RTUSBBssBeaconInit( IN RTMP_ADAPTER *pAd); -VOID RT2870_WatchDog( +VOID RTUSBWatchDog( IN RTMP_ADAPTER *pAd); NTSTATUS RTUSBWriteMACRegister( @@ -6215,28 +5519,27 @@ NTSTATUS RTUSBSingleWrite( IN USHORT Offset, IN USHORT Value); -NTSTATUS RTUSBFirmwareRun( - IN PRTMP_ADAPTER pAd); - NTSTATUS RTUSBFirmwareWrite( IN PRTMP_ADAPTER pAd, IN PUCHAR pFwImage, IN ULONG FwLen); -NTSTATUS RTUSBFirmwareOpmode( - IN PRTMP_ADAPTER pAd, - OUT PUINT32 pValue); - NTSTATUS RTUSBVenderReset( IN PRTMP_ADAPTER pAd); -VOID CMDHandler( - IN PRTMP_ADAPTER pAd); +NDIS_STATUS RTUSBSetHardWareRegister( + IN PRTMP_ADAPTER pAdapter, + IN PVOID pBuf); +NDIS_STATUS RTUSBQueryHardWareRegister( + IN PRTMP_ADAPTER pAdapter, + IN PVOID pBuf); -NDIS_STATUS CreateThreads( - IN struct net_device *net_dev ); +VOID CMDHandler( + IN PRTMP_ADAPTER pAd); +NDIS_STATUS RTUSBWriteHWMACAddress( + IN PRTMP_ADAPTER pAdapter); VOID MacTableInitialize( IN PRTMP_ADAPTER pAd); @@ -6252,12 +5555,30 @@ NDIS_STATUS RTMPWPAAddKeyProc( VOID AsicRxAntEvalAction( IN PRTMP_ADAPTER pAd); +void append_pkt( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pHeader802_3, + IN UINT HdrLen, + IN PUCHAR pData, + IN ULONG DataSize, + OUT PNDIS_PACKET *ppPacket); + +UINT deaggregate_AMSDU_announce( + IN PRTMP_ADAPTER pAd, + PNDIS_PACKET pPacket, + IN PUCHAR pData, + IN ULONG DataSize); + NDIS_STATUS RTMPCheckRxError( IN PRTMP_ADAPTER pAd, IN PHEADER_802_11 pHeader, IN PRXWI_STRUC pRxWI, IN PRT28XX_RXD_STRUC pRxINFO); +VOID RTUSBMlmeHardTransmit( + IN PRTMP_ADAPTER pAd, + IN PMGMT_STRUC pMgmt); + INT MlmeThread( IN PVOID Context); @@ -6285,7 +5606,7 @@ VOID RTMPWriteTxInfo( IN UCHAR TxBurst); // -// Function Prototype in cmm_data_2870.c +// Function Prototype in cmm_data_usb.c // USHORT RtmpUSB_WriteSubTxResource( IN PRTMP_ADAPTER pAd, @@ -6315,9 +5636,6 @@ VOID RtmpUSB_FinalWriteTxResource( IN PRTMP_ADAPTER pAd, IN TX_BLK *pTxBlk, IN USHORT totalMPDUSize, -#ifdef RT2860 - IN USHORT FirstTxIdx); -#endif IN USHORT TxIdx); VOID RtmpUSBDataLastTxIdx( @@ -6344,6 +5662,12 @@ VOID RtmpUSBNullFrameKickOut( IN UCHAR *pNullFrame, IN UINT32 frameLen); +VOID RtmpUsbStaAsicForceWakeupTimeout( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); + VOID RT28xxUsbStaAsicForceWakeup( IN PRTMP_ADAPTER pAd, IN BOOLEAN bFromTx); @@ -6357,44 +5681,72 @@ VOID RT28xxUsbMlmeRadioOn( VOID RT28xxUsbMlmeRadioOFF( IN PRTMP_ADAPTER pAd); -#endif // RT2870 // +#endif // RTMP_MAC_USB // + +VOID AsicTurnOffRFClk( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel); + +VOID AsicTurnOnRFClk( + IN PRTMP_ADAPTER pAd, + IN UCHAR Channel); + + + +#ifdef RTMP_TIMER_TASK_SUPPORT +INT RtmpTimerQThread( + IN OUT PVOID Context); + +RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert( + IN RTMP_ADAPTER *pAd, + IN RALINK_TIMER_STRUCT *pTimer); +BOOLEAN RtmpTimerQRemove( + IN RTMP_ADAPTER *pAd, + IN RALINK_TIMER_STRUCT *pTimer); + +void RtmpTimerQExit( + IN RTMP_ADAPTER *pAd); + +void RtmpTimerQInit( + IN RTMP_ADAPTER *pAd); +#endif // RTMP_TIMER_TASK_SUPPORT // + +/////////////////////////////////////// INT RTMPShowCfgValue( IN PRTMP_ADAPTER pAd, - IN PUCHAR pName, - IN PUCHAR pBuf); + IN PSTRING pName, + IN PSTRING pBuf); -PCHAR RTMPGetRalinkAuthModeStr( +PSTRING RTMPGetRalinkAuthModeStr( IN NDIS_802_11_AUTHENTICATION_MODE authMode); -PCHAR RTMPGetRalinkEncryModeStr( +PSTRING RTMPGetRalinkEncryModeStr( IN USHORT encryMode); +////////////////////////////////////// VOID AsicStaBbpTuning( IN PRTMP_ADAPTER pAd); -#ifdef RT2860 -VOID AsicResetFromDMABusy( - IN PRTMP_ADAPTER pAd); - -VOID AsicResetBBP( - IN PRTMP_ADAPTER pAd); - -VOID AsicResetMAC( - IN PRTMP_ADAPTER pAd); - -VOID AsicResetPBF( - IN PRTMP_ADAPTER pAd); -#endif -#ifdef RT2870 BOOLEAN StaAddMacTableEntry( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN UCHAR MaxSupportedRateIn500Kbps, IN HT_CAPABILITY_IE *pHtCapability, IN UCHAR HtCapabilityLen, + IN ADD_HT_INFO_IE *pAddHtInfo, + IN UCHAR AddHtInfoLen, IN USHORT CapabilityInfo); -#endif + + +BOOLEAN AUTH_ReqSend( + IN PRTMP_ADAPTER pAd, + IN PMLME_QUEUE_ELEM pElem, + IN PRALINK_TIMER_STRUCT pAuthTimer, + IN PSTRING pSMName, + IN USHORT SeqNo, + IN PUCHAR pNewElement, + IN ULONG ElementLen); void RTMP_IndicateMediaState( IN PRTMP_ADAPTER pAd); @@ -6409,13 +5761,23 @@ VOID RTMPSetAGCInitValue( int rt28xx_close(IN PNET_DEV dev); int rt28xx_open(IN PNET_DEV dev); + +#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++) +#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--) +#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt) + + +#ifdef LINUX __inline INT VIRTUAL_IF_UP(PRTMP_ADAPTER pAd) { if (VIRTUAL_IF_NUM(pAd) == 0) { if (rt28xx_open(pAd->net_dev) != 0) + { + DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_open return fail!\n")); return -1; } + } else { } @@ -6430,6 +5792,107 @@ __inline VOID VIRTUAL_IF_DOWN(PRTMP_ADAP rt28xx_close(pAd->net_dev); return; } +#endif // LINUX // + + +/* + OS Related funciton prototype definitions. + TODO: Maybe we need to move these function prototypes to other proper place. +*/ +int RtmpOSWrielessEventSend( + IN RTMP_ADAPTER *pAd, + IN UINT32 eventType, + IN INT flags, + IN PUCHAR pSrcMac, + IN PUCHAR pData, + IN UINT32 dataLen); + +int RtmpOSNetDevAddrSet( + IN PNET_DEV pNetDev, + IN PUCHAR pMacAddr); + +int RtmpOSNetDevAttach( + IN PNET_DEV pNetDev, + IN RTMP_OS_NETDEV_OP_HOOK *pDevOpHook); + +void RtmpOSNetDevClose( + IN PNET_DEV pNetDev); + +void RtmpOSNetDevDetach( + IN PNET_DEV pNetDev); + +INT RtmpOSNetDevAlloc( + IN PNET_DEV *pNewNetDev, + IN UINT32 privDataSize); + +void RtmpOSNetDevFree( + IN PNET_DEV pNetDev); + +PNET_DEV RtmpOSNetDevGetByName( + IN PNET_DEV pNetDev, + IN PSTRING pDevName); + +void RtmpOSNetDeviceRefPut( + IN PNET_DEV pNetDev); + +PNET_DEV RtmpOSNetDevCreate( + IN RTMP_ADAPTER *pAd, + IN INT devType, + IN INT devNum, + IN INT privMemSize, + IN PSTRING pNamePrefix); + +/* + Task operation related function prototypes +*/ +void RtmpOSTaskCustomize( + IN RTMP_OS_TASK *pTask); + +INT RtmpOSTaskNotifyToExit( + IN RTMP_OS_TASK *pTask); + +NDIS_STATUS RtmpOSTaskKill( + IN RTMP_OS_TASK *pTask); + +NDIS_STATUS RtmpOSTaskInit( + IN RTMP_OS_TASK *pTask, + PSTRING pTaskName, + VOID *pPriv); + +NDIS_STATUS RtmpOSTaskAttach( + IN RTMP_OS_TASK *pTask, + IN int (*fn)(void *), + IN void *arg); + + +/* + File operation related function prototypes +*/ +RTMP_OS_FD RtmpOSFileOpen( + IN char *pPath, + IN int flag, + IN int mode); + +int RtmpOSFileClose( + IN RTMP_OS_FD osfd); + +void RtmpOSFileSeek( + IN RTMP_OS_FD osfd, + IN int offset); + +int RtmpOSFileRead( + IN RTMP_OS_FD osfd, + IN char *pDataPtr, + IN int readLen); + +int RtmpOSFileWrite( + IN RTMP_OS_FD osfd, + IN char *pDataPtr, + IN int writeLen); + +void RtmpOSFSInfoChange( + IN RTMP_OS_FS_INFO *pOSFSInfo, + IN BOOLEAN bSet); #endif // __RTMP_H__ Index: b/drivers/staging/rt2860/rtmp_chip.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/rtmp_chip.h @@ -0,0 +1,265 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rtmp_chip.h + + Abstract: + Ralink Wireless Chip related definition & structures + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifndef __RTMP_CHIP_H__ +#define __RTMP_CHIP_H__ + +#include "rtmp_type.h" + +#ifdef RT2860 +#include "chip/rt2860.h" +#endif // RT2860 // +#ifdef RT2870 +#include "chip/rt2870.h" +#endif // RT2870 // +#ifdef RT3070 +#include "chip/rt3070.h" +#endif // RT3070 // + +// We will have a cost down version which mac version is 0x3090xxxx +// +// RT3090A facts +// +// a) 2.4 GHz +// b) Replacement for RT3090 +// c) Internal LNA +// d) Interference over channel #14 +// e) New BBP features (e.g., SIG re-modulation) +// +#define IS_RT3090A(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x30900000)) + +// We will have a cost down version which mac version is 0x3090xxxx +#define IS_RT3090(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (IS_RT3090A(_pAd))) + +#define IS_RT3070(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30700000) +#define IS_RT3071(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30710000) +#define IS_RT2070(_pAd) (((_pAd)->RfIcType == RFIC_2020) || ((_pAd)->EFuseTag == 0x27)) + +#define IS_RT30xx(_pAd) (((_pAd)->MACVersion & 0xfff00000) == 0x30700000||IS_RT3090A(_pAd)) +//#define IS_RT305X(_pAd) ((_pAd)->MACVersion == 0x28720200) + +/* RT3572, 3592, 3562, 3062 share the same MAC version */ +#define IS_RT3572(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x35720000) +#define IS_VERSION_BEFORE_F(_pAd) (((_pAd)->MACVersion&0xffff) <= 0x0211) +// F version is 0x0212, E version is 0x0211. 309x can save more power after F version. +#define IS_VERSION_AFTER_F(_pAd) ((((_pAd)->MACVersion&0xffff) >= 0x0212) || (((_pAd)->b3090ESpecialChip == TRUE))) +// +// RT3390 facts +// +// a) Base on RT3090 (RF IC: RT3020) +// b) 2.4 GHz +// c) 1x1 +// d) Single chip +// e) Internal components: PA and LNA +// +//RT3390,RT3370 +#define IS_RT3390(_pAd) (((_pAd)->MACVersion & 0xFFFF0000) == 0x33900000) + +// ------------------------------------------------------ +// PCI registers - base address 0x0000 +// ------------------------------------------------------ +#define CHIP_PCI_CFG 0x0000 +#define CHIP_PCI_EECTRL 0x0004 +#define CHIP_PCI_MCUCTRL 0x0008 + +#define OPT_14 0x114 + +#define RETRY_LIMIT 10 + + + +// ------------------------------------------------------ +// BBP & RF definition +// ------------------------------------------------------ +#define BUSY 1 +#define IDLE 0 + + +//------------------------------------------------------------------------- +// EEPROM definition +//------------------------------------------------------------------------- +#define EEDO 0x08 +#define EEDI 0x04 +#define EECS 0x02 +#define EESK 0x01 +#define EERL 0x80 + +#define EEPROM_WRITE_OPCODE 0x05 +#define EEPROM_READ_OPCODE 0x06 +#define EEPROM_EWDS_OPCODE 0x10 +#define EEPROM_EWEN_OPCODE 0x13 + +#define NUM_EEPROM_BBP_PARMS 19 // Include NIC Config 0, 1, CR, TX ALC step, BBPs +#define NUM_EEPROM_TX_G_PARMS 7 +#define EEPROM_NIC1_OFFSET 0x34 // The address is from NIC config 0, not BBP register ID +#define EEPROM_NIC2_OFFSET 0x36 // The address is from NIC config 0, not BBP register ID +#define EEPROM_BBP_BASE_OFFSET 0xf0 // The address is from NIC config 0, not BBP register ID +#define EEPROM_G_TX_PWR_OFFSET 0x52 +#define EEPROM_G_TX2_PWR_OFFSET 0x60 +#define EEPROM_LED1_OFFSET 0x3c +#define EEPROM_LED2_OFFSET 0x3e +#define EEPROM_LED3_OFFSET 0x40 +#define EEPROM_LNA_OFFSET 0x44 +#define EEPROM_RSSI_BG_OFFSET 0x46 +#define EEPROM_TXMIXER_GAIN_2_4G 0x48 +#define EEPROM_RSSI_A_OFFSET 0x4a +#define EEPROM_TXMIXER_GAIN_5G 0x4c +#define EEPROM_DEFINE_MAX_TXPWR 0x4e +#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G 0xde // 20MHZ 2.4G tx power. +#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G 0xee // 40MHZ 2.4G tx power. +#define EEPROM_TXPOWER_BYRATE_20MHZ_5G 0xfa // 20MHZ 5G tx power. +#define EEPROM_TXPOWER_BYRATE_40MHZ_5G 0x10a // 40MHZ 5G tx power. +#define EEPROM_A_TX_PWR_OFFSET 0x78 +#define EEPROM_A_TX2_PWR_OFFSET 0xa6 +//#define EEPROM_Japan_TX_PWR_OFFSET 0x90 // 802.11j +//#define EEPROM_Japan_TX2_PWR_OFFSET 0xbe +//#define EEPROM_TSSI_REF_OFFSET 0x54 +//#define EEPROM_TSSI_DELTA_OFFSET 0x24 +//#define EEPROM_CCK_TX_PWR_OFFSET 0x62 +//#define EEPROM_CALIBRATE_OFFSET 0x7c +#define EEPROM_VERSION_OFFSET 0x02 +#define EEPROM_FREQ_OFFSET 0x3a +#define EEPROM_TXPOWER_BYRATE 0xde // 20MHZ power. +#define EEPROM_TXPOWER_DELTA 0x50 // 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ. +#define VALID_EEPROM_VERSION 1 + + +/* + * EEPROM operation related marcos + */ +#define RT28xx_EEPROM_READ16(_pAd, _offset, _value) \ + (_pAd)->chipOps.eeread((RTMP_ADAPTER *)(_pAd), (USHORT)(_offset), (PUSHORT)&(_value)) + +#define RT28xx_EEPROM_WRITE16(_pAd, _offset, _value) \ + (_pAd)->chipOps.eewrite((RTMP_ADAPTER *)(_pAd), (USHORT)(_offset), (USHORT)(_value)) + + + +// ------------------------------------------------------------------- +// E2PROM data layout +// ------------------------------------------------------------------- + +// +// MCU_LEDCS: MCU LED Control Setting. +// +typedef union _MCU_LEDCS_STRUC { + struct { + UCHAR LedMode:7; + UCHAR Polarity:1; + } field; + UCHAR word; +} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC; + + +// +// EEPROM antenna select format +// +typedef union _EEPROM_ANTENNA_STRUC { + struct { + USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R + USHORT TxPath:4; // 1: 1T, 2: 2T + USHORT RfIcType:4; // see E2PROM document + USHORT Rsv:4; + } field; + USHORT word; +} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC; + +typedef union _EEPROM_NIC_CINFIG2_STRUC { + struct { + USHORT HardwareRadioControl:1; // 1:enable, 0:disable + USHORT DynamicTxAgcControl:1; // + USHORT ExternalLNAForG:1; // + USHORT ExternalLNAForA:1; // external LNA enable for 2.4G + USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable + USHORT BW40MSidebandForG:1; + USHORT BW40MSidebandForA:1; + USHORT EnableWPSPBC:1; // WPS PBC Control bit + USHORT BW40MAvailForG:1; // 0:enable, 1:disable + USHORT BW40MAvailForA:1; // 0:enable, 1:disable + USHORT Rsv1:1; // must be 0 + USHORT AntDiversity:1; // Antenna diversity + USHORT Rsv2:3; // must be 0 + USHORT DACTestBit:1; // control if driver should patch the DAC issue + } field; + USHORT word; +} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC; + +// +// TX_PWR Value valid range 0xFA(-6) ~ 0x24(36) +// +typedef union _EEPROM_TX_PWR_STRUC { + struct { + CHAR Byte0; // Low Byte + CHAR Byte1; // High Byte + } field; + USHORT word; +} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC; + +typedef union _EEPROM_VERSION_STRUC { + struct { + UCHAR FaeReleaseNumber; // Low Byte + UCHAR Version; // High Byte + } field; + USHORT word; +} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC; + +typedef union _EEPROM_LED_STRUC { + struct { + USHORT PolarityRDY_G:1; // Polarity RDY_G setting. + USHORT PolarityRDY_A:1; // Polarity RDY_A setting. + USHORT PolarityACT:1; // Polarity ACT setting. + USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting. + USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting. + USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting. + USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting. + USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting. + USHORT LedMode:5; // Led mode. + USHORT Rsvd:3; // Reserved + } field; + USHORT word; +} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC; + +typedef union _EEPROM_TXPOWER_DELTA_STRUC { + struct { + UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4) + UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value + UCHAR TxPowerEnable:1;// Enable + } field; + UCHAR value; +} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC; + +#endif // __RTMP_CHIP_H__ // Index: b/drivers/staging/rt2860/rtmp_ckipmic.h =================================================================== --- a/drivers/staging/rt2860/rtmp_ckipmic.h +++ b/drivers/staging/rt2860/rtmp_ckipmic.h @@ -46,6 +46,24 @@ typedef struct _MIC_CONTEXT { UCHAR part[4]; /* for conversion of message to u32 for mmh */ } MIC_CONTEXT, *PMIC_CONTEXT; +VOID CKIP_key_permute( + OUT UCHAR *PK, /* output permuted key */ + IN UCHAR *CK, /* input CKIP key */ + IN UCHAR toDsFromDs, /* input toDs/FromDs bits */ + IN UCHAR *piv); /* input pointer to IV */ + +VOID RTMPCkipMicInit( + IN PMIC_CONTEXT pContext, + IN PUCHAR CK); + +VOID RTMPMicUpdate( + IN PMIC_CONTEXT pContext, + IN PUCHAR pOctets, + IN INT len); + +ULONG RTMPMicGetCoefficient( + IN PMIC_CONTEXT pContext); + VOID xor_128( IN PUCHAR a, IN PUCHAR b, @@ -75,4 +93,21 @@ VOID mix_column( IN PUCHAR in, OUT PUCHAR out); +VOID RTMPAesEncrypt( + IN PUCHAR key, + IN PUCHAR data, + IN PUCHAR ciphertext); + +VOID RTMPMicFinal( + IN PMIC_CONTEXT pContext, + OUT UCHAR digest[4]); + +VOID RTMPCkipInsertCMIC( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pMIC, + IN PUCHAR p80211hdr, + IN PNDIS_PACKET pPacket, + IN PCIPHER_KEY pKey, + IN PUCHAR mic_snap); + #endif //__RTMP_CKIPMIC_H__ Index: b/drivers/staging/rt2860/rtmp_def.h =================================================================== --- a/drivers/staging/rt2860/rtmp_def.h +++ b/drivers/staging/rt2860/rtmp_def.h @@ -41,6 +41,15 @@ #include "oid.h" +#undef AP_WSC_INCLUDED +#undef STA_WSC_INCLUDED +#undef WSC_INCLUDED + + + +#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED) +#define WSC_INCLUDED +#endif // // Debug information verbosity: lower values indicate higher urgency // @@ -54,55 +63,28 @@ #define NIC_TAG ((ULONG)'0682') #define NIC_DBG_STRING ("**RT28xx**") +#ifdef RTMP_MAC_USB +#define TX_RING_SIZE 8 // 1 +#define PRIO_RING_SIZE 8 +#define MGMT_RING_SIZE 32 // PRIO_RING_SIZE +#define RX_RING_SIZE 8 +#define MAX_TX_PROCESS 4 +#define LOCAL_TXBUF_SIZE 2048 +#endif // RTMP_MAC_USB // + +//#define PACKED + #define RALINK_2883_VERSION ((UINT32)0x28830300) #define RALINK_2880E_VERSION ((UINT32)0x28720200) #define RALINK_3070_VERSION ((UINT32)0x30700200) -// -// NDIS version in use by the NIC driver. -// The high byte is the major version. The low byte is the minor version. -// -#ifdef NDIS51_MINIPORT -#define NIC_DRIVER_VERSION 0x0501 -#else -#define NIC_DRIVER_VERSION 0x0500 -#endif - -// -// NDIS media type, current is ethernet, change if native wireless supported -// -#define NIC_MEDIA_TYPE NdisMedium802_3 -#define NIC_PCI_HDR_LENGTH 0xe2 -#define NIC_MAX_PACKET_SIZE 2304 -#define NIC_HEADER_SIZE 14 -#define MAX_MAP_REGISTERS_NEEDED 32 -#define MIN_MAP_REGISTERS_NEEDED 2 //Todo: should consider fragment issue. - -// -// interface type, we use PCI -// -#define NIC_INTERFACE_TYPE NdisInterfacePci -#define NIC_INTERRUPT_MODE NdisInterruptLevelSensitive - -// -// buffer size passed in NdisMQueryAdapterResources -// We should only need three adapter resources (IO, interrupt and memory), -// Some devices get extra resources, so have room for 10 resources -// UF_SIZE (sizeof(NDIS_RESOURCE_LIST) + (10*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR))) - - -#define NIC_RESOURCE_B// -// IO space length -// -#define NIC_MAP_IOSPACE_LENGTH sizeof(CSR_STRUC) - #define MAX_RX_PKT_LEN 1520 // // Entry number for each DMA descriptor ring // -#ifdef RT2860 +#ifdef RTMP_MAC_PCI #define TX_RING_SIZE 64 //64 #define MGMT_RING_SIZE 128 #define RX_RING_SIZE 128 //64 @@ -110,15 +92,7 @@ #define MAX_DMA_DONE_PROCESS TX_RING_SIZE #define MAX_TX_DONE_PROCESS TX_RING_SIZE //8 #define LOCAL_TXBUF_SIZE 2 -#endif -#ifdef RT2870 -#define TX_RING_SIZE 8 // 1 -#define PRIO_RING_SIZE 8 -#define MGMT_RING_SIZE 32 // PRIO_RING_SIZE -#define RX_RING_SIZE 8 -#define MAX_TX_PROCESS 4 -#define LOCAL_TXBUF_SIZE 2048 -#endif // RT2870 // +#endif // RTMP_MAC_PCI // #define MAX_RX_PROCESS 128 //64 //32 #define NUM_OF_LOCAL_TXBUF 2 @@ -143,16 +117,43 @@ #define MAX_RX_PROCESS_CNT (RX_RING_SIZE) +/* + WMM Note: If memory of your system is not much, please reduce the definition; + or when you do WMM test, the queue for low priority AC will be full, i.e. + TX_RING_SIZE + MAX_PACKETS_IN_QUEUE packets for the AC will be buffered in + WLAN, maybe no any packet buffer can be got in Ethernet driver. + + Sometimes no packet buffer can be got in Ethernet driver, the system will + send flow control packet to the sender to slow down its sending rate. + So no WMM can be saw in the air. +*/ + +/* + Need to use 64 in vxworks for test case WMM A5-T07 + Two dnlink (10Mbps) from a WMM station to a non-WMM station. + If use 256, queue is not enough. + And in rt_main_end.c, clConfig.clNum = RX_RING_SIZE * 3; is changed to + clConfig.clNum = RX_RING_SIZE * 4; +*/ +// TODO: For VxWorks the size is 256. Shall we cahnge the value as 256 for all OS????? #define MAX_PACKETS_IN_QUEUE (512) //(512) // to pass WMM A5-WPAPSK + #define MAX_PACKETS_IN_MCAST_PS_QUEUE 32 #define MAX_PACKETS_IN_PS_QUEUE 128 //32 #define WMM_NUM_OF_AC 4 /* AC0, AC1, AC2, and AC3 */ + +#ifdef RTMP_EFUSE_SUPPORT +//2008/09/11:KH add to support efuse<-- #define MAX_EEPROM_BIN_FILE_SIZE 1024 +#define EFUSE_BUFFER_PATH "/tmp/RT30xxEEPROM.bin" +//2008/09/11:KH add to support efuse--> +#endif // RTMP_EFUSE_SUPPORT // // RxFilter #define STANORMAL 0x17f97 #define APNORMAL 0x15f97 +#define PSPXLINK 0x17f93 // // RTMP_ADAPTER flags // @@ -185,6 +186,16 @@ #define fRTMP_ADAPTER_MEDIA_STATE_CHANGE 0x20000000 #define fRTMP_ADAPTER_IDLE_RADIO_OFF 0x40000000 +// Lock bit for accessing different ring buffers +//#define fRTMP_ADAPTER_TX_RING_BUSY 0x80000000 +//#define fRTMP_ADAPTER_MGMT_RING_BUSY 0x40000000 +//#define fRTMP_ADAPTER_ATIM_RING_BUSY 0x20000000 +//#define fRTMP_ADAPTER_RX_RING_BUSY 0x10000000 + +// Lock bit for accessing different queue +//#define fRTMP_ADAPTER_TX_QUEUE_BUSY 0x08000000 +//#define fRTMP_ADAPTER_MGMT_QUEUE_BUSY 0x04000000 + // // STA operation status flags // @@ -194,6 +205,7 @@ #define fOP_STATUS_SHORT_SLOT_INUSED 0x00000008 #define fOP_STATUS_SHORT_PREAMBLE_INUSED 0x00000010 #define fOP_STATUS_RECEIVE_DTIM 0x00000020 +//#define fOP_STATUS_TX_RATE_SWITCH_ENABLED 0x00000040 #define fOP_STATUS_MEDIA_STATE_CONNECTED 0x00000080 #define fOP_STATUS_WMM_INUSED 0x00000100 #define fOP_STATUS_AGGREGATION_INUSED 0x00000200 @@ -203,9 +215,9 @@ #define fOP_STATUS_TX_AMSDU_INUSED 0x00002000 #define fOP_STATUS_MAX_RETRY_ENABLED 0x00004000 #define fOP_STATUS_WAKEUP_NOW 0x00008000 -#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE 0x00020000 +#define fOP_STATUS_PCIE_DEVICE 0x00020000 +#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE fOP_STATUS_PCIE_DEVICE -#ifdef RT2860 // // RTMP_ADAPTER PSFlags : related to advanced power save. // @@ -218,7 +230,8 @@ // Indicate driver should IMMEDIATELY fo to sleep after receiving AP's beacon in which doesn't indicate unicate nor multicast packets for me //. This flag is used ONLY in RTMPHandleRxDoneInterrupt routine. #define fRTMP_PS_GO_TO_SLEEP_NOW 0x00000008 -#endif +#define fRTMP_PS_TOGGLE_L1 0x00000010 // Use Toggle L1 mechanism for rt28xx PCIe + #define CCKSETPROTECT 0x1 #define OFDMSETPROTECT 0x2 @@ -248,6 +261,7 @@ // // STA configuration flags // +//#define fSTA_CFG_ENABLE_TX_BURST 0x00000001 // 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case #define HT_NO_PROTECT 0 @@ -266,6 +280,7 @@ #define fRX_FILTER_ACCEPT_MULTICAST NDIS_PACKET_TYPE_MULTICAST #define fRX_FILTER_ACCEPT_BROADCAST NDIS_PACKET_TYPE_BROADCAST #define fRX_FILTER_ACCEPT_ALL_MULTICAST NDIS_PACKET_TYPE_ALL_MULTICAST +#define fRX_FILTER_ACCEPT_PROMISCUOUS NDIS_PACKET_TYPE_PROMISCUOUS // // Error code section @@ -321,17 +336,15 @@ #define MAX_APCLI_NUM 0 #define MAX_MBSSID_NUM 1 -#if defined(RT2860) || defined(RT30xx) #ifdef MBSS_SUPPORT #undef MAX_MBSSID_NUM #define MAX_MBSSID_NUM (8 - MAX_MESH_NUM - MAX_APCLI_NUM) #endif // MBSS_SUPPORT // -#endif /* sanity check for apidx */ #define MBSS_MR_APIDX_SANITY_CHECK(apidx) \ { if (apidx > MAX_MBSSID_NUM) { \ - printk("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __func__, apidx); \ + DBGPRINT(RT_DEBUG_ERROR, ("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __func__, apidx)); \ apidx = MAIN_MBSSID; } } #define VALID_WCID(_wcid) ((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE ) @@ -397,6 +410,7 @@ #define HASH_TABLE_SIZE 256 #define MAX_VIE_LEN 1024 // New for WPA cipher suite variable IE sizes. #define MAX_SUPPORT_MCS 32 +#define MAX_NUM_OF_BBP_LATCH 140 //============================================================ // ASIC WCID Table definition. @@ -448,10 +462,14 @@ #define PWR_ACTIVE 0 #define PWR_SAVE 1 #define PWR_MMPS 2 //MIMO power save +//#define PWR_UNKNOWN 2 // Auth and Assoc mode related definitions #define AUTH_MODE_OPEN 0x00 #define AUTH_MODE_KEY 0x01 +//#define AUTH_MODE_AUTO_SWITCH 0x03 +//#define AUTH_MODE_DEAUTH 0x04 +//#define AUTH_MODE_UPLAYER 0x05 // reserved for 802.11i use // BSS Type definitions #define BSS_ADHOC 0 // = Ndis802_11IBSS @@ -515,6 +533,9 @@ #define MLME_QOS_UNSPECIFY 32 #define MLME_REQUEST_DECLINED 37 #define MLME_REQUEST_WITH_INVALID_PARAM 38 +#define MLME_INVALID_GROUP_CIPHER 41 +#define MLME_INVALID_PAIRWISE_CIPHER 42 +#define MLME_INVALID_AKMP 43 #define MLME_DLS_NOT_ALLOW_IN_QBSS 48 #define MLME_DEST_STA_NOT_IN_QBSS 49 #define MLME_DEST_STA_IS_NOT_A_QSTA 50 @@ -569,6 +590,7 @@ // For 802.11n D3.03 //#define IE_NEW_EXT_CHA_OFFSET 62 // 802.11n d1. New extension channel offset elemet #define IE_SECONDARY_CH_OFFSET 62 // 802.11n D3.03 Secondary Channel Offset element +#define IE_WAPI 68 // WAPI information element #define IE_2040_BSS_COEXIST 72 // 802.11n D3.0.3 #define IE_2040_BSS_INTOLERANT_REPORT 73 // 802.11n D3.03 #define IE_OVERLAPBSS_SCAN_PARM 74 // 802.11n D3.03 @@ -605,17 +627,22 @@ #define SYNC_STATE_MACHINE 4 #define MLME_CNTL_STATE_MACHINE 5 #define WPA_PSK_STATE_MACHINE 6 -#define LEAP_STATE_MACHINE 7 +//#define LEAP_STATE_MACHINE 7 #define AIRONET_STATE_MACHINE 8 #define ACTION_STATE_MACHINE 9 // AP MLME state machines #define AP_ASSOC_STATE_MACHINE 11 #define AP_AUTH_STATE_MACHINE 12 -#define AP_AUTH_RSP_STATE_MACHINE 13 #define AP_SYNC_STATE_MACHINE 14 #define AP_CNTL_STATE_MACHINE 15 -#define AP_WPA_STATE_MACHINE 16 +#define WSC_STATE_MACHINE 17 +#define WSC_UPNP_STATE_MACHINE 18 + + +#define WPA_STATE_MACHINE 23 + + // // STA's CONTROL/CONNECT state machine: states, events, total function # @@ -630,9 +657,9 @@ #define CNTL_WAIT_AUTH2 7 #define CNTL_WAIT_OID_LIST_SCAN 8 #define CNTL_WAIT_OID_DISASSOC 9 -#ifdef RT2870 +#ifdef RTMP_MAC_USB #define CNTL_WAIT_SCAN_FOR_CONNECT 10 -#endif // RT2870 // +#endif // RTMP_MAC_USB // #define MT2_ASSOC_CONF 34 #define MT2_AUTH_CONF 35 @@ -646,6 +673,7 @@ #define MT2_GET_CONF 43 #define MT2_SET_CONF 44 #define MT2_RESET_CONF 45 +#define MT2_FT_OTD_CONF 46 #define MT2_MLME_ROAMING_REQ 52 #define CNTL_FUNC_SIZE 1 @@ -691,8 +719,11 @@ #define MT2_PEER_BA_CATE 3 #define MT2_PEER_PUBLIC_CATE 4 #define MT2_PEER_RM_CATE 5 +/* "FT_CATEGORY_BSS_TRANSITION equal to 6" is defined file of "dot11r_ft.h" */ #define MT2_PEER_HT_CATE 7 // 7.4.7 #define MAX_PEER_CATE_MSG 7 + + #define MT2_MLME_ADD_BA_CATE 8 #define MT2_MLME_ORI_DELBA_CATE 9 #define MT2_MLME_REC_DELBA_CATE 10 @@ -822,35 +853,8 @@ #define DLS_FUNC_SIZE (MAX_DLS_STATE * MAX_DLS_MSG) // -// STA's WPA-PSK State machine: states, events, total function # -// -#define WPA_PSK_IDLE 0 -#define MAX_WPA_PSK_STATE 1 - -#define WPA_MACHINE_BASE 0 -#define MT2_EAPPacket 0 -#define MT2_EAPOLStart 1 -#define MT2_EAPOLLogoff 2 -#define MT2_EAPOLKey 3 -#define MT2_EAPOLASFAlert 4 -#define MAX_WPA_PSK_MSG 5 - -#define WPA_PSK_FUNC_SIZE (MAX_WPA_PSK_STATE * MAX_WPA_PSK_MSG) - -// -// STA's CISCO-AIRONET State machine: states, events, total function # +// WSC State machine: states, events, total function # // -#define AIRONET_IDLE 0 -#define AIRONET_SCANNING 1 -#define MAX_AIRONET_STATE 2 - -#define AIRONET_MACHINE_BASE 0 -#define MT2_AIRONET_MSG 0 -#define MT2_AIRONET_SCAN_REQ 1 -#define MT2_AIRONET_SCAN_DONE 2 -#define MAX_AIRONET_MSG 3 - -#define AIRONET_FUNC_SIZE (MAX_AIRONET_STATE * MAX_AIRONET_MSG) // // AP's CONTROL/CONNECT state machine: states, events, total function # @@ -882,23 +886,12 @@ #define AP_AUTH_MACHINE_BASE 0 #define APMT2_MLME_DEAUTH_REQ 0 #define APMT2_CLS2ERR 1 -#define AP_MAX_AUTH_MSG 2 - -#define AP_AUTH_FUNC_SIZE (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG) - -// -// AP's AUTH-RSP state machine: states, events, total function # -// -#define AP_AUTH_RSP_IDLE 0 -#define AP_MAX_AUTH_RSP_STATE 1 - -#define AP_AUTH_RSP_MACHINE_BASE 0 -#define APMT2_AUTH_CHALLENGE_TIMEOUT 0 -#define APMT2_PEER_AUTH_ODD 1 #define APMT2_PEER_DEAUTH 2 -#define AP_MAX_AUTH_RSP_MSG 3 +#define APMT2_PEER_AUTH_REQ 3 +#define APMT2_PEER_AUTH_CONFIRM 4 +#define AP_MAX_AUTH_MSG 5 -#define AP_AUTH_RSP_FUNC_SIZE (AP_MAX_AUTH_RSP_STATE * AP_MAX_AUTH_RSP_MSG) +#define AP_AUTH_FUNC_SIZE (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG) // // AP's SYNC state machine: states, events, total function # @@ -919,20 +912,22 @@ #define AP_SYNC_FUNC_SIZE (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG) // -// AP's WPA state machine: states, events, total function # +// Common WPA state machine: states, events, total function # // -#define AP_WPA_PTK 0 -#define AP_MAX_WPA_PTK_STATE 1 +#define WPA_PTK 0 +#define MAX_WPA_PTK_STATE 1 + +#define WPA_MACHINE_BASE 0 +#define MT2_EAPPacket 0 +#define MT2_EAPOLStart 1 +#define MT2_EAPOLLogoff 2 +#define MT2_EAPOLKey 3 +#define MT2_EAPOLASFAlert 4 +#define MAX_WPA_MSG 5 + +#define WPA_FUNC_SIZE (MAX_WPA_PTK_STATE * MAX_WPA_MSG) -#define AP_WPA_MACHINE_BASE 0 -#define APMT2_EAPPacket 0 -#define APMT2_EAPOLStart 1 -#define APMT2_EAPOLLogoff 2 -#define APMT2_EAPOLKey 3 -#define APMT2_EAPOLASFAlert 4 -#define AP_MAX_WPA_MSG 5 -#define AP_WPA_FUNC_SIZE (AP_MAX_WPA_PTK_STATE * AP_MAX_WPA_MSG) // ============================================================================= @@ -1178,12 +1173,16 @@ #define REGION_4_A_BAND 4 // 149, 153, 157, 161, 165 #define REGION_5_A_BAND 5 // 149, 153, 157, 161 #define REGION_6_A_BAND 6 // 36, 40, 44, 48 -#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 +#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, 169, 173 #define REGION_8_A_BAND 8 // 52, 56, 60, 64 #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 #define REGION_10_A_BAND 10 // 36, 40, 44, 48, 149, 153, 157, 161, 165 #define REGION_11_A_BAND 11 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161 -#define REGION_MAXIMUM_A_BAND 11 +#define REGION_12_A_BAND 12 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 +#define REGION_13_A_BAND 13 // 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161 +#define REGION_14_A_BAND 14 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165 +#define REGION_15_A_BAND 15 // 149, 153, 157, 161, 165, 169, 173 +#define REGION_MAXIMUM_A_BAND 15 // pTxD->CipherAlg #define CIPHER_NONE 0 @@ -1196,15 +1195,6 @@ #define CIPHER_TKIP_NO_MIC 7 // MIC appended by driver: not a valid value in hardware key table #define CIPHER_SMS4 8 -// value domain of pAd->RfIcType -#define RFIC_2820 1 // 2.4G 2T3R -#define RFIC_2850 2 // 2.4G/5G 2T3R -#define RFIC_2720 3 // 2.4G 1T2R -#define RFIC_2750 4 // 2.4G/5G 1T2R -#define RFIC_3020 5 // 2.4G 1T1R -#define RFIC_2020 6 // 2.4G B/G -#define RFIC_3021 7 // 2.4G 1T2R -#define RFIC_3022 8 // 2.4G 2T2R // LED Status. #define LED_LINK_DOWN 0 @@ -1219,7 +1209,8 @@ // value domain of pAd->LedCntl.LedMode and E2PROM #define LED_MODE_DEFAULT 0 #define LED_MODE_TWO_LED 1 -#define LED_MODE_SIGNAL_STREGTH 8 // EEPROM define =8 +//#define LED_MODE_SIGNAL_STREGTH 8 // EEPROM define =8 +#define LED_MODE_SIGNAL_STREGTH 0x40 // EEPROM define = 64 // RC4 init value, used fro WEP & TKIP #define PPPINITFCS32 0xffffffff /* Initial FCS value */ @@ -1305,7 +1296,12 @@ #define INT_APCLI 0x0400 #define INT_MESH 0x0500 -// Use bitmap to allow coexist of ATE_TXFRAME and ATE_RXFRAME(i.e.,to support LoopBack mode) +#define INF_MAIN_DEV_NAME "wlan" +#define INF_MBSSID_DEV_NAME "ra" +#define INF_WDS_DEV_NAME "wds" +#define INF_APCLI_DEV_NAME "apcli" +#define INF_MESH_DEV_NAME "mesh" + // WEP Key TYPE #define WEP_HEXADECIMAL_TYPE 0 @@ -1380,7 +1376,7 @@ #define MAX_NUM_OF_INIT_DLS_ENTRY 1 #define MAX_NUM_OF_DLS_ENTRY MAX_NUMBER_OF_DLS_ENTRY -//Block ACK , rt2860, kathy +//Block ACK, kathy #define MAX_TX_REORDERBUF 64 #define MAX_RX_REORDERBUF 64 #define DEFAULT_TX_TIMEOUT 30 @@ -1399,22 +1395,13 @@ #define MCAST_HTMIX 3 #endif // MCAST_RATE_SPECIFIC // -#ifdef RT2860 -// For AsicRadioOff/AsicRadioOn/AsicForceWakeup function -// This is to indicate from where to call this function. -#define DOT11POWERSAVE 0 // TO do .11 power save sleep -#define GUIRADIO_OFF 1 // To perform Radio OFf command from GUI -#define RTMP_HALT 2 // Called from Halt handler. -#define GUI_IDLE_POWER_SAVE 3 // Call to sleep before link up with AP -#define FROM_TX 4 // Force wake up from Tx packet. -#endif -#ifdef RT2870 // For AsicRadioOff/AsicRadioOn function #define DOT11POWERSAVE 0 #define GUIRADIO_OFF 1 #define RTMP_HALT 2 #define GUI_IDLE_POWER_SAVE 3 -#endif +// -- + // definition for WpaSupport flag #define WPA_SUPPLICANT_DISABLE 0 @@ -1458,6 +1445,41 @@ #define cpu2be16(x) SWAP16((x)) #define be2cpu16(x) SWAP16((x)) + +#define ABS(_x, _y) ((_x) > (_y)) ? ((_x) -(_y)) : ((_y) -(_x)) + + +#define A2Dec(_X, _p) \ +{ \ + UCHAR *p; \ + _X = 0; \ + p = _p; \ + while (((*p >= '0') && (*p <= '9'))) \ + { \ + if ((*p >= '0') && (*p <= '9')) \ + _X = _X * 10 + *p - 48; \ + p++; \ + } \ +} + + +#define A2Hex(_X, _p) \ +do{ \ + char *__p; \ + (_X) = 0; \ + __p = (char *)(_p); \ + while (((*__p >= 'a') && (*__p <= 'f')) || ((*__p >= 'A') && (*__p <= 'F')) || ((*__p >= '0') && (*__p <= '9'))) \ + { \ + if ((*__p >= 'a') && (*__p <= 'f')) \ + (_X) = (_X) * 16 + *__p - 87; \ + else if ((*__p >= 'A') && (*__p <= 'F')) \ + (_X) = (_X) * 16 + *__p - 55; \ + else if ((*__p >= '0') && (*__p <= '9')) \ + (_X) = (_X) * 16 + *__p - 48; \ + __p++; \ + } \ +}while(0) + #endif // __RTMP_DEF_H__ Index: b/drivers/staging/rt2860/rtmp_dot11.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/rtmp_dot11.h @@ -0,0 +1,102 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* +*/ + +#ifndef __DOT11_BASE_H__ +#define __DOT11_BASE_H__ + +#include "rtmp_type.h" + + +// 4-byte HTC field. maybe included in any frame except non-QOS data frame. The Order bit must set 1. +typedef struct PACKED { + UINT32 MA:1; //management action payload exist in (QoS Null+HTC) + UINT32 TRQ:1; //sounding request + UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback + UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110. + UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB. + UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available + UINT32 CalPos:2; // calibration position + UINT32 CalSeq:2; //calibration sequence + UINT32 FBKReq:2; //feedback request + UINT32 CSISTEERING:2; //CSI/ STEERING + UINT32 ZLFAnnouce:1; // ZLF announcement + UINT32 rsv:5; //calibration sequence + UINT32 ACConstraint:1; //feedback request + UINT32 RDG:1; //RDG / More PPDU +} HT_CONTROL, *PHT_CONTROL; + +// 2-byte QOS CONTROL field +typedef struct PACKED { + USHORT TID:4; + USHORT EOSP:1; + USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA + USHORT AMsduPresent:1; + USHORT Txop_QueueSize:8; +} QOS_CONTROL, *PQOS_CONTROL; + + +// 2-byte Frame control field +typedef struct PACKED { + USHORT Ver:2; // Protocol version + USHORT Type:2; // MSDU type + USHORT SubType:4; // MSDU subtype + USHORT ToDs:1; // To DS indication + USHORT FrDs:1; // From DS indication + USHORT MoreFrag:1; // More fragment bit + USHORT Retry:1; // Retry status bit + USHORT PwrMgmt:1; // Power management bit + USHORT MoreData:1; // More data bit + USHORT Wep:1; // Wep data + USHORT Order:1; // Strict order expected +} FRAME_CONTROL, *PFRAME_CONTROL; + +typedef struct PACKED _HEADER_802_11 { + FRAME_CONTROL FC; + USHORT Duration; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; + UCHAR Addr3[MAC_ADDR_LEN]; + USHORT Frag:4; + USHORT Sequence:12; + UCHAR Octet[0]; +} HEADER_802_11, *PHEADER_802_11; + +typedef struct PACKED _PSPOLL_FRAME { + FRAME_CONTROL FC; + USHORT Aid; + UCHAR Bssid[MAC_ADDR_LEN]; + UCHAR Ta[MAC_ADDR_LEN]; +} PSPOLL_FRAME, *PPSPOLL_FRAME; + +typedef struct PACKED _RTS_FRAME { + FRAME_CONTROL FC; + USHORT Duration; + UCHAR Addr1[MAC_ADDR_LEN]; + UCHAR Addr2[MAC_ADDR_LEN]; +}RTS_FRAME, *PRTS_FRAME; + +#endif // __DOT11_BASE_H__ // Index: b/drivers/staging/rt2860/rtmp_iface.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/rtmp_iface.h @@ -0,0 +1,84 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rt_iface.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + +#ifndef __RTMP_IFACE_H__ +#define __RTMP_IFACE_H__ + + +#ifdef RTMP_PCI_SUPPORT +#include "iface/rtmp_pci.h" +#endif // RTMP_PCI_SUPPORT // +#ifdef RTMP_USB_SUPPORT +#include "iface/rtmp_usb.h" +#endif // RTMP_USB_SUPPORT // + +typedef struct _INF_PCI_CONFIG_ +{ + unsigned long CSRBaseAddress; // PCI MMIO Base Address, all access will use + unsigned int irq_num; +}INF_PCI_CONFIG; + + +typedef struct _INF_USB_CONFIG_ +{ + UINT8 BulkInEpAddr; // bulk-in endpoint address + UINT8 BulkOutEpAddr[6]; // bulk-out endpoint address +}INF_USB_CONFIG; + + +typedef struct _INF_RBUS_CONFIG_ +{ + unsigned long csr_addr; + unsigned int irq; +}INF_RBUS_CONFIG; + + +typedef enum _RTMP_INF_TYPE_ +{ + RTMP_DEV_INF_UNKNOWN = 0, + RTMP_DEV_INF_PCI = 1, + RTMP_DEV_INF_USB = 2, + RTMP_DEV_INF_RBUS = 4, +}RTMP_INF_TYPE; + + +typedef union _RTMP_INF_CONFIG_{ + struct _INF_PCI_CONFIG_ pciConfig; + struct _INF_USB_CONFIG_ usbConfig; + struct _INF_RBUS_CONFIG_ rbusConfig; +}RTMP_INF_CONFIG; + +#endif // __RTMP_IFACE_H__ // Index: b/drivers/staging/rt2860/rtmp_mcu.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/rtmp_mcu.h @@ -0,0 +1,55 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rtmp_mcu.h + + Abstract: + Miniport header file for mcu related information + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ + +#ifndef __RTMP_MCU_H__ +#define __RTMP_MCU_H__ + + +INT RtmpAsicEraseFirmware( + IN PRTMP_ADAPTER pAd); + +NDIS_STATUS RtmpAsicLoadFirmware( + IN PRTMP_ADAPTER pAd); + +INT RtmpAsicSendCommandToMcu( + IN PRTMP_ADAPTER pAd, + IN UCHAR Command, + IN UCHAR Token, + IN UCHAR Arg0, + IN UCHAR Arg1); + +#endif // __RTMP_MCU_H__ // Index: b/drivers/staging/rt2860/rtmp_os.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/rtmp_os.h @@ -0,0 +1,98 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rtmp_os.h + + Abstract: + + Revision History: + Who When What + --------- ---------- ---------------------------------------------- + */ + + +#ifndef __RTMP_OS_H__ +#define __RTMP_OS_H__ + +#ifdef LINUX +#include "rt_linux.h" +#endif // LINUX // + + + +/* + This data structure mainly strip some callback function defined in + "struct net_device" in kernel source "include/linux/netdevice.h". + + The definition of this data structure may various depends on different + OS. Use it carefully. +*/ +typedef struct _RTMP_OS_NETDEV_OP_HOOK_ +{ + const struct net_device_ops *netdev_ops; + void *priv; + int priv_flags; + unsigned char devAddr[6]; + unsigned char devName[16]; + unsigned char needProtcted; +}RTMP_OS_NETDEV_OP_HOOK, *PRTMP_OS_NETDEV_OP_HOOK; + + +typedef enum _RTMP_TASK_STATUS_ +{ + RTMP_TASK_STAT_UNKNOWN = 0, + RTMP_TASK_STAT_INITED = 1, + RTMP_TASK_STAT_RUNNING = 2, + RTMP_TASK_STAT_STOPED = 4, +}RTMP_TASK_STATUS; +#define RTMP_TASK_CAN_DO_INSERT (RTMP_TASK_STAT_INITED |RTMP_TASK_STAT_RUNNING) + +#define RTMP_OS_TASK_NAME_LEN 16 +typedef struct _RTMP_OS_TASK_ +{ + char taskName[RTMP_OS_TASK_NAME_LEN]; + void *priv; + //unsigned long taskFlags; + RTMP_TASK_STATUS taskStatus; +#ifndef KTHREAD_SUPPORT + RTMP_OS_SEM taskSema; + RTMP_OS_PID taskPID; + struct completion taskComplete; +#endif + unsigned char task_killed; +#ifdef KTHREAD_SUPPORT + struct task_struct *kthread_task; + wait_queue_head_t kthread_q; + BOOLEAN kthread_running; +#endif +}RTMP_OS_TASK; + + +int RtmpOSIRQRequest(IN PNET_DEV pNetDev); +int RtmpOSIRQRelease(IN PNET_DEV pNetDev); + +#endif // __RMTP_OS_H__ // Index: b/drivers/staging/rt2860/rtmp_timer.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/rtmp_timer.h @@ -0,0 +1,156 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rtmp_timer.h + + Abstract: + Ralink Wireless Driver timer related data structures and delcarations + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Name Date Modification logs + Shiang Tu Aug-28-2008 init version + +*/ + +#ifndef __RTMP_TIMER_H__ +#define __RTMP_TIMER_H__ + +#include "rtmp_os.h" + + +#define DECLARE_TIMER_FUNCTION(_func) \ + void rtmp_timer_##_func(unsigned long data) + +#define GET_TIMER_FUNCTION(_func) \ + rtmp_timer_##_func + + +/* ----------------- Timer Related MARCO ---------------*/ +// In some os or chipset, we have a lot of timer functions and will read/write register, +// it's not allowed in Linux USB sub-system to do it ( because of sleep issue when +// submit to ctrl pipe). So we need a wrapper function to take care it. + +#ifdef RTMP_TIMER_TASK_SUPPORT +typedef VOID (*RTMP_TIMER_TASK_HANDLE)( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3); +#endif // RTMP_TIMER_TASK_SUPPORT // + +typedef struct _RALINK_TIMER_STRUCT { + RTMP_OS_TIMER TimerObj; // Ndis Timer object + BOOLEAN Valid; // Set to True when call RTMPInitTimer + BOOLEAN State; // True if timer cancelled + BOOLEAN PeriodicType; // True if timer is periodic timer + BOOLEAN Repeat; // True if periodic timer + ULONG TimerValue; // Timer value in milliseconds + ULONG cookie; // os specific object +#ifdef RTMP_TIMER_TASK_SUPPORT + RTMP_TIMER_TASK_HANDLE handle; + void *pAd; +#endif // RTMP_TIMER_TASK_SUPPORT // +}RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT; + + +#ifdef RTMP_TIMER_TASK_SUPPORT +typedef struct _RTMP_TIMER_TASK_ENTRY_ +{ + RALINK_TIMER_STRUCT *pRaTimer; + struct _RTMP_TIMER_TASK_ENTRY_ *pNext; +}RTMP_TIMER_TASK_ENTRY; + + +#define TIMER_QUEUE_SIZE_MAX 128 +typedef struct _RTMP_TIMER_TASK_QUEUE_ +{ + unsigned int status; + unsigned char *pTimerQPoll; + RTMP_TIMER_TASK_ENTRY *pQPollFreeList; + RTMP_TIMER_TASK_ENTRY *pQHead; + RTMP_TIMER_TASK_ENTRY *pQTail; +}RTMP_TIMER_TASK_QUEUE; + +#define BUILD_TIMER_FUNCTION(_func) \ +void rtmp_timer_##_func(unsigned long data) \ +{ \ + PRALINK_TIMER_STRUCT _pTimer = (PRALINK_TIMER_STRUCT)data; \ + RTMP_TIMER_TASK_ENTRY *_pQNode; \ + RTMP_ADAPTER *_pAd; \ + \ + _pTimer->handle = _func; \ + _pAd = (RTMP_ADAPTER *)_pTimer->pAd; \ + _pQNode = RtmpTimerQInsert(_pAd, _pTimer); \ + if ((_pQNode == NULL) && (_pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT)) \ + RTMP_OS_Add_Timer(&_pTimer->TimerObj, OS_HZ); \ +} +#else +#define BUILD_TIMER_FUNCTION(_func) \ +void rtmp_timer_##_func(unsigned long data) \ +{ \ + PRALINK_TIMER_STRUCT pTimer = (PRALINK_TIMER_STRUCT) data; \ + \ + _func(NULL, (PVOID) pTimer->cookie, NULL, pTimer); \ + if (pTimer->Repeat) \ + RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); \ +} +#endif // RTMP_TIMER_TASK_SUPPORT // + + +DECLARE_TIMER_FUNCTION(MlmePeriodicExec); +DECLARE_TIMER_FUNCTION(MlmeRssiReportExec); +DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout); +DECLARE_TIMER_FUNCTION(APSDPeriodicExec); +DECLARE_TIMER_FUNCTION(AsicRfTuningExec); +#ifdef RTMP_MAC_USB +DECLARE_TIMER_FUNCTION(BeaconUpdateExec); +#endif // RTMP_MAC_USB // + +DECLARE_TIMER_FUNCTION(BeaconTimeout); +DECLARE_TIMER_FUNCTION(ScanTimeout); +DECLARE_TIMER_FUNCTION(AuthTimeout); +DECLARE_TIMER_FUNCTION(AssocTimeout); +DECLARE_TIMER_FUNCTION(ReassocTimeout); +DECLARE_TIMER_FUNCTION(DisassocTimeout); +DECLARE_TIMER_FUNCTION(LinkDownExec); +DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec); +DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc); +DECLARE_TIMER_FUNCTION(PsPollWakeExec); +DECLARE_TIMER_FUNCTION(RadioOnExec); + +#ifdef RTMP_MAC_USB +DECLARE_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout); +#endif // RTMP_MAC_USB // + +#if defined(AP_LED) || defined(STA_LED) +DECLARE_TIMER_FUNCTION(LedCtrlMain); +#endif + + +#endif // __RTMP_TIMER_H__ // Index: b/drivers/staging/rt2860/rtmp_type.h =================================================================== --- a/drivers/staging/rt2860/rtmp_type.h +++ b/drivers/staging/rt2860/rtmp_type.h @@ -38,8 +38,10 @@ #ifndef __RTMP_TYPE_H__ #define __RTMP_TYPE_H__ + #define PACKED __attribute__ ((packed)) +#ifdef LINUX // Put platform dependent declaration here // For example, linux type definition typedef unsigned char UINT8; @@ -48,6 +50,7 @@ typedef unsigned int UINT32; typedef unsigned long long UINT64; typedef int INT32; typedef long long INT64; +#endif // LINUX // typedef unsigned char * PUINT8; typedef unsigned short * PUINT16; @@ -56,22 +59,30 @@ typedef unsigned long long * PUINT64; typedef int * PINT32; typedef long long * PINT64; +// modified for fixing compile warning on Sigma 8634 platform +typedef char STRING; typedef signed char CHAR; + typedef signed short SHORT; typedef signed int INT; typedef signed long LONG; typedef signed long long LONGLONG; +#ifdef LINUX typedef unsigned char UCHAR; typedef unsigned short USHORT; typedef unsigned int UINT; typedef unsigned long ULONG; +#endif // LINUX // typedef unsigned long long ULONGLONG; typedef unsigned char BOOLEAN; +#ifdef LINUX typedef void VOID; +#endif // LINUX // +typedef char * PSTRING; typedef VOID * PVOID; typedef CHAR * PCHAR; typedef UCHAR * PUCHAR; @@ -90,5 +101,47 @@ typedef union _LARGE_INTEGER { INT64 QuadPart; } LARGE_INTEGER; -#endif // __RTMP_TYPE_H__ + +// +// Register set pair for initialzation register set definition +// +typedef struct _RTMP_REG_PAIR +{ + ULONG Register; + ULONG Value; +} RTMP_REG_PAIR, *PRTMP_REG_PAIR; + +typedef struct _REG_PAIR +{ + UCHAR Register; + UCHAR Value; +} REG_PAIR, *PREG_PAIR; + +// +// Register set pair for initialzation register set definition +// +typedef struct _RTMP_RF_REGS +{ + UCHAR Channel; + ULONG R1; + ULONG R2; + ULONG R3; + ULONG R4; +} RTMP_RF_REGS, *PRTMP_RF_REGS; + +typedef struct _FREQUENCY_ITEM { + UCHAR Channel; + UCHAR N; + UCHAR R; + UCHAR K; +} FREQUENCY_ITEM, *PFREQUENCY_ITEM; + + +typedef int NTSTATUS; + + +#define STATUS_SUCCESS 0x00 +#define STATUS_UNSUCCESSFUL 0x01 + +#endif // __RTMP_TYPE_H__ // Index: b/drivers/staging/rt2860/rtusb_io.h =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/rtusb_io.h @@ -0,0 +1,189 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* +*/ + + +#ifndef __RTUSB_IO_H__ +#define __RTUSB_IO_H__ + +#include "rtmp_type.h" + +// New for MeetingHouse Api support +#define CMDTHREAD_VENDOR_RESET 0x0D730101 // cmd +#define CMDTHREAD_VENDOR_UNPLUG 0x0D730102 // cmd +#define CMDTHREAD_VENDOR_SWITCH_FUNCTION 0x0D730103 // cmd +#define CMDTHREAD_MULTI_WRITE_MAC 0x0D730107 // cmd +#define CMDTHREAD_MULTI_READ_MAC 0x0D730108 // cmd +#define CMDTHREAD_VENDOR_EEPROM_WRITE 0x0D73010A // cmd +#define CMDTHREAD_VENDOR_EEPROM_READ 0x0D73010B // cmd +#define CMDTHREAD_VENDOR_ENTER_TESTMODE 0x0D73010C // cmd +#define CMDTHREAD_VENDOR_EXIT_TESTMODE 0x0D73010D // cmd +#define CMDTHREAD_VENDOR_WRITE_BBP 0x0D730119 // cmd +#define CMDTHREAD_VENDOR_READ_BBP 0x0D730118 // cmd +#define CMDTHREAD_VENDOR_WRITE_RF 0x0D73011A // cmd +#define CMDTHREAD_VENDOR_FLIP_IQ 0x0D73011D // cmd +#define CMDTHREAD_RESET_BULK_OUT 0x0D730210 // cmd +#define CMDTHREAD_RESET_BULK_IN 0x0D730211 // cmd +#define CMDTHREAD_SET_PSM_BIT 0x0D730212 // cmd +#define CMDTHREAD_SET_RADIO 0x0D730214 // cmd +#define CMDTHREAD_UPDATE_TX_RATE 0x0D730216 // cmd +#define CMDTHREAD_802_11_ADD_KEY_WEP 0x0D730218 // cmd +#define CMDTHREAD_RESET_FROM_ERROR 0x0D73021A // cmd +#define CMDTHREAD_LINK_DOWN 0x0D73021B // cmd +#define CMDTHREAD_RESET_FROM_NDIS 0x0D73021C // cmd +#define CMDTHREAD_CHECK_GPIO 0x0D730215 // cmd +#define CMDTHREAD_FORCE_WAKE_UP 0x0D730222 // cmd +#define CMDTHREAD_SET_BW 0x0D730225 // cmd +#define CMDTHREAD_SET_ASIC_WCID 0x0D730226 // cmd +#define CMDTHREAD_SET_ASIC_WCID_CIPHER 0x0D730227 // cmd +#define CMDTHREAD_QKERIODIC_EXECUT 0x0D73023D // cmd +#define RT_CMD_SET_KEY_TABLE 0x0D730228 // cmd +#define RT_CMD_SET_RX_WCID_TABLE 0x0D730229 // cmd +#define CMDTHREAD_SET_CLIENT_MAC_ENTRY 0x0D73023E // cmd +#define CMDTHREAD_SET_GROUP_KEY 0x0D73023F // cmd +#define CMDTHREAD_SET_PAIRWISE_KEY 0x0D730240 // cmd + +#define CMDTHREAD_802_11_QUERY_HARDWARE_REGISTER 0x0D710105 // cmd +#define CMDTHREAD_802_11_SET_PHY_MODE 0x0D79010C // cmd +#define CMDTHREAD_802_11_SET_STA_CONFIG 0x0D790111 // cmd +#define CMDTHREAD_802_11_SET_PREAMBLE 0x0D790101 // cmd +#define CMDTHREAD_802_11_COUNTER_MEASURE 0x0D790102 // cmd +// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet +#define CMDTHREAD_UPDATE_PROTECT 0x0D790103 // cmd +// end johnli + + +//CMDTHREAD_MULTI_READ_MAC +//CMDTHREAD_MULTI_WRITE_MAC +//CMDTHREAD_VENDOR_EEPROM_READ +//CMDTHREAD_VENDOR_EEPROM_WRITE +typedef struct _CMDHandler_TLV { + USHORT Offset; + USHORT Length; + UCHAR DataFirst; +} CMDHandler_TLV, *PCMDHandler_TLV; + + +typedef struct _CmdQElmt { + UINT command; + PVOID buffer; + ULONG bufferlength; + BOOLEAN CmdFromNdis; + BOOLEAN SetOperation; + struct _CmdQElmt *next; +} CmdQElmt, *PCmdQElmt; + +typedef struct _CmdQ { + UINT size; + CmdQElmt *head; + CmdQElmt *tail; + UINT32 CmdQState; +}CmdQ, *PCmdQ; + + +#define EnqueueCmd(cmdq, cmdqelmt) \ +{ \ + if (cmdq->size == 0) \ + cmdq->head = cmdqelmt; \ + else \ + cmdq->tail->next = cmdqelmt; \ + cmdq->tail = cmdqelmt; \ + cmdqelmt->next = NULL; \ + cmdq->size++; \ +} + + +/****************************************************************************** + + USB Cmd to ASIC Related MACRO + +******************************************************************************/ +// reset MAC of a station entry to 0xFFFFFFFFFFFF +#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid) \ + { RT_SET_ASIC_WCID SetAsicWcid; \ + SetAsicWcid.WCID = Wcid; \ + SetAsicWcid.SetTid = 0xffffffff; \ + SetAsicWcid.DeleteTid = 0xffffffff; \ + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID, \ + &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); } + +// add this entry into ASIC RX WCID search table +#define RTMP_STA_ENTRY_ADD(pAd, pEntry) \ + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY, \ + pEntry, sizeof(MAC_TABLE_ENTRY)); + +// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet +// Set MAC register value according operation mode +#define RTMP_UPDATE_PROTECT(pAd) \ + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0); +// end johnli + +// remove Pair-wise key material from ASIC +// yet implement +#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid) + +// add Client security information into ASIC WCID table and IVEIV table +#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry) \ + { RTMP_STA_ENTRY_MAC_RESET(pAd, pEntry->Aid); \ + if (pEntry->Aid >= 1) { \ + RT_SET_ASIC_WCID_ATTRI SetAsicWcidAttri; \ + SetAsicWcidAttri.WCID = pEntry->Aid; \ + if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && \ + (pEntry->WepStatus == Ndis802_11Encryption1Enabled)) \ + { \ + SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \ + } \ + else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone) \ + { \ + SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \ + } \ + else SetAsicWcidAttri.Cipher = 0; \ + DBGPRINT(RT_DEBUG_TRACE, ("aid cipher = %ld\n",SetAsicWcidAttri.Cipher)); \ + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID_CIPHER, \ + &SetAsicWcidAttri, sizeof(RT_SET_ASIC_WCID_ATTRI)); } } + +// Insert the BA bitmap to ASIC for the Wcid entry +#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \ + do{ \ + RT_SET_ASIC_WCID SetAsicWcid; \ + SetAsicWcid.WCID = (_Aid); \ + SetAsicWcid.SetTid = (0x10000<<(_TID)); \ + SetAsicWcid.DeleteTid = 0xffffffff; \ + RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \ + }while(0) + +// Remove the BA bitmap from ASIC for the Wcid entry +#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \ + do{ \ + RT_SET_ASIC_WCID SetAsicWcid; \ + SetAsicWcid.WCID = (_Wcid); \ + SetAsicWcid.SetTid = (0xffffffff); \ + SetAsicWcid.DeleteTid = (0x10000<<(_TID) ); \ + RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \ + }while(0) + + +#endif // __RTUSB_IO_H__ // Index: b/drivers/staging/rt2860/spectrum.h =================================================================== --- a/drivers/staging/rt2860/spectrum.h +++ b/drivers/staging/rt2860/spectrum.h @@ -23,7 +23,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * ************************************************************************* -*/ + */ #ifndef __SPECTRUM_H__ #define __SPECTRUM_H__ @@ -31,112 +31,10 @@ #include "rtmp_type.h" #include "spectrum_def.h" -typedef struct PACKED _TPC_REPORT_INFO -{ - UINT8 TxPwr; - UINT8 LinkMargin; -} TPC_REPORT_INFO, *PTPC_REPORT_INFO; - -typedef struct PACKED _CH_SW_ANN_INFO -{ - UINT8 ChSwMode; - UINT8 Channel; - UINT8 ChSwCnt; -} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO; - -typedef union PACKED _MEASURE_REQ_MODE -{ - struct PACKED - { - UINT8 Rev0:1; - UINT8 Enable:1; - UINT8 Request:1; - UINT8 Report:1; - UINT8 Rev1:4; - } field; - UINT8 word; -} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE; - -typedef struct PACKED _MEASURE_REQ -{ - UINT8 ChNum; - UINT64 MeasureStartTime; - UINT16 MeasureDuration; -} MEASURE_REQ, *PMEASURE_REQ; - -typedef struct PACKED _MEASURE_REQ_INFO -{ - UINT8 Token; - MEASURE_REQ_MODE ReqMode; - UINT8 ReqType; - MEASURE_REQ MeasureReq; -} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO; - -typedef union PACKED _MEASURE_BASIC_REPORT_MAP -{ - struct PACKED - { - UINT8 BSS:1; - UINT8 OfdmPreamble:1; - UINT8 UnidentifiedSignal:1; - UINT8 Radar:1; - UINT8 Unmeasure:1; - UINT8 Rev:3; - } field; - UINT8 word; -} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP; - -typedef struct PACKED _MEASURE_BASIC_REPORT -{ - UINT8 ChNum; - UINT64 MeasureStartTime; - UINT16 MeasureDuration; - MEASURE_BASIC_REPORT_MAP Map; -} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT; - -typedef struct PACKED _MEASURE_CCA_REPORT -{ - UINT8 ChNum; - UINT64 MeasureStartTime; - UINT16 MeasureDuration; - UINT8 CCA_Busy_Fraction; -} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT; - -typedef struct PACKED _MEASURE_RPI_REPORT -{ - UINT8 ChNum; - UINT64 MeasureStartTime; - UINT16 MeasureDuration; - UINT8 RPI_Density[8]; -} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT; - -typedef union PACKED _MEASURE_REPORT_MODE -{ - struct PACKED - { - UINT8 Late:1; - UINT8 Incapable:1; - UINT8 Refused:1; - UINT8 Rev:5; - } field; - UINT8 word; -} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE; - -typedef struct PACKED _MEASURE_REPORT_INFO -{ - UINT8 Token; - MEASURE_REPORT_MODE ReportMode; - UINT8 ReportType; - UINT8 Octect[0]; -} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO; - -typedef struct PACKED _QUIET_INFO -{ - UINT8 QuietCnt; - UINT8 QuietPeriod; - UINT8 QuietDuration; - UINT8 QuietOffset; -} QUIET_INFO, *PQUIET_INFO; + +CHAR RTMP_GetTxPwr( + IN PRTMP_ADAPTER pAd, + IN HTTRANSMIT_SETTING HTTxMode); /* ========================================================================== @@ -150,14 +48,17 @@ typedef struct PACKED _QUIET_INFO Return : None. ========================================================================== */ -VOID EnqueueMeasurementReq( +VOID MakeMeasurementReqFrame( IN PRTMP_ADAPTER pAd, - IN PUCHAR pDA, + OUT PUCHAR pOutBuffer, + OUT PULONG pFrameLen, + IN UINT8 TotalLen, + IN UINT8 Category, + IN UINT8 Action, IN UINT8 MeasureToken, IN UINT8 MeasureReqMode, IN UINT8 MeasureReqType, - IN UINT8 MeasureCh, - IN UINT16 MeasureDuration); + IN UINT8 NumOfRepetitions); /* ========================================================================== @@ -264,11 +165,16 @@ VOID PeerSpectrumAction( */ INT Set_MeasureReq_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_TpcReq_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); + +INT Set_PwrConstraint( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + VOID MeasureReqTabInit( IN PRTMP_ADAPTER pAd); @@ -276,6 +182,38 @@ VOID MeasureReqTabInit( VOID MeasureReqTabExit( IN PRTMP_ADAPTER pAd); +PMEASURE_REQ_ENTRY MeasureReqLookUp( + IN PRTMP_ADAPTER pAd, + IN UINT8 DialogToken); + +PMEASURE_REQ_ENTRY MeasureReqInsert( + IN PRTMP_ADAPTER pAd, + IN UINT8 DialogToken); + +VOID MeasureReqDelete( + IN PRTMP_ADAPTER pAd, + IN UINT8 DialogToken); + +VOID InsertChannelRepIE( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN PSTRING pCountry, + IN UINT8 RegulatoryClass); + +VOID InsertTpcReportIE( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN UINT8 TxPwr, + IN UINT8 LinkMargin); + +VOID InsertDialogToken( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN UINT8 DialogToken); + VOID TpcReqTabInit( IN PRTMP_ADAPTER pAd); @@ -288,5 +226,10 @@ VOID NotifyChSwAnnToPeerAPs( IN PUCHAR pTA, IN UINT8 ChSwMode, IN UINT8 Channel); + +VOID RguClass_BuildBcnChList( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pBuf, + OUT PULONG pBufLen); #endif // __SPECTRUM_H__ // Index: b/drivers/staging/rt2860/spectrum_def.h =================================================================== --- a/drivers/staging/rt2860/spectrum_def.h +++ b/drivers/staging/rt2860/spectrum_def.h @@ -39,21 +39,15 @@ #ifndef __SPECTRUM_DEF_H__ #define __SPECTRUM_DEF_H__ -#define MAX_MEASURE_REQ_TAB_SIZE 3 + +#define MAX_MEASURE_REQ_TAB_SIZE 32 #define MAX_HASH_MEASURE_REQ_TAB_SIZE MAX_MEASURE_REQ_TAB_SIZE -#define MAX_TPC_REQ_TAB_SIZE 3 +#define MAX_TPC_REQ_TAB_SIZE 32 #define MAX_HASH_TPC_REQ_TAB_SIZE MAX_TPC_REQ_TAB_SIZE #define MIN_RCV_PWR 100 /* Negative value ((dBm) */ -#define RM_TPC_REQ 0 -#define RM_MEASURE_REQ 1 - -#define RM_BASIC 0 -#define RM_CCA 1 -#define RM_RPI_HISTOGRAM 2 - #define TPC_REQ_AGE_OUT 500 /* ms */ #define MQ_REQ_AGE_OUT 500 /* ms */ @@ -91,5 +85,141 @@ typedef struct _TPC_REQ_TAB TPC_REQ_ENTRY Content[MAX_TPC_REQ_TAB_SIZE]; } TPC_REQ_TAB, *PTPC_REQ_TAB; + +/* The regulatory information */ +typedef struct _DOT11_CHANNEL_SET +{ + UCHAR NumberOfChannels; + UINT8 MaxTxPwr; + UCHAR ChannelList[16]; +} DOT11_CHANNEL_SET, *PDOT11_CHANNEL_SET; + +typedef struct _DOT11_REGULATORY_INFORMATION +{ + UCHAR RegulatoryClass; + DOT11_CHANNEL_SET ChannelSet; +} DOT11_REGULATORY_INFORMATION, *PDOT11_REGULATORY_INFORMATION; + + + +#define RM_TPC_REQ 0 +#define RM_MEASURE_REQ 1 + +#define RM_BASIC 0 +#define RM_CCA 1 +#define RM_RPI_HISTOGRAM 2 +#define RM_CH_LOAD 3 +#define RM_NOISE_HISTOGRAM 4 + + +typedef struct PACKED _TPC_REPORT_INFO +{ + UINT8 TxPwr; + UINT8 LinkMargin; +} TPC_REPORT_INFO, *PTPC_REPORT_INFO; + +typedef struct PACKED _CH_SW_ANN_INFO +{ + UINT8 ChSwMode; + UINT8 Channel; + UINT8 ChSwCnt; +} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO; + +typedef union PACKED _MEASURE_REQ_MODE +{ + struct PACKED + { + UINT8 Parallel:1; + UINT8 Enable:1; + UINT8 Request:1; + UINT8 Report:1; + UINT8 DurationMandatory:1; + UINT8 :3; + } field; + UINT8 word; +} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE; + +typedef struct PACKED _MEASURE_REQ +{ + UINT8 ChNum; + UINT64 MeasureStartTime; + UINT16 MeasureDuration; +} MEASURE_REQ, *PMEASURE_REQ; + +typedef struct PACKED _MEASURE_REQ_INFO +{ + UINT8 Token; + MEASURE_REQ_MODE ReqMode; + UINT8 ReqType; + UINT8 Oct[0]; +} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO; + +typedef union PACKED _MEASURE_BASIC_REPORT_MAP +{ + struct PACKED + { + UINT8 BSS:1; + + UINT8 OfdmPreamble:1; + UINT8 UnidentifiedSignal:1; + UINT8 Radar:1; + UINT8 Unmeasure:1; + UINT8 Rev:3; + } field; + UINT8 word; +} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP; + +typedef struct PACKED _MEASURE_BASIC_REPORT +{ + UINT8 ChNum; + UINT64 MeasureStartTime; + UINT16 MeasureDuration; + MEASURE_BASIC_REPORT_MAP Map; +} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT; + +typedef struct PACKED _MEASURE_CCA_REPORT +{ + UINT8 ChNum; + UINT64 MeasureStartTime; + UINT16 MeasureDuration; + UINT8 CCA_Busy_Fraction; +} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT; + +typedef struct PACKED _MEASURE_RPI_REPORT +{ + UINT8 ChNum; + UINT64 MeasureStartTime; + UINT16 MeasureDuration; + UINT8 RPI_Density[8]; +} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT; + +typedef union PACKED _MEASURE_REPORT_MODE +{ + struct PACKED + { + UINT8 Late:1; + UINT8 Incapable:1; + UINT8 Refused:1; + UINT8 Rev:5; + } field; + UINT8 word; +} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE; + +typedef struct PACKED _MEASURE_REPORT_INFO +{ + UINT8 Token; + UINT8 ReportMode; + UINT8 ReportType; + UINT8 Octect[0]; +} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO; + +typedef struct PACKED _QUIET_INFO +{ + UINT8 QuietCnt; + UINT8 QuietPeriod; + UINT16 QuietDuration; + UINT16 QuietOffset; +} QUIET_INFO, *PQUIET_INFO; + #endif // __SPECTRUM_DEF_H__ // Index: b/drivers/staging/rt2860/sta/aironet.c =================================================================== --- a/drivers/staging/rt2860/sta/aironet.c +++ /dev/null @@ -1,1312 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - - Module Name: - aironet.c - - Abstract: - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Paul Lin 04-06-15 Initial -*/ -#include "../rt_config.h" - -/* - ========================================================================== - Description: - association state machine init, including state transition and timer init - Parameters: - S - pointer to the association state machine - ========================================================================== - */ -VOID AironetStateMachineInit( - IN PRTMP_ADAPTER pAd, - IN STATE_MACHINE *S, - OUT STATE_MACHINE_FUNC Trans[]) -{ - StateMachineInit(S, Trans, MAX_AIRONET_STATE, MAX_AIRONET_MSG, (STATE_MACHINE_FUNC)Drop, AIRONET_IDLE, AIRONET_MACHINE_BASE); - StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_MSG, (STATE_MACHINE_FUNC)AironetMsgAction); - StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_SCAN_REQ, (STATE_MACHINE_FUNC)AironetRequestAction); - StateMachineSetAction(S, AIRONET_SCANNING, MT2_AIRONET_SCAN_DONE, (STATE_MACHINE_FUNC)AironetReportAction); -} - -/* - ========================================================================== - Description: - This is state machine function. - When receiving EAPOL packets which is for 802.1x key management. - Use both in WPA, and WPAPSK case. - In this function, further dispatch to different functions according to the received packet. 3 categories are : - 1. normal 4-way pairwisekey and 2-way groupkey handshake - 2. MIC error (Countermeasures attack) report packet from STA. - 3. Request for pairwise/group key update from STA - Return: - ========================================================================== -*/ -VOID AironetMsgAction( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem) -{ - USHORT Length; - UCHAR Index, i; - PUCHAR pData; - PAIRONET_RM_REQUEST_FRAME pRMReq; - PRM_REQUEST_ACTION pReqElem; - - DBGPRINT(RT_DEBUG_TRACE, ("-----> AironetMsgAction\n")); - - // 0. Get Aironet IAPP header first - pRMReq = (PAIRONET_RM_REQUEST_FRAME) &Elem->Msg[LENGTH_802_11]; - pData = (PUCHAR) &Elem->Msg[LENGTH_802_11]; - - // 1. Change endian format form network to little endian - Length = be2cpu16(pRMReq->IAPP.Length); - - // 2.0 Sanity check, this should only happen when CCX 2.0 support is enabled - if (pAd->StaCfg.CCXEnable != TRUE) - return; - - // 2.1 Radio measurement must be on - if (pAd->StaCfg.CCXControl.field.RMEnable != 1) - return; - - // 2.2. Debug print all bit information - DBGPRINT(RT_DEBUG_TRACE, ("IAPP ID & Length %d\n", Length)); - DBGPRINT(RT_DEBUG_TRACE, ("IAPP Type %x\n", pRMReq->IAPP.Type)); - DBGPRINT(RT_DEBUG_TRACE, ("IAPP SubType %x\n", pRMReq->IAPP.SubType)); - DBGPRINT(RT_DEBUG_TRACE, ("IAPP Dialog Token %x\n", pRMReq->IAPP.Token)); - DBGPRINT(RT_DEBUG_TRACE, ("IAPP Activation Delay %x\n", pRMReq->Delay)); - DBGPRINT(RT_DEBUG_TRACE, ("IAPP Measurement Offset %x\n", pRMReq->Offset)); - - // 3. Check IAPP frame type, it must be 0x32 for Cisco Aironet extension - if (pRMReq->IAPP.Type != AIRONET_IAPP_TYPE) - { - DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP type for Cisco Aironet extension\n")); - return; - } - - // 4. Check IAPP frame subtype, it must be 0x01 for Cisco Aironet extension request. - // Since we are acting as client only, we will disregards reply subtype. - if (pRMReq->IAPP.SubType != AIRONET_IAPP_SUBTYPE_REQUEST) - { - DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP subtype for Cisco Aironet extension\n")); - return; - } - - // 5. Verify Destination MAC and Source MAC, both should be all zeros. - if (! MAC_ADDR_EQUAL(pRMReq->IAPP.DA, ZERO_MAC_ADDR)) - { - DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP DA for Cisco Aironet extension, it's not Zero\n")); - return; - } - - if (! MAC_ADDR_EQUAL(pRMReq->IAPP.SA, ZERO_MAC_ADDR)) - { - DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP SA for Cisco Aironet extension, it's not Zero\n")); - return; - } - - // 6. Reinit all report related fields - NdisZeroMemory(pAd->StaCfg.FrameReportBuf, 2048); - NdisZeroMemory(pAd->StaCfg.BssReportOffset, sizeof(USHORT) * MAX_LEN_OF_BSS_TABLE); - NdisZeroMemory(pAd->StaCfg.MeasurementRequest, sizeof(RM_REQUEST_ACTION) * 4); - - // 7. Point to the start of first element report element - pAd->StaCfg.FrameReportLen = LENGTH_802_11 + sizeof(AIRONET_IAPP_HEADER); - DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen)); - pAd->StaCfg.LastBssIndex = 0xff; - pAd->StaCfg.RMReqCnt = 0; - pAd->StaCfg.ParallelReq = FALSE; - pAd->StaCfg.ParallelDuration = 0; - pAd->StaCfg.ParallelChannel = 0; - pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token; - pAd->StaCfg.CurrentRMReqIdx = 0; - pAd->StaCfg.CLBusyBytes = 0; - // Reset the statistics - for (i = 0; i < 8; i++) - pAd->StaCfg.RPIDensity[i] = 0; - - Index = 0; - - // 8. Save dialog token for report - pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token; - - // Save Activation delay & measurement offset, Not really needed - - // 9. Point to the first request element - pData += sizeof(AIRONET_RM_REQUEST_FRAME); - // Length should exclude the CISCO Aironet SNAP header - Length -= (sizeof(AIRONET_RM_REQUEST_FRAME) - LENGTH_802_1_H); - - // 10. Start Parsing the Measurement elements. - // Be careful about multiple MR elements within one frames. - while (Length > 0) - { - pReqElem = (PRM_REQUEST_ACTION) pData; - switch (pReqElem->ReqElem.Eid) - { - case IE_MEASUREMENT_REQUEST: - // From the example, it seems we only need to support one request in one frame - // There is no multiple request in one frame. - // Besides, looks like we need to take care the measurement request only. - // The measurement request is always 4 bytes. - - // Start parsing this type of request. - // 0. Eid is IE_MEASUREMENT_REQUEST - // 1. Length didn't include Eid and Length field, it always be 8. - // 2. Measurement Token, we nned to save it for the corresponding report. - // 3. Measurement Mode, Although there are definitions, but we din't see value other than - // 0 from test specs examples. - // 4. Measurement Type, this is what we need to do. - switch (pReqElem->ReqElem.Type) - { - case MSRN_TYPE_CHANNEL_LOAD_REQ: - case MSRN_TYPE_NOISE_HIST_REQ: - case MSRN_TYPE_BEACON_REQ: - // Check the Enable non-serving channel measurement control - if (pAd->StaCfg.CCXControl.field.DCRMEnable == 0) - { - // Check channel before enqueue the action - if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel) - break; - } - else - { - // If off channel measurement, check the TU duration limit - if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel) - if (pReqElem->Measurement.Duration > pAd->StaCfg.CCXControl.field.TuLimit) - break; - } - - // Save requests and execute actions later - NdisMoveMemory(&pAd->StaCfg.MeasurementRequest[Index], pReqElem, sizeof(RM_REQUEST_ACTION)); - Index += 1; - break; - - case MSRN_TYPE_FRAME_REQ: - // Since it's option, we will support later - // FrameRequestAction(pAd, pData); - break; - - default: - break; - } - - // Point to next Measurement request - pData += sizeof(RM_REQUEST_ACTION); - Length -= sizeof(RM_REQUEST_ACTION); - break; - - // We accept request only, all others are dropped - case IE_MEASUREMENT_REPORT: - case IE_AP_TX_POWER: - case IE_MEASUREMENT_CAPABILITY: - default: - return; - } - } - - // 11. Update some flags and index - pAd->StaCfg.RMReqCnt = Index; - - if (Index) - { - MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL); - RT28XX_MLME_HANDLER(pAd); - } - - DBGPRINT(RT_DEBUG_TRACE, ("<----- AironetMsgAction\n")); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID AironetRequestAction( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem) -{ - PRM_REQUEST_ACTION pReq; - - // 1. Point to next request element - pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx]; - - // 2. Parse measurement type and call appropriate functions - if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ) - // Channel Load measurement request - ChannelLoadRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx); - else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ) - // Noise Histogram measurement request - NoiseHistRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx); - else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ) - // Beacon measurement request - BeaconRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx); - else - // Unknown. Do nothing and return, this should never happen - return; - - // 3. Peek into the next request, if it's parallel, we will update the scan time to the largest one - if ((pAd->StaCfg.CurrentRMReqIdx + 1) < pAd->StaCfg.RMReqCnt) - { - pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx + 1]; - // Check for parallel bit - if ((pReq->ReqElem.Mode & 0x01) && (pReq->Measurement.Channel == pAd->StaCfg.CCXScanChannel)) - { - // Update parallel mode request information - pAd->StaCfg.ParallelReq = TRUE; - pAd->StaCfg.CCXScanTime = ((pReq->Measurement.Duration > pAd->StaCfg.CCXScanTime) ? - (pReq->Measurement.Duration) : (pAd->StaCfg.CCXScanTime)); - } - } - - // 4. Call RT28XX_MLME_HANDLER to execute the request mlme commands, Scan request is the only one used - RT28XX_MLME_HANDLER(pAd); - -} - - -/* - ======================================================================== - - Routine Description: - Prepare channel load report action, special scan operation added - to support - - Arguments: - pAd Pointer to our adapter - pData Start from element ID - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID ChannelLoadRequestAction( - IN PRTMP_ADAPTER pAd, - IN UCHAR Index) -{ - PRM_REQUEST_ACTION pReq; - MLME_SCAN_REQ_STRUCT ScanReq; - UCHAR ZeroSsid[32]; - NDIS_STATUS NStatus; - PUCHAR pOutBuffer = NULL; - PHEADER_802_11 pNullFrame; - - DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction ----->\n")); - - pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index]; - NdisZeroMemory(ZeroSsid, 32); - - // Prepare for special scan request - // The scan definition is different with our Active, Passive scan definition. - // For CCX2, Active means send out probe request with broadcast BSSID. - // Passive means no probe request sent, only listen to the beacons. - // The channel scanned is fixed as specified, no need to scan all channels. - // The scan wait time is specified in the request too. - // Passive scan Mode - - // Control state machine is not idle, reject the request - if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0)) - return; - - // Fill out stuff for scan request - ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_CHANNEL_LOAD); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; - - // Reset some internal control flags to make sure this scan works. - BssTableInit(&pAd->StaCfg.CCXBssTab); - pAd->StaCfg.ScanCnt = 0; - pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel; - pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration; - - DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel)); - - // If it's non serving channel scan, send out a null frame with PSM bit on. - if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel) - { - // Use MLME enqueue method - NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory - if (NStatus != NDIS_STATUS_SUCCESS) - return; - - pNullFrame = (PHEADER_802_11) pOutBuffer;; - // Make the power save Null frame with PSM bit on - MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid); - pNullFrame->Duration = 0; - pNullFrame->FC.Type = BTYPE_DATA; - pNullFrame->FC.PwrMgmt = PWR_SAVE; - - // Send using priority queue - MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11)); - MlmeFreeMemory(pAd, pOutBuffer); - DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n")); - RTMPusecDelay(5000); - } - - pAd->StaCfg.CCXReqType = MSRN_TYPE_CHANNEL_LOAD_REQ; - pAd->StaCfg.CLBusyBytes = 0; - // Enable Rx with promiscuous reception - RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010); - - // Set channel load measurement flag - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT); - - pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING; - - DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction <-----\n")); -} - -/* - ======================================================================== - - Routine Description: - Prepare noise histogram report action, special scan operation added - to support - - Arguments: - pAd Pointer to our adapter - pData Start from element ID - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID NoiseHistRequestAction( - IN PRTMP_ADAPTER pAd, - IN UCHAR Index) -{ - PRM_REQUEST_ACTION pReq; - MLME_SCAN_REQ_STRUCT ScanReq; - UCHAR ZeroSsid[32], i; - NDIS_STATUS NStatus; - PUCHAR pOutBuffer = NULL; - PHEADER_802_11 pNullFrame; - - DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction ----->\n")); - - pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index]; - NdisZeroMemory(ZeroSsid, 32); - - // Prepare for special scan request - // The scan definition is different with our Active, Passive scan definition. - // For CCX2, Active means send out probe request with broadcast BSSID. - // Passive means no probe request sent, only listen to the beacons. - // The channel scanned is fixed as specified, no need to scan all channels. - // The scan wait time is specified in the request too. - // Passive scan Mode - - // Control state machine is not idle, reject the request - if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0)) - return; - - // Fill out stuff for scan request - ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_NOISE); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; - - // Reset some internal control flags to make sure this scan works. - BssTableInit(&pAd->StaCfg.CCXBssTab); - pAd->StaCfg.ScanCnt = 0; - pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel; - pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration; - pAd->StaCfg.CCXReqType = MSRN_TYPE_NOISE_HIST_REQ; - - DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel)); - - // If it's non serving channel scan, send out a null frame with PSM bit on. - if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel) - { - // Use MLME enqueue method - NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory - if (NStatus != NDIS_STATUS_SUCCESS) - return; - - pNullFrame = (PHEADER_802_11) pOutBuffer; - // Make the power save Null frame with PSM bit on - MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid); - pNullFrame->Duration = 0; - pNullFrame->FC.Type = BTYPE_DATA; - pNullFrame->FC.PwrMgmt = PWR_SAVE; - - // Send using priority queue - MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11)); - MlmeFreeMemory(pAd, pOutBuffer); - DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n")); - RTMPusecDelay(5000); - } - - // Reset the statistics - for (i = 0; i < 8; i++) - pAd->StaCfg.RPIDensity[i] = 0; - - // Enable Rx with promiscuous reception - RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010); - - // Set channel load measurement flag - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT); - - pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING; - - DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction <-----\n")); -} - -/* - ======================================================================== - - Routine Description: - Prepare Beacon report action, special scan operation added - to support - - Arguments: - pAd Pointer to our adapter - pData Start from element ID - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID BeaconRequestAction( - IN PRTMP_ADAPTER pAd, - IN UCHAR Index) -{ - PRM_REQUEST_ACTION pReq; - NDIS_STATUS NStatus; - PUCHAR pOutBuffer = NULL; - PHEADER_802_11 pNullFrame; - MLME_SCAN_REQ_STRUCT ScanReq; - UCHAR ZeroSsid[32]; - - DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction ----->\n")); - - pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index]; - NdisZeroMemory(ZeroSsid, 32); - - // Prepare for special scan request - // The scan definition is different with our Active, Passive scan definition. - // For CCX2, Active means send out probe request with broadcast BSSID. - // Passive means no probe request sent, only listen to the beacons. - // The channel scanned is fixed as specified, no need to scan all channels. - // The scan wait time is specified in the request too. - if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_PASSIVE) - { - // Passive scan Mode - DBGPRINT(RT_DEBUG_TRACE, ("Passive Scan Mode!\n")); - - // Control state machine is not idle, reject the request - if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0)) - return; - - // Fill out stuff for scan request - ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_PASSIVE); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; - - // Reset some internal control flags to make sure this scan works. - BssTableInit(&pAd->StaCfg.CCXBssTab); - pAd->StaCfg.ScanCnt = 0; - pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel; - pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration; - pAd->StaCfg.CCXReqType = MSRN_TYPE_BEACON_REQ; - DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration)); - - // If it's non serving channel scan, send out a null frame with PSM bit on. - if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel) - { - // Use MLME enqueue method - NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory - if (NStatus != NDIS_STATUS_SUCCESS) - return; - - pNullFrame = (PHEADER_802_11) pOutBuffer; - // Make the power save Null frame with PSM bit on - MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid); - pNullFrame->Duration = 0; - pNullFrame->FC.Type = BTYPE_DATA; - pNullFrame->FC.PwrMgmt = PWR_SAVE; - - // Send using priority queue - MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11)); - MlmeFreeMemory(pAd, pOutBuffer); - DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n")); - RTMPusecDelay(5000); - } - - pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING; - } - else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_ACTIVE) - { - // Active scan Mode - DBGPRINT(RT_DEBUG_TRACE, ("Active Scan Mode!\n")); - - // Control state machine is not idle, reject the request - if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) - return; - - // Fill out stuff for scan request - ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_ACTIVE); - MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq); - pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; - - // Reset some internal control flags to make sure this scan works. - BssTableInit(&pAd->StaCfg.CCXBssTab); - pAd->StaCfg.ScanCnt = 0; - pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel; - pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration; - pAd->StaCfg.CCXReqType = MSRN_TYPE_BEACON_REQ; - DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration)); - - // If it's non serving channel scan, send out a null frame with PSM bit on. - if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel) - { - // Use MLME enqueue method - NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory - if (NStatus != NDIS_STATUS_SUCCESS) - return; - - pNullFrame = (PHEADER_802_11) pOutBuffer; - // Make the power save Null frame with PSM bit on - MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid); - pNullFrame->Duration = 0; - pNullFrame->FC.Type = BTYPE_DATA; - pNullFrame->FC.PwrMgmt = PWR_SAVE; - - // Send using priority queue - MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11)); - MlmeFreeMemory(pAd, pOutBuffer); - DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n")); - RTMPusecDelay(5000); - } - - pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING; - } - else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_BEACON_TABLE) - { - // Beacon report Mode, report all the APS in current bss table - DBGPRINT(RT_DEBUG_TRACE, ("Beacon Report Mode!\n")); - - // Copy current BSS table to CCX table, we can omit this step later on. - NdisMoveMemory(&pAd->StaCfg.CCXBssTab, &pAd->ScanTab, sizeof(BSS_TABLE)); - - // Create beacon report from Bss table - AironetCreateBeaconReportFromBssTable(pAd); - - // Set state to scanning - pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING; - - // Enqueue report request - // Cisco scan request is finished, prepare beacon report - MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL); - } - else - { - // Wrong scan Mode - DBGPRINT(RT_DEBUG_TRACE, ("Wrong Scan Mode!\n")); - } - - DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction <-----\n")); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID AironetReportAction( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem) -{ - PRM_REQUEST_ACTION pReq; - ULONG Now32; - - NdisGetSystemUpTime(&Now32); - pAd->StaCfg.LastBeaconRxTime = Now32; - - pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx]; - - DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction ----->\n")); - - // 1. Parse measurement type and call appropriate functions - if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ) - // Channel Load measurement request - ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx); - else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ) - // Noise Histogram measurement request - NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx); - else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ) - // Beacon measurement request - BeaconReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx); - else - // Unknown. Do nothing and return - ; - - // 2. Point to the correct index of action element, start from 0 - pAd->StaCfg.CurrentRMReqIdx++; - - // 3. Check for parallel actions - if (pAd->StaCfg.ParallelReq == TRUE) - { - pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx]; - - // Process next action right away - if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ) - // Channel Load measurement request - ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx); - else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ) - // Noise Histogram measurement request - NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx); - - pAd->StaCfg.ParallelReq = FALSE; - pAd->StaCfg.CurrentRMReqIdx++; - } - - if (pAd->StaCfg.CurrentRMReqIdx >= pAd->StaCfg.RMReqCnt) - { - // 4. There is no more unprocessed measurement request, go for transmit this report - AironetFinalReportAction(pAd); - pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE; - } - else - { - pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx]; - - if (pReq->Measurement.Channel != pAd->CommonCfg.Channel) - { - RTMPusecDelay(100000); - } - - // 5. There are more requests to be measure - MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL); - RT28XX_MLME_HANDLER(pAd); - } - - DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction <-----\n")); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID AironetFinalReportAction( - IN PRTMP_ADAPTER pAd) -{ - PUCHAR pDest; - PAIRONET_IAPP_HEADER pIAPP; - PHEADER_802_11 pHeader; - UCHAR AckRate = RATE_2; - USHORT AckDuration = 0; - NDIS_STATUS NStatus; - PUCHAR pOutBuffer = NULL; - ULONG FrameLen = 0; - - DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction ----->\n")); - - // 0. Set up the frame pointer, Frame was inited at the end of message action - pDest = &pAd->StaCfg.FrameReportBuf[LENGTH_802_11]; - - // 1. Update report IAPP fields - pIAPP = (PAIRONET_IAPP_HEADER) pDest; - - // 2. Copy Cisco SNAP header - NdisMoveMemory(pIAPP->CiscoSnapHeader, SNAP_AIRONET, LENGTH_802_1_H); - - // 3. network order for this 16bit length - pIAPP->Length = cpu2be16(pAd->StaCfg.FrameReportLen - LENGTH_802_11 - LENGTH_802_1_H); - - // 3.1 sanity check the report length, ignore it if there is nothing to report - if (be2cpu16(pIAPP->Length) <= 18) - return; - - // 4. Type must be 0x32 - pIAPP->Type = AIRONET_IAPP_TYPE; - - // 5. SubType for report must be 0x81 - pIAPP->SubType = AIRONET_IAPP_SUBTYPE_REPORT; - - // 6. DA is not used and must be zero, although the whole frame was cleared at the start of function - // We will do it again here. We can use BSSID instead - COPY_MAC_ADDR(pIAPP->DA, pAd->CommonCfg.Bssid); - - // 7. SA is the client reporting which must be our MAC - COPY_MAC_ADDR(pIAPP->SA, pAd->CurrentAddress); - - // 8. Copy the saved dialog token - pIAPP->Token = pAd->StaCfg.IAPPToken; - - // 9. Make the Report frame 802.11 header - // Reuse function in wpa.c - pHeader = (PHEADER_802_11) pAd->StaCfg.FrameReportBuf; - pAd->Sequence ++; - WpaMacHeaderInit(pAd, pHeader, 0, pAd->CommonCfg.Bssid); - - // ACK size is 14 include CRC, and its rate is based on real time information - AckRate = pAd->CommonCfg.ExpectedACKRate[pAd->CommonCfg.MlmeRate]; - AckDuration = RTMPCalcDuration(pAd, AckRate, 14); - pHeader->Duration = pAd->CommonCfg.Dsifs + AckDuration; - - // Use MLME enqueue method - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory - if (NStatus != NDIS_STATUS_SUCCESS) - return; - - // 10. Prepare report frame with dynamic outbuffer. Just simply copy everything. - MakeOutgoingFrame(pOutBuffer, &FrameLen, - pAd->StaCfg.FrameReportLen, pAd->StaCfg.FrameReportBuf, - END_OF_ARGS); - - // 11. Send using priority queue - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED; - - DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction <-----\n")); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID ChannelLoadReportAction( - IN PRTMP_ADAPTER pAd, - IN UCHAR Index) -{ - PMEASUREMENT_REPORT_ELEMENT pReport; - PCHANNEL_LOAD_REPORT pLoad; - PUCHAR pDest; - UCHAR CCABusyFraction; - - DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction ----->\n")); - - // Disable Rx with promiscuous reception, make it back to normal - RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification. - - // 0. Setup pointer for processing beacon & probe response - pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen]; - pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest; - - // 1. Fill Measurement report element field. - pReport->Eid = IE_MEASUREMENT_REPORT; - // Fixed Length at 9, not include Eid and length fields - pReport->Length = 9; - pReport->Token = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token; - pReport->Mode = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode; - pReport->Type = MSRN_TYPE_CHANNEL_LOAD_REQ; - - // 2. Fill channel report measurement data - pDest += sizeof(MEASUREMENT_REPORT_ELEMENT); - pLoad = (PCHANNEL_LOAD_REPORT) pDest; - pLoad->Channel = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel; - pLoad->Spare = 0; - pLoad->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration; - - // 3. Calculate the CCA Busy Fraction - // (Bytes + ACK size) * 8 / Tx speed * 255 / 1000 / measurement duration, use 24 us Tx speed - // = (Bytes + ACK) / 12 / duration - // 9 is the good value for pAd->StaCfg.CLFactor - // CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 9 / pLoad->Duration); - CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / pAd->StaCfg.CLFactor / pLoad->Duration); - if (CCABusyFraction < 10) - CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 3 / pLoad->Duration) + 1; - - pLoad->CCABusy = CCABusyFraction; - DBGPRINT(RT_DEBUG_TRACE, ("CLBusyByte %ld, Duration %d, Result, %d\n", pAd->StaCfg.CLBusyBytes, pLoad->Duration, CCABusyFraction)); - - DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen)); - pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(CHANNEL_LOAD_REPORT)); - DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen)); - - // 4. Clear channel load measurement flag - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT); - - // 5. reset to idle state - pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE; - - DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction <-----\n")); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID NoiseHistReportAction( - IN PRTMP_ADAPTER pAd, - IN UCHAR Index) -{ - PMEASUREMENT_REPORT_ELEMENT pReport; - PNOISE_HIST_REPORT pNoise; - PUCHAR pDest; - UCHAR i,NoiseCnt; - USHORT TotalRPICnt, TotalRPISum; - - DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction ----->\n")); - - // 0. Disable Rx with promiscuous reception, make it back to normal - RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification. - // 1. Setup pointer for processing beacon & probe response - pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen]; - pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest; - - // 2. Fill Measurement report element field. - pReport->Eid = IE_MEASUREMENT_REPORT; - // Fixed Length at 16, not include Eid and length fields - pReport->Length = 16; - pReport->Token = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token; - pReport->Mode = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode; - pReport->Type = MSRN_TYPE_NOISE_HIST_REQ; - - // 3. Fill noise histogram report measurement data - pDest += sizeof(MEASUREMENT_REPORT_ELEMENT); - pNoise = (PNOISE_HIST_REPORT) pDest; - pNoise->Channel = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel; - pNoise->Spare = 0; - pNoise->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration; - // 4. Fill Noise histogram, the total RPI counts should be 0.4 * TU - // We estimate 4000 normal packets received durning 10 seconds test. - // Adjust it if required. - // 3 is a good value for pAd->StaCfg.NHFactor - // TotalRPICnt = pNoise->Duration * 3 / 10; - TotalRPICnt = pNoise->Duration * pAd->StaCfg.NHFactor / 10; - TotalRPISum = 0; - - for (i = 0; i < 8; i++) - { - TotalRPISum += pAd->StaCfg.RPIDensity[i]; - DBGPRINT(RT_DEBUG_TRACE, ("RPI %d Conuts %d\n", i, pAd->StaCfg.RPIDensity[i])); - } - - // Double check if the counter is larger than our expectation. - // We will replace it with the total number plus a fraction. - if (TotalRPISum > TotalRPICnt) - TotalRPICnt = TotalRPISum + pNoise->Duration / 20; - - DBGPRINT(RT_DEBUG_TRACE, ("Total RPI Conuts %d\n", TotalRPICnt)); - - // 5. Initialize noise count for the total summation of 0xff - NoiseCnt = 0; - for (i = 1; i < 8; i++) - { - pNoise->Density[i] = (UCHAR) (pAd->StaCfg.RPIDensity[i] * 255 / TotalRPICnt); - if ((pNoise->Density[i] == 0) && (pAd->StaCfg.RPIDensity[i] != 0)) - pNoise->Density[i]++; - NoiseCnt += pNoise->Density[i]; - DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[%d] = 0x%02x\n", i, pNoise->Density[i])); - } - - // 6. RPI[0] represents the rest of counts - pNoise->Density[0] = 0xff - NoiseCnt; - DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[0] = 0x%02x\n", pNoise->Density[0])); - - pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(NOISE_HIST_REPORT)); - - // 7. Clear channel load measurement flag - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT); - - // 8. reset to idle state - pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE; - - DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction <-----\n")); -} - -/* - ======================================================================== - - Routine Description: - Prepare Beacon report action, - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID BeaconReportAction( - IN PRTMP_ADAPTER pAd, - IN UCHAR Index) -{ - DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction ----->\n")); - - // Looks like we don't have anything thing need to do here. - // All measurement report already finished in AddBeaconReport - // The length is in the FrameReportLen - - // reset Beacon index for next beacon request - pAd->StaCfg.LastBssIndex = 0xff; - - // reset to idle state - pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE; - - DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction <-----\n")); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - Index Current BSSID in CCXBsstab entry index - - Return Value: - - Note: - - ======================================================================== -*/ -VOID AironetAddBeaconReport( - IN PRTMP_ADAPTER pAd, - IN ULONG Index, - IN PMLME_QUEUE_ELEM pElem) -{ - PVOID pMsg; - PUCHAR pSrc, pDest; - UCHAR ReqIdx; - ULONG MsgLen; - USHORT Length; - PFRAME_802_11 pFrame; - PMEASUREMENT_REPORT_ELEMENT pReport; - PEID_STRUCT pEid; - PBEACON_REPORT pBeaconReport; - PBSS_ENTRY pBss; - - // 0. Setup pointer for processing beacon & probe response - pMsg = pElem->Msg; - MsgLen = pElem->MsgLen; - pFrame = (PFRAME_802_11) pMsg; - pSrc = pFrame->Octet; // Start from AP TSF - pBss = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index]; - ReqIdx = pAd->StaCfg.CurrentRMReqIdx; - - // 1 Check the Index, if we already create this entry, only update the average RSSI - if ((Index <= pAd->StaCfg.LastBssIndex) && (pAd->StaCfg.LastBssIndex != 0xff)) - { - pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.BssReportOffset[Index]]; - // Point to bss report information - pDest += sizeof(MEASUREMENT_REPORT_ELEMENT); - pBeaconReport = (PBEACON_REPORT) pDest; - - // Update Rx power, in dBm - // Get the original RSSI readback from BBP - pBeaconReport->RxPower += pAd->BbpRssiToDbmDelta; - // Average the Rssi reading - pBeaconReport->RxPower = (pBeaconReport->RxPower + pBss->Rssi) / 2; - // Get to dBm format - pBeaconReport->RxPower -= pAd->BbpRssiToDbmDelta; - - DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ", - pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], - pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5])); - DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld] Rssi %d, Avg Rssi %d\n", Index, (pBss->Rssi - pAd->BbpRssiToDbmDelta), pBeaconReport->RxPower - 256)); - DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.BssReportOffset[Index])); - - // Update other information here - - // Done - return; - } - - // 2. Update reported Index - pAd->StaCfg.LastBssIndex = Index; - - // 3. Setup the buffer address for copying this BSSID into reporting frame - // The offset should start after 802.11 header and report frame header. - pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen]; - - // 4. Save the start offset of each Bss in report frame - pAd->StaCfg.BssReportOffset[Index] = pAd->StaCfg.FrameReportLen; - - // 5. Fill Measurement report fields - pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest; - pReport->Eid = IE_MEASUREMENT_REPORT; - pReport->Length = 0; - pReport->Token = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token; - pReport->Mode = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode; - pReport->Type = MSRN_TYPE_BEACON_REQ; - Length = sizeof(MEASUREMENT_REPORT_ELEMENT); - pDest += sizeof(MEASUREMENT_REPORT_ELEMENT); - - // 6. Start thebeacon report format - pBeaconReport = (PBEACON_REPORT) pDest; - pDest += sizeof(BEACON_REPORT); - Length += sizeof(BEACON_REPORT); - - // 7. Copy Channel number - pBeaconReport->Channel = pBss->Channel; - pBeaconReport->Spare = 0; - pBeaconReport->Duration = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration; - pBeaconReport->PhyType = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS); - // 8. Rx power, in dBm - pBeaconReport->RxPower = pBss->Rssi - pAd->BbpRssiToDbmDelta; - - DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ", - pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], - pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5])); - DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld], Rssi %d\n", Index, pBeaconReport->RxPower - 256)); - DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.FrameReportLen)); - - pBeaconReport->BeaconInterval = pBss->BeaconPeriod; - COPY_MAC_ADDR(pBeaconReport->BSSID, pFrame->Hdr.Addr3); - NdisMoveMemory(pBeaconReport->ParentTSF, pSrc, 4); - NdisMoveMemory(pBeaconReport->TargetTSF, &pElem->TimeStamp.u.LowPart, 4); - NdisMoveMemory(&pBeaconReport->TargetTSF[4], &pElem->TimeStamp.u.HighPart, 4); - - // 9. Skip the beacon frame and offset to start of capabilityinfo since we already processed capabilityinfo - pSrc += (TIMESTAMP_LEN + 2); - pBeaconReport->CapabilityInfo = *(USHORT *)pSrc; - - // 10. Point to start of element ID - pSrc += 2; - pEid = (PEID_STRUCT) pSrc; - - // 11. Start process all variable Eid oayload and add the appropriate to the frame report - while (((PUCHAR) pEid + pEid->Len + 1) < ((PUCHAR) pFrame + MsgLen)) - { - // Only limited EID are required to report for CCX 2. It includes SSID, Supported rate, - // FH paramenter set, DS parameter set, CF parameter set, IBSS parameter set, - // TIM (report first 4 bytes only, radio measurement capability - switch (pEid->Eid) - { - case IE_SSID: - case IE_SUPP_RATES: - case IE_FH_PARM: - case IE_DS_PARM: - case IE_CF_PARM: - case IE_IBSS_PARM: - NdisMoveMemory(pDest, pEid, pEid->Len + 2); - pDest += (pEid->Len + 2); - Length += (pEid->Len + 2); - break; - - case IE_MEASUREMENT_CAPABILITY: - // Since this IE is duplicated with WPA security IE, we has to do sanity check before - // recognize it. - // 1. It also has fixed 6 bytes IE length. - if (pEid->Len != 6) - break; - // 2. Check the Cisco Aironet OUI - if (NdisEqualMemory(CISCO_OUI, (pSrc + 2), 3)) - { - // Matched, this is what we want - NdisMoveMemory(pDest, pEid, pEid->Len + 2); - pDest += (pEid->Len + 2); - Length += (pEid->Len + 2); - } - break; - - case IE_TIM: - if (pEid->Len > 4) - { - // May truncate and report the first 4 bytes only, with the eid & len, total should be 6 - NdisMoveMemory(pDest, pEid, 6); - pDest += 6; - Length += 6; - } - else - { - NdisMoveMemory(pDest, pEid, pEid->Len + 2); - pDest += (pEid->Len + 2); - Length += (pEid->Len + 2); - } - break; - - default: - break; - } - // 12. Move to next element ID - pSrc += (2 + pEid->Len); - pEid = (PEID_STRUCT) pSrc; - } - - // 13. Update the length in the header, not include EID and length - pReport->Length = Length - 4; - - // 14. Update the frame report buffer data length - pAd->StaCfg.FrameReportLen += Length; - DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen)); -} - -/* - ======================================================================== - - Routine Description: - - Arguments: - Index Current BSSID in CCXBsstab entry index - - Return Value: - - Note: - - ======================================================================== -*/ -VOID AironetCreateBeaconReportFromBssTable( - IN PRTMP_ADAPTER pAd) -{ - PMEASUREMENT_REPORT_ELEMENT pReport; - PBEACON_REPORT pBeaconReport; - UCHAR Index, ReqIdx; - USHORT Length; - PUCHAR pDest; - PBSS_ENTRY pBss; - - // 0. setup base pointer - ReqIdx = pAd->StaCfg.CurrentRMReqIdx; - - for (Index = 0; Index < pAd->StaCfg.CCXBssTab.BssNr; Index++) - { - // 1. Setup the buffer address for copying this BSSID into reporting frame - // The offset should start after 802.11 header and report frame header. - pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen]; - pBss = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index]; - Length = 0; - - // 2. Fill Measurement report fields - pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest; - pReport->Eid = IE_MEASUREMENT_REPORT; - pReport->Length = 0; - pReport->Token = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token; - pReport->Mode = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode; - pReport->Type = MSRN_TYPE_BEACON_REQ; - Length = sizeof(MEASUREMENT_REPORT_ELEMENT); - pDest += sizeof(MEASUREMENT_REPORT_ELEMENT); - - // 3. Start the beacon report format - pBeaconReport = (PBEACON_REPORT) pDest; - pDest += sizeof(BEACON_REPORT); - Length += sizeof(BEACON_REPORT); - - // 4. Copy Channel number - pBeaconReport->Channel = pBss->Channel; - pBeaconReport->Spare = 0; - pBeaconReport->Duration = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration; - pBeaconReport->PhyType = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS); - pBeaconReport->RxPower = pBss->Rssi - pAd->BbpRssiToDbmDelta; - pBeaconReport->BeaconInterval = pBss->BeaconPeriod; - pBeaconReport->CapabilityInfo = pBss->CapabilityInfo; - COPY_MAC_ADDR(pBeaconReport->BSSID, pBss->Bssid); - NdisMoveMemory(pBeaconReport->ParentTSF, pBss->PTSF, 4); - NdisMoveMemory(pBeaconReport->TargetTSF, pBss->TTSF, 8); - - // 5. Create SSID - *pDest++ = 0x00; - *pDest++ = pBss->SsidLen; - NdisMoveMemory(pDest, pBss->Ssid, pBss->SsidLen); - pDest += pBss->SsidLen; - Length += (2 + pBss->SsidLen); - - // 6. Create SupportRates - *pDest++ = 0x01; - *pDest++ = pBss->SupRateLen; - NdisMoveMemory(pDest, pBss->SupRate, pBss->SupRateLen); - pDest += pBss->SupRateLen; - Length += (2 + pBss->SupRateLen); - - // 7. DS Parameter - *pDest++ = 0x03; - *pDest++ = 1; - *pDest++ = pBss->Channel; - Length += 3; - - // 8. IBSS parameter if presents - if (pBss->BssType == BSS_ADHOC) - { - *pDest++ = 0x06; - *pDest++ = 2; - *(PUSHORT) pDest = pBss->AtimWin; - pDest += 2; - Length += 4; - } - - // 9. Update length field, not include EID and length - pReport->Length = Length - 4; - - // 10. Update total frame size - pAd->StaCfg.FrameReportLen += Length; - } -} Index: b/drivers/staging/rt2860/sta/assoc.c =================================================================== --- a/drivers/staging/rt2860/sta/assoc.c +++ b/drivers/staging/rt2860/sta/assoc.c @@ -149,7 +149,7 @@ VOID AssocTimeout(IN PVOID SystemSpecifi return; MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL); - RT28XX_MLME_HANDLER(pAd); + RTMP_MLME_HANDLER(pAd); } /* @@ -177,7 +177,7 @@ VOID ReassocTimeout(IN PVOID SystemSpeci return; MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL); - RT28XX_MLME_HANDLER(pAd); + RTMP_MLME_HANDLER(pAd); } /* @@ -205,7 +205,7 @@ VOID DisassocTimeout(IN PVOID SystemSpec return; MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL); - RT28XX_MLME_HANDLER(pAd); + RTMP_MLME_HANDLER(pAd); } /* @@ -236,7 +236,6 @@ VOID MlmeAssocReqAction( { UCHAR ApAddr[6]; HEADER_802_11 AssocHdr; - UCHAR Ccx2Len = 5; UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; USHORT ListenIntv; ULONG Timeout; @@ -247,13 +246,6 @@ VOID MlmeAssocReqAction( ULONG FrameLen = 0; ULONG tmp; USHORT VarIesOffset; - UCHAR CkipFlag; - UCHAR CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH]; - UCHAR AironetCkipIe = IE_AIRONET_CKIP; - UCHAR AironetCkipLen = CKIP_NEGOTIATION_LENGTH; - UCHAR AironetIPAddressIE = IE_AIRONET_IPADDRESS; - UCHAR AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH; - UCHAR AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00}; USHORT Status; // Block all authentication request durning WPA block period @@ -454,7 +446,8 @@ VOID MlmeAssocReqAction( RSNIe = IE_WPA2; } - if (pAd->StaCfg.WpaSupplicantUP != 1) + if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE) && + (pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE)) RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0); // Check for WPA PMK cache list @@ -471,7 +464,18 @@ VOID MlmeAssocReqAction( break; } } - +#ifdef RT2860 + /* + When AuthMode is WPA2-Enterprise and AP reboot or STA lost AP, + AP would not do PMK cache with STA after STA re-connect to AP again. + In this case, driver doesn't need to send PMKID to AP and WpaSupplicant. + */ + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) && + (NdisEqualMemory(pAd->MlmeAux.Bssid, pAd->CommonCfg.LastBssid, MAC_ADDR_LEN))) + { + FoundPMK = FALSE; + } +#endif // RT2860 // if (FoundPMK) { // Set PMK number @@ -481,7 +485,8 @@ VOID MlmeAssocReqAction( } } - if (pAd->StaCfg.WpaSupplicantUP == 1) + if ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) && + (pAd->StaCfg.bRSN_IE_FromWpaSupplicant == TRUE)) { MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE, @@ -498,7 +503,8 @@ VOID MlmeAssocReqAction( FrameLen += tmp; - if (pAd->StaCfg.WpaSupplicantUP != 1) + if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE) || + (pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE)) { // Append Variable IE NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1); @@ -513,53 +519,6 @@ VOID MlmeAssocReqAction( pAd->StaCfg.ReqVarIELen = VarIesOffset; } - // We have update that at PeerBeaconAtJoinRequest() - CkipFlag = pAd->StaCfg.CkipFlag; - if (CkipFlag != 0) - { - NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH); - CkipNegotiationBuffer[2] = 0x66; - // Make it try KP & MIC, since we have to follow the result from AssocRsp - CkipNegotiationBuffer[8] = 0x18; - CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22; - CkipFlag = 0x18; - - MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, - 1, &AironetCkipIe, - 1, &AironetCkipLen, - AironetCkipLen, CkipNegotiationBuffer, - END_OF_ARGS); - FrameLen += tmp; - } - - // Add CCX v2 request if CCX2 admin state is on - if (pAd->StaCfg.CCXControl.field.Enable == 1) - { - - // - // Add AironetIPAddressIE for Cisco CCX 2.X - // Add CCX Version - // - MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, - 1, &AironetIPAddressIE, - 1, &AironetIPAddressLen, - AironetIPAddressLen, AironetIPAddressBuffer, - 1, &Ccx2Ie, - 1, &Ccx2Len, - Ccx2Len, Ccx2IeInfo, - END_OF_ARGS); - FrameLen += tmp; - - // Add by James 03/06/27 - // Set Variable IEs Length - pAd->StaCfg.ReqVarIELen = VarIesOffset; - pAd->StaCfg.AssocInfo.RequestIELength = VarIesOffset; - - // OffsetResponseIEs follow ReqVarIE - pAd->StaCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->StaCfg.ReqVarIELen; - // End Add by James - } - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); @@ -600,7 +559,6 @@ VOID MlmeReassocReqAction( { UCHAR ApAddr[6]; HEADER_802_11 ReassocHdr; - UCHAR Ccx2Len = 5; UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00}; USHORT CapabilityInfo, ListenIntv; ULONG Timeout; @@ -749,20 +707,6 @@ VOID MlmeReassocReqAction( FrameLen += TmpLen; } - // Add CCX v2 request if CCX2 admin state is on - if (pAd->StaCfg.CCXControl.field.Enable == 1) - { - // - // Add CCX Version - // - MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, - 1, &Ccx2Ie, - 1, &Ccx2Len, - Ccx2Len, Ccx2IeInfo, - END_OF_ARGS); - FrameLen += tmp; - } - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); @@ -800,9 +744,10 @@ VOID MlmeDisassocReqAction( ULONG FrameLen = 0; NDIS_STATUS NStatus; BOOLEAN TimerCancelled; - ULONG Timeout = 0; + ULONG Timeout = 500; USHORT Status; + // skip sanity check pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg); @@ -845,11 +790,9 @@ VOID MlmeDisassocReqAction( RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */ pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP; - { - union iwreq_data wrqu; - memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN); - wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); - } + + RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0); + } /* @@ -876,7 +819,7 @@ VOID PeerAssocRspAction( EDCA_PARM EdcaParm; HT_CAPABILITY_IE HtCapability; ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE - UCHAR HtCapabilityLen; + UCHAR HtCapabilityLen = 0; UCHAR AddHtInfoLen; UCHAR NewExtChannelOffset = 0xff; @@ -889,24 +832,10 @@ VOID PeerAssocRspAction( DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status)); 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)); RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled); - if(Status == MLME_SUCCESS) - { -#ifdef RT2860 - // go to procedure listed on page 376 - AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen, - &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo); - - { - union iwreq_data wrqu; - wext_notify_event_assoc(pAd); - memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN); - memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN); - wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); - } -#endif -#ifdef RT2870 + if(Status == MLME_SUCCESS) + { UCHAR MaxSupportedRateIn500Kbps = 0; UCHAR idx; @@ -926,23 +855,14 @@ VOID PeerAssocRspAction( AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen, &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo); - StaAddMacTableEntry(pAd, &pAd->MacTab.Content[BSSID_WCID], MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo); -#endif - pAd->StaCfg.CkipFlag = CkipFlag; - if (CkipFlag & 0x18) - { - NdisZeroMemory(pAd->StaCfg.TxSEQ, 4); - NdisZeroMemory(pAd->StaCfg.RxSEQ, 4); - NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4); - pAd->StaCfg.GIV[0] = RandomByte(pAd); - pAd->StaCfg.GIV[1] = RandomByte(pAd); - pAd->StaCfg.GIV[2] = RandomByte(pAd); - pAd->StaCfg.bCkipOn = TRUE; - DBGPRINT(RT_DEBUG_TRACE, (" pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag)); - } - } - else - { + StaAddMacTableEntry(pAd, + &pAd->MacTab.Content[BSSID_WCID], + MaxSupportedRateIn500Kbps, + &HtCapability, + HtCapabilityLen, + &AddHtInfo, + AddHtInfoLen, + CapabilityInfo); } pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status); @@ -998,25 +918,19 @@ VOID PeerReassocRspAction( AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen, &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo); + { - union iwreq_data wrqu; wext_notify_event_assoc(pAd); - - memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN); - memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN); - wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); - + RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, &pAd->MlmeAux.Bssid[0], NULL, 0); } } - { // CkipFlag is no use for reassociate pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status); } } - } else { DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerReassocRspAction() sanity check fail\n")); @@ -1123,6 +1037,10 @@ VOID AssocPostProc( pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs; len = pAd->ScanTab.BssEntry[Idx].VarIELen; + //KH need to check again + // Don't allow to go to sleep mode if authmode is WPA-related. + //This can make Authentication process more smoothly. + RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); while (len > 0) { @@ -1147,6 +1065,8 @@ VOID AssocPostProc( pVIE += (pEid->Len + 2); len -= (pEid->Len + 2); } + + } if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0) @@ -1190,19 +1110,12 @@ VOID PeerDisassocAction( RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); } - // - // Get Current System time and Turn on AdjacentAPReport - // - NdisGetSystemUpTime(&pAd->StaCfg.CCXAdjacentAPLinkDownTime); - pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE; + LinkDown(pAd, TRUE); pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; - { - union iwreq_data wrqu; - memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN); - wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); - } + + RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0); } } else @@ -1359,143 +1272,16 @@ VOID Cls3errAction( COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr); } - /* - ========================================================================== - Description: - Switch between WEP and CKIP upon new association up. - Parameters: - - IRQL = DISPATCH_LEVEL - - ========================================================================== - */ -VOID SwitchBetweenWepAndCkip( - IN PRTMP_ADAPTER pAd) -{ - int i; - SHAREDKEY_MODE_STRUC csr1; - - // if KP is required. change the CipherAlg in hardware shard key table from WEP - // to CKIP. else remain as WEP - if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10)) - { - // modify hardware key table so that MAC use correct algorithm to decrypt RX - RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word); - if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP64) - csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP64; - else if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP128) - csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP128; - - if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP64) - csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP64; - else if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP128) - csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP128; - - if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP64) - csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP64; - else if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP128) - csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP128; - - if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP64) - csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP64; - else if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP128) - csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP128; - RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word); - DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg])); - - // modify software key table so that driver can specify correct algorithm in TXD upon TX - for (i=0; iSharedKey[BSS0][i].CipherAlg == CIPHER_WEP64) - pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP64; - else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP128) - pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP128; - } - } - - // else if KP NOT inused. change the CipherAlg in hardware shard key table from CKIP - // to WEP. - else - { - // modify hardware key table so that MAC use correct algorithm to decrypt RX - RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word); - if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP64) - csr1.field.Bss0Key0CipherAlg = CIPHER_WEP64; - else if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP128) - csr1.field.Bss0Key0CipherAlg = CIPHER_WEP128; - - if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP64) - csr1.field.Bss0Key1CipherAlg = CIPHER_WEP64; - else if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP128) - csr1.field.Bss0Key1CipherAlg = CIPHER_WEP128; - - if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP64) - csr1.field.Bss0Key2CipherAlg = CIPHER_WEP64; - else if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP128) - csr1.field.Bss0Key2CipherAlg = CIPHER_WEP128; - - if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP64) - csr1.field.Bss0Key3CipherAlg = CIPHER_WEP64; - else if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP128) - csr1.field.Bss0Key3CipherAlg = CIPHER_WEP128; - - // modify software key table so that driver can specify correct algorithm in TXD upon TX - for (i=0; iSharedKey[BSS0][i].CipherAlg == CIPHER_CKIP64) - pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP64; - else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP128) - pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP128; - } - - // - // On WPA-NONE, must update CipherAlg. - // Because the OID_802_11_WEP_STATUS was been set after OID_802_11_ADD_KEY - // and CipherAlg will be CIPHER_NONE by Windows ZeroConfig. - // So we need to update CipherAlg after connect. - // - if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) - { - for (i = 0; i < SHARE_KEY_NUM; i++) - { - if (pAd->SharedKey[BSS0][i].KeyLen != 0) - { - if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) - { - pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_TKIP; - } - else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { - pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_AES; - } - } - else - { - pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE; - } - } - - csr1.field.Bss0Key0CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg; - csr1.field.Bss0Key1CipherAlg = pAd->SharedKey[BSS0][1].CipherAlg; - csr1.field.Bss0Key2CipherAlg = pAd->SharedKey[BSS0][2].CipherAlg; - csr1.field.Bss0Key3CipherAlg = pAd->SharedKey[BSS0][3].CipherAlg; - } - RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word); - DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg])); - } -} int wext_notify_event_assoc( IN RTMP_ADAPTER *pAd) { - union iwreq_data wrqu; char custom[IW_CUSTOM_MAX] = {0}; if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX) { - wrqu.data.length = pAd->StaCfg.ReqVarIELen; - memcpy(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen); - wireless_send_event(pAd->net_dev, IWEVASSOCREQIE, &wrqu, custom); + NdisMoveMemory(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen); + RtmpOSWrielessEventSend(pAd, IWEVASSOCREQIE, -1, NULL, custom, pAd->StaCfg.ReqVarIELen); } else DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n")); @@ -1504,13 +1290,15 @@ int wext_notify_event_assoc( } -#ifdef RT2870 + BOOLEAN StaAddMacTableEntry( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN UCHAR MaxSupportedRateIn500Kbps, IN HT_CAPABILITY_IE *pHtCapability, IN UCHAR HtCapabilityLen, + IN ADD_HT_INFO_IE *pAddHtInfo, + IN UCHAR AddHtInfoLen, IN USHORT CapabilityInfo) { UCHAR MaxSupportedRate = RATE_11; @@ -1586,6 +1374,7 @@ BOOLEAN StaAddMacTableEntry( CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); } + NdisZeroMemory(&pEntry->HTCapability, sizeof(pEntry->HTCapability)); // If this Entry supports 802.11n, upgrade to HT rate. if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) { @@ -1605,7 +1394,9 @@ BOOLEAN StaAddMacTableEntry( pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1; } - if ((pHtCapability->HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth)) + if ((pHtCapability->HtCapInfo.ChannelWidth) && + (pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && + ((pAd->StaCfg.BssType == BSS_INFRA) || ((pAd->StaCfg.BssType == BSS_ADHOC) && (pAddHtInfo->AddHtInfo.ExtChanOffset == pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset)))) { pEntry->MaxHTPhyMode.field.BW= BW_40; pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pHtCapability->HtCapInfo.ShortGIfor40)); @@ -1677,14 +1468,13 @@ BOOLEAN StaAddMacTableEntry( CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE); if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03) CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); + NdisMoveMemory(&pEntry->HTCapability, pHtCapability, HtCapabilityLen); } else { pAd->MacTab.fAnyStationIsLegacy = TRUE; } - NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE)); - pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word; pEntry->CurrTxRate = pEntry->MaxSupportedRate; @@ -1726,4 +1516,3 @@ BOOLEAN StaAddMacTableEntry( } return TRUE; } -#endif /* RT2870 */ Index: b/drivers/staging/rt2860/sta/auth.c =================================================================== --- a/drivers/staging/rt2860/sta/auth.c +++ b/drivers/staging/rt2860/sta/auth.c @@ -108,7 +108,7 @@ VOID AuthTimeout( MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL); - RT28XX_MLME_HANDLER(pAd); + RTMP_MLME_HANDLER(pAd); } @@ -124,59 +124,12 @@ VOID MlmeAuthReqAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { - UCHAR Addr[6]; - USHORT Alg, Seq, Status; - ULONG Timeout; - HEADER_802_11 AuthHdr; - BOOLEAN TimerCancelled; - NDIS_STATUS NStatus; - PUCHAR pOutBuffer = NULL; - ULONG FrameLen = 0; - - // Block all authentication request durning WPA block period - if (pAd->StaCfg.bBlockAssoc == TRUE) - { - DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Block Auth request durning WPA block period!\n")); - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - Status = MLME_STATE_MACHINE_REJECT; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status); - } - else if(MlmeAuthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr, &Timeout, &Alg)) - { - // reset timer - RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled); - COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr); - pAd->MlmeAux.Alg = Alg; - Seq = 1; - Status = MLME_SUCCESS; - - NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory - if(NStatus != NDIS_STATUS_SUCCESS) - { - DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", Alg)); - pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; - Status = MLME_FAIL_NO_RESOURCE; - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status); - return; - } - - DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#1 (Alg=%d)...\n", Alg)); - MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, pAd->MlmeAux.Bssid); - MakeOutgoingFrame(pOutBuffer, &FrameLen, - sizeof(HEADER_802_11),&AuthHdr, - 2, &Alg, - 2, &Seq, - 2, &Status, - END_OF_ARGS); - MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); - MlmeFreeMemory(pAd, pOutBuffer); - - RTMPSetTimer(&pAd->MlmeAux.AuthTimer, Timeout); + if (AUTH_ReqSend(pAd, Elem, &pAd->MlmeAux.AuthTimer, "AUTH", 1, NULL, 0)) pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2; - } else { - DBGPRINT_ERR(("AUTH - MlmeAuthReqAction() sanity check failed\n")); + USHORT Status; + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status); @@ -207,7 +160,7 @@ VOID PeerAuthRspAtSeq2Action( ULONG FrameLen = 0; USHORT Status2; - if (PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText)) + if (PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, (PCHAR)ChlgText)) { if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2) { @@ -217,8 +170,7 @@ VOID PeerAuthRspAtSeq2Action( if (Status == MLME_SUCCESS) { // Authentication Mode "LEAP" has allow for CCX 1.X - if ((pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen) - ) + if (pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen) { pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status); @@ -457,4 +409,82 @@ VOID Cls2errAction( COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr); } +BOOLEAN AUTH_ReqSend( + IN PRTMP_ADAPTER pAd, + IN PMLME_QUEUE_ELEM pElem, + IN PRALINK_TIMER_STRUCT pAuthTimer, + IN PSTRING pSMName, + IN USHORT SeqNo, + IN PUCHAR pNewElement, + IN ULONG ElementLen) +{ + USHORT Alg, Seq, Status; + UCHAR Addr[6]; + ULONG Timeout; + HEADER_802_11 AuthHdr; + BOOLEAN TimerCancelled; + NDIS_STATUS NStatus; + PUCHAR pOutBuffer = NULL; + ULONG FrameLen = 0, tmp = 0; + + // Block all authentication request durning WPA block period + if (pAd->StaCfg.bBlockAssoc == TRUE) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s - Block Auth request durning WPA block period!\n", pSMName)); + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + Status = MLME_STATE_MACHINE_REJECT; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status); + } + else if(MlmeAuthReqSanity(pAd, pElem->Msg, pElem->MsgLen, Addr, &Timeout, &Alg)) + { + /* reset timer */ + RTMPCancelTimer(pAuthTimer, &TimerCancelled); + + COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr); + pAd->MlmeAux.Alg = Alg; + Seq = SeqNo; + Status = MLME_SUCCESS; + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory + if(NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_TRACE, ("%s - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", pSMName, Alg)); + pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; + Status = MLME_FAIL_NO_RESOURCE; + MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status); + return FALSE; + } + + DBGPRINT(RT_DEBUG_TRACE, ("%s - Send AUTH request seq#1 (Alg=%d)...\n", pSMName, Alg)); + MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, pAd->MlmeAux.Bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11),&AuthHdr, + 2, &Alg, + 2, &Seq, + 2, &Status, + END_OF_ARGS); + + if (pNewElement && ElementLen) + { + MakeOutgoingFrame(pOutBuffer+FrameLen, &tmp, + ElementLen, pNewElement, + END_OF_ARGS); + FrameLen += tmp; + } + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + RTMPSetTimer(pAuthTimer, Timeout); + return TRUE; + } + else + { + DBGPRINT_ERR(("%s - MlmeAuthReqAction() sanity check failed\n", pSMName)); + return FALSE; + } + + return TRUE; +} + Index: b/drivers/staging/rt2860/sta/auth_rsp.c =================================================================== --- a/drivers/staging/rt2860/sta/auth_rsp.c +++ b/drivers/staging/rt2860/sta/auth_rsp.c @@ -123,20 +123,24 @@ VOID PeerDeauthAction( if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason)) { - if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid)) + if (INFRA_ON(pAd) + && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid) + ) { DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n", Reason)); - { - union iwreq_data wrqu; - memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN); - wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); - } + + RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0); + // send wireless event - for deauthentication if (pAd->CommonCfg.bWirelessEvent) RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + if ((pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) && + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)) + pAd->StaCfg.bLostAp = TRUE; + LinkDown(pAd, TRUE); } } Index: b/drivers/staging/rt2860/sta/connect.c =================================================================== --- a/drivers/staging/rt2860/sta/connect.c +++ b/drivers/staging/rt2860/sta/connect.c @@ -64,6 +64,7 @@ UCHAR CipherSuiteWpaNoneAesLen = (sizeof // and are copied to pAd->StaActive #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \ { \ + NdisZeroMemory((_pAd)->CommonCfg.Ssid, MAX_LEN_OF_SSID); \ (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \ NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \ COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \ @@ -123,9 +124,7 @@ VOID MlmeCntlMachinePerformAction( switch(pAd->Mlme.CntlMachine.CurrState) { case CNTL_IDLE: - { CntlIdleProc(pAd, Elem); - } break; case CNTL_WAIT_DISASSOC: CntlWaitDisassocProc(pAd, Elem); @@ -163,11 +162,7 @@ VOID MlmeCntlMachinePerformAction( // Resume TxRing after SCANING complete. We hope the out-of-service time // won't be too long to let upper layer time-out the waiting frames RTMPResumeMsduTransmission(pAd); - if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) - { - // Cisco scan request is finished, prepare beacon report - MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL); - } + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; // @@ -188,7 +183,7 @@ VOID MlmeCntlMachinePerformAction( pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; } break; -#ifdef RT2870 +#ifdef RTMP_MAC_USB // // This state is for that we want to connect to an AP but // it didn't find on BSS List table. So we need to scan the air first, @@ -212,14 +207,14 @@ VOID MlmeCntlMachinePerformAction( // // Check if we can connect to. // - BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen); + BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, (CHAR *) pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen); if (pAd->MlmeAux.SsidBssTab.BssNr > 0) { MlmeAutoReconnectLastSSID(pAd); } } break; -#endif // RT2870 // +#endif // RTMP_MAC_USB // default: DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType)); break; @@ -294,11 +289,13 @@ VOID CntlOidScanProc( ULONG BssIdx = BSS_NOT_FOUND; BSS_ENTRY CurrBss; + + // record current BSS if network is connected. // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS. if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { - BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel); + BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, (PUCHAR)pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel); if (BssIdx != BSS_NOT_FOUND) { NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY)); @@ -318,7 +315,7 @@ VOID CntlOidScanProc( pAd->ScanTab.BssNr = 1; } - ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE); + ScanParmFill(pAd, &ScanReq, (PSTRING) Elem->Msg, Elem->MsgLen, BSS_ANY, SCAN_ACTIVE); MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; @@ -341,11 +338,6 @@ VOID CntlOidSsidProc( MLME_DISASSOC_REQ_STRUCT DisassocReq; ULONG Now; -#ifdef RT2860 - // BBP and RF are not accessible in PS mode, we has to wake them up first - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) - AsicForceWakeup(pAd, RTMP_HALT); -#endif // Step 1. record the desired user settings to MlmeAux NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); @@ -354,6 +346,7 @@ VOID CntlOidSsidProc( NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN); pAd->MlmeAux.BssType = pAd->StaCfg.BssType; + pAd->StaCfg.bAutoConnectByBssid = FALSE; // // Update Reconnect Ssid, that user desired to connect. @@ -364,7 +357,7 @@ VOID CntlOidSsidProc( // step 2. find all matching BSS in the lastest SCAN result (inBssTab) // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order - BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); + BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, (PCHAR)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n", pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid)); @@ -423,15 +416,7 @@ VOID CntlOidSsidProc( } pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - - { - union iwreq_data wrqu; - - memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN); - memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN); - wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); - - } + RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, &pAd->MlmeAux.Bssid[0], NULL, 0); } } else if (INFRA_ON(pAd)) @@ -483,7 +468,7 @@ VOID CntlOidSsidProc( MLME_SCAN_REQ_STRUCT ScanReq; DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n")); - ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE); + ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE); MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; // Reset Missed scan number @@ -519,52 +504,41 @@ VOID CntlOidRTBssidProc( COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid); pAd->MlmeAux.BssType = pAd->StaCfg.BssType; - // - // Update Reconnect Ssid, that user desired to connect. - // - NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID); - pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen; - NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); - // find the desired BSS in the latest SCAN result table BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel); if (BssIdx == BSS_NOT_FOUND) { + MLME_SCAN_REQ_STRUCT ScanReq; + DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n")); - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + //pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + + DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. start a new scan\n")); + ScanParmFill(pAd, &ScanReq, (PSTRING) pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE); + MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq); + pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN; + // Reset Missed scan number + NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime); return; } + // + // Update Reconnect Ssid, that user desired to connect. + // + NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID); + pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen; + NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen); + // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why? // Because we need this entry to become the JOIN target in later on SYNC state machine pAd->MlmeAux.BssIdx = 0; pAd->MlmeAux.SsidBssTab.BssNr = 1; NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY)); - // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP - // we just follow normal procedure. The reason of user doing this may because he/she changed - // AP to another channel, but we still received BEACON from it thus don't claim Link Down. - // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following - // checking, we'll disassociate then re-do normal association with this AP at the new channel. - // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do - // connection when setting the same BSSID. - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && - MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid)) - { - // already connected to the same BSSID, go back to idle state directly - DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n")); - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - - { - union iwreq_data wrqu; - - memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN); - memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN); - wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); + // Add SSID into MlmeAux for site surey joining hidden SSID + pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen; + NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen); - } - } - else { if (INFRA_ON(pAd)) { @@ -625,11 +599,11 @@ VOID CntlOidRTBssidProc( // Set Mix cipher flag pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE; - if (pAd->StaCfg.bMixCipher == TRUE) + /*if (pAd->StaCfg.bMixCipher == TRUE) { // If mix cipher, re-build RSNIE RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0); - } + }*/ // No active association, join the BSS immediately DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n", pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5])); @@ -654,19 +628,26 @@ VOID CntlMlmeRoamingProc( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { - // TODO: - // AP in different channel may show lower RSSI than actual value?? - // should we add a weighting factor to compensate it? + UCHAR BBPValue = 0; + DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n")); + { + //Let BBP register at 20MHz to do (fast) roaming. + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); + BBPValue &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); + NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab)); pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr; BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab); pAd->MlmeAux.BssIdx = 0; IterateOnBssTab(pAd); + } } + /* ========================================================================== Description: @@ -696,7 +677,7 @@ VOID CntlWaitDisassocProc( if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC)) { DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid)); - StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); + StartParmFill(pAd, &StartReq, (PCHAR)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START; } @@ -763,15 +744,15 @@ VOID CntlWaitJoinProc( if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch)) { - AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared); + AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_KEY); } else { - AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen); - } + AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_OPEN); } MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ, sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq); + } pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH; } @@ -817,7 +798,7 @@ VOID CntlWaitStartProc( DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel)); return; } - + NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16); if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) { N_ChannelCheck(pAd); @@ -825,7 +806,6 @@ VOID CntlWaitStartProc( NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE)); RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo); pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE; - NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16); NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16); COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd); @@ -911,16 +891,16 @@ VOID CntlWaitAuthProc( (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch)) { // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first - AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared); + AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_KEY); } else { - AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen); - } + AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, AUTH_MODE_OPEN); } MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ, sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq); + } pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2; } } @@ -950,11 +930,13 @@ VOID CntlWaitAuthProc2( DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n")); AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo, ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount); + { MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ, sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC; } + } else { if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) && @@ -998,14 +980,14 @@ VOID CntlWaitAssocProc( NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT)); if (Reason == MLME_SUCCESS) { - LinkUp(pAd, BSS_INFRA); - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; - DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx)); - if (pAd->CommonCfg.bWirelessEvent) { RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); } + + LinkUp(pAd, BSS_INFRA); + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; + DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx)); } else { @@ -1036,15 +1018,16 @@ VOID CntlWaitReassocProc( NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT)); if (Result == MLME_SUCCESS) { + // send wireless event - for association + if (pAd->CommonCfg.bWirelessEvent) + RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); + + // // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC // LinkUp(pAd, BSS_INFRA); - // send wireless event - for association - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); - pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx)); } @@ -1052,14 +1035,15 @@ VOID CntlWaitReassocProc( { // reassoc failed, try to pick next BSS in the BSS Table DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx)); + { pAd->MlmeAux.RoamIdx++; IterateOnBssTab2(pAd); } } + } } -#ifdef RT2870 VOID AdhocTurnOnQos( IN PRTMP_ADAPTER pAd) { @@ -1094,7 +1078,6 @@ VOID AdhocTurnOnQos( } AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); } -#endif /* RT2870 */ /* ========================================================================== @@ -1111,17 +1094,19 @@ VOID LinkUp( ULONG Now; UINT32 Data; BOOLEAN Cancelled; - UCHAR Value = 0, idx; - MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry; + UCHAR Value = 0, idx = 0, HashIdx = 0; + MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry = NULL; -#ifdef RT2860 - if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)) + // Init ChannelQuality to prevent DEAD_CQI at initial LinkUp + pAd->Mlme.ChannelQuality = 50; + + pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid); + if (pEntry) { - RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT); - RTMPusecDelay(6000); - pAd->bPCIclkOff = FALSE; + MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr); + pEntry = NULL; } -#endif + pEntry = &pAd->MacTab.Content[BSSID_WCID]; @@ -1140,52 +1125,16 @@ VOID LinkUp( COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd); - // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS - // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place - // to examine if cipher algorithm switching is required. - //rt2860b. Don't know why need this - SwitchBetweenWepAndCkip(pAd); - -#ifdef RT2860 - // Before power save before link up function, We will force use 1R. - // So after link up, check Rx antenna # again. - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); - if(pAd->Antenna.field.RxPath == 3) - { - Value |= (0x10); - } - else if(pAd->Antenna.field.RxPath == 2) - { - Value |= (0x8); - } - else if(pAd->Antenna.field.RxPath == 1) - { - Value |= (0x0); - } - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); - pAd->StaCfg.BBPR3 = Value; -#endif /* RT2860 */ - if (BssType == BSS_ADHOC) { OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON); - if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && - (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE)) - { - pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2; - } - else if ((pAd->CommonCfg.Channel > 2) && - (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) && - (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW)) - { - pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2; - } -#ifdef RT2870 + if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) AdhocTurnOnQos(pAd); -#endif + + InitChannelRelatedValue(pAd); DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" )); } @@ -1197,6 +1146,7 @@ VOID LinkUp( DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" )); } +#if defined(RT2870) || defined(RT3070) // 3*3 // reset Tx beamforming bit RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); @@ -1221,9 +1171,6 @@ VOID LinkUp( RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); Value &= (~0x20); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); -#ifdef RT2860 - pAd->StaCfg.BBPR3 = Value; -#endif RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); Data &= 0xfffffffe; @@ -1258,9 +1205,6 @@ VOID LinkUp( RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); Value |= (0x20); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); -#ifdef RT2860 - pAd->StaCfg.BBPR3 = Value; -#endif if (pAd->MACVersion == 0x28600100) { @@ -1290,9 +1234,6 @@ VOID LinkUp( RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); Value &= (~0x20); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); -#ifdef RT2860 - pAd->StaCfg.BBPR3 = Value; -#endif if (pAd->MACVersion == 0x28600100) { @@ -1306,6 +1247,8 @@ VOID LinkUp( } RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); +#endif // RT2870 // + // // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission // @@ -1467,25 +1410,23 @@ VOID LinkUp( // On WPA mode, Remove All Keys if not connect to the last BSSID // Key will be set after 4-way handshake. // - if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)) + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) { ULONG IV; // Remove all WPA keys + RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); RTMPWPARemoveAllKeys(pAd); pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP; // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP // If IV related values are too large in GroupMsg2, AP would ignore this message. - IV = 0; + IV = 1; IV |= (pAd->StaCfg.DefaultKeyId << 30); AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0); - -#ifdef RT2860 - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); -#endif } + // NOTE: // the decision of using "short slot time" or not may change dynamically due to // new STA association to the AP. so we have to decide that upon parsing BEACON, not here @@ -1502,28 +1443,6 @@ VOID LinkUp( // Add BSSID to WCID search table AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid); - NdisAcquireSpinLock(&pAd->MacTabLock); - // add this BSSID entry into HASH table - { - UCHAR HashIdx; - - //pEntry = &pAd->MacTab.Content[BSSID_WCID]; - HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid); - if (pAd->MacTab.Hash[HashIdx] == NULL) - { - pAd->MacTab.Hash[HashIdx] = pEntry; - } - else - { - pCurrEntry = pAd->MacTab.Hash[HashIdx]; - while (pCurrEntry->pNext != NULL) - pCurrEntry = pCurrEntry->pNext; - pCurrEntry->pNext = pEntry; - } - } - NdisReleaseSpinLock(&pAd->MacTabLock); - - // If WEP is enabled, add paiewise and shared key if (((pAd->StaCfg.WpaSupplicantUP)&& (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&& @@ -1549,6 +1468,7 @@ VOID LinkUp( // Assign group key info RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL); + pEntry->Aid = BSSID_WCID; // Assign pairwise key info RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry); } @@ -1565,26 +1485,55 @@ VOID LinkUp( { pAd->IndicateMediaState = NdisMediaStateConnected; pAd->ExtraInfo = GENERAL_LINK_UP; -#ifdef RT2870 RTMP_IndicateMediaState(pAd); -#endif + } + else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) || + (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) + RTMPSetTimer(&pAd->Mlme.LinkDownTimer, LINK_DOWN_TIMEOUT); } // -- -#ifdef RT2860 - RTMP_IndicateMediaState(pAd); -#endif // Add BSSID in my MAC Table. NdisAcquireSpinLock(&pAd->MacTabLock); - RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN); - pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID; - pAd->MacTab.Content[BSSID_WCID].pAd = pAd; - pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl + // add this MAC entry into HASH table + if (pEntry) + { + HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid); + if (pAd->MacTab.Hash[HashIdx] == NULL) + { + pAd->MacTab.Hash[HashIdx] = pEntry; + } + else + { + pCurrEntry = pAd->MacTab.Hash[HashIdx]; + while (pCurrEntry->pNext != NULL) + { + pCurrEntry = pCurrEntry->pNext; + } + pCurrEntry->pNext = pEntry; + } + } + RTMPMoveMemory(pEntry->Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN); + pEntry->Aid = BSSID_WCID; + pEntry->pAd = pAd; + pEntry->ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl pAd->MacTab.Size = 1; // infra mode always set MACtab size =1. - pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC; - pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC; - pAd->MacTab.Content[BSSID_WCID].AuthMode = pAd->StaCfg.AuthMode; - pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus; + pEntry->Sst = SST_ASSOC; + pEntry->AuthState = SST_ASSOC; + pEntry->AuthMode = pAd->StaCfg.AuthMode; + pEntry->WepStatus = pAd->StaCfg.WepStatus; + if (pEntry->AuthMode < Ndis802_11AuthModeWPA) + { + pEntry->WpaState = AS_NOTUSE; + pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll; + } + else + { + pEntry->WpaState = AS_PTKSTART; + pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP; + } NdisReleaseSpinLock(&pAd->MacTabLock); DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n", @@ -1598,32 +1547,34 @@ VOID LinkUp( { if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3) { - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED); OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE); RTMPSetPiggyBack(pAd, TRUE); DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n")); } else if (pAd->MlmeAux.APRalinkIe & 0x00000001) { OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE); + DBGPRINT(RT_DEBUG_TRACE, ("Ralink Aggregation\n")); } } if (pAd->MlmeAux.APRalinkIe != 0x0) { - if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE)) + if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE)) { AsicEnableRDG(pAd); } - OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET); - CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET); + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET); } else { OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET); - CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET); + CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET); } } @@ -1707,8 +1658,8 @@ VOID LinkUp( // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable // // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is. - if ( - !(pAd->CommonCfg.RxStream == 1 && pAd->CommonCfg.TxStream == 1) && + if (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) && + (pAd->StaCfg.bForceTxBurst == FALSE) && (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))) { @@ -1770,9 +1721,16 @@ VOID LinkUp( if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled) { + if (pAd->StaCfg.WpaSupplicantUP && + (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) && + (pAd->StaCfg.IEEE8021X == TRUE)) + ; + else + { pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll; } + } NdisAcquireSpinLock(&pAd->MacTabLock); pEntry->PortSecured = pAd->StaCfg.PortSecured; @@ -1792,9 +1750,23 @@ VOID LinkUp( } RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); -#ifdef RT2860 + RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); -#endif + +#ifdef RT2860 + /* + When AuthMode is WPA2-Enterprise and AP reboot or STA lost AP, + WpaSupplicant would not send EapolStart to AP after STA re-connect to AP again. + In this case, driver would send EapolStart to AP. + */ + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) && + (NdisEqualMemory(pAd->CommonCfg.Bssid, pAd->CommonCfg.LastBssid, MAC_ADDR_LEN)) && + (pAd->StaCfg.bLostAp == TRUE)) + { + WpaSendEapolStart(pAd, pAd->CommonCfg.Bssid); + } +#endif // RT2860 // + pAd->StaCfg.bLostAp = FALSE; } /* @@ -1827,21 +1799,17 @@ VOID LinkDown( IN BOOLEAN IsReqFromAP) { UCHAR i, ByteValue = 0; -#ifdef RT2860 BOOLEAN Cancelled; -#endif // Do nothing if monitor mode is on if (MONITOR_ON(pAd)) return; -#ifdef RT2860 RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); - RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); - + //Comment the codes, beasue the line 2291 call the same function. + //RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); // Not allow go to sleep within linkdown function. RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); -#endif if (pAd->CommonCfg.bWirelessEvent) { @@ -1851,7 +1819,7 @@ VOID LinkDown( DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n")); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); -#ifdef RT2860 +#ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) { BOOLEAN Cancelled; @@ -1859,16 +1827,20 @@ VOID LinkDown( RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); } - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) || - RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) || - RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) + pAd->bPCIclkOff = FALSE; +#endif // RTMP_MAC_PCI // + + if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) +|| RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) + || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) { - AsicForceWakeup(pAd, RTMP_HALT); + AUTO_WAKEUP_STRUC AutoWakeupCfg; + AsicForceWakeup(pAd, TRUE); + AutoWakeupCfg.word = 0; + RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); } - pAd->bPCIclkOff = FALSE; -#endif if (ADHOC_ON(pAd)) // Adhoc mode link down { DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n")); @@ -1917,34 +1889,22 @@ VOID LinkDown( // 3. short preamble OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED); - if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE) - { - // - // Record current AP's information. - // for later used reporting Adjacent AP report. - // - pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel; - pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen; - NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen); - COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid); - } + } + for (i=1; iMacTab.Content[i].ValidAsCLI == TRUE) MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr); } - pAd->StaCfg.CCXQosECWMin = 4; - pAd->StaCfg.CCXQosECWMax = 10; - AsicSetSlotTime(pAd, TRUE); //FALSE); AsicSetEdcaParm(pAd, NULL); // Set LED RTMPSetLED(pAd, LED_LINK_DOWN); - pAd->LedIndicatorStregth = 0xF0; + pAd->LedIndicatorStrength = 0xF0; RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it. AsicDisableSync(pAd); @@ -1971,8 +1931,8 @@ VOID LinkDown( pAd->StaCfg.WpaState = SS_START; // Clear Replay counter NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8); - } + } // // if link down come from AP, we need to remove all WPA keys on WPA mode. @@ -2001,31 +1961,21 @@ VOID LinkDown( } NdisAcquireSpinLock(&pAd->MacTabLock); + NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE)); pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured; NdisReleaseSpinLock(&pAd->MacTabLock); pAd->StaCfg.MicErrCnt = 0; - // Turn off Ckip control flag - pAd->StaCfg.bCkipOn = FALSE; - pAd->StaCfg.CCXEnable = FALSE; - pAd->IndicateMediaState = NdisMediaStateDisconnected; // Update extra information to link is up pAd->ExtraInfo = GENERAL_LINK_DOWN; -#ifdef RT2860 - pAd->StaCfg.AdhocBOnlyJoined = FALSE; - pAd->StaCfg.AdhocBGJoined = FALSE; - pAd->StaCfg.Adhoc20NJoined = FALSE; -#endif pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; - // Reset the Current AP's IP address - NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4); -#ifdef RT2870 +#ifdef RTMP_MAC_USB pAd->bUsbTxBulkAggre = FALSE; -#endif // RT2870 // +#endif // RTMP_MAC_USB // // Clean association information NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)); @@ -2081,30 +2031,18 @@ VOID LinkDown( RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff); RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS); -#ifdef RT2860 - // Allow go to sleep after linkdown steps. +// Allow go to sleep after linkdown steps. RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); -#endif - { - union iwreq_data wrqu; - memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN); - wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); - } + RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0); - if (IS_RT3090(pAd)) +#ifdef RT30xx + if ((IS_RT30xx(pAd) || IS_RT3090(pAd)||IS_RT3390(pAd)) + &&(pAd->Antenna.field.RxPath>1||pAd->Antenna.field.TxPath>1)) { - UINT32 macdata; - // disable MMPS BBP control register - RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &ByteValue); - ByteValue &= ~(0x04); //bit 2 - RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, ByteValue); - - // disable MMPS MAC control register - RTMP_IO_READ32(pAd, 0x1210, &macdata); - macdata &= ~(0x09); //bit 0, 3 - RTMP_IO_WRITE32(pAd, 0x1210, macdata); + RTMP_ASIC_MMPS_DISABLE(pAd); } +#endif // RT30xx // } /* @@ -2161,11 +2099,11 @@ VOID IterateOnBssTab( // Set Mix cipher flag pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE; - if (pAd->StaCfg.bMixCipher == TRUE) + /*if (pAd->StaCfg.bMixCipher == TRUE) { // If mix cipher, re-build RSNIE RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0); - } + }*/ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr)); JoinParmFill(pAd, &JoinReq, BssIdx); @@ -2176,15 +2114,19 @@ VOID IterateOnBssTab( else if (pAd->StaCfg.BssType == BSS_ADHOC) { DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid)); - StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); + StartParmFill(pAd, &StartReq, (PCHAR)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen); MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START; } else // no more BSS { - DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel)); + + { AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); + DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); + } + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; } } @@ -2218,9 +2160,13 @@ VOID IterateOnBssTab2( } else // no more BSS { - DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel)); + + { AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); + DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr)); + } + pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; } } @@ -2252,7 +2198,7 @@ VOID JoinParmFill( VOID ScanParmFill( IN PRTMP_ADAPTER pAd, IN OUT MLME_SCAN_REQ_STRUCT *ScanReq, - IN CHAR Ssid[], + IN STRING Ssid[], IN UCHAR SsidLen, IN UCHAR BssType, IN UCHAR ScanType) @@ -2310,10 +2256,32 @@ VOID AuthParmFill( ========================================================================== */ +#ifdef RTMP_MAC_PCI +VOID ComposePsPoll( + IN PRTMP_ADAPTER pAd) +{ + NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME)); + pAd->PsPollFrame.FC.Type = BTYPE_CNTL; + pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL; + pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000; + COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid); + COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress); +} - -#ifdef RT2870 - +// IRQL = DISPATCH_LEVEL +VOID ComposeNullFrame( + IN PRTMP_ADAPTER pAd) +{ + NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11)); + pAd->NullFrame.FC.Type = BTYPE_DATA; + pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC; + pAd->NullFrame.FC.ToDs = 1; + COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid); + COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress); + COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid); +} +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB VOID MlmeCntlConfirm( IN PRTMP_ADAPTER pAd, IN ULONG MsgType, @@ -2321,29 +2289,23 @@ VOID MlmeCntlConfirm( { MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg); } -#endif VOID ComposePsPoll( IN PRTMP_ADAPTER pAd) { -#ifdef RT2870 PTXINFO_STRUC pTxInfo; PTXWI_STRUC pTxWI; DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n")); -#endif NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME)); -#ifdef RT2870 pAd->PsPollFrame.FC.PwrMgmt = 0; -#endif pAd->PsPollFrame.FC.Type = BTYPE_CNTL; pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL; pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000; COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid); COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress); -#ifdef RT2870 RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100); pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0]; RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); @@ -2353,17 +2315,14 @@ VOID ComposePsPoll( RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME)); // Append 4 extra zero bytes. pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4; -#endif } // IRQL = DISPATCH_LEVEL VOID ComposeNullFrame( IN PRTMP_ADAPTER pAd) { -#ifdef RT2870 PTXINFO_STRUC pTxInfo; PTXWI_STRUC pTxWI; -#endif NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11)); pAd->NullFrame.FC.Type = BTYPE_DATA; @@ -2372,7 +2331,6 @@ VOID ComposeNullFrame( COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid); COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress); COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid); -#ifdef RT2870 RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100); pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0]; RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); @@ -2381,11 +2339,8 @@ VOID ComposeNullFrame( 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit); RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11)); pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4; -#endif } - - - +#endif // RTMP_MAC_USB // /* ========================================================================== @@ -2407,7 +2362,7 @@ ULONG MakeIbssBeacon( LARGE_INTEGER FakeTimestamp; ULONG FrameLen = 0; PTXWI_STRUC pTxWI = &pAd->BeaconTxWI; - CHAR *pBeaconFrame = pAd->BeaconBuf; + UCHAR *pBeaconFrame = pAd->BeaconBuf; BOOLEAN Privacy; UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES]; UCHAR SupRateLen = 0; @@ -2566,4 +2521,138 @@ ULONG MakeIbssBeacon( return FrameLen; } +VOID InitChannelRelatedValue( + IN PRTMP_ADAPTER pAd) +{ +#ifdef RT2860 + UCHAR Value = 0; + UINT32 Data = 0; + +#ifdef RTMP_MAC_PCI + // In power save , We will force use 1R. + // So after link up, check Rx antenna # again. + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); + if(pAd->Antenna.field.RxPath == 3) + { + Value |= (0x10); + } + else if(pAd->Antenna.field.RxPath == 2) + { + Value |= (0x8); + } + else if(pAd->Antenna.field.RxPath == 1) + { + Value |= (0x0); + } + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); + pAd->StaCfg.BBPR3 = Value; +#endif // RTMP_MAC_PCI // + + pAd->CommonCfg.CentralChannel = pAd->MlmeAux.CentralChannel; + pAd->CommonCfg.Channel = pAd->MlmeAux.Channel; + // Change to AP channel + if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) + { + // Must using 40MHz. + pAd->CommonCfg.BBPCurrentBW = BW_40; + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); + Value &= (~0x18); + Value |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); + + // RX : control channel at lower + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); + Value &= (~0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); +#ifdef RTMP_MAC_PCI + pAd->StaCfg.BBPR3 = Value; +#endif // RTMP_MAC_PCI // + + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); + Data &= 0xfffffffe; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); + + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); + DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); + } + + DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel )); + } + else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) + { + // Must using 40MHz. + pAd->CommonCfg.BBPCurrentBW = BW_40; + AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); + Value &= (~0x18); + Value |= 0x10; + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); + + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); + Data |= 0x1; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); + Value |= (0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); +#ifdef RTMP_MAC_PCI + pAd->StaCfg.BBPR3 = Value; +#endif // RTMP_MAC_PCI // + + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16); + DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); + } + + DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel )); + } + else + { + pAd->CommonCfg.BBPCurrentBW = BW_20; + pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; + AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); + AsicLockChannel(pAd, pAd->CommonCfg.Channel); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value); + Value &= (~0x18); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value); + + RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data); + Data &= 0xfffffffe; + RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data); + + RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value); + Value &= (~0x20); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value); +#ifdef RTMP_MAC_PCI + pAd->StaCfg.BBPR3 = Value; +#endif // RTMP_MAC_PCI // + + if (pAd->MACVersion == 0x28600100) + { + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08); + RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11); + DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" )); + } + + DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz !!! \n" )); + } + + RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW); +#endif // RT2860 // +} + Index: b/drivers/staging/rt2860/sta/dls.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/sta/dls.c @@ -0,0 +1,2192 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + dls.c + + Abstract: + Handle WMM-DLS state machine + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- + Rory Chen 02-14-2006 + Arvin Tai 06-03-2008 Modified for RT28xx + */ + +#include "../rt_config.h" + +/* + ========================================================================== + Description: + dls state machine init, including state transition and timer init + Parameters: + Sm - pointer to the dls state machine + Note: + The state machine looks like this + + DLS_IDLE + MT2_MLME_DLS_REQUEST MlmeDlsReqAction + MT2_PEER_DLS_REQUEST PeerDlsReqAction + MT2_PEER_DLS_RESPONSE PeerDlsRspAction + MT2_MLME_DLS_TEARDOWN MlmeTearDownAction + MT2_PEER_DLS_TEARDOWN PeerTearDownAction + + IRQL = PASSIVE_LEVEL + + ========================================================================== + */ +void DlsStateMachineInit( + IN PRTMP_ADAPTER pAd, + IN STATE_MACHINE *Sm, + OUT STATE_MACHINE_FUNC Trans[]) +{ + UCHAR i; + + StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG, (STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE); + + // the first column + StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_REQ, (STATE_MACHINE_FUNC)MlmeDlsReqAction); + StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_REQ, (STATE_MACHINE_FUNC)PeerDlsReqAction); + StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_RSP, (STATE_MACHINE_FUNC)PeerDlsRspAction); + StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)MlmeDlsTearDownAction); + StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)PeerDlsTearDownAction); + + for (i=0; iStaCfg.DLSEntry[i].pAd = pAd; + RTMPInitTimer(pAd, &pAd->StaCfg.DLSEntry[i].Timer, GET_TIMER_FUNCTION(DlsTimeoutAction), pAd, FALSE); + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID MlmeDlsReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + HEADER_802_11 DlsReqHdr; + PRT_802_11_DLS pDLS = NULL; + UCHAR Category = CATEGORY_DLS; + UCHAR Action = ACTION_DLS_REQUEST; + ULONG tmp; + USHORT reason; + ULONG Timeout; + BOOLEAN TimerCancelled; + + if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &reason)) + return; + + DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsReqAction() \n")); + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory + if (NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsReqAction() allocate memory failed \n")); + return; + } + + ActHeaderInit(pAd, &DlsReqHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid); + + // Build basic frame first + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DlsReqHdr, + 1, &Category, + 1, &Action, + 6, &pDLS->MacAddr, + 6, pAd->CurrentAddress, + 2, &pAd->StaActive.CapabilityInfo, + 2, &pDLS->TimeOut, + 1, &SupRateIe, + 1, &pAd->MlmeAux.SupRateLen, + pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate, + END_OF_ARGS); + + if (pAd->MlmeAux.ExtRateLen != 0) + { + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &ExtRateIe, + 1, &pAd->MlmeAux.ExtRateLen, + pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate, + END_OF_ARGS); + FrameLen += tmp; + } + + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) + { + UCHAR HtLen; + + + // add HT Capability IE + HtLen = sizeof(HT_CAPABILITY_IE); + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &HtCapIe, + 1, &HtLen, + HtLen, &pAd->CommonCfg.HtCapability, + END_OF_ARGS); + FrameLen = FrameLen + tmp; + } + + RTMPCancelTimer(&pDLS->Timer, &TimerCancelled); + Timeout = DLS_TIMEOUT; + RTMPSetTimer(&pDLS->Timer, Timeout); + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID PeerDlsReqAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + USHORT StatusCode = MLME_SUCCESS; + HEADER_802_11 DlsRspHdr; + UCHAR Category = CATEGORY_DLS; + UCHAR Action = ACTION_DLS_RESPONSE; + ULONG tmp; + USHORT CapabilityInfo; + UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN]; + USHORT DLSTimeOut; + SHORT i; + ULONG Timeout; + BOOLEAN TimerCancelled; + PRT_802_11_DLS pDLS = NULL; + UCHAR MaxSupportedRateIn500Kbps = 0; + UCHAR SupportedRatesLen; + UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR HtCapabilityLen; + HT_CAPABILITY_IE HtCapability; + + if (!PeerDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &DLSTimeOut, + &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability)) + return; + + // supported rates array may not be sorted. sort it and find the maximum rate + for (i = 0; i < SupportedRatesLen; i++) + { + if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f)) + MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f; + } + + 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])); + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory + if (NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() allocate memory failed \n")); + return; + } + + if (!INFRA_ON(pAd)) + { + StatusCode = MLME_REQUEST_DECLINED; + } + else if (!pAd->CommonCfg.bWmmCapable) + { + StatusCode = MLME_DEST_STA_IS_NOT_A_QSTA; + } + else if (!pAd->CommonCfg.bDLSCapable) + { + StatusCode = MLME_REQUEST_DECLINED; + } + else + { + // find table to update parameters + for (i = (MAX_NUM_OF_DLS_ENTRY-1); i >= 0; i--) + { + if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY; + else + { + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); + pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH; + } + + pAd->StaCfg.DLSEntry[i].Sequence = 0; + pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut; + pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut; + if (HtCapabilityLen != 0) + pAd->StaCfg.DLSEntry[i].bHTCap = TRUE; + else + pAd->StaCfg.DLSEntry[i].bHTCap = FALSE; + pDLS = &pAd->StaCfg.DLSEntry[i]; + break; + } + } + + // can not find in table, create a new one + if (i < 0) + { + DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() can not find same entry \n")); + for (i=(MAX_NUM_OF_DLS_ENTRY - 1); i >= MAX_NUM_OF_INIT_DLS_ENTRY; i--) + { + if (!pAd->StaCfg.DLSEntry[i].Valid) + { + MAC_TABLE_ENTRY *pEntry; + UCHAR MaxSupportedRate = RATE_11; + + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + { + pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY; + } + else + { + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); + pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH; + } + + pAd->StaCfg.DLSEntry[i].Sequence = 0; + pAd->StaCfg.DLSEntry[i].Valid = TRUE; + pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut; + pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut; + NdisMoveMemory(pAd->StaCfg.DLSEntry[i].MacAddr, SA, MAC_ADDR_LEN); + if (HtCapabilityLen != 0) + pAd->StaCfg.DLSEntry[i].bHTCap = TRUE; + else + pAd->StaCfg.DLSEntry[i].bHTCap = FALSE; + pDLS = &pAd->StaCfg.DLSEntry[i]; + pEntry = MacTableInsertDlsEntry(pAd, SA, i); + + switch (MaxSupportedRateIn500Kbps) + { + case 108: MaxSupportedRate = RATE_54; break; + case 96: MaxSupportedRate = RATE_48; break; + case 72: MaxSupportedRate = RATE_36; break; + case 48: MaxSupportedRate = RATE_24; break; + case 36: MaxSupportedRate = RATE_18; break; + case 24: MaxSupportedRate = RATE_12; break; + case 18: MaxSupportedRate = RATE_9; break; + case 12: MaxSupportedRate = RATE_6; break; + case 22: MaxSupportedRate = RATE_11; break; + case 11: MaxSupportedRate = RATE_5_5; break; + case 4: MaxSupportedRate = RATE_2; break; + case 2: MaxSupportedRate = RATE_1; break; + default: MaxSupportedRate = RATE_11; break; + } + + pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate); + + if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE) + { + pEntry->MaxHTPhyMode.field.MODE = MODE_CCK; + pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate; + pEntry->MinHTPhyMode.field.MODE = MODE_CCK; + pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate; + pEntry->HTPhyMode.field.MODE = MODE_CCK; + pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate; + } + else + { + pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM; + pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; + pEntry->MinHTPhyMode.field.MODE = MODE_OFDM; + pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; + pEntry->HTPhyMode.field.MODE = MODE_OFDM; + pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; + } + + pEntry->MaxHTPhyMode.field.BW = BW_20; + pEntry->MinHTPhyMode.field.BW = BW_20; + + pEntry->HTCapability.MCSSet[0] = 0; + pEntry->HTCapability.MCSSet[1] = 0; + + // If this Entry supports 802.11n, upgrade to HT rate. + if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) + { + UCHAR j, bitmask; //k,bitmask; + CHAR ii; + + DBGPRINT(RT_DEBUG_TRACE, ("DLS - PeerDlsReqAction() Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n", + SA[0], SA[1], SA[2], SA[3], SA[4], SA[5])); + + if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF)) + { + pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD; + } + else + { + pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX; + pAd->MacTab.fAnyStationNonGF = TRUE; + pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1; + } + + if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth)) + { + pEntry->MaxHTPhyMode.field.BW= BW_40; + pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40)); + } + else + { + pEntry->MaxHTPhyMode.field.BW = BW_20; + pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20)); + pAd->MacTab.fAnyStation20Only = TRUE; + } + + // find max fixed rate + for (ii=15; ii>=0; ii--) + { + j = ii/8; + bitmask = (1<<(ii-(j*8))); + if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask)) + { + pEntry->MaxHTPhyMode.field.MCS = ii; + break; + } + if (ii==0) + break; + } + + + if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) + { + + DBGPRINT(RT_DEBUG_OFF, ("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n", + pAd->StaCfg.DesiredTransmitSetting.field.MCS)); + if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32) + { + // Fix MCS as HT Duplicated Mode + pEntry->MaxHTPhyMode.field.BW = 1; + pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX; + pEntry->MaxHTPhyMode.field.STBC = 0; + pEntry->MaxHTPhyMode.field.ShortGI = 0; + pEntry->MaxHTPhyMode.field.MCS = 32; + } + else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS) + { + // STA supports fixed MCS + pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + } + } + + pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC)); + pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity; + pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor; + pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs; + pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize; + pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word; + + if (HtCapability.HtCapInfo.ShortGIfor20) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE); + if (HtCapability.HtCapInfo.ShortGIfor40) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE); + if (HtCapability.HtCapInfo.TxSTBC) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE); + if (HtCapability.HtCapInfo.RxSTBC) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE); + if (HtCapability.ExtHtCapInfo.PlusHTC) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE); + if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE); + if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); + + NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE)); + } + + pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word; + pEntry->CurrTxRate = pEntry->MaxSupportedRate; + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); + + if (pAd->StaCfg.bAutoTxRateSwitch == TRUE) + { + PUCHAR pTable; + UCHAR TableSize = 0; + + MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex); + pEntry->bAutoTxRateSwitch = TRUE; + } + else + { + pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE; + pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + pEntry->bAutoTxRateSwitch = FALSE; + + RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry); + } + pEntry->RateLen = SupportedRatesLen; + + break; + } + } + } + StatusCode = MLME_SUCCESS; + + // can not find in table, create a new one + if (i < 0) + { + StatusCode = MLME_QOS_UNSPECIFY; + 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)); + } + else + { + DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n", + i, SA[0], SA[1], SA[2], SA[3], SA[4], SA[5])); + } + } + + ActHeaderInit(pAd, &DlsRspHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid); + + // Build basic frame first + if (StatusCode == MLME_SUCCESS) + { + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DlsRspHdr, + 1, &Category, + 1, &Action, + 2, &StatusCode, + 6, SA, + 6, pAd->CurrentAddress, + 2, &pAd->StaActive.CapabilityInfo, + 1, &SupRateIe, + 1, &pAd->MlmeAux.SupRateLen, + pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate, + END_OF_ARGS); + + if (pAd->MlmeAux.ExtRateLen != 0) + { + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &ExtRateIe, + 1, &pAd->MlmeAux.ExtRateLen, + pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate, + END_OF_ARGS); + FrameLen += tmp; + } + + if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) + { + UCHAR HtLen; + + + // add HT Capability IE + HtLen = sizeof(HT_CAPABILITY_IE); + MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp, + 1, &HtCapIe, + 1, &HtLen, + HtLen, &pAd->CommonCfg.HtCapability, + END_OF_ARGS); + FrameLen = FrameLen + tmp; + } + + if (pDLS && (pDLS->Status != DLS_FINISH)) + { + RTMPCancelTimer(&pDLS->Timer, &TimerCancelled); + Timeout = DLS_TIMEOUT; + RTMPSetTimer(&pDLS->Timer, Timeout); + } + } + else + { + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DlsRspHdr, + 1, &Category, + 1, &Action, + 2, &StatusCode, + 6, SA, + 6, pAd->CurrentAddress, + END_OF_ARGS); + } + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID PeerDlsRspAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + USHORT CapabilityInfo; + UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN]; + USHORT StatusCode; + SHORT i; + BOOLEAN TimerCancelled; + UCHAR MaxSupportedRateIn500Kbps = 0; + UCHAR SupportedRatesLen; + UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES]; + UCHAR HtCapabilityLen; + HT_CAPABILITY_IE HtCapability; + + if (!pAd->CommonCfg.bDLSCapable) + return; + + if (!INFRA_ON(pAd)) + return; + + if (!PeerDlsRspSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode, + &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability)) + return; + + // supported rates array may not be sorted. sort it and find the maximum rate + for (i=0; iStaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + if (StatusCode == MLME_SUCCESS) + { + MAC_TABLE_ENTRY *pEntry; + UCHAR MaxSupportedRate = RATE_11; + + pEntry = MacTableInsertDlsEntry(pAd, SA, i); + + switch (MaxSupportedRateIn500Kbps) + { + case 108: MaxSupportedRate = RATE_54; break; + case 96: MaxSupportedRate = RATE_48; break; + case 72: MaxSupportedRate = RATE_36; break; + case 48: MaxSupportedRate = RATE_24; break; + case 36: MaxSupportedRate = RATE_18; break; + case 24: MaxSupportedRate = RATE_12; break; + case 18: MaxSupportedRate = RATE_9; break; + case 12: MaxSupportedRate = RATE_6; break; + case 22: MaxSupportedRate = RATE_11; break; + case 11: MaxSupportedRate = RATE_5_5; break; + case 4: MaxSupportedRate = RATE_2; break; + case 2: MaxSupportedRate = RATE_1; break; + default: MaxSupportedRate = RATE_11; break; + } + + pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate); + + if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE) + { + pEntry->MaxHTPhyMode.field.MODE = MODE_CCK; + pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate; + pEntry->MinHTPhyMode.field.MODE = MODE_CCK; + pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate; + pEntry->HTPhyMode.field.MODE = MODE_CCK; + pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate; + } + else + { + pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM; + pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; + pEntry->MinHTPhyMode.field.MODE = MODE_OFDM; + pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; + pEntry->HTPhyMode.field.MODE = MODE_OFDM; + pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; + } + + pEntry->MaxHTPhyMode.field.BW = BW_20; + pEntry->MinHTPhyMode.field.BW = BW_20; + + pEntry->HTCapability.MCSSet[0] = 0; + pEntry->HTCapability.MCSSet[1] = 0; + + // If this Entry supports 802.11n, upgrade to HT rate. + if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) + { + UCHAR j, bitmask; //k,bitmask; + CHAR ii; + + DBGPRINT(RT_DEBUG_OFF, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n", + SA[0], SA[1], SA[2], SA[3], SA[4], SA[5])); + + if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF)) + { + pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD; + } + else + { + pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX; + pAd->MacTab.fAnyStationNonGF = TRUE; + pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1; + } + + if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth)) + { + pEntry->MaxHTPhyMode.field.BW= BW_40; + pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40)); + } + else + { + pEntry->MaxHTPhyMode.field.BW = BW_20; + pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20)); + pAd->MacTab.fAnyStation20Only = TRUE; + } + + // find max fixed rate + for (ii=15; ii>=0; ii--) + { + j = ii/8; + bitmask = (1<<(ii-(j*8))); + if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask)) + { + pEntry->MaxHTPhyMode.field.MCS = ii; + break; + } + if (ii==0) + break; + } + + if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) + { + if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32) + { + // Fix MCS as HT Duplicated Mode + pEntry->MaxHTPhyMode.field.BW = 1; + pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX; + pEntry->MaxHTPhyMode.field.STBC = 0; + pEntry->MaxHTPhyMode.field.ShortGI = 0; + pEntry->MaxHTPhyMode.field.MCS = 32; + } + else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS) + { + // STA supports fixed MCS + pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + } + } + + pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC)); + pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity; + pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor; + pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs; + pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize; + pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word; + + if (HtCapability.HtCapInfo.ShortGIfor20) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE); + if (HtCapability.HtCapInfo.ShortGIfor40) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE); + if (HtCapability.HtCapInfo.TxSTBC) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE); + if (HtCapability.HtCapInfo.RxSTBC) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE); + if (HtCapability.ExtHtCapInfo.PlusHTC) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE); + if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE); + if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); + + NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE)); + } + pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word; + pEntry->CurrTxRate = pEntry->MaxSupportedRate; + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); + + if (pAd->StaCfg.bAutoTxRateSwitch == TRUE) + { + PUCHAR pTable; + UCHAR TableSize = 0; + + MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex); + pEntry->bAutoTxRateSwitch = TRUE; + } + else + { + pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE; + pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + pEntry->bAutoTxRateSwitch = FALSE; + + RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry); + } + pEntry->RateLen = SupportedRatesLen; + + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + { + // If support WPA or WPA2, start STAKey hand shake, + // If failed hand shake, just tear down peer DLS + if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS) + { + MLME_DLS_REQ_STRUCT MlmeDlsReq; + USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT; + + DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq); + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n")); + } + else + { + pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY; + DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n")); + } + } + else + { + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); + pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH; + 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])); + } + + //initialize seq no for DLS frames. + pAd->StaCfg.DLSEntry[i].Sequence = 0; + if (HtCapabilityLen != 0) + pAd->StaCfg.DLSEntry[i].bHTCap = TRUE; + else + pAd->StaCfg.DLSEntry[i].bHTCap = FALSE; + } + else + { + // DLS setup procedure failed. + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); + DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode)); + } + } + } + + if (i >= MAX_NUM_OF_INIT_DLS_ENTRY) + { + DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() update timeout value \n")); + for (i=(MAX_NUM_OF_DLS_ENTRY-1); i>=MAX_NUM_OF_INIT_DLS_ENTRY; i--) + { + if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + if (StatusCode == MLME_SUCCESS) + { + MAC_TABLE_ENTRY *pEntry; + UCHAR MaxSupportedRate = RATE_11; + + pEntry = MacTableInsertDlsEntry(pAd, SA, i); + + switch (MaxSupportedRateIn500Kbps) + { + case 108: MaxSupportedRate = RATE_54; break; + case 96: MaxSupportedRate = RATE_48; break; + case 72: MaxSupportedRate = RATE_36; break; + case 48: MaxSupportedRate = RATE_24; break; + case 36: MaxSupportedRate = RATE_18; break; + case 24: MaxSupportedRate = RATE_12; break; + case 18: MaxSupportedRate = RATE_9; break; + case 12: MaxSupportedRate = RATE_6; break; + case 22: MaxSupportedRate = RATE_11; break; + case 11: MaxSupportedRate = RATE_5_5; break; + case 4: MaxSupportedRate = RATE_2; break; + case 2: MaxSupportedRate = RATE_1; break; + default: MaxSupportedRate = RATE_11; break; + } + + pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate); + + if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE) + { + pEntry->MaxHTPhyMode.field.MODE = MODE_CCK; + pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate; + pEntry->MinHTPhyMode.field.MODE = MODE_CCK; + pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate; + pEntry->HTPhyMode.field.MODE = MODE_CCK; + pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate; + } + else + { + pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM; + pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; + pEntry->MinHTPhyMode.field.MODE = MODE_OFDM; + pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; + pEntry->HTPhyMode.field.MODE = MODE_OFDM; + pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate]; + } + + pEntry->MaxHTPhyMode.field.BW = BW_20; + pEntry->MinHTPhyMode.field.BW = BW_20; + + pEntry->HTCapability.MCSSet[0] = 0; + pEntry->HTCapability.MCSSet[1] = 0; + + // If this Entry supports 802.11n, upgrade to HT rate. + if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) + { + UCHAR j, bitmask; //k,bitmask; + CHAR ii; + + DBGPRINT(RT_DEBUG_TRACE, ("DLS - PeerDlsRspAction Receive Peer HT Capable STA from %02x:%02x:%02x:%02x:%02x:%02x\n", + SA[0], SA[1], SA[2], SA[3], SA[4], SA[5])); + + if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF)) + { + pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD; + } + else + { + pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX; + pAd->MacTab.fAnyStationNonGF = TRUE; + pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1; + } + + if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth)) + { + pEntry->MaxHTPhyMode.field.BW= BW_40; + pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40)); + } + else + { + pEntry->MaxHTPhyMode.field.BW = BW_20; + pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20)); + pAd->MacTab.fAnyStation20Only = TRUE; + } + + // find max fixed rate + for (ii=15; ii>=0; ii--) + { + j = ii/8; + bitmask = (1<<(ii-(j*8))); + if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask)) + { + pEntry->MaxHTPhyMode.field.MCS = ii; + break; + } + if (ii==0) + break; + } + + if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) + { + DBGPRINT(RT_DEBUG_OFF, ("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n", + pAd->StaCfg.DesiredTransmitSetting.field.MCS)); + if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32) + { + // Fix MCS as HT Duplicated Mode + pEntry->MaxHTPhyMode.field.BW = 1; + pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX; + pEntry->MaxHTPhyMode.field.STBC = 0; + pEntry->MaxHTPhyMode.field.ShortGI = 0; + pEntry->MaxHTPhyMode.field.MCS = 32; + } + else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS) + { + // STA supports fixed MCS + pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + } + } + + pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC)); + pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity; + pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor; + pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs; + pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize; + pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word; + + if (HtCapability.HtCapInfo.ShortGIfor20) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE); + if (HtCapability.HtCapInfo.ShortGIfor40) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE); + if (HtCapability.HtCapInfo.TxSTBC) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE); + if (HtCapability.HtCapInfo.RxSTBC) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE); + if (HtCapability.ExtHtCapInfo.PlusHTC) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE); + if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE); + if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03) + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE); + + NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE)); + } + + pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word; + pEntry->CurrTxRate = pEntry->MaxSupportedRate; + CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE); + + if (pAd->StaCfg.bAutoTxRateSwitch == TRUE) + { + PUCHAR pTable; + UCHAR TableSize = 0; + + MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex); + pEntry->bAutoTxRateSwitch = TRUE; + } + else + { + pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE; + pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS; + pEntry->bAutoTxRateSwitch = FALSE; + + RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry); + } + pEntry->RateLen = SupportedRatesLen; + + if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) + { + // If support WPA or WPA2, start STAKey hand shake, + // If failed hand shake, just tear down peer DLS + if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS) + { + MLME_DLS_REQ_STRUCT MlmeDlsReq; + USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT; + + DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq); + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n")); + } + else + { + pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY; + DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n")); + } + } + else + { + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); + pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH; + 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])); + } + pAd->StaCfg.DLSEntry[i].Sequence = 0; + if (HtCapabilityLen != 0) + pAd->StaCfg.DLSEntry[i].bHTCap = TRUE; + else + pAd->StaCfg.DLSEntry[i].bHTCap = FALSE; + } + else + { + // DLS setup procedure failed. + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); + DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode)); + } + } + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID MlmeDlsTearDownAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + UCHAR Category = CATEGORY_DLS; + UCHAR Action = ACTION_DLS_TEARDOWN; + USHORT ReasonCode = REASON_QOS_UNSPECIFY; + HEADER_802_11 DlsTearDownHdr; + PRT_802_11_DLS pDLS; + BOOLEAN TimerCancelled; + UCHAR i; + + if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode)) + return; + + DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode)); + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory + if (NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsTearDownAction() allocate memory failed \n")); + return; + } + + ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid); + + // Build basic frame first + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DlsTearDownHdr, + 1, &Category, + 1, &Action, + 6, &pDLS->MacAddr, + 6, pAd->CurrentAddress, + 2, &ReasonCode, + END_OF_ARGS); + + MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + RTMPCancelTimer(&pDLS->Timer, &TimerCancelled); + + // Remove key in local dls table entry + for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++) + { + if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr); + } + } + + // clear peer dls table entry + for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++) + { + if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); + MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr); + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID PeerDlsTearDownAction( + IN PRTMP_ADAPTER pAd, + IN MLME_QUEUE_ELEM *Elem) +{ + UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN]; + USHORT ReasonCode; + UINT i; + BOOLEAN TimerCancelled; + + if (!pAd->CommonCfg.bDLSCapable) + return; + + if (!INFRA_ON(pAd)) + return; + + if (!PeerDlsTearDownSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode)) + return; + + 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)); + + // clear local dls table entry + for (i=0; iStaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); + //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID); + //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID); + MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr); + } + } + + // clear peer dls table entry + for (i=MAX_NUM_OF_INIT_DLS_ENTRY; iStaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); + //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID); + //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID); + MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr); + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID RTMPCheckDLSTimeOut( + IN PRTMP_ADAPTER pAd) +{ + ULONG i; + MLME_DLS_REQ_STRUCT MlmeDlsReq; + USHORT reason = REASON_QOS_UNSPECIFY; + + if (! pAd->CommonCfg.bDLSCapable) + return; + + if (! INFRA_ON(pAd)) + return; + + // If timeout value is equaled to zero, it means always not be timeout. + + // update local dls table entry + for (i=0; iStaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + && (pAd->StaCfg.DLSEntry[i].TimeOut != 0)) + { + pAd->StaCfg.DLSEntry[i].CountDownTimer --; + + if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0) + { + reason = REASON_QOS_REQUEST_TIMEOUT; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq); + } + } + } + + // update peer dls table entry + for (i=MAX_NUM_OF_INIT_DLS_ENTRY; iStaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + && (pAd->StaCfg.DLSEntry[i].TimeOut != 0)) + { + pAd->StaCfg.DLSEntry[i].CountDownTimer --; + + if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0) + { + reason = REASON_QOS_REQUEST_TIMEOUT; + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq); + } + } + } +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +BOOLEAN RTMPRcvFrameDLSCheck( + IN PRTMP_ADAPTER pAd, + IN PHEADER_802_11 pHeader, + IN ULONG Len, + IN PRT28XX_RXD_STRUC pRxD) +{ + ULONG i; + BOOLEAN bFindEntry = FALSE; + BOOLEAN bSTAKeyFrame = FALSE; + PEAPOL_PACKET pEap; + PUCHAR pProto, pAddr = NULL; + PUCHAR pSTAKey = NULL; + UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY]; + UCHAR Mic[16], OldMic[16]; + UCHAR digest[80]; + UCHAR DlsPTK[80]; + UCHAR temp[64]; + BOOLEAN TimerCancelled; + CIPHER_KEY PairwiseKey; + + + if (! pAd->CommonCfg.bDLSCapable) + return bSTAKeyFrame; + + if (! INFRA_ON(pAd)) + return bSTAKeyFrame; + + if (Len < LENGTH_802_11 + 6 + 2) /* LENGTH_802_11 + LLC + EAPOL protocol type */ + return bSTAKeyFrame; + + pProto = (PUCHAR)pHeader + LENGTH_802_11; + + if ((pHeader->FC.SubType & 0x08)) + pProto += 2; /* QOS Control field */ + + /* Skip 4-bytes for HTC */ + if (pHeader->FC.Order && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))) + { + pProto += 4; + } + + /* L2PAD bit on will pad 2 bytes at LLC */ + if (pRxD->L2PAD) + { + pProto += 2; + } + + pProto += 6; /* 0xAA 0xAA 0xAA 0x00 0x00 0x00 */ + + if ((!(pHeader->FC.SubType & 0x08)) && (!RTMPEqualMemory(EAPOL, pProto, 2))) + return bSTAKeyFrame; + + pAddr = pHeader->Addr2; + + if (RTMPEqualMemory(EAPOL, pProto, 2) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)) + { + pEap = (PEAPOL_PACKET) (pProto + 2); + + 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, + (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16), + pEap->KeyDesc.KeyInfo.KeyMic, + pEap->KeyDesc.KeyInfo.Install, + pEap->KeyDesc.KeyInfo.KeyAck, + pEap->KeyDesc.KeyInfo.Secure, + pEap->KeyDesc.KeyInfo.EKD_DL, + pEap->KeyDesc.KeyInfo.Error, + pEap->KeyDesc.KeyInfo.Request)); + + if ((Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16)) && pEap->KeyDesc.KeyInfo.KeyMic + && pEap->KeyDesc.KeyInfo.Install && pEap->KeyDesc.KeyInfo.KeyAck && pEap->KeyDesc.KeyInfo.Secure + && pEap->KeyDesc.KeyInfo.EKD_DL && !pEap->KeyDesc.KeyInfo.Error && !pEap->KeyDesc.KeyInfo.Request) + { + // First validate replay counter, only accept message with larger replay counter + // Let equal pass, some AP start with all zero replay counter + NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY); + if ((RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) && + (RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0)) + return bSTAKeyFrame; + + //RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); + RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); + DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n", + pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2], + pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5], + pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1])); + + // put these code segment to get the replay counter + if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) + return bSTAKeyFrame; + + // Check MIC value + // Save the MIC and replace with zero + // use proprietary PTK + NdisZeroMemory(temp, 64); + NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32); + WpaDerivePTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK); + + NdisMoveMemory(OldMic, pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); + NdisZeroMemory(pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); + if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) + { + // AES + HMAC_SHA1(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, digest, SHA1_DIGEST_SIZE); + NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); + } + else + { + HMAC_MD5(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, Mic, MD5_DIGEST_SIZE); + } + + if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC)) + { + DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in Msg1 of STAKey handshake! \n")); + return bSTAKeyFrame; + } + else + DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in Msg1 of STAKey handshake! \n")); + if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0C) + && (pEap->KeyDesc.KeyData[4] == 0x43) && (pEap->KeyDesc.KeyData[5] == 0x02)) + { + pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2) + pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6) + + DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%ld, KeyDataLen=%d\n", + pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1])); + + bSTAKeyFrame = TRUE; + } + + } + else if (Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE)) + { + RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); + DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n", + pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2], + pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5], + pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1])); + } + } + + // If timeout value is equaled to zero, it means always not be timeout. + // update local dls table entry + for (i= 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++) + { + if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + if (bSTAKeyFrame) + { + PMAC_TABLE_ENTRY pEntry; + + // STAKey frame, add pairwise key table + pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); + + PairwiseKey.KeyLen = LEN_TKIP_EK; + NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK); + NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK); + NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK); + + //PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg; + if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) + PairwiseKey.CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) + PairwiseKey.CipherAlg = CIPHER_AES; + + pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE); + //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast + //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr); + // Add Pair-wise key to Asic +#ifdef RTMP_MAC_PCI + AsicAddPairwiseKeyEntry(pAd, + pAd->StaCfg.DLSEntry[i].MacAddr, + (UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, + &PairwiseKey); + + RTMPAddWcidAttributeEntry(pAd, + BSS0, + 0, + PairwiseKey.CipherAlg, + pEntry); + +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB + { + RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo; + COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr); + KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID; + NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY)); + RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY)); + } + { + PMAC_TABLE_ENTRY pDLSEntry; + pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE); + pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg; + RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY)); + } +#endif // RTMP_MAC_USB // + NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY)); + DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n")); + + RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr); + + DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n")); + } + else + { + // Data frame, update timeout value + if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + { + pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut; + //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr); + } + } + + bFindEntry = TRUE; + } + } + + // update peer dls table entry + for (i=MAX_NUM_OF_INIT_DLS_ENTRY; iStaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + if (bSTAKeyFrame) + { + PMAC_TABLE_ENTRY pEntry = NULL; + + // STAKey frame, add pairwise key table, and send STAkey Msg-2 + pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH; + RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled); + + PairwiseKey.KeyLen = LEN_TKIP_EK; + NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK); + NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK); + NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK); + + //PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg; + if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) + PairwiseKey.CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) + PairwiseKey.CipherAlg = CIPHER_AES; + + pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE); + //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast + //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr); + // Add Pair-wise key to Asic +#ifdef RTMP_MAC_PCI + AsicAddPairwiseKeyEntry(pAd, + pAd->StaCfg.DLSEntry[i].MacAddr, + (UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, + &PairwiseKey); + + RTMPAddWcidAttributeEntry(pAd, + BSS0, + 0, + PairwiseKey.CipherAlg, + pEntry); +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB + { + RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo; + COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr); + KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID; + NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY)); + RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY)); + } + { + PMAC_TABLE_ENTRY pDLSEntry; + pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE); + pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg; + RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY)); + } +#endif // RTMP_MAC_USB // + NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY)); + DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n")); + + // If support WPA or WPA2, start STAKey hand shake, + // If failed hand shake, just tear down peer DLS + if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS) + { + MLME_DLS_REQ_STRUCT MlmeDlsReq; + USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT; + + pAd->StaCfg.DLSEntry[i].Valid = FALSE; + pAd->StaCfg.DLSEntry[i].Status = DLS_NONE; + DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq); + } + else + { + DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n")); + } + } + else + { + // Data frame, update timeout value + if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + { + pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut; + } + } + + bFindEntry = TRUE; + } + } + + + return bSTAKeyFrame; +} + +/* + ======================================================================== + + Routine Description: + Check if the frame can be sent through DLS direct link interface + + Arguments: + pAd Pointer to adapter + + Return Value: + DLS entry index + + Note: + + ======================================================================== +*/ +INT RTMPCheckDLSFrame( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA) +{ + INT rval = -1; + INT i; + + if (!pAd->CommonCfg.bDLSCapable) + return rval; + + if (!INFRA_ON(pAd)) + return rval; + + do{ + // check local dls table entry + for (i=0; iStaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && + MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + rval = i; + break; + } + } + + // check peer dls table entry + for (i=MAX_NUM_OF_INIT_DLS_ENTRY; iStaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && + MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + rval = i; + break; + } + } + } while (FALSE); + + return rval; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +VOID RTMPSendDLSTearDownFrame( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA) +{ + PUCHAR pOutBuffer = NULL; + NDIS_STATUS NStatus; + HEADER_802_11 DlsTearDownHdr; + ULONG FrameLen = 0; + USHORT Reason = REASON_QOS_QSTA_LEAVING_QBSS; + UCHAR Category = CATEGORY_DLS; + UCHAR Action = ACTION_DLS_TEARDOWN; + UCHAR i = 0; + + if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) || + RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) + return; + + DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n")); + + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory + if (NStatus != NDIS_STATUS_SUCCESS) + { + DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n")); + return; + } + + ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid); + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(HEADER_802_11), &DlsTearDownHdr, + 1, &Category, + 1, &Action, + 6, pDA, + 6, pAd->CurrentAddress, + 2, &Reason, + END_OF_ARGS); + + MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); + MlmeFreeMemory(pAd, pOutBuffer); + + // Remove key in local dls table entry + for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++) + { + if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr); + } + } + + // Remove key in peer dls table entry + for (i=MAX_NUM_OF_INIT_DLS_ENTRY; iStaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) + && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr)) + { + MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr); + } + } + + DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i)); +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +NDIS_STATUS RTMPSendSTAKeyRequest( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA) +{ + UCHAR Header802_3[14]; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + EAPOL_PACKET Packet; + UCHAR Mic[16]; + UCHAR digest[80]; + PUCHAR pOutBuffer = NULL; + PNDIS_PACKET pNdisPacket; + UCHAR temp[64]; + UCHAR DlsPTK[80]; + + 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])); + + pAd->Sequence ++; + MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL); + + // Zero message body + NdisZeroMemory(&Packet, sizeof(Packet)); + Packet.ProVer = EAPOL_VER; + Packet.ProType = EAPOLKey; + Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE andPeer MAC address + + // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE) + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) + { + Packet.KeyDesc.Type = WPA1_KEY_DESC; + } + else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + Packet.KeyDesc.Type = WPA2_KEY_DESC; + } + + // Key descriptor version + Packet.KeyDesc.KeyInfo.KeyDescVer = + (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP)); + + Packet.KeyDesc.KeyInfo.KeyMic = 1; + Packet.KeyDesc.KeyInfo.Secure = 1; + Packet.KeyDesc.KeyInfo.Request = 1; + + Packet.KeyDesc.KeyDataLen[1] = 12; + + // use our own OUI to distinguish proprietary with standard. + Packet.KeyDesc.KeyData[0] = 0xDD; + Packet.KeyDesc.KeyData[1] = 0x0A; + Packet.KeyDesc.KeyData[2] = 0x00; + Packet.KeyDesc.KeyData[3] = 0x0C; + Packet.KeyDesc.KeyData[4] = 0x43; + Packet.KeyDesc.KeyData[5] = 0x03; + NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN); + + NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY); + + // Allocate buffer for transmitting message + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + if (NStatus != NDIS_STATUS_SUCCESS) + return NStatus; + + // Prepare EAPOL frame for MIC calculation + // Be careful, only EAPOL frame is counted for MIC calculation + MakeOutgoingFrame(pOutBuffer, &FrameLen, + Packet.Body_Len[1] + 4, &Packet, + END_OF_ARGS); + + // use proprietary PTK + NdisZeroMemory(temp, 64); + NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32); + WpaDerivePTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK); + + // calculate MIC + if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) + { + // AES + NdisZeroMemory(digest, sizeof(digest)); + HMAC_SHA1(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE); + NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC); + } + else + { + NdisZeroMemory(Mic, sizeof(Mic)); + HMAC_MD5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE); + NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); + } + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(Header802_3), Header802_3, + Packet.Body_Len[1] + 4, &Packet, + END_OF_ARGS); + + NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen); + if (NStatus == NDIS_STATUS_SUCCESS) + { + RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID); + STASendPacket(pAd, pNdisPacket); + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); + } + + MlmeFreeMemory(pAd, pOutBuffer); + + DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen)); + + return NStatus; +} + +/* + ========================================================================== + Description: + + IRQL = DISPATCH_LEVEL + + ========================================================================== + */ +NDIS_STATUS RTMPSendSTAKeyHandShake( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pDA) +{ + UCHAR Header802_3[14]; + NDIS_STATUS NStatus; + ULONG FrameLen = 0; + EAPOL_PACKET Packet; + UCHAR Mic[16]; + UCHAR digest[80]; + PUCHAR pOutBuffer = NULL; + PNDIS_PACKET pNdisPacket; + UCHAR temp[64]; + UCHAR DlsPTK[80]; // Due to dirver can not get PTK, use proprietary PTK + + 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])); + + pAd->Sequence ++; + MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL); + + // Zero message body + NdisZeroMemory(&Packet, sizeof(Packet)); + Packet.ProVer = EAPOL_VER; + Packet.ProType = EAPOLKey; + Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE and Peer MAC address + + // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE) + if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) + { + Packet.KeyDesc.Type = WPA1_KEY_DESC; + } + else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) + { + Packet.KeyDesc.Type = WPA2_KEY_DESC; + } + + // Key descriptor version + Packet.KeyDesc.KeyInfo.KeyDescVer = + (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP)); + + Packet.KeyDesc.KeyInfo.KeyMic = 1; + Packet.KeyDesc.KeyInfo.Secure = 1; + + Packet.KeyDesc.KeyDataLen[1] = 12; + + // use our own OUI to distinguish proprietary with standard. + Packet.KeyDesc.KeyData[0] = 0xDD; + Packet.KeyDesc.KeyData[1] = 0x0A; + Packet.KeyDesc.KeyData[2] = 0x00; + Packet.KeyDesc.KeyData[3] = 0x0C; + Packet.KeyDesc.KeyData[4] = 0x43; + Packet.KeyDesc.KeyData[5] = 0x03; + NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN); + + NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY); + + // Allocate buffer for transmitting message + NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); + if (NStatus != NDIS_STATUS_SUCCESS) + return NStatus; + + // Prepare EAPOL frame for MIC calculation + // Be careful, only EAPOL frame is counted for MIC calculation + MakeOutgoingFrame(pOutBuffer, &FrameLen, + Packet.Body_Len[1] + 4, &Packet, + END_OF_ARGS); + + // use proprietary PTK + NdisZeroMemory(temp, 64); + NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32); + WpaDerivePTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK); + + // calculate MIC + if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) + { + // AES + NdisZeroMemory(digest, sizeof(digest)); + HMAC_SHA1(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE); + NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC); + } + else + { + NdisZeroMemory(Mic, sizeof(Mic)); + HMAC_MD5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE); + NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); + } + + MakeOutgoingFrame(pOutBuffer, &FrameLen, + sizeof(Header802_3), Header802_3, + Packet.Body_Len[1] + 4, &Packet, + END_OF_ARGS); + + NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen); + if (NStatus == NDIS_STATUS_SUCCESS) + { + RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID); + STASendPacket(pAd, pNdisPacket); + RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); + } + + MlmeFreeMemory(pAd, pOutBuffer); + + DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen)); + + return NStatus; +} + +VOID DlsTimeoutAction( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3) +{ + MLME_DLS_REQ_STRUCT MlmeDlsReq; + USHORT reason; + PRT_802_11_DLS pDLS = (PRT_802_11_DLS)FunctionContext; + PRTMP_ADAPTER pAd = pDLS->pAd; + + DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n", + pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5])); + + if ((pDLS) && (pDLS->Valid)) + { + reason = REASON_QOS_REQUEST_TIMEOUT; + pDLS->Valid = FALSE; + pDLS->Status = DLS_NONE; + DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason); + MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq); + RTMP_MLME_HANDLER(pAd); + } +} + +/* +================================================================ +Description : because DLS and CLI share the same WCID table in ASIC. +Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE. +Also fills the pairwise key. +Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls +from index MAX_AID_BA. +================================================================ +*/ +MAC_TABLE_ENTRY *MacTableInsertDlsEntry( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN UINT DlsEntryIdx) +{ + PMAC_TABLE_ENTRY pEntry = NULL; + + DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n")); + // if FULL, return + if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE) + return NULL; + + do + { + if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL) + break; + + // allocate one MAC entry + pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE); + if (pEntry) + { + pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid; + pEntry->MatchDlsEntryIdx = DlsEntryIdx; + pEntry->AuthMode = pAd->StaCfg.AuthMode; + pEntry->WepStatus = pAd->StaCfg.WepStatus; + pEntry->PortSecured = WPA_802_1X_PORT_SECURED; + + DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size)); + + // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry + if ((pEntry->ValidAsDls) && (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)) + { + UCHAR KeyIdx = 0; + UCHAR CipherAlg = 0; + + KeyIdx = pAd->StaCfg.DefaultKeyId; + + CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg; + + RTMPAddWcidAttributeEntry(pAd, + BSS0, + pAd->StaCfg.DefaultKeyId, + pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, + pEntry); + } + + break; + } + } while(FALSE); + + DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n")); + + return pEntry; +} + + +/* + ========================================================================== + Description: + Delete all Mesh Entry in pAd->MacTab + ========================================================================== + */ +BOOLEAN MacTableDeleteDlsEntry( + IN PRTMP_ADAPTER pAd, + IN USHORT wcid, + IN PUCHAR pAddr) +{ + DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n")); + + if (!VALID_WCID(wcid)) + return FALSE; + + MacTableDeleteEntry(pAd, wcid, pAddr); + + DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n")); + + return TRUE; +} + +MAC_TABLE_ENTRY *DlsEntryTableLookup( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pAddr, + IN BOOLEAN bResetIdelCount) +{ + ULONG HashIdx; + MAC_TABLE_ENTRY *pEntry = NULL; + + RTMP_SEM_LOCK(&pAd->MacTabLock); + HashIdx = MAC_ADDR_HASH_INDEX(pAddr); + pEntry = pAd->MacTab.Hash[HashIdx]; + + while (pEntry) + { + if ((pEntry->ValidAsDls == TRUE) + && MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) + { + if(bResetIdelCount) + pEntry->NoDataIdleCount = 0; + break; + } + else + pEntry = pEntry->pNext; + } + + RTMP_SEM_UNLOCK(&pAd->MacTabLock); + return pEntry; +} + +MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid( + IN PRTMP_ADAPTER pAd, + IN UCHAR wcid, + IN PUCHAR pAddr, + IN BOOLEAN bResetIdelCount) +{ + ULONG DLsIndex; + PMAC_TABLE_ENTRY pCurEntry = NULL; + PMAC_TABLE_ENTRY pEntry = NULL; + + if (!VALID_WCID(wcid)) + return NULL; + + RTMP_SEM_LOCK(&pAd->MacTabLock); + + do + { + pCurEntry = &pAd->MacTab.Content[wcid]; + + DLsIndex = 0xff; + if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE)) + { + DLsIndex = pCurEntry->MatchDlsEntryIdx; + } + + if (DLsIndex == 0xff) + break; + + if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr)) + { + if(bResetIdelCount) + pCurEntry->NoDataIdleCount = 0; + pEntry = pCurEntry; + break; + } + } while(FALSE); + + RTMP_SEM_UNLOCK(&pAd->MacTabLock); + + return pEntry; +} + +INT Set_DlsEntryInfo_Display_Proc( + IN PRTMP_ADAPTER pAd, + IN PUCHAR arg) +{ + INT i; + + DBGPRINT(RT_DEBUG_OFF, ("\n%-19s%-8s\n", "MAC", "TIMEOUT\n")); + for (i=0; iStaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)) + { + PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[pAd->StaCfg.DLSEntry[i].MacTabMatchWCID]; + + DBGPRINT(RT_DEBUG_OFF, ("%02x:%02x:%02x:%02x:%02x:%02x ", + pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2], + pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5])); + DBGPRINT(RT_DEBUG_OFF, ("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut)); + + DBGPRINT(RT_DEBUG_OFF, ("\n")); + DBGPRINT(RT_DEBUG_OFF, ("\n%-19s%-4s%-4s%-4s%-4s%-7s%-7s%-7s","MAC", "AID", "BSS", "PSM", "WMM", "RSSI0", "RSSI1", "RSSI2")); + DBGPRINT(RT_DEBUG_OFF, ("%-8s%-10s%-6s%-6s%-6s%-6s", "MIMOPS", "PhMd", "BW", "MCS", "SGI", "STBC")); + DBGPRINT(RT_DEBUG_OFF, ("\n%02X:%02X:%02X:%02X:%02X:%02X ", + pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], + pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5])); + DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->Aid)); + DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->apidx)); + DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)pEntry->PsMode)); + DBGPRINT(RT_DEBUG_OFF, ("%-4d", (int)CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))); + DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi0)); + DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi1)); + DBGPRINT(RT_DEBUG_OFF, ("%-7d", pEntry->RssiSample.AvgRssi2)); + DBGPRINT(RT_DEBUG_OFF, ("%-8d", (int)pEntry->MmpsMode)); + DBGPRINT(RT_DEBUG_OFF, ("%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE))); + DBGPRINT(RT_DEBUG_OFF, ("%-6s", GetBW(pEntry->HTPhyMode.field.BW))); + DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.MCS)); + DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.ShortGI)); + DBGPRINT(RT_DEBUG_OFF, ("%-6d", pEntry->HTPhyMode.field.STBC)); + DBGPRINT(RT_DEBUG_OFF, ("%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount, + (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0)); + DBGPRINT(RT_DEBUG_OFF, ("\n")); + + } + } + + return TRUE; +} + +INT Set_DlsAddEntry_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR mac[MAC_ADDR_LEN]; + USHORT Timeout; + PSTRING token; + STRING sepValue[] = ":", DASH = '-'; + INT i; + RT_802_11_DLS Dls; + + if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format. + return FALSE; + + token = strchr(arg, DASH); + if ((token != NULL) && (strlen(token)>1)) + { + Timeout = (USHORT) simple_strtol((token+1), 0, 10); + + *token = '\0'; + for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++) + { + if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1)))) + return FALSE; + AtoH(token, (&mac[i]), 1); + } + if(i != 6) + return FALSE; + + DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1], + mac[2], mac[3], mac[4], mac[5], (int)Timeout)); + + NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS)); + Dls.TimeOut = Timeout; + COPY_MAC_ADDR(Dls.MacAddr, mac); + Dls.Valid = 1; + + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + RT_OID_802_11_SET_DLS_PARAM, + sizeof(RT_802_11_DLS), + &Dls); + + return TRUE; + } + + return FALSE; + +} + +INT Set_DlsTearDownEntry_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + UCHAR macAddr[MAC_ADDR_LEN]; + PSTRING value; + INT i; + RT_802_11_DLS Dls; + + if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17 + return FALSE; + + for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":")) + { + if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) ) + return FALSE; //Invalid + + AtoH(value, &macAddr[i++], 2); + } + + DBGPRINT(RT_DEBUG_OFF, ("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1], + macAddr[2], macAddr[3], macAddr[4], macAddr[5])); + + NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS)); + COPY_MAC_ADDR(Dls.MacAddr, macAddr); + Dls.Valid = 0; + + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + RT_OID_802_11_SET_DLS_PARAM, + sizeof(RT_802_11_DLS), + &Dls); + + return TRUE; +} Index: b/drivers/staging/rt2860/sta/rtmp_ckipmic.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/sta/rtmp_ckipmic.c @@ -0,0 +1,577 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + ************************************************************************* + + Module Name: + rtmp_ckipmic.c + + Abstract: + Data path subroutines + + Revision History: + Who When What + -------- ---------- ---------------------------------------------- +*/ +#include "../rt_config.h" +#include "../rtmp_ckipmic.h" + +#define MIC_ACCUM(v) pContext->accum += (ULONGLONG)v * RTMPMicGetCoefficient(pContext) +#define GB(p,i,s) ( ((ULONG) *((UCHAR*)(p)+i) ) << (s) ) +#define GETBIG32(p) GB(p,0,24)|GB(p,1,16)|GB(p,2,8)|GB(p,3,0) + +/*****************************/ +/******** SBOX Table *********/ +/*****************************/ + +UCHAR SboxTable[256] = +{ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +}; + +/*===========================================================================*/ +/*=================== CKIP KEY PERMUTATION ==================================*/ +/*===========================================================================*/ + +/* 2-byte by 2-byte subset of the full AES table */ +static const USHORT Sbox[256] = +{ + 0xC6A5,0xF884,0xEE99,0xF68D,0xFF0D,0xD6BD,0xDEB1,0x9154, + 0x6050,0x0203,0xCEA9,0x567D,0xE719,0xB562,0x4DE6,0xEC9A, + 0x8F45,0x1F9D,0x8940,0xFA87,0xEF15,0xB2EB,0x8EC9,0xFB0B, + 0x41EC,0xB367,0x5FFD,0x45EA,0x23BF,0x53F7,0xE496,0x9B5B, + 0x75C2,0xE11C,0x3DAE,0x4C6A,0x6C5A,0x7E41,0xF502,0x834F, + 0x685C,0x51F4,0xD134,0xF908,0xE293,0xAB73,0x6253,0x2A3F, + 0x080C,0x9552,0x4665,0x9D5E,0x3028,0x37A1,0x0A0F,0x2FB5, + 0x0E09,0x2436,0x1B9B,0xDF3D,0xCD26,0x4E69,0x7FCD,0xEA9F, + 0x121B,0x1D9E,0x5874,0x342E,0x362D,0xDCB2,0xB4EE,0x5BFB, + 0xA4F6,0x764D,0xB761,0x7DCE,0x527B,0xDD3E,0x5E71,0x1397, + 0xA6F5,0xB968,0x0000,0xC12C,0x4060,0xE31F,0x79C8,0xB6ED, + 0xD4BE,0x8D46,0x67D9,0x724B,0x94DE,0x98D4,0xB0E8,0x854A, + 0xBB6B,0xC52A,0x4FE5,0xED16,0x86C5,0x9AD7,0x6655,0x1194, + 0x8ACF,0xE910,0x0406,0xFE81,0xA0F0,0x7844,0x25BA,0x4BE3, + 0xA2F3,0x5DFE,0x80C0,0x058A,0x3FAD,0x21BC,0x7048,0xF104, + 0x63DF,0x77C1,0xAF75,0x4263,0x2030,0xE51A,0xFD0E,0xBF6D, + 0x814C,0x1814,0x2635,0xC32F,0xBEE1,0x35A2,0x88CC,0x2E39, + 0x9357,0x55F2,0xFC82,0x7A47,0xC8AC,0xBAE7,0x322B,0xE695, + 0xC0A0,0x1998,0x9ED1,0xA37F,0x4466,0x547E,0x3BAB,0x0B83, + 0x8CCA,0xC729,0x6BD3,0x283C,0xA779,0xBCE2,0x161D,0xAD76, + 0xDB3B,0x6456,0x744E,0x141E,0x92DB,0x0C0A,0x486C,0xB8E4, + 0x9F5D,0xBD6E,0x43EF,0xC4A6,0x39A8,0x31A4,0xD337,0xF28B, + 0xD532,0x8B43,0x6E59,0xDAB7,0x018C,0xB164,0x9CD2,0x49E0, + 0xD8B4,0xACFA,0xF307,0xCF25,0xCAAF,0xF48E,0x47E9,0x1018, + 0x6FD5,0xF088,0x4A6F,0x5C72,0x3824,0x57F1,0x73C7,0x9751, + 0xCB23,0xA17C,0xE89C,0x3E21,0x96DD,0x61DC,0x0D86,0x0F85, + 0xE090,0x7C42,0x71C4,0xCCAA,0x90D8,0x0605,0xF701,0x1C12, + 0xC2A3,0x6A5F,0xAEF9,0x69D0,0x1791,0x9958,0x3A27,0x27B9, + 0xD938,0xEB13,0x2BB3,0x2233,0xD2BB,0xA970,0x0789,0x33A7, + 0x2DB6,0x3C22,0x1592,0xC920,0x8749,0xAAFF,0x5078,0xA57A, + 0x038F,0x59F8,0x0980,0x1A17,0x65DA,0xD731,0x84C6,0xD0B8, + 0x82C3,0x29B0,0x5A77,0x1E11,0x7BCB,0xA8FC,0x6DD6,0x2C3A + }; + +#define Lo8(v16) ((v16) & 0xFF) +#define Hi8(v16) (((v16) >> 8) & 0xFF) +#define u16Swap(i) ( (((i) >> 8) & 0xFF) | (((i) << 8) & 0xFF00) ) +#define _S_(i) (Sbox[Lo8(i)] ^ u16Swap(Sbox[Hi8(i)])) + +#define rotLeft_1(x) ((((x) << 1) | ((x) >> 15)) & 0xFFFF) +VOID CKIP_key_permute + ( + OUT UCHAR *PK, /* output permuted key */ + IN UCHAR *CK, /* input CKIP key */ + IN UCHAR toDsFromDs, /* input toDs/FromDs bits */ + IN UCHAR *piv /* input pointer to IV */ + ) +{ + int i; + USHORT H[2], tmp; /* H=32-bits of per-packet hash value */ + USHORT L[8], R[8]; /* L=u16 array of CK, R=u16 array of PK */ + + /* build L from input key */ + memset(L, 0, sizeof(L)); + for (i=0; i<16; i++) { + L[i>>1] |= ( ((USHORT)(CK[i])) << ( i & 1 ? 8 : 0) ); + } + + H[0] = (((USHORT)piv[0]) << 8) + piv[1]; + H[1] = ( ((USHORT)toDsFromDs) << 8) | piv[2]; + + for (i=0; i<8; i++) { + H[0] ^= L[i]; /* 16-bits of key material */ + tmp = _S_(H[0]); /* 16x16 permutation */ + H[0] = tmp ^ H[1]; /* set up for next round */ + H[1] = tmp; + R[i] = H[0]; /* store into key array */ + } + + /* sweep in the other direction */ + tmp=L[0]; + for (i=7; i>0; i--) { + R[i] = tmp = rotLeft_1(tmp) + R[i]; + } + + /* IV of the permuted key is unchanged */ + PK[0] = piv[0]; + PK[1] = piv[1]; + PK[2] = piv[2]; + + /* key portion of the permuted key is changed */ + for (i=3; i<16; i++) { + PK[i] = (UCHAR) (R[i>>1] >> (i & 1 ? 8 : 0)); + } +} + +/* prepare for calculation of a new mic */ +VOID RTMPCkipMicInit( + IN PMIC_CONTEXT pContext, + IN PUCHAR CK) +{ + /* prepare for new mic calculation */ + NdisMoveMemory(pContext->CK, CK, sizeof(pContext->CK)); + pContext->accum = 0; + pContext->position = 0; +} + +/* add some bytes to the mic calculation */ +VOID RTMPMicUpdate( + IN PMIC_CONTEXT pContext, + IN PUCHAR pOctets, + IN INT len) +{ + INT byte_position; + ULONG val; + + byte_position = (pContext->position & 3); + while (len > 0) { + /* build a 32-bit word for MIC multiply accumulate */ + do { + if (len == 0) return; + pContext->part[byte_position++] = *pOctets++; + pContext->position++; + len--; + } while (byte_position < 4); + /* have a full 32-bit word to process */ + val = GETBIG32(&pContext->part[0]); + MIC_ACCUM(val); + byte_position = 0; + } +} + +ULONG RTMPMicGetCoefficient( + IN PMIC_CONTEXT pContext) +{ + UCHAR aes_counter[16]; + INT coeff_position; + UCHAR *p; + + coeff_position = (pContext->position - 1) >> 2; + if ( (coeff_position & 3) == 0) { + /* fetching the first coefficient -- get new 16-byte aes counter output */ + u32 counter = (coeff_position >> 2); + + /* new counter value */ + memset(&aes_counter[0], 0, sizeof(aes_counter)); + aes_counter[15] = (UINT8)(counter >> 0); + aes_counter[14] = (UINT8)(counter >> 8); + aes_counter[13] = (UINT8)(counter >> 16); + aes_counter[12] = (UINT8)(counter >> 24); + + RTMPAesEncrypt(&pContext->CK[0], &aes_counter[0], pContext->coefficient); + } + p = &(pContext->coefficient[ (coeff_position & 3) << 2 ]); + return GETBIG32(p); +} + +/****************************************/ +/* aes128k128d() */ +/* Performs a 128 bit AES encrypt with */ +/* 128 bit data. */ +/****************************************/ +VOID xor_128( + IN PUCHAR a, + IN PUCHAR b, + OUT PUCHAR out) +{ + INT i; + + for (i=0;i<16; i++) + { + out[i] = a[i] ^ b[i]; + } +} + +UCHAR RTMPCkipSbox( + IN UCHAR a) +{ + return SboxTable[(int)a]; +} + +VOID xor_32( + IN PUCHAR a, + IN PUCHAR b, + OUT PUCHAR out) +{ + INT i; + + for (i=0;i<4; i++) + { + out[i] = a[i] ^ b[i]; + } +} + +VOID next_key( + IN PUCHAR key, + IN INT round) +{ + UCHAR rcon; + UCHAR sbox_key[4]; + UCHAR rcon_table[12] = + { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, + 0x1b, 0x36, 0x36, 0x36 + }; + + sbox_key[0] = RTMPCkipSbox(key[13]); + sbox_key[1] = RTMPCkipSbox(key[14]); + sbox_key[2] = RTMPCkipSbox(key[15]); + sbox_key[3] = RTMPCkipSbox(key[12]); + + rcon = rcon_table[round]; + + xor_32(&key[0], sbox_key, &key[0]); + key[0] = key[0] ^ rcon; + + xor_32(&key[4], &key[0], &key[4]); + xor_32(&key[8], &key[4], &key[8]); + xor_32(&key[12], &key[8], &key[12]); +} + +VOID byte_sub( + IN PUCHAR in, + OUT PUCHAR out) +{ + INT i; + + for (i=0; i< 16; i++) + { + out[i] = RTMPCkipSbox(in[i]); + } +} + +VOID shift_row( + IN PUCHAR in, + OUT PUCHAR out) +{ + out[0] = in[0]; + out[1] = in[5]; + out[2] = in[10]; + out[3] = in[15]; + out[4] = in[4]; + out[5] = in[9]; + out[6] = in[14]; + out[7] = in[3]; + out[8] = in[8]; + out[9] = in[13]; + out[10] = in[2]; + out[11] = in[7]; + out[12] = in[12]; + out[13] = in[1]; + out[14] = in[6]; + out[15] = in[11]; +} + +VOID mix_column( + IN PUCHAR in, + OUT PUCHAR out) +{ + INT i; + UCHAR add1b[4]; + UCHAR add1bf7[4]; + UCHAR rotl[4]; + UCHAR swap_halfs[4]; + UCHAR andf7[4]; + UCHAR rotr[4]; + UCHAR temp[4]; + UCHAR tempb[4]; + + for (i=0 ; i<4; i++) + { + if ((in[i] & 0x80)== 0x80) + add1b[i] = 0x1b; + else + add1b[i] = 0x00; + } + + swap_halfs[0] = in[2]; /* Swap halfs */ + swap_halfs[1] = in[3]; + swap_halfs[2] = in[0]; + swap_halfs[3] = in[1]; + + rotl[0] = in[3]; /* Rotate left 8 bits */ + rotl[1] = in[0]; + rotl[2] = in[1]; + rotl[3] = in[2]; + + andf7[0] = in[0] & 0x7f; + andf7[1] = in[1] & 0x7f; + andf7[2] = in[2] & 0x7f; + andf7[3] = in[3] & 0x7f; + + for (i = 3; i>0; i--) /* logical shift left 1 bit */ + { + andf7[i] = andf7[i] << 1; + if ((andf7[i-1] & 0x80) == 0x80) + { + andf7[i] = (andf7[i] | 0x01); + } + } + andf7[0] = andf7[0] << 1; + andf7[0] = andf7[0] & 0xfe; + + xor_32(add1b, andf7, add1bf7); + + xor_32(in, add1bf7, rotr); + + temp[0] = rotr[0]; /* Rotate right 8 bits */ + rotr[0] = rotr[1]; + rotr[1] = rotr[2]; + rotr[2] = rotr[3]; + rotr[3] = temp[0]; + + xor_32(add1bf7, rotr, temp); + xor_32(swap_halfs, rotl,tempb); + xor_32(temp, tempb, out); +} + +VOID RTMPAesEncrypt( + IN PUCHAR key, + IN PUCHAR data, + IN PUCHAR ciphertext) +{ + INT round; + INT i; + UCHAR intermediatea[16]; + UCHAR intermediateb[16]; + UCHAR round_key[16]; + + for(i=0; i<16; i++) round_key[i] = key[i]; + + for (round = 0; round < 11; round++) + { + if (round == 0) + { + xor_128(round_key, data, ciphertext); + next_key(round_key, round); + } + else if (round == 10) + { + byte_sub(ciphertext, intermediatea); + shift_row(intermediatea, intermediateb); + xor_128(intermediateb, round_key, ciphertext); + } + else /* 1 - 9 */ + { + byte_sub(ciphertext, intermediatea); + shift_row(intermediatea, intermediateb); + mix_column(&intermediateb[0], &intermediatea[0]); + mix_column(&intermediateb[4], &intermediatea[4]); + mix_column(&intermediateb[8], &intermediatea[8]); + mix_column(&intermediateb[12], &intermediatea[12]); + xor_128(intermediatea, round_key, ciphertext); + next_key(round_key, round); + } + } + +} + +/* calculate the mic */ +VOID RTMPMicFinal( + IN PMIC_CONTEXT pContext, + OUT UCHAR digest[4]) +{ + INT byte_position; + ULONG val; + ULONGLONG sum, utmp; + LONGLONG stmp; + + /* deal with partial 32-bit word left over from last update */ + if ( (byte_position = (pContext->position & 3)) != 0) { + /* have a partial word in part to deal with -- zero unused bytes */ + do { + pContext->part[byte_position++] = 0; + pContext->position++; + } while (byte_position < 4); + val = GETBIG32(&pContext->part[0]); + MIC_ACCUM(val); + } + + /* reduce the accumulated u64 to a 32-bit MIC */ + sum = pContext->accum; + stmp = (sum & 0xffffffffL) - ((sum >> 32) * 15); + utmp = (stmp & 0xffffffffL) - ((stmp >> 32) * 15); + sum = utmp & 0xffffffffL; + if (utmp > 0x10000000fL) + sum -= 15; + + val = (ULONG)sum; + digest[0] = (UCHAR)((val>>24) & 0xFF); + digest[1] = (UCHAR) ((val>>16) & 0xFF); + digest[2] = (UCHAR) ((val>>8) & 0xFF); + digest[3] = (UCHAR)((val>>0) & 0xFF); +} + +VOID RTMPCkipInsertCMIC( + IN PRTMP_ADAPTER pAd, + OUT PUCHAR pMIC, + IN PUCHAR p80211hdr, + IN PNDIS_PACKET pPacket, + IN PCIPHER_KEY pKey, + IN PUCHAR mic_snap) +{ + PACKET_INFO PacketInfo; + PUCHAR pSrcBufVA; + ULONG SrcBufLen; + PUCHAR pDA, pSA, pProto; + UCHAR bigethlen[2]; + UCHAR ckip_ck[16]; + MIC_CONTEXT mic_ctx; + USHORT payloadlen; + UCHAR i; + + if (pKey == NULL) + { + DBGPRINT_ERR(("RTMPCkipInsertCMIC, Before to form the CKIP key (CK), pKey can't be NULL\n")); + return; + } + + switch (*(p80211hdr+1) & 3) + { + case 0: /* FromDs=0, ToDs=0 */ + pDA = p80211hdr+4; + pSA = p80211hdr+10; + break; + case 1: /* FromDs=0, ToDs=1 */ + pDA = p80211hdr+16; + pSA = p80211hdr+10; + break; + case 2: /* FromDs=1, ToDs=0 */ + pDA = p80211hdr+4; + pSA = p80211hdr+16; + break; + case 3: /* FromDs=1, ToDs=1 */ + pDA = p80211hdr+16; + pSA = p80211hdr+24; + break; + } + + RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); + + if (SrcBufLen < LENGTH_802_3) + return; + + pProto = pSrcBufVA + 12; + payloadlen = PacketInfo.TotalPacketLength - LENGTH_802_3 + 18; // CKIP_LLC(8)+CMIC(4)+TxSEQ(4)+PROTO(2)=18 + + bigethlen[0] = (unsigned char)(payloadlen >> 8); + bigethlen[1] = (unsigned char)payloadlen; + + // + // Encryption Key expansion to form the CKIP Key (CKIP_CK). + // + if (pKey->KeyLen < 16) + { + for(i = 0; i < (16 / pKey->KeyLen); i++) + { + NdisMoveMemory(ckip_ck + i * pKey->KeyLen, + pKey->Key, + pKey->KeyLen); + } + NdisMoveMemory(ckip_ck + i * pKey->KeyLen, + pKey->Key, + 16 - (i * pKey->KeyLen)); + } + else + { + NdisMoveMemory(ckip_ck, pKey->Key, pKey->KeyLen); + } + RTMPCkipMicInit(&mic_ctx, ckip_ck); + RTMPMicUpdate(&mic_ctx, pDA, MAC_ADDR_LEN); // MIC <-- DA + RTMPMicUpdate(&mic_ctx, pSA, MAC_ADDR_LEN); // MIC <-- SA + RTMPMicUpdate(&mic_ctx, bigethlen, 2); // MIC <-- payload length starting from CKIP SNAP + RTMPMicUpdate(&mic_ctx, mic_snap, 8); // MIC <-- snap header + RTMPMicUpdate(&mic_ctx, pAd->StaCfg.TxSEQ, 4); // MIC <-- TxSEQ + RTMPMicUpdate(&mic_ctx, pProto, 2); // MIC <-- Protocol + + pSrcBufVA += LENGTH_802_3; + SrcBufLen -= LENGTH_802_3; + + // Mic <-- original payload. loop until all payload processed + do + { + if (SrcBufLen > 0) + RTMPMicUpdate(&mic_ctx, pSrcBufVA, SrcBufLen); + + NdisGetNextBuffer(PacketInfo.pFirstBuffer, &PacketInfo.pFirstBuffer); + if (PacketInfo.pFirstBuffer) + { + NDIS_QUERY_BUFFER(PacketInfo.pFirstBuffer, &pSrcBufVA, &SrcBufLen); + } + else + break; + } while (TRUE); + + RTMPMicFinal(&mic_ctx, pMIC); // update MIC +} Index: b/drivers/staging/rt2860/sta/rtmp_data.c =================================================================== --- a/drivers/staging/rt2860/sta/rtmp_data.c +++ b/drivers/staging/rt2860/sta/rtmp_data.c @@ -33,8 +33,6 @@ Revision History: Who When What -------- ---------- ---------------------------------------------- - John Aug/17/04 major modification for RT2561/2661 - Jan Lee Mar/17/06 major modification for RT2860 New Ring Design */ #include "../rt_config.h" @@ -64,6 +62,7 @@ VOID STARxEAPOLFrameIndicate( int idx = 0; DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n")); + //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; STA_PORT_SECURED(pAd); if (pAd->StaCfg.IEEE8021x_required_keys == FALSE) @@ -74,7 +73,7 @@ VOID STARxEAPOLFrameIndicate( if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0) { -#ifdef RT2860 +#ifdef RTMP_MAC_PCI MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID]; // Set key material and cipherAlg to Asic @@ -88,8 +87,8 @@ VOID STARxEAPOLFrameIndicate( pAd->IndicateMediaState = NdisMediaStateConnected; pAd->ExtraInfo = GENERAL_LINK_UP; -#endif -#ifdef RT2870 +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB union { char buf[sizeof(NDIS_802_11_WEP)+MAX_LEN_OF_KEY- 1]; @@ -113,7 +112,7 @@ VOID STARxEAPOLFrameIndicate( pAd->ExtraInfo = GENERAL_LINK_UP; // need to enqueue cmd to thread RTUSBEnqueueCmdFromNdis(pAd, OID_802_11_ADD_WEP, TRUE, &WepKey, sizeof(WepKey.keyinfo) + len - 1); -#endif // RT2870 // +#endif // RTMP_MAC_USB // // For Preventing ShardKey Table is cleared by remove key procedure. pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg; pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen; @@ -156,6 +155,7 @@ VOID STARxDataFrameAnnounce( // non-EAP frame if (!RTMPCheckWPAframe(pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID)) { + { // drop all non-EAP DATA frame before // this client's Port-Access-Control is secured @@ -309,13 +309,13 @@ VOID STAHandleRxDataFrame( if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && (pHeader->FC.SubType & 0x08)) { UCHAR *pData; - DBGPRINT(RT_DEBUG_TRACE,("bAPSDCapable\n")); + DBGPRINT(RT_DEBUG_INFO,("bAPSDCapable\n")); // Qos bit 4 pData = (PUCHAR)pHeader + LENGTH_802_11; if ((*pData >> 4) & 0x01) { - DBGPRINT(RT_DEBUG_TRACE,("RxDone- Rcv EOSP frame, driver may fall into sleep\n")); + DBGPRINT(RT_DEBUG_INFO,("RxDone- Rcv EOSP frame, driver may fall into sleep\n")); pAd->CommonCfg.bInServicePeriod = FALSE; // Force driver to fall into sleep mode when rcv EOSP frame @@ -332,7 +332,7 @@ VOID STAHandleRxDataFrame( if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim)) TbttNumToNextWakeUp = NextDtim; - MlmeSetPsmBit(pAd, PWR_SAVE); + RTMP_SET_PSM_BIT(pAd, PWR_SAVE); // if WMM-APSD is failed, try to disable following line AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp); } @@ -442,6 +442,23 @@ VOID STAHandleRxDataFrame( } pRxBlk->UserPriority = UserPriority; + /* check if need to resend PS Poll when received packet with MoreData = 1 */ + if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1)) + { + if ((((UserPriority == 0) || (UserPriority == 3)) && + pAd->CommonCfg.bAPSDAC_BE == 0) || + (((UserPriority == 1) || (UserPriority == 2)) && + pAd->CommonCfg.bAPSDAC_BK == 0) || + (((UserPriority == 4) || (UserPriority == 5)) && + pAd->CommonCfg.bAPSDAC_VI == 0) || + (((UserPriority == 6) || (UserPriority == 7)) && + pAd->CommonCfg.bAPSDAC_VO == 0)) + { + /* non-UAPSD delivery-enabled AC */ + RTMP_PS_POLL_ENQUEUE(pAd); + } + } + // 3. Order bit: A-Ralink or HTC+ if (pHeader->FC.Order) { @@ -451,7 +468,7 @@ VOID STAHandleRxDataFrame( RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK); } else -#endif +#endif // AGGREGATION_SUPPORT // { RX_BLK_SET_FLAG(pRxBlk, fRX_HTC); // skip HTC contorl field @@ -574,27 +591,31 @@ VOID STAHandleRxMgmtFrame( do { + + /* check if need to resend PS Poll when received packet with MoreData = 1 */ + if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1)) + { + /* for UAPSD, all management frames will be VO priority */ + if (pAd->CommonCfg.bAPSDAC_VO == 0) + { + /* non-UAPSD delivery-enabled AC */ + RTMP_PS_POLL_ENQUEUE(pAd); + } + } + + /* TODO: if MoreData == 0, station can go to sleep */ + + // We should collect RSSI not only U2M data but also my beacon - if (pAd->RxAnt.EvaluatePeriod == 0 && - pHeader->FC.SubType == SUBTYPE_BEACON && - MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2)) { + if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2)) + && (pAd->RxAnt.EvaluatePeriod == 0)) + { Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI); pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0); pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1); } -#ifdef RT2870 - // collect rssi information for antenna diversity - if (pAd->NicConfig2.field.AntDiversity) - { - if ((pRxD->U2M) || ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2)))) - { - COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAd, ConvertToRssi(pAd, (UCHAR)pRxWI->RSSI0, RSSI_0), 0); //Note: RSSI2 not used on RT73 - pAd->StaCfg.NumOfAvgRssiSample ++; - } - } -#endif // First check the size, it MUST not exceed the mlme queue size if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE) @@ -683,14 +704,14 @@ BOOLEAN STARxDoneInterruptHandle( break; } -#ifdef RT2860 +#ifdef RTMP_MAC_PCI if (RxProcessed++ > MAX_RX_PROCESS_CNT) { // need to reschedule rx handle bReschedule = TRUE; break; } -#endif +#endif // RTMP_MAC_PCI // RxProcessed ++; // test @@ -725,6 +746,7 @@ BOOLEAN STARxDoneInterruptHandle( // Increase Total receive byte counter after real data received no mater any error or not pAd->RalinkCounters.ReceivedByteCount += pRxWI->MPDUtotalByteCount; + pAd->RalinkCounters.OneSecReceivedByteCount += pRxWI->MPDUtotalByteCount; pAd->RalinkCounters.RxCount ++; INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount); @@ -737,7 +759,8 @@ BOOLEAN STARxDoneInterruptHandle( send_monitor_packets(pAd, &RxCell); break; } - /* RT2870 invokes STARxDoneInterruptHandle() in rtusb_bulk.c */ + + /* STARxDoneInterruptHandle() is called in rtusb_bulk.c */ // Check for all RxD errors Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD); @@ -780,15 +803,6 @@ BOOLEAN STARxDoneInterruptHandle( } } -#ifdef RT2860 - // fRTMP_PS_GO_TO_SLEEP_NOW is set if receiving beacon. - if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW) && (INFRA_ON(pAd))) - { - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); - AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp); - bReschedule = FALSE; - } -#endif return bReschedule; } @@ -806,12 +820,7 @@ BOOLEAN STARxDoneInterruptHandle( VOID RTMPHandleTwakeupInterrupt( IN PRTMP_ADAPTER pAd) { -#ifdef RT2860 - AsicForceWakeup(pAd, DOT11POWERSAVE); -#endif -#ifdef RT2870 AsicForceWakeup(pAd, FALSE); -#endif } /* @@ -914,6 +923,7 @@ NDIS_STATUS STASendPacket( UINT SrcBufLen; UINT AllowFragSize; UCHAR NumberOfFrag; + UCHAR RTSRequired; UCHAR QueIdx, UserPriority; MAC_TABLE_ENTRY *pEntry = NULL; unsigned int IrqFlags; @@ -1052,7 +1062,14 @@ NDIS_STATUS STASendPacket( // If multiple fragment required, RTS is required only for the first fragment // if the fragment size large than RTS threshold // For RT28xx, Let ASIC send RTS/CTS - RTMP_SET_PACKET_RTS(pPacket, 0); +// RTMP_SET_PACKET_RTS(pPacket, 0); + if (NumberOfFrag > 1) + RTSRequired = (pAd->CommonCfg.FragmentThreshold > pAd->CommonCfg.RtsThreshold) ? 1 : 0; + else + RTSRequired = (PacketInfo.TotalPacketLength > pAd->CommonCfg.RtsThreshold) ? 1 : 0; + + // Save RTS requirement to Ndis packet reserved field + RTMP_SET_PACKET_RTS(pPacket, RTSRequired); RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate); // @@ -1060,13 +1077,8 @@ NDIS_STATUS STASendPacket( // UserPriority = 0; QueIdx = QID_AC_BE; -#ifdef RT2860 - if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) -#endif -#ifdef RT2870 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)) -#endif { USHORT Protocol; UCHAR LlcSnapLen = 0, Byte0, Byte1; @@ -1102,6 +1114,11 @@ NDIS_STATUS STASendPacket( // TODO: have to check ACM bit. apply TSPEC if ACM is ON // TODO: downgrade UP & QueIdx before passing ACM + /* + Under WMM ACM control, we dont need to check the bit; + Or when a TSPEC is built for VO but we will change to issue + BA session for BE here, so we will not use BA to send VO packets. + */ if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx]) { UserPriority = 0; @@ -1125,18 +1142,14 @@ NDIS_STATUS STASendPacket( } else { - InsertTailQueue(&pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket)); + InsertTailQueueAc(pAd, pEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket)); } RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE)&& -#ifdef RT2860 - (pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)) -#endif -#ifdef RT2870 IS_HT_STA(pEntry)) -#endif { + //PMAC_TABLE_ENTRY pMacEntry = &pAd->MacTab.Content[BSSID_WCID]; if (((pEntry->TXBAbitmap & (1<BADeclineBitmap & (1<PortSecured == WPA_802_1X_PORT_SECURED) @@ -1145,10 +1158,10 @@ NDIS_STATUS STASendPacket( // 2. It is OPEN or AES mode, // then BA session can be bulit. && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0) || - (pEntry->WepStatus == Ndis802_11WEPDisabled || pEntry->WepStatus == Ndis802_11Encryption3Enabled)) + (pEntry->WepStatus != Ndis802_11WEPEnabled && pEntry->WepStatus != Ndis802_11Encryption2Enabled)) ) { - BAOriSessionSetUp(pAd, pEntry, 0, 0, 10, FALSE); + BAOriSessionSetUp(pAd, pEntry, UserPriority, 0, 10, FALSE); } } @@ -1179,27 +1192,15 @@ NDIS_STATUS STASendPacket( ======================================================================== */ - -#ifdef RT2870 -/* - Actually, this function used to check if the TxHardware Queue still has frame need to send. - If no frame need to send, go to sleep, else, still wake up. -*/ -#endif +#ifdef RTMP_MAC_PCI NDIS_STATUS RTMPFreeTXDRequest( IN PRTMP_ADAPTER pAd, IN UCHAR QueIdx, IN UCHAR NumberRequired, IN PUCHAR FreeNumberIs) { -#ifdef RT2860 ULONG FreeNumber = 0; -#endif NDIS_STATUS Status = NDIS_STATUS_FAILURE; -#ifdef RT2870 - unsigned long IrqFlags; - HT_TX_CONTEXT *pHTTXContext; -#endif switch (QueIdx) { @@ -1208,7 +1209,6 @@ NDIS_STATUS RTMPFreeTXDRequest( case QID_AC_VI: case QID_AC_VO: case QID_HCCA: -#ifdef RT2860 if (pAd->TxRing[QueIdx].TxSwFreeIdx > pAd->TxRing[QueIdx].TxCpuIdx) FreeNumber = pAd->TxRing[QueIdx].TxSwFreeIdx - pAd->TxRing[QueIdx].TxCpuIdx - 1; else @@ -1216,8 +1216,49 @@ NDIS_STATUS RTMPFreeTXDRequest( if (FreeNumber >= NumberRequired) Status = NDIS_STATUS_SUCCESS; -#endif -#ifdef RT2870 + break; + + case QID_MGMT: + if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx) + FreeNumber = pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx - 1; + else + FreeNumber = pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - pAd->MgmtRing.TxCpuIdx - 1; + + if (FreeNumber >= NumberRequired) + Status = NDIS_STATUS_SUCCESS; + break; + + default: + DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx)); + break; + } + *FreeNumberIs = (UCHAR)FreeNumber; + + return (Status); +} +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB +/* + Actually, this function used to check if the TxHardware Queue still has frame need to send. + If no frame need to send, go to sleep, else, still wake up. +*/ +NDIS_STATUS RTMPFreeTXDRequest( + IN PRTMP_ADAPTER pAd, + IN UCHAR QueIdx, + IN UCHAR NumberRequired, + IN PUCHAR FreeNumberIs) +{ + //ULONG FreeNumber = 0; + NDIS_STATUS Status = NDIS_STATUS_FAILURE; + unsigned long IrqFlags; + HT_TX_CONTEXT *pHTTXContext; + + switch (QueIdx) + { + case QID_AC_BK: + case QID_AC_BE: + case QID_AC_VI: + case QID_AC_VO: { pHTTXContext = &pAd->TxContext[QueIdx]; RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); @@ -1232,39 +1273,21 @@ NDIS_STATUS RTMPFreeTXDRequest( } RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); } -#endif break; - case QID_MGMT: -#ifdef RT2860 - if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx) - FreeNumber = pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx - 1; - else - FreeNumber = pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - pAd->MgmtRing.TxCpuIdx - 1; - - if (FreeNumber >= NumberRequired) - Status = NDIS_STATUS_SUCCESS; -#endif -#ifdef RT2870 if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE) Status = NDIS_STATUS_FAILURE; else Status = NDIS_STATUS_SUCCESS; -#endif break; - default: DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx)); break; } -#ifdef RT2860 - *FreeNumberIs = (UCHAR)FreeNumber; -#endif return (Status); } - - +#endif // RTMP_MAC_USB // VOID RTMPSendDisassociationFrame( IN PRTMP_ADAPTER pAd) @@ -1527,6 +1550,9 @@ VOID STABuildCache802_11Header( pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ; { + // Check if the frame can be sent through DLS direct link interface + // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability) + // The addr3 of normal packet send from DS is Dest Mac address. if (ADHOC_ON(pAd)) COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid); @@ -1580,13 +1606,13 @@ static inline PUCHAR STA_Build_ARalink_F // padding at front of LLC header. LLC header should at 4-bytes aligment. pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr; - pHeaderBufPtr = (PCHAR)ROUND_UP(pHeaderBufPtr, 4); + pHeaderBufPtr = (PUCHAR)ROUND_UP(pHeaderBufPtr, 4); pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen); // For RA Aggregation, // put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format pQEntry = pTxBlk->TxPacketList.Head; - pNextPacket = QUEUE_ENTRY_TO_PKT(pQEntry); + pNextPacket = QUEUE_ENTRY_TO_PACKET(pQEntry); nextBufLen = GET_OS_PKT_LEN(pNextPacket); if (RTMP_GET_PACKET_VLAN(pNextPacket)) nextBufLen -= LENGTH_802_1Q; @@ -1641,7 +1667,7 @@ static inline PUCHAR STA_Build_AMSDU_Fra // @@@ MpduHeaderLen excluding padding @@@ // pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr; - pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4); + pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4); pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen); return pHeaderBufPtr; @@ -1743,7 +1769,7 @@ VOID STA_AMPDU_Frame_Tx( // @@@ MpduHeaderLen excluding padding @@@ // pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr; - pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4); + pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4); pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen); { @@ -1790,9 +1816,7 @@ VOID STA_AMPDU_Frame_Tx( // // Kick out Tx // -#ifdef RT2860 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) -#endif HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); pAd->RalinkCounters.KickTxCount++; @@ -1923,9 +1947,7 @@ VOID STA_AMSDU_Frame_Tx( // // Kick out Tx // -#ifdef RT2860 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) -#endif HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); } @@ -1991,7 +2013,7 @@ VOID STA_Legacy_Frame_Tx( // // build QOS Control bytes // - *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F); + *(pHeaderBufPtr) = ((pTxBlk->UserPriority & 0x0F) | (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx]<<5)); *(pHeaderBufPtr+1) = 0; pHeaderBufPtr +=2; pTxBlk->MpduHeaderLen += 2; @@ -1999,7 +2021,7 @@ VOID STA_Legacy_Frame_Tx( // The remaining content of MPDU header should locate at 4-octets aligment pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr; - pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4); + pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4); pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen); { @@ -2045,9 +2067,7 @@ VOID STA_Legacy_Frame_Tx( // // Kick out Tx // -#ifdef RT2860 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) -#endif HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); } @@ -2158,9 +2178,7 @@ VOID STA_ARalink_Frame_Tx( // // Kick out Tx // -#ifdef RT2860 if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) -#endif HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); } @@ -2181,6 +2199,7 @@ VOID STA_Fragment_Frame_Tx( UINT NextMpduSize; BOOLEAN bVLANPkt; PQUEUE_ENTRY pQEntry; + HTTRANSMIT_SETTING *pTransmit; ASSERT(pTxBlk); @@ -2243,7 +2262,7 @@ VOID STA_Fragment_Frame_Tx( // LLC header should locate at 4-octets aligment // pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr; - pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4); + pHeaderBufPtr = (PUCHAR) ROUND_UP(pHeaderBufPtr, 4); pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen); @@ -2276,6 +2295,7 @@ VOID STA_Fragment_Frame_Tx( // MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC if (pTxBlk->CipherAlg == CIPHER_TKIP) { + RTMPCalculateMICValue(pAd, pTxBlk->pPacket, pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey, 0); // NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust // to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress. @@ -2301,8 +2321,20 @@ VOID STA_Fragment_Frame_Tx( else EncryptionOverhead = 0; + pTransmit = pTxBlk->pTransmit; + // Decide the TX rate + if (pTransmit->field.MODE == MODE_CCK) + pTxBlk->TxRate = pTransmit->field.MCS; + else if (pTransmit->field.MODE == MODE_OFDM) + pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE; + else + pTxBlk->TxRate = RATE_6_5; + // decide how much time an ACK/CTS frame will consume in the air + if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE) AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14); + else + AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 14); // Init the total payload length of this frame. SrcRemainingBytes = pTxBlk->SrcBufLen; @@ -2365,6 +2397,7 @@ VOID STA_Fragment_Frame_Tx( // // Kick out Tx // + if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX)) HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx); } @@ -2428,13 +2461,13 @@ NDIS_STATUS STAHardTransmit( // not to change PSM bit, just send this frame out? if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { - DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicForceWakeup At HardTx\n")); -#ifdef RT2860 - AsicForceWakeup(pAd, FROM_TX); -#endif -#ifdef RT2870 + DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicForceWakeup At HardTx\n")); +#ifdef RTMP_MAC_PCI AsicForceWakeup(pAd, TRUE); -#endif +#endif // RTMP_MAC_PCI // +#ifdef RTMP_MAC_USB + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_FORCE_WAKE_UP, NULL, 0); +#endif // RTMP_MAC_USB // } // It should not change PSM bit, when APSD turn on. @@ -2444,7 +2477,7 @@ NDIS_STATUS STAHardTransmit( { if ((pAd->StaCfg.Psm == PWR_SAVE) && (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP)) - MlmeSetPsmBit(pAd, PWR_ACTIVE); + RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE); } switch (pTxBlk->TxFrameType) Index: b/drivers/staging/rt2860/sta/sanity.c =================================================================== --- a/drivers/staging/rt2860/sta/sanity.c +++ b/drivers/staging/rt2860/sta/sanity.c @@ -117,7 +117,7 @@ BOOLEAN PeerAssocRspSanity( *pHtCapabilityLen = 0; *pAddHtInfoLen = 0; COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2); - Ptr = pFrame->Octet; + Ptr = (PCHAR)pFrame->Octet; Length += LENGTH_802_11; NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2); @@ -213,28 +213,7 @@ BOOLEAN PeerAssocRspSanity( DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n")); } break; - case IE_AIRONET_CKIP: - // 0. Check Aironet IE length, it must be larger or equal to 28 - // Cisco's AP VxWork version(will not be supported) used this IE length as 28 - // Cisco's AP IOS version used this IE length as 30 - if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2)) - break; - - // 1. Copy CKIP flag byte to buffer for process - *pCkipFlag = *(pEid->Octet + 8); - break; - case IE_AIRONET_IPADDRESS: - if (pEid->Len != 0x0A) - break; - - // Get Cisco Aironet IP information - if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1) - NdisMoveMemory(pAd->StaCfg.AironetIPAddress, pEid->Octet + 4, 4); - break; - - // CCX2, WMM use the same IE value - // case IE_CCX_V2: case IE_VENDOR_SPECIFIC: // handle WME PARAMTER ELEMENT if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24)) @@ -250,7 +229,7 @@ BOOLEAN PeerAssocRspSanity( //pEdcaParm->bMoreDataAck = FALSE; // pEid->Octet[0] & 0x80; pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f; pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0; - ptr = &pEid->Octet[8]; + ptr = (PUCHAR)&pEid->Octet[8]; for (i=0; i<4; i++) { UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX @@ -262,23 +241,7 @@ BOOLEAN PeerAssocRspSanity( ptr += 4; // point to next AC } } - - // handle CCX IE - else - { - // 0. Check the size and CCX admin control - if (pAd->StaCfg.CCXControl.field.Enable == 0) - break; - if (pEid->Len != 5) - break; - - // Turn CCX2 if matched - if (NdisEqualMemory(pEid->Octet, Ccx2IeInfo, 5) == 1) - pAd->StaCfg.CCXEnable = TRUE; - break; - } break; - default: DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid->Eid)); break; @@ -288,9 +251,6 @@ BOOLEAN PeerAssocRspSanity( pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len); } - // Force CCX2 enable to TRUE for those AP didn't replay CCX v2 IE, we still force it to be on - if (pAd->StaCfg.CCXControl.field.Enable == 1) - pAd->StaCfg.CCXEnable = TRUE; return TRUE; } Index: b/drivers/staging/rt2860/sta/sync.c =================================================================== --- a/drivers/staging/rt2860/sta/sync.c +++ b/drivers/staging/rt2860/sta/sync.c @@ -37,45 +37,8 @@ */ #include "../rt_config.h" -#ifdef RT2860 -#define AC0_DEF_TXOP 0 -#define AC1_DEF_TXOP 0 -#define AC2_DEF_TXOP 94 -#define AC3_DEF_TXOP 47 -VOID AdhocTurnOnQos( - IN PRTMP_ADAPTER pAd) -{ - // Turn on QOs if use HT rate. - if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) - { - pAd->CommonCfg.APEdcaParm.bValid = TRUE; - pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3; - pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7; - pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1; - pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1; - - pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4; - pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4; - pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3; - pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2; - - pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10; - pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6; - pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4; - pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3; - - pAd->CommonCfg.APEdcaParm.Txop[0] = 0; - pAd->CommonCfg.APEdcaParm.Txop[1] = 0; - pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP; - pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP; - } - AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); -} -#endif /* RT2860 */ -#ifdef RT2870 #define ADHOC_ENTRY_BEACON_LOST_TIME (2*OS_HZ) // 2 sec -#endif /* ========================================================================== @@ -160,7 +123,7 @@ VOID BeaconTimeout( } MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL); - RT28XX_MLME_HANDLER(pAd); + RTMP_MLME_HANDLER(pAd); } /* @@ -188,8 +151,8 @@ VOID ScanTimeout( if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL)) { - RT28XX_MLME_HANDLER(pAd); - } + RTMP_MLME_HANDLER(pAd); +} else { // To prevent SyncMachine.CurrState is SCAN_LISTEN forever. @@ -231,7 +194,7 @@ VOID MlmeScanReqAction( // Increase the scan retry counters. pAd->StaCfg.ScanCnt++; -#ifdef RT2860 +#ifdef RTMP_MAC_PCI if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) && (IDLE_ON(pAd)) && (pAd->StaCfg.bRadio == TRUE) && @@ -239,30 +202,22 @@ VOID MlmeScanReqAction( { RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); } -#endif +#endif // RTMP_MAC_PCI // // first check the parameter sanity if (MlmeScanReqSanity(pAd, Elem->Msg, Elem->MsgLen, &BssType, - Ssid, + (PCHAR)Ssid, &SsidLen, &ScanType)) { // Check for channel load and noise hist request // Suspend MSDU only at scan request, not the last two mentioned - if ((ScanType == SCAN_CISCO_NOISE) || (ScanType == SCAN_CISCO_CHANNEL_LOAD)) - { - if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel) - RTMPSuspendMsduTransmission(pAd); // Suspend MSDU transmission here - } - else - { // Suspend MSDU transmission here RTMPSuspendMsduTransmission(pAd); - } // // To prevent data lost. @@ -304,11 +259,6 @@ VOID MlmeScanReqAction( // start from the first channel pAd->MlmeAux.Channel = FirstChannel(pAd); - // Change the scan channel when dealing with CCX beacon report - if ((ScanType == SCAN_CISCO_PASSIVE) || (ScanType == SCAN_CISCO_ACTIVE) || - (ScanType == SCAN_CISCO_CHANNEL_LOAD) || (ScanType == SCAN_CISCO_NOISE)) - pAd->MlmeAux.Channel = pAd->StaCfg.CCXScanChannel; - // Let BBP register at 20MHz to do scan RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); BBPValue &= (~0x18); @@ -352,7 +302,7 @@ VOID MlmeJoinReqAction( DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx)); -#ifdef RT2860 +#ifdef RTMP_MAC_PCI if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) && (IDLE_ON(pAd)) && (pAd->StaCfg.bRadio == TRUE) && @@ -360,7 +310,7 @@ VOID MlmeJoinReqAction( { RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE); } -#endif +#endif // RTMP_MAC_PCI // // reset all the timers RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); @@ -374,6 +324,7 @@ VOID MlmeJoinReqAction( // If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again. if (pBss->Hidden == 0) { + RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID); NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen); pAd->MlmeAux.SsidLen = pBss->SsidLen; } @@ -382,10 +333,14 @@ VOID MlmeJoinReqAction( pAd->MlmeAux.Channel = pBss->Channel; pAd->MlmeAux.CentralChannel = pBss->CentralChannel; + // Let BBP register at 20MHz to do scan RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue); BBPValue &= (~0x18); RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue); +#ifdef RT2860 + pAd->CommonCfg.BBPCurrentBW = BW_20; +#endif // RT2860 // DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n")); // switch channel and waiting for beacon timer @@ -494,7 +449,7 @@ VOID MlmeStartReqAction( TimeStamp.u.LowPart = 0; TimeStamp.u.HighPart = 0; - if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, Ssid, &SsidLen)) + if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, (PCHAR)Ssid, &SsidLen)) { // reset all the timers RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled); @@ -541,6 +496,7 @@ VOID MlmeStartReqAction( { pAd->MlmeAux.HtCapabilityLen = 0; pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; + NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16); } // temporarily not support QOS in IBSS NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM)); @@ -601,6 +557,8 @@ VOID PeerBeaconAtScanAction( UCHAR AddHtInfoLen; UCHAR NewExtChannelOffset = 0xff; + + // NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00); pFrame = (PFRAME_802_11) Elem->Msg; // Init Variable IE structure pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; @@ -615,7 +573,7 @@ VOID PeerBeaconAtScanAction( Elem->Channel, Addr2, Bssid, - Ssid, + (PCHAR)Ssid, &SsidLen, &BssType, &BeaconPeriod, @@ -661,24 +619,7 @@ VOID PeerBeaconAtScanAction( if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) HtCapabilityLen = SIZE_HT_CAP_IE; - if ((pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) && (Channel == pAd->StaCfg.CCXScanChannel)) - { - Idx = BssTableSetEntry(pAd, &pAd->StaCfg.CCXBssTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod, - &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen,ExtRate, ExtRateLen, &HtCapability, - &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag, - &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); - if (Idx != BSS_NOT_FOUND) - { - NdisMoveMemory(pAd->StaCfg.CCXBssTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4); - NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); - NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); - if (pAd->StaCfg.CCXReqType == MSRN_TYPE_BEACON_REQ) - AironetAddBeaconReport(pAd, Idx, Elem); - } - } - else - { - Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod, + Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (PCHAR)Ssid, SsidLen, BssType, BeaconPeriod, &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); @@ -689,7 +630,7 @@ VOID PeerBeaconAtScanAction( NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); } - } + } // sanity check fail, ignored } @@ -731,6 +672,7 @@ VOID PeerBeaconAtJoinAction( UCHAR AddHtInfoLen; UCHAR NewExtChannelOffset = 0xff; UCHAR CentralChannel; + BOOLEAN bAllowNrate = FALSE; // Init Variable IE structure pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE; @@ -745,7 +687,7 @@ VOID PeerBeaconAtJoinAction( Elem->Channel, Addr2, Bssid, - Ssid, + (PCHAR)Ssid, &SsidLen, &BssType, &BeaconPeriod, @@ -818,8 +760,24 @@ VOID PeerBeaconAtJoinAction( { Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel); + if (Idx == BSS_NOT_FOUND) + { + CHAR Rssi = 0; + Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2)); + Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (CHAR *) Ssid, SsidLen, BssType, BeaconPeriod, + &Cf, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, + &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag, + &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); if (Idx != BSS_NOT_FOUND) { + NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4); + NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4); + NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4); + CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo; + } + } + else + { // // Multiple SSID case, used correct CapabilityInfo // @@ -847,13 +805,21 @@ VOID PeerBeaconAtJoinAction( NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16); + + if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled) && (pAd->StaCfg.WepStatus != Ndis802_11Encryption2Enabled)) + || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) + { + bAllowNrate = TRUE; + } + pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset; pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen; + RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); // filter out un-supported ht rates - if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) + if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && + ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (bAllowNrate))) { - RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE); // StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability @@ -897,7 +863,9 @@ VOID PeerBeaconAtJoinAction( pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel; pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; + pAd->MlmeAux.NewExtChannelOffset = 0xff; RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); + pAd->MlmeAux.HtCapabilityLen = 0; RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); } @@ -930,6 +898,8 @@ VOID PeerBeaconAtJoinAction( else //Used the default TX Power Percentage. pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; + InitChannelRelatedValue(pAd); + pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_SUCCESS; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status); @@ -1116,8 +1086,6 @@ VOID PeerBeacon( // Add the safeguard against the mismatch of adhoc wep status if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus) { - DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Not matched wep status %d %d\n", pAd->StaCfg.WepStatus, pAd->ScanTab.BssEntry[Bssidx].WepStatus)); - DBGPRINT(RT_DEBUG_TRACE, ("bssid=%s\n", pAd->ScanTab.BssEntry[Bssidx].Bssid)); return; } @@ -1181,200 +1149,8 @@ VOID PeerBeacon( pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault; } -#ifdef RT2860 - // at least one 11b peer joined. downgrade the MaxTxRate to 11Mbps - // after last 11b peer left for several seconds, we'll auto switch back to 11G rate - // in MlmePeriodicExec() -#endif if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo))) { -#ifdef RT2860 - BOOLEAN bRestart; - BOOLEAN bnRestart; - - bRestart = FALSE; - bnRestart = FALSE; - - do - { - if ((SupRateLen+ExtRateLen <= 4) && (pAd->CommonCfg.MaxTxRate > RATE_11)) - { - if (pAd->StaCfg.AdhocBOnlyJoined == FALSE) - { - DBGPRINT(RT_DEBUG_TRACE, ("SYNC - 11b peer joined. down-grade to 11b TX rates \n")); - bRestart = TRUE; - NdisMoveMemory(pAd->StaActive.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES); - pAd->StaActive.SupRateLen = SupRateLen; - NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES); - pAd->StaActive.ExtRateLen = ExtRateLen; - pAd->StaCfg.AdhocBOnlyJoined = TRUE; - pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; - AsicSetEdcaParm(pAd, NULL); - } - - // this timestamp is for MlmePeriodicExec() to check if all 11B peers have left - pAd->StaCfg.Last11bBeaconRxTime = Now; - break; - } - - // Update Ht Phy. - if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) - { - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && - !pAd->StaCfg.AdhocBGJoined && - !pAd->StaCfg.AdhocBOnlyJoined) - AdhocTurnOnQos(pAd); - - // Handle rate switch issue when Adhoc mode - if ((SupRateLen+ExtRateLen >= 8) && (HtCapability.MCSSet[0] == 0) && (HtCapability.MCSSet[1] == 0)) - { - if (pAd->StaCfg.AdhocBGJoined == FALSE) - { - DBGPRINT(RT_DEBUG_TRACE, ("SYNC - 11g peer joined. down-grade to 11g TX rates \n")); - bRestart = TRUE; - NdisMoveMemory(pAd->StaActive.SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES); - pAd->StaActive.SupRateLen = SupRateLen; - NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, MAX_LEN_OF_SUPPORTED_RATES); - pAd->StaActive.ExtRateLen = ExtRateLen; - pAd->StaCfg.AdhocBGJoined = TRUE; - pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE; - AsicSetEdcaParm(pAd, NULL); - } - - // this timestamp is for MlmePeriodicExec() to check if all 11g peers have left - pAd->StaCfg.Last11gBeaconRxTime = Now; - break; - } - else if (!pAd->StaCfg.AdhocBGJoined && - !pAd->StaCfg.AdhocBOnlyJoined && - (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) && - (HtCapability.HtCapInfo.ChannelWidth == BW_20)) - { - if (pAd->StaCfg.Adhoc20NJoined == FALSE) - { - pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel; - - pAd->StaCfg.Adhoc20NJoined = TRUE; - NdisMoveMemory(&pAd->MlmeAux.HtCapability, &HtCapability, SIZE_HT_CAP_IE); - if (AddHtInfoLen != 0) - NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, AddHtInfoLen); - NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16); - - RTMPCheckHt(pAd, Elem->Wcid, &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo); - COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd); - pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE; - bRestart = TRUE; - bnRestart = TRUE; - } - // this timestamp is for MlmePeriodicExec() to check if all 20MHz N peers have left - pAd->StaCfg.Last20NBeaconRxTime = Now; - } - - } - else - { - RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE); - RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE); - } - }while (FALSE); - - // If peer Adhoc is legacy mode, I don't need to call MlmeUpdateHtTxRates no matter I support HT or not - if ((bRestart == TRUE) && (bnRestart == FALSE)) - { - MlmeUpdateTxRates(pAd, FALSE, 0); - MakeIbssBeacon(pAd); // re-build BEACON frame - AsicEnableIbssSync(pAd); // copy to on-chip memory - } - else if ((bRestart == TRUE) && (bnRestart == TRUE)) - { - MlmeUpdateTxRates(pAd, FALSE, BSS0); - MlmeUpdateHtTxRates(pAd, BSS0); - MakeIbssBeacon(pAd); // re-build BEACON frame - AsicEnableIbssSync(pAd); // copy to on-chip memory - } - - // At least another peer in this IBSS, declare MediaState as CONNECTED - if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) - { - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); - - pAd->IndicateMediaState = NdisMediaStateConnected; - RTMP_IndicateMediaState(pAd); - pAd->ExtraInfo = GENERAL_LINK_UP; - AsicSetBssid(pAd, pAd->CommonCfg.Bssid); - - // 2003/03/12 - john - // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that - // "site survey" result should always include the current connected network. - // - Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel); - if (Bssidx == BSS_NOT_FOUND) - { - Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod, - &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability, - &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0, - &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE); - } - DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n")); - } - - // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon. - // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station. - if (ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) - { - UCHAR idx; - MAC_TABLE_ENTRY *pEntry; - - // look up the existing table - pEntry = MacTableLookup(pAd, Addr2); - if (pEntry == NULL) - { - // Another adhoc joining, add to our MAC table. - pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE); - if (pEntry) - { - pEntry->Sst = SST_ASSOC; - idx = pAd->StaCfg.DefaultKeyId; - // After InsertEntry, Write to ASIC on-chip table. - RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry); - 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)); - - pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word; - if (HtCapabilityLen <= 0) - { - pEntry->HTPhyMode.field.STBC = 0; - pEntry->HTPhyMode.field.BW = 0; - pEntry->HTPhyMode.field.ShortGI = 0; - if ((SupRateLen+ExtRateLen <= 4) && (pAd->CommonCfg.Channel <= 14)) - { - pEntry->HTPhyMode.field.MODE = MODE_CCK; - } - else - { - pEntry->HTPhyMode.field.MODE = MODE_OFDM; - } - MlmeUpdateTxRates(pAd, FALSE, 0); - } - else - { - MlmeUpdateTxRates(pAd, FALSE, 0); - MlmeUpdateHtTxRates(pAd, BSS0); - } - - { - union iwreq_data wrqu; - wext_notify_event_assoc(pAd); - - memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN); - memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN); - wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL); - - } - } - } - } -#endif /* RT2860 */ -#ifdef RT2870 UCHAR MaxSupportedRateIn500Kbps = 0; UCHAR idx; MAC_TABLE_ENTRY *pEntry; @@ -1404,7 +1180,14 @@ VOID PeerBeacon( // Another adhoc joining, add to our MAC table. pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE); - if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo) == FALSE) + if (StaAddMacTableEntry(pAd, + pEntry, + MaxSupportedRateIn500Kbps, + &HtCapability, + HtCapabilityLen, + &AddHtInfo, + AddHtInfoLen, + CapabilityInfo) == FALSE) { DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n")); return; @@ -1414,7 +1197,7 @@ VOID PeerBeacon( (Elem->Wcid == RESERVED_WCID)) { idx = pAd->StaCfg.DefaultKeyId; - RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry); + RTMP_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry); } } @@ -1445,7 +1228,6 @@ VOID PeerBeacon( } DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n")); } -#endif /* RT2870 */ } if (INFRA_ON(pAd)) @@ -1534,28 +1316,32 @@ VOID PeerBeacon( // 5. otherwise, put PHY back to sleep to save battery. if (MessageToMe) { -#ifdef RT2860 +#ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) { + // Restore to correct BBP R3 value + if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); + // Turn clk to 80Mhz. } -#endif +#endif // RTMP_MAC_PCI // if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO) { pAd->CommonCfg.bNeedSendTriggerFrame = TRUE; } else - RT28XX_PS_POLL_ENQUEUE(pAd); + RTMP_PS_POLL_ENQUEUE(pAd); } else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM)) { -#ifdef RT2860 +#ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) { + if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } -#endif +#endif // RTMP_MAC_PCI // } else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) || (pAd->TxSwQueue[QID_AC_BE].Number != 0) || @@ -1569,12 +1355,42 @@ VOID PeerBeacon( { // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme // can we cheat here (i.e. just check MGMT & AC_BE) for better performance? -#ifdef RT2860 +#ifdef RTMP_MAC_PCI if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) { + if (pAd->Antenna.field.RxPath > 1) RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3); } -#endif +#endif // RTMP_MAC_PCI // + } + else + { + if ((pAd->CommonCfg.bACMAPSDTr[QID_AC_VO]) || + (pAd->CommonCfg.bACMAPSDTr[QID_AC_VI]) || + (pAd->CommonCfg.bACMAPSDTr[QID_AC_BK]) || + (pAd->CommonCfg.bACMAPSDTr[QID_AC_BE])) + { + /* + WMM Spec v1.0 3.6.2.4, + The WMM STA shall remain awake until it receives a + QoS Data or Null frame addressed to it, with the + EOSP subfield in QoS Control field set to 1. + + So we can not sleep here or we will suffer a case: + + PS Management Frame --> + Trigger frame --> + Beacon (TIM=0) (Beacon is closer to Trig frame) --> + Station goes to sleep --> + AP delivery queued UAPSD packets --> + Station can NOT receive the reply + + Maybe we need a timeout timer to avoid that we do + NOT receive the EOSP frame. + + We can not use More Data to check if SP is ended + due to MaxSPLength. + */ } else { @@ -1589,14 +1405,10 @@ VOID PeerBeacon( if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { -#ifdef RT2860 // Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode. - RTMP_SET_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp; -#endif -#ifdef RT2870 - AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp); -#endif + AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp); + } } } } @@ -1825,6 +1637,8 @@ VOID InvalidStateWhenStart( VOID EnqueuePsPoll( IN PRTMP_ADAPTER pAd) { + + if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP) pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE; MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME)); Index: b/drivers/staging/rt2860/sta/wpa.c =================================================================== --- a/drivers/staging/rt2860/sta/wpa.c +++ b/drivers/staging/rt2860/sta/wpa.c @@ -37,1813 +37,7 @@ */ #include "../rt_config.h" -#define WPARSNIE 0xdd -#define WPA2RSNIE 0x30 - -//extern UCHAR BIT8[]; -UCHAR CipherWpaPskTkip[] = { - 0xDD, 0x16, // RSN IE - 0x00, 0x50, 0xf2, 0x01, // oui - 0x01, 0x00, // Version - 0x00, 0x50, 0xf2, 0x02, // Multicast - 0x01, 0x00, // Number of unicast - 0x00, 0x50, 0xf2, 0x02, // unicast - 0x01, 0x00, // number of authentication method - 0x00, 0x50, 0xf2, 0x02 // authentication - }; -UCHAR CipherWpaPskTkipLen = (sizeof(CipherWpaPskTkip) / sizeof(UCHAR)); - -UCHAR CipherWpaPskAes[] = { - 0xDD, 0x16, // RSN IE - 0x00, 0x50, 0xf2, 0x01, // oui - 0x01, 0x00, // Version - 0x00, 0x50, 0xf2, 0x04, // Multicast - 0x01, 0x00, // Number of unicast - 0x00, 0x50, 0xf2, 0x04, // unicast - 0x01, 0x00, // number of authentication method - 0x00, 0x50, 0xf2, 0x02 // authentication - }; -UCHAR CipherWpaPskAesLen = (sizeof(CipherWpaPskAes) / sizeof(UCHAR)); - -UCHAR CipherSuiteCiscoCCKM[] = { - 0xDD, 0x16, // RSN IE - 0x00, 0x50, 0xf2, 0x01, // oui - 0x01, 0x00, // Version - 0x00, 0x40, 0x96, 0x01, // Multicast - 0x01, 0x00, // Number of uicast - 0x00, 0x40, 0x96, 0x01, // unicast - 0x01, 0x00, // number of authentication method - 0x00, 0x40, 0x96, 0x00 // Authentication - }; -UCHAR CipherSuiteCiscoCCKMLen = (sizeof(CipherSuiteCiscoCCKM) / sizeof(UCHAR)); - -UCHAR CipherSuiteCiscoCCKM24[] = { - 0xDD, 0x18, // RSN IE - 0x00, 0x50, 0xf2, 0x01, // oui - 0x01, 0x00, // Version - 0x00, 0x40, 0x96, 0x01, // Multicast - 0x01, 0x00, // Number of uicast - 0x00, 0x40, 0x96, 0x01, // unicast - 0x01, 0x00, // number of authentication method - 0x00, 0x40, 0x96, 0x00, - 0x28, 0x00// Authentication - }; - -UCHAR CipherSuiteCiscoCCKM24Len = (sizeof(CipherSuiteCiscoCCKM24) / sizeof(UCHAR)); - -UCHAR CipherSuiteCCXTkip[] = { - 0xDD, 0x16, // RSN IE - 0x00, 0x50, 0xf2, 0x01, // oui - 0x01, 0x00, // Version - 0x00, 0x50, 0xf2, 0x02, // Multicast - 0x01, 0x00, // Number of unicast - 0x00, 0x50, 0xf2, 0x02, // unicast - 0x01, 0x00, // number of authentication method - 0x00, 0x50, 0xf2, 0x01 // authentication - }; -UCHAR CipherSuiteCCXTkipLen = (sizeof(CipherSuiteCCXTkip) / sizeof(UCHAR)); - -UCHAR CCX_LLC_HDR[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02}; -UCHAR LLC_NORMAL[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; - -UCHAR EAPOL_FRAME[] = {0x88, 0x8E}; - -BOOLEAN CheckRSNIE( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pData, - IN UCHAR DataLen, - OUT UCHAR *Offset); - -void inc_byte_array(UCHAR *counter, int len); - -/* - ======================================================================== - - Routine Description: - Classify WPA EAP message type - - Arguments: - EAPType Value of EAP message type - MsgType Internal Message definition for MLME state machine - - Return Value: - TRUE Found appropriate message type - FALSE No appropriate message type - - IRQL = DISPATCH_LEVEL - - Note: - All these constants are defined in wpa.h - For supplicant, there is only EAPOL Key message avaliable - - ======================================================================== -*/ -BOOLEAN WpaMsgTypeSubst( - IN UCHAR EAPType, - OUT INT *MsgType) -{ - switch (EAPType) - { - case EAPPacket: - *MsgType = MT2_EAPPacket; - break; - case EAPOLStart: - *MsgType = MT2_EAPOLStart; - break; - case EAPOLLogoff: - *MsgType = MT2_EAPOLLogoff; - break; - case EAPOLKey: - *MsgType = MT2_EAPOLKey; - break; - case EAPOLASFAlert: - *MsgType = MT2_EAPOLASFAlert; - break; - default: - return FALSE; - } - return TRUE; -} - -/* - ========================================================================== - Description: - association state machine init, including state transition and timer init - Parameters: - S - pointer to the association state machine - ========================================================================== - */ -VOID WpaPskStateMachineInit( - IN PRTMP_ADAPTER pAd, - IN STATE_MACHINE *S, - OUT STATE_MACHINE_FUNC Trans[]) -{ - StateMachineInit(S, Trans, MAX_WPA_PSK_STATE, MAX_WPA_PSK_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PSK_IDLE, WPA_MACHINE_BASE); - StateMachineSetAction(S, WPA_PSK_IDLE, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction); -} - -/* - ========================================================================== - Description: - This is state machine function. - When receiving EAPOL packets which is for 802.1x key management. - Use both in WPA, and WPAPSK case. - In this function, further dispatch to different functions according to the received packet. 3 categories are : - 1. normal 4-way pairwisekey and 2-way groupkey handshake - 2. MIC error (Countermeasures attack) report packet from STA. - 3. Request for pairwise/group key update from STA - Return: - ========================================================================== -*/ -VOID WpaEAPOLKeyAction( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem) - -{ - INT MsgType = EAPOL_MSG_INVALID; - PKEY_DESCRIPTER pKeyDesc; - PHEADER_802_11 pHeader; //red - UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY]; - UCHAR EapolVr; - KEY_INFO peerKeyInfo; - - DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaEAPOLKeyAction\n")); - - // Get 802.11 header first - pHeader = (PHEADER_802_11) Elem->Msg; - - // Get EAPoL-Key Descriptor - pKeyDesc = (PKEY_DESCRIPTER) &Elem->Msg[(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H)]; - - NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo)); - NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pKeyDesc->KeyInfo, sizeof(KEY_INFO)); - - *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo)); - - - // 1. Check EAPOL frame version and type - EapolVr = (UCHAR) Elem->Msg[LENGTH_802_11+LENGTH_802_1_H]; - - if (((EapolVr != EAPOL_VER) && (EapolVr != EAPOL_VER2)) || ((pKeyDesc->Type != WPA1_KEY_DESC) && (pKeyDesc->Type != WPA2_KEY_DESC))) - { - DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n")); - return; - } - - // First validate replay counter, only accept message with larger replay counter - // Let equal pass, some AP start with all zero replay counter - NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY); - - if((RTMPCompareMemory(pKeyDesc->ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) && - (RTMPCompareMemory(pKeyDesc->ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0)) - { - DBGPRINT(RT_DEBUG_ERROR, (" ReplayCounter not match \n")); - return; - } - - // Process WPA2PSK frame - if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) - { - if((peerKeyInfo.KeyType == PAIRWISEKEY) && - (peerKeyInfo.EKD_DL == 0) && - (peerKeyInfo.KeyAck == 1) && - (peerKeyInfo.KeyMic == 0) && - (peerKeyInfo.Secure == 0) && - (peerKeyInfo.Error == 0) && - (peerKeyInfo.Request == 0)) - { - MsgType = EAPOL_PAIR_MSG_1; - DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n")); - } else if((peerKeyInfo.KeyType == PAIRWISEKEY) && - (peerKeyInfo.EKD_DL == 1) && - (peerKeyInfo.KeyAck == 1) && - (peerKeyInfo.KeyMic == 1) && - (peerKeyInfo.Secure == 1) && - (peerKeyInfo.Error == 0) && - (peerKeyInfo.Request == 0)) - { - MsgType = EAPOL_PAIR_MSG_3; - DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n")); - } else if((peerKeyInfo.KeyType == GROUPKEY) && - (peerKeyInfo.EKD_DL == 1) && - (peerKeyInfo.KeyAck == 1) && - (peerKeyInfo.KeyMic == 1) && - (peerKeyInfo.Secure == 1) && - (peerKeyInfo.Error == 0) && - (peerKeyInfo.Request == 0)) - { - MsgType = EAPOL_GROUP_MSG_1; - DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n")); - } - - // We will assume link is up (assoc suceess and port not secured). - // All state has to be able to process message from previous state - switch(pAd->StaCfg.WpaState) - { - case SS_START: - if(MsgType == EAPOL_PAIR_MSG_1) - { - Wpa2PairMsg1Action(pAd, Elem); - pAd->StaCfg.WpaState = SS_WAIT_MSG_3; - } - break; - - case SS_WAIT_MSG_3: - if(MsgType == EAPOL_PAIR_MSG_1) - { - Wpa2PairMsg1Action(pAd, Elem); - pAd->StaCfg.WpaState = SS_WAIT_MSG_3; - } - else if(MsgType == EAPOL_PAIR_MSG_3) - { - Wpa2PairMsg3Action(pAd, Elem); - pAd->StaCfg.WpaState = SS_WAIT_GROUP; - } - break; - - case SS_WAIT_GROUP: // When doing group key exchange - case SS_FINISH: // This happened when update group key - if(MsgType == EAPOL_PAIR_MSG_1) - { - // Reset port secured variable - pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; - Wpa2PairMsg1Action(pAd, Elem); - pAd->StaCfg.WpaState = SS_WAIT_MSG_3; - } - else if(MsgType == EAPOL_PAIR_MSG_3) - { - // Reset port secured variable - pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; - Wpa2PairMsg3Action(pAd, Elem); - pAd->StaCfg.WpaState = SS_WAIT_GROUP; - } - else if(MsgType == EAPOL_GROUP_MSG_1) - { - WpaGroupMsg1Action(pAd, Elem); - pAd->StaCfg.WpaState = SS_FINISH; - } - break; - - default: - break; - } - } - // Process WPAPSK Frame - // Classify message Type, either pairwise message 1, 3, or group message 1 for supplicant - else if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) - { - if((peerKeyInfo.KeyType == PAIRWISEKEY) && - (peerKeyInfo.KeyIndex == 0) && - (peerKeyInfo.KeyAck == 1) && - (peerKeyInfo.KeyMic == 0) && - (peerKeyInfo.Secure == 0) && - (peerKeyInfo.Error == 0) && - (peerKeyInfo.Request == 0)) - { - MsgType = EAPOL_PAIR_MSG_1; - DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n")); - } - else if((peerKeyInfo.KeyType == PAIRWISEKEY) && - (peerKeyInfo.KeyIndex == 0) && - (peerKeyInfo.KeyAck == 1) && - (peerKeyInfo.KeyMic == 1) && - (peerKeyInfo.Secure == 0) && - (peerKeyInfo.Error == 0) && - (peerKeyInfo.Request == 0)) - { - MsgType = EAPOL_PAIR_MSG_3; - DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n")); - } - else if((peerKeyInfo.KeyType == GROUPKEY) && - (peerKeyInfo.KeyIndex != 0) && - (peerKeyInfo.KeyAck == 1) && - (peerKeyInfo.KeyMic == 1) && - (peerKeyInfo.Secure == 1) && - (peerKeyInfo.Error == 0) && - (peerKeyInfo.Request == 0)) - { - MsgType = EAPOL_GROUP_MSG_1; - DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n")); - } - - // We will assume link is up (assoc suceess and port not secured). - // All state has to be able to process message from previous state - switch(pAd->StaCfg.WpaState) - { - case SS_START: - if(MsgType == EAPOL_PAIR_MSG_1) - { - WpaPairMsg1Action(pAd, Elem); - pAd->StaCfg.WpaState = SS_WAIT_MSG_3; - } - break; - - case SS_WAIT_MSG_3: - if(MsgType == EAPOL_PAIR_MSG_1) - { - WpaPairMsg1Action(pAd, Elem); - pAd->StaCfg.WpaState = SS_WAIT_MSG_3; - } - else if(MsgType == EAPOL_PAIR_MSG_3) - { - WpaPairMsg3Action(pAd, Elem); - pAd->StaCfg.WpaState = SS_WAIT_GROUP; - } - break; - - case SS_WAIT_GROUP: // When doing group key exchange - case SS_FINISH: // This happened when update group key - if(MsgType == EAPOL_PAIR_MSG_1) - { - WpaPairMsg1Action(pAd, Elem); - pAd->StaCfg.WpaState = SS_WAIT_MSG_3; - // Reset port secured variable - pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; - } - else if(MsgType == EAPOL_PAIR_MSG_3) - { - WpaPairMsg3Action(pAd, Elem); - pAd->StaCfg.WpaState = SS_WAIT_GROUP; - // Reset port secured variable - pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; - } - else if(MsgType == EAPOL_GROUP_MSG_1) - { - WpaGroupMsg1Action(pAd, Elem); - pAd->StaCfg.WpaState = SS_FINISH; - } - break; - - default: - break; - } - } - - DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaEAPOLKeyAction\n")); -} - -/* - ======================================================================== - - Routine Description: - Process Pairwise key 4-way handshaking - - Arguments: - pAd Pointer to our adapter - Elem Message body - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID WpaPairMsg1Action( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem) -{ - PHEADER_802_11 pHeader; - UCHAR *mpool, *PTK, *digest; - PUCHAR pOutBuffer = NULL; - UCHAR Header802_3[14]; - ULONG FrameLen = 0; - PEAPOL_PACKET pMsg1; - EAPOL_PACKET Packet; - UCHAR Mic[16]; - - DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action ----->\n")); - - // allocate memory pool - os_alloc_mem(pAd, (PUCHAR *)&mpool, 256); - - if (mpool == NULL) - return; - - // PTK Len = 80. - PTK = (UCHAR *) ROUND_UP(mpool, 4); - // digest Len = 80. - digest = (UCHAR *) ROUND_UP(PTK + 80, 4); - - pHeader = (PHEADER_802_11) Elem->Msg; - - // Process message 1 from authenticator - pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - - // 1. Save Replay counter, it will use to verify message 3 and construct message 2 - NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); - - // 2. Save ANonce - NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE); - - // Generate random SNonce - GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce); - - // Calc PTK(ANonce, SNonce) - WpaCountPTK(pAd, - pAd->StaCfg.PMK, - pAd->StaCfg.ANonce, - pAd->CommonCfg.Bssid, - pAd->StaCfg.SNonce, - pAd->CurrentAddress, - PTK, - LEN_PTK); - - // Save key to PTK entry - NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK); - - // init 802.3 header and Fill Packet - MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL); - - // Zero Message 2 body - NdisZeroMemory(&Packet, sizeof(Packet)); - Packet.ProVer = EAPOL_VER; - Packet.ProType = EAPOLKey; - // - // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE) - // - Packet.KeyDesc.Type = WPA1_KEY_DESC; - // 1. Key descriptor version and appropriate RSN IE - if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { - Packet.KeyDesc.KeyInfo.KeyDescVer = 2; - } - else // TKIP - { - Packet.KeyDesc.KeyInfo.KeyDescVer = 1; - } - - // fill in Data Material and its length - Packet.KeyDesc.KeyData[0] = IE_WPA; - Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len; - Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2; - NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len); - - // Update packet length after decide Key data payload - Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1]; - - // Update Key length - Packet.KeyDesc.KeyLength[0] = pMsg1->KeyDesc.KeyLength[0]; - Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1]; - // 2. Key Type PeerKey - Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY; - - // 3. KeyMic field presented - Packet.KeyDesc.KeyInfo.KeyMic = 1; - - //Convert to little-endian format. - *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo)); - - - // 4. Fill SNonce - NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE); - - // 5. Key Replay Count - NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY); - - // Send EAPOL(0, 1, 0, 0, 0, P, 0, SNonce, MIC, RSN_IE) - // Out buffer for transmitting message 2 - MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory - if(pOutBuffer == NULL) - { - os_free_mem(pAd, mpool); - return; - } - // Prepare EAPOL frame for MIC calculation - // Be careful, only EAPOL frame is counted for MIC calculation - MakeOutgoingFrame(pOutBuffer, &FrameLen, - Packet.Body_Len[1] + 4, &Packet, - END_OF_ARGS); - - // 6. Prepare and Fill MIC value - NdisZeroMemory(Mic, sizeof(Mic)); - if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { // AES - - HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest); - NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); - } - else - { // TKIP - hmac_md5(PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic); - } - NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); - - //hex_dump("MIC", Mic, LEN_KEY_DESC_MIC); - - MakeOutgoingFrame(pOutBuffer, &FrameLen, - LENGTH_802_3, &Header802_3, - Packet.Body_Len[1] + 4, &Packet, - END_OF_ARGS); - - - // 5. Copy frame to Tx ring and send Msg 2 to authenticator - RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE); - - MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); - os_free_mem(pAd, (PUCHAR)mpool); - - DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action <-----\n")); -} - -VOID Wpa2PairMsg1Action( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem) -{ - PHEADER_802_11 pHeader; - UCHAR *mpool, *PTK, *digest; - PUCHAR pOutBuffer = NULL; - UCHAR Header802_3[14]; - ULONG FrameLen = 0; - PEAPOL_PACKET pMsg1; - EAPOL_PACKET Packet; - UCHAR Mic[16]; - - DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action ----->\n")); - - // allocate memory pool - os_alloc_mem(pAd, (PUCHAR *)&mpool, 256); - - if (mpool == NULL) - return; - - // PTK Len = 80. - PTK = (UCHAR *) ROUND_UP(mpool, 4); - // digest Len = 80. - digest = (UCHAR *) ROUND_UP(PTK + 80, 4); - - pHeader = (PHEADER_802_11) Elem->Msg; - - // Process message 1 from authenticator - pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - - // 1. Save Replay counter, it will use to verify message 3 and construct message 2 - NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); - - // 2. Save ANonce - NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE); - - // Generate random SNonce - GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce); - - if(pMsg1->KeyDesc.KeyDataLen[1] > 0 ) - { - // cached PMKID - } - - // Calc PTK(ANonce, SNonce) - WpaCountPTK(pAd, - pAd->StaCfg.PMK, - pAd->StaCfg.ANonce, - pAd->CommonCfg.Bssid, - pAd->StaCfg.SNonce, - pAd->CurrentAddress, - PTK, - LEN_PTK); - - // Save key to PTK entry - NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK); - - // init 802.3 header and Fill Packet - MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL); - - // Zero message 2 body - NdisZeroMemory(&Packet, sizeof(Packet)); - Packet.ProVer = EAPOL_VER; - Packet.ProType = EAPOLKey; - // - // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE) - // - Packet.KeyDesc.Type = WPA2_KEY_DESC; - - // 1. Key descriptor version and appropriate RSN IE - if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { - Packet.KeyDesc.KeyInfo.KeyDescVer = 2; - } - else // TKIP - { - Packet.KeyDesc.KeyInfo.KeyDescVer = 1; - } - - // fill in Data Material and its length - Packet.KeyDesc.KeyData[0] = IE_WPA2; - Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len; - Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2; - NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len); - - // Update packet length after decide Key data payload - Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1]; - - // 2. Key Type PeerKey - Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY; - - // 3. KeyMic field presented - Packet.KeyDesc.KeyInfo.KeyMic = 1; - - // Update Key Length - Packet.KeyDesc.KeyLength[0] = 0; - Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1]; - - // 4. Fill SNonce - NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE); - - // 5. Key Replay Count - NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY); - - // Convert to little-endian format. - *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo)); - - // Send EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE) - // Out buffer for transmitting message 2 - MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory - if(pOutBuffer == NULL) - { - os_free_mem(pAd, mpool); - return; - } - - // Prepare EAPOL frame for MIC calculation - // Be careful, only EAPOL frame is counted for MIC calculation - MakeOutgoingFrame(pOutBuffer, &FrameLen, - Packet.Body_Len[1] + 4, &Packet, - END_OF_ARGS); - - // 6. Prepare and Fill MIC value - NdisZeroMemory(Mic, sizeof(Mic)); - if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { - // AES - HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest); - NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); - } - else - { - hmac_md5(PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic); - } - NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); - - - // Make Transmitting frame - MakeOutgoingFrame(pOutBuffer, &FrameLen, - LENGTH_802_3, &Header802_3, - Packet.Body_Len[1] + 4, &Packet, - END_OF_ARGS); - - - // 5. Copy frame to Tx ring - RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE); - - MlmeFreeMemory(pAd, pOutBuffer); - os_free_mem(pAd, mpool); - - DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action <-----\n")); - -} - -/* - ======================================================================== - - Routine Description: - Process Pairwise key 4-way handshaking - - Arguments: - pAd Pointer to our adapter - Elem Message body - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID WpaPairMsg3Action( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem) - -{ - PHEADER_802_11 pHeader; - PUCHAR pOutBuffer = NULL; - UCHAR Header802_3[14]; - ULONG FrameLen = 0; - EAPOL_PACKET Packet; - PEAPOL_PACKET pMsg3; - UCHAR Mic[16], OldMic[16]; - MAC_TABLE_ENTRY *pEntry = NULL; - UCHAR skip_offset; - KEY_INFO peerKeyInfo; - - DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action ----->\n")); - - // Record 802.11 header & the received EAPOL packet Msg3 - pHeader = (PHEADER_802_11) Elem->Msg; - pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - - NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo)); - NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO)); - - *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo)); - - - // 1. Verify cipher type match - if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2)) - { - return; - } - else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1)) - { - return; - } - - // Verify RSN IE - //if (!RTMPEqualMemory(pMsg3->KeyDesc.KeyData, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) - if (!CheckRSNIE(pAd, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1], &skip_offset)) - { - DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in Msg 3 of WPA1 4-way handshake!! \n")); - hex_dump("The original RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len); - hex_dump("The received RSN_IE", pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]); - return; - } - else - DBGPRINT(RT_DEBUG_TRACE, ("RSN_IE VALID in Msg 3 of WPA1 4-way handshake!! \n")); - - - // 2. Check MIC value - // Save the MIC and replace with zero - NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); - NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); - if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { - // AES - UCHAR digest[80]; - - HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest); - NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); - } - else // TKIP - { - hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic); - } - - if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC)) - { - DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n")); - return; - } - else - DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n")); - - // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger - if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) - return; - - // Update new replay counter - NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); - - // 4. Double check ANonce - if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) - return; - - // init 802.3 header and Fill Packet - MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL); - - // Zero Message 4 body - NdisZeroMemory(&Packet, sizeof(Packet)); - Packet.ProVer = EAPOL_VER; - Packet.ProType = EAPOLKey; - Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field - - // - // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0) - // - Packet.KeyDesc.Type = WPA1_KEY_DESC; - - // Key descriptor version and appropriate RSN IE - Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer; - - // Update Key Length - Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0]; - Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1]; - - // Key Type PeerKey - Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY; - - // KeyMic field presented - Packet.KeyDesc.KeyInfo.KeyMic = 1; - - // In Msg3, KeyInfo.secure =0 if Group Key HS to come. 1 if no group key HS - // Station sends Msg4 KeyInfo.secure should be the same as that in Msg.3 - Packet.KeyDesc.KeyInfo.Secure= peerKeyInfo.Secure; - - // Convert to little-endian format. - *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo)); - - // Key Replay count - NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); - - // Out buffer for transmitting message 4 - MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory - if(pOutBuffer == NULL) - return; - - // Prepare EAPOL frame for MIC calculation - // Be careful, only EAPOL frame is counted for MIC calculation - MakeOutgoingFrame(pOutBuffer, &FrameLen, - Packet.Body_Len[1] + 4, &Packet, - END_OF_ARGS); - - // Prepare and Fill MIC value - NdisZeroMemory(Mic, sizeof(Mic)); - if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { - // AES - UCHAR digest[80]; - - HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest); - NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); - } - else - { - hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic); - } - NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); - - // Update PTK - // Prepare pair-wise key information into shared key table - NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY)); - pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK); - NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK); - NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK); - - // Decide its ChiperAlg - if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) - pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) - pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES; - else - pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE; - - // Update these related information to MAC_TABLE_ENTRY - pEntry = &pAd->MacTab.Content[BSSID_WCID]; - NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK); - NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK); - NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK); - pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg; - - // Update pairwise key information to ASIC Shared Key Table - AsicAddSharedKeyEntry(pAd, - BSS0, - 0, - pAd->SharedKey[BSS0][0].CipherAlg, - pAd->SharedKey[BSS0][0].Key, - pAd->SharedKey[BSS0][0].TxMic, - pAd->SharedKey[BSS0][0].RxMic); - - // Update ASIC WCID attribute table and IVEIV table - RTMPAddWcidAttributeEntry(pAd, - BSS0, - 0, - pAd->SharedKey[BSS0][0].CipherAlg, - pEntry); - - // Make transmitting frame - MakeOutgoingFrame(pOutBuffer, &FrameLen, - LENGTH_802_3, &Header802_3, - Packet.Body_Len[1] + 4, &Packet, - END_OF_ARGS); - - - // Copy frame to Tx ring and Send Message 4 to authenticator - RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE); - - MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); - - DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action <-----\n")); -} - -VOID Wpa2PairMsg3Action( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem) - -{ - PHEADER_802_11 pHeader; - PUCHAR pOutBuffer = NULL; - UCHAR Header802_3[14]; - ULONG FrameLen = 0; - EAPOL_PACKET Packet; - PEAPOL_PACKET pMsg3; - UCHAR Mic[16], OldMic[16]; - UCHAR *mpool, *KEYDATA, *digest; - UCHAR Key[32]; - MAC_TABLE_ENTRY *pEntry = NULL; - KEY_INFO peerKeyInfo; - - // allocate memory - os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024); - - if(mpool == NULL) - return; - - // KEYDATA Len = 512. - KEYDATA = (UCHAR *) ROUND_UP(mpool, 4); - // digest Len = 80. - digest = (UCHAR *) ROUND_UP(KEYDATA + 512, 4); - - DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg3Action ----->\n")); - - pHeader = (PHEADER_802_11) Elem->Msg; - - // Process message 3 frame. - pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - - NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo)); - NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO)); - - *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo)); - - // 1. Verify cipher type match - if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer!= 2)) - { - os_free_mem(pAd, (PUCHAR)mpool); - return; - } - else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1)) - { - os_free_mem(pAd, (PUCHAR)mpool); - return; - } - - // 2. Check MIC value - // Save the MIC and replace with zero - NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); - NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); - if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { - // AES - HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest); - NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); - } - else - { - hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic); - } - - if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC)) - { - DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n")); - os_free_mem(pAd, (PUCHAR)mpool); - return; - } - else - DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n")); - - // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger - if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) - { - os_free_mem(pAd, (PUCHAR)mpool); - return; - } - - // Update new replay counter - NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); - - // 4. Double check ANonce - if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) - { - os_free_mem(pAd, (PUCHAR)mpool); - return; - } - - // Obtain GTK - // 5. Decrypt GTK from Key Data - DBGPRINT_RAW(RT_DEBUG_TRACE, ("EKD = %d\n", peerKeyInfo.EKD_DL)); - if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { - // Decrypt AES GTK - AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pMsg3->KeyDesc.KeyDataLen[1],pMsg3->KeyDesc.KeyData); - } - else // TKIP - { - INT i; - // Decrypt TKIP GTK - // Construct 32 bytes RC4 Key - NdisMoveMemory(Key, pMsg3->KeyDesc.KeyIv, 16); - NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16); - ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32); - //discard first 256 bytes - for(i = 0; i < 256; i++) - ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT); - // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not - ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]); - } - - if (!ParseKeyData(pAd, KEYDATA, pMsg3->KeyDesc.KeyDataLen[1], 1)) - { - os_free_mem(pAd, (PUCHAR)mpool); - return; - } - - // Update GTK to ASIC - // Update group key information to ASIC Shared Key Table - AsicAddSharedKeyEntry(pAd, - BSS0, - pAd->StaCfg.DefaultKeyId, - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic); - - // Update ASIC WCID attribute table and IVEIV table - RTMPAddWcidAttributeEntry(pAd, - BSS0, - pAd->StaCfg.DefaultKeyId, - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, - NULL); - - // init 802.3 header and Fill Packet - MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL); - - // Zero message 4 body - NdisZeroMemory(&Packet, sizeof(Packet)); - Packet.ProVer = EAPOL_VER; - Packet.ProType = EAPOLKey; - Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field - - // - // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0) - // - Packet.KeyDesc.Type = WPA2_KEY_DESC; - - // Key descriptor version and appropriate RSN IE - Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer; - - // Update Key Length - Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0]; - Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1]; - - // Key Type PeerKey - Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY; - - // KeyMic field presented - Packet.KeyDesc.KeyInfo.KeyMic = 1; - Packet.KeyDesc.KeyInfo.Secure = 1; - - // Convert to little-endian format. - *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo)); - - // Key Replay count - NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); - - // Out buffer for transmitting message 4 - MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory - if(pOutBuffer == NULL) - { - os_free_mem(pAd, (PUCHAR)mpool); - return; - } - - // Prepare EAPOL frame for MIC calculation - // Be careful, only EAPOL frame is counted for MIC calculation - MakeOutgoingFrame(pOutBuffer, &FrameLen, - Packet.Body_Len[1] + 4, &Packet, - END_OF_ARGS); - - // Prepare and Fill MIC value - NdisZeroMemory(Mic, sizeof(Mic)); - if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { - // AES - HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest); - NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); - } - else - { - hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic); - } - NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); - - // Update PTK - // Prepare pair-wise key information into shared key table - NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY)); - pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK); - NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK); - NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK); - - // Decide its ChiperAlg - if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) - pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) - pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES; - else - pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE; - - // Update these related information to MAC_TABLE_ENTRY - pEntry = &pAd->MacTab.Content[BSSID_WCID]; - NdisMoveMemory(&pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK); - NdisMoveMemory(&pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK); - NdisMoveMemory(&pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK); - pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg; - - // Update pairwise key information to ASIC Shared Key Table - AsicAddSharedKeyEntry(pAd, - BSS0, - 0, - pAd->SharedKey[BSS0][0].CipherAlg, - pAd->SharedKey[BSS0][0].Key, - pAd->SharedKey[BSS0][0].TxMic, - pAd->SharedKey[BSS0][0].RxMic); - - // Update ASIC WCID attribute table and IVEIV table - RTMPAddWcidAttributeEntry(pAd, - BSS0, - 0, - pAd->SharedKey[BSS0][0].CipherAlg, - pEntry); - - // Make Transmitting frame - MakeOutgoingFrame(pOutBuffer, &FrameLen, - LENGTH_802_3, &Header802_3, - Packet.Body_Len[1] + 4, &Packet, - END_OF_ARGS); - - - // Copy frame to Tx ring and Send Message 4 to authenticator - RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE); - - // set 802.1x port control - STA_PORT_SECURED(pAd); - - // Indicate Connected for GUI - pAd->IndicateMediaState = NdisMediaStateConnected; - - MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); - os_free_mem(pAd, (PUCHAR)mpool); - - - // send wireless event - for set key done WPA2 - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, BSS0, 0); - - DBGPRINT(RT_DEBUG_ERROR, ("Wpa2PairMsg3Action <-----\n")); - -} - -/* - ======================================================================== - - Routine Description: - Process Group key 2-way handshaking - - Arguments: - pAd Pointer to our adapter - Elem Message body - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID WpaGroupMsg1Action( - IN PRTMP_ADAPTER pAd, - IN MLME_QUEUE_ELEM *Elem) - -{ - PUCHAR pOutBuffer = NULL; - UCHAR Header802_3[14]; - ULONG FrameLen = 0; - EAPOL_PACKET Packet; - PEAPOL_PACKET pGroup; - UCHAR *mpool, *digest, *KEYDATA; - UCHAR Mic[16], OldMic[16]; - UCHAR GTK[32], Key[32]; - KEY_INFO peerKeyInfo; - - // allocate memory - os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024); - - if(mpool == NULL) - return; - - // digest Len = 80. - digest = (UCHAR *) ROUND_UP(mpool, 4); - // KEYDATA Len = 512. - KEYDATA = (UCHAR *) ROUND_UP(digest + 80, 4); - - DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action ----->\n")); - - // Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8) - pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; - - NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo)); - NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pGroup->KeyDesc.KeyInfo, sizeof(KEY_INFO)); - - *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo)); - - // 0. Check cipher type match - if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2)) - { - os_free_mem(pAd, (PUCHAR)mpool); - return; - } - else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1)) - { - os_free_mem(pAd, (PUCHAR)mpool); - return; - } - - // 1. Verify Replay counter - // Check Replay Counter, it has to be larger than last one. No need to be exact one larger - if(RTMPCompareMemory(pGroup->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) - { - os_free_mem(pAd, (PUCHAR)mpool); - return; - } - - // Update new replay counter - NdisMoveMemory(pAd->StaCfg.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); - - // 2. Verify MIC is valid - // Save the MIC and replace with zero - NdisMoveMemory(OldMic, pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); - NdisZeroMemory(pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC); - - if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { // AES - HMAC_SHA1((PUCHAR) pGroup, pGroup->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest); - NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); - } - else - { // TKIP - hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pGroup, pGroup->Body_Len[1] + 4, Mic); - } - - if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC)) - { - DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n")); - MlmeFreeMemory(pAd, (PUCHAR)mpool); - return; - } - else - DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n")); - - - // 3. Decrypt GTK from Key Data - if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { - // Decrypt AES GTK - AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pGroup->KeyDesc.KeyDataLen[1], pGroup->KeyDesc.KeyData); - } - else // TKIP - { - INT i; - - // Decrypt TKIP GTK - // Construct 32 bytes RC4 Key - NdisMoveMemory(Key, pGroup->KeyDesc.KeyIv, 16); - NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16); - ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32); - //discard first 256 bytes - for(i = 0; i < 256; i++) - ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT); - // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not - ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pGroup->KeyDesc.KeyData, pGroup->KeyDesc.KeyDataLen[1]); - } - - // Process decrypted key data material - // Parse keyData to handle KDE format for WPA2PSK - if (peerKeyInfo.EKD_DL) - { - if (!ParseKeyData(pAd, KEYDATA, pGroup->KeyDesc.KeyDataLen[1], 0)) - { - os_free_mem(pAd, (PUCHAR)mpool); - return; - } - } - else // WPAPSK - { - // set key material, TxMic and RxMic for WPAPSK - NdisMoveMemory(GTK, KEYDATA, 32); - NdisMoveMemory(pAd->StaCfg.GTK, GTK, 32); - pAd->StaCfg.DefaultKeyId = peerKeyInfo.KeyIndex; - - // Prepare pair-wise key information into shared key table - NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY)); - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, GTK, LEN_TKIP_EK); - NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, >K[16], LEN_TKIP_RXMICK); - NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, >K[24], LEN_TKIP_TXMICK); - - // Update Shared Key CipherAlg - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE; - if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled) - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled) - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES; - else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled) - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64; - else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled) - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128; - - //hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK); - } - - // Update group key information to ASIC Shared Key Table - AsicAddSharedKeyEntry(pAd, - BSS0, - pAd->StaCfg.DefaultKeyId, - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic); - - // Update ASIC WCID attribute table and IVEIV table - RTMPAddWcidAttributeEntry(pAd, - BSS0, - pAd->StaCfg.DefaultKeyId, - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, - NULL); - - // set 802.1x port control - STA_PORT_SECURED(pAd); - - // Indicate Connected for GUI - pAd->IndicateMediaState = NdisMediaStateConnected; - - // init header and Fill Packet - MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL); - - // Zero Group message 1 body - NdisZeroMemory(&Packet, sizeof(Packet)); - Packet.ProVer = EAPOL_VER; - Packet.ProType = EAPOLKey; - Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field - - // - // Group Message 2 as EAPOL-Key(1,0,0,0,G,0,0,MIC,0) - // - if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) - { - Packet.KeyDesc.Type = WPA2_KEY_DESC; - } - else - { - Packet.KeyDesc.Type = WPA1_KEY_DESC; - } - - // Key descriptor version and appropriate RSN IE - Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer; - - // Update Key Length - Packet.KeyDesc.KeyLength[0] = pGroup->KeyDesc.KeyLength[0]; - Packet.KeyDesc.KeyLength[1] = pGroup->KeyDesc.KeyLength[1]; - - // Key Index as G-Msg 1 - if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) - Packet.KeyDesc.KeyInfo.KeyIndex = peerKeyInfo.KeyIndex; - - // Key Type Group key - Packet.KeyDesc.KeyInfo.KeyType = GROUPKEY; - - // KeyMic field presented - Packet.KeyDesc.KeyInfo.KeyMic = 1; - - // Secure bit - Packet.KeyDesc.KeyInfo.Secure = 1; - - // Convert to little-endian format. - *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo)); - - // Key Replay count - NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY); - - // Out buffer for transmitting group message 2 - MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory - if(pOutBuffer == NULL) - { - MlmeFreeMemory(pAd, (PUCHAR)mpool); - return; - } - - // Prepare EAPOL frame for MIC calculation - // Be careful, only EAPOL frame is counted for MIC calculation - MakeOutgoingFrame(pOutBuffer, &FrameLen, - Packet.Body_Len[1] + 4, &Packet, - END_OF_ARGS); - - // Prepare and Fill MIC value - NdisZeroMemory(Mic, sizeof(Mic)); - if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) - { - // AES - HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest); - NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); - } - else - { - hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic); - } - NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); - - - MakeOutgoingFrame(pOutBuffer, &FrameLen, - LENGTH_802_3, &Header802_3, - Packet.Body_Len[1] + 4, &Packet, - END_OF_ARGS); - - - // 5. Copy frame to Tx ring and prepare for encryption - RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE); - - // 6 Free allocated memory - MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); - os_free_mem(pAd, (PUCHAR)mpool); - - // send wireless event - for set key done WPA2 - if (pAd->CommonCfg.bWirelessEvent) - RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); - - DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action <-----\n")); -} - -/* - ======================================================================== - - Routine Description: - Init WPA MAC header - - Arguments: - pAd Pointer to our adapter - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID WpaMacHeaderInit( - IN PRTMP_ADAPTER pAd, - IN OUT PHEADER_802_11 pHdr80211, - IN UCHAR wep, - IN PUCHAR pAddr1) -{ - NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11)); - pHdr80211->FC.Type = BTYPE_DATA; - pHdr80211->FC.ToDs = 1; - if (wep == 1) - pHdr80211->FC.Wep = 1; - - // Addr1: BSSID, Addr2: SA, Addr3: DA - COPY_MAC_ADDR(pHdr80211->Addr1, pAddr1); - COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress); - COPY_MAC_ADDR(pHdr80211->Addr3, pAd->CommonCfg.Bssid); - pHdr80211->Sequence = pAd->Sequence; -} - -/* - ======================================================================== - - Routine Description: - Copy frame from waiting queue into relative ring buffer and set - appropriate ASIC register to kick hardware encryption before really - sent out to air. - - Arguments: - pAd Pointer to our adapter - PNDIS_PACKET Pointer to outgoing Ndis frame - NumberOfFrag Number of fragment required - - Return Value: - None - - Note: - - ======================================================================== -*/ -VOID RTMPToWirelessSta( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pHeader802_3, - IN UINT HdrLen, - IN PUCHAR pData, - IN UINT DataLen, - IN BOOLEAN is4wayFrame) - -{ - NDIS_STATUS Status; - PNDIS_PACKET pPacket; - UCHAR Index; - - do - { - // 1. build a NDIS packet and call RTMPSendPacket(); - // be careful about how/when to release this internal allocated NDIS PACKET buffer - Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen); - if (Status != NDIS_STATUS_SUCCESS) - break; - - if (is4wayFrame) - RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1); - else - RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0); - - // 2. send out the packet - Status = STASendPacket(pAd, pPacket); - if(Status == NDIS_STATUS_SUCCESS) - { - // Dequeue one frame from TxSwQueue0..3 queue and process it - // There are three place calling dequeue for TX ring. - // 1. Here, right after queueing the frame. - // 2. At the end of TxRingTxDone service routine. - // 3. Upon NDIS call RTMPSendPackets - if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) - { - for(Index = 0; Index < 5; Index ++) - if(pAd->TxSwQueue[Index].Number > 0) - RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS); - } - } - } while(FALSE); - -} - -/* - ======================================================================== - - Routine Description: - Check Sanity RSN IE form AP - - Arguments: - - Return Value: - - - ======================================================================== -*/ -BOOLEAN CheckRSNIE( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pData, - IN UCHAR DataLen, - OUT UCHAR *Offset) -{ - PUCHAR pVIE; - UCHAR len; - PEID_STRUCT pEid; - BOOLEAN result = FALSE; - - pVIE = pData; - len = DataLen; - *Offset = 0; - - while (len > sizeof(RSNIE2)) - { - pEid = (PEID_STRUCT) pVIE; - // WPA RSN IE - if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) - { - if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) && - (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) && - (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2))) - { - DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA/WPAPSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2))); - result = TRUE; - } - - *Offset += (pEid->Len + 2); - } - // WPA2 RSN IE - else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) - { - if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) && - (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) && - (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2))) - { - DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2))); - result = TRUE; - } - - *Offset += (pEid->Len + 2); - } - else - { - break; - } - - pVIE += (pEid->Len + 2); - len -= (pEid->Len + 2); - } - - DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> skip_offset(%d) \n", *Offset)); - - return result; - -} - - -/* - ======================================================================== - - Routine Description: - Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK. - GTK is encaptulated in KDE format at p.83 802.11i D10 - - Arguments: - - Return Value: - - Note: - 802.11i D10 - - ======================================================================== -*/ -BOOLEAN ParseKeyData( - IN PRTMP_ADAPTER pAd, - IN PUCHAR pKeyData, - IN UCHAR KeyDataLen, - IN UCHAR bPairewise) -{ - PKDE_ENCAP pKDE = NULL; - PUCHAR pMyKeyData = pKeyData; - UCHAR KeyDataLength = KeyDataLen; - UCHAR GTKLEN; - UCHAR skip_offset; - - // Verify The RSN IE contained in Pairewise-Msg 3 and skip it - if (bPairewise) - { - // Check RSN IE whether it is WPA2/WPA2PSK - if (!CheckRSNIE(pAd, pKeyData, KeyDataLen, &skip_offset)) - { - DBGPRINT(RT_DEBUG_ERROR, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE mismatched \n")); - hex_dump("Get KEYDATA :", pKeyData, KeyDataLen); - return FALSE; - } - else - { - // skip RSN IE - pMyKeyData += skip_offset; - KeyDataLength -= skip_offset; - - //DBGPRINT(RT_DEBUG_TRACE, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset)); - } - } - - DBGPRINT(RT_DEBUG_TRACE,("ParseKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength)); - - // Parse EKD format - if (KeyDataLength >= 8) - { - pKDE = (PKDE_ENCAP) pMyKeyData; - } - else - { - DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KeyDataLength is too short \n")); - return FALSE; - } - - - // Sanity check - shared key index should not be 0 - if (pKDE->GTKEncap.Kid == 0) - { - DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index zero \n")); - return FALSE; - } - - // Sanity check - KED length - if (KeyDataLength < (pKDE->Len + 2)) - { - DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n")); - return FALSE; - } - - // Get GTK length - refer to IEEE 802.11i-2004 p.82 - GTKLEN = pKDE->Len -6; - - if (GTKLEN < LEN_AES_KEY) - { - DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN)); - return FALSE; - } - else - DBGPRINT(RT_DEBUG_TRACE, ("GTK Key with KDE formet got index=%d, len=%d \n", pKDE->GTKEncap.Kid, GTKLEN)); - - // Update GTK - // set key material, TxMic and RxMic for WPAPSK - NdisMoveMemory(pAd->StaCfg.GTK, pKDE->GTKEncap.GTK, 32); - pAd->StaCfg.DefaultKeyId = pKDE->GTKEncap.Kid; - - // Update shared key table - NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY)); - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK; - NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKDE->GTKEncap.GTK, LEN_TKIP_EK); - NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &pKDE->GTKEncap.GTK[16], LEN_TKIP_RXMICK); - NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &pKDE->GTKEncap.GTK[24], LEN_TKIP_TXMICK); - - // Update Shared Key CipherAlg - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE; - if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled) - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP; - else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled) - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES; - else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled) - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64; - else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled) - pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128; - - return TRUE; - -} - -/* - ======================================================================== - - Routine Description: - Cisco CCKM PRF function - - Arguments: - key Cisco Base Transient Key (BTK) - key_len The key length of the BTK - data Ruquest Number(RN) + BSSID - data_len The length of the data - output Store for PTK(Pairwise transient keys) - len The length of the output - Return Value: - None - - Note: - 802.1i Annex F.9 - - ======================================================================== -*/ -VOID CCKMPRF( - IN UCHAR *key, - IN INT key_len, - IN UCHAR *data, - IN INT data_len, - OUT UCHAR *output, - IN INT len) -{ - INT i; - UCHAR input[1024]; - INT currentindex = 0; - INT total_len; - - NdisMoveMemory(input, data, data_len); - total_len = data_len; - input[total_len] = 0; - total_len++; - for (i = 0; i < (len + 19) / 20; i++) - { - HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]); - currentindex += 20; - input[total_len - 1]++; - } -} +void inc_byte_array(UCHAR *counter, int len); /* ======================================================================== @@ -1872,7 +66,7 @@ VOID RTMPReportMicError( UCHAR unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0); // Record Last MIC error time and count - Now = jiffies; + NdisGetSystemUpTime(&Now); if (pAd->StaCfg.MicErrCnt == 0) { pAd->StaCfg.MicErrCnt++; @@ -1895,6 +89,17 @@ VOID RTMPReportMicError( pAd->StaCfg.LastMicErrorTime = Now; // Violate MIC error counts, MIC countermeasures kicks in pAd->StaCfg.MicErrCnt++; + // We shall block all reception + // We shall clean all Tx ring and disassoicate from AP after next EAPOL frame + // + // No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets + // if pAd->StaCfg.MicErrCnt greater than 2. + // + // RTMPRingCleanUp(pAd, QID_AC_BK); + // RTMPRingCleanUp(pAd, QID_AC_BE); + // RTMPRingCleanUp(pAd, QID_AC_VI); + // RTMPRingCleanUp(pAd, QID_AC_VO); + // RTMPRingCleanUp(pAd, QID_HCCA); } } else @@ -1944,14 +149,13 @@ VOID WpaSendMicFailureToWpaSupplicant IN PRTMP_ADAPTER pAd, IN BOOLEAN bUnicast) { - union iwreq_data wrqu; char custom[IW_CUSTOM_MAX] = {0}; sprintf(custom, "MLME-MICHAELMICFAILURE.indication"); - if (bUnicast) + if(bUnicast) sprintf(custom, "%s unicast", custom); - wrqu.data.length = strlen(custom); - wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom); + + RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, -1, NULL, (PUCHAR)custom, strlen(custom)); return; } @@ -2002,7 +206,7 @@ VOID WpaMicFailureReportFrame( Packet.KeyDesc.KeyInfo.Error = 1; // Update packet length after decide Key data payload - Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; + SET_UINT16_TO_ARRARY(Packet.Body_Len, LEN_EAPOL_KEY_MSG) // Key Replay Count NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY); @@ -2021,7 +225,7 @@ VOID WpaMicFailureReportFrame( // Prepare EAPOL frame for MIC calculation // Be careful, only EAPOL frame is counted for MIC calculation MakeOutgoingFrame(pOutBuffer, &FrameLen, - Packet.Body_Len[1] + 4, &Packet, + CONV_ARRARY_TO_UINT16(Packet.Body_Len) + 4, &Packet, END_OF_ARGS); // Prepare and Fill MIC value @@ -2029,22 +233,20 @@ VOID WpaMicFailureReportFrame( if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) { // AES UCHAR digest[20] = {0}; - HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest); + HMAC_SHA1(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, digest, SHA1_DIGEST_SIZE); NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC); } else { // TKIP - hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic); + HMAC_MD5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic, MD5_DIGEST_SIZE); } NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC); - MakeOutgoingFrame(pOutBuffer, &FrameLen, - LENGTH_802_3, &Header802_3, - Packet.Body_Len[1] + 4, &Packet, - END_OF_ARGS); - - // opy frame to Tx ring and send MIC failure report frame to authenticator - RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE); + // copy frame to Tx ring and send MIC failure report frame to authenticator + RTMPToWirelessSta(pAd, &pAd->MacTab.Content[BSSID_WCID], + Header802_3, LENGTH_802_3, + (PUCHAR)&Packet, + CONV_ARRARY_TO_UINT16(Packet.Body_Len) + 4, FALSE); MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer); @@ -2089,3 +291,149 @@ VOID WpaDisassocApAndBlockAssoc( pAd->StaCfg.bBlockAssoc = TRUE; } +VOID WpaStaPairwiseKeySetting( + IN PRTMP_ADAPTER pAd) +{ + PCIPHER_KEY pSharedKey; + PMAC_TABLE_ENTRY pEntry; + + pEntry = &pAd->MacTab.Content[BSSID_WCID]; + + // Pairwise key shall use key#0 + pSharedKey = &pAd->SharedKey[BSS0][0]; + + NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK); + + // Prepare pair-wise key information into shared key table + NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY)); + pSharedKey->KeyLen = LEN_TKIP_EK; + NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK); + NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK); + NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK); + + // Decide its ChiperAlg + if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled) + pSharedKey->CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) + pSharedKey->CipherAlg = CIPHER_AES; + else + pSharedKey->CipherAlg = CIPHER_NONE; + + // Update these related information to MAC_TABLE_ENTRY + NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK); + NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK); + NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK); + pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg; + + // Update pairwise key information to ASIC Shared Key Table + AsicAddSharedKeyEntry(pAd, + BSS0, + 0, + pSharedKey->CipherAlg, + pSharedKey->Key, + pSharedKey->TxMic, + pSharedKey->RxMic); + + // Update ASIC WCID attribute table and IVEIV table + RTMPAddWcidAttributeEntry(pAd, + BSS0, + 0, + pSharedKey->CipherAlg, + pEntry); + STA_PORT_SECURED(pAd); + pAd->IndicateMediaState = NdisMediaStateConnected; + + DBGPRINT(RT_DEBUG_TRACE, ("%s : AID(%d) port secured\n", __func__, pEntry->Aid)); + +} + +VOID WpaStaGroupKeySetting( + IN PRTMP_ADAPTER pAd) +{ + PCIPHER_KEY pSharedKey; + + pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId]; + + // Prepare pair-wise key information into shared key table + NdisZeroMemory(pSharedKey, sizeof(CIPHER_KEY)); + pSharedKey->KeyLen = LEN_TKIP_EK; + NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK); + NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16], LEN_TKIP_RXMICK); + NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24], LEN_TKIP_TXMICK); + + // Update Shared Key CipherAlg + pSharedKey->CipherAlg = CIPHER_NONE; + if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled) + pSharedKey->CipherAlg = CIPHER_TKIP; + else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled) + pSharedKey->CipherAlg = CIPHER_AES; + else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled) + pSharedKey->CipherAlg = CIPHER_WEP64; + else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled) + pSharedKey->CipherAlg = CIPHER_WEP128; + + // Update group key information to ASIC Shared Key Table + AsicAddSharedKeyEntry(pAd, + BSS0, + pAd->StaCfg.DefaultKeyId, + pSharedKey->CipherAlg, + pSharedKey->Key, + pSharedKey->TxMic, + pSharedKey->RxMic); + + // Update ASIC WCID attribute table and IVEIV table + RTMPAddWcidAttributeEntry(pAd, + BSS0, + pAd->StaCfg.DefaultKeyId, + pSharedKey->CipherAlg, + NULL); + +} + + +/* + ======================================================================== + + Routine Description: + Send EAPoL-Start packet to AP. + + Arguments: + pAd - NIC Adapter pointer + + Return Value: + None + + IRQL = DISPATCH_LEVEL + + Note: + Actions after link up + 1. Change the correct parameters + 2. Send EAPOL - START + + ======================================================================== +*/ +VOID WpaSendEapolStart( + IN PRTMP_ADAPTER pAd, + IN PUCHAR pBssid) +{ + IEEE8021X_FRAME Packet; + UCHAR Header802_3[14]; + + DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaSendEapolStart\n")); + + NdisZeroMemory(Header802_3,sizeof(UCHAR)*14); + + MAKE_802_3_HEADER(Header802_3, pBssid, &pAd->CurrentAddress[0], EAPOL); + + // Zero message 2 body + NdisZeroMemory(&Packet, sizeof(Packet)); + Packet.Version = EAPOL_VER; + Packet.Type = EAPOLStart; + Packet.Length = cpu2be16(0); + + // Copy frame to Tx ring + RTMPToWirelessSta((PRTMP_ADAPTER)pAd, &pAd->MacTab.Content[BSSID_WCID], + Header802_3, LENGTH_802_3, (PUCHAR)&Packet, 4, TRUE); + + DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaSendEapolStart\n")); +} Index: b/drivers/staging/rt2860/sta_ioctl.c =================================================================== --- a/drivers/staging/rt2860/sta_ioctl.c +++ b/drivers/staging/rt2860/sta_ioctl.c @@ -50,8 +50,6 @@ extern ULONG RTDebugLevel; #define GROUP_KEY_NO 4 extern UCHAR CipherWpa2Template[]; -extern UCHAR CipherWpaPskTkip[]; -extern UCHAR CipherWpaPskTkipLen; typedef struct PACKED _RT_VERSION_INFO{ UCHAR DriverVersionW; @@ -68,25 +66,25 @@ struct iw_priv_args privtab[] = { IW_PRIV_TYPE_CHAR | 1024, 0, "set"}, -{ RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, - ""}, { RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, ""}, /* --- sub-ioctls definitions --- */ { SHOW_CONN_STATUS, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" }, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" }, { SHOW_DRVIER_VERION, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" }, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" }, { SHOW_BA_INFO, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" }, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" }, { SHOW_DESC_INFO, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" }, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" }, { RAIO_OFF, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" }, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" }, { RAIO_ON, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" }, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" }, { SHOW_CFG_VALUE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" }, + { SHOW_ADHOC_ENTRY_INFO, + IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "adhocEntry" }, /* --- sub-ioctls relations --- */ { RTPRIV_IOCTL_STATISTICS, @@ -95,62 +93,76 @@ struct iw_priv_args privtab[] = { { RTPRIV_IOCTL_GSITESURVEY, 0, IW_PRIV_TYPE_CHAR | 1024, "get_site_survey"}, + + }; +static __s32 ralinkrate[] = + {2, 4, 11, 22, // CCK + 12, 18, 24, 36, 48, 72, 96, 108, // OFDM + 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15 + 39, 78, 117, 156, 234, 312, 351, 390, // 20MHz, 800ns GI, MCS: 16 ~ 23 + 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15 + 81, 162, 243, 324, 486, 648, 729, 810, // 40MHz, 800ns GI, MCS: 16 ~ 23 + 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15 + 43, 87, 130, 173, 260, 317, 390, 433, // 20MHz, 400ns GI, MCS: 16 ~ 23 + 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15 + 90, 180, 270, 360, 540, 720, 810, 900}; + INT Set_SSID_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); #ifdef WMM_SUPPORT INT Set_WmmCapable_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); #endif INT Set_NetworkType_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); INT Set_AuthMode_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); INT Set_EncrypType_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); INT Set_DefaultKeyID_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); INT Set_Key1_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); INT Set_Key2_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); INT Set_Key3_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); INT Set_Key4_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); INT Set_WPAPSK_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); INT Set_PSMode_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); INT Set_Wpa_Support( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); NDIS_STATUS RTMPWPANoneAddKeyProc( IN PRTMP_ADAPTER pAd, @@ -158,23 +170,45 @@ NDIS_STATUS RTMPWPANoneAddKeyProc( INT Set_FragTest_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); INT Set_TGnWifiTest_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg); + IN PSTRING arg); INT Set_LongRetryLimit_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); INT Set_ShortRetryLimit_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg); + IN PSTRING arg); + + + +INT Show_Adhoc_MacTable_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING extra); + +INT Set_BeaconLostTime_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_AutoRoaming_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_SiteSurvey_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); + +INT Set_ForceTxBurst_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg); static struct { - CHAR *name; - INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg); + PSTRING name; + INT (*set_proc)(PRTMP_ADAPTER pAdapter, PSTRING arg); } *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = { {"DriverVersion", Set_DriverVersion_Proc}, {"CountryRegion", Set_CountryRegion_Proc}, @@ -201,9 +235,10 @@ static struct { {"HtBaDecline", Set_BADecline_Proc}, {"HtProtect", Set_HtProtect_Proc}, {"HtMimoPs", Set_HtMimoPs_Proc}, + {"HtDisallowTKIP", Set_HtDisallowTKIP_Proc}, #ifdef AGGREGATION_SUPPORT {"PktAggregate", Set_PktAggregate_Proc}, -#endif +#endif // AGGREGATION_SUPPORT // #ifdef WMM_SUPPORT {"WmmCapable", Set_WmmCapable_Proc}, @@ -222,18 +257,36 @@ static struct { {"PSMode", Set_PSMode_Proc}, #ifdef DBG {"Debug", Set_Debug_Proc}, -#endif +#endif // DBG // + + {"WpaSupport", Set_Wpa_Support}, + + + + + {"FixedTxMode", Set_FixedTxMode_Proc}, {"TGnWifiTest", Set_TGnWifiTest_Proc}, {"ForceGF", Set_ForceGF_Proc}, {"LongRetry", Set_LongRetryLimit_Proc}, {"ShortRetry", Set_ShortRetryLimit_Proc}, -#ifdef RT2870 + +//2008/09/11:KH add to support efuse<-- +#ifdef RT30xx +#ifdef RTMP_EFUSE_SUPPORT {"efuseFreeNumber", set_eFuseGetFreeBlockCount_Proc}, {"efuseDump", set_eFusedump_Proc}, {"efuseLoadFromBin", set_eFuseLoadFromBin_Proc}, -#endif + {"efuseBufferModeWriteBack", set_eFuseBufferModeWriteBack_Proc}, +#endif // RTMP_EFUSE_SUPPORT // +#endif // RT30xx // +//2008/09/11:KH add to support efuse--> + {"BeaconLostTime", Set_BeaconLostTime_Proc}, + {"AutoRoaming", Set_AutoRoaming_Proc}, + {"SiteSurvey", Set_SiteSurvey_Proc}, + {"ForceTxBurst", Set_ForceTxBurst_Proc}, + {NULL,} }; @@ -247,22 +300,6 @@ VOID RTMPAddKey( DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n")); -#ifdef RT2860 - RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); - if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)) - { - if (pAd->StaCfg.bRadio == FALSE) - { - RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); - return; - } - DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n")); - RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT); - RTMPusecDelay(6000); - pAd->bPCIclkOff = FALSE; - } -#endif - if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) { if (pKey->KeyIndex & 0x80000000) @@ -323,6 +360,7 @@ VOID RTMPAddKey( if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2) { // set 802.1x port control + //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; STA_PORT_SECURED(pAd); // Indicate Connected for GUI @@ -372,6 +410,7 @@ VOID RTMPAddKey( NULL); // set 802.1x port control + //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; STA_PORT_SECURED(pAd); // Indicate Connected for GUI @@ -454,10 +493,6 @@ VOID RTMPAddKey( } } end: -#ifdef RT2860 - RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); - DBGPRINT(RT_DEBUG_INFO, ("<------ RTMPAddKey\n")); -#endif return; } @@ -478,8 +513,8 @@ rt_ioctl_giwname(struct net_device *dev, struct iw_request_info *info, char *name, char *extra) { -// PRTMP_ADAPTER pAdapter = dev->ml_priv; - strncpy(name, RT28xx_CHIP_NAME " Wireless", IFNAMSIZ); + strncpy(name, "Ralink STA", IFNAMSIZ); + // RT2870 2.1.0.0 uses "RT2870 Wireless" return 0; } @@ -487,9 +522,11 @@ int rt_ioctl_siwfreq(struct net_device * struct iw_request_info *info, struct iw_freq *freq, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; int chan = -1; + GET_PAD_FROM_NET_DEV(pAdapter, dev); + //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { @@ -520,9 +557,13 @@ int rt_ioctl_giwfreq(struct net_device * struct iw_request_info *info, struct iw_freq *freq, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; - UCHAR ch = pAdapter->CommonCfg.Channel; - ULONG m; + PRTMP_ADAPTER pAdapter = NULL; + UCHAR ch; + ULONG m = 2412000; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); + + ch = pAdapter->CommonCfg.Channel; DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq %d\n", ch)); @@ -536,7 +577,9 @@ int rt_ioctl_siwmode(struct net_device * struct iw_request_info *info, __u32 *mode, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) @@ -571,7 +614,9 @@ int rt_ioctl_giwmode(struct net_device * struct iw_request_info *info, __u32 *mode, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); if (ADHOC_ON(pAdapter)) *mode = IW_MODE_ADHOC; @@ -592,7 +637,9 @@ int rt_ioctl_siwsens(struct net_device * struct iw_request_info *info, char *name, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) @@ -615,11 +662,13 @@ int rt_ioctl_giwrange(struct net_device struct iw_request_info *info, struct iw_point *data, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; struct iw_range *range = (struct iw_range *) extra; u16 val; int i; + GET_PAD_FROM_NET_DEV(pAdapter, dev); + DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n")); data->length = sizeof(struct iw_range); memset(range, 0, sizeof(struct iw_range)); @@ -651,10 +700,10 @@ int rt_ioctl_giwrange(struct net_device val = 0; for (i = 1; i <= range->num_channels; i++) { - u32 m; + u32 m = 2412000; range->freq[val].i = pAdapter->ChannelList[i-1].Channel; MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m); - range->freq[val].m = m * 100; /* HZ */ + range->freq[val].m = m * 100; /* OS_HZ */ range->freq[val].e = 1; val++; @@ -696,9 +745,11 @@ int rt_ioctl_siwap(struct net_device *de struct iw_request_info *info, struct sockaddr *ap_addr, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; NDIS_802_11_MAC_ADDRESS Bssid; + GET_PAD_FROM_NET_DEV(pAdapter, dev); + //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { @@ -708,7 +759,7 @@ int rt_ioctl_siwap(struct net_device *de if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) { - RT28XX_MLME_RESET_STATE_MACHINE(pAdapter); + RTMP_MLME_RESET_STATE_MACHINE(pAdapter); DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n")); } @@ -736,7 +787,9 @@ int rt_ioctl_giwap(struct net_device *de struct iw_request_info *info, struct sockaddr *ap_addr, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter)) { @@ -802,12 +855,14 @@ int rt_ioctl_iwaplist(struct net_device struct iw_request_info *info, struct iw_point *data, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; struct sockaddr addr[IW_MAX_AP]; struct iw_quality qual[IW_MAX_AP]; int i; + GET_PAD_FROM_NET_DEV(pAdapter, dev); + //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { @@ -837,11 +892,13 @@ int rt_ioctl_siwscan(struct net_device * struct iw_request_info *info, struct iw_point *data, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; ULONG Now; int Status = NDIS_STATUS_SUCCESS; + GET_PAD_FROM_NET_DEV(pAdapter, dev); + //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { @@ -854,17 +911,8 @@ int rt_ioctl_siwscan(struct net_device * DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n")); return -EINVAL; } -#ifdef RT2860 - if ((pAdapter->OpMode == OPMODE_STA) && (IDLE_ON(pAdapter)) - && (pAdapter->StaCfg.bRadio == TRUE) - && (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_IDLE_RADIO_OFF))) - { - RT28xxPciAsicRadioOn(pAdapter, GUI_IDLE_POWER_SAVE); - } - // Check if still radio off. - else if (pAdapter->bPCIclkOff == TRUE) - return 0; -#endif + + if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) { pAdapter->StaCfg.WpaSupplicantScanCount++; @@ -872,7 +920,7 @@ int rt_ioctl_siwscan(struct net_device * pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE; if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - return 0; + return NDIS_STATUS_SUCCESS; do{ Now = jiffies; @@ -896,7 +944,7 @@ int rt_ioctl_siwscan(struct net_device * if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) { - RT28XX_MLME_RESET_STATE_MACHINE(pAdapter); + RTMP_MLME_RESET_STATE_MACHINE(pAdapter); DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n")); } @@ -914,23 +962,25 @@ int rt_ioctl_siwscan(struct net_device * NULL); Status = NDIS_STATUS_SUCCESS; - RT28XX_MLME_HANDLER(pAdapter); + RTMP_MLME_HANDLER(pAdapter); }while(0); - return 0; + return NDIS_STATUS_SUCCESS; } int rt_ioctl_giwscan(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra) { - - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; int i=0; - char *current_ev = extra, *previous_ev = extra; - char *end_buf; - char *current_val, custom[MAX_CUSTOM_LEN] = {0}; + PSTRING current_ev = extra, previous_ev = extra; + PSTRING end_buf; + PSTRING current_val; + STRING custom[MAX_CUSTOM_LEN] = {0}; struct iw_event iwe; + GET_PAD_FROM_NET_DEV(pAdapter, dev); + if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { /* @@ -958,7 +1008,9 @@ int rt_ioctl_giwscan(struct net_device * for (i = 0; i < pAdapter->ScanTab.BssNr; i++) { if (current_ev >= end_buf) + { return -E2BIG; + } //MAC address //================================ @@ -1043,7 +1095,7 @@ int rt_ioctl_giwscan(struct net_device * } previous_ev = current_ev; - current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); + current_ev = iwe_stream_add_event(info, current_ev,end_buf, &iwe, IW_EV_ADDR_LEN); if (current_ev == previous_ev) return -E2BIG; @@ -1055,7 +1107,7 @@ int rt_ioctl_giwscan(struct net_device * iwe.u.data.flags = 1; previous_ev = current_ev; - current_ev = iwe_stream_add_point(info, current_ev,end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid); + current_ev = iwe_stream_add_point(info, current_ev,end_buf, &iwe, (PSTRING) pAdapter->ScanTab.BssEntry[i].Ssid); if (current_ev == previous_ev) return -E2BIG; @@ -1142,6 +1194,20 @@ int rt_ioctl_giwscan(struct net_device * else iwe.u.bitrate.value = (tmpRate/2) * 1000000; + if (tmpRate == 0x6c && pAdapter->ScanTab.BssEntry[i].HtCapabilityLen > 0) + { + int rate_count = sizeof(ralinkrate)/sizeof(__s32); + HT_CAP_INFO capInfo = pAdapter->ScanTab.BssEntry[i].HtCapability.HtCapInfo; + int shortGI = capInfo.ChannelWidth ? capInfo.ShortGIfor40 : capInfo.ShortGIfor20; + int maxMCS = pAdapter->ScanTab.BssEntry[i].HtCapability.MCSSet[1] ? 15 : 7; + int rate_index = 12 + ((UCHAR)capInfo.ChannelWidth * 24) + ((UCHAR)shortGI *48) + ((UCHAR)maxMCS); + if (rate_index < 0) + rate_index = 0; + if (rate_index > rate_count) + rate_index = rate_count; + iwe.u.bitrate.value = ralinkrate[rate_index] * 500000; + } + iwe.u.bitrate.disabled = 0; current_val = iwe_stream_add_value(info, current_ev, current_val, end_buf, &iwe, @@ -1192,7 +1258,9 @@ int rt_ioctl_siwessid(struct net_device struct iw_request_info *info, struct iw_point *data, char *essid) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) @@ -1203,13 +1271,13 @@ int rt_ioctl_siwessid(struct net_device if (data->flags) { - PCHAR pSsidString = NULL; + PSTRING pSsidString = NULL; // Includes null character. if (data->length > (IW_ESSID_MAX_SIZE + 1)) return -E2BIG; - pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG); + pSsidString = kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG); if (pSsidString) { NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1); @@ -1233,7 +1301,9 @@ int rt_ioctl_giwessid(struct net_device struct iw_request_info *info, struct iw_point *data, char *essid) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); data->flags = 1; if (MONITOR_ON(pAdapter)) @@ -1248,14 +1318,14 @@ int rt_ioctl_giwessid(struct net_device data->length = pAdapter->CommonCfg.SsidLen; memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen); } -#ifdef RT2870 +#ifdef RTMP_MAC_USB // Add for RT2870 else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) { data->length = pAdapter->CommonCfg.SsidLen; memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen); } -#endif // RT2870 // +#endif // RTMP_MAC_USB // else {//the ANY ssid was specified data->length = 0; @@ -1270,7 +1340,9 @@ int rt_ioctl_siwnickn(struct net_device struct iw_request_info *info, struct iw_point *data, char *nickname) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) @@ -1293,10 +1365,12 @@ int rt_ioctl_giwnickn(struct net_device struct iw_request_info *info, struct iw_point *data, char *nickname) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); - if (data->length > strlen(pAdapter->nickname) + 1) - data->length = strlen(pAdapter->nickname) + 1; + if (data->length > strlen((PSTRING) pAdapter->nickname) + 1) + data->length = strlen((PSTRING) pAdapter->nickname) + 1; if (data->length > 0) { memcpy(nickname, pAdapter->nickname, data->length-1); nickname[data->length-1] = '\0'; @@ -1308,9 +1382,11 @@ int rt_ioctl_siwrts(struct net_device *d struct iw_request_info *info, struct iw_param *rts, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; u16 val; + GET_PAD_FROM_NET_DEV(pAdapter, dev); + //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { @@ -1337,7 +1413,9 @@ int rt_ioctl_giwrts(struct net_device *d struct iw_request_info *info, struct iw_param *rts, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) @@ -1357,9 +1435,11 @@ int rt_ioctl_siwfrag(struct net_device * struct iw_request_info *info, struct iw_param *frag, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; u16 val; + GET_PAD_FROM_NET_DEV(pAdapter, dev); + //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { @@ -1384,7 +1464,9 @@ int rt_ioctl_giwfrag(struct net_device * struct iw_request_info *info, struct iw_param *frag, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) @@ -1406,7 +1488,9 @@ int rt_ioctl_siwencode(struct net_device struct iw_request_info *info, struct iw_point *erq, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) @@ -1424,8 +1508,10 @@ int rt_ioctl_siwencode(struct net_device pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus; pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen; goto done; - } else if ( - (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)) { + } + else if (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN) + { + //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; STA_PORT_SECURED(pAdapter); pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled; pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled; @@ -1441,7 +1527,8 @@ int rt_ioctl_siwencode(struct net_device { int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1; /* Check the size of the key */ - if (erq->length > MAX_WEP_KEY_SIZE) { + if (erq->length > MAX_WEP_KEY_SIZE) + { return -EINVAL; } /* Check key index */ @@ -1454,7 +1541,7 @@ int rt_ioctl_siwencode(struct net_device keyIdx = pAdapter->StaCfg.DefaultKeyId; } else - pAdapter->StaCfg.DefaultKeyId=keyIdx; + pAdapter->StaCfg.DefaultKeyId = keyIdx; NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16); @@ -1473,7 +1560,8 @@ int rt_ioctl_siwencode(struct net_device pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0; /* Check if the key is not marked as invalid */ - if(!(erq->flags & IW_ENCODE_NOKEY)) { + if(!(erq->flags & IW_ENCODE_NOKEY)) + { /* Copy the key in the driver */ NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length); } @@ -1488,10 +1576,9 @@ int rt_ioctl_siwencode(struct net_device } else /* Don't complain if only change the mode */ - if (!(erq->flags & IW_ENCODE_MODE)) { + if (!(erq->flags & IW_ENCODE_MODE)) return -EINVAL; } - } done: DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags)); @@ -1506,8 +1593,10 @@ rt_ioctl_giwencode(struct net_device *de struct iw_request_info *info, struct iw_point *erq, char *key) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; int kid; + PRTMP_ADAPTER pAdapter = NULL; + + GET_PAD_FROM_NET_DEV(pAdapter, dev); //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) @@ -1564,12 +1653,15 @@ static int rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info, void *w, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; - POS_COOKIE pObj = (POS_COOKIE)pAdapter->OS_Cookie; - char *this_char = extra; - char *value; + PRTMP_ADAPTER pAdapter; + POS_COOKIE pObj; + PSTRING this_char = extra; + PSTRING value; int Status=0; + GET_PAD_FROM_NET_DEV(pAdapter, dev); + + pObj = (POS_COOKIE) pAdapter->OS_Cookie; { pObj->ioctl_if_type = INT_MAIN; pObj->ioctl_if = MAIN_MBSSID; @@ -1588,13 +1680,16 @@ rt_ioctl_setparam(struct net_device *dev if ((value = rtstrchr(this_char, '=')) != NULL) *value++ = 0; - if (!value) + if (!value && (strcmp(this_char, "SiteSurvey") != 0)) return -EINVAL; + else + goto SET_PROC; // reject setting nothing besides ANY ssid(ssidLen=0) if (!*value && (strcmp(this_char, "SSID") != 0)) return -EINVAL; +SET_PROC: for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++) { if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0) @@ -1622,7 +1717,9 @@ rt_private_get_statistics(struct net_dev struct iw_point *wrq, char *extra) { INT Status = 0; - PRTMP_ADAPTER pAd = dev->ml_priv; + PRTMP_ADAPTER pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, dev); if (extra == NULL) { @@ -1655,6 +1752,8 @@ rt_private_get_statistics(struct net_dev } sprintf(extra+strlen(extra), "WpaSupplicantUP = %d\n\n", pAd->StaCfg.WpaSupplicantUP); + + wrq->length = strlen(extra) + 1; // 1: size of '\0' DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length)); @@ -1663,7 +1762,7 @@ rt_private_get_statistics(struct net_dev void getBaInfo( IN PRTMP_ADAPTER pAd, - IN PUCHAR pOutBuf) + IN PSTRING pOutBuf) { INT i, j; BA_ORI_ENTRY *pOriBAEntry; @@ -1710,13 +1809,16 @@ void getBaInfo( static int rt_private_show(struct net_device *dev, struct iw_request_info *info, - struct iw_point *wrq, char *extra) + struct iw_point *wrq, PSTRING extra) { INT Status = 0; - PRTMP_ADAPTER pAd = dev->ml_priv; - POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + PRTMP_ADAPTER pAd; + POS_COOKIE pObj; u32 subcmd = wrq->flags; + GET_PAD_FROM_NET_DEV(pAd, dev); + + pObj = (POS_COOKIE) pAd->OS_Cookie; if (extra == NULL) { wrq->length = 0; @@ -1785,9 +1887,11 @@ rt_private_show(struct net_device *dev, case RAIO_OFF: if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { - sprintf(extra, "Scanning\n"); - wrq->length = strlen(extra) + 1; // 1: size of '\0' - break; + if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) + { + RTMP_MLME_RESET_STATE_MACHINE(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n")); + } } pAd->StaCfg.bSwRadio = FALSE; if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) @@ -1804,14 +1908,6 @@ rt_private_show(struct net_device *dev, wrq->length = strlen(extra) + 1; // 1: size of '\0' break; case RAIO_ON: -#ifdef RT2870 - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) - { - sprintf(extra, "Scanning\n"); - wrq->length = strlen(extra) + 1; // 1: size of '\0' - break; - } -#endif pAd->StaCfg.bSwRadio = TRUE; //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) { @@ -1827,13 +1923,19 @@ rt_private_show(struct net_device *dev, wrq->length = strlen(extra) + 1; // 1: size of '\0' break; + + case SHOW_CFG_VALUE: { - Status = RTMPShowCfgValue(pAd, wrq->pointer, extra); + Status = RTMPShowCfgValue(pAd, (PSTRING) wrq->pointer, extra); if (Status == 0) wrq->length = strlen(extra) + 1; // 1: size of '\0' } break; + case SHOW_ADHOC_ENTRY_INFO: + Show_Adhoc_MacTable_Proc(pAd, extra); + wrq->length = strlen(extra) + 1; // 1: size of '\0' + break; default: DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __func__, subcmd)); break; @@ -1847,12 +1949,14 @@ int rt_ioctl_siwmlme(struct net_device * union iwreq_data *wrqu, char *extra) { - PRTMP_ADAPTER pAd = dev->ml_priv; + PRTMP_ADAPTER pAd = NULL; struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer; MLME_QUEUE_ELEM MsgElem; MLME_DISASSOC_REQ_STRUCT DisAssocReq; MLME_DEAUTH_REQ_STRUCT DeAuthReq; + GET_PAD_FROM_NET_DEV(pAd, dev); + DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __func__)); if (pMlme == NULL) @@ -1902,9 +2006,11 @@ int rt_ioctl_siwauth(struct net_device * struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; struct iw_param *param = &wrqu->param; + GET_PAD_FROM_NET_DEV(pAdapter, dev); + //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { @@ -1992,6 +2098,7 @@ int rt_ioctl_siwauth(struct net_device * } else if (param->value == 0) { + //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; STA_PORT_SECURED(pAdapter); } DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __func__, param->value)); @@ -1999,6 +2106,14 @@ int rt_ioctl_siwauth(struct net_device * case IW_AUTH_RX_UNENCRYPTED_EAPOL: break; case IW_AUTH_PRIVACY_INVOKED: + /*if (param->value == 0) + { + pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen; + pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled; + pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus; + pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled; + pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled; + }*/ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __func__, param->value)); break; case IW_AUTH_DROP_UNENCRYPTED: @@ -2006,6 +2121,7 @@ int rt_ioctl_siwauth(struct net_device * pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; else { + //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; STA_PORT_SECURED(pAdapter); } DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __func__, param->value)); @@ -2037,9 +2153,11 @@ int rt_ioctl_giwauth(struct net_device * struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; struct iw_param *param = &wrqu->param; + GET_PAD_FROM_NET_DEV(pAdapter, dev); + //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { @@ -2074,21 +2192,6 @@ void fnSetCipherKey( IN BOOLEAN bGTK, IN struct iw_encode_ext *ext) { -#ifdef RT2860 - RTMP_CLEAR_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP); - if (RTMP_TEST_PSFLAG(pAdapter, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)) - { - if (pAdapter->StaCfg.bRadio == FALSE) - { - RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP); - return; - } - DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n")); - RTMPPCIeLinkCtrlValueRestore(pAdapter, RESTORE_HALT); - RTMPusecDelay(6000); - pAdapter->bPCIclkOff = FALSE; - } -#endif NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY)); pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK; NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK); @@ -2119,9 +2222,6 @@ void fnSetCipherKey( keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, &pAdapter->MacTab.Content[BSSID_WCID]); -#ifdef RT2860 - RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP); -#endif } int rt_ioctl_siwencodeext(struct net_device *dev, @@ -2129,11 +2229,13 @@ int rt_ioctl_siwencodeext(struct net_dev union iwreq_data *wrqu, char *extra) { - PRTMP_ADAPTER pAdapter = dev->ml_priv; + PRTMP_ADAPTER pAdapter = NULL; struct iw_point *encoding = &wrqu->encoding; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int keyIdx, alg = ext->alg; + GET_PAD_FROM_NET_DEV(pAdapter, dev); + //check if the interface is down if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { @@ -2210,7 +2312,9 @@ int rt_ioctl_siwencodeext(struct net_dev fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext); if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2) { + //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; STA_PORT_SECURED(pAdapter); + pAdapter->IndicateMediaState = NdisMediaStateConnected; } } else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) @@ -2218,7 +2322,9 @@ int rt_ioctl_siwencodeext(struct net_dev fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext); // set 802.1x port control + //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; STA_PORT_SECURED(pAdapter); + pAdapter->IndicateMediaState = NdisMediaStateConnected; } } else @@ -2229,14 +2335,18 @@ int rt_ioctl_siwencodeext(struct net_dev { fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext); if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2) + //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; STA_PORT_SECURED(pAdapter); + pAdapter->IndicateMediaState = NdisMediaStateConnected; } else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext); // set 802.1x port control + //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; STA_PORT_SECURED(pAdapter); + pAdapter->IndicateMediaState = NdisMediaStateConnected; } break; default: @@ -2252,12 +2362,14 @@ rt_ioctl_giwencodeext(struct net_device struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - PRTMP_ADAPTER pAd = dev->ml_priv; + PRTMP_ADAPTER pAd = NULL; PCHAR pKey = NULL; struct iw_point *encoding = &wrqu->encoding; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int idx, max_key_len; + GET_PAD_FROM_NET_DEV(pAd, dev); + DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n")); max_key_len = encoding->length - sizeof(*ext); @@ -2300,7 +2412,7 @@ rt_ioctl_giwencodeext(struct net_device else { ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen; - pKey = &(pAd->SharedKey[BSS0][idx].Key[0]); + pKey = (PCHAR)&(pAd->SharedKey[BSS0][idx].Key[0]); } break; case Ndis802_11Encryption2Enabled: @@ -2315,7 +2427,7 @@ rt_ioctl_giwencodeext(struct net_device else { ext->key_len = 32; - pKey = &pAd->StaCfg.PMK[0]; + pKey = (PCHAR)&pAd->StaCfg.PMK[0]; } break; default: @@ -2335,8 +2447,12 @@ int rt_ioctl_siwgenie(struct net_device struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - PRTMP_ADAPTER pAd = dev->ml_priv; + PRTMP_ADAPTER pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, dev); + DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwgenie\n")); + pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE; if (wrqu->data.length > MAX_LEN_OF_RSNIE || (wrqu->data.length && extra == NULL)) return -EINVAL; @@ -2345,6 +2461,7 @@ int rt_ioctl_siwgenie(struct net_device { pAd->StaCfg.RSNIE_Len = wrqu->data.length; NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len); + pAd->StaCfg.bRSN_IE_FromWpaSupplicant = TRUE; } else { @@ -2359,7 +2476,9 @@ int rt_ioctl_giwgenie(struct net_device struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - PRTMP_ADAPTER pAd = dev->ml_priv; + PRTMP_ADAPTER pAd = NULL; + + GET_PAD_FROM_NET_DEV(pAd, dev); if ((pAd->StaCfg.RSNIE_Len == 0) || (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)) @@ -2401,10 +2520,12 @@ int rt_ioctl_siwpmksa(struct net_device union iwreq_data *wrqu, char *extra) { - PRTMP_ADAPTER pAd = dev->ml_priv; + PRTMP_ADAPTER pAd = NULL; struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer; INT CachedIdx = 0, idx = 0; + GET_PAD_FROM_NET_DEV(pAd, dev); + if (pPmksa == NULL) return -EINVAL; @@ -2475,9 +2596,11 @@ int rt_ioctl_siwrate(struct net_device * struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - PRTMP_ADAPTER pAd = dev->ml_priv; + PRTMP_ADAPTER pAd = NULL; UINT32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed; + GET_PAD_FROM_NET_DEV(pAd, dev); + //check if the interface is down if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { @@ -2529,9 +2652,10 @@ int rt_ioctl_giwrate(struct net_device * struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - PRTMP_ADAPTER pAd = dev->ml_priv; + PRTMP_ADAPTER pAd = NULL; int rate_index = 0, rate_count = 0; HTTRANSMIT_SETTING ht_setting; +/* Remove to global variable __s32 ralinkrate[] = {2, 4, 11, 22, // CCK 12, 18, 24, 36, 48, 72, 96, 108, // OFDM @@ -2543,6 +2667,8 @@ int rt_ioctl_giwrate(struct net_device * 43, 87, 130, 173, 260, 317, 390, 433, // 20MHz, 400ns GI, MCS: 16 ~ 23 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15 90, 180, 270, 360, 540, 720, 810, 900}; // 40MHz, 400ns GI, MCS: 16 ~ 23 +*/ + GET_PAD_FROM_NET_DEV(pAd, dev); rate_count = sizeof(ralinkrate)/sizeof(__s32); //check if the interface is down @@ -2561,6 +2687,7 @@ int rt_ioctl_giwrate(struct net_device * if (ht_setting.field.MODE >= MODE_HTMIX) { +// rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS); rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS); } else @@ -2661,7 +2788,9 @@ static const iw_handler rt_priv_handlers (iw_handler) rt_private_show, /* + 0x11 */ (iw_handler) NULL, /* + 0x12 */ (iw_handler) NULL, /* + 0x13 */ + (iw_handler) NULL, /* + 0x14 */ (iw_handler) NULL, /* + 0x15 */ + (iw_handler) NULL, /* + 0x16 */ (iw_handler) NULL, /* + 0x17 */ (iw_handler) NULL, /* + 0x18 */ }; @@ -2685,12 +2814,16 @@ INT rt28xx_sta_ioctl( IN OUT struct ifreq *rq, IN INT cmd) { - RTMP_ADAPTER *pAd = net_dev->ml_priv; - POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; + POS_COOKIE pObj; + RTMP_ADAPTER *pAd = NULL; struct iwreq *wrq = (struct iwreq *) rq; BOOLEAN StateMachineTouched = FALSE; INT Status = NDIS_STATUS_SUCCESS; + GET_PAD_FROM_NET_DEV(pAd, net_dev); + + pObj = (POS_COOKIE) pAd->OS_Cookie; + //check if the interface is down if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) { @@ -2747,14 +2880,16 @@ INT rt28xx_sta_ioctl( } case SIOCSIWNICKN: //set node name/nickname { - struct iw_point *data=&wrq->u.data; - rt_ioctl_siwnickn(net_dev, NULL, data, NULL); + //struct iw_point *data=&wrq->u.data; + //rt_ioctl_siwnickn(net_dev, NULL, data, NULL); break; } case SIOCGIWNICKN: //get node name/nickname { - struct iw_point *data=&wrq->u.data; - rt_ioctl_giwnickn(net_dev, NULL, data, NULL); + struct iw_point *erq = NULL; + erq = &wrq->u.data; + erq->length = strlen((PSTRING) pAd->nickname); + Status = copy_to_user(erq->pointer, pAd->nickname, erq->length); break; } case SIOCGIWRATE: //get default bit rate (bps) @@ -2790,14 +2925,14 @@ INT rt28xx_sta_ioctl( case SIOCGIWENCODE: //get encoding token & mode { struct iw_point *erq=&wrq->u.encoding; - if(erq->pointer) + if(erq) rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer); break; } case SIOCSIWENCODE: //set encoding token & mode { struct iw_point *erq=&wrq->u.encoding; - if(erq->pointer) + if(erq) rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer); break; } @@ -2865,7 +3000,7 @@ INT rt28xx_sta_ioctl( } if(StateMachineTouched) // Upper layer sent a MLME-related operations - RT28XX_MLME_HANDLER(pAd); + RTMP_MLME_HANDLER(pAd); return Status; } @@ -2880,7 +3015,7 @@ INT rt28xx_sta_ioctl( */ INT Set_SSID_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + IN PSTRING arg) { NDIS_802_11_SSID Ssid, *pSsid=NULL; BOOLEAN StateMachineTouched = FALSE; @@ -2906,10 +3041,29 @@ INT Set_SSID_Proc( if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) { - RT28XX_MLME_RESET_STATE_MACHINE(pAdapter); + RTMP_MLME_RESET_STATE_MACHINE(pAdapter); DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n")); } + if ((pAdapter->StaCfg.WpaPassPhraseLen >= 8) && + (pAdapter->StaCfg.WpaPassPhraseLen <= 64)) + { + STRING passphrase_str[65] = {0}; + UCHAR keyMaterial[40]; + + RTMPMoveMemory(passphrase_str, pAdapter->StaCfg.WpaPassPhrase, pAdapter->StaCfg.WpaPassPhraseLen); + RTMPZeroMemory(pAdapter->StaCfg.PMK, 32); + if (pAdapter->StaCfg.WpaPassPhraseLen == 64) + { + AtoH((PSTRING) pAdapter->StaCfg.WpaPassPhrase, pAdapter->StaCfg.PMK, 32); + } + else + { + PasswordHash((PSTRING) pAdapter->StaCfg.WpaPassPhrase, Ssid.Ssid, Ssid.SsidLength, keyMaterial); + NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32); + } + } + pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE; pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE; pAdapter->bConfigChanged = TRUE; @@ -2927,7 +3081,7 @@ INT Set_SSID_Proc( success = FALSE; if (StateMachineTouched) // Upper layer sent a MLME-related operations - RT28XX_MLME_HANDLER(pAdapter); + RTMP_MLME_HANDLER(pAdapter); return success; } @@ -2943,16 +3097,16 @@ INT Set_SSID_Proc( */ INT Set_WmmCapable_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { BOOLEAN bWmmCapable; bWmmCapable = simple_strtol(arg, 0, 10); if ((bWmmCapable == 1) -#ifdef RT2870 +#ifdef RTMP_MAC_USB && (pAd->NumberOfPipes >= 5) -#endif // RT2870 // +#endif // RTMP_MAC_USB // ) pAd->CommonCfg.bWmmCapable = TRUE; else if (bWmmCapable == 0) @@ -2977,7 +3131,7 @@ INT Set_WmmCapable_Proc( */ INT Set_NetworkType_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + IN PSTRING arg) { UINT32 Value = 0; @@ -3043,8 +3197,6 @@ INT Set_NetworkType_Proc( pAdapter->StaCfg.BssType = BSS_INFRA; pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType; DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n")); - - pAdapter->StaCfg.BssType = BSS_INFRA; } else if (strcmp(arg, "Monitor") == 0) { @@ -3056,7 +3208,7 @@ INT Set_NetworkType_Proc( // disable all periodic state machine pAdapter->StaCfg.bAutoReconnect = FALSE; // reset all mlme state machine - RT28XX_MLME_RESET_STATE_MACHINE(pAdapter); + RTMP_MLME_RESET_STATE_MACHINE(pAdapter); DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n")); if (pAdapter->CommonCfg.CentralChannel == 0) { @@ -3164,7 +3316,7 @@ INT Set_NetworkType_Proc( */ INT Set_AuthMode_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + IN PSTRING arg) { if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0)) pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch; @@ -3202,7 +3354,7 @@ INT Set_AuthMode_Proc( */ INT Set_EncrypType_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + IN PSTRING arg) { if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0)) { @@ -3260,7 +3412,7 @@ INT Set_EncrypType_Proc( */ INT Set_DefaultKeyID_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + IN PSTRING arg) { ULONG KeyIdx; @@ -3285,7 +3437,7 @@ INT Set_DefaultKeyID_Proc( */ INT Set_Key1_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + IN PSTRING arg) { int KeyLen; int i; @@ -3366,7 +3518,7 @@ INT Set_Key1_Proc( */ INT Set_Key2_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + IN PSTRING arg) { int KeyLen; int i; @@ -3445,7 +3597,7 @@ INT Set_Key2_Proc( */ INT Set_Key3_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + IN PSTRING arg) { int KeyLen; int i; @@ -3524,7 +3676,7 @@ INT Set_Key3_Proc( */ INT Set_Key4_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + IN PSTRING arg) { int KeyLen; int i; @@ -3603,50 +3755,40 @@ INT Set_Key4_Proc( ========================================================================== */ INT Set_WPAPSK_Proc( - IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) { - UCHAR keyMaterial[40]; + int status; - if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) && - (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) && - (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) + if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) && + (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) && + (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) ) return TRUE; // do nothing DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg)); - NdisZeroMemory(keyMaterial, 40); - - if ((strlen(arg) < 8) || (strlen(arg) > 64)) + status = RT_CfgSetWPAPSKKey(pAd, arg, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, pAd->StaCfg.PMK); + if (status == FALSE) { - DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg)); + DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc(): Set key failed!\n")); return FALSE; } + NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64); + NdisMoveMemory(pAd->StaCfg.WpaPassPhrase, arg, strlen(arg)); + pAd->StaCfg.WpaPassPhraseLen = (UINT)strlen(arg); - if (strlen(arg) == 64) - { - AtoH(arg, keyMaterial, 32); - NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32); - } - else - { - PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial); - NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32); - } - - - if(pAdapter->StaCfg.BssType == BSS_ADHOC && - pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) + if(pAd->StaCfg.BssType == BSS_ADHOC && + pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) { - pAdapter->StaCfg.WpaState = SS_NOTUSE; + pAd->StaCfg.WpaState = SS_NOTUSE; } else { // Start STA supplicant state machine - pAdapter->StaCfg.WpaState = SS_START; + pAd->StaCfg.WpaState = SS_START; } return TRUE; @@ -3662,7 +3804,7 @@ INT Set_WPAPSK_Proc( */ INT Set_PSMode_Proc( IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + IN PSTRING arg) { if (pAdapter->StaCfg.BssType == BSS_INFRA) { @@ -3670,7 +3812,7 @@ INT Set_PSMode_Proc( (strcmp(arg, "max_psp") == 0) || (strcmp(arg, "MAX_PSP") == 0)) { - // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange() + // do NOT turn on PSM bit here, wait until MlmeCheckPsmChange() // to exclude certain situations. if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE) pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP; @@ -3683,7 +3825,7 @@ INT Set_PSMode_Proc( (strcmp(arg, "fast_psp") == 0) || (strcmp(arg, "FAST_PSP") == 0)) { - // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange() + // do NOT turn on PSM bit here, wait until MlmeCheckPsmChange() // to exclude certain situations. OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM); if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE) @@ -3695,7 +3837,7 @@ INT Set_PSMode_Proc( (strcmp(arg, "legacy_psp") == 0) || (strcmp(arg, "LEGACY_PSP") == 0)) { - // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange() + // do NOT turn on PSM bit here, wait until MlmeCheckPsmChange() // to exclude certain situations. OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM); if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE) @@ -3707,7 +3849,7 @@ INT Set_PSMode_Proc( { //Default Ndis802_11PowerModeCAM // clear PSM bit immediately - MlmeSetPsmBit(pAdapter, PWR_ACTIVE); + RTMP_SET_PSM_BIT(pAdapter, PWR_ACTIVE); OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM); if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE) pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM; @@ -3737,7 +3879,7 @@ INT Set_PSMode_Proc( */ INT Set_Wpa_Support( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { if ( simple_strtol(arg, 0, 10) == 0) @@ -3756,7 +3898,7 @@ INT Set_Wpa_Support( INT Set_TGnWifiTest_Proc( IN PRTMP_ADAPTER pAd, - IN PUCHAR arg) + IN PSTRING arg) { if (simple_strtol(arg, 0, 10) == 0) pAd->StaCfg.bTGnWifiTest = FALSE; @@ -3767,30 +3909,161 @@ INT Set_TGnWifiTest_Proc( return TRUE; } -INT Set_LongRetryLimit_Proc( - IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + + + +INT Show_Adhoc_MacTable_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING extra) { - TX_RTY_CFG_STRUC tx_rty_cfg; - UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10); + INT i; + + sprintf(extra, "\n"); + + sprintf(extra + strlen(extra), "HT Operating Mode : %d\n", pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode); + + sprintf(extra + strlen(extra), "\n%-19s%-4s%-4s%-7s%-7s%-7s%-10s%-6s%-6s%-6s%-6s\n", + "MAC", "AID", "BSS", "RSSI0", "RSSI1", "RSSI2", "PhMd", "BW", "MCS", "SGI", "STBC"); + + for (i=1; iMacTab.Content[i]; + + if (strlen(extra) > (IW_PRIV_SIZE_MASK - 30)) + break; + if ((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC)) + { + sprintf(extra + strlen(extra), "%02X:%02X:%02X:%02X:%02X:%02X ", + pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], + pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]); + sprintf(extra + strlen(extra), "%-4d", (int)pEntry->Aid); + sprintf(extra + strlen(extra), "%-4d", (int)pEntry->apidx); + sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi0); + sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi1); + sprintf(extra + strlen(extra), "%-7d", pEntry->RssiSample.AvgRssi2); + sprintf(extra + strlen(extra), "%-10s", GetPhyMode(pEntry->HTPhyMode.field.MODE)); + sprintf(extra + strlen(extra), "%-6s", GetBW(pEntry->HTPhyMode.field.BW)); + sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.MCS); + sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.ShortGI); + sprintf(extra + strlen(extra), "%-6d", pEntry->HTPhyMode.field.STBC); + sprintf(extra + strlen(extra), "%-10d, %d, %d%%\n", pEntry->DebugFIFOCount, pEntry->DebugTxCount, + (pEntry->DebugTxCount) ? ((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount) : 0); + sprintf(extra, "%s\n", extra); + } + } - RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word); - tx_rty_cfg.field.LongRtyLimit = LongRetryLimit; - RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word); - DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word)); return TRUE; } -INT Set_ShortRetryLimit_Proc( - IN PRTMP_ADAPTER pAdapter, - IN PUCHAR arg) + +INT Set_BeaconLostTime_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + ULONG ltmp = (ULONG)simple_strtol(arg, 0, 10); + + if ((ltmp != 0) && (ltmp <= 60)) + pAd->StaCfg.BeaconLostTime = (ltmp * OS_HZ); + + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_BeaconLostTime_Proc::(BeaconLostTime=%ld)\n", pAd->StaCfg.BeaconLostTime)); + return TRUE; +} + +INT Set_AutoRoaming_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) { - TX_RTY_CFG_STRUC tx_rty_cfg; - UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10); + if (simple_strtol(arg, 0, 10) == 0) + pAd->StaCfg.bAutoRoaming = FALSE; + else + pAd->StaCfg.bAutoRoaming = TRUE; + + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_AutoRoaming_Proc::(bAutoRoaming=%d)\n", pAd->StaCfg.bAutoRoaming)); + return TRUE; +} + + +/* + ========================================================================== + Description: + Issue a site survey command to driver + Arguments: + pAdapter Pointer to our adapter + wrq Pointer to the ioctl argument + + Return Value: + None + + Note: + Usage: + 1.) iwpriv ra0 set site_survey + ========================================================================== +*/ +INT Set_SiteSurvey_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + NDIS_802_11_SSID Ssid; + + //check if the interface is down + if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) + { + DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n")); + return -ENETDOWN; + } + + if (MONITOR_ON(pAd)) + { + DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n")); + return -EINVAL; + } + + RTMPZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID)); + Ssid.SsidLength = 0; + if ((arg != NULL) && + (strlen(arg) <= MAX_LEN_OF_SSID)) + { + RTMPMoveMemory(Ssid.Ssid, arg, strlen(arg)); + Ssid.SsidLength = strlen(arg); + } + + pAd->StaCfg.bScanReqIsFromWebUI = TRUE; + + if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) + { + RTMP_MLME_RESET_STATE_MACHINE(pAd); + DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n")); + } + + // tell CNTL state machine to call NdisMSetInformationComplete() after completing + // this request, because this request is initiated by NDIS. + pAd->MlmeAux.CurrReqIsFromNdis = FALSE; + // Reset allowed scan retries + pAd->StaCfg.ScanCnt = 0; + NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime); + + MlmeEnqueue(pAd, + MLME_CNTL_STATE_MACHINE, + OID_802_11_BSSID_LIST_SCAN, + Ssid.SsidLength, + Ssid.Ssid); + + RTMP_MLME_HANDLER(pAd); + + DBGPRINT(RT_DEBUG_TRACE, ("Set_SiteSurvey_Proc\n")); + + return TRUE; +} + +INT Set_ForceTxBurst_Proc( + IN PRTMP_ADAPTER pAd, + IN PSTRING arg) +{ + if (simple_strtol(arg, 0, 10) == 0) + pAd->StaCfg.bForceTxBurst = FALSE; + else + pAd->StaCfg.bForceTxBurst = TRUE; - RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word); - tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit; - RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word); - DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word)); + DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ForceTxBurst_Proc::(bForceTxBurst=%d)\n", pAd->StaCfg.bForceTxBurst)); return TRUE; } Index: b/drivers/staging/rt2860/usb_main_dev.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2860/usb_main_dev.c @@ -0,0 +1,897 @@ +/* + ************************************************************************* + * Ralink Tech Inc. + * 5F., No.36, Taiyuan St., Jhubei City, + * Hsinchu County 302, + * Taiwan, R.O.C. + * + * (c) Copyright 2002-2007, Ralink Technology, Inc. + * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * * + *************************************************************************/ + +#include "rt_config.h" + + +// Following information will be show when you run 'modinfo' +// *** If you have a solution for the bug in current version of driver, please mail to me. +// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. *** +MODULE_AUTHOR("Paul Lin "); +MODULE_DESCRIPTION("RT2870/RT3070 Wireless Lan Linux Driver"); +MODULE_LICENSE("GPL"); +#ifdef MODULE_VERSION +MODULE_VERSION(STA_DRIVER_VERSION); +#endif + + +/* module table */ +struct usb_device_id rtusb_usb_id[] = { +#ifdef RT2870 + {USB_DEVICE(0x148F,0x2770)}, /* Ralink */ + {USB_DEVICE(0x148F,0x2870)}, /* Ralink */ + {USB_DEVICE(0x07B8,0x2870)}, /* AboCom */ + {USB_DEVICE(0x07B8,0x2770)}, /* AboCom */ + {USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom 2770 */ + {USB_DEVICE(0x083A,0x7512)}, /* Arcadyan 2770 */ + {USB_DEVICE(0x0789,0x0162)}, /* Logitec 2870 */ + {USB_DEVICE(0x0789,0x0163)}, /* Logitec 2870 */ + {USB_DEVICE(0x0789,0x0164)}, /* Logitec 2870 */ + {USB_DEVICE(0x177f,0x0302)}, /* lsusb */ + {USB_DEVICE(0x0B05,0x1731)}, /* Asus */ + {USB_DEVICE(0x0B05,0x1732)}, /* Asus */ + {USB_DEVICE(0x0B05,0x1742)}, /* Asus */ + {USB_DEVICE(0x0DF6,0x0017)}, /* Sitecom */ + {USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */ + {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ + {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ + {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ + {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ + {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ + {USB_DEVICE(0x07D1,0x3C09)}, /* D-Link */ + {USB_DEVICE(0x07D1,0x3C11)}, /* D-Link */ + {USB_DEVICE(0x14B2,0x3C07)}, /* AL */ + {USB_DEVICE(0x050D,0x8053)}, /* Belkin */ + {USB_DEVICE(0x14B2,0x3C23)}, /* Airlink */ + {USB_DEVICE(0x14B2,0x3C27)}, /* Airlink */ + {USB_DEVICE(0x07AA,0x002F)}, /* Corega */ + {USB_DEVICE(0x07AA,0x003C)}, /* Corega */ + {USB_DEVICE(0x07AA,0x003F)}, /* Corega */ + {USB_DEVICE(0x1044,0x800B)}, /* Gigabyte */ + {USB_DEVICE(0x15A9,0x0006)}, /* Sparklan */ + {USB_DEVICE(0x083A,0xB522)}, /* SMC */ + {USB_DEVICE(0x083A,0xA618)}, /* SMC */ + {USB_DEVICE(0x083A,0x8522)}, /* Arcadyan */ + {USB_DEVICE(0x083A,0x7522)}, /* Arcadyan */ + {USB_DEVICE(0x0CDE,0x0022)}, /* ZCOM */ + {USB_DEVICE(0x0586,0x3416)}, /* Zyxel */ + {USB_DEVICE(0x0CDE,0x0025)}, /* Zyxel */ + {USB_DEVICE(0x1740,0x9701)}, /* EnGenius */ + {USB_DEVICE(0x1740,0x9702)}, /* EnGenius */ + {USB_DEVICE(0x0471,0x200f)}, /* Philips */ + {USB_DEVICE(0x14B2,0x3C25)}, /* Draytek */ + {USB_DEVICE(0x13D3,0x3247)}, /* AzureWave */ + {USB_DEVICE(0x083A,0x6618)}, /* Accton */ + {USB_DEVICE(0x15c5,0x0008)}, /* Amit */ + {USB_DEVICE(0x0E66,0x0001)}, /* Hawking */ + {USB_DEVICE(0x0E66,0x0003)}, /* Hawking */ + {USB_DEVICE(0x129B,0x1828)}, /* Siemens */ + {USB_DEVICE(0x157E,0x300E)}, /* U-Media */ + {USB_DEVICE(0x050d,0x805c)}, + {USB_DEVICE(0x050d,0x815c)}, + {USB_DEVICE(0x1482,0x3C09)}, /* Abocom*/ + {USB_DEVICE(0x14B2,0x3C09)}, /* Alpha */ + {USB_DEVICE(0x04E8,0x2018)}, /* samsung */ + {USB_DEVICE(0x5A57,0x0280)}, /* Zinwell */ + {USB_DEVICE(0x5A57,0x0282)}, /* Zinwell */ + {USB_DEVICE(0x7392,0x7718)}, + {USB_DEVICE(0x7392,0x7717)}, + {USB_DEVICE(0x1737,0x0070)}, /* Linksys WUSB100 */ + {USB_DEVICE(0x1737,0x0071)}, /* Linksys WUSB600N */ + {USB_DEVICE(0x0411,0x00e8)}, /* Buffalo WLI-UC-G300N*/ + {USB_DEVICE(0x050d,0x815c)}, /* Belkin F5D8053 */ +#endif // RT2870 // +#ifdef RT3070 + {USB_DEVICE(0x148F,0x3070)}, /* Ralink 3070 */ + {USB_DEVICE(0x148F,0x3071)}, /* Ralink 3071 */ + {USB_DEVICE(0x148F,0x3072)}, /* Ralink 3072 */ + {USB_DEVICE(0x0DB0,0x3820)}, /* Ralink 3070 */ + {USB_DEVICE(0x0DF6,0x003E)}, /* Sitecom 3070 */ + {USB_DEVICE(0x0DF6,0x0042)}, /* Sitecom 3072 */ + {USB_DEVICE(0x14B2,0x3C12)}, /* AL 3070 */ + {USB_DEVICE(0x18C5,0x0012)}, /* Corega 3070 */ + {USB_DEVICE(0x083A,0x7511)}, /* Arcadyan 3070 */ + {USB_DEVICE(0x1740,0x9703)}, /* EnGenius 3070 */ + {USB_DEVICE(0x1740,0x9705)}, /* EnGenius 3071 */ + {USB_DEVICE(0x1740,0x9706)}, /* EnGenius 3072 */ + {USB_DEVICE(0x13D3,0x3273)}, /* AzureWave 3070*/ + {USB_DEVICE(0x1044,0x800D)}, /* Gigabyte GN-WB32L 3070 */ + {USB_DEVICE(0x2019,0xAB25)}, /* Planex Communications, Inc. RT3070 */ + {USB_DEVICE(0x07B8,0x3070)}, /* AboCom 3070 */ + {USB_DEVICE(0x07B8,0x3071)}, /* AboCom 3071 */ + {USB_DEVICE(0x07B8,0x3072)}, /* Abocom 3072 */ + {USB_DEVICE(0x7392,0x7711)}, /* Edimax 3070 */ + {USB_DEVICE(0x1A32,0x0304)}, /* Quanta 3070 */ + {USB_DEVICE(0x1EDA,0x2310)}, /* AirTies 3070 */ + {USB_DEVICE(0x07D1,0x3C0A)}, /* D-Link 3072 */ + {USB_DEVICE(0x07D1,0x3C0D)}, /* D-Link 3070 */ + {USB_DEVICE(0x07D1,0x3C0E)}, /* D-Link 3070 */ + {USB_DEVICE(0x07D1,0x3C0F)}, /* D-Link 3070 */ + {USB_DEVICE(0x1D4D,0x000C)}, /* Pegatron Corporation 3070 */ + {USB_DEVICE(0x1D4D,0x000E)}, /* Pegatron Corporation 3070 */ + {USB_DEVICE(0x5A57,0x5257)}, /* Zinwell 3070 */ + {USB_DEVICE(0x5A57,0x0283)}, /* Zinwell 3072 */ + {USB_DEVICE(0x04BB,0x0945)}, /* I-O DATA 3072 */ + {USB_DEVICE(0x203D,0x1480)}, /* Encore 3070 */ +#endif // RT3070 // + { USB_DEVICE(0x0DF6, 0x003F) }, /* Sitecom WL-608 */ + { USB_DEVICE(0x1737, 0x0077) }, /* Linksys WUSB54GC-EU v3 */ + { USB_DEVICE(0x2001, 0x3C09) }, /* D-Link */ + { USB_DEVICE(0x2001, 0x3C0A) }, /* D-Link 3072*/ + { USB_DEVICE(0x2019, 0xED14) }, /* Planex Communications, Inc. */ + { }/* Terminating entry */ +}; + +INT const rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id); + +MODULE_DEVICE_TABLE(usb, rtusb_usb_id); + +static void rt2870_disconnect( + IN struct usb_device *dev, + IN PRTMP_ADAPTER pAd); + +static int __devinit rt2870_probe( + IN struct usb_interface *intf, + IN struct usb_device *usb_dev, + IN const struct usb_device_id *dev_id, + IN RTMP_ADAPTER **ppAd); + +#ifndef PF_NOFREEZE +#define PF_NOFREEZE 0 +#endif + + +extern int rt28xx_close(IN struct net_device *net_dev); +extern int rt28xx_open(struct net_device *net_dev); + +static BOOLEAN USBDevConfigInit( + IN struct usb_device *dev, + IN struct usb_interface *intf, + IN RTMP_ADAPTER *pAd); + + +/* +======================================================================== +Routine Description: + Check the chipset vendor/product ID. + +Arguments: + _dev_p Point to the PCI or USB device + +Return Value: + TRUE Check ok + FALSE Check fail + +Note: +======================================================================== +*/ +BOOLEAN RT28XXChipsetCheck( + IN void *_dev_p) +{ + struct usb_interface *intf = (struct usb_interface *)_dev_p; + struct usb_device *dev_p = interface_to_usbdev(intf); + UINT32 i; + + + for(i=0; idescriptor.idVendor == rtusb_usb_id[i].idVendor && + dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct) + { + printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n", + dev_p->descriptor.idVendor, dev_p->descriptor.idProduct); + break; + } + } + + if (i == rtusb_usb_id_len) + { + printk("rt2870: Error! Device Descriptor not matching!\n"); + return FALSE; + } + + return TRUE; +} + +/**************************************************************************/ +/**************************************************************************/ +//tested for kernel 2.6series +/**************************************************************************/ +/**************************************************************************/ + +#ifdef CONFIG_PM +static int rt2870_suspend(struct usb_interface *intf, pm_message_t state); +static int rt2870_resume(struct usb_interface *intf); +#endif // CONFIG_PM // + +static int rtusb_probe (struct usb_interface *intf, + const struct usb_device_id *id); +static void rtusb_disconnect(struct usb_interface *intf); + +static BOOLEAN USBDevConfigInit( + IN struct usb_device *dev, + IN struct usb_interface *intf, + IN RTMP_ADAPTER *pAd) +{ + struct usb_host_interface *iface_desc; + ULONG BulkOutIdx; + UINT32 i; + + + /* get the active interface descriptor */ + iface_desc = intf->cur_altsetting; + + /* get # of enpoints */ + pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints; + DBGPRINT(RT_DEBUG_TRACE, ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints)); + + /* Configure Pipes */ + BulkOutIdx = 0; + + for(i=0; iNumberOfPipes; i++) + { + if ((iface_desc->endpoint[i].desc.bmAttributes == + USB_ENDPOINT_XFER_BULK) && + ((iface_desc->endpoint[i].desc.bEndpointAddress & + USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)) + { + pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress; + pAd->BulkInMaxPacketSize = le2cpu16(iface_desc->endpoint[i].desc.wMaxPacketSize); + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("BULK IN MaxPacketSize = %d\n", pAd->BulkInMaxPacketSize)); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress)); + } + else if ((iface_desc->endpoint[i].desc.bmAttributes == + USB_ENDPOINT_XFER_BULK) && + ((iface_desc->endpoint[i].desc.bEndpointAddress & + USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)) + { + // there are 6 bulk out EP. EP6 highest priority. + // EP1-4 is EDCA. EP5 is HCCA. + pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress; + pAd->BulkOutMaxPacketSize = le2cpu16(iface_desc->endpoint[i].desc.wMaxPacketSize); + + DBGPRINT_RAW(RT_DEBUG_TRACE, ("BULK OUT MaxPacketSize = %d\n", pAd->BulkOutMaxPacketSize)); + DBGPRINT_RAW(RT_DEBUG_TRACE, ("EP address = 0x%2x \n", iface_desc->endpoint[i].desc.bEndpointAddress)); + } + } + + if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0])) + { + printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __FUNCTION__); + return FALSE; + } + + pAd->config = &dev->config->desc; + usb_set_intfdata(intf, pAd); + + return TRUE; + +} + + + +static int rtusb_probe (struct usb_interface *intf, + const struct usb_device_id *id) +{ + RTMP_ADAPTER *pAd; + struct usb_device *dev; + int rv; + + dev = interface_to_usbdev(intf); + dev = usb_get_dev(dev); + + rv = rt2870_probe(intf, dev, id, &pAd); + if (rv != 0) + usb_put_dev(dev); + + return rv; +} + + +static void rtusb_disconnect(struct usb_interface *intf) +{ + struct usb_device *dev = interface_to_usbdev(intf); + PRTMP_ADAPTER pAd; + + + pAd = usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); + + rt2870_disconnect(dev, pAd); +} + + +struct usb_driver rtusb_driver = { + .name="rt2870", + .probe=rtusb_probe, + .disconnect=rtusb_disconnect, + .id_table=rtusb_usb_id, + +#ifdef CONFIG_PM + suspend: rt2870_suspend, + resume: rt2870_resume, +#endif + }; + +#ifdef CONFIG_PM + +VOID RT2870RejectPendingPackets( + IN PRTMP_ADAPTER pAd) +{ + // clear PS packets + // clear TxSw packets +} + +static int rt2870_suspend( + struct usb_interface *intf, + pm_message_t state) +{ + struct net_device *net_dev; + PRTMP_ADAPTER pAd = usb_get_intfdata(intf); + + + DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n")); + net_dev = pAd->net_dev; + netif_device_detach(net_dev); + + pAd->PM_FlgSuspend = 1; + if (netif_running(net_dev)) { + RTUSBCancelPendingBulkInIRP(pAd); + RTUSBCancelPendingBulkOutIRP(pAd); + } + DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n")); + return 0; +} + +static int rt2870_resume( + struct usb_interface *intf) +{ + struct net_device *net_dev; + PRTMP_ADAPTER pAd = usb_get_intfdata(intf); + + + DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n")); + + pAd->PM_FlgSuspend = 0; + net_dev = pAd->net_dev; + netif_device_attach(net_dev); + netif_start_queue(net_dev); + netif_carrier_on(net_dev); + netif_wake_queue(net_dev); + + DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n")); + return 0; +} +#endif // CONFIG_PM // + +// Init driver module +INT __init rtusb_init(void) +{ + printk("rtusb init --->\n"); + return usb_register(&rtusb_driver); +} + +// Deinit driver module +VOID __exit rtusb_exit(void) +{ + usb_deregister(&rtusb_driver); + printk("<--- rtusb exit\n"); +} + +module_init(rtusb_init); +module_exit(rtusb_exit); + + + + +/*--------------------------------------------------------------------- */ +/* function declarations */ +/*--------------------------------------------------------------------- */ + +/* +======================================================================== +Routine Description: + MLME kernel thread. + +Arguments: + *Context the pAd, driver control block pointer + +Return Value: + 0 close the thread + +Note: +======================================================================== +*/ +INT MlmeThread( + IN void *Context) +{ + RTMP_ADAPTER *pAd; + RTMP_OS_TASK *pTask; + int status; + status = 0; + + pTask = (RTMP_OS_TASK *)Context; + pAd = (PRTMP_ADAPTER)pTask->priv; + + RtmpOSTaskCustomize(pTask); + + while(!pTask->task_killed) + { +#ifdef KTHREAD_SUPPORT + RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); +#else + RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); + + /* unlock the device pointers */ + if (status != 0) + { + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + break; + } +#endif + + /* lock the device pointers , need to check if required*/ + //down(&(pAd->usbdev_semaphore)); + + if (!pAd->PM_FlgSuspend) + MlmeHandler(pAd); + } + + /* notify the exit routine that we're actually exiting now + * + * complete()/wait_for_completion() is similar to up()/down(), + * except that complete() is safe in the case where the structure + * is getting deleted in a parallel mode of execution (i.e. just + * after the down() -- that's necessary for the thread-shutdown + * case. + * + * complete_and_exit() goes even further than this -- it is safe in + * the case that the thread of the caller is going away (not just + * the structure) -- this is necessary for the module-remove case. + * This is important in preemption kernels, which transfer the flow + * of execution immediately upon a complete(). + */ + DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__)); +#ifndef KTHREAD_SUPPORT + pTask->taskPID = THREAD_PID_INIT_VALUE; + complete_and_exit (&pTask->taskComplete, 0); +#endif + return 0; + +} + + +/* +======================================================================== +Routine Description: + USB command kernel thread. + +Arguments: + *Context the pAd, driver control block pointer + +Return Value: + 0 close the thread + +Note: +======================================================================== +*/ +INT RTUSBCmdThread( + IN void * Context) +{ + RTMP_ADAPTER *pAd; + RTMP_OS_TASK *pTask; + int status; + status = 0; + + pTask = (RTMP_OS_TASK *)Context; + pAd = (PRTMP_ADAPTER)pTask->priv; + + RtmpOSTaskCustomize(pTask); + + NdisAcquireSpinLock(&pAd->CmdQLock); + pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING; + NdisReleaseSpinLock(&pAd->CmdQLock); + + while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING) + { +#ifdef KTHREAD_SUPPORT + RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask); +#else + /* lock the device pointers */ + RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status); + + if (status != 0) + { + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); + break; + } +#endif + + if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED) + break; + + if (!pAd->PM_FlgSuspend) + CMDHandler(pAd); + } + + if (pAd && !pAd->PM_FlgSuspend) + { // Clear the CmdQElements. + CmdQElmt *pCmdQElmt = NULL; + + NdisAcquireSpinLock(&pAd->CmdQLock); + pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED; + while(pAd->CmdQ.size) + { + RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt); + if (pCmdQElmt) + { + if (pCmdQElmt->CmdFromNdis == TRUE) + { + if (pCmdQElmt->buffer != NULL) + os_free_mem(pAd, pCmdQElmt->buffer); + os_free_mem(pAd, (PUCHAR)pCmdQElmt); + } + else + { + if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0)) + os_free_mem(pAd, pCmdQElmt->buffer); + os_free_mem(pAd, (PUCHAR)pCmdQElmt); + } + } + } + + NdisReleaseSpinLock(&pAd->CmdQLock); + } + /* notify the exit routine that we're actually exiting now + * + * complete()/wait_for_completion() is similar to up()/down(), + * except that complete() is safe in the case where the structure + * is getting deleted in a parallel mode of execution (i.e. just + * after the down() -- that's necessary for the thread-shutdown + * case. + * + * complete_and_exit() goes even further than this -- it is safe in + * the case that the thread of the caller is going away (not just + * the structure) -- this is necessary for the module-remove case. + * This is important in preemption kernels, which transfer the flow + * of execution immediately upon a complete(). + */ + DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n")); + +#ifndef KTHREAD_SUPPORT + pTask->taskPID = THREAD_PID_INIT_VALUE; + complete_and_exit (&pTask->taskComplete, 0); +#endif + return 0; + +} + + +VOID RTUSBWatchDog(IN RTMP_ADAPTER *pAd) +{ + PHT_TX_CONTEXT pHTTXContext; + int idx; + ULONG irqFlags; + PURB pUrb; + BOOLEAN needDumpSeq = FALSE; + UINT32 MACValue; + UINT32 TxRxQ_Pcnt; + + idx = 0; + RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); + if ((MACValue & 0xff) !=0 ) + { + DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue)); + RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012); + while((MACValue &0xff) != 0 && (idx++ < 10)) + { + RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); + RTMPusecDelay(1); + } + RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006); + } + + if (pAd->watchDogRxOverFlowCnt >= 2) + { + DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n")); + if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | + fRTMP_ADAPTER_BULKIN_RESET | + fRTMP_ADAPTER_HALT_IN_PROGRESS | + fRTMP_ADAPTER_NIC_NOT_EXIST)))) + { + DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n")); + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); + RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0); + needDumpSeq = TRUE; + } + pAd->watchDogRxOverFlowCnt = 0; + } + + RTUSBReadMACRegister(pAd, 0x438, &TxRxQ_Pcnt); + + for (idx = 0; idx < NUM_OF_TX_RING; idx++) + { + pUrb = NULL; + + RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags); + if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt) + { + INT actual_length=0,transfer_buffer_length=0; + BOOLEAN isDataPacket=FALSE; + pAd->watchDogTxPendingCnt[idx]++; + + if ((pAd->watchDogTxPendingCnt[idx] > 2) && + (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET))) + ) + { + // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it! + pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]); + if (pHTTXContext->IRPPending) + { // Check TxContext. + pUrb = pHTTXContext->pUrb; + + actual_length=pUrb->actual_length; + transfer_buffer_length=pUrb->transfer_buffer_length; + isDataPacket=TRUE; + } + else if (idx == MGMTPIPEIDX) + { + PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext; + + //Check MgmtContext. + pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa); + pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext); + pNULLContext = (PTX_CONTEXT)(&pAd->NullContext); + + if (pMLMEContext->IRPPending) + { + ASSERT(pMLMEContext->IRPPending); + pUrb = pMLMEContext->pUrb; + } + else if (pNULLContext->IRPPending) + { + ASSERT(pNULLContext->IRPPending); + pUrb = pNULLContext->pUrb; + } + else if (pPsPollContext->IRPPending) + { + ASSERT(pPsPollContext->IRPPending); + pUrb = pPsPollContext->pUrb; + } + } + + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); + + + printk("%d:%d LTL=%d , TL=%d L:%d\n",idx,pAd->watchDogTxPendingCnt[idx],pAd->TransferedLength[idx] + ,actual_length,transfer_buffer_length); + + if (pUrb) + { + if ((isDataPacket + && pAd->TransferedLength[idx]==actual_length + && pAd->TransferedLength[idx]watchDogTxPendingCnt[idx]>3) + || isDataPacket==FALSE || pAd->watchDogTxPendingCnt[idx]>6) + { + DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx)); + DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n")); + // unlink it now + RTUSB_UNLINK_URB(pUrb); + // Sleep 200 microseconds to give cancellation time to work + //RTMPusecDelay(200); + needDumpSeq = TRUE; + } + } + else + { + DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n")); + } + } + else + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); + } + + if (isDataPacket==TRUE) + pAd->TransferedLength[idx]=actual_length; + } + else + { + RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); + } + } + + // For Sigma debug, dump the ba_reordering sequence. + if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0)) + { + USHORT Idx; + PBA_REC_ENTRY pBAEntry = NULL; + UCHAR count = 0; + struct reordering_mpdu *mpdu_blk; + + Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0]; + + pBAEntry = &pAd->BATable.BARecEntry[Idx]; + if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL)) + { + DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n")); + NdisAcquireSpinLock(&pBAEntry->RxReRingLock); + mpdu_blk = pBAEntry->list.next; + while (mpdu_blk) + { + DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU)); + mpdu_blk = mpdu_blk->next; + count++; + } + + DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq)); + NdisReleaseSpinLock(&pBAEntry->RxReRingLock); + } + } +} + +/* +======================================================================== +Routine Description: + Release allocated resources. + +Arguments: + *dev Point to the PCI or USB device + pAd driver control block pointer + +Return Value: + None + +Note: +======================================================================== +*/ +static void rt2870_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd) +{ + DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n", + dev->bus->bus_name, dev->devpath)); + if (!pAd) + { + usb_put_dev(dev); + printk("rtusb_disconnect: pAd == NULL!\n"); + return; + } + RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); + + // for debug, wait to show some messages to /proc system + udelay(1); + + + RtmpPhyNetDevExit(pAd, pAd->net_dev); + + // FIXME: Shall we need following delay and flush the schedule?? + udelay(1); + flush_scheduled_work(); + udelay(1); + + // free the root net_device + RtmpOSNetDevFree(pAd->net_dev); + + RtmpRaDevCtrlExit(pAd); + + // release a use of the usb device structure + usb_put_dev(dev); + udelay(1); + + DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n")); +} + + +static int __devinit rt2870_probe( + IN struct usb_interface *intf, + IN struct usb_device *usb_dev, + IN const struct usb_device_id *dev_id, + IN RTMP_ADAPTER **ppAd) +{ + struct net_device *net_dev = NULL; + RTMP_ADAPTER *pAd = (RTMP_ADAPTER *) NULL; + INT status, rv; + PVOID handle; + RTMP_OS_NETDEV_OP_HOOK netDevHook; + + + DBGPRINT(RT_DEBUG_TRACE, ("===>rt2870_probe()!\n")); + + // Check chipset vendor/product ID + //if (RT28XXChipsetCheck(_dev_p) == FALSE) + // goto err_out; + +//RtmpDevInit============================================= + // Allocate RTMP_ADAPTER adapter structure + handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL); + if (handle == NULL) + { + printk("rt2870_probe(): Allocate memory for os handle failed!\n"); + return -ENOMEM; + } + ((POS_COOKIE)handle)->pUsb_Dev = usb_dev; + + rv = RTMPAllocAdapterBlock(handle, &pAd); + if (rv != NDIS_STATUS_SUCCESS) + { + kfree(handle); + goto err_out; + } + +//USBDevInit============================================== + if (USBDevConfigInit(usb_dev, intf, pAd) == FALSE) + goto err_out_free_radev; + + RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_USB); + +//NetDevInit============================================== + net_dev = RtmpPhyNetDevInit(pAd, &netDevHook); + if (net_dev == NULL) + goto err_out_free_radev; + + // Here are the net_device structure with usb specific parameters. + /* for supporting Network Manager. + * Set the sysfs physical device reference for the network logical device if set prior to registration will + * cause a symlink during initialization. + */ + SET_NETDEV_DEV(net_dev, &(usb_dev->dev)); + + pAd->StaCfg.OriDevType = net_dev->type; + +//All done, it's time to register the net device to linux kernel. + // Register this device + status = RtmpOSNetDevAttach(net_dev, &netDevHook); + if (status != 0) + goto err_out_free_netdev; + +#ifdef KTHREAD_SUPPORT + init_waitqueue_head(&pAd->mlmeTask.kthread_q); + init_waitqueue_head(&pAd->timerTask.kthread_q); + init_waitqueue_head(&pAd->cmdQTask.kthread_q); +#endif + + *ppAd = pAd; + + DBGPRINT(RT_DEBUG_TRACE, ("<===rt2870_probe()!\n")); + + return 0; + + /* --------------------------- ERROR HANDLE --------------------------- */ +err_out_free_netdev: + RtmpOSNetDevFree(net_dev); + +err_out_free_radev: + RTMPFreeAdapter(pAd); + +err_out: + *ppAd = NULL; + + return -1; + +} Index: b/drivers/staging/rt2860/wpa.h =================================================================== --- a/drivers/staging/rt2860/wpa.h +++ b/drivers/staging/rt2860/wpa.h @@ -67,7 +67,6 @@ // Key Descriptor Version of Key Information #define DESC_TYPE_TKIP 1 #define DESC_TYPE_AES 2 -#define DESC_TYPE_MESH 3 #define LEN_MSG1_2WAY 0x7f #define MAX_LEN_OF_EAP_HS 256 @@ -90,11 +89,17 @@ #define TKIP_AP_RXMICK_OFFSET (TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK) #define TKIP_GTK_LENGTH ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK)) #define LEN_PTK ((LEN_EAP_KEY)+(LEN_TKIP_KEY)) +#define MIN_LEN_OF_GTK 5 +#define LEN_PMK 32 +#define LEN_PMK_NAME 16 +#define LEN_NONCE 32 // RSN IE Length definition -#define MAX_LEN_OF_RSNIE 90 +#define MAX_LEN_OF_RSNIE 255 #define MIN_LEN_OF_RSNIE 8 +#define KEY_LIFETIME 3600 + //EAP Packet Type #define EAPPacket 0 #define EAPOLStart 1 @@ -119,6 +124,29 @@ #define PEER_MSG3_RETRY_TIMER_CTR 10 #define GROUP_MSG1_RETRY_TIMER_CTR 20 +//#ifdef CONFIG_AP_SUPPORT +// WPA mechanism retry timer interval +#define PEER_MSG1_RETRY_EXEC_INTV 1000 // 1 sec +#define PEER_MSG3_RETRY_EXEC_INTV 3000 // 3 sec +#define GROUP_KEY_UPDATE_EXEC_INTV 1000 // 1 sec +#define PEER_GROUP_KEY_UPDATE_INIV 2000 // 2 sec + +#define ENQUEUE_EAPOL_START_TIMER 200 // 200 ms + +// group rekey interval +#define TIME_REKEY 0 +#define PKT_REKEY 1 +#define DISABLE_REKEY 2 +#define MAX_REKEY 2 + +#define MAX_REKEY_INTER 0x3ffffff +//#endif // CONFIG_AP_SUPPORT // + +#define GROUP_SUITE 0 +#define PAIRWISE_SUITE 1 +#define AKM_SUITE 2 +#define PMKID_LIST 3 + #define EAPOL_START_DISABLE 0 #define EAPOL_START_PSK 1 @@ -129,8 +157,30 @@ #define MIX_CIPHER_WPA2_TKIP_ON(x) (((x) & 0x02) != 0) #define MIX_CIPHER_WPA2_AES_ON(x) (((x) & 0x01) != 0) +#ifndef ROUND_UP #define ROUND_UP(__x, __y) \ (((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1))) +#endif + +#define SET_UINT16_TO_ARRARY(_V, _LEN) \ +{ \ + _V[0] = (_LEN & 0xFF00) >> 8; \ + _V[1] = (_LEN & 0xFF); \ +} + +#define INC_UINT16_TO_ARRARY(_V, _LEN) \ +{ \ + UINT16 var_len; \ + \ + var_len = (_V[0]<<8) | (_V[1]); \ + var_len += _LEN; \ + \ + _V[0] = (var_len & 0xFF00) >> 8; \ + _V[1] = (var_len & 0xFF); \ +} + +#define CONV_ARRARY_TO_UINT16(_V) ((_V[0]<<8) | (_V[1])) + #define ADD_ONE_To_64BIT_VAR(_V) \ { \ @@ -297,6 +347,13 @@ typedef enum _WpaMixPairCipher WPA_TKIPAES_WPA2_TKIPAES = 0x0F, } WPA_MIX_PAIR_CIPHER; +// 802.1x authentication format +typedef struct _IEEE8021X_FRAME { + UCHAR Version; // 1.0 + UCHAR Type; // 0 = EAP Packet + USHORT Length; +} IEEE8021X_FRAME, *PIEEE8021X_FRAME; + typedef struct PACKED _RSN_IE_HEADER_STRUCT { UCHAR Eid; UCHAR Length; @@ -324,4 +381,47 @@ typedef struct PACKED _RSN_CAPABILITY { USHORT PreAuth:1; } RSN_CAPABILITY, *PRSN_CAPABILITY; + +/*======================================== + The prototype is defined in cmm_wpa.c + ========================================*/ +BOOLEAN WpaMsgTypeSubst( + IN UCHAR EAPType, + OUT INT *MsgType); + +VOID PRF( + IN UCHAR *key, + IN INT key_len, + IN UCHAR *prefix, + IN INT prefix_len, + IN UCHAR *data, + IN INT data_len, + OUT UCHAR *output, + IN INT len); + +int PasswordHash( + char *password, + unsigned char *ssid, + int ssidlength, + unsigned char *output); + +PUINT8 GetSuiteFromRSNIE( + IN PUINT8 rsnie, + IN UINT rsnie_len, + IN UINT8 type, + OUT UINT8 *count); + +VOID WpaShowAllsuite( + IN PUINT8 rsnie, + IN UINT rsnie_len); + +VOID RTMPInsertRSNIE( + IN PUCHAR pFrameBuf, + OUT PULONG pFrameLen, + IN PUINT8 rsnie_ptr, + IN UINT8 rsnie_len, + IN PUINT8 pmkid_ptr, + IN UINT8 pmkid_len); + + #endif Index: b/drivers/staging/rt2870/2870_main_dev.c =================================================================== --- a/drivers/staging/rt2870/2870_main_dev.c +++ /dev/null @@ -1,1530 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - - Module Name: - rtmp_main.c - - Abstract: - main initialization routines - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Name Date Modification logs - Jan Lee 01-10-2005 modified - Sample Jun/01/07 Merge RT2870 and RT2860 drivers. -*/ - -#include "rt_config.h" - - -// Following information will be show when you run 'modinfo' -// *** If you have a solution for the bug in current version of driver, please mail to me. -// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. *** -MODULE_AUTHOR("Paul Lin "); -MODULE_DESCRIPTION(RT28xx_CHIP_NAME " Wireless LAN Linux Driver"); -MODULE_LICENSE("GPL"); -#ifdef MODULE_VERSION -MODULE_VERSION(STA_DRIVER_VERSION); -#endif -MODULE_ALIAS("rt3070sta"); - -/* Kernel thread and vars, which handles packets that are completed. Only - * packets that have a "complete" function are sent here. This way, the - * completion is run out of kernel context, and doesn't block the rest of - * the stack. */ - -extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p, - IN UINT argc, OUT PRTMP_ADAPTER *ppAd); - -struct usb_device_id rtusb_usb_id[] = { - { USB_DEVICE(0x148F, 0x2770) }, /* Ralink */ - { USB_DEVICE(0x1737, 0x0071) }, /* Linksys WUSB600N */ - { USB_DEVICE(0x1737, 0x0070) }, /* Linksys */ - { USB_DEVICE(0x148F, 0x2870) }, /* Ralink */ - { USB_DEVICE(0x148F, 0x3070) }, /* Ralink 3070 */ - { USB_DEVICE(0x148F, 0x3071) }, /* Ralink 3071 */ - { USB_DEVICE(0x148F, 0x3072) }, /* Ralink 3072 */ - { USB_DEVICE(0x0B05, 0x1731) }, /* Asus */ - { USB_DEVICE(0x0B05, 0x1732) }, /* Asus */ - { USB_DEVICE(0x0B05, 0x1742) }, /* Asus */ - { USB_DEVICE(0x0DF6, 0x0017) }, /* Sitecom */ - { USB_DEVICE(0x0DF6, 0x002B) }, /* Sitecom */ - { USB_DEVICE(0x0DF6, 0x002C) }, /* Sitecom */ - { USB_DEVICE(0x0DF6, 0x003E) }, /* Sitecom 3070 */ - { USB_DEVICE(0x0DF6, 0x002D) }, /* Sitecom */ - { USB_DEVICE(0x0DF6, 0x0039) }, /* Sitecom 2770 */ - { USB_DEVICE(0x0DF6, 0x003F) }, /* Sitecom WL-608 */ - { USB_DEVICE(0x14B2, 0x3C06) }, /* Conceptronic */ - { USB_DEVICE(0x14B2, 0x3C28) }, /* Conceptronic */ - { USB_DEVICE(0x2019, 0xED06) }, /* Planex Communications, Inc. */ - { USB_DEVICE(0x2019, 0xED14) }, /* Planex Communications, Inc. */ - { USB_DEVICE(0x2019, 0xAB25) }, /* Planex Communications, Inc. RT3070 */ - { USB_DEVICE(0x07D1, 0x3C09) }, /* D-Link */ - { USB_DEVICE(0x07D1, 0x3C11) }, /* D-Link */ - { USB_DEVICE(0x2001, 0x3C09) }, /* D-Link */ - { USB_DEVICE(0x2001, 0x3C0A) }, /* D-Link 3072*/ - { USB_DEVICE(0x14B2, 0x3C07) }, /* AL */ - { USB_DEVICE(0x14B2, 0x3C12) }, /* AL 3070 */ - { USB_DEVICE(0x050D, 0x8053) }, /* Belkin */ - { USB_DEVICE(0x050D, 0x815C) }, /* Belkin */ - { USB_DEVICE(0x050D, 0x825a) }, /* Belkin */ - { USB_DEVICE(0x14B2, 0x3C23) }, /* Airlink */ - { USB_DEVICE(0x14B2, 0x3C27) }, /* Airlink */ - { USB_DEVICE(0x07AA, 0x002F) }, /* Corega */ - { USB_DEVICE(0x07AA, 0x003C) }, /* Corega */ - { USB_DEVICE(0x07AA, 0x003F) }, /* Corega */ - { USB_DEVICE(0x18C5, 0x0012) }, /* Corega 3070 */ - { USB_DEVICE(0x1044, 0x800B) }, /* Gigabyte */ - { USB_DEVICE(0x1044, 0x800D) }, /* Gigabyte GN-WB32L 3070 */ - { USB_DEVICE(0x15A9, 0x0006) }, /* Sparklan */ - { USB_DEVICE(0x083A, 0xB522) }, /* SMC */ - { USB_DEVICE(0x083A, 0xA618) }, /* SMC */ - { USB_DEVICE(0x083A, 0x8522) }, /* Arcadyan */ - { USB_DEVICE(0x083A, 0x7512) }, /* Arcadyan 2770 */ - { USB_DEVICE(0x083A, 0x7522) }, /* Arcadyan */ - { USB_DEVICE(0x083A, 0x7511) }, /* Arcadyan 3070 */ - { USB_DEVICE(0x0CDE, 0x0022) }, /* ZCOM */ - { USB_DEVICE(0x0586, 0x3416) }, /* Zyxel */ - { USB_DEVICE(0x0CDE, 0x0025) }, /* Zyxel */ - { USB_DEVICE(0x1740, 0x9701) }, /* EnGenius */ - { USB_DEVICE(0x1740, 0x9702) }, /* EnGenius */ - { USB_DEVICE(0x1740, 0x9703) }, /* EnGenius 3070 */ - { USB_DEVICE(0x0471, 0x200f) }, /* Philips */ - { USB_DEVICE(0x14B2, 0x3C25) }, /* Draytek */ - { USB_DEVICE(0x13D3, 0x3247) }, /* AzureWave */ - { USB_DEVICE(0x13D3, 0x3273) }, /* AzureWave 3070*/ - { USB_DEVICE(0x083A, 0x6618) }, /* Accton */ - { USB_DEVICE(0x15c5, 0x0008) }, /* Amit */ - { USB_DEVICE(0x0E66, 0x0001) }, /* Hawking */ - { USB_DEVICE(0x0E66, 0x0003) }, /* Hawking */ - { USB_DEVICE(0x129B, 0x1828) }, /* Siemens */ - { USB_DEVICE(0x157E, 0x300E) }, /* U-Media */ - { USB_DEVICE(0x050d, 0x805c) }, - { USB_DEVICE(0x1482, 0x3C09) }, /* Abocom*/ - { USB_DEVICE(0x14B2, 0x3C09) }, /* Alpha */ - { USB_DEVICE(0x04E8, 0x2018) }, /* samsung */ - { USB_DEVICE(0x07B8, 0x3070) }, /* AboCom 3070 */ - { USB_DEVICE(0x07B8, 0x3071) }, /* AboCom 3071 */ - { USB_DEVICE(0x07B8, 0x2870) }, /* AboCom */ - { USB_DEVICE(0x07B8, 0x2770) }, /* AboCom */ - { USB_DEVICE(0x07B8, 0x3072) }, /* Abocom 3072 */ - { USB_DEVICE(0x7392, 0x7711) }, /* Edimax 3070 */ - { USB_DEVICE(0x5A57, 0x0280) }, /* Zinwell */ - { USB_DEVICE(0x5A57, 0x0282) }, /* Zinwell */ - { USB_DEVICE(0x1A32, 0x0304) }, /* Quanta 3070 */ - { USB_DEVICE(0x0789, 0x0162) }, /* Logitec 2870 */ - { USB_DEVICE(0x0789, 0x0163) }, /* Logitec 2870 */ - { USB_DEVICE(0x0789, 0x0164) }, /* Logitec 2870 */ - { USB_DEVICE(0x7392, 0x7717) }, /* Edimax */ - { USB_DEVICE(0x1EDA, 0x2310) }, /* AirTies 3070 */ - { USB_DEVICE(0x1737, 0x0077) }, /* Linksys WUSB54GC-EU v3 */ - { } /* Terminating entry */ -}; - -INT const rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id); -MODULE_DEVICE_TABLE(usb, rtusb_usb_id); - -#ifndef PF_NOFREEZE -#define PF_NOFREEZE 0 -#endif - - -#ifdef CONFIG_PM -static int rt2870_suspend(struct usb_interface *intf, pm_message_t state); -static int rt2870_resume(struct usb_interface *intf); -#endif // CONFIG_PM // - -/**************************************************************************/ -/**************************************************************************/ -//tested for kernel 2.6series -/**************************************************************************/ -/**************************************************************************/ -static int rtusb_probe (struct usb_interface *intf, - const struct usb_device_id *id); -static void rtusb_disconnect(struct usb_interface *intf); - -struct usb_driver rtusb_driver = { - .name="rt2870", - .probe=rtusb_probe, - .disconnect=rtusb_disconnect, - .id_table=rtusb_usb_id, - -#ifdef CONFIG_PM - suspend: rt2870_suspend, - resume: rt2870_resume, -#endif - }; - -#ifdef CONFIG_PM - -VOID RT2860RejectPendingPackets( - IN PRTMP_ADAPTER pAd) -{ - // clear PS packets - // clear TxSw packets -} - -static int rt2870_suspend( - struct usb_interface *intf, - pm_message_t state) -{ - struct net_device *net_dev; - PRTMP_ADAPTER pAd = usb_get_intfdata(intf); - - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n")); - net_dev = pAd->net_dev; - netif_device_detach (net_dev); - - pAd->PM_FlgSuspend = 1; - if (netif_running(net_dev)) { - RTUSBCancelPendingBulkInIRP(pAd); - RTUSBCancelPendingBulkOutIRP(pAd); - } - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n")); - return 0; -} - -static int rt2870_resume( - struct usb_interface *intf) -{ - struct net_device *net_dev; - PRTMP_ADAPTER pAd = usb_get_intfdata(intf); - - - DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n")); - - pAd->PM_FlgSuspend = 0; - net_dev = pAd->net_dev; - netif_device_attach (net_dev); - netif_start_queue(net_dev); - netif_carrier_on(net_dev); - netif_wake_queue(net_dev); - - DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n")); - return 0; -} -#endif // CONFIG_PM // - - -// Init driver module -INT __init rtusb_init(void) -{ - printk("rtusb init --->\n"); - return usb_register(&rtusb_driver); -} - -// Deinit driver module -VOID __exit rtusb_exit(void) -{ - usb_deregister(&rtusb_driver); - printk("<--- rtusb exit\n"); -} - -module_init(rtusb_init); -module_exit(rtusb_exit); - - - - -/*--------------------------------------------------------------------- */ -/* function declarations */ -/*--------------------------------------------------------------------- */ - -/* -======================================================================== -Routine Description: - MLME kernel thread. - -Arguments: - *Context the pAd, driver control block pointer - -Return Value: - 0 close the thread - -Note: -======================================================================== -*/ -INT MlmeThread( - IN void *Context) -{ - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context; - POS_COOKIE pObj; - int status; - - pObj = (POS_COOKIE)pAd->OS_Cookie; - - rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete)); - - while (pAd->mlme_kill == 0) - { - /* lock the device pointers */ - //down(&(pAd->mlme_semaphore)); - status = down_interruptible(&(pAd->mlme_semaphore)); - - /* lock the device pointers , need to check if required*/ - //down(&(pAd->usbdev_semaphore)); - - if (!pAd->PM_FlgSuspend) - MlmeHandler(pAd); - - /* unlock the device pointers */ - //up(&(pAd->usbdev_semaphore)); - if (status != 0) - { - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - break; - } - } - - /* notify the exit routine that we're actually exiting now - * - * complete()/wait_for_completion() is similar to up()/down(), - * except that complete() is safe in the case where the structure - * is getting deleted in a parallel mode of execution (i.e. just - * after the down() -- that's necessary for the thread-shutdown - * case. - * - * complete_and_exit() goes even further than this -- it is safe in - * the case that the thread of the caller is going away (not just - * the structure) -- this is necessary for the module-remove case. - * This is important in preemption kernels, which transfer the flow - * of execution immediately upon a complete(). - */ - DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__)); - - pObj->MLMEThr_pid = NULL; - - complete_and_exit (&pAd->mlmeComplete, 0); - return 0; - -} - - -/* -======================================================================== -Routine Description: - USB command kernel thread. - -Arguments: - *Context the pAd, driver control block pointer - -Return Value: - 0 close the thread - -Note: -======================================================================== -*/ -INT RTUSBCmdThread( - IN void * Context) -{ - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context; - POS_COOKIE pObj; - int status; - - pObj = (POS_COOKIE)pAd->OS_Cookie; - - rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete)); - - NdisAcquireSpinLock(&pAd->CmdQLock); - pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING; - NdisReleaseSpinLock(&pAd->CmdQLock); - - while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING) - { - /* lock the device pointers */ - //down(&(pAd->RTUSBCmd_semaphore)); - status = down_interruptible(&(pAd->RTUSBCmd_semaphore)); - - if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED) - break; - - if (status != 0) - { - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - break; - } - /* lock the device pointers , need to check if required*/ - //down(&(pAd->usbdev_semaphore)); - - if (!pAd->PM_FlgSuspend) - CMDHandler(pAd); - - /* unlock the device pointers */ - //up(&(pAd->usbdev_semaphore)); - } - - if (!pAd->PM_FlgSuspend) - { // Clear the CmdQElements. - CmdQElmt *pCmdQElmt = NULL; - - NdisAcquireSpinLock(&pAd->CmdQLock); - pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED; - while(pAd->CmdQ.size) - { - RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt); - if (pCmdQElmt) - { - if (pCmdQElmt->CmdFromNdis == TRUE) - { - if (pCmdQElmt->buffer != NULL) - NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0); - - NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0); - } - else - { - if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0)) - NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0); - { - NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0); - } - } - } - } - - NdisReleaseSpinLock(&pAd->CmdQLock); - } - /* notify the exit routine that we're actually exiting now - * - * complete()/wait_for_completion() is similar to up()/down(), - * except that complete() is safe in the case where the structure - * is getting deleted in a parallel mode of execution (i.e. just - * after the down() -- that's necessary for the thread-shutdown - * case. - * - * complete_and_exit() goes even further than this -- it is safe in - * the case that the thread of the caller is going away (not just - * the structure) -- this is necessary for the module-remove case. - * This is important in preemption kernels, which transfer the flow - * of execution immediately upon a complete(). - */ - DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n")); - - pObj->RTUSBCmdThr_pid = NULL; - - complete_and_exit (&pAd->CmdQComplete, 0); - return 0; - -} - - -static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd) -{ - int status; - RALINK_TIMER_STRUCT *pTimer; - RT2870_TIMER_ENTRY *pEntry; - unsigned long irqFlag; - - while(!pAd->TimerFunc_kill) - { -// printk("waiting for event!\n"); - pTimer = NULL; - - status = down_interruptible(&(pAd->RTUSBTimer_semaphore)); - - if (pAd->TimerQ.status == RT2870_THREAD_STOPED) - break; - - // event happened. - while(pAd->TimerQ.pQHead) - { - RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag); - pEntry = pAd->TimerQ.pQHead; - if (pEntry) - { - pTimer = pEntry->pRaTimer; - - // update pQHead - pAd->TimerQ.pQHead = pEntry->pNext; - if (pEntry == pAd->TimerQ.pQTail) - pAd->TimerQ.pQTail = NULL; - - // return this queue entry to timerQFreeList. - pEntry->pNext = pAd->TimerQ.pQPollFreeList; - pAd->TimerQ.pQPollFreeList = pEntry; - } - RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag); - - if (pTimer) - { - if (pTimer->handle != NULL) - if (!pAd->PM_FlgSuspend) - pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer); - if ((pTimer->Repeat) && (pTimer->State == FALSE)) - RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); - } - } - - if (status != 0) - { - pAd->TimerQ.status = RT2870_THREAD_STOPED; - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); - break; - } - } -} - - -INT TimerQThread( - IN OUT PVOID Context) -{ - PRTMP_ADAPTER pAd; - POS_COOKIE pObj; - - pAd = (PRTMP_ADAPTER)Context; - pObj = (POS_COOKIE) pAd->OS_Cookie; - - rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete)); - - RT2870_TimerQ_Handle(pAd); - - /* notify the exit routine that we're actually exiting now - * - * complete()/wait_for_completion() is similar to up()/down(), - * except that complete() is safe in the case where the structure - * is getting deleted in a parallel mode of execution (i.e. just - * after the down() -- that's necessary for the thread-shutdown - * case. - * - * complete_and_exit() goes even further than this -- it is safe in - * the case that the thread of the caller is going away (not just - * the structure) -- this is necessary for the module-remove case. - * This is important in preemption kernels, which transfer the flow - * of execution immediately upon a complete(). - */ - DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__)); - - pObj->TimerQThr_pid = NULL; - - complete_and_exit(&pAd->TimerQComplete, 0); - return 0; - -} - - -RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert( - IN RTMP_ADAPTER *pAd, - IN RALINK_TIMER_STRUCT *pTimer) -{ - RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail; - unsigned long irqFlags; - - - RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags); - if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT) - { - if(pAd->TimerQ.pQPollFreeList) - { - pQNode = pAd->TimerQ.pQPollFreeList; - pAd->TimerQ.pQPollFreeList = pQNode->pNext; - - pQNode->pRaTimer = pTimer; - pQNode->pNext = NULL; - - pQTail = pAd->TimerQ.pQTail; - if (pAd->TimerQ.pQTail != NULL) - pQTail->pNext = pQNode; - pAd->TimerQ.pQTail = pQNode; - if (pAd->TimerQ.pQHead == NULL) - pAd->TimerQ.pQHead = pQNode; - } - RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags); - - if (pQNode) - up(&pAd->RTUSBTimer_semaphore); - //wake_up(&timerWaitQ); - } - else - { - RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags); - } - return pQNode; -} - - -BOOLEAN RT2870_TimerQ_Remove( - IN RTMP_ADAPTER *pAd, - IN RALINK_TIMER_STRUCT *pTimer) -{ - RT2870_TIMER_ENTRY *pNode, *pPrev = NULL; - unsigned long irqFlags; - - RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags); - if (pAd->TimerQ.status >= RT2870_THREAD_INITED) - { - pNode = pAd->TimerQ.pQHead; - while (pNode) - { - if (pNode->pRaTimer == pTimer) - break; - pPrev = pNode; - pNode = pNode->pNext; - } - - // Now move it to freeList queue. - if (pNode) - { - if (pNode == pAd->TimerQ.pQHead) - pAd->TimerQ.pQHead = pNode->pNext; - if (pNode == pAd->TimerQ.pQTail) - pAd->TimerQ.pQTail = pPrev; - if (pPrev != NULL) - pPrev->pNext = pNode->pNext; - - // return this queue entry to timerQFreeList. - pNode->pNext = pAd->TimerQ.pQPollFreeList; - pAd->TimerQ.pQPollFreeList = pNode; - } - } - RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags); - - return TRUE; -} - - -void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd) -{ - RT2870_TIMER_ENTRY *pTimerQ; - unsigned long irqFlags; - - RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags); - while (pAd->TimerQ.pQHead) - { - pTimerQ = pAd->TimerQ.pQHead; - pAd->TimerQ.pQHead = pTimerQ->pNext; - // remove the timeQ - } - pAd->TimerQ.pQPollFreeList = NULL; - os_free_mem(pAd, pAd->TimerQ.pTimerQPoll); - pAd->TimerQ.pQTail = NULL; - pAd->TimerQ.pQHead = NULL; - pAd->TimerQ.status = RT2870_THREAD_STOPED; - RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags); - -} - - -void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd) -{ - int i; - RT2870_TIMER_ENTRY *pQNode, *pEntry; - unsigned long irqFlags; - - NdisAllocateSpinLock(&pAd->TimerQLock); - - RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags); - NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ)); - //InterlockedExchange(&pAd->TimerQ.count, 0); - - /* Initialise the wait q head */ - //init_waitqueue_head(&timerWaitQ); - - os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX); - if (pAd->TimerQ.pTimerQPoll) - { - pEntry = NULL; - pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll; - for (i = 0 ;i pNext = pEntry; - pEntry = pQNode; - pQNode++; - } - pAd->TimerQ.pQPollFreeList = pEntry; - pAd->TimerQ.pQHead = NULL; - pAd->TimerQ.pQTail = NULL; - pAd->TimerQ.status = RT2870_THREAD_INITED; - } - RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags); -} - - -VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd) -{ - PHT_TX_CONTEXT pHTTXContext; - int idx; - ULONG irqFlags; - PURB pUrb; - BOOLEAN needDumpSeq = FALSE; - UINT32 MACValue; - - - idx = 0; - RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); - if ((MACValue & 0xff) !=0 ) - { - DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue)); - RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012); - while((MACValue &0xff) != 0 && (idx++ < 10)) - { - RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); - NdisMSleep(1); - } - RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006); - } - -//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) - idx = 0; - if ((MACValue & 0xff00) !=0 ) - { - DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue)); - RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a); - while((MACValue &0xff00) != 0 && (idx++ < 10)) - { - RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue); - NdisMSleep(1); - } - RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006); - } - - if (pAd->watchDogRxOverFlowCnt >= 2) - { - DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n")); - if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_BULKIN_RESET | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) - { - DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n")); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0); - needDumpSeq = TRUE; - } - pAd->watchDogRxOverFlowCnt = 0; - } - - - for (idx = 0; idx < NUM_OF_TX_RING; idx++) - { - pUrb = NULL; - - RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags); - if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt) - { - pAd->watchDogTxPendingCnt[idx]++; - - if ((pAd->watchDogTxPendingCnt[idx] > 2) && - (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET))) - ) - { - // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it! - pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]); - if (pHTTXContext->IRPPending) - { // Check TxContext. - pUrb = pHTTXContext->pUrb; - } - else if (idx == MGMTPIPEIDX) - { - PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext; - - //Check MgmtContext. - pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa); - pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext); - pNULLContext = (PTX_CONTEXT)(&pAd->NullContext); - - if (pMLMEContext->IRPPending) - { - ASSERT(pMLMEContext->IRPPending); - pUrb = pMLMEContext->pUrb; - } - else if (pNULLContext->IRPPending) - { - ASSERT(pNULLContext->IRPPending); - pUrb = pNULLContext->pUrb; - } - else if (pPsPollContext->IRPPending) - { - ASSERT(pPsPollContext->IRPPending); - pUrb = pPsPollContext->pUrb; - } - } - - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); - - DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx)); - if (pUrb) - { - DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n")); - // unlink it now - RTUSB_UNLINK_URB(pUrb); - // Sleep 200 microseconds to give cancellation time to work - RTMPusecDelay(200); - needDumpSeq = TRUE; - } - else - { - DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n")); - } - } - else - { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); - } - } - else - { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags); - } - } - - // For Sigma debug, dump the ba_reordering sequence. - if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0)) - { - USHORT Idx; - PBA_REC_ENTRY pBAEntry = NULL; - UCHAR count = 0; - struct reordering_mpdu *mpdu_blk; - - Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0]; - - pBAEntry = &pAd->BATable.BARecEntry[Idx]; - if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL)) - { - DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n")); - NdisAcquireSpinLock(&pBAEntry->RxReRingLock); - mpdu_blk = pBAEntry->list.next; - while (mpdu_blk) - { - DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU)); - mpdu_blk = mpdu_blk->next; - count++; - } - - DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq)); - NdisReleaseSpinLock(&pBAEntry->RxReRingLock); - } - } -} - -/* -======================================================================== -Routine Description: - Release allocated resources. - -Arguments: - *dev Point to the PCI or USB device - pAd driver control block pointer - -Return Value: - None - -Note: -======================================================================== -*/ -static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd) -{ - struct net_device *net_dev = NULL; - - - DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n", - dev->bus->bus_name, dev->devpath)); - if (!pAd) - { - usb_put_dev(dev); - - printk("rtusb_disconnect: pAd == NULL!\n"); - return; - } - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); - - - - // for debug, wait to show some messages to /proc system - udelay(1); - - - - - net_dev = pAd->net_dev; - if (pAd->net_dev != NULL) - { - printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name); - unregister_netdev (pAd->net_dev); - } - udelay(1); - flush_scheduled_work(); - udelay(1); - - // free net_device memory - free_netdev(net_dev); - - // free adapter memory - RTMPFreeAdapter(pAd); - - // release a use of the usb device structure - usb_put_dev(dev); - udelay(1); - - DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n")); -} - - -/* -======================================================================== -Routine Description: - Probe RT28XX chipset. - -Arguments: - *dev Point to the PCI or USB device - interface - *id_table Point to the PCI or USB device ID - -Return Value: - None - -Note: -======================================================================== -*/ -static int rtusb_probe (struct usb_interface *intf, - const struct usb_device_id *id) -{ - PRTMP_ADAPTER pAd; - return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd); -} - - -static void rtusb_disconnect(struct usb_interface *intf) -{ - struct usb_device *dev = interface_to_usbdev(intf); - PRTMP_ADAPTER pAd; - - - pAd = usb_get_intfdata(intf); - usb_set_intfdata(intf, NULL); - - _rtusb_disconnect(dev, pAd); -} - - -/* -======================================================================== -Routine Description: - Close kernel threads. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - NONE - -Note: -======================================================================== -*/ -VOID RT28xxThreadTerminate( - IN RTMP_ADAPTER *pAd) -{ - POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; - INT ret; - - - // Sleep 50 milliseconds so pending io might finish normally - RTMPusecDelay(50000); - - // We want to wait until all pending receives and sends to the - // device object. We cancel any - // irps. Wait until sends and receives have stopped. - RTUSBCancelPendingIRPs(pAd); - - // Terminate Threads - - if (pid_nr(pObj->TimerQThr_pid) > 0) - { - POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie; - - printk("Terminate the TimerQThr_pid=%d!\n", pid_nr(pObj->TimerQThr_pid)); - mb(); - pAd->TimerFunc_kill = 1; - mb(); - ret = kill_pid(pObj->TimerQThr_pid, SIGTERM, 1); - if (ret) - { - printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n", - pAd->net_dev->name, pid_nr(pObj->TimerQThr_pid), ret); - } - else - { - wait_for_completion(&pAd->TimerQComplete); - pObj->TimerQThr_pid = NULL; - } - } - - if (pid_nr(pObj->MLMEThr_pid) > 0) - { - printk("Terminate the MLMEThr_pid=%d!\n", pid_nr(pObj->MLMEThr_pid)); - mb(); - pAd->mlme_kill = 1; - //RT28XX_MLME_HANDLER(pAd); - mb(); - ret = kill_pid(pObj->MLMEThr_pid, SIGTERM, 1); - if (ret) - { - printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n", - pAd->net_dev->name, pid_nr(pObj->MLMEThr_pid), ret); - } - else - { - //wait_for_completion (&pAd->notify); - wait_for_completion (&pAd->mlmeComplete); - pObj->MLMEThr_pid = NULL; - } - } - - if (pid_nr(pObj->RTUSBCmdThr_pid) > 0) - { - printk("Terminate the RTUSBCmdThr_pid=%d!\n", pid_nr(pObj->RTUSBCmdThr_pid)); - mb(); - NdisAcquireSpinLock(&pAd->CmdQLock); - pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED; - NdisReleaseSpinLock(&pAd->CmdQLock); - mb(); - //RTUSBCMDUp(pAd); - ret = kill_pid(pObj->RTUSBCmdThr_pid, SIGTERM, 1); - if (ret) - { - printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n", - pAd->net_dev->name, pid_nr(pObj->RTUSBCmdThr_pid), ret); - } - else - { - //wait_for_completion (&pAd->notify); - wait_for_completion (&pAd->CmdQComplete); - pObj->RTUSBCmdThr_pid = NULL; - } - } - - // Kill tasklets - pAd->mlme_kill = 0; - pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN; - pAd->TimerFunc_kill = 0; -} - - -void kill_thread_task(IN PRTMP_ADAPTER pAd) -{ - POS_COOKIE pObj; - - pObj = (POS_COOKIE) pAd->OS_Cookie; - - tasklet_kill(&pObj->rx_done_task); - tasklet_kill(&pObj->mgmt_dma_done_task); - tasklet_kill(&pObj->ac0_dma_done_task); - tasklet_kill(&pObj->ac1_dma_done_task); - tasklet_kill(&pObj->ac2_dma_done_task); - tasklet_kill(&pObj->ac3_dma_done_task); - tasklet_kill(&pObj->hcca_dma_done_task); - tasklet_kill(&pObj->tbtt_task); - -} - - -/* -======================================================================== -Routine Description: - Check the chipset vendor/product ID. - -Arguments: - _dev_p Point to the PCI or USB device - -Return Value: - TRUE Check ok - FALSE Check fail - -Note: -======================================================================== -*/ -BOOLEAN RT28XXChipsetCheck( - IN void *_dev_p) -{ - struct usb_interface *intf = (struct usb_interface *)_dev_p; - struct usb_device *dev_p = interface_to_usbdev(intf); - UINT32 i; - - - for(i=0; idescriptor.idVendor == rtusb_usb_id[i].idVendor && - dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct) - { - printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n", - dev_p->descriptor.idVendor, dev_p->descriptor.idProduct); - break; - } - } - - if (i == rtusb_usb_id_len) - { - printk("rt2870: Error! Device Descriptor not matching!\n"); - return FALSE; - } - - return TRUE; -} - - -/* -======================================================================== -Routine Description: - Init net device structure. - -Arguments: - _dev_p Point to the PCI or USB device - *net_dev Point to the net device - *pAd the raxx interface data pointer - -Return Value: - TRUE Init ok - FALSE Init fail - -Note: -======================================================================== -*/ -BOOLEAN RT28XXNetDevInit( - IN void *_dev_p, - IN struct net_device *net_dev, - IN RTMP_ADAPTER *pAd) -{ - struct usb_interface *intf = (struct usb_interface *)_dev_p; - struct usb_device *dev_p = interface_to_usbdev(intf); - - - pAd->config = &dev_p->config->desc; - return TRUE; -} - - -/* -======================================================================== -Routine Description: - Init net device structure. - -Arguments: - _dev_p Point to the PCI or USB device - *pAd the raxx interface data pointer - -Return Value: - TRUE Config ok - FALSE Config fail - -Note: -======================================================================== -*/ -BOOLEAN RT28XXProbePostConfig( - IN void *_dev_p, - IN RTMP_ADAPTER *pAd, - IN INT32 interface) -{ - struct usb_interface *intf = (struct usb_interface *)_dev_p; - struct usb_host_interface *iface_desc; - ULONG BulkOutIdx; - UINT32 i; - - - /* get the active interface descriptor */ - iface_desc = intf->cur_altsetting; - - /* get # of enpoints */ - pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints; - DBGPRINT(RT_DEBUG_TRACE, - ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints)); - - /* Configure Pipes */ - BulkOutIdx = 0; - - for(i=0; iNumberOfPipes; i++) - { - if ((iface_desc->endpoint[i].desc.bmAttributes == - USB_ENDPOINT_XFER_BULK) && - ((iface_desc->endpoint[i].desc.bEndpointAddress & - USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)) - { - pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress; - pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize; - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize)); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress)); - } - else if ((iface_desc->endpoint[i].desc.bmAttributes == - USB_ENDPOINT_XFER_BULK) && - ((iface_desc->endpoint[i].desc.bEndpointAddress & - USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)) - { - // there are 6 bulk out EP. EP6 highest priority. - // EP1-4 is EDCA. EP5 is HCCA. - pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress; - pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize; - - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize)); - DBGPRINT_RAW(RT_DEBUG_TRACE, - ("EP address = 0x%2x \n", iface_desc->endpoint[i].desc.bEndpointAddress)); - } - } - - if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0])) - { - printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __func__); - return FALSE; - } - - return TRUE; -} - - -/* -======================================================================== -Routine Description: - Disable DMA. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -VOID RT28XXDMADisable( - IN RTMP_ADAPTER *pAd) -{ - // no use -} - - - -/* -======================================================================== -Routine Description: - Enable DMA. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -VOID RT28XXDMAEnable( - IN RTMP_ADAPTER *pAd) -{ - WPDMA_GLO_CFG_STRUC GloCfg; - USB_DMA_CFG_STRUC UsbCfg; - int i = 0; - - - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4); - do - { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) - break; - - DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n")); - RTMPusecDelay(1000); - i++; - }while ( i <200); - - - RTMPusecDelay(50); - GloCfg.field.EnTXWriteBackDDONE = 1; - GloCfg.field.EnableRxDMA = 1; - GloCfg.field.EnableTxDMA = 1; - DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word)); - RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word); - - UsbCfg.word = 0; - UsbCfg.field.phyclear = 0; - /* usb version is 1.1,do not use bulk in aggregation */ - if (pAd->BulkInMaxPacketSize == 512) - UsbCfg.field.RxBulkAggEn = 1; - /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */ - UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3; - UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */ - UsbCfg.field.RxBulkEn = 1; - UsbCfg.field.TxBulkEn = 1; - - RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word); - -} - -/* -======================================================================== -Routine Description: - Write Beacon buffer to Asic. - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -VOID RT28xx_UpdateBeaconToAsic( - IN RTMP_ADAPTER *pAd, - IN INT apidx, - IN ULONG FrameLen, - IN ULONG UpdatePos) -{ - PUCHAR pBeaconFrame = NULL; - UCHAR *ptr; - UINT i, padding; - BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync; - UINT32 longValue; - BOOLEAN bBcnReq = FALSE; - UCHAR bcn_idx = 0; - - - if (pBeaconFrame == NULL) - { - DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n")); - return; - } - - if (pBeaconSync == NULL) - { - DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n")); - return; - } - - //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) || - // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) - // ) - if (bBcnReq == FALSE) - { - /* when the ra interface is down, do not send its beacon frame */ - /* clear all zero */ - for(i=0; iBeaconOffset[bcn_idx] + i, 0x00); - } - pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx))); - NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE); - } - else - { - ptr = (PUCHAR)&pAd->BeaconTxWI; - - if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE) - { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames. - pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx))); - NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE); - } - - if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx)) - { - for (i=0; iBeaconOffset[bcn_idx] + i, longValue); - ptr += 4; - } - } - - ptr = pBeaconSync->BeaconBuf[bcn_idx]; - padding = (FrameLen & 0x01); - NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding); - FrameLen += padding; - for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2) - { - if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE) - { - NdisMoveMemory(ptr, pBeaconFrame, 2); - //shortValue = *ptr + (*(ptr+1)<<8); - //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue); - RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2); - } - ptr +=2; - pBeaconFrame += 2; - } - - pBeaconSync->BeaconBitMap |= (1 << bcn_idx); - - // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame. - } - -} - - -VOID RT2870_BssBeaconStop( - IN RTMP_ADAPTER *pAd) -{ - BEACON_SYNC_STRUCT *pBeaconSync; - int i, offset; - BOOLEAN Cancelled = TRUE; - - pBeaconSync = pAd->CommonCfg.pBeaconSync; - if (pBeaconSync && pBeaconSync->EnableBeacon) - { - INT NumOfBcn; - - NumOfBcn = MAX_MESH_NUM; - - RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled); - - for(i=0; iBeaconBuf[i], HW_BEACON_OFFSET); - NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); - - for (offset=0; offsetBeaconOffset[i] + offset, 0x00); - - pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; - pBeaconSync->TimIELocationInBeacon[i] = 0; - } - pBeaconSync->BeaconBitMap = 0; - pBeaconSync->DtimBitOn = 0; - } -} - - -VOID RT2870_BssBeaconStart( - IN RTMP_ADAPTER *pAd) -{ - int apidx; - BEACON_SYNC_STRUCT *pBeaconSync; -// LARGE_INTEGER tsfTime, deltaTime; - - pBeaconSync = pAd->CommonCfg.pBeaconSync; - if (pBeaconSync && pBeaconSync->EnableBeacon) - { - INT NumOfBcn; - - NumOfBcn = MAX_MESH_NUM; - - for(apidx=0; apidxBeaconBuf[apidx], HW_BEACON_OFFSET); - pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon; - pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon; - NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE); - } - pBeaconSync->BeaconBitMap = 0; - pBeaconSync->DtimBitOn = 0; - pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE; - - pAd->CommonCfg.BeaconAdjust = 0; - pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10); - pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1; - printk(RT28xx_CHIP_NAME "_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain); - RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod); - - } -} - - -VOID RT2870_BssBeaconInit( - IN RTMP_ADAPTER *pAd) -{ - BEACON_SYNC_STRUCT *pBeaconSync; - int i; - - NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG); - if (pAd->CommonCfg.pBeaconSync) - { - pBeaconSync = pAd->CommonCfg.pBeaconSync; - NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT)); - for(i=0; i < HW_BEACON_MAX_COUNT; i++) - { - NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET); - pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; - pBeaconSync->TimIELocationInBeacon[i] = 0; - NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); - } - pBeaconSync->BeaconBitMap = 0; - - //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE); - pBeaconSync->EnableBeacon = TRUE; - } -} - - -VOID RT2870_BssBeaconExit( - IN RTMP_ADAPTER *pAd) -{ - BEACON_SYNC_STRUCT *pBeaconSync; - BOOLEAN Cancelled = TRUE; - int i; - - if (pAd->CommonCfg.pBeaconSync) - { - pBeaconSync = pAd->CommonCfg.pBeaconSync; - pBeaconSync->EnableBeacon = FALSE; - RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled); - pBeaconSync->BeaconBitMap = 0; - - for(i=0; iBeaconBuf[i], HW_BEACON_OFFSET); - pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0; - pBeaconSync->TimIELocationInBeacon[i] = 0; - NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE); - } - - NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0); - pAd->CommonCfg.pBeaconSync = NULL; - } -} - -VOID BeaconUpdateExec( - IN PVOID SystemSpecific1, - IN PVOID FunctionContext, - IN PVOID SystemSpecific2, - IN PVOID SystemSpecific3) -{ - PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext; - LARGE_INTEGER tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab; - UINT32 delta, remain, remain_low, remain_high; -// BOOLEAN positive; - - ReSyncBeaconTime(pAd); - - - - RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart); - RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart); - - - //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp); - remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart; - remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10); - remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10); - delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain; - - pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10; - -} - Index: b/drivers/staging/rt2870/Makefile =================================================================== --- a/drivers/staging/rt2870/Makefile +++ b/drivers/staging/rt2870/Makefile @@ -1,27 +1,36 @@ +# obj-$(CONFIG_RT2870) += rt2870sta.o # TODO: all of these should be removed EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT -EXTRA_CFLAGS += -DRT2870 -DRT3070 +EXTRA_CFLAGS += -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT2870 -DRTMP_TIMER_TASK_SUPPORT +EXTRA_CFLAGS += -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRT30xx -DRT3070 EXTRA_CFLAGS += -DDBG rt2870sta-objs := \ - common/md5.o \ + common/crypt_md5.o \ + common/crypt_sha2.o \ + common/crypt_hmac.o \ common/mlme.o \ - common/rtmp_wep.o \ + common/cmm_wep.o \ common/action.o \ common/cmm_data.o \ common/rtmp_init.o \ - common/rtmp_tkip.o \ + common/cmm_tkip.o \ + common/cmm_aes.o \ common/cmm_sync.o \ common/eeprom.o \ common/cmm_sanity.o \ common/cmm_info.o \ + common/cmm_cfg.o \ common/cmm_wpa.o \ common/dfs.o \ common/spectrum.o \ + common/rtmp_timer.o \ + common/rt_channel.o \ + common/cmm_profile.o \ + common/cmm_asic.o \ sta/assoc.o \ - sta/aironet.o \ sta/auth.o \ sta/auth_rsp.o \ sta/sync.o \ @@ -34,10 +43,15 @@ rt2870sta-objs := \ rt_main_dev.o \ sta_ioctl.o \ common/ba_action.o \ - 2870_main_dev.o \ - common/2870_rtmp_init.o \ + usb_main_dev.o \ + rt_usb.o \ + common/cmm_mac_usb.o \ common/rtusb_io.o \ common/rtusb_bulk.o \ common/rtusb_data.o \ - common/cmm_data_2870.o - + common/cmm_data_usb.o \ + common/rtmp_mcu.o \ + common/ee_efuse.o \ + chips/rt30xx.o \ + common/rt_rf.o \ + chips/rt3070.o Index: b/drivers/staging/rt2870/chips/rt3070.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/chips/rt3070.c @@ -0,0 +1 @@ +#include "../../rt2860/chips/rt3070.c" Index: b/drivers/staging/rt2870/chips/rt30xx.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/chips/rt30xx.c @@ -0,0 +1 @@ +#include "../../rt2860/chips/rt30xx.c" Index: b/drivers/staging/rt2870/common/2870_rtmp_init.c =================================================================== --- a/drivers/staging/rt2870/common/2870_rtmp_init.c +++ /dev/null @@ -1,1730 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - - Module Name: - 2870_rtmp_init.c - - Abstract: - Miniport generic portion header file - - Revision History: - Who When What - -------- ---------- ---------------------------------------------- - Paul Lin 2002-08-01 created - John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme - Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT. - Sample Lin 2007-05-31 Merge RT2860 and RT2870 drivers. -*/ - -#include "../rt_config.h" - - -static void rx_done_tasklet(unsigned long data); -static void rt2870_hcca_dma_done_tasklet(unsigned long data); -static void rt2870_ac3_dma_done_tasklet(unsigned long data); -static void rt2870_ac2_dma_done_tasklet(unsigned long data); -static void rt2870_ac1_dma_done_tasklet(unsigned long data); -static void rt2870_ac0_dma_done_tasklet(unsigned long data); -static void rt2870_mgmt_dma_done_tasklet(unsigned long data); -static void rt2870_null_frame_complete_tasklet(unsigned long data); -static void rt2870_rts_frame_complete_tasklet(unsigned long data); -static void rt2870_pspoll_frame_complete_tasklet(unsigned long data); -static void rt2870_dataout_complete_tasklet(unsigned long data); - - -/* -======================================================================== -Routine Description: - Initialize receive data structures. - -Arguments: - pAd Pointer to our adapter - -Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_RESOURCES - -Note: - Initialize all receive releated private buffer, include those define - in RTMP_ADAPTER structure and all private data structures. The mahor - work is to allocate buffer for each packet and chain buffer to - NDIS packet descriptor. -======================================================================== -*/ -NDIS_STATUS NICInitRecv( - IN PRTMP_ADAPTER pAd) -{ - UCHAR i; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; - - - DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n")); - pObj = pObj; - - //InterlockedExchange(&pAd->PendingRx, 0); - pAd->PendingRx = 0; - pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index - pAd->NextRxBulkInIndex = 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer - pAd->NextRxBulkInPosition = 0; - - for (i = 0; i < (RX_RING_SIZE); i++) - { - PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); - - //Allocate URB - pRxContext->pUrb = RTUSB_ALLOC_URB(0); - if (pRxContext->pUrb == NULL) - { - Status = NDIS_STATUS_RESOURCES; - goto out1; - } - - // Allocate transfer buffer - pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma); - if (pRxContext->TransferBuffer == NULL) - { - Status = NDIS_STATUS_RESOURCES; - goto out1; - } - - NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE); - - pRxContext->pAd = pAd; - pRxContext->pIrp = NULL; - pRxContext->InUse = FALSE; - pRxContext->IRPPending = FALSE; - pRxContext->Readable = FALSE; - //pRxContext->ReorderInUse = FALSE; - pRxContext->bRxHandling = FALSE; - pRxContext->BulkInOffset = 0; - } - - DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv\n")); - return Status; - -out1: - for (i = 0; i < (RX_RING_SIZE); i++) - { - PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); - - if (NULL != pRxContext->TransferBuffer) - { - RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, - pRxContext->TransferBuffer, pRxContext->data_dma); - pRxContext->TransferBuffer = NULL; - } - - if (NULL != pRxContext->pUrb) - { - RTUSB_UNLINK_URB(pRxContext->pUrb); - RTUSB_FREE_URB(pRxContext->pUrb); - pRxContext->pUrb = NULL; - } - } - - return Status; -} - - -/* -======================================================================== -Routine Description: - Initialize transmit data structures. - -Arguments: - pAd Pointer to our adapter - -Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_RESOURCES - -Note: -======================================================================== -*/ -NDIS_STATUS NICInitTransmit( - IN PRTMP_ADAPTER pAd) -{ -#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \ - Context->pUrb = RTUSB_ALLOC_URB(0); \ - if (Context->pUrb == NULL) { \ - DBGPRINT(RT_DEBUG_ERROR, msg1); \ - Status = NDIS_STATUS_RESOURCES; \ - goto err1; } \ - \ - Context->TransferBuffer = \ - (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \ - if (Context->TransferBuffer == NULL) { \ - DBGPRINT(RT_DEBUG_ERROR, msg2); \ - Status = NDIS_STATUS_RESOURCES; \ - goto err2; } - -#define LM_URB_FREE(pObj, Context, BufferSize) \ - if (NULL != Context->pUrb) { \ - RTUSB_UNLINK_URB(Context->pUrb); \ - RTUSB_FREE_URB(Context->pUrb); \ - Context->pUrb = NULL; } \ - if (NULL != Context->TransferBuffer) { \ - RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \ - Context->TransferBuffer, \ - Context->data_dma); \ - Context->TransferBuffer = NULL; } - - UCHAR i, acidx; - NDIS_STATUS Status = NDIS_STATUS_SUCCESS; - PTX_CONTEXT pNullContext = &(pAd->NullContext); - PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext); - PTX_CONTEXT pRTSContext = &(pAd->RTSContext); - PTX_CONTEXT pMLMEContext = NULL; -// PHT_TX_CONTEXT pHTTXContext = NULL; - POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; - PVOID RingBaseVa; -// RTMP_TX_RING *pTxRing; - RTMP_MGMT_RING *pMgmtRing; - - DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n")); - pObj = pObj; - - // Init 4 set of Tx parameters - for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++) - { - // Initialize all Transmit releated queues - InitializeQueueHeader(&pAd->TxSwQueue[acidx]); - - // Next Local tx ring pointer waiting for buck out - pAd->NextBulkOutIndex[acidx] = acidx; - pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag - //pAd->DataBulkDoneIdx[acidx] = 0; - } - - //pAd->NextMLMEIndex = 0; - //pAd->PushMgmtIndex = 0; - //pAd->PopMgmtIndex = 0; - //InterlockedExchange(&pAd->MgmtQueueSize, 0); - //InterlockedExchange(&pAd->TxCount, 0); - - //pAd->PrioRingFirstIndex = 0; - //pAd->PrioRingTxCnt = 0; - - do - { - // - // TX_RING_SIZE, 4 ACs - // - for(acidx=0; acidx<4; acidx++) - { - PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); - - NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT)); - //Allocate URB - LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status, - ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx), - done, - ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx), - out1); - - NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4); - pHTTXContext->pAd = pAd; - pHTTXContext->pIrp = NULL; - pHTTXContext->IRPPending = FALSE; - pHTTXContext->NextBulkOutPosition = 0; - pHTTXContext->ENextBulkOutPosition = 0; - pHTTXContext->CurWritePosition = 0; - pHTTXContext->CurWriteRealPos = 0; - pHTTXContext->BulkOutSize = 0; - pHTTXContext->BulkOutPipeId = acidx; - pHTTXContext->bRingEmpty = TRUE; - pHTTXContext->bCopySavePad = FALSE; - - pAd->BulkOutPending[acidx] = FALSE; - } - - - // - // MGMT_RING_SIZE - // - // Allocate MGMT ring descriptor's memory - pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT); - RTMPAllocateMemory(&pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); - if (pAd->MgmtDescRing.AllocVa == NULL) - { - DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n")); - Status = NDIS_STATUS_RESOURCES; - goto out1; - } - NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); - RingBaseVa = pAd->MgmtDescRing.AllocVa; - - // Initialize MGMT Ring and associated buffer memory - pMgmtRing = &pAd->MgmtRing; - for (i = 0; i < MGMT_RING_SIZE; i++) - { - // link the pre-allocated Mgmt buffer to MgmtRing.Cell - pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT); - pMgmtRing->Cell[i].AllocVa = RingBaseVa; - pMgmtRing->Cell[i].pNdisPacket = NULL; - pMgmtRing->Cell[i].pNextNdisPacket = NULL; - - //Allocate URB for MLMEContext - pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa; - pMLMEContext->pUrb = RTUSB_ALLOC_URB(0); - if (pMLMEContext->pUrb == NULL) - { - DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i)); - Status = NDIS_STATUS_RESOURCES; - goto out2; - } - pMLMEContext->pAd = pAd; - pMLMEContext->pIrp = NULL; - pMLMEContext->TransferBuffer = NULL; - pMLMEContext->InUse = FALSE; - pMLMEContext->IRPPending = FALSE; - pMLMEContext->bWaitingBulkOut = FALSE; - pMLMEContext->BulkOutSize = 0; - pMLMEContext->SelfIdx = i; - - // Offset to next ring descriptor address - RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT); - } - DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i)); - - //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1); - pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE; - pAd->MgmtRing.TxCpuIdx = 0; - pAd->MgmtRing.TxDmaIdx = 0; - - // - // BEACON_RING_SIZE - // - for(i=0; iBeaconContext[i]); - - - NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT)); - - //Allocate URB - LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, - ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i), - out2, - ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i), - out3); - - pBeaconContext->pAd = pAd; - pBeaconContext->pIrp = NULL; - pBeaconContext->InUse = FALSE; - pBeaconContext->IRPPending = FALSE; - } - - // - // NullContext - // - NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT)); - - //Allocate URB - LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, - ("<-- ERROR in Alloc TX NullContext urb!! \n"), - out3, - ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"), - out4); - - pNullContext->pAd = pAd; - pNullContext->pIrp = NULL; - pNullContext->InUse = FALSE; - pNullContext->IRPPending = FALSE; - - // - // RTSContext - // - NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT)); - - //Allocate URB - LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, - ("<-- ERROR in Alloc TX RTSContext urb!! \n"), - out4, - ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"), - out5); - - pRTSContext->pAd = pAd; - pRTSContext->pIrp = NULL; - pRTSContext->InUse = FALSE; - pRTSContext->IRPPending = FALSE; - - // - // PsPollContext - // - //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT)); - //Allocate URB - LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status, - ("<-- ERROR in Alloc TX PsPollContext urb!! \n"), - out5, - ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"), - out6); - - pPsPollContext->pAd = pAd; - pPsPollContext->pIrp = NULL; - pPsPollContext->InUse = FALSE; - pPsPollContext->IRPPending = FALSE; - pPsPollContext->bAggregatible = FALSE; - pPsPollContext->LastOne = TRUE; - - } while (FALSE); - - -done: - DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit\n")); - - return Status; - - /* --------------------------- ERROR HANDLE --------------------------- */ -out6: - LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER)); - -out5: - LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER)); - -out4: - LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER)); - -out3: - for(i=0; iBeaconContext[i]); - if (pBeaconContext) - LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER)); - } - -out2: - if (pAd->MgmtDescRing.AllocVa) - { - pMgmtRing = &pAd->MgmtRing; - for(i=0; iMgmtRing.Cell[i].AllocVa; - if (pMLMEContext) - LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER)); - } - NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0); - pAd->MgmtDescRing.AllocVa = NULL; - } - -out1: - for (acidx = 0; acidx < 4; acidx++) - { - PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]); - if (pTxContext) - LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER)); - } - - // Here we didn't have any pre-allocated memory need to free. - - return Status; -} - - -/* -======================================================================== -Routine Description: - Allocate DMA memory blocks for send, receive. - -Arguments: - pAd Pointer to our adapter - -Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_FAILURE - NDIS_STATUS_RESOURCES - -Note: -======================================================================== -*/ -NDIS_STATUS RTMPAllocTxRxRingMemory( - IN PRTMP_ADAPTER pAd) -{ -// COUNTER_802_11 pCounter = &pAd->WlanCounters; - NDIS_STATUS Status; - INT num; - - - DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); - - - do - { - // Init the CmdQ and CmdQLock - NdisAllocateSpinLock(&pAd->CmdQLock); - NdisAcquireSpinLock(&pAd->CmdQLock); - RTUSBInitializeCmdQ(&pAd->CmdQ); - NdisReleaseSpinLock(&pAd->CmdQLock); - - - NdisAllocateSpinLock(&pAd->MLMEBulkOutLock); - //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock); - NdisAllocateSpinLock(&pAd->BulkOutLock[0]); - NdisAllocateSpinLock(&pAd->BulkOutLock[1]); - NdisAllocateSpinLock(&pAd->BulkOutLock[2]); - NdisAllocateSpinLock(&pAd->BulkOutLock[3]); - NdisAllocateSpinLock(&pAd->BulkOutLock[4]); - NdisAllocateSpinLock(&pAd->BulkOutLock[5]); - NdisAllocateSpinLock(&pAd->BulkInLock); - - for (num = 0; num < NUM_OF_TX_RING; num++) - { - NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]); - } - -// NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX - -// NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit() -// NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit() - -// for(num=0; numBATable.BARecEntry[num].RxReRingLock); -// } - - // - // Init Mac Table - // -// MacTableInitialize(pAd); - - // - // Init send data structures and related parameters - // - Status = NICInitTransmit(pAd); - if (Status != NDIS_STATUS_SUCCESS) - break; - - // - // Init receive data structures and related parameters - // - Status = NICInitRecv(pAd); - if (Status != NDIS_STATUS_SUCCESS) - break; - - pAd->PendingIoCount = 1; - - } while (FALSE); - - NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME)); - pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); - - if (pAd->FragFrame.pFragPacket == NULL) - { - Status = NDIS_STATUS_RESOURCES; - } - - DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); - return Status; -} - - -/* -======================================================================== -Routine Description: - Calls USB_InterfaceStop and frees memory allocated for the URBs - calls NdisMDeregisterDevice and frees the memory - allocated in VNetInitialize for the Adapter Object - -Arguments: - *pAd the raxx interface data pointer - -Return Value: - None - -Note: -======================================================================== -*/ -VOID RTMPFreeTxRxRingMemory( - IN PRTMP_ADAPTER pAd) -{ -#define LM_URB_FREE(pObj, Context, BufferSize) \ - if (NULL != Context->pUrb) { \ - RTUSB_UNLINK_URB(Context->pUrb); \ - RTUSB_FREE_URB(Context->pUrb); \ - Context->pUrb = NULL; } \ - if (NULL != Context->TransferBuffer) { \ - RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \ - Context->TransferBuffer, \ - Context->data_dma); \ - Context->TransferBuffer = NULL; } - - - UINT i, acidx; - PTX_CONTEXT pNullContext = &pAd->NullContext; - PTX_CONTEXT pPsPollContext = &pAd->PsPollContext; - PTX_CONTEXT pRTSContext = &pAd->RTSContext; -// PHT_TX_CONTEXT pHTTXContext; - //PRTMP_REORDERBUF pReorderBuf; - POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; -// RTMP_TX_RING *pTxRing; - - DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n")); - pObj = pObj; - - // Free all resources for the RECEIVE buffer queue. - for(i=0; i<(RX_RING_SIZE); i++) - { - PRX_CONTEXT pRxContext = &(pAd->RxContext[i]); - if (pRxContext) - LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE); - } - - // Free PsPoll frame resource - LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER)); - - // Free NULL frame resource - LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER)); - - // Free RTS frame resource - LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER)); - - - // Free beacon frame resource - for(i=0; iBeaconContext[i]); - if (pBeaconContext) - LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER)); - } - - - // Free mgmt frame resource - for(i = 0; i < MGMT_RING_SIZE; i++) - { - PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa; - //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER)); - if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) - { - RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket); - pAd->MgmtRing.Cell[i].pNdisPacket = NULL; - pMLMEContext->TransferBuffer = NULL; - } - - if (pMLMEContext) - { - if (NULL != pMLMEContext->pUrb) - { - RTUSB_UNLINK_URB(pMLMEContext->pUrb); - RTUSB_FREE_URB(pMLMEContext->pUrb); - pMLMEContext->pUrb = NULL; - } - } - } - if (pAd->MgmtDescRing.AllocVa) - NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0); - - - // Free Tx frame resource - for(acidx=0; acidx<4; acidx++) - { - PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]); - if (pHTTXContext) - LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER)); - } - - if (pAd->FragFrame.pFragPacket) - RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS); - - for(i=0; i<6; i++) - { - NdisFreeSpinLock(&pAd->BulkOutLock[i]); - } - - NdisFreeSpinLock(&pAd->BulkInLock); - NdisFreeSpinLock(&pAd->MLMEBulkOutLock); - - NdisFreeSpinLock(&pAd->CmdQLock); - - // Clear all pending bulk-out request flags. - RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff); - -// NdisFreeSpinLock(&pAd->MacTabLock); - -// for(i=0; iBATable.BARecEntry[i].RxReRingLock); -// } - - DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n")); -} - - -/* -======================================================================== -Routine Description: - Allocate memory for adapter control block. - -Arguments: - pAd Pointer to our adapter - -Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_FAILURE - NDIS_STATUS_RESOURCES - -Note: -======================================================================== -*/ -NDIS_STATUS AdapterBlockAllocateMemory( - IN PVOID handle, - OUT PVOID *ppAd) -{ - PUSB_DEV usb_dev; - POS_COOKIE pObj = (POS_COOKIE) handle; - - - usb_dev = pObj->pUsb_Dev; - - pObj->MLMEThr_pid = NULL; - pObj->RTUSBCmdThr_pid = NULL; - - *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER)); - - if (*ppAd) - { - NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER)); - ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle; - return (NDIS_STATUS_SUCCESS); - } - else - { - return (NDIS_STATUS_FAILURE); - } -} - - -/* -======================================================================== -Routine Description: - Create kernel threads & tasklets. - -Arguments: - *net_dev Pointer to wireless net device interface - -Return Value: - NDIS_STATUS_SUCCESS - NDIS_STATUS_FAILURE - -Note: -======================================================================== -*/ -NDIS_STATUS CreateThreads( - IN struct net_device *net_dev) -{ - PRTMP_ADAPTER pAd = net_dev->ml_priv; - POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; - pid_t pid_number; - - //init_MUTEX(&(pAd->usbdev_semaphore)); - - init_MUTEX_LOCKED(&(pAd->mlme_semaphore)); - init_completion (&pAd->mlmeComplete); - - init_MUTEX_LOCKED(&(pAd->RTUSBCmd_semaphore)); - init_completion (&pAd->CmdQComplete); - - init_MUTEX_LOCKED(&(pAd->RTUSBTimer_semaphore)); - init_completion (&pAd->TimerQComplete); - - // Creat MLME Thread - pObj->MLMEThr_pid = NULL; - pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM); - if (pid_number < 0) - { - printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name); - return NDIS_STATUS_FAILURE; - } - - pObj->MLMEThr_pid = find_get_pid(pid_number); - - // Wait for the thread to start - wait_for_completion(&(pAd->mlmeComplete)); - - // Creat Command Thread - pObj->RTUSBCmdThr_pid = NULL; - pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM); - if (pid_number < 0) - { - printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name); - return NDIS_STATUS_FAILURE; - } - - pObj->RTUSBCmdThr_pid = find_get_pid(pid_number); - - wait_for_completion(&(pAd->CmdQComplete)); - - pObj->TimerQThr_pid = NULL; - pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM); - if (pid_number < 0) - { - printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name); - return NDIS_STATUS_FAILURE; - } - - pObj->TimerQThr_pid = find_get_pid(pid_number); - - // Wait for the thread to start - wait_for_completion(&(pAd->TimerQComplete)); - - // Create receive tasklet - tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd); - tasklet_init(&pObj->mgmt_dma_done_task, rt2870_mgmt_dma_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->ac0_dma_done_task, rt2870_ac0_dma_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->ac1_dma_done_task, rt2870_ac1_dma_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->ac2_dma_done_task, rt2870_ac2_dma_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->ac3_dma_done_task, rt2870_ac3_dma_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->hcca_dma_done_task, rt2870_hcca_dma_done_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->null_frame_complete_task, rt2870_null_frame_complete_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->rts_frame_complete_task, rt2870_rts_frame_complete_tasklet, (unsigned long)pAd); - tasklet_init(&pObj->pspoll_frame_complete_task, rt2870_pspoll_frame_complete_tasklet, (unsigned long)pAd); - - return NDIS_STATUS_SUCCESS; -} - -/* -======================================================================== -Routine Description: - As STA's BSSID is a WC too, it uses shared key table. - This function write correct unicast TX key to ASIC WCID. - And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey. - Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key) - Caller guarantee WEP calls this function when set Txkey, default key index=0~3. - -Arguments: - pAd Pointer to our adapter - pKey Pointer to the where the key stored - -Return Value: - NDIS_SUCCESS Add key successfully - -Note: -======================================================================== -*/ -VOID RTMPAddBSSIDCipher( - IN PRTMP_ADAPTER pAd, - IN UCHAR Aid, - IN PNDIS_802_11_KEY pKey, - IN UCHAR CipherAlg) -{ - PUCHAR pTxMic, pRxMic; - BOOLEAN bKeyRSC, bAuthenticator; // indicate the receive SC set by KeyRSC value -// UCHAR CipherAlg; - UCHAR i; - ULONG WCIDAttri; - USHORT offset; - UCHAR KeyIdx, IVEIV[8]; - UINT32 Value; - - DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddBSSIDCipher==> Aid = %d\n",Aid)); - - // Bit 29 of Add-key KeyRSC - bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE; - - // Bit 28 of Add-key Authenticator - bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE; - KeyIdx = (UCHAR)pKey->KeyIndex&0xff; - - if (KeyIdx > 4) - return; - - - if (pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg == CIPHER_TKIP) - { if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) - { - // for WPA-None Tx, Rx MIC is the same - pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16; - pRxMic = pTxMic; - } - else if (bAuthenticator == TRUE) - { - pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16; - pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 24; - } - else - { - pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 16; - pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 24; - } - - offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x10; - for (i=0; i<8; ) - { - Value = *(pTxMic+i); - Value += (*(pTxMic+i+1)<<8); - Value += (*(pTxMic+i+2)<<16); - Value += (*(pTxMic+i+3)<<24); - RTUSBWriteMACRegister(pAd, offset+i, Value); - i+=4; - } - - offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x18; - for (i=0; i<8; ) - { - Value = *(pRxMic+i); - Value += (*(pRxMic+i+1)<<8); - Value += (*(pRxMic+i+2)<<16); - Value += (*(pRxMic+i+3)<<24); - RTUSBWriteMACRegister(pAd, offset+i, Value); - i+=4; - } - - // Only Key lenth equal to TKIP key have these - NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxMic, pRxMic, 8); - NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.TxMic, pTxMic, 8); - - DBGPRINT(RT_DEBUG_TRACE, - (" TxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n", - pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3], - pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7])); - DBGPRINT(RT_DEBUG_TRACE, - (" RxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n", - pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3], - pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7])); - } - - // 2. Record Security Key. - pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen= (UCHAR)pKey->KeyLength; - NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength); - - // 3. Check RxTsc. And used to init to ASIC IV. - if (bKeyRSC == TRUE) - NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, &pKey->KeyRSC, 6); - else - NdisZeroMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, 6); - - // 4. Init TxTsc to one based on WiFi WPA specs - pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[0] = 1; - pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[1] = 0; - pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[2] = 0; - pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[3] = 0; - pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[4] = 0; - pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[5] = 0; - - CipherAlg = pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg; - - offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE); - RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial, - ((pKey->KeyLength == LEN_TKIP_KEY) ? 16 : (USHORT)pKey->KeyLength)); - - offset = SHARED_KEY_TABLE_BASE + (KeyIdx * HW_KEY_ENTRY_SIZE); - RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial, (USHORT)pKey->KeyLength); - - offset = PAIRWISE_IVEIV_TABLE_BASE + (Aid * HW_IVEIV_ENTRY_SIZE); - NdisZeroMemory(IVEIV, 8); - - // IV/EIV - if ((CipherAlg == CIPHER_TKIP) || - (CipherAlg == CIPHER_TKIP_NO_MIC) || - (CipherAlg == CIPHER_AES)) - { - IVEIV[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key - } - // default key idx needs to set. - // in TKIP/AES KeyIdx = 0 , WEP KeyIdx is default tx key. - else - { - IVEIV[3] |= (KeyIdx<< 6); - } - RTUSBMultiWrite(pAd, (USHORT) offset, IVEIV, 8); - - // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0 - if ((CipherAlg == CIPHER_TKIP) || - (CipherAlg == CIPHER_TKIP_NO_MIC) || - (CipherAlg == CIPHER_AES)) - { - WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE; - } - else - WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE; - - offset = MAC_WCID_ATTRIBUTE_BASE + (Aid* HW_WCID_ATTRI_SIZE); - RTUSBWriteMACRegister(pAd, offset, WCIDAttri); - RTUSBReadMACRegister(pAd, offset, &Value); - - DBGPRINT(RT_DEBUG_TRACE, ("BSSID_WCID : offset = %x, WCIDAttri = %lx\n", - offset, WCIDAttri)); - - // pAddr - // Add Bssid mac address at linkup. not here. check! - /*offset = MAC_WCID_BASE + (BSSID_WCID * HW_WCID_ENTRY_SIZE); - *for (i=0; iBSSID[i]); - } - */ - - DBGPRINT(RT_DEBUG_ERROR, ("AddBSSIDasWCIDEntry: Alg=%s, KeyLength = %d\n", - CipherName[CipherAlg], pKey->KeyLength)); - DBGPRINT(RT_DEBUG_TRACE, ("Key [idx=%x] [KeyLen = %d]\n", - pKey->KeyIndex, pKey->KeyLength)); - for(i=0; iKeyLength; i++) - DBGPRINT_RAW(RT_DEBUG_TRACE,(" %x:", pKey->KeyMaterial[i])); - DBGPRINT(RT_DEBUG_TRACE,(" \n")); -} - -/* -======================================================================== -Routine Description: - Get a received packet. - -Arguments: - pAd device control block - pSaveRxD receive descriptor information - *pbReschedule need reschedule flag - *pRxPending pending received packet flag - -Return Value: - the recieved packet - -Note: -======================================================================== -*/ -#define RT2870_RXDMALEN_FIELD_SIZE 4 -PNDIS_PACKET GetPacketFromRxRing( - IN PRTMP_ADAPTER pAd, - OUT PRT28XX_RXD_STRUC pSaveRxD, - OUT BOOLEAN *pbReschedule, - IN OUT UINT32 *pRxPending) -{ - PRX_CONTEXT pRxContext; - PNDIS_PACKET pSkb; - PUCHAR pData; - ULONG ThisFrameLen; - ULONG RxBufferLength; - PRXWI_STRUC pRxWI; - - pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex]; - if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE)) - return NULL; - - RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition; - if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC))) - { - goto label_null; - } - - pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */ - // The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding) - ThisFrameLen = *pData + (*(pData+1)<<8); - if (ThisFrameLen == 0) - { - DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n", - pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset)); - goto label_null; - } - if ((ThisFrameLen&0x3) != 0) - { - DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n", - pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset)); - goto label_null; - } - - if ((ThisFrameLen + 8)> RxBufferLength) // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC)) - { - DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n", - pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition)); - - // error frame. finish this loop - goto label_null; - } - - // skip USB frame length field - pData += RT2870_RXDMALEN_FIELD_SIZE; - pRxWI = (PRXWI_STRUC)pData; - - if (pRxWI->MPDUtotalByteCount > ThisFrameLen) - { - DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n", - __func__, pRxWI->MPDUtotalByteCount, ThisFrameLen)); - goto label_null; - } - - // allocate a rx packet - pSkb = dev_alloc_skb(ThisFrameLen); - if (pSkb == NULL) - { - DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __func__)); - goto label_null; - } - - // copy the rx packet - memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen); - RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0); - RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS); - - // copy RxD - *pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen); - - // update next packet read position. - pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC)) - - return pSkb; - -label_null: - - return NULL; -} - - -/* -======================================================================== -Routine Description: - Handle received packets. - -Arguments: - data - URB information pointer - -Return Value: - None - -Note: -======================================================================== -*/ -static void rx_done_tasklet(unsigned long data) -{ - purbb_t pUrb; - PRX_CONTEXT pRxContext; - PRTMP_ADAPTER pAd; - NTSTATUS Status; - unsigned int IrqFlags; - - pUrb = (purbb_t)data; - pRxContext = (PRX_CONTEXT)pUrb->context; - pAd = pRxContext->pAd; - Status = pUrb->status; - - - RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); - pRxContext->InUse = FALSE; - pRxContext->IRPPending = FALSE; - pRxContext->BulkInOffset += pUrb->actual_length; - //NdisInterlockedDecrement(&pAd->PendingRx); - pAd->PendingRx--; - - if (Status == USB_ST_NOERROR) - { - pAd->BulkInComplete++; - pAd->NextRxBulkInPosition = 0; - if (pRxContext->BulkInOffset) // As jan's comment, it may bulk-in success but size is zero. - { - pRxContext->Readable = TRUE; - INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE); - } - RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - } - else // STATUS_OTHER - { - pAd->BulkInCompleteFail++; - // Still read this packet although it may comtain wrong bytes. - pRxContext->Readable = FALSE; - RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); - - // Parsing all packets. because after reset, the index will reset to all zero. - if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_BULKIN_RESET | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) - { - - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n", - Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length)); - - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET); - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0); - } - } - - ASSERT((pRxContext->InUse == pRxContext->IRPPending)); - - RTUSBBulkReceive(pAd); - - return; - -} - - -static void rt2870_mgmt_dma_done_tasklet(unsigned long data) -{ - PRTMP_ADAPTER pAd; - PTX_CONTEXT pMLMEContext; - int index; - PNDIS_PACKET pPacket; - purbb_t pUrb; - NTSTATUS Status; - unsigned long IrqFlags; - - - pUrb = (purbb_t)data; - pMLMEContext = (PTX_CONTEXT)pUrb->context; - pAd = pMLMEContext->pAd; - Status = pUrb->status; - index = pMLMEContext->SelfIdx; - - ASSERT((pAd->MgmtRing.TxDmaIdx == index)); - - RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); - - - if (Status != USB_ST_NOERROR) - { - //Bulk-Out fail status handle - if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) - { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status)); - // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt? - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); - pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); - } - } - - pAd->BulkOutPending[MGMTPIPEIDX] = FALSE; - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags); - - RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); - // Reset MLME context flags - pMLMEContext->IRPPending = FALSE; - pMLMEContext->InUse = FALSE; - pMLMEContext->bWaitingBulkOut = FALSE; - pMLMEContext->BulkOutSize = 0; - - pPacket = pAd->MgmtRing.Cell[index].pNdisPacket; - pAd->MgmtRing.Cell[index].pNdisPacket = NULL; - - // Increase MgmtRing Index - INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE); - pAd->MgmtRing.TxSwFreeIdx++; - RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); - - // No-matter success or fail, we free the mgmt packet. - if (pPacket) - RTMPFreeNdisPacket(pAd, pPacket); - - if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) - { - // do nothing and return directly. - } - else - { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) && - ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)) - { // For Mgmt Bulk-Out failed, ignore it now. - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); - } - else - { - - // Always call Bulk routine, even reset bulk. - // The protectioon of rest bulk should be in BulkOut routine - if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */) - { - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); - } - RTUSBKickBulkOut(pAd); - } - } - -} - - -static void rt2870_hcca_dma_done_tasklet(unsigned long data) -{ - PRTMP_ADAPTER pAd; - PHT_TX_CONTEXT pHTTXContext; - UCHAR BulkOutPipeId = 4; - purbb_t pUrb; - - DBGPRINT_RAW(RT_DEBUG_ERROR, ("--->hcca_dma_done_tasklet\n")); - - pUrb = (purbb_t)data; - pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; - pAd = pHTTXContext->pAd; - - rt2870_dataout_complete_tasklet((unsigned long)pUrb); - - if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) - { - // do nothing and return directly. - } - else - { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) - { - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); - } - else - { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; - if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && - /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ - (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && - (pHTTXContext->bCurWriting == FALSE)) - { - RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); - } - - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<4); - RTUSBKickBulkOut(pAd); - } - } - - DBGPRINT_RAW(RT_DEBUG_ERROR, ("<---hcca_dma_done_tasklet\n")); -} - - -static void rt2870_ac3_dma_done_tasklet(unsigned long data) -{ - PRTMP_ADAPTER pAd; - PHT_TX_CONTEXT pHTTXContext; - UCHAR BulkOutPipeId = 3; - purbb_t pUrb; - - - pUrb = (purbb_t)data; - pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; - pAd = pHTTXContext->pAd; - - rt2870_dataout_complete_tasklet((unsigned long)pUrb); - - if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) - { - // do nothing and return directly. - } - else - { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) - { - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); - } - else - { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; - if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && - /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ - (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && - (pHTTXContext->bCurWriting == FALSE)) - { - RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); - } - - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3); - RTUSBKickBulkOut(pAd); - } - } - - - return; -} - - -static void rt2870_ac2_dma_done_tasklet(unsigned long data) -{ - PRTMP_ADAPTER pAd; - PHT_TX_CONTEXT pHTTXContext; - UCHAR BulkOutPipeId = 2; - purbb_t pUrb; - - - pUrb = (purbb_t)data; - pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; - pAd = pHTTXContext->pAd; - - rt2870_dataout_complete_tasklet((unsigned long)pUrb); - - if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) - { - // do nothing and return directly. - } - else - { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) - { - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); - } - else - { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; - if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && - /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ - (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && - (pHTTXContext->bCurWriting == FALSE)) - { - RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); - } - - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2); - RTUSBKickBulkOut(pAd); - } - } - - return; -} - - -static void rt2870_ac1_dma_done_tasklet(unsigned long data) -{ - PRTMP_ADAPTER pAd; - PHT_TX_CONTEXT pHTTXContext; - UCHAR BulkOutPipeId = 1; - purbb_t pUrb; - - - pUrb = (purbb_t)data; - pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; - pAd = pHTTXContext->pAd; - - rt2870_dataout_complete_tasklet((unsigned long)pUrb); - - if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) - { - // do nothing and return directly. - } - else - { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) - { - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); - } - else - { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; - if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && - /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ - (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && - (pHTTXContext->bCurWriting == FALSE)) - { - RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); - } - - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1); - RTUSBKickBulkOut(pAd); - } - } - - - return; -} - - -static void rt2870_ac0_dma_done_tasklet(unsigned long data) -{ - PRTMP_ADAPTER pAd; - PHT_TX_CONTEXT pHTTXContext; - UCHAR BulkOutPipeId = 0; - purbb_t pUrb; - - - pUrb = (purbb_t)data; - pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; - pAd = pHTTXContext->pAd; - - rt2870_dataout_complete_tasklet((unsigned long)pUrb); - - if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST)))) - { - // do nothing and return directly. - } - else - { - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) - { - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); - } - else - { pHTTXContext = &pAd->TxContext[BulkOutPipeId]; - if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) && - /* ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */ - (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) && - (pHTTXContext->bCurWriting == FALSE)) - { - RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS); - } - - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL); - RTUSBKickBulkOut(pAd); - } - } - - - return; - -} - - -static void rt2870_null_frame_complete_tasklet(unsigned long data) -{ - PRTMP_ADAPTER pAd; - PTX_CONTEXT pNullContext; - purbb_t pUrb; - NTSTATUS Status; - unsigned long irqFlag; - - - pUrb = (purbb_t)data; - pNullContext = (PTX_CONTEXT)pUrb->context; - pAd = pNullContext->pAd; - Status = pUrb->status; - - // Reset Null frame context flags - RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag); - pNullContext->IRPPending = FALSE; - pNullContext->InUse = FALSE; - pAd->BulkOutPending[0] = FALSE; - pAd->watchDogTxPendingCnt[0] = 0; - - if (Status == USB_ST_NOERROR) - { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); - - RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); - } - else // STATUS_OTHER - { - if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) - { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status)); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); - pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); - } - else - { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); - } - } - - // Always call Bulk routine, even reset bulk. - // The protectioon of rest bulk should be in BulkOut routine - RTUSBKickBulkOut(pAd); - -} - - -static void rt2870_rts_frame_complete_tasklet(unsigned long data) -{ - PRTMP_ADAPTER pAd; - PTX_CONTEXT pRTSContext; - purbb_t pUrb; - NTSTATUS Status; - unsigned long irqFlag; - - - pUrb = (purbb_t)data; - pRTSContext = (PTX_CONTEXT)pUrb->context; - pAd = pRTSContext->pAd; - Status = pUrb->status; - - // Reset RTS frame context flags - RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag); - pRTSContext->IRPPending = FALSE; - pRTSContext->InUse = FALSE; - - if (Status == USB_ST_NOERROR) - { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); - RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); - } - else // STATUS_OTHER - { - if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) - { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n")); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); - pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); - } - else - { - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag); - } - } - - RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]); - pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE; - RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]); - - // Always call Bulk routine, even reset bulk. - // The protectioon of rest bulk should be in BulkOut routine - RTUSBKickBulkOut(pAd); - -} - - -static void rt2870_pspoll_frame_complete_tasklet(unsigned long data) -{ - PRTMP_ADAPTER pAd; - PTX_CONTEXT pPsPollContext; - purbb_t pUrb; - NTSTATUS Status; - - - pUrb = (purbb_t)data; - pPsPollContext = (PTX_CONTEXT)pUrb->context; - pAd = pPsPollContext->pAd; - Status = pUrb->status; - - // Reset PsPoll context flags - pPsPollContext->IRPPending = FALSE; - pPsPollContext->InUse = FALSE; - pAd->watchDogTxPendingCnt[0] = 0; - - if (Status == USB_ST_NOERROR) - { - RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS); - } - else // STATUS_OTHER - { - if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) - { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n")); - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); - pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG); - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0); - } - } - - RTMP_SEM_LOCK(&pAd->BulkOutLock[0]); - pAd->BulkOutPending[0] = FALSE; - RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]); - - // Always call Bulk routine, even reset bulk. - // The protectioon of rest bulk should be in BulkOut routine - RTUSBKickBulkOut(pAd); - -} - - -static void rt2870_dataout_complete_tasklet(unsigned long data) -{ - PRTMP_ADAPTER pAd; - purbb_t pUrb; - POS_COOKIE pObj; - PHT_TX_CONTEXT pHTTXContext; - UCHAR BulkOutPipeId; - NTSTATUS Status; - unsigned long IrqFlags; - - - pUrb = (purbb_t)data; - pHTTXContext = (PHT_TX_CONTEXT)pUrb->context; - pAd = pHTTXContext->pAd; - pObj = (POS_COOKIE) pAd->OS_Cookie; - Status = pUrb->status; - - // Store BulkOut PipeId - BulkOutPipeId = pHTTXContext->BulkOutPipeId; - pAd->BulkOutDataOneSecCount++; - - //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition, - // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); - - RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - pAd->BulkOutPending[BulkOutPipeId] = FALSE; - pHTTXContext->IRPPending = FALSE; - pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0; - - if (Status == USB_ST_NOERROR) - { - pAd->BulkOutComplete++; - - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - - pAd->Counters8023.GoodTransmits++; - //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); - FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext); - //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); - - - } - else // STATUS_OTHER - { - PUCHAR pBuf; - - pAd->BulkOutCompleteOther++; - - pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition]; - - if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | - fRTMP_ADAPTER_HALT_IN_PROGRESS | - fRTMP_ADAPTER_NIC_NOT_EXIST | - fRTMP_ADAPTER_BULKOUT_RESET))) - { - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET); - pAd->bulkResetPipeid = BulkOutPipeId; - pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq; - } - RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags); - - DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status)); - DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther)); - DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7])); - //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther)); - - } - - // - // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut - // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. - // - //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); - if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) && - (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) && - !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId))) - { - // Indicate There is data avaliable - RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); - } - //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); - - // Always call Bulk routine, even reset bulk. - // The protection of rest bulk should be in BulkOut routine - RTUSBKickBulkOut(pAd); -} - -/* End of 2870_rtmp_init.c */ Index: b/drivers/staging/rt2870/common/acction.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/acction.c @@ -0,0 +1 @@ +#include "../../rt2860/common/action.c" Index: b/drivers/staging/rt2870/common/cmm_aes.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/cmm_aes.c @@ -0,0 +1 @@ +#include "../../rt2860/common/cmm_aes.c" Index: b/drivers/staging/rt2870/common/cmm_asic.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/cmm_asic.c @@ -0,0 +1 @@ +#include "../../rt2860/common/cmm_asic.c" Index: b/drivers/staging/rt2870/common/cmm_cfg.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/cmm_cfg.c @@ -0,0 +1 @@ +#include "../../rt2860/common/cmm_cfg.c" Index: b/drivers/staging/rt2870/common/cmm_data_2870.c =================================================================== --- a/drivers/staging/rt2870/common/cmm_data_2870.c +++ /dev/null @@ -1,936 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* -*/ -/* - All functions in this file must be USB-depended, or you should out your function - in other files. - -*/ -#include "../rt_config.h" - - -/* - We can do copy the frame into pTxContext when match following conditions. - => - => - => -*/ -static inline NDIS_STATUS RtmpUSBCanDoWrite( - IN RTMP_ADAPTER *pAd, - IN UCHAR QueIdx, - IN HT_TX_CONTEXT *pHTTXContext) -{ - NDIS_STATUS canWrite = NDIS_STATUS_RESOURCES; - - if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition) - { - DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n")); - RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); - } - else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE)) - { - DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n")); - RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); - } - else if (pHTTXContext->bCurWriting == TRUE) - { - DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n")); - } - else - { - canWrite = NDIS_STATUS_SUCCESS; - } - - - return canWrite; -} - - -USHORT RtmpUSB_WriteSubTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN BOOLEAN bIsLast, - OUT USHORT *FreeNumber) -{ - - // Dummy function. Should be removed in the future. - return 0; - -} - -USHORT RtmpUSB_WriteFragTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN UCHAR fragNum, - OUT USHORT *FreeNumber) -{ - HT_TX_CONTEXT *pHTTXContext; - USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length. - UINT32 fillOffset; - TXINFO_STRUC *pTxInfo; - TXWI_STRUC *pTxWI; - PUCHAR pWirelessPacket = NULL; - UCHAR QueIdx; - NDIS_STATUS Status; - unsigned long IrqFlags; - UINT32 USBDMApktLen = 0, DMAHdrLen, padding; - BOOLEAN TxQLastRound = FALSE; - - // - // get Tx Ring Resource & Dma Buffer address - // - QueIdx = pTxBlk->QueIdx; - pHTTXContext = &pAd->TxContext[QueIdx]; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - pHTTXContext = &pAd->TxContext[QueIdx]; - fillOffset = pHTTXContext->CurWritePosition; - - if(fragNum == 0) - { - // Check if we have enough space for this bulk-out batch. - Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); - if (Status == NDIS_STATUS_SUCCESS) - { - pHTTXContext->bCurWriting = TRUE; - - // Reserve space for 8 bytes padding. - if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) - { - pHTTXContext->ENextBulkOutPosition += 8; - pHTTXContext->CurWritePosition += 8; - fillOffset += 8; - } - pTxBlk->Priv = 0; - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - } - else - { - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); - return(Status); - } - } - else - { - // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. - Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE); - if (Status == NDIS_STATUS_SUCCESS) - { - fillOffset += pTxBlk->Priv; - } - else - { - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE); - return(Status); - } - } - - NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE); - pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); - pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); - - pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; - - // copy TXWI + WLAN Header + LLC into DMA Header Buffer - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); - hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - // Build our URB for USBD - DMAHdrLen = TXWI_SIZE + hwHdrLen; - USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen; - padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment - USBDMApktLen += padding; - - pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen); - - // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload - RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); - - if (fragNum == pTxBlk->TotalFragNum) - { - pTxInfo->USBDMATxburst = 0; - if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT) - { - pTxInfo->SwUseLastRound = 1; - TxQLastRound = TRUE; - } - } - else - { - pTxInfo->USBDMATxburst = 1; - } - - NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); - - // Zero the last padding. - pWirelessPacket += pTxBlk->SrcBufLen; - NdisZeroMemory(pWirelessPacket, padding + 8); - - if (fragNum == pTxBlk->TotalFragNum) - { - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - // Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame. - pHTTXContext->CurWritePosition += pTxBlk->Priv; - if (TxQLastRound == TRUE) - pHTTXContext->CurWritePosition = 8; - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - - // Finally, set bCurWriting as FALSE - pHTTXContext->bCurWriting = FALSE; - - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - // succeed and release the skb buffer - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); - } - - - return(Status); - -} - - -USHORT RtmpUSB_WriteSingleTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN BOOLEAN bIsLast, - OUT USHORT *FreeNumber) -{ - HT_TX_CONTEXT *pHTTXContext; - USHORT hwHdrLen; - UINT32 fillOffset; - TXINFO_STRUC *pTxInfo; - TXWI_STRUC *pTxWI; - PUCHAR pWirelessPacket; - UCHAR QueIdx; - unsigned long IrqFlags; - NDIS_STATUS Status; - UINT32 USBDMApktLen = 0, DMAHdrLen, padding; - BOOLEAN bTxQLastRound = FALSE; - - // For USB, didn't need PCI_MAP_SINGLE() - //SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE); - - - // - // get Tx Ring Resource & Dma Buffer address - // - QueIdx = pTxBlk->QueIdx; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - pHTTXContext = &pAd->TxContext[QueIdx]; - fillOffset = pHTTXContext->CurWritePosition; - - - - // Check ring full. - Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); - if(Status == NDIS_STATUS_SUCCESS) - { - pHTTXContext->bCurWriting = TRUE; - - pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); - pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); - - // Reserve space for 8 bytes padding. - if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) - { - pHTTXContext->ENextBulkOutPosition += 8; - pHTTXContext->CurWritePosition += 8; - fillOffset += 8; - } - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; - - // copy TXWI + WLAN Header + LLC into DMA Header Buffer - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); - hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - // Build our URB for USBD - DMAHdrLen = TXWI_SIZE + hwHdrLen; - USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen; - padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment - USBDMApktLen += padding; - - pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen); - - // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload - //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) - RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); - - if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT) - { - pTxInfo->SwUseLastRound = 1; - bTxQLastRound = TRUE; - } - NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - - // We unlock it here to prevent the first 8 bytes maybe over-writed issue. - // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext. - // 2. An interrupt break our routine and handle bulk-out complete. - // 3. In the bulk-out compllete, it need to do another bulk-out, - // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, - // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. - // 4. Interrupt complete. - // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. - // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. - // and the packet will wrong. - pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen); - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); - pWirelessPacket += pTxBlk->SrcBufLen; - NdisZeroMemory(pWirelessPacket, padding + 8); - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - pHTTXContext->CurWritePosition += pTxBlk->Priv; - if (bTxQLastRound) - pHTTXContext->CurWritePosition = 8; - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - pHTTXContext->bCurWriting = FALSE; - } - - - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - - // succeed and release the skb buffer - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); - - return(Status); - -} - - -USHORT RtmpUSB_WriteMultiTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN UCHAR frameNum, - OUT USHORT *FreeNumber) -{ - HT_TX_CONTEXT *pHTTXContext; - USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length. - UINT32 fillOffset; - TXINFO_STRUC *pTxInfo; - TXWI_STRUC *pTxWI; - PUCHAR pWirelessPacket = NULL; - UCHAR QueIdx; - NDIS_STATUS Status; - unsigned long IrqFlags; - //UINT32 USBDMApktLen = 0, DMAHdrLen, padding; - - // - // get Tx Ring Resource & Dma Buffer address - // - QueIdx = pTxBlk->QueIdx; - pHTTXContext = &pAd->TxContext[QueIdx]; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - if(frameNum == 0) - { - // Check if we have enough space for this bulk-out batch. - Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext); - if (Status == NDIS_STATUS_SUCCESS) - { - pHTTXContext->bCurWriting = TRUE; - - pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]); - pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]); - - - // Reserve space for 8 bytes padding. - if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)) - { - - pHTTXContext->CurWritePosition += 8; - pHTTXContext->ENextBulkOutPosition += 8; - } - fillOffset = pHTTXContext->CurWritePosition; - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; - - // - // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer - // - if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; - hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD; - else if (pTxBlk->TxFrameType == TX_RALINK_FRAME) - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; - hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD; - else - //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); - hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen; - - // Update the pTxBlk->Priv. - pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen; - - // pTxInfo->USBDMApktLen now just a temp value and will to correct latter. - RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE); - - // Copy it. - NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv); - pHTTXContext->CurWriteRealPos += pTxBlk->Priv; - pWirelessPacket += pTxBlk->Priv; - } - } - else - { // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. - - Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE); - if (Status == NDIS_STATUS_SUCCESS) - { - fillOffset = (pHTTXContext->CurWritePosition + pTxBlk->Priv); - pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]; - - //hwHdrLen = pTxBlk->MpduHeaderLen; - NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen); - pWirelessPacket += (pTxBlk->MpduHeaderLen); - pTxBlk->Priv += pTxBlk->MpduHeaderLen; - } - else - { // It should not happened now unless we are going to shutdown. - DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n")); - Status = NDIS_STATUS_FAILURE; - } - } - - - // We unlock it here to prevent the first 8 bytes maybe over-write issue. - // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext. - // 2. An interrupt break our routine and handle bulk-out complete. - // 3. In the bulk-out compllete, it need to do another bulk-out, - // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, - // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. - // 4. Interrupt complete. - // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. - // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. - // and the packet will wrong. - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - if (Status != NDIS_STATUS_SUCCESS) - { - DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition)); - goto done; - } - - // Copy the frame content into DMA buffer and update the pTxBlk->Priv - NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen); - pWirelessPacket += pTxBlk->SrcBufLen; - pTxBlk->Priv += pTxBlk->SrcBufLen; - -done: - // Release the skb buffer here - RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS); - - return(Status); - -} - - -VOID RtmpUSB_FinalWriteTxResource( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN USHORT totalMPDUSize, - IN USHORT TxIdx) -{ - UCHAR QueIdx; - HT_TX_CONTEXT *pHTTXContext; - UINT32 fillOffset; - TXINFO_STRUC *pTxInfo; - TXWI_STRUC *pTxWI; - UINT32 USBDMApktLen, padding; - unsigned long IrqFlags; - PUCHAR pWirelessPacket; - - QueIdx = pTxBlk->QueIdx; - pHTTXContext = &pAd->TxContext[QueIdx]; - - RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - - if (pHTTXContext->bCurWriting == TRUE) - { - fillOffset = pHTTXContext->CurWritePosition; - if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition)) - && (pHTTXContext->bCopySavePad == TRUE)) - pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]); - else - pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]); - - // - // Update TxInfo->USBDMApktLen , - // the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding - // - pTxInfo = (PTXINFO_STRUC)(pWirelessPacket); - - // Calculate the bulk-out padding - USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE; - padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment - USBDMApktLen += padding; - - pTxInfo->USBDMATxPktLen = USBDMApktLen; - - // - // Update TXWI->MPDUtotalByteCount , - // the length = 802.11 header + payload_of_all_batch_frames - pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE); - pTxWI->MPDUtotalByteCount = totalMPDUSize; - - // - // Update the pHTTXContext->CurWritePosition - // - pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen); - if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT) - { // Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame. - pHTTXContext->CurWritePosition = 8; - pTxInfo->SwUseLastRound = 1; - } - pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition; - - - // - // Zero the last padding. - // - pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]); - NdisZeroMemory(pWirelessPacket, padding + 8); - - // Finally, set bCurWriting as FALSE - pHTTXContext->bCurWriting = FALSE; - - } - else - { // It should not happened now unless we are going to shutdown. - DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n")); - } - - RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags); - -} - - -VOID RtmpUSBDataLastTxIdx( - IN PRTMP_ADAPTER pAd, - IN UCHAR QueIdx, - IN USHORT TxIdx) -{ - // DO nothing for USB. -} - - -/* - When can do bulk-out: - 1. TxSwFreeIdx < TX_RING_SIZE; - It means has at least one Ring entity is ready for bulk-out, kick it out. - 2. If TxSwFreeIdx == TX_RING_SIZE - Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out. - -*/ -VOID RtmpUSBDataKickOut( - IN PRTMP_ADAPTER pAd, - IN TX_BLK *pTxBlk, - IN UCHAR QueIdx) -{ - RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx)); - RTUSBKickBulkOut(pAd); - -} - - -/* - Must be run in Interrupt context - This function handle RT2870 specific TxDesc and cpu index update and kick the packet out. - */ -int RtmpUSBMgmtKickOut( - IN RTMP_ADAPTER *pAd, - IN UCHAR QueIdx, - IN PNDIS_PACKET pPacket, - IN PUCHAR pSrcBufVA, - IN UINT SrcBufLen) -{ - PTXINFO_STRUC pTxInfo; - ULONG BulkOutSize; - UCHAR padLen; - PUCHAR pDest; - ULONG SwIdx = pAd->MgmtRing.TxCpuIdx; - PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa; - unsigned long IrqFlags; - - - pTxInfo = (PTXINFO_STRUC)(pSrcBufVA); - - // Build our URB for USBD - BulkOutSize = SrcBufLen; - BulkOutSize = (BulkOutSize + 3) & (~3); - RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); - - BulkOutSize += 4; // Always add 4 extra bytes at every packet. - - // If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. - if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0) - BulkOutSize += 4; - - padLen = BulkOutSize - SrcBufLen; - ASSERT((padLen <= RTMP_PKT_TAIL_PADDING)); - - // Now memzero all extra padding bytes. - pDest = (PUCHAR)(pSrcBufVA + SrcBufLen); - skb_put(GET_OS_PKT_TYPE(pPacket), padLen); - NdisZeroMemory(pDest, padLen); - - RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); - - pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket; - pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket)); - - // Length in TxInfo should be 8 less than bulkout size. - pMLMEContext->BulkOutSize = BulkOutSize; - pMLMEContext->InUse = TRUE; - pMLMEContext->bWaitingBulkOut = TRUE; - - - //for debug - //hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); - - //pAd->RalinkCounters.KickTxCount++; - //pAd->RalinkCounters.OneSecTxDoneCount++; - - //if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) - // needKickOut = TRUE; - - // Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX - pAd->MgmtRing.TxSwFreeIdx--; - INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE); - - RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); - - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); - //if (needKickOut) - RTUSBKickBulkOut(pAd); - - return 0; -} - - -VOID RtmpUSBNullFrameKickOut( - IN RTMP_ADAPTER *pAd, - IN UCHAR QueIdx, - IN UCHAR *pNullFrame, - IN UINT32 frameLen) -{ - if (pAd->NullContext.InUse == FALSE) - { - PTX_CONTEXT pNullContext; - PTXINFO_STRUC pTxInfo; - PTXWI_STRUC pTxWI; - PUCHAR pWirelessPkt; - - pNullContext = &(pAd->NullContext); - - // Set the in use bit - pNullContext->InUse = TRUE; - pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0]; - - RTMPZeroMemory(&pWirelessPkt[0], 100); - pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0]; - RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); - pTxInfo->QSEL = FIFO_EDCA; - pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE]; - RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)), - 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit); - RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11)); - pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4; - - // Fill out frame length information for global Bulk out arbitor - //pNullContext->BulkOutSize = TransferBufferLength; - DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate])); - RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL); - - // Kick bulk out - RTUSBKickBulkOut(pAd); - } - -} - -/* - ======================================================================== - - Routine Description: - Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound - - Arguments: - pRxD Pointer to the Rx descriptor - - Return Value: - NDIS_STATUS_SUCCESS No err - NDIS_STATUS_FAILURE Error - - Note: - - ======================================================================== -*/ -NDIS_STATUS RTMPCheckRxError( - IN PRTMP_ADAPTER pAd, - IN PHEADER_802_11 pHeader, - IN PRXWI_STRUC pRxWI, - IN PRT28XX_RXD_STRUC pRxINFO) -{ - PCIPHER_KEY pWpaKey; - INT dBm; - - if (pAd->bPromiscuous == TRUE) - return(NDIS_STATUS_SUCCESS); - if(pRxINFO == NULL) - return(NDIS_STATUS_FAILURE); - - // Phy errors & CRC errors - if (pRxINFO->Crc) - { - // Check RSSI for Noise Hist statistic collection. - dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta; - if (dBm <= -87) - pAd->StaCfg.RPIDensity[0] += 1; - else if (dBm <= -82) - pAd->StaCfg.RPIDensity[1] += 1; - else if (dBm <= -77) - pAd->StaCfg.RPIDensity[2] += 1; - else if (dBm <= -72) - pAd->StaCfg.RPIDensity[3] += 1; - else if (dBm <= -67) - pAd->StaCfg.RPIDensity[4] += 1; - else if (dBm <= -62) - pAd->StaCfg.RPIDensity[5] += 1; - else if (dBm <= -57) - pAd->StaCfg.RPIDensity[6] += 1; - else if (dBm > -57) - pAd->StaCfg.RPIDensity[7] += 1; - - return(NDIS_STATUS_FAILURE); - } - - // Add Rx size to channel load counter, we should ignore error counts - pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14); - - // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics - if (pHeader->FC.ToDs) - { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n")); - return NDIS_STATUS_FAILURE; - } - - // Paul 04-03 for OFDM Rx length issue - if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE) - { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n")); - return NDIS_STATUS_FAILURE; - } - - // Drop not U2M frames, cant's drop here because we will drop beacon in this case - // I am kind of doubting the U2M bit operation - // if (pRxD->U2M == 0) - // return(NDIS_STATUS_FAILURE); - - // drop decyption fail frame - if (pRxINFO->Decrypted && pRxINFO->CipherErr) - { - - // - // MIC Error - // - if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss) - { - pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex]; - RTMPReportMicError(pAd, pWpaKey); - DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n")); - } - - if (pRxINFO->Decrypted && - (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) && - (pHeader->Sequence == pAd->FragFrame.Sequence)) - { - // - // Acceptable since the First FragFrame no CipherErr problem. - // - return(NDIS_STATUS_SUCCESS); - } - - return(NDIS_STATUS_FAILURE); - } - - return(NDIS_STATUS_SUCCESS); -} - -VOID RT28xxUsbStaAsicForceWakeup( - IN PRTMP_ADAPTER pAd, - IN BOOLEAN bFromTx) -{ - AUTO_WAKEUP_STRUC AutoWakeupCfg; - - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - - AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); - - OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE); -} - -VOID RT28xxUsbStaAsicSleepThenAutoWakeup( - IN PRTMP_ADAPTER pAd, - IN USHORT TbttNumToNextWakeUp) -{ - AUTO_WAKEUP_STRUC AutoWakeupCfg; - - // we have decided to SLEEP, so at least do it for a BEACON period. - if (TbttNumToNextWakeUp == 0) - TbttNumToNextWakeUp = 1; - - AutoWakeupCfg.word = 0; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - - AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1; - AutoWakeupCfg.field.EnableAutoWakeup = 1; - AutoWakeupCfg.field.AutoLeadTime = 5; - RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word); - - AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); // send POWER-SAVE command to MCU. Timeout 40us. - - OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE); - -} - -VOID RT28xxUsbMlmeRadioOn( - IN PRTMP_ADAPTER pAd) -{ - DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n")); - - if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) - return; - - AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02); - RTMPusecDelay(10000); - - NICResetFromError(pAd); - - // Enable Tx/Rx - RTMPEnableRxTx(pAd); - -#ifdef RT3070 - if (IS_RT3071(pAd)) - { - RT30xxReverseRFSleepModeSetup(pAd); - } -#endif // RT3070 // - - // Clear Radio off flag - RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - RTUSBBulkReceive(pAd); - - // Set LED - RTMPSetLED(pAd, LED_RADIO_ON); -} - -VOID RT28xxUsbMlmeRadioOFF( - IN PRTMP_ADAPTER pAd) -{ - WPDMA_GLO_CFG_STRUC GloCfg; - UINT32 Value, i; - - DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n")); - - if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) - return; - - // Set LED - RTMPSetLED(pAd, LED_RADIO_OFF); - // Set Radio off flag - RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF); - - { - // Link down first if any association exists - if (INFRA_ON(pAd) || ADHOC_ON(pAd)) - LinkDown(pAd, FALSE); - RTMPusecDelay(10000); - - //========================================== - // Clean up old bss table - BssTableInit(&pAd->ScanTab); - } - - if (pAd->CommonCfg.BBPCurrentBW == BW_40) - { - // Must using 40MHz. - AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel); - } - else - { - // Must using 20MHz. - AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel); - } - - // Disable Tx/Rx DMA - RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA - GloCfg.field.EnableTxDMA = 0; - GloCfg.field.EnableRxDMA = 0; - RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings - - // Waiting for DMA idle - i = 0; - do - { - RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); - if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0)) - break; - - RTMPusecDelay(1000); - }while (i++ < 100); - - // Disable MAC Tx/Rx - RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value); - Value &= (0xfffffff3); - RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value); - - AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); -} - Index: b/drivers/staging/rt2870/common/cmm_data_usb.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/cmm_data_usb.c @@ -0,0 +1 @@ +#include "../../rt2860/common/cmm_data_usb.c" Index: b/drivers/staging/rt2870/common/cmm_mac_usb.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/cmm_mac_usb.c @@ -0,0 +1 @@ +#include "../../rt2860/common/cmm_mac_usb.c" Index: b/drivers/staging/rt2870/common/cmm_profile.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/cmm_profile.c @@ -0,0 +1 @@ +#include "../../rt2860/common/cmm_profile.c" Index: b/drivers/staging/rt2870/common/cmm_tkip.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/cmm_tkip.c @@ -0,0 +1 @@ +#include "../../rt2860/common/cmm_tkip.c" Index: b/drivers/staging/rt2870/common/cmm_wep.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/cmm_wep.c @@ -0,0 +1 @@ +#include "../../rt2860/common/cmm_wep.c" Index: b/drivers/staging/rt2870/common/crypt_hmac.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/crypt_hmac.c @@ -0,0 +1 @@ +#include "../../rt2860/common/crypt_hmac.c" Index: b/drivers/staging/rt2870/common/crypt_md5.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/crypt_md5.c @@ -0,0 +1 @@ +#include "../../rt2860/common/crypt_md5.c" Index: b/drivers/staging/rt2870/common/crypt_sha2.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/crypt_sha2.c @@ -0,0 +1 @@ +#include "../../rt2860/common/crypt_sha2.c" Index: b/drivers/staging/rt2870/common/ee_efuse.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/ee_efuse.c @@ -0,0 +1 @@ +#include "../../rt2860/common/ee_efuse.c" Index: b/drivers/staging/rt2870/common/rt_channel.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/rt_channel.c @@ -0,0 +1 @@ +#include "../../rt2860/common/rt_channel.c" Index: b/drivers/staging/rt2870/common/rt_rf.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/rt_rf.c @@ -0,0 +1 @@ +#include "../../rt2860/common/rt_rf.c" Index: b/drivers/staging/rt2870/common/rtmp_mcu.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/rtmp_mcu.c @@ -0,0 +1 @@ +#include "../../rt2860/common/rtmp_mcu.c" Index: b/drivers/staging/rt2870/common/rtmp_timer.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/common/rtmp_timer.c @@ -0,0 +1 @@ +#include "../../rt2860/common/rtmp_timer.c" Index: b/drivers/staging/rt2870/common/rtusb_bulk.c =================================================================== --- a/drivers/staging/rt2870/common/rtusb_bulk.c +++ b/drivers/staging/rt2870/common/rtusb_bulk.c @@ -1,4 +1,4 @@ - /* +/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, @@ -37,6 +37,9 @@ */ +#ifdef RTMP_MAC_USB + + #include "../rt_config.h" // Match total 6 bulkout endpoint to corresponding queue. UCHAR EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT}; @@ -281,12 +284,56 @@ VOID RTUSBBulkOutDataPacket( //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0)) if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) { +#ifdef INF_AMAZON_SE + /*Iverson Add for AMAZON USB (RT2070 && RT3070) to pass WMM A2-T4 ~ A2-T10*/ + if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)) + { + /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate*/ + if(pTxWI->PacketId == 6) + { + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } + else if (BulkOutPipeId == 1) + { + /*BK No Limit BulkOut size .*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } + else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x1000) == 0x1000) && (BulkOutPipeId == 0) )) + { + /*BE Limit BulkOut size to about 4k bytes.*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } + else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x1c00) == 0x1c00) && (BulkOutPipeId == 2) )) + { + /*VI Limit BulkOut size to about 7k bytes.*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } + else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x2500) == 0x2500) && (BulkOutPipeId == 3) )) + { + /*VO Limit BulkOut size to about 9k bytes.*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } + } + else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) + { + /* Limit BulkOut size to about 4k bytes.*/ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } +#else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000)) { // Limit BulkOut size to about 4k bytes. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; break; } +#endif // INF_AMAZON_SE // + else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/) { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. @@ -298,6 +345,65 @@ VOID RTUSBBulkOutDataPacket( // end Iverson else { +#ifdef INF_AMAZON_SE +//#ifdef DOT11_N_SUPPORT +// if(((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000) || ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))) +// { +// /* AMAZON_SE: BG mode Disable BulkOut Aggregate, N mode BulkOut Aggregaet size 24K */ +// pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; +// break; +// } +// else +//#endif // DOT11_N_SUPPORT // +// { + if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && (pTxWI->AMPDU == 0)) + { + if (((ThisBulkSize&0x1000) == 0x1000) && (BulkOutPipeId == 0)) + { + /*BE BulkOut Aggregate 4K for AMAZON B/G throughput and PASS WMM (need usb host patch) */ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } + else if (((ThisBulkSize&0x1c00) == 0x1c00) && (BulkOutPipeId == 2)) + { + /*VI BulkOut Aggregate 7K for AMAZON B/G PASS WMM (need usb host patch) */ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } + else if (((ThisBulkSize&0x2500) == 0x2500) && (BulkOutPipeId == 3)) + { + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + /*V0 BulkOut Aggregate 9K for AMAZON B/G PASS WMM (need usb host patch) */ + break; + } + + else if (((ThisBulkSize != 0) && (BulkOutPipeId == 1) ) ) + { + /*BK BulkOut Disable Aggregate for AMAZON B/G PASS WMM (need usb host patch) */ + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } +/* + else if(((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0))) + { + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + + } + +*/ + } +/* + else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) + { + // Limit BulkOut size to about 24k bytes. + pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; + break; + } + } +*/ +#endif // INF_AMAZON_SE // + if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000)) { // Limit BulkOut size to about 24k bytes. pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos; @@ -317,11 +423,13 @@ VOID RTUSBBulkOutDataPacket( break; } - //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) if (pTxInfo->QSEL != FIFO_EDCA) { - printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __func__, pTxInfo->QSEL); - printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad); + DBGPRINT(RT_DEBUG_ERROR, ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", + __FUNCTION__, pTxInfo->QSEL)); + DBGPRINT(RT_DEBUG_ERROR, ("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", + pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, + pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition)); } @@ -350,7 +458,7 @@ VOID RTUSBBulkOutDataPacket( pLastTxInfo = pTxInfo; // Make sure we use EDCA QUEUE. - pTxInfo->QSEL = FIFO_EDCA; //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) + pTxInfo->QSEL = FIFO_EDCA; ThisBulkSize += (pTxInfo->USBDMATxPktLen+4); TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4); @@ -366,8 +474,11 @@ VOID RTUSBBulkOutDataPacket( bTxQLastRound = TRUE; pHTTXContext->ENextBulkOutPosition = 8; + break; } + + }while (TRUE); // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo. @@ -481,11 +592,9 @@ VOID RTUSBBulkOutDataPacketComplete(purb pObj->ac3_dma_done_task.data = (unsigned long)pUrb; tasklet_hi_schedule(&pObj->ac3_dma_done_task); break; - case 4: - pObj->hcca_dma_done_task.data = (unsigned long)pUrb; - tasklet_hi_schedule(&pObj->hcca_dma_done_task); - break; } + + } @@ -933,7 +1042,7 @@ VOID RTUSBKickBulkOut( } // 5. Mlme frame is next - else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) && + else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) || (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE)) { RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx); @@ -977,16 +1086,6 @@ VOID RTUSBKickBulkOut( } } - //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA) - if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_5)) - { - if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || - (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) - )) - { - } - } - // 7. Null frame is the last else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL)) { @@ -1231,3 +1330,4 @@ VOID RTUSBCancelPendingBulkOutIRP( } } +#endif // RTMP_MAC_USB // Index: b/drivers/staging/rt2870/common/rtusb_data.c =================================================================== --- a/drivers/staging/rt2870/common/rtusb_data.c +++ b/drivers/staging/rt2870/common/rtusb_data.c @@ -36,6 +36,10 @@ Jan 03-25-2006 created */ + +#ifdef RTMP_MAC_USB + + #include "../rt_config.h" extern UCHAR Phy11BGNextRateUpward[]; // defined in mlme.c @@ -68,6 +72,26 @@ VOID REPORT_AMSDU_FRAMES_TO_LLC( } } + +/* + ======================================================================== + + Routine Description: + This subroutine will scan through releative ring descriptor to find + out avaliable free ring descriptor and compare with request size. + + Arguments: + pAd Pointer to our adapter + RingType Selected Ring + + Return Value: + NDIS_STATUS_FAILURE Not enough free descriptor + NDIS_STATUS_SUCCESS Enough free descriptor + + Note: + + ======================================================================== +*/ NDIS_STATUS RTUSBFreeDescriptorRequest( IN PRTMP_ADAPTER pAd, IN UCHAR BulkOutPipeId, @@ -193,6 +217,36 @@ VOID RTUSBRejectPendingPackets( } + +/* + ======================================================================== + + Routine Description: + Calculates the duration which is required to transmit out frames + with given size and specified rate. + + Arguments: + pTxD Pointer to transmit descriptor + Ack Setting for Ack requirement bit + Fragment Setting for Fragment bit + RetryMode Setting for retry mode + Ifs Setting for IFS gap + Rate Setting for transmit rate + Service Setting for service + Length Frame length + TxPreamble Short or Long preamble when using CCK rates + QueIdx - 0-3, according to 802.11e/d4.4 June/2003 + + Return Value: + None + + IRQL = PASSIVE_LEVEL + IRQL = DISPATCH_LEVEL + + ======================================================================== +*/ + + VOID RTMPWriteTxInfo( IN PRTMP_ADAPTER pAd, IN PTXINFO_STRUC pTxInfo, @@ -214,3 +268,4 @@ VOID RTMPWriteTxInfo( pTxInfo->rsv2 = 0; } +#endif // RTMP_MAC_USB // Index: b/drivers/staging/rt2870/common/rtusb_io.c =================================================================== --- a/drivers/staging/rt2870/common/rtusb_io.c +++ b/drivers/staging/rt2870/common/rtusb_io.c @@ -36,6 +36,9 @@ Paul Lin 06-25-2004 created */ +#ifdef RTMP_MAC_USB + + #include "../rt_config.h" @@ -55,7 +58,7 @@ ======================================================================== */ -NTSTATUS RTUSBFirmwareRun( +static NTSTATUS RTUSBFirmwareRun( IN PRTMP_ADAPTER pAd) { NTSTATUS Status; @@ -110,48 +113,26 @@ NTSTATUS RTUSBFirmwareWrite( Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff); Status = RTUSBFirmwareRun(pAd); + //2008/11/28:KH add to fix the dead rf frequency offset bug<-- RTMPusecDelay(10000); RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0); - AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00);//reset rf by MCU supported by new firmware + AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00); //reset rf by MCU supported by new firmware + //2008/11/28:KH add to fix the dead rf frequency offset bug--> + +#ifdef NEW_FW + if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)) + { + // send 0x36 mcu command after 0x72 for RT3xxx to fix Radio-Off current leakage issue + RTMPusecDelay(200); + AsicSendCommandToMcu(pAd, 0x36, 0, 0, 0); + RTMPusecDelay(10); + } +#endif // NEW_FW // return Status; } -/* - ======================================================================== - - Routine Description: Get current firmware operation mode (Return Value) - - Arguments: - - Return Value: - 0 or 1 = Downloaded by host driver - others = Driver doesn't download firmware - - IRQL = - - Note: - - ======================================================================== -*/ -NTSTATUS RTUSBFirmwareOpmode( - IN PRTMP_ADAPTER pAd, - OUT PUINT32 pValue) -{ - NTSTATUS Status; - - Status = RTUSB_VendorRequest( - pAd, - (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK), - DEVICE_VENDOR_REQUEST_IN, - 0x1, - 0x11, - 0, - pValue, - 4); - return Status; -} NTSTATUS RTUSBVenderReset( IN PRTMP_ADAPTER pAd) { @@ -312,7 +293,7 @@ NTSTATUS RTUSBReadMACRegister( IN USHORT Offset, OUT PUINT32 pValue) { - NTSTATUS Status; + NTSTATUS Status = 0; UINT32 localVal; Status = RTUSB_VendorRequest( @@ -368,7 +349,6 @@ NTSTATUS RTUSBWriteMACRegister( -#if 1 /* ======================================================================== @@ -402,10 +382,9 @@ NTSTATUS RTUSBReadBBPRegister( if (!(BbpCsr.field.Busy == BUSY)) break; } - printk("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", i); + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", i)); i++; - } - while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); + }while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { @@ -438,10 +417,9 @@ NTSTATUS RTUSBReadBBPRegister( break; } } - printk("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", i); + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", i)); i++; - } - while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); + }while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { @@ -456,67 +434,8 @@ NTSTATUS RTUSBReadBBPRegister( return STATUS_SUCCESS; } -#else -/* - ======================================================================== - - Routine Description: Read 8-bit BBP register via firmware - - Arguments: - - Return Value: - IRQL = - - Note: - ======================================================================== -*/ -NTSTATUS RTUSBReadBBPRegister( - IN PRTMP_ADAPTER pAd, - IN UCHAR Id, - IN PUCHAR pValue) -{ - BBP_CSR_CFG_STRUC BbpCsr; - int i, k; - for (i=0; iBbpWriteLatch[Id]; - return STATUS_UNSUCCESSFUL; - } - return STATUS_SUCCESS; -} -#endif - -#if 1 /* ======================================================================== @@ -549,7 +468,7 @@ NTSTATUS RTUSBWriteBBPRegister( if (!(BbpCsr.field.Busy == BUSY)) break; } - printk("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i); + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i)); i++; } while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); @@ -572,55 +491,6 @@ NTSTATUS RTUSBWriteBBPRegister( return STATUS_SUCCESS; } -#else -/* - ======================================================================== - - Routine Description: Write 8-bit BBP register via firmware - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ - -NTSTATUS RTUSBWriteBBPRegister( - IN PRTMP_ADAPTER pAd, - IN UCHAR Id, - IN UCHAR Value) - -{ - BBP_CSR_CFG_STRUC BbpCsr; - int BusyCnt; - for (BusyCnt=0; BusyCntBbpWriteLatch[Id] = Value; - break; - } - if (BusyCnt == MAX_BUSY_COUNT) - { - DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", Id, BbpCsr.word)); - return STATUS_UNSUCCESSFUL; - } - return STATUS_SUCCESS; -} -#endif /* ======================================================================== @@ -653,7 +523,7 @@ NTSTATUS RTUSBWriteRFRegister( if (!(PhyCsr4.field.Busy)) break; } - printk("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i); + DBGPRINT(RT_DEBUG_TRACE, ("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i)); i++; } while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); @@ -669,114 +539,6 @@ NTSTATUS RTUSBWriteRFRegister( return STATUS_SUCCESS; } -/* - ======================================================================== - - Routine Description: Write RT30xx RF register through MAC - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -NTSTATUS RT30xxWriteRFRegister( - IN PRTMP_ADAPTER pAd, - IN UCHAR RegID, - IN UCHAR Value) -{ - RF_CSR_CFG_STRUC rfcsr; - UINT i = 0; - - do - { - RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word); - - if (!rfcsr.field.RF_CSR_KICK) - break; - i++; - } - while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))); - - if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) - { - DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n")); - return STATUS_UNSUCCESSFUL; - } - - rfcsr.field.RF_CSR_WR = 1; - rfcsr.field.RF_CSR_KICK = 1; - rfcsr.field.TESTCSR_RFACC_REGNUM = RegID; - rfcsr.field.RF_CSR_DATA = Value; - - RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word); - - return STATUS_SUCCESS; -} - - -/* - ======================================================================== - - Routine Description: Read RT30xx RF register through MAC - - Arguments: - - Return Value: - - IRQL = - - Note: - - ======================================================================== -*/ -NTSTATUS RT30xxReadRFRegister( - IN PRTMP_ADAPTER pAd, - IN UCHAR RegID, - IN PUCHAR pValue) -{ - RF_CSR_CFG_STRUC rfcsr; - UINT i=0, k=0; - - for (i=0; ibUseEfuse) - Status =eFuseRead(pAd, Offset, pData, length); - else - { Status = RTUSB_VendorRequest( pAd, (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK), @@ -814,7 +572,6 @@ NTSTATUS RTUSBReadEEPROM( Offset, pData, length); - } return Status; } @@ -842,10 +599,6 @@ NTSTATUS RTUSBWriteEEPROM( { NTSTATUS Status = STATUS_SUCCESS; - if(pAd->bUseEfuse) - Status = eFuseWrite(pAd, Offset, pData, length); - else - { Status = RTUSB_VendorRequest( pAd, USBD_TRANSFER_DIRECTION_OUT, @@ -855,11 +608,38 @@ NTSTATUS RTUSBWriteEEPROM( Offset, pData, length); - } return Status; } + +NTSTATUS RTUSBReadEEPROM16( + IN PRTMP_ADAPTER pAd, + IN USHORT offset, + OUT PUSHORT pData) +{ + NTSTATUS status; + USHORT localData; + + status = RTUSBReadEEPROM(pAd, offset, (PUCHAR)(&localData), 2); + if (status == STATUS_SUCCESS) + *pData = le2cpu16(localData); + + return status; + +} + +NTSTATUS RTUSBWriteEEPROM16( + IN RTMP_ADAPTER *pAd, + IN USHORT offset, + IN USHORT value) +{ + USHORT tmpVal; + + tmpVal = cpu2le16(value); + return RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(tmpVal), 2); +} + /* ======================================================================== @@ -943,7 +723,7 @@ VOID RTUSBInitializeCmdQ( cmdq->head = NULL; cmdq->tail = NULL; cmdq->size = 0; - cmdq->CmdQState = RT2870_THREAD_INITED; + cmdq->CmdQState = RTMP_TASK_STAT_INITED; } /* @@ -970,19 +750,26 @@ NDIS_STATUS RTUSBEnqueueCmdFromNdis( { NDIS_STATUS status; PCmdQElmt cmdqelmt = NULL; - POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; + RTMP_OS_TASK *pTask = &pAd->cmdQTask; - if (pid_nr(pObj->RTUSBCmdThr_pid) > 0) +#ifdef KTHREAD_SUPPORT + if (pTask->kthread_task == NULL) +#else + CHECK_PID_LEGALITY(pTask->taskPID) + { + } + else +#endif return (NDIS_STATUS_RESOURCES); - status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt)); + status = os_alloc_mem(pAd, (PUCHAR *)(&cmdqelmt), sizeof(CmdQElmt)); if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) return (NDIS_STATUS_RESOURCES); cmdqelmt->buffer = NULL; if (pInformationBuffer != NULL) { - status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength); + status = os_alloc_mem(pAd, (PUCHAR *)&cmdqelmt->buffer, InformationBufferLength); if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL)) { kfree(cmdqelmt); @@ -1005,7 +792,7 @@ NDIS_STATUS RTUSBEnqueueCmdFromNdis( cmdqelmt->SetOperation = FALSE; NdisAcquireSpinLock(&pAd->CmdQLock); - if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT) + if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) { EnqueueCmd((&pAd->CmdQ), cmdqelmt); status = NDIS_STATUS_SUCCESS; @@ -1019,8 +806,8 @@ NDIS_STATUS RTUSBEnqueueCmdFromNdis( if (status == NDIS_STATUS_FAILURE) { if (cmdqelmt->buffer) - NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0); - NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0); + os_free_mem(pAd, cmdqelmt->buffer); + os_free_mem(pAd, cmdqelmt); } else RTUSBCMDUp(pAd); @@ -1054,17 +841,17 @@ NDIS_STATUS RTUSBEnqueueInternalCmd( PCmdQElmt cmdqelmt = NULL; - status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt)); + status = os_alloc_mem(pAd, (PUCHAR *)&cmdqelmt, sizeof(CmdQElmt)); if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL)) return (NDIS_STATUS_RESOURCES); NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt)); if(InformationBufferLength > 0) { - status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength); + status = os_alloc_mem(pAd, (PUCHAR *)&cmdqelmt->buffer, InformationBufferLength); if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL)) { - NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0); + os_free_mem(pAd, cmdqelmt); return (NDIS_STATUS_RESOURCES); } else @@ -1085,7 +872,7 @@ NDIS_STATUS RTUSBEnqueueInternalCmd( if (cmdqelmt != NULL) { NdisAcquireSpinLock(&pAd->CmdQLock); - if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT) + if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) { EnqueueCmd((&pAd->CmdQ), cmdqelmt); status = NDIS_STATUS_SUCCESS; @@ -1099,8 +886,8 @@ NDIS_STATUS RTUSBEnqueueInternalCmd( if (status == NDIS_STATUS_FAILURE) { if (cmdqelmt->buffer) - NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0); - NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0); + os_free_mem(pAd, cmdqelmt->buffer); + os_free_mem(pAd, cmdqelmt); } else RTUSBCMDUp(pAd); @@ -1185,7 +972,7 @@ NTSTATUS RTUSB_VendorRequest( IN PVOID TransferBuffer, IN UINT32 TransferBufferLength) { - int ret; + int ret = 0; POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) @@ -1206,7 +993,18 @@ NTSTATUS RTUSB_VendorRequest( int retryCount = 0; void *tmpBuf = TransferBuffer; - // Acquire Control token + ret = down_interruptible(&(pAd->UsbVendorReq_semaphore)); + if (pAd->UsbVendorReqBuf) + { + ASSERT(TransferBufferLength UsbVendorReqBuf; + NdisZeroMemory(pAd->UsbVendorReqBuf, TransferBufferLength); + + if (RequestType == DEVICE_VENDOR_REQUEST_OUT) + NdisMoveMemory(tmpBuf, TransferBuffer, TransferBufferLength); + } + do { if( RequestType == DEVICE_VENDOR_REQUEST_OUT) ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES); @@ -1220,13 +1018,16 @@ NTSTATUS RTUSB_VendorRequest( retryCount++; if (ret < 0) { - printk("#\n"); + DBGPRINT(RT_DEBUG_OFF, ("#\n")); RTMPusecDelay(5000); } } while((ret < 0) && (retryCount < MAX_RETRY_COUNT)); + if ((pAd->UsbVendorReqBuf) && (RequestType == DEVICE_VENDOR_REQUEST_IN)) + NdisMoveMemory(TransferBuffer, tmpBuf, TransferBufferLength); + up(&(pAd->UsbVendorReq_semaphore)); + if (ret < 0) { -// DBGPRINT(RT_DEBUG_ERROR, ("USBVendorRequest failed ret=%d \n",ret)); DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n", ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index)); if (Request == 0x2) @@ -1235,8 +1036,14 @@ NTSTATUS RTUSB_VendorRequest( if ((TransferBuffer!= NULL) && (TransferBufferLength > 0)) hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength); } + + } - return ret; + + if (ret != -1) + return STATUS_SUCCESS; + else + return STATUS_UNSUCCESSFUL; } /* @@ -1275,7 +1082,7 @@ VOID CMDHandler( NTSTATUS ntStatus; // unsigned long IrqFlags; - while (pAd->CmdQ.size > 0) + while (pAd && pAd->CmdQ.size > 0) { NdisStatus = NDIS_STATUS_SUCCESS; @@ -1410,8 +1217,6 @@ VOID CMDHandler( //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); -/*-----------------------------------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------------------*/ { RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete); @@ -1522,8 +1327,7 @@ VOID CMDHandler( // All transfers must be aborted or cancelled before attempting to reset the pipe. { UINT32 MACValue; -/*-----------------------------------------------------------------------------------------------*/ -/*-----------------------------------------------------------------------------------------------*/ + { //while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) @@ -1612,6 +1416,8 @@ VOID CMDHandler( } else { // success + //DBGPRINT(RT_DEBUG_TRACE, ("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", + // pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex)); DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status)); ASSERT((pRxContext->InUse == pRxContext->IRPPending)); } @@ -1722,6 +1528,40 @@ VOID CMDHandler( } } break; + +//Benson modified for USB interface, avoid in interrupt when write key, 20080724 --> + case RT_CMD_SET_KEY_TABLE: //General call for AsicAddPairwiseKeyEntry() + { + RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo; + KeyInfo = *((PRT_ADD_PAIRWISE_KEY_ENTRY)(pData)); + AsicAddPairwiseKeyEntry(pAd, + KeyInfo.MacAddr, + (UCHAR)KeyInfo.MacTabMatchWCID, + &KeyInfo.CipherKey); + } + break; + + case RT_CMD_SET_RX_WCID_TABLE: //General call for RTMPAddWcidAttributeEntry() + { + PMAC_TABLE_ENTRY pEntry ; + UCHAR KeyIdx = 0; + UCHAR CipherAlg = CIPHER_NONE; + UCHAR ApIdx = BSS0; + + pEntry = (PMAC_TABLE_ENTRY)(pData); + + + + RTMPAddWcidAttributeEntry( + pAd, + ApIdx, + KeyIdx, + CipherAlg, + pEntry); + } + break; +//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <-- + case CMDTHREAD_SET_CLIENT_MAC_ENTRY: { MAC_TABLE_ENTRY *pEntry; @@ -1731,7 +1571,7 @@ VOID CMDHandler( AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid); if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled)) { - UINT32 uIV = 0; + UINT32 uIV = 1; PUCHAR ptr; ptr = (PUCHAR) &uIV; @@ -1741,7 +1581,7 @@ VOID CMDHandler( } else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone) { - UINT32 uIV = 0; + UINT32 uIV = 1; PUCHAR ptr; ptr = (PUCHAR) &uIV; @@ -1763,15 +1603,19 @@ VOID CMDHandler( } AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr); - printk("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid, - pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]); + DBGPRINT(RT_DEBUG_TRACE, ("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid, + pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5])); } break; + +// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet case CMDTHREAD_UPDATE_PROTECT: { AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0); } break; +// end johnli + case OID_802_11_ADD_WEP: { UINT i; @@ -1852,6 +1696,25 @@ VOID CMDHandler( case CMDTHREAD_802_11_COUNTER_MEASURE: break; + + case CMDTHREAD_SET_GROUP_KEY: + WpaStaGroupKeySetting(pAd); + break; + + case CMDTHREAD_SET_PAIRWISE_KEY: + WpaStaPairwiseKeySetting(pAd); + break; + + case CMDTHREAD_SET_PSM_BIT: + { + USHORT *pPsm = (USHORT *)pData; + MlmeSetPsmBit(pAd, *pPsm); + } + break; + case CMDTHREAD_FORCE_WAKE_UP: + AsicForceWakeup(pAd, TRUE); + break; + default: DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command)); break; @@ -1861,18 +1724,16 @@ VOID CMDHandler( if (cmdqelmt->CmdFromNdis == TRUE) { if (cmdqelmt->buffer != NULL) - NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0); - - NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0); + os_free_mem(pAd, cmdqelmt->buffer); + os_free_mem(pAd, cmdqelmt); } else { if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0)) - NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0); - { - NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0); - } + os_free_mem(pAd, cmdqelmt->buffer); + os_free_mem(pAd, cmdqelmt); } } /* end of while */ } +#endif // RTMP_MAC_USB // Index: b/drivers/staging/rt2870/rt2870.h =================================================================== --- a/drivers/staging/rt2870/rt2870.h +++ /dev/null @@ -1,583 +0,0 @@ -/* - ************************************************************************* - * Ralink Tech Inc. - * 5F., No.36, Taiyuan St., Jhubei City, - * Hsinchu County 302, - * Taiwan, R.O.C. - * - * (c) Copyright 2002-2007, Ralink Technology, Inc. - * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * * - ************************************************************************* - */ - -#ifndef __RT2870_H__ -#define __RT2870_H__ - -//usb header files -#include - -/* rtmp_def.h */ -// -#define BULKAGGRE_ZISE 100 -#define RT28XX_DRVDATA_SET(_a) usb_set_intfdata(_a, pAd); -#define RT28XX_PUT_DEVICE usb_put_dev -#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso, GFP_ATOMIC) -#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb, GFP_ATOMIC) -#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr) usb_buffer_alloc(pUsb_Dev, BufSize, GFP_ATOMIC, pDma_addr) -#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr) usb_buffer_free(pUsb_Dev, BufSize, pTransferBuf, Dma_addr) - -#define RXBULKAGGRE_ZISE 12 -#define MAX_TXBULK_LIMIT (LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1)) -#define MAX_TXBULK_SIZE (LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE) -#define MAX_RXBULK_SIZE (LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE) -#define MAX_MLME_HANDLER_MEMORY 20 -#define RETRY_LIMIT 10 -#define BUFFER_SIZE 2400 //2048 -#define TX_RING 0xa -#define PRIO_RING 0xc - - -// Flags for Bulkflags control for bulk out data -// -#define fRTUSB_BULK_OUT_DATA_NULL 0x00000001 -#define fRTUSB_BULK_OUT_RTS 0x00000002 -#define fRTUSB_BULK_OUT_MLME 0x00000004 - -#define fRTUSB_BULK_OUT_DATA_NORMAL 0x00010000 -#define fRTUSB_BULK_OUT_DATA_NORMAL_2 0x00020000 -#define fRTUSB_BULK_OUT_DATA_NORMAL_3 0x00040000 -#define fRTUSB_BULK_OUT_DATA_NORMAL_4 0x00080000 -#define fRTUSB_BULK_OUT_DATA_NORMAL_5 0x00100000 - -#define fRTUSB_BULK_OUT_PSPOLL 0x00000020 -#define fRTUSB_BULK_OUT_DATA_FRAG 0x00000040 -#define fRTUSB_BULK_OUT_DATA_FRAG_2 0x00000080 -#define fRTUSB_BULK_OUT_DATA_FRAG_3 0x00000100 -#define fRTUSB_BULK_OUT_DATA_FRAG_4 0x00000200 - -#define FREE_HTTX_RING(_p, _b, _t) \ -{ \ - if ((_t)->ENextBulkOutPosition == (_t)->CurWritePosition) \ - { \ - (_t)->bRingEmpty = TRUE; \ - } \ - /*NdisInterlockedDecrement(&(_p)->TxCount); */\ -} - -// -// RXINFO appends at the end of each rx packet. -// -typedef struct PACKED _RXINFO_STRUC { - UINT32 BA:1; - UINT32 DATA:1; - UINT32 NULLDATA:1; - UINT32 FRAG:1; - UINT32 U2M:1; // 1: this RX frame is unicast to me - UINT32 Mcast:1; // 1: this is a multicast frame - UINT32 Bcast:1; // 1: this is a broadcast frame - UINT32 MyBss:1; // 1: this frame belongs to the same BSSID - UINT32 Crc:1; // 1: CRC error - UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid - UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header. - UINT32 HTC:1; - UINT32 RSSI:1; - UINT32 L2PAD:1; - UINT32 AMPDU:1; // To be moved - UINT32 Decrypted:1; - UINT32 PlcpRssil:1; - UINT32 CipherAlg:1; - UINT32 LastAMSDU:1; - UINT32 PlcpSignal:12; -} RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC; - -// -// TXINFO -// -typedef struct _TXINFO_STRUC { - // Word 0 - UINT32 USBDMATxPktLen:16; //used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame. - UINT32 rsv:8; - UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition - UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA - UINT32 SwUseLastRound:1; // Software use. - UINT32 rsv2:2; // Software use. - UINT32 USBDMANextVLD:1; //used ONLY in USB bulk Aggregation, NextValid - UINT32 USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint -} TXINFO_STRUC, *PTXINFO_STRUC; - -#define TXINFO_SIZE 4 -#define RXINFO_SIZE 4 -#define TXPADDING_SIZE 11 - -// -// Management ring buffer format -// -typedef struct _MGMT_STRUC { - BOOLEAN Valid; - PUCHAR pBuffer; - ULONG Length; -} MGMT_STRUC, *PMGMT_STRUC; - - -/* ----------------- EEPROM Related MACRO ----------------- */ -#define RT28xx_EEPROM_READ16(pAd, offset, var) \ - do { \ - RTUSBReadEEPROM(pAd, offset, (PUCHAR)&(var), 2); \ - if(!pAd->bUseEfuse) \ - var = le2cpu16(var); \ - }while(0) - -#define RT28xx_EEPROM_WRITE16(pAd, offset, var) \ - do{ \ - USHORT _tmpVar=var; \ - if(!pAd->bUseEfuse) \ - _tmpVar = cpu2le16(var); \ - RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(_tmpVar), 2); \ - }while(0) - -/* ----------------- TASK/THREAD Related MACRO ----------------- */ -#define RT28XX_TASK_THREAD_INIT(pAd, Status) \ - Status = CreateThreads(net_dev); - - -/* ----------------- Frimware Related MACRO ----------------- */ -#define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \ - RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen) - -/* ----------------- TX Related MACRO ----------------- */ -#define RT28XX_START_DEQUEUE(pAd, QueIdx, irqFlags) \ - { \ - RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ - if (pAd->DeQueueRunning[QueIdx]) \ - { \ - RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\ - printk("DeQueueRunning[%d]= TRUE!\n", QueIdx); \ - continue; \ - } \ - else \ - { \ - pAd->DeQueueRunning[QueIdx] = TRUE; \ - RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\ - } \ - } -#define RT28XX_STOP_DEQUEUE(pAd, QueIdx, irqFlags) \ - do{ \ - RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ - pAd->DeQueueRunning[QueIdx] = FALSE; \ - RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \ - }while(0) - - -#define RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \ - (RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS) - -#define RT28XX_RELEASE_DESC_RESOURCE(pAd, QueIdx) \ - do{}while(0) - -#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType) \ - ((_TxFrameType == TX_RALINK_FRAME) && (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx))) - - - -#define fRTMP_ADAPTER_NEED_STOP_TX \ - (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \ - fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \ - fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS) - - -#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \ - RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) - -#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \ - RtmpUSB_WriteSingleTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) - -#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \ - RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) - -#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \ - RtmpUSB_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) - -#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) \ - RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) - -#define HAL_LastTxIdx(pAd, QueIdx,TxIdx) \ - /*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx)*/ - -#define HAL_KickOutTx(pAd, pTxBlk, QueIdx) \ - RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx) - - -#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) \ - RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) - -#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \ - RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen) - -#define RTMP_PKT_TAIL_PADDING 11 // 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding) - -extern UCHAR EpToQueue[6]; - - -#ifdef RT2870 -#define GET_TXRING_FREENO(_pAd, _QueIdx) (_QueIdx) //(_pAd->TxRing[_QueIdx].TxSwFreeIdx) -#define GET_MGMTRING_FREENO(_pAd) (_pAd->MgmtRing.TxSwFreeIdx) -#endif // RT2870 // - - -/* ----------------- RX Related MACRO ----------------- */ -//#define RT28XX_RX_ERROR_CHECK RTMPCheckRxWI - -#define RT28XX_RV_ALL_BUF_END(bBulkReceive) \ - /* We return STATUS_MORE_PROCESSING_REQUIRED so that the completion */ \ - /* routine (IofCompleteRequest) will stop working on the irp. */ \ - if (bBulkReceive == TRUE) RTUSBBulkReceive(pAd); - - -/* ----------------- ASIC Related MACRO ----------------- */ - -// reset MAC of a station entry to 0xFFFFFFFFFFFF -#define RT28XX_STA_ENTRY_MAC_RESET(pAd, Wcid) \ - { RT_SET_ASIC_WCID SetAsicWcid; \ - SetAsicWcid.WCID = Wcid; \ - SetAsicWcid.SetTid = 0xffffffff; \ - SetAsicWcid.DeleteTid = 0xffffffff; \ - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID, \ - &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); } - -// add this entry into ASIC RX WCID search table -#define RT28XX_STA_ENTRY_ADD(pAd, pEntry) \ - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY, \ - pEntry, sizeof(MAC_TABLE_ENTRY)); - -// remove Pair-wise key material from ASIC -// yet implement -#define RT28XX_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid) - -// add Client security information into ASIC WCID table and IVEIV table -#define RT28XX_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry) \ - { RT28XX_STA_ENTRY_MAC_RESET(pAd, pEntry->Aid); \ - if (pEntry->Aid >= 1) { \ - RT_SET_ASIC_WCID_ATTRI SetAsicWcidAttri; \ - SetAsicWcidAttri.WCID = pEntry->Aid; \ - if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && \ - (pEntry->WepStatus == Ndis802_11Encryption1Enabled)) \ - { \ - SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \ - } \ - else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone) \ - { \ - SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \ - } \ - else SetAsicWcidAttri.Cipher = 0; \ - DBGPRINT(RT_DEBUG_TRACE, ("aid cipher = %ld\n",SetAsicWcidAttri.Cipher)); \ - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID_CIPHER, \ - &SetAsicWcidAttri, sizeof(RT_SET_ASIC_WCID_ATTRI)); } } - -// Insert the BA bitmap to ASIC for the Wcid entry -#define RT28XX_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \ - do{ \ - RT_SET_ASIC_WCID SetAsicWcid; \ - SetAsicWcid.WCID = (_Aid); \ - SetAsicWcid.SetTid = (0x10000<<(_TID)); \ - SetAsicWcid.DeleteTid = 0xffffffff; \ - RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \ - }while(0) - -// Remove the BA bitmap from ASIC for the Wcid entry -#define RT28XX_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \ - do{ \ - RT_SET_ASIC_WCID SetAsicWcid; \ - SetAsicWcid.WCID = (_Wcid); \ - SetAsicWcid.SetTid = (0xffffffff); \ - SetAsicWcid.DeleteTid = (0x10000<<(_TID) ); \ - RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \ - }while(0) - - -/* ----------------- PCI/USB Related MACRO ----------------- */ -#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p) \ - ((POS_COOKIE)handle)->pUsb_Dev = dev_p; - -// no use -#define RT28XX_UNMAP() -#define RT28XX_IRQ_REQUEST(net_dev) -#define RT28XX_IRQ_RELEASE(net_dev) -#define RT28XX_IRQ_INIT(pAd) -#define RT28XX_IRQ_ENABLE(pAd) - - -/* ----------------- MLME Related MACRO ----------------- */ -#define RT28XX_MLME_HANDLER(pAd) RTUSBMlmeUp(pAd) - -#define RT28XX_MLME_PRE_SANITY_CHECK(pAd) \ - { if ((pAd->CommonCfg.bHardwareRadio == TRUE) && \ - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && \ - (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { \ - RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } } - -#define RT28XX_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \ - { RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0); \ - RTUSBMlmeUp(pAd); } - -#define RT28XX_MLME_RESET_STATE_MACHINE(pAd) \ - MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL); \ - RTUSBMlmeUp(pAd); - -#define RT28XX_HANDLE_COUNTER_MEASURE(_pAd, _pEntry) \ - { RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(MAC_TABLE_ENTRY)); \ - RTUSBMlmeUp(_pAd); \ - } - - -/* ----------------- Power Save Related MACRO ----------------- */ -#define RT28XX_PS_POLL_ENQUEUE(pAd) \ - { RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); \ - RTUSBKickBulkOut(pAd); } - -#define RT28xx_CHIP_NAME "RTxx70" - -#define USB_CYC_CFG 0x02a4 -#define STATUS_SUCCESS 0x00 -#define STATUS_UNSUCCESSFUL 0x01 -#define NT_SUCCESS(status) (((status) > 0) ? (1):(0)) -#define InterlockedIncrement atomic_inc -#define NdisInterlockedIncrement atomic_inc -#define InterlockedDecrement atomic_dec -#define NdisInterlockedDecrement atomic_dec -#define InterlockedExchange atomic_set -//#define NdisMSendComplete RTMP_SendComplete -#define NdisMCancelTimer RTMPCancelTimer -#define NdisAllocMemory(_ptr, _size, _flag) \ - do{_ptr = kmalloc((_size),(_flag));}while(0) -#define NdisFreeMemory(a, b, c) kfree((a)) -#define NdisMSleep RTMPusecDelay /* unit: microsecond */ - - -#define USBD_TRANSFER_DIRECTION_OUT 0 -#define USBD_TRANSFER_DIRECTION_IN 0 -#define USBD_SHORT_TRANSFER_OK 0 -#define PURB purbb_t - -#define RTUSB_FREE_URB(pUrb) usb_free_urb(pUrb) - -//#undef MlmeAllocateMemory -//#undef MlmeFreeMemory - -typedef struct usb_device * PUSB_DEV; - -/* MACRO for linux usb */ -typedef struct urb *purbb_t; -typedef struct usb_ctrlrequest devctrlrequest; -#define PIRP PVOID -#define PMDL PVOID -#define NDIS_OID UINT -#ifndef USB_ST_NOERROR -#define USB_ST_NOERROR 0 -#endif - -// vendor-specific control operations -#define CONTROL_TIMEOUT_JIFFIES ( (100 * HZ) / 1000) -#define UNLINK_TIMEOUT_MS 3 - -/* unlink urb */ -#define RTUSB_UNLINK_URB(pUrb) usb_kill_urb(pUrb) - -// Prototypes of completion funuc. -VOID RTUSBBulkOutDataPacketComplete(purbb_t purb, struct pt_regs *pt_regs); -VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs); -VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs); -VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs); -VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb, struct pt_regs *pt_regs); -VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs); - -#define RTUSBMlmeUp(pAd) \ -{ \ - POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \ - if (pid_nr(pObj->MLMEThr_pid) > 0) \ - up(&(pAd->mlme_semaphore)); \ -} - -#define RTUSBCMDUp(pAd) \ -{ \ - POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \ - if (pid_nr(pObj->RTUSBCmdThr_pid) > 0) \ - up(&(pAd->RTUSBCmd_semaphore)); \ -} - -static inline NDIS_STATUS RTMPAllocateMemory( - OUT PVOID *ptr, - IN size_t size) -{ - *ptr = kmalloc(size, GFP_ATOMIC); - if(*ptr) - return NDIS_STATUS_SUCCESS; - else - return NDIS_STATUS_RESOURCES; -} - -/* rtmp.h */ -#define BEACON_RING_SIZE 2 -#define DEVICE_VENDOR_REQUEST_OUT 0x40 -#define DEVICE_VENDOR_REQUEST_IN 0xc0 -#define INTERFACE_VENDOR_REQUEST_OUT 0x41 -#define INTERFACE_VENDOR_REQUEST_IN 0xc1 -#define MGMTPIPEIDX 0 // EP6 is highest priority - -#define BULKOUT_MGMT_RESET_FLAG 0x80 - -#define RTUSB_SET_BULK_FLAG(_M, _F) ((_M)->BulkFlags |= (_F)) -#define RTUSB_CLEAR_BULK_FLAG(_M, _F) ((_M)->BulkFlags &= ~(_F)) -#define RTUSB_TEST_BULK_FLAG(_M, _F) (((_M)->BulkFlags & (_F)) != 0) - -#define EnqueueCmd(cmdq, cmdqelmt) \ -{ \ - if (cmdq->size == 0) \ - cmdq->head = cmdqelmt; \ - else \ - cmdq->tail->next = cmdqelmt; \ - cmdq->tail = cmdqelmt; \ - cmdqelmt->next = NULL; \ - cmdq->size++; \ -} - -typedef struct _RT_SET_ASIC_WCID { - ULONG WCID; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based - ULONG SetTid; // time-based: seconds, packet-based: kilo-packets - ULONG DeleteTid; // time-based: seconds, packet-based: kilo-packets - UCHAR Addr[MAC_ADDR_LEN]; // avoid in interrupt when write key -} RT_SET_ASIC_WCID,*PRT_SET_ASIC_WCID; - -typedef struct _RT_SET_ASIC_WCID_ATTRI { - ULONG WCID; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based - ULONG Cipher; // ASIC Cipher definition - UCHAR Addr[ETH_LENGTH_OF_ADDRESS]; -} RT_SET_ASIC_WCID_ATTRI,*PRT_SET_ASIC_WCID_ATTRI; - -typedef struct _MLME_MEMORY_STRUCT { - PVOID AllocVa; //Pointer to the base virtual address of the allocated memory - struct _MLME_MEMORY_STRUCT *Next; //Pointer to the next virtual address of the allocated memory -} MLME_MEMORY_STRUCT, *PMLME_MEMORY_STRUCT; - -typedef struct _MLME_MEMORY_HANDLER { - BOOLEAN MemRunning; //The flag of the Mlme memory handler's status - UINT MemoryCount; //Total nonpaged system-space memory not size - UINT InUseCount; //Nonpaged system-space memory in used counts - UINT UnUseCount; //Nonpaged system-space memory available counts - INT PendingCount; //Nonpaged system-space memory for free counts - PMLME_MEMORY_STRUCT pInUseHead; //Pointer to the first nonpaed memory not used - PMLME_MEMORY_STRUCT pInUseTail; //Pointer to the last nonpaged memory not used - PMLME_MEMORY_STRUCT pUnUseHead; //Pointer to the first nonpaged memory in used - PMLME_MEMORY_STRUCT pUnUseTail; //Pointer to the last nonpaged memory in used - PULONG MemFreePending[MAX_MLME_HANDLER_MEMORY]; //an array to keep pending free-memory's pointer (32bits) -} MLME_MEMORY_HANDLER, *PMLME_MEMORY_HANDLER; - -typedef struct _CmdQElmt { - UINT command; - PVOID buffer; - ULONG bufferlength; - BOOLEAN CmdFromNdis; - BOOLEAN SetOperation; - struct _CmdQElmt *next; -} CmdQElmt, *PCmdQElmt; - -typedef struct _CmdQ { - UINT size; - CmdQElmt *head; - CmdQElmt *tail; - UINT32 CmdQState; -}CmdQ, *PCmdQ; - -/* oid.h */ -// Cipher suite type for mixed mode group cipher, P802.11i-2004 -typedef enum _RT_802_11_CIPHER_SUITE_TYPE { - Cipher_Type_NONE, - Cipher_Type_WEP40, - Cipher_Type_TKIP, - Cipher_Type_RSVD, - Cipher_Type_CCMP, - Cipher_Type_WEP104 -} RT_802_11_CIPHER_SUITE_TYPE, *PRT_802_11_CIPHER_SUITE_TYPE; - -//CMDTHREAD_MULTI_READ_MAC -//CMDTHREAD_MULTI_WRITE_MAC -//CMDTHREAD_VENDOR_EEPROM_READ -//CMDTHREAD_VENDOR_EEPROM_WRITE -typedef struct _CMDHandler_TLV { - USHORT Offset; - USHORT Length; - UCHAR DataFirst; -} CMDHandler_TLV, *PCMDHandler_TLV; - -// New for MeetingHouse Api support -#define CMDTHREAD_VENDOR_RESET 0x0D730101 // cmd -#define CMDTHREAD_VENDOR_UNPLUG 0x0D730102 // cmd -#define CMDTHREAD_VENDOR_SWITCH_FUNCTION 0x0D730103 // cmd -#define CMDTHREAD_MULTI_WRITE_MAC 0x0D730107 // cmd -#define CMDTHREAD_MULTI_READ_MAC 0x0D730108 // cmd -#define CMDTHREAD_VENDOR_EEPROM_WRITE 0x0D73010A // cmd -#define CMDTHREAD_VENDOR_EEPROM_READ 0x0D73010B // cmd -#define CMDTHREAD_VENDOR_ENTER_TESTMODE 0x0D73010C // cmd -#define CMDTHREAD_VENDOR_EXIT_TESTMODE 0x0D73010D // cmd -#define CMDTHREAD_VENDOR_WRITE_BBP 0x0D730119 // cmd -#define CMDTHREAD_VENDOR_READ_BBP 0x0D730118 // cmd -#define CMDTHREAD_VENDOR_WRITE_RF 0x0D73011A // cmd -#define CMDTHREAD_VENDOR_FLIP_IQ 0x0D73011D // cmd -#define CMDTHREAD_RESET_BULK_OUT 0x0D730210 // cmd -#define CMDTHREAD_RESET_BULK_IN 0x0D730211 // cmd -#define CMDTHREAD_SET_PSM_BIT_SAVE 0x0D730212 // cmd -#define CMDTHREAD_SET_RADIO 0x0D730214 // cmd -#define CMDTHREAD_UPDATE_TX_RATE 0x0D730216 // cmd -#define CMDTHREAD_802_11_ADD_KEY_WEP 0x0D730218 // cmd -#define CMDTHREAD_RESET_FROM_ERROR 0x0D73021A // cmd -#define CMDTHREAD_LINK_DOWN 0x0D73021B // cmd -#define CMDTHREAD_RESET_FROM_NDIS 0x0D73021C // cmd -#define CMDTHREAD_CHECK_GPIO 0x0D730215 // cmd -#define CMDTHREAD_FORCE_WAKE_UP 0x0D730222 // cmd -#define CMDTHREAD_SET_BW 0x0D730225 // cmd -#define CMDTHREAD_SET_ASIC_WCID 0x0D730226 // cmd -#define CMDTHREAD_SET_ASIC_WCID_CIPHER 0x0D730227 // cmd -#define CMDTHREAD_QKERIODIC_EXECUT 0x0D73023D // cmd -#define CMDTHREAD_SET_CLIENT_MAC_ENTRY 0x0D73023E // cmd -#define CMDTHREAD_802_11_QUERY_HARDWARE_REGISTER 0x0D710105 // cmd -#define CMDTHREAD_802_11_SET_PHY_MODE 0x0D79010C // cmd -#define CMDTHREAD_802_11_SET_STA_CONFIG 0x0D790111 // cmd -#define CMDTHREAD_802_11_SET_PREAMBLE 0x0D790101 // cmd -#define CMDTHREAD_802_11_COUNTER_MEASURE 0x0D790102 // cmd -#define CMDTHREAD_UPDATE_PROTECT 0x0D790103 // cmd - -#define WPA1AKMBIT 0x01 -#define WPA2AKMBIT 0x02 -#define WPA1PSKAKMBIT 0x04 -#define WPA2PSKAKMBIT 0x08 -#define TKIPBIT 0x01 -#define CCMPBIT 0x02 - - -#define RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx) \ - RT28xxUsbStaAsicForceWakeup(pAd, bFromTx); - -#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \ - RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp); - -#define RT28XX_MLME_RADIO_ON(pAd) \ - RT28xxUsbMlmeRadioOn(pAd); - -#define RT28XX_MLME_RADIO_OFF(pAd) \ - RT28xxUsbMlmeRadioOFF(pAd); - -#endif //__RT2870_H__ Index: b/drivers/staging/rt2870/rt_usb.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/rt_usb.c @@ -0,0 +1 @@ +#include "../rt2860/rt_usb.c" Index: b/drivers/staging/rt2870/usb_main_dev.c =================================================================== --- /dev/null +++ b/drivers/staging/rt2870/usb_main_dev.c @@ -0,0 +1 @@ +#include "../rt2860/usb_main_dev.c" Index: b/drivers/staging/rt3070/firmware.h =================================================================== --- a/drivers/staging/rt3070/firmware.h +++ b/drivers/staging/rt3070/firmware.h @@ -43,7 +43,7 @@ /* AUTO GEN PLEASE DO NOT MODIFY IT */ -UCHAR FirmwareImage [] = { +UCHAR FirmwareImage_2870 [] = { 0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02, 0x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02, 0x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,