Skip to content

Commit

Permalink
iwlwifi: maintain uCode key table state
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Emmanuel Grumbach authored and John W. Linville committed Apr 16, 2008
1 parent 0211ddd commit 80fb47a
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 6 deletions.
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/iwl-4965.h
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,7 @@ struct iwl_priv {
struct iwl_wep_key wep_keys[WEP_KEYS_MAX];
u8 default_wep_key;
u8 key_mapping_key;
unsigned long ucode_key_table;

/* Indication if ieee80211_ops->open has been called */
u8 is_open;
Expand Down
28 changes: 25 additions & 3 deletions drivers/net/wireless/iwlwifi/iwl-sta.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@
#include "iwl-io.h"
#include "iwl-helpers.h"
#include "iwl-4965.h"
#include "iwl-sta.h"

int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
int i;

for (i = 0; i < STA_KEY_MAX_NUM; i++)
if (test_and_set_bit(i, &priv->ucode_key_table))
return i;

return -1;
}

int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
{
Expand Down Expand Up @@ -81,14 +93,19 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
}

int iwl_remove_default_wep_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key)
struct ieee80211_key_conf *keyconf)
{
int ret;
unsigned long flags;

spin_lock_irqsave(&priv->sta_lock, flags);

if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table))
IWL_ERROR("index %d not used in uCode key table.\n",
keyconf->keyidx);

priv->default_wep_key--;
memset(&priv->wep_keys[key->keyidx], 0, sizeof(priv->wep_keys[0]));
memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
ret = iwl_send_static_wepkey_cmd(priv, 1);
spin_unlock_irqrestore(&priv->sta_lock, flags);

Expand All @@ -108,6 +125,10 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
spin_lock_irqsave(&priv->sta_lock, flags);
priv->default_wep_key++;

if (test_and_set_bit(keyconf->keyidx, &priv->ucode_key_table))
IWL_ERROR("index %d already used in uCode key table.\n",
keyconf->keyidx);

priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key,
keyconf->keylen);
Expand Down Expand Up @@ -151,7 +172,8 @@ int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
memcpy(&priv->stations[sta_id].sta.key.key[3],
keyconf->key, keyconf->keylen);

priv->stations[sta_id].sta.key.key_offset = sta_id % 8; /* FIXME */
priv->stations[sta_id].sta.key.key_offset =
iwl_get_free_ucode_key_index(priv);
priv->stations[sta_id].sta.key.key_flags = key_flags;

priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/iwl-sta.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "iwl-io.h"
#include "iwl-helpers.h"

int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty);
int iwl_remove_default_wep_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key);
Expand Down
10 changes: 7 additions & 3 deletions drivers/net/wireless/iwlwifi/iwl4965-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1140,8 +1140,8 @@ static int iwl4965_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
keyconf->keylen);

priv->stations[sta_id].sta.key.key_offset
= (sta_id % STA_KEY_MAX_NUM);/*FIXME*/
priv->stations[sta_id].sta.key.key_offset =
iwl_get_free_ucode_key_index(priv);
priv->stations[sta_id].sta.key.key_flags = key_flags;
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
Expand Down Expand Up @@ -1187,6 +1187,10 @@ static int iwl4965_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
priv->key_mapping_key = 0;

spin_lock_irqsave(&priv->sta_lock, flags);
if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
&priv->ucode_key_table))
IWL_ERROR("index %d not used in uCode key table.\n",
priv->stations[sta_id].sta.key.key_offset);
memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl4965_hw_key));
memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl4965_keyinfo));
priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
Expand Down Expand Up @@ -6971,7 +6975,7 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
spin_lock_irqsave(&priv->sta_lock, flags);

priv->stations[sta_id].sta.key.key_offset =
(sta_id % STA_KEY_MAX_NUM);/* FIXME */
iwl_get_free_ucode_key_index(priv);
priv->stations[sta_id].sta.key.key_flags = key_flags;
priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;

Expand Down

0 comments on commit 80fb47a

Please sign in to comment.