From 21fff75d2fb64455291c77813dba371e03a301a3 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Mon, 5 Nov 2012 16:22:16 -0800 Subject: brcmfmac: use wait_event_timeout for 8021x pending count brcmf_netdev_wait_pend8021x was polling to see if 8021x data was already sent. Code was replaced using wait_event_timeout. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Franky Lin Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 1 + .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 34 ++++++++++------------ 2 files changed, 17 insertions(+), 18 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 34bad32d2a74..8d4789ba0ff4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -621,6 +621,7 @@ struct brcmf_pub { struct work_struct multicast_work; u8 macvalue[ETH_ALEN]; atomic_t pend_8021x_cnt; + wait_queue_head_t pend_8021x_wait; #ifdef DEBUG struct dentry *dbgfs_dir; #endif diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 9e2451f8e9e1..0f81f31be018 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -52,6 +52,7 @@ MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver."); MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); MODULE_LICENSE("Dual BSD/GPL"); +#define MAX_WAIT_FOR_8021X_TX 50 /* msecs */ /* Error bits */ int brcmf_msg_level = BRCMF_ERROR_VAL; @@ -404,9 +405,11 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) eh = (struct ethhdr *)(txp->data); type = ntohs(eh->h_proto); - if (type == ETH_P_PAE) + if (type == ETH_P_PAE) { atomic_dec(&drvr->pend_8021x_cnt); - + if (waitqueue_active(&drvr->pend_8021x_wait)) + wake_up(&drvr->pend_8021x_wait); + } } static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) @@ -822,6 +825,8 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev) INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); + init_waitqueue_head(&drvr->pend_8021x_wait); + return ret; fail: @@ -924,26 +929,19 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr) return atomic_read(&drvr->pend_8021x_cnt); } -#define MAX_WAIT_FOR_8021X_TX 10 - int brcmf_netdev_wait_pend8021x(struct net_device *ndev) { struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_pub *drvr = ifp->drvr; - int timeout = 10 * HZ / 1000; - int ntimes = MAX_WAIT_FOR_8021X_TX; - int pend = brcmf_get_pend_8021x_cnt(drvr); - - while (ntimes && pend) { - if (pend) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(timeout); - set_current_state(TASK_RUNNING); - ntimes--; - } - pend = brcmf_get_pend_8021x_cnt(drvr); - } - return pend; + int err; + + err = wait_event_timeout(drvr->pend_8021x_wait, + !brcmf_get_pend_8021x_cnt(drvr), + msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX)); + + WARN_ON(!err); + + return !err; } static void brcmf_driver_init(struct work_struct *work) -- cgit v1.2.3