2008-06-12 01:49:28

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 00/29] iwlwifi driver 06/12 updates

Hi John,

Here are the iwlwifi updates on 06/12. Please apply.

Thanks,
-yi

[PATCH 01/29] iwlwifi: removing IWL4965_HT config
[PATCH 02/29] iwlwifi: removes the RUN_TIME_CALIB ifdef
[PATCH 03/29] iwlwifi: clean up in setup/cancel deferred work
[PATCH 04/29] iwlwifi: add possibility to disable tx_power calibration
[PATCH 05/29] iwlwifi: map sw and hw ampdu queues
[PATCH 06/29] iwlwifi: add TX aggregation code for 5000 HW
[PATCH 07/29] iwlwifi: use ieee80211_conf to examine rate capabilities
[PATCH 08/29] iwlwifi: fix allow iwlwifi to aggregate according to tid load
[PATCH 09/29] iwlwifi: remove unused flag
[PATCH 10/29] iwlwifi: remove redundant flags regarding to FAT channel
[PATCH 11/29] iwlwifi: fix bug when moving from 11gn to 11a or 11an to 11g
[PATCH 12/29] iwlwifi: format log prints for easier parsing
[PATCH 13/29] iwlwifi: fix resume SW RF-kill
[PATCH 14/29] iwlwifi: fix resart flow after fw error
[PATCH 15/29] iwlwifi enabling IBSS (Ad-Hoc) mode
[PATCH 16/29] iwlwifi: Fix mode changes (ad-hoc <--> managed)
[PATCH 17/29] iwlwifi: refactor tx aggregation response flow
[PATCH 18/29] iwlwifi: refactor setting tx power
[PATCH 19/29] iwlwifi: add bad length check for WEP keys
[PATCH 20/29] iwlwifi: move scan to iwl-scan.c iwlcore
[PATCH 21/29] iwlwifi: move rate helpers to iwlcore
[PATCH 22/29] iwlwifi: cleans up scanning code
[PATCH 23/29] iwlwifi: move iwl4965_rf_kill_ct_config to iwl-core.c
[PATCH 24/29] iwlwifi: retfactor get_temperature functions
[PATCH 25/29] iwlwifi: remove dead code iwl4965_calc_db_from_ratio
[PATCH 26/29] mac80211 : fix for iwconfig in ad-hoc mode
[PATCH 27/29] iwlwifi: fix software rf_kill problem when interface is down
[PATCH 28/29] iwlwifi: general code clean up
[PATCH 29/29] iwlwifi: remove iwlcore_low_level_notify


2008-06-12 02:16:52

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH 26/29] mac80211 : fix for iwconfig in ad-hoc mode

On Thu, 2008-06-12 at 09:47 +0800, Zhu Yi wrote:
> From: Abhijeet Kolekar <[email protected]>
>
> The patch checks interface status, if it is in IBSS_JOINED mode
> show cell id it is associated with.
>
> Signed-off-by: Abhijeet Kolekar <[email protected]>

Good catch. This is actually a regression since 2.6.25.3 where the code
didn't care about the state but was just:

if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
ap_addr->sa_family = ARPHRD_ETHER;
memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
return 0;

John, this is a good candidate for 2.6.26 as it's technically a
regression, even though impact is probably low.

Dan

> net/mac80211/wext.c | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
> index 4806d96..5af3862 100644
> --- a/net/mac80211/wext.c
> +++ b/net/mac80211/wext.c
> @@ -508,7 +508,8 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
> sdata = IEEE80211_DEV_TO_SUB_IF(dev);
> if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
> sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
> - if (sdata->u.sta.state == IEEE80211_ASSOCIATED) {
> + if (sdata->u.sta.state == IEEE80211_ASSOCIATED ||
> + sdata->u.sta.state == IEEE80211_IBSS_JOINED) {
> ap_addr->sa_family = ARPHRD_ETHER;
> memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
> return 0;


2008-06-12 01:49:31

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 03/29] iwlwifi: clean up in setup/cancel deferred work

From: Emmanuel Grumbach <[email protected]>

This patch makes some clean up in setup/cancel_deferred_work.
iwl_setup_deferred_work does the work that is common to 4965
and 5000, then it calls to HW specific handlers.

This patch also removes uneeded work_struct from iwl_priv.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 33 +++------------------
drivers/net/wireless/iwlwifi/iwl-core.h | 4 ++
drivers/net/wireless/iwlwifi/iwl-dev.h | 3 --
drivers/net/wireless/iwlwifi/iwl4965-base.c | 41 ++++++++++++++++++++++----
4 files changed, 43 insertions(+), 38 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index e2c2d9f..be6b6eb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -608,26 +608,6 @@ out:

#define REG_RECALIB_PERIOD (60)

-/**
- * iwl4965_bg_statistics_periodic - Timer callback to queue statistics
- *
- * This callback is provided in order to send a statistics request.
- *
- * This timer function is continually reset to execute within
- * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION
- * was received. We need to ensure we receive the statistics in order
- * to update the temperature used for calibrating the TXPOWER.
- */
-static void iwl4965_bg_statistics_periodic(unsigned long data)
-{
- struct iwl_priv *priv = (struct iwl_priv *)data;
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- iwl_send_statistics_request(priv, CMD_ASYNC);
-}
-
void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)
{
struct iwl4965_ct_kill_config cmd;
@@ -3469,19 +3449,14 @@ static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba;
}

-void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv)
+static void iwl4965_setup_deferred_work(struct iwl_priv *priv)
{
INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work);
- init_timer(&priv->statistics_periodic);
- priv->statistics_periodic.data = (unsigned long)priv;
- priv->statistics_periodic.function = iwl4965_bg_statistics_periodic;
}

-void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv)
+static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
{
- del_timer_sync(&priv->statistics_periodic);
-
- cancel_delayed_work(&priv->init_alive_start);
+ cancel_work_sync(&priv->txpower_work);
}


@@ -3506,6 +3481,8 @@ static struct iwl_lib_ops iwl4965_lib = {
.txq_agg_enable = iwl4965_txq_agg_enable,
.txq_agg_disable = iwl4965_txq_agg_disable,
.rx_handler_setup = iwl4965_rx_handler_setup,
+ .setup_deferred_work = iwl4965_setup_deferred_work,
+ .cancel_deferred_work = iwl4965_cancel_deferred_work,
.is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr,
.alive_notify = iwl4965_alive_notify,
.init_alive_start = iwl4965_init_alive_start,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 192cda2..a86e08b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -116,6 +116,10 @@ struct iwl_lib_ops {
u8 tx_fifo);
/* setup Rx handler */
void (*rx_handler_setup)(struct iwl_priv *priv);
+ /* setup deferred work */
+ void (*setup_deferred_work)(struct iwl_priv *priv);
+ /* cancel deferred work */
+ void (*cancel_deferred_work)(struct iwl_priv *priv);
/* alive notification after init uCode load */
void (*init_alive_start)(struct iwl_priv *priv);
/* alive notification */
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 631931c..9e5a7cd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1179,9 +1179,6 @@ struct iwl_priv {

struct delayed_work init_alive_start;
struct delayed_work alive_start;
- struct delayed_work activity_timer;
- struct delayed_work thermal_periodic;
- struct delayed_work gather_stats;
struct delayed_work scan_check;
struct delayed_work post_associate;

diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index a8dfdcb..0acd42b 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1647,6 +1647,26 @@ static void iwl4965_bg_beacon_update(struct work_struct *work)
iwl4965_send_beacon_cmd(priv);
}

+/**
+ * iwl4965_bg_statistics_periodic - Timer callback to queue statistics
+ *
+ * This callback is provided in order to send a statistics request.
+ *
+ * This timer function is continually reset to execute within
+ * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION
+ * was received. We need to ensure we receive the statistics in order
+ * to update the temperature used for calibrating the TXPOWER.
+ */
+static void iwl4965_bg_statistics_periodic(unsigned long data)
+{
+ struct iwl_priv *priv = (struct iwl_priv *)data;
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ iwl_send_statistics_request(priv, CMD_ASYNC);
+}
+
static void iwl4965_rx_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
@@ -2887,7 +2907,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
queue_work(priv->workqueue, &priv->restart);
}

-static void iwl4965_cancel_deferred_work(struct iwl_priv *priv);
+static void iwl_cancel_deferred_work(struct iwl_priv *priv);

static void __iwl4965_down(struct iwl_priv *priv)
{
@@ -2991,7 +3011,7 @@ static void iwl4965_down(struct iwl_priv *priv)
__iwl4965_down(priv);
mutex_unlock(&priv->mutex);

- iwl4965_cancel_deferred_work(priv);
+ iwl_cancel_deferred_work(priv);
}

#define MAX_HW_RESTARTS 5
@@ -5022,7 +5042,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
*
*****************************************************************************/

-static void iwl4965_setup_deferred_work(struct iwl_priv *priv)
+static void iwl_setup_deferred_work(struct iwl_priv *priv)
{
priv->workqueue = create_workqueue(DRV_NAME);

@@ -5043,21 +5063,28 @@ static void iwl4965_setup_deferred_work(struct iwl_priv *priv)
INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
INIT_DELAYED_WORK(&priv->scan_check, iwl4965_bg_scan_check);

- iwl4965_hw_setup_deferred_work(priv);
+ if (priv->cfg->ops->lib->setup_deferred_work)
+ priv->cfg->ops->lib->setup_deferred_work(priv);
+
+ init_timer(&priv->statistics_periodic);
+ priv->statistics_periodic.data = (unsigned long)priv;
+ priv->statistics_periodic.function = iwl4965_bg_statistics_periodic;

tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
iwl4965_irq_tasklet, (unsigned long)priv);
}

-static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
+static void iwl_cancel_deferred_work(struct iwl_priv *priv)
{
- iwl4965_hw_cancel_deferred_work(priv);
+ if (priv->cfg->ops->lib->cancel_deferred_work)
+ priv->cfg->ops->lib->cancel_deferred_work(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);
+ del_timer_sync(&priv->statistics_periodic);
}

static struct attribute *iwl4965_sysfs_entries[] = {
@@ -5269,7 +5296,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
}


- iwl4965_setup_deferred_work(priv);
+ iwl_setup_deferred_work(priv);
iwl4965_setup_rx_handlers(priv);

/********************
--
1.5.3.6


2008-06-12 01:50:06

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 28/29] iwlwifi: general code clean up

From: Emmanuel Grumbach <[email protected]>

This patch cleans up iwlwifi's code: Add missing include, remove empty
lines etc...

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 1 +
drivers/net/wireless/iwlwifi/iwl-4965.c | 4 +-
drivers/net/wireless/iwlwifi/iwl-calib.c | 2 -
drivers/net/wireless/iwlwifi/iwl-calib.h | 9 +---
drivers/net/wireless/iwlwifi/iwl-dev.h | 62 +--------------------------
drivers/net/wireless/iwlwifi/iwl-sta.c | 23 ++++++----
drivers/net/wireless/iwlwifi/iwl-sta.h | 16 +++++--
7 files changed, 32 insertions(+), 85 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index b9a4e4b..d601d31 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -38,6 +38,7 @@
#include "../net/mac80211/rate.h"

#include "iwl-dev.h"
+#include "iwl-sta.h"
#include "iwl-core.h"
#include "iwl-helpers.h"

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 6e6038f..9662fae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -722,7 +722,7 @@ static const u16 default_queue_to_tx_fifo[] = {
IWL_TX_FIFO_HCCA_2
};

-int iwl4965_alive_notify(struct iwl_priv *priv)
+static int iwl4965_alive_notify(struct iwl_priv *priv)
{
u32 a;
int i = 0;
@@ -827,7 +827,7 @@ static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
*
* Called when initializing driver
*/
-int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
+static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
{

if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 72242a4..48f5800 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -60,13 +60,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/

-#include <linux/kernel.h>
#include <net/mac80211.h>

#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-calib.h"
-#include "iwl-eeprom.h"

/* "false alarms" are signals that our DSP tries to lock onto,
* but then determines that they are either noise, or transmissions
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
index 45f37cb..5524a29 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.h
@@ -62,14 +62,9 @@
#ifndef __iwl_calib_h__
#define __iwl_calib_h__

-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/version.h>
-
-#include <net/mac80211.h>
-#include "iwl-eeprom.h"
-#include "iwl-core.h"
#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-commands.h"

void iwl_chain_noise_calibration(struct iwl_priv *priv,
struct iwl4965_notif_statistics *stat_resp);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 7001854..e6188f0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -29,8 +29,8 @@
* Please use iwl-4965-hw.h for hardware-related definitions.
*/

-#ifndef __iwl_4965_h__
-#define __iwl_4965_h__
+#ifndef __iwl_dev_h__
+#define __iwl_dev_h__

#include <linux/pci.h> /* for struct pci_device_id */
#include <linux/kernel.h>
@@ -593,15 +593,8 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
u8 flags, struct ieee80211_ht_info *ht_info);
extern int iwl4965_is_network_packet(struct iwl_priv *priv,
struct ieee80211_hdr *header);
-extern int iwl4965_power_init_handle(struct iwl_priv *priv);
-extern void iwl4965_handle_data_packet_monitor(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb,
- void *data, short len,
- struct ieee80211_rx_status *stats,
- u16 phy_flags);
extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv,
struct ieee80211_hdr *header);
-extern int iwl4965_calc_db_from_ratio(int sig_ratio);
extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm);
extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,
@@ -609,18 +602,7 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);

-int iwl4965_init_geos(struct iwl_priv *priv);
-void iwl4965_free_geos(struct iwl_priv *priv);
-
extern const u8 iwl_bcast_addr[ETH_ALEN];
-int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
-
-/*
- * Currently used by iwl-3945-rs... look at restructuring so that it doesn't
- * call this... todo... fix that.
-*/
-extern u8 iwl4965_sync_station(struct iwl_priv *priv, int sta_id,
- u16 tx_rate, u8 flags);

/******************************************************************************
*
@@ -638,35 +620,16 @@ extern u8 iwl4965_sync_station(struct iwl_priv *priv, int sta_id,
* iwl4965_mac_ <-- mac80211 callback
*
****************************************************************************/
-extern void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv);
-extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv);
-extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv);
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_hw_build_tx_cmd_rate(struct iwl_priv *priv,
- struct iwl_cmd *cmd,
- struct ieee80211_tx_info *info,
- struct ieee80211_hdr *hdr,
- int sta_id, int tx_id);
extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
extern void iwl4965_disable_events(struct iwl_priv *priv);
-extern int iwl4965_get_temperature(const struct iwl_priv *priv);
extern void iwl4965_rx_reply_rx(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);

-/**
- * iwl_find_station - Find station id for a given BSSID
- * @bssid: MAC address of station ID to find
- *
- * NOTE: This should not be hardware specific but the code has
- * not yet been merged into a single common layer for managing the
- * station tables.
- */
-extern u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid);
-
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)
@@ -694,16 +657,8 @@ extern int iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio);
/*
* Forward declare iwl-4965.c functions for iwl-base.c
*/
-extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv,
- struct iwl_tx_queue *txq,
- u16 byte_cnt);
-extern int iwl4965_alive_notify(struct iwl_priv *priv);
-extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode);
extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);

-extern void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,
- struct ieee80211_ht_info *ht_info,
- enum ieee80211_band band);
int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
const u8 *addr, u16 tid, u16 *ssn);
@@ -1174,17 +1129,6 @@ static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
#endif


-static inline int iwl_get_ra_sta_id(struct iwl_priv *priv,
- struct ieee80211_hdr *hdr)
-{
- if (priv->iw_mode == IEEE80211_IF_TYPE_STA) {
- return IWL_AP_ID;
- } else {
- u8 *da = ieee80211_get_DA(hdr);
- return iwl_find_station(priv, da);
- }
-}
-
static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv,
int txq_id, int idx)
{
@@ -1254,4 +1198,4 @@ extern const struct iwl_channel_info *iwl_get_channel_info(

/* Requires full declaration of iwl_priv before including */

-#endif /* __iwl4965_4965_h__ */
+#endif /* __iwl_dev_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index fae5d6d..f874e7d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -30,11 +30,9 @@
#include <net/mac80211.h>
#include <linux/etherdevice.h>

-#include "iwl-eeprom.h"
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-sta.h"
-#include "iwl-io.h"
#include "iwl-helpers.h"


@@ -74,6 +72,17 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
}
EXPORT_SYMBOL(iwl_find_station);

+int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
+{
+ if (priv->iw_mode == IEEE80211_IF_TYPE_STA) {
+ return IWL_AP_ID;
+ } else {
+ u8 *da = ieee80211_get_DA(hdr);
+ return iwl_find_station(priv, da);
+ }
+}
+EXPORT_SYMBOL(iwl_get_ra_sta_id);
+
static int iwl_add_sta_callback(struct iwl_priv *priv,
struct iwl_cmd *cmd, struct sk_buff *skb)
{
@@ -105,8 +114,6 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
return 1;
}

-
-
int iwl_send_add_sta(struct iwl_priv *priv,
struct iwl_addsta_cmd *sta, u8 flags)
{
@@ -272,7 +279,6 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
}
EXPORT_SYMBOL(iwl_add_station_flags);

-
static int iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
{
unsigned long flags;
@@ -376,9 +382,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,

return ret;
}
+
/**
* iwl_remove_station - Remove driver's knowledge of station.
- *
*/
u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
{
@@ -418,7 +424,7 @@ out:
return 0;
}
EXPORT_SYMBOL(iwl_remove_station);
-int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
+static int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
int i;

@@ -869,7 +875,6 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
}
EXPORT_SYMBOL(iwl_rxon_add_station);

-
/**
* iwl_get_sta_id - Find station's index within station table
*
@@ -927,7 +932,6 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
}
EXPORT_SYMBOL(iwl_get_sta_id);

-
/**
* iwl_sta_modify_enable_tid_tx - Enable Tx for this TID in station table
*/
@@ -946,4 +950,3 @@ void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid)
}
EXPORT_SYMBOL(iwl_sta_modify_enable_tid_tx);

-
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 3d55716..b6bb209 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -32,18 +32,24 @@
#define HW_KEY_DYNAMIC 0
#define HW_KEY_DEFAULT 1

-int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
+/**
+ * iwl_find_station - Find station id for a given BSSID
+ * @bssid: MAC address of station ID to find
+ */
+u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid);
+
int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty);
int iwl_remove_default_wep_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key);
+ struct ieee80211_key_conf *key);
int iwl_set_default_wep_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key);
+ struct ieee80211_key_conf *key);
int iwl_set_dynamic_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key, u8 sta_id);
+ struct ieee80211_key_conf *key, u8 sta_id);
int iwl_remove_dynamic_key(struct iwl_priv *priv,
- struct ieee80211_key_conf *key, u8 sta_id);
+ struct ieee80211_key_conf *key, u8 sta_id);
int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid);
+int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
#endif /* __iwl_sta_h__ */
--
1.5.3.6


2008-06-12 01:49:54

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 19/29] iwlwifi: add bad length check for WEP keys

From: Emmanuel Grumbach <[email protected]>

This patch adds a check for bad length in set key flow. This solves the
Oops reported by Thomas Backlund, Joonwoo Park and Ian Schram.
It also adds some debug printing that can be useful.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-commands.h | 1 +
drivers/net/wireless/iwlwifi/iwl-sta.c | 18 +++++++++++++++++-
2 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index a093f5b..b58f796 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1002,6 +1002,7 @@ struct iwl_wep_cmd {
#define WEP_KEY_WEP_TYPE 1
#define WEP_KEYS_MAX 4
#define WEP_INVALID_OFFSET 0xff
+#define WEP_KEY_LEN_64 5
#define WEP_KEY_LEN_128 13

/******************************************************************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index b3caed4..3e257cf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -488,6 +488,8 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
priv->default_wep_key--;
memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
ret = iwl_send_static_wepkey_cmd(priv, 1);
+ IWL_DEBUG_WEP("Remove default WEP key: idx=%d ret=%d\n",
+ keyconf->keyidx, ret);
spin_unlock_irqrestore(&priv->sta_lock, flags);

return ret;
@@ -500,6 +502,12 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
int ret;
unsigned long flags;

+ if (keyconf->keylen != WEP_KEY_LEN_128 &&
+ keyconf->keylen != WEP_KEY_LEN_64) {
+ IWL_DEBUG_WEP("Bad WEP key length %d\n", keyconf->keylen);
+ return -EINVAL;
+ }
+
keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
keyconf->hw_key_idx = HW_KEY_DEFAULT;
priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP;
@@ -516,6 +524,8 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
keyconf->keylen);

ret = iwl_send_static_wepkey_cmd(priv, 0);
+ IWL_DEBUG_WEP("Set default WEP key: len=%d idx=%d ret=%d\n",
+ keyconf->keylen, keyconf->keyidx, ret);
spin_unlock_irqrestore(&priv->sta_lock, flags);

return ret;
@@ -662,6 +672,9 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;

+ IWL_DEBUG_WEP("Remove dynamic key: idx=%d sta=%d\n",
+ keyconf->keyidx, sta_id);
+
if (keyconf->keyidx != keyidx) {
/* We need to remove a key with index different that the one
* in the uCode. This means that the key we need to remove has
@@ -686,7 +699,6 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;

- IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
spin_unlock_irqrestore(&priv->sta_lock, flags);
return ret;
@@ -716,6 +728,10 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
ret = -EINVAL;
}

+ IWL_DEBUG_WEP("Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
+ keyconf->alg, keyconf->keylen, keyconf->keyidx,
+ sta_id, ret);
+
return ret;
}
EXPORT_SYMBOL(iwl_set_dynamic_key);
--
1.5.3.6


2008-06-12 01:50:04

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 27/29] iwlwifi: fix software rf_kill problem when interface is down

The patch fixes the problem that software rf_kill messes up the
card status when it is disabled if the interface is down.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 72279e0..d0084bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2875,7 +2875,8 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
return;
}

- queue_work(priv->workqueue, &priv->restart);
+ if (priv->is_open)
+ queue_work(priv->workqueue, &priv->restart);
return;
}

diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 8f1ab23..5aec7d5 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -970,7 +970,8 @@ int iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
return 0;
}

- queue_work(priv->workqueue, &priv->restart);
+ if (priv->is_open)
+ queue_work(priv->workqueue, &priv->restart);
return 1;
}

--
1.5.3.6


2008-06-12 05:15:26

by Harvey Harrison

[permalink] [raw]
Subject: Re: [PATCH 00/29] iwlwifi driver 06/12 updates

On Thu, 2008-06-12 at 09:46 +0800, Zhu Yi wrote:
> Hi John,
>
> Here are the iwlwifi updates on 06/12. Please apply.
>
> Thanks,
> -yi

Since you're the one submitting the patches, shouldn't they have your
Signed-off-by as well?

Cheers,

Harvey


2008-06-12 01:49:44

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 12/29] iwlwifi: format log prints for easier parsing

From: Tomas Winkler <[email protected]>

This patch changes uCode log print to for easier parsing.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 7d0a257..21995ff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1169,12 +1169,14 @@ void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
ptr += sizeof(u32);
time = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- if (mode == 0)
- IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */
- else {
+ if (mode == 0) {
+ /* data, ev */
+ IWL_ERROR("EVT_LOG:0x%08x:%04u\n", time, ev);
+ } else {
data = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
- IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev);
+ IWL_ERROR("EVT_LOGT:%010u:0x%08x:%04u\n",
+ time, data, ev);
}
}
}
--
1.5.3.6


2008-06-12 01:49:42

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 11/29] iwlwifi: fix bug when moving from 11gn to 11a or 11an to 11g

From: Emmanuel Grumbach <[email protected]>

It is wrong to set the rxon channel according to the ht-channel
in case there is a mismatch (e.g. when there is no ht).

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index fad26f7..7d0a257 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -597,7 +597,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
IWL_DEBUG_ASSOC("control diff than current %d %d\n",
le16_to_cpu(rxon->channel),
ht_info->control_channel);
- rxon->channel = cpu_to_le16(ht_info->control_channel);
return;
}

diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index daa14d9..ac68cce 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -742,8 +742,6 @@ extern void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv,
extern void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,
struct ieee80211_ht_info *ht_info,
enum ieee80211_band band);
-void iwl4965_set_rxon_ht(struct iwl_priv *priv,
- struct iwl_ht_info *ht_info);
int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
const u8 *addr, u16 tid, u16 *ssn);
--
1.5.3.6


2008-06-12 05:26:44

by Zhu Yi

[permalink] [raw]
Subject: Re: [PATCH 00/29] iwlwifi driver 06/12 updates

On Wed, 2008-06-11 at 22:15 -0700, Harvey Harrison wrote:
>
> Since you're the one submitting the patches, shouldn't they have your
> Signed-off-by as well?

You're right. Will do it next time.

Thanks,
-yi


2008-06-12 01:50:02

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 25/29] iwlwifi: remove dead code iwl4965_calc_db_from_ratio

From: Emmanuel Grumbach <[email protected]>

This patch removes iwl4965_calc_db_from_ratio which is dead code.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl4965-base.c | 36 ---------------------------
1 files changed, 0 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 14d4432..8f1ab23 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1597,42 +1597,6 @@ void iwl_rx_handle(struct iwl_priv *priv)
priv->rxq.read = i;
iwl_rx_queue_restock(priv);
}
-/* Convert linear signal-to-noise ratio into dB */
-static u8 ratio2dB[100] = {
-/* 0 1 2 3 4 5 6 7 8 9 */
- 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */
- 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */
- 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */
- 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */
- 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */
- 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */
- 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */
- 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */
- 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */
- 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */
-};
-
-/* Calculates a relative dB value from a ratio of linear
- * (i.e. not dB) signal levels.
- * Conversion assumes that levels are voltages (20*log), not powers (10*log). */
-int iwl4965_calc_db_from_ratio(int sig_ratio)
-{
- /* 1000:1 or higher just report as 60 dB */
- if (sig_ratio >= 1000)
- return 60;
-
- /* 100:1 or higher, divide by 10 and use table,
- * add 20 dB to make up for divide by 10 */
- if (sig_ratio >= 100)
- return (20 + (int)ratio2dB[sig_ratio/10]);
-
- /* We shouldn't see this */
- if (sig_ratio < 1)
- return 0;
-
- /* Use table for ratios 1:1 - 99:1 */
- return (int)ratio2dB[sig_ratio];
-}

#define PERFECT_RSSI (-20) /* dBm */
#define WORST_RSSI (-95) /* dBm */
--
1.5.3.6


2008-06-12 01:49:36

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 06/29] iwlwifi: add TX aggregation code for 5000 HW

From: Tomas Winkler <[email protected]>

This patch adds TX aggregation handler for 5000 HW.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 0ae5421..d3c0e10 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -41,6 +41,7 @@
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h"
+#include "iwl-sta.h"
#include "iwl-helpers.h"
#include "iwl-5000-hw.h"

@@ -976,6 +977,135 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
}
}

