bcmdhd wifi: update to 1.201.59.4
authorhwg <hwg@rock-chips.com>
Mon, 1 Jun 2015 07:54:19 +0000 (15:54 +0800)
committerhwg <hwg@rock-chips.com>
Mon, 1 Jun 2015 07:54:19 +0000 (15:54 +0800)
13 files changed:
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/Makefile
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_common.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/sbchipc.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/wlioctl.h
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.c

index 439ef60a1626366befa07a09265ddc943baac978..81963579c8aaa733cb1a0f53f120122a31fd8ea8 100755 (executable)
@@ -67,7 +67,7 @@ DHDCFLAGS += -DCUSTOMER_HW -DDHD_OF_SUPPORT -DGET_CUSTOM_MAC_ENABLE
 #DHDCFLAGS += -DBCMWAPI_WPI -DBCMWAPI_WAI
 #endif
 
-DHDCFLAGS += -DBAND_AG
+#DHDCFLAGS += -DBAND_AG
 
 ifeq ($(CONFIG_DHD_USE_STATIC_BUF),y)
 # add dhd_static_buf to kernel image build
@@ -83,7 +83,7 @@ ifneq ($(CONFIG_CFG80211),)
 bcmdhd-objs += wl_cfg80211.o wl_cfgp2p.o wl_linux_mon.o wl_cfg_btcoex.o
 bcmdhd-objs += dhd_cfg80211.o dhd_cfg_vendor.o
 DHDCFLAGS += -DWL_CFG80211 -DWLP2P -DWL_CFG80211_STA_EVENT -DWL_ENABLE_P2P_IF
-#DHDCFLAGS += -DWL_IFACE_COMB_NUM_CHANNELS
+DHDCFLAGS += -DWL_IFACE_COMB_NUM_CHANNELS
 DHDCFLAGS += -DCUSTOM_ROAM_TRIGGER_SETTING=-65
 DHDCFLAGS += -DCUSTOM_ROAM_DELTA_SETTING=15
 DHDCFLAGS += -DCUSTOM_KEEP_ALIVE_SETTING=28000
index cc3f16d03b1c86d3a4691f1e1c71b777ce3aa7f2..8257d6251ab48b3b530b4c7c0281434746373b93 100755 (executable)
@@ -121,7 +121,7 @@ enum dhd_op_flags {
 #define DHD_SCAN_PASSIVE_TIME          130 /* ms: Embedded default Passive setting from DHD */
 
 #ifndef POWERUP_MAX_RETRY
-#define POWERUP_MAX_RETRY      3 /* how many times we retry to power up the chip */
+#define POWERUP_MAX_RETRY      0//3 /* how many times we retry to power up the chip */
 #endif
 #ifndef POWERUP_WAIT_MS
 #define POWERUP_WAIT_MS                2000 /* ms: time out in waiting wifi to come up */
index c52b8da108dc1ddeda9b03f0cdf45b53e2347cf7..13cdf0267f1285a69e007645101e73813db41c62 100755 (executable)
@@ -2007,7 +2007,7 @@ dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_
        rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0);
        rc = rc >= 0 ? 0 : rc;
        if (rc)
-               DHD_TRACE(("%s: failed to %s pktfilter %s, retcode = %d\n",
+               DHD_ERROR(("%s: failed to %s pktfilter %s, retcode = %d\n",
                __FUNCTION__, enable?"enable":"disable", arg, rc));
        else
                DHD_TRACE(("%s: successfully %s pktfilter %s\n",
@@ -2151,7 +2151,7 @@ dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg)
        rc = rc >= 0 ? 0 : rc;
 
        if (rc)
-               DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
+               DHD_ERROR(("%s: failed to add pktfilter %s, retcode = %d\n",
                __FUNCTION__, arg, rc));
        else
                DHD_TRACE(("%s: successfully added pktfilter %s\n",
index c15b95aff6c619f7ee29d6e5e9a0962f1166c614..383b9f59e0bfdf41e6893b00e8c7b70c832712e7 100755 (executable)
 #include <dhd_config.h>\r
 #include <dhd_dbg.h>\r
 \r
-/* message levels */\r
+/* message levels */
 #define CONFIG_ERROR_LEVEL     0x0001\r
 #define CONFIG_TRACE_LEVEL     0x0002\r
-\r
+
 uint config_msg_level = CONFIG_ERROR_LEVEL;\r
-\r
+
 #define CONFIG_ERROR(x) \\r
-       do { \\r
+       do { \
                if (config_msg_level & CONFIG_ERROR_LEVEL) { \\r
                        printk(KERN_ERR "CONFIG-ERROR) ");      \\r
-                       printk x; \\r
-               } \\r
-       } while (0)\r
+                       printk x; \
+               } \
+       } while (0)
 #define CONFIG_TRACE(x) \\r
-       do { \\r
+       do { \
                if (config_msg_level & CONFIG_TRACE_LEVEL) { \\r
                        printk(KERN_ERR "CONFIG-TRACE) ");      \\r
-                       printk x; \\r
-               } \\r
+                       printk x; \
+               } \
        } while (0)\r
 \r
 #define MAXSZ_BUF              1000\r
@@ -58,6 +58,7 @@ uint config_msg_level = CONFIG_ERROR_LEVEL;
 #define BCM43241B4_CHIP_REV     5\r
 #define BCM4335A0_CHIP_REV      2\r
 #define BCM4339A0_CHIP_REV      1\r
+#define BCM43455C0_CHIP_REV     6\r
 #define BCM4354A1_CHIP_REV      1\r
 #define BCM4356A2_CHIP_REV      2\r
 \r
@@ -124,6 +125,13 @@ const static char *bcm4339a0_ag_fw_name[] = {
        "fw_bcm4339a0_ag_mfg.bin"\r
 };\r
 \r
+const static char *bcm43455c0_ag_fw_name[] = {\r
+       "fw_bcm43455c0_ag.bin",\r
+       "fw_bcm43455c0_ag_apsta.bin",\r
+       "fw_bcm43455c0_ag_p2p.bin",\r
+       "fw_bcm43455c0_ag_mfg.bin"\r
+};\r
+\r
 const static char *bcm4354a1_ag_fw_name[] = {\r
        "fw_bcm4354a1_ag.bin",\r
        "fw_bcm4354a1_ag_apsta.bin",\r
@@ -149,11 +157,11 @@ const static char *bcm4356a2_pcie_ag_fw_name[] = {
 };\r
 #endif\r
 \r
-#define htod32(i) i\r
-#define htod16(i) i\r
-#define dtoh32(i) i\r
-#define dtoh16(i) i\r
-#define htodchanspec(i) i\r
+#define htod32(i) i
+#define htod16(i) i
+#define dtoh32(i) i
+#define dtoh16(i) i
+#define htodchanspec(i) i
 #define dtohchanspec(i) i\r
 \r
 #ifdef BCMSDIO\r
@@ -173,6 +181,18 @@ dhd_conf_free_mac_list(wl_mac_list_ctrl_t *mac_list)
        mac_list->count = 0;\r
 }\r
 \r
+void\r
+dhd_conf_free_chip_nv_path_list(wl_chip_nv_path_list_ctrl_t *chip_nv_list)\r
+{\r
+       CONFIG_TRACE(("%s called\n", __FUNCTION__));\r
+\r
+       if (chip_nv_list->m_chip_nv_path_head) {\r
+               CONFIG_TRACE(("%s Free %p\n", __FUNCTION__, chip_nv_list->m_chip_nv_path_head));\r
+               kfree(chip_nv_list->m_chip_nv_path_head);\r
+       }\r
+       chip_nv_list->count = 0;\r
+}\r
+\r
 #if defined(HW_OOB)\r
 void\r
 dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip)\r
@@ -463,6 +483,10 @@ dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)
                        if (chiprev == BCM4335A0_CHIP_REV)\r
                                strcpy(&fw_path[i+1], bcm4339a0_ag_fw_name[fw_type]);\r
                        break;\r
+               case BCM4345_CHIP_ID:\r
+                       if (chiprev == BCM43455C0_CHIP_REV)\r
+                               strcpy(&fw_path[i+1], bcm43455c0_ag_fw_name[fw_type]);\r
+                       break;\r
                case BCM4339_CHIP_ID:\r
                        if (chiprev == BCM4339A0_CHIP_REV)\r
                                strcpy(&fw_path[i+1], bcm4339a0_ag_fw_name[fw_type]);\r
@@ -485,6 +509,49 @@ dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)
        printf("%s: firmware_path=%s\n", __FUNCTION__, fw_path);\r
 }\r
 \r
