summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
authorWey-Yi Guy2010-06-24 22:22:36 +0200
committerWey-Yi Guy2010-07-02 20:10:33 +0200
commit716c74b00717ad9caedb4a46059fb64a3da99808 (patch)
tree2343795f1314e36d51c3101502dde6aadb34d202 /drivers/net/wireless/iwlwifi/iwl-agn.c
parentiwlwifi: tx fifo queue flush command (diff)
downloadkernel-qcow2-linux-716c74b00717ad9caedb4a46059fb64a3da99808.tar.gz
kernel-qcow2-linux-716c74b00717ad9caedb4a46059fb64a3da99808.tar.xz
kernel-qcow2-linux-716c74b00717ad9caedb4a46059fb64a3da99808.zip
iwlwifi: add mac80211 flush callback support
Adding flush callback support in the driver. Two type of flush can be issued by mac80211: 1. drop = true: frame drop is ok, issue REPLY_TXFIFO_FLUSH host command to uCode to drop all the frames in tx fifo queues; then return the control back to mac80211 2. drop = false: wait for either all the frames in tx fifo queues been transmitted, or timeout; then return the control back to mac80211 If the flush request coming from mac80211, mac80211 will make sure there are no additional frames push down to driver before flush operation is completed. Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 22c0149e5d4a..c735a39ec176 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3639,6 +3639,44 @@ out_exit:
IWL_DEBUG_MAC80211(priv, "leave\n");
}
+static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop)
+{
+ struct iwl_priv *priv = hw->priv;
+
+ mutex_lock(&priv->mutex);
+ IWL_DEBUG_MAC80211(priv, "enter\n");
+
+ /* do not support "flush" */
+ if (!priv->cfg->ops->lib->txfifo_flush)
+ goto done;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+ IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n");
+ goto done;
+ }
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n");
+ goto done;
+ }
+
+ /*
+ * mac80211 will not push any more frames for transmit
+ * until the flush is completed
+ */
+ if (drop) {
+ IWL_DEBUG_MAC80211(priv, "send flush command\n");
+ if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) {
+ IWL_ERR(priv, "flush request fail\n");
+ goto done;
+ }
+ }
+ IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
+ iwlagn_wait_tx_queue_empty(priv);
+done:
+ mutex_unlock(&priv->mutex);
+ IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+
/*****************************************************************************
*
* driver setup and teardown
@@ -3812,6 +3850,7 @@ static struct ieee80211_ops iwl_hw_ops = {
.sta_add = iwlagn_mac_sta_add,
.sta_remove = iwl_mac_sta_remove,
.channel_switch = iwl_mac_channel_switch,
+ .flush = iwl_mac_flush,
};
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)