2008-09-03 03:30:56

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 00/39] iwlwifi driver 09/03 updates

Hi,

Below are iwlwifi patches (1 for mac80211 and 1 for ath9k) against
wireless-testing GIT tip. Patches 01 ~ 11 are resubmitted.

Thanks,
-yi

[PATCH 01/39] iwlwifi : Added bss_info_changed callback to 3945
[PATCH 02/39] iwlwifi: W/A for the TSF correction in IBSS
[PATCH 03/39] iwlwifi: clean up hw scan handler
[PATCH 04/39] iwlwifi: remove obsolete 4965 forward declarations
[PATCH 05/39] iwlwifi: allow consecutive scans in unassociated state
[PATCH 06/39] iwlwifi: align set channel with mac80211
[PATCH 07/39] iwl3945: fix unbalanced mutex
[PATCH 08/39] iwl3945: replace association and beacon hooks with bss_info_changed cb
[PATCH 09/39] iwlwifi: fix hidden ssid discovery in passive channels
[PATCH 10/39] iwl3945: removed bg_post_associate work
[PATCH 11/39] iwl3945: avoid redundant iwl3945_get_active_dwell_time
[PATCH 12/39] iwlwifi: use strict_strtoul instead of simple_strtoul
[PATCH 13/39] iwlwifi: void full rxon on rx chain changes
[PATCH 14/39] iwlwifi: replace readl and writel with io/read/write/32
[PATCH 15/39] iwlwifi: remove rfkill warning from iwl-io
[PATCH 16/39] iwlwifi: fix apm_stop function
[PATCH 17/39] iwlwifi: generic init calibrations framework
[PATCH 18/39] iwlwifi: call apm stop on exit
[PATCH 19/39] iwlwifi: fix strict_strtoul error checking
[PATCH 20/39] iwlwifi: use station's mimo power save values
[PATCH 21/39] iwlwifi: fix rx_chain computation
[PATCH 22/39] iwlwifi: fix 64bit platform firmware loading
[PATCH 23/39] mac80211: change MIMO_PS to SM_PS
[PATCH 24/39] iwlwifi: change MIMO_PS to SM_PS
[PATCH 25/39] ath9k: change MIMO_PS to SM_PS
[PATCH 26/39] iwlwifi: remove double definition of SM PS
[PATCH 27/39] iwlwifi: rename ps_mode to sm_ps
[PATCH 28/39] iwlwifi: workaround interrupt handling no some platforms
[PATCH 29/39] iwlwifi: cleanup PCI register handling
[PATCH 30/39] iwlwifi: allow association on radar channel in power save
[PATCH 31/39] iwlwifi: fix memory allocation of TX command
[PATCH 32/39] iwlwifi: fix host command header according the HW spec
[PATCH 33/39] iwlwifi: use the results from disconnected antenna algorithm
[PATCH 34/39] iwlwifi: take a fresh set of supported rates at each cycle
[PATCH 35/39] iwlwifi: remove bad language from the comments
[PATCH 36/39] iwlwifi: remove uneeded declarations
[PATCH 37/39] iwlwifi: fix compile warning
[PATCH 38/39] iwl3945: enable active scanning on active channels
[PATCH 39/39] iwlwifi: enable packet injection for iwlagn


2008-09-03 03:31:01

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 04/39] iwlwifi: remove obsolete 4965 forward declarations

From: Ron Rindjunsky <[email protected]>

This patch removes unused forward declarations functions.

Signed-off-by: Ron Rindjunsky <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-dev.h | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index f46e9cd..0711b35 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -637,12 +637,6 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)

struct iwl_priv;

-/*
- * Forward declare iwl-4965.c functions for iwl-base.c
- */
-extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);
-int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id,
- u8 tid, int txq_id);

/* Structures, enum, and defines specific to the 4965 */

--
1.5.3.6


2008-09-03 03:31:33

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 29/39] iwlwifi: cleanup PCI register handling

From: Tomas Winkler <[email protected]>

This patch cleans up pci registers handling.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 13 +++++++------
drivers/net/wireless/iwlwifi/iwl-4965.c | 6 +++---
drivers/net/wireless/iwlwifi/iwl-5000.c | 6 +++---
drivers/net/wireless/iwlwifi/iwl-agn.c | 9 +++++----
drivers/net/wireless/iwlwifi/iwl-commands.h | 4 ++--
drivers/net/wireless/iwlwifi/iwl-power.c | 27 +++++++++++----------------
6 files changed, 31 insertions(+), 34 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index fce950f..f4793a6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -98,16 +98,17 @@
#define IWL_RSSI_OFFSET 44


-#include "iwl-commands.h"

/* PCI registers */
-#define PCI_LINK_CTRL 0x0F0 /* 1 byte */
-#define PCI_POWER_SOURCE 0x0C8
-#define PCI_REG_WUM8 0x0E8
+#define PCI_CFG_RETRY_TIMEOUT 0x041
+#define PCI_CFG_POWER_SOURCE 0x0C8
+#define PCI_REG_WUM8 0x0E8
+#define PCI_CFG_LINK_CTRL 0x0F0

/* PCI register values */
-#define PCI_LINK_VAL_L0S_EN 0x01
-#define PCI_LINK_VAL_L1_EN 0x02
+#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
+#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
+#define PCI_CFG_CMD_REG_INT_DIS_MSK 0x04
#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000)

#define TFD_QUEUE_SIZE_MAX (256)
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 23fed32..d9c4fdb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -399,7 +399,7 @@ static void iwl4965_nic_config(struct iwl_priv *priv)
unsigned long flags;
u32 val;
u16 radio_cfg;
- u8 val_link;
+ u16 link;

spin_lock_irqsave(&priv->lock, flags);

@@ -410,10 +410,10 @@ static void iwl4965_nic_config(struct iwl_priv *priv)
val & ~(1 << 11));
}

- pci_read_config_byte(priv->pci_dev, PCI_LINK_CTRL, &val_link);
+ pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link);

/* L1 is enabled by BIOS */
- if ((val_link & PCI_LINK_VAL_L1_EN) == PCI_LINK_VAL_L1_EN)
+ if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
/* diable L0S disabled L1A enabled */
iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
else
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 79ff288..cccd84c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -209,14 +209,14 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
{
unsigned long flags;
u16 radio_cfg;
- u8 val_link;
+ u16 link;

spin_lock_irqsave(&priv->lock, flags);

- pci_read_config_byte(priv->pci_dev, PCI_LINK_CTRL, &val_link);
+ pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &link);

/* L1 is enabled by BIOS */
- if ((val_link & PCI_LINK_VAL_L1_EN) == PCI_LINK_VAL_L1_EN)
+ if ((link & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN)
/* diable L0S disabled L1A enabled */
iwl_set_bit(priv, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED);
else
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 10980c7..3743e4b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1270,7 +1270,7 @@ int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)

if (src == IWL_PWR_SRC_VAUX) {
u32 val;
- ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
+ ret = pci_read_config_dword(priv->pci_dev, PCI_CFG_POWER_SOURCE,
&val);

if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
@@ -4237,9 +4237,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e

pci_set_drvdata(pdev, priv);

- /* We disable the RETRY_TIMEOUT register (0x41) to keep
- * PCI Tx retries from interfering with C3 CPU state */
- pci_write_config_byte(pdev, 0x41, 0x00);

/***********************
* 3. Read REV register
@@ -4259,6 +4256,10 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
": Detected Intel Wireless WiFi Link %s REV=0x%X\n",
priv->cfg->name, priv->hw_rev);

+ /* We disable the RETRY_TIMEOUT register (0x41) to keep
+ * PCI Tx retries from interfering with C3 CPU state */
+ pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
+
/* amp init */
err = priv->cfg->ops->lib->apm_ops.init(priv);
if (err < 0) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 28b5b09..fbd8cc1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2026,8 +2026,8 @@ struct iwl4965_spectrum_notification {
* bit 2 - '0' PM have to walk up every DTIM
* '1' PM could sleep over DTIM till listen Interval.
* PCI power managed
- * bit 3 - '0' (PCI_LINK_CTRL & 0x1)
- * '1' !(PCI_LINK_CTRL & 0x1)
+ * bit 3 - '0' (PCI_CFG_LINK_CTRL & 0x1)
+ * '1' !(PCI_CFG_LINK_CTRL & 0x1)
* Force sleep Modes
* bit 31/30- '00' use both mac/xtal sleeps
* '01' force Mac sleep
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index a099c9e..eb6312d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -152,9 +152,10 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
/* initialize to default */
static int iwl_power_init_handle(struct iwl_priv *priv)
{
- int ret = 0, i;
struct iwl_power_mgr *pow_data;
int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
+ struct iwl_powertable_cmd *cmd;
+ int i;
u16 pci_pm;

IWL_DEBUG_POWER("Initialize power \n");
@@ -167,25 +168,19 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
memcpy(&pow_data->pwr_range_1[0], &range_1[0], size);
memcpy(&pow_data->pwr_range_2[0], &range_2[0], size);

- ret = pci_read_config_word(priv->pci_dev,
- PCI_LINK_CTRL, &pci_pm);
- if (ret != 0)
- return 0;
- else {
- struct iwl_powertable_cmd *cmd;
+ pci_read_config_word(priv->pci_dev, PCI_CFG_LINK_CTRL, &pci_pm);

- IWL_DEBUG_POWER("adjust power command flags\n");
+ IWL_DEBUG_POWER("adjust power command flags\n");

- for (i = 0; i < IWL_POWER_MAX; i++) {
- cmd = &pow_data->pwr_range_0[i].cmd;
+ for (i = 0; i < IWL_POWER_MAX; i++) {
+ cmd = &pow_data->pwr_range_0[i].cmd;

- if (pci_pm & 0x1)
- cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
- else
- cmd->flags |= IWL_POWER_PCI_PM_MSK;
- }
+ if (pci_pm & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
+ cmd->flags &= ~IWL_POWER_PCI_PM_MSK;
+ else
+ cmd->flags |= IWL_POWER_PCI_PM_MSK;
}
- return ret;
+ return 0;
}

/* adjust power command according to dtim period and power level*/
--
1.5.3.6


2008-09-03 03:31:08

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 10/39] iwl3945: removed bg_post_associate work

From: Abhijeet Kolekar <[email protected]>

This patch removes bg_post_associate work. A direct call
iwl3945_post_associate is made to avoid the waiting by
userspace programs.

Signed-off-by: Abhijeet Kolekar <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.h | 1 -
drivers/net/wireless/iwlwifi/iwl3945-base.c | 18 +-----------------
2 files changed, 1 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 4dd3f0d..9bbbc9d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -894,7 +894,6 @@ struct iwl3945_priv {
struct delayed_work thermal_periodic;
struct delayed_work gather_stats;
struct delayed_work scan_check;
- struct delayed_work post_associate;

#define IWL_DEFAULT_TX_POWER 0x0F
s8 user_txpower_limit;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 85581b6..70dfe9d 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -6415,16 +6415,6 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv)
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
}

-static void iwl3945_bg_post_associate(struct work_struct *data)
-{
- struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv,
- post_associate.work);
-
- mutex_lock(&priv->mutex);
- iwl3945_post_associate(priv);
- mutex_unlock(&priv->mutex);
-}
-
static void iwl3945_bg_abort_scan(struct work_struct *work)
{
struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, abort_scan);
@@ -6570,7 +6560,6 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
*/
mutex_lock(&priv->mutex);
iwl3945_scan_cancel_timeout(priv, 100);
- cancel_delayed_work(&priv->post_associate);
mutex_unlock(&priv->mutex);
}

@@ -6936,7 +6925,6 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,

if (iwl3945_is_ready_rf(priv)) {
iwl3945_scan_cancel_timeout(priv, 100);
- cancel_delayed_work(&priv->post_associate);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl3945_commit_rxon(priv);
}
@@ -7240,8 +7228,6 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)

iwl3945_reset_qos(priv);

- cancel_delayed_work(&priv->post_associate);
-
spin_lock_irqsave(&priv->lock, flags);
priv->assoc_id = 0;
priv->assoc_capability = 0;
@@ -7326,7 +7312,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk

iwl3945_reset_qos(priv);

- queue_work(priv->workqueue, &priv->post_associate.work);
+ iwl3945_post_associate(priv);

mutex_unlock(&priv->mutex);

@@ -7825,7 +7811,6 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv)
INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
INIT_WORK(&priv->set_monitor, iwl3945_bg_set_monitor);
- INIT_DELAYED_WORK(&priv->post_associate, iwl3945_bg_post_associate);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check);
@@ -7843,7 +7828,6 @@ static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv)
cancel_delayed_work_sync(&priv->init_alive_start);
cancel_delayed_work(&priv->scan_check);
cancel_delayed_work(&priv->alive_start);
- cancel_delayed_work(&priv->post_associate);
cancel_work_sync(&priv->beacon_update);
}

--
1.5.3.6


2008-09-03 03:31:44

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 38/39] iwl3945: enable active scanning on active channels

From: Abhijeet Kolekar <[email protected]>

This patch enables active scanning on active channels.

Signed-off-by: Abhijeet Kolekar <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl3945-base.c | 54 +++++++++++++--------------
1 files changed, 26 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 709be78..53e234d 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4782,8 +4782,11 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
* sending probe req. This should be set long enough to hear probe responses
* from more than one AP. */
-#define IWL_ACTIVE_DWELL_TIME_24 (20) /* all times in msec */
-#define IWL_ACTIVE_DWELL_TIME_52 (10)
+#define IWL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */
+#define IWL_ACTIVE_DWELL_TIME_52 (20)
+
+#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
+#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)

/* For faster active scanning, scan will move to the next channel if fewer than
* PLCP_QUIET_THRESH packets are heard on this channel within
@@ -4792,7 +4795,7 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
* no other traffic).
* Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
-#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(5) /* msec */
+#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */

/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
* Must be set longer than active dwell time.
@@ -4802,13 +4805,18 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv)
#define IWL_PASSIVE_DWELL_BASE (100)
#define IWL_CHANNEL_TUNE_TIME 5

+#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
+
static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
- enum ieee80211_band band)
+ enum ieee80211_band band,
+ u8 n_probes)
{
if (band == IEEE80211_BAND_5GHZ)
- return IWL_ACTIVE_DWELL_TIME_52;
+ return IWL_ACTIVE_DWELL_TIME_52 +
+ IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1);
else
- return IWL_ACTIVE_DWELL_TIME_24;
+ return IWL_ACTIVE_DWELL_TIME_24 +
+ IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
}

static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,
@@ -4833,7 +4841,7 @@ static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,