+void\r
+dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path)\r
+{\r
+       int matched=-1;\r
+       uint chip, chiprev;\r
+       int i;\r
+\r
+       chip = dhd->conf->chip;\r
+       chiprev = dhd->conf->chiprev;\r
+\r
+       for (i=0; i<dhd->conf->nv_by_chip.count; i++) {\r
+               if (chip==dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chip &&\r
+                               chiprev==dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chiprev) {\r
+                       matched = i;\r
+                       break;\r
+               }\r
+       }\r
+       if (matched < 0)\r
+               return;\r
+\r
+       if (nv_path[0] == '\0') {\r
+#ifdef CONFIG_BCMDHD_NVRAM_PATH\r
+               bcm_strncpy_s(nv_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_NVRAM_PATH, MOD_PARAM_PATHLEN-1);\r
+               if (nv_path[0] == '\0')\r
+#endif\r
+               {\r
+                       printf("nvram path is null\n");\r
+                       return;\r
+               }\r
+       }\r
+\r
+       /* find out the last '/' */\r
+       i = strlen(nv_path);\r
+       while (i>0){\r
+               if (nv_path[i] == '/') break;\r
+               i--;\r
+       }\r
+       \r
+       strcpy(&nv_path[i+1], dhd->conf->nv_by_chip.m_chip_nv_path_head[matched].name);\r
+\r
+       printf("%s: nvram_path=%s\n", __FUNCTION__, nv_path);\r
+}\r
+\r
 void\r
 dhd_conf_set_conf_path_by_nv_path(dhd_pub_t *dhd, char *conf_path, char *nv_path)\r
 {\r
@@ -582,10 +649,10 @@ dhd_conf_fix_country(dhd_pub_t *dhd)
        if (!(dhd && dhd->conf)) {\r
                return bcmerror;\r
        }\r
-\r
+
        memset(valid_chan_list, 0, sizeof(valid_chan_list));\r
-       list = (wl_uint32_list_t *)(void *) valid_chan_list;\r
-       list->count = htod32(WL_NUMCHANNELS);\r
+       list = (wl_uint32_list_t *)(void *) valid_chan_list;
+       list->count = htod32(WL_NUMCHANNELS);
        if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), FALSE, 0)) < 0) {\r
                CONFIG_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, bcmerror));\r
        }\r
@@ -718,25 +785,25 @@ dhd_conf_get_wme(dhd_pub_t *dhd, edcf_acparam_t *acp)
        memcpy((char*)acp, iovbuf, sizeof(edcf_acparam_t)*AC_COUNT);\r
 \r
        acparam = &acp[AC_BK];\r
-       CONFIG_TRACE(("%s: BK: aci %d aifsn %d ecwmin %d ecwmax %d size %zu\n", __FUNCTION__,\r
+       CONFIG_TRACE(("%s: BK: aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__,\r
                acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
                acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               sizeof(acp)));\r
+               (int)sizeof(acp)));\r
        acparam = &acp[AC_BE];\r
-       CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d size %zu\n", __FUNCTION__,\r
+       CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__,\r
                acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
                acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               sizeof(acp)));\r
+               (int)sizeof(acp)));\r
        acparam = &acp[AC_VI];\r
-       CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d size %zu\n", __FUNCTION__,\r
+       CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__,\r
                acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
                acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               sizeof(acp)));\r
+               (int)sizeof(acp)));\r
        acparam = &acp[AC_VO];\r
-       CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d size %zu\n", __FUNCTION__,\r
+       CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__,\r
                acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,\r
                acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               sizeof(acp)));\r
+               (int)sizeof(acp)));\r
 \r
        return;\r
 }\r
@@ -769,10 +836,10 @@ dhd_conf_update_wme(dhd_pub_t *dhd, edcf_acparam_t *acparam_cur, int aci)
        acp->ECW = ((ecwmax << EDCF_ECWMAX_SHIFT) & EDCF_ECWMAX_MASK) | (acp->ECW & EDCF_ECWMIN_MASK);\r
        acp->ECW = ((acp->ECW & EDCF_ECWMAX_MASK) | (ecwmin & EDCF_ECWMIN_MASK));\r
 \r
-       CONFIG_TRACE(("%s: mod aci %d aifsn %d ecwmin %d ecwmax %d size %zu\n", __FUNCTION__,\r
+       CONFIG_TRACE(("%s: mod aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__,\r
                acp->ACI, acp->ACI&EDCF_AIFSN_MASK,\r
                acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,\r
-               sizeof(edcf_acparam_t)));\r
+               (int)sizeof(edcf_acparam_t)));\r
 \r
        /*\r
        * Now use buf as an output buffer.\r
@@ -1053,6 +1120,16 @@ dhd_conf_set_disable_proptx(dhd_pub_t *dhd)
        disable_proptx = dhd->conf->disable_proptx;\r
 }\r
 \r
+int\r
+dhd_conf_get_pm(void *context)\r
+{\r
+       dhd_pub_t *dhd = context;\r
+\r
+       if (dhd && dhd->conf)\r
+               return dhd->conf->pm;\r
+       return -1;\r
+}\r
+\r
 unsigned int\r
 process_config_vars(char *varbuf, unsigned int len, char *pickbuf, char *param)\r
 {\r
@@ -1173,8 +1250,8 @@ dhd_conf_read_log_level(dhd_pub_t *dhd, char *bufp, uint len)
                dhd_console_ms = (int)simple_strtol(pick, NULL, 0);\r
                printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms);\r
        }\r
-}\r
-\r
+}
+
 void\r
 dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *bufp, uint len)\r
 {\r
@@ -1365,6 +1442,7 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
        bool conf_file_exists;\r
        wl_mac_list_t *mac_list;\r
        wl_mac_range_t *mac_range;\r
+       wl_chip_nv_path_t *chip_nv_path;\r
        struct dhd_conf *conf = dhd->conf;\r
 \r
        conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0'));\r
@@ -1399,7 +1477,7 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                /* Process log_level */\r
                dhd_conf_read_log_level(dhd, bufp, len);\r
                dhd_conf_read_roam_params(dhd, bufp, len);\r
