2008-10-06 08:11:49

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 0/7] iwlwifi driver 10/06 updates

Hi John,

Here are some updates for iwlwifi. Please apply.

Thanks,
-yi

[PATCH 1/7] iwlwifi: make initial calibration set configurable
[PATCH 2/7] iwlwifi: fix ct kill configuration for 5350
[PATCH 3/7] iwlwifi: scan correct setting of valid rx_chains
[PATCH 4/7] iwlwifi: scan fix comment
[PATCH 5/7] iwlwifi: take a valid antenna upon rate scale init
[PATCH 6/7] iwlwifi: remove STATUS_CONF_PENDING in scanning
[PATCH 7/7] iwlwifi: refactor rxon time command


2008-10-06 08:11:50

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 1/7] iwlwifi: make initial calibration set configurable

From: Tomas Winkler <[email protected]>

This patch adds ability to configure inital calibration set.
Some clean ups are also included in this patch.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 1 +
drivers/net/wireless/iwlwifi/iwl-5000.c | 44 +++++++++++++++++---------
drivers/net/wireless/iwlwifi/iwl-calib.c | 8 +++--
drivers/net/wireless/iwlwifi/iwl-commands.h | 27 +++++++----------
drivers/net/wireless/iwlwifi/iwl-dev.h | 4 ++-
5 files changed, 49 insertions(+), 35 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index c479ee2..66ed993 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -132,6 +132,7 @@ struct iwl5000_shared {
/* calibrations defined for 5000 */
/* defines the order in which results should be sent to the runtime uCode */
enum iwl5000_calib {
+ IWL5000_CALIB_XTAL,
IWL5000_CALIB_LO,
IWL5000_CALIB_TX_IQ,
IWL5000_CALIB_TX_IQ_PERD,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index f6003e7..ba92667 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -429,20 +429,19 @@ static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
/*
* Calibration
*/
-static int iwl5000_send_Xtal_calib(struct iwl_priv *priv)
+static int iwl5000_set_Xtal_calib(struct iwl_priv *priv)
{
+ u8 data[sizeof(struct iwl5000_calib_hdr) +
+ sizeof(struct iwl_cal_xtal_freq)];
+ struct iwl5000_calib_cmd *cmd = (struct iwl5000_calib_cmd *)data;
+ struct iwl_cal_xtal_freq *xtal = (struct iwl_cal_xtal_freq *)cmd->data;
u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);

- struct iwl5000_calibration cal_cmd = {
- .op_code = IWL5000_PHY_CALIBRATE_CRYSTAL_FRQ_CMD,
- .data = {
- (u8)xtal_calib[0],
- (u8)xtal_calib[1],
- }
- };
-
- return iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
- sizeof(cal_cmd), &cal_cmd);
+ cmd->hdr.op_code = IWL5000_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
+ xtal->cap_pin1 = (u8)xtal_calib[0];
+ xtal->cap_pin2 = (u8)xtal_calib[1];
+ return iwl_calib_set(&priv->calib_results[IWL5000_CALIB_XTAL],
+ data, sizeof(data));
}

static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
@@ -784,10 +783,8 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)

iwl5000_send_wimax_coex(priv);

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

return 0;
}
@@ -844,6 +841,23 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
break;
}

+ /* Set initial calibration set */
+ switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+ case CSR_HW_REV_TYPE_5100:
+ case CSR_HW_REV_TYPE_5300:
+ case CSR_HW_REV_TYPE_5350:
+ priv->hw_params.calib_init_cfg =
+ BIT(IWL5000_CALIB_XTAL) |
+ BIT(IWL5000_CALIB_LO) |
+ BIT(IWL5000_CALIB_TX_IQ) |
+ BIT(IWL5000_CALIB_TX_IQ_PERD);
+ break;
+ case CSR_HW_REV_TYPE_5150:
+ priv->hw_params.calib_init_cfg = 0;
+ break;
+ }
+
+
return 0;
}

diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 72fbf47..25f4658 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -70,7 +70,7 @@
* INIT calibrations framework
*****************************************************************************/