+static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
+ u16 txq_id)
+{
+ u32 tbl_dw_addr;
+ u32 tbl_dw;
+ u16 scd_q2ratid;
+
+ scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
+
+ tbl_dw_addr = priv->scd_base_addr +
+ IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
+
+ tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
+
+ if (txq_id & 0x1)
+ tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
+ else
+ tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
+
+ iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
+
+ return 0;
+}
+static void iwl5000_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
+{
+ /* Simply stop the queue, but don't change any configuration;
+ * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
+ iwl_write_prph(priv,
+ IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
+ (0 << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
+ (1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
+}
+
+static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
+ int tx_fifo, int sta_id, int tid, u16 ssn_idx)
+{
+ unsigned long flags;
+ int ret;
+ u16 ra_tid;
+
+ if (IWL50_FIRST_AMPDU_QUEUE > txq_id)
+ IWL_WARNING("queue number too small: %d, must be > %d\n",
+ txq_id, IWL50_FIRST_AMPDU_QUEUE);
+
+ ra_tid = BUILD_RAxTID(sta_id, tid);
+
+ /* Modify device's station table to Tx this TID */
+ iwl_sta_modify_enable_tid_tx(priv, sta_id, tid);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
+ }
+
+ /* Stop this Tx queue before configuring it */
+ iwl5000_tx_queue_stop_scheduler(priv, txq_id);
+
+ /* Map receiver-address / traffic-ID to this queue */
+ iwl5000_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
+
+ /* Set this queue as a chain-building queue */
+ iwl_set_bits_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, (1<<txq_id));
+
+ /* enable aggregations for the queue */
+ iwl_set_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1<<txq_id));
+
+ /* Place first TFD at index corresponding to start sequence number.
+ * Assumes that ssn_idx is valid (!= 0xFFF) */
+ priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
+ priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
+ iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);
+
+ /* Set up Tx window size and frame limit for this queue */
+ iwl_write_targ_mem(priv, priv->scd_base_addr +
+ IWL50_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
+ sizeof(u32),
+ ((SCD_WIN_SIZE <<
+ IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
+ IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
+ ((SCD_FRAME_LIMIT <<
+ IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
+ IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
+
+ iwl_set_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
+
+ /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
+ iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
+ u16 ssn_idx, u8 tx_fifo)
+{
+ int ret;
+
+ if (IWL50_FIRST_AMPDU_QUEUE > txq_id) {
+ IWL_WARNING("queue number too small: %d, must be > %d\n",
+ txq_id, IWL50_FIRST_AMPDU_QUEUE);
+ return -EINVAL;
+ }
+
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ return ret;
+
+ iwl5000_tx_queue_stop_scheduler(priv, txq_id);
+
+ iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id));
+
+ priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
+ priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
+ /* supposes that ssn_idx is valid (!= 0xFFF) */
+ iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);
+
+ iwl_clear_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
+ iwl_txq_ctx_deactivate(priv, txq_id);
+ iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
+
+ iwl_release_nic_access(priv);
+
+ return 0;
+}
+
static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
{
u16 size = (u16)sizeof(struct iwl_addsta_cmd);
@@ -1319,6 +1449,8 @@ static struct iwl_lib_ops iwl5000_lib = {
.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwl5000_txq_set_sched,
+ .txq_agg_enable = iwl5000_txq_agg_enable,
+ .txq_agg_disable = iwl5000_txq_agg_disable,
.rx_handler_setup = iwl5000_rx_handler_setup,
.setup_deferred_work = iwl5000_setup_deferred_work,
.is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
--
1.5.3.6


2008-06-12 01:49:34

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 05/29] iwlwifi: map sw and hw ampdu queues

From: Ron Rindjunsky <[email protected]>

This patch maps sw and hw queues (for aggregations), so the right
mac80211 queue will be waken when ieee80211_wake_queue is invoked.

Signed-off-by: Ron Rindjunsky <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-4965.c | 17 +++++++++--------
drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-5000.c | 3 ++-
drivers/net/wireless/iwlwifi/iwl-dev.h | 2 ++
5 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index fc11833..721f505 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -82,7 +82,7 @@
*/
#define IWL_CMD_QUEUE_NUM 4
#define IWL_CMD_FIFO_NUM 4
-#define IWL_BACK_QUEUE_FIRST_ID 7
+#define IWL49_FIRST_AMPDU_QUEUE 7

/* Tx rates */
#define IWL_CCK_RATES 4
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 6d249bb..4d47dd7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -913,6 +913,7 @@ int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
}

priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
+ priv->hw_params.first_ampdu_q = IWL49_FIRST_AMPDU_QUEUE;
priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto;
priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
@@ -2893,7 +2894,7 @@ static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv,
}

/**
- * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID
+ * txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE
* priv->lock must be held by the caller
*/
static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
@@ -2901,9 +2902,9 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
{
int ret = 0;

- if (IWL_BACK_QUEUE_FIRST_ID > txq_id) {
+ if (IWL49_FIRST_AMPDU_QUEUE > txq_id) {
IWL_WARNING("queue number too small: %d, must be > %d\n",
- txq_id, IWL_BACK_QUEUE_FIRST_ID);
+ txq_id, IWL49_FIRST_AMPDU_QUEUE);
return -EINVAL;
}

@@ -2991,7 +2992,7 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv,
if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
/* calculate mac80211 ampdu sw queue to wake */
int ampdu_q =
- scd_flow - IWL_BACK_QUEUE_FIRST_ID + priv->hw->queues;
+ scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues;
int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
priv->stations[ba_resp->sta_id].
tid[ba_resp->tid].tfds_in_queue -= freed;
@@ -3036,7 +3037,7 @@ static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
/**
* iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue
*
- * NOTE: txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID,
+ * NOTE: txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE,
* i.e. it must be one of the higher queues used for aggregation
*/
static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
@@ -3046,9 +3047,9 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
int ret;
u16 ra_tid;

- if (IWL_BACK_QUEUE_FIRST_ID > txq_id)
+ if (IWL49_FIRST_AMPDU_QUEUE > txq_id)
IWL_WARNING("queue number too small: %d, must be > %d\n",
- txq_id, IWL_BACK_QUEUE_FIRST_ID);
+ txq_id, IWL49_FIRST_AMPDU_QUEUE);

ra_tid = BUILD_RAxTID(sta_id, tid);

@@ -3398,7 +3399,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
txq_id >= 0 && priv->mac80211_registered &&
agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) {
/* calculate mac80211 ampdu sw queue to wake */
- ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID +
+ ampdu_q = txq_id - IWL49_FIRST_AMPDU_QUEUE +
priv->hw->queues;
if (agg->state == IWL_AGG_OFF)
ieee80211_wake_queue(priv->hw, txq_id);
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
index 9e557ce..4efe0c0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
@@ -81,7 +81,7 @@
#define IWL50_QUEUE_SIZE 256
#define IWL50_CMD_FIFO_NUM 7
#define IWL50_NUM_QUEUES 20
-#define IWL50_BACK_QUEUE_FIRST_ID 10
+#define IWL50_FIRST_AMPDU_QUEUE 10

#define IWL_sta_id_POS 12
#define IWL_sta_id_LEN 4
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 31ea363..0ae5421 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -825,6 +825,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
}

priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
+ priv->hw_params.first_ampdu_q = IWL50_FIRST_AMPDU_QUEUE;
priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto;
priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
@@ -1183,7 +1184,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
txq_id >= 0 && priv->mac80211_registered &&
agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) {
/* calculate mac80211 ampdu sw queue to wake */
- ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID +
+ ampdu_q = txq_id - IWL50_FIRST_AMPDU_QUEUE +
priv->hw->queues;
if (agg->state == IWL_AGG_OFF)
ieee80211_wake_queue(priv->hw, txq_id);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index bf4b883..fa35193 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -583,6 +583,7 @@ struct iwl_sensitivity_ranges {
* @max_xxx_size: for ucode uses
* @ct_kill_threshold: temperature threshold
* @struct iwl_sensitivity_ranges: range of sensitivity values
+ * @first_ampdu_q: first HW queue available for ampdu
*/
struct iwl_hw_params {
u16 max_txq_num;
@@ -603,6 +604,7 @@ struct iwl_hw_params {
u32 max_bsm_size;
u32 ct_kill_threshold; /* value in hw-dependent units */
const struct iwl_sensitivity_ranges *sens;
+ u8 first_ampdu_q;
};

#define HT_SHORT_GI_20MHZ (1 << 0)
--
1.5.3.6


2008-06-12 01:49:48

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 15/29] iwlwifi enabling IBSS (Ad-Hoc) mode

From: Assaf Krauss <[email protected]>

This patch enables ibss mode. It consists of two changes upon entering ibss
mode:
1. Removing the redundant line which clears the driver's station table.
This line creates a discrepancy between the driver and the FW's station
table. This prevented the generation of beacons.
2. Assigning a default value to priv's assoc_id. Normally given by an AP in
STA mode, this field is used as an indication for association. Being 0,
it prevented normal TX flow.
3. Remove a redundant ADD_STA command that cause uCode error.
4. Delay the set_mode until after the uCode is ready.

Signed-off-by: Assaf Krauss <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.h | 1 +
drivers/net/wireless/iwlwifi/iwl4965-base.c | 30 +++++++++++++++++---------
2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index b4c9d5d..44d0fcf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -284,6 +284,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv);
#define STATUS_POWER_PMI 16
#define STATUS_FW_ERROR 17
#define STATUS_CONF_PENDING 18
+#define STATUS_MODE_PENDING 19


static inline int iwl_is_ready(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 3f54dec..4570fd1 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -2900,6 +2900,10 @@ static void iwl_alive_start(struct iwl_priv *priv)

iwlcore_low_level_notify(priv, IWLCORE_START_EVT);
ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
+
+ if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
+ iwl4965_set_mode(priv, priv->iw_mode);
+
return;

restart:
@@ -3189,16 +3193,20 @@ static void iwl4965_bg_set_monitor(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work,
struct iwl_priv, set_monitor);
+ int ret;

IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n");

mutex_lock(&priv->mutex);

- if (!iwl_is_ready(priv))
- IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n");
- else
- if (iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR) != 0)
- IWL_ERROR("iwl4965_set_mode() failed\n");
+ ret = iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR);
+
+ if (ret) {
+ if (ret == -EAGAIN)
+ IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n");
+ else
+ IWL_ERROR("iwl4965_set_mode() failed ret = %d\n", ret);
+ }

mutex_unlock(&priv->mutex);
}
@@ -3575,10 +3583,9 @@ static void iwl4965_post_associate(struct iwl_priv *priv)

case IEEE80211_IF_TYPE_IBSS:

- /* clear out the station table */
- iwlcore_clear_stations_table(priv);
+ /* assume default assoc id */
+ priv->assoc_id = 1;

- iwl_rxon_add_station(priv, iwl_bcast_addr, 0);
iwl_rxon_add_station(priv, priv->bssid, 0);
iwl4965_rate_scale_init(priv->hw, IWL_STA_ID);
iwl4965_send_beacon_cmd(priv);
@@ -3826,8 +3833,9 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw,
memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
}

- if (iwl_is_ready(priv))
- iwl4965_set_mode(priv, conf->type);
+ if (iwl4965_set_mode(priv, conf->type) == -EAGAIN)
+ /* we are not ready, will run again when ready */
+ set_bit(STATUS_MODE_PENDING, &priv->status);

mutex_unlock(&priv->mutex);

@@ -4608,7 +4616,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk

iwl_reset_qos(priv);

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

mutex_unlock(&priv->mutex);

--
1.5.3.6


2008-06-12 01:50:07

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 29/29] iwlwifi: remove iwlcore_low_level_notify

From: Emmanuel Grumbach <[email protected]>

This patch removes the iwlcore_low_level_notify. The
notification chain is not required in this level.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.c | 31 ---------------------------
drivers/net/wireless/iwlwifi/iwl-core.h | 9 -------
drivers/net/wireless/iwlwifi/iwl4965-base.c | 14 ++++++------
3 files changed, 7 insertions(+), 47 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 8096463..fa17cd9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -965,37 +965,6 @@ void iwl_uninit_drv(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_uninit_drv);

-
-
-/* Low level driver call this function to update iwlcore with
- * driver status.
- */
-int iwlcore_low_level_notify(struct iwl_priv *priv,
- enum iwlcore_card_notify notify)
-{
- int ret;
- switch (notify) {
- case IWLCORE_INIT_EVT:
- ret = iwl_rfkill_init(priv);
- if (ret)
- IWL_ERROR("Unable to initialize RFKILL system. "
- "Ignoring error: %d\n", ret);
- iwl_power_initialize(priv);
- break;
- case IWLCORE_START_EVT:
- iwl_power_update_mode(priv, 1);
- break;
- case IWLCORE_STOP_EVT:
- break;
- case IWLCORE_REMOVE_EVT:
- iwl_rfkill_unregister(priv);
- break;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(iwlcore_low_level_notify);
-
int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
{
u32 stat_flags = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 054ab7c..6626665 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -359,15 +359,6 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
return iwl_is_ready(priv);
}

-enum iwlcore_card_notify {
- IWLCORE_INIT_EVT = 0,
- IWLCORE_START_EVT = 1,
- IWLCORE_STOP_EVT = 2,
- IWLCORE_REMOVE_EVT = 3,
-};
-
-int iwlcore_low_level_notify(struct iwl_priv *priv,
- enum iwlcore_card_notify notify);
extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags);
extern int iwl_verify_ucode(struct iwl_priv *priv);
extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 5aec7d5..81a1c22 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -2271,7 +2271,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
if (priv->error_recovering)
iwl4965_error_recovery(priv);

- iwlcore_low_level_notify(priv, IWLCORE_START_EVT);
+ iwl_power_update_mode(priv, 1);
ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);

if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
@@ -2297,8 +2297,6 @@ static void __iwl4965_down(struct iwl_priv *priv)

iwl_leds_unregister(priv);

- iwlcore_low_level_notify(priv, IWLCORE_STOP_EVT);
-
iwlcore_clear_stations_table(priv);

/* Unblock any waiting calls */
@@ -4460,8 +4458,11 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
if (err)
IWL_ERROR("failed to create debugfs files\n");

- /* notify iwlcore to init */
- iwlcore_low_level_notify(priv, IWLCORE_INIT_EVT);
+ err = iwl_rfkill_init(priv);
+ if (err)
+ IWL_ERROR("Unable to initialize RFKILL system. "
+ "Ignoring error: %d\n", err);
+ iwl_power_initialize(priv);
return 0;

out_remove_sysfs:
@@ -4524,8 +4525,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
}
}

- iwlcore_low_level_notify(priv, IWLCORE_REMOVE_EVT);
-
+ iwl_rfkill_unregister(priv);
iwl4965_dealloc_ucode_pci(priv);

if (priv->rxq.bd)
--
1.5.3.6


2008-06-12 01:49:50

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 16/29] iwlwifi: Fix mode changes (ad-hoc <--> managed)

From: Assaf Krauss <[email protected]>

This fix allows to move between modes (ad-hoc to managed, and vice versa).
Since mode changes can only be done while driver is down, check for ibss
support can only be made when the channel is set (afte the driver goes up).

Signed-off-by: Assaf Krauss <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl4965-base.c | 25 +++++++++++--------------
1 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 4570fd1..8e7860d 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1176,22 +1176,11 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv)

static int iwl4965_set_mode(struct iwl_priv *priv, int mode)
{
- if (mode == IEEE80211_IF_TYPE_IBSS) {
- const struct iwl_channel_info *ch_info;
-
- ch_info = iwl_get_channel_info(priv,
- priv->band,
- le16_to_cpu(priv->staging_rxon.channel));
-
- if (!ch_info || !is_channel_ibss(ch_info)) {
- IWL_ERROR("channel %d not IBSS channel\n",
- le16_to_cpu(priv->staging_rxon.channel));
- return -EINVAL;
- }
- }
-
priv->iw_mode = mode;

+ /* init channel/phymode to values given at driver init */
+ iwl_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
+
iwl4965_connection_init_rx_config(priv);
memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);

@@ -3892,6 +3881,14 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
goto out;
}

+ if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS &&
+ !is_channel_ibss(ch_info)) {
+ IWL_ERROR("channel %d in band %d not IBSS channel\n",
+ conf->channel->hw_value, conf->channel->band);
+ ret = -EINVAL;
+ goto out;
+ }
+
spin_lock_irqsave(&priv->lock, flags);

/* if we are switching from ht to 2.4 clear flags
--
1.5.3.6


2008-06-12 01:49:38

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 08/29] iwlwifi: fix allow iwlwifi to aggregate according to tid load

From: Ron Rindjunsky <[email protected]>

This fix opens back the aggregation decision path for iwlwifi.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index a928741..77884e1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -273,8 +273,8 @@ static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time)
* increment traffic load value for tid and also remove
* any old values if passed the certain time period
*/
-static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
- struct ieee80211_hdr *hdr)
+static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
+ struct ieee80211_hdr *hdr)
{
u32 curr_time = jiffies_to_msecs(jiffies);
u32 time_diff;
@@ -287,7 +287,7 @@ static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
tid = qc[0] & 0xf;
} else
- return;
+ return MAX_TID_COUNT;

tl = &lq_data->load[tid];

@@ -300,7 +300,7 @@ static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
tl->queue_count = 1;
tl->head = 0;
tl->packet_count[0] = 1;
- return;
+ return MAX_TID_COUNT;
}

time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);
@@ -317,6 +317,8 @@ static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,

if ((index + 1) > tl->queue_count)
tl->queue_count = index + 1;
+
+ return tid;
}

/*
@@ -1680,7 +1682,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
}
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;

- rs_tl_add_packet(lq_sta, hdr);
+ tid = rs_tl_add_packet(lq_sta, hdr);
+
/*
* Select rate-scale / modulation-mode table to work with in
* the rest of this function: "search" if searching for better
--
1.5.3.6


2008-06-12 01:49:33

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 04/29] iwlwifi: add possibility to disable tx_power calibration

From: Emmanuel Grumbach <[email protected]>

This patch adds the possibility to disable the tx_power calibration.
In 5000 HW, this calibration is implemented in uCode, hence, it is
disabled in driver by default.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index be6b6eb..6d249bb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2103,8 +2103,9 @@ void iwl4965_hw_rx_statistics(struct iwl_priv *priv,
priv->temperature = temp;
set_bit(STATUS_TEMPERATURE, &priv->status);

- if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
- iwl4965_is_temp_calib_needed(priv))
+ if (!priv->disable_tx_power_cal &&
+ unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
+ iwl4965_is_temp_calib_needed(priv))
queue_work(priv->workqueue, &priv->txpower_work);
}

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index fc8ad73..31ea363 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1229,6 +1229,12 @@ static u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
return len;
}

+static void iwl5000_setup_deferred_work(struct iwl_priv *priv)
+{
+ /* in 5000 the tx power calibration is done in uCode */
+ priv->disable_tx_power_cal = 1;
+}
+
static void iwl5000_rx_handler_setup(struct iwl_priv *priv)
{
/* init calibration handlers */
@@ -1313,6 +1319,7 @@ static struct iwl_lib_ops iwl5000_lib = {
.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwl5000_txq_set_sched,
.rx_handler_setup = iwl5000_rx_handler_setup,
+ .setup_deferred_work = iwl5000_setup_deferred_work,
.is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
.load_ucode = iwl5000_load_ucode,
.init_alive_start = iwl5000_init_alive_start,
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 48563a0..5838480 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -57,6 +57,7 @@ struct iwl_debugfs {
struct dir_rf_files {
struct dentry *file_disable_sensitivity;
struct dentry *file_disable_chain_noise;
+ struct dentry *file_disable_tx_power;
} dbgfs_rf_files;
u32 sram_offset;
u32 sram_len;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index da6dcb2..ed948dc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -388,6 +388,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
&priv->disable_chain_noise_cal);
+ DEBUGFS_ADD_BOOL(disable_tx_power, rf, &priv->disable_tx_power_cal);
return 0;

err:
@@ -415,6 +416,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
DEBUGFS_REMOVE(priv->dbgfs->dir_data);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
+ DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power);
DEBUGFS_REMOVE(priv->dbgfs->dir_rf);
DEBUGFS_REMOVE(priv->dbgfs->dir_drv);
kfree(priv->dbgfs);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 9e5a7cd..bf4b883 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1204,6 +1204,7 @@ struct iwl_priv {
struct work_struct txpower_work;
u32 disable_sens_cal;
u32 disable_chain_noise_cal;
+ u32 disable_tx_power_cal;
struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
}; /*iwl_priv */
--
1.5.3.6


2008-06-12 01:49:53

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 18/29] iwlwifi: refactor setting tx power

From: Tomas Winkler <[email protected]>

This patch
1. Refactors settings of tx power
2. enables iwconfig txpower <value>
3. adds 5000 HW tx power

Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 51 ++++++---------------------
drivers/net/wireless/iwlwifi/iwl-5000.c | 14 +++++++
drivers/net/wireless/iwlwifi/iwl-commands.h | 12 ++++++
drivers/net/wireless/iwlwifi/iwl-core.c | 37 +++++++++++++++++--
drivers/net/wireless/iwlwifi/iwl-core.h | 6 +++
drivers/net/wireless/iwlwifi/iwl-dev.h | 9 ++---
drivers/net/wireless/iwlwifi/iwl-eeprom.c | 12 +++---
drivers/net/wireless/iwlwifi/iwl4965-base.c | 17 ++++++---
8 files changed, 96 insertions(+), 62 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 3f24e97..1b8dc2d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -46,6 +46,8 @@
#include "iwl-calib.h"
#include "iwl-sta.h"

+static int iwl4965_send_tx_power(struct iwl_priv *priv);
+
/* module parameters */
static struct iwl_mod_params iwl4965_mod_params = {
.num_of_queues = IWL49_NUM_QUEUES,
@@ -737,7 +739,7 @@ static void iwl4965_bg_txpower_work(struct work_struct *work)
/* Regardless of if we are assocaited, we must reconfigure the
* TX power since frames can be sent on non-radar channels while
* not associated */
- iwl4965_hw_reg_send_txpower(priv);
+ iwl4965_send_tx_power(priv);

/* Update last_temperature to keep is_calib_needed from running
* when it isn't needed... */
@@ -952,11 +954,6 @@ static int iwl4965_set_power(struct iwl_priv *priv,
cmd, NULL);
return ret;
}
-int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
-{
- IWL_ERROR("TODO: Implement iwl4965_hw_reg_set_txpower!\n");
- return -EINVAL;
-}

static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)
{
@@ -1007,20 +1004,6 @@ static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage,
return comp;
}

-static const struct iwl_channel_info *
-iwl4965_get_channel_txpower_info(struct iwl_priv *priv,
- enum ieee80211_band band, u16 channel)
-{
- const struct iwl_channel_info *ch_info;
-
- ch_info = iwl_get_channel_info(priv, band, channel);
-
- if (!is_channel_valid(ch_info))
- return NULL;
-
- return ch_info;
-}
-
static s32 iwl4965_get_tx_atten_grp(u16 channel)
{
if (channel >= CALIB_IWL_TX_ATTEN_GR5_FCH &&
@@ -1444,30 +1427,17 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
s32 factory_actual_pwr[2];
s32 power_index;

- /* Sanity check requested level (dBm) */
- if (priv->user_txpower_limit < IWL_TX_POWER_TARGET_POWER_MIN) {
- IWL_WARNING("Requested user TXPOWER %d below limit.\n",
- priv->user_txpower_limit);
- return -EINVAL;
- }
- if (priv->user_txpower_limit > IWL_TX_POWER_TARGET_POWER_MAX) {
- IWL_WARNING("Requested user TXPOWER %d above limit.\n",
- priv->user_txpower_limit);
- return -EINVAL;
- }
-
/* user_txpower_limit is in dBm, convert to half-dBm (half-dB units
* are used for indexing into txpower table) */
- user_target_power = 2 * priv->user_txpower_limit;
+ user_target_power = 2 * priv->tx_power_user_lmt;

/* Get current (RXON) channel, band, width */
- ch_info =
- iwl4965_get_channel_txpower_info(priv, priv->band, channel);
-
IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band,
is_fat);

- if (!ch_info)
+ ch_info = iwl_get_channel_info(priv, priv->band, channel);
+
+ if (!is_channel_valid(ch_info))
return -EINVAL;

/* get txatten group, used to select 1) thermal txpower adjustment
@@ -1668,12 +1638,12 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
}

/**
- * iwl4965_hw_reg_send_txpower - Configure the TXPOWER level user limit
+ * iwl4965_send_tx_power - Configure the TXPOWER level user limit
*
* Uses the active RXON for channel, band, and characteristics (fat, high)
- * The power limit is taken from priv->user_txpower_limit.
+ * The power limit is taken from priv->tx_power_user_lmt.
*/
-int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv)
+static int iwl4965_send_tx_power(struct iwl_priv *priv)
{
struct iwl4965_txpowertable_cmd cmd = { 0 };
int ret;
@@ -3507,6 +3477,7 @@ static struct iwl_lib_ops iwl4965_lib = {
},
.radio_kill_sw = iwl4965_radio_kill_sw,
.set_power = iwl4965_set_power,
+ .send_tx_power = iwl4965_send_tx_power,
.update_chain_flags = iwl4965_update_chain_flags,
};

diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 2a30306..da8750b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1424,6 +1424,19 @@ static int iwl5000_send_rxon_assoc(struct iwl_priv *priv)

return ret;
}
+static int iwl5000_send_tx_power(struct iwl_priv *priv)
+{
+ struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
+
+ /* half dBm need to multiply */
+ tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
+ tx_power_cmd.flags = 0;
+ tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
+ return iwl_send_cmd_pdu_async(priv, REPLY_TX_POWER_DBM_CMD,
+ sizeof(tx_power_cmd), &tx_power_cmd,
+ NULL);
+}
+

