From b7dbfeaa6e0080f59b2ce20e27cc1fba5984564e Mon Sep 17 00:00:00 2001 From: "peter.lin" Date: Mon, 23 Dec 2013 17:41:56 +0800 Subject: [PATCH] PD #84934: check null pointer for suspend, add wakelock for cfg80211 cmd --- broadcm_40181/dhd_config.c | 16 +++++++++++----- broadcm_40181/dhd_linux.c | 4 +++- broadcm_40181/wl_cfg80211.c | 21 ++++++++++++++++++++- broadcm_40181/wl_cfg80211.h | 7 +++++++ 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/broadcm_40181/dhd_config.c b/broadcm_40181/dhd_config.c index 7448476..56a3744 100755 --- a/broadcm_40181/dhd_config.c +++ b/broadcm_40181/dhd_config.c @@ -689,20 +689,26 @@ bool wifi_ready = true; void dhd_conf_wifi_power(bool on) { + extern struct wl_priv *wlcfg_drv_priv; printk("%s: Enter %d\n", __FUNCTION__, on); if (on) { wl_cfg80211_user_sync(true); wl_android_wifi_on(g_netdev); wl_cfg80211_send_disconnect(); - wl_cfgp2p_start_p2p_device(NULL, NULL); + if (wlcfg_drv_priv && wlcfg_drv_priv->p2p) + wl_cfgp2p_start_p2p_device(NULL, NULL); + else + printk("======= ON : no p2p ======\n"); wl_cfg80211_user_sync(false); wifi_ready = true; } else { - extern struct wl_priv *wlcfg_drv_priv; wifi_ready = false; - wl_cfgp2p_clear_management_ie(wlcfg_drv_priv, 0); - wl_cfgp2p_clear_management_ie(wlcfg_drv_priv, 1); - wl_cfgp2p_stop_p2p_device(NULL, wlcfg_drv_priv->p2p_wdev); + if (wlcfg_drv_priv && wlcfg_drv_priv->p2p) { + wl_cfgp2p_clear_management_ie(wlcfg_drv_priv, 0); + wl_cfgp2p_clear_management_ie(wlcfg_drv_priv, 1); + wl_cfgp2p_stop_p2p_device(NULL, wlcfg_drv_priv->p2p_wdev); + } else + printk("======= OFF : no p2p ======\n"); dhd_conf_wifi_stop(g_netdev); } printk("%s: Exit %d\n", __FUNCTION__, on); diff --git a/broadcm_40181/dhd_linux.c b/broadcm_40181/dhd_linux.c index 244cfc6..8550a20 100755 --- a/broadcm_40181/dhd_linux.c +++ b/broadcm_40181/dhd_linux.c @@ -2857,7 +2857,7 @@ dhd_stop(struct net_device *net) int ifidx = 0; dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net); DHD_OS_WAKE_LOCK(&dhd->pub); - DHD_TRACE(("%s: Enter %p\n", __FUNCTION__, net)); + DHD_ERROR(("%s: Enter %p\n", __FUNCTION__, net)); if (dhd->pub.up == 0) { goto exit; @@ -2919,6 +2919,8 @@ dhd_open(struct net_device *net) int ifidx; int32 ret = 0; + DHD_ERROR(("%s: Enter %p\n", __FUNCTION__, net)); + #if defined(MULTIPLE_SUPPLICANT) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1 && 1 if (mutex_is_locked(&_dhd_sdio_mutex_lock_) != 0) { diff --git a/broadcm_40181/wl_cfg80211.c b/broadcm_40181/wl_cfg80211.c index f22ddb0..4cd2e11 100755 --- a/broadcm_40181/wl_cfg80211.c +++ b/broadcm_40181/wl_cfg80211.c @@ -602,6 +602,14 @@ wl_sdo_proto_t wl_sdo_protos [] = { }; #endif +static void wl_wakelock_timeout(struct wl_priv *priv) +{ +#if defined(CONFIG_HAS_WAKELOCK) + wake_lock_timeout(&priv->priv_lock, msecs_to_jiffies(20)); +#endif +} + + #define RETURN_EIO_IF_NOT_UP(wlpriv) \ do { \ struct net_device *checkSysUpNDev = wl_to_prmry_ndev(wlpriv); \ @@ -609,6 +617,11 @@ do { \ WL_INFO(("device is not ready\n")); \ return -EIO; \ } \ + if (unlikely(!g_wifi_on)) { \ + WL_ERR(("g_wifi_on is not ready\n")); \ + return -EIO; \ + } \ + wl_wakelock_timeout(wlpriv); \ } while (0) @@ -9872,7 +9885,10 @@ static s32 wl_init_priv(struct wl_priv *wl) wl_init_prof(wl, ndev); wl_link_down(wl); DNGL_FUNC(dhd_cfg80211_init, (wl)); - +#ifdef CONFIG_HAS_WAKELOCK + wake_lock_init(&wl->priv_lock, WAKE_LOCK_SUSPEND, "wlan_priv_wake"); + printk("init wlan_priv_wake\n"); +#endif return err; } @@ -9886,6 +9902,9 @@ static void wl_deinit_priv(struct wl_priv *wl) wl_term_iscan(wl); wl_deinit_priv_mem(wl); unregister_netdevice_notifier(&wl_cfg80211_netdev_notifier); +#ifdef CONFIG_HAS_WAKELOCK + wake_lock_destroy(&wl->priv_lock); +#endif } #if defined(WL_ENABLE_P2P_IF) diff --git a/broadcm_40181/wl_cfg80211.h b/broadcm_40181/wl_cfg80211.h index 5189809..5c11b44 100755 --- a/broadcm_40181/wl_cfg80211.h +++ b/broadcm_40181/wl_cfg80211.h @@ -16,6 +16,9 @@ #include #include #include +#ifdef CONFIG_HAS_WAKELOCK +#include +#endif #include @@ -534,6 +537,10 @@ struct wl_priv { struct wl_scan_results *bss_list; struct wl_scan_results *scan_results; +#if defined(CONFIG_HAS_WAKELOCK) + struct wake_lock priv_lock; +#endif + /* scan request object for internal purpose */ struct wl_scan_req *scan_req_int; /* information element object for internal purpose */ -- 2.20.1