#include <dhd_rtt.h>
#endif // endif
+#ifdef CSI_SUPPORT
+#include <dhd_csi.h>
+#endif /* CSI_SUPPORT */
+
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
#endif // endif
DEFINE_MUTEX(_dhd_mutex_lock_);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
#endif
+static int dhd_suspend_resume_helper(struct dhd_info *dhd, int val, int force);
#ifdef CONFIG_BCM_DETECT_CONSECUTIVE_HANG
#define MAX_CONSECUTIVE_HANG_COUNTS 5
break;
}
-#if defined(SUPPORT_P2P_GO_PS) && defined(PROP_TXSTATUS)
+ printf("%s: action=%ld, suspend=%d, suspend_mode=%d\n",
+ __FUNCTION__, action, suspend, dhdinfo->pub.conf->suspend_mode);
if (suspend) {
DHD_OS_WAKE_LOCK_WAIVE(&dhdinfo->pub);
+ if (dhdinfo->pub.conf->suspend_mode == PM_NOTIFIER)
+ dhd_suspend_resume_helper(dhdinfo, suspend, 0);
+#if defined(SUPPORT_P2P_GO_PS) && defined(PROP_TXSTATUS)
dhd_wlfc_suspend(&dhdinfo->pub);
+#endif /* defined(SUPPORT_P2P_GO_PS) && defined(PROP_TXSTATUS) */
+ if (dhdinfo->pub.conf->suspend_mode == PM_NOTIFIER)
+ dhd_conf_set_suspend_resume(&dhdinfo->pub, suspend);
DHD_OS_WAKE_LOCK_RESTORE(&dhdinfo->pub);
} else {
+ if (dhdinfo->pub.conf->suspend_mode == PM_NOTIFIER)
+ dhd_conf_set_suspend_resume(&dhdinfo->pub, suspend);
+#if defined(SUPPORT_P2P_GO_PS) && defined(PROP_TXSTATUS)
dhd_wlfc_resume(&dhdinfo->pub);
- }
#endif /* defined(SUPPORT_P2P_GO_PS) && defined(PROP_TXSTATUS) */
+ if (dhdinfo->pub.conf->suspend_mode == PM_NOTIFIER)
+ dhd_suspend_resume_helper(dhdinfo, suspend, 0);
+ }
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \
+ KERNEL_VERSION(2, 6, 39))
dhd_mmc_suspend = suspend;
smp_mb();
+#endif
return ret;
}
static int dhd_set_suspend(int value, dhd_pub_t *dhd)
{
+#ifndef SUPPORT_PM2_ONLY
int power_mode = PM_MAX;
+#endif /* SUPPORT_PM2_ONLY */
/* wl_pkt_filter_enable_t enable_parm; */
int bcn_li_dtim = 0; /* Default bcn_li_dtim in resume mode is 0 */
int ret = 0;
int roam_time_thresh = 0; /* (ms) */
#endif /* CUSTOM_ROAM_TIME_THRESH_IN_SUSPEND */
#ifndef ENABLE_FW_ROAM_SUSPEND
- uint roamvar = dhd->conf->roam_off_suspend;
+ uint roamvar = 1;
#endif /* ENABLE_FW_ROAM_SUSPEND */
#ifdef ENABLE_BCN_LI_BCN_WAKEUP
int bcn_li_bcn = 1;
/* set specific cpucore */
dhd_set_cpucore(dhd, TRUE);
#endif /* CUSTOM_SET_CPUCORE */
-
- if (dhd->conf->pm >= 0)
- power_mode = dhd->conf->pm;
- else
- power_mode = PM_FAST;
-
if (dhd->up) {
if (value && dhd->in_suspend) {
#ifdef PKT_FILTER_SUPPORT
/* Kernel suspended */
DHD_ERROR(("%s: force extra Suspend setting\n", __FUNCTION__));
- if (dhd->conf->pm_in_suspend >= 0)
- power_mode = dhd->conf->pm_in_suspend;
+#ifndef SUPPORT_PM2_ONLY
dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode,
sizeof(power_mode), TRUE, 0);
+#endif /* SUPPORT_PM2_ONLY */
#ifdef PKT_FILTER_SUPPORT
/* Enable packet filter,
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 */
#if defined(WL_CFG80211) && defined(WL_BCNRECV)
ret = wl_android_bcnrecv_resume(dhd_linux_get_primary_netdev(dhd));
if (ret != BCME_OK) {
struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend);
DHD_TRACE_HW4(("%s: enter\n", __FUNCTION__));
- if (dhd)
+ if (dhd && dhd->pub.conf->suspend_mode == EARLY_SUSPEND) {
dhd_suspend_resume_helper(dhd, 1, 0);
+ dhd_conf_set_suspend_resume(&dhd->pub, 1);
+ }
}
static void dhd_late_resume(struct early_suspend *h)
struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend);
DHD_TRACE_HW4(("%s: enter\n", __FUNCTION__));
- if (dhd)
+ if (dhd && dhd->pub.conf->suspend_mode == EARLY_SUSPEND) {
+ dhd_conf_set_suspend_resume(&dhd->pub, 0);
dhd_suspend_resume_helper(dhd, 0, 0);
+ }
}
#endif /* CONFIG_HAS_EARLYSUSPEND && DHD_USE_EARLYSUSPEND */
bcm_object_trace_opr(skb, BCM_OBJDBG_ADD_PKT, __FUNCTION__, __LINE__);
+ skb_orphan(skb);
+
/* re-align socket buffer if "skb->data" is odd address */
if (((unsigned long)(skb->data)) & 0x1) {
unsigned char *data = skb->data;
netif_stop_queue(net);
dhd_prot_update_pktid_txq_stop_cnt(dhdp);
} else if (state == ON) {
- DHD_ERROR(("%s: Netif Queue has already stopped\n", __FUNCTION__));
+ DHD_INFO(("%s: Netif Queue has already stopped\n", __FUNCTION__));
}
if ((state == OFF) && (dhdp->txoff == TRUE)) {
netif_wake_queue(net);
dhd_prot_update_pktid_txq_start_cnt(dhdp);
} else if (state == OFF) {
- DHD_ERROR(("%s: Netif Queue has already started\n", __FUNCTION__));
+ DHD_INFO(("%s: Netif Queue has already started\n", __FUNCTION__));
}
}
* logtrace_pkt_sendup is true
*/
if (event_type == WLC_E_TRACE) {
- DHD_TRACE(("%s: WLC_E_TRACE\n", __FUNCTION__));
+ DHD_EVENT(("%s: WLC_E_TRACE\n", __FUNCTION__));
dhd_event_logtrace_enqueue(dhdp, ifidx, pktbuf);
continue;
}
continue;
}
- if (dhdp->wl_event_enabled) {
+#ifdef SENDPROB
+ if (dhdp->wl_event_enabled ||
+ (dhdp->recv_probereq && (event.event_type == WLC_E_PROBREQ_MSG)))
+#else
+ if (dhdp->wl_event_enabled)
+#endif
+ {
#ifdef DHD_USE_STATIC_CTRLBUF
/* If event bufs are allocated via static buf pool
* and wl events are enabled, make a copy, free the
/* Copy out any request driver name */
if (copy_from_user(&info, uaddr, sizeof(info)))
return -EFAULT;
- strncpy(drvname, info.driver, sizeof(info.driver));
- drvname[sizeof(info.driver)-1] = '\0';
+ strncpy(drvname, info.driver, sizeof(drvname) - 1);
+ drvname[sizeof(drvname) - 1] = '\0';
/* clear struct for return */
memset(&info, 0, sizeof(info));
}
}
+#ifndef CONFIG_VTS_SUPPORT
if (!capable(CAP_NET_ADMIN)) {
bcmerror = BCME_EPERM;
goto done;
}
+#endif
/* Take backup of ioc.buf and restore later */
ioc_buf_user = ioc.buf;
/* Allow transmit calls */
netif_start_queue(net);
DHD_ERROR(("[%s] tx queue started\n", net->name));
+
+#if defined(SET_RPS_CPUS)
+ dhd_rps_cpus_enable(net, TRUE);
+ DHD_ERROR(("[%s] RPS started\n", net->name));
+#endif
+
+#if defined(SET_XPS_CPUS)
+ dhd_xps_cpus_enable(net, TRUE);
+ DHD_ERROR(("[%s] XPS started\n", net->name));
+#endif
+
return ret;
}
#endif /* DHD_DEBUG */
#ifdef GET_CUSTOM_MAC_ENABLE
- wifi_platform_get_mac_addr(dhd->adapter, hw_ether);
+ wifi_platform_get_mac_addr(dhd->adapter, hw_ether, iface_name);
bcopy(hw_ether, dhd->pub.mac.octet, sizeof(struct ether_addr));
#endif /* GET_CUSTOM_MAC_ENABLE */
#ifdef CUSTOM_FORCE_NODFS_FLAG
len = strlen(if_name);
ch = if_name[len - 1];
if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2))
- strncat(if_name, "%d", 2);
+ strncat(if_name, "%d", IFNAMSIZ - len - 1);
}
/* Passing NULL to dngl_name to ensure host gets if_name in dngl_name member */
dhd->dhd_state = dhd_state;
dhd_found++;
+
+#ifdef CSI_SUPPORT
+ dhd_csi_init(&dhd->pub);
+#endif /* CSI_SUPPORT */
#ifdef DHD_DUMP_MNGR
dhd->pub.dump_file_manage =
#ifdef GET_CUSTOM_MAC_ENABLE
memset(hw_ether, 0, sizeof(hw_ether));
- ret = wifi_platform_get_mac_addr(dhd->info->adapter, hw_ether);
+ ret = wifi_platform_get_mac_addr(dhd->info->adapter, hw_ether, iface_name);
#ifdef GET_CUSTOM_MAC_FROM_CONFIG
if (!memcmp(ðer_null, &dhd->conf->hw_ether, ETHER_ADDR_LEN)) {
ret = 0;
#ifdef WL_ESCAN
setbit(eventmask, WLC_E_ESCAN_RESULT);
#endif /* WL_ESCAN */
+#ifdef CSI_SUPPORT
+ setbit(eventmask, WLC_E_CSI);
+#endif /* CSI_SUPPORT */
#ifdef RTT_SUPPORT
setbit(eventmask, WLC_E_PROXD);
#endif /* RTT_SUPPORT */
setbit(eventmask, WLC_E_TRACE);
#else
clrbit(eventmask, WLC_E_TRACE);
+ if (dhd->conf->chip == BCM43752_CHIP_ID)
+ setbit(eventmask, WLC_E_TRACE);
#endif /* defined(SHOW_LOGTRACE) && defined(LOGTRACE_FROM_FILE) */
setbit(eventmask, WLC_E_CSA_COMPLETE_IND);
#ifdef WL_MBO
setbit(eventmask_msg->mask, WLC_E_MBO);
#endif /* WL_MBO */
+#ifdef WL_CLIENT_SAE
+ setbit(eventmask_msg->mask, WLC_E_JOIN_START);
+#endif /* WL_CLIENT_SAE */
#ifdef WL_BCNRECV
setbit(eventmask_msg->mask, WLC_E_BCNRECV_ABORTED);
#endif /* WL_BCNRECV */
memset(buf, 0, sizeof(buf));
ret = dhd_iovar(dhd, 0, "clmver", NULL, 0, buf, sizeof(buf), FALSE);
if (ret < 0)
- DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret));
+ DHD_ERROR(("%s clmver failed %d\n", __FUNCTION__, ret));
else {
char *ver_temp_buf = NULL, *ver_date_buf = NULL;
int len;
/* query for 'wlc_ver' to get version info from firmware */
memset(&wlc_ver, 0, sizeof(wl_wlc_version_t));
- ret = dhd_iovar(dhd, 0, "wlc_ver", NULL, 0, (char *)&wlc_ver,
+ ret2 = dhd_iovar(dhd, 0, "wlc_ver", NULL, 0, (char *)&wlc_ver,
sizeof(wl_wlc_version_t), FALSE);
- if (ret < 0)
- DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret));
- else {
+ if (ret2 < 0) {
+ DHD_ERROR(("%s wlc_ver failed %d\n", __FUNCTION__, ret2));
+ if (ret2 != BCME_UNSUPPORTED)
+ ret = ret2;
+ } else {
dhd->wlc_ver_major = wlc_ver.wlc_ver_major;
dhd->wlc_ver_minor = wlc_ver.wlc_ver_minor;
}
if (ifidx == 0)
printf("%s\n", dhd_version);
else {
-#if defined(WL_EXT_IAPSTA) || defined(USE_IW) || defined(WL_ESCAN)
- wl_ext_event_attach_netdev(net, ifidx, ifp->bssidx);
-#ifdef WL_ESCAN
- wl_escan_event_attach(net, dhdp);
-#endif /* WL_ESCAN */
#ifdef WL_EXT_IAPSTA
- wl_ext_iapsta_attach_netdev(net, ifidx, ifp->bssidx);
+ wl_ext_iapsta_update_net_device(net, ifidx);
#endif /* WL_EXT_IAPSTA */
-#endif /* WL_EXT_IAPSTA || USE_IW || WL_ESCAN */
- }
- if (ifidx != 0) {
if (_dhd_set_mac_address(dhd, ifidx, net->dev_addr) == 0)
DHD_INFO(("%s: MACID is overwritten\n", __FUNCTION__));
else
DHD_ERROR(("couldn't register the net device [%s], err %d\n", net->name, err));
goto fail;
}
- if (ifidx == 0) {
#if defined(WL_EXT_IAPSTA) || defined(USE_IW) || defined(WL_ESCAN)
- wl_ext_event_attach_netdev(net, ifidx, ifp->bssidx);
+ wl_ext_event_attach_netdev(net, ifidx, ifp->bssidx);
#ifdef WL_ESCAN
- wl_escan_event_attach(net, dhdp);
+ wl_escan_event_attach(net, dhdp);
#endif /* WL_ESCAN */
#ifdef WL_EXT_IAPSTA
- wl_ext_iapsta_attach_netdev(net, ifidx, ifp->bssidx);
-#endif /* WL_EXT_IAPSTA */
-#endif /* WL_EXT_IAPSTA || USE_IW || WL_ESCAN */
- }
-#ifdef WL_EXT_IAPSTA
+ wl_ext_iapsta_attach_netdev(net, ifidx, ifp->bssidx);
wl_ext_iapsta_attach_name(net, ifidx);
#endif /* WL_EXT_IAPSTA */
+#endif /* WL_EXT_IAPSTA || USE_IW || WL_ESCAN */
printf("Register interface [%s] MAC: "MACDBG"\n\n", net->name,
MAC2STRDBG(net->dev_addr));
if (dev) {
rtnl_lock();
+#if defined(WL_CFG80211) && defined(WL_STATIC_IF)
+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) {
+ cfg = wl_get_cfg(dev);
+ if (cfg && cfg->static_ndev && (cfg->static_ndev->flags & IFF_UP)) {
+ dev_close(cfg->static_ndev);
+ }
+ }
+#endif /* WL_CFG80211 && WL_STATIC_IF */
if (dev->flags & IFF_UP) {
/* If IFF_UP is still up, it indicates that
* "ifconfig wlan0 down" hasn't been called.
MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
dhd->iflist[0] = NULL;
+#ifdef WL_CFG80211
+ if (cfg && cfg->wdev)
+ cfg->wdev->netdev = NULL;
+#endif
}
}
}
#endif /* DHD_LB */
+#ifdef CSI_SUPPORT
+ dhd_csi_deinit(dhdp);
+#endif /* CSI_SUPPORT */
+
#if defined(DNGL_AXI_ERROR_LOGGING) && defined(DHD_USE_WQ_FOR_DNGL_AXI_ERROR)
cancel_work_sync(&dhd->axi_error_dispatcher_work);
#endif /* DNGL_AXI_ERROR_LOGGING && DHD_USE_WQ_FOR_DNGL_AXI_ERROR */
return NULL;
}
+ if (!(dev->flags & IFF_UP)) {
+ return NULL;
+ }
+
res = wl_iw_get_wireless_stats(dev, &dhd->iw.wstats);
if (res == 0)
int ret = 0;
dhd_info_t *dhd = DHD_DEV_INFO(dev);
- if (dhd) {
+ if (dhd && dhd->pub.conf->suspend_mode == EARLY_SUSPEND) {
+ if (!val)
+ dhd_conf_set_suspend_resume(&dhd->pub, val);
#ifdef CONFIG_MACH_UNIVERSAL7420
#endif /* CONFIG_MACH_UNIVERSAL7420 */
#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
#ifdef WL_CFG80211
wl_cfg80211_update_power_mode(dev);
#endif // endif
+ if (val)
+ dhd_conf_set_suspend_resume(&dhd->pub, val);
}
return ret;
}
if (ntimes == 0)
{
atomic_set(&dhd->pend_8021x_cnt, 0);
- DHD_ERROR(("%s: TIMEOUT\n", __FUNCTION__));
+ WL_MSG(dev->name, "TIMEOUT\n");
}
return pend;
}
}
#endif /* DHD_L2_FILTER */
+#if defined(SET_XPS_CPUS)
+int dhd_xps_cpus_enable(struct net_device *net, int enable)
+{
+ dhd_info_t *dhd = DHD_DEV_INFO(net);
+ dhd_if_t *ifp;
+ int ifidx;
+ char * XPS_CPU_SETBUF;
+
+ ifidx = dhd_net2idx(dhd, net);
+ if (ifidx == DHD_BAD_IF) {
+ DHD_ERROR(("%s bad ifidx\n", __FUNCTION__));
+ return -ENODEV;
+ }
+
+ if (ifidx == PRIMARY_INF) {
+ if (dhd->pub.op_mode == DHD_FLAG_IBSS_MODE) {
+ DHD_INFO(("%s : set for IBSS.\n", __FUNCTION__));
+ XPS_CPU_SETBUF = RPS_CPUS_MASK_IBSS;
+ } else {
+ DHD_INFO(("%s : set for BSS.\n", __FUNCTION__));
+ XPS_CPU_SETBUF = RPS_CPUS_MASK;
+ }
+ } else if (ifidx == VIRTUAL_INF) {
+ DHD_INFO(("%s : set for P2P.\n", __FUNCTION__));
+ XPS_CPU_SETBUF = RPS_CPUS_MASK_P2P;
+ } else {
+ DHD_ERROR(("%s : Invalid index : %d.\n", __FUNCTION__, ifidx));
+ return -EINVAL;
+ }
+
+ ifp = dhd->iflist[ifidx];
+ if (ifp) {
+ if (enable) {
+ DHD_INFO(("%s : set xps_cpus as [%s]\n", __FUNCTION__, XPS_CPU_SETBUF));
+ custom_xps_map_set(ifp->net, XPS_CPU_SETBUF, strlen(XPS_CPU_SETBUF));
+ } else {
+ custom_xps_map_clear(ifp->net);
+ }
+ } else {
+ DHD_ERROR(("%s : ifp is NULL!!\n", __FUNCTION__));
+ return -ENODEV;
+ }
+ return BCME_OK;
+}
+
+int custom_xps_map_set(struct net_device *net, char *buf, size_t len)
+{
+ cpumask_var_t mask;
+ int err;
+
+ DHD_INFO(("%s : Entered.\n", __FUNCTION__));
+
+ if (!alloc_cpumask_var(&mask, GFP_KERNEL)) {
+ DHD_ERROR(("%s : alloc_cpumask_var fail.\n", __FUNCTION__));
+ return -ENOMEM;
+ }
+
+ err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits);
+ if (err) {
+ free_cpumask_var(mask);
+ DHD_ERROR(("%s : bitmap_parse fail.\n", __FUNCTION__));
+ return err;
+ }
+
+ err = netif_set_xps_queue(net, mask, 0);
+
+ free_cpumask_var(mask);
+
+ if (0 == err)
+ DHD_ERROR(("%s : Done. mapping cpu\n", __FUNCTION__));
+
+ return err;
+}
+
+void custom_xps_map_clear(struct net_device *net)
+{
+ struct xps_dev_maps *dev_maps;
+
+ DHD_INFO(("%s : Entered.\n", __FUNCTION__));
+
+ rcu_read_lock();
+ dev_maps = rcu_dereference(net->xps_maps);
+ rcu_read_unlock();
+
+ if (dev_maps) {
+ RCU_INIT_POINTER(net->xps_maps, NULL);
+ kfree_rcu(dev_maps, rcu);
+ DHD_INFO(("%s : xps_cpus map clear.\n", __FUNCTION__));
+ }
+}
+#endif // endif
+
#if defined(SET_RPS_CPUS)
int dhd_rps_cpus_enable(struct net_device *net, int enable)
{
}
free_cpumask_var(mask);
- DHD_INFO(("%s : Done. mapping cpu nummber : %d\n", __FUNCTION__, map->len));
+ DHD_ERROR(("%s : Done. mapping cpu nummber : %d\n", __FUNCTION__, map->len));
return map->len;
}