static struct iwl_hcmd_ops iwl5000_hcmd = {
.rxon_assoc = iwl5000_send_rxon_assoc,
@@ -1452,6 +1465,7 @@ static struct iwl_lib_ops iwl5000_lib = {
.load_ucode = iwl5000_load_ucode,
.init_alive_start = iwl5000_init_alive_start,
.alive_notify = iwl5000_alive_notify,
+ .send_tx_power = iwl5000_send_tx_power,
.apm_ops = {
.init = iwl5000_apm_init,
.reset = iwl5000_apm_reset,
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 9b64a39..a093f5b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -126,6 +126,7 @@ enum {
/* Miscellaneous commands */
QUIET_NOTIFICATION = 0x96, /* not used */
REPLY_TX_PWR_TABLE_CMD = 0x97,
+ REPLY_TX_POWER_DBM_CMD = 0x98,
MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */

/* Bluetooth device coexistance config command */
@@ -339,6 +340,17 @@ struct iwl4965_tx_power_db {
struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES];
} __attribute__ ((packed));

+/**
+ * Commad REPLY_TX_POWER_DBM_CMD = 0x98
+ * struct iwl5000_tx_power_dbm_cmd
+ */
+#define IWL50_TX_POWER_AUTO 0x7f
+struct iwl5000_tx_power_dbm_cmd {
+ s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */
+ u8 flags;
+ s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */
+ u8 reserved;
+} __attribute__ ((packed));

/******************************************************************************
* (0a)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 21995ff..164697a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -480,9 +480,8 @@ static int iwlcore_init_geos(struct iwl_priv *priv)

geo_ch->flags |= ch->fat_extension_channel;

- if (ch->max_power_avg > priv->max_channel_txpower_limit)
- priv->max_channel_txpower_limit =
- ch->max_power_avg;
+ if (ch->max_power_avg > priv->tx_power_channel_lmt)
+ priv->tx_power_channel_lmt = ch->max_power_avg;
} else {
geo_ch->flags |= IEEE80211_CHAN_DISABLED;
}
@@ -832,7 +831,7 @@ int iwl_init_drv(struct iwl_priv *priv)
priv->rates_mask = IWL_RATES_MASK;
/* If power management is turned on, default to AC mode */
priv->power_mode = IWL_POWER_AC;
- priv->user_txpower_limit = IWL_DEFAULT_TX_POWER;
+ priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX;

ret = iwl_init_channel_map(priv);
if (ret) {
@@ -871,6 +870,34 @@ void iwl_free_calib_results(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_free_calib_results);

+int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
+{
+ int ret = 0;
+ if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) {
+ IWL_WARNING("Requested user TXPOWER %d below limit.\n",
+ priv->tx_power_user_lmt);
+ return -EINVAL;
+ }
+
+ if (tx_power > IWL_TX_POWER_TARGET_POWER_MAX) {
+ IWL_WARNING("Requested user TXPOWER %d above limit.\n",
+ priv->tx_power_user_lmt);
+ return -EINVAL;
+ }
+
+ if (priv->tx_power_user_lmt != tx_power)
+ force = true;
+
+ priv->tx_power_user_lmt = tx_power;
+
+ if (force && priv->cfg->ops->lib->send_tx_power)
+ ret = priv->cfg->ops->lib->send_tx_power(priv);
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_set_tx_power);
+
+
void iwl_uninit_drv(struct iwl_priv *priv)
{
iwl_free_calib_results(priv);
@@ -880,6 +907,8 @@ void iwl_uninit_drv(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_uninit_drv);

+
+
/* Low level driver call this function to update iwlcore with
* driver status.
*/
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 44d0fcf..5bae691 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -140,6 +140,7 @@ struct iwl_lib_ops {
} apm_ops;
/* power */
int (*set_power)(struct iwl_priv *priv, void *cmd);
+ int (*send_tx_power) (struct iwl_priv *priv);
void (*update_chain_flags)(struct iwl_priv *priv);
/* eeprom operations (as defined in iwl-eeprom.h) */
struct iwl_eeprom_ops eeprom_ops;
@@ -238,6 +239,11 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);

/*****************************************************
+ * TX power
+ ****************************************************/
+int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
+
+/*****************************************************
* 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 54e6ac8..b420f64 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -683,8 +683,6 @@ extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv,
struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr,
int sta_id, int tx_id);
-extern int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv);
-extern int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
extern void iwl4965_disable_events(struct iwl_priv *priv);
@@ -1167,10 +1165,9 @@ struct iwl_priv {
struct delayed_work alive_start;
struct delayed_work scan_check;
struct delayed_work post_associate;
-
-#define IWL_DEFAULT_TX_POWER 0x0F
- s8 user_txpower_limit;
- s8 max_channel_txpower_limit;
+ /* TX Power */
+ s8 tx_power_user_lmt;
+ s8 tx_power_channel_lmt;

#ifdef CONFIG_PM
u32 pm_state[16];
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index cbb812f..4a08a1b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -382,8 +382,8 @@ static int iwl_set_fat_chan_info(struct iwl_priv *priv,
if (!is_channel_valid(ch_info))
return -1;

- IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x"
- " %ddBm): Ad-Hoc %ssupported\n",
+ IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):"
+ " Ad-Hoc %ssupported\n",
ch_info->channel,
is_channel_a_band(ch_info) ?
"5.2" : "2.4",
@@ -493,8 +493,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
ch_info->min_power = 0;

- IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x"
- " %ddBm): Ad-Hoc %ssupported\n",
+ IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):"
+ " Ad-Hoc %ssupported\n",
ch_info->channel,
is_channel_a_band(ch_info) ?
"5.2" : "2.4",
@@ -515,8 +515,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
/* Set the user_txpower_limit to the highest power
* supported by any channel */
if (eeprom_ch_info[ch].max_power_avg >
- priv->user_txpower_limit)
- priv->user_txpower_limit =
+ priv->tx_power_user_lmt)
+ priv->tx_power_user_lmt =
eeprom_ch_info[ch].max_power_avg;

ch_info++;
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 510e403..af44819 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -367,9 +367,9 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv)

/* If we issue a new RXON command which required a tune then we must
* send a new TXPOWER command or we won't be able to Tx any frames */
- rc = iwl4965_hw_reg_send_txpower(priv);
+ rc = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
if (rc) {
- IWL_ERROR("Error setting Tx power (%d).\n", rc);
+ IWL_ERROR("Error sending TX power (%d).\n", rc);
return rc;
}

@@ -3637,7 +3637,7 @@ static void iwl4965_bg_scan_completed(struct work_struct *work)
struct iwl_priv *priv =
container_of(work, struct iwl_priv, scan_completed);

- IWL_DEBUG(IWL_DL_SCAN, "SCAN complete scan\n");
+ IWL_DEBUG_SCAN("SCAN complete scan\n");

if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
@@ -3650,7 +3650,7 @@ static void iwl4965_bg_scan_completed(struct work_struct *work)
/* Since setting the TXPOWER may have been deferred while
* performing the scan, fire one off */
mutex_lock(&priv->mutex);
- iwl4965_hw_reg_send_txpower(priv);
+ iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
mutex_unlock(&priv->mutex);
}

@@ -3930,6 +3930,11 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
goto out;
}

+ IWL_DEBUG_MAC80211("TX Power old=%d new=%d\n",
+ priv->tx_power_user_lmt, conf->power_level);
+
+ iwl_set_tx_power(priv, conf->power_level, false);
+
iwl4965_set_rate(priv);

if (memcmp(&priv->active_rxon,
@@ -4713,7 +4718,7 @@ static ssize_t show_tx_power(struct device *d,
struct device_attribute *attr, char *buf)
{
struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- return sprintf(buf, "%d\n", priv->user_txpower_limit);
+ return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
}

static ssize_t store_tx_power(struct device *d,
@@ -4729,7 +4734,7 @@ static ssize_t store_tx_power(struct device *d,
printk(KERN_INFO DRV_NAME
": %s is not in decimal form.\n", buf);
else
- iwl4965_hw_reg_set_txpower(priv, val);
+ iwl_set_tx_power(priv, val, false);

return count;
}
--
1.5.3.6


2008-06-12 01:49:51

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 17/29] iwlwifi: refactor tx aggregation response flow

From: Tomas Winkler <[email protected]>

This patch refactors tx aggregation respnse flow
and fixes bug revealed by tx_info to cb patch

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 23 ++++++++---------------
drivers/net/wireless/iwlwifi/iwl-5000.c | 17 ++++++-----------
drivers/net/wireless/iwlwifi/iwl-commands.h | 19 ++++---------------
drivers/net/wireless/iwlwifi/iwl4965-base.c | 2 +-
4 files changed, 19 insertions(+), 42 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 4d47dd7..3f24e97 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -3204,10 +3204,7 @@ static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)

static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
{
- __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status +
- tx_resp->frame_count);
- return le32_to_cpu(*scd_ssn) & MAX_SN;
-
+ return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
}

/**
@@ -3215,15 +3212,14 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
*/
static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
struct iwl_ht_agg *agg,
- struct iwl4965_tx_resp_agg *tx_resp,
- u16 start_idx)
+ struct iwl4965_tx_resp *tx_resp,
+ int txq_id, u16 start_idx)
{
u16 status;
- struct agg_tx_status *frame_status = &tx_resp->status;
+ struct agg_tx_status *frame_status = tx_resp->u.agg_status;
struct ieee80211_tx_info *info = NULL;
struct ieee80211_hdr *hdr = NULL;
- int i, sh;
- int txq_id, idx;
+ int i, sh, idx;
u16 seq;

if (agg->wait_for_ba)
@@ -3238,9 +3234,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
if (agg->frame_count == 1) {
/* Only one frame was attempted; no block-ack will arrive */
status = le16_to_cpu(frame_status[0].status);
- seq = le16_to_cpu(frame_status[0].sequence);
- idx = SEQ_TO_INDEX(seq);
- txq_id = SEQ_TO_QUEUE(seq);
+ idx = start_idx;

/* FIXME: code repetition */
IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
@@ -3341,7 +3335,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct ieee80211_tx_info *info;
struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
- u32 status = le32_to_cpu(tx_resp->status);
+ u32 status = le32_to_cpu(tx_resp->u.status);
int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
u16 fc;
struct ieee80211_hdr *hdr;
@@ -3380,8 +3374,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,

agg = &priv->stations[sta_id].tid[tid].agg;

- iwl4965_tx_status_reply_tx(priv, agg,
- (struct iwl4965_tx_resp_agg *)tx_resp, index);
+ iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);

if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {
/* TODO: send BAR */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index d3c0e10..2a30306 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1126,23 +1126,20 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)

static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
{
- __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status +
- tx_resp->frame_count);
- return le32_to_cpu(*scd_ssn) & MAX_SN;
-
+ return le32_to_cpup((__le32*)&tx_resp->status +
+ tx_resp->frame_count) & MAX_SN;
}

static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
struct iwl_ht_agg *agg,
struct iwl5000_tx_resp *tx_resp,
- u16 start_idx)
+ int txq_id, u16 start_idx)
{
u16 status;
struct agg_tx_status *frame_status = &tx_resp->status;
struct ieee80211_tx_info *info = NULL;
struct ieee80211_hdr *hdr = NULL;
- int i, sh;
- int txq_id, idx;
+ int i, sh, idx;
u16 seq;

if (agg->wait_for_ba)
@@ -1157,9 +1154,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
if (agg->frame_count == 1) {
/* Only one frame was attempted; no block-ack will arrive */
status = le16_to_cpu(frame_status[0].status);
- seq = le16_to_cpu(frame_status[0].sequence);
- idx = SEQ_TO_INDEX(seq);
- txq_id = SEQ_TO_QUEUE(seq);
+ idx = start_idx;

/* FIXME: code repetition */
IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
@@ -1296,7 +1291,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,

agg = &priv->stations[sta_id].tid[tid].agg;

- iwl5000_tx_status_reply_tx(priv, agg, tx_resp, index);
+ iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);

if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {
/* TODO: send BAR */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index fb6f5ff..9b64a39 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1481,21 +1481,10 @@ struct iwl4965_tx_resp {
* table entry used for all frames in the new agg.
* 31-16: Sequence # for this frame's Tx cmd (not SSN!)
*/
- __le32 status; /* TX status (for aggregation status of 1st frame) */
-} __attribute__ ((packed));
-
-struct iwl4965_tx_resp_agg {
- u8 frame_count; /* 1 no aggregation, >1 aggregation */
- u8 reserved1;
- u8 failure_rts;
- u8 failure_frame;
- __le32 rate_n_flags;
- __le16 wireless_media_time;
- __le16 reserved3;
- __le32 pa_power1;
- __le32 pa_power2;
- struct agg_tx_status status; /* TX status (for aggregation status */
- /* of 1st frame) */
+ union {
+ __le32 status;
+ struct agg_tx_status agg_status[0]; /* for each agg frame */
+ } u;
} __attribute__ ((packed));

struct iwl5000_tx_resp {
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 8e7860d..510e403 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1668,7 +1668,7 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv,

IWL_DEBUG_RX("beacon status %x retries %d iss %d "
"tsf %d %d rate %d\n",
- le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK,
+ le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
beacon->beacon_notify_hdr.failure_frame,
le32_to_cpu(beacon->ibss_mgr_status),
le32_to_cpu(beacon->high_tsf),
--
1.5.3.6


2008-06-12 01:49:31

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 02/29] iwlwifi: removes the RUN_TIME_CALIB ifdef

From: Emmanuel Grumbach <[email protected]>

This patch removes the possibility not to compile the run time
calibrations. It also renames priv->sensitivity_work to
priv->run_time_calib_work, and moves bg_run_time_calib to iwl4965_base
since it is common to both: 4965 and 5000.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/Kconfig | 28 -------------------
drivers/net/wireless/iwlwifi/Makefile | 3 +-
drivers/net/wireless/iwlwifi/iwl-4965.c | 39 +--------------------------
drivers/net/wireless/iwlwifi/iwl-5000.c | 11 -------
drivers/net/wireless/iwlwifi/iwl-calib.c | 2 -
drivers/net/wireless/iwlwifi/iwl-calib.h | 20 --------------
drivers/net/wireless/iwlwifi/iwl-core.h | 2 -
drivers/net/wireless/iwlwifi/iwl-debug.h | 2 -
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 4 ---
drivers/net/wireless/iwlwifi/iwl-dev.h | 12 +-------
drivers/net/wireless/iwlwifi/iwl-rx.c | 2 -
drivers/net/wireless/iwlwifi/iwl4965-base.c | 24 ++++++++++++++++
12 files changed, 27 insertions(+), 122 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index b992428..a382c00 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -14,15 +14,6 @@ config IWLWIFI_LEDS
bool
default n

-config IWLWIFI_RUN_TIME_CALIB
- bool
- depends on IWLCORE
- default n
- ---help---
- This option will enable run time calibration for the iwlwifi driver.
- These calibrations are Sensitivity and Chain Noise.
-
-
config IWLWIFI_RFKILL
boolean "IWLWIFI RF kill support"
depends on IWLCORE
@@ -68,15 +59,6 @@ config IWL4965_SPECTRUM_MEASUREMENT
---help---
This option will enable spectrum measurement for the iwl4965 driver.

-config IWL4965_RUN_TIME_CALIB
- bool "Enable run time Calibration for 4965 NIC"
- select IWLWIFI_RUN_TIME_CALIB
- depends on IWL4965
- default y
- ---help---
- This option will enable run time calibration for the iwl4965 driver.
- These calibrations are Sensitivity and Chain Noise. If unsure, say yes
-
config IWLWIFI_DEBUG
bool "Enable full debugging output in iwl4965 driver"
depends on IWL4965
@@ -110,16 +92,6 @@ config IWL5000
This option enables support for Intel Wireless WiFi Link 5000AGN Family
Dependency on 4965 is temporary

-config IWL5000_RUN_TIME_CALIB
- bool "Enable run time Calibration for 5000 NIC"
- select IWLWIFI_RUN_TIME_CALIB
- depends on IWL5000
- default y
- ---help---
- This option will enable run time calibration for the iwl5000 driver.
- These calibrations are Sensitivity and Chain Noise. If unsure, say yes
-
-
config IWLWIFI_DEBUGFS
bool "Iwlwifi debugfs support"
depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 5c73eed..184fdee 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,10 +1,9 @@
obj-$(CONFIG_IWLCORE) += iwlcore.o
-iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
+iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o iwl-calib.o
iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
-iwlcore-$(CONFIG_IWLWIFI_RUN_TIME_CALIB) += iwl-calib.o

obj-$(CONFIG_IWL3945) += iwl3945.o
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 84414da..e2c2d9f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -652,8 +652,6 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)
cmd.critical_temperature_R);
}

-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB
-
/* Reset differential Rx gains in NIC to prepare for chain noise calibration.
* Called after every association, but this runs only once!
* ... once chain noise is calibrated the first time, it's good forever. */
@@ -741,30 +739,6 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
data->beacon_count = 0;
}

-static void iwl4965_bg_sensitivity_work(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv,
- sensitivity_work);
-
- mutex_lock(&priv->mutex);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
- test_bit(STATUS_SCANNING, &priv->status)) {
- mutex_unlock(&priv->mutex);
- return;
- }
-
- if (priv->start_calib) {
- iwl_chain_noise_calibration(priv, &priv->statistics);
-
- iwl_sensitivity_calibration(priv, &priv->statistics);
- }
-
- mutex_unlock(&priv->mutex);
- return;
-}
-#endif /*CONFIG_IWL4965_RUN_TIME_CALIB*/
-
static void iwl4965_bg_txpower_work(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv,
@@ -920,7 +894,6 @@ int iwl4965_alive_notify(struct iwl_priv *priv)
return ret;
}

-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB
static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
.min_nrg_cck = 97,
.max_nrg_cck = 0,
@@ -943,7 +916,6 @@ static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
.nrg_th_cck = 100,
.nrg_th_ofdm = 100,
};
-#endif

/**
* iwl4965_hw_set_hw_params
@@ -983,9 +955,7 @@ int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.valid_rx_ant = ANT_A | ANT_B;
priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);

-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB
priv->hw_params.sens = &iwl4965_sensitivity;
-#endif

return 0;
}
@@ -2123,9 +2093,7 @@ void iwl4965_hw_rx_statistics(struct iwl_priv *priv,
if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
(pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
iwl4965_rx_calc_noise(priv);
-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB
- queue_work(priv->workqueue, &priv->sensitivity_work);
-#endif
+ queue_work(priv->workqueue, &priv->run_time_calib_work);
}

iwl_leds_background(priv);
@@ -3504,9 +3472,6 @@ static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv)
{
INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work);
-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB
- INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work);
-#endif
init_timer(&priv->statistics_periodic);
priv->statistics_periodic.data = (unsigned long)priv;
priv->statistics_periodic.function = iwl4965_bg_statistics_periodic;
@@ -3527,10 +3492,8 @@ static struct iwl_hcmd_ops iwl4965_hcmd = {
static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
.get_hcmd_size = iwl4965_get_hcmd_size,
.build_addsta_hcmd = iwl4965_build_addsta_hcmd,
-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB
.chain_noise_reset = iwl4965_chain_noise_reset,
.gain_computation = iwl4965_gain_computation,
-#endif
};

static struct iwl_lib_ops iwl4965_lib = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 6548477..fc8ad73 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -300,8 +300,6 @@ err:

}

-#ifdef CONFIG_IWL5000_RUN_TIME_CALIB
-
static void iwl5000_gain_computation(struct iwl_priv *priv,
u32 average_noise[NUM_RX_CHAINS],
u16 min_average_noise_antenna_i,
@@ -354,7 +352,6 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
data->beacon_count = 0;
}

-
static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
{
struct iwl_chain_noise_data *data = &priv->chain_noise_data;
@@ -393,10 +390,6 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
.nrg_th_ofdm = 95,
};

-#endif /* CONFIG_IWL5000_RUN_TIME_CALIB */
-
-
-
static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
size_t offset)
{
@@ -847,9 +840,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
-#ifdef CONFIG_IWL5000_RUN_TIME_CALIB
priv->hw_params.sens = &iwl5000_sensitivity;
-#endif

switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
case CSR_HW_REV_TYPE_5100:
@@ -1309,10 +1300,8 @@ static struct iwl_hcmd_ops iwl5000_hcmd = {
static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
.get_hcmd_size = iwl5000_get_hcmd_size,
.build_addsta_hcmd = iwl5000_build_addsta_hcmd,
-#ifdef CONFIG_IWL5000_RUN_TIME_CALIB
.gain_computation = iwl5000_gain_computation,
.chain_noise_reset = iwl5000_chain_noise_reset,
-#endif
};

static struct iwl_lib_ops iwl5000_lib = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index a6c7f0d..72242a4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -435,8 +435,6 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
data = &(priv->sensitivity_data);

if (ranges == NULL)
- /* can happen if IWLWIFI_RUN_TIME_CALIB is selected
- * but no IWLXXXX_RUN_TIME_CALIB for specific is selected */
return;

memset(data, 0, sizeof(struct iwl_sensitivity_data));
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h
index b8e57c5..45f37cb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.h
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.h
@@ -71,7 +71,6 @@
#include "iwl-core.h"
#include "iwl-dev.h"

-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
void iwl_chain_noise_calibration(struct iwl_priv *priv,
struct iwl4965_notif_statistics *stat_resp);
void iwl_sensitivity_calibration(struct iwl_priv *priv,
@@ -86,24 +85,5 @@ static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
priv->cfg->ops->utils->chain_noise_reset)
priv->cfg->ops->utils->chain_noise_reset(priv);
}
-#else
-static inline void iwl_chain_noise_calibration(struct iwl_priv *priv,
- struct iwl4965_notif_statistics *stat_resp)
-{
-}
-static inline void iwl_sensitivity_calibration(struct iwl_priv *priv,
- struct iwl4965_notif_statistics *resp)
-{
-}
-static inline void iwl_init_sensitivity(struct iwl_priv *priv)
-{
-}
-static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
-{
-}
-static inline void iwl_reset_run_time_calib(struct iwl_priv *priv)
-{
-}
-#endif

#endif /* __iwl_calib_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index d9c5bd1..192cda2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -88,13 +88,11 @@ struct iwl_hcmd_ops {
struct iwl_hcmd_utils_ops {
u16 (*get_hcmd_size)(u8 cmd_id, u16 len);
u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
void (*gain_computation)(struct iwl_priv *priv,
u32 *average_noise,
u16 min_average_noise_antennat_i,
u32 min_average_noise);
void (*chain_noise_reset)(struct iwl_priv *priv);
-#endif
};

struct iwl_lib_ops {
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 11de561..48563a0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -55,10 +55,8 @@ struct iwl_debugfs {
struct dentry *file_log_event;
} dbgfs_data_files;
struct dir_rf_files {
-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
struct dentry *file_disable_sensitivity;
struct dentry *file_disable_chain_noise;
-#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */
} dbgfs_rf_files;
u32 sram_offset;
u32 sram_len;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index d5f9df1..da6dcb2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -385,11 +385,9 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(stations, data);
DEBUGFS_ADD_FILE(rx_statistics, data);
DEBUGFS_ADD_FILE(tx_statistics, data);
-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
&priv->disable_chain_noise_cal);
-#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */
return 0;

err:
@@ -415,10 +413,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
DEBUGFS_REMOVE(priv->dbgfs->dir_data);
-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
-#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */
DEBUGFS_REMOVE(priv->dbgfs->dir_rf);
DEBUGFS_REMOVE(priv->dbgfs->dir_drv);
kfree(priv->dbgfs);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 59a6960..631931c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -602,9 +602,7 @@ struct iwl_hw_params {
u32 max_data_size;
u32 max_bsm_size;
u32 ct_kill_threshold; /* value in hw-dependent units */
-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
const struct iwl_sensitivity_ranges *sens;
-#endif
};

#define HT_SHORT_GI_20MHZ (1 << 0)
@@ -882,7 +880,6 @@ enum ucode_type {
UCODE_RT
};

-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
/* Sensitivity calib data */
struct iwl_sensitivity_data {
u32 auto_corr_ofdm;
@@ -924,7 +921,6 @@ struct iwl_chain_noise_data {
u8 delta_gain_code[NUM_RX_CHAINS];
u8 radio_write;
};
-#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */

#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */
#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
@@ -1057,11 +1053,9 @@ struct iwl_priv {
u8 assoc_station_added;
u8 use_ant_b_for_management_frame; /* Tx antenna selection */
u8 start_calib;
-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
struct iwl_sensitivity_data sensitivity_data;
struct iwl_chain_noise_data chain_noise_data;
__le16 sensitivity_tbl[HD_TABLE_SIZE];
-#endif /*CONFIG_IWLWIFI_RUN_TIME_CALIB*/

struct iwl_ht_info current_ht_config;
u8 last_phy_res[100];
@@ -1211,13 +1205,9 @@ struct iwl_priv {
#endif /* CONFIG_IWLWIFI_DEBUG */

struct work_struct txpower_work;
-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
u32 disable_sens_cal;
u32 disable_chain_noise_cal;
-#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */
-#ifdef CONFIG_IWL4965_RUN_TIME_CALIB
- struct work_struct sensitivity_work;
-#endif /* CONFIG_IWL4965_RUN_TIME_CALIB */
+ struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
}; /*iwl_priv */

diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index cc61c93..c248448 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -451,7 +451,6 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)

{
-#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
struct iwl4965_missed_beacon_notif *missed_beacon;

@@ -465,6 +464,5 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
if (!test_bit(STATUS_SCANNING, &priv->status))
iwl_init_sensitivity(priv);
}
-#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */
}
EXPORT_SYMBOL(iwl_rx_missed_beacon_notif);
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 88229e2..a8dfdcb 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -3423,6 +3423,29 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
mutex_unlock(&priv->mutex);
}

+static void iwl_bg_run_time_calib_work(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv,
+ run_time_calib_work);
+
+ mutex_lock(&priv->mutex);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
+ test_bit(STATUS_SCANNING, &priv->status)) {
+ mutex_unlock(&priv->mutex);
+ return;
+ }
+
+ if (priv->start_calib) {
+ iwl_chain_noise_calibration(priv, &priv->statistics);
+
+ iwl_sensitivity_calibration(priv, &priv->statistics);
+ }
+
+ mutex_unlock(&priv->mutex);
+ return;
+}
+
static void iwl4965_bg_up(struct work_struct *data)
{
struct iwl_priv *priv = container_of(data, struct iwl_priv, up);
@@ -5014,6 +5037,7 @@ static void iwl4965_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update);
INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor);
+ INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
--
1.5.3.6


2008-06-12 14:32:31

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 00/29] iwlwifi driver 06/12 updates

On Thu, Jun 12, 2008 at 01:26:20PM +0800, Zhu Yi wrote:
> On Wed, 2008-06-11 at 22:15 -0700, Harvey Harrison wrote:
> >
> > Since you're the one submitting the patches, shouldn't they have your
> > Signed-off-by as well?
>
> You're right. Will do it next time.

I'll add your S-o-b if you would like?

John
--
John W. Linville
[email protected]

2008-06-12 01:49:39

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 09/29] iwlwifi: remove unused flag

From: Tomas Winkler <[email protected]>

This patch removes IEEE80211_CHAN_W_RADAR_DETECT flag.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index dedefa0..eec423a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -139,8 +139,6 @@ static inline void iwl_set_bits16(__le16 *dst, u8 pos, u8 len, int val)
#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))


-#define IEEE80211_CHAN_W_RADAR_DETECT 0x00000010
-
static inline struct ieee80211_conf *ieee80211_get_hw_conf(
struct ieee80211_hw *hw)
{
--
1.5.3.6


2008-06-12 01:49:59

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 23/29] iwlwifi: move iwl4965_rf_kill_ct_config to iwl-core.c

From: Emmanuel Grumbach <[email protected]>

This patch moves iwl4965_rf_kill_ct_config to iwl-core.c.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 24 ------------------------
drivers/net/wireless/iwlwifi/iwl-commands.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-core.c | 23 +++++++++++++++++++++++
drivers/net/wireless/iwlwifi/iwl-core.h | 1 +
drivers/net/wireless/iwlwifi/iwl4965-base.c | 2 +-
5 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 87648d0..aeb29b9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -556,30 +556,6 @@ out:

#define REG_RECALIB_PERIOD (60)

