2009-02-28 00:16:49

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 0/6] iwlwifi driver updates 02/27/2009

This series contains mostly 3945 porting patches. We include one fix in the
probe function's error flow. The API version of uCode for new hardware is
updated, backport support already present.

[PATCH 1/6] iwlwifi: update 5150 API version to support new firmware
[PATCH 2/6] iwl3945: synchronize timestamp with uCode
[PATCH 3/6] iwl3945: unify set key flow with iwlwifi
[PATCH 4/6] iwlwifi: fix *pci_probe error flow
[PATCH 5/6] iwl3945: add iwl3945_setup_mac
[PATCH 6/6] iwl3945 : use iwl_activate_qos


Thank you

Reinette



2009-02-28 00:16:48

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 2/6] iwl3945: synchronize timestamp with uCode

From: Abhijeet Kolekar <[email protected]>

In IBSS, TSF maintains local clock counters at each station. Network
Synchronization follows a completely distributed scheme where beacon frames
are generated. Each station maintain its own TSF timestamp, extracted from
beacon timestamps they recieved. Following patch synchronize this beacon timestamp
with uCode.

Signed-off-by: Abhijeet Kolekar <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl3945-base.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 6dcc577..443c00e 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4305,6 +4305,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
{
struct iwl_priv *priv = hw->priv;
unsigned long flags;
+ __le64 timestamp;

IWL_DEBUG_MAC80211(priv, "enter\n");

@@ -4326,6 +4327,8 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
priv->ibss_beacon = skb;

priv->assoc_id = 0;
+ timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+ priv->timestamp = le64_to_cpu(timestamp);

IWL_DEBUG_MAC80211(priv, "leave\n");
spin_unlock_irqrestore(&priv->lock, flags);
--
1.5.6.3


2009-02-28 00:16:49

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 1/6] iwlwifi: update 5150 API version to support new firmware

From: Jay Sternberg <[email protected]>

update API to support new numbering that is used for other newer devices.
5150 ucode has not been released yet, so the first released API will be v2.
For those who do have a v1 API the driver does have backward compatibility
support new value of REPLY_TX_POWER_DBM_CMD

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index ab39f4a..08c19be 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -47,7 +47,7 @@

/* Highest firmware API version supported */
#define IWL5000_UCODE_API_MAX 1
-#define IWL5150_UCODE_API_MAX 1
+#define IWL5150_UCODE_API_MAX 2

/* Lowest firmware API version supported */
#define IWL5000_UCODE_API_MIN 1
--
1.5.6.3


2009-02-28 00:16:50

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 4/6] iwlwifi: fix *pci_probe error flow

for iwlagn:
- Have to free eeprom of version check fails - otherwise we end up with
memory leak.
- Include removal of workqueue (created in _setup_deferred_work) in error
handling.

for iwl3945:
- Fix a few places to jump to correct error handling.
- Reorganize error handling to match with code flow.
- Include iwl_free_channel_map as part of error handling.
- Include releasing eeprom as part of error handling.

Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 4 +++-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 22 ++++++++++++----------
2 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index b49f9f7..18f6f68 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3405,7 +3405,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
err = iwl_eeprom_check_version(priv);
if (err)
- goto out_iounmap;
+ goto out_free_eeprom;

/* extract MAC Address */
iwl_eeprom_get_mac(priv, priv->mac_addr);
@@ -3501,6 +3501,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;

out_remove_sysfs:
+ destroy_workqueue(priv->workqueue);
+ priv->workqueue = NULL;
sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
out_free_irq:
free_irq(priv->pci_dev->irq, priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 18735aa..913d1a5 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -5053,7 +5053,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
"invalid queues_num, should be between %d and %d\n",
IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES);
err = -EINVAL;
- goto out;
+ goto out_ieee80211_free_hw;
}

/*
@@ -5147,7 +5147,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
err = iwl_eeprom_init(priv);
if (err) {
IWL_ERR(priv, "Unable to init EEPROM\n");
- goto out_remove_sysfs;
+ goto out_iounmap;
}
/* MAC Address location in EEPROM same for 3945/4965 */
eeprom = (struct iwl3945_eeprom *)priv->eeprom;
@@ -5161,7 +5161,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/* Device-specific setup */
if (iwl3945_hw_set_hw_params(priv)) {
IWL_ERR(priv, "failed to set hw settings\n");
- goto out_iounmap;
+ goto out_eeprom_free;
}

