staging: brcm80211: implement flush driver callback for mac80211
The mac80211 interface has a flush callback which is used by mac80211 to assure all pending transmit packets have been transmitted. This is used before scanning off-channel. Cc: devel@linuxdriverproject.org Cc: linux-wireless@vger.kernel.org Cc: Brett Rudley <brudley@broadcom.com> Cc: Henry Ptasinski <henryp@broadcom.com> Cc: Roland Vossen <rvossen@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
be2fee08bb
commit
12392c6d4d
4 changed files with 39 additions and 0 deletions
|
@ -42,5 +42,6 @@ extern void wl_free_timer(struct wl_info *wl, struct wl_timer *timer);
|
||||||
extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms,
|
extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms,
|
||||||
int periodic);
|
int periodic);
|
||||||
extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer);
|
extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer);
|
||||||
|
extern void wl_msleep(struct wl_info *wl, uint ms);
|
||||||
|
|
||||||
#endif /* _wl_export_h_ */
|
#endif /* _wl_export_h_ */
|
||||||
|
|
|
@ -149,6 +149,7 @@ static int wl_ops_ampdu_action(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||||
u8 buf_size);
|
u8 buf_size);
|
||||||
static void wl_ops_rfkill_poll(struct ieee80211_hw *hw);
|
static void wl_ops_rfkill_poll(struct ieee80211_hw *hw);
|
||||||
|
static void wl_ops_flush(struct ieee80211_hw *hw, bool drop);
|
||||||
|
|
||||||
static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
|
@ -667,6 +668,18 @@ static void wl_ops_rfkill_poll(struct ieee80211_hw *hw)
|
||||||
wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
|
wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wl_ops_flush(struct ieee80211_hw *hw, bool drop)
|
||||||
|
{
|
||||||
|
struct wl_info *wl = HW_TO_WL(hw);
|
||||||
|
|
||||||
|
no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
|
||||||
|
|
||||||
|
/* wait for packet queue and dma fifos to run empty */
|
||||||
|
WL_LOCK(wl);
|
||||||
|
wlc_wait_for_tx_completion(wl->wlc, drop);
|
||||||
|
WL_UNLOCK(wl);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct ieee80211_ops wl_ops = {
|
static const struct ieee80211_ops wl_ops = {
|
||||||
.tx = wl_ops_tx,
|
.tx = wl_ops_tx,
|
||||||
.start = wl_ops_start,
|
.start = wl_ops_start,
|
||||||
|
@ -688,6 +701,7 @@ static const struct ieee80211_ops wl_ops = {
|
||||||
.sta_remove = wl_ops_sta_remove,
|
.sta_remove = wl_ops_sta_remove,
|
||||||
.ampdu_action = wl_ops_ampdu_action,
|
.ampdu_action = wl_ops_ampdu_action,
|
||||||
.rfkill_poll = wl_ops_rfkill_poll,
|
.rfkill_poll = wl_ops_rfkill_poll,
|
||||||
|
.flush = wl_ops_flush,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1947,3 +1961,13 @@ bool wl_rfkill_set_hw_state(struct wl_info *wl)
|
||||||
WL_LOCK(wl);
|
WL_LOCK(wl);
|
||||||
return blocked;
|
return blocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* precondition: perimeter lock has been acquired
|
||||||
|
*/
|
||||||
|
void wl_msleep(struct wl_info *wl, uint ms)
|
||||||
|
{
|
||||||
|
WL_UNLOCK(wl);
|
||||||
|
msleep(ms);
|
||||||
|
WL_LOCK(wl);
|
||||||
|
}
|
||||||
|
|
|
@ -8104,3 +8104,16 @@ int wlc_get_curband(struct wlc_info *wlc)
|
||||||
{
|
{
|
||||||
return wlc->band->bandunit;
|
return wlc->band->bandunit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop)
|
||||||
|
{
|
||||||
|
/* flush packet queue when requested */
|
||||||
|
if (drop)
|
||||||
|
pktq_flush(&wlc->active_queue->q, false, NULL, 0);
|
||||||
|
|
||||||
|
/* wait for queue and DMA fifos to run dry */
|
||||||
|
while (!pktq_empty(&wlc->active_queue->q) ||
|
||||||
|
TXPKTPENDTOT(wlc) > 0) {
|
||||||
|
wl_msleep(wlc->wl, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -569,6 +569,7 @@ extern void wlc_associate_upd(struct wlc_info *wlc, bool state);
|
||||||
extern void wlc_scan_start(struct wlc_info *wlc);
|
extern void wlc_scan_start(struct wlc_info *wlc);
|
||||||
extern void wlc_scan_stop(struct wlc_info *wlc);
|
extern void wlc_scan_stop(struct wlc_info *wlc);
|
||||||
extern int wlc_get_curband(struct wlc_info *wlc);
|
extern int wlc_get_curband(struct wlc_info *wlc);
|
||||||
|
extern void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop);
|
||||||
|
|
||||||
static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name,
|
static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name,
|
||||||
uint *arg)
|
uint *arg)
|
||||||
|
|
Loading…
Add table
Reference in a new issue