diff options
author | Hante Meuleman <meuleman@broadcom.com> | 2012-11-05 19:22:16 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-11-14 14:55:47 -0500 |
commit | 21fff75d2fb64455291c77813dba371e03a301a3 (patch) | |
tree | a3e9b1aa468117fd462ed00bc5086135c7b009f8 | |
parent | 6b028c5ee249fa974c9730ebcf227b7351eab39d (diff) |
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 <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 34 |
2 files changed, 17 insertions, 18 deletions
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 { | |||
621 | struct work_struct multicast_work; | 621 | struct work_struct multicast_work; |
622 | u8 macvalue[ETH_ALEN]; | 622 | u8 macvalue[ETH_ALEN]; |
623 | atomic_t pend_8021x_cnt; | 623 | atomic_t pend_8021x_cnt; |
624 | wait_queue_head_t pend_8021x_wait; | ||
624 | #ifdef DEBUG | 625 | #ifdef DEBUG |
625 | struct dentry *dbgfs_dir; | 626 | struct dentry *dbgfs_dir; |
626 | #endif | 627 | #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."); | |||
52 | MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); | 52 | MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); |
53 | MODULE_LICENSE("Dual BSD/GPL"); | 53 | MODULE_LICENSE("Dual BSD/GPL"); |
54 | 54 | ||
55 | #define MAX_WAIT_FOR_8021X_TX 50 /* msecs */ | ||
55 | 56 | ||
56 | /* Error bits */ | 57 | /* Error bits */ |
57 | int brcmf_msg_level = BRCMF_ERROR_VAL; | 58 | int brcmf_msg_level = BRCMF_ERROR_VAL; |
@@ -404,9 +405,11 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) | |||
404 | eh = (struct ethhdr *)(txp->data); | 405 | eh = (struct ethhdr *)(txp->data); |
405 | type = ntohs(eh->h_proto); | 406 | type = ntohs(eh->h_proto); |
406 | 407 | ||
407 | if (type == ETH_P_PAE) | 408 | if (type == ETH_P_PAE) { |
408 | atomic_dec(&drvr->pend_8021x_cnt); | 409 | atomic_dec(&drvr->pend_8021x_cnt); |
409 | 410 | if (waitqueue_active(&drvr->pend_8021x_wait)) | |
411 | wake_up(&drvr->pend_8021x_wait); | ||
412 | } | ||
410 | } | 413 | } |
411 | 414 | ||
412 | static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) | 415 | 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) | |||
822 | 825 | ||
823 | INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); | 826 | INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); |
824 | 827 | ||
828 | init_waitqueue_head(&drvr->pend_8021x_wait); | ||
829 | |||
825 | return ret; | 830 | return ret; |
826 | 831 | ||
827 | fail: | 832 | fail: |
@@ -924,26 +929,19 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr) | |||
924 | return atomic_read(&drvr->pend_8021x_cnt); | 929 | return atomic_read(&drvr->pend_8021x_cnt); |
925 | } | 930 | } |
926 | 931 | ||
927 | #define MAX_WAIT_FOR_8021X_TX 10 | ||
928 | |||
929 | int brcmf_netdev_wait_pend8021x(struct net_device *ndev) | 932 | int brcmf_netdev_wait_pend8021x(struct net_device *ndev) |
930 | { | 933 | { |
931 | struct brcmf_if *ifp = netdev_priv(ndev); | 934 | struct brcmf_if *ifp = netdev_priv(ndev); |
932 | struct brcmf_pub *drvr = ifp->drvr; | 935 | struct brcmf_pub *drvr = ifp->drvr; |
933 | int timeout = 10 * HZ / 1000; | 936 | int err; |
934 | int ntimes = MAX_WAIT_FOR_8021X_TX; | 937 | |
935 | int pend = brcmf_get_pend_8021x_cnt(drvr); | 938 | err = wait_event_timeout(drvr->pend_8021x_wait, |
936 | 939 | !brcmf_get_pend_8021x_cnt(drvr), | |
937 | while (ntimes && pend) { | 940 | msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX)); |
938 | if (pend) { | 941 | |
939 | set_current_state(TASK_INTERRUPTIBLE); | 942 | WARN_ON(!err); |
940 | schedule_timeout(timeout); | 943 | |
941 | set_current_state(TASK_RUNNING); | 944 | return !err; |
942 | ntimes--; | ||
943 | } | ||
944 | pend = brcmf_get_pend_8021x_cnt(drvr); | ||
945 | } | ||
946 | return pend; | ||
947 | } | 945 | } |
948 | 946 | ||
949 | static void brcmf_driver_init(struct work_struct *work) | 947 | static void brcmf_driver_init(struct work_struct *work) |