diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2008-04-15 00:16:08 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-04-16 15:59:58 -0400 |
commit | 80fb47a11eaf3d1d70c02f3dc7976eaac9b0eef2 (patch) | |
tree | b9d94392f6e9ca2f98b85ab9b968656b71cc50e8 /drivers/net/wireless/iwlwifi | |
parent | 0211ddda9deb681a804572936cd49e466a1aa88b (diff) |
iwlwifi: maintain uCode key table state
This patch fix book keeping of key table in the driver
to be synchronized with uCode
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 10 |
4 files changed, 34 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 23ab5236504..daf157adf24 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h | |||
@@ -1116,6 +1116,7 @@ struct iwl_priv { | |||
1116 | struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; | 1116 | struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; |
1117 | u8 default_wep_key; | 1117 | u8 default_wep_key; |
1118 | u8 key_mapping_key; | 1118 | u8 key_mapping_key; |
1119 | unsigned long ucode_key_table; | ||
1119 | 1120 | ||
1120 | /* Indication if ieee80211_ops->open has been called */ | 1121 | /* Indication if ieee80211_ops->open has been called */ |
1121 | u8 is_open; | 1122 | u8 is_open; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index cb964196ad2..41238f208ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -36,6 +36,18 @@ | |||
36 | #include "iwl-io.h" | 36 | #include "iwl-io.h" |
37 | #include "iwl-helpers.h" | 37 | #include "iwl-helpers.h" |
38 | #include "iwl-4965.h" | 38 | #include "iwl-4965.h" |
39 | #include "iwl-sta.h" | ||
40 | |||
41 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv) | ||
42 | { | ||
43 | int i; | ||
44 | |||
45 | for (i = 0; i < STA_KEY_MAX_NUM; i++) | ||
46 | if (test_and_set_bit(i, &priv->ucode_key_table)) | ||
47 | return i; | ||
48 | |||
49 | return -1; | ||
50 | } | ||
39 | 51 | ||
40 | int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) | 52 | int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) |
41 | { | 53 | { |
@@ -81,14 +93,19 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) | |||
81 | } | 93 | } |
82 | 94 | ||
83 | int iwl_remove_default_wep_key(struct iwl_priv *priv, | 95 | int iwl_remove_default_wep_key(struct iwl_priv *priv, |
84 | struct ieee80211_key_conf *key) | 96 | struct ieee80211_key_conf *keyconf) |
85 | { | 97 | { |
86 | int ret; | 98 | int ret; |
87 | unsigned long flags; | 99 | unsigned long flags; |
88 | 100 | ||
89 | spin_lock_irqsave(&priv->sta_lock, flags); | 101 | spin_lock_irqsave(&priv->sta_lock, flags); |
102 | |||
103 | if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table)) | ||
104 | IWL_ERROR("index %d not used in uCode key table.\n", | ||
105 | keyconf->keyidx); | ||
106 | |||
90 | priv->default_wep_key--; | 107 | priv->default_wep_key--; |
91 | memset(&priv->wep_keys[key->keyidx], 0, sizeof(priv->wep_keys[0])); | 108 | memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); |
92 | ret = iwl_send_static_wepkey_cmd(priv, 1); | 109 | ret = iwl_send_static_wepkey_cmd(priv, 1); |
93 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 110 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
94 | 111 | ||
@@ -108,6 +125,10 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, | |||
108 | spin_lock_irqsave(&priv->sta_lock, flags); | 125 | spin_lock_irqsave(&priv->sta_lock, flags); |
109 | priv->default_wep_key++; | 126 | priv->default_wep_key++; |
110 | 127 | ||
128 | if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table)) | ||
129 | IWL_ERROR("index %d already used in uCode key table.\n", | ||
130 | keyconf->keyidx); | ||
131 | |||
111 | priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; | 132 | priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; |
112 | memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, | 133 | memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, |
113 | keyconf->keylen); | 134 | keyconf->keylen); |
@@ -151,7 +172,8 @@ int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, | |||
151 | memcpy(&priv->stations[sta_id].sta.key.key[3], | 172 | memcpy(&priv->stations[sta_id].sta.key.key[3], |
152 | keyconf->key, keyconf->keylen); | 173 | keyconf->key, keyconf->keylen); |
153 | 174 | ||
154 | priv->stations[sta_id].sta.key.key_offset = sta_id % 8; /* FIXME */ | 175 | priv->stations[sta_id].sta.key.key_offset = |
176 | iwl_get_free_ucode_key_index(priv); | ||
155 | priv->stations[sta_id].sta.key.key_flags = key_flags; | 177 | priv->stations[sta_id].sta.key.key_flags = key_flags; |
156 | 178 | ||
157 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 179 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 78e0254c93b..3f1b2053439 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "iwl-io.h" | 37 | #include "iwl-io.h" |
38 | #include "iwl-helpers.h" | 38 | #include "iwl-helpers.h" |
39 | 39 | ||
40 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv); | ||
40 | int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty); | 41 | int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty); |
41 | int iwl_remove_default_wep_key(struct iwl_priv *priv, | 42 | int iwl_remove_default_wep_key(struct iwl_priv *priv, |
42 | struct ieee80211_key_conf *key); | 43 | struct ieee80211_key_conf *key); |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 37ab1c565ce..da01896bd40 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -1140,8 +1140,8 @@ static int iwl4965_set_ccmp_dynamic_key_info(struct iwl_priv *priv, | |||
1140 | memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, | 1140 | memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, |
1141 | keyconf->keylen); | 1141 | keyconf->keylen); |
1142 | 1142 | ||
1143 | priv->stations[sta_id].sta.key.key_offset | 1143 | priv->stations[sta_id].sta.key.key_offset = |
1144 | = (sta_id % STA_KEY_MAX_NUM);/*FIXME*/ | 1144 | iwl_get_free_ucode_key_index(priv); |
1145 | priv->stations[sta_id].sta.key.key_flags = key_flags; | 1145 | priv->stations[sta_id].sta.key.key_flags = key_flags; |
1146 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 1146 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
1147 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 1147 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
@@ -1187,6 +1187,10 @@ static int iwl4965_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) | |||
1187 | priv->key_mapping_key = 0; | 1187 | priv->key_mapping_key = 0; |
1188 | 1188 | ||
1189 | spin_lock_irqsave(&priv->sta_lock, flags); | 1189 | spin_lock_irqsave(&priv->sta_lock, flags); |
1190 | if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, | ||
1191 | &priv->ucode_key_table)) | ||
1192 | IWL_ERROR("index %d not used in uCode key table.\n", | ||
1193 | priv->stations[sta_id].sta.key.key_offset); | ||
1190 | memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl4965_hw_key)); | 1194 | memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl4965_hw_key)); |
1191 | memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl4965_keyinfo)); | 1195 | memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl4965_keyinfo)); |
1192 | priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; | 1196 | priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; |
@@ -6971,7 +6975,7 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, | |||
6971 | spin_lock_irqsave(&priv->sta_lock, flags); | 6975 | spin_lock_irqsave(&priv->sta_lock, flags); |
6972 | 6976 | ||
6973 | priv->stations[sta_id].sta.key.key_offset = | 6977 | priv->stations[sta_id].sta.key.key_offset = |
6974 | (sta_id % STA_KEY_MAX_NUM);/* FIXME */ | 6978 | iwl_get_free_ucode_key_index(priv); |
6975 | priv->stations[sta_id].sta.key.key_flags = key_flags; | 6979 | priv->stations[sta_id].sta.key.key_flags = key_flags; |
6976 | priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; | 6980 | priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; |
6977 | 6981 | ||