static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
enum ieee80211_band band,
- u8 is_active, u8 direct_mask,
+ u8 is_active, u8 n_probes,
struct iwl3945_scan_channel *scan_ch)
{
const struct ieee80211_channel *channels = NULL;
@@ -4849,7 +4857,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,

channels = sband->channels;

- active_dwell = iwl3945_get_active_dwell_time(priv, band);
+ active_dwell = iwl3945_get_active_dwell_time(priv, band, n_probes);
passive_dwell = iwl3945_get_passive_dwell_time(priv, band);

if (passive_dwell <= active_dwell)
@@ -4874,8 +4882,8 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
else
scan_ch->type = 1; /* active */

- if (scan_ch->type & 1)
- scan_ch->type |= (direct_mask << 1);
+ if ((scan_ch->type & 1) && n_probes)
+ scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);

scan_ch->active_dwell = cpu_to_le16(active_dwell);
scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
@@ -6092,7 +6100,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
int rc = 0;
struct iwl3945_scan_cmd *scan;
struct ieee80211_conf *conf = NULL;
- u8 direct_mask;
+ u8 n_probes = 2;
enum ieee80211_band band;

conf = ieee80211_get_hw_conf(priv->hw);
@@ -6200,7 +6208,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
scan->direct_scan[0].len = priv->direct_ssid_len;
memcpy(scan->direct_scan[0].ssid,
priv->direct_ssid, priv->direct_ssid_len);
- direct_mask = 1;
+ n_probes++;
} else if (!iwl3945_is_associated(priv) && priv->essid_len) {
IWL_DEBUG_SCAN
("Kicking off one direct scan for '%s' when not associated\n",
@@ -6208,11 +6216,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
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 {
+ n_probes++;
+ } 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 */
@@ -6245,18 +6251,10 @@ 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)
- 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
- scan->channel_count =
- iwl3945_get_channels_for_scan(
- priv, band, 0, /* passive */
- direct_mask,
- (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ scan->channel_count =
+ iwl3945_get_channels_for_scan(priv, band, 1, /* active */
+ n_probes,
+ (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);
--
1.5.3.6


2008-09-03 03:30:58

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 02/39] iwlwifi: W/A for the TSF correction in IBSS

From: Assaf Krauss <[email protected]>

This patch is a W/A for the TSF sync issue, in which the ucode's timestamp
is constantly a little behind incoming beacons' timestamps (in IBSS cells).
The W/A simply stops the driver from declaring it has a reliable TSF value.

Signed-off-by: Assaf Krauss <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-rx.c | 5 ++++-
2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 676fc0a..1badcf3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3578,7 +3578,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk

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

IWL_DEBUG_MAC80211("leave\n");
spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index b92a580..faad4d3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1068,7 +1068,10 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;

rx_status.flag = 0;
- rx_status.flag |= RX_FLAG_TSFT;
+
+ /* TSF isn't reliable. In order to allow smooth user experience,
+ * this W/A doesn't propagate it to the mac80211 */
+ /*rx_status.flag |= RX_FLAG_TSFT;*/

if ((unlikely(rx_start->cfg_phy_cnt > 20))) {
IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n",
--
1.5.3.6


2008-09-03 03:31:30

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 26/39] iwlwifi: remove double definition of SM PS

From: Ron Rindjunsky <[email protected]>

This patch removes iwlwifi definition of spatial power save modes,
already defined in ieee80211.h.

Signed-off-by: Ron Rindjunsky <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-core.c | 14 +++++++-------
drivers/net/wireless/iwlwifi/iwl-dev.h | 5 -----
3 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 609ad1d..c1b70c8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1154,7 +1154,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
return -1;

if (((sta->ht_info.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
- == IWL_MIMO_PS_STATIC)
+ == WLAN_HT_CAP_SM_PS_STATIC)
return -1;

/* Need both Tx chains/antennas to support MIMO */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index e2f06aa..fa48615 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -400,7 +400,7 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD;
ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20;
ht_info->cap |= (u16)(IEEE80211_HT_CAP_SM_PS &
- (IWL_MIMO_PS_NONE << 2));
+ (WLAN_HT_CAP_SM_PS_DISABLED << 2));

max_bit_rate = MAX_BIT_RATE_20_MHZ;
if (priv->hw_params.fat_channel & BIT(band)) {
@@ -709,7 +709,7 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);

/* # of Rx chains to use when expecting MIMO. */
- if (is_single || (!is_cam && (priv->ps_mode == IWL_MIMO_PS_STATIC)))
+ if (is_single || (!is_cam && (priv->ps_mode == WLAN_HT_CAP_SM_PS_STATIC)))
return 2;
else
return 3;
@@ -721,14 +721,14 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
/* # Rx chains when idling and maybe trying to save power */
switch (priv->ps_mode) {
- case IWL_MIMO_PS_STATIC:
- case IWL_MIMO_PS_DYNAMIC:
+ case WLAN_HT_CAP_SM_PS_STATIC:
+ case WLAN_HT_CAP_SM_PS_DYNAMIC:
idle_cnt = (is_cam) ? 2 : 1;
break;
- case IWL_MIMO_PS_NONE:
+ case WLAN_HT_CAP_SM_PS_DISABLED:
idle_cnt = (is_cam) ? active_cnt : 1;
break;
- case IWL_MIMO_PS_INVALID:
+ case WLAN_HT_CAP_SM_PS_INVALID:
default:
IWL_ERROR("invalide mimo ps mode %d\n", priv->ps_mode);
WARN_ON(1);
@@ -908,7 +908,7 @@ int iwl_init_drv(struct iwl_priv *priv)
priv->iw_mode = IEEE80211_IF_TYPE_STA;

priv->use_ant_b_for_management_frame = 1; /* start with ant B */
- priv->ps_mode = IWL_MIMO_PS_NONE;
+ priv->ps_mode = WLAN_HT_CAP_SM_PS_DISABLED;

/* Choose which receivers/antennas to use */
iwl_set_rxon_chain(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index ee38697..1b11664 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -650,11 +650,6 @@ struct iwl_kw {
#define IWL_CHANNEL_WIDTH_20MHZ 0
#define IWL_CHANNEL_WIDTH_40MHZ 1

-#define IWL_MIMO_PS_STATIC 0
-#define IWL_MIMO_PS_NONE 3
-#define IWL_MIMO_PS_DYNAMIC 1
-#define IWL_MIMO_PS_INVALID 2
-
#define IWL_OPERATION_MODE_AUTO 0
#define IWL_OPERATION_MODE_HT_ONLY 1
#define IWL_OPERATION_MODE_MIXED 2
--
1.5.3.6


2008-09-03 03:31:57

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 39/39] iwlwifi: enable packet injection for iwlagn

=46rom: Stefanik G=C3=A1bor <[email protected]>

Handle station IDs of transmitted packets when in monitor mode, and
remove the various anti-injection checks from the iwl4965 driver.
This makes injection work on iwl4965 and iwl5000. Tested on both cards.

Note: To inject management frames with encryption, HW crypto support
must be disabled using the "swcrypto=3D1" modparam (or "swcrypto50=3D1"
for iwl5000). Otherwise most management frames won't be transmitted.

Signed-off-by: G=C3=A1bor Stefanik <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 6 ------
drivers/net/wireless/iwlwifi/iwl-sta.c | 5 +++++
drivers/net/wireless/iwlwifi/iwl-tx.c | 13 +++++--------
3 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wirel=
ess/iwlwifi/iwl-agn.c
index cf882bf..31ea288 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2734,12 +2734,6 @@ static int iwl4965_mac_tx(struct ieee80211_hw *h=
w, struct sk_buff *skb)
=20
IWL_DEBUG_MACDUMP("enter\n");
=20
- if (priv->iw_mode =3D=3D IEEE80211_IF_TYPE_MNTR) {
- IWL_DEBUG_MAC80211("leave - monitor\n");
- dev_kfree_skb_any(skb);
- return 0;
- }
-
IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
=20
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wirel=
ess/iwlwifi/iwl-sta.c
index 3c0204c..a72569f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -968,6 +968,11 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct i=
eee80211_hdr *hdr)
iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
return priv->hw_params.bcast_sta_id;
=20
+ /* If we are in monitor mode, use BCAST. This is required for
+ * packet injection. */
+ case IEEE80211_IF_TYPE_MNTR:
+ return priv->hw_params.bcast_sta_id;
+
default:
IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
return priv->hw_params.bcast_sta_id;
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wirele=
ss/iwlwifi/iwl-tx.c
index 9ef6451..9d5bcf4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -793,11 +793,6 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_bu=
ff *skb)
goto drop_unlock;
}
=20
- if (!priv->vif) {
- IWL_DEBUG_DROP("Dropping - !priv->vif\n");
- goto drop_unlock;
- }
-
if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) =3D=3D
IWL_INVALID_RATE) {
IWL_ERROR("ERROR: No TX rate available.\n");
@@ -819,9 +814,11 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_bu=
ff *skb)
=20
/* drop all data frame if we are not associated */
if (ieee80211_is_data(fc) &&
- (!iwl_is_associated(priv) ||
- ((priv->iw_mode =3D=3D IEEE80211_IF_TYPE_STA) && !priv->assoc_id)=
||
- !priv->assoc_station_added)) {
+ (priv->iw_mode !=3D IEEE80211_IF_TYPE_MNTR ||
+ !(info->flags & IEEE80211_TX_CTL_INJECTED)) && /* packet injectio=
n */
+ (!iwl_is_associated(priv) ||
+ ((priv->iw_mode =3D=3D IEEE80211_IF_TYPE_STA) && !priv->assoc_id=
) ||
+ !priv->assoc_station_added)) {
IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n");
goto drop_unlock;
}
--=20
1.5.3.6

2008-09-03 03:31:02

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 05/39] iwlwifi: allow consecutive scans in unassociated state

From: Ron Rindjunsky <[email protected]>

This patch allows consecutive scans requests when driver is in
unassociated state.

Signed-off-by: Ron Rindjunsky <[email protected]>
Signed-off-by: Esti Kummer <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 1073fa0..08ca2a3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3205,12 +3205,14 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
/* we don't schedule scan within next_scan_jiffies period */
if (priv->next_scan_jiffies &&
time_after(priv->next_scan_jiffies, jiffies)) {
+ IWL_DEBUG_SCAN("scan rejected: within next scan period\n");
ret = -EAGAIN;
goto out_unlock;
}
/* if we just finished scan ask for delay */
- if (priv->last_scan_jiffies &&
+ if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
+ IWL_DEBUG_SCAN("scan rejected: within previous scan period\n");
ret = -EAGAIN;
goto out_unlock;
}
--
1.5.3.6


2008-09-03 03:31:38

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 32/39] iwlwifi: fix host command header according the HW spec

From: Tomas Winkler <[email protected]>

This patch aligns definition of host command with the spec. The
inaccuracies weren't critical though.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-commands.h | 20 ++++++++++++++------
drivers/net/wireless/iwlwifi/iwl-dev.h | 6 ------
drivers/net/wireless/iwlwifi/iwl-tx.c | 4 ++--
3 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index fbd8cc1..8d04e96 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -163,6 +163,13 @@ enum {
/* iwl_cmd_header flags value */
#define IWL_CMD_FAILED_MSK 0x40

+#define SEQ_TO_QUEUE(s) (((s) >> 8) & 0x1f)
+#define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8)
+#define SEQ_TO_INDEX(s) ((s) & 0xff)
+#define INDEX_TO_SEQ(i) ((i) & 0xff)
+#define SEQ_HUGE_FRAME __constant_cpu_to_le16(0x4000)
+#define SEQ_RX_FRAME __constant_cpu_to_le16(0x8000)
+
/**
* struct iwl_cmd_header
*
@@ -171,7 +178,7 @@ enum {
*/
struct iwl_cmd_header {
u8 cmd; /* Command ID: REPLY_RXON, etc. */
- u8 flags; /* IWL_CMD_* */
+ u8 flags; /* 0:5 reserved, 6 abort, 7 internal */
/*
* The driver sets up the sequence number to values of its chosing.
* uCode does not use this value, but passes it back to the driver
@@ -187,11 +194,12 @@ struct iwl_cmd_header {
*
* The Linux driver uses the following format:
*
- * 0:7 index/position within Tx queue
- * 8:13 Tx queue selection
- * 14:14 driver sets this to indicate command is in the 'huge'
- * storage at the end of the command buffers, i.e. scan cmd
- * 15:15 uCode sets this in uCode-originated response/notification
+ * 0:7 tfd index - position within TX queue
+ * 8:12 TX queue id
+ * 13 reserved
+ * 14 huge - driver sets this to indicate command is in the
+ * 'huge' storage at the end of the command buffers
+ * 15 unsolicited RX or uCode-originated notification
*/
__le16 sequence;

diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 8daeafd..7934f56 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -225,12 +225,6 @@ struct iwl_frame {
struct list_head list;
};

-#define SEQ_TO_QUEUE(x) ((x >> 8) & 0xbf)
-#define QUEUE_TO_SEQ(x) ((x & 0xbf) << 8)
-#define SEQ_TO_INDEX(x) ((u8)(x & 0xff))
-#define INDEX_TO_SEQ(x) ((u8)(x & 0xff))
-#define SEQ_HUGE_FRAME (0x4000)
-#define SEQ_RX_FRAME __constant_cpu_to_le16(0x8000)
#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 68567fa..4b4a2bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -1064,7 +1064,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
INDEX_TO_SEQ(q->write_ptr));
if (out_cmd->meta.flags & CMD_SIZE_HUGE)
- out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
+ out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
len = (idx == TFD_CMD_SLOTS) ?
IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
phys_addr = pci_map_single(priv->pci_dev, out_cmd, len,
@@ -1199,8 +1199,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
int txq_id = SEQ_TO_QUEUE(sequence);
int index = SEQ_TO_INDEX(sequence);
- int huge = sequence & SEQ_HUGE_FRAME;
int cmd_index;
+ bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
struct iwl_cmd *cmd;

/* If a Tx command is being handled and it isn't in the actual
--
1.5.3.6


2008-09-03 03:31:15

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 15/39] iwlwifi: remove rfkill warning from iwl-io

From: Tomas Winkler <[email protected]>

The patch removes the warning since registers might be accessed also
during rfkill.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945-io.h | 18 ------------------
drivers/net/wireless/iwlwifi/iwl-io.h | 18 ------------------
2 files changed, 0 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
index 98740e8..b3fe48d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
@@ -153,28 +153,10 @@ static inline void __iwl3945_clear_bit(const char *f, u32 l,
static inline int _iwl3945_grab_nic_access(struct iwl3945_priv *priv)
{
int ret;
- u32 gp_ctl;
-
#ifdef CONFIG_IWL3945_DEBUG
if (atomic_read(&priv->restrict_refcnt))
return 0;
#endif
- if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
- test_bit(STATUS_RF_KILL_SW, &priv->status)) {
- IWL_WARNING("WARNING: Requesting MAC access during RFKILL "
- "wakes up NIC\n");
-
- /* 10 msec allows time for NIC to complete its data save */
- gp_ctl = _iwl3945_read32(priv, CSR_GP_CNTRL);
- if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) {
- IWL_DEBUG_RF_KILL("Wait for complete power-down, "
- "gpctl = 0x%08x\n", gp_ctl);
- mdelay(10);
- } else
- IWL_DEBUG_RF_KILL("power-down complete, "
- "gpctl = 0x%08x\n", gp_ctl);
- }
-
/* this bit wakes up the NIC */
_iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
ret = _iwl3945_poll_bit(priv, CSR_GP_CNTRL,
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 17fb4e2..9740fcc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -155,28 +155,10 @@ static inline void __iwl_clear_bit(const char *f, u32 l,
static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
{
int ret;
- u32 gp_ctl;
-
#ifdef CONFIG_IWLWIFI_DEBUG
if (atomic_read(&priv->restrict_refcnt))
return 0;
#endif
- if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
- test_bit(STATUS_RF_KILL_SW, &priv->status)) {
- IWL_WARNING("WARNING: Requesting MAC access during RFKILL "
- "wakes up NIC\n");
-
- /* 10 msec allows time for NIC to complete its data save */
- gp_ctl = _iwl_read32(priv, CSR_GP_CNTRL);
- if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) {
- IWL_DEBUG_RF_KILL("Wait for complete power-down, "
- "gpctl = 0x%08x\n", gp_ctl);
- mdelay(10);
- } else
- IWL_DEBUG_RF_KILL("power-down complete, "
- "gpctl = 0x%08x\n", gp_ctl);
- }
-
/* this bit wakes up the NIC */
_iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
--
1.5.3.6


2008-09-05 21:14:29

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 08/39] iwl3945: replace association and beacon hooks with bss_info_changed cb

