mac80211: allow configure_filter callback to sleep
[deliverable/linux.git] / drivers / net / wireless / ath / ar9170 / main.c
index 85a1452a7c3c30707f67b8f2df6d37b95405f20b..6a9462e4fd87afb8df278a6b63feb38eeca32840 100644 (file)
@@ -595,10 +595,12 @@ static void ar9170_tx_janitor(struct work_struct *work)
 
        ar9170_tx_fake_ampdu_status(ar);
 
-       if (resched)
-               queue_delayed_work(ar->hw->workqueue,
-                                  &ar->tx_janitor,
-                                  msecs_to_jiffies(AR9170_JANITOR_DELAY));
+       if (!resched)
+               return;
+
+       ieee80211_queue_delayed_work(ar->hw,
+                                    &ar->tx_janitor,
+                                    msecs_to_jiffies(AR9170_JANITOR_DELAY));
 }
 
 void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
@@ -648,7 +650,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
                 * pre-TBTT event
                 */
                if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
-                       queue_work(ar->hw->workqueue, &ar->beacon_work);
+                       ieee80211_queue_work(ar->hw, &ar->beacon_work);
                break;
 
        case 0xc2:
@@ -1290,14 +1292,13 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
        if (IS_STARTED(ar))
                ar->state = AR9170_IDLE;
 
-       flush_workqueue(ar->hw->workqueue);
-
        cancel_delayed_work_sync(&ar->tx_janitor);
 #ifdef CONFIG_AR9170_LEDS
        cancel_delayed_work_sync(&ar->led_work);
 #endif
        cancel_work_sync(&ar->filter_config_work);
        cancel_work_sync(&ar->beacon_work);
+
        mutex_lock(&ar->mutex);
 
        if (IS_ACCEPTING_CMD(ar)) {
@@ -1826,10 +1827,12 @@ static void ar9170_tx(struct ar9170 *ar)
                }
        }
 
-       if (schedule_garbagecollector)
-               queue_delayed_work(ar->hw->workqueue,
-                                  &ar->tx_janitor,
-                                  msecs_to_jiffies(AR9170_JANITOR_DELAY));
+       if (!schedule_garbagecollector)
+               return;
+
+       ieee80211_queue_delayed_work(ar->hw,
+                                    &ar->tx_janitor,
+                                    msecs_to_jiffies(AR9170_JANITOR_DELAY));
 }
 
 static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb)
@@ -2097,10 +2100,29 @@ unlock:
        mutex_unlock(&ar->mutex);
 }
 
+static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
+                                      struct dev_addr_list *mclist)
+{
+       u64 mchash;
+       int i;
+
+       /* always get broadcast frames */
+       mchash = 1ULL << (0xff >> 2);
+
+       for (i = 0; i < mc_count; i++) {
+               if (WARN_ON(!mclist))
+                       break;
+               mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
+               mclist = mclist->next;
+       }
+
+       return mchash;
+}
+
 static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
                                       unsigned int changed_flags,
                                       unsigned int *new_flags,
-                                      int mc_count, struct dev_mc_list *mclist)
+                                      u64 multicast)
 {
        struct ar9170 *ar = hw->priv;
 
@@ -2113,24 +2135,11 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
         * then checking the error flags, later.
         */
 
-       if (changed_flags & FIF_ALLMULTI) {
-               if (*new_flags & FIF_ALLMULTI) {
-                       ar->want_mc_hash = ~0ULL;
-               } else {
-                       u64 mchash;
-                       int i;
-
-                       /* always get broadcast frames */
-                       mchash = 1ULL << (0xff >> 2);
+       if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
+                       multicast = ~0ULL;
 
-                       for (i = 0; i < mc_count; i++) {
-                               if (WARN_ON(!mclist))
-                                       break;
-                               mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
-                               mclist = mclist->next;
-                       }
-               ar->want_mc_hash = mchash;
-               }
+       if (multicast != ar->want_mc_hash) {
+               ar->want_mc_hash = multicast;
                set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
        }
 
@@ -2158,7 +2167,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
        }
 
        if (likely(IS_STARTED(ar)))
-               queue_work(ar->hw->workqueue, &ar->filter_config_work);
+               ieee80211_queue_work(ar->hw, &ar->filter_config_work);
 }
 
 static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
@@ -2416,7 +2425,7 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw,
        }
 
        if (IS_STARTED(ar) && ar->filter_changed)
-               queue_work(ar->hw->workqueue, &ar->filter_config_work);
+               ieee80211_queue_work(ar->hw, &ar->filter_config_work);
 }
 
 static int ar9170_get_stats(struct ieee80211_hw *hw,
@@ -2455,13 +2464,14 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
        int ret;
 
        mutex_lock(&ar->mutex);
-       if ((param) && !(queue > __AR9170_NUM_TXQ)) {
+       if (queue < __AR9170_NUM_TXQ) {
                memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
                       param, sizeof(*param));
 
                ret = ar9170_set_qos(ar);
-       } else
+       } else {
                ret = -EINVAL;
+       }
 
        mutex_unlock(&ar->mutex);
        return ret;
@@ -2539,6 +2549,7 @@ static const struct ieee80211_ops ar9170_ops = {
        .add_interface          = ar9170_op_add_interface,
        .remove_interface       = ar9170_op_remove_interface,
        .config                 = ar9170_op_config,
+       .prepare_multicast      = ar9170_op_prepare_multicast,
        .configure_filter       = ar9170_op_configure_filter,
        .conf_tx                = ar9170_conf_tx,
        .bss_info_changed       = ar9170_op_bss_info_changed,
This page took 0.092139 seconds and 5 git commands to generate.