-               dhd_conf_read_wme_ac_params(dhd, bufp, len);\r
+               dhd_conf_read_wme_ac_params(dhd, bufp, len);
 \r
                /* Process fw_by_mac */\r
                memset(pick, 0, MAXSZ_BUF);\r
@@ -1481,6 +1559,31 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        }\r
                }\r
 \r
+               /* Process nv_by_chip */\r
+               memset(pick, 0, MAXSZ_BUF);\r
+               len_val = process_config_vars(bufp, len, pick, "nv_by_chip=");\r
+               if (len_val) {\r
+                       pick_tmp = pick;\r
+                       pch = bcmstrtok(&pick_tmp, " ", 0);\r
+                       conf->nv_by_chip.count = (uint32)simple_strtol(pch, NULL, 0);\r
+                       if (!(chip_nv_path = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_chip.count, GFP_KERNEL))) {\r
+                               conf->nv_by_chip.count = 0;\r
+                               CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__));\r
+                       }\r
+                       printf("%s: nv_by_chip_count=%d\n", __FUNCTION__, conf->nv_by_chip.count);\r
+                       conf->nv_by_chip.m_chip_nv_path_head = chip_nv_path;\r
+                       for (i=0; i<conf->nv_by_chip.count; i++) {\r
+                               pch = bcmstrtok(&pick_tmp, " ", 0);\r
+                               chip_nv_path[i].chip = (uint32)simple_strtol(pch, NULL, 0);\r
+                               pch = bcmstrtok(&pick_tmp, " ", 0);\r
+                               chip_nv_path[i].chiprev = (uint32)simple_strtol(pch, NULL, 0);\r
+                               pch = bcmstrtok(&pick_tmp, " ", 0);\r
+                               strcpy(chip_nv_path[i].name, pch);\r
+                               printf("%s: chip=0x%x, chiprev=%d, name=%s\n", __FUNCTION__,\r
+                                       chip_nv_path[i].chip, chip_nv_path[i].chiprev, chip_nv_path[i].name);\r
+                       }\r
+               }\r
+\r
                /* Process band */\r
                memset(pick, 0, MAXSZ_BUF);\r
                len_val = process_config_vars(bufp, len, pick, "band=");\r
@@ -1647,7 +1750,7 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                len_val = process_config_vars(bufp, len, pick, "bus:txglom=");\r
                if (len_val) {\r
                        conf->bus_txglom = (int)simple_strtol(pick, NULL, 10);\r
-                       printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom);\r
+                       printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom);
                }\r
 \r
                /* Process ampdu_ba_wsize parameters */\r
@@ -1741,7 +1844,7 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                                conf->bus_rxglom = FALSE;\r
                        else\r
                                conf->bus_rxglom = TRUE;\r
-                       printf("%s: bus_rxglom = %d\n", __FUNCTION__, conf->bus_rxglom);\r
+                       printf("%s: bus:rxglom = %d\n", __FUNCTION__, conf->bus_rxglom);\r
                }\r
 \r
                /* Process deepsleep parameters */\r
@@ -1755,6 +1858,14 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
                        printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep);\r
                }\r
 \r
+               /* Process PM parameters */\r
+               memset(pick, 0, MAXSZ_BUF);\r
+               len_val = process_config_vars(bufp, len, pick, "PM=");\r
+               if (len_val) {\r
+                       conf->pm = (int)simple_strtol(pick, NULL, 10);\r
+                       printf("%s: PM = %d\n", __FUNCTION__, conf->pm);\r
+               }\r
+\r
                bcmerror = 0;\r
        } else {\r
                CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len));\r
@@ -1810,6 +1921,7 @@ dhd_conf_preinit(dhd_pub_t *dhd)
 #ifdef BCMSDIO\r
        dhd_conf_free_mac_list(&conf->fw_by_mac);\r
        dhd_conf_free_mac_list(&conf->nv_by_mac);\r
+       dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip);\r
 #endif\r
        conf->band = WLC_BAND_AUTO;\r
        conf->mimo_bw_cap = -1;\r
@@ -1844,9 +1956,9 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        conf->roam_delta[0] = 15;\r
 #endif\r
        conf->roam_delta[1] = WLC_BAND_ALL;\r
-#ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC\r
+#ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC
        conf->fullroamperiod = 60;\r
-#else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */\r
+#else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
        conf->fullroamperiod = 120;\r
 #endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */\r
 #ifdef CUSTOM_KEEP_ALIVE_SETTING\r
@@ -1877,17 +1989,17 @@ dhd_conf_preinit(dhd_pub_t *dhd)
        conf->dpc_cpucore = 0;\r
        conf->frameburst = -1;\r
        conf->deepsleep = FALSE;\r
+       conf->pm = -1;\r
        if ((conf->chip == BCM43362_CHIP_ID) || (conf->chip == BCM4330_CHIP_ID)) {\r
                conf->disable_proptx = 1;\r
                conf->use_rxchain = 0;\r
-       }\r
-    if (conf->chip == BCM43430_CHIP_ID) {\r
-        conf->use_rxchain = 0;\r
-        conf->bus_rxglom = FALSE;\r
-    }\r
+       }
        if (conf->chip == BCM4339_CHIP_ID) {\r
                conf->txbf = 1;\r
        }\r
+       if (conf->chip == BCM4345_CHIP_ID) {\r
+               conf->txbf = 1;\r
+       }\r
        if (conf->chip == BCM4354_CHIP_ID) {\r
                conf->txbf = 1;\r
        }\r
@@ -1904,6 +2016,7 @@ dhd_conf_reset(dhd_pub_t *dhd)
 #ifdef BCMSDIO\r
        dhd_conf_free_mac_list(&dhd->conf->fw_by_mac);\r
        dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);\r
+       dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);\r
 #endif\r
        memset(dhd->conf, 0, sizeof(dhd_conf_t));\r
        return 0;\r
@@ -1946,6 +2059,7 @@ dhd_conf_detach(dhd_pub_t *dhd)
 #ifdef BCMSDIO\r
                dhd_conf_free_mac_list(&dhd->conf->fw_by_mac);\r
                dhd_conf_free_mac_list(&dhd->conf->nv_by_mac);\r
+               dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip);\r
 #endif\r
                MFREE(dhd->osh, dhd->conf, sizeof(dhd_conf_t));\r
        }\r
index a74ec6ee25ba39fe2689278a8b011bb69cd717d5..09748e07df89f05398ba36007aa8afc958dab424 100755 (executable)
@@ -35,6 +35,19 @@ typedef struct wl_mac_list_ctrl {
        struct wl_mac_list *m_mac_list_head;\r
 } wl_mac_list_ctrl_t;\r
 \r
