iwlwifi: mvm: refactor key add/remove functions
authorJohannes Berg <johannes.berg@intel.com>
Wed, 12 Nov 2014 22:39:56 +0000 (23:39 +0100)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 24 Nov 2014 06:30:15 +0000 (08:30 +0200)
Refactor the key add/remove functions to be able to reuse parts
of them later for RX WEP keys, which need to be uploaded twice.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/mvm/sta.c

index 74a7c9138ce996fc0c77b7624b118c8b23cb70ce..f94be3cdeff69ea9355a1da78a333d5539620f9a 100644 (file)
@@ -1072,8 +1072,7 @@ static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
 static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
                                struct iwl_mvm_sta *mvm_sta,
                                struct ieee80211_key_conf *keyconf,
-                               u8 sta_id, u32 tkip_iv32, u16 *tkip_p1k,
-                               u32 cmd_flags)
+                               u32 tkip_iv32, u16 *tkip_p1k, u32 cmd_flags)
 {
        struct iwl_mvm_add_sta_key_cmd cmd = {};
        __le16 key_flags;
@@ -1081,6 +1080,7 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
        u32 status;
        u16 keyidx;
        int i;
+       u8 sta_id = mvm_sta->sta_id;
 
        keyidx = (keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
                 STA_KEY_FLG_KEYID_MSK;
@@ -1196,17 +1196,83 @@ static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm,
        return NULL;
 }
 
+static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
+                                struct ieee80211_vif *vif,
+                                struct ieee80211_sta *sta,
+                                struct ieee80211_key_conf *keyconf)
+{
+       struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
+       int ret;
+       const u8 *addr;
+       struct ieee80211_key_seq seq;
+       u16 p1k[5];
+
+       switch (keyconf->cipher) {
+       case WLAN_CIPHER_SUITE_TKIP:
+               addr = iwl_mvm_get_mac_addr(mvm, vif, sta);
+               /* get phase 1 key from mac80211 */
+               ieee80211_get_key_rx_seq(keyconf, 0, &seq);
+               ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k);
+               ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf,
+                                          seq.tkip.iv32, p1k, 0);
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf,
+                                          0, NULL, 0);
+               break;
+       default:
+               ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf,
+                                          0, NULL, 0);
+       }
+
+       return ret;
+}
+
+static int __iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, u8 sta_id,
+                                   struct ieee80211_key_conf *keyconf)
+{
+       struct iwl_mvm_add_sta_key_cmd cmd = {};
+       __le16 key_flags;
+       int ret;
+       u32 status;
+
+       key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
+                                STA_KEY_FLG_KEYID_MSK);
+       key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP);
+       key_flags |= cpu_to_le16(STA_KEY_NOT_VALID);
+
+       if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+               key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
+
+       cmd.key_flags = key_flags;
+       cmd.key_offset = keyconf->hw_key_idx;
+       cmd.sta_id = sta_id;
+
+       status = ADD_STA_SUCCESS;
+       ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY, sizeof(cmd),
+                                         &cmd, &status);
+
+       switch (status) {
+       case ADD_STA_SUCCESS:
+               IWL_DEBUG_WEP(mvm, "MODIFY_STA: remove sta key passed\n");
+               break;
+       default:
+               ret = -EIO;
+               IWL_ERR(mvm, "MODIFY_STA: remove sta key failed\n");
+               break;
+       }
+
+       return ret;
+}
+
 int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
                        struct ieee80211_vif *vif,
                        struct ieee80211_sta *sta,
                        struct ieee80211_key_conf *keyconf,
                        bool have_key_offset)
 {
-       struct iwl_mvm_sta *mvm_sta;
+       u8 sta_id;
        int ret;
-       u8 *addr, sta_id;
-       struct ieee80211_key_seq seq;
-       u16 p1k[5];
 
        lockdep_assert_held(&mvm->mutex);
 
@@ -1235,8 +1301,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
                }
        }
 
-       mvm_sta = (struct iwl_mvm_sta *)sta->drv_priv;
-       if (WARN_ON_ONCE(mvm_sta->vif != vif))
+       if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif))
                return -EINVAL;
 
        if (!have_key_offset) {
@@ -1250,24 +1315,7 @@ int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
                        return -ENOSPC;
        }
 
-       switch (keyconf->cipher) {
-       case WLAN_CIPHER_SUITE_TKIP:
-               addr = iwl_mvm_get_mac_addr(mvm, vif, sta);
-               /* get phase 1 key from mac80211 */
-               ieee80211_get_key_rx_seq(keyconf, 0, &seq);
-               ieee80211_get_tkip_rx_p1k(keyconf, addr, seq.tkip.iv32, p1k);
-               ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
-                                          seq.tkip.iv32, p1k, 0);
-               break;
-       case WLAN_CIPHER_SUITE_CCMP:
-               ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
-                                          0, NULL, 0);
-               break;
-       default:
-               ret = iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf,
-                                          sta_id, 0, NULL, 0);
-       }
-
+       ret = __iwl_mvm_set_sta_key(mvm, vif, sta, keyconf);
        if (ret)
                __clear_bit(keyconf->hw_key_idx, mvm->fw_key_table);
 
@@ -1283,11 +1331,6 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
                           struct ieee80211_sta *sta,
                           struct ieee80211_key_conf *keyconf)
 {
-       struct iwl_mvm_sta *mvm_sta;
-       struct iwl_mvm_add_sta_key_cmd cmd = {};
-       __le16 key_flags;
-       int ret;
-       u32 status;
        u8 sta_id;
 
        lockdep_assert_held(&mvm->mutex);
@@ -1301,8 +1344,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
        if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
                return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
 
-       ret = __test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table);
-       if (!ret) {
+       if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) {
                IWL_ERR(mvm, "offset %d not used in fw key table.\n",
                        keyconf->hw_key_idx);
                return -ENOENT;
@@ -1328,37 +1370,10 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
                }
        }
 
-       mvm_sta = (struct iwl_mvm_sta *)sta->drv_priv;
-       if (WARN_ON_ONCE(mvm_sta->vif != vif))
+       if (WARN_ON_ONCE(iwl_mvm_sta_from_mac80211(sta)->vif != vif))
                return -EINVAL;
 
-       key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
-                                STA_KEY_FLG_KEYID_MSK);
-       key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP);
-       key_flags |= cpu_to_le16(STA_KEY_NOT_VALID);
-
-       if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE))
-               key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
-
-       cmd.key_flags = key_flags;
-       cmd.key_offset = keyconf->hw_key_idx;
-       cmd.sta_id = sta_id;
-
-       status = ADD_STA_SUCCESS;
-       ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY, sizeof(cmd),
-                                         &cmd, &status);
-
-       switch (status) {
-       case ADD_STA_SUCCESS:
-               IWL_DEBUG_WEP(mvm, "MODIFY_STA: remove sta key passed\n");
-               break;
-       default:
-               ret = -EIO;
-               IWL_ERR(mvm, "MODIFY_STA: remove sta key failed\n");
-               break;
-       }
-
-       return ret;
+       return __iwl_mvm_remove_sta_key(mvm, sta_id, keyconf);
 }
 
 void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
@@ -1383,8 +1398,8 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
                }
        }
 
-       mvm_sta = (void *)sta->drv_priv;
-       iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf, sta_id,
+       mvm_sta = iwl_mvm_sta_from_mac80211(sta);
+       iwl_mvm_send_sta_key(mvm, mvm_sta, keyconf,
                             iv32, phase1key, CMD_ASYNC);
        rcu_read_unlock();
 }