/***********************
@@ -5171,7 +5171,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
err = iwl3945_init_drv(priv);
if (err) {
IWL_ERR(priv, "initializing driver failed\n");
- goto out_free_geos;
+ goto out_unset_hw_params;
}

IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n",
@@ -5242,17 +5242,19 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
return 0;

out_remove_sysfs:
+ destroy_workqueue(priv->workqueue);
+ priv->workqueue = NULL;
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
- out_free_geos:
- iwlcore_free_geos(priv);
-
out_release_irq:
free_irq(priv->pci_dev->irq, priv);
- destroy_workqueue(priv->workqueue);
- priv->workqueue = NULL;
- iwl3945_unset_hw_params(priv);
out_disable_msi:
pci_disable_msi(priv->pci_dev);
+ iwlcore_free_geos(priv);
+ iwl_free_channel_map(priv);
+ out_unset_hw_params:
+ iwl3945_unset_hw_params(priv);
+ out_eeprom_free:
+ iwl_eeprom_free(priv);
out_iounmap:
pci_iounmap(pdev, priv->hw_base);
out_pci_release_regions:
--
1.5.6.3


2009-02-28 02:07:24

by Sujith

[permalink] [raw]
Subject: [PATCH 2/6] iwl3945: synchronize timestamp with uCode

Reinette Chatre wrote:
> From: Abhijeet Kolekar <[email protected]>
>
> In IBSS, TSF maintains local clock counters at each station. Network
> Synchronization follows a completely distributed scheme where beacon frames
> are generated. Each station maintain its own TSF timestamp, extracted from
> beacon timestamps they recieved. Following patch synchronize this beacon timestamp
> with uCode.
>
> Signed-off-by: Abhijeet Kolekar <[email protected]>
> Signed-off-by: Reinette Chatre <[email protected]>
> ---
> drivers/net/wireless/iwlwifi/iwl3945-base.c | 3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
> index 6dcc577..443c00e 100644
> --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
> +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
> @@ -4305,6 +4305,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
> {
> struct iwl_priv *priv = hw->priv;
> unsigned long flags;
> + __le64 timestamp;
>
> IWL_DEBUG_MAC80211(priv, "enter\n");
>
> @@ -4326,6 +4327,8 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
> priv->ibss_beacon = skb;
>
> priv->assoc_id = 0;
> + timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
> + priv->timestamp = le64_to_cpu(timestamp);
>

This won't work, since the timestamp in the beacon isn't being updated in mac80211.
See the 'IBSS Issues' thread. I attached a quick patch there.

Sujith

2009-02-28 00:16:49

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 5/6] iwl3945: add iwl3945_setup_mac

From: Abhijeet Kolekar <[email protected]>

Patch does following,
1) mac80211's shared data is now initialized in iwl3945_setup_mac.
2) Set the rfkill to right state after initialization

Signed-off-by: Abhijeet Kolekar <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl3945-base.c | 74 ++++++++++++++++----------
1 files changed, 45 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 913d1a5..b667f27 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -5008,19 +5008,53 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
}
iwl3945_init_hw_rates(priv, priv->ieee_rates);

+ return 0;
+
+err_free_channel_map:
+ iwl_free_channel_map(priv);
+err:
+ return ret;
+}
+
+static int iwl3945_setup_mac(struct iwl_priv *priv)
+{
+ int ret;
+ struct ieee80211_hw *hw = priv->hw;
+
+ hw->rate_control_algorithm = "iwl-3945-rs";
+ hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
+
+ /* Tell mac80211 our characteristics */
+ hw->flags = IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_NOISE_DBM;
+
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC);
+
+ hw->wiphy->custom_regulatory = true;
+
+ /* Default value; 4 EDCA QOS priorities */
+ hw->queues = 4;
+
+ hw->conf.beacon_int = 100;
+
if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&priv->bands[IEEE80211_BAND_2GHZ];
+
if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&priv->bands[IEEE80211_BAND_5GHZ];

- return 0;
+ ret = ieee80211_register_hw(priv->hw);
+ if (ret) {
+ IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
+ return ret;
+ }
+ priv->mac80211_registered = 1;

-err_free_channel_map:
- iwl_free_channel_map(priv);
-err:
- return ret;
+ return 0;
}

