From efa3144e7cb2a7a58961e5b881b1b9ef73f39cd5 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 22 Feb 2011 16:43:05 -0800 Subject: [PATCH 01/12] iwlegacy: MAINTAINERS Add iwlegacy driver to MAINTAINERS file and mark as 'Orphan' Signed-off-by: Wey-Yi Guy --- MAINTAINERS | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 95482e9e5ba5..12698b3e3caa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3322,6 +3322,16 @@ F: Documentation/wimax/README.i2400m F: drivers/net/wimax/i2400m/ F: include/linux/wimax/i2400m.h +INTEL PRO/WIRELESS 3945ABG/BG NETWORK CONNECTION SUPPORT +L: linux-wireless@vger.kernel.org +S: Orphan +F: drivers/net/wireless/iwlegacy/ + +INTEL WIRELESS WIFI 4965AGN NETWORK CONNECTION SUPPORT +L: linux-wireless@vger.kernel.org +S: Orphan +F: drivers/net/wireless/iwlegacy/ + INTEL WIRELESS WIFI LINK (iwlwifi) M: Wey-Yi Guy M: Intel Linux Wireless From d103e3448a3ecb9f81babd1f6d7f5a678e213c82 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Thu, 10 Mar 2011 03:17:16 -0800 Subject: [PATCH 02/12] iwlagn: use 6030 configuration for 6035 series 6035 series of devices should use the same uCode as 6030 series, change it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-2000.c | 31 ------------------------- drivers/net/wireless/iwlwifi/iwl-6000.c | 16 +++++++++++++ 2 files changed, 16 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index d7b6126408c9..b1dbe93a88b0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -471,37 +471,6 @@ struct iwl_cfg iwl2030_2bg_cfg = { IWL_DEVICE_2030, }; -#define IWL_DEVICE_6035 \ - .fw_name_pre = IWL2030_FW_PRE, \ - .ucode_api_max = IWL2030_UCODE_API_MAX, \ - .ucode_api_min = IWL2030_UCODE_API_MIN, \ - .eeprom_ver = EEPROM_6035_EEPROM_VERSION, \ - .eeprom_calib_ver = EEPROM_6035_TX_POWER_VERSION, \ - .ops = &iwl2030_ops, \ - .mod_params = &iwlagn_mod_params, \ - .base_params = &iwl2030_base_params, \ - .bt_params = &iwl2030_bt_params, \ - .need_dc_calib = true, \ - .need_temp_offset_calib = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true \ - -struct iwl_cfg iwl6035_2agn_cfg = { - .name = "2000 Series 2x2 AGN/BT", - IWL_DEVICE_6035, - .ht_params = &iwl2000_ht_params, -}; - -struct iwl_cfg iwl6035_2abg_cfg = { - .name = "2000 Series 2x2 ABG/BT", - IWL_DEVICE_6035, -}; - -struct iwl_cfg iwl6035_2bg_cfg = { - .name = "2000 Series 2x2 BG/BT", - IWL_DEVICE_6035, -}; - #define IWL_DEVICE_200 \ .fw_name_pre = IWL200_FW_PRE, \ .ucode_api_max = IWL200_UCODE_API_MAX, \ diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index a745b01c0ec1..40e022617527 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -613,6 +613,22 @@ struct iwl_cfg iwl6030_2bg_cfg = { IWL_DEVICE_6030, }; +struct iwl_cfg iwl6035_2agn_cfg = { + .name = "6035 Series 2x2 AGN/BT", + IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, +}; + +struct iwl_cfg iwl6035_2abg_cfg = { + .name = "6035 Series 2x2 ABG/BT", + IWL_DEVICE_6030, +}; + +struct iwl_cfg iwl6035_2bg_cfg = { + .name = "6035 Series 2x2 BG/BT", + IWL_DEVICE_6030, +}; + struct iwl_cfg iwl1030_bgn_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", IWL_DEVICE_6030, From 7ffef13d7a24654292c4641450f2794224b9eb5d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 15 Mar 2011 04:59:10 -0700 Subject: [PATCH 03/12] iwlagn: clean up TX aggregation code Since the driver split, there's no need for function pointers any more for aggregation queue setup and teardown as all devices now share the same code. Simplify this. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-6000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 17 +++++++---------- drivers/net/wireless/iwlwifi/iwl-agn.h | 4 ---- drivers/net/wireless/iwlwifi/iwl-core.h | 5 ----- 7 files changed, 7 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index e8e1c2dc8659..9631d8fa802a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -179,8 +179,6 @@ static struct iwl_lib_ops iwl1000_lib = { .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index b1dbe93a88b0..55274a14af01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -259,8 +259,6 @@ static struct iwl_lib_ops iwl2000_lib = { .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 90e727b1b4c1..4064490e3b96 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -348,8 +348,6 @@ static struct iwl_lib_ops iwl5000_lib = { .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, @@ -416,8 +414,6 @@ static struct iwl_lib_ops iwl5150_lib = { .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 40e022617527..7ecfbbc9457a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -288,8 +288,6 @@ static struct iwl_lib_ops iwl6000_lib = { .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, @@ -357,8 +355,6 @@ static struct iwl_lib_ops iwl6030_lib = { .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, .txq_set_sched = iwlagn_txq_set_sched, - .txq_agg_enable = iwlagn_txq_agg_enable, - .txq_agg_disable = iwlagn_txq_agg_disable, .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, .txq_free_tfd = iwl_hw_txq_free_tfd, .txq_init = iwl_hw_tx_queue_init, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index a709d05c5868..23e5667108e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -222,8 +222,8 @@ void iwlagn_tx_queue_set_status(struct iwl_priv *priv, scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); } -int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, - int tx_fifo, int sta_id, int tid, u16 ssn_idx) +static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, + int tx_fifo, int sta_id, int tid, u16 ssn_idx) { unsigned long flags; u16 ra_tid; @@ -288,8 +288,8 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, return 0; } -int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, - u16 ssn_idx, u8 tx_fifo) +static int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, + u16 ssn_idx, u8 tx_fifo) { if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || (IWLAGN_FIRST_AMPDU_QUEUE + @@ -1037,8 +1037,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id); spin_unlock_irqrestore(&priv->sta_lock, flags); - ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo, - sta_id, tid, *ssn); + ret = iwlagn_txq_agg_enable(priv, txq_id, tx_fifo, sta_id, tid, *ssn); if (ret) return ret; @@ -1125,8 +1124,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, * to deactivate the uCode queue, just return "success" to allow * mac80211 to clean up it own data. */ - priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, - tx_fifo_id); + iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo_id); spin_unlock_irqrestore(&priv->lock, flags); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); @@ -1155,8 +1153,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, u16 ssn = SEQ_TO_SN(tid_data->seq_number); int tx_fifo = get_fifo_from_tid(ctx, tid); IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n"); - priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, - ssn, tx_fifo); + iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo); tid_data->agg.state = IWL_AGG_OFF; ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 20f8e4188994..8d918ea36c61 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -133,10 +133,6 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv, u16 byte_cnt); void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, struct iwl_tx_queue *txq); -int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, - int tx_fifo, int sta_id, int tid, u16 ssn_idx); -int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, - u16 ssn_idx, u8 tx_fifo); void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); void iwl_free_tfds_in_queue(struct iwl_priv *priv, int sta_id, int tid, int freed); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index b316d833d9a2..1f4f6dd18009 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -171,11 +171,6 @@ struct iwl_lib_ops { struct iwl_tx_queue *txq); int (*txq_init)(struct iwl_priv *priv, struct iwl_tx_queue *txq); - /* 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); /* setup Rx handler */ void (*rx_handler_setup)(struct iwl_priv *priv); /* setup deferred work */ From c8823ec1337017e23b99fb0814e2f3d62537f811 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 15 Mar 2011 11:33:03 -0700 Subject: [PATCH 04/12] iwlagn: fix aggregation queue scheduler setup iwlagn's hardware scheduler needs to be set up with the right aggregation frame limit and buffer sizes. To achieve this, we need to move the hardware queue setup to when the session becomes operational. Tested-by: Daniel Halperin Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 47 +++++++++++++++-------- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++ drivers/net/wireless/iwlwifi/iwl-agn.h | 3 ++ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 23e5667108e2..fb63a03a395e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -222,13 +222,8 @@ void iwlagn_tx_queue_set_status(struct iwl_priv *priv, scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); } -static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, - int tx_fifo, int sta_id, int tid, u16 ssn_idx) +static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int sta_id, int tid) { - unsigned long flags; - u16 ra_tid; - int ret; - if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { @@ -240,12 +235,33 @@ static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, return -EINVAL; } - ra_tid = BUILD_RAxTID(sta_id, tid); - /* Modify device's station table to Tx this TID */ - ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); - if (ret) - return ret; + return iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); +} + +void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv, + struct ieee80211_sta *sta, + int tid, int frame_limit) +{ + int sta_id, tx_fifo, txq_id, ssn_idx; + u16 ra_tid; + unsigned long flags; + struct iwl_tid_data *tid_data; + + sta_id = iwl_sta_id(sta); + if (WARN_ON(sta_id == IWL_INVALID_STATION)) + return; + if (WARN_ON(tid >= MAX_TID_COUNT)) + return; + + spin_lock_irqsave(&priv->sta_lock, flags); + tid_data = &priv->stations[sta_id].tid[tid]; + ssn_idx = SEQ_TO_SN(tid_data->seq_number); + txq_id = tid_data->agg.txq_id; + tx_fifo = tid_data->agg.tx_fifo; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + ra_tid = BUILD_RAxTID(sta_id, tid); spin_lock_irqsave(&priv->lock, flags); @@ -271,10 +287,10 @@ static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, iwl_write_targ_mem(priv, priv->scd_base_addr + IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), - ((SCD_WIN_SIZE << + ((frame_limit << IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | - ((SCD_FRAME_LIMIT << + ((frame_limit << IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); @@ -284,8 +300,6 @@ static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); spin_unlock_irqrestore(&priv->lock, flags); - - return 0; } static int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, @@ -1034,10 +1048,11 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, tid_data = &priv->stations[sta_id].tid[tid]; *ssn = SEQ_TO_SN(tid_data->seq_number); tid_data->agg.txq_id = txq_id; + tid_data->agg.tx_fifo = tx_fifo; iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id); spin_unlock_irqrestore(&priv->sta_lock, flags); - ret = iwlagn_txq_agg_enable(priv, txq_id, tx_fifo, sta_id, tid, *ssn); + ret = iwlagn_txq_agg_enable(priv, txq_id, sta_id, tid); if (ret) return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b57fbbf3fb64..8fdd1746c102 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3345,6 +3345,10 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, } break; case IEEE80211_AMPDU_TX_OPERATIONAL: + buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF); + + iwlagn_txq_agg_queue_setup(priv, sta, tid, buf_size); + /* * If the limit is 0, then it wasn't initialised yet, * use the default. We can do that since we take the diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 8d918ea36c61..4f7c9ce9d8bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -202,6 +202,9 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid, u16 *ssn); int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid); +void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv, + struct ieee80211_sta *sta, + int tid, int frame_limit); int iwlagn_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 68b953f2bdc7..a5d438d91821 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -416,6 +416,7 @@ struct iwl_ht_agg { #define IWL_EMPTYING_HW_QUEUE_ADDBA 2 #define IWL_EMPTYING_HW_QUEUE_DELBA 3 u8 state; + u8 tx_fifo; }; From 374920cb0512f5938fdf1f5af4f9afa7502dd0f9 Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Wed, 16 Mar 2011 19:16:36 -0700 Subject: [PATCH 05/12] iwlwifi: limit number of attempts for highest HT rate When filling out its rate scale table, iwlwifi repeats the first HT rate IWL_HT_NUMBER_TRY times. The hardware scheduler will stop using aggregation for any frame that fails LINK_QUAL_AGG_DISABLE_START_DEF times. Currently, both these constants equal 3. If iwlwifi probes a faster rate than the link supports, all frames in a (potentially tens of frames large) batch will fail IWL_HT_NUMBER_TRY times. Because this happens to be as large as LINK_QUAL_AGG_DISABLE_START_DEF, all frames will then be sent individually. This leads to a short, but performance-degrading window where the legacy stop-and-wait MAC takes over. Bounding the initial rate by (LINK_QUAL_AGG_DISABLE_START_DEF-1) attempts makes the third try use a lower rate and hence more be likely to succeed. This somewhat mitigates the above described behavior. Signed-off-by: Daniel Halperin Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index d03b4734c892..63b58ecb0dc6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -2912,7 +2912,8 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, ant_toggle_cnt = 1; repeat_rate = IWL_NUMBER_TRY; } else { - repeat_rate = IWL_HT_NUMBER_TRY; + repeat_rate = min(IWL_HT_NUMBER_TRY, + LINK_QUAL_AGG_DISABLE_START_DEF - 1); } lq_cmd->general_params.mimo_delimiter = From d0eb633431ec922f8f9b2040f46d9b42a4cec193 Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Wed, 16 Mar 2011 17:17:36 -0700 Subject: [PATCH 06/12] iwlwifi: cleanup and bugfix tx aggregation code Since the driver split, there's no need for no_agg_framecnt_info since all devices have this set to false. Secondly, the compressed block ack handling code was broken. Fix this. (1) A shift less than zero simply implies that the buffer wrapped, this is expected. Remove the incorrect comment. (2) The (agg->frame_count > (64-sh)) condition can happen if the last frame is dropped. E.g., if I send 7 frames and the 6th is received but the 7th is lost, the other side may only shift the window 6, not 7 frames since the last bit is a 0. This is perfectly fine behavior and doesn't invalidate the feedback. (3) Store the feedback from a Compressed BA in the first newly received frame, rather than the start of the window. This way it will get processed by the rate selection code. Feedback stored in a non-received frame is likely to get overwritten by the retransmission. This is based on the approach taken by minstrel_ht. Signed-off-by: Daniel Halperin Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 82 ++++++++--------------- drivers/net/wireless/iwlwifi/iwl-core.h | 3 - 2 files changed, 27 insertions(+), 58 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index fb63a03a395e..cb8eacd5fdb5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1263,11 +1263,11 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, struct iwl_compressed_ba_resp *ba_resp) { - int i, sh, ack; + int sh; u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl); u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); - int successes = 0; struct ieee80211_tx_info *info; + u64 bitmap, sent_bitmap; if (unlikely(!agg->wait_for_ba)) { if (unlikely(ba_resp->bitmap)) @@ -1281,70 +1281,42 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, /* Calculate shift to align block-ack bits with our Tx window bits */ sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4); - if (sh < 0) /* tbw something is wrong with indices */ + if (sh < 0) sh += 0x100; - if (agg->frame_count > (64 - sh)) { - IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size"); - return -1; - } - if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) { + /* + * Check for success or failure according to the + * transmitted bitmap and block-ack bitmap + */ + bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; + sent_bitmap = bitmap & agg->bitmap; + + /* Sanity check values reported by uCode */ + if (ba_resp->txed_2_done > ba_resp->txed) { + IWL_DEBUG_TX_REPLY(priv, + "bogus sent(%d) and ack(%d) count\n", + ba_resp->txed, ba_resp->txed_2_done); /* - * sent and ack information provided by uCode - * use it instead of figure out ourself + * set txed_2_done = txed, + * so it won't impact rate scale */ - if (ba_resp->txed_2_done > ba_resp->txed) { - IWL_DEBUG_TX_REPLY(priv, - "bogus sent(%d) and ack(%d) count\n", - ba_resp->txed, ba_resp->txed_2_done); - /* - * set txed_2_done = txed, - * so it won't impact rate scale - */ - ba_resp->txed = ba_resp->txed_2_done; - } - IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n", - ba_resp->txed, ba_resp->txed_2_done); - } else { - u64 bitmap, sent_bitmap; + ba_resp->txed = ba_resp->txed_2_done; + } + IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n", + ba_resp->txed, ba_resp->txed_2_done); - /* don't use 64-bit values for now */ - bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; - - /* check for success or failure according to the - * transmitted bitmap and block-ack bitmap */ - sent_bitmap = bitmap & agg->bitmap; - - /* For each frame attempted in aggregation, - * update driver's record of tx frame's status. */ - i = 0; - while (sent_bitmap) { - ack = sent_bitmap & 1ULL; - successes += ack; - IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n", - ack ? "ACK" : "NACK", i, - (agg->start_idx + i) & 0xff, - agg->start_idx + i); - sent_bitmap >>= 1; - ++i; - } - - IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", - (unsigned long long)bitmap); + /* Find the first ACKed frame to store the TX status */ + while (sent_bitmap && !(sent_bitmap & 1)) { + agg->start_idx = (agg->start_idx + 1) & 0xff; + sent_bitmap >>= 1; } info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb); memset(&info->status, 0, sizeof(info->status)); info->flags |= IEEE80211_TX_STAT_ACK; info->flags |= IEEE80211_TX_STAT_AMPDU; - if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) { - info->status.ampdu_ack_len = ba_resp->txed_2_done; - info->status.ampdu_len = ba_resp->txed; - - } else { - info->status.ampdu_ack_len = successes; - info->status.ampdu_len = agg->frame_count; - } + info->status.ampdu_ack_len = ba_resp->txed_2_done; + info->status.ampdu_len = ba_resp->txed; iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 1f4f6dd18009..3e680af7ff70 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -281,8 +281,6 @@ struct iwl_mod_params { * @chain_noise_calib_by_driver: driver has the capability to perform * chain noise calibration operation * @shadow_reg_enable: HW shadhow register bit - * @no_agg_framecnt_info: uCode do not provide aggregation frame count - * information */ struct iwl_base_params { int eeprom_size; @@ -312,7 +310,6 @@ struct iwl_base_params { const bool sensitivity_calib_by_driver; const bool chain_noise_calib_by_driver; const bool shadow_reg_enable; - const bool no_agg_framecnt_info; }; /* * @advanced_bt_coexist: support advanced bt coexist From 2520546aecc969372080448a2422b39eedb2a528 Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Fri, 18 Mar 2011 18:48:55 -0700 Subject: [PATCH 07/12] iwlwifi: add RATE_MCS_RATE_MSK Throughout the code we use rate_n_flags & 0xff to extract the lower byte of the rate_n_flags u32 that contains the information about the rate. Add a #define and remove the use of the magic number. Signed-off-by: Daniel Halperin Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 15 ++++++++------- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 +- drivers/net/wireless/iwlwifi/iwl-commands.h | 2 ++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 63b58ecb0dc6..e394e49228ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -115,13 +115,18 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { /* FIXME:RS: ^^ should be INV (legacy) */ }; +static inline u8 rs_extract_rate(u32 rate_n_flags) +{ + return (u8)(rate_n_flags & RATE_MCS_RATE_MSK); +} + static 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); + idx = rs_extract_rate(rate_n_flags); if (idx >= IWL_RATE_MIMO3_6M_PLCP) idx = idx - IWL_RATE_MIMO3_6M_PLCP; @@ -138,7 +143,8 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) /* 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)) + if (iwl_rates[idx].plcp == + rs_extract_rate(rate_n_flags)) return idx; } @@ -239,11 +245,6 @@ static const struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = { #define MCS_INDEX_PER_STREAM (8) -static inline u8 rs_extract_rate(u32 rate_n_flags) -{ - return (u8)(rate_n_flags & 0xFF); -} - static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) { window->data = 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 4f7c9ce9d8bd..39313acb9cc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -310,7 +310,7 @@ static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) static inline u8 iwl_hw_get_rate(__le32 rate_n_flags) { - return le32_to_cpu(rate_n_flags) & 0xFF; + return le32_to_cpu(rate_n_flags) & RATE_MCS_RATE_MSK; } static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index ca42ffa63ed7..288391558afd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -324,6 +324,8 @@ struct iwl3945_power_per_rate { #define RATE_MCS_SPATIAL_MSK 0x18 #define RATE_MCS_HT_DUP_POS 5 #define RATE_MCS_HT_DUP_MSK 0x20 +/* Both legacy and HT use bits 7:0 as the CCK/OFDM rate or HT MCS */ +#define RATE_MCS_RATE_MSK 0xff /* Bit 8: (1) HT format, (0) legacy format in bits 7:0 */ #define RATE_MCS_FLAGS_POS 8 From 4263108c2a9028544cf4037fa4e72000ee456c33 Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Mon, 21 Mar 2011 15:27:34 -0700 Subject: [PATCH 08/12] iwlwifi: set default aggregation frame limit to 63 This gives much better performance at fast 3x3 rates (up to ~160 Mbps). The scheduler will still make most decisions about batch size based on available packets and RX parameters. Signed-off-by: Daniel Halperin Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-commands.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 288391558afd..cc2151482f31 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2132,7 +2132,7 @@ struct iwl_link_qual_general_params { #define LINK_QUAL_AGG_DISABLE_START_MAX (255) #define LINK_QUAL_AGG_DISABLE_START_MIN (0) -#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (31) +#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63) #define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) #define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) From d6b8061824a03fbe915c6cf5be2b290ae44c4ec4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 21 Mar 2011 16:53:38 -0700 Subject: [PATCH 09/12] iwlwifi: remove legacy isr tasklet After driver split, no need for support legacy isr, remove it. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn-ict.c | 2 - drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 3 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 193 +-------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 4 files changed, 3 insertions(+), 196 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c index b5cb3be0eb4b..47e1fa4bacfd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c @@ -59,8 +59,6 @@ void iwl_free_isr_ict(struct iwl_priv *priv) int iwl_alloc_isr_ict(struct iwl_priv *priv) { - if (priv->cfg->base_params->use_isr_legacy) - return 0; /* allocate shrared data table */ priv->_agn.ict_tbl_vir = dma_alloc_coherent(&priv->pci_dev->dev, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 2003c1d4295f..8163a0efdc83 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -652,8 +652,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */ - if (!priv->cfg->base_params->use_isr_legacy) - rb_timeout = RX_RB_TIMEOUT; + rb_timeout = RX_RB_TIMEOUT; if (priv->cfg->mod_params->amsdu_size_8K) rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8fdd1746c102..bd980a2da413 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -845,191 +845,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv) tasklet_kill(&priv->irq_tasklet); } -static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) -{ - u32 inta, handled = 0; - u32 inta_fh; - unsigned long flags; - u32 i; -#ifdef CONFIG_IWLWIFI_DEBUG - u32 inta_mask; -#endif - - spin_lock_irqsave(&priv->lock, flags); - - /* Ack/clear/reset pending uCode interrupts. - * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, - * and will clear only when CSR_FH_INT_STATUS gets cleared. */ - inta = iwl_read32(priv, CSR_INT); - iwl_write32(priv, CSR_INT, inta); - - /* Ack/clear/reset pending flow-handler (DMA) interrupts. - * Any new interrupts that happen after this, either while we're - * in this tasklet, or later, will show up in next ISR/tasklet. */ - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); - -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & IWL_DL_ISR) { - /* just for debug */ - inta_mask = iwl_read32(priv, CSR_INT_MASK); - IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", - inta, inta_mask, inta_fh); - } -#endif - - spin_unlock_irqrestore(&priv->lock, flags); - - /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not - * atomic, make sure that inta covers all the interrupts that - * we've discovered, even if FH interrupt came in just after - * reading CSR_INT. */ - if (inta_fh & CSR49_FH_INT_RX_MASK) - inta |= CSR_INT_BIT_FH_RX; - if (inta_fh & CSR49_FH_INT_TX_MASK) - inta |= CSR_INT_BIT_FH_TX; - - /* Now service all interrupt bits discovered above. */ - if (inta & CSR_INT_BIT_HW_ERR) { - IWL_ERR(priv, "Hardware error detected. Restarting.\n"); - - /* Tell the device to stop sending interrupts */ - iwl_disable_interrupts(priv); - - priv->isr_stats.hw++; - iwl_irq_handle_error(priv); - - handled |= CSR_INT_BIT_HW_ERR; - - return; - } - -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { - /* NIC fires this, but we don't use it, redundant with WAKEUP */ - if (inta & CSR_INT_BIT_SCD) { - IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " - "the frame/frames.\n"); - priv->isr_stats.sch++; - } - - /* Alive notification via Rx interrupt will do the real work */ - if (inta & CSR_INT_BIT_ALIVE) { - IWL_DEBUG_ISR(priv, "Alive interrupt\n"); - priv->isr_stats.alive++; - } - } -#endif - /* Safely ignore these bits for debug checks below */ - inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE); - - /* HW RF KILL switch toggled */ - if (inta & CSR_INT_BIT_RF_KILL) { - int hw_rf_kill = 0; - if (!(iwl_read32(priv, CSR_GP_CNTRL) & - CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) - hw_rf_kill = 1; - - IWL_WARN(priv, "RF_KILL bit toggled to %s.\n", - hw_rf_kill ? "disable radio" : "enable radio"); - - priv->isr_stats.rfkill++; - - /* driver only loads ucode once setting the interface up. - * the driver allows loading the ucode even if the radio - * is killed. Hence update the killswitch state here. The - * rfkill handler will care about restarting if needed. - */ - if (!test_bit(STATUS_ALIVE, &priv->status)) { - if (hw_rf_kill) - set_bit(STATUS_RF_KILL_HW, &priv->status); - else - clear_bit(STATUS_RF_KILL_HW, &priv->status); - wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); - } - - handled |= CSR_INT_BIT_RF_KILL; - } - - /* Chip got too hot and stopped itself */ - if (inta & CSR_INT_BIT_CT_KILL) { - IWL_ERR(priv, "Microcode CT kill error detected.\n"); - priv->isr_stats.ctkill++; - handled |= CSR_INT_BIT_CT_KILL; - } - - /* Error detected by uCode */ - if (inta & CSR_INT_BIT_SW_ERR) { - IWL_ERR(priv, "Microcode SW error detected. " - " Restarting 0x%X.\n", inta); - priv->isr_stats.sw++; - iwl_irq_handle_error(priv); - handled |= CSR_INT_BIT_SW_ERR; - } - - /* - * uCode wakes up after power-down sleep. - * Tell device about any new tx or host commands enqueued, - * and about any Rx buffers made available while asleep. - */ - if (inta & CSR_INT_BIT_WAKEUP) { - IWL_DEBUG_ISR(priv, "Wakeup interrupt\n"); - iwl_rx_queue_update_write_ptr(priv, &priv->rxq); - for (i = 0; i < priv->hw_params.max_txq_num; i++) - iwl_txq_update_write_ptr(priv, &priv->txq[i]); - priv->isr_stats.wakeup++; - handled |= CSR_INT_BIT_WAKEUP; - } - - /* All uCode command responses, including Tx command responses, - * Rx "responses" (frame-received notification), and other - * notifications from uCode come through here*/ - if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { - iwl_rx_handle(priv); - priv->isr_stats.rx++; - handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); - } - - /* This "Tx" DMA channel is used only for loading uCode */ - if (inta & CSR_INT_BIT_FH_TX) { - IWL_DEBUG_ISR(priv, "uCode load interrupt\n"); - priv->isr_stats.tx++; - handled |= CSR_INT_BIT_FH_TX; - /* Wake up uCode load routine, now that load is complete */ - priv->ucode_write_complete = 1; - wake_up_interruptible(&priv->wait_command_queue); - } - - if (inta & ~handled) { - IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled); - priv->isr_stats.unhandled++; - } - - if (inta & ~(priv->inta_mask)) { - IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n", - inta & ~priv->inta_mask); - IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh); - } - - /* Re-enable all interrupts */ - /* only Re-enable if disabled by irq */ - if (test_bit(STATUS_INT_ENABLED, &priv->status)) - iwl_enable_interrupts(priv); - /* Re-enable RF_KILL if it occurred */ - else if (handled & CSR_INT_BIT_RF_KILL) - iwl_enable_rfkill_int(priv); - -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) { - inta = iwl_read32(priv, CSR_INT); - inta_mask = iwl_read32(priv, CSR_INT_MASK); - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, " - "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); - } -#endif -} - /* tasklet for iwlagn interrupt */ static void iwl_irq_tasklet(struct iwl_priv *priv) { @@ -3751,12 +3566,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) priv->watchdog.data = (unsigned long)priv; priv->watchdog.function = iwl_bg_watchdog; - if (!priv->cfg->base_params->use_isr_legacy) - tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) - iwl_irq_tasklet, (unsigned long)priv); - else - tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) - iwl_irq_tasklet_legacy, (unsigned long)priv); + tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) + iwl_irq_tasklet, (unsigned long)priv); } static void iwl_cancel_deferred_work(struct iwl_priv *priv) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3e680af7ff70..3a4e9b4d0973 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -291,7 +291,6 @@ struct iwl_base_params { bool set_l0s; bool use_bsm; - bool use_isr_legacy; const u16 max_ll_items; const bool shadow_ram_support; u16 led_compensation; From 2a226ab67f2f9c46e534f37f867d3bf3af335d02 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 22 Mar 2011 08:05:36 -0700 Subject: [PATCH 10/12] iwlagn: remove 3945 only station code After driver split, no more 3945 only station support needed. Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-sta.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index bc90a12408a3..b0dcca07ff45 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -306,12 +306,6 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, */ iwl_set_ht_add_station(priv, sta_id, sta, ctx); - /* 3945 only */ - rate = (priv->band == IEEE80211_BAND_5GHZ) ? - IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP; - /* Turn on both antennas for the station... */ - station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK); - return sta_id; } From f7d046f91bd165e747b9a95d089a4168b6f9796a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 22 Mar 2011 08:05:37 -0700 Subject: [PATCH 11/12] iwlagn: remove reference to 3945 and 4965 After driver split, remove the unused reference to 3945 and 4965 Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 39 +++++++++-------------- drivers/net/wireless/iwlwifi/iwl-csr.h | 39 +++++------------------ drivers/net/wireless/iwlwifi/iwl-eeprom.c | 2 -- 3 files changed, 23 insertions(+), 57 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index bd980a2da413..9251c68934dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -409,7 +409,7 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, * Tell nic where to find circular buffer of Tx Frame Descriptors for * given Tx queue, and enable the DMA channel used for that queue. * - * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA + * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA * channels supported in hardware. */ int iwl_hw_tx_queue_init(struct iwl_priv *priv, @@ -986,7 +986,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); iwl_write32(priv, CSR_FH_INT_STATUS, - CSR49_FH_INT_RX_MASK); + CSR_FH_INT_RX_MASK); } if (inta & CSR_INT_BIT_RX_PERIODIC) { handled |= CSR_INT_BIT_RX_PERIODIC; @@ -1024,7 +1024,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) /* This "Tx" DMA channel is used only for loading uCode */ if (inta & CSR_INT_BIT_FH_TX) { - iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK); + iwl_write32(priv, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); IWL_DEBUG_ISR(priv, "uCode load interrupt\n"); priv->isr_stats.tx++; handled |= CSR_INT_BIT_FH_TX; @@ -1259,28 +1259,19 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, switch (api_ver) { default: - /* - * 4965 doesn't revision the firmware file format - * along with the API version, it always uses v1 - * file format. - */ - if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != - CSR_HW_REV_TYPE_4965) { - hdr_size = 28; - if (ucode_raw->size < hdr_size) { - IWL_ERR(priv, "File size too small!\n"); - return -EINVAL; - } - pieces->build = le32_to_cpu(ucode->u.v2.build); - pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); - pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); - pieces->boot_size = le32_to_cpu(ucode->u.v2.boot_size); - src = ucode->u.v2.data; - break; + hdr_size = 28; + if (ucode_raw->size < hdr_size) { + IWL_ERR(priv, "File size too small!\n"); + return -EINVAL; } - /* fall through for 4965 */ + pieces->build = le32_to_cpu(ucode->u.v2.build); + pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); + pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); + pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); + pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); + pieces->boot_size = le32_to_cpu(ucode->u.v2.boot_size); + src = ucode->u.v2.data; + break; case 0: case 1: case 2: diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index f52bc040bcbf..1123319f2e2b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -155,18 +155,10 @@ #define CSR_DBG_LINK_PWR_MGMT_REG (CSR_BASE+0x250) /* Bits for CSR_HW_IF_CONFIG_REG */ -#define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010) #define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00) #define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) #define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) -#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MB (0x00000100) -#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MM (0x00000200) -#define CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC (0x00000400) -#define CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE (0x00000800) -#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000) -#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000) - #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000) #define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) #define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000) /* PCI_OWN_SEM */ @@ -186,7 +178,7 @@ #define CSR_INT_BIT_SW_ERR (1 << 25) /* uCode error */ #define CSR_INT_BIT_RF_KILL (1 << 7) /* HW RFKILL switch GP_CNTRL[27] toggled */ #define CSR_INT_BIT_CT_KILL (1 << 6) /* Critical temp (chip too hot) rfkill */ -#define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses, 3945 */ +#define CSR_INT_BIT_SW_RX (1 << 3) /* Rx, command responses */ #define CSR_INT_BIT_WAKEUP (1 << 1) /* NIC controller waking up (pwr mgmt) */ #define CSR_INT_BIT_ALIVE (1 << 0) /* uCode interrupts once it initializes */ @@ -202,29 +194,17 @@ /* interrupt flags in FH (flow handler) (PCI busmaster DMA) */ #define CSR_FH_INT_BIT_ERR (1 << 31) /* Error */ #define CSR_FH_INT_BIT_HI_PRIOR (1 << 30) /* High priority Rx, bypass coalescing */ -#define CSR39_FH_INT_BIT_RX_CHNL2 (1 << 18) /* Rx channel 2 (3945 only) */ #define CSR_FH_INT_BIT_RX_CHNL1 (1 << 17) /* Rx channel 1 */ #define CSR_FH_INT_BIT_RX_CHNL0 (1 << 16) /* Rx channel 0 */ -#define CSR39_FH_INT_BIT_TX_CHNL6 (1 << 6) /* Tx channel 6 (3945 only) */ #define CSR_FH_INT_BIT_TX_CHNL1 (1 << 1) /* Tx channel 1 */ #define CSR_FH_INT_BIT_TX_CHNL0 (1 << 0) /* Tx channel 0 */ -#define CSR39_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ - CSR39_FH_INT_BIT_RX_CHNL2 | \ - CSR_FH_INT_BIT_RX_CHNL1 | \ - CSR_FH_INT_BIT_RX_CHNL0) +#define CSR_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ + CSR_FH_INT_BIT_RX_CHNL1 | \ + CSR_FH_INT_BIT_RX_CHNL0) - -#define CSR39_FH_INT_TX_MASK (CSR39_FH_INT_BIT_TX_CHNL6 | \ - CSR_FH_INT_BIT_TX_CHNL1 | \ - CSR_FH_INT_BIT_TX_CHNL0) - -#define CSR49_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ - CSR_FH_INT_BIT_RX_CHNL1 | \ - CSR_FH_INT_BIT_RX_CHNL0) - -#define CSR49_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \ - CSR_FH_INT_BIT_TX_CHNL0) +#define CSR_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \ + CSR_FH_INT_BIT_TX_CHNL0) /* GPIO */ #define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200) @@ -268,7 +248,7 @@ * Indicates MAC (ucode processor, etc.) is powered up and can run. * Internal resources are accessible. * NOTE: This does not indicate that the processor is actually running. - * NOTE: This does not indicate that 4965 or 3945 has completed + * NOTE: This does not indicate that device has completed * init or post-power-down restore of internal SRAM memory. * Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that * SRAM is restored and uCode is in normal operation mode. @@ -291,8 +271,6 @@ /* HW REV */ #define CSR_HW_REV_TYPE_MSK (0x00001F0) -#define CSR_HW_REV_TYPE_3945 (0x00000D0) -#define CSR_HW_REV_TYPE_4965 (0x0000000) #define CSR_HW_REV_TYPE_5300 (0x0000020) #define CSR_HW_REV_TYPE_5350 (0x0000030) #define CSR_HW_REV_TYPE_5100 (0x0000050) @@ -363,7 +341,7 @@ * 0: MAC_SLEEP * uCode sets this when preparing a power-saving power-down. * uCode resets this when power-up is complete and SRAM is sane. - * NOTE: 3945/4965 saves internal SRAM data to host when powering down, + * NOTE: device saves internal SRAM data to host when powering down, * and must restore this data after powering back up. * MAC_SLEEP is the best indication that restore is complete. * Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and @@ -394,7 +372,6 @@ #define CSR_LED_REG_TRUN_OFF (0x38) /* ANA_PLL */ -#define CSR39_ANA_PLL_CFG_VAL (0x01000000) #define CSR50_ANA_PLL_CFG_VAL (0x00880300) /* HPET MEM debug */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 833194a2c639..c831a0f24613 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -198,8 +198,6 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv) case CSR_HW_REV_TYPE_NONE: IWL_ERR(priv, "Unknown hardware type\n"); return -ENOENT; - case CSR_HW_REV_TYPE_3945: - case CSR_HW_REV_TYPE_4965: case CSR_HW_REV_TYPE_5300: case CSR_HW_REV_TYPE_5350: case CSR_HW_REV_TYPE_5100: From 7eaa6a5e964f1ab02d849bda36950c0d30be8ce2 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 22 Mar 2011 08:05:38 -0700 Subject: [PATCH 12/12] iwlagn: remove deprecated module parameters Number of deprecated module parameters need to be remove for 2.6.40 kernel Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 30 ------------------------- drivers/net/wireless/iwlwifi/iwl-core.h | 1 - 2 files changed, 31 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 9251c68934dd..39a05e32c34f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3771,14 +3771,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * 1. Allocating HW data ************************/ - /* Disabling hardware scan means that mac80211 will perform scans - * "the hard way", rather than using device's scan. */ - if (cfg->mod_params->disable_hw_scan) { - dev_printk(KERN_DEBUG, &(pdev->dev), - "sw scan support is deprecated\n"); - iwlagn_hw_ops.hw_scan = NULL; - } - hw = iwl_alloc_all(cfg); if (!hw) { err = -ENOMEM; @@ -4388,43 +4380,21 @@ module_exit(iwl_exit); module_init(iwl_init); #ifdef CONFIG_IWLWIFI_DEBUG -module_param_named(debug50, iwl_debug_level, uint, S_IRUGO); -MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)"); module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "debug output mask"); #endif -module_param_named(swcrypto50, iwlagn_mod_params.sw_crypto, bool, S_IRUGO); -MODULE_PARM_DESC(swcrypto50, - "using crypto in software (default 0 [hardware]) (deprecated)"); module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO); MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); -module_param_named(queues_num50, - iwlagn_mod_params.num_of_queues, int, S_IRUGO); -MODULE_PARM_DESC(queues_num50, - "number of hw queues in 50xx series (deprecated)"); module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO); MODULE_PARM_DESC(queues_num, "number of hw queues."); -module_param_named(11n_disable50, iwlagn_mod_params.disable_11n, int, S_IRUGO); -MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality (deprecated)"); module_param_named(11n_disable, iwlagn_mod_params.disable_11n, int, S_IRUGO); MODULE_PARM_DESC(11n_disable, "disable 11n functionality"); -module_param_named(amsdu_size_8K50, iwlagn_mod_params.amsdu_size_8K, - int, S_IRUGO); -MODULE_PARM_DESC(amsdu_size_8K50, - "enable 8K amsdu size in 50XX series (deprecated)"); module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K, int, S_IRUGO); MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); -module_param_named(fw_restart50, iwlagn_mod_params.restart_fw, int, S_IRUGO); -MODULE_PARM_DESC(fw_restart50, - "restart firmware in case of error (deprecated)"); module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO); MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); -module_param_named( - disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO); -MODULE_PARM_DESC(disable_hw_scan, - "disable hardware scanning (default 0) (deprecated)"); module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int, S_IRUGO); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3a4e9b4d0973..967b4c008bc0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -247,7 +247,6 @@ struct iwl_ops { struct iwl_mod_params { int sw_crypto; /* def: 0 = using hardware encryption */ - int disable_hw_scan; /* def: 0 = use h/w scan */ int num_of_queues; /* def: HW dependent */ int disable_11n; /* def: 0 = 11n capabilities enabled */ int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */