aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-08-23 04:46:43 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2010-08-27 12:25:56 -0400
commitc10afb6e844b7936092396f719b794c4d0038f27 (patch)
tree32d2aa88058ff320063fdec5f606235acc2e3015
parent2995bafafd4d9d2f840b51b0121997be09fb8b47 (diff)
iwlwifi: make hw crypto context aware
HW crypto needs to be aware of the context, and there are different command IDs for the WEP keys per context, so move the key tracking variables and command IDs into the context structure. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c41
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c1
7 files changed, 63 insertions, 35 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index ba3a9f9d519e..5d09686c3389 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2430,6 +2430,8 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
2430 priv->hw_params.max_stations = IWL3945_STATION_COUNT; 2430 priv->hw_params.max_stations = IWL3945_STATION_COUNT;
2431 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID; 2431 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID;
2432 2432
2433 priv->sta_key_max_num = STA_KEY_MAX_NUM;
2434
2433 priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR; 2435 priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
2434 priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL; 2436 priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL;
2435 priv->hw_params.beacon_time_tsf_bits = IWL3945_EXT_BEACON_TIME_POS; 2437 priv->hw_params.beacon_time_tsf_bits = IWL3945_EXT_BEACON_TIME_POS;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index a67b04b309e0..837406e53b3f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -165,7 +165,7 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
165 } 165 }
166 iwl_clear_ucode_stations(priv, ctx); 166 iwl_clear_ucode_stations(priv, ctx);
167 iwl_restore_stations(priv, ctx); 167 iwl_restore_stations(priv, ctx);
168 ret = iwl_restore_default_wep_keys(priv); 168 ret = iwl_restore_default_wep_keys(priv, ctx);
169 if (ret) { 169 if (ret) {
170 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); 170 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
171 return ret; 171 return ret;
@@ -197,7 +197,7 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
197 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); 197 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
198 iwl_clear_ucode_stations(priv, ctx); 198 iwl_clear_ucode_stations(priv, ctx);
199 iwl_restore_stations(priv, ctx); 199 iwl_restore_stations(priv, ctx);
200 ret = iwl_restore_default_wep_keys(priv); 200 ret = iwl_restore_default_wep_keys(priv, ctx);
201 if (ret) { 201 if (ret) {
202 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); 202 IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
203 return ret; 203 return ret;
@@ -2222,6 +2222,11 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
2222 priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size; 2222 priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size;
2223 priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr; 2223 priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
2224 2224
2225 if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS))
2226 priv->sta_key_max_num = STA_KEY_MAX_NUM;
2227 else
2228 priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
2229
2225 /* Copy images into buffers for card's bus-master reads ... */ 2230 /* Copy images into buffers for card's bus-master reads ... */
2226 2231
2227 /* Runtime instructions (first block of data in file) */ 2232 /* Runtime instructions (first block of data in file) */
@@ -3548,6 +3553,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3548{ 3553{
3549 struct iwl_priv *priv = hw->priv; 3554 struct iwl_priv *priv = hw->priv;
3550 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 3555 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
3556 struct iwl_rxon_context *ctx = vif_priv->ctx;
3551 int ret; 3557 int ret;
3552 u8 sta_id; 3558 u8 sta_id;
3553 bool is_default_wep_key = false; 3559 bool is_default_wep_key = false;
@@ -3576,7 +3582,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3576 key->cipher == WLAN_CIPHER_SUITE_WEP104) && 3582 key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
3577 !sta) { 3583 !sta) {
3578 if (cmd == SET_KEY) 3584 if (cmd == SET_KEY)
3579 is_default_wep_key = !priv->key_mapping_key; 3585 is_default_wep_key = !ctx->key_mapping_keys;
3580 else 3586 else
3581 is_default_wep_key = 3587 is_default_wep_key =
3582 (key->hw_key_idx == HW_KEY_DEFAULT); 3588 (key->hw_key_idx == HW_KEY_DEFAULT);
@@ -3594,9 +3600,9 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3594 break; 3600 break;
3595 case DISABLE_KEY: 3601 case DISABLE_KEY:
3596 if (is_default_wep_key) 3602 if (is_default_wep_key)
3597 ret = iwl_remove_default_wep_key(priv, key); 3603 ret = iwl_remove_default_wep_key(priv, ctx, key);
3598 else 3604 else
3599 ret = iwl_remove_dynamic_key(priv, key, sta_id); 3605 ret = iwl_remove_dynamic_key(priv, ctx, key, sta_id);
3600 3606
3601 IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n"); 3607 IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
3602 break; 3608 break;
@@ -4209,6 +4215,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4209 priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; 4215 priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
4210 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; 4216 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
4211 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; 4217 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
4218 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
4212 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 1); 4219 BUILD_BUG_ON(NUM_IWL_RXON_CTX != 1);
4213 4220
4214 SET_IEEE80211_DEV(hw, &pdev->dev); 4221 SET_IEEE80211_DEV(hw, &pdev->dev);
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 9b535832f117..55779bf0627b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1001,6 +1001,7 @@ struct iwl_qosparam_cmd {
1001#define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000) 1001#define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000)
1002#define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000) 1002#define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000)
1003#define STA_KEY_MAX_NUM 8 1003#define STA_KEY_MAX_NUM 8
1004#define STA_KEY_MAX_NUM_PAN 16
1004 1005
1005/* Flags indicate whether to modify vs. don't change various station params */ 1006/* Flags indicate whether to modify vs. don't change various station params */
1006#define STA_MODIFY_KEY_MASK 0x01 1007#define STA_MODIFY_KEY_MASK 0x01
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index d1400a0926eb..ef7862b5e91c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1133,6 +1133,10 @@ struct iwl_rxon_context {
1133 1133
1134 u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd; 1134 u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd;
1135 u8 qos_cmd; 1135 u8 qos_cmd;
1136 u8 wep_key_cmd;
1137
1138 struct iwl_wep_key wep_keys[WEP_KEYS_MAX];
1139 u8 key_mapping_keys;
1136}; 1140};
1137 1141
1138struct iwl_priv { 1142struct iwl_priv {
@@ -1217,6 +1221,9 @@ struct iwl_priv {
1217 /* command queue number */ 1221 /* command queue number */
1218 u8 cmd_queue; 1222 u8 cmd_queue;
1219 1223
1224 /* max number of station keys */
1225 u8 sta_key_max_num;
1226
1220 /* EEPROM MAC addresses */ 1227 /* EEPROM MAC addresses */
1221 struct mac_address addresses[2]; 1228 struct mac_address addresses[2];
1222 1229
@@ -1296,8 +1303,6 @@ struct iwl_priv {
1296 spinlock_t sta_lock; 1303 spinlock_t sta_lock;
1297 int num_stations; 1304 int num_stations;
1298 struct iwl_station_entry stations[IWL_STATION_COUNT]; 1305 struct iwl_station_entry stations[IWL_STATION_COUNT];
1299 struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; /* protected by mutex */
1300 u8 key_mapping_key;
1301 unsigned long ucode_key_table; 1306 unsigned long ucode_key_table;
1302 1307
1303 /* queue refcounts */ 1308 /* queue refcounts */
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index f5500cc8a44e..ac6e2be35284 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -724,7 +724,7 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
724{ 724{
725 int i; 725 int i;
726 726
727 for (i = 0; i < STA_KEY_MAX_NUM; i++) 727 for (i = 0; i < priv->sta_key_max_num; i++)
728 if (!test_and_set_bit(i, &priv->ucode_key_table)) 728 if (!test_and_set_bit(i, &priv->ucode_key_table))
729 return i; 729 return i;
730 730
@@ -732,7 +732,9 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
732} 732}
733EXPORT_SYMBOL(iwl_get_free_ucode_key_index); 733EXPORT_SYMBOL(iwl_get_free_ucode_key_index);
734 734
735static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) 735static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
736 struct iwl_rxon_context *ctx,
737 bool send_if_empty)
736{ 738{
737 int i, not_empty = 0; 739 int i, not_empty = 0;
738 u8 buff[sizeof(struct iwl_wep_cmd) + 740 u8 buff[sizeof(struct iwl_wep_cmd) +
@@ -740,7 +742,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
740 struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff; 742 struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff;
741 size_t cmd_size = sizeof(struct iwl_wep_cmd); 743 size_t cmd_size = sizeof(struct iwl_wep_cmd);
742 struct iwl_host_cmd cmd = { 744 struct iwl_host_cmd cmd = {
743 .id = REPLY_WEPKEY, 745 .id = ctx->wep_key_cmd,
744 .data = wep_cmd, 746 .data = wep_cmd,
745 .flags = CMD_SYNC, 747 .flags = CMD_SYNC,
746 }; 748 };
@@ -752,16 +754,16 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
752 754
753 for (i = 0; i < WEP_KEYS_MAX ; i++) { 755 for (i = 0; i < WEP_KEYS_MAX ; i++) {
754 wep_cmd->key[i].key_index = i; 756 wep_cmd->key[i].key_index = i;
755 if (priv->wep_keys[i].key_size) { 757 if (ctx->wep_keys[i].key_size) {
756 wep_cmd->key[i].key_offset = i; 758 wep_cmd->key[i].key_offset = i;
757 not_empty = 1; 759 not_empty = 1;
758 } else { 760 } else {
759 wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET; 761 wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
760 } 762 }
761 763
762 wep_cmd->key[i].key_size = priv->wep_keys[i].key_size; 764 wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
763 memcpy(&wep_cmd->key[i].key[3], priv->wep_keys[i].key, 765 memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
764 priv->wep_keys[i].key_size); 766 ctx->wep_keys[i].key_size);
765 } 767 }
766 768
767 wep_cmd->global_key_type = WEP_KEY_WEP_TYPE; 769 wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
@@ -777,15 +779,17 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
777 return 0; 779 return 0;
778} 780}
779 781
780int iwl_restore_default_wep_keys(struct iwl_priv *priv) 782int iwl_restore_default_wep_keys(struct iwl_priv *priv,
783 struct iwl_rxon_context *ctx)
781{ 784{
782 lockdep_assert_held(&priv->mutex); 785 lockdep_assert_held(&priv->mutex);
783 786
784 return iwl_send_static_wepkey_cmd(priv, 0); 787 return iwl_send_static_wepkey_cmd(priv, ctx, false);
785} 788}
786EXPORT_SYMBOL(iwl_restore_default_wep_keys); 789EXPORT_SYMBOL(iwl_restore_default_wep_keys);
787 790
788int iwl_remove_default_wep_key(struct iwl_priv *priv, 791int iwl_remove_default_wep_key(struct iwl_priv *priv,
792 struct iwl_rxon_context *ctx,
789 struct ieee80211_key_conf *keyconf) 793 struct ieee80211_key_conf *keyconf)
790{ 794{
791 int ret; 795 int ret;
@@ -795,13 +799,13 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
795 IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", 799 IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
796 keyconf->keyidx); 800 keyconf->keyidx);
797 801
798 memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); 802 memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
799 if (iwl_is_rfkill(priv)) { 803 if (iwl_is_rfkill(priv)) {
800 IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); 804 IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
801 /* but keys in device are clear anyway so return success */ 805 /* but keys in device are clear anyway so return success */
802 return 0; 806 return 0;
803 } 807 }
804 ret = iwl_send_static_wepkey_cmd(priv, 1); 808 ret = iwl_send_static_wepkey_cmd(priv, ctx, 1);
805 IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", 809 IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
806 keyconf->keyidx, ret); 810 keyconf->keyidx, ret);
807 811
@@ -827,11 +831,11 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
827 keyconf->hw_key_idx = HW_KEY_DEFAULT; 831 keyconf->hw_key_idx = HW_KEY_DEFAULT;
828 priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher; 832 priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
829 833
830 priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; 834 ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
831 memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, 835 memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
832 keyconf->keylen); 836 keyconf->keylen);
833 837
834 ret = iwl_send_static_wepkey_cmd(priv, 0); 838 ret = iwl_send_static_wepkey_cmd(priv, ctx, false);
835 IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n", 839 IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n",
836 keyconf->keylen, keyconf->keyidx, ret); 840 keyconf->keylen, keyconf->keyidx, ret);
837 841
@@ -1029,8 +1033,9 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
1029EXPORT_SYMBOL(iwl_update_tkip_key); 1033EXPORT_SYMBOL(iwl_update_tkip_key);
1030 1034
1031int iwl_remove_dynamic_key(struct iwl_priv *priv, 1035int iwl_remove_dynamic_key(struct iwl_priv *priv,
1032 struct ieee80211_key_conf *keyconf, 1036 struct iwl_rxon_context *ctx,
1033 u8 sta_id) 1037 struct ieee80211_key_conf *keyconf,
1038 u8 sta_id)
1034{ 1039{
1035 unsigned long flags; 1040 unsigned long flags;
1036 u16 key_flags; 1041 u16 key_flags;
@@ -1039,7 +1044,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
1039 1044
1040 lockdep_assert_held(&priv->mutex); 1045 lockdep_assert_held(&priv->mutex);
1041 1046
1042 priv->key_mapping_key--; 1047 ctx->key_mapping_keys--;
1043 1048
1044 spin_lock_irqsave(&priv->sta_lock, flags); 1049 spin_lock_irqsave(&priv->sta_lock, flags);
1045 key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); 1050 key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
@@ -1098,7 +1103,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
1098 1103
1099 lockdep_assert_held(&priv->mutex); 1104 lockdep_assert_held(&priv->mutex);
1100 1105
1101 priv->key_mapping_key++; 1106 ctx->key_mapping_keys++;
1102 keyconf->hw_key_idx = HW_KEY_DYNAMIC; 1107 keyconf->hw_key_idx = HW_KEY_DYNAMIC;
1103 1108
1104 switch (keyconf->cipher) { 1109 switch (keyconf->cipher) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index b7f700638dae..6ab5587870dc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -44,14 +44,16 @@
44 44
45 45
46int iwl_remove_default_wep_key(struct iwl_priv *priv, 46int iwl_remove_default_wep_key(struct iwl_priv *priv,
47 struct iwl_rxon_context *ctx,
47 struct ieee80211_key_conf *key); 48 struct ieee80211_key_conf *key);
48int iwl_set_default_wep_key(struct iwl_priv *priv, 49int iwl_set_default_wep_key(struct iwl_priv *priv,
49 struct iwl_rxon_context *ctx, 50 struct iwl_rxon_context *ctx,
50 struct ieee80211_key_conf *key); 51 struct ieee80211_key_conf *key);
51int iwl_restore_default_wep_keys(struct iwl_priv *priv); 52int iwl_restore_default_wep_keys(struct iwl_priv *priv,
53 struct iwl_rxon_context *ctx);
52int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, 54int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
53 struct ieee80211_key_conf *key, u8 sta_id); 55 struct ieee80211_key_conf *key, u8 sta_id);
54int iwl_remove_dynamic_key(struct iwl_priv *priv, 56int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
55 struct ieee80211_key_conf *key, u8 sta_id); 57 struct ieee80211_key_conf *key, u8 sta_id);
56void iwl_update_tkip_key(struct iwl_priv *priv, 58void iwl_update_tkip_key(struct iwl_priv *priv,
57 struct iwl_rxon_context *ctx, 59 struct iwl_rxon_context *ctx,
@@ -97,20 +99,25 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
97static inline void iwl_clear_driver_stations(struct iwl_priv *priv) 99static inline void iwl_clear_driver_stations(struct iwl_priv *priv)
98{ 100{
99 unsigned long flags; 101 unsigned long flags;
102 struct iwl_rxon_context *ctx;
100 103
101 spin_lock_irqsave(&priv->sta_lock, flags); 104 spin_lock_irqsave(&priv->sta_lock, flags);
102 memset(priv->stations, 0, sizeof(priv->stations)); 105 memset(priv->stations, 0, sizeof(priv->stations));
103 priv->num_stations = 0; 106 priv->num_stations = 0;
104 107
105 /*
106 * Remove all key information that is not stored as part of station
107 * information since mac80211 may not have had a
108 * chance to remove all the keys. When device is reconfigured by
109 * mac80211 after an error all keys will be reconfigured.
110 */
111 priv->ucode_key_table = 0; 108 priv->ucode_key_table = 0;
112 priv->key_mapping_key = 0; 109
113 memset(priv->wep_keys, 0, sizeof(priv->wep_keys)); 110 for_each_context(priv, ctx) {
111 /*
112 * Remove all key information that is not stored as part
113 * of station information since mac80211 may not have had
114 * a chance to remove all the keys. When device is
115 * reconfigured by mac80211 after an error all keys will
116 * be reconfigured.
117 */
118 memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
119 ctx->key_mapping_keys = 0;
120 }
114 121
115 spin_unlock_irqrestore(&priv->sta_lock, flags); 122 spin_unlock_irqrestore(&priv->sta_lock, flags);
116} 123}
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 29d13765ff66..be48f7977278 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4022,6 +4022,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4022 priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; 4022 priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
4023 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; 4023 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
4024 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; 4024 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
4025 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
4025 4026
4026 /* 4027 /*
4027 * Disabling hardware scan means that mac80211 will perform scans 4028 * Disabling hardware scan means that mac80211 will perform scans