+/* chip_nv_path */\r
+typedef struct wl_chip_nv_path {\r
+       uint chip;\r
+       uint chiprev;\r
+       char name[MOD_PARAM_PATHLEN];           /* path */\r
+} wl_chip_nv_path_t;\r
+\r
+/* chip_nv_path list head */\r
+typedef struct wl_chip_nv_path_list_ctrl {\r
+       int count;\r
+       struct wl_chip_nv_path *m_chip_nv_path_head;\r
+} wl_chip_nv_path_list_ctrl_t;\r
+\r
 /* channel list */\r
 typedef struct wl_channel_list {\r
        /* in - # of channels, out - # of entries */\r
@@ -74,6 +87,7 @@ typedef struct dhd_conf {
        uint    chiprev;                /* chip revision */\r
        wl_mac_list_ctrl_t fw_by_mac;   /* Firmware auto selection by MAC */\r
        wl_mac_list_ctrl_t nv_by_mac;   /* NVRAM auto selection by MAC */\r
+       wl_chip_nv_path_list_ctrl_t nv_by_chip; /* NVRAM auto selection by chip */\r
        uint band;                      /* Band, b:2.4G only, otherwise for auto */\r
        int mimo_bw_cap;                        /* Bandwidth, 0:HT20ALL, 1: HT40ALL, 2:HT20IN2G_HT40PIN5G */\r
        wl_country_t cspec;             /* Country */\r
@@ -109,6 +123,7 @@ typedef struct dhd_conf {
        int dpc_cpucore;\r
        int frameburst;\r
        bool deepsleep;\r
+       int pm;\r
 } dhd_conf_t;\r
 \r
 #ifdef BCMSDIO\r
@@ -120,6 +135,7 @@ void dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip);
 #endif\r
 #endif\r
 void dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path);\r
+void dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path);\r
 void dhd_conf_set_conf_path_by_nv_path(dhd_pub_t *dhd, char *conf_path, char *nv_path);\r
 int dhd_conf_set_band(dhd_pub_t *dhd);\r
 uint dhd_conf_get_band(dhd_pub_t *dhd);\r
@@ -150,6 +166,7 @@ int dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path);
 int dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev);\r
 uint dhd_conf_get_chip(void *context);\r
 uint dhd_conf_get_chiprev(void *context);\r
+int dhd_conf_get_pm(void *context);\r
 int dhd_conf_preinit(dhd_pub_t *dhd);\r
 int dhd_conf_reset(dhd_pub_t *dhd);\r
 int dhd_conf_attach(dhd_pub_t *dhd);\r
index 78c84c0c01ff43ff3df6e2080bd38a8b31c9f805..ed276a73bc849063fd810cacbc43dd400b81dd6a 100755 (executable)
@@ -1635,6 +1635,10 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
        /* set specific cpucore */
        dhd_set_cpucore(dhd, TRUE);
 #endif /* CUSTOM_SET_CPUCORE */
+#ifndef SUPPORT_PM2_ONLY
+       if (dhd->conf->pm >= 0)
+               power_mode = dhd->conf->pm;
+#endif /* SUPPORT_PM2_ONLY */
        if (dhd->up) {
                if (value && dhd->in_suspend) {
 #ifdef PKT_FILTER_SUPPORT
@@ -2397,7 +2401,7 @@ dhd_os_wlfc_unblock(dhd_pub_t *pub)
 
 #endif /* PROP_TXSTATUS */
 
-#ifdef DHD_RX_DUMP
+#if defined(DHD_RX_DUMP) || defined(DHD_TX_DUMP)
 typedef struct {
        uint16 type;
        const char *str;
@@ -2425,17 +2429,19 @@ static const char *_get_packet_type_str(uint16 type)
 
        return packet_type_info[n].str;
 }
-#endif /* DHD_RX_DUMP */
+#endif /* DHD_RX_DUMP || DHD_TX_DUMP */
 
-#if defined(DHD_8021X_DUMP)
+#if defined(DHD_TX_DUMP)
 void
 dhd_tx_dump(osl_t *osh, void *pkt)
 {
        uint8 *dump_data;
        uint16 protocol;
+       struct ether_header *eh;
 
        dump_data = PKTDATA(osh, pkt);
-       protocol = (dump_data[12] << 8) | dump_data[13];
+       eh = (struct ether_header *) dump_data;
+       protocol = ntoh16(eh->ether_type);
        
        DHD_ERROR(("TX DUMP - %s\n", _get_packet_type_str(protocol)));
 
@@ -2444,22 +2450,22 @@ dhd_tx_dump(osl_t *osh, void *pkt)
                        dump_data[14], dump_data[15], dump_data[30]));
        }
 
-#if defined(DHD_TX_DUMP) && defined(DHD_TX_FULL_DUMP)
+#if defined(DHD_TX_FULL_DUMP)
        {
                int i;
                uint datalen;
                datalen = PKTLEN(osh, pkt);
 
-               for (i = 0; i < (datalen - 4); i++) {
+               for (i = 0; i < datalen; i++) {
                        DHD_ERROR(("%02X ", dump_data[i]));
                        if ((i & 15) == 15)
                                printk("\n");
                }
                DHD_ERROR(("\n"));
        }
-#endif /* DHD_TX_DUMP && DHD_TX_FULL_DUMP */
+#endif /* DHD_TX_FULL_DUMP */
 }
-#endif /* DHD_8021X_DUMP */
+#endif /* DHD_TX_DUMP */
 
 int BCMFASTPATH
 dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf)
@@ -2523,6 +2529,9 @@ dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf)
                return ret;
        }
 #endif
+#if defined(DHD_TX_DUMP)
+       dhd_tx_dump(dhdp->osh, pktbuf);
+#endif
 
 #ifdef PROP_TXSTATUS
        if (dhd_wlfc_is_supported(dhdp)) {
@@ -2547,9 +2556,7 @@ dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf)
 #ifdef WLMEDIA_HTSF
        dhd_htsf_addtxts(dhdp, pktbuf);
 #endif
