mwl8k: get rid of mwl8k_configure_filter() workqueue use
[pandora-kernel.git] / drivers / net / wireless / mwl8k.c
index 77e280a..43e5dd1 100644 (file)
@@ -1970,7 +1970,7 @@ struct mwl8k_cmd_rts_threshold {
 } __attribute__((packed));
 
 static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
-                              u16 action, u16 *threshold)
+                              u16 action, u16 threshold)
 {
        struct mwl8k_cmd_rts_threshold *cmd;
        int rc;
@@ -1982,7 +1982,7 @@ static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
        cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
        cmd->header.length = cpu_to_le16(sizeof(*cmd));
        cmd->action = cpu_to_le16(action);
-       cmd->threshold = cpu_to_le16(*threshold);
+       cmd->threshold = cpu_to_le16(threshold);
 
        rc = mwl8k_post_cmd(hw, &cmd->header);
        kfree(cmd);
@@ -2663,58 +2663,62 @@ out:
        return rc;
 }
 
-struct mwl8k_bss_info_changed_worker {
-       struct mwl8k_work_struct header;
-       struct ieee80211_vif *vif;
-       struct ieee80211_bss_conf *info;
-       u32 changed;
-};
-
-static int mwl8k_bss_info_changed_wt(struct work_struct *wt)
+static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
+                                  struct ieee80211_vif *vif,
+                                  struct ieee80211_bss_conf *info,
+                                  u32 changed)
 {
-       struct mwl8k_bss_info_changed_worker *worker =
-               (struct mwl8k_bss_info_changed_worker *)wt;
-       struct ieee80211_hw *hw = worker->header.hw;
-       struct ieee80211_vif *vif = worker->vif;
-       struct ieee80211_bss_conf *info = worker->info;
-       u32 changed;
-       int rc;
-
        struct mwl8k_priv *priv = hw->priv;
        struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
+       int rc;
+
+       if (changed & BSS_CHANGED_BSSID)
+               memcpy(mwl8k_vif->bssid, info->bssid, ETH_ALEN);
+
+       if ((changed & BSS_CHANGED_ASSOC) == 0)
+               return;
 
-       changed = worker->changed;
        priv->capture_beacon = false;
 
+       rc = mwl8k_fw_lock(hw);
+       if (!rc)
+               return;
+
        if (info->assoc) {
                memcpy(&mwl8k_vif->bss_info, info,
                        sizeof(struct ieee80211_bss_conf));
 
                /* Install rates */
-               if (mwl8k_update_rateset(hw, vif))
-                       goto mwl8k_bss_info_changed_exit;
+               rc = mwl8k_update_rateset(hw, vif);
+               if (rc)
+                       goto out;
 
                /* Turn on rate adaptation */
-               if (mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
-                       MWL8K_UCAST_RATE, NULL))
-                       goto mwl8k_bss_info_changed_exit;
+               rc = mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
+                       MWL8K_UCAST_RATE, NULL);
+               if (rc)
+                       goto out;
 
                /* Set radio preamble */
-               if (mwl8k_set_radio_preamble(hw, info->use_short_preamble))
-                       goto mwl8k_bss_info_changed_exit;
+               rc = mwl8k_set_radio_preamble(hw, info->use_short_preamble);
+               if (rc)
+                       goto out;
 
                /* Set slot time */
-               if (mwl8k_cmd_set_slot(hw, info->use_short_slot))
-                       goto mwl8k_bss_info_changed_exit;
+               rc = mwl8k_cmd_set_slot(hw, info->use_short_slot);
+               if (rc)
+                       goto out;
 
                /* Update peer rate info */
-               if (mwl8k_cmd_update_sta_db(hw, vif,
-                               MWL8K_STA_DB_MODIFY_ENTRY))
-                       goto mwl8k_bss_info_changed_exit;
+               rc = mwl8k_cmd_update_sta_db(hw, vif,
+                               MWL8K_STA_DB_MODIFY_ENTRY);
+               if (rc)
+                       goto out;
 
                /* Set AID */