On Wed, 2008-09-03 at 11:26 +0800, Zhu Yi wrote:
> From: Abhijeet Kolekar <[email protected]>
>
> Let mac80211 and bss_info_changed callback handle the association and
> beacon changes.

Nice.


> @@ -688,87 +688,6 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
>
> switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
> case IEEE80211_FTYPE_MGMT:

You can, umm, simplify all this code a bit now:

if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
return;
}

switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
case IEEE80211_FTYPE_MGMT:
case IEEE80211_FTYPE_DATA:
/* fall through */
default:
iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
break;
}


a single line can express the same :)

johannes


Attachments:
signature.asc (836.00 B)
This is a digitally signed message part

2008-09-03 03:31:25

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 23/39] mac80211: change MIMO_PS to SM_PS

From: Ron Rindjunsky <[email protected]>

This patch follows 11n spec naming more rigorously replacing MIMO_PS
with SM_PS (Spatial Multiplexing Power Save).

Signed-off-by: Ron Rindjunsky <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
include/linux/ieee80211.h | 12 ++++++------
net/mac80211/main.c | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index be45645..333d3ae 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -708,7 +708,7 @@ struct ieee80211_ht_addt_info {

/* 802.11n HT capabilities masks */
#define IEEE80211_HT_CAP_SUP_WIDTH 0x0002
-#define IEEE80211_HT_CAP_MIMO_PS 0x000C
+#define IEEE80211_HT_CAP_SM_PS 0x000C
#define IEEE80211_HT_CAP_GRN_FLD 0x0010
#define IEEE80211_HT_CAP_SGI_20 0x0020
#define IEEE80211_HT_CAP_SGI_40 0x0040
@@ -737,11 +737,11 @@ struct ieee80211_ht_addt_info {
#define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004
#define IEEE80211_HT_IE_NON_HT_STA_PRSNT 0x0010

-/* MIMO Power Save Modes */
-#define WLAN_HT_CAP_MIMO_PS_STATIC 0
-#define WLAN_HT_CAP_MIMO_PS_DYNAMIC 1
-#define WLAN_HT_CAP_MIMO_PS_INVALID 2
-#define WLAN_HT_CAP_MIMO_PS_DISABLED 3
+/* Spatial Multiplexing Power Save Modes */
+#define WLAN_HT_CAP_SM_PS_STATIC 0
+#define WLAN_HT_CAP_SM_PS_DYNAMIC 1
+#define WLAN_HT_CAP_SM_PS_INVALID 2
+#define WLAN_HT_CAP_SM_PS_DISABLED 3

/* Authentication algorithms */
#define WLAN_AUTH_OPEN 0
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 638b75f..804a875 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1140,8 +1140,8 @@ u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht,
ht_conf.ht_supported = 1;

ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap;
- ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS);
- ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS;
+ ht_conf.cap &= ~(IEEE80211_HT_CAP_SM_PS);
+ ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_SM_PS;
ht_bss_conf.primary_channel = req_bss_cap->primary_channel;
ht_bss_conf.bss_cap = req_bss_cap->bss_cap;
ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode;
--
1.5.3.6


2008-09-03 03:31:39

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 33/39] iwlwifi: use the results from disconnected antenna algorithm

From: Grumbach, Emmanuel <[email protected]>

This patch makes usage of the results from disconnected antenna alg to
know how many antennas are connected.

It also synchronizes between the chain noise alg and the W/A that
disables power management during association. All the antennas must be
enables during the chain noise algorithm. Hence, power management is
restored only after the completion of the algorithm.

In the future, we will need to update the AP that we don't support MIMO
if there is only one antenna connected. We also need to update the rate
scaling algorithm.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 6 ++++-
drivers/net/wireless/iwlwifi/iwl-calib.c | 15 +++++++++---
drivers/net/wireless/iwlwifi/iwl-core.c | 35 ++++++++++++++++++++++++------
drivers/net/wireless/iwlwifi/iwl-dev.h | 10 +++++---
drivers/net/wireless/iwlwifi/iwl-power.c | 26 +++++++++++-----------
drivers/net/wireless/iwlwifi/iwl-power.h | 2 +-
6 files changed, 64 insertions(+), 30 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 42cb3dd..45cdf31 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2558,7 +2558,11 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
iwl_activate_qos(priv, 0);
spin_unlock_irqrestore(&priv->lock, flags);

- iwl_power_enable_management(priv);
+ /* the chain noise calibration will enabled PM upon completion
+ * If chain noise has already been run, then we need to enable
+ * power management here */
+ if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
+ iwl_power_enable_management(priv);

/* Enable Rx differential gain and sensitivity calibrations */
iwl_chain_noise_reset(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 35fb4a4..72fbf47 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -808,13 +808,11 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
}
}

+ /* Save for use within RXON, TX, SCAN commands, etc. */
+ priv->chain_noise_data.active_chains = active_chains;
IWL_DEBUG_CALIB("active_chains (bitwise) = 0x%x\n",
active_chains);

- /* Save for use within RXON, TX, SCAN commands, etc. */
- /*priv->valid_antenna = active_chains;*/
- /*FIXME: should be reflected in RX chains in RXON */
-
/* Analyze noise for rx balance */
average_noise[0] = ((data->chain_noise_a)/CAL_NUM_OF_BEACONS);
average_noise[1] = ((data->chain_noise_b)/CAL_NUM_OF_BEACONS);
@@ -839,6 +837,15 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,

priv->cfg->ops->utils->gain_computation(priv, average_noise,
min_average_noise_antenna_i, min_average_noise);
+
+ /* Some power changes may have been made during the calibration.
+ * Update and commit the RXON
+ */
+ if (priv->cfg->ops->lib->update_chain_flags)
+ priv->cfg->ops->lib->update_chain_flags(priv);
+
+ data->state = IWL_CHAIN_NOISE_DONE;
+ iwl_power_enable_management(priv);
}
EXPORT_SYMBOL(iwl_chain_noise_calibration);

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index b29c84a..134f4ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -740,6 +740,17 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
return idle_cnt;
}

+/* up to 4 chains */
+static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
+{
+ u8 res;
+ res = (chain_bitmap & BIT(0)) >> 0;
+ res += (chain_bitmap & BIT(1)) >> 1;
+ res += (chain_bitmap & BIT(2)) >> 2;
+ res += (chain_bitmap & BIT(4)) >> 4;
+ return res;
+}
+
/**
* iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
*
@@ -750,25 +761,35 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
{
bool is_single = is_single_rx_stream(priv);
bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
- u8 idle_rx_cnt, active_rx_cnt;
+ u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt;
+ u32 active_chains;
u16 rx_chain;

/* Tell uCode which antennas are actually connected.
* Before first association, we assume all antennas are connected.
* Just after first association, iwl_chain_noise_calibration()
* checks which antennas actually *are* connected. */
- rx_chain = priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
+ if (priv->chain_noise_data.active_chains)
+ active_chains = priv->chain_noise_data.active_chains;
+ else
+ active_chains = priv->hw_params.valid_rx_ant;
+
+ rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;

/* How many receivers should we use? */
active_rx_cnt = iwl_get_active_rx_chain_count(priv);
idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);

- /* correct rx chain count accoridng hw settings */
- if (priv->hw_params.rx_chains_num < active_rx_cnt)
- active_rx_cnt = priv->hw_params.rx_chains_num;

- if (priv->hw_params.rx_chains_num < idle_rx_cnt)
- idle_rx_cnt = priv->hw_params.rx_chains_num;
+ /* correct rx chain count according hw settings
+ * and chain noise calibration
+ */
+ valid_rx_cnt = iwl_count_chain_bitmap(active_chains);
+ if (valid_rx_cnt < active_rx_cnt)
+ active_rx_cnt = valid_rx_cnt;
+
+ if (valid_rx_cnt < idle_rx_cnt)
+ idle_rx_cnt = valid_rx_cnt;

rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 7934f56..6e150f6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -699,8 +699,9 @@ enum iwl4965_false_alarm_state {

enum iwl4965_chain_noise_state {
IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */
- IWL_CHAIN_NOISE_ACCUMULATE = 1,
- IWL_CHAIN_NOISE_CALIBRATED = 2,
+ IWL_CHAIN_NOISE_ACCUMULATE,
+ IWL_CHAIN_NOISE_CALIBRATED,
+ IWL_CHAIN_NOISE_DONE,
};

enum iwl4965_calib_enabled_state {
@@ -758,17 +759,18 @@ struct iwl_sensitivity_data {

/* Chain noise (differential Rx gain) calib data */
struct iwl_chain_noise_data {
- u8 state;
- u16 beacon_count;
+ u32 active_chains;
u32 chain_noise_a;
u32 chain_noise_b;
u32 chain_noise_c;
u32 chain_signal_a;
u32 chain_signal_b;
u32 chain_signal_c;
+ u16 beacon_count;
u8 disconn_array[NUM_RX_CHAINS];
u8 delta_gain_code[NUM_RX_CHAINS];
u8 radio_write;
+ u8 state;
};

#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 16f834d..bd6f600 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -252,12 +252,21 @@ static int iwl_update_power_command(struct iwl_priv *priv,
/*
* calucaute the final power mode index
*/
-int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
+int iwl_power_update_mode(struct iwl_priv *priv, bool force)
{
struct iwl_power_mgr *setting = &(priv->power_data);
int ret = 0;
u16 uninitialized_var(final_mode);

+ /* Don't update the RX chain when chain noise calibration is running */
+ if (priv->chain_noise_data.state != IWL_CHAIN_NOISE_DONE &&
+ priv->chain_noise_data.state != IWL_CHAIN_NOISE_ALIVE) {
+ IWL_DEBUG_POWER("Cannot update the power, chain noise "
+ "calibration running: %d\n",
+ priv->chain_noise_data.state);
+ return -EAGAIN;
+ }
+
/* If on battery, set to 3,
* if plugged into AC power, set to CAM ("continuously aware mode"),
* else user level */
@@ -285,7 +294,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
final_mode = IWL_POWER_MODE_CAM;

if (!iwl_is_rfkill(priv) && !setting->power_disabled &&
- ((setting->power_mode != final_mode) || refresh)) {
+ ((setting->power_mode != final_mode) || force)) {
struct iwl_powertable_cmd cmd;

if (final_mode != IWL_POWER_MODE_CAM)
@@ -359,35 +368,26 @@ EXPORT_SYMBOL(iwl_power_enable_management);
/* set user_power_setting */
int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
{
- int ret = 0;
-
if (mode > IWL_POWER_LIMIT)
return -EINVAL;

priv->power_data.user_power_setting = mode;

- ret = iwl_power_update_mode(priv, 0);
-
- return ret;
+ return iwl_power_update_mode(priv, 0);
}
EXPORT_SYMBOL(iwl_power_set_user_mode);

-
/* set system_power_setting. This should be set by over all
* PM application.
*/
int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
{
- int ret = 0;
-
if (mode > IWL_POWER_LIMIT)
return -EINVAL;

priv->power_data.system_power_setting = mode;

- ret = iwl_power_update_mode(priv, 0);
-
- return ret;
+ return iwl_power_update_mode(priv, 0);
}
EXPORT_SYMBOL(iwl_power_set_system_mode);

diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index aa99f36..a5c334f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -80,7 +80,7 @@ struct iwl_power_mgr {

void iwl_setup_power_deferred_work(struct iwl_priv *priv);
void iwl_power_cancel_timeout(struct iwl_priv *priv);
-int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh);
+int iwl_power_update_mode(struct iwl_priv *priv, bool force);
int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);
int iwl_power_enable_management(struct iwl_priv *priv);
int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
--
1.5.3.6


2008-09-03 03:31:24

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 22/39] iwlwifi: fix 64bit platform firmware loading

From: Tomas Winkler <[email protected]>

This patch fixes loading firmware from memory above 34bit.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-5000.c | 11 ++++-------
drivers/net/wireless/iwlwifi/iwl-fh.h | 1 +
2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index e04a26f..79ff288 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -533,14 +533,11 @@ static int iwl5000_load_section(struct iwl_priv *priv,
FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);

- /* FIME: write the MSB of the phy_addr in CTRL1
- * iwl_write_direct32(priv,
- IWL_FH_TFDIB_CTRL1_REG(IWL_FH_SRVC_CHNL),
- ((phy_addr & MSB_MSK)
- << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_count);
- */
iwl_write_direct32(priv,
- FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), byte_cnt);
+ FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
+ (iwl_get_dma_hi_address(phy_addr)
+ << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
+
iwl_write_direct32(priv,
FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 9446424..cd11c0c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -287,6 +287,7 @@

#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)

+#define FH_MEM_TFDIB_REG1_ADDR_BITSHIFT 28

/**
* Transmit DMA Channel Control/Status Registers (TCSR)
--
1.5.3.6


2008-09-05 22:50:26

by Abhijeet Kolekar

[permalink] [raw]
Subject: RE: [PATCH 08/39] iwl3945: replace association and beacon hooks with bss_info_changed cb



-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Johannes Berg
Sent: Friday, September 05, 2008 2:14 PM
To: Zhu, Yi
Cc: [email protected]; [email protected]; Kolekar, Abhijeet
Subject: Re: [PATCH 08/39] iwl3945: replace association and beacon hooks with bss_info_changed cb

On Wed, 2008-09-03 at 11:26 +0800, Zhu Yi wrote:
> From: Abhijeet Kolekar <[email protected]>
>
> Let mac80211 and bss_info_changed callback handle the association and
> beacon changes.

Nice.


> @@ -688,87 +688,6 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
>
> switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
> case IEEE80211_FTYPE_MGMT:

You can, umm, simplify all this code a bit now:
---------
Patch is on way :-)
Thanks
Abhijeet
---------

if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
return;
}

switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
case IEEE80211_FTYPE_MGMT:
case IEEE80211_FTYPE_DATA:
/* fall through */
default:
iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
break;
}


a single line can express the same :)

johannes

2008-09-03 03:31:16

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 16/39] iwlwifi: fix apm_stop function

From: Mohamed Abbas <[email protected]>

The patch fixes CSR_GP_CNTRL_REG_FLAG_INIT_DONE was set instead of
cleared which disabled move device to D0U state.

Signed-off-by: Mohamed Abbas <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 4 ++--
drivers/net/wireless/iwlwifi/iwl-5000.c | 3 ++-
2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index e258122..23fed32 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -474,8 +474,8 @@ static void iwl4965_apm_stop(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);

udelay(10);
-
- iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ /* clear "init complete" move adapter D0A* --> D0U state */
+ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
spin_unlock_irqrestore(&priv->lock, flags);
}

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index cbc01a0..d95fb42 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -145,7 +145,8 @@ static void iwl5000_apm_stop(struct iwl_priv *priv)

