2009-11-06 22:52:59

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 00/20] iwlwifi updates 11/6/2009

Ben M Cahill (6):
iwlwifi: Limit size of Event Log dump
iwlwifi: speed up event log dumps
iwlwifi: Update comments for struct iwl_ssid_ie
iwlwifi: Add comments about MAC_ACCESS_REQ
iwlagn: update write pointers in iwl_irq_tasklet()
iwlwifi: MAC_ACCESS_REQ cleanup

Johannes Berg (3):
iwlwifi: don't double-activate queue 4
iwlwifi: fix FIFO vs. queue confusion
iwlwifi: add FIFO usage for 5000

Reinette Chatre (1):
iwlwifi: change debug message to error in failure case

Shanyu Zhao (2):
iwlwifi: use only one chain for scan in PS
iwlwifi: use configured valid rx chain for scan

Wey-Yi Guy (7):
iwlwifi: print rx_on config to help debug
iwlwifi: no periodic Tx/IQ calibration for 6x00/6x50 series
iwlwifi: remove un-used parameter
iwlwifi: fix for channel switch
iwlwifi: drop non-production PCI-IDs
iwlwifi: do not base station's sm_ps setting on AP
iwlwifi: Fix issue on file transfer stalled in HT mode

Zhu Yi (1):
iwlwifi: allocate 128 bytes linear buffer for rx skb

drivers/net/wireless/iwlwifi/iwl-1000.c | 1 +
drivers/net/wireless/iwlwifi/iwl-3945.c | 3 +-
drivers/net/wireless/iwlwifi/iwl-4965.c | 14 ++--
drivers/net/wireless/iwlwifi/iwl-5000.c | 16 +++-
drivers/net/wireless/iwlwifi/iwl-6000.c | 106 +-------------------------
drivers/net/wireless/iwlwifi/iwl-agn.c | 79 +++++++++++++-------
drivers/net/wireless/iwlwifi/iwl-commands.h | 7 +-
drivers/net/wireless/iwlwifi/iwl-core.c | 54 ++++++++------
drivers/net/wireless/iwlwifi/iwl-core.h | 5 +
drivers/net/wireless/iwlwifi/iwl-dev.h | 22 ++++--
drivers/net/wireless/iwlwifi/iwl-hcmd.c | 4 +-
drivers/net/wireless/iwlwifi/iwl-io.h | 20 +++++
drivers/net/wireless/iwlwifi/iwl-prph.h | 19 ++++-
drivers/net/wireless/iwlwifi/iwl-rx.c | 5 +-
drivers/net/wireless/iwlwifi/iwl-scan.c | 18 ++++-
drivers/net/wireless/iwlwifi/iwl-tx.c | 12 ++-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 42 ++++++++--
17 files changed, 235 insertions(+), 192 deletions(-)



2009-11-06 22:53:05

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 18/20] iwlagn: update write pointers in iwl_irq_tasklet()

From: Ben Cahill <[email protected]>

Follow-up to "update write pointers for all tx queues after wakeup"; that
patch changed iwl_irq_tasklet_legacy(), but not iwl_irq_tasklet(), so
newer devices were not covered.

Comments from original patch:

Wakeup interrupt has been updating write pointers (indexes, actually) only
for tx queues 0-5. This is adequate just for 3945, but inadequate for other
devices, all of which have more tx queues. Now updating all tx/command queues,
so device can be aware of all new tx and host commands enqueued while
device was asleep.

This can potentially improve data traffic bandwidth and/or latency.

Signed-off-by: Ben Cahill <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index a1d2cda..4ba4282 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1085,6 +1085,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
u32 inta = 0;
u32 handled = 0;
unsigned long flags;
+ u32 i;
#ifdef CONFIG_IWLWIFI_DEBUG
u32 inta_mask;
#endif
@@ -1195,12 +1196,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
if (inta & CSR_INT_BIT_WAKEUP) {
IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
- iwl_txq_update_write_ptr(priv, &priv->txq[0]);
- iwl_txq_update_write_ptr(priv, &priv->txq[1]);
- iwl_txq_update_write_ptr(priv, &priv->txq[2]);
- iwl_txq_update_write_ptr(priv, &priv->txq[3]);
- iwl_txq_update_write_ptr(priv, &priv->txq[4]);
- iwl_txq_update_write_ptr(priv, &priv->txq[5]);
+ for (i = 0; i < priv->hw_params.max_txq_num; i++)
+ iwl_txq_update_write_ptr(priv, &priv->txq[i]);

priv->isr_stats.wakeup++;

--
1.5.6.3


2009-11-06 22:53:02

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 11/20] iwlwifi: fix for channel switch

From: Wey-Yi Guy <[email protected]>

Different channel has different configuration, need to pass correct
configuration to uCode when send "channel switch" command to uCode.
Invalid configuration will cause sysassert in uCode and produce
un-expected result.

Even it is a very small windows, but we also need to consider and handle
the case if commit_rxon occurred before the "channel switch
announcement" notification received from uCode.

Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 12 +++++---
drivers/net/wireless/iwlwifi/iwl-5000.c | 6 +++-
drivers/net/wireless/iwlwifi/iwl-6000.c | 6 +++-
drivers/net/wireless/iwlwifi/iwl-agn.c | 11 +++++++
drivers/net/wireless/iwlwifi/iwl-core.c | 45 ++++++++++++++++++++-----------
drivers/net/wireless/iwlwifi/iwl-dev.h | 13 +++++++++
6 files changed, 68 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 607c312..cc39424 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1450,14 +1450,14 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
is_ht40 = is_ht40_channel(priv->staging_rxon.flags);