-               if (mwl8k_cmd_set_aid(hw, vif))
-                       goto mwl8k_bss_info_changed_exit;
+               rc = mwl8k_cmd_set_aid(hw, vif);
+               if (rc)
+                       goto out;
 
                /*
                 * Finalize the join.  Tell rx handler to process
@@ -2723,43 +2727,14 @@ static int mwl8k_bss_info_changed_wt(struct work_struct *wt)
                memcpy(priv->capture_bssid, mwl8k_vif->bssid, ETH_ALEN);
                priv->capture_beacon = true;
        } else {
-               mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
+               rc = mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
                memset(&mwl8k_vif->bss_info, 0,
                        sizeof(struct ieee80211_bss_conf));
                memset(mwl8k_vif->bssid, 0, ETH_ALEN);
        }
 
-mwl8k_bss_info_changed_exit:
-       rc = 0;
-       return rc;
-}
-
-static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
-                                  struct ieee80211_vif *vif,
-                                  struct ieee80211_bss_conf *info,
-                                  u32 changed)
-{
-       struct mwl8k_bss_info_changed_worker *worker;
-       struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
-       int rc;
-
-       if (changed & BSS_CHANGED_BSSID)
-               memcpy(mv_vif->bssid, info->bssid, ETH_ALEN);
-
-       if ((changed & BSS_CHANGED_ASSOC) == 0)
-               return;
-
-       worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-       if (worker == NULL)
-               return;
-
-       worker->vif = vif;
-       worker->info = info;
-       worker->changed = changed;
-       rc = mwl8k_queue_work(hw, &worker->header, mwl8k_bss_info_changed_wt);
-       kfree(worker);
-       if (rc == -ETIMEDOUT)
-               printk(KERN_ERR "%s() timed out\n", __func__);
+out:
+       mwl8k_fw_unlock(hw);
 }
 
 static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
@@ -2772,26 +2747,23 @@ static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
        return (unsigned long)cmd;
 }
 
-struct mwl8k_configure_filter_worker {
-       struct mwl8k_work_struct header;
-       unsigned int changed_flags;
-       unsigned int total_flags;
+static void mwl8k_configure_filter(struct ieee80211_hw *hw,
+                                  unsigned int changed_flags,
+                                  unsigned int *total_flags,
+                                  u64 multicast)
+{
+       struct mwl8k_priv *priv = hw->priv;
        struct mwl8k_cmd_pkt *multicast_adr_cmd;
-};
 
-#define MWL8K_SUPPORTED_IF_FLAGS       FIF_BCN_PRBRESP_PROMISC
+       /* Clear unsupported feature flags */
+       *total_flags &= FIF_BCN_PRBRESP_PROMISC;
 