static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -5074,23 +5108,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
priv->debug_level = iwl3945_mod_params.debug;
atomic_set(&priv->restrict_refcnt, 0);
#endif
- hw->rate_control_algorithm = "iwl-3945-rs";
- hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
-
- /* Tell mac80211 our characteristics */
- hw->flags = IEEE80211_HW_SIGNAL_DBM |
- IEEE80211_HW_NOISE_DBM;
-
- hw->wiphy->interface_modes =
- BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC);
-
- hw->wiphy->custom_regulatory = true;
-
- hw->wiphy->max_scan_ssids = 1;
-
- /* 4 EDCA QOS priorities */
- hw->queues = 4;

/***************************
* 2. Initializing PCI bus
@@ -5221,19 +5238,18 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
* 9. Setup and Register mac80211
* *******************************/

- err = ieee80211_register_hw(priv->hw);
- if (err) {
- IWL_ERR(priv, "Failed to register network device: %d\n", err);
- goto out_remove_sysfs;
- }
+ iwl_enable_interrupts(priv);

- priv->hw->conf.beacon_int = 100;
- priv->mac80211_registered = 1;
+ err = iwl3945_setup_mac(priv);
+ if (err)
+ goto out_remove_sysfs;

err = iwl_rfkill_init(priv);
if (err)
IWL_ERR(priv, "Unable to initialize RFKILL system. "
"Ignoring error: %d\n", err);
+ else
+ iwl_rfkill_set_hw_state(priv);

/* Start monitoring the killswitch */
queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
--
1.5.6.3


2009-02-28 00:16:51

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 3/6] iwl3945: unify set key flow with iwlwifi

From: Abhijeet Kolekar <[email protected]>

unify the set key flow with iwlwifi.

Signed-off-by: Abhijeet Kolekar <[email protected]>
Acked-by: Samuel Ortiz <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-sta.c | 3 +-
drivers/net/wireless/iwlwifi/iwl-sta.h | 1 +
drivers/net/wireless/iwlwifi/iwl3945-base.c | 172 ++++++++++++++++++---------
3 files changed, 121 insertions(+), 55 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 1fae3a6..0ea08d0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -490,7 +490,7 @@ void iwl_clear_stations_table(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_clear_stations_table);

-static int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
+int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
int i;

@@ -500,6 +500,7 @@ static int iwl_get_free_ucode_key_index(struct iwl_priv *priv)

return WEP_INVALID_OFFSET;
}
+EXPORT_SYMBOL(iwl_get_free_ucode_key_index);

int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 97f6169..59a586b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -54,6 +54,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
void iwl_clear_stations_table(struct iwl_priv *priv);
+int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
int iwl_send_add_sta(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 443c00e..18735aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -407,6 +407,8 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
staging_rxon->reserved4 = 0;
staging_rxon->reserved5 = 0;

+ iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
+
/* Apply the new configuration */
rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
sizeof(struct iwl3945_rxon_cmd),
@@ -456,25 +458,24 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
return 0;
}

-static int iwl3945_update_sta_key_info(struct iwl_priv *priv,
+static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf,
u8 sta_id)
{
unsigned long flags;
__le16 key_flags = 0;
+ int ret;
+
+ key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
+ key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+
+ if (sta_id == priv->hw_params.bcast_sta_id)
+ key_flags |= STA_KEY_MULTICAST_MSK;
+
+ keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+ keyconf->hw_key_idx = keyconf->keyidx;
+ key_flags &= ~STA_KEY_FLG_INVALID;

- switch (keyconf->alg) {
- case ALG_CCMP:
- key_flags |= STA_KEY_FLG_CCMP;
- key_flags |= cpu_to_le16(
- keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
- key_flags &= ~STA_KEY_FLG_INVALID;
- break;
- case ALG_TKIP:
- case ALG_WEP:
- default:
- return -EINVAL;
- }
spin_lock_irqsave(&priv->sta_lock, flags);
priv->stations_39[sta_id].keyinfo.alg = keyconf->alg;
priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen;
@@ -483,16 +484,43 @@ static int iwl3945_update_sta_key_info(struct iwl_priv *priv,

memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key,
keyconf->keylen);
+
+ 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. */
+
+ WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+ "no space for a new key");
+
priv->stations_39[sta_id].sta.key.key_flags = key_flags;
priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;

+ IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");
+
+ ret = iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC);
+
spin_unlock_irqrestore(&priv->sta_lock, flags);

- IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");
- iwl_send_add_sta(priv,
- (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
- return 0;
+ return ret;
+}
+
+static int iwl3945_set_tkip_dynamic_key_info(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
+{
+ return -EOPNOTSUPP;
+}
+
+static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
+{
+ return -EOPNOTSUPP;
}

static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
@@ -514,6 +542,52 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
return 0;
}

+int iwl3945_set_dynamic_key(struct iwl_priv *priv,
+ struct ieee80211_key_conf *keyconf, u8 sta_id)
+{
+ int ret = 0;
+
+ keyconf->hw_key_idx = HW_KEY_DYNAMIC;
+
+ switch (keyconf->alg) {
+ case ALG_CCMP:
+ ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id);
+ break;
+ case ALG_TKIP:
+ ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id);
+ break;
+ case ALG_WEP:
+ ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id);
+ break;
+ default:
+ IWL_ERR(priv,"Unknown alg: %s alg = %d\n", __func__, keyconf->alg);
+ ret = -EINVAL;
+ }
+
+ IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
+ keyconf->alg, keyconf->keylen, keyconf->keyidx,
+ sta_id, ret);
+
+ return ret;
+}
+
+static int iwl3945_remove_static_key(struct iwl_priv *priv)
+{
+ int ret = -EOPNOTSUPP;
+
+ return ret;
+}
+
+static int iwl3945_set_static_key(struct iwl_priv *priv,
+ struct ieee80211_key_conf *key)
+{
+ if (key->alg == ALG_WEP)
+ return -EOPNOTSUPP;
+
+ IWL_ERR(priv, "Static key invalid: alg %d\n", key->alg);
+ return -EINVAL;
+}
+
static void iwl3945_clear_free_frames(struct iwl_priv *priv)
{
struct list_head *element;
@@ -766,11 +840,11 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
struct ieee80211_tx_info *info,
struct iwl_cmd *cmd,
struct sk_buff *skb_frag,
- int last_frag)
+ int sta_id)
{
struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
struct iwl3945_hw_key *keyinfo =
- &priv->stations_39[info->control.hw_key->hw_key_idx].keyinfo;
+ &priv->stations_39[sta_id].keyinfo;

switch (keyinfo->alg) {
case ALG_CCMP:
@@ -780,15 +854,6 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
break;

case ALG_TKIP:
-#if 0
- tx->sec_ctl = TX_CMD_SEC_TKIP;
-
- if (last_frag)
- memcpy(tx->tkip_mic.byte, skb_frag->tail - 8,
- 8);
- else
- memset(tx->tkip_mic.byte, 0, 8);
-#endif
break;

case ALG_WEP:
@@ -1088,7 +1153,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
txcmd_phys, len, 1, 0);

if (info->control.hw_key)
- iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0);
+ iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id);

/* Set up TFD's 2nd entry to point directly to remainder of skb,
* if any (802.11 null frames have no payload). */
@@ -4110,8 +4175,9 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
{
struct iwl_priv *priv = hw->priv;
const u8 *addr;
- int ret;
- u8 sta_id;
+ int ret = 0;
+ u8 sta_id = IWL_INVALID_STATION;
+ u8 static_key;

IWL_DEBUG_MAC80211(priv, "enter\n");

@@ -4121,43 +4187,41 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
}

addr = sta ? sta->addr : iwl_bcast_addr;
- sta_id = iwl3945_hw_find_station(priv, addr);
- if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
- addr);
- return -EINVAL;
+ static_key = !iwl_is_associated(priv);
+
+ if (!static_key) {
+ sta_id = iwl3945_hw_find_station(priv, addr);
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_DEBUG_MAC80211(priv, "leave - %pMnot in station map.\n",
+ addr);
+ return -EINVAL;
+ }
}

mutex_lock(&priv->mutex);
-
iwl_scan_cancel_timeout(priv, 100);
+ mutex_unlock(&priv->mutex);