udelay(10);

- iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ /* clear "init complete" move adapter D0A* --> D0U state */
+ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);

spin_unlock_irqrestore(&priv->lock, flags);
}
--
1.5.3.6


2008-09-03 03:31:29

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 25/39] ath9k: change MIMO_PS to SM_PS

From: Ron Rindjunsky <[email protected]>

This patch follows 11n spec naming more accurately, replacing MIMO_PS
with SM_PS (Spatial Multiplexing Power Save).

Signed-off-by: Ron Rindjunsky <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/ath9k/main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index dc45eef..6ca4b89 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -223,7 +223,7 @@ static void setup_ht_cap(struct ieee80211_ht_info *ht_info)

ht_info->ht_supported = 1;
ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH
- |(u16)IEEE80211_HT_CAP_MIMO_PS
+ |(u16)IEEE80211_HT_CAP_SM_PS
|(u16)IEEE80211_HT_CAP_SGI_40
|(u16)IEEE80211_HT_CAP_DSSSCCK40;

--
1.5.3.6


2008-09-03 03:31:18

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 17/39] iwlwifi: generic init calibrations framework

From: Tomas Winkler <[email protected]>

This patch allows variable number of init calibrations and allows
addition new HW.

This patch also fixes critical bug. Only last calibration result
was applied. On reception of one calibration result all the calibration
was freed.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 7 +++
drivers/net/wireless/iwlwifi/iwl-5000.c | 63 ++++------------------------
drivers/net/wireless/iwlwifi/iwl-calib.c | 60 ++++++++++++++++++++++++++
drivers/net/wireless/iwlwifi/iwl-core.c | 19 +--------
drivers/net/wireless/iwlwifi/iwl-core.h | 8 +++-
drivers/net/wireless/iwlwifi/iwl-dev.h | 14 +++----
6 files changed, 90 insertions(+), 81 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 17d4f31..c479ee2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -129,6 +129,13 @@ struct iwl5000_shared {
__le32 padding2;
} __attribute__ ((packed));

+/* calibrations defined for 5000 */
+/* defines the order in which results should be sent to the runtime uCode */
+enum iwl5000_calib {
+ IWL5000_CALIB_LO,
+ IWL5000_CALIB_TX_IQ,
+ IWL5000_CALIB_TX_IQ_PERD,
+};

#endif /* __iwl_5000_hw_h__ */

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index d95fb42..e04a26f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -445,48 +445,6 @@ static int iwl5000_send_Xtal_calib(struct iwl_priv *priv)
sizeof(cal_cmd), &cal_cmd);
}

-static int iwl5000_send_calib_results(struct iwl_priv *priv)
-{
- int ret = 0;
-
- struct iwl_host_cmd hcmd = {
- .id = REPLY_PHY_CALIBRATION_CMD,
- .meta.flags = CMD_SIZE_HUGE,
- };
-
- if (priv->calib_results.lo_res) {
- hcmd.len = priv->calib_results.lo_res_len;
- hcmd.data = priv->calib_results.lo_res;
- ret = iwl_send_cmd_sync(priv, &hcmd);
-
- if (ret)
- goto err;
- }
-
- if (priv->calib_results.tx_iq_res) {
- hcmd.len = priv->calib_results.tx_iq_res_len;
- hcmd.data = priv->calib_results.tx_iq_res;
- ret = iwl_send_cmd_sync(priv, &hcmd);
-
- if (ret)
- goto err;
- }
-
- if (priv->calib_results.tx_iq_perd_res) {
- hcmd.len = priv->calib_results.tx_iq_perd_res_len;
- hcmd.data = priv->calib_results.tx_iq_perd_res;
- ret = iwl_send_cmd_sync(priv, &hcmd);
-
- if (ret)
- goto err;
- }
-
- return 0;
-err:
- IWL_ERROR("Error %d\n", ret);
- return ret;
-}
-
static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
{
struct iwl5000_calib_cfg_cmd calib_cfg_cmd;
@@ -511,33 +469,30 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
struct iwl5000_calib_hdr *hdr = (struct iwl5000_calib_hdr *)pkt->u.raw;
int len = le32_to_cpu(pkt->len) & FH_RSCSR_FRAME_SIZE_MSK;
-
- iwl_free_calib_results(priv);
+ int index;

/* reduce the size of the length field itself */
len -= 4;

+ /* Define the order in which the results will be sent to the runtime
+ * uCode. iwl_send_calib_results sends them in a row according to their
+ * index. We sort them here */
switch (hdr->op_code) {
case IWL5000_PHY_CALIBRATE_LO_CMD:
- priv->calib_results.lo_res = kzalloc(len, GFP_ATOMIC);
- priv->calib_results.lo_res_len = len;
- memcpy(priv->calib_results.lo_res, pkt->u.raw, len);
+ index = IWL5000_CALIB_LO;
break;
case IWL5000_PHY_CALIBRATE_TX_IQ_CMD:
- priv->calib_results.tx_iq_res = kzalloc(len, GFP_ATOMIC);
- priv->calib_results.tx_iq_res_len = len;
- memcpy(priv->calib_results.tx_iq_res, pkt->u.raw, len);
+ index = IWL5000_CALIB_TX_IQ;
break;
case IWL5000_PHY_CALIBRATE_TX_IQ_PERD_CMD:
- priv->calib_results.tx_iq_perd_res = kzalloc(len, GFP_ATOMIC);
- priv->calib_results.tx_iq_perd_res_len = len;
- memcpy(priv->calib_results.tx_iq_perd_res, pkt->u.raw, len);
+ index = IWL5000_CALIB_TX_IQ_PERD;
break;
default:
IWL_ERROR("Unknown calibration notification %d\n",
hdr->op_code);
return;
}
+ iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
}

