Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-nmw
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl-agn-sta.c
index e483cfa8d14e175aac3432f77951d3641989f116..c4175603864b24f195cd0aa9dda554783a67a80f 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project, as well
  * as portions of the ieee80211 subsystem header files.
@@ -26,7 +26,7 @@
  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  *
  *****************************************************************************/
-
+#include <linux/etherdevice.h>
 #include <net/mac80211.h>
 
 #include "iwl-dev.h"
 #include "iwl-agn.h"
 #include "iwl-trans.h"
 
-/* priv->shrd->sta_lock must be held */
-static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
+static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
 {
+       lockdep_assert_held(&priv->sta_lock);
 
+       if (sta_id >= IWLAGN_STATION_COUNT) {
+               IWL_ERR(priv, "invalid sta_id %u", sta_id);
+               return -EINVAL;
+       }
        if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
                IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u "
                        "addr %pM\n",
@@ -53,14 +57,15 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
                IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n",
                                sta_id, priv->stations[sta_id].sta.sta.addr);
        }
+       return 0;
 }
 
 static int iwl_process_add_sta_resp(struct iwl_priv *priv,
                                    struct iwl_addsta_cmd *addsta,
                                    struct iwl_rx_packet *pkt)
 {
+       struct iwl_add_sta_resp *add_sta_resp = (void *)pkt->data;
        u8 sta_id = addsta->sta.sta_id;
-       unsigned long flags;
        int ret = -EIO;
 
        if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
@@ -72,13 +77,12 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
        IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n",
                       sta_id);
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock(&priv->sta_lock);
 
-       switch (pkt->u.add_sta.status) {
+       switch (add_sta_resp->status) {
        case ADD_STA_SUCCESS_MSK:
                IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n");
-               iwl_sta_ucode_activate(priv, sta_id);
-               ret = 0;
+               ret = iwl_sta_ucode_activate(priv, sta_id);
                break;
        case ADD_STA_NO_ROOM_IN_TABLE:
                IWL_ERR(priv, "Adding station %d failed, no room in table.\n",
@@ -94,7 +98,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
                break;
        default:
                IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n",
-                               pkt->u.add_sta.status);
+                               add_sta_resp->status);
                break;
        }
 
@@ -115,12 +119,12 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
                       priv->stations[sta_id].sta.mode ==
                       STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
                       addsta->sta.addr);
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock(&priv->sta_lock);
 
        return ret;
 }
 
-int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
                               struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -150,14 +154,14 @@ int iwl_send_add_sta(struct iwl_priv *priv,
                might_sleep();
        }
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
 
        if (ret || (flags & CMD_ASYNC))
                return ret;
        /*else the command was successfully sent in SYNC mode, need to free
         * the reply page */
 