- int iwl_send_calib_results(struct iwl_priv *priv)
+int iwl_send_calib_results(struct iwl_priv *priv)
{
int ret = 0;
int i = 0;
@@ -80,14 +80,16 @@
.meta.flags = CMD_SIZE_HUGE,
};

- for (i = 0; i < IWL_CALIB_MAX; i++)
- if (priv->calib_results[i].buf) {
+ for (i = 0; i < IWL_CALIB_MAX; i++) {
+ if ((BIT(i) & priv->hw_params.calib_init_cfg) &&
+ 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:
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 8d04e96..fc467c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -98,6 +98,11 @@ enum {
COEX_MEDIUM_NOTIFICATION = 0x5b,
COEX_EVENT_CMD = 0x5c,

+ /* Calibration */
+ CALIBRATION_CFG_CMD = 0x65,
+ CALIBRATION_RES_NOTIFICATION = 0x66,
+ CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
+
/* 802.11h related */
RADAR_NOTIFICATION = 0x70, /* not used */
REPLY_QUIET_CMD = 0x71, /* not used */
@@ -2879,25 +2884,11 @@ enum {
IWL5000_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD = 19,
};

-enum {
- CALIBRATION_CFG_CMD = 0x65,
- CALIBRATION_RES_NOTIFICATION = 0x66,
- CALIBRATION_COMPLETE_NOTIFICATION = 0x67
-};
-
-struct iwl_cal_crystal_freq_cmd {
+struct iwl_cal_xtal_freq {
u8 cap_pin1;
u8 cap_pin2;
} __attribute__ ((packed));

-struct iwl5000_calibration {
- u8 op_code;
- u8 first_group;
- u8 num_groups;
- u8 all_data_valid;
- struct iwl_cal_crystal_freq_cmd data;
-} __attribute__ ((packed));
-
#define IWL_CALIB_INIT_CFG_ALL __constant_cpu_to_le32(0xffffffff)

struct iwl_calib_cfg_elmnt_s {
@@ -2927,6 +2918,11 @@ struct iwl5000_calib_hdr {
u8 data_valid;
} __attribute__ ((packed));

+struct iwl5000_calib_cmd {
+ struct iwl5000_calib_hdr hdr;
+ u8 data[0];
+} __attribute__ ((packed));
+
struct iwl5000_calibration_chain_noise_reset_cmd {
u8 op_code; /* IWL5000_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */
u8 flags; /* not used */
@@ -3039,7 +3035,6 @@ struct iwl_rx_packet {
struct iwl_notif_statistics stats;
struct iwl_compressed_ba_resp compressed_ba;
struct iwl4965_missed_beacon_notif missed_beacon;
- struct iwl5000_calibration calib;
__le32 status;
u8 raw[0];
} u;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index c018121..2125844 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -527,6 +527,7 @@ struct iwl_sensitivity_ranges {
* @sw_crypto: 0 for hw, 1 for sw
* @max_xxx_size: for ucode uses
* @ct_kill_threshold: temperature threshold
+ * @calib_init_cfg: setup initial claibrations for the hw
* @struct iwl_sensitivity_ranges: range of sensitivity values
* @first_ampdu_q: first HW queue available for ampdu
*/
@@ -548,6 +549,7 @@ struct iwl_hw_params {
u32 max_data_size;
u32 max_bsm_size;
u32 ct_kill_threshold; /* value in hw-dependent units */
+ u32 calib_init_cfg;
const struct iwl_sensitivity_ranges *sens;
u8 first_ampdu_q;
};
@@ -765,7 +767,7 @@ enum {


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

struct iwl_priv {

--
1.5.3.6


2008-10-06 08:11:54

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 4/7] iwlwifi: scan fix comment

From: Tomas Winkler <[email protected]>

This patch moves comment to proper line, it has moved during
code shuffling.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index debdbd9..639904a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -843,7 +843,7 @@ static void iwl_bg_request_scan(struct work_struct *data)

/* Force use of chains B and C (0x6) for scan Rx for 4965
* Avoid A (0x1) because of its off-channel reception on A-band.
- * MIMO is not used here, but value is required */
+ */
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
rx_chain = 0x6;
} else {
@@ -851,6 +851,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
goto done;
}

+ /* MIMO is not used here, but value is required */
scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |
cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |
(rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) |
--
1.5.3.6


2008-10-06 21:31:03

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 7/7] iwlwifi: refactor rxon time command

On Mon, Oct 06, 2008 at 04:05:33PM +0800, Zhu Yi wrote:
> From: Tomas Winkler <[email protected]>
>
> This patch refactors rxon time command.

Why did you refactor it? What did you change? What did you
accomplish?

John
--
John W. Linville Linux should be at the core
[email protected] of your literate lifestyle.

2008-10-06 21:13:27

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 1/7] iwlwifi: make initial calibration set configurable

On Mon, Oct 06, 2008 at 04:05:27PM +0800, Zhu Yi wrote:
> From: Tomas Winkler <[email protected]>
>
> This patch adds ability to configure inital calibration set.
> Some clean ups are also included in this patch.
>
> Signed-off-by: Tomas Winkler <[email protected]>
> Signed-off-by: Zhu Yi <[email protected]>

Why do I want to do this? What does this buy us? How does this make
things better?

John
--
John W. Linville Linux should be at the core
[email protected] of your literate lifestyle.

2008-10-06 21:39:51

by Tomas Winkler

[permalink] [raw]
Subject: Re: [PATCH 5/7] iwlwifi: take a valid antenna upon rate scale init

On Mon, Oct 6, 2008 at 11:25 PM, John W. Linville
<[email protected]> wrote:
> On Mon, Oct 06, 2008 at 04:05:31PM +0800, Zhu Yi wrote:
>> From: Tomas Winkler <[email protected]>
>>
>> This patch selects a valid antenna upon RS init. This solves a SYSASSERT
>> complaining that the driver is setting a non valid antenna in the LQ CMD.
>
> I suppose this is an accurate description, but I think you can do
> better. :-)

>
>> diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
>> index c1300fb..56a3f0c 100644
>> --- a/drivers/net/wireless/iwlwifi/iwl-5000.c
>> +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
>> @@ -811,10 +811,14 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
>>
>> switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
>> case CSR_HW_REV_TYPE_5100:
>> + priv->hw_params.tx_chains_num = 1;
>> + priv->hw_params.rx_chains_num = 2;
>> + priv->hw_params.valid_tx_ant = ANT_B;
>> + priv->hw_params.valid_rx_ant = ANT_AB;
>> + break;
>> case CSR_HW_REV_TYPE_5150:
>> priv->hw_params.tx_chains_num = 1;
>> priv->hw_params.rx_chains_num = 2;
>> - /* FIXME: move to ANT_A, ANT_B, ANT_C enum */
>> priv->hw_params.valid_tx_ant = ANT_A;
>> priv->hw_params.valid_rx_ant = ANT_AB;
>> break;
>
> Do you realize that both clauses are the same (i.e. there is no
> functional change)? How is this useful?

The change is tx_ant

>
>> diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
>> index d148d73..bac91f1 100644
>> --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
>> +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
>> @@ -284,6 +284,16 @@ static inline u8 num_of_ant(u8 mask)
>> !!((mask) & ANT_C);
>> }
>>
>> +static inline u8 first_antenna(u8 mask)
>> +{
>> + if (mask & ANT_A)
>> + return ANT_A;
>> + if (mask & ANT_B)
>> + return ANT_B;
>> + return ANT_C;
>> +}
>> +
>> +
>> static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
>> {
>> u8 rate = iwl_rates[rate_index].prev_ieee;
>> diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
>> index 61797f3..f9efc0c 100644
>> --- a/drivers/net/wireless/iwlwifi/iwl-sta.c
>> +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
>> @@ -852,7 +852,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
>> struct iwl_link_quality_cmd link_cmd = {
>> .reserved1 = 0,
>> };
>> - u16 rate_flags;
>> + u32 rate_flags;
>>
>> /* Set up the rate scaling to start at selected rate, fall back
>> * all the way down to 1M in IEEE order, and then spin on 1M */
>> @@ -869,14 +869,16 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
>> rate_flags |= RATE_MCS_CCK_MSK;
>>
>> /* Use Tx antenna B only */
>> - rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/
>> + rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
>> + RATE_MCS_ANT_POS;
>
> You need to change the comment...

Right
> John
> --
> John W. Linville Linux should be at the core
> [email protected] of your literate lifestyle.
> --
> 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-10-06 08:12:03

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 6/7] iwlwifi: remove STATUS_CONF_PENDING in scanning

From: Tomas Winkler <[email protected]>

This patch removes STATUS_CONF_PENDING usage that called from
iwl4965_mac_config internally after scan completed.

It's called anyway from the mac80211 ieee80211_scan_completed():

if (local->hw_scanning) {
local->hw_scanning = false;
if (ieee80211_hw_config(local))
...
}

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 28 ----------------------------
drivers/net/wireless/iwlwifi/iwl-core.h | 3 +--
drivers/net/wireless/iwlwifi/iwl-scan.c | 23 +++++++++++++++++++++--
3 files changed, 22 insertions(+), 32 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 204abab..24a1aeb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2569,30 +2569,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv)

}

-static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
-
-static void iwl_bg_scan_completed(struct work_struct *work)
-{
- struct iwl_priv *priv =
- container_of(work, struct iwl_priv, scan_completed);
-
- IWL_DEBUG_SCAN("SCAN complete scan\n");
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (test_bit(STATUS_CONF_PENDING, &priv->status))
- iwl4965_mac_config(priv->hw, ieee80211_get_hw_conf(priv->hw));
-
- ieee80211_scan_completed(priv->hw);
-
- /* Since setting the TXPOWER may have been deferred while
- * performing the scan, fire one off */
- mutex_lock(&priv->mutex);
- iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
- mutex_unlock(&priv->mutex);
-}
-
/*****************************************************************************
*
* mac80211 entry point functions
@@ -2812,7 +2788,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
test_bit(STATUS_SCANNING, &priv->status))) {
IWL_DEBUG_MAC80211("leave - scanning\n");
- set_bit(STATUS_CONF_PENDING, &priv->status);
mutex_unlock(&priv->mutex);
return 0;
}
@@ -2898,7 +2873,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
IWL_DEBUG_MAC80211("leave\n");

out:
- clear_bit(STATUS_CONF_PENDING, &priv->status);
mutex_unlock(&priv->mutex);
return ret;
}
@@ -4117,8 +4091,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);

- /* 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);

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 55a4b58..288b6a8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -333,8 +333,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv);
#define STATUS_SCAN_HW 15
#define STATUS_POWER_PMI 16
#define STATUS_FW_ERROR 17
-#define STATUS_CONF_PENDING 18
-#define STATUS_MODE_PENDING 19
+#define STATUS_MODE_PENDING 18


static inline int iwl_is_ready(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 639904a..3b0bee3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -916,10 +916,29 @@ static void iwl_bg_abort_scan(struct work_struct *work)
mutex_unlock(&priv->mutex);
}

+static void iwl_bg_scan_completed(struct work_struct *work)
+{
+ struct iwl_priv *priv =
+ container_of(work, struct iwl_priv, scan_completed);
+
+ IWL_DEBUG_SCAN("SCAN complete scan\n");
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ ieee80211_scan_completed(priv->hw);
+
+ /* Since setting the TXPOWER may have been deferred while
+ * performing the scan, fire one off */
+ mutex_lock(&priv->mutex);
+ iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
+ mutex_unlock(&priv->mutex);
+}
+
+
void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
{
- /* FIXME: move here when resolved PENDING
- * INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); */
+ INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
--
1.5.3.6


2008-10-06 21:17:36

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 4/7] iwlwifi: scan fix comment

On Mon, Oct 06, 2008 at 04:05:30PM +0800, Zhu Yi wrote:
> From: Tomas Winkler <[email protected]>
>
> This patch moves comment to proper line, it has moved during
> code shuffling.

This description is OK.

John
--
John W. Linville Linux should be at the core
[email protected] of your literate lifestyle.

2008-10-06 21:15:40

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 2/7] iwlwifi: fix ct kill configuration for 5350