static void iwl5000_rx_calib_complete(struct iwl_priv *priv,
@@ -835,7 +790,7 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
iwl5000_send_Xtal_calib(priv);

if (priv->ucode_type == UCODE_RT)
- iwl5000_send_calib_results(priv);
+ iwl_send_calib_results(priv);

return 0;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index ef49440..35fb4a4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -66,6 +66,66 @@
#include "iwl-core.h"
#include "iwl-calib.h"

+/*****************************************************************************
+ * INIT calibrations framework
+ *****************************************************************************/
+
+ int iwl_send_calib_results(struct iwl_priv *priv)
+{
+ int ret = 0;
+ int i = 0;
+
+ struct iwl_host_cmd hcmd = {
+ .id = REPLY_PHY_CALIBRATION_CMD,
+ .meta.flags = CMD_SIZE_HUGE,
+ };
+
+ for (i = 0; i < IWL_CALIB_MAX; i++)
+ if (priv->calib_results[i].buf) {
+ hcmd.len = priv->calib_results[i].buf_len;
+ hcmd.data = priv->calib_results[i].buf;
+ ret = iwl_send_cmd_sync(priv, &hcmd);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+err:
+ IWL_ERROR("Error %d iteration %d\n", ret, i);
+ return ret;
+}
+EXPORT_SYMBOL(iwl_send_calib_results);
+
+int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len)
+{
+ if (res->buf_len != len) {
+ kfree(res->buf);
+ res->buf = kzalloc(len, GFP_ATOMIC);
+ }
+ if (unlikely(res->buf == NULL))
+ return -ENOMEM;
+
+ res->buf_len = len;
+ memcpy(res->buf, buf, len);
+ return 0;
+}
+EXPORT_SYMBOL(iwl_calib_set);
+
+void iwl_calib_free_results(struct iwl_priv *priv)
+{
+ int i;
+
+ for (i = 0; i < IWL_CALIB_MAX; i++) {
+ kfree(priv->calib_results[i].buf);
+ priv->calib_results[i].buf = NULL;
+ priv->calib_results[i].buf_len = 0;
+ }
+}
+
+/*****************************************************************************
+ * RUNTIME calibrations framework
+ *****************************************************************************/
+
/* "false alarms" are signals that our DSP tries to lock onto,
* but then determines that they are either noise, or transmissions
* from a distant wireless network (also "noise", really) that get
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index bb03032..129b0a3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -933,22 +933,6 @@ err:
}
EXPORT_SYMBOL(iwl_init_drv);

-void iwl_free_calib_results(struct iwl_priv *priv)
-{
- kfree(priv->calib_results.lo_res);
- priv->calib_results.lo_res = NULL;
- priv->calib_results.lo_res_len = 0;
-
- kfree(priv->calib_results.tx_iq_res);
- priv->calib_results.tx_iq_res = NULL;
- priv->calib_results.tx_iq_res_len = 0;
-
- kfree(priv->calib_results.tx_iq_perd_res);
- priv->calib_results.tx_iq_perd_res = NULL;
- priv->calib_results.tx_iq_perd_res_len = 0;
-}
-EXPORT_SYMBOL(iwl_free_calib_results);
-
int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
{
int ret = 0;
@@ -976,10 +960,9 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
}
EXPORT_SYMBOL(iwl_set_tx_power);

-
void iwl_uninit_drv(struct iwl_priv *priv)
{
- iwl_free_calib_results(priv);
+ iwl_calib_free_results(priv);
iwlcore_free_geos(priv);
iwl_free_channel_map(priv);
kfree(priv->scan);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index ff86abc..b5db050 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -186,7 +186,6 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
void iwl_hw_detect(struct iwl_priv *priv);

void iwl_clear_stations_table(struct iwl_priv *priv);
-void iwl_free_calib_results(struct iwl_priv *priv);
void iwl_reset_qos(struct iwl_priv *priv);
void iwl_set_rxon_chain(struct iwl_priv *priv);
int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
@@ -289,6 +288,13 @@ int iwl_scan_initiate(struct iwl_priv *priv);
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);

+/*******************************************************************************
+ * Calibrations - implemented in iwl-calib.c
+ ******************************************************************************/
+int iwl_send_calib_results(struct iwl_priv *priv);
+int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
+void iwl_calib_free_results(struct iwl_priv *priv);
+
/*****************************************************
* S e n d i n g H o s t C o m m a n d s *
*****************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 0711b35..5a55c87 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -728,13 +728,10 @@ struct statistics_general_data {
u32 beacon_energy_c;
};

-struct iwl_calib_results {
- void *tx_iq_res;
- void *tx_iq_perd_res;
- void *lo_res;
- u32 tx_iq_res_len;
- u32 tx_iq_perd_res_len;
- u32 lo_res_len;
+/* Opaque calibration results */
+struct iwl_calib_result {
+ void *buf;
+ size_t buf_len;
};

enum ucode_type {
@@ -796,6 +793,7 @@ enum {


#define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */
+#define IWL_CALIB_MAX 3

struct iwl_priv {

@@ -839,7 +837,7 @@ struct iwl_priv {
s32 last_temperature;

/* init calibration results */
- struct iwl_calib_results calib_results;
+ struct iwl_calib_result calib_results[IWL_CALIB_MAX];

/* Scan related variables */
unsigned long last_scan_jiffies;
--
1.5.3.6


2008-09-03 03:31:22

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 20/39] iwlwifi: use station's mimo power save values

From: Ron Rindjunsky <[email protected]>

This patch fixes the wrong use of self mimo power save values instead of
peer's mimo power save values.

Signed-off-by: Ron Rindjunsky <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 3 ++-
drivers/net/wireless/iwlwifi/iwl-agn.c | 2 --
drivers/net/wireless/iwlwifi/iwl-dev.h | 1 -
3 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 754fef5..90a2b6d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1153,7 +1153,8 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
!sta->ht_info.ht_supported)
return -1;

- if (priv->current_ht_config.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC)
+ if (((sta->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS) >> 2)
+ == IWL_MIMO_PS_STATIC)
return -1;

/* Need both Tx chains/antennas to support MIMO */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index f3c96ad..326ab01 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -586,8 +586,6 @@ static void iwl4965_ht_conf(struct iwl_priv *priv,
iwl_conf->supported_chan_width = 0;
}

- iwl_conf->tx_mimo_ps_mode =
- (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);

iwl_conf->control_channel = ht_bss_conf->primary_channel;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 5a55c87..ee38697 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -412,7 +412,6 @@ struct iwl_ht_info {
/* self configuration data */
u8 is_ht;
u8 supported_chan_width;
- u16 tx_mimo_ps_mode;
u8 is_green_field;
u8 sgf; /* HT_SHORT_GI_* short guard interval */
u8 max_amsdu_size;
--
1.5.3.6


2008-09-03 03:31:31

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 27/39] iwlwifi: rename ps_mode to sm_ps

From: Ron Rindjunsky <[email protected]>

This patch renames iwl_priv.ps_mode for clearer
iwl_priv.current_ht_config.sm_ps (spatial multiplexing power save).

Signed-off-by: Ron Rindjunsky <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++--
drivers/net/wireless/iwlwifi/iwl-core.c | 10 ++++++----
drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +-
3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 74fe85a..aad0ddc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -564,8 +564,6 @@ static void iwl4965_ht_conf(struct iwl_priv *priv,
if (!iwl_conf->is_ht)
return;

- priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
-
if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
@@ -586,6 +584,8 @@ static void iwl4965_ht_conf(struct iwl_priv *priv,
iwl_conf->supported_chan_width = 0;
}

+ iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
+
memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);

iwl_conf->control_channel = ht_bss_conf->primary_channel;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index fa48615..b29c84a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -709,7 +709,8 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);

/* # of Rx chains to use when expecting MIMO. */
- if (is_single || (!is_cam && (priv->ps_mode == WLAN_HT_CAP_SM_PS_STATIC)))
+ if (is_single || (!is_cam && (priv->current_ht_config.sm_ps ==
+ WLAN_HT_CAP_SM_PS_STATIC)))
return 2;
else
return 3;
@@ -720,7 +721,7 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
int idle_cnt;
bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
/* # Rx chains when idling and maybe trying to save power */
- switch (priv->ps_mode) {
+ switch (priv->current_ht_config.sm_ps) {
case WLAN_HT_CAP_SM_PS_STATIC:
case WLAN_HT_CAP_SM_PS_DYNAMIC:
idle_cnt = (is_cam) ? 2 : 1;
@@ -730,7 +731,8 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
break;
case WLAN_HT_CAP_SM_PS_INVALID:
default:
- IWL_ERROR("invalide mimo ps mode %d\n", priv->ps_mode);
+ IWL_ERROR("invalide mimo ps mode %d\n",
+ priv->current_ht_config.sm_ps);
WARN_ON(1);
idle_cnt = -1;
break;
@@ -908,7 +910,7 @@ int iwl_init_drv(struct iwl_priv *priv)
priv->iw_mode = IEEE80211_IF_TYPE_STA;

priv->use_ant_b_for_management_frame = 1; /* start with ant B */
- priv->ps_mode = WLAN_HT_CAP_SM_PS_DISABLED;
+ priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;

/* Choose which receivers/antennas to use */
iwl_set_rxon_chain(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 1b11664..45ae68a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -412,6 +412,7 @@ struct iwl_ht_info {
/* self configuration data */
u8 is_ht;
u8 supported_chan_width;
+ u8 sm_ps;
u8 is_green_field;
u8 sgf; /* HT_SHORT_GI_* short guard interval */
u8 max_amsdu_size;
@@ -996,7 +997,6 @@ struct iwl_priv {
* hardware */
u16 assoc_id;
u16 assoc_capability;
- u8 ps_mode;

struct iwl_qos_info qos_data;

--
1.5.3.6


2008-09-03 03:31:12

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 13/39] iwlwifi: void full rxon on rx chain changes

From: Mohamed Abbas <[email protected]>

Rx chain might change during power save transitions but it doesn't
requires full rxon.

Signed-off-by: Mohamed Abbas <[email protected]
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index d436f70..e903aeb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -181,14 +181,14 @@ static int iwl4965_check_rxon_cmd(struct iwl_rxon_cmd *rxon)
}

/**
- * iwl4965_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
+ * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
* @priv: staging_rxon is compared to active_rxon
*
* If the RXON structure is changing enough to require a new tune,
* or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
* a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
*/
-static int iwl4965_full_rxon_required(struct iwl_priv *priv)
+static int iwl_full_rxon_required(struct iwl_priv *priv)
{

/* These items are only settable from the full RXON command */
@@ -207,7 +207,6 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv)
priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
(priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
- (priv->staging_rxon.rx_chain != priv->active_rxon.rx_chain) ||
(priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
return 1;

@@ -263,7 +262,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)
/* If we don't need to send a full RXON, we can use
* iwl4965_rxon_assoc_cmd which is used to reconfigure filter
* and other flags for the current radio configuration. */
- if (!iwl4965_full_rxon_required(priv)) {
+ if (!iwl_full_rxon_required(priv)) {
ret = iwl_send_rxon_assoc(priv);
if (ret) {
IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret);
--
1.5.3.6


2008-09-03 03:31:21

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 19/39] iwlwifi: fix strict_strtoul error checking

From: Emmanuel Grumbach <[email protected]>

This patch fixes handling of strcit_strtoul return value
"0 == sucess".

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 2330ed1..f3c96ad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3728,7 +3728,7 @@ static ssize_t store_flags(struct device *d,
unsigned long val;
u32 flags;
int ret = strict_strtoul(buf, 0, &val);
- if (!ret)
+ if (ret)
return ret;
flags = (u32)val;

@@ -3767,7 +3767,7 @@ static ssize_t store_filter_flags(struct device *d,
unsigned long val;
u32 filter_flags;
int ret = strict_strtoul(buf, 0, &val);
- if (!ret)
+ if (ret)
return ret;
filter_flags = (u32)val;

@@ -3907,7 +3907,7 @@ static ssize_t store_power_level(struct device *d,
}

ret = strict_strtoul(buf, 10, &mode);
- if (!ret)
+ if (ret)
goto out;

ret = iwl_power_set_user_mode(priv, mode);
--
1.5.3.6


2008-09-03 03:31:42

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 36/39] iwlwifi: remove uneeded declarations

From: Emmanuel Grumbach <[email protected]>

This patch cleans up iwlwifi by removing uneeded declarations and removing
uneeded symbol export reducing the namespace pollution. It also fixes some
typos in comments.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 3 +-
drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-core.c | 9 ++----
drivers/net/wireless/iwlwifi/iwl-core.h | 10 +------
drivers/net/wireless/iwlwifi/iwl-dev.h | 45 ++++++++---------------------
drivers/net/wireless/iwlwifi/iwl-power.c | 8 ++--
drivers/net/wireless/iwlwifi/iwl-power.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-scan.c | 3 +-
drivers/net/wireless/iwlwifi/iwl-tx.c | 9 ++----
9 files changed, 28 insertions(+), 63 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index d9c4fdb..d2569a2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1607,8 +1607,7 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
return ret;
}

-
-int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
+static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
{
int rc;
u8 band = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 45cdf31..cf882bf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -485,7 +485,7 @@ static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv)
return IWL_RATE_6M_PLCP;
}

-unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
+static unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl_frame *frame, u8 rate)
{
struct iwl_tx_beacon_cmd *tx_beacon_cmd;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 134f4ee..0901e43 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -801,7 +801,7 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
else
priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;

- IWL_DEBUG_ASSOC("rx_chain=0x%Xi active=%d idle=%d\n",
+ IWL_DEBUG_ASSOC("rx_chain=0x%X active=%d idle=%d\n",
priv->staging_rxon.rx_chain,
active_rx_cnt, idle_rx_cnt);

@@ -1154,7 +1154,6 @@ int iwl_verify_ucode(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_verify_ucode);

-
static const char *desc_lookup(int i)
{
switch (i) {
@@ -1235,9 +1234,9 @@ EXPORT_SYMBOL(iwl_dump_nic_error_log);
/**
* iwl_print_event_log - Dump error event log to syslog
*
- * NOTE: Must be called with iwl4965_grab_nic_access() already obtained!
+ * NOTE: Must be called with iwl_grab_nic_access() already obtained!
*/
-void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
+static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
u32 num_events, u32 mode)
{
u32 i;
@@ -1278,8 +1277,6 @@ void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
}
}
}
-EXPORT_SYMBOL(iwl_print_event_log);
-

void iwl_dump_nic_event_log(struct iwl_priv *priv)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index b5db050..55a4b58 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -184,7 +184,6 @@ struct iwl_cfg {
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_clear_stations_table(struct iwl_priv *priv);
void iwl_reset_qos(struct iwl_priv *priv);
void iwl_set_rxon_chain(struct iwl_priv *priv);
@@ -215,7 +214,6 @@ void iwl_rx_replenish(struct iwl_priv *priv);
int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
int iwl_rx_agg_start(struct iwl_priv *priv, const u8 *addr, int tid, u16 ssn);
int iwl_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid);
-/* FIXME: remove when TX is moved to iwl core */
int iwl_rx_queue_restock(struct iwl_priv *priv);
int iwl_rx_queue_space(const struct iwl_rx_queue *q);
void iwl_rx_allocate(struct iwl_priv *priv);
@@ -234,11 +232,7 @@ void iwl_rx_statistics(struct iwl_priv *priv,
******************************************************/
int iwl_txq_ctx_reset(struct iwl_priv *priv);
int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
-/* FIXME: remove when free Tx is fully merged into iwlcore */
-int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
-int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd,
- dma_addr_t addr, u16 len);
int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
@@ -253,6 +247,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
* RF -Kill - here and not in iwl-rfkill.h to be available when
* RF-kill subsystem is not compiled.
****************************************************/
+void iwl_rf_kill(struct iwl_priv *priv);
void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv);
int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv);

@@ -283,7 +278,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
void iwl_init_scan_params(struct iwl_priv *priv);
int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
-const char *iwl_escape_essid(const char *essid, u8 essid_len);
int iwl_scan_initiate(struct iwl_priv *priv);
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
@@ -316,8 +310,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
/*****************************************************
* Error Handling Debugging
******************************************************/
-void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
- u32 num_events, u32 mode);
void iwl_dump_nic_error_log(struct iwl_priv *priv);
void iwl_dump_nic_event_log(struct iwl_priv *priv);

diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 6e150f6..1823687 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -565,50 +565,31 @@ struct iwl_hw_params {
#define IWL_RX_STATS(x) (&x->u.rx_frame.stats)
#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload)

-
-/******************************************************************************
- *
- * Functions implemented in iwl-base.c which are forward declared here
- * for use by iwl-*.c
- *
- *****************************************************************************/
-struct iwl_addsta_cmd;
-extern int iwl_send_add_sta(struct iwl_priv *priv,
- struct iwl_addsta_cmd *sta, u8 flags);
-u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
- u8 flags, struct ieee80211_ht_info *ht_info);
-extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr,
- const u8 *dest, int left);
-extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
-int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
-extern int iwl4965_set_power(struct iwl_priv *priv, void *cmd);
-
-extern const u8 iwl_bcast_addr[ETH_ALEN];
-
/******************************************************************************
*
- * Functions implemented in iwl-[34]*.c which are forward declared here
- * for use by iwl-base.c
+ * Functions implemented in core module which are forward declared here
+ * for use by iwl-[4-5].c
*
- * NOTE: The implementation of these functions are hardware specific
- * which is why they are in the hardware specific files (vs. iwl-base.c)
+ * NOTE: The implementation of these functions are not hardware specific
+ * which is why they are in the core module files.
*
* Naming convention --
- * iwl4965_ <-- Its part of iwlwifi (should be changed to iwl4965_)
- * iwl4965_hw_ <-- Hardware specific (implemented in iwl-XXXX.c by all HW)
+ * iwl_ <-- Is part of iwlwifi
* iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX)
* iwl4965_bg_ <-- Called from work queue context
* iwl4965_mac_ <-- mac80211 callback
*
****************************************************************************/
+struct iwl_addsta_cmd;
+extern int iwl_send_add_sta(struct iwl_priv *priv,
+ struct iwl_addsta_cmd *sta, u8 flags);
+extern u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr,
+ int is_ap, u8 flags, struct ieee80211_ht_info *ht_info);
+extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
+extern int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
+extern const u8 iwl_bcast_addr[ETH_ALEN];
extern int iwl_rxq_stop(struct iwl_priv *priv);
extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
-extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
- struct iwl_frame *frame, u8 rate);
-extern void iwl4965_disable_events(struct iwl_priv *priv);
-
-extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel);
extern int iwl_queue_space(const struct iwl_queue *q);
static inline int iwl_queue_used(const struct iwl_queue *q, int i)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index bd6f600..55ec31e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -250,7 +250,7 @@ static int iwl_update_power_command(struct iwl_priv *priv,


/*
- * calucaute the final power mode index
+ * compute the final power mode index
*/
int iwl_power_update_mode(struct iwl_priv *priv, bool force)
{
@@ -267,9 +267,9 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
return -EAGAIN;
}

- /* If on battery, set to 3,
- * if plugged into AC power, set to CAM ("continuously aware mode"),
- * else user level */
+ /* If on battery, set to 3,
+ * if plugged into AC power, set to CAM ("continuously aware mode"),
+ * else user level */

switch (setting->system_power_setting) {
case IWL_POWER_SYS_AUTO:
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index a5c334f..df484a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -72,7 +72,7 @@ struct iwl_power_mgr {
/* final power level that used to calculate final power command */
u8 power_mode;
u8 user_power_setting; /* set by user through mac80211 or sysfs */
- u8 system_power_setting; /* set by kernel syatem tools */
+ u8 system_power_setting; /* set by kernel system tools */
u8 critical_power_setting; /* set if driver over heated */
u8 is_battery_active; /* DC/AC power */
u8 power_disabled; /* flag to disable using power saving level */
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 6c8ac3a..d026aaf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -88,7 +88,7 @@ static int iwl_is_empty_essid(const char *essid, int essid_len)



-const char *iwl_escape_essid(const char *essid, u8 essid_len)
+static const char *iwl_escape_essid(const char *essid, u8 essid_len)
{
static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
const char *s = essid;
@@ -111,7 +111,6 @@ const char *iwl_escape_essid(const char *essid, u8 essid_len)
*d = '\0';
return escaped;
}
-EXPORT_SYMBOL(iwl_escape_essid);

/**
* iwl_scan_cancel - Cancel any currently executing HW scan
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 4b4a2bc..9ef6451 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -63,7 +63,7 @@ static const u16 default_tid_to_tx_fifo[] = {
* Does NOT advance any TFD circular buffer read/write indexes
* Does NOT free the TFD itself (which is within circular buffer)
*/
-int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+static int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
{
struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0];
struct iwl_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
@@ -115,10 +115,8 @@ int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
}
return 0;
}
-EXPORT_SYMBOL(iwl_hw_txq_free_tfd);

-
-int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
+static int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
dma_addr_t addr, u16 len)
{
int index, is_odd;
@@ -151,7 +149,6 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,

return 0;
}
-EXPORT_SYMBOL(iwl_hw_txq_attach_buf_to_tfd);

