aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-02-03 13:11:48 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-03-01 09:55:12 -0500
commit7e1223b50089ab5901215d2fd8c61b42c7cfe034 (patch)
treedb8a5926ff56da9f6bc51c2d8a955151f845c3d2
parent33cef9256342f200a708211958cec9c44406631d (diff)
iwlwifi: mvm: new Alive / error table API
The new API slightly changes the layout of the version of the firmware - prepare for that. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h26
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c49
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c154
7 files changed, 245 insertions, 32 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index c4d6dd7402d9..234e30f498b2 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -1549,7 +1549,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
1549 table.blink1, table.blink2, table.ilink1, 1549 table.blink1, table.blink2, table.ilink1,
1550 table.ilink2, table.bcon_time, table.gp1, 1550 table.ilink2, table.bcon_time, table.gp1,
1551 table.gp2, table.gp3, table.ucode_ver, 1551 table.gp2, table.gp3, table.ucode_ver,
1552 table.hw_ver, table.brd_ver); 1552 table.hw_ver, 0, table.brd_ver);
1553 IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id, 1553 IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id,
1554 desc_lookup(table.error_id)); 1554 desc_lookup(table.error_id));
1555 IWL_ERR(priv, "0x%08X | uPc\n", table.pc); 1555 IWL_ERR(priv, "0x%08X | uPc\n", table.pc);
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 78bd41bf34b0..53555a0fce56 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -431,11 +431,11 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
431 TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, 431 TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low,
432 u32 data1, u32 data2, u32 line, u32 blink1, 432 u32 data1, u32 data2, u32 line, u32 blink1,
433 u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, 433 u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
434 u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, 434 u32 gp1, u32 gp2, u32 gp3, u32 major, u32 minor, u32 hw_ver,
435 u32 brd_ver), 435 u32 brd_ver),
436 TP_ARGS(dev, desc, tsf_low, data1, data2, line, 436 TP_ARGS(dev, desc, tsf_low, data1, data2, line,
437 blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, 437 blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2,
438 gp3, ucode_ver, hw_ver, brd_ver), 438 gp3, major, minor, hw_ver, brd_ver),
439 TP_STRUCT__entry( 439 TP_STRUCT__entry(
440 DEV_ENTRY 440 DEV_ENTRY
441 __field(u32, desc) 441 __field(u32, desc)
@@ -451,7 +451,8 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
451 __field(u32, gp1) 451 __field(u32, gp1)
452 __field(u32, gp2) 452 __field(u32, gp2)
453 __field(u32, gp3) 453 __field(u32, gp3)
454 __field(u32, ucode_ver) 454 __field(u32, major)
455 __field(u32, minor)
455 __field(u32, hw_ver) 456 __field(u32, hw_ver)
456 __field(u32, brd_ver) 457 __field(u32, brd_ver)
457 ), 458 ),
@@ -470,21 +471,22 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
470 __entry->gp1 = gp1; 471 __entry->gp1 = gp1;
471 __entry->gp2 = gp2; 472 __entry->gp2 = gp2;
472 __entry->gp3 = gp3; 473 __entry->gp3 = gp3;
473 __entry->ucode_ver = ucode_ver; 474 __entry->major = major;
475 __entry->minor = minor;
474 __entry->hw_ver = hw_ver; 476 __entry->hw_ver = hw_ver;
475 __entry->brd_ver = brd_ver; 477 __entry->brd_ver = brd_ver;
476 ), 478 ),
477 TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " 479 TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, "
478 "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " 480 "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X "
479 "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " 481 "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X major 0x%08X "
480 "hw 0x%08X brd 0x%08X", 482 "minor 0x%08X hw 0x%08X brd 0x%08X",
481 __get_str(dev), __entry->desc, __entry->tsf_low, 483 __get_str(dev), __entry->desc, __entry->tsf_low,
482 __entry->data1, 484 __entry->data1,
483 __entry->data2, __entry->line, __entry->blink1, 485 __entry->data2, __entry->line, __entry->blink1,
484 __entry->blink2, __entry->ilink1, __entry->ilink2, 486 __entry->blink2, __entry->ilink1, __entry->ilink2,
485 __entry->bcon_time, __entry->gp1, __entry->gp2, 487 __entry->bcon_time, __entry->gp1, __entry->gp2,
486 __entry->gp3, __entry->ucode_ver, __entry->hw_ver, 488 __entry->gp3, __entry->major, __entry->minor,
487 __entry->brd_ver) 489 __entry->hw_ver, __entry->brd_ver)
488); 490);
489 491
490TRACE_EVENT(iwlwifi_dev_ucode_event, 492TRACE_EVENT(iwlwifi_dev_ucode_event,
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 996e7f16adf9..b608114b6b9e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -842,6 +842,23 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
842 capa->n_scan_channels = 842 capa->n_scan_channels =
843 le32_to_cpup((__le32 *)tlv_data); 843 le32_to_cpup((__le32 *)tlv_data);
844 break; 844 break;
845 case IWL_UCODE_TLV_FW_VERSION: {
846 __le32 *ptr = (void *)tlv_data;
847 u32 major, minor;
848 u8 local_comp;
849
850 if (tlv_len != sizeof(u32) * 3)
851 goto invalid_tlv_len;
852
853 major = le32_to_cpup(ptr++);
854 minor = le32_to_cpup(ptr++);
855 local_comp = le32_to_cpup(ptr);
856
857 snprintf(drv->fw.fw_version,
858 sizeof(drv->fw.fw_version), "%u.%u.%u",
859 major, minor, local_comp);
860 break;
861 }
845 case IWL_UCODE_TLV_FW_DBG_DEST: { 862 case IWL_UCODE_TLV_FW_DBG_DEST: {
846 struct iwl_fw_dbg_dest_tlv *dest = (void *)tlv_data; 863 struct iwl_fw_dbg_dest_tlv *dest = (void *)tlv_data;
847 864
@@ -1107,7 +1124,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1107 if (err) 1124 if (err)
1108 goto try_again; 1125 goto try_again;
1109 1126
1110 api_ver = IWL_UCODE_API(drv->fw.ucode_ver); 1127 if (drv->fw.ucode_capa.api[0] & IWL_UCODE_TLV_API_NEW_VERSION)
1128 api_ver = drv->fw.ucode_ver;
1129 else
1130 api_ver = IWL_UCODE_API(drv->fw.ucode_ver);
1111 1131
1112 /* 1132 /*
1113 * api_ver should match the api version forming part of the 1133 * api_ver should match the api version forming part of the
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index be4393e2c19c..3ec32e8a3cc4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -133,6 +133,7 @@ enum iwl_ucode_tlv_type {
133 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31, 133 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31,
134 IWL_UCODE_TLV_SEC_RT_USNIFFER = 34, 134 IWL_UCODE_TLV_SEC_RT_USNIFFER = 34,
135 IWL_UCODE_TLV_SDIO_ADMA_ADDR = 35, 135 IWL_UCODE_TLV_SDIO_ADMA_ADDR = 35,
136 IWL_UCODE_TLV_FW_VERSION = 36,
136 IWL_UCODE_TLV_FW_DBG_DEST = 38, 137 IWL_UCODE_TLV_FW_DBG_DEST = 38,
137 IWL_UCODE_TLV_FW_DBG_CONF = 39, 138 IWL_UCODE_TLV_FW_DBG_CONF = 39,
138}; 139};
@@ -156,7 +157,8 @@ struct iwl_tlv_ucode_header {
156 __le32 zero; 157 __le32 zero;
157 __le32 magic; 158 __le32 magic;
158 u8 human_readable[FW_VER_HUMAN_READABLE_SZ]; 159 u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
159 __le32 ver; /* major/minor/API/serial */ 160 /* major/minor/API/serial or major in new format */
161 __le32 ver;
160 __le32 build; 162 __le32 build;
161 __le64 ignore; 163 __le64 ignore;
162 /* 164 /*
@@ -250,6 +252,7 @@ enum iwl_ucode_tlv_flag {
250 * @IWL_UCODE_TLV_API_ASYNC_DTM: Async temperature notifications are supported. 252 * @IWL_UCODE_TLV_API_ASYNC_DTM: Async temperature notifications are supported.
251 * @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params 253 * @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params
252 * @IWL_UCODE_TLV_API_STATS_V10: uCode supports/uses statistics API version 10 254 * @IWL_UCODE_TLV_API_STATS_V10: uCode supports/uses statistics API version 10
255 * @IWL_UCODE_TLV_API_NEW_VERSION: new versioning format
253 */ 256 */
254enum iwl_ucode_tlv_api { 257enum iwl_ucode_tlv_api {
255 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3), 258 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
@@ -263,6 +266,7 @@ enum iwl_ucode_tlv_api {
263 IWL_UCODE_TLV_API_ASYNC_DTM = BIT(17), 266 IWL_UCODE_TLV_API_ASYNC_DTM = BIT(17),
264 IWL_UCODE_TLV_API_LQ_SS_PARAMS = BIT(18), 267 IWL_UCODE_TLV_API_LQ_SS_PARAMS = BIT(18),
265 IWL_UCODE_TLV_API_STATS_V10 = BIT(19), 268 IWL_UCODE_TLV_API_STATS_V10 = BIT(19),
269 IWL_UCODE_TLV_API_NEW_VERSION = BIT(20),
266}; 270};
267 271
268/** 272/**
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index c43e5c2bb85c..d95b47213731 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -432,7 +432,7 @@ enum {
432 432
433#define IWL_ALIVE_FLG_RFKILL BIT(0) 433#define IWL_ALIVE_FLG_RFKILL BIT(0)
434 434
435struct mvm_alive_resp { 435struct mvm_alive_resp_ver1 {
436 __le16 status; 436 __le16 status;
437 __le16 flags; 437 __le16 flags;
438 u8 ucode_minor; 438 u8 ucode_minor;
@@ -483,6 +483,30 @@ struct mvm_alive_resp_ver2 {
483 __le32 dbg_print_buff_addr; 483 __le32 dbg_print_buff_addr;
484} __packed; /* ALIVE_RES_API_S_VER_2 */ 484} __packed; /* ALIVE_RES_API_S_VER_2 */
485 485
486struct mvm_alive_resp {
487 __le16 status;
488 __le16 flags;
489 __le32 ucode_minor;
490 __le32 ucode_major;
491 u8 ver_subtype;
492 u8 ver_type;
493 u8 mac;
494 u8 opt;
495 __le32 timestamp;
496 __le32 error_event_table_ptr; /* SRAM address for error log */
497 __le32 log_event_table_ptr; /* SRAM address for LMAC event log */
498 __le32 cpu_register_ptr;
499 __le32 dbgm_config_ptr;
500 __le32 alive_counter_ptr;
501 __le32 scd_base_ptr; /* SRAM address for SCD */
502 __le32 st_fwrd_addr; /* pointer to Store and forward */
503 __le32 st_fwrd_size;
504 __le32 umac_minor; /* UMAC version: minor */
505 __le32 umac_major; /* UMAC version: major */
506 __le32 error_info_addr; /* SRAM address for UMAC error log */
507 __le32 dbg_print_buff_addr;
508} __packed; /* ALIVE_RES_API_S_VER_3 */
509
486/* Error response/notification */ 510/* Error response/notification */
487enum { 511enum {
488 FW_ERR_UNKNOWN_CMD = 0x0, 512 FW_ERR_UNKNOWN_CMD = 0x0,
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index ab81124c6029..7426bb0811be 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -112,25 +112,27 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
112 struct iwl_mvm *mvm = 112 struct iwl_mvm *mvm =
113 container_of(notif_wait, struct iwl_mvm, notif_wait); 113 container_of(notif_wait, struct iwl_mvm, notif_wait);
114 struct iwl_mvm_alive_data *alive_data = data; 114 struct iwl_mvm_alive_data *alive_data = data;
115 struct mvm_alive_resp *palive; 115 struct mvm_alive_resp_ver1 *palive1;
116 struct mvm_alive_resp_ver2 *palive2; 116 struct mvm_alive_resp_ver2 *palive2;
117 struct mvm_alive_resp *palive;
117 118
118 if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive)) { 119 if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive1)) {
119 palive = (void *)pkt->data; 120 palive1 = (void *)pkt->data;
120 121
121 mvm->support_umac_log = false; 122 mvm->support_umac_log = false;
122 mvm->error_event_table = 123 mvm->error_event_table =
123 le32_to_cpu(palive->error_event_table_ptr); 124 le32_to_cpu(palive1->error_event_table_ptr);
124 mvm->log_event_table = le32_to_cpu(palive->log_event_table_ptr); 125 mvm->log_event_table =
125 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr); 126 le32_to_cpu(palive1->log_event_table_ptr);
127 alive_data->scd_base_addr = le32_to_cpu(palive1->scd_base_ptr);
126 128
127 alive_data->valid = le16_to_cpu(palive->status) == 129 alive_data->valid = le16_to_cpu(palive1->status) ==
128 IWL_ALIVE_STATUS_OK; 130 IWL_ALIVE_STATUS_OK;
129 IWL_DEBUG_FW(mvm, 131 IWL_DEBUG_FW(mvm,
130 "Alive VER1 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n", 132 "Alive VER1 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
131 le16_to_cpu(palive->status), palive->ver_type, 133 le16_to_cpu(palive1->status), palive1->ver_type,
132 palive->ver_subtype, palive->flags); 134 palive1->ver_subtype, palive1->flags);
133 } else { 135 } else if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive2)) {
134 palive2 = (void *)pkt->data; 136 palive2 = (void *)pkt->data;
135 137
136 mvm->error_event_table = 138 mvm->error_event_table =
@@ -156,6 +158,33 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
156 IWL_DEBUG_FW(mvm, 158 IWL_DEBUG_FW(mvm,
157 "UMAC version: Major - 0x%x, Minor - 0x%x\n", 159 "UMAC version: Major - 0x%x, Minor - 0x%x\n",
158 palive2->umac_major, palive2->umac_minor); 160 palive2->umac_major, palive2->umac_minor);
161 } else if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive)) {
162 palive = (void *)pkt->data;
163
164 mvm->error_event_table =
165 le32_to_cpu(palive->error_event_table_ptr);
166 mvm->log_event_table =
167 le32_to_cpu(palive->log_event_table_ptr);
168 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr);
169 mvm->umac_error_event_table =
170 le32_to_cpu(palive->error_info_addr);
171 mvm->sf_space.addr = le32_to_cpu(palive->st_fwrd_addr);
172 mvm->sf_space.size = le32_to_cpu(palive->st_fwrd_size);
173
174 alive_data->valid = le16_to_cpu(palive->status) ==
175 IWL_ALIVE_STATUS_OK;
176 if (mvm->umac_error_event_table)
177 mvm->support_umac_log = true;
178
179 IWL_DEBUG_FW(mvm,
180 "Alive VER3 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
181 le16_to_cpu(palive->status), palive->ver_type,
182 palive->ver_subtype, palive->flags);
183
184 IWL_DEBUG_FW(mvm,
185 "UMAC version: Major - 0x%x, Minor - 0x%x\n",
186 le32_to_cpu(palive->umac_major),
187 le32_to_cpu(palive->umac_minor));
159 } 188 }
160 189
161 return true; 190 return true;
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index a50122344aac..2b9de63951e6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -332,7 +332,7 @@ static const char *desc_lookup(u32 num)
332 * read with u32-sized accesses, any members with a different size 332 * read with u32-sized accesses, any members with a different size
333 * need to be ordered correctly though! 333 * need to be ordered correctly though!
334 */ 334 */
335struct iwl_error_event_table { 335struct iwl_error_event_table_v1 {
336 u32 valid; /* (nonzero) valid, (0) log is empty */ 336 u32 valid; /* (nonzero) valid, (0) log is empty */
337 u32 error_id; /* type of error */ 337 u32 error_id; /* type of error */
338 u32 pc; /* program counter */ 338 u32 pc; /* program counter */
@@ -377,7 +377,55 @@ struct iwl_error_event_table {
377 u32 u_timestamp; /* indicate when the date and time of the 377 u32 u_timestamp; /* indicate when the date and time of the
378 * compilation */ 378 * compilation */
379 u32 flow_handler; /* FH read/write pointers, RX credit */ 379 u32 flow_handler; /* FH read/write pointers, RX credit */
380} __packed; 380} __packed /* LOG_ERROR_TABLE_API_S_VER_1 */;
381
382struct iwl_error_event_table {
383 u32 valid; /* (nonzero) valid, (0) log is empty */
384 u32 error_id; /* type of error */
385 u32 pc; /* program counter */
386 u32 blink1; /* branch link */
387 u32 blink2; /* branch link */
388 u32 ilink1; /* interrupt link */
389 u32 ilink2; /* interrupt link */
390 u32 data1; /* error-specific data */
391 u32 data2; /* error-specific data */
392 u32 data3; /* error-specific data */
393 u32 bcon_time; /* beacon timer */
394 u32 tsf_low; /* network timestamp function timer */
395 u32 tsf_hi; /* network timestamp function timer */
396 u32 gp1; /* GP1 timer register */
397 u32 gp2; /* GP2 timer register */
398 u32 gp3; /* GP3 timer register */
399 u32 major; /* uCode version major */
400 u32 minor; /* uCode version minor */
401 u32 hw_ver; /* HW Silicon version */
402 u32 brd_ver; /* HW board version */
403 u32 log_pc; /* log program counter */
404 u32 frame_ptr; /* frame pointer */
405 u32 stack_ptr; /* stack pointer */
406 u32 hcmd; /* last host command header */
407 u32 isr0; /* isr status register LMPM_NIC_ISR0:
408 * rxtx_flag */
409 u32 isr1; /* isr status register LMPM_NIC_ISR1:
410 * host_flag */
411 u32 isr2; /* isr status register LMPM_NIC_ISR2:
412 * enc_flag */
413 u32 isr3; /* isr status register LMPM_NIC_ISR3:
414 * time_flag */
415 u32 isr4; /* isr status register LMPM_NIC_ISR4:
416 * wico interrupt */
417 u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
418 u32 wait_event; /* wait event() caller address */
419 u32 l2p_control; /* L2pControlField */
420 u32 l2p_duration; /* L2pDurationField */
421 u32 l2p_mhvalid; /* L2pMhValidBits */
422 u32 l2p_addr_match; /* L2pAddrMatchStat */
423 u32 lmpm_pmg_sel; /* indicate which clocks are turned on
424 * (LMPM_PMG_SEL) */
425 u32 u_timestamp; /* indicate when the date and time of the
426 * compilation */
427 u32 flow_handler; /* FH read/write pointers, RX credit */
428} __packed /* LOG_ERROR_TABLE_API_S_VER_2 */;
381 429
382/* 430/*
383 * UMAC error struct - relevant starting from family 8000 chip. 431 * UMAC error struct - relevant starting from family 8000 chip.
@@ -396,11 +444,11 @@ struct iwl_umac_error_event_table {
396 u32 data1; /* error-specific data */ 444 u32 data1; /* error-specific data */
397 u32 data2; /* error-specific data */ 445 u32 data2; /* error-specific data */
398 u32 data3; /* error-specific data */ 446 u32 data3; /* error-specific data */
399 u32 umac_fw_ver; /* UMAC version */ 447 u32 umac_major;
400 u32 umac_fw_api_ver; /* UMAC FW API ver */ 448 u32 umac_minor;
401 u32 frame_pointer; /* core register 27*/ 449 u32 frame_pointer; /* core register 27*/
402 u32 stack_pointer; /* core register 28 */ 450 u32 stack_pointer; /* core register 28 */
403 u32 cmd_header; /* latest host cmd sent to UMAC */ 451 u32 cmd_header; /* latest host cmd sent to UMAC */
404 u32 nic_isr_pref; /* ISR status register */ 452 u32 nic_isr_pref; /* ISR status register */
405} __packed; 453} __packed;
406 454
@@ -441,18 +489,18 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm)
441 IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1); 489 IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1);
442 IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2); 490 IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2);
443 IWL_ERR(mvm, "0x%08X | umac data3\n", table.data3); 491 IWL_ERR(mvm, "0x%08X | umac data3\n", table.data3);
444 IWL_ERR(mvm, "0x%08X | umac version\n", table.umac_fw_ver); 492 IWL_ERR(mvm, "0x%08X | umac major\n", table.umac_major);
445 IWL_ERR(mvm, "0x%08X | umac api version\n", table.umac_fw_api_ver); 493 IWL_ERR(mvm, "0x%08X | umac minor\n", table.umac_minor);
446 IWL_ERR(mvm, "0x%08X | frame pointer\n", table.frame_pointer); 494 IWL_ERR(mvm, "0x%08X | frame pointer\n", table.frame_pointer);
447 IWL_ERR(mvm, "0x%08X | stack pointer\n", table.stack_pointer); 495 IWL_ERR(mvm, "0x%08X | stack pointer\n", table.stack_pointer);
448 IWL_ERR(mvm, "0x%08X | last host cmd\n", table.cmd_header); 496 IWL_ERR(mvm, "0x%08X | last host cmd\n", table.cmd_header);
449 IWL_ERR(mvm, "0x%08X | isr status reg\n", table.nic_isr_pref); 497 IWL_ERR(mvm, "0x%08X | isr status reg\n", table.nic_isr_pref);
450} 498}
451 499
452void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) 500static void iwl_mvm_dump_nic_error_log_old(struct iwl_mvm *mvm)
453{ 501{
454 struct iwl_trans *trans = mvm->trans; 502 struct iwl_trans *trans = mvm->trans;
455 struct iwl_error_event_table table; 503 struct iwl_error_event_table_v1 table;
456 u32 base; 504 u32 base;
457 505
458 base = mvm->error_event_table; 506 base = mvm->error_event_table;
@@ -489,7 +537,7 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
489 table.data1, table.data2, table.data3, 537 table.data1, table.data2, table.data3,
490 table.blink1, table.blink2, table.ilink1, 538 table.blink1, table.blink2, table.ilink1,
491 table.ilink2, table.bcon_time, table.gp1, 539 table.ilink2, table.bcon_time, table.gp1,
492 table.gp2, table.gp3, table.ucode_ver, 540 table.gp2, table.gp3, table.ucode_ver, 0,
493 table.hw_ver, table.brd_ver); 541 table.hw_ver, table.brd_ver);
494 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, 542 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
495 desc_lookup(table.error_id)); 543 desc_lookup(table.error_id));
@@ -530,6 +578,92 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
530 iwl_mvm_dump_umac_error_log(mvm); 578 iwl_mvm_dump_umac_error_log(mvm);
531} 579}
532 580
581void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
582{
583 struct iwl_trans *trans = mvm->trans;
584 struct iwl_error_event_table table;
585 u32 base;
586
587 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_NEW_VERSION)) {
588 iwl_mvm_dump_nic_error_log_old(mvm);
589 return;
590 }
591
592 base = mvm->error_event_table;
593 if (mvm->cur_ucode == IWL_UCODE_INIT) {
594 if (!base)
595 base = mvm->fw->init_errlog_ptr;
596 } else {
597 if (!base)
598 base = mvm->fw->inst_errlog_ptr;
599 }
600
601 if (base < 0x800000) {
602 IWL_ERR(mvm,
603 "Not valid error log pointer 0x%08X for %s uCode\n",
604 base,
605 (mvm->cur_ucode == IWL_UCODE_INIT)
606 ? "Init" : "RT");
607 return;
608 }
609
610 iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
611
612 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
613 IWL_ERR(trans, "Start IWL Error Log Dump:\n");
614 IWL_ERR(trans, "Status: 0x%08lX, count: %d\n",
615 mvm->status, table.valid);
616 }
617
618 /* Do not change this output - scripts rely on it */
619
620 IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version);
621
622 trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
623 table.data1, table.data2, table.data3,
624 table.blink1, table.blink2, table.ilink1,
625 table.ilink2, table.bcon_time, table.gp1,
626 table.gp2, table.gp3, table.major,
627 table.minor, table.hw_ver, table.brd_ver);
628 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
629 desc_lookup(table.error_id));
630 IWL_ERR(mvm, "0x%08X | uPc\n", table.pc);
631 IWL_ERR(mvm, "0x%08X | branchlink1\n", table.blink1);
632 IWL_ERR(mvm, "0x%08X | branchlink2\n", table.blink2);
633 IWL_ERR(mvm, "0x%08X | interruptlink1\n", table.ilink1);
634 IWL_ERR(mvm, "0x%08X | interruptlink2\n", table.ilink2);
635 IWL_ERR(mvm, "0x%08X | data1\n", table.data1);
636 IWL_ERR(mvm, "0x%08X | data2\n", table.data2);
637 IWL_ERR(mvm, "0x%08X | data3\n", table.data3);
638 IWL_ERR(mvm, "0x%08X | beacon time\n", table.bcon_time);
639 IWL_ERR(mvm, "0x%08X | tsf low\n", table.tsf_low);
640 IWL_ERR(mvm, "0x%08X | tsf hi\n", table.tsf_hi);
641 IWL_ERR(mvm, "0x%08X | time gp1\n", table.gp1);
642 IWL_ERR(mvm, "0x%08X | time gp2\n", table.gp2);
643 IWL_ERR(mvm, "0x%08X | time gp3\n", table.gp3);
644 IWL_ERR(mvm, "0x%08X | uCode version major\n", table.major);
645 IWL_ERR(mvm, "0x%08X | uCode version minor\n", table.minor);
646 IWL_ERR(mvm, "0x%08X | hw version\n", table.hw_ver);
647 IWL_ERR(mvm, "0x%08X | board version\n", table.brd_ver);
648 IWL_ERR(mvm, "0x%08X | hcmd\n", table.hcmd);
649 IWL_ERR(mvm, "0x%08X | isr0\n", table.isr0);
650 IWL_ERR(mvm, "0x%08X | isr1\n", table.isr1);
651 IWL_ERR(mvm, "0x%08X | isr2\n", table.isr2);
652 IWL_ERR(mvm, "0x%08X | isr3\n", table.isr3);
653 IWL_ERR(mvm, "0x%08X | isr4\n", table.isr4);
654 IWL_ERR(mvm, "0x%08X | isr_pref\n", table.isr_pref);
655 IWL_ERR(mvm, "0x%08X | wait_event\n", table.wait_event);
656 IWL_ERR(mvm, "0x%08X | l2p_control\n", table.l2p_control);
657 IWL_ERR(mvm, "0x%08X | l2p_duration\n", table.l2p_duration);
658 IWL_ERR(mvm, "0x%08X | l2p_mhvalid\n", table.l2p_mhvalid);
659 IWL_ERR(mvm, "0x%08X | l2p_addr_match\n", table.l2p_addr_match);
660 IWL_ERR(mvm, "0x%08X | lmpm_pmg_sel\n", table.lmpm_pmg_sel);
661 IWL_ERR(mvm, "0x%08X | timestamp\n", table.u_timestamp);
662 IWL_ERR(mvm, "0x%08X | flow_handler\n", table.flow_handler);
663
664 if (mvm->support_umac_log)
665 iwl_mvm_dump_umac_error_log(mvm);
666}
533void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn, 667void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
534 const struct iwl_trans_txq_scd_cfg *cfg, 668 const struct iwl_trans_txq_scd_cfg *cfg,
535 unsigned int wdg_timeout) 669 unsigned int wdg_timeout)