if (is_ht40 &&
- (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
+ (priv->staging_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
ctrl_chan_high = 1;

cmd.band = band;
cmd.expect_beacon = 0;
cmd.channel = cpu_to_le16(channel);
- cmd.rxon_flags = priv->active_rxon.flags;
- cmd.rxon_filter_flags = priv->active_rxon.filter_flags;
+ cmd.rxon_flags = priv->staging_rxon.flags;
+ cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
if (ch_info)
cmd.expect_beacon = is_channel_radar(ch_info);
@@ -1474,8 +1474,10 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
return rc;
}

- rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
- return rc;
+ priv->switch_rxon.channel = cpu_to_le16(channel);
+ priv->switch_rxon.switch_in_progress = true;
+
+ return iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
}

/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index f6cbbfa..e23d301 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1392,8 +1392,8 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
priv->active_rxon.channel, channel);
cmd.band = priv->band == IEEE80211_BAND_2GHZ;
cmd.channel = cpu_to_le16(channel);
- cmd.rxon_flags = priv->active_rxon.flags;
- cmd.rxon_filter_flags = priv->active_rxon.filter_flags;
+ cmd.rxon_flags = priv->staging_rxon.flags;
+ cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
ch_info = iwl_get_channel_info(priv, priv->band, channel);
if (ch_info)
@@ -1403,6 +1403,8 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
priv->active_rxon.channel, channel);
return -EFAULT;
}
+ priv->switch_rxon.channel = cpu_to_le16(channel);
+ priv->switch_rxon.switch_in_progress = true;

return iwl_send_cmd_sync(priv, &hcmd);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 9ab7954..1f769ea 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -186,8 +186,8 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u16 channel)

cmd.band = priv->band == IEEE80211_BAND_2GHZ;
cmd.channel = cpu_to_le16(channel);
- cmd.rxon_flags = priv->active_rxon.flags;
- cmd.rxon_filter_flags = priv->active_rxon.filter_flags;
+ cmd.rxon_flags = priv->staging_rxon.flags;
+ cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
ch_info = iwl_get_channel_info(priv, priv->band, channel);
if (ch_info)
@@ -197,6 +197,8 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, u16 channel)
priv->active_rxon.channel, channel);
return -EFAULT;
}
+ priv->switch_rxon.channel = cpu_to_le16(channel);
+ priv->switch_rxon.switch_in_progress = true;

return iwl_send_cmd_sync(priv, &hcmd);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 46503a6..fd7ba51 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -123,6 +123,17 @@ int iwl_commit_rxon(struct iwl_priv *priv)
return -EINVAL;
}

+ /*
+ * receive commit_rxon request
+ * abort any previous channel switch if still in process
+ */
+ if (priv->switch_rxon.switch_in_progress &&
+ (priv->switch_rxon.channel != priv->staging_rxon.channel)) {
+ IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
+ le16_to_cpu(priv->switch_rxon.channel));
+ priv->switch_rxon.switch_in_progress = false;
+ }
+
/* If we don't need to send a full RXON, we can use
* iwl_rxon_assoc_cmd which is used to reconfigure filter
* and other flags for the current radio configuration. */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 34ffcdd..e5854a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1317,14 +1317,19 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
struct iwl_csa_notification *csa = &(pkt->u.csa_notif);

- if (!le32_to_cpu(csa->status)) {
- rxon->channel = csa->channel;
- priv->staging_rxon.channel = csa->channel;
- IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
- le16_to_cpu(csa->channel));
- } else
- IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
- le16_to_cpu(csa->channel));
+ if (priv->switch_rxon.switch_in_progress) {
+ if (!le32_to_cpu(csa->status) &&
+ (csa->channel == priv->switch_rxon.channel)) {
+ rxon->channel = csa->channel;
+ priv->staging_rxon.channel = csa->channel;
+ IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
+ le16_to_cpu(csa->channel));
+ } else
+ IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
+ le16_to_cpu(csa->channel));
+
+ priv->switch_rxon.switch_in_progress = false;
+ }
}
EXPORT_SYMBOL(iwl_rx_csa);

@@ -2691,14 +2696,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
goto set_ch_out;
}

- if (iwl_is_associated(priv) &&
- (le16_to_cpu(priv->active_rxon.channel) != ch) &&
- priv->cfg->ops->lib->set_channel_switch) {
- ret = priv->cfg->ops->lib->set_channel_switch(priv,
- ch);
- goto out;
- }
-
spin_lock_irqsave(&priv->lock, flags);

/* Configure HT40 channels */
@@ -2733,6 +2730,22 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)

