Commit 0a0755c9 authored by David S. Miller's avatar David S. Miller
parents a6af2d6b cde6901b
...@@ -3897,6 +3897,7 @@ static int ipw_disassociate(void *data) ...@@ -3897,6 +3897,7 @@ static int ipw_disassociate(void *data)
if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
return 0; return 0;
ipw_send_disassociate(data, 0); ipw_send_disassociate(data, 0);
netif_carrier_off(priv->net_dev);
return 1; return 1;
} }
...@@ -10190,6 +10191,9 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, ...@@ -10190,6 +10191,9 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
u16 remaining_bytes; u16 remaining_bytes;
int fc; int fc;
if (!(priv->status & STATUS_ASSOCIATED))
goto drop;
hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
switch (priv->ieee->iw_mode) { switch (priv->ieee->iw_mode) {
case IW_MODE_ADHOC: case IW_MODE_ADHOC:
......
...@@ -290,6 +290,9 @@ void iwl_clear_stations_table(struct iwl_priv *priv) ...@@ -290,6 +290,9 @@ void iwl_clear_stations_table(struct iwl_priv *priv)
priv->num_stations = 0; priv->num_stations = 0;
memset(priv->stations, 0, sizeof(priv->stations)); memset(priv->stations, 0, sizeof(priv->stations));
/* clean ucode key table bit map */
priv->ucode_key_table = 0;
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
} }
EXPORT_SYMBOL(iwl_clear_stations_table); EXPORT_SYMBOL(iwl_clear_stations_table);
......
...@@ -475,7 +475,7 @@ static int iwl_get_free_ucode_key_index(struct iwl_priv *priv) ...@@ -475,7 +475,7 @@ static int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
if (!test_and_set_bit(i, &priv->ucode_key_table)) if (!test_and_set_bit(i, &priv->ucode_key_table))
return i; return i;
return -1; return WEP_INVALID_OFFSET;
} }
int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
...@@ -620,6 +620,9 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, ...@@ -620,6 +620,9 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
/* else, we are overriding an existing key => no need to allocated room /* else, we are overriding an existing key => no need to allocated room
* in uCode. */ * in uCode. */
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
"no space for new kew");
priv->stations[sta_id].sta.key.key_flags = key_flags; 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.sta.modify_mask = STA_MODIFY_KEY_MASK;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
...@@ -637,6 +640,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, ...@@ -637,6 +640,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
{ {
unsigned long flags; unsigned long flags;
__le16 key_flags = 0; __le16 key_flags = 0;
int ret;
key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
...@@ -664,14 +668,18 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, ...@@ -664,14 +668,18 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
/* else, we are overriding an existing key => no need to allocated room /* else, we are overriding an existing key => no need to allocated room
* in uCode. */ * in uCode. */
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
"no space for new kew");
priv->stations[sta_id].sta.key.key_flags = key_flags; 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.sta.modify_mask = STA_MODIFY_KEY_MASK;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); return ret;
return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
} }
static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
...@@ -696,6 +704,9 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, ...@@ -696,6 +704,9 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
/* else, we are overriding an existing key => no need to allocated room /* else, we are overriding an existing key => no need to allocated room
* in uCode. */ * in uCode. */
WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
"no space for new kew");
/* This copy is acutally not needed: we get the key with each TX */ /* This copy is acutally not needed: we get the key with each TX */
memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
...@@ -734,6 +745,13 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, ...@@ -734,6 +745,13 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
return 0; return 0;
} }
if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
IWL_WARNING("Removing wrong key %d 0x%x\n",
keyconf->keyidx, key_flags);
spin_unlock_irqrestore(&priv->sta_lock, flags);
return 0;
}
if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset,
&priv->ucode_key_table)) &priv->ucode_key_table))
IWL_ERROR("index %d not used in uCode key table.\n", IWL_ERROR("index %d not used in uCode key table.\n",
......
...@@ -615,7 +615,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, ...@@ -615,7 +615,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
struct ieee80211_hdr *tx_hdr; struct ieee80211_hdr *tx_hdr;
tx_hdr = (struct ieee80211_hdr *)skb->data; tx_hdr = (struct ieee80211_hdr *)skb->data;
if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1))) if (likely(!memcmp(tx_hdr->addr2, rx_hdr->addr1, ETH_ALEN)))
{ {
__skb_unlink(skb, q); __skb_unlink(skb, q);
tx_status(hw, skb, IEEE80211_TX_STAT_ACK, stats->signal, 1); tx_status(hw, skb, IEEE80211_TX_STAT_ACK, stats->signal, 1);
......
...@@ -99,7 +99,7 @@ struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr) ...@@ -99,7 +99,7 @@ struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr)
sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
while (sta) { while (sta) {
if (compare_ether_addr(sta->sta.addr, addr) == 0) if (memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
break; break;
sta = rcu_dereference(sta->hnext); sta = rcu_dereference(sta->hnext);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment