2008-04-17 23:03:41

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 0/5] iwlwifi driver updates

This series continues to stabilize the HW crypto work. There are
a few patches related to the architecture changes.
The final patch fixes debugging output.

[PATCH 1/5] iwlwifi: HW crypto acceleration fixes
[PATCH 2/5] iwlwifi: arranging aggregation actions
[PATCH 3/5] iwlwifi: define ANA_PLL values in iwl-csr.h
[PATCH 4/5] iwlwifi: export int iwl4965_set_pwr_src
[PATCH 5/5] iwlwifi: fix debug messages during scanning

Thank you

Reinette



2008-04-17 23:03:42

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 1/5] iwlwifi: HW crypto acceleration fixes

From: Emmanuel Grumbach <[email protected]>

This patch fixes several issues in security:

1) the uCode doesn't know about TKIP-MMIC failure, if uCode set
RX_RES_STATUS_BAD_ICV_MIC, it means ICV failure: drop the packet silently.
2) do not allocate room in the key table of the uCode is the set_key call
is a replacement of an old key
3) check the keyidx of the key in the uCode before removing it upon
disable_key call

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 53 ++++++++++++++++++++++++++-
drivers/net/wireless/iwlwifi/iwl-4965.h | 3 --
drivers/net/wireless/iwlwifi/iwl-sta.c | 53 ++++++++++++++++++++++-----
drivers/net/wireless/iwlwifi/iwl-sta.h | 3 +-
drivers/net/wireless/iwlwifi/iwl4965-base.c | 41 +--------------------
5 files changed, 98 insertions(+), 55 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 69a355b..ddcd1b2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2871,6 +2871,53 @@ static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len)
priv->rx_stats[idx].bytes += len;
}

+/*
+ * returns non-zero if packet should be dropped
+ */
+static int iwl4965_set_decrypted_flag(struct iwl_priv *priv,
+ struct ieee80211_hdr *hdr,
+ u32 decrypt_res,
+ struct ieee80211_rx_status *stats)
+{
+ u16 fc = le16_to_cpu(hdr->frame_control);
+
+ if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
+ return 0;
+
+ if (!(fc & IEEE80211_FCTL_PROTECTED))
+ return 0;
+
+ IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
+ switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
+ case RX_RES_STATUS_SEC_TYPE_TKIP:
+ /* The uCode has got a bad phase 1 Key, pushes the packet.
+ * Decryption will be done in SW. */
+ if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
+ RX_RES_STATUS_BAD_KEY_TTAK)
+ break;
+
+ if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
+ RX_RES_STATUS_BAD_ICV_MIC) {
+ /* bad ICV, the packet is destroyed since the
+ * decryption is inplace, drop it */
+ IWL_DEBUG_RX("Packet destroyed\n");
+ return -1;
+ }
+ case RX_RES_STATUS_SEC_TYPE_WEP:
+ case RX_RES_STATUS_SEC_TYPE_CCMP:
+ if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
+ RX_RES_STATUS_DECRYPT_OK) {
+ IWL_DEBUG_RX("hw decrypt successfully!!!\n");
+ stats->flag |= RX_FLAG_DECRYPTED;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
static u32 iwl4965_translate_rx_status(u32 decrypt_in)
{
u32 decrypt_out = 0;
@@ -3000,8 +3047,10 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
stats->flag = 0;
hdr = (struct ieee80211_hdr *)rxb->skb->data;

- if (!priv->cfg->mod_params->sw_crypto)
- iwl4965_set_decrypted_flag(priv, rxb->skb, ampdu_status, stats);
+ /* in case of HW accelerated crypto and bad decryption, drop */
+ if (!priv->cfg->mod_params->sw_crypto &&
+ iwl4965_set_decrypted_flag(priv, hdr, ampdu_status, stats))
+ return;

if (priv->add_radiotap)
iwl4965_add_radiotap(priv, rxb->skb, rx_start, stats, ampdu_status);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h
index 547c313..8672c88 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.h
@@ -673,9 +673,6 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
const u8 *dest, int left);
extern int iwl4965_rx_queue_update_write_ptr(struct iwl_priv *priv,
struct iwl4965_rx_queue *q);
-extern void iwl4965_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
- u32 decrypt_res,
- struct ieee80211_rx_status *stats);
extern __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr);
int iwl4965_init_geos(struct iwl_priv *priv);
void iwl4965_free_geos(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index fa463ce..d39ac1c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -207,10 +207,14 @@ static 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 =
+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ == STA_KEY_FLG_NO_ENC)
+ 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;
+ /* else, we are overriding an existing key => no need to allocated room
+ * in uCode. */