switch (cmd) {
- case SET_KEY:
- ret = iwl3945_update_sta_key_info(priv, key, sta_id);
- if (!ret) {
- iwl_set_rxon_hwcrypto(priv, 1);
- iwl3945_commit_rxon(priv);
- key->hw_key_idx = sta_id;
- IWL_DEBUG_MAC80211(priv,
- "set_key success, using hwcrypto\n");
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
- }
+ case SET_KEY:
+ if (static_key)
+ ret = iwl3945_set_static_key(priv, key);
+ else
+ ret = iwl3945_set_dynamic_key(priv, key, sta_id);
+ IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
break;
case DISABLE_KEY:
- ret = iwl3945_clear_sta_key_info(priv, sta_id);
- if (!ret) {
- iwl_set_rxon_hwcrypto(priv, 0);
- iwl3945_commit_rxon(priv);
- IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
- }
+ if (static_key)
+ ret = iwl3945_remove_static_key(priv);
+ else
+ ret = iwl3945_clear_sta_key_info(priv, sta_id);
+ IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
break;
default:
ret = -EINVAL;
}

IWL_DEBUG_MAC80211(priv, "leave\n");
- mutex_unlock(&priv->mutex);

return ret;
}
--
1.5.6.3


2009-02-28 00:16:49

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 6/6] iwl3945 : use iwl_activate_qos

From: Abhijeet Kolekar <[email protected]>

3945 can use iwl_activate_qos instead of iwl3945_activate_qos.
Patch does two things
1) Patch adds iwl_activate_qos in core library.
2) 3945 makes use of iwl_activate_qos.

Signed-off-by: Abhijeet Kolekar <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 32 ------------------
drivers/net/wireless/iwlwifi/iwl-core.c | 33 ++++++++++++++++++
drivers/net/wireless/iwlwifi/iwl-core.h | 1 +
drivers/net/wireless/iwlwifi/iwl3945-base.c | 48 ++-------------------------
4 files changed, 37 insertions(+), 77 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 18f6f68..31e64bd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -601,38 +601,6 @@ static void iwl_ht_conf(struct iwl_priv *priv,
IWL_DEBUG_MAC80211(priv, "leave\n");
}

-/*
- * QoS support
-*/
-static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
-{
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- priv->qos_data.def_qos_parm.qos_flags = 0;
-
- if (priv->qos_data.qos_cap.q_AP.queue_request &&
- !priv->qos_data.qos_cap.q_AP.txop_request)
- priv->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_TXOP_TYPE_MSK;
- if (priv->qos_data.qos_active)
- priv->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_UPDATE_EDCA_MSK;
-
- if (priv->current_ht_config.is_ht)
- priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
-
- if (force || iwl_is_associated(priv)) {
- IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
- priv->qos_data.qos_active,
- priv->qos_data.def_qos_parm.qos_flags);
-
- iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
- sizeof(struct iwl_qosparam_cmd),
- &priv->qos_data.def_qos_parm, NULL);
- }
-}
-
#define MAX_UCODE_BEACON_INTERVAL 4096

static u16 iwl_adjust_beacon_interval(u16 beacon_val)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 37069d4..085e9cf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -240,6 +240,39 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_hw_nic_init);

+/*
+ * QoS support
+*/
+void iwl_activate_qos(struct iwl_priv *priv, u8 force)
+{
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ priv->qos_data.def_qos_parm.qos_flags = 0;
+
+ if (priv->qos_data.qos_cap.q_AP.queue_request &&
+ !priv->qos_data.qos_cap.q_AP.txop_request)
+ priv->qos_data.def_qos_parm.qos_flags |=
+ QOS_PARAM_FLG_TXOP_TYPE_MSK;
+ if (priv->qos_data.qos_active)
+ priv->qos_data.def_qos_parm.qos_flags |=
+ QOS_PARAM_FLG_UPDATE_EDCA_MSK;
+
+ if (priv->current_ht_config.is_ht)
+ priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+
+ if (force || iwl_is_associated(priv)) {
+ IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
+ priv->qos_data.qos_active,
+ priv->qos_data.def_qos_parm.qos_flags);
+
+ iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM,
+ sizeof(struct iwl_qosparam_cmd),
+ &priv->qos_data.def_qos_parm, NULL);
+ }
+}
+EXPORT_SYMBOL(iwl_activate_qos);
+
void iwl_reset_qos(struct iwl_priv *priv)
{
u16 cw_min = 15;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7427d75..27310fe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -224,6 +224,7 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
struct ieee80211_ops *hw_ops);
void iwl_hw_detect(struct iwl_priv *priv);
void iwl_reset_qos(struct iwl_priv *priv);
+void iwl_activate_qos(struct iwl_priv *priv, u8 force);
void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
int iwl_check_rxon_cmd(struct iwl_priv *priv);
int iwl_full_rxon_required(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index b667f27..883d0c2 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -689,48 +689,6 @@ static void iwl3945_unset_hw_params(struct iwl_priv *priv)
priv->shared_phys);
}

-/*
- * QoS support
-*/
-static int iwl3945_send_qos_params_command(struct iwl_priv *priv,
- struct iwl_qosparam_cmd *qos)
-{
-
- return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM,
- sizeof(struct iwl_qosparam_cmd), qos);
-}
-
-static void iwl3945_activate_qos(struct iwl_priv *priv, u8 force)
-{
- unsigned long flags;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->qos_data.def_qos_parm.qos_flags = 0;
-
- if (priv->qos_data.qos_cap.q_AP.queue_request &&
- !priv->qos_data.qos_cap.q_AP.txop_request)
- priv->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_TXOP_TYPE_MSK;
-
- if (priv->qos_data.qos_active)
- priv->qos_data.def_qos_parm.qos_flags |=
- QOS_PARAM_FLG_UPDATE_EDCA_MSK;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (force || iwl_is_associated(priv)) {
- IWL_DEBUG_QOS(priv, "send QoS cmd with QoS active %d \n",
- priv->qos_data.qos_active);
-
- iwl3945_send_qos_params_command(priv,
- &(priv->qos_data.def_qos_parm));
- }
-}
-
-
#define MAX_UCODE_BEACON_INTERVAL 1024
#define INTEL_CONN_LISTEN_INTERVAL cpu_to_le16(0xA)

@@ -3663,7 +3621,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
break;
}

- iwl3945_activate_qos(priv, 0);
+ iwl_activate_qos(priv, 0);

/* we have just associated, don't start scan too early */
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
@@ -4262,9 +4220,9 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,

mutex_lock(&priv->mutex);
if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl3945_activate_qos(priv, 1);
+ iwl_activate_qos(priv, 1);
else if (priv->assoc_id && iwl_is_associated(priv))
- iwl3945_activate_qos(priv, 0);
+ iwl_activate_qos(priv, 0);

mutex_unlock(&priv->mutex);

--
1.5.6.3


2009-03-02 18:06:25

by Reinette Chatre

[permalink] [raw]
Subject: Re: [PATCH 2/6] iwl3945: synchronize timestamp with uCode

On Fri, 2009-02-27 at 18:06 -0800, Sujith wrote:
> Reinette Chatre wrote:
> > From: Abhijeet Kolekar <[email protected]>
> >
> > In IBSS, TSF maintains local clock counters at each station. Network
> > Synchronization follows a completely distributed scheme where beacon frames
> > are generated. Each station maintain its own TSF timestamp, extracted from
> > beacon timestamps they recieved. Following patch synchronize this beacon timestamp
> > with uCode.
> >
> > Signed-off-by: Abhijeet Kolekar <[email protected]>
> > Signed-off-by: Reinette Chatre <[email protected]>
> > ---
> > drivers/net/wireless/iwlwifi/iwl3945-base.c | 3 +++
> > 1 files changed, 3 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
> > index 6dcc577..443c00e 100644
> > --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
> > +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
> > @@ -4305,6 +4305,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
> > {
> > struct iwl_priv *priv = hw->priv;
> > unsigned long flags;
> > + __le64 timestamp;
> >
> > IWL_DEBUG_MAC80211(priv, "enter\n");
> >
> > @@ -4326,6 +4327,8 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
> > priv->ibss_beacon = skb;
> >
> > priv->assoc_id = 0;
> > + timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
> > + priv->timestamp = le64_to_cpu(timestamp);
> >
>
> This won't work, since the timestamp in the beacon isn't being updated in mac80211.
> See the 'IBSS Issues' thread. I attached a quick patch there.

Thanks for spotting this. There is thus not a problem with this specific
patch ... just the information it depends on, which you now fixed. Are
you going to send your fix for inclusion ?

Reinette


2009-03-02 18:24:51

by Sujith

[permalink] [raw]
Subject: Re: [PATCH 2/6] iwl3945: synchronize timestamp with uCode

reinette chatre wrote:
> > This won't work, since the timestamp in the beacon isn't being updated in mac80211.
> > See the 'IBSS Issues' thread. I attached a quick patch there.
>
> Thanks for spotting this. There is thus not a problem with this specific
> patch ... just the information it depends on, which you now fixed. Are
> you going to send your fix for inclusion ?

Yep, will send a patch soon.

Sujith