iwl_set_flags_for_band(priv, conf->channel->band);
spin_unlock_irqrestore(&priv->lock, flags);
+ if (iwl_is_associated(priv) &&
+ (le16_to_cpu(priv->active_rxon.channel) != ch) &&
+ priv->cfg->ops->lib->set_channel_switch) {
+ iwl_set_rate(priv);
+ /*
+ * at this point, staging_rxon has the
+ * configuration for channel switch
+ */
+ ret = priv->cfg->ops->lib->set_channel_switch(priv,
+ ch);
+ if (!ret) {
+ iwl_print_rx_config_cmd(priv);
+ goto out;
+ }
+ priv->switch_rxon.switch_in_progress = false;
+ }
set_ch_out:
/* The list of supported rates and rate mask can be different
* for each band; since the band may have changed, reset
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 9975645..9a19a3d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -994,6 +994,17 @@ struct traffic_stats {
};
#endif

+/*
+ * iwl_switch_rxon: "channel switch" structure
+ *
+ * @ switch_in_progress: channel switch in progress
+ * @ channel: new channel
+ */
+struct iwl_switch_rxon {
+ bool switch_in_progress;
+ __le16 channel;
+};
+
struct iwl_priv {

/* ieee device used by generic ieee processing code */
@@ -1087,6 +1098,8 @@ struct iwl_priv {
const struct iwl_rxon_cmd active_rxon;
struct iwl_rxon_cmd staging_rxon;

+ struct iwl_switch_rxon switch_rxon;
+
/* 1st responses from initialize and runtime uCode images.
* 4965's initialize alive response contains some calibration data. */
struct iwl_init_alive_resp card_alive_init;
--
1.5.6.3


2009-11-06 22:53:01

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 10/20] iwlwifi: add FIFO usage for 5000

From: Johannes Berg <[email protected]>

This is part of the code, but the comment doesn't have it,
add pointers to the code and the FIFO usage for 5000 and
up.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-prph.h | 19 ++++++++++++++++---
1 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index d393e8f..6d95832 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -254,7 +254,8 @@
* device. A queue maps to only one (selectable by driver) Tx DMA channel,
* but one DMA channel may take input from several queues.
*
- * Tx DMA channels have dedicated purposes. For 4965, they are used as follows:
+ * Tx DMA channels have dedicated purposes. For 4965, they are used as follows
+ * (cf. default_queue_to_tx_fifo in iwl-4965.c):
*
* 0 -- EDCA BK (background) frames, lowest priority
* 1 -- EDCA BE (best effort) frames, normal priority
@@ -265,9 +266,21 @@
* 6 -- HCCA long frames
* 7 -- not used by driver (device-internal only)
*
+ * For 5000 series and up, they are used slightly differently
+ * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c):
+ *
+ * 0 -- EDCA BK (background) frames, lowest priority
+ * 1 -- EDCA BE (best effort) frames, normal priority
+ * 2 -- EDCA VI (video) frames, higher priority
+ * 3 -- EDCA VO (voice) and management frames, highest priority
+ * 4 -- (TBD)
+ * 5 -- HCCA short frames
+ * 6 -- HCCA long frames
+ * 7 -- Commands
+ *
* Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6.
- * In addition, driver can map queues 7-15 to Tx DMA/FIFO channels 0-3 to
- * support 11n aggregation via EDCA DMA channels.
+ * In addition, driver can map the remaining queues to Tx DMA/FIFO
+ * channels 0-3 to support 11n aggregation via EDCA DMA channels.
*
* The driver sets up each queue to work in one of two modes:
*
--
1.5.6.3


2009-11-06 22:53:05

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 20/20] iwlwifi: MAC_ACCESS_REQ cleanup

From: Ben Cahill <[email protected]>

Add txq_id info to "Tx queue requesting wakeup" debug message

Add "Rx queue requesting wakeup" debug message

Move clear of CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ to be after nearby
iwl_write_prph(), since iwl_write_prph() sets it and clears it. Almost
removed it entirely, but just making sure in case someone removes the
iwl_write_prph()! Also remove unneeded priv->lock usage; this is now
handled by priv->reg_lock within iwl_clear_bit().

Join a couple of lines that had unneeded line returns.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 4ba4282..29f7510 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1935,19 +1935,17 @@ static void __iwl_down(struct iwl_priv *priv)

/* device going down, Stop using ICT table */
iwl_disable_ict(priv);
- spin_lock_irqsave(&priv->lock, flags);
- iwl_clear_bit(priv, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- spin_unlock_irqrestore(&priv->lock, flags);

iwl_txq_ctx_stop(priv);
iwl_rxq_stop(priv);

- iwl_write_prph(priv, APMG_CLK_DIS_REG,
- APMG_CLK_VAL_DMA_CLK_RQT);
-
+ /* Power-down device's busmaster DMA clocks */
+ iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
udelay(5);

+ /* Make sure (redundant) we've released our request to stay awake */
+ iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
/* Stop the device, and put it in low power state */
priv->cfg->ops->lib->apm_ops.stop(priv);

diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index d2dc7cc..61b3b0e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -140,6 +140,8 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);

if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
+ IWL_DEBUG_INFO(priv, "Rx queue requesting wakeup, GP1 = 0x%x\n",
+ reg);
iwl_set_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
goto exit_unlock;
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index d2b606e..6199bf6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -97,7 +97,8 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
reg = iwl_read32(priv, CSR_UCODE_DRV_GP1);

if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) {
- IWL_DEBUG_INFO(priv, "Requesting wakeup, GP1 = 0x%x\n", reg);
+ IWL_DEBUG_INFO(priv, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
+ txq_id, reg);
iwl_set_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
return ret;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 6285e51..5d26330 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2601,9 +2601,8 @@ static void __iwl3945_down(struct iwl_priv *priv)
iwl3945_hw_txq_ctx_stop(priv);
iwl3945_hw_rxq_stop(priv);

- iwl_write_prph(priv, APMG_CLK_DIS_REG,
- APMG_CLK_VAL_DMA_CLK_RQT);
-
+ /* Power-down device's busmaster DMA clocks */
+ iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
udelay(5);

/* Stop the device, and put it in low power state */
--
1.5.6.3


2009-11-06 22:53:00

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 04/20] iwlwifi: use only one chain for scan in PS