+ 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;

@@ -249,8 +253,13 @@ static int iwl_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 =
- iwl_get_free_ucode_key_index(priv);
+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ == STA_KEY_FLG_NO_ENC)
+ priv->stations[sta_id].sta.key.key_offset =
+ iwl_get_free_ucode_key_index(priv);
+ /* else, we are overriding an existing key => no need to allocated room
+ * in uCode. */
+
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;
@@ -278,8 +287,13 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
priv->stations[sta_id].keyinfo.alg = keyconf->alg;
priv->stations[sta_id].keyinfo.conf = keyconf;
priv->stations[sta_id].keyinfo.keylen = 16;
- priv->stations[sta_id].sta.key.key_offset =
+
+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ == STA_KEY_FLG_NO_ENC)
+ priv->stations[sta_id].sta.key.key_offset =
iwl_get_free_ucode_key_index(priv);
+ /* else, we are overriding an existing key => no need to allocated room
+ * in uCode. */

/* This copy is acutally not needed: we get the key with each TX */
memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16);
@@ -291,13 +305,31 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
return ret;
}

-int iwl_remove_dynamic_key(struct iwl_priv *priv, u8 sta_id)
+int iwl_remove_dynamic_key(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
unsigned long flags;
+ int ret = 0;
+ u16 key_flags;
+ u8 keyidx;

priv->key_mapping_key = 0;

spin_lock_irqsave(&priv->sta_lock, flags);
+ key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
+ keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
+
+ if (keyconf->keyidx != keyidx) {
+ /* We need to remove a key with index different that the one
+ * in the uCode. This means that the key we need to remove has
+ * been replaced by another one with different index.
+ * Don't do anything and return ok
+ */
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return 0;
+ }
+
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",
@@ -306,13 +338,16 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, u8 sta_id)
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;
+ priv->stations[sta_id].sta.key.key_flags =
+ STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
+ priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
- spin_unlock_irqrestore(&priv->sta_lock, flags);

IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
- return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0);
+ ret = iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0);
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return ret;
}

int iwl_set_dynamic_key(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 44f272e..8955835 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -43,7 +43,8 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key);
int iwl_set_default_wep_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key);
-int iwl_remove_dynamic_key(struct iwl_priv *priv, u8 sta_id);
int iwl_set_dynamic_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key, u8 sta_id);
+int iwl_remove_dynamic_key(struct iwl_priv *priv,
+ struct ieee80211_key_conf *key, u8 sta_id);
#endif /* __iwl_sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 2dc4960..fe340fd 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -2456,45 +2456,6 @@ void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
return;
}

-void iwl4965_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
- u32 decrypt_res, struct ieee80211_rx_status *stats)
-{
- u16 fc =
- le16_to_cpu(((struct ieee80211_hdr *)skb->data)->frame_control);
-
- if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
- return;
-
- if (!(fc & IEEE80211_FCTL_PROTECTED))
- return;
-
- IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
- switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
- case RX_RES_STATUS_SEC_TYPE_TKIP:
- /* The uCode has got a bad phase 1 Key, pushes the packet.
- * Decryption will be done in SW. */
- if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
- RX_RES_STATUS_BAD_KEY_TTAK)
- break;
-
- if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
- RX_RES_STATUS_BAD_ICV_MIC)
- stats->flag |= RX_FLAG_MMIC_ERROR;
- case RX_RES_STATUS_SEC_TYPE_WEP:
- case RX_RES_STATUS_SEC_TYPE_CCMP:
- if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
- RX_RES_STATUS_DECRYPT_OK) {
- IWL_DEBUG_RX("hw decrypt successfully!!!\n");
- stats->flag |= RX_FLAG_DECRYPTED;
- }
- break;
-
- default:
- break;
- }
-}
-
-
#define IWL_PACKET_RETRY_TIME HZ

int iwl4965_is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
@@ -6874,7 +6835,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (is_default_wep_key)
ret = iwl_remove_default_wep_key(priv, key);
else
- ret = iwl_remove_dynamic_key(priv, sta_id);
+ ret = iwl_remove_dynamic_key(priv, key, sta_id);