-void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)
-{
- struct iwl4965_ct_kill_config cmd;
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&priv->lock, flags);
- iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
- CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- cmd.critical_temperature_R =
- cpu_to_le32(priv->hw_params.ct_kill_threshold);
-
- ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
- sizeof(cmd), &cmd);
- if (ret)
- IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n");
- else
- IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, "
- "critical temperature is %d\n",
- cmd.critical_temperature_R);
-}
-
/* Reset differential Rx gains in NIC to prepare for chain noise calibration.
* Called after every association, but this runs only once!
* ... once chain noise is calibrated the first time, it's good forever. */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 6613d32..920dfc1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2078,7 +2078,7 @@ struct iwl4965_card_state_notif {
#define RF_CARD_DISABLED 0x04
#define RXON_CARD_DISABLED 0x10

-struct iwl4965_ct_kill_config {
+struct iwl_ct_kill_config {
__le32 reserved;
__le32 critical_temperature_M;
__le32 critical_temperature_R;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 9794904..8096463 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1326,4 +1326,27 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_dump_nic_event_log);

+void iwl_rf_kill_ct_config(struct iwl_priv *priv)
+{
+ struct iwl_ct_kill_config cmd;
+ unsigned long flags;
+ int ret = 0;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+ CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ cmd.critical_temperature_R =
+ cpu_to_le32(priv->hw_params.ct_kill_threshold);

+ ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
+ sizeof(cmd), &cmd);
+ if (ret)
+ IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n");
+ else
+ IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, "
+ "critical temperature is %d\n",
+ cmd.critical_temperature_R);
+}
+EXPORT_SYMBOL(iwl_rf_kill_ct_config);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 8d9fde6..59dd342 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -371,6 +371,7 @@ int iwlcore_low_level_notify(struct iwl_priv *priv,
enum iwlcore_card_notify notify);
extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags);
extern int iwl_verify_ucode(struct iwl_priv *priv);
+extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
int iwl_send_lq_cmd(struct iwl_priv *priv,
struct iwl_link_quality_cmd *lq, u8 flags);

diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 2073ba6..3717f99 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -2295,7 +2295,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
iwl4965_commit_rxon(priv);

/* At this point, the NIC is initialized and operational */
- iwl4965_rf_kill_ct_config(priv);
+ iwl_rf_kill_ct_config(priv);

iwl_leds_register(priv);

--
1.5.3.6


2008-06-12 01:49:56

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 20/29] iwlwifi: move scan to iwl-scan.c iwlcore

From: Tomas Winkler <[email protected]>

This patch moves scan code to iwl-scan.c file in iwlcore module.

Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/Makefile | 5 +-
drivers/net/wireless/iwlwifi/iwl-commands.h | 24 +-
drivers/net/wireless/iwlwifi/iwl-core.h | 10 +
drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-scan.c | 896 +++++++++++++++++++++++++++
drivers/net/wireless/iwlwifi/iwl4965-base.c | 881 +-------------------------
6 files changed, 946 insertions(+), 872 deletions(-)
create mode 100644 drivers/net/wireless/iwlwifi/iwl-scan.c

diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 184fdee..1f52b92 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,6 +1,7 @@
obj-$(CONFIG_IWLCORE) += iwlcore.o
-iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o iwl-calib.o
-iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o
+iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
+iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
+iwlcore-objs += iwl-scan.o
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index b58f796..058e764 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2100,7 +2100,7 @@ struct iwl4965_ct_kill_config {
*****************************************************************************/

/**
- * struct iwl4965_scan_channel - entry in REPLY_SCAN_CMD channel table
+ * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table
*
* One for each channel in the scan list.
* Each channel can independently select:
@@ -2110,7 +2110,7 @@ struct iwl4965_ct_kill_config {
* quiet_plcp_th, good_CRC_th)
*
* To avoid uCode errors, make sure the following are true (see comments
- * under struct iwl4965_scan_cmd about max_out_time and quiet_time):
+ * under struct iwl_scan_cmd about max_out_time and quiet_time):
* 1) If using passive_dwell (i.e. passive_dwell != 0):
* active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
* 2) quiet_time <= active_dwell
@@ -2118,7 +2118,7 @@ struct iwl4965_ct_kill_config {
* passive_dwell < max_out_time
* active_dwell < max_out_time
*/
-struct iwl4965_scan_channel {
+struct iwl_scan_channel {
/*
* type is defined as:
* 0:0 1 = active, 0 = passive
@@ -2134,13 +2134,13 @@ struct iwl4965_scan_channel {
} __attribute__ ((packed));

/**
- * struct iwl4965_ssid_ie - directed scan network information element
+ * 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 iwl4965_scan_channel; each channel may select different ssids from
* among the 4 entries. SSID IEs get transmitted in reverse order of entry.
*/
-struct iwl4965_ssid_ie {
+struct iwl_ssid_ie {
u8 id;
u8 len;
u8 ssid[32];
@@ -2201,9 +2201,9 @@ struct iwl4965_ssid_ie {
* Driver must use separate scan commands for 2.4 vs. 5 GHz bands.
*
* To avoid uCode errors, see timing restrictions described under
- * struct iwl4965_scan_channel.
+ * struct iwl_scan_channel.
*/
-struct iwl4965_scan_cmd {
+struct iwl_scan_cmd {
__le16 len;
u8 reserved0;
u8 channel_count; /* # channels in channel list */
@@ -2227,7 +2227,7 @@ struct iwl4965_scan_cmd {
struct iwl_tx_cmd tx_cmd;

/* For directed active scans (set to all-0s otherwise) */
- struct iwl4965_ssid_ie direct_scan[PROBE_OPTION_MAX];
+ struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];

/*
* Probe request frame, followed by channel list.
@@ -2255,14 +2255,14 @@ struct iwl4965_scan_cmd {
/*
* REPLY_SCAN_CMD = 0x80 (response)
*/
-struct iwl4965_scanreq_notification {
+struct iwl_scanreq_notification {
__le32 status; /* 1: okay, 2: cannot fulfill request */
} __attribute__ ((packed));

/*
* SCAN_START_NOTIFICATION = 0x82 (notification only, not a command)
*/
-struct iwl4965_scanstart_notification {
+struct iwl_scanstart_notification {
__le32 tsf_low;
__le32 tsf_high;
__le32 beacon_timer;
@@ -2279,7 +2279,7 @@ struct iwl4965_scanstart_notification {
/*
* SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command)
*/
-struct iwl4965_scanresults_notification {
+struct iwl_scanresults_notification {
u8 channel;
u8 band;
u8 reserved[2];
@@ -2291,7 +2291,7 @@ struct iwl4965_scanresults_notification {
/*
* SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command)
*/
-struct iwl4965_scancomplete_notification {
+struct iwl_scancomplete_notification {
u8 scanned_channels;
u8 status;
u8 reserved;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 5bae691..5837577 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -243,6 +243,16 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
****************************************************/
int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);

+/*******************************************************************************
+ * Scanning
+ ******************************************************************************/
+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);
+
/*****************************************************
* 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 b420f64..e586987 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -976,7 +976,7 @@ struct iwl_priv {
int one_direct_scan;
u8 direct_ssid_len;
u8 direct_ssid[IW_ESSID_MAX_SIZE];
- struct iwl4965_scan_cmd *scan;
+ struct iwl_scan_cmd *scan;

/* spinlock */
spinlock_t lock; /* protect general shared data */
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
new file mode 100644
index 0000000..c2ed7c1
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -0,0 +1,896 @@
+/******************************************************************************
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Tomas Winkler <[email protected]>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *****************************************************************************/
+#include <net/mac80211.h>
+#include <linux/etherdevice.h>
+
+#include "iwl-eeprom.h"
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-sta.h"
+#include "iwl-io.h"
+#include "iwl-helpers.h"
+
+/* 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)
+
+/* For faster active scanning, scan will move to the next channel if fewer than
+ * PLCP_QUIET_THRESH packets are heard on this channel within
+ * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
+ * time if it's a quiet channel (nothing responded to our probe, and there's
+ * 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 */
+
+/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
+ * Must be set longer than active dwell time.
+ * For the most reliable scan, set > AP beacon interval (typically 100msec). */
+#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */
+#define IWL_PASSIVE_DWELL_TIME_52 (10)
+#define IWL_PASSIVE_DWELL_BASE (100)
+#define IWL_CHANNEL_TUNE_TIME 5
+
+
+
+static int iwl_is_empty_essid(const char *essid, int essid_len)
+{
+ /* Single white space is for Linksys APs */
+ if (essid_len == 1 && essid[0] == ' ')
+ return 1;
+
+ /* Otherwise, if the entire essid is 0, we assume it is hidden */
+ while (essid_len) {
+ essid_len--;
+ if (essid[essid_len] != '\0')
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
+const char *iwl_escape_essid(const char *essid, u8 essid_len)
+{
+ static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
+ const char *s = essid;
+ char *d = escaped;
+
+ if (iwl_is_empty_essid(essid, essid_len)) {
+ memcpy(escaped, "<hidden>", sizeof("<hidden>"));
+ return escaped;
+ }
+
+ essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
+ while (essid_len--) {
+ if (*s == '\0') {
+ *d++ = '\\';
+ *d++ = '0';
+ s++;
+ } else
+ *d++ = *s++;
+ }
+ *d = '\0';
+ return escaped;
+}
+EXPORT_SYMBOL(iwl_escape_essid);
+
+/**
+ * iwl_scan_cancel - Cancel any currently executing HW scan
+ *
+ * NOTE: priv->mutex is not required before calling this function
+ */
+int iwl_scan_cancel(struct iwl_priv *priv)
+{
+ if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
+ clear_bit(STATUS_SCANNING, &priv->status);
+ return 0;
+ }
+
+ if (test_bit(STATUS_SCANNING, &priv->status)) {
+ if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_SCAN("Queuing scan abort.\n");
+ set_bit(STATUS_SCAN_ABORTING, &priv->status);
+ queue_work(priv->workqueue, &priv->abort_scan);
+
+ } else
+ IWL_DEBUG_SCAN("Scan abort already in progress.\n");
+
+ return test_bit(STATUS_SCANNING, &priv->status);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_scan_cancel);
+/**
+ * iwl_scan_cancel_timeout - Cancel any currently executing HW scan
+ * @ms: amount of time to wait (in milliseconds) for scan to abort
+ *
+ * NOTE: priv->mutex must be held before calling this function
+ */
+int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
+{
+ unsigned long now = jiffies;
+ int ret;
+
+ ret = iwl_scan_cancel(priv);
+ if (ret && ms) {
+ mutex_unlock(&priv->mutex);
+ while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
+ test_bit(STATUS_SCANNING, &priv->status))
+ msleep(1);
+ mutex_lock(&priv->mutex);
+
+ return test_bit(STATUS_SCANNING, &priv->status);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(iwl_scan_cancel_timeout);
+
+static int iwl_send_scan_abort(struct iwl_priv *priv)
+{
+ int ret = 0;
+ struct iwl_rx_packet *res;
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_SCAN_ABORT_CMD,
+ .meta.flags = CMD_WANT_SKB,
+ };
+
+ /* If there isn't a scan actively going on in the hardware
+ * then we are in between scan bands and not actually
+ * actively scanning, so don't send the abort command */
+ if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+ return 0;
+ }
+
+ ret = iwl_send_cmd_sync(priv, &cmd);
+ if (ret) {
+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+ return ret;
+ }
+
+ res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+ if (res->u.status != CAN_ABORT_STATUS) {
+ /* The scan abort will return 1 for success or
+ * 2 for "failure". A failure condition can be
+ * due to simply not being in an active scan which
+ * can occur if we send the scan abort before we
+ * the microcode has notified us that a scan is
+ * completed. */
+ IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);
+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+ clear_bit(STATUS_SCAN_HW, &priv->status);
+ }
+
+ dev_kfree_skb_any(cmd.meta.u.skb);
+
+ return ret;
+}
+
+
+/* Service response to REPLY_SCAN_CMD (0x80) */
+static void iwl_rx_reply_scan(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_scanreq_notification *notif =
+ (struct iwl_scanreq_notification *)pkt->u.raw;
+
+ IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
+#endif
+}
+
+/* Service SCAN_START_NOTIFICATION (0x82) */
+static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_scanstart_notification *notif =
+ (struct iwl_scanstart_notification *)pkt->u.raw;
+ priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
+ IWL_DEBUG_SCAN("Scan start: "
+ "%d [802.11%s] "
+ "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",
+ notif->channel,
+ notif->band ? "bg" : "a",
+ notif->tsf_high,
+ notif->tsf_low, notif->status, notif->beacon_timer);
+}
+
+/* Service SCAN_RESULTS_NOTIFICATION (0x83) */
+static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+#ifdef CONFIG_IWLWIFI_DEBUG
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_scanresults_notification *notif =
+ (struct iwl_scanresults_notification *)pkt->u.raw;
+
+ IWL_DEBUG_SCAN("Scan ch.res: "
+ "%d [802.11%s] "
+ "(TSF: 0x%08X:%08X) - %d "
+ "elapsed=%lu usec (%dms since last)\n",
+ notif->channel,
+ notif->band ? "bg" : "a",
+ le32_to_cpu(notif->tsf_high),
+ le32_to_cpu(notif->tsf_low),
+ le32_to_cpu(notif->statistics[0]),
+ le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf,
+ jiffies_to_msecs(elapsed_jiffies
+ (priv->last_scan_jiffies, jiffies)));
+#endif
+
+ priv->last_scan_jiffies = jiffies;
+ priv->next_scan_jiffies = 0;
+}
+
+/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
+static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
+{
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+ struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
+
+ IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
+ scan_notif->scanned_channels,
+ scan_notif->tsf_low,
+ scan_notif->tsf_high, scan_notif->status);
+
+ /* The HW is no longer scanning */
+ clear_bit(STATUS_SCAN_HW, &priv->status);
+
+ /* The scan completion notification came in, so kill that timer... */
+ cancel_delayed_work(&priv->scan_check);
+
+ IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
+ (priv->scan_bands == 2) ? "2.4" : "5.2",
+ jiffies_to_msecs(elapsed_jiffies
+ (priv->scan_pass_start, jiffies)));
+
+ /* Remove this scanned band from the list
+ * of pending bands to scan */
+ priv->scan_bands--;
+
+ /* If a request to abort was given, or the scan did not succeed
+ * then we reset the scan state machine and terminate,
+ * re-queuing another scan if one has been requested */
+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_INFO("Aborted scan completed.\n");
+ clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+ } else {
+ /* If there are more bands on this scan pass reschedule */
+ if (priv->scan_bands > 0)
+ goto reschedule;
+ }
+
+ priv->last_scan_jiffies = jiffies;
+ priv->next_scan_jiffies = 0;
+ IWL_DEBUG_INFO("Setting scan to off\n");
+
+ clear_bit(STATUS_SCANNING, &priv->status);
+
+ IWL_DEBUG_INFO("Scan took %dms\n",
+ jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
+
+ queue_work(priv->workqueue, &priv->scan_completed);
+
+ return;
+
+reschedule:
+ priv->scan_pass_start = jiffies;
+ queue_work(priv->workqueue, &priv->request_scan);
+}
+
+void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
+{
+ /* scan handlers */
+ priv->rx_handlers[REPLY_SCAN_CMD] = iwl_rx_reply_scan;
+ priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl_rx_scan_start_notif;
+ priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] =
+ iwl_rx_scan_results_notif;
+ priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
+ iwl_rx_scan_complete_notif;
+}
+EXPORT_SYMBOL(iwl_setup_rx_scan_handlers);
+
+static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band)
+{
+ if (band == IEEE80211_BAND_5GHZ)
+ return IWL_ACTIVE_DWELL_TIME_52;
+ else
+ return IWL_ACTIVE_DWELL_TIME_24;
+}
+
+static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band)
+{
+ u16 active = iwl_get_active_dwell_time(priv, band);
+ u16 passive = (band != IEEE80211_BAND_5GHZ) ?
+ IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
+ IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
+
+ if (iwl_is_associated(priv)) {
+ /* If we're associated, we clamp the maximum passive
+ * dwell time to be 98% of the beacon interval (minus
+ * 2 * channel tune time) */
+ passive = priv->beacon_int;
+ if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
+ passive = IWL_PASSIVE_DWELL_BASE;
+ passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
+ }
+
+ if (passive <= active)
+ passive = active + 1;
+
+ return passive;
+}
+
+static int iwl_get_channels_for_scan(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 is_active, u8 direct_mask,
+ struct iwl_scan_channel *scan_ch)
+{
+ const struct ieee80211_channel *channels = NULL;
+ const struct ieee80211_supported_band *sband;
+ const struct iwl_channel_info *ch_info;
+ u16 passive_dwell = 0;
+ u16 active_dwell = 0;
+ int added, i;
+
+ sband = iwl_get_hw_mode(priv, band);
+ if (!sband)
+ return 0;
+
+ channels = sband->channels;
+
+ active_dwell = iwl_get_active_dwell_time(priv, band);
+ passive_dwell = iwl_get_passive_dwell_time(priv, band);
+
+ for (i = 0, added = 0; i < sband->n_channels; i++) {
+ if (channels[i].flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
+ scan_ch->channel =
+ ieee80211_frequency_to_channel(channels[i].center_freq);
+
+ ch_info = iwl_get_channel_info(priv, band,
+ scan_ch->channel);
+ if (!is_channel_valid(ch_info)) {
+ IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",
+ scan_ch->channel);
+ continue;
+ }
+
+ if (!is_active || is_channel_passive(ch_info) ||
+ (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))
+ scan_ch->type = 0; /* passive */
+ else
+ scan_ch->type = 1; /* active */
+
+ if (scan_ch->type & 1)
+ scan_ch->type |= (direct_mask << 1);
+
+ scan_ch->active_dwell = cpu_to_le16(active_dwell);
+ scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
+
+ /* Set txpower levels to defaults */
+ scan_ch->tpc.dsp_atten = 110;
+ /* scan_pwr_info->tpc.dsp_atten; */
+
+ /*scan_pwr_info->tpc.tx_gain; */
+ if (band == IEEE80211_BAND_5GHZ)
+ scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3;
+ else {
+ scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3));
+ /* NOTE: if we were doing 6Mb OFDM for scans we'd use
+ * power level:
+ * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3;
+ */
+ }
+
+ IWL_DEBUG_SCAN("Scanning %d [%s %d]\n",
+ scan_ch->channel,
+ (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE",
+ (scan_ch->type & 1) ?
+ active_dwell : passive_dwell);
+
+ scan_ch++;
+ added++;
+ }
+
+ IWL_DEBUG_SCAN("total channels to scan %d \n", added);
+ return added;
+}
+
+int iwl_scan_initiate(struct iwl_priv *priv)
+{
+ if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
+ IWL_ERROR("APs don't scan.\n");
+ return 0;
+ }
+
+ if (!iwl_is_ready_rf(priv)) {
+ IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
+ return -EIO;
+ }
+
+ if (test_bit(STATUS_SCANNING, &priv->status)) {
+ IWL_DEBUG_SCAN("Scan already in progress.\n");
+ return -EAGAIN;
+ }
+
+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_SCAN("Scan request while abort pending. "
+ "Queuing.\n");
+ return -EAGAIN;
+ }
+
+ IWL_DEBUG_INFO("Starting scan...\n");
+ priv->scan_bands = 2;
+ set_bit(STATUS_SCANNING, &priv->status);
+ priv->scan_start = jiffies;
+ priv->scan_pass_start = priv->scan_start;
+
+ queue_work(priv->workqueue, &priv->request_scan);
+
+ return 0;
+}
+EXPORT_SYMBOL(iwl_scan_initiate);
+
+#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
+
+static void iwl_bg_scan_check(struct work_struct *data)
+{
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, scan_check.work);
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+ return;
+
+ mutex_lock(&priv->mutex);
+ if (test_bit(STATUS_SCANNING, &priv->status) ||
+ test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting "
+ "adapter (%dms)\n",
+ jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
+
+ if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
+ iwl_send_scan_abort(priv);
+ }
+ mutex_unlock(&priv->mutex);
+}
+/**
+ * iwl_supported_rate_to_ie - fill in the supported rate in IE field
+ *
+ * return : set the bit for each supported rate insert in ie
+ */
+static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
+ u16 basic_rate, int *left)
+{
+ u16 ret_rates = 0, bit;
+ int i;
+ u8 *cnt = ie;
+ u8 *rates = ie + 1;
+
+ for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
+ if (bit & supported_rate) {
+ ret_rates |= bit;
+ rates[*cnt] = iwl_rates[i].ieee |
+ ((bit & basic_rate) ? 0x80 : 0x00);
+ (*cnt)++;
+ (*left)--;
+ if ((*left <= 0) ||
+ (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
+ break;
+ }
+ }
+
+ return ret_rates;
+}
+
+
+static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
+ u8 *pos, int *left)
+{
+ struct ieee80211_ht_cap *ht_cap;
+
+ if (!sband || !sband->ht_info.ht_supported)
+ return;
+
+ if (*left < sizeof(struct ieee80211_ht_cap))
+ return;
+
+ *pos++ = sizeof(struct ieee80211_ht_cap);
+ ht_cap = (struct ieee80211_ht_cap *) pos;
+
+ ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap);
+ memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16);
+ ht_cap->ampdu_params_info =
+ (sband->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) |
+ ((sband->ht_info.ampdu_density << 2) &
+ IEEE80211_HT_CAP_AMPDU_DENSITY);
+ *left -= sizeof(struct ieee80211_ht_cap);
+}
+
+/**
+ * iwl_fill_probe_req - fill in all required fields and IE for probe request
+ */
+static u16 iwl_fill_probe_req(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ struct ieee80211_mgmt *frame,
+ int left, int is_direct)
+{
+ int len = 0;
+ u8 *pos = NULL;
+ u16 active_rates, ret_rates, cck_rates, active_rate_basic;
+ const struct ieee80211_supported_band *sband =
+ iwl_get_hw_mode(priv, band);
+
+ /* Make sure there is enough space for the probe request,
+ * two mandatory IEs and the data */
+ left -= 24;
+ if (left < 0)
+ return 0;
+ len += 24;
+
+ frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
+ memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);
+ memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
+ memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);
+ frame->seq_ctrl = 0;
+
+ /* fill in our indirect SSID IE */
+ /* ...next IE... */
+
+ left -= 2;
+ if (left < 0)
+ return 0;
+ len += 2;
+ pos = &(frame->u.probe_req.variable[0]);
+ *pos++ = WLAN_EID_SSID;
+ *pos++ = 0;
+
+ /* fill in our direct SSID IE... */
+ if (is_direct) {
+ /* ...next IE... */
+ left -= 2 + priv->essid_len;
+ if (left < 0)
+ return 0;
+ /* ... fill it in... */
+ *pos++ = WLAN_EID_SSID;
+ *pos++ = priv->essid_len;
+ memcpy(pos, priv->essid, priv->essid_len);
+ pos += priv->essid_len;
+ len += 2 + priv->essid_len;
+ }
+
+ /* fill in supported rate */
+ /* ...next IE... */
+ left -= 2;
+ if (left < 0)
+ return 0;
+
+ /* ... fill it in... */
+ *pos++ = WLAN_EID_SUPP_RATES;
+ *pos = 0;
+
+ /* exclude 60M rate */
+ active_rates = priv->rates_mask;
+ active_rates &= ~IWL_RATE_60M_MASK;
+
+ active_rate_basic = active_rates & IWL_BASIC_RATES_MASK;
+
+ cck_rates = IWL_CCK_RATES_MASK & active_rates;
+ ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
+ active_rate_basic, &left);
+ active_rates &= ~ret_rates;
+
+ ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
+ active_rate_basic, &left);
+ active_rates &= ~ret_rates;
+
+ len += 2 + *pos;
+ pos += (*pos) + 1;
+ if (active_rates == 0)
+ goto fill_end;
+
+ /* fill in supported extended rate */
+ /* ...next IE... */
+ left -= 2;
+ if (left < 0)
+ return 0;
+ /* ... fill it in... */
+ *pos++ = WLAN_EID_EXT_SUPP_RATES;
+ *pos = 0;
+ iwl_supported_rate_to_ie(pos, active_rates,
+ active_rate_basic, &left);
+ if (*pos > 0)
+ len += 2 + *pos;
+
+ fill_end:
+ /* fill in HT IE */
+ left -= 2;
+ if (left < 0)
+ return 0;
+
+ *pos++ = WLAN_EID_HT_CAPABILITY;
+ *pos = 0;
+
+ iwl_ht_cap_to_ie(sband, pos, &left);
+
+ if (*pos > 0)
+ len += 2 + *pos;
+ return (u16)len;
+}
+
+static void iwl_bg_request_scan(struct work_struct *data)
+{
+ struct iwl_priv *priv =
+ container_of(data, struct iwl_priv, request_scan);
+ struct iwl_host_cmd cmd = {
+ .id = REPLY_SCAN_CMD,
+ .len = sizeof(struct iwl_scan_cmd),
+ .meta.flags = CMD_SIZE_HUGE,
+ };
+ struct iwl_scan_cmd *scan;
+ struct ieee80211_conf *conf = NULL;
+ u16 cmd_len;
+ enum ieee80211_band band;
+ u8 direct_mask;
+ int ret = 0;
+
+ conf = ieee80211_get_hw_conf(priv->hw);
+
+ mutex_lock(&priv->mutex);
+
+ if (!iwl_is_ready(priv)) {
+ IWL_WARNING("request scan called when driver not ready.\n");
+ goto done;
+ }
+
+ /* Make sure the scan wasn't cancelled before this queued work
+ * was given the chance to run... */
+ if (!test_bit(STATUS_SCANNING, &priv->status))
+ goto done;
+
+ /* This should never be called or scheduled if there is currently
+ * a scan active in the hardware. */
+ if (test_bit(STATUS_SCAN_HW, &priv->status)) {
+ IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. "
+ "Ignoring second request.\n");
+ ret = -EIO;
+ goto done;
+ }
+
+ if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+ IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n");
+ goto done;
+ }
+
+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+ IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n");
+ goto done;
+ }
+
+ if (iwl_is_rfkill(priv)) {
+ IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
+ goto done;
+ }
+
+ if (!test_bit(STATUS_READY, &priv->status)) {
+ IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n");
+ goto done;
+ }
+
+ if (!priv->scan_bands) {
+ IWL_DEBUG_HC("Aborting scan due to no requested bands\n");
+ goto done;
+ }
+
+ if (!priv->scan) {
+ priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) +
+ IWL_MAX_SCAN_SIZE, GFP_KERNEL);
+ if (!priv->scan) {
+ ret = -ENOMEM;
+ goto done;
+ }
+ }
+ scan = priv->scan;
+ memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
+
+ scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
+ scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
+
+ if (iwl_is_associated(priv)) {
+ u16 interval = 0;
+ u32 extra;
+ u32 suspend_time = 100;
+ u32 scan_suspend_time = 100;
+ unsigned long flags;
+
+ IWL_DEBUG_INFO("Scanning while associated...\n");
+
+ spin_lock_irqsave(&priv->lock, flags);
+ interval = priv->beacon_int;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ scan->suspend_time = 0;
+ scan->max_out_time = cpu_to_le32(200 * 1024);
+ if (!interval)
+ interval = suspend_time;
+
+ extra = (suspend_time / interval) << 22;
+ scan_suspend_time = (extra |
+ ((suspend_time % interval) * 1024));
+ scan->suspend_time = cpu_to_le32(scan_suspend_time);
+ IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n",
+ scan_suspend_time, interval);
+ }
+
+ /* We should add the ability for user to lock to PASSIVE ONLY */
+ if (priv->one_direct_scan) {
+ IWL_DEBUG_SCAN
+ ("Kicking off one direct scan for '%s'\n",
+ iwl_escape_essid(priv->direct_ssid,
+ priv->direct_ssid_len));
+ scan->direct_scan[0].id = WLAN_EID_SSID;
+ 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;
+ } else if (!iwl_is_associated(priv) && priv->essid_len) {
+ IWL_DEBUG_SCAN
+ ("Kicking off one direct scan for '%s' when not associated\n",
+ iwl_escape_essid(priv->essid, priv->essid_len));
+ scan->direct_scan[0].id = WLAN_EID_SSID;
+ scan->direct_scan[0].len = priv->essid_len;
+ memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
+ direct_mask = 1;
+ } else {
+ IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");
+ direct_mask = 0;
+ }
+
+ scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
+ scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
+ scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+
+
+ switch (priv->scan_bands) {
+ case 2:
+ scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
+ scan->tx_cmd.rate_n_flags =
+ iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,
+ RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK);
+
+ scan->good_CRC_th = 0;
+ band = IEEE80211_BAND_2GHZ;
+ break;
+
+ case 1:
+ scan->tx_cmd.rate_n_flags =
+ iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
+ RATE_MCS_ANT_B_MSK);
+ scan->good_CRC_th = IWL_GOOD_CRC_TH;
+ band = IEEE80211_BAND_5GHZ;
+ break;
+
+ default:
+ IWL_WARNING("Invalid scan band count\n");
+ goto done;
+ }
+
+ /* We don't build a direct scan probe request; the uCode will do
+ * that based on the direct_mask added to each channel entry */
+ cmd_len = iwl_fill_probe_req(priv, band,
+ (struct ieee80211_mgmt *)scan->data,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan), 0);
+
+ scan->tx_cmd.len = cpu_to_le16(cmd_len);
+ /* select Rx chains */
+
+ /* Force use of chains B and C (0x6) for scan Rx.
+ * Avoid A (0x1) because of its off-channel reception on A-band.
+ * MIMO is not used here, but value is required to make uCode happy. */
+ scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |
+ cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |
+ (0x6 << RXON_RX_CHAIN_FORCE_SEL_POS) |
+ (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS));
+
+ if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
+ scan->filter_flags = RXON_FILTER_PROMISC_MSK;
+
+ if (direct_mask)
+ scan->channel_count =
+ iwl_get_channels_for_scan(
+ priv, band, 1, /* active */
+ direct_mask,
+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ else
+ scan->channel_count =
+ iwl_get_channels_for_scan(
+ priv, band, 0, /* passive */
+ direct_mask,
+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+
+ scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
+ RXON_FILTER_BCON_AWARE_MSK);
+ cmd.len += le16_to_cpu(scan->tx_cmd.len) +
+ scan->channel_count * sizeof(struct iwl_scan_channel);
+ cmd.data = scan;
+ scan->len = cpu_to_le16(cmd.len);
+
+ set_bit(STATUS_SCAN_HW, &priv->status);
+ ret = iwl_send_cmd_sync(priv, &cmd);
+ if (ret)
+ goto done;
+
+ queue_delayed_work(priv->workqueue, &priv->scan_check,
+ IWL_SCAN_CHECK_WATCHDOG);
+
+ mutex_unlock(&priv->mutex);
+ return;
+
+ done:
+ /* inform mac80211 scan aborted */
+ queue_work(priv->workqueue, &priv->scan_completed);
+ mutex_unlock(&priv->mutex);
+}
+
+static void iwl_bg_abort_scan(struct work_struct *work)
+{
+ struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
+
+ if (!iwl_is_ready(priv))
+ return;
+
+ mutex_lock(&priv->mutex);
+
+ set_bit(STATUS_SCAN_ABORTING, &priv->status);
+ iwl_send_scan_abort(priv);
+
+ 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->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);
+}
+EXPORT_SYMBOL(iwl_setup_scan_deferred_work);
+
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index af44819..4183bd5 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -87,46 +87,6 @@ MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL");

