rt2x00: Implement flush callback
Implement a basic flush callback function, which simply loops over all TX queues and waits until all frames have been transmitted and the status reports have been gathered. At this moment we don't support dropping any frames during the flush, but mac80211 will only send 'false' for this argument anyway, so this is not important at this time. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Acked-by: Helmut Schaa <helmut.schaa@googlemail.com> Acked-by: Gertjan van Wingerde <gwingerde@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
aaf886bd21
commit
f44df18c58
9 changed files with 46 additions and 0 deletions
|
@ -1612,6 +1612,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
|
||||||
.get_tsf = rt2400pci_get_tsf,
|
.get_tsf = rt2400pci_get_tsf,
|
||||||
.tx_last_beacon = rt2400pci_tx_last_beacon,
|
.tx_last_beacon = rt2400pci_tx_last_beacon,
|
||||||
.rfkill_poll = rt2x00mac_rfkill_poll,
|
.rfkill_poll = rt2x00mac_rfkill_poll,
|
||||||
|
.flush = rt2x00mac_flush,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
|
static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
|
||||||
|
|
|
@ -1909,6 +1909,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
|
||||||
.get_tsf = rt2500pci_get_tsf,
|
.get_tsf = rt2500pci_get_tsf,
|
||||||
.tx_last_beacon = rt2500pci_tx_last_beacon,
|
.tx_last_beacon = rt2500pci_tx_last_beacon,
|
||||||
.rfkill_poll = rt2x00mac_rfkill_poll,
|
.rfkill_poll = rt2x00mac_rfkill_poll,
|
||||||
|
.flush = rt2x00mac_flush,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
|
static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
|
||||||
|
|
|
@ -1801,6 +1801,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
|
||||||
.bss_info_changed = rt2x00mac_bss_info_changed,
|
.bss_info_changed = rt2x00mac_bss_info_changed,
|
||||||
.conf_tx = rt2x00mac_conf_tx,
|
.conf_tx = rt2x00mac_conf_tx,
|
||||||
.rfkill_poll = rt2x00mac_rfkill_poll,
|
.rfkill_poll = rt2x00mac_rfkill_poll,
|
||||||
|
.flush = rt2x00mac_flush,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
|
static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
|
||||||
|
|
|
@ -943,6 +943,7 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = {
|
||||||
.get_tsf = rt2800_get_tsf,
|
.get_tsf = rt2800_get_tsf,
|
||||||
.rfkill_poll = rt2x00mac_rfkill_poll,
|
.rfkill_poll = rt2x00mac_rfkill_poll,
|
||||||
.ampdu_action = rt2800_ampdu_action,
|
.ampdu_action = rt2800_ampdu_action,
|
||||||
|
.flush = rt2x00mac_flush,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct rt2800_ops rt2800pci_rt2800_ops = {
|
static const struct rt2800_ops rt2800pci_rt2800_ops = {
|
||||||
|
|
|
@ -508,6 +508,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
|
||||||
.get_tsf = rt2800_get_tsf,
|
.get_tsf = rt2800_get_tsf,
|
||||||
.rfkill_poll = rt2x00mac_rfkill_poll,
|
.rfkill_poll = rt2x00mac_rfkill_poll,
|
||||||
.ampdu_action = rt2800_ampdu_action,
|
.ampdu_action = rt2800_ampdu_action,
|
||||||
|
.flush = rt2x00mac_flush,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct rt2800_ops rt2800usb_rt2800_ops = {
|
static const struct rt2800_ops rt2800usb_rt2800_ops = {
|
||||||
|
|
|
@ -1133,6 +1133,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
|
||||||
int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
|
int rt2x00mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
|
||||||
const struct ieee80211_tx_queue_params *params);
|
const struct ieee80211_tx_queue_params *params);
|
||||||
void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
|
void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
|
||||||
|
void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Driver allocation handlers.
|
* Driver allocation handlers.
|
||||||
|
|
|
@ -719,3 +719,41 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw)
|
||||||
wiphy_rfkill_set_hw_state(hw->wiphy, !active);
|
wiphy_rfkill_set_hw_state(hw->wiphy, !active);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
|
EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
|
||||||
|
|
||||||
|
void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop)
|
||||||
|
{
|
||||||
|
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||||
|
struct data_queue *queue;
|
||||||
|
unsigned int i = 0;
|
||||||
|
|
||||||
|
ieee80211_stop_queues(hw);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Run over all queues to kick them, this will force
|
||||||
|
* any pending frames to be transmitted.
|
||||||
|
*/
|
||||||
|
tx_queue_for_each(rt2x00dev, queue) {
|
||||||
|
rt2x00dev->ops->lib->kick_tx_queue(queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All queues have been kicked, now wait for each queue
|
||||||
|
* to become empty. With a bit of luck, we only have to wait
|
||||||
|
* for the first queue to become empty, because while waiting
|
||||||
|
* for the that queue, the other queues will have transmitted
|
||||||
|
* all their frames as well (since they were already kicked).
|
||||||
|
*/
|
||||||
|
tx_queue_for_each(rt2x00dev, queue) {
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
if (rt2x00queue_empty(queue))
|
||||||
|
break;
|
||||||
|
msleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rt2x00queue_empty(queue))
|
||||||
|
WARNING(rt2x00dev, "Failed to flush queue %d", queue->qid);
|
||||||
|
}
|
||||||
|
|
||||||
|
ieee80211_wake_queues(hw);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(rt2x00mac_flush);
|
||||||
|
|
|
@ -2824,6 +2824,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
|
||||||
.conf_tx = rt61pci_conf_tx,
|
.conf_tx = rt61pci_conf_tx,
|
||||||
.get_tsf = rt61pci_get_tsf,
|
.get_tsf = rt61pci_get_tsf,
|
||||||
.rfkill_poll = rt2x00mac_rfkill_poll,
|
.rfkill_poll = rt2x00mac_rfkill_poll,
|
||||||
|
.flush = rt2x00mac_flush,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
|
static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
|
||||||
|
|
|
@ -2264,6 +2264,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
|
||||||
.conf_tx = rt73usb_conf_tx,
|
.conf_tx = rt73usb_conf_tx,
|
||||||
.get_tsf = rt73usb_get_tsf,
|
.get_tsf = rt73usb_get_tsf,
|
||||||
.rfkill_poll = rt2x00mac_rfkill_poll,
|
.rfkill_poll = rt2x00mac_rfkill_poll,
|
||||||
|
.flush = rt2x00mac_flush,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
|
static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
|
||||||
|
|
Loading…
Reference in a new issue