aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/bcmdhd
diff options
context:
space:
mode:
authorDaniel Hillenbrand <daniel.hillenbrand@codeworkx.de>2012-07-21 23:04:45 +0200
committerDaniel Hillenbrand <daniel.hillenbrand@codeworkx.de>2012-07-21 23:04:45 +0200
commit0a1182796f6475b8cb2ff1781dad873a744b3197 (patch)
treee15b5256dac226c49a25b5e24594cd638e2fec2c /drivers/net/wireless/bcmdhd
parent633018c13fe06461d9c60692fbb114734aa37802 (diff)
downloadkernel_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')
-rw-r--r--drivers/net/wireless/bcmdhd/Makefile4
-rw-r--r--drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_linux.c18
-rw-r--r--drivers/net/wireless/bcmdhd/src/bcmsdio/sys/bcmsdh_sdmmc_linux.c9
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd.h11
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_cfg80211.c18
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_common.c53
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_custom_sec.c148
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_linux.c99
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sdio.c72
-rw-r--r--drivers/net/wireless/bcmdhd/src/dhd/sys/dhd_sec_feature.h11
-rw-r--r--drivers/net/wireless/bcmdhd/src/include/epivers.h8
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_android.c49
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.c215
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfg80211.h16
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.c152
-rw-r--r--drivers/net/wireless/bcmdhd/src/wl/sys/wl_cfgp2p.h8
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