-static int iwl4965_is_empty_essid(const char *essid, int essid_len)
-{
- /* Single white space is for Linksys APs */
- if (essid_len == 1 && essid[0] == ' ')
- return 1;
-
- /* Otherwise, if the entire essid is 0, we assume it is hidden */
- while (essid_len) {
- essid_len--;
- if (essid[essid_len] != '\0')
- return 0;
- }
-
- return 1;
-}
-
-static const char *iwl4965_escape_essid(const char *essid, u8 essid_len)
-{
- static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
- const char *s = essid;
- char *d = escaped;
-
- if (iwl4965_is_empty_essid(essid, essid_len)) {
- memcpy(escaped, "<hidden>", sizeof("<hidden>"));
- return escaped;
- }
-
- essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE);
- while (essid_len--) {
- if (*s == '\0') {
- *d++ = '\\';
- *d++ = '0';
- s++;
- } else
- *d++ = *s++;
- }
- *d = '\0';
- return escaped;
-}
-
/*************** STATION TABLE MANAGEMENT ****
* mac80211 should be examined to determine if sta_info is duplicating
* the functionality provided here
@@ -419,47 +379,6 @@ static int iwl4965_send_bt_config(struct iwl_priv *priv)
sizeof(struct iwl4965_bt_cmd), &bt_cmd);
}

-static int iwl4965_send_scan_abort(struct iwl_priv *priv)
-{
- int ret = 0;
- struct iwl_rx_packet *res;
- struct iwl_host_cmd cmd = {
- .id = REPLY_SCAN_ABORT_CMD,
- .meta.flags = CMD_WANT_SKB,
- };
-
- /* If there isn't a scan actively going on in the hardware
- * then we are in between scan bands and not actually
- * actively scanning, so don't send the abort command */
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return 0;
- }
-
- ret = iwl_send_cmd_sync(priv, &cmd);
- if (ret) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return ret;
- }
-
- res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
- if (res->u.status != CAN_ABORT_STATUS) {
- /* The scan abort will return 1 for success or
- * 2 for "failure". A failure condition can be
- * due to simply not being in an active scan which
- * can occur if we send the scan abort before we
- * the microcode has notified us that a scan is
- * completed. */
- IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- clear_bit(STATUS_SCAN_HW, &priv->status);
- }
-
- dev_kfree_skb_any(cmd.meta.u.skb);
-
- return ret;
-}
-
/*
* CARD_STATE_CMD
*
@@ -605,35 +524,6 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
*
******************************************************************************/

-/**
- * iwl4965_supported_rate_to_ie - fill in the supported rate in IE field
- *
- * return : set the bit for each supported rate insert in ie
- */
-static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate,
- u16 basic_rate, int *left)
-{
- u16 ret_rates = 0, bit;
- int i;
- u8 *cnt = ie;
- u8 *rates = ie + 1;
-
- for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
- if (bit & supported_rate) {
- ret_rates |= bit;
- rates[*cnt] = iwl_rates[i].ieee |
- ((bit & basic_rate) ? 0x80 : 0x00);
- (*cnt)++;
- (*left)--;
- if ((*left <= 0) ||
- (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
- break;
- }
- }
-
- return ret_rates;
-}
-
static void iwl4965_ht_conf(struct iwl_priv *priv,
struct ieee80211_bss_conf *bss_conf)
{
@@ -686,140 +576,6 @@ static void iwl4965_ht_conf(struct iwl_priv *priv,
IWL_DEBUG_MAC80211("leave\n");
}

-static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
- u8 *pos, int *left)
-{
- struct ieee80211_ht_cap *ht_cap;
-
- if (!sband || !sband->ht_info.ht_supported)
- return;
-
- if (*left < sizeof(struct ieee80211_ht_cap))
- return;
-
- *pos++ = sizeof(struct ieee80211_ht_cap);
- ht_cap = (struct ieee80211_ht_cap *) pos;
-
- ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap);
- memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16);
- ht_cap->ampdu_params_info =
- (sband->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) |
- ((sband->ht_info.ampdu_density << 2) &
- IEEE80211_HT_CAP_AMPDU_DENSITY);
- *left -= sizeof(struct ieee80211_ht_cap);
-}
-
-/**
- * iwl4965_fill_probe_req - fill in all required fields and IE for probe request
- */
-static u16 iwl4965_fill_probe_req(struct iwl_priv *priv,
- enum ieee80211_band band,
- struct ieee80211_mgmt *frame,
- int left, int is_direct)
-{
- int len = 0;
- u8 *pos = NULL;
- u16 active_rates, ret_rates, cck_rates, active_rate_basic;
- const struct ieee80211_supported_band *sband =
- iwl_get_hw_mode(priv, band);
-
- /* Make sure there is enough space for the probe request,
- * two mandatory IEs and the data */
- left -= 24;
- if (left < 0)
- return 0;
- len += 24;
-
- frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);
- memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
- memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);
- frame->seq_ctrl = 0;
-
- /* fill in our indirect SSID IE */
- /* ...next IE... */
-
- left -= 2;
- if (left < 0)
- return 0;
- len += 2;
- pos = &(frame->u.probe_req.variable[0]);
- *pos++ = WLAN_EID_SSID;
- *pos++ = 0;
-
- /* fill in our direct SSID IE... */
- if (is_direct) {
- /* ...next IE... */
- left -= 2 + priv->essid_len;
- if (left < 0)
- return 0;
- /* ... fill it in... */
- *pos++ = WLAN_EID_SSID;
- *pos++ = priv->essid_len;
- memcpy(pos, priv->essid, priv->essid_len);
- pos += priv->essid_len;
- len += 2 + priv->essid_len;
- }
-
- /* fill in supported rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
-
- /* ... fill it in... */
- *pos++ = WLAN_EID_SUPP_RATES;
- *pos = 0;
-
- /* exclude 60M rate */
- active_rates = priv->rates_mask;
- active_rates &= ~IWL_RATE_60M_MASK;
-
- active_rate_basic = active_rates & IWL_BASIC_RATES_MASK;
-
- cck_rates = IWL_CCK_RATES_MASK & active_rates;
- ret_rates = iwl4965_supported_rate_to_ie(pos, cck_rates,
- active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- ret_rates = iwl4965_supported_rate_to_ie(pos, active_rates,
- active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- len += 2 + *pos;
- pos += (*pos) + 1;
- if (active_rates == 0)
- goto fill_end;
-
- /* fill in supported extended rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
- /* ... fill it in... */
- *pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos = 0;
- iwl4965_supported_rate_to_ie(pos, active_rates,
- active_rate_basic, &left);
- if (*pos > 0)
- len += 2 + *pos;
-
- fill_end:
- /* fill in HT IE */
- left -= 2;
- if (left < 0)
- return 0;
-
- *pos++ = WLAN_EID_HT_CAPABILITY;
- *pos = 0;
-
- iwl_ht_cap_to_ie(sband, pos, &left);
-
- if (*pos > 0)
- len += 2 + *pos;
- return (u16)len;
-}
-
/*
* QoS support
*/
@@ -897,60 +653,6 @@ int iwl4965_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *heade
return 1;
}

-
-
-/**
- * iwl4965_scan_cancel - Cancel any currently executing HW scan
- *
- * NOTE: priv->mutex is not required before calling this function
- */
-static int iwl4965_scan_cancel(struct iwl_priv *priv)
-{
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCANNING, &priv->status);
- return 0;
- }
-
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Queuing scan abort.\n");
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
- queue_work(priv->workqueue, &priv->abort_scan);
-
- } else
- IWL_DEBUG_SCAN("Scan abort already in progress.\n");
-
- return test_bit(STATUS_SCANNING, &priv->status);
- }
-
- return 0;
-}
-
-/**
- * iwl4965_scan_cancel_timeout - Cancel any currently executing HW scan
- * @ms: amount of time to wait (in milliseconds) for scan to abort
- *
- * NOTE: priv->mutex must be held before calling this function
- */
-static int iwl4965_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
-{
- unsigned long now = jiffies;
- int ret;
-
- ret = iwl4965_scan_cancel(priv);
- if (ret && ms) {
- mutex_unlock(&priv->mutex);
- while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
- test_bit(STATUS_SCANNING, &priv->status))
- msleep(1);
- mutex_lock(&priv->mutex);
-
- return test_bit(STATUS_SCANNING, &priv->status);
- }
-
- return ret;
-}
-
static void iwl4965_sequence_reset(struct iwl_priv *priv)
{
/* Reset ieee stats */
@@ -962,7 +664,7 @@ static void iwl4965_sequence_reset(struct iwl_priv *priv)
priv->last_frag_num = -1;
priv->last_packet_time = 0;

- iwl4965_scan_cancel(priv);
+ iwl_scan_cancel(priv);
}

#define MAX_UCODE_BEACON_INTERVAL 4096
@@ -1037,41 +739,6 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv)
le16_to_cpu(priv->rxon_timing.atim_window));
}

-static int iwl4965_scan_initiate(struct iwl_priv *priv)
-{
- if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
- IWL_ERROR("APs don't scan.\n");
- return 0;
- }
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
- return -EIO;
- }
-
- if (test_bit(STATUS_SCANNING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan already in progress.\n");
- return -EAGAIN;
- }
-
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_SCAN("Scan request while abort pending. "
- "Queuing.\n");
- return -EAGAIN;
- }
-
- IWL_DEBUG_INFO("Starting scan...\n");
- priv->scan_bands = 2;
- set_bit(STATUS_SCANNING, &priv->status);
- priv->scan_start = jiffies;
- priv->scan_pass_start = priv->scan_start;
-
- queue_work(priv->workqueue, &priv->request_scan);
-
- return 0;
-}
-
-
static void iwl_set_flags_for_band(struct iwl_priv *priv,
enum ieee80211_band band)
{
@@ -1191,7 +858,7 @@ static int iwl4965_set_mode(struct iwl_priv *priv, int mode)
return -EAGAIN;

cancel_delayed_work(&priv->scan_check);
- if (iwl4965_scan_cancel_timeout(priv, 100)) {
+ if (iwl_scan_cancel_timeout(priv, 100)) {
IWL_WARNING("Aborted scan still in progress after 100ms\n");
IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
return -EAGAIN;
@@ -1260,7 +927,7 @@ int iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
disable_radio ? "OFF" : "ON");

if (disable_radio) {
- iwl4965_scan_cancel(priv);
+ iwl_scan_cancel(priv);
/* FIXME: This is a workaround for AP */
if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
spin_lock_irqsave(&priv->lock, flags);
@@ -1680,118 +1347,6 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv,
queue_work(priv->workqueue, &priv->beacon_update);
}

-/* Service response to REPLY_SCAN_CMD (0x80) */
-static void iwl4965_rx_reply_scan(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
-#ifdef CONFIG_IWLWIFI_DEBUG
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- struct iwl4965_scanreq_notification *notif =
- (struct iwl4965_scanreq_notification *)pkt->u.raw;
-
- IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status);
-#endif
-}
-
-/* Service SCAN_START_NOTIFICATION (0x82) */
-static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- struct iwl4965_scanstart_notification *notif =
- (struct iwl4965_scanstart_notification *)pkt->u.raw;
- priv->scan_start_tsf = le32_to_cpu(notif->tsf_low);
- IWL_DEBUG_SCAN("Scan start: "
- "%d [802.11%s] "
- "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n",
- notif->channel,
- notif->band ? "bg" : "a",
- notif->tsf_high,
- notif->tsf_low, notif->status, notif->beacon_timer);
-}
-
-/* Service SCAN_RESULTS_NOTIFICATION (0x83) */
-static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- struct iwl4965_scanresults_notification *notif =
- (struct iwl4965_scanresults_notification *)pkt->u.raw;
-
- IWL_DEBUG_SCAN("Scan ch.res: "
- "%d [802.11%s] "
- "(TSF: 0x%08X:%08X) - %d "
- "elapsed=%lu usec (%dms since last)\n",
- notif->channel,
- notif->band ? "bg" : "a",
- le32_to_cpu(notif->tsf_high),
- le32_to_cpu(notif->tsf_low),
- le32_to_cpu(notif->statistics[0]),
- le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf,
- jiffies_to_msecs(elapsed_jiffies
- (priv->last_scan_jiffies, jiffies)));
-
- priv->last_scan_jiffies = jiffies;
- priv->next_scan_jiffies = 0;
-}
-
-/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
-static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv,
- struct iwl_rx_mem_buffer *rxb)
-{
- struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
- struct iwl4965_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
-
- IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n",
- scan_notif->scanned_channels,
- scan_notif->tsf_low,
- scan_notif->tsf_high, scan_notif->status);
-
- /* The HW is no longer scanning */
- clear_bit(STATUS_SCAN_HW, &priv->status);
-
- /* The scan completion notification came in, so kill that timer... */
- cancel_delayed_work(&priv->scan_check);
-
- IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
- (priv->scan_bands == 2) ? "2.4" : "5.2",
- jiffies_to_msecs(elapsed_jiffies
- (priv->scan_pass_start, jiffies)));
-
- /* Remove this scanned band from the list
- * of pending bands to scan */
- priv->scan_bands--;
-
- /* If a request to abort was given, or the scan did not succeed
- * then we reset the scan state machine and terminate,
- * re-queuing another scan if one has been requested */
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_INFO("Aborted scan completed.\n");
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- } else {
- /* If there are more bands on this scan pass reschedule */
- if (priv->scan_bands > 0)
- goto reschedule;
- }
-
- priv->last_scan_jiffies = jiffies;
- priv->next_scan_jiffies = 0;
- IWL_DEBUG_INFO("Setting scan to off\n");
-
- clear_bit(STATUS_SCANNING, &priv->status);
-
- IWL_DEBUG_INFO("Scan took %dms\n",
- jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies)));
-
- queue_work(priv->workqueue, &priv->scan_completed);
-
- return;
-
-reschedule:
- priv->scan_pass_start = jiffies;
- queue_work(priv->workqueue, &priv->request_scan);
-}
-
/* Handle notification from uCode that card's power state is changing
* due to software, hardware, or critical temperature RFKILL */
static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
@@ -1852,7 +1407,7 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
clear_bit(STATUS_RF_KILL_SW, &priv->status);

if (!(flags & RXON_CARD_DISABLED))
- iwl4965_scan_cancel(priv);
+ iwl_scan_cancel(priv);

if ((test_bit(STATUS_RF_KILL_HW, &status) !=
test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
@@ -1902,13 +1457,9 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv)
*/
priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_hw_rx_statistics;
priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_hw_rx_statistics;
- /* scan handlers */
- priv->rx_handlers[REPLY_SCAN_CMD] = iwl4965_rx_reply_scan;
- priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl4965_rx_scan_start_notif;
- priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] =
- iwl4965_rx_scan_results_notif;
- priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
- iwl4965_rx_scan_complete_notif;
+
+ iwl_setup_rx_scan_handlers(priv);
+
/* status change handler */
priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif;

@@ -2456,138 +2007,6 @@ static irqreturn_t iwl4965_isr(int irq, void *data)
return IRQ_NONE;
}

-/* 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)
-
-/* For faster active scanning, scan will move to the next channel if fewer than
- * PLCP_QUIET_THRESH packets are heard on this channel within
- * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
- * time if it's a quiet channel (nothing responded to our probe, and there's
- * 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 */
-
-/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
- * Must be set longer than active dwell time.
- * For the most reliable scan, set > AP beacon interval (typically 100msec). */
-#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */
-#define IWL_PASSIVE_DWELL_TIME_52 (10)
-#define IWL_PASSIVE_DWELL_BASE (100)
-#define IWL_CHANNEL_TUNE_TIME 5
-
-static inline u16 iwl4965_get_active_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band)
-{
- if (band == IEEE80211_BAND_5GHZ)
- return IWL_ACTIVE_DWELL_TIME_52;
- else
- return IWL_ACTIVE_DWELL_TIME_24;
-}
-
-static u16 iwl4965_get_passive_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band)
-{
- u16 active = iwl4965_get_active_dwell_time(priv, band);
- u16 passive = (band != IEEE80211_BAND_5GHZ) ?
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
-
- if (iwl_is_associated(priv)) {
- /* If we're associated, we clamp the maximum passive
- * dwell time to be 98% of the beacon interval (minus
- * 2 * channel tune time) */
- passive = priv->beacon_int;
- if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
- passive = IWL_PASSIVE_DWELL_BASE;
- passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
- }
-
- if (passive <= active)
- passive = active + 1;
-
- return passive;
-}
-
-static int iwl4965_get_channels_for_scan(struct iwl_priv *priv,
- enum ieee80211_band band,
- u8 is_active, u8 direct_mask,
- struct iwl4965_scan_channel *scan_ch)
-{
- const struct ieee80211_channel *channels = NULL;
- const struct ieee80211_supported_band *sband;
- const struct iwl_channel_info *ch_info;
- u16 passive_dwell = 0;
- u16 active_dwell = 0;
- int added, i;
-
- sband = iwl_get_hw_mode(priv, band);
- if (!sband)
- return 0;
-
- channels = sband->channels;
-
- active_dwell = iwl4965_get_active_dwell_time(priv, band);
- passive_dwell = iwl4965_get_passive_dwell_time(priv, band);
-
- for (i = 0, added = 0; i < sband->n_channels; i++) {
- if (channels[i].flags & IEEE80211_CHAN_DISABLED)
- continue;
-
- scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq);
-
- ch_info = iwl_get_channel_info(priv, band,
- scan_ch->channel);
- if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",
- scan_ch->channel);
- continue;
- }
-
- if (!is_active || is_channel_passive(ch_info) ||
- (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))
- scan_ch->type = 0; /* passive */
- else
- scan_ch->type = 1; /* active */
-
- if (scan_ch->type & 1)
- scan_ch->type |= (direct_mask << 1);
-
- scan_ch->active_dwell = cpu_to_le16(active_dwell);
- scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
-
- /* Set txpower levels to defaults */
- scan_ch->tpc.dsp_atten = 110;
- /* scan_pwr_info->tpc.dsp_atten; */
-
- /*scan_pwr_info->tpc.tx_gain; */
- if (band == IEEE80211_BAND_5GHZ)
- scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3;
- else {
- scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3));
- /* NOTE: if we were doing 6Mb OFDM for scans we'd use
- * power level:
- * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3;
- */
- }
-
- IWL_DEBUG_SCAN("Scanning %d [%s %d]\n",
- scan_ch->channel,
- (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE",
- (scan_ch->type & 1) ?
- active_dwell : passive_dwell);
-
- scan_ch++;
- added++;
- }
-
- IWL_DEBUG_SCAN("total channels to scan %d \n", added);
- return added;
-}
-
/******************************************************************************
*
* uCode download functions
@@ -3200,243 +2619,6 @@ static void iwl4965_bg_set_monitor(struct work_struct *work)
mutex_unlock(&priv->mutex);
}

-#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
-
-static void iwl4965_bg_scan_check(struct work_struct *data)
-{
- struct iwl_priv *priv =
- container_of(data, struct iwl_priv, scan_check.work);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
- if (test_bit(STATUS_SCANNING, &priv->status) ||
- test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting "
- "adapter (%dms)\n",
- jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- iwl4965_send_scan_abort(priv);
- }
- mutex_unlock(&priv->mutex);
-}
-
-static void iwl4965_bg_request_scan(struct work_struct *data)
-{
- struct iwl_priv *priv =
- container_of(data, struct iwl_priv, request_scan);
- struct iwl_host_cmd cmd = {
- .id = REPLY_SCAN_CMD,
- .len = sizeof(struct iwl4965_scan_cmd),
- .meta.flags = CMD_SIZE_HUGE,
- };
- struct iwl4965_scan_cmd *scan;
- struct ieee80211_conf *conf = NULL;
- u16 cmd_len;
- enum ieee80211_band band;
- u8 direct_mask;
- int ret = 0;
-
- conf = ieee80211_get_hw_conf(priv->hw);
-
- mutex_lock(&priv->mutex);
-
- if (!iwl_is_ready(priv)) {
- IWL_WARNING("request scan called when driver not ready.\n");
- goto done;
- }
-
- /* Make sure the scan wasn't cancelled before this queued work
- * was given the chance to run... */
- if (!test_bit(STATUS_SCANNING, &priv->status))
- goto done;
-
- /* This should never be called or scheduled if there is currently
- * a scan active in the hardware. */
- if (test_bit(STATUS_SCAN_HW, &priv->status)) {
- IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. "
- "Ignoring second request.\n");
- ret = -EIO;
- goto done;
- }
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
- IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n");
- goto done;
- }
-
- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n");
- goto done;
- }
-
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
- goto done;
- }
-
- if (!test_bit(STATUS_READY, &priv->status)) {
- IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n");
- goto done;
- }
-
- if (!priv->scan_bands) {
- IWL_DEBUG_HC("Aborting scan due to no requested bands\n");
- goto done;
- }
-
- if (!priv->scan) {
- priv->scan = kmalloc(sizeof(struct iwl4965_scan_cmd) +
- IWL_MAX_SCAN_SIZE, GFP_KERNEL);
- if (!priv->scan) {
- ret = -ENOMEM;
- goto done;
- }
- }
- scan = priv->scan;
- memset(scan, 0, sizeof(struct iwl4965_scan_cmd) + IWL_MAX_SCAN_SIZE);
-
- scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
- scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
-
- if (iwl_is_associated(priv)) {
- u16 interval = 0;
- u32 extra;
- u32 suspend_time = 100;
- u32 scan_suspend_time = 100;
- unsigned long flags;
-
- IWL_DEBUG_INFO("Scanning while associated...\n");
-
- spin_lock_irqsave(&priv->lock, flags);
- interval = priv->beacon_int;
- spin_unlock_irqrestore(&priv->lock, flags);
-
- scan->suspend_time = 0;
- scan->max_out_time = cpu_to_le32(200 * 1024);
- if (!interval)
- interval = suspend_time;
-
- extra = (suspend_time / interval) << 22;
- scan_suspend_time = (extra |
- ((suspend_time % interval) * 1024));
- scan->suspend_time = cpu_to_le32(scan_suspend_time);
- IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n",
- scan_suspend_time, interval);
- }
-
- /* We should add the ability for user to lock to PASSIVE ONLY */
- if (priv->one_direct_scan) {
- IWL_DEBUG_SCAN
- ("Kicking off one direct scan for '%s'\n",
- iwl4965_escape_essid(priv->direct_ssid,
- priv->direct_ssid_len));
- scan->direct_scan[0].id = WLAN_EID_SSID;
- 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;
- } else if (!iwl_is_associated(priv) && priv->essid_len) {
- IWL_DEBUG_SCAN
- ("Kicking off one direct scan for '%s' when not associated\n",
- iwl4965_escape_essid(priv->essid, priv->essid_len));
- scan->direct_scan[0].id = WLAN_EID_SSID;
- scan->direct_scan[0].len = priv->essid_len;
- memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
- direct_mask = 1;
- } else {
- IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");
- direct_mask = 0;
- }
-
- scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
- scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
- scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
-
-
- switch (priv->scan_bands) {
- case 2:
- scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
- scan->tx_cmd.rate_n_flags =
- iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,
- RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK);
-
- scan->good_CRC_th = 0;
- band = IEEE80211_BAND_2GHZ;
- break;
-
- case 1:
- scan->tx_cmd.rate_n_flags =
- iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
- RATE_MCS_ANT_B_MSK);
- scan->good_CRC_th = IWL_GOOD_CRC_TH;
- band = IEEE80211_BAND_5GHZ;
- break;
-
- default:
- IWL_WARNING("Invalid scan band count\n");
- goto done;
- }
-
- /* We don't build a direct scan probe request; the uCode will do
- * that based on the direct_mask added to each channel entry */
- cmd_len = iwl4965_fill_probe_req(priv, band,
- (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan), 0);
-
- scan->tx_cmd.len = cpu_to_le16(cmd_len);
- /* select Rx chains */
-
- /* Force use of chains B and C (0x6) for scan Rx.
- * Avoid A (0x1) because of its off-channel reception on A-band.
- * MIMO is not used here, but value is required to make uCode happy. */
- scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |
- cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |
- (0x6 << RXON_RX_CHAIN_FORCE_SEL_POS) |
- (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS));
-
- if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
- scan->filter_flags = RXON_FILTER_PROMISC_MSK;
-
- if (direct_mask)
- scan->channel_count =
- iwl4965_get_channels_for_scan(
- priv, band, 1, /* active */
- direct_mask,
- (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
- else
- scan->channel_count =
- iwl4965_get_channels_for_scan(
- priv, band, 0, /* passive */
- direct_mask,
- (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
-
- scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
- RXON_FILTER_BCON_AWARE_MSK);
- cmd.len += le16_to_cpu(scan->tx_cmd.len) +
- scan->channel_count * sizeof(struct iwl4965_scan_channel);
- cmd.data = scan;
- scan->len = cpu_to_le16(cmd.len);
-
- set_bit(STATUS_SCAN_HW, &priv->status);
- ret = iwl_send_cmd_sync(priv, &cmd);
- if (ret)
- goto done;
-
- queue_delayed_work(priv->workqueue, &priv->scan_check,
- IWL_SCAN_CHECK_WATCHDOG);
-
- mutex_unlock(&priv->mutex);
- return;
-
- done:
- /* inform mac80211 scan aborted */
- queue_work(priv->workqueue, &priv->scan_completed);
- mutex_unlock(&priv->mutex);
-}
-
static void iwl_bg_run_time_calib_work(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv,
@@ -3521,7 +2703,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
if (!priv->vif || !priv->is_open)
return;

- iwl4965_scan_cancel_timeout(priv, 200);
+ iwl_scan_cancel_timeout(priv, 200);

conf = ieee80211_get_hw_conf(priv->hw);

@@ -3615,24 +2797,9 @@ static void iwl4965_bg_post_associate(struct work_struct *data)

}

-static void iwl4965_bg_abort_scan(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
-
- if (!iwl_is_ready(priv))
- return;
-
- mutex_lock(&priv->mutex);
-
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
- iwl4965_send_scan_abort(priv);
-
- mutex_unlock(&priv->mutex);
-}
-
static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);

-static void iwl4965_bg_scan_completed(struct work_struct *work)
+static void iwl_bg_scan_completed(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, scan_completed);
@@ -3759,7 +2926,7 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw)
* RXON_FILTER_ASSOC_MSK BIT
*/
mutex_lock(&priv->mutex);
- iwl4965_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
cancel_delayed_work(&priv->post_associate);
mutex_unlock(&priv->mutex);
}
@@ -4071,7 +3238,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
!is_multicast_ether_addr(conf->bssid)) {
/* If there is currently a HW scan going on in the background
* then we need to cancel it else the RXON below will fail. */
- if (iwl4965_scan_cancel_timeout(priv, 100)) {
+ if (iwl_scan_cancel_timeout(priv, 100)) {
IWL_WARNING("Aborted scan still in progress "
"after 100ms\n");
IWL_DEBUG_MAC80211("leaving - scan abort failed.\n");
@@ -4096,7 +3263,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
}

} else {
- iwl4965_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl4965_commit_rxon(priv);
}
@@ -4154,7 +3321,7 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);

