diff options
author | Daniel Hillenbrand <daniel.hillenbrand@codeworkx.de> | 2012-07-21 23:04:45 +0200 |
---|---|---|
committer | Daniel Hillenbrand <daniel.hillenbrand@codeworkx.de> | 2012-07-21 23:04:45 +0200 |
commit | 0a1182796f6475b8cb2ff1781dad873a744b3197 (patch) | |
tree | e15b5256dac226c49a25b5e24594cd638e2fec2c /drivers/net/wireless/bcmdhd | |
parent | 633018c13fe06461d9c60692fbb114734aa37802 (diff) | |
download | kernel_samsung_smdk4412-0a1182796f6475b8cb2ff1781dad873a744b3197.zip kernel_samsung_smdk4412-0a1182796f6475b8cb2ff1781dad873a744b3197.tar.gz kernel_samsung_smdk4412-0a1182796f6475b8cb2ff1781dad873a744b3197.tar.bz2 |
samsung opensource update3
Diffstat (limited to 'drivers/net/wireless/bcmdhd')
16 files changed, 582 insertions, 309 deletions
diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile index 15d6c7c..1a27ef0 100644 --- a/drivers/net/wireless/bcmdhd/Makefile +++ b/drivers/net/wireless/bcmdhd/Makefile @@ -1,7 +1,7 @@ # bcmdhd DHDCFLAGS = -Wall -Wstrict-prototypes -Dlinux -DBCMDRIVER \ -DBCMDONGLEHOST -DUNRELEASEDCHIP -DBCMDMA32 -DWLBTAMP -DBCMFILEIMAGE \ - -DDHDTHREAD -DDHD_GPL -DDHD_SCHED -DDHD_DEBUG -DBDC -DTOE \ + -DDHDTHREAD -DDHD_GPL -DDHD_SCHED -DDHD_DEBUG -DBDC \ -DDHD_BCMEVENTS -DSHOW_EVENTS -DDONGLEOVERLAYS -DBCMDBG \ -DCUSTOMER_HW_SAMSUNG -DOOB_INTR_ONLY \ -DMMC_SDIO_ABORT -DBCMSDIO -DBCMLXSDMMC -DBCMPLATFORM_BUS -DWLP2P \ @@ -84,7 +84,7 @@ endif # For SLP feature ifeq ($(CONFIG_SLP),y) -DHDCFLAGS += -DSLP_PATH -DWRITE_MACADDR +DHDCFLAGS += -DSLP_PATH -DWRITE_MACADDR -DCUSTOMER_HW_SLP endif # 5GHz channels setting diff --git a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c index 42433d6..f7676d8 100644 --- a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c +++ b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c @@ -49,6 +49,10 @@ extern void dhdsdio_isr(void * args); #include <dhd.h> #endif /* defined(OOB_INTR_ONLY) */ +#if defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP) +/*SLP_wakelock_alternative_code*/ +struct device *pm_dev; +#endif /* CONFIG_PM_SLEEP && CUSTOMER_HW_SLP */ /** * SDIO Host Controller info */ @@ -162,6 +166,9 @@ int bcmsdh_probe(struct device *dev) int irq = 0; uint32 vendevid; unsigned long irq_flags = 0; +#if defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP) + int ret = 0; +#endif /* CONFIG_PM_SLEEP && CUSTOMER_HW_SLP */ #if !defined(BCMLXSDMMC) && defined(BCMPLATFORM_BUS) pdev = to_platform_device(dev); @@ -228,6 +235,12 @@ int bcmsdh_probe(struct device *dev) sdhc->next = sdhcinfo; sdhcinfo = sdhc; +#if defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP) + /*SLP_wakelock_alternative_code*/ + pm_dev=sdhc->dev; + ret = device_init_wakeup(pm_dev, 1); + printf("%s : device_init_wakeup(pm_dev) enable, ret = %d\n", __func__, ret); +#endif /* CONFIG_PM_SLEEP && CUSTOMER_HW_SLP */ /* Read the vendor/device ID from the CIS */ vendevid = bcmsdh_query_device(sdh); /* try to attach to the target device */ @@ -261,6 +274,11 @@ int bcmsdh_remove(struct device *dev) osl_t *osh; sdhc = sdhcinfo; +#if defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP) + /*SLP_wakelock_alternative_code*/ + device_init_wakeup(pm_dev, 0); + printf("%s : device_init_wakeup(pm_dev) disable\n", __func__); +#endif /* CONFIG_PM_SLEEP && CUSTOMER_HW_SLP */ drvinfo.detach(sdhc->ch); bcmsdh_detach(sdhc->osh, sdhc->sdh); diff --git a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c index 9687141..83c1192 100644 --- a/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c +++ b/drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c @@ -200,6 +200,9 @@ static int bcmsdh_sdmmc_suspend(struct device *pdev) #endif /* defined(OOB_INTR_ONLY) */ #endif /* defined(OOB_INTR_ONLY) */ dhd_mmc_suspend = TRUE; +#if defined (CUSTOMER_HW_SAMSUNG) && defined (CONFIG_ARCH_TEGRA) + irq_set_irq_wake(390, 1); +#endif smp_mb(); return 0; @@ -218,7 +221,11 @@ static int bcmsdh_sdmmc_resume(struct device *pdev) if ((func->num == 2) && dhd_os_check_if_up(bcmsdh_get_drvdata())) bcmsdh_oob_intr_set(1); #endif /* (OOB_INTR_ONLY) */ -#endif /* (OOB_INTR_ONLY) */ +#endif /* !CUSTOMER_HW_SAMSUNG */ +#if defined (CUSTOMER_HW_SAMSUNG) && defined (CONFIG_ARCH_TEGRA) + if (func->num == 2) + irq_set_irq_wake(390, 0); +#endif smp_mb(); return 0; diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h index 3b7f026..5095aba 100644 --- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h +++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h @@ -83,7 +83,11 @@ enum dhd_bus_state { #define CONCURRENT_MASK (STA_MASK | WFD_MASK) /* max sequential rxcntl timeouts to set HANG event */ +#ifdef BCM4334_CHIP +#define MAX_CNTL_TIMEOUT 1 +#else #define MAX_CNTL_TIMEOUT 2 +#endif #define DHD_SCAN_ACTIVE_TIME 40 /* ms : Embedded default Active setting from DHD Driver */ #define DHD_SCAN_PASSIVE_TIME 130 /* ms: Embedded default Passive setting from DHD Driver */ @@ -258,9 +262,6 @@ typedef struct dhd_pub { int hang_was_sent; int rxcnt_timeout; /* counter rxcnt timeout to send HANG */ int txcnt_timeout; /* counter txcnt timeout to send HANG */ -#ifdef BCM4334_CHIP - int tx_seq_badcnt; -#endif #ifdef WLMEDIA_HTSF uint8 htsfdlystat_sz; /* Size of delay stats, max 255B */ #endif @@ -638,7 +639,11 @@ extern uint dhd_radio_up; /* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */ extern int dhd_idletime; +#ifdef DHD_USE_IDLECOUNT +#define DHD_IDLETIME_TICKS 5 +#else #define DHD_IDLETIME_TICKS 1 +#endif /* DHD_USE_IDLECOUNT */ /* SDIO Drive Strength */ extern uint dhd_sdiod_drive_strength; diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c index 73760ef..c0ef0bd 100644 --- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c +++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c @@ -507,10 +507,6 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command) int i; #endif -#ifdef PASS_ALL_MCAST_PKTS - char iovbuf[20]; - uint32 allmultivar = 0; -#endif /* Figure out powermode 1 or o command */ strncpy((char *)&powermode_val, command + strlen("BTCOEXMODE") +1, 1); @@ -530,13 +526,6 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command) dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], 0, dhd_master_mode); } - -#ifdef PASS_ALL_MCAST_PKTS - allmultivar = 1; - bcm_mkiovar("allmulti", (char *)&allmultivar, 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - WL_ERR(("DHCP is progressing , allmulti value = %d \n", allmultivar)); -#endif /* PASS_ALL_MCAST_PKTS */ } #endif @@ -594,13 +583,6 @@ int wl_cfg80211_set_btcoex_dhcp(struct net_device *dev, char *command) dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], 1, dhd_master_mode); } - -#ifdef PASS_ALL_MCAST_PKTS - allmultivar = 0; - bcm_mkiovar("allmulti", (char *)&allmultivar, 4, iovbuf, sizeof(iovbuf)); - dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); - WL_ERR(("DHCP is complete , allmulti value = %d \n", allmultivar)); -#endif /* PASS_ALL_MCAST_PKTS */ } #endif diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c index 956c4e1..f9f8c20 100644 --- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c +++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c @@ -267,36 +267,13 @@ int dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set, int ifindex) { wl_ioctl_t ioc; -#ifdef CUSTOMER_HW_SAMSUNG - int ret; -#endif /* CUSTOMER_HW_SAMSUNG */ ioc.cmd = cmd; ioc.buf = arg; ioc.len = len; ioc.set = set; -#ifdef CUSTOMER_HW_SAMSUNG - ret = dhd_wl_ioctl(dhd_pub, ifindex, &ioc, arg, len); - if (ret < 0) { - if (ioc.cmd == WLC_GET_VAR) { - DHD_ERROR(("%s: WLC_GET_VAR: %s, error = %d\n", - __FUNCTION__, (char *)ioc.buf, ret)); - } else if (ioc.cmd == WLC_SET_VAR) { - char pkt_filter[] = "pkt_filter_add"; - if (strncmp(pkt_filter, ioc.buf, sizeof(pkt_filter)) != 0) { - DHD_ERROR(("%s: WLC_SET_VAR: %s, error = %d\n", - __FUNCTION__, (char *)ioc.buf, ret)); - } - } else { - DHD_ERROR(("%s: WLC_IOCTL: cmd:%d, error = %d\n", - __FUNCTION__, ioc.cmd, ret)); - } - } - return ret; -#else return dhd_wl_ioctl(dhd_pub, ifindex, &ioc, arg, len); -#endif /* CUSTOMER_HW_SAMSUNG */ } @@ -308,14 +285,26 @@ dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int le dhd_os_proto_block(dhd_pub); ret = dhd_prot_ioctl(dhd_pub, ifindex, ioc, buf, len); -#ifdef BCM4334_CHIP - if (!ret || ret == -ETIMEDOUT || (dhd_pub->tx_seq_badcnt >= 2)) -#else - if (!ret || ret == -ETIMEDOUT) -#endif + if (!ret || ret == -ETIMEDOUT) { + /* Send hang event only if dhd_open() was success */ + if (dhd_pub->up) dhd_os_check_hang(dhd_pub, ifindex, ret); + } dhd_os_proto_unblock(dhd_pub); +#ifdef CUSTOMER_HW_SAMSUNG + if (ret < 0) { + if (ioc->cmd == WLC_GET_VAR) + DHD_ERROR(("%s: WLC_GET_VAR: %s, error = %d\n", + __FUNCTION__, (char *)ioc->buf, ret)); + else if (ioc->cmd == WLC_SET_VAR) + DHD_ERROR(("%s: WLC_SET_VAR: %s, error = %d\n", + __FUNCTION__, (char *)ioc->buf, ret)); + else + DHD_ERROR(("%s: WLC_IOCTL: cmd: %d, error = %d\n", + __FUNCTION__, ioc->cmd, ret)); + } +#endif /* CUSTOMER_HW_SAMSUNG */ return ret; } @@ -586,10 +575,8 @@ dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec) if (pktq_pfull(q, prec)) eprec = prec; else if (pktq_full(q)) { -#if defined(BCMASSERT_LOG) p = pktq_peek_tail(q, &eprec); - ASSERT(p); -#endif +// ASSERT(p); if (eprec > prec || eprec < 0) return FALSE; } @@ -608,11 +595,9 @@ dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec) PKTFREE(dhdp->osh, p, TRUE); } -#if defined(BCMASSERT_LOG) /* Enqueue */ p = pktq_penq(q, prec, pkt); - ASSERT(p); -#endif +// ASSERT(p); return TRUE; } diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c index 2e80890..4ef1dcb 100644 --- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c +++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c @@ -1,3 +1,19 @@ +/* Function list + 1. Module Type + a. For CID - Use 'USE_CID_CHECK' Feature + dhd_write_cid_file(), dhd_dump_cis(), dhd_check_module_cid() + b. For MAC - Use 'GET_MAC_FROM_OTP' Feature + dhd_write_mac_file(), dhd_check_module_mac() + 2. COB Type + a. For MAC - Use 'READ_MACADDR' Feature + dhd_read_macaddr() + 3. Etc + a. Power Save Mode - Use 'CONFIG_CONTROL_PM' Feature + sec_control_pm() + b. U1 Module only - Use 'WRITE_MACADDR' Feature + dhd_write_macaddr +*/ + #include <typedefs.h> #include <linuxver.h> #include <osl.h> @@ -21,6 +37,9 @@ extern int _dhd_set_mac_address(struct dhd_info *dhd, #define MACINFO "/opt/etc/.mac.info" #define REVINFO "/data/.rev" #else +#define MACINFO "/data/.mac.info" +#define MACINFO_EFS "/efs/wifi/.mac.info" +#define NVMACINFO "/data/.nvmac.info" #define REVINFO "/data/.rev" #define CIDINFO "/data/.cid.info" #define PSMINFO "/data/.psm.info" @@ -34,21 +53,21 @@ int dhd_read_macaddr(struct dhd_info *dhd, struct ether_addr *mac) mm_segment_t oldfs = {0}; char randommac[3] = {0}; char buf[18] = {0}; - char *filepath = "/efs/wifi/.mac.info"; + char *filepath_efs = MACINFO_EFS; #ifdef CONFIG_TARGET_LOCALE_VZW char *nvfilepath = "/data/misc/wifi/.nvmac.info"; #else - char *nvfilepath = "/data/.nvmac.info"; + char *nvfilepath = NVMACINFO; #endif int ret = 0; - fp = filp_open(filepath, O_RDONLY, 0); + fp = filp_open(filepath_efs, O_RDONLY, 0); if (IS_ERR(fp)) { start_readmac: /* File Doesn't Exist. Create and write mac addr.*/ - fp = filp_open(filepath, O_RDWR | O_CREAT, 0666); + fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp)) { - DHD_ERROR(("[WIFI] %s: File open error\n", filepath)); + DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs)); return -1; } oldfs = get_fs(); @@ -64,9 +83,9 @@ start_readmac: if (fp->f_mode & FMODE_WRITE) { ret = fp->f_op->write(fp, (const char *)macbuffer, sizeof(macbuffer), &fp->f_pos); if (ret < 0) - DHD_ERROR(("[WIFI]MAC address [%s] Failed to write into File: %s\n", macbuffer, filepath)); + DHD_ERROR(("[WIFI]MAC address [%s] Failed to write into File: %s\n", macbuffer, filepath_efs)); else - DHD_ERROR(("[WIFI]MAC address [%s] written into File: %s\n", macbuffer, filepath)); + DHD_ERROR(("[WIFI]MAC address [%s] written into File: %s\n", macbuffer, filepath_efs)); } set_fs(oldfs); /* Reading the MAC Address from .mac.info file( the existed file or just created file)*/ @@ -90,7 +109,7 @@ start_readmac: (unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]), (unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5])); else - DHD_ERROR(("dhd_bus_start: Reading from the '%s' returns 0 bytes\n", filepath)); + DHD_ERROR(("dhd_bus_start: Reading from the '%s' returns 0 bytes\n", filepath_efs)); if (fp) filp_close(fp, NULL); @@ -119,8 +138,8 @@ enum { int dhd_write_rdwr_macaddr(struct ether_addr *mac) { - char *filepath_old = "/data/.mac.info"; - char *filepath = "/efs/wifi/.mac.info"; + char *filepath_data = MACINFO; + char *filepath_efs = MACINFO_EFS; struct file *fp_mac = NULL; char buf[18] = {0}; mm_segment_t oldfs = {0}; @@ -134,9 +153,9 @@ int dhd_write_rdwr_macaddr(struct ether_addr *mac) mac->octet[3], mac->octet[4], mac->octet[5]); /* /data/.mac.info will be created */ - fp_mac = filp_open(filepath_old, O_RDWR | O_CREAT, 0666); + fp_mac = filp_open(filepath_data, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp_mac)) { - DHD_ERROR(("[WIFI] %s: File open error\n", filepath_old)); + DHD_ERROR(("[WIFI] %s: File open error\n", filepath_data)); return -1; } else { oldfs = get_fs(); @@ -147,18 +166,18 @@ int dhd_write_rdwr_macaddr(struct ether_addr *mac) sizeof(buf), &fp_mac->f_pos); if (ret < 0) DHD_ERROR(("[WIFI] Mac address [%s] Failed" - " to write into File: %s\n", buf, filepath_old)); + " to write into File: %s\n", buf, filepath_data)); else DHD_INFO(("[WIFI] Mac address [%s] written" - " into File: %s\n", buf, filepath_old)); + " into File: %s\n", buf, filepath_data)); } set_fs(oldfs); filp_close(fp_mac, NULL); } /* /efs/wifi/.mac.info will be created */ - fp_mac = filp_open(filepath, O_RDWR | O_CREAT, 0666); + fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp_mac)) { - DHD_ERROR(("[WIFI] %s: File open error\n", filepath)); + DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs)); return -1; } else { oldfs = get_fs(); @@ -169,10 +188,10 @@ int dhd_write_rdwr_macaddr(struct ether_addr *mac) sizeof(buf), &fp_mac->f_pos); if (ret < 0) DHD_ERROR(("[WIFI] Mac address [%s] Failed" - " to write into File: %s\n", buf, filepath)); + " to write into File: %s\n", buf, filepath_efs)); else DHD_INFO(("[WIFI] Mac address [%s] written" - " into File: %s\n", buf, filepath)); + " into File: %s\n", buf, filepath_efs)); } set_fs(oldfs); filp_close(fp_mac, NULL); @@ -190,12 +209,12 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp, char macbuffer[18] = {0}; char randommac[3] = {0}; char buf[18] = {0}; - char *filepath_old = "/data/.mac.info"; - char *filepath = "/efs/wifi/.mac.info"; + char *filepath_data = MACINFO; + char *filepath_efs = MACINFO_EFS; #ifdef CONFIG_TARGET_LOCALE_NA char *nvfilepath = "/data/misc/wifi/.nvmac.info"; #else - char *nvfilepath = "/data/.nvmac.info"; + char *nvfilepath = NVMACINFO; #endif char cur_mac[128] = {0}; char dummy_mac[ETHER_ADDR_LEN] = {0x00, 0x90, 0x4C, 0xC5, 0x12, 0x38}; @@ -231,7 +250,7 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp, cur_mac[0], cur_mac[1], cur_mac[2], cur_mac[3], cur_mac[4], cur_mac[5]); - fp_mac = filp_open(filepath_old, O_RDONLY, 0); + fp_mac = filp_open(filepath_data, O_RDONLY, 0); if (IS_ERR(fp_mac)) { /* file does not exist */ /* read mac is the dummy mac (00:90:4C:C5:12:38) */ if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0) @@ -280,7 +299,7 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp, } } } - fp_mac = filp_open(filepath, O_RDONLY, 0); + fp_mac = filp_open(filepath_efs, O_RDONLY, 0); if (IS_ERR(fp_mac)) { /* file does not exist */ /* read mac is the dummy mac (00:90:4C:C5:12:38) */ if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0) @@ -402,18 +421,18 @@ int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac) mm_segment_t oldfs = {0}; char randommac[3] = {0}; char buf[18] = {0}; - char *filepath = "/efs/wifi/.mac.info"; + char *filepath_efs = MACINFO_EFS; int is_zeromac = 0; int ret = 0; /* MAC address copied from efs/wifi.mac.info */ - fp = filp_open(filepath, O_RDONLY, 0); + fp = filp_open(filepath_efs, O_RDONLY, 0); if (IS_ERR(fp)) { /* File Doesn't Exist. Create and write mac addr.*/ - fp = filp_open(filepath, O_RDWR | O_CREAT, 0666); + fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp)) { DHD_ERROR(("[WIFI] %s: File open error\n", - filepath)); + filepath_efs)); return -1; } @@ -438,11 +457,11 @@ int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac) if (ret < 0) DHD_ERROR(("[WIFI] Mac address [%s]" " Failed to write into File:" - " %s\n", macbuffer, filepath)); + " %s\n", macbuffer, filepath_efs)); else DHD_ERROR(("[WIFI] Mac address [%s]" " written into File: %s\n", - macbuffer, filepath)); + macbuffer, filepath_efs)); } set_fs(oldfs); } else { @@ -473,7 +492,7 @@ int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac) (unsigned int *)&(mac->octet[5])); else DHD_INFO(("dhd_bus_start: Reading from the" - " '%s' returns 0 bytes\n", filepath)); + " '%s' returns 0 bytes\n", filepath_efs)); if (fp) filp_close(fp, NULL); @@ -494,16 +513,16 @@ int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac) #endif /* RDWR_KORICS_MACADDR */ #ifdef USE_CID_CHECK -static int dhd_write_cid_file(const char *filepath, const char *buf, int buf_len) +static int dhd_write_cid_file(const char *filepath_efs, const char *buf, int buf_len) { struct file *fp = NULL; mm_segment_t oldfs = {0}; int ret = 0; /* File is always created.*/ - fp = filp_open(filepath, O_RDWR | O_CREAT, 0666); + fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp)) { - DHD_ERROR(("[WIFI] %s: File open error\n", filepath)); + DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs)); return -1; } else { oldfs = get_fs(); @@ -513,10 +532,10 @@ static int dhd_write_cid_file(const char *filepath, const char *buf, int buf_len ret = fp->f_op->write(fp, buf, buf_len, &fp->f_pos); if (ret < 0) DHD_ERROR(("[WIFI] Failed to write CIS[%s]" - " into '%s'\n", buf, filepath)); + " into '%s'\n", buf, filepath_efs)); else DHD_ERROR(("[WIFI] CID [%s] written into" - " '%s'\n", buf, filepath)); + " '%s'\n", buf, filepath_efs)); } set_fs(oldfs); } @@ -664,7 +683,7 @@ static int dhd_write_mac_file(const char *filepath, const char *buf, int buf_len fp = filp_open(filepath, O_RDWR | O_CREAT, 0666); /*File is always created.*/ if (IS_ERR(fp)) { - DHD_ERROR(("[WIFI] %s: File open error\n", filepath)); + DHD_ERROR(("[WIFI] File open error\n")); return -1; } else { oldfs = get_fs(); @@ -673,11 +692,9 @@ static int dhd_write_mac_file(const char *filepath, const char *buf, int buf_len if (fp->f_mode & FMODE_WRITE) { ret = fp->f_op->write(fp, buf, buf_len, &fp->f_pos); if (ret < 0) - DHD_ERROR(("[WIFI] Failed to write CIS[%s]\ -into '%s'\n", buf, filepath)); + DHD_ERROR(("[WIFI] Failed to write CIS. \n")); else - DHD_ERROR(("[WIFI] MAC [%s] written\ -into '%s'\n", buf, filepath)); + DHD_ERROR(("[WIFI] MAC written. \n")); } set_fs(oldfs); } @@ -693,19 +710,13 @@ int dhd_check_module_mac(dhd_pub_t *dhd) int ret = -1; unsigned char cis_buf[250] = {0}; unsigned char mac_buf[20] = {0}; - const char *macfilepath = "/efs/wifi/.mac.info"; + unsigned char otp_mac_buf[20] = {0}; + const char *macfilepath = MACINFO_EFS; /* Try reading out from CIS */ cis_rw_t *cish = (cis_rw_t *)&cis_buf[8]; struct file *fp_mac = NULL; - fp_mac = filp_open(macfilepath, O_RDONLY, 0); - if (!IS_ERR(fp_mac)) { - kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf)); - DHD_ERROR(("[WIFI].mac.info file already exist : [%s]\n", - mac_buf)); - return 0; - } cish->source = 0; cish->byteoff = 0; cish->nbytes = sizeof(cis_buf); @@ -716,6 +727,7 @@ int dhd_check_module_mac(dhd_pub_t *dhd) if (ret < 0) { DHD_ERROR(("%s: CIS reading failed, err=%d\n", __func__, ret)); + return ret; } else { unsigned char mac_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; #ifdef DUMP_CIS @@ -728,11 +740,21 @@ int dhd_check_module_mac(dhd_pub_t *dhd) mac_id[4] = cis_buf[CIS_MAC_OFFSET + 4]; mac_id[5] = cis_buf[CIS_MAC_OFFSET + 5]; - sprintf(mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n", + sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n", mac_id[0], mac_id[1], mac_id[2], mac_id[3], mac_id[4], mac_id[5]); - DHD_ERROR(("[WIFI]mac_id is setted from OTP: [%s]\n", mac_buf)); - dhd_write_mac_file(macfilepath, mac_buf, sizeof(mac_buf)); + DHD_ERROR(("[WIFI]mac_id is setted from OTP \n")); + } + + fp_mac = filp_open(macfilepath, O_RDONLY, 0); + if (!IS_ERR(fp_mac)) { + DHD_ERROR(("[WIFI]Check Mac address in .mac.info \n")); + kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf)); + + if (strncmp(mac_buf , otp_mac_buf , 17) != 0) { + DHD_ERROR(("[WIFI]file MAC is wrong. Write OTP MAC in .mac.info \n")); + dhd_write_mac_file(macfilepath, otp_mac_buf, sizeof(otp_mac_buf)); + } } return ret; @@ -742,8 +764,8 @@ int dhd_check_module_mac(dhd_pub_t *dhd) #ifdef WRITE_MACADDR int dhd_write_macaddr(struct ether_addr *mac) { - char *filepath_old = "/data/.mac.info"; - char *filepath = "/efs/wifi/.mac.info"; + char *filepath_data = MACINFO; + char *filepath_efs = MACINFO_EFS; struct file *fp_mac = NULL; char buf[18] = {0}; @@ -758,10 +780,10 @@ startwrite: mac->octet[3], mac->octet[4], mac->octet[5]); /* File will be created /data/.mac.info. */ - fp_mac = filp_open(filepath_old, O_RDWR | O_CREAT, 0666); + fp_mac = filp_open(filepath_data, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp_mac)) { - DHD_ERROR(("[WIFI] %s: File open error\n", filepath_old)); + DHD_ERROR(("[WIFI] %s: File open error\n", filepath_data)); return -1; } else { oldfs = get_fs(); @@ -772,16 +794,16 @@ startwrite: sizeof(buf), &fp_mac->f_pos); if (ret < 0) DHD_ERROR(("[WIFI] Mac address [%s] Failed to" - " write into File: %s\n", buf, filepath_old)); + " write into File: %s\n", buf, filepath_data)); else DHD_INFO(("[WIFI] Mac address [%s] written" - " into File: %s\n", buf, filepath_old)); + " into File: %s\n", buf, filepath_data)); } set_fs(oldfs); filp_close(fp_mac, NULL); } /* check .mac.info file is 0 byte */ - fp_mac = filp_open(filepath_old, O_RDONLY, 0); + fp_mac = filp_open(filepath_data, O_RDONLY, 0); ret = kernel_read(fp_mac, 0, buf, 18); if ((ret == 0) && (retry_count++ < 3)) { @@ -793,10 +815,10 @@ startwrite: /* end of /data/.mac.info */ /* File will be created /efs/wifi/.mac.info. */ - fp_mac = filp_open(filepath, O_RDWR | O_CREAT, 0666); + fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666); if (IS_ERR(fp_mac)) { - DHD_ERROR(("[WIFI] %s: File open error\n", filepath)); + DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs)); return -1; } else { oldfs = get_fs(); @@ -807,17 +829,17 @@ startwrite: sizeof(buf), &fp_mac->f_pos); if (ret < 0) DHD_ERROR(("[WIFI] Mac address [%s] Failed to" - " write into File: %s\n", buf, filepath)); + " write into File: %s\n", buf, filepath_efs)); else DHD_INFO(("[WIFI] Mac address [%s] written" - " into File: %s\n", buf, filepath)); + " into File: %s\n", buf, filepath_efs)); } set_fs(oldfs); filp_close(fp_mac, NULL); } /* check .mac.info file is 0 byte */ - fp_mac = filp_open(filepath, O_RDONLY, 0); + fp_mac = filp_open(filepath_efs, O_RDONLY, 0); ret = kernel_read(fp_mac, 0, buf, 18); if ((ret == 0) && (retry_count++ < 3)) { diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c index d01b9fc..ca43dda 100644 --- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c +++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c @@ -244,6 +244,10 @@ static uint32 maxdelay = 0, tspktcnt = 0, maxdelaypktno = 0; #endif /* WLMEDIA_HTSF */ +#if defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP) +/*SLP_wakelock_alternative_code*/ +extern struct device *pm_dev; +#endif /* CONFIG_PM_SLEEP && CUSTOMER_HW_SLP */ #if defined(PKT_FILTER_SUPPORT) #if defined(CUSTOMER_HW_SAMSUNG) #define HEX_PREF_STR "0x" @@ -617,13 +621,17 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) #ifdef BCM4334_CHIP int bcn_li_bcn; #endif +#ifdef PASS_ALL_MCAST_PKTS + uint32 allmulti; +#endif /* PASS_ALL_MCAST_PKTS */ DHD_ERROR(("%s: enter, value = %d in_suspend=%d\n", __FUNCTION__, value, dhd->in_suspend)); if (dhd && dhd->up) { if (value && dhd->in_suspend) { - + if (wl_cfgp2p_p2p_listen_suspend()) + DHD_ERROR(("failed to set WLC_E_P2P_PROBREQ_MSG\n")); #ifdef PKT_FILTER_SUPPORT dhd->early_suspended = 1; #endif @@ -637,7 +645,17 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) #endif /* Enable packet filter, only allow unicast packet to send up */ - dhd_set_packet_filter(1, dhd); + if (dhd_pkt_filter_enable && !dhd->dhcp_in_progress) { + int i; + for (i = 0; i < dhd->pktfilter_count; i++) + dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], + 1, dhd_master_mode); + } +#ifdef PASS_ALL_MCAST_PKTS + allmulti = 0; + bcm_mkiovar("allmulti", (char *)&allmulti, 4, iovbuf, sizeof(iovbuf)); + dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); +#endif /* PASS_ALL_MCAST_PKTS */ #ifndef CUSTOMER_HW_SAMSUNG /* If DTIM skip is set up as default, force it to wake @@ -676,7 +694,17 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd) #endif /* disable pkt filter */ - dhd_set_packet_filter(0, dhd); + if (dhd_pkt_filter_enable && !dhd->dhcp_in_progress) { + int i; + for (i = 0; i < dhd->pktfilter_count; i++) + dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i], + 0, dhd_master_mode); + } +#ifdef PASS_ALL_MCAST_PKTS + allmulti = 1; + bcm_mkiovar("allmulti", (char *)&allmulti, 4, iovbuf, sizeof(iovbuf)); + dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0); +#endif /* PASS_ALL_MCAST_PKTS */ #ifndef CUSTOMER_HW_SAMSUNG /* restore pre-suspend setting for dtim_skip */ @@ -1319,7 +1347,10 @@ _dhd_sysioc_thread(void *data) } if (dhd->set_macaddress == i+1) { dhd->set_macaddress = 0; - _dhd_set_mac_address(dhd, i, &dhd->macvalue); + if (0 == _dhd_set_mac_address(dhd, i, &dhd->macvalue)) + DHD_INFO(("dhd_sysioc_thread: MACID is overwritten\n")); + else + DHD_ERROR(("dhd_sysioc_thread: _dhd_set_mac_address() failed\n")); } } } @@ -2334,16 +2365,6 @@ static bool dhd_check_hang(struct net_device *net, dhd_pub_t *dhdp, int error) { if (!dhdp) return FALSE; -#ifdef BCM4334_CHIP - if ((error == -ETIMEDOUT) || (error == -EREMOTEIO) || (dhdp->tx_seq_badcnt >= 2) - || ((dhdp->busstate == DHD_BUS_DOWN)&&(!dhdp->dongle_reset))) { - DHD_ERROR(("%s: Event HANG send up due to re=%d te=%d e=%d s=%d tse=%d\n", - __FUNCTION__, dhdp->rxcnt_timeout, dhdp->txcnt_timeout, error, - dhdp->busstate, dhdp->tx_seq_badcnt)); - net_os_send_hang_message(net); - return TRUE; - } -#else if ((error == -ETIMEDOUT) || (error == -EREMOTEIO) || ((dhdp->busstate == DHD_BUS_DOWN)&&(!dhdp->dongle_reset))) { DHD_ERROR(("%s: Event HANG send up due to re=%d te=%d e=%d s=%d\n", __FUNCTION__, @@ -2351,7 +2372,6 @@ static bool dhd_check_hang(struct net_device *net, dhd_pub_t *dhdp, int error) net_os_send_hang_message(net); return TRUE; } -#endif return FALSE; } @@ -2680,9 +2700,6 @@ dhd_stop(struct net_device *net) dhd->pub.hang_was_sent = 0; dhd->pub.rxcnt_timeout = 0; dhd->pub.txcnt_timeout = 0; -#ifdef BCM4334_CHIP - dhd->pub.tx_seq_badcnt = 0; -#endif OLD_MOD_DEC_USE_COUNT; exit: DHD_OS_WAKE_UNLOCK(&dhd->pub); @@ -3457,6 +3474,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) #ifdef AUTOCOUNTRY int autocountry = 1; #endif +#ifdef VSDB + int interference_mode = 3; +#endif #ifdef PROP_TXSTATUS dhd->wlfc_enabled = FALSE; /* enable WLFC only if the firmware is VSDB */ @@ -3736,7 +3756,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) setbit(eventmask, WLC_E_ACTION_FRAME_RX); setbit(eventmask, WLC_E_ACTION_FRAME_COMPLETE); setbit(eventmask, WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE); - setbit(eventmask, WLC_E_P2P_PROBREQ_MSG); setbit(eventmask, WLC_E_P2P_DISC_LISTEN_COMPLETE); } #endif /* WL_CFG80211 */ @@ -3812,6 +3831,12 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) } } #endif /* defined(SOFTAP) */ + if (dhd->pktfilter_count) { + int i; + + for (i = 0; i < dhd->pktfilter_count; i++) + dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]); + } #endif /* PKT_FILTER_SUPPORT */ #ifdef VLAN_MODE_OFF @@ -3828,6 +3853,9 @@ dhd_preinit_ioctls(dhd_pub_t *dhd) DHD_ERROR(("%s Setting WL UP failed %d\n", __FUNCTION__, ret)); goto done; } +#ifdef VSDB + dhd_wl_ioctl_cmd(dhd, WLC_SET_INTERFERENCE_MODE, (int *)&interference_mode, sizeof(int), TRUE, 0); +#endif #ifdef BCM4334_CHIP bcm_mkiovar("bcn_li_bcn", (char *)&bcn_li_bcn, 4, iovbuf, sizeof(iovbuf)); @@ -4598,6 +4626,9 @@ dhd_os_wd_timer(void *bus, uint wdtick) DHD_TRACE(("%s: Enter\n", __FUNCTION__)); + if (!dhd) + return; + flags = dhd_os_spin_lock(pub); /* don't start the wd until fw is loaded */ @@ -4936,7 +4967,7 @@ void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar) #if 1 && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)) struct dhd_info *dhdinfo = dhd->info; dhd_os_sdunlock(dhd); - wait_event_interruptible_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), HZ * 2); + wait_event_interruptible_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), HZ * 5); dhd_os_sdlock(dhd); #endif return; @@ -5034,6 +5065,7 @@ int net_os_rxfilter_add_remove(struct net_device *dev, int add_remove, int num) } } dhd->pub.pktfilter[num] = filterp; + dhd_pktfilter_offload_set(&dhd->pub, dhd->pub.pktfilter[num]); return ret; #else return 0; @@ -5052,8 +5084,12 @@ int net_os_set_packet_filter(struct net_device *dev, int val) */ if (dhd && dhd->pub.up) { if (dhd->pub.in_suspend) { - if (!val || (val && !dhd->pub.suspend_disable_flag)) - dhd_set_packet_filter(val, &dhd->pub); + if (!val || (val && !dhd->pub.suspend_disable_flag)) { + int i; + for (i = 0; i < dhd->pub.pktfilter_count; i++) + dhd_pktfilter_offload_enable(&dhd->pub, dhd->pub.pktfilter[i], + val, dhd_master_mode); + } } } return ret; @@ -5337,6 +5373,9 @@ int dhd_os_wake_lock(dhd_pub_t *pub) #ifdef CONFIG_HAS_WAKELOCK if (!dhd->wakelock_counter) wake_lock(&dhd->wl_wifi); +#elif defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP) + /*SLP_wakelock_alternative_code*/ + pm_stay_awake(pm_dev); #endif dhd->wakelock_counter++; ret = dhd->wakelock_counter; @@ -5369,6 +5408,9 @@ int dhd_os_wake_unlock(dhd_pub_t *pub) #ifdef CONFIG_HAS_WAKELOCK if (!dhd->wakelock_counter) wake_unlock(&dhd->wl_wifi); +#elif defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP) + /*SLP_wakelock_alternative_code*/ + pm_relax(pm_dev); #endif ret = dhd->wakelock_counter; } @@ -5389,6 +5431,19 @@ int dhd_os_check_wakelock(void *dhdp) if (dhd && wake_lock_active(&dhd->wl_wifi)) return 1; +#elif defined(CONFIG_PM_SLEEP) && defined(CUSTOMER_HW_SLP) + /*SLP_wakelock_alternative_code*/ + dhd_pub_t *pub = (dhd_pub_t *)dhdp; + dhd_info_t *dhd; + + if (!pub) + return 0; + dhd = (dhd_info_t *)(pub->info); + + DHD_ERROR(("%s : wakelock_count = %d\n", __func__, dhd->wakelock_counter )); + + if (dhd && (dhd->wakelock_counter > 0)) + return 1; #endif return 0; } diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c index 2c411f8..052eaaf 100644 --- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c +++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c @@ -265,9 +265,6 @@ typedef struct dhd_bus { bool activity; /* Activity flag for clock down */ int32 idletime; /* Control for activity timeout */ int32 idlecount; /* Activity timeout counter */ -#ifdef DHD_USE_IDLECOUNT - int32 dhd_idlecount; /* DHD idle count */ -#endif /* DHD_USE_IDLECOUNT */ int32 idleclock; /* How to set bus driver when idle */ int32 sd_divisor; /* Speed control to bus driver */ int32 sd_mode; /* Mode control to bus driver */ @@ -1034,7 +1031,7 @@ dhdsdio_htclk(dhd_bus_t *bus, bool on, bool pendok) bus->activity = TRUE; #ifdef DHD_USE_IDLECOUNT - bus->dhd_idlecount = 0; + bus->idlecount = 0; #endif /* DHD_USE_IDLECOUNT */ } else { clkreq = 0; @@ -1162,7 +1159,7 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); bus->activity = TRUE; #ifdef DHD_USE_IDLECOUNT - bus->dhd_idlecount = 0; + bus->idlecount = 0; #endif /* DHD_USE_IDLECOUNT */ } return ret; @@ -1179,7 +1176,7 @@ dhdsdio_clkctl(dhd_bus_t *bus, uint target, bool pendok) dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms); bus->activity = TRUE; #ifdef DHD_USE_IDLECOUNT - bus->dhd_idlecount = 0; + bus->idlecount = 0; #endif /* DHD_USE_IDLECOUNT */ } break; @@ -1828,8 +1825,13 @@ dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen) /* Send from dpc */ bus->ctrl_frame_buf = frame; bus->ctrl_frame_len = len; - - dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat); + if(!bus->dpc_sched) { + bus->dpc_sched = TRUE; + dhd_sched_dpc(bus->dhd); + } + if (bus->ctrl_frame_stat) { + dhd_wait_for_event(bus->dhd, &bus->ctrl_frame_stat); + } if (bus->ctrl_frame_stat == FALSE) { DHD_INFO(("%s: ctrl_frame_stat == FALSE\n", __FUNCTION__)); @@ -4645,22 +4647,11 @@ dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) } /* Check window for sanity */ -#ifdef BCM4334_CHIP - if ((uint8)(txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", - __FUNCTION__, txmax, bus->tx_seq)); - txmax = bus->tx_max; - bus->dhd->tx_seq_badcnt++; - } - else - bus->dhd->tx_seq_badcnt = 0; -#else if ((uint8)(txmax - bus->tx_seq) > 0x40) { DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", __FUNCTION__, txmax, bus->tx_seq)); txmax = bus->tx_max; } -#endif bus->tx_max = txmax; #ifdef DHD_DEBUG @@ -4813,22 +4804,11 @@ dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) } /* Check window for sanity */ -#ifdef BCM4334_CHIP - if ((uint8)(txmax - bus->tx_seq) > 0x40) { - DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", - __FUNCTION__, txmax, bus->tx_seq)); - txmax = bus->tx_max; - bus->dhd->tx_seq_badcnt++; - } - else - bus->dhd->tx_seq_badcnt = 0; -#else if ((uint8)(txmax - bus->tx_seq) > 0x40) { DHD_ERROR(("%s: got unlikely tx max %d with tx_seq %d\n", __FUNCTION__, txmax, bus->tx_seq)); txmax = bus->tx_max; } -#endif bus->tx_max = txmax; /* Call a separate function for control frames */ @@ -5296,6 +5276,13 @@ clkwait: if (TXCTLOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) { int ret, i; + uint8* frame_seq = bus->ctrl_frame_buf + SDPCM_FRAMETAG_LEN; + if (*frame_seq != bus->tx_seq) { + DHD_INFO(("%s IOCTL frame seq lag detected!" + " frm_seq:%d != bus->tx_seq:%d, corrected\n", + __FUNCTION__, *frame_seq, bus->tx_seq)); + *frame_seq = bus->tx_seq; + } ret = dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC, (uint8 *)bus->ctrl_frame_buf, (uint32)bus->ctrl_frame_len, @@ -5720,9 +5707,6 @@ dhd_disable_intr(dhd_pub_t *dhdp) bcmsdh_intr_disable(bus->sdh); } -#ifdef DHD_USE_IDLECOUNT -#define DHD_IDLE_TIMEOUT_MS (50) -#endif /* DHD_USE_IDLECOUNT */ extern bool dhd_bus_watchdog(dhd_pub_t *dhdp) @@ -5805,31 +5789,27 @@ dhd_bus_watchdog(dhd_pub_t *dhdp) #endif /* On idle timeout clear activity flag and/or turn off clock */ - if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { #ifdef DHD_USE_IDLECOUNT - if (++bus->idlecount >= bus->idletime) { - bus->idlecount = 0; if (bus->activity) bus->activity = FALSE; else { - bus->dhd_idlecount++; + bus->idlecount++; - if (bus->dhd_idlecount >= (DHD_IDLE_TIMEOUT_MS/dhd_watchdog_ms)) { + if (bus->idlecount >= bus->idletime) { DHD_TIMER(("%s: DHD Idle state!!\n", __FUNCTION__)); if (SLPAUTO_ENAB(bus)) { if (dhdsdio_bussleep(bus, TRUE) != BCME_BUSY) dhd_os_wd_timer(bus->dhd, 0); - } - else + } else dhdsdio_clkctl(bus, CLK_NONE, FALSE); - bus->dhd_idlecount = 0; + bus->idlecount = 0; } } - } #else + if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { if (++bus->idlecount >= bus->idletime) { bus->idlecount = 0; if (bus->activity) { @@ -5840,8 +5820,8 @@ dhd_bus_watchdog(dhd_pub_t *dhdp) dhdsdio_clkctl(bus, CLK_NONE, FALSE); } } -#endif /* DHD_USE_IDLECOUNT */ } +#endif /* DHD_USE_IDLECOUNT */ return bus->ipend; } @@ -6147,6 +6127,12 @@ dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot, goto fail; } +#ifdef BCMHOST_XTAL_PU_TIME_MOD +#ifdef BCM4334_CHIP + bcmsdh_reg_write(bus->sdh, 0x18000620, 2, 11); + bcmsdh_reg_write(bus->sdh, 0x18000628, 4, 0x00A60001); +#endif +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) mutex_unlock(&_dhd_sdio_mutex_lock_); DHD_ERROR(("%s : the lock is released.\n", __FUNCTION__)); diff --git a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h index 89fc7ee..2d1d200 100644 --- a/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h +++ b/drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h @@ -40,7 +40,8 @@ #define HW_OOB #endif -#ifdef CONFIG_MACH_U1 /* Q1 also uses this feature */ +/* Q1 also uses this feature */ +#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_TRATS) #ifdef CONFIG_MACH_Q1_BD #define HW_OOB #endif @@ -48,6 +49,11 @@ #define WRITE_MACADDR #endif +#ifdef CONFIG_MACH_GC1 +#undef USE_CID_CHECK +#define READ_MACADDR +#endif + /* REGION CODE */ #if (WLAN_REGION_CODE >= 100) && (WLAN_REGION_CODE < 200) /*EUR*/ @@ -106,3 +112,6 @@ #define BCMWAPI_WAI #endif +#if !defined(READ_MACADDR) && !defined(WRITE_MACADDR) && !defined(RDWR_KORICS_MACADDR) && !defined(RDWR_MACADDR) +#define GET_MAC_FROM_OTP +#endif diff --git a/drivers/net/wireless/bcmdhd/src/include/epivers.h b/drivers/net/wireless/bcmdhd/src/include/epivers.h index 058f1d4..8be59f6 100644 --- a/drivers/net/wireless/bcmdhd/src/include/epivers.h +++ b/drivers/net/wireless/bcmdhd/src/include/epivers.h @@ -30,19 +30,19 @@ #define EPI_MINOR_VERSION 15 -#define EPI_RC_NUMBER 11 +#define EPI_RC_NUMBER 12 #define EPI_INCREMENTAL_NUMBER 0 #define EPI_BUILD_NUMBER 0 -#define EPI_VERSION 1, 15, 11, 0 +#define EPI_VERSION 1, 15, 12, 0 #define EPI_VERSION_NUM 0x010f0900 -#define EPI_VERSION_DEV 1.15.11 +#define EPI_VERSION_DEV 1.15.12 -#define EPI_VERSION_STR "1.15.11" +#define EPI_VERSION_STR "1.15.12" #endif /* _epivers_h_ */ diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c index 1704701..49782c5 100644 --- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c +++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c @@ -132,7 +132,10 @@ typedef struct cmd_tlv { #ifdef BCM4334_CHIP //ampdu_mpdu #define CMD_AMPDU_MPDU "AMPDU_MPDU" #endif - +#ifdef VSDB +#define CMD_CHANGE_RL "CHANGE_RL" +#define CMD_RESTORE_RL "RESTORE_RL" +#endif typedef struct android_wifi_priv_cmd { char *buf; int used_len; @@ -778,10 +781,12 @@ wl_android_set_auto_channel(struct net_device *dev, const char* string_num, } done: - snprintf(command, total_len, "%d", channel); +// snprintf(command, total_len, "%d", channel); + snprintf(command, 4, "%d", channel); DHD_INFO(("%s: command result is %s\n", __FUNCTION__, command)); - return 1; +// return 1; + return 4; } static int @@ -895,6 +900,31 @@ wl_android_okc_enable(struct net_device *dev, char *command, int total_len) } #endif /* OKC_ SUPPORT */ +#ifdef VSDB +static int +wl_android_ch_res_rl(struct net_device *dev, bool change) +{ + int error = 0; + s32 srl = 7; + s32 lrl = 4; + printk("%s enter\n", __FUNCTION__); + if (change) { + srl = 4; + lrl = 2; + } + error = wldev_ioctl(dev, WLC_SET_SRL, &srl, + sizeof(s32), true); + if (error) { + DHD_ERROR(("Failed to set SRL, error = %d\n", error)); + } + error = wldev_ioctl(dev, WLC_SET_LRL, &lrl, + sizeof(s32), true); + if (error) { + DHD_ERROR(("Failed to set LRL, error = %d\n", error)); + } + return error; +} +#endif #ifdef BCM4334_CHIP //ampdu_mpdu static int @@ -1012,8 +1042,9 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) /* TBD: BTCOEXSCAN-STOP */ } else if (strnicmp(command, CMD_BTCOEXMODE, strlen(CMD_BTCOEXMODE)) == 0) { +#if !defined(CUSTOMER_HW_SAMSUNG) uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0'; -#if 0 + if (mode == 1) net_os_set_packet_filter(net, 0); /* DHCP starts */ else @@ -1116,7 +1147,9 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) else if (strnicmp(command, CMD_SET_HAPD_AUTO_CHANNEL, strlen(CMD_SET_HAPD_AUTO_CHANNEL)) == 0) { int skip = strlen(CMD_SET_HAPD_AUTO_CHANNEL) + 3; - wl_android_set_auto_channel(net, (const char*)command+skip, command, +// wl_android_set_auto_channel(net, (const char*)command+skip, command, +// priv_cmd.total_len); + bytes_written = wl_android_set_auto_channel(net, (const char*)command+skip, command, priv_cmd.total_len); } else if (strnicmp(command, CMD_SET_HAPD_MAX_NUM_STA, @@ -1162,6 +1195,12 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) bytes_written = wl_android_set_ampdu_mpdu(net, (const char*)command+skip); } #endif +#ifdef VSDB + else if (strnicmp(command, CMD_CHANGE_RL, strlen(CMD_CHANGE_RL)) == 0) + bytes_written = wl_android_ch_res_rl(net, true); + else if (strnicmp(command, CMD_RESTORE_RL, strlen(CMD_RESTORE_RL)) == 0) + bytes_written = wl_android_ch_res_rl(net, false); +#endif else { if ((strnicmp(command, CMD_START, strlen(CMD_START)) != 0) && (strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) != 0)) diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c index f805d60..c74adcc 100644 --- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c +++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c @@ -402,7 +402,6 @@ static __used bool wl_is_ibssstarter(struct wl_priv *wl); */ static s32 __wl_cfg80211_up(struct wl_priv *wl); static s32 __wl_cfg80211_down(struct wl_priv *wl); -static s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add); static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e); static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e, struct net_device *ndev); static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e); @@ -2462,9 +2461,9 @@ wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) val = WL_AUTH_OPEN_SHARED; WL_DBG(("automatic\n")); break; +#ifdef BCMCCX case NL80211_AUTHTYPE_NETWORK_EAP: WL_DBG(("network eap\n")); -#ifdef BCMCCX val = DOT11_LEAP_AUTH; break; #endif @@ -4286,6 +4285,7 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev, #ifdef WL_CFG80211_SYNC_GON_TIME bool is_waiting_more_time = false; #endif /* WL_CFG80211_SYNC_GON_TIME */ + bool is_PROVDIS_REQ_GO = false; WL_DBG(("Enter \n")); @@ -4542,8 +4542,14 @@ wl_cfg80211_mgmt_tx(struct wiphy *wiphy, struct net_device *ndev, memcpy(wl->afx_hdl->tx_dst_addr.octet, af_params->action_frame.da.octet, sizeof(wl->afx_hdl->tx_dst_addr.octet)); + if ((act_frm->subtype == P2P_PAF_PROVDIS_REQ) && + (p2p_ie = wl_cfgp2p_find_p2pie((u8 *)act_frm->elts, action_frame->len)) != NULL) { + if ((ptr = wl_cfgp2p_retreive_p2pattrib(p2p_ie, P2P_SEID_GROUP_ID))) { + is_PROVDIS_REQ_GO = true; + } + } - if (IS_P2P_SOCIAL(af_params->channel) && + if (!is_PROVDIS_REQ_GO && IS_P2P_SOCIAL(af_params->channel) && (IS_P2P_PUB_ACT_REQ(act_frm, action_frame->len) || IS_GAS_REQ(sd_act_frm, action_frame->len)) && wl_to_p2p_bss_saved_ie(wl, P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len) { @@ -5132,6 +5138,14 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev, is_bssup = wl_cfgp2p_bss_isup(dev, bssidx); if (!is_bssup && (wpa2_ie != NULL)) { + if (!info->dtim_period) { + info->dtim_period = 1; + } + if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD, + &info->dtim_period, sizeof(s32), true)) < 0) { + WL_ERR(("DTIM Interval Set Error, %d\n", err)); + return err; + } wldev_iovar_setint(dev, "mpc", 0); if ((err = wl_validate_wpa2ie(dev, wpa2_ie, bssidx)) < 0) { WL_ERR(("WPA2 IE parsing error")); @@ -5248,13 +5262,15 @@ wl_cfg80211_add_set_beacon(struct wiphy *wiphy, struct net_device *dev, return err; } } - if (info->dtim_period) { - if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD, - &info->dtim_period, sizeof(s32), true)) < 0) { - WL_ERR(("DTIM Interval Set Error, %d\n", err)); - return err; - } + if (!info->dtim_period) { + info->dtim_period = 1; } + if ((err = wldev_ioctl(dev, WLC_SET_DTIMPRD, + &info->dtim_period, sizeof(s32), true)) < 0) { + WL_ERR(("DTIM Interval Set Error, %d\n", err)); + return err; + } + err = wldev_ioctl(dev, WLC_UP, &ap, sizeof(s32), true); if (unlikely(err)) { WL_ERR(("WLC_UP error (%d)\n", err)); @@ -5734,20 +5750,26 @@ wl_notify_connect_status_ap(struct wl_priv *wl, struct net_device *ndev, } #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) && !CFG80211_STA_EVENT_AVAILABLE - body=kzalloc(len, GFP_KERNEL); WL_DBG(("Enter \n")); + if (!len && (event == WLC_E_DEAUTH)) { + len = 2; /* reason code field */ + data = &reason; + } + if (len) { + body=kzalloc(len, GFP_KERNEL); + if(body==NULL) { WL_ERR(("wl_notify_connect_status: Failed to allocate body\n")); return WL_INVALID; } - + } memset(&bssid, 0, ETHER_ADDR_LEN); WL_DBG(("Enter \n")); if (wl_get_mode_by_netdev(wl, ndev) == WL_INVALID) { kfree(body); return WL_INVALID; } - + if (len) memcpy(body, data, len); wldev_iovar_getbuf_bsscfg(ndev, "cur_etheraddr", NULL, 0, wl->ioctl_buf, WLC_IOCTL_MAXLEN, bsscfgidx, &wl->ioctl_buf_sync); @@ -5858,8 +5880,6 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, if (wl_is_linkup(wl, e, ndev)) { wl_link_up(wl); act = true; - wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT); - wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID); if (wl_is_ibssmode(wl, ndev)) { printk("cfg80211_ibss_joined\n"); cfg80211_ibss_joined(ndev, (s8 *)&e->addr, @@ -5874,6 +5894,8 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, wl_read_prof(wl, ndev, WL_PROF_SSID))->SSID)); } } + wl_update_prof(wl, ndev, e, &act, WL_PROF_ACT); + wl_update_prof(wl, ndev, NULL, (void *)&e->addr, WL_PROF_BSSID); } else if (wl_is_linkdown(wl, e)) { if (wl->scan_request) { @@ -6222,18 +6244,17 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, WL_DBG((" Enter\n")); #ifdef ESCAN_RESULT_PATCH - if (memcmp(curbssid, broad_bssid, ETHER_ADDR_LEN) == 0 && - memcmp(broad_bssid, connect_req_bssid, ETHER_ADDR_LEN) != 0) { - WL_DBG(("copy bssid\n")); - memcpy(curbssid, connect_req_bssid, ETHER_ADDR_LEN); - } if (wl_get_drv_status(wl, CONNECTED, ndev)) { if (memcmp(curbssid, connect_req_bssid, ETHER_ADDR_LEN) == 0) { WL_ERR((" Connected event of connected device, ignore it\n")); return err; } } - + if (memcmp(curbssid, broad_bssid, ETHER_ADDR_LEN) == 0 && + memcmp(broad_bssid, connect_req_bssid, ETHER_ADDR_LEN) != 0) { + WL_DBG(("copy bssid\n")); + memcpy(curbssid, connect_req_bssid, ETHER_ADDR_LEN); + } WL_SCAN2(("Connect done \n")); #if defined(BCM4334_CHIP) @@ -6403,7 +6424,8 @@ wl_frame_get_mgmt(u16 fc, const struct ether_addr *da, bcopy((const char*)da, (u8*)&hdr->da, ETHER_ADDR_LEN); bcopy((const char*)sa, (u8*)&hdr->sa, ETHER_ADDR_LEN); bcopy((const char*)bssid, (u8*)&hdr->bssid, ETHER_ADDR_LEN); - bcopy((const char*)pbody, offset, prebody_len); + if ((pbody != NULL) && prebody_len) + bcopy((const char*)pbody, offset, prebody_len); *body_len = totlen; return err; } @@ -7103,7 +7125,8 @@ wl_cfg80211_netdev_notifier_call(struct notifier_block * nb, return NOTIFY_DONE; switch (state) { case NETDEV_DOWN: - while(work_pending(&wdev->cleanup_work)) { + while(work_pending(&wdev->cleanup_work) && refcnt < 100) { + if(refcnt%5==0) WL_ERR(("%s : [NETDEV_DOWN] work_pending (%d th)\n", __FUNCTION__, refcnt)); set_current_state(TASK_INTERRUPTIBLE); @@ -7265,10 +7288,6 @@ static s32 wl_escan_handler(struct wl_priv *wl, } else { int cur_len = 0; list = (wl_scan_results_t *)wl->escan_info.escan_buf[wl->escan_info.cur_sync_id%2]; - if (bi_length > ESCAN_BUF_SIZE - list->buflen) { - WL_ERR(("Buffer is too small: ignoring\n")); - goto exit; - } #define WLC_BSS_RSSI_ON_CHANNEL 0x0002 for (i = 0; i < list->count; i++) { bss = bss ? (wl_bss_info_t *)((uintptr)bss + dtoh32(bss->length)) @@ -7276,25 +7295,26 @@ static s32 wl_escan_handler(struct wl_priv *wl, if (!bcmp(&bi->BSSID, &bss->BSSID, ETHER_ADDR_LEN) && CHSPEC_BAND(bi->chanspec) == CHSPEC_BAND(bss->chanspec) && bi->SSID_len == bss->SSID_len && - !bcmp(bi->SSID, bss->SSID, bi->SSID_len) - && (bi->length == bss->length)) { - if (p2p_is_on(wl) && p2p_scan(wl)) { - if (bss->dtoh32(ie_length)< bi_length) { - int prev_len = dtoh32(bss->length); - WL_SCAN2(("bss info replacement is occured(bcast:%d->probresp%d)\n", - bss->ie_length, bi->ie_length)); - /* prev : broadcast, cur : prob_resp */ - if (list->count != 1 && i < list->count -1) { - /* memory copy required by this case only */ - memcpy((u8 *)bss, - (u8 *)bss + prev_len, list->buflen - cur_len - prev_len); - } - list->buflen -= prev_len; - memcpy(&(((u8 *)list)[list->buflen]), bi, bi_length); - list->version = dtoh32(bi->version); - list->buflen += bi_length; + !bcmp(bi->SSID, bss->SSID, bi->SSID_len)) { + if (bss->dtoh32(ie_length) != bi_length) { + int prev_len = dtoh32(bss->length); + WL_SCAN2(("bss info replacement is occured(bcast:%d->probresp%d)\n", + bss->ie_length, bi->ie_length)); + /* prev : broadcast, cur : prob_resp */ + if (list->count != 1 && i < list->count -1) { + /* memory copy required by this case only */ + memcpy((u8 *)bss, + (u8 *)bss + prev_len, list->buflen - cur_len - prev_len); + } + list->buflen -= prev_len; + if (bi_length > ESCAN_BUF_SIZE - list->buflen) { + WL_ERR(("Buffer is too small: ignoring\n")); goto exit; } + memcpy(&(((u8 *)list)[list->buflen]), bi, bi_length); + list->version = dtoh32(bi->version); + list->buflen += bi_length; + goto exit; } if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) == (bi->flags & WLC_BSS_RSSI_ON_CHANNEL)) { @@ -7315,6 +7335,10 @@ static s32 wl_escan_handler(struct wl_priv *wl, } cur_len += dtoh32(bss->length); } + if (bi_length > ESCAN_BUF_SIZE - list->buflen) { + WL_ERR(("Buffer is too small: ignoring\n")); + goto exit; + } memcpy(&(wl->escan_info.escan_buf[wl->escan_info.cur_sync_id%2][list->buflen]), bi, bi_length); list->version = dtoh32(bi->version); list->buflen += bi_length; @@ -7373,6 +7397,12 @@ static s32 wl_escan_handler(struct wl_priv *wl, } wl->escan_info.cur_sync_id += 2; } + else if (status == WLC_E_STATUS_NEWSCAN) + { + escan_result = (wl_escan_result_t *) data; + WL_ERR(("WLC_E_STATUS_NEWSCAN : scan_request[%p]\n", wl->scan_request)); + WL_ERR(("sync_id[%d], bss_count[%d]\n", escan_result->sync_id, escan_result->bss_count)); + } else { WL_ERR(("unexpected Escan Event %d : abort\n", status)); wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE; @@ -7405,12 +7435,17 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in { s32 pm = PM_FAST; s32 err = BCME_OK; + s32 glom = -1; + u32 chan = 0; + u32 chanspec = 0; + u32 prev_chan = 0; + u32 connected_cnt = 0; struct net_info *iter, *next; + struct net_device *primary_dev = wl_to_prmry_ndev(wl); if (set) { /* set */ switch (state) { case WL_STATUS_CONNECTED: { - if (wl_get_drv_status_all(wl, CONNECTED) > 1) { - wl->vsdb_mode = true; + if ((connected_cnt = wl_get_drv_status_all(wl, CONNECTED)) > 1) { pm = PM_OFF; WL_INFO(("Do not enable the power save for VSDB mode\n")); } else if (_net_info->pm_block) { @@ -7419,10 +7454,22 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in pm = PM_FAST; } for_each_ndev(wl, iter, next) { - if (!wl->vsdb_mode && (iter->ndev != _net_info->ndev)) + if ((connected_cnt == 1) && (iter->ndev != _net_info->ndev)) continue; - if (wl_get_drv_status(wl, CONNECTED, iter->ndev) && - (wl_get_mode_by_netdev(wl, iter->ndev) == WL_MODE_BSS)) { + chanspec = 0; + chan = 0; + if (wl_get_drv_status(wl, CONNECTED, iter->ndev)) { + if (wldev_iovar_getint(iter->ndev, "chanspec", (s32 *)&chanspec) == BCME_OK) { + chan = CHSPEC_CHANNEL(chanspec); + if (CHSPEC_IS40(chanspec)) { + if (CHSPEC_SB_UPPER(chanspec)) + chan += CH_10MHZ_APART; + else + chan -= CH_10MHZ_APART; + } + wl_update_prof(wl, iter->ndev, NULL, &chan, WL_PROF_CHAN); + } + if ((wl_get_mode_by_netdev(wl, iter->ndev) == WL_MODE_BSS)) { pm = htod32(pm); WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled"))); err = wldev_ioctl(iter->ndev, WLC_SET_PM, &pm, sizeof(pm), true); @@ -7434,6 +7481,23 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in break; } } + if (connected_cnt > 1) { + if (!prev_chan && chan) + prev_chan = chan; + else if (prev_chan && (prev_chan != chan)){ + wl->vsdb_mode = true; + } + } + } + } + if ((wl_get_mode_by_netdev(wl, _net_info->ndev) == WL_MODE_AP) && p2p_is_on(wl)) + if (wl_add_remove_eventmsg(primary_dev, WLC_E_P2P_PROBREQ_MSG, true) != BCME_OK) + CFGP2P_ERR((" failed to set WLC_E_P2P_PROPREQ_MSG\n")); + if (!wl->vsdb_mode && (connected_cnt > 1)) { + if (wldev_iovar_getint(primary_dev, "bus:txglom", (s32 *)&glom) == BCME_OK) { + wl->glom = glom; + wldev_iovar_setint(primary_dev, "bus:txglom", 0); + } } break; } @@ -7443,6 +7507,8 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in } else { /* clear */ switch (state) { case WL_STATUS_CONNECTED: { + chan = 0; + wl_update_prof(wl, _net_info->ndev, NULL, &chan, WL_PROF_CHAN); if (wl_get_drv_status_all(wl, CONNECTED) == 1) { wl->vsdb_mode = false; for_each_ndev(wl, iter, next) { @@ -7465,7 +7531,13 @@ static s32 wl_notifier_change_state(struct wl_priv *wl, struct net_info *_net_in } } } + if (wl->glom != -1) + wldev_iovar_setint(primary_dev, "bus:txglom", wl->glom); + wl->glom = -1; } + if ((wl_get_mode_by_netdev(wl, _net_info->ndev) == WL_MODE_AP) && p2p_is_on(wl)) + if (wl_add_remove_eventmsg(primary_dev, WLC_E_P2P_PROBREQ_MSG, false) != BCME_OK) + CFGP2P_ERR((" failed to unset WLC_E_P2P_PROPREQ_MSG\n")); break; } default: @@ -7524,6 +7596,7 @@ static s32 wl_init_priv(struct wl_priv *wl) wl->rf_blocked = false; wl->first_remain = true; wl->wlfc_on = false; + wl->glom = -1; set_bit(WL_STATUS_CONNECTED, &wl->interrested_state); spin_lock_init(&wl->cfgdrv_lock); mutex_init(&wl->ioctl_buf_sync); @@ -7997,7 +8070,7 @@ static s32 wl_config_ifmode(struct wl_priv *wl, struct net_device *ndev, s32 ift return 0; } -static s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add) +s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add) { s8 iovbuf[WL_EVENTING_MASK_LEN + 12]; @@ -8088,6 +8161,9 @@ static int wl_construct_reginfo(struct wl_priv *wl, s32 bw_cap) n_cnt = &n_5g; band = IEEE80211_BAND_5GHZ; ht40_allowed = (bw_cap == WLC_N_BW_20ALL)? false : true; + } else { + WL_ERR(("Invalid channel Sepc. 0x%x.\n", c)); + continue; } for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { if (band_chan_arr[j].hw_value == channel) { @@ -8377,6 +8453,8 @@ static void *wl_read_prof(struct wl_priv *wl, struct net_device *ndev, s32 item) break; case WL_PROF_SSID: rptr = &profile->ssid; + case WL_PROF_CHAN: + rptr = &profile->channel; break; } spin_unlock_irqrestore(&wl->cfgdrv_lock, flags); @@ -8423,6 +8501,8 @@ wl_update_prof(struct wl_priv *wl, struct net_device *ndev, case WL_PROF_DTIMPERIOD: profile->dtim_period = *(u8 *)data; break; + case WL_PROF_CHAN: + profile->channel = *(u32*)data; default: err = -EOPNOTSUPP; break; @@ -8607,17 +8687,44 @@ s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len, { struct wl_priv *wl; struct net_device *ndev = NULL; + struct ether_addr primary_mac; s32 ret = 0; s32 bssidx = 0; s32 pktflag = 0; wl = wlcfg_drv_priv; - if (wl->p2p && wl->p2p->vif_created) { - ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION); - bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION); - } else if (wl_get_drv_status(wl, AP_CREATING, net) || + + if (wl_get_drv_status(wl, AP_CREATING, net) || wl_get_drv_status(wl, AP_CREATED, net)) { ndev = net; bssidx = 0; + } else if (wl->p2p) { + if (net == wl->p2p_net) { + net = wl_to_prmry_ndev(wl); + } + if (!wl->p2p->on) { + get_primary_mac(wl, &primary_mac); + wl_cfgp2p_generate_bss_mac(&primary_mac, &wl->p2p->dev_addr, &wl->p2p->int_addr); + + /* In case of p2p_listen command, supplicant send remain_on_channel + * without turning on P2P + */ + + p2p_on(wl) = true; + ret = wl_cfgp2p_enable_discovery(wl, net, NULL, 0); + + if (unlikely(ret)) { + goto exit; + } + } + if (net != wl_to_prmry_ndev(wl)) { + if (wl_get_mode_by_netdev(wl, net) == WL_MODE_AP) { + ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION); + bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION); + } + } else { + ndev = wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_PRIMARY); + bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); + } } if (ndev != NULL) { switch (type) { @@ -8634,7 +8741,7 @@ s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len, if (pktflag) ret = wl_cfgp2p_set_management_ie(wl, ndev, bssidx, pktflag, buf, len); } - +exit: return ret; } diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h index cc8e7e1..04bd49e 100644 --- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h +++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h @@ -65,7 +65,7 @@ struct wl_ibss; #define WL_ERR(args) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ - printk(KERN_ERR "CFG80211-INFO2) %s : ", __func__); \ + printk(KERN_INFO "CFG80211-INFO2) %s : ", __func__); \ printk args; \ } \ } while (0) @@ -75,7 +75,7 @@ do { \ #define WL_INFO(args) \ do { \ if (wl_dbg_level & WL_DBG_INFO) { \ - printk(KERN_ERR "CFG80211-INFO) %s : ", __func__); \ + printk(KERN_INFO "CFG80211-INFO) %s : ", __func__); \ printk args; \ } \ } while (0) @@ -85,7 +85,7 @@ do { \ #define WL_SCAN(args) \ do { \ if (wl_dbg_level & WL_DBG_SCAN) { \ - printk(KERN_ERR "CFG80211-SCAN) %s :", __func__); \ + printk(KERN_INFO "CFG80211-SCAN) %s :", __func__); \ printk args; \ } \ } while (0) @@ -95,7 +95,7 @@ do { \ #define WL_TRACE(args) \ do { \ if (wl_dbg_level & WL_DBG_TRACE) { \ - printk(KERN_ERR "CFG80211-TRACE) %s :", __func__); \ + printk(KERN_INFO "CFG80211-TRACE) %s :", __func__); \ printk args; \ } \ } while (0) @@ -103,7 +103,7 @@ do { \ #define WL_DBG(args) \ do { \ if (wl_dbg_level & WL_DBG_DBG) { \ - printk(KERN_ERR "CFG80211-DEBUG) %s :", __func__); \ + printk(KERN_DEBUG "CFG80211-DEBUG) %s :", __func__); \ printk args; \ } \ } while (0) @@ -116,7 +116,7 @@ do { \ #define WL_SCAN2(args) \ do { \ if (wl_dbg_level & WL_DBG_SCAN2) { \ - printk(KERN_ERR "CFG80211-SCAN) %s :", __func__); \ + printk(KERN_DEBUG "CFG80211-SCAN) %s :", __func__); \ printk args; \ } \ } while (0) @@ -193,6 +193,7 @@ enum wl_prof_list { WL_PROF_SEC, WL_PROF_IBSS, WL_PROF_BAND, + WL_PROF_CHAN, WL_PROF_BSSID, WL_PROF_ACT, WL_PROF_BEACONINT, @@ -292,6 +293,7 @@ struct wl_ibss { struct wl_profile { u32 mode; s32 band; + u32 channel; struct wlc_ssid ssid; struct wl_security sec; struct wl_ibss ibss; @@ -453,6 +455,7 @@ struct wl_priv { void *pub; u32 iface_cnt; u32 channel; /* current channel */ + s32 glom; #ifdef WL_CFG80211_SYNC_GON_TIME u32 af_sent_channel; /* channel action frame is sent */ /* save the next gon af subtype when it needs to wait more time for next gon af @@ -796,4 +799,5 @@ extern s32 wl_update_wiphybands(struct wl_priv *wl); extern s32 wl_cfg80211_scan_abort(struct wl_priv *wl, struct net_device *ndev); extern s32 wl_cfg80211_if_is_group_owner(void); +extern s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add); #endif /* _wl_cfg80211_h_ */ diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c index f25cae4..fdc2ed8 100644 --- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c +++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c @@ -41,20 +41,25 @@ #include <bcmutils.h> #include <bcmendian.h> #include <proto/ethernet.h> - +#include <dngl_stats.h> +#include <dhd.h> +#include <dhdioctl.h> +#include <wlioctl.h> +#include <dhd_cfg80211.h> #include <wl_cfg80211.h> #include <wl_cfgp2p.h> #include <wldev_common.h> #include <wl_android.h> static s8 scanparambuf[WLC_IOCTL_SMLEN]; - +static s8 g_mgmt_ie_buf[2048]; +extern struct wl_priv *wlcfg_drv_priv; static bool wl_cfgp2p_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len, const u8 *oui, u32 oui_len, u8 type); -static s32 -wl_cfgp2p_vndr_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag, - s8 *oui, s32 ie_id, s8 *data, s32 data_len, s32 delete); +static u32 +wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 bssidx, s32 pktflag, + s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd); static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev); static int wl_cfgp2p_do_ioctl(struct net_device *net, struct ifreq *ifr, int cmd); @@ -924,13 +929,17 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss s32 ret = BCME_OK; u32 pos; u8 *ie_buf; + u8 *curr_ie_buf = NULL; u8 *mgmt_ie_buf = NULL; u32 mgmt_ie_buf_len = 0; u32 *mgmt_ie_len = 0; + u32 del_add_ie_buf_len = 0; + u32 total_ie_buf_len = 0; u8 ie_id, ie_len; - u8 delete = 0; #define IE_TYPE(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie) #define IE_TYPE_LEN(type, bsstype) (wl_to_p2p_bss_saved_ie(wl, bsstype).p2p_ ## type ## _ie_len) + memset(g_mgmt_ie_buf, 0, sizeof(g_mgmt_ie_buf)); + curr_ie_buf = g_mgmt_ie_buf; if (p2p_is_on(wl) && bssidx != -1) { if (bssidx == P2PAPI_BSSCFG_PRIMARY) bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); @@ -1020,7 +1029,6 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss goto exit; } pos = 0; - delete = 1; ie_buf = (u8 *) mgmt_ie_buf; while (pos < *mgmt_ie_len) { ie_id = ie_buf[pos++]; @@ -1030,12 +1038,14 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss wl_cfgp2p_is_p2p_ie(&ie_buf[pos-2], NULL, 0) || wl_cfgp2p_is_wfd_ie(&ie_buf[pos-2], NULL, 0) || wl_cfgp2p_is_customer_ie(&ie_buf[pos-2], NULL, 0))) { - CFGP2P_INFO(("DELELED ID : %d, Len : %d , OUI :" + CFGP2P_INFO(("DELETED ID : %d, Len : %d , OUI :" "%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos], ie_buf[pos+1], ie_buf[pos+2])); - ret = wl_cfgp2p_vndr_ie(wl, ndev, bssidx, pktflag, + del_add_ie_buf_len = wl_cfgp2p_vndr_ie(wl, curr_ie_buf, bssidx, pktflag, ie_buf+pos, VNDR_SPEC_ELEMENT_ID, ie_buf+pos+3, - ie_len-3, delete); + ie_len-3, "del"); + curr_ie_buf += del_add_ie_buf_len; + total_ie_buf_len += del_add_ie_buf_len; } pos += ie_len; } @@ -1049,7 +1059,6 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss *mgmt_ie_len = vndr_ie_len; pos = 0; ie_buf = (u8 *) vndr_ie; - delete = 0; while (pos < vndr_ie_len) { ie_id = ie_buf[pos++]; ie_len = ie_buf[pos++]; @@ -1061,14 +1070,21 @@ wl_cfgp2p_set_management_ie(struct wl_priv *wl, struct net_device *ndev, s32 bss CFGP2P_INFO(("ADDED ID : %d, Len : %d , OUI :" "%02x:%02x:%02x\n", ie_id, ie_len, ie_buf[pos], ie_buf[pos+1], ie_buf[pos+2])); - ret = wl_cfgp2p_vndr_ie(wl, ndev, bssidx, pktflag, + del_add_ie_buf_len = wl_cfgp2p_vndr_ie(wl, curr_ie_buf, bssidx, pktflag, ie_buf+pos, VNDR_SPEC_ELEMENT_ID, ie_buf+pos+3, - ie_len-3, delete); + ie_len-3, "add"); + curr_ie_buf += del_add_ie_buf_len; + total_ie_buf_len += del_add_ie_buf_len; } pos += ie_len; } } - + if (total_ie_buf_len) { + ret = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", g_mgmt_ie_buf, total_ie_buf_len, + wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); + if (ret) + CFGP2P_ERR(("vndr ie set error : %d\n", ret)); + } } #undef IE_TYPE #undef IE_TYPE_LEN @@ -1203,15 +1219,13 @@ wl_cfgp2p_find_wfdie(u8 *parse, u32 len) } return NULL; } -static s32 -wl_cfgp2p_vndr_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 pktflag, - s8 *oui, s32 ie_id, s8 *data, s32 data_len, s32 delete) +static u32 +wl_cfgp2p_vndr_ie(struct wl_priv *wl, u8 *iebuf, s32 bssidx, s32 pktflag, + s8 *oui, s32 ie_id, s8 *data, s32 datalen, const s8* add_del_cmd) { - s32 err = BCME_OK; - s32 buf_len; + vndr_ie_setbuf_t hdr; /* aligned temporary vndr_ie buffer header */ s32 iecount; - - vndr_ie_setbuf_t *ie_setbuf; + u32 data_offset; /* Validate the pktflag parameter */ if ((pktflag & ~(VNDR_IE_BEACON_FLAG | VNDR_IE_PRBRSP_FLAG | @@ -1221,36 +1235,34 @@ wl_cfgp2p_vndr_ie(struct wl_priv *wl, struct net_device *ndev, s32 bssidx, s32 p return -1; } - buf_len = sizeof(vndr_ie_setbuf_t) + data_len - 1; - ie_setbuf = (vndr_ie_setbuf_t *) kzalloc(buf_len, GFP_KERNEL); + /* Copy the vndr_ie SET command ("add"/"del") to the buffer */ + strncpy(hdr.cmd, add_del_cmd, VNDR_IE_CMD_LEN - 1); + hdr.cmd[VNDR_IE_CMD_LEN - 1] = '\0'; - CFGP2P_INFO((" ie_id : %02x, data length : %d\n", ie_id, data_len)); - if (!ie_setbuf) { - - CFGP2P_ERR(("Error allocating buffer for IE\n")); - return -ENOMEM; - } - if (delete) - strcpy(ie_setbuf->cmd, "del"); - else - strcpy(ie_setbuf->cmd, "add"); /* Buffer contains only 1 IE */ iecount = htod32(1); - memcpy((void *)&ie_setbuf->vndr_ie_buffer.iecount, &iecount, sizeof(int)); + memcpy((void *)&hdr.vndr_ie_buffer.iecount, &iecount, sizeof(s32)); pktflag = htod32(pktflag); - memcpy((void *)&ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].pktflag, - &pktflag, sizeof(uint32)); - ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.id = ie_id; - ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len - = (uchar)(data_len + VNDR_IE_MIN_LEN); - memcpy(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui, oui, 3); - memcpy(ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data, data, data_len); - err = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", ie_setbuf, buf_len, - wl->ioctl_buf, WLC_IOCTL_MAXLEN, bssidx, &wl->ioctl_buf_sync); + memcpy((void *)&hdr.vndr_ie_buffer.vndr_ie_list[0].pktflag, &pktflag, + sizeof(u32)); + hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.id = ie_id; + hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len = + (uint8) VNDR_IE_MIN_LEN + datalen; + + /* Add the IE OUI to the buffer */ + hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[0] = oui[0]; + hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[1] = oui[1]; + hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[2] = oui[2]; + + /* Copy the aligned temporary vndr_ie buffer header to the IE buffer */ + memcpy(iebuf, &hdr, sizeof(hdr) - 1); + + data_offset = + (u8*)&hdr.vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.data[0] - + (u8*)&hdr; + memcpy(iebuf + data_offset, data, datalen); + return data_offset + datalen; - CFGP2P_INFO(("vndr_ie iovar returns %d\n", err)); - kfree(ie_setbuf); - return err; } /* @@ -1284,6 +1296,33 @@ wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev) exit: return index; } +s32 wl_cfgp2p_p2p_listen_suspend(void) +{ + struct wl_priv *wl = wlcfg_drv_priv; + bool enable = true; + s32 ret = BCME_OK; + s32 bssidx = -1; + struct net_device *netdev = wl_to_prmry_ndev(wl); + CFGP2P_ERR(("enter\n")); + if (wl == NULL || wl->p2p == NULL || netdev == NULL) + goto exit; + if (wl_get_p2p_status(wl, DISCOVERY_ON) == 0) + goto exit; + if (!timer_pending(&wl->p2p->listen_timer)) + goto exit; + bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); + if (bssidx) { + if (wl_to_p2p_bss_saved_ie(wl, bssidx).p2p_probe_res_ie_len) + enable = false; + + if ((ret = wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, enable)) != BCME_OK) { + CFGP2P_ERR((" failed to %s WLC_E_P2P_PROPREQ_MSG\n", enable? "set":"unset" )); + } + + } +exit: + return ret; +} /* * Callback function for WLC_E_P2P_DISC_LISTEN_COMPLETE */ @@ -1292,7 +1331,7 @@ wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data) { s32 ret = BCME_OK; - + struct net_device *netdev = wl_to_prmry_ndev(wl); CFGP2P_DBG((" Enter\n")); if (wl_get_p2p_status(wl, LISTEN_EXPIRED) == 0) { wl_set_p2p_status(wl, LISTEN_EXPIRED); @@ -1333,6 +1372,9 @@ wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev, cfg80211_remain_on_channel_expired(ndev, wl->last_roc_id, &wl->remain_on_chan, wl->remain_on_chan_type, GFP_KERNEL); } + if (wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, false) != BCME_OK) { + CFGP2P_ERR((" failed to unset WLC_E_P2P_PROPREQ_MSG\n")); + } } else wl_clr_p2p_status(wl, LISTEN_EXPIRED); @@ -1374,6 +1416,10 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms) s32 ret = BCME_OK; struct timer_list *_timer; s32 extra_delay; + struct net_device *netdev = wl_to_prmry_ndev(wl); + dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub); + bool enable = true; + s32 bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE); CFGP2P_DBG((" Enter Listen Channel : %d, Duration : %d\n", channel, duration_ms)); if (unlikely(wl_get_p2p_status(wl, DISCOVERY_ON) == 0)) { @@ -1392,9 +1438,15 @@ wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms) else wl_clr_p2p_status(wl, LISTEN_EXPIRED); #endif /* not WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ - - ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms, - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE)); + if (wl_to_p2p_bss_saved_ie(wl, bssidx).p2p_probe_res_ie_len && dhd && dhd->in_suspend) { + /* Clear WLC_E_P2P_PROBREQ_MSG in case of early suspend and p2p ie != 0 */ + enable = false; + } + + if (wl_add_remove_eventmsg(netdev, WLC_E_P2P_PROBREQ_MSG, enable) != BCME_OK) { + CFGP2P_ERR((" failed to set WLC_E_P2P_PROPREQ_MSG\n")); + } + ret = wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms, bssidx); _timer = &wl->p2p->listen_timer; /* We will wait to receive WLC_E_P2P_DISC_LISTEN_COMPLETE from dongle , diff --git a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.h b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.h index ebc1030..348aeca 100644 --- a/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.h +++ b/drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.h @@ -123,21 +123,21 @@ enum wl_cfgp2p_status { #define CFGP2P_ERR(args) \ do { \ if (wl_dbg_level & WL_DBG_ERR) { \ - printk(KERN_ERR "CFGP2P-INFO2) %s : ", __func__); \ + printk(KERN_INFO "CFGP2P-INFO2) %s : ", __func__); \ printk args; \ } \ } while (0) #define CFGP2P_INFO(args) \ do { \ if (wl_dbg_level & WL_DBG_INFO) { \ - printk(KERN_ERR "CFGP2P-INFO) %s : ", __func__); \ + printk(KERN_INFO "CFGP2P-INFO) %s : ", __func__); \ printk args; \ } \ } while (0) #define CFGP2P_DBG(args) \ do { \ if (wl_dbg_level & WL_DBG_DBG) { \ - printk(KERN_ERR "CFGP2P-DEBUG) %s :", __func__); \ + printk(KERN_DEBUG "CFGP2P-DEBUG) %s :", __func__); \ printk args; \ } \ } while (0) @@ -221,6 +221,8 @@ wl_cfgp2p_find_idx(struct wl_priv *wl, struct net_device *ndev); extern s32 +wl_cfgp2p_p2p_listen_suspend(void); +extern s32 wl_cfgp2p_listen_complete(struct wl_priv *wl, struct net_device *ndev, const wl_event_msg_t *e, void *data); extern s32 |