From: Shanyu Zhao <[email protected]>

When doing scan in power saving mode, choose only 1 valid RX chain instead of
turning all chains on.

Signed-off-by: Shanyu Zhao <[email protected]>
Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-scan.c | 16 +++++++++++++++-
1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 1eb0d0b..48bc263 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -581,6 +581,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
u8 rate;
bool is_active = false;
int chan_mod;
+ u8 active_chains;

conf = ieee80211_get_hw_conf(priv->hw);

@@ -734,9 +735,22 @@ static void iwl_bg_request_scan(struct work_struct *data)
rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);

+ /* In power save mode use one chain, otherwise use all chains */
+ if (test_bit(STATUS_POWER_PMI, &priv->status)) {
+ /* rx_ant has been set to all valid chains previously */
+ active_chains = rx_ant &
+ ((u8)(priv->chain_noise_data.active_chains));
+ if (!active_chains)
+ active_chains = rx_ant;
+
+ IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
+ priv->chain_noise_data.active_chains);
+
+ rx_ant = first_antenna(active_chains);
+ }
/* MIMO is not used here, but value is required */
rx_chain |= ANT_ABC << RXON_RX_CHAIN_VALID_POS;
- rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+ rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
scan->rx_chain = cpu_to_le16(rx_chain);
--
1.5.6.3


2009-11-06 22:53:03

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 13/20] iwlwifi: do not base station's sm_ps setting on AP

From: Wey-Yi Guy <[email protected]>

Do not use AP's SM_PS setting for our own SM_PS setting.

Reported-by: Johannes Berg <[email protected]>
Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.c | 6 ------
1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index e5854a9..7ffa0f0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2317,12 +2317,6 @@ static void iwl_ht_conf(struct iwl_priv *priv,
>> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
maxstreams += 1;

- ht_conf->sm_ps =
- (u8)((ht_cap->cap & IEEE80211_HT_CAP_SM_PS)
- >> 2);
- IWL_DEBUG_MAC80211(priv, "sm_ps: 0x%x\n",
- ht_conf->sm_ps);
-
if ((ht_cap->mcs.rx_mask[1] == 0) &&
(ht_cap->mcs.rx_mask[2] == 0))
ht_conf->single_chain_sufficient = true;
--
1.5.6.3


2009-11-06 22:53:04

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 15/20] iwlwifi: speed up event log dumps

From: Ben Cahill <[email protected]>

Take advantage of device's auto-increment for SRAM reads to eliminate extra
write address accesses.

Grab/release NIC access before/after entire read sequence, rather than for
each read individually.

After a quick check of dmesg logs, this seems to double Event Log dump speed,
reducing from about 20 milliseconds to about 10 milliseconds for 512 entries
using 3945.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index be99d19..a1d2cda 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1667,6 +1667,7 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
u32 ptr; /* SRAM byte address of log data */
u32 ev, time, data; /* event log data */
+ unsigned long reg_flags;

if (num_events == 0)
return;
@@ -1682,25 +1683,34 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,

ptr = base + EVENT_START_OFFSET + (start_idx * event_size);

+ /* Make sure device is powered up for SRAM reads */
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ iwl_grab_nic_access(priv);
+
+ /* Set starting address; reads will auto-increment */
+ _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+ rmb();
+
/* "time" is actually "data" for mode 0 (no timestamp).
* place event id # at far right for easier visual parsing. */
for (i = 0; i < num_events; i++) {
- ev = iwl_read_targ_mem(priv, ptr);
- ptr += sizeof(u32);
- time = iwl_read_targ_mem(priv, ptr);
- ptr += sizeof(u32);
+ ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (mode == 0) {
/* data, ev */
trace_iwlwifi_dev_ucode_event(priv, 0, time, ev);
IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
} else {
- data = iwl_read_targ_mem(priv, ptr);
- ptr += sizeof(u32);
+ data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
time, data, ev);
trace_iwlwifi_dev_ucode_event(priv, time, data, ev);
}
}
+
+ /* Allow device to power down */
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
}

/* For sanity check only. Actual size is determined by uCode, typ. 512 */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 75caa5f..6285e51 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1571,6 +1571,7 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
u32 ptr; /* SRAM byte address of log data */
u32 ev, time, data; /* event log data */
+ unsigned long reg_flags;

if (num_events == 0)
return;
@@ -1584,24 +1585,33 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,

ptr = base + EVENT_START_OFFSET + (start_idx * event_size);

+ /* Make sure device is powered up for SRAM reads */
+ spin_lock_irqsave(&priv->reg_lock, reg_flags);
+ iwl_grab_nic_access(priv);
+
+ /* Set starting address; reads will auto-increment */
+ _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+ rmb();
+
/* "time" is actually "data" for mode 0 (no timestamp).
* place event id # at far right for easier visual parsing. */
for (i = 0; i < num_events; i++) {
- ev = iwl_read_targ_mem(priv, ptr);
- ptr += sizeof(u32);
- time = iwl_read_targ_mem(priv, ptr);
- ptr += sizeof(u32);
+ ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+ time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
if (mode == 0) {
/* data, ev */
IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
trace_iwlwifi_dev_ucode_event(priv, 0, time, ev);
} else {
- data = iwl_read_targ_mem(priv, ptr);
- ptr += sizeof(u32);
+ data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev);
trace_iwlwifi_dev_ucode_event(priv, time, data, ev);
}
}
+
+ /* Allow device to power down */
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
}

