aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-06-02 15:36:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-02 15:36:51 -0400
commit1c62c72b1a3c4478fb9069503d20c41b1f385ca1 (patch)
tree939634bedbabfcd389ab7ad96ab7e161e25b2061 /drivers/net
parentda1fdb02d9200ff28b6f3a380d21930335fe5429 (diff)
parent9f6e1bafac4f3c58c8a670496adcc4d313d3c7f7 (diff)
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')
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c286
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c91
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c46
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c123
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c196
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h34
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c131
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c81
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h58
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c63
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c72
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c53
24 files changed, 916 insertions, 458 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index dc8ed1527666..6491e27baac5 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -30,9 +30,11 @@ config IWLWIFI_DEBUG
30 30
31config IWLWIFI_DEBUGFS 31config IWLWIFI_DEBUGFS
32 bool "iwlagn debugfs support" 32 bool "iwlagn debugfs support"
33 depends on IWLWIFI && IWLWIFI_DEBUG && MAC80211_DEBUGFS 33 depends on IWLWIFI && MAC80211_DEBUGFS
34 ---help--- 34 ---help---
35 Enable creation of debugfs files for the iwlwifi drivers. 35 Enable creation of debugfs files for the iwlwifi drivers. This
36 is a low-impact option that allows getting insight into the
37 driver's state at runtime.
36 38
37config IWLWIFI_DEVICE_TRACING 39config IWLWIFI_DEVICE_TRACING
38 bool "iwlwifi device access tracing" 40 bool "iwlwifi device access tracing"
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c
index 6a9c64a50e36..ef0835b01b6b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-debugfs.c
@@ -28,6 +28,28 @@
28 28
29#include "iwl-3945-debugfs.h" 29#include "iwl-3945-debugfs.h"
30 30
31
32static int iwl3945_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
33{
34 int p = 0;
35
36 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
37 le32_to_cpu(priv->_3945.statistics.flag));
38 if (le32_to_cpu(priv->_3945.statistics.flag) &
39 UCODE_STATISTICS_CLEAR_MSK)
40 p += scnprintf(buf + p, bufsz - p,
41 "\tStatistics have been cleared\n");
42 p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
43 (le32_to_cpu(priv->_3945.statistics.flag) &
44 UCODE_STATISTICS_FREQUENCY_MSK)
45 ? "2.4 GHz" : "5.2 GHz");
46 p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
47 (le32_to_cpu(priv->_3945.statistics.flag) &
48 UCODE_STATISTICS_NARROW_BAND_MSK)
49 ? "enabled" : "disabled");
50 return p;
51}
52
31ssize_t iwl3945_ucode_rx_stats_read(struct file *file, 53ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
32 char __user *user_buf, 54 char __user *user_buf,
33 size_t count, loff_t *ppos) 55 size_t count, loff_t *ppos)
@@ -70,7 +92,7 @@ ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
70 max_cck = &priv->_3945.max_delta.rx.cck; 92 max_cck = &priv->_3945.max_delta.rx.cck;
71 max_general = &priv->_3945.max_delta.rx.general; 93 max_general = &priv->_3945.max_delta.rx.general;
72 94
73 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 95 pos += iwl3945_statistics_flag(priv, buf, bufsz);
74 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 96 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
75 "acumulative delta max\n", 97 "acumulative delta max\n",
76 "Statistics_Rx - OFDM:"); 98 "Statistics_Rx - OFDM:");
@@ -331,7 +353,7 @@ ssize_t iwl3945_ucode_tx_stats_read(struct file *file,
331 accum_tx = &priv->_3945.accum_statistics.tx; 353 accum_tx = &priv->_3945.accum_statistics.tx;
332 delta_tx = &priv->_3945.delta_statistics.tx; 354 delta_tx = &priv->_3945.delta_statistics.tx;
333 max_tx = &priv->_3945.max_delta.tx; 355 max_tx = &priv->_3945.max_delta.tx;
334 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 356 pos += iwl3945_statistics_flag(priv, buf, bufsz);
335 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 357 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
336 "acumulative delta max\n", 358 "acumulative delta max\n",
337 "Statistics_Tx:"); 359 "Statistics_Tx:");
@@ -438,7 +460,7 @@ ssize_t iwl3945_ucode_general_stats_read(struct file *file,
438 accum_div = &priv->_3945.accum_statistics.general.div; 460 accum_div = &priv->_3945.accum_statistics.general.div;
439 delta_div = &priv->_3945.delta_statistics.general.div; 461 delta_div = &priv->_3945.delta_statistics.general.div;
440 max_div = &priv->_3945.max_delta.general.div; 462 max_div = &priv->_3945.max_delta.general.div;
441 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 463 pos += iwl3945_statistics_flag(priv, buf, bufsz);
442 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 464 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
443 "acumulative delta max\n", 465 "acumulative delta max\n",
444 "Statistics_General:"); 466 "Statistics_General:");
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 068f7f8435c5..de915c4b9e5c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -352,7 +352,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
352 * RX handler implementations 352 * RX handler implementations
353 * 353 *
354 *****************************************************************************/ 354 *****************************************************************************/
355#ifdef CONFIG_IWLWIFI_DEBUG 355#ifdef CONFIG_IWLWIFI_DEBUGFS
356/* 356/*
357 * based on the assumption of all statistics counter are in DWORD 357 * based on the assumption of all statistics counter are in DWORD
358 * FIXME: This function is for debugging, do not deal with 358 * FIXME: This function is for debugging, do not deal with
@@ -460,7 +460,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
460 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 460 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
461 (int)sizeof(struct iwl3945_notif_statistics), 461 (int)sizeof(struct iwl3945_notif_statistics),
462 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); 462 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
463#ifdef CONFIG_IWLWIFI_DEBUG 463#ifdef CONFIG_IWLWIFI_DEBUGFS
464 iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw); 464 iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw);
465#endif 465#endif
466 iwl_recover_from_statistics(priv, pkt); 466 iwl_recover_from_statistics(priv, pkt);
@@ -475,7 +475,7 @@ void iwl3945_reply_statistics(struct iwl_priv *priv,
475 __le32 *flag = (__le32 *)&pkt->u.raw; 475 __le32 *flag = (__le32 *)&pkt->u.raw;
476 476
477 if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) { 477 if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) {
478#ifdef CONFIG_IWLWIFI_DEBUG 478#ifdef CONFIG_IWLWIFI_DEBUGFS
479 memset(&priv->_3945.accum_statistics, 0, 479 memset(&priv->_3945.accum_statistics, 0,
480 sizeof(struct iwl3945_notif_statistics)); 480 sizeof(struct iwl3945_notif_statistics));
481 memset(&priv->_3945.delta_statistics, 0, 481 memset(&priv->_3945.delta_statistics, 0,
@@ -947,8 +947,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
947 tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]); 947 tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]);
948} 948}
949 949
950static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, 950static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate)
951 u16 tx_rate, u8 flags)
952{ 951{
953 unsigned long flags_spin; 952 unsigned long flags_spin;
954 struct iwl_station_entry *station; 953 struct iwl_station_entry *station;
@@ -962,10 +961,9 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
962 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; 961 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
963 station->sta.rate_n_flags = cpu_to_le16(tx_rate); 962 station->sta.rate_n_flags = cpu_to_le16(tx_rate);
964 station->sta.mode = STA_CONTROL_MODIFY_MSK; 963 station->sta.mode = STA_CONTROL_MODIFY_MSK;
965 964 iwl_send_add_sta(priv, &station->sta, CMD_ASYNC);
966 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 965 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
967 966
968 iwl_send_add_sta(priv, &station->sta, flags);
969 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", 967 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
970 sta_id, tx_rate); 968 sta_id, tx_rate);
971 return sta_id; 969 return sta_id;
@@ -2473,8 +2471,7 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
2473 2471
2474 iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id, 2472 iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id,
2475 (priv->band == IEEE80211_BAND_5GHZ) ? 2473 (priv->band == IEEE80211_BAND_5GHZ) ?
2476 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, 2474 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP);
2477 CMD_ASYNC);
2478 iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id); 2475 iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id);
2479 2476
2480 return 0; 2477 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index d3afddae8d9f..ad4d7d11c3b8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1542,7 +1542,7 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
1542 u32 R4; 1542 u32 R4;
1543 1543
1544 if (test_bit(STATUS_TEMPERATURE, &priv->status) && 1544 if (test_bit(STATUS_TEMPERATURE, &priv->status) &&
1545 (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)) { 1545 (priv->_agn.statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)) {
1546 IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n"); 1546 IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n");
1547 R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]); 1547 R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]);
1548 R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]); 1548 R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]);
@@ -1567,7 +1567,7 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
1567 vt = sign_extend(R4, 23); 1567 vt = sign_extend(R4, 23);
1568 else 1568 else
1569 vt = sign_extend( 1569 vt = sign_extend(
1570 le32_to_cpu(priv->statistics.general.temperature), 23); 1570 le32_to_cpu(priv->_agn.statistics.general.temperature), 23);
1571 1571
1572 IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); 1572 IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
1573 1573
@@ -2026,6 +2026,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2026 int sta_id; 2026 int sta_id;
2027 int freed; 2027 int freed;
2028 u8 *qc = NULL; 2028 u8 *qc = NULL;
2029 unsigned long flags;
2029 2030
2030 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { 2031 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
2031 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " 2032 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
@@ -2050,10 +2051,10 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2050 return; 2051 return;
2051 } 2052 }
2052 2053
2054 spin_lock_irqsave(&priv->sta_lock, flags);
2053 if (txq->sched_retry) { 2055 if (txq->sched_retry) {
2054 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); 2056 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
2055 struct iwl_ht_agg *agg = NULL; 2057 struct iwl_ht_agg *agg = NULL;
2056
2057 WARN_ON(!qc); 2058 WARN_ON(!qc);
2058 2059
2059 agg = &priv->stations[sta_id].tid[tid].agg; 2060 agg = &priv->stations[sta_id].tid[tid].agg;
@@ -2110,6 +2111,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2110 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); 2111 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
2111 2112
2112 iwl_check_abort_status(priv, tx_resp->frame_count, status); 2113 iwl_check_abort_status(priv, tx_resp->frame_count, status);
2114
2115 spin_unlock_irqrestore(&priv->sta_lock, flags);
2113} 2116}
2114 2117
2115static int iwl4965_calc_rssi(struct iwl_priv *priv, 2118static int iwl4965_calc_rssi(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index a28af7eb67eb..447ec4885a41 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -260,7 +260,7 @@ static void iwl5150_temperature(struct iwl_priv *priv)
260 u32 vt = 0; 260 u32 vt = 0;
261 s32 offset = iwl_temp_calib_to_offset(priv); 261 s32 offset = iwl_temp_calib_to_offset(priv);
262 262
263 vt = le32_to_cpu(priv->statistics.general.temperature); 263 vt = le32_to_cpu(priv->_agn.statistics.general.temperature);
264 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; 264 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
265 /* now vt hold the temperature in Kelvin */ 265 /* now vt hold the temperature in Kelvin */
266 priv->temperature = KELVIN_TO_CELSIUS(vt); 266 priv->temperature = KELVIN_TO_CELSIUS(vt);
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 9fbf54cd3e1a..73713f6a8df4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -71,6 +71,10 @@
71#define _IWL6000G2A_MODULE_FIRMWARE(api) IWL6000G2A_FW_PRE #api ".ucode" 71#define _IWL6000G2A_MODULE_FIRMWARE(api) IWL6000G2A_FW_PRE #api ".ucode"
72#define IWL6000G2A_MODULE_FIRMWARE(api) _IWL6000G2A_MODULE_FIRMWARE(api) 72#define IWL6000G2A_MODULE_FIRMWARE(api) _IWL6000G2A_MODULE_FIRMWARE(api)
73 73
74#define IWL6000G2B_FW_PRE "iwlwifi-6000g2b-"
75#define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode"
76#define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api)
77
74 78
75static void iwl6000_set_ct_threshold(struct iwl_priv *priv) 79static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
76{ 80{
@@ -335,6 +339,25 @@ static const struct iwl_ops iwl6000_ops = {
335 .led = &iwlagn_led_ops, 339 .led = &iwlagn_led_ops,
336}; 340};
337 341
342static void do_not_send_bt_config(struct iwl_priv *priv)
343{
344}
345
346static struct iwl_hcmd_ops iwl6000g2b_hcmd = {
347 .rxon_assoc = iwlagn_send_rxon_assoc,
348 .commit_rxon = iwl_commit_rxon,
349 .set_rxon_chain = iwl_set_rxon_chain,
350 .set_tx_ant = iwlagn_send_tx_ant_config,
351 .send_bt_config = do_not_send_bt_config,
352};
353
354static const struct iwl_ops iwl6000g2b_ops = {
355 .lib = &iwl6000_lib,
356 .hcmd = &iwl6000g2b_hcmd,
357 .utils = &iwlagn_hcmd_utils,
358 .led = &iwlagn_led_ops,
359};
360
338static struct iwl_lib_ops iwl6050_lib = { 361static struct iwl_lib_ops iwl6050_lib = {
339 .set_hw_params = iwl6050_hw_set_hw_params, 362 .set_hw_params = iwl6050_hw_set_hw_params,
340 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, 363 .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
@@ -445,6 +468,268 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
445 .chain_noise_calib_by_driver = true, 468 .chain_noise_calib_by_driver = true,
446}; 469};
447 470
471struct iwl_cfg iwl6000g2a_2abg_cfg = {
472 .name = "6000 Series 2x2 ABG Gen2a",
473 .fw_name_pre = IWL6000G2A_FW_PRE,
474 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
475 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
476 .sku = IWL_SKU_A|IWL_SKU_G,
477 .ops = &iwl6000_ops,
478 .eeprom_size = OTP_LOW_IMAGE_SIZE,
479 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
480 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
481 .num_of_queues = IWLAGN_NUM_QUEUES,
482 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
483 .mod_params = &iwlagn_mod_params,
484 .valid_tx_ant = ANT_AB,
485 .valid_rx_ant = ANT_AB,
486 .pll_cfg_val = 0,
487 .set_l0s = true,
488 .use_bsm = false,
489 .pa_type = IWL_PA_SYSTEM,
490 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
491 .shadow_ram_support = true,
492 .led_compensation = 51,
493 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
494 .supports_idle = true,
495 .adv_thermal_throttle = true,
496 .support_ct_kill_exit = true,
497 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
498 .chain_noise_scale = 1000,
499 .monitor_recover_period = IWL_MONITORING_PERIOD,
500 .max_event_log_size = 512,
501};
502
503struct iwl_cfg iwl6000g2a_2bg_cfg = {
504 .name = "6000 Series 2x2 BG Gen2a",
505 .fw_name_pre = IWL6000G2A_FW_PRE,
506 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
507 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
508 .sku = IWL_SKU_G,
509 .ops = &iwl6000_ops,
510 .eeprom_size = OTP_LOW_IMAGE_SIZE,
511 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
512 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
513 .num_of_queues = IWLAGN_NUM_QUEUES,
514 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
515 .mod_params = &iwlagn_mod_params,
516 .valid_tx_ant = ANT_AB,
517 .valid_rx_ant = ANT_AB,
518 .pll_cfg_val = 0,
519 .set_l0s = true,
520 .use_bsm = false,
521 .pa_type = IWL_PA_SYSTEM,
522 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
523 .shadow_ram_support = true,
524 .led_compensation = 51,
525 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
526 .supports_idle = true,
527 .adv_thermal_throttle = true,
528 .support_ct_kill_exit = true,
529 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
530 .chain_noise_scale = 1000,
531 .monitor_recover_period = IWL_MONITORING_PERIOD,
532 .max_event_log_size = 512,
533};
534
535struct iwl_cfg iwl6000g2b_2agn_cfg = {
536 .name = "6000 Series 2x2 AGN Gen2b",
537 .fw_name_pre = IWL6000G2B_FW_PRE,
538 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
539 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
540 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
541 .ops = &iwl6000g2b_ops,
542 .eeprom_size = OTP_LOW_IMAGE_SIZE,
543 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
544 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
545 .num_of_queues = IWLAGN_NUM_QUEUES,
546 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
547 .mod_params = &iwlagn_mod_params,
548 .valid_tx_ant = ANT_AB,
549 .valid_rx_ant = ANT_AB,
550 .pll_cfg_val = 0,
551 .set_l0s = true,
552 .use_bsm = false,
553 .pa_type = IWL_PA_SYSTEM,
554 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
555 .shadow_ram_support = true,
556 .ht_greenfield_support = true,
557 .led_compensation = 51,
558 .use_rts_for_ht = true, /* use rts/cts protection */
559 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
560 .supports_idle = true,
561 .adv_thermal_throttle = true,
562 .support_ct_kill_exit = true,
563 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
564 .chain_noise_scale = 1000,
565 .monitor_recover_period = IWL_MONITORING_PERIOD,
566 .max_event_log_size = 512,
567};
568
569struct iwl_cfg iwl6000g2b_2abg_cfg = {
570 .name = "6000 Series 2x2 ABG Gen2b",
571 .fw_name_pre = IWL6000G2B_FW_PRE,
572 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
573 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
574 .sku = IWL_SKU_A|IWL_SKU_G,
575 .ops = &iwl6000g2b_ops,
576 .eeprom_size = OTP_LOW_IMAGE_SIZE,
577 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
578 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
579 .num_of_queues = IWLAGN_NUM_QUEUES,
580 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
581 .mod_params = &iwlagn_mod_params,
582 .valid_tx_ant = ANT_AB,
583 .valid_rx_ant = ANT_AB,
584 .pll_cfg_val = 0,
585 .set_l0s = true,
586 .use_bsm = false,
587 .pa_type = IWL_PA_SYSTEM,
588 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
589 .shadow_ram_support = true,
590 .led_compensation = 51,
591 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
592 .supports_idle = true,
593 .adv_thermal_throttle = true,
594 .support_ct_kill_exit = true,
595 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
596 .chain_noise_scale = 1000,
597 .monitor_recover_period = IWL_MONITORING_PERIOD,
598 .max_event_log_size = 512,
599};
600
601struct iwl_cfg iwl6000g2b_2bgn_cfg = {
602 .name = "6000 Series 2x2 BGN Gen2b",
603 .fw_name_pre = IWL6000G2B_FW_PRE,
604 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
605 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
606 .sku = IWL_SKU_G|IWL_SKU_N,
607 .ops = &iwl6000g2b_ops,
608 .eeprom_size = OTP_LOW_IMAGE_SIZE,
609 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
610 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
611 .num_of_queues = IWLAGN_NUM_QUEUES,
612 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
613 .mod_params = &iwlagn_mod_params,
614 .valid_tx_ant = ANT_AB,
615 .valid_rx_ant = ANT_AB,
616 .pll_cfg_val = 0,
617 .set_l0s = true,
618 .use_bsm = false,
619 .pa_type = IWL_PA_SYSTEM,
620 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
621 .shadow_ram_support = true,
622 .ht_greenfield_support = true,
623 .led_compensation = 51,
624 .use_rts_for_ht = true, /* use rts/cts protection */
625 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
626 .supports_idle = true,
627 .adv_thermal_throttle = true,
628 .support_ct_kill_exit = true,
629 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
630 .chain_noise_scale = 1000,
631 .monitor_recover_period = IWL_MONITORING_PERIOD,
632 .max_event_log_size = 512,
633};
634
635struct iwl_cfg iwl6000g2b_2bg_cfg = {
636 .name = "6000 Series 2x2 BG Gen2b",
637 .fw_name_pre = IWL6000G2B_FW_PRE,
638 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
639 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
640 .sku = IWL_SKU_G,
641 .ops = &iwl6000g2b_ops,
642 .eeprom_size = OTP_LOW_IMAGE_SIZE,
643 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
644 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
645 .num_of_queues = IWLAGN_NUM_QUEUES,
646 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
647 .mod_params = &iwlagn_mod_params,
648 .valid_tx_ant = ANT_AB,
649 .valid_rx_ant = ANT_AB,
650 .pll_cfg_val = 0,
651 .set_l0s = true,
652 .use_bsm = false,
653 .pa_type = IWL_PA_SYSTEM,
654 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
655 .shadow_ram_support = true,
656 .led_compensation = 51,
657 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
658 .supports_idle = true,
659 .adv_thermal_throttle = true,
660 .support_ct_kill_exit = true,
661 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
662 .chain_noise_scale = 1000,
663 .monitor_recover_period = IWL_MONITORING_PERIOD,
664 .max_event_log_size = 512,
665};
666
667struct iwl_cfg iwl6000g2b_bgn_cfg = {
668 .name = "6000 Series 1x2 BGN Gen2b",
669 .fw_name_pre = IWL6000G2B_FW_PRE,
670 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
671 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
672 .sku = IWL_SKU_G|IWL_SKU_N,
673 .ops = &iwl6000g2b_ops,
674 .eeprom_size = OTP_LOW_IMAGE_SIZE,
675 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
676 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
677 .num_of_queues = IWLAGN_NUM_QUEUES,
678 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
679 .mod_params = &iwlagn_mod_params,
680 .valid_tx_ant = ANT_A,
681 .valid_rx_ant = ANT_AB,
682 .pll_cfg_val = 0,
683 .set_l0s = true,
684 .use_bsm = false,
685 .pa_type = IWL_PA_SYSTEM,
686 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
687 .shadow_ram_support = true,
688 .ht_greenfield_support = true,
689 .led_compensation = 51,
690 .use_rts_for_ht = true, /* use rts/cts protection */
691 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
692 .supports_idle = true,
693 .adv_thermal_throttle = true,
694 .support_ct_kill_exit = true,
695 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
696 .chain_noise_scale = 1000,
697 .monitor_recover_period = IWL_MONITORING_PERIOD,
698 .max_event_log_size = 512,
699};
700
701struct iwl_cfg iwl6000g2b_bg_cfg = {
702 .name = "6000 Series 1x2 BG Gen2b",
703 .fw_name_pre = IWL6000G2B_FW_PRE,
704 .ucode_api_max = IWL6000G2_UCODE_API_MAX,
705 .ucode_api_min = IWL6000G2_UCODE_API_MIN,
706 .sku = IWL_SKU_G,
707 .ops = &iwl6000g2b_ops,
708 .eeprom_size = OTP_LOW_IMAGE_SIZE,
709 .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION,
710 .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION,
711 .num_of_queues = IWLAGN_NUM_QUEUES,
712 .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
713 .mod_params = &iwlagn_mod_params,
714 .valid_tx_ant = ANT_A,
715 .valid_rx_ant = ANT_AB,
716 .pll_cfg_val = 0,
717 .set_l0s = true,
718 .use_bsm = false,
719 .pa_type = IWL_PA_SYSTEM,
720 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
721 .shadow_ram_support = true,
722 .led_compensation = 51,
723 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
724 .supports_idle = true,
725 .adv_thermal_throttle = true,
726 .support_ct_kill_exit = true,
727 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
728 .chain_noise_scale = 1000,
729 .monitor_recover_period = IWL_MONITORING_PERIOD,
730 .max_event_log_size = 512,
731};
732
448/* 733/*
449 * "i": Internal configuration, use internal Power Amplifier 734 * "i": Internal configuration, use internal Power Amplifier
450 */ 735 */
@@ -667,3 +952,4 @@ struct iwl_cfg iwl6000_3agn_cfg = {
667MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 952MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
668MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); 953MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
669MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); 954MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
955MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
index 48c023b4ca36..75d6bfcbc607 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -28,6 +28,27 @@
28 28
29#include "iwl-agn-debugfs.h" 29#include "iwl-agn-debugfs.h"
30 30
31static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
32{
33 int p = 0;
34
35 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
36 le32_to_cpu(priv->_agn.statistics.flag));
37 if (le32_to_cpu(priv->_agn.statistics.flag) &
38 UCODE_STATISTICS_CLEAR_MSK)
39 p += scnprintf(buf + p, bufsz - p,
40 "\tStatistics have been cleared\n");
41 p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
42 (le32_to_cpu(priv->_agn.statistics.flag) &
43 UCODE_STATISTICS_FREQUENCY_MSK)
44 ? "2.4 GHz" : "5.2 GHz");
45 p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
46 (le32_to_cpu(priv->_agn.statistics.flag) &
47 UCODE_STATISTICS_NARROW_BAND_MSK)
48 ? "enabled" : "disabled");
49 return p;
50}
51
31ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, 52ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
32 size_t count, loff_t *ppos) 53 size_t count, loff_t *ppos)
33 { 54 {
@@ -58,24 +79,24 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
58 * the last statistics notification from uCode 79 * the last statistics notification from uCode
59 * might not reflect the current uCode activity 80 * might not reflect the current uCode activity
60 */ 81 */
61 ofdm = &priv->statistics.rx.ofdm; 82 ofdm = &priv->_agn.statistics.rx.ofdm;
62 cck = &priv->statistics.rx.cck; 83 cck = &priv->_agn.statistics.rx.cck;
63 general = &priv->statistics.rx.general; 84 general = &priv->_agn.statistics.rx.general;
64 ht = &priv->statistics.rx.ofdm_ht; 85 ht = &priv->_agn.statistics.rx.ofdm_ht;
65 accum_ofdm = &priv->accum_statistics.rx.ofdm; 86 accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
66 accum_cck = &priv->accum_statistics.rx.cck; 87 accum_cck = &priv->_agn.accum_statistics.rx.cck;
67 accum_general = &priv->accum_statistics.rx.general; 88 accum_general = &priv->_agn.accum_statistics.rx.general;
68 accum_ht = &priv->accum_statistics.rx.ofdm_ht; 89 accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
69 delta_ofdm = &priv->delta_statistics.rx.ofdm; 90 delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
70 delta_cck = &priv->delta_statistics.rx.cck; 91 delta_cck = &priv->_agn.delta_statistics.rx.cck;
71 delta_general = &priv->delta_statistics.rx.general; 92 delta_general = &priv->_agn.delta_statistics.rx.general;
72 delta_ht = &priv->delta_statistics.rx.ofdm_ht; 93 delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
73 max_ofdm = &priv->max_delta.rx.ofdm; 94 max_ofdm = &priv->_agn.max_delta.rx.ofdm;
74 max_cck = &priv->max_delta.rx.cck; 95 max_cck = &priv->_agn.max_delta.rx.cck;
75 max_general = &priv->max_delta.rx.general; 96 max_general = &priv->_agn.max_delta.rx.general;
76 max_ht = &priv->max_delta.rx.ofdm_ht; 97 max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
77 98
78 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 99 pos += iwl_statistics_flag(priv, buf, bufsz);
79 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 100 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
80 "acumulative delta max\n", 101 "acumulative delta max\n",
81 "Statistics_Rx - OFDM:"); 102 "Statistics_Rx - OFDM:");
@@ -539,11 +560,11 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
539 * the last statistics notification from uCode 560 * the last statistics notification from uCode
540 * might not reflect the current uCode activity 561 * might not reflect the current uCode activity
541 */ 562 */
542 tx = &priv->statistics.tx; 563 tx = &priv->_agn.statistics.tx;
543 accum_tx = &priv->accum_statistics.tx; 564 accum_tx = &priv->_agn.accum_statistics.tx;
544 delta_tx = &priv->delta_statistics.tx; 565 delta_tx = &priv->_agn.delta_statistics.tx;
545 max_tx = &priv->max_delta.tx; 566 max_tx = &priv->_agn.max_delta.tx;
546 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 567 pos += iwl_statistics_flag(priv, buf, bufsz);
547 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 568 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
548 "acumulative delta max\n", 569 "acumulative delta max\n",
549 "Statistics_Tx:"); 570 "Statistics_Tx:");
@@ -756,19 +777,19 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
756 * the last statistics notification from uCode 777 * the last statistics notification from uCode
757 * might not reflect the current uCode activity 778 * might not reflect the current uCode activity
758 */ 779 */
759 general = &priv->statistics.general; 780 general = &priv->_agn.statistics.general;
760 dbg = &priv->statistics.general.dbg; 781 dbg = &priv->_agn.statistics.general.dbg;
761 div = &priv->statistics.general.div; 782 div = &priv->_agn.statistics.general.div;
762 accum_general = &priv->accum_statistics.general; 783 accum_general = &priv->_agn.accum_statistics.general;
763 delta_general = &priv->delta_statistics.general; 784 delta_general = &priv->_agn.delta_statistics.general;
764 max_general = &priv->max_delta.general; 785 max_general = &priv->_agn.max_delta.general;
765 accum_dbg = &priv->accum_statistics.general.dbg; 786 accum_dbg = &priv->_agn.accum_statistics.general.dbg;
766 delta_dbg = &priv->delta_statistics.general.dbg; 787 delta_dbg = &priv->_agn.delta_statistics.general.dbg;
767 max_dbg = &priv->max_delta.general.dbg; 788 max_dbg = &priv->_agn.max_delta.general.dbg;
768 accum_div = &priv->accum_statistics.general.div; 789 accum_div = &priv->_agn.accum_statistics.general.div;
769 delta_div = &priv->delta_statistics.general.div; 790 delta_div = &priv->_agn.delta_statistics.general.div;
770 max_div = &priv->max_delta.general.div; 791 max_div = &priv->_agn.max_delta.general.div;
771 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 792 pos += iwl_statistics_flag(priv, buf, bufsz);
772 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" 793 pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
773 "acumulative delta max\n", 794 "acumulative delta max\n",
774 "Statistics_General:"); 795 "Statistics_General:");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 44ef5d93befc..25851ec2ab10 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -37,7 +37,7 @@
37#include "iwl-io.h" 37#include "iwl-io.h"
38#include "iwl-agn.h" 38#include "iwl-agn.h"
39 39
40static int iwlagn_send_rxon_assoc(struct iwl_priv *priv) 40int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
41{ 41{
42 int ret = 0; 42 int ret = 0;
43 struct iwl5000_rxon_assoc_cmd rxon_assoc; 43 struct iwl5000_rxon_assoc_cmd rxon_assoc;
@@ -84,7 +84,7 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
84 return ret; 84 return ret;
85} 85}
86 86
87static int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) 87int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
88{ 88{
89 struct iwl_tx_ant_config_cmd tx_ant_cmd = { 89 struct iwl_tx_ant_config_cmd tx_ant_cmd = {
90 .valid = cpu_to_le32(valid_tx_ant), 90 .valid = cpu_to_le32(valid_tx_ant),
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 1004cfc403b1..501d97f19170 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -184,6 +184,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
184 int tid; 184 int tid;
185 int sta_id; 185 int sta_id;
186 int freed; 186 int freed;
187 unsigned long flags;
187 188
188 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { 189 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
189 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " 190 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
@@ -199,9 +200,10 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
199 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS; 200 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
200 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS; 201 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
201 202
203 spin_lock_irqsave(&priv->sta_lock, flags);
202 if (txq->sched_retry) { 204 if (txq->sched_retry) {
203 const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp); 205 const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp);
204 struct iwl_ht_agg *agg = NULL; 206 struct iwl_ht_agg *agg;
205 207
206 agg = &priv->stations[sta_id].tid[tid].agg; 208 agg = &priv->stations[sta_id].tid[tid].agg;
207 209
@@ -256,6 +258,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
256 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); 258 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
257 259
258 iwl_check_abort_status(priv, tx_resp->frame_count, status); 260 iwl_check_abort_status(priv, tx_resp->frame_count, status);
261 spin_unlock_irqrestore(&priv->sta_lock, flags);
259} 262}
260 263
261void iwlagn_rx_handler_setup(struct iwl_priv *priv) 264void iwlagn_rx_handler_setup(struct iwl_priv *priv)
@@ -319,7 +322,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
319void iwlagn_temperature(struct iwl_priv *priv) 322void iwlagn_temperature(struct iwl_priv *priv)
320{ 323{
321 /* store temperature from statistics (in Celsius) */ 324 /* store temperature from statistics (in Celsius) */
322 priv->temperature = le32_to_cpu(priv->statistics.general.temperature); 325 priv->temperature =
326 le32_to_cpu(priv->_agn.statistics.general.temperature);
323 iwl_tt_handler(priv); 327 iwl_tt_handler(priv);
324} 328}
325 329
@@ -1528,3 +1532,18 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
1528 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, 1532 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
1529 vif->bss_conf.bssid); 1533 vif->bss_conf.bssid);
1530} 1534}
1535
1536void iwl_free_tfds_in_queue(struct iwl_priv *priv,
1537 int sta_id, int tid, int freed)
1538{
1539 WARN_ON(!spin_is_locked(&priv->sta_lock));
1540
1541 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
1542 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
1543 else {
1544 IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
1545 priv->stations[sta_id].tid[tid].tfds_in_queue,
1546 freed);
1547 priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
1548 }
1549}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index c402bfc83f36..52bec1040467 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -567,10 +567,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
567 hdr_len = ieee80211_hdrlen(fc); 567 hdr_len = ieee80211_hdrlen(fc);
568 568
569 /* Find index into station table for destination station */ 569 /* Find index into station table for destination station */
570 if (!info->control.sta) 570 sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
571 sta_id = priv->hw_params.bcast_sta_id;
572 else
573 sta_id = iwl_sta_id(info->control.sta);
574 if (sta_id == IWL_INVALID_STATION) { 571 if (sta_id == IWL_INVALID_STATION) {
575 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", 572 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
576 hdr->addr1); 573 hdr->addr1);
@@ -598,11 +595,17 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
598 } 595 }
599 596
600 txq_id = get_queue_from_ac(skb_get_queue_mapping(skb)); 597 txq_id = get_queue_from_ac(skb_get_queue_mapping(skb));
598
599 /* irqs already disabled/saved above when locking priv->lock */
600 spin_lock(&priv->sta_lock);
601
601 if (ieee80211_is_data_qos(fc)) { 602 if (ieee80211_is_data_qos(fc)) {
602 qc = ieee80211_get_qos_ctl(hdr); 603 qc = ieee80211_get_qos_ctl(hdr);
603 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 604 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
604 if (unlikely(tid >= MAX_TID_COUNT)) 605 if (WARN_ON_ONCE(tid >= MAX_TID_COUNT)) {
606 spin_unlock(&priv->sta_lock);
605 goto drop_unlock; 607 goto drop_unlock;
608 }
606 seq_number = priv->stations[sta_id].tid[tid].seq_number; 609 seq_number = priv->stations[sta_id].tid[tid].seq_number;
607 seq_number &= IEEE80211_SCTL_SEQ; 610 seq_number &= IEEE80211_SCTL_SEQ;
608 hdr->seq_ctrl = hdr->seq_ctrl & 611 hdr->seq_ctrl = hdr->seq_ctrl &
@@ -620,11 +623,18 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
620 swq_id = txq->swq_id; 623 swq_id = txq->swq_id;
621 q = &txq->q; 624 q = &txq->q;
622 625
623 if (unlikely(iwl_queue_space(q) < q->high_mark)) 626 if (unlikely(iwl_queue_space(q) < q->high_mark)) {
627 spin_unlock(&priv->sta_lock);
624 goto drop_unlock; 628 goto drop_unlock;
629 }
625 630
626 if (ieee80211_is_data_qos(fc)) 631 if (ieee80211_is_data_qos(fc)) {
627 priv->stations[sta_id].tid[tid].tfds_in_queue++; 632 priv->stations[sta_id].tid[tid].tfds_in_queue++;
633 if (!ieee80211_has_morefrags(fc))
634 priv->stations[sta_id].tid[tid].seq_number = seq_number;
635 }
636
637 spin_unlock(&priv->sta_lock);
628 638
629 /* Set up driver data for this TFD */ 639 /* Set up driver data for this TFD */
630 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); 640 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
@@ -703,8 +713,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
703 713
704 if (!ieee80211_has_morefrags(hdr->frame_control)) { 714 if (!ieee80211_has_morefrags(hdr->frame_control)) {
705 txq->need_update = 1; 715 txq->need_update = 1;
706 if (qc)
707 priv->stations[sta_id].tid[tid].seq_number = seq_number;
708 } else { 716 } else {
709 wait_write_ptr = 1; 717 wait_write_ptr = 1;
710 txq->need_update = 0; 718 txq->need_update = 0;
@@ -1009,6 +1017,8 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
1009 if (ret) 1017 if (ret)
1010 return ret; 1018 return ret;
1011 1019
1020 spin_lock_irqsave(&priv->sta_lock, flags);
1021 tid_data = &priv->stations[sta_id].tid[tid];
1012 if (tid_data->tfds_in_queue == 0) { 1022 if (tid_data->tfds_in_queue == 0) {
1013 IWL_DEBUG_HT(priv, "HW queue is empty\n"); 1023 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1014 tid_data->agg.state = IWL_AGG_ON; 1024 tid_data->agg.state = IWL_AGG_ON;
@@ -1018,6 +1028,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
1018 tid_data->tfds_in_queue); 1028 tid_data->tfds_in_queue);
1019 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; 1029 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
1020 } 1030 }
1031 spin_unlock_irqrestore(&priv->sta_lock, flags);
1021 return ret; 1032 return ret;
1022} 1033}
1023 1034
@@ -1040,11 +1051,14 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
1040 return -ENXIO; 1051 return -ENXIO;
1041 } 1052 }
1042 1053
1054 spin_lock_irqsave(&priv->sta_lock, flags);
1055
1043 if (priv->stations[sta_id].tid[tid].agg.state == 1056 if (priv->stations[sta_id].tid[tid].agg.state ==
1044 IWL_EMPTYING_HW_QUEUE_ADDBA) { 1057 IWL_EMPTYING_HW_QUEUE_ADDBA) {
1045 IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); 1058 IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
1046 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1059 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1047 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; 1060 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1061 spin_unlock_irqrestore(&priv->sta_lock, flags);
1048 return 0; 1062 return 0;
1049 } 1063 }
1050 1064
@@ -1062,13 +1076,17 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
1062 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n"); 1076 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
1063 priv->stations[sta_id].tid[tid].agg.state = 1077 priv->stations[sta_id].tid[tid].agg.state =
1064 IWL_EMPTYING_HW_QUEUE_DELBA; 1078 IWL_EMPTYING_HW_QUEUE_DELBA;
1079 spin_unlock_irqrestore(&priv->sta_lock, flags);
1065 return 0; 1080 return 0;
1066 } 1081 }
1067 1082
1068 IWL_DEBUG_HT(priv, "HW queue is empty\n"); 1083 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1069 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; 1084 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1070 1085
1071 spin_lock_irqsave(&priv->lock, flags); 1086 /* do not restore/save irqs */
1087 spin_unlock(&priv->sta_lock);
1088 spin_lock(&priv->lock);
1089
1072 /* 1090 /*
1073 * the only reason this call can fail is queue number out of range, 1091 * the only reason this call can fail is queue number out of range,
1074 * which can happen if uCode is reloaded and all the station 1092 * which can happen if uCode is reloaded and all the station
@@ -1092,6 +1110,8 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
1092 u8 *addr = priv->stations[sta_id].sta.sta.addr; 1110 u8 *addr = priv->stations[sta_id].sta.sta.addr;
1093 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; 1111 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
1094 1112
1113 WARN_ON(!spin_is_locked(&priv->sta_lock));
1114
1095 switch (priv->stations[sta_id].tid[tid].agg.state) { 1115 switch (priv->stations[sta_id].tid[tid].agg.state) {
1096 case IWL_EMPTYING_HW_QUEUE_DELBA: 1116 case IWL_EMPTYING_HW_QUEUE_DELBA:
1097 /* We are reclaiming the last packet of the */ 1117 /* We are reclaiming the last packet of the */
@@ -1116,6 +1136,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
1116 } 1136 }
1117 break; 1137 break;
1118 } 1138 }
1139
1119 return 0; 1140 return 0;
1120} 1141}
1121 1142
@@ -1279,6 +1300,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1279 int index; 1300 int index;
1280 int sta_id; 1301 int sta_id;
1281 int tid; 1302 int tid;
1303 unsigned long flags;
1282 1304
1283 /* "flow" corresponds to Tx queue */ 1305 /* "flow" corresponds to Tx queue */
1284 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); 1306 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
@@ -1301,7 +1323,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1301 /* Find index just before block-ack window */ 1323 /* Find index just before block-ack window */
1302 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); 1324 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
1303 1325
1304 /* TODO: Need to get this copy more safely - now good for debug */ 1326 spin_lock_irqsave(&priv->sta_lock, flags);
1305 1327
1306 IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " 1328 IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
1307 "sta_id = %d\n", 1329 "sta_id = %d\n",
@@ -1337,4 +1359,6 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1337 1359
1338 iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow); 1360 iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow);
1339 } 1361 }
1362
1363 spin_unlock_irqrestore(&priv->sta_lock, flags);
1340} 1364}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 637286c396fe..6f77441cb65a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -423,3 +423,126 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
423 423
424 return 0; 424 return 0;
425} 425}
426
427
428/**
429 * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
430 * using sample data 100 bytes apart. If these sample points are good,
431 * it's a pretty good bet that everything between them is good, too.
432 */
433static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
434{
435 u32 val;
436 int ret = 0;
437 u32 errcnt = 0;
438 u32 i;
439
440 IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
441
442 for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
443 /* read data comes through single port, auto-incr addr */
444 /* NOTE: Use the debugless read so we don't flood kernel log
445 * if IWL_DL_IO is set */
446 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
447 i + IWLAGN_RTC_INST_LOWER_BOUND);
448 val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
449 if (val != le32_to_cpu(*image)) {
450 ret = -EIO;
451 errcnt++;
452 if (errcnt >= 3)
453 break;
454 }
455 }
456
457 return ret;
458}
459
460/**
461 * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host,
462 * looking at all data.
463 */
464static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
465 u32 len)
466{
467 u32 val;
468 u32 save_len = len;
469 int ret = 0;
470 u32 errcnt;
471
472 IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
473
474 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
475 IWLAGN_RTC_INST_LOWER_BOUND);
476
477 errcnt = 0;
478 for (; len > 0; len -= sizeof(u32), image++) {
479 /* read data comes through single port, auto-incr addr */
480 /* NOTE: Use the debugless read so we don't flood kernel log
481 * if IWL_DL_IO is set */
482 val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
483 if (val != le32_to_cpu(*image)) {
484 IWL_ERR(priv, "uCode INST section is invalid at "
485 "offset 0x%x, is 0x%x, s/b 0x%x\n",
486 save_len - len, val, le32_to_cpu(*image));
487 ret = -EIO;
488 errcnt++;
489 if (errcnt >= 20)
490 break;
491 }
492 }
493
494 if (!errcnt)
495 IWL_DEBUG_INFO(priv,
496 "ucode image in INSTRUCTION memory is good\n");
497
498 return ret;
499}
500
501/**
502 * iwl_verify_ucode - determine which instruction image is in SRAM,
503 * and verify its contents
504 */
505int iwl_verify_ucode(struct iwl_priv *priv)
506{
507 __le32 *image;
508 u32 len;
509 int ret;
510
511 /* Try bootstrap */
512 image = (__le32 *)priv->ucode_boot.v_addr;
513 len = priv->ucode_boot.len;
514 ret = iwlcore_verify_inst_sparse(priv, image, len);
515 if (!ret) {
516 IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
517 return 0;
518 }
519
520 /* Try initialize */
521 image = (__le32 *)priv->ucode_init.v_addr;
522 len = priv->ucode_init.len;
523 ret = iwlcore_verify_inst_sparse(priv, image, len);
524 if (!ret) {
525 IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
526 return 0;
527 }
528
529 /* Try runtime/protocol */
530 image = (__le32 *)priv->ucode_code.v_addr;
531 len = priv->ucode_code.len;
532 ret = iwlcore_verify_inst_sparse(priv, image, len);
533 if (!ret) {
534 IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
535 return 0;
536 }
537
538 IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
539
540 /* Since nothing seems to match, show first several data entries in
541 * instruction SRAM, so maybe visual inspection will give a clue.
542 * Selection of bootstrap image (vs. other images) is arbitrary. */
543 image = (__le32 *)priv->ucode_boot.v_addr;
544 len = priv->ucode_boot.len;
545 ret = iwl_verify_inst_full(priv, image, len);
546
547 return ret;
548}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index aef4f71f1981..a5db952d953b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1450,13 +1450,13 @@ bool iwl_good_ack_health(struct iwl_priv *priv,
1450 1450
1451 actual_ack_cnt_delta = 1451 actual_ack_cnt_delta =
1452 le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) - 1452 le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) -
1453 le32_to_cpu(priv->statistics.tx.actual_ack_cnt); 1453 le32_to_cpu(priv->_agn.statistics.tx.actual_ack_cnt);
1454 expected_ack_cnt_delta = 1454 expected_ack_cnt_delta =
1455 le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) - 1455 le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) -
1456 le32_to_cpu(priv->statistics.tx.expected_ack_cnt); 1456 le32_to_cpu(priv->_agn.statistics.tx.expected_ack_cnt);
1457 ba_timeout_delta = 1457 ba_timeout_delta =
1458 le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) - 1458 le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) -
1459 le32_to_cpu(priv->statistics.tx.agg.ba_timeout); 1459 le32_to_cpu(priv->_agn.statistics.tx.agg.ba_timeout);
1460 if ((priv->_agn.agg_tids_count > 0) && 1460 if ((priv->_agn.agg_tids_count > 0) &&
1461 (expected_ack_cnt_delta > 0) && 1461 (expected_ack_cnt_delta > 0) &&
1462 (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta) 1462 (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta)
@@ -1466,12 +1466,17 @@ bool iwl_good_ack_health(struct iwl_priv *priv,
1466 " expected_ack_cnt = %d\n", 1466 " expected_ack_cnt = %d\n",
1467 actual_ack_cnt_delta, expected_ack_cnt_delta); 1467 actual_ack_cnt_delta, expected_ack_cnt_delta);
1468 1468
1469#ifdef CONFIG_IWLWIFI_DEBUG 1469#ifdef CONFIG_IWLWIFI_DEBUGFS
1470 /*
1471 * This is ifdef'ed on DEBUGFS because otherwise the
1472 * statistics aren't available. If DEBUGFS is set but
1473 * DEBUG is not, these will just compile out.
1474 */
1470 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n", 1475 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n",
1471 priv->delta_statistics.tx.rx_detected_cnt); 1476 priv->_agn.delta_statistics.tx.rx_detected_cnt);
1472 IWL_DEBUG_RADIO(priv, 1477 IWL_DEBUG_RADIO(priv,
1473 "ack_or_ba_timeout_collision delta = %d\n", 1478 "ack_or_ba_timeout_collision delta = %d\n",
1474 priv->delta_statistics.tx. 1479 priv->_agn.delta_statistics.tx.
1475 ack_or_ba_timeout_collision); 1480 ack_or_ba_timeout_collision);
1476#endif 1481#endif
1477 IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n", 1482 IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n",
@@ -1544,6 +1549,9 @@ struct iwlagn_firmware_pieces {
1544 size_t inst_size, data_size, init_size, init_data_size, boot_size; 1549 size_t inst_size, data_size, init_size, init_data_size, boot_size;
1545 1550
1546 u32 build; 1551 u32 build;
1552
1553 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
1554 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
1547}; 1555};
1548 1556
1549static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, 1557static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
@@ -1721,6 +1729,42 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1721 capa->max_probe_length = 1729 capa->max_probe_length =
1722 le32_to_cpup((__le32 *)tlv_data); 1730 le32_to_cpup((__le32 *)tlv_data);
1723 break; 1731 break;
1732 case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
1733 if (tlv_len != 4)
1734 return -EINVAL;
1735 pieces->init_evtlog_ptr =
1736 le32_to_cpup((__le32 *)tlv_data);
1737 break;
1738 case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
1739 if (tlv_len != 4)
1740 return -EINVAL;
1741 pieces->init_evtlog_size =
1742 le32_to_cpup((__le32 *)tlv_data);
1743 break;
1744 case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
1745 if (tlv_len != 4)
1746 return -EINVAL;
1747 pieces->init_errlog_ptr =
1748 le32_to_cpup((__le32 *)tlv_data);
1749 break;
1750 case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
1751 if (tlv_len != 4)
1752 return -EINVAL;
1753 pieces->inst_evtlog_ptr =
1754 le32_to_cpup((__le32 *)tlv_data);
1755 break;
1756 case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
1757 if (tlv_len != 4)
1758 return -EINVAL;
1759 pieces->inst_evtlog_size =
1760 le32_to_cpup((__le32 *)tlv_data);
1761 break;
1762 case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
1763 if (tlv_len != 4)
1764 return -EINVAL;
1765 pieces->inst_errlog_ptr =
1766 le32_to_cpup((__le32 *)tlv_data);
1767 break;
1724 default: 1768 default:
1725 break; 1769 break;
1726 } 1770 }
@@ -1913,6 +1957,26 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
1913 goto err_pci_alloc; 1957 goto err_pci_alloc;
1914 } 1958 }
1915 1959
1960 /* Now that we can no longer fail, copy information */
1961
1962 /*
1963 * The (size - 16) / 12 formula is based on the information recorded
1964 * for each event, which is of mode 1 (including timestamp) for all
1965 * new microcodes that include this information.
1966 */
1967 priv->_agn.init_evtlog_ptr = pieces.init_evtlog_ptr;
1968 if (pieces.init_evtlog_size)
1969 priv->_agn.init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
1970 else
1971 priv->_agn.init_evtlog_size = priv->cfg->max_event_log_size;
1972 priv->_agn.init_errlog_ptr = pieces.init_errlog_ptr;
1973 priv->_agn.inst_evtlog_ptr = pieces.inst_evtlog_ptr;
1974 if (pieces.inst_evtlog_size)
1975 priv->_agn.inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
1976 else
1977 priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size;
1978 priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
1979
1916 /* Copy images into buffers for card's bus-master reads ... */ 1980 /* Copy images into buffers for card's bus-master reads ... */
1917 1981
1918 /* Runtime instructions (first block of data in file) */ 1982 /* Runtime instructions (first block of data in file) */
@@ -2038,10 +2102,15 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
2038 u32 blink1, blink2, ilink1, ilink2; 2102 u32 blink1, blink2, ilink1, ilink2;
2039 u32 pc, hcmd; 2103 u32 pc, hcmd;
2040 2104
2041 if (priv->ucode_type == UCODE_INIT) 2105 if (priv->ucode_type == UCODE_INIT) {
2042 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr); 2106 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
2043 else 2107 if (!base)
2108 base = priv->_agn.init_errlog_ptr;
2109 } else {
2044 base = le32_to_cpu(priv->card_alive.error_event_table_ptr); 2110 base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
2111 if (!base)
2112 base = priv->_agn.inst_errlog_ptr;
2113 }
2045 2114
2046 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { 2115 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
2047 IWL_ERR(priv, 2116 IWL_ERR(priv,
@@ -2101,10 +2170,16 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
2101 2170
2102 if (num_events == 0) 2171 if (num_events == 0)
2103 return pos; 2172 return pos;
2104 if (priv->ucode_type == UCODE_INIT) 2173
2174 if (priv->ucode_type == UCODE_INIT) {
2105 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 2175 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
2106 else 2176 if (!base)
2177 base = priv->_agn.init_evtlog_ptr;
2178 } else {
2107 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 2179 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
2180 if (!base)
2181 base = priv->_agn.inst_evtlog_ptr;
2182 }
2108 2183
2109 if (mode == 0) 2184 if (mode == 0)
2110 event_size = 2 * sizeof(u32); 2185 event_size = 2 * sizeof(u32);
@@ -2206,13 +2281,21 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
2206 u32 num_wraps; /* # times uCode wrapped to top of log */ 2281 u32 num_wraps; /* # times uCode wrapped to top of log */
2207 u32 next_entry; /* index of next entry to be written by uCode */ 2282 u32 next_entry; /* index of next entry to be written by uCode */
2208 u32 size; /* # entries that we'll print */ 2283 u32 size; /* # entries that we'll print */
2284 u32 logsize;
2209 int pos = 0; 2285 int pos = 0;
2210 size_t bufsz = 0; 2286 size_t bufsz = 0;
2211 2287
2212 if (priv->ucode_type == UCODE_INIT) 2288 if (priv->ucode_type == UCODE_INIT) {
2213 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 2289 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
2214 else 2290 logsize = priv->_agn.init_evtlog_size;
2291 if (!base)
2292 base = priv->_agn.init_evtlog_ptr;
2293 } else {
2215 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 2294 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
2295 logsize = priv->_agn.inst_evtlog_size;
2296 if (!base)
2297 base = priv->_agn.inst_evtlog_ptr;
2298 }
2216 2299
2217 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { 2300 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
2218 IWL_ERR(priv, 2301 IWL_ERR(priv,
@@ -2227,16 +2310,16 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
2227 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); 2310 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
2228 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); 2311 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
2229 2312
2230 if (capacity > priv->cfg->max_event_log_size) { 2313 if (capacity > logsize) {
2231 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", 2314 IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n",
2232 capacity, priv->cfg->max_event_log_size); 2315 capacity, logsize);
2233 capacity = priv->cfg->max_event_log_size; 2316 capacity = logsize;
2234 } 2317 }
2235 2318
2236 if (next_entry > priv->cfg->max_event_log_size) { 2319 if (next_entry > logsize) {
2237 IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", 2320 IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n",
2238 next_entry, priv->cfg->max_event_log_size); 2321 next_entry, logsize);
2239 next_entry = priv->cfg->max_event_log_size; 2322 next_entry = logsize;
2240 } 2323 }
2241 2324
2242 size = num_wraps ? capacity : next_entry; 2325 size = num_wraps ? capacity : next_entry;
@@ -2686,9 +2769,9 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
2686 } 2769 }
2687 2770
2688 if (priv->start_calib) { 2771 if (priv->start_calib) {
2689 iwl_chain_noise_calibration(priv, &priv->statistics); 2772 iwl_chain_noise_calibration(priv, &priv->_agn.statistics);
2690 2773
2691 iwl_sensitivity_calibration(priv, &priv->statistics); 2774 iwl_sensitivity_calibration(priv, &priv->_agn.statistics);
2692 } 2775 }
2693 2776
2694 mutex_unlock(&priv->mutex); 2777 mutex_unlock(&priv->mutex);
@@ -2777,20 +2860,16 @@ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
2777 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 2860 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
2778 vif->bss_conf.aid, vif->bss_conf.beacon_int); 2861 vif->bss_conf.aid, vif->bss_conf.beacon_int);
2779 2862
2780 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 2863 if (vif->bss_conf.use_short_preamble)
2781 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 2864 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
2782 else 2865 else
2783 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 2866 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
2784 2867
2785 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 2868 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
2786 if (vif->bss_conf.assoc_capability & 2869 if (vif->bss_conf.use_short_slot)
2787 WLAN_CAPABILITY_SHORT_SLOT_TIME)
2788 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 2870 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
2789 else 2871 else
2790 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 2872 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2791
2792 if (vif->type == NL80211_IFTYPE_ADHOC)
2793 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2794 } 2873 }
2795 2874
2796 iwlcore_commit_rxon(priv); 2875 iwlcore_commit_rxon(priv);
@@ -3016,8 +3095,7 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3016 3095
3017 priv->staging_rxon.assoc_id = 0; 3096 priv->staging_rxon.assoc_id = 0;
3018 3097
3019 if (vif->bss_conf.assoc_capability & 3098 if (vif->bss_conf.use_short_preamble)
3020 WLAN_CAPABILITY_SHORT_PREAMBLE)
3021 priv->staging_rxon.flags |= 3099 priv->staging_rxon.flags |=
3022 RXON_FLG_SHORT_PREAMBLE_MSK; 3100 RXON_FLG_SHORT_PREAMBLE_MSK;
3023 else 3101 else
@@ -3025,17 +3103,12 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3025 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3103 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3026 3104
3027 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3105 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3028 if (vif->bss_conf.assoc_capability & 3106 if (vif->bss_conf.use_short_slot)
3029 WLAN_CAPABILITY_SHORT_SLOT_TIME)
3030 priv->staging_rxon.flags |= 3107 priv->staging_rxon.flags |=
3031 RXON_FLG_SHORT_SLOT_MSK; 3108 RXON_FLG_SHORT_SLOT_MSK;
3032 else 3109 else
3033 priv->staging_rxon.flags &= 3110 priv->staging_rxon.flags &=
3034 ~RXON_FLG_SHORT_SLOT_MSK; 3111 ~RXON_FLG_SHORT_SLOT_MSK;
3035
3036 if (vif->type == NL80211_IFTYPE_ADHOC)
3037 priv->staging_rxon.flags &=
3038 ~RXON_FLG_SHORT_SLOT_MSK;
3039 } 3112 }
3040 /* restore RXON assoc */ 3113 /* restore RXON assoc */
3041 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3114 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
@@ -3081,17 +3154,9 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3081 return -EOPNOTSUPP; 3154 return -EOPNOTSUPP;
3082 } 3155 }
3083 3156
3084 if (sta) { 3157 sta_id = iwl_sta_id_or_broadcast(priv, sta);
3085 sta_id = iwl_sta_id(sta); 3158 if (sta_id == IWL_INVALID_STATION)
3086 3159 return -EINVAL;
3087 if (sta_id == IWL_INVALID_STATION) {
3088 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
3089 sta->addr);
3090 return -EINVAL;
3091 }
3092 } else {
3093 sta_id = priv->hw_params.bcast_sta_id;
3094 }
3095 3160
3096 mutex_lock(&priv->mutex); 3161 mutex_lock(&priv->mutex);
3097 iwl_scan_cancel_timeout(priv, 100); 3162 iwl_scan_cancel_timeout(priv, 100);
@@ -3989,6 +4054,47 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
3989 {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)}, 4054 {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)},
3990 {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)}, 4055 {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)},
3991 {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)}, 4056 {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)},
4057 {IWL_PCI_DEVICE(0x0082, 0x1206, iwl6000g2a_2abg_cfg)},
4058 {IWL_PCI_DEVICE(0x0085, 0x1216, iwl6000g2a_2abg_cfg)},
4059 {IWL_PCI_DEVICE(0x0082, 0x1226, iwl6000g2a_2abg_cfg)},
4060 {IWL_PCI_DEVICE(0x0082, 0x1207, iwl6000g2a_2bg_cfg)},
4061 {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2a_2agn_cfg)},
4062 {IWL_PCI_DEVICE(0x0082, 0x1306, iwl6000g2a_2abg_cfg)},
4063 {IWL_PCI_DEVICE(0x0082, 0x1307, iwl6000g2a_2bg_cfg)},
4064 {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6000g2a_2agn_cfg)},
4065 {IWL_PCI_DEVICE(0x0082, 0x1326, iwl6000g2a_2abg_cfg)},
4066 {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6000g2a_2agn_cfg)},
4067 {IWL_PCI_DEVICE(0x0085, 0x1316, iwl6000g2a_2abg_cfg)},
4068
4069/* 6x00 Series Gen2b */
4070 {IWL_PCI_DEVICE(0x008F, 0x5105, iwl6000g2b_bgn_cfg)},
4071 {IWL_PCI_DEVICE(0x0090, 0x5115, iwl6000g2b_bgn_cfg)},
4072 {IWL_PCI_DEVICE(0x008F, 0x5125, iwl6000g2b_bgn_cfg)},
4073 {IWL_PCI_DEVICE(0x008F, 0x5107, iwl6000g2b_bg_cfg)},
4074 {IWL_PCI_DEVICE(0x008F, 0x5201, iwl6000g2b_2agn_cfg)},
4075 {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)},
4076 {IWL_PCI_DEVICE(0x008F, 0x5221, iwl6000g2b_2agn_cfg)},
4077 {IWL_PCI_DEVICE(0x008F, 0x5206, iwl6000g2b_2abg_cfg)},
4078 {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)},
4079 {IWL_PCI_DEVICE(0x008F, 0x5226, iwl6000g2b_2abg_cfg)},
4080 {IWL_PCI_DEVICE(0x008F, 0x5207, iwl6000g2b_2bg_cfg)},
4081 {IWL_PCI_DEVICE(0x008A, 0x5301, iwl6000g2b_bgn_cfg)},
4082 {IWL_PCI_DEVICE(0x008A, 0x5305, iwl6000g2b_bgn_cfg)},
4083 {IWL_PCI_DEVICE(0x008A, 0x5307, iwl6000g2b_bg_cfg)},
4084 {IWL_PCI_DEVICE(0x008A, 0x5321, iwl6000g2b_bgn_cfg)},
4085 {IWL_PCI_DEVICE(0x008A, 0x5325, iwl6000g2b_bgn_cfg)},
4086 {IWL_PCI_DEVICE(0x008B, 0x5311, iwl6000g2b_bgn_cfg)},
4087 {IWL_PCI_DEVICE(0x008B, 0x5315, iwl6000g2b_bgn_cfg)},
4088 {IWL_PCI_DEVICE(0x0090, 0x5211, iwl6000g2b_2agn_cfg)},
4089 {IWL_PCI_DEVICE(0x0090, 0x5215, iwl6000g2b_2bgn_cfg)},
4090 {IWL_PCI_DEVICE(0x0090, 0x5216, iwl6000g2b_2abg_cfg)},
4091 {IWL_PCI_DEVICE(0x0091, 0x5201, iwl6000g2b_2agn_cfg)},
4092 {IWL_PCI_DEVICE(0x0091, 0x5205, iwl6000g2b_2bgn_cfg)},
4093 {IWL_PCI_DEVICE(0x0091, 0x5206, iwl6000g2b_2abg_cfg)},
4094 {IWL_PCI_DEVICE(0x0091, 0x5207, iwl6000g2b_2bg_cfg)},
4095 {IWL_PCI_DEVICE(0x0091, 0x5221, iwl6000g2b_2agn_cfg)},
4096 {IWL_PCI_DEVICE(0x0091, 0x5225, iwl6000g2b_2bgn_cfg)},
4097 {IWL_PCI_DEVICE(0x0091, 0x5226, iwl6000g2b_2abg_cfg)},
3992 4098
3993/* 6x50 WiFi/WiMax Series */ 4099/* 6x50 WiFi/WiMax Series */
3994 {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)}, 4100 {IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 2d748053358e..5c32777b0a49 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -65,6 +65,33 @@
65 65
66#include "iwl-dev.h" 66#include "iwl-dev.h"
67 67
68/* configuration for the _agn devices */
69extern struct iwl_cfg iwl4965_agn_cfg;
70extern struct iwl_cfg iwl5300_agn_cfg;
71extern struct iwl_cfg iwl5100_agn_cfg;
72extern struct iwl_cfg iwl5350_agn_cfg;
73extern struct iwl_cfg iwl5100_bgn_cfg;
74extern struct iwl_cfg iwl5100_abg_cfg;
75extern struct iwl_cfg iwl5150_agn_cfg;
76extern struct iwl_cfg iwl5150_abg_cfg;
77extern struct iwl_cfg iwl6000g2a_2agn_cfg;
78extern struct iwl_cfg iwl6000g2a_2abg_cfg;
79extern struct iwl_cfg iwl6000g2a_2bg_cfg;
80extern struct iwl_cfg iwl6000g2b_bgn_cfg;
81extern struct iwl_cfg iwl6000g2b_bg_cfg;
82extern struct iwl_cfg iwl6000g2b_2agn_cfg;
83extern struct iwl_cfg iwl6000g2b_2abg_cfg;
84extern struct iwl_cfg iwl6000g2b_2bgn_cfg;
85extern struct iwl_cfg iwl6000g2b_2bg_cfg;
86extern struct iwl_cfg iwl6000i_2agn_cfg;
87extern struct iwl_cfg iwl6000i_2abg_cfg;
88extern struct iwl_cfg iwl6000i_2bg_cfg;
89extern struct iwl_cfg iwl6000_3agn_cfg;
90extern struct iwl_cfg iwl6050_2agn_cfg;
91extern struct iwl_cfg iwl6050_2abg_cfg;
92extern struct iwl_cfg iwl1000_bgn_cfg;
93extern struct iwl_cfg iwl1000_bg_cfg;
94
68extern struct iwl_mod_params iwlagn_mod_params; 95extern struct iwl_mod_params iwlagn_mod_params;
69extern struct iwl_hcmd_ops iwlagn_hcmd; 96extern struct iwl_hcmd_ops iwlagn_hcmd;
70extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; 97extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
@@ -93,6 +120,8 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
93int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, 120int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
94 u16 ssn_idx, u8 tx_fifo); 121 u16 ssn_idx, u8 tx_fifo);
95void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); 122void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
123void iwl_free_tfds_in_queue(struct iwl_priv *priv,
124 int sta_id, int tid, int freed);
96 125
97/* uCode */ 126/* uCode */
98int iwlagn_load_ucode(struct iwl_priv *priv); 127int iwlagn_load_ucode(struct iwl_priv *priv);
@@ -102,6 +131,7 @@ void iwlagn_rx_calib_complete(struct iwl_priv *priv,
102 struct iwl_rx_mem_buffer *rxb); 131 struct iwl_rx_mem_buffer *rxb);
103void iwlagn_init_alive_start(struct iwl_priv *priv); 132void iwlagn_init_alive_start(struct iwl_priv *priv);
104int iwlagn_alive_notify(struct iwl_priv *priv); 133int iwlagn_alive_notify(struct iwl_priv *priv);
134int iwl_verify_ucode(struct iwl_priv *priv);
105 135
106/* lib */ 136/* lib */
107void iwl_check_abort_status(struct iwl_priv *priv, 137void iwl_check_abort_status(struct iwl_priv *priv,
@@ -178,4 +208,8 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
178int iwlagn_manage_ibss_station(struct iwl_priv *priv, 208int iwlagn_manage_ibss_station(struct iwl_priv *priv,
179 struct ieee80211_vif *vif, bool add); 209 struct ieee80211_vif *vif, bool add);
180 210
211/* hcmd */
212int iwlagn_send_rxon_assoc(struct iwl_priv *priv);
213int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
214
181#endif /* __iwl_agn_h__ */ 215#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 9aab020c474b..4790571207b5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -952,7 +952,6 @@ struct iwl_qosparam_cmd {
952 952
953/* Special, dedicated locations within device's station table */ 953/* Special, dedicated locations within device's station table */
954#define IWL_AP_ID 0 954#define IWL_AP_ID 0
955#define IWL_MULTICAST_ID 1
956#define IWL_STA_ID 2 955#define IWL_STA_ID 2
957#define IWL3945_BROADCAST_ID 24 956#define IWL3945_BROADCAST_ID 24
958#define IWL3945_STATION_COUNT 25 957#define IWL3945_STATION_COUNT 25
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 5a7eca8fb789..2d538f4436a7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -457,7 +457,7 @@ u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
457 if (!sta_ht_inf->ht_supported) 457 if (!sta_ht_inf->ht_supported)
458 return 0; 458 return 0;
459 } 459 }
460#ifdef CONFIG_IWLWIFI_DEBUG 460#ifdef CONFIG_IWLWIFI_DEBUGFS
461 if (priv->disable_ht40) 461 if (priv->disable_ht40)
462 return 0; 462 return 0;
463#endif 463#endif
@@ -904,14 +904,11 @@ static void iwl_set_flags_for_band(struct iwl_priv *priv,
904 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 904 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
905 } else { 905 } else {
906 /* Copied from iwl_post_associate() */ 906 /* Copied from iwl_post_associate() */
907 if (vif && vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) 907 if (vif && vif->bss_conf.use_short_slot)
908 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 908 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
909 else 909 else
910 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 910 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
911 911
912 if (vif && vif->type == NL80211_IFTYPE_ADHOC)
913 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
914
915 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; 912 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
916 priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK; 913 priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK;
917 priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK; 914 priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
@@ -1463,130 +1460,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
1463} 1460}
1464EXPORT_SYMBOL(iwl_send_statistics_request); 1461EXPORT_SYMBOL(iwl_send_statistics_request);
1465 1462
1466/**
1467 * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host,
1468 * using sample data 100 bytes apart. If these sample points are good,
1469 * it's a pretty good bet that everything between them is good, too.
1470 */
1471static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
1472{
1473 u32 val;
1474 int ret = 0;
1475 u32 errcnt = 0;
1476 u32 i;
1477
1478 IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
1479
1480 for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
1481 /* read data comes through single port, auto-incr addr */
1482 /* NOTE: Use the debugless read so we don't flood kernel log
1483 * if IWL_DL_IO is set */
1484 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
1485 i + IWL49_RTC_INST_LOWER_BOUND);
1486 val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1487 if (val != le32_to_cpu(*image)) {
1488 ret = -EIO;
1489 errcnt++;
1490 if (errcnt >= 3)
1491 break;
1492 }
1493 }
1494
1495 return ret;
1496}
1497
1498/**
1499 * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host,
1500 * looking at all data.
1501 */
1502static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
1503 u32 len)
1504{
1505 u32 val;
1506 u32 save_len = len;
1507 int ret = 0;
1508 u32 errcnt;
1509
1510 IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
1511
1512 iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
1513 IWL49_RTC_INST_LOWER_BOUND);
1514
1515 errcnt = 0;
1516 for (; len > 0; len -= sizeof(u32), image++) {
1517 /* read data comes through single port, auto-incr addr */
1518 /* NOTE: Use the debugless read so we don't flood kernel log
1519 * if IWL_DL_IO is set */
1520 val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1521 if (val != le32_to_cpu(*image)) {
1522 IWL_ERR(priv, "uCode INST section is invalid at "
1523 "offset 0x%x, is 0x%x, s/b 0x%x\n",
1524 save_len - len, val, le32_to_cpu(*image));
1525 ret = -EIO;
1526 errcnt++;
1527 if (errcnt >= 20)
1528 break;
1529 }
1530 }
1531
1532 if (!errcnt)
1533 IWL_DEBUG_INFO(priv,
1534 "ucode image in INSTRUCTION memory is good\n");
1535
1536 return ret;
1537}
1538
1539/**
1540 * iwl_verify_ucode - determine which instruction image is in SRAM,
1541 * and verify its contents
1542 */
1543int iwl_verify_ucode(struct iwl_priv *priv)
1544{
1545 __le32 *image;
1546 u32 len;
1547 int ret;
1548
1549 /* Try bootstrap */
1550 image = (__le32 *)priv->ucode_boot.v_addr;
1551 len = priv->ucode_boot.len;
1552 ret = iwlcore_verify_inst_sparse(priv, image, len);
1553 if (!ret) {
1554 IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
1555 return 0;
1556 }
1557
1558 /* Try initialize */
1559 image = (__le32 *)priv->ucode_init.v_addr;
1560 len = priv->ucode_init.len;
1561 ret = iwlcore_verify_inst_sparse(priv, image, len);
1562 if (!ret) {
1563 IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
1564 return 0;
1565 }
1566
1567 /* Try runtime/protocol */
1568 image = (__le32 *)priv->ucode_code.v_addr;
1569 len = priv->ucode_code.len;
1570 ret = iwlcore_verify_inst_sparse(priv, image, len);
1571 if (!ret) {
1572 IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
1573 return 0;
1574 }
1575
1576 IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
1577
1578 /* Since nothing seems to match, show first several data entries in
1579 * instruction SRAM, so maybe visual inspection will give a clue.
1580 * Selection of bootstrap image (vs. other images) is arbitrary. */
1581 image = (__le32 *)priv->ucode_boot.v_addr;
1582 len = priv->ucode_boot.len;
1583 ret = iwl_verify_inst_full(priv, image, len);
1584
1585 return ret;
1586}
1587EXPORT_SYMBOL(iwl_verify_ucode);
1588
1589
1590void iwl_rf_kill_ct_config(struct iwl_priv *priv) 1463void iwl_rf_kill_ct_config(struct iwl_priv *priv)
1591{ 1464{
1592 struct iwl_ct_kill_config cmd; 1465 struct iwl_ct_kill_config cmd;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7e5a5ba41fd2..d3b61dc2c43e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -472,8 +472,6 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
472 dma_addr_t addr, u16 len, u8 reset, u8 pad); 472 dma_addr_t addr, u16 len, u8 reset, u8 pad);
473int iwl_hw_tx_queue_init(struct iwl_priv *priv, 473int iwl_hw_tx_queue_init(struct iwl_priv *priv,
474 struct iwl_tx_queue *txq); 474 struct iwl_tx_queue *txq);
475void iwl_free_tfds_in_queue(struct iwl_priv *priv,
476 int sta_id, int tid, int freed);
477void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); 475void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
478int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, 476int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
479 int slots_num, u32 txq_id); 477 int slots_num, u32 txq_id);
@@ -691,7 +689,6 @@ extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
691extern void iwl_send_bt_config(struct iwl_priv *priv); 689extern void iwl_send_bt_config(struct iwl_priv *priv);
692extern int iwl_send_statistics_request(struct iwl_priv *priv, 690extern int iwl_send_statistics_request(struct iwl_priv *priv,
693 u8 flags, bool clear); 691 u8 flags, bool clear);
694extern int iwl_verify_ucode(struct iwl_priv *priv);
695extern int iwl_send_lq_cmd(struct iwl_priv *priv, 692extern int iwl_send_lq_cmd(struct iwl_priv *priv,
696 struct iwl_link_quality_cmd *lq, u8 flags, bool init); 693 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
697void iwl_apm_stop(struct iwl_priv *priv); 694void iwl_apm_stop(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 9659c5d01df9..d9f21bb9d75d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -106,27 +106,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
106 .open = iwl_dbgfs_open_file_generic, \ 106 .open = iwl_dbgfs_open_file_generic, \
107}; 107};
108 108
109int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
110{
111 int p = 0;
112
113 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
114 le32_to_cpu(priv->statistics.flag));
115 if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK)
116 p += scnprintf(buf + p, bufsz - p,
117 "\tStatistics have been cleared\n");
118 p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
119 (le32_to_cpu(priv->statistics.flag) &
120 UCODE_STATISTICS_FREQUENCY_MSK)
121 ? "2.4 GHz" : "5.2 GHz");
122 p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
123 (le32_to_cpu(priv->statistics.flag) &
124 UCODE_STATISTICS_NARROW_BAND_MSK)
125 ? "enabled" : "disabled");
126 return p;
127}
128EXPORT_SYMBOL(iwl_dbgfs_statistics_flag);
129
130static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, 109static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
131 char __user *user_buf, 110 char __user *user_buf,
132 size_t count, loff_t *ppos) { 111 size_t count, loff_t *ppos) {
@@ -330,45 +309,35 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
330 309
331 for (i = 0; i < max_sta; i++) { 310 for (i = 0; i < max_sta; i++) {
332 station = &priv->stations[i]; 311 station = &priv->stations[i];
333 if (station->used) { 312 if (!station->used)
334 pos += scnprintf(buf + pos, bufsz - pos, 313 continue;
335 "station %d:\ngeneral data:\n", i+1); 314 pos += scnprintf(buf + pos, bufsz - pos,
336 pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n", 315 "station %d - addr: %pM, flags: %#x\n",
337 station->sta.sta.sta_id); 316 i, station->sta.sta.addr,
338 pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n", 317 station->sta.station_flags_msk);
339 station->sta.mode); 318 pos += scnprintf(buf + pos, bufsz - pos,
340 pos += scnprintf(buf + pos, bufsz - pos, 319 "TID\tseq_num\ttxq_id\tframes\ttfds\t");
341 "flags: 0x%x\n", 320 pos += scnprintf(buf + pos, bufsz - pos,
342 station->sta.station_flags_msk); 321 "start_idx\tbitmap\t\t\trate_n_flags\n");
343 pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n");
344 pos += scnprintf(buf + pos, bufsz - pos,
345 "seq_num\t\ttxq_id");
346 pos += scnprintf(buf + pos, bufsz - pos,
347 "\tframe_count\twait_for_ba\t");
348 pos += scnprintf(buf + pos, bufsz - pos,
349 "start_idx\tbitmap0\t");
350 pos += scnprintf(buf + pos, bufsz - pos,
351 "bitmap1\trate_n_flags");
352 pos += scnprintf(buf + pos, bufsz - pos, "\n");
353 322
354 for (j = 0; j < MAX_TID_COUNT; j++) { 323 for (j = 0; j < MAX_TID_COUNT; j++) {
355 pos += scnprintf(buf + pos, bufsz - pos, 324 pos += scnprintf(buf + pos, bufsz - pos,
356 "[%d]:\t\t%u", j, 325 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",
357 station->tid[j].seq_number); 326 j, station->tid[j].seq_number,
358 pos += scnprintf(buf + pos, bufsz - pos, 327 station->tid[j].agg.txq_id,
359 "\t%u\t\t%u\t\t%u\t\t", 328 station->tid[j].agg.frame_count,
360 station->tid[j].agg.txq_id, 329 station->tid[j].tfds_in_queue,
361 station->tid[j].agg.frame_count, 330 station->tid[j].agg.start_idx,
362 station->tid[j].agg.wait_for_ba); 331 station->tid[j].agg.bitmap,
332 station->tid[j].agg.rate_n_flags);
333
334 if (station->tid[j].agg.wait_for_ba)
363 pos += scnprintf(buf + pos, bufsz - pos, 335 pos += scnprintf(buf + pos, bufsz - pos,
364 "%u\t%llu\t%u", 336 " - waitforba");
365 station->tid[j].agg.start_idx,
366 (unsigned long long)station->tid[j].agg.bitmap,
367 station->tid[j].agg.rate_n_flags);
368 pos += scnprintf(buf + pos, bufsz - pos, "\n");
369 }
370 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 337 pos += scnprintf(buf + pos, bufsz - pos, "\n");
371 } 338 }
339
340 pos += scnprintf(buf + pos, bufsz - pos, "\n");
372 } 341 }
373 342
374 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 343 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index f3f3473c5c7e..57a3c579c870 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -48,25 +48,6 @@
48#include "iwl-power.h" 48#include "iwl-power.h"
49#include "iwl-agn-rs.h" 49#include "iwl-agn-rs.h"
50 50
51/* configuration for the iwl4965 */
52extern struct iwl_cfg iwl4965_agn_cfg;
53extern struct iwl_cfg iwl5300_agn_cfg;
54extern struct iwl_cfg iwl5100_agn_cfg;
55extern struct iwl_cfg iwl5350_agn_cfg;
56extern struct iwl_cfg iwl5100_bgn_cfg;
57extern struct iwl_cfg iwl5100_abg_cfg;
58extern struct iwl_cfg iwl5150_agn_cfg;
59extern struct iwl_cfg iwl5150_abg_cfg;
60extern struct iwl_cfg iwl6000g2a_2agn_cfg;
61extern struct iwl_cfg iwl6000i_2agn_cfg;
62extern struct iwl_cfg iwl6000i_2abg_cfg;
63extern struct iwl_cfg iwl6000i_2bg_cfg;
64extern struct iwl_cfg iwl6000_3agn_cfg;
65extern struct iwl_cfg iwl6050_2agn_cfg;
66extern struct iwl_cfg iwl6050_2abg_cfg;
67extern struct iwl_cfg iwl1000_bgn_cfg;
68extern struct iwl_cfg iwl1000_bg_cfg;
69
70struct iwl_tx_queue; 51struct iwl_tx_queue;
71 52
72/* CT-KILL constants */ 53/* CT-KILL constants */
@@ -433,7 +414,7 @@ struct iwl_ht_agg {
433 414
434 415
435struct iwl_tid_data { 416struct iwl_tid_data {
436 u16 seq_number; 417 u16 seq_number; /* agn only */
437 u16 tfds_in_queue; 418 u16 tfds_in_queue;
438 struct iwl_ht_agg agg; 419 struct iwl_ht_agg agg;
439}; 420};
@@ -583,6 +564,12 @@ enum iwl_ucode_tlv_type {
583 IWL_UCODE_TLV_INIT_DATA = 4, 564 IWL_UCODE_TLV_INIT_DATA = 4,
584 IWL_UCODE_TLV_BOOT = 5, 565 IWL_UCODE_TLV_BOOT = 5,
585 IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ 566 IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */
567 IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8,
568 IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9,
569 IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10,
570 IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11,
571 IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12,
572 IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13,
586}; 573};
587 574
588struct iwl_ucode_tlv { 575struct iwl_ucode_tlv {
@@ -1109,7 +1096,7 @@ struct iwl_priv {
1109 /* force reset */ 1096 /* force reset */
1110 struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET]; 1097 struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];
1111 1098
1112 /* we allocate array of iwl4965_channel_info for NIC's valid channels. 1099 /* we allocate array of iwl_channel_info for NIC's valid channels.
1113 * Access via channel # using indirect index array */ 1100 * Access via channel # using indirect index array */
1114 struct iwl_channel_info *channel_info; /* channel info array */ 1101 struct iwl_channel_info *channel_info; /* channel info array */
1115 u8 channel_count; /* # of channels */ 1102 u8 channel_count; /* # of channels */
@@ -1174,7 +1161,7 @@ struct iwl_priv {
1174 struct iwl_switch_rxon switch_rxon; 1161 struct iwl_switch_rxon switch_rxon;
1175 1162
1176 /* 1st responses from initialize and runtime uCode images. 1163 /* 1st responses from initialize and runtime uCode images.
1177 * 4965's initialize alive response contains some calibration data. */ 1164 * _agn's initialize alive response contains some calibration data. */
1178 struct iwl_init_alive_resp card_alive_init; 1165 struct iwl_init_alive_resp card_alive_init;
1179 struct iwl_alive_resp card_alive; 1166 struct iwl_alive_resp card_alive;
1180 1167
@@ -1220,18 +1207,13 @@ struct iwl_priv {
1220 struct iwl_power_mgr power_data; 1207 struct iwl_power_mgr power_data;
1221 struct iwl_tt_mgmt thermal_throttle; 1208 struct iwl_tt_mgmt thermal_throttle;
1222 1209
1223 struct iwl_notif_statistics statistics;
1224#ifdef CONFIG_IWLWIFI_DEBUG
1225 struct iwl_notif_statistics accum_statistics;
1226 struct iwl_notif_statistics delta_statistics;
1227 struct iwl_notif_statistics max_delta;
1228#endif
1229
1230 /* context information */ 1210 /* context information */
1231 u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */ 1211 u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */
1232 u8 mac_addr[ETH_ALEN]; 1212 u8 mac_addr[ETH_ALEN];
1233 1213
1234 /*station table variables */ 1214 /* station table variables */
1215
1216 /* Note: if lock and sta_lock are needed, lock must be acquired first */
1235 spinlock_t sta_lock; 1217 spinlock_t sta_lock;
1236 int num_stations; 1218 int num_stations;
1237 struct iwl_station_entry stations[IWL_STATION_COUNT]; 1219 struct iwl_station_entry stations[IWL_STATION_COUNT];
@@ -1273,7 +1255,7 @@ struct iwl_priv {
1273 struct delayed_work rfkill_poll; 1255 struct delayed_work rfkill_poll;
1274 1256
1275 struct iwl3945_notif_statistics statistics; 1257 struct iwl3945_notif_statistics statistics;
1276#ifdef CONFIG_IWLWIFI_DEBUG 1258#ifdef CONFIG_IWLWIFI_DEBUGFS
1277 struct iwl3945_notif_statistics accum_statistics; 1259 struct iwl3945_notif_statistics accum_statistics;
1278 struct iwl3945_notif_statistics delta_statistics; 1260 struct iwl3945_notif_statistics delta_statistics;
1279 struct iwl3945_notif_statistics max_delta; 1261 struct iwl3945_notif_statistics max_delta;
@@ -1315,6 +1297,16 @@ struct iwl_priv {
1315 bool last_phy_res_valid; 1297 bool last_phy_res_valid;
1316 1298
1317 struct completion firmware_loading_complete; 1299 struct completion firmware_loading_complete;
1300
1301 struct iwl_notif_statistics statistics;
1302#ifdef CONFIG_IWLWIFI_DEBUGFS
1303 struct iwl_notif_statistics accum_statistics;
1304 struct iwl_notif_statistics delta_statistics;
1305 struct iwl_notif_statistics max_delta;
1306#endif
1307
1308 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
1309 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
1318 } _agn; 1310 } _agn;
1319#endif 1311#endif
1320 }; 1312 };
@@ -1355,7 +1347,7 @@ struct iwl_priv {
1355 iwl_debug_level if set */ 1347 iwl_debug_level if set */
1356 u32 framecnt_to_us; 1348 u32 framecnt_to_us;
1357 atomic_t restrict_refcnt; 1349 atomic_t restrict_refcnt;
1358 bool disable_ht40; 1350#endif /* CONFIG_IWLWIFI_DEBUG */
1359#ifdef CONFIG_IWLWIFI_DEBUGFS 1351#ifdef CONFIG_IWLWIFI_DEBUGFS
1360 /* debugfs */ 1352 /* debugfs */
1361 u16 tx_traffic_idx; 1353 u16 tx_traffic_idx;
@@ -1364,8 +1356,8 @@ struct iwl_priv {
1364 u8 *rx_traffic; 1356 u8 *rx_traffic;
1365 struct dentry *debugfs_dir; 1357 struct dentry *debugfs_dir;
1366 u32 dbgfs_sram_offset, dbgfs_sram_len; 1358 u32 dbgfs_sram_offset, dbgfs_sram_len;
1359 bool disable_ht40;
1367#endif /* CONFIG_IWLWIFI_DEBUGFS */ 1360#endif /* CONFIG_IWLWIFI_DEBUGFS */
1368#endif /* CONFIG_IWLWIFI_DEBUG */
1369 1361
1370 struct work_struct txpower_work; 1362 struct work_struct txpower_work;
1371 u32 disable_sens_cal; 1363 u32 disable_sens_cal;
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index 3ff6b9d25a10..69846395763b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -92,6 +92,11 @@ static inline void iwl_free_fw_desc(struct pci_dev *pci_dev,
92static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, 92static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
93 struct fw_desc *desc) 93 struct fw_desc *desc)
94{ 94{
95 if (!desc->len) {
96 desc->v_addr = NULL;
97 return -EINVAL;
98 }
99
95 desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len, 100 desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len,
96 &desc->p_addr, GFP_KERNEL); 101 &desc->p_addr, GFP_KERNEL);
97 return (desc->v_addr != NULL) ? 0 : -ENOMEM; 102 return (desc->v_addr != NULL) ? 0 : -ENOMEM;
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 0a5d7cf25196..5cd756077422 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -251,7 +251,7 @@ EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif);
251static void iwl_rx_calc_noise(struct iwl_priv *priv) 251static void iwl_rx_calc_noise(struct iwl_priv *priv)
252{ 252{
253 struct statistics_rx_non_phy *rx_info 253 struct statistics_rx_non_phy *rx_info
254 = &(priv->statistics.rx.general); 254 = &(priv->_agn.statistics.rx.general);
255 int num_active_rx = 0; 255 int num_active_rx = 0;
256 int total_silence = 0; 256 int total_silence = 0;
257 int bcn_silence_a = 257 int bcn_silence_a =
@@ -286,7 +286,7 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
286 last_rx_noise); 286 last_rx_noise);
287} 287}
288 288
289#ifdef CONFIG_IWLWIFI_DEBUG 289#ifdef CONFIG_IWLWIFI_DEBUGFS
290/* 290/*
291 * based on the assumption of all statistics counter are in DWORD 291 * based on the assumption of all statistics counter are in DWORD
292 * FIXME: This function is for debugging, do not deal with 292 * FIXME: This function is for debugging, do not deal with
@@ -300,10 +300,10 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
300 u32 *accum_stats; 300 u32 *accum_stats;
301 u32 *delta, *max_delta; 301 u32 *delta, *max_delta;
302 302
303 prev_stats = (__le32 *)&priv->statistics; 303 prev_stats = (__le32 *)&priv->_agn.statistics;
304 accum_stats = (u32 *)&priv->accum_statistics; 304 accum_stats = (u32 *)&priv->_agn.accum_statistics;
305 delta = (u32 *)&priv->delta_statistics; 305 delta = (u32 *)&priv->_agn.delta_statistics;
306 max_delta = (u32 *)&priv->max_delta; 306 max_delta = (u32 *)&priv->_agn.max_delta;
307 307
308 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); 308 for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
309 i += sizeof(__le32), stats++, prev_stats++, delta++, 309 i += sizeof(__le32), stats++, prev_stats++, delta++,
@@ -318,18 +318,18 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
318 } 318 }
319 319
320 /* reset accumulative statistics for "no-counter" type statistics */ 320 /* reset accumulative statistics for "no-counter" type statistics */
321 priv->accum_statistics.general.temperature = 321 priv->_agn.accum_statistics.general.temperature =
322 priv->statistics.general.temperature; 322 priv->_agn.statistics.general.temperature;
323 priv->accum_statistics.general.temperature_m = 323 priv->_agn.accum_statistics.general.temperature_m =
324 priv->statistics.general.temperature_m; 324 priv->_agn.statistics.general.temperature_m;
325 priv->accum_statistics.general.ttl_timestamp = 325 priv->_agn.accum_statistics.general.ttl_timestamp =
326 priv->statistics.general.ttl_timestamp; 326 priv->_agn.statistics.general.ttl_timestamp;
327 priv->accum_statistics.tx.tx_power.ant_a = 327 priv->_agn.accum_statistics.tx.tx_power.ant_a =
328 priv->statistics.tx.tx_power.ant_a; 328 priv->_agn.statistics.tx.tx_power.ant_a;
329 priv->accum_statistics.tx.tx_power.ant_b = 329 priv->_agn.accum_statistics.tx.tx_power.ant_b =
330 priv->statistics.tx.tx_power.ant_b; 330 priv->_agn.statistics.tx.tx_power.ant_b;
331 priv->accum_statistics.tx.tx_power.ant_c = 331 priv->_agn.accum_statistics.tx.tx_power.ant_c =
332 priv->statistics.tx.tx_power.ant_c; 332 priv->_agn.statistics.tx.tx_power.ant_c;
333} 333}
334#endif 334#endif
335 335
@@ -364,9 +364,9 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
364 if (plcp_msec) { 364 if (plcp_msec) {
365 combined_plcp_delta = 365 combined_plcp_delta =
366 (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) - 366 (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
367 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) + 367 le32_to_cpu(priv->_agn.statistics.rx.ofdm.plcp_err)) +
368 (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) - 368 (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
369 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err)); 369 le32_to_cpu(priv->_agn.statistics.rx.ofdm_ht.plcp_err));
370 370
371 if ((combined_plcp_delta > 0) && 371 if ((combined_plcp_delta > 0) &&
372 ((combined_plcp_delta * 100) / plcp_msec) > 372 ((combined_plcp_delta * 100) / plcp_msec) >
@@ -386,10 +386,10 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
386 "%u, %u, %u, %u, %d, %u mSecs\n", 386 "%u, %u, %u, %u, %d, %u mSecs\n",
387 priv->cfg->plcp_delta_threshold, 387 priv->cfg->plcp_delta_threshold,
388 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err), 388 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
389 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err), 389 le32_to_cpu(priv->_agn.statistics.rx.ofdm.plcp_err),
390 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err), 390 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
391 le32_to_cpu( 391 le32_to_cpu(
392 priv->statistics.rx.ofdm_ht.plcp_err), 392 priv->_agn.statistics.rx.ofdm_ht.plcp_err),
393 combined_plcp_delta, plcp_msec); 393 combined_plcp_delta, plcp_msec);
394 rc = false; 394 rc = false;
395 } 395 }
@@ -439,21 +439,22 @@ void iwl_rx_statistics(struct iwl_priv *priv,
439 439
440 440
441 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 441 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
442 (int)sizeof(priv->statistics), 442 (int)sizeof(priv->_agn.statistics),
443 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK); 443 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
444 444
445 change = ((priv->statistics.general.temperature != 445 change = ((priv->_agn.statistics.general.temperature !=
446 pkt->u.stats.general.temperature) || 446 pkt->u.stats.general.temperature) ||
447 ((priv->statistics.flag & 447 ((priv->_agn.statistics.flag &
448 STATISTICS_REPLY_FLG_HT40_MODE_MSK) != 448 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
449 (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK))); 449 (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
450 450
451#ifdef CONFIG_IWLWIFI_DEBUG 451#ifdef CONFIG_IWLWIFI_DEBUGFS
452 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); 452 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
453#endif 453#endif
454 iwl_recover_from_statistics(priv, pkt); 454 iwl_recover_from_statistics(priv, pkt);
455 455
456 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); 456 memcpy(&priv->_agn.statistics, &pkt->u.stats,
457 sizeof(priv->_agn.statistics));
457 458
458 set_bit(STATUS_STATISTICS, &priv->status); 459 set_bit(STATUS_STATISTICS, &priv->status);
459 460
@@ -480,12 +481,12 @@ void iwl_reply_statistics(struct iwl_priv *priv,
480 struct iwl_rx_packet *pkt = rxb_addr(rxb); 481 struct iwl_rx_packet *pkt = rxb_addr(rxb);
481 482
482 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { 483 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
483#ifdef CONFIG_IWLWIFI_DEBUG 484#ifdef CONFIG_IWLWIFI_DEBUGFS
484 memset(&priv->accum_statistics, 0, 485 memset(&priv->_agn.accum_statistics, 0,
485 sizeof(struct iwl_notif_statistics)); 486 sizeof(struct iwl_notif_statistics));
486 memset(&priv->delta_statistics, 0, 487 memset(&priv->_agn.delta_statistics, 0,
487 sizeof(struct iwl_notif_statistics)); 488 sizeof(struct iwl_notif_statistics));
488 memset(&priv->max_delta, 0, 489 memset(&priv->_agn.max_delta, 0,
489 sizeof(struct iwl_notif_statistics)); 490 sizeof(struct iwl_notif_statistics));
490#endif 491#endif
491 IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); 492 IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 83a26361a9b5..c7127132c298 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -311,10 +311,10 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
311 struct ieee80211_sta_ht_cap *ht_info, 311 struct ieee80211_sta_ht_cap *ht_info,
312 u8 *sta_id_r) 312 u8 *sta_id_r)
313{ 313{
314 struct iwl_station_entry *station;
315 unsigned long flags_spin; 314 unsigned long flags_spin;
316 int ret = 0; 315 int ret = 0;
317 u8 sta_id; 316 u8 sta_id;
317 struct iwl_addsta_cmd sta_cmd;
318 318
319 *sta_id_r = 0; 319 *sta_id_r = 0;
320 spin_lock_irqsave(&priv->sta_lock, flags_spin); 320 spin_lock_irqsave(&priv->sta_lock, flags_spin);
@@ -347,14 +347,15 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
347 } 347 }
348 348
349 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; 349 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
350 station = &priv->stations[sta_id]; 350 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
351 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 351 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
352 352
353 /* Add station to device's station table */ 353 /* Add station to device's station table */
354 ret = iwl_send_add_sta(priv, &station->sta, CMD_SYNC); 354 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
355 if (ret) { 355 if (ret) {
356 IWL_ERR(priv, "Adding station %pM failed.\n", station->sta.sta.addr);
357 spin_lock_irqsave(&priv->sta_lock, flags_spin); 356 spin_lock_irqsave(&priv->sta_lock, flags_spin);
357 IWL_ERR(priv, "Adding station %pM failed.\n",
358 priv->stations[sta_id].sta.sta.addr);
358 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; 359 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
359 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; 360 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
360 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 361 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
@@ -488,7 +489,7 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
488} 489}
489 490
490static int iwl_send_remove_station(struct iwl_priv *priv, 491static int iwl_send_remove_station(struct iwl_priv *priv,
491 struct iwl_station_entry *station) 492 const u8 *addr, int sta_id)
492{ 493{
493 struct iwl_rx_packet *pkt; 494 struct iwl_rx_packet *pkt;
494 int ret; 495 int ret;
@@ -505,7 +506,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
505 506
506 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); 507 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
507 rm_sta_cmd.num_sta = 1; 508 rm_sta_cmd.num_sta = 1;
508 memcpy(&rm_sta_cmd.addr, &station->sta.sta.addr , ETH_ALEN); 509 memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN);
509 510
510 cmd.flags |= CMD_WANT_SKB; 511 cmd.flags |= CMD_WANT_SKB;
511 512
@@ -525,7 +526,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
525 switch (pkt->u.rem_sta.status) { 526 switch (pkt->u.rem_sta.status) {
526 case REM_STA_SUCCESS_MSK: 527 case REM_STA_SUCCESS_MSK:
527 spin_lock_irqsave(&priv->sta_lock, flags_spin); 528 spin_lock_irqsave(&priv->sta_lock, flags_spin);
528 iwl_sta_ucode_deactivate(priv, station->sta.sta.sta_id); 529 iwl_sta_ucode_deactivate(priv, sta_id);
529 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 530 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
530 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); 531 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
531 break; 532 break;
@@ -546,7 +547,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
546int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, 547int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
547 const u8 *addr) 548 const u8 *addr)
548{ 549{
549 struct iwl_station_entry *station;
550 unsigned long flags; 550 unsigned long flags;
551 551
552 if (!iwl_is_ready(priv)) { 552 if (!iwl_is_ready(priv)) {
@@ -592,10 +592,9 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
592 592
593 BUG_ON(priv->num_stations < 0); 593 BUG_ON(priv->num_stations < 0);
594 594
595 station = &priv->stations[sta_id];
596 spin_unlock_irqrestore(&priv->sta_lock, flags); 595 spin_unlock_irqrestore(&priv->sta_lock, flags);
597 596
598 return iwl_send_remove_station(priv, station); 597 return iwl_send_remove_station(priv, addr, sta_id);
599out_err: 598out_err:
600 spin_unlock_irqrestore(&priv->sta_lock, flags); 599 spin_unlock_irqrestore(&priv->sta_lock, flags);
601 return -EINVAL; 600 return -EINVAL;
@@ -643,11 +642,13 @@ EXPORT_SYMBOL(iwl_clear_ucode_stations);
643 */ 642 */
644void iwl_restore_stations(struct iwl_priv *priv) 643void iwl_restore_stations(struct iwl_priv *priv)
645{ 644{
646 struct iwl_station_entry *station; 645 struct iwl_addsta_cmd sta_cmd;
646 struct iwl_link_quality_cmd lq;
647 unsigned long flags_spin; 647 unsigned long flags_spin;
648 int i; 648 int i;
649 bool found = false; 649 bool found = false;
650 int ret; 650 int ret;
651 bool send_lq;
651 652
652 if (!iwl_is_ready(priv)) { 653 if (!iwl_is_ready(priv)) {
653 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n"); 654 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n");
@@ -669,13 +670,20 @@ void iwl_restore_stations(struct iwl_priv *priv)
669 670
670 for (i = 0; i < priv->hw_params.max_stations; i++) { 671 for (i = 0; i < priv->hw_params.max_stations; i++) {
671 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) { 672 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
673 memcpy(&sta_cmd, &priv->stations[i].sta,
674 sizeof(struct iwl_addsta_cmd));
675 send_lq = false;
676 if (priv->stations[i].lq) {
677 memcpy(&lq, priv->stations[i].lq,
678 sizeof(struct iwl_link_quality_cmd));
679 send_lq = true;
680 }
672 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 681 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
673 station = &priv->stations[i]; 682 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
674 ret = iwl_send_add_sta(priv, &priv->stations[i].sta, CMD_SYNC);
675 if (ret) { 683 if (ret) {
676 IWL_ERR(priv, "Adding station %pM failed.\n",
677 station->sta.sta.addr);
678 spin_lock_irqsave(&priv->sta_lock, flags_spin); 684 spin_lock_irqsave(&priv->sta_lock, flags_spin);
685 IWL_ERR(priv, "Adding station %pM failed.\n",
686 priv->stations[i].sta.sta.addr);
679 priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE; 687 priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE;
680 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; 688 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
681 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 689 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
@@ -684,8 +692,8 @@ void iwl_restore_stations(struct iwl_priv *priv)
684 * Rate scaling has already been initialized, send 692 * Rate scaling has already been initialized, send
685 * current LQ command 693 * current LQ command
686 */ 694 */
687 if (station->lq) 695 if (send_lq)
688 iwl_send_lq_cmd(priv, station->lq, CMD_SYNC, true); 696 iwl_send_lq_cmd(priv, &lq, CMD_SYNC, true);
689 spin_lock_irqsave(&priv->sta_lock, flags_spin); 697 spin_lock_irqsave(&priv->sta_lock, flags_spin);
690 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; 698 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
691 } 699 }
@@ -972,24 +980,16 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
972 unsigned long flags; 980 unsigned long flags;
973 int i; 981 int i;
974 982
975 if (sta) {
976 sta_id = iwl_sta_id(sta);
977
978 if (sta_id == IWL_INVALID_STATION) {
979 IWL_DEBUG_MAC80211(priv, "leave - %pM not initialised.\n",
980 sta->addr);
981 return;
982 }
983 } else
984 sta_id = priv->hw_params.bcast_sta_id;
985
986
987 if (iwl_scan_cancel(priv)) { 983 if (iwl_scan_cancel(priv)) {
988 /* cancel scan failed, just live w/ bad key and rely 984 /* cancel scan failed, just live w/ bad key and rely
989 briefly on SW decryption */ 985 briefly on SW decryption */
990 return; 986 return;
991 } 987 }
992 988
989 sta_id = iwl_sta_id_or_broadcast(priv, sta);
990 if (sta_id == IWL_INVALID_STATION)
991 return;
992
993 spin_lock_irqsave(&priv->sta_lock, flags); 993 spin_lock_irqsave(&priv->sta_lock, flags);
994 994
995 priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; 995 priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
@@ -1277,9 +1277,8 @@ void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
1277 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; 1277 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
1278 priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); 1278 priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
1279 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1279 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1280 spin_unlock_irqrestore(&priv->sta_lock, flags);
1281
1282 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 1280 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1281 spin_unlock_irqrestore(&priv->sta_lock, flags);
1283} 1282}
1284EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); 1283EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid);
1285 1284
@@ -1310,7 +1309,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
1310 int tid) 1309 int tid)
1311{ 1310{
1312 unsigned long flags; 1311 unsigned long flags;
1313 int sta_id; 1312 int sta_id, ret;
1314 1313
1315 sta_id = iwl_sta_id(sta); 1314 sta_id = iwl_sta_id(sta);
1316 if (sta_id == IWL_INVALID_STATION) { 1315 if (sta_id == IWL_INVALID_STATION) {
@@ -1323,10 +1322,11 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
1323 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; 1322 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
1324 priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; 1323 priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
1325 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1324 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1325 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1326 spin_unlock_irqrestore(&priv->sta_lock, flags); 1326 spin_unlock_irqrestore(&priv->sta_lock, flags);
1327 1327
1328 return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 1328 return ret;
1329 CMD_ASYNC); 1329
1330} 1330}
1331EXPORT_SYMBOL(iwl_sta_rx_agg_stop); 1331EXPORT_SYMBOL(iwl_sta_rx_agg_stop);
1332 1332
@@ -1340,9 +1340,9 @@ void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
1340 priv->stations[sta_id].sta.sta.modify_mask = 0; 1340 priv->stations[sta_id].sta.sta.modify_mask = 0;
1341 priv->stations[sta_id].sta.sleep_tx_count = 0; 1341 priv->stations[sta_id].sta.sleep_tx_count = 0;
1342 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1342 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1343 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1343 spin_unlock_irqrestore(&priv->sta_lock, flags); 1344 spin_unlock_irqrestore(&priv->sta_lock, flags);
1344 1345
1345 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1346} 1346}
1347EXPORT_SYMBOL(iwl_sta_modify_ps_wake); 1347EXPORT_SYMBOL(iwl_sta_modify_ps_wake);
1348 1348
@@ -1357,9 +1357,9 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
1357 STA_MODIFY_SLEEP_TX_COUNT_MSK; 1357 STA_MODIFY_SLEEP_TX_COUNT_MSK;
1358 priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); 1358 priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
1359 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1359 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1360 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1360 spin_unlock_irqrestore(&priv->sta_lock, flags); 1361 spin_unlock_irqrestore(&priv->sta_lock, flags);
1361 1362
1362 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1363} 1363}
1364EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count); 1364EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
1365 1365
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index c2a453a1a991..5b1b1e461eb6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -107,4 +107,33 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
107 107
108 return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id; 108 return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id;
109} 109}
110
111/**
112 * iwl_sta_id_or_broadcast - return sta_id or broadcast sta
113 * @priv: iwl priv
114 * @sta: mac80211 station
115 *
116 * In certain circumstances mac80211 passes a station pointer
117 * that may be %NULL, for example during TX or key setup. In
118 * that case, we need to use the broadcast station, so this
119 * inline wraps that pattern.
120 */
121static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv,
122 struct ieee80211_sta *sta)
123{
124 int sta_id;
125
126 if (!sta)
127 return priv->hw_params.bcast_sta_id;
128
129 sta_id = iwl_sta_id(sta);
130
131 /*
132 * mac80211 should not be passing a partially
133 * initialised station!
134 */
135 WARN_ON(sta_id == IWL_INVALID_STATION);
136
137 return sta_id;
138}
110#endif /* __iwl_sta_h__ */ 139#endif /* __iwl_sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 1ece2ea09773..e732f21ce7e9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -77,21 +77,6 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
77} 77}
78EXPORT_SYMBOL(iwl_txq_update_write_ptr); 78EXPORT_SYMBOL(iwl_txq_update_write_ptr);
79 79
80
81void iwl_free_tfds_in_queue(struct iwl_priv *priv,
82 int sta_id, int tid, int freed)
83{
84 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
85 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
86 else {
87 IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
88 priv->stations[sta_id].tid[tid].tfds_in_queue,
89 freed);
90 priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
91 }
92}
93EXPORT_SYMBOL(iwl_free_tfds_in_queue);
94
95/** 80/**
96 * iwl_tx_queue_free - Deallocate DMA queue. 81 * iwl_tx_queue_free - Deallocate DMA queue.
97 * @txq: Transmit queue to deallocate. 82 * @txq: Transmit queue to deallocate.
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 3e5bffb6034f..f3127d599739 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -197,6 +197,7 @@ static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv,
197static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) 197static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
198{ 198{
199 unsigned long flags; 199 unsigned long flags;
200 struct iwl_addsta_cmd sta_cmd;
200 201
201 spin_lock_irqsave(&priv->sta_lock, flags); 202 spin_lock_irqsave(&priv->sta_lock, flags);
202 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); 203 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
@@ -205,11 +206,11 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
205 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; 206 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
206 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 207 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
207 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 208 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
209 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
208 spin_unlock_irqrestore(&priv->sta_lock, flags); 210 spin_unlock_irqrestore(&priv->sta_lock, flags);
209 211
210 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); 212 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
211 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0); 213 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
212 return 0;
213} 214}
214 215
215static int iwl3945_set_dynamic_key(struct iwl_priv *priv, 216static int iwl3945_set_dynamic_key(struct iwl_priv *priv,
@@ -474,10 +475,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
474 u8 unicast; 475 u8 unicast;
475 u8 sta_id; 476 u8 sta_id;
476 u8 tid = 0; 477 u8 tid = 0;
477 u16 seq_number = 0;
478 __le16 fc; 478 __le16 fc;
479 u8 wait_write_ptr = 0; 479 u8 wait_write_ptr = 0;
480 u8 *qc = NULL;
481 unsigned long flags; 480 unsigned long flags;
482 481
483 spin_lock_irqsave(&priv->lock, flags); 482 spin_lock_irqsave(&priv->lock, flags);
@@ -510,10 +509,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
510 hdr_len = ieee80211_hdrlen(fc); 509 hdr_len = ieee80211_hdrlen(fc);
511 510
512 /* Find index into station table for destination station */ 511 /* Find index into station table for destination station */
513 if (!info->control.sta) 512 sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta);
514 sta_id = priv->hw_params.bcast_sta_id;
515 else
516 sta_id = iwl_sta_id(info->control.sta);
517 if (sta_id == IWL_INVALID_STATION) { 513 if (sta_id == IWL_INVALID_STATION) {
518 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", 514 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
519 hdr->addr1); 515 hdr->addr1);
@@ -523,16 +519,10 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
523 IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id); 519 IWL_DEBUG_RATE(priv, "station Id %d\n", sta_id);
524 520
525 if (ieee80211_is_data_qos(fc)) { 521 if (ieee80211_is_data_qos(fc)) {
526 qc = ieee80211_get_qos_ctl(hdr); 522 u8 *qc = ieee80211_get_qos_ctl(hdr);
527 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 523 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
528 if (unlikely(tid >= MAX_TID_COUNT)) 524 if (unlikely(tid >= MAX_TID_COUNT))
529 goto drop; 525 goto drop;
530 seq_number = priv->stations[sta_id].tid[tid].seq_number &
531 IEEE80211_SCTL_SEQ;
532 hdr->seq_ctrl = cpu_to_le16(seq_number) |
533 (hdr->seq_ctrl &
534 cpu_to_le16(IEEE80211_SCTL_FRAG));
535 seq_number += 0x10;
536 } 526 }
537 527
538 /* Descriptor for chosen Tx queue */ 528 /* Descriptor for chosen Tx queue */
@@ -591,8 +581,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
591 581
592 if (!ieee80211_has_morefrags(hdr->frame_control)) { 582 if (!ieee80211_has_morefrags(hdr->frame_control)) {
593 txq->need_update = 1; 583 txq->need_update = 1;
594 if (qc)
595 priv->stations[sta_id].tid[tid].seq_number = seq_number;
596 } else { 584 } else {
597 wait_write_ptr = 1; 585 wait_write_ptr = 1;
598 txq->need_update = 0; 586 txq->need_update = 0;
@@ -3108,19 +3096,16 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3108 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3096 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3109 vif->bss_conf.aid, vif->bss_conf.beacon_int); 3097 vif->bss_conf.aid, vif->bss_conf.beacon_int);
3110 3098
3111 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 3099 if (vif->bss_conf.use_short_preamble)
3112 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3100 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3113 else 3101 else
3114 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3102 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3115 3103
3116 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3104 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3117 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) 3105 if (vif->bss_conf.use_short_slot)
3118 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 3106 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
3119 else 3107 else
3120 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3108 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3121
3122 if (vif->type == NL80211_IFTYPE_ADHOC)
3123 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3124 } 3109 }
3125 3110
3126 iwlcore_commit_rxon(priv); 3111 iwlcore_commit_rxon(priv);
@@ -3284,8 +3269,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3284 3269
3285 priv->staging_rxon.assoc_id = 0; 3270 priv->staging_rxon.assoc_id = 0;
3286 3271
3287 if (vif->bss_conf.assoc_capability & 3272 if (vif->bss_conf.use_short_preamble)
3288 WLAN_CAPABILITY_SHORT_PREAMBLE)
3289 priv->staging_rxon.flags |= 3273 priv->staging_rxon.flags |=
3290 RXON_FLG_SHORT_PREAMBLE_MSK; 3274 RXON_FLG_SHORT_PREAMBLE_MSK;
3291 else 3275 else
@@ -3293,17 +3277,12 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3293 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3277 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3294 3278
3295 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3279 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3296 if (vif->bss_conf.assoc_capability & 3280 if (vif->bss_conf.use_short_slot)
3297 WLAN_CAPABILITY_SHORT_SLOT_TIME)
3298 priv->staging_rxon.flags |= 3281 priv->staging_rxon.flags |=
3299 RXON_FLG_SHORT_SLOT_MSK; 3282 RXON_FLG_SHORT_SLOT_MSK;
3300 else 3283 else
3301 priv->staging_rxon.flags &= 3284 priv->staging_rxon.flags &=
3302 ~RXON_FLG_SHORT_SLOT_MSK; 3285 ~RXON_FLG_SHORT_SLOT_MSK;
3303
3304 if (vif->type == NL80211_IFTYPE_ADHOC)
3305 priv->staging_rxon.flags &=
3306 ~RXON_FLG_SHORT_SLOT_MSK;
3307 } 3286 }
3308 /* restore RXON assoc */ 3287 /* restore RXON assoc */
3309 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3288 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
@@ -3336,17 +3315,9 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3336 static_key = !iwl_is_associated(priv); 3315 static_key = !iwl_is_associated(priv);
3337 3316
3338 if (!static_key) { 3317 if (!static_key) {
3339 if (!sta) { 3318 sta_id = iwl_sta_id_or_broadcast(priv, sta);
3340 sta_id = priv->hw_params.bcast_sta_id; 3319 if (sta_id == IWL_INVALID_STATION)
3341 } else { 3320 return -EINVAL;
3342 sta_id = iwl_sta_id(sta);
3343 if (sta_id == IWL_INVALID_STATION) {
3344 IWL_DEBUG_MAC80211(priv,
3345 "leave - %pM not in station map.\n",
3346 sta->addr);
3347 return -EINVAL;
3348 }
3349 }
3350 } 3321 }
3351 3322
3352 mutex_lock(&priv->mutex); 3323 mutex_lock(&priv->mutex);