IWL_DEBUG_MAC80211("disable hwcrypto key\n");
break;
--
1.5.3.4


2008-04-17 23:03:42

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 4/5] iwlwifi: export int iwl4965_set_pwr_src

From: Tomas Winkler <[email protected]>

This handler is universal for most of the HW

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-4965.h | 2 ++
2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 890dfa4..2b9471f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -492,7 +492,7 @@ int iwl4965_hw_rxq_stop(struct iwl_priv *priv)
return 0;
}

-static int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
+int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
{
int ret;
unsigned long flags;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h
index 8672c88..b8c86c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.h
@@ -674,6 +674,8 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
extern int iwl4965_rx_queue_update_write_ptr(struct iwl_priv *priv,
struct iwl4965_rx_queue *q);
extern __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr);
+int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
+
int iwl4965_init_geos(struct iwl_priv *priv);
void iwl4965_free_geos(struct iwl_priv *priv);

--
1.5.3.4


2008-04-17 23:03:43

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 5/5] iwlwifi: fix debug messages during scanning

From: Bill Moss <[email protected]>

direct_mask will be set when we are not associated and requesting a
direct scan. The second debug print will be confusing as priv->essid
is not set at that time and it will thus print "<hidden>" while it is
known to which AP a direct scan is requested - as previous debug message
also indicates.

Now make all debugging consistent.

Signed-off-by: Bill Moss <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl3945-base.c | 16 ++++++++--------
drivers/net/wireless/iwlwifi/iwl4965-base.c | 13 ++++++-------
2 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 1a5678f..1351e91 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -6303,12 +6303,17 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
priv->direct_ssid, priv->direct_ssid_len);
direct_mask = 1;
} else if (!iwl3945_is_associated(priv) && priv->essid_len) {
+ IWL_DEBUG_SCAN
+ ("Kicking off one direct scan for '%s' when not associated\n",
+ iwl3945_escape_essid(priv->essid, priv->essid_len));
scan->direct_scan[0].id = WLAN_EID_SSID;
scan->direct_scan[0].len = priv->essid_len;
memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
direct_mask = 1;
- } else
+ } else {
+ IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");
direct_mask = 0;
+ }

/* We don't build a direct scan probe request; the uCode will do
* that based on the direct_mask added to each channel entry */
@@ -6346,23 +6351,18 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
scan->filter_flags = RXON_FILTER_PROMISC_MSK;

- if (direct_mask) {
- IWL_DEBUG_SCAN
- ("Initiating direct scan for %s.\n",
- iwl3945_escape_essid(priv->essid, priv->essid_len));
+ if (direct_mask)
scan->channel_count =
iwl3945_get_channels_for_scan(
priv, band, 1, /* active */
direct_mask,
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
- } else {
- IWL_DEBUG_SCAN("Initiating indirect scan.\n");
+ else
scan->channel_count =
iwl3945_get_channels_for_scan(
priv, band, 0, /* passive */
direct_mask,
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
- }

cmd.len += le16_to_cpu(scan->tx_cmd.len) +
scan->channel_count * sizeof(struct iwl3945_scan_channel);
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index fe340fd..7f1a743 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -5775,11 +5775,15 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
priv->direct_ssid, priv->direct_ssid_len);
direct_mask = 1;
} else if (!iwl_is_associated(priv) && priv->essid_len) {
+ IWL_DEBUG_SCAN
+ ("Kicking off one direct scan for '%s' when not associated\n",
+ iwl4965_escape_essid(priv->essid, priv->essid_len));
scan->direct_scan[0].id = WLAN_EID_SSID;
scan->direct_scan[0].len = priv->essid_len;
memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
direct_mask = 1;
} else {
+ IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");
direct_mask = 0;
}

@@ -5832,23 +5836,18 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
scan->filter_flags = RXON_FILTER_PROMISC_MSK;