On Mon, Oct 06, 2008 at 04:05:28PM +0800, Zhu Yi wrote:
> From: Tomas Winkler <[email protected]>
>
> This patch fixes ct kill configuration for 5350.

How about "we need to use the temperature units that the hardware
expects for its critical temperature setting"?

John
--
John W. Linville Linux should be at the core
[email protected] of your literate lifestyle.

2008-10-06 08:11:51

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 3/7] iwlwifi: scan correct setting of valid rx_chains

From: Tomas Winkler <[email protected]>

This patch sets rx_chain bitmap correctly according hw configuration.

Signed-off-by: Tomas Winkler <[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 bf855c3..debdbd9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -703,7 +703,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
u16 cmd_len;
enum ieee80211_band band;
u8 n_probes = 2;
- u8 rx_chain = 0x7; /* bitmap: ABC chains */
+ u8 rx_chain = priv->hw_params.valid_rx_ant;

conf = ieee80211_get_hw_conf(priv->hw);

--
1.5.3.6


2008-10-06 21:17:05

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 3/7] iwlwifi: scan correct setting of valid rx_chains

On Mon, Oct 06, 2008 at 04:05:29PM +0800, Zhu Yi wrote:
> From: Tomas Winkler <[email protected]>
>
> This patch sets rx_chain bitmap correctly according hw configuration.