/**
* iwl_txq_update_write_ptr - Send new write index to hardware
@@ -478,7 +475,6 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_hw_txq_ctx_free);

-
/**
* iwl_txq_ctx_reset - Reset TX queue context
* Destroys all DMA structures and initialise them again
@@ -545,6 +541,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
error_kw:
return ret;
}
+
/**
* iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
*/
--
1.5.3.6


2008-09-03 03:31:10

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 11/39] iwl3945: avoid redundant iwl3945_get_active_dwell_time

From: Abhijeet Kolekar <[email protected]>

iwl3945_get_active_dwell_time is called twice within the same context.
The patch removes one instance.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 70dfe9d..709be78 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -4814,7 +4814,6 @@ static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv,
static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,
enum ieee80211_band band)
{
- u16 active = iwl3945_get_active_dwell_time(priv, band);
u16 passive = (band == IEEE80211_BAND_2GHZ) ?
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
@@ -4829,9 +4828,6 @@ static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv,
passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
}

- if (passive <= active)
- passive = active + 1;
-
return passive;
}

@@ -4856,6 +4852,9 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
active_dwell = iwl3945_get_active_dwell_time(priv, band);
passive_dwell = iwl3945_get_passive_dwell_time(priv, band);

+ if (passive_dwell <= active_dwell)
+ passive_dwell = active_dwell + 1;
+
for (i = 0, added = 0; i < sband->n_channels; i++) {
if (channels[i].flags & IEEE80211_CHAN_DISABLED)
continue;
--
1.5.3.6


2008-09-03 03:31:19

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 18/39] iwlwifi: call apm stop on exit

From: Gregory Greenman <[email protected]>

This patch calls apm stop on exit and suspend and sets STATUS_EXIT_PENDING
accordingly.

Signed-off-by: Gregory Greenman <[email protected]>
Signed-off-by: Mohamed Abbas <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 16 +++++++++++-----
1 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index e903aeb..2330ed1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2189,7 +2189,10 @@ static void __iwl4965_down(struct iwl_priv *priv)
udelay(5);

/* FIXME: apm_ops.suspend(priv) */
- priv->cfg->ops->lib->apm_ops.reset(priv);
+ if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+ priv->cfg->ops->lib->apm_ops.stop(priv);
+ else
+ priv->cfg->ops->lib->apm_ops.reset(priv);
priv->cfg->ops->lib->free_shared_mem(priv);

exit:
@@ -4375,15 +4378,18 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
iwl_dbgfs_unregister(priv);
sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);

+ /* ieee80211_unregister_hw call wil cause iwl4965_mac_stop to
+ * to be called and iwl4965_down since we are removing the device
+ * we need to set STATUS_EXIT_PENDING bit.
+ */
+ set_bit(STATUS_EXIT_PENDING, &priv->status);
if (priv->mac80211_registered) {
ieee80211_unregister_hw(priv->hw);
priv->mac80211_registered = 0;
+ } else {
+ iwl4965_down(priv);
}

- set_bit(STATUS_EXIT_PENDING, &priv->status);
-
- iwl4965_down(priv);
-
/* make sure we flush any pending irq or
* tasklet for the driver
*/
--
1.5.3.6


2008-09-03 03:31:27

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 24/39] iwlwifi: change MIMO_PS to SM_PS

From: Ron Rindjunsky <[email protected]>

This patch follows 11n spec naming more accurately, replacing MIMO_PS
with SM_PS (Spatial Multiplexing Power Save).

Signed-off-by: Ron Rindjunsky <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-core.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-sta.c | 8 ++++----
4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 90a2b6d..609ad1d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1153,7 +1153,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
!sta->ht_info.ht_supported)
return -1;

- if (((sta->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS) >> 2)
+ if (((sta->ht_info.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
== IWL_MIMO_PS_STATIC)
return -1;

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 326ab01..74fe85a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -564,7 +564,7 @@ static void iwl4965_ht_conf(struct iwl_priv *priv,
if (!iwl_conf->is_ht)
return;

- priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
+ priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);

if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index e55a62d..e2f06aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -399,7 +399,7 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,

ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD;
ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20;
- ht_info->cap |= (u16)(IEEE80211_HT_CAP_MIMO_PS &
+ ht_info->cap |= (u16)(IEEE80211_HT_CAP_SM_PS &
(IWL_MIMO_PS_NONE << 2));

max_bit_rate = MAX_BIT_RATE_20_MHZ;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 6283a3a..3c0204c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -191,20 +191,20 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
if (!sta_ht_inf || !sta_ht_inf->ht_supported)
goto done;

- mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2;
+ mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;

sta_flags = priv->stations[index].sta.station_flags;

sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);

switch (mimo_ps_mode) {
- case WLAN_HT_CAP_MIMO_PS_STATIC:
+ case WLAN_HT_CAP_SM_PS_STATIC:
sta_flags |= STA_FLG_MIMO_DIS_MSK;
break;
- case WLAN_HT_CAP_MIMO_PS_DYNAMIC:
+ case WLAN_HT_CAP_SM_PS_DYNAMIC:
sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
break;
- case WLAN_HT_CAP_MIMO_PS_DISABLED:
+ case WLAN_HT_CAP_SM_PS_DISABLED:
break;
default:
IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode);
--
1.5.3.6


2008-09-03 03:31:05

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 07/39] iwl3945: fix unbalanced mutex

From: Abhijeet Kolekar <[email protected]>

The patch removes unlocking of mutex from post_associate.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 6d27264..85581b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -6339,10 +6339,9 @@ static void iwl3945_post_associate(struct iwl3945_priv *priv)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;

- if (!priv->vif || !priv->is_open) {
- mutex_unlock(&priv->mutex);
+ if (!priv->vif || !priv->is_open)
return;
- }
+
iwl3945_scan_cancel_timeout(priv, 200);

conf = ieee80211_get_hw_conf(priv->hw);
--
1.5.3.6


2008-09-03 03:31:14

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 14/39] iwlwifi: replace readl and writel with io/read/write/32

From: Tomas Winkler <[email protected]>

This patch replaces readl and writel with more cross platform ioread32
and iowrite32.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945-io.h | 6 +++---
drivers/net/wireless/iwlwifi/iwl-io.h | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
index 0b94751..98740e8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-io.h
@@ -59,7 +59,7 @@
*
*/

-#define _iwl3945_write32(priv, ofs, val) writel((val), (priv)->hw_base + (ofs))
+#define _iwl3945_write32(priv, ofs, val) iowrite32((val), (priv)->hw_base + (ofs))
#ifdef CONFIG_IWL3945_DEBUG
static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *priv,
u32 ofs, u32 val)
@@ -73,14 +73,14 @@ static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *
#define iwl3945_write32(priv, ofs, val) _iwl3945_write32(priv, ofs, val)
#endif

-#define _iwl3945_read32(priv, ofs) readl((priv)->hw_base + (ofs))
+#define _iwl3945_read32(priv, ofs) ioread32((priv)->hw_base + (ofs))
#ifdef CONFIG_IWL3945_DEBUG
static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *priv, u32 ofs)
{
IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l);
return _iwl3945_read32(priv, ofs);
}
-#define iwl3945_read32(priv, ofs) __iwl3945_read32(__FILE__, __LINE__, priv, ofs)
+#define iwl3945_read32(priv, ofs)__iwl3945_read32(__FILE__, __LINE__, priv, ofs)
#else
#define iwl3945_read32(p, o) _iwl3945_read32(p, o)
#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 5bc3df4..17fb4e2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -61,7 +61,7 @@
*
*/

-#define _iwl_write32(priv, ofs, val) writel((val), (priv)->hw_base + (ofs))
+#define _iwl_write32(priv, ofs, val) iowrite32((val), (priv)->hw_base + (ofs))
#ifdef CONFIG_IWLWIFI_DEBUG
static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
u32 ofs, u32 val)
@@ -75,7 +75,7 @@ static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
#define iwl_write32(priv, ofs, val) _iwl_write32(priv, ofs, val)
#endif

-#define _iwl_read32(priv, ofs) readl((priv)->hw_base + (ofs))
+#define _iwl_read32(priv, ofs) ioread32((priv)->hw_base + (ofs))
#ifdef CONFIG_IWLWIFI_DEBUG
static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs)
{
--
1.5.3.6


2008-09-03 03:31:36

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 31/39] iwlwifi: fix memory allocation of TX command

From: Tomas Winkler <[email protected]>

This patch removes GFP_DMA from allocation tx command buffers
GFP_DMA allows allocation only for memory under 16M which causes
allocation problems suspend/resume flows.

Using kmalloc is temporal solution and some consistent/coherent
allocation schema will be more correct. Since iwlwifi hardware
supports 64bit address this solution should work on x86 (32 and
64bit) for now. This patch also fixes memory freeing in error path.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Ian Schram <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-tx.c | 29 ++++++++++++++++++-----------
1 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 6cba5e9..68567fa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -402,12 +402,11 @@ static int iwl_hw_tx_queue_init(struct iwl_priv *priv,
/**
* iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
*/
-static int iwl_tx_queue_init(struct iwl_priv *priv,
- struct iwl_tx_queue *txq,
+static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id)
{
int i, len;
- int rc = 0;
+ int ret;

/*
* Alloc buffer array for commands (Tx or other types of commands).
@@ -426,19 +425,16 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
continue;
}

- txq->cmd[i] = kmalloc(len, GFP_KERNEL | GFP_DMA);
+ txq->cmd[i] = kmalloc(len, GFP_KERNEL);
if (!txq->cmd[i])
- return -ENOMEM;
+ goto err;
}

/* Alloc driver data array and TFD circular buffer */
- rc = iwl_tx_queue_alloc(priv, txq, txq_id);
- if (rc) {
- for (i = 0; i < slots_num; i++)
- kfree(txq->cmd[i]);
+ ret = iwl_tx_queue_alloc(priv, txq, txq_id);
+ if (ret)
+ goto err;

- return -ENOMEM;
- }
txq->need_update = 0;

/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
@@ -452,6 +448,17 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
iwl_hw_tx_queue_init(priv, txq);

return 0;
+err:
+ for (i = 0; i < slots_num; i++) {
+ kfree(txq->cmd[i]);
+ txq->cmd[i] = NULL;
+ }
+
+ if (txq_id == IWL_CMD_QUEUE_NUM) {
+ kfree(txq->cmd[slots_num]);
+ txq->cmd[slots_num] = NULL;
+ }
+ return -ENOMEM;
}
/**
* iwl_hw_txq_ctx_free - Free TXQ Context
--
1.5.3.6


2008-09-03 03:31:39

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 34/39] iwlwifi: take a fresh set of supported rates at each cycle

From: Emmanuel Grumbach <[email protected]>

This patch fixes regression in iwlwifi IBSS rate scaling caused by the
patch named "mac80211: eliminate IBSS warning in rate_lowest_index()"
by Vladimir Koutny <[email protected]>.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index c1b70c8..169c548 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1669,6 +1669,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
return;

lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
+ lq_sta->supp_rates = sta->supp_rates[lq_sta->band];

tid = rs_tl_add_packet(lq_sta, hdr);

--
1.5.3.6


2008-09-03 03:31:00

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 03/39] iwlwifi: clean up hw scan handler

From: Tomas Winkler <[email protected]>

This patch cleans up iwl_mac_hw_scan handler.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 35 ++++++++++++++-----------------
1 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 1badcf3..1073fa0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3179,9 +3179,9 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,

}

-static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
+static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
{
- int rc = 0;
+ int ret;
unsigned long flags;
struct iwl_priv *priv = hw->priv;

@@ -3191,41 +3191,38 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
spin_lock_irqsave(&priv->lock, flags);

if (!iwl_is_ready_rf(priv)) {
- rc = -EIO;
+ ret = -EIO;
IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
goto out_unlock;
}

if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { /* APs don't scan */
- rc = -EIO;
+ ret = -EIO;
IWL_ERROR("ERROR: APs don't scan\n");
goto out_unlock;
}

/* we don't schedule scan within next_scan_jiffies period */
if (priv->next_scan_jiffies &&
- time_after(priv->next_scan_jiffies, jiffies)) {
- rc = -EAGAIN;
+ time_after(priv->next_scan_jiffies, jiffies)) {
+ ret = -EAGAIN;
goto out_unlock;
}
/* if we just finished scan ask for delay */
- if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies +
- IWL_DELAY_NEXT_SCAN, jiffies)) {
- rc = -EAGAIN;
+ if (priv->last_scan_jiffies &&
+ time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
+ ret = -EAGAIN;
goto out_unlock;
}
- if (len) {
- IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
- iwl_escape_essid(ssid, len), (int)len);
-
+ if (ssid_len) {
priv->one_direct_scan = 1;
- priv->direct_ssid_len = (u8)
- min((u8) len, (u8) IW_ESSID_MAX_SIZE);
+ priv->direct_ssid_len = min_t(u8, ssid_len, IW_ESSID_MAX_SIZE);
memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
- } else
+ } else {
priv->one_direct_scan = 0;
+ }

- rc = iwl_scan_initiate(priv);
+ ret = iwl_scan_initiate(priv);

IWL_DEBUG_MAC80211("leave\n");

@@ -3233,7 +3230,7 @@ out_unlock:
spin_unlock_irqrestore(&priv->lock, flags);
mutex_unlock(&priv->mutex);

- return rc;
+ return ret;
}

static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
@@ -4140,7 +4137,7 @@ static struct ieee80211_ops iwl4965_hw_ops = {
.reset_tsf = iwl4965_mac_reset_tsf,
.bss_info_changed = iwl4965_bss_info_changed,
.ampdu_action = iwl4965_mac_ampdu_action,
- .hw_scan = iwl4965_mac_hw_scan
+ .hw_scan = iwl_mac_hw_scan
};

static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
--
1.5.3.6


2008-09-03 03:30:57

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 01/39] iwlwifi : Added bss_info_changed callback to 3945

From: Abhijeet Kolekar <[email protected]>

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

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index a622fc3..6d27264 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -6320,11 +6320,8 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)

#define IWL_DELAY_NEXT_SCAN (HZ*2)

-static void iwl3945_bg_post_associate(struct work_struct *data)
+static void iwl3945_post_associate(struct iwl3945_priv *priv)
{
- struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv,
- post_associate.work);
-
int rc = 0;
struct ieee80211_conf *conf = NULL;
DECLARE_MAC_BUF(mac);
@@ -6342,8 +6339,6 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;