-#if defined(DHD_8021X_DUMP)
-       dhd_tx_dump(dhdp->osh, pktbuf);
-#endif
+
 #ifdef PROP_TXSTATUS
        {
                if (dhd_wlfc_commit_packets(dhdp, (f_commitpkt_t)dhd_bus_txdata,
@@ -5187,7 +5194,6 @@ bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo)
        const char *conf = NULL;
        char firmware[100] = {0};
        char nvram[100] = {0};
-       //char config[100] = "";
        wifi_adapter_info_t *adapter = dhdinfo->adapter;
 
 
@@ -6321,6 +6327,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
        dhd_conf_set_lpc(dhd);
 
        /* Set PowerSave mode */
+       if (dhd->conf->pm >= 0)
+               power_mode = dhd->conf->pm;
        dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0);
 
        /* Match Host and Dongle rx alignment */
@@ -10404,5 +10412,8 @@ EXPORT_SYMBOL(SDA_function4RecvDone);
 void *dhd_get_pub(struct net_device *dev)
 {
        dhd_info_t *dhdinfo = *(dhd_info_t **)netdev_priv(dev);
-       return (void *)&dhdinfo->pub;
+       if (dhdinfo)
+               return (void *)&dhdinfo->pub;
+       else
+               return NULL;
 }
index e51f71b9ce43a47da83b8ea5f5fcac1d239e1a4f..21a9e735481d94ad83fbc2b0328449e92180dd6d 100755 (executable)
@@ -508,7 +508,8 @@ dhdpcie_dongle_attach(dhd_bus_t *bus)
                        bus->dongle_ram_base = CR4_4360_RAM_BASE;
                        break;
                case BCM4345_CHIP_ID:
-                       bus->dongle_ram_base = CR4_4345_RAM_BASE;
+                       bus->dongle_ram_base = (bus->sih->chiprev < 6)  /* changed at 4345C0 */
+                               ? CR4_4345_LT_C0_RAM_BASE : CR4_4345_GE_C0_RAM_BASE;
                        break;
                case BCM43602_CHIP_ID:
                        bus->dongle_ram_base = CR4_43602_RAM_BASE;
index f172ce283e5b8a0170f56204522f45e9b62e5f36..1a186d95ebdbf9c3d4f095497cc3aaa0ce77c476 100755 (executable)
@@ -1563,10 +1563,6 @@ dhd_bus_txdata(struct dhd_bus *bus, void *pkt)
        int ret = BCME_ERROR;
        osl_t *osh;
        uint datalen, prec;
-#if defined(DHD_TX_DUMP)
-       uint8 *dump_data;
-       uint16 protocol;
-#endif /* DHD_TX_DUMP */
 
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
@@ -1589,31 +1585,6 @@ dhd_bus_txdata(struct dhd_bus *bus, void *pkt)
        BCM_REFERENCE(datalen);
 #endif /* SDTEST */
 
-#if defined(DHD_TX_DUMP)
-       dump_data = PKTDATA(osh, pkt);
-       dump_data += 4; /* skip 4 bytes header */
-       protocol = (dump_data[12] << 8) | dump_data[13];
-
-       if (protocol == ETHER_TYPE_802_1X) {
-               DHD_ERROR(("ETHER_TYPE_802_1X [TX]: ver %d, type %d, replay %d\n",
-                       dump_data[14], dump_data[15], dump_data[30]));
-       }
-#endif /* DHD_TX_DUMP */
-
-#if defined(DHD_TX_DUMP) && defined(DHD_TX_FULL_DUMP)
-       {
-               int i;
-               DHD_ERROR(("TX DUMP\n"));
-
-               for (i = 0; i < (datalen - 4); i++) {
-                       DHD_ERROR(("%02X ", dump_data[i]));
-                       if ((i & 15) == 15)
-                               printk("\n");
-               }
-               DHD_ERROR(("\n"));
-       }
-#endif /* DHD_TX_DUMP && DHD_TX_FULL_DUMP */
-
        prec = PRIO2PREC((PKTPRIO(pkt) & PRIOMASK));
 
        /* Check for existing queue, current flow-control, pending event, or pending clock */
@@ -7423,7 +7394,8 @@ dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva,
                                bus->dongle_ram_base = CR4_4360_RAM_BASE;
                                break;
                        case BCM4345_CHIP_ID:
-                               bus->dongle_ram_base = CR4_4345_RAM_BASE;
+                               bus->dongle_ram_base = (bus->sih->chiprev < 6)  /* from 4345C0 */
+                                       ? CR4_4345_LT_C0_RAM_BASE : CR4_4345_GE_C0_RAM_BASE;
                                break;
                        case BCM4349_CHIP_GRPID:
                                bus->dongle_ram_base = CR4_4349_RAM_BASE;
@@ -7661,6 +7633,7 @@ dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh)
        dhd_conf_preinit(bus->dhd);
        dhd_conf_read_config(bus->dhd, bus->dhd->conf_path);
        dhd_conf_set_fw_name_by_chip(bus->dhd, bus->fw_path);
+       dhd_conf_set_nv_name_by_chip(bus->dhd, bus->nv_path);
        dhd_conf_set_fw_name_by_mac(bus->dhd, bus->sdh, bus->fw_path);
        dhd_conf_set_nv_name_by_mac(bus->dhd, bus->sdh, bus->nv_path);
 
index b31979bb74deb5f372d62704bdef4c366dd3f7ab..a33ded17c646950ddccde6bca8ed6c0f724b2c8f 100755 (executable)
@@ -25,6 +25,6 @@
 #define EPI_VERSION_DEV                1.201.59
 
 /* Driver Version String, ASCII, 32 chars max */
-#define        EPI_VERSION_STR         "1.201.59.3 (r506368)"
+#define        EPI_VERSION_STR         "1.201.59.4 (r506368)"
 
 #endif /* _epivers_h_ */