I guess this description is OK...I'm sure you can do better.

John
--
John W. Linville Linux should be at the core
[email protected] of your literate lifestyle.

2008-10-06 08:12:09

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 7/7] iwlwifi: refactor rxon time command

From: Tomas Winkler <[email protected]>

This patch refactors rxon time command.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Zhu Yi <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 70 ++++++++++-----------------
drivers/net/wireless/iwlwifi/iwl-commands.h | 11 +---
drivers/net/wireless/iwlwifi/iwl-dev.h | 3 +-
3 files changed, 29 insertions(+), 55 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 24a1aeb..d6100e7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -637,23 +637,22 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force)

#define MAX_UCODE_BEACON_INTERVAL 4096

-static __le16 iwl4965_adjust_beacon_interval(u16 beacon_val)
+static u16 iwl_adjust_beacon_interval(u16 beacon_val)
{
u16 new_val = 0;
u16 beacon_factor = 0;

- beacon_factor =
- (beacon_val + MAX_UCODE_BEACON_INTERVAL)
- / MAX_UCODE_BEACON_INTERVAL;
+ beacon_factor = (beacon_val + MAX_UCODE_BEACON_INTERVAL)
+ / MAX_UCODE_BEACON_INTERVAL;
new_val = beacon_val / beacon_factor;

- return cpu_to_le16(new_val);
+ return new_val;
}