- if (direct_mask) {
- IWL_DEBUG_SCAN
- ("Initiating direct scan for %s.\n",
- iwl4965_escape_essid(priv->essid, priv->essid_len));
+ if (direct_mask)
scan->channel_count =
iwl4965_get_channels_for_scan(
priv, band, 1, /* active */
direct_mask,
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
- } else {
- IWL_DEBUG_SCAN("Initiating indirect scan.\n");
+ else
scan->channel_count =
iwl4965_get_channels_for_scan(
priv, band, 0, /* passive */
direct_mask,
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
- }

cmd.len += le16_to_cpu(scan->tx_cmd.len) +
scan->channel_count * sizeof(struct iwl4965_scan_channel);
--
1.5.3.4


2008-04-17 23:03:42

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 2/5] iwlwifi: arranging aggregation actions

From: Ron Rindjunsky <[email protected]>

This patch makes some renaming of the ampdu_action functions inside
iwlwifi, and adds checks for correct station id in Rx flows

Signed-off-by: Ron Rindjunsky <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 70 ++++++++++++++++--------------
1 files changed, 37 insertions(+), 33 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index ddcd1b2..890dfa4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -4063,10 +4063,15 @@ void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index,
return;
}

-static void iwl4965_sta_modify_add_ba_tid(struct iwl_priv *priv,
- int sta_id, int tid, u16 ssn)
+static int iwl4965_rx_agg_start(struct iwl_priv *priv,
+ const u8 *addr, int tid, u16 ssn)
{
unsigned long flags;
+ int sta_id;
+
+ sta_id = iwl_find_station(priv, addr);
+ if (sta_id == IWL_INVALID_STATION)
+ return -ENXIO;

spin_lock_irqsave(&priv->sta_lock, flags);
priv->stations[sta_id].sta.station_flags_msk = 0;
@@ -4076,13 +4081,19 @@ static void iwl4965_sta_modify_add_ba_tid(struct iwl_priv *priv,
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
spin_unlock_irqrestore(&priv->sta_lock, flags);

- iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+ return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta,
+ CMD_ASYNC);
}