/* For sanity check only. Actual size is determined by uCode, typ. 512 */
--
1.5.6.3


2009-11-06 22:53:01

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 08/20] iwlwifi: fix FIFO vs. queue confusion

From: Johannes Berg <[email protected]>

When I added that code setting the swq_id, I evidently
did not understand the distinction between FIFO and TX
queue yet and added code to compare a queue ID and a
FIFO number, which is bogus.

However, the code there need not be this specific, it
can just set all queues to the identity mapping which
will be overwritten by the aggregation queue code. As
a bit of defensive coding, don't assign an swq_id to
the command queue so that if we ever use it for frames
we notice quickly.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-dev.h | 5 +++--
drivers/net/wireless/iwlwifi/iwl-tx.c | 9 +++++++--
2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index cb2642c..b4e8145 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -324,8 +324,9 @@ struct iwl_channel_info {
#define IWL_MIN_NUM_QUEUES 10

/*
- * uCode queue management definitions ...
- * Queue #4 is the command queue for 3945/4965/5x00/1000/6x00.
+ * Queue #4 is the command queue for 3945/4965/5x00/1000/6x00,
+ * the driver maps it into the appropriate device FIFO for the
+ * uCode.
*/
#define IWL_CMD_QUEUE_NUM 4

diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index b1a2de8..d2b606e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -365,8 +365,13 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,

txq->need_update = 0;

- /* aggregation TX queues will get their ID when aggregation begins */
- if (txq_id <= IWL_TX_FIFO_AC3)
+ /*
+ * Aggregation TX queues will get their ID when aggregation begins;
+ * they overwrite the setting done here. The command FIFO doesn't
+ * need an swq_id so don't set one to catch errors, all others can
+ * be set up to the identity mapping.
+ */
+ if (txq_id != IWL_CMD_QUEUE_NUM)
txq->swq_id = txq_id;

/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
--
1.5.6.3


2009-11-06 22:52:59

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 03/20] iwlwifi: print rx_on config to help debug

From: Wey-Yi Guy <[email protected]>

To help debug rx related issues, if IWL_DEBUG_RADIO flag is set, print
the rxon configuration when rxon host command send to uCode.

Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 2 ++
drivers/net/wireless/iwlwifi/iwl-core.c | 3 ++-
drivers/net/wireless/iwlwifi/iwl-core.h | 5 +++++
3 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 2bbd04d..46503a6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -134,6 +134,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
}

memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
+ iwl_print_rx_config_cmd(priv);
return 0;
}

@@ -229,6 +230,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
}
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
}
+ iwl_print_rx_config_cmd(priv);

iwl_init_sensitivity(priv);

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 112181b..34ffcdd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1329,7 +1329,7 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
EXPORT_SYMBOL(iwl_rx_csa);

#ifdef CONFIG_IWLWIFI_DEBUG
-static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
+void iwl_print_rx_config_cmd(struct iwl_priv *priv)
{
struct iwl_rxon_cmd *rxon = &priv->staging_rxon;

@@ -1347,6 +1347,7 @@ static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
}
+EXPORT_SYMBOL(iwl_print_rx_config_cmd);
#endif
/**
* iwl_irq_handle_error - called for HW or SW error interrupt from card
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 9574d8f..3f97036 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -579,6 +579,7 @@ int iwl_pci_resume(struct pci_dev *pdev);
#ifdef CONFIG_IWLWIFI_DEBUG
void iwl_dump_nic_event_log(struct iwl_priv *priv);
void iwl_dump_nic_error_log(struct iwl_priv *priv);
+void iwl_print_rx_config_cmd(struct iwl_priv *priv);
#else
static inline void iwl_dump_nic_event_log(struct iwl_priv *priv)
{
@@ -587,6 +588,10 @@ static inline void iwl_dump_nic_event_log(struct iwl_priv *priv)
static inline void iwl_dump_nic_error_log(struct iwl_priv *priv)
{
}
+
+static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv)
+{
+}
#endif

void iwl_clear_isr_stats(struct iwl_priv *priv);
--
1.5.6.3


2009-11-06 22:53:00

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 05/20] iwlwifi: use configured valid rx chain for scan

From: Shanyu Zhao <[email protected]>

Use configured valid rx chains in scan command instead of ANT_ABC, correcting
valid rx chain configuration of 4965, should be ANT_ABC instead of ANT_AB.

Signed-off-by: Shanyu Zhao <[email protected]>
Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-scan.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 62c95eb..607c312 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2229,7 +2229,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
.num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
.mod_params = &iwl4965_mod_params,
.valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
+ .valid_rx_ant = ANT_ABC,
.pll_cfg_val = 0,
.set_l0s = true,
.use_bsm = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 48bc263..a2b2b83 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -749,7 +749,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
rx_ant = first_antenna(active_chains);
}
/* MIMO is not used here, but value is required */
- rx_chain |= ANT_ABC << RXON_RX_CHAIN_VALID_POS;
+ rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
--
1.5.6.3


