From a9f10c019204c03f01ad37fd13501eaf4c4e7e52 Mon Sep 17 00:00:00 2001 From: hwg Date: Mon, 1 Jun 2015 15:54:19 +0800 Subject: [PATCH] bcmdhd wifi: update to 1.201.59.4 --- .../rockchip_wlan/rkwifi/bcmdhd/Makefile | 4 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd.h | 2 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd_common.c | 4 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd_config.c | 194 ++++++++++++--- .../rockchip_wlan/rkwifi/bcmdhd/dhd_config.h | 17 ++ .../rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c | 37 ++- .../rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.c | 3 +- .../rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c | 33 +-- .../rkwifi/bcmdhd/include/epivers.h | 2 +- .../rkwifi/bcmdhd/include/sbchipc.h | 3 +- .../rkwifi/bcmdhd/include/wlioctl.h | 7 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c | 26 +- .../rockchip_wlan/rkwifi/bcmdhd/wl_iw.c | 233 ++++++++++-------- 13 files changed, 366 insertions(+), 199 deletions(-) diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/Makefile b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/Makefile index 439ef60a1626..81963579c8aa 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/Makefile +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/Makefile @@ -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 diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd.h index cc3f16d03b1c..8257d6251ab4 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd.h @@ -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 */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_common.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_common.c index c52b8da108dc..13cdf0267f12 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_common.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_common.c @@ -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", diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.c index c15b95aff6c6..383b9f59e0bf 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.c @@ -14,25 +14,25 @@ #include #include -/* message levels */ +/* message levels */ #define CONFIG_ERROR_LEVEL 0x0001 #define CONFIG_TRACE_LEVEL 0x0002 - + uint config_msg_level = CONFIG_ERROR_LEVEL; - + #define CONFIG_ERROR(x) \ - do { \ + do { \ if (config_msg_level & CONFIG_ERROR_LEVEL) { \ printk(KERN_ERR "CONFIG-ERROR) "); \ - printk x; \ - } \ - } while (0) + printk x; \ + } \ + } while (0) #define CONFIG_TRACE(x) \ - do { \ + do { \ if (config_msg_level & CONFIG_TRACE_LEVEL) { \ printk(KERN_ERR "CONFIG-TRACE) "); \ - printk x; \ - } \ + printk x; \ + } \ } while (0) #define MAXSZ_BUF 1000 @@ -58,6 +58,7 @@ uint config_msg_level = CONFIG_ERROR_LEVEL; #define BCM43241B4_CHIP_REV 5 #define BCM4335A0_CHIP_REV 2 #define BCM4339A0_CHIP_REV 1 +#define BCM43455C0_CHIP_REV 6 #define BCM4354A1_CHIP_REV 1 #define BCM4356A2_CHIP_REV 2 @@ -124,6 +125,13 @@ const static char *bcm4339a0_ag_fw_name[] = { "fw_bcm4339a0_ag_mfg.bin" }; +const static char *bcm43455c0_ag_fw_name[] = { + "fw_bcm43455c0_ag.bin", + "fw_bcm43455c0_ag_apsta.bin", + "fw_bcm43455c0_ag_p2p.bin", + "fw_bcm43455c0_ag_mfg.bin" +}; + const static char *bcm4354a1_ag_fw_name[] = { "fw_bcm4354a1_ag.bin", "fw_bcm4354a1_ag_apsta.bin", @@ -149,11 +157,11 @@ const static char *bcm4356a2_pcie_ag_fw_name[] = { }; #endif -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i -#define htodchanspec(i) i +#define htod32(i) i +#define htod16(i) i +#define dtoh32(i) i +#define dtoh16(i) i +#define htodchanspec(i) i #define dtohchanspec(i) i #ifdef BCMSDIO @@ -173,6 +181,18 @@ dhd_conf_free_mac_list(wl_mac_list_ctrl_t *mac_list) mac_list->count = 0; } +void +dhd_conf_free_chip_nv_path_list(wl_chip_nv_path_list_ctrl_t *chip_nv_list) +{ + CONFIG_TRACE(("%s called\n", __FUNCTION__)); + + if (chip_nv_list->m_chip_nv_path_head) { + CONFIG_TRACE(("%s Free %p\n", __FUNCTION__, chip_nv_list->m_chip_nv_path_head)); + kfree(chip_nv_list->m_chip_nv_path_head); + } + chip_nv_list->count = 0; +} + #if defined(HW_OOB) void dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip) @@ -463,6 +483,10 @@ dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path) if (chiprev == BCM4335A0_CHIP_REV) strcpy(&fw_path[i+1], bcm4339a0_ag_fw_name[fw_type]); break; + case BCM4345_CHIP_ID: + if (chiprev == BCM43455C0_CHIP_REV) + strcpy(&fw_path[i+1], bcm43455c0_ag_fw_name[fw_type]); + break; case BCM4339_CHIP_ID: if (chiprev == BCM4339A0_CHIP_REV) strcpy(&fw_path[i+1], bcm4339a0_ag_fw_name[fw_type]); @@ -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); } +void +dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path) +{ + int matched=-1; + uint chip, chiprev; + int i; + + chip = dhd->conf->chip; + chiprev = dhd->conf->chiprev; + + for (i=0; iconf->nv_by_chip.count; i++) { + if (chip==dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chip && + chiprev==dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chiprev) { + matched = i; + break; + } + } + if (matched < 0) + return; + + if (nv_path[0] == '\0') { +#ifdef CONFIG_BCMDHD_NVRAM_PATH + bcm_strncpy_s(nv_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_NVRAM_PATH, MOD_PARAM_PATHLEN-1); + if (nv_path[0] == '\0') +#endif + { + printf("nvram path is null\n"); + return; + } + } + + /* find out the last '/' */ + i = strlen(nv_path); + while (i>0){ + if (nv_path[i] == '/') break; + i--; + } + + strcpy(&nv_path[i+1], dhd->conf->nv_by_chip.m_chip_nv_path_head[matched].name); + + printf("%s: nvram_path=%s\n", __FUNCTION__, nv_path); +} + void dhd_conf_set_conf_path_by_nv_path(dhd_pub_t *dhd, char *conf_path, char *nv_path) { @@ -582,10 +649,10 @@ dhd_conf_fix_country(dhd_pub_t *dhd) if (!(dhd && dhd->conf)) { return bcmerror; } - + memset(valid_chan_list, 0, sizeof(valid_chan_list)); - list = (wl_uint32_list_t *)(void *) valid_chan_list; - list->count = htod32(WL_NUMCHANNELS); + 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) { CONFIG_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, bcmerror)); } @@ -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); acparam = &acp[AC_BK]; - CONFIG_TRACE(("%s: BK: aci %d aifsn %d ecwmin %d ecwmax %d size %zu\n", __FUNCTION__, + CONFIG_TRACE(("%s: BK: aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__, acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, - sizeof(acp))); + (int)sizeof(acp))); acparam = &acp[AC_BE]; - CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d size %zu\n", __FUNCTION__, + CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__, acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, - sizeof(acp))); + (int)sizeof(acp))); acparam = &acp[AC_VI]; - CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d size %zu\n", __FUNCTION__, + CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__, acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, - sizeof(acp))); + (int)sizeof(acp))); acparam = &acp[AC_VO]; - CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d size %zu\n", __FUNCTION__, + CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__, acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, - sizeof(acp))); + (int)sizeof(acp))); return; } @@ -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); acp->ECW = ((acp->ECW & EDCF_ECWMAX_MASK) | (ecwmin & EDCF_ECWMIN_MASK)); - CONFIG_TRACE(("%s: mod aci %d aifsn %d ecwmin %d ecwmax %d size %zu\n", __FUNCTION__, + CONFIG_TRACE(("%s: mod aci %d aifsn %d ecwmin %d ecwmax %d size %d\n", __FUNCTION__, acp->ACI, acp->ACI&EDCF_AIFSN_MASK, acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, - sizeof(edcf_acparam_t))); + (int)sizeof(edcf_acparam_t))); /* * Now use buf as an output buffer. @@ -1053,6 +1120,16 @@ dhd_conf_set_disable_proptx(dhd_pub_t *dhd) disable_proptx = dhd->conf->disable_proptx; } +int +dhd_conf_get_pm(void *context) +{ + dhd_pub_t *dhd = context; + + if (dhd && dhd->conf) + return dhd->conf->pm; + return -1; +} + unsigned int process_config_vars(char *varbuf, unsigned int len, char *pickbuf, char *param) { @@ -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); printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms); } -} - +} + void dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *bufp, uint len) { @@ -1365,6 +1442,7 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path) bool conf_file_exists; wl_mac_list_t *mac_list; wl_mac_range_t *mac_range; + wl_chip_nv_path_t *chip_nv_path; struct dhd_conf *conf = dhd->conf; conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0')); @@ -1399,7 +1477,7 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path) /* Process log_level */ dhd_conf_read_log_level(dhd, bufp, len); dhd_conf_read_roam_params(dhd, bufp, len); - dhd_conf_read_wme_ac_params(dhd, bufp, len); + dhd_conf_read_wme_ac_params(dhd, bufp, len); /* Process fw_by_mac */ memset(pick, 0, MAXSZ_BUF); @@ -1481,6 +1559,31 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path) } } + /* Process nv_by_chip */ + memset(pick, 0, MAXSZ_BUF); + len_val = process_config_vars(bufp, len, pick, "nv_by_chip="); + if (len_val) { + pick_tmp = pick; + pch = bcmstrtok(&pick_tmp, " ", 0); + conf->nv_by_chip.count = (uint32)simple_strtol(pch, NULL, 0); + if (!(chip_nv_path = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_chip.count, GFP_KERNEL))) { + conf->nv_by_chip.count = 0; + CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); + } + printf("%s: nv_by_chip_count=%d\n", __FUNCTION__, conf->nv_by_chip.count); + conf->nv_by_chip.m_chip_nv_path_head = chip_nv_path; + for (i=0; inv_by_chip.count; i++) { + pch = bcmstrtok(&pick_tmp, " ", 0); + chip_nv_path[i].chip = (uint32)simple_strtol(pch, NULL, 0); + pch = bcmstrtok(&pick_tmp, " ", 0); + chip_nv_path[i].chiprev = (uint32)simple_strtol(pch, NULL, 0); + pch = bcmstrtok(&pick_tmp, " ", 0); + strcpy(chip_nv_path[i].name, pch); + printf("%s: chip=0x%x, chiprev=%d, name=%s\n", __FUNCTION__, + chip_nv_path[i].chip, chip_nv_path[i].chiprev, chip_nv_path[i].name); + } + } + /* Process band */ memset(pick, 0, MAXSZ_BUF); len_val = process_config_vars(bufp, len, pick, "band="); @@ -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="); if (len_val) { conf->bus_txglom = (int)simple_strtol(pick, NULL, 10); - printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom); + printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom); } /* Process ampdu_ba_wsize parameters */ @@ -1741,7 +1844,7 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path) conf->bus_rxglom = FALSE; else conf->bus_rxglom = TRUE; - printf("%s: bus_rxglom = %d\n", __FUNCTION__, conf->bus_rxglom); + printf("%s: bus:rxglom = %d\n", __FUNCTION__, conf->bus_rxglom); } /* Process deepsleep parameters */ @@ -1755,6 +1858,14 @@ dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path) printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep); } + /* Process PM parameters */ + memset(pick, 0, MAXSZ_BUF); + len_val = process_config_vars(bufp, len, pick, "PM="); + if (len_val) { + conf->pm = (int)simple_strtol(pick, NULL, 10); + printf("%s: PM = %d\n", __FUNCTION__, conf->pm); + } + bcmerror = 0; } else { CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len)); @@ -1810,6 +1921,7 @@ dhd_conf_preinit(dhd_pub_t *dhd) #ifdef BCMSDIO dhd_conf_free_mac_list(&conf->fw_by_mac); dhd_conf_free_mac_list(&conf->nv_by_mac); + dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip); #endif conf->band = WLC_BAND_AUTO; conf->mimo_bw_cap = -1; @@ -1844,9 +1956,9 @@ dhd_conf_preinit(dhd_pub_t *dhd) conf->roam_delta[0] = 15; #endif conf->roam_delta[1] = WLC_BAND_ALL; -#ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC +#ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC conf->fullroamperiod = 60; -#else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ +#else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ conf->fullroamperiod = 120; #endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ #ifdef CUSTOM_KEEP_ALIVE_SETTING @@ -1877,17 +1989,17 @@ dhd_conf_preinit(dhd_pub_t *dhd) conf->dpc_cpucore = 0; conf->frameburst = -1; conf->deepsleep = FALSE; + conf->pm = -1; if ((conf->chip == BCM43362_CHIP_ID) || (conf->chip == BCM4330_CHIP_ID)) { conf->disable_proptx = 1; conf->use_rxchain = 0; - } - if (conf->chip == BCM43430_CHIP_ID) { - conf->use_rxchain = 0; - conf->bus_rxglom = FALSE; - } + } if (conf->chip == BCM4339_CHIP_ID) { conf->txbf = 1; } + if (conf->chip == BCM4345_CHIP_ID) { + conf->txbf = 1; + } if (conf->chip == BCM4354_CHIP_ID) { conf->txbf = 1; } @@ -1904,6 +2016,7 @@ dhd_conf_reset(dhd_pub_t *dhd) #ifdef BCMSDIO dhd_conf_free_mac_list(&dhd->conf->fw_by_mac); dhd_conf_free_mac_list(&dhd->conf->nv_by_mac); + dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip); #endif memset(dhd->conf, 0, sizeof(dhd_conf_t)); return 0; @@ -1946,6 +2059,7 @@ dhd_conf_detach(dhd_pub_t *dhd) #ifdef BCMSDIO dhd_conf_free_mac_list(&dhd->conf->fw_by_mac); dhd_conf_free_mac_list(&dhd->conf->nv_by_mac); + dhd_conf_free_chip_nv_path_list(&dhd->conf->nv_by_chip); #endif MFREE(dhd->osh, dhd->conf, sizeof(dhd_conf_t)); } diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.h index a74ec6ee25ba..09748e07df89 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_config.h @@ -35,6 +35,19 @@ typedef struct wl_mac_list_ctrl { struct wl_mac_list *m_mac_list_head; } wl_mac_list_ctrl_t; +/* chip_nv_path */ +typedef struct wl_chip_nv_path { + uint chip; + uint chiprev; + char name[MOD_PARAM_PATHLEN]; /* path */ +} wl_chip_nv_path_t; + +/* chip_nv_path list head */ +typedef struct wl_chip_nv_path_list_ctrl { + int count; + struct wl_chip_nv_path *m_chip_nv_path_head; +} wl_chip_nv_path_list_ctrl_t; + /* channel list */ typedef struct wl_channel_list { /* in - # of channels, out - # of entries */ @@ -74,6 +87,7 @@ typedef struct dhd_conf { uint chiprev; /* chip revision */ wl_mac_list_ctrl_t fw_by_mac; /* Firmware auto selection by MAC */ wl_mac_list_ctrl_t nv_by_mac; /* NVRAM auto selection by MAC */ + wl_chip_nv_path_list_ctrl_t nv_by_chip; /* NVRAM auto selection by chip */ uint band; /* Band, b:2.4G only, otherwise for auto */ int mimo_bw_cap; /* Bandwidth, 0:HT20ALL, 1: HT40ALL, 2:HT20IN2G_HT40PIN5G */ wl_country_t cspec; /* Country */ @@ -109,6 +123,7 @@ typedef struct dhd_conf { int dpc_cpucore; int frameburst; bool deepsleep; + int pm; } dhd_conf_t; #ifdef BCMSDIO @@ -120,6 +135,7 @@ void dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip); #endif #endif void dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path); +void dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path); void dhd_conf_set_conf_path_by_nv_path(dhd_pub_t *dhd, char *conf_path, char *nv_path); int dhd_conf_set_band(dhd_pub_t *dhd); uint dhd_conf_get_band(dhd_pub_t *dhd); @@ -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); uint dhd_conf_get_chip(void *context); uint dhd_conf_get_chiprev(void *context); +int dhd_conf_get_pm(void *context); int dhd_conf_preinit(dhd_pub_t *dhd); int dhd_conf_reset(dhd_pub_t *dhd); int dhd_conf_attach(dhd_pub_t *dhd); diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c index 78c84c0c01ff..ed276a73bc84 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c @@ -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; } diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.c index e51f71b9ce43..21a9e735481d 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_pcie.c @@ -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; diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c index f172ce283e5b..1a186d95ebdb 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_sdio.c @@ -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); diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h index b31979bb74de..a33ded17c646 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/epivers.h @@ -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_ */ diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/sbchipc.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/sbchipc.h index 597bc752c050..f08e98ad8e27 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/sbchipc.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/sbchipc.h @@ -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) diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/wlioctl.h b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/wlioctl.h index 25d83f2b5340..ea727bae425c 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/wlioctl.h +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/include/wlioctl.h @@ -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. diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c index 54c9633dd68a..cb4fc5eefa84 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_cfg80211.c @@ -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) diff --git a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.c b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.c index 339fa7aa65e8..219c1df03211 100755 --- a/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.c +++ b/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/wl_iw.c @@ -22,6 +22,7 @@ typedef const struct si_pub si_t; #include +#include /* 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 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); } -- 2.34.1