-static int mwl8k_configure_filter_wt(struct work_struct *wt)
-{
-       struct mwl8k_configure_filter_worker *worker =
-               (struct mwl8k_configure_filter_worker *)wt;
-       struct ieee80211_hw *hw = worker->header.hw;
-       struct mwl8k_priv *priv = hw->priv;
-       int rc = 0;
+       if (mwl8k_fw_lock(hw))
+               return;
 
-       if (worker->changed_flags & FIF_BCN_PRBRESP_PROMISC) {
-               if (worker->total_flags & FIF_BCN_PRBRESP_PROMISC)
-                       rc = mwl8k_cmd_set_pre_scan(hw);
+       if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
+               if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
+                       mwl8k_cmd_set_pre_scan(hw);
                else {
                        u8 *bssid;
 
@@ -2799,132 +2771,45 @@ static int mwl8k_configure_filter_wt(struct work_struct *wt)
                        if (priv->vif != NULL)
                                bssid = MWL8K_VIF(priv->vif)->bssid;
 
-                       rc = mwl8k_cmd_set_post_scan(hw, bssid);
+                       mwl8k_cmd_set_post_scan(hw, bssid);
                }
        }
 
-       if (!rc && worker->multicast_adr_cmd != NULL)
-               rc = mwl8k_post_cmd(hw, worker->multicast_adr_cmd);
-       kfree(worker->multicast_adr_cmd);
-
-       return rc;
-}
-
-static void mwl8k_configure_filter(struct ieee80211_hw *hw,
-                                  unsigned int changed_flags,
-                                  unsigned int *total_flags,
-                                  u64 multicast)
-{
-       struct mwl8k_configure_filter_worker *worker;
-
-       /* Clear unsupported feature flags */
-       *total_flags &= MWL8K_SUPPORTED_IF_FLAGS;
-
-       if (!(changed_flags & MWL8K_SUPPORTED_IF_FLAGS))
-               return;
-
-       worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
-       if (worker == NULL)
-               return;
-
-       worker->changed_flags = changed_flags;
-       worker->total_flags = *total_flags;
-       worker->multicast_adr_cmd = (void *)(unsigned long)multicast;
-
-       mwl8k_queue_work(hw, &worker->header, mwl8k_configure_filter_wt);
-}
-
-struct mwl8k_set_rts_threshold_worker {
-       struct mwl8k_work_struct header;
-       u32 value;
-};
-
-static int mwl8k_set_rts_threshold_wt(struct work_struct *wt)
-{
-       struct mwl8k_set_rts_threshold_worker *worker =
-               (struct mwl8k_set_rts_threshold_worker *)wt;
-
-       struct ieee80211_hw *hw = worker->header.hw;
-       u16 threshold = (u16)(worker->value);
-       int rc;
-
-       rc = mwl8k_rts_threshold(hw, MWL8K_CMD_SET, &threshold);
+       multicast_adr_cmd = (void *)(unsigned long)multicast;
+       if (multicast_adr_cmd != NULL) {
+               mwl8k_post_cmd(hw, multicast_adr_cmd);
+               kfree(multicast_adr_cmd);
+       }
 
-       return rc;
+       mwl8k_fw_unlock(hw);
 }
 
 static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 {
-       int rc;
-       struct mwl8k_set_rts_threshold_worker *worker;
-
-       worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-       if (worker == NULL)
-               return -ENOMEM;
-
-       worker->value = value;
-
-       rc = mwl8k_queue_work(hw, &worker->header, mwl8k_set_rts_threshold_wt);
-       kfree(worker);
-
-       if (rc == -ETIMEDOUT) {
-               printk(KERN_ERR "%s() timed out\n", __func__);
-               rc = -EINVAL;
-       }
-
-       return rc;
-}
-
-struct mwl8k_conf_tx_worker {
-       struct mwl8k_work_struct header;
-       u16 queue;
-       const struct ieee80211_tx_queue_params *params;
-};
-
-static int mwl8k_conf_tx_wt(struct work_struct *wt)
-{
-       struct mwl8k_conf_tx_worker *worker =
-       (struct mwl8k_conf_tx_worker *)wt;
-
-       struct ieee80211_hw *hw = worker->header.hw;
-       u16 queue = worker->queue;
-       const struct ieee80211_tx_queue_params *params = worker->params;
-
-       struct mwl8k_priv *priv = hw->priv;
-       int rc = 0;
-
-       if (!priv->wmm_enabled) {
-               if (mwl8k_set_wmm(hw, 1)) {
-                       rc = -EINVAL;
-                       goto mwl8k_conf_tx_exit;
-               }
-       }
-
-       if (mwl8k_set_edca_params(hw, GET_TXQ(queue), params->cw_min,
-               params->cw_max, params->aifs, params->txop))
-                       rc = -EINVAL;
-mwl8k_conf_tx_exit:
-       return rc;
+       return mwl8k_rts_threshold(hw, MWL8K_CMD_SET, value);
 }
 
 static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
                         const struct ieee80211_tx_queue_params *params)
 {
+       struct mwl8k_priv *priv = hw->priv;
        int rc;
-       struct mwl8k_conf_tx_worker *worker;
 
-       worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-       if (worker == NULL)
-               return -ENOMEM;
+       rc = mwl8k_fw_lock(hw);
+       if (!rc) {
+               if (!priv->wmm_enabled)
+                       rc = mwl8k_set_wmm(hw, 1);
 
-       worker->queue = queue;
-       worker->params = params;
-       rc = mwl8k_queue_work(hw, &worker->header, mwl8k_conf_tx_wt);
-       kfree(worker);
-       if (rc == -ETIMEDOUT) {
-               printk(KERN_ERR "%s() timed out\n", __func__);
-               rc = -EINVAL;
+               if (!rc)
+                       rc = mwl8k_set_edca_params(hw, queue,
+                                                  params->cw_min,
+                                                  params->cw_max,
+                                                  params->aifs,
+                                                  params->txop);
+
+               mwl8k_fw_unlock(hw);
        }
+
        return rc;
 }
 
@@ -2942,42 +2827,14 @@ static int mwl8k_get_tx_stats(struct ieee80211_hw *hw,
                        sizeof(struct ieee80211_tx_queue_stats));
        }
        spin_unlock_bh(&priv->tx_lock);
-       return 0;
-}
-
-struct mwl8k_get_stats_worker {
-       struct mwl8k_work_struct header;
-       struct ieee80211_low_level_stats *stats;
-};
 
-static int mwl8k_get_stats_wt(struct work_struct *wt)
-{
-       struct mwl8k_get_stats_worker *worker =
-               (struct mwl8k_get_stats_worker *)wt;
-
-       return mwl8k_cmd_802_11_get_stat(worker->header.hw, worker->stats);
+       return 0;
 }
 
 static int mwl8k_get_stats(struct ieee80211_hw *hw,
                           struct ieee80211_low_level_stats *stats)
 {
-       int rc;
-       struct mwl8k_get_stats_worker *worker;
-
-       worker = kzalloc(sizeof(*worker), GFP_KERNEL);
-       if (worker == NULL)
-               return -ENOMEM;
-
-       worker->stats = stats;
-       rc = mwl8k_queue_work(hw, &worker->header, mwl8k_get_stats_wt);
-
-       kfree(worker);
-       if (rc == -ETIMEDOUT) {
-               printk(KERN_ERR "%s() timed out\n", __func__);
-               rc = -EINVAL;
-       }
-
-       return rc;
+       return mwl8k_cmd_802_11_get_stat(hw, stats);
 }
 
 static const struct ieee80211_ops mwl8k_ops = {