-static void iwl4965_setup_rxon_timing(struct iwl_priv *priv)
+static void iwl_setup_rxon_timing(struct iwl_priv *priv)
{
- u64 interval_tm_unit;
- u64 tsf, result;
+ u64 tsf;
+ s32 interval_tm, rem;
unsigned long flags;
struct ieee80211_conf *conf = NULL;
u16 beacon_int = 0;
@@ -661,49 +660,32 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv)
conf = ieee80211_get_hw_conf(priv->hw);

spin_lock_irqsave(&priv->lock, flags);
- priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp >> 32);
- priv->rxon_timing.timestamp.dw[0] =
- cpu_to_le32(priv->timestamp & 0xFFFFFFFF);
-
+ priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);

- tsf = priv->timestamp;
-
- beacon_int = priv->beacon_int;
- spin_unlock_irqrestore(&priv->lock, flags);
-
if (priv->iw_mode == NL80211_IFTYPE_STATION) {
- if (beacon_int == 0) {
- priv->rxon_timing.beacon_interval = cpu_to_le16(100);
- priv->rxon_timing.beacon_init_val = cpu_to_le32(102400);
- } else {
- priv->rxon_timing.beacon_interval =
- cpu_to_le16(beacon_int);
- priv->rxon_timing.beacon_interval =
- iwl4965_adjust_beacon_interval(
- le16_to_cpu(priv->rxon_timing.beacon_interval));
- }
-
+ beacon_int = iwl_adjust_beacon_interval(priv->beacon_int);
priv->rxon_timing.atim_window = 0;
} else {
- priv->rxon_timing.beacon_interval =
- iwl4965_adjust_beacon_interval(conf->beacon_int);
+ beacon_int = iwl_adjust_beacon_interval(conf->beacon_int);
+
/* TODO: we need to get atim_window from upper stack
* for now we set to 0 */
priv->rxon_timing.atim_window = 0;
}