- mutex_lock(&priv->mutex);
-
if (!priv->vif || !priv->is_open) {
mutex_unlock(&priv->mutex);
return;
@@ -6419,6 +6414,15 @@ static void iwl3945_bg_post_associate(struct work_struct *data)

/* we have just associated, don't start scan too early */
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
+}
+
+static void iwl3945_bg_post_associate(struct work_struct *data)
+{
+ struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv,
+ post_associate.work);
+
+ mutex_lock(&priv->mutex);
+ iwl3945_post_associate(priv);
mutex_unlock(&priv->mutex);
}

@@ -6948,6 +6952,63 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211("leave\n");
}

+#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
+
+static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *bss_conf,
+ u32 changes)
+{
+ struct iwl3945_priv *priv = hw->priv;
+
+ IWL_DEBUG_MAC80211("changes = 0x%X\n", changes);
+
+ if (changes & BSS_CHANGED_ERP_PREAMBLE) {
+ IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n",
+ bss_conf->use_short_preamble);
+ if (bss_conf->use_short_preamble)
+ priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ else
+ priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ }
+
+ if (changes & BSS_CHANGED_ERP_CTS_PROT) {
+ IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot);
+ if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
+ priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
+ else
+ priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+ }
+
+ if (changes & BSS_CHANGED_ASSOC) {
+ IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc);
+ /* This should never happen as this function should
+ * never be called from interrupt context. */
+ if (WARN_ON_ONCE(in_interrupt()))
+ return;
+ if (bss_conf->assoc) {
+ priv->assoc_id = bss_conf->aid;
+ priv->beacon_int = bss_conf->beacon_int;
+ priv->timestamp0 = bss_conf->timestamp & 0xFFFFFFFF;
+ priv->timestamp1 = (bss_conf->timestamp >> 32) &
+ 0xFFFFFFFF;
+ priv->assoc_capability = bss_conf->assoc_capability;
+ priv->next_scan_jiffies = jiffies +
+ IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
+ mutex_lock(&priv->mutex);
+ iwl3945_post_associate(priv);
+ mutex_unlock(&priv->mutex);
+ } else {
+ priv->assoc_id = 0;
+ IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc);
+ }
+ } else if (changes && iwl3945_is_associated(priv) && priv->assoc_id) {
+ IWL_DEBUG_MAC80211("Associated Changes %d\n", changes);
+ iwl3945_send_rxon_assoc(priv);
+ }
+
+}
+
static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
{
int rc = 0;
@@ -7828,6 +7889,7 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.conf_tx = iwl3945_mac_conf_tx,
.get_tsf = iwl3945_mac_get_tsf,
.reset_tsf = iwl3945_mac_reset_tsf,
+ .bss_info_changed = iwl3945_bss_info_changed,
.hw_scan = iwl3945_mac_hw_scan
};

--
1.5.3.6


2008-09-03 03:31:36

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 30/39] iwlwifi: allow association on radar channel in power save

From: Emmanuel Grumbach <[email protected]>

This patch disables power save upon association and enables it back
after association. This allows to associate to AP on a radar channel
if power save is enabled.

Radar and passive channels are not allowed for TX (required for association)
unless RX is received but PS may close the radio and no RX will be received
effectively failing association.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Mohamed Abbas <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 24 ++++++++++++++----
drivers/net/wireless/iwlwifi/iwl-dev.h | 1 +
drivers/net/wireless/iwlwifi/iwl-power.c | 39 +++++++++++++++++++++++++++++-
drivers/net/wireless/iwlwifi/iwl-power.h | 4 ++-
4 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 3743e4b..42cb3dd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2486,6 +2486,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
if (!priv->vif || !priv->is_open)
return;

+ iwl_power_cancel_timeout(priv);
iwl_scan_cancel_timeout(priv, 200);

conf = ieee80211_get_hw_conf(priv->hw);
@@ -2550,10 +2551,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
break;
}

- /* Enable Rx differential gain and sensitivity calibrations */
- iwl_chain_noise_reset(priv);
- priv->start_calib = 1;
-
if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
priv->assoc_station_added = 1;

@@ -2561,7 +2558,12 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
iwl_activate_qos(priv, 0);
spin_unlock_irqrestore(&priv->lock, flags);

- iwl_power_update_mode(priv, 0);
+ iwl_power_enable_management(priv);
+
+ /* Enable Rx differential gain and sensitivity calibrations */
+ iwl_chain_noise_reset(priv);
+ priv->start_calib = 1;
+
/* we have just associated, don't start scan too early */
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
}
@@ -3543,6 +3545,16 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
/* Per mac80211.h: This is only used in IBSS mode... */
if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) {

+ /* switch to CAM during association period.
+ * the ucode will block any association/authentication
+ * frome during assiciation period if it can not hear
+ * the AP because of PM. the timer enable PM back is
+ * association do not complete
+ */
+ if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN |
+ IEEE80211_CHAN_RADAR))
+ iwl_power_disable_management(priv, 3000);
+
IWL_DEBUG_MAC80211("leave - not in IBSS\n");
mutex_unlock(&priv->mutex);
return;
@@ -4095,6 +4107,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
/* FIXME : remove when resolved PENDING */
INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
iwl_setup_scan_deferred_work(priv);
+ iwl_setup_power_deferred_work(priv);

if (priv->cfg->ops->lib->setup_deferred_work)
priv->cfg->ops->lib->setup_deferred_work(priv);
@@ -4114,6 +4127,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)

cancel_delayed_work_sync(&priv->init_alive_start);
cancel_delayed_work(&priv->scan_check);
+ cancel_delayed_work_sync(&priv->set_power_save);
cancel_delayed_work(&priv->alive_start);
cancel_work_sync(&priv->beacon_update);
del_timer_sync(&priv->statistics_periodic);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 45ae68a..8daeafd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1018,6 +1018,7 @@ struct iwl_priv {

struct tasklet_struct irq_tasklet;

+ struct delayed_work set_power_save;
struct delayed_work init_alive_start;
struct delayed_work alive_start;
struct delayed_work scan_check;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index eb6312d..16f834d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -319,7 +319,7 @@ EXPORT_SYMBOL(iwl_power_update_mode);
* this will be usefull for rate scale to disable PM during heavy
* Tx/Rx activities
*/
-int iwl_power_disable_management(struct iwl_priv *priv)
+int iwl_power_disable_management(struct iwl_priv *priv, u32 ms)
{
u16 prev_mode;
int ret = 0;
@@ -332,6 +332,11 @@ int iwl_power_disable_management(struct iwl_priv *priv)
ret = iwl_power_update_mode(priv, 0);
priv->power_data.power_disabled = 1;
priv->power_data.user_power_setting = prev_mode;
+ cancel_delayed_work(&priv->set_power_save);
+ if (ms)
+ queue_delayed_work(priv->workqueue, &priv->set_power_save,
+ msecs_to_jiffies(ms));
+

return ret;
}
@@ -426,3 +431,35 @@ int iwl_power_temperature_change(struct iwl_priv *priv)
return ret;
}
EXPORT_SYMBOL(iwl_power_temperature_change);
+
+static void iwl_bg_set_power_save(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work,
+ struct iwl_priv, set_power_save.work);
+ IWL_DEBUG(IWL_DL_STATE, "update power\n");
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ mutex_lock(&priv->mutex);
+
+ /* on starting association we disable power managment
+ * until association, if association failed then this
+ * timer will expire and enable PM again.
+ */
+ if (!iwl_is_associated(priv))
+ iwl_power_enable_management(priv);
+
+ mutex_unlock(&priv->mutex);
+}
+void iwl_setup_power_deferred_work(struct iwl_priv *priv)
+{
+ INIT_DELAYED_WORK(&priv->set_power_save, iwl_bg_set_power_save);
+}
+EXPORT_SYMBOL(iwl_setup_power_deferred_work);
+
+void iwl_power_cancel_timeout(struct iwl_priv *priv)
+{
+ cancel_delayed_work(&priv->set_power_save);
+}
+EXPORT_SYMBOL(iwl_power_cancel_timeout);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index abcbbf9..aa99f36 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -78,8 +78,10 @@ struct iwl_power_mgr {
u8 power_disabled; /* flag to disable using power saving level */
};

+void iwl_setup_power_deferred_work(struct iwl_priv *priv);
+void iwl_power_cancel_timeout(struct iwl_priv *priv);
int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh);
-int iwl_power_disable_management(struct iwl_priv *priv);
+int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);
int iwl_power_enable_management(struct iwl_priv *priv);
int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode);
--
1.5.3.6


2008-09-03 03:31:11

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 12/39] iwlwifi: use strict_strtoul instead of simple_strtoul

From: Tomas Winkler <[email protected]>

