Commit | Line | Data |
---|---|---|
4fa9c49f | 1 | // SPDX-License-Identifier: GPL-2.0-only |
ad75b7d3 RL |
2 | /* |
3 | * Copyright (C) 2017 Chelsio Communications. All rights reserved. | |
ad75b7d3 RL |
4 | */ |
5 | ||
b33af022 | 6 | #include "t4_regs.h" |
ad75b7d3 RL |
7 | #include "cxgb4.h" |
8 | #include "cxgb4_cudbg.h" | |
91c1953d | 9 | #include "cudbg_zlib.h" |
ad75b7d3 | 10 | |
b33af022 RL |
11 | static const struct cxgb4_collect_entity cxgb4_collect_mem_dump[] = { |
12 | { CUDBG_EDC0, cudbg_collect_edc0_meminfo }, | |
13 | { CUDBG_EDC1, cudbg_collect_edc1_meminfo }, | |
a1c69520 RL |
14 | { CUDBG_MC0, cudbg_collect_mc0_meminfo }, |
15 | { CUDBG_MC1, cudbg_collect_mc1_meminfo }, | |
4db0401f | 16 | { CUDBG_HMA, cudbg_collect_hma_meminfo }, |
b33af022 RL |
17 | }; |
18 | ||
a7975a2f | 19 | static const struct cxgb4_collect_entity cxgb4_collect_hw_dump[] = { |
844d1b6f | 20 | { CUDBG_MBOX_LOG, cudbg_collect_mbox_log }, |
68ddc82a | 21 | { CUDBG_QDESC, cudbg_collect_qdesc }, |
844d1b6f | 22 | { CUDBG_DEV_LOG, cudbg_collect_fw_devlog }, |
a7975a2f | 23 | { CUDBG_REG_DUMP, cudbg_collect_reg_dump }, |
27887bc7 RL |
24 | { CUDBG_CIM_LA, cudbg_collect_cim_la }, |
25 | { CUDBG_CIM_MA_LA, cudbg_collect_cim_ma_la }, | |
3044d0fb | 26 | { CUDBG_CIM_QCFG, cudbg_collect_cim_qcfg }, |
7c075ce2 RL |
27 | { CUDBG_CIM_IBQ_TP0, cudbg_collect_cim_ibq_tp0 }, |
28 | { CUDBG_CIM_IBQ_TP1, cudbg_collect_cim_ibq_tp1 }, | |
29 | { CUDBG_CIM_IBQ_ULP, cudbg_collect_cim_ibq_ulp }, | |
30 | { CUDBG_CIM_IBQ_SGE0, cudbg_collect_cim_ibq_sge0 }, | |
31 | { CUDBG_CIM_IBQ_SGE1, cudbg_collect_cim_ibq_sge1 }, | |
32 | { CUDBG_CIM_IBQ_NCSI, cudbg_collect_cim_ibq_ncsi }, | |
33 | { CUDBG_CIM_OBQ_ULP0, cudbg_collect_cim_obq_ulp0 }, | |
34 | { CUDBG_CIM_OBQ_ULP1, cudbg_collect_cim_obq_ulp1 }, | |
35 | { CUDBG_CIM_OBQ_ULP2, cudbg_collect_cim_obq_ulp2 }, | |
36 | { CUDBG_CIM_OBQ_ULP3, cudbg_collect_cim_obq_ulp3 }, | |
37 | { CUDBG_CIM_OBQ_SGE, cudbg_collect_cim_obq_sge }, | |
38 | { CUDBG_CIM_OBQ_NCSI, cudbg_collect_cim_obq_ncsi }, | |
28b44556 RL |
39 | { CUDBG_RSS, cudbg_collect_rss }, |
40 | { CUDBG_RSS_VF_CONF, cudbg_collect_rss_vf_config }, | |
6f92a654 RL |
41 | { CUDBG_PATH_MTU, cudbg_collect_path_mtu }, |
42 | { CUDBG_PM_STATS, cudbg_collect_pm_stats }, | |
08c4901b | 43 | { CUDBG_HW_SCHED, cudbg_collect_hw_sched }, |
4359cf33 | 44 | { CUDBG_TP_INDIRECT, cudbg_collect_tp_indirect }, |
270d39bf | 45 | { CUDBG_SGE_INDIRECT, cudbg_collect_sge_indirect }, |
27887bc7 RL |
46 | { CUDBG_ULPRX_LA, cudbg_collect_ulprx_la }, |
47 | { CUDBG_TP_LA, cudbg_collect_tp_la }, | |
123e25c4 | 48 | { CUDBG_MEMINFO, cudbg_collect_meminfo }, |
27887bc7 | 49 | { CUDBG_CIM_PIF_LA, cudbg_collect_cim_pif_la }, |
6f92a654 | 50 | { CUDBG_CLK, cudbg_collect_clk_info }, |
7c075ce2 RL |
51 | { CUDBG_CIM_OBQ_RXQ0, cudbg_collect_obq_sge_rx_q0 }, |
52 | { CUDBG_CIM_OBQ_RXQ1, cudbg_collect_obq_sge_rx_q1 }, | |
270d39bf RL |
53 | { CUDBG_PCIE_INDIRECT, cudbg_collect_pcie_indirect }, |
54 | { CUDBG_PM_INDIRECT, cudbg_collect_pm_indirect }, | |
9030e498 | 55 | { CUDBG_TID_INFO, cudbg_collect_tid }, |
6078ab19 | 56 | { CUDBG_PCIE_CONFIG, cudbg_collect_pcie_config }, |
9e5c598c | 57 | { CUDBG_DUMP_CONTEXT, cudbg_collect_dump_context }, |
b289593e | 58 | { CUDBG_MPS_TCAM, cudbg_collect_mps_tcam }, |
6f92a654 | 59 | { CUDBG_VPD_DATA, cudbg_collect_vpd_data }, |
03e98b91 | 60 | { CUDBG_LE_TCAM, cudbg_collect_le_tcam }, |
6f92a654 | 61 | { CUDBG_CCTRL, cudbg_collect_cctrl }, |
270d39bf | 62 | { CUDBG_MA_INDIRECT, cudbg_collect_ma_indirect }, |
27887bc7 | 63 | { CUDBG_ULPTX_LA, cudbg_collect_ulptx_la }, |
270d39bf | 64 | { CUDBG_UP_CIM_INDIRECT, cudbg_collect_up_cim_indirect }, |
db8cd7ce | 65 | { CUDBG_PBT_TABLE, cudbg_collect_pbt_tables }, |
270d39bf | 66 | { CUDBG_HMA_INDIRECT, cudbg_collect_hma_indirect }, |
a7975a2f RL |
67 | }; |
68 | ||
69 | static u32 cxgb4_get_entity_length(struct adapter *adap, u32 entity) | |
70 | { | |
03e98b91 | 71 | struct cudbg_tcam tcam_region = { 0 }; |
4359cf33 | 72 | u32 value, n = 0, len = 0; |
a7975a2f RL |
73 | |
74 | switch (entity) { | |
75 | case CUDBG_REG_DUMP: | |
76 | switch (CHELSIO_CHIP_VERSION(adap->params.chip)) { | |
77 | case CHELSIO_T4: | |
78 | len = T4_REGMAP_SIZE; | |
79 | break; | |
80 | case CHELSIO_T5: | |
81 | case CHELSIO_T6: | |
82 | len = T5_REGMAP_SIZE; | |
83 | break; | |
84 | default: | |
85 | break; | |
86 | } | |
87 | break; | |
844d1b6f RL |
88 | case CUDBG_DEV_LOG: |
89 | len = adap->params.devlog.size; | |
90 | break; | |
27887bc7 RL |
91 | case CUDBG_CIM_LA: |
92 | if (is_t6(adap->params.chip)) { | |
93 | len = adap->params.cim_la_size / 10 + 1; | |
e6f02a4d | 94 | len *= 10 * sizeof(u32); |
27887bc7 RL |
95 | } else { |
96 | len = adap->params.cim_la_size / 8; | |
97 | len *= 8 * sizeof(u32); | |
98 | } | |
99 | len += sizeof(u32); /* for reading CIM LA configuration */ | |
100 | break; | |
101 | case CUDBG_CIM_MA_LA: | |
102 | len = 2 * CIM_MALA_SIZE * 5 * sizeof(u32); | |
103 | break; | |
3044d0fb RL |
104 | case CUDBG_CIM_QCFG: |
105 | len = sizeof(struct cudbg_cim_qcfg); | |
106 | break; | |
7c075ce2 RL |
107 | case CUDBG_CIM_IBQ_TP0: |
108 | case CUDBG_CIM_IBQ_TP1: | |
109 | case CUDBG_CIM_IBQ_ULP: | |
110 | case CUDBG_CIM_IBQ_SGE0: | |
111 | case CUDBG_CIM_IBQ_SGE1: | |
112 | case CUDBG_CIM_IBQ_NCSI: | |
113 | len = CIM_IBQ_SIZE * 4 * sizeof(u32); | |
114 | break; | |
115 | case CUDBG_CIM_OBQ_ULP0: | |
acfdf7ea RL |
116 | len = cudbg_cim_obq_size(adap, 0); |
117 | break; | |
7c075ce2 | 118 | case CUDBG_CIM_OBQ_ULP1: |
acfdf7ea RL |
119 | len = cudbg_cim_obq_size(adap, 1); |
120 | break; | |
7c075ce2 | 121 | case CUDBG_CIM_OBQ_ULP2: |
acfdf7ea RL |
122 | len = cudbg_cim_obq_size(adap, 2); |
123 | break; | |
7c075ce2 | 124 | case CUDBG_CIM_OBQ_ULP3: |
acfdf7ea RL |
125 | len = cudbg_cim_obq_size(adap, 3); |
126 | break; | |
7c075ce2 | 127 | case CUDBG_CIM_OBQ_SGE: |
acfdf7ea RL |
128 | len = cudbg_cim_obq_size(adap, 4); |
129 | break; | |
7c075ce2 | 130 | case CUDBG_CIM_OBQ_NCSI: |
acfdf7ea RL |
131 | len = cudbg_cim_obq_size(adap, 5); |
132 | break; | |
7c075ce2 | 133 | case CUDBG_CIM_OBQ_RXQ0: |
acfdf7ea RL |
134 | len = cudbg_cim_obq_size(adap, 6); |
135 | break; | |
7c075ce2 | 136 | case CUDBG_CIM_OBQ_RXQ1: |
acfdf7ea | 137 | len = cudbg_cim_obq_size(adap, 7); |
7c075ce2 | 138 | break; |
b33af022 RL |
139 | case CUDBG_EDC0: |
140 | value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A); | |
141 | if (value & EDRAM0_ENABLE_F) { | |
142 | value = t4_read_reg(adap, MA_EDRAM0_BAR_A); | |
143 | len = EDRAM0_SIZE_G(value); | |
144 | } | |
145 | len = cudbg_mbytes_to_bytes(len); | |
146 | break; | |
147 | case CUDBG_EDC1: | |
148 | value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A); | |
149 | if (value & EDRAM1_ENABLE_F) { | |
150 | value = t4_read_reg(adap, MA_EDRAM1_BAR_A); | |
151 | len = EDRAM1_SIZE_G(value); | |
152 | } | |
153 | len = cudbg_mbytes_to_bytes(len); | |
154 | break; | |
a1c69520 RL |
155 | case CUDBG_MC0: |
156 | value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A); | |
157 | if (value & EXT_MEM0_ENABLE_F) { | |
158 | value = t4_read_reg(adap, MA_EXT_MEMORY0_BAR_A); | |
159 | len = EXT_MEM0_SIZE_G(value); | |
160 | } | |
161 | len = cudbg_mbytes_to_bytes(len); | |
162 | break; | |
163 | case CUDBG_MC1: | |
164 | value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A); | |
165 | if (value & EXT_MEM1_ENABLE_F) { | |
166 | value = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A); | |
167 | len = EXT_MEM1_SIZE_G(value); | |
168 | } | |
169 | len = cudbg_mbytes_to_bytes(len); | |
170 | break; | |
28b44556 | 171 | case CUDBG_RSS: |
f988008a | 172 | len = t4_chip_rss_size(adap) * sizeof(u16); |
28b44556 RL |
173 | break; |
174 | case CUDBG_RSS_VF_CONF: | |
175 | len = adap->params.arch.vfcount * | |
176 | sizeof(struct cudbg_rss_vf_conf); | |
177 | break; | |
6f92a654 RL |
178 | case CUDBG_PATH_MTU: |
179 | len = NMTUS * sizeof(u16); | |
180 | break; | |
181 | case CUDBG_PM_STATS: | |
182 | len = sizeof(struct cudbg_pm_stats); | |
183 | break; | |
08c4901b RL |
184 | case CUDBG_HW_SCHED: |
185 | len = sizeof(struct cudbg_hw_sched); | |
186 | break; | |
4359cf33 RL |
187 | case CUDBG_TP_INDIRECT: |
188 | switch (CHELSIO_CHIP_VERSION(adap->params.chip)) { | |
189 | case CHELSIO_T5: | |
190 | n = sizeof(t5_tp_pio_array) + | |
191 | sizeof(t5_tp_tm_pio_array) + | |
192 | sizeof(t5_tp_mib_index_array); | |
193 | break; | |
194 | case CHELSIO_T6: | |
195 | n = sizeof(t6_tp_pio_array) + | |
196 | sizeof(t6_tp_tm_pio_array) + | |
197 | sizeof(t6_tp_mib_index_array); | |
198 | break; | |
199 | default: | |
200 | break; | |
201 | } | |
202 | n = n / (IREG_NUM_ELEM * sizeof(u32)); | |
203 | len = sizeof(struct ireg_buf) * n; | |
204 | break; | |
270d39bf | 205 | case CUDBG_SGE_INDIRECT: |
80a95a80 RL |
206 | len = sizeof(struct ireg_buf) * 2 + |
207 | sizeof(struct sge_qbase_reg_field); | |
270d39bf | 208 | break; |
27887bc7 RL |
209 | case CUDBG_ULPRX_LA: |
210 | len = sizeof(struct cudbg_ulprx_la); | |
211 | break; | |
212 | case CUDBG_TP_LA: | |
213 | len = sizeof(struct cudbg_tp_la) + TPLA_SIZE * sizeof(u64); | |
214 | break; | |
123e25c4 | 215 | case CUDBG_MEMINFO: |
9d0f180c RL |
216 | len = sizeof(struct cudbg_ver_hdr) + |
217 | sizeof(struct cudbg_meminfo); | |
123e25c4 | 218 | break; |
27887bc7 RL |
219 | case CUDBG_CIM_PIF_LA: |
220 | len = sizeof(struct cudbg_cim_pif_la); | |
221 | len += 2 * CIM_PIFLA_SIZE * 6 * sizeof(u32); | |
222 | break; | |
6f92a654 RL |
223 | case CUDBG_CLK: |
224 | len = sizeof(struct cudbg_clk_info); | |
225 | break; | |
270d39bf RL |
226 | case CUDBG_PCIE_INDIRECT: |
227 | n = sizeof(t5_pcie_pdbg_array) / (IREG_NUM_ELEM * sizeof(u32)); | |
228 | len = sizeof(struct ireg_buf) * n * 2; | |
229 | break; | |
230 | case CUDBG_PM_INDIRECT: | |
231 | n = sizeof(t5_pm_rx_array) / (IREG_NUM_ELEM * sizeof(u32)); | |
232 | len = sizeof(struct ireg_buf) * n * 2; | |
233 | break; | |
9030e498 RL |
234 | case CUDBG_TID_INFO: |
235 | len = sizeof(struct cudbg_tid_info_region_rev1); | |
236 | break; | |
6078ab19 RL |
237 | case CUDBG_PCIE_CONFIG: |
238 | len = sizeof(u32) * CUDBG_NUM_PCIE_CONFIG_REGS; | |
239 | break; | |
9e5c598c RL |
240 | case CUDBG_DUMP_CONTEXT: |
241 | len = cudbg_dump_context_size(adap); | |
242 | break; | |
b289593e RL |
243 | case CUDBG_MPS_TCAM: |
244 | len = sizeof(struct cudbg_mps_tcam) * | |
245 | adap->params.arch.mps_tcam_size; | |
246 | break; | |
6f92a654 RL |
247 | case CUDBG_VPD_DATA: |
248 | len = sizeof(struct cudbg_vpd_data); | |
249 | break; | |
03e98b91 RL |
250 | case CUDBG_LE_TCAM: |
251 | cudbg_fill_le_tcam_info(adap, &tcam_region); | |
252 | len = sizeof(struct cudbg_tcam) + | |
253 | sizeof(struct cudbg_tid_data) * tcam_region.max_tid; | |
254 | break; | |
6f92a654 RL |
255 | case CUDBG_CCTRL: |
256 | len = sizeof(u16) * NMTUS * NCCTRL_WIN; | |
257 | break; | |
270d39bf RL |
258 | case CUDBG_MA_INDIRECT: |
259 | if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) { | |
260 | n = sizeof(t6_ma_ireg_array) / | |
261 | (IREG_NUM_ELEM * sizeof(u32)); | |
262 | len = sizeof(struct ireg_buf) * n * 2; | |
263 | } | |
264 | break; | |
27887bc7 | 265 | case CUDBG_ULPTX_LA: |
1eb94d44 SM |
266 | len = sizeof(struct cudbg_ver_hdr) + |
267 | sizeof(struct cudbg_ulptx_la); | |
27887bc7 | 268 | break; |
270d39bf | 269 | case CUDBG_UP_CIM_INDIRECT: |
be6e36d9 RL |
270 | n = 0; |
271 | if (is_t5(adap->params.chip)) | |
272 | n = sizeof(t5_up_cim_reg_array) / | |
273 | ((IREG_NUM_ELEM + 1) * sizeof(u32)); | |
274 | else if (is_t6(adap->params.chip)) | |
275 | n = sizeof(t6_up_cim_reg_array) / | |
276 | ((IREG_NUM_ELEM + 1) * sizeof(u32)); | |
270d39bf RL |
277 | len = sizeof(struct ireg_buf) * n; |
278 | break; | |
db8cd7ce RL |
279 | case CUDBG_PBT_TABLE: |
280 | len = sizeof(struct cudbg_pbt_tables); | |
281 | break; | |
844d1b6f RL |
282 | case CUDBG_MBOX_LOG: |
283 | len = sizeof(struct cudbg_mbox_log) * adap->mbox_log->size; | |
284 | break; | |
270d39bf RL |
285 | case CUDBG_HMA_INDIRECT: |
286 | if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) { | |
287 | n = sizeof(t6_hma_ireg_array) / | |
288 | (IREG_NUM_ELEM * sizeof(u32)); | |
289 | len = sizeof(struct ireg_buf) * n; | |
290 | } | |
291 | break; | |
4db0401f RL |
292 | case CUDBG_HMA: |
293 | value = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A); | |
294 | if (value & HMA_MUX_F) { | |
295 | /* In T6, there's no MC1. So, HMA shares MC1 | |
296 | * address space. | |
297 | */ | |
298 | value = t4_read_reg(adap, MA_EXT_MEMORY1_BAR_A); | |
299 | len = EXT_MEM1_SIZE_G(value); | |
300 | } | |
301 | len = cudbg_mbytes_to_bytes(len); | |
302 | break; | |
68ddc82a RL |
303 | case CUDBG_QDESC: |
304 | cudbg_fill_qdesc_num_and_size(adap, NULL, &len); | |
305 | break; | |
a7975a2f RL |
306 | default: |
307 | break; | |
308 | } | |
309 | ||
310 | return len; | |
311 | } | |
312 | ||
ad75b7d3 RL |
313 | u32 cxgb4_get_dump_length(struct adapter *adap, u32 flag) |
314 | { | |
a7975a2f RL |
315 | u32 i, entity; |
316 | u32 len = 0; | |
91c1953d | 317 | u32 wsize; |
a7975a2f RL |
318 | |
319 | if (flag & CXGB4_ETH_DUMP_HW) { | |
320 | for (i = 0; i < ARRAY_SIZE(cxgb4_collect_hw_dump); i++) { | |
321 | entity = cxgb4_collect_hw_dump[i].entity; | |
322 | len += cxgb4_get_entity_length(adap, entity); | |
323 | } | |
324 | } | |
325 | ||
b33af022 RL |
326 | if (flag & CXGB4_ETH_DUMP_MEM) { |
327 | for (i = 0; i < ARRAY_SIZE(cxgb4_collect_mem_dump); i++) { | |
328 | entity = cxgb4_collect_mem_dump[i].entity; | |
329 | len += cxgb4_get_entity_length(adap, entity); | |
330 | } | |
331 | } | |
332 | ||
91c1953d RL |
333 | /* If compression is enabled, a smaller destination buffer is enough */ |
334 | wsize = cudbg_get_workspace_size(); | |
335 | if (wsize && len > CUDBG_DUMP_BUFF_SIZE) | |
336 | len = CUDBG_DUMP_BUFF_SIZE; | |
337 | ||
a7975a2f RL |
338 | return len; |
339 | } | |
340 | ||
341 | static void cxgb4_cudbg_collect_entity(struct cudbg_init *pdbg_init, | |
342 | struct cudbg_buffer *dbg_buff, | |
343 | const struct cxgb4_collect_entity *e_arr, | |
344 | u32 arr_size, void *buf, u32 *tot_size) | |
345 | { | |
a7975a2f RL |
346 | struct cudbg_error cudbg_err = { 0 }; |
347 | struct cudbg_entity_hdr *entity_hdr; | |
56cf2635 | 348 | u32 i, total_size = 0; |
a7975a2f RL |
349 | int ret; |
350 | ||
351 | for (i = 0; i < arr_size; i++) { | |
352 | const struct cxgb4_collect_entity *e = &e_arr[i]; | |
353 | ||
a7975a2f RL |
354 | entity_hdr = cudbg_get_entity_hdr(buf, e->entity); |
355 | entity_hdr->entity_type = e->entity; | |
356 | entity_hdr->start_offset = dbg_buff->offset; | |
357 | memset(&cudbg_err, 0, sizeof(struct cudbg_error)); | |
358 | ret = e->collect_cb(pdbg_init, dbg_buff, &cudbg_err); | |
359 | if (ret) { | |
360 | entity_hdr->size = 0; | |
361 | dbg_buff->offset = entity_hdr->start_offset; | |
362 | } else { | |
363 | cudbg_align_debug_buffer(dbg_buff, entity_hdr); | |
364 | } | |
365 | ||
366 | /* Log error and continue with next entity */ | |
367 | if (cudbg_err.sys_err) | |
368 | ret = CUDBG_SYSTEM_ERROR; | |
369 | ||
370 | entity_hdr->hdr_flags = ret; | |
371 | entity_hdr->sys_err = cudbg_err.sys_err; | |
372 | entity_hdr->sys_warn = cudbg_err.sys_warn; | |
373 | total_size += entity_hdr->size; | |
374 | } | |
375 | ||
376 | *tot_size += total_size; | |
ad75b7d3 RL |
377 | } |
378 | ||
91c1953d RL |
379 | static int cudbg_alloc_compress_buff(struct cudbg_init *pdbg_init) |
380 | { | |
381 | u32 workspace_size; | |
382 | ||
383 | workspace_size = cudbg_get_workspace_size(); | |
384 | pdbg_init->compress_buff = vzalloc(CUDBG_COMPRESS_BUFF_SIZE + | |
385 | workspace_size); | |
386 | if (!pdbg_init->compress_buff) | |
387 | return -ENOMEM; | |
388 | ||
389 | pdbg_init->compress_buff_size = CUDBG_COMPRESS_BUFF_SIZE; | |
390 | pdbg_init->workspace = (u8 *)pdbg_init->compress_buff + | |
391 | CUDBG_COMPRESS_BUFF_SIZE - workspace_size; | |
392 | return 0; | |
393 | } | |
394 | ||
395 | static void cudbg_free_compress_buff(struct cudbg_init *pdbg_init) | |
396 | { | |
397 | if (pdbg_init->compress_buff) | |
398 | vfree(pdbg_init->compress_buff); | |
399 | } | |
400 | ||
ad75b7d3 RL |
401 | int cxgb4_cudbg_collect(struct adapter *adap, void *buf, u32 *buf_size, |
402 | u32 flag) | |
403 | { | |
ad75b7d3 RL |
404 | struct cudbg_buffer dbg_buff = { 0 }; |
405 | u32 size, min_size, total_size = 0; | |
325694e6 | 406 | struct cudbg_init cudbg_init; |
ad75b7d3 | 407 | struct cudbg_hdr *cudbg_hdr; |
91c1953d | 408 | int rc; |
ad75b7d3 RL |
409 | |
410 | size = *buf_size; | |
411 | ||
325694e6 | 412 | memset(&cudbg_init, 0, sizeof(struct cudbg_init)); |
ad75b7d3 RL |
413 | cudbg_init.adap = adap; |
414 | cudbg_init.outbuf = buf; | |
415 | cudbg_init.outbuf_size = size; | |
416 | ||
417 | dbg_buff.data = buf; | |
418 | dbg_buff.size = size; | |
419 | dbg_buff.offset = 0; | |
420 | ||
421 | cudbg_hdr = (struct cudbg_hdr *)buf; | |
422 | cudbg_hdr->signature = CUDBG_SIGNATURE; | |
423 | cudbg_hdr->hdr_len = sizeof(struct cudbg_hdr); | |
424 | cudbg_hdr->major_ver = CUDBG_MAJOR_VERSION; | |
425 | cudbg_hdr->minor_ver = CUDBG_MINOR_VERSION; | |
426 | cudbg_hdr->max_entities = CUDBG_MAX_ENTITY; | |
427 | cudbg_hdr->chip_ver = adap->params.chip; | |
428 | cudbg_hdr->dump_type = CUDBG_DUMP_TYPE_MINI; | |
ad75b7d3 RL |
429 | |
430 | min_size = sizeof(struct cudbg_hdr) + | |
431 | sizeof(struct cudbg_entity_hdr) * | |
432 | cudbg_hdr->max_entities; | |
433 | if (size < min_size) | |
434 | return -ENOMEM; | |
435 | ||
91c1953d RL |
436 | rc = cudbg_get_workspace_size(); |
437 | if (rc) { | |
438 | /* Zlib available. So, use zlib deflate */ | |
439 | cudbg_init.compress_type = CUDBG_COMPRESSION_ZLIB; | |
440 | rc = cudbg_alloc_compress_buff(&cudbg_init); | |
441 | if (rc) { | |
442 | /* Ignore error and continue without compression. */ | |
443 | dev_warn(adap->pdev_dev, | |
444 | "Fail allocating compression buffer ret: %d. Continuing without compression.\n", | |
445 | rc); | |
446 | cudbg_init.compress_type = CUDBG_COMPRESSION_NONE; | |
447 | rc = 0; | |
448 | } | |
449 | } else { | |
450 | cudbg_init.compress_type = CUDBG_COMPRESSION_NONE; | |
451 | } | |
452 | ||
453 | cudbg_hdr->compress_type = cudbg_init.compress_type; | |
ad75b7d3 RL |
454 | dbg_buff.offset += min_size; |
455 | total_size = dbg_buff.offset; | |
456 | ||
a7975a2f RL |
457 | if (flag & CXGB4_ETH_DUMP_HW) |
458 | cxgb4_cudbg_collect_entity(&cudbg_init, &dbg_buff, | |
459 | cxgb4_collect_hw_dump, | |
460 | ARRAY_SIZE(cxgb4_collect_hw_dump), | |
461 | buf, | |
462 | &total_size); | |
463 | ||
b33af022 RL |
464 | if (flag & CXGB4_ETH_DUMP_MEM) |
465 | cxgb4_cudbg_collect_entity(&cudbg_init, &dbg_buff, | |
466 | cxgb4_collect_mem_dump, | |
467 | ARRAY_SIZE(cxgb4_collect_mem_dump), | |
468 | buf, | |
469 | &total_size); | |
470 | ||
91c1953d | 471 | cudbg_free_compress_buff(&cudbg_init); |
ad75b7d3 | 472 | cudbg_hdr->data_len = total_size; |
91c1953d RL |
473 | if (cudbg_init.compress_type != CUDBG_COMPRESSION_NONE) |
474 | *buf_size = size; | |
475 | else | |
476 | *buf_size = total_size; | |
ad75b7d3 RL |
477 | return 0; |
478 | } | |
479 | ||
480 | void cxgb4_init_ethtool_dump(struct adapter *adapter) | |
481 | { | |
482 | adapter->eth_dump.flag = CXGB4_ETH_DUMP_NONE; | |
483 | adapter->eth_dump.version = adapter->params.fw_vers; | |
484 | adapter->eth_dump.len = 0; | |
485 | } | |
1dde532d RL |
486 | |
487 | static int cxgb4_cudbg_vmcoredd_collect(struct vmcoredd_data *data, void *buf) | |
488 | { | |
489 | struct adapter *adap = container_of(data, struct adapter, vmcoredd); | |
490 | u32 len = data->size; | |
491 | ||
492 | return cxgb4_cudbg_collect(adap, buf, &len, CXGB4_ETH_DUMP_ALL); | |
493 | } | |
494 | ||
495 | int cxgb4_cudbg_vmcore_add_dump(struct adapter *adap) | |
496 | { | |
497 | struct vmcoredd_data *data = &adap->vmcoredd; | |
498 | u32 len; | |
499 | ||
500 | len = sizeof(struct cudbg_hdr) + | |
501 | sizeof(struct cudbg_entity_hdr) * CUDBG_MAX_ENTITY; | |
502 | len += CUDBG_DUMP_BUFF_SIZE; | |
503 | ||
504 | data->size = len; | |
505 | snprintf(data->dump_name, sizeof(data->dump_name), "%s_%s", | |
506 | cxgb4_driver_name, adap->name); | |
507 | data->vmcoredd_callback = cxgb4_cudbg_vmcoredd_collect; | |
508 | ||
509 | return vmcore_add_device_dump(data); | |
510 | } |