2009-11-06 22:53:04

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 17/20] iwlwifi: Add comments about MAC_ACCESS_REQ

From: Ben Cahill <[email protected]>

Signed-off-by: Ben Cahill <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-io.h | 20 ++++++++++++++++++++
1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h
index 0a078b0..d0a358c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/iwlwifi/iwl-io.h
@@ -200,6 +200,26 @@ static inline int _iwl_grab_nic_access(struct iwl_priv *priv)

/* this bit wakes up the NIC */
_iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
+ /*
+ * These bits say the device is running, and should keep running for
+ * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
+ * but they do not indicate that embedded SRAM is restored yet;
+ * 3945 and 4965 have volatile SRAM, and must save/restore contents
+ * to/from host DRAM when sleeping/waking for power-saving.
+ * Each direction takes approximately 1/4 millisecond; with this
+ * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
+ * series of register accesses are expected (e.g. reading Event Log),
+ * to keep device from sleeping.
+ *
+ * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
+ * SRAM is okay/restored. We don't check that here because this call
+ * is just for hardware register access; but GP1 MAC_SLEEP check is a
+ * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
+ *
+ * 5000 series and later (including 1000 series) have non-volatile SRAM,
+ * and do not save/restore SRAM when power cycling.
+ */
ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
(CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
--
1.5.6.3


2009-11-06 22:53:05

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 16/20] iwlwifi: Update comments for struct iwl_ssid_ie

From: Ben Cahill <[email protected]>

Signed-off-by: Ben Cahill <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-commands.h | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index b62c90e..2857287 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2566,9 +2566,10 @@ struct iwl_scan_channel {
/**
* struct iwl_ssid_ie - directed scan network information element
*
- * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field
- * in struct iwl_scan_channel; each channel may select different ssids from
- * among the 4 entries. SSID IEs get transmitted in reverse order of entry.
+ * Up to 20 of these may appear in REPLY_SCAN_CMD (Note: Only 4 are in
+ * 3945 SCAN api), selected by "type" bit field in struct iwl_scan_channel;
+ * each channel may select different ssids from among the 20 (4) entries.
+ * SSID IEs get transmitted in reverse order of entry.
*/
struct iwl_ssid_ie {
u8 id;
--
1.5.6.3


2009-11-06 22:53:01

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 09/20] iwlwifi: remove un-used parameter

From: Wey-Yi Guy <[email protected]>

Remove un-used parameter "recovery_rxon" from "priv" data structure

Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-dev.h | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index b4e8145..9975645 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1087,8 +1087,6 @@ struct iwl_priv {
const struct iwl_rxon_cmd active_rxon;
struct iwl_rxon_cmd staging_rxon;

- struct iwl_rxon_cmd recovery_rxon;
-
/* 1st responses from initialize and runtime uCode images.
* 4965's initialize alive response contains some calibration data. */
struct iwl_init_alive_resp card_alive_init;
--
1.5.6.3


2009-11-06 22:53:05

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 19/20] iwlwifi: Fix issue on file transfer stalled in HT mode

From: Wey-Yi Guy <[email protected]>

Turn on RTS/CTS for HT to prevent uCode TX fifo underrun

This is fix for
http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2103

Signed-off-by: Wey-Yi Guy <[email protected]>
Tested-by: Jiajia Zheng <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
This is a serious problem that needs to be fixed also in 2.6.32 and 2.6.31.
This patch does depend on some other work that is not in these kernels
though so separate backported patches will be provided.

drivers/net/wireless/iwlwifi/iwl-1000.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 1e387b9..8f82537 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -170,6 +170,7 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.shadow_ram_support = false,
.ht_greenfield_support = true,
.led_compensation = 51,
+ .use_rts_for_ht = true, /* use rts/cts protection */
.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
.support_ct_kill_exit = true,
};
--
1.5.6.3


2009-11-06 22:53:01

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 06/20] iwlwifi: no periodic Tx/IQ calibration for 6x00/6x50 series

From: Wey-Yi Guy <[email protected]>

For both 6x00 and 6x50 series devices, periodic Tx IQ calibration is
disabled in uCode, driver do not need to set the periodic Tx/IQ calibration
bit in calibration command.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 70e117f..9ab7954 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -166,9 +166,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
BIT(IWL_CALIB_XTAL) |
BIT(IWL_CALIB_LO) |
BIT(IWL_CALIB_TX_IQ) |
- BIT(IWL_CALIB_TX_IQ_PERD) |
BIT(IWL_CALIB_BASE_BAND);
-
return 0;
}

--
1.5.6.3


2009-11-06 22:53:01

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 07/20] iwlwifi: don't double-activate queue 4

From: Johannes Berg <[email protected]>

The fourth queue (command queue) is already activated in
the loop above that also maps it to the command FIFO and
therefore doesn't need to be marked as activated again.
Also change the TODO comment to be accurate -- we need
to initialise the _queues_, not FIFOs, and map them to
device FIFOs.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index a97d93d..f6cbbfa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -662,9 +662,13 @@ int iwl5000_alive_notify(struct iwl_priv *priv)
iwl_txq_ctx_activate(priv, i);
iwl5000_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
}
- /* TODO - need to initialize those FIFOs inside the loop above,
- * not only mark them as active */
- iwl_txq_ctx_activate(priv, 4);
+
+ /*
+ * TODO - need to initialize these queues and map them to FIFOs
+ * in the loop above, not only mark them as active. We do this
+ * because we want the first aggregation queue to be queue #10,
+ * but do not use 8 or 9 otherwise yet.
+ */
iwl_txq_ctx_activate(priv, 7);
iwl_txq_ctx_activate(priv, 8);
iwl_txq_ctx_activate(priv, 9);
--
1.5.6.3


