net: wireless: bcm4329: Add wakelock processing in ioctl and messaging
authorDmitry Shmidt <dimitrysh@google.com>
Thu, 22 Jul 2010 01:49:49 +0000 (18:49 -0700)
committerColin Cross <ccross@android.com>
Thu, 30 Sep 2010 00:49:41 +0000 (17:49 -0700)
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcm4329/dhd_linux.c
drivers/net/wireless/bcm4329/wl_iw.c

index 48c2ef777b136d155bff4ccbafc97e4ee0d5580b..00f545045cdcdefa33d9c0bbc0b711f25ca65d26 100644 (file)
@@ -1082,6 +1082,8 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
 
        DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
+       dhd_os_wake_lock(&dhd->pub);
+
        /* Reject if down */
        if (!dhd->pub.up || (dhd->pub.busstate == DHD_BUS_DOWN)) {
                DHD_ERROR(("%s: xmit rejected pub.up=%d busstate=%d\n",
@@ -1092,6 +1094,7 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
                        DHD_ERROR(("%s: Event HANG send up\n", __FUNCTION__));
                        wl_iw_send_priv_event(net, "HANG");
                }
+               dhd_os_wake_unlock(&dhd->pub);
                return -ENODEV;
        }
 
@@ -1099,6 +1102,7 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
        if (ifidx == DHD_BAD_IF) {
                DHD_ERROR(("%s: bad ifidx %d\n", __FUNCTION__, ifidx));
                netif_stop_queue(net);
+               dhd_os_wake_unlock(&dhd->pub);
                return -ENODEV;
        }
 
@@ -1130,13 +1134,14 @@ dhd_start_xmit(struct sk_buff *skb, struct net_device *net)
 
        ret = dhd_sendpkt(&dhd->pub, ifidx, pktbuf);
 
-
 done:
        if (ret)
                dhd->pub.dstats.tx_dropped++;
        else
                dhd->pub.tx_packets++;
 
+       dhd_os_wake_unlock(&dhd->pub);
+
        /* Return ok: we always eat the packet */
        return 0;
 }
@@ -1666,28 +1671,40 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
        uint driver = 0;
        int ifidx;
        bool is_set_key_cmd;
+       int ret;
+
+       dhd_os_wake_lock(&dhd->pub);
 
        ifidx = dhd_net2idx(dhd, net);
        DHD_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __FUNCTION__, ifidx, cmd));
 
-       if (ifidx == DHD_BAD_IF)
+       if (ifidx == DHD_BAD_IF) {
+               dhd_os_wake_unlock(&dhd->pub);
                return -1;
+       }
 
 #if defined(CONFIG_WIRELESS_EXT)
        /* linux wireless extensions */
        if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) {
                /* may recurse, do NOT lock */
-               return wl_iw_ioctl(net, ifr, cmd);
+               ret = wl_iw_ioctl(net, ifr, cmd);
+               dhd_os_wake_unlock(&dhd->pub);
+               return ret;
        }
 #endif /* defined(CONFIG_WIRELESS_EXT) */
 
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2)
-       if (cmd == SIOCETHTOOL)
-               return (dhd_ethtool(dhd, (void*)ifr->ifr_data));
+       if (cmd == SIOCETHTOOL) {
+               ret = dhd_ethtool(dhd, (void*)ifr->ifr_data);
+               dhd_os_wake_unlock(&dhd->pub);
+               return ret;
+       }
 #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 2) */
 
-       if (cmd != SIOCDEVPRIVATE)
+       if (cmd != SIOCDEVPRIVATE) {
+               dhd_os_wake_unlock(&dhd->pub);
                return -EOPNOTSUPP;
+       }
 
        memset(&ioc, 0, sizeof(ioc));
 
@@ -1779,6 +1796,8 @@ done:
        if (buf)
                MFREE(dhd->pub.osh, buf, buflen);
 
+       dhd_os_wake_unlock(&dhd->pub);
+
        return OSL_ERROR(bcmerror);
 }
 
index 98133bbf4b6ad4354d318a7776f94d130372423b..03385bb5f56bb6c23a6066fd5272b504644ee6f4 100644 (file)
@@ -308,6 +308,8 @@ dev_wlc_ioctl(
                return ret;
        }
 
