aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-02-06 13:55:44 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-02-06 13:55:44 -0500
commitb3b66ae4c8aff0636521034d824b8953dc617335 (patch)
tree0a4c792efd730a59adc79d0d2476e0a4b3aa2f2e /drivers/net
parentbf414b369f158bb527f9f29174ada815f961b44c (diff)
parent7b2385b95363c9ff49801c19cba2489a05bd6672 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c35
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h3
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c15
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pub.h3
-rw-r--r--drivers/net/wireless/rtlwifi/base.c7
5 files changed, 31 insertions, 32 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 0f71d1d4339d..e5fd20994bec 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -36,6 +36,7 @@
36#include "debug.h" 36#include "debug.h"
37 37
38#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ 38#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */
39#define BRCMS_FLUSH_TIMEOUT 500 /* msec */
39 40
40/* Flags we support */ 41/* Flags we support */
41#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \ 42#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
@@ -708,16 +709,29 @@ static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw)
708 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked); 709 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
709} 710}
710 711
712static bool brcms_tx_flush_completed(struct brcms_info *wl)
713{
714 bool result;
715
716 spin_lock_bh(&wl->lock);
717 result = brcms_c_tx_flush_completed(wl->wlc);
718 spin_unlock_bh(&wl->lock);
719 return result;
720}
721
711static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop) 722static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)
712{ 723{
713 struct brcms_info *wl = hw->priv; 724 struct brcms_info *wl = hw->priv;
725 int ret;
714 726
715 no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false"); 727 no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
716 728
717 /* wait for packet queue and dma fifos to run empty */ 729 ret = wait_event_timeout(wl->tx_flush_wq,
718 spin_lock_bh(&wl->lock); 730 brcms_tx_flush_completed(wl),
719 brcms_c_wait_for_tx_completion(wl->wlc, drop); 731 msecs_to_jiffies(BRCMS_FLUSH_TIMEOUT));
720 spin_unlock_bh(&wl->lock); 732
733 brcms_dbg_mac80211(wl->wlc->hw->d11core,
734 "ret=%d\n", jiffies_to_msecs(ret));
721} 735}
722 736
723static const struct ieee80211_ops brcms_ops = { 737static const struct ieee80211_ops brcms_ops = {
@@ -772,6 +786,7 @@ void brcms_dpc(unsigned long data)
772 786
773 done: 787 done:
774 spin_unlock_bh(&wl->lock); 788 spin_unlock_bh(&wl->lock);
789 wake_up(&wl->tx_flush_wq);
775} 790}
776 791
777/* 792/*
@@ -1020,6 +1035,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
1020 1035
1021 atomic_set(&wl->callbacks, 0); 1036 atomic_set(&wl->callbacks, 0);
1022 1037
1038 init_waitqueue_head(&wl->tx_flush_wq);
1039
1023 /* setup the bottom half handler */ 1040 /* setup the bottom half handler */
1024 tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl); 1041 tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl);
1025 1042
@@ -1609,13 +1626,3 @@ bool brcms_rfkill_set_hw_state(struct brcms_info *wl)
1609 spin_lock_bh(&wl->lock); 1626 spin_lock_bh(&wl->lock);
1610 return blocked; 1627 return blocked;
1611} 1628}
1612
1613/*
1614 * precondition: perimeter lock has been acquired
1615 */
1616void brcms_msleep(struct brcms_info *wl, uint ms)
1617{
1618 spin_unlock_bh(&wl->lock);
1619 msleep(ms);
1620 spin_lock_bh(&wl->lock);
1621}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
index 9358bd5ebd35..947ccacf43e6 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
@@ -68,6 +68,8 @@ struct brcms_info {
68 spinlock_t lock; /* per-device perimeter lock */ 68 spinlock_t lock; /* per-device perimeter lock */
69 spinlock_t isr_lock; /* per-device ISR synchronization lock */ 69 spinlock_t isr_lock; /* per-device ISR synchronization lock */
70 70
71 /* tx flush */
72 wait_queue_head_t tx_flush_wq;
71 73
72 /* timer related fields */ 74 /* timer related fields */
73 atomic_t callbacks; /* # outstanding callback functions */ 75 atomic_t callbacks; /* # outstanding callback functions */
@@ -100,7 +102,6 @@ extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
100extern void brcms_free_timer(struct brcms_timer *timer); 102extern void brcms_free_timer(struct brcms_timer *timer);
101extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic); 103extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic);
102extern bool brcms_del_timer(struct brcms_timer *timer); 104extern bool brcms_del_timer(struct brcms_timer *timer);
103extern void brcms_msleep(struct brcms_info *wl, uint ms);
104extern void brcms_dpc(unsigned long data); 105extern void brcms_dpc(unsigned long data);
105extern void brcms_timer(struct brcms_timer *t); 106extern void brcms_timer(struct brcms_timer *t);
106extern void brcms_fatal_error(struct brcms_info *wl); 107extern void brcms_fatal_error(struct brcms_info *wl);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 9f3d7e9f3bb5..8b5839008af3 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -7511,25 +7511,16 @@ int brcms_c_get_curband(struct brcms_c_info *wlc)
7511 return wlc->band->bandunit; 7511 return wlc->band->bandunit;
7512} 7512}
7513 7513
7514void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) 7514bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc)
7515{ 7515{
7516 int timeout = 20;
7517 int i; 7516 int i;
7518 7517
7519 /* Kick DMA to send any pending AMPDU */ 7518 /* Kick DMA to send any pending AMPDU */
7520 for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) 7519 for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++)
7521 if (wlc->hw->di[i]) 7520 if (wlc->hw->di[i])
7522 dma_txflush(wlc->hw->di[i]); 7521 dma_kick_tx(wlc->hw->di[i]);
7523 7522
7524 /* wait for queue and DMA fifos to run dry */ 7523 return !brcms_txpktpendtot(wlc);
7525 while (brcms_txpktpendtot(wlc) > 0) {
7526 brcms_msleep(wlc->wl, 1);
7527
7528 if (--timeout == 0)
7529 break;
7530 }
7531
7532 WARN_ON_ONCE(timeout == 0);
7533} 7524}
7534 7525
7535void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval) 7526void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index 4fb2834f4e64..b0f14b7b8616 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -314,8 +314,6 @@ extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state);
314extern void brcms_c_scan_start(struct brcms_c_info *wlc); 314extern void brcms_c_scan_start(struct brcms_c_info *wlc);
315extern void brcms_c_scan_stop(struct brcms_c_info *wlc); 315extern void brcms_c_scan_stop(struct brcms_c_info *wlc);
316extern int brcms_c_get_curband(struct brcms_c_info *wlc); 316extern int brcms_c_get_curband(struct brcms_c_info *wlc);
317extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc,
318 bool drop);
319extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel); 317extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);
320extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl); 318extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);
321extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc, 319extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
@@ -332,5 +330,6 @@ extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
332extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); 330extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
333extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); 331extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
334extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); 332extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
333extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc);
335 334
336#endif /* _BRCM_PUB_H_ */ 335#endif /* _BRCM_PUB_H_ */
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index 4494d130b37c..0f8b05185eda 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -1004,7 +1004,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
1004 is_tx ? "Tx" : "Rx"); 1004 is_tx ? "Tx" : "Rx");
1005 1005
1006 if (is_tx) { 1006 if (is_tx) {
1007 rtl_lps_leave(hw); 1007 schedule_work(&rtlpriv->
1008 works.lps_leave_work);
1008 ppsc->last_delaylps_stamp_jiffies = 1009 ppsc->last_delaylps_stamp_jiffies =
1009 jiffies; 1010 jiffies;
1010 } 1011 }
@@ -1014,7 +1015,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
1014 } 1015 }
1015 } else if (ETH_P_ARP == ether_type) { 1016 } else if (ETH_P_ARP == ether_type) {
1016 if (is_tx) { 1017 if (is_tx) {
1017 rtl_lps_leave(hw); 1018 schedule_work(&rtlpriv->works.lps_leave_work);
1018 ppsc->last_delaylps_stamp_jiffies = jiffies; 1019 ppsc->last_delaylps_stamp_jiffies = jiffies;
1019 } 1020 }
1020 1021
@@ -1024,7 +1025,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
1024 "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); 1025 "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx");
1025 1026
1026 if (is_tx) { 1027 if (is_tx) {
1027 rtl_lps_leave(hw); 1028 schedule_work(&rtlpriv->works.lps_leave_work);
1028 ppsc->last_delaylps_stamp_jiffies = jiffies; 1029 ppsc->last_delaylps_stamp_jiffies = jiffies;
1029 } 1030 }
1030 1031