summaryrefslogtreecommitdiffstats
path: root/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8192cd_osdep.c
diff options
context:
space:
mode:
authorRoman Yeryomin <roman@advem.lv>2012-09-13 00:40:35 +0300
committerRoman Yeryomin <roman@advem.lv>2012-12-03 00:13:21 +0200
commit5deb3317cb51ac52de922bb55f8492624018906d (patch)
treec2fbe6346699d9bb0f2100490c3029519bb8fde8 /target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8192cd_osdep.c
parent0239d37124f9184b478a42de8a7fa1bc85a6a6fe (diff)
Add realtek target files
Signed-off-by: Roman Yeryomin <roman@advem.lv>
Diffstat (limited to 'target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8192cd_osdep.c')
-rw-r--r--target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8192cd_osdep.c7899
1 files changed, 7899 insertions, 0 deletions
diff --git a/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8192cd_osdep.c b/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8192cd_osdep.c
new file mode 100644
index 000000000..a85745b42
--- /dev/null
+++ b/target/linux/realtek/files/drivers/net/wireless/rtl8192cd/8192cd_osdep.c
@@ -0,0 +1,7899 @@
+/*
+ * Routines to handle OS dependent jobs and interfaces
+ *
+ * $Id: 8192cd_osdep.c,v 1.61.2.28 2011/01/11 13:48:37 button Exp $
+ *
+ * Copyright (c) 2009 Realtek Semiconductor Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*-----------------------------------------------------------------------------
+ This file is for OS related functions.
+------------------------------------------------------------------------------*/
+#define _8192CD_OSDEP_C_
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/in.h>
+#include <linux/if.h>
+#include <linux/ip.h>
+#include <asm/io.h>
+#include <linux/skbuff.h>
+#include <linux/socket.h>
+#include <linux/fs.h>
+#include <linux/major.h>
+#include <linux/fcntl.h>
+#include <linux/signal.h>
+#include <asm/uaccess.h>
+#include <linux/sched.h>
+#endif
+
+#ifdef __DRAYTEK_OS__
+#include <draytek/softimer.h>
+#include <draytek/skbuff.h>
+#include <draytek/wl_dev.h>
+#endif
+
+#include "./8192cd_cfg.h"
+
+#ifdef __KERNEL__
+#ifdef __LINUX_2_6__
+#include <linux/syscalls.h>
+#include <linux/file.h>
+#include <asm/unistd.h>
+#endif
+#if defined(RTK_BR_EXT) || defined(BR_SHORTCUT)
+#ifdef __LINUX_2_6__
+#include <linux/syscalls.h>
+#else
+#include <linux/fs.h>
+#endif
+#include <../net/bridge/br_private.h>
+#endif
+#else
+#include "./sys-support.h"
+#endif
+
+#include "./8192cd.h"
+#include "./8192cd_hw.h"
+#include "./8192cd_headers.h"
+#include "./8192cd_rx.h"
+#include "./8192cd_debug.h"
+
+#ifdef RTL8192CD_VARIABLE_USED_DMEM
+#include "./8192cd_dmem.h"
+#endif
+
+#ifdef CONFIG_RTL_92D_DMDP
+u32 if_priv[NUM_WLAN_IFACE];
+#endif
+
+#ifdef CONFIG_RTK_MESH
+#include "./mesh_ext/mesh_route.h" // Note : Not include in #ifdef CONFIG_RTK_MESH, Because use in wlan_device[]
+#include "./mesh_ext/mesh_util.h"
+#endif // CONFIG_RTK_MESH
+
+#ifdef CONFIG_RTL_KERNEL_MIPS16_WLAN
+#include <asm/mips16_lib.h>
+#endif
+
+#ifndef CONFIG_RTK_MESH //move below from mesh_route.h ; plus 0119
+#define MESH_SHIFT 0
+#define MESH_NUM_CFG 0
+#else
+#define MESH_SHIFT 8 // ACCESS_MASK uses 2 bits, WDS_MASK use 4 bits
+#define MESH_MASK 0x3
+#define MESH_NUM_CFG NUM_MESH
+#endif
+
+
+#if defined(CONFIG_RTL_8198)
+#define CONFIG_RTL8198_REVISION_B 1
+//#define CONFIG_PHY_EAT_40MHZ 1
+#endif
+
+#ifdef CONFIG_RTL8672
+#include <platform.h>
+#else
+#if !defined(CONFIG_NET_PCI) && defined(CONFIG_RTL8196B)
+#include <asm/rtl865x/platform.h>
+#endif
+
+#if !defined(CONFIG_NET_PCI) && defined(CONFIG_RTL8196C)
+#include <asm/rtl865x/platform.h>
+#endif
+#endif
+
+#if !defined(CONFIG_NET_PCI) && defined(CONFIG_RTL_819X) && defined(__LINUX_2_6__)
+#if !defined(USE_RLX_BSP)
+#include <platform.h>
+#else
+#include <bsp/bspchip.h>
+#endif
+#endif
+
+#if defined(CONFIG_RTL_WAPI_SUPPORT)
+#include "wapiCrypto.h"
+#endif
+#ifdef CONFIG_RTL_CUSTOM_PASSTHRU //mark_test
+#include <linux/proc_fs.h>
+#endif
+#ifdef CONFIG_WIRELESS_LAN_MODULE
+extern int (*wirelessnet_hook)(void);
+#ifdef BR_SHORTCUT
+extern struct net_device* (*wirelessnet_hook_shortcut)(unsigned char *da);
+#endif
+#ifdef PERF_DUMP
+extern int rtl8651_romeperfEnterPoint(unsigned int index);
+extern int rtl8651_romeperfExitPoint(unsigned int index);
+extern int (*Fn_rtl8651_romeperfEnterPoint)(unsigned int index);
+extern int (*Fn_rtl8651_romeperfExitPoint)(unsigned int index);
+#endif
+#ifdef CONFIG_RTL8190_PRIV_SKB
+extern int (*wirelessnet_hook_is_priv_buf)(void);
+extern void (*wirelessnet_hook_free_priv_buf)(unsigned char *head);
+#endif
+#endif // CONFIG_WIRELESS_LAN_MODULE
+
+struct _device_info_ wlan_device[] =
+{
+#if defined(USE_RTL8186_SDK)
+ //{(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_EMBEDDED<<TYPE_SHIFT), 0, 0xbd400000, 2, NULL},
+ #ifdef CONFIG_NET_PCI
+ {(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_BIOS<<TYPE_SHIFT) | ACCESS_SWAP_MEM, 0, 0, 0, NULL},
+ #else
+ #ifdef IO_MAPPING
+ {(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, PCI_SLOT1_CONFIG_ADDR, 0xb8C00000, 3, NULL},
+ #else
+ #if defined(CONFIG_RTL8196B) || defined(CONFIG_RTL8196C) || defined(CONFIG_RTL_819X)
+ #if defined(__LINUX_2_6__) && defined(USE_RLX_BSP)
+ #if defined(CONFIG_RTL_92D_SUPPORT)
+ #if (RTL_USED_PCIE_SLOT==0)
+ {(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, BSP_PCIE0_D_CFG0, BSP_PCIE0_D_MEM, BSP_PCIE_IRQ, NULL},
+ #ifdef CONFIG_RTL_92D_DMDP
+ {(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, BSP_PCIE0_D_CFG0, BSP_PCIE0_F1_D_MEM, BSP_PCIE_IRQ, NULL},
+ #endif
+ #elif (RTL_USED_PCIE_SLOT==1)
+ {(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, BSP_PCIE1_D_CFG0, BSP_PCIE1_D_MEM, BSP_PCIE2_IRQ, NULL},
+ #ifdef CONFIG_RTL_92D_DMDP
+ {(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, BSP_PCIE1_D_CFG0, BSP_PCIE1_F1_D_MEM, BSP_PCIE2_IRQ, NULL},
+ #endif
+ #if defined(CONFIG_RTL_DUAL_PCIESLOT_BIWLAN_D) || defined(CONFIG_RTL_DUAL_PCIESLOT_BIWLAN)
+ {(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, BSP_PCIE0_D_CFG0, BSP_PCIE0_D_MEM, BSP_PCIE_IRQ, NULL},
+ #endif
+
+
+
+ #else
+ #error "define pcie error"
+ #endif
+ #else
+ {(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, BSP_PCIE0_D_CFG0, BSP_PCIE0_D_MEM, BSP_PCIE_IRQ, NULL},
+ #if defined(CONFIG_RTL_DUAL_PCIESLOT_BIWLAN)
+ {(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, BSP_PCIE1_D_CFG0, BSP_PCIE1_D_MEM, BSP_PCIE2_IRQ, NULL}
+ #endif
+ #endif
+#else
+ {(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, PCIE0_D_CFG0, PCIE0_D_MEM, PCIE_IRQ, NULL},
+ #ifdef CONFIG_RTL_92D_DMDP
+ {(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, PCIE0_D_CFG0, PCIE0_F1_D_MEM, PCIE_IRQ, NULL},
+ #endif
+#endif
+ //{(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_BIOS<<TYPE_SHIFT) | ACCESS_SWAP_MEM, 0, 0, 0, NULL},
+ #else
+ {(MESH_NUM_CFG<<MESH_SHIFT) | (WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, PCI_SLOT1_CONFIG_ADDR, 0xb9000000, 3, NULL},
+ #endif
+ #endif
+ #endif
+#elif defined(NOT_RTK_BSP)
+ {(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_BIOS<<TYPE_SHIFT) | ACCESS_SWAP_MEM, 0, 0, 0, NULL}
+#elif defined(CONFIG_RTL8671)
+ #ifdef IO_MAPPING
+ {(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, PCI_SLOT0_CONFIG_ADDR, 0xbd200000, 7, NULL},
+ #else
+ {(MESH_NUM_CFG<<MESH_SHIFT) |(WDS_NUM_CFG<<WDS_SHIFT) | (TYPE_PCI_DIRECT<<TYPE_SHIFT) | ACCESS_SWAP_MEM, PCI_SLOT0_CONFIG_ADDR, 0xbd300000, 7, NULL},
+ #endif
+#else
+ #error No_System_Defined
+#endif
+};
+
+static int wlan_index=0;
+
+#ifdef CONFIG_RTL8672
+// Added by Mason Yu
+// MBSSID Port Mapping
+struct port_map wlanDev[RTL8192CD_NUM_VWLAN+1];
+static int wlanDevNum=0;
+#endif
+
+#ifdef PRIV_STA_BUF
+#ifdef CONCURRENT_MODE
+static struct rtl8192cd_hw hw_info[NUM_WLAN_IFACE];
+static struct priv_shared_info shared_info[NUM_WLAN_IFACE];
+static struct wlan_hdr_poll hdr_pool[NUM_WLAN_IFACE];
+static struct wlanllc_hdr_poll llc_pool[NUM_WLAN_IFACE];
+static struct wlanbuf_poll buf_pool[NUM_WLAN_IFACE];
+static struct wlanicv_poll icv_pool[NUM_WLAN_IFACE];
+static struct wlanmic_poll mic_pool[NUM_WLAN_IFACE];
+static unsigned char desc_buf[NUM_WLAN_IFACE][DESC_DMA_PAGE_SIZE];
+static int wlandev_idx = 0;
+
+#else
+static struct rtl8192cd_hw hw_info;
+static struct priv_shared_info shared_info;
+static struct wlan_hdr_poll hdr_pool;
+static struct wlanllc_hdr_poll llc_pool;
+static struct wlanbuf_poll buf_pool;
+static struct wlanicv_poll icv_pool;
+static struct wlanmic_poll mic_pool;
+static unsigned char desc_buf[DESC_DMA_PAGE_SIZE];
+#endif
+#endif
+
+// init and remove char device
+#ifdef CONFIG_WIRELESS_LAN_MODULE
+extern int rtl8192cd_chr_init(void);
+extern void rtl8192cd_chr_exit(void);
+#else
+int rtl8192cd_chr_init(void);
+void rtl8192cd_chr_exit(void);
+#endif
+struct rtl8192cd_priv *rtl8192cd_chr_reg(unsigned int minor, struct rtl8192cd_chr_priv *priv);
+void rtl8192cd_chr_unreg(unsigned int minor);
+int rtl8192cd_fileopen(const char *filename, int flags, int mode);
+
+__MIPS16
+__IRAM_IN_865X
+struct net_device *get_shortcut_dev(unsigned char *da);
+
+void force_stop_wlan_hw(void);
+
+
+#if defined(_INCLUDE_PROC_FS_) && defined(PERF_DUMP)
+#include "romeperf.h"
+static int read_perf_dump(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv;
+ unsigned long x;
+
+ SAVE_INT_AND_CLI(x);
+
+ rtl8651_romeperfDump(1, 1);
+
+ RESTORE_INT(x);
+ return count;
+}
+
+
+static int flush_perf_dump(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv;
+ unsigned long x;
+
+ SAVE_INT_AND_CLI(x);
+
+ rtl8651_romeperfReset();
+
+ RESTORE_INT(x);
+ return count;
+}
+#endif // _INCLUDE_PROC_FS_ && PERF_DUMP
+
+#define GPIO_BASE 0xB8003500
+#define PEFGHCNR_REG (0x01C + GPIO_BASE) /* Port EFGH control */
+#define PEFGHPTYPE_REG (0x020 + GPIO_BASE) /* Port EFGH type */
+#define PEFGHDIR_REG (0x024 + GPIO_BASE) /* Port EFGH direction */
+#define PEFGHDAT_REG (0x028 + GPIO_BASE) /* Port EFGH data */
+#ifndef REG32
+ #define REG32(reg) (*(volatile unsigned int *)(reg))
+#endif
+
+#ifdef CONFIG_RTL_92D_DMDP
+void Sw_PCIE_Func(int func)
+{
+#if (RTL_USED_PCIE_SLOT==1)
+ REG32(0xb8b2100c)=REG32(0xb8b2100c)|func; // switch to function #
+#else
+ REG32(0xb8b0100c)=REG32(0xb8b0100c)|func; // switch to function #
+#endif
+}
+#endif
+#if !defined(CONFIG_NET_PCI) && (defined(CONFIG_RTL8196B) || defined(CONFIG_RTL_819X))
+#define MAX_PAYLOAD_SIZE_128B 0x00
+
+#if !(defined(CONFIG_RTL8196C) || defined(CONFIG_RTL_8196C))
+#ifdef CONFIG_RTL_KERNEL_MIPS16_WLAN
+__NOMIPS16
+#endif
+static int rtl8196b_pci_reset(unsigned long conf_addr)
+{
+ /* If PCI needs to be reset, put code here.
+ * Note:
+ * Software may need to do hot reset for a period of time, say ~100us.
+ * Here we put 2ms.
+ */
+ //Modified for PCIE PHY parameter due to RD center suggestion by Jason 12252009
+ WRITE_MEM32(0xb8000044, 0x9);//Enable PCIE PLL
+ delay_ms(10);
+ REG32(0xb8000010)=REG32(0xb8000010)|(0x500); //Active LX & PCIE Clock in 8196B system register
+ delay_ms(10);
+ WRITE_MEM32(0xb800003C, 0x1);//PORT0 PCIE PHY MDIO Reset
+ delay_ms(10);
+ WRITE_MEM32(0xb800003C, 0x3);//PORT0 PCIE PHY MDIO Reset
+ delay_ms(10);
+ WRITE_MEM32(0xb8000040, 0x1);//PORT1 PCIE PHY MDIO Reset
+ delay_ms(10);
+ WRITE_MEM32(0xb8000040, 0x3);//PORT1 PCIE PHY MDIO Reset
+ delay_ms(10);
+ WRITE_MEM32(0xb8b01008, 0x1);// PCIE PHY Reset Close:Port 0
+ delay_ms(10);
+ WRITE_MEM32(0xb8b01008, 0x81);// PCIE PHY Reset On:Port 0
+ delay_ms(10);
+#ifdef PIN_208
+ WRITE_MEM32(0xb8b21008, 0x1);// PCIE PHY Reset Close:Port 1
+ delay_ms(10);
+ WRITE_MEM32(0xb8b21008, 0x81);// PCIE PHY Reset On:Port 1
+ delay_ms(10);
+#endif
+#ifdef OUT_CYSTALL
+ WRITE_MEM32(0xb8b01000, 0xcc011901);// PCIE PHY Reset On:Port 0
+ delay_ms(10);
+#ifdef PIN_208
+ WRITE_MEM32(0xb8b21000, 0xcc011901);// PCIE PHY Reset On:Port 1
+ delay_ms(10);
+#endif
+#endif
+ REG32(0xb8000010)=REG32(0xb8000010)|(0x01000000); //PCIE PHY Reset On:Port 0
+ delay_ms(10);
+
+#if defined(__LINUX_2_6__) && defined(USE_RLX_BSP)
+ WRITE_MEM32(BSP_PCIE0_H_PWRCR, READ_MEM32(BSP_PCIE0_H_PWRCR) & 0xFFFFFF7F);
+#ifdef PIN_208
+ WRITE_MEM32(BSP_PCIE1_H_PWRCR, READ_MEM32(BSP_PCIE1_H_PWRCR) & 0xFFFFFF7F);
+#endif
+ delay_ms(100);
+ WRITE_MEM32(BSP_PCIE0_H_PWRCR, READ_MEM32(BSP_PCIE0_H_PWRCR) | 0x00000080);
+#ifdef PIN_208
+ WRITE_MEM32(BSP_PCIE1_H_PWRCR, READ_MEM32(BSP_PCIE1_H_PWRCR) | 0x00000080);
+#endif
+#else
+ WRITE_MEM32(PCIE0_H_PWRCR, READ_MEM32(PCIE0_H_PWRCR) & 0xFFFFFF7F);
+#ifdef PIN_208
+ WRITE_MEM32(PCIE1_H_PWRCR, READ_MEM32(PCIE1_H_PWRCR) & 0xFFFFFF7F);
+#endif
+ delay_ms(100);
+ WRITE_MEM32(PCIE0_H_PWRCR, READ_MEM32(PCIE0_H_PWRCR) | 0x00000080);
+#ifdef PIN_208
+ WRITE_MEM32(PCIE1_H_PWRCR, READ_MEM32(PCIE1_H_PWRCR) | 0x00000080);
+#endif
+#endif
+
+ delay_ms(10);
+
+ if ((READ_MEM32(0xb8b00728)&0x1f)!=0x11)
+ {
+ _DEBUG_INFO("PCIE LINK FAIL\n");
+ return FAIL;
+ }
+
+ // Enable PCIE host
+#if defined(__LINUX_2_6__) && defined(USE_RLX_BSP)
+ WRITE_MEM32(BSP_PCIE0_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(BSP_PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#else
+ WRITE_MEM32(PCIE0_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#endif
+ return SUCCESS;
+}
+#endif // !defined(CONFIG_NET_PCI) && (defined(CONFIG_RTL8196B) || defined(CONFIG_RTL_819X))
+#endif
+
+
+#if defined(CONFIG_RTL_8198) || defined(CONFIG_RTL8196C) || defined(CONFIG_RTL_8196C)
+#define MAX_PAYLOAD_SIZE_128B 0x00
+
+#define CLK_MANAGE 0xb8000010
+#define PCIE0_RC_EXT_BASE (0xb8b01000)
+#define PCIE1_RC_EXT_BASE (0xb8b21000)
+//RC Extended register
+#define PCIE0_MDIO (PCIE0_RC_EXT_BASE+0x00)
+#define PCIE1_MDIO (PCIE1_RC_EXT_BASE+0x00)
+//MDIO
+#define PCIE_MDIO_DATA_OFFSET (16)
+#define PCIE_MDIO_DATA_MASK (0xffff <<PCIE_MDIO_DATA_OFFSET)
+#define PCIE_MDIO_REG_OFFSET (8)
+#define PCIE_MDIO_RDWR_OFFSET (0)
+#if !defined(CONFIG_NET_PCI) && defined(CONFIG_RTL_8198)
+#define PHY_EAT_40MHZ 1
+#endif
+
+#if !defined(CONFIG_NET_PCI) && !defined(CONFIG_PCI)
+#if defined(__LINUX_2_6__) && defined(USE_RLX_BSP)
+#define PCIE0_H_CFG BSP_PCIE0_H_CFG
+#define PCIE1_H_CFG BSP_PCIE1_H_CFG
+#endif
+
+void HostPCIe_SetPhyMdioWrite(unsigned int portnum, unsigned int regaddr, unsigned short val)
+{
+ unsigned int mdioaddr;
+ volatile int i;
+
+ if(portnum==0) mdioaddr=PCIE0_MDIO;
+ else if(portnum==1) mdioaddr=PCIE1_MDIO;
+ else return;
+
+ REG32(mdioaddr)= ( (regaddr&0x1f)<<PCIE_MDIO_REG_OFFSET) | ((val&0xffff)<<PCIE_MDIO_DATA_OFFSET) | (1<<PCIE_MDIO_RDWR_OFFSET) ;
+ //delay
+ for(i=0;i<5555;i++) ;
+ mdelay(1);
+}
+#if defined(CONFIG_RTL_8196CS) || defined(CONFIG_RTL_8197B)
+static void GPIO6_PCIE_Device_PERST(void)
+
+{
+
+#if defined(CONFIG_RTL_8197B)
+ REG32(0xb8000040)=REG32(0xb8000040)|0x00018;
+
+ REG32(0xb8003500)=REG32(0xb8003500)&(~0x10);
+
+ REG32(0xb8003508)= REG32(0xb8003508)|0x10;
+
+ REG32(0xb800350c)= REG32(0xb800350c)|0x10;
+
+ delay_ms(500);
+
+ delay_ms(500);
+
+
+
+ // 6. PCIE Device Reset
+
+ //REG32(CLK_MANAGE) &= ~(1<<26); //perst=0 off.
+
+ REG32(0xb800350c)= REG32(0xb800350c)&(~0x10);
+
+ delay_ms(500); //PCIE standadrd: poweron: 100us, after poweron: 100ms
+
+ delay_ms(500);
+
+ REG32(0xb800350c)= REG32(0xb800350c)|0x10;
+#else
+ REG32(0xb8000040)=REG32(0xb8000040)|0x300000;
+
+ REG32(0xb8003500)=REG32(0xb8003500)&(~0x40);
+
+ REG32(0xb8003508)= REG32(0xb8003508)|0x40;
+
+ REG32(0xb800350c)= REG32(0xb800350c)|0x40;
+
+ delay_ms(500);
+
+ delay_ms(500);
+
+
+
+ // 6. PCIE Device Reset
+
+ //REG32(CLK_MANAGE) &= ~(1<<26); //perst=0 off.
+
+ REG32(0xb800350c)= REG32(0xb800350c)&(~0x40);
+
+ delay_ms(500); //PCIE standadrd: poweron: 100us, after poweron: 100ms
+
+ delay_ms(500);
+
+ REG32(0xb800350c)= REG32(0xb800350c)|0x40;
+
+ // REG32(CLK_MANAGE) |= (1<<26); //PERST=1
+#endif
+}
+#endif
+#ifdef CONFIG_RTL_8196C_iNIC //mark_inic
+static void iNIC_PCIE_Device_PERST(void)
+
+{
+
+ REG32(0xb8000040)=REG32(0xb8000040)|0x300000;
+
+ REG32(0xb8003500)=REG32(0xb8003500)&(~0x40);
+
+ REG32(0xb8003508)= REG32(0xb8003508)|0x40;
+
+ REG32(0xb800350c)= REG32(0xb800350c)|0x40;
+
+ delay_ms(500);
+
+ delay_ms(500);
+
+
+
+ // 6. PCIE Device Reset
+
+ //REG32(CLK_MANAGE) &= ~(1<<26); //perst=0 off.
+
+ REG32(0xb800350c)= REG32(0xb800350c)&(~0x40);
+
+ delay_ms(500); //PCIE standadrd: poweron: 100us, after poweron: 100ms
+
+ delay_ms(500);
+
+ REG32(0xb800350c)= REG32(0xb800350c)|0x40;
+
+ // REG32(CLK_MANAGE) |= (1<<26); //PERST=1
+
+}
+#endif
+
+#if defined(CONFIG_RTL_8198)
+static int at2_mode=0;
+static void PCIE_Device_PERST(int portnum)
+{
+ if (portnum==0)
+ {
+ REG32(CLK_MANAGE) &= ~(1<<26); //perst=0 off.
+ mdelay(500); //PCIE standadrd: poweron: 100us, after poweron: 100ms
+ mdelay(500);
+ REG32(CLK_MANAGE) |= (1<<26); //PERST=1
+ }
+ else if (portnum==1)
+ {
+ /* PCIE Device Reset
+ * The pcei1 slot reset register depends on the hw
+ */
+
+#if defined(CONFIG_RTL_DUAL_PCIESLOT_BIWLAN) || (RTL_USED_PCIE_SLOT==1) || defined(CONFIG_RTL_DUAL_PCIESLOT_BIWLAN_D)
+#if defined(CONFIG_RTL_8197B)
+ GPIO6_PCIE_Device_PERST();
+#else
+ REG32(PEFGHDAT_REG) &= ~(0x1000); //perst=0 off.
+ mdelay(300); //PCIE standadrd: poweron: 100us, after poweron: 100ms
+ mdelay(300);
+ REG32(PEFGHDAT_REG) |= (0x1000); //PERST=1
+#endif
+#elif defined(CONFIG_RTL_92D_SUPPORT)
+ REG32(CLK_MANAGE) &= ~(1<<26); //perst=0 off.
+ mdelay(500); //PCIE standadrd: poweron: 100us, after poweron: 100ms
+ mdelay(500);
+ REG32(CLK_MANAGE) |= (1<<26); //PERST=1
+#endif
+ }
+ else
+ return;
+}
+
+void PCIE_MDIO_Reset(unsigned int portnum)
+{
+ #define SYS_PCIE_PHY0 (0xb8000000 +0x50)
+ #define SYS_PCIE_PHY1 (0xb8000000 +0x54)
+
+ unsigned int sys_pcie_phy;
+
+ if(portnum==0) sys_pcie_phy=SYS_PCIE_PHY0;
+ else if(portnum==1) sys_pcie_phy=SYS_PCIE_PHY1;
+ else return;
+
+ // 3.MDIO Reset
+ REG32(sys_pcie_phy) = (1<<3) |(0<<1) | (0<<0); //mdio reset=0,
+ REG32(sys_pcie_phy) = (1<<3) |(0<<1) | (1<<0); //mdio reset=1,
+ REG32(sys_pcie_phy) = (1<<3) |(1<<1) | (1<<0); //bit1 load_done=1
+}
+
+void PCIE_PHY_Reset(unsigned int portnum)
+{
+ #define PCIE_PHY0 0xb8b01008
+ #define PCIE_PHY1 0xb8b21008
+
+ unsigned int pcie_phy;
+
+ if(portnum==0) pcie_phy=BSP_PCIE0_H_PWRCR;
+ else if(portnum==1) pcie_phy=BSP_PCIE1_H_PWRCR;
+ else return;
+
+ //4. PCIE PHY Reset
+ REG32(pcie_phy) = 0x01; //bit7:PHY reset=0 bit0: Enable LTSSM=1
+ REG32(pcie_phy) = 0x81; //bit7: PHY reset=1 bit0: Enable LTSSM=1
+}
+
+int PCIE_Check_Link(unsigned int portnum)
+{
+ unsigned int dbgaddr;
+ unsigned int cfgaddr=0;
+ int i=10;
+
+ if(portnum==0) dbgaddr=0xb8b00728;
+ else if(portnum==1) dbgaddr=0xb8b20728;
+ else return 1;
+
+
+ //wait for LinkUP
+
+ while(--i)
+ {
+ if( (REG32(dbgaddr)&0x1f)==0x11)
+ break;
+
+ mdelay(100);
+ }
+
+ if(i==0)
+ { if(at2_mode==0) //not auto test, show message
+ printk("i=%x Cannot LinkUP \n",i);
+ return 0;
+ }
+ else
+ {
+ if(portnum==0) cfgaddr=0xb8b10000;
+ else if(portnum==1) cfgaddr=0xb8b30000;
+
+ if(at2_mode==0)
+ printk("Find Port=%x Device:Vender ID=%x\n", portnum, REG32(cfgaddr) );
+ }
+ return 1;
+}
+
+int PCIE_reset_procedure(int portnum, int Use_External_PCIE_CLK, int mdio_reset, unsigned long conf_addr)
+{
+ static int pcie_reset_done[RTL_MAX_PCIE_SLOT_NUM] = {0};
+ int status=FAIL;
+
+
+ #if defined(CONFIG_RTL_DUAL_PCIESLOT_BIWLAN) || (RTL_USED_PCIE_SLOT==1) || defined(CONFIG_RTL_DUAL_PCIESLOT_BIWLAN_D)
+ if (portnum==0)
+ {
+ REG32(CLK_MANAGE) |= (1<<26); //PERST=1
+ }
+ else if (portnum==1)
+ {
+ #if defined(CONFIG_RTL_8197B)
+ REG32(0xb8000040)|=0x18;
+ REG32(0xb8003500) &= ~(0x10); /*port Abit 4 */
+ REG32(0xb8003508) |= (0x10); /*port A bit 4 */
+ REG32(0xb800350c) |= (0x10); //PERST=1
+
+ #else
+ REG32(0xb8000040)|=0x300;
+ REG32(PEFGHCNR_REG) &= ~(0x1000); /*port F bit 4 */
+ REG32(PEFGHDIR_REG) |= (0x1000); /*port F bit 4 */
+ REG32(PEFGHDAT_REG) |= (0x1000); //PERST=1
+ #endif
+ }
+ #endif
+
+ if (pcie_reset_done[portnum])
+ goto SET_BAR;
+
+ printk("PCIE reset (%d) \n", pcie_reset_done[portnum]);
+ if(portnum==0) REG32(CLK_MANAGE) |= (1<<14); //enable active_pcie0
+ else if(portnum==1) REG32(CLK_MANAGE) |= (1<<16); //enable active_pcie1
+ else return 0;
+
+ mdelay(500);
+
+ #ifdef CONFIG_RTL8198_REVISION_B
+ if(portnum==1)
+ {
+ #define PAD_CONTROL 0xb8000048
+ REG32(PAD_CONTROL)|=(1<<27);
+ }
+ #endif
+ mdelay(500);
+
+
+ if(mdio_reset)
+ {
+ if(at2_mode==0) //no auto test, show message
+ printk("Do MDIO_RESET\n");
+
+ // 3.MDIO Reset
+ PCIE_MDIO_Reset(portnum);
+ }
+
+ /*
+ PCIE_PHY_Reset(portnum);
+ */
+ mdelay(500);
+ mdelay(500);
+
+ //----------------------------------------
+ if(mdio_reset)
+ {
+ //fix 8198 test chip pcie tx problem.
+ #ifdef CONFIG_RTL8198_REVISION_B
+ if (REG32(BSP_REVR) >= BSP_RTL8198_REVISION_B)
+ {
+ HostPCIe_SetPhyMdioWrite(portnum, 0, 0xD087); //bokai tell, and fix
+
+ HostPCIe_SetPhyMdioWrite(portnum, 1, 0x0003);
+ HostPCIe_SetPhyMdioWrite(portnum, 2, 0x4d18);
+ #if CONFIG_PHY_EAT_40MHZ
+ HostPCIe_SetPhyMdioWrite(portnum, 5, 0x0BCB); //40M
+ #endif
+
+ #if CONFIG_PHY_EAT_40MHZ
+ printk("98 - 40MHz Clock Source\n");
+ HostPCIe_SetPhyMdioWrite(portnum, 6, 0xF148); //40M
+ #else
+ printk("98 - 25MHz Clock Source\n");
+ HostPCIe_SetPhyMdioWrite(portnum, 6, 0xf848); //25M
+ #endif
+
+ HostPCIe_SetPhyMdioWrite(portnum, 7, 0x31ff);
+ HostPCIe_SetPhyMdioWrite(portnum, 8, 0x18d7); //peisi tune
+
+ //saving more power, 8196c pe-si tune
+ HostPCIe_SetPhyMdioWrite(portnum, 0x09, 0x539c);
+ HostPCIe_SetPhyMdioWrite(portnum, 0x0a, 0x20eb);
+ HostPCIe_SetPhyMdioWrite(portnum, 0x0d, 0x1766);
+
+ HostPCIe_SetPhyMdioWrite(portnum, 0x0b, 0x0511); //for sloving low performance
+
+
+ HostPCIe_SetPhyMdioWrite(portnum, 0xf, 0x0a00);
+ HostPCIe_SetPhyMdioWrite(portnum, 0x19, 0xFCE0);
+
+ HostPCIe_SetPhyMdioWrite(portnum, 0x1a, 0x7e40); //formal chip, reg 0x1a.4=0
+ HostPCIe_SetPhyMdioWrite(portnum, 0x1b, 0xFC01); //formal chip reg 0x1b.0=1
+
+ HostPCIe_SetPhyMdioWrite(portnum, 0x1e, 0xC280);
+ }
+ else
+ #endif
+ {
+ HostPCIe_SetPhyMdioWrite(portnum, 0, 0xD087);
+
+ HostPCIe_SetPhyMdioWrite(portnum, 1, 0x0003);
+ HostPCIe_SetPhyMdioWrite(portnum, 6, 0xf448); //new
+ HostPCIe_SetPhyMdioWrite(portnum, 6, 0x408); //avoid noise infuse //15-12=0, 7-5=0, 0448
+
+ HostPCIe_SetPhyMdioWrite(portnum, 7, 0x31ff);
+ HostPCIe_SetPhyMdioWrite(portnum, 8, 0x18d5); //new
+ HostPCIe_SetPhyMdioWrite(portnum, 9, 0x531c);
+
+ HostPCIe_SetPhyMdioWrite(portnum, 0xd, 0x1766);
+ HostPCIe_SetPhyMdioWrite(portnum, 0xf, 0x0010);//ori
+
+ HostPCIe_SetPhyMdioWrite(portnum, 0x19, 0xFCE0);
+ HostPCIe_SetPhyMdioWrite(portnum, 0x1e, 0xC280);
+ }
+ }
+
+ //---------------------------------------
+ PCIE_Device_PERST(portnum);
+ PCIE_PHY_Reset(portnum);
+ mdelay(500);
+ mdelay(500);
+ status=PCIE_Check_Link(portnum);
+ if(status==FAIL)
+ return FAIL;
+
+
+SET_BAR:
+ if (portnum==0)
+ {
+ // Enable PCIE host
+ if (pcie_reset_done[portnum] == 0) {
+#if defined(__LINUX_2_6__) && defined(USE_RLX_BSP)
+ WRITE_MEM32(BSP_PCIE0_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(BSP_PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#else
+ WRITE_MEM32(PCIE0_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#endif
+ pcie_reset_done[portnum] = 1;
+ }
+#ifdef CONFIG_RTL_92D_DMDP
+ else {
+ Sw_PCIE_Func(1);
+ //choose the PCIE port number
+ WRITE_MEM32(PCIE0_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+ Sw_PCIE_Func(0);
+ }
+#endif
+ }
+ else if (portnum==1)
+ {
+ // Enable PCIE host
+#if defined(__LINUX_2_6__) && defined(USE_RLX_BSP)
+ if (pcie_reset_done[portnum] == 0) {
+ WRITE_MEM32(BSP_PCIE1_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(BSP_PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+ pcie_reset_done[portnum] = 1;
+ }
+ #ifdef CONFIG_RTL_92D_DMDP
+ else {
+ Sw_PCIE_Func(1);
+ //choose the PCIE port number
+ WRITE_MEM32(BSP_PCIE1_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(BSP_PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+ Sw_PCIE_Func(0);
+ }
+ #endif
+ #else /* defined(__LINUX_2_6__) && defined(USE_RLX_BSP) */
+ WRITE_MEM32(PCIE1_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+ #endif /* defined(__LINUX_2_6__) && defined(USE_RLX_BSP) */
+ }
+ else
+ return FAIL;
+
+ mdelay(500);
+ return SUCCESS;
+
+}
+#elif defined(CONFIG_RTL8196C) || defined(CONFIG_RTL_8196C)
+
+#ifdef CONFIG_RTL8672
+int PCIE_reset_procedure(int PCIE_Port0and1_8196B_208pin, int Use_External_PCIE_CLK, int mdio_reset,unsigned long conf_addr)
+{
+ #define SYS_PCIE_PHY0 0xb8003400
+ #define Module_Enable 0xb800330c
+ //PCIE Register
+ #define CLK_MANAGE 0xb800350c
+ #define PCIE_PHY0_REG 0xb8b01000
+ //#define PCIE_PHY1_REG 0xb8b21000
+ #define PCIE_PHY0 0xb8b01008
+ // #define PCIE_PHY1 0xb8b21008
+ #define PCIE_gpio_RST 5
+
+ //1. PCIE phy mdio reset
+ REG32(SYS_PCIE_PHY0) = 0x1d400000;
+ REG32(SYS_PCIE_PHY0) = 0x1d500000;
+
+ //2. PCIE MAC reset
+ REG32(Module_Enable) &= ~(1<<9);
+ REG32(Module_Enable) |= (1<<9);
+
+ //3.Active LX & PCIE Clock
+ gpioSet(PCIE_gpio_RST);
+ delay_ms(100);
+
+ //4. GPIO output
+ REG32(0xb8003508) |= (1<<5);
+ delay_ms(100);
+
+ if(mdio_reset)
+ {
+ //printk("Do MDIO_RESET\n");
+ // 5.MDIO Reset
+ REG32(SYS_PCIE_PHY0) = 0x1d500000;
+ }
+ //6. PCIE PHY Reset
+ REG32(PCIE_PHY0) = 0x1; //bit7 PHY reset=0 bit0 Enable LTSSM=1
+ REG32(PCIE_PHY0) = 0x81; //bit7 PHY reset=1 bit0 Enable LTSSM=1
+ delay_ms(100);
+
+ delay_ms(100);
+
+ //----------------------------------------
+ if(mdio_reset)
+ {
+ int port=0;
+ HostPCIe_SetPhyMdioWrite(port, 0, 0x5027);
+ HostPCIe_SetPhyMdioWrite(port, 2, 0x6d18);
+ //HostPCIe_SetPhyMdioWrite(port, 6, 0x8028);
+ if( (IS_RLE0315 ||IS_6166) && (REG32(MISC_PINSR)&(0x200000))){
+ HostPCIe_SetPhyMdioWrite(port, 6, 0x20c8); //35.328 clock source
+ HostPCIe_SetPhyMdioWrite(port, 5, 0x0bcb);
+ printk("Clock source is 35.328MHz\n");
+ }else if( (IS_RLE0315 ||IS_6166) && ~(REG32(MISC_PINSR)&(0x200000))){
+ HostPCIe_SetPhyMdioWrite(port, 6, 0xf848); //25M clock source
+ HostPCIe_SetPhyMdioWrite(port, 5, 0x08ab);
+ printk("Clock source is 25MHz\n");
+ }
+ HostPCIe_SetPhyMdioWrite(port, 7, 0x30ff);
+ //HostPCIe_SetPhyMdioWrite(port, 8, 0x18dd);
+ HostPCIe_SetPhyMdioWrite(port, 8, 0x18d7);
+ HostPCIe_SetPhyMdioWrite(port, 0xa, 0xe9);
+ HostPCIe_SetPhyMdioWrite(port, 0xb, 0x0511);
+ //HostPCIe_SetPhyMdioWrite(port, 0xd, 0x15b6);
+ HostPCIe_SetPhyMdioWrite(port, 0xd, 0x15a6);
+ HostPCIe_SetPhyMdioWrite(port, 0xf, 0x0f0f);
+ //HostPCIe_SetPhyMdioWrite(port, 0x9, 0xe950); //czyao adds to leave L0 mode
+ }
+
+ //---------------------------------------
+ //delay_ms(10000);
+
+ // 7. PCIE Device Reset
+ gpioClear(PCIE_gpio_RST);
+ delay_ms(100);
+
+ gpioSet(PCIE_gpio_RST);
+
+ //4. PCIE PHY Reset
+ REG32(PCIE_PHY0) = 0x1; //bit7 PHY reset=0 bit0 Enable LTSSM=1
+ REG32(PCIE_PHY0) = 0x81; //bit7 PHY reset=1 bit0 Enable LTSSM=1
+ delay_ms(100);
+
+ //8. Set BAR
+ REG32(0xb8b10010) = 0x18c00001;
+ REG32(0xb8b10018) = 0x19000004;
+ REG32(0xb8b10004) = 0x00180007;
+ REG32(0xb8b00004) = 0x00100007;
+
+ //8. Fine tune parameter, and depends on RD center's suggestion
+ //REG32(0xb8003204) = 0x4cc3106d; //This is added in bootcode
+#if 1 //wait for LinkUP
+ int i=100;
+ while(--i)
+ {
+ if( (REG32(0xb8b00728)&0x1f)==0x11)
+ break;
+ delay_ms(100);
+ }
+ if(i==0)
+ {
+ printk("i=%x Cannot LinkUP \n",i);
+ return FAIL;
+ }
+#endif
+ // Enable PCIE host
+#if defined(__LINUX_2_6__) && defined(USE_RLX_BSP)
+ WRITE_MEM32(BSP_PCIE0_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(BSP_PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#else
+ WRITE_MEM32(PCIE0_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#endif
+ return SUCCESS;
+}
+#else /* defined(CONFIG_RTL8672) */
+static int pcie_reset_done = 0;
+int PCIE_reset_procedure(int PCIE_Port0and1_8196B_208pin, int Use_External_PCIE_CLK, int mdio_reset,unsigned long conf_addr)
+{
+
+ int i=100;
+#define SYS_PCIE_PHY0 (0xb8000000 +0x50)
+ //PCIE Register
+#define CLK_MANAGE 0xb8000010
+#define PCIE_PHY0_REG 0xb8b01000
+ //#define PCIE_PHY1_REG 0xb8b21000
+#define PCIE_PHY0 0xb8b01008
+ // #define PCIE_PHY1 0xb8b21008
+ int port =0;
+
+ if (pcie_reset_done)
+ goto SET_BAR;
+
+ //2.Active LX & PCIE Clock
+ REG32(CLK_MANAGE) |= (1<<11); //enable active_pcie0
+ delay_ms(100);
+
+#if 1
+ if(mdio_reset)
+ {
+ //printk("Do MDIO_RESET\n");
+ // 3.MDIO Reset
+ REG32(SYS_PCIE_PHY0) = (1<<3) |(0<<1) | (0<<0); //mdio reset=0,
+ REG32(SYS_PCIE_PHY0) = (1<<3) |(0<<1) | (1<<0); //mdio reset=1,
+ REG32(SYS_PCIE_PHY0) = (1<<3) |(1<<1) | (1<<0); //bit1 load_done=1
+ }
+ //4. PCIE PHY Reset
+ REG32(PCIE_PHY0) = 0x1; //bit7 PHY reset=0 bit0 Enable LTSSM=1
+ REG32(PCIE_PHY0) = 0x81; //bit7 PHY reset=1 bit0 Enable LTSSM=1
+ delay_ms(100);
+#endif
+
+ delay_ms(100);
+
+ //----------------------------------------
+ if(mdio_reset)
+ {
+ if (REG32(REVR) == RTL8196C_REVISION_A)
+ {
+ HostPCIe_SetPhyMdioWrite(port, 0, 0x5027);
+ HostPCIe_SetPhyMdioWrite(port, 2, 0x6d18);
+ HostPCIe_SetPhyMdioWrite(port, 6, 0x8828);
+ HostPCIe_SetPhyMdioWrite(port, 7, 0x30ff);
+ HostPCIe_SetPhyMdioWrite(port, 8, 0x18d7);
+ HostPCIe_SetPhyMdioWrite(port, 0xa, 0xe9);
+ HostPCIe_SetPhyMdioWrite(port, 0xb, 0x0511);
+ HostPCIe_SetPhyMdioWrite(port, 0xd, 0x15b6);
+ HostPCIe_SetPhyMdioWrite(port, 0xf, 0x0f0f);
+#if 1 // PHY_EAT_40MHZ
+ HostPCIe_SetPhyMdioWrite(port, 5, 0xbcb); //[9:3]=1111001 (binary) 121 (10)
+ HostPCIe_SetPhyMdioWrite(port, 6, 0x8128); //[11]=0 [9:8]=01
+#endif
+ /*
+ emdiow 0 5027
+ emdiow 2 6d18
+ emdiow 6 8828
+ emdiow 7 30ff
+ emdiow 8 18dd
+ emdiow a e9
+ emdiow b 0511
+ emdiow d 15b6
+ emdiow f 0f0f
+ */
+ }
+ else
+ {
+ HostPCIe_SetPhyMdioWrite(port, 0, 0xD087);
+ HostPCIe_SetPhyMdioWrite(port, 1, 0x0003);
+ HostPCIe_SetPhyMdioWrite(port, 2, 0x4d18);
+
+#ifdef CONFIG_PHY_EAT_40MHZ
+
+ printk("96C - 40MHz Clock Source\n");
+#ifdef HIGH_POWER_EXT_PA
+ HostPCIe_SetPhyMdioWrite(port, 5, 0x0BF3); //40M
+#else
+ HostPCIe_SetPhyMdioWrite(port, 5, 0x0BCB); //40M
+#endif
+ HostPCIe_SetPhyMdioWrite(port, 6, 0xF148); //40M
+
+#else
+ printk("96C - 25MHz Clock Source\n");
+ HostPCIe_SetPhyMdioWrite(port, 6, 0xf848); //25M
+#endif
+
+ HostPCIe_SetPhyMdioWrite(port, 7, 0x31ff);
+ HostPCIe_SetPhyMdioWrite(port, 8, 0x18d7);
+ HostPCIe_SetPhyMdioWrite(port, 9, 0x539c);
+ HostPCIe_SetPhyMdioWrite(port, 0xa, 0x20eb);
+ HostPCIe_SetPhyMdioWrite(port, 0xb, 0x0511);
+ HostPCIe_SetPhyMdioWrite(port, 0xd, 0x1764);
+ HostPCIe_SetPhyMdioWrite(port, 0xf, 0x0a00);
+
+#ifdef HAVING_FIB
+ HostPCIe_SetPhyMdioWrite(port,8, 0x18dd);
+ HostPCIe_SetPhyMdioWrite(port, 0xd, 0x1776);
+#endif
+
+ HostPCIe_SetPhyMdioWrite(port, 0x19, 0xFCE0);
+ HostPCIe_SetPhyMdioWrite(port, 0x1e, 0xC280);
+ }
+ }
+
+ //---------------------------------------
+ // 6. PCIE Device Reset
+#ifndef CONFIG_RTL_8196C_iNIC
+ REG32(CLK_MANAGE) &= ~(1<<12); //perst=0 off.
+ delay_ms(300);
+#endif
+ //mark_inic , from jason patch
+#ifdef CONFIG_RTL_8196C_iNIC
+ iNIC_PCIE_Device_PERST();
+#endif
+#if defined(CONFIG_RTL_8196CS) || defined(CONFIG_RTL_8197B)
+ GPIO6_PCIE_Device_PERST();
+#endif
+ //4. PCIE PHY Reset
+ REG32(PCIE_PHY0) = 0x1; //bit7 PHY reset=0 bit0 Enable LTSSM=1
+ REG32(PCIE_PHY0) = 0x81; //bit7 PHY reset=1 bit0 Enable LTSSM=1
+ delay_ms(300);
+#ifndef CONFIG_RTL_8196C_iNIC
+ REG32(CLK_MANAGE) |= (1<<12); //PERST=1
+#endif
+ //4. PCIE PHY Reset
+
+ //prom_printf("\nCLK_MANAGE(0x%x)=0x%x\n\n",CLK_MANAGE,READ_MEM32(CLK_MANAGE));
+ delay_ms(100);
+#if 1 //wait for LinkUP
+ while(--i)
+ {
+ if( (REG32(0xb8b00728)&0x1f)==0x11)
+ break;
+ delay_ms(100);
+ }
+ if(i==0)
+ {
+ printk("i=%x Cannot LinkUP \n",i);
+ return FAIL;
+ }
+#endif
+
+SET_BAR:
+ if (port==0)
+ {
+ // Enable PCIE host
+ if (pcie_reset_done == 0) {
+#if defined(__LINUX_2_6__) && defined(USE_RLX_BSP)
+ WRITE_MEM32(BSP_PCIE0_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(BSP_PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#else
+ WRITE_MEM32(PCIE0_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#endif
+ pcie_reset_done = 1;
+ }
+#ifdef CONFIG_RTL_92D_DMDP
+ else {
+ Sw_PCIE_Func(1);
+ //choose the PCIE port number
+#if defined(__LINUX_2_6__) && defined(USE_RLX_BSP)
+ WRITE_MEM32(BSP_PCIE0_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(BSP_PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#else
+ WRITE_MEM32(PCIE0_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(PCIE0_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#endif
+ Sw_PCIE_Func(0);
+ }
+#endif
+ }
+ else if (port==1)
+ {
+ // Enable PCIE host
+ if (pcie_reset_done == 0) {
+#if defined(__LINUX_2_6__) && defined(USE_RLX_BSP)
+ WRITE_MEM32(BSP_PCIE1_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(BSP_PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#else
+ WRITE_MEM32(PCIE1_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#endif
+ pcie_reset_done = 1;
+ }
+#ifdef CONFIG_RTL_92D_DMDP
+ else {
+ Sw_PCIE_Func(1);
+#if defined(__LINUX_2_6__) && defined(USE_RLX_BSP)
+ //choose the PCIE port number
+ WRITE_MEM32(BSP_PCIE1_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(BSP_PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#else
+ WRITE_MEM32(PCIE1_H_CFG + 0x04, 0x00100007);
+ WRITE_MEM8(PCIE1_H_CFG + 0x78, (READ_MEM8(conf_addr + 0x78) & (~0xE0)) | MAX_PAYLOAD_SIZE_128B); // Set MAX_PAYLOAD_SIZE to 128B
+#endif
+ Sw_PCIE_Func(0);
+ }
+#endif
+ }
+ else
+ return FAIL;
+ return SUCCESS;
+}
+
+#endif /* defined(CONFIG_RTL8672) */
+
+void HostPCIe_Close(void)
+{
+ REG32(0xb8b10044) &= (~(3));
+ REG32(0xb8b10044) |= (3);
+ HostPCIe_SetPhyMdioWrite(0, 0xf, 0x0708);
+ //.DeActive LX & PCIE Clock
+ REG32(CLK_MANAGE) &=(0xFFFFFFFF- (1<<11)); //enable active_pcie0
+ pcie_reset_done=0;
+}
+#endif /* #elif (defined(CONFIG_RTL8196C) || defined(CONFIG_RTL_8196C)) */
+
+#endif /* !defined(CONFIG_NET_PCI) */
+#endif
+static void rtl8192cd_bcnProc(struct rtl8192cd_priv *priv, unsigned int bcnInt,
+ unsigned int bcnDmaOk, unsigned int bcnOk, unsigned int bcnErr, unsigned int status)
+{
+#ifdef MBSSID
+ int i;
+#endif
+
+ /* ================================================================
+ Process Beacon interrupt
+ ================================================================ */
+ //
+ // Update beacon content
+ //
+ if (bcnInt) {
+ unsigned char val8;
+ if (status & HIMR_BCNDMA0) {
+#ifdef UNIVERSAL_REPEATER
+ if ((OPMODE & WIFI_STATION_STATE) && GET_VXD_PRIV(priv) &&
+ (GET_VXD_PRIV(priv)->drv_state & DRV_STATE_VXD_AP_STARTED)) {
+ if (GET_VXD_PRIV(priv)->timoffset) {
+ update_beacon(GET_VXD_PRIV(priv));
+ }
+ } else
+#endif
+ {
+#if 0 //TESTCHIP_SUPPORT
+#ifdef SMART_CONCURRENT_92D // -- fwdebug
+ if (priv->pshare->wlandev_idx == 1) {
+ DMDP_RTL_W8(0, 0x663, DMDP_RTL_R8(0, 0x663)|BIT(2)); // write MAC'0 0x663 to notify DRVERLY_INT
+ DMDP_RTL_W8(0, 0x1cf, DMDP_RTL_R8(0, 0x1cf)|BIT(4)); // write MAC'0 0x1cf to notify firmware INT
+ if (priv->smcc_state==0) {
+ unsigned int now, timeout;
+ now = RTL_R32(TSFTR);
+ timeout = now + (priv->pmib->dot11RFEntry.smcc_t * 1000);
+ //printk("wlan%d start timer now=%d timeout=%d timeout1=%d\n", priv->pshare->wlandev_idx, now, timeout, timeout1);
+ setup_timer2(priv, timeout);
+#ifdef PHASE2_TEST
+ timeout = now + (priv->pmib->dot11RFEntry.smcc_p * 1000);
+ setup_timer1(priv, timeout);
+#endif
+ }
+ }
+#endif
+#endif
+#if 0//def SMART_CONCURRENT_92D
+ priv->pshare->bcnCount++;
+ if ((priv->pshare->bcnCount % 3)==0)
+ smcc_signin_linkstate(priv, 1, 5, priv->smcc_state);
+ else if ((priv->pshare->bcnCount % 3)==1)
+ smcc_signin_linkstate(priv, 1, priv->pmib->dot11RFEntry.smcc_t, priv->smcc_state);
+#endif
+
+ if (priv->timoffset) {
+ update_beacon(priv);
+ }
+ }
+ }
+#ifdef MBSSID
+ else {
+ if (GET_ROOT(priv)->pmib->miscEntry.vap_enable) {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++) {
+ if ((priv->pvap_priv[i]->vap_init_seq > 0) && IS_DRV_OPEN(priv->pvap_priv[i])
+ && (status & (HIMR_BCNDMA1 << (priv->pvap_priv[i]->vap_init_seq-1))))
+ {
+ if (priv->pvap_priv[i]->timoffset) {
+ update_beacon(priv->pvap_priv[i]);
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ //
+ // Polling highQ as there is multicast waiting for tx...
+ //
+#ifdef UNIVERSAL_REPEATER
+ struct rtl8192cd_priv *priv_root=NULL;
+ if ((OPMODE & WIFI_STATION_STATE) && GET_VXD_PRIV(priv) &&
+ (GET_VXD_PRIV(priv)->drv_state & DRV_STATE_VXD_AP_STARTED)) {
+ priv_root = priv;
+ priv = GET_VXD_PRIV(priv);
+ }
+#endif
+
+ if ((OPMODE & WIFI_AP_STATE)) {
+
+ if (status & HIMR_BCNDMA0) {
+ val8 = *((unsigned char *)priv->beaconbuf + priv->timoffset + 4);
+ if (val8 & 0x01) {
+ if(RTL_R8(BCN_CTRL) & DIS_ATIM)
+ RTL_W8(BCN_CTRL, (RTL_R8(BCN_CTRL) & (~DIS_ATIM)));
+ process_mcast_dzqueue(priv);
+ priv->pkt_in_dtimQ = 0;
+ } else {
+ if(!(RTL_R8(BCN_CTRL) & DIS_ATIM))
+ RTL_W8(BCN_CTRL, (RTL_R8(BCN_CTRL) | DIS_ATIM));
+ }
+#ifdef MBSSID
+ priv->pshare->bcnDOk_priv = priv;
+#endif
+ }
+#ifdef MBSSID
+ else if (GET_ROOT(priv)->pmib->miscEntry.vap_enable) {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++) {
+ if ((priv->pvap_priv[i]->vap_init_seq > 0) && IS_DRV_OPEN(priv->pvap_priv[i])
+ && (status & (HIMR_BCNDMA1 << (priv->pvap_priv[i]->vap_init_seq-1)))) {
+ val8 = *((unsigned char *)priv->pvap_priv[i]->beaconbuf + priv->pvap_priv[i]->timoffset + 4);
+ if (val8 & 0x01) {
+ if(RTL_R8(BCN_CTRL) & DIS_ATIM)
+ RTL_W8(BCN_CTRL, (RTL_R8(BCN_CTRL) & (~DIS_ATIM)));
+ process_mcast_dzqueue(priv->pvap_priv[i]);
+ priv->pvap_priv[i]->pkt_in_dtimQ = 0;
+ } else {
+ if(!(RTL_R8(BCN_CTRL) & DIS_ATIM))
+ RTL_W8(BCN_CTRL, (RTL_R8(BCN_CTRL) | DIS_ATIM));
+ }
+
+ priv->pshare->bcnDOk_priv = priv->pvap_priv[i];
+ }
+ }
+ }
+#endif
+
+ }
+
+ if (priv->pshare->pkt_in_hiQ) {
+ int pre_head = get_txhead(priv->pshare->phw, MCAST_QNUM);
+ do {
+ txdesc_rollback(&pre_head);
+ } while ((get_txdesc_info(priv->pshare->pdesc_info, MCAST_QNUM) + pre_head)->type != _PRE_ALLOCLLCHDR_);
+ if (get_desc((get_txdesc(priv->pshare->phw, MCAST_QNUM) + pre_head)->Dword0) & TX_OWN) {
+ unsigned short *phdr = (unsigned short *)((get_txdesc_info(priv->pshare->pdesc_info, MCAST_QNUM) + pre_head)->pframe);
+#ifdef __MIPSEB__
+ phdr = (unsigned short *)KSEG1ADDR(phdr);
+#endif
+ ClearMData(phdr);
+ }
+ tx_poll(priv, MCAST_QNUM);
+ priv->pshare->pkt_in_hiQ = 0;
+ }
+
+#ifdef UNIVERSAL_REPEATER
+ if (priv_root != NULL)
+ priv = priv_root;
+#endif
+ }
+
+ /* ================================================================
+ Process Beacon OK/ERROR interrupt
+ ================================================================ */
+ if (bcnDmaOk || bcnOk || bcnErr)
+ {
+
+#ifdef UNIVERSAL_REPEATER
+ struct rtl8192cd_priv *priv_root=NULL;
+ if ((OPMODE & WIFI_STATION_STATE) && GET_VXD_PRIV(priv) &&
+ (GET_VXD_PRIV(priv)->drv_state & DRV_STATE_VXD_AP_STARTED)) {
+ priv_root = priv;
+ priv = GET_VXD_PRIV(priv);
+ }
+#endif
+
+ //
+ // Polling highQ as there is multicast waiting for tx...
+ //
+ if ((OPMODE & WIFI_AP_STATE) && bcnDmaOk) {
+#ifdef PCIE_POWER_SAVING
+ if ((priv->offload_ctrl & 1) && (priv->offload_ctrl >> 7) && priv->pshare->rf_ft_var.power_save) {
+ priv->offload_ctrl &= (~1);
+ update_beacon(priv);
+ RTL_W16(0x100 , RTL_R16(0x100) & ~BIT(8)); // disable sw beacon
+ return;
+ }
+#endif
+
+ }
+
+ //
+ // Statistics and LED counting
+ //
+ if (bcnOk) {
+ // for SW LED
+ if (((LED_TYPE >= LEDTYPE_SW_LINK_TXRX) && (LED_TYPE <= LEDTYPE_SW_LINKTXRX)) ||
+ (LED_TYPE == LEDTYPE_SW_LED2_GPIO8_LINKTXRX)||(LED_TYPE == LEDTYPE_SW_LED2_GPIO10_LINKTXRX)||
+ (LED_TYPE == LEDTYPE_SW_LED1_GPIO10_LINKTXRX))
+ priv->pshare->LED_tx_cnt++;
+#ifdef MBSSID
+ if (priv->pshare->bcnDOk_priv)
+ priv->pshare->bcnDOk_priv->ext_stats.beacon_ok++;
+#else
+ priv->ext_stats.beacon_ok++;
+#endif
+ SNMP_MIB_INC(dot11TransmittedFragmentCount, 1);
+ } else if (bcnErr) {
+#ifdef MBSSID
+ if (priv->pshare->bcnDOk_priv)
+ priv->pshare->bcnDOk_priv->ext_stats.beacon_er++;
+#else
+ priv->ext_stats.beacon_er++;
+#endif
+ }
+
+#ifdef UNIVERSAL_REPEATER
+ if (priv_root != NULL)
+ priv = priv_root;
+#endif
+ }
+
+#ifdef CLIENT_MODE
+ //
+ // Ad-hoc beacon status
+ //
+ if (OPMODE & WIFI_ADHOC_STATE) {
+ if (bcnOk)
+ priv->ibss_tx_beacon = TRUE;
+ if (bcnErr)
+ priv->ibss_tx_beacon = FALSE;
+ }
+#endif
+}
+
+
+void check_dma_error(struct rtl8192cd_priv *priv, unsigned int status, unsigned int status_ext)
+{
+ unsigned char reg_rxdma;
+ unsigned int reg_txdma;
+ int clear_isr=0;
+
+ if ((status & HIMR_RXFOVW) | (status_ext & HIMRE_RXERR)) {
+ reg_rxdma = RTL_R8(RXDMA_STATUS);
+ if (reg_rxdma) {
+ RTL_W8(RXDMA_STATUS, reg_rxdma);
+ //panic_printk("RXDMA_STATUS %02x\n", reg_rxdma);
+ clear_isr = 1;
+ }
+ }
+
+ if ((status & HIMR_TXFOVW) | (status_ext & HIMRE_TXERR)) {
+ reg_txdma = RTL_R32(TXDMA_STATUS);
+ if (reg_txdma) {
+ RTL_W32(TXDMA_STATUS, reg_txdma);
+ //panic_printk("TXDMA_STATUS %08x\n", reg_txdma);
+ clear_isr = 1;
+ }
+ }
+
+ if (clear_isr) {
+ RTL_W32(HISR, status);
+ RTL_W32(HISRE, status_ext);
+ }
+}
+
+#define RTL_WLAN_INT_RETRY_MAX (32)
+__MIPS16
+__IRAM_IN_865X
+__inline__ static int __rtl8192cd_interrupt(void *dev_instance)
+{
+ struct net_device *dev;
+ struct rtl8192cd_priv *priv;
+ struct rtl8192cd_hw *phw;
+
+ unsigned int status, status_ext, retry_cnt;
+ unsigned int caseBcnInt, caseBcnDmaOK, caseBcnStatusOK, caseBcnStatusER;
+ unsigned int caseRxStatus, caseRxRDU;
+ #if 0 //TESTCHIP_SUPPORT || defined(SMART_CONCURRENT_92D) // --fwdebug
+ unsigned int caseTimer1;
+ #endif
+ #ifdef SUPPORT_TX_AMSDU
+ unsigned int caseTimer2;
+ #endif
+#if defined (SUPPORT_TX_AMSDU) || defined (SMART_CONCURRENT_92D)
+ unsigned long current_value, timeout;
+#endif
+
+ dev = (struct net_device *)dev_instance;
+#ifdef NETDEV_NO_PRIV
+ priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv;
+#else
+ priv = (struct rtl8192cd_priv *)dev->priv;
+#endif
+
+#ifdef CONFIG_RTL_92D_DMDP
+ if (GET_CHIP_VER(priv)==VERSION_8192D) {
+ #if (RTL_USED_PCIE_SLOT==1)
+ if (!((REG32(0xb8b21004)& 0x01) && (priv->pshare->wlandev_idx ==0)) &&
+ !((REG32(0xb8b21004)& 0x02) && (priv->pshare->wlandev_idx ==1))) {
+ //printk("INT=[%02x] WLAN(%d)\n",(REG32(0xb8b21004)& 0x0f),(priv->pshare->wlandev_idx));
+ goto int_exit;
+ }
+ #else
+ if (!((REG32(0xb8b01004)& 0x01) && (priv->pshare->wlandev_idx ==0)) &&
+ !((REG32(0xb8b01004)& 0x02) && (priv->pshare->wlandev_idx ==1))) {
+ //printk("INT=[%02x] WLAN(%d)\n",(REG32(0xb8b21004)& 0x0f),(priv->pshare->wlandev_idx));
+ goto int_exit;
+ }
+ #endif
+ }
+#endif
+
+#ifdef PCIE_POWER_SAVING
+ if ((priv->pwr_state == L2) || (priv->pwr_state == L1)) {
+#ifdef CONFIG_RTL_92D_DMDP
+ REG32(0xb8003000) = REG32(0xb8003000)|BIT(22);
+#endif
+ goto int_exit;
+ }
+#endif
+
+ status = RTL_R32(HISR);
+ RTL_W32(HISR, status);
+ status_ext = RTL_R32(HISRE);
+ RTL_W32(HISRE, status_ext);
+ if (status == 0 && status_ext == 0) {
+ goto int_exit;
+ }
+
+ retry_cnt = 0;
+retry_process:
+
+ caseBcnInt = caseBcnDmaOK = caseBcnStatusOK = caseBcnStatusER = 0;
+ caseRxStatus = caseRxRDU = 0;
+ #if 0 //TESTCHIP_SUPPORT || defined(SMART_CONCURRENT_92D) // --fwdebug
+ caseTimer1 = 0;
+ #endif
+ #ifdef SUPPORT_TX_AMSDU
+ caseTimer2 = 0
+ #endif
+
+#ifdef TXREPORT
+ if(status_ext & BIT(9) ) {
+ C2H_isr(priv);
+ }
+#endif
+
+ check_dma_error(priv, status, status_ext);
+
+ if (status & (HIMR_BCNDMA0 | HIMR_BCNDMA1 | HIMR_BCNDMA2 | HIMR_BCNDMA3 | HIMR_BCNDMA4 | HIMR_BCNDMA5 | HIMR_BCNDMA6 | HIMR_BCNDMA7))
+ caseBcnInt = 1;
+
+ if (status & (HIMR_BCNDOK0 | HIMR_BCNDOK1 | HIMR_BCNDOK2 | HIMR_BCNDOK3 | HIMR_BCNDOK4 | HIMR_BCNDOK5 | HIMR_BCNDOK6 | HIMR_BCNDOK7))
+ caseBcnDmaOK = 1;
+
+ if (status & HIMR_TXBCNOK)
+ caseBcnStatusOK = 1;
+
+ if (status & HIMR_TXBCNERR)
+ caseBcnStatusER = 1;
+
+ if (status & (HIMR_ROK | HIMR_RDU))
+ caseRxStatus = 1;
+
+ if (status & HIMR_RDU) {
+ priv->ext_stats.rx_rdu++;
+ caseRxRDU = 1;
+ priv->pshare->skip_mic_chk = SKIP_MIC_NUM;
+ }
+
+ if (status & HIMR_RXFOVW) {
+ priv->ext_stats.rx_fifoO++;
+ priv->pshare->skip_mic_chk = SKIP_MIC_NUM;
+ }
+
+ #if 0 //TESTCHIP_SUPPORT || defined(SMART_CONCURRENT_92D) // --fwdebug
+ if (status & HIMR_TIMEOUT1)
+ caseTimer1 = 1;
+ #endif
+
+ #ifdef SUPPORT_TX_AMSDU
+ if (status & HIMR_TIMEOUT2)
+ caseTimer2 = 1;
+ #endif
+
+ if (caseBcnInt || caseBcnDmaOK || caseBcnStatusOK || caseBcnStatusER){
+ rtl8192cd_bcnProc(priv, caseBcnInt, caseBcnDmaOK, caseBcnStatusOK, caseBcnStatusER, status);
+ }
+
+ //
+ // Rx interrupt
+ //
+ if (caseRxStatus)
+ {
+ // stop RX first
+#ifdef __KERNEL__
+#if defined(RTL8190_ISR_RX) && defined(RTL8190_DIRECT_RX)
+#if defined(RX_TASKLET)
+ if (!priv->pshare->has_triggered_rx_tasklet) {
+ priv->pshare->has_triggered_rx_tasklet = 1;
+ //RTL_W32(HIMR, priv->pshare->InterruptMask & ~(HIMR_RXFOVW | HIMR_RDU | HIMR_ROK));
+ RTL_W32(HIMR, priv->pshare->InterruptMask & ~(HIMR_RXFOVW | HIMR_ROK));
+ tasklet_hi_schedule(&priv->pshare->rx_tasklet);
+ }
+#else
+ rtl8192cd_rx_isr(priv);
+#endif
+
+#else // !(defined RTL8190_ISR_RX && RTL8190_DIRECT_RX)
+ if (caseRxRDU) {
+ rtl8192cd_rx_isr(priv);
+ tasklet_hi_schedule(&priv->pshare->rx_tasklet);
+ }
+ else {
+ if (priv->pshare->rxInt_useTsklt)
+ tasklet_hi_schedule(&priv->pshare->rx_tasklet);
+ else
+ rtl8192cd_rx_dsr((unsigned long)priv);
+ }
+#endif
+
+#else // !__KERNEL__
+ rtl8192cd_rx_dsr((unsigned long)priv);
+#endif
+ }
+
+ //
+ // Tx interrupt
+ //
+ phw = GET_HW(priv);
+#ifdef MP_TEST
+#ifdef SMP_SYNC
+ if (OPMODE & WIFI_MP_STATE){
+ if (!priv->pshare->has_triggered_tx_tasklet) {
+ tasklet_schedule(&priv->pshare->tx_tasklet);
+ priv->pshare->has_triggered_tx_tasklet = 1;
+ }
+ }
+#else
+ if (OPMODE & WIFI_MP_STATE)
+ rtl8192cd_tx_dsr((unsigned long)priv);
+#endif
+ else
+#endif
+ if ((CIRC_CNT_RTK(phw->txhead0, phw->txtail0, NUM_TX_DESC) > 10) ||
+ (CIRC_CNT_RTK(phw->txhead1, phw->txtail1, NUM_TX_DESC) > 10) ||
+ (CIRC_CNT_RTK(phw->txhead2, phw->txtail2, NUM_TX_DESC) > 10) ||
+ (CIRC_CNT_RTK(phw->txhead3, phw->txtail3, NUM_TX_DESC) > 10) ||
+ (CIRC_CNT_RTK(phw->txhead4, phw->txtail4, NUM_TX_DESC) > 10) ||
+ (CIRC_CNT_RTK(phw->txhead5, phw->txtail5, NUM_TX_DESC) > 10)
+ ) {
+#ifdef __KERNEL__
+ if (!priv->pshare->has_triggered_tx_tasklet) {
+ tasklet_schedule(&priv->pshare->tx_tasklet);
+ priv->pshare->has_triggered_tx_tasklet = 1;
+ }
+#else
+#ifdef SMP_SYNC
+ if (!priv->pshare->has_triggered_tx_tasklet) {
+ tasklet_schedule(&priv->pshare->tx_tasklet);
+ priv->pshare->has_triggered_tx_tasklet = 1;
+ }
+#else
+ rtl8192cd_tx_dsr((unsigned long)priv);
+#endif
+#endif
+ }
+
+#if 0 //TESTCHIP_SUPPORT
+#ifdef SMART_CONCURRENT_92D // --fwdebug
+
+#ifdef PHASE2_TEST
+ if (caseTimer1 && priv->pshare->wlandev_idx == 1) {
+ cancel_timer1(priv);
+ current_value = RTL_R32(TSFTR) ;
+ timeout = RTL_R32(TIMER0);
+ if (TSF_LESS(current_value, timeout)){
+ setup_timer1(priv, timeout);
+ }else {
+ //printk("TIMER1 %d \n", current_value);
+ RTL_W8_Phy0(priv, 0x1cf, RTL_R8_Phy0(priv, 0x1cf)|BIT(2)); // write MAC'0 0x1cf to notify firmware h2c cmd
+ }
+ }
+#endif
+ if (caseTimer2 && priv->pshare->wlandev_idx == 1) {
+ cancel_timer2(priv);
+
+ current_value = RTL_R32(TSFTR) ;
+ timeout = RTL_R32(TIMER1);
+ if (TSF_LESS(current_value, timeout)){
+ setup_timer2(priv, timeout);
+ }else {
+ //printk("TIMER2 %d \n", current_value);
+ DMDP_RTL_W8(0, 0x1cf, DMDP_RTL_R8(0, 0x1cf)|BIT(3)); // write MAC'0 0x1cf to notify firmware h2c cmd
+ }
+ }
+#endif
+#endif
+
+#ifdef SUPPORT_TX_AMSDU
+ if (caseTimer2) {
+ RTL_W32(IMR, RTL_R32(IMR) & ~IMR_TIMEOUT2);
+
+ current_value = RTL_R32(TSFR) ;
+ timeout = RTL_R32(TIMER1);
+ if (TSF_LESS(current_value, timeout))
+ setup_timer2(priv, timeout);
+ else
+ amsdu_timeout(priv, current_value);
+ }
+#endif
+
+ status = RTL_R32(HISR);
+ status_ext = RTL_R32(HISRE);
+
+ if ((status!=0||status_ext!=0) && ((retry_cnt++)<RTL_WLAN_INT_RETRY_MAX)) {
+ #if defined(CONFIG_RTL865X_WTDOG) || defined(CONFIG_RTL_WTDOG)
+ REG32(BSP_WDTCNR) |= 1 << 23;
+ #endif
+ RTL_W32(HISR, status);
+ RTL_W32(HISRE, status_ext);
+
+ goto retry_process;
+ }
+
+int_exit:
+ return SUCCESS;
+}
+
+
+#ifdef __LINUX_2_6__
+__MIPS16
+__IRAM_IN_865X
+irqreturn_t rtl8192cd_interrupt(int irq, void *dev_instance)
+{
+ __rtl8192cd_interrupt(dev_instance);
+ return IRQ_HANDLED;
+}
+#else
+__MIPS16
+__IRAM_IN_865X
+void rtl8192cd_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+{
+ __rtl8192cd_interrupt(dev_instance);
+ return;
+}
+#endif
+
+
+static void rtl8192cd_set_rx_mode(struct net_device *dev)
+{
+
+}
+
+
+static struct net_device_stats *rtl8192cd_get_stats(struct net_device *dev)
+{
+#ifdef NETDEV_NO_PRIV
+ struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv;
+#else
+ struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv;
+#endif
+
+#ifdef SMP_SYNC
+ unsigned long flags;
+#endif
+
+ SMP_LOCK(flags);
+
+#ifdef WDS
+ int idx;
+ struct stat_info *pstat;
+
+ if (dev->base_addr == 0) {
+ idx = getWdsIdxByDev(priv, dev);
+ if (idx < 0) {
+ memset(&priv->wds_stats[NUM_WDS-1], 0, sizeof(struct net_device_stats));
+ SMP_UNLOCK(flags);
+ return &priv->wds_stats[NUM_WDS-1];
+ }
+
+ if (netif_running(dev) && netif_running(priv->dev)) {
+ pstat = get_stainfo(priv, priv->pmib->dot11WdsInfo.entry[idx].macAddr);
+ if (pstat == NULL) {
+ DEBUG_ERR("%s: get_stainfo() wds fail!\n", (char *)__FUNCTION__);
+ memset(&priv->wds_stats[idx], 0, sizeof(struct net_device_stats));
+ }
+ else {
+ priv->wds_stats[idx].tx_packets = pstat->tx_pkts;
+ priv->wds_stats[idx].tx_errors = pstat->tx_fail;
+ priv->wds_stats[idx].tx_bytes = pstat->tx_bytes;
+ priv->wds_stats[idx].rx_packets = pstat->rx_pkts;
+ priv->wds_stats[idx].rx_bytes = pstat->rx_bytes;
+ }
+ }
+ SMP_UNLOCK(flags);
+ return &priv->wds_stats[idx];
+ }
+#endif
+
+#ifdef CONFIG_RTK_MESH
+
+ if (dev->base_addr == 1) {
+ if(priv->mesh_dev != dev)
+ {
+ SMP_UNLOCK(flags);
+ return NULL;
+ }
+
+ SMP_UNLOCK(flags);
+ return &priv->mesh_stats;
+ }
+#endif // CONFIG_RTK_MESH
+
+ SMP_UNLOCK(flags);
+ return &(priv->net_stats);
+}
+
+static int rtl8192cd_init_sw(struct rtl8192cd_priv *priv)
+{
+ // All the index/counters should be reset to zero...
+ struct rtl8192cd_hw *phw=NULL;
+ unsigned long offset;
+ unsigned int i;
+ struct sk_buff *pskb;
+ unsigned char *page_ptr;
+ struct wlan_hdr_poll *pwlan_hdr_poll;
+ struct wlanllc_hdr_poll *pwlanllc_hdr_poll;
+ struct wlanbuf_poll *pwlanbuf_poll;
+ struct wlanicv_poll *pwlanicv_poll;
+ struct wlanmic_poll *pwlanmic_poll;
+ struct wlan_acl_poll *pwlan_acl_poll;
+#ifdef _MESH_ACL_ENABLE_
+ struct mesh_acl_poll *pmesh_acl_poll;
+#endif
+ unsigned long ring_virt_addr;
+ unsigned long ring_dma_addr;
+ unsigned int ring_buf_len;
+ unsigned char MIMO_TR_hw_support;
+ unsigned int NumTotalRFPath;
+#ifndef PRIV_STA_BUF
+ unsigned long alloc_dma_buf;
+#endif
+#if defined(CLIENT_MODE) && defined(CHECK_HANGUP)
+ unsigned char *pbackup=NULL;
+ unsigned long backup_len=0;
+#endif
+#ifdef _11s_TEST_MODE_
+ struct Galileo_poll *pgalileo_poll;
+#endif
+
+#ifdef DFS
+ /*
+ * For JAPAN : prevent switching to channels 52, 56, 60, and 64 in adhoc mode
+ */
+ if (((priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK) ||
+ (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK3)) &&
+ (OPMODE & WIFI_ADHOC_STATE)) {
+ if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) {
+ /* block channels 52~64 and place them in NOP_chnl */
+ if (!timer_pending(&priv->ch52_timer))
+ InsertChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 52);
+ if (!timer_pending(&priv->ch56_timer))
+ InsertChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 56);
+ if (!timer_pending(&priv->ch60_timer))
+ InsertChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 60);
+ if (!timer_pending(&priv->ch64_timer))
+ InsertChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 64);
+ }
+
+ /* if users select an illegal channel, the driver will switch to channel 36~48 */
+ if ((priv->pmib->dot11RFEntry.dot11channel >= 52) && (priv->pmib->dot11RFEntry.dot11channel <= 64)) {
+ PRINT_INFO("Channel %d is illegal in ad-hoc mode in Japan!\n", priv->pmib->dot11RFEntry.dot11channel);
+ priv->pmib->dot11RFEntry.dot11channel = DFS_SelectChannel(priv);
+ PRINT_INFO("Swiching to channel %d!\n", priv->pmib->dot11RFEntry.dot11channel);
+ }
+ }
+
+ /* if users select a blocked channel, the driver will switch to unblocked channel */
+ if (!priv->pmib->dot11DFSEntry.disable_DFS &&
+ ((timer_pending(&priv->ch52_timer) && (priv->pmib->dot11RFEntry.dot11channel == 52)) ||
+ (timer_pending(&priv->ch56_timer) && (priv->pmib->dot11RFEntry.dot11channel == 56)) ||
+ (timer_pending(&priv->ch60_timer) && (priv->pmib->dot11RFEntry.dot11channel == 60)) ||
+ (timer_pending(&priv->ch64_timer) && (priv->pmib->dot11RFEntry.dot11channel == 64)) ||
+ (timer_pending(&priv->ch100_timer) && (priv->pmib->dot11RFEntry.dot11channel == 100)) ||
+ (timer_pending(&priv->ch104_timer) && (priv->pmib->dot11RFEntry.dot11channel == 104)) ||
+ (timer_pending(&priv->ch108_timer) && (priv->pmib->dot11RFEntry.dot11channel == 108)) ||
+ (timer_pending(&priv->ch112_timer) && (priv->pmib->dot11RFEntry.dot11channel == 112)) ||
+ (timer_pending(&priv->ch116_timer) && (priv->pmib->dot11RFEntry.dot11channel == 116)) ||
+ (timer_pending(&priv->ch120_timer) && (priv->pmib->dot11RFEntry.dot11channel == 120)) ||
+ (timer_pending(&priv->ch124_timer) && (priv->pmib->dot11RFEntry.dot11channel == 124)) ||
+ (timer_pending(&priv->ch128_timer) && (priv->pmib->dot11RFEntry.dot11channel == 128)) ||
+ (timer_pending(&priv->ch132_timer) && (priv->pmib->dot11RFEntry.dot11channel == 132)) ||
+ (timer_pending(&priv->ch136_timer) && (priv->pmib->dot11RFEntry.dot11channel == 136)) ||
+ (timer_pending(&priv->ch140_timer) && (priv->pmib->dot11RFEntry.dot11channel == 140)))) {
+ PRINT_INFO("Channel %d is still in none occupancy period!\n", priv->pmib->dot11RFEntry.dot11channel);
+ priv->pmib->dot11RFEntry.dot11channel = DFS_SelectChannel(priv);
+ PRINT_INFO("Swiching to channel %d!\n", priv->pmib->dot11RFEntry.dot11channel);
+ }
+
+ /* disable all of the transmissions during channel availability check */
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+ priv->pmib->dot11DFSEntry.disable_tx = 0;
+ if (!priv->pmib->dot11DFSEntry.disable_DFS &&
+ (((priv->pmib->dot11RFEntry.dot11channel >= 52) &&
+ (priv->pmib->dot11RFEntry.dot11channel <= 64)) ||
+ ((priv->pmib->dot11RFEntry.dot11channel >= 100) &&
+ (priv->pmib->dot11RFEntry.dot11channel <= 140))) &&
+ (OPMODE & WIFI_AP_STATE))
+ priv->pmib->dot11DFSEntry.disable_tx = 1;
+ }
+#endif
+
+#ifdef ENABLE_RTL_SKB_STATS
+ rtl_atomic_set(&priv->rtl_tx_skb_cnt, 0);
+ rtl_atomic_set(&priv->rtl_rx_skb_cnt, 0);
+#endif
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+#ifdef __KERNEL__
+#ifdef DFS
+ /* will not initialize the tasklet if the driver is rebooting due to the detection of radar */
+ if (!priv->pmib->dot11DFSEntry.DFS_detected)
+#endif
+ {
+#ifdef CHECK_HANGUP
+ if (!priv->reset_hangup)
+#endif
+ {
+#ifdef PCIE_POWER_SAVING
+ tasklet_init(&priv->pshare->ps_tasklet, PCIe_power_save_tasklet, (unsigned long)priv);
+#endif
+#if !(defined(RTL8190_ISR_RX) && defined(RTL8190_DIRECT_RX))
+ tasklet_init(&priv->pshare->rx_tasklet, rtl8192cd_rx_dsr, (unsigned long)priv);
+#else
+#ifdef RX_TASKLET
+ tasklet_init(&priv->pshare->rx_tasklet, rtl8192cd_rx_tkl_isr, (unsigned long)priv);
+#endif
+#endif
+ tasklet_init(&priv->pshare->tx_tasklet, rtl8192cd_tx_dsr, (unsigned long)priv);
+ tasklet_init(&priv->pshare->oneSec_tasklet, rtl8192cd_expire_timer, (unsigned long)priv);
+ }
+ }
+#endif // __KERNEL__
+
+#ifdef DFS
+ if (priv->pmib->dot11DFSEntry.DFS_detected)
+ priv->pmib->dot11DFSEntry.DFS_detected = 0;
+#endif
+
+ phw = GET_HW(priv);
+
+ // save descriptor virtual address before reset, david
+ ring_virt_addr = phw->ring_virt_addr;
+ ring_dma_addr = phw->ring_dma_addr;
+ ring_buf_len = phw->ring_buf_len;
+#ifndef PRIV_STA_BUF
+ alloc_dma_buf = phw->alloc_dma_buf;
+#endif
+
+ // save RF related settings before reset
+ MIMO_TR_hw_support = phw->MIMO_TR_hw_support;
+ NumTotalRFPath = phw->NumTotalRFPath;
+
+ memset((void *)phw, 0, sizeof(struct rtl8192cd_hw));
+ phw->ring_virt_addr = ring_virt_addr;
+ phw->ring_buf_len = ring_buf_len;
+#ifndef PRIV_STA_BUF
+ phw->alloc_dma_buf = alloc_dma_buf;
+#endif
+
+#ifdef CONFIG_NET_PCI
+ if (IS_PCIBIOS_TYPE)
+ phw->ring_dma_addr = ring_dma_addr;
+#endif
+ phw->MIMO_TR_hw_support = MIMO_TR_hw_support;
+ phw->NumTotalRFPath = NumTotalRFPath;
+
+#if defined(DUALBAND_ONLY) && defined(CONFIG_RTL8190_PRIV_SKB)
+ if (priv->pmib->dot11RFEntry.macPhyMode == DUALMAC_DUALPHY)
+ split_pool(priv);
+ else
+ merge_pool(priv);
+#endif
+ }
+
+#if defined(CLIENT_MODE) && defined(CHECK_HANGUP)
+ if (priv->reset_hangup &&
+ (OPMODE & (WIFI_STATION_STATE | WIFI_ADHOC_STATE))) {
+ backup_len = ((unsigned long)&((struct rtl8192cd_priv *)0)->br_ip) -
+ ((unsigned long)&((struct rtl8192cd_priv *)0)->join_res)+4;
+ pbackup = kmalloc(backup_len, GFP_ATOMIC);
+ if (pbackup)
+ memcpy(pbackup, &priv->join_res, backup_len);
+ }
+#endif
+
+ offset = (unsigned long)(&((struct rtl8192cd_priv *)0)->net_stats);
+ // zero all data members below (including) stats
+ memset((void *)((unsigned long)priv + offset), 0, sizeof(struct rtl8192cd_priv)-offset);
+
+#ifdef CHECK_HANGUP
+ if (!priv->reset_hangup)
+#endif
+ {
+ priv->up_time = 0;
+ }
+
+#if defined(CLIENT_MODE) && defined(CHECK_HANGUP)
+ if (priv->reset_hangup && pbackup) {
+ memcpy(&priv->join_res, pbackup, backup_len);
+ kfree(pbackup);
+ }
+#endif
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+ // zero all data members below (including) LED_Timer of share_info
+ offset = (unsigned long)(&((struct priv_shared_info*)0)->LED_Timer);
+ memset((void *)((unsigned long)priv->pshare+ offset), 0, sizeof(struct priv_shared_info)-offset);
+
+#ifdef CONFIG_RTK_MESH
+ memset((void *)&priv->pshare->meshare, 0, sizeof(struct MESH_Share));
+ get_random_bytes((void *)&priv->pshare->meshare.seq, sizeof(priv->pshare->meshare.seq));
+#if (MESH_DBG_LV & MESH_DBG_COMPLEX)
+ init_timer(&priv->pshare->meshare.mesh_test_sme_timer);
+ priv->pshare->meshare.mesh_test_sme_timer.data = (unsigned long) priv;
+ priv->pshare->meshare.mesh_test_sme_timer.function = mesh_test_sme_timer;
+ mod_timer(&priv->pshare->meshare.mesh_test_sme_timer, jiffies + RTL_SECONDS_TO_JIFFIES(2));
+#endif // (MESH_DBG_LV & MESH_DBG_COMPLEX)
+
+#if (MESH_DBG_LV & MESH_DBG_TEST)
+ init_timer(&priv->pshare->meshare.mesh_test_sme_timer2);
+ priv->pshare->meshare.mesh_test_sme_timer2.data = (unsigned long) priv;
+ priv->pshare->meshare.mesh_test_sme_timer2.function = mesh_test_sme_timer2;
+ mod_timer(&priv->pshare->meshare.mesh_test_sme_timer2, jiffies + RTL_SECONDS_TO_JIFFIES(50));
+#endif // (MESH_DBG_LV & MESH_DBG_TEST)
+
+#endif // CONFIG_RTK_MESH
+
+ pwlan_hdr_poll = priv->pshare->pwlan_hdr_poll;
+ pwlanllc_hdr_poll = priv->pshare->pwlanllc_hdr_poll;
+ pwlanbuf_poll = priv->pshare->pwlanbuf_poll;
+ pwlanicv_poll = priv->pshare->pwlanicv_poll;
+ pwlanmic_poll = priv->pshare->pwlanmic_poll;
+
+#ifdef _11s_TEST_MODE_
+ pgalileo_poll = priv->pshare->galileo_poll;
+ pgalileo_poll->count = AODV_RREQ_TABLE_SIZE;
+#endif
+ pwlan_hdr_poll->count = PRE_ALLOCATED_HDR;
+ pwlanllc_hdr_poll->count = PRE_ALLOCATED_HDR;
+ pwlanbuf_poll->count = PRE_ALLOCATED_MMPDU;
+ pwlanicv_poll->count = PRE_ALLOCATED_HDR;
+ pwlanmic_poll->count = PRE_ALLOCATED_HDR;
+
+ // initialize all the hdr/buf node, and list to the poll_list
+ INIT_LIST_HEAD(&priv->pshare->wlan_hdrlist);
+ INIT_LIST_HEAD(&priv->pshare->wlanllc_hdrlist);
+ INIT_LIST_HEAD(&priv->pshare->wlanbuf_list);
+ INIT_LIST_HEAD(&priv->pshare->wlanicv_list);
+ INIT_LIST_HEAD(&priv->pshare->wlanmic_list);
+
+#ifdef _11s_TEST_MODE_ //Galileo
+
+ memset(priv->rvTestPacket, 0, 3000);
+
+ INIT_LIST_HEAD(&priv->pshare->galileo_list);
+ INIT_LIST_HEAD(&priv->mtb_list);
+
+ for(i=0; i< AODV_RREQ_TABLE_SIZE; i++)
+ {
+ INIT_LIST_HEAD(&(pgalileo_poll->node[i].list));
+ list_add_tail(&(pgalileo_poll->node[i].list), &priv->pshare->galileo_list);
+ init_timer(&pgalileo_poll->node[i].data.expire_timer);
+ pgalileo_poll->node[i].data.priv = priv;
+ pgalileo_poll->node[i].data.expire_timer.function = galileo_timer;
+ }
+#endif
+
+ for(i=0; i< PRE_ALLOCATED_HDR; i++)
+ {
+ INIT_LIST_HEAD(&(pwlan_hdr_poll->hdrnode[i].list));
+ list_add_tail(&(pwlan_hdr_poll->hdrnode[i].list), &priv->pshare->wlan_hdrlist);
+
+ INIT_LIST_HEAD(&(pwlanllc_hdr_poll->hdrnode[i].list));
+ list_add_tail( &(pwlanllc_hdr_poll->hdrnode[i].list), &priv->pshare->wlanllc_hdrlist);
+
+ INIT_LIST_HEAD(&(pwlanicv_poll->hdrnode[i].list));
+ list_add_tail( &(pwlanicv_poll->hdrnode[i].list), &priv->pshare->wlanicv_list);
+
+ INIT_LIST_HEAD(&(pwlanmic_poll->hdrnode[i].list));
+ list_add_tail( &(pwlanmic_poll->hdrnode[i].list), &priv->pshare->wlanmic_list);
+ }
+
+ for(i=0; i< PRE_ALLOCATED_MMPDU; i++)
+ {
+ INIT_LIST_HEAD(&(pwlanbuf_poll->hdrnode[i].list));
+ list_add_tail( &(pwlanbuf_poll->hdrnode[i].list), &priv->pshare->wlanbuf_list);
+ }
+
+ DEBUG_INFO("hdrlist=%x, llc_hdrlist=%x, buf_list=%x, icv_list=%x, mic_list=%X\n",
+ (UINT)&priv->pshare->wlan_hdrlist, (UINT)&priv->pshare->wlanllc_hdrlist, (UINT)&priv->pshare->wlanbuf_list,
+ (UINT)&priv->pshare->wlanicv_list, (UINT)&priv->pshare->wlanmic_list);
+
+ page_ptr = (unsigned char *)phw->ring_virt_addr;
+ memset(page_ptr, 0, phw->ring_buf_len); // this is vital!
+
+#ifndef __KERNEL__
+ if ((unsigned int)page_ptr & (~(PAGE_SIZE - 1)))
+ page_ptr = (unsigned char *)(((unsigned int)page_ptr & (~(PAGE_SIZE - 1))) + PAGE_SIZE);
+#endif
+#ifdef CONFIG_NET_PCI
+ if (!IS_PCIBIOS_TYPE)
+#endif
+ phw->ring_dma_addr = virt_to_bus(page_ptr);
+
+ phw->rx_ring_addr = phw->ring_dma_addr;
+ phw->tx_ring0_addr = phw->ring_dma_addr + NUM_RX_DESC * sizeof(struct rx_desc);
+ phw->tx_ring1_addr = phw->tx_ring0_addr + NUM_TX_DESC * sizeof(struct tx_desc);
+ phw->tx_ring2_addr = phw->tx_ring1_addr + NUM_TX_DESC * sizeof(struct tx_desc);
+ phw->tx_ring3_addr = phw->tx_ring2_addr + NUM_TX_DESC * sizeof(struct tx_desc);
+ phw->tx_ring4_addr = phw->tx_ring3_addr + NUM_TX_DESC * sizeof(struct tx_desc);
+ phw->tx_ring5_addr = phw->tx_ring4_addr + NUM_TX_DESC * sizeof(struct tx_desc);
+ phw->rxcmd_ring_addr = phw->tx_ring5_addr + NUM_TX_DESC * sizeof(struct tx_desc);
+ phw->txcmd_ring_addr = phw->rxcmd_ring_addr + NUM_CMD_DESC * sizeof(struct rx_desc);
+ phw->tx_ringB_addr = phw->txcmd_ring_addr + NUM_CMD_DESC * sizeof(struct tx_desc);
+
+ phw->rx_descL = (struct rx_desc *)page_ptr;
+ phw->tx_desc0 = (struct tx_desc *)(page_ptr + NUM_RX_DESC * sizeof(struct rx_desc));
+ phw->tx_desc1 = (struct tx_desc *)((unsigned long)phw->tx_desc0 + NUM_TX_DESC * sizeof(struct tx_desc));
+ phw->tx_desc2 = (struct tx_desc *)((unsigned long)phw->tx_desc1 + NUM_TX_DESC * sizeof(struct tx_desc));
+ phw->tx_desc3 = (struct tx_desc *)((unsigned long)phw->tx_desc2 + NUM_TX_DESC * sizeof(struct tx_desc));
+ phw->tx_desc4 = (struct tx_desc *)((unsigned long)phw->tx_desc3 + NUM_TX_DESC * sizeof(struct tx_desc));
+ phw->tx_desc5 = (struct tx_desc *)((unsigned long)phw->tx_desc4 + NUM_TX_DESC * sizeof(struct tx_desc));
+ phw->rxcmd_desc = (struct rx_desc *)((unsigned long)phw->tx_desc5 + NUM_TX_DESC * sizeof(struct tx_desc));
+ phw->txcmd_desc = (struct tx_desc *)((unsigned long)phw->rxcmd_desc + NUM_CMD_DESC * sizeof(struct rx_desc));
+ phw->tx_descB = (struct tx_desc *)((unsigned long)phw->txcmd_desc + NUM_CMD_DESC * sizeof(struct tx_desc));
+
+ /* To set the DMA address for both RX/TX ring */
+ {
+#ifndef USE_RTL8186_SDK
+ int txDescRingIdx;
+
+ struct tx_desc *tx_desc_array[] = {
+ phw->tx_desc0,
+ phw->tx_desc1,
+ phw->tx_desc2,
+ phw->tx_desc3,
+ phw->tx_desc4,
+ phw->tx_desc5,
+ phw->tx_descB,
+ 0
+ };
+#ifdef CONFIG_NET_PCI
+ unsigned long *tx_desc_dma_array[] = {
+ (unsigned long*)(phw->tx_desc0_dma_addr),
+ (unsigned long*)(phw->tx_desc1_dma_addr),
+ (unsigned long*)(phw->tx_desc2_dma_addr),
+ (unsigned long*)(phw->tx_desc3_dma_addr),
+ (unsigned long*)(phw->tx_desc4_dma_addr),
+ (unsigned long*)(phw->tx_desc5_dma_addr),
+ (unsigned long*)(phw->tx_descB_dma_addr),
+ (unsigned long*)0
+ };
+#endif
+#endif // !USE_RTL8186_SDK
+
+ /* RX RING */
+#if defined(NOT_RTK_BSP)
+ for (i=0; i<NUM_RX_DESC; i++) {
+ phw->rx_descL_dma_addr[i] = phw->rx_ring_addr + i*(sizeof(struct rx_desc));
+ }
+#else
+ for (i=0; i<NUM_RX_DESC; i++) {
+ phw->rx_descL_dma_addr[i] = get_physical_addr(priv, (void *)(&phw->rx_descL[i]),
+ sizeof(struct rx_desc), PCI_DMA_TODEVICE);
+ }
+#endif
+
+#ifndef USE_RTL8186_SDK
+
+#if defined(NOT_RTK_BSP)
+ unsigned int tx_dma_start;
+ tx_dma_start = phw->ring_dma_addr + NUM_RX_DESC * sizeof(struct rx_desc);
+#endif
+
+ /* TX RING */
+ txDescRingIdx = 0;
+
+ while (tx_desc_array[txDescRingIdx] != 0) {
+#ifdef CONFIG_NET_PCI
+ unsigned long *tx_desc_dma_ptr = tx_desc_dma_array[txDescRingIdx];
+#endif
+ struct tx_desc *tx_desc_ptr = tx_desc_array[txDescRingIdx];
+
+#if defined(NOT_RTK_BSP)
+ for (i=0; i<NUM_TX_DESC; i++) {
+ tx_desc_dma_ptr[i]= tx_dma_start + txDescRingIdx*NUM_TX_DESC * sizeof(struct tx_desc) + i*sizeof(struct tx_desc);
+ }
+#else
+ for (i=0; i<NUM_TX_DESC; i++) {
+ tx_desc_dma_ptr[i] = get_physical_addr(priv, (void *)(&(tx_desc_ptr[i])),
+ sizeof(struct tx_desc), PCI_DMA_TODEVICE);
+ }
+#endif
+
+ txDescRingIdx ++;
+ }
+#endif // !USE_RTL8186_SDK
+
+#if defined(NOT_RTK_BSP)
+ for (i=0; i<NUM_CMD_DESC; i++) {
+ phw->rxcmd_desc_dma_addr[i] = phw->rxcmd_ring_addr + i*sizeof(struct rx_desc);
+ phw->txcmd_desc_dma_addr[i] = phw->txcmd_ring_addr + i*sizeof(struct tx_desc);
+ }
+
+#else
+ for (i=0; i<NUM_CMD_DESC; i++) {
+ phw->rxcmd_desc_dma_addr[i] = get_physical_addr(priv, (void *)(&phw->rxcmd_desc[i]),
+ sizeof(struct rx_desc), PCI_DMA_TODEVICE);
+ phw->txcmd_desc_dma_addr[i] = get_physical_addr(priv, (void *)(&phw->txcmd_desc[i]),
+ sizeof(struct tx_desc), PCI_DMA_TODEVICE);
+ }
+#endif
+ }
+
+ DEBUG_INFO("rx_descL=%08x tx_desc0=%08x, tx_desc1=%08x, tx_desc2=%08x, tx_desc3=%08x, tx_desc4=%08x, "
+ "tx_desc5=%08x, rxcmd_desc=%08x, txcmd_desc=%08x, tx_descB=%08x\n",
+ (UINT)phw->rx_descL, (UINT)phw->tx_desc0, (UINT)phw->tx_desc1, (UINT)phw->tx_desc2,
+ (UINT)phw->tx_desc3, (UINT)phw->tx_desc4, (UINT)phw->tx_desc5,
+ (UINT)phw->rxcmd_desc, (UINT)phw->txcmd_desc, (UINT)phw->tx_descB);
+#ifdef RTK_QUE
+ rtk_queue_init(&priv->pshare->skb_queue);
+#else
+ skb_queue_head_init(&priv->pshare->skb_queue);
+#endif
+
+ // Now for Rx desc...
+ for(i=0; i<NUM_RX_DESC; i++)
+ {
+ pskb = rtl_dev_alloc_skb(priv, RX_BUF_LEN, _SKB_RX_, 1);
+ if (pskb == NULL) {
+ printk("can't allocate skbuff for RX, abort!\n");
+ return 1;
+ }
+ init_rxdesc(pskb, i, priv);
+ }
+
+ // Nothing to do for Tx desc...
+ for(i=0; i<NUM_TX_DESC; i++)
+ {
+ init_txdesc(priv, phw->tx_desc0, phw->tx_ring0_addr, i);
+ init_txdesc(priv, phw->tx_desc1, phw->tx_ring1_addr, i);
+ init_txdesc(priv, phw->tx_desc2, phw->tx_ring2_addr, i);
+ init_txdesc(priv, phw->tx_desc3, phw->tx_ring3_addr, i);
+ init_txdesc(priv, phw->tx_desc4, phw->tx_ring4_addr, i);
+ init_txdesc(priv, phw->tx_desc5, phw->tx_ring5_addr, i);
+ }
+
+#ifdef MBSSID
+ for(i=0; i<(RTL8192CD_NUM_VWLAN+1); i++) {
+ if (GET_ROOT(priv)->pmib->miscEntry.vap_enable) {
+ if (i == RTL8192CD_NUM_VWLAN)
+ (phw->tx_descB + i)->Dword10 = set_desc(phw->tx_ringB_addr);
+ //(phw->tx_descB + i)->NextTxDescAddress = set_desc(phw->tx_ringB_addr);
+ else
+ (phw->tx_descB + i)->Dword10 = set_desc(phw->tx_ringB_addr + (i+1) * sizeof(struct tx_desc));
+ //(phw->tx_descB + i)->NextTxDescAddress = set_desc(phw->tx_ringB_addr + (i+1) * sizeof(struct tx_desc));
+ }
+ }
+#endif
+
+ //Family add: must re-initialize use_txdesc_cnt after realloc txdesc
+#ifdef RESERVE_TXDESC_FOR_EACH_IF
+ for(i=0; i<=HIGH_QUEUE; ++i) {
+ priv->use_txdesc_cnt[i] = 0;
+ }
+
+#ifdef MBSSID
+ if (priv->pmib->miscEntry.vap_enable){
+ int j;
+ for (i=0; i<RTL8192CD_NUM_VWLAN; ++i){
+ for (j=0; j<=HIGH_QUEUE; ++j){
+ priv->pvap_priv[i]->use_txdesc_cnt[j] = 0;
+ }
+ }
+ }
+#endif // #ifdef MBSSID
+#ifdef UNIVERSAL_REPEATER
+ if (GET_VXD_PRIV(priv)) {
+ for(i=0; i<=HIGH_QUEUE; ++i) {
+ GET_VXD_PRIV(priv)->use_txdesc_cnt[i] = 0;
+ }
+ }
+#endif // #ifdef UNIVERSAL_REPEATER
+#endif // #ifdef RESERVE_TXDESC_FOR_EACH_IF
+ for(i=0; i<NUM_CMD_DESC; i++) {
+ if (i == (NUM_CMD_DESC - 1))// set NextAddrs
+ (phw->txcmd_desc + i)->Dword9 = set_desc(phw->txcmd_ring_addr);
+ else
+ (phw->txcmd_desc + i)->Dword9 = set_desc(phw->txcmd_ring_addr + (i+1) * sizeof(struct tx_desc));
+ }
+
+ priv->pshare->amsdu_timer_head = priv->pshare->amsdu_timer_tail = 0;
+
+#ifdef RX_BUFFER_GATHER
+ INIT_LIST_HEAD(&priv->pshare->gather_list);
+#endif
+ }
+
+ INIT_LIST_HEAD(&priv->wlan_acl_list);
+ INIT_LIST_HEAD(&priv->wlan_aclpolllist);
+
+ pwlan_acl_poll = priv->pwlan_acl_poll;
+ for(i=0; i< NUM_ACL; i++)
+ {
+ INIT_LIST_HEAD(&(pwlan_acl_poll->aclnode[i].list));
+ list_add_tail(&(pwlan_acl_poll->aclnode[i].list), &priv->wlan_aclpolllist);
+ }
+
+ // copy acl from mib to link list
+ for (i=0; i<priv->pmib->dot11StationConfigEntry.dot11AclNum; i++)
+ {
+ struct list_head *pnewlist;
+ struct wlan_acl_node *paclnode;
+
+ pnewlist = priv->wlan_aclpolllist.next;
+ list_del_init(pnewlist);
+
+ paclnode = list_entry(pnewlist, struct wlan_acl_node, list);
+ memcpy((void *)paclnode->addr, priv->pmib->dot11StationConfigEntry.dot11AclAddr[i], 6);
+ paclnode->mode = (unsigned char)priv->pmib->dot11StationConfigEntry.dot11AclMode;
+
+ list_add_tail(pnewlist, &priv->wlan_acl_list);
+ }
+
+ for(i=0; i<NUM_STAT; i++)
+ INIT_LIST_HEAD(&(priv->stat_hash[i]));
+
+#ifdef CONFIG_RTK_MESH
+ /*
+ * CAUTION !! These statement meshX(virtual interface) ONLY, Maybe modify....
+ */
+#ifdef _MESH_ACL_ENABLE_ // copy acl from mib to link list (below code copy above ACL code)
+ INIT_LIST_HEAD(&priv->mesh_acl_list);
+ INIT_LIST_HEAD(&priv->mesh_aclpolllist);
+
+ pmesh_acl_poll = priv->pmesh_acl_poll;
+ for(i=0; i< NUM_MESH_ACL; i++)
+ {
+ INIT_LIST_HEAD(&(pmesh_acl_poll->meshaclnode[i].list));
+ list_add_tail(&(pmesh_acl_poll->meshaclnode[i].list), &priv->mesh_aclpolllist);
+ }
+
+ for (i=0; i<priv->pmib->dot1180211sInfo.mesh_acl_num; i++)
+ {
+ struct list_head *pnewlist;
+ struct wlan_acl_node *paclnode;
+
+ pnewlist = priv->mesh_aclpolllist.next;
+ list_del_init(pnewlist);
+
+ paclnode = list_entry(pnewlist, struct wlan_acl_node, list);
+ memcpy((void *)paclnode->addr, priv->pmib->dot1180211sInfo.mesh_acl_addr[i], MACADDRLEN);
+ paclnode->mode = (unsigned char)priv->pmib->dot1180211sInfo.mesh_acl_mode;
+
+ list_add_tail(pnewlist, &priv->mesh_acl_list);
+ }
+#endif
+
+#ifdef MESH_BOOTSEQ_AUTH
+ INIT_LIST_HEAD(&(priv->mesh_auth_hdr));
+#endif
+
+ INIT_LIST_HEAD(&(priv->mesh_unEstablish_hdr));
+ INIT_LIST_HEAD(&(priv->mesh_mp_hdr));
+
+ priv->mesh_profile[0].used = FALSE; // Configure by WEB in the future, Maybe delete, Preservation before delete
+#endif
+
+ INIT_LIST_HEAD(&(priv->asoc_list));
+ INIT_LIST_HEAD(&(priv->auth_list));
+ INIT_LIST_HEAD(&(priv->sleep_list));
+ INIT_LIST_HEAD(&(priv->defrag_list));
+ INIT_LIST_HEAD(&(priv->wakeup_list));
+ INIT_LIST_HEAD(&(priv->rx_datalist));
+ INIT_LIST_HEAD(&(priv->rx_mgtlist));
+ INIT_LIST_HEAD(&(priv->rx_ctrllist));
+ INIT_LIST_HEAD(&(priv->addRAtid_list)); // to avoid add RAtid fail
+ INIT_LIST_HEAD(&(priv->addrssi_list));
+
+#ifdef A4_STA
+ INIT_LIST_HEAD(&(priv->a4_sta_list));
+#endif
+
+#ifdef CHECK_BEACON_HANGUP
+ if (priv->reset_hangup)
+ priv->pshare->beacon_wait_cnt = 1;
+ else
+ priv->pshare->beacon_wait_cnt = 2;
+#endif
+
+#ifdef CHECK_HANGUP
+ if (priv->reset_hangup) {
+ get_available_channel(priv);
+ validate_oper_rate(priv);
+ get_oper_rate(priv);
+ DOT11_InitQueue(priv->pevent_queue);
+ return 0;
+ }
+#endif
+
+ // construct operation and basic rates set
+ {
+ // validate region domain
+ if ((priv->pmib->dot11StationConfigEntry.dot11RegDomain < DOMAIN_FCC) ||
+ (priv->pmib->dot11StationConfigEntry.dot11RegDomain >= DOMAIN_MAX)) {
+ PRINT_INFO("invalid region domain, use default value [DOMAIN_FCC]!\n");
+ priv->pmib->dot11StationConfigEntry.dot11RegDomain = DOMAIN_FCC;
+ }
+
+ // validate band
+ if (priv->pmib->dot11BssType.net_work_type == 0) {
+ PRINT_INFO("operation band is not set, use G+B as default!\n");
+ priv->pmib->dot11BssType.net_work_type = WIRELESS_11B | WIRELESS_11G;
+ }
+ if ((OPMODE & WIFI_AP_STATE) && (priv->pmib->dot11BssType.net_work_type & (WIRELESS_11B | WIRELESS_11G))) {
+ if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) {
+ priv->pmib->dot11BssType.net_work_type &= (WIRELESS_11B | WIRELESS_11G);
+ PRINT_INFO("operation band not appropriate, use G/B as default!\n");
+ }
+ }
+
+ if (should_forbid_Nmode(priv))
+ priv->pmib->dot11BssType.net_work_type &= ~WIRELESS_11N;
+
+ // validate channel number
+ if (get_available_channel(priv) == FAIL) {
+ PRINT_INFO("can't get operation channels, abort!\n");
+ return 1;
+ }
+ if (priv->pmib->dot11RFEntry.dot11channel != 0) {
+ for (i=0; i<priv->available_chnl_num; i++)
+ if (priv->pmib->dot11RFEntry.dot11channel == priv->available_chnl[i])
+ break;
+ if (i == priv->available_chnl_num) {
+ priv->pmib->dot11RFEntry.dot11channel = priv->available_chnl[0];
+
+ PRINT_INFO("invalid channel number, use default value [%d]!\n",
+ priv->pmib->dot11RFEntry.dot11channel);
+ }
+ priv->auto_channel = 0;
+#ifdef SIMPLE_CH_UNI_PROTOCOL
+ SET_PSEUDO_RANDOM_NUMBER(priv->mesh_ChannelPrecedence);
+#endif
+ }
+ else {
+#ifdef SIMPLE_CH_UNI_PROTOCOL
+ if(GET_MIB(priv)->dot1180211sInfo.mesh_enable)
+ priv->auto_channel = 16;
+ else
+#endif
+ {
+ if (OPMODE & WIFI_AP_STATE)
+ priv->auto_channel = 1;
+ else
+ priv->auto_channel = 2;
+ priv->pmib->dot11RFEntry.dot11channel = priv->available_chnl[0];
+ }
+ }
+ priv->auto_channel_backup = priv->auto_channel;
+
+ // validate hi and low channel
+ if (priv->pmib->dot11RFEntry.dot11ch_low != 0) {
+ for (i=0; i<priv->available_chnl_num; i++)
+ if (priv->pmib->dot11RFEntry.dot11ch_low == priv->available_chnl[i])
+ break;
+ if (i == priv->available_chnl_num) {
+ priv->pmib->dot11RFEntry.dot11ch_low = priv->available_chnl[0];
+
+ PRINT_INFO("invalid low channel number, use default value [%d]!\n",
+ priv->pmib->dot11RFEntry.dot11ch_low);
+ }
+ }
+ if (priv->pmib->dot11RFEntry.dot11ch_hi != 0) {
+ for (i=0; i<priv->available_chnl_num; i++)
+ if (priv->pmib->dot11RFEntry.dot11ch_hi == priv->available_chnl[i])
+ break;
+ if (i == priv->available_chnl_num) {
+ priv->pmib->dot11RFEntry.dot11ch_hi = priv->available_chnl[priv->available_chnl_num-1];
+
+ PRINT_INFO("invalid hi channel number, use default value [%d]!\n",
+ priv->pmib->dot11RFEntry.dot11ch_hi);
+ }
+ }
+
+// Mark the code to auto disable N mode in WEP encrypt
+#if 0
+ if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) &&
+ (priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm == _WEP_40_PRIVACY_ ||
+ priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm == _WEP_104_PRIVACY_))
+ priv->pmib->dot11BssType.net_work_type &= ~WIRELESS_11N;
+#endif
+//------------------------------ david+2008-01-11
+
+ // support cck only in channel 14
+ if ((priv->pmib->dot11RFEntry.disable_ch14_ofdm) &&
+ (priv->pmib->dot11RFEntry.dot11channel == 14)) {
+ priv->pmib->dot11BssType.net_work_type = WIRELESS_11B;
+ PRINT_INFO("support cck only in channel 14!\n");
+ }
+
+ // validate and get support and basic rates
+ validate_oper_rate(priv);
+ get_oper_rate(priv);
+
+ if (priv->pmib->dot11nConfigEntry.dot11nUse40M &&
+ (!(priv->pmib->dot11BssType.net_work_type & WIRELESS_11N))) {
+ PRINT_INFO("enable 40M but not in N mode! back to 20M\n");
+ priv->pmib->dot11nConfigEntry.dot11nUse40M = 0;
+ }
+
+ // check deny band
+ if ((priv->pmib->dot11BssType.net_work_type & (~priv->pmib->dot11StationConfigEntry.legacySTADeny)) == 0) {
+ PRINT_INFO("legacySTADeny %d not suitable! set to 0\n", priv->pmib->dot11StationConfigEntry.legacySTADeny);
+ priv->pmib->dot11StationConfigEntry.legacySTADeny = 0;
+ }
+ }
+
+ if (!(priv->pmib->dot11BssType.net_work_type & WIRELESS_11N)) {
+ if (AMSDU_ENABLE)
+ AMSDU_ENABLE = 0;
+ if (AMPDU_ENABLE)
+ AMPDU_ENABLE = 0;
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+ priv->pshare->is_40m_bw = 0;
+ priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_DONTCARE;
+ }
+ }
+ else {
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+ priv->pshare->is_40m_bw = priv->pmib->dot11nConfigEntry.dot11nUse40M;
+ if (priv->pshare->is_40m_bw == 0)
+ priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_DONTCARE;
+ else {
+#ifdef CONFIG_RTL_92D_SUPPORT
+ if ((priv->pmib->dot11RFEntry.phyBandSelect & PHY_BAND_5G)&&(GET_CHIP_VER(priv)==VERSION_8192D)) {
+ priv->pshare->offset_2nd_chan = priv->pmib->dot11nConfigEntry.dot11n2ndChOffset;
+ } else
+#endif
+ {
+ if ((priv->pmib->dot11RFEntry.dot11channel < 5) &&
+ (priv->pmib->dot11nConfigEntry.dot11n2ndChOffset == HT_2NDCH_OFFSET_BELOW))
+ priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_ABOVE;
+ else if ((priv->pmib->dot11RFEntry.dot11channel > 9) &&
+ (priv->pmib->dot11nConfigEntry.dot11n2ndChOffset == HT_2NDCH_OFFSET_ABOVE))
+ priv->pshare->offset_2nd_chan = HT_2NDCH_OFFSET_BELOW;
+ else
+ priv->pshare->offset_2nd_chan = priv->pmib->dot11nConfigEntry.dot11n2ndChOffset;
+ }
+ }
+ }
+
+ // force wmm enabled if n mode
+ // so hostapd should always set wmm_enabled=1 if n mode.
+ QOS_ENABLE = 1;
+ }
+
+ // set wep key length
+ if (priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm == _WEP_40_PRIVACY_)
+ priv->pmib->dot1180211AuthEntry.dot11PrivacyKeyLen = 8;
+ else if (priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm == _WEP_104_PRIVACY_)
+ priv->pmib->dot1180211AuthEntry.dot11PrivacyKeyLen = 16;
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+ init_crc32_table(); // for sw encryption
+ }
+
+#ifdef WIFI_WMM
+ if (QOS_ENABLE) {
+ if ((OPMODE & WIFI_AP_STATE)
+#ifdef CLIENT_MODE
+ || (OPMODE & WIFI_ADHOC_STATE)
+#endif
+ ) {
+ GET_EDCA_PARA_UPDATE = 0;
+ //BK
+ GET_STA_AC_BK_PARA.AIFSN = 7;
+ GET_STA_AC_BK_PARA.TXOPlimit = 0;
+ GET_STA_AC_BK_PARA.ACM = 0;
+ GET_STA_AC_BK_PARA.ECWmin = 4;
+ GET_STA_AC_BK_PARA.ECWmax = 10;
+ //BE
+ GET_STA_AC_BE_PARA.AIFSN = 3;
+ GET_STA_AC_BE_PARA.TXOPlimit = 0;
+ GET_STA_AC_BE_PARA.ACM = 0;
+ GET_STA_AC_BE_PARA.ECWmin = 4;
+ GET_STA_AC_BE_PARA.ECWmax = 10;
+ //VI
+ GET_STA_AC_VI_PARA.AIFSN = 2;
+ if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) ||
+ (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A))
+ GET_STA_AC_VI_PARA.TXOPlimit = 94; // 3.008ms
+ else
+ GET_STA_AC_VI_PARA.TXOPlimit = 188; // 6.016ms
+ GET_STA_AC_VI_PARA.ACM = 0;
+ GET_STA_AC_VI_PARA.ECWmin = 3;
+ GET_STA_AC_VI_PARA.ECWmax = 4;
+ //VO
+ GET_STA_AC_VO_PARA.AIFSN = 2;
+ if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) ||
+ (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A))
+ GET_STA_AC_VO_PARA.TXOPlimit = 47; // 1.504ms
+ else
+ GET_STA_AC_VO_PARA.TXOPlimit = 102; // 3.264ms
+ GET_STA_AC_VO_PARA.ACM = 0;
+ GET_STA_AC_VO_PARA.ECWmin = 2;
+ GET_STA_AC_VO_PARA.ECWmax = 3;
+
+ //init WMM Para ie in beacon
+ init_WMM_Para_Element(priv, priv->pmib->dot11QosEntry.WMM_PARA_IE);
+ }
+#ifdef CLIENT_MODE
+ else if (OPMODE & WIFI_STATION_STATE)
+ init_WMM_Para_Element(priv, priv->pmib->dot11QosEntry.WMM_IE); // WMM STA
+#endif
+ }
+#endif
+
+ i = priv->pmib->dot11ErpInfo.ctsToSelf;
+ memset(&priv->pmib->dot11ErpInfo, '\0', sizeof(struct erp_mib)); // reset ERP mib
+ priv->pmib->dot11ErpInfo.ctsToSelf = i;
+
+ if ( (priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) ||
+ (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) )
+ priv->pmib->dot11ErpInfo.shortSlot = 1;
+ else
+ priv->pmib->dot11ErpInfo.shortSlot = 0;
+
+ if (OPMODE & WIFI_AP_STATE) {
+ memcpy(priv->pmib->dot11StationConfigEntry.dot11Bssid,
+ priv->pmib->dot11OperationEntry.hwaddr, 6);
+ //priv->oper_band = priv->pmib->dot11BssType.net_work_type;
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+ if (!priv->pshare->ra40MLowerMinus && (priv->pshare->rf_ft_var.raGoUp40MLower > 5) &&
+ (priv->pshare->rf_ft_var.raGoDown40MLower > 5)) {
+ priv->pshare->rf_ft_var.raGoUp40MLower-=5;
+ priv->pshare->rf_ft_var.raGoDown40MLower-=5;
+ priv->pshare->ra40MLowerMinus++;
+ }
+#ifdef HIGH_POWER_EXT_PA
+ if (!priv->pshare->raThdHP_Minus) {
+
+ if( priv->pshare->rf_ft_var.use_ext_pa ) {
+ if(priv->pshare->rf_ft_var.raGoDownUpper > RSSI_DIFF_PA) {
+ priv->pshare->rf_ft_var.raGoDownUpper -= RSSI_DIFF_PA;
+ priv->pshare->rf_ft_var.raGoUpUpper -= RSSI_DIFF_PA;
+ }
+ if(priv->pshare->rf_ft_var.raGoDown20MLower > RSSI_DIFF_PA) {
+ priv->pshare->rf_ft_var.raGoDown20MLower -= RSSI_DIFF_PA;
+ priv->pshare->rf_ft_var.raGoUp20MLower -= RSSI_DIFF_PA;
+ }
+ if(priv->pshare->rf_ft_var.raGoDown40MLower > RSSI_DIFF_PA) {
+ priv->pshare->rf_ft_var.raGoDown40MLower -= RSSI_DIFF_PA;
+ priv->pshare->rf_ft_var.raGoUp40MLower -= RSSI_DIFF_PA;
+ }
+ }
+ ++priv->pshare->raThdHP_Minus;
+ }
+#endif
+ }
+ }
+#ifdef CLIENT_MODE
+ else {
+ if (priv->pmib->dot11StationConfigEntry.dot11DefaultSSIDLen == 0) {
+ priv->pmib->dot11StationConfigEntry.dot11DefaultSSIDLen = 11;
+ memcpy(priv->pmib->dot11StationConfigEntry.dot11DefaultSSID, "defaultSSID", 11);
+ }
+ memset(priv->pmib->dot11StationConfigEntry.dot11Bssid, 0, 6);
+ priv->join_res = STATE_Sta_No_Bss;
+
+// Add mac clone address manually ----------
+#ifdef RTK_BR_EXT
+ if (priv->pmib->ethBrExtInfo.macclone_enable == 2) {
+ extern void mac_clone(struct rtl8192cd_priv *priv, unsigned char *addr);
+ mac_clone(priv, priv->pmib->ethBrExtInfo.nat25_dmzMac);
+ priv->macclone_completed = 1;
+ }
+#endif
+//------------------------- david+2007-5-31
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+ if (priv->pshare->ra40MLowerMinus) {
+ priv->pshare->rf_ft_var.raGoUp40MLower+=5;
+ priv->pshare->rf_ft_var.raGoDown40MLower+=5;
+ priv->pshare->ra40MLowerMinus = 0;
+ }
+ }
+ }
+#endif
+
+ // initialize event queue
+ DOT11_InitQueue(priv->pevent_queue);
+#ifdef CONFIG_RTL_WAPI_SUPPORT
+ DOT11_InitQueue(priv->wapiEvent_queue);
+#ifdef MBSSID
+ if (IS_ROOT_INTERFACE(priv)&&priv->pmib->miscEntry.vap_enable) {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++)
+ DOT11_InitQueue(priv->pvap_priv[i]->wapiEvent_queue);
+ }
+#endif
+
+#endif
+
+#ifdef CONFIG_RTK_MESH
+ if(GET_MIB(priv)->dot1180211sInfo.mesh_enable == 1) // plus add 0217, not mesh mode should not do below function
+ {
+ DOT11_InitQueue2(priv->pathsel_queue, MAXQUEUESIZE2, MAXDATALEN2);
+#ifdef _11s_TEST_MODE_
+ DOT11_InitQueue2(priv->receiver_queue, MAXQUEUESIZE2, MAXDATALEN2);
+#endif
+ //modify by Joule for SECURITY
+ i = priv->pmib->dot11sKeysTable.dot11Privacy;
+ memset(&priv->pmib->dot11sKeysTable, '\0', sizeof(struct Dot11KeyMappingsEntry)); // reset key
+ priv->pmib->dot11sKeysTable.dot11Privacy = i;
+ } //
+#endif
+
+#ifdef __DRAYTEK_OS__
+ if (priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm != _TKIP_PRIVACY_ &&
+ priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm != _CCMP_PRIVACY_ &&
+ priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm != _WEP_WPA_MIXED_PRIVACY_) {
+#ifdef UNIVERSAL_REPEATER
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+ priv->pmib->dot11RsnIE.rsnielen = 0; // reset RSN IE length
+ memset(&priv->pmib->dot11GroupKeysTable, '\0', sizeof(struct Dot11KeyMappingsEntry)); // reset group key
+#ifdef UNIVERSAL_REPEATER
+ if (GET_VXD_PRIV(priv))
+ GET_VXD_PRIV(priv)->pmib->dot11RsnIE.rsnielen = 0;
+#endif
+ }
+ }
+#endif
+
+ i = RC_ENTRY_NUM;
+ for (;;) {
+ if (priv->pmib->reorderCtrlEntry.ReorderCtrlWinSz >= i) {
+ priv->pmib->reorderCtrlEntry.ReorderCtrlWinSz = i;
+ break;
+ }
+ else if (i > 8)
+ i = i / 2;
+ else {
+ priv->pmib->reorderCtrlEntry.ReorderCtrlWinSz = 8;
+ break;
+ }
+ }
+
+ // Realtek proprietary IE
+ memcpy(&(priv->pshare->rtk_ie_buf[0]), Realtek_OUI, 3);
+ priv->pshare->rtk_ie_buf[3] = 2;
+ priv->pshare->rtk_ie_buf[4] = 1;
+ priv->pshare->rtk_ie_buf[5] = 0;
+ priv->pshare->rtk_ie_buf[5] |= RTK_CAP_IE_WLAN_88C92C | RTK_CAP_IE_WLAN_8192SE;
+#ifdef CLIENT_MODE
+ if (OPMODE & WIFI_STATION_STATE)
+ priv->pshare->rtk_ie_buf[5] |= RTK_CAP_IE_AP_CLIENT;
+#endif
+ priv->pshare->rtk_ie_len = 6;
+
+
+#ifdef WIFI_HAPD
+ if ((priv->pmib->dot1180211AuthEntry.dot11EnablePSK == 0)
+ && (priv->pmib->dot118021xAuthEntry.dot118021xAlgrthm)
+ && (priv->pmib->dot1180211AuthEntry.dot11WPACipher || priv->pmib->dot1180211AuthEntry.dot11WPA2Cipher))
+ rsn_init(priv);
+#endif
+
+#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD)
+ if (priv->pmib->dot1180211AuthEntry.dot11EnablePSK)
+ psk_init(priv);
+
+#ifdef WDS
+#ifdef UNIVERSAL_REPEATER
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+#ifdef LAZY_WDS
+ if (priv->pmib->dot11WdsInfo.wdsEnabled == WDS_LAZY_ENABLE) {
+ priv->pmib->dot11WdsInfo.wdsNum = 0;
+ memset(priv->pmib->dot11WdsInfo.entry, '\0', sizeof(struct wdsEntry)*NUM_WDS);
+ }
+#endif
+ if ((priv->pmib->dot11WdsInfo.wdsEnabled) && (priv->pmib->dot11WdsInfo.wdsNum > 0) &&
+ ((priv->pmib->dot11WdsInfo.wdsPrivacy == _TKIP_PRIVACY_) ||
+ (priv->pmib->dot11WdsInfo.wdsPrivacy == _CCMP_PRIVACY_)))
+ wds_psk_init(priv);
+ }
+#endif
+#endif
+
+#ifdef WIFI_WPAS
+
+ {
+ WPAS_ASSOCIATION_INFO Assoc_Info;
+ memset((void *)&Assoc_Info, 0, sizeof(struct _WPAS_ASSOCIATION_INFO));
+ Assoc_Info.ReqIELen = priv->pmib->dot11RsnIE.rsnie[1]+ 2;
+ memcpy(Assoc_Info.ReqIE, priv->pmib->dot11RsnIE.rsnie, Assoc_Info.ReqIELen);
+
+ //event_indicate_wpas(priv, NULL, WPAS_ASSOC_INFO, (UINT8 *)&Assoc_Info);
+ }
+
+#endif
+
+
+#ifdef GBWC
+ priv->GBWC_tx_queue.head = 0;
+ priv->GBWC_tx_queue.tail = 0;
+ priv->GBWC_rx_queue.head = 0;
+ priv->GBWC_rx_queue.tail = 0;
+ priv->GBWC_tx_count = 0;
+ priv->GBWC_rx_count = 0;
+ priv->GBWC_consuming_Q = 0;
+#endif
+
+ priv->release_mcast = 0;
+
+#ifdef USB_PKT_RATE_CTRL_SUPPORT //mark_test
+ priv->change_toggle = 0;
+ priv->pre_pkt_cnt = 0;
+ priv->pkt_nsec_diff = 0;
+ priv->poll_usb_cnt = 0;
+ priv->auto_rate_mask = 0;
+#endif
+
+#ifdef STA_EXT
+ priv->pshare->fw_free_space = FW_NUM_STAT - 2; // One for MAGANEMENT_AID, one for other STAs
+#endif
+
+#ifdef CONFIG_RTK_VLAN_SUPPORT
+ if (priv->pmib->vlan.global_vlan)
+ priv->pmib->dot11OperationEntry.disable_brsc = 1;
+#endif
+
+
+#ifdef CONFIG_RTL_WAPI_SUPPORT
+ if (priv->pmib->wapiInfo.wapiType!=wapiDisable)
+ {
+ /* set NMK */
+ GenerateRandomData(priv->wapiNMK, WAPI_KEY_LEN);
+ priv->wapiMCastKeyId = 0;
+ priv->wapiMCastKeyUpdate = 0;
+ priv->wapiWaiTxSeq = 0;
+ wapiInit(priv);
+ }
+
+#ifdef MBSSID
+ if (IS_ROOT_INTERFACE(priv)&&priv->pmib->miscEntry.vap_enable) {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++)
+ if (priv->pvap_priv[i]->pmib->wapiInfo.wapiType!=wapiDisable) {
+ /* set NMK */
+ GenerateRandomData(priv->pvap_priv[i]->wapiNMK, WAPI_KEY_LEN);
+ priv->pvap_priv[i]->wapiMCastKeyId = 0;
+ priv->pvap_priv[i]->wapiMCastKeyUpdate = 0;
+ priv->wapiWaiTxSeq = 0;
+ wapiInit(priv->pvap_priv[i]);
+ }
+ }
+#endif
+#endif
+
+#ifdef MBSSID
+ // if vap enabled, set beacon int to 100 at minimun when guest ssid num <= 4
+ // if vap enabled, set beacon int to 200 at minimun when guest ssid num > 4
+ {
+ int ssid_num = 1, minbcn_period;
+ priv->bcn_period_bak = priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod;
+
+ if ((OPMODE & WIFI_AP_STATE) && GET_ROOT(priv)->pmib->miscEntry.vap_enable)
+ {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++)
+ {
+ if (GET_ROOT(priv)->pvap_priv[i] && IS_DRV_OPEN(GET_ROOT(priv)->pvap_priv[i]))
+ {
+ ssid_num++;
+ }
+ }
+ }
+
+ if (ssid_num >= 5)
+ minbcn_period = 200;
+ else
+ minbcn_period = 100;
+
+ // if vap enabled, set beacon int to 100 at minimun
+ if ((OPMODE & WIFI_AP_STATE) && GET_ROOT(priv)->pmib->miscEntry.vap_enable
+ && priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod < minbcn_period)
+ priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod = minbcn_period;
+
+ if ((OPMODE & WIFI_AP_STATE) && GET_ROOT(priv)->pmib->miscEntry.vap_enable)
+ {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++)
+ {
+ if (GET_ROOT(priv)->pvap_priv[i])
+ {
+ GET_ROOT(priv)->pvap_priv[i]->pmib->dot11StationConfigEntry.dot11BeaconPeriod = priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod;
+ GET_ROOT(priv)->pvap_priv[i]->update_bcn_period = 1;
+ }
+ }
+
+ GET_ROOT(priv)->pmib->dot11StationConfigEntry.dot11BeaconPeriod = priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod;
+ GET_ROOT(priv)->update_bcn_period = 1;
+
+ }
+ }
+#endif
+
+#ifdef DOT11D
+{
+ extern COUNTRY_IE_ELEMENT countryIEArray[];
+ int found = 0;
+ char *CStringPtr = priv->pmib->dot11dCountry.dot11CountryString ;
+
+ if ((OPMODE & WIFI_AP_STATE) && COUNTRY_CODE_ENABLED) {
+ for (i=0; i<COUNTRYNUMBER; i++) {
+ if (!memcmp(CStringPtr, countryIEArray[i].countryA2, 2)) {
+ priv->pshare->countryTabIdx = i;
+ found = 1;
+ break;
+ }
+ }
+
+ if (found == 0) {
+ priv->pshare->countryTabIdx = 1;
+ printk("can't found country code(%s),use default region\n",CStringPtr);
+ }
+
+ i = priv->pshare->countryTabIdx;
+
+ if (countryIEArray[i].A_Band_Region == 0) {
+ priv->pshare->countryBandUsed=0; /*2.4G*/
+ } else {
+ /*5G*/
+ if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) {
+ priv->pshare->countryBandUsed = 1; /*5G*/
+ //printk("2.4G and 5G both enabled, select 5G \n");
+ } else {
+ priv->pshare->countryBandUsed = 0; /*2.4G*/
+ //printk("2.4G and 5G both enabled, select 2.4G \n");
+ }
+ }
+ }
+}
+#endif
+
+#ifdef RTL_MANUAL_EDCA
+ for (i=0; i<8; i++) {
+ if ((priv->pmib->dot11QosEntry.TID_mapping[i] < 1) || (priv->pmib->dot11QosEntry.TID_mapping[i] > 4))
+ priv->pmib->dot11QosEntry.TID_mapping[i] = 2;
+ }
+#endif
+
+#ifdef TXREPORT
+ priv->pshare->sta_query_idx=-1;
+
+ // Init StaDetectInfo to detect disappearing STA. Added by Annie, 2010-08-10.
+ priv->pmib->staDetectInfo.txRprDetectPeriod = 1;
+#endif
+
+#ifdef INCLUDE_WPS
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ wps_init(priv);
+#endif
+
+ return 0;
+}
+
+
+static int rtl8192cd_stop_sw(struct rtl8192cd_priv *priv)
+{
+ struct rtl8192cd_hw *phw;
+ unsigned long flags;
+ int i;
+
+ // we hope all this can be done in critical section
+ SAVE_INT_AND_CLI(flags);
+
+#ifdef INCLUDE_WPS
+ priv->pshare->WSC_CONT_S.wait_reinit = 1 ;
+#endif
+
+ if (timer_pending(&priv->frag_to_filter))
+ del_timer_sync(&priv->frag_to_filter);
+
+#ifdef DETECT_STA_EXISTANCE
+ // Added by Annie for Retry Limit Recovery Timer, 2010-08-10.
+ if (timer_pending(&priv->pshare->rl_recover_timer))
+ del_timer_sync (&priv->pshare->rl_recover_timer);
+#endif
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+ if (timer_pending(&priv->expire_timer))
+ del_timer_sync(&priv->expire_timer);
+#ifdef SW_ANT_SWITCH
+ if (timer_pending(&priv->pshare->swAntennaSwitchTimer))
+ del_timer_sync(&priv->pshare->swAntennaSwitchTimer);
+#endif
+ if (timer_pending(&priv->pshare->rc_sys_timer))
+ del_timer_sync(&priv->pshare->rc_sys_timer);
+#if 0
+ if (timer_pending(&priv->pshare->phw->tpt_timer))
+ del_timer_sync(&priv->pshare->phw->tpt_timer);
+#endif
+#ifdef CONFIG_RTL_WAPI_SUPPORT
+ if (priv->pmib->wapiInfo.wapiType!=wapiDisable
+#ifdef CHECK_HANGUP
+ &&(!priv->reset_hangup)
+#endif
+ )
+ {
+ wapiExit(priv);
+ }
+
+
+#ifdef MBSSID
+ if( priv->pmib->miscEntry.vap_enable) {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++){
+ if (priv->pvap_priv[i]->pmib->wapiInfo.wapiType!=wapiDisable
+#ifdef CHECK_HANGUP
+ &&(!priv->pvap_priv[i]->reset_hangup)
+#endif
+ ) {
+ wapiExit(priv->pvap_priv[i]);
+ }
+ }
+ }
+#endif
+#endif
+
+#ifdef PCIE_POWER_SAVING
+ if (timer_pending(&priv->ps_timer))
+ del_timer_sync(&priv->ps_timer);
+#endif
+#ifdef CONFIG_RTK_MESH
+ /*
+ * CAUTION !! These statement meshX(virtual interface) ONLY, Maybe modify....
+ */
+ if (timer_pending(&priv->mesh_peer_link_timer))
+ del_timer_sync(&priv->mesh_peer_link_timer);
+
+#ifdef MESH_BOOTSEQ_AUTH
+ if (timer_pending(&priv->mesh_auth_timer))
+ del_timer_sync(&priv->mesh_auth_timer);
+#endif
+#endif
+ }
+ if (timer_pending(&priv->ss_timer))
+ del_timer_sync(&priv->ss_timer);
+ if (timer_pending(&priv->MIC_check_timer))
+ del_timer_sync(&priv->MIC_check_timer);
+ if (timer_pending(&priv->assoc_reject_timer))
+ del_timer_sync(&priv->assoc_reject_timer);
+ // to avoid add RAtid fail
+ if (timer_pending(&priv->add_RATid_timer))
+ del_timer_sync(&priv->add_RATid_timer);
+ if (timer_pending(&priv->add_rssi_timer))
+ del_timer_sync(&priv->add_rssi_timer);
+ if (timer_pending(&priv->add_ps_timer))
+ del_timer_sync(&priv->add_ps_timer);
+
+
+#if defined(CONFIG_RTL_92D_SUPPORT) && defined(CONFIG_RTL_NOISE_CONTROL)
+ if (GET_CHIP_VER(priv) == VERSION_8192D){
+ if (timer_pending(&priv->dnc_timer))
+ del_timer_sync(&priv->dnc_timer);
+ }
+#endif
+
+#ifdef SMART_CONCURRENT_92D
+ if (GET_CHIP_VER(priv) == VERSION_8192D){
+ if (timer_pending(&priv->smcc_prb_timer))
+ del_timer_sync(&priv->smcc_prb_timer);
+ }
+#endif
+
+#ifdef CLIENT_MODE
+ if (timer_pending(&priv->reauth_timer))
+ del_timer_sync(&priv->reauth_timer);
+ if (timer_pending(&priv->reassoc_timer))
+ del_timer_sync(&priv->reassoc_timer);
+ if (timer_pending(&priv->idle_timer))
+ del_timer_sync(&priv->idle_timer);
+#endif
+
+#ifdef GBWC
+ if (timer_pending(&priv->GBWC_timer))
+ del_timer_sync(&priv->GBWC_timer);
+ while (CIRC_CNT(priv->GBWC_tx_queue.head, priv->GBWC_tx_queue.tail, NUM_TXPKT_QUEUE))
+ {
+ struct sk_buff *pskb = priv->GBWC_tx_queue.pSkb[priv->GBWC_tx_queue.tail];
+ rtl_kfree_skb(priv, pskb, _SKB_TX_);
+ priv->GBWC_tx_queue.tail++;
+ priv->GBWC_tx_queue.tail = priv->GBWC_tx_queue.tail & (NUM_TXPKT_QUEUE - 1);
+ }
+ while (CIRC_CNT(priv->GBWC_rx_queue.head, priv->GBWC_rx_queue.tail, NUM_TXPKT_QUEUE))
+ {
+ struct sk_buff *pskb = priv->GBWC_rx_queue.pSkb[priv->GBWC_rx_queue.tail];
+ rtl_kfree_skb(priv, pskb, _SKB_RX_);
+ priv->GBWC_rx_queue.tail++;
+ priv->GBWC_rx_queue.tail = priv->GBWC_rx_queue.tail & (NUM_TXPKT_QUEUE - 1);
+ }
+#endif
+
+#ifdef INCLUDE_WPA_PSK
+ if (timer_pending(&priv->wpa_global_info->GKRekeyTimer))
+ del_timer_sync(&priv->wpa_global_info->GKRekeyTimer);
+#endif
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+#ifdef DFS
+ if (timer_pending(&priv->DFS_timer))
+ del_timer_sync(&priv->DFS_timer);
+
+ if (timer_pending(&priv->ch_avail_chk_timer))
+ del_timer_sync(&priv->ch_avail_chk_timer);
+
+ /*
+ * when we disable the DFS function dynamically, we also remove the channel
+ * from NOP_chnl while the driver is rebooting
+ */
+ if (timer_pending(&priv->ch52_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch52_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 52);
+ }
+
+ if (timer_pending(&priv->ch56_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch56_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 56);
+ }
+
+ if (timer_pending(&priv->ch60_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch60_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 60);
+ }
+
+ if (timer_pending(&priv->ch64_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch64_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 64);
+ }
+
+ if (timer_pending(&priv->ch100_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch100_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 100);
+ }
+
+ if (timer_pending(&priv->ch104_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch104_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 104);
+ }
+
+ if (timer_pending(&priv->ch108_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch108_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 108);
+ }
+
+ if (timer_pending(&priv->ch112_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch112_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 112);
+ }
+
+ if (timer_pending(&priv->ch116_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch116_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 116);
+ }
+
+ if (timer_pending(&priv->ch120_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch120_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 120);
+ }
+
+ if (timer_pending(&priv->ch124_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch124_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 124);
+ }
+
+ if (timer_pending(&priv->ch128_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch128_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 128);
+ }
+
+ if (timer_pending(&priv->ch132_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch128_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 128);
+ }
+
+ if (timer_pending(&priv->ch136_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch136_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 136);
+ }
+
+ if (timer_pending(&priv->ch140_timer) &&
+ (priv->pmib->dot11DFSEntry.disable_DFS)) {
+ del_timer_sync(&priv->ch140_timer);
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 140);
+ }
+
+ /*
+ * For JAPAN in adhoc mode
+ */
+ if (((priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK) ||
+ (priv->pmib->dot11StationConfigEntry.dot11RegDomain == DOMAIN_MKK3)) &&
+ (OPMODE & WIFI_ADHOC_STATE)) {
+ if (priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) {
+ if (!timer_pending(&priv->ch52_timer))
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 52);
+ if (!timer_pending(&priv->ch56_timer))
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 56);
+ if (!timer_pending(&priv->ch60_timer))
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 60);
+ if (!timer_pending(&priv->ch64_timer))
+ RemoveChannel(priv->NOP_chnl, &priv->NOP_chnl_num, 64);
+ }
+ }
+#endif // DFS
+
+ // for SW LED
+ if ((LED_TYPE >= LEDTYPE_SW_LINK_TXRX) && (LED_TYPE < LEDTYPE_SW_MAX))
+ disable_sw_LED(priv);
+
+#ifdef __KERNEL__
+#ifdef DFS
+ /* prevent killing tasklet issue in interrupt */
+ if (!priv->pmib->dot11DFSEntry.DFS_detected)
+#endif
+ {
+#ifdef CHECK_HANGUP
+ if (!priv->reset_hangup)
+#endif
+ {
+ tasklet_kill(&priv->pshare->rx_tasklet);
+ tasklet_kill(&priv->pshare->tx_tasklet);
+ tasklet_kill(&priv->pshare->oneSec_tasklet);
+ }
+ }
+#endif // __KERNEL__
+
+ phw = GET_HW(priv);
+
+#ifdef DELAY_REFILL_RX_BUF
+ priv->pshare->phw->cur_rx_refill = priv->pshare->phw->cur_rx = 0; // avoid refill to rx ring
+#endif
+ for (i=0; i<NUM_RX_DESC; i++)
+ {
+ if (phw->rx_infoL[i].pbuf != NULL) {
+#ifdef CONFIG_NET_PCI
+ // if pci bios, then pci_unmap_single and dev_kfree_skb
+ if (IS_PCIBIOS_TYPE)
+ pci_unmap_single(priv->pshare->pdev, phw->rx_infoL[i].paddr, (RX_BUF_LEN - sizeof(struct rx_frinfo)), PCI_DMA_FROMDEVICE);
+#endif
+ rtl_kfree_skb(priv, (struct sk_buff*)(phw->rx_infoL[i].pbuf), _SKB_RX_);
+ }
+ }
+
+ // free the skb buffer in Low and Hi queue
+ DEBUG_INFO("free tx Q0 head %d tail %d\n", phw->txhead0, phw->txtail0);
+ DEBUG_INFO("free tx Q1 head %d tail %d\n", phw->txhead1, phw->txtail1);
+ DEBUG_INFO("free tx Q2 head %d tail %d\n", phw->txhead2, phw->txtail2);
+ DEBUG_INFO("free tx Q3 head %d tail %d\n", phw->txhead3, phw->txtail3);
+ DEBUG_INFO("free tx Q4 head %d tail %d\n", phw->txhead4, phw->txtail4);
+ DEBUG_INFO("free tx Q5 head %d tail %d\n", phw->txhead5, phw->txtail5);
+
+ for (i=0; i<NUM_TX_DESC; i++)
+ {
+ // free tx queue skb
+ struct tx_desc_info *tx_info;
+ int j;
+ int head, tail;
+
+ for (j=0; j<=HIGH_QUEUE; j++) {
+ head = get_txhead(phw, j);
+ tail = get_txtail(phw, j);
+// if (i <tail || i >= head)
+ if( (tail < head) ? (i <tail || i >= head) :(i <tail && i >= head))
+ continue;
+
+ tx_info = get_txdesc_info(priv->pshare->pdesc_info, j);
+
+#if defined(RESERVE_TXDESC_FOR_EACH_IF) && (defined(UNIVERSAL_REPEATER) || defined(MBSSID)) //Family add
+ if (tx_info[i].priv)
+ tx_info[i].priv->use_txdesc_cnt[j]--;
+#endif
+
+ if (tx_info[i].pframe &&
+ (tx_info[i].type == _SKB_FRAME_TYPE_)) {
+#ifdef CONFIG_NET_PCI
+ if (IS_PCIBIOS_TYPE)
+ pci_unmap_single(priv->pshare->pdev, tx_info[i].paddr, (tx_info[i].len), PCI_DMA_TODEVICE);
+#endif
+ rtl_kfree_skb(priv, tx_info[i].pframe, _SKB_TX_);
+ DEBUG_INFO("free skb in queue %d\n", j);
+ }
+ }
+ } // TX descriptor Free
+
+#ifdef CONFIG_NET_PCI
+ // unmap beacon buffer
+ if (IS_PCIBIOS_TYPE) {
+ pci_unmap_single(priv->pshare->pdev, get_desc(phw->tx_descB->Dword8),
+ 128*sizeof(unsigned int), PCI_DMA_TODEVICE);
+ }
+#endif
+
+#ifdef RX_BUFFER_GATHER
+ flush_rx_list(priv);
+#endif
+ } // if (IS_ROOT_INTERFACE(priv))
+
+ for (i=0; i<NUM_STAT; i++)
+ {
+ if (priv->pshare->aidarray[i]) {
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (priv != priv->pshare->aidarray[i]->priv)
+ continue;
+ else
+#endif
+ {
+ if (priv->pshare->aidarray[i]->used == TRUE)
+ if (free_stainfo(priv, &(priv->pshare->aidarray[i]->station)) == FALSE)
+ DEBUG_ERR("free station %d fails\n", i);
+
+#if defined(WIFI_WMM) && defined(WMM_APSD)
+#ifdef PRIV_STA_BUF
+ free_sta_que(priv, priv->pshare->aidarray[i]->station.VO_dz_queue);
+ free_sta_que(priv, priv->pshare->aidarray[i]->station.VI_dz_queue);
+ free_sta_que(priv, priv->pshare->aidarray[i]->station.BE_dz_queue);
+ free_sta_que(priv, priv->pshare->aidarray[i]->station.BK_dz_queue);
+
+#else
+ kfree(priv->pshare->aidarray[i]->station.VO_dz_queue);
+ kfree(priv->pshare->aidarray[i]->station.VI_dz_queue);
+ kfree(priv->pshare->aidarray[i]->station.BE_dz_queue);
+ kfree(priv->pshare->aidarray[i]->station.BK_dz_queue);
+#endif
+#endif
+
+#if defined(WIFI_WMM)
+#ifdef PRIV_STA_BUF
+ free_sta_mgt_que(priv, priv->pshare->aidarray[i]->station.MGT_dz_queue);
+#else
+ kfree(priv->pshare->aidarray[i]->station.MGT_dz_queue);
+#endif
+#endif
+
+#ifdef INCLUDE_WPA_PSK
+#ifdef PRIV_STA_BUF
+ free_wpa_buf(priv, priv->pshare->aidarray[i]->station.wpa_sta_info);
+#else
+ kfree(priv->pshare->aidarray[i]->station.wpa_sta_info);
+#endif
+#endif
+#ifdef RTL8192CD_VARIABLE_USED_DMEM
+ {
+ unsigned int index = (unsigned int)i;
+ rtl8192cd_dmem_free(AID_OBJ, &index);
+ }
+#else
+#ifdef PRIV_STA_BUF
+ free_sta_obj(priv, priv->pshare->aidarray[i]);
+#else
+ kfree(priv->pshare->aidarray[i]);
+#endif
+#endif
+ priv->pshare->aidarray[i] = NULL;
+ }
+ }
+ }
+
+#ifndef __DRAYTEK_OS__
+ // reset rsnie and group key from open to here, david
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+#ifdef WIFI_SIMPLE_CONFIG
+ if (!priv->pmib->dot11OperationEntry.keep_rsnie) {
+ priv->pmib->wscEntry.beacon_ielen = 0;
+ priv->pmib->wscEntry.probe_rsp_ielen = 0;
+ priv->pmib->wscEntry.probe_req_ielen = 0;
+ priv->pmib->wscEntry.assoc_ielen = 0;
+ }
+
+// if (!(OPMODE & WIFI_AP_STATE))
+// priv->pmib->dot11OperationEntry.keep_rsnie = 1;
+#endif
+ }
+
+ if (!priv->pmib->dot11OperationEntry.keep_rsnie) {
+ priv->pmib->dot11RsnIE.rsnielen = 0; // reset RSN IE length
+ memset(&priv->pmib->dot11GroupKeysTable, '\0', sizeof(struct Dot11KeyMappingsEntry)); // reset group key
+#ifdef UNIVERSAL_REPEATER
+ if (GET_VXD_PRIV(priv))
+ GET_VXD_PRIV(priv)->pmib->dot11RsnIE.rsnielen = 0;
+#endif
+ priv->auto_channel_backup = 0;
+ }
+ else {
+ // When wlan scheduling and auto-chan case, it will disable/enable
+ // wlan interface directly w/o re-set mib. Therefore, we need use
+ // "keep_rsnie" flag to keep auto-chan value
+
+ if (
+#ifdef CHECK_HANGUP
+ !priv->reset_hangup &&
+#endif
+ priv->auto_channel_backup)
+ priv->pmib->dot11RFEntry.dot11channel = 0;
+ }
+#endif
+
+#ifdef MBSSID
+ if (GET_ROOT(priv)->pmib->miscEntry.vap_enable)
+ {
+ if (IS_VAP_INTERFACE(priv) && !priv->pmib->dot11OperationEntry.keep_rsnie) {
+ priv->pmib->dot11RsnIE.rsnielen = 0; // reset RSN IE length
+ memset(&priv->pmib->dot11GroupKeysTable, '\0', sizeof(struct Dot11KeyMappingsEntry)); // reset group key
+ }
+ }
+
+ priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod = priv->bcn_period_bak;
+#endif
+
+#ifdef RTK_BR_EXT
+ if (OPMODE & (WIFI_STATION_STATE | WIFI_ADHOC_STATE)) {
+#ifdef CHECK_HANGUP
+ if (!priv->reset_hangup)
+#endif
+ nat25_db_cleanup(priv);
+ }
+#endif
+
+#ifdef A4_STA
+ if (OPMODE & WIFI_AP_STATE) {
+#ifdef CHECK_HANGUP
+ if (!priv->reset_hangup)
+#endif
+ a4_sta_cleanup(priv);
+ }
+#endif
+
+ {
+ int hd, tl;
+ struct sk_buff *pskb;
+
+ hd = priv->dz_queue.head;
+ tl = priv->dz_queue.tail;
+ while (CIRC_CNT(hd, tl, NUM_TXPKT_QUEUE))
+ {
+ pskb = priv->dz_queue.pSkb[tl];
+ rtl_kfree_skb(priv, pskb, _SKB_TX_);
+ tl++;
+ tl = tl & (NUM_TXPKT_QUEUE - 1);
+ }
+ priv->dz_queue.head = 0;
+ priv->dz_queue.tail = 0;
+ }
+
+#ifdef MP_TEST
+ if (!priv->pshare->rf_ft_var.mp_specific)
+#endif
+ priv->pshare->ThermalValue = 0;
+
+ RESTORE_INT(flags);
+ return 0;
+}
+
+
+#ifdef MBSSID
+static void rtl8192cd_init_vap_mib(struct rtl8192cd_priv *priv)
+{
+#if 0
+ unsigned char tmpbuf[36], hwaddr[6];
+ int len;
+ //unsigned int AclMode;
+ //unsigned char AclAddr[NUM_ACL][MACADDRLEN];
+ //unsigned int AclNum;
+ struct Dot1180211AuthEntry dot1180211AuthEntry;
+ struct Dot118021xAuthEntry dot118021xAuthEntry;
+ struct Dot11DefaultKeysTable dot11DefaultKeysTable;
+ struct Dot11RsnIE dot11RsnIE;
+
+ // backup mib that can differ from root interface
+ memcpy(hwaddr, GET_MY_HWADDR, 6);
+ len = SSID_LEN;
+ memcpy(tmpbuf, SSID, len);
+ //AclMode = priv->pmib->dot11StationConfigEntry.dot11AclMode;
+ //memcpy(AclAddr, priv->pmib->dot11StationConfigEntry.dot11AclAddr, sizeof(AclAddr));
+ //AclNum = priv->pmib->dot11StationConfigEntry.dot11AclNum;
+ memcpy(&dot1180211AuthEntry, &priv->pmib->dot1180211AuthEntry, sizeof(struct Dot1180211AuthEntry));
+ memcpy(&dot118021xAuthEntry, &priv->pmib->dot118021xAuthEntry, sizeof(struct Dot118021xAuthEntry));
+ memcpy(&dot11DefaultKeysTable, &priv->pmib->dot11DefaultKeysTable, sizeof(struct Dot11DefaultKeysTable));
+ memcpy(&dot11RsnIE, &priv->pmib->dot11RsnIE, sizeof(struct Dot11RsnIE));
+
+ // copy mib from root interface
+ memcpy(priv->pmib, GET_ROOT_PRIV(priv)->pmib, sizeof(struct wifi_mib));
+
+ // restore the different part
+ memcpy(GET_MY_HWADDR, hwaddr, 6);
+ SSID_LEN = len;
+ memcpy(SSID, tmpbuf, len);
+ SSID2SCAN_LEN = len;
+ memcpy(SSID2SCAN, SSID, len);
+ //priv->pmib->dot11StationConfigEntry.dot11AclMode = AclMode;
+ //memcpy(priv->pmib->dot11StationConfigEntry.dot11AclAddr, AclAddr, sizeof(AclAddr));
+ //priv->pmib->dot11StationConfigEntry.dot11AclNum = AclNum;
+ memcpy(&priv->pmib->dot1180211AuthEntry, &dot1180211AuthEntry, sizeof(struct Dot1180211AuthEntry));
+ memcpy(&priv->pmib->dot118021xAuthEntry, &dot118021xAuthEntry, sizeof(struct Dot118021xAuthEntry));
+ memcpy(&priv->pmib->dot11DefaultKeysTable, &dot11DefaultKeysTable, sizeof(struct Dot11DefaultKeysTable));
+ memcpy(&priv->pmib->dot11RsnIE, &dot11RsnIE, sizeof(struct Dot11RsnIE));
+#endif
+
+ // copy mib_rf from root interface
+ memcpy(&priv->pmib->dot11RFEntry, &GET_ROOT_PRIV(priv)->pmib->dot11RFEntry, sizeof(struct Dot11RFEntry));
+
+ // special mib that need to set
+#ifdef WIFI_WMM
+ //QOS_ENABLE = 0;
+#ifdef WMM_APSD
+ APSD_ENABLE = 0;
+#endif
+#endif
+
+#ifdef WDS
+ // always disable wds in vap
+ priv->pmib->dot11WdsInfo.wdsEnabled = 0;
+ priv->pmib->dot11WdsInfo.wdsPure = 0;
+#endif
+#ifdef CONFIG_RTK_MESH
+ // in current release, mesh can be only run upon wlan0, so we disable the following flag in vap
+ priv->pmib->dot1180211sInfo.mesh_enable = 0;
+#endif
+}
+
+
+static void rtl8192cd_init_mbssid(struct rtl8192cd_priv *priv)
+{
+ int i, j;
+ unsigned int camData[2];
+ unsigned char *macAddr = GET_MY_HWADDR;
+
+ if (IS_ROOT_INTERFACE(priv))
+ {
+ //camData[0] = 0x00800000 | (macAddr[5] << 8) | macAddr[4];
+ camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | MBIDCAM_VALID | (macAddr[5] << 8) | macAddr[4];
+ camData[1] = (macAddr[3] << 24) | (macAddr[2] << 16) | (macAddr[1] << 8) | macAddr[0];
+// for (j=0; j<2; j++) {
+ for (j=1; j>=0; j--) {
+ //RTL_W32((_MBIDCAMCONTENT_+4)-4*j, camData[j]);
+ RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
+ }
+ //RTL_W8(_MBIDCAMCFG_, BIT(7) | BIT(6));
+
+ // clear the rest area of CAM
+ //camData[0] = 0;
+ camData[1] = 0;
+ for (i=1; i<8; i++) {
+ camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | (i&MBIDCAM_ADDR_Mask)<<MBIDCAM_ADDR_SHIFT;
+// for (j=0; j<2; j++) {
+ for (j=1; j>=0; j--) {
+ RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
+ }
+// RTL_W8(_MBIDCAMCFG_, BIT(7) | BIT(6) | (unsigned char)i);
+ }
+
+ // set MBIDCTRL & MBID_BCN_SPACE by cmd
+// set_fw_reg(priv, 0xf1000101, 0, 0);
+ RTL_W32(MBSSID_BCN_SPACE,
+ (priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod & BCN_SPACE2_Mask)<<BCN_SPACE2_SHIFT
+ |(priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod & BCN_SPACE1_Mask)<<BCN_SPACE1_SHIFT);
+
+ RTL_W8(BCN_CTRL, 0);
+ RTL_W8(0x553, 1);
+
+ if (IS_TEST_CHIP(priv))
+ RTL_W8(BCN_CTRL, EN_BCN_FUNCTION |EN_MBSSID| DIS_SUB_STATE | DIS_TSF_UPDATE|EN_TXBCN_RPT);
+ else
+ RTL_W8(BCN_CTRL, EN_BCN_FUNCTION | DIS_SUB_STATE_N | DIS_TSF_UPDATE_N|EN_TXBCN_RPT);
+
+ RTL_W32(RCR, RTL_R32(RCR) | RCR_MBID_EN); // MBSSID enable
+/*
+#ifdef CLIENT_MODE
+ if ((OPMODE & WIFI_STATION_STATE) || (OPMODE & WIFI_ADHOC_STATE))
+ RTL_W32(RCR, RTL_R32(RCR) | RCR_CBSSID);
+#endif
+*/
+ }
+ else if (IS_VAP_INTERFACE(priv))
+ {
+// priv->vap_init_seq = (RTL_R8(_MBIDCTRL_) & (BIT(4) | BIT(5) | BIT(6))) >> 4;
+// priv->vap_init_seq++;
+// set_fw_reg(priv, 0xf1000001 | ((priv->vap_init_seq + 1)&0xffff)<<8, 0, 0);
+
+ priv->vap_init_seq = RTL_R8(MBID_NUM) & MBID_BCN_NUM_Mask;
+ priv->vap_init_seq++;
+ camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | MBIDCAM_VALID |
+ (priv->vap_init_seq&MBIDCAM_ADDR_Mask)<<MBIDCAM_ADDR_SHIFT |
+ (macAddr[5] << 8) | macAddr[4];
+ camData[1] = (macAddr[3] << 24) | (macAddr[2] << 16) | (macAddr[1] << 8) | macAddr[0];
+ for (j=1; j>=0; j--) {
+ RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
+ }
+// RTL_W8(_MBIDCAMCFG_, BIT(7) | BIT(6) | ((unsigned char)priv->vap_init_seq & 0x1f));
+ RTL_W32(MBSSID_BCN_SPACE,
+ ((priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod-
+ ((priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod/(priv->vap_init_seq+1))*priv->vap_init_seq))
+ & BCN_SPACE2_Mask)<<BCN_SPACE2_SHIFT
+ |((priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod/(priv->vap_init_seq+1)) & BCN_SPACE1_Mask)
+ <<BCN_SPACE1_SHIFT);
+ RTL_W8(BCN_CTRL, 0);
+ RTL_W8(0x553, 1);
+
+ if (IS_TEST_CHIP(priv))
+ RTL_W8(BCN_CTRL, EN_BCN_FUNCTION |EN_MBSSID| DIS_SUB_STATE | DIS_TSF_UPDATE|EN_TXBCN_RPT);
+ else
+ RTL_W8(BCN_CTRL, EN_BCN_FUNCTION | DIS_SUB_STATE_N | DIS_TSF_UPDATE_N|EN_TXBCN_RPT);
+
+
+ RTL_W8(MBID_NUM, priv->vap_init_seq & MBID_BCN_NUM_Mask);
+ RTL_W32(RCR, RTL_R32(RCR) & ~RCR_MBID_EN);
+ RTL_W32(RCR, RTL_R32(RCR) | RCR_MBID_EN); // MBSSID enable
+ }
+}
+
+
+static void rtl8192cd_stop_mbssid(struct rtl8192cd_priv *priv)
+{
+ int i, j;
+ unsigned int camData[2];
+ camData[1] = 0;
+
+ if (IS_ROOT_INTERFACE(priv))
+ {
+ // clear the rest area of CAM
+ for (i=0; i<8; i++) {
+ camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | (i&MBIDCAM_ADDR_Mask)<<MBIDCAM_ADDR_SHIFT;
+ for (j=1; j>=0; j--) {
+ RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
+ }
+// RTL_W8(_MBIDCAMCFG_, BIT(7) | BIT(6) | (unsigned char)i);
+ }
+
+// set_fw_reg(priv, 0xf1000001, 0, 0);
+ RTL_W32(RCR, RTL_R32(RCR) & ~RCR_MBID_EN); // MBSSID disable
+ RTL_W32(MBSSID_BCN_SPACE,
+ (priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod & BCN_SPACE1_Mask)<<BCN_SPACE1_SHIFT);
+
+ RTL_W8(BCN_CTRL, 0);
+ RTL_W8(0x553, 1);
+ if (IS_TEST_CHIP(priv))
+ RTL_W8(BCN_CTRL, EN_BCN_FUNCTION | DIS_SUB_STATE | DIS_TSF_UPDATE| EN_TXBCN_RPT);
+ else
+ RTL_W8(BCN_CTRL, EN_BCN_FUNCTION | DIS_SUB_STATE_N | DIS_TSF_UPDATE_N| EN_TXBCN_RPT);
+
+ }
+ else if (IS_VAP_INTERFACE(priv) && (priv->vap_init_seq >= 0))
+ {
+// set_fw_reg(priv, 0xf1000001 | (((RTL_R8(_MBIDCTRL_) & (BIT(4) | BIT(5) | BIT(6))) >> 4)&0xffff)<<8, 0, 0);
+ camData[0] = MBIDCAM_POLL | MBIDWRITE_EN |
+ (priv->vap_init_seq&MBIDCAM_ADDR_Mask)<<MBIDCAM_ADDR_SHIFT;
+ for (j=1; j>=0; j--) {
+ RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
+ }
+// RTL_W8(_MBIDCAMCFG_, BIT(7) | BIT(6) | ((unsigned char)priv->vap_init_seq & 0x1f));
+
+ if (RTL_R8(MBID_NUM) & MBID_BCN_NUM_Mask) {
+ RTL_W8(MBID_NUM, (RTL_R8(MBID_NUM)-1) & MBID_BCN_NUM_Mask);
+ RTL_W32(MBSSID_BCN_SPACE,
+ ((priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod-
+ ((priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod/(RTL_R8(MBID_NUM)+1))*RTL_R8(MBID_NUM)))
+ & BCN_SPACE2_Mask)<<BCN_SPACE2_SHIFT
+ |((priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod/(RTL_R8(MBID_NUM)+1)) & BCN_SPACE1_Mask)
+ <<BCN_SPACE1_SHIFT);
+ RTL_W8(BCN_CTRL, 0);
+ RTL_W8(0x553, 1);
+ if (IS_TEST_CHIP(priv))
+ RTL_W8(BCN_CTRL, EN_BCN_FUNCTION | DIS_SUB_STATE | DIS_TSF_UPDATE| EN_TXBCN_RPT);
+ else
+ RTL_W8(BCN_CTRL, EN_BCN_FUNCTION | DIS_SUB_STATE_N | DIS_TSF_UPDATE_N| EN_TXBCN_RPT);
+
+ }
+ RTL_W32(RCR, RTL_R32(RCR) & ~RCR_MBID_EN);
+ RTL_W32(RCR, RTL_R32(RCR) | RCR_MBID_EN);
+ priv->vap_init_seq = -1;
+ }
+}
+#endif
+
+
+#ifdef WDS
+#ifdef LAZY_WDS
+void delete_wds_entry(struct rtl8192cd_priv *priv, struct stat_info *pstat)
+{
+ int i;
+
+ for (i=0; i<NUM_WDS; i++) {
+ if (!memcmp(priv->pmib->dot11WdsInfo.entry[i].macAddr, pstat->hwaddr, MACADDRLEN)) {
+ memcpy(priv->pmib->dot11WdsInfo.entry[i].macAddr,
+ NULL_MAC_ADDR, MACADDRLEN);
+ free_stainfo(priv, pstat);
+ priv->pmib->dot11WdsInfo.wdsNum--;
+ break;
+ }
+ }
+}
+#endif
+
+struct stat_info *add_wds_entry(struct rtl8192cd_priv *priv, int idx, unsigned char *mac)
+{
+ struct stat_info *pstat;
+ DOT11_SET_KEY Set_Key;
+#ifdef LAZY_WDS
+ int i;
+
+ if (mac != NULL) {
+ for (i=0; i<NUM_WDS; i++) {
+ if (!memcmp(priv->pmib->dot11WdsInfo.entry[i].macAddr,
+ NULL_MAC_ADDR, MACADDRLEN)) {
+ memcpy( priv->pmib->dot11WdsInfo.entry[i].macAddr, mac, MACADDRLEN);
+ idx = i;
+ priv->pmib->dot11WdsInfo.wdsNum++;
+ break;
+ }
+ }
+ if (i == NUM_WDS) {
+ DEBUG_ERR("WDS table is full!!!\n");
+ return NULL;
+ }
+ }
+#endif
+
+ pstat = alloc_stainfo(priv, priv->pmib->dot11WdsInfo.entry[idx].macAddr, -1);
+ if (pstat == NULL) {
+ DEBUG_ERR("alloc_stainfo() fail!\n");
+ return NULL;
+ }
+
+ // use self supported rate for wds
+ memcpy(pstat->bssrateset, AP_BSSRATE, AP_BSSRATE_LEN);
+ pstat->bssratelen = AP_BSSRATE_LEN;
+
+ if (priv->pmib->dot11WdsInfo.entry[idx].txRate) {
+ if (!(priv->pmib->dot11BssType.net_work_type & WIRELESS_11N))
+ priv->pmib->dot11WdsInfo.entry[idx].txRate &= 0x0000fff; // mask HT rates
+
+ if (!(priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) &&
+ !(priv->pmib->dot11BssType.net_work_type & WIRELESS_11G))
+ priv->pmib->dot11WdsInfo.entry[idx].txRate &= 0xffff00f; // mask OFDM rates
+
+ if (!(priv->pmib->dot11BssType.net_work_type & WIRELESS_11B))
+ priv->pmib->dot11WdsInfo.entry[idx].txRate &= 0xffffff0; // mask CCK rates
+ }
+
+ pstat->state = WIFI_WDS;
+
+#ifdef LAZY_WDS
+ if (priv->pmib->dot11WdsInfo.wdsEnabled == WDS_LAZY_ENABLE)
+ pstat->state |= WIFI_WDS_LAZY;
+
+ if ((priv->pmib->dot11WdsInfo.wdsEnabled == WDS_LAZY_ENABLE) &&
+ (priv->pmib->dot11WdsInfo.wdsPrivacy == _TKIP_PRIVACY_ ||
+ priv->pmib->dot11WdsInfo.wdsPrivacy == _CCMP_PRIVACY_))
+ wds_psk_set(priv, idx, NULL);
+#endif
+
+ if (priv->pmib->dot11WdsInfo.wdsPrivacy == _WEP_40_PRIVACY_ ||
+ priv->pmib->dot11WdsInfo.wdsPrivacy == _WEP_104_PRIVACY_ ) {
+#ifndef CONFIG_RTL8186_KB
+ memcpy(Set_Key.MACAddr, priv->pmib->dot11WdsInfo.entry[idx].macAddr, 6);
+ Set_Key.KeyType = DOT11_KeyType_Pairwise;
+ Set_Key.EncType = priv->pmib->dot11WdsInfo.wdsPrivacy;
+ Set_Key.KeyIndex = priv->pmib->dot11WdsInfo.wdsKeyId;
+ DOT11_Process_Set_Key(priv->dev, NULL, &Set_Key, priv->pmib->dot11WdsInfo.wdsWepKey);
+#endif
+ }
+ else if ((priv->pmib->dot11WdsInfo.wdsPrivacy == _TKIP_PRIVACY_ ||
+ priv->pmib->dot11WdsInfo.wdsPrivacy == _CCMP_PRIVACY_) &&
+ (priv->pmib->dot11WdsInfo.wdsMappingKeyLen[idx]&0x80000000) ) {
+ priv->pmib->dot11WdsInfo.wdsMappingKeyLen[idx] &= ~0x80000000;
+ memcpy(Set_Key.MACAddr, priv->pmib->dot11WdsInfo.entry[idx].macAddr, 6);
+ Set_Key.KeyType = DOT11_KeyType_Pairwise;
+ Set_Key.EncType = priv->pmib->dot11WdsInfo.wdsPrivacy;
+ Set_Key.KeyIndex = priv->pmib->dot11WdsInfo.wdsKeyId;
+ DOT11_Process_Set_Key(priv->dev, NULL, &Set_Key, priv->pmib->dot11WdsInfo.wdsMapingKey[idx]);
+ }
+
+ add_update_RATid(priv, pstat);
+ pstat->wds_idx = idx;
+ assign_tx_rate(priv, pstat, NULL);
+ assign_aggre_mthod(priv, pstat);
+ assign_aggre_size(priv, pstat);
+
+ list_add_tail(&pstat->asoc_list, &priv->asoc_list);
+
+ return pstat;
+}
+
+static void create_wds_tbl(struct rtl8192cd_priv *priv)
+{
+ int i;
+ struct stat_info *pstat;
+
+#ifdef FAST_RECOVERY
+ if (priv->reset_hangup)
+ return;
+#endif
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (!IS_ROOT_INTERFACE(priv))
+ return;
+#endif
+
+ if (priv->pmib->dot11WdsInfo.wdsEnabled) {
+ for (i=0; i<priv->pmib->dot11WdsInfo.wdsNum; i++) {
+ pstat = add_wds_entry(priv, i, NULL);
+ if (pstat == NULL)
+ break;
+ }
+ }
+}
+#endif // WDS
+
+
+void validate_fixed_tx_rate(struct rtl8192cd_priv *priv)
+{
+ if (!priv->pmib->dot11StationConfigEntry.autoRate) {
+ if (!(priv->pmib->dot11BssType.net_work_type & WIRELESS_11N))
+ priv->pmib->dot11StationConfigEntry.fixedTxRate &= 0x0000fff; // mask HT rates
+
+ if((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) &&
+ ((get_rf_mimo_mode(priv) == MIMO_1T2R) || (get_rf_mimo_mode(priv) == MIMO_1T1R)))
+ priv->pmib->dot11StationConfigEntry.fixedTxRate &= 0x00fffff; // mask MCS8 - MCS15
+
+ if (!(priv->pmib->dot11BssType.net_work_type & WIRELESS_11A) &&
+ !(priv->pmib->dot11BssType.net_work_type & WIRELESS_11G))
+ priv->pmib->dot11StationConfigEntry.fixedTxRate &= 0xffff00f; // mask OFDM rates
+
+ if (!(priv->pmib->dot11BssType.net_work_type & WIRELESS_11B))
+ priv->pmib->dot11StationConfigEntry.fixedTxRate &= 0xffffff0; // mask CCK rates
+
+ if (priv->pmib->dot11StationConfigEntry.fixedTxRate==0) {
+ priv->pmib->dot11StationConfigEntry.autoRate=1;
+ PRINT_INFO("invalid fixed tx rate, use auto rate!\n");
+ }
+ else
+ priv->pshare->current_tx_rate = get_rate_from_bit_value(priv->pmib->dot11StationConfigEntry.fixedTxRate);
+ }
+}
+
+
+#if defined(RESERVE_TXDESC_FOR_EACH_IF) && (defined(UNIVERSAL_REPEATER) || defined(MBSSID))
+void recalc_txdesc_limit(struct rtl8192cd_priv *priv)
+{
+ struct rtl8192cd_priv *root_priv = NULL;
+ int i, num, total_if = 0;
+
+ if (IS_ROOT_INTERFACE(priv))
+ root_priv = priv;
+ else
+ root_priv = GET_ROOT_PRIV(priv);
+
+ if (IS_DRV_OPEN(root_priv))
+ total_if++;
+
+#ifdef UNIVERSAL_REPEATER
+ if (IS_DRV_OPEN(root_priv->pvxd_priv))
+ total_if++;
+#endif
+
+#ifdef MBSSID
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++) {
+ if (IS_DRV_OPEN(root_priv->pvap_priv[i]))
+ total_if++;
+ }
+#endif
+
+ if (total_if <= 1) {
+ root_priv->pshare->num_txdesc_cnt = NUM_TX_DESC - 2; // 2 for space...
+ root_priv->pshare->num_txdesc_upper_limit = NUM_TX_DESC - 2;
+ root_priv->pshare->num_txdesc_lower_limit = 0;
+ return;
+ }
+
+ num = (NUM_TX_DESC * IF_TXDESC_UPPER_LIMIT) / 100;
+ root_priv->pshare->num_txdesc_upper_limit = num;
+
+ num = ((NUM_TX_DESC - 2) - num) / (total_if - 1);
+ root_priv->pshare->num_txdesc_lower_limit = num;
+
+ num = root_priv->pshare->num_txdesc_upper_limit +
+ root_priv->pshare->num_txdesc_lower_limit * (total_if - 1);
+ root_priv->pshare->num_txdesc_cnt = num;
+}
+#endif
+
+
+int rtl8192cd_open(struct net_device *dev)
+{
+ struct rtl8192cd_priv *priv; // recuresively used, can't be static
+ int rc;
+#ifdef MBSSID
+ int i;
+#endif
+ unsigned long x;
+#if defined(CONFIG_RTL865X_WTDOG) || (defined(CONFIG_RTL_WTDOG) && defined(CONFIG_RTL_92D_SUPPORT))
+#if !(defined(CONFIG_RTL8196B) || defined(CONFIG_RTL_819X))
+ unsigned long wtval;
+#endif
+#endif
+#ifdef CHECK_HANGUP
+ int is_reset;
+#endif
+ int init_hw_cnt = 0;
+
+ DBFENTER;
+
+#ifdef NETDEV_NO_PRIV
+ priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv;
+#else
+ priv = dev->priv;
+#endif
+
+ #if defined(CONFIG_RTL_CUSTOM_PASSTHRU)
+ /*to open custom pass through pseudo device*/
+ if(dev==wlan_device[passThruWanIdx].priv->pWlanDev)
+ {
+ /*root device is opened*/
+ if(priv->drv_state&DRV_STATE_OPEN)
+ {
+ netif_start_queue(dev);
+ return 0;
+ }
+
+ }
+ #endif
+
+#if 0
+//#ifdef PCIE_POWER_SAVING
+ if (((REG32(CLK_MANAGE) & BIT(11)) == 0)
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ && IS_ROOT_INTERFACE(priv)
+#endif
+ ) {
+ extern void setBaseAddressRegister(void);
+ REG32(CLK_MANAGE) |= BIT(11);
+ delay_ms(10);
+ PCIE_reset_procedure(0, 0, 1, priv->pshare->ioaddr);
+ setBaseAddressRegister();
+ }
+#endif
+
+#ifdef CHECK_HANGUP
+ is_reset = priv->reset_hangup;
+#endif
+
+// init mib from cfg file, we only need to load cfg file once - chris 2010/02
+#ifdef CONFIG_RTL_COMAPI_CFGFILE
+#ifdef WDS
+ if (dev->base_addr) //root
+#endif
+ {
+ //printk(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>dev %s set_default\n", dev->name);
+ //memset(priv->pmib, 0, sizeof(struct wifi_mib));
+ //set_mib_default(priv);
+
+ CfgFileProc(dev);
+ }
+#endif
+
+// register iw_handler - chris 2010/02
+#ifdef CONFIG_RTL_COMAPI_WLTOOLS
+ dev->wireless_handlers = (struct iw_handler_def *) &rtl8192cd_iw_handler_def;
+#endif
+
+ memcpy((void *)dev->dev_addr, priv->pmib->dot11OperationEntry.hwaddr, 6);
+
+#ifdef WDS
+ if (dev->base_addr == 0)
+ {
+#ifdef BR_SHORTCUT
+ extern struct net_device *cached_wds_dev;
+ cached_wds_dev = NULL;
+#endif
+
+ netif_start_queue(dev);
+ return 0;
+ }
+#endif
+
+#ifdef CONFIG_RTK_MESH
+ if (dev->base_addr == 1) {
+ netif_start_queue(dev);
+ return 0;
+ }
+#endif // CONFIG_RTK_MESH
+
+#ifdef PCIE_POWER_SAVING
+ if((priv->pwr_state == L1) || (priv->pwr_state == L2)) {
+ PCIeWakeUp(priv, (POWER_DOWN_T0<<3));
+ }
+#endif
+
+ // stop h/w in the very beginning
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+ if ( CheckNoResetHwExceptionCase(priv) ) {
+ rtl8192cd_stop_hw(priv);
+ }
+ }
+
+#ifdef UNIVERSAL_REPEATER
+ // If vxd interface, see if some mandatory mib is set. If ok, backup these
+ // mib, and copy all mib from root interface. Then, restore the backup mib
+ // to current.
+
+ if (IS_VXD_INTERFACE(priv)) {
+ DEBUG_INFO("Open request from vxd\n");
+ if (!IS_DRV_OPEN(GET_ROOT_PRIV(priv))) {
+ printk("Open vxd error! Root interface should be opened in advanced.\n");
+ return 0;
+ }
+
+ if (!(priv->drv_state & DRV_STATE_VXD_INIT)) {
+// Mark following code. MIB copy will be executed through ioctl -------------
+#if 0
+ unsigned char tmpbuf[36];
+ int len, encyption, is_1x, mac_clone, nat25;
+ struct Dot11RsnIE rsnie;
+
+ len = SSID_LEN;
+ memcpy(tmpbuf, SSID, len);
+ encyption = priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm;
+ is_1x = IEEE8021X_FUN;
+ mac_clone = priv->pmib->ethBrExtInfo.macclone_enable;
+ nat25 = priv->pmib->ethBrExtInfo.nat25_disable;
+ memcpy((char *)&rsnie, (char *)&priv->pmib->dot11RsnIE, sizeof(rsnie));
+
+ memcpy(priv->pmib, GET_ROOT_PRIV(priv)->pmib, sizeof(struct wifi_mib));
+
+ SSID_LEN = len;
+ memcpy(SSID, tmpbuf, len);
+ SSID2SCAN_LEN = len;
+ memcpy(SSID2SCAN, SSID, len);
+ priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm = encyption;
+ IEEE8021X_FUN = is_1x;
+ priv->pmib->ethBrExtInfo.macclone_enable = mac_clone;
+ priv->pmib->ethBrExtInfo.nat25_disable = nat25;
+ memcpy((char *)&priv->pmib->dot11RsnIE, (char *)&rsnie, sizeof(rsnie));
+#ifdef WDS
+ // always disable wds in vxd
+ priv->pmib->dot11WdsInfo.wdsEnabled = 0;
+ priv->pmib->dot11WdsInfo.wdsPure = 0;
+#endif
+
+ // if root interface is AP mode, set infra-client in vxd
+ // if root interfeace is a infra-client, set AP in vxd
+ if (OPMODE & WIFI_AP_STATE) {
+ OPMODE = WIFI_STATION_STATE;
+#if defined(WIFI_WMM) && defined(WMM_APSD)
+ APSD_ENABLE = 0;
+#endif
+ DEBUG_INFO("Set vxd as an infra-client\n");
+ }
+ else if (OPMODE & WIFI_STATION_STATE) {
+ OPMODE = WIFI_AP_STATE;
+ priv->auto_channel = 0;
+ DEBUG_INFO("Set vxd as an AP\n");
+ }
+ else {
+ DEBUG_ERR("Invalid opmode for vxd!\n");
+ return 0;
+ }
+#endif
+//---------------------------------------------------------- david+2008-03-17
+
+ // correct RSN IE will be set later for WPA/WPA2
+#ifdef CHECK_HANGUP
+ if (!is_reset)
+#endif
+ memset(&priv->pmib->dot11RsnIE, 0, sizeof(struct Dot11RsnIE));
+
+#ifdef WDS
+ // always disable wds in vxd
+ priv->pmib->dot11WdsInfo.wdsEnabled = 0;
+ priv->pmib->dot11WdsInfo.wdsPure = 0;
+#endif
+
+#ifdef CONFIG_RTK_MESH
+ // always disable mesh in vxd (for dev)
+ GET_MIB(priv)->dot1180211sInfo.mesh_enable = 0;
+#endif // CONFIG_RTK_MESH
+ priv->drv_state |= DRV_STATE_VXD_INIT; // indicate the mib of vxd driver has been initialized
+ }
+ }
+#endif // UNIVERSAL_REPEATER
+
+#ifdef CHECK_HANGUP
+ if (!is_reset)
+#endif
+ {
+ if (OPMODE & WIFI_AP_STATE)
+ OPMODE = WIFI_AP_STATE;
+#ifdef CLIENT_MODE
+ else if (OPMODE & WIFI_STATION_STATE) {
+ OPMODE = WIFI_STATION_STATE;
+#if defined(WIFI_WMM) && defined(WMM_APSD)
+ APSD_ENABLE = 0;
+#endif
+ }
+ else if (OPMODE & WIFI_ADHOC_STATE) {
+ OPMODE = WIFI_ADHOC_STATE;
+#ifdef WIFI_WMM
+#ifdef WMM_APSD
+ APSD_ENABLE = 0;
+#endif
+#endif
+ }
+#endif
+ else {
+ printk("Undefined state... using AP mode as default\n");
+ OPMODE = WIFI_AP_STATE;
+ }
+ }
+
+#ifdef MBSSID
+ if (GET_ROOT(priv)->pmib->miscEntry.vap_enable)
+ {
+ if (IS_VAP_INTERFACE(priv)) {
+ if (!IS_DRV_OPEN(GET_ROOT_PRIV(priv))) {
+ printk("Open vap error! Root interface should be opened in advanced.\n");
+ return -1;
+ }
+
+ if ((GET_ROOT_PRIV(priv)->pmib->dot11OperationEntry.opmode & WIFI_AP_STATE) == 0) {
+ printk("Fail to open VAP under non-AP mode!\n");
+ return -1;
+ }
+ else {
+ rtl8192cd_init_vap_mib(priv);
+ }
+ }
+ }
+#endif
+
+#if defined(BR_SHORTCUT)
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if(IS_ROOT_INTERFACE(priv))
+#endif
+ clear_shortcut_cache();
+#endif
+
+ rc = rtl8192cd_init_sw(priv);
+ if (rc)
+ return rc;
+
+#if defined(CONFIG_RTL8196B_TR) || defined(CONFIG_RTL8196C_EC)
+ if (!priv->auto_channel) {
+ LOG_START_MSG();
+ }
+#endif
+//#ifdef CONFIG_RTL865X_AC
+#if defined(CONFIG_RTL865X_AC) || defined(CONFIG_RTL865X_KLD) || defined(CONFIG_RTL8196B_KLD) || defined(CONFIG_RTL8196C_KLD)
+ if (!priv->auto_channel) {
+ LOG_START_MSG();
+ }
+#endif
+
+ validate_fixed_tx_rate(priv);
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+#ifdef __KERNEL__
+#ifdef CHECK_HANGUP
+ if (!is_reset)
+#endif
+ {
+#if !defined(CONFIG_RTL8671)
+ #if defined(__LINUX_2_6__)
+ #if defined(CONFIG_RTL_92D_DMDP)
+ rc = request_irq(dev->irq, rtl8192cd_interrupt, IRQF_SHARED|IRQF_DISABLED, dev->name, dev);
+ #else
+ rc = request_irq(dev->irq, rtl8192cd_interrupt, IRQF_DISABLED, dev->name, dev);
+ #endif
+ #else
+ rc = request_irq(dev->irq, rtl8192cd_interrupt, SA_SHIRQ, dev->name, dev);
+ #endif
+#else
+ rc = request_irq(dev->irq, rtl8192cd_interrupt, SA_INTERRUPT, dev->name, dev);
+#endif
+
+#if defined(PCIE_POWER_SAVING) && defined(GPIO_WAKEPIN)
+ rc |= request_irq_for_wakeup_pin(dev);
+#endif
+
+ if (rc) {
+ DEBUG_ERR("some issue in request_irq, rc=%d\n", rc);
+ }
+ }
+#endif
+
+ SAVE_INT_AND_CLI(x);
+ SMP_LOCK(x);
+
+#ifdef CONFIG_RTL865X_WTDOG
+#if !(defined(CONFIG_RTL8196B) || defined(CONFIG_RTL_819X))
+ wtval = *((volatile unsigned long *)0xB800311C);
+ *((volatile unsigned long *)0xB800311C) = 0xA5f00000;
+#endif
+#endif
+
+do_hw_init:
+
+#ifdef EN_EFUSE
+ {
+ int i, readEfuse=0;
+ for(i=0;i<MAX_2G_CHANNEL_NUM;i++) {
+ if( priv->pmib->dot11RFEntry.pwrlevelCCK_A[i]==0
+ || priv->pmib->dot11RFEntry.pwrlevelHT40_1S_A[i] ==0) {
+ readEfuse = 1;
+ break;
+ }
+ }
+ if(readEfuse)
+ ReadTxPowerInfoFromHWPG(priv);
+
+ if(priv->pmib->dot11RFEntry.ther==0) {
+ ReadThermalMeterFromEfuse(priv);
+
+#ifdef CONFIG_RTL_92D_SUPPORT
+ if (GET_CHIP_VER(priv) == VERSION_8192D) {
+ ReadCrystalCalibrationFromEfuse(priv);
+ ReadDeltaValFromEfuse(priv);
+ ReadTRSWPAPEFromEfuse(priv);
+ }
+#endif
+ }
+ }
+#endif
+ rc = rtl8192cd_init_hw_PCI(priv);
+ //delay_ms(200); // TODO: need refinement, for 98 watchdog time out
+
+ // write IDR0, IDR4 here
+ {
+ unsigned long reg = 0;
+ reg = *(unsigned long *)(dev->dev_addr);
+// RTL_W32(IDR0, (cpu_to_le32(reg)));
+ RTL_W32(MACID, (cpu_to_le32(reg)));
+ reg = *(unsigned short *)((unsigned long)dev->dev_addr + 4);
+// RTL_W32(IDR4, (cpu_to_le32(reg)));
+ RTL_W16(MACID+4, (cpu_to_le16(reg)));
+#ifdef CONFIG_RTL_92D_SUPPORT
+ RTL_W32(MACID1 , RTL_R32(MACID));
+ RTL_W16(MACID1+4, RTL_R16(MACID+4));
+#endif
+ }
+
+ if (rc && ++init_hw_cnt < 5) {
+#if defined(CONFIG_RTL865X_WTDOG) || (defined(CONFIG_RTL_WTDOG) && defined(CONFIG_RTL_92D_SUPPORT))
+ if (GET_CHIP_VER(priv)==VERSION_8192D) {
+ *((volatile unsigned long *)0xB800311C) |= 1 << 23;
+ }
+#endif
+ goto do_hw_init;
+ }
+
+#if defined(CONFIG_RTL865X_WTDOG) || (defined(CONFIG_RTL_WTDOG) && defined(CONFIG_RTL_92D_SUPPORT))
+if (GET_CHIP_VER(priv)==VERSION_8192D) {
+#if !(defined(CONFIG_RTL8196B) || defined(CONFIG_RTL_819X))
+ *((volatile unsigned long *)0xB800311C) |= 1 << 23;
+ *((volatile unsigned long *)0xB800311C) = wtval;
+#endif
+}
+#endif
+
+
+
+ RESTORE_INT(x);
+ SMP_UNLOCK(x);
+
+ if (rc) {
+ DEBUG_ERR("init hw failed!\n");
+#ifdef CONFIG_RTL_92D_SUPPORT
+ if (GET_CHIP_VER(priv)==VERSION_8192D){
+ RTL_W8(RSV_MAC0_CTRL, RTL_R8(RSV_MAC0_CTRL)&(~MAC0_EN));
+ RTL_W8(RSV_MAC1_CTRL, RTL_R8(RSV_MAC1_CTRL)&(~MAC1_EN));
+ }
+#endif //CONFIG_RTL_92D_SUPPORT
+ force_stop_wlan_hw();
+#ifdef CONFIG_RTL_92D_SUPPORT
+ if (GET_CHIP_VER(priv)!=VERSION_8192D) /* do not trigger wtdog if 92D open fail */
+#endif
+ {
+#ifdef LINUX_2_6_21_
+ local_irq_disable();
+#else
+ cli();
+#endif
+#ifndef NOT_RTK_BSP
+ *(volatile unsigned long *)(0xB800311c) = 0; /* enable watchdog reset now */
+#endif
+ for(;;)
+ ;
+ }
+ return rc;
+ }
+ }
+#if 0 // defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ else {
+ if (get_rf_mimo_mode(priv) == MIMO_1T1R)
+ GET_MIB(priv)->dot11nConfigEntry.dot11nSupportedMCS &= 0x00ff;
+ }
+#endif
+
+#ifdef MBSSID
+ if ((OPMODE & WIFI_AP_STATE) && (GET_ROOT(priv)->pmib->miscEntry.vap_enable)) {
+ rtl8192cd_init_mbssid(priv);
+
+ if (IS_VAP_INTERFACE(priv)) {
+ // set BcnDmaInt & BcnOk of different VAP in IMR
+ priv->pshare->InterruptMask |= (HIMR_BCNDOK1 << (priv->vap_init_seq-1)) |
+ (HIMR_BCNDMA1 << (priv->vap_init_seq-1));
+ RTL_W32(HIMR, priv->pshare->InterruptMask);
+
+ if (GET_ROOT_PRIV(priv)->auto_channel == 0) {
+ priv->pmib->dot11RFEntry.dot11channel = GET_ROOT_PRIV(priv)->pmib->dot11RFEntry.dot11channel;
+ priv->ht_cap_len = 0; // re-construct HT IE
+
+ init_beacon(priv);
+ }
+ }
+ }
+#endif
+
+// new added to reset keep_rsnie flag
+ if (priv->pmib->dot11OperationEntry.keep_rsnie)
+ priv->pmib->dot11OperationEntry.keep_rsnie = 0;
+//------------------- david+2006-06-30
+
+ priv->drv_state |= DRV_STATE_OPEN; // set driver as has been opened, david
+
+#if defined(RESERVE_TXDESC_FOR_EACH_IF) && (defined(UNIVERSAL_REPEATER) || defined(MBSSID))
+ recalc_txdesc_limit(priv);
+#endif
+
+ //memcpy((void *)dev->dev_addr, priv->pmib->dot11OperationEntry.hwaddr, 6);
+
+ // below is for site_survey timer
+ init_timer(&priv->ss_timer);
+ priv->ss_timer.data = (unsigned long) priv;
+ priv->ss_timer.function = rtl8192cd_ss_timer;
+
+#ifdef CONFIG_RTL_COMAPI_WLTOOLS
+ init_waitqueue_head(&priv->ss_wait);
+#endif
+
+#ifdef CLIENT_MODE
+ init_timer(&priv->reauth_timer);
+ priv->reauth_timer.data = (unsigned long) priv;
+ priv->reauth_timer.function = rtl8192cd_reauth_timer;
+
+ init_timer(&priv->reassoc_timer);
+ priv->reassoc_timer.data = (unsigned long) priv;
+ priv->reassoc_timer.function = rtl8192cd_reassoc_timer;
+
+ init_timer(&priv->idle_timer);
+ priv->idle_timer.data = (unsigned long) priv;
+ priv->idle_timer.function = rtl8192cd_idle_timer;
+#ifdef DFS
+ init_timer(&priv->dfs_cntdwn_timer);
+ priv->dfs_cntdwn_timer.data = (unsigned long) priv;
+ priv->dfs_cntdwn_timer.function = rtl8192cd_dfs_cntdwn_timer;
+#endif
+#endif
+
+ priv->frag_to = 0;
+ init_timer(&priv->frag_to_filter);
+ priv->frag_to_filter.expires = jiffies + FRAG_TO;
+ priv->frag_to_filter.data = (unsigned long) priv;
+ priv->frag_to_filter.function = rtl8192cd_frag_timer;
+ mod_timer(&priv->frag_to_filter, jiffies + FRAG_TO);
+
+#ifdef DETECT_STA_EXISTANCE
+ // Added by Annie for Retry Limit Recovery Timer, 2010-08-10.
+ init_timer(&priv->pshare->rl_recover_timer);
+ priv->pshare->rl_recover_timer.data = (unsigned long) priv;
+ priv->pshare->rl_recover_timer.function = RetryLimitRecovery;
+ priv->pshare->bRLShortened = FALSE;
+#endif
+
+ priv->auth_to = AUTH_TO / HZ;
+ priv->assoc_to = ASSOC_TO / HZ;
+
+#ifdef PCIE_POWER_SAVING_DEBUG
+ priv->expire_to = 60;
+#else
+ priv->expire_to = (EXPIRETIME > 100)? (EXPIRETIME / 100) : 86400; /*10ms to 1s*/
+#endif
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+#ifdef PCIE_POWER_SAVING
+ init_timer(&priv->ps_timer);
+ priv->ps_timer.expires = jiffies + POWER_DOWN_T0;
+ priv->ps_timer.data = (unsigned long) priv;
+ priv->ps_timer.function = PCIe_power_save_timer;
+ mod_timer(&priv->ps_timer, jiffies + POWER_DOWN_T0);
+// priv->ps_ctrl = 0x11;
+#endif
+ init_timer(&priv->expire_timer);
+ priv->expire_timer.expires = jiffies + EXPIRE_TO;
+ priv->expire_timer.data = (unsigned long) priv;
+ priv->expire_timer.function = rtl8192cd_1sec_timer;
+#ifdef SW_ANT_SWITCH
+ init_timer(&priv->pshare->swAntennaSwitchTimer);
+ priv->pshare->swAntennaSwitchTimer.data = (unsigned long) priv;
+ priv->pshare->swAntennaSwitchTimer.function = dm_SW_AntennaSwitchCallback;
+#endif
+ mod_timer(&priv->expire_timer, jiffies + EXPIRE_TO);
+
+ init_timer(&priv->pshare->rc_sys_timer);
+ priv->pshare->rc_sys_timer.data = (unsigned long) priv;
+ priv->pshare->rc_sys_timer.function = reorder_ctrl_timeout;
+
+#if 0
+ init_timer(&priv->pshare->phw->tpt_timer);
+ priv->pshare->phw->tpt_timer.data = (unsigned long)priv;
+ priv->pshare->phw->tpt_timer.function = rtl8192cd_tpt_timer;
+#endif
+ }
+
+ // for MIC check
+ init_timer(&priv->MIC_check_timer);
+ priv->MIC_check_timer.data = (unsigned long) priv;
+ priv->MIC_check_timer.function = DOT11_Process_MIC_Timerup;
+ init_timer(&priv->assoc_reject_timer);
+ priv->assoc_reject_timer.data = (unsigned long) priv;
+ priv->assoc_reject_timer.function = DOT11_Process_Reject_Assoc_Timerup;
+ priv->MIC_timer_on = FALSE;
+ priv->assoc_reject_on = FALSE;
+
+#ifdef GBWC
+ init_timer(&priv->GBWC_timer);
+ priv->GBWC_timer.data = (unsigned long) priv;
+ priv->GBWC_timer.function = rtl8192cd_GBWC_timer;
+ mod_timer(&priv->GBWC_timer, jiffies + GBWC_TO);
+#endif
+
+ // to avoid add RAtid fail
+ init_timer(&priv->add_RATid_timer);
+ priv->add_RATid_timer.data = (unsigned long) priv;
+ priv->add_RATid_timer.function = add_RATid_timer;
+
+ init_timer(&priv->add_rssi_timer);
+ priv->add_rssi_timer.data = (unsigned long) priv;
+ priv->add_rssi_timer.function = add_rssi_timer;
+
+ init_timer(&priv->add_ps_timer);
+ priv->add_ps_timer.data = (unsigned long) priv;
+ priv->add_ps_timer.function = add_ps_timer;
+
+#if defined(CONFIG_RTL_92D_SUPPORT) && defined(CONFIG_RTL_NOISE_CONTROL)
+ if (GET_CHIP_VER(priv) == VERSION_8192D){
+ init_timer(&priv->dnc_timer);
+ priv->dnc_timer.data = (unsigned long) priv;
+ priv->dnc_timer.function = dnc_timer;
+ }
+#endif
+
+#ifdef SMART_CONCURRENT_92D
+ if (GET_CHIP_VER(priv) == VERSION_8192D){
+ init_timer(&priv->smcc_prb_timer);
+ priv->smcc_prb_timer.data = (unsigned long) priv;
+ priv->smcc_prb_timer.function = smcc_prb_timer;
+ }
+
+#endif
+
+#ifdef CONFIG_RTK_MESH
+ /*
+ * CAUTION !! These statement meshX(virtual interface) ONLY, Maybe modify....
+ * These statment is initial information, (If "ZERO" no need set it, because all cleared to ZERO)
+ */
+ init_timer(&priv->mesh_peer_link_timer);
+ priv->mesh_peer_link_timer.data = (unsigned long) priv;
+ priv->mesh_peer_link_timer.function = mesh_peer_link_timer;
+
+#ifdef MESH_BOOTSEQ_AUTH
+ init_timer(&priv->mesh_auth_timer);
+ priv->mesh_auth_timer.data = (unsigned long) priv;
+ priv->mesh_auth_timer.function = mesh_auth_timer;
+#endif
+
+ priv->mesh_Version = 1;
+#ifdef MESH_ESTABLISH_RSSI_THRESHOLD
+ priv->mesh_fake_mib.establish_rssi_threshold = DEFAULT_ESTABLISH_RSSI_THRESHOLD;
+#endif
+
+#ifdef MESH_USE_METRICOP
+ // in next version, the fake_mib related values will be actually recorded in MIB
+ priv->mesh_fake_mib.metricID = 1; // 0: very old version, 1: version before 2009/3/10, 2: 11s
+ priv->mesh_fake_mib.isPure11s = 0;
+ priv->mesh_fake_mib.intervalMetricAuto = RTL_SECONDS_TO_JIFFIES(60); // 1 Mins
+ priv->mesh_fake_mib.spec11kv.defPktTO = RTL_SECONDS_TO_JIFFIES(2); // 2 * 100 = 2 secs
+ priv->mesh_fake_mib.spec11kv.defPktLen = 1024; // bt=8196 bits
+ priv->mesh_fake_mib.spec11kv.defPktCnt = 2;
+ priv->mesh_fake_mib.spec11kv.defPktPri = 5;
+
+ // once driver starts up, toMeshMetricAuto will be updated
+ // (I think it might be put in "init one" to match our original concept...)
+ priv->toMeshMetricAuto = jiffies + priv->mesh_fake_mib.intervalMetricAuto;
+#endif // MESH_USE_METRICOP
+
+ mesh_set_PeerLink_CAP(priv, GET_MIB(priv)->dot1180211sInfo.mesh_max_neightbor);
+
+ priv->mesh_PeerCAP_flags = 0x80; // Bit15(Operation as MP) shall be "1"
+ priv->mesh_HeaderFlags = 0; // NO Address Extension
+
+ // The following info can be saved by FLASH in the future
+ priv->mesh_profile[0].used = TRUE;
+ priv->mesh_profile[0].PathSelectMetricID.value = 0;
+ priv->mesh_profile[0].PathSelectMetricID.OUI[0] = 0x00;
+ priv->mesh_profile[0].PathSelectMetricID.OUI[1] = 0x0f;
+ priv->mesh_profile[0].PathSelectMetricID.OUI[2] = 0xac;
+ priv->mesh_profile[0].PathSelectProtocolID.value = 0;
+ priv->mesh_profile[0].PathSelectProtocolID.OUI[0] = 0x00;
+ priv->mesh_profile[0].PathSelectProtocolID.OUI[1] = 0x0f;
+ priv->mesh_profile[0].PathSelectProtocolID.OUI[2] = 0xac;
+#endif
+
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+ // for HW/SW LED
+ if ((LED_TYPE >= LEDTYPE_HW_TX_RX) && (LED_TYPE <= LEDTYPE_HW_LINKACT_INFRA))
+ enable_hw_LED(priv, LED_TYPE);
+ else if ((LED_TYPE >= LEDTYPE_SW_LINK_TXRX) && (LED_TYPE < LEDTYPE_SW_MAX))
+ enable_sw_LED(priv, 1);
+#ifdef SW_ANT_SWITCH
+ dm_SW_AntennaSwitchInit(priv); // SW Ant Switch use LED pin to control TRX Antenna
+#endif
+#if defined(HW_ANT_SWITCH)
+ dm_HW_AntennaSwitchInit(priv);
+#endif
+
+#ifdef DFS
+ if (!priv->pmib->dot11DFSEntry.disable_DFS &&
+ (OPMODE & WIFI_AP_STATE) &&
+ (((priv->pmib->dot11RFEntry.dot11channel >= 52) &&
+ (priv->pmib->dot11RFEntry.dot11channel <= 64)) ||
+ ((priv->pmib->dot11RFEntry.dot11channel >= 100) &&
+ (priv->pmib->dot11RFEntry.dot11channel <= 140)))) {
+ init_timer(&priv->ch_avail_chk_timer);
+ priv->ch_avail_chk_timer.data = (unsigned long) priv;
+ priv->ch_avail_chk_timer.function = rtl8192cd_ch_avail_chk_timer;
+ mod_timer(&priv->ch_avail_chk_timer, jiffies + CH_AVAIL_CHK_TO);
+
+ init_timer(&priv->DFS_timer);
+ priv->DFS_timer.data = (unsigned long) priv;
+ priv->DFS_timer.function = rtl8192cd_DFS_timer;
+
+ /* DFS activated after 5 sec; prevent switching channel due to DFS false alarm */
+ mod_timer(&priv->DFS_timer, jiffies + RTL_SECONDS_TO_JIFFIES(5));
+
+ DFS_SetReg(priv);
+ }
+#endif
+
+#ifdef SUPPORT_SNMP_MIB
+ mib_init(priv);
+#endif
+
+ }
+
+#if defined(BR_SHORTCUT) && defined(CLIENT_MODE)
+ if (OPMODE & WIFI_STATION_STATE) {
+ extern struct net_device *cached_sta_dev;
+ cached_sta_dev = NULL;
+ }
+#endif
+
+#if defined(BR_SHORTCUT) && defined(RTL_CACHED_BR_STA)
+ {
+ extern unsigned char cached_br_sta_mac[MACADDRLEN];
+ extern struct net_device *cached_br_sta_dev;
+ memset(cached_br_sta_mac, 0, MACADDRLEN);
+ cached_br_sta_dev = NULL;
+ }
+#endif
+
+ //if (OPMODE & WIFI_AP_STATE) //in case of station mode, queue will start only after assoc.
+ netif_start_queue(dev); // start queue always
+
+#ifdef WDS
+ create_wds_tbl(priv);
+#endif
+
+#ifdef CHECK_HANGUP
+ if (priv->reset_hangup)
+ priv->reset_hangup = 0;
+#endif
+
+#if defined(INCLUDE_WPA_PSK) && defined(CLIENT_MODE)
+ if (OPMODE & WIFI_ADHOC_STATE)
+ if (priv->pmib->dot1180211AuthEntry.dot11EnablePSK)
+ ToDrv_SetGTK(priv);
+#endif
+
+#ifdef MBSSID
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ if ((OPMODE & WIFI_AP_STATE) && priv->auto_channel) {
+ if (((priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm != _TKIP_PRIVACY_) &&
+ (priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm != _CCMP_PRIVACY_) &&
+ (priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm != _WEP_WPA_MIXED_PRIVACY_)) ||
+ (priv->pmib->dot11RsnIE.rsnielen > 0)) {
+ priv->ss_ssidlen = 0;
+ DEBUG_INFO("start_clnt_ss, trigger by %s, ss_ssidlen=0\n", (char *)__FUNCTION__);
+ start_clnt_ss(priv);
+ }
+ }
+
+#ifdef CLIENT_MODE
+ if (OPMODE & (WIFI_STATION_STATE | WIFI_ADHOC_STATE)) {
+#ifdef RTK_BR_EXT
+ if (priv->dev->br_port) {
+#ifdef __LINUX_2_6__
+ memcpy(priv->br_mac, priv->dev->br_port->br->dev->dev_addr, MACADDRLEN);
+#else
+ memcpy(priv->br_mac, priv->dev->br_port->br->dev.dev_addr, MACADDRLEN);
+#endif
+ }
+#endif
+
+ if (!IEEE8021X_FUN || (IEEE8021X_FUN && (priv->pmib->dot11RsnIE.rsnielen > 0))) {
+#ifdef CHECK_HANGUP
+ if (!is_reset || priv->join_res == STATE_Sta_No_Bss ||
+ priv->join_res == STATE_Sta_Roaming_Scan || priv->join_res == 0)
+#endif
+ {
+#ifdef CHECK_HANGUP
+ if (is_reset)
+ OPMODE &= ~WIFI_SITE_MONITOR;
+#endif
+ start_clnt_lookup(priv, 1);
+ }
+ }
+ }
+#endif
+
+#ifdef UNIVERSAL_REPEATER
+ if (IS_ROOT_INTERFACE(priv) &&
+ netif_running(GET_VXD_PRIV(priv)->dev)) {
+ SAVE_INT_AND_CLI(x);
+ rtl8192cd_open(GET_VXD_PRIV(priv)->dev);
+ RESTORE_INT(x);
+ }
+ if (IS_VXD_INTERFACE(priv) &&
+ (GET_ROOT_PRIV(priv)->pmib->dot11OperationEntry.opmode&WIFI_STATION_STATE) &&
+ (GET_ROOT_PRIV(priv)->pmib->dot11OperationEntry.opmode&WIFI_ASOC_STATE) &&
+#ifdef RTK_BR_EXT
+ !(GET_ROOT_PRIV(priv)->pmib->ethBrExtInfo.macclone_enable && !priv->macclone_completed) &&
+#endif
+ !(priv->drv_state & DRV_STATE_VXD_AP_STARTED) )
+ enable_vxd_ap(priv);
+#endif
+
+#ifdef MBSSID
+ if (IS_ROOT_INTERFACE(priv)) {
+ if (priv->pmib->miscEntry.vap_enable) {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++) {
+ if (netif_running(priv->pvap_priv[i]->dev))
+ rtl8192cd_open(priv->pvap_priv[i]->dev);
+ }
+ }
+ }
+#endif
+
+#ifdef PCIE_POWER_SAVING
+#ifdef CHECK_HANGUP
+ if(!is_reset)
+#endif
+#ifdef MBSSID
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+#ifdef CONFIG_RTL_8198
+ if (1)
+#else
+ if (REG32(REVR) == RTL8196C_REVISION_B)
+#endif
+ init_pcie_power_saving(priv);
+ else
+ priv->pshare->rf_ft_var.power_save = 0;
+ }
+#endif
+
+ DBFEXIT;
+ return 0;
+}
+
+
+int rtl8192cd_set_hwaddr(struct net_device *dev, void *addr)
+{
+ unsigned long flags;
+#ifdef NETDEV_NO_PRIV
+ struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv;
+#else
+ struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv;
+#endif
+ unsigned long reg;
+ unsigned char *p;
+#ifdef WDS
+ int i;
+#endif
+
+#ifdef __KERNEL__
+ p = ((struct sockaddr *)addr)->sa_data;
+#else
+ p = (unsigned char *)addr;
+#endif
+
+ SAVE_INT_AND_CLI(flags);
+ SMP_LOCK(flags);
+
+ memcpy(priv->dev->dev_addr, p, 6);
+ memcpy(GET_MY_HWADDR, p, 6);
+
+#ifdef MBSSID
+ if (GET_ROOT(priv)->pmib->miscEntry.vap_enable)
+ {
+ if (IS_VAP_INTERFACE(priv)) {
+ RESTORE_INT(flags);
+ SMP_UNLOCK(flags);
+ return 0;
+ }
+ }
+#endif
+
+#ifdef WDS
+ for (i=0; i<NUM_WDS; i++)
+ if (priv->wds_dev[i])
+ memcpy(priv->wds_dev[i]->dev_addr, p, 6);
+#endif
+#ifdef CONFIG_RTK_MESH
+ if(NUM_MESH>0)
+ if (priv->mesh_dev)
+ memcpy(priv->mesh_dev->dev_addr, p, 6);
+#endif
+
+#ifdef UNIVERSAL_REPEATER
+ if (IS_ROOT_INTERFACE(priv)) {
+ if (GET_VXD_PRIV(priv)) {
+ memcpy(GET_VXD_PRIV(priv)->dev->dev_addr, p, 6);
+ memcpy(GET_VXD_PRIV(priv)->pmib->dot11OperationEntry.hwaddr, p, 6);
+ }
+ }
+ else if (IS_VXD_INTERFACE(priv)) {
+ memcpy(GET_ROOT_PRIV(priv)->dev->dev_addr, p, 6);
+ memcpy(GET_ROOT_PRIV(priv)->pmib->dot11OperationEntry.hwaddr, p, 6);
+ }
+#endif
+ reg = *(unsigned long *)(dev->dev_addr);
+ RTL_W32(MACID, (cpu_to_le32(reg)));
+ reg = *(unsigned short *)((unsigned long)dev->dev_addr + 4);
+ RTL_W16(MACID+4, (cpu_to_le16(reg)));
+#ifdef CONFIG_RTL_92D_SUPPORT
+ RTL_W32(MACID1 , RTL_R32(MACID));
+ RTL_W16(MACID1+4, RTL_R16(MACID+4));
+#endif
+
+#ifdef MBSSID
+ if (GET_ROOT(priv)->pmib->miscEntry.vap_enable)
+ {
+ if (OPMODE & WIFI_AP_STATE)
+ rtl8192cd_init_mbssid(priv);
+ }
+#endif
+
+ RESTORE_INT(flags);
+ SMP_UNLOCK(flags);
+
+#ifdef CLIENT_MODE
+ if (!(OPMODE & WIFI_AP_STATE) && netif_running(priv->dev)) {
+ int link_status = chklink_wkstaQ(priv);
+ if (link_status)
+ start_clnt_join(priv);
+ }
+#endif
+
+ return 0;
+}
+
+
+int rtl8192cd_close(struct net_device *dev)
+{
+#ifdef NETDEV_NO_PRIV
+ struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv;
+#else
+ struct rtl8192cd_priv *priv = dev->priv;
+#endif
+#ifdef UNIVERSAL_REPEATER
+ struct rtl8192cd_priv *priv_vxd;
+#endif
+
+ unsigned long flags;
+
+ DBFENTER;
+
+ if (!(priv->drv_state & DRV_STATE_OPEN)
+#ifdef WDS
+ && dev->base_addr
+#endif
+) {
+ DBFEXIT;
+ return 0;
+ }
+
+ SAVE_INT_AND_CLI(flags);
+ SMP_LOCK(flags);
+
+#ifdef WDS
+ if(dev->base_addr)
+#endif
+ priv->drv_state &= ~DRV_STATE_OPEN; // set driver as has been closed, david
+
+#ifdef PCIE_POWER_SAVING
+ if((priv->pwr_state == L1) || (priv->pwr_state == L2)) {
+ PCIeWakeUp(priv, (POWER_DOWN_T0<<3));
+ }
+#endif
+
+#if defined(RESERVE_TXDESC_FOR_EACH_IF) && (defined(UNIVERSAL_REPEATER) || defined(MBSSID))
+ recalc_txdesc_limit(priv);
+#endif
+
+#ifdef UNIVERSAL_REPEATER
+ if (IS_ROOT_INTERFACE(priv)) {
+ priv_vxd = GET_VXD_PRIV(priv);
+
+ // if vxd interface is opened, close it first
+ if (IS_DRV_OPEN(priv_vxd))
+ rtl8192cd_close(priv_vxd->dev);
+ }
+ else {
+#ifdef MBSSID
+/*
+ if (GET_ROOT(priv)->pmib->miscEntry.vap_enable)
+*/
+ if (priv->vap_id < 0)
+#endif
+ disable_vxd_ap(priv);
+ }
+#endif
+
+ netif_stop_queue(dev);
+
+#ifdef WDS
+ if (dev->base_addr == 0)
+ {
+ RESTORE_INT(flags);
+ SMP_UNLOCK(flags);
+ DBFEXIT;
+ return 0;
+ }
+#endif
+
+#ifdef CONFIG_RTK_MESH
+ if (dev->base_addr == 1)
+ {
+ RESTORE_INT(flags);
+ SMP_UNLOCK(flags);
+ return 0;
+ }
+#endif // CONFIG_RTK_MESH
+
+#ifdef CHECK_HANGUP
+ if (!priv->reset_hangup)
+#endif
+ if (OPMODE & WIFI_AP_STATE) {
+ int i;
+ for(i=0; i<NUM_STAT; i++)
+ {
+ if (priv->pshare->aidarray[i] && (priv->pshare->aidarray[i]->used == TRUE)
+#ifdef WDS
+ && !(priv->pshare->aidarray[i]->station.state & WIFI_WDS)
+#endif
+ ) {
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (priv != priv->pshare->aidarray[i]->priv)
+ continue;
+#endif
+ issue_deauth(priv, priv->pshare->aidarray[i]->station.hwaddr, _RSON_DEAUTH_STA_LEAVING_);
+ }
+ }
+
+ delay_ms(10);
+ }
+#ifdef CLIENT_MODE /* WPS2DOTX */
+ else if((OPMODE & (WIFI_STATION_STATE|WIFI_AUTH_SUCCESS|WIFI_ASOC_STATE))==(WIFI_STATION_STATE|WIFI_AUTH_SUCCESS|WIFI_ASOC_STATE)){
+ //printMac(BSSID);
+ issue_disassoc(priv,BSSID,_RSON_DEAUTH_STA_LEAVING_);
+ delay_ms(30);//make sure before issue_disassoc then TX be close
+ OPMODE &= ~(WIFI_AUTH_SUCCESS|WIFI_ASOC_STATE) ;
+ }
+#endif /* WPS2DOTX */
+
+#ifdef MBSSID
+ if (IS_ROOT_INTERFACE(priv)) {
+ int i;
+ if (priv->pmib->miscEntry.vap_enable) {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++) {
+ if (IS_DRV_OPEN(priv->pvap_priv[i]))
+ rtl8192cd_close(priv->pvap_priv[i]->dev);
+ }
+ }
+ }
+
+ if (GET_ROOT(priv)->pmib->miscEntry.vap_enable)
+ rtl8192cd_stop_mbssid(priv);
+#endif
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+#ifdef RTK_QUE
+ free_rtk_queue(priv, &priv->pshare->skb_queue);
+#else
+ free_skb_queue(priv, &priv->pshare->skb_queue);
+#endif
+
+ rtl8192cd_stop_hw(priv);
+
+#ifdef __KERNEL__
+#ifdef CHECK_HANGUP
+ if (!priv->reset_hangup)
+#endif
+ {
+ free_irq(dev->irq, dev);
+#ifdef PCIE_POWER_SAVING
+#ifdef GPIO_WAKEPIN
+#ifdef CONFIG_RTL_8198
+ REG32(0xb8003000) &= ~ BIT(16); // GIMR
+#else
+ if (REG32(REVR) == RTL8196C_REVISION_B)
+ REG32(0xb8003000) &= ~ BIT(9); // GIMR
+#endif
+#if defined(__LINUX_2_6__)
+ free_irq(BSP_GPIO_ABCD_IRQ, dev);
+#else
+ free_irq(1, dev);
+#endif
+#endif
+#endif
+ }
+#endif
+
+
+
+#ifdef UNIVERSAL_REPEATER
+ GET_VXD_PRIV(priv)->drv_state &= ~DRV_STATE_VXD_INIT;
+#endif
+ }
+
+ rtl8192cd_stop_sw(priv);
+
+#ifdef ENABLE_RTL_SKB_STATS
+ DEBUG_INFO("skb_tx_cnt =%d\n", rtl_atomic_read(&priv->rtl_tx_skb_cnt));
+ DEBUG_INFO("skb_rx_cnt =%d\n", rtl_atomic_read(&priv->rtl_rx_skb_cnt));
+#endif
+
+#if defined(CONFIG_RTL_92D_DMDP) && defined(CHECK_HANGUP)
+#ifdef MBSSID
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ if ((GET_CHIP_VER(priv) == VERSION_8192D)
+ && (priv->pshare->rf_ft_var.peerReinit)
+ && (priv->pmib->dot11RFEntry.macPhyMode == DUALMAC_DUALPHY))
+ reset_dmdp_peer(priv);
+#endif
+
+ RESTORE_INT(flags);
+ SMP_UNLOCK(flags);
+
+
+#if 0
+//#ifdef PCIE_POWER_SAVING
+ if(!IS_UMC_A_CUT_88C(priv))
+#ifdef CHECK_HANGUP
+ if (!priv->reset_hangup)
+#endif
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ HostPCIe_Close();
+#endif
+
+ DBFEXIT;
+ return 0;
+}
+
+
+#ifdef CONFIG_RTL_KERNEL_MIPS16_WLAN
+__NOMIPS16
+#endif
+static void MDL_DEVINIT set_mib_default(struct rtl8192cd_priv *priv)
+{
+ unsigned char *p;
+#ifdef __KERNEL__
+ struct sockaddr addr;
+ p = addr.sa_data;
+#else
+ unsigned char tmpbuf[10];
+ p = (unsigned char *)tmpbuf;
+#endif
+
+ priv->pmib->mib_version = MIB_VERSION;
+ set_mib_default_tbl(priv);
+
+ // others that are not types of byte and int
+ strcpy((char *)priv->pmib->dot11StationConfigEntry.dot11DesiredSSID, "RTL8186-default");
+ priv->pmib->dot11StationConfigEntry.dot11DesiredSSIDLen = strlen("RTL8186-default");
+ memcpy(p, "\x00\xe0\x4c\x81\x86\x86", MACADDRLEN);
+
+#ifdef DOT11D
+ // set countryCode for 11d
+ strcpy(priv->pmib->dot11dCountry.dot11CountryString, "US");
+#endif
+
+#ifdef __KERNEL__
+ rtl8192cd_set_hwaddr(priv->dev, (void *)&addr);
+#else
+ rtl8192cd_set_hwaddr(priv->dev, (void *)p);
+#endif
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ {
+#ifdef DFS
+ init_timer(&priv->ch52_timer);
+ priv->ch52_timer.data = (unsigned long) priv;
+ priv->ch52_timer.function = rtl8192cd_ch52_timer;
+
+ init_timer(&priv->ch56_timer);
+ priv->ch56_timer.data = (unsigned long) priv;
+ priv->ch56_timer.function = rtl8192cd_ch56_timer;
+
+ init_timer(&priv->ch60_timer);
+ priv->ch60_timer.data = (unsigned long) priv;
+ priv->ch60_timer.function = rtl8192cd_ch60_timer;
+
+ init_timer(&priv->ch64_timer);
+ priv->ch64_timer.data = (unsigned long) priv;
+ priv->ch64_timer.function = rtl8192cd_ch64_timer;
+
+ init_timer(&priv->ch100_timer);
+ priv->ch100_timer.data = (unsigned long) priv;
+ priv->ch100_timer.function = rtl8192cd_ch100_timer;
+
+ init_timer(&priv->ch104_timer);
+ priv->ch104_timer.data = (unsigned long) priv;
+ priv->ch104_timer.function = rtl8192cd_ch104_timer;
+
+ init_timer(&priv->ch108_timer);
+ priv->ch108_timer.data = (unsigned long) priv;
+ priv->ch108_timer.function = rtl8192cd_ch108_timer;
+
+ init_timer(&priv->ch112_timer);
+ priv->ch112_timer.data = (unsigned long) priv;
+ priv->ch112_timer.function = rtl8192cd_ch112_timer;
+
+ init_timer(&priv->ch116_timer);
+ priv->ch116_timer.data = (unsigned long) priv;
+ priv->ch116_timer.function = rtl8192cd_ch116_timer;
+
+ init_timer(&priv->ch120_timer);
+ priv->ch120_timer.data = (unsigned long) priv;
+ priv->ch120_timer.function = rtl8192cd_ch120_timer;
+
+ init_timer(&priv->ch124_timer);
+ priv->ch124_timer.data = (unsigned long) priv;
+ priv->ch124_timer.function = rtl8192cd_ch124_timer;
+
+ init_timer(&priv->ch128_timer);
+ priv->ch128_timer.data = (unsigned long) priv;
+ priv->ch128_timer.function = rtl8192cd_ch128_timer;
+
+ init_timer(&priv->ch132_timer);
+ priv->ch132_timer.data = (unsigned long) priv;
+ priv->ch132_timer.function = rtl8192cd_ch132_timer;
+
+ init_timer(&priv->ch136_timer);
+ priv->ch136_timer.data = (unsigned long) priv;
+ priv->ch136_timer.function = rtl8192cd_ch136_timer;
+
+ init_timer(&priv->ch140_timer);
+ priv->ch140_timer.data = (unsigned long) priv;
+ priv->ch140_timer.function = rtl8192cd_ch140_timer;
+#endif
+
+ if (((priv->pshare->type>>TYPE_SHIFT) & TYPE_MASK) == TYPE_EMBEDDED) {
+ // not implement yet
+ } else {
+#ifdef IO_MAPPING
+ priv->pshare->io_mapping = 1;
+#endif
+ }
+ }
+}
+
+#if defined(__LINUX_2_6__) && !defined(CONFIG_COMPAT_NET_DEV_OPS)
+static const struct net_device_ops rtl8192cd_netdev_ops = {
+ .ndo_open = rtl8192cd_open,
+ .ndo_stop = rtl8192cd_close,
+ .ndo_set_mac_address = rtl8192cd_set_hwaddr,
+ .ndo_set_multicast_list = rtl8192cd_set_rx_mode,
+ .ndo_get_stats = rtl8192cd_get_stats,
+ .ndo_do_ioctl = rtl8192cd_ioctl,
+ .ndo_start_xmit = rtl8192cd_start_xmit,
+};
+#endif
+
+
+#ifdef CONFIG_RTL_KERNEL_MIPS16_WLAN
+__NOMIPS16
+#endif
+static int MDL_DEVINIT rtl8192cd_init_one(struct pci_dev *pdev,
+ const struct pci_device_id *ent, struct _device_info_ *wdev, int vap_idx)
+{
+#if defined(NOT_RTK_BSP)
+ unsigned long page_align_phy=0;
+#endif
+ struct net_device *dev;
+ struct rtl8192cd_priv *priv;
+ void *regs;
+ struct wifi_mib *pmib;
+ DOT11_QUEUE *pevent_queue;
+#ifdef CONFIG_RTL_WAPI_SUPPORT
+ DOT11_QUEUE *wapiEvent_queue;
+ #if defined(MBSSID)
+ DOT11_QUEUE *wapiVapEvent_queue;
+ #endif
+
+#endif
+ struct rtl8192cd_hw *phw;
+ struct rtl8192cd_tx_desc_info *ptxdesc;
+ struct wlan_hdr_poll *pwlan_hdr_poll;
+ struct wlanllc_hdr_poll *pwlanllc_hdr_poll;
+ struct wlanbuf_poll *pwlanbuf_poll;
+ struct wlanicv_poll *pwlanicv_poll;
+ struct wlanmic_poll *pwlanmic_poll;
+ struct wlan_acl_poll *pwlan_acl_poll;
+ DOT11_EAP_PACKET *Eap_packet;
+#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD)
+ WPA_GLOBAL_INFO *wpa_global_info;
+#endif
+#ifdef CONFIG_RTK_MESH
+#ifdef _MESH_ACL_ENABLE_
+ struct mesh_acl_poll *pmesh_acl_poll = NULL;
+#endif
+#ifdef _11s_TEST_MODE_
+ struct Galileo_poll *pgalileo_poll = NULL;
+#endif
+#ifndef WDS
+ char baseDevName[8];
+#endif
+ int mesh_num;
+
+ struct hash_table *proxy_table;
+#ifdef PU_STANDARD
+ //pepsi
+ struct hash_table *proxyupdate_table;
+#endif
+ struct mpp_tb *pann_mpp_tb;
+ struct hash_table *mesh_rreq_retry_queue;
+ // add by chuangch 2007.09.13
+ struct hash_table *pathsel_table;
+
+ DOT11_QUEUE2 *pathsel_queue ;
+#ifdef _11s_TEST_MODE_
+ DOT11_QUEUE2 *receiver_queue = NULL;
+#endif
+#endif // CONFIG_RTK_MESH
+
+
+
+#ifdef CONFIG_NET_PCI
+ u8 cache_size;
+ u16 pci_command;
+#ifndef USE_IO_OPS
+ u32 pciaddr;
+#endif
+ u32 pmem_len;
+#endif
+
+#ifdef WDS
+ int wds_num;
+ char baseDevName[8];
+#endif
+#if defined(CONFIG_RTK_MESH) || defined(WDS)
+ int i;
+#endif
+
+ unsigned char *page_ptr;
+ struct priv_shared_info *pshare; // david
+
+ int rc=0;
+
+ priv = NULL;
+ regs = NULL;
+ pmib = NULL;
+ pevent_queue = NULL;
+#ifdef CONFIG_RTL_WAPI_SUPPORT
+ wapiEvent_queue = NULL;
+ #if defined(MBSSID)
+ wapiVapEvent_queue = NULL;
+ #endif
+
+#endif
+ phw = NULL;
+ ptxdesc = NULL;
+ pwlan_hdr_poll = NULL;
+ pwlanllc_hdr_poll = NULL;
+ pwlanbuf_poll = NULL;
+ pwlanicv_poll = NULL;
+ pwlanmic_poll = NULL;
+ pwlan_acl_poll = NULL;
+ Eap_packet = NULL;
+#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD)
+ wpa_global_info = NULL;
+#endif
+
+
+
+
+#ifdef CONFIG_NET_PCI
+ cache_size=0;
+#ifndef USE_IO_OPS
+ pciaddr=0;
+#endif
+ pmem_len=0;
+#endif
+
+
+ pshare = NULL; // david
+
+ printk("=====>>INSIDE rtl8192cd_init_one <<=====\n");
+ dev = alloc_etherdev(sizeof(struct rtl8192cd_priv));
+ if (!dev) {
+ printk(KERN_ERR "alloc_etherdev() error!\n");
+ return -ENOMEM;
+ }
+
+ // now, allocating memory for pmib
+#ifdef RTL8192CD_VARIABLE_USED_DMEM
+ pmib = (struct wifi_mib *)rtl8192cd_dmem_alloc(PMIB, NULL);
+#else
+ pmib = (struct wifi_mib *)kmalloc((sizeof(struct wifi_mib)), GFP_ATOMIC);
+#endif
+ if (!pmib) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for wifi_mib (size %d)\n", sizeof(struct wifi_mib));
+ goto err_out_free;
+ }
+ memset(pmib, 0, sizeof(struct wifi_mib));
+
+ pevent_queue = (DOT11_QUEUE *)kmalloc((sizeof(DOT11_QUEUE)), GFP_ATOMIC);
+ if (!pevent_queue) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for DOT11_QUEUE (size %d)\n", sizeof(DOT11_QUEUE));
+ goto err_out_free;
+ }
+ memset((void *)pevent_queue, 0, sizeof(DOT11_QUEUE));
+#ifdef CONFIG_RTL_WAPI_SUPPORT
+ wapiEvent_queue = (DOT11_QUEUE *)kmalloc((sizeof(DOT11_QUEUE)), GFP_ATOMIC);
+ if (!wapiEvent_queue) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for DOT11_QUEUE (size %d)\n", sizeof(DOT11_QUEUE));
+ goto err_out_free;
+ }
+ memset((void *)wapiEvent_queue, 0, sizeof(DOT11_QUEUE));
+#ifdef MBSSID
+ wapiVapEvent_queue = (DOT11_QUEUE *)kmalloc((sizeof(DOT11_QUEUE)*RTL8192CD_NUM_VWLAN), GFP_ATOMIC);
+ if (!wapiVapEvent_queue) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for DOT11_QUEUE (size %d)\n", sizeof(DOT11_QUEUE)*RTL8192CD_NUM_VWLAN);
+ goto err_out_free;
+ }
+ memset((void *)wapiVapEvent_queue, 0, sizeof(DOT11_QUEUE)*RTL8192CD_NUM_VWLAN);
+ #endif
+
+#endif
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (wdev->priv == NULL) // root interface
+#endif
+ {
+#ifdef PRIV_STA_BUF
+#ifdef CONCURRENT_MODE
+ phw = &hw_info[wlandev_idx];
+#else
+ phw = &hw_info;
+#endif
+#else
+ phw = (struct rtl8192cd_hw *)kmalloc((sizeof(struct rtl8192cd_hw)), GFP_ATOMIC);
+ if (!phw) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for rtl8192cd_hw (size %d)\n", sizeof(struct rtl8192cd_hw));
+ goto err_out_free;
+ }
+#endif
+ memset((void *)phw, 0, sizeof(struct rtl8192cd_hw));
+ ptxdesc = &phw->tx_info;
+
+#ifdef PRIV_STA_BUF
+#ifdef CONCURRENT_MODE
+ pshare = &shared_info[wlandev_idx];
+#else
+ pshare = &shared_info;
+#endif
+#else
+ pshare = (struct priv_shared_info *)kmalloc(sizeof(struct priv_shared_info), GFP_ATOMIC);
+ if (!pshare) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for priv_shared_info (size %d)\n", sizeof(struct priv_shared_info));
+ goto err_out_free;
+ }
+#endif
+ memset((void *)pshare, 0, sizeof(struct priv_shared_info));
+
+#ifdef PRIV_STA_BUF
+#ifdef CONCURRENT_MODE
+ pwlan_hdr_poll = &hdr_pool[wlandev_idx];
+#else
+ pwlan_hdr_poll = &hdr_pool;
+#endif
+#else
+ pwlan_hdr_poll = (struct wlan_hdr_poll *)
+ kmalloc((sizeof(struct wlan_hdr_poll)), GFP_ATOMIC);
+ if (!pwlan_hdr_poll) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for wlan_hdr_poll (size %d)\n", sizeof(struct wlan_hdr_poll));
+ goto err_out_free;
+ }
+#endif
+
+#ifdef PRIV_STA_BUF
+#ifdef CONCURRENT_MODE
+ pwlanllc_hdr_poll = &llc_pool[wlandev_idx];
+#else
+ pwlanllc_hdr_poll = &llc_pool;
+#endif
+#else
+ pwlanllc_hdr_poll = (struct wlanllc_hdr_poll *)
+ kmalloc((sizeof(struct wlanllc_hdr_poll)), GFP_ATOMIC);
+ if (!pwlanllc_hdr_poll) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for wlanllc_hdr_poll (size %d)\n", sizeof(struct wlanllc_hdr_poll));
+ goto err_out_free;
+ }
+#endif
+
+#ifdef PRIV_STA_BUF
+#ifdef CONCURRENT_MODE
+ pwlanbuf_poll = &buf_pool[wlandev_idx];
+#else
+ pwlanbuf_poll = &buf_pool;
+#endif
+#else
+ pwlanbuf_poll = (struct wlanbuf_poll *)
+ kmalloc((sizeof(struct wlanbuf_poll)), GFP_ATOMIC);
+ if (!pwlanbuf_poll) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for wlanbuf_poll (size %d)\n", sizeof(struct wlanbuf_poll));
+ goto err_out_free;
+ }
+#endif
+
+#ifdef PRIV_STA_BUF
+#ifdef CONCURRENT_MODE
+ pwlanicv_poll = &icv_pool[wlandev_idx];
+#else
+ pwlanicv_poll = &icv_pool;
+#endif
+#else
+ pwlanicv_poll = (struct wlanicv_poll *)
+ kmalloc((sizeof(struct wlanicv_poll)), GFP_ATOMIC);
+ if (!pwlanicv_poll) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for wlanicv_poll (size %d)\n", sizeof(struct wlanicv_poll));
+ goto err_out_free;
+ }
+#endif
+
+#ifdef PRIV_STA_BUF
+#ifdef CONCURRENT_MODE
+ pwlanmic_poll = &mic_pool[wlandev_idx];
+ wlandev_idx++;
+#else
+ pwlanmic_poll = &mic_pool;
+#endif
+#else
+ pwlanmic_poll = (struct wlanmic_poll *)
+ kmalloc((sizeof(struct wlanmic_poll)), GFP_ATOMIC);
+ if (!pwlanmic_poll) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for wlanmic_poll (size %d)\n", sizeof(struct wlanmic_poll));
+ goto err_out_free;
+ }
+#endif
+ }
+
+ pwlan_acl_poll = (struct wlan_acl_poll *)
+ kmalloc((sizeof(struct wlan_acl_poll)), GFP_ATOMIC);
+ if (!pwlan_acl_poll) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for wlan_acl_poll (size %d)\n", sizeof(struct wlan_acl_poll));
+ goto err_out_free;
+ }
+
+#if defined(CONFIG_RTK_MESH) && defined(_MESH_ACL_ENABLE_) // below code copy above ACL code
+ pmesh_acl_poll = (struct mesh_acl_poll *)
+ kmalloc((sizeof(struct mesh_acl_poll)), GFP_ATOMIC);
+ if (!pmesh_acl_poll) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for Mesh wlan_acl_poll (size %d)\n", sizeof(struct mesh_acl_poll));
+ goto err_out_free;
+ }
+#endif
+
+ Eap_packet = (DOT11_EAP_PACKET *)
+ kmalloc((sizeof(DOT11_EAP_PACKET)), GFP_ATOMIC);
+ if (!Eap_packet) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for Eap_packet (size %d)\n", sizeof(DOT11_EAP_PACKET));
+ goto err_out_free;
+ }
+ memset((void *)Eap_packet, 0, sizeof(DOT11_EAP_PACKET));
+
+#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD)
+ wpa_global_info = (WPA_GLOBAL_INFO *)
+ kmalloc((sizeof(WPA_GLOBAL_INFO)), GFP_ATOMIC);
+ if (!wpa_global_info) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for wpa_global_info (size %d)\n", sizeof(WPA_GLOBAL_INFO));
+ goto err_out_free;
+ }
+ memset((void *)wpa_global_info, 0, sizeof(WPA_GLOBAL_INFO));
+#endif
+
+#ifndef __DRAYTEK_OS__
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (wdev->priv) {
+#ifdef UNIVERSAL_REPEATER
+ if (vap_idx < 0)
+ sprintf(dev->name, "%s-vxd", wdev->priv->dev->name);
+#endif
+#ifdef MBSSID
+ if (vap_idx >= 0)
+#ifdef CONFIG_RTL8672
+ sprintf(dev->name, "%s-vap%d", wdev->priv->dev->name, vap_idx);
+#else
+ sprintf(dev->name, "%s-va%d", wdev->priv->dev->name, vap_idx);
+#endif
+#endif
+ }
+ else
+#endif
+ strcpy(dev->name, "wlan%d");
+#endif
+
+#ifdef LINUX_2_6_24_
+ /*SET_MODULE_OWNER is obsolete from 2.6.24*/
+#else
+ SET_MODULE_OWNER(dev);
+#endif
+
+#ifdef NETDEV_NO_PRIV
+ priv = (struct rtl8192cd_priv *)netdev_priv(dev);
+ priv->wlan_priv = priv;
+#else
+ priv = dev->priv;
+#endif
+
+ priv->pmib = pmib;
+#if 0/*defined(CONFIG_RTL_WAPI_SUPPORT)*/
+ /* only for test */
+ priv->pmib->wapiInfo.wapiType = wapiDisable;
+ priv->pmib->wapiInfo.wapiUpdateMCastKeyType = wapi_disable_update;
+ priv->pmib->wapiInfo.wapiUpdateUCastKeyTimeout = WAPI_KEY_UPDATE_PERIOD;
+ priv->pmib->wapiInfo.wapiUpdateUCastKeyPktNum = WAPI_KEY_UPDATE_PKTCNT;
+#endif
+ priv->pevent_queue = pevent_queue;
+#ifdef CONFIG_RTL_WAPI_SUPPORT
+ priv->wapiEvent_queue= wapiEvent_queue;
+#endif
+ priv->pwlan_acl_poll = pwlan_acl_poll;
+ priv->Eap_packet = Eap_packet;
+#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD)
+ priv->wpa_global_info = wpa_global_info;
+#endif
+#ifdef MBSSID
+ priv->vap_id = -1;
+#endif
+#if defined(CONFIG_RTK_MESH) && defined(_MESH_ACL_ENABLE_) // below code copy above ACL code
+ priv->pmesh_acl_poll = pmesh_acl_poll;
+#endif
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (wdev->priv) {
+ priv->pshare = wdev->priv->pshare;
+ GET_ROOT_PRIV(priv) = wdev->priv;
+#ifdef UNIVERSAL_REPEATER
+ if (vap_idx < 0) // create for vxd
+ GET_VXD_PRIV(wdev->priv) = priv;
+#endif
+#ifdef MBSSID
+ if (vap_idx >= 0) { // create for vap
+ GET_ROOT_PRIV(priv)->pvap_priv[vap_idx] = priv;
+ priv->vap_id = vap_idx;
+ priv->vap_init_seq = -1;
+
+ #if 0 /*defined(CONFIG_RTL_WAPI_SUPPORT)*/
+ priv->pmib->wapiInfo.wapiType = wapiDisable;
+ priv->pmib->wapiInfo.wapiUpdateMCastKeyType = wapi_disable_update;
+ priv->pmib->wapiInfo.wapiUpdateUCastKeyTimeout = WAPI_KEY_UPDATE_PERIOD;
+ priv->pmib->wapiInfo.wapiUpdateUCastKeyPktNum = WAPI_KEY_UPDATE_PKTCNT;
+ priv->wapiEvent_queue= &wapiVapEvent_queue[vap_idx];
+ printk("dev[%s]:wapiType[%d] UCastKeyType[%d] psk[%s] len[%d]\n",
+ priv->dev->name, priv->pmib->wapiInfo.wapiType,
+ priv->pmib->wapiInfo.wapiUpdateMCastKeyType,
+ priv->pmib->wapiInfo.wapiPsk.octet,
+ priv->pmib->wapiInfo.wapiPsk.len);
+ #endif
+
+
+ }
+#endif
+ }
+ else
+#endif
+ {
+ priv->pshare = pshare; // david
+ priv->pshare->phw = phw;
+#ifdef CONCURRENT_MODE
+ priv->pshare->wlandev_idx = wlan_index;
+#endif
+ priv->pshare->pdesc_info = ptxdesc;
+ priv->pshare->pwlan_hdr_poll = pwlan_hdr_poll;
+ priv->pshare->pwlanllc_hdr_poll = pwlanllc_hdr_poll;
+ priv->pshare->pwlanbuf_poll = pwlanbuf_poll;
+ priv->pshare->pwlanicv_poll = pwlanicv_poll;
+ priv->pshare->pwlanmic_poll = pwlanmic_poll;
+ wdev->priv = priv;
+#ifdef __KERNEL__
+ spin_lock_init(&priv->pshare->lock);
+#endif
+
+#ifdef CONFIG_RTK_MESH
+ spin_lock_init(&priv->pshare->lock_queue);
+ spin_lock_init(&priv->pshare->lock_Rreq);
+#endif
+
+#ifdef SMP_SYNC
+ spin_lock_init(&priv->pshare->lock_xmit);
+ spin_lock_init(&priv->pshare->lock_skb);
+ spin_lock_init(&priv->pshare->lock_buf);
+#endif
+
+#ifdef CONFIG_NET_PCI
+ if (((wdev->type >> TYPE_SHIFT) & TYPE_MASK) == TYPE_PCI_BIOS)
+ priv->pshare->pdev = pdev;
+#endif
+ priv->pshare->type = wdev->type;
+#ifdef USE_RTL8186_SDK
+#if defined(CONFIG_RTL8196B) || defined(CONFIG_RTL_819X)
+ priv->pshare->have_hw_mic = 1;
+#else
+ priv->pshare->have_hw_mic = 0;
+#endif
+#else
+ priv->pshare->have_hw_mic = 0;
+#endif
+// priv->pshare->is_giga_exist = is_giga_board();
+ }
+
+ priv->dev = dev;
+#ifndef __DRAYTEK_OS__
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (GET_ROOT_PRIV(priv)) { // is a vxd or vap
+ dev->base_addr = GET_ROOT_PRIV(priv)->dev->base_addr;
+ goto register_driver;
+ }
+#endif
+#ifdef CONFIG_NET_PCI
+ if (((wdev->type >> TYPE_SHIFT) & TYPE_MASK) == TYPE_PCI_BIOS)
+ {
+ rc = pci_enable_device(pdev);
+ if (rc)
+ goto err_out_free;
+#ifndef USE_IO_OPS
+ rc = pci_request_regions(pdev, DRV_NAME);
+#endif
+ if (rc)
+ goto err_out_disable;
+
+ if (pdev->irq < 2) {
+ rc = -EIO;
+#ifdef __LINUX_2_6__
+ printk(KERN_ERR "invalid irq (%d) for pci dev\n", pdev->irq);
+#else
+ printk(KERN_ERR "invalid irq (%d) for pci dev %s\n", pdev->irq, pdev->slot_name);
+#endif
+ goto err_out_res;
+ }
+#ifdef USE_IO_OPS
+ {
+ unsigned long pio_start, pio_len, pio_flags;
+
+ pio_start = (unsigned long)pci_resource_start(pdev, 0);
+ pio_len = (unsigned long)pci_resource_len(pdev, 0);
+ pio_flags = (unsigned long)pci_resource_flags(pdev, 0);
+//// pio_start = (unsigned long)pci_resource_start(pdev, 2);
+//// pio_len = (unsigned long)pci_resource_len(pdev, 2);
+//// pio_flags = (unsigned long)pci_resource_flags(pdev, 2);
+
+
+ if (!(pio_flags & IORESOURCE_IO)) {
+ rc = -EIO;
+#ifdef __LINUX_2_6__
+ printk(KERN_ERR "pci: region #0 not a PIO resource, aborting\n");
+#else
+ printk(KERN_ERR "%s: region #0 not a PIO resource, aborting\n", pdev->slot_name);
+#endif
+ goto err_out_res;
+ }
+
+ if (!request_region(pio_start, pio_len, DRV_NAME)) {
+ rc = -EIO;
+ printk(KERN_ERR "request_region failed!\n");
+ goto err_out_res;
+ }
+
+ if (pio_len < RTL8192CD_REGS_SIZE) {
+ rc = -EIO;
+#ifdef __LINUX_2_6__
+ printk(KERN_ERR "PIO resource (%lx) too small on pci dev\n", pio_len);
+#else
+ printk(KERN_ERR "PIO resource (%lx) too small on pci dev %s\n", pio_len, pdev->slot_name);
+#endif
+ goto err_out_res;
+ }
+
+ dev->base_addr = pio_start;
+ priv->pshare->ioaddr = pio_start; // device I/O address
+ }
+#else
+#ifdef IO_MAPPING
+ pciaddr = pci_resource_start(pdev, 0);
+//// pciaddr = pci_resource_start(pdev, 2);
+#else
+// pciaddr = pci_resource_start(pdev, 1);
+ pciaddr = pci_resource_start(pdev, 2);
+#endif
+ if (!pciaddr) {
+ rc = -EIO;
+#ifdef __LINUX_2_6__
+ printk(KERN_ERR "no MMIO resource for pci dev");
+#else
+ printk(KERN_ERR "no MMIO resource for pci dev %s\n", pdev->slot_name);
+#endif
+ goto err_out_res;
+ }
+
+// if ((pmem_len = pci_resource_len(pdev, 1)) < RTL8192CD_REGS_SIZE) {
+ if ((pmem_len = pci_resource_len(pdev, 2)) < RTL8192CD_REGS_SIZE) {
+ rc = -EIO;
+#ifdef __LINUX_2_6__
+ printk(KERN_ERR "MMIO resource () too small on pci dev\n");
+#else
+ printk(KERN_ERR "MMIO resource (%lx) too small on pci dev %s\n", (unsigned long)pmem_len, pdev->slot_name);
+#endif
+ goto err_out_res;
+ }
+
+ regs = ioremap_nocache(pciaddr, pmem_len);
+ if (!regs) {
+ rc = -EIO;
+#ifdef __LINUX_2_6__
+ printk(KERN_ERR "Cannot map PCI MMIO () on pci dev \n");
+#else
+ printk(KERN_ERR "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", (unsigned long)pmem_len, (long)pciaddr, pdev->slot_name);
+#endif
+ goto err_out_res;
+ }
+
+ dev->base_addr = (unsigned long)regs;
+ priv->pshare->ioaddr = (UINT)regs;
+ check_chipID_MIMO(priv);
+#endif // USE_IO_OPS
+#ifdef CONFIG_RTL_92D_SUPPORT
+ u32 vendor_deivce_id, config_base;
+
+ vendor_deivce_id = dev->base_addr;
+ if(dev->base_addr==0xba000000)
+ {
+ vendor_deivce_id= *((volatile unsigned long *)(0xb8b30000));
+ }
+ else if(dev->base_addr==0xb9000000)
+ {
+ vendor_deivce_id= *((volatile unsigned long *)(0xb8b10000));
+ }
+ printk(" vendor_deivce_id=%x\n", vendor_deivce_id);
+ if (vendor_deivce_id == ((unsigned long)((0x8193<<16)|PCI_VENDOR_ID_REALTEK)))
+ priv->pshare->version_id = VERSION_8192D;
+ else
+ priv->pshare->version_id =0x1234;
+#endif
+
+ }
+ else
+#endif
+ {
+ regs = (void *)wdev->base_addr;
+ dev->base_addr = (unsigned long)wdev->base_addr;
+ priv->pshare->ioaddr = (UINT)regs;
+
+ if (((priv->pshare->type>>TYPE_SHIFT) & TYPE_MASK) == TYPE_PCI_DIRECT)
+ {
+ int i ;
+#ifdef CONFIG_RTL_92D_SUPPORT
+ u32 vendor_deivce_id, config_base, base_addr;
+ config_base = wdev->conf_addr;
+ base_addr = wdev->base_addr;
+#endif
+
+ _DEBUG_INFO("INIT PCI config space directly\n");
+#if !defined(CONFIG_NET_PCI) && (defined(CONFIG_RTL8196B) || defined(CONFIG_RTL_819X))
+ #if defined(CONFIG_RTL8196C) || defined(CONFIG_RTL_8196C) || defined(CONFIG_RTL_819X)
+ if (BSP_PCIE0_D_CFG0 == wdev->conf_addr)
+ {
+ if ((PCIE_reset_procedure(0, 0, 1, wdev->conf_addr))== FAIL)
+ {
+ rc = -ENODEV;
+ goto err_out_free;
+ }
+ }
+ else if (BSP_PCIE1_D_CFG0 == wdev->conf_addr)
+ {
+ if ((PCIE_reset_procedure(1, 0, 1, wdev->conf_addr))== FAIL)
+ {
+ rc = -ENODEV;
+ goto err_out_free;
+ }
+ }
+ else
+ {
+ goto err_out_free;
+ }
+ #else
+ if (rtl8196b_pci_reset(wdev->conf_addr) == FAIL)
+ goto err_out_free;
+ #endif
+ //REG32(0xb8000040)=0xf; // port 5 support !!!!!
+#endif
+
+
+ {
+ u32 vendor_deivce_id, config_base;
+ config_base = wdev->conf_addr;
+ vendor_deivce_id = *((volatile unsigned long *)(config_base+0));
+ printk("vendor_deivce_id=%x\n", vendor_deivce_id);
+ if (
+#if defined(CONFIG_RTL_92D_SUPPORT)
+ (vendor_deivce_id != ((unsigned long)((0x8193<<16)|PCI_VENDOR_ID_REALTEK))) &&
+#endif
+ (vendor_deivce_id != ((unsigned long)((0x8191<<16)|PCI_VENDOR_ID_REALTEK))) &&
+ (vendor_deivce_id != ((unsigned long)((0x8171<<16)|PCI_VENDOR_ID_REALTEK))) &&
+ (vendor_deivce_id != ((unsigned long)((0x8178<<16)|PCI_VENDOR_ID_REALTEK))) &&
+ (vendor_deivce_id != ((unsigned long)((0x8174<<16)|PCI_VENDOR_ID_REALTEK))) &&
+ (vendor_deivce_id != ((unsigned long)((0x8176<<16)|PCI_VENDOR_ID_REALTEK))))
+ {
+ _DEBUG_ERR("vendor_deivce_id=%x not match\n", vendor_deivce_id);
+ rc = -EIO;
+ goto err_out_free;
+ }
+#ifdef CONFIG_RTL_92D_SUPPORT
+ if (vendor_deivce_id == ((unsigned long)((0x8193<<16)|PCI_VENDOR_ID_REALTEK)))
+ priv->pshare->version_id = VERSION_8192D;
+ else
+ priv->pshare->version_id = 0;
+#endif
+ }
+
+ *((volatile unsigned long *)PCI_CONFIG_BASE1) = virt_to_bus((void *)dev->base_addr);
+ //DEBUG_INFO("...config_base1 = 0x%08lx\n", *((volatile unsigned long *)PCI_CONFIG_BASE1));
+ for(i=0; i<1000000; i++);
+ *((volatile unsigned char *)PCI_CONFIG_COMMAND) = 0x07;
+ //DEBUG_INFO("...command = 0x%08lx\n", *((volatile unsigned long *)PCI_CONFIG_COMMAND));
+ for(i=0; i<1000000; i++);
+ *((volatile unsigned short *)PCI_CONFIG_LATENCY) = 0x2000;
+ for(i=0; i<1000000; i++);
+ //DEBUG_INFO("...latency = 0x%08lx\n", *((volatile unsigned long *)PCI_CONFIG_LATENCY));
+
+#if defined(CONFIG_RTL8196C_REVISION_B) || defined(CONFIG_RTL_8196C)
+ #if defined(CONFIG_NET_PCI)
+ #define REVR 0xB8000000
+ #define RTL8196C_REVISION_A 0x80000001
+ #define RTL8196C_REVISION_B 0x80000002
+ #endif
+ if (REG32(REVR) == RTL8196C_REVISION_B) {
+ REG32(0xb9000354)=0xc940; //Card PCIE PHY initial parameter for rtl8196c revision B
+ REG32(0xb9000358)=0x24;
+ for(i=0; i<1000000; i++);
+ REG32(0xb9000354)=0x4270;
+ REG32(0xb9000358)=0x25;
+ for(i=0; i<1000000; i++);
+ REG32(0xb9000354)=0x019E; //Card PCIE PHY initial parameter for rtl8196c revision B
+ REG32(0xb9000358)=0x23;
+ }
+#endif
+#if defined(CONFIG_RTL8198_REVISION_B) || defined(CONFIG_RTL_8198)
+#if !defined(CONFIG_RTL_92D_SUPPORT)
+ #if defined(CONFIG_NET_PCI)
+ #define BSP_REVR 0xB8000000
+ #define BSP_RTL8198_REVISION_A 0xC0000000
+ #define BSP_RTL8198_REVISION_B 0xC0000001
+ #endif
+ #if !defined(CONFIG_RTL_DUAL_PCIESLOT_BIWLAN)
+ if (REG32(BSP_REVR) >= BSP_RTL8198_REVISION_B) {
+ REG32(0xb9000354)=0xc940; //Card PCIE PHY initial parameter for rtl8196c revision B
+ REG32(0xb9000358)=0x24;
+ for(i=0; i<1000000; i++);
+ REG32(0xb9000354)=0x4270;
+ REG32(0xb9000358)=0x25;
+ for(i=0; i<1000000; i++);
+ REG32(0xb9000354)=0x019E; //Card PCIE PHY initial parameter for rtl8196c revision B
+ REG32(0xb9000358)=0x23;
+ }
+ #endif
+#endif
+#endif
+
+#ifndef NOT_RTK_BSP
+ REG32(0xB800311C) |= 1 << 23;
+#endif
+ check_chipID_MIMO(priv);
+ //Exception Case
+ if ( CheckNoResetHwExceptionCase(priv) ) {
+ rtl8192cd_stop_hw(priv);
+ }
+ }
+ }
+/* ==========>> maybe later
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (IS_ROOT_INTERFACE(priv))
+#endif
+ rtl8192cd_ePhyInit(priv);
+*/
+
+
+#ifdef CONFIG_NET_PCI
+ if (((wdev->type >> TYPE_SHIFT) & TYPE_MASK) == TYPE_PCI_BIOS) {
+ dev->irq = pdev->irq;
+ pci_set_drvdata(pdev, dev);
+ }
+ else
+#endif
+ {
+ dev->irq = wdev->irq;
+ }
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+register_driver:
+#endif
+
+#if !defined(__LINUX_2_6__) || defined(CONFIG_COMPAT_NET_DEV_OPS)
+ dev->open = rtl8192cd_open;
+ dev->stop = rtl8192cd_close;
+ dev->set_multicast_list = rtl8192cd_set_rx_mode;
+ dev->hard_start_xmit = rtl8192cd_start_xmit;
+ dev->get_stats = rtl8192cd_get_stats;
+ dev->do_ioctl = rtl8192cd_ioctl;
+ dev->set_mac_address = rtl8192cd_set_hwaddr;
+#else
+ dev->netdev_ops = &rtl8192cd_netdev_ops;
+#endif
+
+#ifdef CONFIG_RTL8672
+ dev->priv_flags = IFF_DOMAIN_WLAN;
+#endif
+
+ rc = register_netdev(dev);
+ if (rc)
+ goto err_out_iomap;
+
+#ifdef CONFIG_RTL8672
+ // Added by Mason Yu
+ // MBSSID Port Mapping
+ wlanDev[wlanDevNum].dev_pointer = dev;
+ wlanDev[wlanDevNum].dev_ifgrp_member = 0;
+ wlanDevNum++;
+#endif
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (GET_ROOT_PRIV(priv) == NULL) // is root interface
+#endif
+ DEBUG_INFO("Init %s, base_addr=%08x, irq=%d\n",
+ dev->name, (UINT)dev->base_addr, dev->irq);
+
+#else // __DRAYTEK_OS__
+ regs = (void *)wdev->base_addr;
+ dev->base_addr = (unsigned long)wdev->base_addr;
+ priv->pshare->ioaddr = (UINT)regs;
+
+#ifdef UNIVERSAL_REPEATER
+ if (GET_ROOT_PRIV(priv) == NULL) // is root interface
+#endif
+ DEBUG_INFO("Init %s, base_addr=%08x\n",
+ dev->name, (UINT)dev->base_addr);
+
+#endif // __DRAYTEK_OS__
+
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (GET_ROOT_PRIV(priv) == NULL) // is root interface
+#endif
+ {
+#ifdef CONFIG_NET_PCI
+ if (((wdev->type >> TYPE_SHIFT) & TYPE_MASK) == TYPE_PCI_BIOS) {
+ if (cache_size != SMP_CACHE_BYTES) {
+// printk(KERN_INFO "%s: PCI cache line size set incorrectly "
+// "(%i bytes) by BIOS/FW, ", dev->name, cache_size);
+ if (cache_size > SMP_CACHE_BYTES)
+ printk("expecting %i\n", SMP_CACHE_BYTES);
+ else {
+ printk("correcting to %i\n", SMP_CACHE_BYTES);
+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
+ SMP_CACHE_BYTES >> 2);
+ }
+ }
+
+ /* enable busmastering and memory-write-invalidate */
+ pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
+ if (!(pci_command & PCI_COMMAND_INVALIDATE)) {
+ pci_command |= PCI_COMMAND_INVALIDATE;
+ pci_write_config_word(pdev, PCI_COMMAND, pci_command);
+ }
+ pci_set_master(pdev);
+ }
+#endif
+ }
+
+
+#ifdef _INCLUDE_PROC_FS_
+#ifdef __KERNEL__
+ rtl8192cd_proc_init(dev);
+#ifdef PERF_DUMP
+ {
+ #include <linux/proc_fs.h>
+
+ struct proc_dir_entry *res;
+ res = create_proc_entry("perf_dump", 0, NULL);
+ if (res) {
+ res->read_proc = read_perf_dump;
+ res->write_proc = flush_perf_dump;
+ }
+ }
+#endif
+#endif
+#endif
+
+ // set some default value of mib
+ set_mib_default(priv);
+
+#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
+ if (GET_ROOT_PRIV(priv) == NULL) // is root interface
+#endif
+ {
+#ifndef __DRAYTEK_OS__
+#ifdef WDS
+ wds_num = (priv->pshare->type>>WDS_SHIFT) & WDS_MASK;
+ strcpy(baseDevName, dev->name);
+
+ for (i=0; i<wds_num; i++) {
+#ifdef NETDEV_NO_PRIV
+ struct rtl8192cd_wds_priv* priv_wds;
+ dev = alloc_etherdev(sizeof(struct rtl8192cd_wds_priv));
+#else
+ dev = alloc_etherdev(0);
+#endif
+ if (!dev) {
+ printk(KERN_ERR "alloc_etherdev() wds error!\n");
+ rc = -ENOMEM;
+ goto err_out_dev;
+ }
+
+#if !defined(__LINUX_2_6__) || defined(CONFIG_COMPAT_NET_DEV_OPS)
+ dev->open = rtl8192cd_open;
+ dev->stop = rtl8192cd_close;
+ dev->hard_start_xmit = rtl8192cd_start_xmit;
+ dev->get_stats = rtl8192cd_get_stats;
+ dev->set_mac_address = rtl8192cd_set_hwaddr;
+#else
+ dev->netdev_ops = &rtl8192cd_netdev_ops;
+#endif
+
+#ifdef CONFIG_RTL8672
+ dev->priv_flags = IFF_DOMAIN_WLAN;
+#endif
+
+ priv->wds_dev[i] = dev;
+ strcpy(dev->name, baseDevName);
+ strcat(dev->name, "-wds%d");
+
+#ifdef NETDEV_NO_PRIV
+ priv_wds = (struct rtl8192cd_wds_priv*)netdev_priv(dev);
+ priv_wds->wlan_priv = priv;
+#else
+ dev->priv = priv;
+#endif
+ rc = register_netdev(dev);
+ if (rc) {
+ printk(KERN_ERR "register_netdev() wds error!\n");
+ goto err_out_dev;
+ }
+ }
+#endif // WDS
+
+#ifdef CONFIG_RTK_MESH
+ mesh_num = (priv->pshare->type>>MESH_SHIFT) & MESH_MASK;
+
+#ifndef WDS
+ strcpy(baseDevName, dev->name);
+#endif
+ if(mesh_num>0) {
+ GET_MIB(priv)->dot1180211sInfo.mesh_enable = 1;
+ dev = alloc_etherdev(0); // mesh allocate ethernet device BUT don't have priv memory (Because share root priv)
+ if (!dev) {
+ printk(KERN_ERR "alloc_etherdev() mesh error!\n");
+ rc = -ENOMEM;
+ goto err_out_iomap;
+ }
+ dev->base_addr = 1;
+#if !defined(__LINUX_2_6__) || defined(CONFIG_COMPAT_NET_DEV_OPS)
+ dev->open = rtl8192cd_open;
+ dev->stop = rtl8192cd_close;
+ dev->hard_start_xmit = rtl8192cd_start_xmit;
+ dev->get_stats = rtl8192cd_get_stats;
+ dev->set_mac_address = rtl8192cd_set_hwaddr;
+ dev->do_ioctl = rtl8192cd_ioctl;
+#else
+ dev->netdev_ops = &rtl8192cd_netdev_ops;
+#endif
+
+#ifdef CONFIG_RTL8672
+ dev->priv_flags = IFF_DOMAIN_WLAN;
+#endif
+
+ priv->mesh_dev = dev; // NO priv zone dev
+ strcpy(dev->name, baseDevName);
+ strcat(dev->name, "-msh%d");
+ dev->priv = priv; // mesh priv pointer to root's priv
+ rc = register_netdev(dev);
+ if (rc) {
+ printk(KERN_ERR "register_netdev() mesh error!\n");
+ goto err_out_iomap;
+ }
+ } // end of if(mesh_num>0)
+
+ priv->RreqEnd = 0;
+ priv->RreqBegin = 0;
+
+ pann_mpp_tb = (struct mpp_tb*)kmalloc(sizeof(struct mpp_tb), GFP_ATOMIC);
+ if(!pann_mpp_tb)
+ {
+ rc = -ENOMEM;
+ printk("allocate pann_mpp_tb error!!\n");
+ goto err_out_free;
+ }
+ init_mpp_pool(pann_mpp_tb);
+ proxy_table = (struct hash_table*)kmalloc(sizeof(struct hash_table), GFP_ATOMIC);
+ if(!proxy_table)
+ {
+ rc = -ENOMEM;
+ printk("allocate proxy_table error!!\n");
+ goto err_out_free;
+ }
+ memset((void*)proxy_table, 0, sizeof(struct hash_table));
+
+#ifdef PU_STANDARD
+ //pepsi
+ proxyupdate_table = (struct hash_table*)kmalloc(sizeof(struct hash_table), GFP_ATOMIC);
+ if(!proxyupdate_table)
+ {
+ rc = -ENOMEM;
+ printk("allocate proxyupdate_table error!!\n");
+ goto err_out_free;
+ }
+ memset((void*)proxyupdate_table, 0, sizeof(struct hash_table));
+#endif
+
+ pathsel_queue = (DOT11_QUEUE2 *)kmalloc((sizeof(DOT11_QUEUE2)), GFP_ATOMIC);
+ if (!pathsel_queue) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for PATHSELECTION_QUEUE (size %d)\n", sizeof(DOT11_QUEUE));
+ goto err_out_free;
+ }
+ memset((void *)pathsel_queue, 0, sizeof (DOT11_QUEUE2));
+#ifdef _11s_TEST_MODE_
+ receiver_queue = (DOT11_QUEUE2 *)kmalloc((sizeof(DOT11_QUEUE2)), GFP_ATOMIC);
+ if (!receiver_queue) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for receiver_queue (size %d)\n", sizeof(DOT11_QUEUE));
+ goto err_out_free;
+ }
+ memset((void *)receiver_queue, 0, sizeof (DOT11_QUEUE2));
+ pgalileo_poll = (struct Galileo_poll *) kmalloc((sizeof( struct Galileo_poll)), GFP_ATOMIC);
+ if (!pgalileo_poll) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for pgalileo_poll (size %d)\n", sizeof(struct Galileo_poll));
+ goto err_out_free;
+ }
+#endif
+ pathsel_table = (struct hash_table*)kmalloc(sizeof(struct hash_table), GFP_ATOMIC);
+ if(!pathsel_table)
+ {
+ rc = -ENOMEM;
+ printk("allocate pathsel_table error!!\n");
+ goto err_out_free;
+ }
+ memset((void*)pathsel_table, 0, sizeof(struct hash_table));
+
+ mesh_rreq_retry_queue = (struct hash_table*)kmalloc(sizeof(struct hash_table), GFP_ATOMIC);
+ if(!mesh_rreq_retry_queue)
+ {
+ rc = -ENOMEM;
+ printk("allocate mesh_rreq_retry_queue error!!\n");
+ goto err_out_free;
+ }
+ memset((void*)mesh_rreq_retry_queue, 0, sizeof(struct hash_table));
+
+ rc = init_hash_table(proxy_table, PROXY_TABLE_SIZE, MACADDRLEN, sizeof(struct proxy_table_entry), crc_hashing, search_default, insert_default, delete_default,traverse_default);
+ if(rc == HASH_TABLE_FAILED)
+ {
+ printk("init_hash_table \"proxy_table\" error!!\n");
+ }
+
+#ifdef PU_STANDARD
+ //pepsi
+ rc = init_hash_table(proxyupdate_table, 8, sizeof(UINT8), sizeof(struct proxyupdate_table_entry), PU_hashing, search_default, insert_default, delete_default,traverse_default);
+ if(rc == HASH_TABLE_FAILED)
+ {
+ printk("init_hash_table \"proxyupdate_table\" error!!\n");
+ }
+#endif
+ rc = init_hash_table(pathsel_table, 8, MACADDRLEN, sizeof(struct path_sel_entry), crc_hashing, search_default, insert_default, delete_default,traverse_default);
+ if(rc == HASH_TABLE_FAILED)
+ {
+ printk("init_hash_table \"pathsel_table\" error!!\n");
+ }
+
+ rc = init_hash_table(mesh_rreq_retry_queue, DATA_SKB_BUFFER_SIZE, MACADDRLEN, sizeof(struct mesh_rreq_retry_entry), crc_hashing, search_default, insert_default, delete_default,traverse_default);
+ if(rc == HASH_TABLE_FAILED)
+ {
+ printk("init_hash_table \"mesh_rreq_retry_queue\" error!!\n");
+ }
+
+ for(i = 0; i < (1 << mesh_rreq_retry_queue->table_size_power); i++)
+ {
+ (((struct mesh_rreq_retry_entry*)(mesh_rreq_retry_queue->entry_array[i].data))->ptr) = (struct pkt_queue*)kmalloc(sizeof(struct pkt_queue), GFP_ATOMIC);
+ if (!(((struct mesh_rreq_retry_entry*)(mesh_rreq_retry_queue->entry_array[i].data))->ptr)) {
+ rc = -ENOMEM;
+ printk(KERN_ERR "Can't kmalloc for mesh_rreq_retry_entry (size %d)\n", sizeof(struct pkt_queue));
+ goto err_out_free;
+ }
+ memset((void *)((((struct mesh_rreq_retry_entry*)(mesh_rreq_retry_queue->entry_array[i].data))->ptr)), 0, sizeof (struct pkt_queue));
+ }
+
+#ifdef PU_STANDARD
+ priv->proxyupdate_table = proxyupdate_table;
+#endif
+#ifdef _11s_TEST_MODE_
+ priv->receiver_queue = receiver_queue;
+ priv->pshare->galileo_poll = pgalileo_poll ;
+#endif
+ priv->proxy_table = proxy_table;
+ priv->pathsel_queue = pathsel_queue;
+ priv->pann_mpp_tb = pann_mpp_tb;
+ priv->pathsel_table = pathsel_table;
+ priv->mesh_rreq_retry_queue = mesh_rreq_retry_queue;
+ //=========================================================
+#endif // CONFIG_RTK_MESH
+
+
+#endif // __DRAYTEK_OS__
+
+#ifdef PRIV_STA_BUF
+#ifdef CONCURRENT_MODE
+ page_ptr = (unsigned char *)
+ (((unsigned long)&desc_buf[priv->pshare->wlandev_idx]) + (PAGE_SIZE - (((unsigned long)&desc_buf[priv->pshare->wlandev_idx]) & (PAGE_SIZE-1))));
+ phw->ring_buf_len = ((unsigned long)&desc_buf[priv->pshare->wlandev_idx]) + (sizeof(desc_buf)/NUM_WLAN_IFACE) - ((unsigned long)page_ptr);
+ phw->ring_dma_addr = virt_to_bus(page_ptr);
+ page_ptr = (unsigned char *)KSEG1ADDR(page_ptr);
+#else
+ page_ptr = (unsigned char *)
+ (((unsigned long)desc_buf) + (PAGE_SIZE - (((unsigned long)desc_buf) & (PAGE_SIZE-1))));
+ phw->ring_buf_len = (unsigned long)desc_buf + sizeof(desc_buf) - (unsigned long)page_ptr;
+ phw->ring_dma_addr = virt_to_bus(page_ptr);
+ page_ptr = (unsigned char *)KSEG1ADDR(page_ptr);
+#endif
+#else
+#ifdef CONFIG_NET_PCI
+ if (IS_PCIBIOS_TYPE)
+ page_ptr = pci_alloc_consistent(priv->pshare->pdev, DESC_DMA_PAGE_SIZE, (dma_addr_t *)&phw->ring_dma_addr);
+ else
+#endif
+ {
+#ifdef __DRAYTEK_OS__
+ page_ptr = rtl8185_malloc(DESC_DMA_PAGE_SIZE, 1); // allocate non-cache buffer
+#else
+ page_ptr = kmalloc(DESC_DMA_PAGE_SIZE, GFP_ATOMIC);
+#endif
+ }
+
+ if (page_ptr == NULL) {
+ printk(KERN_ERR "can't allocate descriptior page, abort!\n");
+ goto err_out_dev;
+ }
+
+ phw->alloc_dma_buf = (unsigned long)page_ptr;
+#if defined(NOT_RTK_BSP)
+ page_align_phy = (PAGE_SIZE - (((unsigned long)page_ptr) & (PAGE_SIZE-1)));
+#endif
+ page_ptr = (unsigned char *)
+ (((unsigned long)page_ptr) + (PAGE_SIZE - (((unsigned long)page_ptr) & (PAGE_SIZE-1))));
+ phw->ring_buf_len = phw->alloc_dma_buf + DESC_DMA_PAGE_SIZE - ((unsigned long)page_ptr);
+#if defined(NOT_RTK_BSP)
+ phw->ring_dma_addr = phw->ring_dma_addr + page_align_phy;
+#else
+ phw->ring_dma_addr = virt_to_bus(page_ptr);
+#endif
+
+#ifdef __MIPSEB__
+ page_ptr = (unsigned char *)KSEG1ADDR(page_ptr);
+#endif
+#endif
+
+ DEBUG_INFO("page_ptr=%lx, size=%ld\n", (unsigned long)page_ptr, (unsigned long)DESC_DMA_PAGE_SIZE);
+ phw->ring_virt_addr = (unsigned long)page_ptr;
+
+#ifdef CONFIG_RTL8190_PRIV_SKB
+ init_priv_skb_buf(priv);
+#endif
+
+#ifdef PRIV_STA_BUF
+ init_priv_sta_buf(priv);
+#endif
+
+#ifdef CONFIG_RTL_92D_DMDP
+ if_priv[priv->pshare->wlandev_idx] = (u32)priv;
+#endif
+ }
+
+ INIT_LIST_HEAD(&priv->asoc_list); // init assoc_list first because webs may get sta_num even it is not open,
+ // and it will cause exception if it is not init, david+2008-03-05
+#ifdef EN_EFUSE
+ extern int ReadAdapterInfo8192CE(struct rtl8192cd_priv *priv);
+ ReadAdapterInfo8192CE(priv);
+#endif
+ printk("=====>>EXIT rtl8192cd_init_one <<=====\n");
+ return 0;
+
+err_out_dev:
+
+ unregister_netdev(dev);
+
+err_out_iomap:
+
+#ifdef CONFIG_NET_PCI
+ if (((wdev->type >> TYPE_SHIFT) & TYPE_MASK) == TYPE_PCI_BIOS) {
+#ifndef USE_IO_OPS
+ iounmap(regs);
+#endif
+ }
+
+err_out_res:
+
+ if (((wdev->type >> TYPE_SHIFT) & TYPE_MASK) == TYPE_PCI_BIOS) {
+#ifdef USE_IO_OPS
+ release_region(dev->base_addr, pci_resource_len(pdev, 0));
+//// release_region(dev->base_addr, pci_resource_len(pdev, 2));
+#else
+ pci_release_regions(pdev);
+#endif
+ }
+
+err_out_disable:
+
+ if (((wdev->type >> TYPE_SHIFT) & TYPE_MASK) == TYPE_PCI_BIOS)
+ pci_disable_device(pdev);
+#endif // CONFIG_NET_PCI
+
+err_out_free:
+
+ if (pmib){
+#ifdef RTL8192CD_VARIABLE_USED_DMEM
+ rtl8192cd_dmem_free(PMIB, pmib);
+#else
+ kfree(pmib);
+#endif
+ }
+#ifdef CONFIG_RTK_MESH
+ if(proxy_table)
+ {
+ remove_hash_table(proxy_table);
+ kfree(proxy_table);
+ }
+ if(mesh_rreq_retry_queue)
+ {
+ for (i=0; i< (1 << mesh_rreq_retry_queue->table_size_power); i++)
+ {
+ if(((struct mesh_rreq_retry_entry*)(mesh_rreq_retry_queue->entry_array[i].data))->ptr)
+ {
+ kfree(((struct mesh_rreq_retry_entry*)(mesh_rreq_retry_queue->entry_array[i].data))->ptr);
+ }
+ }
+ remove_hash_table(mesh_rreq_retry_queue);
+ kfree(mesh_rreq_retry_queue);
+ }
+
+ // add by chuangch 2007.09.13
+ if(pathsel_table)
+ {
+ remove_hash_table(pathsel_table);
+ kfree(pathsel_table);
+ }
+
+ if(pann_mpp_tb)
+ kfree(pann_mpp_tb);
+
+ if (pathsel_queue)
+ kfree(pathsel_queue);
+#ifdef _11s_TEST_MODE_
+ if (receiver_queue)
+ kfree(receiver_queue);
+#endif
+#endif // CONFIG_RTK_MESH
+ if (pevent_queue)
+ kfree(pevent_queue);
+#ifdef CONFIG_RTL_WAPI_SUPPORT
+ if (wapiEvent_queue)
+ kfree(wapiEvent_queue);
+ #if defined(MBSSID)
+ if (wapiVapEvent_queue)
+ kfree(wapiVapEvent_queue);
+ #endif
+
+#endif
+#ifndef PRIV_STA_BUF
+ if (phw)
+ kfree(phw);
+ if (pshare) // david
+ kfree(pshare);
+ if (pwlan_hdr_poll)
+ kfree(pwlan_hdr_poll);
+ if (pwlanllc_hdr_poll)
+ kfree(pwlanllc_hdr_poll);
+ if (pwlanbuf_poll)
+ kfree(pwlanbuf_poll);
+ if (pwlanicv_poll)
+ kfree(pwlanicv_poll);
+ if (pwlanmic_poll)
+ kfree(pwlanmic_poll);
+#endif
+ if (pwlan_acl_poll)
+ kfree(pwlan_acl_poll);
+
+#if defined(CONFIG_RTK_MESH) && defined(_MESH_ACL_ENABLE_) // below code copy above ACL code
+ if (pmesh_acl_poll)
+ kfree(pmesh_acl_poll);
+#endif
+
+ if (Eap_packet)
+ kfree(Eap_packet);
+#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD)
+ if (wpa_global_info)
+ kfree(wpa_global_info);
+#endif
+
+#ifdef __LINUX_2_6__
+ free_netdev(dev);
+#else
+ kfree(dev);
+#endif
+ wdev->priv = NULL;
+ printk("=====>>EXIT rtl8192cd_init_one2(%d) <<=====\n", rc);
+ return rc;
+}
+
+
+#ifdef CONFIG_RTL_STP
+extern int rtl865x_wlanIF_Init(struct net_device *dev);
+static int rtl_pseudo_dev_set_hwaddr(struct net_device *dev, void *addr)
+{
+ unsigned long flags;
+ int i;
+ unsigned char *p;
+
+ p = ((struct sockaddr *)addr)->sa_data;
+ local_irq_save(flags);
+ for (i = 0; i<MACADDRLEN; ++i) {
+ dev->dev_addr[i] = p[i];
+ }
+ local_irq_restore(flags);
+ return SUCCESS;
+}
+
+#if defined(__LINUX_2_6__) && !defined(CONFIG_COMPAT_NET_DEV_OPS)
+static const struct net_device_ops rtl8192cd_rtl_pseudodev_ops = {
+ .ndo_open = rtl8192cd_open,
+ .ndo_stop = rtl8192cd_close,
+ .ndo_set_mac_address = rtl_pseudo_dev_set_hwaddr,
+ .ndo_get_stats = rtl8192cd_get_stats,
+ .ndo_do_ioctl = rtl8192cd_ioctl,
+ .ndo_start_xmit = rtl8192cd_start_xmit,
+};
+#endif
+
+void rtl_pseudo_dev_init(void* priv)
+{
+ struct net_device *dev;
+
+/* printk("[%s][%d] priv of %s\n", __FUNCTION__, __LINE__, ((struct rtl8192cd_priv*)priv)->dev->name);*/
+ dev = alloc_etherdev(0);
+ if (dev == NULL) {
+ printk("alloc_etherdev() pseudo port5 error!\n");
+ return;
+ }
+
+#if !defined(__LINUX_2_6__) || defined(CONFIG_COMPAT_NET_DEV_OPS)
+ dev->open = rtl8192cd_open;
+ dev->stop = rtl8192cd_close;
+ dev->hard_start_xmit = rtl8192cd_start_xmit;
+ dev->get_stats = rtl8192cd_get_stats;
+ dev->do_ioctl = rtl8192cd_ioctl;
+ dev->set_mac_address = rtl_pseudo_dev_set_hwaddr;
+#else
+ dev->netdev_ops = &rtl8192cd_rtl_pseudodev_ops;
+#endif
+ dev->priv = priv;
+ strcpy(dev->name, "port5");
+ memcpy((char*)dev->dev_addr,"\x00\xe0\x4c\x81\x86\x86", MACADDRLEN);
+ if (register_netdev(dev)) {
+ printk(KERN_ERR "register_netdev() wds error!\n");
+ }
+ rtl865x_wlanIF_Init(dev);
+}
+#endif
+
+#if defined(CONFIG_RTL_CUSTOM_PASSTHRU)
+__DRAM_IN_865X int passThruStatusWlan;
+int passThruWanIdx;
+static struct proc_dir_entry *resPassThruWlan=NULL;
+static char passThru_flag_wlan[10];
+
+static int rtl_passthru_pseudo_dev_set_hwaddr(struct net_device *dev, void *addr)
+{
+ unsigned long flags;
+ int i;
+ unsigned char *p;
+
+ p = ((struct sockaddr *)addr)->sa_data;
+ local_irq_save(flags);
+ for (i = 0; i<MACADDRLEN; ++i) {
+ dev->dev_addr[i] = p[i];
+ }
+ local_irq_restore(flags);
+ return SUCCESS;
+}
+
+#if defined(__LINUX_2_6__) && !defined(CONFIG_COMPAT_NET_DEV_OPS)
+static const struct net_device_ops rtl8192cd_pseudodev_ops = {
+ .ndo_open = rtl8192cd_open,
+ .ndo_stop = rtl8192cd_close,
+ .ndo_set_mac_address = rtl_passthru_pseudo_dev_set_hwaddr,
+ .ndo_set_multicast_list = rtl8192cd_set_rx_mode,
+ .ndo_get_stats = rtl8192cd_get_stats,
+ .ndo_do_ioctl = rtl8192cd_ioctl,
+ .ndo_start_xmit = rtl8192cd_start_xmit,
+};
+#endif
+
+void rtl_passthru_pseudo_dev_init(void *priv)
+{
+ struct net_device *dev;
+ struct rtl8192cd_priv *dp;
+
+ dev = alloc_etherdev(sizeof(struct rtl8192cd_priv));
+ if (dev == NULL) {
+ printk("alloc_etherdev() pseudo pwlan0 error!\n");
+ return;
+ }
+
+#if !defined(__LINUX_2_6__) || defined(CONFIG_COMPAT_NET_DEV_OPS)
+ dev->open = rtl8192cd_open;
+ dev->stop = rtl8192cd_close;
+ dev->set_multicast_list = rtl8192cd_set_rx_mode;
+ dev->hard_start_xmit = rtl8192cd_start_xmit;
+ dev->get_stats = rtl8192cd_get_stats;
+ dev->do_ioctl = rtl8192cd_ioctl;
+ dev->set_mac_address = rtl_passthru_pseudo_dev_set_hwaddr;
+#else
+ dev->netdev_ops = &rtl8192cd_pseudodev_ops;
+#endif
+
+#ifndef NETDEV_NO_PRIV
+ dev->priv = priv;
+#endif
+
+ strcpy(dev->name, "pwlan%d");
+ memcpy((char*)dev->dev_addr,"\x00\xe0\x4c\x81\x96\x96", MACADDRLEN);
+ if (register_netdev(dev)) {
+ printk(KERN_ERR "register_netdev() pwlan0 error!\n");
+ }
+
+ ((struct rtl8192cd_priv *)priv)->pWlanDev=dev; //pWlanDev point to the virtual pwlan0
+}
+
+
+static unsigned long atoi_dec(char *s)
+{
+ unsigned long k = 0;
+
+ k = 0;
+ while (*s != '\0' && *s >= '0' && *s <= '9') {
+ k = 10 * k + (*s - '0');
+ s++;
+ }
+ return k;
+}
+
+static int wlan_custom_Passthru_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len;
+ len = sprintf(page, "%s\n", passThru_flag_wlan);
+ if (len <= off+count)
+ *eof = 1;
+
+ *start = page + off;
+ len -= off;
+
+ if (len>count)
+ len = count;
+
+ if (len<0) len = 0;
+
+ return len;
+}
+
+static int wlan_custom_Passthru_write_proc(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ int flag,i;
+
+ if (buffer && !copy_from_user(&passThru_flag_wlan, buffer, count))
+ {
+ flag=(int)atoi_dec(passThru_flag_wlan);
+
+ passThruStatusWlan=flag;
+
+ return count;
+ }
+ return -EFAULT;
+}
+
+int rtl_wlan_customPassthru_init(void)
+{
+ int wlan_idx;
+
+ for(wlan_idx=0;wlan_idx<sizeof(wlan_device)/sizeof(struct _device_info_);wlan_idx++)
+ {
+ if (wlan_device[wlan_idx].priv!=NULL)
+ break;
+ }
+
+ if (wlan_idx==sizeof(wlan_device)/sizeof(struct _device_info_))
+ return -EINVAL;
+
+ passThruWanIdx = wlan_idx;
+ //initial
+ memset(passThru_flag_wlan,0, sizeof(passThru_flag_wlan));
+ //strcpy(passThru_flag_wlan,"0");
+ passThruStatusWlan=0;
+
+ resPassThruWlan = create_proc_entry("custom_Passthru_wlan", 0, NULL);
+ if(resPassThruWlan)
+ {
+ resPassThruWlan->read_proc = wlan_custom_Passthru_read_proc;
+ resPassThruWlan->write_proc = wlan_custom_Passthru_write_proc;
+ }
+
+
+ rtl_passthru_pseudo_dev_init(wlan_device[passThruWanIdx].priv);
+
+ return 0;
+}
+
+void __exit rtl_wlan_customPassthru_exit(void)
+{
+ if (resPassThruWlan) {
+ remove_proc_entry("custom_Passthru_wlan", resPassThruWlan);
+ resPassThruWlan = NULL;
+ }
+}
+#endif
+
+
+
+#if defined(__DRAYTEK_OS__) && defined(WDS)
+int rtl8192cd_add_wds(struct net_device *dev, struct net_device *wds_dev, unsigned char *addr)
+{
+ struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)dev->priv;
+ int wds_num=priv->pmib->dot11WdsInfo.wdsNum;
+
+ priv->pmib->dot11WdsInfo.dev[wds_num] = wds_dev;
+ memcpy(priv->pmib->dot11WdsInfo.entry[wds_num].macAddr, addr, 6);
+ wds_dev->priv = priv;
+ wds_dev->base_addr = 0;
+ priv->pmib->dot11WdsInfo.wdsNum++;
+
+ if (!priv->pmib->dot11WdsInfo.wdsEnabled)
+ priv->pmib->dot11WdsInfo.wdsEnabled = 1;
+
+ if (netif_running(priv->dev))
+ create_wds_tbl(priv);
+
+ DEBUG_INFO("\r\nAdd WDS: %02x%02x %02x%02x%02x%02x\n",
+ addr[0],addr[1],addr[2],addr[3],addr[4],addr[5]);
+}
+#endif
+
+
+#ifdef CONFIG_NET_PCI
+static int MDL_DEVINIT rtl8192cd_init_pci(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ int dev_num=0;
+ int ret;
+#ifdef MBSSID
+ int i;
+#endif
+
+#ifdef RTL8192CD_VARIABLE_USED_DMEM
+ /* For D-MEM allocation system's initialization : It would before ALL processes */
+ rtl8192cd_dmem_init();
+#endif
+
+ if(dev_num >= (sizeof(wlan_device)/sizeof(struct _device_info_))){
+ printk("PCI device %d can't be support\n", dev_num);
+ return -1;
+ }
+ else {
+
+ ret = rtl8192cd_init_one(pdev, ent, &wlan_device[dev_num++], -1);
+#ifdef UNIVERSAL_REPEATER
+ if (ret == 0) {
+ ret = rtl8192cd_init_one(pdev, ent, &wlan_device[--dev_num], -1);
+ dev_num++;
+ }
+#endif
+#ifdef MBSSID
+ if (ret == 0) {
+ dev_num--;
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++) {
+ ret = rtl8192cd_init_one(pdev, ent, &wlan_device[dev_num], i);
+ if (ret != 0) {
+ printk("Init fail!\n");
+ return ret;
+ }
+ }
+ dev_num++;
+ }
+#endif
+ return ret;
+ }
+}
+
+
+static void MDL_DEVEXIT rtk_remove_one(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+
+#ifdef NETDEV_NO_PRIV
+ struct rtl8192cd_priv *priv = ((struct rtl8192cd_priv *)netdev_priv(dev))->wlan_priv;
+#else
+ struct rtl8192cd_priv *priv = dev->priv;
+#endif
+
+ if (!dev)
+ BUG();
+
+ iounmap((void *)priv->dev->base_addr);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+}
+
+
+static struct pci_device_id MDL_DEVINITDATA rtl8192cd_pci_tbl[] =
+{
+/*
+ { PCI_VENDOR_ID_REALTEK, 0x8190,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+*/
+#ifdef CONFIG_RTL_92D_SUPPORT
+ { PCI_VENDOR_ID_REALTEK, 0x8193,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+#endif
+ { PCI_VENDOR_ID_REALTEK, 0x8191,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+
+ { PCI_VENDOR_ID_REALTEK, 0x8171,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+
+ { PCI_VENDOR_ID_REALTEK, 0x8178,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+
+ { PCI_VENDOR_ID_REALTEK, 0x8176,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+
+ { PCI_VENDOR_ID_REALTEK, 0x8174,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+
+ { },
+};
+
+
+MODULE_DEVICE_TABLE(pci, rtl8192cd_pci_tbl);
+
+static struct pci_driver rtl8192cd_driver = {
+ name: DRV_NAME,
+ id_table: rtl8192cd_pci_tbl,
+ probe: rtl8192cd_init_pci,
+ remove: __devexit_p(rtk_remove_one),
+};
+#endif // CONFIG_NET_PCI
+
+
+#ifdef CONFIG_WIRELESS_LAN_MODULE
+int GetCpuCanSuspend(void)
+{
+ extern int gCpuCanSuspend;
+ return gCpuCanSuspend;
+}
+#endif
+
+
+#if defined(CONFIG_RTL8196B)
+//System identification for CHIP
+#define CHIP_OEM_ID 0xb8000000
+#define DDR_SELECT 0xb8000008
+#define C_CUT 2
+#define DDR_BOOT 2
+int no_ddr_patch;
+#endif
+
+
+int MDL_INIT __rtl8192cd_init(unsigned long base_addr)
+{
+#ifdef CONFIG_NET_PCI
+ int pci_reg=0;
+#endif
+ int rc;
+#ifdef MBSSID
+ int i;
+#endif
+
+#if defined(CONFIG_RTL8196B)
+ //System identification for CHIP
+ no_ddr_patch = !((REG32(CHIP_OEM_ID)<C_CUT)&(REG32(DDR_SELECT)&&DDR_BOOT));
+#endif
+
+#ifdef __KERNEL__
+#if defined(EAP_BY_QUEUE) && defined(USE_CHAR_DEV)
+// for module, 2005-12-26 -----------
+ extern struct rtl8192cd_priv* (*rtl8192cd_chr_reg_hook)(unsigned int minor, struct rtl8192cd_chr_priv *priv);
+ extern void (*rtl8192cd_chr_unreg_hook)(unsigned int minor);
+//------------------------------------
+#endif
+#ifdef CONFIG_WIRELESS_LAN_MODULE
+ wirelessnet_hook = GetCpuCanSuspend;
+#ifdef BR_SHORTCUT
+ wirelessnet_hook_shortcut = get_shortcut_dev;
+#endif
+#ifdef PERF_DUMP
+ Fn_rtl8651_romeperfEnterPoint = rtl8651_romeperfEnterPoint;
+ Fn_rtl8651_romeperfExitPoint = rtl8651_romeperfExitPoint;
+#endif
+#ifdef CONFIG_RTL8190_PRIV_SKB
+ wirelessnet_hook_is_priv_buf = is_rtl8190_priv_buf;
+ wirelessnet_hook_free_priv_buf = free_rtl8190_priv_buf;
+#endif
+#endif // CONFIG_WIRELESS_LAN_MODULE
+#endif // __KERNEL__
+
+#ifndef GREEN_HILL
+#ifdef CONFIG_RTL8671
+ printk("%s driver version %d.%d.%d (%s)\n", DRV_NAME, DRV_VERSION_H, DRV_VERSION_L, DRV_VERSION_SUBL, DRV_RELDATE);
+#else
+ panic_printk("%s driver version %d.%d (%s)\n", DRV_NAME, DRV_VERSION_H, DRV_VERSION_L, DRV_RELDATE);
+#endif
+#endif
+
+
+#ifdef __KERNEL__
+ for (wlan_index=0; wlan_index<sizeof(wlan_device)/sizeof(struct _device_info_); wlan_index++)
+#else
+ if (wlan_index<sizeof(wlan_device)/sizeof(struct _device_info_))
+#endif
+ {
+ if (((wlan_device[wlan_index].type >> TYPE_SHIFT) & TYPE_MASK) == TYPE_PCI_BIOS) {
+#ifdef CONFIG_NET_PCI
+ if(!pci_reg){
+ pci_reg=1;
+#ifdef LINUX_2_6_21_
+ pci_register_driver(&rtl8192cd_driver);
+#else
+ pci_module_init(&rtl8192cd_driver);
+#endif
+ }
+#endif
+ }
+ else {
+
+#ifdef __DRAYTEK_OS__
+ wlan_device[wlan_index].base_addr = base_addr;
+ wlan_device[wlan_index].type = (TYPE_PCI_DIRECT<<TYPE_SHIFT);
+#endif
+ rc = rtl8192cd_init_one(NULL, NULL, &wlan_device[wlan_index], -1);
+
+ // victoryman debug
+ if (rc)
+ printk("init_one fail!!! rc=%d\n",rc);
+
+#ifdef UNIVERSAL_REPEATER
+ if (rc == 0)
+ rc = rtl8192cd_init_one(NULL, NULL, &wlan_device[wlan_index], -1);
+#endif
+#ifdef MBSSID
+ if (rc == 0) {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++) {
+ rc = rtl8192cd_init_one(NULL, NULL, &wlan_device[wlan_index], i);
+ if (rc != 0) {
+ printk("Init fail! rc=%d\n", rc);
+ break;
+ }
+ }
+ }
+#endif
+ }
+
+#if defined(__DRAYTEK_OS__)
+ if (rc != 0)
+ return rc;
+#endif
+
+#ifndef __KERNEL__
+ wlan_index++;
+#endif
+ }
+
+#if defined(CONFIG_RTL_CUSTOM_PASSTHRU)
+ rtl_wlan_customPassthru_init();
+#endif
+
+#if 0
+//#ifdef PCIE_POWER_SAVING
+ HostPCIe_Close();
+#endif
+
+
+#ifdef CONFIG_RTL_STP
+ rtl_pseudo_dev_init(wlan_device[0].priv);
+#endif
+
+#ifdef _USE_DRAM_
+ {
+ extern unsigned char *en_cipherstream;
+ extern unsigned char *tx_cipherstream;
+ extern char *rc4sbox, *rc4kbox;
+ extern unsigned char *pTkip_Sbox_Lower, *pTkip_Sbox_Upper;
+ extern unsigned char Tkip_Sbox_Lower[256], Tkip_Sbox_Upper[256];
+
+#ifdef CONFIG_RTL8671
+ extern void r3k_enable_DRAM(void); //6/7/04' hrchen, for 8671 DRAM init
+ r3k_enable_DRAM(); //6/7/04' hrchen, for 8671 DRAM init
+#endif
+
+ en_cipherstream = (unsigned char *)(DRAM_START_ADDR);
+ tx_cipherstream = en_cipherstream;
+
+ rc4sbox = (char *)(DRAM_START_ADDR + 2048);
+ rc4kbox = (char *)(DRAM_START_ADDR + 2048 + 256);
+ pTkip_Sbox_Lower = (unsigned char *)(DRAM_START_ADDR + 2048 + 256*2);
+ pTkip_Sbox_Upper = (unsigned char *)(DRAM_START_ADDR + 2048 + 256*3);
+
+ memcpy(pTkip_Sbox_Lower, Tkip_Sbox_Lower, 256);
+ memcpy(pTkip_Sbox_Upper, Tkip_Sbox_Upper, 256);
+ }
+#endif
+
+#ifdef __KERNEL__
+#if defined(EAP_BY_QUEUE) && defined(USE_CHAR_DEV)
+// for module, 2005-12-26 -----------
+ rtl8192cd_chr_reg_hook = rtl8192cd_chr_reg;
+ rtl8192cd_chr_unreg_hook = rtl8192cd_chr_unreg;
+//------------------------------------
+ rtl8192cd_chr_init();
+#endif
+#endif
+
+#ifdef CONFIG_RTL8671
+ //turn off AP LED
+ {
+ unsigned char wlanreg = *(volatile unsigned char *)0xbd30005e;
+ *(volatile unsigned char *)0xbd30005e = (wlanreg | ((1<<5)));
+ }
+#endif
+
+#ifdef PERF_DUMP
+ rtl8651_romeperfInit();
+#endif
+
+#ifdef USB_PKT_RATE_CTRL_SUPPORT
+ register_usb_hook = (register_usb_pkt_cnt_fn)(register_usb_pkt_cnt_f);
+#endif
+
+ return 0;
+}
+
+
+#ifdef __DRAYTEK_OS__
+int rtl8192cd_init(unsigned long base_addr)
+{
+ return __rtl8192cd_init(base_addr);
+}
+#else // not __DRAYTEK_OS__
+int MDL_INIT rtl8192cd_init(void)
+{
+#ifdef CONFIG_RTL8671
+ gpioConfig(10,2);
+ gpioClear(10);
+ delay_ms(10);
+ gpioSet(10);
+#endif
+
+ return __rtl8192cd_init(0);
+}
+#endif
+
+
+#ifdef __KERNEL__
+static void MDL_EXIT rtl8192cd_exit (void)
+{
+ struct net_device *dev;
+ struct rtl8192cd_priv *priv;
+ int idx;
+#if defined(WDS) || defined(MBSSID)
+ int i;
+#endif
+
+#ifdef CONFIG_WIRELESS_LAN_MODULE
+ wirelessnet_hook = NULL;
+#ifdef BR_SHORTCUT
+ wirelessnet_hook_shortcut = NULL;
+#endif
+#ifdef PERF_DUMP
+ Fn_rtl8651_romeperfEnterPoint = NULL;
+ Fn_rtl8651_romeperfExitPoint = NULL;
+ #endif
+#ifdef CONFIG_RTL8190_PRIV_SKB
+ wirelessnet_hook_is_priv_buf = NULL;
+ wirelessnet_hook_free_priv_buf = NULL;
+#endif
+#endif // CONFIG_WIRELESS_LAN_MODULE
+
+#if defined(EAP_BY_QUEUE) && defined(USE_CHAR_DEV)
+// for module, 2005-12-26 ------------
+ extern struct rtl8192cd_priv* (*rtl8192cd_chr_reg_hook)(unsigned int minor, struct rtl8192cd_chr_priv *priv);
+ extern void (*rtl8192cd_chr_unreg_hook)(unsigned int minor);
+//------------------------------------
+#endif
+
+#ifdef WDS
+ int num;
+
+ for (idx=0; idx<sizeof(wlan_device)/sizeof(struct _device_info_); idx++) {
+ if (wlan_device[idx].priv) {
+ num = (wlan_device[idx].type >> WDS_SHIFT) & WDS_MASK;
+ for (i=0; i<num; i++) {
+ unregister_netdev(wlan_device[idx].priv->wds_dev[i]);
+#ifndef NETDEV_NO_PRIV
+ wlan_device[idx].priv->wds_dev[i]->priv = NULL;
+#endif
+#ifdef __LINUX_2_6__
+ free_netdev(wlan_device[idx].priv->wds_dev[i]);
+#else
+ kfree(wlan_device[idx].priv->wds_dev[i]);
+#endif
+ }
+ }
+ }
+#endif
+
+#ifdef CONFIG_RTK_MESH
+#ifndef WDS
+ int num;
+#endif
+
+ for (idx=0; idx<sizeof(wlan_device)/sizeof(struct _device_info_); idx++) {
+ num = (wlan_device[idx].type >> MESH_SHIFT) & MESH_MASK;
+ if(num > 0) { // num is always 0 or 1 in this time
+ // for (i=0; i<num; i++) {
+ if (wlan_device[idx].priv) {
+ wlan_device[idx].priv->mesh_dev->priv = NULL;
+ unregister_netdev(wlan_device[idx].priv->mesh_dev);
+ kfree(wlan_device[idx].priv->mesh_dev);
+ }
+ } // end of if(num > 0)
+ }
+
+#endif // CONFIG_RTK_MESH
+
+
+#ifdef UNIVERSAL_REPEATER
+ for (idx=0; idx<sizeof(wlan_device)/sizeof(struct _device_info_); idx++) {
+ if (wlan_device[idx].priv) {
+ struct rtl8192cd_priv *vxd_priv = GET_VXD_PRIV(wlan_device[idx].priv);
+ if (vxd_priv) {
+ unregister_netdev(vxd_priv->dev);
+#ifdef RTL8192CD_VARIABLE_USED_DMEM
+ rtl8192cd_dmem_free(PMIB, vxd_priv->pmib);
+#else
+ kfree(vxd_priv->pmib);
+#endif
+ kfree(vxd_priv->pevent_queue);
+#ifdef CONFIG_RTL_WAPI_SUPPORT
+ kfree(vxd_priv->wapiEvent_queue);
+#endif
+ kfree(vxd_priv->pwlan_acl_poll);
+ kfree(vxd_priv->Eap_packet);
+#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD)
+ kfree(vxd_priv->wpa_global_info);
+#endif
+#ifdef __LINUX_2_6__
+ free_netdev(vxd_priv->dev);
+#else
+ kfree(vxd_priv->dev);
+#endif
+ wlan_device[idx].priv->pvxd_priv = NULL;
+ }
+ }
+ }
+#endif
+
+#ifdef MBSSID
+ for (idx=0; idx<sizeof(wlan_device)/sizeof(struct _device_info_); idx++) {
+ if (wlan_device[idx].priv) {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++) {
+ struct rtl8192cd_priv *vap_priv = wlan_device[idx].priv->pvap_priv[i];
+ if (vap_priv) {
+ unregister_netdev(vap_priv->dev);
+#ifdef RTL8192CD_VARIABLE_USED_DMEM
+ rtl8192cd_dmem_free(PMIB, vap_priv->pmib);
+#else
+ kfree(vap_priv->pmib);
+#endif
+ kfree(vap_priv->pevent_queue);
+#ifdef CONFIG_RTL_WAPI_SUPPORT
+ kfree(vap_priv->wapiEvent_queue);
+#endif
+ kfree(vap_priv->pwlan_acl_poll);
+ kfree(vap_priv->Eap_packet);
+#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD)
+ kfree(vap_priv->wpa_global_info);
+#endif
+#ifdef __LINUX_2_6__
+ free_netdev(vap_priv->dev);
+#else
+ kfree(vap_priv->dev);
+#endif
+ wlan_device[idx].priv->pvap_priv[i] = NULL;
+ }
+ }
+ }
+ }
+#endif
+
+#ifdef CONFIG_NET_PCI
+ pci_unregister_driver (&rtl8192cd_driver);
+#endif
+
+ for (idx=0; idx<sizeof(wlan_device)/sizeof(struct _device_info_); idx++)
+ {
+ if (wlan_device[idx].priv == NULL)
+ continue;
+ priv = wlan_device[idx].priv;
+ dev = priv->dev;
+
+#ifdef _INCLUDE_PROC_FS_
+ rtl8192cd_proc_remove(dev);
+#endif
+
+ unregister_netdev(dev);
+
+#ifndef PRIV_STA_BUF
+#ifdef CONFIG_NET_PCI
+ if (IS_PCIBIOS_TYPE)
+ pci_free_consistent(priv->pshare->pdev, DESC_DMA_PAGE_SIZE, (void *)priv->pshare->phw->ring_virt_addr,
+ priv->pshare->phw->alloc_dma_buf);
+ else
+#endif
+ kfree((void *)priv->pshare->phw->alloc_dma_buf);
+#endif
+
+#ifdef RTL8192CD_VARIABLE_USED_DMEM
+ rtl8192cd_dmem_free(PMIB, priv->pmib);
+#else
+ kfree(priv->pmib);
+#endif
+ kfree(priv->pevent_queue);
+#ifdef CONFIG_RTL_WAPI_SUPPORT
+ kfree(priv->wapiEvent_queue);
+ #ifdef MBSSID
+ if (IS_ROOT_INTERFACE(priv)&&priv->pmib->miscEntry.vap_enable){
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++)
+ kfree(priv->pvap_priv[i]->wapiEvent_queue);
+ }
+ #endif
+
+#endif
+
+#ifdef CONFIG_RTK_MESH
+ kfree(priv->pathsel_queue);
+#ifdef _11s_TEST_MODE_
+ kfree(priv->receiver_queue);
+
+ for(i=0; i< AODV_RREQ_TABLE_SIZE; i++)
+ del_timer(&priv->pshare->galileo_poll->node[i].data.expire_timer);
+
+ kfree(priv->pshare->galileo_poll);
+#endif
+#ifdef _MESH_ACL_ENABLE_
+ kfree(priv->pmesh_acl_poll);
+#endif
+#endif
+
+#ifndef PRIV_STA_BUF
+ kfree(priv->pshare->phw);
+ kfree(priv->pshare->pwlan_hdr_poll);
+ kfree(priv->pshare->pwlanllc_hdr_poll);
+ kfree(priv->pshare->pwlanbuf_poll);
+ kfree(priv->pshare->pwlanicv_poll);
+ kfree(priv->pshare->pwlanmic_poll);
+#endif
+ kfree(priv->pwlan_acl_poll);
+ kfree(priv->Eap_packet);
+#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD)
+ kfree(priv->wpa_global_info);
+#endif
+#ifndef PRIV_STA_BUF
+ kfree(priv->pshare); // david
+#endif
+#ifdef __LINUX_2_6__
+ free_netdev(dev);
+#else
+ kfree(dev);
+#endif
+ wlan_device[idx].priv = NULL;
+ }
+
+#if defined(EAP_BY_QUEUE) && defined(USE_CHAR_DEV)
+// for module, 2005-12-26 ------------
+ rtl8192cd_chr_reg_hook = NULL;
+ rtl8192cd_chr_unreg_hook = NULL;
+//------------------------------------
+
+ rtl8192cd_chr_exit();
+#endif
+}
+#else // not __KERNEL__
+void MDL_EXIT rtl8192cd_exit(void *data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ struct rtl8192cd_priv *priv = dev->priv;
+ int idx, i;
+
+ for (idx=0; idx<sizeof(wlan_device)/sizeof(struct _device_info_); idx++)
+ if (wlan_device[idx].priv == priv)
+ break;
+
+ if (idx == sizeof(wlan_device)/sizeof(struct _device_info_))
+ return; // wrong argument!!
+
+#ifdef WDS
+ {
+ int num;
+
+ num = (wlan_device[idx].type >> WDS_SHIFT) & WDS_MASK;
+ for (i=0; i<num; i++) {
+ wlan_device[idx].priv->pmib->dot11WdsInfo.dev[i]->priv = NULL;
+ unregister_netdev(wlan_device[idx].priv->pmib->dot11WdsInfo.dev[i]);
+ kfree(wlan_device[idx].priv->pmib->dot11WdsInfo.dev[i]);
+ }
+ }
+#endif
+
+ unregister_netdev(dev);
+
+ kfree(priv->pmib);
+
+#ifdef CONFIG_RTK_MESH
+
+ if(priv->proxy_table)
+ {
+ remove_hash_table(priv->proxy_table);
+ kfree(priv->proxy_table);
+ }
+ if(priv->mesh_rreq_retry_queue)
+ {
+ for (i = 0; i < (1 << priv->mesh_rreq_retry_queue->table_size_power); i++) {
+ if(((struct mesh_rreq_retry_entry*)(priv->mesh_rreq_retry_queue->entry_array[i].data))->ptr)
+ kfree(((struct mesh_rreq_retry_entry*)(priv->mesh_rreq_retry_queue->entry_array[i].data))->ptr);
+ }
+ remove_hash_table(priv->mesh_rreq_retry_queue);
+ kfree(priv->mesh_rreq_retry_queue);
+ }
+
+ // add by chuangch 2007.09.13
+ if(priv->pathsel_table)
+ {
+ remove_hash_table(priv->pathsel_table);
+ kfree(priv->pathsel_table);
+ }
+
+ if(priv->pann_mpp_tb)
+ kfree(priv->pann_mpp_tb);
+
+ kfree(priv->pathsel_queue);
+#ifdef _11s_TEST_MODE_
+ kfree(priv->receiver_queue);
+ for(i=0; i< AODV_RREQ_TABLE_SIZE; i++)
+ del_timer(&priv->pshare->galileo_poll->node[i].data.expire_timer);
+
+ kfree(priv->pshare->galileo_poll);
+#endif
+
+#ifdef _MESH_ACL_ENABLE_
+ kfree(priv->pmesh_acl_poll);
+#endif
+#endif // CONFIG_RTK_MESH
+
+ kfree(priv->pevent_queue);
+#ifdef CONFIG_RTL_WAPI_SUPPORT
+// kfree(vxd_priv->wapiEvent_queue);
+ kfree(priv->wapiEvent_queue);
+ #ifdef MBSSID
+ if (IS_ROOT_INTERFACE(priv)&&priv->pmib->miscEntry.vap_enable) {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++)
+ kfree(priv->pvap_priv[i]->wapiEvent_queue);
+ }
+ #endif
+
+#endif
+#ifndef PRIV_STA_BUF
+ kfree((void *)priv->pshare->phw->alloc_dma_buf);
+
+ kfree(priv->pshare->phw);
+ kfree(priv->pshare->pwlan_hdr_poll);
+ kfree(priv->pshare->pwlanllc_hdr_poll);
+ kfree(priv->pshare->pwlanbuf_poll);
+ kfree(priv->pshare->pwlanicv_poll);
+ kfree(priv->pshare->pwlanmic_poll);
+#endif
+ kfree(priv->pwlan_acl_poll);
+ kfree(priv->Eap_packet);
+#if defined(INCLUDE_WPA_PSK) || defined(WIFI_HAPD)
+ kfree(priv->wpa_global_info);
+#endif
+#ifndef PRIV_STA_BUF
+ kfree(priv->pshare); // david
+#endif
+ kfree(dev);
+ wlan_device[idx].priv = NULL;
+
+ wlan_index--;
+}
+#endif
+
+
+#ifdef __KERNEL__
+#ifdef USE_CHAR_DEV
+struct rtl8192cd_priv *rtl8192cd_chr_reg(unsigned int minor, struct rtl8192cd_chr_priv *priv)
+{
+ if (wlan_device[minor].priv)
+ wlan_device[minor].priv->pshare->chr_priv = priv;
+ return wlan_device[minor].priv;
+}
+
+
+void rtl8192cd_chr_unreg(unsigned int minor)
+{
+ if (wlan_device[minor].priv)
+ wlan_device[minor].priv->pshare->chr_priv = NULL;
+}
+#endif
+
+
+#ifdef RTL_WPA2_PREAUTH
+void wpa2_kill_fasync(void)
+{
+ int wlan_index = 0;
+ struct _device_info_ *wdev = &wlan_device[wlan_index];
+ struct rtl8192cd_priv *priv = wdev->priv;
+ event_indicate(priv, NULL, -1);
+}
+
+
+void wpa2_preauth_packet(struct sk_buff *pskb)
+{
+ // ****** NOTICE **********
+ int wlan_index = 0;
+ struct _device_info_ *wdev = &wlan_device[wlan_index];
+ // ****** NOTICE **********
+
+ struct rtl8192cd_priv *priv = wdev->priv;
+
+ unsigned char szEAPOL[] = {0x02, 0x01, 0x00, 0x00};
+ DOT11_EAPOL_START Eapol_Start;
+
+ if (priv == NULL) {
+ PRINT_INFO("%s: priv == NULL\n", (char *)__FUNCTION__);
+ return;
+ }
+
+#ifndef WITHOUT_ENQUEUE
+ if (!memcmp(pskb->data, szEAPOL, sizeof(szEAPOL)))
+ {
+ Eapol_Start.EventId = DOT11_EVENT_EAPOLSTART_PREAUTH;
+ Eapol_Start.IsMoreEvent = FALSE;
+#ifdef LINUX_2_6_22_
+ memcpy(&Eapol_Start.MACAddr, pskb->mac_header + MACADDRLEN, WLAN_ETHHDR_LEN);
+#else
+ memcpy(&Eapol_Start.MACAddr, pskb->mac.raw + MACADDRLEN, WLAN_ETHHDR_LEN);
+#endif
+ DOT11_EnQueue((unsigned long)priv, priv->pevent_queue, (unsigned char*)&Eapol_Start, sizeof(DOT11_EAPOL_START));
+ }
+ else
+ {
+ unsigned short pkt_len;
+
+ pkt_len = WLAN_ETHHDR_LEN + pskb->len;
+ priv->Eap_packet->EventId = DOT11_EVENT_EAP_PACKET_PREAUTH;
+ priv->Eap_packet->IsMoreEvent = FALSE;
+ memcpy(&(priv->Eap_packet->packet_len), &pkt_len, sizeof(unsigned short));
+#ifdef LINUX_2_6_22_
+ memcpy(&(priv->Eap_packet->packet[0]), pskb->mac_header, WLAN_ETHHDR_LEN);
+#else
+ memcpy(&(priv->Eap_packet->packet[0]), pskb->mac.raw, WLAN_ETHHDR_LEN);
+#endif
+ memcpy(&(priv->Eap_packet->packet[WLAN_ETHHDR_LEN]), pskb->data, pskb->len);
+ DOT11_EnQueue((unsigned long)priv, priv->pevent_queue, (unsigned char*)priv->Eap_packet, sizeof(DOT11_EAP_PACKET));
+ }
+#endif // WITHOUT_ENQUEUE
+
+ event_indicate(priv, NULL, -1);
+
+ // let dsr to free this skb
+}
+#endif // RTL_WPA2_PREAUTH
+#endif // __KERNEL__
+
+#if defined(CONFIG_RTL_ETH_PRIV_SKB_DEBUG)
+extern int is_rtl865x_eth_priv_buf(unsigned char *head);
+int get_nic_buf_in_wireless_tx(const char *name)
+{
+ int i,txCnt;
+ int queueCnt,idx;
+ struct rtl8192cd_priv *priv;
+ struct tx_desc_info *pdescinfoH,*pdescinfo;
+ struct tx_desc *pdescH, *pdesc;
+ struct sk_buff *skb = NULL;
+ struct rtl8192cd_hw *phw;
+
+ txCnt = 0;
+ for (i=0; (i<sizeof(wlan_device)/sizeof(struct _device_info_)); i++)
+ {
+ //if(counted)
+ //break;
+
+ if (wlan_device[i].priv && netif_running(wlan_device[i].priv->dev) && strcmp(wlan_device[i].priv->dev->name,name)==0)
+ {
+ priv = wlan_device[i].priv;
+ if (OPMODE & WIFI_AP_STATE)
+ {
+ for(queueCnt = 0; queueCnt <= HIGH_QUEUE;queueCnt++)
+ {
+ phw=GET_HW(priv);
+ pdescH = get_txdesc(phw, queueCnt);
+ pdescinfoH = get_txdesc_info(priv->pshare->pdesc_info,queueCnt);
+ for(idx = 0; idx < NUM_TX_DESC; idx++)
+ {
+ pdesc = pdescH + idx;
+ pdescinfo = pdescinfoH + idx;
+ //if (!pdesc || (get_desc(pdesc->Dword0) & TX_OWN))
+ //continue;
+ if(pdescinfo->type == _SKB_FRAME_TYPE_ || pdescinfo->type == _RESERVED_FRAME_TYPE_)
+ skb = (struct sk_buff *)(pdescinfo->pframe);
+ else
+ continue;
+
+ if(skb && is_rtl865x_eth_priv_buf(skb->head))
+ txCnt++;
+ }
+ }
+
+ //counted = 1;
+ }
+ }
+ }
+
+ return txCnt;
+}
+#endif
+
+
+#if defined(CONFIG_RTK_VLAN_SUPPORT) && defined(CONFIG_RTK_VLAN_FOR_CABLE_MODEM)
+struct net_device* get_dev_by_vid(int vid)
+{
+ int i;
+ struct rtl8192cd_priv *priv;
+
+ for (i=0; (i<sizeof(wlan_device)/sizeof(struct _device_info_)); i++)
+ {
+ if (wlan_device[i].priv && netif_running(wlan_device[i].priv->dev))
+ {
+ priv = wlan_device[i].priv;
+ if ((OPMODE & WIFI_AP_STATE) && priv->pmib->miscEntry.vap_enable) {
+ int j;
+ for (j=0; j<RTL8192CD_NUM_VWLAN; j++) {
+ if (IS_DRV_OPEN(priv->pvap_priv[j])) {
+ if(priv->pvap_priv[j]->pmib->vlan.vlan_enable && priv->pvap_priv[j]->pmib->vlan.vlan_id == vid)
+ return priv->pvap_priv[j]->dev;
+ }
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+#endif
+
+__MIPS16
+__IRAM_IN_865X
+struct net_device *get_shortcut_dev(unsigned char *da)
+{
+ int i,j;
+ struct rtl8192cd_priv *priv;
+ struct stat_info *pstat;
+ struct net_device *dev;
+
+#if defined(BR_SHORTCUT)
+ #ifdef CONFIG_RTK_MESH //11 mesh no support shortcut now
+ {
+ extern unsigned char cached_mesh_mac[MACADDRLEN];
+ extern struct net_device *cached_mesh_dev;
+ if (cached_mesh_dev && !memcmp(da, cached_mesh_mac, MACADDRLEN))
+ return cached_mesh_dev;
+ }
+ #endif
+
+ #ifdef WDS
+ {
+ extern unsigned char cached_wds_mac[MACADDRLEN];
+ extern struct net_device *cached_wds_dev;
+ if (cached_wds_dev && !memcmp(da, cached_wds_mac, MACADDRLEN))
+ return cached_wds_dev;
+ }
+ #endif
+
+ #ifdef CLIENT_MODE
+ {
+ extern unsigned char cached_sta_mac[MACADDRLEN];
+ extern struct net_device *cached_sta_dev;
+ if (cached_sta_dev && !memcmp(da, cached_sta_mac, MACADDRLEN))
+ return cached_sta_dev;
+ }
+ #endif
+
+ #if defined(RTL_CACHED_BR_STA)
+ {
+ extern unsigned char cached_br_sta_mac[MACADDRLEN];
+ extern struct net_device *cached_br_sta_dev;
+ if ((cached_br_sta_dev!=NULL)&&!memcmp(da, cached_br_sta_mac, MACADDRLEN))
+ return cached_br_sta_dev;
+ }
+ #endif
+#endif
+
+ dev = NULL;
+ for (i=0; (i<sizeof(wlan_device)/sizeof(struct _device_info_)) && (dev==NULL); i++) {
+ if (wlan_device[i].priv && netif_running(wlan_device[i].priv->dev)) {
+ priv = wlan_device[i].priv;
+
+ if (priv
+ //2010-5-10
+ #ifndef _SINUX_
+ // if sinux, no linux bridge, so should don't depend on br_port if use br_shortcut (John Qian 2010/6/24)
+ && (priv->dev->br_port)
+ && !(priv->dev->br_port->br->stp_enabled)
+ #endif
+ ) {
+ if (!priv->pmib->dot11OperationEntry.disable_brsc) {
+ pstat = get_stainfo(priv, da);
+ if (pstat && pstat->tx_pkts > 10) { /* Make sure it must have some packets go theough bridge module before shortcut */
+ #ifdef WDS
+ if (!(pstat->state & WIFI_WDS)) // if WDS peer
+ #endif
+ {
+ #ifdef CONFIG_RTK_MESH
+ if( isMeshPoint(pstat))
+ {dev = priv->mesh_dev;}
+ else
+ #endif
+ {dev = priv->dev;}
+ break;
+ }
+ }
+ }
+ #ifdef MBSSID
+ else if ((OPMODE & WIFI_AP_STATE) && priv->pmib->miscEntry.vap_enable) {
+ for (j=0; j<RTL8192CD_NUM_VWLAN; j++) {
+ if ((priv->pvap_priv[j]->assoc_num > 0) && IS_DRV_OPEN(priv->pvap_priv[j]) &&
+ !(priv->pvap_priv[j]->pmib->dot11OperationEntry.disable_brsc)) {
+ pstat = get_stainfo(priv->pvap_priv[j], da);
+ if (pstat && pstat->tx_pkts > 10) {
+ dev = priv->pvap_priv[j]->dev;
+ break;
+ }
+ }
+ }
+ }
+ #endif
+ }
+ }
+ }
+
+#if defined(RTL_CACHED_BR_STA) && defined(BR_SHORTCUT)
+ if (dev!=NULL) {
+ memcpy(cached_br_sta_mac, da, MACADDRLEN);
+ cached_br_sta_dev = dev;
+ }
+#endif
+
+ return dev;
+}
+
+#if defined(BR_SHORTCUT)
+void clear_shortcut_cache(void)
+{
+ extern unsigned char cached_eth_addr[MACADDRLEN];
+ extern struct net_device *cached_dev;
+#ifdef CLIENT_MODE
+ extern struct net_device *cached_sta_dev;
+ extern unsigned char cached_sta_mac[MACADDRLEN];
+#endif
+#ifdef CONFIG_RTK_MESH
+ extern struct net_device *cached_mesh_dev;
+ extern unsigned char cached_mesh_mac[MACADDRLEN];
+ cached_mesh_dev = NULL;
+ memset(cached_mesh_mac,0,MACADDRLEN);
+#endif
+
+#ifdef WDS
+ extern struct net_device *cached_wds_dev;
+ extern unsigned char cached_wds_mac[MACADDRLEN];
+ cached_wds_dev= NULL;
+ memset(cached_wds_mac,0,MACADDRLEN);
+#endif
+
+#ifdef CLIENT_MODE
+ cached_sta_dev = NULL;
+ memset(cached_sta_mac,0,MACADDRLEN);
+#endif
+
+#if defined(RTL_CACHED_BR_STA)
+ extern struct net_device *cached_br_sta_dev;
+ extern unsigned char cached_br_sta_mac[MACADDRLEN];
+ cached_br_sta_dev = NULL;
+ memset(cached_br_sta_mac,0,MACADDRLEN);
+#endif
+
+#if defined(CONFIG_RTL_819X) && defined(__LINUX_2_6__)
+ cached_dev = NULL;
+ memset(cached_eth_addr,0,MACADDRLEN);
+#endif
+
+#ifdef CONFIG_RTL8672
+ extern void clear_cached_eth_mac_addr(void);
+ clear_cached_eth_mac_addr();
+#endif
+}
+#endif // BR_SHORTCUT
+
+
+void update_fwtbl_asoclst(struct rtl8192cd_priv *priv, struct stat_info *pstat)
+{
+ unsigned char tmpbuf[16];
+ int i;
+
+#ifdef __KERNEL__
+ struct sk_buff *skb = NULL;
+ struct wlan_ethhdr_t *e_hdr;
+ unsigned char xid_cmd[] = {0, 0, 0xaf, 0x81, 1, 2};
+
+ // update forwarding table of bridge module
+ if (priv->dev->br_port) {
+ skb = dev_alloc_skb(64);
+ if (skb != NULL) {
+ skb->dev = priv->dev;
+ skb_put(skb, 60);
+ e_hdr = (struct wlan_ethhdr_t *)skb->data;
+ memset(e_hdr, 0, 64);
+ memcpy(e_hdr->daddr, priv->dev->dev_addr, MACADDRLEN);
+ memcpy(e_hdr->saddr, pstat->hwaddr, MACADDRLEN);
+ e_hdr->type = 8;
+ memcpy(&skb->data[14], xid_cmd, sizeof(xid_cmd));
+ skb->protocol = eth_type_trans(skb, priv->dev);
+ #if defined(__LINUX_2_6__) && defined(RX_TASKLET)
+ netif_receive_skb(skb);
+ #else
+ netif_rx(skb);
+ #endif
+ }
+ }
+#endif
+
+ // update association lists of the other WLAN interfaces
+ for (i=0; i<sizeof(wlan_device)/sizeof(struct _device_info_); i++) {
+ if (wlan_device[i].priv && (wlan_device[i].priv != priv)) {
+ if (wlan_device[i].priv->pmib->dot11OperationEntry.opmode & WIFI_AP_STATE) {
+ sprintf((char *)tmpbuf, "%02x%02x%02x%02x%02x%02x",
+ pstat->hwaddr[0],pstat->hwaddr[1],pstat->hwaddr[2],pstat->hwaddr[3],pstat->hwaddr[4],pstat->hwaddr[5]);
+ del_sta(wlan_device[i].priv, tmpbuf);
+ }
+ }
+ }
+
+#ifdef MBSSID
+ if (GET_ROOT(priv)->pmib->miscEntry.vap_enable) {
+ for (i=0; i<RTL8192CD_NUM_VWLAN; i++) {
+ if (priv->pvap_priv[i] && IS_DRV_OPEN(priv->pvap_priv[i]) && (priv->pvap_priv[i] != priv) &&
+ (priv->vap_init_seq >= 0)) {
+ if (priv->pvap_priv[i]->pmib->dot11OperationEntry.opmode & WIFI_AP_STATE) {
+ sprintf(tmpbuf, "%02x%02x%02x%02x%02x%02x",
+ pstat->hwaddr[0],pstat->hwaddr[1],pstat->hwaddr[2],pstat->hwaddr[3],pstat->hwaddr[4],pstat->hwaddr[5]);
+ del_sta(priv->pvap_priv[i], tmpbuf);
+ }
+ }
+ }
+ }
+#endif
+}
+
+
+// quick fix for warn reboot fail issue
+void force_stop_wlan_hw(void)
+{
+ int i=0;
+ int temp;
+
+#if defined(CONFIG_RTL_DUAL_PCIESLOT_BIWLAN) || defined(CONFIG_RTL_DUAL_PCIESLOT_BIWLAN_D)
+ for (i=0; i<sizeof(wlan_device)/sizeof(struct _device_info_); i++)
+#endif
+ {
+ if (wlan_device[i].priv) {
+ struct rtl8192cd_priv *priv = wlan_device[i].priv;
+#ifdef PCIE_POWER_SAVING
+ if ((REG32(CLK_MANAGE) & BIT(11)) == 0)
+ {
+ extern void setBaseAddressRegister(void);
+ REG32(CLK_MANAGE) |= BIT(11);
+ delay_ms(10);
+ PCIE_reset_procedure(0, 0, 1, wlan_device[i].base_addr);
+ setBaseAddressRegister();
+ }
+#endif
+ if ( CheckNoResetHwExceptionCase(priv) ) {
+ rtl8192cd_stop_hw(priv);
+ }
+#if 0 // defined(CONFIG_RTL_92D_SUPPORT)
+ #if defined(CONFIG_RTL_8198)
+ REG32(0xb8003528)=0xb000803;
+ mdelay(100);
+ #if (RTL_USED_PCIE_SLOT==1)
+ REG32(0xb8b21008)=1;
+ mdelay(100);
+ REG32(0xb8b21008)=0x81;
+ #else
+ REG32(0xb8b01008)=1;
+ mdelay(100);
+ REG32(0xb8b01008)=0x81;
+ #endif
+ mdelay(100);
+ REG32(0xb8003528)=0xb000803;
+ mdelay(100);
+ #if (RTL_USED_PCIE_SLOT==1)
+ temp=REG32(0xb8b30000);
+ #else
+ temp=REG32(0xb8b10000);
+ #endif
+ mdelay(100);
+ temp=REG32(0xb8000054);
+ mdelay(100);
+ REG32(0xb8000054)=8;
+ mdelay(100);
+ REG32(0xb8000054)=9;
+ mdelay(100);
+ REG32(0xb8000054)=0xa;
+ mdelay(100);
+ #if (RTL_USED_PCIE_SLOT==1)
+ temp=REG32(0xb8b30000);
+ #else
+ temp=REG32(0xb8b10000);
+ #endif
+ mdelay(100);
+ #endif
+#endif
+#if 0
+//#ifdef PCIE_POWER_SAVING
+ HostPCIe_Close();
+#endif
+ }
+ }
+}
+
+
+#ifdef CONFIG_RTL8671
+/*6/7/04 hrchen, invalidate the dcache with a 0->1 transition*/
+
+#ifdef CONFIG_CPU_RLX4181
+int r3k_flush_dcache_range(int a, int b)
+{
+ int garbage_tmp;
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "mfc0 %0, $20\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "andi %0, 0xFDFF\n\t"
+ "mtc0 %0, $20\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "ori %0, 0x200\n\t"
+ "mtc0 %0, $20\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ : "=r" (garbage_tmp));
+ return 0;
+}
+#else
+int r3k_flush_dcache_range(int a, int b)
+{
+ int garbage_tmp;
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "mfc0 %0, $20\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "andi %0, 0xFFFE\n\t"
+ "mtc0 %0, $20\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "ori %0, 1\n\t"
+ "mtc0 %0, $20\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ : "=r" (garbage_tmp));
+ return 0;
+}
+#endif
+
+#ifdef _USE_DRAM_
+//init DRAM
+void r3k_enable_DRAM(void)
+{
+ int tmp, tmp1;
+ //--- initialize and start COP3
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "mfc0 %0,$12\n\t"
+ "nop\n\t"
+ "lui %1,0x8000\n\t"
+ "or %1,%0\n\t"
+ "mtc0 %1,$12\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ : "=r" (tmp), "=r" (tmp1));
+
+ //set base
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "mtc3 %0, $4 # $4: d-ram base\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :
+ : "r" (DRAM_START_ADDR&0x0fffffff));
+
+ //set size
+ __asm__ __volatile__(
+ ".set\tnoreorder\n\t"
+ ".set\tnoat\n\t"
+ "mtc3 %0, $5 # $5: d-ram top\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :
+ : "r" (R3K_DRAM_SIZE-1));
+
+ //clear DRAM
+ __asm__ __volatile__(
+"1:\n\t"
+ "sw $0,0(%1)\n\t"
+ "addiu %1,4\n\t"
+ "bne %0,%1,1b\n\t"
+ "nop\n\t"
+ ".set\tat\n\t"
+ ".set\treorder"
+ :
+ : "r" (DRAM_START_ADDR+R3K_DRAM_SIZE), "r" (DRAM_START_ADDR));
+}
+#endif // _USE_DRAM_
+#endif // CONFIG_RTL8671
+
+
+#ifdef __KERNEL__
+#if defined(CONFIG_WIRELESS_LAN_MODULE)
+MODULE_LICENSE("GPL");
+#endif
+module_init(rtl8192cd_init);
+module_exit(rtl8192cd_exit);
+#endif
+