- interval_tm_unit =
- (le16_to_cpu(priv->rxon_timing.beacon_interval) * 1024);
- result = do_div(tsf, interval_tm_unit);
- priv->rxon_timing.beacon_init_val =
- cpu_to_le32((u32) ((u64) interval_tm_unit - result));
+ priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int);

- IWL_DEBUG_ASSOC
- ("beacon interval %d beacon timer %d beacon tim %d\n",
- le16_to_cpu(priv->rxon_timing.beacon_interval),
- le32_to_cpu(priv->rxon_timing.beacon_init_val),
- le16_to_cpu(priv->rxon_timing.atim_window));
+ tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
+ interval_tm = beacon_int * 1024;
+ rem = do_div(tsf, interval_tm);
+ priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+ IWL_DEBUG_ASSOC("beacon interval %d beacon timer %d beacon tim %d\n",
+ le16_to_cpu(priv->rxon_timing.beacon_interval),
+ le32_to_cpu(priv->rxon_timing.beacon_init_val),
+ le16_to_cpu(priv->rxon_timing.atim_window));
}

static void iwl_set_flags_for_band(struct iwl_priv *priv,
@@ -2494,8 +2476,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl4965_commit_rxon(priv);

- memset(&priv->rxon_timing, 0, sizeof(struct iwl4965_rxon_time_cmd));
- iwl4965_setup_rxon_timing(priv);
+ iwl_setup_rxon_timing(priv);
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (ret)
@@ -2886,15 +2867,14 @@ static void iwl4965_config_ap(struct iwl_priv *priv)
return;

/* The following should be done only at AP bring up */
- if (!(iwl_is_associated(priv))) {
+ if (!iwl_is_associated(priv)) {

/* RXON - unassoc (to set timing command) */
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl4965_commit_rxon(priv);

/* RXON Timing */
- memset(&priv->rxon_timing, 0, sizeof(struct iwl4965_rxon_time_cmd));
- iwl4965_setup_rxon_timing(priv);
+ iwl_setup_rxon_timing(priv);
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (ret)
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index fc467c5..ba54613 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -482,11 +482,6 @@ struct iwl_alive_resp {
} __attribute__ ((packed));


-union tsf {
- u8 byte[8];
- __le16 word[4];
- __le32 dw[2];
-};

/*
* REPLY_ERROR = 0x2 (response only, not a command)
@@ -497,7 +492,7 @@ struct iwl_error_resp {
u8 reserved1;
__le16 bad_cmd_seq_num;
__le32 error_info;
- union tsf timestamp;
+ __le64 timestamp;
} __attribute__ ((packed));

/******************************************************************************
@@ -684,8 +679,8 @@ struct iwl4965_rxon_assoc_cmd {
/*
* REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
*/
-struct iwl4965_rxon_time_cmd {
- union tsf timestamp;
+struct iwl_rxon_time_cmd {
+ __le64 timestamp;
__le16 beacon_interval;
__le16 atim_window;
__le32 beacon_init_val;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 2125844..34306b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -275,7 +275,6 @@ struct iwl_cmd {
u16 val16;
u32 val32;
struct iwl4965_bt_cmd bt;
- struct iwl4965_rxon_time_cmd rxon_time;
struct iwl_powertable_cmd powertable;
struct iwl_qosparam_cmd qosparam;
struct iwl_tx_cmd tx;
@@ -851,7 +850,7 @@ struct iwl_priv {
u8 ucode_write_complete; /* the image write is complete */


- struct iwl4965_rxon_time_cmd rxon_timing;
+ struct iwl_rxon_time_cmd rxon_timing;

/* We declare this const so it can only be
* changed via explicit cast within the
--
1.5.3.6


2008-10-06 08:11:51

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 2/7] iwlwifi: fix ct kill configuration for 5350

From: Tomas Winkler <[email protected]>

This patch fixes ct kill configuration for 5350.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index ba92667..c1300fb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -830,12 +830,12 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
case CSR_HW_REV_TYPE_5100:
case CSR_HW_REV_TYPE_5300:
- /* 5X00 wants in Celsius */
+ case CSR_HW_REV_TYPE_5350:
+ /* 5X00 and 5350 wants in Celsius */
priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
break;
case CSR_HW_REV_TYPE_5150:
- case CSR_HW_REV_TYPE_5350:
- /* 5X50 wants in Kelvin */
+ /* 5150 wants in Kelvin */
priv->hw_params.ct_kill_threshold =
CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
break;
--
1.5.3.6


2008-10-06 08:12:04

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 5/7] iwlwifi: take a valid antenna upon rate scale init

From: Tomas Winkler <[email protected]>

This patch selects a valid antenna upon RS init. This solves a SYSASSERT
complaining that the driver is setting a non valid antenna in the LQ CMD.

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-5000.c | 6 +++++-
drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 10 ++++++++++
drivers/net/wireless/iwlwifi/iwl-sta.c | 8 +++++---
3 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index c1300fb..56a3f0c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -811,10 +811,14 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)

switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
case CSR_HW_REV_TYPE_5100:
+ priv->hw_params.tx_chains_num = 1;
+ priv->hw_params.rx_chains_num = 2;
+ priv->hw_params.valid_tx_ant = ANT_B;
+ priv->hw_params.valid_rx_ant = ANT_AB;
+ break;
case CSR_HW_REV_TYPE_5150:
priv->hw_params.tx_chains_num = 1;
priv->hw_params.rx_chains_num = 2;
- /* FIXME: move to ANT_A, ANT_B, ANT_C enum */
priv->hw_params.valid_tx_ant = ANT_A;
priv->hw_params.valid_rx_ant = ANT_AB;
break;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index d148d73..bac91f1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -284,6 +284,16 @@ static inline u8 num_of_ant(u8 mask)
!!((mask) & ANT_C);
}

+static inline u8 first_antenna(u8 mask)
+{
+ if (mask & ANT_A)
+ return ANT_A;
+ if (mask & ANT_B)
+ return ANT_B;
+ return ANT_C;
+}
+
+
static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
{
u8 rate = iwl_rates[rate_index].prev_ieee;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 61797f3..f9efc0c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -852,7 +852,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
struct iwl_link_quality_cmd link_cmd = {
.reserved1 = 0,
};
- u16 rate_flags;
+ u32 rate_flags;

/* Set up the rate scaling to start at selected rate, fall back
* all the way down to 1M in IEEE order, and then spin on 1M */
@@ -869,14 +869,16 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
rate_flags |= RATE_MCS_CCK_MSK;

/* Use Tx antenna B only */
- rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/
+ rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
+ RATE_MCS_ANT_POS;

link_cmd.rs_table[i].rate_n_flags =
iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
r = iwl4965_get_prev_ieee_rate(r);
}

- link_cmd.general_params.single_stream_ant_msk = 2;
+ link_cmd.general_params.single_stream_ant_msk =
+ first_antenna(priv->hw_params.valid_tx_ant);
link_cmd.general_params.dual_stream_ant_msk = 3;
link_cmd.agg_params.agg_dis_start_th = 3;
link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000);
--
1.5.3.6


2008-10-06 21:42:59

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 5/7] iwlwifi: take a valid antenna upon rate scale init

On Mon, Oct 06, 2008 at 11:39:49PM +0200, Tomas Winkler wrote:
> On Mon, Oct 6, 2008 at 11:25 PM, John W. Linville
> <[email protected]> wrote:

> >> diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
> >> index c1300fb..56a3f0c 100644
> >> --- a/drivers/net/wireless/iwlwifi/iwl-5000.c
> >> +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
> >> @@ -811,10 +811,14 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
> >>
> >> switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
> >> case CSR_HW_REV_TYPE_5100:
> >> + priv->hw_params.tx_chains_num = 1;
> >> + priv->hw_params.rx_chains_num = 2;
> >> + priv->hw_params.valid_tx_ant = ANT_B;
> >> + priv->hw_params.valid_rx_ant = ANT_AB;
> >> + break;
> >> case CSR_HW_REV_TYPE_5150:
> >> priv->hw_params.tx_chains_num = 1;
> >> priv->hw_params.rx_chains_num = 2;
> >> - /* FIXME: move to ANT_A, ANT_B, ANT_C enum */
> >> priv->hw_params.valid_tx_ant = ANT_A;
> >> priv->hw_params.valid_rx_ant = ANT_AB;
> >> break;
> >
> > Do you realize that both clauses are the same (i.e. there is no
> > functional change)? How is this useful?
>
> The change is tx_ant

Quite right.

> > You need to change the comment...
>
> Right

Thanks.

John
--
John W. Linville Linux should be at the core
[email protected] of your literate lifestyle.

2008-10-06 21:25:50

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 5/7] iwlwifi: take a valid antenna upon rate scale init

On Mon, Oct 06, 2008 at 04:05:31PM +0800, Zhu Yi wrote:
> From: Tomas Winkler <[email protected]>
>
> This patch selects a valid antenna upon RS init. This solves a SYSASSERT
> complaining that the driver is setting a non valid antenna in the LQ CMD.

I suppose this is an accurate description, but I think you can do
better. :-)

> diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
> index c1300fb..56a3f0c 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-5000.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
> @@ -811,10 +811,14 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
>
> switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
> case CSR_HW_REV_TYPE_5100:
> + priv->hw_params.tx_chains_num = 1;
> + priv->hw_params.rx_chains_num = 2;
> + priv->hw_params.valid_tx_ant = ANT_B;
> + priv->hw_params.valid_rx_ant = ANT_AB;
> + break;
> case CSR_HW_REV_TYPE_5150:
> priv->hw_params.tx_chains_num = 1;
> priv->hw_params.rx_chains_num = 2;
> - /* FIXME: move to ANT_A, ANT_B, ANT_C enum */
> priv->hw_params.valid_tx_ant = ANT_A;
> priv->hw_params.valid_rx_ant = ANT_AB;
> break;

Do you realize that both clauses are the same (i.e. there is no
functional change)? How is this useful?

> diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
> index d148d73..bac91f1 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
> +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
> @@ -284,6 +284,16 @@ static inline u8 num_of_ant(u8 mask)
> !!((mask) & ANT_C);
> }
>
> +static inline u8 first_antenna(u8 mask)
> +{
> + if (mask & ANT_A)
> + return ANT_A;
> + if (mask & ANT_B)
> + return ANT_B;
> + return ANT_C;
> +}
> +
> +
> static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
> {
> u8 rate = iwl_rates[rate_index].prev_ieee;
> diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
> index 61797f3..f9efc0c 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-sta.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
> @@ -852,7 +852,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
> struct iwl_link_quality_cmd link_cmd = {
> .reserved1 = 0,
> };
> - u16 rate_flags;
> + u32 rate_flags;
>
> /* Set up the rate scaling to start at selected rate, fall back
> * all the way down to 1M in IEEE order, and then spin on 1M */
> @@ -869,14 +869,16 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
> rate_flags |= RATE_MCS_CCK_MSK;
>
> /* Use Tx antenna B only */
> - rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/
> + rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
> + RATE_MCS_ANT_POS;

You need to change the comment...

John
--
John W. Linville Linux should be at the core
[email protected] of your literate lifestyle.