From 424b00bfbacfbeabbfbbc7484c38c51d6abcdd47 Mon Sep 17 00:00:00 2001 From: Weiguang Ruan Date: Thu, 19 Oct 2017 14:54:42 +0800 Subject: [PATCH] wifi: broadcom sta + ap mode use hostapd [1/3] PD#151669 1. add sta + ap with hostapd mode support 2. fix unload driver kernel panic(wowlan_config->nd_config) Change-Id: Ie72b70a22c1f3c5c0bedb3ee1de912b64d228018 --- bcmdhd.1.363.59.144.x.cn/Makefile | 5 +- bcmdhd.1.363.59.144.x.cn/bcmsdh_linux.c | 11 - bcmdhd.1.363.59.144.x.cn/bcmsdh_sdmmc.c | 22 +- bcmdhd.1.363.59.144.x.cn/bcmutils.c | 9 +- bcmdhd.1.363.59.144.x.cn/dhd.h | 1 + bcmdhd.1.363.59.144.x.cn/dhd_config.c | 5227 +++++++++--------- bcmdhd.1.363.59.144.x.cn/dhd_config.c.rej | 5140 ----------------- bcmdhd.1.363.59.144.x.cn/dhd_config.h | 502 +- bcmdhd.1.363.59.144.x.cn/dhd_gpio.c | 16 + bcmdhd.1.363.59.144.x.cn/dhd_linux.c | 77 +- bcmdhd.1.363.59.144.x.cn/dhd_sdio.c | 2 +- bcmdhd.1.363.59.144.x.cn/dhd_static_buf.c | 1 + bcmdhd.1.363.59.144.x.cn/dhd_wlfc.c | 6 +- bcmdhd.1.363.59.144.x.cn/include/epivers.h | 2 +- bcmdhd.1.363.59.144.x.cn/include/linux_osl.h | 2 - bcmdhd.1.363.59.144.x.cn/include/wlioctl.h | 9 + bcmdhd.1.363.59.144.x.cn/linux_osl.c | 6 +- bcmdhd.1.363.59.144.x.cn/wl_android.c | 26 +- bcmdhd.1.363.59.144.x.cn/wl_android_ext.c | 4138 +++++++------- bcmdhd.1.363.59.144.x.cn/wl_cfg80211.c | 346 +- bcmdhd.1.363.59.144.x.cn/wl_cfgvendor.c | 57 +- 21 files changed, 5423 insertions(+), 10182 deletions(-) delete mode 100644 bcmdhd.1.363.59.144.x.cn/dhd_config.c.rej diff --git a/bcmdhd.1.363.59.144.x.cn/Makefile b/bcmdhd.1.363.59.144.x.cn/Makefile index d8b7686..c0dadf7 100644 --- a/bcmdhd.1.363.59.144.x.cn/Makefile +++ b/bcmdhd.1.363.59.144.x.cn/Makefile @@ -6,7 +6,7 @@ ifeq ($(CONFIG_BCMDHD_PCIE),) $(info bcm SDIO driver configured) CONFIG_BCMDHD_SDIO := y -CONFIG_DHD_USE_STATIC_BUF :=y +CONFIG_DHD_USE_STATIC_BUF := y endif CONFIG_BCMDHD_PROPTXSTATUS := y @@ -36,8 +36,6 @@ DHDCFLAGS += \ -DBDC -DDHD_USE_IDLECOUNT -DBCMSDIOH_TXGLOM \ -DCUSTOM_SDIO_F2_BLKSIZE=256 -DHDCFLAGS += -DDCUSTOM_DPC_PRIO_SETTING=-1 -DHDCFLAGS += -DCUSTOM_RXF_CPUCORE=2 DHDCFLAGS += -DDHD_FIRSTREAD=256 -DMAX_HDR_READ=256 DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o \ @@ -111,6 +109,7 @@ DHDCFLAGS += -DWL_SUPPORT_BACKPORTED_KPATCHES DHDCFLAGS += -DESCAN_RESULT_PATCH DHDCFLAGS += -DVSDB -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST DHDCFLAGS += -DWLTDLS -DMIRACAST_AMPDU_SIZE=8 +DHDCFLAGS += -DWL_VIRTUAL_APSTA endif EXTRA_CFLAGS = $(DHDCFLAGS) ifeq ($(CONFIG_BCMDHD),m) diff --git a/bcmdhd.1.363.59.144.x.cn/bcmsdh_linux.c b/bcmdhd.1.363.59.144.x.cn/bcmsdh_linux.c index 5087eb4..9c93279 100644 --- a/bcmdhd.1.363.59.144.x.cn/bcmsdh_linux.c +++ b/bcmdhd.1.363.59.144.x.cn/bcmsdh_linux.c @@ -52,8 +52,6 @@ extern void dhdsdio_isr(void * args); #endif /* defined(CONFIG_ARCH_ODIN) */ #include -#include - /* driver info, initialized when bcmsdh_register is called */ static bcmsdh_driver_t drvinfo = {NULL, NULL, NULL, NULL}; @@ -349,11 +347,6 @@ int bcmsdh_oob_intr_register(bcmsdh_info_t *bcmsdh, bcmsdh_cb_fn_t oob_irq_handl #endif SDLX_MSG(("%s OOB irq=%d flags=0x%X\n", __FUNCTION__, (int)bcmsdh_osinfo->oob_irq_num, (int)bcmsdh_osinfo->oob_irq_flags)); - // anthony: test begin - bcmsdh_osinfo->oob_irq_flags &= IRQF_TRIGGER_MASK; - printf("%s change flags to 0x%X\n", __FUNCTION__, (int)bcmsdh_osinfo->oob_irq_flags); - // anthony: test end - bcmsdh_osinfo->oob_irq_handler = oob_irq_handler; bcmsdh_osinfo->oob_irq_handler_context = oob_irq_handler_context; bcmsdh_osinfo->oob_irq_enabled = TRUE; @@ -372,10 +365,6 @@ int bcmsdh_oob_intr_register(bcmsdh_info_t *bcmsdh, bcmsdh_cb_fn_t oob_irq_handl return err; } -#ifdef CUSTOM_DPC_CPUCORE - irq_set_affinity(bcmsdh_osinfo->oob_irq_num, cpumask_of(CUSTOM_DPC_CPUCORE)); -#endif - #if defined(DISABLE_WOWLAN) SDLX_MSG(("%s: disable_irq_wake\n", __FUNCTION__)); bcmsdh_osinfo->oob_irq_wake_enabled = FALSE; diff --git a/bcmdhd.1.363.59.144.x.cn/bcmsdh_sdmmc.c b/bcmdhd.1.363.59.144.x.cn/bcmsdh_sdmmc.c index 58be7ff..9c57647 100644 --- a/bcmdhd.1.363.59.144.x.cn/bcmsdh_sdmmc.c +++ b/bcmdhd.1.363.59.144.x.cn/bcmsdh_sdmmc.c @@ -919,8 +919,8 @@ sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *by if (sd_msglevel & SDH_COST_VAL) { getnstimeofday(&now); -// sd_cost(("%s: rw=%d len=1 cost=%lds %luus\n", __FUNCTION__, -// rw, now.tv_sec-before.tv_sec, now.tv_nsec/1000-before.tv_nsec/1000)); + sd_cost(("%s: rw=%d len=1 cost=%lds %luus\n", __FUNCTION__, + rw, now.tv_sec-before.tv_sec, now.tv_nsec/1000-before.tv_nsec/1000)); } return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); @@ -1396,8 +1396,8 @@ sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint add if (sd_msglevel & SDH_COST_VAL) { getnstimeofday(&now); -// sd_cost(("%s: rw=%d, len=%d cost=%lds %luus\n", __FUNCTION__, -// rw, nbytes, now.tv_sec-before.tv_sec, now.tv_nsec/1000 - before.tv_nsec/1000)); + sd_cost(("%s: rw=%d, len=%d cost=%lds %luus\n", __FUNCTION__, + rw, nbytes, now.tv_sec-before.tv_sec, now.tv_nsec/1000 - before.tv_nsec/1000)); } return (((err_ret == 0)&&(err_ret2 == 0)) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); @@ -1475,7 +1475,7 @@ sdioh_request_packet_chain(sdioh_info_t *sd, uint fix_inc, uint write, uint func * a restriction on max tx/glom count (based on host->max_segs). */ if (sg_count >= ARRAYSIZE(sd->sg_list)) { -// sd_err(("%s: sg list entries exceed limit, sg_count=%d(%lu)\n", __FUNCTION__, sg_count, ARRAYSIZE(sd->sg_list))); + sd_err(("%s: sg list entries exceed limit %d\n", __FUNCTION__, sg_count)); return (SDIOH_API_RC_FAIL); } pdata += pkt_offset; @@ -1613,8 +1613,8 @@ txglomfail: if (sd_msglevel & SDH_COST_VAL) { getnstimeofday(&now); -// sd_cost(("%s: rw=%d, cost=%lds %luus\n", __FUNCTION__, -// write, now.tv_sec-before.tv_sec, now.tv_nsec/1000-before.tv_nsec/1000)); + sd_cost(("%s: rw=%d, cost=%lds %luus\n", __FUNCTION__, + write, now.tv_sec-before.tv_sec, now.tv_nsec/1000-before.tv_nsec/1000)); } sd_trace(("%s: Exit\n", __FUNCTION__)); @@ -1668,8 +1668,8 @@ sdioh_buffer_tofrom_bus(sdioh_info_t *sd, uint fix_inc, uint write, uint func, if (sd_msglevel & SDH_COST_VAL) { getnstimeofday(&now); -// sd_cost(("%s: rw=%d, len=%d cost=%lds %luus\n", __FUNCTION__, -// write, len, now.tv_sec-before.tv_sec, now.tv_nsec/1000 - before.tv_nsec/1000)); + sd_cost(("%s: rw=%d, len=%d cost=%lds %luus\n", __FUNCTION__, + write, len, now.tv_sec-before.tv_sec, now.tv_nsec/1000 - before.tv_nsec/1000)); } return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL); @@ -1745,8 +1745,8 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u if (sd_msglevel & SDH_COST_VAL) { getnstimeofday(&now); -// sd_cost(("%s: len=%d cost=%lds %luus\n", __FUNCTION__, -// buf_len, now.tv_sec-before.tv_sec, now.tv_nsec/1000 - before.tv_nsec/1000)); + sd_cost(("%s: len=%d cost=%lds %luus\n", __FUNCTION__, + buf_len, now.tv_sec-before.tv_sec, now.tv_nsec/1000 - before.tv_nsec/1000)); } return status; diff --git a/bcmdhd.1.363.59.144.x.cn/bcmutils.c b/bcmdhd.1.363.59.144.x.cn/bcmutils.c index badb223..32ddc1f 100644 --- a/bcmdhd.1.363.59.144.x.cn/bcmutils.c +++ b/bcmdhd.1.363.59.144.x.cn/bcmutils.c @@ -2469,6 +2469,7 @@ process_nvram_vars(char *varbuf, unsigned int len) int column; unsigned int buf_len, n; unsigned int pad = 0; + char nv_ver[128]; dp = varbuf; @@ -2477,13 +2478,13 @@ process_nvram_vars(char *varbuf, unsigned int len) // terence 20130914: print out NVRAM version if (varbuf[0] == '#') { - printf("NVRAM version: "); - for (n=1; n -#include - -#include -#include -#include + +#include +#include + +#include +#include +#include #if defined(HW_OOB) || defined(FORCE_WOWLAN) -#include -#include -#include -#include -#endif - -#include -#include - +#include +#include +#include +#include +#endif + +#include +#include + /* message levels */ -#define CONFIG_ERROR_LEVEL 0x0001 -#define CONFIG_TRACE_LEVEL 0x0002 +#define CONFIG_ERROR_LEVEL 0x0001 +#define CONFIG_TRACE_LEVEL 0x0002 -uint config_msg_level = CONFIG_ERROR_LEVEL; +uint config_msg_level = CONFIG_ERROR_LEVEL; -#define CONFIG_ERROR(x) \ +#define CONFIG_ERROR(x) \ do { \ - if (config_msg_level & CONFIG_ERROR_LEVEL) { \ - printk(KERN_ERR "CONFIG-ERROR) "); \ + if (config_msg_level & CONFIG_ERROR_LEVEL) { \ + printk(KERN_ERR "CONFIG-ERROR) "); \ printk x; \ } \ } while (0) -#define CONFIG_TRACE(x) \ +#define CONFIG_TRACE(x) \ do { \ - if (config_msg_level & CONFIG_TRACE_LEVEL) { \ - printk(KERN_ERR "CONFIG-TRACE) "); \ + if (config_msg_level & CONFIG_TRACE_LEVEL) { \ + printk(KERN_ERR "CONFIG-TRACE) "); \ printk x; \ } \ - } while (0) - -#define MAXSZ_BUF 1000 -#define MAXSZ_CONFIG 4096 - -#define FW_TYPE_STA 0 -#define FW_TYPE_APSTA 1 -#define FW_TYPE_P2P 2 -#define FW_TYPE_ES 3 -#define FW_TYPE_MFG 4 -#define FW_TYPE_G 0 -#define FW_TYPE_AG 1 - -#ifdef CONFIG_PATH_AUTO_SELECT -#ifdef BCMSDIO -#define CONFIG_BCM4330B2 "config_40183b2.txt" -#define CONFIG_BCM43362A0 "config_40181a0.txt" -#define CONFIG_BCM43362A2 "config_40181a2.txt" -#define CONFIG_BCM43438A0 "config_43438a0.txt" -#define CONFIG_BCM43438A1 "config_43438a1.txt" -#define CONFIG_BCM43436B0 "config_43436b0.txt" -#define CONFIG_BCM4334B1 "config_4334b1.txt" -#define CONFIG_BCM43341B0 "config_43341b0.txt" -#define CONFIG_BCM43241B4 "config_43241b4.txt" -#define CONFIG_BCM4339A0 "config_4339a0.txt" -#define CONFIG_BCM43455C0 "config_43455c0.txt" -#define CONFIG_BCM43456C5 "config_43456c5.txt" -#define CONFIG_BCM4354A1 "config_4354a1.txt" -#endif -#define CONFIG_BCM4356A2 "config_4356a2.txt" -#define CONFIG_BCM4358A3 "config_4358.txt" -#define CONFIG_BCM4359B1 "config_4359b1.txt" -#define CONFIG_BCM4359C0 "config_4359c0.txt" -#endif - -#ifdef BCMSDIO -#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */ - -#define FW_BCM4330B2 "fw_bcm40183b2" -#define FW_BCM4330B2_AG "fw_bcm40183b2_ag" -#define FW_BCM43362A0 "fw_bcm40181a0" -#define FW_BCM43362A2 "fw_bcm40181a2" -#define FW_BCM4334B1 "fw_bcm4334b1_ag" -#define FW_BCM43438A0 "fw_bcm43438a0" -#define FW_BCM43438A1 "fw_bcm43438a1" -#define FW_BCM43436B0 "fw_bcm43436b0" -#define FW_BCM43012B0 "fw_bcm43012b0" -#define FW_BCM43341B1 "fw_bcm43341b0_ag" -#define FW_BCM43241B4 "fw_bcm43241b4_ag" -#define FW_BCM4339A0 "fw_bcm4339a0_ag" -#define FW_BCM43455C0 "fw_bcm43455c0_ag" -#define FW_BCM43456C5 "fw_bcm43456c5_ag" -#define FW_BCM4354A1 "fw_bcm4354a1_ag" -#define FW_BCM4356A2 "fw_bcm4356a2_ag" -#define FW_BCM4358A3 "fw_bcm4358_ag" -#define FW_BCM4359B1 "fw_bcm4359b1_ag" -#define FW_BCM4359C0 "fw_bcm4359c0_ag" - -#define CLM_BCM43012B0 "clm_bcm43012b0" -#endif -#ifdef BCMPCIE -#define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag" -#endif - + } while (0) + +#define MAXSZ_BUF 1000 +#define MAXSZ_CONFIG 4096 + +#define FW_TYPE_STA 0 +#define FW_TYPE_APSTA 1 +#define FW_TYPE_P2P 2 +#define FW_TYPE_ES 3 +#define FW_TYPE_MFG 4 +#define FW_TYPE_G 0 +#define FW_TYPE_AG 1 + +#ifdef CONFIG_PATH_AUTO_SELECT +#ifdef BCMSDIO +#define CONFIG_BCM4330B2 "config_40183b2.txt" +#define CONFIG_BCM43362A0 "config_40181a0.txt" +#define CONFIG_BCM43362A2 "config_40181a2.txt" +#define CONFIG_BCM43438A0 "config_43438a0.txt" +#define CONFIG_BCM43438A1 "config_43438a1.txt" +#define CONFIG_BCM43436B0 "config_43436b0.txt" +#define CONFIG_BCM4334B1 "config_4334b1.txt" +#define CONFIG_BCM43341B0 "config_43341b0.txt" +#define CONFIG_BCM43241B4 "config_43241b4.txt" +#define CONFIG_BCM4339A0 "config_4339a0.txt" +#define CONFIG_BCM43454C0 "config_43454c0.txt" +#define CONFIG_BCM43455C0 "config_43455c0.txt" +#define CONFIG_BCM43456C5 "config_43456c5.txt" +#define CONFIG_BCM4354A1 "config_4354a1.txt" +#endif +#define CONFIG_BCM4356A2 "config_4356a2.txt" +#define CONFIG_BCM4358A3 "config_4358a3.txt" +#define CONFIG_BCM4359B1 "config_4359b1.txt" +#define CONFIG_BCM4359C0 "config_4359c0.txt" +#endif + +#ifdef BCMSDIO +#define SBSDIO_CIS_SIZE_LIMIT 0x200 + +#define FW_BCM4330B2 "fw_bcm40183b2" +#define FW_BCM4330B2_AG "fw_bcm40183b2_ag" +#define FW_BCM43362A0 "fw_bcm40181a0" +#define FW_BCM43362A2 "fw_bcm40181a2" +#define FW_BCM4334B1 "fw_bcm4334b1_ag" +#define FW_BCM43438A0 "fw_bcm43438a0" +#define FW_BCM43438A1 "fw_bcm43438a1" +#define FW_BCM43436B0 "fw_bcm43436b0" +#define FW_BCM43012B0 "fw_bcm43012b0" +#define FW_BCM43341B1 "fw_bcm43341b0_ag" +#define FW_BCM43241B4 "fw_bcm43241b4_ag" +#define FW_BCM4339A0 "fw_bcm4339a0_ag" +#define FW_BCM43455C0 "fw_bcm43455c0_ag" +#define FW_BCM43456C5 "fw_bcm43456c5_ag" +#define FW_BCM4354A1 "fw_bcm4354a1_ag" +#define FW_BCM4356A2 "fw_bcm4356a2_ag" +#define FW_BCM4358A3 "fw_bcm4358a3_ag" +#define FW_BCM4359B1 "fw_bcm4359b1_ag" +#define FW_BCM4359C0 "fw_bcm4359c0_ag" + +#define CLM_BCM43012B0 "clm_bcm43012b0" +#endif +#ifdef BCMPCIE +#define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag" +#endif + #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 -void -dhd_conf_free_mac_list(wl_mac_list_ctrl_t *mac_list) -{ - int i; - - CONFIG_TRACE(("%s called\n", __FUNCTION__)); - if (mac_list->m_mac_list_head) { - for (i=0; icount; i++) { - if (mac_list->m_mac_list_head[i].mac) { - CONFIG_TRACE(("%s Free mac %p\n", __FUNCTION__, mac_list->m_mac_list_head[i].mac)); - kfree(mac_list->m_mac_list_head[i].mac); - } - } - CONFIG_TRACE(("%s Free m_mac_list_head %p\n", __FUNCTION__, mac_list->m_mac_list_head)); - kfree(mac_list->m_mac_list_head); - } - 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) || defined(FORCE_WOWLAN) -void -dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip) -{ - uint32 gpiocontrol, addr; - - if (CHIPID(chip) == BCM43362_CHIP_ID) { - printf("%s: Enable HW OOB for 43362\n", __FUNCTION__); - addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol); - gpiocontrol = bcmsdh_reg_read(sdh, addr, 4); - gpiocontrol |= 0x2; - bcmsdh_reg_write(sdh, addr, 4, gpiocontrol); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL); - bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL); - } -} -#endif - -int -dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac) -{ - int i, err = -1; - uint8 *ptr = 0; - unsigned char tpl_code, tpl_link='\0'; - uint8 header[3] = {0x80, 0x07, 0x19}; - uint8 *cis; - - if (!(cis = MALLOC(dhd->osh, SBSDIO_CIS_SIZE_LIMIT))) { - CONFIG_ERROR(("%s: cis malloc failed\n", __FUNCTION__)); - return err; - } - bzero(cis, SBSDIO_CIS_SIZE_LIMIT); - - if ((err = bcmsdh_cis_read(sdh, 0, cis, SBSDIO_CIS_SIZE_LIMIT))) { - CONFIG_ERROR(("%s: cis read err %d\n", __FUNCTION__, err)); - MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT); - return err; - } - err = -1; // reset err; - ptr = cis; - do { - /* 0xff means we're done */ - tpl_code = *ptr; - ptr++; - if (tpl_code == 0xff) - break; - - /* null entries have no link field or data */ - if (tpl_code == 0x00) - continue; - - tpl_link = *ptr; - ptr++; - /* a size of 0xff also means we're done */ - if (tpl_link == 0xff) - break; - if (config_msg_level & CONFIG_TRACE_LEVEL) { - printf("%s: tpl_code=0x%02x, tpl_link=0x%02x, tag=0x%02x\n", - __FUNCTION__, tpl_code, tpl_link, *ptr); - printk("%s: value:", __FUNCTION__); - for (i=0; iosh, cis, SBSDIO_CIS_SIZE_LIMIT); - - return err; -} - -void -dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path) -{ - int i, j; - uint8 mac[6]={0}; - int fw_num=0, mac_num=0; - uint32 oui, nic; - wl_mac_list_t *mac_list; - wl_mac_range_t *mac_range; - char *pfw_name; - int fw_type, fw_type_new; - - mac_list = dhd->conf->fw_by_mac.m_mac_list_head; - fw_num = dhd->conf->fw_by_mac.count; - if (!mac_list || !fw_num) - return; - - if (dhd_conf_get_mac(dhd, sdh, mac)) { - CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__)); - return; - } - oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]); - nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]); - - /* find out the last '/' */ - i = strlen(fw_path); - while (i > 0) { - if (fw_path[i] == '/') break; - i--; - } - pfw_name = &fw_path[i+1]; - fw_type = (strstr(pfw_name, "_mfg") ? - FW_TYPE_MFG : (strstr(pfw_name, "_apsta") ? - FW_TYPE_APSTA : (strstr(pfw_name, "_p2p") ? - FW_TYPE_P2P : FW_TYPE_STA))); - - for (i=0; i= mac_range[j].nic_start && nic <= mac_range[j].nic_end) { - strcpy(pfw_name, mac_list[i].name); - printf("%s: matched oui=0x%06X, nic=0x%06X\n", - __FUNCTION__, oui, nic); - printf("%s: fw_path=%s\n", __FUNCTION__, fw_path); - return; - } - } - } - } -} - -void -dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path) -{ - int i, j; - uint8 mac[6]={0}; - int nv_num=0, mac_num=0; - uint32 oui, nic; - wl_mac_list_t *mac_list; - wl_mac_range_t *mac_range; - char *pnv_name; - - mac_list = dhd->conf->nv_by_mac.m_mac_list_head; - nv_num = dhd->conf->nv_by_mac.count; - if (!mac_list || !nv_num) - return; - - if (dhd_conf_get_mac(dhd, sdh, mac)) { - CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__)); - return; - } - oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]); - nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]); - - /* find out the last '/' */ - i = strlen(nv_path); - while (i > 0) { - if (nv_path[i] == '/') break; - i--; - } - pnv_name = &nv_path[i+1]; - - for (i=0; i= mac_range[j].nic_start && nic <= mac_range[j].nic_end) { - strcpy(pnv_name, mac_list[i].name); - printf("%s: matched oui=0x%06X, nic=0x%06X\n", - __FUNCTION__, oui, nic); - printf("%s: nv_path=%s\n", __FUNCTION__, nv_path); - return; - } - } - } - } -} -#endif - -void -dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path) -{ - int fw_type, ag_type; - uint chip, chiprev; - int i; - char fw_tail[20]; - - chip = dhd->conf->chip; - chiprev = dhd->conf->chiprev; - - if (fw_path[0] == '\0') { -#ifdef CONFIG_BCMDHD_FW_PATH - bcm_strncpy_s(fw_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1); - if (fw_path[0] == '\0') -#endif - { - printf("firmware path is null\n"); - return; - } - } -#ifndef FW_PATH_AUTO_SELECT - return; -#endif - - /* find out the last '/' */ - i = strlen(fw_path); - while (i > 0) { - if (fw_path[i] == '/') break; - i--; - } -#ifdef BAND_AG - ag_type = FW_TYPE_AG; -#else - ag_type = strstr(&fw_path[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G; -#endif - fw_type = (strstr(&fw_path[i], "_mfg") ? FW_TYPE_MFG : - (strstr(&fw_path[i], "_apsta") ? FW_TYPE_APSTA : - (strstr(&fw_path[i], "_p2p") ? FW_TYPE_P2P : - (strstr(&fw_path[i], "_es") ? FW_TYPE_ES : - FW_TYPE_STA)))); - - if (fw_type == FW_TYPE_STA) - strcpy(fw_tail, ".bin"); - else if (fw_type == FW_TYPE_APSTA) - strcpy(fw_tail, "_apsta.bin"); - else if (fw_type == FW_TYPE_P2P) - strcpy(fw_tail, "_p2p.bin"); - else if (fw_type == FW_TYPE_ES) - strcpy(fw_tail, "_es.bin"); - else if (fw_type == FW_TYPE_MFG) - strcpy(fw_tail, "_mfg.bin"); - - switch (chip) { -#ifdef BCMSDIO - case BCM4330_CHIP_ID: - if (ag_type == FW_TYPE_G) { - if (chiprev == BCM4330B2_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM4330B2); - } else { - if (chiprev == BCM4330B2_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM4330B2_AG); - } - break; - case BCM43362_CHIP_ID: - if (chiprev == BCM43362A0_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM43362A0); - else - strcpy(&fw_path[i+1], FW_BCM43362A2); - break; - case BCM43430_CHIP_ID: - if (chiprev == BCM43430A0_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM43438A0); - else if (chiprev == BCM43430A1_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM43438A1); - else if (chiprev == BCM43430A2_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM43436B0); - break; - case BCM43012_CHIP_ID: - if (chiprev == BCM43012B0_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM43012B0); - case BCM4334_CHIP_ID: - if (chiprev == BCM4334B1_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM4334B1); - break; - case BCM43340_CHIP_ID: - case BCM43341_CHIP_ID: - if (chiprev == BCM43341B0_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM43341B1); - break; - case BCM4324_CHIP_ID: - if (chiprev == BCM43241B4_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM43241B4); - break; - case BCM4335_CHIP_ID: - if (chiprev == BCM4335A0_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM4339A0); - break; - case BCM4339_CHIP_ID: - if (chiprev == BCM4339A0_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM4339A0); - break; - case BCM4345_CHIP_ID: - case BCM43454_CHIP_ID: - if (chiprev == BCM43455C0_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM43455C0); - else if (chiprev == BCM43455C5_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM43456C5); - break; - case BCM4354_CHIP_ID: - if (chiprev == BCM4354A1_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM4354A1); - else if (chiprev == BCM4356A2_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM4356A2); - break; - case BCM4356_CHIP_ID: - case BCM4371_CHIP_ID: - if (chiprev == BCM4356A2_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM4356A2); - break; - case BCM43569_CHIP_ID: - if (chiprev == BCM4358A3_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM4358A3); - break; - case BCM4359_CHIP_ID: - if (chiprev == BCM4359B1_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM4359B1); - else if (chiprev == BCM4359C0_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM4359C0); - break; -#endif -#ifdef BCMPCIE - case BCM4354_CHIP_ID: - case BCM4356_CHIP_ID: - if (chiprev == BCM4356A2_CHIP_REV) - strcpy(&fw_path[i+1], FW_BCM4356A2); - break; -#endif - default: - strcpy(&fw_path[i+1], "fw_bcmdhd"); - } - strcat(fw_path, fw_tail); - - CONFIG_TRACE(("%s: firmware_path=%s\n", __FUNCTION__, fw_path)); -} - -void -dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path) -{ - uint chip, chiprev; - int i; - char fw_tail[20]; - - chip = dhd->conf->chip; - chiprev = dhd->conf->chiprev; - - if (clm_path[0] == '\0') { - printf("clm path is null\n"); - return; - } - - /* find out the last '/' */ - i = strlen(clm_path); - while (i > 0) { - if (clm_path[i] == '/') break; - i--; - } - - strcpy(fw_tail, ".blob"); - - switch (chip) { -#ifdef BCMSDIO - case BCM43012_CHIP_ID: - if (chiprev == BCM43012B0_CHIP_REV) - strcpy(&clm_path[i+1], CLM_BCM43012B0); - break; -#endif - default: - strcpy(&clm_path[i+1], "clm_bcmdhd"); - } - strcat(clm_path, fw_tail); - - CONFIG_TRACE(("%s: clm_path=%s\n", __FUNCTION__, clm_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); +#define dtohchanspec(i) i + +#ifdef BCMSDIO +void +dhd_conf_free_mac_list(wl_mac_list_ctrl_t *mac_list) +{ + int i; + + CONFIG_TRACE(("%s called\n", __FUNCTION__)); + if (mac_list->m_mac_list_head) { + for (i=0; icount; i++) { + if (mac_list->m_mac_list_head[i].mac) { + CONFIG_TRACE(("%s Free mac %p\n", __FUNCTION__, mac_list->m_mac_list_head[i].mac)); + kfree(mac_list->m_mac_list_head[i].mac); + } + } + CONFIG_TRACE(("%s Free m_mac_list_head %p\n", __FUNCTION__, mac_list->m_mac_list_head)); + kfree(mac_list->m_mac_list_head); + } + 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) || defined(FORCE_WOWLAN) +void +dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip) +{ + uint32 gpiocontrol, addr; + + if (CHIPID(chip) == BCM43362_CHIP_ID) { + printf("%s: Enable HW OOB for 43362\n", __FUNCTION__); + addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol); + gpiocontrol = bcmsdh_reg_read(sdh, addr, 4); + gpiocontrol |= 0x2; + bcmsdh_reg_write(sdh, addr, 4, gpiocontrol); + bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL); + bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL); + bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL); + } +} +#endif + +int +dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac) +{ + int i, err = -1; + uint8 *ptr = 0; + unsigned char tpl_code, tpl_link='\0'; + uint8 header[3] = {0x80, 0x07, 0x19}; + uint8 *cis; + + if (!(cis = MALLOC(dhd->osh, SBSDIO_CIS_SIZE_LIMIT))) { + CONFIG_ERROR(("%s: cis malloc failed\n", __FUNCTION__)); + return err; + } + bzero(cis, SBSDIO_CIS_SIZE_LIMIT); + + if ((err = bcmsdh_cis_read(sdh, 0, cis, SBSDIO_CIS_SIZE_LIMIT))) { + CONFIG_ERROR(("%s: cis read err %d\n", __FUNCTION__, err)); + MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT); + return err; + } + err = -1; // reset err; + ptr = cis; + do { + /* 0xff means we're done */ + tpl_code = *ptr; + ptr++; + if (tpl_code == 0xff) + break; + + /* null entries have no link field or data */ + if (tpl_code == 0x00) + continue; + + tpl_link = *ptr; + ptr++; + /* a size of 0xff also means we're done */ + if (tpl_link == 0xff) + break; + if (config_msg_level & CONFIG_TRACE_LEVEL) { + printf("%s: tpl_code=0x%02x, tpl_link=0x%02x, tag=0x%02x\n", + __FUNCTION__, tpl_code, tpl_link, *ptr); + printk("%s: value:", __FUNCTION__); + for (i=0; iosh, cis, SBSDIO_CIS_SIZE_LIMIT); + + return err; +} + +void +dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path) +{ + int i, j; + uint8 mac[6]={0}; + int fw_num=0, mac_num=0; + uint32 oui, nic; + wl_mac_list_t *mac_list; + wl_mac_range_t *mac_range; + char *pfw_name; + int fw_type, fw_type_new; + + mac_list = dhd->conf->fw_by_mac.m_mac_list_head; + fw_num = dhd->conf->fw_by_mac.count; + if (!mac_list || !fw_num) + return; + + if (dhd_conf_get_mac(dhd, sdh, mac)) { + CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__)); + return; + } + oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]); + nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]); + + /* find out the last '/' */ + i = strlen(fw_path); + while (i > 0) { + if (fw_path[i] == '/') break; + i--; + } + pfw_name = &fw_path[i+1]; + fw_type = (strstr(pfw_name, "_mfg") ? + FW_TYPE_MFG : (strstr(pfw_name, "_apsta") ? + FW_TYPE_APSTA : (strstr(pfw_name, "_p2p") ? + FW_TYPE_P2P : FW_TYPE_STA))); + + for (i=0; i= mac_range[j].nic_start && nic <= mac_range[j].nic_end) { + strcpy(pfw_name, mac_list[i].name); + printf("%s: matched oui=0x%06X, nic=0x%06X\n", + __FUNCTION__, oui, nic); + printf("%s: fw_path=%s\n", __FUNCTION__, fw_path); + return; + } + } + } + } +} + +void +dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path) +{ + int i, j; + uint8 mac[6]={0}; + int nv_num=0, mac_num=0; + uint32 oui, nic; + wl_mac_list_t *mac_list; + wl_mac_range_t *mac_range; + char *pnv_name; + + mac_list = dhd->conf->nv_by_mac.m_mac_list_head; + nv_num = dhd->conf->nv_by_mac.count; + if (!mac_list || !nv_num) + return; + + if (dhd_conf_get_mac(dhd, sdh, mac)) { + CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__)); + return; + } + oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]); + nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]); + + /* find out the last '/' */ + i = strlen(nv_path); + while (i > 0) { + if (nv_path[i] == '/') break; + i--; + } + pnv_name = &nv_path[i+1]; + + for (i=0; i= mac_range[j].nic_start && nic <= mac_range[j].nic_end) { + strcpy(pnv_name, mac_list[i].name); + printf("%s: matched oui=0x%06X, nic=0x%06X\n", + __FUNCTION__, oui, nic); + printf("%s: nv_path=%s\n", __FUNCTION__, nv_path); + return; + } + } + } + } +} +#endif + +void +dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path) +{ + int fw_type, ag_type; + uint chip, chiprev; + int i; + char fw_tail[20]; + + chip = dhd->conf->chip; + chiprev = dhd->conf->chiprev; + + if (fw_path[0] == '\0') { +#ifdef CONFIG_BCMDHD_FW_PATH + bcm_strncpy_s(fw_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1); + if (fw_path[0] == '\0') +#endif + { + printf("firmware path is null\n"); + return; + } + } +#ifndef FW_PATH_AUTO_SELECT + return; +#endif + + /* find out the last '/' */ + i = strlen(fw_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); - - CONFIG_TRACE(("%s: nvram_path=%s\n", __FUNCTION__, nv_path)); -} - -void -dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path) -{ - int i; - - if (src_path[0] == '\0') { - printf("src_path is null\n"); - return; - } else - strcpy(dst_path, src_path); - - /* find out the last '/' */ - i = strlen(dst_path); + if (fw_path[i] == '/') break; + i--; + } +#ifdef BAND_AG + ag_type = FW_TYPE_AG; +#else + ag_type = strstr(&fw_path[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G; +#endif + fw_type = (strstr(&fw_path[i], "_mfg") ? FW_TYPE_MFG : + (strstr(&fw_path[i], "_apsta") ? FW_TYPE_APSTA : + (strstr(&fw_path[i], "_p2p") ? FW_TYPE_P2P : + (strstr(&fw_path[i], "_es") ? FW_TYPE_ES : + FW_TYPE_STA)))); + + if (fw_type == FW_TYPE_STA) + strcpy(fw_tail, ".bin"); + else if (fw_type == FW_TYPE_APSTA) + strcpy(fw_tail, "_apsta.bin"); + else if (fw_type == FW_TYPE_P2P) + strcpy(fw_tail, "_p2p.bin"); + else if (fw_type == FW_TYPE_ES) + strcpy(fw_tail, "_es.bin"); + else if (fw_type == FW_TYPE_MFG) + strcpy(fw_tail, "_mfg.bin"); + + switch (chip) { +#ifdef BCMSDIO + case BCM4330_CHIP_ID: + if (ag_type == FW_TYPE_G) { + if (chiprev == BCM4330B2_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM4330B2); + } else { + if (chiprev == BCM4330B2_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM4330B2_AG); + } + break; + case BCM43362_CHIP_ID: + if (chiprev == BCM43362A0_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM43362A0); + else + strcpy(&fw_path[i+1], FW_BCM43362A2); + break; + case BCM43430_CHIP_ID: + if (chiprev == BCM43430A0_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM43438A0); + else if (chiprev == BCM43430A1_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM43438A1); + else if (chiprev == BCM43430A2_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM43436B0); + break; + case BCM43012_CHIP_ID: + if (chiprev == BCM43012B0_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM43012B0); + break; + case BCM4334_CHIP_ID: + if (chiprev == BCM4334B1_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM4334B1); + break; + case BCM43340_CHIP_ID: + case BCM43341_CHIP_ID: + if (chiprev == BCM43341B0_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM43341B1); + break; + case BCM4324_CHIP_ID: + if (chiprev == BCM43241B4_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM43241B4); + break; + case BCM4335_CHIP_ID: + if (chiprev == BCM4335A0_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM4339A0); + break; + case BCM4339_CHIP_ID: + if (chiprev == BCM4339A0_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM4339A0); + break; + case BCM43454_CHIP_ID: + if (chiprev == BCM43455C0_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM43455C0); + break; + case BCM4345_CHIP_ID: + if (chiprev == BCM43455C0_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM43455C0); + else if (chiprev == BCM43456C5_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM43456C5); + break; + case BCM4354_CHIP_ID: + if (chiprev == BCM4354A1_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM4354A1); + else if (chiprev == BCM4356A2_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM4356A2); + break; + case BCM4356_CHIP_ID: + case BCM4371_CHIP_ID: + if (chiprev == BCM4356A2_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM4356A2); + break; + case BCM43569_CHIP_ID: + if (chiprev == BCM4358A3_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM4358A3); + break; + case BCM4359_CHIP_ID: + if (chiprev == BCM4359B1_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM4359B1); + else if (chiprev == BCM4359C0_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM4359C0); + break; +#endif +#ifdef BCMPCIE + case BCM4354_CHIP_ID: + case BCM4356_CHIP_ID: + if (chiprev == BCM4356A2_CHIP_REV) + strcpy(&fw_path[i+1], FW_BCM4356A2); + break; +#endif + default: + strcpy(&fw_path[i+1], "fw_bcmdhd"); + } + strcat(fw_path, fw_tail); + + CONFIG_TRACE(("%s: firmware_path=%s\n", __FUNCTION__, fw_path)); +} + +void +dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path) +{ + uint chip, chiprev; + int i; + char fw_tail[20]; + + chip = dhd->conf->chip; + chiprev = dhd->conf->chiprev; + + if (clm_path[0] == '\0') { + printf("clm path is null\n"); + return; + } + + /* find out the last '/' */ + i = strlen(clm_path); while (i > 0) { - if (dst_path[i] == '/') break; - i--; - } - strcpy(&dst_path[i+1], dst_name); - - CONFIG_TRACE(("%s: dst_path=%s\n", __FUNCTION__, dst_path)); -} - -#ifdef CONFIG_PATH_AUTO_SELECT -void -dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path) -{ - uint chip, chiprev; - int i; - - chip = dhd->conf->chip; - chiprev = dhd->conf->chiprev; - - if (conf_path[0] == '\0') { - printf("config path is null\n"); - return; - } - - /* find out the last '/' */ - i = strlen(conf_path); - while (i > 0) { - if (conf_path[i] == '/') break; - i--; - } - - switch (chip) { -#ifdef BCMSDIO - case BCM4330_CHIP_ID: - if (chiprev == BCM4330B2_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM4330B2); - break; - case BCM43362_CHIP_ID: - if (chiprev == BCM43362A0_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM43362A0); - else - strcpy(&conf_path[i+1], CONFIG_BCM43362A2); - break; - case BCM43430_CHIP_ID: - if (chiprev == BCM43430A0_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM43438A0); - else if (chiprev == BCM43430A1_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM43438A1); - else if (chiprev == BCM43430A2_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM43436B0); - break; - case BCM4334_CHIP_ID: - if (chiprev == BCM4334B1_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM4334B1); - break; - case BCM43340_CHIP_ID: - case BCM43341_CHIP_ID: - if (chiprev == BCM43341B0_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM43341B0); - break; - case BCM4324_CHIP_ID: - if (chiprev == BCM43241B4_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM43241B4); - break; - case BCM4335_CHIP_ID: - if (chiprev == BCM4335A0_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM4339A0); - break; - case BCM4345_CHIP_ID: - case BCM43454_CHIP_ID: - if (chiprev == BCM43455C0_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM43455C0); - else if (chiprev == BCM43455C5_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM43456C5); - break; - case BCM4339_CHIP_ID: - if (chiprev == BCM4339A0_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM4339A0); - break; - case BCM4354_CHIP_ID: - if (chiprev == BCM4354A1_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM4354A1); - else if (chiprev == BCM4356A2_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM4356A2); - break; - case BCM4356_CHIP_ID: - case BCM4371_CHIP_ID: - if (chiprev == BCM4356A2_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM4356A2); - break; - case BCM43569_CHIP_ID: - if (chiprev == BCM4358A3_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM4358A3); - break; - case BCM4359_CHIP_ID: - if (chiprev == BCM4359B1_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM4359B1); - else if (chiprev == BCM4359C0_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM4359C0); - break; -#endif -#ifdef BCMPCIE - case BCM4354_CHIP_ID: - case BCM4356_CHIP_ID: - if (chiprev == BCM4356A2_CHIP_REV) - strcpy(&conf_path[i+1], CONFIG_BCM4356A2); - break; -#endif - } - - CONFIG_TRACE(("%s: config_path=%s\n", __FUNCTION__, conf_path)); -} -#endif - -int -dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val, - int def, bool down) -{ - int ret = -1; - char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ - - if (val >= def) { - if (down) { - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0) - CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret)); - } - if (cmd == WLC_SET_VAR) { - printf("%s: set %s %d\n", __FUNCTION__, name, val); - bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) - CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); - } else { - printf("%s: set %s %d %d\n", __FUNCTION__, name, cmd, val); - if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, 0)) < 0) - CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); - } - } - - return ret; -} - -int -dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf, - int len, bool down) -{ - char iovbuf[WLC_IOCTL_SMLEN]; - int ret = -1; - - if (down) { - if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0) - CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret)); - } - - if (cmd == WLC_SET_VAR) { - bcm_mkiovar(name, buf, len, iovbuf, sizeof(iovbuf)); - if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) - CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); - } else { - if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, TRUE, 0)) < 0) - CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); - } - - return ret; -} - -int -dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx) -{ - char iovbuf[WLC_IOCTL_SMLEN]; - int ret = -1; - - if (cmd == WLC_GET_VAR) { - if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) { - ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx); - if (!ret) { - memcpy(buf, iovbuf, len); - } else { - CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret)); - } - } else { - CONFIG_ERROR(("%s: mkiovar %s failed\n", __FUNCTION__, name)); - } - } else { - ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, FALSE, 0); - if (ret < 0) - CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret)); - } - - return ret; -} - -uint -dhd_conf_get_band(dhd_pub_t *dhd) -{ - uint band = WLC_BAND_AUTO; - - if (dhd && dhd->conf) - band = dhd->conf->band; - else - CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__)); - - return band; -} - -int -dhd_conf_set_country(dhd_pub_t *dhd) -{ - int bcmerror = -1; - - memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t)); - printf("%s: set country %s, revision %d\n", __FUNCTION__, - dhd->conf->cspec.ccode, dhd->conf->cspec.rev); - dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)&dhd->conf->cspec, sizeof(wl_country_t), FALSE); - - return bcmerror; -} - -int -dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec) -{ - int bcmerror = -1; - - memset(cspec, 0, sizeof(wl_country_t)); - bcm_mkiovar("country", NULL, 0, (char*)cspec, sizeof(wl_country_t)); - if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cspec, sizeof(wl_country_t), FALSE, 0)) < 0) - CONFIG_ERROR(("%s: country code getting failed %d\n", __FUNCTION__, bcmerror)); - else - printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev); - - return bcmerror; -} - -int -dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec) -{ - int bcmerror = -1, i; - struct dhd_conf *conf = dhd->conf; - - for (i = 0; i < conf->country_list.count; i++) { - if (!strncmp(cspec->country_abbrev, conf->country_list.cspec[i].country_abbrev, 2)) { - memcpy(cspec->ccode, - conf->country_list.cspec[i].ccode, WLC_CNTRY_BUF_SZ); - cspec->rev = conf->country_list.cspec[i].rev; - printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev); - return 0; - } - } - - return bcmerror; -} - -int -dhd_conf_fix_country(dhd_pub_t *dhd) -{ - int bcmerror = -1; - uint band; - wl_uint32_list_t *list; - u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)]; - - if (!(dhd && dhd->conf)) { - return bcmerror; - } - - memset(valid_chan_list, 0, sizeof(valid_chan_list)); + if (clm_path[i] == '/') break; + i--; + } + + strcpy(fw_tail, ".blob"); + + switch (chip) { +#ifdef BCMSDIO + case BCM43012_CHIP_ID: + if (chiprev == BCM43012B0_CHIP_REV) + strcpy(&clm_path[i+1], CLM_BCM43012B0); + break; +#endif + default: + strcpy(&clm_path[i+1], "clm_bcmdhd"); + } + strcat(clm_path, fw_tail); + + CONFIG_TRACE(("%s: clm_path=%s\n", __FUNCTION__, clm_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); + + CONFIG_TRACE(("%s: nvram_path=%s\n", __FUNCTION__, nv_path)); +} + +void +dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path) +{ + int i; + + if (src_path[0] == '\0') { + printf("src_path is null\n"); + return; + } else + strcpy(dst_path, src_path); + + /* find out the last '/' */ + i = strlen(dst_path); + while (i > 0) { + if (dst_path[i] == '/') break; + i--; + } + strcpy(&dst_path[i+1], dst_name); + + CONFIG_TRACE(("%s: dst_path=%s\n", __FUNCTION__, dst_path)); +} + +#ifdef CONFIG_PATH_AUTO_SELECT +void +dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path) +{ + uint chip, chiprev; + int i; + + chip = dhd->conf->chip; + chiprev = dhd->conf->chiprev; + + if (conf_path[0] == '\0') { + printf("config path is null\n"); + return; + } + + /* find out the last '/' */ + i = strlen(conf_path); + while (i > 0) { + if (conf_path[i] == '/') break; + i--; + } + + switch (chip) { +#ifdef BCMSDIO + case BCM4330_CHIP_ID: + if (chiprev == BCM4330B2_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM4330B2); + break; + case BCM43362_CHIP_ID: + if (chiprev == BCM43362A0_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM43362A0); + else + strcpy(&conf_path[i+1], CONFIG_BCM43362A2); + break; + case BCM43430_CHIP_ID: + if (chiprev == BCM43430A0_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM43438A0); + else if (chiprev == BCM43430A1_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM43438A1); + else if (chiprev == BCM43430A2_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM43436B0); + break; + case BCM4334_CHIP_ID: + if (chiprev == BCM4334B1_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM4334B1); + break; + case BCM43340_CHIP_ID: + case BCM43341_CHIP_ID: + if (chiprev == BCM43341B0_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM43341B0); + break; + case BCM4324_CHIP_ID: + if (chiprev == BCM43241B4_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM43241B4); + break; + case BCM4335_CHIP_ID: + if (chiprev == BCM4335A0_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM4339A0); + break; + case BCM43454_CHIP_ID: + if (chiprev == BCM43455C0_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM43454C0); + break; + case BCM4345_CHIP_ID: + if (chiprev == BCM43455C0_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM43455C0); + else if (chiprev == BCM43456C5_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM43456C5); + break; + case BCM4339_CHIP_ID: + if (chiprev == BCM4339A0_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM4339A0); + break; + case BCM4354_CHIP_ID: + if (chiprev == BCM4354A1_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM4354A1); + else if (chiprev == BCM4356A2_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM4356A2); + break; + case BCM4356_CHIP_ID: + case BCM4371_CHIP_ID: + if (chiprev == BCM4356A2_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM4356A2); + break; + case BCM43569_CHIP_ID: + if (chiprev == BCM4358A3_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM4358A3); + break; + case BCM4359_CHIP_ID: + if (chiprev == BCM4359B1_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM4359B1); + else if (chiprev == BCM4359C0_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM4359C0); + break; +#endif +#ifdef BCMPCIE + case BCM4354_CHIP_ID: + case BCM4356_CHIP_ID: + if (chiprev == BCM4356A2_CHIP_REV) + strcpy(&conf_path[i+1], CONFIG_BCM4356A2); + break; +#endif + } + + CONFIG_TRACE(("%s: config_path=%s\n", __FUNCTION__, conf_path)); +} +#endif + +int +dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val, + int def, bool down) +{ + int ret = -1; + char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ + + if (val >= def) { + if (down) { + if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0) + CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret)); + } + if (cmd == WLC_SET_VAR) { + printf("%s: set %s %d\n", __FUNCTION__, name, val); + bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf)); + if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) + CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); + } else { + printf("%s: set %s %d %d\n", __FUNCTION__, name, cmd, val); + if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, 0)) < 0) + CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); + } + } + + return ret; +} + +int +dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf, + int len, bool down) +{ + char iovbuf[WLC_IOCTL_SMLEN]; + int ret = -1; + + if (down) { + if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0) + CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret)); + } + + if (cmd == WLC_SET_VAR) { + bcm_mkiovar(name, buf, len, iovbuf, sizeof(iovbuf)); + if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) + CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); + } else { + if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, TRUE, 0)) < 0) + CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); + } + + return ret; +} + +int +dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx) +{ + char iovbuf[WLC_IOCTL_SMLEN]; + int ret = -1; + + if (cmd == WLC_GET_VAR) { + if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) { + ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx); + if (!ret) { + memcpy(buf, iovbuf, len); + } else { + CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret)); + } + } else { + CONFIG_ERROR(("%s: mkiovar %s failed\n", __FUNCTION__, name)); + } + } else { + ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, FALSE, 0); + if (ret < 0) + CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret)); + } + + return ret; +} + +uint +dhd_conf_get_band(dhd_pub_t *dhd) +{ + uint band = WLC_BAND_AUTO; + + if (dhd && dhd->conf) + band = dhd->conf->band; + else + CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__)); + + return band; +} + +int +dhd_conf_set_country(dhd_pub_t *dhd) +{ + int bcmerror = -1; + + memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t)); + printf("%s: set country %s, revision %d\n", __FUNCTION__, + dhd->conf->cspec.ccode, dhd->conf->cspec.rev); + dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)&dhd->conf->cspec, sizeof(wl_country_t), FALSE); + + return bcmerror; +} + +int +dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec) +{ + int bcmerror = -1; + + memset(cspec, 0, sizeof(wl_country_t)); + bcm_mkiovar("country", NULL, 0, (char*)cspec, sizeof(wl_country_t)); + if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cspec, sizeof(wl_country_t), FALSE, 0)) < 0) + CONFIG_ERROR(("%s: country code getting failed %d\n", __FUNCTION__, bcmerror)); + else + printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev); + + return bcmerror; +} + +int +dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec) +{ + int bcmerror = -1, i; + struct dhd_conf *conf = dhd->conf; + + for (i = 0; i < conf->country_list.count; i++) { + if (!strncmp(cspec->country_abbrev, conf->country_list.cspec[i].country_abbrev, 2)) { + memcpy(cspec->ccode, + conf->country_list.cspec[i].ccode, WLC_CNTRY_BUF_SZ); + cspec->rev = conf->country_list.cspec[i].rev; + printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev); + return 0; + } + } + + return bcmerror; +} + +int +dhd_conf_fix_country(dhd_pub_t *dhd) +{ + int bcmerror = -1; + uint band; + wl_uint32_list_t *list; + u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)]; + + 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); - 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)); - } - - band = dhd_conf_get_band(dhd); - - if (bcmerror || ((band==WLC_BAND_AUTO || band==WLC_BAND_2G) && - dtoh32(list->count)<11)) { - CONFIG_ERROR(("%s: bcmerror=%d, # of channels %d\n", - __FUNCTION__, bcmerror, dtoh32(list->count))); - if ((bcmerror = dhd_conf_set_country(dhd)) < 0) { - strcpy(dhd->conf->cspec.country_abbrev, "US"); - dhd->conf->cspec.rev = 0; - strcpy(dhd->conf->cspec.ccode, "US"); - dhd_conf_set_country(dhd); - } - } - - return bcmerror; -} - -bool -dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel) -{ - int i; - bool match = false; - - if (dhd && dhd->conf) { - if (dhd->conf->channels.count == 0) - return true; - for (i=0; iconf->channels.count; i++) { - if (channel == dhd->conf->channels.channel[i]) - match = true; - } - } else { - match = true; - CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__)); - } - - return match; -} - -int -dhd_conf_set_roam(dhd_pub_t *dhd) -{ - int bcmerror = -1; - struct dhd_conf *conf = dhd->conf; - - dhd_roam_disable = conf->roam_off; - dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_off", dhd->conf->roam_off, 0, FALSE); - - if (!conf->roam_off || !conf->roam_off_suspend) { - printf("%s: set roam_trigger %d\n", __FUNCTION__, conf->roam_trigger[0]); - dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_TRIGGER, "WLC_SET_ROAM_TRIGGER", - (char *)conf->roam_trigger, sizeof(conf->roam_trigger), FALSE); - - printf("%s: set roam_scan_period %d\n", __FUNCTION__, conf->roam_scan_period[0]); - dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_SCAN_PERIOD, "WLC_SET_ROAM_SCAN_PERIOD", - (char *)conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE); - - printf("%s: set roam_delta %d\n", __FUNCTION__, conf->roam_delta[0]); - dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_DELTA, "WLC_SET_ROAM_DELTA", - (char *)conf->roam_delta, sizeof(conf->roam_delta), FALSE); - - dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "fullroamperiod", dhd->conf->fullroamperiod, 1, FALSE); - } - - return bcmerror; -} - -void -dhd_conf_set_bw_cap(dhd_pub_t *dhd) -{ - struct { - u32 band; - u32 bw_cap; - } param = {0, 0}; - - if (dhd->conf->bw_cap_2g >= 0) { - param.band = WLC_BAND_2G; - param.bw_cap = (uint)dhd->conf->bw_cap_2g; - printf("%s: set bw_cap 2g %d\n", __FUNCTION__, param.bw_cap); - dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)¶m, sizeof(param), TRUE); - } - - if (dhd->conf->bw_cap_5g >= 0) { - param.band = WLC_BAND_5G; - param.bw_cap = (uint)dhd->conf->bw_cap_5g; - printf("%s: set bw_cap 5g %d\n", __FUNCTION__, param.bw_cap); - dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)¶m, sizeof(param), TRUE); - } -} - -void -dhd_conf_get_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acp) -{ - int bcmerror = -1; - char iovbuf[WLC_IOCTL_SMLEN]; - edcf_acparam_t *acparam; - - bzero(iovbuf, sizeof(iovbuf)); - - /* - * Get current acparams, using buf as an input buffer. - * Return data is array of 4 ACs of wme params. - */ - if (mode == 0) - bcm_mkiovar("wme_ac_sta", NULL, 0, iovbuf, sizeof(iovbuf)); - else - bcm_mkiovar("wme_ac_ap", NULL, 0, iovbuf, sizeof(iovbuf)); - if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) { - CONFIG_ERROR(("%s: wme_ac_sta getting failed %d\n", __FUNCTION__, bcmerror)); - return; - } - 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 txop 0x%x\n", - __FUNCTION__, - acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, - acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, - acparam->TXOP)); - acparam = &acp[AC_BE]; - CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", - __FUNCTION__, - acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, - acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, - acparam->TXOP)); - acparam = &acp[AC_VI]; - CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", - __FUNCTION__, - acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, - acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, - acparam->TXOP)); - acparam = &acp[AC_VO]; - CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", - __FUNCTION__, - acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, - acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, - acparam->TXOP)); - - return; -} - -void -dhd_conf_update_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acparam_cur, int aci) -{ - int aifsn, ecwmin, ecwmax, txop; - edcf_acparam_t *acp; - struct dhd_conf *conf = dhd->conf; - wme_param_t *wme; - - if (mode == 0) - wme = &conf->wme_sta; - else - wme = &conf->wme_ap; - - /* Default value */ - aifsn = acparam_cur->ACI&EDCF_AIFSN_MASK; - ecwmin = acparam_cur->ECW&EDCF_ECWMIN_MASK; - ecwmax = (acparam_cur->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT; - txop = acparam_cur->TXOP; - - /* Modified value */ - if (wme->aifsn[aci] > 0) - aifsn = wme->aifsn[aci]; - if (wme->ecwmin[aci] > 0) - ecwmin = wme->ecwmin[aci]; - if (wme->ecwmax[aci] > 0) - ecwmax = wme->ecwmax[aci]; - if (wme->txop[aci] > 0) - txop = wme->txop[aci]; - - if (!(wme->aifsn[aci] || wme->ecwmin[aci] || - wme->ecwmax[aci] || wme->txop[aci])) - return; - - /* Update */ - acp = acparam_cur; - acp->ACI = (acp->ACI & ~EDCF_AIFSN_MASK) | (aifsn & EDCF_AIFSN_MASK); - 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)); - acp->TXOP = txop; - - printf("%s: wme_ac %s aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", - __FUNCTION__, mode?"ap":"sta", - acp->ACI, acp->ACI&EDCF_AIFSN_MASK, - acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, - acp->TXOP); - - /* - * Now use buf as an output buffer. - * Put WME acparams after "wme_ac\0" in buf. - * NOTE: only one of the four ACs can be set at a time. - */ - if (mode == 0) - dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE); - else - dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_ap", (char *)acp, sizeof(edcf_acparam_t), FALSE); - -} - -void -dhd_conf_set_wme(dhd_pub_t *dhd, int mode) -{ - edcf_acparam_t acparam_cur[AC_COUNT]; - - if (dhd && dhd->conf) { - if (!dhd->conf->force_wme_ac) { - CONFIG_TRACE(("%s: force_wme_ac is not enabled %d\n", - __FUNCTION__, dhd->conf->force_wme_ac)); - return; - } - - CONFIG_TRACE(("%s: Before change:\n", __FUNCTION__)); - dhd_conf_get_wme(dhd, mode, acparam_cur); - - dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BK], AC_BK); - dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BE], AC_BE); - dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VI], AC_VI); - dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VO], AC_VO); - - CONFIG_TRACE(("%s: After change:\n", __FUNCTION__)); - dhd_conf_get_wme(dhd, mode, acparam_cur); - } else { - CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__)); - } - - return; -} - -#ifdef PKT_FILTER_SUPPORT -void -dhd_conf_add_pkt_filter(dhd_pub_t *dhd) -{ - int i, j; - char str[12]; -#define MACS "%02x%02x%02x%02x%02x%02x" - - /* - * 1. Filter out all pkt: actually not to enable this since 4-way handshake will be filter out as well. - * 1) dhd_master_mode=0 - * 2) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000 - * 2. Filter in less pkt: ARP(0x0806, ID is 105), BRCM(0x886C), 802.1X(0x888E) - * 1) dhd_master_mode=1 - * 2) pkt_filter_del=100, 102, 103, 104, 105 - * 3) pkt_filter_add=131 0 0 12 0xFFFF 0x886C, 132 0 0 12 0xFFFF 0x888E - * 3. magic pkt: magic_pkt_filter_add=141 0 1 12 - * 4. Filter out netbios pkt: - * Netbios: 121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089 - */ - for(i=0; iconf->pkt_filter_add.count; i++) { - dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[i]; - printf("%s: %s\n", __FUNCTION__, dhd->pktfilter[i+dhd->pktfilter_count]); - } - dhd->pktfilter_count += i; - - for(i=0; iconf->magic_pkt_filter_add.count; i++) { - strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x"); - strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF"); - for (j=0; j<16; j++) - strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF"); - strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x"); - strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF"); - sprintf(str, MACS, MAC2STRDBG(dhd->mac.octet)); - for (j=0; j<16; j++) - strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], str); - dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add.filter[i]; - dhd->pktfilter_count += 1; - } -} - -bool -dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id) -{ - int i; - - if (dhd && dhd->conf) { - for (i=0; iconf->pkt_filter_del.count; i++) { - if (id == dhd->conf->pkt_filter_del.id[i]) { - printf("%s: %d\n", __FUNCTION__, dhd->conf->pkt_filter_del.id[i]); - return true; - } - } - return false; - } - return false; -} - -void -dhd_conf_discard_pkt_filter(dhd_pub_t *dhd) + 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)); + } + + band = dhd_conf_get_band(dhd); + + if (bcmerror || ((band == WLC_BAND_AUTO || band == WLC_BAND_2G) && + dtoh32(list->count)<11)) { + CONFIG_ERROR(("%s: bcmerror=%d, # of channels %d\n", + __FUNCTION__, bcmerror, dtoh32(list->count))); + if ((bcmerror = dhd_conf_set_country(dhd)) < 0) { + strcpy(dhd->conf->cspec.country_abbrev, "US"); + dhd->conf->cspec.rev = 0; + strcpy(dhd->conf->cspec.ccode, "US"); + dhd_conf_set_country(dhd); + } + } + + return bcmerror; +} + +bool +dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel) +{ + int i; + bool match = false; + + if (dhd && dhd->conf) { + if (dhd->conf->channels.count == 0) + return true; + for (i=0; iconf->channels.count; i++) { + if (channel == dhd->conf->channels.channel[i]) + match = true; + } + } else { + match = true; + CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__)); + } + + return match; +} + +int +dhd_conf_set_roam(dhd_pub_t *dhd) { - dhd->pktfilter_count = 6; - dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = NULL; - dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF"; - dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "102 0 0 0 0xFFFFFF 0x01005E"; - dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = "103 0 0 0 0xFFFF 0x3333"; - dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL; - /* Do not enable ARP to pkt filter if dhd_master_mode is false.*/ - dhd->pktfilter[DHD_ARP_FILTER_NUM] = NULL; - - /* IPv4 broadcast address XXX.XXX.XXX.255 */ - dhd->pktfilter[dhd->pktfilter_count] = "110 0 0 12 0xFFFF00000000000000000000000000000000000000FF 0x080000000000000000000000000000000000000000FF"; - dhd->pktfilter_count++; - /* discard IPv4 multicast address 224.0.0.0/4 */ - dhd->pktfilter[dhd->pktfilter_count] = "111 0 0 12 0xFFFF00000000000000000000000000000000F0 0x080000000000000000000000000000000000E0"; - dhd->pktfilter_count++; - /* discard IPv6 multicast address FF00::/8 */ - dhd->pktfilter[dhd->pktfilter_count] = "112 0 0 12 0xFFFF000000000000000000000000000000000000000000000000FF 0x86DD000000000000000000000000000000000000000000000000FF"; - dhd->pktfilter_count++; - /* discard Netbios pkt */ - dhd->pktfilter[dhd->pktfilter_count] = "121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089"; - dhd->pktfilter_count++; - -} -#endif /* PKT_FILTER_SUPPORT */ - -int -dhd_conf_get_pm(dhd_pub_t *dhd) -{ - if (dhd && dhd->conf) - return dhd->conf->pm; - return -1; -} - -#ifdef PROP_TXSTATUS -int -dhd_conf_get_disable_proptx(dhd_pub_t *dhd) -{ - struct dhd_conf *conf = dhd->conf; - int disable_proptx = -1; - int fw_proptx = 0; - - /* check fw proptx priority: - * 1st: check fw support by wl cap - * 2nd: 4334/43340/43341/43241 support proptx but not show in wl cap, so enable it by default - * if you would like to disable it, please set disable_proptx=1 in config.txt - * 3th: disable when proptxstatus not support in wl cap - */ - if (FW_SUPPORTED(dhd, proptxstatus)) { - fw_proptx = 1; - } else if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID || - dhd->conf->chip == BCM43340_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { - fw_proptx = 1; - } else { - fw_proptx = 0; - } - - /* returned disable_proptx value: - * -1: disable in STA and enable in P2P(follow original dhd settings when PROP_TXSTATUS_VSDB enabled) - * 0: depend on fw support - * 1: always disable proptx - */ - if (conf->disable_proptx == 0) { - // check fw support as well - if (fw_proptx) - disable_proptx = 0; - else - disable_proptx = 1; - } else if (conf->disable_proptx >= 1) { - disable_proptx = 1; - } else { - // check fw support as well - if (fw_proptx) - disable_proptx = -1; - else - disable_proptx = 1; - } - - printf("%s: fw_proptx=%d, disable_proptx=%d\n", __FUNCTION__, fw_proptx, disable_proptx); - - return disable_proptx; -} -#endif - -uint -pick_config_vars(char *varbuf, uint len, uint start_pos, char *pickbuf) -{ - bool findNewline, changenewline=FALSE, pick=FALSE; - int column; - uint n, pick_column=0; - - findNewline = FALSE; - column = 0; - - if (start_pos >= len) { - CONFIG_ERROR(("%s: wrong start pos\n", __FUNCTION__)); - return 0; - } - - for (n = start_pos; n < len; n++) { - if (varbuf[n] == '\r') - continue; - if ((findNewline || changenewline) && varbuf[n] != '\n') - continue; - findNewline = FALSE; - if (varbuf[n] == '#') { - findNewline = TRUE; - continue; - } - if (varbuf[n] == '\\') { - changenewline = TRUE; - continue; - } - if (!changenewline && varbuf[n] == '\n') { - if (column == 0) - continue; - column = 0; - continue; - } - if (changenewline && varbuf[n] == '\n') { - changenewline = FALSE; - continue; - } - - if (column==0 && !pick) { // start to pick - pick = TRUE; - column++; - pick_column = 0; - } else { - if (pick && column==0) { // stop to pick - pick = FALSE; - break; - } else - column++; - } - if (pick) { - if (varbuf[n] == 0x9) - continue; - if (pick_column>0 && pickbuf[pick_column-1]==' ' && varbuf[n]==' ') - continue; - pickbuf[pick_column] = varbuf[n]; - pick_column++; - } - } - - return n; // return current position -} - -bool -dhd_conf_read_log_level(dhd_pub_t *dhd, char *full_param, uint len_param) -{ - char *data = full_param+len_param; - - if (!strncmp("dhd_msg_level=", full_param, len_param)) { - dhd_msg_level = (int)simple_strtol(data, NULL, 0); - printf("%s: dhd_msg_level = 0x%X\n", __FUNCTION__, dhd_msg_level); - } -#ifdef BCMSDIO - else if (!strncmp("sd_msglevel=", full_param, len_param)) { - sd_msglevel = (int)simple_strtol(data, NULL, 0); - printf("%s: sd_msglevel = 0x%X\n", __FUNCTION__, sd_msglevel); - } -#endif - else if (!strncmp("android_msg_level=", full_param, len_param)) { - android_msg_level = (int)simple_strtol(data, NULL, 0); - printf("%s: android_msg_level = 0x%X\n", __FUNCTION__, android_msg_level); - } - else if (!strncmp("config_msg_level=", full_param, len_param)) { - config_msg_level = (int)simple_strtol(data, NULL, 0); - printf("%s: config_msg_level = 0x%X\n", __FUNCTION__, config_msg_level); - } -#ifdef WL_CFG80211 - else if (!strncmp("wl_dbg_level=", full_param, len_param)) { - wl_dbg_level = (int)simple_strtol(data, NULL, 0); - printf("%s: wl_dbg_level = 0x%X\n", __FUNCTION__, wl_dbg_level); - } -#endif -#if defined(WL_WIRELESS_EXT) - else if (!strncmp("iw_msg_level=", full_param, len_param)) { - iw_msg_level = (int)simple_strtol(data, NULL, 0); - printf("%s: iw_msg_level = 0x%X\n", __FUNCTION__, iw_msg_level); - } -#endif -#if defined(DHD_DEBUG) - else if (!strncmp("dhd_console_ms=", full_param, len_param)) { - dhd_console_ms = (int)simple_strtol(data, NULL, 0); - printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms); - } -#endif - else - return false; - - return true; -} - -void -dhd_conf_read_wme_ac_value(wme_param_t *wme, char *pick, int ac_val) -{ - char *pick_tmp, *pch; - - /* Process WMM parameters */ - pick_tmp = pick; - pch = bcmstrstr(pick_tmp, "aifsn "); - if (pch) { - wme->aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0); - printf("%s: ac_val=%d, aifsn=%d\n", __FUNCTION__, ac_val, wme->aifsn[ac_val]); - } - pick_tmp = pick; - pch = bcmstrstr(pick_tmp, "ecwmin "); - if (pch) { - wme->ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0); - printf("%s: ac_val=%d, ecwmin=%d\n", __FUNCTION__, ac_val, wme->ecwmin[ac_val]); - } - pick_tmp = pick; - pch = bcmstrstr(pick_tmp, "ecwmax "); - if (pch) { - wme->ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0); - printf("%s: ac_val=%d, ecwmax=%d\n", __FUNCTION__, ac_val, wme->ecwmax[ac_val]); - } - pick_tmp = pick; - pch = bcmstrstr(pick_tmp, "txop "); - if (pch) { - wme->txop[ac_val] = (int)simple_strtol(pch+strlen("txop "), NULL, 0); - printf("%s: ac_val=%d, txop=0x%x\n", __FUNCTION__, ac_val, wme->txop[ac_val]); - } - -} - -bool -dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *full_param, uint len_param) -{ - struct dhd_conf *conf = dhd->conf; - char *data = full_param+len_param; - - // wme_ac_sta_be=aifsn 1 ecwmin 2 ecwmax 3 txop 0x5e - // wme_ac_sta_vo=aifsn 1 ecwmin 1 ecwmax 1 txop 0x5e - - /* Process WMM parameters */ - if (!strncmp("force_wme_ac=", full_param, len_param)) { - conf->force_wme_ac = (int)simple_strtol(data, NULL, 10); - printf("%s: force_wme_ac = %d\n", __FUNCTION__, conf->force_wme_ac); - } - else if (!strncmp("wme_ac_sta_be=", full_param, len_param)) { - dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BE); - } - else if (!strncmp("wme_ac_sta_bk=", full_param, len_param)) { - dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BK); - } - else if (!strncmp("wme_ac_sta_vi=", full_param, len_param)) { - dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VI); - } - else if (!strncmp("wme_ac_sta_vo=", full_param, len_param)) { - dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VO); - } - else if (!strncmp("wme_ac_ap_be=", full_param, len_param)) { - dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BE); - } - else if (!strncmp("wme_ac_ap_bk=", full_param, len_param)) { - dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BK); - } - else if (!strncmp("wme_ac_ap_vi=", full_param, len_param)) { - dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VI); - } - else if (!strncmp("wme_ac_ap_vo=", full_param, len_param)) { - dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VO); - } - else - return false; - - return true; -} - -bool -dhd_conf_read_fw_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param) -{ - int i, j; - char *pch, *pick_tmp; - wl_mac_list_t *mac_list; - wl_mac_range_t *mac_range; - struct dhd_conf *conf = dhd->conf; - char *data = full_param+len_param; - - /* Process fw_by_mac: - * fw_by_mac=[fw_mac_num] \ - * [fw_name1] [mac_num1] [oui1-1] [nic_start1-1] [nic_end1-1] \ - * [oui1-1] [nic_start1-1] [nic_end1-1]... \ - * [oui1-n] [nic_start1-n] [nic_end1-n] \ - * [fw_name2] [mac_num2] [oui2-1] [nic_start2-1] [nic_end2-1] \ - * [oui2-1] [nic_start2-1] [nic_end2-1]... \ - * [oui2-n] [nic_start2-n] [nic_end2-n] \ - * Ex: fw_by_mac=2 \ - * fw_bcmdhd1.bin 2 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \ - * fw_bcmdhd2.bin 3 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \ - * 0x983B16 0x916157 0x916487 - */ - - if (!strncmp("fw_by_mac=", full_param, len_param)) { - pick_tmp = data; - pch = bcmstrtok(&pick_tmp, " ", 0); - conf->fw_by_mac.count = (uint32)simple_strtol(pch, NULL, 0); - if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->fw_by_mac.count, GFP_KERNEL))) { - conf->fw_by_mac.count = 0; - CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - } - printf("%s: fw_count=%d\n", __FUNCTION__, conf->fw_by_mac.count); - conf->fw_by_mac.m_mac_list_head = mac_list; - for (i=0; ifw_by_mac.count; i++) { - pch = bcmstrtok(&pick_tmp, " ", 0); - strcpy(mac_list[i].name, pch); - pch = bcmstrtok(&pick_tmp, " ", 0); - mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0); - printf("%s: name=%s, mac_count=%d\n", __FUNCTION__, - mac_list[i].name, mac_list[i].count); - if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) { - mac_list[i].count = 0; - CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - break; - } - mac_list[i].mac = mac_range; - for (j=0; jconf; - char *data = full_param+len_param; - - /* Process nv_by_mac: - * [nv_by_mac]: The same format as fw_by_mac - */ - if (!strncmp("nv_by_mac=", full_param, len_param)) { - pick_tmp = data; - pch = bcmstrtok(&pick_tmp, " ", 0); - conf->nv_by_mac.count = (uint32)simple_strtol(pch, NULL, 0); - if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_mac.count, GFP_KERNEL))) { - conf->nv_by_mac.count = 0; - CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - } - printf("%s: nv_count=%d\n", __FUNCTION__, conf->nv_by_mac.count); - conf->nv_by_mac.m_mac_list_head = mac_list; - for (i=0; inv_by_mac.count; i++) { - pch = bcmstrtok(&pick_tmp, " ", 0); - strcpy(mac_list[i].name, pch); - pch = bcmstrtok(&pick_tmp, " ", 0); - mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0); - printf("%s: name=%s, mac_count=%d\n", __FUNCTION__, - mac_list[i].name, mac_list[i].count); - if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) { - mac_list[i].count = 0; - CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); - break; - } - mac_list[i].mac = mac_range; - for (j=0; jconf; - char *data = full_param+len_param; - - /* Process nv_by_chip: - * nv_by_chip=[nv_chip_num] \ - * [chip1] [chiprev1] [nv_name1] [chip2] [chiprev2] [nv_name2] \ - * Ex: nv_by_chip=2 \ - * 43430 0 nvram_ap6212.txt 43430 1 nvram_ap6212a.txt \ - */ - if (!strncmp("nv_by_chip=", full_param, len_param)) { - pick_tmp = data; - 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); - } - } - else - return false; - - return true; -} - -bool -dhd_conf_read_roam_params(dhd_pub_t *dhd, char *full_param, uint len_param) -{ - struct dhd_conf *conf = dhd->conf; - char *data = full_param+len_param; - - if (!strncmp("roam_off=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - conf->roam_off = 0; - else - conf->roam_off = 1; - printf("%s: roam_off = %d\n", __FUNCTION__, conf->roam_off); - } - else if (!strncmp("roam_off_suspend=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - conf->roam_off_suspend = 0; - else - conf->roam_off_suspend = 1; - printf("%s: roam_off_suspend = %d\n", __FUNCTION__, conf->roam_off_suspend); - } - else if (!strncmp("roam_trigger=", full_param, len_param)) { - conf->roam_trigger[0] = (int)simple_strtol(data, NULL, 10); - printf("%s: roam_trigger = %d\n", __FUNCTION__, - conf->roam_trigger[0]); - } - else if (!strncmp("roam_scan_period=", full_param, len_param)) { - conf->roam_scan_period[0] = (int)simple_strtol(data, NULL, 10); - printf("%s: roam_scan_period = %d\n", __FUNCTION__, - conf->roam_scan_period[0]); - } - else if (!strncmp("roam_delta=", full_param, len_param)) { - conf->roam_delta[0] = (int)simple_strtol(data, NULL, 10); - printf("%s: roam_delta = %d\n", __FUNCTION__, conf->roam_delta[0]); - } - else if (!strncmp("fullroamperiod=", full_param, len_param)) { - conf->fullroamperiod = (int)simple_strtol(data, NULL, 10); - printf("%s: fullroamperiod = %d\n", __FUNCTION__, - conf->fullroamperiod); - } else - return false; - - return true; -} - -bool -dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param) -{ - int i; - char *pch, *pick_tmp; - struct dhd_conf *conf = dhd->conf; - char *data = full_param+len_param; - - /* Process country_list: - * country_list=[country1]:[ccode1]/[regrev1], - * [country2]:[ccode2]/[regrev2] \ - * Ex: country_list=US:US/0, TW:TW/1 - */ - if (!strncmp("country_list=", full_param, len_param)) { - pick_tmp = data; - for (i=0; icountry_list.cspec[i].country_abbrev, pch); - pch = bcmstrtok(&pick_tmp, "/", 0); - if (!pch) - break; - memcpy(conf->country_list.cspec[i].ccode, pch, 2); - pch = bcmstrtok(&pick_tmp, ", ", 0); - if (!pch) - break; - conf->country_list.cspec[i].rev = (int32)simple_strtol(pch, NULL, 10); - conf->country_list.count ++; - CONFIG_TRACE(("%s: country_list abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__, - conf->country_list.cspec[i].country_abbrev, - conf->country_list.cspec[i].ccode, - conf->country_list.cspec[i].rev)); - } - printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count); - } - else - return false; - - return true; -} - -#ifdef PKT_FILTER_SUPPORT -bool -dhd_conf_read_pkt_filter(dhd_pub_t *dhd, char *full_param, uint len_param) -{ - struct dhd_conf *conf = dhd->conf; - char *data = full_param+len_param; - char *pch, *pick_tmp; - int i; - - /* Process pkt filter: - * 1) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000 - * 2) pkt_filter_del=100, 102, 103, 104, 105 - * 3) magic_pkt_filter_add=141 0 1 12 - */ - if (!strncmp("dhd_master_mode=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - dhd_master_mode = FALSE; - else - dhd_master_mode = TRUE; - printf("%s: dhd_master_mode = %d\n", __FUNCTION__, dhd_master_mode); - } - else if (!strncmp("pkt_filter_add=", full_param, len_param)) { - pick_tmp = data; - pch = bcmstrtok(&pick_tmp, ",.-", 0); - i=0; - while (pch != NULL && ipkt_filter_add.filter[i][0], pch); - printf("%s: pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->pkt_filter_add.filter[i][0]); - pch = bcmstrtok(&pick_tmp, ",.-", 0); - i++; - } - conf->pkt_filter_add.count = i; - } - else if (!strncmp("pkt_filter_del=", full_param, len_param)) { - pick_tmp = data; - pch = bcmstrtok(&pick_tmp, " ,.-", 0); - i=0; - while (pch != NULL && ipkt_filter_del.id[i] = (uint32)simple_strtol(pch, NULL, 10); - pch = bcmstrtok(&pick_tmp, " ,.-", 0); - i++; - } - conf->pkt_filter_del.count = i; - printf("%s: pkt_filter_del id = ", __FUNCTION__); - for (i=0; ipkt_filter_del.count; i++) - printf("%d ", conf->pkt_filter_del.id[i]); - printf("\n"); - } - else if (!strncmp("magic_pkt_filter_add=", full_param, len_param)) { - pick_tmp = data; - pch = bcmstrtok(&pick_tmp, ",.-", 0); - i=0; - while (pch != NULL && imagic_pkt_filter_add.filter[i][0], pch); - printf("%s: magic_pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->magic_pkt_filter_add.filter[i][0]); - pch = bcmstrtok(&pick_tmp, ",.-", 0); - i++; - } - conf->magic_pkt_filter_add.count = i; - } - else - return false; - - return true; -} -#endif - -#ifdef IAPSTA_PREINIT -/* - * iapsta_init=mode [sta|ap|apsta|dualap] vifname [wlan1] - * iapsta_config=ifname [wlan0|wlan1] ssid [xxx] chan [x] - hidden [y|n] maxassoc [x] - amode [open|shared|wpapsk|wpa2psk|wpawpa2psk] - emode [none|wep|tkip|aes|tkipaes] - key [xxxxx] - * iapsta_enable=ifname [wlan0|wlan1] -*/ -bool -dhd_conf_read_iapsta(dhd_pub_t *dhd, char *full_param, uint len_param) -{ - struct dhd_conf *conf = dhd->conf; - char *data = full_param+len_param; - - if (!strncmp("iapsta_init=", full_param, len_param)) { - sprintf(conf->iapsta_init, "iapsta_init %s", data); - printf("%s: iapsta_init=%s\n", __FUNCTION__, conf->iapsta_init); - } - else if (!strncmp("iapsta_config=", full_param, len_param)) { - sprintf(conf->iapsta_config, "iapsta_config %s", data); - printf("%s: iapsta_config=%s\n", __FUNCTION__, conf->iapsta_config); - } - else if (!strncmp("iapsta_enable=", full_param, len_param)) { - sprintf(conf->iapsta_enable, "iapsta_enable %s", data); - printf("%s: iapsta_enable=%s\n", __FUNCTION__, conf->iapsta_enable); - } - else - return false; - - return true; -} -#endif - -#ifdef IDHCPC -bool -dhd_conf_read_dhcp_params(dhd_pub_t *dhd, char *full_param, uint len_param) -{ - struct dhd_conf *conf = dhd->conf; - char *data = full_param+len_param; - - if (!strncmp("dhcpc_enable=", full_param, len_param)) { - conf->dhcpc_enable = (int)simple_strtol(data, NULL, 10); - printf("%s: dhcpc_enable = %d\n", __FUNCTION__, conf->dhcpc_enable); - } - else - return false; - - return true; -} -#endif - -#ifdef BCMSDIO -bool -dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param) -{ - struct dhd_conf *conf = dhd->conf; - char *data = full_param+len_param; - - if (!strncmp("dhd_doflow=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - dhd_doflow = FALSE; - else - dhd_doflow = TRUE; - printf("%s: dhd_doflow = %d\n", __FUNCTION__, dhd_doflow); - } - else if (!strncmp("dhd_slpauto=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - dhd_slpauto = FALSE; - else - dhd_slpauto = TRUE; - printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto); - } - else if (!strncmp("kso_enable=", full_param, len_param)) { - if (!strncmp(data, "1", 1)) - dhd_slpauto = FALSE; - else - dhd_slpauto = TRUE; - printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto); - } - else if (!strncmp("bus:txglom=", full_param, len_param)) { - conf->bus_txglom = (int)simple_strtol(data, NULL, 10); - printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom); - } - else if (!strncmp("use_rxchain=", full_param, len_param)) { - conf->use_rxchain = (int)simple_strtol(data, NULL, 10); - printf("%s: use_rxchain = %d\n", __FUNCTION__, conf->use_rxchain); - } - else if (!strncmp("dhd_txminmax=", full_param, len_param)) { - conf->dhd_txminmax = (uint)simple_strtol(data, NULL, 10); - printf("%s: dhd_txminmax = %d\n", __FUNCTION__, conf->dhd_txminmax); - } - else if (!strncmp("txinrx_thres=", full_param, len_param)) { - conf->txinrx_thres = (int)simple_strtol(data, NULL, 10); - printf("%s: txinrx_thres = %d\n", __FUNCTION__, conf->txinrx_thres); - } - else if (!strncmp("sd_f2_blocksize=", full_param, len_param)) { - conf->sd_f2_blocksize = (int)simple_strtol(data, NULL, 10); - printf("%s: sd_f2_blocksize = %d\n", __FUNCTION__, conf->sd_f2_blocksize); - } - else if (!strncmp("oob_enabled_later=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - conf->oob_enabled_later = FALSE; - else - conf->oob_enabled_later = TRUE; - printf("%s: oob_enabled_later = %d\n", __FUNCTION__, conf->oob_enabled_later); - } -#if defined(BCMSDIOH_TXGLOM) - else if (!strncmp("txglomsize=", full_param, len_param)) { - conf->txglomsize = (uint)simple_strtol(data, NULL, 10); - if (conf->txglomsize > SDPCM_MAXGLOM_SIZE) - conf->txglomsize = SDPCM_MAXGLOM_SIZE; - printf("%s: txglomsize = %d\n", __FUNCTION__, conf->txglomsize); - } - else if (!strncmp("swtxglom=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - conf->swtxglom = FALSE; - else - conf->swtxglom = TRUE; - printf("%s: swtxglom = %d\n", __FUNCTION__, conf->swtxglom); - } - else if (!strncmp("txglom_ext=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - conf->txglom_ext = FALSE; - else - conf->txglom_ext = TRUE; - printf("%s: txglom_ext = %d\n", __FUNCTION__, conf->txglom_ext); - if (conf->txglom_ext) { - if ((conf->chip == BCM43362_CHIP_ID) || (conf->chip == BCM4330_CHIP_ID)) - conf->txglom_bucket_size = 1680; - else if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || - conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) - conf->txglom_bucket_size = 1684; - } - printf("%s: txglom_bucket_size = %d\n", __FUNCTION__, conf->txglom_bucket_size); - } - else if (!strncmp("bus:rxglom=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - conf->bus_rxglom = FALSE; - else - conf->bus_rxglom = TRUE; - printf("%s: bus:rxglom = %d\n", __FUNCTION__, conf->bus_rxglom); - } - else if (!strncmp("dhd_poll=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - conf->dhd_poll = 0; - else - conf->dhd_poll = 1; - printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll); - } - else if (!strncmp("deferred_tx_len=", full_param, len_param)) { - conf->deferred_tx_len = (int)simple_strtol(data, NULL, 10); - printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len); - } - else if (!strncmp("txctl_tmo_fix=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - conf->txctl_tmo_fix = FALSE; - else - conf->txctl_tmo_fix = TRUE; - printf("%s: txctl_tmo_fix = %d\n", __FUNCTION__, conf->txctl_tmo_fix); - } - else if (!strncmp("tx_in_rx=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - conf->tx_in_rx = FALSE; - else - conf->tx_in_rx = TRUE; - printf("%s: tx_in_rx = %d\n", __FUNCTION__, conf->tx_in_rx); - } - else if (!strncmp("tx_max_offset=", full_param, len_param)) { - conf->tx_max_offset = (int)simple_strtol(data, NULL, 10); - printf("%s: tx_max_offset = %d\n", __FUNCTION__, conf->tx_max_offset); - } - else if (!strncmp("txglom_mode=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - conf->txglom_mode = FALSE; - else - conf->txglom_mode = TRUE; - printf("%s: txglom_mode = %d\n", __FUNCTION__, conf->txglom_mode); - } -#endif - else - return false; - - return true; -} -#endif - -bool -dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param) -{ - struct dhd_conf *conf = dhd->conf; - char *data = full_param+len_param; - - if (!strncmp("lpc=", full_param, len_param)) { - conf->lpc = (int)simple_strtol(data, NULL, 10); - printf("%s: lpc = %d\n", __FUNCTION__, conf->lpc); - } - else if (!strncmp("deepsleep=", full_param, len_param)) { - if (!strncmp(data, "1", 1)) - conf->deepsleep = TRUE; - else - conf->deepsleep = FALSE; - printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep); - } - else if (!strncmp("PM=", full_param, len_param)) { - conf->pm = (int)simple_strtol(data, NULL, 10); - printf("%s: PM = %d\n", __FUNCTION__, conf->pm); - } - else if (!strncmp("pm_in_suspend=", full_param, len_param)) { - conf->pm_in_suspend = (int)simple_strtol(data, NULL, 10); - printf("%s: pm_in_suspend = %d\n", __FUNCTION__, conf->pm_in_suspend); - } - else if (!strncmp("pm2_sleep_ret=", full_param, len_param)) { - conf->pm2_sleep_ret = (int)simple_strtol(data, NULL, 10); - printf("%s: pm2_sleep_ret = %d\n", __FUNCTION__, conf->pm2_sleep_ret); - } - else if (!strncmp("xmit_in_suspend=", full_param, len_param)) { - if (!strncmp(data, "1", 1)) - conf->xmit_in_suspend = TRUE; - else - conf->xmit_in_suspend = FALSE; - printf("%s: xmit_in_suspend = %d\n", __FUNCTION__, conf->xmit_in_suspend); - } - else - return false; - - return true; -} - -bool -dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param) -{ - struct dhd_conf *conf = dhd->conf; - char *data = full_param+len_param; - uint len_data = strlen(data); - char *pch, *pick_tmp; - int i; - - if (!strncmp("band=", full_param, len_param)) { - /* Process band: - * band=a for 5GHz only and band=b for 2.4GHz only - */ - if (!strcmp(data, "b")) - conf->band = WLC_BAND_2G; - else if (!strcmp(data, "a")) - conf->band = WLC_BAND_5G; - else - conf->band = WLC_BAND_AUTO; - printf("%s: band = %d\n", __FUNCTION__, conf->band); - } - else if (!strncmp("mimo_bw_cap=", full_param, len_param)) { - conf->mimo_bw_cap = (uint)simple_strtol(data, NULL, 10); - printf("%s: mimo_bw_cap = %d\n", __FUNCTION__, conf->mimo_bw_cap); - } - else if (!strncmp("bw_cap_2g=", full_param, len_param)) { - conf->bw_cap_2g = (uint)simple_strtol(data, NULL, 0); - printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_2g); - } - else if (!strncmp("bw_cap_5g=", full_param, len_param)) { - conf->bw_cap_5g = (uint)simple_strtol(data, NULL, 0); - printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_5g); - } - else if (!strncmp("ccode=", full_param, len_param)) { - memset(&conf->cspec, 0, sizeof(wl_country_t)); - memcpy(conf->cspec.country_abbrev, data, len_data); - memcpy(conf->cspec.ccode, data, len_data); - printf("%s: ccode = %s\n", __FUNCTION__, conf->cspec.ccode); - } - else if (!strncmp("regrev=", full_param, len_param)) { - conf->cspec.rev = (int32)simple_strtol(data, NULL, 10); - printf("%s: regrev = %d\n", __FUNCTION__, conf->cspec.rev); - } - else if (!strncmp("channels=", full_param, len_param)) { - pick_tmp = data; - pch = bcmstrtok(&pick_tmp, " ,.-", 0); - i=0; - while (pch != NULL && ichannels.channel[i] = (uint32)simple_strtol(pch, NULL, 10); - pch = bcmstrtok(&pick_tmp, " ,.-", 0); - i++; - } - conf->channels.count = i; - printf("%s: channels = ", __FUNCTION__); - for (i=0; ichannels.count; i++) - printf("%d ", conf->channels.channel[i]); - printf("\n"); - } - else if (!strncmp("keep_alive_period=", full_param, len_param)) { - conf->keep_alive_period = (uint)simple_strtol(data, NULL, 10); - printf("%s: keep_alive_period = %d\n", __FUNCTION__, - conf->keep_alive_period); - } - else if (!strncmp("stbc=", full_param, len_param)) { - conf->stbc = (int)simple_strtol(data, NULL, 10); - printf("%s: stbc = %d\n", __FUNCTION__, conf->stbc); - } - else if (!strncmp("phy_oclscdenable=", full_param, len_param)) { - conf->phy_oclscdenable = (int)simple_strtol(data, NULL, 10); - printf("%s: phy_oclscdenable = %d\n", __FUNCTION__, conf->phy_oclscdenable); - } - else if (!strncmp("srl=", full_param, len_param)) { - conf->srl = (int)simple_strtol(data, NULL, 10); - printf("%s: srl = %d\n", __FUNCTION__, conf->srl); - } - else if (!strncmp("lrl=", full_param, len_param)) { - conf->lrl = (int)simple_strtol(data, NULL, 10); - printf("%s: lrl = %d\n", __FUNCTION__, conf->lrl); - } - else if (!strncmp("bcn_timeout=", full_param, len_param)) { - conf->bcn_timeout= (uint)simple_strtol(data, NULL, 10); - printf("%s: bcn_timeout = %d\n", __FUNCTION__, conf->bcn_timeout); - } - else if (!strncmp("ampdu_ba_wsize=", full_param, len_param)) { - conf->ampdu_ba_wsize = (int)simple_strtol(data, NULL, 10); - printf("%s: ampdu_ba_wsize = %d\n", __FUNCTION__, conf->ampdu_ba_wsize); - } - else if (!strncmp("ampdu_hostreorder=", full_param, len_param)) { - conf->ampdu_hostreorder = (int)simple_strtol(data, NULL, 10); - printf("%s: ampdu_hostreorder = %d\n", __FUNCTION__, conf->ampdu_hostreorder); - } - else if (!strncmp("spect=", full_param, len_param)) { - conf->spect = (int)simple_strtol(data, NULL, 10); - printf("%s: spect = %d\n", __FUNCTION__, conf->spect); - } - else if (!strncmp("txbf=", full_param, len_param)) { - conf->txbf = (int)simple_strtol(data, NULL, 10); - printf("%s: txbf = %d\n", __FUNCTION__, conf->txbf); - } - else if (!strncmp("frameburst=", full_param, len_param)) { - conf->frameburst = (int)simple_strtol(data, NULL, 10); - printf("%s: frameburst = %d\n", __FUNCTION__, conf->frameburst); - } - else if (!strncmp("disable_proptx=", full_param, len_param)) { - conf->disable_proptx = (int)simple_strtol(data, NULL, 10); - printf("%s: disable_proptx = %d\n", __FUNCTION__, conf->disable_proptx); - } -#ifdef DHDTCPACK_SUPPRESS - else if (!strncmp("tcpack_sup_mode=", full_param, len_param)) { - conf->tcpack_sup_mode = (uint)simple_strtol(data, NULL, 10); - printf("%s: tcpack_sup_mode = %d\n", __FUNCTION__, conf->tcpack_sup_mode); - } -#endif - else if (!strncmp("pktprio8021x=", full_param, len_param)) { - conf->pktprio8021x = (int)simple_strtol(data, NULL, 10); - printf("%s: pktprio8021x = %d\n", __FUNCTION__, conf->pktprio8021x); - } - else if (!strncmp("dhd_txbound=", full_param, len_param)) { - dhd_txbound = (uint)simple_strtol(data, NULL, 10); - printf("%s: dhd_txbound = %d\n", __FUNCTION__, dhd_txbound); - } - else if (!strncmp("dhd_rxbound=", full_param, len_param)) { - dhd_rxbound = (uint)simple_strtol(data, NULL, 10); - printf("%s: dhd_rxbound = %d\n", __FUNCTION__, dhd_rxbound); - } - else if (!strncmp("rsdb_mode=", full_param, len_param)) { - conf->rsdb_mode = (int)simple_strtol(data, NULL, 10); - printf("%s: rsdb_mode = %d\n", __FUNCTION__, conf->rsdb_mode); - } - else if (!strncmp("vhtmode=", full_param, len_param)) { - if (!strncmp(data, "0", 1)) - conf->vhtmode = 0; - else - conf->vhtmode = 1; - printf("%s: vhtmode = %d\n", __FUNCTION__, conf->vhtmode); - } - else if (!strncmp("num_different_channels=", full_param, len_param)) { - conf->num_different_channels = (int)simple_strtol(data, NULL, 10); - printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels); - } - else if (!strncmp("autocountry=", full_param, len_param)) { - conf->autocountry = (int)simple_strtol(data, NULL, 10); - printf("%s: autocountry = %d\n", __FUNCTION__, conf->autocountry); - } - else if (!strncmp("tsq=", full_param, len_param)) { - conf->tsq = (int)simple_strtol(data, NULL, 10); - printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq); - } - else - return false; - - return true; -} - -int -dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path) -{ - int bcmerror = -1; - uint len, start_pos=0; - void * image = NULL; - char * memblock = NULL; - char *bufp, *pick = NULL, *pch; - bool conf_file_exists; - uint len_param; - - conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0')); - if (!conf_file_exists) { - printf("%s: config path %s\n", __FUNCTION__, conf_path); - return (0); - } - - if (conf_file_exists) { - image = dhd_os_open_image(conf_path); - if (image == NULL) { - printf("%s: Ignore config file %s\n", __FUNCTION__, conf_path); - goto err; - } - } - - memblock = MALLOC(dhd->osh, MAXSZ_CONFIG); - if (memblock == NULL) { - CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n", - __FUNCTION__, MAXSZ_CONFIG)); - goto err; - } - - pick = MALLOC(dhd->osh, MAXSZ_BUF); - if (!pick) { - CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n", - __FUNCTION__, MAXSZ_BUF)); - goto err; - } - - /* Read variables */ - if (conf_file_exists) { - len = dhd_os_get_image_block(memblock, MAXSZ_CONFIG, image); - } - if (len > 0 && len < MAXSZ_CONFIG) { - bufp = (char *)memblock; - bufp[len] = 0; - - while (start_pos < len) { - memset(pick, 0, MAXSZ_BUF); - start_pos = pick_config_vars(bufp, len, start_pos, pick); - pch = strchr(pick, '='); - if (pch != NULL) { - len_param = pch-pick+1; - if (len_param == strlen(pick)) { - CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick)); - continue; - } - } else { - CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick)); - continue; - } - - if (dhd_conf_read_log_level(dhd, pick, len_param)) - continue; - else if (dhd_conf_read_roam_params(dhd, pick, len_param)) - continue; - else if (dhd_conf_read_wme_ac_params(dhd, pick, len_param)) - continue; - else if (dhd_conf_read_fw_by_mac(dhd, pick, len_param)) - continue; - else if (dhd_conf_read_nv_by_mac(dhd, pick, len_param)) - continue; - else if (dhd_conf_read_nv_by_chip(dhd, pick, len_param)) - continue; - else if (dhd_conf_read_country_list(dhd, pick, len_param)) - continue; -#ifdef PKT_FILTER_SUPPORT - else if (dhd_conf_read_pkt_filter(dhd, pick, len_param)) - continue; -#endif /* PKT_FILTER_SUPPORT */ -#ifdef IAPSTA_PREINIT - else if (dhd_conf_read_iapsta(dhd, pick, len_param)) - continue; -#endif /* IAPSTA_PREINIT */ -#ifdef IDHCPC - else if (dhd_conf_read_dhcp_params(dhd, pick, len_param)) - continue; -#endif /* IDHCPC */ -#ifdef BCMSDIO - else if (dhd_conf_read_sdio_params(dhd, pick, len_param)) - continue; -#endif /* BCMSDIO */ - else if (dhd_conf_read_pm_params(dhd, pick, len_param)) - continue; - else if (dhd_conf_read_others(dhd, pick, len_param)) - continue; + int bcmerror = -1; + struct dhd_conf *conf = dhd->conf; + + dhd_roam_disable = conf->roam_off; + dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_off", dhd->conf->roam_off, 0, FALSE); + + if (!conf->roam_off || !conf->roam_off_suspend) { + printf("%s: set roam_trigger %d\n", __FUNCTION__, conf->roam_trigger[0]); + dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_TRIGGER, "WLC_SET_ROAM_TRIGGER", + (char *)conf->roam_trigger, sizeof(conf->roam_trigger), FALSE); + + printf("%s: set roam_scan_period %d\n", __FUNCTION__, conf->roam_scan_period[0]); + dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_SCAN_PERIOD, "WLC_SET_ROAM_SCAN_PERIOD", + (char *)conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE); + + printf("%s: set roam_delta %d\n", __FUNCTION__, conf->roam_delta[0]); + dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_DELTA, "WLC_SET_ROAM_DELTA", + (char *)conf->roam_delta, sizeof(conf->roam_delta), FALSE); + + dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "fullroamperiod", dhd->conf->fullroamperiod, 1, FALSE); + } + + return bcmerror; +} + +void +dhd_conf_set_bw_cap(dhd_pub_t *dhd) +{ + struct { + u32 band; + u32 bw_cap; + } param = {0, 0}; + + if (dhd->conf->bw_cap_2g >= 0) { + param.band = WLC_BAND_2G; + param.bw_cap = (uint)dhd->conf->bw_cap_2g; + printf("%s: set bw_cap 2g %d\n", __FUNCTION__, param.bw_cap); + dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)¶m, sizeof(param), TRUE); + } + + if (dhd->conf->bw_cap_5g >= 0) { + param.band = WLC_BAND_5G; + param.bw_cap = (uint)dhd->conf->bw_cap_5g; + printf("%s: set bw_cap 5g %d\n", __FUNCTION__, param.bw_cap); + dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)¶m, sizeof(param), TRUE); + } +} + +void +dhd_conf_get_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acp) +{ + int bcmerror = -1; + char iovbuf[WLC_IOCTL_SMLEN]; + edcf_acparam_t *acparam; + + bzero(iovbuf, sizeof(iovbuf)); + + /* + * Get current acparams, using buf as an input buffer. + * Return data is array of 4 ACs of wme params. + */ + if (mode == 0) + bcm_mkiovar("wme_ac_sta", NULL, 0, iovbuf, sizeof(iovbuf)); + else + bcm_mkiovar("wme_ac_ap", NULL, 0, iovbuf, sizeof(iovbuf)); + if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) { + CONFIG_ERROR(("%s: wme_ac_sta getting failed %d\n", __FUNCTION__, bcmerror)); + return; + } + 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 txop 0x%x\n", + __FUNCTION__, + acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, + acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, + acparam->TXOP)); + acparam = &acp[AC_BE]; + CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", + __FUNCTION__, + acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, + acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, + acparam->TXOP)); + acparam = &acp[AC_VI]; + CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", + __FUNCTION__, + acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, + acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, + acparam->TXOP)); + acparam = &acp[AC_VO]; + CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", + __FUNCTION__, + acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, + acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, + acparam->TXOP)); + + return; +} + +void +dhd_conf_update_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acparam_cur, int aci) +{ + int aifsn, ecwmin, ecwmax, txop; + edcf_acparam_t *acp; + struct dhd_conf *conf = dhd->conf; + wme_param_t *wme; + + if (mode == 0) + wme = &conf->wme_sta; + else + wme = &conf->wme_ap; + + /* Default value */ + aifsn = acparam_cur->ACI&EDCF_AIFSN_MASK; + ecwmin = acparam_cur->ECW&EDCF_ECWMIN_MASK; + ecwmax = (acparam_cur->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT; + txop = acparam_cur->TXOP; + + /* Modified value */ + if (wme->aifsn[aci] > 0) + aifsn = wme->aifsn[aci]; + if (wme->ecwmin[aci] > 0) + ecwmin = wme->ecwmin[aci]; + if (wme->ecwmax[aci] > 0) + ecwmax = wme->ecwmax[aci]; + if (wme->txop[aci] > 0) + txop = wme->txop[aci]; + + if (!(wme->aifsn[aci] || wme->ecwmin[aci] || + wme->ecwmax[aci] || wme->txop[aci])) + return; + + /* Update */ + acp = acparam_cur; + acp->ACI = (acp->ACI & ~EDCF_AIFSN_MASK) | (aifsn & EDCF_AIFSN_MASK); + 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)); + acp->TXOP = txop; + + printf("%s: wme_ac %s aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", + __FUNCTION__, mode?"ap":"sta", + acp->ACI, acp->ACI&EDCF_AIFSN_MASK, + acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, + acp->TXOP); + + /* + * Now use buf as an output buffer. + * Put WME acparams after "wme_ac\0" in buf. + * NOTE: only one of the four ACs can be set at a time. + */ + if (mode == 0) + dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE); + else + dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_ap", (char *)acp, sizeof(edcf_acparam_t), FALSE); + +} + +void +dhd_conf_set_wme(dhd_pub_t *dhd, int mode) +{ + edcf_acparam_t acparam_cur[AC_COUNT]; + + if (dhd && dhd->conf) { + if (!dhd->conf->force_wme_ac) { + CONFIG_TRACE(("%s: force_wme_ac is not enabled %d\n", + __FUNCTION__, dhd->conf->force_wme_ac)); + return; + } + + CONFIG_TRACE(("%s: Before change:\n", __FUNCTION__)); + dhd_conf_get_wme(dhd, mode, acparam_cur); + + dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BK], AC_BK); + dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BE], AC_BE); + dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VI], AC_VI); + dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VO], AC_VO); + + CONFIG_TRACE(("%s: After change:\n", __FUNCTION__)); + dhd_conf_get_wme(dhd, mode, acparam_cur); + } else { + CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__)); + } + + return; +} + +#ifdef PKT_FILTER_SUPPORT +void +dhd_conf_add_pkt_filter(dhd_pub_t *dhd) +{ + int i, j; + char str[12]; +#define MACS "%02x%02x%02x%02x%02x%02x" + + /* + * 1. Filter out all pkt: actually not to enable this since 4-way handshake will be filter out as well. + * 1) dhd_master_mode=0 + * 2) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000 + * 2. Filter in less pkt: ARP(0x0806, ID is 105), BRCM(0x886C), 802.1X(0x888E) + * 1) dhd_master_mode=1 + * 2) pkt_filter_del=100, 102, 103, 104, 105 + * 3) pkt_filter_add=131 0 0 12 0xFFFF 0x886C, 132 0 0 12 0xFFFF 0x888E + * 3. magic pkt: magic_pkt_filter_add=141 0 1 12 + * 4. Filter out netbios pkt: + * Netbios: 121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089 + */ + for (i=0; iconf->pkt_filter_add.count; i++) { + dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[i]; + printf("%s: %s\n", __FUNCTION__, dhd->pktfilter[i+dhd->pktfilter_count]); + } + dhd->pktfilter_count += i; + + for (i=0; iconf->magic_pkt_filter_add.count; i++) { + strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x"); + strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF"); + for (j=0; j<16; j++) + strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF"); + strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x"); + strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF"); + sprintf(str, MACS, MAC2STRDBG(dhd->mac.octet)); + for (j=0; j<16; j++) + strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], str); + dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add.filter[i]; + dhd->pktfilter_count += 1; + } +} + +bool +dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id) +{ + int i; + + if (dhd && dhd->conf) { + for (i=0; iconf->pkt_filter_del.count; i++) { + if (id == dhd->conf->pkt_filter_del.id[i]) { + printf("%s: %d\n", __FUNCTION__, dhd->conf->pkt_filter_del.id[i]); + return true; + } + } + return false; + } + return false; +} + +void +dhd_conf_discard_pkt_filter(dhd_pub_t *dhd) +{ + dhd->pktfilter_count = 6; + dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = NULL; + dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF"; + dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "102 0 0 0 0xFFFFFF 0x01005E"; + dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = "103 0 0 0 0xFFFF 0x3333"; + dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL; + /* Do not enable ARP to pkt filter if dhd_master_mode is false.*/ + dhd->pktfilter[DHD_ARP_FILTER_NUM] = NULL; + + /* IPv4 broadcast address XXX.XXX.XXX.255 */ + dhd->pktfilter[dhd->pktfilter_count] = "110 0 0 12 0xFFFF00000000000000000000000000000000000000FF 0x080000000000000000000000000000000000000000FF"; + dhd->pktfilter_count++; + /* discard IPv4 multicast address 224.0.0.0/4 */ + dhd->pktfilter[dhd->pktfilter_count] = "111 0 0 12 0xFFFF00000000000000000000000000000000F0 0x080000000000000000000000000000000000E0"; + dhd->pktfilter_count++; + /* discard IPv6 multicast address FF00::/8 */ + dhd->pktfilter[dhd->pktfilter_count] = "112 0 0 12 0xFFFF000000000000000000000000000000000000000000000000FF 0x86DD000000000000000000000000000000000000000000000000FF"; + dhd->pktfilter_count++; + /* discard Netbios pkt */ + dhd->pktfilter[dhd->pktfilter_count] = "121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089"; + dhd->pktfilter_count++; + +} +#endif /* PKT_FILTER_SUPPORT */ + +int +dhd_conf_get_pm(dhd_pub_t *dhd) +{ + if (dhd && dhd->conf) + return dhd->conf->pm; + return -1; +} + +#define AP_IN_SUSPEND 1 +#define AP_DOWN_IN_SUSPEND 2 +int +dhd_conf_get_ap_mode_in_suspend(dhd_pub_t *dhd) +{ + int mode = 0; + + /* returned ap_in_suspend value: + * 0: nothing + * 1: ap enabled in suspend + * 2: ap enabled, but down in suspend + */ + if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) { + mode = dhd->conf->ap_in_suspend; + } + + return mode; +} + +int +dhd_conf_set_ap_in_suspend(dhd_pub_t *dhd, int suspend) +{ + int mode = 0; + uint wl_down = 1; + + mode = dhd_conf_get_ap_mode_in_suspend(dhd); + if (mode) + printf("%s: suspend %d, mode %d\n", __FUNCTION__, suspend, mode); + if (suspend) { + if (mode == AP_IN_SUSPEND) { +#ifdef SUSPEND_EVENT + if (dhd->conf->suspend_eventmask_enable) { + char *eventmask = dhd->conf->suspend_eventmask; + dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask, sizeof(eventmask), TRUE); + } +#endif + } else if (mode == AP_DOWN_IN_SUSPEND) + dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_down, sizeof(wl_down), TRUE, 0); + } else { + if (mode == AP_IN_SUSPEND) { +#ifdef SUSPEND_EVENT + if (dhd->conf->suspend_eventmask_enable) { + char *eventmask = dhd->conf->resume_eventmask; + dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask, sizeof(eventmask), TRUE); + } +#endif + } else if (mode == AP_DOWN_IN_SUSPEND) { + wl_down = 0; + dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&wl_down, sizeof(wl_down), TRUE, 0); + } + } + + return mode; +} + +#ifdef PROP_TXSTATUS +int +dhd_conf_get_disable_proptx(dhd_pub_t *dhd) +{ + struct dhd_conf *conf = dhd->conf; + int disable_proptx = -1; + int fw_proptx = 0; + + /* check fw proptx priority: + * 1st: check fw support by wl cap + * 2nd: 4334/43340/43341/43241 support proptx but not show in wl cap, so enable it by default + * if you would like to disable it, please set disable_proptx=1 in config.txt + * 3th: disable when proptxstatus not support in wl cap + */ + if (FW_SUPPORTED(dhd, proptxstatus)) { + fw_proptx = 1; + } else if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID || + dhd->conf->chip == BCM43340_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { + fw_proptx = 1; + } else { + fw_proptx = 0; + } + + /* returned disable_proptx value: + * -1: disable in STA and enable in P2P(follow original dhd settings when PROP_TXSTATUS_VSDB enabled) + * 0: depend on fw support + * 1: always disable proptx + */ + if (conf->disable_proptx == 0) { + // check fw support as well + if (fw_proptx) + disable_proptx = 0; + else + disable_proptx = 1; + } else if (conf->disable_proptx >= 1) { + disable_proptx = 1; + } else { + // check fw support as well + if (fw_proptx) + disable_proptx = -1; + else + disable_proptx = 1; + } + + printf("%s: fw_proptx=%d, disable_proptx=%d\n", __FUNCTION__, fw_proptx, disable_proptx); + + return disable_proptx; +} +#endif + +uint +pick_config_vars(char *varbuf, uint len, uint start_pos, char *pickbuf) +{ + bool findNewline, changenewline=FALSE, pick=FALSE; + int column; + uint n, pick_column=0; + + findNewline = FALSE; + column = 0; + + if (start_pos >= len) { + CONFIG_ERROR(("%s: wrong start pos\n", __FUNCTION__)); + return 0; + } + + for (n = start_pos; n < len; n++) { + if (varbuf[n] == '\r') + continue; + if ((findNewline || changenewline) && varbuf[n] != '\n') + continue; + findNewline = FALSE; + if (varbuf[n] == '#') { + findNewline = TRUE; + continue; + } + if (varbuf[n] == '\\') { + changenewline = TRUE; + continue; + } + if (!changenewline && varbuf[n] == '\n') { + if (column == 0) + continue; + column = 0; + continue; + } + if (changenewline && varbuf[n] == '\n') { + changenewline = FALSE; + continue; + } + + if (column == 0 && !pick) { // start to pick + pick = TRUE; + column++; + pick_column = 0; + } else { + if (pick && column == 0) { // stop to pick + pick = FALSE; + break; + } else + column++; + } + if (pick) { + if (varbuf[n] == 0x9) + continue; + if (pick_column>0 && pickbuf[pick_column-1] == ' ' && varbuf[n] == ' ') + continue; + pickbuf[pick_column] = varbuf[n]; + pick_column++; + } + } + + return n; // return current position +} + +bool +dhd_conf_read_log_level(dhd_pub_t *dhd, char *full_param, uint len_param) +{ + char *data = full_param+len_param; + + if (!strncmp("dhd_msg_level=", full_param, len_param)) { + dhd_msg_level = (int)simple_strtol(data, NULL, 0); + printf("%s: dhd_msg_level = 0x%X\n", __FUNCTION__, dhd_msg_level); + } +#ifdef BCMSDIO + else if (!strncmp("sd_msglevel=", full_param, len_param)) { + sd_msglevel = (int)simple_strtol(data, NULL, 0); + printf("%s: sd_msglevel = 0x%X\n", __FUNCTION__, sd_msglevel); + } +#endif + else if (!strncmp("android_msg_level=", full_param, len_param)) { + android_msg_level = (int)simple_strtol(data, NULL, 0); + printf("%s: android_msg_level = 0x%X\n", __FUNCTION__, android_msg_level); + } + else if (!strncmp("config_msg_level=", full_param, len_param)) { + config_msg_level = (int)simple_strtol(data, NULL, 0); + printf("%s: config_msg_level = 0x%X\n", __FUNCTION__, config_msg_level); + } +#ifdef WL_CFG80211 + else if (!strncmp("wl_dbg_level=", full_param, len_param)) { + wl_dbg_level = (int)simple_strtol(data, NULL, 0); + printf("%s: wl_dbg_level = 0x%X\n", __FUNCTION__, wl_dbg_level); + } +#endif +#if defined(WL_WIRELESS_EXT) + else if (!strncmp("iw_msg_level=", full_param, len_param)) { + iw_msg_level = (int)simple_strtol(data, NULL, 0); + printf("%s: iw_msg_level = 0x%X\n", __FUNCTION__, iw_msg_level); + } +#endif +#if defined(DHD_DEBUG) + else if (!strncmp("dhd_console_ms=", full_param, len_param)) { + dhd_console_ms = (int)simple_strtol(data, NULL, 0); + printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms); + } +#endif + else + return false; + + return true; +} + +void +dhd_conf_read_wme_ac_value(wme_param_t *wme, char *pick, int ac_val) +{ + char *pick_tmp, *pch; + + pick_tmp = pick; + pch = bcmstrstr(pick_tmp, "aifsn "); + if (pch) { + wme->aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0); + printf("%s: ac_val=%d, aifsn=%d\n", __FUNCTION__, ac_val, wme->aifsn[ac_val]); + } + pick_tmp = pick; + pch = bcmstrstr(pick_tmp, "ecwmin "); + if (pch) { + wme->ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0); + printf("%s: ac_val=%d, ecwmin=%d\n", __FUNCTION__, ac_val, wme->ecwmin[ac_val]); + } + pick_tmp = pick; + pch = bcmstrstr(pick_tmp, "ecwmax "); + if (pch) { + wme->ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0); + printf("%s: ac_val=%d, ecwmax=%d\n", __FUNCTION__, ac_val, wme->ecwmax[ac_val]); + } + pick_tmp = pick; + pch = bcmstrstr(pick_tmp, "txop "); + if (pch) { + wme->txop[ac_val] = (int)simple_strtol(pch+strlen("txop "), NULL, 0); + printf("%s: ac_val=%d, txop=0x%x\n", __FUNCTION__, ac_val, wme->txop[ac_val]); + } + +} + +bool +dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *full_param, uint len_param) +{ + struct dhd_conf *conf = dhd->conf; + char *data = full_param+len_param; + + // wme_ac_sta_be=aifsn 1 ecwmin 2 ecwmax 3 txop 0x5e + // wme_ac_sta_vo=aifsn 1 ecwmin 1 ecwmax 1 txop 0x5e + + if (!strncmp("force_wme_ac=", full_param, len_param)) { + conf->force_wme_ac = (int)simple_strtol(data, NULL, 10); + printf("%s: force_wme_ac = %d\n", __FUNCTION__, conf->force_wme_ac); + } + else if (!strncmp("wme_ac_sta_be=", full_param, len_param)) { + dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BE); + } + else if (!strncmp("wme_ac_sta_bk=", full_param, len_param)) { + dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BK); + } + else if (!strncmp("wme_ac_sta_vi=", full_param, len_param)) { + dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VI); + } + else if (!strncmp("wme_ac_sta_vo=", full_param, len_param)) { + dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VO); + } + else if (!strncmp("wme_ac_ap_be=", full_param, len_param)) { + dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BE); + } + else if (!strncmp("wme_ac_ap_bk=", full_param, len_param)) { + dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BK); + } + else if (!strncmp("wme_ac_ap_vi=", full_param, len_param)) { + dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VI); + } + else if (!strncmp("wme_ac_ap_vo=", full_param, len_param)) { + dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VO); + } + else + return false; + + return true; +} + +bool +dhd_conf_read_fw_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param) +{ + int i, j; + char *pch, *pick_tmp; + wl_mac_list_t *mac_list; + wl_mac_range_t *mac_range; + struct dhd_conf *conf = dhd->conf; + char *data = full_param+len_param; + + /* Process fw_by_mac: + * fw_by_mac=[fw_mac_num] \ + * [fw_name1] [mac_num1] [oui1-1] [nic_start1-1] [nic_end1-1] \ + * [oui1-1] [nic_start1-1] [nic_end1-1]... \ + * [oui1-n] [nic_start1-n] [nic_end1-n] \ + * [fw_name2] [mac_num2] [oui2-1] [nic_start2-1] [nic_end2-1] \ + * [oui2-1] [nic_start2-1] [nic_end2-1]... \ + * [oui2-n] [nic_start2-n] [nic_end2-n] \ + * Ex: fw_by_mac=2 \ + * fw_bcmdhd1.bin 2 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \ + * fw_bcmdhd2.bin 3 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \ + * 0x983B16 0x916157 0x916487 + */ + + if (!strncmp("fw_by_mac=", full_param, len_param)) { + pick_tmp = data; + pch = bcmstrtok(&pick_tmp, " ", 0); + conf->fw_by_mac.count = (uint32)simple_strtol(pch, NULL, 0); + if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->fw_by_mac.count, GFP_KERNEL))) { + conf->fw_by_mac.count = 0; + CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); + } + printf("%s: fw_count=%d\n", __FUNCTION__, conf->fw_by_mac.count); + conf->fw_by_mac.m_mac_list_head = mac_list; + for (i=0; ifw_by_mac.count; i++) { + pch = bcmstrtok(&pick_tmp, " ", 0); + strcpy(mac_list[i].name, pch); + pch = bcmstrtok(&pick_tmp, " ", 0); + mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0); + printf("%s: name=%s, mac_count=%d\n", __FUNCTION__, + mac_list[i].name, mac_list[i].count); + if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) { + mac_list[i].count = 0; + CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); + break; + } + mac_list[i].mac = mac_range; + for (j=0; jconf; + char *data = full_param+len_param; + + /* Process nv_by_mac: + * [nv_by_mac]: The same format as fw_by_mac + */ + if (!strncmp("nv_by_mac=", full_param, len_param)) { + pick_tmp = data; + pch = bcmstrtok(&pick_tmp, " ", 0); + conf->nv_by_mac.count = (uint32)simple_strtol(pch, NULL, 0); + if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_mac.count, GFP_KERNEL))) { + conf->nv_by_mac.count = 0; + CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); + } + printf("%s: nv_count=%d\n", __FUNCTION__, conf->nv_by_mac.count); + conf->nv_by_mac.m_mac_list_head = mac_list; + for (i=0; inv_by_mac.count; i++) { + pch = bcmstrtok(&pick_tmp, " ", 0); + strcpy(mac_list[i].name, pch); + pch = bcmstrtok(&pick_tmp, " ", 0); + mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0); + printf("%s: name=%s, mac_count=%d\n", __FUNCTION__, + mac_list[i].name, mac_list[i].count); + if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) { + mac_list[i].count = 0; + CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); + break; + } + mac_list[i].mac = mac_range; + for (j=0; jconf; + char *data = full_param+len_param; + + /* Process nv_by_chip: + * nv_by_chip=[nv_chip_num] \ + * [chip1] [chiprev1] [nv_name1] [chip2] [chiprev2] [nv_name2] \ + * Ex: nv_by_chip=2 \ + * 43430 0 nvram_ap6212.txt 43430 1 nvram_ap6212a.txt \ + */ + if (!strncmp("nv_by_chip=", full_param, len_param)) { + pick_tmp = data; + 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); + } + } + else + return false; + + return true; +} + +bool +dhd_conf_read_roam_params(dhd_pub_t *dhd, char *full_param, uint len_param) +{ + struct dhd_conf *conf = dhd->conf; + char *data = full_param+len_param; + + if (!strncmp("roam_off=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + conf->roam_off = 0; + else + conf->roam_off = 1; + printf("%s: roam_off = %d\n", __FUNCTION__, conf->roam_off); + } + else if (!strncmp("roam_off_suspend=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + conf->roam_off_suspend = 0; + else + conf->roam_off_suspend = 1; + printf("%s: roam_off_suspend = %d\n", __FUNCTION__, conf->roam_off_suspend); + } + else if (!strncmp("roam_trigger=", full_param, len_param)) { + conf->roam_trigger[0] = (int)simple_strtol(data, NULL, 10); + printf("%s: roam_trigger = %d\n", __FUNCTION__, + conf->roam_trigger[0]); + } + else if (!strncmp("roam_scan_period=", full_param, len_param)) { + conf->roam_scan_period[0] = (int)simple_strtol(data, NULL, 10); + printf("%s: roam_scan_period = %d\n", __FUNCTION__, + conf->roam_scan_period[0]); + } + else if (!strncmp("roam_delta=", full_param, len_param)) { + conf->roam_delta[0] = (int)simple_strtol(data, NULL, 10); + printf("%s: roam_delta = %d\n", __FUNCTION__, conf->roam_delta[0]); + } + else if (!strncmp("fullroamperiod=", full_param, len_param)) { + conf->fullroamperiod = (int)simple_strtol(data, NULL, 10); + printf("%s: fullroamperiod = %d\n", __FUNCTION__, + conf->fullroamperiod); + } else + return false; + + return true; +} + +bool +dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param) +{ + int i; + char *pch, *pick_tmp; + struct dhd_conf *conf = dhd->conf; + char *data = full_param+len_param; + + /* Process country_list: + * country_list=[country1]:[ccode1]/[regrev1], + * [country2]:[ccode2]/[regrev2] \ + * Ex: country_list=US:US/0, TW:TW/1 + */ + if (!strncmp("country_list=", full_param, len_param)) { + pick_tmp = data; + for (i=0; icountry_list.cspec[i].country_abbrev, pch); + pch = bcmstrtok(&pick_tmp, "/", 0); + if (!pch) + break; + memcpy(conf->country_list.cspec[i].ccode, pch, 2); + pch = bcmstrtok(&pick_tmp, ", ", 0); + if (!pch) + break; + conf->country_list.cspec[i].rev = (int32)simple_strtol(pch, NULL, 10); + conf->country_list.count ++; + CONFIG_TRACE(("%s: country_list abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__, + conf->country_list.cspec[i].country_abbrev, + conf->country_list.cspec[i].ccode, + conf->country_list.cspec[i].rev)); + } + printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count); + } + else + return false; + + return true; +} + +#ifdef PKT_FILTER_SUPPORT +bool +dhd_conf_read_pkt_filter(dhd_pub_t *dhd, char *full_param, uint len_param) +{ + struct dhd_conf *conf = dhd->conf; + char *data = full_param+len_param; + char *pch, *pick_tmp; + int i; + + /* Process pkt filter: + * 1) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000 + * 2) pkt_filter_del=100, 102, 103, 104, 105 + * 3) magic_pkt_filter_add=141 0 1 12 + */ + if (!strncmp("dhd_master_mode=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + dhd_master_mode = FALSE; + else + dhd_master_mode = TRUE; + printf("%s: dhd_master_mode = %d\n", __FUNCTION__, dhd_master_mode); + } + else if (!strncmp("pkt_filter_add=", full_param, len_param)) { + pick_tmp = data; + pch = bcmstrtok(&pick_tmp, ",.-", 0); + i=0; + while (pch != NULL && ipkt_filter_add.filter[i][0], pch); + printf("%s: pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->pkt_filter_add.filter[i][0]); + pch = bcmstrtok(&pick_tmp, ",.-", 0); + i++; + } + conf->pkt_filter_add.count = i; + } + else if (!strncmp("pkt_filter_del=", full_param, len_param)) { + pick_tmp = data; + pch = bcmstrtok(&pick_tmp, " ,.-", 0); + i=0; + while (pch != NULL && ipkt_filter_del.id[i] = (uint32)simple_strtol(pch, NULL, 10); + pch = bcmstrtok(&pick_tmp, " ,.-", 0); + i++; + } + conf->pkt_filter_del.count = i; + printf("%s: pkt_filter_del id = ", __FUNCTION__); + for (i=0; ipkt_filter_del.count; i++) + printf("%d ", conf->pkt_filter_del.id[i]); + printf("\n"); + } + else if (!strncmp("magic_pkt_filter_add=", full_param, len_param)) { + pick_tmp = data; + pch = bcmstrtok(&pick_tmp, ",.-", 0); + i=0; + while (pch != NULL && imagic_pkt_filter_add.filter[i][0], pch); + printf("%s: magic_pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->magic_pkt_filter_add.filter[i][0]); + pch = bcmstrtok(&pick_tmp, ",.-", 0); + i++; + } + conf->magic_pkt_filter_add.count = i; + } + else + return false; + + return true; +} +#endif + +#ifdef IAPSTA_PREINIT +/* + * iapsta_init=mode [sta|ap|apsta|dualap] vifname [wlan1] + * iapsta_config=ifname [wlan0|wlan1] ssid [xxx] chan [x] + hidden [y|n] maxassoc [x] + amode [open|shared|wpapsk|wpa2psk|wpawpa2psk] + emode [none|wep|tkip|aes|tkipaes] + key [xxxxx] + * iapsta_enable=ifname [wlan0|wlan1] +*/ +bool +dhd_conf_read_iapsta(dhd_pub_t *dhd, char *full_param, uint len_param) +{ + struct dhd_conf *conf = dhd->conf; + char *data = full_param+len_param; + + if (!strncmp("iapsta_init=", full_param, len_param)) { + sprintf(conf->iapsta_init, "iapsta_init %s", data); + printf("%s: iapsta_init=%s\n", __FUNCTION__, conf->iapsta_init); + } + else if (!strncmp("iapsta_config=", full_param, len_param)) { + sprintf(conf->iapsta_config, "iapsta_config %s", data); + printf("%s: iapsta_config=%s\n", __FUNCTION__, conf->iapsta_config); + } + else if (!strncmp("iapsta_enable=", full_param, len_param)) { + sprintf(conf->iapsta_enable, "iapsta_enable %s", data); + printf("%s: iapsta_enable=%s\n", __FUNCTION__, conf->iapsta_enable); + } + else + return false; + + return true; +} +#endif + +#ifdef IDHCP +bool +dhd_conf_read_dhcp_params(dhd_pub_t *dhd, char *full_param, uint len_param) +{ + struct dhd_conf *conf = dhd->conf; + char *data = full_param+len_param; + struct ipv4_addr ipa_set; + + if (!strncmp("dhcpc_enable=", full_param, len_param)) { + conf->dhcpc_enable = (int)simple_strtol(data, NULL, 10); + printf("%s: dhcpc_enable = %d\n", __FUNCTION__, conf->dhcpc_enable); + } + else if (!strncmp("dhcpd_enable=", full_param, len_param)) { + conf->dhcpd_enable = (int)simple_strtol(data, NULL, 10); + printf("%s: dhcpd_enable = %d\n", __FUNCTION__, conf->dhcpd_enable); + } + else if (!strncmp("dhcpd_ip_addr=", full_param, len_param)) { + if (!bcm_atoipv4(data, &ipa_set)) + printf("%s : dhcpd_ip_addr adress setting failed.\n", __FUNCTION__); + conf->dhcpd_ip_addr = ipa_set; + printf("%s: dhcpd_ip_addr = %s\n",__FUNCTION__, data); + } + else if (!strncmp("dhcpd_ip_mask=", full_param, len_param)) { + if (!bcm_atoipv4(data, &ipa_set)) + printf("%s : dhcpd_ip_mask adress setting failed.\n", __FUNCTION__); + conf->dhcpd_ip_mask = ipa_set; + printf("%s: dhcpd_ip_mask = %s\n",__FUNCTION__, data); + } + else if (!strncmp("dhcpd_ip_start=", full_param, len_param)) { + if (!bcm_atoipv4(data, &ipa_set)) + printf("%s : dhcpd_ip_start adress setting failed.\n", __FUNCTION__); + conf->dhcpd_ip_start = ipa_set; + printf("%s: dhcpd_ip_start = %s\n",__FUNCTION__, data); + } + else if (!strncmp("dhcpd_ip_end=", full_param, len_param)) { + if (!bcm_atoipv4(data, &ipa_set)) + printf("%s : dhcpd_ip_end adress setting failed.\n", __FUNCTION__); + conf->dhcpd_ip_end = ipa_set; + printf("%s: dhcpd_ip_end = %s\n",__FUNCTION__, data); + } + else + return false; + + return true; +} +#endif + +#ifdef BCMSDIO +bool +dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param) +{ + struct dhd_conf *conf = dhd->conf; + char *data = full_param+len_param; + + if (!strncmp("dhd_doflow=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + dhd_doflow = FALSE; + else + dhd_doflow = TRUE; + printf("%s: dhd_doflow = %d\n", __FUNCTION__, dhd_doflow); + } + else if (!strncmp("dhd_slpauto=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + dhd_slpauto = FALSE; + else + dhd_slpauto = TRUE; + printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto); + } + else if (!strncmp("kso_enable=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + dhd_slpauto = FALSE; + else + dhd_slpauto = TRUE; + printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto); + } + else if (!strncmp("bus:txglom=", full_param, len_param)) { + conf->bus_txglom = (int)simple_strtol(data, NULL, 10); + printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom); + } + else if (!strncmp("use_rxchain=", full_param, len_param)) { + conf->use_rxchain = (int)simple_strtol(data, NULL, 10); + printf("%s: use_rxchain = %d\n", __FUNCTION__, conf->use_rxchain); + } + else if (!strncmp("dhd_txminmax=", full_param, len_param)) { + conf->dhd_txminmax = (uint)simple_strtol(data, NULL, 10); + printf("%s: dhd_txminmax = %d\n", __FUNCTION__, conf->dhd_txminmax); + } + else if (!strncmp("txinrx_thres=", full_param, len_param)) { + conf->txinrx_thres = (int)simple_strtol(data, NULL, 10); + printf("%s: txinrx_thres = %d\n", __FUNCTION__, conf->txinrx_thres); + } + else if (!strncmp("sd_f2_blocksize=", full_param, len_param)) { + conf->sd_f2_blocksize = (int)simple_strtol(data, NULL, 10); + printf("%s: sd_f2_blocksize = %d\n", __FUNCTION__, conf->sd_f2_blocksize); + } + else if (!strncmp("oob_enabled_later=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + conf->oob_enabled_later = FALSE; + else + conf->oob_enabled_later = TRUE; + printf("%s: oob_enabled_later = %d\n", __FUNCTION__, conf->oob_enabled_later); + } + else if (!strncmp("dpc_cpucore=", full_param, len_param)) { + conf->dpc_cpucore = (int)simple_strtol(data, NULL, 10); + printf("%s: dpc_cpucore = %d\n", __FUNCTION__, conf->dpc_cpucore); + } + else if (!strncmp("rxf_cpucore=", full_param, len_param)) { + conf->rxf_cpucore = (int)simple_strtol(data, NULL, 10); + printf("%s: rxf_cpucore = %d\n", __FUNCTION__, conf->rxf_cpucore); + } +#if defined(BCMSDIOH_TXGLOM) + else if (!strncmp("txglomsize=", full_param, len_param)) { + conf->txglomsize = (uint)simple_strtol(data, NULL, 10); + if (conf->txglomsize > SDPCM_MAXGLOM_SIZE) + conf->txglomsize = SDPCM_MAXGLOM_SIZE; + printf("%s: txglomsize = %d\n", __FUNCTION__, conf->txglomsize); + } + else if (!strncmp("swtxglom=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + conf->swtxglom = FALSE; + else + conf->swtxglom = TRUE; + printf("%s: swtxglom = %d\n", __FUNCTION__, conf->swtxglom); + } + else if (!strncmp("txglom_ext=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + conf->txglom_ext = FALSE; + else + conf->txglom_ext = TRUE; + printf("%s: txglom_ext = %d\n", __FUNCTION__, conf->txglom_ext); + if (conf->txglom_ext) { + if ((conf->chip == BCM43362_CHIP_ID) || (conf->chip == BCM4330_CHIP_ID)) + conf->txglom_bucket_size = 1680; + else if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || + conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) + conf->txglom_bucket_size = 1684; + } + printf("%s: txglom_bucket_size = %d\n", __FUNCTION__, conf->txglom_bucket_size); + } + else if (!strncmp("bus:rxglom=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + conf->bus_rxglom = FALSE; + else + conf->bus_rxglom = TRUE; + printf("%s: bus:rxglom = %d\n", __FUNCTION__, conf->bus_rxglom); + } + else if (!strncmp("dhd_poll=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + conf->dhd_poll = 0; + else + conf->dhd_poll = 1; + printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll); + } + else if (!strncmp("deferred_tx_len=", full_param, len_param)) { + conf->deferred_tx_len = (int)simple_strtol(data, NULL, 10); + printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len); + } + else if (!strncmp("txctl_tmo_fix=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + conf->txctl_tmo_fix = FALSE; + else + conf->txctl_tmo_fix = TRUE; + printf("%s: txctl_tmo_fix = %d\n", __FUNCTION__, conf->txctl_tmo_fix); + } + else if (!strncmp("tx_in_rx=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + conf->tx_in_rx = FALSE; + else + conf->tx_in_rx = TRUE; + printf("%s: tx_in_rx = %d\n", __FUNCTION__, conf->tx_in_rx); + } + else if (!strncmp("tx_max_offset=", full_param, len_param)) { + conf->tx_max_offset = (int)simple_strtol(data, NULL, 10); + printf("%s: tx_max_offset = %d\n", __FUNCTION__, conf->tx_max_offset); + } + else if (!strncmp("txglom_mode=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + conf->txglom_mode = FALSE; + else + conf->txglom_mode = TRUE; + printf("%s: txglom_mode = %d\n", __FUNCTION__, conf->txglom_mode); + } +#endif + else + return false; + + return true; +} +#endif + +bool +dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param) +{ + struct dhd_conf *conf = dhd->conf; + char *data = full_param+len_param; + + if (!strncmp("lpc=", full_param, len_param)) { + conf->lpc = (int)simple_strtol(data, NULL, 10); + printf("%s: lpc = %d\n", __FUNCTION__, conf->lpc); + } + else if (!strncmp("deepsleep=", full_param, len_param)) { + if (!strncmp(data, "1", 1)) + conf->deepsleep = TRUE; + else + conf->deepsleep = FALSE; + printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep); + } + else if (!strncmp("PM=", full_param, len_param)) { + conf->pm = (int)simple_strtol(data, NULL, 10); + printf("%s: PM = %d\n", __FUNCTION__, conf->pm); + } + else if (!strncmp("pm_in_suspend=", full_param, len_param)) { + conf->pm_in_suspend = (int)simple_strtol(data, NULL, 10); + printf("%s: pm_in_suspend = %d\n", __FUNCTION__, conf->pm_in_suspend); + } + else if (!strncmp("pm2_sleep_ret=", full_param, len_param)) { + conf->pm2_sleep_ret = (int)simple_strtol(data, NULL, 10); + printf("%s: pm2_sleep_ret = %d\n", __FUNCTION__, conf->pm2_sleep_ret); + } + else if (!strncmp("xmit_in_suspend=", full_param, len_param)) { + if (!strncmp(data, "1", 1)) + conf->xmit_in_suspend = TRUE; + else + conf->xmit_in_suspend = FALSE; + printf("%s: xmit_in_suspend = %d\n", __FUNCTION__, conf->xmit_in_suspend); + } + else if (!strncmp("ap_in_suspend=", full_param, len_param)) { + conf->ap_in_suspend = (int)simple_strtol(data, NULL, 10); + printf("%s: ap_in_suspend = %d\n", __FUNCTION__, conf->ap_in_suspend); + } + else + return false; + + return true; +} + +bool +dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param) +{ + struct dhd_conf *conf = dhd->conf; + char *data = full_param+len_param; + uint len_data = strlen(data); + char *pch, *pick_tmp; + int i; + + if (!strncmp("band=", full_param, len_param)) { + /* Process band: + * band=a for 5GHz only and band=b for 2.4GHz only + */ + if (!strcmp(data, "b")) + conf->band = WLC_BAND_2G; + else if (!strcmp(data, "a")) + conf->band = WLC_BAND_5G; + else + conf->band = WLC_BAND_AUTO; + printf("%s: band = %d\n", __FUNCTION__, conf->band); + } + else if (!strncmp("mimo_bw_cap=", full_param, len_param)) { + conf->mimo_bw_cap = (uint)simple_strtol(data, NULL, 10); + printf("%s: mimo_bw_cap = %d\n", __FUNCTION__, conf->mimo_bw_cap); + } + else if (!strncmp("bw_cap_2g=", full_param, len_param)) { + conf->bw_cap_2g = (uint)simple_strtol(data, NULL, 0); + printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_2g); + } + else if (!strncmp("bw_cap_5g=", full_param, len_param)) { + conf->bw_cap_5g = (uint)simple_strtol(data, NULL, 0); + printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_5g); + } + else if (!strncmp("ccode=", full_param, len_param)) { + memset(&conf->cspec, 0, sizeof(wl_country_t)); + memcpy(conf->cspec.country_abbrev, data, len_data); + memcpy(conf->cspec.ccode, data, len_data); + printf("%s: ccode = %s\n", __FUNCTION__, conf->cspec.ccode); + } + else if (!strncmp("regrev=", full_param, len_param)) { + conf->cspec.rev = (int32)simple_strtol(data, NULL, 10); + printf("%s: regrev = %d\n", __FUNCTION__, conf->cspec.rev); + } + else if (!strncmp("channels=", full_param, len_param)) { + pick_tmp = data; + pch = bcmstrtok(&pick_tmp, " ,.-", 0); + i=0; + while (pch != NULL && ichannels.channel[i] = (uint32)simple_strtol(pch, NULL, 10); + pch = bcmstrtok(&pick_tmp, " ,.-", 0); + i++; + } + conf->channels.count = i; + printf("%s: channels = ", __FUNCTION__); + for (i=0; ichannels.count; i++) + printf("%d ", conf->channels.channel[i]); + printf("\n"); + } + else if (!strncmp("keep_alive_period=", full_param, len_param)) { + conf->keep_alive_period = (uint)simple_strtol(data, NULL, 10); + printf("%s: keep_alive_period = %d\n", __FUNCTION__, + conf->keep_alive_period); + } + else if (!strncmp("stbc=", full_param, len_param)) { + conf->stbc = (int)simple_strtol(data, NULL, 10); + printf("%s: stbc = %d\n", __FUNCTION__, conf->stbc); + } + else if (!strncmp("phy_oclscdenable=", full_param, len_param)) { + conf->phy_oclscdenable = (int)simple_strtol(data, NULL, 10); + printf("%s: phy_oclscdenable = %d\n", __FUNCTION__, conf->phy_oclscdenable); + } + else if (!strncmp("srl=", full_param, len_param)) { + conf->srl = (int)simple_strtol(data, NULL, 10); + printf("%s: srl = %d\n", __FUNCTION__, conf->srl); + } + else if (!strncmp("lrl=", full_param, len_param)) { + conf->lrl = (int)simple_strtol(data, NULL, 10); + printf("%s: lrl = %d\n", __FUNCTION__, conf->lrl); + } + else if (!strncmp("bcn_timeout=", full_param, len_param)) { + conf->bcn_timeout= (uint)simple_strtol(data, NULL, 10); + printf("%s: bcn_timeout = %d\n", __FUNCTION__, conf->bcn_timeout); + } + else if (!strncmp("ampdu_ba_wsize=", full_param, len_param)) { + conf->ampdu_ba_wsize = (int)simple_strtol(data, NULL, 10); + printf("%s: ampdu_ba_wsize = %d\n", __FUNCTION__, conf->ampdu_ba_wsize); + } + else if (!strncmp("ampdu_hostreorder=", full_param, len_param)) { + conf->ampdu_hostreorder = (int)simple_strtol(data, NULL, 10); + printf("%s: ampdu_hostreorder = %d\n", __FUNCTION__, conf->ampdu_hostreorder); + } + else if (!strncmp("spect=", full_param, len_param)) { + conf->spect = (int)simple_strtol(data, NULL, 10); + printf("%s: spect = %d\n", __FUNCTION__, conf->spect); + } + else if (!strncmp("txbf=", full_param, len_param)) { + conf->txbf = (int)simple_strtol(data, NULL, 10); + printf("%s: txbf = %d\n", __FUNCTION__, conf->txbf); + } + else if (!strncmp("frameburst=", full_param, len_param)) { + conf->frameburst = (int)simple_strtol(data, NULL, 10); + printf("%s: frameburst = %d\n", __FUNCTION__, conf->frameburst); + } + else if (!strncmp("disable_proptx=", full_param, len_param)) { + conf->disable_proptx = (int)simple_strtol(data, NULL, 10); + printf("%s: disable_proptx = %d\n", __FUNCTION__, conf->disable_proptx); + } +#ifdef DHDTCPACK_SUPPRESS + else if (!strncmp("tcpack_sup_mode=", full_param, len_param)) { + conf->tcpack_sup_mode = (uint)simple_strtol(data, NULL, 10); + printf("%s: tcpack_sup_mode = %d\n", __FUNCTION__, conf->tcpack_sup_mode); + } +#endif + else if (!strncmp("pktprio8021x=", full_param, len_param)) { + conf->pktprio8021x = (int)simple_strtol(data, NULL, 10); + printf("%s: pktprio8021x = %d\n", __FUNCTION__, conf->pktprio8021x); + } + else if (!strncmp("dhd_txbound=", full_param, len_param)) { + dhd_txbound = (uint)simple_strtol(data, NULL, 10); + printf("%s: dhd_txbound = %d\n", __FUNCTION__, dhd_txbound); + } + else if (!strncmp("dhd_rxbound=", full_param, len_param)) { + dhd_rxbound = (uint)simple_strtol(data, NULL, 10); + printf("%s: dhd_rxbound = %d\n", __FUNCTION__, dhd_rxbound); + } + else if (!strncmp("rsdb_mode=", full_param, len_param)) { + conf->rsdb_mode = (int)simple_strtol(data, NULL, 10); + printf("%s: rsdb_mode = %d\n", __FUNCTION__, conf->rsdb_mode); + } + else if (!strncmp("vhtmode=", full_param, len_param)) { + if (!strncmp(data, "0", 1)) + conf->vhtmode = 0; + else + conf->vhtmode = 1; + printf("%s: vhtmode = %d\n", __FUNCTION__, conf->vhtmode); + } + else if (!strncmp("num_different_channels=", full_param, len_param)) { + conf->num_different_channels = (int)simple_strtol(data, NULL, 10); + printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels); + } + else if (!strncmp("autocountry=", full_param, len_param)) { + conf->autocountry = (int)simple_strtol(data, NULL, 10); + printf("%s: autocountry = %d\n", __FUNCTION__, conf->autocountry); + } + else if (!strncmp("tsq=", full_param, len_param)) { + conf->tsq = (int)simple_strtol(data, NULL, 10); + printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq); + } + else + return false; + + return true; +} + +int +dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path) +{ + int bcmerror = -1; + uint len, start_pos=0; + void * image = NULL; + char * memblock = NULL; + char *bufp, *pick = NULL, *pch; + bool conf_file_exists; + uint len_param; + + conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0')); + if (!conf_file_exists) { + printf("%s: config path %s\n", __FUNCTION__, conf_path); + return (0); + } + + if (conf_file_exists) { + image = dhd_os_open_image(conf_path); + if (image == NULL) { + printf("%s: Ignore config file %s\n", __FUNCTION__, conf_path); + goto err; + } + } + + memblock = MALLOC(dhd->osh, MAXSZ_CONFIG); + if (memblock == NULL) { + CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n", + __FUNCTION__, MAXSZ_CONFIG)); + goto err; + } + + pick = MALLOC(dhd->osh, MAXSZ_BUF); + if (!pick) { + CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n", + __FUNCTION__, MAXSZ_BUF)); + goto err; + } + + /* Read variables */ + if (conf_file_exists) { + len = dhd_os_get_image_block(memblock, MAXSZ_CONFIG, image); + } + if (len > 0 && len < MAXSZ_CONFIG) { + bufp = (char *)memblock; + bufp[len] = 0; + + while (start_pos < len) { + memset(pick, 0, MAXSZ_BUF); + start_pos = pick_config_vars(bufp, len, start_pos, pick); + pch = strchr(pick, '='); + if (pch != NULL) { + len_param = pch-pick+1; + if (len_param == strlen(pick)) { + CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick)); + continue; + } + } else { + CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick)); + continue; + } + + if (dhd_conf_read_log_level(dhd, pick, len_param)) + continue; + else if (dhd_conf_read_roam_params(dhd, pick, len_param)) + continue; + else if (dhd_conf_read_wme_ac_params(dhd, pick, len_param)) + continue; + else if (dhd_conf_read_fw_by_mac(dhd, pick, len_param)) + continue; + else if (dhd_conf_read_nv_by_mac(dhd, pick, len_param)) + continue; + else if (dhd_conf_read_nv_by_chip(dhd, pick, len_param)) + continue; + else if (dhd_conf_read_country_list(dhd, pick, len_param)) + continue; +#ifdef PKT_FILTER_SUPPORT + else if (dhd_conf_read_pkt_filter(dhd, pick, len_param)) + continue; +#endif /* PKT_FILTER_SUPPORT */ +#ifdef IAPSTA_PREINIT + else if (dhd_conf_read_iapsta(dhd, pick, len_param)) + continue; +#endif /* IAPSTA_PREINIT */ +#ifdef IDHCP + else if (dhd_conf_read_dhcp_params(dhd, pick, len_param)) + continue; +#endif /* IDHCP */ +#ifdef BCMSDIO + else if (dhd_conf_read_sdio_params(dhd, pick, len_param)) + continue; +#endif /* BCMSDIO */ + else if (dhd_conf_read_pm_params(dhd, pick, len_param)) + continue; + else if (dhd_conf_read_others(dhd, pick, len_param)) + continue; else - continue; - } - - bcmerror = 0; - } else { - CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len)); - bcmerror = BCME_SDIO_ERROR; - } - -err: - if (pick) - MFREE(dhd->osh, pick, MAXSZ_BUF); - - if (memblock) - MFREE(dhd->osh, memblock, MAXSZ_CONFIG); - - if (image) - dhd_os_close_image(image); - - return bcmerror; -} - -int -dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev) -{ - printf("%s: chip=0x%x, chiprev=%d\n", __FUNCTION__, chip, chiprev); - dhd->conf->chip = chip; - dhd->conf->chiprev = chiprev; - return 0; -} - -uint -dhd_conf_get_chip(void *context) -{ - dhd_pub_t *dhd = context; - - if (dhd && dhd->conf) - return dhd->conf->chip; - return 0; -} - -uint -dhd_conf_get_chiprev(void *context) -{ - dhd_pub_t *dhd = context; - - if (dhd && dhd->conf) - return dhd->conf->chiprev; - return 0; -} - -#ifdef BCMSDIO -void -dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable) -{ - struct dhd_conf *conf = dhd->conf; - - if (enable) { -#if defined(SWTXGLOM) - if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || - conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || - conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { - // 43362/4330/4334/43340/43341/43241 must use 1.88.45.x swtxglom if txglom_ext is true, since 1.201.59 not support swtxglom - conf->swtxglom = TRUE; - conf->txglom_ext = TRUE; - } - if (conf->chip == BCM43362_CHIP_ID && conf->bus_txglom == 0) { - conf->bus_txglom = 1; // improve tcp tx tput. and cpu idle for 43362 only - } -#elif defined(BCMSDIOH_TXGLOM_EXT) - if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || - conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || - conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { - conf->txglom_mode = SDPCM_TXGLOM_CPY; - } -#endif - // other parameters set in preinit or config.txt - } else { - // clear txglom parameters, but don't change swtxglom since it's possible enabled in config.txt - conf->txglom_ext = FALSE; - conf->txglom_bucket_size = 0; - conf->txglomsize = 0; - conf->deferred_tx_len = 0; - } - printf("%s: swtxglom=%d, txglom_ext=%d, txglom_bucket_size=%d\n", __FUNCTION__, - conf->swtxglom, conf->txglom_ext, conf->txglom_bucket_size); - printf("%s: txglomsize=%d, deferred_tx_len=%d, bus_txglom=%d\n", __FUNCTION__, - conf->txglomsize, conf->deferred_tx_len, conf->bus_txglom); - printf("%s: tx_in_rx=%d, txinrx_thres=%d, dhd_txminmax=%d\n", __FUNCTION__, - conf->tx_in_rx, conf->txinrx_thres, conf->dhd_txminmax); - printf("%s: tx_max_offset=%d, txctl_tmo_fix=%d\n", __FUNCTION__, - conf->tx_max_offset, conf->txctl_tmo_fix); - -} -#endif - -int -dhd_conf_preinit(dhd_pub_t *dhd) -{ - struct dhd_conf *conf = dhd->conf; - - CONFIG_TRACE(("%s: Enter\n", __FUNCTION__)); - -#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 - memset(&conf->country_list, 0, sizeof(conf_country_list_t)); - conf->band = WLC_BAND_AUTO; - conf->mimo_bw_cap = -1; - conf->bw_cap_2g = -1; - conf->bw_cap_5g = -1; - if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) { - strcpy(conf->cspec.country_abbrev, "ALL"); - strcpy(conf->cspec.ccode, "ALL"); - conf->cspec.rev = 0; - } else if (conf->chip == BCM4335_CHIP_ID || conf->chip == BCM4339_CHIP_ID || - conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID || - conf->chip == BCM4345_CHIP_ID || conf->chip == BCM4371_CHIP_ID || - conf->chip == BCM43569_CHIP_ID || conf->chip == BCM4359_CHIP_ID) { - strcpy(conf->cspec.country_abbrev, "CN"); - strcpy(conf->cspec.ccode, "CN"); - conf->cspec.rev = 38; - } else { - strcpy(conf->cspec.country_abbrev, "CN"); - strcpy(conf->cspec.ccode, "CN"); - conf->cspec.rev = 0; - } - memset(&conf->channels, 0, sizeof(wl_channel_list_t)); - conf->roam_off = 1; - conf->roam_off_suspend = 1; -#ifdef CUSTOM_ROAM_TRIGGER_SETTING - conf->roam_trigger[0] = CUSTOM_ROAM_TRIGGER_SETTING; -#else - conf->roam_trigger[0] = -65; -#endif - conf->roam_trigger[1] = WLC_BAND_ALL; - conf->roam_scan_period[0] = 10; - conf->roam_scan_period[1] = WLC_BAND_ALL; -#ifdef CUSTOM_ROAM_DELTA_SETTING - conf->roam_delta[0] = CUSTOM_ROAM_DELTA_SETTING; -#else - conf->roam_delta[0] = 15; -#endif - conf->roam_delta[1] = WLC_BAND_ALL; + continue; + } + + bcmerror = 0; + } else { + CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len)); + bcmerror = BCME_SDIO_ERROR; + } + +err: + if (pick) + MFREE(dhd->osh, pick, MAXSZ_BUF); + + if (memblock) + MFREE(dhd->osh, memblock, MAXSZ_CONFIG); + + if (image) + dhd_os_close_image(image); + + return bcmerror; +} + +int +dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev) +{ + printf("%s: chip=0x%x, chiprev=%d\n", __FUNCTION__, chip, chiprev); + dhd->conf->chip = chip; + dhd->conf->chiprev = chiprev; + return 0; +} + +uint +dhd_conf_get_chip(void *context) +{ + dhd_pub_t *dhd = context; + + if (dhd && dhd->conf) + return dhd->conf->chip; + return 0; +} + +uint +dhd_conf_get_chiprev(void *context) +{ + dhd_pub_t *dhd = context; + + if (dhd && dhd->conf) + return dhd->conf->chiprev; + return 0; +} + +#ifdef BCMSDIO +void +dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable) +{ + struct dhd_conf *conf = dhd->conf; + + if (enable) { +#if defined(SWTXGLOM) + if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || + conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || + conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { + // 43362/4330/4334/43340/43341/43241 must use 1.88.45.x swtxglom if txglom_ext is true, since 1.201.59 not support swtxglom + conf->swtxglom = TRUE; + conf->txglom_ext = TRUE; + } + if (conf->chip == BCM43362_CHIP_ID && conf->bus_txglom == 0) { + conf->bus_txglom = 1; // improve tcp tx tput. and cpu idle for 43362 only + } +#elif defined(BCMSDIOH_TXGLOM_EXT) + if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || + conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || + conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { + conf->txglom_mode = SDPCM_TXGLOM_CPY; + } +#endif + // other parameters set in preinit or config.txt + } else { + // clear txglom parameters, but don't change swtxglom since it's possible enabled in config.txt + conf->txglom_ext = FALSE; + conf->txglom_bucket_size = 0; + conf->txglomsize = 0; + conf->deferred_tx_len = 0; + } + printf("%s: swtxglom=%d, txglom_ext=%d, txglom_bucket_size=%d\n", __FUNCTION__, + conf->swtxglom, conf->txglom_ext, conf->txglom_bucket_size); + printf("%s: txglomsize=%d, deferred_tx_len=%d, bus_txglom=%d\n", __FUNCTION__, + conf->txglomsize, conf->deferred_tx_len, conf->bus_txglom); + printf("%s: tx_in_rx=%d, txinrx_thres=%d, dhd_txminmax=%d\n", __FUNCTION__, + conf->tx_in_rx, conf->txinrx_thres, conf->dhd_txminmax); + printf("%s: tx_max_offset=%d, txctl_tmo_fix=%d\n", __FUNCTION__, + conf->tx_max_offset, conf->txctl_tmo_fix); + +} +#endif + +int +dhd_conf_preinit(dhd_pub_t *dhd) +{ + struct dhd_conf *conf = dhd->conf; + + CONFIG_TRACE(("%s: Enter\n", __FUNCTION__)); + +#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 + memset(&conf->country_list, 0, sizeof(conf_country_list_t)); + conf->band = WLC_BAND_AUTO; + conf->mimo_bw_cap = -1; + conf->bw_cap_2g = -1; + conf->bw_cap_5g = -1; + if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) { + strcpy(conf->cspec.country_abbrev, "ALL"); + strcpy(conf->cspec.ccode, "ALL"); + conf->cspec.rev = 0; + } else if (conf->chip == BCM4335_CHIP_ID || conf->chip == BCM4339_CHIP_ID || + conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID || + conf->chip == BCM4345_CHIP_ID || conf->chip == BCM4371_CHIP_ID || + conf->chip == BCM43569_CHIP_ID || conf->chip == BCM4359_CHIP_ID) { + strcpy(conf->cspec.country_abbrev, "CN"); + strcpy(conf->cspec.ccode, "CN"); + conf->cspec.rev = 38; + } else { + strcpy(conf->cspec.country_abbrev, "CN"); + strcpy(conf->cspec.ccode, "CN"); + conf->cspec.rev = 0; + } + memset(&conf->channels, 0, sizeof(wl_channel_list_t)); + conf->roam_off = 1; + conf->roam_off_suspend = 1; +#ifdef CUSTOM_ROAM_TRIGGER_SETTING + conf->roam_trigger[0] = CUSTOM_ROAM_TRIGGER_SETTING; +#else + conf->roam_trigger[0] = -65; +#endif + conf->roam_trigger[1] = WLC_BAND_ALL; + conf->roam_scan_period[0] = 10; + conf->roam_scan_period[1] = WLC_BAND_ALL; +#ifdef CUSTOM_ROAM_DELTA_SETTING + conf->roam_delta[0] = CUSTOM_ROAM_DELTA_SETTING; +#else + conf->roam_delta[0] = 15; +#endif + conf->roam_delta[1] = WLC_BAND_ALL; #ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC - conf->fullroamperiod = 60; + conf->fullroamperiod = 60; #else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ - conf->fullroamperiod = 120; -#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ -#ifdef CUSTOM_KEEP_ALIVE_SETTING - conf->keep_alive_period = CUSTOM_KEEP_ALIVE_SETTING; -#else - conf->keep_alive_period = 28000; -#endif - conf->force_wme_ac = 0; - memset(&conf->wme_sta, 0, sizeof(wme_param_t)); - memset(&conf->wme_ap, 0, sizeof(wme_param_t)); - conf->stbc = -1; - conf->phy_oclscdenable = -1; -#ifdef PKT_FILTER_SUPPORT - memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t)); - memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t)); - memset(&conf->magic_pkt_filter_add, 0, sizeof(conf_pkt_filter_del_t)); -#endif - conf->srl = -1; - conf->lrl = -1; - conf->bcn_timeout = 15; - conf->spect = -1; - conf->txbf = -1; - conf->lpc = -1; - conf->disable_proptx = -1; -#ifdef BCMSDIO - conf->bus_txglom = -1; - conf->use_rxchain = 0; - conf->bus_rxglom = TRUE; - conf->txglom_ext = FALSE; - conf->tx_max_offset = 0; - conf->txglomsize = SDPCM_DEFGLOM_SIZE; - conf->dhd_poll = -1; - conf->txctl_tmo_fix = FALSE; - conf->tx_in_rx = TRUE; - conf->txglom_mode = SDPCM_TXGLOM_MDESC; - conf->deferred_tx_len = 0; - conf->dhd_txminmax = 1; - conf->txinrx_thres = -1; - conf->sd_f2_blocksize = 0; - conf->oob_enabled_later = FALSE; -#endif - conf->ampdu_ba_wsize = 0; - conf->ampdu_hostreorder = -1; - conf->dpc_cpucore = -1; - conf->rxf_cpucore = -1; - conf->frameburst = -1; - conf->deepsleep = FALSE; - conf->pm = -1; - conf->pm_in_suspend = -1; - conf->pm2_sleep_ret = -1; - conf->num_different_channels = -1; - conf->xmit_in_suspend = TRUE; -#ifdef IDHCPC - conf->dhcpc_enable = -1; -#endif - conf->tsq = 0; + conf->fullroamperiod = 120; +#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ +#ifdef CUSTOM_KEEP_ALIVE_SETTING + conf->keep_alive_period = CUSTOM_KEEP_ALIVE_SETTING; +#else + conf->keep_alive_period = 28000; +#endif + conf->force_wme_ac = 0; + memset(&conf->wme_sta, 0, sizeof(wme_param_t)); + memset(&conf->wme_ap, 0, sizeof(wme_param_t)); + conf->stbc = -1; + conf->phy_oclscdenable = -1; +#ifdef PKT_FILTER_SUPPORT + memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t)); + memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t)); + memset(&conf->magic_pkt_filter_add, 0, sizeof(conf_pkt_filter_del_t)); +#endif + conf->srl = -1; + conf->lrl = -1; + conf->bcn_timeout = 15; + conf->spect = -1; + conf->txbf = -1; + conf->lpc = -1; + conf->disable_proptx = -1; +#ifdef BCMSDIO + conf->bus_txglom = -1; + conf->use_rxchain = 0; + conf->bus_rxglom = TRUE; + conf->txglom_ext = FALSE; + conf->tx_max_offset = 0; + conf->txglomsize = SDPCM_DEFGLOM_SIZE; + conf->dhd_poll = -1; + conf->txctl_tmo_fix = FALSE; + conf->tx_in_rx = TRUE; + conf->txglom_mode = SDPCM_TXGLOM_MDESC; + conf->deferred_tx_len = 0; + conf->dhd_txminmax = 1; + conf->txinrx_thres = -1; + conf->sd_f2_blocksize = 0; + conf->oob_enabled_later = FALSE; +#endif + conf->ampdu_ba_wsize = 0; + conf->ampdu_hostreorder = -1; + conf->dpc_cpucore = -1; + conf->rxf_cpucore = -1; + conf->frameburst = -1; + conf->deepsleep = FALSE; + conf->pm = -1; + conf->pm_in_suspend = -1; + conf->pm2_sleep_ret = -1; + conf->num_different_channels = -1; + conf->xmit_in_suspend = TRUE; + conf->ap_in_suspend = 0; +#ifdef IDHCP + conf->dhcpc_enable = -1; + conf->dhcpd_enable = -1; +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)) + conf->tsq = 10; +#else + conf->tsq = 0; +#endif +#ifdef DHDTCPACK_SUPPRESS + conf->tcpack_sup_mode = TCPACK_SUP_OFF; +#endif + conf->pktprio8021x = -1; + conf->rsdb_mode = -2; + conf->vhtmode = -1; + conf->autocountry = -1; +#ifdef IAPSTA_PREINIT + memset(conf->iapsta_init, 0, sizeof(conf->iapsta_init)); + memset(conf->iapsta_config, 0, sizeof(conf->iapsta_config)); + memset(conf->iapsta_enable, 0, sizeof(conf->iapsta_enable)); +#endif +#ifdef CUSTOMER_HW_AMLOGIC + dhd_slpauto = FALSE; +#endif +#ifdef BCMSDIO + if (conf->chip == BCM43430_CHIP_ID || conf->chip == BCM43454_CHIP_ID || + conf->chip == BCM4345_CHIP_ID) { + conf->txctl_tmo_fix = 1; + } +#endif + if (conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID || + conf->chip == BCM4371_CHIP_ID || conf->chip == BCM43569_CHIP_ID || + conf->chip == BCM4359_CHIP_ID) { #ifdef DHDTCPACK_SUPPRESS - conf->tcpack_sup_mode = TCPACK_SUP_OFF; -#endif - conf->pktprio8021x = -1; - conf->rsdb_mode = -2; - conf->vhtmode = -1; - conf->autocountry = -1; -#ifdef IAPSTA_PREINIT - memset(conf->iapsta_init, 0, sizeof(conf->iapsta_init)); - memset(conf->iapsta_config, 0, sizeof(conf->iapsta_config)); - memset(conf->iapsta_enable, 0, sizeof(conf->iapsta_enable)); -#endif -#ifdef BCMSDIO - if (conf->chip == BCM43430_CHIP_ID || conf->chip == BCM4345_CHIP_ID) { - conf->txctl_tmo_fix = 1; - } -#endif - if (conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID || - conf->chip == BCM4371_CHIP_ID || conf->chip == BCM43569_CHIP_ID || - conf->chip == BCM4359_CHIP_ID) { -#ifdef DHDTCPACK_SUPPRESS - conf->tcpack_sup_mode = TCPACK_SUP_REPLACE; -#endif - dhd_rxbound = 64; - dhd_txbound = 64; - conf->txbf = 1; - conf->frameburst = 1; -#ifdef BCMSDIO - conf->dhd_txminmax = -1; - conf->txinrx_thres = 128; - conf->sd_f2_blocksize = 256; - conf->oob_enabled_later = TRUE; -#endif - } - -#ifdef BCMSDIO -#if defined(SWTXGLOM) - if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || - conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || - conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { - conf->swtxglom = FALSE; // disabled by default - conf->txglom_ext = TRUE; // enabled by default - conf->use_rxchain = 0; // use_rxchain have been disabled if swtxglom enabled - conf->txglomsize = 16; - } else { - conf->swtxglom = FALSE; // use 1.201.59.x txglom by default - conf->txglom_ext = FALSE; - } - - if (conf->chip == BCM43362_CHIP_ID) { - conf->txglom_bucket_size = 1680; // fixed value, don't change - conf->tx_in_rx = FALSE; - conf->tx_max_offset = 1; - } - if (conf->chip == BCM4330_CHIP_ID) { - conf->txglom_bucket_size = 1680; // fixed value, don't change - conf->tx_in_rx = FALSE; - conf->tx_max_offset = 0; - } - if (conf->chip == BCM4334_CHIP_ID) { - conf->txglom_bucket_size = 1684; // fixed value, don't change - conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle - conf->tx_max_offset = 0; // reduce udp tx: dhdsdio_readframes: got unlikely tx max 109 with tx_seq 110 - } - if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID) { - conf->txglom_bucket_size = 1684; // fixed value, don't change - conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle - conf->tx_max_offset = 1; - } - if (conf->chip == BCM4324_CHIP_ID) { - conf->txglom_bucket_size = 1684; // fixed value, don't change - conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle - conf->tx_max_offset = 0; - } -#endif -#if defined(BCMSDIOH_TXGLOM_EXT) - if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || - conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || - conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { - conf->txglom_ext = TRUE; - conf->use_rxchain = 0; - conf->tx_in_rx = TRUE; - conf->tx_max_offset = 1; - } else { - conf->txglom_ext = FALSE; - } - if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) { - conf->txglom_bucket_size = 1680; // fixed value, don't change - conf->txglomsize = 6; - } - if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID || - conf->chip == BCM43341_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { - conf->txglom_bucket_size = 1684; // fixed value, don't change - conf->txglomsize = 16; - } -#endif - if (conf->txglomsize > SDPCM_MAXGLOM_SIZE) - conf->txglomsize = SDPCM_MAXGLOM_SIZE; - conf->deferred_tx_len = 0; -#endif - - return 0; -} - -int -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; -} - -int -dhd_conf_attach(dhd_pub_t *dhd) -{ - dhd_conf_t *conf; - - CONFIG_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (dhd->conf != NULL) { - printf("%s: config is attached before!\n", __FUNCTION__); - return 0; - } - /* Allocate private bus interface state */ - if (!(conf = MALLOC(dhd->osh, sizeof(dhd_conf_t)))) { - CONFIG_ERROR(("%s: MALLOC failed\n", __FUNCTION__)); - goto fail; - } - memset(conf, 0, sizeof(dhd_conf_t)); - - dhd->conf = conf; - - return 0; - -fail: - if (conf != NULL) - MFREE(dhd->osh, conf, sizeof(dhd_conf_t)); - return BCME_NOMEM; -} - -void -dhd_conf_detach(dhd_pub_t *dhd) -{ - CONFIG_TRACE(("%s: Enter\n", __FUNCTION__)); - - if (dhd->conf) { -#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)); - } - dhd->conf = NULL; -} + conf->tcpack_sup_mode = TCPACK_SUP_REPLACE; +#endif + dhd_rxbound = 128; + dhd_txbound = 64; + conf->txbf = 1; + conf->frameburst = 1; +#ifdef BCMSDIO + conf->dhd_txminmax = -1; + conf->txinrx_thres = 128; + conf->sd_f2_blocksize = CUSTOM_SDIO_F2_BLKSIZE; + conf->oob_enabled_later = TRUE; +#ifdef CUSTOMER_HW_AMLOGIC + conf->rxf_cpucore = 2; +#endif +#endif + } + +#ifdef BCMSDIO +#if defined(SWTXGLOM) + if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || + conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || + conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { + conf->swtxglom = FALSE; // disabled by default + conf->txglom_ext = TRUE; // enabled by default + conf->use_rxchain = 0; // use_rxchain have been disabled if swtxglom enabled + conf->txglomsize = 16; + } else { + conf->swtxglom = FALSE; // use 1.201.59.x txglom by default + conf->txglom_ext = FALSE; + } + + if (conf->chip == BCM43362_CHIP_ID) { + conf->txglom_bucket_size = 1680; // fixed value, don't change + conf->tx_in_rx = FALSE; + conf->tx_max_offset = 1; + } + if (conf->chip == BCM4330_CHIP_ID) { + conf->txglom_bucket_size = 1680; // fixed value, don't change + conf->tx_in_rx = FALSE; + conf->tx_max_offset = 0; + } + if (conf->chip == BCM4334_CHIP_ID) { + conf->txglom_bucket_size = 1684; // fixed value, don't change + conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle + conf->tx_max_offset = 0; // reduce udp tx: dhdsdio_readframes: got unlikely tx max 109 with tx_seq 110 + } + if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID) { + conf->txglom_bucket_size = 1684; // fixed value, don't change + conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle + conf->tx_max_offset = 1; + } + if (conf->chip == BCM4324_CHIP_ID) { + conf->txglom_bucket_size = 1684; // fixed value, don't change + conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle + conf->tx_max_offset = 0; + } +#endif +#if defined(BCMSDIOH_TXGLOM_EXT) + if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || + conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || + conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { + conf->txglom_ext = TRUE; + conf->use_rxchain = 0; + conf->tx_in_rx = TRUE; + conf->tx_max_offset = 1; + } else { + conf->txglom_ext = FALSE; + } + if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) { + conf->txglom_bucket_size = 1680; // fixed value, don't change + conf->txglomsize = 6; + } + if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID || + conf->chip == BCM43341_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { + conf->txglom_bucket_size = 1684; // fixed value, don't change + conf->txglomsize = 16; + } +#endif + if (conf->txglomsize > SDPCM_MAXGLOM_SIZE) + conf->txglomsize = SDPCM_MAXGLOM_SIZE; + conf->deferred_tx_len = 0; +#endif + + return 0; +} + +int +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; +} + +int +dhd_conf_attach(dhd_pub_t *dhd) +{ + dhd_conf_t *conf; + + CONFIG_TRACE(("%s: Enter\n", __FUNCTION__)); + + if (dhd->conf != NULL) { + printf("%s: config is attached before!\n", __FUNCTION__); + return 0; + } + /* Allocate private bus interface state */ + if (!(conf = MALLOC(dhd->osh, sizeof(dhd_conf_t)))) { + CONFIG_ERROR(("%s: MALLOC failed\n", __FUNCTION__)); + goto fail; + } + memset(conf, 0, sizeof(dhd_conf_t)); + + dhd->conf = conf; + + return 0; + +fail: + if (conf != NULL) + MFREE(dhd->osh, conf, sizeof(dhd_conf_t)); + return BCME_NOMEM; +} + +void +dhd_conf_detach(dhd_pub_t *dhd) +{ + CONFIG_TRACE(("%s: Enter\n", __FUNCTION__)); + + if (dhd->conf) { +#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)); + } + dhd->conf = NULL; +} diff --git a/bcmdhd.1.363.59.144.x.cn/dhd_config.c.rej b/bcmdhd.1.363.59.144.x.cn/dhd_config.c.rej deleted file mode 100644 index c5d7f90..0000000 --- a/bcmdhd.1.363.59.144.x.cn/dhd_config.c.rej +++ /dev/null @@ -1,5140 +0,0 @@ ---- bcmdhd.1.363.59.144.x.cn/dhd_config.c -+++ bcmdhd.1.363.59.144.x.cn/dhd_config.c -@@ -1,2581 +1,2581 @@ -- --#include --#include -- --#include --#include --#include -+ -+#include -+#include -+ -+#include -+#include -+#include - #if defined(HW_OOB) || defined(FORCE_WOWLAN) --#include --#include --#include --#include --#endif -- --#include --#include -- -+#include -+#include -+#include -+#include -+#endif -+ -+#include -+#include -+ - /* message levels */ --#define CONFIG_ERROR_LEVEL 0x0001 --#define CONFIG_TRACE_LEVEL 0x0002 -+#define CONFIG_ERROR_LEVEL 0x0001 -+#define CONFIG_TRACE_LEVEL 0x0002 - --uint config_msg_level = CONFIG_ERROR_LEVEL; -+uint config_msg_level = CONFIG_ERROR_LEVEL; - --#define CONFIG_ERROR(x) \ -+#define CONFIG_ERROR(x) \ - do { \ -- if (config_msg_level & CONFIG_ERROR_LEVEL) { \ -- printk(KERN_ERR "CONFIG-ERROR) "); \ -+ if (config_msg_level & CONFIG_ERROR_LEVEL) { \ -+ printk(KERN_ERR "CONFIG-ERROR) "); \ - printk x; \ - } \ - } while (0) --#define CONFIG_TRACE(x) \ -+#define CONFIG_TRACE(x) \ - do { \ -- if (config_msg_level & CONFIG_TRACE_LEVEL) { \ -- printk(KERN_ERR "CONFIG-TRACE) "); \ -+ if (config_msg_level & CONFIG_TRACE_LEVEL) { \ -+ printk(KERN_ERR "CONFIG-TRACE) "); \ - printk x; \ - } \ -- } while (0) -- --#define MAXSZ_BUF 1000 --#define MAXSZ_CONFIG 4096 -- --#define FW_TYPE_STA 0 --#define FW_TYPE_APSTA 1 --#define FW_TYPE_P2P 2 --#define FW_TYPE_ES 3 --#define FW_TYPE_MFG 4 --#define FW_TYPE_G 0 --#define FW_TYPE_AG 1 -- --#ifdef CONFIG_PATH_AUTO_SELECT --#ifdef BCMSDIO --#define CONFIG_BCM4330B2 "config_40183b2.txt" --#define CONFIG_BCM43362A0 "config_40181a0.txt" --#define CONFIG_BCM43362A2 "config_40181a2.txt" --#define CONFIG_BCM43438A0 "config_43438a0.txt" --#define CONFIG_BCM43438A1 "config_43438a1.txt" --#define CONFIG_BCM43436B0 "config_43436b0.txt" --#define CONFIG_BCM4334B1 "config_4334b1.txt" --#define CONFIG_BCM43341B0 "config_43341b0.txt" --#define CONFIG_BCM43241B4 "config_43241b4.txt" --#define CONFIG_BCM4339A0 "config_4339a0.txt" --#define CONFIG_BCM43455C0 "config_43455c0.txt" --#define CONFIG_BCM43456C5 "config_43456c5.txt" --#define CONFIG_BCM4354A1 "config_4354a1.txt" --#endif --#define CONFIG_BCM4356A2 "config_4356a2.txt" --#define CONFIG_BCM4358A3 "config_4358a3.txt" --#define CONFIG_BCM4359B1 "config_4359b1.txt" --#define CONFIG_BCM4359C0 "config_4359c0.txt" --#endif -- --#ifdef BCMSDIO --#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */ -- --#define FW_BCM4330B2 "fw_bcm40183b2" --#define FW_BCM4330B2_AG "fw_bcm40183b2_ag" --#define FW_BCM43362A0 "fw_bcm40181a0" --#define FW_BCM43362A2 "fw_bcm40181a2" --#define FW_BCM4334B1 "fw_bcm4334b1_ag" --#define FW_BCM43438A0 "fw_bcm43438a0" --#define FW_BCM43438A1 "fw_bcm43438a1" --#define FW_BCM43436B0 "fw_bcm43436b0" --#define FW_BCM43012B0 "fw_bcm43012b0" --#define FW_BCM43341B1 "fw_bcm43341b0_ag" --#define FW_BCM43241B4 "fw_bcm43241b4_ag" --#define FW_BCM4339A0 "fw_bcm4339a0_ag" --#define FW_BCM43455C0 "fw_bcm43455c0_ag" --#define FW_BCM43456C5 "fw_bcm43456c5_ag" --#define FW_BCM4354A1 "fw_bcm4354a1_ag" --#define FW_BCM4356A2 "fw_bcm4356a2_ag" --#define FW_BCM4358A3 "fw_bcm4358a3_ag" --#define FW_BCM4359B1 "fw_bcm4359b1_ag" --#define FW_BCM4359C0 "fw_bcm4359c0_ag" -- --#define CLM_BCM43012B0 "clm_bcm43012b0" --#endif --#ifdef BCMPCIE --#define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag" --#endif -- -+ } while (0) -+ -+#define MAXSZ_BUF 1000 -+#define MAXSZ_CONFIG 4096 -+ -+#define FW_TYPE_STA 0 -+#define FW_TYPE_APSTA 1 -+#define FW_TYPE_P2P 2 -+#define FW_TYPE_ES 3 -+#define FW_TYPE_MFG 4 -+#define FW_TYPE_G 0 -+#define FW_TYPE_AG 1 -+ -+#ifdef CONFIG_PATH_AUTO_SELECT -+#ifdef BCMSDIO -+#define CONFIG_BCM4330B2 "config_40183b2.txt" -+#define CONFIG_BCM43362A0 "config_40181a0.txt" -+#define CONFIG_BCM43362A2 "config_40181a2.txt" -+#define CONFIG_BCM43438A0 "config_43438a0.txt" -+#define CONFIG_BCM43438A1 "config_43438a1.txt" -+#define CONFIG_BCM43436B0 "config_43436b0.txt" -+#define CONFIG_BCM4334B1 "config_4334b1.txt" -+#define CONFIG_BCM43341B0 "config_43341b0.txt" -+#define CONFIG_BCM43241B4 "config_43241b4.txt" -+#define CONFIG_BCM4339A0 "config_4339a0.txt" -+#define CONFIG_BCM43455C0 "config_43455c0.txt" -+#define CONFIG_BCM43456C5 "config_43456c5.txt" -+#define CONFIG_BCM4354A1 "config_4354a1.txt" -+#endif -+#define CONFIG_BCM4356A2 "config_4356a2.txt" -+#define CONFIG_BCM4358A3 "config_4358.txt" -+#define CONFIG_BCM4359B1 "config_4359b1.txt" -+#define CONFIG_BCM4359C0 "config_4359c0.txt" -+#endif -+ -+#ifdef BCMSDIO -+#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */ -+ -+#define FW_BCM4330B2 "fw_bcm40183b2" -+#define FW_BCM4330B2_AG "fw_bcm40183b2_ag" -+#define FW_BCM43362A0 "fw_bcm40181a0" -+#define FW_BCM43362A2 "fw_bcm40181a2" -+#define FW_BCM4334B1 "fw_bcm4334b1_ag" -+#define FW_BCM43438A0 "fw_bcm43438a0" -+#define FW_BCM43438A1 "fw_bcm43438a1" -+#define FW_BCM43436B0 "fw_bcm43436b0" -+#define FW_BCM43012B0 "fw_bcm43012b0" -+#define FW_BCM43341B1 "fw_bcm43341b0_ag" -+#define FW_BCM43241B4 "fw_bcm43241b4_ag" -+#define FW_BCM4339A0 "fw_bcm4339a0_ag" -+#define FW_BCM43455C0 "fw_bcm43455c0_ag" -+#define FW_BCM43456C5 "fw_bcm43456c5_ag" -+#define FW_BCM4354A1 "fw_bcm4354a1_ag" -+#define FW_BCM4356A2 "fw_bcm4356a2_ag" -+#define FW_BCM4358A3 "fw_bcm4358_ag" -+#define FW_BCM4359B1 "fw_bcm4359b1_ag" -+#define FW_BCM4359C0 "fw_bcm4359c0_ag" -+ -+#define CLM_BCM43012B0 "clm_bcm43012b0" -+#endif -+#ifdef BCMPCIE -+#define FW_BCM4356A2 "fw_bcm4356a2_pcie_ag" -+#endif -+ - #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 --void --dhd_conf_free_mac_list(wl_mac_list_ctrl_t *mac_list) --{ -- int i; -- -- CONFIG_TRACE(("%s called\n", __FUNCTION__)); -- if (mac_list->m_mac_list_head) { -- for (i=0; icount; i++) { -- if (mac_list->m_mac_list_head[i].mac) { -- CONFIG_TRACE(("%s Free mac %p\n", __FUNCTION__, mac_list->m_mac_list_head[i].mac)); -- kfree(mac_list->m_mac_list_head[i].mac); -- } -- } -- CONFIG_TRACE(("%s Free m_mac_list_head %p\n", __FUNCTION__, mac_list->m_mac_list_head)); -- kfree(mac_list->m_mac_list_head); -- } -- 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) || defined(FORCE_WOWLAN) --void --dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip) --{ -- uint32 gpiocontrol, addr; -- -- if (CHIPID(chip) == BCM43362_CHIP_ID) { -- printf("%s: Enable HW OOB for 43362\n", __FUNCTION__); -- addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol); -- gpiocontrol = bcmsdh_reg_read(sdh, addr, 4); -- gpiocontrol |= 0x2; -- bcmsdh_reg_write(sdh, addr, 4, gpiocontrol); -- bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL); -- bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL); -- bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL); -- } --} --#endif -- --int --dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac) --{ -- int i, err = -1; -- uint8 *ptr = 0; -- unsigned char tpl_code, tpl_link='\0'; -- uint8 header[3] = {0x80, 0x07, 0x19}; -- uint8 *cis; -- -- if (!(cis = MALLOC(dhd->osh, SBSDIO_CIS_SIZE_LIMIT))) { -- CONFIG_ERROR(("%s: cis malloc failed\n", __FUNCTION__)); -- return err; -- } -- bzero(cis, SBSDIO_CIS_SIZE_LIMIT); -- -- if ((err = bcmsdh_cis_read(sdh, 0, cis, SBSDIO_CIS_SIZE_LIMIT))) { -- CONFIG_ERROR(("%s: cis read err %d\n", __FUNCTION__, err)); -- MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT); -- return err; -- } -- err = -1; // reset err; -- ptr = cis; -- do { -- /* 0xff means we're done */ -- tpl_code = *ptr; -- ptr++; -- if (tpl_code == 0xff) -- break; -- -- /* null entries have no link field or data */ -- if (tpl_code == 0x00) -- continue; -- -- tpl_link = *ptr; -- ptr++; -- /* a size of 0xff also means we're done */ -- if (tpl_link == 0xff) -- break; -- if (config_msg_level & CONFIG_TRACE_LEVEL) { -- printf("%s: tpl_code=0x%02x, tpl_link=0x%02x, tag=0x%02x\n", -- __FUNCTION__, tpl_code, tpl_link, *ptr); -- printk("%s: value:", __FUNCTION__); -- for (i=0; iosh, cis, SBSDIO_CIS_SIZE_LIMIT); -- -- return err; --} -- --void --dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path) --{ -- int i, j; -- uint8 mac[6]={0}; -- int fw_num=0, mac_num=0; -- uint32 oui, nic; -- wl_mac_list_t *mac_list; -- wl_mac_range_t *mac_range; -- char *pfw_name; -- int fw_type, fw_type_new; -- -- mac_list = dhd->conf->fw_by_mac.m_mac_list_head; -- fw_num = dhd->conf->fw_by_mac.count; -- if (!mac_list || !fw_num) -- return; -- -- if (dhd_conf_get_mac(dhd, sdh, mac)) { -- CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__)); -- return; -- } -- oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]); -- nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]); -- -- /* find out the last '/' */ -- i = strlen(fw_path); -- while (i > 0) { -- if (fw_path[i] == '/') break; -- i--; -- } -- pfw_name = &fw_path[i+1]; -- fw_type = (strstr(pfw_name, "_mfg") ? -- FW_TYPE_MFG : (strstr(pfw_name, "_apsta") ? -- FW_TYPE_APSTA : (strstr(pfw_name, "_p2p") ? -- FW_TYPE_P2P : FW_TYPE_STA))); -- -- for (i=0; i= mac_range[j].nic_start && nic <= mac_range[j].nic_end) { -- strcpy(pfw_name, mac_list[i].name); -- printf("%s: matched oui=0x%06X, nic=0x%06X\n", -- __FUNCTION__, oui, nic); -- printf("%s: fw_path=%s\n", __FUNCTION__, fw_path); -- return; -- } -- } -- } -- } --} -- --void --dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path) --{ -- int i, j; -- uint8 mac[6]={0}; -- int nv_num=0, mac_num=0; -- uint32 oui, nic; -- wl_mac_list_t *mac_list; -- wl_mac_range_t *mac_range; -- char *pnv_name; -- -- mac_list = dhd->conf->nv_by_mac.m_mac_list_head; -- nv_num = dhd->conf->nv_by_mac.count; -- if (!mac_list || !nv_num) -- return; -- -- if (dhd_conf_get_mac(dhd, sdh, mac)) { -- CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__)); -- return; -- } -- oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]); -- nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]); -- -- /* find out the last '/' */ -- i = strlen(nv_path); -- while (i > 0) { -- if (nv_path[i] == '/') break; -- i--; -- } -- pnv_name = &nv_path[i+1]; -- -- for (i=0; i= mac_range[j].nic_start && nic <= mac_range[j].nic_end) { -- strcpy(pnv_name, mac_list[i].name); -- printf("%s: matched oui=0x%06X, nic=0x%06X\n", -- __FUNCTION__, oui, nic); -- printf("%s: nv_path=%s\n", __FUNCTION__, nv_path); -- return; -- } -- } -- } -- } --} --#endif -- --void --dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path) --{ -- int fw_type, ag_type; -- uint chip, chiprev; -- int i; -- char fw_tail[20]; -- -- chip = dhd->conf->chip; -- chiprev = dhd->conf->chiprev; -- -- if (fw_path[0] == '\0') { --#ifdef CONFIG_BCMDHD_FW_PATH -- bcm_strncpy_s(fw_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1); -- if (fw_path[0] == '\0') --#endif -- { -- printf("firmware path is null\n"); -- return; -- } -- } --#ifndef FW_PATH_AUTO_SELECT -- return; --#endif -- -- /* find out the last '/' */ -- i = strlen(fw_path); -- while (i > 0) { -- if (fw_path[i] == '/') break; -- i--; -- } --#ifdef BAND_AG -- ag_type = FW_TYPE_AG; --#else -- ag_type = strstr(&fw_path[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G; --#endif -- fw_type = (strstr(&fw_path[i], "_mfg") ? FW_TYPE_MFG : -- (strstr(&fw_path[i], "_apsta") ? FW_TYPE_APSTA : -- (strstr(&fw_path[i], "_p2p") ? FW_TYPE_P2P : -- (strstr(&fw_path[i], "_es") ? FW_TYPE_ES : -- FW_TYPE_STA)))); -- -- if (fw_type == FW_TYPE_STA) -- strcpy(fw_tail, ".bin"); -- else if (fw_type == FW_TYPE_APSTA) -- strcpy(fw_tail, "_apsta.bin"); -- else if (fw_type == FW_TYPE_P2P) -- strcpy(fw_tail, "_p2p.bin"); -- else if (fw_type == FW_TYPE_ES) -- strcpy(fw_tail, "_es.bin"); -- else if (fw_type == FW_TYPE_MFG) -- strcpy(fw_tail, "_mfg.bin"); -- -- switch (chip) { --#ifdef BCMSDIO -- case BCM4330_CHIP_ID: -- if (ag_type == FW_TYPE_G) { -- if (chiprev == BCM4330B2_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM4330B2); -- } else { -- if (chiprev == BCM4330B2_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM4330B2_AG); -- } -- break; -- case BCM43362_CHIP_ID: -- if (chiprev == BCM43362A0_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM43362A0); -- else -- strcpy(&fw_path[i+1], FW_BCM43362A2); -- break; -- case BCM43430_CHIP_ID: -- if (chiprev == BCM43430A0_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM43438A0); -- else if (chiprev == BCM43430A1_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM43438A1); -- else if (chiprev == BCM43430A2_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM43436B0); -- break; -- case BCM43012_CHIP_ID: -- if (chiprev == BCM43012B0_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM43012B0); -- case BCM4334_CHIP_ID: -- if (chiprev == BCM4334B1_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM4334B1); -- break; -- case BCM43340_CHIP_ID: -- case BCM43341_CHIP_ID: -- if (chiprev == BCM43341B0_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM43341B1); -- break; -- case BCM4324_CHIP_ID: -- if (chiprev == BCM43241B4_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM43241B4); -- break; -- case BCM4335_CHIP_ID: -- if (chiprev == BCM4335A0_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM4339A0); -- break; -- case BCM4339_CHIP_ID: -- if (chiprev == BCM4339A0_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM4339A0); -- break; -- case BCM4345_CHIP_ID: -- case BCM43454_CHIP_ID: -- if (chiprev == BCM43455C0_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM43455C0); -- else if (chiprev == BCM43455C5_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM43456C5); -- break; -- case BCM4354_CHIP_ID: -- if (chiprev == BCM4354A1_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM4354A1); -- else if (chiprev == BCM4356A2_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM4356A2); -- break; -- case BCM4356_CHIP_ID: -- case BCM4371_CHIP_ID: -- if (chiprev == BCM4356A2_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM4356A2); -- break; -- case BCM43569_CHIP_ID: -- if (chiprev == BCM4358A3_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM4358A3); -- break; -- case BCM4359_CHIP_ID: -- if (chiprev == BCM4359B1_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM4359B1); -- else if (chiprev == BCM4359C0_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM4359C0); -- break; --#endif --#ifdef BCMPCIE -- case BCM4354_CHIP_ID: -- case BCM4356_CHIP_ID: -- if (chiprev == BCM4356A2_CHIP_REV) -- strcpy(&fw_path[i+1], FW_BCM4356A2); -- break; --#endif -- default: -- strcpy(&fw_path[i+1], "fw_bcmdhd"); -- } -- strcat(fw_path, fw_tail); -- -- CONFIG_TRACE(("%s: firmware_path=%s\n", __FUNCTION__, fw_path)); --} -- --void --dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path) --{ -- uint chip, chiprev; -- int i; -- char fw_tail[20]; -- -- chip = dhd->conf->chip; -- chiprev = dhd->conf->chiprev; -- -- if (clm_path[0] == '\0') { -- printf("clm path is null\n"); -- return; -- } -- -- /* find out the last '/' */ -- i = strlen(clm_path); -- while (i > 0) { -- if (clm_path[i] == '/') break; -- i--; -- } -- -- strcpy(fw_tail, ".blob"); -- -- switch (chip) { --#ifdef BCMSDIO -- case BCM43012_CHIP_ID: -- if (chiprev == BCM43012B0_CHIP_REV) -- strcpy(&clm_path[i+1], CLM_BCM43012B0); -- break; --#endif -- default: -- strcpy(&clm_path[i+1], "clm_bcmdhd"); -- } -- strcat(clm_path, fw_tail); -- -- CONFIG_TRACE(("%s: clm_path=%s\n", __FUNCTION__, clm_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); -+#define dtohchanspec(i) i -+ -+#ifdef BCMSDIO -+void -+dhd_conf_free_mac_list(wl_mac_list_ctrl_t *mac_list) -+{ -+ int i; -+ -+ CONFIG_TRACE(("%s called\n", __FUNCTION__)); -+ if (mac_list->m_mac_list_head) { -+ for (i=0; icount; i++) { -+ if (mac_list->m_mac_list_head[i].mac) { -+ CONFIG_TRACE(("%s Free mac %p\n", __FUNCTION__, mac_list->m_mac_list_head[i].mac)); -+ kfree(mac_list->m_mac_list_head[i].mac); -+ } -+ } -+ CONFIG_TRACE(("%s Free m_mac_list_head %p\n", __FUNCTION__, mac_list->m_mac_list_head)); -+ kfree(mac_list->m_mac_list_head); -+ } -+ 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) || defined(FORCE_WOWLAN) -+void -+dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip) -+{ -+ uint32 gpiocontrol, addr; -+ -+ if (CHIPID(chip) == BCM43362_CHIP_ID) { -+ printf("%s: Enable HW OOB for 43362\n", __FUNCTION__); -+ addr = SI_ENUM_BASE + OFFSETOF(chipcregs_t, gpiocontrol); -+ gpiocontrol = bcmsdh_reg_read(sdh, addr, 4); -+ gpiocontrol |= 0x2; -+ bcmsdh_reg_write(sdh, addr, 4, gpiocontrol); -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10005, 0xf, NULL); -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10006, 0x0, NULL); -+ bcmsdh_cfg_write(sdh, SDIO_FUNC_1, 0x10007, 0x2, NULL); -+ } -+} -+#endif -+ -+int -+dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac) -+{ -+ int i, err = -1; -+ uint8 *ptr = 0; -+ unsigned char tpl_code, tpl_link='\0'; -+ uint8 header[3] = {0x80, 0x07, 0x19}; -+ uint8 *cis; -+ -+ if (!(cis = MALLOC(dhd->osh, SBSDIO_CIS_SIZE_LIMIT))) { -+ CONFIG_ERROR(("%s: cis malloc failed\n", __FUNCTION__)); -+ return err; -+ } -+ bzero(cis, SBSDIO_CIS_SIZE_LIMIT); -+ -+ if ((err = bcmsdh_cis_read(sdh, 0, cis, SBSDIO_CIS_SIZE_LIMIT))) { -+ CONFIG_ERROR(("%s: cis read err %d\n", __FUNCTION__, err)); -+ MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT); -+ return err; -+ } -+ err = -1; // reset err; -+ ptr = cis; -+ do { -+ /* 0xff means we're done */ -+ tpl_code = *ptr; -+ ptr++; -+ if (tpl_code == 0xff) -+ break; -+ -+ /* null entries have no link field or data */ -+ if (tpl_code == 0x00) -+ continue; -+ -+ tpl_link = *ptr; -+ ptr++; -+ /* a size of 0xff also means we're done */ -+ if (tpl_link == 0xff) -+ break; -+ if (config_msg_level & CONFIG_TRACE_LEVEL) { -+ printf("%s: tpl_code=0x%02x, tpl_link=0x%02x, tag=0x%02x\n", -+ __FUNCTION__, tpl_code, tpl_link, *ptr); -+ printk("%s: value:", __FUNCTION__); -+ for (i=0; iosh, cis, SBSDIO_CIS_SIZE_LIMIT); -+ -+ return err; -+} -+ -+void -+dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path) -+{ -+ int i, j; -+ uint8 mac[6]={0}; -+ int fw_num=0, mac_num=0; -+ uint32 oui, nic; -+ wl_mac_list_t *mac_list; -+ wl_mac_range_t *mac_range; -+ char *pfw_name; -+ int fw_type, fw_type_new; -+ -+ mac_list = dhd->conf->fw_by_mac.m_mac_list_head; -+ fw_num = dhd->conf->fw_by_mac.count; -+ if (!mac_list || !fw_num) -+ return; -+ -+ if (dhd_conf_get_mac(dhd, sdh, mac)) { -+ CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__)); -+ return; -+ } -+ oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]); -+ nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]); -+ -+ /* find out the last '/' */ -+ i = strlen(fw_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); -- -- CONFIG_TRACE(("%s: nvram_path=%s\n", __FUNCTION__, nv_path)); --} -- --void --dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path) --{ -- int i; -- -- if (src_path[0] == '\0') { -- printf("src_path is null\n"); -- return; -- } else -- strcpy(dst_path, src_path); -- -- /* find out the last '/' */ -- i = strlen(dst_path); -+ if (fw_path[i] == '/') break; -+ i--; -+ } -+ pfw_name = &fw_path[i+1]; -+ fw_type = (strstr(pfw_name, "_mfg") ? -+ FW_TYPE_MFG : (strstr(pfw_name, "_apsta") ? -+ FW_TYPE_APSTA : (strstr(pfw_name, "_p2p") ? -+ FW_TYPE_P2P : FW_TYPE_STA))); -+ -+ for (i=0; i= mac_range[j].nic_start && nic <= mac_range[j].nic_end) { -+ strcpy(pfw_name, mac_list[i].name); -+ printf("%s: matched oui=0x%06X, nic=0x%06X\n", -+ __FUNCTION__, oui, nic); -+ printf("%s: fw_path=%s\n", __FUNCTION__, fw_path); -+ return; -+ } -+ } -+ } -+ } -+} -+ -+void -+dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path) -+{ -+ int i, j; -+ uint8 mac[6]={0}; -+ int nv_num=0, mac_num=0; -+ uint32 oui, nic; -+ wl_mac_list_t *mac_list; -+ wl_mac_range_t *mac_range; -+ char *pnv_name; -+ -+ mac_list = dhd->conf->nv_by_mac.m_mac_list_head; -+ nv_num = dhd->conf->nv_by_mac.count; -+ if (!mac_list || !nv_num) -+ return; -+ -+ if (dhd_conf_get_mac(dhd, sdh, mac)) { -+ CONFIG_ERROR(("%s: Can not read MAC address\n", __FUNCTION__)); -+ return; -+ } -+ oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]); -+ nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]); -+ -+ /* find out the last '/' */ -+ i = strlen(nv_path); - while (i > 0) { -- if (dst_path[i] == '/') break; -- i--; -- } -- strcpy(&dst_path[i+1], dst_name); -- -- CONFIG_TRACE(("%s: dst_path=%s\n", __FUNCTION__, dst_path)); --} -- --#ifdef CONFIG_PATH_AUTO_SELECT --void --dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path) --{ -- uint chip, chiprev; -- int i; -- -- chip = dhd->conf->chip; -- chiprev = dhd->conf->chiprev; -- -- if (conf_path[0] == '\0') { -- printf("config path is null\n"); -- return; -- } -- -- /* find out the last '/' */ -- i = strlen(conf_path); -- while (i > 0) { -- if (conf_path[i] == '/') break; -- i--; -- } -- -- switch (chip) { --#ifdef BCMSDIO -- case BCM4330_CHIP_ID: -- if (chiprev == BCM4330B2_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM4330B2); -- break; -- case BCM43362_CHIP_ID: -- if (chiprev == BCM43362A0_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM43362A0); -- else -- strcpy(&conf_path[i+1], CONFIG_BCM43362A2); -- break; -- case BCM43430_CHIP_ID: -- if (chiprev == BCM43430A0_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM43438A0); -- else if (chiprev == BCM43430A1_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM43438A1); -- else if (chiprev == BCM43430A2_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM43436B0); -- break; -- case BCM4334_CHIP_ID: -- if (chiprev == BCM4334B1_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM4334B1); -- break; -- case BCM43340_CHIP_ID: -- case BCM43341_CHIP_ID: -- if (chiprev == BCM43341B0_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM43341B0); -- break; -- case BCM4324_CHIP_ID: -- if (chiprev == BCM43241B4_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM43241B4); -- break; -- case BCM4335_CHIP_ID: -- if (chiprev == BCM4335A0_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM4339A0); -- break; -- case BCM4345_CHIP_ID: -- case BCM43454_CHIP_ID: -- if (chiprev == BCM43455C0_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM43455C0); -- else if (chiprev == BCM43455C5_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM43456C5); -- break; -- case BCM4339_CHIP_ID: -- if (chiprev == BCM4339A0_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM4339A0); -- break; -- case BCM4354_CHIP_ID: -- if (chiprev == BCM4354A1_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM4354A1); -- else if (chiprev == BCM4356A2_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM4356A2); -- break; -- case BCM4356_CHIP_ID: -- case BCM4371_CHIP_ID: -- if (chiprev == BCM4356A2_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM4356A2); -- break; -- case BCM43569_CHIP_ID: -- if (chiprev == BCM4358A3_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM4358A3); -- break; -- case BCM4359_CHIP_ID: -- if (chiprev == BCM4359B1_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM4359B1); -- else if (chiprev == BCM4359C0_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM4359C0); -- break; --#endif --#ifdef BCMPCIE -- case BCM4354_CHIP_ID: -- case BCM4356_CHIP_ID: -- if (chiprev == BCM4356A2_CHIP_REV) -- strcpy(&conf_path[i+1], CONFIG_BCM4356A2); -- break; --#endif -- } -- -- CONFIG_TRACE(("%s: config_path=%s\n", __FUNCTION__, conf_path)); --} --#endif -- --int --dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val, -- int def, bool down) --{ -- int ret = -1; -- char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ -- -- if (val >= def) { -- if (down) { -- if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0) -- CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret)); -- } -- if (cmd == WLC_SET_VAR) { -- printf("%s: set %s %d\n", __FUNCTION__, name, val); -- bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf)); -- if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) -- CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); -- } else { -- printf("%s: set %s %d %d\n", __FUNCTION__, name, cmd, val); -- if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, 0)) < 0) -- CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); -- } -- } -- -- return ret; --} -- --int --dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf, -- int len, bool down) --{ -- char iovbuf[WLC_IOCTL_SMLEN]; -- int ret = -1; -- -- if (down) { -- if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0) -- CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret)); -- } -- -- if (cmd == WLC_SET_VAR) { -- bcm_mkiovar(name, buf, len, iovbuf, sizeof(iovbuf)); -- if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) -- CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); -- } else { -- if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, TRUE, 0)) < 0) -- CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); -- } -- -- return ret; --} -- --int --dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx) --{ -- char iovbuf[WLC_IOCTL_SMLEN]; -- int ret = -1; -- -- if (cmd == WLC_GET_VAR) { -- if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) { -- ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx); -- if (!ret) { -- memcpy(buf, iovbuf, len); -- } else { -- CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret)); -- } -- } else { -- CONFIG_ERROR(("%s: mkiovar %s failed\n", __FUNCTION__, name)); -- } -- } else { -- ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, FALSE, 0); -- if (ret < 0) -- CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret)); -- } -- -- return ret; --} -- --uint --dhd_conf_get_band(dhd_pub_t *dhd) --{ -- uint band = WLC_BAND_AUTO; -- -- if (dhd && dhd->conf) -- band = dhd->conf->band; -- else -- CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__)); -- -- return band; --} -- --int --dhd_conf_set_country(dhd_pub_t *dhd) --{ -- int bcmerror = -1; -- -- memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t)); -- printf("%s: set country %s, revision %d\n", __FUNCTION__, -- dhd->conf->cspec.ccode, dhd->conf->cspec.rev); -- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)&dhd->conf->cspec, sizeof(wl_country_t), FALSE); -- -- return bcmerror; --} -- --int --dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec) --{ -- int bcmerror = -1; -- -- memset(cspec, 0, sizeof(wl_country_t)); -- bcm_mkiovar("country", NULL, 0, (char*)cspec, sizeof(wl_country_t)); -- if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cspec, sizeof(wl_country_t), FALSE, 0)) < 0) -- CONFIG_ERROR(("%s: country code getting failed %d\n", __FUNCTION__, bcmerror)); -- else -- printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev); -- -- return bcmerror; --} -- --int --dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec) --{ -- int bcmerror = -1, i; -- struct dhd_conf *conf = dhd->conf; -- -- for (i = 0; i < conf->country_list.count; i++) { -- if (!strncmp(cspec->country_abbrev, conf->country_list.cspec[i].country_abbrev, 2)) { -- memcpy(cspec->ccode, -- conf->country_list.cspec[i].ccode, WLC_CNTRY_BUF_SZ); -- cspec->rev = conf->country_list.cspec[i].rev; -- printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev); -- return 0; -- } -- } -- -- return bcmerror; --} -- --int --dhd_conf_fix_country(dhd_pub_t *dhd) --{ -- int bcmerror = -1; -- uint band; -- wl_uint32_list_t *list; -- u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)]; -- -- if (!(dhd && dhd->conf)) { -- return bcmerror; -- } -- -- memset(valid_chan_list, 0, sizeof(valid_chan_list)); -+ if (nv_path[i] == '/') break; -+ i--; -+ } -+ pnv_name = &nv_path[i+1]; -+ -+ for (i=0; i= mac_range[j].nic_start && nic <= mac_range[j].nic_end) { -+ strcpy(pnv_name, mac_list[i].name); -+ printf("%s: matched oui=0x%06X, nic=0x%06X\n", -+ __FUNCTION__, oui, nic); -+ printf("%s: nv_path=%s\n", __FUNCTION__, nv_path); -+ return; -+ } -+ } -+ } -+ } -+} -+#endif -+ -+void -+dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path) -+{ -+ int fw_type, ag_type; -+ uint chip, chiprev; -+ int i; -+ char fw_tail[20]; -+ -+ chip = dhd->conf->chip; -+ chiprev = dhd->conf->chiprev; -+ -+ if (fw_path[0] == '\0') { -+#ifdef CONFIG_BCMDHD_FW_PATH -+ bcm_strncpy_s(fw_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1); -+ if (fw_path[0] == '\0') -+#endif -+ { -+ printf("firmware path is null\n"); -+ return; -+ } -+ } -+#ifndef FW_PATH_AUTO_SELECT -+ return; -+#endif -+ -+ /* find out the last '/' */ -+ i = strlen(fw_path); -+ while (i > 0) { -+ if (fw_path[i] == '/') break; -+ i--; -+ } -+#ifdef BAND_AG -+ ag_type = FW_TYPE_AG; -+#else -+ ag_type = strstr(&fw_path[i], "_ag") ? FW_TYPE_AG : FW_TYPE_G; -+#endif -+ fw_type = (strstr(&fw_path[i], "_mfg") ? FW_TYPE_MFG : -+ (strstr(&fw_path[i], "_apsta") ? FW_TYPE_APSTA : -+ (strstr(&fw_path[i], "_p2p") ? FW_TYPE_P2P : -+ (strstr(&fw_path[i], "_es") ? FW_TYPE_ES : -+ FW_TYPE_STA)))); -+ -+ if (fw_type == FW_TYPE_STA) -+ strcpy(fw_tail, ".bin"); -+ else if (fw_type == FW_TYPE_APSTA) -+ strcpy(fw_tail, "_apsta.bin"); -+ else if (fw_type == FW_TYPE_P2P) -+ strcpy(fw_tail, "_p2p.bin"); -+ else if (fw_type == FW_TYPE_ES) -+ strcpy(fw_tail, "_es.bin"); -+ else if (fw_type == FW_TYPE_MFG) -+ strcpy(fw_tail, "_mfg.bin"); -+ -+ switch (chip) { -+#ifdef BCMSDIO -+ case BCM4330_CHIP_ID: -+ if (ag_type == FW_TYPE_G) { -+ if (chiprev == BCM4330B2_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM4330B2); -+ } else { -+ if (chiprev == BCM4330B2_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM4330B2_AG); -+ } -+ break; -+ case BCM43362_CHIP_ID: -+ if (chiprev == BCM43362A0_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM43362A0); -+ else -+ strcpy(&fw_path[i+1], FW_BCM43362A2); -+ break; -+ case BCM43430_CHIP_ID: -+ if (chiprev == BCM43430A0_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM43438A0); -+ else if (chiprev == BCM43430A1_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM43438A1); -+ else if (chiprev == BCM43430A2_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM43436B0); -+ break; -+ case BCM43012_CHIP_ID: -+ if (chiprev == BCM43012B0_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM43012B0); -+ case BCM4334_CHIP_ID: -+ if (chiprev == BCM4334B1_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM4334B1); -+ break; -+ case BCM43340_CHIP_ID: -+ case BCM43341_CHIP_ID: -+ if (chiprev == BCM43341B0_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM43341B1); -+ break; -+ case BCM4324_CHIP_ID: -+ if (chiprev == BCM43241B4_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM43241B4); -+ break; -+ case BCM4335_CHIP_ID: -+ if (chiprev == BCM4335A0_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM4339A0); -+ break; -+ case BCM4339_CHIP_ID: -+ if (chiprev == BCM4339A0_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM4339A0); -+ break; -+ case BCM4345_CHIP_ID: -+ case BCM43454_CHIP_ID: -+ if (chiprev == BCM43455C0_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM43455C0); -+ else if (chiprev == BCM43455C5_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM43456C5); -+ break; -+ case BCM4354_CHIP_ID: -+ if (chiprev == BCM4354A1_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM4354A1); -+ else if (chiprev == BCM4356A2_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM4356A2); -+ break; -+ case BCM4356_CHIP_ID: -+ case BCM4371_CHIP_ID: -+ if (chiprev == BCM4356A2_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM4356A2); -+ break; -+ case BCM43569_CHIP_ID: -+ if (chiprev == BCM4358A3_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM4358A3); -+ break; -+ case BCM4359_CHIP_ID: -+ if (chiprev == BCM4359B1_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM4359B1); -+ else if (chiprev == BCM4359C0_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM4359C0); -+ break; -+#endif -+#ifdef BCMPCIE -+ case BCM4354_CHIP_ID: -+ case BCM4356_CHIP_ID: -+ if (chiprev == BCM4356A2_CHIP_REV) -+ strcpy(&fw_path[i+1], FW_BCM4356A2); -+ break; -+#endif -+ default: -+ strcpy(&fw_path[i+1], "fw_bcmdhd"); -+ } -+ strcat(fw_path, fw_tail); -+ -+ CONFIG_TRACE(("%s: firmware_path=%s\n", __FUNCTION__, fw_path)); -+} -+ -+void -+dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path) -+{ -+ uint chip, chiprev; -+ int i; -+ char fw_tail[20]; -+ -+ chip = dhd->conf->chip; -+ chiprev = dhd->conf->chiprev; -+ -+ if (clm_path[0] == '\0') { -+ printf("clm path is null\n"); -+ return; -+ } -+ -+ /* find out the last '/' */ -+ i = strlen(clm_path); -+ while (i > 0) { -+ if (clm_path[i] == '/') break; -+ i--; -+ } -+ -+ strcpy(fw_tail, ".blob"); -+ -+ switch (chip) { -+#ifdef BCMSDIO -+ case BCM43012_CHIP_ID: -+ if (chiprev == BCM43012B0_CHIP_REV) -+ strcpy(&clm_path[i+1], CLM_BCM43012B0); -+ break; -+#endif -+ default: -+ strcpy(&clm_path[i+1], "clm_bcmdhd"); -+ } -+ strcat(clm_path, fw_tail); -+ -+ CONFIG_TRACE(("%s: clm_path=%s\n", __FUNCTION__, clm_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); -+ -+ CONFIG_TRACE(("%s: nvram_path=%s\n", __FUNCTION__, nv_path)); -+} -+ -+void -+dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path) -+{ -+ int i; -+ -+ if (src_path[0] == '\0') { -+ printf("src_path is null\n"); -+ return; -+ } else -+ strcpy(dst_path, src_path); -+ -+ /* find out the last '/' */ -+ i = strlen(dst_path); -+ while (i > 0) { -+ if (dst_path[i] == '/') break; -+ i--; -+ } -+ strcpy(&dst_path[i+1], dst_name); -+ -+ CONFIG_TRACE(("%s: dst_path=%s\n", __FUNCTION__, dst_path)); -+} -+ -+#ifdef CONFIG_PATH_AUTO_SELECT -+void -+dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path) -+{ -+ uint chip, chiprev; -+ int i; -+ -+ chip = dhd->conf->chip; -+ chiprev = dhd->conf->chiprev; -+ -+ if (conf_path[0] == '\0') { -+ printf("config path is null\n"); -+ return; -+ } -+ -+ /* find out the last '/' */ -+ i = strlen(conf_path); -+ while (i > 0) { -+ if (conf_path[i] == '/') break; -+ i--; -+ } -+ -+ switch (chip) { -+#ifdef BCMSDIO -+ case BCM4330_CHIP_ID: -+ if (chiprev == BCM4330B2_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM4330B2); -+ break; -+ case BCM43362_CHIP_ID: -+ if (chiprev == BCM43362A0_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM43362A0); -+ else -+ strcpy(&conf_path[i+1], CONFIG_BCM43362A2); -+ break; -+ case BCM43430_CHIP_ID: -+ if (chiprev == BCM43430A0_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM43438A0); -+ else if (chiprev == BCM43430A1_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM43438A1); -+ else if (chiprev == BCM43430A2_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM43436B0); -+ break; -+ case BCM4334_CHIP_ID: -+ if (chiprev == BCM4334B1_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM4334B1); -+ break; -+ case BCM43340_CHIP_ID: -+ case BCM43341_CHIP_ID: -+ if (chiprev == BCM43341B0_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM43341B0); -+ break; -+ case BCM4324_CHIP_ID: -+ if (chiprev == BCM43241B4_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM43241B4); -+ break; -+ case BCM4335_CHIP_ID: -+ if (chiprev == BCM4335A0_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM4339A0); -+ break; -+ case BCM4345_CHIP_ID: -+ case BCM43454_CHIP_ID: -+ if (chiprev == BCM43455C0_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM43455C0); -+ else if (chiprev == BCM43455C5_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM43456C5); -+ break; -+ case BCM4339_CHIP_ID: -+ if (chiprev == BCM4339A0_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM4339A0); -+ break; -+ case BCM4354_CHIP_ID: -+ if (chiprev == BCM4354A1_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM4354A1); -+ else if (chiprev == BCM4356A2_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM4356A2); -+ break; -+ case BCM4356_CHIP_ID: -+ case BCM4371_CHIP_ID: -+ if (chiprev == BCM4356A2_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM4356A2); -+ break; -+ case BCM43569_CHIP_ID: -+ if (chiprev == BCM4358A3_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM4358A3); -+ break; -+ case BCM4359_CHIP_ID: -+ if (chiprev == BCM4359B1_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM4359B1); -+ else if (chiprev == BCM4359C0_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM4359C0); -+ break; -+#endif -+#ifdef BCMPCIE -+ case BCM4354_CHIP_ID: -+ case BCM4356_CHIP_ID: -+ if (chiprev == BCM4356A2_CHIP_REV) -+ strcpy(&conf_path[i+1], CONFIG_BCM4356A2); -+ break; -+#endif -+ } -+ -+ CONFIG_TRACE(("%s: config_path=%s\n", __FUNCTION__, conf_path)); -+} -+#endif -+ -+int -+dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val, -+ int def, bool down) -+{ -+ int ret = -1; -+ char iovbuf[WL_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ -+ -+ if (val >= def) { -+ if (down) { -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0) -+ CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret)); -+ } -+ if (cmd == WLC_SET_VAR) { -+ printf("%s: set %s %d\n", __FUNCTION__, name, val); -+ bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) -+ CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); -+ } else { -+ printf("%s: set %s %d %d\n", __FUNCTION__, name, cmd, val); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, 0)) < 0) -+ CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); -+ } -+ } -+ -+ return ret; -+} -+ -+int -+dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf, -+ int len, bool down) -+{ -+ char iovbuf[WLC_IOCTL_SMLEN]; -+ int ret = -1; -+ -+ if (down) { -+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, 0)) < 0) -+ CONFIG_ERROR(("%s: WLC_DOWN setting failed %d\n", __FUNCTION__, ret)); -+ } -+ -+ if (cmd == WLC_SET_VAR) { -+ bcm_mkiovar(name, buf, len, iovbuf, sizeof(iovbuf)); -+ if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) -+ CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); -+ } else { -+ if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, TRUE, 0)) < 0) -+ CONFIG_ERROR(("%s: %s setting failed %d\n", __FUNCTION__, name, ret)); -+ } -+ -+ return ret; -+} -+ -+int -+dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx) -+{ -+ char iovbuf[WLC_IOCTL_SMLEN]; -+ int ret = -1; -+ -+ if (cmd == WLC_GET_VAR) { -+ if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) { -+ ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx); -+ if (!ret) { -+ memcpy(buf, iovbuf, len); -+ } else { -+ CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret)); -+ } -+ } else { -+ CONFIG_ERROR(("%s: mkiovar %s failed\n", __FUNCTION__, name)); -+ } -+ } else { -+ ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, FALSE, 0); -+ if (ret < 0) -+ CONFIG_ERROR(("%s: get iovar %s failed %d\n", __FUNCTION__, name, ret)); -+ } -+ -+ return ret; -+} -+ -+uint -+dhd_conf_get_band(dhd_pub_t *dhd) -+{ -+ uint band = WLC_BAND_AUTO; -+ -+ if (dhd && dhd->conf) -+ band = dhd->conf->band; -+ else -+ CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__)); -+ -+ return band; -+} -+ -+int -+dhd_conf_set_country(dhd_pub_t *dhd) -+{ -+ int bcmerror = -1; -+ -+ memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t)); -+ printf("%s: set country %s, revision %d\n", __FUNCTION__, -+ dhd->conf->cspec.ccode, dhd->conf->cspec.rev); -+ dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)&dhd->conf->cspec, sizeof(wl_country_t), FALSE); -+ -+ return bcmerror; -+} -+ -+int -+dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec) -+{ -+ int bcmerror = -1; -+ -+ memset(cspec, 0, sizeof(wl_country_t)); -+ bcm_mkiovar("country", NULL, 0, (char*)cspec, sizeof(wl_country_t)); -+ if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cspec, sizeof(wl_country_t), FALSE, 0)) < 0) -+ CONFIG_ERROR(("%s: country code getting failed %d\n", __FUNCTION__, bcmerror)); -+ else -+ printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev); -+ -+ return bcmerror; -+} -+ -+int -+dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec) -+{ -+ int bcmerror = -1, i; -+ struct dhd_conf *conf = dhd->conf; -+ -+ for (i = 0; i < conf->country_list.count; i++) { -+ if (!strncmp(cspec->country_abbrev, conf->country_list.cspec[i].country_abbrev, 2)) { -+ memcpy(cspec->ccode, -+ conf->country_list.cspec[i].ccode, WLC_CNTRY_BUF_SZ); -+ cspec->rev = conf->country_list.cspec[i].rev; -+ printf("%s: %s/%d\n", __FUNCTION__, cspec->ccode, cspec->rev); -+ return 0; -+ } -+ } -+ -+ return bcmerror; -+} -+ -+int -+dhd_conf_fix_country(dhd_pub_t *dhd) -+{ -+ int bcmerror = -1; -+ uint band; -+ wl_uint32_list_t *list; -+ u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)]; -+ -+ 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); -- 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)); -- } -- -- band = dhd_conf_get_band(dhd); -- -- if (bcmerror || ((band==WLC_BAND_AUTO || band==WLC_BAND_2G) && -- dtoh32(list->count)<11)) { -- CONFIG_ERROR(("%s: bcmerror=%d, # of channels %d\n", -- __FUNCTION__, bcmerror, dtoh32(list->count))); -- if ((bcmerror = dhd_conf_set_country(dhd)) < 0) { -- strcpy(dhd->conf->cspec.country_abbrev, "US"); -- dhd->conf->cspec.rev = 0; -- strcpy(dhd->conf->cspec.ccode, "US"); -- dhd_conf_set_country(dhd); -- } -- } -- -- return bcmerror; --} -- --bool --dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel) --{ -- int i; -- bool match = false; -- -- if (dhd && dhd->conf) { -- if (dhd->conf->channels.count == 0) -- return true; -- for (i=0; iconf->channels.count; i++) { -- if (channel == dhd->conf->channels.channel[i]) -- match = true; -- } -- } else { -- match = true; -- CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__)); -- } -- -- return match; --} -- --int --dhd_conf_set_roam(dhd_pub_t *dhd) --{ -- int bcmerror = -1; -- struct dhd_conf *conf = dhd->conf; -- -- dhd_roam_disable = conf->roam_off; -- dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_off", dhd->conf->roam_off, 0, FALSE); -- -- if (!conf->roam_off || !conf->roam_off_suspend) { -- printf("%s: set roam_trigger %d\n", __FUNCTION__, conf->roam_trigger[0]); -- dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_TRIGGER, "WLC_SET_ROAM_TRIGGER", -- (char *)conf->roam_trigger, sizeof(conf->roam_trigger), FALSE); -- -- printf("%s: set roam_scan_period %d\n", __FUNCTION__, conf->roam_scan_period[0]); -- dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_SCAN_PERIOD, "WLC_SET_ROAM_SCAN_PERIOD", -- (char *)conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE); -- -- printf("%s: set roam_delta %d\n", __FUNCTION__, conf->roam_delta[0]); -- dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_DELTA, "WLC_SET_ROAM_DELTA", -- (char *)conf->roam_delta, sizeof(conf->roam_delta), FALSE); -- -- dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "fullroamperiod", dhd->conf->fullroamperiod, 1, FALSE); -- } -- -- return bcmerror; --} -- --void --dhd_conf_set_bw_cap(dhd_pub_t *dhd) --{ -- struct { -- u32 band; -- u32 bw_cap; -- } param = {0, 0}; -- -- if (dhd->conf->bw_cap_2g >= 0) { -- param.band = WLC_BAND_2G; -- param.bw_cap = (uint)dhd->conf->bw_cap_2g; -- printf("%s: set bw_cap 2g %d\n", __FUNCTION__, param.bw_cap); -- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)¶m, sizeof(param), TRUE); -- } -- -- if (dhd->conf->bw_cap_5g >= 0) { -- param.band = WLC_BAND_5G; -- param.bw_cap = (uint)dhd->conf->bw_cap_5g; -- printf("%s: set bw_cap 5g %d\n", __FUNCTION__, param.bw_cap); -- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)¶m, sizeof(param), TRUE); -- } --} -- --void --dhd_conf_get_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acp) --{ -- int bcmerror = -1; -- char iovbuf[WLC_IOCTL_SMLEN]; -- edcf_acparam_t *acparam; -- -- bzero(iovbuf, sizeof(iovbuf)); -- -- /* -- * Get current acparams, using buf as an input buffer. -- * Return data is array of 4 ACs of wme params. -- */ -- if (mode == 0) -- bcm_mkiovar("wme_ac_sta", NULL, 0, iovbuf, sizeof(iovbuf)); -- else -- bcm_mkiovar("wme_ac_ap", NULL, 0, iovbuf, sizeof(iovbuf)); -- if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) { -- CONFIG_ERROR(("%s: wme_ac_sta getting failed %d\n", __FUNCTION__, bcmerror)); -- return; -- } -- 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 txop 0x%x\n", -- __FUNCTION__, -- acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, -- acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, -- acparam->TXOP)); -- acparam = &acp[AC_BE]; -- CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", -- __FUNCTION__, -- acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, -- acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, -- acparam->TXOP)); -- acparam = &acp[AC_VI]; -- CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", -- __FUNCTION__, -- acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, -- acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, -- acparam->TXOP)); -- acparam = &acp[AC_VO]; -- CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", -- __FUNCTION__, -- acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, -- acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, -- acparam->TXOP)); -- -- return; --} -- --void --dhd_conf_update_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acparam_cur, int aci) --{ -- int aifsn, ecwmin, ecwmax, txop; -- edcf_acparam_t *acp; -- struct dhd_conf *conf = dhd->conf; -- wme_param_t *wme; -- -- if (mode == 0) -- wme = &conf->wme_sta; -- else -- wme = &conf->wme_ap; -- -- /* Default value */ -- aifsn = acparam_cur->ACI&EDCF_AIFSN_MASK; -- ecwmin = acparam_cur->ECW&EDCF_ECWMIN_MASK; -- ecwmax = (acparam_cur->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT; -- txop = acparam_cur->TXOP; -- -- /* Modified value */ -- if (wme->aifsn[aci] > 0) -- aifsn = wme->aifsn[aci]; -- if (wme->ecwmin[aci] > 0) -- ecwmin = wme->ecwmin[aci]; -- if (wme->ecwmax[aci] > 0) -- ecwmax = wme->ecwmax[aci]; -- if (wme->txop[aci] > 0) -- txop = wme->txop[aci]; -- -- if (!(wme->aifsn[aci] || wme->ecwmin[aci] || -- wme->ecwmax[aci] || wme->txop[aci])) -- return; -- -- /* Update */ -- acp = acparam_cur; -- acp->ACI = (acp->ACI & ~EDCF_AIFSN_MASK) | (aifsn & EDCF_AIFSN_MASK); -- 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)); -- acp->TXOP = txop; -- -- printf("%s: wme_ac %s aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", -- __FUNCTION__, mode?"ap":"sta", -- acp->ACI, acp->ACI&EDCF_AIFSN_MASK, -- acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, -- acp->TXOP); -- -- /* -- * Now use buf as an output buffer. -- * Put WME acparams after "wme_ac\0" in buf. -- * NOTE: only one of the four ACs can be set at a time. -- */ -- if (mode == 0) -- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE); -- else -- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_ap", (char *)acp, sizeof(edcf_acparam_t), FALSE); -- --} -- --void --dhd_conf_set_wme(dhd_pub_t *dhd, int mode) --{ -- edcf_acparam_t acparam_cur[AC_COUNT]; -- -- if (dhd && dhd->conf) { -- if (!dhd->conf->force_wme_ac) { -- CONFIG_TRACE(("%s: force_wme_ac is not enabled %d\n", -- __FUNCTION__, dhd->conf->force_wme_ac)); -- return; -- } -- -- CONFIG_TRACE(("%s: Before change:\n", __FUNCTION__)); -- dhd_conf_get_wme(dhd, mode, acparam_cur); -- -- dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BK], AC_BK); -- dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BE], AC_BE); -- dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VI], AC_VI); -- dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VO], AC_VO); -- -- CONFIG_TRACE(("%s: After change:\n", __FUNCTION__)); -- dhd_conf_get_wme(dhd, mode, acparam_cur); -- } else { -- CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__)); -- } -- -- return; --} -- --#ifdef PKT_FILTER_SUPPORT --void --dhd_conf_add_pkt_filter(dhd_pub_t *dhd) --{ -- int i, j; -- char str[12]; --#define MACS "%02x%02x%02x%02x%02x%02x" -- -- /* -- * 1. Filter out all pkt: actually not to enable this since 4-way handshake will be filter out as well. -- * 1) dhd_master_mode=0 -- * 2) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000 -- * 2. Filter in less pkt: ARP(0x0806, ID is 105), BRCM(0x886C), 802.1X(0x888E) -- * 1) dhd_master_mode=1 -- * 2) pkt_filter_del=100, 102, 103, 104, 105 -- * 3) pkt_filter_add=131 0 0 12 0xFFFF 0x886C, 132 0 0 12 0xFFFF 0x888E -- * 3. magic pkt: magic_pkt_filter_add=141 0 1 12 -- * 4. Filter out netbios pkt: -- * Netbios: 121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089 -- */ -- for(i=0; iconf->pkt_filter_add.count; i++) { -- dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[i]; -- printf("%s: %s\n", __FUNCTION__, dhd->pktfilter[i+dhd->pktfilter_count]); -- } -- dhd->pktfilter_count += i; -- -- for(i=0; iconf->magic_pkt_filter_add.count; i++) { -- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x"); -- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF"); -- for (j=0; j<16; j++) -- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF"); -- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x"); -- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF"); -- sprintf(str, MACS, MAC2STRDBG(dhd->mac.octet)); -- for (j=0; j<16; j++) -- strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], str); -- dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add.filter[i]; -- dhd->pktfilter_count += 1; -- } --} -- --bool --dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id) --{ -- int i; -- -- if (dhd && dhd->conf) { -- for (i=0; iconf->pkt_filter_del.count; i++) { -- if (id == dhd->conf->pkt_filter_del.id[i]) { -- printf("%s: %d\n", __FUNCTION__, dhd->conf->pkt_filter_del.id[i]); -- return true; -- } -- } -- return false; -- } -- return false; --} -- --void --dhd_conf_discard_pkt_filter(dhd_pub_t *dhd) -+ 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)); -+ } -+ -+ band = dhd_conf_get_band(dhd); -+ -+ if (bcmerror || ((band==WLC_BAND_AUTO || band==WLC_BAND_2G) && -+ dtoh32(list->count)<11)) { -+ CONFIG_ERROR(("%s: bcmerror=%d, # of channels %d\n", -+ __FUNCTION__, bcmerror, dtoh32(list->count))); -+ if ((bcmerror = dhd_conf_set_country(dhd)) < 0) { -+ strcpy(dhd->conf->cspec.country_abbrev, "US"); -+ dhd->conf->cspec.rev = 0; -+ strcpy(dhd->conf->cspec.ccode, "US"); -+ dhd_conf_set_country(dhd); -+ } -+ } -+ -+ return bcmerror; -+} -+ -+bool -+dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel) -+{ -+ int i; -+ bool match = false; -+ -+ if (dhd && dhd->conf) { -+ if (dhd->conf->channels.count == 0) -+ return true; -+ for (i=0; iconf->channels.count; i++) { -+ if (channel == dhd->conf->channels.channel[i]) -+ match = true; -+ } -+ } else { -+ match = true; -+ CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__)); -+ } -+ -+ return match; -+} -+ -+int -+dhd_conf_set_roam(dhd_pub_t *dhd) - { -- dhd->pktfilter_count = 6; -- dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = NULL; -- dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF"; -- dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "102 0 0 0 0xFFFFFF 0x01005E"; -- dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = "103 0 0 0 0xFFFF 0x3333"; -- dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL; -- /* Do not enable ARP to pkt filter if dhd_master_mode is false.*/ -- dhd->pktfilter[DHD_ARP_FILTER_NUM] = NULL; -- -- /* IPv4 broadcast address XXX.XXX.XXX.255 */ -- dhd->pktfilter[dhd->pktfilter_count] = "110 0 0 12 0xFFFF00000000000000000000000000000000000000FF 0x080000000000000000000000000000000000000000FF"; -- dhd->pktfilter_count++; -- /* discard IPv4 multicast address 224.0.0.0/4 */ -- dhd->pktfilter[dhd->pktfilter_count] = "111 0 0 12 0xFFFF00000000000000000000000000000000F0 0x080000000000000000000000000000000000E0"; -- dhd->pktfilter_count++; -- /* discard IPv6 multicast address FF00::/8 */ -- dhd->pktfilter[dhd->pktfilter_count] = "112 0 0 12 0xFFFF000000000000000000000000000000000000000000000000FF 0x86DD000000000000000000000000000000000000000000000000FF"; -- dhd->pktfilter_count++; -- /* discard Netbios pkt */ -- dhd->pktfilter[dhd->pktfilter_count] = "121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089"; -- dhd->pktfilter_count++; -- --} --#endif /* PKT_FILTER_SUPPORT */ -- --int --dhd_conf_get_pm(dhd_pub_t *dhd) --{ -- if (dhd && dhd->conf) -- return dhd->conf->pm; -- return -1; --} -- --#ifdef PROP_TXSTATUS --int --dhd_conf_get_disable_proptx(dhd_pub_t *dhd) --{ -- struct dhd_conf *conf = dhd->conf; -- int disable_proptx = -1; -- int fw_proptx = 0; -- -- /* check fw proptx priority: -- * 1st: check fw support by wl cap -- * 2nd: 4334/43340/43341/43241 support proptx but not show in wl cap, so enable it by default -- * if you would like to disable it, please set disable_proptx=1 in config.txt -- * 3th: disable when proptxstatus not support in wl cap -- */ -- if (FW_SUPPORTED(dhd, proptxstatus)) { -- fw_proptx = 1; -- } else if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID || -- dhd->conf->chip == BCM43340_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { -- fw_proptx = 1; -- } else { -- fw_proptx = 0; -- } -- -- /* returned disable_proptx value: -- * -1: disable in STA and enable in P2P(follow original dhd settings when PROP_TXSTATUS_VSDB enabled) -- * 0: depend on fw support -- * 1: always disable proptx -- */ -- if (conf->disable_proptx == 0) { -- // check fw support as well -- if (fw_proptx) -- disable_proptx = 0; -- else -- disable_proptx = 1; -- } else if (conf->disable_proptx >= 1) { -- disable_proptx = 1; -- } else { -- // check fw support as well -- if (fw_proptx) -- disable_proptx = -1; -- else -- disable_proptx = 1; -- } -- -- printf("%s: fw_proptx=%d, disable_proptx=%d\n", __FUNCTION__, fw_proptx, disable_proptx); -- -- return disable_proptx; --} --#endif -- --uint --pick_config_vars(char *varbuf, uint len, uint start_pos, char *pickbuf) --{ -- bool findNewline, changenewline=FALSE, pick=FALSE; -- int column; -- uint n, pick_column=0; -- -- findNewline = FALSE; -- column = 0; -- -- if (start_pos >= len) { -- CONFIG_ERROR(("%s: wrong start pos\n", __FUNCTION__)); -- return 0; -- } -- -- for (n = start_pos; n < len; n++) { -- if (varbuf[n] == '\r') -- continue; -- if ((findNewline || changenewline) && varbuf[n] != '\n') -- continue; -- findNewline = FALSE; -- if (varbuf[n] == '#') { -- findNewline = TRUE; -- continue; -- } -- if (varbuf[n] == '\\') { -- changenewline = TRUE; -- continue; -- } -- if (!changenewline && varbuf[n] == '\n') { -- if (column == 0) -- continue; -- column = 0; -- continue; -- } -- if (changenewline && varbuf[n] == '\n') { -- changenewline = FALSE; -- continue; -- } -- -- if (column==0 && !pick) { // start to pick -- pick = TRUE; -- column++; -- pick_column = 0; -- } else { -- if (pick && column==0) { // stop to pick -- pick = FALSE; -- break; -- } else -- column++; -- } -- if (pick) { -- if (varbuf[n] == 0x9) -- continue; -- if (pick_column>0 && pickbuf[pick_column-1]==' ' && varbuf[n]==' ') -- continue; -- pickbuf[pick_column] = varbuf[n]; -- pick_column++; -- } -- } -- -- return n; // return current position --} -- --bool --dhd_conf_read_log_level(dhd_pub_t *dhd, char *full_param, uint len_param) --{ -- char *data = full_param+len_param; -- -- if (!strncmp("dhd_msg_level=", full_param, len_param)) { -- dhd_msg_level = (int)simple_strtol(data, NULL, 0); -- printf("%s: dhd_msg_level = 0x%X\n", __FUNCTION__, dhd_msg_level); -- } --#ifdef BCMSDIO -- else if (!strncmp("sd_msglevel=", full_param, len_param)) { -- sd_msglevel = (int)simple_strtol(data, NULL, 0); -- printf("%s: sd_msglevel = 0x%X\n", __FUNCTION__, sd_msglevel); -- } --#endif -- else if (!strncmp("android_msg_level=", full_param, len_param)) { -- android_msg_level = (int)simple_strtol(data, NULL, 0); -- printf("%s: android_msg_level = 0x%X\n", __FUNCTION__, android_msg_level); -- } -- else if (!strncmp("config_msg_level=", full_param, len_param)) { -- config_msg_level = (int)simple_strtol(data, NULL, 0); -- printf("%s: config_msg_level = 0x%X\n", __FUNCTION__, config_msg_level); -- } --#ifdef WL_CFG80211 -- else if (!strncmp("wl_dbg_level=", full_param, len_param)) { -- wl_dbg_level = (int)simple_strtol(data, NULL, 0); -- printf("%s: wl_dbg_level = 0x%X\n", __FUNCTION__, wl_dbg_level); -- } --#endif --#if defined(WL_WIRELESS_EXT) -- else if (!strncmp("iw_msg_level=", full_param, len_param)) { -- iw_msg_level = (int)simple_strtol(data, NULL, 0); -- printf("%s: iw_msg_level = 0x%X\n", __FUNCTION__, iw_msg_level); -- } --#endif --#if defined(DHD_DEBUG) -- else if (!strncmp("dhd_console_ms=", full_param, len_param)) { -- dhd_console_ms = (int)simple_strtol(data, NULL, 0); -- printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms); -- } --#endif -- else -- return false; -- -- return true; --} -- --void --dhd_conf_read_wme_ac_value(wme_param_t *wme, char *pick, int ac_val) --{ -- char *pick_tmp, *pch; -- -- /* Process WMM parameters */ -- pick_tmp = pick; -- pch = bcmstrstr(pick_tmp, "aifsn "); -- if (pch) { -- wme->aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0); -- printf("%s: ac_val=%d, aifsn=%d\n", __FUNCTION__, ac_val, wme->aifsn[ac_val]); -- } -- pick_tmp = pick; -- pch = bcmstrstr(pick_tmp, "ecwmin "); -- if (pch) { -- wme->ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0); -- printf("%s: ac_val=%d, ecwmin=%d\n", __FUNCTION__, ac_val, wme->ecwmin[ac_val]); -- } -- pick_tmp = pick; -- pch = bcmstrstr(pick_tmp, "ecwmax "); -- if (pch) { -- wme->ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0); -- printf("%s: ac_val=%d, ecwmax=%d\n", __FUNCTION__, ac_val, wme->ecwmax[ac_val]); -- } -- pick_tmp = pick; -- pch = bcmstrstr(pick_tmp, "txop "); -- if (pch) { -- wme->txop[ac_val] = (int)simple_strtol(pch+strlen("txop "), NULL, 0); -- printf("%s: ac_val=%d, txop=0x%x\n", __FUNCTION__, ac_val, wme->txop[ac_val]); -- } -- --} -- --bool --dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *full_param, uint len_param) --{ -- struct dhd_conf *conf = dhd->conf; -- char *data = full_param+len_param; -- -- // wme_ac_sta_be=aifsn 1 ecwmin 2 ecwmax 3 txop 0x5e -- // wme_ac_sta_vo=aifsn 1 ecwmin 1 ecwmax 1 txop 0x5e -- -- /* Process WMM parameters */ -- if (!strncmp("force_wme_ac=", full_param, len_param)) { -- conf->force_wme_ac = (int)simple_strtol(data, NULL, 10); -- printf("%s: force_wme_ac = %d\n", __FUNCTION__, conf->force_wme_ac); -- } -- else if (!strncmp("wme_ac_sta_be=", full_param, len_param)) { -- dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BE); -- } -- else if (!strncmp("wme_ac_sta_bk=", full_param, len_param)) { -- dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BK); -- } -- else if (!strncmp("wme_ac_sta_vi=", full_param, len_param)) { -- dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VI); -- } -- else if (!strncmp("wme_ac_sta_vo=", full_param, len_param)) { -- dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VO); -- } -- else if (!strncmp("wme_ac_ap_be=", full_param, len_param)) { -- dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BE); -- } -- else if (!strncmp("wme_ac_ap_bk=", full_param, len_param)) { -- dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BK); -- } -- else if (!strncmp("wme_ac_ap_vi=", full_param, len_param)) { -- dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VI); -- } -- else if (!strncmp("wme_ac_ap_vo=", full_param, len_param)) { -- dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VO); -- } -- else -- return false; -- -- return true; --} -- --bool --dhd_conf_read_fw_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param) --{ -- int i, j; -- char *pch, *pick_tmp; -- wl_mac_list_t *mac_list; -- wl_mac_range_t *mac_range; -- struct dhd_conf *conf = dhd->conf; -- char *data = full_param+len_param; -- -- /* Process fw_by_mac: -- * fw_by_mac=[fw_mac_num] \ -- * [fw_name1] [mac_num1] [oui1-1] [nic_start1-1] [nic_end1-1] \ -- * [oui1-1] [nic_start1-1] [nic_end1-1]... \ -- * [oui1-n] [nic_start1-n] [nic_end1-n] \ -- * [fw_name2] [mac_num2] [oui2-1] [nic_start2-1] [nic_end2-1] \ -- * [oui2-1] [nic_start2-1] [nic_end2-1]... \ -- * [oui2-n] [nic_start2-n] [nic_end2-n] \ -- * Ex: fw_by_mac=2 \ -- * fw_bcmdhd1.bin 2 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \ -- * fw_bcmdhd2.bin 3 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \ -- * 0x983B16 0x916157 0x916487 -- */ -- -- if (!strncmp("fw_by_mac=", full_param, len_param)) { -- pick_tmp = data; -- pch = bcmstrtok(&pick_tmp, " ", 0); -- conf->fw_by_mac.count = (uint32)simple_strtol(pch, NULL, 0); -- if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->fw_by_mac.count, GFP_KERNEL))) { -- conf->fw_by_mac.count = 0; -- CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); -- } -- printf("%s: fw_count=%d\n", __FUNCTION__, conf->fw_by_mac.count); -- conf->fw_by_mac.m_mac_list_head = mac_list; -- for (i=0; ifw_by_mac.count; i++) { -- pch = bcmstrtok(&pick_tmp, " ", 0); -- strcpy(mac_list[i].name, pch); -- pch = bcmstrtok(&pick_tmp, " ", 0); -- mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0); -- printf("%s: name=%s, mac_count=%d\n", __FUNCTION__, -- mac_list[i].name, mac_list[i].count); -- if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) { -- mac_list[i].count = 0; -- CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); -- break; -- } -- mac_list[i].mac = mac_range; -- for (j=0; jconf; -- char *data = full_param+len_param; -- -- /* Process nv_by_mac: -- * [nv_by_mac]: The same format as fw_by_mac -- */ -- if (!strncmp("nv_by_mac=", full_param, len_param)) { -- pick_tmp = data; -- pch = bcmstrtok(&pick_tmp, " ", 0); -- conf->nv_by_mac.count = (uint32)simple_strtol(pch, NULL, 0); -- if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_mac.count, GFP_KERNEL))) { -- conf->nv_by_mac.count = 0; -- CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); -- } -- printf("%s: nv_count=%d\n", __FUNCTION__, conf->nv_by_mac.count); -- conf->nv_by_mac.m_mac_list_head = mac_list; -- for (i=0; inv_by_mac.count; i++) { -- pch = bcmstrtok(&pick_tmp, " ", 0); -- strcpy(mac_list[i].name, pch); -- pch = bcmstrtok(&pick_tmp, " ", 0); -- mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0); -- printf("%s: name=%s, mac_count=%d\n", __FUNCTION__, -- mac_list[i].name, mac_list[i].count); -- if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) { -- mac_list[i].count = 0; -- CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); -- break; -- } -- mac_list[i].mac = mac_range; -- for (j=0; jconf; -- char *data = full_param+len_param; -- -- /* Process nv_by_chip: -- * nv_by_chip=[nv_chip_num] \ -- * [chip1] [chiprev1] [nv_name1] [chip2] [chiprev2] [nv_name2] \ -- * Ex: nv_by_chip=2 \ -- * 43430 0 nvram_ap6212.txt 43430 1 nvram_ap6212a.txt \ -- */ -- if (!strncmp("nv_by_chip=", full_param, len_param)) { -- pick_tmp = data; -- 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); -- } -- } -- else -- return false; -- -- return true; --} -- --bool --dhd_conf_read_roam_params(dhd_pub_t *dhd, char *full_param, uint len_param) --{ -- struct dhd_conf *conf = dhd->conf; -- char *data = full_param+len_param; -- -- if (!strncmp("roam_off=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- conf->roam_off = 0; -- else -- conf->roam_off = 1; -- printf("%s: roam_off = %d\n", __FUNCTION__, conf->roam_off); -- } -- else if (!strncmp("roam_off_suspend=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- conf->roam_off_suspend = 0; -- else -- conf->roam_off_suspend = 1; -- printf("%s: roam_off_suspend = %d\n", __FUNCTION__, conf->roam_off_suspend); -- } -- else if (!strncmp("roam_trigger=", full_param, len_param)) { -- conf->roam_trigger[0] = (int)simple_strtol(data, NULL, 10); -- printf("%s: roam_trigger = %d\n", __FUNCTION__, -- conf->roam_trigger[0]); -- } -- else if (!strncmp("roam_scan_period=", full_param, len_param)) { -- conf->roam_scan_period[0] = (int)simple_strtol(data, NULL, 10); -- printf("%s: roam_scan_period = %d\n", __FUNCTION__, -- conf->roam_scan_period[0]); -- } -- else if (!strncmp("roam_delta=", full_param, len_param)) { -- conf->roam_delta[0] = (int)simple_strtol(data, NULL, 10); -- printf("%s: roam_delta = %d\n", __FUNCTION__, conf->roam_delta[0]); -- } -- else if (!strncmp("fullroamperiod=", full_param, len_param)) { -- conf->fullroamperiod = (int)simple_strtol(data, NULL, 10); -- printf("%s: fullroamperiod = %d\n", __FUNCTION__, -- conf->fullroamperiod); -- } else -- return false; -- -- return true; --} -- --bool --dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param) --{ -- int i; -- char *pch, *pick_tmp; -- struct dhd_conf *conf = dhd->conf; -- char *data = full_param+len_param; -- -- /* Process country_list: -- * country_list=[country1]:[ccode1]/[regrev1], -- * [country2]:[ccode2]/[regrev2] \ -- * Ex: country_list=US:US/0, TW:TW/1 -- */ -- if (!strncmp("country_list=", full_param, len_param)) { -- pick_tmp = data; -- for (i=0; icountry_list.cspec[i].country_abbrev, pch); -- pch = bcmstrtok(&pick_tmp, "/", 0); -- if (!pch) -- break; -- memcpy(conf->country_list.cspec[i].ccode, pch, 2); -- pch = bcmstrtok(&pick_tmp, ", ", 0); -- if (!pch) -- break; -- conf->country_list.cspec[i].rev = (int32)simple_strtol(pch, NULL, 10); -- conf->country_list.count ++; -- CONFIG_TRACE(("%s: country_list abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__, -- conf->country_list.cspec[i].country_abbrev, -- conf->country_list.cspec[i].ccode, -- conf->country_list.cspec[i].rev)); -- } -- printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count); -- } -- else -- return false; -- -- return true; --} -- --#ifdef PKT_FILTER_SUPPORT --bool --dhd_conf_read_pkt_filter(dhd_pub_t *dhd, char *full_param, uint len_param) --{ -- struct dhd_conf *conf = dhd->conf; -- char *data = full_param+len_param; -- char *pch, *pick_tmp; -- int i; -- -- /* Process pkt filter: -- * 1) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000 -- * 2) pkt_filter_del=100, 102, 103, 104, 105 -- * 3) magic_pkt_filter_add=141 0 1 12 -- */ -- if (!strncmp("dhd_master_mode=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- dhd_master_mode = FALSE; -- else -- dhd_master_mode = TRUE; -- printf("%s: dhd_master_mode = %d\n", __FUNCTION__, dhd_master_mode); -- } -- else if (!strncmp("pkt_filter_add=", full_param, len_param)) { -- pick_tmp = data; -- pch = bcmstrtok(&pick_tmp, ",.-", 0); -- i=0; -- while (pch != NULL && ipkt_filter_add.filter[i][0], pch); -- printf("%s: pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->pkt_filter_add.filter[i][0]); -- pch = bcmstrtok(&pick_tmp, ",.-", 0); -- i++; -- } -- conf->pkt_filter_add.count = i; -- } -- else if (!strncmp("pkt_filter_del=", full_param, len_param)) { -- pick_tmp = data; -- pch = bcmstrtok(&pick_tmp, " ,.-", 0); -- i=0; -- while (pch != NULL && ipkt_filter_del.id[i] = (uint32)simple_strtol(pch, NULL, 10); -- pch = bcmstrtok(&pick_tmp, " ,.-", 0); -- i++; -- } -- conf->pkt_filter_del.count = i; -- printf("%s: pkt_filter_del id = ", __FUNCTION__); -- for (i=0; ipkt_filter_del.count; i++) -- printf("%d ", conf->pkt_filter_del.id[i]); -- printf("\n"); -- } -- else if (!strncmp("magic_pkt_filter_add=", full_param, len_param)) { -- pick_tmp = data; -- pch = bcmstrtok(&pick_tmp, ",.-", 0); -- i=0; -- while (pch != NULL && imagic_pkt_filter_add.filter[i][0], pch); -- printf("%s: magic_pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->magic_pkt_filter_add.filter[i][0]); -- pch = bcmstrtok(&pick_tmp, ",.-", 0); -- i++; -- } -- conf->magic_pkt_filter_add.count = i; -- } -- else -- return false; -- -- return true; --} --#endif -- --#ifdef IAPSTA_PREINIT --/* -- * iapsta_init=mode [sta|ap|apsta|dualap] vifname [wlan1] -- * iapsta_config=ifname [wlan0|wlan1] ssid [xxx] chan [x] -- hidden [y|n] maxassoc [x] -- amode [open|shared|wpapsk|wpa2psk|wpawpa2psk] -- emode [none|wep|tkip|aes|tkipaes] -- key [xxxxx] -- * iapsta_enable=ifname [wlan0|wlan1] --*/ --bool --dhd_conf_read_iapsta(dhd_pub_t *dhd, char *full_param, uint len_param) --{ -- struct dhd_conf *conf = dhd->conf; -- char *data = full_param+len_param; -- -- if (!strncmp("iapsta_init=", full_param, len_param)) { -- sprintf(conf->iapsta_init, "iapsta_init %s", data); -- printf("%s: iapsta_init=%s\n", __FUNCTION__, conf->iapsta_init); -- } -- else if (!strncmp("iapsta_config=", full_param, len_param)) { -- sprintf(conf->iapsta_config, "iapsta_config %s", data); -- printf("%s: iapsta_config=%s\n", __FUNCTION__, conf->iapsta_config); -- } -- else if (!strncmp("iapsta_enable=", full_param, len_param)) { -- sprintf(conf->iapsta_enable, "iapsta_enable %s", data); -- printf("%s: iapsta_enable=%s\n", __FUNCTION__, conf->iapsta_enable); -- } -- else -- return false; -- -- return true; --} --#endif -- --#ifdef IDHCPC --bool --dhd_conf_read_dhcp_params(dhd_pub_t *dhd, char *full_param, uint len_param) --{ -- struct dhd_conf *conf = dhd->conf; -- char *data = full_param+len_param; -- -- if (!strncmp("dhcpc_enable=", full_param, len_param)) { -- conf->dhcpc_enable = (int)simple_strtol(data, NULL, 10); -- printf("%s: dhcpc_enable = %d\n", __FUNCTION__, conf->dhcpc_enable); -- } -- else -- return false; -- -- return true; --} --#endif -- --#ifdef BCMSDIO --bool --dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param) --{ -- struct dhd_conf *conf = dhd->conf; -- char *data = full_param+len_param; -- -- if (!strncmp("dhd_doflow=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- dhd_doflow = FALSE; -- else -- dhd_doflow = TRUE; -- printf("%s: dhd_doflow = %d\n", __FUNCTION__, dhd_doflow); -- } -- else if (!strncmp("dhd_slpauto=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- dhd_slpauto = FALSE; -- else -- dhd_slpauto = TRUE; -- printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto); -- } -- else if (!strncmp("kso_enable=", full_param, len_param)) { -- if (!strncmp(data, "1", 1)) -- dhd_slpauto = FALSE; -- else -- dhd_slpauto = TRUE; -- printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto); -- } -- else if (!strncmp("bus:txglom=", full_param, len_param)) { -- conf->bus_txglom = (int)simple_strtol(data, NULL, 10); -- printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom); -- } -- else if (!strncmp("use_rxchain=", full_param, len_param)) { -- conf->use_rxchain = (int)simple_strtol(data, NULL, 10); -- printf("%s: use_rxchain = %d\n", __FUNCTION__, conf->use_rxchain); -- } -- else if (!strncmp("dhd_txminmax=", full_param, len_param)) { -- conf->dhd_txminmax = (uint)simple_strtol(data, NULL, 10); -- printf("%s: dhd_txminmax = %d\n", __FUNCTION__, conf->dhd_txminmax); -- } -- else if (!strncmp("txinrx_thres=", full_param, len_param)) { -- conf->txinrx_thres = (int)simple_strtol(data, NULL, 10); -- printf("%s: txinrx_thres = %d\n", __FUNCTION__, conf->txinrx_thres); -- } -- else if (!strncmp("sd_f2_blocksize=", full_param, len_param)) { -- conf->sd_f2_blocksize = (int)simple_strtol(data, NULL, 10); -- printf("%s: sd_f2_blocksize = %d\n", __FUNCTION__, conf->sd_f2_blocksize); -- } -- else if (!strncmp("oob_enabled_later=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- conf->oob_enabled_later = FALSE; -- else -- conf->oob_enabled_later = TRUE; -- printf("%s: oob_enabled_later = %d\n", __FUNCTION__, conf->oob_enabled_later); -- } --#if defined(BCMSDIOH_TXGLOM) -- else if (!strncmp("txglomsize=", full_param, len_param)) { -- conf->txglomsize = (uint)simple_strtol(data, NULL, 10); -- if (conf->txglomsize > SDPCM_MAXGLOM_SIZE) -- conf->txglomsize = SDPCM_MAXGLOM_SIZE; -- printf("%s: txglomsize = %d\n", __FUNCTION__, conf->txglomsize); -- } -- else if (!strncmp("swtxglom=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- conf->swtxglom = FALSE; -- else -- conf->swtxglom = TRUE; -- printf("%s: swtxglom = %d\n", __FUNCTION__, conf->swtxglom); -- } -- else if (!strncmp("txglom_ext=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- conf->txglom_ext = FALSE; -- else -- conf->txglom_ext = TRUE; -- printf("%s: txglom_ext = %d\n", __FUNCTION__, conf->txglom_ext); -- if (conf->txglom_ext) { -- if ((conf->chip == BCM43362_CHIP_ID) || (conf->chip == BCM4330_CHIP_ID)) -- conf->txglom_bucket_size = 1680; -- else if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || -- conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) -- conf->txglom_bucket_size = 1684; -- } -- printf("%s: txglom_bucket_size = %d\n", __FUNCTION__, conf->txglom_bucket_size); -- } -- else if (!strncmp("bus:rxglom=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- conf->bus_rxglom = FALSE; -- else -- conf->bus_rxglom = TRUE; -- printf("%s: bus:rxglom = %d\n", __FUNCTION__, conf->bus_rxglom); -- } -- else if (!strncmp("dhd_poll=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- conf->dhd_poll = 0; -- else -- conf->dhd_poll = 1; -- printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll); -- } -- else if (!strncmp("deferred_tx_len=", full_param, len_param)) { -- conf->deferred_tx_len = (int)simple_strtol(data, NULL, 10); -- printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len); -- } -- else if (!strncmp("txctl_tmo_fix=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- conf->txctl_tmo_fix = FALSE; -- else -- conf->txctl_tmo_fix = TRUE; -- printf("%s: txctl_tmo_fix = %d\n", __FUNCTION__, conf->txctl_tmo_fix); -- } -- else if (!strncmp("tx_in_rx=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- conf->tx_in_rx = FALSE; -- else -- conf->tx_in_rx = TRUE; -- printf("%s: tx_in_rx = %d\n", __FUNCTION__, conf->tx_in_rx); -- } -- else if (!strncmp("tx_max_offset=", full_param, len_param)) { -- conf->tx_max_offset = (int)simple_strtol(data, NULL, 10); -- printf("%s: tx_max_offset = %d\n", __FUNCTION__, conf->tx_max_offset); -- } -- else if (!strncmp("txglom_mode=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- conf->txglom_mode = FALSE; -- else -- conf->txglom_mode = TRUE; -- printf("%s: txglom_mode = %d\n", __FUNCTION__, conf->txglom_mode); -- } --#endif -- else -- return false; -- -- return true; --} --#endif -- --bool --dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param) --{ -- struct dhd_conf *conf = dhd->conf; -- char *data = full_param+len_param; -- -- if (!strncmp("lpc=", full_param, len_param)) { -- conf->lpc = (int)simple_strtol(data, NULL, 10); -- printf("%s: lpc = %d\n", __FUNCTION__, conf->lpc); -- } -- else if (!strncmp("deepsleep=", full_param, len_param)) { -- if (!strncmp(data, "1", 1)) -- conf->deepsleep = TRUE; -- else -- conf->deepsleep = FALSE; -- printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep); -- } -- else if (!strncmp("PM=", full_param, len_param)) { -- conf->pm = (int)simple_strtol(data, NULL, 10); -- printf("%s: PM = %d\n", __FUNCTION__, conf->pm); -- } -- else if (!strncmp("pm_in_suspend=", full_param, len_param)) { -- conf->pm_in_suspend = (int)simple_strtol(data, NULL, 10); -- printf("%s: pm_in_suspend = %d\n", __FUNCTION__, conf->pm_in_suspend); -- } -- else if (!strncmp("pm2_sleep_ret=", full_param, len_param)) { -- conf->pm2_sleep_ret = (int)simple_strtol(data, NULL, 10); -- printf("%s: pm2_sleep_ret = %d\n", __FUNCTION__, conf->pm2_sleep_ret); -- } -- else if (!strncmp("xmit_in_suspend=", full_param, len_param)) { -- if (!strncmp(data, "1", 1)) -- conf->xmit_in_suspend = TRUE; -- else -- conf->xmit_in_suspend = FALSE; -- printf("%s: xmit_in_suspend = %d\n", __FUNCTION__, conf->xmit_in_suspend); -- } -- else -- return false; -- -- return true; --} -- --bool --dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param) --{ -- struct dhd_conf *conf = dhd->conf; -- char *data = full_param+len_param; -- uint len_data = strlen(data); -- char *pch, *pick_tmp; -- int i; -- -- if (!strncmp("band=", full_param, len_param)) { -- /* Process band: -- * band=a for 5GHz only and band=b for 2.4GHz only -- */ -- if (!strcmp(data, "b")) -- conf->band = WLC_BAND_2G; -- else if (!strcmp(data, "a")) -- conf->band = WLC_BAND_5G; -- else -- conf->band = WLC_BAND_AUTO; -- printf("%s: band = %d\n", __FUNCTION__, conf->band); -- } -- else if (!strncmp("mimo_bw_cap=", full_param, len_param)) { -- conf->mimo_bw_cap = (uint)simple_strtol(data, NULL, 10); -- printf("%s: mimo_bw_cap = %d\n", __FUNCTION__, conf->mimo_bw_cap); -- } -- else if (!strncmp("bw_cap_2g=", full_param, len_param)) { -- conf->bw_cap_2g = (uint)simple_strtol(data, NULL, 0); -- printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_2g); -- } -- else if (!strncmp("bw_cap_5g=", full_param, len_param)) { -- conf->bw_cap_5g = (uint)simple_strtol(data, NULL, 0); -- printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_5g); -- } -- else if (!strncmp("ccode=", full_param, len_param)) { -- memset(&conf->cspec, 0, sizeof(wl_country_t)); -- memcpy(conf->cspec.country_abbrev, data, len_data); -- memcpy(conf->cspec.ccode, data, len_data); -- printf("%s: ccode = %s\n", __FUNCTION__, conf->cspec.ccode); -- } -- else if (!strncmp("regrev=", full_param, len_param)) { -- conf->cspec.rev = (int32)simple_strtol(data, NULL, 10); -- printf("%s: regrev = %d\n", __FUNCTION__, conf->cspec.rev); -- } -- else if (!strncmp("channels=", full_param, len_param)) { -- pick_tmp = data; -- pch = bcmstrtok(&pick_tmp, " ,.-", 0); -- i=0; -- while (pch != NULL && ichannels.channel[i] = (uint32)simple_strtol(pch, NULL, 10); -- pch = bcmstrtok(&pick_tmp, " ,.-", 0); -- i++; -- } -- conf->channels.count = i; -- printf("%s: channels = ", __FUNCTION__); -- for (i=0; ichannels.count; i++) -- printf("%d ", conf->channels.channel[i]); -- printf("\n"); -- } -- else if (!strncmp("keep_alive_period=", full_param, len_param)) { -- conf->keep_alive_period = (uint)simple_strtol(data, NULL, 10); -- printf("%s: keep_alive_period = %d\n", __FUNCTION__, -- conf->keep_alive_period); -- } -- else if (!strncmp("stbc=", full_param, len_param)) { -- conf->stbc = (int)simple_strtol(data, NULL, 10); -- printf("%s: stbc = %d\n", __FUNCTION__, conf->stbc); -- } -- else if (!strncmp("phy_oclscdenable=", full_param, len_param)) { -- conf->phy_oclscdenable = (int)simple_strtol(data, NULL, 10); -- printf("%s: phy_oclscdenable = %d\n", __FUNCTION__, conf->phy_oclscdenable); -- } -- else if (!strncmp("srl=", full_param, len_param)) { -- conf->srl = (int)simple_strtol(data, NULL, 10); -- printf("%s: srl = %d\n", __FUNCTION__, conf->srl); -- } -- else if (!strncmp("lrl=", full_param, len_param)) { -- conf->lrl = (int)simple_strtol(data, NULL, 10); -- printf("%s: lrl = %d\n", __FUNCTION__, conf->lrl); -- } -- else if (!strncmp("bcn_timeout=", full_param, len_param)) { -- conf->bcn_timeout= (uint)simple_strtol(data, NULL, 10); -- printf("%s: bcn_timeout = %d\n", __FUNCTION__, conf->bcn_timeout); -- } -- else if (!strncmp("ampdu_ba_wsize=", full_param, len_param)) { -- conf->ampdu_ba_wsize = (int)simple_strtol(data, NULL, 10); -- printf("%s: ampdu_ba_wsize = %d\n", __FUNCTION__, conf->ampdu_ba_wsize); -- } -- else if (!strncmp("ampdu_hostreorder=", full_param, len_param)) { -- conf->ampdu_hostreorder = (int)simple_strtol(data, NULL, 10); -- printf("%s: ampdu_hostreorder = %d\n", __FUNCTION__, conf->ampdu_hostreorder); -- } -- else if (!strncmp("spect=", full_param, len_param)) { -- conf->spect = (int)simple_strtol(data, NULL, 10); -- printf("%s: spect = %d\n", __FUNCTION__, conf->spect); -- } -- else if (!strncmp("txbf=", full_param, len_param)) { -- conf->txbf = (int)simple_strtol(data, NULL, 10); -- printf("%s: txbf = %d\n", __FUNCTION__, conf->txbf); -- } -- else if (!strncmp("frameburst=", full_param, len_param)) { -- conf->frameburst = (int)simple_strtol(data, NULL, 10); -- printf("%s: frameburst = %d\n", __FUNCTION__, conf->frameburst); -- } -- else if (!strncmp("disable_proptx=", full_param, len_param)) { -- conf->disable_proptx = (int)simple_strtol(data, NULL, 10); -- printf("%s: disable_proptx = %d\n", __FUNCTION__, conf->disable_proptx); -- } --#ifdef DHDTCPACK_SUPPRESS -- else if (!strncmp("tcpack_sup_mode=", full_param, len_param)) { -- conf->tcpack_sup_mode = (uint)simple_strtol(data, NULL, 10); -- printf("%s: tcpack_sup_mode = %d\n", __FUNCTION__, conf->tcpack_sup_mode); -- } --#endif -- else if (!strncmp("pktprio8021x=", full_param, len_param)) { -- conf->pktprio8021x = (int)simple_strtol(data, NULL, 10); -- printf("%s: pktprio8021x = %d\n", __FUNCTION__, conf->pktprio8021x); -- } -- else if (!strncmp("dhd_txbound=", full_param, len_param)) { -- dhd_txbound = (uint)simple_strtol(data, NULL, 10); -- printf("%s: dhd_txbound = %d\n", __FUNCTION__, dhd_txbound); -- } -- else if (!strncmp("dhd_rxbound=", full_param, len_param)) { -- dhd_rxbound = (uint)simple_strtol(data, NULL, 10); -- printf("%s: dhd_rxbound = %d\n", __FUNCTION__, dhd_rxbound); -- } -- else if (!strncmp("rsdb_mode=", full_param, len_param)) { -- conf->rsdb_mode = (int)simple_strtol(data, NULL, 10); -- printf("%s: rsdb_mode = %d\n", __FUNCTION__, conf->rsdb_mode); -- } -- else if (!strncmp("vhtmode=", full_param, len_param)) { -- if (!strncmp(data, "0", 1)) -- conf->vhtmode = 0; -- else -- conf->vhtmode = 1; -- printf("%s: vhtmode = %d\n", __FUNCTION__, conf->vhtmode); -- } -- else if (!strncmp("num_different_channels=", full_param, len_param)) { -- conf->num_different_channels = (int)simple_strtol(data, NULL, 10); -- printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels); -- } -- else if (!strncmp("autocountry=", full_param, len_param)) { -- conf->autocountry = (int)simple_strtol(data, NULL, 10); -- printf("%s: autocountry = %d\n", __FUNCTION__, conf->autocountry); -- } -- else if (!strncmp("tsq=", full_param, len_param)) { -- conf->tsq = (int)simple_strtol(data, NULL, 10); -- printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq); -- } -- else -- return false; -- -- return true; --} -- --int --dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path) --{ -- int bcmerror = -1; -- uint len, start_pos=0; -- void * image = NULL; -- char * memblock = NULL; -- char *bufp, *pick = NULL, *pch; -- bool conf_file_exists; -- uint len_param; -- -- conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0')); -- if (!conf_file_exists) { -- printf("%s: config path %s\n", __FUNCTION__, conf_path); -- return (0); -- } -- -- if (conf_file_exists) { -- image = dhd_os_open_image(conf_path); -- if (image == NULL) { -- printf("%s: Ignore config file %s\n", __FUNCTION__, conf_path); -- goto err; -- } -- } -- -- memblock = MALLOC(dhd->osh, MAXSZ_CONFIG); -- if (memblock == NULL) { -- CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n", -- __FUNCTION__, MAXSZ_CONFIG)); -- goto err; -- } -- -- pick = MALLOC(dhd->osh, MAXSZ_BUF); -- if (!pick) { -- CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n", -- __FUNCTION__, MAXSZ_BUF)); -- goto err; -- } -- -- /* Read variables */ -- if (conf_file_exists) { -- len = dhd_os_get_image_block(memblock, MAXSZ_CONFIG, image); -- } -- if (len > 0 && len < MAXSZ_CONFIG) { -- bufp = (char *)memblock; -- bufp[len] = 0; -- -- while (start_pos < len) { -- memset(pick, 0, MAXSZ_BUF); -- start_pos = pick_config_vars(bufp, len, start_pos, pick); -- pch = strchr(pick, '='); -- if (pch != NULL) { -- len_param = pch-pick+1; -- if (len_param == strlen(pick)) { -- CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick)); -- continue; -- } -- } else { -- CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick)); -- continue; -- } -- -- if (dhd_conf_read_log_level(dhd, pick, len_param)) -- continue; -- else if (dhd_conf_read_roam_params(dhd, pick, len_param)) -- continue; -- else if (dhd_conf_read_wme_ac_params(dhd, pick, len_param)) -- continue; -- else if (dhd_conf_read_fw_by_mac(dhd, pick, len_param)) -- continue; -- else if (dhd_conf_read_nv_by_mac(dhd, pick, len_param)) -- continue; -- else if (dhd_conf_read_nv_by_chip(dhd, pick, len_param)) -- continue; -- else if (dhd_conf_read_country_list(dhd, pick, len_param)) -- continue; --#ifdef PKT_FILTER_SUPPORT -- else if (dhd_conf_read_pkt_filter(dhd, pick, len_param)) -- continue; --#endif /* PKT_FILTER_SUPPORT */ --#ifdef IAPSTA_PREINIT -- else if (dhd_conf_read_iapsta(dhd, pick, len_param)) -- continue; --#endif /* IAPSTA_PREINIT */ --#ifdef IDHCPC -- else if (dhd_conf_read_dhcp_params(dhd, pick, len_param)) -- continue; --#endif /* IDHCPC */ --#ifdef BCMSDIO -- else if (dhd_conf_read_sdio_params(dhd, pick, len_param)) -- continue; --#endif /* BCMSDIO */ -- else if (dhd_conf_read_pm_params(dhd, pick, len_param)) -- continue; -- else if (dhd_conf_read_others(dhd, pick, len_param)) -- continue; -+ int bcmerror = -1; -+ struct dhd_conf *conf = dhd->conf; -+ -+ dhd_roam_disable = conf->roam_off; -+ dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_off", dhd->conf->roam_off, 0, FALSE); -+ -+ if (!conf->roam_off || !conf->roam_off_suspend) { -+ printf("%s: set roam_trigger %d\n", __FUNCTION__, conf->roam_trigger[0]); -+ dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_TRIGGER, "WLC_SET_ROAM_TRIGGER", -+ (char *)conf->roam_trigger, sizeof(conf->roam_trigger), FALSE); -+ -+ printf("%s: set roam_scan_period %d\n", __FUNCTION__, conf->roam_scan_period[0]); -+ dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_SCAN_PERIOD, "WLC_SET_ROAM_SCAN_PERIOD", -+ (char *)conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE); -+ -+ printf("%s: set roam_delta %d\n", __FUNCTION__, conf->roam_delta[0]); -+ dhd_conf_set_bufiovar(dhd, WLC_SET_ROAM_DELTA, "WLC_SET_ROAM_DELTA", -+ (char *)conf->roam_delta, sizeof(conf->roam_delta), FALSE); -+ -+ dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "fullroamperiod", dhd->conf->fullroamperiod, 1, FALSE); -+ } -+ -+ return bcmerror; -+} -+ -+void -+dhd_conf_set_bw_cap(dhd_pub_t *dhd) -+{ -+ struct { -+ u32 band; -+ u32 bw_cap; -+ } param = {0, 0}; -+ -+ if (dhd->conf->bw_cap_2g >= 0) { -+ param.band = WLC_BAND_2G; -+ param.bw_cap = (uint)dhd->conf->bw_cap_2g; -+ printf("%s: set bw_cap 2g %d\n", __FUNCTION__, param.bw_cap); -+ dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)¶m, sizeof(param), TRUE); -+ } -+ -+ if (dhd->conf->bw_cap_5g >= 0) { -+ param.band = WLC_BAND_5G; -+ param.bw_cap = (uint)dhd->conf->bw_cap_5g; -+ printf("%s: set bw_cap 5g %d\n", __FUNCTION__, param.bw_cap); -+ dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "bw_cap", (char *)¶m, sizeof(param), TRUE); -+ } -+} -+ -+void -+dhd_conf_get_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acp) -+{ -+ int bcmerror = -1; -+ char iovbuf[WLC_IOCTL_SMLEN]; -+ edcf_acparam_t *acparam; -+ -+ bzero(iovbuf, sizeof(iovbuf)); -+ -+ /* -+ * Get current acparams, using buf as an input buffer. -+ * Return data is array of 4 ACs of wme params. -+ */ -+ if (mode == 0) -+ bcm_mkiovar("wme_ac_sta", NULL, 0, iovbuf, sizeof(iovbuf)); -+ else -+ bcm_mkiovar("wme_ac_ap", NULL, 0, iovbuf, sizeof(iovbuf)); -+ if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) < 0) { -+ CONFIG_ERROR(("%s: wme_ac_sta getting failed %d\n", __FUNCTION__, bcmerror)); -+ return; -+ } -+ 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 txop 0x%x\n", -+ __FUNCTION__, -+ acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, -+ acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, -+ acparam->TXOP)); -+ acparam = &acp[AC_BE]; -+ CONFIG_TRACE(("%s: BE: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", -+ __FUNCTION__, -+ acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, -+ acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, -+ acparam->TXOP)); -+ acparam = &acp[AC_VI]; -+ CONFIG_TRACE(("%s: VI: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", -+ __FUNCTION__, -+ acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, -+ acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, -+ acparam->TXOP)); -+ acparam = &acp[AC_VO]; -+ CONFIG_TRACE(("%s: VO: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", -+ __FUNCTION__, -+ acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK, -+ acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, -+ acparam->TXOP)); -+ -+ return; -+} -+ -+void -+dhd_conf_update_wme(dhd_pub_t *dhd, int mode, edcf_acparam_t *acparam_cur, int aci) -+{ -+ int aifsn, ecwmin, ecwmax, txop; -+ edcf_acparam_t *acp; -+ struct dhd_conf *conf = dhd->conf; -+ wme_param_t *wme; -+ -+ if (mode == 0) -+ wme = &conf->wme_sta; -+ else -+ wme = &conf->wme_ap; -+ -+ /* Default value */ -+ aifsn = acparam_cur->ACI&EDCF_AIFSN_MASK; -+ ecwmin = acparam_cur->ECW&EDCF_ECWMIN_MASK; -+ ecwmax = (acparam_cur->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT; -+ txop = acparam_cur->TXOP; -+ -+ /* Modified value */ -+ if (wme->aifsn[aci] > 0) -+ aifsn = wme->aifsn[aci]; -+ if (wme->ecwmin[aci] > 0) -+ ecwmin = wme->ecwmin[aci]; -+ if (wme->ecwmax[aci] > 0) -+ ecwmax = wme->ecwmax[aci]; -+ if (wme->txop[aci] > 0) -+ txop = wme->txop[aci]; -+ -+ if (!(wme->aifsn[aci] || wme->ecwmin[aci] || -+ wme->ecwmax[aci] || wme->txop[aci])) -+ return; -+ -+ /* Update */ -+ acp = acparam_cur; -+ acp->ACI = (acp->ACI & ~EDCF_AIFSN_MASK) | (aifsn & EDCF_AIFSN_MASK); -+ 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)); -+ acp->TXOP = txop; -+ -+ printf("%s: wme_ac %s aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n", -+ __FUNCTION__, mode?"ap":"sta", -+ acp->ACI, acp->ACI&EDCF_AIFSN_MASK, -+ acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT, -+ acp->TXOP); -+ -+ /* -+ * Now use buf as an output buffer. -+ * Put WME acparams after "wme_ac\0" in buf. -+ * NOTE: only one of the four ACs can be set at a time. -+ */ -+ if (mode == 0) -+ dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_sta", (char *)acp, sizeof(edcf_acparam_t), FALSE); -+ else -+ dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "wme_ac_ap", (char *)acp, sizeof(edcf_acparam_t), FALSE); -+ -+} -+ -+void -+dhd_conf_set_wme(dhd_pub_t *dhd, int mode) -+{ -+ edcf_acparam_t acparam_cur[AC_COUNT]; -+ -+ if (dhd && dhd->conf) { -+ if (!dhd->conf->force_wme_ac) { -+ CONFIG_TRACE(("%s: force_wme_ac is not enabled %d\n", -+ __FUNCTION__, dhd->conf->force_wme_ac)); -+ return; -+ } -+ -+ CONFIG_TRACE(("%s: Before change:\n", __FUNCTION__)); -+ dhd_conf_get_wme(dhd, mode, acparam_cur); -+ -+ dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BK], AC_BK); -+ dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_BE], AC_BE); -+ dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VI], AC_VI); -+ dhd_conf_update_wme(dhd, mode, &acparam_cur[AC_VO], AC_VO); -+ -+ CONFIG_TRACE(("%s: After change:\n", __FUNCTION__)); -+ dhd_conf_get_wme(dhd, mode, acparam_cur); -+ } else { -+ CONFIG_ERROR(("%s: dhd or conf is NULL\n", __FUNCTION__)); -+ } -+ -+ return; -+} -+ -+#ifdef PKT_FILTER_SUPPORT -+void -+dhd_conf_add_pkt_filter(dhd_pub_t *dhd) -+{ -+ int i, j; -+ char str[12]; -+#define MACS "%02x%02x%02x%02x%02x%02x" -+ -+ /* -+ * 1. Filter out all pkt: actually not to enable this since 4-way handshake will be filter out as well. -+ * 1) dhd_master_mode=0 -+ * 2) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000 -+ * 2. Filter in less pkt: ARP(0x0806, ID is 105), BRCM(0x886C), 802.1X(0x888E) -+ * 1) dhd_master_mode=1 -+ * 2) pkt_filter_del=100, 102, 103, 104, 105 -+ * 3) pkt_filter_add=131 0 0 12 0xFFFF 0x886C, 132 0 0 12 0xFFFF 0x888E -+ * 3. magic pkt: magic_pkt_filter_add=141 0 1 12 -+ * 4. Filter out netbios pkt: -+ * Netbios: 121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089 -+ */ -+ for(i=0; iconf->pkt_filter_add.count; i++) { -+ dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[i]; -+ printf("%s: %s\n", __FUNCTION__, dhd->pktfilter[i+dhd->pktfilter_count]); -+ } -+ dhd->pktfilter_count += i; -+ -+ for(i=0; iconf->magic_pkt_filter_add.count; i++) { -+ strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x"); -+ strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF"); -+ for (j=0; j<16; j++) -+ strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF"); -+ strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], " 0x"); -+ strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], "FFFFFFFFFFFF"); -+ sprintf(str, MACS, MAC2STRDBG(dhd->mac.octet)); -+ for (j=0; j<16; j++) -+ strcat(&dhd->conf->magic_pkt_filter_add.filter[i][0], str); -+ dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add.filter[i]; -+ dhd->pktfilter_count += 1; -+ } -+} -+ -+bool -+dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id) -+{ -+ int i; -+ -+ if (dhd && dhd->conf) { -+ for (i=0; iconf->pkt_filter_del.count; i++) { -+ if (id == dhd->conf->pkt_filter_del.id[i]) { -+ printf("%s: %d\n", __FUNCTION__, dhd->conf->pkt_filter_del.id[i]); -+ return true; -+ } -+ } -+ return false; -+ } -+ return false; -+} -+ -+void -+dhd_conf_discard_pkt_filter(dhd_pub_t *dhd) -+{ -+ dhd->pktfilter_count = 6; -+ dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = NULL; -+ dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF"; -+ dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "102 0 0 0 0xFFFFFF 0x01005E"; -+ dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = "103 0 0 0 0xFFFF 0x3333"; -+ dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL; -+ /* Do not enable ARP to pkt filter if dhd_master_mode is false.*/ -+ dhd->pktfilter[DHD_ARP_FILTER_NUM] = NULL; -+ -+ /* IPv4 broadcast address XXX.XXX.XXX.255 */ -+ dhd->pktfilter[dhd->pktfilter_count] = "110 0 0 12 0xFFFF00000000000000000000000000000000000000FF 0x080000000000000000000000000000000000000000FF"; -+ dhd->pktfilter_count++; -+ /* discard IPv4 multicast address 224.0.0.0/4 */ -+ dhd->pktfilter[dhd->pktfilter_count] = "111 0 0 12 0xFFFF00000000000000000000000000000000F0 0x080000000000000000000000000000000000E0"; -+ dhd->pktfilter_count++; -+ /* discard IPv6 multicast address FF00::/8 */ -+ dhd->pktfilter[dhd->pktfilter_count] = "112 0 0 12 0xFFFF000000000000000000000000000000000000000000000000FF 0x86DD000000000000000000000000000000000000000000000000FF"; -+ dhd->pktfilter_count++; -+ /* discard Netbios pkt */ -+ dhd->pktfilter[dhd->pktfilter_count] = "121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089"; -+ dhd->pktfilter_count++; -+ -+} -+#endif /* PKT_FILTER_SUPPORT */ -+ -+int -+dhd_conf_get_pm(dhd_pub_t *dhd) -+{ -+ if (dhd && dhd->conf) -+ return dhd->conf->pm; -+ return -1; -+} -+ -+#ifdef PROP_TXSTATUS -+int -+dhd_conf_get_disable_proptx(dhd_pub_t *dhd) -+{ -+ struct dhd_conf *conf = dhd->conf; -+ int disable_proptx = -1; -+ int fw_proptx = 0; -+ -+ /* check fw proptx priority: -+ * 1st: check fw support by wl cap -+ * 2nd: 4334/43340/43341/43241 support proptx but not show in wl cap, so enable it by default -+ * if you would like to disable it, please set disable_proptx=1 in config.txt -+ * 3th: disable when proptxstatus not support in wl cap -+ */ -+ if (FW_SUPPORTED(dhd, proptxstatus)) { -+ fw_proptx = 1; -+ } else if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID || -+ dhd->conf->chip == BCM43340_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { -+ fw_proptx = 1; -+ } else { -+ fw_proptx = 0; -+ } -+ -+ /* returned disable_proptx value: -+ * -1: disable in STA and enable in P2P(follow original dhd settings when PROP_TXSTATUS_VSDB enabled) -+ * 0: depend on fw support -+ * 1: always disable proptx -+ */ -+ if (conf->disable_proptx == 0) { -+ // check fw support as well -+ if (fw_proptx) -+ disable_proptx = 0; -+ else -+ disable_proptx = 1; -+ } else if (conf->disable_proptx >= 1) { -+ disable_proptx = 1; -+ } else { -+ // check fw support as well -+ if (fw_proptx) -+ disable_proptx = -1; -+ else -+ disable_proptx = 1; -+ } -+ -+ printf("%s: fw_proptx=%d, disable_proptx=%d\n", __FUNCTION__, fw_proptx, disable_proptx); -+ -+ return disable_proptx; -+} -+#endif -+ -+uint -+pick_config_vars(char *varbuf, uint len, uint start_pos, char *pickbuf) -+{ -+ bool findNewline, changenewline=FALSE, pick=FALSE; -+ int column; -+ uint n, pick_column=0; -+ -+ findNewline = FALSE; -+ column = 0; -+ -+ if (start_pos >= len) { -+ CONFIG_ERROR(("%s: wrong start pos\n", __FUNCTION__)); -+ return 0; -+ } -+ -+ for (n = start_pos; n < len; n++) { -+ if (varbuf[n] == '\r') -+ continue; -+ if ((findNewline || changenewline) && varbuf[n] != '\n') -+ continue; -+ findNewline = FALSE; -+ if (varbuf[n] == '#') { -+ findNewline = TRUE; -+ continue; -+ } -+ if (varbuf[n] == '\\') { -+ changenewline = TRUE; -+ continue; -+ } -+ if (!changenewline && varbuf[n] == '\n') { -+ if (column == 0) -+ continue; -+ column = 0; -+ continue; -+ } -+ if (changenewline && varbuf[n] == '\n') { -+ changenewline = FALSE; -+ continue; -+ } -+ -+ if (column==0 && !pick) { // start to pick -+ pick = TRUE; -+ column++; -+ pick_column = 0; -+ } else { -+ if (pick && column==0) { // stop to pick -+ pick = FALSE; -+ break; -+ } else -+ column++; -+ } -+ if (pick) { -+ if (varbuf[n] == 0x9) -+ continue; -+ if (pick_column>0 && pickbuf[pick_column-1]==' ' && varbuf[n]==' ') -+ continue; -+ pickbuf[pick_column] = varbuf[n]; -+ pick_column++; -+ } -+ } -+ -+ return n; // return current position -+} -+ -+bool -+dhd_conf_read_log_level(dhd_pub_t *dhd, char *full_param, uint len_param) -+{ -+ char *data = full_param+len_param; -+ -+ if (!strncmp("dhd_msg_level=", full_param, len_param)) { -+ dhd_msg_level = (int)simple_strtol(data, NULL, 0); -+ printf("%s: dhd_msg_level = 0x%X\n", __FUNCTION__, dhd_msg_level); -+ } -+#ifdef BCMSDIO -+ else if (!strncmp("sd_msglevel=", full_param, len_param)) { -+ sd_msglevel = (int)simple_strtol(data, NULL, 0); -+ printf("%s: sd_msglevel = 0x%X\n", __FUNCTION__, sd_msglevel); -+ } -+#endif -+ else if (!strncmp("android_msg_level=", full_param, len_param)) { -+ android_msg_level = (int)simple_strtol(data, NULL, 0); -+ printf("%s: android_msg_level = 0x%X\n", __FUNCTION__, android_msg_level); -+ } -+ else if (!strncmp("config_msg_level=", full_param, len_param)) { -+ config_msg_level = (int)simple_strtol(data, NULL, 0); -+ printf("%s: config_msg_level = 0x%X\n", __FUNCTION__, config_msg_level); -+ } -+#ifdef WL_CFG80211 -+ else if (!strncmp("wl_dbg_level=", full_param, len_param)) { -+ wl_dbg_level = (int)simple_strtol(data, NULL, 0); -+ printf("%s: wl_dbg_level = 0x%X\n", __FUNCTION__, wl_dbg_level); -+ } -+#endif -+#if defined(WL_WIRELESS_EXT) -+ else if (!strncmp("iw_msg_level=", full_param, len_param)) { -+ iw_msg_level = (int)simple_strtol(data, NULL, 0); -+ printf("%s: iw_msg_level = 0x%X\n", __FUNCTION__, iw_msg_level); -+ } -+#endif -+#if defined(DHD_DEBUG) -+ else if (!strncmp("dhd_console_ms=", full_param, len_param)) { -+ dhd_console_ms = (int)simple_strtol(data, NULL, 0); -+ printf("%s: dhd_console_ms = 0x%X\n", __FUNCTION__, dhd_console_ms); -+ } -+#endif -+ else -+ return false; -+ -+ return true; -+} -+ -+void -+dhd_conf_read_wme_ac_value(wme_param_t *wme, char *pick, int ac_val) -+{ -+ char *pick_tmp, *pch; -+ -+ /* Process WMM parameters */ -+ pick_tmp = pick; -+ pch = bcmstrstr(pick_tmp, "aifsn "); -+ if (pch) { -+ wme->aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0); -+ printf("%s: ac_val=%d, aifsn=%d\n", __FUNCTION__, ac_val, wme->aifsn[ac_val]); -+ } -+ pick_tmp = pick; -+ pch = bcmstrstr(pick_tmp, "ecwmin "); -+ if (pch) { -+ wme->ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0); -+ printf("%s: ac_val=%d, ecwmin=%d\n", __FUNCTION__, ac_val, wme->ecwmin[ac_val]); -+ } -+ pick_tmp = pick; -+ pch = bcmstrstr(pick_tmp, "ecwmax "); -+ if (pch) { -+ wme->ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0); -+ printf("%s: ac_val=%d, ecwmax=%d\n", __FUNCTION__, ac_val, wme->ecwmax[ac_val]); -+ } -+ pick_tmp = pick; -+ pch = bcmstrstr(pick_tmp, "txop "); -+ if (pch) { -+ wme->txop[ac_val] = (int)simple_strtol(pch+strlen("txop "), NULL, 0); -+ printf("%s: ac_val=%d, txop=0x%x\n", __FUNCTION__, ac_val, wme->txop[ac_val]); -+ } -+ -+} -+ -+bool -+dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *full_param, uint len_param) -+{ -+ struct dhd_conf *conf = dhd->conf; -+ char *data = full_param+len_param; -+ -+ // wme_ac_sta_be=aifsn 1 ecwmin 2 ecwmax 3 txop 0x5e -+ // wme_ac_sta_vo=aifsn 1 ecwmin 1 ecwmax 1 txop 0x5e -+ -+ /* Process WMM parameters */ -+ if (!strncmp("force_wme_ac=", full_param, len_param)) { -+ conf->force_wme_ac = (int)simple_strtol(data, NULL, 10); -+ printf("%s: force_wme_ac = %d\n", __FUNCTION__, conf->force_wme_ac); -+ } -+ else if (!strncmp("wme_ac_sta_be=", full_param, len_param)) { -+ dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BE); -+ } -+ else if (!strncmp("wme_ac_sta_bk=", full_param, len_param)) { -+ dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BK); -+ } -+ else if (!strncmp("wme_ac_sta_vi=", full_param, len_param)) { -+ dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VI); -+ } -+ else if (!strncmp("wme_ac_sta_vo=", full_param, len_param)) { -+ dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VO); -+ } -+ else if (!strncmp("wme_ac_ap_be=", full_param, len_param)) { -+ dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BE); -+ } -+ else if (!strncmp("wme_ac_ap_bk=", full_param, len_param)) { -+ dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BK); -+ } -+ else if (!strncmp("wme_ac_ap_vi=", full_param, len_param)) { -+ dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VI); -+ } -+ else if (!strncmp("wme_ac_ap_vo=", full_param, len_param)) { -+ dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VO); -+ } -+ else -+ return false; -+ -+ return true; -+} -+ -+bool -+dhd_conf_read_fw_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param) -+{ -+ int i, j; -+ char *pch, *pick_tmp; -+ wl_mac_list_t *mac_list; -+ wl_mac_range_t *mac_range; -+ struct dhd_conf *conf = dhd->conf; -+ char *data = full_param+len_param; -+ -+ /* Process fw_by_mac: -+ * fw_by_mac=[fw_mac_num] \ -+ * [fw_name1] [mac_num1] [oui1-1] [nic_start1-1] [nic_end1-1] \ -+ * [oui1-1] [nic_start1-1] [nic_end1-1]... \ -+ * [oui1-n] [nic_start1-n] [nic_end1-n] \ -+ * [fw_name2] [mac_num2] [oui2-1] [nic_start2-1] [nic_end2-1] \ -+ * [oui2-1] [nic_start2-1] [nic_end2-1]... \ -+ * [oui2-n] [nic_start2-n] [nic_end2-n] \ -+ * Ex: fw_by_mac=2 \ -+ * fw_bcmdhd1.bin 2 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \ -+ * fw_bcmdhd2.bin 3 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \ -+ * 0x983B16 0x916157 0x916487 -+ */ -+ -+ if (!strncmp("fw_by_mac=", full_param, len_param)) { -+ pick_tmp = data; -+ pch = bcmstrtok(&pick_tmp, " ", 0); -+ conf->fw_by_mac.count = (uint32)simple_strtol(pch, NULL, 0); -+ if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->fw_by_mac.count, GFP_KERNEL))) { -+ conf->fw_by_mac.count = 0; -+ CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); -+ } -+ printf("%s: fw_count=%d\n", __FUNCTION__, conf->fw_by_mac.count); -+ conf->fw_by_mac.m_mac_list_head = mac_list; -+ for (i=0; ifw_by_mac.count; i++) { -+ pch = bcmstrtok(&pick_tmp, " ", 0); -+ strcpy(mac_list[i].name, pch); -+ pch = bcmstrtok(&pick_tmp, " ", 0); -+ mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0); -+ printf("%s: name=%s, mac_count=%d\n", __FUNCTION__, -+ mac_list[i].name, mac_list[i].count); -+ if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) { -+ mac_list[i].count = 0; -+ CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); -+ break; -+ } -+ mac_list[i].mac = mac_range; -+ for (j=0; jconf; -+ char *data = full_param+len_param; -+ -+ /* Process nv_by_mac: -+ * [nv_by_mac]: The same format as fw_by_mac -+ */ -+ if (!strncmp("nv_by_mac=", full_param, len_param)) { -+ pick_tmp = data; -+ pch = bcmstrtok(&pick_tmp, " ", 0); -+ conf->nv_by_mac.count = (uint32)simple_strtol(pch, NULL, 0); -+ if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_mac.count, GFP_KERNEL))) { -+ conf->nv_by_mac.count = 0; -+ CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); -+ } -+ printf("%s: nv_count=%d\n", __FUNCTION__, conf->nv_by_mac.count); -+ conf->nv_by_mac.m_mac_list_head = mac_list; -+ for (i=0; inv_by_mac.count; i++) { -+ pch = bcmstrtok(&pick_tmp, " ", 0); -+ strcpy(mac_list[i].name, pch); -+ pch = bcmstrtok(&pick_tmp, " ", 0); -+ mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0); -+ printf("%s: name=%s, mac_count=%d\n", __FUNCTION__, -+ mac_list[i].name, mac_list[i].count); -+ if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count, GFP_KERNEL))) { -+ mac_list[i].count = 0; -+ CONFIG_ERROR(("%s: kmalloc failed\n", __FUNCTION__)); -+ break; -+ } -+ mac_list[i].mac = mac_range; -+ for (j=0; jconf; -+ char *data = full_param+len_param; -+ -+ /* Process nv_by_chip: -+ * nv_by_chip=[nv_chip_num] \ -+ * [chip1] [chiprev1] [nv_name1] [chip2] [chiprev2] [nv_name2] \ -+ * Ex: nv_by_chip=2 \ -+ * 43430 0 nvram_ap6212.txt 43430 1 nvram_ap6212a.txt \ -+ */ -+ if (!strncmp("nv_by_chip=", full_param, len_param)) { -+ pick_tmp = data; -+ 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); -+ } -+ } -+ else -+ return false; -+ -+ return true; -+} -+ -+bool -+dhd_conf_read_roam_params(dhd_pub_t *dhd, char *full_param, uint len_param) -+{ -+ struct dhd_conf *conf = dhd->conf; -+ char *data = full_param+len_param; -+ -+ if (!strncmp("roam_off=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ conf->roam_off = 0; -+ else -+ conf->roam_off = 1; -+ printf("%s: roam_off = %d\n", __FUNCTION__, conf->roam_off); -+ } -+ else if (!strncmp("roam_off_suspend=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ conf->roam_off_suspend = 0; -+ else -+ conf->roam_off_suspend = 1; -+ printf("%s: roam_off_suspend = %d\n", __FUNCTION__, conf->roam_off_suspend); -+ } -+ else if (!strncmp("roam_trigger=", full_param, len_param)) { -+ conf->roam_trigger[0] = (int)simple_strtol(data, NULL, 10); -+ printf("%s: roam_trigger = %d\n", __FUNCTION__, -+ conf->roam_trigger[0]); -+ } -+ else if (!strncmp("roam_scan_period=", full_param, len_param)) { -+ conf->roam_scan_period[0] = (int)simple_strtol(data, NULL, 10); -+ printf("%s: roam_scan_period = %d\n", __FUNCTION__, -+ conf->roam_scan_period[0]); -+ } -+ else if (!strncmp("roam_delta=", full_param, len_param)) { -+ conf->roam_delta[0] = (int)simple_strtol(data, NULL, 10); -+ printf("%s: roam_delta = %d\n", __FUNCTION__, conf->roam_delta[0]); -+ } -+ else if (!strncmp("fullroamperiod=", full_param, len_param)) { -+ conf->fullroamperiod = (int)simple_strtol(data, NULL, 10); -+ printf("%s: fullroamperiod = %d\n", __FUNCTION__, -+ conf->fullroamperiod); -+ } else -+ return false; -+ -+ return true; -+} -+ -+bool -+dhd_conf_read_country_list(dhd_pub_t *dhd, char *full_param, uint len_param) -+{ -+ int i; -+ char *pch, *pick_tmp; -+ struct dhd_conf *conf = dhd->conf; -+ char *data = full_param+len_param; -+ -+ /* Process country_list: -+ * country_list=[country1]:[ccode1]/[regrev1], -+ * [country2]:[ccode2]/[regrev2] \ -+ * Ex: country_list=US:US/0, TW:TW/1 -+ */ -+ if (!strncmp("country_list=", full_param, len_param)) { -+ pick_tmp = data; -+ for (i=0; icountry_list.cspec[i].country_abbrev, pch); -+ pch = bcmstrtok(&pick_tmp, "/", 0); -+ if (!pch) -+ break; -+ memcpy(conf->country_list.cspec[i].ccode, pch, 2); -+ pch = bcmstrtok(&pick_tmp, ", ", 0); -+ if (!pch) -+ break; -+ conf->country_list.cspec[i].rev = (int32)simple_strtol(pch, NULL, 10); -+ conf->country_list.count ++; -+ CONFIG_TRACE(("%s: country_list abbrev=%s, ccode=%s, regrev=%d\n", __FUNCTION__, -+ conf->country_list.cspec[i].country_abbrev, -+ conf->country_list.cspec[i].ccode, -+ conf->country_list.cspec[i].rev)); -+ } -+ printf("%s: %d country in list\n", __FUNCTION__, conf->country_list.count); -+ } -+ else -+ return false; -+ -+ return true; -+} -+ -+#ifdef PKT_FILTER_SUPPORT -+bool -+dhd_conf_read_pkt_filter(dhd_pub_t *dhd, char *full_param, uint len_param) -+{ -+ struct dhd_conf *conf = dhd->conf; -+ char *data = full_param+len_param; -+ char *pch, *pick_tmp; -+ int i; -+ -+ /* Process pkt filter: -+ * 1) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000 -+ * 2) pkt_filter_del=100, 102, 103, 104, 105 -+ * 3) magic_pkt_filter_add=141 0 1 12 -+ */ -+ if (!strncmp("dhd_master_mode=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ dhd_master_mode = FALSE; -+ else -+ dhd_master_mode = TRUE; -+ printf("%s: dhd_master_mode = %d\n", __FUNCTION__, dhd_master_mode); -+ } -+ else if (!strncmp("pkt_filter_add=", full_param, len_param)) { -+ pick_tmp = data; -+ pch = bcmstrtok(&pick_tmp, ",.-", 0); -+ i=0; -+ while (pch != NULL && ipkt_filter_add.filter[i][0], pch); -+ printf("%s: pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->pkt_filter_add.filter[i][0]); -+ pch = bcmstrtok(&pick_tmp, ",.-", 0); -+ i++; -+ } -+ conf->pkt_filter_add.count = i; -+ } -+ else if (!strncmp("pkt_filter_del=", full_param, len_param)) { -+ pick_tmp = data; -+ pch = bcmstrtok(&pick_tmp, " ,.-", 0); -+ i=0; -+ while (pch != NULL && ipkt_filter_del.id[i] = (uint32)simple_strtol(pch, NULL, 10); -+ pch = bcmstrtok(&pick_tmp, " ,.-", 0); -+ i++; -+ } -+ conf->pkt_filter_del.count = i; -+ printf("%s: pkt_filter_del id = ", __FUNCTION__); -+ for (i=0; ipkt_filter_del.count; i++) -+ printf("%d ", conf->pkt_filter_del.id[i]); -+ printf("\n"); -+ } -+ else if (!strncmp("magic_pkt_filter_add=", full_param, len_param)) { -+ pick_tmp = data; -+ pch = bcmstrtok(&pick_tmp, ",.-", 0); -+ i=0; -+ while (pch != NULL && imagic_pkt_filter_add.filter[i][0], pch); -+ printf("%s: magic_pkt_filter_add[%d][] = %s\n", __FUNCTION__, i, &conf->magic_pkt_filter_add.filter[i][0]); -+ pch = bcmstrtok(&pick_tmp, ",.-", 0); -+ i++; -+ } -+ conf->magic_pkt_filter_add.count = i; -+ } -+ else -+ return false; -+ -+ return true; -+} -+#endif -+ -+#ifdef IAPSTA_PREINIT -+/* -+ * iapsta_init=mode [sta|ap|apsta|dualap] vifname [wlan1] -+ * iapsta_config=ifname [wlan0|wlan1] ssid [xxx] chan [x] -+ hidden [y|n] maxassoc [x] -+ amode [open|shared|wpapsk|wpa2psk|wpawpa2psk] -+ emode [none|wep|tkip|aes|tkipaes] -+ key [xxxxx] -+ * iapsta_enable=ifname [wlan0|wlan1] -+*/ -+bool -+dhd_conf_read_iapsta(dhd_pub_t *dhd, char *full_param, uint len_param) -+{ -+ struct dhd_conf *conf = dhd->conf; -+ char *data = full_param+len_param; -+ -+ if (!strncmp("iapsta_init=", full_param, len_param)) { -+ sprintf(conf->iapsta_init, "iapsta_init %s", data); -+ printf("%s: iapsta_init=%s\n", __FUNCTION__, conf->iapsta_init); -+ } -+ else if (!strncmp("iapsta_config=", full_param, len_param)) { -+ sprintf(conf->iapsta_config, "iapsta_config %s", data); -+ printf("%s: iapsta_config=%s\n", __FUNCTION__, conf->iapsta_config); -+ } -+ else if (!strncmp("iapsta_enable=", full_param, len_param)) { -+ sprintf(conf->iapsta_enable, "iapsta_enable %s", data); -+ printf("%s: iapsta_enable=%s\n", __FUNCTION__, conf->iapsta_enable); -+ } -+ else -+ return false; -+ -+ return true; -+} -+#endif -+ -+#ifdef IDHCPC -+bool -+dhd_conf_read_dhcp_params(dhd_pub_t *dhd, char *full_param, uint len_param) -+{ -+ struct dhd_conf *conf = dhd->conf; -+ char *data = full_param+len_param; -+ -+ if (!strncmp("dhcpc_enable=", full_param, len_param)) { -+ conf->dhcpc_enable = (int)simple_strtol(data, NULL, 10); -+ printf("%s: dhcpc_enable = %d\n", __FUNCTION__, conf->dhcpc_enable); -+ } -+ else -+ return false; -+ -+ return true; -+} -+#endif -+ -+#ifdef BCMSDIO -+bool -+dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param) -+{ -+ struct dhd_conf *conf = dhd->conf; -+ char *data = full_param+len_param; -+ -+ if (!strncmp("dhd_doflow=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ dhd_doflow = FALSE; -+ else -+ dhd_doflow = TRUE; -+ printf("%s: dhd_doflow = %d\n", __FUNCTION__, dhd_doflow); -+ } -+ else if (!strncmp("dhd_slpauto=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ dhd_slpauto = FALSE; -+ else -+ dhd_slpauto = TRUE; -+ printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto); -+ } -+ else if (!strncmp("kso_enable=", full_param, len_param)) { -+ if (!strncmp(data, "1", 1)) -+ dhd_slpauto = FALSE; -+ else -+ dhd_slpauto = TRUE; -+ printf("%s: dhd_slpauto = %d\n", __FUNCTION__, dhd_slpauto); -+ } -+ else if (!strncmp("bus:txglom=", full_param, len_param)) { -+ conf->bus_txglom = (int)simple_strtol(data, NULL, 10); -+ printf("%s: bus:txglom = %d\n", __FUNCTION__, conf->bus_txglom); -+ } -+ else if (!strncmp("use_rxchain=", full_param, len_param)) { -+ conf->use_rxchain = (int)simple_strtol(data, NULL, 10); -+ printf("%s: use_rxchain = %d\n", __FUNCTION__, conf->use_rxchain); -+ } -+ else if (!strncmp("dhd_txminmax=", full_param, len_param)) { -+ conf->dhd_txminmax = (uint)simple_strtol(data, NULL, 10); -+ printf("%s: dhd_txminmax = %d\n", __FUNCTION__, conf->dhd_txminmax); -+ } -+ else if (!strncmp("txinrx_thres=", full_param, len_param)) { -+ conf->txinrx_thres = (int)simple_strtol(data, NULL, 10); -+ printf("%s: txinrx_thres = %d\n", __FUNCTION__, conf->txinrx_thres); -+ } -+ else if (!strncmp("sd_f2_blocksize=", full_param, len_param)) { -+ conf->sd_f2_blocksize = (int)simple_strtol(data, NULL, 10); -+ printf("%s: sd_f2_blocksize = %d\n", __FUNCTION__, conf->sd_f2_blocksize); -+ } -+ else if (!strncmp("oob_enabled_later=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ conf->oob_enabled_later = FALSE; -+ else -+ conf->oob_enabled_later = TRUE; -+ printf("%s: oob_enabled_later = %d\n", __FUNCTION__, conf->oob_enabled_later); -+ } -+#if defined(BCMSDIOH_TXGLOM) -+ else if (!strncmp("txglomsize=", full_param, len_param)) { -+ conf->txglomsize = (uint)simple_strtol(data, NULL, 10); -+ if (conf->txglomsize > SDPCM_MAXGLOM_SIZE) -+ conf->txglomsize = SDPCM_MAXGLOM_SIZE; -+ printf("%s: txglomsize = %d\n", __FUNCTION__, conf->txglomsize); -+ } -+ else if (!strncmp("swtxglom=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ conf->swtxglom = FALSE; -+ else -+ conf->swtxglom = TRUE; -+ printf("%s: swtxglom = %d\n", __FUNCTION__, conf->swtxglom); -+ } -+ else if (!strncmp("txglom_ext=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ conf->txglom_ext = FALSE; -+ else -+ conf->txglom_ext = TRUE; -+ printf("%s: txglom_ext = %d\n", __FUNCTION__, conf->txglom_ext); -+ if (conf->txglom_ext) { -+ if ((conf->chip == BCM43362_CHIP_ID) || (conf->chip == BCM4330_CHIP_ID)) -+ conf->txglom_bucket_size = 1680; -+ else if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || -+ conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) -+ conf->txglom_bucket_size = 1684; -+ } -+ printf("%s: txglom_bucket_size = %d\n", __FUNCTION__, conf->txglom_bucket_size); -+ } -+ else if (!strncmp("bus:rxglom=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ conf->bus_rxglom = FALSE; -+ else -+ conf->bus_rxglom = TRUE; -+ printf("%s: bus:rxglom = %d\n", __FUNCTION__, conf->bus_rxglom); -+ } -+ else if (!strncmp("dhd_poll=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ conf->dhd_poll = 0; -+ else -+ conf->dhd_poll = 1; -+ printf("%s: dhd_poll = %d\n", __FUNCTION__, conf->dhd_poll); -+ } -+ else if (!strncmp("deferred_tx_len=", full_param, len_param)) { -+ conf->deferred_tx_len = (int)simple_strtol(data, NULL, 10); -+ printf("%s: deferred_tx_len = %d\n", __FUNCTION__, conf->deferred_tx_len); -+ } -+ else if (!strncmp("txctl_tmo_fix=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ conf->txctl_tmo_fix = FALSE; -+ else -+ conf->txctl_tmo_fix = TRUE; -+ printf("%s: txctl_tmo_fix = %d\n", __FUNCTION__, conf->txctl_tmo_fix); -+ } -+ else if (!strncmp("tx_in_rx=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ conf->tx_in_rx = FALSE; -+ else -+ conf->tx_in_rx = TRUE; -+ printf("%s: tx_in_rx = %d\n", __FUNCTION__, conf->tx_in_rx); -+ } -+ else if (!strncmp("tx_max_offset=", full_param, len_param)) { -+ conf->tx_max_offset = (int)simple_strtol(data, NULL, 10); -+ printf("%s: tx_max_offset = %d\n", __FUNCTION__, conf->tx_max_offset); -+ } -+ else if (!strncmp("txglom_mode=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ conf->txglom_mode = FALSE; -+ else -+ conf->txglom_mode = TRUE; -+ printf("%s: txglom_mode = %d\n", __FUNCTION__, conf->txglom_mode); -+ } -+#endif -+ else -+ return false; -+ -+ return true; -+} -+#endif -+ -+bool -+dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param) -+{ -+ struct dhd_conf *conf = dhd->conf; -+ char *data = full_param+len_param; -+ -+ if (!strncmp("lpc=", full_param, len_param)) { -+ conf->lpc = (int)simple_strtol(data, NULL, 10); -+ printf("%s: lpc = %d\n", __FUNCTION__, conf->lpc); -+ } -+ else if (!strncmp("deepsleep=", full_param, len_param)) { -+ if (!strncmp(data, "1", 1)) -+ conf->deepsleep = TRUE; -+ else -+ conf->deepsleep = FALSE; -+ printf("%s: deepsleep = %d\n", __FUNCTION__, conf->deepsleep); -+ } -+ else if (!strncmp("PM=", full_param, len_param)) { -+ conf->pm = (int)simple_strtol(data, NULL, 10); -+ printf("%s: PM = %d\n", __FUNCTION__, conf->pm); -+ } -+ else if (!strncmp("pm_in_suspend=", full_param, len_param)) { -+ conf->pm_in_suspend = (int)simple_strtol(data, NULL, 10); -+ printf("%s: pm_in_suspend = %d\n", __FUNCTION__, conf->pm_in_suspend); -+ } -+ else if (!strncmp("pm2_sleep_ret=", full_param, len_param)) { -+ conf->pm2_sleep_ret = (int)simple_strtol(data, NULL, 10); -+ printf("%s: pm2_sleep_ret = %d\n", __FUNCTION__, conf->pm2_sleep_ret); -+ } -+ else if (!strncmp("xmit_in_suspend=", full_param, len_param)) { -+ if (!strncmp(data, "1", 1)) -+ conf->xmit_in_suspend = TRUE; -+ else -+ conf->xmit_in_suspend = FALSE; -+ printf("%s: xmit_in_suspend = %d\n", __FUNCTION__, conf->xmit_in_suspend); -+ } -+ else -+ return false; -+ -+ return true; -+} -+ -+bool -+dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param) -+{ -+ struct dhd_conf *conf = dhd->conf; -+ char *data = full_param+len_param; -+ uint len_data = strlen(data); -+ char *pch, *pick_tmp; -+ int i; -+ -+ if (!strncmp("band=", full_param, len_param)) { -+ /* Process band: -+ * band=a for 5GHz only and band=b for 2.4GHz only -+ */ -+ if (!strcmp(data, "b")) -+ conf->band = WLC_BAND_2G; -+ else if (!strcmp(data, "a")) -+ conf->band = WLC_BAND_5G; -+ else -+ conf->band = WLC_BAND_AUTO; -+ printf("%s: band = %d\n", __FUNCTION__, conf->band); -+ } -+ else if (!strncmp("mimo_bw_cap=", full_param, len_param)) { -+ conf->mimo_bw_cap = (uint)simple_strtol(data, NULL, 10); -+ printf("%s: mimo_bw_cap = %d\n", __FUNCTION__, conf->mimo_bw_cap); -+ } -+ else if (!strncmp("bw_cap_2g=", full_param, len_param)) { -+ conf->bw_cap_2g = (uint)simple_strtol(data, NULL, 0); -+ printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_2g); -+ } -+ else if (!strncmp("bw_cap_5g=", full_param, len_param)) { -+ conf->bw_cap_5g = (uint)simple_strtol(data, NULL, 0); -+ printf("%s: bw_cap_2g = %d\n", __FUNCTION__, conf->bw_cap_5g); -+ } -+ else if (!strncmp("ccode=", full_param, len_param)) { -+ memset(&conf->cspec, 0, sizeof(wl_country_t)); -+ memcpy(conf->cspec.country_abbrev, data, len_data); -+ memcpy(conf->cspec.ccode, data, len_data); -+ printf("%s: ccode = %s\n", __FUNCTION__, conf->cspec.ccode); -+ } -+ else if (!strncmp("regrev=", full_param, len_param)) { -+ conf->cspec.rev = (int32)simple_strtol(data, NULL, 10); -+ printf("%s: regrev = %d\n", __FUNCTION__, conf->cspec.rev); -+ } -+ else if (!strncmp("channels=", full_param, len_param)) { -+ pick_tmp = data; -+ pch = bcmstrtok(&pick_tmp, " ,.-", 0); -+ i=0; -+ while (pch != NULL && ichannels.channel[i] = (uint32)simple_strtol(pch, NULL, 10); -+ pch = bcmstrtok(&pick_tmp, " ,.-", 0); -+ i++; -+ } -+ conf->channels.count = i; -+ printf("%s: channels = ", __FUNCTION__); -+ for (i=0; ichannels.count; i++) -+ printf("%d ", conf->channels.channel[i]); -+ printf("\n"); -+ } -+ else if (!strncmp("keep_alive_period=", full_param, len_param)) { -+ conf->keep_alive_period = (uint)simple_strtol(data, NULL, 10); -+ printf("%s: keep_alive_period = %d\n", __FUNCTION__, -+ conf->keep_alive_period); -+ } -+ else if (!strncmp("stbc=", full_param, len_param)) { -+ conf->stbc = (int)simple_strtol(data, NULL, 10); -+ printf("%s: stbc = %d\n", __FUNCTION__, conf->stbc); -+ } -+ else if (!strncmp("phy_oclscdenable=", full_param, len_param)) { -+ conf->phy_oclscdenable = (int)simple_strtol(data, NULL, 10); -+ printf("%s: phy_oclscdenable = %d\n", __FUNCTION__, conf->phy_oclscdenable); -+ } -+ else if (!strncmp("srl=", full_param, len_param)) { -+ conf->srl = (int)simple_strtol(data, NULL, 10); -+ printf("%s: srl = %d\n", __FUNCTION__, conf->srl); -+ } -+ else if (!strncmp("lrl=", full_param, len_param)) { -+ conf->lrl = (int)simple_strtol(data, NULL, 10); -+ printf("%s: lrl = %d\n", __FUNCTION__, conf->lrl); -+ } -+ else if (!strncmp("bcn_timeout=", full_param, len_param)) { -+ conf->bcn_timeout= (uint)simple_strtol(data, NULL, 10); -+ printf("%s: bcn_timeout = %d\n", __FUNCTION__, conf->bcn_timeout); -+ } -+ else if (!strncmp("ampdu_ba_wsize=", full_param, len_param)) { -+ conf->ampdu_ba_wsize = (int)simple_strtol(data, NULL, 10); -+ printf("%s: ampdu_ba_wsize = %d\n", __FUNCTION__, conf->ampdu_ba_wsize); -+ } -+ else if (!strncmp("ampdu_hostreorder=", full_param, len_param)) { -+ conf->ampdu_hostreorder = (int)simple_strtol(data, NULL, 10); -+ printf("%s: ampdu_hostreorder = %d\n", __FUNCTION__, conf->ampdu_hostreorder); -+ } -+ else if (!strncmp("spect=", full_param, len_param)) { -+ conf->spect = (int)simple_strtol(data, NULL, 10); -+ printf("%s: spect = %d\n", __FUNCTION__, conf->spect); -+ } -+ else if (!strncmp("txbf=", full_param, len_param)) { -+ conf->txbf = (int)simple_strtol(data, NULL, 10); -+ printf("%s: txbf = %d\n", __FUNCTION__, conf->txbf); -+ } -+ else if (!strncmp("frameburst=", full_param, len_param)) { -+ conf->frameburst = (int)simple_strtol(data, NULL, 10); -+ printf("%s: frameburst = %d\n", __FUNCTION__, conf->frameburst); -+ } -+ else if (!strncmp("disable_proptx=", full_param, len_param)) { -+ conf->disable_proptx = (int)simple_strtol(data, NULL, 10); -+ printf("%s: disable_proptx = %d\n", __FUNCTION__, conf->disable_proptx); -+ } -+#ifdef DHDTCPACK_SUPPRESS -+ else if (!strncmp("tcpack_sup_mode=", full_param, len_param)) { -+ conf->tcpack_sup_mode = (uint)simple_strtol(data, NULL, 10); -+ printf("%s: tcpack_sup_mode = %d\n", __FUNCTION__, conf->tcpack_sup_mode); -+ } -+#endif -+ else if (!strncmp("pktprio8021x=", full_param, len_param)) { -+ conf->pktprio8021x = (int)simple_strtol(data, NULL, 10); -+ printf("%s: pktprio8021x = %d\n", __FUNCTION__, conf->pktprio8021x); -+ } -+ else if (!strncmp("dhd_txbound=", full_param, len_param)) { -+ dhd_txbound = (uint)simple_strtol(data, NULL, 10); -+ printf("%s: dhd_txbound = %d\n", __FUNCTION__, dhd_txbound); -+ } -+ else if (!strncmp("dhd_rxbound=", full_param, len_param)) { -+ dhd_rxbound = (uint)simple_strtol(data, NULL, 10); -+ printf("%s: dhd_rxbound = %d\n", __FUNCTION__, dhd_rxbound); -+ } -+ else if (!strncmp("rsdb_mode=", full_param, len_param)) { -+ conf->rsdb_mode = (int)simple_strtol(data, NULL, 10); -+ printf("%s: rsdb_mode = %d\n", __FUNCTION__, conf->rsdb_mode); -+ } -+ else if (!strncmp("vhtmode=", full_param, len_param)) { -+ if (!strncmp(data, "0", 1)) -+ conf->vhtmode = 0; -+ else -+ conf->vhtmode = 1; -+ printf("%s: vhtmode = %d\n", __FUNCTION__, conf->vhtmode); -+ } -+ else if (!strncmp("num_different_channels=", full_param, len_param)) { -+ conf->num_different_channels = (int)simple_strtol(data, NULL, 10); -+ printf("%s: num_different_channels = %d\n", __FUNCTION__, conf->num_different_channels); -+ } -+ else if (!strncmp("autocountry=", full_param, len_param)) { -+ conf->autocountry = (int)simple_strtol(data, NULL, 10); -+ printf("%s: autocountry = %d\n", __FUNCTION__, conf->autocountry); -+ } -+ else if (!strncmp("tsq=", full_param, len_param)) { -+ conf->tsq = (int)simple_strtol(data, NULL, 10); -+ printf("%s: tsq = %d\n", __FUNCTION__, conf->tsq); -+ } -+ else -+ return false; -+ -+ return true; -+} -+ -+int -+dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path) -+{ -+ int bcmerror = -1; -+ uint len, start_pos=0; -+ void * image = NULL; -+ char * memblock = NULL; -+ char *bufp, *pick = NULL, *pch; -+ bool conf_file_exists; -+ uint len_param; -+ -+ conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0')); -+ if (!conf_file_exists) { -+ printf("%s: config path %s\n", __FUNCTION__, conf_path); -+ return (0); -+ } -+ -+ if (conf_file_exists) { -+ image = dhd_os_open_image(conf_path); -+ if (image == NULL) { -+ printf("%s: Ignore config file %s\n", __FUNCTION__, conf_path); -+ goto err; -+ } -+ } -+ -+ memblock = MALLOC(dhd->osh, MAXSZ_CONFIG); -+ if (memblock == NULL) { -+ CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n", -+ __FUNCTION__, MAXSZ_CONFIG)); -+ goto err; -+ } -+ -+ pick = MALLOC(dhd->osh, MAXSZ_BUF); -+ if (!pick) { -+ CONFIG_ERROR(("%s: Failed to allocate memory %d bytes\n", -+ __FUNCTION__, MAXSZ_BUF)); -+ goto err; -+ } -+ -+ /* Read variables */ -+ if (conf_file_exists) { -+ len = dhd_os_get_image_block(memblock, MAXSZ_CONFIG, image); -+ } -+ if (len > 0 && len < MAXSZ_CONFIG) { -+ bufp = (char *)memblock; -+ bufp[len] = 0; -+ -+ while (start_pos < len) { -+ memset(pick, 0, MAXSZ_BUF); -+ start_pos = pick_config_vars(bufp, len, start_pos, pick); -+ pch = strchr(pick, '='); -+ if (pch != NULL) { -+ len_param = pch-pick+1; -+ if (len_param == strlen(pick)) { -+ CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick)); -+ continue; -+ } -+ } else { -+ CONFIG_ERROR(("%s: not a right parameter %s\n", __FUNCTION__, pick)); -+ continue; -+ } -+ -+ if (dhd_conf_read_log_level(dhd, pick, len_param)) -+ continue; -+ else if (dhd_conf_read_roam_params(dhd, pick, len_param)) -+ continue; -+ else if (dhd_conf_read_wme_ac_params(dhd, pick, len_param)) -+ continue; -+ else if (dhd_conf_read_fw_by_mac(dhd, pick, len_param)) -+ continue; -+ else if (dhd_conf_read_nv_by_mac(dhd, pick, len_param)) -+ continue; -+ else if (dhd_conf_read_nv_by_chip(dhd, pick, len_param)) -+ continue; -+ else if (dhd_conf_read_country_list(dhd, pick, len_param)) -+ continue; -+#ifdef PKT_FILTER_SUPPORT -+ else if (dhd_conf_read_pkt_filter(dhd, pick, len_param)) -+ continue; -+#endif /* PKT_FILTER_SUPPORT */ -+#ifdef IAPSTA_PREINIT -+ else if (dhd_conf_read_iapsta(dhd, pick, len_param)) -+ continue; -+#endif /* IAPSTA_PREINIT */ -+#ifdef IDHCPC -+ else if (dhd_conf_read_dhcp_params(dhd, pick, len_param)) -+ continue; -+#endif /* IDHCPC */ -+#ifdef BCMSDIO -+ else if (dhd_conf_read_sdio_params(dhd, pick, len_param)) -+ continue; -+#endif /* BCMSDIO */ -+ else if (dhd_conf_read_pm_params(dhd, pick, len_param)) -+ continue; -+ else if (dhd_conf_read_others(dhd, pick, len_param)) -+ continue; - else -- continue; -- } -- -- bcmerror = 0; -- } else { -- CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len)); -- bcmerror = BCME_SDIO_ERROR; -- } -- --err: -- if (pick) -- MFREE(dhd->osh, pick, MAXSZ_BUF); -- -- if (memblock) -- MFREE(dhd->osh, memblock, MAXSZ_CONFIG); -- -- if (image) -- dhd_os_close_image(image); -- -- return bcmerror; --} -- --int --dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev) --{ -- printf("%s: chip=0x%x, chiprev=%d\n", __FUNCTION__, chip, chiprev); -- dhd->conf->chip = chip; -- dhd->conf->chiprev = chiprev; -- return 0; --} -- --uint --dhd_conf_get_chip(void *context) --{ -- dhd_pub_t *dhd = context; -- -- if (dhd && dhd->conf) -- return dhd->conf->chip; -- return 0; --} -- --uint --dhd_conf_get_chiprev(void *context) --{ -- dhd_pub_t *dhd = context; -- -- if (dhd && dhd->conf) -- return dhd->conf->chiprev; -- return 0; --} -- --#ifdef BCMSDIO --void --dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable) --{ -- struct dhd_conf *conf = dhd->conf; -- -- if (enable) { --#if defined(SWTXGLOM) -- if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || -- conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || -- conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { -- // 43362/4330/4334/43340/43341/43241 must use 1.88.45.x swtxglom if txglom_ext is true, since 1.201.59 not support swtxglom -- conf->swtxglom = TRUE; -- conf->txglom_ext = TRUE; -- } -- if (conf->chip == BCM43362_CHIP_ID && conf->bus_txglom == 0) { -- conf->bus_txglom = 1; // improve tcp tx tput. and cpu idle for 43362 only -- } --#elif defined(BCMSDIOH_TXGLOM_EXT) -- if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || -- conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || -- conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { -- conf->txglom_mode = SDPCM_TXGLOM_CPY; -- } --#endif -- // other parameters set in preinit or config.txt -- } else { -- // clear txglom parameters, but don't change swtxglom since it's possible enabled in config.txt -- conf->txglom_ext = FALSE; -- conf->txglom_bucket_size = 0; -- conf->txglomsize = 0; -- conf->deferred_tx_len = 0; -- } -- printf("%s: swtxglom=%d, txglom_ext=%d, txglom_bucket_size=%d\n", __FUNCTION__, -- conf->swtxglom, conf->txglom_ext, conf->txglom_bucket_size); -- printf("%s: txglomsize=%d, deferred_tx_len=%d, bus_txglom=%d\n", __FUNCTION__, -- conf->txglomsize, conf->deferred_tx_len, conf->bus_txglom); -- printf("%s: tx_in_rx=%d, txinrx_thres=%d, dhd_txminmax=%d\n", __FUNCTION__, -- conf->tx_in_rx, conf->txinrx_thres, conf->dhd_txminmax); -- printf("%s: tx_max_offset=%d, txctl_tmo_fix=%d\n", __FUNCTION__, -- conf->tx_max_offset, conf->txctl_tmo_fix); -- --} --#endif -- --int --dhd_conf_preinit(dhd_pub_t *dhd) --{ -- struct dhd_conf *conf = dhd->conf; -- -- CONFIG_TRACE(("%s: Enter\n", __FUNCTION__)); -- --#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 -- memset(&conf->country_list, 0, sizeof(conf_country_list_t)); -- conf->band = WLC_BAND_AUTO; -- conf->mimo_bw_cap = -1; -- conf->bw_cap_2g = -1; -- conf->bw_cap_5g = -1; -- if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) { -- strcpy(conf->cspec.country_abbrev, "ALL"); -- strcpy(conf->cspec.ccode, "ALL"); -- conf->cspec.rev = 0; -- } else if (conf->chip == BCM4335_CHIP_ID || conf->chip == BCM4339_CHIP_ID || -- conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID || -- conf->chip == BCM4345_CHIP_ID || conf->chip == BCM4371_CHIP_ID || -- conf->chip == BCM43569_CHIP_ID || conf->chip == BCM4359_CHIP_ID) { -- strcpy(conf->cspec.country_abbrev, "CN"); -- strcpy(conf->cspec.ccode, "CN"); -- conf->cspec.rev = 38; -- } else { -- strcpy(conf->cspec.country_abbrev, "CN"); -- strcpy(conf->cspec.ccode, "CN"); -- conf->cspec.rev = 0; -- } -- memset(&conf->channels, 0, sizeof(wl_channel_list_t)); -- conf->roam_off = 1; -- conf->roam_off_suspend = 1; --#ifdef CUSTOM_ROAM_TRIGGER_SETTING -- conf->roam_trigger[0] = CUSTOM_ROAM_TRIGGER_SETTING; --#else -- conf->roam_trigger[0] = -65; --#endif -- conf->roam_trigger[1] = WLC_BAND_ALL; -- conf->roam_scan_period[0] = 10; -- conf->roam_scan_period[1] = WLC_BAND_ALL; --#ifdef CUSTOM_ROAM_DELTA_SETTING -- conf->roam_delta[0] = CUSTOM_ROAM_DELTA_SETTING; --#else -- conf->roam_delta[0] = 15; --#endif -- conf->roam_delta[1] = WLC_BAND_ALL; -+ continue; -+ } -+ -+ bcmerror = 0; -+ } else { -+ CONFIG_ERROR(("%s: error reading config file: %d\n", __FUNCTION__, len)); -+ bcmerror = BCME_SDIO_ERROR; -+ } -+ -+err: -+ if (pick) -+ MFREE(dhd->osh, pick, MAXSZ_BUF); -+ -+ if (memblock) -+ MFREE(dhd->osh, memblock, MAXSZ_CONFIG); -+ -+ if (image) -+ dhd_os_close_image(image); -+ -+ return bcmerror; -+} -+ -+int -+dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev) -+{ -+ printf("%s: chip=0x%x, chiprev=%d\n", __FUNCTION__, chip, chiprev); -+ dhd->conf->chip = chip; -+ dhd->conf->chiprev = chiprev; -+ return 0; -+} -+ -+uint -+dhd_conf_get_chip(void *context) -+{ -+ dhd_pub_t *dhd = context; -+ -+ if (dhd && dhd->conf) -+ return dhd->conf->chip; -+ return 0; -+} -+ -+uint -+dhd_conf_get_chiprev(void *context) -+{ -+ dhd_pub_t *dhd = context; -+ -+ if (dhd && dhd->conf) -+ return dhd->conf->chiprev; -+ return 0; -+} -+ -+#ifdef BCMSDIO -+void -+dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable) -+{ -+ struct dhd_conf *conf = dhd->conf; -+ -+ if (enable) { -+#if defined(SWTXGLOM) -+ if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || -+ conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || -+ conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { -+ // 43362/4330/4334/43340/43341/43241 must use 1.88.45.x swtxglom if txglom_ext is true, since 1.201.59 not support swtxglom -+ conf->swtxglom = TRUE; -+ conf->txglom_ext = TRUE; -+ } -+ if (conf->chip == BCM43362_CHIP_ID && conf->bus_txglom == 0) { -+ conf->bus_txglom = 1; // improve tcp tx tput. and cpu idle for 43362 only -+ } -+#elif defined(BCMSDIOH_TXGLOM_EXT) -+ if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || -+ conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || -+ conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { -+ conf->txglom_mode = SDPCM_TXGLOM_CPY; -+ } -+#endif -+ // other parameters set in preinit or config.txt -+ } else { -+ // clear txglom parameters, but don't change swtxglom since it's possible enabled in config.txt -+ conf->txglom_ext = FALSE; -+ conf->txglom_bucket_size = 0; -+ conf->txglomsize = 0; -+ conf->deferred_tx_len = 0; -+ } -+ printf("%s: swtxglom=%d, txglom_ext=%d, txglom_bucket_size=%d\n", __FUNCTION__, -+ conf->swtxglom, conf->txglom_ext, conf->txglom_bucket_size); -+ printf("%s: txglomsize=%d, deferred_tx_len=%d, bus_txglom=%d\n", __FUNCTION__, -+ conf->txglomsize, conf->deferred_tx_len, conf->bus_txglom); -+ printf("%s: tx_in_rx=%d, txinrx_thres=%d, dhd_txminmax=%d\n", __FUNCTION__, -+ conf->tx_in_rx, conf->txinrx_thres, conf->dhd_txminmax); -+ printf("%s: tx_max_offset=%d, txctl_tmo_fix=%d\n", __FUNCTION__, -+ conf->tx_max_offset, conf->txctl_tmo_fix); -+ -+} -+#endif -+ -+int -+dhd_conf_preinit(dhd_pub_t *dhd) -+{ -+ struct dhd_conf *conf = dhd->conf; -+ -+ CONFIG_TRACE(("%s: Enter\n", __FUNCTION__)); -+ -+#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 -+ memset(&conf->country_list, 0, sizeof(conf_country_list_t)); -+ conf->band = WLC_BAND_AUTO; -+ conf->mimo_bw_cap = -1; -+ conf->bw_cap_2g = -1; -+ conf->bw_cap_5g = -1; -+ if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) { -+ strcpy(conf->cspec.country_abbrev, "ALL"); -+ strcpy(conf->cspec.ccode, "ALL"); -+ conf->cspec.rev = 0; -+ } else if (conf->chip == BCM4335_CHIP_ID || conf->chip == BCM4339_CHIP_ID || -+ conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID || -+ conf->chip == BCM4345_CHIP_ID || conf->chip == BCM4371_CHIP_ID || -+ conf->chip == BCM43569_CHIP_ID || conf->chip == BCM4359_CHIP_ID) { -+ strcpy(conf->cspec.country_abbrev, "CN"); -+ strcpy(conf->cspec.ccode, "CN"); -+ conf->cspec.rev = 38; -+ } else { -+ strcpy(conf->cspec.country_abbrev, "CN"); -+ strcpy(conf->cspec.ccode, "CN"); -+ conf->cspec.rev = 0; -+ } -+ memset(&conf->channels, 0, sizeof(wl_channel_list_t)); -+ conf->roam_off = 1; -+ conf->roam_off_suspend = 1; -+#ifdef CUSTOM_ROAM_TRIGGER_SETTING -+ conf->roam_trigger[0] = CUSTOM_ROAM_TRIGGER_SETTING; -+#else -+ conf->roam_trigger[0] = -65; -+#endif -+ conf->roam_trigger[1] = WLC_BAND_ALL; -+ conf->roam_scan_period[0] = 10; -+ conf->roam_scan_period[1] = WLC_BAND_ALL; -+#ifdef CUSTOM_ROAM_DELTA_SETTING -+ conf->roam_delta[0] = CUSTOM_ROAM_DELTA_SETTING; -+#else -+ conf->roam_delta[0] = 15; -+#endif -+ conf->roam_delta[1] = WLC_BAND_ALL; - #ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC -- conf->fullroamperiod = 60; -+ conf->fullroamperiod = 60; - #else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ -- conf->fullroamperiod = 120; --#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ --#ifdef CUSTOM_KEEP_ALIVE_SETTING -- conf->keep_alive_period = CUSTOM_KEEP_ALIVE_SETTING; --#else -- conf->keep_alive_period = 28000; --#endif -- conf->force_wme_ac = 0; -- memset(&conf->wme_sta, 0, sizeof(wme_param_t)); -- memset(&conf->wme_ap, 0, sizeof(wme_param_t)); -- conf->stbc = -1; -- conf->phy_oclscdenable = -1; --#ifdef PKT_FILTER_SUPPORT -- memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t)); -- memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t)); -- memset(&conf->magic_pkt_filter_add, 0, sizeof(conf_pkt_filter_del_t)); --#endif -- conf->srl = -1; -- conf->lrl = -1; -- conf->bcn_timeout = 15; -- conf->spect = -1; -- conf->txbf = -1; -- conf->lpc = -1; -- conf->disable_proptx = -1; --#ifdef BCMSDIO -- conf->bus_txglom = -1; -- conf->use_rxchain = 0; -- conf->bus_rxglom = TRUE; -- conf->txglom_ext = FALSE; -- conf->tx_max_offset = 0; -- conf->txglomsize = SDPCM_DEFGLOM_SIZE; -- conf->dhd_poll = -1; -- conf->txctl_tmo_fix = FALSE; -- conf->tx_in_rx = TRUE; -- conf->txglom_mode = SDPCM_TXGLOM_MDESC; -- conf->deferred_tx_len = 0; -- conf->dhd_txminmax = 1; -- conf->txinrx_thres = -1; -- conf->sd_f2_blocksize = 0; -- conf->oob_enabled_later = FALSE; --#endif -- conf->ampdu_ba_wsize = 0; -- conf->ampdu_hostreorder = -1; -- conf->dpc_cpucore = -1; -- conf->rxf_cpucore = -1; -- conf->frameburst = -1; -- conf->deepsleep = FALSE; -- conf->pm = -1; -- conf->pm_in_suspend = -1; -- conf->pm2_sleep_ret = -1; -- conf->num_different_channels = -1; -- conf->xmit_in_suspend = TRUE; --#ifdef IDHCPC -- conf->dhcpc_enable = -1; --#endif -- conf->tsq = 0; -+ conf->fullroamperiod = 120; -+#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */ -+#ifdef CUSTOM_KEEP_ALIVE_SETTING -+ conf->keep_alive_period = CUSTOM_KEEP_ALIVE_SETTING; -+#else -+ conf->keep_alive_period = 28000; -+#endif -+ conf->force_wme_ac = 0; -+ memset(&conf->wme_sta, 0, sizeof(wme_param_t)); -+ memset(&conf->wme_ap, 0, sizeof(wme_param_t)); -+ conf->stbc = -1; -+ conf->phy_oclscdenable = -1; -+#ifdef PKT_FILTER_SUPPORT -+ memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t)); -+ memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t)); -+ memset(&conf->magic_pkt_filter_add, 0, sizeof(conf_pkt_filter_del_t)); -+#endif -+ conf->srl = -1; -+ conf->lrl = -1; -+ conf->bcn_timeout = 15; -+ conf->spect = -1; -+ conf->txbf = -1; -+ conf->lpc = -1; -+ conf->disable_proptx = -1; -+#ifdef BCMSDIO -+ conf->bus_txglom = -1; -+ conf->use_rxchain = 0; -+ conf->bus_rxglom = TRUE; -+ conf->txglom_ext = FALSE; -+ conf->tx_max_offset = 0; -+ conf->txglomsize = SDPCM_DEFGLOM_SIZE; -+ conf->dhd_poll = -1; -+ conf->txctl_tmo_fix = FALSE; -+ conf->tx_in_rx = TRUE; -+ conf->txglom_mode = SDPCM_TXGLOM_MDESC; -+ conf->deferred_tx_len = 0; -+ conf->dhd_txminmax = 1; -+ conf->txinrx_thres = -1; -+ conf->sd_f2_blocksize = 0; -+ conf->oob_enabled_later = FALSE; -+#endif -+ conf->ampdu_ba_wsize = 0; -+ conf->ampdu_hostreorder = -1; -+ conf->dpc_cpucore = -1; -+ conf->rxf_cpucore = -1; -+ conf->frameburst = -1; -+ conf->deepsleep = FALSE; -+ conf->pm = -1; -+ conf->pm_in_suspend = -1; -+ conf->pm2_sleep_ret = -1; -+ conf->num_different_channels = -1; -+ conf->xmit_in_suspend = TRUE; -+#ifdef IDHCPC -+ conf->dhcpc_enable = -1; -+#endif -+ conf->tsq = 0; -+#ifdef DHDTCPACK_SUPPRESS -+ conf->tcpack_sup_mode = TCPACK_SUP_OFF; -+#endif -+ conf->pktprio8021x = -1; -+ conf->rsdb_mode = -2; -+ conf->vhtmode = -1; -+ conf->autocountry = -1; -+#ifdef IAPSTA_PREINIT -+ memset(conf->iapsta_init, 0, sizeof(conf->iapsta_init)); -+ memset(conf->iapsta_config, 0, sizeof(conf->iapsta_config)); -+ memset(conf->iapsta_enable, 0, sizeof(conf->iapsta_enable)); -+#endif -+#ifdef BCMSDIO -+ if (conf->chip == BCM43430_CHIP_ID || conf->chip == BCM4345_CHIP_ID) { -+ conf->txctl_tmo_fix = 1; -+ } -+#endif -+ if (conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID || -+ conf->chip == BCM4371_CHIP_ID || conf->chip == BCM43569_CHIP_ID || -+ conf->chip == BCM4359_CHIP_ID) { - #ifdef DHDTCPACK_SUPPRESS -- conf->tcpack_sup_mode = TCPACK_SUP_OFF; --#endif -- conf->pktprio8021x = -1; -- conf->rsdb_mode = -2; -- conf->vhtmode = -1; -- conf->autocountry = -1; --#ifdef IAPSTA_PREINIT -- memset(conf->iapsta_init, 0, sizeof(conf->iapsta_init)); -- memset(conf->iapsta_config, 0, sizeof(conf->iapsta_config)); -- memset(conf->iapsta_enable, 0, sizeof(conf->iapsta_enable)); --#endif --#ifdef BCMSDIO -- if (conf->chip == BCM43430_CHIP_ID || conf->chip == BCM4345_CHIP_ID) { -- conf->txctl_tmo_fix = 1; -- } --#endif -- if (conf->chip == BCM4354_CHIP_ID || conf->chip == BCM4356_CHIP_ID || -- conf->chip == BCM4371_CHIP_ID || conf->chip == BCM43569_CHIP_ID || -- conf->chip == BCM4359_CHIP_ID) { --#ifdef DHDTCPACK_SUPPRESS -- conf->tcpack_sup_mode = TCPACK_SUP_REPLACE; --#endif -- dhd_rxbound = 64; -- dhd_txbound = 64; -- conf->txbf = 1; -- conf->frameburst = 1; --#ifdef BCMSDIO -- conf->dhd_txminmax = -1; -- conf->txinrx_thres = 128; -- conf->sd_f2_blocksize = 256; -- conf->oob_enabled_later = TRUE; --#endif -- } -- --#ifdef BCMSDIO --#if defined(SWTXGLOM) -- if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || -- conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || -- conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { -- conf->swtxglom = FALSE; // disabled by default -- conf->txglom_ext = TRUE; // enabled by default -- conf->use_rxchain = 0; // use_rxchain have been disabled if swtxglom enabled -- conf->txglomsize = 16; -- } else { -- conf->swtxglom = FALSE; // use 1.201.59.x txglom by default -- conf->txglom_ext = FALSE; -- } -- -- if (conf->chip == BCM43362_CHIP_ID) { -- conf->txglom_bucket_size = 1680; // fixed value, don't change -- conf->tx_in_rx = FALSE; -- conf->tx_max_offset = 1; -- } -- if (conf->chip == BCM4330_CHIP_ID) { -- conf->txglom_bucket_size = 1680; // fixed value, don't change -- conf->tx_in_rx = FALSE; -- conf->tx_max_offset = 0; -- } -- if (conf->chip == BCM4334_CHIP_ID) { -- conf->txglom_bucket_size = 1684; // fixed value, don't change -- conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle -- conf->tx_max_offset = 0; // reduce udp tx: dhdsdio_readframes: got unlikely tx max 109 with tx_seq 110 -- } -- if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID) { -- conf->txglom_bucket_size = 1684; // fixed value, don't change -- conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle -- conf->tx_max_offset = 1; -- } -- if (conf->chip == BCM4324_CHIP_ID) { -- conf->txglom_bucket_size = 1684; // fixed value, don't change -- conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle -- conf->tx_max_offset = 0; -- } --#endif --#if defined(BCMSDIOH_TXGLOM_EXT) -- if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || -- conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || -- conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { -- conf->txglom_ext = TRUE; -- conf->use_rxchain = 0; -- conf->tx_in_rx = TRUE; -- conf->tx_max_offset = 1; -- } else { -- conf->txglom_ext = FALSE; -- } -- if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) { -- conf->txglom_bucket_size = 1680; // fixed value, don't change -- conf->txglomsize = 6; -- } -- if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID || -- conf->chip == BCM43341_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { -- conf->txglom_bucket_size = 1684; // fixed value, don't change -- conf->txglomsize = 16; -- } --#endif -- if (conf->txglomsize > SDPCM_MAXGLOM_SIZE) -- conf->txglomsize = SDPCM_MAXGLOM_SIZE; -- conf->deferred_tx_len = conf->txglomsize; --#endif -- -- return 0; --} -- --int --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; --} -- --int --dhd_conf_attach(dhd_pub_t *dhd) --{ -- dhd_conf_t *conf; -- -- CONFIG_TRACE(("%s: Enter\n", __FUNCTION__)); -- -- if (dhd->conf != NULL) { -- printf("%s: config is attached before!\n", __FUNCTION__); -- return 0; -- } -- /* Allocate private bus interface state */ -- if (!(conf = MALLOC(dhd->osh, sizeof(dhd_conf_t)))) { -- CONFIG_ERROR(("%s: MALLOC failed\n", __FUNCTION__)); -- goto fail; -- } -- memset(conf, 0, sizeof(dhd_conf_t)); -- -- dhd->conf = conf; -- -- return 0; -- --fail: -- if (conf != NULL) -- MFREE(dhd->osh, conf, sizeof(dhd_conf_t)); -- return BCME_NOMEM; --} -- --void --dhd_conf_detach(dhd_pub_t *dhd) --{ -- CONFIG_TRACE(("%s: Enter\n", __FUNCTION__)); -- -- if (dhd->conf) { --#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)); -- } -- dhd->conf = NULL; --} -+ conf->tcpack_sup_mode = TCPACK_SUP_REPLACE; -+#endif -+ dhd_rxbound = 64; -+ dhd_txbound = 64; -+ conf->txbf = 1; -+ conf->frameburst = 1; -+#ifdef BCMSDIO -+ conf->dhd_txminmax = -1; -+ conf->txinrx_thres = 128; -+ conf->sd_f2_blocksize = 256; -+ conf->oob_enabled_later = TRUE; -+#endif -+ } -+ -+#ifdef BCMSDIO -+#if defined(SWTXGLOM) -+ if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || -+ conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || -+ conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { -+ conf->swtxglom = FALSE; // disabled by default -+ conf->txglom_ext = TRUE; // enabled by default -+ conf->use_rxchain = 0; // use_rxchain have been disabled if swtxglom enabled -+ conf->txglomsize = 16; -+ } else { -+ conf->swtxglom = FALSE; // use 1.201.59.x txglom by default -+ conf->txglom_ext = FALSE; -+ } -+ -+ if (conf->chip == BCM43362_CHIP_ID) { -+ conf->txglom_bucket_size = 1680; // fixed value, don't change -+ conf->tx_in_rx = FALSE; -+ conf->tx_max_offset = 1; -+ } -+ if (conf->chip == BCM4330_CHIP_ID) { -+ conf->txglom_bucket_size = 1680; // fixed value, don't change -+ conf->tx_in_rx = FALSE; -+ conf->tx_max_offset = 0; -+ } -+ if (conf->chip == BCM4334_CHIP_ID) { -+ conf->txglom_bucket_size = 1684; // fixed value, don't change -+ conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle -+ conf->tx_max_offset = 0; // reduce udp tx: dhdsdio_readframes: got unlikely tx max 109 with tx_seq 110 -+ } -+ if (conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID) { -+ conf->txglom_bucket_size = 1684; // fixed value, don't change -+ conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle -+ conf->tx_max_offset = 1; -+ } -+ if (conf->chip == BCM4324_CHIP_ID) { -+ conf->txglom_bucket_size = 1684; // fixed value, don't change -+ conf->tx_in_rx = TRUE; // improve tcp tx tput. and cpu idle -+ conf->tx_max_offset = 0; -+ } -+#endif -+#if defined(BCMSDIOH_TXGLOM_EXT) -+ if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID || -+ conf->chip == BCM43340_CHIP_ID || conf->chip == BCM43341_CHIP_ID || -+ conf->chip == BCM4334_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { -+ conf->txglom_ext = TRUE; -+ conf->use_rxchain = 0; -+ conf->tx_in_rx = TRUE; -+ conf->tx_max_offset = 1; -+ } else { -+ conf->txglom_ext = FALSE; -+ } -+ if (conf->chip == BCM43362_CHIP_ID || conf->chip == BCM4330_CHIP_ID) { -+ conf->txglom_bucket_size = 1680; // fixed value, don't change -+ conf->txglomsize = 6; -+ } -+ if (conf->chip == BCM4334_CHIP_ID || conf->chip == BCM43340_CHIP_ID || -+ conf->chip == BCM43341_CHIP_ID || conf->chip == BCM4324_CHIP_ID) { -+ conf->txglom_bucket_size = 1684; // fixed value, don't change -+ conf->txglomsize = 16; -+ } -+#endif -+ if (conf->txglomsize > SDPCM_MAXGLOM_SIZE) -+ conf->txglomsize = SDPCM_MAXGLOM_SIZE; -+ conf->deferred_tx_len = 0; -+#endif -+ -+ return 0; -+} -+ -+int -+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; -+} -+ -+int -+dhd_conf_attach(dhd_pub_t *dhd) -+{ -+ dhd_conf_t *conf; -+ -+ CONFIG_TRACE(("%s: Enter\n", __FUNCTION__)); -+ -+ if (dhd->conf != NULL) { -+ printf("%s: config is attached before!\n", __FUNCTION__); -+ return 0; -+ } -+ /* Allocate private bus interface state */ -+ if (!(conf = MALLOC(dhd->osh, sizeof(dhd_conf_t)))) { -+ CONFIG_ERROR(("%s: MALLOC failed\n", __FUNCTION__)); -+ goto fail; -+ } -+ memset(conf, 0, sizeof(dhd_conf_t)); -+ -+ dhd->conf = conf; -+ -+ return 0; -+ -+fail: -+ if (conf != NULL) -+ MFREE(dhd->osh, conf, sizeof(dhd_conf_t)); -+ return BCME_NOMEM; -+} -+ -+void -+dhd_conf_detach(dhd_pub_t *dhd) -+{ -+ CONFIG_TRACE(("%s: Enter\n", __FUNCTION__)); -+ -+ if (dhd->conf) { -+#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)); -+ } -+ dhd->conf = NULL; -+} diff --git a/bcmdhd.1.363.59.144.x.cn/dhd_config.h b/bcmdhd.1.363.59.144.x.cn/dhd_config.h index 750a283..4d02895 100644 --- a/bcmdhd.1.363.59.144.x.cn/dhd_config.h +++ b/bcmdhd.1.363.59.144.x.cn/dhd_config.h @@ -1,258 +1,254 @@ - -#ifndef _dhd_config_ -#define _dhd_config_ - -#include -#include -#include -#include -#include - -#define FW_PATH_AUTO_SELECT 1 -//#define CONFIG_PATH_AUTO_SELECT -extern char firmware_path[MOD_PARAM_PATHLEN]; + +#ifndef _dhd_config_ +#define _dhd_config_ + +#include +#include +#include +#include +#include + +#define FW_PATH_AUTO_SELECT 1 +//#define CONFIG_PATH_AUTO_SELECT +extern char firmware_path[MOD_PARAM_PATHLEN]; extern uint dhd_rxbound; -extern uint dhd_txbound; -#ifdef BCMSDIO -#define TXGLOM_RECV_OFFSET 8 -extern uint dhd_doflow; -extern uint dhd_slpauto; - -#define BCM43362A0_CHIP_REV 0 -#define BCM43362A2_CHIP_REV 1 -#define BCM43430A0_CHIP_REV 0 -#define BCM43430A1_CHIP_REV 1 -#define BCM43430A2_CHIP_REV 2 -#define BCM43012B0_CHIP_REV 1 -#define BCM4330B2_CHIP_REV 4 -#define BCM4334B1_CHIP_REV 3 -#define BCM43341B0_CHIP_REV 2 -#define BCM43241B4_CHIP_REV 5 -#define BCM4335A0_CHIP_REV 2 -#define BCM4339A0_CHIP_REV 1 -#define BCM43455C0_CHIP_REV 6 -#define BCM43455C5_CHIP_REV 9 -#define BCM4354A1_CHIP_REV 1 -#define BCM4359B1_CHIP_REV 5 -#define BCM4359C0_CHIP_REV 9 -#endif -#define BCM4356A2_CHIP_REV 2 -#define BCM4358A3_CHIP_REV 3 - -/* mac range */ -typedef struct wl_mac_range { - uint32 oui; - uint32 nic_start; - uint32 nic_end; -} wl_mac_range_t; - -/* mac list */ -typedef struct wl_mac_list { - int count; - wl_mac_range_t *mac; - char name[MOD_PARAM_PATHLEN]; /* path */ -} wl_mac_list_t; - -/* mac list head */ -typedef struct wl_mac_list_ctrl { - int count; - 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 */ - uint32 count; - /* variable length channel list */ - uint32 channel[WL_NUMCHANNELS]; -} wl_channel_list_t; - -typedef struct wmes_param { - int aifsn[AC_COUNT]; - int ecwmin[AC_COUNT]; - int ecwmax[AC_COUNT]; - int txop[AC_COUNT]; -} wme_param_t; - -#ifdef PKT_FILTER_SUPPORT -#define DHD_CONF_FILTER_MAX 8 -/* filter list */ -#define PKT_FILTER_LEN 300 -typedef struct conf_pkt_filter_add { - /* in - # of channels, out - # of entries */ - uint32 count; - /* variable length filter list */ - char filter[DHD_CONF_FILTER_MAX][PKT_FILTER_LEN]; -} conf_pkt_filter_add_t; - -/* pkt_filter_del list */ -typedef struct conf_pkt_filter_del { - /* in - # of channels, out - # of entries */ - uint32 count; - /* variable length filter list */ - uint32 id[DHD_CONF_FILTER_MAX]; -} conf_pkt_filter_del_t; -#endif - -#define CONFIG_COUNTRY_LIST_SIZE 100 -/* country list */ -typedef struct conf_country_list { - uint32 count; - wl_country_t cspec[CONFIG_COUNTRY_LIST_SIZE]; -} conf_country_list_t; - -typedef struct dhd_conf { - uint chip; /* chip number */ - 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 */ - conf_country_list_t country_list; /* Country list */ - int band; /* Band, b:2.4G only, otherwise for auto */ - int mimo_bw_cap; /* Bandwidth, 0:HT20ALL, 1: HT40ALL, 2:HT20IN2G_HT40PIN5G */ - int bw_cap_2g; /* Bandwidth, 1:20MHz, 3: 20/40MHz, 7:20/40/80MHz */ - int bw_cap_5g; /* Bandwidth, 1:20MHz, 3: 20/40MHz, 7:20/40/80MHz */ - wl_country_t cspec; /* Country */ - wl_channel_list_t channels; /* Support channels */ - uint roam_off; /* Roaming, 0:enable, 1:disable */ - uint roam_off_suspend; /* Roaming in suspend, 0:enable, 1:disable */ - int roam_trigger[2]; /* The RSSI threshold to trigger roaming */ - int roam_scan_period[2]; /* Roaming scan period */ - int roam_delta[2]; /* Roaming candidate qualification delta */ - int fullroamperiod; /* Full Roaming period */ - uint keep_alive_period; /* The perioid in ms to send keep alive packet */ - int force_wme_ac; - wme_param_t wme_sta; /* WME parameters */ - wme_param_t wme_ap; /* WME parameters */ - int stbc; /* STBC for Tx/Rx */ - int phy_oclscdenable; /* phy_oclscdenable */ -#ifdef PKT_FILTER_SUPPORT - conf_pkt_filter_add_t pkt_filter_add; /* Packet filter add */ - conf_pkt_filter_del_t pkt_filter_del; /* Packet filter add */ - conf_pkt_filter_add_t magic_pkt_filter_add; /* Magic Packet filter add */ -#endif - int srl; /* short retry limit */ - int lrl; /* long retry limit */ - uint bcn_timeout; /* beacon timeout */ - int spect; - int txbf; - int lpc; - int disable_proptx; -#ifdef BCMSDIO - int bus_txglom; /* bus:txglom */ - int use_rxchain; - bool bus_rxglom; /* bus:rxglom */ +extern uint dhd_txbound; +#ifdef BCMSDIO +#define TXGLOM_RECV_OFFSET 8 +extern uint dhd_doflow; +extern uint dhd_slpauto; + +#define BCM43362A0_CHIP_REV 0 +#define BCM43362A2_CHIP_REV 1 +#define BCM43430A0_CHIP_REV 0 +#define BCM43430A1_CHIP_REV 1 +#define BCM43430A2_CHIP_REV 2 +#define BCM43012B0_CHIP_REV 1 +#define BCM4330B2_CHIP_REV 4 +#define BCM4334B1_CHIP_REV 3 +#define BCM43341B0_CHIP_REV 2 +#define BCM43241B4_CHIP_REV 5 +#define BCM4335A0_CHIP_REV 2 +#define BCM4339A0_CHIP_REV 1 +#define BCM43455C0_CHIP_REV 6 +#define BCM43456C5_CHIP_REV 9 +#define BCM4354A1_CHIP_REV 1 +#define BCM4359B1_CHIP_REV 5 +#define BCM4359C0_CHIP_REV 9 +#endif +#define BCM4356A2_CHIP_REV 2 +#define BCM4358A3_CHIP_REV 3 + +typedef struct wl_mac_range { + uint32 oui; + uint32 nic_start; + uint32 nic_end; +} wl_mac_range_t; + +typedef struct wl_mac_list { + int count; + wl_mac_range_t *mac; + char name[MOD_PARAM_PATHLEN]; +} wl_mac_list_t; + +typedef struct wl_mac_list_ctrl { + int count; + struct wl_mac_list *m_mac_list_head; +} wl_mac_list_ctrl_t; + +typedef struct wl_chip_nv_path { + uint chip; + uint chiprev; + char name[MOD_PARAM_PATHLEN]; +} wl_chip_nv_path_t; + +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; + +typedef struct wl_channel_list { + uint32 count; + uint32 channel[WL_NUMCHANNELS]; +} wl_channel_list_t; + +typedef struct wmes_param { + int aifsn[AC_COUNT]; + int ecwmin[AC_COUNT]; + int ecwmax[AC_COUNT]; + int txop[AC_COUNT]; +} wme_param_t; + +#ifdef PKT_FILTER_SUPPORT +#define DHD_CONF_FILTER_MAX 8 +#define PKT_FILTER_LEN 300 +typedef struct conf_pkt_filter_add { + uint32 count; + char filter[DHD_CONF_FILTER_MAX][PKT_FILTER_LEN]; +} conf_pkt_filter_add_t; + +typedef struct conf_pkt_filter_del { + uint32 count; + uint32 id[DHD_CONF_FILTER_MAX]; +} conf_pkt_filter_del_t; +#endif + +#define CONFIG_COUNTRY_LIST_SIZE 100 +typedef struct conf_country_list { + uint32 count; + wl_country_t cspec[CONFIG_COUNTRY_LIST_SIZE]; +} conf_country_list_t; + +typedef struct dhd_conf { + uint chip; + uint chiprev; + wl_mac_list_ctrl_t fw_by_mac; + wl_mac_list_ctrl_t nv_by_mac; + wl_chip_nv_path_list_ctrl_t nv_by_chip; + conf_country_list_t country_list; + int band; + int mimo_bw_cap; + int bw_cap_2g; + int bw_cap_5g; + wl_country_t cspec; + wl_channel_list_t channels; + uint roam_off; + uint roam_off_suspend; + int roam_trigger[2]; + int roam_scan_period[2]; + int roam_delta[2]; + int fullroamperiod; + uint keep_alive_period; + int force_wme_ac; + wme_param_t wme_sta; + wme_param_t wme_ap; + int stbc; + int phy_oclscdenable; +#ifdef PKT_FILTER_SUPPORT + conf_pkt_filter_add_t pkt_filter_add; + conf_pkt_filter_del_t pkt_filter_del; + conf_pkt_filter_add_t magic_pkt_filter_add; +#endif + int srl; + int lrl; + uint bcn_timeout; + int spect; + int txbf; + int lpc; + int disable_proptx; +#ifdef BCMSDIO + int bus_txglom; + int use_rxchain; + bool bus_rxglom; bool txglom_ext; /* Only for 43362/4330/43340/43341/43241 */ - /* terence 20161011: - 1) conf->tx_max_offset = 1 to fix credict issue in adaptivity testing - 2) conf->tx_max_offset = 1 will cause to UDP Tx not work in rxglom supported, - but not happened in sw txglom - */ - int tx_max_offset; - uint txglomsize; - int dhd_poll; - /* terence 20161011: conf->txctl_tmo_fix = 1 to fix for "sched: RT throttling activated, " - this issue happened in tx tput. and tx cmd at the same time in inband interrupt mode - */ - bool txctl_tmo_fix; - bool tx_in_rx; // Skip tx before rx, in order to get more glomed in tx - bool txglom_mode; - uint deferred_tx_len; - bool swtxglom; /* SW TXGLOM */ + /* terence 20161011: + 1) conf->tx_max_offset = 1 to fix credict issue in adaptivity testing + 2) conf->tx_max_offset = 1 will cause to UDP Tx not work in rxglom supported, + but not happened in sw txglom + */ + int tx_max_offset; + uint txglomsize; + int dhd_poll; + bool txctl_tmo_fix; + bool tx_in_rx; + bool txglom_mode; + uint deferred_tx_len; + bool swtxglom; /* SW TXGLOM */ /*txglom_bucket_size: * 43362/4330: 1680 * 43340/43341/43241: 1684 - */ - int txglom_bucket_size; - int txinrx_thres; - int dhd_txminmax; // -1=DATABUFCNT(bus) - uint sd_f2_blocksize; - bool oob_enabled_later; -#endif - int ampdu_ba_wsize; - int ampdu_hostreorder; - int dpc_cpucore; - int rxf_cpucore; - int frameburst; - bool deepsleep; - int pm; - int pm_in_suspend; - int pm2_sleep_ret; -#ifdef DHDTCPACK_SUPPRESS - uint8 tcpack_sup_mode; -#endif - int pktprio8021x; - int rsdb_mode; - int vhtmode; - int num_different_channels; - int xmit_in_suspend; -#ifdef IDHCPC - int dhcpc_enable; -#endif -#ifdef IAPSTA_PREINIT - char iapsta_init[50]; - char iapsta_config[300]; - char iapsta_enable[50]; -#endif - int autocountry; - int tsq; -} dhd_conf_t; - -#ifdef BCMSDIO -int dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac); -void dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path); -void dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path); -#if defined(HW_OOB) || defined(FORCE_WOWLAN) -void dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip); -#endif -void dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable); -#endif -void dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path); -void dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path); -void dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path); -void dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path); -#ifdef CONFIG_PATH_AUTO_SELECT -void dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path); -#endif -int dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val, int def, bool down); -int dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx); -uint dhd_conf_get_band(dhd_pub_t *dhd); -int dhd_conf_set_country(dhd_pub_t *dhd); -int dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec); -int dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec); -int dhd_conf_fix_country(dhd_pub_t *dhd); -bool dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel); -int dhd_conf_set_roam(dhd_pub_t *dhd); -void dhd_conf_set_bw_cap(dhd_pub_t *dhd); -void dhd_conf_set_wme(dhd_pub_t *dhd, int mode); -void dhd_conf_add_pkt_filter(dhd_pub_t *dhd); -bool dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id); -void dhd_conf_discard_pkt_filter(dhd_pub_t *dhd); -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(dhd_pub_t *dhd); -#ifdef PROP_TXSTATUS -int dhd_conf_get_disable_proptx(dhd_pub_t *dhd); -#endif -int dhd_conf_preinit(dhd_pub_t *dhd); -int dhd_conf_reset(dhd_pub_t *dhd); -int dhd_conf_attach(dhd_pub_t *dhd); -void dhd_conf_detach(dhd_pub_t *dhd); -void *dhd_get_pub(struct net_device *dev); -void *dhd_get_conf(struct net_device *dev); -#endif /* _dhd_config_ */ + */ + int txglom_bucket_size; + int txinrx_thres; + int dhd_txminmax; // -1=DATABUFCNT(bus) + uint sd_f2_blocksize; + bool oob_enabled_later; +#endif + int ampdu_ba_wsize; + int ampdu_hostreorder; + int dpc_cpucore; + int rxf_cpucore; + int frameburst; + bool deepsleep; + int pm; + int pm_in_suspend; + int pm2_sleep_ret; +#ifdef DHDTCPACK_SUPPRESS + uint8 tcpack_sup_mode; +#endif + int pktprio8021x; + int rsdb_mode; + int vhtmode; + int num_different_channels; + int xmit_in_suspend; + int ap_in_suspend; +#ifdef SUSPEND_EVENT + bool suspend_eventmask_enable; + char suspend_eventmask[WL_EVENTING_MASK_LEN]; + char resume_eventmask[WL_EVENTING_MASK_LEN]; +#endif +#ifdef IDHCP + int dhcpc_enable; + int dhcpd_enable; + struct ipv4_addr dhcpd_ip_addr; + struct ipv4_addr dhcpd_ip_mask; + struct ipv4_addr dhcpd_ip_start; + struct ipv4_addr dhcpd_ip_end; +#endif +#ifdef IAPSTA_PREINIT + char iapsta_init[50]; + char iapsta_config[300]; + char iapsta_enable[50]; +#endif + int autocountry; + int tsq; +} dhd_conf_t; + +#ifdef BCMSDIO +int dhd_conf_get_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, uint8 *mac); +void dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *fw_path); +void dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, bcmsdh_info_t *sdh, char *nv_path); +#if defined(HW_OOB) || defined(FORCE_WOWLAN) +void dhd_conf_set_hw_oob_intr(bcmsdh_info_t *sdh, uint chip); +#endif +void dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable); +#endif +void dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path); +void dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path); +void dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path); +void dhd_conf_set_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path); +#ifdef CONFIG_PATH_AUTO_SELECT +void dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path); +#endif +int dhd_conf_set_intiovar(dhd_pub_t *dhd, uint cmd, char *name, int val, int def, bool down); +int dhd_conf_get_iovar(dhd_pub_t *dhd, int cmd, char *name, char *buf, int len, int ifidx); +int dhd_conf_set_bufiovar(dhd_pub_t *dhd, uint cmd, char *name, char *buf, int len, bool down); +uint dhd_conf_get_band(dhd_pub_t *dhd); +int dhd_conf_set_country(dhd_pub_t *dhd); +int dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec); +int dhd_conf_get_country_from_config(dhd_pub_t *dhd, wl_country_t *cspec); +int dhd_conf_fix_country(dhd_pub_t *dhd); +bool dhd_conf_match_channel(dhd_pub_t *dhd, uint32 channel); +int dhd_conf_set_roam(dhd_pub_t *dhd); +void dhd_conf_set_bw_cap(dhd_pub_t *dhd); +void dhd_conf_set_wme(dhd_pub_t *dhd, int mode); +void dhd_conf_add_pkt_filter(dhd_pub_t *dhd); +bool dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id); +void dhd_conf_discard_pkt_filter(dhd_pub_t *dhd); +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(dhd_pub_t *dhd); +#ifdef PROP_TXSTATUS +int dhd_conf_get_disable_proptx(dhd_pub_t *dhd); +#endif +int dhd_conf_get_ap_mode_in_suspend(dhd_pub_t *dhd); +int dhd_conf_set_ap_in_suspend(dhd_pub_t *dhd, int suspend); +int dhd_conf_preinit(dhd_pub_t *dhd); +int dhd_conf_reset(dhd_pub_t *dhd); +int dhd_conf_attach(dhd_pub_t *dhd); +void dhd_conf_detach(dhd_pub_t *dhd); +void *dhd_get_pub(struct net_device *dev); +void *dhd_get_conf(struct net_device *dev); +#endif /* _dhd_config_ */ diff --git a/bcmdhd.1.363.59.144.x.cn/dhd_gpio.c b/bcmdhd.1.363.59.144.x.cn/dhd_gpio.c index db3b45d..8b9c665 100644 --- a/bcmdhd.1.363.59.144.x.cn/dhd_gpio.c +++ b/bcmdhd.1.363.59.144.x.cn/dhd_gpio.c @@ -175,6 +175,22 @@ static int dhd_wlan_get_mac_addr(unsigned char *buf) bcopy((char *)&ea_example, buf, sizeof(struct ether_addr)); } #endif /* EXAMPLE_GET_MAC */ +#ifdef EXAMPLE_GET_MAC_VER2 + /* EXAMPLE code */ + { + char mac[6] = {0x00,0x11,0x22,0x33,0x44,0xFF}; + char macpad[56]= { + 0x00,0xaa,0x9c,0x84,0xc7,0xbc,0x9b,0xf6, + 0x02,0x33,0xa9,0x4d,0x5c,0xb4,0x0a,0x5d, + 0xa8,0xef,0xb0,0xcf,0x8e,0xbf,0x24,0x8a, + 0x87,0x0f,0x6f,0x0d,0xeb,0x83,0x6a,0x70, + 0x4a,0xeb,0xf6,0xe6,0x3c,0xe7,0x5f,0xfc, + 0x0e,0xa7,0xb3,0x0f,0x00,0xe4,0x4a,0xaf, + 0x87,0x08,0x16,0x6d,0x3a,0xe3,0xc7,0x80}; + bcopy(mac, buf, sizeof(mac)); + bcopy(macpad, buf+6, sizeof(macpad)); + } +#endif /* EXAMPLE_GET_MAC_VER2 */ bcopy((char *)wifi_get_mac(), buf, sizeof(struct ether_addr)); if (buf[0] == 0xff) { printf("custom wifi mac is not set\n"); diff --git a/bcmdhd.1.363.59.144.x.cn/dhd_linux.c b/bcmdhd.1.363.59.144.x.cn/dhd_linux.c index 71bef8f..c04d185 100644 --- a/bcmdhd.1.363.59.144.x.cn/dhd_linux.c +++ b/bcmdhd.1.363.59.144.x.cn/dhd_linux.c @@ -821,11 +821,11 @@ module_param(dhd_watchdog_prio, int, 0); /* DPC thread priority */ int dhd_dpc_prio = CUSTOM_DPC_PRIO_SETTING; -module_param(dhd_dpc_prio, int, 0644); +module_param(dhd_dpc_prio, int, 0); /* RX frame thread priority */ int dhd_rxf_prio = CUSTOM_RXF_PRIO_SETTING; -module_param(dhd_rxf_prio, int, 0644); +module_param(dhd_rxf_prio, int, 0); int passive_channel_skip = 0; module_param(passive_channel_skip, int, (S_IRUSR|S_IWUSR)); @@ -2720,7 +2720,9 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) } #endif /* DYNAMIC_SWOOB_DURATION */ #endif /* DHD_USE_EARLYSUSPEND */ + dhd_conf_set_ap_in_suspend(dhd, value); } else { + dhd_conf_set_ap_in_suspend(dhd, value); #ifdef PKT_FILTER_SUPPORT dhd->early_suspended = 0; #endif @@ -2830,7 +2832,7 @@ static int dhd_suspend_resume_helper(struct dhd_info *dhd, int val, int force) /* Set flag when early suspend was called */ dhdp->in_suspend = val; if ((force || !dhdp->suspend_disable_flag) && - dhd_support_sta_mode(dhdp)) + (dhd_support_sta_mode(dhdp) || dhd_conf_get_ap_mode_in_suspend(dhdp))) { ret = dhd_set_suspend(val, dhdp); } @@ -4949,17 +4951,17 @@ dhd_dpc_thread(void *data) #ifdef CUSTOM_DPC_CPUCORE set_cpus_allowed_ptr(current, cpumask_of(CUSTOM_DPC_CPUCORE)); -#else - if (dhd->pub.conf->dpc_cpucore >= 0) { - printf("%s: set dpc_cpucore %d from config.txt\n", __FUNCTION__, dhd->pub.conf->dpc_cpucore); - set_cpus_allowed_ptr(current, cpumask_of(dhd->pub.conf->dpc_cpucore)); - } #endif #ifdef CUSTOM_SET_CPUCORE dhd->pub.current_dpc = current; #endif /* CUSTOM_SET_CPUCORE */ /* Run until signal received */ while (1) { + if (dhd->pub.conf->dpc_cpucore >= 0) { + printf("%s: set dpc_cpucore %d\n", __FUNCTION__, dhd->pub.conf->dpc_cpucore); + set_cpus_allowed_ptr(current, cpumask_of(dhd->pub.conf->dpc_cpucore)); + dhd->pub.conf->dpc_cpucore = -1; + } if (!binary_sema_down(tsk)) { #ifdef ENABLE_ADAPTIVE_SCHED dhd_sched_policy(dhd_dpc_prio); @@ -5030,11 +5032,6 @@ dhd_rxf_thread(void *data) #ifdef CUSTOM_RXF_CPUCORE /* change rxf thread to other cpu core */ set_cpus_allowed_ptr(current, cpumask_of(CUSTOM_RXF_CPUCORE)); -#else - if (dhd->pub.conf->rxf_cpucore >= 0) { - printf("%s: set rxf_cpucore %d from config.txt\n", __FUNCTION__, dhd->pub.conf->rxf_cpucore); - set_cpus_allowed_ptr(current, cpumask_of(dhd->pub.conf->rxf_cpucore)); - } #endif /* signal: thread has started */ @@ -5044,6 +5041,11 @@ dhd_rxf_thread(void *data) #endif /* CUSTOM_SET_CPUCORE */ /* Run until signal received */ while (1) { + if (dhd->pub.conf->rxf_cpucore >= 0) { + printf("%s: set rxf_cpucore %d\n", __FUNCTION__, dhd->pub.conf->rxf_cpucore); + set_cpus_allowed_ptr(current, cpumask_of(dhd->pub.conf->rxf_cpucore)); + dhd->pub.conf->rxf_cpucore = -1; + } if (down_interruptible(&tsk->sema) == 0) { void *skb; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) @@ -5758,13 +5760,11 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) if (is_compat_task()) #endif { - compat_wl_ioctl_t compat_ioc; if (copy_from_user(&compat_ioc, ifr->ifr_data, sizeof(compat_wl_ioctl_t))) { ret = BCME_BADADDR; goto done; } - ioc.cmd = compat_ioc.cmd; ioc.buf = (uint64 *)compat_ioc.buf; ioc.len = compat_ioc.len; @@ -7296,7 +7296,7 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) } #ifdef WL_ESCAN wl_escan_attach(net, (void *)&dhd->pub); -#endif +#endif /* WL_ESCAN */ #endif /* defined(WL_WIRELESS_EXT) */ #ifdef SHOW_LOGTRACE @@ -8260,6 +8260,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) #endif /* (defined(AP) || defined(WLP2P)) && !defined(SOFTAP_AND_GC) */ #ifdef GET_CUSTOM_MAC_ENABLE struct ether_addr ea_addr; + char hw_ether[62]; #endif /* GET_CUSTOM_MAC_ENABLE */ #ifdef DISABLE_11N @@ -8330,15 +8331,33 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) DHD_INFO(("%s : Set IOCTL response time.\n", __FUNCTION__)); } #ifdef GET_CUSTOM_MAC_ENABLE - ret = wifi_platform_get_mac_addr(dhd->info->adapter, ea_addr.octet); + ret = wifi_platform_get_mac_addr(dhd->info->adapter, hw_ether); if (!ret) { memset(buf, 0, sizeof(buf)); + bcopy(hw_ether, ea_addr.octet, sizeof(struct ether_addr)); bcm_mkiovar("cur_etheraddr", (void *)&ea_addr, ETHER_ADDR_LEN, buf, sizeof(buf)); ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0); if (ret < 0) { - DHD_ERROR(("%s: can't set MAC address MAC="MACDBG", error=%d\n", - __FUNCTION__, MAC2STRDBG(ea_addr.octet), ret)); + memset(buf, 0, sizeof(buf)); + bcm_mkiovar("hw_ether", hw_ether, sizeof(hw_ether), buf, sizeof(buf)); + ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0); + if (ret) { + int i; + DHD_ERROR(("%s: can't set MAC address MAC="MACDBG", error=%d\n", + __FUNCTION__, MAC2STRDBG(hw_ether), ret)); + for (i=0; iconf->lpc, 0, FALSE); + dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "lpc", dhd->conf->lpc, 0, TRUE); /* Set PowerSave mode */ if (dhd->conf->pm >= 0) @@ -8670,7 +8689,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); #endif /* defined(AP) && !defined(WLP2P) */ /* 0:HT20 in ALL, 1:HT40 in ALL, 2: HT20 in 2G HT40 in 5G */ - dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "mimo_bw_cap", dhd->conf->mimo_bw_cap, 1, TRUE); + dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "mimo_bw_cap", dhd->conf->mimo_bw_cap, 0, TRUE); dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "force_wme_ac", dhd->conf->force_wme_ac, 1, FALSE); dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "stbc_tx", dhd->conf->stbc, 0, FALSE); dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "stbc_rx", dhd->conf->stbc, 0, FALSE); @@ -8679,8 +8698,15 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) dhd_conf_set_intiovar(dhd, WLC_SET_SPECT_MANAGMENT, "WLC_SET_SPECT_MANAGMENT", dhd->conf->spect, 0, FALSE); dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "rsdb_mode", dhd->conf->rsdb_mode, -1, TRUE); dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "vhtmode", dhd->conf->vhtmode, 0, TRUE); -#ifdef IDHCPC +#ifdef IDHCP dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "dhcpc_enable", dhd->conf->dhcpc_enable, 0, FALSE); + if (dhd->conf->dhcpd_enable >= 0) { + dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "dhcpd_ip_addr", (char *)&dhd->conf->dhcpd_ip_addr, sizeof(dhd->conf->dhcpd_ip_addr), FALSE); + dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "dhcpd_ip_mask", (char *)&dhd->conf->dhcpd_ip_mask, sizeof(dhd->conf->dhcpd_ip_mask), FALSE); + dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "dhcpd_ip_start", (char *)&dhd->conf->dhcpd_ip_start, sizeof(dhd->conf->dhcpd_ip_start), FALSE); + dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "dhcpd_ip_end", (char *)&dhd->conf->dhcpd_ip_end, sizeof(dhd->conf->dhcpd_ip_end), FALSE); + dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "dhcpd_enable", dhd->conf->dhcpd_enable, 0, FALSE); + } #endif dhd_conf_set_bw_cap(dhd); @@ -8886,7 +8912,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) #endif /* WLTDLS */ #ifdef WL_ESCAN setbit(eventmask, WLC_E_ESCAN_RESULT); -#endif +#endif /* WL_ESCAN */ #ifdef WL_CFG80211 setbit(eventmask, WLC_E_ESCAN_RESULT); setbit(eventmask, WLC_E_AP_STARTED); @@ -8919,6 +8945,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) dhd_update_flow_prio_map(dhd, DHD_FLOW_PRIO_LLR_MAP); #endif /* defined(PCIE_FULL_DONGLE) && defined(DHD_LOSSLESS_ROAMING) */ +#ifdef SUSPEND_EVENT + bcopy(eventmask, dhd->conf->resume_eventmask, WL_EVENTING_MASK_LEN); +#endif /* Write updated Event mask */ bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) { @@ -9803,7 +9832,7 @@ void dhd_detach(dhd_pub_t *dhdp) } #ifdef WL_ESCAN wl_escan_detach(); -#endif +#endif /* WL_ESCAN */ #endif /* defined(WL_WIRELESS_EXT) */ /* delete all interfaces, start with virtual */ diff --git a/bcmdhd.1.363.59.144.x.cn/dhd_sdio.c b/bcmdhd.1.363.59.144.x.cn/dhd_sdio.c index a5059f9..b9b3512 100644 --- a/bcmdhd.1.363.59.144.x.cn/dhd_sdio.c +++ b/bcmdhd.1.363.59.144.x.cn/dhd_sdio.c @@ -936,7 +936,7 @@ dhdsdio_clk_kso_enab(dhd_bus_t *bus, bool on) uint8 wr_val = 0, rd_val, cmp_val, bmask; int err = 0; int try_cnt = 0; - return 0; + KSO_DBG(("%s> op:%s\n", __FUNCTION__, (on ? "KSO_SET" : "KSO_CLR"))); wr_val |= (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); diff --git a/bcmdhd.1.363.59.144.x.cn/dhd_static_buf.c b/bcmdhd.1.363.59.144.x.cn/dhd_static_buf.c index 36cca5b..42cef00 100644 --- a/bcmdhd.1.363.59.144.x.cn/dhd_static_buf.c +++ b/bcmdhd.1.363.59.144.x.cn/dhd_static_buf.c @@ -255,6 +255,7 @@ static int dhd_init_wlan_mem(void) pr_err("Failed to alloc wlan_static_if_flow_lkup\n"); goto err_mem_alloc; } + printk("%s: sectoin %d, size=%d\n", __FUNCTION__, DHD_PREALLOC_IF_FLOW_LKUP, DHD_PREALLOC_IF_FLOW_LKUP_SIZE); #endif /* CONFIG_BCMDHD_PCIE */ return 0; diff --git a/bcmdhd.1.363.59.144.x.cn/dhd_wlfc.c b/bcmdhd.1.363.59.144.x.cn/dhd_wlfc.c index 81cf51f..b790c8d 100644 --- a/bcmdhd.1.363.59.144.x.cn/dhd_wlfc.c +++ b/bcmdhd.1.363.59.144.x.cn/dhd_wlfc.c @@ -2812,7 +2812,11 @@ static void _dhd_wlfc_reorderinfo_indicate(uint8 *val, uint8 len, uchar *info_buf, uint *info_len) { if (info_len) { - if (info_buf) { + /* Check copy length to avoid buffer overrun. In case of length exceeding + * WLHOST_REORDERDATA_TOTLEN, return failure instead sending incomplete result + * of length WLHOST_REORDERDATA_TOTLEN + */ + if ((info_buf) && (len <= WLHOST_REORDERDATA_TOTLEN)) { bcopy(val, info_buf, len); *info_len = len; } else { diff --git a/bcmdhd.1.363.59.144.x.cn/include/epivers.h b/bcmdhd.1.363.59.144.x.cn/include/epivers.h index 931576e..dfa3aff 100644 --- a/bcmdhd.1.363.59.144.x.cn/include/epivers.h +++ b/bcmdhd.1.363.59.144.x.cn/include/epivers.h @@ -46,6 +46,6 @@ #define EPI_VERSION_DEV 1.363.59 /* Driver Version String, ASCII, 32 chars max */ -#define EPI_VERSION_STR "1.363.59.144.9 (r)" +#define EPI_VERSION_STR "1.363.59.144.10 (r)" #endif /* _epivers_h_ */ diff --git a/bcmdhd.1.363.59.144.x.cn/include/linux_osl.h b/bcmdhd.1.363.59.144.x.cn/include/linux_osl.h index 278fecf..d560fec 100644 --- a/bcmdhd.1.363.59.144.x.cn/include/linux_osl.h +++ b/bcmdhd.1.363.59.144.x.cn/include/linux_osl.h @@ -448,8 +448,6 @@ extern int osl_error(int bcmerror); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) && defined(TSQ_MULTIPLIER) #define PKTORPHAN(skb, tsq) osl_pkt_orphan_partial(skb, tsq) extern void osl_pkt_orphan_partial(struct sk_buff *skb, int tsq); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) -#define PKTORPHAN(skb, tsq) skb_orphan(skb, tsq) #else #define PKTORPHAN(skb, tsq) ({BCM_REFERENCE(skb); 0;}) #endif /* LINUX VERSION >= 3.6 */ diff --git a/bcmdhd.1.363.59.144.x.cn/include/wlioctl.h b/bcmdhd.1.363.59.144.x.cn/include/wlioctl.h index 001a261..a02faee 100644 --- a/bcmdhd.1.363.59.144.x.cn/include/wlioctl.h +++ b/bcmdhd.1.363.59.144.x.cn/include/wlioctl.h @@ -7998,6 +7998,15 @@ typedef enum { } ulb_bw_type_t; #endif /* WL11ULB */ +#ifdef MFP +/* values for IOV_MFP arg */ +enum { + WL_MFP_NONE = 0, + WL_MFP_CAPABLE, + WL_MFP_REQUIRED +}; +#endif /* MFP */ + #if defined(WLRCC) #define MAX_ROAM_CHANNEL 20 diff --git a/bcmdhd.1.363.59.144.x.cn/linux_osl.c b/bcmdhd.1.363.59.144.x.cn/linux_osl.c index d8dac6c..2b5ccbf 100644 --- a/bcmdhd.1.363.59.144.x.cn/linux_osl.c +++ b/bcmdhd.1.363.59.144.x.cn/linux_osl.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #if !defined(STBLINUX) @@ -465,7 +467,7 @@ int osl_static_mem_init(osl_t *osh, void *adapter) #ifdef CONFIG_DHD_USE_STATIC_BUF if (!bcm_static_buf && adapter) { if (!(bcm_static_buf = (bcm_static_buf_t *)wifi_platform_prealloc(adapter, - 3, STATIC_BUF_SIZE + STATIC_BUF_TOTAL_LEN))) { + DHD_PREALLOC_OSL_BUF, STATIC_BUF_SIZE + STATIC_BUF_TOTAL_LEN))) { printk("can not alloc static buf!\n"); bcm_static_skb = NULL; ASSERT(osh->magic == OS_HANDLE_MAGIC); @@ -484,7 +486,7 @@ int osl_static_mem_init(osl_t *osh, void *adapter) int i; void *skb_buff_ptr = 0; bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048); - skb_buff_ptr = wifi_platform_prealloc(adapter, 4, 0); + skb_buff_ptr = wifi_platform_prealloc(adapter, DHD_PREALLOC_SKB_BUF, 0); if (!skb_buff_ptr) { printk("cannot alloc static buf!\n"); bcm_static_buf = NULL; diff --git a/bcmdhd.1.363.59.144.x.cn/wl_android.c b/bcmdhd.1.363.59.144.x.cn/wl_android.c index 1961e6a..810f8f8 100644 --- a/bcmdhd.1.363.59.144.x.cn/wl_android.c +++ b/bcmdhd.1.363.59.144.x.cn/wl_android.c @@ -1653,6 +1653,7 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str, u8 *reqbuf = NULL; uint32 band = WLC_BAND_2G; uint32 buf_size; + char *pos = command; if (cmd_str) { ANDROID_INFO(("Command: %s len:%d \n", cmd_str, (int)strlen(cmd_str))); @@ -1734,7 +1735,7 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str, goto done2; } - buf_size = (band == WLC_BAND_AUTO) ? sizeof(int) : CHANSPEC_BUF_SIZE; + buf_size = CHANSPEC_BUF_SIZE; ret = wldev_ioctl(dev, WLC_START_CHANNEL_SEL, (void *)reqbuf, buf_size, true); if (ret < 0) { @@ -1764,6 +1765,18 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str, chosen = dtoh32(chosen); } + if ((ret == 0) && (dtoh32(chosen) != 0)) { + uint chip; + chip = dhd_conf_get_chip(dhd_get_pub(dev)); + if (chip != BCM43362_CHIP_ID && chip != BCM4330_CHIP_ID) { + u32 chanspec = 0; + chanspec = wl_chspec_driver_to_host(chosen); + ANDROID_INFO(("selected chanspec = 0x%x\n", chanspec)); + chosen = wf_chspec_ctlchan(chanspec); + ANDROID_INFO(("selected chosen = 0x%x\n", chosen)); + } + } + if (chosen) { int chosen_band; int apcs_band; @@ -1778,9 +1791,12 @@ wl_android_set_auto_channel(struct net_device *dev, const char* cmd_str, #endif /* D11AC_IOTYPES */ apcs_band = (band == WLC_BAND_AUTO) ? WLC_BAND_2G : band; chosen_band = (channel <= CH_MAX_2G_CHANNEL) ? WLC_BAND_2G : WLC_BAND_5G; - if (apcs_band == chosen_band) { + if (band == WLC_BAND_AUTO) { ANDROID_ERROR(("selected channel = %d\n", channel)); break; + } else if (apcs_band == chosen_band) { + printf("%s: selected channel = %d\n", __FUNCTION__, channel); + break; } } ANDROID_INFO(("%d tried, ret = %d, chosen = 0x%x\n", @@ -1810,7 +1826,11 @@ done2: } if (channel) { - snprintf(command, 4, "%d", channel); + if (channel < 15) + pos += snprintf(pos, total_len, "2g="); + else + pos += snprintf(pos, total_len, "5g="); + pos += snprintf(pos, total_len, "%d", channel); ANDROID_INFO(("command result is %s \n", command)); return strlen(command); } else { diff --git a/bcmdhd.1.363.59.144.x.cn/wl_android_ext.c b/bcmdhd.1.363.59.144.x.cn/wl_android_ext.c index cf40743..3fd2bfa 100644 --- a/bcmdhd.1.363.59.144.x.cn/wl_android_ext.c +++ b/bcmdhd.1.363.59.144.x.cn/wl_android_ext.c @@ -1,150 +1,150 @@ - - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define htod32(i) i -#define htod16(i) i -#define dtoh32(i) i -#define dtoh16(i) i -#define htodchanspec(i) i -#define dtohchanspec(i) i -#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) - -#define CMD_CHANNEL "CHANNEL" -#define CMD_CHANNELS "CHANNELS" -#define CMD_ROAM_TRIGGER "ROAM_TRIGGER" -#define CMD_KEEP_ALIVE "KEEP_ALIVE" -#define CMD_PM "PM" -#define CMD_MONITOR "MONITOR" -#define CMD_SET_SUSPEND_BCN_LI_DTIM "SET_SUSPEND_BCN_LI_DTIM" - -#ifdef WL_EXT_IAPSTA -#define CMD_IAPSTA_INIT "IAPSTA_INIT" -#define CMD_IAPSTA_CONFIG "IAPSTA_CONFIG" -#define CMD_IAPSTA_ENABLE "IAPSTA_ENABLE" -#define CMD_IAPSTA_DISABLE "IAPSTA_DISABLE" -#ifdef PROP_TXSTATUS -#ifdef PROP_TXSTATUS_VSDB -#include + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define htod32(i) i +#define htod16(i) i +#define dtoh32(i) i +#define dtoh16(i) i +#define htodchanspec(i) i +#define dtohchanspec(i) i +#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base)) + +#define CMD_CHANNEL "CHANNEL" +#define CMD_CHANNELS "CHANNELS" +#define CMD_ROAM_TRIGGER "ROAM_TRIGGER" +#define CMD_KEEP_ALIVE "KEEP_ALIVE" +#define CMD_PM "PM" +#define CMD_MONITOR "MONITOR" +#define CMD_SET_SUSPEND_BCN_LI_DTIM "SET_SUSPEND_BCN_LI_DTIM" + +#ifdef WL_EXT_IAPSTA +#define CMD_IAPSTA_INIT "IAPSTA_INIT" +#define CMD_IAPSTA_CONFIG "IAPSTA_CONFIG" +#define CMD_IAPSTA_ENABLE "IAPSTA_ENABLE" +#define CMD_IAPSTA_DISABLE "IAPSTA_DISABLE" +#ifdef PROP_TXSTATUS +#ifdef PROP_TXSTATUS_VSDB +#include extern int disable_proptx; -#endif /* PROP_TXSTATUS_VSDB */ -#endif -#endif -#ifdef IDHCPC -#define CMD_DHCPC_ENABLE "DHCPC_ENABLE" -#define CMD_DHCPC_DUMP "DHCPC_DUMP" -#endif -#define CMD_WL "WL" - -#define IEEE80211_BAND_2GHZ 0 -#define IEEE80211_BAND_5GHZ 1 - -int wl_ext_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set) -{ - int ret; - - ret = wldev_ioctl(dev, cmd, arg, len, set); - if (ret) - ANDROID_ERROR(("%s: cmd=%d ret=%d\n", __FUNCTION__, cmd, ret)); - return ret; -} - -int wl_ext_iovar_getint(struct net_device *dev, s8 *iovar, s32 *val) -{ - int ret; - - ret = wldev_iovar_getint(dev, iovar, val); - if (ret) - ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret)); - - return ret; -} - -int wl_ext_iovar_setint(struct net_device *dev, s8 *iovar, s32 val) -{ - int ret; - - ret = wldev_iovar_setint(dev, iovar, val); - if (ret) - ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret)); - - return ret; -} - -int wl_ext_iovar_getbuf(struct net_device *dev, s8 *iovar_name, - void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync) -{ - int ret; - - ret = wldev_iovar_getbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync); - if (ret != 0) - ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret)); - - return ret; -} - -int wl_ext_iovar_setbuf(struct net_device *dev, s8 *iovar_name, - void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync) -{ - int ret; - - ret = wldev_iovar_setbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync); - if (ret != 0) - ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret)); - - return ret; -} - -#ifdef WL_EXT_IAPSTA -int wl_ext_iovar_setbuf_bsscfg(struct net_device *dev, s8 *iovar_name, - void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync) -{ - int ret; - - ret = wldev_iovar_setbuf_bsscfg(dev, iovar_name, param, paramlen, - buf, buflen, bsscfg_idx, buf_sync); - if (ret < 0) - ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret)); - - return ret; -} - -int wl_ext_iovar_getbuf_bsscfg(struct net_device *dev, s8 *iovar_name, - void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync) -{ - int ret; - - ret = wldev_iovar_getbuf_bsscfg(dev, iovar_name, param, paramlen, - buf, buflen, bsscfg_idx, buf_sync); - if (ret < 0) - ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret)); - - return ret; -} -#endif +#endif /* PROP_TXSTATUS_VSDB */ +#endif +#endif +#ifdef IDHCP +#define CMD_DHCPC_ENABLE "DHCPC_ENABLE" +#define CMD_DHCPC_DUMP "DHCPC_DUMP" +#endif +#define CMD_WL "WL" + +#define IEEE80211_BAND_2GHZ 0 +#define IEEE80211_BAND_5GHZ 1 + +int wl_ext_ioctl(struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set) +{ + int ret; + + ret = wldev_ioctl(dev, cmd, arg, len, set); + if (ret) + ANDROID_ERROR(("%s: cmd=%d ret=%d\n", __FUNCTION__, cmd, ret)); + return ret; +} + +int wl_ext_iovar_getint(struct net_device *dev, s8 *iovar, s32 *val) +{ + int ret; + + ret = wldev_iovar_getint(dev, iovar, val); + if (ret) + ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret)); + + return ret; +} + +int wl_ext_iovar_setint(struct net_device *dev, s8 *iovar, s32 val) +{ + int ret; + + ret = wldev_iovar_setint(dev, iovar, val); + if (ret) + ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar, ret)); + + return ret; +} + +int wl_ext_iovar_getbuf(struct net_device *dev, s8 *iovar_name, + void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync) +{ + int ret; + + ret = wldev_iovar_getbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync); + if (ret != 0) + ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret)); + + return ret; +} + +int wl_ext_iovar_setbuf(struct net_device *dev, s8 *iovar_name, + void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync) +{ + int ret; + + ret = wldev_iovar_setbuf(dev, iovar_name, param, paramlen, buf, buflen, buf_sync); + if (ret != 0) + ANDROID_ERROR(("%s: iovar=%s, ret=%d\n", __FUNCTION__, iovar_name, ret)); + + return ret; +} + +#ifdef WL_EXT_IAPSTA +int wl_ext_iovar_setbuf_bsscfg(struct net_device *dev, s8 *iovar_name, + void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync) +{ + int ret; + + ret = wldev_iovar_setbuf_bsscfg(dev, iovar_name, param, paramlen, + buf, buflen, bsscfg_idx, buf_sync); + if (ret < 0) + ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret)); + + return ret; +} + +int wl_ext_iovar_getbuf_bsscfg(struct net_device *dev, s8 *iovar_name, + void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync) +{ + int ret; + + ret = wldev_iovar_getbuf_bsscfg(dev, iovar_name, param, paramlen, + buf, buflen, bsscfg_idx, buf_sync); + if (ret < 0) + ANDROID_ERROR(("%s: iovar_name=%s ret=%d\n", __FUNCTION__, iovar_name, ret)); + + return ret; +} +#endif /* Return a legacy chanspec given a new chanspec * Returns INVCHANSPEC on error */ static chanspec_t -wl_ext_chspec_to_legacy(chanspec_t chspec) +wl_ext_chspec_to_legacy(chanspec_t chspec) { chanspec_t lchspec; if (wf_chspec_malformed(chspec)) { - ANDROID_ERROR(("wl_ext_chspec_to_legacy: input chanspec (0x%04X) malformed\n", + ANDROID_ERROR(("wl_ext_chspec_to_legacy: input chanspec (0x%04X) malformed\n", chspec)); return INVCHANSPEC; } @@ -173,25 +173,25 @@ wl_ext_chspec_to_legacy(chanspec_t chspec) } else { /* cannot express the bandwidth */ char chanbuf[CHANSPEC_STR_LEN]; - ANDROID_ERROR(( - "wl_ext_chspec_to_legacy: unable to convert chanspec %s (0x%04X) " + ANDROID_ERROR(( + "wl_ext_chspec_to_legacy: unable to convert chanspec %s (0x%04X) " "to pre-11ac format\n", wf_chspec_ntoa(chspec, chanbuf), chspec)); return INVCHANSPEC; } return lchspec; -} +} /* given a chanspec value, do the endian and chanspec version conversion to * a chanspec_t value * Returns INVCHANSPEC on error */ static chanspec_t -wl_ext_chspec_host_to_driver(int ioctl_ver, chanspec_t chanspec) +wl_ext_chspec_host_to_driver(int ioctl_ver, chanspec_t chanspec) { - if (ioctl_ver == 1) { - chanspec = wl_ext_chspec_to_legacy(chanspec); + if (ioctl_ver == 1) { + chanspec = wl_ext_chspec_to_legacy(chanspec); if (chanspec == INVCHANSPEC) { return chanspec; } @@ -199,99 +199,99 @@ wl_ext_chspec_host_to_driver(int ioctl_ver, chanspec_t chanspec) chanspec = htodchanspec(chanspec); return chanspec; -} - -static int -wl_ext_get_ioctl_ver(struct net_device *dev, int *ioctl_ver) -{ - int ret = 0; - s32 val = 0; - - val = 1; - ret = wl_ext_ioctl(dev, WLC_GET_VERSION, &val, sizeof(val), 0); - if (ret) { - ANDROID_ERROR(("WLC_GET_VERSION failed, err=%d\n", ret)); - return ret; - } - val = dtoh32(val); - if (val != WLC_IOCTL_VERSION && val != 1) { - ANDROID_ERROR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n", - val, WLC_IOCTL_VERSION)); - return BCME_VERSION; - } - *ioctl_ver = val; - - return ret; -} - -static int -wl_ext_set_chanspec(struct net_device *dev, uint16 channel) -{ - s32 _chan = channel; +} + +static int +wl_ext_get_ioctl_ver(struct net_device *dev, int *ioctl_ver) +{ + int ret = 0; + s32 val = 0; + + val = 1; + ret = wl_ext_ioctl(dev, WLC_GET_VERSION, &val, sizeof(val), 0); + if (ret) { + ANDROID_ERROR(("WLC_GET_VERSION failed, err=%d\n", ret)); + return ret; + } + val = dtoh32(val); + if (val != WLC_IOCTL_VERSION && val != 1) { + ANDROID_ERROR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n", + val, WLC_IOCTL_VERSION)); + return BCME_VERSION; + } + *ioctl_ver = val; + + return ret; +} + +static int +wl_ext_set_chanspec(struct net_device *dev, uint16 channel) +{ + s32 _chan = channel; chanspec_t chspec = 0; - chanspec_t fw_chspec = 0; - u32 bw = WL_CHANSPEC_BW_20; + chanspec_t fw_chspec = 0; + u32 bw = WL_CHANSPEC_BW_20; s32 err = BCME_OK; - s32 bw_cap = 0; - s8 iovar_buf[WLC_IOCTL_SMLEN]; + s32 bw_cap = 0; + s8 iovar_buf[WLC_IOCTL_SMLEN]; struct { u32 band; u32 bw_cap; - } param = {0, 0}; - uint band; - int ioctl_ver = 0; - - if (_chan <= CH_MAX_2G_CHANNEL) - band = IEEE80211_BAND_2GHZ; - else - band = IEEE80211_BAND_5GHZ; - wl_ext_get_ioctl_ver(dev, &ioctl_ver); - - if (band == IEEE80211_BAND_5GHZ) { + } param = {0, 0}; + uint band; + int ioctl_ver = 0; + + if (_chan <= CH_MAX_2G_CHANNEL) + band = IEEE80211_BAND_2GHZ; + else + band = IEEE80211_BAND_5GHZ; + wl_ext_get_ioctl_ver(dev, &ioctl_ver); + + if (band == IEEE80211_BAND_5GHZ) { param.band = WLC_BAND_5G; err = wldev_iovar_getbuf(dev, "bw_cap", ¶m, sizeof(param), - iovar_buf, WLC_IOCTL_SMLEN, NULL); + iovar_buf, WLC_IOCTL_SMLEN, NULL); if (err) { if (err != BCME_UNSUPPORTED) { - ANDROID_ERROR(("bw_cap failed, %d\n", err)); + ANDROID_ERROR(("bw_cap failed, %d\n", err)); return err; } else { err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap); if (err) { - ANDROID_ERROR(("error get mimo_bw_cap (%d)\n", err)); + ANDROID_ERROR(("error get mimo_bw_cap (%d)\n", err)); } if (bw_cap != WLC_N_BW_20ALL) bw = WL_CHANSPEC_BW_40; } } else { - if (WL_BW_CAP_80MHZ(iovar_buf[0])) + if (WL_BW_CAP_80MHZ(iovar_buf[0])) bw = WL_CHANSPEC_BW_80; - else if (WL_BW_CAP_40MHZ(iovar_buf[0])) + else if (WL_BW_CAP_40MHZ(iovar_buf[0])) bw = WL_CHANSPEC_BW_40; else bw = WL_CHANSPEC_BW_20; - } - } - else if (band == IEEE80211_BAND_2GHZ) - bw = WL_CHANSPEC_BW_20; - + } + } + else if (band == IEEE80211_BAND_2GHZ) + bw = WL_CHANSPEC_BW_20; + set_channel: chspec = wf_channel2chspec(_chan, bw); if (wf_chspec_valid(chspec)) { - fw_chspec = wl_ext_chspec_host_to_driver(ioctl_ver, chspec); + fw_chspec = wl_ext_chspec_host_to_driver(ioctl_ver, chspec); if (fw_chspec != INVCHANSPEC) { - if ((err = wldev_iovar_setint(dev, "chanspec", fw_chspec)) == BCME_BADCHAN) { + if ((err = wldev_iovar_setint(dev, "chanspec", fw_chspec)) == BCME_BADCHAN) { if (bw == WL_CHANSPEC_BW_80) - goto change_bw; - wl_ext_ioctl(dev, WLC_SET_CHANNEL, &_chan, sizeof(_chan), 1); - printf("%s: channel %d\n", __FUNCTION__, _chan); + goto change_bw; + wl_ext_ioctl(dev, WLC_SET_CHANNEL, &_chan, sizeof(_chan), 1); + printf("%s: channel %d\n", __FUNCTION__, _chan); } else if (err) { - ANDROID_ERROR(("%s: failed to set chanspec error %d\n", __FUNCTION__, err)); - } else - printf("%s: channel %d, 0x%x\n", __FUNCTION__, channel, chspec); + ANDROID_ERROR(("%s: failed to set chanspec error %d\n", __FUNCTION__, err)); + } else + printf("%s: channel %d, 0x%x\n", __FUNCTION__, channel, chspec); } else { - ANDROID_ERROR(("%s: failed to convert host chanspec to fw chanspec\n", __FUNCTION__)); + ANDROID_ERROR(("%s: failed to convert host chanspec to fw chanspec\n", __FUNCTION__)); err = BCME_ERROR; } } else { @@ -304,1875 +304,1875 @@ change_bw: bw = 0; if (bw) goto set_channel; - ANDROID_ERROR(("%s: Invalid chanspec 0x%x\n", __FUNCTION__, chspec)); + ANDROID_ERROR(("%s: Invalid chanspec 0x%x\n", __FUNCTION__, chspec)); err = BCME_ERROR; - } - - return err; -} - -int -wl_ext_channel(struct net_device *dev, char* command, int total_len) -{ - int ret; - int channel=0; - channel_info_t ci; - int bytes_written = 0; - - ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command)); - - sscanf(command, "%*s %d", &channel); - - if (channel > 0) { - ret = wl_ext_set_chanspec(dev, channel); - } else { - if (!(ret = wldev_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) { - ANDROID_TRACE(("hw_channel %d\n", ci.hw_channel)); - ANDROID_TRACE(("target_channel %d\n", ci.target_channel)); - ANDROID_TRACE(("scan_channel %d\n", ci.scan_channel)); - bytes_written = snprintf(command, sizeof(channel_info_t)+2, "channel %d", ci.hw_channel); - ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); - ret = bytes_written; - } - } - - return ret; -} - -int -wl_ext_channels(struct net_device *dev, char* command, int total_len) -{ - int ret, i; - int bytes_written = -1; - u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)]; - wl_uint32_list_t *list; - - ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command)); - - memset(valid_chan_list, 0, sizeof(valid_chan_list)); - list = (wl_uint32_list_t *)(void *) valid_chan_list; - list->count = htod32(WL_NUMCHANNELS); - ret = wldev_ioctl(dev, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), 0); - if (ret<0) { - ANDROID_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, ret)); - } else { - bytes_written = snprintf(command, total_len, "channels"); - for (i = 0; i < dtoh32(list->count); i++) { - bytes_written += snprintf(command+bytes_written, total_len, " %d", dtoh32(list->element[i])); - printf("%d ", dtoh32(list->element[i])); - } - printf("\n"); - ret = bytes_written; - } - - return ret; -} - -int -wl_ext_roam_trigger(struct net_device *dev, char* command, int total_len) -{ - int ret = 0; - int roam_trigger[2] = {0, 0}; - int trigger[2]= {0, 0}; - int bytes_written=-1; - - sscanf(command, "%*s %10d", &roam_trigger[0]); - - if (roam_trigger[0]) { - roam_trigger[1] = WLC_BAND_ALL; - ret = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 1); - if (ret) - ANDROID_ERROR(("WLC_SET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret)); - } else { - roam_trigger[1] = WLC_BAND_2G; - ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0); - if (!ret) - trigger[0] = roam_trigger[0]; - else - ANDROID_ERROR(("2G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret)); - - roam_trigger[1] = WLC_BAND_5G; - ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0); - if (!ret) - trigger[1] = roam_trigger[0]; - else - ANDROID_ERROR(("5G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret)); - - ANDROID_TRACE(("roam_trigger %d %d\n", trigger[0], trigger[1])); - bytes_written = snprintf(command, total_len, "%d %d", trigger[0], trigger[1]); - ret = bytes_written; - } - - return ret; -} - -static int -wl_ext_pattern_atoh(char *src, char *dst) -{ - int i; - if (strncmp(src, "0x", 2) != 0 && - strncmp(src, "0X", 2) != 0) { - ANDROID_ERROR(("Mask invalid format. Needs to start with 0x\n")); - return -1; - } - src = src + 2; /* Skip past 0x */ - if (strlen(src) % 2 != 0) { - DHD_ERROR(("Mask invalid format. Needs to be of even length\n")); - return -1; - } - for (i = 0; *src != '\0'; i++) { - char num[3]; - bcm_strncpy_s(num, sizeof(num), src, 2); - num[2] = '\0'; - dst[i] = (uint8)strtoul(num, NULL, 16); - src += 2; - } - return i; -} - -int -wl_ext_keep_alive(struct net_device *dev, char *command, int total_len) -{ - wl_mkeep_alive_pkt_t *mkeep_alive_pktp; - int ret = -1, i; - int id, period=-1, len_bytes=0, buf_len=0; - char data[200]="\0"; - char buf[WLC_IOCTL_SMLEN]="\0", iovar_buf[WLC_IOCTL_SMLEN]="\0"; - int bytes_written = -1; - - ANDROID_TRACE(("%s: command = %s\n", __FUNCTION__, command)); - sscanf(command, "%*s %d %d %s", &id, &period, data); - ANDROID_TRACE(("%s: id=%d, period=%d, data=%s\n", __FUNCTION__, id, period, data)); - - if (period >= 0) { - mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *)buf; - mkeep_alive_pktp->version = htod16(WL_MKEEP_ALIVE_VERSION); - mkeep_alive_pktp->length = htod16(WL_MKEEP_ALIVE_FIXED_LEN); - mkeep_alive_pktp->keep_alive_id = id; - buf_len += WL_MKEEP_ALIVE_FIXED_LEN; - mkeep_alive_pktp->period_msec = period; - if (strlen(data)) { - len_bytes = wl_ext_pattern_atoh(data, (char *) mkeep_alive_pktp->data); - buf_len += len_bytes; - } - mkeep_alive_pktp->len_bytes = htod16(len_bytes); - - ret = wl_ext_iovar_setbuf(dev, "mkeep_alive", buf, buf_len, - iovar_buf, sizeof(iovar_buf), NULL); - } else { - if (id < 0) - id = 0; - ret = wl_ext_iovar_getbuf(dev, "mkeep_alive", &id, sizeof(id), buf, sizeof(buf), NULL); - if (ret) { - goto exit; - } else { - mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) buf; - printf("Id :%d\n" - "Period (msec) :%d\n" - "Length :%d\n" - "Packet :0x", - mkeep_alive_pktp->keep_alive_id, - dtoh32(mkeep_alive_pktp->period_msec), - dtoh16(mkeep_alive_pktp->len_bytes)); - for (i=0; ilen_bytes; i++) { - printf("%02x", mkeep_alive_pktp->data[i]); - } - printf("\n"); - } - bytes_written = snprintf(command, total_len, "mkeep_alive_period_msec %d ", dtoh32(mkeep_alive_pktp->period_msec)); - bytes_written += snprintf(command+bytes_written, total_len, "0x"); - for (i=0; ilen_bytes; i++) { - bytes_written += snprintf(command+bytes_written, total_len, "%x", mkeep_alive_pktp->data[i]); - } - ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); - ret = bytes_written; - } - -exit: - return ret; -} - -int -wl_ext_pm(struct net_device *dev, char *command, int total_len) -{ - int pm=-1, ret = -1; - char *pm_local; - int bytes_written=-1; - - ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command)); - - sscanf(command, "%*s %d", &pm); - - if (pm >= 0) { - ret = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), FALSE); - if (ret) - ANDROID_ERROR(("WLC_SET_PM ERROR %d ret=%d\n", pm, ret)); - } else { - ret = wldev_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm), FALSE); - if (!ret) { - ANDROID_TRACE(("%s: PM = %d\n", __func__, pm)); - if (pm == PM_OFF) - pm_local = "PM_OFF"; - else if(pm == PM_MAX) - pm_local = "PM_MAX"; - else if(pm == PM_FAST) - pm_local = "PM_FAST"; - else { - pm = 0; - pm_local = "Invalid"; - } - bytes_written = snprintf(command, total_len, "PM %s", pm_local); - ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); - ret = bytes_written; - } - } - - return ret; -} - -static int -wl_ext_monitor(struct net_device *dev, char *command, int total_len) -{ - int val, ret = -1; - int bytes_written=-1; - - sscanf(command, "%*s %d", &val); - - if (val >=0) { - ret = wldev_ioctl(dev, WLC_SET_MONITOR, &val, sizeof(int), 1); - if (ret) - ANDROID_ERROR(("WLC_SET_MONITOR ERROR %d ret=%d\n", val, ret)); - } else { - ret = wldev_ioctl(dev, WLC_GET_MONITOR, &val, sizeof(val), FALSE); - if (!ret) { - ANDROID_TRACE(("%s: monitor = %d\n", __FUNCTION__, val)); - bytes_written = snprintf(command, total_len, "monitor %d", val); - ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); - ret = bytes_written; - } - } - - return ret; -} - -#ifdef WL_EXT_IAPSTA -struct wl_apsta_params g_apsta_params; -static int -wl_ext_parse_wep(char *key, struct wl_wsec_key *wsec_key) -{ - char hex[] = "XX"; - unsigned char *data = wsec_key->data; - char *keystr = key; - - switch (strlen(keystr)) { - case 5: - case 13: - case 16: - wsec_key->len = strlen(keystr); - memcpy(data, keystr, wsec_key->len + 1); - break; - case 12: - case 28: - case 34: - case 66: - /* strip leading 0x */ - if (!strnicmp(keystr, "0x", 2)) - keystr += 2; - else - return -1; - /* fall through */ - case 10: - case 26: - case 32: - case 64: - wsec_key->len = strlen(keystr) / 2; - while (*keystr) { - strncpy(hex, keystr, 2); - *data++ = (char) strtoul(hex, NULL, 16); - keystr += 2; - } - break; - default: - return -1; - } - - switch (wsec_key->len) { - case 5: - wsec_key->algo = CRYPTO_ALGO_WEP1; - break; - case 13: - wsec_key->algo = CRYPTO_ALGO_WEP128; - break; - case 16: - /* default to AES-CCM */ - wsec_key->algo = CRYPTO_ALGO_AES_CCM; - break; - case 32: - wsec_key->algo = CRYPTO_ALGO_TKIP; - break; - default: - return -1; - } - - /* Set as primary wsec_key by default */ - wsec_key->flags |= WL_PRIMARY_KEY; - - return 0; -} - -static int -wl_ext_set_bgnmode(struct wl_if_info *cur_if) -{ - struct net_device *dev = cur_if->dev; - bgnmode_t bgnmode = cur_if->bgnmode; - int val; - - if (bgnmode == 0) - return 0; - - wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); - if (bgnmode == IEEE80211B) { - wl_ext_iovar_setint(dev, "nmode", 0); - val = 0; - wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1); - ANDROID_TRACE(("%s: Network mode: B only\n", __FUNCTION__)); - } else if (bgnmode == IEEE80211G) { - wl_ext_iovar_setint(dev, "nmode", 0); - val = 2; - wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1); - ANDROID_TRACE(("%s: Network mode: G only\n", __FUNCTION__)); - } else if (bgnmode == IEEE80211BG) { - wl_ext_iovar_setint(dev, "nmode", 0); - val = 1; - wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1); - ANDROID_TRACE(("%s: Network mode: : B/G mixed\n", __FUNCTION__)); - } else if (bgnmode == IEEE80211BGN) { - wl_ext_iovar_setint(dev, "nmode", 0); - wl_ext_iovar_setint(dev, "nmode", 1); - wl_ext_iovar_setint(dev, "vhtmode", 0); - val = 1; - wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1); - ANDROID_TRACE(("%s: Network mode: : B/G/N mixed\n", __FUNCTION__)); - } else if (bgnmode == IEEE80211BGNAC) { - wl_ext_iovar_setint(dev, "nmode", 0); - wl_ext_iovar_setint(dev, "nmode", 1); - wl_ext_iovar_setint(dev, "vhtmode", 1); - val = 1; - wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1); - ANDROID_TRACE(("%s: Network mode: : B/G/N/AC mixed\n", __FUNCTION__)); - } - wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); - - return 0; -} - -static int -wl_ext_set_amode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params) -{ - struct net_device *dev = cur_if->dev; - authmode_t amode = cur_if->amode; - int auth=0, wpa_auth=0; - - if (amode == AUTH_OPEN) { - auth = 0; - wpa_auth = 0; - ANDROID_TRACE(("%s: Authentication: Open System\n", __FUNCTION__)); - } else if (amode == AUTH_SHARED) { - auth = 1; - wpa_auth = 0; - ANDROID_TRACE(("%s: Authentication: Shared Key\n", __FUNCTION__)); - } else if (amode == AUTH_WPAPSK) { - auth = 0; - wpa_auth = 4; - ANDROID_TRACE(("%s: Authentication: WPA-PSK\n", __FUNCTION__)); - } else if (amode == AUTH_WPA2PSK) { - auth = 0; - wpa_auth = 128; - ANDROID_TRACE(("%s: Authentication: WPA2-PSK\n", __FUNCTION__)); - } else if (amode == AUTH_WPAWPA2PSK) { - auth = 0; - wpa_auth = 132; - ANDROID_TRACE(("%s: Authentication: WPA/WPA2-PSK\n", __FUNCTION__)); - } - wl_ext_iovar_setint(dev, "auth", auth); - - wl_ext_iovar_setint(dev, "wpa_auth", wpa_auth); - - return 0; -} - -static int -wl_ext_set_emode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params) -{ - struct net_device *dev = cur_if->dev; - int wsec=0; - struct wl_wsec_key wsec_key; - wsec_pmk_t psk; - encmode_t emode = cur_if->emode; - char *key = cur_if->key; - - memset(&wsec_key, 0, sizeof(wsec_key)); - memset(&psk, 0, sizeof(psk)); - if (emode == ENC_NONE) { - wsec = 0; - ANDROID_TRACE(("%s: Encryption: No securiy\n", __FUNCTION__)); - } else if (emode == ENC_WEP) { - wsec = 1; - wl_ext_parse_wep(key, &wsec_key); - ANDROID_TRACE(("%s: Encryption: WEP\n", __FUNCTION__)); - ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, wsec_key.data)); - } else if (emode == ENC_TKIP) { - wsec = 2; - psk.key_len = strlen(key); - psk.flags = WSEC_PASSPHRASE; - memcpy(psk.key, key, strlen(key)); - ANDROID_TRACE(("%s: Encryption: TKIP\n", __FUNCTION__)); - ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key)); - } else if (emode == ENC_AES) { - wsec = 4; - psk.key_len = strlen(key); - psk.flags = WSEC_PASSPHRASE; - memcpy(psk.key, key, strlen(key)); - ANDROID_TRACE(("%s: Encryption: AES\n", __FUNCTION__)); - ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key)); - } else if (emode == ENC_TKIPAES) { - wsec = 6; - psk.key_len = strlen(key); - psk.flags = WSEC_PASSPHRASE; - memcpy(psk.key, key, strlen(key)); - ANDROID_TRACE(("%s: Encryption: TKIP/AES\n", __FUNCTION__)); - ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key)); - } - - wl_ext_iovar_setint(dev, "wsec", wsec); - - if (wsec == 1) { - wl_ext_ioctl(dev, WLC_SET_KEY, &wsec_key, sizeof(wsec_key), 1); - } else if (emode == ENC_TKIP || emode == ENC_AES || emode == ENC_TKIPAES) { - if (dev) { - if (cur_if->ifmode == ISTA_MODE) - wl_ext_iovar_setint(dev, "sup_wpa", 1); - wl_ext_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk), 1); - } else { - ANDROID_ERROR(("%s: apdev is null\n", __FUNCTION__)); - } - } - - return 0; -} - -static int -wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len) -{ - s32 val = 0; - char *pch, *pick_tmp, *param; - wlc_ssid_t ssid = { 0, {0} }; - s8 iovar_buf[WLC_IOCTL_SMLEN]; - struct wl_apsta_params *apsta_params = &g_apsta_params; - wl_interface_create_t iface; - struct dhd_pub *dhd; - wl_p2p_if_t ifreq; - - if (apsta_params->init) { - ANDROID_ERROR(("%s: don't init twice\n", __FUNCTION__)); - return -1; - } - - dhd = dhd_get_pub(dev); - memset(apsta_params, 0, sizeof(struct wl_apsta_params)); - - ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); - - pick_tmp = command; - param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_init - param = bcmstrtok(&pick_tmp, " ", 0); - while (param != NULL) { - if (!strcmp(param, "mode")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) { - if (!strcmp(pch, "sta")) { - apsta_params->apstamode = ISTAONLY_MODE; - } else if (!strcmp(pch, "ap")) { - apsta_params->apstamode = IAPONLY_MODE; - } else if (!strcmp(pch, "apsta")) { - apsta_params->apstamode = IAPSTA_MODE; - } else if (!strcmp(pch, "dualap")) { - apsta_params->apstamode = IDUALAP_MODE; - } else if (!strcmp(pch, "gosta")) { - if (!FW_SUPPORTED(dhd, p2p)) { - return -1; - } - apsta_params->apstamode = IGOSTA_MODE; - } else if (!strcmp(pch, "gcsta")) { - if (!FW_SUPPORTED(dhd, p2p)) { - return -1; - } - apsta_params->apstamode = IGCSTA_MODE; - } else { - ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__)); - return -1; - } - } - } else if (!strcmp(param, "vifname")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) - strcpy(apsta_params->vif.ifname, pch); - else { - ANDROID_ERROR(("%s: vifname [wlan1]\n", __FUNCTION__)); - return -1; - } - } - param = bcmstrtok(&pick_tmp, " ", 0); - } - - if (apsta_params->apstamode == 0) { - ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__)); - return -1; - } - - apsta_params->pif.dev = dev; - apsta_params->pif.bssidx = 0; - strcpy(apsta_params->pif.ifname, dev->name); - strcpy(apsta_params->pif.ssid, "tttp"); - apsta_params->pif.maxassoc = -1; - apsta_params->pif.channel = 1; - - if (!strlen(apsta_params->vif.ifname)) - strcpy(apsta_params->vif.ifname, "wlan1"); - strcpy(apsta_params->vif.ssid, "tttv"); - apsta_params->vif.maxassoc = -1; - apsta_params->vif.channel = 1; - - if (apsta_params->apstamode == ISTAONLY_MODE) { - apsta_params->pif.ifmode = ISTA_MODE; - apsta_params->pif.ifstate = IF_STATE_INIT; - wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); - wl_ext_iovar_setint(dev, "apsta", 1); // keep 1 as we set in dhd_preinit_ioctls - // don't set WLC_SET_AP to 0, some parameters will be reset, such as bcn_timeout and roam_off - wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); - } else if (apsta_params->apstamode == IAPONLY_MODE) { - apsta_params->pif.ifmode = IAP_MODE; - apsta_params->pif.ifstate = IF_STATE_INIT; - wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); + } + + return err; +} + +int +wl_ext_channel(struct net_device *dev, char* command, int total_len) +{ + int ret; + int channel=0; + channel_info_t ci; + int bytes_written = 0; + + ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command)); + + sscanf(command, "%*s %d", &channel); + + if (channel > 0) { + ret = wl_ext_set_chanspec(dev, channel); + } else { + if (!(ret = wldev_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) { + ANDROID_TRACE(("hw_channel %d\n", ci.hw_channel)); + ANDROID_TRACE(("target_channel %d\n", ci.target_channel)); + ANDROID_TRACE(("scan_channel %d\n", ci.scan_channel)); + bytes_written = snprintf(command, sizeof(channel_info_t)+2, "channel %d", ci.hw_channel); + ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); + ret = bytes_written; + } + } + + return ret; +} + +int +wl_ext_channels(struct net_device *dev, char* command, int total_len) +{ + int ret, i; + int bytes_written = -1; + u8 valid_chan_list[sizeof(u32)*(WL_NUMCHANNELS + 1)]; + wl_uint32_list_t *list; + + ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command)); + + memset(valid_chan_list, 0, sizeof(valid_chan_list)); + list = (wl_uint32_list_t *)(void *) valid_chan_list; + list->count = htod32(WL_NUMCHANNELS); + ret = wldev_ioctl(dev, WLC_GET_VALID_CHANNELS, valid_chan_list, sizeof(valid_chan_list), 0); + if (ret<0) { + ANDROID_ERROR(("%s: get channels failed with %d\n", __FUNCTION__, ret)); + } else { + bytes_written = snprintf(command, total_len, "channels"); + for (i = 0; i < dtoh32(list->count); i++) { + bytes_written += snprintf(command+bytes_written, total_len, " %d", dtoh32(list->element[i])); + printf("%d ", dtoh32(list->element[i])); + } + printf("\n"); + ret = bytes_written; + } + + return ret; +} + +int +wl_ext_roam_trigger(struct net_device *dev, char* command, int total_len) +{ + int ret = 0; + int roam_trigger[2] = {0, 0}; + int trigger[2]= {0, 0}; + int bytes_written=-1; + + sscanf(command, "%*s %10d", &roam_trigger[0]); + + if (roam_trigger[0]) { + roam_trigger[1] = WLC_BAND_ALL; + ret = wldev_ioctl(dev, WLC_SET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 1); + if (ret) + ANDROID_ERROR(("WLC_SET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret)); + } else { + roam_trigger[1] = WLC_BAND_2G; + ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0); + if (!ret) + trigger[0] = roam_trigger[0]; + else + ANDROID_ERROR(("2G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret)); + + roam_trigger[1] = WLC_BAND_5G; + ret = wldev_ioctl(dev, WLC_GET_ROAM_TRIGGER, roam_trigger, sizeof(roam_trigger), 0); + if (!ret) + trigger[1] = roam_trigger[0]; + else + ANDROID_ERROR(("5G WLC_GET_ROAM_TRIGGER ERROR %d ret=%d\n", roam_trigger[0], ret)); + + ANDROID_TRACE(("roam_trigger %d %d\n", trigger[0], trigger[1])); + bytes_written = snprintf(command, total_len, "%d %d", trigger[0], trigger[1]); + ret = bytes_written; + } + + return ret; +} + +static int +wl_ext_pattern_atoh(char *src, char *dst) +{ + int i; + if (strncmp(src, "0x", 2) != 0 && + strncmp(src, "0X", 2) != 0) { + ANDROID_ERROR(("Mask invalid format. Needs to start with 0x\n")); + return -1; + } + src = src + 2; /* Skip past 0x */ + if (strlen(src) % 2 != 0) { + DHD_ERROR(("Mask invalid format. Needs to be of even length\n")); + return -1; + } + for (i = 0; *src != '\0'; i++) { + char num[3]; + bcm_strncpy_s(num, sizeof(num), src, 2); + num[2] = '\0'; + dst[i] = (uint8)strtoul(num, NULL, 16); + src += 2; + } + return i; +} + +int +wl_ext_keep_alive(struct net_device *dev, char *command, int total_len) +{ + wl_mkeep_alive_pkt_t *mkeep_alive_pktp; + int ret = -1, i; + int id, period=-1, len_bytes=0, buf_len=0; + char data[200]="\0"; + char buf[WLC_IOCTL_SMLEN]="\0", iovar_buf[WLC_IOCTL_SMLEN]="\0"; + int bytes_written = -1; + + ANDROID_TRACE(("%s: command = %s\n", __FUNCTION__, command)); + sscanf(command, "%*s %d %d %s", &id, &period, data); + ANDROID_TRACE(("%s: id=%d, period=%d, data=%s\n", __FUNCTION__, id, period, data)); + + if (period >= 0) { + mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *)buf; + mkeep_alive_pktp->version = htod16(WL_MKEEP_ALIVE_VERSION); + mkeep_alive_pktp->length = htod16(WL_MKEEP_ALIVE_FIXED_LEN); + mkeep_alive_pktp->keep_alive_id = id; + buf_len += WL_MKEEP_ALIVE_FIXED_LEN; + mkeep_alive_pktp->period_msec = period; + if (strlen(data)) { + len_bytes = wl_ext_pattern_atoh(data, (char *) mkeep_alive_pktp->data); + buf_len += len_bytes; + } + mkeep_alive_pktp->len_bytes = htod16(len_bytes); + + ret = wl_ext_iovar_setbuf(dev, "mkeep_alive", buf, buf_len, + iovar_buf, sizeof(iovar_buf), NULL); + } else { + if (id < 0) + id = 0; + ret = wl_ext_iovar_getbuf(dev, "mkeep_alive", &id, sizeof(id), buf, sizeof(buf), NULL); + if (ret) { + goto exit; + } else { + mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) buf; + printf("Id :%d\n" + "Period (msec) :%d\n" + "Length :%d\n" + "Packet :0x", + mkeep_alive_pktp->keep_alive_id, + dtoh32(mkeep_alive_pktp->period_msec), + dtoh16(mkeep_alive_pktp->len_bytes)); + for (i=0; ilen_bytes; i++) { + printf("%02x", mkeep_alive_pktp->data[i]); + } + printf("\n"); + } + bytes_written = snprintf(command, total_len, "mkeep_alive_period_msec %d ", dtoh32(mkeep_alive_pktp->period_msec)); + bytes_written += snprintf(command+bytes_written, total_len, "0x"); + for (i=0; ilen_bytes; i++) { + bytes_written += snprintf(command+bytes_written, total_len, "%x", mkeep_alive_pktp->data[i]); + } + ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); + ret = bytes_written; + } + +exit: + return ret; +} + +int +wl_ext_pm(struct net_device *dev, char *command, int total_len) +{ + int pm=-1, ret = -1; + char *pm_local; + int bytes_written=-1; + + ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command)); + + sscanf(command, "%*s %d", &pm); + + if (pm >= 0) { + ret = wldev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm), FALSE); + if (ret) + ANDROID_ERROR(("WLC_SET_PM ERROR %d ret=%d\n", pm, ret)); + } else { + ret = wldev_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm), FALSE); + if (!ret) { + ANDROID_TRACE(("%s: PM = %d\n", __func__, pm)); + if (pm == PM_OFF) + pm_local = "PM_OFF"; + else if(pm == PM_MAX) + pm_local = "PM_MAX"; + else if(pm == PM_FAST) + pm_local = "PM_FAST"; + else { + pm = 0; + pm_local = "Invalid"; + } + bytes_written = snprintf(command, total_len, "PM %s", pm_local); + ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); + ret = bytes_written; + } + } + + return ret; +} + +static int +wl_ext_monitor(struct net_device *dev, char *command, int total_len) +{ + int val, ret = -1; + int bytes_written=-1; + + sscanf(command, "%*s %d", &val); + + if (val >=0) { + ret = wldev_ioctl(dev, WLC_SET_MONITOR, &val, sizeof(int), 1); + if (ret) + ANDROID_ERROR(("WLC_SET_MONITOR ERROR %d ret=%d\n", val, ret)); + } else { + ret = wldev_ioctl(dev, WLC_GET_MONITOR, &val, sizeof(val), FALSE); + if (!ret) { + ANDROID_TRACE(("%s: monitor = %d\n", __FUNCTION__, val)); + bytes_written = snprintf(command, total_len, "monitor %d", val); + ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); + ret = bytes_written; + } + } + + return ret; +} + +#ifdef WL_EXT_IAPSTA +struct wl_apsta_params g_apsta_params; +static int +wl_ext_parse_wep(char *key, struct wl_wsec_key *wsec_key) +{ + char hex[] = "XX"; + unsigned char *data = wsec_key->data; + char *keystr = key; + + switch (strlen(keystr)) { + case 5: + case 13: + case 16: + wsec_key->len = strlen(keystr); + memcpy(data, keystr, wsec_key->len + 1); + break; + case 12: + case 28: + case 34: + case 66: + /* strip leading 0x */ + if (!strnicmp(keystr, "0x", 2)) + keystr += 2; + else + return -1; + /* fall through */ + case 10: + case 26: + case 32: + case 64: + wsec_key->len = strlen(keystr) / 2; + while (*keystr) { + strncpy(hex, keystr, 2); + *data++ = (char) strtoul(hex, NULL, 16); + keystr += 2; + } + break; + default: + return -1; + } + + switch (wsec_key->len) { + case 5: + wsec_key->algo = CRYPTO_ALGO_WEP1; + break; + case 13: + wsec_key->algo = CRYPTO_ALGO_WEP128; + break; + case 16: + /* default to AES-CCM */ + wsec_key->algo = CRYPTO_ALGO_AES_CCM; + break; + case 32: + wsec_key->algo = CRYPTO_ALGO_TKIP; + break; + default: + return -1; + } + + /* Set as primary wsec_key by default */ + wsec_key->flags |= WL_PRIMARY_KEY; + + return 0; +} + +static int +wl_ext_set_bgnmode(struct wl_if_info *cur_if) +{ + struct net_device *dev = cur_if->dev; + bgnmode_t bgnmode = cur_if->bgnmode; + int val; + + if (bgnmode == 0) + return 0; + + wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); + if (bgnmode == IEEE80211B) { + wl_ext_iovar_setint(dev, "nmode", 0); + val = 0; + wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1); + ANDROID_TRACE(("%s: Network mode: B only\n", __FUNCTION__)); + } else if (bgnmode == IEEE80211G) { + wl_ext_iovar_setint(dev, "nmode", 0); + val = 2; + wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1); + ANDROID_TRACE(("%s: Network mode: G only\n", __FUNCTION__)); + } else if (bgnmode == IEEE80211BG) { + wl_ext_iovar_setint(dev, "nmode", 0); + val = 1; + wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1); + ANDROID_TRACE(("%s: Network mode: : B/G mixed\n", __FUNCTION__)); + } else if (bgnmode == IEEE80211BGN) { + wl_ext_iovar_setint(dev, "nmode", 0); + wl_ext_iovar_setint(dev, "nmode", 1); + wl_ext_iovar_setint(dev, "vhtmode", 0); + val = 1; + wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1); + ANDROID_TRACE(("%s: Network mode: : B/G/N mixed\n", __FUNCTION__)); + } else if (bgnmode == IEEE80211BGNAC) { + wl_ext_iovar_setint(dev, "nmode", 0); + wl_ext_iovar_setint(dev, "nmode", 1); + wl_ext_iovar_setint(dev, "vhtmode", 1); + val = 1; + wl_ext_ioctl(dev, WLC_SET_GMODE, &val, sizeof(val), 1); + ANDROID_TRACE(("%s: Network mode: : B/G/N/AC mixed\n", __FUNCTION__)); + } + wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); + + return 0; +} + +static int +wl_ext_set_amode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params) +{ + struct net_device *dev = cur_if->dev; + authmode_t amode = cur_if->amode; + int auth=0, wpa_auth=0; + + if (amode == AUTH_OPEN) { + auth = 0; + wpa_auth = 0; + ANDROID_TRACE(("%s: Authentication: Open System\n", __FUNCTION__)); + } else if (amode == AUTH_SHARED) { + auth = 1; + wpa_auth = 0; + ANDROID_TRACE(("%s: Authentication: Shared Key\n", __FUNCTION__)); + } else if (amode == AUTH_WPAPSK) { + auth = 0; + wpa_auth = 4; + ANDROID_TRACE(("%s: Authentication: WPA-PSK\n", __FUNCTION__)); + } else if (amode == AUTH_WPA2PSK) { + auth = 0; + wpa_auth = 128; + ANDROID_TRACE(("%s: Authentication: WPA2-PSK\n", __FUNCTION__)); + } else if (amode == AUTH_WPAWPA2PSK) { + auth = 0; + wpa_auth = 132; + ANDROID_TRACE(("%s: Authentication: WPA/WPA2-PSK\n", __FUNCTION__)); + } + wl_ext_iovar_setint(dev, "auth", auth); + + wl_ext_iovar_setint(dev, "wpa_auth", wpa_auth); + + return 0; +} + +static int +wl_ext_set_emode(struct wl_if_info *cur_if, struct wl_apsta_params *apsta_params) +{ + struct net_device *dev = cur_if->dev; + int wsec=0; + struct wl_wsec_key wsec_key; + wsec_pmk_t psk; + encmode_t emode = cur_if->emode; + char *key = cur_if->key; + + memset(&wsec_key, 0, sizeof(wsec_key)); + memset(&psk, 0, sizeof(psk)); + if (emode == ENC_NONE) { + wsec = 0; + ANDROID_TRACE(("%s: Encryption: No securiy\n", __FUNCTION__)); + } else if (emode == ENC_WEP) { + wsec = 1; + wl_ext_parse_wep(key, &wsec_key); + ANDROID_TRACE(("%s: Encryption: WEP\n", __FUNCTION__)); + ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, wsec_key.data)); + } else if (emode == ENC_TKIP) { + wsec = 2; + psk.key_len = strlen(key); + psk.flags = WSEC_PASSPHRASE; + memcpy(psk.key, key, strlen(key)); + ANDROID_TRACE(("%s: Encryption: TKIP\n", __FUNCTION__)); + ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key)); + } else if (emode == ENC_AES) { + wsec = 4; + psk.key_len = strlen(key); + psk.flags = WSEC_PASSPHRASE; + memcpy(psk.key, key, strlen(key)); + ANDROID_TRACE(("%s: Encryption: AES\n", __FUNCTION__)); + ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key)); + } else if (emode == ENC_TKIPAES) { + wsec = 6; + psk.key_len = strlen(key); + psk.flags = WSEC_PASSPHRASE; + memcpy(psk.key, key, strlen(key)); + ANDROID_TRACE(("%s: Encryption: TKIP/AES\n", __FUNCTION__)); + ANDROID_TRACE(("%s: Key: %s\n", __FUNCTION__, psk.key)); + } + + wl_ext_iovar_setint(dev, "wsec", wsec); + + if (wsec == 1) { + wl_ext_ioctl(dev, WLC_SET_KEY, &wsec_key, sizeof(wsec_key), 1); + } else if (emode == ENC_TKIP || emode == ENC_AES || emode == ENC_TKIPAES) { + if (dev) { + if (cur_if->ifmode == ISTA_MODE) + wl_ext_iovar_setint(dev, "sup_wpa", 1); + wl_ext_ioctl(dev, WLC_SET_WSEC_PMK, &psk, sizeof(psk), 1); + } else { + ANDROID_ERROR(("%s: apdev is null\n", __FUNCTION__)); + } + } + + return 0; +} + +static int +wl_ext_iapsta_init(struct net_device *dev, char *command, int total_len) +{ + s32 val = 0; + char *pch, *pick_tmp, *param; + wlc_ssid_t ssid = { 0, {0} }; + s8 iovar_buf[WLC_IOCTL_SMLEN]; + struct wl_apsta_params *apsta_params = &g_apsta_params; + wl_interface_create_t iface; + struct dhd_pub *dhd; + wl_p2p_if_t ifreq; + + if (apsta_params->init) { + ANDROID_ERROR(("%s: don't init twice\n", __FUNCTION__)); + return -1; + } + + dhd = dhd_get_pub(dev); + memset(apsta_params, 0, sizeof(struct wl_apsta_params)); + + ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); + + pick_tmp = command; + param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_init + param = bcmstrtok(&pick_tmp, " ", 0); + while (param != NULL) { + if (!strcmp(param, "mode")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) { + if (!strcmp(pch, "sta")) { + apsta_params->apstamode = ISTAONLY_MODE; + } else if (!strcmp(pch, "ap")) { + apsta_params->apstamode = IAPONLY_MODE; + } else if (!strcmp(pch, "apsta")) { + apsta_params->apstamode = IAPSTA_MODE; + } else if (!strcmp(pch, "dualap")) { + apsta_params->apstamode = IDUALAP_MODE; + } else if (!strcmp(pch, "gosta")) { + if (!FW_SUPPORTED(dhd, p2p)) { + return -1; + } + apsta_params->apstamode = IGOSTA_MODE; + } else if (!strcmp(pch, "gcsta")) { + if (!FW_SUPPORTED(dhd, p2p)) { + return -1; + } + apsta_params->apstamode = IGCSTA_MODE; + } else { + ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__)); + return -1; + } + } + } else if (!strcmp(param, "vifname")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) + strcpy(apsta_params->vif.ifname, pch); + else { + ANDROID_ERROR(("%s: vifname [wlan1]\n", __FUNCTION__)); + return -1; + } + } + param = bcmstrtok(&pick_tmp, " ", 0); + } + + if (apsta_params->apstamode == 0) { + ANDROID_ERROR(("%s: mode [sta|ap|apsta|dualap]\n", __FUNCTION__)); + return -1; + } + + apsta_params->pif.dev = dev; + apsta_params->pif.bssidx = 0; + strcpy(apsta_params->pif.ifname, dev->name); + strcpy(apsta_params->pif.ssid, "tttp"); + apsta_params->pif.maxassoc = -1; + apsta_params->pif.channel = 1; + + if (!strlen(apsta_params->vif.ifname)) + strcpy(apsta_params->vif.ifname, "wlan1"); + strcpy(apsta_params->vif.ssid, "tttv"); + apsta_params->vif.maxassoc = -1; + apsta_params->vif.channel = 1; + + if (apsta_params->apstamode == ISTAONLY_MODE) { + apsta_params->pif.ifmode = ISTA_MODE; + apsta_params->pif.ifstate = IF_STATE_INIT; + wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); + wl_ext_iovar_setint(dev, "apsta", 1); // keep 1 as we set in dhd_preinit_ioctls + // don't set WLC_SET_AP to 0, some parameters will be reset, such as bcn_timeout and roam_off + wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); + } else if (apsta_params->apstamode == IAPONLY_MODE) { + apsta_params->pif.ifmode = IAP_MODE; + apsta_params->pif.ifstate = IF_STATE_INIT; + wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); #ifdef ARP_OFFLOAD_SUPPORT - /* IF SoftAP is enabled, disable arpoe */ - dhd_arp_offload_set(dhd, 0); - dhd_arp_offload_enable(dhd, FALSE); -#endif /* ARP_OFFLOAD_SUPPORT */ - wl_ext_iovar_setint(dev, "mpc", 0); - wl_ext_iovar_setint(dev, "apsta", 0); - val = 1; - wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1); - } else if (apsta_params->apstamode == IAPSTA_MODE) { - apsta_params->pif.ifmode = ISTA_MODE; - apsta_params->pif.ifstate = IF_STATE_INIT; - apsta_params->vif.ifmode = IAP_MODE; - apsta_params->vif.ifstate = IF_STATE_INIT; - wl_ext_iovar_setint(dev, "mpc", 0); - wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); - wl_ext_iovar_setint(dev, "apsta", 1); - wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); - if (FW_SUPPORTED(dhd, rsdb)) { - bzero(&iface, sizeof(wl_interface_create_t)); - iface.ver = WL_INTERFACE_CREATE_VER; - iface.flags = WL_INTERFACE_CREATE_AP; - wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface), iovar_buf, - WLC_IOCTL_SMLEN, 1, NULL); - } else { - wl_ext_iovar_setbuf_bsscfg(dev, "ssid", &ssid, sizeof(ssid), iovar_buf, - WLC_IOCTL_SMLEN, 1, NULL); - } - } - else if (apsta_params->apstamode == IDUALAP_MODE) { - apsta_params->pif.ifmode = IAP_MODE; - apsta_params->pif.ifstate = IF_STATE_INIT; - apsta_params->vif.ifmode = IAP_MODE; - apsta_params->vif.ifstate = IF_STATE_INIT; - wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); - wl_ext_iovar_setint(dev, "apsta", 0); - wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); - val = 1; - wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1); - /* IF SoftAP is enabled, disable arpoe or wlan1 will ping fail */ + /* IF SoftAP is enabled, disable arpoe */ + dhd_arp_offload_set(dhd, 0); + dhd_arp_offload_enable(dhd, FALSE); +#endif /* ARP_OFFLOAD_SUPPORT */ + wl_ext_iovar_setint(dev, "mpc", 0); + wl_ext_iovar_setint(dev, "apsta", 0); + val = 1; + wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1); + } else if (apsta_params->apstamode == IAPSTA_MODE) { + apsta_params->pif.ifmode = ISTA_MODE; + apsta_params->pif.ifstate = IF_STATE_INIT; + apsta_params->vif.ifmode = IAP_MODE; + apsta_params->vif.ifstate = IF_STATE_INIT; + wl_ext_iovar_setint(dev, "mpc", 0); + wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); + wl_ext_iovar_setint(dev, "apsta", 1); + wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); + if (FW_SUPPORTED(dhd, rsdb)) { + bzero(&iface, sizeof(wl_interface_create_t)); + iface.ver = WL_INTERFACE_CREATE_VER; + iface.flags = WL_INTERFACE_CREATE_AP; + wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface), iovar_buf, + WLC_IOCTL_SMLEN, 1, NULL); + } else { + wl_ext_iovar_setbuf_bsscfg(dev, "ssid", &ssid, sizeof(ssid), iovar_buf, + WLC_IOCTL_SMLEN, 1, NULL); + } + } + else if (apsta_params->apstamode == IDUALAP_MODE) { + apsta_params->pif.ifmode = IAP_MODE; + apsta_params->pif.ifstate = IF_STATE_INIT; + apsta_params->vif.ifmode = IAP_MODE; + apsta_params->vif.ifstate = IF_STATE_INIT; + wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); + wl_ext_iovar_setint(dev, "apsta", 0); + wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); + val = 1; + wl_ext_ioctl(dev, WLC_SET_AP, &val, sizeof(val), 1); + /* IF SoftAP is enabled, disable arpoe or wlan1 will ping fail */ #ifdef ARP_OFFLOAD_SUPPORT - /* IF SoftAP is enabled, disable arpoe */ - dhd_arp_offload_set(dhd, 0); - dhd_arp_offload_enable(dhd, FALSE); -#endif /* ARP_OFFLOAD_SUPPORT */ - bzero(&iface, sizeof(wl_interface_create_t)); - iface.ver = WL_INTERFACE_CREATE_VER; - iface.flags = WL_INTERFACE_CREATE_AP; - wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface), iovar_buf, - WLC_IOCTL_SMLEN, 1, NULL); - } - else if (apsta_params->apstamode == IGOSTA_MODE) { - apsta_params->pif.ifmode = ISTA_MODE; - apsta_params->pif.ifstate = IF_STATE_INIT; - apsta_params->vif.ifmode = IAP_MODE; - apsta_params->vif.ifstate = IF_STATE_INIT; - wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); - wl_ext_iovar_setint(dev, "apsta", 1); - wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); - bzero(&ifreq, sizeof(wl_p2p_if_t)); - ifreq.type = htod32(WL_P2P_IF_GO); - wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq), - iovar_buf, WLC_IOCTL_SMLEN, NULL); - } - else if (apsta_params->apstamode == IGCSTA_MODE) { - apsta_params->pif.ifmode = ISTA_MODE; - apsta_params->pif.ifstate = IF_STATE_INIT; - apsta_params->vif.ifmode = ISTA_MODE; - apsta_params->vif.ifstate = IF_STATE_INIT; - wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); - wl_ext_iovar_setint(dev, "apsta", 1); - wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); - bzero(&ifreq, sizeof(wl_p2p_if_t)); - ifreq.type = htod32(WL_P2P_IF_CLIENT); - wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq), - iovar_buf, WLC_IOCTL_SMLEN, NULL); - } - - wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver); - printf("%s: apstamode=%d\n", __FUNCTION__, apsta_params->apstamode); - - apsta_params->init = TRUE; - - return 0; -} - -static int -wl_ext_iapsta_config(struct net_device *dev, char *command, int total_len) -{ - int i; - char *pch, *pick_tmp, *param; - struct wl_apsta_params *apsta_params = &g_apsta_params; - char ifname[IFNAMSIZ+1]; - struct wl_if_info *cur_if = &apsta_params->pif; - - if (!apsta_params->init) { - ANDROID_ERROR(("%s: please init first\n", __FUNCTION__)); - return -1; - } - - ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); - - pick_tmp = command; - param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_config - param = bcmstrtok(&pick_tmp, " ", 0); - - if (param != NULL) { - if (strcmp(param, "ifname")) { - ANDROID_ERROR(("%s: first arg must be ifname\n", __FUNCTION__)); - return -1; - } - } - - while (param != NULL) { - if (!strcmp(param, "ifname")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) - strcpy(ifname, pch); - else { - ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__)); - return -1; - } - if (!strcmp(apsta_params->pif.dev->name, ifname)) { - cur_if = &apsta_params->pif; - } else if (!strcmp(apsta_params->vif.ifname, ifname)) { - cur_if = &apsta_params->vif; - } else { - ANDROID_ERROR(("%s: wrong ifname=%s in apstamode=%d\n", __FUNCTION__, - ifname, apsta_params->apstamode)); - return -1; - } - } else if (!strcmp(param, "ssid")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) - strcpy(cur_if->ssid, pch); - } else if (!strcmp(param, "bssid")) { - pch = bcmstrtok(&pick_tmp, ": ", 0); - for (i=0; i<6 && pch; i++) { - ((u8 *)&cur_if->bssid)[i] = (int)simple_strtol(pch, NULL, 16); - pch = bcmstrtok(&pick_tmp, ": ", 0); - } - } else if (!strcmp(param, "bgnmode")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) { - if (!strcmp(pch, "b")) - cur_if->bgnmode = IEEE80211B; - else if (!strcmp(pch, "g")) - cur_if->bgnmode = IEEE80211G; - else if (!strcmp(pch, "bg")) - cur_if->bgnmode = IEEE80211BG; - else if (!strcmp(pch, "bgn")) - cur_if->bgnmode = IEEE80211BGN; - else if (!strcmp(pch, "bgnac")) - cur_if->bgnmode = IEEE80211BGNAC; - else { - ANDROID_ERROR(("%s: bgnmode [b|g|bg|bgn|bgnac]\n", __FUNCTION__)); - return -1; - } - } - } else if (!strcmp(param, "hidden")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) { - if (!strcmp(pch, "n")) - cur_if->hidden = 0; - else if (!strcmp(pch, "y")) - cur_if->hidden = 1; - else { - ANDROID_ERROR(("%s: hidden [y|n]\n", __FUNCTION__)); - return -1; - } - } - } else if (!strcmp(param, "maxassoc")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) - cur_if->maxassoc = (int)simple_strtol(pch, NULL, 10); - } else if (!strcmp(param, "chan")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) - cur_if->channel = (int)simple_strtol(pch, NULL, 10); - } else if (!strcmp(param, "amode")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) { - if (!strcmp(pch, "open")) - cur_if->amode = AUTH_OPEN; - else if (!strcmp(pch, "shared")) - cur_if->amode = AUTH_SHARED; - else if (!strcmp(pch, "wpapsk")) - cur_if->amode = AUTH_WPAPSK; - else if (!strcmp(pch, "wpa2psk")) - cur_if->amode = AUTH_WPA2PSK; - else if (!strcmp(pch, "wpawpa2psk")) - cur_if->amode = AUTH_WPAWPA2PSK; - else { - ANDROID_ERROR(("%s: amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]\n", - __FUNCTION__)); - return -1; - } - } - } else if (!strcmp(param, "emode")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) { - if (!strcmp(pch, "none")) - cur_if->emode = ENC_NONE; - else if (!strcmp(pch, "wep")) - cur_if->emode = ENC_WEP; - else if (!strcmp(pch, "tkip")) - cur_if->emode = ENC_TKIP; - else if (!strcmp(pch, "aes")) - cur_if->emode = ENC_AES; - else if (!strcmp(pch, "tkipaes")) - cur_if->emode = ENC_TKIPAES; - else { - ANDROID_ERROR(("%s: emode [none|wep|tkip|aes|tkipaes]\n", - __FUNCTION__)); - return -1; - } - } - } else if (!strcmp(param, "key")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) { - strcpy(cur_if->key, pch); - } - } - param = bcmstrtok(&pick_tmp, " ", 0); - } - - return 0; -} - -static int -wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len) -{ - char *pch, *pick_tmp, *param; - s8 iovar_buf[WLC_IOCTL_SMLEN]; - wlc_ssid_t ssid = { 0, {0} }; - scb_val_t scbval; - struct { - s32 tmp; + /* IF SoftAP is enabled, disable arpoe */ + dhd_arp_offload_set(dhd, 0); + dhd_arp_offload_enable(dhd, FALSE); +#endif /* ARP_OFFLOAD_SUPPORT */ + bzero(&iface, sizeof(wl_interface_create_t)); + iface.ver = WL_INTERFACE_CREATE_VER; + iface.flags = WL_INTERFACE_CREATE_AP; + wl_ext_iovar_getbuf_bsscfg(dev, "interface_create", &iface, sizeof(iface), iovar_buf, + WLC_IOCTL_SMLEN, 1, NULL); + } + else if (apsta_params->apstamode == IGOSTA_MODE) { + apsta_params->pif.ifmode = ISTA_MODE; + apsta_params->pif.ifstate = IF_STATE_INIT; + apsta_params->vif.ifmode = IAP_MODE; + apsta_params->vif.ifstate = IF_STATE_INIT; + wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); + wl_ext_iovar_setint(dev, "apsta", 1); + wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); + bzero(&ifreq, sizeof(wl_p2p_if_t)); + ifreq.type = htod32(WL_P2P_IF_GO); + wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq), + iovar_buf, WLC_IOCTL_SMLEN, NULL); + } + else if (apsta_params->apstamode == IGCSTA_MODE) { + apsta_params->pif.ifmode = ISTA_MODE; + apsta_params->pif.ifstate = IF_STATE_INIT; + apsta_params->vif.ifmode = ISTA_MODE; + apsta_params->vif.ifstate = IF_STATE_INIT; + wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); + wl_ext_iovar_setint(dev, "apsta", 1); + wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); + bzero(&ifreq, sizeof(wl_p2p_if_t)); + ifreq.type = htod32(WL_P2P_IF_CLIENT); + wl_ext_iovar_setbuf(dev, "p2p_ifadd", &ifreq, sizeof(ifreq), + iovar_buf, WLC_IOCTL_SMLEN, NULL); + } + + wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver); + printf("%s: apstamode=%d\n", __FUNCTION__, apsta_params->apstamode); + + apsta_params->init = TRUE; + + return 0; +} + +static int +wl_ext_iapsta_config(struct net_device *dev, char *command, int total_len) +{ + int i; + char *pch, *pick_tmp, *param; + struct wl_apsta_params *apsta_params = &g_apsta_params; + char ifname[IFNAMSIZ+1]; + struct wl_if_info *cur_if = &apsta_params->pif; + + if (!apsta_params->init) { + ANDROID_ERROR(("%s: please init first\n", __FUNCTION__)); + return -1; + } + + ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); + + pick_tmp = command; + param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_config + param = bcmstrtok(&pick_tmp, " ", 0); + + if (param != NULL) { + if (strcmp(param, "ifname")) { + ANDROID_ERROR(("%s: first arg must be ifname\n", __FUNCTION__)); + return -1; + } + } + + while (param != NULL) { + if (!strcmp(param, "ifname")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) + strcpy(ifname, pch); + else { + ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__)); + return -1; + } + if (!strcmp(apsta_params->pif.dev->name, ifname)) { + cur_if = &apsta_params->pif; + } else if (!strcmp(apsta_params->vif.ifname, ifname)) { + cur_if = &apsta_params->vif; + } else { + ANDROID_ERROR(("%s: wrong ifname=%s in apstamode=%d\n", __FUNCTION__, + ifname, apsta_params->apstamode)); + return -1; + } + } else if (!strcmp(param, "ssid")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) + strcpy(cur_if->ssid, pch); + } else if (!strcmp(param, "bssid")) { + pch = bcmstrtok(&pick_tmp, ": ", 0); + for (i=0; i<6 && pch; i++) { + ((u8 *)&cur_if->bssid)[i] = (int)simple_strtol(pch, NULL, 16); + pch = bcmstrtok(&pick_tmp, ": ", 0); + } + } else if (!strcmp(param, "bgnmode")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) { + if (!strcmp(pch, "b")) + cur_if->bgnmode = IEEE80211B; + else if (!strcmp(pch, "g")) + cur_if->bgnmode = IEEE80211G; + else if (!strcmp(pch, "bg")) + cur_if->bgnmode = IEEE80211BG; + else if (!strcmp(pch, "bgn")) + cur_if->bgnmode = IEEE80211BGN; + else if (!strcmp(pch, "bgnac")) + cur_if->bgnmode = IEEE80211BGNAC; + else { + ANDROID_ERROR(("%s: bgnmode [b|g|bg|bgn|bgnac]\n", __FUNCTION__)); + return -1; + } + } + } else if (!strcmp(param, "hidden")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) { + if (!strcmp(pch, "n")) + cur_if->hidden = 0; + else if (!strcmp(pch, "y")) + cur_if->hidden = 1; + else { + ANDROID_ERROR(("%s: hidden [y|n]\n", __FUNCTION__)); + return -1; + } + } + } else if (!strcmp(param, "maxassoc")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) + cur_if->maxassoc = (int)simple_strtol(pch, NULL, 10); + } else if (!strcmp(param, "chan")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) + cur_if->channel = (int)simple_strtol(pch, NULL, 10); + } else if (!strcmp(param, "amode")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) { + if (!strcmp(pch, "open")) + cur_if->amode = AUTH_OPEN; + else if (!strcmp(pch, "shared")) + cur_if->amode = AUTH_SHARED; + else if (!strcmp(pch, "wpapsk")) + cur_if->amode = AUTH_WPAPSK; + else if (!strcmp(pch, "wpa2psk")) + cur_if->amode = AUTH_WPA2PSK; + else if (!strcmp(pch, "wpawpa2psk")) + cur_if->amode = AUTH_WPAWPA2PSK; + else { + ANDROID_ERROR(("%s: amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]\n", + __FUNCTION__)); + return -1; + } + } + } else if (!strcmp(param, "emode")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) { + if (!strcmp(pch, "none")) + cur_if->emode = ENC_NONE; + else if (!strcmp(pch, "wep")) + cur_if->emode = ENC_WEP; + else if (!strcmp(pch, "tkip")) + cur_if->emode = ENC_TKIP; + else if (!strcmp(pch, "aes")) + cur_if->emode = ENC_AES; + else if (!strcmp(pch, "tkipaes")) + cur_if->emode = ENC_TKIPAES; + else { + ANDROID_ERROR(("%s: emode [none|wep|tkip|aes|tkipaes]\n", + __FUNCTION__)); + return -1; + } + } + } else if (!strcmp(param, "key")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) { + strcpy(cur_if->key, pch); + } + } + param = bcmstrtok(&pick_tmp, " ", 0); + } + + return 0; +} + +static int +wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len) +{ + char *pch, *pick_tmp, *param; + s8 iovar_buf[WLC_IOCTL_SMLEN]; + wlc_ssid_t ssid = { 0, {0} }; + scb_val_t scbval; + struct { + s32 tmp; s32 cfg; s32 val; - } bss_setbuf; - struct wl_apsta_params *apsta_params = &g_apsta_params; - apstamode_t apstamode = apsta_params->apstamode; - char ifname[IFNAMSIZ+1]; - struct wl_if_info *cur_if; - struct dhd_pub *dhd; - - if (!apsta_params->init) { - ANDROID_ERROR(("%s: please init first\n", __FUNCTION__)); - return -1; - } - - ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); - dhd = dhd_get_pub(dev); - - pick_tmp = command; - param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_disable - param = bcmstrtok(&pick_tmp, " ", 0); - while (param != NULL) { - if (!strcmp(param, "ifname")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) - strcpy(ifname, pch); - else { - ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__)); - return -1; - } - } - param = bcmstrtok(&pick_tmp, " ", 0); - } - if (!strcmp(apsta_params->pif.dev->name, ifname)) { - cur_if = &apsta_params->pif; - } else if (!strcmp(apsta_params->vif.ifname, ifname)) { - cur_if = &apsta_params->vif; - } else { - ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname)); - return -1; - } - if (!cur_if->dev) { - ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname)); - return -1; - } - - if (cur_if->ifmode == ISTA_MODE) { - wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1); - } else if (cur_if->ifmode == IAP_MODE) { - // deauthenticate all STA first - memcpy(scbval.ea.octet, ðer_bcast, ETHER_ADDR_LEN); - wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1); - } - - if (apstamode == IAPONLY_MODE) { - wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); - wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); // reset ssid - wl_ext_iovar_setint(dev, "mpc", 1); - } else if ((apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) && - cur_if->ifmode == IAP_MODE) { - // vif is AP mode - bss_setbuf.tmp = 0xffffffff; - bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down - bss_setbuf.val = htod32(0); - wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf), - iovar_buf, WLC_IOCTL_SMLEN, NULL); - wl_ext_iovar_setint(dev, "mpc", 1); -#ifdef ARP_OFFLOAD_SUPPORT - /* IF SoftAP is disabled, enable arpoe back for STA mode. */ - dhd_arp_offload_set(dhd, dhd_arp_mode); - dhd_arp_offload_enable(dhd, TRUE); -#endif /* ARP_OFFLOAD_SUPPORT */ - } else if (apstamode == IDUALAP_MODE) { - bss_setbuf.tmp = 0xffffffff; - bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down - bss_setbuf.val = htod32(0); - wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf), - iovar_buf, WLC_IOCTL_SMLEN, NULL); - } - -#ifdef PROP_TXSTATUS_VSDB -#if defined(BCMSDIO) - if (cur_if==&apsta_params->vif && dhd->conf->disable_proptx!=0) { - bool enabled; - dhd_wlfc_get_enable(dhd, &enabled); - if (enabled) { - dhd_wlfc_deinit(dhd); - } - } -#endif -#endif /* PROP_TXSTATUS_VSDB */ - - cur_if->ifstate = IF_STATE_DISALBE; - printf("%s: apstamode=%d, ifname=%s\n", __FUNCTION__, apstamode, ifname); - - return 0; -} - -static int -wl_ext_iapsta_enable(struct net_device *dev, char *command, int total_len) -{ - int ret = 0; - s32 val = 0; - char *pch, *pick_tmp, *param; - s8 iovar_buf[WLC_IOCTL_SMLEN]; - wlc_ssid_t ssid = { 0, {0} }; - struct { + } bss_setbuf; + struct wl_apsta_params *apsta_params = &g_apsta_params; + apstamode_t apstamode = apsta_params->apstamode; + char ifname[IFNAMSIZ+1]; + struct wl_if_info *cur_if; + struct dhd_pub *dhd; + + if (!apsta_params->init) { + ANDROID_ERROR(("%s: please init first\n", __FUNCTION__)); + return -1; + } + + ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); + dhd = dhd_get_pub(dev); + + pick_tmp = command; + param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_disable + param = bcmstrtok(&pick_tmp, " ", 0); + while (param != NULL) { + if (!strcmp(param, "ifname")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) + strcpy(ifname, pch); + else { + ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__)); + return -1; + } + } + param = bcmstrtok(&pick_tmp, " ", 0); + } + if (!strcmp(apsta_params->pif.dev->name, ifname)) { + cur_if = &apsta_params->pif; + } else if (!strcmp(apsta_params->vif.ifname, ifname)) { + cur_if = &apsta_params->vif; + } else { + ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname)); + return -1; + } + if (!cur_if->dev) { + ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname)); + return -1; + } + + if (cur_if->ifmode == ISTA_MODE) { + wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1); + } else if (cur_if->ifmode == IAP_MODE) { + // deauthenticate all STA first + memcpy(scbval.ea.octet, ðer_bcast, ETHER_ADDR_LEN); + wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1); + } + + if (apstamode == IAPONLY_MODE) { + wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1); + wl_ext_ioctl(dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); // reset ssid + wl_ext_iovar_setint(dev, "mpc", 1); + } else if ((apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) && + cur_if->ifmode == IAP_MODE) { + // vif is AP mode + bss_setbuf.tmp = 0xffffffff; + bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down + bss_setbuf.val = htod32(0); + wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf), + iovar_buf, WLC_IOCTL_SMLEN, NULL); + wl_ext_iovar_setint(dev, "mpc", 1); +#ifdef ARP_OFFLOAD_SUPPORT + /* IF SoftAP is disabled, enable arpoe back for STA mode. */ + dhd_arp_offload_set(dhd, dhd_arp_mode); + dhd_arp_offload_enable(dhd, TRUE); +#endif /* ARP_OFFLOAD_SUPPORT */ + } else if (apstamode == IDUALAP_MODE) { + bss_setbuf.tmp = 0xffffffff; + bss_setbuf.cfg = 0; // must be 0, or wlan1 can not be down + bss_setbuf.val = htod32(0); + wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf), + iovar_buf, WLC_IOCTL_SMLEN, NULL); + } + +#ifdef PROP_TXSTATUS_VSDB +#if defined(BCMSDIO) + if (cur_if == &apsta_params->vif && dhd->conf->disable_proptx != 0) { + bool enabled; + dhd_wlfc_get_enable(dhd, &enabled); + if (enabled) { + dhd_wlfc_deinit(dhd); + } + } +#endif +#endif /* PROP_TXSTATUS_VSDB */ + + cur_if->ifstate = IF_STATE_DISALBE; + printf("%s: apstamode=%d, ifname=%s\n", __FUNCTION__, apstamode, ifname); + + return 0; +} + +static int +wl_ext_iapsta_enable(struct net_device *dev, char *command, int total_len) +{ + int ret = 0; + s32 val = 0; + char *pch, *pick_tmp, *param; + s8 iovar_buf[WLC_IOCTL_SMLEN]; + wlc_ssid_t ssid = { 0, {0} }; + struct { s32 cfg; s32 val; - } bss_setbuf; - struct wl_apsta_params *apsta_params = &g_apsta_params; - apstamode_t apstamode = apsta_params->apstamode; - char ifname[IFNAMSIZ+1]; - struct wl_if_info *cur_if; - char cmd[128] = "iapsta_stop ifname "; - struct dhd_pub *dhd; - - if (!apsta_params->init) { - ANDROID_ERROR(("%s: please init first\n", __FUNCTION__)); - return -1; - } - - ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); - dhd = dhd_get_pub(dev); - - pick_tmp = command; - param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_enable - param = bcmstrtok(&pick_tmp, " ", 0); - while (param != NULL) { - if (!strcmp(param, "ifname")) { - pch = bcmstrtok(&pick_tmp, " ", 0); - if (pch) - strcpy(ifname, pch); - else { - ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__)); - return -1; - } - } - param = bcmstrtok(&pick_tmp, " ", 0); - } - if (!strcmp(apsta_params->pif.dev->name, ifname)) { - cur_if = &apsta_params->pif; - } else if (!strcmp(apsta_params->vif.ifname, ifname)) { - cur_if = &apsta_params->vif; - } else { - ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname)); - return -1; - } - if (!cur_if->dev) { - ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname)); - return -1; - } - ssid.SSID_len = strlen(cur_if->ssid); - memcpy(ssid.SSID, cur_if->ssid, ssid.SSID_len); - ANDROID_TRACE(("%s: apstamode=%d, bssidx=%d\n", __FUNCTION__, apstamode, cur_if->bssidx)); - - snprintf(cmd, 128, "iapsta_stop ifname %s", cur_if->ifname); - ret = wl_ext_iapsta_disable(dev, cmd, strlen(cmd)); - if (ret) - goto exit; - - if (cur_if == &apsta_params->vif) { - wl_ext_iovar_setbuf(cur_if->dev, "cur_etheraddr", (u8 *)cur_if->dev->dev_addr, - ETHER_ADDR_LEN, iovar_buf, WLC_IOCTL_SMLEN, NULL); - } - - // set ssid for AP - if (cur_if->ifmode == IAP_MODE) { - wl_ext_iovar_setint(dev, "mpc", 0); - if (apstamode == IAPONLY_MODE) { - wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); - } else if (apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) { - wl_ext_iovar_setbuf_bsscfg(cur_if->dev, "ssid", &ssid, sizeof(ssid), - iovar_buf, WLC_IOCTL_SMLEN, cur_if->bssidx, NULL); - } - } - - if (cur_if->ifmode == IAP_MODE) { - wl_ext_set_bgnmode(cur_if); - wl_ext_set_chanspec(cur_if->dev, cur_if->channel); - } - wl_ext_set_amode(cur_if, apsta_params); - wl_ext_set_emode(cur_if, apsta_params); - - if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) { - if (!ETHER_ISBCAST(&cur_if->bssid) && !ETHER_ISNULLADDR(&cur_if->bssid)) { - printf("%s: BSSID: %pM\n", __FUNCTION__, &cur_if->bssid); - wl_ext_ioctl(cur_if->dev, WLC_SET_BSSID, &cur_if->bssid, ETHER_ADDR_LEN, 1); - } - val = 1; - wl_ext_ioctl(dev, WLC_SET_INFRA, &val, sizeof(val), 1); - } - if (cur_if->ifmode == IAP_MODE) { - if (cur_if->maxassoc >= 0) - wl_ext_iovar_setint(dev, "maxassoc", cur_if->maxassoc); - printf("%s: Broadcast SSID: %s\n", __FUNCTION__, cur_if->hidden ? "OFF":"ON"); - // terence: fix me, hidden does not work in dualAP mode - wl_ext_ioctl(cur_if->dev, WLC_SET_CLOSED, &cur_if->hidden, sizeof(cur_if->hidden), 1); - } - - if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) { - wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); - } else if (apstamode == IAPONLY_MODE) { - wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); - wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); - } else if (apstamode == IAPSTA_MODE || apstamode == IGOSTA_MODE) { - if (cur_if->ifmode == ISTA_MODE) { - wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); - } else { - if (FW_SUPPORTED(dhd, rsdb)) { - wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); - } else { - bss_setbuf.cfg = htod32(cur_if->bssidx); - bss_setbuf.val = htod32(1); - wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf), - iovar_buf, WLC_IOCTL_SMLEN, NULL); - } + } bss_setbuf; + struct wl_apsta_params *apsta_params = &g_apsta_params; + apstamode_t apstamode = apsta_params->apstamode; + char ifname[IFNAMSIZ+1]; + struct wl_if_info *cur_if; + char cmd[128] = "iapsta_stop ifname "; + struct dhd_pub *dhd; + + if (!apsta_params->init) { + ANDROID_ERROR(("%s: please init first\n", __FUNCTION__)); + return -1; + } + + ANDROID_TRACE(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len)); + dhd = dhd_get_pub(dev); + + pick_tmp = command; + param = bcmstrtok(&pick_tmp, " ", 0); // skip iapsta_enable + param = bcmstrtok(&pick_tmp, " ", 0); + while (param != NULL) { + if (!strcmp(param, "ifname")) { + pch = bcmstrtok(&pick_tmp, " ", 0); + if (pch) + strcpy(ifname, pch); + else { + ANDROID_ERROR(("%s: ifname [wlanX]\n", __FUNCTION__)); + return -1; + } + } + param = bcmstrtok(&pick_tmp, " ", 0); + } + if (!strcmp(apsta_params->pif.dev->name, ifname)) { + cur_if = &apsta_params->pif; + } else if (!strcmp(apsta_params->vif.ifname, ifname)) { + cur_if = &apsta_params->vif; + } else { + ANDROID_ERROR(("%s: wrong ifname=%s\n", __FUNCTION__, ifname)); + return -1; + } + if (!cur_if->dev) { + ANDROID_ERROR(("%s: %s is not ready\n", __FUNCTION__, ifname)); + return -1; + } + ssid.SSID_len = strlen(cur_if->ssid); + memcpy(ssid.SSID, cur_if->ssid, ssid.SSID_len); + ANDROID_TRACE(("%s: apstamode=%d, bssidx=%d\n", __FUNCTION__, apstamode, cur_if->bssidx)); + + snprintf(cmd, 128, "iapsta_stop ifname %s", cur_if->ifname); + ret = wl_ext_iapsta_disable(dev, cmd, strlen(cmd)); + if (ret) + goto exit; + + if (cur_if == &apsta_params->vif) { + wl_ext_iovar_setbuf(cur_if->dev, "cur_etheraddr", (u8 *)cur_if->dev->dev_addr, + ETHER_ADDR_LEN, iovar_buf, WLC_IOCTL_SMLEN, NULL); + } + + // set ssid for AP + if (cur_if->ifmode == IAP_MODE) { + wl_ext_iovar_setint(dev, "mpc", 0); + if (apstamode == IAPONLY_MODE) { + wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); + } else if (apstamode==IAPSTA_MODE || apstamode==IGOSTA_MODE) { + wl_ext_iovar_setbuf_bsscfg(cur_if->dev, "ssid", &ssid, sizeof(ssid), + iovar_buf, WLC_IOCTL_SMLEN, cur_if->bssidx, NULL); + } + } + + if (cur_if->ifmode == IAP_MODE) { + wl_ext_set_bgnmode(cur_if); + wl_ext_set_chanspec(cur_if->dev, cur_if->channel); + } + wl_ext_set_amode(cur_if, apsta_params); + wl_ext_set_emode(cur_if, apsta_params); + + if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) { + if (!ETHER_ISBCAST(&cur_if->bssid) && !ETHER_ISNULLADDR(&cur_if->bssid)) { + printf("%s: BSSID: %pM\n", __FUNCTION__, &cur_if->bssid); + wl_ext_ioctl(cur_if->dev, WLC_SET_BSSID, &cur_if->bssid, ETHER_ADDR_LEN, 1); + } + val = 1; + wl_ext_ioctl(dev, WLC_SET_INFRA, &val, sizeof(val), 1); + } + if (cur_if->ifmode == IAP_MODE) { + if (cur_if->maxassoc >= 0) + wl_ext_iovar_setint(dev, "maxassoc", cur_if->maxassoc); + printf("%s: Broadcast SSID: %s\n", __FUNCTION__, cur_if->hidden ? "OFF":"ON"); + // terence: fix me, hidden does not work in dualAP mode + wl_ext_ioctl(cur_if->dev, WLC_SET_CLOSED, &cur_if->hidden, sizeof(cur_if->hidden), 1); + } + + if (apstamode == ISTAONLY_MODE || apstamode == IGCSTA_MODE) { + wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); + } else if (apstamode == IAPONLY_MODE) { + wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); + wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); + } else if (apstamode == IAPSTA_MODE || apstamode == IGOSTA_MODE) { + if (cur_if->ifmode == ISTA_MODE) { + wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); + } else { + if (FW_SUPPORTED(dhd, rsdb)) { + wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); + } else { + bss_setbuf.cfg = htod32(cur_if->bssidx); + bss_setbuf.val = htod32(1); + wl_ext_iovar_setbuf(cur_if->dev, "bss", &bss_setbuf, sizeof(bss_setbuf), + iovar_buf, WLC_IOCTL_SMLEN, NULL); + } #ifdef ARP_OFFLOAD_SUPPORT - /* IF SoftAP is enabled, disable arpoe */ - dhd_arp_offload_set(dhd, 0); - dhd_arp_offload_enable(dhd, FALSE); -#endif /* ARP_OFFLOAD_SUPPORT */ - } - } - else if (apstamode == IDUALAP_MODE) { - wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); - } - -#ifdef PROP_TXSTATUS_VSDB -#if defined(BCMSDIO) - if (cur_if==&apsta_params->vif && !disable_proptx) { - bool enabled; - dhd_wlfc_get_enable(dhd, &enabled); - if (!enabled) { - dhd_wlfc_init(dhd); - wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); - } - } -#endif -#endif /* PROP_TXSTATUS_VSDB */ - - printf("%s: ifname=%s, SSID: %s\n", __FUNCTION__, ifname, cur_if->ssid); - - cur_if->ifstate = IF_STATE_ENABLE; - -exit: - return ret; -} - -void -wl_android_ext_iapsta_disconnect_sta(struct net_device *dev, u32 channel) -{ - struct wl_apsta_params *apsta_params = &g_apsta_params; - struct wl_if_info *cur_if = &apsta_params->vif; - scb_val_t scbval; - int ret; - channel_info_t ci; - struct dhd_pub *dhd; - - if (apsta_params->apstamode==IAPSTA_MODE && cur_if->ifstate==IF_STATE_ENABLE) { - dhd = dhd_get_pub(dev); - if (!FW_SUPPORTED(dhd, vsdb)) { - if (!(ret = wldev_ioctl(cur_if->dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) { - if (channel != ci.target_channel) { - printf("%s: deauthenticate all STA on vif\n", __FUNCTION__); - memcpy(scbval.ea.octet, ðer_bcast, ETHER_ADDR_LEN); - wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1); - } - } - } - } -} - -int wl_android_ext_attach_netdev(struct net_device *net, uint8 bssidx) -{ - g_apsta_params.vif.dev = net; - g_apsta_params.vif.bssidx = bssidx; - if (strlen(g_apsta_params.vif.ifname)) { - memset(net->name, 0, sizeof(IFNAMSIZ)); - strcpy(net->name, g_apsta_params.vif.ifname); - net->name[IFNAMSIZ - 1] = '\0'; - } - if (g_apsta_params.pif.dev) { - memcpy(net->dev_addr, g_apsta_params.pif.dev->dev_addr, ETHER_ADDR_LEN); - net->dev_addr[0] |= 0x02; - } - - return 0; -} - -int wl_android_ext_dettach_netdev(void) -{ - struct wl_apsta_params *apsta_params = &g_apsta_params; - - ANDROID_TRACE(("%s: Enter\n", __FUNCTION__)); - memset(apsta_params, 0, sizeof(struct wl_apsta_params)); - - return 0; -} -#endif - -#ifdef IDHCPC -int wl_ext_ip_dump(int ip, char *buf) -{ - unsigned char bytes[4]; - int bytes_written=-1; - - bytes[0] = ip & 0xFF; - bytes[1] = (ip >> 8) & 0xFF; - bytes[2] = (ip >> 16) & 0xFF; - bytes[3] = (ip >> 24) & 0xFF; - bytes_written = sprintf(buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]); - - return bytes_written; -} - -/* -terence 20170215: -dhd_priv dhcpc_dump ifname [wlan0|wlan1] -dhd_priv dhcpc_enable [0|1] -*/ -int -wl_ext_dhcpc_enable(struct net_device *dev, char *command, int total_len) -{ - int enable = -1, ret = -1; - int bytes_written = -1; - - ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command)); - - sscanf(command, "%*s %d", &enable); - - if (enable >= 0) - ret = wl_ext_iovar_setint(dev, "dhcpc_enable", enable); - else { - ret = wl_ext_iovar_getint(dev, "dhcpc_enable", &enable); - if (!ret) { - bytes_written = snprintf(command, total_len, "%d", enable); - ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); - ret = bytes_written; - } - } - - return ret; -} - -int -wl_ext_dhcpc_dump(struct net_device *dev, char *command, int total_len) -{ - - int ret = 0; - int bytes_written = 0; - uint32 ip_addr; - char buf[20]=""; - - ret = wl_ext_iovar_getint(dev, "dhcpc_ip_addr", &ip_addr); - if (!ret) { - wl_ext_ip_dump(ip_addr, buf); - bytes_written += snprintf(command+bytes_written, total_len, "ipaddr %s ", buf); - } - - ret = wl_ext_iovar_getint(dev, "dhcpc_ip_mask", &ip_addr); - if (!ret) { - wl_ext_ip_dump(ip_addr, buf); - bytes_written += snprintf(command+bytes_written, total_len, "mask %s ", buf); - } - - ret = wl_ext_iovar_getint(dev, "dhcpc_ip_gateway", &ip_addr); - if (!ret) { - wl_ext_ip_dump(ip_addr, buf); - bytes_written += snprintf(command+bytes_written, total_len, "gw %s ", buf); - } - - ret = wl_ext_iovar_getint(dev, "dhcpc_ip_dnsserv", &ip_addr); - if (!ret) { - wl_ext_ip_dump(ip_addr, buf); - bytes_written += snprintf(command+bytes_written, total_len, "dnsserv %s ", buf); - } - - if (!bytes_written) - bytes_written = -1; - - ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); - - return bytes_written; -} -#endif - -/* -dhd_priv dhd [string] ==> Not ready -1. Get dhd val: - Ex: dhd_priv dhd bussleep -2. Set dhd val: - Ex: dhd_priv dhd bussleep 1 - -dhd_priv wl [WLC_GET_PM] ==> Ready to get int val -dhd_priv wl [WLC_SET_PM] [int] ==> Ready to set int val -dhd_priv wl [string] ==> Ready to get int val -dhd_priv wl [string] [int] ==> Ready to set int val -Ex: get/set WLC_PM - dhd_priv wl 85 - dhd_priv wl 86 1 -Ex: get/set mpc - dhd_priv wl mpc - dhd_priv wl mpc 1 -*/ -int -wl_ext_iovar(struct net_device *dev, char *command, int total_len) -{ - int ret = 0; - char wl[3]="\0", arg[20]="\0", cmd_str[20]="\0", val_str[20]="\0"; - int cmd=-1, val=0; - int bytes_written=-1; - - ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command)); - - sscanf(command, "%s %d %s", wl, &cmd, arg); - if (cmd < 0) - sscanf(command, "%s %s %s", wl, cmd_str, val_str); - - if (!strcmp(wl, "wl")) { - if (cmd>=0 && cmd!=WLC_GET_VAR && cmd!=WLC_SET_VAR) { - ret = sscanf(arg, "%d", &val); - if (ret > 0) { // set - ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), TRUE); - } else { // get - ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), FALSE); - if (!ret) { - bytes_written = snprintf(command, total_len, "%d", val); - ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); - ret = bytes_written; - } - } - } else if (strlen(cmd_str)) { - ret = sscanf(val_str, "%d", &val); - if (ret > 0) { // set - ret = wl_ext_iovar_setint(dev, cmd_str, val); - } else { // get - ret = wl_ext_iovar_getint(dev, cmd_str, &val); - if (!ret) { - bytes_written = snprintf(command, total_len, "%d", val); - ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); - ret = bytes_written; - } - } - } - } - - return ret; -} - -int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len, - int *bytes_written) -{ - int ret = 0; - - if (strnicmp(command, CMD_CHANNELS, strlen(CMD_CHANNELS)) == 0) { - *bytes_written = wl_ext_channels(net, command, total_len); - } - else if (strnicmp(command, CMD_CHANNEL, strlen(CMD_CHANNEL)) == 0) { - *bytes_written = wl_ext_channel(net, command, total_len); - } - else if (strnicmp(command, CMD_ROAM_TRIGGER, strlen(CMD_ROAM_TRIGGER)) == 0) { - *bytes_written = wl_ext_roam_trigger(net, command, total_len); - } - else if (strnicmp(command, CMD_KEEP_ALIVE, strlen(CMD_KEEP_ALIVE)) == 0) { - *bytes_written = wl_ext_keep_alive(net, command, total_len); - } - else if (strnicmp(command, CMD_PM, strlen(CMD_PM)) == 0) { - *bytes_written = wl_ext_pm(net, command, total_len); - } + /* IF SoftAP is enabled, disable arpoe */ + dhd_arp_offload_set(dhd, 0); + dhd_arp_offload_enable(dhd, FALSE); +#endif /* ARP_OFFLOAD_SUPPORT */ + } + } + else if (apstamode == IDUALAP_MODE) { + wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1); + } + +#ifdef PROP_TXSTATUS_VSDB +#if defined(BCMSDIO) + if (cur_if == &apsta_params->vif && !disable_proptx) { + bool enabled; + dhd_wlfc_get_enable(dhd, &enabled); + if (!enabled) { + dhd_wlfc_init(dhd); + wl_ext_ioctl(dev, WLC_UP, NULL, 0, 1); + } + } +#endif +#endif /* PROP_TXSTATUS_VSDB */ + + printf("%s: ifname=%s, SSID: %s\n", __FUNCTION__, ifname, cur_if->ssid); + + cur_if->ifstate = IF_STATE_ENABLE; + +exit: + return ret; +} + +void +wl_android_ext_iapsta_disconnect_sta(struct net_device *dev, u32 channel) +{ + struct wl_apsta_params *apsta_params = &g_apsta_params; + struct wl_if_info *cur_if = &apsta_params->vif; + scb_val_t scbval; + int ret; + channel_info_t ci; + struct dhd_pub *dhd; + + if (apsta_params->apstamode == IAPSTA_MODE && cur_if->ifstate == IF_STATE_ENABLE) { + dhd = dhd_get_pub(dev); + if (!FW_SUPPORTED(dhd, vsdb)) { + if (!(ret = wldev_ioctl(cur_if->dev, WLC_GET_CHANNEL, &ci, sizeof(channel_info_t), FALSE))) { + if (channel != ci.target_channel) { + printf("%s: deauthenticate all STA on vif\n", __FUNCTION__); + memcpy(scbval.ea.octet, ðer_bcast, ETHER_ADDR_LEN); + wl_ext_ioctl(cur_if->dev, WLC_SCB_DEAUTHENTICATE, &scbval.ea, ETHER_ADDR_LEN, 1); + } + } + } + } +} + +int wl_android_ext_attach_netdev(struct net_device *net, uint8 bssidx) +{ + g_apsta_params.vif.dev = net; + g_apsta_params.vif.bssidx = bssidx; + if (strlen(g_apsta_params.vif.ifname)) { + memset(net->name, 0, sizeof(IFNAMSIZ)); + strcpy(net->name, g_apsta_params.vif.ifname); + net->name[IFNAMSIZ - 1] = '\0'; + } + if (g_apsta_params.pif.dev) { + memcpy(net->dev_addr, g_apsta_params.pif.dev->dev_addr, ETHER_ADDR_LEN); + net->dev_addr[0] |= 0x02; + } + + return 0; +} + +int wl_android_ext_dettach_netdev(void) +{ + struct wl_apsta_params *apsta_params = &g_apsta_params; + + ANDROID_TRACE(("%s: Enter\n", __FUNCTION__)); + memset(apsta_params, 0, sizeof(struct wl_apsta_params)); + + return 0; +} +#endif + +#ifdef IDHCP +int wl_ext_ip_dump(int ip, char *buf) +{ + unsigned char bytes[4]; + int bytes_written=-1; + + bytes[0] = ip & 0xFF; + bytes[1] = (ip >> 8) & 0xFF; + bytes[2] = (ip >> 16) & 0xFF; + bytes[3] = (ip >> 24) & 0xFF; + bytes_written = sprintf(buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]); + + return bytes_written; +} + +/* +terence 20170215: +dhd_priv dhcpc_dump ifname [wlan0|wlan1] +dhd_priv dhcpc_enable [0|1] +*/ +int +wl_ext_dhcpc_enable(struct net_device *dev, char *command, int total_len) +{ + int enable = -1, ret = -1; + int bytes_written = -1; + + ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command)); + + sscanf(command, "%*s %d", &enable); + + if (enable >= 0) + ret = wl_ext_iovar_setint(dev, "dhcpc_enable", enable); + else { + ret = wl_ext_iovar_getint(dev, "dhcpc_enable", &enable); + if (!ret) { + bytes_written = snprintf(command, total_len, "%d", enable); + ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); + ret = bytes_written; + } + } + + return ret; +} + +int +wl_ext_dhcpc_dump(struct net_device *dev, char *command, int total_len) +{ + + int ret = 0; + int bytes_written = 0; + uint32 ip_addr; + char buf[20]=""; + + ret = wl_ext_iovar_getint(dev, "dhcpc_ip_addr", &ip_addr); + if (!ret) { + wl_ext_ip_dump(ip_addr, buf); + bytes_written += snprintf(command+bytes_written, total_len, "ipaddr %s ", buf); + } + + ret = wl_ext_iovar_getint(dev, "dhcpc_ip_mask", &ip_addr); + if (!ret) { + wl_ext_ip_dump(ip_addr, buf); + bytes_written += snprintf(command+bytes_written, total_len, "mask %s ", buf); + } + + ret = wl_ext_iovar_getint(dev, "dhcpc_ip_gateway", &ip_addr); + if (!ret) { + wl_ext_ip_dump(ip_addr, buf); + bytes_written += snprintf(command+bytes_written, total_len, "gw %s ", buf); + } + + ret = wl_ext_iovar_getint(dev, "dhcpc_ip_dnsserv", &ip_addr); + if (!ret) { + wl_ext_ip_dump(ip_addr, buf); + bytes_written += snprintf(command+bytes_written, total_len, "dnsserv %s ", buf); + } + + if (!bytes_written) + bytes_written = -1; + + ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); + + return bytes_written; +} +#endif + +/* +dhd_priv dhd [string] ==> Not ready +1. Get dhd val: + Ex: dhd_priv dhd bussleep +2. Set dhd val: + Ex: dhd_priv dhd bussleep 1 + +dhd_priv wl [WLC_GET_PM] ==> Ready to get int val +dhd_priv wl [WLC_SET_PM] [int] ==> Ready to set int val +dhd_priv wl [string] ==> Ready to get int val +dhd_priv wl [string] [int] ==> Ready to set int val +Ex: get/set WLC_PM + dhd_priv wl 85 + dhd_priv wl 86 1 +Ex: get/set mpc + dhd_priv wl mpc + dhd_priv wl mpc 1 +*/ +int +wl_ext_iovar(struct net_device *dev, char *command, int total_len) +{ + int ret = 0; + char wl[3]="\0", arg[20]="\0", cmd_str[20]="\0", val_str[20]="\0"; + int cmd=-1, val=0; + int bytes_written=-1; + + ANDROID_TRACE(("%s: cmd %s\n", __FUNCTION__, command)); + + sscanf(command, "%s %d %s", wl, &cmd, arg); + if (cmd < 0) + sscanf(command, "%s %s %s", wl, cmd_str, val_str); + + if (!strcmp(wl, "wl")) { + if (cmd >= 0 && cmd != WLC_GET_VAR && cmd != WLC_SET_VAR) { + ret = sscanf(arg, "%d", &val); + if (ret > 0) { // set + ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), TRUE); + } else { // get + ret = wl_ext_ioctl(dev, cmd, &val, sizeof(val), FALSE); + if (!ret) { + bytes_written = snprintf(command, total_len, "%d", val); + ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); + ret = bytes_written; + } + } + } else if (strlen(cmd_str)) { + ret = sscanf(val_str, "%d", &val); + if (ret > 0) { // set + ret = wl_ext_iovar_setint(dev, cmd_str, val); + } else { // get + ret = wl_ext_iovar_getint(dev, cmd_str, &val); + if (!ret) { + bytes_written = snprintf(command, total_len, "%d", val); + ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command)); + ret = bytes_written; + } + } + } + } + + return ret; +} + +int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len, + int *bytes_written) +{ + int ret = 0; + + if (strnicmp(command, CMD_CHANNELS, strlen(CMD_CHANNELS)) == 0) { + *bytes_written = wl_ext_channels(net, command, total_len); + } + else if (strnicmp(command, CMD_CHANNEL, strlen(CMD_CHANNEL)) == 0) { + *bytes_written = wl_ext_channel(net, command, total_len); + } + else if (strnicmp(command, CMD_ROAM_TRIGGER, strlen(CMD_ROAM_TRIGGER)) == 0) { + *bytes_written = wl_ext_roam_trigger(net, command, total_len); + } + else if (strnicmp(command, CMD_KEEP_ALIVE, strlen(CMD_KEEP_ALIVE)) == 0) { + *bytes_written = wl_ext_keep_alive(net, command, total_len); + } + else if (strnicmp(command, CMD_PM, strlen(CMD_PM)) == 0) { + *bytes_written = wl_ext_pm(net, command, total_len); + } else if (strnicmp(command, CMD_MONITOR, strlen(CMD_MONITOR)) == 0) { - *bytes_written = wl_ext_monitor(net, command, total_len); - } - else if (strnicmp(command, CMD_SET_SUSPEND_BCN_LI_DTIM, strlen(CMD_SET_SUSPEND_BCN_LI_DTIM)) == 0) { - int bcn_li_dtim; - bcn_li_dtim = (int)simple_strtol((command + strlen(CMD_SET_SUSPEND_BCN_LI_DTIM) + 1), NULL, 10); - *bytes_written = net_os_set_suspend_bcn_li_dtim(net, bcn_li_dtim); - } -#ifdef WL_EXT_IAPSTA - else if (strnicmp(command, CMD_IAPSTA_INIT, strlen(CMD_IAPSTA_INIT)) == 0) { - *bytes_written = wl_ext_iapsta_init(net, command, total_len); - } - else if (strnicmp(command, CMD_IAPSTA_CONFIG, strlen(CMD_IAPSTA_CONFIG)) == 0) { - *bytes_written = wl_ext_iapsta_config(net, command, total_len); - } - else if (strnicmp(command, CMD_IAPSTA_ENABLE, strlen(CMD_IAPSTA_ENABLE)) == 0) { - *bytes_written = wl_ext_iapsta_enable(net, command, total_len); - } - else if (strnicmp(command, CMD_IAPSTA_DISABLE, strlen(CMD_IAPSTA_DISABLE)) == 0) { - *bytes_written = wl_ext_iapsta_disable(net, command, total_len); - } -#endif -#ifdef IDHCPC - else if (strnicmp(command, CMD_DHCPC_ENABLE, strlen(CMD_DHCPC_ENABLE)) == 0) { - *bytes_written = wl_ext_dhcpc_enable(net, command, total_len); - } - else if (strnicmp(command, CMD_DHCPC_DUMP, strlen(CMD_DHCPC_DUMP)) == 0) { - *bytes_written = wl_ext_dhcpc_dump(net, command, total_len); - } -#endif - else if (strnicmp(command, CMD_WL, strlen(CMD_WL)) == 0) { - *bytes_written = wl_ext_iovar(net, command, total_len); - } - else - ret = -1; - - return ret; -} - -#if defined(RSSIAVG) -void -wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl) -{ - wl_rssi_cache_t *node, *cur, **rssi_head; - int i=0; - - rssi_head = &rssi_cache_ctrl->m_cache_head; - node = *rssi_head; - - for (;node;) { - ANDROID_INFO(("%s: Free %d with BSSID %pM\n", - __FUNCTION__, i, &node->BSSID)); - cur = node; - node = cur->next; - kfree(cur); - i++; - } - *rssi_head = NULL; -} - -void -wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl) -{ - wl_rssi_cache_t *node, *prev, **rssi_head; - int i = -1, tmp = 0; - struct timeval now; - - do_gettimeofday(&now); - - rssi_head = &rssi_cache_ctrl->m_cache_head; - node = *rssi_head; - prev = node; - for (;node;) { - i++; - if (now.tv_sec > node->tv.tv_sec) { - if (node == *rssi_head) { - tmp = 1; - *rssi_head = node->next; - } else { - tmp = 0; - prev->next = node->next; - } - ANDROID_INFO(("%s: Del %d with BSSID %pM\n", - __FUNCTION__, i, &node->BSSID)); - kfree(node); - if (tmp == 1) { - node = *rssi_head; - prev = node; - } else { - node = prev->next; - } - continue; - } - prev = node; - node = node->next; - } -} - -void -wl_delete_disconnected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, u8 *bssid) -{ - wl_rssi_cache_t *node, *prev, **rssi_head; - int i = -1, tmp = 0; - - rssi_head = &rssi_cache_ctrl->m_cache_head; - node = *rssi_head; - prev = node; - for (;node;) { - i++; - if (!memcmp(&node->BSSID, bssid, ETHER_ADDR_LEN)) { - if (node == *rssi_head) { - tmp = 1; - *rssi_head = node->next; - } else { - tmp = 0; - prev->next = node->next; - } - ANDROID_INFO(("%s: Del %d with BSSID %pM\n", - __FUNCTION__, i, &node->BSSID)); - kfree(node); - if (tmp == 1) { - node = *rssi_head; - prev = node; - } else { - node = prev->next; - } - continue; - } - prev = node; - node = node->next; - } -} - -void -wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl) -{ - wl_rssi_cache_t *node, **rssi_head; - - rssi_head = &rssi_cache_ctrl->m_cache_head; - - /* reset dirty */ - node = *rssi_head; - for (;node;) { - node->dirty += 1; - node = node->next; - } -} - -int -wl_update_connected_rssi_cache(struct net_device *net, wl_rssi_cache_ctrl_t *rssi_cache_ctrl, int *rssi_avg) -{ - wl_rssi_cache_t *node, *prev, *leaf, **rssi_head; - int j, k=0; - int rssi, error=0; - struct ether_addr bssid; - struct timeval now, timeout; - - if (!g_wifi_on) - return 0; - - error = wldev_ioctl(net, WLC_GET_BSSID, &bssid, sizeof(bssid), false); - if (error == BCME_NOTASSOCIATED) { - ANDROID_INFO(("%s: Not Associated! res:%d\n", __FUNCTION__, error)); - return 0; - } - if (error) { - ANDROID_ERROR(("Could not get bssid (%d)\n", error)); - } - error = wldev_get_rssi(net, &rssi); - if (error) { - ANDROID_ERROR(("Could not get rssi (%d)\n", error)); - return error; - } - - do_gettimeofday(&now); - timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT; - if (timeout.tv_sec < now.tv_sec) { - /* - * Integer overflow - assume long enough timeout to be assumed - * to be infinite, i.e., the timeout would never happen. - */ - ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu", - __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec)); - } - - /* update RSSI */ - rssi_head = &rssi_cache_ctrl->m_cache_head; - node = *rssi_head; - prev = NULL; - for (;node;) { - if (!memcmp(&node->BSSID, &bssid, ETHER_ADDR_LEN)) { - ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%d\n", - __FUNCTION__, k, &bssid, rssi)); - for (j=0; jRSSI[j] = node->RSSI[j+1]; - node->RSSI[j] = rssi; - node->dirty = 0; - node->tv = timeout; - goto exit; - } - prev = node; - node = node->next; - k++; - } - - leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL); - if (!leaf) { - ANDROID_ERROR(("%s: Memory alloc failure %d\n", - __FUNCTION__, (int)sizeof(wl_rssi_cache_t))); - return 0; - } - ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d in the leaf\n", - __FUNCTION__, k, &bssid, rssi)); - - leaf->next = NULL; - leaf->dirty = 0; - leaf->tv = timeout; - memcpy(&leaf->BSSID, &bssid, ETHER_ADDR_LEN); - for (j=0; jRSSI[j] = rssi; - - if (!prev) - *rssi_head = leaf; - else - prev->next = leaf; - -exit: - *rssi_avg = (int)wl_get_avg_rssi(rssi_cache_ctrl, &bssid); - - return error; -} - -void -wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list) -{ - wl_rssi_cache_t *node, *prev, *leaf, **rssi_head; - wl_bss_info_t *bi = NULL; - int i, j, k; - struct timeval now, timeout; - - if (!ss_list->count) - return; - - do_gettimeofday(&now); - timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT; - if (timeout.tv_sec < now.tv_sec) { - /* - * Integer overflow - assume long enough timeout to be assumed - * to be infinite, i.e., the timeout would never happen. - */ - ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu", - __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec)); - } - - rssi_head = &rssi_cache_ctrl->m_cache_head; - - /* update RSSI */ - for (i = 0; i < ss_list->count; i++) { - node = *rssi_head; - prev = NULL; - k = 0; - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info; - for (;node;) { - if (!memcmp(&node->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) { - ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n", - __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID)); - for (j=0; jRSSI[j] = node->RSSI[j+1]; - node->RSSI[j] = dtoh16(bi->RSSI); - node->dirty = 0; - node->tv = timeout; - break; - } - prev = node; - node = node->next; - k++; - } - - if (node) - continue; - - leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL); - if (!leaf) { - ANDROID_ERROR(("%s: Memory alloc failure %d\n", - __FUNCTION__, (int)sizeof(wl_rssi_cache_t))); - return; - } - ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\" in the leaf\n", - __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID)); - - leaf->next = NULL; - leaf->dirty = 0; - leaf->tv = timeout; - memcpy(&leaf->BSSID, &bi->BSSID, ETHER_ADDR_LEN); - for (j=0; jRSSI[j] = dtoh16(bi->RSSI); - - if (!prev) - *rssi_head = leaf; - else - prev->next = leaf; - } -} - -int16 -wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr) -{ - wl_rssi_cache_t *node, **rssi_head; - int j, rssi_sum, rssi=RSSI_MINVAL; - - rssi_head = &rssi_cache_ctrl->m_cache_head; - - node = *rssi_head; - for (;node;) { - if (!memcmp(&node->BSSID, addr, ETHER_ADDR_LEN)) { - rssi_sum = 0; - rssi = 0; - for (j=0; jRSSI[RSSIAVG_LEN-j-1]; - rssi = rssi_sum / j; - break; - } - node = node->next; - } - rssi = MIN(rssi, RSSI_MAXVAL); - if (rssi == RSSI_MINVAL) { - ANDROID_ERROR(("%s: BSSID %pM does not in RSSI cache\n", - __FUNCTION__, addr)); - } - return (int16)rssi; -} -#endif - -#if defined(RSSIOFFSET) -int -wl_update_rssi_offset(struct net_device *net, int rssi) -{ -#if defined(RSSIOFFSET_NEW) - int j; -#endif - - if (!g_wifi_on) - return rssi; - -#if defined(RSSIOFFSET_NEW) - for (j=0; jm_cache_head; - node = *bss_head; - - for (;node;) { - ANDROID_TRACE(("%s: Free %d with BSSID %pM\n", - __FUNCTION__, i, &node->results.bss_info->BSSID)); - cur = node; - node = cur->next; - kfree(cur); - i++; - } - *bss_head = NULL; -} - -void -wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl) -{ - wl_bss_cache_t *node, *prev, **bss_head; - int i = -1, tmp = 0; - struct timeval now; - - do_gettimeofday(&now); - - bss_head = &bss_cache_ctrl->m_cache_head; - node = *bss_head; - prev = node; - for (;node;) { - i++; - if (now.tv_sec > node->tv.tv_sec) { - if (node == *bss_head) { - tmp = 1; - *bss_head = node->next; - } else { - tmp = 0; - prev->next = node->next; - } - ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n", - __FUNCTION__, i, &node->results.bss_info->BSSID, - dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID)); - kfree(node); - if (tmp == 1) { - node = *bss_head; - prev = node; - } else { - node = prev->next; - } - continue; - } - prev = node; - node = node->next; - } -} - -void -wl_delete_disconnected_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, u8 *bssid) -{ - wl_bss_cache_t *node, *prev, **bss_head; - int i = -1, tmp = 0; - - bss_head = &bss_cache_ctrl->m_cache_head; - node = *bss_head; - prev = node; - for (;node;) { - i++; - if (!memcmp(&node->results.bss_info->BSSID, bssid, ETHER_ADDR_LEN)) { - if (node == *bss_head) { - tmp = 1; - *bss_head = node->next; - } else { - tmp = 0; - prev->next = node->next; - } - ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n", - __FUNCTION__, i, &node->results.bss_info->BSSID, - dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID)); - kfree(node); - if (tmp == 1) { - node = *bss_head; - prev = node; - } else { - node = prev->next; - } - continue; - } - prev = node; - node = node->next; - } -} - -void -wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl) -{ - wl_bss_cache_t *node, **bss_head; - - bss_head = &bss_cache_ctrl->m_cache_head; - - /* reset dirty */ - node = *bss_head; - for (;node;) { - node->dirty += 1; - node = node->next; - } -} - -void dump_bss_cache( -#if defined(RSSIAVG) - wl_rssi_cache_ctrl_t *rssi_cache_ctrl, -#endif - wl_bss_cache_t *node) -{ - int k = 0; - int16 rssi; - - for (;node;) { -#if defined(RSSIAVG) - rssi = wl_get_avg_rssi(rssi_cache_ctrl, &node->results.bss_info->BSSID); -#else - rssi = dtoh16(node->results.bss_info->RSSI); -#endif - ANDROID_TRACE(("%s: dump %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n", - __FUNCTION__, k, &node->results.bss_info->BSSID, rssi, node->results.bss_info->SSID)); - k++; - node = node->next; - } -} - -void -wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, -#if defined(RSSIAVG) - wl_rssi_cache_ctrl_t *rssi_cache_ctrl, -#endif - wl_scan_results_t *ss_list) -{ - wl_bss_cache_t *node, *prev, *leaf, **bss_head; - wl_bss_info_t *bi = NULL; - int i, k=0; -#if defined(SORT_BSS_BY_RSSI) - int16 rssi, rssi_node; -#endif - struct timeval now, timeout; - - if (!ss_list->count) - return; - - do_gettimeofday(&now); - timeout.tv_sec = now.tv_sec + BSSCACHE_TIMEOUT; - if (timeout.tv_sec < now.tv_sec) { - /* - * Integer overflow - assume long enough timeout to be assumed - * to be infinite, i.e., the timeout would never happen. - */ - ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu", - __FUNCTION__, BSSCACHE_TIMEOUT, now.tv_sec, timeout.tv_sec)); - } - - bss_head = &bss_cache_ctrl->m_cache_head; - - for (i=0; i < ss_list->count; i++) { - node = *bss_head; - prev = NULL; - bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info; - - for (;node;) { - if (!memcmp(&node->results.bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) { - if (node == *bss_head) - *bss_head = node->next; - else { - prev->next = node->next; - } - break; - } - prev = node; - node = node->next; - } - - leaf = kmalloc(dtoh32(bi->length) + sizeof(wl_bss_cache_t), GFP_KERNEL); - if (!leaf) { - ANDROID_ERROR(("%s: Memory alloc failure %d\n", __FUNCTION__, - dtoh32(bi->length) + (int)sizeof(wl_bss_cache_t))); - return; - } - if (node) { - kfree(node); - node = NULL; - ANDROID_TRACE(("%s: Update %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n", - __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID)); - } else - ANDROID_TRACE(("%s: Add %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n", - __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID)); - - memcpy(leaf->results.bss_info, bi, dtoh32(bi->length)); - leaf->next = NULL; - leaf->dirty = 0; - leaf->tv = timeout; - leaf->results.count = 1; - leaf->results.version = ss_list->version; - k++; - - if (*bss_head == NULL) - *bss_head = leaf; - else { -#if defined(SORT_BSS_BY_RSSI) - node = *bss_head; -#if defined(RSSIAVG) - rssi = wl_get_avg_rssi(rssi_cache_ctrl, &leaf->results.bss_info->BSSID); -#else - rssi = dtoh16(leaf->results.bss_info->RSSI); -#endif - for (;node;) { -#if defined(RSSIAVG) - rssi_node = wl_get_avg_rssi(rssi_cache_ctrl, &node->results.bss_info->BSSID); -#else - rssi_node = dtoh16(node->results.bss_info->RSSI); -#endif - if (rssi > rssi_node) { - leaf->next = node; - if (node == *bss_head) - *bss_head = leaf; - else - prev->next = leaf; - break; - } - prev = node; - node = node->next; - } - if (node == NULL) - prev->next = leaf; -#else - leaf->next = *bss_head; - *bss_head = leaf; -#endif - } - } - dump_bss_cache( -#if defined(RSSIAVG) - rssi_cache_ctrl, -#endif - *bss_head); -} - -void -wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl) -{ - ANDROID_TRACE(("%s:\n", __FUNCTION__)); - wl_free_bss_cache(bss_cache_ctrl); -} -#endif - - + *bytes_written = wl_ext_monitor(net, command, total_len); + } + else if (strnicmp(command, CMD_SET_SUSPEND_BCN_LI_DTIM, strlen(CMD_SET_SUSPEND_BCN_LI_DTIM)) == 0) { + int bcn_li_dtim; + bcn_li_dtim = (int)simple_strtol((command + strlen(CMD_SET_SUSPEND_BCN_LI_DTIM) + 1), NULL, 10); + *bytes_written = net_os_set_suspend_bcn_li_dtim(net, bcn_li_dtim); + } +#ifdef WL_EXT_IAPSTA + else if (strnicmp(command, CMD_IAPSTA_INIT, strlen(CMD_IAPSTA_INIT)) == 0) { + *bytes_written = wl_ext_iapsta_init(net, command, total_len); + } + else if (strnicmp(command, CMD_IAPSTA_CONFIG, strlen(CMD_IAPSTA_CONFIG)) == 0) { + *bytes_written = wl_ext_iapsta_config(net, command, total_len); + } + else if (strnicmp(command, CMD_IAPSTA_ENABLE, strlen(CMD_IAPSTA_ENABLE)) == 0) { + *bytes_written = wl_ext_iapsta_enable(net, command, total_len); + } + else if (strnicmp(command, CMD_IAPSTA_DISABLE, strlen(CMD_IAPSTA_DISABLE)) == 0) { + *bytes_written = wl_ext_iapsta_disable(net, command, total_len); + } +#endif +#ifdef IDHCP + else if (strnicmp(command, CMD_DHCPC_ENABLE, strlen(CMD_DHCPC_ENABLE)) == 0) { + *bytes_written = wl_ext_dhcpc_enable(net, command, total_len); + } + else if (strnicmp(command, CMD_DHCPC_DUMP, strlen(CMD_DHCPC_DUMP)) == 0) { + *bytes_written = wl_ext_dhcpc_dump(net, command, total_len); + } +#endif + else if (strnicmp(command, CMD_WL, strlen(CMD_WL)) == 0) { + *bytes_written = wl_ext_iovar(net, command, total_len); + } + else + ret = -1; + + return ret; +} + +#if defined(RSSIAVG) +void +wl_free_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl) +{ + wl_rssi_cache_t *node, *cur, **rssi_head; + int i=0; + + rssi_head = &rssi_cache_ctrl->m_cache_head; + node = *rssi_head; + + for (;node;) { + ANDROID_INFO(("%s: Free %d with BSSID %pM\n", + __FUNCTION__, i, &node->BSSID)); + cur = node; + node = cur->next; + kfree(cur); + i++; + } + *rssi_head = NULL; +} + +void +wl_delete_dirty_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl) +{ + wl_rssi_cache_t *node, *prev, **rssi_head; + int i = -1, tmp = 0; + struct timeval now; + + do_gettimeofday(&now); + + rssi_head = &rssi_cache_ctrl->m_cache_head; + node = *rssi_head; + prev = node; + for (;node;) { + i++; + if (now.tv_sec > node->tv.tv_sec) { + if (node == *rssi_head) { + tmp = 1; + *rssi_head = node->next; + } else { + tmp = 0; + prev->next = node->next; + } + ANDROID_INFO(("%s: Del %d with BSSID %pM\n", + __FUNCTION__, i, &node->BSSID)); + kfree(node); + if (tmp == 1) { + node = *rssi_head; + prev = node; + } else { + node = prev->next; + } + continue; + } + prev = node; + node = node->next; + } +} + +void +wl_delete_disconnected_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, u8 *bssid) +{ + wl_rssi_cache_t *node, *prev, **rssi_head; + int i = -1, tmp = 0; + + rssi_head = &rssi_cache_ctrl->m_cache_head; + node = *rssi_head; + prev = node; + for (;node;) { + i++; + if (!memcmp(&node->BSSID, bssid, ETHER_ADDR_LEN)) { + if (node == *rssi_head) { + tmp = 1; + *rssi_head = node->next; + } else { + tmp = 0; + prev->next = node->next; + } + ANDROID_INFO(("%s: Del %d with BSSID %pM\n", + __FUNCTION__, i, &node->BSSID)); + kfree(node); + if (tmp == 1) { + node = *rssi_head; + prev = node; + } else { + node = prev->next; + } + continue; + } + prev = node; + node = node->next; + } +} + +void +wl_reset_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl) +{ + wl_rssi_cache_t *node, **rssi_head; + + rssi_head = &rssi_cache_ctrl->m_cache_head; + + /* reset dirty */ + node = *rssi_head; + for (;node;) { + node->dirty += 1; + node = node->next; + } +} + +int +wl_update_connected_rssi_cache(struct net_device *net, wl_rssi_cache_ctrl_t *rssi_cache_ctrl, int *rssi_avg) +{ + wl_rssi_cache_t *node, *prev, *leaf, **rssi_head; + int j, k=0; + int rssi, error=0; + struct ether_addr bssid; + struct timeval now, timeout; + + if (!g_wifi_on) + return 0; + + error = wldev_ioctl(net, WLC_GET_BSSID, &bssid, sizeof(bssid), false); + if (error == BCME_NOTASSOCIATED) { + ANDROID_INFO(("%s: Not Associated! res:%d\n", __FUNCTION__, error)); + return 0; + } + if (error) { + ANDROID_ERROR(("Could not get bssid (%d)\n", error)); + } + error = wldev_get_rssi(net, &rssi); + if (error) { + ANDROID_ERROR(("Could not get rssi (%d)\n", error)); + return error; + } + + do_gettimeofday(&now); + timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT; + if (timeout.tv_sec < now.tv_sec) { + /* + * Integer overflow - assume long enough timeout to be assumed + * to be infinite, i.e., the timeout would never happen. + */ + ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu", + __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec)); + } + + /* update RSSI */ + rssi_head = &rssi_cache_ctrl->m_cache_head; + node = *rssi_head; + prev = NULL; + for (;node;) { + if (!memcmp(&node->BSSID, &bssid, ETHER_ADDR_LEN)) { + ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%d\n", + __FUNCTION__, k, &bssid, rssi)); + for (j=0; jRSSI[j] = node->RSSI[j+1]; + node->RSSI[j] = rssi; + node->dirty = 0; + node->tv = timeout; + goto exit; + } + prev = node; + node = node->next; + k++; + } + + leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL); + if (!leaf) { + ANDROID_ERROR(("%s: Memory alloc failure %d\n", + __FUNCTION__, (int)sizeof(wl_rssi_cache_t))); + return 0; + } + ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d in the leaf\n", + __FUNCTION__, k, &bssid, rssi)); + + leaf->next = NULL; + leaf->dirty = 0; + leaf->tv = timeout; + memcpy(&leaf->BSSID, &bssid, ETHER_ADDR_LEN); + for (j=0; jRSSI[j] = rssi; + + if (!prev) + *rssi_head = leaf; + else + prev->next = leaf; + +exit: + *rssi_avg = (int)wl_get_avg_rssi(rssi_cache_ctrl, &bssid); + + return error; +} + +void +wl_update_rssi_cache(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, wl_scan_results_t *ss_list) +{ + wl_rssi_cache_t *node, *prev, *leaf, **rssi_head; + wl_bss_info_t *bi = NULL; + int i, j, k; + struct timeval now, timeout; + + if (!ss_list->count) + return; + + do_gettimeofday(&now); + timeout.tv_sec = now.tv_sec + RSSICACHE_TIMEOUT; + if (timeout.tv_sec < now.tv_sec) { + /* + * Integer overflow - assume long enough timeout to be assumed + * to be infinite, i.e., the timeout would never happen. + */ + ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu", + __FUNCTION__, RSSICACHE_TIMEOUT, now.tv_sec, timeout.tv_sec)); + } + + rssi_head = &rssi_cache_ctrl->m_cache_head; + + /* update RSSI */ + for (i = 0; i < ss_list->count; i++) { + node = *rssi_head; + prev = NULL; + k = 0; + bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info; + for (;node;) { + if (!memcmp(&node->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) { + ANDROID_INFO(("%s: Update %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n", + __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID)); + for (j=0; jRSSI[j] = node->RSSI[j+1]; + node->RSSI[j] = dtoh16(bi->RSSI); + node->dirty = 0; + node->tv = timeout; + break; + } + prev = node; + node = node->next; + k++; + } + + if (node) + continue; + + leaf = kmalloc(sizeof(wl_rssi_cache_t), GFP_KERNEL); + if (!leaf) { + ANDROID_ERROR(("%s: Memory alloc failure %d\n", + __FUNCTION__, (int)sizeof(wl_rssi_cache_t))); + return; + } + ANDROID_INFO(("%s: Add %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\" in the leaf\n", + __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID)); + + leaf->next = NULL; + leaf->dirty = 0; + leaf->tv = timeout; + memcpy(&leaf->BSSID, &bi->BSSID, ETHER_ADDR_LEN); + for (j=0; jRSSI[j] = dtoh16(bi->RSSI); + + if (!prev) + *rssi_head = leaf; + else + prev->next = leaf; + } +} + +int16 +wl_get_avg_rssi(wl_rssi_cache_ctrl_t *rssi_cache_ctrl, void *addr) +{ + wl_rssi_cache_t *node, **rssi_head; + int j, rssi_sum, rssi=RSSI_MINVAL; + + rssi_head = &rssi_cache_ctrl->m_cache_head; + + node = *rssi_head; + for (;node;) { + if (!memcmp(&node->BSSID, addr, ETHER_ADDR_LEN)) { + rssi_sum = 0; + rssi = 0; + for (j=0; jRSSI[RSSIAVG_LEN-j-1]; + rssi = rssi_sum / j; + break; + } + node = node->next; + } + rssi = MIN(rssi, RSSI_MAXVAL); + if (rssi == RSSI_MINVAL) { + ANDROID_ERROR(("%s: BSSID %pM does not in RSSI cache\n", + __FUNCTION__, addr)); + } + return (int16)rssi; +} +#endif + +#if defined(RSSIOFFSET) +int +wl_update_rssi_offset(struct net_device *net, int rssi) +{ +#if defined(RSSIOFFSET_NEW) + int j; +#endif + + if (!g_wifi_on) + return rssi; + +#if defined(RSSIOFFSET_NEW) + for (j=0; jm_cache_head; + node = *bss_head; + + for (;node;) { + ANDROID_TRACE(("%s: Free %d with BSSID %pM\n", + __FUNCTION__, i, &node->results.bss_info->BSSID)); + cur = node; + node = cur->next; + kfree(cur); + i++; + } + *bss_head = NULL; +} + +void +wl_delete_dirty_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl) +{ + wl_bss_cache_t *node, *prev, **bss_head; + int i = -1, tmp = 0; + struct timeval now; + + do_gettimeofday(&now); + + bss_head = &bss_cache_ctrl->m_cache_head; + node = *bss_head; + prev = node; + for (;node;) { + i++; + if (now.tv_sec > node->tv.tv_sec) { + if (node == *bss_head) { + tmp = 1; + *bss_head = node->next; + } else { + tmp = 0; + prev->next = node->next; + } + ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n", + __FUNCTION__, i, &node->results.bss_info->BSSID, + dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID)); + kfree(node); + if (tmp == 1) { + node = *bss_head; + prev = node; + } else { + node = prev->next; + } + continue; + } + prev = node; + node = node->next; + } +} + +void +wl_delete_disconnected_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, u8 *bssid) +{ + wl_bss_cache_t *node, *prev, **bss_head; + int i = -1, tmp = 0; + + bss_head = &bss_cache_ctrl->m_cache_head; + node = *bss_head; + prev = node; + for (;node;) { + i++; + if (!memcmp(&node->results.bss_info->BSSID, bssid, ETHER_ADDR_LEN)) { + if (node == *bss_head) { + tmp = 1; + *bss_head = node->next; + } else { + tmp = 0; + prev->next = node->next; + } + ANDROID_TRACE(("%s: Del %d with BSSID %pM, RSSI=%3d, SSID \"%s\"\n", + __FUNCTION__, i, &node->results.bss_info->BSSID, + dtoh16(node->results.bss_info->RSSI), node->results.bss_info->SSID)); + kfree(node); + if (tmp == 1) { + node = *bss_head; + prev = node; + } else { + node = prev->next; + } + continue; + } + prev = node; + node = node->next; + } +} + +void +wl_reset_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl) +{ + wl_bss_cache_t *node, **bss_head; + + bss_head = &bss_cache_ctrl->m_cache_head; + + /* reset dirty */ + node = *bss_head; + for (;node;) { + node->dirty += 1; + node = node->next; + } +} + +void dump_bss_cache( +#if defined(RSSIAVG) + wl_rssi_cache_ctrl_t *rssi_cache_ctrl, +#endif + wl_bss_cache_t *node) +{ + int k = 0; + int16 rssi; + + for (;node;) { +#if defined(RSSIAVG) + rssi = wl_get_avg_rssi(rssi_cache_ctrl, &node->results.bss_info->BSSID); +#else + rssi = dtoh16(node->results.bss_info->RSSI); +#endif + ANDROID_TRACE(("%s: dump %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n", + __FUNCTION__, k, &node->results.bss_info->BSSID, rssi, node->results.bss_info->SSID)); + k++; + node = node->next; + } +} + +void +wl_update_bss_cache(wl_bss_cache_ctrl_t *bss_cache_ctrl, +#if defined(RSSIAVG) + wl_rssi_cache_ctrl_t *rssi_cache_ctrl, +#endif + wl_scan_results_t *ss_list) +{ + wl_bss_cache_t *node, *prev, *leaf, **bss_head; + wl_bss_info_t *bi = NULL; + int i, k=0; +#if defined(SORT_BSS_BY_RSSI) + int16 rssi, rssi_node; +#endif + struct timeval now, timeout; + + if (!ss_list->count) + return; + + do_gettimeofday(&now); + timeout.tv_sec = now.tv_sec + BSSCACHE_TIMEOUT; + if (timeout.tv_sec < now.tv_sec) { + /* + * Integer overflow - assume long enough timeout to be assumed + * to be infinite, i.e., the timeout would never happen. + */ + ANDROID_TRACE(("%s: Too long timeout (secs=%d) to ever happen - now=%lu, timeout=%lu", + __FUNCTION__, BSSCACHE_TIMEOUT, now.tv_sec, timeout.tv_sec)); + } + + bss_head = &bss_cache_ctrl->m_cache_head; + + for (i=0; i < ss_list->count; i++) { + node = *bss_head; + prev = NULL; + bi = bi ? (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length)) : ss_list->bss_info; + + for (;node;) { + if (!memcmp(&node->results.bss_info->BSSID, &bi->BSSID, ETHER_ADDR_LEN)) { + if (node == *bss_head) + *bss_head = node->next; + else { + prev->next = node->next; + } + break; + } + prev = node; + node = node->next; + } + + leaf = kmalloc(dtoh32(bi->length) + sizeof(wl_bss_cache_t), GFP_KERNEL); + if (!leaf) { + ANDROID_ERROR(("%s: Memory alloc failure %d\n", __FUNCTION__, + dtoh32(bi->length) + (int)sizeof(wl_bss_cache_t))); + return; + } + if (node) { + kfree(node); + node = NULL; + ANDROID_TRACE(("%s: Update %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n", + __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID)); + } else + ANDROID_TRACE(("%s: Add %d with cached BSSID %pM, RSSI=%3d, SSID \"%s\"\n", + __FUNCTION__, k, &bi->BSSID, dtoh16(bi->RSSI), bi->SSID)); + + memcpy(leaf->results.bss_info, bi, dtoh32(bi->length)); + leaf->next = NULL; + leaf->dirty = 0; + leaf->tv = timeout; + leaf->results.count = 1; + leaf->results.version = ss_list->version; + k++; + + if (*bss_head == NULL) + *bss_head = leaf; + else { +#if defined(SORT_BSS_BY_RSSI) + node = *bss_head; +#if defined(RSSIAVG) + rssi = wl_get_avg_rssi(rssi_cache_ctrl, &leaf->results.bss_info->BSSID); +#else + rssi = dtoh16(leaf->results.bss_info->RSSI); +#endif + for (;node;) { +#if defined(RSSIAVG) + rssi_node = wl_get_avg_rssi(rssi_cache_ctrl, &node->results.bss_info->BSSID); +#else + rssi_node = dtoh16(node->results.bss_info->RSSI); +#endif + if (rssi > rssi_node) { + leaf->next = node; + if (node == *bss_head) + *bss_head = leaf; + else + prev->next = leaf; + break; + } + prev = node; + node = node->next; + } + if (node == NULL) + prev->next = leaf; +#else + leaf->next = *bss_head; + *bss_head = leaf; +#endif + } + } + dump_bss_cache( +#if defined(RSSIAVG) + rssi_cache_ctrl, +#endif + *bss_head); +} + +void +wl_release_bss_cache_ctrl(wl_bss_cache_ctrl_t *bss_cache_ctrl) +{ + ANDROID_TRACE(("%s:\n", __FUNCTION__)); + wl_free_bss_cache(bss_cache_ctrl); +} +#endif + + diff --git a/bcmdhd.1.363.59.144.x.cn/wl_cfg80211.c b/bcmdhd.1.363.59.144.x.cn/wl_cfg80211.c index 12ae903..8dc9edf 100644 --- a/bcmdhd.1.363.59.144.x.cn/wl_cfg80211.c +++ b/bcmdhd.1.363.59.144.x.cn/wl_cfg80211.c @@ -616,6 +616,9 @@ static void wl_update_hidden_ap_ie(struct wl_bss_info *bi, const u8 *ie_stream, static s32 wl_mrg_ie(struct bcm_cfg80211 *cfg, u8 *ie_stream, u16 ie_size); static s32 wl_cp_ie(struct bcm_cfg80211 *cfg, u8 *dst, u16 dst_size); static u32 wl_get_ielen(struct bcm_cfg80211 *cfg); +#ifdef MFP +static int wl_cfg80211_get_rsn_capa(bcm_tlv_t *wpa2ie, u8* capa); +#endif #ifdef WL11U bcm_tlv_t * @@ -1487,12 +1490,12 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, #ifdef WL_VIRTUAL_APSTA bcm_struct_cfgdev *new_cfgdev; #endif /* WL_VIRTUAL_APSTA */ + dhd_pub_t *dhd; #ifdef PROP_TXSTATUS_VSDB #if defined(BCMSDIO) s32 up = 1; bool enabled; #endif - dhd_pub_t *dhd; #endif /* PROP_TXSTATUS_VSDB */ #if defined(SUPPORT_AP_POWERSAVE) dhd_pub_t *dhd; @@ -1582,12 +1585,8 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, if (cfg->p2p_supported && (wlif_type != -1)) { ASSERT(cfg->p2p); /* ensure expectation of p2p initialization */ -#ifdef PROP_TXSTATUS_VSDB -#if defined(BCMSDIO) if (!dhd) return ERR_PTR(-ENODEV); -#endif -#endif /* PROP_TXSTATUS_VSDB */ if (!cfg->p2p) return ERR_PTR(-ENODEV); @@ -2423,7 +2422,7 @@ static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_req ptr = (char*)params + offset; for (i = 0; i < n_ssids; i++) { memset(&ssid, 0, sizeof(wlc_ssid_t)); - ssid.SSID_len = request->ssids[i].ssid_len; + ssid.SSID_len = MIN(request->ssids[i].ssid_len, DOT11_MAX_SSID_LEN); memcpy(ssid.SSID, request->ssids[i].ssid, ssid.SSID_len); if (!ssid.SSID_len) WL_SCAN(("%d: Broadcast scan\n", i)); @@ -3786,7 +3785,8 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, WL_TRACE(("In\n")); RETURN_EIO_IF_NOT_UP(cfg); WL_INFORM(("JOIN BSSID:" MACDBG "\n", MAC2STRDBG(params->bssid))); - if (!params->ssid || params->ssid_len <= 0) { + if (!params->ssid || params->ssid_len <= 0 || + params->ssid_len > DOT11_MAX_SSID_LEN) { WL_ERR(("Invalid parameter\n")); return -EINVAL; } @@ -3955,6 +3955,43 @@ static s32 wl_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) return err; } +#ifdef MFP +static int wl_cfg80211_get_rsn_capa(bcm_tlv_t *wpa2ie, u8* capa) +{ + u16 suite_count; + wpa_suite_mcast_t *mcast; + wpa_suite_ucast_t *ucast; + u16 len; + wpa_suite_auth_key_mgmt_t *mgmt; + + if (!wpa2ie) + return -1; + + len = wpa2ie->len; + mcast = (wpa_suite_mcast_t *)&wpa2ie->data[WPA2_VERSION_LEN]; + if ((len -= WPA_SUITE_LEN) <= 0) + return BCME_BADLEN; + ucast = (wpa_suite_ucast_t *)&mcast[1]; + suite_count = ltoh16_ua(&ucast->count); + if ((suite_count > NL80211_MAX_NR_CIPHER_SUITES) || + (len -= (WPA_IE_SUITE_COUNT_LEN + + (WPA_SUITE_LEN * suite_count))) <= 0) + return BCME_BADLEN; + + mgmt = (wpa_suite_auth_key_mgmt_t *)&ucast->list[suite_count]; + suite_count = ltoh16_ua(&mgmt->count); + + if ((suite_count > NL80211_MAX_NR_CIPHER_SUITES) || + (len -= (WPA_IE_SUITE_COUNT_LEN + + (WPA_SUITE_LEN * suite_count))) >= RSN_CAP_LEN) { + capa[0] = *(u8 *)&mgmt->list[suite_count]; + capa[1] = *((u8 *)&mgmt->list[suite_count] + 1); + } else + return BCME_BADLEN; + + return 0; +} +#endif /* MFP */ static s32 wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) @@ -4131,6 +4168,11 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) s32 val = 0; s32 err = 0; s32 bssidx; +#ifdef MFP + s32 mfp = WL_MFP_NONE; + bcm_tlv_t *wpa2_ie; + u8 rsn_cap[2]; +#endif /* MFP */ if ((bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr)) < 0) { WL_ERR(("Find p2p index from wdev(%p) failed\n", dev->ieee80211_ptr)); @@ -4163,6 +4205,14 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) case WLAN_AKM_SUITE_8021X: val = WPA2_AUTH_UNSPECIFIED; break; +#ifdef MFP + case WL_AKM_SUITE_SHA256_1X: + val = WPA2_AUTH_UNSPECIFIED; + break; + case WL_AKM_SUITE_SHA256_PSK: + val = WPA2_AUTH_PSK; + break; +#endif /* MFP */ case WLAN_AKM_SUITE_PSK: val = WPA2_AUTH_PSK; break; @@ -4173,6 +4223,33 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) } } +#ifdef MFP + if (((wpa2_ie = bcm_parse_tlvs((u8 *)sme->ie, sme->ie_len, + DOT11_MNG_RSN_ID)) != NULL) && + (wl_cfg80211_get_rsn_capa(wpa2_ie, rsn_cap) == 0)) { + /* Check for MFP cap in the RSN capability field */ + if (rsn_cap[0] & RSN_CAP_MFPR) { + mfp = WL_MFP_REQUIRED; + } else if (rsn_cap[0] & RSN_CAP_MFPC) { + mfp = WL_MFP_CAPABLE; + } + } + err = wldev_iovar_setint(dev, "mfp", mfp); + if (unlikely(err)) { + if (!mfp && (err == BCME_UNSUPPORTED)) { + /* For non-mfp cases, if firmware doesn't support MFP + * ignore the failure and proceed ahead. + */ + WL_DBG(("fw doesn't support mfp \n")); + err = 0; + } else { + WL_ERR(("mfp set failed ret:%d \n", err)); + return err; + } + } else { + WL_DBG(("mfp set to 0x%x \n", mfp)); + } +#endif /* MFP */ WL_DBG(("setting wpa_auth to 0x%x\n", val)); @@ -5125,8 +5202,10 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, return BCME_ERROR; } +#ifndef MFP if ((key_idx >= DOT11_MAX_DEFAULT_KEYS) && (key_idx < DOT11_MAX_DEFAULT_KEYS+2)) return -EINVAL; +#endif RETURN_EIO_IF_NOT_UP(cfg); memset(&key, 0, sizeof(key)); @@ -5223,8 +5302,12 @@ static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx) { +#ifdef MFP + return 0; +#else WL_INFORM(("Not supported\n")); return -EOPNOTSUPP; +#endif /* MFP */ } #if defined(RSSIAVG) @@ -6551,6 +6634,11 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, bcm_struct_cfgdev *cfgdev, WL_DBG(("Enter \n")); + if (len > ACTION_FRAME_SIZE) { + WL_ERR(("bad length:%zu\n", len)); + return BCME_BADLEN; + } + dev = cfgdev_to_wlc_ndev(cfgdev, cfg); if (!dev) { @@ -6951,6 +7039,10 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx) wpa_suite_auth_key_mgmt_t *mgmt; wpa_pmkid_list_t *pmkid; int cnt = 0; +#ifdef MFP + int mfp = 0; + struct bcm_cfg80211 *cfg = g_bcm_cfg; +#endif /* MFP */ u16 suite_count; u8 rsn_cap[2]; @@ -7023,6 +7115,16 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx) case RSN_AKM_PSK: wpa_auth |= WPA2_AUTH_PSK; break; +#ifdef MFP + case RSN_AKM_MFP_PSK: + wpa_auth |= WPA2_AUTH_PSK; + wsec |= MFP_SHA256; + break; + case RSN_AKM_MFP_1X: + wpa_auth |= WPA2_AUTH_UNSPECIFIED; + wsec |= MFP_SHA256; + break; +#endif /* MFP */ default: WL_ERR(("No Key Mgmt Info\n")); } @@ -7038,6 +7140,15 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx) wme_bss_disable = 1; } +#ifdef MFP + if (rsn_cap[0] & RSN_CAP_MFPR) { + WL_DBG(("MFP Required \n")); + mfp = WL_MFP_REQUIRED; + } else if (rsn_cap[0] & RSN_CAP_MFPC) { + WL_DBG(("MFP Capable \n")); + mfp = WL_MFP_CAPABLE; + } +#endif /* MFP */ /* set wme_bss_disable to sync RSN Capabilities */ err = wldev_iovar_setint_bsscfg(dev, "wme_bss_disable", wme_bss_disable, bssidx); @@ -7061,6 +7172,19 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx) /* so don't bother to send down this info to firmware */ } +#ifdef MFP + len -= WPA2_PMKID_COUNT_LEN; + if (len >= WPA_SUITE_LEN) { + err = wldev_iovar_setbuf_bsscfg(dev, "bip", + (void *)((u8 *)&mgmt->list[suite_count] + RSN_CAP_LEN + WPA2_PMKID_COUNT_LEN), + WPA_SUITE_LEN, + cfg->ioctl_buf, WLC_IOCTL_SMLEN, bssidx, &cfg->ioctl_buf_sync); + if (err < 0) { + WL_ERR(("bip set error %d\n", err)); + return BCME_ERROR; + } + } +#endif /* set auth */ err = wldev_iovar_setint_bsscfg(dev, "auth", auth, bssidx); @@ -7076,6 +7200,17 @@ wl_validate_wpa2ie(struct net_device *dev, bcm_tlv_t *wpa2ie, s32 bssidx) return BCME_ERROR; } +#ifdef MFP + if (mfp) { + /* This needs to go after wsec otherwise the wsec command will + * overwrite the values set by MFP + */ + if ((err = wldev_iovar_setint_bsscfg(dev, "mfp", mfp, bssidx)) < 0) { + WL_ERR(("MFP Setting failed. ret = %d \n", err)); + return err; + } + } +#endif /* MFP */ /* set upper-layer auth */ err = wldev_iovar_setint_bsscfg(dev, "wpa_auth", wpa_auth, bssidx); @@ -7592,17 +7727,17 @@ static s32 wl_cfg80211_bcn_set_params( } if ((info->ssid) && (info->ssid_len > 0) && - (info->ssid_len <= 32)) { + (info->ssid_len <= DOT11_MAX_SSID_LEN)) { WL_DBG(("SSID (%s) len:%zd \n", info->ssid, info->ssid_len)); if (dev_role == NL80211_IFTYPE_AP) { /* Store the hostapd SSID */ - memset(cfg->hostapd_ssid.SSID, 0x00, 32); + memset(cfg->hostapd_ssid.SSID, 0x00, DOT11_MAX_SSID_LEN); memcpy(cfg->hostapd_ssid.SSID, info->ssid, info->ssid_len); cfg->hostapd_ssid.SSID_len = info->ssid_len; } else { /* P2P GO */ - memset(cfg->p2p->ssid.SSID, 0x00, 32); - memcpy(cfg->p2p->ssid.SSID, info->ssid, info->ssid_len); + memset(cfg->p2p->ssid.SSID, 0x00, DOT11_MAX_SSID_LEN); + memcpy(cfg->p2p->ssid.SSID, info->ssid, cfg->p2p->ssid.SSID_len); cfg->p2p->ssid.SSID_len = info->ssid_len; } } @@ -7815,9 +7950,11 @@ wl_cfg80211_bcn_bringup_ap( memset(&join_params, 0, sizeof(join_params)); /* join parameters starts with ssid */ join_params_size = sizeof(join_params.ssid); + join_params.ssid.SSID_len = min(cfg->hostapd_ssid.SSID_len, + (uint32)DOT11_MAX_SSID_LEN); memcpy(join_params.ssid.SSID, cfg->hostapd_ssid.SSID, - cfg->hostapd_ssid.SSID_len); - join_params.ssid.SSID_len = htod32(cfg->hostapd_ssid.SSID_len); + join_params.ssid.SSID_len); + join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len); /* create softap */ if ((err = wldev_ioctl(dev, WLC_SET_SSID, &join_params, @@ -8507,33 +8644,44 @@ wl_cfg80211_stop_ap( * Don't do a down or "WLC_SET_AP 0" since the shared * interface may be still running */ - if (is_rsdb_supported) { - if ((err = wl_cfg80211_add_del_bss(cfg, dev, - bssidx, NL80211_IFTYPE_STATION, 0, NULL)) < 0) { - if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), - true)) < 0) { + if (bssidx == 0) { + if (is_rsdb_supported) { + if ((err = wl_cfg80211_add_del_bss(cfg, dev, + bssidx, NL80211_IFTYPE_STATION, 0, NULL)) < 0) { + if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), + true)) < 0) { + WL_ERR(("setting AP mode failed %d \n", err)); + err = -ENOTSUPP; + goto exit; + } + } + } else if (is_rsdb_supported == 0) { + // terence 20160426: fix softap issue + if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) { WL_ERR(("setting AP mode failed %d \n", err)); err = -ENOTSUPP; goto exit; } + err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true); + if (err < 0) { + WL_ERR(("SET INFRA error %d\n", err)); + err = -ENOTSUPP; + goto exit; + } + err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true); + if (unlikely(err)) { + WL_ERR(("WLC_UP error (%d)\n", err)); + err = -EINVAL; + goto exit; + } } - } else if (is_rsdb_supported == 0) { - // terence 20160426: fix softap issue - if ((err = wldev_ioctl(dev, WLC_SET_AP, &ap, sizeof(s32), true)) < 0) { - WL_ERR(("setting AP mode failed %d \n", err)); - err = -ENOTSUPP; - goto exit; - } - err = wldev_ioctl(dev, WLC_SET_INFRA, &infra, sizeof(s32), true); - if (err < 0) { - WL_ERR(("SET INFRA error %d\n", err)); - err = -ENOTSUPP; - goto exit; - } - err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true); - if (unlikely(err)) { - WL_ERR(("WLC_UP error (%d)\n", err)); - err = -EINVAL; + } else if (cfg->cfgdev_bssidx && (bssidx == cfg->cfgdev_bssidx)) { + + WL_ERR(("Stop SoftAP on virtual Interface bssidx:%d \n", bssidx)); + + if ((err = wl_cfg80211_add_del_bss(cfg, dev, + bssidx, NL80211_IFTYPE_AP, 1, NULL)) < 0) { + WL_ERR(("wl bss ap returned error:%d\n", err)); goto exit; } } @@ -8696,14 +8844,16 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev, DOT11_MNG_SSID_ID)) != NULL) { if (dev_role == NL80211_IFTYPE_AP) { /* Store the hostapd SSID */ - memset(&cfg->hostapd_ssid.SSID[0], 0x00, 32); - memcpy(&cfg->hostapd_ssid.SSID[0], ssid_ie->data, ssid_ie->len); - cfg->hostapd_ssid.SSID_len = ssid_ie->len; + memset(&cfg->hostapd_ssid.SSID[0], 0x00, DOT11_MAX_SSID_LEN); + cfg->hostapd_ssid.SSID_len = MIN(ssid_ie->len, DOT11_MAX_SSID_LEN); + memcpy(&cfg->hostapd_ssid.SSID[0], ssid_ie->data, + cfg->hostapd_ssid.SSID_len); } else { - /* P2P GO */ - memset(&cfg->p2p->ssid.SSID[0], 0x00, 32); - memcpy(cfg->p2p->ssid.SSID, ssid_ie->data, ssid_ie->len); - cfg->p2p->ssid.SSID_len = ssid_ie->len; + /* P2P GO */ + memset(&cfg->p2p->ssid.SSID[0], 0x00, DOT11_MAX_SSID_LEN); + cfg->p2p->ssid.SSID_len = MIN(ssid_ie->len, DOT11_MAX_SSID_LEN); + memcpy(cfg->p2p->ssid.SSID, ssid_ie->data, + cfg->p2p->ssid.SSID_len); } } @@ -8877,8 +9027,10 @@ wl_cfg80211_sched_scan_start(struct wiphy *wiphy, ssid = &request->match_sets[i].ssid; /* No need to include null ssid */ if (ssid->ssid_len) { - memcpy(ssids_local[ssid_cnt].SSID, ssid->ssid, ssid->ssid_len); - ssids_local[ssid_cnt].SSID_len = ssid->ssid_len; + ssids_local[ssid_cnt].SSID_len = min(ssid->ssid_len, + (u8)DOT11_MAX_SSID_LEN); + memcpy(ssids_local[ssid_cnt].SSID, ssid->ssid, + ssids_local[ssid_cnt].SSID_len); if (is_ssid_in_list(ssid, hidden_ssid_list, request->n_ssids)) { ssids_local[ssid_cnt].hidden = TRUE; WL_PNO((">>> PNO hidden SSID (%s) \n", ssid->ssid)); @@ -9289,24 +9441,17 @@ static const struct wiphy_wowlan_support brcm_wowlan_support = { #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) */ }; #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) */ - -/* terence 20161107: remove to fix: - * PC is at kfree+0x174/0x180 - * LR is at nl80211_set_wowlan+0x55c/0x614 [cfg80211] - */ -#if 0 -static struct cfg80211_wowlan brcm_wowlan_config = { - .disconnect = true, - .gtk_rekey_failure = true, - .eap_identity_req = true, - .four_way_handshake = true, -}; -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */ #endif /* CONFIG_PM */ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev, dhd_pub_t *context) { s32 err = 0; +#ifdef CONFIG_PM +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) + struct cfg80211_wowlan *brcm_wowlan_config = NULL; +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */ +#endif /* CONFIG_PM */ + //#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) dhd_pub_t *dhd = (dhd_pub_t *)context; BCM_REFERENCE(dhd); @@ -9443,11 +9588,23 @@ static s32 wl_setup_wiphy(struct wireless_dev *wdev, struct device *sdiofunc_dev /* If this is not provided cfg stack will get disconnect * during suspend. */ - /* terence 20161107: remove to fix: - * PC is at kfree+0x174/0x180 - * LR is at nl80211_set_wowlan+0x55c/0x614 [cfg80211] - */ -// wdev->wiphy->wowlan_config = &brcm_wowlan_config; + brcm_wowlan_config = kmalloc(sizeof(struct cfg80211_wowlan), GFP_KERNEL); + if (brcm_wowlan_config) { + brcm_wowlan_config->disconnect = true; + brcm_wowlan_config->gtk_rekey_failure = true; + brcm_wowlan_config->eap_identity_req = true; + brcm_wowlan_config->four_way_handshake = true; + brcm_wowlan_config->patterns = NULL; + brcm_wowlan_config->n_patterns = 0; + brcm_wowlan_config->tcp = NULL; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) + brcm_wowlan_config->nd_config = NULL; +#endif + } else { + WL_ERR(("Can not allocate memory for brcm_wowlan_config," + " So wiphy->wowlan_config is set to NULL\n")); + } + wdev->wiphy->wowlan_config = brcm_wowlan_config; #else wdev->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY; wdev->wiphy->wowlan.n_patterns = WL_WOWLAN_MAX_PATTERNS; @@ -9507,7 +9664,6 @@ static void wl_free_wdev(struct bcm_cfg80211 *cfg) /* Reset wowlan & wowlan_config before Unregister to avoid Kernel Panic */ WL_DBG(("wl_free_wdev Clearing wowlan Config \n")); wdev->wiphy->wowlan = NULL; - wdev->wiphy->wowlan_config = NULL; #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) */ #endif /* CONFIG_PM && WL_CFG80211_P2P_DEV_IF */ wiphy_unregister(wdev->wiphy); @@ -10581,13 +10737,12 @@ wl_notify_connect_status(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, if (!memcmp(ndev->name, WL_P2P_INTERFACE_PREFIX, strlen(WL_P2P_INTERFACE_PREFIX))) { // terence 20130703: Fix for wrong group_capab (timing issue) cfg->p2p_disconnected = 1; + } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) - if (wl_get_drv_status(cfg, DISCONNECTING, ndev)) { - CFG80211_DISCONNECTED(ndev, reason, NULL, 0, - false, GFP_KERNEL); - } -#endif + if (wl_get_drv_status(cfg, DISCONNECTING, ndev)) { + CFG80211_DISCONNECTED(ndev, reason, NULL, 0, false, GFP_KERNEL); } +#endif memcpy(&cfg->disconnected_bssid, curbssid, ETHER_ADDR_LEN); wl_clr_drv_status(cfg, CONNECTED, ndev); if (! wl_get_drv_status(cfg, DISCONNECTING, ndev)) { @@ -12719,7 +12874,7 @@ static s32 wl_escan_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, else band = bcmcfg_to_wiphy(cfg)->bands[IEEE80211_BAND_5GHZ]; if (!band) { - WL_ERR(("No valid band\n")); + WL_ERR(("No valid band, channel=%d\n", channel)); goto exit; } if (!dhd_conf_match_channel(cfg->pub, channel)) @@ -14734,8 +14889,8 @@ wl_update_prof(struct bcm_cfg80211 *cfg, struct net_device *ndev, ssid = (const wlc_ssid_t *) data; memset(profile->ssid.SSID, 0, sizeof(profile->ssid.SSID)); - memcpy(profile->ssid.SSID, ssid->SSID, ssid->SSID_len); - profile->ssid.SSID_len = ssid->SSID_len; + profile->ssid.SSID_len = MIN(ssid->SSID_len, DOT11_MAX_SSID_LEN); + memcpy(profile->ssid.SSID, ssid->SSID, profile->ssid.SSID_len); break; case WL_PROF_BSSID: if (data) @@ -14819,6 +14974,8 @@ static void wl_update_hidden_ap_ie(struct wl_bss_info *bi, const u8 *ie_stream, bool roam) { u8 *ssidie; + int32 ssid_len = MIN(bi->SSID_len, DOT11_MAX_SSID_LEN); + int32 remaining_ie_buf_len, available_buffer_len; /* cfg80211_find_ie defined in kernel returning const u8 */ #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \ 4 && __GNUC_MINOR__ >= 6)) @@ -14830,26 +14987,41 @@ _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") 4 && __GNUC_MINOR__ >= 6)) _Pragma("GCC diagnostic pop") #endif - if (!ssidie) + /* ERROR out if + * 1. No ssid IE is FOUND or + * 2. New ssid length is > what was allocated for existing ssid (as + * we do not want to overwrite the rest of the IEs) or + * 3. If in case of erroneous buffer input where ssid length doesnt match the space + * allocated to it. + */ + if (!ssidie) { + return; + } + available_buffer_len = ((int)(*ie_size)) - (ssidie + 2 - ie_stream); + remaining_ie_buf_len = available_buffer_len - (int)ssidie[1]; + if ((ssid_len > ssidie[1]) || + (ssidie[1] > available_buffer_len)) { return; - if (ssidie[1] != bi->SSID_len) { + } + + if (ssidie[1] != ssid_len) { if (ssidie[1]) { WL_ERR(("%s: Wrong SSID len: %d != %d\n", __FUNCTION__, ssidie[1], bi->SSID_len)); } if (roam) { WL_ERR(("Changing the SSID Info.\n")); - memmove(ssidie + bi->SSID_len + 2, + memmove(ssidie + ssid_len + 2, (ssidie + 2) + ssidie[1], - *ie_size - (ssidie + 2 + ssidie[1] - ie_stream)); - memcpy(ssidie + 2, bi->SSID, bi->SSID_len); - *ie_size = *ie_size + bi->SSID_len - ssidie[1]; - ssidie[1] = bi->SSID_len; + remaining_ie_buf_len); + memcpy(ssidie + 2, bi->SSID, ssid_len); + *ie_size = *ie_size + ssid_len - ssidie[1]; + ssidie[1] = ssid_len; } return; } if (*(ssidie + 2) == '\0') - memcpy(ssidie + 2, bi->SSID, bi->SSID_len); + memcpy(ssidie + 2, bi->SSID, ssid_len); return; } @@ -15483,7 +15655,7 @@ wl_cfg80211_get_best_channel(struct net_device *ndev, void *buf, int buflen, chanspec = wl_chspec_driver_to_host(chosen); printf("selected chanspec = 0x%x\n", chanspec); ctl_chan = wf_chspec_ctlchan(chanspec); - printf("selected ctl_chan = 0x%x\n", ctl_chan); + printf("selected ctl_chan = %d\n", ctl_chan); *channel = (u16)(ctl_chan & 0x00FF); } else *channel = (u16)(chosen & 0x00FF); @@ -15499,6 +15671,7 @@ wl_cfg80211_get_best_channel(struct net_device *ndev, void *buf, int buflen, *channel = 0; ret = BCME_ERROR; } + WL_INFORM(("selected channel = %d\n", *channel)); done: return ret; @@ -15579,17 +15752,19 @@ wl_cfg80211_get_best_channels(struct net_device *dev, char* cmd, int total_len) } if (CHANNEL_IS_2G(channel)) { +#if 0 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) && !defined(WL_COMPAT_WIRELESS) channel = ieee80211_channel_to_frequency(channel); #else channel = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ); +#endif #endif } else { WL_ERR(("invalid 2.4GHz channel, channel = %d\n", channel)); channel = 0; } + pos += snprintf(pos, total_len, "2g=%d ", channel); } - pos += snprintf(pos, total_len, "%04d ", channel); if (band_cur != WLC_BAND_2G) { // terence 20140120: fix for some chipsets only return 2.4GHz channel (4330b2/43341b0/4339a0) @@ -15613,10 +15788,12 @@ wl_cfg80211_get_best_channels(struct net_device *dev, char* cmd, int total_len) } if (CHANNEL_IS_5G(channel)) { +#if 0 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) && !defined(WL_COMPAT_WIRELESS) channel = ieee80211_channel_to_frequency(channel); #else channel = ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ); +#endif #endif } else { WL_ERR(("invalid 5GHz channel, channel = %d\n", channel)); @@ -15626,11 +15803,8 @@ wl_cfg80211_get_best_channels(struct net_device *dev, char* cmd, int total_len) ret = wldev_ioctl(dev, WLC_SET_BAND, &band_cur, sizeof(band_cur), true); if (ret < 0) WL_ERR(("WLC_SET_BAND error %d\n", ret)); + pos += snprintf(pos, total_len, "5g=%d ", channel); } - pos += snprintf(pos, total_len, "%04d ", channel); - - /* Set overall best channel same as 5GHz best channel. */ - pos += snprintf(pos, total_len, "%04d ", channel); done: if (NULL != buf) { @@ -15643,7 +15817,7 @@ done: WL_ERR(("can't restore auto channel scan state, error = %d\n", ret)); } - printf("%s: channel %s\n", __FUNCTION__, cmd); + printf("%s: %s\n", __FUNCTION__, cmd); return (pos - cmd); } diff --git a/bcmdhd.1.363.59.144.x.cn/wl_cfgvendor.c b/bcmdhd.1.363.59.144.x.cn/wl_cfgvendor.c index 75dd877..acb78aa 100644 --- a/bcmdhd.1.363.59.144.x.cn/wl_cfgvendor.c +++ b/bcmdhd.1.363.59.144.x.cn/wl_cfgvendor.c @@ -753,13 +753,16 @@ wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy, gscan_swc_params_t *significant_params; int tmp, tmp1, tmp2, type, j = 0; const struct nlattr *outer, *inner, *iter; - uint8 flush = 0; - wl_pfn_significant_bssid_t *bssid; + bool flush = FALSE; + wl_pfn_significant_bssid_t *pbssid; + uint16 num_bssid = 0; + uint16 max_buf_size = sizeof(gscan_swc_params_t) + + sizeof(wl_pfn_significant_bssid_t) * (PFN_SWC_MAX_NUM_APS - 1); - significant_params = (gscan_swc_params_t *) kzalloc(len, GFP_KERNEL); + significant_params = kzalloc(max_buf_size, GFP_KERNEL); if (!significant_params) { - WL_ERR(("Cannot Malloc mem to parse config commands size - %d bytes \n", len)); - return -ENOMEM; + WL_ERR(("Cannot Malloc mem size:%d\n", len)); + return BCME_NOMEM; } nla_for_each_attr(iter, data, len, tmp2) { @@ -767,7 +770,7 @@ wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy, switch (type) { case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH: - flush = nla_get_u8(iter); + flush = (bool) nla_get_u8(iter); break; case GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE: significant_params->rssi_window = nla_get_u16(iter); @@ -778,23 +781,41 @@ wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy, case GSCAN_ATTRIBUTE_MIN_BREACHING: significant_params->swc_threshold = nla_get_u16(iter); break; + case GSCAN_ATTRIBUTE_NUM_BSSID: + num_bssid = nla_get_u16(iter); + if (num_bssid > PFN_SWC_MAX_NUM_APS) { + WL_ERR(("ovar max SWC bssids:%d\n", + num_bssid)); + err = BCME_BADARG; + goto exit; + } + break; case GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS: - bssid = significant_params->bssid_elem_list; + if (num_bssid == 0) { + WL_ERR(("num_bssid : 0\n")); + err = BCME_BADARG; + goto exit; + } + pbssid = significant_params->bssid_elem_list; nla_for_each_nested(outer, iter, tmp) { + if (j >= num_bssid) { + j++; + break; + } nla_for_each_nested(inner, outer, tmp1) { switch (nla_type(inner)) { case GSCAN_ATTRIBUTE_BSSID: - memcpy(&(bssid[j].macaddr), - nla_data(inner), - ETHER_ADDR_LEN); + memcpy(&(pbssid[j].macaddr), + nla_data(inner), + ETHER_ADDR_LEN); break; case GSCAN_ATTRIBUTE_RSSI_HIGH: - bssid[j].rssi_high_threshold - = (int8) nla_get_u8(inner); + pbssid[j].rssi_high_threshold = + (int8) nla_get_u8(inner); break; case GSCAN_ATTRIBUTE_RSSI_LOW: - bssid[j].rssi_low_threshold - = (int8) nla_get_u8(inner); + pbssid[j].rssi_low_threshold = + (int8) nla_get_u8(inner); break; default: WL_ERR(("ATTR unknown %d\n", @@ -810,13 +831,19 @@ wl_cfgvendor_significant_change_cfg(struct wiphy *wiphy, break; } } + if (j != num_bssid) { + WL_ERR(("swc bssids count:%d not matched to num_bssid:%d\n", + j, num_bssid)); + err = BCME_BADARG; + goto exit; + } significant_params->nbssid = j; if (dhd_dev_pno_set_cfg_gscan(bcmcfg_to_prmry_ndev(cfg), DHD_PNO_SIGNIFICANT_SCAN_CFG_ID, significant_params, flush) < 0) { WL_ERR(("Could not set GSCAN significant cfg\n")); - err = -EINVAL; + err = BCME_ERROR; goto exit; } exit: -- 2.20.1