forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-02-19 1c055e55a242a33e574e48be530e06770a210dcd
kernel/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
....@@ -8,7 +8,7 @@
88 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
99 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
1010 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
11
- * Copyright(c) 2018 Intel Corporation
11
+ * Copyright(c) 2018 - 2019 Intel Corporation
1212 *
1313 * This program is free software; you can redistribute it and/or modify
1414 * it under the terms of version 2 of the GNU General Public License as
....@@ -18,9 +18,6 @@
1818 * WITHOUT ANY WARRANTY; without even the implied warranty of
1919 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2020 * General Public License for more details.
21
- *
22
- * You should have received a copy of the GNU General Public License
23
- * along with this program;
2421 *
2522 * The full GNU General Public License is included in this distribution
2623 * in the file called COPYING.
....@@ -34,7 +31,7 @@
3431 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
3532 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
3633 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
37
- * Copyright(c) 2018 Intel Corporation
34
+ * Copyright(c) 2018 - 2019 Intel Corporation
3835 * All rights reserved.
3936 *
4037 * Redistribution and use in source and binary forms, with or without
....@@ -74,6 +71,9 @@
7471 #include "iwl-io.h"
7572 #include "file.h"
7673 #include "error-dump.h"
74
+#include "api/commands.h"
75
+#include "api/dbg-tlv.h"
76
+#include "api/alive.h"
7777
7878 /**
7979 * struct iwl_fw_dump_desc - describes the dump
....@@ -86,38 +86,42 @@
8686 struct iwl_fw_error_dump_trigger_desc trig_desc;
8787 };
8888
89
+/**
90
+ * struct iwl_fw_dbg_params - register values to restore
91
+ * @in_sample: DBGC_IN_SAMPLE value
92
+ * @out_ctrl: DBGC_OUT_CTRL value
93
+ */
94
+struct iwl_fw_dbg_params {
95
+ u32 in_sample;
96
+ u32 out_ctrl;
97
+};
98
+
8999 extern const struct iwl_fw_dump_desc iwl_dump_desc_assert;
90100
91
-static inline void iwl_fw_free_dump_desc(struct iwl_fw_runtime *fwrt)
92
-{
93
- if (fwrt->dump.desc != &iwl_dump_desc_assert)
94
- kfree(fwrt->dump.desc);
95
- fwrt->dump.desc = NULL;
96
- fwrt->dump.trig = NULL;
97
-}
98
-
99
-void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt);
100101 int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
101102 const struct iwl_fw_dump_desc *desc,
102
- const struct iwl_fw_dbg_trigger_tlv *trigger);
103
+ bool monitor_only, unsigned int delay);
104
+int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt,
105
+ enum iwl_fw_dbg_trigger trig_type);
106
+int iwl_fw_dbg_ini_collect(struct iwl_fw_runtime *fwrt,
107
+ struct iwl_fwrt_dump_data *dump_data);
103108 int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
104
- enum iwl_fw_dbg_trigger trig,
105
- const char *str, size_t len,
106
- const struct iwl_fw_dbg_trigger_tlv *trigger);
109
+ enum iwl_fw_dbg_trigger trig, const char *str,
110
+ size_t len, struct iwl_fw_dbg_trigger_tlv *trigger);
107111 int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
108112 struct iwl_fw_dbg_trigger_tlv *trigger,
109113 const char *fmt, ...) __printf(3, 4);
110114 int iwl_fw_start_dbg_conf(struct iwl_fw_runtime *fwrt, u8 id);
111115
112116 #define iwl_fw_dbg_trigger_enabled(fw, id) ({ \
113
- void *__dbg_trigger = (fw)->dbg_trigger_tlv[(id)]; \
117
+ void *__dbg_trigger = (fw)->dbg.trigger_tlv[(id)]; \
114118 unlikely(__dbg_trigger); \
115119 })
116120
117121 static inline struct iwl_fw_dbg_trigger_tlv*
118122 _iwl_fw_dbg_get_trigger(const struct iwl_fw *fw, enum iwl_fw_dbg_trigger id)
119123 {
120
- return fw->dbg_trigger_tlv[id];
124
+ return fw->dbg.trigger_tlv[id];
121125 }
122126
123127 #define iwl_fw_dbg_get_trigger(fw, id) ({ \
....@@ -146,12 +150,9 @@
146150 }
147151
148152 static inline bool
149
-iwl_fw_dbg_no_trig_window(struct iwl_fw_runtime *fwrt,
150
- struct iwl_fw_dbg_trigger_tlv *trig)
153
+iwl_fw_dbg_no_trig_window(struct iwl_fw_runtime *fwrt, u32 id, u32 dis_usec)
151154 {
152
- unsigned long wind_jiff =
153
- msecs_to_jiffies(le16_to_cpu(trig->trig_dis_ms));
154
- u32 id = le32_to_cpu(trig->id);
155
+ unsigned long wind_jiff = usecs_to_jiffies(dis_usec);
155156
156157 /* If this is the first event checked, jump to update start ts */
157158 if (fwrt->dump.non_collect_ts_start[id] &&
....@@ -168,10 +169,12 @@
168169 struct wireless_dev *wdev,
169170 struct iwl_fw_dbg_trigger_tlv *trig)
170171 {
172
+ u32 usec = le16_to_cpu(trig->trig_dis_ms) * USEC_PER_MSEC;
173
+
171174 if (wdev && !iwl_fw_dbg_trigger_vif_match(trig, wdev))
172175 return false;
173176
174
- if (iwl_fw_dbg_no_trig_window(fwrt, trig)) {
177
+ if (iwl_fw_dbg_no_trig_window(fwrt, le32_to_cpu(trig->id), usec)) {
175178 IWL_WARN(fwrt, "Trigger %d occurred while no-collect window.\n",
176179 trig->id);
177180 return false;
....@@ -179,6 +182,33 @@
179182
180183 return iwl_fw_dbg_trigger_stop_conf_match(fwrt, trig);
181184 }
185
+
186
+static inline struct iwl_fw_dbg_trigger_tlv*
187
+_iwl_fw_dbg_trigger_on(struct iwl_fw_runtime *fwrt,
188
+ struct wireless_dev *wdev,
189
+ const enum iwl_fw_dbg_trigger id)
190
+{
191
+ struct iwl_fw_dbg_trigger_tlv *trig;
192
+
193
+ if (iwl_trans_dbg_ini_valid(fwrt->trans))
194
+ return NULL;
195
+
196
+ if (!iwl_fw_dbg_trigger_enabled(fwrt->fw, id))
197
+ return NULL;
198
+
199
+ trig = _iwl_fw_dbg_get_trigger(fwrt->fw, id);
200
+
201
+ if (!iwl_fw_dbg_trigger_check_stop(fwrt, wdev, trig))
202
+ return NULL;
203
+
204
+ return trig;
205
+}
206
+
207
+#define iwl_fw_dbg_trigger_on(fwrt, wdev, id) ({ \
208
+ BUILD_BUG_ON(!__builtin_constant_p(id)); \
209
+ BUILD_BUG_ON((id) >= FW_DBG_TRIGGER_MAX); \
210
+ _iwl_fw_dbg_trigger_on((fwrt), (wdev), (id)); \
211
+})
182212
183213 static inline void
184214 _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt,
....@@ -198,17 +228,19 @@
198228 _iwl_fw_dbg_trigger_simple_stop((fwrt), (wdev), \
199229 iwl_fw_dbg_get_trigger((fwrt)->fw,\
200230 (trig)))
231
+void iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt,
232
+ struct iwl_fw_dbg_params *params,
233
+ bool stop);
201234
202
-static inline void iwl_fw_dbg_stop_recording(struct iwl_fw_runtime *fwrt)
235
+#ifdef CONFIG_IWLWIFI_DEBUGFS
236
+static inline void iwl_fw_set_dbg_rec_on(struct iwl_fw_runtime *fwrt)
203237 {
204
- if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
205
- iwl_set_bits_prph(fwrt->trans, MON_BUFF_SAMPLE_CTL, 0x100);
206
- } else {
207
- iwl_write_prph(fwrt->trans, DBGC_IN_SAMPLE, 0);
208
- udelay(100);
209
- iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, 0);
210
- }
238
+ if (fwrt->cur_fw_img == IWL_UCODE_REGULAR &&
239
+ (fwrt->fw->dbg.dest_tlv ||
240
+ fwrt->trans->dbg.ini_dest != IWL_FW_INI_LOCATION_INVALID))
241
+ fwrt->trans->dbg.rec_on = true;
211242 }
243
+#endif
212244
213245 static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt)
214246 {
....@@ -217,14 +249,39 @@
217249
218250 void iwl_fw_error_dump_wk(struct work_struct *work);
219251
220
-static inline void iwl_fw_flush_dump(struct iwl_fw_runtime *fwrt)
252
+static inline bool iwl_fw_dbg_type_on(struct iwl_fw_runtime *fwrt, u32 type)
221253 {
222
- flush_delayed_work(&fwrt->dump.wk);
254
+ return (fwrt->fw->dbg.dump_mask & BIT(type));
223255 }
224256
225
-static inline void iwl_fw_cancel_dump(struct iwl_fw_runtime *fwrt)
257
+static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt)
226258 {
227
- cancel_delayed_work_sync(&fwrt->dump.wk);
259
+ return fw_has_capa(&fwrt->fw->ucode_capa,
260
+ IWL_UCODE_TLV_CAPA_D3_DEBUG) &&
261
+ fwrt->trans->cfg->d3_debug_data_length && fwrt->ops &&
262
+ fwrt->ops->d3_debug_enable &&
263
+ fwrt->ops->d3_debug_enable(fwrt->ops_ctx) &&
264
+ iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_D3_DEBUG_DATA);
265
+}
266
+
267
+static inline bool iwl_fw_dbg_is_paging_enabled(struct iwl_fw_runtime *fwrt)
268
+{
269
+ return iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_PAGING) &&
270
+ !fwrt->trans->trans_cfg->gen2 &&
271
+ fwrt->cur_fw_img < IWL_UCODE_TYPE_MAX &&
272
+ fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size &&
273
+ fwrt->fw_paging_db[0].fw_paging_block;
274
+}
275
+
276
+void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt);
277
+
278
+static inline void iwl_fw_flush_dumps(struct iwl_fw_runtime *fwrt)
279
+{
280
+ int i;
281
+
282
+ iwl_dbg_tlv_del_timers(fwrt->trans);
283
+ for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++)
284
+ flush_delayed_work(&fwrt->dump.wks[i].wk);
228285 }
229286
230287 #ifdef CONFIG_IWLWIFI_DEBUGFS
....@@ -263,4 +320,63 @@
263320
264321 #endif /* CONFIG_IWLWIFI_DEBUGFS */
265322
323
+void iwl_fw_dbg_stop_sync(struct iwl_fw_runtime *fwrt);
324
+
325
+static inline void iwl_fw_lmac1_set_alive_err_table(struct iwl_trans *trans,
326
+ u32 lmac_error_event_table)
327
+{
328
+ if (!(trans->dbg.error_event_table_tlv_status &
329
+ IWL_ERROR_EVENT_TABLE_LMAC1) ||
330
+ WARN_ON(trans->dbg.lmac_error_event_table[0] !=
331
+ lmac_error_event_table))
332
+ trans->dbg.lmac_error_event_table[0] = lmac_error_event_table;
333
+}
334
+
335
+static inline void iwl_fw_umac_set_alive_err_table(struct iwl_trans *trans,
336
+ u32 umac_error_event_table)
337
+{
338
+ if (!(trans->dbg.error_event_table_tlv_status &
339
+ IWL_ERROR_EVENT_TABLE_UMAC) ||
340
+ WARN_ON(trans->dbg.umac_error_event_table !=
341
+ umac_error_event_table))
342
+ trans->dbg.umac_error_event_table = umac_error_event_table;
343
+}
344
+
345
+static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt)
346
+{
347
+ enum iwl_fw_ini_time_point tp_id;
348
+
349
+ if (!iwl_trans_dbg_ini_valid(fwrt->trans)) {
350
+ iwl_fw_dbg_collect_desc(fwrt, &iwl_dump_desc_assert, false, 0);
351
+ return;
352
+ }
353
+
354
+ if (fwrt->trans->dbg.hw_error) {
355
+ tp_id = IWL_FW_INI_TIME_POINT_FW_HW_ERROR;
356
+ fwrt->trans->dbg.hw_error = false;
357
+ } else {
358
+ tp_id = IWL_FW_INI_TIME_POINT_FW_ASSERT;
359
+ }
360
+
361
+ iwl_dbg_tlv_time_point(fwrt, tp_id, NULL);
362
+}
363
+
364
+void iwl_fw_error_print_fseq_regs(struct iwl_fw_runtime *fwrt);
365
+
366
+static inline void iwl_fwrt_update_fw_versions(struct iwl_fw_runtime *fwrt,
367
+ struct iwl_lmac_alive *lmac,
368
+ struct iwl_umac_alive *umac)
369
+{
370
+ if (lmac) {
371
+ fwrt->dump.fw_ver.type = lmac->ver_type;
372
+ fwrt->dump.fw_ver.subtype = lmac->ver_subtype;
373
+ fwrt->dump.fw_ver.lmac_major = le32_to_cpu(lmac->ucode_major);
374
+ fwrt->dump.fw_ver.lmac_minor = le32_to_cpu(lmac->ucode_minor);
375
+ }
376
+
377
+ if (umac) {
378
+ fwrt->dump.fw_ver.umac_major = le32_to_cpu(umac->umac_major);
379
+ fwrt->dump.fw_ver.umac_minor = le32_to_cpu(umac->umac_minor);
380
+ }
381
+}
266382 #endif /* __iwl_fw_dbg_h__ */