2009-11-06 22:52:59

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 02/20] iwlwifi: allocate 128 bytes linear buffer for rx skb

From: Zhu Yi <[email protected]>

Allocate 128 bytes linear buffer for rx skb. The first 64 bytes is
reserved for mac80211 usage (for radiotap header expansion, etc).
The frame header starts from the second 64 bytes.

Cc: Johannes Berg <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 3 ++-
drivers/net/wireless/iwlwifi/iwl-rx.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 562860b..7da1dab 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -565,7 +565,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
return;
}

- skb = alloc_skb(IWL_LINK_HDR_MAX, GFP_ATOMIC);
+ skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC);
if (!skb) {
IWL_ERR(priv, "alloc_skb failed\n");
return;
@@ -576,6 +576,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
(struct ieee80211_hdr *)rxb_addr(rxb),
le32_to_cpu(rx_end->status), stats);

+ skb_reserve(skb, IWL_LINK_HDR_MAX);
skb_add_rx_frag(skb, 0, rxb->page,
(void *)rx_hdr->payload - (void *)pkt, len);

diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index e5339c9..d2dc7cc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -937,12 +937,13 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
return;

- skb = alloc_skb(IWL_LINK_HDR_MAX, GFP_ATOMIC);
+ skb = alloc_skb(IWL_LINK_HDR_MAX * 2, GFP_ATOMIC);
if (!skb) {
IWL_ERR(priv, "alloc_skb failed\n");
return;
}

+ skb_reserve(skb, IWL_LINK_HDR_MAX);
skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);

/* mac80211 currently doesn't support paged SKB. Convert it to
--
1.5.6.3


2009-11-06 22:52:58

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 01/20] iwlwifi: change debug message to error in failure case

From: Reinette Chatre <[email protected]>

Since these messages indicate failure we would be interested in seeing them
always.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index ccf50a9..a231659 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -200,13 +200,13 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
}

if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
- IWL_DEBUG_INFO(priv, "Command %s aborted: RF KILL Switch\n",
+ IWL_ERR(priv, "Command %s aborted: RF KILL Switch\n",
get_cmd_string(cmd->id));
ret = -ECANCELED;
goto fail;
}
if (test_bit(STATUS_FW_ERROR, &priv->status)) {
- IWL_DEBUG_INFO(priv, "Command %s failed: FW Error\n",
+ IWL_ERR(priv, "Command %s failed: FW Error\n",
get_cmd_string(cmd->id));
ret = -EIO;
goto fail;
--
1.5.6.3


2009-11-06 22:53:04

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 14/20] iwlwifi: Limit size of Event Log dump

From: Ben Cahill <[email protected]>

If device provides bad values for Event Log parameters (due to being asleep
or SRAM corruption, etc.), the size can be very, very large (e.g. 0xa5a5a5a5),
which can flood system log.

Sanity-check capacity and next_entry values and limit to reasonable size dump.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index eff52b1..be99d19 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1703,6 +1703,9 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
}
}

+/* For sanity check only. Actual size is determined by uCode, typ. 512 */
+#define MAX_EVENT_LOG_SIZE (512)
+
void iwl_dump_nic_event_log(struct iwl_priv *priv)
{
u32 base; /* SRAM byte address of event log header */
@@ -1728,6 +1731,18 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));

+ if (capacity > MAX_EVENT_LOG_SIZE) {
+ IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
+ capacity, MAX_EVENT_LOG_SIZE);
+ capacity = MAX_EVENT_LOG_SIZE;
+ }
+
+ if (next_entry > MAX_EVENT_LOG_SIZE) {
+ IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
+ next_entry, MAX_EVENT_LOG_SIZE);
+ next_entry = MAX_EVENT_LOG_SIZE;
+ }
+
size = num_wraps ? capacity : next_entry;

/* bail out if nothing in log */
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 84dce68..75caa5f 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1604,6 +1604,9 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
}
}

+/* For sanity check only. Actual size is determined by uCode, typ. 512 */
+#define IWL3945_MAX_EVENT_LOG_SIZE (512)
+
void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
{
u32 base; /* SRAM byte address of event log header */
@@ -1625,6 +1628,18 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));

+ if (capacity > IWL3945_MAX_EVENT_LOG_SIZE) {
+ IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
+ capacity, IWL3945_MAX_EVENT_LOG_SIZE);
+ capacity = IWL3945_MAX_EVENT_LOG_SIZE;
+ }
+
+ if (next_entry > IWL3945_MAX_EVENT_LOG_SIZE) {
+ IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
+ next_entry, IWL3945_MAX_EVENT_LOG_SIZE);
+ next_entry = IWL3945_MAX_EVENT_LOG_SIZE;
+ }
+
size = num_wraps ? capacity : next_entry;

/* bail out if nothing in log */
--
1.5.6.3


2009-11-06 22:53:02

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 12/20] iwlwifi: drop non-production PCI-IDs

From: Wey-Yi Guy <[email protected]>

Remove the support for all the PCI_IDs never make into production

Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-6000.c | 98 +------------------------------
drivers/net/wireless/iwlwifi/iwl-agn.c | 8 ---
drivers/net/wireless/iwlwifi/iwl-dev.h | 4 +-
3 files changed, 2 insertions(+), 108 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 1f769ea..f732f6d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -90,11 +90,7 @@ static void iwl6000_nic_config(struct iwl_priv *priv)
CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);

/* no locking required for register write */
- if (priv->cfg->pa_type == IWL_PA_HYBRID) {
- /* 2x2 hybrid phy type */
- iwl_write32(priv, CSR_GP_DRIVER_REG,
- CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB);
- } else if (priv->cfg->pa_type == IWL_PA_INTERNAL) {
+ if (priv->cfg->pa_type == IWL_PA_INTERNAL) {
/* 2x2 IPA phy type */
iwl_write32(priv, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
@@ -279,98 +275,6 @@ static struct iwl_ops iwl6050_ops = {
.led = &iwlagn_led_ops,
};

-
-/*
- * "h": Hybrid configuration, use both internal and external Power Amplifier
- */
-struct iwl_cfg iwl6000h_2agn_cfg = {
- .name = "6000 Series 2x2 AGN",
- .fw_name_pre = IWL6000_FW_PRE,
- .ucode_api_max = IWL6000_UCODE_API_MAX,
- .ucode_api_min = IWL6000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
- .ops = &iwl6000_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
- .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
- .num_of_queues = IWL50_NUM_QUEUES,
- .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
- .mod_params = &iwl50_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_HYBRID,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .use_rts_for_ht = true, /* use rts/cts protection */
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
-};
-
-struct iwl_cfg iwl6000h_2abg_cfg = {
- .name = "6000 Series 2x2 ABG",
- .fw_name_pre = IWL6000_FW_PRE,
- .ucode_api_max = IWL6000_UCODE_API_MAX,
- .ucode_api_min = IWL6000_UCODE_API_MIN,
- .sku = IWL_SKU_A|IWL_SKU_G,
- .ops = &iwl6000_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
- .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
- .num_of_queues = IWL50_NUM_QUEUES,
- .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
- .mod_params = &iwl50_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_HYBRID,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
-};
-
-struct iwl_cfg iwl6000h_2bg_cfg = {
- .name = "6000 Series 2x2 BG",
- .fw_name_pre = IWL6000_FW_PRE,
- .ucode_api_max = IWL6000_UCODE_API_MAX,
- .ucode_api_min = IWL6000_UCODE_API_MIN,
- .sku = IWL_SKU_G,
- .ops = &iwl6000_ops,
- .eeprom_size = OTP_LOW_IMAGE_SIZE,
- .eeprom_ver = EEPROM_6000_EEPROM_VERSION,
- .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
- .num_of_queues = IWL50_NUM_QUEUES,
- .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
- .mod_params = &iwl50_mod_params,
- .valid_tx_ant = ANT_AB,
- .valid_rx_ant = ANT_AB,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = false,
- .pa_type = IWL_PA_HYBRID,
- .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
- .shadow_ram_support = true,
- .ht_greenfield_support = true,
- .led_compensation = 51,
- .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
- .supports_idle = true,
- .adv_thermal_throttle = true,
- .support_ct_kill_exit = true,
-};
-
/*
* "i": Internal configuration, use internal Power Amplifier
*/
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index fd7ba51..eff52b1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3453,14 +3453,6 @@ static struct pci_device_id iwl_hw_card_ids[] = {
{IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)},

/* 6x00 Series */
- {IWL_PCI_DEVICE(0x008D, 0x1301, iwl6000h_2agn_cfg)},
- {IWL_PCI_DEVICE(0x008D, 0x1321, iwl6000h_2agn_cfg)},
- {IWL_PCI_DEVICE(0x008D, 0x1326, iwl6000h_2abg_cfg)},
- {IWL_PCI_DEVICE(0x008D, 0x1306, iwl6000h_2abg_cfg)},
- {IWL_PCI_DEVICE(0x008D, 0x1307, iwl6000h_2bg_cfg)},
- {IWL_PCI_DEVICE(0x008E, 0x1311, iwl6000h_2agn_cfg)},
- {IWL_PCI_DEVICE(0x008E, 0x1316, iwl6000h_2abg_cfg)},
-
{IWL_PCI_DEVICE(0x422B, 0x1101, iwl6000_3agn_cfg)},
{IWL_PCI_DEVICE(0x422B, 0x1121, iwl6000_3agn_cfg)},
{IWL_PCI_DEVICE(0x422C, 0x1301, iwl6000i_2agn_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 9a19a3d..9dea8fa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -927,13 +927,11 @@ enum iwl_access_mode {
/**
* enum iwl_pa_type - Power Amplifier type
* @IWL_PA_SYSTEM: based on uCode configuration
- * @IWL_PA_HYBRID: use both Internal and external PA
* @IWL_PA_INTERNAL: use Internal only
*/
enum iwl_pa_type {
IWL_PA_SYSTEM = 0,
- IWL_PA_HYBRID = 1,
- IWL_PA_INTERNAL = 2,
+ IWL_PA_INTERNAL = 1,
};

/* interrupt statistics */
--
1.5.6.3