+       net_os_wake_lock(dev);
+
        WL_TRACE(("%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, len:%d ,\n",
                __FUNCTION__, current->pid, cmd, arg, len));
 
@@ -323,6 +325,7 @@ dev_wlc_ioctl(
                ret = dev_open(dev);
                if (ret) {
                        WL_ERROR(("%s: Error dev_open: %d\n", __func__, ret));
+                       net_os_wake_unlock(dev);
                        return ret;
                }
 
@@ -338,6 +341,9 @@ dev_wlc_ioctl(
        else {
                WL_TRACE(("%s: call after driver stop\n", __FUNCTION__));
        }
+
+       net_os_wake_unlock(dev);
+
        return ret;
 }
 
@@ -941,6 +947,7 @@ wl_iw_send_priv_event(
        strcpy(extra, flag);
        wrqu.data.length = strlen(extra);
        wireless_send_event(dev, cmd, &wrqu, extra);
+       net_os_wake_lock_timeout_enable(dev);
        WL_TRACE(("Send IWEVCUSTOM Event as %s\n", extra));
 
        return 0;
@@ -1031,8 +1038,6 @@ wl_iw_control_wl_off(
                dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
 
                wl_iw_send_priv_event(dev, "STOP");
-
-               net_os_wake_lock_timeout_enable(dev);
        }
 
        mutex_unlock(&wl_start_lock);
@@ -1064,8 +1069,6 @@ wl_iw_control_wl_on(
        wl_iw_iscan_set_scan_broadcast_prep(dev, 0);
 #endif
 
-       net_os_wake_lock_timeout_enable(dev);
-
        WL_TRACE(("Exited %s \n", __FUNCTION__));
 
        return ret;
@@ -2264,13 +2267,15 @@ _iscan_sysioc_thread(void *data)
        status = WL_SCAN_RESULTS_PARTIAL;
        while (down_interruptible(&iscan->sysioc_sem) == 0) {
 
+               net_os_wake_lock(iscan->dev);
+
 #if defined(SOFTAP)
                if (ap_cfg_running) {
                        WL_TRACE(("%s skipping SCAN ops in AP mode !!!\n", __FUNCTION__));
+                       net_os_wake_unlock(iscan->dev);
                        continue;
                }
 #endif
-               net_os_wake_lock(iscan->dev);
 
                if (iscan->timer_on) {
                        iscan->timer_on = 0;
@@ -5134,7 +5139,7 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
                return -1;
        }
 
-    net_os_wake_lock(dev);
+       net_os_wake_lock(dev);
 
        WL_SOFTAP(("wl_iw: set ap profile:\n"));
        WL_SOFTAP(("    ssid = '%s'\n", ap->ssid));
@@ -5269,9 +5274,9 @@ static int set_ap_cfg(struct net_device *dev, struct ap_profile *ap)
 fail:
        WL_SOFTAP(("%s exit with %d\n", __FUNCTION__, res));
 
-    net_os_wake_unlock(dev);
+       net_os_wake_unlock(dev);
 
-    return res;
+       return res;
 }
 
 
@@ -5555,10 +5560,10 @@ static int iwpriv_softap_stop(struct net_device *dev,
                return res;
        }
 
-    net_os_wake_lock(dev);
+       net_os_wake_lock(dev);
 
        if ((ap_cfg_running == TRUE)) {
-        wl_iw_softap_deassoc_stations(ap_net_dev);
+               wl_iw_softap_deassoc_stations(ap_net_dev);
 
                if ((res = dev_iw_write_cfg1_bss_var(dev, 2)) < 0)
                        WL_ERROR(("%s failed to del BSS err = %d", __FUNCTION__, res));
@@ -5573,9 +5578,9 @@ static int iwpriv_softap_stop(struct net_device *dev,
 
        WL_SOFTAP(("%s Done with %d\n", __FUNCTION__, res));
 
-    net_os_wake_unlock(dev);
+       net_os_wake_unlock(dev);
 
-    return res;
+       return res;
 }
 
 
@@ -5685,7 +5690,7 @@ iwpriv_en_ap_bss(
                return -1;
        }
 
-    net_os_wake_lock(dev);
+       net_os_wake_lock(dev);
 
        WL_TRACE(("%s: rcvd IWPRIV IOCTL:  for dev:%s\n", __FUNCTION__, dev->name));
 
@@ -5701,7 +5706,7 @@ iwpriv_en_ap_bss(
 
        WL_SOFTAP(("%s done with res %d \n", __FUNCTION__, res));
 
-    net_os_wake_unlock(dev);
+       net_os_wake_unlock(dev);
 
        return res;
 }
@@ -6210,11 +6215,14 @@ int wl_iw_ioctl(
        char *extra = NULL;
        int token_size = 1, max_tokens = 0, ret = 0;
 
+       net_os_wake_lock(dev);
+
        WL_TRACE(("%s: cmd:%x alled via dhd->do_ioctl()entry point\n", __FUNCTION__, cmd));
        if (cmd < SIOCIWFIRST ||
                IW_IOCTL_IDX(cmd) >= ARRAYSIZE(wl_iw_handler) ||
                !(handler = wl_iw_handler[IW_IOCTL_IDX(cmd)])) {
                        WL_ERROR(("%s: error in cmd=%x : not supported\n", __FUNCTION__, cmd));
+                       net_os_wake_unlock(dev);
                        return -EOPNOTSUPP;
        }
 
@@ -6279,14 +6287,18 @@ int wl_iw_ioctl(
                if (wrq->u.data.length > max_tokens) {
                        WL_ERROR(("%s: error in cmd=%x wrq->u.data.length=%d  > max_tokens=%d\n", \
                                __FUNCTION__, cmd, wrq->u.data.length, max_tokens));
-                       return -E2BIG;
+                       ret = -E2BIG;
+                       goto wl_iw_ioctl_done;
+               }
+               if (!(extra = kmalloc(max_tokens * token_size, GFP_KERNEL))) {
+                       ret = -ENOMEM;
+                       goto wl_iw_ioctl_done;
                }
-               if (!(extra = kmalloc(max_tokens * token_size, GFP_KERNEL)))
-                       return -ENOMEM;
 
                if (copy_from_user(extra, wrq->u.data.pointer, wrq->u.data.length * token_size)) {
                        kfree(extra);
-                       return -EFAULT;
+                       ret = -EFAULT;
+                       goto wl_iw_ioctl_done;
                }
        }
 
@@ -6298,12 +6310,17 @@ int wl_iw_ioctl(
        if (extra) {
                if (copy_to_user(wrq->u.data.pointer, extra, wrq->u.data.length * token_size)) {
                        kfree(extra);
-                       return -EFAULT;
+                       ret = -EFAULT;
+                       goto wl_iw_ioctl_done;
                }
 
                kfree(extra);
        }
 
+wl_iw_ioctl_done:
+
+       net_os_wake_unlock(dev);
+
        return ret;
 }
 
@@ -6429,7 +6446,7 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
                return;
        }
 
-    net_os_wake_lock(dev);
+       net_os_wake_lock(dev);
 
        WL_TRACE(("%s: dev=%s event=%d \n", __FUNCTION__, dev->name, event_type));
 
@@ -6516,7 +6533,6 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
 
                        bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN);
                        bzero(&extra, ETHER_ADDR_LEN);
-            net_os_wake_lock_timeout_enable(dev);
                }
                else {
                        memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN);
@@ -6535,6 +6551,7 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
                        WL_TRACE(("Link UP\n"));
 
                }
+               net_os_wake_lock_timeout_enable(dev);
                wrqu.addr.sa_family = ARPHRD_ETHER;
                break;
        case WLC_E_ACTION_FRAME:
@@ -6652,8 +6669,8 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
        }
 #endif
 wl_iw_event_end:
-    net_os_wake_unlock(dev);
-#endif 
+       net_os_wake_unlock(dev);
+#endif
 }
 
 int wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats)
@@ -6821,7 +6838,7 @@ _bt_dhcp_sysioc_thread(void *data)
                                g_bt->bt_state = BT_DHCP_IDLE;
                                g_bt->timer_on = 0;
                                break;
-                }
+               }
 
                net_os_wake_unlock(g_bt->dev);
        }