-       iwl_free_pages(priv->shrd, cmd.reply_page);
+       iwl_free_resp(&cmd);
 
        if (cmd.handler_status)
                IWL_ERR(priv, "%s - error in the CMD response %d", __func__,
@@ -166,34 +170,38 @@ int iwl_send_add_sta(struct iwl_priv *priv,
        return cmd.handler_status;
 }
 
-static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
-                                  struct ieee80211_sta *sta,
-                                  struct iwl_rxon_context *ctx)
+static void iwl_sta_calc_ht_flags(struct iwl_priv *priv,
+                                 struct ieee80211_sta *sta,
+                                 struct iwl_rxon_context *ctx,
+                                 __le32 *flags, __le32 *mask)
 {
        struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
-       __le32 sta_flags;
        u8 mimo_ps_mode;
 
+       *mask = STA_FLG_RTS_MIMO_PROT_MSK |
+               STA_FLG_MIMO_DIS_MSK |
+               STA_FLG_HT40_EN_MSK |
+               STA_FLG_MAX_AGG_SIZE_MSK |
+               STA_FLG_AGG_MPDU_DENSITY_MSK;
+       *flags = 0;
+
        if (!sta || !sta_ht_inf->ht_supported)
-               goto done;
+               return;
 
        mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
-       IWL_DEBUG_ASSOC(priv, "spatial multiplexing power save mode: %s\n",
+
+       IWL_DEBUG_INFO(priv, "STA %pM SM PS mode: %s\n",
                        (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?
                        "static" :
                        (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?
                        "dynamic" : "disabled");
 
-       sta_flags = priv->stations[index].sta.station_flags;
-
-       sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
-
        switch (mimo_ps_mode) {
        case WLAN_HT_CAP_SM_PS_STATIC:
-               sta_flags |= STA_FLG_MIMO_DIS_MSK;
+               *flags |= STA_FLG_MIMO_DIS_MSK;
                break;
        case WLAN_HT_CAP_SM_PS_DYNAMIC:
-               sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
+               *flags |= STA_FLG_RTS_MIMO_PROT_MSK;
                break;
        case WLAN_HT_CAP_SM_PS_DISABLED:
                break;
@@ -202,20 +210,53 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
                break;
        }
 
-       sta_flags |= cpu_to_le32(
-             (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
+       *flags |= cpu_to_le32(
+               (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);
 
-       sta_flags |= cpu_to_le32(
-             (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
+       *flags |= cpu_to_le32(
+               (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
 
        if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap))
-               sta_flags |= STA_FLG_HT40_EN_MSK;
-       else
-               sta_flags &= ~STA_FLG_HT40_EN_MSK;
+               *flags |= STA_FLG_HT40_EN_MSK;
+}
+
+int iwl_sta_update_ht(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
+                     struct ieee80211_sta *sta)
+{
+       u8 sta_id = iwl_sta_id(sta);
+       __le32 flags, mask;
+       struct iwl_addsta_cmd cmd;
+
+       if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION))
+               return -EINVAL;
+
+       iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask);
+
+       spin_lock_bh(&priv->sta_lock);
+       priv->stations[sta_id].sta.station_flags &= ~mask;
+       priv->stations[sta_id].sta.station_flags |= flags;
+       spin_unlock_bh(&priv->sta_lock);
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.mode = STA_CONTROL_MODIFY_MSK;
+       cmd.station_flags_msk = mask;
+       cmd.station_flags = flags;
+       cmd.sta.sta_id = sta_id;
+
+       return iwl_send_add_sta(priv, &cmd, CMD_SYNC);
+}
 
-       priv->stations[index].sta.station_flags = sta_flags;
- done:
-       return;
+static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
+                                  struct ieee80211_sta *sta,
+                                  struct iwl_rxon_context *ctx)
+{
+       __le32 flags, mask;
+
+       iwl_sta_calc_ht_flags(priv, sta, ctx, &flags, &mask);
+
+       lockdep_assert_held(&priv->sta_lock);
+       priv->stations[index].sta.station_flags &= ~mask;
+       priv->stations[index].sta.station_flags |= flags;
 }
 
 /**
@@ -314,18 +355,17 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                           const u8 *addr, bool is_ap,
                           struct ieee80211_sta *sta, u8 *sta_id_r)
 {
-       unsigned long flags_spin;
        int ret = 0;
        u8 sta_id;
        struct iwl_addsta_cmd sta_cmd;
 
        *sta_id_r = 0;
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+       spin_lock_bh(&priv->sta_lock);
        sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta);
        if (sta_id == IWL_INVALID_STATION) {
                IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
                        addr);
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
                return -EINVAL;
        }
 
@@ -337,7 +377,7 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
        if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
                IWL_DEBUG_INFO(priv, "STA %d already in process of being "
                               "added.\n", sta_id);
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
                return -EEXIST;
        }
 
@@ -345,24 +385,24 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
            (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
                IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not "
                                "adding again.\n", sta_id, addr);
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
                return -EEXIST;
        }
 
        priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
        memcpy(&sta_cmd, &priv->stations[sta_id].sta,
               sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+       spin_unlock_bh(&priv->sta_lock);
 
        /* Add station to device's station table */
        ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
        if (ret) {
-               spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+               spin_lock_bh(&priv->sta_lock);
                IWL_ERR(priv, "Adding station %pM failed.\n",
                        priv->stations[sta_id].sta.sta.addr);
                priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
                priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
        }
        *sta_id_r = sta_id;
        return ret;
@@ -370,11 +410,11 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 
 /**
  * iwl_sta_ucode_deactivate - deactivate ucode status for a station
- *
- * priv->shrd->sta_lock must be held
  */
 static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
 {
+       lockdep_assert_held(&priv->sta_lock);
+
        /* Ucode must be active and driver must be non active */
        if ((priv->stations[sta_id].used &
             (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) !=
@@ -393,8 +433,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
 {
        struct iwl_rx_packet *pkt;
        int ret;
-
-       unsigned long flags_spin;
        struct iwl_rem_sta_cmd rm_sta_cmd;
 
        struct iwl_host_cmd cmd = {
@@ -410,12 +448,12 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
 
        cmd.flags |= CMD_WANT_SKB;
 
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       ret = iwl_dvm_send_cmd(priv, &cmd);
 
        if (ret)
                return ret;
 
-       pkt = (struct iwl_rx_packet *)cmd.reply_page;
+       pkt = cmd.resp_pkt;
        if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
                IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
                          pkt->hdr.flags);
@@ -423,14 +461,13 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
        }
 
        if (!ret) {
-               switch (pkt->u.rem_sta.status) {
+               struct iwl_rem_sta_resp *rem_sta_resp = (void *)pkt->data;
+               switch (rem_sta_resp->status) {
                case REM_STA_SUCCESS_MSK:
                        if (!temporary) {
-                               spin_lock_irqsave(&priv->shrd->sta_lock,
-                                       flags_spin);
+                               spin_lock_bh(&priv->sta_lock);
                                iwl_sta_ucode_deactivate(priv, sta_id);
-                               spin_unlock_irqrestore(&priv->shrd->sta_lock,
-                                       flags_spin);
+                               spin_unlock_bh(&priv->sta_lock);
                        }
                        IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
                        break;
@@ -440,7 +477,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
                        break;
                }
        }
-       iwl_free_pages(priv->shrd, cmd.reply_page);
+       iwl_free_resp(&cmd);
 
        return ret;
 }
@@ -451,10 +488,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
 int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
                       const u8 *addr)
 {
-       unsigned long flags;
        u8 tid;
 
-       if (!iwl_is_ready(priv->shrd)) {
+       if (!iwl_is_ready(priv)) {
                IWL_DEBUG_INFO(priv,
                        "Unable to remove station %pM, device not ready.\n",
                        addr);
@@ -472,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
        if (WARN_ON(sta_id == IWL_INVALID_STATION))
                return -EINVAL;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
 
        if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
                IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
@@ -502,14 +538,49 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
        if (WARN_ON(priv->num_stations < 0))
                priv->num_stations = 0;
 
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return iwl_send_remove_station(priv, addr, sta_id, false);
 out_err:
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
        return -EINVAL;
 }
 
+void iwl_deactivate_station(struct iwl_priv *priv, const u8 sta_id,
+                           const u8 *addr)
+{
+       u8 tid;
+
+       if (!iwl_is_ready(priv)) {
+               IWL_DEBUG_INFO(priv,
+                       "Unable to remove station %pM, device not ready.\n",
+                       addr);
+               return;
+       }
+
+       IWL_DEBUG_ASSOC(priv, "Deactivating STA: %pM (%d)\n", addr, sta_id);
+
+       if (WARN_ON_ONCE(sta_id == IWL_INVALID_STATION))
+               return;
+
+       spin_lock_bh(&priv->sta_lock);
+
+       WARN_ON_ONCE(!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE));
+
+       for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
+               memset(&priv->tid_data[sta_id][tid], 0,
+                       sizeof(priv->tid_data[sta_id][tid]));
+
+       priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
+
+       priv->num_stations--;
+
+       if (WARN_ON_ONCE(priv->num_stations < 0))
+               priv->num_stations = 0;
+
+       spin_unlock_bh(&priv->sta_lock);
+}
+
 /**
  * iwl_clear_ucode_stations - clear ucode station table bits
  *
@@ -522,12 +593,11 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv,
                              struct iwl_rxon_context *ctx)
 {
        int i;
-       unsigned long flags_spin;
        bool cleared = false;
 
        IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n");
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+       spin_lock_bh(&priv->sta_lock);
        for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
                if (ctx && ctx->ctxid != priv->stations[i].ctxid)
                        continue;
@@ -539,7 +609,7 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv,
                        cleared = true;
                }
        }
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+       spin_unlock_bh(&priv->sta_lock);
 
        if (!cleared)
                IWL_DEBUG_INFO(priv,
@@ -558,20 +628,19 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
        struct iwl_addsta_cmd sta_cmd;
        struct iwl_link_quality_cmd lq;
-       unsigned long flags_spin;
        int i;
        bool found = false;
        int ret;
        bool send_lq;
 
-       if (!iwl_is_ready(priv->shrd)) {
+       if (!iwl_is_ready(priv)) {
                IWL_DEBUG_INFO(priv,
                               "Not ready yet, not restoring any stations.\n");
                return;
        }
 
        IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+       spin_lock_bh(&priv->sta_lock);
        for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
                if (ctx->ctxid != priv->stations[i].ctxid)
                        continue;
@@ -591,27 +660,24 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                               sizeof(struct iwl_addsta_cmd));
                        send_lq = false;
                        if (priv->stations[i].lq) {
-                               if (priv->shrd->wowlan)
+                               if (priv->wowlan)
                                        iwl_sta_fill_lq(priv, ctx, i, &lq);
                                else
                                        memcpy(&lq, priv->stations[i].lq,
                                               sizeof(struct iwl_link_quality_cmd));
                                send_lq = true;
                        }
-                       spin_unlock_irqrestore(&priv->shrd->sta_lock,
-                                              flags_spin);
+                       spin_unlock_bh(&priv->sta_lock);
                        ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
                        if (ret) {
-                               spin_lock_irqsave(&priv->shrd->sta_lock,
-                                                 flags_spin);
+                               spin_lock_bh(&priv->sta_lock);
                                IWL_ERR(priv, "Adding station %pM failed.\n",
                                        priv->stations[i].sta.sta.addr);
                                priv->stations[i].used &=
                                                ~IWL_STA_DRIVER_ACTIVE;
                                priv->stations[i].used &=
                                                ~IWL_STA_UCODE_INPROGRESS;
-                               spin_unlock_irqrestore(&priv->shrd->sta_lock,
-                                                      flags_spin);
+                               spin_unlock_bh(&priv->sta_lock);
                        }
                        /*
                         * Rate scaling has already been initialized, send
@@ -620,12 +686,12 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                        if (send_lq)
                                iwl_send_lq_cmd(priv, ctx, &lq,
                                                CMD_SYNC, true);
-                       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+                       spin_lock_bh(&priv->sta_lock);
                        priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
                }
        }
 
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+       spin_unlock_bh(&priv->sta_lock);
        if (!found)
                IWL_DEBUG_INFO(priv, "Restoring all known stations .... "
                        "no stations to be restored.\n");
@@ -634,52 +700,6 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                        "complete.\n");
 }
 
-void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
-{
-       unsigned long flags;
-       int sta_id = ctx->ap_sta_id;
-       int ret;
-       struct iwl_addsta_cmd sta_cmd;
-       struct iwl_link_quality_cmd lq;
-       bool active, have_lq = false;
-
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-               return;
-       }
-
-       memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
-       sta_cmd.mode = 0;
-       if (priv->stations[sta_id].lq) {
-               memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
-               have_lq = true;
-       }
-
-       active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
-       priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-
-       if (active) {
-               ret = iwl_send_remove_station(
-                       priv, priv->stations[sta_id].sta.sta.addr,
-                       sta_id, true);
-               if (ret)
-                       IWL_ERR(priv, "failed to remove STA %pM (%d)\n",
-                               priv->stations[sta_id].sta.sta.addr, ret);
-       }
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-
-       ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
-       if (ret)
-               IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
-                       priv->stations[sta_id].sta.sta.addr, ret);
-       if (have_lq)
-               iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
-}
-
 int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)
 {
        int i;
@@ -693,10 +713,9 @@ int iwl_get_free_ucode_key_offset(struct iwl_priv *priv)
 
 void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
 {
-       unsigned long flags;
        int i;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        for (i = 0; i < IWLAGN_STATION_COUNT; i++) {
                if (!(priv->stations[i].used & IWL_STA_BCAST))
                        continue;
@@ -708,7 +727,7 @@ void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
                kfree(priv->stations[i].lq);
                priv->stations[i].lq = NULL;
        }
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -780,8 +799,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                    struct iwl_link_quality_cmd *lq, u8 flags, bool init)
 {
        int ret = 0;
-       unsigned long flags_spin;
-
        struct iwl_host_cmd cmd = {
                .id = REPLY_TX_LINK_QUALITY_CMD,
                .len = { sizeof(struct iwl_link_quality_cmd), },
@@ -793,19 +810,19 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                return -EINVAL;
 
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+       spin_lock_bh(&priv->sta_lock);
        if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
                return -EINVAL;
        }
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+       spin_unlock_bh(&priv->sta_lock);
 
        iwl_dump_lq_cmd(priv, lq);
        if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
                return -EINVAL;
 
        if (is_lq_table_valid(priv, ctx, lq))
-               ret = iwl_trans_send_cmd(trans(priv), &cmd);
+               ret = iwl_dvm_send_cmd(priv, &cmd);
        else
                ret = -EINVAL;
 
@@ -816,9 +833,9 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                IWL_DEBUG_INFO(priv, "init LQ command complete, "
                               "clearing sta addition status for sta %d\n",
                               lq->sta_id);
-               spin_lock_irqsave(&priv->shrd->sta_lock, flags_spin);
+               spin_lock_bh(&priv->sta_lock);
                priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags_spin);
+               spin_unlock_bh(&priv->sta_lock);
        }
        return ret;
 }
@@ -831,7 +848,7 @@ void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
        u32 rate_flags = 0;
        __le32 rate_n_flags;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        memset(link_cmd, 0, sizeof(*link_cmd));
 
@@ -903,7 +920,6 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv,
        int ret;
        u8 sta_id;
        struct iwl_link_quality_cmd *link_cmd;
-       unsigned long flags;
 
        if (sta_id_r)
                *sta_id_r = IWL_INVALID_STATION;
@@ -917,9 +933,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv,
        if (sta_id_r)
                *sta_id_r = sta_id;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].used |= IWL_STA_LOCAL;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        /* Set up default rate scaling table in device's station table */
        link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id);
@@ -934,9 +950,9 @@ int iwlagn_add_bssid_station(struct iwl_priv *priv,
        if (ret)
                IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].lq = link_cmd;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return 0;
 }
@@ -991,7 +1007,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
        cmd.len[0] = cmd_size;
 
        if (not_empty || send_if_empty)
-               return iwl_trans_send_cmd(trans(priv), &cmd);
+               return iwl_dvm_send_cmd(priv, &cmd);
        else
                return 0;
 }
@@ -999,7 +1015,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
 int iwl_restore_default_wep_keys(struct iwl_priv *priv,
                                 struct iwl_rxon_context *ctx)
 {
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        return iwl_send_static_wepkey_cmd(priv, ctx, false);
 }
@@ -1010,13 +1026,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
 {
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
                      keyconf->keyidx);
 
        memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
-       if (iwl_is_rfkill(priv->shrd)) {
+       if (iwl_is_rfkill(priv)) {
                IWL_DEBUG_WEP(priv,
                        "Not sending REPLY_WEPKEY command due to RFKILL.\n");
                /* but keys in device are clear anyway so return success */
@@ -1035,7 +1051,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
 {
        int ret;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        if (keyconf->keylen != WEP_KEY_LEN_128 &&
            keyconf->keylen != WEP_KEY_LEN_64) {
@@ -1077,32 +1093,19 @@ static u8 iwlagn_key_sta_id(struct iwl_priv *priv,
                            struct ieee80211_sta *sta)
 {
        struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
-       u8 sta_id = IWL_INVALID_STATION;
 
        if (sta)
-               sta_id = iwl_sta_id(sta);
+               return iwl_sta_id(sta);
 
        /*
         * The device expects GTKs for station interfaces to be
         * installed as GTKs for the AP station. If we have no
         * station ID, then use the ap_sta_id in that case.
         */
-       if (!sta && vif && vif_priv->ctx) {
-               switch (vif->type) {
-               case NL80211_IFTYPE_STATION:
-                       sta_id = vif_priv->ctx->ap_sta_id;
-                       break;
-               default:
-                       /*
-                        * In all other cases, the key will be
-                        * used either for TX only or is bound
-                        * to a station already.
-                        */
-                       break;
-               }
-       }
+       if (vif->type == NL80211_IFTYPE_STATION && vif_priv->ctx)
+               return vif_priv->ctx->ap_sta_id;
 
-       return sta_id;
+       return IWL_INVALID_STATION;
 }
 
 static int iwlagn_send_sta_key(struct iwl_priv *priv,
@@ -1110,14 +1113,13 @@ static int iwlagn_send_sta_key(struct iwl_priv *priv,
                               u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k,
                               u32 cmd_flags)
 {
-       unsigned long flags;
        __le16 key_flags;
        struct iwl_addsta_cmd sta_cmd;
        int i;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
        key_flags |= STA_KEY_FLG_MAP_KEY_MSK;
@@ -1184,7 +1186,6 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
                           struct ieee80211_key_conf *keyconf,
                           struct ieee80211_sta *sta)
 {
-       unsigned long flags;
        struct iwl_addsta_cmd sta_cmd;
        u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta);
        __le16 key_flags;
@@ -1193,16 +1194,16 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
        if (sta_id == IWL_INVALID_STATION)
                return -ENOENT;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
        if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE))
                sta_id = IWL_INVALID_STATION;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        if (sta_id == IWL_INVALID_STATION)
                return 0;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        ctx->key_mapping_keys--;
 
@@ -1242,7 +1243,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
        if (sta_id == IWL_INVALID_STATION)
                return -EINVAL;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        keyconf->hw_key_idx = iwl_get_free_ucode_key_offset(priv);
        if (keyconf->hw_key_idx == WEP_INVALID_OFFSET)
@@ -1297,21 +1298,20 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
                               struct iwl_rxon_context *ctx)
 {
        struct iwl_link_quality_cmd *link_cmd;
-       unsigned long flags;
        u8 sta_id;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
        if (sta_id == IWL_INVALID_STATION) {
                IWL_ERR(priv, "Unable to prepare broadcast station\n");
-               spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+               spin_unlock_bh(&priv->sta_lock);
 
                return -EINVAL;
        }
 
        priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
        priv->stations[sta_id].used |= IWL_STA_BCAST;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        link_cmd = iwl_sta_alloc_lq(priv, ctx, sta_id);
        if (!link_cmd) {
@@ -1320,9 +1320,9 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
                return -ENOMEM;
        }
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].lq = link_cmd;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return 0;
 }
@@ -1336,7 +1336,6 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
 int iwl_update_bcast_station(struct iwl_priv *priv,
                             struct iwl_rxon_context *ctx)
 {
-       unsigned long flags;
        struct iwl_link_quality_cmd *link_cmd;
        u8 sta_id = ctx->bcast_sta_id;
 
@@ -1346,13 +1345,13 @@ int iwl_update_bcast_station(struct iwl_priv *priv,
                return -ENOMEM;
        }
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        if (priv->stations[sta_id].lq)
                kfree(priv->stations[sta_id].lq);
        else
                IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n");
        priv->stations[sta_id].lq = link_cmd;
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return 0;
 }
@@ -1376,18 +1375,17 @@ int iwl_update_bcast_stations(struct iwl_priv *priv)
  */
 int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
 {
-       unsigned long flags;
        struct iwl_addsta_cmd sta_cmd;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        /* Remove "disable" flag, to enable Tx for this TID */
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
        priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
 }
@@ -1395,24 +1393,23 @@ int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
 int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
                         int tid, u16 ssn)
 {
-       unsigned long flags;
        int sta_id;
        struct iwl_addsta_cmd sta_cmd;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        sta_id = iwl_sta_id(sta);
        if (sta_id == IWL_INVALID_STATION)
                return -ENXIO;
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].sta.station_flags_msk = 0;
        priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
        priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
        priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
 }
@@ -1420,11 +1417,10 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
 int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
                        int tid)
 {
-       unsigned long flags;
        int sta_id;
        struct iwl_addsta_cmd sta_cmd;
 
-       lockdep_assert_held(&priv->shrd->mutex);
+       lockdep_assert_held(&priv->mutex);
 
        sta_id = iwl_sta_id(sta);
        if (sta_id == IWL_INVALID_STATION) {
@@ -1432,13 +1428,13 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
                return -ENXIO;
        }
 
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
+       spin_lock_bh(&priv->sta_lock);
        priv->stations[sta_id].sta.station_flags_msk = 0;
        priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
        priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
        priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       spin_unlock_bh(&priv->sta_lock);
 
        return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
 }
@@ -1447,16 +1443,14 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
 
 void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
 {
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->shrd->sta_lock, flags);
-       priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
-       priv->stations[sta_id].sta.sta.modify_mask =
-                                       STA_MODIFY_SLEEP_TX_COUNT_MSK;
-       priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
-       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
-       iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
-       spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       struct iwl_addsta_cmd cmd = {
+               .mode = STA_CONTROL_MODIFY_MSK,
+               .station_flags = STA_FLG_PWR_SAVE_MSK,
+               .station_flags_msk = STA_FLG_PWR_SAVE_MSK,
+               .sta.sta_id = sta_id,
+               .sta.modify_mask = STA_MODIFY_SLEEP_TX_COUNT_MSK,
+               .sleep_tx_count = cpu_to_le16(cnt),
+       };
 
+       iwl_send_add_sta(priv, &cmd, CMD_ASYNC);
 }
This page took 0.059927 seconds and 5 git commands to generate.