aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c254
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c148
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c154
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h30
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c101
18 files changed, 635 insertions, 173 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 8414178bcff4..0db1fda94a65 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -105,6 +105,7 @@ static struct iwl_lib_ops iwl1000_lib = {
105 .load_ucode = iwl5000_load_ucode, 105 .load_ucode = iwl5000_load_ucode,
106 .dump_nic_event_log = iwl_dump_nic_event_log, 106 .dump_nic_event_log = iwl_dump_nic_event_log,
107 .dump_nic_error_log = iwl_dump_nic_error_log, 107 .dump_nic_error_log = iwl_dump_nic_error_log,
108 .dump_csr = iwl_dump_csr,
108 .init_alive_start = iwl5000_init_alive_start, 109 .init_alive_start = iwl5000_init_alive_start,
109 .alive_notify = iwl5000_alive_notify, 110 .alive_notify = iwl5000_alive_notify,
110 .send_tx_power = iwl5000_send_tx_power, 111 .send_tx_power = iwl5000_send_tx_power,
@@ -140,7 +141,7 @@ static struct iwl_lib_ops iwl1000_lib = {
140 }, 141 },
141}; 142};
142 143
143static struct iwl_ops iwl1000_ops = { 144static const struct iwl_ops iwl1000_ops = {
144 .ucode = &iwl5000_ucode, 145 .ucode = &iwl5000_ucode,
145 .lib = &iwl1000_lib, 146 .lib = &iwl1000_lib,
146 .hcmd = &iwl5000_hcmd, 147 .hcmd = &iwl5000_hcmd,
@@ -173,7 +174,6 @@ struct iwl_cfg iwl1000_bgn_cfg = {
173 .use_rts_for_ht = true, /* use rts/cts protection */ 174 .use_rts_for_ht = true, /* use rts/cts protection */
174 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 175 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
175 .support_ct_kill_exit = true, 176 .support_ct_kill_exit = true,
176 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
177}; 177};
178 178
179struct iwl_cfg iwl1000_bg_cfg = { 179struct iwl_cfg iwl1000_bg_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 234891d8cc10..28ffe4c826d8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2804,7 +2804,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2804 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag, 2804 .rts_tx_cmd_flag = iwlcore_rts_tx_cmd_flag,
2805}; 2805};
2806 2806
2807static struct iwl_ops iwl3945_ops = { 2807static const struct iwl_ops iwl3945_ops = {
2808 .ucode = &iwl3945_ucode, 2808 .ucode = &iwl3945_ucode,
2809 .lib = &iwl3945_lib, 2809 .lib = &iwl3945_lib,
2810 .hcmd = &iwl3945_hcmd, 2810 .hcmd = &iwl3945_hcmd,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 531fa125f5a6..3ec2fe370b58 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -226,7 +226,8 @@ extern void iwl3945_rx_replenish(void *data);
226extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); 226extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
227extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, 227extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
228 struct ieee80211_hdr *hdr,int left); 228 struct ieee80211_hdr *hdr,int left);
229extern void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log); 229extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
230 char **buf, bool display);
230extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv); 231extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
231 232
232/* 233/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 9b4b8b5c7574..6a004abb5973 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2208,7 +2208,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2208 }, 2208 },
2209}; 2209};
2210 2210
2211static struct iwl_ops iwl4965_ops = { 2211static const struct iwl_ops iwl4965_ops = {
2212 .ucode = &iwl4965_ucode, 2212 .ucode = &iwl4965_ucode,
2213 .lib = &iwl4965_lib, 2213 .lib = &iwl4965_lib,
2214 .hcmd = &iwl4965_hcmd, 2214 .hcmd = &iwl4965_hcmd,
@@ -2239,7 +2239,6 @@ struct iwl_cfg iwl4965_agn_cfg = {
2239 .broken_powersave = true, 2239 .broken_powersave = true,
2240 .led_compensation = 61, 2240 .led_compensation = 61,
2241 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, 2241 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
2242 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
2243}; 2242};
2244 2243
2245/* Module firmware */ 2244/* Module firmware */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index de45f308b744..c6120f0b8f98 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -781,7 +781,7 @@ void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
781 781
782 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; 782 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
783 783
784 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) 784 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
785 scd_bc_tbl[txq_id]. 785 scd_bc_tbl[txq_id].
786 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; 786 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
787} 787}
@@ -800,12 +800,12 @@ void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
800 if (txq_id != IWL_CMD_QUEUE_NUM) 800 if (txq_id != IWL_CMD_QUEUE_NUM)
801 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id; 801 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
802 802
803 bc_ent = cpu_to_le16(1 | (sta_id << 12)); 803 bc_ent = cpu_to_le16(1 | (sta_id << 12));
804 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; 804 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
805 805
806 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) 806 if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
807 scd_bc_tbl[txq_id]. 807 scd_bc_tbl[txq_id].
808 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; 808 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
809} 809}
810 810
811static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, 811static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
@@ -1466,6 +1466,7 @@ struct iwl_lib_ops iwl5000_lib = {
1466 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 1466 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1467 .dump_nic_event_log = iwl_dump_nic_event_log, 1467 .dump_nic_event_log = iwl_dump_nic_event_log,
1468 .dump_nic_error_log = iwl_dump_nic_error_log, 1468 .dump_nic_error_log = iwl_dump_nic_error_log,
1469 .dump_csr = iwl_dump_csr,
1469 .load_ucode = iwl5000_load_ucode, 1470 .load_ucode = iwl5000_load_ucode,
1470 .init_alive_start = iwl5000_init_alive_start, 1471 .init_alive_start = iwl5000_init_alive_start,
1471 .alive_notify = iwl5000_alive_notify, 1472 .alive_notify = iwl5000_alive_notify,
@@ -1518,6 +1519,7 @@ static struct iwl_lib_ops iwl5150_lib = {
1518 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, 1519 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
1519 .dump_nic_event_log = iwl_dump_nic_event_log, 1520 .dump_nic_event_log = iwl_dump_nic_event_log,
1520 .dump_nic_error_log = iwl_dump_nic_error_log, 1521 .dump_nic_error_log = iwl_dump_nic_error_log,
1522 .dump_csr = iwl_dump_csr,
1521 .load_ucode = iwl5000_load_ucode, 1523 .load_ucode = iwl5000_load_ucode,
1522 .init_alive_start = iwl5000_init_alive_start, 1524 .init_alive_start = iwl5000_init_alive_start,
1523 .alive_notify = iwl5000_alive_notify, 1525 .alive_notify = iwl5000_alive_notify,
@@ -1555,7 +1557,7 @@ static struct iwl_lib_ops iwl5150_lib = {
1555 }, 1557 },
1556}; 1558};
1557 1559
1558static struct iwl_ops iwl5000_ops = { 1560static const struct iwl_ops iwl5000_ops = {
1559 .ucode = &iwl5000_ucode, 1561 .ucode = &iwl5000_ucode,
1560 .lib = &iwl5000_lib, 1562 .lib = &iwl5000_lib,
1561 .hcmd = &iwl5000_hcmd, 1563 .hcmd = &iwl5000_hcmd,
@@ -1563,7 +1565,7 @@ static struct iwl_ops iwl5000_ops = {
1563 .led = &iwlagn_led_ops, 1565 .led = &iwlagn_led_ops,
1564}; 1566};
1565 1567
1566static struct iwl_ops iwl5150_ops = { 1568static const struct iwl_ops iwl5150_ops = {
1567 .ucode = &iwl5000_ucode, 1569 .ucode = &iwl5000_ucode,
1568 .lib = &iwl5150_lib, 1570 .lib = &iwl5150_lib,
1569 .hcmd = &iwl5000_hcmd, 1571 .hcmd = &iwl5000_hcmd,
@@ -1600,7 +1602,6 @@ struct iwl_cfg iwl5300_agn_cfg = {
1600 .led_compensation = 51, 1602 .led_compensation = 51,
1601 .use_rts_for_ht = true, /* use rts/cts protection */ 1603 .use_rts_for_ht = true, /* use rts/cts protection */
1602 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1604 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1603 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
1604}; 1605};
1605 1606
1606struct iwl_cfg iwl5100_bgn_cfg = { 1607struct iwl_cfg iwl5100_bgn_cfg = {
@@ -1671,7 +1672,6 @@ struct iwl_cfg iwl5100_agn_cfg = {
1671 .led_compensation = 51, 1672 .led_compensation = 51,
1672 .use_rts_for_ht = true, /* use rts/cts protection */ 1673 .use_rts_for_ht = true, /* use rts/cts protection */
1673 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1674 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1674 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
1675}; 1675};
1676 1676
1677struct iwl_cfg iwl5350_agn_cfg = { 1677struct iwl_cfg iwl5350_agn_cfg = {
@@ -1696,7 +1696,6 @@ struct iwl_cfg iwl5350_agn_cfg = {
1696 .led_compensation = 51, 1696 .led_compensation = 51,
1697 .use_rts_for_ht = true, /* use rts/cts protection */ 1697 .use_rts_for_ht = true, /* use rts/cts protection */
1698 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1698 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1699 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
1700}; 1699};
1701 1700
1702struct iwl_cfg iwl5150_agn_cfg = { 1701struct iwl_cfg iwl5150_agn_cfg = {
@@ -1721,7 +1720,6 @@ struct iwl_cfg iwl5150_agn_cfg = {
1721 .led_compensation = 51, 1720 .led_compensation = 51,
1722 .use_rts_for_ht = true, /* use rts/cts protection */ 1721 .use_rts_for_ht = true, /* use rts/cts protection */
1723 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1722 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1724 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
1725}; 1723};
1726 1724
1727struct iwl_cfg iwl5150_abg_cfg = { 1725struct iwl_cfg iwl5150_abg_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 74e571049273..a5a0ed4817a4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -215,6 +215,7 @@ static struct iwl_lib_ops iwl6000_lib = {
215 .load_ucode = iwl5000_load_ucode, 215 .load_ucode = iwl5000_load_ucode,
216 .dump_nic_event_log = iwl_dump_nic_event_log, 216 .dump_nic_event_log = iwl_dump_nic_event_log,
217 .dump_nic_error_log = iwl_dump_nic_error_log, 217 .dump_nic_error_log = iwl_dump_nic_error_log,
218 .dump_csr = iwl_dump_csr,
218 .init_alive_start = iwl5000_init_alive_start, 219 .init_alive_start = iwl5000_init_alive_start,
219 .alive_notify = iwl5000_alive_notify, 220 .alive_notify = iwl5000_alive_notify,
220 .send_tx_power = iwl5000_send_tx_power, 221 .send_tx_power = iwl5000_send_tx_power,
@@ -252,7 +253,7 @@ static struct iwl_lib_ops iwl6000_lib = {
252 }, 253 },
253}; 254};
254 255
255static struct iwl_ops iwl6000_ops = { 256static const struct iwl_ops iwl6000_ops = {
256 .ucode = &iwl5000_ucode, 257 .ucode = &iwl5000_ucode,
257 .lib = &iwl6000_lib, 258 .lib = &iwl6000_lib,
258 .hcmd = &iwl5000_hcmd, 259 .hcmd = &iwl5000_hcmd,
@@ -267,7 +268,7 @@ static struct iwl_hcmd_utils_ops iwl6050_hcmd_utils = {
267 .calc_rssi = iwl5000_calc_rssi, 268 .calc_rssi = iwl5000_calc_rssi,
268}; 269};
269 270
270static struct iwl_ops iwl6050_ops = { 271static const struct iwl_ops iwl6050_ops = {
271 .ucode = &iwl5000_ucode, 272 .ucode = &iwl5000_ucode,
272 .lib = &iwl6000_lib, 273 .lib = &iwl6000_lib,
273 .hcmd = &iwl5000_hcmd, 274 .hcmd = &iwl5000_hcmd,
@@ -306,7 +307,6 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
306 .supports_idle = true, 307 .supports_idle = true,
307 .adv_thermal_throttle = true, 308 .adv_thermal_throttle = true,
308 .support_ct_kill_exit = true, 309 .support_ct_kill_exit = true,
309 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
310}; 310};
311 311
312struct iwl_cfg iwl6000i_2abg_cfg = { 312struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -395,7 +395,6 @@ struct iwl_cfg iwl6050_2agn_cfg = {
395 .supports_idle = true, 395 .supports_idle = true,
396 .adv_thermal_throttle = true, 396 .adv_thermal_throttle = true,
397 .support_ct_kill_exit = true, 397 .support_ct_kill_exit = true,
398 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DYNAMIC,
399}; 398};
400 399
401struct iwl_cfg iwl6050_2abg_cfg = { 400struct iwl_cfg iwl6050_2abg_cfg = {
@@ -455,7 +454,6 @@ struct iwl_cfg iwl6000_3agn_cfg = {
455 .supports_idle = true, 454 .supports_idle = true,
456 .adv_thermal_throttle = true, 455 .adv_thermal_throttle = true,
457 .support_ct_kill_exit = true, 456 .support_ct_kill_exit = true,
458 .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
459}; 457};
460 458
461MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 459MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 1c9866daf815..c78063312ea9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -657,6 +657,131 @@ static void iwl_bg_statistics_periodic(unsigned long data)
657 iwl_send_statistics_request(priv, CMD_ASYNC, false); 657 iwl_send_statistics_request(priv, CMD_ASYNC, false);
658} 658}
659 659
660
661static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
662 u32 start_idx, u32 num_events,
663 u32 mode)
664{
665 u32 i;
666 u32 ptr; /* SRAM byte address of log data */
667 u32 ev, time, data; /* event log data */
668 unsigned long reg_flags;
669
670 if (mode == 0)
671 ptr = base + (4 * sizeof(u32)) + (start_idx * 2 * sizeof(u32));
672 else
673 ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32));
674
675 /* Make sure device is powered up for SRAM reads */
676 spin_lock_irqsave(&priv->reg_lock, reg_flags);
677 if (iwl_grab_nic_access(priv)) {
678 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
679 return;
680 }
681
682 /* Set starting address; reads will auto-increment */
683 _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
684 rmb();
685
686 /*
687 * "time" is actually "data" for mode 0 (no timestamp).
688 * place event id # at far right for easier visual parsing.
689 */
690 for (i = 0; i < num_events; i++) {
691 ev = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
692 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
693 if (mode == 0) {
694 trace_iwlwifi_dev_ucode_cont_event(priv,
695 0, time, ev);
696 } else {
697 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
698 trace_iwlwifi_dev_ucode_cont_event(priv,
699 time, data, ev);
700 }
701 }
702 /* Allow device to power down */
703 iwl_release_nic_access(priv);
704 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
705}
706
707void iwl_continuous_event_trace(struct iwl_priv *priv)
708{
709 u32 capacity; /* event log capacity in # entries */
710 u32 base; /* SRAM byte address of event log header */
711 u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
712 u32 num_wraps; /* # times uCode wrapped to top of log */
713 u32 next_entry; /* index of next entry to be written by uCode */
714
715 if (priv->ucode_type == UCODE_INIT)
716 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
717 else
718 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
719 if (priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
720 capacity = iwl_read_targ_mem(priv, base);
721 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
722 mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
723 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
724 } else
725 return;
726
727 if (num_wraps == priv->event_log.num_wraps) {
728 iwl_print_cont_event_trace(priv,
729 base, priv->event_log.next_entry,
730 next_entry - priv->event_log.next_entry,
731 mode);
732 priv->event_log.non_wraps_count++;
733 } else {
734 if ((num_wraps - priv->event_log.num_wraps) > 1)
735 priv->event_log.wraps_more_count++;
736 else
737 priv->event_log.wraps_once_count++;
738 trace_iwlwifi_dev_ucode_wrap_event(priv,
739 num_wraps - priv->event_log.num_wraps,
740 next_entry, priv->event_log.next_entry);
741 if (next_entry < priv->event_log.next_entry) {
742 iwl_print_cont_event_trace(priv, base,
743 priv->event_log.next_entry,
744 capacity - priv->event_log.next_entry,
745 mode);
746
747 iwl_print_cont_event_trace(priv, base, 0,
748 next_entry, mode);
749 } else {
750 iwl_print_cont_event_trace(priv, base,
751 next_entry, capacity - next_entry,
752 mode);
753
754 iwl_print_cont_event_trace(priv, base, 0,
755 next_entry, mode);
756 }
757 }
758 priv->event_log.num_wraps = num_wraps;
759 priv->event_log.next_entry = next_entry;
760}
761
762/**
763 * iwl_bg_ucode_trace - Timer callback to log ucode event
764 *
765 * The timer is continually set to execute every
766 * UCODE_TRACE_PERIOD milliseconds after the last timer expired
767 * this function is to perform continuous uCode event logging operation
768 * if enabled
769 */
770static void iwl_bg_ucode_trace(unsigned long data)
771{
772 struct iwl_priv *priv = (struct iwl_priv *)data;
773
774 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
775 return;
776
777 if (priv->event_log.ucode_trace) {
778 iwl_continuous_event_trace(priv);
779 /* Reschedule the timer to occur in UCODE_TRACE_PERIOD */
780 mod_timer(&priv->ucode_trace,
781 jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
782 }
783}
784
660static void iwl_rx_beacon_notif(struct iwl_priv *priv, 785static void iwl_rx_beacon_notif(struct iwl_priv *priv,
661 struct iwl_rx_mem_buffer *rxb) 786 struct iwl_rx_mem_buffer *rxb)
662{ 787{
@@ -689,12 +814,14 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
689 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); 814 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
690 unsigned long status = priv->status; 815 unsigned long status = priv->status;
691 816
692 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n", 817 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n",
693 (flags & HW_CARD_DISABLED) ? "Kill" : "On", 818 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
694 (flags & SW_CARD_DISABLED) ? "Kill" : "On"); 819 (flags & SW_CARD_DISABLED) ? "Kill" : "On",
820 (flags & CT_CARD_DISABLED) ?
821 "Reached" : "Not reached");
695 822
696 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | 823 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
697 RF_CARD_DISABLED)) { 824 CT_CARD_DISABLED)) {
698 825
699 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, 826 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
700 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); 827 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
@@ -708,10 +835,10 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
708 iwl_write_direct32(priv, HBUS_TARG_MBX_C, 835 iwl_write_direct32(priv, HBUS_TARG_MBX_C,
709 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); 836 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
710 } 837 }
711 if (flags & RF_CARD_DISABLED) 838 if (flags & CT_CARD_DISABLED)
712 iwl_tt_enter_ct_kill(priv); 839 iwl_tt_enter_ct_kill(priv);
713 } 840 }
714 if (!(flags & RF_CARD_DISABLED)) 841 if (!(flags & CT_CARD_DISABLED))
715 iwl_tt_exit_ct_kill(priv); 842 iwl_tt_exit_ct_kill(priv);
716 843
717 if (flags & HW_CARD_DISABLED) 844 if (flags & HW_CARD_DISABLED)
@@ -1705,8 +1832,9 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1705 * iwl_print_event_log - Dump error event log to syslog 1832 * iwl_print_event_log - Dump error event log to syslog
1706 * 1833 *
1707 */ 1834 */
1708static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, 1835static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1709 u32 num_events, u32 mode) 1836 u32 num_events, u32 mode,
1837 int pos, char **buf, size_t bufsz)
1710{ 1838{
1711 u32 i; 1839 u32 i;
1712 u32 base; /* SRAM byte address of event log header */ 1840 u32 base; /* SRAM byte address of event log header */
@@ -1716,7 +1844,7 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1716 unsigned long reg_flags; 1844 unsigned long reg_flags;
1717 1845
1718 if (num_events == 0) 1846 if (num_events == 0)
1719 return; 1847 return pos;
1720 if (priv->ucode_type == UCODE_INIT) 1848 if (priv->ucode_type == UCODE_INIT)
1721 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 1849 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
1722 else 1850 else
@@ -1744,27 +1872,44 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1744 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1872 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1745 if (mode == 0) { 1873 if (mode == 0) {
1746 /* data, ev */ 1874 /* data, ev */
1747 trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); 1875 if (bufsz) {
1748 IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev); 1876 pos += scnprintf(*buf + pos, bufsz - pos,
1877 "EVT_LOG:0x%08x:%04u\n",
1878 time, ev);
1879 } else {
1880 trace_iwlwifi_dev_ucode_event(priv, 0,
1881 time, ev);
1882 IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n",
1883 time, ev);
1884 }
1749 } else { 1885 } else {
1750 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1886 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1751 IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n", 1887 if (bufsz) {
1888 pos += scnprintf(*buf + pos, bufsz - pos,
1889 "EVT_LOGT:%010u:0x%08x:%04u\n",
1890 time, data, ev);
1891 } else {
1892 IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
1752 time, data, ev); 1893 time, data, ev);
1753 trace_iwlwifi_dev_ucode_event(priv, time, data, ev); 1894 trace_iwlwifi_dev_ucode_event(priv, time,
1895 data, ev);
1896 }
1754 } 1897 }
1755 } 1898 }
1756 1899
1757 /* Allow device to power down */ 1900 /* Allow device to power down */
1758 iwl_release_nic_access(priv); 1901 iwl_release_nic_access(priv);
1759 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 1902 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
1903 return pos;
1760} 1904}
1761 1905
1762/** 1906/**
1763 * iwl_print_last_event_logs - Dump the newest # of event log to syslog 1907 * iwl_print_last_event_logs - Dump the newest # of event log to syslog
1764 */ 1908 */
1765static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity, 1909static int iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1766 u32 num_wraps, u32 next_entry, 1910 u32 num_wraps, u32 next_entry,
1767 u32 size, u32 mode) 1911 u32 size, u32 mode,
1912 int pos, char **buf, size_t bufsz)
1768{ 1913{
1769 /* 1914 /*
1770 * display the newest DEFAULT_LOG_ENTRIES entries 1915 * display the newest DEFAULT_LOG_ENTRIES entries
@@ -1772,21 +1917,26 @@ static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1772 */ 1917 */
1773 if (num_wraps) { 1918 if (num_wraps) {
1774 if (next_entry < size) { 1919 if (next_entry < size) {
1775 iwl_print_event_log(priv, 1920 pos = iwl_print_event_log(priv,
1776 capacity - (size - next_entry), 1921 capacity - (size - next_entry),
1777 size - next_entry, mode); 1922 size - next_entry, mode,
1778 iwl_print_event_log(priv, 0, 1923 pos, buf, bufsz);
1779 next_entry, mode); 1924 pos = iwl_print_event_log(priv, 0,
1925 next_entry, mode,
1926 pos, buf, bufsz);
1780 } else 1927 } else
1781 iwl_print_event_log(priv, next_entry - size, 1928 pos = iwl_print_event_log(priv, next_entry - size,
1782 size, mode); 1929 size, mode, pos, buf, bufsz);
1783 } else { 1930 } else {
1784 if (next_entry < size) 1931 if (next_entry < size) {
1785 iwl_print_event_log(priv, 0, next_entry, mode); 1932 pos = iwl_print_event_log(priv, 0, next_entry,
1786 else 1933 mode, pos, buf, bufsz);
1787 iwl_print_event_log(priv, next_entry - size, 1934 } else {
1788 size, mode); 1935 pos = iwl_print_event_log(priv, next_entry - size,
1936 size, mode, pos, buf, bufsz);
1937 }
1789 } 1938 }
1939 return pos;
1790} 1940}
1791 1941
1792/* For sanity check only. Actual size is determined by uCode, typ. 512 */ 1942/* For sanity check only. Actual size is determined by uCode, typ. 512 */
@@ -1794,7 +1944,8 @@ static void iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1794 1944
1795#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20) 1945#define DEFAULT_DUMP_EVENT_LOG_ENTRIES (20)
1796 1946
1797void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log) 1947int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1948 char **buf, bool display)
1798{ 1949{
1799 u32 base; /* SRAM byte address of event log header */ 1950 u32 base; /* SRAM byte address of event log header */
1800 u32 capacity; /* event log capacity in # entries */ 1951 u32 capacity; /* event log capacity in # entries */
@@ -1802,6 +1953,8 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1802 u32 num_wraps; /* # times uCode wrapped to top of log */ 1953 u32 num_wraps; /* # times uCode wrapped to top of log */
1803 u32 next_entry; /* index of next entry to be written by uCode */ 1954 u32 next_entry; /* index of next entry to be written by uCode */
1804 u32 size; /* # entries that we'll print */ 1955 u32 size; /* # entries that we'll print */
1956 int pos = 0;
1957 size_t bufsz = 0;
1805 1958
1806 if (priv->ucode_type == UCODE_INIT) 1959 if (priv->ucode_type == UCODE_INIT)
1807 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr); 1960 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
@@ -1812,7 +1965,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1812 IWL_ERR(priv, 1965 IWL_ERR(priv,
1813 "Invalid event log pointer 0x%08X for %s uCode\n", 1966 "Invalid event log pointer 0x%08X for %s uCode\n",
1814 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); 1967 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
1815 return; 1968 return pos;
1816 } 1969 }
1817 1970
1818 /* event log header */ 1971 /* event log header */
@@ -1838,7 +1991,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1838 /* bail out if nothing in log */ 1991 /* bail out if nothing in log */
1839 if (size == 0) { 1992 if (size == 0) {
1840 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); 1993 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1841 return; 1994 return pos;
1842 } 1995 }
1843 1996
1844#ifdef CONFIG_IWLWIFI_DEBUG 1997#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1853,6 +2006,15 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1853 size); 2006 size);
1854 2007
1855#ifdef CONFIG_IWLWIFI_DEBUG 2008#ifdef CONFIG_IWLWIFI_DEBUG
2009 if (display) {
2010 if (full_log)
2011 bufsz = capacity * 48;
2012 else
2013 bufsz = size * 48;
2014 *buf = kmalloc(bufsz, GFP_KERNEL);
2015 if (!*buf)
2016 return pos;
2017 }
1856 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 2018 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1857 /* 2019 /*
1858 * if uCode has wrapped back to top of log, 2020 * if uCode has wrapped back to top of log,
@@ -1860,17 +2022,22 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1860 * i.e the next one that uCode would fill. 2022 * i.e the next one that uCode would fill.
1861 */ 2023 */
1862 if (num_wraps) 2024 if (num_wraps)
1863 iwl_print_event_log(priv, next_entry, 2025 pos = iwl_print_event_log(priv, next_entry,
1864 capacity - next_entry, mode); 2026 capacity - next_entry, mode,
2027 pos, buf, bufsz);
1865 /* (then/else) start at top of log */ 2028 /* (then/else) start at top of log */
1866 iwl_print_event_log(priv, 0, next_entry, mode); 2029 pos = iwl_print_event_log(priv, 0,
2030 next_entry, mode, pos, buf, bufsz);
1867 } else 2031 } else
1868 iwl_print_last_event_logs(priv, capacity, num_wraps, 2032 pos = iwl_print_last_event_logs(priv, capacity, num_wraps,
1869 next_entry, size, mode); 2033 next_entry, size, mode,
2034 pos, buf, bufsz);
1870#else 2035#else
1871 iwl_print_last_event_logs(priv, capacity, num_wraps, 2036 pos = iwl_print_last_event_logs(priv, capacity, num_wraps,
1872 next_entry, size, mode); 2037 next_entry, size, mode,
2038 pos, buf, bufsz);
1873#endif 2039#endif
2040 return pos;
1874} 2041}
1875 2042
1876/** 2043/**
@@ -2456,6 +2623,10 @@ static int iwl_setup_mac(struct iwl_priv *priv)
2456 hw->flags |= IEEE80211_HW_SUPPORTS_PS | 2623 hw->flags |= IEEE80211_HW_SUPPORTS_PS |
2457 IEEE80211_HW_SUPPORTS_DYNAMIC_PS; 2624 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
2458 2625
2626 if (priv->cfg->sku & IWL_SKU_N)
2627 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
2628 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
2629
2459 hw->sta_data_size = sizeof(struct iwl_station_priv); 2630 hw->sta_data_size = sizeof(struct iwl_station_priv);
2460 hw->wiphy->interface_modes = 2631 hw->wiphy->interface_modes =
2461 BIT(NL80211_IFTYPE_STATION) | 2632 BIT(NL80211_IFTYPE_STATION) |
@@ -2784,6 +2955,9 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
2784 return 0; 2955 return 0;
2785 else 2956 else
2786 return ret; 2957 return ret;
2958 case IEEE80211_AMPDU_TX_OPERATIONAL:
2959 /* do nothing */
2960 return -EOPNOTSUPP;
2787 default: 2961 default:
2788 IWL_DEBUG_HT(priv, "unknown\n"); 2962 IWL_DEBUG_HT(priv, "unknown\n");
2789 return -EINVAL; 2963 return -EINVAL;
@@ -3126,6 +3300,10 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3126 priv->statistics_periodic.data = (unsigned long)priv; 3300 priv->statistics_periodic.data = (unsigned long)priv;
3127 priv->statistics_periodic.function = iwl_bg_statistics_periodic; 3301 priv->statistics_periodic.function = iwl_bg_statistics_periodic;
3128 3302
3303 init_timer(&priv->ucode_trace);
3304 priv->ucode_trace.data = (unsigned long)priv;
3305 priv->ucode_trace.function = iwl_bg_ucode_trace;
3306
3129 if (!priv->cfg->use_isr_legacy) 3307 if (!priv->cfg->use_isr_legacy)
3130 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3308 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3131 iwl_irq_tasklet, (unsigned long)priv); 3309 iwl_irq_tasklet, (unsigned long)priv);
@@ -3144,6 +3322,7 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
3144 cancel_delayed_work(&priv->alive_start); 3322 cancel_delayed_work(&priv->alive_start);
3145 cancel_work_sync(&priv->beacon_update); 3323 cancel_work_sync(&priv->beacon_update);
3146 del_timer_sync(&priv->statistics_periodic); 3324 del_timer_sync(&priv->statistics_periodic);
3325 del_timer_sync(&priv->ucode_trace);
3147} 3326}
3148 3327
3149static void iwl_init_hw_rates(struct iwl_priv *priv, 3328static void iwl_init_hw_rates(struct iwl_priv *priv,
@@ -3188,6 +3367,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
3188 priv->band = IEEE80211_BAND_2GHZ; 3367 priv->band = IEEE80211_BAND_2GHZ;
3189 3368
3190 priv->iw_mode = NL80211_IFTYPE_STATION; 3369 priv->iw_mode = NL80211_IFTYPE_STATION;
3370 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
3191 3371
3192 /* Choose which receivers/antennas to use */ 3372 /* Choose which receivers/antennas to use */
3193 if (priv->cfg->ops->hcmd->set_rxon_chain) 3373 if (priv->cfg->ops->hcmd->set_rxon_chain)
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 95a57b36a7ea..dc61906290e8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -414,7 +414,6 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
414/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ 414/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
415static int iwl_sensitivity_write(struct iwl_priv *priv) 415static int iwl_sensitivity_write(struct iwl_priv *priv)
416{ 416{
417 int ret = 0;
418 struct iwl_sensitivity_cmd cmd ; 417 struct iwl_sensitivity_cmd cmd ;
419 struct iwl_sensitivity_data *data = NULL; 418 struct iwl_sensitivity_data *data = NULL;
420 struct iwl_host_cmd cmd_out = { 419 struct iwl_host_cmd cmd_out = {
@@ -477,11 +476,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
477 memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), 476 memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
478 sizeof(u16)*HD_TABLE_SIZE); 477 sizeof(u16)*HD_TABLE_SIZE);
479 478
480 ret = iwl_send_cmd(priv, &cmd_out); 479 return iwl_send_cmd(priv, &cmd_out);
481 if (ret)
482 IWL_ERR(priv, "SENSITIVITY_CMD failed\n");
483
484 return ret;
485} 480}
486 481
487void iwl_init_sensitivity(struct iwl_priv *priv) 482void iwl_init_sensitivity(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index e91507531923..3320cce3d57b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -120,7 +120,6 @@ enum {
120 CALIBRATION_COMPLETE_NOTIFICATION = 0x67, 120 CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
121 121
122 /* 802.11h related */ 122 /* 802.11h related */
123 RADAR_NOTIFICATION = 0x70, /* not used */
124 REPLY_QUIET_CMD = 0x71, /* not used */ 123 REPLY_QUIET_CMD = 0x71, /* not used */
125 REPLY_CHANNEL_SWITCH = 0x72, 124 REPLY_CHANNEL_SWITCH = 0x72,
126 CHANNEL_SWITCH_NOTIFICATION = 0x73, 125 CHANNEL_SWITCH_NOTIFICATION = 0x73,
@@ -2510,7 +2509,7 @@ struct iwl_card_state_notif {
2510 2509
2511#define HW_CARD_DISABLED 0x01 2510#define HW_CARD_DISABLED 0x01
2512#define SW_CARD_DISABLED 0x02 2511#define SW_CARD_DISABLED 0x02
2513#define RF_CARD_DISABLED 0x04 2512#define CT_CARD_DISABLED 0x04
2514#define RXON_CARD_DISABLED 0x10 2513#define RXON_CARD_DISABLED 0x10
2515 2514
2516struct iwl_ct_kill_config { 2515struct iwl_ct_kill_config {
@@ -2984,7 +2983,7 @@ struct statistics_rx_ht_phy {
2984 __le32 agg_crc32_good; 2983 __le32 agg_crc32_good;
2985 __le32 agg_mpdu_cnt; 2984 __le32 agg_mpdu_cnt;
2986 __le32 agg_cnt; 2985 __le32 agg_cnt;
2987 __le32 reserved2; 2986 __le32 unsupport_mcs;
2988} __attribute__ ((packed)); 2987} __attribute__ ((packed));
2989 2988
2990#define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1) 2989#define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1)
@@ -3087,8 +3086,8 @@ struct statistics_div {
3087} __attribute__ ((packed)); 3086} __attribute__ ((packed));
3088 3087
3089struct statistics_general { 3088struct statistics_general {
3090 __le32 temperature; 3089 __le32 temperature; /* radio temperature */
3091 __le32 temperature_m; 3090 __le32 temperature_m; /* for 5000 and up, this is radio voltage */
3092 struct statistics_dbg dbg; 3091 struct statistics_dbg dbg;
3093 __le32 sleep_time; 3092 __le32 sleep_time;
3094 __le32 slots_out; 3093 __le32 slots_out;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 5461f105bd2d..5b56307a3812 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -450,8 +450,6 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
450 if (priv->cfg->ht_greenfield_support) 450 if (priv->cfg->ht_greenfield_support)
451 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; 451 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
452 ht_info->cap |= IEEE80211_HT_CAP_SGI_20; 452 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
453 ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
454 (priv->cfg->sm_ps_mode << 2));
455 max_bit_rate = MAX_BIT_RATE_20_MHZ; 453 max_bit_rate = MAX_BIT_RATE_20_MHZ;
456 if (priv->hw_params.ht40_channel & BIT(band)) { 454 if (priv->hw_params.ht40_channel & BIT(band)) {
457 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 455 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@ -636,7 +634,7 @@ EXPORT_SYMBOL(iwlcore_rts_tx_cmd_flag);
636 634
637static bool is_single_rx_stream(struct iwl_priv *priv) 635static bool is_single_rx_stream(struct iwl_priv *priv)
638{ 636{
639 return !priv->current_ht_config.is_ht || 637 return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
640 priv->current_ht_config.single_chain_sufficient; 638 priv->current_ht_config.single_chain_sufficient;
641} 639}
642 640
@@ -1003,28 +1001,18 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
1003 */ 1001 */
1004static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) 1002static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
1005{ 1003{
1006 int idle_cnt = active_cnt; 1004 /* # Rx chains when idling, depending on SMPS mode */
1007 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); 1005 switch (priv->current_ht_config.smps) {
1008 1006 case IEEE80211_SMPS_STATIC:
1009 /* # Rx chains when idling and maybe trying to save power */ 1007 case IEEE80211_SMPS_DYNAMIC:
1010 switch (priv->cfg->sm_ps_mode) { 1008 return IWL_NUM_IDLE_CHAINS_SINGLE;
1011 case WLAN_HT_CAP_SM_PS_STATIC: 1009 case IEEE80211_SMPS_OFF:
1012 idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE; 1010 return active_cnt;
1013 break;
1014 case WLAN_HT_CAP_SM_PS_DYNAMIC:
1015 idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
1016 IWL_NUM_IDLE_CHAINS_SINGLE;
1017 break;
1018 case WLAN_HT_CAP_SM_PS_DISABLED:
1019 break;
1020 case WLAN_HT_CAP_SM_PS_INVALID:
1021 default: 1011 default:
1022 IWL_ERR(priv, "invalid sm_ps mode %u\n", 1012 WARN(1, "invalid SMPS mode %d",
1023 priv->cfg->sm_ps_mode); 1013 priv->current_ht_config.smps);
1024 WARN_ON(1); 1014 return active_cnt;
1025 break;
1026 } 1015 }
1027 return idle_cnt;
1028} 1016}
1029 1017
1030/* up to 4 chains */ 1018/* up to 4 chains */
@@ -1363,7 +1351,9 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1363 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 1351 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1364 1352
1365 priv->cfg->ops->lib->dump_nic_error_log(priv); 1353 priv->cfg->ops->lib->dump_nic_error_log(priv);
1366 priv->cfg->ops->lib->dump_nic_event_log(priv, false); 1354 if (priv->cfg->ops->lib->dump_csr)
1355 priv->cfg->ops->lib->dump_csr(priv);
1356 priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
1367#ifdef CONFIG_IWLWIFI_DEBUG 1357#ifdef CONFIG_IWLWIFI_DEBUG
1368 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) 1358 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
1369 iwl_print_rx_config_cmd(priv); 1359 iwl_print_rx_config_cmd(priv);
@@ -2599,12 +2589,12 @@ int iwl_set_mode(struct iwl_priv *priv, int mode)
2599EXPORT_SYMBOL(iwl_set_mode); 2589EXPORT_SYMBOL(iwl_set_mode);
2600 2590
2601int iwl_mac_add_interface(struct ieee80211_hw *hw, 2591int iwl_mac_add_interface(struct ieee80211_hw *hw,
2602 struct ieee80211_if_init_conf *conf) 2592 struct ieee80211_vif *vif)
2603{ 2593{
2604 struct iwl_priv *priv = hw->priv; 2594 struct iwl_priv *priv = hw->priv;
2605 unsigned long flags; 2595 unsigned long flags;
2606 2596
2607 IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type); 2597 IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type);
2608 2598
2609 if (priv->vif) { 2599 if (priv->vif) {
2610 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); 2600 IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
@@ -2612,19 +2602,19 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
2612 } 2602 }
2613 2603
2614 spin_lock_irqsave(&priv->lock, flags); 2604 spin_lock_irqsave(&priv->lock, flags);
2615 priv->vif = conf->vif; 2605 priv->vif = vif;
2616 priv->iw_mode = conf->type; 2606 priv->iw_mode = vif->type;
2617 2607
2618 spin_unlock_irqrestore(&priv->lock, flags); 2608 spin_unlock_irqrestore(&priv->lock, flags);
2619 2609
2620 mutex_lock(&priv->mutex); 2610 mutex_lock(&priv->mutex);
2621 2611
2622 if (conf->mac_addr) { 2612 if (vif->addr) {
2623 IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr); 2613 IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr);
2624 memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); 2614 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
2625 } 2615 }
2626 2616
2627 if (iwl_set_mode(priv, conf->type) == -EAGAIN) 2617 if (iwl_set_mode(priv, vif->type) == -EAGAIN)
2628 /* we are not ready, will run again when ready */ 2618 /* we are not ready, will run again when ready */
2629 set_bit(STATUS_MODE_PENDING, &priv->status); 2619 set_bit(STATUS_MODE_PENDING, &priv->status);
2630 2620
@@ -2636,7 +2626,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
2636EXPORT_SYMBOL(iwl_mac_add_interface); 2626EXPORT_SYMBOL(iwl_mac_add_interface);
2637 2627
2638void iwl_mac_remove_interface(struct ieee80211_hw *hw, 2628void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2639 struct ieee80211_if_init_conf *conf) 2629 struct ieee80211_vif *vif)
2640{ 2630{
2641 struct iwl_priv *priv = hw->priv; 2631 struct iwl_priv *priv = hw->priv;
2642 2632
@@ -2649,7 +2639,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2649 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2639 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2650 iwlcore_commit_rxon(priv); 2640 iwlcore_commit_rxon(priv);
2651 } 2641 }
2652 if (priv->vif == conf->vif) { 2642 if (priv->vif == vif) {
2653 priv->vif = NULL; 2643 priv->vif = NULL;
2654 memset(priv->bssid, 0, ETH_ALEN); 2644 memset(priv->bssid, 0, ETH_ALEN);
2655 } 2645 }
@@ -2689,6 +2679,21 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2689 IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); 2679 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
2690 } 2680 }
2691 2681
2682 if (changed & (IEEE80211_CONF_CHANGE_SMPS |
2683 IEEE80211_CONF_CHANGE_CHANNEL)) {
2684 /* mac80211 uses static for non-HT which is what we want */
2685 priv->current_ht_config.smps = conf->smps_mode;
2686
2687 /*
2688 * Recalculate chain counts.
2689 *
2690 * If monitor mode is enabled then mac80211 will
2691 * set up the SM PS mode to OFF if an HT channel is
2692 * configured.
2693 */
2694 if (priv->cfg->ops->hcmd->set_rxon_chain)
2695 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2696 }
2692 2697
2693 /* during scanning mac80211 will delay channel setting until 2698 /* during scanning mac80211 will delay channel setting until
2694 * scan finish with changed = 0 2699 * scan finish with changed = 0
@@ -2785,10 +2790,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2785 iwl_set_tx_power(priv, conf->power_level, false); 2790 iwl_set_tx_power(priv, conf->power_level, false);
2786 } 2791 }
2787 2792
2788 /* call to ensure that 4965 rx_chain is set properly in monitor mode */
2789 if (priv->cfg->ops->hcmd->set_rxon_chain)
2790 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2791
2792 if (!iwl_is_ready(priv)) { 2793 if (!iwl_is_ready(priv)) {
2793 IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); 2794 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2794 goto out; 2795 goto out;
@@ -3196,6 +3197,77 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
3196EXPORT_SYMBOL(iwl_update_stats); 3197EXPORT_SYMBOL(iwl_update_stats);
3197#endif 3198#endif
3198 3199
3200const static char *get_csr_string(int cmd)
3201{
3202 switch (cmd) {
3203 IWL_CMD(CSR_HW_IF_CONFIG_REG);
3204 IWL_CMD(CSR_INT_COALESCING);
3205 IWL_CMD(CSR_INT);
3206 IWL_CMD(CSR_INT_MASK);
3207 IWL_CMD(CSR_FH_INT_STATUS);
3208 IWL_CMD(CSR_GPIO_IN);
3209 IWL_CMD(CSR_RESET);
3210 IWL_CMD(CSR_GP_CNTRL);
3211 IWL_CMD(CSR_HW_REV);
3212 IWL_CMD(CSR_EEPROM_REG);
3213 IWL_CMD(CSR_EEPROM_GP);
3214 IWL_CMD(CSR_OTP_GP_REG);
3215 IWL_CMD(CSR_GIO_REG);
3216 IWL_CMD(CSR_GP_UCODE_REG);
3217 IWL_CMD(CSR_GP_DRIVER_REG);
3218 IWL_CMD(CSR_UCODE_DRV_GP1);
3219 IWL_CMD(CSR_UCODE_DRV_GP2);
3220 IWL_CMD(CSR_LED_REG);
3221 IWL_CMD(CSR_DRAM_INT_TBL_REG);
3222 IWL_CMD(CSR_GIO_CHICKEN_BITS);
3223 IWL_CMD(CSR_ANA_PLL_CFG);
3224 IWL_CMD(CSR_HW_REV_WA_REG);
3225 IWL_CMD(CSR_DBG_HPET_MEM_REG);
3226 default:
3227 return "UNKNOWN";
3228
3229 }
3230}
3231
3232void iwl_dump_csr(struct iwl_priv *priv)
3233{
3234 int i;
3235 u32 csr_tbl[] = {
3236 CSR_HW_IF_CONFIG_REG,
3237 CSR_INT_COALESCING,
3238 CSR_INT,
3239 CSR_INT_MASK,
3240 CSR_FH_INT_STATUS,
3241 CSR_GPIO_IN,
3242 CSR_RESET,
3243 CSR_GP_CNTRL,
3244 CSR_HW_REV,
3245 CSR_EEPROM_REG,
3246 CSR_EEPROM_GP,
3247 CSR_OTP_GP_REG,
3248 CSR_GIO_REG,
3249 CSR_GP_UCODE_REG,
3250 CSR_GP_DRIVER_REG,
3251 CSR_UCODE_DRV_GP1,
3252 CSR_UCODE_DRV_GP2,
3253 CSR_LED_REG,
3254 CSR_DRAM_INT_TBL_REG,
3255 CSR_GIO_CHICKEN_BITS,
3256 CSR_ANA_PLL_CFG,
3257 CSR_HW_REV_WA_REG,
3258 CSR_DBG_HPET_MEM_REG
3259 };
3260 IWL_ERR(priv, "CSR values:\n");
3261 IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
3262 "CSR_INT_PERIODIC_REG)\n");
3263 for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) {
3264 IWL_ERR(priv, " %25s: 0X%08x\n",
3265 get_csr_string(csr_tbl[i]),
3266 iwl_read32(priv, csr_tbl[i]));
3267 }
3268}
3269EXPORT_SYMBOL(iwl_dump_csr);
3270
3199#ifdef CONFIG_PM 3271#ifdef CONFIG_PM
3200 3272
3201int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) 3273int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 675b7df632fc..8deb83bfe182 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -63,8 +63,6 @@
63#ifndef __iwl_core_h__ 63#ifndef __iwl_core_h__
64#define __iwl_core_h__ 64#define __iwl_core_h__
65 65
66#include <linux/utsrelease.h>
67
68/************************ 66/************************
69 * forward declarations * 67 * forward declarations *
70 ************************/ 68 ************************/
@@ -72,7 +70,7 @@ struct iwl_host_cmd;
72struct iwl_cmd; 70struct iwl_cmd;
73 71
74 72
75#define IWLWIFI_VERSION UTS_RELEASE "-k" 73#define IWLWIFI_VERSION "in-tree:"
76#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation" 74#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
77#define DRV_AUTHOR "<ilw@linux.intel.com>" 75#define DRV_AUTHOR "<ilw@linux.intel.com>"
78 76
@@ -169,8 +167,10 @@ struct iwl_lib_ops {
169 int (*is_valid_rtc_data_addr)(u32 addr); 167 int (*is_valid_rtc_data_addr)(u32 addr);
170 /* 1st ucode load */ 168 /* 1st ucode load */
171 int (*load_ucode)(struct iwl_priv *priv); 169 int (*load_ucode)(struct iwl_priv *priv);
172 void (*dump_nic_event_log)(struct iwl_priv *priv, bool full_log); 170 int (*dump_nic_event_log)(struct iwl_priv *priv,
171 bool full_log, char **buf, bool display);
173 void (*dump_nic_error_log)(struct iwl_priv *priv); 172 void (*dump_nic_error_log)(struct iwl_priv *priv);
173 void (*dump_csr)(struct iwl_priv *priv);
174 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); 174 int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
175 /* power management */ 175 /* power management */
176 struct iwl_apm_ops apm_ops; 176 struct iwl_apm_ops apm_ops;
@@ -230,7 +230,6 @@ struct iwl_mod_params {
230 * @chain_noise_num_beacons: number of beacons used to compute chain noise 230 * @chain_noise_num_beacons: number of beacons used to compute chain noise
231 * @adv_thermal_throttle: support advance thermal throttle 231 * @adv_thermal_throttle: support advance thermal throttle
232 * @support_ct_kill_exit: support ct kill exit condition 232 * @support_ct_kill_exit: support ct kill exit condition
233 * @sm_ps_mode: spatial multiplexing power save mode
234 * @support_wimax_coexist: support wimax/wifi co-exist 233 * @support_wimax_coexist: support wimax/wifi co-exist
235 * 234 *
236 * We enable the driver to be backward compatible wrt API version. The 235 * We enable the driver to be backward compatible wrt API version. The
@@ -287,7 +286,6 @@ struct iwl_cfg {
287 const bool supports_idle; 286 const bool supports_idle;
288 bool adv_thermal_throttle; 287 bool adv_thermal_throttle;
289 bool support_ct_kill_exit; 288 bool support_ct_kill_exit;
290 u8 sm_ps_mode;
291 const bool support_wimax_coexist; 289 const bool support_wimax_coexist;
292}; 290};
293 291
@@ -332,9 +330,9 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
332int iwl_commit_rxon(struct iwl_priv *priv); 330int iwl_commit_rxon(struct iwl_priv *priv);
333int iwl_set_mode(struct iwl_priv *priv, int mode); 331int iwl_set_mode(struct iwl_priv *priv, int mode);
334int iwl_mac_add_interface(struct ieee80211_hw *hw, 332int iwl_mac_add_interface(struct ieee80211_hw *hw,
335 struct ieee80211_if_init_conf *conf); 333 struct ieee80211_vif *vif);
336void iwl_mac_remove_interface(struct ieee80211_hw *hw, 334void iwl_mac_remove_interface(struct ieee80211_hw *hw,
337 struct ieee80211_if_init_conf *conf); 335 struct ieee80211_vif *vif);
338int iwl_mac_config(struct ieee80211_hw *hw, u32 changed); 336int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
339void iwl_config_ap(struct iwl_priv *priv); 337void iwl_config_ap(struct iwl_priv *priv);
340int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, 338int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
@@ -581,7 +579,9 @@ int iwl_pci_resume(struct pci_dev *pdev);
581* Error Handling Debugging 579* Error Handling Debugging
582******************************************************/ 580******************************************************/
583void iwl_dump_nic_error_log(struct iwl_priv *priv); 581void iwl_dump_nic_error_log(struct iwl_priv *priv);
584void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log); 582int iwl_dump_nic_event_log(struct iwl_priv *priv,
583 bool full_log, char **buf, bool display);
584void iwl_dump_csr(struct iwl_priv *priv);
585#ifdef CONFIG_IWLWIFI_DEBUG 585#ifdef CONFIG_IWLWIFI_DEBUG
586void iwl_print_rx_config_cmd(struct iwl_priv *priv); 586void iwl_print_rx_config_cmd(struct iwl_priv *priv);
587#else 587#else
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index d61293ab67c9..58e0462cafa3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -109,6 +109,8 @@ struct iwl_debugfs {
109 struct dentry *file_power_save_status; 109 struct dentry *file_power_save_status;
110 struct dentry *file_clear_ucode_statistics; 110 struct dentry *file_clear_ucode_statistics;
111 struct dentry *file_clear_traffic_statistics; 111 struct dentry *file_clear_traffic_statistics;
112 struct dentry *file_csr;
113 struct dentry *file_ucode_tracing;
112 } dbgfs_debug_files; 114 } dbgfs_debug_files;
113 u32 sram_offset; 115 u32 sram_offset;
114 u32 sram_len; 116 u32 sram_len;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 21e0f6699daf..4a2ac9311ba8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -125,7 +125,7 @@ static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
125 char __user *user_buf, 125 char __user *user_buf,
126 size_t count, loff_t *ppos) { 126 size_t count, loff_t *ppos) {
127 127
128 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 128 struct iwl_priv *priv = file->private_data;
129 char *buf; 129 char *buf;
130 int pos = 0; 130 int pos = 0;
131 131
@@ -184,7 +184,7 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
184 char __user *user_buf, 184 char __user *user_buf,
185 size_t count, loff_t *ppos) { 185 size_t count, loff_t *ppos) {
186 186
187 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 187 struct iwl_priv *priv = file->private_data;
188 char *buf; 188 char *buf;
189 int pos = 0; 189 int pos = 0;
190 int cnt; 190 int cnt;
@@ -232,7 +232,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
232 ssize_t ret; 232 ssize_t ret;
233 int i; 233 int i;
234 int pos = 0; 234 int pos = 0;
235 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 235 struct iwl_priv *priv = file->private_data;
236 size_t bufsz; 236 size_t bufsz;
237 237
238 /* default is to dump the entire data segment */ 238 /* default is to dump the entire data segment */
@@ -306,7 +306,7 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file,
306static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 306static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
307 size_t count, loff_t *ppos) 307 size_t count, loff_t *ppos)
308{ 308{
309 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 309 struct iwl_priv *priv = file->private_data;
310 struct iwl_station_entry *station; 310 struct iwl_station_entry *station;
311 int max_sta = priv->hw_params.max_stations; 311 int max_sta = priv->hw_params.max_stations;
312 char *buf; 312 char *buf;
@@ -376,7 +376,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
376 loff_t *ppos) 376 loff_t *ppos)
377{ 377{
378 ssize_t ret; 378 ssize_t ret;
379 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 379 struct iwl_priv *priv = file->private_data;
380 int pos = 0, ofs = 0, buf_size = 0; 380 int pos = 0, ofs = 0, buf_size = 0;
381 const u8 *ptr; 381 const u8 *ptr;
382 char *buf; 382 char *buf;
@@ -420,6 +420,23 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
420 return ret; 420 return ret;
421} 421}
422 422
423static ssize_t iwl_dbgfs_log_event_read(struct file *file,
424 char __user *user_buf,
425 size_t count, loff_t *ppos)
426{
427 struct iwl_priv *priv = file->private_data;
428 char *buf;
429 int pos = 0;
430 ssize_t ret = -ENOMEM;
431
432 pos = priv->cfg->ops->lib->dump_nic_event_log(priv, true, &buf, true);
433 if (pos && buf) {
434 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
435 kfree(buf);
436 }
437 return ret;
438}
439
423static ssize_t iwl_dbgfs_log_event_write(struct file *file, 440static ssize_t iwl_dbgfs_log_event_write(struct file *file,
424 const char __user *user_buf, 441 const char __user *user_buf,
425 size_t count, loff_t *ppos) 442 size_t count, loff_t *ppos)
@@ -436,7 +453,8 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
436 if (sscanf(buf, "%d", &event_log_flag) != 1) 453 if (sscanf(buf, "%d", &event_log_flag) != 1)
437 return -EFAULT; 454 return -EFAULT;
438 if (event_log_flag == 1) 455 if (event_log_flag == 1)
439 priv->cfg->ops->lib->dump_nic_event_log(priv, true); 456 priv->cfg->ops->lib->dump_nic_event_log(priv, true,
457 NULL, false);
440 458
441 return count; 459 return count;
442} 460}
@@ -446,7 +464,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
446static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, 464static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
447 size_t count, loff_t *ppos) 465 size_t count, loff_t *ppos)
448{ 466{
449 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 467 struct iwl_priv *priv = file->private_data;
450 struct ieee80211_channel *channels = NULL; 468 struct ieee80211_channel *channels = NULL;
451 const struct ieee80211_supported_band *supp_band = NULL; 469 const struct ieee80211_supported_band *supp_band = NULL;
452 int pos = 0, i, bufsz = PAGE_SIZE; 470 int pos = 0, i, bufsz = PAGE_SIZE;
@@ -519,7 +537,7 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
519 char __user *user_buf, 537 char __user *user_buf,
520 size_t count, loff_t *ppos) { 538 size_t count, loff_t *ppos) {
521 539
522 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 540 struct iwl_priv *priv = file->private_data;
523 char buf[512]; 541 char buf[512];
524 int pos = 0; 542 int pos = 0;
525 const size_t bufsz = sizeof(buf); 543 const size_t bufsz = sizeof(buf);
@@ -567,7 +585,7 @@ static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
567 char __user *user_buf, 585 char __user *user_buf,
568 size_t count, loff_t *ppos) { 586 size_t count, loff_t *ppos) {
569 587
570 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 588 struct iwl_priv *priv = file->private_data;
571 int pos = 0; 589 int pos = 0;
572 int cnt = 0; 590 int cnt = 0;
573 char *buf; 591 char *buf;
@@ -654,7 +672,7 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
654static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, 672static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
655 size_t count, loff_t *ppos) 673 size_t count, loff_t *ppos)
656{ 674{
657 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 675 struct iwl_priv *priv = file->private_data;
658 int pos = 0, i; 676 int pos = 0, i;
659 char buf[256]; 677 char buf[256];
660 const size_t bufsz = sizeof(buf); 678 const size_t bufsz = sizeof(buf);
@@ -677,7 +695,7 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
677static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, 695static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
678 size_t count, loff_t *ppos) 696 size_t count, loff_t *ppos)
679{ 697{
680 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 698 struct iwl_priv *priv = file->private_data;
681 int pos = 0; 699 int pos = 0;
682 char buf[256]; 700 char buf[256];
683 const size_t bufsz = sizeof(buf); 701 const size_t bufsz = sizeof(buf);
@@ -703,7 +721,7 @@ static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
703 char __user *user_buf, 721 char __user *user_buf,
704 size_t count, loff_t *ppos) 722 size_t count, loff_t *ppos)
705{ 723{
706 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 724 struct iwl_priv *priv = file->private_data;
707 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 725 struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
708 struct iwl_tt_restriction *restriction; 726 struct iwl_tt_restriction *restriction;
709 char buf[100]; 727 char buf[100];
@@ -763,7 +781,7 @@ static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
763 char __user *user_buf, 781 char __user *user_buf,
764 size_t count, loff_t *ppos) 782 size_t count, loff_t *ppos)
765{ 783{
766 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 784 struct iwl_priv *priv = file->private_data;
767 char buf[100]; 785 char buf[100];
768 int pos = 0; 786 int pos = 0;
769 const size_t bufsz = sizeof(buf); 787 const size_t bufsz = sizeof(buf);
@@ -820,7 +838,7 @@ static ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
820 char __user *user_buf, 838 char __user *user_buf,
821 size_t count, loff_t *ppos) 839 size_t count, loff_t *ppos)
822{ 840{
823 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 841 struct iwl_priv *priv = file->private_data;
824 char buf[10]; 842 char buf[10];
825 int pos, value; 843 int pos, value;
826 const size_t bufsz = sizeof(buf); 844 const size_t bufsz = sizeof(buf);
@@ -838,7 +856,7 @@ static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
838 char __user *user_buf, 856 char __user *user_buf,
839 size_t count, loff_t *ppos) 857 size_t count, loff_t *ppos)
840{ 858{
841 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 859 struct iwl_priv *priv = file->private_data;
842 char buf[200]; 860 char buf[200];
843 int pos = 0, i; 861 int pos = 0, i;
844 const size_t bufsz = sizeof(buf); 862 const size_t bufsz = sizeof(buf);
@@ -859,7 +877,7 @@ static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
859} 877}
860 878
861DEBUGFS_READ_WRITE_FILE_OPS(sram); 879DEBUGFS_READ_WRITE_FILE_OPS(sram);
862DEBUGFS_WRITE_FILE_OPS(log_event); 880DEBUGFS_READ_WRITE_FILE_OPS(log_event);
863DEBUGFS_READ_FILE_OPS(nvm); 881DEBUGFS_READ_FILE_OPS(nvm);
864DEBUGFS_READ_FILE_OPS(stations); 882DEBUGFS_READ_FILE_OPS(stations);
865DEBUGFS_READ_FILE_OPS(channels); 883DEBUGFS_READ_FILE_OPS(channels);
@@ -976,7 +994,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
976 char __user *user_buf, 994 char __user *user_buf,
977 size_t count, loff_t *ppos) { 995 size_t count, loff_t *ppos) {
978 996
979 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 997 struct iwl_priv *priv = file->private_data;
980 struct iwl_tx_queue *txq; 998 struct iwl_tx_queue *txq;
981 struct iwl_queue *q; 999 struct iwl_queue *q;
982 char *buf; 1000 char *buf;
@@ -1022,7 +1040,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1022 char __user *user_buf, 1040 char __user *user_buf,
1023 size_t count, loff_t *ppos) { 1041 size_t count, loff_t *ppos) {
1024 1042
1025 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1043 struct iwl_priv *priv = file->private_data;
1026 struct iwl_rx_queue *rxq = &priv->rxq; 1044 struct iwl_rx_queue *rxq = &priv->rxq;
1027 char buf[256]; 1045 char buf[256];
1028 int pos = 0; 1046 int pos = 0;
@@ -1068,7 +1086,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1068 char __user *user_buf, 1086 char __user *user_buf,
1069 size_t count, loff_t *ppos) 1087 size_t count, loff_t *ppos)
1070{ 1088{
1071 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1089 struct iwl_priv *priv = file->private_data;
1072 int pos = 0; 1090 int pos = 0;
1073 char *buf; 1091 char *buf;
1074 int bufsz = sizeof(struct statistics_rx_phy) * 20 + 1092 int bufsz = sizeof(struct statistics_rx_phy) * 20 +
@@ -1369,6 +1387,9 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1369 accum_ht->agg_mpdu_cnt); 1387 accum_ht->agg_mpdu_cnt);
1370 pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n", 1388 pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n",
1371 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt); 1389 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt);
1390 pos += scnprintf(buf + pos, bufsz - pos, "unsupport_mcs:\t\t%u\t\t\t%u\n",
1391 le32_to_cpu(ht->unsupport_mcs),
1392 accum_ht->unsupport_mcs);
1372 1393
1373 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1394 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1374 kfree(buf); 1395 kfree(buf);
@@ -1379,7 +1400,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1379 char __user *user_buf, 1400 char __user *user_buf,
1380 size_t count, loff_t *ppos) 1401 size_t count, loff_t *ppos)
1381{ 1402{
1382 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1403 struct iwl_priv *priv = file->private_data;
1383 int pos = 0; 1404 int pos = 0;
1384 char *buf; 1405 char *buf;
1385 int bufsz = (sizeof(struct statistics_tx) * 24) + 250; 1406 int bufsz = (sizeof(struct statistics_tx) * 24) + 250;
@@ -1521,7 +1542,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1521 char __user *user_buf, 1542 char __user *user_buf,
1522 size_t count, loff_t *ppos) 1543 size_t count, loff_t *ppos)
1523{ 1544{
1524 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1545 struct iwl_priv *priv = file->private_data;
1525 int pos = 0; 1546 int pos = 0;
1526 char *buf; 1547 char *buf;
1527 int bufsz = sizeof(struct statistics_general) * 4 + 250; 1548 int bufsz = sizeof(struct statistics_general) * 4 + 250;
@@ -1612,7 +1633,7 @@ static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
1612 char __user *user_buf, 1633 char __user *user_buf,
1613 size_t count, loff_t *ppos) { 1634 size_t count, loff_t *ppos) {
1614 1635
1615 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1636 struct iwl_priv *priv = file->private_data;
1616 int pos = 0; 1637 int pos = 0;
1617 int cnt = 0; 1638 int cnt = 0;
1618 char *buf; 1639 char *buf;
@@ -1693,7 +1714,7 @@ static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
1693 char __user *user_buf, 1714 char __user *user_buf,
1694 size_t count, loff_t *ppos) { 1715 size_t count, loff_t *ppos) {
1695 1716
1696 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1717 struct iwl_priv *priv = file->private_data;
1697 int pos = 0; 1718 int pos = 0;
1698 int cnt = 0; 1719 int cnt = 0;
1699 char *buf; 1720 char *buf;
@@ -1751,7 +1772,7 @@ static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
1751 char __user *user_buf, 1772 char __user *user_buf,
1752 size_t count, loff_t *ppos) { 1773 size_t count, loff_t *ppos) {
1753 1774
1754 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1775 struct iwl_priv *priv = file->private_data;
1755 char buf[128]; 1776 char buf[128];
1756 int pos = 0; 1777 int pos = 0;
1757 ssize_t ret; 1778 ssize_t ret;
@@ -1802,7 +1823,7 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
1802 char __user *user_buf, 1823 char __user *user_buf,
1803 size_t count, loff_t *ppos) 1824 size_t count, loff_t *ppos)
1804{ 1825{
1805 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1826 struct iwl_priv *priv = file->private_data;
1806 char buf[60]; 1827 char buf[60];
1807 int pos = 0; 1828 int pos = 0;
1808 const size_t bufsz = sizeof(buf); 1829 const size_t bufsz = sizeof(buf);
@@ -1845,6 +1866,80 @@ static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file,
1845 return count; 1866 return count;
1846} 1867}
1847 1868
1869static ssize_t iwl_dbgfs_csr_write(struct file *file,
1870 const char __user *user_buf,
1871 size_t count, loff_t *ppos)
1872{
1873 struct iwl_priv *priv = file->private_data;
1874 char buf[8];
1875 int buf_size;
1876 int csr;
1877
1878 memset(buf, 0, sizeof(buf));
1879 buf_size = min(count, sizeof(buf) - 1);
1880 if (copy_from_user(buf, user_buf, buf_size))
1881 return -EFAULT;
1882 if (sscanf(buf, "%d", &csr) != 1)
1883 return -EFAULT;
1884
1885 if (priv->cfg->ops->lib->dump_csr)
1886 priv->cfg->ops->lib->dump_csr(priv);
1887
1888 return count;
1889}
1890
1891static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file,
1892 char __user *user_buf,
1893 size_t count, loff_t *ppos) {
1894
1895 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
1896 int pos = 0;
1897 char buf[128];
1898 const size_t bufsz = sizeof(buf);
1899 ssize_t ret;
1900
1901 pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n",
1902 priv->event_log.ucode_trace ? "On" : "Off");
1903 pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n",
1904 priv->event_log.non_wraps_count);
1905 pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n",
1906 priv->event_log.wraps_once_count);
1907 pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n",
1908 priv->event_log.wraps_more_count);
1909
1910 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1911 return ret;
1912}
1913
1914static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file,
1915 const char __user *user_buf,
1916 size_t count, loff_t *ppos)
1917{
1918 struct iwl_priv *priv = file->private_data;
1919 char buf[8];
1920 int buf_size;
1921 int trace;
1922
1923 memset(buf, 0, sizeof(buf));
1924 buf_size = min(count, sizeof(buf) - 1);
1925 if (copy_from_user(buf, user_buf, buf_size))
1926 return -EFAULT;
1927 if (sscanf(buf, "%d", &trace) != 1)
1928 return -EFAULT;
1929
1930 if (trace) {
1931 priv->event_log.ucode_trace = true;
1932 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */
1933 mod_timer(&priv->ucode_trace,
1934 jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD));
1935 } else {
1936 priv->event_log.ucode_trace = false;
1937 del_timer_sync(&priv->ucode_trace);
1938 }
1939
1940 return count;
1941}
1942
1848DEBUGFS_READ_FILE_OPS(rx_statistics); 1943DEBUGFS_READ_FILE_OPS(rx_statistics);
1849DEBUGFS_READ_FILE_OPS(tx_statistics); 1944DEBUGFS_READ_FILE_OPS(tx_statistics);
1850DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 1945DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1859,6 +1954,8 @@ DEBUGFS_READ_FILE_OPS(tx_power);
1859DEBUGFS_READ_FILE_OPS(power_save_status); 1954DEBUGFS_READ_FILE_OPS(power_save_status);
1860DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); 1955DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
1861DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); 1956DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
1957DEBUGFS_WRITE_FILE_OPS(csr);
1958DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
1862 1959
1863/* 1960/*
1864 * Create the debugfs files and directories 1961 * Create the debugfs files and directories
@@ -1889,7 +1986,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1889 DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv); 1986 DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv);
1890 DEBUGFS_ADD_FILE(nvm, data, S_IRUSR); 1987 DEBUGFS_ADD_FILE(nvm, data, S_IRUSR);
1891 DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR); 1988 DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR);
1892 DEBUGFS_ADD_FILE(log_event, data, S_IWUSR); 1989 DEBUGFS_ADD_FILE(log_event, data, S_IWUSR | S_IRUSR);
1893 DEBUGFS_ADD_FILE(stations, data, S_IRUSR); 1990 DEBUGFS_ADD_FILE(stations, data, S_IRUSR);
1894 DEBUGFS_ADD_FILE(channels, data, S_IRUSR); 1991 DEBUGFS_ADD_FILE(channels, data, S_IRUSR);
1895 DEBUGFS_ADD_FILE(status, data, S_IRUSR); 1992 DEBUGFS_ADD_FILE(status, data, S_IRUSR);
@@ -1909,12 +2006,14 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
1909 DEBUGFS_ADD_FILE(power_save_status, debug, S_IRUSR); 2006 DEBUGFS_ADD_FILE(power_save_status, debug, S_IRUSR);
1910 DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR); 2007 DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR);
1911 DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR); 2008 DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR);
2009 DEBUGFS_ADD_FILE(csr, debug, S_IWUSR);
1912 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 2010 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1913 DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); 2011 DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR);
1914 DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); 2012 DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR);
1915 DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR); 2013 DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR);
1916 DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR); 2014 DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR);
1917 DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR); 2015 DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR);
2016 DEBUGFS_ADD_FILE(ucode_tracing, debug, S_IWUSR | S_IRUSR);
1918 } 2017 }
1919 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 2018 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
1920 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 2019 DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
@@ -1966,6 +2065,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
1966 file_clear_ucode_statistics); 2065 file_clear_ucode_statistics);
1967 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 2066 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1968 file_clear_traffic_statistics); 2067 file_clear_traffic_statistics);
2068 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_csr);
1969 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 2069 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
1970 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 2070 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1971 file_ucode_rx_stats); 2071 file_ucode_rx_stats);
@@ -1977,6 +2077,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
1977 file_sensitivity); 2077 file_sensitivity);
1978 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 2078 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
1979 file_chain_noise); 2079 file_chain_noise);
2080 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.
2081 file_ucode_tracing);
1980 } 2082 }
1981 DEBUGFS_REMOVE(priv->dbgfs->dir_debug); 2083 DEBUGFS_REMOVE(priv->dbgfs->dir_debug);
1982 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); 2084 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 3822cf53e368..70f0e79c8e4a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -512,6 +512,7 @@ struct iwl_ht_config {
512 bool is_ht; 512 bool is_ht;
513 bool is_40mhz; 513 bool is_40mhz;
514 bool single_chain_sufficient; 514 bool single_chain_sufficient;
515 enum ieee80211_smps_mode smps; /* current smps mode */
515 /* BSS related data */ 516 /* BSS related data */
516 u8 extension_chan_offset; 517 u8 extension_chan_offset;
517 u8 ht_protection; 518 u8 ht_protection;
@@ -984,6 +985,32 @@ struct iwl_switch_rxon {
984 __le16 channel; 985 __le16 channel;
985}; 986};
986 987
988/*
989 * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
990 * to perform continuous uCode event logging operation if enabled
991 */
992#define UCODE_TRACE_PERIOD (100)
993
994/*
995 * iwl_event_log: current uCode event log position
996 *
997 * @ucode_trace: enable/disable ucode continuous trace timer
998 * @num_wraps: how many times the event buffer wraps
999 * @next_entry: the entry just before the next one that uCode would fill
1000 * @non_wraps_count: counter for no wrap detected when dump ucode events
1001 * @wraps_once_count: counter for wrap once detected when dump ucode events
1002 * @wraps_more_count: counter for wrap more than once detected
1003 * when dump ucode events
1004 */
1005struct iwl_event_log {
1006 bool ucode_trace;
1007 u32 num_wraps;
1008 u32 next_entry;
1009 int non_wraps_count;
1010 int wraps_once_count;
1011 int wraps_more_count;
1012};
1013
987struct iwl_priv { 1014struct iwl_priv {
988 1015
989 /* ieee device used by generic ieee processing code */ 1016 /* ieee device used by generic ieee processing code */
@@ -1261,6 +1288,7 @@ struct iwl_priv {
1261 u32 disable_tx_power_cal; 1288 u32 disable_tx_power_cal;
1262 struct work_struct run_time_calib_work; 1289 struct work_struct run_time_calib_work;
1263 struct timer_list statistics_periodic; 1290 struct timer_list statistics_periodic;
1291 struct timer_list ucode_trace;
1264 bool hw_ready; 1292 bool hw_ready;
1265 /*For 3945*/ 1293 /*For 3945*/
1266#define IWL_DEFAULT_TX_POWER 0x0F 1294#define IWL_DEFAULT_TX_POWER 0x0F
@@ -1268,6 +1296,8 @@ struct iwl_priv {
1268 struct iwl3945_notif_statistics statistics_39; 1296 struct iwl3945_notif_statistics statistics_39;
1269 1297
1270 u32 sta_supp_rates; 1298 u32 sta_supp_rates;
1299
1300 struct iwl_event_log event_log;
1271}; /*iwl_priv */ 1301}; /*iwl_priv */
1272 1302
1273static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) 1303static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
index 83cc4e500a96..36580d8d8b8d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c
@@ -37,4 +37,6 @@ EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32);
37EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx); 37EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx);
38EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event); 38EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event);
39EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error); 39EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error);
40EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event);
41EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event);
40#endif 42#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index d9c7363b1bbb..ff4d012ce260 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -91,6 +91,50 @@ TRACE_EVENT(iwlwifi_dev_iowrite32,
91); 91);
92 92
93#undef TRACE_SYSTEM 93#undef TRACE_SYSTEM
94#define TRACE_SYSTEM iwlwifi_ucode
95
96TRACE_EVENT(iwlwifi_dev_ucode_cont_event,
97 TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev),
98 TP_ARGS(priv, time, data, ev),
99 TP_STRUCT__entry(
100 PRIV_ENTRY
101
102 __field(u32, time)
103 __field(u32, data)
104 __field(u32, ev)
105 ),
106 TP_fast_assign(
107 PRIV_ASSIGN;
108 __entry->time = time;
109 __entry->data = data;
110 __entry->ev = ev;
111 ),
112 TP_printk("[%p] EVT_LOGT:%010u:0x%08x:%04u",
113 __entry->priv, __entry->time, __entry->data, __entry->ev)
114);
115
116TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
117 TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry),
118 TP_ARGS(priv, wraps, n_entry, p_entry),
119 TP_STRUCT__entry(
120 PRIV_ENTRY
121
122 __field(u32, wraps)
123 __field(u32, n_entry)
124 __field(u32, p_entry)
125 ),
126 TP_fast_assign(
127 PRIV_ASSIGN;
128 __entry->wraps = wraps;
129 __entry->n_entry = n_entry;
130 __entry->p_entry = p_entry;
131 ),
132 TP_printk("[%p] wraps=#%02d n=0x%X p=0x%X",
133 __entry->priv, __entry->wraps, __entry->n_entry,
134 __entry->p_entry)
135);
136
137#undef TRACE_SYSTEM
94#define TRACE_SYSTEM iwlwifi 138#define TRACE_SYSTEM iwlwifi
95 139
96TRACE_EVENT(iwlwifi_dev_hcmd, 140TRACE_EVENT(iwlwifi_dev_hcmd,
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 30e9ea6d54ec..87d684efe110 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -58,7 +58,6 @@ const char *get_cmd_string(u8 cmd)
58 IWL_CMD(COEX_PRIORITY_TABLE_CMD); 58 IWL_CMD(COEX_PRIORITY_TABLE_CMD);
59 IWL_CMD(COEX_MEDIUM_NOTIFICATION); 59 IWL_CMD(COEX_MEDIUM_NOTIFICATION);
60 IWL_CMD(COEX_EVENT_CMD); 60 IWL_CMD(COEX_EVENT_CMD);
61 IWL_CMD(RADAR_NOTIFICATION);
62 IWL_CMD(REPLY_QUIET_CMD); 61 IWL_CMD(REPLY_QUIET_CMD);
63 IWL_CMD(REPLY_CHANNEL_SWITCH); 62 IWL_CMD(REPLY_CHANNEL_SWITCH);
64 IWL_CMD(CHANNEL_SWITCH_NOTIFICATION); 63 IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index f8e4e4b18d02..10b0aa8024c4 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1518,8 +1518,9 @@ void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
1518 * iwl3945_print_event_log - Dump error event log to syslog 1518 * iwl3945_print_event_log - Dump error event log to syslog
1519 * 1519 *
1520 */ 1520 */
1521static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx, 1521static int iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1522 u32 num_events, u32 mode) 1522 u32 num_events, u32 mode,
1523 int pos, char **buf, size_t bufsz)
1523{ 1524{
1524 u32 i; 1525 u32 i;
1525 u32 base; /* SRAM byte address of event log header */ 1526 u32 base; /* SRAM byte address of event log header */
@@ -1529,7 +1530,7 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1529 unsigned long reg_flags; 1530 unsigned long reg_flags;
1530 1531
1531 if (num_events == 0) 1532 if (num_events == 0)
1532 return; 1533 return pos;
1533 1534
1534 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1535 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1535 1536
@@ -1555,26 +1556,43 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
1555 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1556 time = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1556 if (mode == 0) { 1557 if (mode == 0) {
1557 /* data, ev */ 1558 /* data, ev */
1558 IWL_ERR(priv, "0x%08x\t%04u\n", time, ev); 1559 if (bufsz) {
1559 trace_iwlwifi_dev_ucode_event(priv, 0, time, ev); 1560 pos += scnprintf(*buf + pos, bufsz - pos,
1561 "0x%08x:%04u\n",
1562 time, ev);
1563 } else {
1564 IWL_ERR(priv, "0x%08x\t%04u\n", time, ev);
1565 trace_iwlwifi_dev_ucode_event(priv, 0,
1566 time, ev);
1567 }
1560 } else { 1568 } else {
1561 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT); 1569 data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
1562 IWL_ERR(priv, "%010u\t0x%08x\t%04u\n", time, data, ev); 1570 if (bufsz) {
1563 trace_iwlwifi_dev_ucode_event(priv, time, data, ev); 1571 pos += scnprintf(*buf + pos, bufsz - pos,
1572 "%010u:0x%08x:%04u\n",
1573 time, data, ev);
1574 } else {
1575 IWL_ERR(priv, "%010u\t0x%08x\t%04u\n",
1576 time, data, ev);
1577 trace_iwlwifi_dev_ucode_event(priv, time,
1578 data, ev);
1579 }
1564 } 1580 }
1565 } 1581 }
1566 1582
1567 /* Allow device to power down */ 1583 /* Allow device to power down */
1568 iwl_release_nic_access(priv); 1584 iwl_release_nic_access(priv);
1569 spin_unlock_irqrestore(&priv->reg_lock, reg_flags); 1585 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
1586 return pos;
1570} 1587}
1571 1588
1572/** 1589/**
1573 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog 1590 * iwl3945_print_last_event_logs - Dump the newest # of event log to syslog
1574 */ 1591 */
1575static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity, 1592static int iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1576 u32 num_wraps, u32 next_entry, 1593 u32 num_wraps, u32 next_entry,
1577 u32 size, u32 mode) 1594 u32 size, u32 mode,
1595 int pos, char **buf, size_t bufsz)
1578{ 1596{
1579 /* 1597 /*
1580 * display the newest DEFAULT_LOG_ENTRIES entries 1598 * display the newest DEFAULT_LOG_ENTRIES entries
@@ -1582,21 +1600,28 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1582 */ 1600 */
1583 if (num_wraps) { 1601 if (num_wraps) {
1584 if (next_entry < size) { 1602 if (next_entry < size) {
1585 iwl3945_print_event_log(priv, 1603 pos = iwl3945_print_event_log(priv,
1586 capacity - (size - next_entry), 1604 capacity - (size - next_entry),
1587 size - next_entry, mode); 1605 size - next_entry, mode,
1588 iwl3945_print_event_log(priv, 0, 1606 pos, buf, bufsz);
1589 next_entry, mode); 1607 pos = iwl3945_print_event_log(priv, 0,
1608 next_entry, mode,
1609 pos, buf, bufsz);
1590 } else 1610 } else
1591 iwl3945_print_event_log(priv, next_entry - size, 1611 pos = iwl3945_print_event_log(priv, next_entry - size,
1592 size, mode); 1612 size, mode,
1613 pos, buf, bufsz);
1593 } else { 1614 } else {
1594 if (next_entry < size) 1615 if (next_entry < size)
1595 iwl3945_print_event_log(priv, 0, next_entry, mode); 1616 pos = iwl3945_print_event_log(priv, 0,
1617 next_entry, mode,
1618 pos, buf, bufsz);
1596 else 1619 else
1597 iwl3945_print_event_log(priv, next_entry - size, 1620 pos = iwl3945_print_event_log(priv, next_entry - size,
1598 size, mode); 1621 size, mode,
1622 pos, buf, bufsz);
1599 } 1623 }
1624 return pos;
1600} 1625}
1601 1626
1602/* For sanity check only. Actual size is determined by uCode, typ. 512 */ 1627/* For sanity check only. Actual size is determined by uCode, typ. 512 */
@@ -1604,7 +1629,8 @@ static void iwl3945_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
1604 1629
1605#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20) 1630#define DEFAULT_IWL3945_DUMP_EVENT_LOG_ENTRIES (20)
1606 1631
1607void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log) 1632int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1633 char **buf, bool display)
1608{ 1634{
1609 u32 base; /* SRAM byte address of event log header */ 1635 u32 base; /* SRAM byte address of event log header */
1610 u32 capacity; /* event log capacity in # entries */ 1636 u32 capacity; /* event log capacity in # entries */
@@ -1612,11 +1638,13 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1612 u32 num_wraps; /* # times uCode wrapped to top of log */ 1638 u32 num_wraps; /* # times uCode wrapped to top of log */
1613 u32 next_entry; /* index of next entry to be written by uCode */ 1639 u32 next_entry; /* index of next entry to be written by uCode */
1614 u32 size; /* # entries that we'll print */ 1640 u32 size; /* # entries that we'll print */
1641 int pos = 0;
1642 size_t bufsz = 0;
1615 1643
1616 base = le32_to_cpu(priv->card_alive.log_event_table_ptr); 1644 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1617 if (!iwl3945_hw_valid_rtc_data_addr(base)) { 1645 if (!iwl3945_hw_valid_rtc_data_addr(base)) {
1618 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); 1646 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
1619 return; 1647 return pos;
1620 } 1648 }
1621 1649
1622 /* event log header */ 1650 /* event log header */
@@ -1642,7 +1670,7 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1642 /* bail out if nothing in log */ 1670 /* bail out if nothing in log */
1643 if (size == 0) { 1671 if (size == 0) {
1644 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n"); 1672 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1645 return; 1673 return pos;
1646 } 1674 }
1647 1675
1648#ifdef CONFIG_IWLWIFI_DEBUG 1676#ifdef CONFIG_IWLWIFI_DEBUG
@@ -1658,25 +1686,38 @@ void iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log)
1658 size); 1686 size);
1659 1687
1660#ifdef CONFIG_IWLWIFI_DEBUG 1688#ifdef CONFIG_IWLWIFI_DEBUG
1689 if (display) {
1690 if (full_log)
1691 bufsz = capacity * 48;
1692 else
1693 bufsz = size * 48;
1694 *buf = kmalloc(bufsz, GFP_KERNEL);
1695 if (!*buf)
1696 return pos;
1697 }
1661 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { 1698 if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) {
1662 /* if uCode has wrapped back to top of log, 1699 /* if uCode has wrapped back to top of log,
1663 * start at the oldest entry, 1700 * start at the oldest entry,
1664 * i.e the next one that uCode would fill. 1701 * i.e the next one that uCode would fill.
1665 */ 1702 */
1666 if (num_wraps) 1703 if (num_wraps)
1667 iwl3945_print_event_log(priv, next_entry, 1704 pos = iwl3945_print_event_log(priv, next_entry,
1668 capacity - next_entry, mode); 1705 capacity - next_entry, mode,
1706 pos, buf, bufsz);
1669 1707
1670 /* (then/else) start at top of log */ 1708 /* (then/else) start at top of log */
1671 iwl3945_print_event_log(priv, 0, next_entry, mode); 1709 pos = iwl3945_print_event_log(priv, 0, next_entry, mode,
1710 pos, buf, bufsz);
1672 } else 1711 } else
1673 iwl3945_print_last_event_logs(priv, capacity, num_wraps, 1712 pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1674 next_entry, size, mode); 1713 next_entry, size, mode,
1714 pos, buf, bufsz);
1675#else 1715#else
1676 iwl3945_print_last_event_logs(priv, capacity, num_wraps, 1716 pos = iwl3945_print_last_event_logs(priv, capacity, num_wraps,
1677 next_entry, size, mode); 1717 next_entry, size, mode,
1718 pos, buf, bufsz);
1678#endif 1719#endif
1679 1720 return pos;
1680} 1721}
1681 1722
1682static void iwl3945_irq_tasklet(struct iwl_priv *priv) 1723static void iwl3945_irq_tasklet(struct iwl_priv *priv)