if (iwl_is_ready_rf(priv)) {
- iwl4965_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
cancel_delayed_work(&priv->post_associate);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl4965_commit_rxon(priv);
@@ -4268,7 +3435,7 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
}
if (len) {
IWL_DEBUG_SCAN("direct scan for %s [%d]\n ",
- iwl4965_escape_essid(ssid, len), (int)len);
+ iwl_escape_essid(ssid, len), (int)len);

priv->one_direct_scan = 1;
priv->direct_ssid_len = (u8)
@@ -4277,7 +3444,7 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
} else
priv->one_direct_scan = 0;

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

IWL_DEBUG_MAC80211("leave\n");

@@ -4308,7 +3475,7 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
return;
}

- iwl4965_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);

key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
@@ -4366,7 +3533,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
}

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

/* If we are getting WEP group key and we didn't receive any key mapping
@@ -4562,7 +3729,7 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
* clear RXON_FILTER_ASSOC_MSK bit
*/
if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
- iwl4965_scan_cancel_timeout(priv, 100);
+ iwl_scan_cancel_timeout(priv, 100);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwl4965_commit_rxon(priv);
}
@@ -4759,7 +3926,7 @@ static ssize_t store_flags(struct device *d,
mutex_lock(&priv->mutex);
if (le32_to_cpu(priv->staging_rxon.flags) != flags) {
/* Cancel any currently running scans... */
- if (iwl4965_scan_cancel_timeout(priv, 100))
+ if (iwl_scan_cancel_timeout(priv, 100))
IWL_WARNING("Could not cancel scan.\n");
else {
IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n",
@@ -4794,7 +3961,7 @@ static ssize_t store_filter_flags(struct device *d,
mutex_lock(&priv->mutex);
if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) {
/* Cancel any currently running scans... */
- if (iwl4965_scan_cancel_timeout(priv, 100))
+ if (iwl_scan_cancel_timeout(priv, 100))
IWL_WARNING("Could not cancel scan.\n");
else {
IWL_DEBUG_INFO("Committing rxon.filter_flags = "
@@ -5062,9 +4229,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->up, iwl4965_bg_up);
INIT_WORK(&priv->restart, iwl4965_bg_restart);
INIT_WORK(&priv->rx_replenish, iwl4965_bg_rx_replenish);
- INIT_WORK(&priv->scan_completed, iwl4965_bg_scan_completed);
- INIT_WORK(&priv->request_scan, iwl4965_bg_request_scan);
- INIT_WORK(&priv->abort_scan, iwl4965_bg_abort_scan);
INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update);
INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor);
@@ -5072,7 +4236,10 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
- INIT_DELAYED_WORK(&priv->scan_check, iwl4965_bg_scan_check);
+
+ /* FIXME : remove when resolved PENDING */
+ INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
+ iwl_setup_scan_deferred_work(priv);

if (priv->cfg->ops->lib->setup_deferred_work)
priv->cfg->ops->lib->setup_deferred_work(priv);
--
1.5.3.6


2008-06-12 01:49:41

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 10/29] iwlwifi: remove redundant flags regarding to FAT channel

From: Emmanuel Grumbach <[email protected]>

This patch removes redundant flags regarding to FAT channel. Use
mac80211's flag instead.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.c | 42 ++++++++------------------
drivers/net/wireless/iwlwifi/iwl-dev.h | 14 ---------
drivers/net/wireless/iwlwifi/iwl-eeprom.c | 19 ++++++++----
drivers/net/wireless/iwlwifi/iwl4965-base.c | 6 ++-
include/linux/ieee80211.h | 1 +
5 files changed, 31 insertions(+), 51 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 6c7617c..fad26f7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -478,24 +478,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
if (ch->flags & EEPROM_CHANNEL_RADAR)
geo_ch->flags |= IEEE80211_CHAN_RADAR;

- switch (ch->fat_extension_channel) {
- case HT_IE_EXT_CHANNEL_ABOVE:
- /* only above is allowed, disable below */
- geo_ch->flags |= IEEE80211_CHAN_NO_FAT_BELOW;
- break;
- case HT_IE_EXT_CHANNEL_BELOW:
- /* only below is allowed, disable above */
- geo_ch->flags |= IEEE80211_CHAN_NO_FAT_ABOVE;
- break;
- case HT_IE_EXT_CHANNEL_NONE:
- /* fat not allowed: disable both*/
- geo_ch->flags |= (IEEE80211_CHAN_NO_FAT_ABOVE |
- IEEE80211_CHAN_NO_FAT_BELOW);
- break;
- case HT_IE_EXT_CHANNEL_MAX:
- /* both above and below are permitted */
- break;
- }
+ geo_ch->flags |= ch->fat_extension_channel;

if (ch->max_power_avg > priv->max_channel_txpower_limit)
priv->max_channel_txpower_limit =
@@ -507,7 +490,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
/* Save flags for reg domain usage */
geo_ch->orig_flags = geo_ch->flags;

- IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n",
+ IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
ch->channel, geo_ch->center_freq,
is_channel_a_band(ch) ? "5.2" : "2.4",
geo_ch->flags & IEEE80211_CHAN_DISABLED ?
@@ -552,6 +535,7 @@ static u8 is_single_rx_stream(struct iwl_priv *priv)
(priv->current_ht_config.supp_mcs_set[2] == 0)) ||
priv->ps_mode == IWL_MIMO_PS_STATIC;
}
+
static u8 iwl_is_channel_extension(struct iwl_priv *priv,
enum ieee80211_band band,
u16 channel, u8 extension_chan_offset)
@@ -562,12 +546,12 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv,
if (!is_channel_valid(ch_info))
return 0;

- if (extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE)
- return 0;
-
- if ((ch_info->fat_extension_channel == extension_chan_offset) ||
- (ch_info->fat_extension_channel == HT_IE_EXT_CHANNEL_MAX))
- return 1;
+ if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE)
+ return !(ch_info->fat_extension_channel &
+ IEEE80211_CHAN_NO_FAT_ABOVE);
+ else if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW)
+ return !(ch_info->fat_extension_channel &
+ IEEE80211_CHAN_NO_FAT_BELOW);

return 0;
}
@@ -579,7 +563,7 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,

if ((!iwl_ht_conf->is_ht) ||
(iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) ||
- (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE))
+ (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE))
return 0;

if (sta_ht_inf) {
@@ -619,13 +603,13 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)

/* Note: control channel is opposite of extension channel */
switch (ht_info->extension_chan_offset) {
- case IWL_EXT_CHANNEL_OFFSET_ABOVE:
+ case IEEE80211_HT_IE_CHA_SEC_ABOVE:
rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
break;
- case IWL_EXT_CHANNEL_OFFSET_BELOW:
+ case IEEE80211_HT_IE_CHA_SEC_BELOW:
rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
break;
- case IWL_EXT_CHANNEL_OFFSET_NONE:
+ case IEEE80211_HT_IE_CHA_SEC_NONE:
default:
rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK;
break;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index fa35193..daa14d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -179,15 +179,6 @@ struct iwl4965_scan_power_info {
s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */
};

-/* For fat_extension_channel */
-enum {
- HT_IE_EXT_CHANNEL_NONE = 0,
- HT_IE_EXT_CHANNEL_ABOVE,
- HT_IE_EXT_CHANNEL_INVALID,
- HT_IE_EXT_CHANNEL_BELOW,
- HT_IE_EXT_CHANNEL_MAX
-};
-
/*
* One for each channel, holds all channel setup data
* Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
@@ -782,11 +773,6 @@ struct iwl_kw {
#define IWL_OPERATION_MODE_MIXED 2
#define IWL_OPERATION_MODE_20MHZ 3

-#define IWL_EXT_CHANNEL_OFFSET_NONE 0
-#define IWL_EXT_CHANNEL_OFFSET_ABOVE 1
-#define IWL_EXT_CHANNEL_OFFSET_RESERVE1 2
-#define IWL_EXT_CHANNEL_OFFSET_BELOW 3
-
#define IWL_TX_CRC_SIZE 4
#define IWL_TX_DELIMITER_SIZE 4

diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 11f9d95..cbb812f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -470,6 +470,11 @@ int iwl_init_channel_map(struct iwl_priv *priv)
/* Copy the run-time flags so they are there even on
* invalid channels */
ch_info->flags = eeprom_ch_info[ch].flags;
+ /* First write that fat is not enabled, and then enable
+ * one by one */
+ ch_info->fat_extension_channel =
+ (IEEE80211_CHAN_NO_FAT_ABOVE |
+ IEEE80211_CHAN_NO_FAT_BELOW);

if (!(is_channel_valid(ch_info))) {
IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - "
@@ -534,12 +539,14 @@ int iwl_init_channel_map(struct iwl_priv *priv)
for (ch = 0; ch < eeprom_ch_count; ch++) {

if ((band == 6) &&
- ((eeprom_ch_index[ch] == 5) ||
- (eeprom_ch_index[ch] == 6) ||
- (eeprom_ch_index[ch] == 7)))
- fat_extension_chan = HT_IE_EXT_CHANNEL_MAX;
+ ((eeprom_ch_index[ch] == 5) ||
+ (eeprom_ch_index[ch] == 6) ||
+ (eeprom_ch_index[ch] == 7)))
+ /* both are allowed: above and below */
+ fat_extension_chan = 0;
else
- fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE;
+ fat_extension_chan =
+ IEEE80211_CHAN_NO_FAT_BELOW;

/* Set up driver's info for lower half */
iwl_set_fat_chan_info(priv, ieeeband,
@@ -551,7 +558,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
iwl_set_fat_chan_info(priv, ieeeband,
(eeprom_ch_index[ch] + 4),
&(eeprom_ch_info[ch]),
- HT_IE_EXT_CHANNEL_BELOW);
+ IEEE80211_CHAN_NO_FAT_ABOVE);
}
}

diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 0acd42b..de40e89 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -664,9 +664,11 @@ static void iwl4965_ht_conf(struct iwl_priv *priv,
iwl_conf->extension_chan_offset =
ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
/* If no above or below channel supplied disable FAT channel */
- if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE &&
- iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW)
+ if (iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_ABOVE &&
+ iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_BELOW) {
+ iwl_conf->extension_chan_offset = IEEE80211_HT_IE_CHA_SEC_NONE;
iwl_conf->supported_chan_width = 0;
+ }

iwl_conf->tx_mimo_ps_mode =
(u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 9300f37..8f2c20b 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -320,6 +320,7 @@ struct ieee80211_ht_addt_info {
#define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10
/* 802.11n HT IE masks */
#define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03
+#define IEEE80211_HT_IE_CHA_SEC_NONE 0x00
#define IEEE80211_HT_IE_CHA_SEC_ABOVE 0x01
#define IEEE80211_HT_IE_CHA_SEC_BELOW 0x03
#define IEEE80211_HT_IE_CHA_WIDTH 0x04
--
1.5.3.6


2008-06-12 01:50:03

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 26/29] mac80211 : fix for iwconfig in ad-hoc mode

From: Abhijeet Kolekar <[email protected]>

The patch checks interface status, if it is in IBSS_JOINED mode
show cell id it is associated with.

Signed-off-by: Abhijeet Kolekar <[email protected]>
---
net/mac80211/wext.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 4806d96..5af3862 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -508,7 +508,8 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
- if (sdata->u.sta.state == IEEE80211_ASSOCIATED) {
+ if (sdata->u.sta.state == IEEE80211_ASSOCIATED ||
+ sdata->u.sta.state == IEEE80211_IBSS_JOINED) {
ap_addr->sa_family = ARPHRD_ETHER;
memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
return 0;
--
1.5.3.6


2008-06-12 01:49:37

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 07/29] iwlwifi: use ieee80211_conf to examine rate capabilities

From: Ron Rindjunsky <[email protected]>

This patch switches the use of internal iwlwifi structure with
ieee80211_conf in order to examine ht rate capabilities.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 7f9178b..a928741 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -2245,25 +2245,19 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
* active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
* supp_rates[] does not; shift to convert format, force 9 MBits off.
*/
- lq_sta->active_siso_rate =
- priv->current_ht_config.supp_mcs_set[0] << 1;
- lq_sta->active_siso_rate |=
- priv->current_ht_config.supp_mcs_set[0] & 0x1;
+ lq_sta->active_siso_rate = conf->ht_conf.supp_mcs_set[0] << 1;
+ lq_sta->active_siso_rate |= conf->ht_conf.supp_mcs_set[0] & 0x1;
lq_sta->active_siso_rate &= ~((u16)0x2);
lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;

/* Same here */
- lq_sta->active_mimo2_rate =
- priv->current_ht_config.supp_mcs_set[1] << 1;
- lq_sta->active_mimo2_rate |=
- priv->current_ht_config.supp_mcs_set[1] & 0x1;
+ lq_sta->active_mimo2_rate = conf->ht_conf.supp_mcs_set[1] << 1;
+ lq_sta->active_mimo2_rate |= conf->ht_conf.supp_mcs_set[1] & 0x1;
lq_sta->active_mimo2_rate &= ~((u16)0x2);
lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;

- lq_sta->active_mimo3_rate =
- priv->current_ht_config.supp_mcs_set[2] << 1;
- lq_sta->active_mimo3_rate |=
- priv->current_ht_config.supp_mcs_set[2] & 0x1;
+ lq_sta->active_mimo3_rate = conf->ht_conf.supp_mcs_set[2] << 1;
+ lq_sta->active_mimo3_rate |= conf->ht_conf.supp_mcs_set[2] & 0x1;
lq_sta->active_mimo3_rate &= ~((u16)0x2);
lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;

--
1.5.3.6


2008-06-12 01:49:58

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 22/29] iwlwifi: cleans up scanning code

From: Tomas Winkler <[email protected]>

This patch
1. cleans up scanning code.
2. It adds round robin of TX antannas/chains.

Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-commands.h | 14 +--
drivers/net/wireless/iwlwifi/iwl-core.c | 1 +
drivers/net/wireless/iwlwifi/iwl-core.h | 1 +
drivers/net/wireless/iwlwifi/iwl-dev.h | 33 +-----
drivers/net/wireless/iwlwifi/iwl-scan.c | 178 +++++++++++++++------------
5 files changed, 107 insertions(+), 120 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 058e764..6613d32 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -281,16 +281,7 @@ struct iwl_cmd_header {
#define RATE_MCS_ANT_C_MSK 0x10000
#define RATE_MCS_ANT_ABC_MSK 0x1C000

-
-/**
- * struct iwl4965_tx_power - txpower format used in REPLY_SCAN_CMD
- *
- * Scan uses only one transmitter, so only one analog/dsp gain pair is needed.
- */
-struct iwl4965_tx_power {
- u8 tx_gain; /* gain for analog radio */
- u8 dsp_atten; /* gain for DSP */
-} __attribute__ ((packed));
+#define RATE_MCS_ANT_INIT_IND 1

#define POWER_TABLE_NUM_ENTRIES 33
#define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32
@@ -2128,7 +2119,8 @@ struct iwl_scan_channel {
*/
u8 type;
u8 channel; /* band is selected by iwl4965_scan_cmd "flags" field */
- struct iwl4965_tx_power tpc;
+ u8 tx_gain; /* gain for analog radio */
+ u8 dsp_atten; /* gain for DSP */
__le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */
__le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
} __attribute__ ((packed));
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 7e20f46..9794904 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -874,6 +874,7 @@ int iwl_init_drv(struct iwl_priv *priv)

/* Choose which receivers/antennas to use */
iwl_set_rxon_chain(priv);
+ iwl_init_scan_params(priv);

if (priv->cfg->mod_params->enable_qos)
priv->qos_data.qos_enable = 1;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 2eb08f3..8d9fde6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -267,6 +267,7 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
/*******************************************************************************
* Scanning
******************************************************************************/
+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);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 69765c9..ef74159 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -157,35 +157,11 @@ struct iwl4965_channel_tgh_info {
s64 last_radar_time;
};

-/* current Tx power values to use, one for each rate for each channel.
- * requested power is limited by:
- * -- regulatory EEPROM limits for this channel
- * -- hardware capabilities (clip-powers)
- * -- spectrum management
- * -- user preference (e.g. iwconfig)
- * when requested power is set, base power index must also be set. */
-struct iwl4965_channel_power_info {
- struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */
- s8 power_table_index; /* actual (compenst'd) index into gain table */
- s8 base_power_index; /* gain index for power at factory temp. */
- s8 requested_power; /* power (dBm) requested for this chnl/rate */
-};
-
-/* current scan Tx power values to use, one for each scan rate for each
- * channel. */
-struct iwl4965_scan_power_info {
- struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */
- s8 power_table_index; /* actual (compenst'd) index into gain table */
- s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */
-};
-
/*
* One for each channel, holds all channel setup data
* Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
* with one another!
*/
-#define IWL4965_MAX_RATE (33)
-
struct iwl_channel_info {
struct iwl4965_channel_tgd_info tgd;
struct iwl4965_channel_tgh_info tgh;
@@ -204,11 +180,6 @@ struct iwl_channel_info {
u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */
enum ieee80211_band band;

- /* Radio/DSP gain settings for each "normal" data Tx rate.
- * These include, in addition to RF and DSP gain, a few fields for
- * remembering/modifying gain settings (indexes). */
- struct iwl4965_channel_power_info power_info[IWL4965_MAX_RATE];
-
/* FAT channel info */
s8 fat_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
s8 fat_curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */
@@ -216,9 +187,6 @@ struct iwl_channel_info {
s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */
u8 fat_flags; /* flags copied from EEPROM */
u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */
-
- /* Radio/DSP gain settings for each scan rate, for directed scans. */
- struct iwl4965_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
};

struct iwl4965_clip_group {
@@ -974,6 +942,7 @@ struct iwl_priv {
u8 direct_ssid_len;
u8 direct_ssid[IW_ESSID_MAX_SIZE];
struct iwl_scan_cmd *scan;
+ u32 scan_tx_ant[IEEE80211_NUM_BANDS];

/* spinlock */
spinlock_t lock; /* protect general shared data */
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 7b9475b..5ca181f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -58,7 +58,9 @@
#define IWL_PASSIVE_DWELL_BASE (100)
#define IWL_CHANNEL_TUNE_TIME 5

-
+static int scan_tx_ant[3] = {
+ RATE_MCS_ANT_A_MSK, RATE_MCS_ANT_B_MSK, RATE_MCS_ANT_C_MSK
+};

static int iwl_is_empty_essid(const char *essid, int essid_len)
{
@@ -385,8 +387,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
scan_ch->channel =
ieee80211_frequency_to_channel(channels[i].center_freq);

- ch_info = iwl_get_channel_info(priv, band,
- scan_ch->channel);
+ ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);
if (!is_channel_valid(ch_info)) {
IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",
scan_ch->channel);
@@ -395,9 +396,9 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,

if (!is_active || is_channel_passive(ch_info) ||
(channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))
- scan_ch->type = 0; /* passive */
+ scan_ch->type = 0;
else
- scan_ch->type = 1; /* active */
+ scan_ch->type = 1;

if (scan_ch->type & 1)
scan_ch->type |= (direct_mask << 1);
@@ -406,17 +407,15 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
scan_ch->passive_dwell = cpu_to_le16(passive_dwell);

/* Set txpower levels to defaults */
- scan_ch->tpc.dsp_atten = 110;
- /* scan_pwr_info->tpc.dsp_atten; */
+ scan_ch->dsp_atten = 110;

- /*scan_pwr_info->tpc.tx_gain; */
if (band == IEEE80211_BAND_5GHZ)
- scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3;
+ scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
else {
- scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3));
+ scan_ch->tx_gain = ((1 << 5) | (5 << 3));
/* NOTE: if we were doing 6Mb OFDM for scans we'd use
* power level:
- * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3;
+ * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
*/
}

@@ -434,6 +433,14 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
return added;
}

+void iwl_init_scan_params(struct iwl_priv *priv)
+{
+ if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ])
+ priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = RATE_MCS_ANT_INIT_IND;
+ if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ])
+ priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = RATE_MCS_ANT_INIT_IND;
+}
+
int iwl_scan_initiate(struct iwl_priv *priv)
{
if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
@@ -522,7 +529,7 @@ static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,


static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
- u8 *pos, int *left)
+ u8 *pos, int *left)
{
struct ieee80211_ht_cap *ht_cap;

@@ -547,10 +554,11 @@ static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
/**
* iwl_fill_probe_req - fill in all required fields and IE for probe request
*/
+
static u16 iwl_fill_probe_req(struct iwl_priv *priv,
enum ieee80211_band band,
struct ieee80211_mgmt *frame,
- int left, int is_direct)
+ int left)
{
int len = 0;
u8 *pos = NULL;
@@ -558,12 +566,12 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
const struct ieee80211_supported_band *sband =
iwl_get_hw_mode(priv, band);

+
/* Make sure there is enough space for the probe request,
* two mandatory IEs and the data */
left -= 24;
if (left < 0)
return 0;
- len += 24;

frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);
@@ -571,38 +579,25 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);
frame->seq_ctrl = 0;

- /* fill in our indirect SSID IE */
+ len += 24;
+
/* ...next IE... */
+ pos = &frame->u.probe_req.variable[0];

+ /* fill in our indirect SSID IE */
left -= 2;
if (left < 0)
return 0;
- len += 2;
- pos = &(frame->u.probe_req.variable[0]);
*pos++ = WLAN_EID_SSID;
*pos++ = 0;

- /* fill in our direct SSID IE... */
- if (is_direct) {
- /* ...next IE... */
- left -= 2 + priv->essid_len;
- if (left < 0)
- return 0;
- /* ... fill it in... */
- *pos++ = WLAN_EID_SSID;
- *pos++ = priv->essid_len;
- memcpy(pos, priv->essid, priv->essid_len);
- pos += priv->essid_len;
- len += 2 + priv->essid_len;
- }
+ len += 2;

/* fill in supported rate */
- /* ...next IE... */
left -= 2;
if (left < 0)
return 0;

- /* ... fill it in... */
*pos++ = WLAN_EID_SUPP_RATES;
*pos = 0;

@@ -614,15 +609,16 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,

cck_rates = IWL_CCK_RATES_MASK & active_rates;
ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
- active_rate_basic, &left);
+ active_rate_basic, &left);
active_rates &= ~ret_rates;

ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
- active_rate_basic, &left);
+ active_rate_basic, &left);
active_rates &= ~ret_rates;

len += 2 + *pos;
pos += (*pos) + 1;
+
if (active_rates == 0)
goto fill_end;

@@ -634,27 +630,46 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
/* ... fill it in... */
*pos++ = WLAN_EID_EXT_SUPP_RATES;
*pos = 0;
- iwl_supported_rate_to_ie(pos, active_rates,
- active_rate_basic, &left);
- if (*pos > 0)
+ iwl_supported_rate_to_ie(pos, active_rates, active_rate_basic, &left);
+ if (*pos > 0) {
len += 2 + *pos;
+ pos += (*pos) + 1;
+ } else {
+ pos--;
+ }