-static void iwl4965_sta_modify_del_ba_tid(struct iwl_priv *priv,
- int sta_id, int tid)
+static int iwl4965_rx_agg_stop(struct iwl_priv *priv,
+ const u8 *addr, int tid)
{
unsigned long flags;
+ int sta_id;
+
+ sta_id = iwl_find_station(priv, addr);
+ if (sta_id == IWL_INVALID_STATION)
+ return -ENXIO;

spin_lock_irqsave(&priv->sta_lock, flags);
priv->stations[sta_id].sta.station_flags_msk = 0;
@@ -4091,7 +4102,8 @@ static void iwl4965_sta_modify_del_ba_tid(struct iwl_priv *priv,
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
spin_unlock_irqrestore(&priv->sta_lock, flags);

- iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
+ return iwl4965_send_add_station(priv, &priv->stations[sta_id].sta,
+ CMD_ASYNC);
}

/*
@@ -4110,8 +4122,8 @@ static int iwl4965_txq_ctx_activate_free(struct iwl_priv *priv)
return -1;
}

-static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
- u16 tid, u16 *start_seq_num)
+static int iwl4965_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra,
+ u16 tid, u16 *start_seq_num)
{
struct iwl_priv *priv = hw->priv;
int sta_id;
@@ -4128,10 +4140,10 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
else
return -EINVAL;

- IWL_WARNING("%s on da = %s tid = %d\n",
- __func__, print_mac(mac, da), tid);
+ IWL_WARNING("%s on ra = %s tid = %d\n",
+ __func__, print_mac(mac, ra), tid);

- sta_id = iwl_find_station(priv, da);
+ sta_id = iwl_find_station(priv, ra);
if (sta_id == IWL_INVALID_STATION)
return -ENXIO;

@@ -4160,7 +4172,7 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
if (tid_data->tfds_in_queue == 0) {
printk(KERN_ERR "HW queue is empty\n");
tid_data->agg.state = IWL_AGG_ON;
- ieee80211_start_tx_ba_cb_irqsafe(hw, da, tid);
+ ieee80211_start_tx_ba_cb_irqsafe(hw, ra, tid);
} else {
IWL_DEBUG_HT("HW queue is NOT empty: %d packets in HW queue\n",
tid_data->tfds_in_queue);
@@ -4169,10 +4181,8 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
return ret;
}

-static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
- u16 tid)
+static int iwl4965_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid)
{
-
struct iwl_priv *priv = hw->priv;
int tx_fifo_id, txq_id, sta_id, ssn = -1;
struct iwl4965_tid_data *tid_data;
@@ -4180,8 +4190,8 @@ static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
unsigned long flags;
DECLARE_MAC_BUF(mac);

- if (!da) {
- IWL_ERROR("da = NULL\n");
+ if (!ra) {
+ IWL_ERROR("ra = NULL\n");
return -EINVAL;
}

@@ -4190,7 +4200,7 @@ static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
else
return -EINVAL;

- sta_id = iwl_find_station(priv, da);
+ sta_id = iwl_find_station(priv, ra);

if (sta_id == IWL_INVALID_STATION)
return -ENXIO;
@@ -4212,7 +4222,7 @@ static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
return 0;
}

- IWL_DEBUG_HT("HW queue empty\n");;
+ IWL_DEBUG_HT("HW queue is empty\n");
priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;

spin_lock_irqsave(&priv->lock, flags);
@@ -4222,10 +4232,7 @@ static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
if (ret)
return ret;

- ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, da, tid);
-
- IWL_DEBUG_INFO("iwl4965_mac_ht_tx_agg_stop on da=%s tid=%d\n",
- print_mac(mac, da), tid);
+ ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, ra, tid);

return 0;
}
@@ -4235,27 +4242,24 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
const u8 *addr, u16 tid, u16 *ssn)
{
struct iwl_priv *priv = hw->priv;
- int sta_id;
DECLARE_MAC_BUF(mac);

- IWL_DEBUG_HT("A-MPDU action on da=%s tid=%d ",
- print_mac(mac, addr), tid);
- sta_id = iwl_find_station(priv, addr);
+ IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n",
+ print_mac(mac, addr), tid);
+
switch (action) {
case IEEE80211_AMPDU_RX_START:
IWL_DEBUG_HT("start Rx\n");
- iwl4965_sta_modify_add_ba_tid(priv, sta_id, tid, *ssn);
- break;
+ return iwl4965_rx_agg_start(priv, addr, tid, *ssn);
case IEEE80211_AMPDU_RX_STOP:
IWL_DEBUG_HT("stop Rx\n");
- iwl4965_sta_modify_del_ba_tid(priv, sta_id, tid);
- break;
+ return iwl4965_rx_agg_stop(priv, addr, tid);
case IEEE80211_AMPDU_TX_START:
IWL_DEBUG_HT("start Tx\n");
- return iwl4965_mac_ht_tx_agg_start(hw, addr, tid, ssn);
+ return iwl4965_tx_agg_start(hw, addr, tid, ssn);
case IEEE80211_AMPDU_TX_STOP:
IWL_DEBUG_HT("stop Tx\n");
- return iwl4965_mac_ht_tx_agg_stop(hw, addr, tid);
+ return iwl4965_tx_agg_stop(hw, addr, tid);
default:
IWL_DEBUG_HT("unknown\n");
return -EINVAL;
--
1.5.3.4


2008-04-17 23:03:42

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 3/5] iwlwifi: define ANA_PLL values in iwl-csr.h

From: Tomas Winkler <[email protected]>

This patch defines ANA_PLL values in iwl-csr.h

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-csr.h | 7 +++++--
2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 598e4ee..2869533 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1233,7 +1233,7 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
iwl3945_power_init_handle(priv);

spin_lock_irqsave(&priv->lock, flags);
- iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, (1 << 24));
+ iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, CSR39_ANA_PLL_CFG_VAL);
iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);

diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index a59f48b..82c7445 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -95,8 +95,7 @@
#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100)
#define CSR_LED_REG (CSR_BASE+0x094)

-/* Analog phase-lock-loop configuration (3945 only)
- * Set bit 24. */
+/* Analog phase-lock-loop configuration */
#define CSR_ANA_PLL_CFG (CSR_BASE+0x20c)
/*
* Indicates hardware rev, to determine CCK backoff for txpower calculation.
@@ -219,6 +218,10 @@
#define CSR_LED_REG_TRUN_ON (0x78)
#define CSR_LED_REG_TRUN_OFF (0x38)

+/* ANA_PLL */
+#define CSR39_ANA_PLL_CFG_VAL (0x01000000)
+#define CSR50_ANA_PLL_CFG_VAL (0x00880300)
+
/*=== HBUS (Host-side Bus) ===*/
#define HBUS_BASE (0x400)
/*
--
1.5.3.4