index 597bc752c050dc19a6f4a945980e8377315b026c..f08e98ad8e27d506f501fdcad214d32e93f514fb 100755 (executable)
@@ -2824,7 +2824,8 @@ typedef volatile struct {
 #define CCTRL2_4335_PMUWAKE            (1 << 31)
 #define PATCHTBL_SIZE                  (0x800)
 #define CR4_4335_RAM_BASE                    (0x180000)
-#define CR4_4345_RAM_BASE                    (0x1b0000)
+#define CR4_4345_LT_C0_RAM_BASE              (0x1b0000)
+#define CR4_4345_GE_C0_RAM_BASE              (0x198000)
 #define CR4_4349_RAM_BASE                    (0x180000)
 #define CR4_4350_RAM_BASE                    (0x180000)
 #define CR4_4360_RAM_BASE                    (0x0)
index 25d83f2b53407e17569e41bfa6a015f305b19011..ea727bae425c009feae8ea964823e3e312710049 100755 (executable)
@@ -2989,12 +2989,13 @@ typedef struct wl_pkt_decrypter {
  * that indicates which bits within the pattern should be matched.
  */
 typedef struct wl_pkt_filter_pattern {
-       union {
+// terence 20150525: fix pkt filter error -14 in 64bit OS
+//     union {
                uint32  offset;         /* Offset within received packet to start pattern matching.
                                 * Offset '0' is the first byte of the ethernet header.
                                 */
-               wl_pkt_decrypter_t*     decrypt_ctx;    /* Decrypt context */
-       };
+//             wl_pkt_decrypter_t*     decrypt_ctx;    /* Decrypt context */
+//     };
        uint32  size_bytes;     /* Size of the pattern.  Bitmask must be the same size. */
        uint8   mask_and_pattern[1]; /* Variable length mask and pattern data.  mask starts
                                      * at offset 0.  Pattern immediately follows mask.
index 54c9633dd68ace199c753a05fd4f703f08863dd3..cb4fc5eefa84409b7506cba2be4cf839ea94dce9 100755 (executable)
@@ -5302,6 +5302,7 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
        s32 err = 0;
        struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
        struct net_info *_net_info = wl_get_netinfo_by_netdev(cfg, dev);
+       dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
 
        RETURN_EIO_IF_NOT_UP(cfg);
        WL_DBG(("Enter\n"));
@@ -5319,6 +5320,8 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
                        dev->name, _net_info->pm_block));
                pm = PM_OFF;
        }
+       if (enabled && dhd_conf_get_pm(dhd) >= 0)
+               pm = dhd_conf_get_pm(dhd);
        pm = htod32(pm);
        WL_DBG(("%s:power save %s\n", dev->name, (pm ? "enabled" : "disabled")));
        err = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), true);
@@ -11626,6 +11629,7 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_
        u32 chan = 0;
        struct net_info *iter, *next;
        struct net_device *primary_dev = bcmcfg_to_prmry_ndev(cfg);
+       dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
        WL_DBG(("Enter state %d set %d _net_info->pm_restore %d iface %s\n",
                state, set, _net_info->pm_restore, _net_info->ndev->name));
 
@@ -11649,6 +11653,8 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_
                         */
                        if (!_net_info->pm_block && (mode == WL_MODE_BSS)) {
                                _net_info->pm = PM_FAST;
+                               if (dhd_conf_get_pm(dhd) >= 0)
+                                       _net_info->pm = dhd_conf_get_pm(dhd);
                                _net_info->pm_restore = true;
                        }
                        pm = PM_OFF;
@@ -11668,6 +11674,8 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_
                        for_each_ndev(cfg, iter, next) {
                                if (!wl_get_drv_status(cfg, CONNECTED, iter->ndev))
                                        continue;
+                               if (pm != PM_OFF && dhd_conf_get_pm(dhd) >= 0)
+                                       pm = dhd_conf_get_pm(dhd);
                                if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM, &pm,
                                        sizeof(pm), true)) != 0) {
                                        if (err == -ENODEV)
@@ -11705,6 +11713,8 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_
                        for_each_ndev(cfg, iter, next) {
                                if (!wl_get_drv_status(cfg, CONNECTED, iter->ndev))
                                        continue;
+                               if (pm != PM_OFF && dhd_conf_get_pm(dhd) >= 0)
+                                       pm = dhd_conf_get_pm(dhd);
                                if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM, &pm,
                                        sizeof(pm), true)) != 0) {
                                        if (err == -ENODEV)
@@ -11742,6 +11752,8 @@ static s32 wl_notifier_change_state(struct bcm_cfg80211 *cfg, struct net_info *_
                        if (iter->pm_restore && iter->pm) {
                                WL_DBG(("%s:restoring power save %s\n",
                                        iter->ndev->name, (iter->pm ? "enabled" : "disabled")));
+                               if (iter->pm != PM_OFF && dhd_conf_get_pm(dhd) >= 0)
+                                       iter->pm = dhd_conf_get_pm(dhd);
                                err = wldev_ioctl(iter->ndev,
                                        WLC_SET_PM, &iter->pm, sizeof(iter->pm), true);
                                if (unlikely(err)) {
@@ -12118,7 +12130,7 @@ static void wl_wakeup_event(struct bcm_cfg80211 *cfg)
        }
 }
 
-#if defined(P2PONEINT)
+#if defined(P2PONEINT) || defined(WL_ENABLE_P2P_IF)
 static int wl_is_p2p_event(struct wl_event_q *e)
 {
        struct bcm_cfg80211 *cfg = g_bcm_cfg;
@@ -12165,7 +12177,7 @@ static int wl_is_p2p_event(struct wl_event_q *e)
                        return FALSE;
        }
 }
-#endif 
+#endif
 
 static s32 wl_event_handler(void *data)
 {
@@ -12220,7 +12232,9 @@ static s32 wl_event_handler(void *data)
 #endif
                        }
 #elif defined(WL_ENABLE_P2P_IF)
-                       if (WL_IS_P2P_DEV_EVENT(e) && (cfg->p2p_net)) {
+                       // terence 20150116: fix for p2p connection in kernel 3.4
+//                     if (WL_IS_P2P_DEV_EVENT(e) && (cfg->p2p_net)) {
+                       if ((wl_is_p2p_event(e) == TRUE) && (cfg->p2p_net)) {
                                cfgdev = cfg->p2p_net;
                        } else {
                                cfgdev = dhd_idx2net((struct dhd_pub *)(cfg->pub),
@@ -12231,7 +12245,7 @@ static s32 wl_event_handler(void *data)
                        if (!cfgdev) {
 #if defined(WL_CFG80211_P2P_DEV_IF)
                                cfgdev = bcmcfg_to_prmry_wdev(cfg);
-#elif defined(WL_ENABLE_P2P_IF)
+#else
                                cfgdev = bcmcfg_to_prmry_ndev(cfg);
 #endif /* WL_CFG80211_P2P_DEV_IF */
                        }
@@ -15302,6 +15316,7 @@ static void wl_cfg80211_work_handler(struct work_struct * work)
        struct net_info *iter, *next;
        s32 err = BCME_OK;
        s32 pm = PM_FAST;
+       dhd_pub_t *dhd;
 
        cfg = container_of(work, struct bcm_cfg80211, pm_enable_work.work);
        WL_DBG(("Enter \n"));
@@ -15312,6 +15327,9 @@ static void wl_cfg80211_work_handler(struct work_struct * work)
                                (wl_get_mode_by_netdev(cfg, iter->ndev) != WL_MODE_BSS))
                                continue;
                        if (iter->ndev) {
+                               dhd = (dhd_pub_t *)(cfg->pub);
+                               if (pm != PM_OFF && dhd_conf_get_pm(dhd) >= 0)
+                                       pm = dhd_conf_get_pm(dhd);
                                if ((err = wldev_ioctl(iter->ndev, WLC_SET_PM,
                                        &pm, sizeof(pm), true)) != 0) {
                                        if (err == -ENODEV)
index 339fa7aa65e8c74eef61a2ea9f4c22643e95480b..219c1df032111829298aec2dfeb8de1e4ef5351a 100755 (executable)
@@ -22,6 +22,7 @@
 
 typedef const struct si_pub    si_t;
 #include <wlioctl.h>
+#include <wl_android.h>
 
 
 /* message levels */
@@ -599,9 +600,12 @@ wl_iw_set_freq(
 
                chan = wf_mhz2channel(fwrq->m, sf);
        }
+       WL_ERROR(("%s: chan=%d\n", __FUNCTION__, chan));
        chan = htod32(chan);
-       if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan))))
+       if ((error = dev_wlc_ioctl(dev, WLC_SET_CHANNEL, &chan, sizeof(chan)))) {
+               WL_ERROR(("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error));
                return error;
+       }
 
        /* -EINPROGRESS: Call commit handler */
        return -EINPROGRESS;
@@ -993,6 +997,7 @@ wl_iw_set_wap(
        if (ETHER_ISBCAST(awrq->sa_data) || ETHER_ISNULLADDR(awrq->sa_data)) {
                scb_val_t scbval;
                bzero(&scbval, sizeof(scb_val_t));
+               WL_ERROR(("%s: WLC_DISASSOC\n", __FUNCTION__));
                if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) {
                        WL_ERROR(("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error));
                }
@@ -1006,6 +1011,7 @@ wl_iw_set_wap(
                WL_ERROR(("%s: WLC_REASSOC failed (%d).\n", __FUNCTION__, error));
                return error;
        }
+       WL_ERROR(("%s: join BSSID="MACSTR"\n", __FUNCTION__, MAC2STR((u8 *)awrq->sa_data)));
 
        return 0;
 }
@@ -1085,6 +1091,7 @@ wl_iw_get_aplist(
        wl_bss_info_t *bi = NULL;
        int error, i;
        uint buflen = dwrq->length;
+       int16 rssi;
 
        WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name));
 
@@ -1119,8 +1126,10 @@ wl_iw_get_aplist(
                /* BSSID */
                memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN);
                addr[dwrq->length].sa_family = ARPHRD_ETHER;
-               qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI));
-               qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI);
+               // terence 20150419: limit the max. rssi to -2 or the bss will be filtered out in android OS
+               rssi = MIN(dtoh16(bi->RSSI), RSSI_MAXVAL);
+               qual[dwrq->length].qual = rssi_to_qual(rssi);
+               qual[dwrq->length].level = 0x100 + rssi;
                qual[dwrq->length].noise = 0x100 + bi->phy_noise;
 
                /* Updated qual, level, and noise */
@@ -1160,6 +1169,7 @@ wl_iw_iscan_get_aplist(
        struct iw_quality qual[IW_MAX_AP];
        wl_bss_info_t *bi = NULL;
        int i;
+       int16 rssi;
 
        WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name));
 
