conf->txglom_ext = FALSE;\r
conf->tx_max_offset = 0;\r
conf->txglomsize = SDPCM_DEFGLOM_SIZE;\r
- conf->txctl_tmo_fix = -1;\r
+ conf->txctl_tmo_fix = 300;\r
conf->txglom_mode = SDPCM_TXGLOM_CPY;\r
conf->deferred_tx_len = 0;\r
conf->dhd_txminmax = 1;\r
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();
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.
*/
}
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
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;
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
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;
#define htodchanspec(i) i\r
#define dtohchanspec(i) i\r
\r
+#define MAX_EVENT_BUF_NUM 16\r
+typedef struct eventmsg_buf {\r
+ u16 num;\r
+ struct {\r
+ u16 type;\r
+ bool set;\r
+ } event [MAX_EVENT_BUF_NUM];\r
+} eventmsg_buf_t;\r
+\r
typedef struct cihp_name_map_t {\r
uint chip;\r
uint chiprev;\r
memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));\r
\r
printf("%s: set country %s, revision %d\n", __FUNCTION__, cspec->ccode, cspec->rev);\r
- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)cspec, sizeof(wl_country_t), FALSE);\r
+ bcmerror = dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "country", (char *)cspec,\r
+ sizeof(wl_country_t), FALSE);\r
dhd_conf_get_country(dhd, cspec);\r
printf("Country code: %s (%s/%d)\n", cspec->country_abbrev, cspec->ccode, cspec->rev);\r
\r
return bcmerror;\r
}\r
\r
+void\r
+dhd_conf_add_to_eventbuffer(struct eventmsg_buf *ev, u16 event, bool set)\r
+{\r
+ if (!ev || (event > WLC_E_LAST))\r
+ return;\r
+\r
+ if (ev->num < MAX_EVENT_BUF_NUM) {\r
+ ev->event[ev->num].type = event;\r
+ ev->event[ev->num].set = set;\r
+ ev->num++;\r
+ } else {\r
+ CONFIG_ERROR(("evenbuffer doesn't support > %u events. Update"\r
+ " the define MAX_EVENT_BUF_NUM \n", MAX_EVENT_BUF_NUM));\r
+ ASSERT(0);\r
+ }\r
+}\r
+\r
+s32\r
+dhd_conf_apply_eventbuffer(dhd_pub_t *dhd, eventmsg_buf_t *ev)\r
+{\r
+ char eventmask[WL_EVENTING_MASK_LEN];\r
+ int i, ret = 0;\r
+\r
+ if (!ev || (!ev->num))\r
+ return -EINVAL;\r
+\r
+ /* Read event_msgs mask */\r
+ ret = dhd_conf_get_iovar(dhd, WLC_GET_VAR, "event_msgs", eventmask, sizeof(eventmask), 0);\r
+ if (unlikely(ret)) {\r
+ CONFIG_ERROR(("Get event_msgs error (%d)\n", ret));\r
+ goto exit;\r
+ }\r
+\r
+ /* apply the set bits */\r
+ for (i = 0; i < ev->num; i++) {\r
+ if (ev->event[i].set)\r
+ setbit(eventmask, ev->event[i].type);\r
+ else\r
+ clrbit(eventmask, ev->event[i].type);\r
+ }\r
+\r
+ /* Write updated Event mask */\r
+ ret = dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask,\r
+ sizeof(eventmask), FALSE);\r
+ if (unlikely(ret)) {\r
+ CONFIG_ERROR(("Set event_msgs error (%d)\n", ret));\r
+ }\r
+\r
+exit:\r
+ return ret;\r
+}\r
+\r
+int\r
+dhd_conf_enable_roam_offload(dhd_pub_t *dhd, int enable)\r
+{\r
+ int err;\r
+ eventmsg_buf_t ev_buf;\r
+\r
+ if (dhd->conf->roam_off_suspend)\r
+ return 0;\r
+\r
+ err = dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "roam_offload", enable, 0, FALSE);\r
+ if (err)\r
+ return err;\r
+\r
+ bzero(&ev_buf, sizeof(eventmsg_buf_t));\r
+ dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_PSK_SUP, !enable);\r
+ dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_ASSOC_REQ_IE, !enable);\r
+ dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_ASSOC_RESP_IE, !enable);\r
+ dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_REASSOC, !enable);\r
+ dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_JOIN, !enable);\r
+ dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_ROAM, !enable);\r
+ err = dhd_conf_apply_eventbuffer(dhd, &ev_buf);\r
+\r
+ CONFIG_TRACE(("%s: roam_offload %d\n", __FUNCTION__, enable));\r
+\r
+ return err;\r
+}\r
+\r
void\r
dhd_conf_set_bw_cap(dhd_pub_t *dhd)\r
{\r
return -1;\r
}\r
\r
-#define AP_IN_SUSPEND 1\r
-#define AP_DOWN_IN_SUSPEND 2\r
-int\r
-dhd_conf_get_ap_mode_in_suspend(dhd_pub_t *dhd)\r
+uint\r
+dhd_conf_get_insuspend(dhd_pub_t *dhd)\r
{\r
- int mode = 0;\r
+ uint mode = 0;\r
\r
- /* returned ap_in_suspend value:\r
- * 0: nothing\r
- * 1: ap enabled in suspend\r
- * 2: ap enabled, but down in suspend\r
- */\r
- if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {\r
- mode = dhd->conf->ap_in_suspend;\r
+ if (dhd->op_mode & DHD_FLAG_STA_MODE) {\r
+ mode = dhd->conf->insuspend &\r
+ (NO_EVENT_IN_SUSPEND | NO_TXDATA_IN_SUSPEND | ROAM_OFFLOAD_IN_SUSPEND);\r
+ } else if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {\r
+ mode = dhd->conf->insuspend &\r
+ (NO_EVENT_IN_SUSPEND | NO_TXDATA_IN_SUSPEND | AP_DOWN_IN_SUSPEND);\r
}\r
\r
return mode;\r
}\r
\r
int\r
-dhd_conf_set_ap_in_suspend(dhd_pub_t *dhd, int suspend)\r
+dhd_conf_set_suspend_resume(dhd_pub_t *dhd, int suspend)\r
{\r
- int mode = 0;\r
- uint wl_down = 1;\r
+ uint mode = 0, wl_down = 1;\r
+ struct dhd_conf *conf = dhd->conf;\r
\r
- mode = dhd_conf_get_ap_mode_in_suspend(dhd);\r
+ mode = dhd_conf_get_insuspend(dhd);\r
if (mode)\r
- printf("%s: suspend %d, mode %d\n", __FUNCTION__, suspend, mode);\r
+ printf("%s: op_mode %d, suspend %d, mode 0x%x\n", __FUNCTION__,\r
+ dhd->op_mode, suspend, mode);\r
+\r
if (suspend) {\r
- if (mode == AP_IN_SUSPEND) {\r
+ if (dhd->op_mode & DHD_FLAG_STA_MODE) {\r
+ if (mode & ROAM_OFFLOAD_IN_SUSPEND)\r
+ dhd_conf_enable_roam_offload(dhd, 1);\r
+ } else if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {\r
+ if (mode & AP_DOWN_IN_SUSPEND) {\r
+ dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_down,\r
+ sizeof(wl_down), TRUE, 0);\r
+ }\r
+ }\r
#ifdef SUSPEND_EVENT\r
- if (dhd->conf->suspend_eventmask_enable) {\r
- char *eventmask = dhd->conf->suspend_eventmask;\r
- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask, sizeof(eventmask), TRUE);\r
+ if (mode & NO_EVENT_IN_SUSPEND) {\r
+ char suspend_eventmask[WL_EVENTING_MASK_LEN];\r
+ if (!conf->suspended) {\r
+ dhd_conf_get_iovar(dhd, WLC_GET_VAR, "event_msgs",\r
+ conf->resume_eventmask, sizeof(conf->resume_eventmask), 0);\r
}\r
+ memset(suspend_eventmask, 0, sizeof(suspend_eventmask));\r
+ dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs",\r
+ suspend_eventmask, sizeof(suspend_eventmask), FALSE);\r
+ }\r
#endif\r
- } else if (mode == AP_DOWN_IN_SUSPEND)\r
- dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_down, sizeof(wl_down), TRUE, 0);\r
+ conf->suspended = TRUE;\r
} else {\r
- if (mode == AP_IN_SUSPEND) {\r
#ifdef SUSPEND_EVENT\r
- if (dhd->conf->suspend_eventmask_enable) {\r
- char *eventmask = dhd->conf->resume_eventmask;\r
- dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs", eventmask, sizeof(eventmask), TRUE);\r
+ if (mode & NO_EVENT_IN_SUSPEND) {\r
+ dhd_conf_set_bufiovar(dhd, WLC_SET_VAR, "event_msgs",\r
+ conf->resume_eventmask, sizeof(conf->resume_eventmask), FALSE);\r
+ if (dhd->op_mode & DHD_FLAG_STA_MODE) {\r
+ struct ether_addr bssid;\r
+ int ret = 0;\r
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID, &bssid,\r
+ sizeof(struct ether_addr), FALSE, 0);\r
+ if (ret != BCME_NOTASSOCIATED && !memcmp(ðer_null, &bssid, ETHER_ADDR_LEN)) {\r
+ CONFIG_TRACE(("%s: send disassoc\n", __FUNCTION__));\r
+ dhd_conf_set_intiovar(dhd, WLC_DISASSOC, "WLC_DISASSOC", 0, 0, FALSE);\r
+ }\r
}\r
+ }\r
#endif\r
- } else if (mode == AP_DOWN_IN_SUSPEND) {\r
- wl_down = 0;\r
- dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&wl_down, sizeof(wl_down), TRUE, 0);\r
+ if (dhd->op_mode & DHD_FLAG_STA_MODE) {\r
+ if (mode & ROAM_OFFLOAD_IN_SUSPEND)\r
+ dhd_conf_enable_roam_offload(dhd, 0);\r
+ } else if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {\r
+ if (mode & AP_DOWN_IN_SUSPEND) {\r
+ wl_down = 0;\r
+ dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&wl_down,\r
+ sizeof(wl_down), TRUE, 0);\r
+ }\r
}\r
+ conf->suspended = FALSE;\r
}\r
\r
- return mode;\r
+ return 0;\r
}\r
\r
#ifdef PROP_TXSTATUS\r
}\r
else if (!strncmp("xmit_in_suspend=", full_param, len_param)) {\r
if (!strncmp(data, "1", 1))\r
- conf->xmit_in_suspend = TRUE;\r
+ conf->insuspend &= ~NO_TXDATA_IN_SUSPEND;\r
else\r
- conf->xmit_in_suspend = FALSE;\r
- printf("%s: xmit_in_suspend = %d\n", __FUNCTION__, conf->xmit_in_suspend);\r
- }\r
- else if (!strncmp("ap_in_suspend=", full_param, len_param)) {\r
- conf->ap_in_suspend = (int)simple_strtol(data, NULL, 10);\r
- printf("%s: ap_in_suspend = %d\n", __FUNCTION__, conf->ap_in_suspend);\r
+ conf->insuspend |= NO_TXDATA_IN_SUSPEND;\r
+ printf("%s: insuspend = 0x%x\n", __FUNCTION__, conf->insuspend);\r
}\r
-#ifdef SUSPEND_EVENT\r
- else if (!strncmp("suspend_eventmask_enable=", full_param, len_param)) {\r
- if (!strncmp(data, "1", 1))\r
- conf->suspend_eventmask_enable = TRUE;\r
- else\r
- conf->suspend_eventmask_enable = FALSE;\r
- printf("%s: suspend_eventmask_enable = %d\n", __FUNCTION__, conf->suspend_eventmask_enable);\r
+ else if (!strncmp("insuspend=", full_param, len_param)) {\r
+ conf->insuspend = (int)simple_strtol(data, NULL, 0);\r
+ printf("%s: insuspend = 0x%x\n", __FUNCTION__, conf->insuspend);\r
}\r
-#endif\r
else\r
return false;\r
\r
dhd_conf_set_intiovar(dhd, WLC_SET_BAND, "WLC_SET_BAND", conf->band, 0, FALSE);\r
dhd_conf_set_intiovar(dhd, WLC_SET_VAR, "bcn_timeout", conf->bcn_timeout, 0, FALSE);\r
dhd_conf_set_intiovar(dhd, WLC_SET_PM, "PM", conf->pm, 0, FALSE);\r
- dhd_conf_set_intiovar(dhd, WLC_SET_SRL, "WLC_SET_SRL", conf->srl, 0, TRUE);\r
+ dhd_conf_set_intiovar(dhd, WLC_SET_SRL, "WLC_SET_SRL", conf->srl, 0, FALSE);\r
dhd_conf_set_intiovar(dhd, WLC_SET_LRL, "WLC_SET_LRL", conf->lrl, 0, FALSE);\r
dhd_conf_set_bw_cap(dhd);\r
dhd_conf_set_roam(dhd);\r
conf->pm = -1;\r
conf->pm_in_suspend = -1;\r
conf->suspend_bcn_li_dtim = -1;\r
- conf->xmit_in_suspend = TRUE;\r
- conf->ap_in_suspend = 0;\r
+ conf->insuspend = 0;\r
#ifdef SUSPEND_EVENT\r
- conf->suspend_eventmask_enable = FALSE;\r
- memset(&conf->suspend_eventmask, 0, sizeof(conf->suspend_eventmask));\r
memset(&conf->resume_eventmask, 0, sizeof(conf->resume_eventmask));\r
#endif\r
#ifdef IDHCP\r
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,
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
#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);
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,
}
#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
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) {
#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);
}
}
/* 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);
}
}
/* 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;
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)
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 {
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 */
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) {
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;
struct net_device *dev;
dhd = (dhd_info_t *)dhd_info;
+ if (!dhd || !dhd->iflist[0])
+ return;
dev = dhd->iflist[0]->net;
if (dev) {
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);
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,
if (dhdpcie_init (pdev)) {
DHD_ERROR(("%s: PCIe Enumeration failed\n", __FUNCTION__));
+ DHD_MUTEX_UNLOCK();
return -ENODEV;
}
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;
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)
#include <linux/err.h>\r
#include <linux/skbuff.h>\r
\r
-#define DHD_STATIC_VERSION_STR "100.10.315.1"\r
+#define DHD_STATIC_VERSION_STR "100.10.315.2"\r
\r
#define BCMDHD_SDIO\r
#define BCMDHD_PCIE\r
#define DHD_PREALLOC_OSL_BUF_SIZE (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)\r
#define DHD_PREALLOC_WIPHY_ESCAN0_SIZE (64 * 1024)\r
#define DHD_PREALLOC_DHD_INFO_SIZE (32 * 1024)\r
-#define DHD_PREALLOC_MEMDUMP_RAM_SIZE (810 * 1024)\r
+#define DHD_PREALLOC_MEMDUMP_RAM_SIZE (1290 * 1024)\r
#define DHD_PREALLOC_DHD_WLFC_HANGER_SIZE (73 * 1024)\r
#define DHD_PREALLOC_WL_ESCAN_INFO_SIZE (66 * 1024)\r
#ifdef CONFIG_64BIT\r
\r
if (wlan_static_wl_escan_info_buf)\r
kfree(wlan_static_wl_escan_info_buf);\r
- \r
+\r
#ifdef BCMDHD_PCIE\r
if (wlan_static_fw_verbose_ring_buf)\r
kfree(wlan_static_fw_verbose_ring_buf);\r
\r
if (wlan_static_wl_escan_info_buf)\r
kfree(wlan_static_wl_escan_info_buf);\r
- \r
+\r
#ifdef BCMDHD_PCIE\r
if (wlan_static_fw_verbose_ring_buf)\r
kfree(wlan_static_fw_verbose_ring_buf);\r
#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_ */
#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)
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
#endif /* BCM_BACKPLANE_TIMEOUT */
#ifdef USE_DMA_LOCK
spinlock_t dma_lock;
+ bool dma_lock_bh;
#endif /* USE_DMA_LOCK */
};
{
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]) {
#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) { \
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 {
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
#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
uint csa;
apstamode_t apstamode;
bool netif_change;
+ bool mesh_creating;
wait_queue_head_t netif_change_event;
} wl_apsta_params_t;
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__));
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;
}
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));
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) {
}
+#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)
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)
{
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);
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);
// 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);
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);
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
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++;
} 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);
}
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);
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);
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;
}
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;
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__));
}
}
}
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;
}
}
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);
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) {
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"));
}
}
} 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 ||
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
}
#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;
// 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;
}
#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;
}
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));
}
}
}
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));
}
}
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];
}
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];
}
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;
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);
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];
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;
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;
return bytes_written;
}
+#ifdef SENDPROB
static int
wl_ext_send_probresp(struct net_device *dev, char *data, char *command, int total_len)
{
}
#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);
#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},
};
/*
}
}
- 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]);
}
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
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) {
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,
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));
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;
+ }
}
/*
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) {
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)) {
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) {
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;
}
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;
}
} 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;
}
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);
#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)
#endif
if (wl_create_event_handler(escan)) {
+ ESCAN_ERROR(("device is not ready\n"));
err = -ENOMEM;
goto err;
}
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;
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__);
/* 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)) {
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:
\r
/* donlge escan state */\r
enum escan_state {\r
+ ESCAN_STATE_DOWN,\r
ESCAN_STATE_IDLE,\r
ESCAN_STATE_SCANING\r
};\r
struct net_device *dev;\r
dhd_pub_t *pub;\r
struct timer_list scan_timeout; /* Timer for catch scan event timeout */\r
- int escan_state;\r
+ int escan_state;\r
int ioctl_ver;\r
\r
char ioctlbuf[WLC_IOCTL_SMLEN];\r
s32 wl_escan_autochannel(struct net_device *dev, char* command, int total_len);\r
int wl_escan_attach(struct net_device *dev, dhd_pub_t *dhdp);\r
void wl_escan_detach(dhd_pub_t *dhdp);\r
+int wl_escan_up(struct net_device *net, dhd_pub_t *dhdp);\r
+void wl_escan_down(dhd_pub_t *dhdp);\r
\r
#endif /* _wl_escan_ */\r
\r
#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;
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));
#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:
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),
}
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;
}
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;
}
}
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 {
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;
}
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));
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;
}
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));
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:
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));
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)
{
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 */
#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;
}
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;
#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 "
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;
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));