View | Details | Raw Unified | Return to bug 48391
Collapse All | Expand All

(-)a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c (-14 / +32 lines)
Lines 35-40 Link Here
35
#include "main.h"
35
#include "main.h"
36
36
37
#define N_TX_QUEUES	4 /* #tx queues on mac80211<->driver interface */
37
#define N_TX_QUEUES	4 /* #tx queues on mac80211<->driver interface */
38
#define BRCMS_FLUSH_TIMEOUT	100 /* msec */
38
39
39
/* Flags we support */
40
/* Flags we support */
40
#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
41
#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
Lines 700-715 static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw) Link Here
700
	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
701
	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
701
}
702
}
702
703
704
static bool brcms_tx_flush_completed(struct brcms_info *wl)
705
{
706
	bool result;
707
708
	spin_lock_bh(&wl->lock);
709
	result = brcms_c_tx_flush_completed(wl->wlc);
710
	spin_unlock_bh(&wl->lock);
711
	return result;
712
}
713
703
static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)
714
static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)
704
{
715
{
705
	struct brcms_info *wl = hw->priv;
716
	struct brcms_info *wl = hw->priv;
717
	int ret;
706
718
707
	no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
719
	no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
708
720
709
	/* wait for packet queue and dma fifos to run empty */
721
	ieee80211_stop_queues(hw);
710
	spin_lock_bh(&wl->lock);
722
	if (drop) {
711
	brcms_c_wait_for_tx_completion(wl->wlc, drop);
723
		spin_lock_bh(&wl->lock);
712
	spin_unlock_bh(&wl->lock);
724
		brcms_c_pktq_flush(wl->wlc);
725
		spin_unlock_bh(&wl->lock);
726
	}
727
	pr_info("%s queue size %d txpktpend %d\n", __func__, 
728
		pktq_len(&wl->wlc->pkt_queue->q),
729
		wl->wlc->core->txpktpend[0] + wl->wlc->core->txpktpend[1] +
730
	        wl->wlc->core->txpktpend[2] + wl->wlc->core->txpktpend[3]);
731
	brcms_c_send_q(wl->wlc);
732
	ret = wait_event_timeout(wl->tx_flush_wq,
733
				 brcms_tx_flush_completed(wl),
734
				 msecs_to_jiffies(BRCMS_FLUSH_TIMEOUT));
735
736
	ieee80211_wake_queues(hw);
737
	WARN_ON(!ret);
713
}
738
}
714
739
715
static const struct ieee80211_ops brcms_ops = {
740
static const struct ieee80211_ops brcms_ops = {
Lines 764-769 void brcms_dpc(unsigned long data) Link Here
764
789
765
 done:
790
 done:
766
	spin_unlock_bh(&wl->lock);
791
	spin_unlock_bh(&wl->lock);
792
	wake_up(&wl->tx_flush_wq);
767
}
793
}
768
794
769
/*
795
/*
Lines 1015-1020 static struct brcms_info *brcms_attach(struct bcma_device *pdev) Link Here
1015
1041
1016
	atomic_set(&wl->callbacks, 0);
1042
	atomic_set(&wl->callbacks, 0);
1017
1043
1044
	init_waitqueue_head(&wl->tx_flush_wq);
1045
1018
	/* setup the bottom half handler */
1046
	/* setup the bottom half handler */
1019
	tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl);
1047
	tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl);
1020
1048
Lines 1601-1613 bool brcms_rfkill_set_hw_state(struct brcms_info *wl) Link Here
1601
	spin_lock_bh(&wl->lock);
1629
	spin_lock_bh(&wl->lock);
1602
	return blocked;
1630
	return blocked;
1603
}
1631
}
1604
1605
/*
1606
 * precondition: perimeter lock has been acquired
1607
 */
1608
void brcms_msleep(struct brcms_info *wl, uint ms)
1609
{
1610
	spin_unlock_bh(&wl->lock);
1611
	msleep(ms);
1612
	spin_lock_bh(&wl->lock);
1613
}
(-)a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h (-1 / +2 lines)
Lines 68-73 struct brcms_info { Link Here
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 */
Lines 100-106 extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl, Link Here
100
extern void brcms_free_timer(struct brcms_timer *timer);
102
extern void brcms_free_timer(struct brcms_timer *timer);
101
extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic);
103
extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic);
102
extern bool brcms_del_timer(struct brcms_timer *timer);
104
extern bool brcms_del_timer(struct brcms_timer *timer);
103
extern void brcms_msleep(struct brcms_info *wl, uint ms);
104
extern void brcms_dpc(unsigned long data);
105
extern void brcms_dpc(unsigned long data);
105
extern void brcms_timer(struct brcms_timer *t);
106
extern void brcms_timer(struct brcms_timer *t);
106
extern void brcms_fatal_error(struct brcms_info *wl);
107
extern void brcms_fatal_error(struct brcms_info *wl);
(-)a/drivers/net/wireless/brcm80211/brcmsmac/main.c (-15 / +6 lines)
Lines 7974-7996 int brcms_c_get_curband(struct brcms_c_info *wlc) Link Here
7974
	return wlc->band->bandunit;
7974
	return wlc->band->bandunit;
7975
}
7975
}
7976
7976
7977
void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop)
7977
void brcms_c_pktq_flush(struct brcms_c_info *wlc)
7978
{
7978
{
7979
	int timeout = 20;
7979
	brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
7980
7980
}
7981
	/* flush packet queue when requested */
7982
	if (drop)
7983
		brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
7984
7985
	/* wait for queue and DMA fifos to run dry */
7986
	while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) {
7987
		brcms_msleep(wlc->wl, 1);
7988
7989
		if (--timeout == 0)
7990
			break;
7991
	}
7992
7981
7993
	WARN_ON_ONCE(timeout == 0);
7982
bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc)
7983
{
7984
	return pktq_empty(&wlc->pkt_queue->q) && !brcms_txpktpendtot(wlc);
7994
}
7985
}
7995
7986
7996
void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
7987
void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval)
(-)a/drivers/net/wireless/brcm80211/brcmsmac/pub.h (-2 / +2 lines)
Lines 350-357 extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state); Link Here
350
extern void brcms_c_scan_start(struct brcms_c_info *wlc);
350
extern void brcms_c_scan_start(struct brcms_c_info *wlc);
351
extern void brcms_c_scan_stop(struct brcms_c_info *wlc);
351
extern void brcms_c_scan_stop(struct brcms_c_info *wlc);
352
extern int brcms_c_get_curband(struct brcms_c_info *wlc);
352
extern int brcms_c_get_curband(struct brcms_c_info *wlc);
353
extern void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc,
354
					   bool drop);
355
extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);
353
extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel);
356
extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);
354
extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl);
357
extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
355
extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc,
Lines 368-372 extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); Link Here
368
extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
366
extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
369
extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
367
extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
370
extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
368
extern void brcms_c_mute(struct brcms_c_info *wlc, bool on);
369
extern void brcms_c_pktq_flush(struct brcms_c_info *wlc);
370
extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc);
371
371
372
#endif				/* _BRCM_PUB_H_ */
372
#endif				/* _BRCM_PUB_H_ */

Return to bug 48391