summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRongjun Chen <rongjun.chen@amlogic.com>2019-01-04 10:00:48 +0800
committerRongjun Chen <rongjun.chen@amlogic.com>2019-01-07 19:02:03 +0800
commit47fa5ad572febc2cc89c86e6b2264d57842fa906 (patch)
tree66f03994b2e4e90ac1c7186f500ee90ad17fe789
parentce3b8cf9f02c0b37f6acd7d8b8422c096c2dd3a9 (diff)
downloaddhd-driver-47fa5ad572febc2cc89c86e6b2264d57842fa906.tar.gz
WIFI: fix ap62x8 cts test fail issue [1/5]
PD#SWPL-3773 Problem: CtsNetTestCases Module 3 Fails Solution: update driver to fix cts test fail issue Verify: r311 Change-Id: Ibea9da241061f1ce2771ba2c39f78952bd201976 Signed-off-by: Rongjun Chen <rongjun.chen@amlogic.com>
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_config.c2
-rw-r--r--bcmdhd.1.579.77.41.1.cn/dhd_sdio.c7
-rw-r--r--bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c7
-rw-r--r--bcmdhd.1.579.77.41.1.cn/wl_cfgvendor.c1
-rw-r--r--bcmdhd.100.10.315.x/Makefile2
-rw-r--r--bcmdhd.100.10.315.x/bcmsdh_sdmmc.c4
-rw-r--r--bcmdhd.100.10.315.x/dhd_config.c209
-rw-r--r--bcmdhd.100.10.315.x/dhd_config.h17
-rw-r--r--bcmdhd.100.10.315.x/dhd_linux.c63
-rw-r--r--bcmdhd.100.10.315.x/dhd_msgbuf.c1
-rw-r--r--bcmdhd.100.10.315.x/dhd_pcie_linux.c6
-rw-r--r--bcmdhd.100.10.315.x/dhd_sdio.c12
-rw-r--r--bcmdhd.100.10.315.x/dhd_static_buf.c8
-rw-r--r--bcmdhd.100.10.315.x/include/epivers.h2
-rw-r--r--bcmdhd.100.10.315.x/linux_osl.c48
-rw-r--r--bcmdhd.100.10.315.x/linux_osl_priv.h1
-rw-r--r--bcmdhd.100.10.315.x/wl_android.c2
-rw-r--r--bcmdhd.100.10.315.x/wl_android.h22
-rw-r--r--bcmdhd.100.10.315.x/wl_android_ext.c356
-rw-r--r--bcmdhd.100.10.315.x/wl_cfg80211.c82
-rw-r--r--bcmdhd.100.10.315.x/wl_escan.c51
-rw-r--r--bcmdhd.100.10.315.x/wl_escan.h5
-rw-r--r--bcmdhd.100.10.315.x/wl_iw.c99
-rw-r--r--bcmdhd.100.10.315.x/wl_iw.h1
-rw-r--r--bcmdhd.100.10.315.x/wldev_common.c4
25 files changed, 786 insertions, 226 deletions
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_config.c b/bcmdhd.1.579.77.41.1.cn/dhd_config.c
index 27d0e9d..8aa7a9a 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_config.c
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_config.c
@@ -2740,7 +2740,7 @@ dhd_conf_preinit(dhd_pub_t *dhd)
conf->txglom_ext = FALSE;
conf->tx_max_offset = 0;
conf->txglomsize = SDPCM_DEFGLOM_SIZE;
- conf->txctl_tmo_fix = -1;
+ conf->txctl_tmo_fix = 300;
conf->txglom_mode = SDPCM_TXGLOM_CPY;
conf->deferred_tx_len = 0;
conf->dhd_txminmax = 1;
diff --git a/bcmdhd.1.579.77.41.1.cn/dhd_sdio.c b/bcmdhd.1.579.77.41.1.cn/dhd_sdio.c
index fb6150f..53e9eaf 100644
--- a/bcmdhd.1.579.77.41.1.cn/dhd_sdio.c
+++ b/bcmdhd.1.579.77.41.1.cn/dhd_sdio.c
@@ -6610,7 +6610,7 @@ dhdsdio_dpc(dhd_bus_t *bus)
goto clkwait;
/* Pending interrupt indicates new device status */
- if (bus->ipend || (bus->ctrl_frame_stat && bus->dhd->conf->txctl_tmo_fix)) {
+ if (bus->ipend) {
bus->ipend = FALSE;
#if defined(BT_OVER_SDIO)
bcmsdh_btsdio_process_f3_intr();
@@ -7552,6 +7552,11 @@ dhd_bus_console_in(dhd_pub_t *dhdp, uchar *msg, uint msglen)
if ((rv = dhdsdio_membytes(bus, TRUE, addr, (uint8 *)&val, sizeof(val))) < 0)
goto done;
+ if (!DATAOK(bus)) {
+ rv = BCME_NOTREADY;
+ goto done;
+ }
+
/* Bump dongle by sending an empty packet on the event channel.
* sdpcm_sendup (RX) checks for virtual console input.
*/
diff --git a/bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c b/bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c
index 777ac49..34cedee 100644
--- a/bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c
+++ b/bcmdhd.1.579.77.41.1.cn/wl_cfg80211.c
@@ -2948,10 +2948,13 @@ wl_run_escan(struct bcm_cfg80211 *cfg, struct net_device *ndev,
}
exit:
if (unlikely(err)) {
+ int suppressed = 0;
+ wldev_ioctl(dev, WLC_GET_SCANSUPPRESS, &suppressed, sizeof(int), false);
/* Don't print Error incase of Scan suppress */
- if ((err == BCME_EPERM) && cfg->scan_suppressed)
+ if ((err == BCME_EPERM) && (cfg->scan_suppressed || suppressed)) {
+ cnt = 0;
WL_DBG(("Escan failed: Scan Suppressed \n"));
- else {
+ } else {
cnt++;
WL_ERR(("error (%d), cnt=%d\n", err, cnt));
// terence 20140111: send disassoc to firmware
diff --git a/bcmdhd.1.579.77.41.1.cn/wl_cfgvendor.c b/bcmdhd.1.579.77.41.1.cn/wl_cfgvendor.c
index c5b4b2b..d0fd9f9 100644
--- a/bcmdhd.1.579.77.41.1.cn/wl_cfgvendor.c
+++ b/bcmdhd.1.579.77.41.1.cn/wl_cfgvendor.c
@@ -2513,6 +2513,7 @@ wl_cfgvendor_dbg_trigger_mem_dump(struct wiphy *wiphy,
if (ret) {
WL_ERR(("Vendor Command reply failed ret:%d \n", ret));
}
+ printk("wl_cfgvendor_dbg_trigger_mem_dump ===================ret : %d\n", ret);
exit:
return ret;
diff --git a/bcmdhd.100.10.315.x/Makefile b/bcmdhd.100.10.315.x/Makefile
index 3c964b1..9884970 100644
--- a/bcmdhd.100.10.315.x/Makefile
+++ b/bcmdhd.100.10.315.x/Makefile
@@ -101,7 +101,7 @@ ifeq ($(CONFIG_VTS_SUPPORT),y)
ifneq ($(CONFIG_CFG80211),)
DHDCFLAGS += -DGSCAN_SUPPORT -DRTT_SUPPORT -DCUSTOM_FORCE_NODFS_FLAG \
-DLINKSTAT_SUPPORT -DDEBUGABILITY -DDBG_PKT_MON -DPKT_FILTER_SUPPORT \
- -DAPF -DNDO_CONFIG_SUPPORT -DRSSI_MONITOR_SUPPORT -DDHD_WAKE_STATUS \
+ -DAPF -DNDO_CONFIG_SUPPORT -DRSSI_MONITOR_SUPPORT -DDHD_WAKE_STATUS \
-DCUSTOM_COUNTRY_CODE -DDHD_FW_COREDUMP -DEXPLICIT_DISCIF_CLEANUP
DHDOFILES += dhd_rtt.o bcm_app_utils.o
diff --git a/bcmdhd.100.10.315.x/bcmsdh_sdmmc.c b/bcmdhd.100.10.315.x/bcmsdh_sdmmc.c
index 04111dc..338ec0e 100644
--- a/bcmdhd.100.10.315.x/bcmsdh_sdmmc.c
+++ b/bcmdhd.100.10.315.x/bcmsdh_sdmmc.c
@@ -1244,10 +1244,10 @@ sdioh_request_packet_chain(sdioh_info_t *sd, uint fix_inc, uint write, uint func
goto txglomfail;
}
}
-
+
bcopy(buf, (localbuf + local_plen), pkt_len);
local_plen += pkt_len;
- if (PKTNEXT(sd->osh, pnext))
+ if (PKTNEXT(sd->osh, pnext))
continue;
buf = localbuf;
diff --git a/bcmdhd.100.10.315.x/dhd_config.c b/bcmdhd.100.10.315.x/dhd_config.c
index eedac09..fed007f 100644
--- a/bcmdhd.100.10.315.x/dhd_config.c
+++ b/bcmdhd.100.10.315.x/dhd_config.c
@@ -46,6 +46,15 @@ uint config_msg_level = CONFIG_ERROR_LEVEL;
#define htodchanspec(i) i
#define dtohchanspec(i) i
+#define MAX_EVENT_BUF_NUM 16
+typedef struct eventmsg_buf {
+ u16 num;
+ struct {
+ u16 type;
+ bool set;
+ } event [MAX_EVENT_BUF_NUM];
+} eventmsg_buf_t;
+
typedef struct cihp_name_map_t {
uint chip;
uint chiprev;
@@ -792,7 +801,8 @@ dhd_conf_set_country(dhd_pub_t *dhd, wl_country_t *cspec)
memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));
printf("%s: set country %s, revision %d\n", __FUNCTION__, cspec->ccode, cspec->rev);
- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)cspec, sizeof(wl_country_t), FALSE);
+ bcmerror = dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)cspec,
+ sizeof(wl_country_t), FALSE);
dhd_conf_get_country(dhd, cspec);
printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);
@@ -888,6 +898,85 @@ dhd_conf_set_roam(dhd_pub_t *dhd)
}
void
+dhd_conf_add_to_eventbuffer(struct eventmsg_buf *ev, u16 event, bool set)
+{
+ if (!ev || (event > WLC_E_LAST))
+ return;
+
+ if (ev->num < MAX_EVENT_BUF_NUM) {
+ ev->event[ev->num].type = event;
+ ev->event[ev->num].set = set;
+ ev->num++;
+ } else {
+ CONFIG_ERROR(("evenbuffer doesn't support > %u events. Update"
+ " the define MAX_EVENT_BUF_NUM \n", MAX_EVENT_BUF_NUM));
+ ASSERT(0);
+ }
+}
+
+s32
+dhd_conf_apply_eventbuffer(dhd_pub_t *dhd, eventmsg_buf_t *ev)
+{
+ char eventmask[WL_EVENTING_MASK_LEN];
+ int i, ret = 0;
+
+ if (!ev || (!ev->num))
+ return -EINVAL;
+
+ /* Read event_msgs mask */
+ ret = dhd_conf_get_iovar(dhd, WLC_GET_VAR, "event_msgs", eventmask, sizeof(eventmask), 0);
+ if (unlikely(ret)) {
+ CONFIG_ERROR(("Get event_msgs error (%d)\n", ret));
+ goto exit;
+ }
+
+ /* apply the set bits */
+ for (i = 0; i < ev->num; i++) {
+ if (ev->event[i].set)
+ setbit(eventmask, ev->event[i].type);
+ else
+ clrbit(eventmask, ev->event[i].type);
+ }
+
+ /* Write updated Event mask */
+ ret = dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask,
+ sizeof(eventmask), FALSE);
+ if (unlikely(ret)) {
+ CONFIG_ERROR(("Set event_msgs error (%d)\n", ret));
+ }
+
+exit:
+ return ret;
+}
+
+int
+dhd_conf_enable_roam_offload(dhd_pub_t *dhd, int enable)
+{
+ int err;
+ eventmsg_buf_t ev_buf;
+
+ if (dhd->conf->roam_off_suspend)
+ return 0;
+
+ err = dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_offload", enable, 0, FALSE);
+ if (err)
+ return err;
+
+ bzero(&ev_buf, sizeof(eventmsg_buf_t));
+ dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_PSK_SUP, !enable);
+ dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_ASSOC_REQ_IE, !enable);
+ dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_ASSOC_RESP_IE, !enable);
+ dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_REASSOC, !enable);
+ dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_JOIN, !enable);
+ dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_ROAM, !enable);
+ err = dhd_conf_apply_eventbuffer(dhd, &ev_buf);
+
+ CONFIG_TRACE(("%s: roam_offload %d\n", __FUNCTION__, enable));
+
+ return err;
+}
+
+void
dhd_conf_set_bw_cap(dhd_pub_t *dhd)
{
struct {
@@ -1160,59 +1249,87 @@ dhd_conf_get_pm(dhd_pub_t *dhd)
return -1;
}
-#define AP_IN_SUSPEND 1
-#define AP_DOWN_IN_SUSPEND 2
-int
-dhd_conf_get_ap_mode_in_suspend(dhd_pub_t *dhd)
+uint
+dhd_conf_get_insuspend(dhd_pub_t *dhd)
{
- int mode = 0;
+ uint mode = 0;
- /* returned ap_in_suspend value:
- * 0: nothing
- * 1: ap enabled in suspend
- * 2: ap enabled, but down in suspend
- */
- if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
- mode = dhd->conf->ap_in_suspend;
+ if (dhd->op_mode & DHD_FLAG_STA_MODE) {
+ mode = dhd->conf->insuspend &
+ (NO_EVENT_IN_SUSPEND | NO_TXDATA_IN_SUSPEND | ROAM_OFFLOAD_IN_SUSPEND);
+ } else if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+ mode = dhd->conf->insuspend &
+ (NO_EVENT_IN_SUSPEND | NO_TXDATA_IN_SUSPEND | AP_DOWN_IN_SUSPEND);
}
return mode;
}
int
-dhd_conf_set_ap_in_suspend(dhd_pub_t *dhd, int suspend)
+dhd_conf_set_suspend_resume(dhd_pub_t *dhd, int suspend)
{
- int mode = 0;
- uint wl_down = 1;
+ uint mode = 0, wl_down = 1;
+ struct dhd_conf *conf = dhd->conf;
- mode = dhd_conf_get_ap_mode_in_suspend(dhd);
+ mode = dhd_conf_get_insuspend(dhd);
if (mode)
- printf("%s: suspend %d, mode %d\n", __FUNCTION__, suspend, mode);
+ printf("%s: op_mode %d, suspend %d, mode 0x%x\n", __FUNCTION__,
+ dhd->op_mode, suspend, mode);
+
if (suspend) {
- if (mode == AP_IN_SUSPEND) {
+ if (dhd->op_mode & DHD_FLAG_STA_MODE) {
+ if (mode & ROAM_OFFLOAD_IN_SUSPEND)
+ dhd_conf_enable_roam_offload(dhd, 1);
+ } else if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+ if (mode & AP_DOWN_IN_SUSPEND) {
+ dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_down,
+ sizeof(wl_down), TRUE, 0);
+ }
+ }
#ifdef SUSPEND_EVENT
- if (dhd->conf->suspend_eventmask_enable) {
- char *eventmask = dhd->conf->suspend_eventmask;
- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask, sizeof(eventmask), TRUE);
+ if (mode & NO_EVENT_IN_SUSPEND) {
+ char suspend_eventmask[WL_EVENTING_MASK_LEN];
+ if (!conf->suspended) {
+ dhd_conf_get_iovar(dhd, WLC_GET_VAR, "event_msgs",
+ conf->resume_eventmask, sizeof(conf->resume_eventmask), 0);
}
+ memset(suspend_eventmask, 0, sizeof(suspend_eventmask));
+ dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs",
+ suspend_eventmask, sizeof(suspend_eventmask), FALSE);
+ }
#endif
- } else if (mode == AP_DOWN_IN_SUSPEND)
- dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_down, sizeof(wl_down), TRUE, 0);
+ conf->suspended = TRUE;
} else {
- if (mode == AP_IN_SUSPEND) {
#ifdef SUSPEND_EVENT
- if (dhd->conf->suspend_eventmask_enable) {
- char *eventmask = dhd->conf->resume_eventmask;
- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask, sizeof(eventmask), TRUE);
+ if (mode & NO_EVENT_IN_SUSPEND) {
+ dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs",
+ conf->resume_eventmask, sizeof(conf->resume_eventmask), FALSE);
+ if (dhd->op_mode & DHD_FLAG_STA_MODE) {
+ struct ether_addr bssid;
+ int ret = 0;
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID, &bssid,
+ sizeof(struct ether_addr), FALSE, 0);
+ if (ret != BCME_NOTASSOCIATED && !memcmp(&ether_null, &bssid, ETHER_ADDR_LEN)) {
+ CONFIG_TRACE(("%s: send disassoc\n", __FUNCTION__));
+ dhd_conf_set_intiovar(dhd, WLC_DISASSOC, "WLC_DISASSOC", 0, 0, FALSE);
+ }
}
+ }
#endif
- } else if (mode == AP_DOWN_IN_SUSPEND) {
- wl_down = 0;
- dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&wl_down, sizeof(wl_down), TRUE, 0);
+ if (dhd->op_mode & DHD_FLAG_STA_MODE) {
+ if (mode & ROAM_OFFLOAD_IN_SUSPEND)
+ dhd_conf_enable_roam_offload(dhd, 0);
+ } else if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+ if (mode & AP_DOWN_IN_SUSPEND) {
+ wl_down = 0;
+ dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&wl_down,
+ sizeof(wl_down), TRUE, 0);
+ }
}
+ conf->suspended = FALSE;
}
- return mode;
+ return 0;
}
#ifdef PROP_TXSTATUS
@@ -2099,24 +2216,15 @@ dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param)
}
else if (!strncmp("xmit_in_suspend=", full_param, len_param)) {
if (!strncmp(data, "1", 1))
- conf->xmit_in_suspend = TRUE;
+ conf->insuspend &= ~NO_TXDATA_IN_SUSPEND;
else
- conf->xmit_in_suspend = FALSE;
- printf("%s: xmit_in_suspend = %d\n", __FUNCTION__, conf->xmit_in_suspend);
- }
- else if (!strncmp("ap_in_suspend=", full_param, len_param)) {
- conf->ap_in_suspend = (int)simple_strtol(data, NULL, 10);
- printf("%s: ap_in_suspend = %d\n", __FUNCTION__, conf->ap_in_suspend);
+ conf->insuspend |= NO_TXDATA_IN_SUSPEND;
+ printf("%s: insuspend = 0x%x\n", __FUNCTION__, conf->insuspend);
}
-#ifdef SUSPEND_EVENT
- else if (!strncmp("suspend_eventmask_enable=", full_param, len_param)) {
- if (!strncmp(data, "1", 1))
- conf->suspend_eventmask_enable = TRUE;
- else
- conf->suspend_eventmask_enable = FALSE;
- printf("%s: suspend_eventmask_enable = %d\n", __FUNCTION__, conf->suspend_eventmask_enable);
+ else if (!strncmp("insuspend=", full_param, len_param)) {
+ conf->insuspend = (int)simple_strtol(data, NULL, 0);
+ printf("%s: insuspend = 0x%x\n", __FUNCTION__, conf->insuspend);
}
-#endif
else
return false;
@@ -2582,7 +2690,7 @@ dhd_conf_postinit_ioctls(dhd_pub_t *dhd)
dhd_conf_set_intiovar(dhd, WLC_SET_BAND, "WLC_SET_BAND", conf->band, 0, FALSE);
dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "bcn_timeout", conf->bcn_timeout, 0, FALSE);
dhd_conf_set_intiovar(dhd, WLC_SET_PM, "PM", conf->pm, 0, FALSE);
- dhd_conf_set_intiovar(dhd, WLC_SET_SRL, "WLC_SET_SRL", conf->srl, 0, TRUE);
+ dhd_conf_set_intiovar(dhd, WLC_SET_SRL, "WLC_SET_SRL", conf->srl, 0, FALSE);
dhd_conf_set_intiovar(dhd, WLC_SET_LRL, "WLC_SET_LRL", conf->lrl, 0, FALSE);
dhd_conf_set_bw_cap(dhd);
dhd_conf_set_roam(dhd);
@@ -2728,11 +2836,8 @@ dhd_conf_preinit(dhd_pub_t *dhd)
conf->pm = -1;
conf->pm_in_suspend = -1;
conf->suspend_bcn_li_dtim = -1;
- conf->xmit_in_suspend = TRUE;
- conf->ap_in_suspend = 0;
+ conf->insuspend = 0;
#ifdef SUSPEND_EVENT
- conf->suspend_eventmask_enable = FALSE;
- memset(&conf->suspend_eventmask, 0, sizeof(conf->suspend_eventmask));
memset(&conf->resume_eventmask, 0, sizeof(conf->resume_eventmask));
#endif
#ifdef IDHCP
diff --git a/bcmdhd.100.10.315.x/dhd_config.h b/bcmdhd.100.10.315.x/dhd_config.h
index d7ad3c8..1830c5f 100644
--- a/bcmdhd.100.10.315.x/dhd_config.h
+++ b/bcmdhd.100.10.315.x/dhd_config.h
@@ -109,6 +109,13 @@ enum in4way_flags {
WAIT_DISCONNECTED = (1 << (3)),
};
+enum in_suspend_flags {
+ NO_EVENT_IN_SUSPEND = (1 << (0)),
+ NO_TXDATA_IN_SUSPEND = (1 << (1)),
+ AP_DOWN_IN_SUSPEND = (1 << (2)),
+ ROAM_OFFLOAD_IN_SUSPEND = (1 << (3)),
+};
+
enum eapol_status {
EAPOL_STATUS_NONE = 0,
EAPOL_STATUS_WPS_REQID,
@@ -204,11 +211,9 @@ typedef struct dhd_conf {
uint8 tcpack_sup_mode;
#endif
int pktprio8021x;
- int xmit_in_suspend;
- int ap_in_suspend;
+ uint insuspend;
+ bool suspended;
#ifdef SUSPEND_EVENT
- bool suspend_eventmask_enable;
- char suspend_eventmask[WL_EVENTING_MASK_LEN];
char resume_eventmask[WL_EVENTING_MASK_LEN];
#endif
#ifdef IDHCP
@@ -273,8 +278,8 @@ int dhd_conf_get_pm(dhd_pub_t *dhd);
#ifdef PROP_TXSTATUS
int dhd_conf_get_disable_proptx(dhd_pub_t *dhd);
#endif
-int dhd_conf_get_ap_mode_in_suspend(dhd_pub_t *dhd);
-int dhd_conf_set_ap_in_suspend(dhd_pub_t *dhd, int suspend);
+uint dhd_conf_get_insuspend(dhd_pub_t *dhd);
+int dhd_conf_set_suspend_resume(dhd_pub_t *dhd, int suspend);
void dhd_conf_postinit_ioctls(dhd_pub_t *dhd);
int dhd_conf_preinit(dhd_pub_t *dhd);
int dhd_conf_reset(dhd_pub_t *dhd);
diff --git a/bcmdhd.100.10.315.x/dhd_linux.c b/bcmdhd.100.10.315.x/dhd_linux.c
index e8914db..18a3684 100644
--- a/bcmdhd.100.10.315.x/dhd_linux.c
+++ b/bcmdhd.100.10.315.x/dhd_linux.c
@@ -3587,7 +3587,7 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
if (dhd->conf->pm_in_suspend >= 0)
power_mode = dhd->conf->pm_in_suspend;
dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode,
- sizeof(power_mode), TRUE, 0);
+ sizeof(power_mode), TRUE, 0);
#ifdef PKT_FILTER_SUPPORT
/* Enable packet filter,
@@ -3768,9 +3768,9 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
}
#endif /* CUSTOM_EVENT_PM_WAKE */
#endif /* DHD_USE_EARLYSUSPEND */
- dhd_conf_set_ap_in_suspend(dhd, value);
+ dhd_conf_set_suspend_resume(dhd, value);
} else {
- dhd_conf_set_ap_in_suspend(dhd, value);
+ dhd_conf_set_suspend_resume(dhd, value);
#ifdef PKT_FILTER_SUPPORT
dhd->early_suspended = 0;
#endif // endif
@@ -3784,11 +3784,8 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
DHD_ERROR(("failed to set intr_width (%d)\n", ret));
}
#endif /* DYNAMIC_SWOOB_DURATION */
-#ifndef SUPPORT_PM2_ONLY
- power_mode = PM_FAST;
dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode,
- sizeof(power_mode), TRUE, 0);
-#endif /* SUPPORT_PM2_ONLY */
+ sizeof(power_mode), TRUE, 0);
#if defined(WL_CFG80211) && defined(WL_BCNRECV)
ret = wl_android_bcnrecv_resume(dhd_linux_get_primary_netdev(dhd));
if (ret != BCME_OK) {
@@ -3929,7 +3926,7 @@ static int dhd_set_suspend(int value, dhd_pub_t *dhd)
#endif /* DHD_LB_IRQSET */
/* terence 2017029: Reject in early suspend */
- if (!dhd->conf->xmit_in_suspend) {
+ if (dhd->conf->insuspend & NO_TXDATA_IN_SUSPEND) {
dhd_txflowcontrol(dhd, ALL_INTERFACES, OFF);
}
}
@@ -3950,7 +3947,7 @@ static int dhd_suspend_resume_helper(struct dhd_info *dhd, int val, int force)
/* Set flag when early suspend was called */
dhdp->in_suspend = val;
if ((force || !dhdp->suspend_disable_flag) &&
- (dhd_support_sta_mode(dhdp) || dhd_conf_get_ap_mode_in_suspend(dhdp)))
+ (dhd_support_sta_mode(dhdp) || dhd_conf_get_insuspend(dhdp)))
{
ret = dhd_set_suspend(val, dhdp);
}
@@ -5271,7 +5268,7 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
}
/* terence 2017029: Reject in early suspend */
- if (!dhd->pub.conf->xmit_in_suspend && dhd->pub.early_suspended) {
+ if ((dhd->pub.conf->insuspend & NO_TXDATA_IN_SUSPEND) && dhd->pub.early_suspended) {
dhd_txflowcontrol(&dhd->pub, ALL_INTERFACES, ON);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20))
return -ENODEV;
@@ -8549,6 +8546,15 @@ dhd_stop(struct net_device *net)
OLD_MOD_DEC_USE_COUNT;
exit:
+#if defined(WL_WIRELESS_EXT)
+ if (ifidx == 0) {
+#ifdef WL_ESCAN
+ wl_escan_down(&dhd->pub);
+#else
+ wl_iw_down(&dhd->pub);
+#endif /* WL_ESCAN */
+ }
+#endif /* defined(WL_WIRELESS_EXT) */
if (skip_reset == false) {
if (ifidx == 0 && !dhd_download_fw_on_driverload) {
#if defined(BT_OVER_SDIO)
@@ -8766,14 +8772,6 @@ dhd_open(struct net_device *net)
ret = -1;
goto exit;
}
-#if defined(WL_EXT_IAPSTA) && defined(ISAM_PREINIT)
- conf = dhd_get_conf(net);
- if (conf) {
- wl_android_ext_priv_cmd(net, conf->isam_init, 0, &bytes_written);
- wl_android_ext_priv_cmd(net, conf->isam_config, 0, &bytes_written);
- wl_android_ext_priv_cmd(net, conf->isam_enable, 0, &bytes_written);
- }
-#endif
}
#ifdef SUPPORT_DEEP_SLEEP
else {
@@ -8924,6 +8922,25 @@ dhd_open(struct net_device *net)
dhd_set_scb_probe(&dhd->pub);
#endif /* NUM_SCB_MAX_PROBE */
#endif /* WL_CFG80211 */
+#if defined(WL_WIRELESS_EXT)
+#ifdef WL_ESCAN
+ if (unlikely(wl_escan_up(net, &dhd->pub))) {
+ DHD_ERROR(("%s: failed to bring up escan\n", __FUNCTION__));
+ ret = -1;
+ goto exit;
+ }
+#endif
+#endif
+#if defined(WL_EXT_IAPSTA) && defined(ISAM_PREINIT)
+ if (!dhd_download_fw_on_driverload) {
+ conf = dhd_get_conf(net);
+ if (conf) {
+ wl_android_ext_priv_cmd(net, conf->isam_init, 0, &bytes_written);
+ wl_android_ext_priv_cmd(net, conf->isam_config, 0, &bytes_written);
+ wl_android_ext_priv_cmd(net, conf->isam_enable, 0, &bytes_written);
+ }
+ }
+#endif
}
/* Allow transmit calls */
@@ -12391,9 +12408,6 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
dhd_update_flow_prio_map(dhd, DHD_FLOW_PRIO_LLR_MAP);
#endif /* defined(BCMPCIE) && defined(EAPOL_PKT_PRIO) */
-#ifdef SUSPEND_EVENT
- bcopy(eventmask, dhd->conf->resume_eventmask, WL_EVENTING_MASK_LEN);
-#endif
/* Write updated Event mask */
ret = dhd_iovar(dhd, 0, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, NULL, 0, TRUE);
if (ret < 0) {
@@ -13494,6 +13508,11 @@ dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock)
dhd->bus_user_count--;
#endif /* BT_OVER_SDIO */
}
+#if defined(WL_WIRELESS_EXT)
+#ifdef WL_ESCAN
+ wl_escan_down(&dhd->pub);
+#endif /* WL_ESCAN */
+#endif /* defined(WL_WIRELESS_EXT) */
}
#endif /* OEM_ANDROID && (BCMPCIE || (BCMLXSDMMC && KERNEL_VERSION >= 2.6.27)) */
return 0;
@@ -16656,6 +16675,8 @@ static void dhd_hang_process(void *dhd_info, void *event_info, u8 event)
struct net_device *dev;
dhd = (dhd_info_t *)dhd_info;
+ if (!dhd || !dhd->iflist[0])
+ return;
dev = dhd->iflist[0]->net;
if (dev) {
diff --git a/bcmdhd.100.10.315.x/dhd_msgbuf.c b/bcmdhd.100.10.315.x/dhd_msgbuf.c
index 408cf89..8eb0b8a 100644
--- a/bcmdhd.100.10.315.x/dhd_msgbuf.c
+++ b/bcmdhd.100.10.315.x/dhd_msgbuf.c
@@ -6834,6 +6834,7 @@ dhd_msgbuf_wait_ioctl_cmplt(dhd_pub_t *dhd, uint32 len, void *buf)
if (intstatus) {
DHD_ERROR(("%s: reschedule dhd_dpc, cnt=%d, intstatus=0x%x, intmask=0x%x\n",
__FUNCTION__, cnt, intstatus, intmask));
+ dhd->bus->intstatus = intstatus;
dhd->bus->ipend = TRUE;
dhd->bus->dpc_sched = TRUE;
dhd_sched_dpc(dhd);
diff --git a/bcmdhd.100.10.315.x/dhd_pcie_linux.c b/bcmdhd.100.10.315.x/dhd_pcie_linux.c
index 3033dfd..8885b09 100644
--- a/bcmdhd.100.10.315.x/dhd_pcie_linux.c
+++ b/bcmdhd.100.10.315.x/dhd_pcie_linux.c
@@ -1140,7 +1140,8 @@ dhdpcie_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (dhdpcie_chipmatch (pdev->vendor, pdev->device)) {
DHD_ERROR(("%s: chipmatch failed!!\n", __FUNCTION__));
- return -ENODEV;
+ DHD_MUTEX_UNLOCK();
+ return -ENODEV;
}
printf("PCI_PROBE: bus %X, slot %X,vendor %X, device %X"
"(good PCI location)\n", pdev->bus->number,
@@ -1148,6 +1149,7 @@ dhdpcie_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (dhdpcie_init (pdev)) {
DHD_ERROR(("%s: PCIe Enumeration failed\n", __FUNCTION__));
+ DHD_MUTEX_UNLOCK();
return -ENODEV;
}
@@ -1845,7 +1847,7 @@ dhdpcie_enable_irq(dhd_bus_t *bus)
int
dhdpcie_irq_disabled(dhd_bus_t *bus)
{
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
struct irq_desc *desc = irq_to_desc(bus->dev->irq);
/* depth will be zero, if enabled */
return desc->depth;
diff --git a/bcmdhd.100.10.315.x/dhd_sdio.c b/bcmdhd.100.10.315.x/dhd_sdio.c
index 3c3b3ba..4a52e87 100644
--- a/bcmdhd.100.10.315.x/dhd_sdio.c
+++ b/bcmdhd.100.10.315.x/dhd_sdio.c
@@ -7829,6 +7829,18 @@ dhd_dump_cis(uint fn, uint8 *cis)
static bool
dhdsdio_chipmatch(uint16 chipid)
{
+ if (chipid == BCM4330_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM43362_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM43340_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM43341_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM4334_CHIP_ID)
+ return TRUE;
+ if (chipid == BCM4324_CHIP_ID)
+ return TRUE;
if (chipid == BCM4335_CHIP_ID)
return TRUE;
if (chipid == BCM4339_CHIP_ID)
diff --git a/bcmdhd.100.10.315.x/dhd_static_buf.c b/bcmdhd.100.10.315.x/dhd_static_buf.c
index 2e29474..2352ba8 100644
--- a/bcmdhd.100.10.315.x/dhd_static_buf.c
+++ b/bcmdhd.100.10.315.x/dhd_static_buf.c
@@ -6,7 +6,7 @@
#include <linux/err.h>
#include <linux/skbuff.h>
-#define DHD_STATIC_VERSION_STR "100.10.315.1"
+#define DHD_STATIC_VERSION_STR "100.10.315.2"
#define BCMDHD_SDIO
#define BCMDHD_PCIE
@@ -52,7 +52,7 @@ enum dhd_prealloc_index {
#define DHD_PREALLOC_OSL_BUF_SIZE (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)
#define DHD_PREALLOC_WIPHY_ESCAN0_SIZE (64 * 1024)
#define DHD_PREALLOC_DHD_INFO_SIZE (32 * 1024)
-#define DHD_PREALLOC_MEMDUMP_RAM_SIZE (810 * 1024)
+#define DHD_PREALLOC_MEMDUMP_RAM_SIZE (1290 * 1024)
#define DHD_PREALLOC_DHD_WLFC_HANGER_SIZE (73 * 1024)
#define DHD_PREALLOC_WL_ESCAN_INFO_SIZE (66 * 1024)
#ifdef CONFIG_64BIT
@@ -416,7 +416,7 @@ err_mem_alloc:
if (wlan_static_wl_escan_info_buf)
kfree(wlan_static_wl_escan_info_buf);
-
+
#ifdef BCMDHD_PCIE
if (wlan_static_fw_verbose_ring_buf)
kfree(wlan_static_fw_verbose_ring_buf);
@@ -512,7 +512,7 @@ dhd_static_buf_exit(void)
if (wlan_static_wl_escan_info_buf)
kfree(wlan_static_wl_escan_info_buf);
-
+
#ifdef BCMDHD_PCIE
if (wlan_static_fw_verbose_ring_buf)
kfree(wlan_static_fw_verbose_ring_buf);
diff --git a/bcmdhd.100.10.315.x/include/epivers.h b/bcmdhd.100.10.315.x/include/epivers.h
index c99ea90..0edcbdd 100644
--- a/bcmdhd.100.10.315.x/include/epivers.h
+++ b/bcmdhd.100.10.315.x/include/epivers.h
@@ -46,6 +46,6 @@
#define EPI_VERSION_DEV 100.10.315
/* Driver Version String, ASCII, 32 chars max */
-#define EPI_VERSION_STR "100.10.315.2 (r771911)"
+#define EPI_VERSION_STR "100.10.315.3 (r771911)"
#endif /* _epivers_h_ */
diff --git a/bcmdhd.100.10.315.x/linux_osl.c b/bcmdhd.100.10.315.x/linux_osl.c
index 6105a2f..f702c89 100644
--- a/bcmdhd.100.10.315.x/linux_osl.c
+++ b/bcmdhd.100.10.315.x/linux_osl.c
@@ -115,9 +115,12 @@ static int secdma_found = 0;
#endif /* BCM_SECURE_DMA */
#ifdef USE_DMA_LOCK
-#define DMA_LOCK(osh) spin_lock_bh(&(osh)->dma_lock)
-#define DMA_UNLOCK(osh) spin_unlock_bh(&(osh)->dma_lock)
-#define DMA_LOCK_INIT(osh) spin_lock_init(&(osh)->dma_lock)
+static void osl_dma_lock(osl_t *osh);
+static void osl_dma_unlock(osl_t *osh);
+static void osl_dma_lock_init(osl_t *osh);
+#define DMA_LOCK(osh) osl_dma_lock(osh)
+#define DMA_UNLOCK(osh) osl_dma_unlock(osh)
+#define DMA_LOCK_INIT(osh) osl_dma_lock_init(osh);
#else
#define DMA_LOCK(osh) do { /* noop */ } while(0)
#define DMA_UNLOCK(osh) do { /* noop */ } while(0)
@@ -1901,3 +1904,42 @@ osl_timer_del(osl_t *osh, osl_timer_t *t)
return (TRUE);
}
#endif
+
+#ifdef USE_DMA_LOCK
+static void
+osl_dma_lock(osl_t *osh)
+{
+ /* XXX: The conditional check is to avoid the scheduling bug.
+ * If the spin_lock_bh is used under the spin_lock_irqsave,
+ * Kernel triggered the warning message as the spin_lock_irqsave
+ * disables the interrupt and the spin_lock_bh doesn't use in case
+ * interrupt is disabled.
+ * Please refer to the __local_bh_enable_ip() function
+ * in kernel/softirq.c to understand the condtion.
+ */
+ if (likely(in_irq() || irqs_disabled())) {
+ spin_lock(&osh->dma_lock);
+ } else {
+ spin_lock_bh(&osh->dma_lock);
+ osh->dma_lock_bh = TRUE;
+ }
+}
+
+static void
+osl_dma_unlock(osl_t *osh)
+{
+ if (unlikely(osh->dma_lock_bh)) {
+ osh->dma_lock_bh = FALSE;
+ spin_unlock_bh(&osh->dma_lock);
+ } else {
+ spin_unlock(&osh->dma_lock);
+ }
+}
+
+static void
+osl_dma_lock_init(osl_t *osh)
+{
+ spin_lock_init(&osh->dma_lock);
+ osh->dma_lock_bh = FALSE;
+}
+#endif /* USE_DMA_LOCK */ \ No newline at end of file
diff --git a/bcmdhd.100.10.315.x/linux_osl_priv.h b/bcmdhd.100.10.315.x/linux_osl_priv.h
index 0b602cd..7ae18c2 100644
--- a/bcmdhd.100.10.315.x/linux_osl_priv.h
+++ b/bcmdhd.100.10.315.x/linux_osl_priv.h
@@ -173,6 +173,7 @@ struct osl_info {
#endif /* BCM_BACKPLANE_TIMEOUT */
#ifdef USE_DMA_LOCK
spinlock_t dma_lock;
+ bool dma_lock_bh;
#endif /* USE_DMA_LOCK */
};
diff --git a/bcmdhd.100.10.315.x/wl_android.c b/bcmdhd.100.10.315.x/wl_android.c
index 4e4b927..4fb7ab9 100644
--- a/bcmdhd.100.10.315.x/wl_android.c
+++ b/bcmdhd.100.10.315.x/wl_android.c
@@ -5256,7 +5256,7 @@ int wl_android_init(void)
{
int ret = 0;
-#ifdef ENABLE_INSMOD_NO_FW_LOAD
+#if defined(ENABLE_INSMOD_NO_FW_LOAD) || defined(BUS_POWER_RESTORE)
dhd_download_fw_on_driverload = FALSE;
#endif /* ENABLE_INSMOD_NO_FW_LOAD */
if (!iface_name[0]) {
diff --git a/bcmdhd.100.10.315.x/wl_android.h b/bcmdhd.100.10.315.x/wl_android.h
index 4fe94bc..e035aa7 100644
--- a/bcmdhd.100.10.315.x/wl_android.h
+++ b/bcmdhd.100.10.315.x/wl_android.h
@@ -73,6 +73,13 @@ typedef struct _compat_android_wifi_priv_cmd {
#define ANDROID_INFO_LEVEL 0x0004
#define ANDROID_EVENT_LEVEL 0x0008
+#define ANDROID_MSG(x) \
+ do { \
+ if (android_msg_level & ANDROID_ERROR_LEVEL) { \
+ printk(KERN_ERR "ANDROID-MSG) "); \
+ printk x; \
+ } \
+ } while (0)
#define ANDROID_ERROR(x) \
do { \
if (android_msg_level & ANDROID_ERROR_LEVEL) { \
@@ -123,8 +130,15 @@ int wl_ext_iapsta_alive_postinit(struct net_device *dev);
int wl_ext_iapsta_event(struct net_device *dev, wl_event_msg_t *e, void* data);
int wl_ext_iapsta_attach(dhd_pub_t *pub);
void wl_ext_iapsta_dettach(dhd_pub_t *pub);
+bool wl_ext_check_mesh_creating(struct net_device *net);
extern int op_mode;
#endif
+typedef struct bcol_gtk_para {
+ int enable;
+ int ptk_len;
+ char ptk[64];
+ char replay[8];
+} bcol_gtk_para_t;
int wl_android_ext_priv_cmd(struct net_device *net, char *command, int total_len,
int *bytes_written);
enum wl_ext_status {
@@ -141,12 +155,20 @@ enum wl_ext_status {
WL_EXT_STATUS_AP_DISABLED
};
typedef struct wl_conn_info {
+ struct net_device *dev;
+ dhd_pub_t *dhd;
uint8 bssidx;
wlc_ssid_t ssid;
struct ether_addr bssid;
uint16 channel;
+ struct delayed_work pm_enable_work;
+ struct mutex pm_sync;
} wl_conn_info_t;
+#if defined(WL_WIRELESS_EXT)
s32 wl_ext_connect(struct net_device *dev, wl_conn_info_t *conn_info);
+void wl_ext_pm_work_handler(struct work_struct * work);
+void wl_ext_add_remove_pm_enable_work(struct wl_conn_info *conn_info, bool add);
+#endif /* defined(WL_WIRELESS_EXT) */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
#define strnicmp(str1, str2, len) strncasecmp((str1), (str2), (len))
#endif
diff --git a/bcmdhd.100.10.315.x/wl_android_ext.c b/bcmdhd.100.10.315.x/wl_android_ext.c
index d247d7e..fe00236 100644
--- a/bcmdhd.100.10.315.x/wl_android_ext.c
+++ b/bcmdhd.100.10.315.x/wl_android_ext.c
@@ -32,6 +32,21 @@
#include <wl_escan.h>
#endif
+#if defined(WL_WIRELESS_EXT)
+#define WL_PM_ENABLE_TIMEOUT 10000
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
+ 4 && __GNUC_MINOR__ >= 6))
+#define BCM_SET_CONTAINER_OF(entry, ptr, type, member) \
+_Pragma("GCC diagnostic push") \
+_Pragma("GCC diagnostic ignored \"-Wcast-qual\"") \
+entry = container_of((ptr), type, member); \
+_Pragma("GCC diagnostic pop")
+#else
+#define BCM_SET_CONTAINER_OF(entry, ptr, type, member) \
+entry = container_of((ptr), type, member);
+#endif /* STRICT_GCC_WARNINGS */
+#endif /* defined(WL_WIRELESS_EXT) */
+
#ifndef WL_CFG80211
#define htod32(i) i
#define htod16(i) i
@@ -252,6 +267,7 @@ typedef struct wl_apsta_params {
uint csa;
apstamode_t apstamode;
bool netif_change;
+ bool mesh_creating;
wait_queue_head_t netif_change_event;
} wl_apsta_params_t;
@@ -487,13 +503,13 @@ set_channel:
if (bw == WL_CHANSPEC_BW_80)
goto change_bw;
wl_ext_ioctl(dev, WLC_SET_CHANNEL, &_chan, sizeof(_chan), 1);
- printf("%s: channel %d\n", __FUNCTION__, _chan);
+ ANDROID_MSG(("%s: channel %d\n", __FUNCTION__, _chan));
} else if (err) {
ANDROID_ERROR(("%s: failed to set chanspec error %d\n",
__FUNCTION__, err));
} else
- printf("%s: %s channel %d, 0x%x\n", __FUNCTION__,
- dev->name, channel, chspec);
+ ANDROID_MSG(("%s: %s channel %d, 0x%x\n", __FUNCTION__,
+ dev->name, channel, chspec));
} else {
ANDROID_ERROR(("%s: failed to convert host chanspec to fw chanspec\n",
__FUNCTION__));
@@ -572,9 +588,8 @@ wl_ext_channels(struct net_device *dev, char* command, int total_len)
for (i = 0; i < dtoh32(list->count); i++) {
bytes_written += snprintf(command+bytes_written, total_len, " %d",
dtoh32(list->element[i]));
- printf("%d ", dtoh32(list->element[i]));
}
- printf("\n");
+ ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
ret = bytes_written;
}
@@ -678,23 +693,25 @@ wl_ext_keep_alive(struct net_device *dev, char *command, int total_len)
goto exit;
} else {
mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) buf;
- printf("Id :%d\n"
- "Period (msec) :%d\n"
- "Length :%d\n"
- "Packet :0x",
- mkeep_alive_pktp->keep_alive_id,
- dtoh32(mkeep_alive_pktp->period_msec),
- dtoh16(mkeep_alive_pktp->len_bytes));
- for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {
- printf("%02x", mkeep_alive_pktp->data[i]);
+ if (android_msg_level & ANDROID_INFO_LEVEL) {
+ printf("Id :%d\n"
+ "Period (msec) :%d\n"
+ "Length :%d\n"
+ "Packet :0x",
+ mkeep_alive_pktp->keep_alive_id,
+ dtoh32(mkeep_alive_pktp->period_msec),
+ dtoh16(mkeep_alive_pktp->len_bytes));
+ for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {
+ printf("%02x", mkeep_alive_pktp->data[i]);
+ }
+ printf("\n");
}
- printf("\n");
}
bytes_written = snprintf(command, total_len, "mkeep_alive_period_msec %d ",
dtoh32(mkeep_alive_pktp->period_msec));
bytes_written += snprintf(command+bytes_written, total_len, "0x");
for (i=0; i<mkeep_alive_pktp->len_bytes; i++) {
- bytes_written += snprintf(command+bytes_written, total_len, "%x",
+ bytes_written += snprintf(command+bytes_written, total_len, "%02x",
mkeep_alive_pktp->data[i]);
}
ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
@@ -830,9 +847,9 @@ wl_ext_connect(struct net_device *dev, struct wl_conn_info *conn_info)
err = wl_ext_iovar_setbuf_bsscfg(dev, "join", ext_join_params,
join_params_size, iovar_buf, WLC_IOCTL_SMLEN, conn_info->bssidx, NULL);
- printf("Connecting with " MACDBG " channel (%d) ssid \"%s\", len (%d)\n\n",
+ ANDROID_MSG(("Connecting with " MACDBG " channel (%d) ssid \"%s\", len (%d)\n\n",
MAC2STRDBG((u8*)(&ext_join_params->assoc.bssid)), conn_info->channel,
- ext_join_params->ssid.SSID, ext_join_params->ssid.SSID_len);
+ ext_join_params->ssid.SSID, ext_join_params->ssid.SSID_len));
kfree(ext_join_params);
if (err) {
@@ -872,6 +889,79 @@ exit:
}
+#if defined(WL_WIRELESS_EXT)
+void wl_ext_pm_work_handler(struct work_struct * work)
+{
+ struct wl_conn_info *conn_info;
+ s32 pm = PM_FAST;
+ dhd_pub_t *dhd;
+ BCM_SET_CONTAINER_OF(conn_info, work, struct wl_conn_info, pm_enable_work.work);
+
+ ANDROID_TRACE(("%s: Enter\n", __FUNCTION__));
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
+ 4 && __GNUC_MINOR__ >= 6))
+_Pragma("GCC diagnostic push")
+_Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
+#endif
+
+ dhd = (dhd_pub_t *)(conn_info->dhd);
+ if (!dhd || !conn_info->dhd->up) {
+ ANDROID_TRACE(("%s: dhd is null or not up\n", __FUNCTION__));
+ return;
+ }
+ if (dhd_conf_get_pm(dhd) >= 0)
+ pm = dhd_conf_get_pm(dhd);
+ wl_ext_ioctl(conn_info->dev, WLC_SET_PM, &pm, sizeof(pm), 1);
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
+ 4 && __GNUC_MINOR__ >= 6))
+_Pragma("GCC diagnostic pop")
+#endif
+ DHD_PM_WAKE_UNLOCK(conn_info->dhd);
+
+}
+
+void wl_ext_add_remove_pm_enable_work(struct wl_conn_info *conn_info,
+ bool add)
+{
+ u16 wq_duration = 0;
+ s32 pm = PM_OFF;
+
+ if (conn_info == NULL || conn_info->dhd == NULL)
+ return;
+
+ mutex_lock(&conn_info->pm_sync);
+ /*
+ * Make cancel and schedule work part mutually exclusive
+ * so that while cancelling, we are sure that there is no
+ * work getting scheduled.
+ */
+
+ if (delayed_work_pending(&conn_info->pm_enable_work)) {
+ cancel_delayed_work_sync(&conn_info->pm_enable_work);
+ DHD_PM_WAKE_UNLOCK(conn_info->dhd);
+ }
+
+ if (add) {
+ wq_duration = (WL_PM_ENABLE_TIMEOUT);
+ }
+
+ /* It should schedule work item only if driver is up */
+ if (wq_duration && conn_info->dhd->up) {
+ if (dhd_conf_get_pm(conn_info->dhd) >= 0)
+ pm = dhd_conf_get_pm(conn_info->dhd);
+ wl_ext_ioctl(conn_info->dev, WLC_SET_PM, &pm, sizeof(pm), 1);
+ if (schedule_delayed_work(&conn_info->pm_enable_work,
+ msecs_to_jiffies((const unsigned int)wq_duration))) {
+ DHD_PM_WAKE_LOCK_TIMEOUT(conn_info->dhd, wq_duration);
+ } else {
+ ANDROID_ERROR(("%s: Can't schedule pm work handler\n", __FUNCTION__));
+ }
+ }
+ mutex_unlock(&conn_info->pm_sync);
+
+}
+#endif /* defined(WL_WIRELESS_EXT) */
+
#ifdef WL_EXT_IAPSTA
static int
wl_ext_parse_wep(char *key, struct wl_wsec_key *wsec_key)
@@ -1299,6 +1389,17 @@ wl_ext_wait_netif_change(struct wl_apsta_params *apsta_params,
rtnl_lock();
}
+bool
+wl_ext_check_mesh_creating(struct net_device *net)
+{
+ struct dhd_pub *dhd = dhd_get_pub(net);
+ struct wl_apsta_params *apsta_params = dhd->iapsta_params;
+
+ if (apsta_params)
+ return apsta_params->mesh_creating;
+ return FALSE;
+}
+
static void
wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_params)
{
@@ -1372,7 +1473,7 @@ wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_para
wl_config_t rsdb_mode_cfg = {0, 0};
if (apsta_params->rsdb)
rsdb_mode_cfg.config = 1;
- printf("%s: set rsdb_mode %d\n", __FUNCTION__, rsdb_mode_cfg.config);
+ ANDROID_MSG(("%s: set rsdb_mode %d\n", __FUNCTION__, rsdb_mode_cfg.config));
wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
wl_ext_iovar_setbuf(dev, "rsdb_mode", &rsdb_mode_cfg,
sizeof(rsdb_mode_cfg), iovar_buf, sizeof(iovar_buf), NULL);
@@ -1503,9 +1604,11 @@ wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_para
iface.ver = WL_INTERFACE_CREATE_VER;
iface.flags = WL_INTERFACE_CREATE_STA;
apsta_params->netif_change = FALSE;
+ apsta_params->mesh_creating = TRUE;
wl_ext_iovar_getbuf(dev, "interface_create", &iface, sizeof(iface),
iovar_buf, WLC_IOCTL_SMLEN, NULL);
wl_ext_wait_netif_change(apsta_params, TRUE);
+ apsta_params->mesh_creating = FALSE;
}
else if (apstamode == IMESHAP_MODE) {
wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
@@ -1516,11 +1619,13 @@ wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_para
// don't set WLC_SET_AP to 0, some parameters will be reset, such as bcn_timeout and roam_off
bzero(&iface, sizeof(wl_interface_create_t));
iface.ver = WL_INTERFACE_CREATE_VER;
- iface.flags = WL_INTERFACE_CREATE_AP;
+ iface.flags = WL_INTERFACE_CREATE_STA;
apsta_params->netif_change = FALSE;
+ apsta_params->mesh_creating = TRUE;
wl_ext_iovar_getbuf(dev, "interface_create", &iface, sizeof(iface),
iovar_buf, WLC_IOCTL_SMLEN, NULL);
wl_ext_wait_netif_change(apsta_params, TRUE);
+ apsta_params->mesh_creating = FALSE;
}
else if (apstamode == IMESHAPSTA_MODE) {
wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
@@ -1540,9 +1645,11 @@ wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_para
iface.ver = WL_INTERFACE_CREATE_VER;
iface.flags = WL_INTERFACE_CREATE_STA;
apsta_params->netif_change = FALSE;
+ apsta_params->mesh_creating = TRUE;
wl_ext_iovar_getbuf(dev, "interface_create", &iface, sizeof(iface),
iovar_buf, WLC_IOCTL_SMLEN, NULL);
wl_ext_wait_netif_change(apsta_params, TRUE);
+ apsta_params->mesh_creating = FALSE;
}
else if (apstamode == IMESHAPAP_MODE) {
wl_ext_ioctl(dev, WLC_DOWN, NULL, 0, 1);
@@ -1582,7 +1689,7 @@ wl_ext_iapsta_preinit(struct net_device *dev, struct wl_apsta_params *apsta_para
wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver);
apsta_params->init = TRUE;
- printf("%s: apstamode=%d\n", __FUNCTION__, apstamode);
+ ANDROID_MSG(("%s: apstamode=%d\n", __FUNCTION__, apstamode));
}
static int
@@ -2062,9 +2169,9 @@ wl_mesh_print_peer_info(mesh_peer_info_ext_t *mpi_ext,
mpi_ext->rssi);
} else {
bytes_written += snprintf(command+bytes_written, total_len,
- "\n%d: %pM : %6s : %5s : %6s :"
+ "\n%2d: %pM : %6s : %5s : %6s :"
" %5s : %4s : %4s : %11s : %4s",
- count, &mpi_ext->ea, " NA ", " NA ", " NA ",
+ count, &mpi_ext->ea, " NA ", " NA ", " NA ",
" NA ", " NA ", " NA ", " TIMEDOUT ", " NA ");
}
mpi_ext++;
@@ -2138,7 +2245,8 @@ wl_ext_if_down(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if)
} bss_setbuf;
apstamode_t apstamode = apsta_params->apstamode;
- printf("%s: %s[%c] Turning off\n", __FUNCTION__, cur_if->ifname, cur_if->prefix);
+ ANDROID_MSG(("%s: %s[%c] Turning off\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix));
if (cur_if->ifmode == ISTA_MODE) {
wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1);
@@ -2178,12 +2286,13 @@ wl_ext_if_up(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_if)
}
if (cur_if->channel >= 52 && cur_if->channel <= 148) {
- printf("%s: %s[%c] skip DFS channel %d\n", __FUNCTION__,
- cur_if->ifname, cur_if->prefix, cur_if->channel);
+ ANDROID_MSG(("%s: %s[%c] skip DFS channel %d\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix, cur_if->channel));
return 0;
}
- printf("%s: %s[%c] Turning on\n", __FUNCTION__, cur_if->ifname, cur_if->prefix);
+ ANDROID_MSG(("%s: %s[%c] Turning on\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix));
wl_ext_set_chanspec(cur_if->dev, apsta_params->ioctl_ver, cur_if->channel,
&fw_chspec);
@@ -2256,7 +2365,7 @@ wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)
return -1;
}
- printf("%s: %s[%c] Disabling\n", __FUNCTION__, ifname, cur_if->prefix);
+ ANDROID_MSG(("%s: %s[%c] Disabling\n", __FUNCTION__, ifname, cur_if->prefix));
if (cur_if->ifmode == ISTA_MODE) {
wl_ext_ioctl(cur_if->dev, WLC_DISASSOC, NULL, 0, 1);
@@ -2327,7 +2436,7 @@ wl_ext_iapsta_disable(struct net_device *dev, char *command, int total_len)
cur_if->ifstate = IF_STATE_DISALBE;
- printf("%s: %s[%c] disabled\n", __FUNCTION__, ifname, cur_if->prefix);
+ ANDROID_MSG(("%s: %s[%c] disabled\n", __FUNCTION__, ifname, cur_if->prefix));
return 0;
}
@@ -2372,11 +2481,11 @@ wl_ext_triger_csa(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_i
if (apsta_params->csa & CSA_DRV_BIT &&
(cur_if->ifmode == IAP_MODE || cur_if->ifmode == IMESH_MODE)) {
if (!cur_if->channel) {
- printf("%s: %s[%c] skip channel %d\n", __FUNCTION__,
- cur_if->ifname, cur_if->prefix, cur_if->channel);
+ ANDROID_MSG(("%s: %s[%c] skip channel %d\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix, cur_if->channel));
} else if (cur_if->channel >= 52 && cur_if->channel <= 148) {
- printf("%s: %s[%c] skip DFS channel %d\n", __FUNCTION__,
- cur_if->ifname, cur_if->prefix, cur_if->channel);
+ ANDROID_MSG(("%s: %s[%c] skip DFS channel %d\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix, cur_if->channel));
wl_ext_if_down(apsta_params, cur_if);
} else {
wl_chan_switch_t csa_arg;
@@ -2386,14 +2495,14 @@ wl_ext_triger_csa(struct wl_apsta_params *apsta_params, struct wl_if_info *cur_i
csa_arg.chspec = wl_ext_get_chanspec(apsta_params, cur_if->dev,
cur_if->channel);
if (csa_arg.chspec) {
- printf("%s: Trigger CSA to channel %d(0x%x)\n", __FUNCTION__,
- cur_if->channel, csa_arg.chspec);
+ ANDROID_MSG(("%s: Trigger CSA to channel %d(0x%x)\n", __FUNCTION__,
+ cur_if->channel, csa_arg.chspec));
wl_ext_iovar_setbuf(cur_if->dev, "csa", &csa_arg, sizeof(csa_arg),
iovar_buf, sizeof(iovar_buf), NULL);
OSL_SLEEP(500);
wl_ext_isam_status(cur_if->dev, NULL, 0);
} else {
- printf("%s: fail to get chanspec\n", __FUNCTION__);
+ ANDROID_ERROR(("%s: fail to get chanspec\n", __FUNCTION__));
}
}
}
@@ -2433,21 +2542,21 @@ wl_ext_move_cur_channel(struct wl_apsta_params *apsta_params,
tmp_chan = wl_ext_get_chan(apsta_params, cur_if->dev);
if (apsta_params->rsdb && tmp_chan &&
wl_ext_diff_band(tmp_chan, target_chan)) {
- printf("%s: %s[%c] keep on current channel %d\n", __FUNCTION__,
- cur_if->ifname, cur_if->prefix, tmp_chan);
+ ANDROID_MSG(("%s: %s[%c] keep on current channel %d\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix, tmp_chan));
cur_if->channel = 0;
} else {
- printf("%s: %s[%c] channel=%d => %s[%c] channel=%d\n", __FUNCTION__,
+ ANDROID_MSG(("%s: %s[%c] channel=%d => %s[%c] channel=%d\n", __FUNCTION__,
cur_if->ifname, cur_if->prefix, cur_if->channel,
- target_if->ifname, target_if->prefix, target_chan);
+ target_if->ifname, target_if->prefix, target_chan));
cur_if->channel = target_chan;
}
}
exit:
if ((cur_if->ifmode == IAP_MODE || cur_if->ifmode == IMESH_MODE) &&
(cur_if->channel >= 52 && cur_if->channel <= 148)) {
- printf("%s: %s[%c] skip DFS channel %d\n", __FUNCTION__,
- cur_if->ifname, cur_if->prefix, cur_if->channel);
+ ANDROID_MSG(("%s: %s[%c] skip DFS channel %d\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix, cur_if->channel));
cur_if->channel = 0;
}
@@ -2483,8 +2592,8 @@ wl_ext_move_other_channel(struct wl_apsta_params *apsta_params,
}
if (target_if) {
- printf("%s: %s channel=%d => %s channel=%d\n", __FUNCTION__,
- target_if->ifname, target_chan, cur_if->ifname, cur_if->channel);
+ ANDROID_MSG(("%s: %s channel=%d => %s channel=%d\n", __FUNCTION__,
+ target_if->ifname, target_chan, cur_if->ifname, cur_if->channel));
target_if->channel = cur_if->channel;
if (apsta_params->csa == 0) {
wl_ext_if_down(apsta_params, target_if);
@@ -2531,9 +2640,8 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname)
return -1;
}
- printf("%s: %s[%c] Enabling\n", __FUNCTION__, ifname, cur_if->prefix);
-
wl_ext_isam_status(cur_if->dev, NULL, 0);
+ ANDROID_MSG(("%s: %s[%c] Enabling\n", __FUNCTION__, ifname, cur_if->prefix));
wl_ext_move_cur_channel(apsta_params, dev, cur_if);
if (!cur_if->channel && cur_if->ifmode != ISTA_MODE) {
@@ -2615,8 +2723,8 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname)
if (cur_if->hidden > 0) {
wl_ext_ioctl(cur_if->dev, WLC_SET_CLOSED, &cur_if->hidden,
sizeof(cur_if->hidden), 1);
- printf("%s: Broadcast SSID: %s\n", __FUNCTION__,
- cur_if->hidden ? "OFF":"ON");
+ ANDROID_MSG(("%s: Broadcast SSID: %s\n", __FUNCTION__,
+ cur_if->hidden ? "OFF":"ON"));
}
}
@@ -2664,7 +2772,7 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname)
} else if (cur_if->ifmode == IAP_MODE) {
wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &ssid, sizeof(ssid), 1);
} else {
- printf("%s: wrong ifmode %d\n", __FUNCTION__, cur_if->ifmode);
+ ANDROID_ERROR(("%s: wrong ifmode %d\n", __FUNCTION__, cur_if->ifmode));
}
#ifdef WLMESH
} else if (apstamode == IMESHONLY_MODE ||
@@ -2684,7 +2792,7 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname)
join_params.params.chanspec_num = 1;
wl_ext_ioctl(cur_if->dev, WLC_SET_SSID, &join_params, sizeof(join_params), 1);
} else {
- printf("%s: wrong ifmode %d\n", __FUNCTION__, cur_if->ifmode);
+ ANDROID_ERROR(("%s: wrong ifmode %d\n", __FUNCTION__, cur_if->ifmode));
}
#endif
}
@@ -2705,8 +2813,8 @@ wl_ext_enable_iface(struct net_device *dev, char *ifname)
#endif
OSL_SLEEP(500);
- printf("%s: %s[%c] enabled with SSID: \"%s\"\n", __FUNCTION__,
- ifname, cur_if->prefix, cur_if->ssid);
+ ANDROID_MSG(("%s: %s[%c] enabled with SSID: \"%s\"\n", __FUNCTION__,
+ ifname, cur_if->prefix, cur_if->ssid));
wl_ext_isam_status(cur_if->dev, NULL, 0);
cur_if->ifstate = IF_STATE_ENABLE;
@@ -2824,7 +2932,7 @@ wl_ext_iapsta_alive_postinit(struct net_device *dev)
// fix me: how to check it's IAPSTA_MODE or IDUALAP_MODE?
wl_ext_get_ioctl_ver(dev, &apsta_params->ioctl_ver);
- printf("%s: apstamode=%d\n", __FUNCTION__, apsta_params->apstamode);
+ ANDROID_MSG(("%s: apstamode=%d\n", __FUNCTION__, apsta_params->apstamode));
return op_mode;
}
@@ -2957,15 +3065,14 @@ wl_ext_iapsta_event(struct net_device *dev, wl_event_msg_t *e, void* data)
#if defined(WL_WIRELESS_EXT)
char extra[IW_CUSTOM_MAX];
union iwreq_data wrqu;
+ uint32 datalen = ntoh32(e->datalen);
#endif
uint32 event_type = ntoh32(e->event_type);
uint32 status = ntoh32(e->status);
uint32 reason = ntoh32(e->reason);
uint16 flags = ntoh16(e->flags);
- uint32 datalen = ntoh32(e->datalen);
if (!apsta_params->init) {
- ANDROID_TRACE(("%s: please init first\n", __FUNCTION__));
return -1;
}
@@ -2984,11 +3091,11 @@ wl_ext_iapsta_event(struct net_device *dev, wl_event_msg_t *e, void* data)
if (cur_if->ifmode == ISTA_MODE) {
if (event_type == WLC_E_LINK) {
if (!(flags & WLC_EVENT_MSG_LINK)) {
- printf("%s: %s[%c] Link Down with %pM\n", __FUNCTION__,
- cur_if->ifname, cur_if->prefix, &e->addr);
+ ANDROID_MSG(("%s: %s[%c] Link Down with %pM\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix, &e->addr));
} else {
- printf("%s: %s[%c] Link UP with %pM\n", __FUNCTION__,
- cur_if->ifname, cur_if->prefix, &e->addr);
+ ANDROID_MSG(("%s: %s[%c] Link UP with %pM\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix, &e->addr));
}
}
}
@@ -2996,25 +3103,25 @@ wl_ext_iapsta_event(struct net_device *dev, wl_event_msg_t *e, void* data)
if ((event_type == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) ||
(event_type == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS &&
reason == WLC_E_REASON_INITIAL_ASSOC)) {
- printf("%s: %s[%c] Link up\n", __FUNCTION__,
- cur_if->ifname, cur_if->prefix);
+ ANDROID_MSG(("%s: %s[%c] Link up\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix));
} else if ((event_type == WLC_E_LINK && reason == WLC_E_LINK_BSSCFG_DIS) ||
(event_type == WLC_E_LINK && status == WLC_E_STATUS_SUCCESS &&
reason == WLC_E_REASON_DEAUTH)) {
- printf("%s: %s[%c] Link down\n", __FUNCTION__,
- cur_if->ifname, cur_if->prefix);
+ ANDROID_MSG(("%s: %s[%c] Link down\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix));
}
else if ((event_type == WLC_E_ASSOC_IND || event_type == WLC_E_REASSOC_IND) &&
reason == DOT11_SC_SUCCESS) {
- printf("%s: %s[%c] connected device %pM\n", __FUNCTION__,
- cur_if->ifname, cur_if->prefix, &e->addr);
+ ANDROID_MSG(("%s: %s[%c] connected device %pM\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix, &e->addr));
} else if (event_type == WLC_E_DISASSOC_IND) {
- printf("%s: %s[%c] disassociated device %pM\n", __FUNCTION__,
- cur_if->ifname, cur_if->prefix, &e->addr);
+ ANDROID_MSG(("%s: %s[%c] disassociated device %pM\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix, &e->addr));
} else if (event_type == WLC_E_DEAUTH_IND ||
(event_type == WLC_E_DEAUTH && reason != DOT11_RC_RESERVED)) {
- printf("%s: %s[%c] deauthenticated device %pM\n", __FUNCTION__,
- cur_if->ifname, cur_if->prefix, &e->addr);
+ ANDROID_MSG(("%s: %s[%c] deauthenticated device %pM\n", __FUNCTION__,
+ cur_if->ifname, cur_if->prefix, &e->addr));
}
}
@@ -3103,7 +3210,7 @@ wl_ext_iapsta_attach_netdev(struct net_device *net, int ifidx, uint8 bssidx)
struct wl_apsta_params *apsta_params = dhd->iapsta_params;
struct wl_if_info *cur_if = NULL, *primary_if;
- printf("%s: ifidx=%d, bssidx=%d\n", __FUNCTION__, ifidx, bssidx);
+ ANDROID_MSG(("%s: ifidx=%d, bssidx=%d\n", __FUNCTION__, ifidx, bssidx));
if (ifidx < MAX_IF_NUM) {
cur_if = &apsta_params->if_info[ifidx];
}
@@ -3159,7 +3266,7 @@ wl_ext_iapsta_dettach_netdev(struct net_device *net, int ifidx)
if (!apsta_params)
return 0;
- printf("%s: ifidx=%d\n", __FUNCTION__, ifidx);
+ ANDROID_MSG(("%s: ifidx=%d\n", __FUNCTION__, ifidx));
if (ifidx < MAX_IF_NUM) {
cur_if = &apsta_params->if_info[ifidx];
}
@@ -3179,7 +3286,7 @@ int wl_ext_iapsta_attach(dhd_pub_t *pub)
iapsta_params = kzalloc(sizeof(struct wl_apsta_params), GFP_KERNEL);
if (unlikely(!iapsta_params)) {
- printf("%s: Could not allocate apsta_params\n", __FUNCTION__);
+ ANDROID_ERROR(("%s: Could not allocate apsta_params\n", __FUNCTION__));
return -ENOMEM;
}
pub->iapsta_params = (void *)iapsta_params;
@@ -3296,7 +3403,7 @@ wl_ext_rsdb_mode(struct net_device *dev, char *data, char *command,
rsdb_mode_cfg.config = (int)simple_strtol(data, NULL, 0);
ret = wl_ext_iovar_setbuf(dev, "rsdb_mode", (char *)&rsdb_mode_cfg,
sizeof(rsdb_mode_cfg), iovar_buf, WLC_IOCTL_SMLEN, NULL);
- printf("%s: rsdb_mode %d\n", __FUNCTION__, rsdb_mode_cfg.config);
+ ANDROID_MSG(("%s: rsdb_mode %d\n", __FUNCTION__, rsdb_mode_cfg.config));
} else {
ret = wl_ext_iovar_getbuf(dev, "rsdb_mode", NULL, 0,
iovar_buf, WLC_IOCTL_SMLEN, NULL);
@@ -3311,9 +3418,41 @@ wl_ext_rsdb_mode(struct net_device *dev, char *data, char *command,
return ret;
}
-#ifdef SENDPROB
-int
-wl_ext_add_remove_eventmsg(struct net_device *dev, char *data,
+static s32
+wl_ext_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add)
+{
+ s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
+ s8 eventmask[WL_EVENTING_MASK_LEN];
+ s32 err = 0;
+
+ if (!ndev)
+ return -ENODEV;
+
+ /* Setup event_msgs */
+ err = wldev_iovar_getbuf(ndev, "event_msgs", NULL, 0, iovbuf, sizeof(iovbuf), NULL);
+ if (unlikely(err)) {
+ ANDROID_ERROR(("Get event_msgs error (%d)\n", err));
+ goto eventmsg_out;
+ }
+ memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
+ if (add) {
+ setbit(eventmask, event);
+ } else {
+ clrbit(eventmask, event);
+ }
+ err = wldev_iovar_setbuf(ndev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+ sizeof(iovbuf), NULL);
+ if (unlikely(err)) {
+ ANDROID_ERROR(("Set event_msgs error (%d)\n", err));
+ goto eventmsg_out;
+ }
+
+eventmsg_out:
+ return err;
+}
+
+static int
+wl_ext_event_msg(struct net_device *dev, char *data,
char *command, int total_len)
{
s8 iovbuf[WL_EVENTING_MASK_LEN + 12];
@@ -3329,7 +3468,8 @@ wl_ext_add_remove_eventmsg(struct net_device *dev, char *data,
ANDROID_TRACE(("%s: command = %s\n", __FUNCTION__, data));
sscanf(data, "%d %d", &event, &add);
/* Setup event_msgs */
- bytes_written = wldev_iovar_getbuf(dev, "event_msgs", NULL, 0, iovbuf, sizeof(iovbuf), NULL);
+ bytes_written = wldev_iovar_getbuf(dev, "event_msgs", NULL, 0, iovbuf,
+ sizeof(iovbuf), NULL);
if (unlikely(bytes_written)) {
ANDROID_ERROR(("Get event_msgs error (%d)\n", bytes_written));
goto eventmsg_out;
@@ -3343,21 +3483,12 @@ wl_ext_add_remove_eventmsg(struct net_device *dev, char *data,
ANDROID_INFO(("%s\n", command));
goto eventmsg_out;
}
- if (add) {
- setbit(eventmask, event);
- } else {
- clrbit(eventmask, event);
- }
- bytes_written = wl_ext_iovar_setbuf(dev, "event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
- sizeof(iovbuf), NULL);
- if (unlikely(bytes_written)) {
- ANDROID_ERROR(("Set event_msgs error (%d)\n", bytes_written));
- goto eventmsg_out;
- }
+ bytes_written = wl_ext_add_remove_eventmsg(dev, event, add);
}
else {
/* Setup event_msgs */
- bytes_written = wldev_iovar_getbuf(dev, "event_msgs", NULL, 0, iovbuf, sizeof(iovbuf), NULL);
+ bytes_written = wldev_iovar_getbuf(dev, "event_msgs", NULL, 0, iovbuf,
+ sizeof(iovbuf), NULL);
if (bytes_written) {
ANDROID_ERROR(("Get event_msgs error (%d)\n", bytes_written));
goto eventmsg_out;
@@ -3379,6 +3510,7 @@ eventmsg_out:
return bytes_written;
}
+#ifdef SENDPROB
static int
wl_ext_send_probresp(struct net_device *dev, char *data, char *command, int total_len)
{
@@ -3443,6 +3575,47 @@ exit:
}
#endif
+static int
+wl_ext_gtk_key_info(struct net_device *dev, char *data, char *command, int total_len)
+{
+ int err = 0;
+ char iovar_buf[WLC_IOCTL_SMLEN]="\0";
+ gtk_keyinfo_t keyinfo;
+ bcol_gtk_para_t bcol_keyinfo;
+
+ /* wl gtk_key_info [kck kek replay_ctr] */
+ /* wl gtk_key_info 001122..FF001122..FF00000000000001 */
+ if (data) {
+ memset(&keyinfo, 0, sizeof(keyinfo));
+ memcpy(&keyinfo, data, RSN_KCK_LENGTH+RSN_KEK_LENGTH+RSN_REPLAY_LEN);
+ if (android_msg_level & ANDROID_INFO_LEVEL) {
+ prhex("kck", (uchar *)keyinfo.KCK, RSN_KCK_LENGTH);
+ prhex("kek", (uchar *)keyinfo.KEK, RSN_KEK_LENGTH);
+ prhex("replay_ctr", (uchar *)keyinfo.ReplayCounter, RSN_REPLAY_LEN);
+ }
+
+ memset(&bcol_keyinfo, 0, sizeof(bcol_keyinfo));
+ bcol_keyinfo.enable = 1;
+ bcol_keyinfo.ptk_len = 64;
+ memcpy(&bcol_keyinfo.ptk, data, RSN_KCK_LENGTH+RSN_KEK_LENGTH);
+ err = wl_ext_iovar_setbuf(dev, "bcol_gtk_rekey_ptk", &bcol_keyinfo,
+ sizeof(bcol_keyinfo), iovar_buf, sizeof(iovar_buf), NULL);
+ if (!err) {
+ goto exit;
+ }
+
+ err = wl_ext_iovar_setbuf(dev, "gtk_key_info", &keyinfo, sizeof(keyinfo),
+ iovar_buf, sizeof(iovar_buf), NULL);
+ if (err) {
+ ANDROID_ERROR(("%s: failed to set gtk_key_info\n", __FUNCTION__));
+ goto exit;
+ }
+ }
+
+exit:
+ return err;
+}
+
typedef int (wl_ext_tpl_parse_t)(struct net_device *dev, char *data, char *command,
int total_len);
@@ -3458,10 +3631,11 @@ const wl_ext_iovar_tpl_t wl_ext_iovar_tpl_list[] = {
#ifdef WLMESH
{WLC_GET_VAR, WLC_SET_VAR, "mesh_peer_status", wl_ext_mesh_peer_status},
#endif
+ {WLC_GET_VAR, WLC_SET_VAR, "event_msg", wl_ext_event_msg},
#ifdef SENDPROB
- {WLC_GET_VAR, WLC_SET_VAR, "event_msg", wl_ext_add_remove_eventmsg},
{WLC_GET_VAR, WLC_SET_VAR, "send_probresp", wl_ext_send_probresp},
#endif
+ {WLC_GET_VAR, WLC_SET_VAR, "gtk_key_info", wl_ext_gtk_key_info},
};
/*
@@ -3796,7 +3970,7 @@ wl_ext_get_best_channel(struct net_device *net,
}
}
- if (android_msg_level&ANDROID_INFO_LEVEL) {
+ if (android_msg_level & ANDROID_INFO_LEVEL) {
printf("%s: b_band: ", __FUNCTION__);
for (j=0; j<ARRAYSIZE(b_band); j++)
printf("%d, ", b_band[j]);
diff --git a/bcmdhd.100.10.315.x/wl_cfg80211.c b/bcmdhd.100.10.315.x/wl_cfg80211.c
index 7138d7d..a15d019 100644
--- a/bcmdhd.100.10.315.x/wl_cfg80211.c
+++ b/bcmdhd.100.10.315.x/wl_cfg80211.c
@@ -3457,10 +3457,13 @@ wl_run_escan(struct bcm_cfg80211 *cfg, struct net_device *ndev,
}
exit:
if (unlikely(err)) {
+ int suppressed = 0;
+ wldev_ioctl(dev, WLC_GET_SCANSUPPRESS, &suppressed, sizeof(int), false);
/* Don't print Error incase of Scan suppress */
- if ((err == BCME_EPERM) && cfg->scan_suppressed)
+ if ((err == BCME_EPERM) && (cfg->scan_suppressed || suppressed)) {
+ cnt = 0;
WL_DBG(("Escan failed: Scan Suppressed \n"));
- else {
+ } else {
cnt++;
WL_ERR(("error (%d), cnt=%d\n", err, cnt));
// terence 20140111: send disassoc to firmware
@@ -4686,6 +4689,13 @@ wl_cfg80211_post_ifcreate(struct net_device *ndev,
return NULL;
}
+#ifdef WL_EXT_IAPSTA
+ if (wl_ext_check_mesh_creating(ndev)) {
+ printf("%s: change iface_type to NL80211_IFTYPE_MESH_POINT\n", __FUNCTION__);
+ iface_type = NL80211_IFTYPE_MESH_POINT;
+ }
+#endif
+
WL_DBG(("mac_ptr:%p name:%s role:%d nl80211_iftype:%d " MACDBG "\n",
addr, name, event->role, iface_type, MAC2STRDBG(event->mac)));
if (!name) {
@@ -10640,6 +10650,31 @@ wl_cfg80211_parse_ies(const u8 *ptr, u32 len, struct parsed_ies *ies)
return err;
}
+
+bool
+wl_legacy_chip_check(struct bcm_cfg80211 *cfg)
+{
+ dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
+ uint chip;
+
+ chip = dhd_conf_get_chip(dhd);
+
+ if (chip == BCM43362_CHIP_ID || chip == BCM4330_CHIP_ID ||
+ chip == BCM43430_CHIP_ID || chip == BCM43012_CHIP_ID ||
+ chip == BCM4334_CHIP_ID || chip == BCM43340_CHIP_ID ||
+ chip == BCM43341_CHIP_ID || chip == BCM4324_CHIP_ID ||
+ chip == BCM4335_CHIP_ID || chip == BCM4339_CHIP_ID ||
+ chip == BCM4345_CHIP_ID || chip == BCM43454_CHIP_ID ||
+ chip == BCM4354_CHIP_ID || chip == BCM4356_CHIP_ID ||
+ chip == BCM4371_CHIP_ID || chip == BCM4359_CHIP_ID ||
+ chip == BCM43143_CHIP_ID || chip == BCM43242_CHIP_ID ||
+ chip == BCM43569_CHIP_ID) {
+ return true;
+ }
+
+ return false;
+}
+
static s32
wl_cfg80211_set_ap_role(
struct bcm_cfg80211 *cfg,
@@ -10651,6 +10686,9 @@ wl_cfg80211_set_ap_role(
s32 pm;
s32 bssidx;
s32 apsta = 0;
+ bool legacy_chip;
+
+ legacy_chip = wl_legacy_chip_check(cfg);
if ((bssidx = wl_get_bssidx_by_wdev(cfg, dev->ieee80211_ptr)) < 0) {
WL_ERR(("Find p2p index from wdev(%p) failed\n", dev->ieee80211_ptr));
@@ -10659,10 +10697,12 @@ wl_cfg80211_set_ap_role(
WL_INFORM_MEM(("[%s] Bringup SoftAP on bssidx:%d \n", dev->name, bssidx));
- if ((err = wl_cfg80211_add_del_bss(cfg, dev, bssidx,
- WL_IF_TYPE_AP, 0, NULL)) < 0) {
- WL_ERR(("wl add_del_bss returned error:%d\n", err));
- return err;
+ if (bssidx != 0 || !legacy_chip) {
+ if ((err = wl_cfg80211_add_del_bss(cfg, dev, bssidx,
+ WL_IF_TYPE_AP, 0, NULL)) < 0) {
+ WL_ERR(("wl add_del_bss returned error:%d\n", err));
+ return err;
+ }
}
/*
@@ -10710,6 +10750,21 @@ wl_cfg80211_set_ap_role(
return err;
}
}
+ } else if (bssidx == 0 && legacy_chip) {
+ err = wldev_ioctl_set(dev, WLC_DOWN, &ap, sizeof(s32));
+ if (err < 0) {
+ WL_ERR(("WLC_DOWN error %d\n", err));
+ return err;
+ }
+ err = wldev_iovar_setint(dev, "apsta", 0);
+ if (err < 0) {
+ WL_ERR(("wl apsta 0 error %d\n", err));
+ return err;
+ }
+ if ((err = wldev_ioctl_set(dev, WLC_SET_AP, &ap, sizeof(s32))) < 0) {
+ WL_ERR(("setting AP mode failed %d \n", err));
+ return err;
+ }
}
if (bssidx == 0) {
@@ -10796,7 +10851,7 @@ wl_cfg80211_bcn_bringup_ap(
WL_DBG(("Bss is already up\n"));
} else if (dev_role == NL80211_IFTYPE_AP) {
- if (!wl_get_drv_status(cfg, AP_CREATING, dev)) {
+ if (!wl_get_drv_status(cfg, AP_CREATED, dev)) {
/* Make sure fw is in proper state */
err = wl_cfg80211_set_ap_role(cfg, dev);
if (unlikely(err)) {
@@ -22109,6 +22164,7 @@ wl_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
s32 err = 0;
gtk_keyinfo_t keyinfo;
+ bcol_gtk_para_t bcol_keyinfo;
WL_DBG(("Enter\n"));
if (data == NULL || cfg->p2p_net == dev) {
@@ -22123,11 +22179,23 @@ wl_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
bcopy(data->kek, keyinfo.KEK, RSN_KEK_LENGTH);
bcopy(data->replay_ctr, keyinfo.ReplayCounter, RSN_REPLAY_LEN);
+ memset(&bcol_keyinfo, 0, sizeof(bcol_keyinfo));
+ bcol_keyinfo.enable = 1;
+ bcol_keyinfo.ptk_len = 64;
+ memcpy(&bcol_keyinfo.ptk[0], data->kck, RSN_KCK_LENGTH);
+ memcpy(&bcol_keyinfo.ptk[RSN_KCK_LENGTH], data->kek, RSN_KEK_LENGTH);
+ err = wldev_iovar_setbuf(dev, "bcol_gtk_rekey_ptk", &bcol_keyinfo,
+ sizeof(bcol_keyinfo), cfg->ioctl_buf, WLC_IOCTL_SMLEN, &cfg->ioctl_buf_sync);
+ if (!err) {
+ return err;
+ }
+
if ((err = wldev_iovar_setbuf(dev, "gtk_key_info", &keyinfo, sizeof(keyinfo),
cfg->ioctl_buf, WLC_IOCTL_SMLEN, &cfg->ioctl_buf_sync)) < 0) {
WL_ERR(("seting gtk_key_info failed code=%d\n", err));
return err;
}
+
WL_DBG(("Exit\n"));
return err;
}
diff --git a/bcmdhd.100.10.315.x/wl_escan.c b/bcmdhd.100.10.315.x/wl_escan.c
index ef1dde1..a612957 100644
--- a/bcmdhd.100.10.315.x/wl_escan.c
+++ b/bcmdhd.100.10.315.x/wl_escan.c
@@ -1072,17 +1072,21 @@ wl_escan_set_scan(
ESCAN_ERROR(("device is not ready\n"));
return -EIO;
}
+ if (escan->escan_state == ESCAN_STATE_DOWN) {
+ ESCAN_ERROR(("STATE is down\n"));
+ return -EIO;
+ }
mutex_lock(&escan->usr_sync);
if (!escan->ioctl_ver) {
val = 1;
if ((err = wldev_ioctl(dev, WLC_GET_VERSION, &val, sizeof(int), false) < 0)) {
- ANDROID_ERROR(("WLC_GET_VERSION failed, err=%d\n", err));
+ ESCAN_ERROR(("WLC_GET_VERSION failed, err=%d\n", err));
goto exit;
}
val = dtoh32(val);
if (val != WLC_IOCTL_VERSION && val != 1) {
- ANDROID_ERROR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n",
+ ESCAN_ERROR(("Version mismatch, please upgrade. Got %d, expected %d or 1\n",
val, WLC_IOCTL_VERSION));
goto exit;
}
@@ -1415,7 +1419,7 @@ s32 wl_escan_autochannel(struct net_device *dev, char* command, int total_len)
} else if (escan->autochannel == 2) {
bytes_written = snprintf(command, total_len, "2g=%d 5g=%d",
escan->best_2g_ch, escan->best_5g_ch);
- ANDROID_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
+ ESCAN_TRACE(("%s: command result is %s\n", __FUNCTION__, command));
ret = bytes_written;
}
@@ -1452,7 +1456,7 @@ static void wl_escan_deinit(struct wl_escan_info *escan)
wl_destroy_event_handler(escan);
wl_flush_eq(escan);
del_timer_sync(&escan->scan_timeout);
- escan->escan_state = ESCAN_STATE_IDLE;
+ escan->escan_state = ESCAN_STATE_DOWN;
#if defined(RSSIAVG)
wl_free_rssi_cache(&escan->g_rssi_cache_ctrl);
@@ -1460,6 +1464,7 @@ static void wl_escan_deinit(struct wl_escan_info *escan)
#if defined(BSSCACHE)
wl_free_bss_cache(&escan->g_bss_cache_ctrl);
#endif
+ wl_ext_add_remove_pm_enable_work(&escan->conn_info, FALSE);
}
static s32 wl_escan_init(struct wl_escan_info *escan)
@@ -1482,6 +1487,7 @@ static s32 wl_escan_init(struct wl_escan_info *escan)
#endif
if (wl_create_event_handler(escan)) {
+ ESCAN_ERROR(("device is not ready\n"));
err = -ENOMEM;
goto err;
}
@@ -1490,14 +1496,33 @@ static s32 wl_escan_init(struct wl_escan_info *escan)
escan->evt_handler[WLC_E_ESCAN_RESULT] = wl_escan_handler;
escan->escan_state = ESCAN_STATE_IDLE;
- mutex_init(&escan->usr_sync);
-
return 0;
err:
wl_escan_deinit(escan);
return err;
}
+void wl_escan_down(dhd_pub_t *dhdp)
+{
+ struct wl_escan_info *escan = dhdp->escan;
+
+ wl_escan_deinit(escan);
+}
+
+int wl_escan_up(struct net_device *net, dhd_pub_t *dhdp)
+{
+ struct wl_escan_info *escan = dhdp->escan;
+ int err;
+
+ err = wl_escan_init(escan);
+ if (err) {
+ ESCAN_ERROR(("wl_escan_init err %d\n", err));
+ return err;
+ }
+
+ return 0;
+}
+
void wl_escan_detach(dhd_pub_t *dhdp)
{
struct wl_escan_info *escan = dhdp->escan;
@@ -1523,6 +1548,7 @@ int
wl_escan_attach(struct net_device *dev, dhd_pub_t *dhdp)
{
struct wl_escan_info *escan = NULL;
+ int err = 0;
printf("%s: Enter\n", __FUNCTION__);
@@ -1537,7 +1563,9 @@ wl_escan_attach(struct net_device *dev, dhd_pub_t *dhdp)
/* we only care about main interface so save a global here */
escan->dev = dev;
escan->pub = dhdp;
- escan->escan_state = ESCAN_STATE_IDLE;
+ escan->conn_info.dev = dev;
+ escan->conn_info.dhd = dhdp;
+ escan->escan_state = ESCAN_STATE_DOWN;
escan->escan_ioctl_buf = (void *)kzalloc(WLC_IOCTL_MAXLEN, GFP_KERNEL);
if (unlikely(!escan->escan_ioctl_buf)) {
@@ -1545,7 +1573,14 @@ wl_escan_attach(struct net_device *dev, dhd_pub_t *dhdp)
goto err ;
}
wl_init_eq(escan);
- wl_escan_init(escan);
+ err = wl_escan_init(escan);
+ if (err) {
+ ESCAN_ERROR(("wl_escan_init err %d\n", err));
+ return err;
+ }
+ mutex_init(&escan->usr_sync);
+ mutex_init(&escan->conn_info.pm_sync);
+ INIT_DELAYED_WORK(&escan->conn_info.pm_enable_work, wl_ext_pm_work_handler);
return 0;
err:
diff --git a/bcmdhd.100.10.315.x/wl_escan.h b/bcmdhd.100.10.315.x/wl_escan.h
index 1cb7428..86cde62 100644
--- a/bcmdhd.100.10.315.x/wl_escan.h
+++ b/bcmdhd.100.10.315.x/wl_escan.h
@@ -34,6 +34,7 @@ struct pmk_list {
/* donlge escan state */
enum escan_state {
+ ESCAN_STATE_DOWN,
ESCAN_STATE_IDLE,
ESCAN_STATE_SCANING
};
@@ -47,7 +48,7 @@ typedef struct wl_escan_info {
struct net_device *dev;
dhd_pub_t *pub;
struct timer_list scan_timeout; /* Timer for catch scan event timeout */
- int escan_state;
+ int escan_state;
int ioctl_ver;
char ioctlbuf[WLC_IOCTL_SMLEN];
@@ -88,6 +89,8 @@ int wl_escan_get_scan(struct net_device *dev, struct iw_request_info *info,
s32 wl_escan_autochannel(struct net_device *dev, char* command, int total_len);
int wl_escan_attach(struct net_device *dev, dhd_pub_t *dhdp);
void wl_escan_detach(dhd_pub_t *dhdp);
+int wl_escan_up(struct net_device *net, dhd_pub_t *dhdp);
+void wl_escan_down(dhd_pub_t *dhdp);
#endif /* _wl_escan_ */
diff --git a/bcmdhd.100.10.315.x/wl_iw.c b/bcmdhd.100.10.315.x/wl_iw.c
index 1556d9c..7859fba 100644
--- a/bcmdhd.100.10.315.x/wl_iw.c
+++ b/bcmdhd.100.10.315.x/wl_iw.c
@@ -472,18 +472,35 @@ wl_iw_set_pm(
#endif /* WIRELESS_EXT > 12 */
static void
-wl_iw_check_handshake(struct net_device *dev, bool set)
+wl_iw_update_connect_status(struct net_device *dev, enum wl_ext_status status)
{
#ifndef WL_CFG80211
struct dhd_pub *dhd = dhd_get_pub(dev);
int cur_eapol_status = 0;
int wpa_auth = 0;
int error = -EINVAL;
+ wl_conn_info_t *conn_info = NULL;
+#ifdef WL_ESCAN
+ wl_escan_info_t *escan;
+ if (dhd && dhd->escan) {
+ escan = (wl_escan_info_t *)dhd->escan;
+ conn_info = &escan->conn_info;
+ }
+#else
+ iscan_info_t *iscan;
+ if (dhd && dhd->iscan) {
+ iscan = (iscan_info_t *)dhd->iscan;
+ conn_info = &iscan->conn_info;
+ }
+#endif
+
+ if (!dhd || !dhd->conf || !conn_info)
+ return;
- if (dhd && dhd->conf)
- cur_eapol_status = dhd->conf->eapol_status;
+ cur_eapol_status = dhd->conf->eapol_status;
- if (set) {
+ if (status == WL_EXT_STATUS_CONNECTING) {
+ wl_ext_add_remove_pm_enable_work(conn_info, TRUE);
if ((error = dev_wlc_intvar_get(dev, "wpa_auth", &wpa_auth))) {
WL_ERROR(("%s: wpa_auth get error %d\n", __FUNCTION__, error));
return;
@@ -492,7 +509,20 @@ wl_iw_check_handshake(struct net_device *dev, bool set)
dhd->conf->eapol_status = EAPOL_STATUS_WPA_START;
else
dhd->conf->eapol_status = EAPOL_STATUS_NONE;
- } else {
+ } else if (status == WL_EXT_STATUS_ADD_KEY) {
+ dhd->conf->eapol_status = EAPOL_STATUS_WPA_END;
+ } else if (status == WL_EXT_STATUS_DISCONNECTING) {
+ wl_ext_add_remove_pm_enable_work(conn_info, FALSE);
+ if (cur_eapol_status >= EAPOL_STATUS_WPA_START &&
+ cur_eapol_status < EAPOL_STATUS_WPA_END) {
+ WL_ERROR(("%s: WPA failed at %d\n", __FUNCTION__, cur_eapol_status));
+ dhd->conf->eapol_status = EAPOL_STATUS_NONE;
+ } else if (cur_eapol_status >= EAPOL_STATUS_WPS_WSC_START &&
+ cur_eapol_status < EAPOL_STATUS_WPS_DONE) {
+ WL_ERROR(("%s: WPS failed at %d\n", __FUNCTION__, cur_eapol_status));
+ dhd->conf->eapol_status = EAPOL_STATUS_NONE;
+ }
+ } else if (status == WL_EXT_STATUS_DISCONNECTED) {
if (cur_eapol_status >= EAPOL_STATUS_WPA_START &&
cur_eapol_status < EAPOL_STATUS_WPA_END) {
WL_ERROR(("%s: WPA failed at %d\n", __FUNCTION__, cur_eapol_status));
@@ -722,8 +752,11 @@ wl_iw_set_mode(
#endif
WL_TRACE(("%s: SIOCSIWMODE\n", dev->name));
- if (conn_info)
- memset(conn_info, 0, sizeof(wl_conn_info_t));
+ if (conn_info) {
+ memset(&conn_info->ssid, 0, sizeof(wlc_ssid_t));
+ memset(&conn_info->bssid, 0, sizeof(struct ether_addr));
+ conn_info->channel = 0;
+ }
switch (*uwrq) {
case IW_MODE_MASTER:
@@ -1098,7 +1131,7 @@ wl_iw_set_wap(
if ((error = dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)))) {
WL_ERROR(("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error));
}
- wl_iw_check_handshake(dev, FALSE);
+ wl_iw_update_connect_status(dev, WL_EXT_STATUS_DISCONNECTING);
return 0;
}
/* WL_ASSOC(("Assoc to %s\n", bcm_ether_ntoa((struct ether_addr *)&(awrq->sa_data),
@@ -1117,7 +1150,7 @@ wl_iw_set_wap(
}
WL_ERROR(("%s: join BSSID="MACSTR"\n", __FUNCTION__, MAC2STR((u8 *)awrq->sa_data)));
}
- wl_iw_check_handshake(dev, TRUE);
+ wl_iw_update_connect_status(dev, WL_EXT_STATUS_CONNECTING);
return 0;
}
@@ -1178,7 +1211,7 @@ wl_iw_mlme(
WL_ERROR(("%s: Invalid ioctl data.\n", __FUNCTION__));
return error;
}
- wl_iw_check_handshake(dev, FALSE);
+ wl_iw_update_connect_status(dev, WL_EXT_STATUS_DISCONNECTING);
return error;
}
@@ -1869,7 +1902,7 @@ wl_iw_set_essid(
}
WL_ERROR(("%s: join SSID=%s\n", __FUNCTION__, ssid.SSID));
}
- wl_iw_check_handshake(dev, TRUE);
+ wl_iw_update_connect_status(dev, WL_EXT_STATUS_CONNECTING);
}
/* If essid null then it is "iwconfig <interface> essid off" command */
else {
@@ -1880,7 +1913,7 @@ wl_iw_set_essid(
WL_ERROR(("%s: WLC_DISASSOC failed (%d).\n", __FUNCTION__, error));
return error;
}
- wl_iw_check_handshake(dev, FALSE);
+ wl_iw_update_connect_status(dev, WL_EXT_STATUS_DISCONNECTING);
}
return 0;
}
@@ -2540,7 +2573,6 @@ wl_iw_set_encodeext(
wl_wsec_key_t key;
int error;
struct iw_encode_ext *iwe;
- struct dhd_pub *dhd = dhd_get_pub(dev);
WL_TRACE(("%s: SIOCSIWENCODEEXT\n", dev->name));
@@ -2666,8 +2698,7 @@ wl_iw_set_encodeext(
error = dev_wlc_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
if (error)
return error;
- if (dhd && dhd->conf)
- dhd->conf->eapol_status = EAPOL_STATUS_WPA_END;
+ wl_iw_update_connect_status(dev, WL_EXT_STATUS_ADD_KEY);
}
return 0;
}
@@ -3458,11 +3489,20 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
uint32 datalen = ntoh32(e->datalen);
uint32 status = ntoh32(e->status);
uint32 reason = ntoh32(e->reason);
-#ifndef WL_ESCAN
struct dhd_pub *dhd = dhd_get_pub(dev);
+ wl_conn_info_t *conn_info = NULL;
+#ifdef WL_ESCAN
+ wl_escan_info_t *escan;
+ if (dhd && dhd->escan) {
+ escan = (wl_escan_info_t *)dhd->escan;
+ conn_info = &escan->conn_info;
+ }
+#else
iscan_info_t *iscan;
- if (dhd && dhd->iscan)
+ if (dhd && dhd->iscan) {
iscan = (iscan_info_t *)dhd->iscan;
+ conn_info = &iscan->conn_info;
+ }
#endif
memset(&wrqu, 0, sizeof(wrqu));
@@ -3481,13 +3521,21 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
case WLC_E_REASSOC_IND:
cmd = IWEVREGISTERED;
break;
+ case WLC_E_DEAUTH:
+ case WLC_E_DISASSOC:
+ wl_iw_update_connect_status(dev, WL_EXT_STATUS_DISCONNECTED);
+ printf("%s: disconnected with "MACSTR", event %d, reason %d\n",
+ __FUNCTION__, MAC2STR((u8 *)wrqu.addr.sa_data), event_type, reason);
+ break;
case WLC_E_DEAUTH_IND:
case WLC_E_DISASSOC_IND:
cmd = SIOCGIWAP;
wrqu.data.length = strlen(extra);
bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
bzero(&extra, ETHER_ADDR_LEN);
- wl_iw_check_handshake(dev, FALSE);
+ wl_iw_update_connect_status(dev, WL_EXT_STATUS_DISCONNECTED);
+ printf("%s: disconnected with "MACSTR", event %d, reason %d\n",
+ __FUNCTION__, MAC2STR((u8 *)wrqu.addr.sa_data), event_type, reason);
break;
case WLC_E_LINK:
@@ -3497,7 +3545,7 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
MAC2STR((u8 *)wrqu.addr.sa_data), reason);
bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
bzero(&extra, ETHER_ADDR_LEN);
- wl_iw_check_handshake(dev, FALSE);
+ wl_iw_update_connect_status(dev, WL_EXT_STATUS_DISCONNECTED);
} else {
printf("%s: Link UP with "MACSTR"\n", __FUNCTION__,
MAC2STR((u8 *)wrqu.addr.sa_data));
@@ -4035,6 +4083,14 @@ _iscan_sysioc_thread(void *data)
complete_and_exit(&iscan->sysioc_exited, 0);
}
+void wl_iw_down(dhd_pub_t *dhdp)
+{
+ iscan_info_t *iscan = dhdp->iscan;
+
+ if (iscan)
+ wl_ext_add_remove_pm_enable_work(&iscan->conn_info, FALSE);
+}
+
int
wl_iw_attach(struct net_device *dev, dhd_pub_t *dhdp)
{
@@ -4056,6 +4112,8 @@ wl_iw_attach(struct net_device *dev, dhd_pub_t *dhdp)
iscan->sysioc_pid = -1;
/* we only care about main interface so save a global here */
iscan->dev = dev;
+ iscan->conn_info.dev = dev;
+ iscan->conn_info.dhd = dhdp;
iscan->iscan_state = ISCAN_STATE_IDLE;
/* Set up the timer */
@@ -4078,6 +4136,8 @@ wl_iw_attach(struct net_device *dev, dhd_pub_t *dhdp)
#endif
if (iscan->sysioc_pid < 0)
return -ENOMEM;
+ mutex_init(&iscan->conn_info.pm_sync);
+ INIT_DELAYED_WORK(&iscan->conn_info.pm_enable_work, wl_ext_pm_work_handler);
return 0;
}
@@ -4091,6 +4151,7 @@ void wl_iw_detach(dhd_pub_t *dhdp)
KILL_PROC(iscan->sysioc_pid, SIGTERM);
wait_for_completion(&iscan->sysioc_exited);
}
+ wl_ext_add_remove_pm_enable_work(&iscan->conn_info, FALSE);
while (iscan->list_hdr) {
buf = iscan->list_hdr->next;
diff --git a/bcmdhd.100.10.315.x/wl_iw.h b/bcmdhd.100.10.315.x/wl_iw.h
index 0adba1b..b00a489 100644
--- a/bcmdhd.100.10.315.x/wl_iw.h
+++ b/bcmdhd.100.10.315.x/wl_iw.h
@@ -132,6 +132,7 @@ int wl_iw_handle_scanresults_ies(char **event_p, char *end,
#else
int wl_iw_attach(struct net_device *dev, dhd_pub_t *dhdp);
void wl_iw_detach(dhd_pub_t *dhdp);
+void wl_iw_down(dhd_pub_t *dhdp);
#endif
#define CSCAN_COMMAND "CSCAN "
diff --git a/bcmdhd.100.10.315.x/wldev_common.c b/bcmdhd.100.10.315.x/wldev_common.c
index ac72f96..398c54a 100644
--- a/bcmdhd.100.10.315.x/wldev_common.c
+++ b/bcmdhd.100.10.315.x/wldev_common.c
@@ -471,7 +471,6 @@ int wldev_set_country(
int error = -1;
wl_country_t cspec = {{0}, 0, {0}};
scb_val_t scbval;
- char smbuf[WLC_IOCTL_SMLEN];
#ifdef WL_CFG80211
struct wireless_dev *wdev = ndev_to_wdev(dev);
struct wiphy *wiphy = wdev->wiphy;
@@ -518,8 +517,7 @@ int wldev_set_country(
error = dhd_conf_map_country_list(dhd_get_pub(dev), &cspec);
if (error)
dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec);
- error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
- smbuf, sizeof(smbuf), NULL);
+ error = dhd_conf_set_country(dhd_get_pub(dev), &cspec);
if (error < 0) {
WLDEV_ERROR(("%s: set country for %s as %s rev %d failed\n",
__FUNCTION__, country_code, cspec.ccode, cspec.rev));