This patch makes use of strict_srtoul in sysfs code.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 49 +++++++++++++++++++++-----------
1 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index f1a5225..d436f70 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3619,11 +3619,11 @@ static ssize_t store_debug_level(struct device *d,
const char *buf, size_t count)
{
struct iwl_priv *priv = d->driver_data;
- char *p = (char *)buf;
- u32 val;
+ unsigned long val;
+ int ret;

- val = simple_strtoul(p, &p, 0);
- if (p == buf)
+ ret = strict_strtoul(buf, 0, &val);
+ if (ret)
printk(KERN_INFO DRV_NAME
": %s is not in hex or decimal form.\n", buf);
else
@@ -3695,11 +3695,11 @@ static ssize_t store_tx_power(struct device *d,
const char *buf, size_t count)
{
struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- char *p = (char *)buf;
- u32 val;
+ unsigned long val;
+ int ret;

- val = simple_strtoul(p, &p, 10);
- if (p == buf)
+ ret = strict_strtoul(buf, 10, &val);
+ if (ret)
printk(KERN_INFO DRV_NAME
": %s is not in decimal form.\n", buf);
else
@@ -3723,7 +3723,12 @@ static ssize_t store_flags(struct device *d,
const char *buf, size_t count)
{
struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- u32 flags = simple_strtoul(buf, NULL, 0);
+ unsigned long val;
+ u32 flags;
+ int ret = strict_strtoul(buf, 0, &val);
+ if (!ret)
+ return ret;
+ flags = (u32)val;

mutex_lock(&priv->mutex);
if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
@@ -3731,8 +3736,7 @@ static ssize_t store_flags(struct device *d,
if (iwl_scan_cancel_timeout(priv, 100))
IWL_WARNING("Could not cancel scan.\n");
else {
- IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n",
- flags);
+ IWL_DEBUG_INFO("Commit rxon.flags = 0x%04X\n", flags);
priv->staging_rxon.flags = cpu_to_le32(flags);
iwl4965_commit_rxon(priv);
}
@@ -3758,7 +3762,12 @@ static ssize_t store_filter_flags(struct device *d,
const char *buf, size_t count)
{
struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- u32 filter_flags = simple_strtoul(buf, NULL, 0);
+ unsigned long val;
+ u32 filter_flags;
+ int ret = strict_strtoul(buf, 0, &val);
+ if (!ret)
+ return ret;
+ filter_flags = (u32)val;

mutex_lock(&priv->mutex);
if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
@@ -3859,10 +3868,12 @@ static ssize_t store_retry_rate(struct device *d,
const char *buf, size_t count)
{
struct iwl_priv *priv = dev_get_drvdata(d);
+ long val;
+ int ret = strict_strtol(buf, 10, &val);
+ if (!ret)
+ return ret;

- priv->retry_rate = simple_strtoul(buf, NULL, 0);
- if (priv->retry_rate <= 0)
- priv->retry_rate = 1;
+ priv->retry_rate = (val > 0) ? val : 1;

return count;
}
@@ -3883,9 +3894,9 @@ static ssize_t store_power_level(struct device *d,
{
struct iwl_priv *priv = dev_get_drvdata(d);
int ret;
- int mode;
+ unsigned long mode;
+

- mode = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);

if (!iwl_is_ready(priv)) {
@@ -3893,6 +3904,10 @@ static ssize_t store_power_level(struct device *d,
goto out;
}

+ ret = strict_strtoul(buf, 10, &mode);
+ if (!ret)
+ goto out;
+
ret = iwl_power_set_user_mode(priv, mode);
if (ret) {
IWL_DEBUG_MAC80211("failed setting power mode.\n");
--
1.5.3.6


2008-09-03 03:31:06

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 08/39] iwl3945: replace association and beacon hooks with bss_info_changed cb

From: Abhijeet Kolekar <[email protected]>

Let mac80211 and bss_info_changed callback handle the association and
beacon changes.

Signed-off-by: Abhijeet Kolekar <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 81 -------------------------------
1 files changed, 0 insertions(+), 81 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 8dc26ad..1377c81 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -688,87 +688,6 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,

switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
case IEEE80211_FTYPE_MGMT:
- switch (le16_to_cpu(header->frame_control) &
- IEEE80211_FCTL_STYPE) {
- case IEEE80211_STYPE_PROBE_RESP:
- case IEEE80211_STYPE_BEACON:{
- /* If this is a beacon or probe response for
- * our network then cache the beacon
- * timestamp */
- if ((((priv->iw_mode == IEEE80211_IF_TYPE_STA)
- && !compare_ether_addr(header->addr2,
- priv->bssid)) ||
- ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
- && !compare_ether_addr(header->addr3,
- priv->bssid)))) {
- struct ieee80211_mgmt *mgmt =
- (struct ieee80211_mgmt *)header;
- __le32 *pos;
- pos = (__le32 *)&mgmt->u.beacon.
- timestamp;
- priv->timestamp0 = le32_to_cpu(pos[0]);
- priv->timestamp1 = le32_to_cpu(pos[1]);
- priv->beacon_int = le16_to_cpu(
- mgmt->u.beacon.beacon_int);
- if (priv->call_post_assoc_from_beacon &&
- (priv->iw_mode ==
- IEEE80211_IF_TYPE_STA))
- queue_work(priv->workqueue,
- &priv->post_associate.work);
-
- priv->call_post_assoc_from_beacon = 0;
- }
-
- break;
- }
-
- case IEEE80211_STYPE_ACTION:
- /* TODO: Parse 802.11h frames for CSA... */
- break;
-
- /*
- * TODO: Use the new callback function from
- * mac80211 instead of sniffing these packets.
- */
- case IEEE80211_STYPE_ASSOC_RESP:
- case IEEE80211_STYPE_REASSOC_RESP:{
- struct ieee80211_mgmt *mgnt =
- (struct ieee80211_mgmt *)header;
-
- /* We have just associated, give some
- * time for the 4-way handshake if
- * any. Don't start scan too early. */
- priv->next_scan_jiffies = jiffies +
- IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
-
- priv->assoc_id = (~((1 << 15) | (1 << 14)) &
- le16_to_cpu(mgnt->u.
- assoc_resp.aid));
- priv->assoc_capability =
- le16_to_cpu(mgnt->u.assoc_resp.capab_info);
- if (priv->beacon_int)
- queue_work(priv->workqueue,
- &priv->post_associate.work);
- else
- priv->call_post_assoc_from_beacon = 1;
- break;
- }
-
- case IEEE80211_STYPE_PROBE_REQ:{
- DECLARE_MAC_BUF(mac1);
- DECLARE_MAC_BUF(mac2);
- DECLARE_MAC_BUF(mac3);
- if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
- IWL_DEBUG_DROP
- ("Dropping (non network): %s"
- ", %s, %s\n",
- print_mac(mac1, header->addr1),
- print_mac(mac2, header->addr2),
- print_mac(mac3, header->addr3));
- return;
- }
- }
-
case IEEE80211_FTYPE_DATA:
/* fall through */
default:
--
1.5.3.6


2008-09-03 03:31:41

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 35/39] iwlwifi: remove bad language from the comments

From: Tomas Winkler <[email protected]>

This patch removes bad language in the comments in iwl-agn-rs.c.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 169c548..4fc3a0f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -2218,8 +2218,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
sta->txrate_idx = i;

sta->last_txrate_idx = sta->txrate_idx;
- /* WTF is with this bogus comment? A doesn't have cck rates */
- /* For MODE_IEEE80211A, cck rates are at end of rate table */
+ /* For MODE_IEEE80211A, skip over cck rates in global rate table */
if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;

--
1.5.3.6


2008-09-03 03:31:23

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 21/39] iwlwifi: fix rx_chain computation

From: Tomas Winkler <[email protected]>

This patch fixes and simplifies rx_chain computation.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Mohamed Abbas <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.c | 77 ++++++++++++++++++------------
1 files changed, 46 insertions(+), 31 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 129b0a3..e55a62d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -592,12 +592,11 @@ static void iwlcore_free_geos(struct iwl_priv *priv)
clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
}

-static u8 is_single_rx_stream(struct iwl_priv *priv)
+static bool is_single_rx_stream(struct iwl_priv *priv)
{
return !priv->current_ht_config.is_ht ||
((priv->current_ht_config.supp_mcs_set[1] == 0) &&
- (priv->current_ht_config.supp_mcs_set[2] == 0)) ||
- priv->ps_mode == IWL_MIMO_PS_STATIC;
+ (priv->current_ht_config.supp_mcs_set[2] == 0));
}

static u8 iwl_is_channel_extension(struct iwl_priv *priv,
@@ -704,33 +703,39 @@ EXPORT_SYMBOL(iwl_set_rxon_ht);
* MIMO (dual stream) requires at least 2, but works better with 3.
* This does not determine *which* chains to use, just how many.
*/
-static int iwlcore_get_rx_chain_counter(struct iwl_priv *priv,
- u8 *idle_state, u8 *rx_state)
+static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
{
- u8 is_single = is_single_rx_stream(priv);
- u8 is_cam = test_bit(STATUS_POWER_PMI, &priv->status) ? 0 : 1;
+ bool is_single = is_single_rx_stream(priv);
+ bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);

/* # of Rx chains to use when expecting MIMO. */
if (is_single || (!is_cam && (priv->ps_mode == IWL_MIMO_PS_STATIC)))
- *rx_state = 2;
+ return 2;
else
- *rx_state = 3;
+ return 3;
+}

+static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
+{
+ int idle_cnt;
+ bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
/* # Rx chains when idling and maybe trying to save power */
switch (priv->ps_mode) {
case IWL_MIMO_PS_STATIC:
case IWL_MIMO_PS_DYNAMIC:
- *idle_state = (is_cam) ? 2 : 1;
+ idle_cnt = (is_cam) ? 2 : 1;
break;
case IWL_MIMO_PS_NONE:
- *idle_state = (is_cam) ? *rx_state : 1;
+ idle_cnt = (is_cam) ? active_cnt : 1;
break;
+ case IWL_MIMO_PS_INVALID:
default:
- *idle_state = 1;
+ IWL_ERROR("invalide mimo ps mode %d\n", priv->ps_mode);
+ WARN_ON(1);
+ idle_cnt = -1;
break;
}
-
- return 0;
+ return idle_cnt;
}

/**
@@ -741,34 +746,44 @@ static int iwlcore_get_rx_chain_counter(struct iwl_priv *priv,
*/
void iwl_set_rxon_chain(struct iwl_priv *priv)
{
- u8 is_single = is_single_rx_stream(priv);
- u8 idle_state, rx_state;
-
- priv->staging_rxon.rx_chain = 0;
- rx_state = idle_state = 3;
+ bool is_single = is_single_rx_stream(priv);
+ bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
+ u8 idle_rx_cnt, active_rx_cnt;
+ u16 rx_chain;

/* Tell uCode which antennas are actually connected.
* Before first association, we assume all antennas are connected.
* Just after first association, iwl_chain_noise_calibration()
* checks which antennas actually *are* connected. */
- priv->staging_rxon.rx_chain |=
- cpu_to_le16(priv->hw_params.valid_rx_ant <<
- RXON_RX_CHAIN_VALID_POS);
+ rx_chain = priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;

/* How many receivers should we use? */
- iwlcore_get_rx_chain_counter(priv, &idle_state, &rx_state);
- priv->staging_rxon.rx_chain |=
- cpu_to_le16(rx_state << RXON_RX_CHAIN_MIMO_CNT_POS);
- priv->staging_rxon.rx_chain |=
- cpu_to_le16(idle_state << RXON_RX_CHAIN_CNT_POS);
-
- if (!is_single && (rx_state >= 2) &&
- !test_bit(STATUS_POWER_PMI, &priv->status))
+ active_rx_cnt = iwl_get_active_rx_chain_count(priv);
+ idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
+
+ /* correct rx chain count accoridng hw settings */
+ if (priv->hw_params.rx_chains_num < active_rx_cnt)
+ active_rx_cnt = priv->hw_params.rx_chains_num;
+
+ if (priv->hw_params.rx_chains_num < idle_rx_cnt)
+ idle_rx_cnt = priv->hw_params.rx_chains_num;
+
+ rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
+ rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
+
+ priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
+
+ if (!is_single && (active_rx_cnt >= 2) && is_cam)
priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
else
priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;

- IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain);
+ IWL_DEBUG_ASSOC("rx_chain=0x%Xi active=%d idle=%d\n",
+ priv->staging_rxon.rx_chain,
+ active_rx_cnt, idle_rx_cnt);
+
+ WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
+ active_rx_cnt < idle_rx_cnt);
}
EXPORT_SYMBOL(iwl_set_rxon_chain);

--
1.5.3.6


2008-09-03 03:31:04

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 06/39] iwlwifi: align set channel with mac80211

From: Tomas Winkler <[email protected]>

This patch makes use of mac80211 defaults for channel and band.
Older code that uses G band channel 6 was removed. This patch also
changes iwl_set_rxon_channel signature.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-core.c | 11 +++++------
drivers/net/wireless/iwlwifi/iwl-core.h | 4 +---
3 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 08ca2a3..f1a5225 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2841,7 +2841,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
)
priv->staging_rxon.flags = 0;

- iwl_set_rxon_channel(priv, conf->channel->band, channel);
+ iwl_set_rxon_channel(priv, conf->channel);

iwl_set_flags_for_band(priv, conf->channel->band);

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index fbf75a6..bb03032 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -773,7 +773,7 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
EXPORT_SYMBOL(iwl_set_rxon_chain);

/**
- * iwlcore_set_rxon_channel - Set the phymode and channel values in staging RXON
+ * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON
* @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz
* @channel: Any channel valid for the requested phymode

@@ -782,10 +782,11 @@ EXPORT_SYMBOL(iwl_set_rxon_chain);
* NOTE: Does not commit to the hardware; it sets appropriate bit fields
* in the staging RXON flag structure based on the phymode
*/
-int iwl_set_rxon_channel(struct iwl_priv *priv,
- enum ieee80211_band band,
- u16 channel)
+int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
{
+ enum ieee80211_band band = ch->band;
+ u16 channel = ieee80211_frequency_to_channel(ch->center_freq);
+
if (!iwl_get_channel_info(priv, band, channel)) {
IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
channel, band);
@@ -906,8 +907,6 @@ int iwl_init_drv(struct iwl_priv *priv)
priv->qos_data.qos_active = 0;
priv->qos_data.qos_cap.val = 0;

- iwl_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
-
priv->rates_mask = IWL_RATES_MASK;
/* If power management is turned on, default to AC mode */
priv->power_mode = IWL_POWER_AC;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 64f139e..ff86abc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -189,9 +189,7 @@ void iwl_clear_stations_table(struct iwl_priv *priv);
void iwl_free_calib_results(struct iwl_priv *priv);
void iwl_reset_qos(struct iwl_priv *priv);
void iwl_set_rxon_chain(struct iwl_priv *priv);
-int iwl_set_rxon_channel(struct iwl_priv *priv,
- enum ieee80211_band band,
- u16 channel);
+int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info);
u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
struct ieee80211_ht_info *sta_ht_inf);
--
1.5.3.6


2008-09-03 14:28:10

by Tomas Winkler

[permalink] [raw]
Subject: Re: [PATCH 31/39] iwlwifi: fix memory allocation of TX command

On Wed, Sep 3, 2008 at 6:26 AM, Zhu Yi <[email protected]> wrote:
> From: Tomas Winkler <[email protected]>
>
> This patch removes GFP_DMA from allocation tx command buffers
> GFP_DMA allows allocation only for memory under 16M which causes
> allocation problems suspend/resume flows.
>
> Using kmalloc is temporal solution and some consistent/coherent
> allocation schema will be more correct. Since iwlwifi hardware
> supports 64bit address this solution should work on x86 (32 and
> 64bit) for now. This patch also fixes memory freeing in error path.
>
> Signed-off-by: Tomas Winkler <[email protected]>
> Signed-off-by: Ian Schram <[email protected]>
> Signed-off-by: Zhu Yi <[email protected]>

Note: this address the same fix as

commit 49898852e6aa8a6de9a5bc0bab2cf305b3583bbf
Author: John W. Linville <[email protected]>
Date: Tue Sep 2 15:07:18 2008 -0400

One line conflicts. Need just to merge the error path handling.
Tomas


> drivers/net/wireless/iwlwifi/iwl-tx.c | 29 ++++++++++++++++++-----------
> 1 files changed, 18 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
> index 6cba5e9..68567fa 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-tx.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
> @@ -402,12 +402,11 @@ static int iwl_hw_tx_queue_init(struct iwl_priv *priv,
> /**
> * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
> */
> -static int iwl_tx_queue_init(struct iwl_priv *priv,
> - struct iwl_tx_queue *txq,
> +static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
> int slots_num, u32 txq_id)
> {
> int i, len;
> - int rc = 0;
> + int ret;
>
> /*
> * Alloc buffer array for commands (Tx or other types of commands).
> @@ -426,19 +425,16 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
> continue;
> }
>
> - txq->cmd[i] = kmalloc(len, GFP_KERNEL | GFP_DMA);
> + txq->cmd[i] = kmalloc(len, GFP_KERNEL);
> if (!txq->cmd[i])
> - return -ENOMEM;
> + goto err;
> }
>
> /* Alloc driver data array and TFD circular buffer */
> - rc = iwl_tx_queue_alloc(priv, txq, txq_id);
> - if (rc) {
> - for (i = 0; i < slots_num; i++)
> - kfree(txq->cmd[i]);
> + ret = iwl_tx_queue_alloc(priv, txq, txq_id);
> + if (ret)
> + goto err;
>
> - return -ENOMEM;
> - }
> txq->need_update = 0;
>
> /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
> @@ -452,6 +448,17 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
> iwl_hw_tx_queue_init(priv, txq);
>
> return 0;
> +err:
> + for (i = 0; i < slots_num; i++) {
> + kfree(txq->cmd[i]);
> + txq->cmd[i] = NULL;
> + }
> +
> + if (txq_id == IWL_CMD_QUEUE_NUM) {
> + kfree(txq->cmd[slots_num]);
> + txq->cmd[slots_num] = NULL;
> + }
> + return -ENOMEM;
> }
> /**
> * iwl_hw_txq_ctx_free - Free TXQ Context
> --
> 1.5.3.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>

2008-09-03 03:31:32

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 28/39] iwlwifi: workaround interrupt handling no some platforms

From: Tomas Winkler <[email protected]>

This patch adds workaround for an interrupt related hardware bug on
some platforms.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index aad0ddc..10980c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2602,6 +2602,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
int ret;
+ u16 pci_cmd;

IWL_DEBUG_MAC80211("enter\n");

@@ -2612,6 +2613,13 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
pci_restore_state(priv->pci_dev);
pci_enable_msi(priv->pci_dev);

+ /* enable interrupts if needed: hw bug w/a */
+ pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
+ if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
+ pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
+ pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
+ }
+
ret = request_irq(priv->pci_dev->irq, iwl4965_isr, IRQF_SHARED,
DRV_NAME, priv);
if (ret) {
--
1.5.3.6


2008-09-03 03:31:44

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 37/39] iwlwifi: fix compile warning

The patch fixes compile warning for =E2=80=98iwl4965_hw_channel_switch=E2=
=80=99 defined
but not used.

Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wire=
less/iwlwifi/iwl-4965.c
index d2569a2..9838de5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1607,6 +1607,7 @@ static int iwl4965_send_rxon_assoc(struct iwl_pri=
v *priv)
return ret;
}
=20
+#ifdef IEEE80211_CONF_CHANNEL_SWITCH
static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channe=
l)
{
int rc;
@@ -1647,6 +1648,7 @@ static int iwl4965_hw_channel_switch(struct iwl_p=
riv *priv, u16 channel)
rc =3D iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd=
);
return rc;
}
+#endif
=20
static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
{
--=20
1.5.3.6

2008-09-03 03:31:07

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 09/39] iwlwifi: fix hidden ssid discovery in passive channels

From: Ron Rindjunsky <[email protected]>

This patch gives the HW the possibility to send direct probes in passive
channels (as long as traffic was detected in that channel) if such ssid
was requested, so hidden ssid can be found now in those channels as well.

Signed-off-by: Cahill Ben <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Ron Rindjunsky <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-scan.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 9bb6adb..6c8ac3a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -421,7 +421,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
else
scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;

- if ((scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) && n_probes)
+ if (n_probes)
scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);

scan_ch->active_dwell = cpu_to_le16(active_dwell);
--
1.5.3.6