@@ -1189,8 +1199,10 @@ wl_iw_iscan_get_aplist(
                /* BSSID */
                memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN);
                addr[dwrq->length].sa_family = ARPHRD_ETHER;
-               qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI));
-               qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI);
+               // terence 20150419: limit the max. rssi to -2 or the bss will be filtered out in android OS
+               rssi = MIN(dtoh16(bi->RSSI), RSSI_MAXVAL);
+               qual[dwrq->length].qual = rssi_to_qual(rssi);
+               qual[dwrq->length].level = 0x100 + rssi;
                qual[dwrq->length].noise = 0x100 + bi->phy_noise;
 
                /* Updated qual, level, and noise */
@@ -1497,6 +1509,8 @@ wl_iw_get_scan(
        int error, i, j;
        char *event = extra, *end = extra + dwrq->length, *value;
        uint buflen = dwrq->length;
+       int16 rssi;
+       int channel;
 
        WL_TRACE(("%s: %s SIOCGIWSCAN\n", __FUNCTION__, dev->name));
 
@@ -1531,12 +1545,11 @@ wl_iw_get_scan(
                ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list +
                        buflen));
 
-{
-               int channel;
+               // terence 20150419: limit the max. rssi to -2 or the bss will be filtered out in android OS
+               rssi = MIN(dtoh16(bi->RSSI), RSSI_MAXVAL);
                channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch;
                WL_SCAN(("%s: BSSID="MACSTR", channel=%d, RSSI=%d, merge broadcast SSID=\"%s\"\n",
-               __FUNCTION__, MAC2STR(bi->BSSID.octet), channel, dtoh16(bi->RSSI), bi->SSID));
-}
+               __FUNCTION__, MAC2STR(bi->BSSID.octet), channel, rssi, bi->SSID));
 
                /* First entry must be the BSSID */
                iwe.cmd = SIOCGIWAP;
@@ -1562,8 +1575,7 @@ wl_iw_get_scan(
 
                /* Channel */
                iwe.cmd = SIOCGIWFREQ;
-
-               iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec),
+               iwe.u.freq.m = wf_channel2mhz(channel,
                        (CHSPEC_IS2G(bi->chanspec)) ?
                        WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G);
                iwe.u.freq.e = 6;
@@ -1571,8 +1583,8 @@ wl_iw_get_scan(
 
                /* Channel quality */
                iwe.cmd = IWEVQUAL;
-               iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI));
-               iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI);
+               iwe.u.qual.qual = rssi_to_qual(rssi);
+               iwe.u.qual.level = 0x100 + rssi;
                iwe.u.qual.noise = 0x100 + bi->phy_noise;
                event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN);
 
@@ -1627,6 +1639,8 @@ wl_iw_iscan_get_scan(
        char *event = extra, *end = extra + dwrq->length, *value;
        iscan_info_t *iscan = g_iscan;
        iscan_buf_t * p_buf;
+       int16 rssi;
+       int channel;
 
        WL_TRACE(("%s: %s SIOCGIWSCAN\n", __FUNCTION__, dev->name));
 
@@ -1639,103 +1653,105 @@ wl_iw_iscan_get_scan(
        }
 
        /* Check for scan in progress */
-       if (iscan->iscan_state == ISCAN_STATE_SCANING)
+       if (iscan->iscan_state == ISCAN_STATE_SCANING) {
+               WL_TRACE(("%s: SIOCGIWSCAN GET still scanning\n", dev->name));
                return -EAGAIN;
+       }
 
        apcnt = 0;
        p_buf = iscan->list_hdr;
        /* Get scan results */
        while (p_buf != iscan->list_cur) {
-           list = &((wl_iscan_results_t*)p_buf->iscan_buf)->results;
-
-           if (list->version != WL_BSS_INFO_VERSION) {
-               WL_ERROR(("list->version %d != WL_BSS_INFO_VERSION\n", list->version));
-           }
-
-           bi = NULL;
-           for (ii = 0; ii < list->count && apcnt < IW_MAX_AP; apcnt++, ii++) {
-               bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info;
-               ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list +
-                       WLC_IW_ISCAN_MAXLEN));
-
-               /* overflow check cover fields before wpa IEs */
-               if (event + ETHER_ADDR_LEN + bi->SSID_len + IW_EV_UINT_LEN + IW_EV_FREQ_LEN +
-                       IW_EV_QUAL_LEN >= end)
-                       return -E2BIG;
-{
-               int channel;
-               channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch;
-               WL_SCAN(("%s: BSSID="MACSTR", channel=%d, RSSI=%d, merge broadcast SSID=\"%s\"\n",
-               __FUNCTION__, MAC2STR(bi->BSSID.octet), channel, dtoh16(bi->RSSI), bi->SSID));
-}
-               /* First entry must be the BSSID */
-               iwe.cmd = SIOCGIWAP;
-               iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-               memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN);
-               event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN);
+               list = &((wl_iscan_results_t*)p_buf->iscan_buf)->results;
 
-               /* SSID */
-               iwe.u.data.length = dtoh32(bi->SSID_len);
-               iwe.cmd = SIOCGIWESSID;
-               iwe.u.data.flags = 1;
-               event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID);
-
-               /* Mode */
-               if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) {
-                       iwe.cmd = SIOCGIWMODE;
-                       if (dtoh16(bi->capability) & DOT11_CAP_ESS)
-                               iwe.u.mode = IW_MODE_INFRA;
-                       else
-                               iwe.u.mode = IW_MODE_ADHOC;
-                       event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN);
+               if (list->version != WL_BSS_INFO_VERSION) {
+                       WL_ERROR(("list->version %d != WL_BSS_INFO_VERSION\n", list->version));
                }
 
