diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-11-22 15:28:30 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-11-22 15:28:30 -0500 |
commit | 840fd8ff64f7b6c9cbfa9b7d0419f015f33303ff (patch) | |
tree | bcdc472c9b794f1d141534c14dcb0dd17015f030 /drivers/net/wireless | |
parent | b84a7d3d9e7cd5a25f4fd32142cebdf4481a74a4 (diff) | |
parent | 9e2e7422d059f9b98c3a0810df92a1ff660ade2f (diff) | |
download | op-kernel-dev-840fd8ff64f7b6c9cbfa9b7d0419f015f33303ff.zip op-kernel-dev-840fd8ff64f7b6c9cbfa9b7d0419f015f33303ff.tar.gz |
Merge branch 'wireless-next-2.6' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6
Diffstat (limited to 'drivers/net/wireless')
26 files changed, 345 insertions, 225 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 068f1e1..3100a72 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -278,7 +278,6 @@ struct iwl_cfg iwl1000_bgn_cfg = { .fw_name_pre = IWL1000_FW_PRE, .ucode_api_max = IWL1000_UCODE_API_MAX, .ucode_api_min = IWL1000_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, @@ -287,6 +286,7 @@ struct iwl_cfg iwl1000_bgn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, .ht_params = &iwl1000_ht_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl1000_bg_cfg = { @@ -294,7 +294,6 @@ struct iwl_cfg iwl1000_bg_cfg = { .fw_name_pre = IWL1000_FW_PRE, .ucode_api_max = IWL1000_UCODE_API_MAX, .ucode_api_min = IWL1000_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, @@ -302,6 +301,7 @@ struct iwl_cfg iwl1000_bg_cfg = { .ops = &iwl1000_ops, .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl100_bgn_cfg = { @@ -309,7 +309,6 @@ struct iwl_cfg iwl100_bgn_cfg = { .fw_name_pre = IWL100_FW_PRE, .ucode_api_max = IWL100_UCODE_API_MAX, .ucode_api_min = IWL100_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, @@ -318,6 +317,7 @@ struct iwl_cfg iwl100_bgn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, .ht_params = &iwl1000_ht_params, + .led_mode = IWL_LED_RF_STATE, }; struct iwl_cfg iwl100_bg_cfg = { @@ -325,7 +325,6 @@ struct iwl_cfg iwl100_bg_cfg = { .fw_name_pre = IWL100_FW_PRE, .ucode_api_max = IWL100_UCODE_API_MAX, .ucode_api_min = IWL100_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, @@ -333,6 +332,7 @@ struct iwl_cfg iwl100_bg_cfg = { .ops = &iwl1000_ops, .mod_params = &iwlagn_mod_params, .base_params = &iwl1000_base_params, + .led_mode = IWL_LED_RF_STATE, }; MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index ebac04b..56f4ca7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -297,7 +297,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && (txq_id != IWL39_CMD_QUEUE_NUM) && priv->mac80211_registered) - iwl_wake_queue(priv, txq_id); + iwl_wake_queue(priv, txq); } /** @@ -2788,6 +2788,7 @@ static struct iwl_cfg iwl3945_bg_cfg = { .ops = &iwl3945_ops, .mod_params = &iwl3945_mod_params, .base_params = &iwl3945_base_params, + .led_mode = IWL_LED_BLINK, }; static struct iwl_cfg iwl3945_abg_cfg = { @@ -2800,6 +2801,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { .ops = &iwl3945_ops, .mod_params = &iwl3945_mod_params, .base_params = &iwl3945_base_params, + .led_mode = IWL_LED_BLINK, }; DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 4748d06..6788ceb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2238,12 +2238,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark) && - (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) { - if (agg->state == IWL_AGG_OFF) - iwl_wake_queue(priv, txq_id); - else - iwl_wake_queue(priv, txq->swq_id); - } + (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) + iwl_wake_queue(priv, txq); } } else { info->status.rates[0].count = tx_resp->failure_frame + 1; @@ -2267,7 +2263,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark)) - iwl_wake_queue(priv, txq_id); + iwl_wake_queue(priv, txq); } if (qc && likely(sta_id != IWL_INVALID_STATION)) iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); @@ -2620,6 +2616,7 @@ static struct iwl_base_params iwl4965_base_params = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, + .no_agg_framecnt_info = true, }; struct iwl_cfg iwl4965_agn_cfg = { @@ -2627,7 +2624,6 @@ struct iwl_cfg iwl4965_agn_cfg = { .fw_name_pre = IWL4965_FW_PRE, .ucode_api_max = IWL4965_UCODE_API_MAX, .ucode_api_min = IWL4965_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_4965_EEPROM_VERSION, @@ -2635,6 +2631,7 @@ struct iwl_cfg iwl4965_agn_cfg = { .ops = &iwl4965_ops, .mod_params = &iwlagn_mod_params, .base_params = &iwl4965_base_params, + .led_mode = IWL_LED_BLINK, /* * Force use of chains B and C for scan RX on 5 GHz band * because the device has off-channel reception on chain A. diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index ad43f0fd..3ee0f7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -527,7 +527,6 @@ struct iwl_cfg iwl5300_agn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_ABC, .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, @@ -536,6 +535,7 @@ struct iwl_cfg iwl5300_agn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5100_bgn_cfg = { @@ -543,7 +543,6 @@ struct iwl_cfg iwl5100_bgn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_B, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, @@ -552,6 +551,7 @@ struct iwl_cfg iwl5100_bgn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5100_abg_cfg = { @@ -559,7 +559,6 @@ struct iwl_cfg iwl5100_abg_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, .valid_tx_ant = ANT_B, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, @@ -567,6 +566,7 @@ struct iwl_cfg iwl5100_abg_cfg = { .ops = &iwl5000_ops, .mod_params = &iwlagn_mod_params, .base_params = &iwl5000_base_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5100_agn_cfg = { @@ -574,7 +574,6 @@ struct iwl_cfg iwl5100_agn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_B, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, @@ -583,6 +582,7 @@ struct iwl_cfg iwl5100_agn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5350_agn_cfg = { @@ -590,7 +590,6 @@ struct iwl_cfg iwl5350_agn_cfg = { .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_ABC, .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, @@ -599,6 +598,7 @@ struct iwl_cfg iwl5350_agn_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5150_agn_cfg = { @@ -606,7 +606,6 @@ struct iwl_cfg iwl5150_agn_cfg = { .fw_name_pre = IWL5150_FW_PRE, .ucode_api_max = IWL5150_UCODE_API_MAX, .ucode_api_min = IWL5150_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, @@ -616,6 +615,7 @@ struct iwl_cfg iwl5150_agn_cfg = { .base_params = &iwl5000_base_params, .ht_params = &iwl5000_ht_params, .need_dc_calib = true, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl5150_abg_cfg = { @@ -623,7 +623,6 @@ struct iwl_cfg iwl5150_abg_cfg = { .fw_name_pre = IWL5150_FW_PRE, .ucode_api_max = IWL5150_UCODE_API_MAX, .ucode_api_min = IWL5150_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, @@ -632,6 +631,7 @@ struct iwl_cfg iwl5150_abg_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl5000_base_params, .need_dc_calib = true, + .led_mode = IWL_LED_BLINK, }; MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index c7ff1bd..0cc66fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -546,6 +546,7 @@ static struct iwl_bt_params iwl6000_bt_params = { .bt_statistics = true, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .advanced_bt_coexist = true, + .agg_time_limit = BT_AGG_THRESHOLD_DEF, .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, }; @@ -555,7 +556,6 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -566,6 +566,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, }; struct iwl_cfg iwl6000g2a_2abg_cfg = { @@ -573,7 +574,6 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -583,6 +583,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { .base_params = &iwl6000_base_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, }; struct iwl_cfg iwl6000g2a_2bg_cfg = { @@ -590,7 +591,6 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { .fw_name_pre = IWL6000G2A_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -600,6 +600,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { .base_params = &iwl6000_base_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, }; struct iwl_cfg iwl6000g2b_2agn_cfg = { @@ -607,7 +608,6 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -619,6 +619,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -628,7 +629,6 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -639,6 +639,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -648,7 +649,6 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -660,6 +660,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -669,7 +670,6 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -680,6 +680,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -689,7 +690,6 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -701,6 +701,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .ht_params = &iwl6000_ht_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -710,7 +711,6 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -721,6 +721,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .bt_params = &iwl6000_bt_params, .need_dc_calib = true, .need_temp_offset_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -733,7 +734,6 @@ struct iwl_cfg iwl6000i_2agn_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_BC, .valid_rx_ant = ANT_BC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, @@ -743,6 +743,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = { .base_params = &iwl6000_base_params, .ht_params = &iwl6000_ht_params, .pa_type = IWL_PA_INTERNAL, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl6000i_2abg_cfg = { @@ -750,7 +751,6 @@ struct iwl_cfg iwl6000i_2abg_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, .valid_tx_ant = ANT_BC, .valid_rx_ant = ANT_BC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, @@ -759,6 +759,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl6000_base_params, .pa_type = IWL_PA_INTERNAL, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl6000i_2bg_cfg = { @@ -766,7 +767,6 @@ struct iwl_cfg iwl6000i_2bg_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_BC, .valid_rx_ant = ANT_BC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, @@ -775,6 +775,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl6000_base_params, .pa_type = IWL_PA_INTERNAL, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl6050_2agn_cfg = { @@ -782,7 +783,6 @@ struct iwl_cfg iwl6050_2agn_cfg = { .fw_name_pre = IWL6050_FW_PRE, .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .ops = &iwl6050_ops, @@ -792,6 +792,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { .base_params = &iwl6050_base_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl6050g2_bgn_cfg = { @@ -799,7 +800,6 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { .fw_name_pre = IWL6050_FW_PRE, .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION, @@ -809,6 +809,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { .base_params = &iwl6050_base_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .led_mode = IWL_LED_RF_STATE, }; struct iwl_cfg iwl6050_2abg_cfg = { @@ -816,7 +817,6 @@ struct iwl_cfg iwl6050_2abg_cfg = { .fw_name_pre = IWL6050_FW_PRE, .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, .valid_tx_ant = ANT_AB, .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, @@ -825,6 +825,7 @@ struct iwl_cfg iwl6050_2abg_cfg = { .mod_params = &iwlagn_mod_params, .base_params = &iwl6050_base_params, .need_dc_calib = true, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl6000_3agn_cfg = { @@ -832,7 +833,6 @@ struct iwl_cfg iwl6000_3agn_cfg = { .fw_name_pre = IWL6000_FW_PRE, .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_ABC, .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, @@ -842,6 +842,7 @@ struct iwl_cfg iwl6000_3agn_cfg = { .base_params = &iwl6000_base_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .led_mode = IWL_LED_BLINK, }; struct iwl_cfg iwl130_bgn_cfg = { @@ -849,7 +850,6 @@ struct iwl_cfg iwl130_bgn_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -860,6 +860,7 @@ struct iwl_cfg iwl130_bgn_cfg = { .bt_params = &iwl6000_bt_params, .ht_params = &iwl6000_ht_params, .need_dc_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; @@ -869,7 +870,6 @@ struct iwl_cfg iwl130_bg_cfg = { .fw_name_pre = IWL6000G2B_FW_PRE, .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G, .valid_tx_ant = ANT_A, .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, @@ -879,6 +879,7 @@ struct iwl_cfg iwl130_bg_cfg = { .base_params = &iwl6000_coex_base_params, .bt_params = &iwl6000_bt_params, .need_dc_calib = true, + .led_mode = IWL_LED_RF_STATE, /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index a650bab..8a4d3ac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -248,6 +248,27 @@ err: } +int iwl_eeprom_check_sku(struct iwl_priv *priv) +{ + u16 eeprom_sku; + + eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); + + priv->cfg->sku = ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >> + EEPROM_SKU_CAP_BAND_POS); + if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE) + priv->cfg->sku |= IWL_SKU_N; + + if (!priv->cfg->sku) { + IWL_ERR(priv, "Invalid device sku\n"); + return -EINVAL; + } + + IWL_INFO(priv, "Device SKU: 0X%x\n", priv->cfg->sku); + + return 0; +} + void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) { const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index ffb2f41..366340f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -307,6 +307,7 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) if (ctx_bss->vif && ctx_pan->vif) { int bcnint = ctx_pan->vif->bss_conf.beacon_int; + int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1; /* should be set, but seems unused?? */ cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE); @@ -329,10 +330,10 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) if (test_bit(STATUS_SCAN_HW, &priv->status) || (!ctx_bss->vif->bss_conf.idle && !ctx_bss->vif->bss_conf.assoc)) { - slot0 = bcnint * 3 - 20; + slot0 = dtim * bcnint * 3 - 20; slot1 = 20; } else if (!ctx_pan->vif->bss_conf.idle && - !ctx_pan->vif->bss_conf.assoc) { + !ctx_pan->vif->bss_conf.assoc) { slot1 = bcnint * 3 - 20; slot0 = 20; } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index ca3530c..881475c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -445,22 +445,17 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark) && - (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) { - if (agg->state == IWL_AGG_OFF) - iwl_wake_queue(priv, txq_id); - else - iwl_wake_queue(priv, txq->swq_id); - } + (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) + iwl_wake_queue(priv, txq); } } else { - BUG_ON(txq_id != txq->swq_id); iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false); freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); iwl_free_tfds_in_queue(priv, sta_id, tid, freed); if (priv->mac80211_registered && (iwl_queue_space(&txq->q) > txq->q.low_mark)) - iwl_wake_queue(priv, txq_id); + iwl_wake_queue(priv, txq); } iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); @@ -2025,7 +2020,6 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 }; struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; - u8 last_traffic_load; IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); @@ -2034,11 +2028,10 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, coex->bt_ci_compliance); iwlagn_print_uartmsg(priv, uart_msg); - last_traffic_load = priv->notif_bt_traffic_load; - priv->notif_bt_traffic_load = coex->bt_traffic_load; + priv->last_bt_traffic_load = priv->bt_traffic_load; if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { if (priv->bt_status != coex->bt_status || - last_traffic_load != coex->bt_traffic_load) { + priv->last_bt_traffic_load != coex->bt_traffic_load) { if (coex->bt_status) { /* BT on */ if (!priv->bt_ch_announce) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 0655536..f450adc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -833,17 +833,23 @@ static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_lq_sta *lq_sta) { struct iwl_scale_tbl_info *tbl; - bool full_concurrent; + bool full_concurrent = priv->bt_full_concurrent; unsigned long flags; - spin_lock_irqsave(&priv->lock, flags); - if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) - full_concurrent = true; - else - full_concurrent = false; - spin_unlock_irqrestore(&priv->lock, flags); - - if (priv->bt_full_concurrent != full_concurrent) { + if (priv->bt_ant_couple_ok) { + /* + * Is there a need to switch between + * full concurrency and 3-wire? + */ + spin_lock_irqsave(&priv->lock, flags); + if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) + full_concurrent = true; + else + full_concurrent = false; + spin_unlock_irqrestore(&priv->lock, flags); + } + if ((priv->bt_traffic_load != priv->last_bt_traffic_load) || + (priv->bt_full_concurrent != full_concurrent)) { priv->bt_full_concurrent = full_concurrent; /* Update uCode's rate table. */ @@ -1040,8 +1046,7 @@ done: if (sta && sta->supp_rates[sband->band]) rs_rate_scale_perform(priv, skb, sta, lq_sta); - /* Is there a need to switch between full concurrency and 3-wire? */ - if (priv->bt_ant_couple_ok) + if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) rs_bt_update_lq(priv, ctx, lq_sta); } @@ -3010,10 +3015,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, */ if (priv && priv->cfg->bt_params && priv->cfg->bt_params->agg_time_limit && - priv->cfg->bt_params->agg_time_limit >= - LINK_QUAL_AGG_TIME_LIMIT_MIN && - priv->cfg->bt_params->agg_time_limit <= - LINK_QUAL_AGG_TIME_LIMIT_MAX) + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) lq_cmd->agg_params.agg_time_limit = cpu_to_le16(priv->cfg->bt_params->agg_time_limit); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 2d927a9..203ee60 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -72,6 +72,34 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, return ret; } +static void iwlagn_update_qos(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + int ret; + + if (!ctx->is_active) + return; + + ctx->qos_data.def_qos_parm.qos_flags = 0; + + if (ctx->qos_data.qos_active) + ctx->qos_data.def_qos_parm.qos_flags |= + QOS_PARAM_FLG_UPDATE_EDCA_MSK; + + if (ctx->ht.enabled) + ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; + + IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", + ctx->qos_data.qos_active, + ctx->qos_data.def_qos_parm.qos_flags); + + ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd, + sizeof(struct iwl_qosparam_cmd), + &ctx->qos_data.def_qos_parm); + if (ret) + IWL_ERR(priv, "Failed to update QoS\n"); +} + static int iwlagn_update_beacon(struct iwl_priv *priv, struct ieee80211_vif *vif) { @@ -97,6 +125,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) /* cast away the const for active_rxon in this function */ struct iwl_rxon_cmd *active = (void *)&ctx->active; bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); + bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK); int ret; lockdep_assert_held(&priv->mutex); @@ -176,25 +205,27 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) * AP station must be done after the BSSID is set to correctly * set up filters in the device. */ - if (ctx->ctxid == IWL_RXON_CTX_BSS) - ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); - else - ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); - if (ret) - return ret; + if ((old_assoc && new_assoc) || !new_assoc) { + if (ctx->ctxid == IWL_RXON_CTX_BSS) + ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); + else + ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); + if (ret) + return ret; - memcpy(active, &ctx->staging, sizeof(*active)); + memcpy(active, &ctx->staging, sizeof(*active)); - /* - * Un-assoc RXON clears the station table and WEP - * keys, so we have to restore those afterwards. - */ - iwl_clear_ucode_stations(priv, ctx); - iwl_restore_stations(priv, ctx); - ret = iwl_restore_default_wep_keys(priv, ctx); - if (ret) { - IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); - return ret; + /* + * Un-assoc RXON clears the station table and WEP + * keys, so we have to restore those afterwards. + */ + iwl_clear_ucode_stations(priv, ctx); + iwl_restore_stations(priv, ctx); + ret = iwl_restore_default_wep_keys(priv, ctx); + if (ret) { + IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); + return ret; + } } /* RXON timing must be before associated RXON */ @@ -205,6 +236,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } if (new_assoc) { + /* QoS info may be cleared by previous un-assoc RXON */ + iwlagn_update_qos(priv, ctx); + /* * We'll run into this code path when beaconing is * enabled, but then we also need to send the beacon @@ -235,6 +269,8 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } memcpy(active, &ctx->staging, sizeof(*active)); + iwl_reprogram_ap_sta(priv, ctx); + /* IBSS beacon needs to be sent after setting assoc */ if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) if (iwlagn_update_beacon(priv, ctx->vif)) @@ -261,34 +297,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) return 0; } -static void iwlagn_update_qos(struct iwl_priv *priv, - struct iwl_rxon_context *ctx) -{ - int ret; - - if (!ctx->is_active) - return; - - ctx->qos_data.def_qos_parm.qos_flags = 0; - - if (ctx->qos_data.qos_active) - ctx->qos_data.def_qos_parm.qos_flags |= - QOS_PARAM_FLG_UPDATE_EDCA_MSK; - - if (ctx->ht.enabled) - ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; - - IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", - ctx->qos_data.qos_active, - ctx->qos_data.def_qos_parm.qos_flags); - - ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd, - sizeof(struct iwl_qosparam_cmd), - &ctx->qos_data.def_qos_parm); - if (ret) - IWL_ERR(priv, "Failed to update QoS\n"); -} - int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) { struct iwl_priv *priv = hw->priv; @@ -507,6 +515,11 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); + if (WARN_ON(!ctx->vif)) { + mutex_unlock(&priv->mutex); + return; + } + if (changes & BSS_CHANGED_BEACON_INT) force = true; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 1205cec..07bbc91 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -518,7 +518,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) struct iwl_cmd_meta *out_meta; struct iwl_tx_cmd *tx_cmd; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - int swq_id, txq_id; + int txq_id; dma_addr_t phys_addr; dma_addr_t txcmd_phys; dma_addr_t scratch_phys; @@ -620,7 +620,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) } txq = &priv->txq[txq_id]; - swq_id = txq->swq_id; q = &txq->q; if (unlikely(iwl_queue_space(q) < q->high_mark)) { @@ -775,7 +774,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) iwl_txq_update_write_ptr(priv, txq); spin_unlock_irqrestore(&priv->lock, flags); } else { - iwl_stop_queue(priv, txq->swq_id); + iwl_stop_queue(priv, txq); } } @@ -1004,7 +1003,7 @@ 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; - priv->txq[txq_id].swq_id = iwl_virtual_agg_queue_num(get_ac_from_tid(tid), txq_id); + 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, @@ -1232,37 +1231,61 @@ static int iwlagn_tx_status_reply_compressed_ba(struct iwl_priv *priv, if (sh < 0) /* tbw something is wrong with indices */ sh += 0x100; - /* don't use 64-bit values for now */ - bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; - if (agg->frame_count > (64 - sh)) { IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size"); return -1; } - - /* 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; + if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) { + /* + * sent and ack information provided by uCode + * use it instead of figure out ourself + */ + 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 { + /* 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; + } } - 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; - info->status.ampdu_ack_len = successes; - info->status.ampdu_len = agg->frame_count; + 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; + } iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info); IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n", (unsigned long long)bitmap); @@ -1376,7 +1399,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && priv->mac80211_registered && (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) - iwl_wake_queue(priv, txq->swq_id); + iwl_wake_queue(priv, txq); iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow); } diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 7036211..411a7a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -40,30 +40,36 @@ #include "iwl-agn.h" #include "iwl-agn-calib.h" -static const s8 iwlagn_default_queue_to_tx_fifo[] = { - IWL_TX_FIFO_VO, - IWL_TX_FIFO_VI, - IWL_TX_FIFO_BE, - IWL_TX_FIFO_BK, - IWLAGN_CMD_FIFO_NUM, - IWL_TX_FIFO_UNUSED, - IWL_TX_FIFO_UNUSED, - IWL_TX_FIFO_UNUSED, - IWL_TX_FIFO_UNUSED, - IWL_TX_FIFO_UNUSED, +#define IWL_AC_UNSET -1 + +struct queue_to_fifo_ac { + s8 fifo, ac; +}; + +static const struct queue_to_fifo_ac iwlagn_default_queue_to_tx_fifo[] = { + { IWL_TX_FIFO_VO, 0, }, + { IWL_TX_FIFO_VI, 1, }, + { IWL_TX_FIFO_BE, 2, }, + { IWL_TX_FIFO_BK, 3, }, + { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, + { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, + { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, + { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, + { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, + { IWL_TX_FIFO_UNUSED, IWL_AC_UNSET, }, }; -static const s8 iwlagn_ipan_queue_to_tx_fifo[] = { - IWL_TX_FIFO_VO, - IWL_TX_FIFO_VI, - IWL_TX_FIFO_BE, - IWL_TX_FIFO_BK, - IWL_TX_FIFO_BK_IPAN, - IWL_TX_FIFO_BE_IPAN, - IWL_TX_FIFO_VI_IPAN, - IWL_TX_FIFO_VO_IPAN, - IWL_TX_FIFO_BE_IPAN, - IWLAGN_CMD_FIFO_NUM, +static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = { + { IWL_TX_FIFO_VO, 0, }, + { IWL_TX_FIFO_VI, 1, }, + { IWL_TX_FIFO_BE, 2, }, + { IWL_TX_FIFO_BK, 3, }, + { IWL_TX_FIFO_BK_IPAN, 3, }, + { IWL_TX_FIFO_BE_IPAN, 2, }, + { IWL_TX_FIFO_VI_IPAN, 1, }, + { IWL_TX_FIFO_VO_IPAN, 0, }, + { IWL_TX_FIFO_BE_IPAN, 2, }, + { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, }; static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { @@ -429,7 +435,7 @@ void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) int iwlagn_alive_notify(struct iwl_priv *priv) { - const s8 *queues; + const struct queue_to_fifo_ac *queue_to_fifo; u32 a; unsigned long flags; int i, chan; @@ -492,9 +498,9 @@ int iwlagn_alive_notify(struct iwl_priv *priv) /* map queues to FIFOs */ if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) - queues = iwlagn_ipan_queue_to_tx_fifo; + queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo; else - queues = iwlagn_default_queue_to_tx_fifo; + queue_to_fifo = iwlagn_default_queue_to_tx_fifo; iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0); @@ -510,14 +516,17 @@ int iwlagn_alive_notify(struct iwl_priv *priv) BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10); for (i = 0; i < 10; i++) { - int ac = queues[i]; + int fifo = queue_to_fifo[i].fifo; + int ac = queue_to_fifo[i].ac; iwl_txq_ctx_activate(priv, i); - if (ac == IWL_TX_FIFO_UNUSED) + if (fifo == IWL_TX_FIFO_UNUSED) continue; - iwlagn_tx_queue_set_status(priv, &priv->txq[i], ac, 0); + if (ac != IWL_AC_UNSET) + iwl_set_swq_id(&priv->txq[i], ac, i); + iwlagn_tx_queue_set_status(priv, &priv->txq[i], fifo, 0); } spin_unlock_irqrestore(&priv->lock, flags); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 007fb20..5b96b0d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -97,7 +97,8 @@ void iwl_update_chain_flags(struct iwl_priv *priv) if (priv->cfg->ops->hcmd->set_rxon_chain) { for_each_context(priv, ctx) { priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - iwlcore_commit_rxon(priv, ctx); + if (ctx->active.rx_chain != ctx->staging.rx_chain) + iwlcore_commit_rxon(priv, ctx); } } } @@ -2716,6 +2717,8 @@ static void iwl_alive_start(struct iwl_priv *priv) iwl_reset_run_time_calib(priv); + set_bit(STATUS_READY, &priv->status); + /* Configure the adapter for unassociated operation */ iwlcore_commit_rxon(priv, ctx); @@ -2725,7 +2728,6 @@ static void iwl_alive_start(struct iwl_priv *priv) iwl_leds_init(priv); IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); - set_bit(STATUS_READY, &priv->status); wake_up_interruptible(&priv->wait_command_queue); iwl_power_update_mode(priv, true); @@ -3837,7 +3839,6 @@ static int iwl_init_drv(struct iwl_priv *priv) priv->bt_on_thresh = BT_ON_THRESHOLD_DEF; priv->bt_duration = BT_DURATION_LIMIT_DEF; priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; - priv->dynamic_agg_thresh = BT_AGG_THRESHOLD_DEF; } /* Set the tx_power_user_lmt to the lowest power level @@ -4135,6 +4136,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (err) goto out_free_eeprom; + err = iwl_eeprom_check_sku(priv); + if (err) + goto out_free_eeprom; + /* extract MAC Address */ iwl_eeprom_get_mac(priv, priv->addresses[0].addr); IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr); diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 424801a..9c1b7fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2022,6 +2022,9 @@ struct iwl_compressed_ba_resp { __le64 bitmap; __le16 scd_flow; __le16 scd_ssn; + /* following only for 5000 series and up */ + u8 txed; /* number of frames sent */ + u8 txed_2_done; /* number of frames acked */ } __packed; /* @@ -2407,9 +2410,9 @@ struct iwl_link_quality_cmd { #define BT_FRAG_THRESHOLD_MAX 0 #define BT_FRAG_THRESHOLD_MIN 0 -#define BT_AGG_THRESHOLD_DEF 0 -#define BT_AGG_THRESHOLD_MAX 0 -#define BT_AGG_THRESHOLD_MIN 0 +#define BT_AGG_THRESHOLD_DEF 1200 +#define BT_AGG_THRESHOLD_MAX 8000 +#define BT_AGG_THRESHOLD_MIN 400 /* * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) @@ -2447,8 +2450,8 @@ struct iwl_bt_cmd { #define IWLAGN_BT3_T7_DEFAULT 1 -#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff) -#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff) +#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffff0000) +#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffff0000) #define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2 diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c884ed3..c41f5a87 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1469,7 +1469,7 @@ static void iwl_teardown_interface(struct iwl_priv *priv, * both values are the same and zero. */ if (vif->type == NL80211_IFTYPE_ADHOC) - priv->bt_traffic_load = priv->notif_bt_traffic_load; + priv->bt_traffic_load = priv->last_bt_traffic_load; } void iwl_mac_remove_interface(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index ee8cf24..9035cd8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -291,7 +291,9 @@ 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; int num_of_queues; /* def: HW dependent */ @@ -322,6 +324,7 @@ 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 @@ -360,6 +363,7 @@ struct iwl_ht_params { * @need_dc_calib: need to perform init dc calibration * @need_temp_offset_calib: need to perform temperature offset calibration * @scan_antennas: available antenna for scan operation + * @led_mode: 0=blinking, 1=On(RF On)/Off(RF Off) * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -406,6 +410,7 @@ struct iwl_cfg { const bool need_temp_offset_calib; /* if used set to true */ u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; + enum iwl_led_mode led_mode; }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 8fdd4ef..3cc5842 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -992,11 +992,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, " swq_id=%#.2x (ac %d/hwq %d)\n", cnt, q->read_ptr, q->write_ptr, !!test_bit(cnt, priv->queue_stopped), - txq->swq_id, - txq->swq_id & 0x80 ? txq->swq_id & 3 : - txq->swq_id, - txq->swq_id & 0x80 ? (txq->swq_id >> 2) & - 0x1f : txq->swq_id); + txq->swq_id, txq->swq_id & 3, + (txq->swq_id >> 2) & 0x1f); if (cnt >= 4) continue; /* for the ACs, display the stop count too */ @@ -1580,7 +1577,7 @@ static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, priv->bt_full_concurrent ? "full concurrency" : "3-wire"); pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, " "last traffic notif: %d\n", - priv->bt_status ? "On" : "Off", priv->notif_bt_traffic_load); + priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load); pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, " "sco_active: %d, kill_ack_mask: %x, " "kill_cts_mask: %x\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 9fcaaf0..ea81ced 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1471,7 +1471,7 @@ struct iwl_priv { /* bt coex */ u8 bt_status; - u8 bt_traffic_load, notif_bt_traffic_load; + u8 bt_traffic_load, last_bt_traffic_load; bool bt_ch_announce; bool bt_sco_active; bool bt_full_concurrent; @@ -1482,7 +1482,6 @@ struct iwl_priv { u16 bt_on_thresh; u16 bt_duration; u16 dynamic_frag_thresh; - u16 dynamic_agg_thresh; u8 bt_ci_compliance; struct work_struct bt_traffic_change_work; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index d9b5906..e87be1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -110,9 +110,18 @@ enum { }; /* SKU Capabilities */ +/* 3945 only */ #define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0) #define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1) +/* 5000 and up */ +#define EEPROM_SKU_CAP_BAND_POS (4) +#define EEPROM_SKU_CAP_BAND_SELECTION \ + (3 << EEPROM_SKU_CAP_BAND_POS) +#define EEPROM_SKU_CAP_11N_ENABLE (1 << 6) +#define EEPROM_SKU_CAP_AMT_ENABLE (1 << 7) +#define EEPROM_SKU_CAP_IPAN_ENABLE (1 << 8) + /* *regulatory* channel data format in eeprom, one for each channel. * There are separate entries for HT40 (40 MHz) vs. normal (20 MHz) channels. */ struct iwl_eeprom_channel { @@ -397,7 +406,7 @@ struct iwl_eeprom_calib_info { #define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ #define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ #define EEPROM_VERSION (2*0x44) /* 2 bytes */ -#define EEPROM_SKU_CAP (2*0x45) /* 1 bytes */ +#define EEPROM_SKU_CAP (2*0x45) /* 2 bytes */ #define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ #define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ #define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */ @@ -504,6 +513,7 @@ struct iwl_eeprom_ops { int iwl_eeprom_init(struct iwl_priv *priv); void iwl_eeprom_free(struct iwl_priv *priv); int iwl_eeprom_check_version(struct iwl_priv *priv); +int iwl_eeprom_check_sku(struct iwl_priv *priv); const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); int iwlcore_eeprom_verify_signature(struct iwl_priv *priv); u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset); diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 9233683..3f5bedd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -95,42 +95,36 @@ static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, * | | | | | | | | * | | | | | | +-+-------- AC queue (0-3) * | | | | | | - * | +-+-+-+-+------------ HW A-MPDU queue + * | +-+-+-+-+------------ HW queue ID * | - * +---------------------- indicates agg queue + * +---------------------- unused */ -static inline u8 iwl_virtual_agg_queue_num(u8 ac, u8 hwq) +static inline void iwl_set_swq_id(struct iwl_tx_queue *txq, u8 ac, u8 hwq) { BUG_ON(ac > 3); /* only have 2 bits */ - BUG_ON(hwq > 31); /* only have 5 bits */ + BUG_ON(hwq > 31); /* only use 5 bits */ - return 0x80 | (hwq << 2) | ac; + txq->swq_id = (hwq << 2) | ac; } -static inline void iwl_wake_queue(struct iwl_priv *priv, u8 queue) +static inline void iwl_wake_queue(struct iwl_priv *priv, + struct iwl_tx_queue *txq) { - u8 ac = queue; - u8 hwq = queue; - - if (queue & 0x80) { - ac = queue & 3; - hwq = (queue >> 2) & 0x1f; - } + u8 queue = txq->swq_id; + u8 ac = queue & 3; + u8 hwq = (queue >> 2) & 0x1f; if (test_and_clear_bit(hwq, priv->queue_stopped)) if (atomic_dec_return(&priv->queue_stop_count[ac]) <= 0) ieee80211_wake_queue(priv->hw, ac); } -static inline void iwl_stop_queue(struct iwl_priv *priv, u8 queue) +static inline void iwl_stop_queue(struct iwl_priv *priv, + struct iwl_tx_queue *txq) { - u8 ac = queue; - u8 hwq = queue; - - if (queue & 0x80) { - ac = queue & 3; - hwq = (queue >> 2) & 0x1f; - } + u8 queue = txq->swq_id; + u8 ac = queue & 3; + u8 hwq = (queue >> 2) & 0x1f; if (!test_and_set_bit(hwq, priv->queue_stopped)) if (atomic_inc_return(&priv->queue_stop_count[ac]) > 0) diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 5a91292..516e557 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -45,9 +45,8 @@ /* default: IWL_LED_BLINK(0) using blinking index table */ static int led_mode; module_param(led_mode, int, S_IRUGO); -MODULE_PARM_DESC(led_mode, "led mode: 0=blinking, 1=On(RF On)/Off(RF Off), " - "(default 0)"); - +MODULE_PARM_DESC(led_mode, "led mode: 0=system default, " + "1=On(RF On)/Off(RF Off), 2=blinking"); static const struct { u16 tpt; /* Mb/s */ @@ -128,7 +127,7 @@ EXPORT_SYMBOL(iwl_led_start); int iwl_led_associate(struct iwl_priv *priv) { IWL_DEBUG_LED(priv, "Associated\n"); - if (led_mode == IWL_LED_BLINK) + if (priv->cfg->led_mode == IWL_LED_BLINK) priv->allow_blinking = 1; priv->last_blink_time = jiffies; @@ -223,5 +222,8 @@ void iwl_leds_init(struct iwl_priv *priv) priv->last_blink_rate = 0; priv->last_blink_time = 0; priv->allow_blinking = 0; + if (led_mode != IWL_LED_DEFAULT && + led_mode != priv->cfg->led_mode) + priv->cfg->led_mode = led_mode; } EXPORT_SYMBOL(iwl_leds_init); diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 49a70ba..9079b33 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h @@ -47,14 +47,16 @@ enum led_type { /* * LED mode - * IWL_LED_BLINK: adjust led blink rate based on blink table + * IWL_LED_DEFAULT: use system default * IWL_LED_RF_STATE: turn LED on/off based on RF state * LED ON = RF ON * LED OFF = RF OFF + * IWL_LED_BLINK: adjust led blink rate based on blink table */ enum iwl_led_mode { - IWL_LED_BLINK, + IWL_LED_DEFAULT, IWL_LED_RF_STATE, + IWL_LED_BLINK, }; void iwl_leds_init(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 7c7f7dc..0a67b2f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -400,7 +400,8 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id) } static int iwl_send_remove_station(struct iwl_priv *priv, - const u8 *addr, int sta_id) + const u8 *addr, int sta_id, + bool temporary) { struct iwl_rx_packet *pkt; int ret; @@ -436,9 +437,11 @@ static int iwl_send_remove_station(struct iwl_priv *priv, if (!ret) { switch (pkt->u.rem_sta.status) { case REM_STA_SUCCESS_MSK: - spin_lock_irqsave(&priv->sta_lock, flags_spin); - iwl_sta_ucode_deactivate(priv, sta_id); - spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + if (!temporary) { + spin_lock_irqsave(&priv->sta_lock, flags_spin); + iwl_sta_ucode_deactivate(priv, sta_id); + spin_unlock_irqrestore(&priv->sta_lock, flags_spin); + } IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); break; default: @@ -505,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, spin_unlock_irqrestore(&priv->sta_lock, flags); - return iwl_send_remove_station(priv, addr, sta_id); + return iwl_send_remove_station(priv, addr, sta_id, false); out_err: spin_unlock_irqrestore(&priv->sta_lock, flags); return -EINVAL; @@ -624,6 +627,44 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } EXPORT_SYMBOL(iwl_restore_stations); +void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + unsigned long flags; + int sta_id = ctx->ap_sta_id; + int ret; + struct iwl_addsta_cmd sta_cmd; + struct iwl_link_quality_cmd lq; + bool active; + + spin_lock_irqsave(&priv->sta_lock, flags); + if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { + spin_unlock_irqrestore(&priv->sta_lock, flags); + return; + } + + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd)); + sta_cmd.mode = 0; + memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); + + active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + if (active) { + ret = iwl_send_remove_station( + priv, priv->stations[sta_id].sta.sta.addr, + sta_id, true); + if (ret) + IWL_ERR(priv, "failed to remove STA %pM (%d)\n", + priv->stations[sta_id].sta.sta.addr, ret); + } + ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); + if (ret) + IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", + priv->stations[sta_id].sta.sta.addr, ret); + iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); +} +EXPORT_SYMBOL(iwl_reprogram_ap_sta); + int iwl_get_free_ucode_key_index(struct iwl_priv *priv) { int i; diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 0647587..206f1e1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -63,6 +63,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq, u8 flags, bool init); +void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx); /** * iwl_clear_driver_stations - clear knowledge of all stations from driver diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index feaa367..90659bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -359,13 +359,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, txq->need_update = 0; /* - * Aggregation TX queues will get their ID when aggregation begins; - * they overwrite the setting done here. The command FIFO doesn't - * need an swq_id so don't set one to catch errors, all others can - * be set up to the identity mapping. + * For the default queues 0-3, set up the swq_id + * already -- all others need to get one later + * (if they need one at all). */ - if (txq_id != priv->cmd_queue) - txq->swq_id = txq_id; + if (txq_id < 4) + iwl_set_swq_id(txq, txq_id, txq_id); /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 6d09c09..c3ebc04 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -655,7 +655,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) spin_unlock_irqrestore(&priv->lock, flags); } - iwl_stop_queue(priv, skb_get_queue_mapping(skb)); + iwl_stop_queue(priv, txq); } return 0; |