fill_end:
- /* fill in HT IE */
+
left -= 2;
if (left < 0)
return 0;

*pos++ = WLAN_EID_HT_CAPABILITY;
*pos = 0;
-
iwl_ht_cap_to_ie(sband, pos, &left);
-
if (*pos > 0)
len += 2 + *pos;
+
return (u16)len;
}

+static u32 iwl_scan_tx_ant(struct iwl_priv *priv, enum ieee80211_band band)
+{
+ int i, ind;
+
+ ind = priv->scan_tx_ant[band];
+ for (i = 0; i < priv->hw_params.tx_chains_num; i++) {
+ ind = (ind+1) >= priv->hw_params.tx_chains_num ? 0 : ind+1;
+ if (priv->hw_params.valid_tx_ant & (1 << ind)) {
+ priv->scan_tx_ant[band] = ind;
+ break;
+ }
+ }
+
+ return scan_tx_ant[ind];
+}
+
+
static void iwl_bg_request_scan(struct work_struct *data)
{
struct iwl_priv *priv =
@@ -666,10 +681,12 @@ static void iwl_bg_request_scan(struct work_struct *data)
};
struct iwl_scan_cmd *scan;
struct ieee80211_conf *conf = NULL;
+ int ret = 0;
+ u32 tx_ant;
u16 cmd_len;
enum ieee80211_band band;
u8 direct_mask;
- int ret = 0;
+ u8 rx_chain = 0x7; /* bitmap: ABC chains */

conf = ieee80211_get_hw_conf(priv->hw);

@@ -761,25 +778,23 @@ static void iwl_bg_request_scan(struct work_struct *data)

/* We should add the ability for user to lock to PASSIVE ONLY */
if (priv->one_direct_scan) {
- IWL_DEBUG_SCAN
- ("Kicking off one direct scan for '%s'\n",
- iwl_escape_essid(priv->direct_ssid,
- priv->direct_ssid_len));
+ IWL_DEBUG_SCAN("Start direct scan for '%s'\n",
+ iwl_escape_essid(priv->direct_ssid,
+ priv->direct_ssid_len));
scan->direct_scan[0].id = WLAN_EID_SSID;
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;
} else if (!iwl_is_associated(priv) && priv->essid_len) {
- IWL_DEBUG_SCAN
- ("Kicking off one direct scan for '%s' when not associated\n",
- iwl_escape_essid(priv->essid, priv->essid_len));
+ IWL_DEBUG_SCAN("Start direct scan for '%s' (not associated)\n",
+ iwl_escape_essid(priv->essid, priv->essid_len));
scan->direct_scan[0].id = WLAN_EID_SSID;
scan->direct_scan[0].len = priv->essid_len;
memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
direct_mask = 1;
} else {
- IWL_DEBUG_SCAN("Kicking off one indirect scan.\n");
+ IWL_DEBUG_SCAN("Start indirect scan.\n");
direct_mask = 0;
}

@@ -790,64 +805,73 @@ static void iwl_bg_request_scan(struct work_struct *data)

switch (priv->scan_bands) {
case 2:
+ band = IEEE80211_BAND_2GHZ;
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
- scan->tx_cmd.rate_n_flags =
+ tx_ant = iwl_scan_tx_ant(priv, band);
+ if (priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK)
+ scan->tx_cmd.rate_n_flags =
+ iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
+ tx_ant);
+ else
+ scan->tx_cmd.rate_n_flags =
iwl_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,
- RATE_MCS_ANT_B_MSK|
+ tx_ant |
RATE_MCS_CCK_MSK);
-
scan->good_CRC_th = 0;
- band = IEEE80211_BAND_2GHZ;
break;

case 1:
+ band = IEEE80211_BAND_5GHZ;
+ tx_ant = iwl_scan_tx_ant(priv, band);
scan->tx_cmd.rate_n_flags =
iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
- RATE_MCS_ANT_B_MSK);
+ tx_ant);
scan->good_CRC_th = IWL_GOOD_CRC_TH;
- band = IEEE80211_BAND_5GHZ;
- break;

+ /* 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;
+
+ break;
default:
IWL_WARNING("Invalid scan band count\n");
goto done;
}

- /* We don't build a direct scan probe request; the uCode will do
- * that based on the direct_mask added to each channel entry */
+ 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) |
+ (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS));
+
cmd_len = iwl_fill_probe_req(priv, band,
- (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan), 0);
+ (struct ieee80211_mgmt *)scan->data,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan));

scan->tx_cmd.len = cpu_to_le16(cmd_len);
- /* select Rx chains */
-
- /* Force use of chains B and C (0x6) for scan Rx.
- * Avoid A (0x1) because of its off-channel reception on A-band.
- * MIMO is not used here, but value is required to make uCode happy. */
- scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |
- cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |
- (0x6 << RXON_RX_CHAIN_FORCE_SEL_POS) |
- (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS));

if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
scan->filter_flags = RXON_FILTER_PROMISC_MSK;

+ scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
+ RXON_FILTER_BCON_AWARE_MSK);
+
if (direct_mask)
scan->channel_count =
- iwl_get_channels_for_scan(
- priv, band, 1, /* active */
- direct_mask,
+ iwl_get_channels_for_scan(priv, band, 1, /* active */
+ direct_mask,
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
else
scan->channel_count =
- iwl_get_channels_for_scan(
- priv, band, 0, /* passive */
- direct_mask,
+ iwl_get_channels_for_scan(priv, band, 0, /* passive */
+ direct_mask,
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ if (scan->channel_count == 0) {
+ IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count);
+ goto done;
+ }

- scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
- RXON_FILTER_BCON_AWARE_MSK);
cmd.len += le16_to_cpu(scan->tx_cmd.len) +
scan->channel_count * sizeof(struct iwl_scan_channel);
cmd.data = scan;
--
1.5.3.6


2008-06-13 01:30:32

by Zhu Yi

[permalink] [raw]
Subject: Re: [PATCH 00/29] iwlwifi driver 06/12 updates

On Thu, 2008-06-12 at 10:00 -0400, John W. Linville wrote:
> I'll add your S-o-b if you would like?

Yeah, please.

Thanks,
-yi


2008-06-12 01:49:29

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 01/29] iwlwifi: removing IWL4965_HT config

From: Ron Rindjunsky <[email protected]>

This patch removes CONFIG_IWL4965_HT #ifdefs for iwl 4965 and 5000. 11n
feature is stable in those drivers and its mode of operation is determined
in mac80211, so this dependency is not needed any more.

Signed-off-by: Ron Rindjunsky <[email protected]>
---
drivers/net/wireless/iwlwifi/Kconfig | 8 ---
drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 46 +-------------------
drivers/net/wireless/iwlwifi/iwl-4965.c | 62 +++++++++------------------
drivers/net/wireless/iwlwifi/iwl-5000.c | 44 +++++++++----------
drivers/net/wireless/iwlwifi/iwl-core.c | 18 --------
drivers/net/wireless/iwlwifi/iwl-core.h | 4 --
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 4 --
drivers/net/wireless/iwlwifi/iwl-dev.h | 14 ------
drivers/net/wireless/iwlwifi/iwl-sta.c | 10 ----
drivers/net/wireless/iwlwifi/iwl-tx.c | 10 ----
drivers/net/wireless/iwlwifi/iwl4965-base.c | 23 +---------
11 files changed, 43 insertions(+), 200 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 5f3e849..b992428 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -54,14 +54,6 @@ config IWL4965
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl4965.ko.

-config IWL4965_HT
- bool "Enable 802.11n HT features in iwl4965 driver"
- depends on EXPERIMENTAL
- depends on IWL4965
- ---help---
- This option enables IEEE 802.11n High Throughput features
- for the iwl4965 driver.
-
config IWL4965_LEDS
bool "Enable LEDS features in iwl4965 driver"
depends on IWL4965
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index d8f2b4d..7f9178b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -105,8 +105,6 @@ struct iwl4965_scale_tbl_info {
struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
};

-#ifdef CONFIG_IWL4965_HT
-
struct iwl4965_traffic_load {
unsigned long time_stamp; /* age of the oldest statistics */
u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time
@@ -118,8 +116,6 @@ struct iwl4965_traffic_load {
u8 head; /* start of the circular buffer */
};

-#endif /* CONFIG_IWL4965_HT */
-
/**
* struct iwl4965_lq_sta -- driver's rate scaling private structure
*
@@ -157,16 +153,12 @@ struct iwl4965_lq_sta {

struct iwl_link_quality_cmd lq;
struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
-#ifdef CONFIG_IWL4965_HT
struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT];
u8 tx_agg_tid_en;
-#endif
#ifdef CONFIG_MAC80211_DEBUGFS
struct dentry *rs_sta_dbgfs_scale_table_file;
struct dentry *rs_sta_dbgfs_stats_table_file;
-#ifdef CONFIG_IWL4965_HT
struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
-#endif
u32 dbg_fixed_rate;
#endif
struct iwl_priv *drv;
@@ -256,7 +248,6 @@ static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
return ((ant_type & valid_antenna) == ant_type);
}

-#ifdef CONFIG_IWL4965_HT
/*
* removes the old data from the statistics. All data that is older than
* TID_MAX_TIME_DIFF, will be deleted.
@@ -389,8 +380,6 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
}

-#endif /* CONFIG_IWLWIFI_HT */
-
static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
{
return (!!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
@@ -626,7 +615,6 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,

/* FIXME:RS: in 4965 we don't use greenfield at all */
/* FIXME:RS: don't use greenfield for now in TX */
-/* #ifdef CONFIG_IWL4965_HT */
#if 0
static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
{
@@ -634,12 +622,11 @@ static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf
priv->current_ht_config.is_green_field &&
!priv->current_ht_config.non_GF_STA_present);
}
-#else
+#endif
static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
{
return 0;
}
-#endif /* CONFIG_IWL4965_HT */

/**
* rs_get_supported_rates - get the available rates
@@ -1050,7 +1037,6 @@ static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
tbl->expected_tpt = expected_tpt_G;
}

-#ifdef CONFIG_IWL4965_HT
/*
* Find starting rate for new "search" high-throughput mode of modulation.
* Goal is to find lowest expected rate (under perfect conditions) that is
@@ -1152,12 +1138,10 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,

return new_rate;
}
-#endif /* CONFIG_IWL4965_HT */

/*
* Set up search table for MIMO
*/
-#ifdef CONFIG_IWL4965_HT
static int rs_switch_to_mimo2(struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta,
struct ieee80211_conf *conf,
@@ -1221,16 +1205,6 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
tbl->current_rate, is_green);
return 0;
}
-#else
-static int rs_switch_to_mimo2(struct iwl_priv *priv,
- struct iwl4965_lq_sta *lq_sta,
- struct ieee80211_conf *conf,
- struct sta_info *sta,
- struct iwl4965_scale_tbl_info *tbl, int index)
-{
- return -1;
-}
-#endif /*CONFIG_IWL4965_HT */

/*
* Set up search table for SISO
@@ -1241,7 +1215,6 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
struct sta_info *sta,
struct iwl4965_scale_tbl_info *tbl, int index)
{
-#ifdef CONFIG_IWL4965_HT
u16 rate_mask;
u8 is_green = lq_sta->is_green;
s32 rate;
@@ -1291,9 +1264,6 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",
tbl->current_rate, is_green);
return 0;
-#else
- return -1;
-#endif /*CONFIG_IWL4965_HT */
}

/*
@@ -1689,9 +1659,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
u8 done_search = 0;
u16 high_low;
s32 sr;
-#ifdef CONFIG_IWL4965_HT
u8 tid = MAX_TID_COUNT;
-#endif

IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");

@@ -1712,9 +1680,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
}
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;

-#ifdef CONFIG_IWL4965_HT
rs_tl_add_packet(lq_sta, hdr);
-#endif
/*
* Select rate-scale / modulation-mode table to work with in
* the rest of this function: "search" if searching for better
@@ -2013,9 +1979,7 @@ lq_update:
* before next round of mode comparisons. */
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
if (is_legacy(tbl1->lq_type) &&
-#ifdef CONFIG_IWL4965_HT
(!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) &&
-#endif
(lq_sta->action_counter >= 1)) {
lq_sta->action_counter = 0;
IWL_DEBUG_RATE("LQ: STAY in legacy table\n");
@@ -2027,14 +1991,12 @@ lq_update:
* mode for a while before next round of mode comparisons. */
if (lq_sta->enable_counter &&
(lq_sta->action_counter >= IWL_ACTION_LIMIT)) {
-#ifdef CONFIG_IWL4965_HT
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != MAX_TID_COUNT)) {
IWL_DEBUG_RATE("try to aggregate tid %d\n", tid);
rs_tl_turn_on_agg(priv, tid, lq_sta, sta);
}
-#endif /*CONFIG_IWL4965_HT */
lq_sta->action_counter = 0;
rs_set_stay_in_table(priv, 0, lq_sta);
}
@@ -2279,7 +2241,6 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
lq_sta->active_rate_basic = priv->active_rate_basic;
lq_sta->band = priv->band;
-#ifdef CONFIG_IWL4965_HT
/*
* active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
* supp_rates[] does not; shift to convert format, force 9 MBits off.
@@ -2317,7 +2278,6 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,

/* as default allow aggregation for all tids */
lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
-#endif /*CONFIG_IWL4965_HT*/
#ifdef CONFIG_MAC80211_DEBUGFS
lq_sta->drv = priv;
#endif
@@ -2635,11 +2595,9 @@ static void rs_add_debugfs(void *priv, void *priv_sta,
lq_sta->rs_sta_dbgfs_stats_table_file =
debugfs_create_file("rate_stats_table", 0600, dir,
lq_sta, &rs_sta_dbgfs_stats_table_ops);
-#ifdef CONFIG_IWL4965_HT
lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
debugfs_create_u8("tx_agg_tid_enable", 0600, dir,
&lq_sta->tx_agg_tid_en);
-#endif

}

@@ -2648,9 +2606,7 @@ static void rs_remove_debugfs(void *priv, void *priv_sta)
struct iwl4965_lq_sta *lq_sta = priv_sta;
debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
-#ifdef CONFIG_IWL4965_HT
debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
-#endif
}
#endif

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index aee7014..84414da 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2819,7 +2819,6 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv,
break;

case IEEE80211_FTYPE_CTL:
-#ifdef CONFIG_IWL4965_HT
switch (fc & IEEE80211_FCTL_STYPE) {
case IEEE80211_STYPE_BACK_REQ:
IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n");
@@ -2829,7 +2828,6 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv,
default:
break;
}
-#endif
break;

case IEEE80211_FTYPE_DATA: {
@@ -2863,8 +2861,6 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv,
}
}

-#ifdef CONFIG_IWL4965_HT
-
/**
* iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack
*
@@ -3154,10 +3150,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
return 0;
}

-#endif /* CONFIG_IWL4965_HT */
-
-
-#ifdef CONFIG_IWL4965_HT
static int iwl4965_rx_agg_start(struct iwl_priv *priv,
const u8 *addr, int tid, u16 ssn)
{
@@ -3231,8 +3223,6 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
}
return 0;
}
-#endif /* CONFIG_IWL4965_HT */
-

static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len)
{
@@ -3262,7 +3252,6 @@ static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
return (u16)sizeof(struct iwl4965_addsta_cmd);
}

-#ifdef CONFIG_IWL4965_HT
static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
{
__le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status +
@@ -3388,7 +3377,6 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
}
return 0;
}
-#endif

/**
* iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response
@@ -3404,12 +3392,10 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
struct ieee80211_tx_info *info;
struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le32_to_cpu(tx_resp->status);
-#ifdef CONFIG_IWL4965_HT
int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
u16 fc;
struct ieee80211_hdr *hdr;
u8 *qc = NULL;
-#endif

if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
@@ -3422,7 +3408,6 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
memset(&info->status, 0, sizeof(info->status));

-#ifdef CONFIG_IWL4965_HT
hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
fc = le16_to_cpu(hdr->frame_control);
if (ieee80211_is_qos_data(fc)) {
@@ -3474,32 +3459,31 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
}
} else {
-#endif /* CONFIG_IWL4965_HT */
-
- info->status.retry_count = tx_resp->failure_frame;
- info->flags |= iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
- iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
- info);
-
- IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x "
- "retries %d\n", txq_id, iwl_get_tx_fail_reason(status),
- status, le32_to_cpu(tx_resp->rate_n_flags),
- tx_resp->failure_frame);
-
- IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
-#ifdef CONFIG_IWL4965_HT
- if (index != -1) {
- int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
- if (tid != MAX_TID_COUNT)
+ info->status.retry_count = tx_resp->failure_frame;
+ info->flags |=
+ iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
+ iwl4965_hwrate_to_tx_control(priv,
+ le32_to_cpu(tx_resp->rate_n_flags),
+ info);
+
+ IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags "
+ "0x%x retries %d\n", txq_id,
+ iwl_get_tx_fail_reason(status),
+ status, le32_to_cpu(tx_resp->rate_n_flags),
+ tx_resp->failure_frame);
+
+ IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
+ if (index != -1) {
+ int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
+ if (tid != MAX_TID_COUNT)
priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
- if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
+ if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
(txq_id >= 0) && priv->mac80211_registered)
ieee80211_wake_queue(priv->hw, txq_id);
- if (tid != MAX_TID_COUNT)
+ if (tid != MAX_TID_COUNT)
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+ }
}
- }
-#endif /* CONFIG_IWL4965_HT */

if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
@@ -3513,10 +3497,8 @@ static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
priv->rx_handlers[REPLY_RX] = iwl4965_rx_reply_rx;
/* Tx response */
priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
-
-#ifdef CONFIG_IWL4965_HT
+ /* block ack */
priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba;
-#endif /* CONFIG_IWL4965_HT */
}

void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv)
@@ -3558,10 +3540,8 @@ static struct iwl_lib_ops iwl4965_lib = {
.shared_mem_rx_idx = iwl4965_shared_mem_rx_idx,
.txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl,
.txq_set_sched = iwl4965_txq_set_sched,
-#ifdef CONFIG_IWL4965_HT
.txq_agg_enable = iwl4965_txq_agg_enable,
.txq_agg_disable = iwl4965_txq_agg_disable,
-#endif
.rx_handler_setup = iwl4965_rx_handler_setup,
.is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr,
.alive_notify = iwl4965_alive_notify,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 7e525ad..6548477 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1136,12 +1136,10 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
struct ieee80211_tx_info *info;
struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le16_to_cpu(tx_resp->status.status);
-#ifdef CONFIG_IWL4965_HT
int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
u16 fc;
struct ieee80211_hdr *hdr;
u8 *qc = NULL;
-#endif

if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
@@ -1154,7 +1152,6 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
memset(&info->status, 0, sizeof(info->status));

-#ifdef CONFIG_IWL4965_HT
hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
fc = le16_to_cpu(hdr->frame_control);
if (ieee80211_is_qos_data(fc)) {
@@ -1205,32 +1202,31 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
}
} else {
-#endif /* CONFIG_IWL4965_HT */
-
- info->status.retry_count = tx_resp->failure_frame;
- info->flags = iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
- iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
- info);
-
- IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x "
- "retries %d\n", txq_id, iwl_get_tx_fail_reason(status),
- status, le32_to_cpu(tx_resp->rate_n_flags),
- tx_resp->failure_frame);
-
- IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
-#ifdef CONFIG_IWL4965_HT
- if (index != -1) {
- int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
- if (tid != MAX_TID_COUNT)
+ info->status.retry_count = tx_resp->failure_frame;
+ info->flags =
+ iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
+ iwl4965_hwrate_to_tx_control(priv,
+ le32_to_cpu(tx_resp->rate_n_flags),
+ info);
+
+ IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags "
+ "0x%x retries %d\n", txq_id,
+ iwl_get_tx_fail_reason(status),
+ status, le32_to_cpu(tx_resp->rate_n_flags),
+ tx_resp->failure_frame);
+
+ IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
+ if (index != -1) {
+ int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
+ if (tid != MAX_TID_COUNT)
priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
- if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
+ if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
(txq_id >= 0) && priv->mac80211_registered)
ieee80211_wake_queue(priv->hw, txq_id);
- if (tid != MAX_TID_COUNT)
+ if (tid != MAX_TID_COUNT)
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+ }
}
- }
-#endif /* CONFIG_IWL4965_HT */

if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 61716ba..6c7617c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -321,7 +321,6 @@ void iwl_reset_qos(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_reset_qos);

-#ifdef CONFIG_IWL4965_HT
#define MAX_BIT_RATE_40_MHZ 0x96; /* 150 Mbps */
#define MAX_BIT_RATE_20_MHZ 0x48; /* 72 Mbps */
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
@@ -374,13 +373,6 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
ht_info->supp_mcs_set[12] |= ((tx_chains_num - 1) << 2);
}
}
-#else
-static inline void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
- struct ieee80211_ht_info *ht_info,
- enum ieee80211_band band)
-{
-}
-#endif /* CONFIG_IWL4965_HT */

static void iwlcore_init_hw_rates(struct iwl_priv *priv,
struct ieee80211_rate *rates)
@@ -553,7 +545,6 @@ static void iwlcore_free_geos(struct iwl_priv *priv)
clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
}

-#ifdef CONFIG_IWL4965_HT
static u8 is_single_rx_stream(struct iwl_priv *priv)
{
return !priv->current_ht_config.is_ht ||
@@ -660,13 +651,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
}
EXPORT_SYMBOL(iwl_set_rxon_ht);

-#else
-static inline u8 is_single_rx_stream(struct iwl_priv *priv)
-{
- return 1;
-}
-#endif /*CONFIG_IWL4965_HT */
-
/*
* Determine how many receiver/antenna chains to use.
* More provides better reception via diversity. Fewer saves power.
@@ -791,10 +775,8 @@ int iwl_setup_mac(struct iwl_priv *priv)
IEEE80211_HW_NOISE_DBM;
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
-#ifdef CONFIG_IWL4965_HT
/* Enhanced value; more queues, to support 11n aggregation */
hw->ampdu_queues = 12;
-#endif /* CONFIG_IWL4965_HT */

hw->conf.beacon_int = 100;

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 6b5af7a..d9c5bd1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -111,13 +111,11 @@ struct iwl_lib_ops {
void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
-#ifdef CONFIG_IWL4965_HT
/* aggregations */
int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
int sta_id, int tid, u16 ssn_idx);
int (*txq_agg_disable)(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx,
u8 tx_fifo);
-#endif /* CONFIG_IWL4965_HT */
/* setup Rx handler */
void (*rx_handler_setup)(struct iwl_priv *priv);
/* alive notification after init uCode load */
@@ -233,11 +231,9 @@ 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);
-#ifdef CONFIG_IWL4965_HT
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);
int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
-#endif

/*****************************************************
* 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-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 29e16ba..d5f9df1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -255,21 +255,18 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n");
pos += scnprintf(buf + pos, bufsz - pos,
"seq_num\t\ttxq_id");
-#ifdef CONFIG_IWL4965_HT
pos += scnprintf(buf + pos, bufsz - pos,
"\tframe_count\twait_for_ba\t");
pos += scnprintf(buf + pos, bufsz - pos,
"start_idx\tbitmap0\t");
pos += scnprintf(buf + pos, bufsz - pos,
"bitmap1\trate_n_flags");
-#endif
pos += scnprintf(buf + pos, bufsz - pos, "\n");

for (j = 0; j < MAX_TID_COUNT; j++) {
pos += scnprintf(buf + pos, bufsz - pos,
"[%d]:\t\t%u", j,
station->tid[j].seq_number);
-#ifdef CONFIG_IWL4965_HT
pos += scnprintf(buf + pos, bufsz - pos,
"\t%u\t\t%u\t\t%u\t\t",
station->tid[j].agg.txq_id,
@@ -280,7 +277,6 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
station->tid[j].agg.start_idx,
(unsigned long long)station->tid[j].agg.bitmap,
station->tid[j].agg.rate_n_flags);
-#endif
pos += scnprintf(buf + pos, bufsz - pos, "\n");
}
pos += scnprintf(buf + pos, bufsz - pos, "\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 802f1a1..59a6960 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -401,7 +401,6 @@ struct iwl_rx_queue {
#define IWL_INVALID_RATE 0xFF
#define IWL_INVALID_VALUE -1

-#ifdef CONFIG_IWL4965_HT
/**
* struct iwl_ht_agg -- aggregation status while waiting for block-ack
* @txq_id: Tx queue used for Tx attempt
@@ -430,14 +429,11 @@ struct iwl_ht_agg {
u8 state;
};

-#endif /* CONFIG_IWL4965_HT */

struct iwl_tid_data {
u16 seq_number;
u16 tfds_in_queue;
-#ifdef CONFIG_IWL4965_HT
struct iwl_ht_agg agg;
-#endif /* CONFIG_IWL4965_HT */
};

struct iwl_hw_key {
@@ -752,7 +748,6 @@ extern void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv,
u32 rate_n_flags,
struct ieee80211_tx_info *info);

-#ifdef CONFIG_IWL4965_HT
extern void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,
struct ieee80211_ht_info *ht_info,
enum ieee80211_band band);
@@ -763,12 +758,7 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
const u8 *addr, u16 tid, u16 *ssn);
int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id,
u8 tid, int txq_id);
-#else
-static inline void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,
- struct ieee80211_ht_info *ht_info,
- enum ieee80211_band band) {}

-#endif /*CONFIG_IWL4965_HT */
/* Structures, enum, and defines specific to the 4965 */

#define IWL_KW_SIZE 0x1000 /*4k */
@@ -1073,9 +1063,7 @@ struct iwl_priv {
__le16 sensitivity_tbl[HD_TABLE_SIZE];
#endif /*CONFIG_IWLWIFI_RUN_TIME_CALIB*/

-#ifdef CONFIG_IWL4965_HT
struct iwl_ht_info current_ht_config;
-#endif
u8 last_phy_res[100];

/* Rate scaling data */
@@ -1250,7 +1238,6 @@ static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
#endif


-#ifdef CONFIG_IWL4965_HT
static inline int iwl_get_ra_sta_id(struct iwl_priv *priv,
struct ieee80211_hdr *hdr)
{
@@ -1270,7 +1257,6 @@ static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv,
txb[idx].skb[0]->data;
return NULL;
}
-#endif


static inline int iwl_is_associated(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 983f107..b3caed4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -156,8 +156,6 @@ int iwl_send_add_sta(struct iwl_priv *priv,
}
EXPORT_SYMBOL(iwl_send_add_sta);

-#ifdef CONFIG_IWL4965_HT
-
static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
struct ieee80211_ht_info *sta_ht_inf)
{
@@ -202,12 +200,6 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
done:
return;
}
-#else
-static inline void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
- struct ieee80211_ht_info *sta_ht_info)
-{
-}
-#endif

/**
* iwl_add_station_flags - Add station to tables in driver and device
@@ -842,7 +834,6 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
u8 sta_id;

/* Add station to device's station table */
-#ifdef CONFIG_IWL4965_HT
struct ieee80211_conf *conf = &priv->hw->conf;
struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf;

@@ -852,7 +843,6 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
sta_id = iwl_add_station_flags(priv, addr, is_ap,
0, cur_ht_config);
else
-#endif /* CONFIG_IWL4965_HT */
sta_id = iwl_add_station_flags(priv, addr, is_ap,
0, NULL);

diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index cfe6f4b..1aa19f4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -36,8 +36,6 @@
#include "iwl-io.h"
#include "iwl-helpers.h"

-#ifdef CONFIG_IWL4965_HT
-
static const u16 default_tid_to_tx_fifo[] = {
IWL_TX_FIFO_AC1,
IWL_TX_FIFO_AC0,
@@ -58,9 +56,6 @@ static const u16 default_tid_to_tx_fifo[] = {
IWL_TX_FIFO_AC3
};

-#endif /*CONFIG_IWL4965_HT */
-
-

/**
* iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
@@ -848,12 +843,10 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
(hdr->seq_ctrl &
__constant_cpu_to_le16(IEEE80211_SCTL_FRAG));
seq_number += 0x10;
-#ifdef CONFIG_IWL4965_HT
/* aggregation is on for this <sta,tid> */
if (info->flags & IEEE80211_TX_CTL_AMPDU)
txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
priv->stations[sta_id].tid[tid].tfds_in_queue++;
-#endif /* CONFIG_IWL4965_HT */
}

/* Descriptor for chosen Tx queue */
@@ -1196,8 +1189,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
}
EXPORT_SYMBOL(iwl_tx_cmd_complete);

-
-#ifdef CONFIG_IWL4965_HT
/*
* Find first available (lowest unused) Tx Queue, mark it "active".
* Called only when finding queue for aggregation.
@@ -1359,7 +1350,6 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
return 0;
}
EXPORT_SYMBOL(iwl_txq_check_empty);
-#endif /* CONFIG_IWL4965_HT */

#ifdef CONFIG_IWLWIF_DEBUG
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index c71daec..88229e2 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -634,7 +634,6 @@ static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate,
return ret_rates;
}

-#ifdef CONFIG_IWL4965_HT
static void iwl4965_ht_conf(struct iwl_priv *priv,
struct ieee80211_bss_conf *bss_conf)
{
@@ -707,17 +706,6 @@ static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
IEEE80211_HT_CAP_AMPDU_DENSITY);
*left -= sizeof(struct ieee80211_ht_cap);
}
-#else
-static inline void iwl4965_ht_conf(struct iwl_priv *priv,
- struct ieee80211_bss_conf *bss_conf)
-{
-}
-static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
- u8 *pos, int *left)
-{
-}
-#endif
-

/**
* iwl4965_fill_probe_req - fill in all required fields and IE for probe request
@@ -862,10 +850,8 @@ static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force)
priv->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_UPDATE_EDCA_MSK;

-#ifdef CONFIG_IWL4965_HT
if (priv->current_ht_config.is_ht)
priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
-#endif /* CONFIG_IWL4965_HT */

spin_unlock_irqrestore(&priv->lock, flags);

@@ -3515,10 +3501,9 @@ static void iwl4965_post_associate(struct iwl_priv *priv)

priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;

-#ifdef CONFIG_IWL4965_HT
if (priv->current_ht_config.is_ht)
iwl_set_rxon_ht(priv, &priv->current_ht_config);
-#endif /* CONFIG_IWL4965_HT*/
+
iwl_set_rxon_chain(priv);
priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);

@@ -3854,7 +3839,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co

spin_lock_irqsave(&priv->lock, flags);

-#ifdef CONFIG_IWL4965_HT
/* if we are switching from ht to 2.4 clear flags
* from any ht related info since 2.4 does not
* support ht */
@@ -3864,7 +3848,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
#endif
)
priv->staging_rxon.flags = 0;
-#endif /* CONFIG_IWL4965_HT */

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

@@ -4489,11 +4472,9 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211("enter\n");

priv->lq_mngr.lq_ready = 0;
-#ifdef CONFIG_IWL4965_HT
spin_lock_irqsave(&priv->lock, flags);
memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
spin_unlock_irqrestore(&priv->lock, flags);
-#endif /* CONFIG_IWL4965_HT */

iwl_reset_qos(priv);

@@ -5100,9 +5081,7 @@ static struct ieee80211_ops iwl4965_hw_ops = {
.reset_tsf = iwl4965_mac_reset_tsf,
.beacon_update = iwl4965_mac_beacon_update,
.bss_info_changed = iwl4965_bss_info_changed,
-#ifdef CONFIG_IWL4965_HT
.ampdu_action = iwl4965_mac_ampdu_action,
-#endif /* CONFIG_IWL4965_HT */
.hw_scan = iwl4965_mac_hw_scan
};

--
1.5.3.6


2008-06-12 01:49:57

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 21/29] iwlwifi: move rate helpers to iwlcore

From: Tomas Winkler <[email protected]>

This patch moves rate helpers to iwlcore.

Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 13 -----
drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 8 +--
drivers/net/wireless/iwlwifi/iwl-4965-rs.h | 2 -
drivers/net/wireless/iwlwifi/iwl-4965.c | 79 ++++-----------------------
drivers/net/wireless/iwlwifi/iwl-5000.c | 14 ++---
drivers/net/wireless/iwlwifi/iwl-core.c | 57 +++++++++++++++++++
drivers/net/wireless/iwlwifi/iwl-core.h | 21 +++++++
drivers/net/wireless/iwlwifi/iwl-dev.h | 3 -
drivers/net/wireless/iwlwifi/iwl-scan.c | 9 ++--
drivers/net/wireless/iwlwifi/iwl-sta.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-tx.c | 2 +-
drivers/net/wireless/iwlwifi/iwl4965-base.c | 2 +-
12 files changed, 106 insertions(+), 106 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index 721f505..10f630e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -793,19 +793,6 @@ enum {

/********************* END TXPOWER *****************************************/

-static inline u8 iwl4965_hw_get_rate(__le32 rate_n_flags)
-{
- return le32_to_cpu(rate_n_flags) & 0xFF;
-}
-static inline u32 iwl4965_hw_get_rate_n_flags(__le32 rate_n_flags)
-{
- return le32_to_cpu(rate_n_flags) & 0x1FFFF;
-}
-static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags)
-{
- return cpu_to_le32(flags|(u16)rate);
-}
-

/**
* Tx/Rx Queues
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 77884e1..b9a4e4b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -536,7 +536,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
u8 mcs;

- *rate_idx = iwl4965_hwrate_to_plcp_idx(rate_n_flags);
+ *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);

if (*rate_idx == IWL_RATE_INVALID) {
*rate_idx = -1;
@@ -1811,8 +1811,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
tbl = &(lq_sta->lq_info[active_tbl]);

/* Revert to "active" rate and throughput info */
- index = iwl4965_hwrate_to_plcp_idx(
- tbl->current_rate);
+ index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
current_tpt = lq_sta->last_tpt;

/* Need to set up a new rate table in uCode */
@@ -1966,8 +1965,7 @@ lq_update:
rs_rate_scale_clear_window(&(tbl->win[i]));

/* Use new "search" start rate */
- index = iwl4965_hwrate_to_plcp_idx(
- tbl->current_rate);
+ index = iwl_hwrate_to_plcp_idx(tbl->current_rate);

IWL_DEBUG_RATE("Switch current mcs: %X index: %d\n",
tbl->current_rate, index);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
index 1dd4124..cbd1264 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
@@ -286,8 +286,6 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
return rate;
}

-extern int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags);
-
/**
* iwl4965_fill_rs_info - Fill an output text buffer with the rate representation
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 1b8dc2d..87648d0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -307,60 +307,6 @@ static int is_fat_channel(__le32 rxon_flags)
(rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK);
}

-int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags)
-{
- int idx = 0;
-
- /* 4965 HT rate format */
- if (rate_n_flags & RATE_MCS_HT_MSK) {
- idx = (rate_n_flags & 0xff);
-
- if (idx >= IWL_RATE_MIMO2_6M_PLCP)
- idx = idx - IWL_RATE_MIMO2_6M_PLCP;
-
- idx += IWL_FIRST_OFDM_RATE;
- /* skip 9M not supported in ht*/
- if (idx >= IWL_RATE_9M_INDEX)
- idx += 1;
- if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
- return idx;
-
- /* 4965 legacy rate format, search for match in table */
- } else {
- for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
- if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
- return idx;
- }
-
- return -1;
-}
-
-/**
- * translate ucode response to mac80211 tx status control values
- */
-void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
- struct ieee80211_tx_info *control)
-{
- int rate_index;
-
- control->antenna_sel_tx =
- ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
- if (rate_n_flags & RATE_MCS_HT_MSK)
- control->flags |= IEEE80211_TX_CTL_OFDM_HT;
- if (rate_n_flags & RATE_MCS_GF_MSK)
- control->flags |= IEEE80211_TX_CTL_GREEN_FIELD;
- if (rate_n_flags & RATE_MCS_FAT_MSK)
- control->flags |= IEEE80211_TX_CTL_40_MHZ_WIDTH;
- if (rate_n_flags & RATE_MCS_DUP_MSK)
- control->flags |= IEEE80211_TX_CTL_DUP_DATA;
- if (rate_n_flags & RATE_MCS_SGI_MSK)
- control->flags |= IEEE80211_TX_CTL_SHORT_GI;
- rate_index = iwl4965_hwrate_to_plcp_idx(rate_n_flags);
- if (control->band == IEEE80211_BAND_5GHZ)
- rate_index -= IWL_FIRST_OFDM_RATE;
- control->tx_rate_idx = rate_index;
-}
-
/*
* EEPROM handlers
*/
@@ -1796,10 +1742,10 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,

if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
tx_beacon_cmd->tx.rate_n_flags =
- iwl4965_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
+ iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
else
tx_beacon_cmd->tx.rate_n_flags =
- iwl4965_hw_set_rate_n_flags(rate, 0);
+ iwl_hw_set_rate_n_flags(rate, 0);

tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK);
@@ -2568,7 +2514,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv,
else
title = "Frame";

- rate_idx = iwl4965_hwrate_to_plcp_idx(rate_sym);
+ rate_idx = iwl_hwrate_to_plcp_idx(rate_sym);
if (unlikely(rate_idx == -1))
bitrate = 0;
else
@@ -2633,7 +2579,7 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv,
rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
rx_status.rate_idx =
- iwl4965_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags));
+ iwl_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags));
if (rx_status.band == IEEE80211_BAND_5GHZ)
rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;

@@ -2842,7 +2788,7 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv,
info->flags |= IEEE80211_TX_STAT_AMPDU;
info->status.ampdu_ack_map = successes;
info->status.ampdu_ack_len = agg->frame_count;
- iwl4965_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
+ iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info);

IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);

@@ -3189,15 +3135,15 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
struct agg_tx_status *frame_status = tx_resp->u.agg_status;
struct ieee80211_tx_info *info = NULL;
struct ieee80211_hdr *hdr = NULL;
+ u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
int i, sh, idx;
u16 seq;
-
if (agg->wait_for_ba)
IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");

agg->frame_count = tx_resp->frame_count;
agg->start_idx = start_idx;
- agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
+ agg->rate_n_flags = rate_n_flags;
agg->bitmap = 0;

/* # frames attempted by Tx command */
@@ -3215,15 +3161,12 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
info->flags |= iwl_is_tx_success(status)?
IEEE80211_TX_STAT_ACK : 0;
- iwl4965_hwrate_to_tx_control(priv,
- le32_to_cpu(tx_resp->rate_n_flags),
- info);
+ iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
/* FIXME: code repetition end */

IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
status & 0xff, tx_resp->failure_frame);
- IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n",
- iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags));
+ IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);

agg->wait_for_ba = 0;
} else {
@@ -3281,7 +3224,6 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,

agg->bitmap = bitmap;
agg->start_idx = start;
- agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
agg->frame_count, agg->start_idx,
(unsigned long long)agg->bitmap);
@@ -3375,7 +3317,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
info->status.retry_count = tx_resp->failure_frame;
info->flags |=
iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
- iwl4965_hwrate_to_tx_control(priv,
+ iwl_hwrate_to_tx_control(priv,
le32_to_cpu(tx_resp->rate_n_flags),
info);

@@ -3386,6 +3328,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
tx_resp->failure_frame);

IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
+
if (index != -1) {
int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
if (tid != MAX_TID_COUNT)
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index da8750b..8c466b0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1139,6 +1139,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
struct agg_tx_status *frame_status = &tx_resp->status;
struct ieee80211_tx_info *info = NULL;
struct ieee80211_hdr *hdr = NULL;
+ u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
int i, sh, idx;
u16 seq;

@@ -1147,7 +1148,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,

agg->frame_count = tx_resp->frame_count;
agg->start_idx = start_idx;
- agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
+ agg->rate_n_flags = rate_n_flags;
agg->bitmap = 0;

/* # frames attempted by Tx command */
@@ -1165,15 +1166,13 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
info->flags |= iwl_is_tx_success(status)?
IEEE80211_TX_STAT_ACK : 0;
- iwl4965_hwrate_to_tx_control(priv,
- le32_to_cpu(tx_resp->rate_n_flags),
- info);
+ iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
+
/* FIXME: code repetition end */

IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
status & 0xff, tx_resp->failure_frame);
- IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n",
- iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags));
+ IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);

agg->wait_for_ba = 0;
} else {
@@ -1231,7 +1230,6 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,

agg->bitmap = bitmap;
agg->start_idx = start;
- agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
agg->frame_count, agg->start_idx,
(unsigned long long)agg->bitmap);
@@ -1322,7 +1320,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
info->status.retry_count = tx_resp->failure_frame;
info->flags =
iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
- iwl4965_hwrate_to_tx_control(priv,
+ iwl_hwrate_to_tx_control(priv,
le32_to_cpu(tx_resp->rate_n_flags),
info);

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 164697a..7e20f46 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -85,6 +85,63 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
};
EXPORT_SYMBOL(iwl_rates);

+/**
+ * translate ucode response to mac80211 tx status control values
+ */
+void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
+ struct ieee80211_tx_info *control)
+{
+ int rate_index;
+
+ control->antenna_sel_tx =
+ ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
+ if (rate_n_flags & RATE_MCS_HT_MSK)
+ control->flags |= IEEE80211_TX_CTL_OFDM_HT;
+ if (rate_n_flags & RATE_MCS_GF_MSK)
+ control->flags |= IEEE80211_TX_CTL_GREEN_FIELD;
+ if (rate_n_flags & RATE_MCS_FAT_MSK)
+ control->flags |= IEEE80211_TX_CTL_40_MHZ_WIDTH;
+ if (rate_n_flags & RATE_MCS_DUP_MSK)
+ control->flags |= IEEE80211_TX_CTL_DUP_DATA;
+ if (rate_n_flags & RATE_MCS_SGI_MSK)
+ control->flags |= IEEE80211_TX_CTL_SHORT_GI;
+ rate_index = iwl_hwrate_to_plcp_idx(rate_n_flags);
+ if (control->band == IEEE80211_BAND_5GHZ)
+ rate_index -= IWL_FIRST_OFDM_RATE;
+ control->tx_rate_idx = rate_index;
+}
+EXPORT_SYMBOL(iwl_hwrate_to_tx_control);
+
+int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
+{
+ int idx = 0;
+
+ /* HT rate format */
+ if (rate_n_flags & RATE_MCS_HT_MSK) {
+ idx = (rate_n_flags & 0xff);
+
+ if (idx >= IWL_RATE_MIMO2_6M_PLCP)
+ idx = idx - IWL_RATE_MIMO2_6M_PLCP;
+
+ idx += IWL_FIRST_OFDM_RATE;
+ /* skip 9M not supported in ht*/
+ if (idx >= IWL_RATE_9M_INDEX)
+ idx += 1;
+ if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
+ return idx;
+
+ /* legacy rate format, search for match in table */
+ } else {
+ for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
+ if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
+ return idx;
+ }
+
+ return -1;
+}
+EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
+
+

const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
EXPORT_SYMBOL(iwl_bcast_addr);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 5837577..2eb08f3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -244,6 +244,27 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);

/*******************************************************************************
+ * Rate
+ ******************************************************************************/
+
+void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
+ struct ieee80211_tx_info *info);
+int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
+
+static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
+{
+ return le32_to_cpu(rate_n_flags) & 0xFF;
+}
+static inline u32 iwl_hw_get_rate_n_flags(__le32 rate_n_flags)
+{
+ return le32_to_cpu(rate_n_flags) & 0x1FFFF;
+}
+static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
+{
+ return cpu_to_le32(flags|(u32)rate);
+}
+
+/*******************************************************************************
* Scanning
******************************************************************************/
int iwl_scan_cancel(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index e586987..69765c9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -733,9 +733,6 @@ extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv,
extern int iwl4965_alive_notify(struct iwl_priv *priv);
extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode);
extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);
-extern void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv,
- u32 rate_n_flags,
- struct ieee80211_tx_info *info);

extern void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,
struct ieee80211_ht_info *ht_info,
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index c2ed7c1..7b9475b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -792,8 +792,9 @@ static void iwl_bg_request_scan(struct work_struct *data)
case 2:
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
scan->tx_cmd.rate_n_flags =
- iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,
- RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK);
+ iwl_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,
+ RATE_MCS_ANT_B_MSK|
+ RATE_MCS_CCK_MSK);

scan->good_CRC_th = 0;
band = IEEE80211_BAND_2GHZ;
@@ -801,8 +802,8 @@ static void iwl_bg_request_scan(struct work_struct *data)

case 1:
scan->tx_cmd.rate_n_flags =
- iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
- RATE_MCS_ANT_B_MSK);
+ iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
+ RATE_MCS_ANT_B_MSK);
scan->good_CRC_th = IWL_GOOD_CRC_TH;
band = IEEE80211_BAND_5GHZ;
break;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 3e257cf..fae5d6d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -824,7 +824,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 1aa19f4..e804bf8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -696,7 +696,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,

tx_cmd->rts_retry_limit = rts_retry_limit;
tx_cmd->data_retry_limit = data_retry_limit;
- tx_cmd->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags);
+ tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags);
}

static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 4183bd5..2073ba6 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1331,7 +1331,7 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv,
#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status);
- u8 rate = iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
+ u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);

IWL_DEBUG_RX("beacon status %x retries %d iss %d "
"tsf %d %d rate %d\n",
--
1.5.3.6


2008-06-12 01:49:47

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 14/29] iwlwifi: fix resart flow after fw error

From: Emmanuel Grumbach <[email protected]>

Clear STATUS_FW_ERROR in the _up_ flow before reseting NIC.
UP flow will otherwise call restart again causing endless restart loop.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 7a9567c..3f54dec 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -2857,9 +2857,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
/* After the ALIVE response, we can send host commands to 4965 uCode */
set_bit(STATUS_ALIVE, &priv->status);

- /* Clear out the uCode error bit if it is set */
- clear_bit(STATUS_FW_ERROR, &priv->status);
-
if (iwl_is_rfkill(priv))
return;

@@ -3099,6 +3096,9 @@ static int __iwl4965_up(struct iwl_priv *priv)
continue;
}

+ /* Clear out the uCode error bit if it is set */
+ clear_bit(STATUS_FW_ERROR, &priv->status);
+
/* start card; "initialize" will load runtime ucode */
iwl4965_nic_start(priv);

--
1.5.3.6


2008-06-12 01:49:45

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 13/29] iwlwifi: fix resume SW RF-kill

From: Mohamed Abbas <[email protected]>

This patch fixes SW RF-kill. If we resumed from S3 state with SW RF-kill
set, the driver wouldn't be able to remove SW RF-kill. This patch fixes
this.

Signed-off-by: Mohamed Abbas <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +-
drivers/net/wireless/iwlwifi/iwl4965-base.c | 31 +++++++++++++--------------
3 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index a86e08b..b4c9d5d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -129,7 +129,7 @@ struct iwl_lib_ops {
/* 1st ucode load */
int (*load_ucode)(struct iwl_priv *priv);
/* rfkill */
- void (*radio_kill_sw)(struct iwl_priv *priv, int disable_radio);
+ int (*radio_kill_sw)(struct iwl_priv *priv, int disable_radio);
/* power management */
struct {
int (*init)(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index ac68cce..54e6ac8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -725,7 +725,7 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)

struct iwl_priv;

-extern void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio);
+extern int iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio);
/*
* Forward declare iwl-4965.c functions for iwl-base.c
*/
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index de40e89..7a9567c 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1260,12 +1260,12 @@ static void iwl4965_set_rate(struct iwl_priv *priv)
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
}

-void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
+int iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
{
unsigned long flags;

if (!!disable_radio == test_bit(STATUS_RF_KILL_SW, &priv->status))
- return;
+ return 0;

IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO %s\n",
disable_radio ? "OFF" : "ON");
@@ -1290,7 +1290,7 @@ void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw);
}
- return;
+ return 0;
}

spin_lock_irqsave(&priv->lock, flags);
@@ -1311,11 +1311,11 @@ void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
IWL_DEBUG_RF_KILL("Can not turn radio back on - "
"disabled by HW switch\n");
- return;
+ return 0;
}

queue_work(priv->workqueue, &priv->restart);
- return;
+ return 1;
}

#define IWL_PACKET_RETRY_TIME HZ
@@ -3028,13 +3028,6 @@ static int __iwl4965_up(struct iwl_priv *priv)
return -EIO;
}

- if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
- IWL_WARNING("Radio disabled by SW RF kill (module "
- "parameter)\n");
- iwl_rfkill_set_hw_state(priv);
- return -ENODEV;
- }
-
if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
IWL_ERROR("ucode not available for device bringup\n");
return -EIO;
@@ -3088,7 +3081,8 @@ static int __iwl4965_up(struct iwl_priv *priv)
priv->ucode_data.len);

/* We return success when we resume from suspend and rf_kill is on. */
- if (test_bit(STATUS_RF_KILL_HW, &priv->status))
+ if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
+ test_bit(STATUS_RF_KILL_SW, &priv->status))
return 0;

for (i = 0; i < MAX_HW_RESTARTS; i++) {
@@ -3115,6 +3109,7 @@ static int __iwl4965_up(struct iwl_priv *priv)

set_bit(STATUS_EXIT_PENDING, &priv->status);
__iwl4965_down(priv);
+ clear_bit(STATUS_EXIT_PENDING, &priv->status);

/* tried to restart and config the device for as long as our
* patience could withstand */
@@ -3860,6 +3855,13 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co

priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);

+
+ if (priv->cfg->ops->lib->radio_kill_sw &&
+ priv->cfg->ops->lib->radio_kill_sw(priv, !conf->radio_enabled)) {
+ IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n");
+ mutex_unlock(&priv->mutex);
+ }
+
if (!iwl_is_ready(priv)) {
IWL_DEBUG_MAC80211("leave - not ready\n");
ret = -EIO;
@@ -3912,9 +3914,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
}
#endif

- if (priv->cfg->ops->lib->radio_kill_sw)
- priv->cfg->ops->lib->radio_kill_sw(priv, !conf->radio_enabled);
-
if (!conf->radio_enabled) {
IWL_DEBUG_MAC80211("leave - radio disabled\n");
goto out;
--
1.5.3.6


2008-06-12 01:50:00

by Zhu Yi

[permalink] [raw]
Subject: [PATCH 24/29] iwlwifi: retfactor get_temperature functions

From: Emmanuel Grumbach <[email protected]>

This patch renames iwl4965_get_tempearture to iwl4965_hw_get_temperature
and replaces usage of original iwl4965_hw_get_temperature by
direct access to priv->temperature.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 24 +++++++++---------------
drivers/net/wireless/iwlwifi/iwl-core.h | 1 -
drivers/net/wireless/iwlwifi/iwl-dev.h | 1 -
drivers/net/wireless/iwlwifi/iwl4965-base.c | 2 +-
4 files changed, 10 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index aeb29b9..6e6038f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -47,6 +47,7 @@
#include "iwl-sta.h"

static int iwl4965_send_tx_power(struct iwl_priv *priv);
+static int iwl4965_hw_get_temperature(const struct iwl_priv *priv);

/* module parameters */
static struct iwl_mod_params iwl4965_mod_params = {
@@ -283,7 +284,7 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv)
}

/* Calculate temperature */
- priv->temperature = iwl4965_get_temperature(priv);
+ priv->temperature = iwl4965_hw_get_temperature(priv);

/* Send pointers to protocol/runtime uCode image ... init code will
* load and launch runtime uCode, which will send us another "Alive"
@@ -1691,11 +1692,6 @@ static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
return le32_to_cpu(s->rb_closed) & 0xFFF;
}

-int iwl4965_hw_get_temperature(struct iwl_priv *priv)
-{
- return priv->temperature;
-}
-
unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl_frame *frame, u8 rate)
{
@@ -1793,12 +1789,12 @@ static s32 sign_extend(u32 oper, int index)
}

/**
- * iwl4965_get_temperature - return the calibrated temperature (in Kelvin)
+ * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin)
* @statistics: Provides the temperature reading from the uCode
*
* A return of <0 indicates bogus data in the statistics
*/
-int iwl4965_get_temperature(const struct iwl_priv *priv)
+static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
{
s32 temperature;
s32 vt;
@@ -1833,8 +1829,7 @@ int iwl4965_get_temperature(const struct iwl_priv *priv)
vt = sign_extend(
le32_to_cpu(priv->statistics.general.temperature), 23);

- IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n",
- R1, R2, R3, vt);
+ IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);

if (R3 == R1) {
IWL_ERROR("Calibration conflict R1 == R3\n");
@@ -1845,11 +1840,10 @@ int iwl4965_get_temperature(const struct iwl_priv *priv)
* Add offset to center the adjustment around 0 degrees Centigrade. */
temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2);
temperature /= (R3 - R1);
- temperature = (temperature * 97) / 100 +
- TEMPERATURE_CALIB_KELVIN_OFFSET;
+ temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET;

- IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n", temperature,
- KELVIN_TO_CELSIUS(temperature));
+ IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n",
+ temperature, KELVIN_TO_CELSIUS(temperature));

return temperature;
}
@@ -1977,7 +1971,7 @@ void iwl4965_hw_rx_statistics(struct iwl_priv *priv,
if (!change)
return;

- temp = iwl4965_get_temperature(priv);
+ temp = iwl4965_hw_get_temperature(priv);
if (temp < 0)
return;

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 59dd342..054ab7c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -359,7 +359,6 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
return iwl_is_ready(priv);
}

-
enum iwlcore_card_notify {
IWLCORE_INIT_EVT = 0,
IWLCORE_START_EVT = 1,
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index ef74159..7001854 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -643,7 +643,6 @@ extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv);
extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv);
extern int iwl_rxq_stop(struct iwl_priv *priv);
extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
-extern int iwl4965_hw_get_temperature(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_hw_build_tx_cmd_rate(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 3717f99..14d4432 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -3867,7 +3867,7 @@ static ssize_t show_temperature(struct device *d,
if (!iwl_is_alive(priv))
return -EAGAIN;

- return sprintf(buf, "%d\n", iwl4965_hw_get_temperature(priv));
+ return sprintf(buf, "%d\n", priv->temperature);
}

static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
--
1.5.3.6