-               /* Channel */
-               iwe.cmd = SIOCGIWFREQ;
+               bi = NULL;
+               for (ii = 0; ii < list->count && apcnt < IW_MAX_AP; apcnt++, ii++) {
+                       bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : list->bss_info;
+                       ASSERT(((uintptr)bi + dtoh32(bi->length)) <= ((uintptr)list +
+                               WLC_IW_ISCAN_MAXLEN));
 
-               iwe.u.freq.m = wf_channel2mhz(CHSPEC_CHANNEL(bi->chanspec),
-                       (CHSPEC_IS2G(bi->chanspec)) ?
-                       WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G);
-               iwe.u.freq.e = 6;
-               event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN);
-
-               /* Channel quality */
-               iwe.cmd = IWEVQUAL;
-               iwe.u.qual.qual = rssi_to_qual(dtoh16(bi->RSSI));
-               iwe.u.qual.level = 0x100 + dtoh16(bi->RSSI);
-               iwe.u.qual.noise = 0x100 + bi->phy_noise;
-               event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN);
-
-               /* WPA, WPA2, WPS, WAPI IEs */
-               wl_iw_handle_scanresults_ies(&event, end, info, bi);
-
-               /* Encryption */
-               iwe.cmd = SIOCGIWENCODE;
-               if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY)
-                       iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-               else
-                       iwe.u.data.flags = IW_ENCODE_DISABLED;
-               iwe.u.data.length = 0;
-               event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event);
-
-               /* Rates */
-               if (bi->rateset.count <= sizeof(bi->rateset.rates)) {
-                       if (event + IW_MAX_BITRATES*IW_EV_PARAM_LEN >= end)
+                       /* overflow check cover fields before wpa IEs */
+                       if (event + ETHER_ADDR_LEN + bi->SSID_len + IW_EV_UINT_LEN + IW_EV_FREQ_LEN +
+                               IW_EV_QUAL_LEN >= end)
                                return -E2BIG;
 
-                       value = event + IW_EV_LCP_LEN;
-                       iwe.cmd = SIOCGIWRATE;
-                       /* Those two flags are ignored... */
-                       iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-                       for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) {
-                               iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000;
-                               value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe,
-                                       IW_EV_PARAM_LEN);
+                       // terence 20150419: limit the max. rssi to -2 or the bss will be filtered out in android OS
+                       rssi = MIN(dtoh16(bi->RSSI), RSSI_MAXVAL);
+                       channel = (bi->ctl_ch == 0) ? CHSPEC_CHANNEL(bi->chanspec) : bi->ctl_ch;
+                       WL_SCAN(("%s: BSSID="MACSTR", channel=%d, RSSI=%d, merge broadcast SSID=\"%s\"\n",
+                       __FUNCTION__, MAC2STR(bi->BSSID.octet), channel, rssi, bi->SSID));
+
+                       /* First entry must be the BSSID */
+                       iwe.cmd = SIOCGIWAP;
+                       iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+                       memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN);
+                       event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN);
+
+                       /* SSID */
+                       iwe.u.data.length = dtoh32(bi->SSID_len);
+                       iwe.cmd = SIOCGIWESSID;
+                       iwe.u.data.flags = 1;
+                       event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, bi->SSID);
+
+                       /* Mode */
+                       if (dtoh16(bi->capability) & (DOT11_CAP_ESS | DOT11_CAP_IBSS)) {
+                               iwe.cmd = SIOCGIWMODE;
+                               if (dtoh16(bi->capability) & DOT11_CAP_ESS)
+                                       iwe.u.mode = IW_MODE_INFRA;
+                               else
+                                       iwe.u.mode = IW_MODE_ADHOC;
+                               event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_UINT_LEN);
+                       }
+
+                       /* Channel */
+                       iwe.cmd = SIOCGIWFREQ;
+                       iwe.u.freq.m = wf_channel2mhz(channel,
+                               (CHSPEC_IS2G(bi->chanspec)) ?
+                               WF_CHAN_FACTOR_2_4_G : WF_CHAN_FACTOR_5_G);
+                       iwe.u.freq.e = 6;
+                       event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_FREQ_LEN);
+
+                       /* Channel quality */
+                       iwe.cmd = IWEVQUAL;
+                       iwe.u.qual.qual = rssi_to_qual(rssi);
+                       iwe.u.qual.level = 0x100 + rssi;
+                       iwe.u.qual.noise = 0x100 + bi->phy_noise;
+                       event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_QUAL_LEN);
+
+                       /* WPA, WPA2, WPS, WAPI IEs */
+                       wl_iw_handle_scanresults_ies(&event, end, info, bi);
+
+                       /* Encryption */
+                       iwe.cmd = SIOCGIWENCODE;
+                       if (dtoh16(bi->capability) & DOT11_CAP_PRIVACY)
+                               iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+                       else
+                               iwe.u.data.flags = IW_ENCODE_DISABLED;
+                       iwe.u.data.length = 0;
+                       event = IWE_STREAM_ADD_POINT(info, event, end, &iwe, (char *)event);
+
+                       /* Rates */
+                       if (bi->rateset.count <= sizeof(bi->rateset.rates)) {
+                               if (event + IW_MAX_BITRATES*IW_EV_PARAM_LEN >= end)
+                                       return -E2BIG;
+
+                               value = event + IW_EV_LCP_LEN;
+                               iwe.cmd = SIOCGIWRATE;
+                               /* Those two flags are ignored... */
+                               iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+                               for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) {
+                                       iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000;
+                                       value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe,
+                                               IW_EV_PARAM_LEN);
+                               }
+                               event = value;
                        }
-                       event = value;
                }
-           }
-           p_buf = p_buf->next;
+               p_buf = p_buf->next;
        } /* while (p_buf) */
 
        dwrq->length = event - extra;
@@ -1771,15 +1787,21 @@ wl_iw_set_essid(
                memcpy(ssid.SSID, extra, ssid.SSID_len);
                ssid.SSID_len = htod32(ssid.SSID_len);
 
-               if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid))))
+               if ((error = dev_wlc_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid)))) {
+                       WL_ERROR(("%s: WLC_SET_SSID failed (%d).\n", __FUNCTION__, error));
                        return error;
+               }
+               WL_ERROR(("%s: join SSID=%s\n", __FUNCTION__, ssid.SSID));
        }
        /* If essid null then it is "iwconfig <interface> essid off" command */
        else {
                scb_val_t scbval;
                bzero(&scbval, sizeof(scb_val_t));
-               if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t))))
+               WL_ERROR(("%s: WLC_DISASSOC\n", __FUNCTION__));
+               if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) {
+                       WL_ERROR(("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error));
                        return error;
+               }
        }
        return 0;
 }
@@ -3396,8 +3418,13 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
                cmd = SIOCGIWAP;
                wrqu.data.length = strlen(extra);
                if (!(flags & WLC_EVENT_MSG_LINK)) {
+                       printk("%s: Link Down with BSSID="MACSTR"\n", __FUNCTION__,
+                               MAC2STR((u8 *)wrqu.addr.sa_data));
                        bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
                        bzero(&extra, ETHER_ADDR_LEN);
+               } else {
+                       printk("%s: Link UP with BSSID="MACSTR"\n", __FUNCTION__,
+                               MAC2STR((u8 *)wrqu.addr.sa_data));
                }
                break;
        case WLC_E_ACTION_FRAME:
@@ -3495,9 +3522,11 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
        }
 
        if (cmd) {
-               if (cmd == SIOCGIWSCAN)
-                       wireless_send_event(dev, cmd, &wrqu, NULL);
-               else
+               if (cmd == SIOCGIWSCAN) {
+                       if ((!g_iscan) || (g_iscan->sysioc_pid < 0)) {
+                               wireless_send_event(dev, cmd, &wrqu, NULL);
+                       };
+               } else
                        wireless_send_event(dev, cmd, &wrqu, extra);
        }
 
@@ -3754,6 +3783,7 @@ _iscan_sysioc_thread(void *data)
        uint32 status;
        iscan_info_t *iscan = (iscan_info_t *)data;
 
+       printk("%s: thread Enter\n", __FUNCTION__);
        DAEMONIZE("iscan_sysioc");
 
        status = WL_SCAN_RESULTS_PARTIAL;
@@ -3809,6 +3839,7 @@ _iscan_sysioc_thread(void *data)
                                break;
                 }
        }
+       printk("%s: was terminated\n", __FUNCTION__);
        complete_and_exit(&iscan->sysioc_exited, 0);
 }